Hi Hartmut & Mm Experts,
It seems that on ROS, every process has its own Page Table for the Kernel Area/System Table. This needs to be updated with MmUpdatePageDir all the time, and creates a bunch of annoyances in the Context Switching code too (for example, I can't check the trap frame for VM_MASK because at that time the Page Directory hasn't been changed yet. I could change it before but that would screw up the optimizations. Philip Susi and I have researched this and arrived to the common conclusion that every new Process's Page Table should share the same System Page Table. I'm not an expert so maybe I'm not explaining it properly, but the System Page Table shouldn't have to be "inserted/mapped" into every Process's Page Table, it should already be there, shared amongst all processes. I hope that made sense...if not, maybe Philip can fix up my explenation.
Is it possible for any of the Mm guys to implement this properly? Thanks a lot..
Best regards, Alex Ionescu
Just to help clarify the technical explanation of the problem, I'll explain in other words:
cr3 points to the page table directory. The page table directory points to several page tables. The page tables point to the physical pages ( if any ) and access mask. Each process gets its own page table directory. Right now every process also gets it's own page tables, so the kernel has to be careful to make sure and fix up each process's page tables to point to the correct shared kernel memory before it can access that memory. The way it should work is every page table directory should point to a single shared page table for kernel memory, so that an update to the kernel memory map in one process is reflected immediately in all.
Alex Ionescu wrote:
Hi Hartmut & Mm Experts,
It seems that on ROS, every process has its own Page Table for the Kernel Area/System Table. This needs to be updated with MmUpdatePageDir all the time, and creates a bunch of annoyances in the Context Switching code too (for example, I can't check the trap frame for VM_MASK because at that time the Page Directory hasn't been changed yet. I could change it before but that would screw up the optimizations. Philip Susi and I have researched this and arrived to the common conclusion that every new Process's Page Table should share the same System Page Table. I'm not an expert so maybe I'm not explaining it properly, but the System Page Table shouldn't have to be "inserted/mapped" into every Process's Page Table, it should already be there, shared amongst all processes. I hope that made sense...if not, maybe Philip can fix up my explenation.
Is it possible for any of the Mm guys to implement this properly? Thanks a lot..
Best regards, Alex Ionescu _______________________________________________ Ros-dev mailing list Ros-dev@reactos.com http://reactos.com:8080/mailman/listinfo/ros-dev
Alex Ionescu wrote:
Hi Hartmut & Mm Experts,
It seems that on ROS, every process has its own Page Table for the Kernel Area/System Table. This needs to be updated with MmUpdatePageDir all the time, and creates a bunch of annoyances in the Context Switching code too (for example, I can't check the trap frame for VM_MASK because at that time the Page Directory hasn't been changed yet. I could change it before but that would screw up the optimizations. Philip Susi and I have researched this and arrived to the common conclusion that every new Process's Page Table should share the same System Page Table. I'm not an expert so maybe I'm not explaining it properly, but the System Page Table shouldn't have to be "inserted/mapped" into every Process's Page Table, it should already be there, shared amongst all processes. I hope that made sense...if not, maybe Philip can fix up my explenation.
Is it possible for any of the Mm guys to implement this properly? Thanks a lot..
Best regards, Alex Ionescu _______________________________________________ Ros-dev mailing list Ros-dev@reactos.com http://reactos.com:8080/mailman/listinfo/ros-dev
Hi,
It isn't possible to share the page table in non pae mode. The page table contains the page directories for user and kernel mode. The page directories for kernel mode are always shared except the hyperspace and self mapped page table. On a task switch there is accessed the stack and the thread/process structure of the next and/or the previous thread. A page fault at this point is always a result of a missing page directory. We can remove the call to MmUpdatePageDir before each task switch if we do some changes: - The kernel stack should never cross a page directory boundary (4MB). - The old thread should access the stack and the thread/process structure from the new thread before the thread pointer within the pcr is changed. This may trigger a page fault and sets the page directory within the page table of the old thread. - The trap handler (KiTrapHandler) should check for a missing page directory, befor PsGetCurrentThread is called.
- Hartmut
Hrm... are you saying that the page tables are shared, but since the page directory is not, a page fault can happen because the current processes' page directory does not contain a PDE yet pointing to the page table? That makes sense, but the page fault handler should notice that the fault happened because the PDE is missing, and just copy the PDE (if it exists) from the system process page directory. As long as the page fault handler does that, then the process management code will not need to do anything special.
Hartmut Birr wrote:
It isn't possible to share the page table in non pae mode. The page table contains the page directories for user and kernel mode. The page directories for kernel mode are always shared except the hyperspace and self mapped page table. On a task switch there is accessed the stack and the thread/process structure of the next and/or the previous thread. A page fault at this point is always a result of a missing page directory. We can remove the call to MmUpdatePageDir before each task switch if we do some changes:
- The kernel stack should never cross a page directory boundary (4MB).
- The old thread should access the stack and the thread/process
structure from the new thread before the thread pointer within the pcr is changed. This may trigger a page fault and sets the page directory within the page table of the old thread.
- The trap handler (KiTrapHandler) should check for a missing page
directory, befor PsGetCurrentThread is called.
- Hartmut
Phillip Susi wrote:
Hrm... are you saying that the page tables are shared, but since the page directory is not, a page fault can happen because the current processes' page directory does not contain a PDE yet pointing to the page table? That makes sense, but the page fault handler should notice that the fault happened because the PDE is missing, and just copy the PDE (if it exists) from the system process page directory. As long as the page fault handler does that, then the process management code will not need to do anything special.
Currently there exist two problems which cannot resolved by the trap/page fault handler. The trap handler is invoked before the page fault handler. The trap handler checks always for a stack under flow and use the current thread entry from the pcr (PsGetCurrentThread). This means, a page fault from the pcr's current thread entry cannot be handled. While the thread switch code is execute, interrupts are only disabled while the kernel stack is switched. There is a gap between switching the stack and switching the page table. If the pde for the new stack isn't valid for the old thread and the stack is accessed (by an interrupt or a trap), it does occur a double fault.
- Hartmut