Skip to content

Commit d99e4cb

Browse files
committed
KVM: x86: Use "is Intel compatible" helper to emulate SYSCALL in !64-bit
Use guest_cpuid_is_intel_compatible() to determine whether SYSCALL in 32-bit Protected Mode (including Compatibility Mode) should #UD or succeed. The existing code already does the exact equivalent of guest_cpuid_is_intel_compatible(), just in a rather roundabout way. No functional change intended. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sean Christopherson <[email protected]>
1 parent c092fc8 commit d99e4cb

File tree

3 files changed

+16
-36
lines changed

3 files changed

+16
-36
lines changed

arch/x86/kvm/emulate.c

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2363,41 +2363,6 @@ static bool vendor_intel(struct x86_emulate_ctxt *ctxt)
23632363
return is_guest_vendor_intel(ebx, ecx, edx);
23642364
}
23652365

2366-
static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
2367-
{
2368-
const struct x86_emulate_ops *ops = ctxt->ops;
2369-
u32 eax, ebx, ecx, edx;
2370-
2371-
/*
2372-
* syscall should always be enabled in longmode - so only become
2373-
* vendor specific (cpuid) if other modes are active...
2374-
*/
2375-
if (ctxt->mode == X86EMUL_MODE_PROT64)
2376-
return true;
2377-
2378-
eax = 0x00000000;
2379-
ecx = 0x00000000;
2380-
ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, true);
2381-
/*
2382-
* remark: Intel CPUs only support "syscall" in 64bit longmode. Also a
2383-
* 64bit guest with a 32bit compat-app running will #UD !! While this
2384-
* behaviour can be fixed (by emulating) into AMD response - CPUs of
2385-
* AMD can't behave like Intel.
2386-
*/
2387-
if (is_guest_vendor_intel(ebx, ecx, edx))
2388-
return false;
2389-
2390-
if (is_guest_vendor_amd(ebx, ecx, edx) ||
2391-
is_guest_vendor_hygon(ebx, ecx, edx))
2392-
return true;
2393-
2394-
/*
2395-
* default: (not Intel, not AMD, not Hygon), apply Intel's
2396-
* stricter rules...
2397-
*/
2398-
return false;
2399-
}
2400-
24012366
static int em_syscall(struct x86_emulate_ctxt *ctxt)
24022367
{
24032368
const struct x86_emulate_ops *ops = ctxt->ops;
@@ -2411,7 +2376,15 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt)
24112376
ctxt->mode == X86EMUL_MODE_VM86)
24122377
return emulate_ud(ctxt);
24132378

2414-
if (!(em_syscall_is_enabled(ctxt)))
2379+
/*
2380+
* Intel compatible CPUs only support SYSCALL in 64-bit mode, whereas
2381+
* AMD allows SYSCALL in any flavor of protected mode. Note, it's
2382+
* infeasible to emulate Intel behavior when running on AMD hardware,
2383+
* as SYSCALL won't fault in the "wrong" mode, i.e. there is no #UD
2384+
* for KVM to trap-and-emulate, unlike emulating AMD on Intel.
2385+
*/
2386+
if (ctxt->mode != X86EMUL_MODE_PROT64 &&
2387+
ctxt->ops->guest_cpuid_is_intel_compatible(ctxt))
24152388
return emulate_ud(ctxt);
24162389

24172390
ops->get_msr(ctxt, MSR_EFER, &efer);

arch/x86/kvm/kvm_emulate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ struct x86_emulate_ops {
223223
bool (*guest_has_movbe)(struct x86_emulate_ctxt *ctxt);
224224
bool (*guest_has_fxsr)(struct x86_emulate_ctxt *ctxt);
225225
bool (*guest_has_rdpid)(struct x86_emulate_ctxt *ctxt);
226+
bool (*guest_cpuid_is_intel_compatible)(struct x86_emulate_ctxt *ctxt);
226227

227228
void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked);
228229

arch/x86/kvm/x86.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8549,6 +8549,11 @@ static bool emulator_guest_has_rdpid(struct x86_emulate_ctxt *ctxt)
85498549
return guest_cpuid_has(emul_to_vcpu(ctxt), X86_FEATURE_RDPID);
85508550
}
85518551

8552+
static bool emulator_guest_cpuid_is_intel_compatible(struct x86_emulate_ctxt *ctxt)
8553+
{
8554+
return guest_cpuid_is_intel_compatible(emul_to_vcpu(ctxt));
8555+
}
8556+
85528557
static ulong emulator_read_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg)
85538558
{
85548559
return kvm_register_read_raw(emul_to_vcpu(ctxt), reg);
@@ -8647,6 +8652,7 @@ static const struct x86_emulate_ops emulate_ops = {
86478652
.guest_has_movbe = emulator_guest_has_movbe,
86488653
.guest_has_fxsr = emulator_guest_has_fxsr,
86498654
.guest_has_rdpid = emulator_guest_has_rdpid,
8655+
.guest_cpuid_is_intel_compatible = emulator_guest_cpuid_is_intel_compatible,
86508656
.set_nmi_mask = emulator_set_nmi_mask,
86518657
.is_smm = emulator_is_smm,
86528658
.is_guest_mode = emulator_is_guest_mode,

0 commit comments

Comments
 (0)