Commit 8f27ed00 authored by Xiang Chen's avatar Xiang Chen Committed by Dongxu Sun
Browse files

irqchip: gicv3: Add workaround for hip09 erratum 162200803

virt inclusion
category: other
bugzilla: https://gitee.com/openeuler/kernel/issues/I9SGLA



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

For gicv4.0 of hip09, it has a soc bug with vPE schedule:
when multiple vPEs are sending vpe schedule/deschedule commands
concurrently and repeatly, some vPE schedule command may not be
scheduled, and it will cause the command timeout.
To avoid the issue,  limit the number of vLPI to 4096 for virtual machine.

Signed-off-by: default avatarXiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: default avatarcaijian <caijian11@h-partners.com>
parent f300accf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -522,6 +522,7 @@ int kvm_vgic_hyp_init(void)
		return -ENXIO;
	}

	kvm_vgic_global_state.flags = gic_kvm_info->flags;
	switch (gic_kvm_info->type) {
	case GIC_V2:
		ret = vgic_v2_probe(gic_kvm_info);
+5 −0
Original line number Diff line number Diff line
@@ -81,6 +81,11 @@ static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
		if (vgic_has_its(vcpu->kvm)) {
			value |= (INTERRUPT_ID_BITS_ITS - 1) << 19;
			value |= GICD_TYPER_LPIS;
			/* Limit the number of vlpis to 4096 */
			if (kvm_vgic_global_state.flags &
			    FLAGS_WORKAROUND_HIP09_ERRATUM_162200803)
				value |= 11 << GICD_TYPER_NUM_LPIS_SHIFT;

		} else {
			value |= (INTERRUPT_ID_BITS_SPIS - 1) << 19;
		}
+2 −0
Original line number Diff line number Diff line
@@ -5,6 +5,8 @@
#ifndef __KVM_ARM_VGIC_MMIO_H__
#define __KVM_ARM_VGIC_MMIO_H__

#define FLAGS_WORKAROUND_HIP09_ERRATUM_162200803    (1ULL << 4)

struct vgic_register_region {
	unsigned int reg_offset;
	unsigned int len;
+20 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#define FLAGS_WORKAROUND_GICR_WAKER_MSM8996	(1ULL << 0)
#define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539	(1ULL << 1)
#define FLAGS_WORKAROUND_MTK_GICR_SAVE		(1ULL << 2)
#define FLAGS_WORKAROUND_HIP09_ERRATUM_162200803	(1ULL << 4)

#define GIC_IRQ_TYPE_PARTITION	(GIC_IRQ_TYPE_LPI + 1)

@@ -1700,6 +1701,15 @@ static bool gic_enable_quirk_hip06_07(void *data)
	return false;
}

static bool gic_enable_quirk_hip09_162200803(void *data)
{
	struct gic_chip_data *d = data;

	d->flags |= FLAGS_WORKAROUND_HIP09_ERRATUM_162200803;

	return true;
}

static const struct gic_quirk gic_quirks[] = {
	{
		.desc	= "GICv3: Qualcomm MSM8996 broken firmware",
@@ -1736,6 +1746,12 @@ static const struct gic_quirk gic_quirks[] = {
		.mask	= 0xe8f00fff,
		.init	= gic_enable_quirk_cavium_38539,
	},
	{
		.desc	= "GICv3: HIP09 erratum 162200803",
		.iidr	= 0x01050736,
		.mask	= 0xffffffff,
		.init	= gic_enable_quirk_hip09_162200803,
	},
	{
	}
};
@@ -2036,6 +2052,8 @@ static void __init gic_of_setup_kvm_info(struct device_node *node)
	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_vtimer = gic_data.rdists.has_vtimer;
	if (gic_v3_kvm_info.has_v4 && !gic_v3_kvm_info.has_v4_1)
		gic_v3_kvm_info.flags = gic_data.flags;
	gic_set_kvm_info(&gic_v3_kvm_info);
}

@@ -2353,6 +2371,8 @@ 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_vtimer = gic_data.rdists.has_vtimer;
	if (gic_v3_kvm_info.has_v4 && !gic_v3_kvm_info.has_v4_1)
		gic_v3_kvm_info.flags = gic_data.flags;
	gic_set_kvm_info(&gic_v3_kvm_info);
}

+1 −0
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ struct vgic_global {
	struct static_key_false gicv3_cpuif;

	u32			ich_vtr_el2;
	u64			flags;
};

extern struct vgic_global kvm_vgic_global_state;
Loading