Skip to content

Commit 9893deb

Browse files
committed
Merge tag 'kvm-x86-fixes-6.12-rcN' of https://github.com/kvm-x86/linux into HEAD
KVM x86 and selftests fixes for 6.12: - Increase the timeout for the memslot performance selftest to avoid false failures on arm64 and nested x86 platforms. - Fix a goof in the guest_memfd selftest where a for-loop initialized a bit mask to zero instead of BIT(0). - Disable strict aliasing when building KVM selftests to prevent the compiler from treating things like "u64 *" to "uint64_t *" cases as undefined behavior, which can lead to nasty, hard to debug failures. - Force -march=x86-64-v2 for KVM x86 selftests if and only if the uarch is supported by the compiler. - When emulating a guest TLB flush for a nested guest, flush vpid01, not vpid02, if L2 is active but VPID is disabled in vmcs12, i.e. if L2 and L1 are sharing VPID '0' (from L1's perspective). - Fix a bug in the SNP initialization flow where KVM would return '0' to userspace instead of -errno on failure.
2 parents 59b723c + e5d253c commit 9893deb

File tree

6 files changed

+39
-14
lines changed

6 files changed

+39
-14
lines changed

arch/x86/kvm/svm/sev.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,8 +450,11 @@ static int __sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp,
450450
goto e_free;
451451

452452
/* This needs to happen after SEV/SNP firmware initialization. */
453-
if (vm_type == KVM_X86_SNP_VM && snp_guest_req_init(kvm))
454-
goto e_free;
453+
if (vm_type == KVM_X86_SNP_VM) {
454+
ret = snp_guest_req_init(kvm);
455+
if (ret)
456+
goto e_free;
457+
}
455458

456459
INIT_LIST_HEAD(&sev->regions_list);
457460
INIT_LIST_HEAD(&sev->mirror_vms);

arch/x86/kvm/vmx/nested.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,11 +1197,14 @@ static void nested_vmx_transition_tlb_flush(struct kvm_vcpu *vcpu,
11971197
kvm_hv_nested_transtion_tlb_flush(vcpu, enable_ept);
11981198

11991199
/*
1200-
* If vmcs12 doesn't use VPID, L1 expects linear and combined mappings
1201-
* for *all* contexts to be flushed on VM-Enter/VM-Exit, i.e. it's a
1202-
* full TLB flush from the guest's perspective. This is required even
1203-
* if VPID is disabled in the host as KVM may need to synchronize the
1204-
* MMU in response to the guest TLB flush.
1200+
* If VPID is disabled, then guest TLB accesses use VPID=0, i.e. the
1201+
* same VPID as the host, and so architecturally, linear and combined
1202+
* mappings for VPID=0 must be flushed at VM-Enter and VM-Exit. KVM
1203+
* emulates L2 sharing L1's VPID=0 by using vpid01 while running L2,
1204+
* and so KVM must also emulate TLB flush of VPID=0, i.e. vpid01. This
1205+
* is required if VPID is disabled in KVM, as a TLB flush (there are no
1206+
* VPIDs) still occurs from L1's perspective, and KVM may need to
1207+
* synchronize the MMU in response to the guest TLB flush.
12051208
*
12061209
* Note, using TLB_FLUSH_GUEST is correct even if nested EPT is in use.
12071210
* EPT is a special snowflake, as guest-physical mappings aren't
@@ -2315,6 +2318,17 @@ static void prepare_vmcs02_early_rare(struct vcpu_vmx *vmx,
23152318

23162319
vmcs_write64(VMCS_LINK_POINTER, INVALID_GPA);
23172320

2321+
/*
2322+
* If VPID is disabled, then guest TLB accesses use VPID=0, i.e. the
2323+
* same VPID as the host. Emulate this behavior by using vpid01 for L2
2324+
* if VPID is disabled in vmcs12. Note, if VPID is disabled, VM-Enter
2325+
* and VM-Exit are architecturally required to flush VPID=0, but *only*
2326+
* VPID=0. I.e. using vpid02 would be ok (so long as KVM emulates the
2327+
* required flushes), but doing so would cause KVM to over-flush. E.g.
2328+
* if L1 runs L2 X with VPID12=1, then runs L2 Y with VPID12 disabled,
2329+
* and then runs L2 X again, then KVM can and should retain TLB entries
2330+
* for VPID12=1.
2331+
*/
23182332
if (enable_vpid) {
23192333
if (nested_cpu_has_vpid(vmcs12) && vmx->nested.vpid02)
23202334
vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->nested.vpid02);
@@ -5950,6 +5964,12 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
59505964
return nested_vmx_fail(vcpu,
59515965
VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
59525966

5967+
/*
5968+
* Always flush the effective vpid02, i.e. never flush the current VPID
5969+
* and never explicitly flush vpid01. INVVPID targets a VPID, not a
5970+
* VMCS, and so whether or not the current vmcs12 has VPID enabled is
5971+
* irrelevant (and there may not be a loaded vmcs12).
5972+
*/
59535973
vpid02 = nested_get_vpid02(vcpu);
59545974
switch (type) {
59555975
case VMX_VPID_EXTENT_INDIVIDUAL_ADDR:

arch/x86/kvm/vmx/vmx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3216,7 +3216,7 @@ void vmx_flush_tlb_all(struct kvm_vcpu *vcpu)
32163216

32173217
static inline int vmx_get_current_vpid(struct kvm_vcpu *vcpu)
32183218
{
3219-
if (is_guest_mode(vcpu))
3219+
if (is_guest_mode(vcpu) && nested_cpu_has_vpid(get_vmcs12(vcpu)))
32203220
return nested_get_vpid02(vcpu);
32213221
return to_vmx(vcpu)->vpid;
32223222
}

tools/testing/selftests/kvm/Makefile

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,16 +241,18 @@ CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
241241
-Wno-gnu-variable-sized-type-not-at-end -MD -MP -DCONFIG_64BIT \
242242
-fno-builtin-memcmp -fno-builtin-memcpy \
243243
-fno-builtin-memset -fno-builtin-strnlen \
244-
-fno-stack-protector -fno-PIE -I$(LINUX_TOOL_INCLUDE) \
245-
-I$(LINUX_TOOL_ARCH_INCLUDE) -I$(LINUX_HDR_PATH) -Iinclude \
246-
-I$(<D) -Iinclude/$(ARCH_DIR) -I ../rseq -I.. $(EXTRA_CFLAGS) \
247-
$(KHDR_INCLUDES)
244+
-fno-stack-protector -fno-PIE -fno-strict-aliasing \
245+
-I$(LINUX_TOOL_INCLUDE) -I$(LINUX_TOOL_ARCH_INCLUDE) \
246+
-I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -Iinclude/$(ARCH_DIR) \
247+
-I ../rseq -I.. $(EXTRA_CFLAGS) $(KHDR_INCLUDES)
248248
ifeq ($(ARCH),s390)
249249
CFLAGS += -march=z10
250250
endif
251251
ifeq ($(ARCH),x86)
252+
ifeq ($(shell echo "void foo(void) { }" | $(CC) -march=x86-64-v2 -x c - -c -o /dev/null 2>/dev/null; echo "$$?"),0)
252253
CFLAGS += -march=x86-64-v2
253254
endif
255+
endif
254256
ifeq ($(ARCH),arm64)
255257
tools_dir := $(top_srcdir)/tools
256258
arm64_tools_dir := $(tools_dir)/arch/arm64/tools/

tools/testing/selftests/kvm/guest_memfd_test.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ static void test_create_guest_memfd_invalid(struct kvm_vm *vm)
134134
size);
135135
}
136136

137-
for (flag = 0; flag; flag <<= 1) {
137+
for (flag = BIT(0); flag; flag <<= 1) {
138138
fd = __vm_create_guest_memfd(vm, page_size, flag);
139139
TEST_ASSERT(fd == -1 && errno == EINVAL,
140140
"guest_memfd() with flag '0x%lx' should fail with EINVAL",

tools/testing/selftests/kvm/memslot_perf_test.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ static bool _guest_should_exit(void)
417417
*/
418418
static noinline void host_perform_sync(struct sync_area *sync)
419419
{
420-
alarm(2);
420+
alarm(10);
421421

422422
atomic_store_explicit(&sync->sync_flag, true, memory_order_release);
423423
while (atomic_load_explicit(&sync->sync_flag, memory_order_acquire))

0 commit comments

Comments
 (0)