Skip to content

Commit b965592

Browse files
tlendackygregkh
authored andcommitted
KVM: SVM: Implement VIRT_SPEC_CTRL support for SSBD
commit bc226f0 upstream Expose the new virtualized architectural mechanism, VIRT_SSBD, for using speculative store bypass disable (SSBD) under SVM. This will allow guests to use SSBD on hardware that uses non-architectural mechanisms for enabling SSBD. [ tglx: Folded the migration fixup from Paolo Bonzini ] Signed-off-by: Tom Lendacky <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: David Woodhouse <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b0ef8c7 commit b965592

File tree

7 files changed

+59
-18
lines changed

7 files changed

+59
-18
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,7 @@ struct kvm_x86_ops {
864864
int (*hardware_setup)(void); /* __init */
865865
void (*hardware_unsetup)(void); /* __exit */
866866
bool (*cpu_has_accelerated_tpr)(void);
867-
bool (*cpu_has_high_real_mode_segbase)(void);
867+
bool (*has_emulated_msr)(int index);
868868
void (*cpuid_update)(struct kvm_vcpu *vcpu);
869869

870870
int (*vm_init)(struct kvm *kvm);

arch/x86/kernel/cpu/common.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,8 @@ static void init_speculation_control(struct cpuinfo_x86 *c)
735735
if (cpu_has(c, X86_FEATURE_INTEL_STIBP))
736736
set_cpu_cap(c, X86_FEATURE_STIBP);
737737

738-
if (cpu_has(c, X86_FEATURE_SPEC_CTRL_SSBD))
738+
if (cpu_has(c, X86_FEATURE_SPEC_CTRL_SSBD) ||
739+
cpu_has(c, X86_FEATURE_VIRT_SSBD))
739740
set_cpu_cap(c, X86_FEATURE_SSBD);
740741

741742
if (cpu_has(c, X86_FEATURE_AMD_IBRS)) {

arch/x86/kvm/cpuid.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
357357

358358
/* cpuid 0x80000008.ebx */
359359
const u32 kvm_cpuid_8000_0008_ebx_x86_features =
360-
F(AMD_IBPB) | F(AMD_IBRS);
360+
F(AMD_IBPB) | F(AMD_IBRS) | F(VIRT_SSBD);
361361

362362
/* cpuid 0xC0000001.edx */
363363
const u32 kvm_cpuid_C000_0001_edx_x86_features =
@@ -618,13 +618,20 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
618618
g_phys_as = phys_as;
619619
entry->eax = g_phys_as | (virt_as << 8);
620620
entry->edx = 0;
621-
/* IBRS and IBPB aren't necessarily present in hardware cpuid */
621+
/*
622+
* IBRS, IBPB and VIRT_SSBD aren't necessarily present in
623+
* hardware cpuid
624+
*/
622625
if (boot_cpu_has(X86_FEATURE_AMD_IBPB))
623626
entry->ebx |= F(AMD_IBPB);
624627
if (boot_cpu_has(X86_FEATURE_AMD_IBRS))
625628
entry->ebx |= F(AMD_IBRS);
629+
if (boot_cpu_has(X86_FEATURE_VIRT_SSBD))
630+
entry->ebx |= F(VIRT_SSBD);
626631
entry->ebx &= kvm_cpuid_8000_0008_ebx_x86_features;
627632
cpuid_mask(&entry->ebx, CPUID_8000_0008_EBX);
633+
if (boot_cpu_has(X86_FEATURE_LS_CFG_SSBD))
634+
entry->ebx |= F(VIRT_SSBD);
628635
break;
629636
}
630637
case 0x80000019:

arch/x86/kvm/cpuid.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,15 @@ static inline bool guest_cpuid_has_arch_capabilities(struct kvm_vcpu *vcpu)
190190
return best && (best->edx & bit(X86_FEATURE_ARCH_CAPABILITIES));
191191
}
192192

193+
static inline bool guest_cpuid_has_virt_ssbd(struct kvm_vcpu *vcpu)
194+
{
195+
struct kvm_cpuid_entry2 *best;
196+
197+
best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
198+
return best && (best->ebx & bit(X86_FEATURE_VIRT_SSBD));
199+
}
200+
201+
193202

