Commit e5c5bbf9 authored by Marc Zyngier's avatar Marc Zyngier Committed by chenxiang
Browse files

KVM: arm64: Allow GICv3.3 NMI if the host supports it

virt inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I97WGU

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?h=arm64/nmi&id=aa2c072f6ac4dba0e6385731ccc477b1febf1262



-----------------------------------------------------------

Let the GICv3 driver populate a has_nmi flag in the kvm_gic_info
structure, and communicate it to the rest of KVM.

We disallow the use of NMI if trapping of the CPU interface is
enabled, because life is definitely too short to write more
emulation.

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Signed-off-by: default avatarXiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: default avatarcaijian <caijian11@h-partners.com>
parent 8b487c60
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -192,7 +192,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
	/* The maximum number of VCPUs is limited by the host's GIC model */
	kvm->max_vcpus = kvm_arm_default_max_vcpus();

	if (system_uses_nmi())
	if (system_uses_nmi() && !static_branch_unlikely(&vgic_v3_cpuif_trap))
		kvm->arch.pfr1_nmi = ID_AA64PFR1_EL1_NMI_IMP;

	kvm_arm_init_hypercalls(kvm);
+2 −1
Original line number Diff line number Diff line
@@ -1580,7 +1580,8 @@ static int set_id_aa64pfr1_el1(struct kvm_vcpu *vcpu,
	u8 nmi;

	nmi = cpuid_feature_extract_unsigned_field(val, ID_AA64PFR1_EL1_NMI_SHIFT);
	if (nmi > ID_AA64PFR1_EL1_NMI_IMP || (nmi && !system_uses_nmi()))
	if (nmi > ID_AA64PFR1_EL1_NMI_IMP ||
	    (nmi && (!system_uses_nmi() || static_branch_unlikely(&vgic_v3_cpuif_trap))))
		return -EINVAL;

	/* We can only differ with NMI, and anything else is an error */
+6 −0
Original line number Diff line number Diff line
@@ -724,6 +724,12 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
		static_branch_enable(&vgic_v3_cpuif_trap);
	}

	if (info->has_nmi) {
		kvm_vgic_global_state.has_nmi = !static_branch_unlikely(&vgic_v3_cpuif_trap);
		kvm_info("GICv3 NMI support %s\n",
			 kvm_vgic_global_state.has_nmi ? "enabled" : "disabled due to trapping");
	}

	kvm_vgic_global_state.vctrl_base = NULL;
	kvm_vgic_global_state.type = VGIC_V3;
	kvm_vgic_global_state.max_gic_vcpus = VGIC_V3_MAX_CPUS;
+1 −0
Original line number Diff line number Diff line
@@ -2681,6 +2681,7 @@ static void __init gic_acpi_setup_kvm_info(void)

	gic_v3_kvm_info.has_v4 = gic_data.rdists.has_vlpis;
	gic_v3_kvm_info.has_v4_1 = gic_data.rdists.has_rvpeid;
	gic_v3_kvm_info.has_nmi = has_v3_3_nmi();
#ifdef CONFIG_VIRT_VTIMER_IRQ_BYPASS
	gic_v3_kvm_info.has_vtimer = gic_data.rdists.has_vtimer;
#endif
+2 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ struct gic_kvm_info {
	bool		has_v4;
	/* rvpeid support */
	bool		has_v4_1;
	/* NMI support */
	bool            has_nmi;
#ifdef CONFIG_VIRT_VTIMER_IRQ_BYPASS
	/* vtimer irqbypass support */
	bool            has_vtimer;