Skip to content

Commit 0ddc84d

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini: "ARM64: - Address a rather annoying bug w.r.t. guest timer offsetting. The synchronization of timer offsets between vCPUs was broken, leading to inconsistent timer reads within the VM. x86: - New tests for the slow path of the EVTCHNOP_send Xen hypercall - Add missing nVMX consistency checks for CR0 and CR4 - Fix bug that broke AMD GATag on 512 vCPU machines Selftests: - Skip hugetlb tests if huge pages are not available - Sync KVM exit reasons" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: selftests: Sync KVM exit reasons in selftests KVM: selftests: Add macro to generate KVM exit reason strings KVM: selftests: Print expected and actual exit reason in KVM exit reason assert KVM: selftests: Make vCPU exit reason test assertion common KVM: selftests: Add EVTCHNOP_send slow path test to xen_shinfo_test KVM: selftests: Use enum for test numbers in xen_shinfo_test KVM: selftests: Add helpers to make Xen-style VMCALL/VMMCALL hypercalls KVM: selftests: Move the guts of kvm_hypercall() to a separate macro KVM: SVM: WARN if GATag generation drops VM or vCPU ID information KVM: SVM: Modify AVIC GATag to support max number of 512 vCPUs KVM: SVM: Fix a benign off-by-one bug in AVIC physical table mask selftests: KVM: skip hugetlb tests if huge pages are not available KVM: VMX: Use tabs instead of spaces for indentation KVM: VMX: Fix indentation coding style issue KVM: nVMX: remove unnecessary #ifdef KVM: nVMX: add missing consistency checks for CR0 and CR4 KVM: arm64: timers: Convert per-vcpu virtual offset to a global value
2 parents 9c1bec9 + f3e7074 commit 0ddc84d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+354
-511
lines changed

arch/arm64/include/asm/kvm_host.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ struct kvm_arch {
193193
/* Interrupt controller */
194194
struct vgic_dist vgic;
195195

196+
/* Timers */
197+
struct arch_timer_vm_data timer_data;
198+
196199
/* Mandated version of PSCI */
197200
u32 psci_version;
198201

arch/arm64/kvm/arch_timer.c

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,10 @@ u64 timer_get_cval(struct arch_timer_context *ctxt)
8484

8585
static u64 timer_get_offset(struct arch_timer_context *ctxt)
8686
{
87-
struct kvm_vcpu *vcpu = ctxt->vcpu;
87+
if (ctxt->offset.vm_offset)
88+
return *ctxt->offset.vm_offset;
8889

89-
switch(arch_timer_ctx_index(ctxt)) {
90-
case TIMER_VTIMER:
91-
return __vcpu_sys_reg(vcpu, CNTVOFF_EL2);
92-
default:
93-
return 0;
94-
}
90+
return 0;
9591
}
9692

9793
static void timer_set_ctl(struct arch_timer_context *ctxt, u32 ctl)
@@ -128,15 +124,12 @@ static void timer_set_cval(struct arch_timer_context *ctxt, u64 cval)
128124

129125
static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
130126
{
131-
struct kvm_vcpu *vcpu = ctxt->vcpu;
132-
133-
switch(arch_timer_ctx_index(ctxt)) {
134-
case TIMER_VTIMER:
135-
__vcpu_sys_reg(vcpu, CNTVOFF_EL2) = offset;
136-
break;
137-
default:
127+
if (!ctxt->offset.vm_offset) {
138128
WARN(offset, "timer %ld\n", arch_timer_ctx_index(ctxt));
129+
return;
139130
}
131+
132+
WRITE_ONCE(*ctxt->offset.vm_offset, offset);
140133
}
141134

142135
u64 kvm_phys_timer_read(void)
@@ -765,36 +758,18 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
765758
return 0;
766759
}
767760

768-
/* Make the updates of cntvoff for all vtimer contexts atomic */
769-
static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
770-
{
771-
unsigned long i;
772-
struct kvm *kvm = vcpu->kvm;
773-
struct kvm_vcpu *tmp;
774-
775-
mutex_lock(&kvm->lock);
776-
kvm_for_each_vcpu(i, tmp, kvm)
777-
timer_set_offset(vcpu_vtimer(tmp), cntvoff);
778-
779-
/*
780-
* When called from the vcpu create path, the CPU being created is not
781-
* included in the loop above, so we just set it here as well.
782-
*/
783-
timer_set_offset(vcpu_vtimer(vcpu), cntvoff);
784-
mutex_unlock(&kvm->lock);
785-
}
786-
787761
void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
788762
{
789763
struct arch_timer_cpu *timer = vcpu_timer(vcpu);
790764
struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
791765
struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
792766

793767
vtimer->vcpu = vcpu;
768+
vtimer->offset.vm_offset = &vcpu->kvm->arch.timer_data.voffset;
794769
ptimer->vcpu = vcpu;
795770

796771
/* Synchronize cntvoff across all vtimers of a VM. */
797-
update_vtimer_cntvoff(vcpu, kvm_phys_timer_read());
772+
timer_set_offset(vtimer, kvm_phys_timer_read());
798773
timer_set_offset(ptimer, 0);
799774

800775
hrtimer_init(&timer->bg_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
@@ -840,7 +815,7 @@ int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value)
840815
break;
841816
case KVM_REG_ARM_TIMER_CNT:
842817
timer = vcpu_vtimer(vcpu);
843-
update_vtimer_cntvoff(vcpu, kvm_phys_timer_read() - value);
818+
timer_set_offset(timer, kvm_phys_timer_read() - value);
844819
break;
845820
case KVM_REG_ARM_TIMER_CVAL:
846821
timer = vcpu_vtimer(vcpu);

arch/arm64/kvm/hypercalls.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val)
4444
feature = smccc_get_arg1(vcpu);
4545
switch (feature) {
4646
case KVM_PTP_VIRT_COUNTER:
47-
cycles = systime_snapshot.cycles - vcpu_read_sys_reg(vcpu, CNTVOFF_EL2);
47+
cycles = systime_snapshot.cycles - vcpu->kvm->arch.timer_data.voffset;
4848
break;
4949
case KVM_PTP_PHYS_COUNTER:
5050
cycles = systime_snapshot.cycles;

arch/x86/include/asm/svm.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,20 +261,22 @@ enum avic_ipi_failure_cause {
261261
AVIC_IPI_FAILURE_INVALID_BACKING_PAGE,
262262
};
263263

264-
#define AVIC_PHYSICAL_MAX_INDEX_MASK GENMASK_ULL(9, 0)
264+
#define AVIC_PHYSICAL_MAX_INDEX_MASK GENMASK_ULL(8, 0)
265265

266266
/*
267-
* For AVIC, the max index allowed for physical APIC ID
268-
* table is 0xff (255).
267+
* For AVIC, the max index allowed for physical APIC ID table is 0xfe (254), as
268+
* 0xff is a broadcast to all CPUs, i.e. can't be targeted individually.
269269
*/
270270
#define AVIC_MAX_PHYSICAL_ID 0XFEULL
271271

272272
/*
273-
* For x2AVIC, the max index allowed for physical APIC ID
274-
* table is 0x1ff (511).
273+
* For x2AVIC, the max index allowed for physical APIC ID table is 0x1ff (511).
275274
*/
276275
#define X2AVIC_MAX_PHYSICAL_ID 0x1FFUL
277276

277+
static_assert((AVIC_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == AVIC_MAX_PHYSICAL_ID);
278+
static_assert((X2AVIC_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == X2AVIC_MAX_PHYSICAL_ID);
279+
278280
#define AVIC_HPA_MASK ~((0xFFFULL << 52) | 0xFFF)
279281
#define VMCB_AVIC_APIC_BAR_MASK 0xFFFFFFFFFF000ULL
280282

arch/x86/kvm/svm/avic.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,38 @@
2727
#include "irq.h"
2828
#include "svm.h"
2929

30-
/* AVIC GATAG is encoded using VM and VCPU IDs */
31-
#define AVIC_VCPU_ID_BITS 8
32-
#define AVIC_VCPU_ID_MASK ((1 << AVIC_VCPU_ID_BITS) - 1)
30+
/*
31+
* Encode the arbitrary VM ID and the vCPU's default APIC ID, i.e the vCPU ID,
32+
* into the GATag so that KVM can retrieve the correct vCPU from a GALog entry
33+
* if an interrupt can't be delivered, e.g. because the vCPU isn't running.
34+
*
35+
* For the vCPU ID, use however many bits are currently allowed for the max
36+
* guest physical APIC ID (limited by the size of the physical ID table), and
37+
* use whatever bits remain to assign arbitrary AVIC IDs to VMs. Note, the
38+
* size of the GATag is defined by hardware (32 bits), but is an opaque value
39+
* as far as hardware is concerned.
40+
*/
41+
#define AVIC_VCPU_ID_MASK AVIC_PHYSICAL_MAX_INDEX_MASK
3342

34-
#define AVIC_VM_ID_BITS 24
35-
#define AVIC_VM_ID_NR (1 << AVIC_VM_ID_BITS)
36-
#define AVIC_VM_ID_MASK ((1 << AVIC_VM_ID_BITS) - 1)
43+
#define AVIC_VM_ID_SHIFT HWEIGHT32(AVIC_PHYSICAL_MAX_INDEX_MASK)
44+
#define AVIC_VM_ID_MASK (GENMASK(31, AVIC_VM_ID_SHIFT) >> AVIC_VM_ID_SHIFT)
3745

38-
#define AVIC_GATAG(x, y) (((x & AVIC_VM_ID_MASK) << AVIC_VCPU_ID_BITS) | \
39-
(y & AVIC_VCPU_ID_MASK))
40-
#define AVIC_GATAG_TO_VMID(x) ((x >> AVIC_VCPU_ID_BITS) & AVIC_VM_ID_MASK)
46+
#define AVIC_GATAG_TO_VMID(x) ((x >> AVIC_VM_ID_SHIFT) & AVIC_VM_ID_MASK)
4147
#define AVIC_GATAG_TO_VCPUID(x) (x & AVIC_VCPU_ID_MASK)
4248

49+
#define __AVIC_GATAG(vm_id, vcpu_id) ((((vm_id) & AVIC_VM_ID_MASK) << AVIC_VM_ID_SHIFT) | \
50+
((vcpu_id) & AVIC_VCPU_ID_MASK))
51+
#define AVIC_GATAG(vm_id, vcpu_id) \
52+
({ \
53+
u32 ga_tag = __AVIC_GATAG(vm_id, vcpu_id); \
54+
\
55+
WARN_ON_ONCE(AVIC_GATAG_TO_VCPUID(ga_tag) != (vcpu_id)); \
56+
WARN_ON_ONCE(AVIC_GATAG_TO_VMID(ga_tag) != (vm_id)); \
57+
ga_tag; \
58+
})
59+
60+
static_assert(__AVIC_GATAG(AVIC_VM_ID_MASK, AVIC_VCPU_ID_MASK) == -1u);
61+
4362
static bool force_avic;
4463
module_param_unsafe(force_avic, bool, 0444);
4564

arch/x86/kvm/vmx/nested.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2903,7 +2903,7 @@ static int nested_vmx_check_address_space_size(struct kvm_vcpu *vcpu,
29032903
static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu,
29042904
struct vmcs12 *vmcs12)
29052905
{
2906-
bool ia32e;
2906+
bool ia32e = !!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE);
29072907

29082908
if (CC(!nested_host_cr0_valid(vcpu, vmcs12->host_cr0)) ||
29092909
CC(!nested_host_cr4_valid(vcpu, vmcs12->host_cr4)) ||
@@ -2923,12 +2923,6 @@ static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu,
29232923
vmcs12->host_ia32_perf_global_ctrl)))
29242924
return -EINVAL;
29252925

