Skip to content

Commit ac8d6ca

Browse files
bysuibonzini
authored andcommitted
KVM: x86: Only do MSR filtering when access MSR by rdmsr/wrmsr
If MSR access is rejected by MSR filtering, kvm_set_msr()/kvm_get_msr() would return KVM_MSR_RET_FILTERED, and the return value is only handled well for rdmsr/wrmsr. However, some instruction emulation and state transition also use kvm_set_msr()/kvm_get_msr() to do msr access but may trigger some unexpected results if MSR access is rejected, E.g. RDPID emulation would inject a #UD but RDPID wouldn't cause a exit when RDPID is supported in hardware and ENABLE_RDTSCP is set. And it would also cause failure when load MSR at nested entry/exit. Since msr filtering is based on MSR bitmap, it is better to only do MSR filtering for rdmsr/wrmsr. Signed-off-by: Hou Wenlong <houwenlong.hwl@antgroup.com> Message-Id: <2b2774154f7532c96a6f04d71c82a8bec7d9e80b.1646655860.git.houwenlong.hwl@antgroup.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent a836839 commit ac8d6ca

3 files changed

Lines changed: 40 additions & 16 deletions

File tree

arch/x86/kvm/emulate.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3625,7 +3625,7 @@ static int em_wrmsr(struct x86_emulate_ctxt *ctxt)
36253625

36263626
msr_data = (u32)reg_read(ctxt, VCPU_REGS_RAX)
36273627
| ((u64)reg_read(ctxt, VCPU_REGS_RDX) << 32);
3628-
r = ctxt->ops->set_msr(ctxt, msr_index, msr_data);
3628+
r = ctxt->ops->set_msr_with_filter(ctxt, msr_index, msr_data);
36293629

36303630
if (r == X86EMUL_IO_NEEDED)
36313631
return r;
@@ -3642,7 +3642,7 @@ static int em_rdmsr(struct x86_emulate_ctxt *ctxt)
36423642
u64 msr_data;
36433643
int r;
36443644

3645-
r = ctxt->ops->get_msr(ctxt, msr_index, &msr_data);
3645+
r = ctxt->ops->get_msr_with_filter(ctxt, msr_index, &msr_data);
36463646

36473647
if (r == X86EMUL_IO_NEEDED)
36483648
return r;

arch/x86/kvm/kvm_emulate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ struct x86_emulate_ops {
210210
int (*set_dr)(struct x86_emulate_ctxt *ctxt, int dr, ulong value);
211211
u64 (*get_smbase)(struct x86_emulate_ctxt *ctxt);
212212
void (*set_smbase)(struct x86_emulate_ctxt *ctxt, u64 smbase);
213+
int (*set_msr_with_filter)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 data);
214+
int (*get_msr_with_filter)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 *pdata);
213215
int (*set_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 data);
214216
int (*get_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 *pdata);
215217
int (*check_pmc)(struct x86_emulate_ctxt *ctxt, u32 pmc);

