[kvm-unit-tests RFC PATCH 12/17] x86 TDX: Enable lvl5 boot page table

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux