Commit d77f4792 authored by Marc Zyngier's avatar Marc Zyngier
Browse files

Merge branch kvm-arm64/vgic-fixes-7.1 into kvmarm-master/next



* kvm-arm64/vgic-fixes-7.1:
  : .
  : FIrst pass at fixing a number of vgic-v5 bugs that were found
  : after the merge of the initial series.
  : .
  KVM: arm64: Advertise ID_AA64PFR2_EL1.GCIE
  KVM: arm64: vgic-v5: Fold PPI state for all exposed PPIs
  KVM: arm64: set_id_regs: Allow GICv3 support to be set at runtime
  KVM: arm64: Don't advertises GICv3 in ID_PFR1_EL1 if AArch32 isn't supported
  KVM: arm64: Correctly plumb ID_AA64PFR2_EL1 into pkvm idreg handling
  KVM: arm64: Move GICv5 timer PPI validation into timer_irqs_are_valid()
  KVM: arm64: Remove evaluation of timer state in kvm_cpu_has_pending_timer()
  KVM: arm64: Kill arch_timer_context::direct field
  KVM: arm64: vgic-v5: Correctly set dist->ready once initialised
  KVM: arm64: vgic-v5: Make the effective priority mask a strict limit
  KVM: arm64: vgic-v5: Cast vgic_apr to u32 to avoid undefined behaviours
  KVM: arm64: vgic-v5: Transfer edge pending state to ICH_PPI_PENDRx_EL2
  KVM: arm64: vgic-v5: Hold config_lock while finalizing GICv5 PPIs
  KVM: arm64: Account for RESx bits in __compute_fgt()
  KVM: arm64: Fix writeable mask for ID_AA64PFR2_EL1
  arm64: Fix field references for ICH_PPI_DVIR[01]_EL2
  KVM: arm64: Don't skip per-vcpu NV initialisation
  KVM: arm64: vgic: Don't reset cpuif/redist addresses at finalize time

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parents 83a39807 7e629348
Loading
Loading
Loading
Loading
+1 −8
Original line number Diff line number Diff line
@@ -821,14 +821,7 @@ struct kvm_host_data {

	/* PPI state tracking for GICv5-based guests */
	struct {
		/*
		 * For tracking the PPI pending state, we need both the entry
		 * state and exit state to correctly detect edges as it is
		 * possible that an interrupt has been injected in software in
		 * the interim.
		 */
		DECLARE_BITMAP(pendr_entry, VGIC_V5_NR_PRIVATE_IRQS);
		DECLARE_BITMAP(pendr_exit, VGIC_V5_NR_PRIVATE_IRQS);
		DECLARE_BITMAP(pendr, VGIC_V5_NR_PRIVATE_IRQS);

		/* The saved state of the regs when leaving the guest */
		DECLARE_BITMAP(activer_exit, VGIC_V5_NR_PRIVATE_IRQS);
+1 −0
Original line number Diff line number Diff line
@@ -325,6 +325,7 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {

static const struct arm64_ftr_bits ftr_id_aa64pfr2[] = {
	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR2_EL1_FPMR_SHIFT, 4, 0),
	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR2_EL1_GCIE_SHIFT, 4, ID_AA64PFR2_EL1_GCIE_NI),
	ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR2_EL1_MTEFAR_SHIFT, 4, ID_AA64PFR2_EL1_MTEFAR_NI),
	ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR2_EL1_MTESTOREONLY_SHIFT, 4, ID_AA64PFR2_EL1_MTESTOREONLY_NI),
	ARM64_FTR_END,
+14 −18
Original line number Diff line number Diff line
@@ -183,10 +183,6 @@ void get_timer_map(struct kvm_vcpu *vcpu, struct timer_map *map)
		map->emul_ptimer = vcpu_ptimer(vcpu);
	}

	map->direct_vtimer->direct = true;
	if (map->direct_ptimer)
		map->direct_ptimer->direct = true;

	trace_kvm_get_timer_map(vcpu->vcpu_id, map);
}

@@ -406,11 +402,7 @@ static bool kvm_timer_should_fire(struct arch_timer_context *timer_ctx)

int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
{
	struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
	struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);

	return kvm_timer_should_fire(vtimer) || kvm_timer_should_fire(ptimer) ||
	       (vcpu_has_wfit_active(vcpu) && wfit_delay_ns(vcpu) == 0);
	return vcpu_has_wfit_active(vcpu) && wfit_delay_ns(vcpu) == 0;
}

/*
@@ -462,8 +454,15 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level,
		return;

	/* Skip injecting on GICv5 for directly injected (DVI'd) timers */
	if (vgic_is_v5(vcpu->kvm) && timer_ctx->direct)
	if (vgic_is_v5(vcpu->kvm)) {
		struct timer_map map;

		get_timer_map(vcpu, &map);

		if (map.direct_ptimer == timer_ctx ||
		    map.direct_vtimer == timer_ctx)
			return;
	}

	kvm_vgic_inject_irq(vcpu->kvm, vcpu,
			    timer_irq(timer_ctx),
@@ -1544,6 +1543,10 @@ static bool timer_irqs_are_valid(struct kvm_vcpu *vcpu)
		if (kvm_vgic_set_owner(vcpu, irq, ctx))
			break;

		/* With GICv5, the default PPI is what you get -- nothing else */
		if (vgic_is_v5(vcpu->kvm) && irq != get_vgic_ppi(vcpu->kvm, default_ppi[i]))
			break;

		/*
		 * We know by construction that we only have PPIs, so all values
		 * are less than 32 for non-GICv5 VGICs. On GICv5, they are
@@ -1679,13 +1682,6 @@ int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
		return -ENXIO;
	}

	/*
	 * The PPIs for the Arch Timers are architecturally defined for
	 * GICv5. Reject anything that changes them from the specified value.
	 */
	if (vgic_is_v5(vcpu->kvm) && vcpu->kvm->arch.timer_data.ppi[idx] != irq)
		return -EINVAL;

	/*
	 * We cannot validate the IRQ unicity before we run, so take it at
	 * face value. The verdict will be given on first vcpu run, for each
+2 −2
Original line number Diff line number Diff line
@@ -1663,8 +1663,8 @@ static __always_inline void __compute_fgt(struct kvm_vcpu *vcpu, enum vcpu_sysre
		clear |= ~nested & m->nmask;
	}

	val |= set;
	val &= ~clear;
	val |= set | m->res1;
	val &= ~(clear | m->res0);
	*vcpu_fgt(vcpu, reg) = val;
}

+1 −1
Original line number Diff line number Diff line
@@ -447,7 +447,7 @@ static const struct sys_reg_desc pvm_sys_reg_descs[] = {
	/* CRm=4 */
	AARCH64(SYS_ID_AA64PFR0_EL1),
	AARCH64(SYS_ID_AA64PFR1_EL1),
	ID_UNALLOCATED(4,2),
	AARCH64(SYS_ID_AA64PFR2_EL1),
	ID_UNALLOCATED(4,3),
	AARCH64(SYS_ID_AA64ZFR0_EL1),
	ID_UNALLOCATED(4,5),
Loading