arch/x86/kvm/x86.c

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,9 +1748,6 @@ static int __kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data,
17481748
{
17491749
struct msr_data msr;
17501750

1751-
if (!host_initiated && !kvm_msr_allowed(vcpu, index, KVM_MSR_FILTER_WRITE))
1752-
return KVM_MSR_RET_FILTERED;
1753-
17541751
switch (index) {
17551752
case MSR_FS_BASE:
17561753
case MSR_GS_BASE:
@@ -1832,9 +1829,6 @@ int __kvm_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data,
18321829
struct msr_data msr;
18331830
int ret;
18341831

1835-
if (!host_initiated && !kvm_msr_allowed(vcpu, index, KVM_MSR_FILTER_READ))
1836-
return KVM_MSR_RET_FILTERED;
1837-
18381832
switch (index) {
18391833
case MSR_TSC_AUX:
18401834
if (!kvm_is_supported_user_return_msr(MSR_TSC_AUX))
@@ -1871,6 +1865,20 @@ static int kvm_get_msr_ignored_check(struct kvm_vcpu *vcpu,
18711865
return ret;
18721866
}
18731867

1868+
static int kvm_get_msr_with_filter(struct kvm_vcpu *vcpu, u32 index, u64 *data)
1869+
{
1870+
if (!kvm_msr_allowed(vcpu, index, KVM_MSR_FILTER_READ))
1871+
return KVM_MSR_RET_FILTERED;
1872+
return kvm_get_msr_ignored_check(vcpu, index, data, false);
1873+
}
1874+
1875+
static int kvm_set_msr_with_filter(struct kvm_vcpu *vcpu, u32 index, u64 data)
1876+
{
1877+
if (!kvm_msr_allowed(vcpu, index, KVM_MSR_FILTER_WRITE))
1878+
return KVM_MSR_RET_FILTERED;
1879+
return kvm_set_msr_ignored_check(vcpu, index, data, false);
1880+
}
1881+
18741882
int kvm_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data)
18751883
{
18761884
return kvm_get_msr_ignored_check(vcpu, index, data, false);
@@ -1953,7 +1961,7 @@ int kvm_emulate_rdmsr(struct kvm_vcpu *vcpu)
19531961
u64 data;
19541962
int r;
19551963

1956-
r = kvm_get_msr(vcpu, ecx, &data);
1964+
r = kvm_get_msr_with_filter(vcpu, ecx, &data);
19571965

19581966
if (!r) {
19591967
trace_kvm_msr_read(ecx, data);
@@ -1978,7 +1986,7 @@ int kvm_emulate_wrmsr(struct kvm_vcpu *vcpu)
19781986
u64 data = kvm_read_edx_eax(vcpu);
19791987
int r;
19801988

1981-
r = kvm_set_msr(vcpu, ecx, data);
1989+
r = kvm_set_msr_with_filter(vcpu, ecx, data);
19821990

19831991
if (!r) {
19841992
trace_kvm_msr_write(ecx, data);
@@ -7631,13 +7639,13 @@ static void emulator_set_segment(struct x86_emulate_ctxt *ctxt, u16 selector,
76317639
return;
76327640
}
76337641

7634-
static int emulator_get_msr(struct x86_emulate_ctxt *ctxt,
7635-
u32 msr_index, u64 *pdata)
7642+
static int emulator_get_msr_with_filter(struct x86_emulate_ctxt *ctxt,
7643+
u32 msr_index, u64 *pdata)
76367644
{
76377645
struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
76387646
int r;
76397647

7640-
r = kvm_get_msr(vcpu, msr_index, pdata);
7648+
r = kvm_get_msr_with_filter(vcpu, msr_index, pdata);
76417649

76427650
if (r && kvm_msr_user_space(vcpu, msr_index, KVM_EXIT_X86_RDMSR, 0,
76437651
complete_emulated_rdmsr, r)) {
@@ -7648,13 +7656,13 @@ static int emulator_get_msr(struct x86_emulate_ctxt *ctxt,
76487656
return r;
76497657
}
76507658

7651-
static int emulator_set_msr(struct x86_emulate_ctxt *ctxt,
7652-
u32 msr_index, u64 data)
7659+
static int emulator_set_msr_with_filter(struct x86_emulate_ctxt *ctxt,
7660+
u32 msr_index, u64 data)
76537661
{
76547662
struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
76557663
int r;
76567664

7657-
r = kvm_set_msr(vcpu, msr_index, data);
7665+
r = kvm_set_msr_with_filter(vcpu, msr_index, data);
76587666

76597667
if (r && kvm_msr_user_space(vcpu, msr_index, KVM_EXIT_X86_WRMSR, data,
76607668
complete_emulated_msr_access, r)) {
@@ -7665,6 +7673,18 @@ static int emulator_set_msr(struct x86_emulate_ctxt *ctxt,
76657673
return r;
76667674
}
76677675

7676+
static int emulator_get_msr(struct x86_emulate_ctxt *ctxt,
7677+
u32 msr_index, u64 *pdata)
7678+
{
7679+
return kvm_get_msr(emul_to_vcpu(ctxt), msr_index, pdata);
7680+
}
7681+
7682+
static int emulator_set_msr(struct x86_emulate_ctxt *ctxt,
7683+
u32 msr_index, u64 data)
7684+
{
7685+
return kvm_set_msr(emul_to_vcpu(ctxt), msr_index, data);
7686+
}
7687+
76687688
static u64 emulator_get_smbase(struct x86_emulate_ctxt *ctxt)
76697689
{
76707690
struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
@@ -7803,6 +7823,8 @@ static const struct x86_emulate_ops emulate_ops = {
78037823
.set_dr = emulator_set_dr,
78047824
.get_smbase = emulator_get_smbase,
78057825
.set_smbase = emulator_set_smbase,
7826+
.set_msr_with_filter = emulator_set_msr_with_filter,
7827+
.get_msr_with_filter = emulator_get_msr_with_filter,
78067828
.set_msr = emulator_set_msr,
78077829
.get_msr = emulator_get_msr,
78087830
.check_pmc = emulator_check_pmc,

0 commit comments

Comments
 (0)