On Sun, Oct 17, 2010 at 12:33 PM, Maciej W. Rozycki <macro@xxxxxxxxxxxxxx> wrote: >> where pgd_current is at 0x8054_5008, and PTEBase is 0, 4, 8, 12, ... > > ÂIt has been always making me wonder (though not as much to go and dig > through our code ;) ) why Linux is uncapable of using the value presented > by the CPU in the CP0 Context register as is, or perhaps after a trivial > operation such as a left-shift by a constant number of bits (where the > size of the page entry slot assumed by hardware turned out too small). > There should be no need to add another constant as in the piece of code > you have quoted -- this constant should already have been preloaded to > this register when switching the context the last time. ÂThe design of the > TLB refill exception in the MIPS Architecture has been such as to allow > this register to be readily used as an address into the page table. On plain old 32-bit MIPS: The pgd entry for "va" is at address: (unsigned long)pgd + ((va >> 22) << 2) i.e. each 4-byte entry in the pgd table represents 4MB of virtual address space. PTEBase only gives you 9 bits to work with. If you use it to store pgd[31:23] directly, that means every pgd needs to be 8MB-aligned - ouch. You could potentially use PTEBase to store more of the significant bits, e.g. pgd = 0x8000_0000 | (PTEBase << 12) But that still places limits on where the pgd table can be stored, and probably adds a decent number of extra arithmetic operations to each handler.