Messages in this thread | | | Date | Fri, 4 Jun 1999 08:22:58 -0700 | From | "David S. Miller" <> | Subject | Re: Linux address mapping |
| |
Date: Fri, 4 Jun 1999 15:45:54 +0200 (MET DST) From: Bjorn Wesen <bjorn@sparta.lu.se>
Where in the memory space is this placed, and are there any particular restrictions/requirements for placing this ?
Look for the VMALLOC* macros in include/asm-*/*.h
Another thing I was thinking about, is if the kernel is mapped into every process page table, is this done on a page-by-page basis, i.e a 600 kb kernel is mapped using for example 600/4 PTE's linearily, but maybe processes can share the second level page table for the kernel mapping so each process don't need its own kernel PTE map set.
It depends upon the architecture, some mmus do it right enough that the kernel is transparently mapped correctly for each process.
I wonder if there is an "ideal" MMU for Linux, i.e. one that maximizes performance and minimizes the porting work :)
My heavily biased opinion is that UltraSparc is the current mainstream "closest to ideal". The user and the kernel happily live in the same virtual addresses, and are seperated by address space identifiers. It's like a segment on x86, but imho much cleaner. This setup means that the user can have the entire (32-bit or 64-bit) virtual address space, if the whole thing is available in the hardware (most current generation 64-bit cpus do not, and have a "hole" in the middle of the 64-bit virtual address space which is not usable, Alpha, UltraSparc-I, and UltraSparc-II fall into this category). But from what is available, the user can map all of it on UltraSparc.
As an example, from the kernel we can access user address space only when we set the correct attributes in a load or store instruction, so:
ldx [user_address] ASI_AIUS, %reg
Loads an 8-byte word, at 'user_address', from the ASI_AIUS (stands for "Address Space Indentifier, As If from User Secondary") address space, into %reg.
This means it uses the "secondary user" translations in the MMU (the UltraSparc has three address spaces, primary, secondary, and nucleus, the first two have settable "MMU context" values, whereas the nucleus is fixed at "MMU context" zero which is where the kernel thus lives). And it accesses the data as if it were done in non-privileged mode, thus full protection checking are done as if the user did it himself.
During user process execution, the "primary" context is set to the appropriate MMU context value for his address space. At trap time the cpu automatically enters the nucleus context as the default (ie. the one which normal loads and stores, without attributes, will use) The trap entry code saves the critical register state etc. and then sets the "primary" context to zero (ie. nucleus) and sets the "secondary" context to what the user had.
This is how it all works out.
A nice side effect of this is that kernel page tables are explicit in every access, and since UltraSparc uses software filled TLBs the Linux kernel can manage the kernel page tables seperately, and in any way it likes (and thus a minimally and efficiently as it likes) since we are not fixed into any hardware imposed page table structure. For example, most of the kernel address space can have it's mapping computed in constant time because of their linear physical-->virtual nature, we take advantage of this by not having any page table state for it at all on UltraSparc.
Alpha works similarly, except:
1) without the primary/secondary contexts 2) "software managed" TLBs are filled by PAL code
Up until now the Alpha port has not modified the PAL code from the reference version provided by Digital, so in essence the page table structure used by Tru64/DUX/whatever is what Linux is using. There is no reason this couldn't be changed and experimented with in the future though.
Later, David S. Miller davem@redhat.com
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |