Commit 86d6a628 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull kvm fixes from Paolo Bonzini:
 "ARM:

   - Fix the handling of the phycal timer offset when FEAT_ECV and
     CNTPOFF_EL2 are implemented

   - Restore the functionnality of Permission Indirection that was
     broken by the Fine Grained Trapping rework

   - Cleanup some PMU event sharing code

  MIPS:

   - Fix W=1 build

  s390:

   - One small fix for gisa to avoid stalls

  x86:

   - Truncate writes to PMU counters to the counter's width to avoid
     spurious overflows when emulating counter events in software

   - Set the LVTPC entry mask bit when handling a PMI (to match
     Intel-defined architectural behavior)

   - Treat KVM_REQ_PMI as a wake event instead of queueing host IRQ work
     to kick the guest out of emulated halt

   - Fix for loading XSAVE state from an old kernel into a new one

   - Fixes for AMD AVIC

  selftests:

   - Play nice with %llx when formatting guest printf and assert
     statements

   - Clean up stale test metadata

   - Zero-initialize structures in memslot perf test to workaround a
     suspected 'may be used uninitialized' false positives from GCC"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (21 commits)
  KVM: arm64: timers: Correctly handle TGE flip with CNTPOFF_EL2
  KVM: arm64: POR{E0}_EL1 do not need trap handlers
  KVM: arm64: Add nPIR{E0}_EL1 to HFG traps
  KVM: MIPS: fix -Wunused-but-set-variable warning
  KVM: arm64: pmu: Drop redundant check for non-NULL kvm_pmu_events
  KVM: SVM: Fix build error when using -Werror=unused-but-set-variable
  x86: KVM: SVM: refresh AVIC inhibition in svm_leave_nested()
  x86: KVM: SVM: add support for Invalid IPI Vector interception
  x86: KVM: SVM: always update the x2avic msr interception
  KVM: selftests: Force load all supported XSAVE state in state test
  KVM: selftests: Load XSAVE state into untouched vCPU during state test
  KVM: selftests: Touch relevant XSAVE state in guest for state test
  KVM: x86: Constrain guest-supported xfeatures only at KVM_GET_XSAVE{2}
  x86/fpu: Allow caller to constrain xfeatures when copying to uabi buffer
  KVM: selftests: Zero-initialize entire test_result in memslot perf test
  KVM: selftests: Remove obsolete and incorrect test case metadata
  KVM: selftests: Treat %llx like %lx when formatting guest printf
  KVM: x86/pmu: Synthesize at most one PMI per VM-exit
  KVM: x86: Mask LVTPC when handling a PMI
  KVM: x86/pmu: Truncate counter value to allowed width on write
  ...
parents 58720809 2b3f2325
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -344,14 +344,14 @@
 */
#define __HFGRTR_EL2_RES0	(GENMASK(63, 56) | GENMASK(53, 51))
#define __HFGRTR_EL2_MASK	GENMASK(49, 0)
#define __HFGRTR_EL2_nMASK	(GENMASK(55, 54) | BIT(50))
#define __HFGRTR_EL2_nMASK	(GENMASK(58, 57) | GENMASK(55, 54) | BIT(50))

#define __HFGWTR_EL2_RES0	(GENMASK(63, 56) | GENMASK(53, 51) |	\
				 BIT(46) | BIT(42) | BIT(40) | BIT(28) | \
				 GENMASK(26, 25) | BIT(21) | BIT(18) |	\
				 GENMASK(15, 14) | GENMASK(10, 9) | BIT(2))
#define __HFGWTR_EL2_MASK	GENMASK(49, 0)
#define __HFGWTR_EL2_nMASK	(GENMASK(55, 54) | BIT(50))
#define __HFGWTR_EL2_nMASK	(GENMASK(58, 57) | GENMASK(55, 54) | BIT(50))

#define __HFGITR_EL2_RES0	GENMASK(63, 57)
#define __HFGITR_EL2_MASK	GENMASK(54, 0)
+3 −10
Original line number Diff line number Diff line
@@ -55,11 +55,6 @@ static struct irq_ops arch_timer_irq_ops = {
	.get_input_level = kvm_arch_timer_get_input_level,
};

static bool has_cntpoff(void)
{
	return (has_vhe() && cpus_have_final_cap(ARM64_HAS_ECV_CNTPOFF));
}

static int nr_timers(struct kvm_vcpu *vcpu)
{
	if (!vcpu_has_nv(vcpu))
@@ -180,7 +175,7 @@ u64 kvm_phys_timer_read(void)
	return timecounter->cc->read(timecounter->cc);
}

static void get_timer_map(struct kvm_vcpu *vcpu, struct timer_map *map)
void get_timer_map(struct kvm_vcpu *vcpu, struct timer_map *map)
{
	if (vcpu_has_nv(vcpu)) {
		if (is_hyp_ctxt(vcpu)) {
@@ -548,7 +543,6 @@ static void timer_save_state(struct arch_timer_context *ctx)
		timer_set_ctl(ctx, read_sysreg_el0(SYS_CNTP_CTL));
		cval = read_sysreg_el0(SYS_CNTP_CVAL);

		if (!has_cntpoff())
		cval -= timer_get_offset(ctx);

		timer_set_cval(ctx, cval);
@@ -636,7 +630,6 @@ static void timer_restore_state(struct arch_timer_context *ctx)
		cval = timer_get_cval(ctx);
		offset = timer_get_offset(ctx);
		set_cntpoff(offset);
		if (!has_cntpoff())
		cval += offset;
		write_sysreg_el0(cval, SYS_CNTP_CVAL);
		isb();
+2 −0
Original line number Diff line number Diff line
@@ -977,6 +977,8 @@ enum fg_filter_id {

static const struct encoding_to_trap_config encoding_to_fgt[] __initconst = {
	/* HFGRTR_EL2, HFGWTR_EL2 */
	SR_FGT(SYS_PIR_EL1,		HFGxTR, nPIR_EL1, 0),
	SR_FGT(SYS_PIRE0_EL1,		HFGxTR, nPIRE0_EL1, 0),
	SR_FGT(SYS_TPIDR2_EL0,		HFGxTR, nTPIDR2_EL0, 0),
	SR_FGT(SYS_SMPRI_EL1,		HFGxTR, nSMPRI_EL1, 0),
	SR_FGT(SYS_ACCDATA_EL1,		HFGxTR, nACCDATA_EL1, 0),
+44 −0
Original line number Diff line number Diff line
@@ -39,6 +39,26 @@ static void __activate_traps(struct kvm_vcpu *vcpu)

	___activate_traps(vcpu);

	if (has_cntpoff()) {
		struct timer_map map;

		get_timer_map(vcpu, &map);

		/*
		 * We're entrering the guest. Reload the correct
		 * values from memory now that TGE is clear.
		 */
		if (map.direct_ptimer == vcpu_ptimer(vcpu))
			val = __vcpu_sys_reg(vcpu, CNTP_CVAL_EL0);
		if (map.direct_ptimer == vcpu_hptimer(vcpu))
			val = __vcpu_sys_reg(vcpu, CNTHP_CVAL_EL2);

		if (map.direct_ptimer) {
			write_sysreg_el0(val, SYS_CNTP_CVAL);
			isb();
		}
	}

	val = read_sysreg(cpacr_el1);
	val |= CPACR_ELx_TTA;
	val &= ~(CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN |
@@ -77,6 +97,30 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)

	write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2);

	if (has_cntpoff()) {
		struct timer_map map;
		u64 val, offset;

		get_timer_map(vcpu, &map);

		/*
		 * We're exiting the guest. Save the latest CVAL value
		 * to memory and apply the offset now that TGE is set.
		 */
		val = read_sysreg_el0(SYS_CNTP_CVAL);
		if (map.direct_ptimer == vcpu_ptimer(vcpu))
			__vcpu_sys_reg(vcpu, CNTP_CVAL_EL0) = val;
		if (map.direct_ptimer == vcpu_hptimer(vcpu))
			__vcpu_sys_reg(vcpu, CNTHP_CVAL_EL2) = val;

		offset = read_sysreg_s(SYS_CNTPOFF_EL2);

		if (map.direct_ptimer && offset) {
			write_sysreg_el0(val + offset, SYS_CNTP_CVAL);
			isb();
		}
	}

	/*
	 * ARM errata 1165522 and 1530923 require the actual execution of the
	 * above before we can switch to the EL2/EL0 translation regime used by
+2 −2
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr)
{
	struct kvm_pmu_events *pmu = kvm_get_pmu_events();

	if (!kvm_arm_support_pmu_v3() || !pmu || !kvm_pmu_switch_needed(attr))
	if (!kvm_arm_support_pmu_v3() || !kvm_pmu_switch_needed(attr))
		return;

	if (!attr->exclude_host)
@@ -55,7 +55,7 @@ void kvm_clr_pmu_events(u32 clr)
{
	struct kvm_pmu_events *pmu = kvm_get_pmu_events();

	if (!kvm_arm_support_pmu_v3() || !pmu)
	if (!kvm_arm_support_pmu_v3())
		return;

	pmu->events_host &= ~clr;
Loading