Skip to content

Commit dee67a9

Browse files
committed
Merge tag 'kvm-x86-fixes-6.10-rcN' of https://github.com/kvm-x86/linux into HEAD
KVM fixes for 6.10 - Fix a "shift too big" goof in the KVM_SEV_INIT2 selftest. - Compute the max mappable gfn for KVM selftests on x86 using GuestMaxPhyAddr from KVM's supported CPUID (if it's available). - Fix a race in kvm_vcpu_on_spin() by ensuring loads and stores are atomic. - Fix technically benign bug in __kvm_handle_hva_range() where KVM consumes the return from a void-returning function as if it were a boolean.
2 parents cf6d9d2 + c3f3edf commit dee67a9

File tree

4 files changed

+21
-7
lines changed

4 files changed

+21
-7
lines changed

tools/testing/selftests/kvm/include/x86_64/processor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ struct kvm_x86_cpu_property {
277277
#define X86_PROPERTY_MAX_EXT_LEAF KVM_X86_CPU_PROPERTY(0x80000000, 0, EAX, 0, 31)
278278
#define X86_PROPERTY_MAX_PHY_ADDR KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 0, 7)
279279
#define X86_PROPERTY_MAX_VIRT_ADDR KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 8, 15)
280+
#define X86_PROPERTY_GUEST_MAX_PHY_ADDR KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 16, 23)
280281
#define X86_PROPERTY_SEV_C_BIT KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 0, 5)
281282
#define X86_PROPERTY_PHYS_ADDR_REDUCTION KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 6, 11)
282283

tools/testing/selftests/kvm/lib/x86_64/processor.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,9 +1247,20 @@ unsigned long vm_compute_max_gfn(struct kvm_vm *vm)
12471247
{
12481248
const unsigned long num_ht_pages = 12 << (30 - vm->page_shift); /* 12 GiB */
12491249
unsigned long ht_gfn, max_gfn, max_pfn;
1250-
uint8_t maxphyaddr;
1250+
uint8_t maxphyaddr, guest_maxphyaddr;
12511251

1252-
max_gfn = (1ULL << (vm->pa_bits - vm->page_shift)) - 1;
1252+
/*
1253+
* Use "guest MAXPHYADDR" from KVM if it's available. Guest MAXPHYADDR
1254+
* enumerates the max _mappable_ GPA, which can be less than the raw
1255+
* MAXPHYADDR, e.g. if MAXPHYADDR=52, KVM is using TDP, and the CPU
1256+
* doesn't support 5-level TDP.
1257+
*/
1258+
guest_maxphyaddr = kvm_cpu_property(X86_PROPERTY_GUEST_MAX_PHY_ADDR);
1259+
guest_maxphyaddr = guest_maxphyaddr ?: vm->pa_bits;
1260+
TEST_ASSERT(guest_maxphyaddr <= vm->pa_bits,
1261+
"Guest MAXPHYADDR should never be greater than raw MAXPHYADDR");
1262+
1263+
max_gfn = (1ULL << (guest_maxphyaddr - vm->page_shift)) - 1;
12531264

12541265
/* Avoid reserved HyperTransport region on AMD processors. */
12551266
if (!host_cpu_is_amd)

tools/testing/selftests/kvm/x86_64/sev_init2_tests.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,11 @@ void test_features(uint32_t vm_type, uint64_t supported_features)
105105
int i;
106106

107107
for (i = 0; i < 64; i++) {
108-
if (!(supported_features & (1u << i)))
108+
if (!(supported_features & BIT_ULL(i)))
109109
test_init2_invalid(vm_type,
110110
&(struct kvm_sev_init){ .vmsa_features = BIT_ULL(i) },
111111
"unknown feature");
112-
else if (KNOWN_FEATURES & (1u << i))
112+
else if (KNOWN_FEATURES & BIT_ULL(i))
113113
test_init2(vm_type,
114114
&(struct kvm_sev_init){ .vmsa_features = BIT_ULL(i) });
115115
}

virt/kvm/kvm_main.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ static __always_inline kvm_mn_ret_t __kvm_handle_hva_range(struct kvm *kvm,
651651
range->on_lock(kvm);
652652

653653
if (IS_KVM_NULL_FN(range->handler))
654-
break;
654+
goto mmu_unlock;
655655
}
656656
r.ret |= range->handler(kvm, &gfn_range);
657657
}
@@ -660,6 +660,7 @@ static __always_inline kvm_mn_ret_t __kvm_handle_hva_range(struct kvm *kvm,
660660
if (range->flush_on_ret && r.ret)
661661
kvm_flush_remote_tlbs(kvm);
662662

663+
mmu_unlock:
663664
if (r.found_memslot)
664665
KVM_MMU_UNLOCK(kvm);
665666

@@ -4025,12 +4026,13 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool yield_to_kernel_mode)
40254026
{
40264027
struct kvm *kvm = me->kvm;
40274028
struct kvm_vcpu *vcpu;
4028-
int last_boosted_vcpu = me->kvm->last_boosted_vcpu;
4029+
int last_boosted_vcpu;
40294030
unsigned long i;
40304031
int yielded = 0;
40314032
int try = 3;
40324033
int pass;
40334034

4035+
last_boosted_vcpu = READ_ONCE(kvm->last_boosted_vcpu);
40344036
kvm_vcpu_set_in_spin_loop(me, true);
40354037
/*
40364038
* We boost the priority of a VCPU that is runnable but not
@@ -4068,7 +4070,7 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool yield_to_kernel_mode)
40684070

40694071
yielded = kvm_vcpu_yield_to(vcpu);
40704072
if (yielded > 0) {
4071-
kvm->last_boosted_vcpu = i;
4073+
WRITE_ONCE(kvm->last_boosted_vcpu, i);
40724074
break;
40734075
} else if (yielded < 0) {
40744076
try--;

0 commit comments

Comments
 (0)