Skip to content

Commit 58ddfe6

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini: - ARM/ARM64 locking fixes - x86 fixes: PCID, UMIP, locking - improved support for recent Windows version that have a 2048 Hz APIC timer - rename KVM_HINTS_DEDICATED CPUID bit to KVM_HINTS_REALTIME - better behaved selftests * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: kvm: rename KVM_HINTS_DEDICATED to KVM_HINTS_REALTIME KVM: arm/arm64: VGIC/ITS save/restore: protect kvm_read_guest() calls KVM: arm/arm64: VGIC/ITS: protect kvm_read_guest() calls with SRCU lock KVM: arm/arm64: VGIC/ITS: Promote irq_lock() in update_affinity KVM: arm/arm64: Properly protect VGIC locks from IRQs KVM: X86: Lower the default timer frequency limit to 200us KVM: vmx: update sec exec controls for UMIP iff emulating UMIP kvm: x86: Suppress CR3_PCID_INVD bit only when PCIDs are enabled KVM: selftests: exit with 0 status code when tests cannot be run KVM: hyperv: idr_find needs RCU protection x86: Delay skip of emulated hypercall instruction KVM: Extend MAX_IRQ_ROUTES to 4096 for all archs
2 parents 7c9a0fc + 633711e commit 58ddfe6

File tree

18 files changed

+157
-87
lines changed

18 files changed

+157
-87
lines changed

Documentation/virtual/kvm/cpuid.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ KVM_FEATURE_CLOCKSOURCE_STABLE_BIT || 24 || host will warn if no guest-side
7272

7373
flag || value || meaning
7474
==================================================================================
75-
KVM_HINTS_DEDICATED || 0 || guest checks this feature bit to
76-
|| || determine if there is vCPU pinning
77-
|| || and there is no vCPU over-commitment,
75+
KVM_HINTS_REALTIME || 0 || guest checks this feature bit to
76+
|| || determine that vCPUs are never
77+
|| || preempted for an unlimited time,
7878
|| || allowing optimizations
7979
----------------------------------------------------------------------------------

arch/arm/include/asm/kvm_mmu.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,22 @@ static inline unsigned int kvm_get_vmid_bits(void)
309309
return 8;
310310
}
311311

312+
/*
313+
* We are not in the kvm->srcu critical section most of the time, so we take
314+
* the SRCU read lock here. Since we copy the data from the user page, we
315+
* can immediately drop the lock again.
316+
*/
317+
static inline int kvm_read_guest_lock(struct kvm *kvm,
318+
gpa_t gpa, void *data, unsigned long len)
319+
{
320+
int srcu_idx = srcu_read_lock(&kvm->srcu);
321+
int ret = kvm_read_guest(kvm, gpa, data, len);
322+
323+
srcu_read_unlock(&kvm->srcu, srcu_idx);
324+
325+
return ret;
326+
}
327+
312328
static inline void *kvm_get_hyp_vector(void)
313329
{
314330
return kvm_ksym_ref(__kvm_hyp_vector);

arch/arm64/include/asm/kvm_mmu.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,22 @@ static inline unsigned int kvm_get_vmid_bits(void)
360360
return (cpuid_feature_extract_unsigned_field(reg, ID_AA64MMFR1_VMIDBITS_SHIFT) == 2) ? 16 : 8;
361361
}
362362

363+
/*
364+
* We are not in the kvm->srcu critical section most of the time, so we take
365+
* the SRCU read lock here. Since we copy the data from the user page, we
366+
* can immediately drop the lock again.
367+
*/
368+
static inline int kvm_read_guest_lock(struct kvm *kvm,
369+
gpa_t gpa, void *data, unsigned long len)
370+
{
371+
int srcu_idx = srcu_read_lock(&kvm->srcu);
372+
int ret = kvm_read_guest(kvm, gpa, data, len);
373+
374+
srcu_read_unlock(&kvm->srcu, srcu_idx);
375+
376+
return ret;
377+
}
378+
363379
#ifdef CONFIG_KVM_INDIRECT_VECTORS
364380
/*
365381
* EL2 vectors can be mapped and rerouted in a number of ways,

arch/x86/include/uapi/asm/kvm_para.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#define KVM_FEATURE_PV_TLB_FLUSH 9
3030
#define KVM_FEATURE_ASYNC_PF_VMEXIT 10
3131

32-
#define KVM_HINTS_DEDICATED 0
32+
#define KVM_HINTS_REALTIME 0
3333

3434
/* The last 8 bits are used to indicate how to interpret the flags field
3535
* in pvclock structure. If no bits are set, all flags are ignored.

arch/x86/kernel/kvm.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ static void __init sev_map_percpu_data(void)
457457
static void __init kvm_smp_prepare_cpus(unsigned int max_cpus)
458458
{
459459
native_smp_prepare_cpus(max_cpus);
460-
if (kvm_para_has_hint(KVM_HINTS_DEDICATED))
460+
if (kvm_para_has_hint(KVM_HINTS_REALTIME))
461461
static_branch_disable(&virt_spin_lock_key);
462462
}
463463

@@ -553,7 +553,7 @@ static void __init kvm_guest_init(void)
553553
}
554554

555555
if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
556-
!kvm_para_has_hint(KVM_HINTS_DEDICATED) &&
556+
!kvm_para_has_hint(KVM_HINTS_REALTIME) &&
557557
kvm_para_has_feature(KVM_FEATURE_STEAL_TIME))
558558
pv_mmu_ops.flush_tlb_others = kvm_flush_tlb_others;
559559

@@ -649,7 +649,7 @@ static __init int kvm_setup_pv_tlb_flush(void)
649649
int cpu;
650650

651651
if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
652-
!kvm_para_has_hint(KVM_HINTS_DEDICATED) &&
652+
!kvm_para_has_hint(KVM_HINTS_REALTIME) &&
653653
kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) {
654654
for_each_possible_cpu(cpu) {
655655
zalloc_cpumask_var_node(per_cpu_ptr(&__pv_tlb_mask, cpu),
@@ -745,7 +745,7 @@ void __init kvm_spinlock_init(void)
745745
if (!kvm_para_has_feature(KVM_FEATURE_PV_UNHALT))
746746
return;
747747

748-
if (kvm_para_has_hint(KVM_HINTS_DEDICATED))
748+
if (kvm_para_has_hint(KVM_HINTS_REALTIME))
749749
return;
750750

751751
__pv_init_lock_hash();

arch/x86/kvm/hyperv.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,7 @@ static int kvm_hv_hypercall_complete_userspace(struct kvm_vcpu *vcpu)
12651265
struct kvm_run *run = vcpu->run;
12661266

12671267
kvm_hv_hypercall_set_result(vcpu, run->hyperv.u.hcall.result);
1268-
return 1;
1268+
return kvm_skip_emulated_instruction(vcpu);
12691269
}
12701270

12711271
static u16 kvm_hvcall_signal_event(struct kvm_vcpu *vcpu, bool fast, u64 param)
@@ -1296,8 +1296,10 @@ static u16 kvm_hvcall_signal_event(struct kvm_vcpu *vcpu, bool fast, u64 param)
12961296
if (param & ~KVM_HYPERV_CONN_ID_MASK)
12971297
return HV_STATUS_INVALID_HYPERCALL_INPUT;
12981298

1299-
/* conn_to_evt is protected by vcpu->kvm->srcu */
1299+
/* the eventfd is protected by vcpu->kvm->srcu, but conn_to_evt isn't */
1300+
rcu_read_lock();
13001301
eventfd = idr_find(&vcpu->kvm->arch.hyperv.conn_to_evt, param);
1302+
rcu_read_unlock();
13011303
if (!eventfd)
13021304
return HV_STATUS_INVALID_PORT_ID;
13031305

arch/x86/kvm/vmx.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,12 @@ static inline bool cpu_has_vmx_vmfunc(void)
14941494
SECONDARY_EXEC_ENABLE_VMFUNC;
14951495
}
14961496

