48 lines
1.7 KiB
Diff
48 lines
1.7 KiB
Diff
From 9826e3e9edc355aea6b2f2f386e538aa0f199542 Mon Sep 17 00:00:00 2001
|
|
From: Sandwich <sandwich@archworks.co>
|
|
Date: Sat, 5 Sep 2026 11:58:18 +0200
|
|
Subject: [PATCH 2/5] KVM: x86: emulator: #UD, not #GP, for VMCALL at CPL > 0
|
|
|
|
Targets VMAware check: KVM_INTERCEPTION
|
|
|
|
0F 01 C1 is not an AMD instruction, and on Intel VMCALL is invalid
|
|
outside VMX operation. Hardware raises #UD for it at CPL > 0 on both
|
|
vendors.
|
|
|
|
The emulator declares VMCALL as Priv without PrivUD, so the generic CPL
|
|
check injects #GP(0) instead. Windows surfaces that to userspace as an
|
|
access violation rather than an illegal instruction, which is guest-
|
|
observable and differs from every physical machine.
|
|
|
|
Add PrivUD so the existing branch injects #UD. RIP is not advanced
|
|
either way, and CPL0 VMCALL is unaffected, so a guest built for Intel
|
|
and migrated onto an AMD host keeps working through
|
|
emulator_fix_hypercall().
|
|
|
|
Signed-off-by: Sandwich <sandwich@archworks.co>
|
|
---
|
|
arch/x86/kvm/emulate.c | 7 ++++++-
|
|
1 file changed, 6 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
|
|
index b566ab5c7..a723d05d9 100644
|
|
--- a/arch/x86/kvm/emulate.c
|
|
+++ b/arch/x86/kvm/emulate.c
|
|
@@ -3969,7 +3969,12 @@ static const struct opcode ud = I(SrcNone, emulate_ud);
|
|
|
|
static const struct opcode group7_rm0[] = {
|
|
N,
|
|
- I(SrcNone | Priv | EmulateOnUD, em_hypercall),
|
|
+ /*
|
|
+ * 0F 01 C1 is not an AMD instruction, and on Intel VMCALL is invalid
|
|
+ * outside VMX operation, i.e. hardware raises #UD at CPL > 0. Without
|
|
+ * PrivUD the CPL check below injects #GP, which is guest-observable.
|
|
+ */
|
|
+ I(SrcNone | Priv | PrivUD | EmulateOnUD, em_hypercall),
|
|
N, N, N, N, N, N,
|
|
};
|
|
|
|
--
|
|
2.55.0
|
|
|