Skip to content

Commit b9172f9

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini: "More x86 fixes: - Logic bugs in CR0 writes and Hyper-V hypercalls - Don't use Enlightened MSR Bitmap for L3 - Remove user-triggerable WARN Plus a few selftest fixes and a regression test for the user-triggerable WARN" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: selftests: KVM: Add test to verify KVM doesn't explode on "bad" I/O KVM: x86: Don't WARN if userspace mucks with RCX during string I/O exit KVM: X86: Raise #GP when clearing CR0_PG in 64 bit mode selftests: KVM: avoid failures due to reserved HyperTransport region KVM: x86: Ignore sparse banks size for an "all CPUs", non-sparse IPI req KVM: x86: Wait for IPIs to be delivered when handling Hyper-V TLB flush hypercall KVM: x86: selftests: svm_int_ctl_test: fix intercept calculation KVM: nVMX: Don't use Enlightened MSR Bitmap for L3
2 parents b8a98b6 + 10e7a09 commit b9172f9

File tree

11 files changed

+223
-17
lines changed

11 files changed

+223
-17
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797
KVM_ARCH_REQ_FLAGS(25, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
9898
#define KVM_REQ_TLB_FLUSH_CURRENT KVM_ARCH_REQ(26)
9999
#define KVM_REQ_TLB_FLUSH_GUEST \
100-
KVM_ARCH_REQ_FLAGS(27, KVM_REQUEST_NO_WAKEUP)
100+
KVM_ARCH_REQ_FLAGS(27, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
101101
#define KVM_REQ_APF_READY KVM_ARCH_REQ(28)
102102
#define KVM_REQ_MSR_FILTER_CHANGED KVM_ARCH_REQ(29)
103103
#define KVM_REQ_UPDATE_CPU_DIRTY_LOGGING \

arch/x86/kvm/hyperv.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1922,18 +1922,21 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool
19221922

19231923
all_cpus = send_ipi_ex.vp_set.format == HV_GENERIC_SET_ALL;
19241924

1925+
if (all_cpus)
1926+
goto check_and_send_ipi;
1927+
19251928
if (!sparse_banks_len)
19261929
goto ret_success;
19271930

1928-
if (!all_cpus &&
1929-
kvm_read_guest(kvm,
1931+
if (kvm_read_guest(kvm,
19301932
hc->ingpa + offsetof(struct hv_send_ipi_ex,
19311933
vp_set.bank_contents),
19321934
sparse_banks,
19331935
sparse_banks_len))
19341936
return HV_STATUS_INVALID_HYPERCALL_INPUT;
19351937
}
19361938

1939+
check_and_send_ipi:
19371940
if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR))
19381941
return HV_STATUS_INVALID_HYPERCALL_INPUT;
19391942

arch/x86/kvm/vmx/vmx.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2646,15 +2646,6 @@ int alloc_loaded_vmcs(struct loaded_vmcs *loaded_vmcs)
26462646
if (!loaded_vmcs->msr_bitmap)
26472647
goto out_vmcs;
26482648
memset(loaded_vmcs->msr_bitmap, 0xff, PAGE_SIZE);
2649-
2650-
if (IS_ENABLED(CONFIG_HYPERV) &&
2651-
static_branch_unlikely(&enable_evmcs) &&
2652-
(ms_hyperv.nested_features & HV_X64_NESTED_MSR_BITMAP)) {
2653-
struct hv_enlightened_vmcs *evmcs =
2654-
(struct hv_enlightened_vmcs *)loaded_vmcs->vmcs;
2655-
2656-
evmcs->hv_enlightenments_control.msr_bitmap = 1;
2657-
}
26582649
}
26592650

26602651
memset(&loaded_vmcs->host_state, 0, sizeof(struct vmcs_host_state));
@@ -6842,6 +6833,19 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu)
68426833
if (err < 0)
68436834
goto free_pml;
68446835

6836+
/*
6837+
* Use Hyper-V 'Enlightened MSR Bitmap' feature when KVM runs as a
6838+
* nested (L1) hypervisor and Hyper-V in L0 supports it. Enable the
6839+
* feature only for vmcs01, KVM currently isn't equipped to realize any
6840+
* performance benefits from enabling it for vmcs02.
6841+
*/
6842+
if (IS_ENABLED(CONFIG_HYPERV) && static_branch_unlikely(&enable_evmcs) &&
6843+
(ms_hyperv.nested_features & HV_X64_NESTED_MSR_BITMAP)) {
6844+
struct hv_enlightened_vmcs *evmcs = (void *)vmx->vmcs01.vmcs;
6845+
6846+
evmcs->hv_enlightenments_control.msr_bitmap = 1;
6847+
}
6848+
68456849
/* The MSR bitmap starts with all ones */
68466850
bitmap_fill(vmx->shadow_msr_intercept.read, MAX_POSSIBLE_PASSTHROUGH_MSRS);
68476851
bitmap_fill(vmx->shadow_msr_intercept.write, MAX_POSSIBLE_PASSTHROUGH_MSRS);

arch/x86/kvm/x86.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,8 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
890890
!load_pdptrs(vcpu, vcpu->arch.walk_mmu, kvm_read_cr3(vcpu)))
891891
return 1;
892892

893-
if (!(cr0 & X86_CR0_PG) && kvm_read_cr4_bits(vcpu, X86_CR4_PCIDE))
893+
if (!(cr0 & X86_CR0_PG) &&
894+
(is_64_bit_mode(vcpu) || kvm_read_cr4_bits(vcpu, X86_CR4_PCIDE)))
894895
return 1;
895896

896897
static_call(kvm_x86_set_cr0)(vcpu, cr0);
@@ -7121,7 +7122,13 @@ static int emulator_pio_in(struct kvm_vcpu *vcpu, int size,
71217122
unsigned short port, void *val, unsigned int count)
71227123
{
71237124
if (vcpu->arch.pio.count) {
7124-
/* Complete previous iteration. */
7125+
/*
7126+
* Complete a previous iteration that required userspace I/O.
7127+
* Note, @count isn't guaranteed to match pio.count as userspace
7128+
* can modify ECX before rerunning the vCPU. Ignore any such
7129+
* shenanigans as KVM doesn't support modifying the rep count,
7130+
* and the emulator ensures @count doesn't overflow the buffer.
7131+
*/
71257132
} else {
71267133
int r = __emulator_pio_in(vcpu, size, port, count);
71277134
if (!r)
@@ -7130,7 +7137,6 @@ static int emulator_pio_in(struct kvm_vcpu *vcpu, int size,
71307137
/* Results already available, fall through. */
71317138
}
71327139

7133-
WARN_ON(count != vcpu->arch.pio.count);
71347140
complete_emulator_pio_in(vcpu, val);
71357141
return 1;
71367142
}

tools/testing/selftests/kvm/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
/x86_64/svm_int_ctl_test
3131
/x86_64/sync_regs_test
3232
/x86_64/tsc_msrs_test
33+
/x86_64/userspace_io_test
3334
/x86_64/userspace_msr_exit_test
3435
/x86_64/vmx_apic_access_test
3536
/x86_64/vmx_close_while_nested_test

tools/testing/selftests/kvm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/vmx_preemption_timer_test
5959
TEST_GEN_PROGS_x86_64 += x86_64/svm_vmcall_test
6060
TEST_GEN_PROGS_x86_64 += x86_64/svm_int_ctl_test
6161
TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test
62+
TEST_GEN_PROGS_x86_64 += x86_64/userspace_io_test
6263
TEST_GEN_PROGS_x86_64 += x86_64/userspace_msr_exit_test
6364
TEST_GEN_PROGS_x86_64 += x86_64/vmx_apic_access_test
6465
TEST_GEN_PROGS_x86_64 += x86_64/vmx_close_while_nested_test

tools/testing/selftests/kvm/include/kvm_util.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ enum vm_guest_mode {
7171

7272
#endif
7373

74+
#if defined(__x86_64__)
75+
unsigned long vm_compute_max_gfn(struct kvm_vm *vm);
76+
#else
77+
static inline unsigned long vm_compute_max_gfn(struct kvm_vm *vm)
78+
{
79+
return ((1ULL << vm->pa_bits) >> vm->page_shift) - 1;
80+
}
81+
#endif
82+
7483
#define MIN_PAGE_SIZE (1U << MIN_PAGE_SHIFT)
7584
#define PTES_PER_MIN_PAGE ptes_per_page(MIN_PAGE_SIZE)
7685

tools/testing/selftests/kvm/lib/kvm_util.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm)
302302
(1ULL << (vm->va_bits - 1)) >> vm->page_shift);
303303

