After looking at the Linux x86 virtual memory map and reading about the differences between kernel virtual and kernel logical addresses (see 1, 2, 3, 4, 5, etc.), I've come away a little confused. I created a diagram to help me explain and get feedback on what I understand. (diagram not drawn to scale, but virtual memory addresses come from 4-level x86 memory map)
First, all user-space programs deal with user-space virtual addresses. Although user-space address spaces share the same kernel mapping, the user-space programs can't access kernel addresses directly. All user-space virtual addresses must be translated using page tables, which lead to physical addresses of where the memory resides on RAM if it is in RAM.
Second, the kernel portion of address space (in 32-bit systems, was a 3:1 split meaning 1 GB for kernel), the kernel uses a portion of the address space for logical addresses. Logical addresses are virtual addresses that are directly mapped to physical memory (1:1).
Next, kernel virtual addresses are any addresses that reside within the kernel address space region, which includes kernel logical addresses. So when people ask what the difference is between kernel virtual addresses and kernel logical addresses, the question implies they are distinct, when in reality kernel logical addresses are a subset of kernel virtual addresses. What they really mean to ask is what is the difference between kernel logical virtual addresses and kernel non-logical virtual addresses. Non-logical virtual addresses, as used by vmalloc
, are addresses that are not directly mapped to RAM and may not even be mapped to RAM.
If I'm correct so far, are the following two conclusions correct?
User virtual addresses and kernel non-logical virtual addresses that are mapped must be translated in exactly the same way: by walking through page tables to get the physical address. My evidence for this is the function
vmalloc_to_page()
, sincevmalloc
returns non-logical virtual addresses. This would mean that the kernel has its own set of page tables that aren't associated with any user space process.In x86-64, every mapped user virtual address or kernel non-logical virtual address has a corresponding kernel logical address. For instance, in my diagram user-space address
0000700000000000
maps to0x1
. Therefore, to get the kernel logical address, we add0x1
to the direct mapping baseffff888000000000
which leavesffff888000000001
. We can do the same with thevmalloc
address that has physical address0x3
, its kernel logical address isffff888000000003
. In this way, given any mapped non-logical virtual address, the kernel has at least two virtual addresses it could use to find the physical address (the non-logical virtual address and its logical address equivalent).