0

In 64-bit Linux, IA-32E paging is used with 4 levels of paging structures (PML4/PDPT/PD/PT). The entries in the former three structures give the physical address of the corresponding next structure. My question is that will the physical addresses of all these paging structures be mapped in the paging table? If they are mapped, in which mode (User/Supervisor)? Thanks very much!

I captured some specific memory addresses which a vcpu have accessed during a period in KVM. These addresses are in the gfn(guest physical frame number) form. I wanted to tell if these gfns were mapped in kernel or userspace. So I traversed the guest's (virtual machine) paging table to find out the corresponding page table entries mapping to these gfns. See my previous question here.

I found that the physical addresses of some paging structures are mapped in the paging table while some are not. That is, the physical addresses of some paging structures (such as the address of PT given by a PDE) do not have valid corresponding PTE in the page table. Since I have changed the memory mechanism of the KVM a lot, I am afraid that maybe this phenomenon is caused by my code or maybe there is something wrong with my page-table-walking code.

So I want to know in a normal Linux, how these stuffs are handled.
Thanks very much!

Community
  • 1
  • 1
tamlok
  • 697
  • 1
  • 5
  • 15

2 Answers2

2

In 64-bit Linux, all physical addresses are always mapped with a Supervisor mapping in the kernel half of the address space.

You can convert a physical address to the corresponding virtual address in the linear kernel mapping by adding PAGE_OFFSET, which on x86-64 is 0xffff880000000000.

Are you sure that you are correctly handling 1GB and 2MB "huge pages" in your page table walker?

caf
  • 233,326
  • 40
  • 323
  • 462
  • Oh, thanks for your confirm. I run `getconf PAGE_SIZE` in the guest and it said `4096`. So the page size is 4KB? Linux won't mix 4KB and 2MB pages at the same time, right? I will try to do this experiment in an official KVM base later. Thanks very much! :) – tamlok May 30 '15 at 12:00
  • 1
    Yes, Linux does mix page sizes. In particular when it's mapping all of physical memory for the kernel's linear mapping, it uses the biggest mappings it can to reduce TLB pressure. – caf May 30 '15 at 16:41
  • Amazing! I didn't know that before. I checked it just now and it did show that there exists 2MB huge pages. So, though I haven't verify it yet, I think those "missing" physical addresses of the paging structures may be located right in the middle of a huge page. Thanks very much! – tamlok May 31 '15 at 01:03
  • I read your first statement carefully and I am supprised. Do you mean it is impossible that one physical address is mapped in the userspace and not mapped in the kernel space? If so, I think I need to change my code, because I counted how many relevant physical addresses were mapped in userspace by substracting thoes mapped in kernel space. This method is wrong if all physcial addresses are mapped in kernel space just as you said. – tamlok May 31 '15 at 01:10
  • Yes, that is the case, at least for 64-bit kernels and mappings of regular memory (ie anything backed by a `struct page`). Some device drivers might map special device memory regions into userspace but that would very much be the exception and not the rule. – caf May 31 '15 at 06:32
0

In normal linux CR3 contains PA of frame containing PML4 of Page table. last bits of virtual address are offset in that frame. data at that offset contains PA of page frame for next level. In this way corresponding page frame, containing desired data,is accessed.Those addresses containing PT structs are not mapped in any Page table.

In case of KVM, guest physical pages are virtual addresses mmaped by kernel. Those addresses used by guest need mapping to physical frames which is duty and discretion of host kernel. So host kernel can map some pages and not others according to its own algorithm. So if some gfn are mapped while others not is a quite natural and correct phenomena.

incompetent
  • 1,715
  • 18
  • 29