194203
/*
195204
* NRIPS is provided through cpuidfn 0x8000000a.edx bit 3

arch/x86/kvm/svm.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3557,6 +3557,13 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
35573557

35583558
msr_info->data = svm->spec_ctrl;
35593559
break;
3560+
case MSR_AMD64_VIRT_SPEC_CTRL:
3561+
if (!msr_info->host_initiated &&
3562+
!guest_cpuid_has_virt_ssbd(vcpu))
3563+
return 1;
3564+
3565+
msr_info->data = svm->virt_spec_ctrl;
3566+
break;
35603567
case MSR_IA32_UCODE_REV:
35613568
msr_info->data = 0x01000065;
35623569
break;
@@ -3691,6 +3698,16 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
36913698
break;
36923699
set_msr_interception(svm->msrpm, MSR_IA32_PRED_CMD, 0, 1);
36933700
break;
3701+
case MSR_AMD64_VIRT_SPEC_CTRL:
3702+
if (!msr->host_initiated &&
3703+
!guest_cpuid_has_virt_ssbd(vcpu))
3704+
return 1;
3705+
3706+
if (data & ~SPEC_CTRL_SSBD)
3707+
return 1;
3708+
3709+
svm->virt_spec_ctrl = data;
3710+
break;
36943711
case MSR_STAR:
36953712
svm->vmcb->save.star = data;
36963713
break;
@@ -5150,7 +5167,7 @@ static bool svm_cpu_has_accelerated_tpr(void)
51505167
return false;
51515168
}
51525169

5153-
static bool svm_has_high_real_mode_segbase(void)
5170+
static bool svm_has_emulated_msr(int index)
51545171
{
51555172
return true;
51565173
}
@@ -5467,7 +5484,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
54675484
.hardware_enable = svm_hardware_enable,
54685485
.hardware_disable = svm_hardware_disable,
54695486
.cpu_has_accelerated_tpr = svm_cpu_has_accelerated_tpr,
5470-
.cpu_has_high_real_mode_segbase = svm_has_high_real_mode_segbase,
5487+
.has_emulated_msr = svm_has_emulated_msr,
54715488

54725489
.vcpu_create = svm_create_vcpu,
54735490
.vcpu_free = svm_free_vcpu,

arch/x86/kvm/vmx.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8691,9 +8691,21 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu)
86918691
}
86928692
}
86938693

8694-
static bool vmx_has_high_real_mode_segbase(void)
8694+
static bool vmx_has_emulated_msr(int index)
86958695
{
8696-
return enable_unrestricted_guest || emulate_invalid_guest_state;
8696+
switch (index) {
8697+
case MSR_IA32_SMBASE:
8698+
/*
8699+
* We cannot do SMM unless we can run the guest in big
8700+
* real mode.
8701+
*/
8702+
return enable_unrestricted_guest || emulate_invalid_guest_state;
8703+
case MSR_AMD64_VIRT_SPEC_CTRL:
8704+
/* This is AMD only. */
8705+
return false;
8706+
default:
8707+
return true;
8708+
}
86978709
}
86988710

86998711
static bool vmx_mpx_supported(void)
@@ -11346,7 +11358,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
1134611358
.hardware_enable = hardware_enable,
1134711359
.hardware_disable = hardware_disable,
1134811360
.cpu_has_accelerated_tpr = report_flexpriority,
11349-
.cpu_has_high_real_mode_segbase = vmx_has_high_real_mode_segbase,
11361+
.has_emulated_msr = vmx_has_emulated_msr,
1135011362

1135111363
.vcpu_create = vmx_create_vcpu,
1135211364
.vcpu_free = vmx_free_vcpu,

arch/x86/kvm/x86.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,7 @@ static u32 emulated_msrs[] = {
10021002
MSR_IA32_MCG_CTL,
10031003
MSR_IA32_MCG_EXT_CTL,
10041004
MSR_IA32_SMBASE,
1005+
MSR_AMD64_VIRT_SPEC_CTRL,
10051006
};
10061007

10071008
static unsigned num_emulated_msrs;
@@ -2664,7 +2665,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
26642665
* fringe case that is not enabled except via specific settings
26652666
* of the module parameters.
26662667
*/
2667-
r = kvm_x86_ops->cpu_has_high_real_mode_segbase();
2668+
r = kvm_x86_ops->has_emulated_msr(MSR_IA32_SMBASE);
26682669
break;
26692670
case KVM_CAP_COALESCED_MMIO:
26702671
r = KVM_COALESCED_MMIO_PAGE_OFFSET;
@@ -4226,14 +4227,8 @@ static void kvm_init_msr_list(void)
42264227
num_msrs_to_save = j;
42274228

42284229
for (i = j = 0; i < ARRAY_SIZE(emulated_msrs); i++) {
4229-
switch (emulated_msrs[i]) {
4230-
case MSR_IA32_SMBASE:
4231-
if (!kvm_x86_ops->cpu_has_high_real_mode_segbase())
4232-
continue;
4233-
break;
4234-
default:
4235-
break;
4236-
}
4230+
if (!kvm_x86_ops->has_emulated_msr(emulated_msrs[i]))
4231+
continue;
42374232

42384233
if (j < i)
42394234
emulated_msrs[j] = emulated_msrs[i];

0 commit comments

Comments
 (0)