Skip to content

Commit 33d0403

Browse files
committed
Merge tag 'kvm-x86-misc-6.8' of https://github.com/kvm-x86/linux into HEAD
KVM x86 misc changes for 6.8: - Turn off KVM_WERROR by default for all configs so that it's not inadvertantly enabled by non-KVM developers, which can be problematic for subsystems that require no regressions for W=1 builds. - Advertise all of the host-supported CPUID bits that enumerate IA32_SPEC_CTRL "features". - Don't force a masterclock update when a vCPU synchronizes to the current TSC generation, as updating the masterclock can cause kvmclock's time to "jump" unexpectedly, e.g. when userspace hotplugs a pre-created vCPU. - Use RIP-relative address to read kvm_rebooting in the VM-Enter fault paths, partly as a super minor optimization, but mostly to make KVM play nice with position independent executable builds.
2 parents 0afdfd8 + 15223c4 commit 33d0403

6 files changed

Lines changed: 70 additions & 41 deletions

File tree

arch/x86/kvm/Kconfig

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,13 @@ config KVM
6262

6363
config KVM_WERROR
6464
bool "Compile KVM with -Werror"
65-
# KASAN may cause the build to fail due to larger frames
66-
default y if X86_64 && !KASAN
67-
# We use the dependency on !COMPILE_TEST to not be enabled
68-
# blindly in allmodconfig or allyesconfig configurations
69-
depends on KVM
70-
depends on (X86_64 && !KASAN) || !COMPILE_TEST
71-
depends on EXPERT
65+
# Disallow KVM's -Werror if KASAN is enabled, e.g. to guard against
66+
# randomized configs from selecting KVM_WERROR=y, which doesn't play
67+
# nice with KASAN. KASAN builds generates warnings for the default
68+
# FRAME_WARN, i.e. KVM_WERROR=y with KASAN=y requires special tuning.
69+
# Building KVM with -Werror and KASAN is still doable via enabling
70+
# the kernel-wide WERROR=y.
71+
depends on KVM && EXPERT && !KASAN
7272
help
7373
Add -Werror to the build flags for KVM.
7474

arch/x86/kvm/cpuid.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,11 @@ void kvm_set_cpu_caps(void)
685685
F(AMX_COMPLEX)
686686
);
687687

688+
kvm_cpu_cap_init_kvm_defined(CPUID_7_2_EDX,
689+
F(INTEL_PSFD) | F(IPRED_CTRL) | F(RRSBA_CTRL) | F(DDPD_U) |
690+
F(BHI_CTRL) | F(MCDT_NO)
691+
);
692+
688693
kvm_cpu_cap_mask(CPUID_D_1_EAX,
689694
F(XSAVEOPT) | F(XSAVEC) | F(XGETBV1) | F(XSAVES) | f_xfd
690695
);
@@ -966,13 +971,13 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
966971
break;
967972
/* function 7 has additional index. */
968973
case 7:
969-
entry->eax = min(entry->eax, 1u);
974+
max_idx = entry->eax = min(entry->eax, 2u);
970975
cpuid_entry_override(entry, CPUID_7_0_EBX);
971976
cpuid_entry_override(entry, CPUID_7_ECX);
972977
cpuid_entry_override(entry, CPUID_7_EDX);
973978

