fix: let nested-KVM vmlaunch succeed with Virtual NMIs

Self-test and Linux guest were failing VM-instruction error 7. Share a KVM-style control adjust, request PIN_VIRTUAL_NMIS, and stop intercepting guest #PF. Land isolated XNU/Python/KDE scaffolding off the boot path.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Linehu
2026-09-06 10:48:07 +08:00
co-authored by Cursor
parent cc0fcf26e3
commit 737a2cb0db
17 changed files with 1615 additions and 163 deletions
+10 -8
View File
@@ -76,8 +76,9 @@ static u64 *ept_walk(u64 gpa, int alloc_missing) {
if (!alloc_missing) return (u64 *)0;
u64 new_phys = ept_alloc_page();
if (new_phys == 0) return (u64 *)0;
/* 中间页表项:RWX + WB 内存类型 */
table[indices[level]] = new_phys | EPT_RWX | (EPT_MEMORY_TYPE_WB << 3);
/* 非叶 EPT 表项只含物理地址与 RWX。bits 5:3 在非叶项中
* 保留,写入 leaf memory type 会触发 EPT misconfiguration。 */
table[indices[level]] = new_phys | EPT_RWX;
/* 切换到新分配的下一级页表 */
table = (u64 *)phys_to_virt(new_phys);
} else {
@@ -145,7 +146,7 @@ int ept_map_2m_page(u64 gpa, u64 hpa, u64 flags, u64 memtype) {
if (!(entry & EPT_READ)) {
u64 new_phys = ept_alloc_page();
if (new_phys == 0) return -3;
table[pml4_idx] = new_phys | EPT_RWX | (EPT_MEMORY_TYPE_WB << 3);
table[pml4_idx] = new_phys | EPT_RWX;
table = (u64 *)phys_to_virt(new_phys);
} else {
table = (u64 *)phys_to_virt(entry & 0x000FFFFFFFFFF000ULL);
@@ -156,7 +157,7 @@ int ept_map_2m_page(u64 gpa, u64 hpa, u64 flags, u64 memtype) {
if (!(entry & EPT_READ)) {
u64 new_phys = ept_alloc_page();
if (new_phys == 0) return -4;
table[pdpt_idx] = new_phys | EPT_RWX | (EPT_MEMORY_TYPE_WB << 3);
table[pdpt_idx] = new_phys | EPT_RWX;
table = (u64 *)phys_to_virt(new_phys);
} else {
table = (u64 *)phys_to_virt(entry & 0x000FFFFFFFFFF000ULL);
@@ -210,7 +211,7 @@ void ept_flush_ept(void) {
int err;
__asm__ volatile(
"invept (%2), %1\n"
"jnc 1f\n"
"ja 1f\n"
"mov $1, %0\n"
"jmp 2f\n"
"1:\n"
@@ -234,7 +235,7 @@ void ept_flush_vpid(u16 vpid) {
int err;
__asm__ volatile(
"invvpid (%2), %1\n"
"jnc 1f\n"
"ja 1f\n"
"mov $1, %0\n"
"jmp 2f\n"
"1:\n"
@@ -296,7 +297,8 @@ u64 ept_gpa_to_hpa(u64 gpa) {
u64 ept_get_eptp(void) {
if (!g_ept_ready) return 0;
/* EPTP: bits [5:0] = memtype, bits [7:6] = walk length-1 (3 for 4-level),
* bits [51:12] = PML4 HPA */
/* EPTP: bits [2:0]=memory type WB(6), bits [5:3]=walk length-1 (3 => 4-level).
* Nested KVM accepted WB (eptp=...1e) on the passing self-test; forcing UC
* after a misread of EPT_VPID_CAP bit 8 regressed to error 7. */
return g_ept_pml4_phys | EPTP_WALK_LEN_4 | EPTP_MEMTYPE_WB;
}