2926-
#ifdef CONFIG_X86_64
2927-
ia32e = !!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE);
2928-
#else
2929-
ia32e = false;
2930-
#endif
2931-
29322926
if (ia32e) {
29332927
if (CC(!(vmcs12->host_cr4 & X86_CR4_PAE)))
29342928
return -EINVAL;
@@ -3022,7 +3016,7 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,
30223016
struct vmcs12 *vmcs12,
30233017
enum vm_entry_failure_code *entry_failure_code)
30243018
{
3025-
bool ia32e;
3019+
bool ia32e = !!(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE);
30263020

30273021
*entry_failure_code = ENTRY_FAIL_DEFAULT;
30283022

@@ -3048,6 +3042,13 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,
30483042
vmcs12->guest_ia32_perf_global_ctrl)))
30493043
return -EINVAL;
30503044

3045+
if (CC((vmcs12->guest_cr0 & (X86_CR0_PG | X86_CR0_PE)) == X86_CR0_PG))
3046+
return -EINVAL;
3047+
3048+
if (CC(ia32e && !(vmcs12->guest_cr4 & X86_CR4_PAE)) ||
3049+
CC(ia32e && !(vmcs12->guest_cr0 & X86_CR0_PG)))
3050+
return -EINVAL;
3051+
30513052
/*
30523053
* If the load IA32_EFER VM-entry control is 1, the following checks
30533054
* are performed on the field for the IA32_EFER MSR:
@@ -3059,7 +3060,6 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,
30593060
*/
30603061
if (to_vmx(vcpu)->nested.nested_run_pending &&
30613062
(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_EFER)) {
3062-
ia32e = (vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) != 0;
30633063
if (CC(!kvm_valid_efer(vcpu, vmcs12->guest_ia32_efer)) ||
30643064
CC(ia32e != !!(vmcs12->guest_ia32_efer & EFER_LMA)) ||
30653065
CC(((vmcs12->guest_cr0 & X86_CR0_PG) &&

arch/x86/kvm/vmx/vmenter.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ SYM_INNER_LABEL(vmx_vmexit, SYM_L_GLOBAL)
262262
* eIBRS has its own protection against poisoned RSB, so it doesn't
263263
* need the RSB filling sequence. But it does need to be enabled, and a
264264
* single call to retire, before the first unbalanced RET.
265-
*/
265+
*/
266266

267267
FILL_RETURN_BUFFER %_ASM_CX, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_VMEXIT,\
268268
X86_FEATURE_RSB_VMEXIT_LITE
@@ -311,7 +311,7 @@ SYM_FUNC_END(vmx_do_nmi_irqoff)
311311
* vmread_error_trampoline - Trampoline from inline asm to vmread_error()
312312
* @field: VMCS field encoding that failed
313313
* @fault: %true if the VMREAD faulted, %false if it failed
314-
314+
*
315315
* Save and restore volatile registers across a call to vmread_error(). Note,
316316
* all parameters are passed on the stack.
317317
*/

arch/x86/kvm/vmx/vmx.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,7 @@ void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu)
874874
*/
875875
if (is_guest_mode(vcpu))
876876
eb |= get_vmcs12(vcpu)->exception_bitmap;
877-
else {
877+
else {
878878
int mask = 0, match = 0;
879879

880880
if (enable_ept && (eb & (1u << PF_VECTOR))) {
@@ -1282,7 +1282,7 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
12821282
}
12831283
}
12841284

1285-
if (vmx->nested.need_vmcs12_to_shadow_sync)
1285+
if (vmx->nested.need_vmcs12_to_shadow_sync)
12861286
nested_sync_vmcs12_to_shadow(vcpu);
12871287

12881288
if (vmx->guest_state_loaded)
@@ -5049,10 +5049,10 @@ static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu, bool for_injection)
50495049
if (to_vmx(vcpu)->nested.nested_run_pending)
50505050
return -EBUSY;
50515051

5052-
/*
5053-
* An IRQ must not be injected into L2 if it's supposed to VM-Exit,
5054-
* e.g. if the IRQ arrived asynchronously after checking nested events.
5055-
*/
5052+
/*
5053+
* An IRQ must not be injected into L2 if it's supposed to VM-Exit,
5054+
* e.g. if the IRQ arrived asynchronously after checking nested events.
5055+
*/
50565056
if (for_injection && is_guest_mode(vcpu) && nested_exit_on_intr(vcpu))
50575057
return -EBUSY;
50585058

include/kvm/arm_arch_timer.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@ enum kvm_arch_timer_regs {
2323
TIMER_REG_CTL,
2424
};
2525

26+
struct arch_timer_offset {
27+
/*
28+
* If set, pointer to one of the offsets in the kvm's offset
29+
* structure. If NULL, assume a zero offset.
30+
*/
31+
u64 *vm_offset;
32+
};
33+
34+
struct arch_timer_vm_data {
35+
/* Offset applied to the virtual timer/counter */
36+
u64 voffset;
37+
};
38+
2639
struct arch_timer_context {
2740
struct kvm_vcpu *vcpu;
2841

@@ -32,6 +45,8 @@ struct arch_timer_context {
3245
/* Emulated Timer (may be unused) */
3346
struct hrtimer hrtimer;
3447

48+
/* Offset for this counter/timer */
49+
struct arch_timer_offset offset;
3550
/*
3651
* We have multiple paths which can save/restore the timer state onto
3752
* the hardware, so we need some way of keeping track of where the

tools/testing/selftests/kvm/aarch64/psci_test.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,7 @@ static void host_test_system_suspend(void)
180180

181181
enter_guest(source);
182182

183-
TEST_ASSERT(run->exit_reason == KVM_EXIT_SYSTEM_EVENT,
184-
"Unhandled exit reason: %u (%s)",
185-
run->exit_reason, exit_reason_str(run->exit_reason));
183+
TEST_ASSERT_KVM_EXIT_REASON(source, KVM_EXIT_SYSTEM_EVENT);
186184
TEST_ASSERT(run->system_event.type == KVM_SYSTEM_EVENT_SUSPEND,
187185
"Unhandled system event: %u (expected: %u)",
188186
run->system_event.type, KVM_SYSTEM_EVENT_SUSPEND);

0 commit comments

Comments
 (0)