Hi, I'm currently working on synchronizing kernel address space pages between different user processes, aka tables from 256 -> 511 (or 768 -> 1023 in non-pae 32 bit mode)
and I've been thinking about different approaches to do that. The simplest solution would be to preallocate all kernel tables right away, which amounts to about 1 MiB
of physical memory, which seems like almost nothing nowadays. Then all synchronization required would be to memcpy all kernel tables addresses to the new PML4.
The other potential solution I can think of is some complex page fault handling algorithm that checks accesses against kernel address space and then maps the missing pieces.
Which approach do you think I should go for? Or maybe there's a completely different approach that I haven't even thought of.
Thanks.
How to synchronize kernel address space between processes
- AndrewAPrice
- Member
- Posts: 2300
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Re: How to synchronize kernel address space between processe
You could do what you suggested - preallocate all kernel page tables, then when you create a new address space, just remember to copy those across.
Long mode makes it a bit easier. There are many more page structure levels, and I have a kernel PDP (which represents a 512 GB range of memory, which for a microkernel in 2021 seems like plenty of space) and it's super simple to implement.
Long mode makes it a bit easier. There are many more page structure levels, and I have a kernel PDP (which represents a 512 GB range of memory, which for a microkernel in 2021 seems like plenty of space) and it's super simple to implement.
My OS is Perception.
Re: How to synchronize kernel address space between processe
You really have to copy only one entry - the top level one. On a 64-bit system this should provide enough memory for the kernel. Also, make sure that kernel mappings are global.
Re: How to synchronize kernel address space between processe
I keep the direct map of physical memory at 256, so I guess 2 entries in my case. But yeah I guess 512 GB is more than enough for everything I could ever need...iansjack wrote:You really have to copy only one entry - the top level one. On a 64-bit system this should provide enough memory for the kernel. Also, make sure that kernel mappings are global.
Re: How to synchronize kernel address space between processe
Yeah for some reason I assumed that I could potentially need other entries, but it seems very unlikely I guess.AndrewAPrice wrote:You could do what you suggested - preallocate all kernel page tables, then when you create a new address space, just remember to copy those across.
Long mode makes it a bit easier. There are many more page structure levels, and I have a kernel PDP (which represents a 512 GB range of memory, which for a microkernel in 2021 seems like plenty of space) and it's super simple to implement.
Re: How to synchronize kernel address space between processe
Linux uses that second idea. There is one specific PML4 that is authoritative on the kernel side. The handling isn't all that complex: When a page fault comes in due to an unmapped address, and the address is on kernel side, and the global PML4 has a page for that address, the current PML4's entry for that address is synchronized with the authoritative one. All processes share kernel-side PDPTs, PDTs, and PTs, only the PML4s must be different, of course. This way, new kernel-side mappings get propagated on an as-needed basis. Deleting kernel-side mappings is a major PITA, though, but then it is rarely necessary to unmap anything on the kernel side.
Carpe diem!
Re: How to synchronize kernel address space between processe
Ha! Good to know, thanksnullplan wrote:Linux uses that second idea. There is one specific PML4 that is authoritative on the kernel side. The handling isn't all that complex: When a page fault comes in due to an unmapped address, and the address is on kernel side, and the global PML4 has a page for that address, the current PML4's entry for that address is synchronized with the authoritative one. All processes share kernel-side PDPTs, PDTs, and PTs, only the PML4s must be different, of course. This way, new kernel-side mappings get propagated on an as-needed basis. Deleting kernel-side mappings is a major PITA, though, but then it is rarely necessary to unmap anything on the kernel side.
Re: How to synchronize kernel address space between processe
That's my method too. I have a "system" (authorative) "CR3" and then the page fault handler will allocate new page directory entries on demand and also copy those to other address spaces. The kernel page directory entries are never deleted.nullplan wrote:Linux uses that second idea. There is one specific PML4 that is authoritative on the kernel side. The handling isn't all that complex: When a page fault comes in due to an unmapped address, and the address is on kernel side, and the global PML4 has a page for that address, the current PML4's entry for that address is synchronized with the authoritative one. All processes share kernel-side PDPTs, PDTs, and PTs, only the PML4s must be different, of course. This way, new kernel-side mappings get propagated on an as-needed basis. Deleting kernel-side mappings is a major PITA, though, but then it is rarely necessary to unmap anything on the kernel side.