How is paging supposed to work in multiprocessing kernel

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
yasar11732
Member
Member
Posts: 28
Joined: Thu Sep 27, 2018 5:10 pm
Libera.chat IRC: yasar
Location: Turkey
Contact:

How is paging supposed to work in multiprocessing kernel

Post by yasar11732 »

Hi,

I am reading wiki articles about paging, and I think I understand how translation of adress from linear adress space to physical adress space works.

But, how is it designed to work with multiple processes.

Lets say we are switching from process A to process B, should I clear paging structures and and load them with new mapping for process B? It is doable, but seems like a too much work after each switch, considering there will be lots of switching in a second.

How about switching back to A later? Should I create a copy of old mapping each time I switch from a process? This, again, seems a lot of work after each task switch.

How do you even switch a task? If an interrupt occur while userspace process is doing work, kernel is not mapped, so interrupt handlers cannot be called.

I could keep kernel mapped at all times, but wouldn't it make kernel memory accessable to each process? Wouldn't that negate the whole point of having memory protection?

I am probably missing some very important key points here, otherwise, paging doesn't make much sense to me.

Best Regards,
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: How is paging supposed to work in multiprocessing kernel

Post by Octocontrabass »

yasar11732 wrote:Lets say we are switching from process A to process B, should I clear paging structures and and load them with new mapping for process B? It is doable, but seems like a too much work after each switch, considering there will be lots of switching in a second.

How about switching back to A later? Should I create a copy of old mapping each time I switch from a process? This, again, seems a lot of work after each task switch.
Normally each process has its own set of page tables. When you switch between them, you only have to change the top-level pointer to the paging structures. On x86, this is accomplished by changing CR3.
yasar11732 wrote:How do you even switch a task? If an interrupt occur while userspace process is doing work, kernel is not mapped, so interrupt handlers cannot be called.

I could keep kernel mapped at all times, but wouldn't it make kernel memory accessable to each process? Wouldn't that negate the whole point of having memory protection?
Most architectures provide user/supervisor separation at the page level, so you actually can keep the kernel mapped at all times without giving direct access to userspace. However, some architectures provide a mechanism to automatically map the kernel when an interrupt or system call occurs and unmap it upon returning to userspace. If your target architecture doesn't provide this functionality but you really need to have the kernel unmapped while userspace is running (e.g. to increase usable address space or prevent speculative execution vulnerabilities), you can use a stub that's always mapped to handle mapping and unmapping the rest of the kernel during privilege changes.
thewrongchristian
Member
Member
Posts: 426
Joined: Tue Apr 03, 2018 2:44 am

Re: How is paging supposed to work in multiprocessing kernel

Post by thewrongchristian »

yasar11732 wrote:Hi,

I am reading wiki articles about paging, and I think I understand how translation of adress from linear adress space to physical adress space works.

But, how is it designed to work with multiple processes.

Lets say we are switching from process A to process B, should I clear paging structures and and load them with new mapping for process B? It is doable, but seems like a too much work after each switch, considering there will be lots of switching in a second.

How about switching back to A later? Should I create a copy of old mapping each time I switch from a process? This, again, seems a lot of work after each task switch.
What @Octocontrabass said, but there have been systems that also maintain a single paging directory, that is updated at task switch in-situ.

SCO OpenServer worked like this. There was a single static page directory page, with the upper entries pointing to kernel page tables, and the lower entries (I don't know the user/kernel cut-off off hand) pointing to the current user process.

Given its vintage, we're not talking a huge amount of page table entries being required. Given 4K page sizes, and a 256KB process working set, you might only have to clear out 64 ptes per task switch, then the new task can fault back in ptes on demand.

My own kernel goes for a hybrid approach. Page tables are transient, and assigned to an address space on an as needed purpose, so a process that is sleeping for a long time may lose its page tables.

I interface with my MMU using a TLB like interface, without exposing the hardware MMU data structures at all to the rest of the kernel.

So, given a user address space handle, which is itself just a segment map, I switch to a user address space using:

Code: Select all

	if (old->process != thread->process) {
		if (thread->process) {
			vmap_set_asid(thread->process->as);
		} else {
			vmap_set_asid(0);
		}
	}
Here, asid 0 indicates the kernel address space, and that the thread being switched to in this case doesn't have a user level process.
yasar11732 wrote: How do you even switch a task? If an interrupt occur while user space process is doing work, kernel is not mapped, so interrupt handlers cannot be called.

I could keep kernel mapped at all times, but wouldn't it make kernel memory accessible to each process? Wouldn't that negate the whole point of having memory protection?
The hardware MMU protects the kernel portion of the address space from user access. Page table entries can be marked as supervisor only, which means they're only accessible in kernel mode. User mode access to pages mapped by such supervisor only page table entries will produce a trap, and the kernel will generate a SIGSEGV signal or access violation exception to your process in response.
Post Reply