hv: multiarch: move page table entry function

this patch moves function xx_offset and xx_index to common code,
Add arch interface arch_quirk/arch_pgtle_page_vaddr and
arch_pgtle_large.

Tracked-On: #8831
Signed-off-by: hangliu1 <hang1.liu@intel.com>
Reviewed-by: Liu, Yifan1 <yifan1.liu@intel.com>
Acked-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
hangliu1
2025-10-13 15:17:19 +08:00
committed by acrnsi-robot
parent 8be20c690b
commit 5cc6694eab
11 changed files with 216 additions and 232 deletions

View File

@@ -9,7 +9,7 @@
#include <mmu.h>
#include <vm.h>
#include <asm/guest/virq.h>
#include <asm/pgtable.h>
#include <pgtable.h>
#include <asm/guest/ept.h>
#include <asm/vmx.h>
#include <asm/vtd.h>
@@ -444,30 +444,30 @@ void walk_ept_table(struct acrn_vm *vm, pge_handler cb)
uint64_t i, j, k, m;
for (i = 0UL; i < PTRS_PER_PGTL3E; i++) {
pml4e = pml4e_offset((uint64_t *)get_eptp(vm), i << PML4E_SHIFT);
pml4e = pgtl3e_offset((uint64_t *)get_eptp(vm), i << PML4E_SHIFT);
if (!table->pgentry_present(*pml4e)) {
continue;
}
for (j = 0UL; j < PTRS_PER_PGTL2E; j++) {
pdpte = pdpte_offset(pml4e, j << PDPTE_SHIFT);
pdpte = pgtl2e_offset(pml4e, j << PDPTE_SHIFT);
if (!table->pgentry_present(*pdpte)) {
continue;
}
if (pdpte_large(*pdpte) != 0UL) {
if (is_pgtl_large(*pdpte) != 0UL) {
cb(pdpte, PGTL2_SIZE);
continue;
}
for (k = 0UL; k < PTRS_PER_PGTL1E; k++) {
pde = pde_offset(pdpte, k << PDE_SHIFT);
pde = pgtl1e_offset(pdpte, k << PDE_SHIFT);
if (!table->pgentry_present(*pde)) {
continue;
}
if (pde_large(*pde) != 0UL) {
if (is_pgtl_large(*pde) != 0UL) {
cb(pde, PGTL1_SIZE);
continue;
}
for (m = 0UL; m < PTRS_PER_PGTL0E; m++) {
pte = pte_offset(pde, m << PTE_SHIFT);
pte = pgtl0e_offset(pde, m << PTE_SHIFT);
if (table->pgentry_present(*pte)) {
cb(pte, PGTL0_SIZE);
}

View File

@@ -14,6 +14,7 @@
#include <asm/mmu.h>
#include <asm/guest/ept.h>
#include <logmsg.h>
#include <pgtable.h>
struct page_walk_info {
uint64_t top_entry; /* Top level paging structure entry */

View File

@@ -16,6 +16,7 @@
#include <reloc.h>
#include <hypercall.h>
#include <logmsg.h>
#include <pgtable.h>
int is_tee_vm(struct acrn_vm *vm)
{

View File

@@ -13,6 +13,7 @@
#include <logmsg.h>
#include <asm/rtcm.h>
#include <ptdev.h>
#include <pgtable.h>
#define ENTRY_GPA_L 2U
#define ENTRY_GPA_HI 8U

View File

@@ -79,18 +79,18 @@ static void free_sept_table(uint64_t *shadow_eptp)
if (shadow_eptp) {
for (i = 0UL; i < PTRS_PER_PML4E; i++) {
shadow_pml4e = pml4e_offset(shadow_eptp, i << PML4E_SHIFT);
shadow_pml4e = pgtl3e_offset(shadow_eptp, i << PML4E_SHIFT);
if (!is_present_ept_entry(*shadow_pml4e)) {
continue;
}
for (j = 0UL; j < PTRS_PER_PDPTE; j++) {
shadow_pdpte = pdpte_offset(shadow_pml4e, j << PDPTE_SHIFT);
shadow_pdpte = pgtl2e_offset(shadow_pml4e, j << PDPTE_SHIFT);
if (!is_present_ept_entry(*shadow_pdpte) ||
is_leaf_ept_entry(*shadow_pdpte, PGT_LVL2)) {
continue;
}
for (k = 0UL; k < PTRS_PER_PDE; k++) {
shadow_pde = pde_offset(shadow_pdpte, k << PDE_SHIFT);
shadow_pde = pgtl1e_offset(shadow_pdpte, k << PDE_SHIFT);
if (!is_present_ept_entry(*shadow_pde) ||
is_leaf_ept_entry(*shadow_pde, PGT_LVL1)) {
continue;

View File

@@ -29,7 +29,7 @@
#include <types.h>
#include <atomic.h>
#include <asm/cpufeatures.h>
#include <asm/pgtable.h>
#include <pgtable.h>
#include <asm/cpu_caps.h>
#include <asm/vmx.h>
#include <reloc.h>

View File

@@ -0,0 +1,32 @@
#include <asm/mmu.h>
#include <asm/pgtable.h>
uint64_t arch_pgtl_page_paddr(uint64_t pgtle)
{
return pgtle & PFN_MASK;
}
/**
* @brief Check whether specified page table entry is pointing to huge page.
*
* PS(Page Size) flag indicates whether maps a 1-GByte page or 2MByte page or references a page directory table. This function
* checks this flag. This function is typically used in the context of setting up or modifying page tables where it's
* necessary to distinguish between large and regular page mappings.
*
* It returns the value that bit 7 is 1 if the specified pte maps a 1-GByte or 2MByte page, and 0 if references a page table.
*
* @param[in] pgtle The page directory pointer table entry to check.
*
* @return The value of PS flag in the PDPTE.
*
* @retval PAGE_PSE indicating mapping to a 1-GByte or 2MByte page.
* @retval 0 indicating reference to a page directory table.
*
* @pre N/A
*
* @post N/A
*/
uint64_t arch_pgtl_large(uint64_t pgtle)
{
return pgtle & PAGE_PSE;
}