mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-07-05 21:35:46 +02:00
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/20240405235603.1173076-7-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
parent
c092fc879f
commit
d99e4cb2ae
|
@ -2363,41 +2363,6 @@ static bool vendor_intel(struct x86_emulate_ctxt *ctxt)
|
||||||
return is_guest_vendor_intel(ebx, ecx, edx);
|
return is_guest_vendor_intel(ebx, ecx, edx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
|
|
||||||
{
|
|
||||||
const struct x86_emulate_ops *ops = ctxt->ops;
|
|
||||||
u32 eax, ebx, ecx, edx;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* syscall should always be enabled in longmode - so only become
|
|
||||||
* vendor specific (cpuid) if other modes are active...
|
|
||||||
*/
|
|
||||||
if (ctxt->mode == X86EMUL_MODE_PROT64)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
eax = 0x00000000;
|
|
||||||
ecx = 0x00000000;
|
|
||||||
ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, true);
|
|
||||||
/*
|
|
||||||
* remark: Intel CPUs only support "syscall" in 64bit longmode. Also a
|
|
||||||
* 64bit guest with a 32bit compat-app running will #UD !! While this
|
|
||||||
* behaviour can be fixed (by emulating) into AMD response - CPUs of
|
|
||||||
* AMD can't behave like Intel.
|
|
||||||
*/
|
|
||||||
if (is_guest_vendor_intel(ebx, ecx, edx))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (is_guest_vendor_amd(ebx, ecx, edx) ||
|
|
||||||
is_guest_vendor_hygon(ebx, ecx, edx))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* default: (not Intel, not AMD, not Hygon), apply Intel's
|
|
||||||
* stricter rules...
|
|
||||||
*/
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int em_syscall(struct x86_emulate_ctxt *ctxt)
|
static int em_syscall(struct x86_emulate_ctxt *ctxt)
|
||||||
{
|
{
|
||||||
const struct x86_emulate_ops *ops = ctxt->ops;
|
const struct x86_emulate_ops *ops = ctxt->ops;
|
||||||
|
@ -2411,7 +2376,15 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt)
|
||||||
ctxt->mode == X86EMUL_MODE_VM86)
|
ctxt->mode == X86EMUL_MODE_VM86)
|
||||||
return emulate_ud(ctxt);
|
return emulate_ud(ctxt);
|
||||||
|
|
||||||
if (!(em_syscall_is_enabled(ctxt)))
|
/*
|
||||||
|
* Intel compatible CPUs only support SYSCALL in 64-bit mode, whereas
|
||||||
|
* AMD allows SYSCALL in any flavor of protected mode. Note, it's
|
||||||
|
* infeasible to emulate Intel behavior when running on AMD hardware,
|
||||||
|
* as SYSCALL won't fault in the "wrong" mode, i.e. there is no #UD
|
||||||
|
* for KVM to trap-and-emulate, unlike emulating AMD on Intel.
|
||||||
|
*/
|
||||||
|
if (ctxt->mode != X86EMUL_MODE_PROT64 &&
|
||||||
|
ctxt->ops->guest_cpuid_is_intel_compatible(ctxt))
|
||||||
return emulate_ud(ctxt);
|
return emulate_ud(ctxt);
|
||||||
|
|
||||||
ops->get_msr(ctxt, MSR_EFER, &efer);
|
ops->get_msr(ctxt, MSR_EFER, &efer);
|
||||||
|
|
|
@ -223,6 +223,7 @@ struct x86_emulate_ops {
|
||||||
bool (*guest_has_movbe)(struct x86_emulate_ctxt *ctxt);
|
bool (*guest_has_movbe)(struct x86_emulate_ctxt *ctxt);
|
||||||
bool (*guest_has_fxsr)(struct x86_emulate_ctxt *ctxt);
|
bool (*guest_has_fxsr)(struct x86_emulate_ctxt *ctxt);
|
||||||
bool (*guest_has_rdpid)(struct x86_emulate_ctxt *ctxt);
|
bool (*guest_has_rdpid)(struct x86_emulate_ctxt *ctxt);
|
||||||
|
bool (*guest_cpuid_is_intel_compatible)(struct x86_emulate_ctxt *ctxt);
|
||||||
|
|
||||||
void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked);
|
void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked);
|
||||||
|
|
||||||
|
|
|
@ -8549,6 +8549,11 @@ static bool emulator_guest_has_rdpid(struct x86_emulate_ctxt *ctxt)
|
||||||
return guest_cpuid_has(emul_to_vcpu(ctxt), X86_FEATURE_RDPID);
|
return guest_cpuid_has(emul_to_vcpu(ctxt), X86_FEATURE_RDPID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool emulator_guest_cpuid_is_intel_compatible(struct x86_emulate_ctxt *ctxt)
|
||||||
|
{
|
||||||
|
return guest_cpuid_is_intel_compatible(emul_to_vcpu(ctxt));
|
||||||
|
}
|
||||||
|
|
||||||
static ulong emulator_read_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg)
|
static ulong emulator_read_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg)
|
||||||
{
|
{
|
||||||
return kvm_register_read_raw(emul_to_vcpu(ctxt), reg);
|
return kvm_register_read_raw(emul_to_vcpu(ctxt), reg);
|
||||||
|
@ -8647,6 +8652,7 @@ static const struct x86_emulate_ops emulate_ops = {
|
||||||
.guest_has_movbe = emulator_guest_has_movbe,
|
.guest_has_movbe = emulator_guest_has_movbe,
|
||||||
.guest_has_fxsr = emulator_guest_has_fxsr,
|
.guest_has_fxsr = emulator_guest_has_fxsr,
|
||||||
.guest_has_rdpid = emulator_guest_has_rdpid,
|
.guest_has_rdpid = emulator_guest_has_rdpid,
|
||||||
|
.guest_cpuid_is_intel_compatible = emulator_guest_cpuid_is_intel_compatible,
|
||||||
.set_nmi_mask = emulator_set_nmi_mask,
|
.set_nmi_mask = emulator_set_nmi_mask,
|
||||||
.is_smm = emulator_is_smm,
|
.is_smm = emulator_is_smm,
|
||||||
.is_guest_mode = emulator_is_guest_mode,
|
.is_guest_mode = emulator_is_guest_mode,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user