1497+
static bool vmx_umip_emulated(void)
1498+
{
1499+
return vmcs_config.cpu_based_2nd_exec_ctrl &
1500+
SECONDARY_EXEC_DESC;
1501+
}
1502+
14971503
static inline bool report_flexpriority(void)
14981504
{
14991505
return flexpriority_enabled;
@@ -4761,14 +4767,16 @@ static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
47614767
else
47624768
hw_cr4 |= KVM_PMODE_VM_CR4_ALWAYS_ON;
47634769

4764-
if ((cr4 & X86_CR4_UMIP) && !boot_cpu_has(X86_FEATURE_UMIP)) {
4765-
vmcs_set_bits(SECONDARY_VM_EXEC_CONTROL,
4766-
SECONDARY_EXEC_DESC);
4767-
hw_cr4 &= ~X86_CR4_UMIP;
4768-
} else if (!is_guest_mode(vcpu) ||
4769-
!nested_cpu_has2(get_vmcs12(vcpu), SECONDARY_EXEC_DESC))
4770-
vmcs_clear_bits(SECONDARY_VM_EXEC_CONTROL,
4770+
if (!boot_cpu_has(X86_FEATURE_UMIP) && vmx_umip_emulated()) {
4771+
if (cr4 & X86_CR4_UMIP) {
4772+
vmcs_set_bits(SECONDARY_VM_EXEC_CONTROL,
47714773
SECONDARY_EXEC_DESC);
4774+
hw_cr4 &= ~X86_CR4_UMIP;
4775+
} else if (!is_guest_mode(vcpu) ||
4776+
!nested_cpu_has2(get_vmcs12(vcpu), SECONDARY_EXEC_DESC))
4777+
vmcs_clear_bits(SECONDARY_VM_EXEC_CONTROL,
4778+
SECONDARY_EXEC_DESC);
4779+
}
47724780

47734781
if (cr4 & X86_CR4_VMXE) {
47744782
/*
@@ -9497,12 +9505,6 @@ static bool vmx_xsaves_supported(void)
94979505
SECONDARY_EXEC_XSAVES;
94989506
}
94999507

9500-
static bool vmx_umip_emulated(void)
9501-
{
9502-
return vmcs_config.cpu_based_2nd_exec_ctrl &
9503-
SECONDARY_EXEC_DESC;
9504-
}
9505-
95069508
static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
95079509
{
95089510
u32 exit_intr_info;

arch/x86/kvm/x86.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ module_param(ignore_msrs, bool, S_IRUGO | S_IWUSR);
114114
static bool __read_mostly report_ignored_msrs = true;
115115
module_param(report_ignored_msrs, bool, S_IRUGO | S_IWUSR);
116116

117-
unsigned int min_timer_period_us = 500;
117+
unsigned int min_timer_period_us = 200;
118118
module_param(min_timer_period_us, uint, S_IRUGO | S_IWUSR);
119119

120120
static bool __read_mostly kvmclock_periodic_sync = true;
@@ -843,7 +843,10 @@ EXPORT_SYMBOL_GPL(kvm_set_cr4);
843843
int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
844844
{
845845
#ifdef CONFIG_X86_64
846-
cr3 &= ~CR3_PCID_INVD;
846+
bool pcid_enabled = kvm_read_cr4_bits(vcpu, X86_CR4_PCIDE);
847+
848+
if (pcid_enabled)
849+
cr3 &= ~CR3_PCID_INVD;
847850
#endif
848851

849852
if (cr3 == kvm_read_cr3(vcpu) && !pdptrs_changed(vcpu)) {
@@ -6671,12 +6674,13 @@ void kvm_vcpu_deactivate_apicv(struct kvm_vcpu *vcpu)
66716674
int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
66726675
{
66736676
unsigned long nr, a0, a1, a2, a3, ret;
6674-
int op_64_bit, r;
6675-
6676-
r = kvm_skip_emulated_instruction(vcpu);
6677+
int op_64_bit;
66776678

6678-
if (kvm_hv_hypercall_enabled(vcpu->kvm))
6679-
return kvm_hv_hypercall(vcpu);
6679+
if (kvm_hv_hypercall_enabled(vcpu->kvm)) {
6680+
if (!kvm_hv_hypercall(vcpu))
6681+
return 0;
6682+
goto out;
6683+
}
66806684

66816685
nr = kvm_register_read(vcpu, VCPU_REGS_RAX);
66826686
a0 = kvm_register_read(vcpu, VCPU_REGS_RBX);
@@ -6697,7 +6701,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
66976701

66986702
if (kvm_x86_ops->get_cpl(vcpu) != 0) {
66996703
ret = -KVM_EPERM;
6700-
goto out;
6704+
goto out_error;
67016705
}
67026706

67036707
switch (nr) {
@@ -6717,12 +6721,14 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
67176721
ret = -KVM_ENOSYS;
67186722
break;
67196723
}
6720-
out:
6724+
out_error:
67216725
if (!op_64_bit)
67226726
ret = (u32)ret;
67236727
kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
6728+
6729+
out:
67246730
++vcpu->stat.hypercalls;
6725-
return r;
6731+
return kvm_skip_emulated_instruction(vcpu);
67266732
}
67276733
EXPORT_SYMBOL_GPL(kvm_emulate_hypercall);
67286734

include/linux/kvm_host.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,13 +1045,7 @@ static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq)
10451045

10461046
#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
10471047

1048-
#ifdef CONFIG_S390
1049-
#define KVM_MAX_IRQ_ROUTES 4096 //FIXME: we can have more than that...
1050-
#elif defined(CONFIG_ARM64)
1051-
#define KVM_MAX_IRQ_ROUTES 4096
1052-
#else
1053-
#define KVM_MAX_IRQ_ROUTES 1024
1054-
#endif
1048+
#define KVM_MAX_IRQ_ROUTES 4096 /* might need extension/rework in the future */
10551049

10561050
bool kvm_arch_can_set_irq_routing(struct kvm *kvm);
10571051
int kvm_set_irq_routing(struct kvm *kvm,

tools/testing/selftests/kvm/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ LIBKVM += $(LIBKVM_$(UNAME_M))
1515

1616
INSTALL_HDR_PATH = $(top_srcdir)/usr
1717
LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
18-
CFLAGS += -O2 -g -std=gnu99 -I$(LINUX_HDR_PATH) -Iinclude -I$(<D)
18+
CFLAGS += -O2 -g -std=gnu99 -I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -I..
1919

2020
# After inclusion, $(OUTPUT) is defined and
2121
# $(TEST_GEN_PROGS) starts with $(OUTPUT)/

0 commit comments

Comments
 (0)