Skip to content

Commit d1d93fa

Browse files
tlendackyrkrcmar
authored andcommitted
KVM: SVM: Add MSR-based feature support for serializing LFENCE
In order to determine if LFENCE is a serializing instruction on AMD processors, MSR 0xc0011029 (MSR_F10H_DECFG) must be read and the state of bit 1 checked. This patch will add support to allow a guest to properly make this determination. Add the MSR feature callback operation to svm.c and add MSR 0xc0011029 to the list of MSR-based features. If LFENCE is serializing, then the feature is supported, allowing the hypervisor to set the value of the MSR that guest will see. Support is also added to write (hypervisor only) and read the MSR value for the guest. A write by the guest will result in a #GP. A read by the guest will return the value as set by the host. In this way, the support to expose the feature to the guest is controlled by the hypervisor. Reviewed-by: Paolo Bonzini <[email protected]> Signed-off-by: Tom Lendacky <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]> Signed-off-by: Radim Krčmář <[email protected]>
1 parent 801e459 commit d1d93fa

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

arch/x86/kvm/svm.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ struct vcpu_svm {
178178
uint64_t sysenter_eip;
179179
uint64_t tsc_aux;
180180

181+
u64 msr_decfg;
182+
181183
u64 next_rip;
182184

183185
u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS];
@@ -3871,7 +3873,18 @@ static int cr8_write_interception(struct vcpu_svm *svm)
38713873

38723874
static int svm_get_msr_feature(struct kvm_msr_entry *msr)
38733875
{
3874-
return 1;
3876+
msr->data = 0;
3877+
3878+
switch (msr->index) {
3879+
case MSR_F10H_DECFG:
3880+
if (boot_cpu_has(X86_FEATURE_LFENCE_RDTSC))
3881+
msr->data |= MSR_F10H_DECFG_LFENCE_SERIALIZE;
3882+
break;
3883+
default:
3884+
return 1;
3885+
}
3886+
3887+
return 0;
38753888
}
38763889

38773890
static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
@@ -3969,6 +3982,9 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
39693982
msr_info->data = 0x1E;
39703983
}
39713984
break;
3985+
case MSR_F10H_DECFG:
3986+
msr_info->data = svm->msr_decfg;
3987+
break;
39723988
default:
39733989
return kvm_get_msr_common(vcpu, msr_info);
39743990
}
@@ -4147,6 +4163,24 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
41474163
case MSR_VM_IGNNE:
41484164
vcpu_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data);
41494165
break;
4166+
case MSR_F10H_DECFG: {
4167+
struct kvm_msr_entry msr_entry;
4168+
4169+
msr_entry.index = msr->index;
4170+
if (svm_get_msr_feature(&msr_entry))
4171+
return 1;
4172+
4173+
/* Check the supported bits */
4174+
if (data & ~msr_entry.data)
4175+
return 1;
4176+
4177+
/* Don't allow the guest to change a bit, #GP */
4178+
if (!msr->host_initiated && (data ^ msr_entry.data))
4179+
return 1;
4180+
4181+
svm->msr_decfg = data;
4182+
break;
4183+
}
41504184
case MSR_IA32_APICBASE:
41514185
if (kvm_vcpu_apicv_active(vcpu))
41524186
avic_update_vapic_bar(to_svm(vcpu), data);

arch/x86/kvm/x86.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,7 @@ static unsigned num_emulated_msrs;
10541054
* can be used by a hypervisor to validate requested CPU features.
10551055
*/
10561056
static u32 msr_based_features[] = {
1057+
MSR_F10H_DECFG,
10571058
};
10581059

10591060
static unsigned int num_msr_based_features;

0 commit comments

Comments
 (0)