Commit 1c880ea3 authored by Marc Zyngier's avatar Marc Zyngier
Browse files

Merge branch kvm-arm64/gicv3-tdir-fixes into kvmarm-master/next



* kvm-arm64/gicv3-tdir-fixes:
  : .
  : Address two trapping-related issues when running legacy (i.e. GICv3)
  : guests on GICv5 hosts, courtesy of Sascha Bischoff.
  : .
  KVM: arm64: Correct test for ICH_HCR_EL2_TDIR cap for GICv5 hosts
  KVM: arm64: gic: Enable GICv3 CPUIF trapping on GICv5 hosts if required

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parents 26e013b3 28e505d8
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -2335,16 +2335,16 @@ static bool can_trap_icv_dir_el1(const struct arm64_cpu_capabilities *entry,

	BUILD_BUG_ON(ARM64_HAS_ICH_HCR_EL2_TDIR <= ARM64_HAS_GICV3_CPUIF);
	BUILD_BUG_ON(ARM64_HAS_ICH_HCR_EL2_TDIR <= ARM64_HAS_GICV5_LEGACY);
	if (!this_cpu_has_cap(ARM64_HAS_GICV3_CPUIF) &&
	    !is_midr_in_range_list(has_vgic_v3))
		return false;

	if (!is_hyp_mode_available())
		return false;

	if (this_cpu_has_cap(ARM64_HAS_GICV5_LEGACY))
		return true;

	if (!this_cpu_has_cap(ARM64_HAS_GICV3_CPUIF) &&
	    !is_midr_in_range_list(has_vgic_v3))
		return false;

	if (is_kernel_in_hyp_mode())
		res.a1 = read_sysreg_s(SYS_ICH_VTR_EL2);
	else
+15 −10
Original line number Diff line number Diff line
@@ -880,6 +880,20 @@ void noinstr kvm_compute_ich_hcr_trap_bits(struct alt_instr *alt,
	*updptr = cpu_to_le32(insn);
}

void vgic_v3_enable_cpuif_traps(void)
{
	u64 traps = vgic_ich_hcr_trap_bits();

	if (traps) {
		kvm_info("GICv3 sysreg trapping enabled ([%s%s%s%s], reduced performance)\n",
			 (traps & ICH_HCR_EL2_TALL0) ? "G0" : "",
			 (traps & ICH_HCR_EL2_TALL1) ? "G1" : "",
			 (traps & ICH_HCR_EL2_TC)    ? "C"  : "",
			 (traps & ICH_HCR_EL2_TDIR)  ? "D"  : "");
		static_branch_enable(&vgic_v3_cpuif_trap);
	}
}

/**
 * vgic_v3_probe - probe for a VGICv3 compatible interrupt controller
 * @info:	pointer to the GIC description
@@ -891,7 +905,6 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
{
	u64 ich_vtr_el2 = kvm_call_hyp_ret(__vgic_v3_get_gic_config);
	bool has_v2;
	u64 traps;
	int ret;

	has_v2 = ich_vtr_el2 >> 63;
@@ -955,15 +968,7 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
		kvm_vgic_global_state.ich_vtr_el2 &= ~ICH_VTR_EL2_SEIS;
	}

	traps = vgic_ich_hcr_trap_bits();
	if (traps) {
		kvm_info("GICv3 sysreg trapping enabled ([%s%s%s%s], reduced performance)\n",
			 (traps & ICH_HCR_EL2_TALL0) ? "G0" : "",
			 (traps & ICH_HCR_EL2_TALL1) ? "G1" : "",
			 (traps & ICH_HCR_EL2_TC)    ? "C"  : "",
			 (traps & ICH_HCR_EL2_TDIR)  ? "D"  : "");
		static_branch_enable(&vgic_v3_cpuif_trap);
	}
	vgic_v3_enable_cpuif_traps();

	kvm_vgic_global_state.vctrl_base = NULL;
	kvm_vgic_global_state.type = VGIC_V3;
+2 −0
Original line number Diff line number Diff line
@@ -48,5 +48,7 @@ int vgic_v5_probe(const struct gic_kvm_info *info)
	static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
	kvm_info("GCIE legacy system register CPU interface\n");

	vgic_v3_enable_cpuif_traps();

	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -324,6 +324,7 @@ void vgic_v3_configure_hcr(struct kvm_vcpu *vcpu, struct ap_list_summary *als);
void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
void vgic_v3_reset(struct kvm_vcpu *vcpu);
void vgic_v3_enable_cpuif_traps(void);
int vgic_v3_probe(const struct gic_kvm_info *info);
int vgic_v3_map_resources(struct kvm *kvm);
int vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq);