On understanding the x86 paging GLOBAL flag
Posted: Sun Nov 24, 2024 6:25 am
I'm at the point in my OS where I need to start thinking about allocating userspace address spaces. This comes with a few interesting design decisions that need to be made.
To actually build the page directory, I think I can abuse recursive paging, by putting the top level directory as an entry in the kernel's top level entry at some known offset, then map the same offset in the process' top level to itself - kind of making a recursive page table, but that's accessible from the kernel address space. So far so good, I see no issues with this beyond finding the time to build it.
Separately, the kernel also needs to be mapped to all process address spaces, to allow for syscalls and interrupts. Intel provides the GLOBAL flag, which looks like it's for exactly this purpose, but the docs are very unclear on how it works in practise. AIUI, if I've read correctly, setting GLOBAL in the kernel address space on the relevant pages will mean that, on switching to a userspace address space, the GLOBAL address space will still be mapped, without having necessarily populated the relevant entries in the userspace address spaces. However, I'm not certain that I've correctly understood that. It's also unclear whether I need to set GLOBAL for every entry recursively, OR just the bottom level, OR just the top level. Every entry recursively probably won't hurt, but good to clarify.
Does anyone else make use of GLOBAL pages for kernel mapping, who can shed some light on how to make it work in practise as opposed to just on paper? I know it can work for what I'm trying to do, it's just a question of implementation details the Intel manuals are a bit sparse on.
Relatedly, I'm almost executing userspace programs, which is a very exciting milestone
To actually build the page directory, I think I can abuse recursive paging, by putting the top level directory as an entry in the kernel's top level entry at some known offset, then map the same offset in the process' top level to itself - kind of making a recursive page table, but that's accessible from the kernel address space. So far so good, I see no issues with this beyond finding the time to build it.
Separately, the kernel also needs to be mapped to all process address spaces, to allow for syscalls and interrupts. Intel provides the GLOBAL flag, which looks like it's for exactly this purpose, but the docs are very unclear on how it works in practise. AIUI, if I've read correctly, setting GLOBAL in the kernel address space on the relevant pages will mean that, on switching to a userspace address space, the GLOBAL address space will still be mapped, without having necessarily populated the relevant entries in the userspace address spaces. However, I'm not certain that I've correctly understood that. It's also unclear whether I need to set GLOBAL for every entry recursively, OR just the bottom level, OR just the top level. Every entry recursively probably won't hurt, but good to clarify.
Does anyone else make use of GLOBAL pages for kernel mapping, who can shed some light on how to make it work in practise as opposed to just on paper? I know it can work for what I'm trying to do, it's just a question of implementation details the Intel manuals are a bit sparse on.
Relatedly, I'm almost executing userspace programs, which is a very exciting milestone