Skip to content

Commit 03a6c25

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Radim Krčmář: "x86: - fix NULL dereference when using userspace lapic - optimize spectre v1 mitigations by allowing guests to use LFENCE - make microcode revision configurable to prevent guests from unnecessarily blacklisting spectre v2 mitigation feature" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: x86: fix vcpu initialization with userspace lapic KVM: X86: Allow userspace to define the microcode version KVM: X86: Introduce kvm_get_msr_feature() KVM: SVM: Add MSR-based feature support for serializing LFENCE KVM: x86: Add a framework for supporting MSR-based features
2 parents 329ad5e + b7e31be commit 03a6c25

File tree

7 files changed

+179
-29
lines changed

7 files changed

+179
-29
lines changed

Documentation/virtual/kvm/api.txt

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,15 @@ memory layout to fit in user mode), check KVM_CAP_MIPS_VZ and use the
123123
flag KVM_VM_MIPS_VZ.
124124

125125

126-
4.3 KVM_GET_MSR_INDEX_LIST
126+
4.3 KVM_GET_MSR_INDEX_LIST, KVM_GET_MSR_FEATURE_INDEX_LIST
127127

128-
Capability: basic
128+
Capability: basic, KVM_CAP_GET_MSR_FEATURES for KVM_GET_MSR_FEATURE_INDEX_LIST
129129
Architectures: x86
130-
Type: system
130+
Type: system ioctl
131131
Parameters: struct kvm_msr_list (in/out)
132132
Returns: 0 on success; -1 on error
133133
Errors:
134+
EFAULT: the msr index list cannot be read from or written to
134135
E2BIG: the msr index list is to be to fit in the array specified by
135136
the user.
136137

@@ -139,16 +140,23 @@ struct kvm_msr_list {
139140
__u32 indices[0];
140141
};
141142

142-
This ioctl returns the guest msrs that are supported. The list varies
143-
by kvm version and host processor, but does not change otherwise. The
144-
user fills in the size of the indices array in nmsrs, and in return
145-
kvm adjusts nmsrs to reflect the actual number of msrs and fills in
146-
the indices array with their numbers.
143+
The user fills in the size of the indices array in nmsrs, and in return
144+
kvm adjusts nmsrs to reflect the actual number of msrs and fills in the
145+
indices array with their numbers.
146+
147+
KVM_GET_MSR_INDEX_LIST returns the guest msrs that are supported. The list
148+
varies by kvm version and host processor, but does not change otherwise.
147149

148150
Note: if kvm indicates supports MCE (KVM_CAP_MCE), then the MCE bank MSRs are
149151
not returned in the MSR list, as different vcpus can have a different number
150152
of banks, as set via the KVM_X86_SETUP_MCE ioctl.
151153

154+
KVM_GET_MSR_FEATURE_INDEX_LIST returns the list of MSRs that can be passed
155+
to the KVM_GET_MSRS system ioctl. This lets userspace probe host capabilities
156+
and processor features that are exposed via MSRs (e.g., VMX capabilities).
157+
This list also varies by kvm version and host processor, but does not change
158+
otherwise.
159+
152160

153161
4.4 KVM_CHECK_EXTENSION
154162

@@ -475,14 +483,22 @@ Support for this has been removed. Use KVM_SET_GUEST_DEBUG instead.
475483

476484
4.18 KVM_GET_MSRS
477485

478-
Capability: basic
486+
Capability: basic (vcpu), KVM_CAP_GET_MSR_FEATURES (system)
479487
Architectures: x86
480-
Type: vcpu ioctl
488+
Type: system ioctl, vcpu ioctl
481489
Parameters: struct kvm_msrs (in/out)
482-
Returns: 0 on success, -1 on error
490+
Returns: number of msrs successfully returned;
491+
-1 on error
492+
493+
When used as a system ioctl:
494+
Reads the values of MSR-based features that are available for the VM. This
495+
is similar to KVM_GET_SUPPORTED_CPUID, but it returns MSR indices and values.
496+
The list of msr-based features can be obtained using KVM_GET_MSR_FEATURE_INDEX_LIST
497+
in a system ioctl.
483498

499+
When used as a vcpu ioctl:
484500
Reads model-specific registers from the vcpu. Supported msr indices can
485-
be obtained using KVM_GET_MSR_INDEX_LIST.
501+
be obtained using KVM_GET_MSR_INDEX_LIST in a system ioctl.
486502

