| From 2996b54edbf7dcd9147e3b42ffd1780526424c42 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 2 Mar 2022 21:15:14 +0800 |
| Subject: KVM: x86/emulator: Emulate RDPID only if it is enabled in guest |
| |
| From: Hou Wenlong <houwenlong.hwl@antgroup.com> |
| |
| [ Upstream commit a836839cbfe60dc434c5476a7429cf2bae36415d ] |
| |
| When RDTSCP is supported but RDPID is not supported in host, |
| RDPID emulation is available. However, __kvm_get_msr() would |
| only fail when RDTSCP/RDPID both are disabled in guest, so |
| the emulator wouldn't inject a #UD when RDPID is disabled but |
| RDTSCP is enabled in guest. |
| |
| Fixes: fb6d4d340e05 ("KVM: x86: emulate RDPID") |
| Signed-off-by: Hou Wenlong <houwenlong.hwl@antgroup.com> |
| Message-Id: <1dfd46ae5b76d3ed87bde3154d51c64ea64c99c1.1646226788.git.houwenlong.hwl@antgroup.com> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| arch/x86/kvm/emulate.c | 4 +++- |
| arch/x86/kvm/kvm_emulate.h | 1 + |
| arch/x86/kvm/x86.c | 6 ++++++ |
| 3 files changed, 10 insertions(+), 1 deletion(-) |
| |
| diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c |
| index 5705446c1213..769ba8ffd700 100644 |
| --- a/arch/x86/kvm/emulate.c |
| +++ b/arch/x86/kvm/emulate.c |
| @@ -3514,8 +3514,10 @@ static int em_rdpid(struct x86_emulate_ctxt *ctxt) |
| { |
| u64 tsc_aux = 0; |
| |
| - if (ctxt->ops->get_msr(ctxt, MSR_TSC_AUX, &tsc_aux)) |
| + if (!ctxt->ops->guest_has_rdpid(ctxt)) |
| return emulate_ud(ctxt); |
| + |
| + ctxt->ops->get_msr(ctxt, MSR_TSC_AUX, &tsc_aux); |
| ctxt->dst.val = tsc_aux; |
| return X86EMUL_CONTINUE; |
| } |
| diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h |
| index 68b420289d7e..fb09cd22cb7f 100644 |
| --- a/arch/x86/kvm/kvm_emulate.h |
| +++ b/arch/x86/kvm/kvm_emulate.h |
| @@ -226,6 +226,7 @@ struct x86_emulate_ops { |
| bool (*guest_has_long_mode)(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_rdpid)(struct x86_emulate_ctxt *ctxt); |
| |
| void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked); |
| |
| diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c |
| index ff181a6c1005..08522041df59 100644 |
| --- a/arch/x86/kvm/x86.c |
| +++ b/arch/x86/kvm/x86.c |
| @@ -7466,6 +7466,11 @@ static bool emulator_guest_has_fxsr(struct x86_emulate_ctxt *ctxt) |
| return guest_cpuid_has(emul_to_vcpu(ctxt), X86_FEATURE_FXSR); |
| } |
| |
| +static bool emulator_guest_has_rdpid(struct x86_emulate_ctxt *ctxt) |
| +{ |
| + return guest_cpuid_has(emul_to_vcpu(ctxt), X86_FEATURE_RDPID); |
| +} |
| + |
| static ulong emulator_read_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg) |
| { |
| return kvm_register_read_raw(emul_to_vcpu(ctxt), reg); |
| @@ -7548,6 +7553,7 @@ static const struct x86_emulate_ops emulate_ops = { |
| .guest_has_long_mode = emulator_guest_has_long_mode, |
| .guest_has_movbe = emulator_guest_has_movbe, |
| .guest_has_fxsr = emulator_guest_has_fxsr, |
| + .guest_has_rdpid = emulator_guest_has_rdpid, |
| .set_nmi_mask = emulator_set_nmi_mask, |
| .get_hflags = emulator_get_hflags, |
| .exiting_smm = emulator_exiting_smm, |
| -- |
| 2.35.1 |
| |