[svsm-devel] Allocating 4 contiguous pages and set them shared

Carlos López clopez at suse.de
Thu Nov 2 13:37:01 CET 2023


Hi Claudio,

On 2/11/23 3:57, Claudio Siqueira de Carvalho wrote:
> My question is how should I share 4 pages with the hypervisor in this case? I
> could call "this_cpu_mut().get_pgtable().set_shared_4k()" for the first 4
> contiguous pages of p, but it seems that set_shared_4k() was meant for pages of
> order zero. Am I missing something? Any thoughts?

I'll preface this by saying I'm not completely familiar with the mm
code, so I could be completely wrong here. That being said, IIUC, page
order does not have much to do with the page table, but rather with the
size of the blocks in the free list.

`MemoryRegion` in src/mm/alloc.rs is initialized with a range of virtual
addresses (in `root_mem_init()`) and manages that range in blocks of
determined sizes. It stores a free list for each order, with each free
list holding blocks of `(1 << order)` pages.

You'll notice that the code in mm/alloc does not call into the page
table code at all, meaning that it has no knowledge of page table
hierarchy (or at least none that I could see). In other words, you
should be able to give `PageTable::set_shared_4k()` the address of any
page, and it will (un)set the appropriate bit in the corresponding
entry. Even if you give it the address of a huge page, the function
will handle it by calling `PageTable::split_4k()` first.

In other words, something like this should work:

     let p = allocate_pages(get_order(4*PAGE_SIZE))?;
     let pgtable = this_cpu_mut().get_pgtable();
     for page in (p..p + PAGE_SIZE * 4).step_by(PAGE_SIZE) {
         pgtable.set_shared_4k(page);
     }

Again, maybe I'm wrong here, so maybe someone else can confirm or refute
my explanation. Jörg wrote most of the mm/alloc code according to git
blame, but he's out this week.

PS: with my new `MemoryRegion` type in PR#131, (not to be confused with
the `MemoryRegion` above), the for loop should be simplified quite a
bit, as `allocate_pages()` could return a `MemoryRegion<VirtAddr>`,
which would allow:

     for page in pages.iter_pages(PageSize::Regular) {
         pgtable.set_shared_4k(page);
     }

But this is still a WIP.

Best,
Carlos

-- 
Carlos López
Security Engineer
SUSE Software Solutions


More information about the Svsm-devel mailing list