974-
/* KVM only supports 0x7.0 and 0x7.1, capped above via min(). */
975-
if (entry->eax == 1) {
979+
/* KVM only supports up to 0x7.2, capped above via min(). */
980+
if (max_idx >= 1) {
976981
entry = do_host_cpuid(array, function, 1);
977982
if (!entry)
978983
goto out;
@@ -982,6 +987,16 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
982987
entry->ebx = 0;
983988
entry->ecx = 0;
984989
}
990+
if (max_idx >= 2) {
991+
entry = do_host_cpuid(array, function, 2);
992+
if (!entry)
993+
goto out;
994+
995+
cpuid_entry_override(entry, CPUID_7_2_EDX);
996+
entry->ecx = 0;
997+
entry->ebx = 0;
998+
entry->eax = 0;
999+
}
9851000
break;
9861001
case 0xa: { /* Architectural Performance Monitoring */
9871002
union cpuid10_eax eax;

arch/x86/kvm/reverse_cpuid.h

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ enum kvm_only_cpuid_leafs {
1616
CPUID_7_1_EDX,
1717
CPUID_8000_0007_EDX,
1818
CPUID_8000_0022_EAX,
19+
CPUID_7_2_EDX,
1920
NR_KVM_CPU_CAPS,
2021

2122
NKVMCAPINTS = NR_KVM_CPU_CAPS - NCAPINTS,
@@ -46,6 +47,14 @@ enum kvm_only_cpuid_leafs {
4647
#define X86_FEATURE_AMX_COMPLEX KVM_X86_FEATURE(CPUID_7_1_EDX, 8)
4748
#define X86_FEATURE_PREFETCHITI KVM_X86_FEATURE(CPUID_7_1_EDX, 14)
4849

50+
/* Intel-defined sub-features, CPUID level 0x00000007:2 (EDX) */
51+
#define X86_FEATURE_INTEL_PSFD KVM_X86_FEATURE(CPUID_7_2_EDX, 0)
52+
#define X86_FEATURE_IPRED_CTRL KVM_X86_FEATURE(CPUID_7_2_EDX, 1)
53+
#define KVM_X86_FEATURE_RRSBA_CTRL KVM_X86_FEATURE(CPUID_7_2_EDX, 2)
54+
#define X86_FEATURE_DDPD_U KVM_X86_FEATURE(CPUID_7_2_EDX, 3)
55+
#define X86_FEATURE_BHI_CTRL KVM_X86_FEATURE(CPUID_7_2_EDX, 4)
56+
#define X86_FEATURE_MCDT_NO KVM_X86_FEATURE(CPUID_7_2_EDX, 5)
57+
4958
/* CPUID level 0x80000007 (EDX). */
5059
#define KVM_X86_FEATURE_CONSTANT_TSC KVM_X86_FEATURE(CPUID_8000_0007_EDX, 8)
5160

@@ -80,6 +89,7 @@ static const struct cpuid_reg reverse_cpuid[] = {
8089
[CPUID_8000_0007_EDX] = {0x80000007, 0, CPUID_EDX},
8190
[CPUID_8000_0021_EAX] = {0x80000021, 0, CPUID_EAX},
8291
[CPUID_8000_0022_EAX] = {0x80000022, 0, CPUID_EAX},
92+
[CPUID_7_2_EDX] = { 7, 2, CPUID_EDX},
8393
};
8494

8595
/*
@@ -106,18 +116,19 @@ static __always_inline void reverse_cpuid_check(unsigned int x86_leaf)
106116
*/
107117
static __always_inline u32 __feature_translate(int x86_feature)
108118
{
109-
if (x86_feature == X86_FEATURE_SGX1)
110-
return KVM_X86_FEATURE_SGX1;
111-
else if (x86_feature == X86_FEATURE_SGX2)
112-
return KVM_X86_FEATURE_SGX2;
113-
else if (x86_feature == X86_FEATURE_SGX_EDECCSSA)
114-
return KVM_X86_FEATURE_SGX_EDECCSSA;
115-
else if (x86_feature == X86_FEATURE_CONSTANT_TSC)
116-
return KVM_X86_FEATURE_CONSTANT_TSC;
117-
else if (x86_feature == X86_FEATURE_PERFMON_V2)
118-
return KVM_X86_FEATURE_PERFMON_V2;
119-
120-
return x86_feature;
119+
#define KVM_X86_TRANSLATE_FEATURE(f) \
120+
case X86_FEATURE_##f: return KVM_X86_FEATURE_##f
121+
122+
switch (x86_feature) {
123+
KVM_X86_TRANSLATE_FEATURE(SGX1);
124+
KVM_X86_TRANSLATE_FEATURE(SGX2);
125+
KVM_X86_TRANSLATE_FEATURE(SGX_EDECCSSA);
126+
KVM_X86_TRANSLATE_FEATURE(CONSTANT_TSC);
127+
KVM_X86_TRANSLATE_FEATURE(PERFMON_V2);
128+
KVM_X86_TRANSLATE_FEATURE(RRSBA_CTRL);
129+
default:
130+
return x86_feature;
131+
}
121132
}
122133

123134
static __always_inline u32 __feature_leaf(int x86_feature)

arch/x86/kvm/svm/vmenter.S

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,16 +270,16 @@ SYM_FUNC_START(__svm_vcpu_run)
270270
RESTORE_GUEST_SPEC_CTRL_BODY
271271
RESTORE_HOST_SPEC_CTRL_BODY
272272

273-
10: cmpb $0, kvm_rebooting
273+
10: cmpb $0, _ASM_RIP(kvm_rebooting)
274274
jne 2b
275275
ud2
276-
30: cmpb $0, kvm_rebooting
276+
30: cmpb $0, _ASM_RIP(kvm_rebooting)
277277
jne 4b
278278
ud2
279-
50: cmpb $0, kvm_rebooting
279+
50: cmpb $0, _ASM_RIP(kvm_rebooting)
280280
jne 6b
281281
ud2
282-
70: cmpb $0, kvm_rebooting
282+
70: cmpb $0, _ASM_RIP(kvm_rebooting)
283283
jne 8b
284284
ud2
285285

@@ -381,7 +381,7 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run)
381381
RESTORE_GUEST_SPEC_CTRL_BODY
382382
RESTORE_HOST_SPEC_CTRL_BODY
383383

384-
3: cmpb $0, kvm_rebooting
384+
3: cmpb $0, _ASM_RIP(kvm_rebooting)
385385
jne 2b
386386
ud2
387387

arch/x86/kvm/vmx/vmenter.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ SYM_INNER_LABEL_ALIGN(vmx_vmexit, SYM_L_GLOBAL)
289289
RET
290290

291291
.Lfixup:
292-
cmpb $0, kvm_rebooting
292+
cmpb $0, _ASM_RIP(kvm_rebooting)
293293
jne .Lvmfail
294294
ud2
295295
.Lvmfail:

arch/x86/kvm/x86.c

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2513,26 +2513,29 @@ static inline int gtod_is_based_on_tsc(int mode)
25132513
}
25142514
#endif
25152515

2516-
static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
2516+
static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu, bool new_generation)
25172517
{
25182518
#ifdef CONFIG_X86_64
2519-
bool vcpus_matched;
25202519
struct kvm_arch *ka = &vcpu->kvm->arch;
25212520
struct pvclock_gtod_data *gtod = &pvclock_gtod_data;
25222521

2523-
vcpus_matched = (ka->nr_vcpus_matched_tsc + 1 ==
2524-
atomic_read(&vcpu->kvm->online_vcpus));
2522+
/*
2523+
* To use the masterclock, the host clocksource must be based on TSC
2524+
* and all vCPUs must have matching TSCs. Note, the count for matching
2525+
* vCPUs doesn't include the reference vCPU, hence "+1".
2526+
*/
2527+
bool use_master_clock = (ka->nr_vcpus_matched_tsc + 1 ==
2528+
atomic_read(&vcpu->kvm->online_vcpus)) &&
2529+
gtod_is_based_on_tsc(gtod->clock.vclock_mode);
25252530

25262531
/*
2527-
* Once the masterclock is enabled, always perform request in
2528-
* order to update it.
2529-
*
2530-
* In order to enable masterclock, the host clocksource must be TSC
2531-
* and the vcpus need to have matched TSCs. When that happens,
2532-
* perform request to enable masterclock.
2532+
* Request a masterclock update if the masterclock needs to be toggled
2533+
* on/off, or when starting a new generation and the masterclock is
2534+
* enabled (compute_guest_tsc() requires the masterclock snapshot to be
2535+
* taken _after_ the new generation is created).
25332536
*/
2534-
if (ka->use_master_clock ||
2535-
(gtod_is_based_on_tsc(gtod->clock.vclock_mode) && vcpus_matched))
2537+
if ((ka->use_master_clock && new_generation) ||
2538+
(ka->use_master_clock != use_master_clock))
25362539
kvm_make_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu);
25372540

25382541
trace_kvm_track_tsc(vcpu->vcpu_id, ka->nr_vcpus_matched_tsc,
@@ -2709,7 +2712,7 @@ static void __kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 offset, u64 tsc,
27092712
vcpu->arch.this_tsc_nsec = kvm->arch.cur_tsc_nsec;
27102713
vcpu->arch.this_tsc_write = kvm->arch.cur_tsc_write;
27112714

2712-
kvm_track_tsc_matching(vcpu);
2715+
kvm_track_tsc_matching(vcpu, !matched);
27132716
}
27142717

27152718
static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 *user_value)

0 commit comments

Comments
 (0)