487503
struct kvm_msrs {
488504
__u32 nmsrs; /* number of msrs in entries */

arch/x86/include/asm/kvm_host.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,7 @@ struct kvm_vcpu_arch {
507507
u64 smi_count;
508508
bool tpr_access_reporting;
509509
u64 ia32_xss;
510+
u64 microcode_version;
510511

511512
/*
512513
* Paging state of the vcpu
@@ -1095,6 +1096,8 @@ struct kvm_x86_ops {
10951096
int (*mem_enc_op)(struct kvm *kvm, void __user *argp);
10961097
int (*mem_enc_reg_region)(struct kvm *kvm, struct kvm_enc_region *argp);
10971098
int (*mem_enc_unreg_region)(struct kvm *kvm, struct kvm_enc_region *argp);
1099+
1100+
int (*get_msr_feature)(struct kvm_msr_entry *entry);
10981101
};
10991102

11001103
struct kvm_arch_async_pf {

arch/x86/kvm/lapic.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,14 +2002,13 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
20022002

20032003
void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
20042004
{
2005-
struct kvm_lapic *apic;
2005+
struct kvm_lapic *apic = vcpu->arch.apic;
20062006
int i;
20072007

2008-
apic_debug("%s\n", __func__);
2008+
if (!apic)
2009+
return;
20092010

2010-
ASSERT(vcpu);
2011-
apic = vcpu->arch.apic;
2012-
ASSERT(apic != NULL);
2011+
apic_debug("%s\n", __func__);
20132012

20142013
/* Stop the timer in case it's a reset to an active apic */
20152014
hrtimer_cancel(&apic->lapic_timer.timer);
@@ -2568,7 +2567,6 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu)
25682567

25692568
pe = xchg(&apic->pending_events, 0);
25702569
if (test_bit(KVM_APIC_INIT, &pe)) {
2571-
kvm_lapic_reset(vcpu, true);
25722570
kvm_vcpu_reset(vcpu, true);
25732571
if (kvm_vcpu_is_bsp(apic->vcpu))
25742572
vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;

arch/x86/kvm/svm.c

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ struct vcpu_svm {
179179
uint64_t sysenter_eip;
180180
uint64_t tsc_aux;
181181

182+
u64 msr_decfg;
183+
182184
u64 next_rip;
183185

184186
u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS];
@@ -1906,6 +1908,7 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
19061908
u32 dummy;
19071909
u32 eax = 1;
19081910

1911+
vcpu->arch.microcode_version = 0x01000065;
19091912
svm->spec_ctrl = 0;
19101913

19111914
if (!init_event) {
@@ -3870,6 +3873,22 @@ static int cr8_write_interception(struct vcpu_svm *svm)
38703873
return 0;
38713874
}
38723875

3876+
static int svm_get_msr_feature(struct kvm_msr_entry *msr)
3877+
{
3878+
msr->data = 0;
3879+
3880+
switch (msr->index) {
3881+
case MSR_F10H_DECFG:
3882+
if (boot_cpu_has(X86_FEATURE_LFENCE_RDTSC))
3883+
msr->data |= MSR_F10H_DECFG_LFENCE_SERIALIZE;
3884+
break;
3885+
default:
3886+
return 1;
3887+
}
3888+
3889+
return 0;
3890+
}
3891+
38733892
static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
38743893
{
38753894
struct vcpu_svm *svm = to_svm(vcpu);
@@ -3945,9 +3964,6 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
39453964

39463965
msr_info->data = svm->spec_ctrl;
39473966
break;
3948-
case MSR_IA32_UCODE_REV:
3949-
msr_info->data = 0x01000065;
3950-
break;
39513967
case MSR_F15H_IC_CFG: {
39523968

39533969
int family, model;
@@ -3965,6 +3981,9 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
39653981
msr_info->data = 0x1E;
39663982
}
39673983
break;
3984+
case MSR_F10H_DECFG:
3985+
msr_info->data = svm->msr_decfg;
3986+
break;
39683987
default:
39693988
return kvm_get_msr_common(vcpu, msr_info);
39703989
}
@@ -4143,6 +4162,24 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
41434162
case MSR_VM_IGNNE:
41444163
vcpu_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data);
41454164
break;
4165+
case MSR_F10H_DECFG: {
4166+
struct kvm_msr_entry msr_entry;
4167+
4168+
msr_entry.index = msr->index;
4169+
if (svm_get_msr_feature(&msr_entry))
4170+
return 1;
4171+
4172+
/* Check the supported bits */
4173+
if (data & ~msr_entry.data)
4174+
return 1;
4175+
4176+
/* Don't allow the guest to change a bit, #GP */
4177+
if (!msr->host_initiated && (data ^ msr_entry.data))
4178+
return 1;
4179+
4180+
svm->msr_decfg = data;
4181+
break;
4182+
}
41464183
case MSR_IA32_APICBASE:
41474184
if (kvm_vcpu_apicv_active(vcpu))
41484185
avic_update_vapic_bar(to_svm(vcpu), data);
@@ -6833,6 +6870,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
68336870
.vcpu_unblocking = svm_vcpu_unblocking,
68346871

68356872
.update_bp_intercept = update_bp_intercept,
6873+
.get_msr_feature = svm_get_msr_feature,
68366874
.get_msr = svm_get_msr,
68376875
.set_msr = svm_set_msr,
68386876
.get_segment_base = svm_get_segment_base,

arch/x86/kvm/vmx.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3227,6 +3227,11 @@ static inline bool vmx_feature_control_msr_valid(struct kvm_vcpu *vcpu,
32273227
return !(val & ~valid_bits);
32283228
}
32293229

3230+
static int vmx_get_msr_feature(struct kvm_msr_entry *msr)
3231+
{
3232+
return 1;
3233+
}
3234+
32303235
/*
32313236
* Reads an msr value (of 'msr_index') into 'pdata'.
32323237
* Returns 0 on success, non-0 otherwise.
@@ -5767,6 +5772,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
57675772
vmx->rmode.vm86_active = 0;
57685773
vmx->spec_ctrl = 0;
57695774

5775+
vcpu->arch.microcode_version = 0x100000000ULL;
57705776
vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val();
57715777
kvm_set_cr8(vcpu, 0);
57725778

@@ -12297,6 +12303,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
1229712303
.vcpu_put = vmx_vcpu_put,
1229812304

1229912305
.update_bp_intercept = update_exception_bitmap,
12306+
.get_msr_feature = vmx_get_msr_feature,
1230012307
.get_msr = vmx_get_msr,
1230112308
.set_msr = vmx_set_msr,
1230212309
.get_segment_base = vmx_get_segment_base,

0 commit comments

Comments
 (0)