304304
/* Limit physical addresses to PA-bits. */
305-
vm->max_gfn = ((1ULL << vm->pa_bits) >> vm->page_shift) - 1;
305+
vm->max_gfn = vm_compute_max_gfn(vm);
306306

307307
/* Allocate and setup memory for guest. */
308308
vm->vpages_mapped = sparsebit_alloc();

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

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,3 +1431,71 @@ struct kvm_cpuid2 *vcpu_get_supported_hv_cpuid(struct kvm_vm *vm, uint32_t vcpui
14311431

14321432
return cpuid;
14331433
}
1434+
1435+
#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx 0x68747541
1436+
#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx 0x444d4163
1437+
#define X86EMUL_CPUID_VENDOR_AuthenticAMD_edx 0x69746e65
1438+
1439+
static inline unsigned x86_family(unsigned int eax)
1440+
{
1441+
unsigned int x86;
1442+
1443+
x86 = (eax >> 8) & 0xf;
1444+
1445+
if (x86 == 0xf)
1446+
x86 += (eax >> 20) & 0xff;
1447+
1448+
return x86;
1449+
}
1450+
1451+
unsigned long vm_compute_max_gfn(struct kvm_vm *vm)
1452+
{
1453+
const unsigned long num_ht_pages = 12 << (30 - vm->page_shift); /* 12 GiB */
1454+
unsigned long ht_gfn, max_gfn, max_pfn;
1455+
uint32_t eax, ebx, ecx, edx, max_ext_leaf;
1456+
1457+
max_gfn = (1ULL << (vm->pa_bits - vm->page_shift)) - 1;
1458+
1459+
/* Avoid reserved HyperTransport region on AMD processors. */
1460+
eax = ecx = 0;
1461+
cpuid(&eax, &ebx, &ecx, &edx);
1462+
if (ebx != X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx ||
1463+
ecx != X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx ||
1464+
edx != X86EMUL_CPUID_VENDOR_AuthenticAMD_edx)
1465+
return max_gfn;
1466+
1467+
/* On parts with <40 physical address bits, the area is fully hidden */
1468+
if (vm->pa_bits < 40)
1469+
return max_gfn;
1470+
1471+
/* Before family 17h, the HyperTransport area is just below 1T. */
1472+
ht_gfn = (1 << 28) - num_ht_pages;
1473+
eax = 1;
1474+
cpuid(&eax, &ebx, &ecx, &edx);
1475+
if (x86_family(eax) < 0x17)
1476+
goto done;
1477+
1478+
/*
1479+
* Otherwise it's at the top of the physical address space, possibly
1480+
* reduced due to SME by bits 11:6 of CPUID[0x8000001f].EBX. Use
1481+
* the old conservative value if MAXPHYADDR is not enumerated.
1482+
*/
1483+
eax = 0x80000000;
1484+
cpuid(&eax, &ebx, &ecx, &edx);
1485+
max_ext_leaf = eax;
1486+
if (max_ext_leaf < 0x80000008)
1487+
goto done;
1488+
1489+
eax = 0x80000008;
1490+
cpuid(&eax, &ebx, &ecx, &edx);
1491+
max_pfn = (1ULL << ((eax & 0xff) - vm->page_shift)) - 1;
1492+
if (max_ext_leaf >= 0x8000001f) {
1493+
eax = 0x8000001f;
1494+
cpuid(&eax, &ebx, &ecx, &edx);
1495+
max_pfn >>= (ebx >> 6) & 0x3f;
1496+
}
1497+
1498+
ht_gfn = max_pfn - num_ht_pages;
1499+
done:
1500+
return min(max_gfn, ht_gfn - 1);
1501+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ static void l1_guest_code(struct svm_test_data *svm)
7575
vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK;
7676

7777
/* No intercepts for real and virtual interrupts */
78-
vmcb->control.intercept &= ~(1ULL << INTERCEPT_INTR | INTERCEPT_VINTR);
78+
vmcb->control.intercept &= ~(BIT(INTERCEPT_INTR) | BIT(INTERCEPT_VINTR));
7979

8080
/* Make a virtual interrupt VINTR_IRQ_NUMBER pending */
8181
vmcb->control.int_ctl |= V_IRQ_MASK | (0x1 << V_INTR_PRIO_SHIFT);

0 commit comments

Comments
 (0)