Hi,
I am trying to use global pages to map the kernel heap in all processes (this is necessary because all the thread and process linked lists are there). I enabled PGE (Page Global Enable, mask 0x80) in the CR4 register, made sure PGE is available (with CPUID), and set the page table entries as "global" (bitwise OR with 0x100) in the kernel page directory. However, as soon as a new page directory is loaded into CR3, all of those pages become "not present" as if they weren't global. Can anyone explain why this is happening? I tried running it in Bochs and QEMU.
Thanks in advance.
Global pages not working
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: Global pages not working
Just because a page is global does not mean that it is not permissible for the CPU to flush it from the TLB at any point it wishes (Indeed, the architecture does not define the existence of a TLB)
Re: Global pages not working
But if that is true, what is the purpose of the "global" flag?
The OSDev wiki article on paging states:
The OSDev wiki article on paging states:
But if the CPU can flush the TLB entry when CR3 is reloaded, then the "global" flag has no effect.The Global, or 'G' above, flag, if set, prevents the TLB from updating the address in it's cache if CR3 is reset.
Re: Global pages not working
Hi,
If you set the "global" flag for a page, then you're telling the CPU that you guarantee the same page is at the same address in all virtual address spaces. Based on your guarantee; the CPU can avoid flushing global TLB entries when CR3 is reloaded if it feels like it (to improve performance). If you start getting "not present" page faults for global pages when you change CR3, then you've guaranteed the pages are the same in all virtual address spaces and failed to live up to your own guarantee.
Cheers,
Brendan
CPU flushes TLB entries for a variety of reasons, including flushing a less recently used (global or non-global) TLB entry to make space for a more recently used (global or non-global) translation. Just because something is "global" doesn't mean it's permanently stuck in the TLB forever.alex92 wrote:But if that is true, what is the purpose of the "global" flag?
The OSDev wiki article on paging states:But if the CPU can flush the TLB entry when CR3 is reloaded, then the "global" flag has no effect.The Global, or 'G' above, flag, if set, prevents the TLB from updating the address in it's cache if CR3 is reset.
If you set the "global" flag for a page, then you're telling the CPU that you guarantee the same page is at the same address in all virtual address spaces. Based on your guarantee; the CPU can avoid flushing global TLB entries when CR3 is reloaded if it feels like it (to improve performance). If you start getting "not present" page faults for global pages when you change CR3, then you've guaranteed the pages are the same in all virtual address spaces and failed to live up to your own guarantee.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Global pages not working
Thanks for your reply. Looks like the only way to map a block of memory into all processes is to change all of their page directories manually...
Re: Global pages not working
Hi,
Yes and no. I have no idea whether you are writing a 32 or 64 bit kernel, but let's assume you are writing a 32 bit kernel which reserves the last GiB of the virtual address space for itself.
Taking this assumption, assign 1MiB of physical RAM for kernel page tables and write the corresponding PDE's (but leave the page tables zeroed until you need to page in). You now have your template page directory which can be used to create all page directories for new processes. Now, when you actually page in by adding the appropriate PTE, that change will automatically happen across all process spaces.
This example assumes 4K pages, but if you choose to use large pages for the kernel binary, it will work equally well. What doesn't work with this scheme is using large pages for the whole of kernel space - in that case, you would have to manually propagate a PDE across all PD's (you could do this by using a PFE, in which case any single PDE only causes a single exception for any one task space).
Cheers,
Adam
Yes and no. I have no idea whether you are writing a 32 or 64 bit kernel, but let's assume you are writing a 32 bit kernel which reserves the last GiB of the virtual address space for itself.
Taking this assumption, assign 1MiB of physical RAM for kernel page tables and write the corresponding PDE's (but leave the page tables zeroed until you need to page in). You now have your template page directory which can be used to create all page directories for new processes. Now, when you actually page in by adding the appropriate PTE, that change will automatically happen across all process spaces.
This example assumes 4K pages, but if you choose to use large pages for the kernel binary, it will work equally well. What doesn't work with this scheme is using large pages for the whole of kernel space - in that case, you would have to manually propagate a PDE across all PD's (you could do this by using a PFE, in which case any single PDE only causes a single exception for any one task space).
Cheers,
Adam
Re: Global pages not working
Hi,
Cheers,
Brendan
Best case for a 32-bit OS is PAE, where each virtual address space has a PDP that points to (up to) 4 page directories; where each page directory covers 1 GiB of the virtual address space. In this case you can have one page directory that is the same in all virtual address spaces (for the kernel and all its page tables, etc).AJ wrote:Yes and no. I have no idea whether you are writing a 32 or 64 bit kernel, but let's assume you are writing a 32 bit kernel which reserves the last GiB of the virtual address space for itself.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.