Global pages not working

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
alex92
Posts: 4
Joined: Mon Aug 18, 2008 7:56 am

Global pages not working

Post by alex92 »

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.
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: Global pages not working

Post by Owen »

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)
alex92
Posts: 4
Joined: Mon Aug 18, 2008 7:56 am

Re: Global pages not working

Post by alex92 »

But if that is true, what is the purpose of the "global" flag?
The OSDev wiki article on paging states:
The Global, or 'G' above, flag, if set, prevents the TLB from updating the address in it's cache if CR3 is reset.
But if the CPU can flush the TLB entry when CR3 is reloaded, then the "global" flag has no effect.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Global pages not working

Post by Brendan »

Hi,
alex92 wrote:But if that is true, what is the purpose of the "global" flag?
The OSDev wiki article on paging states:
The Global, or 'G' above, flag, if set, prevents the TLB from updating the address in it's cache if CR3 is reset.
But if the CPU can flush the TLB entry when CR3 is reloaded, then the "global" flag has no effect.
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.

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.
alex92
Posts: 4
Joined: Mon Aug 18, 2008 7:56 am

Re: Global pages not working

Post by alex92 »

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...
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: Global pages not working

Post by AJ »

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
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Global pages not working

Post by Brendan »

Hi,
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.
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).


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.
Post Reply