[kvm-unit-tests RFC PATCH 13/17] x86 TDX: Add lvl5 page table support to virtual memory

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

 



Currently in TDX test case init stage, it setup an initial lvl5
boot page table, but VM code support only lvl4 page table. This
mismatch make the test cases requiring virtual memory crash.

Add below changes to support lvl5 page table for virtual memory:

1. skip finding high memory
2. check X86_CR4_LA57 to decide to initialize lvl5 or lvl4 page table
3. always set X86_CR0_NE for TDX test case

Signed-off-by: Zhenzhong Duan <zhenzhong.duan@xxxxxxxxx>
Reviewed-by: Yu Zhang <yu.c.zhang@xxxxxxxxx>
---
 lib/x86/processor.h |  1 +
 lib/x86/setup.c     |  5 +++++
 lib/x86/vm.c        | 14 ++++++++++++--
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index 865269fd3857..4deff9ebe044 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -35,6 +35,7 @@
 #define X86_CR0_MP	0x00000002
 #define X86_CR0_EM	0x00000004
 #define X86_CR0_TS	0x00000008
+#define X86_CR0_NE	0x00000020
 #define X86_CR0_WP	0x00010000
 #define X86_CR0_AM	0x00040000
 #define X86_CR0_NW	0x20000000
diff --git a/lib/x86/setup.c b/lib/x86/setup.c
index 3a60762494d6..0c299d3dd9bc 100644
--- a/lib/x86/setup.c
+++ b/lib/x86/setup.c
@@ -64,6 +64,11 @@ static struct mbi_bootinfo *bootinfo;
 #ifdef __x86_64__
 void find_highmem(void)
 {
+#ifdef TARGET_EFI
+	/* The largest free memory region is already chosen in setup_efi() */
+	return;
+#endif /* TARGET_EFI */
+
 	/* Memory above 4 GB is only supported on 64-bit systems.  */
 	if (!(bootinfo->flags & 64))
 	    	return;
diff --git a/lib/x86/vm.c b/lib/x86/vm.c
index 56be57be673a..4ead6ed358ae 100644
--- a/lib/x86/vm.c
+++ b/lib/x86/vm.c
@@ -3,6 +3,7 @@
 #include "vmalloc.h"
 #include "alloc_page.h"
 #include "smp.h"
+#include "tdx.h"
 
 static pteval_t pte_opt_mask;
 
@@ -16,7 +17,12 @@ pteval_t *install_pte(pgd_t *cr3,
     pteval_t *pt = cr3;
     unsigned offset;
 
-    for (level = PAGE_LEVEL; level > pte_level; --level) {
+    if (read_cr4() & X86_CR4_LA57)
+        level = 5;
+    else
+        level = PAGE_LEVEL;
+
+    for (; level > pte_level; --level) {
 	offset = PGDIR_OFFSET((uintptr_t)virt, level);
 	if (!(pt[offset] & PT_PRESENT_MASK)) {
 	    pteval_t *new_pt = pt_page;
@@ -187,7 +193,11 @@ void *setup_mmu(phys_addr_t end_of_memory, void *opt_mask)
 #ifndef __x86_64__
     write_cr4(X86_CR4_PSE);
 #endif
-    write_cr0(X86_CR0_PG |X86_CR0_PE | X86_CR0_WP);
+    /* According to TDX module spec 10.6.1 CR0.NE should be 1 */
+    if (is_tdx_guest())
+        write_cr0(X86_CR0_PG | X86_CR0_PE | X86_CR0_WP | X86_CR0_NE);
+    else
+        write_cr0(X86_CR0_PG | X86_CR0_PE | X86_CR0_WP);
 
     printf("paging enabled\n");
     printf("cr0 = %lx\n", read_cr0());
-- 
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