paging: refactor svsm kernel page table to creata a reusable pagetable crate#1062
paging: refactor svsm kernel page table to creata a reusable pagetable crate#1062ziqiaozhou wants to merge 6 commits into
Conversation
3acb125 to
9ca310d
Compare
|
As I mentioned in last-week's dev meeting, I refactored the page table code to extract out the general part of the page table implementation from kernel/src/pagetable.rs, in order to
Goal of the PR: move general OS-independent and arch-independent page table logic into paging crate; keep the change as minimal as possible; Although I tried to keep implementation closer to its original, I still made some minor changes to deduplicate the code and make it easy to be used by non-svsm projects.
|
9ca310d to
ab38e04
Compare
|
@stefano-garzarella can you add verification label to this PR since I moved some verified code into that paging crate from svsm kernel crate? I was able to add that label but cannot do that since this week. |
|
#1059 will fix the verification failure in this PR. |
|
@joergroedel , svsm kernel picks flush_tlb_global_sync, flush_tlb_global_sync_range or flush_tlb_global_sync_page based on the scope of the change, outside pagetable crate. I think I should move the flush_tlb_xxx out of the paging crate for split_4k to make the pagetable implementation consistant. |
ab38e04 to
e44735d
Compare
Create the paging crate and move foundational types from the kernel: - address.rs (PhysAddr, VirtAddr, Address trait), remove unused VirtPhysPair which was introduced 2 years ago and is no longer used by svsm code. - sizes.rs (PAGE_SIZE, PAGE_SHIFT, size constants) - util.rs (align_up, align_down, page_align_up, overlap, bit_mask) - Associated verus spec/proof files for verification - paging: move Verus specs and proofs into dedicated dirs - gate proofs and spec with verus_only The kernel re-exports these types to maintain API compatibility. Unit tests for utility functions move to paging/src/util.rs. Signed-off-by: Ziqiao Zhou <ziqiaozhou@microsoft.com>
e44735d to
f16e21e
Compare
Match the license with other files. Signed-off-by: Ziqiao Zhou <ziqiaozhou@microsoft.com>
f16e21e to
d82a547
Compare
Introduce the generic paging traits, page-level marker types. Keep the pagetable module unwired until the implementation exists so this commit is self-contained. Signed-off-by: Ziqiao Zhou <ziqiaozhou@microsoft.com>
Copy the existing kernel page table implementation into the paging crate without wiring it into the build yet. This gives reviewers a stable baseline so the extraction diff shows old code changing into generic crate code instead of appearing as entirely new code. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ziqiao Zhou <ziqiaozhou@microsoft.com>
…e crate
Wire the previously copied page-table baseline (from
`paging: copy kernel page table baseline`) into the `paging` crate as
a generic, architecture-agnostic implementation, and factor x86_64
specifics into their own module.
Refactor in `paging/src/pagetable.rs`:
- Convert `PageTable`, `PTEntry`, and walk/map/unmap helpers to be
parameterized over the trait types from `paging::traits`
(`PagingLevel`, `PagingHandler`, `GenericPageTableFlags`,
`ArchPagingMeta`, `SelfMap`).
- Drop all svsm-internal dependencies that were carried over with
the baseline (`crate::cpu::*`, `crate::mm::*`, `crate::platform`,
`ImmutAfterInitCell`, `SvsmError`, CR/EFER helpers, encryption-
mask globals, `paging_init`, etc.). These responsibilities move
behind the `PagingHandler` / `ArchPagingMeta` traits and will be
re-supplied by the kernel in a later commit.
- Re-export the generic trait surface from `pagetable` so downstream
callers see one module.
- Introduce `PTE_SHIFT` and rely on `sizes::{PAGE_SHIFT, PAGE_SIZE,
PAGE_SIZE_2M, PAGE_SIZE_1G, PageSize}` from the paging crate
instead of `crate::types`.
Change (not pure refactor):
- Public `map_2m` / `map_4k` still allocate parent entries using the
default `parent_flags()` directly; caller-selectable parent flags
and the `DIRTY` parent default are intentionally deferred to
follow-up commits.
New `paging/src/x86_64.rs`:
- Move the x86_64-specific `PTEntryFlags` bitflags out of
`pagetable.rs` (now `usize`-backed) along with its helpers
(`exec`, `data`, `data_ro`, `task_exec`, `task_data`,
`task_data_ro`, and the `writable`/`user`/`nx`/`global`
accessors).
- Implement `GenericPageTableFlags` for `PTEntryFlags`, defining
`PRESENT`/`USER`/`HUGE`, `parent_flags()` (PRESENT | WRITABLE |
USER | ACCESSED), and `self_map_table_flags()` (PRESENT |
WRITABLE | ACCESSED | DIRTY | NX).
- Add `Pml4Level` (4-level PML4) and `PdptLevel` (PDPT-rooted
3-level sub-tree) type aliases over `traits::PagingLevel{3,2}`.
`paging/src/lib.rs`:
- Expose the new `pagetable` and `x86_64` modules.
No callers are migrated in this commit; the kernel still uses its own
copy of the page table code. Net diff: +434 / -1418 lines.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Ziqiao Zhou <ziqiaozhou@microsoft.com>
x86_64
Signed-off-by: Ziqiao Zhou <ziqiaozhou@microsoft.com>
Replace the kernel-local page table implementation with wrappers around the generic paging crate. Add the SvsmPaging adapter for allocation, address conversion, feature masks, and self-map index configuration while preserving the kernel-facing PageTable and PageTablePart APIs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ziqiao Zhou <ziqiaozhou@microsoft.com>
d82a547 to
f8f609b
Compare
joergroedel
left a comment
There was a problem hiding this comment.
Overall looks great to me. I really like the new abstractions. A detail about the TLB flushing needs to be sorted out.
joergroedel
left a comment
There was a problem hiding this comment.
As I said before, the overall direction of the changes is great. The new crate looks a lot cleaner and is more generic than our previous implementation.
Two things are on my mind, though. I think I already mentioned the TLB-flushing question, but can not find the comment anymore, so I am putting it here again.
- The page-table code itself should not flush the TLB itself on changes, that should be up to the caller. The caller usually has better knowledge of the flushing scope than the page-table code (CPU-set to flush on, global vs. non-global, PCID, ...). What the new paging crate should provide is tracking of which addresses or ranges need to be flushed.
- COCONUT-SVSM has another abstraction in the page-table code:
PageTablePart. This abstraction holds a sub-page-table which can be mapped into several top-level page-tables. Is there a plan to move that to the generic crate as well?
This PR factors the kernel’s page-table implementation into a new standalone paging crate, then updates the kernel to consume (and re-export) those generic paging/address/size/util building blocks. It also introduces Verus specification/proof scaffolding for alignment helpers and basic paging constants.
Changes: