TDVF enables lvl5 page table before pass to OS/bootloader while OVMF enables lvl4 page table. Check CR4.X86_CR4_LA57 to decide which page table level to use and initialize our own lvl5 page table if TDX. Move setup_page_table() before APs startup so that lvl5 page table is ready for APs. Refactor the common part of setting cr3 in a wrapper function load_page_table(). Signed-off-by: Zhenzhong Duan <zhenzhong.duan@xxxxxxxxx> Reviewed-by: Yu Zhang <yu.c.zhang@xxxxxxxxx> --- lib/x86/setup.c | 22 +++++++++++++++++++--- x86/efi/efistart64.S | 5 +++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/x86/setup.c b/lib/x86/setup.c index 7bf5d431f2a8..3a60762494d6 100644 --- a/lib/x86/setup.c +++ b/lib/x86/setup.c @@ -231,10 +231,23 @@ static efi_status_t setup_rsdp(efi_bootinfo_t *efi_bootinfo) } /* Defined in cstart64.S or efistart64.S */ +extern u8 ptl5; extern u8 ptl4; extern u8 ptl3; extern u8 ptl2; +static void load_page_table(void) +{ + /* + * Load new page table based on the level of firmware provided page + * table. + */ + if (read_cr4() & X86_CR4_LA57) + write_cr3((ulong)&ptl5); + else + write_cr3((ulong)&ptl4); +} + static void setup_page_table(void) { pgd_t *curr_pt; @@ -247,6 +260,9 @@ static void setup_page_table(void) /* Set AMD SEV C-Bit for page table entries */ flags |= get_amd_sev_c_bit_mask(); + /* Level 5 */ + curr_pt = (pgd_t *)&ptl5; + curr_pt[0] = ((phys_addr_t)&ptl4) | flags; /* Level 4 */ curr_pt = (pgd_t *)&ptl4; curr_pt[0] = ((phys_addr_t)&ptl3) | flags; @@ -266,8 +282,7 @@ static void setup_page_table(void) setup_ghcb_pte((pgd_t *)&ptl4); } - /* Load 4-level page table */ - write_cr3((ulong)&ptl4); + load_page_table(); } static void setup_gdt_tss(void) @@ -297,6 +312,7 @@ void secondary_startup_64(void) setup_percpu_area(); enable_x2apic(); tdx_ap_init(); + load_page_table(); while (1) safe_halt(); @@ -372,9 +388,9 @@ efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo) if (!is_tdx_guest()) enable_apic(); enable_x2apic(); + setup_page_table(); aps_init(); smp_init(); - setup_page_table(); return EFI_SUCCESS; } diff --git a/x86/efi/efistart64.S b/x86/efi/efistart64.S index 648d047febb5..ef3db0110c3c 100644 --- a/x86/efi/efistart64.S +++ b/x86/efi/efistart64.S @@ -22,6 +22,11 @@ ptl4: . = . + PAGE_SIZE .align PAGE_SIZE +.globl ptl5 +ptl5: + . = . + PAGE_SIZE +.align PAGE_SIZE + .globl stacktop . = . + PAGE_SIZE * MAX_TEST_CPUS stacktop: -- 2.25.1