3

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?

  1. 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(), since vmalloc 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.

  2. 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 to 0x1. Therefore, to get the kernel logical address, we add 0x1 to the direct mapping base ffff888000000000 which leaves ffff888000000001. We can do the same with the vmalloc address that has physical address 0x3, its kernel logical address is ffff888000000003. 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).

Mapping Linux x86 virtual memory to physical memory

wxz
  • 2,254
  • 1
  • 10
  • 31
  • 2
    Minor nitpick, for the accuracy of your diagram: the middle of the Virtual Memory Map should be neither blue nor green, as a substantial portion of the range is unusable in 4-level paging (only 48 of the 64 bits are used). – sj95126 Sep 22 '21 at 04:25
  • 1
    Thanks for pointing that out. You're correct. I see that even in the 5-level paging, there would still be blank space in the middle. Anyway, was everything else I wrote accurate in your opinion? – wxz Sep 22 '21 at 14:53
  • That I couldn't tell you. I know paging, but I'm not extensively familiar with how Linux manages its translations internally aside from the tables read directly by the CPU. It does look like some of what you laid out refers to identity mapping the real memory space, which is a common technique in 64-bit mode as the linear space is huge. – sj95126 Sep 22 '21 at 20:20
  • You could try asking on the [Unix & Linux SE](https://unix.stackexchange.com). A quick search showed a number of questions about paging topics, huge pages, etc. – sj95126 Sep 22 '21 at 20:24

0 Answers0