Page 1 of 1

How to synchronize kernel address space between processes

Posted: Wed Jan 20, 2021 11:14 am
by 8infy
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.

Re: How to synchronize kernel address space between processe

Posted: Wed Jan 20, 2021 12:08 pm
by AndrewAPrice
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

Posted: Wed Jan 20, 2021 12:29 pm
by iansjack
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

Posted: Wed Jan 20, 2021 1:32 pm
by 8infy
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.
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...

Re: How to synchronize kernel address space between processe

Posted: Wed Jan 20, 2021 1:35 pm
by 8infy
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.
Yeah for some reason I assumed that I could potentially need other entries, but it seems very unlikely I guess.

Re: How to synchronize kernel address space between processe

Posted: Wed Jan 20, 2021 1:42 pm
by nullplan
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

Posted: Wed Jan 20, 2021 1:45 pm
by 8infy
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.
Ha! Good to know, thanks

Re: How to synchronize kernel address space between processe

Posted: Wed Jan 20, 2021 1:59 pm
by rdos
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.
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.