Skip to content

Commit

Permalink
Merge tag 'kvm-x86-fixes-6.10-rcN' of https://github.com/kvm-x86/linux
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
bonzini committed Jun 21, 2024
2 parents cf6d9d2 + c3f3edf commit dee67a9
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 7 deletions.
1 change: 1 addition & 0 deletions tools/testing/selftests/kvm/include/x86_64/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ struct kvm_x86_cpu_property {
#define X86_PROPERTY_MAX_EXT_LEAF KVM_X86_CPU_PROPERTY(0x80000000, 0, EAX, 0, 31)
#define X86_PROPERTY_MAX_PHY_ADDR KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 0, 7)
#define X86_PROPERTY_MAX_VIRT_ADDR KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 8, 15)
#define X86_PROPERTY_GUEST_MAX_PHY_ADDR KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 16, 23)
#define X86_PROPERTY_SEV_C_BIT KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 0, 5)
#define X86_PROPERTY_PHYS_ADDR_REDUCTION KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 6, 11)

Expand Down
15 changes: 13 additions & 2 deletions tools/testing/selftests/kvm/lib/x86_64/processor.c
Original file line number Diff line number Diff line change
Expand Up @@ -1247,9 +1247,20 @@ unsigned long vm_compute_max_gfn(struct kvm_vm *vm)
{
const unsigned long num_ht_pages = 12 << (30 - vm->page_shift); /* 12 GiB */
unsigned long ht_gfn, max_gfn, max_pfn;
uint8_t maxphyaddr;
uint8_t maxphyaddr, guest_maxphyaddr;

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

max_gfn = (1ULL << (guest_maxphyaddr - vm->page_shift)) - 1;

/* Avoid reserved HyperTransport region on AMD processors. */
if (!host_cpu_is_amd)
Expand Down
4 changes: 2 additions & 2 deletions tools/testing/selftests/kvm/x86_64/sev_init2_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ void test_features(uint32_t vm_type, uint64_t supported_features)
int i;

for (i = 0; i < 64; i++) {
if (!(supported_features & (1u << i)))
if (!(supported_features & BIT_ULL(i)))
test_init2_invalid(vm_type,
&(struct kvm_sev_init){ .vmsa_features = BIT_ULL(i) },
"unknown feature");
else if (KNOWN_FEATURES & (1u << i))
else if (KNOWN_FEATURES & BIT_ULL(i))
test_init2(vm_type,
&(struct kvm_sev_init){ .vmsa_features = BIT_ULL(i) });
}
Expand Down
8 changes: 5 additions & 3 deletions virt/kvm/kvm_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ static __always_inline kvm_mn_ret_t __kvm_handle_hva_range(struct kvm *kvm,
range->on_lock(kvm);

if (IS_KVM_NULL_FN(range->handler))
break;
goto mmu_unlock;
}
r.ret |= range->handler(kvm, &gfn_range);
}
Expand All @@ -660,6 +660,7 @@ static __always_inline kvm_mn_ret_t __kvm_handle_hva_range(struct kvm *kvm,
if (range->flush_on_ret && r.ret)
kvm_flush_remote_tlbs(kvm);

mmu_unlock:
if (r.found_memslot)
KVM_MMU_UNLOCK(kvm);

Expand Down Expand Up @@ -4025,12 +4026,13 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool yield_to_kernel_mode)
{
struct kvm *kvm = me->kvm;
struct kvm_vcpu *vcpu;
int last_boosted_vcpu = me->kvm->last_boosted_vcpu;
int last_boosted_vcpu;
unsigned long i;
int yielded = 0;
int try = 3;
int pass;

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

yielded = kvm_vcpu_yield_to(vcpu);
if (yielded > 0) {
kvm->last_boosted_vcpu = i;
WRITE_ONCE(kvm->last_boosted_vcpu, i);
break;
} else if (yielded < 0) {
try--;
Expand Down

0 comments on commit dee67a9

Please sign in to comment.