Unverified Commit 607f7176 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!8067 irqchip: gic: some bugfix of hip09

Merge Pull Request from: @did-you-collect-the-wool-today 
 
Patch1:fix one soc bug with vPE schedule for gicv4.0
Patch2:fix another soc bug with inaccurate pending status for gicv4.1
Patch3:Fix the bug that a large-specification VM fails to be created. 
 
Link:https://gitee.com/openeuler/kernel/pulls/8067

 

Reviewed-by: default avatarZhang Jianhua <chris.zjh@huawei.com>
Reviewed-by: default avatarZenghui Yu <yuzenghui@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents e829bca6 989fec19
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -522,6 +522,7 @@ int kvm_vgic_hyp_init(void)
		return -ENXIO;
		return -ENXIO;
	}
	}


	kvm_vgic_global_state.flags = gic_kvm_info->flags;
	switch (gic_kvm_info->type) {
	switch (gic_kvm_info->type) {
	case GIC_V2:
	case GIC_V2:
		ret = vgic_v2_probe(gic_kvm_info);
		ret = vgic_v2_probe(gic_kvm_info);
+25 −4
Original line number Original line 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)) {
		if (vgic_has_its(vcpu->kvm)) {
			value |= (INTERRUPT_ID_BITS_ITS - 1) << 19;
			value |= (INTERRUPT_ID_BITS_ITS - 1) << 19;
			value |= GICD_TYPER_LPIS;
			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 {
		} else {
			value |= (INTERRUPT_ID_BITS_SPIS - 1) << 19;
			value |= (INTERRUPT_ID_BITS_SPIS - 1) << 19;
		}
		}
@@ -308,6 +313,7 @@ static unsigned long vgic_mmio_read_v3_idregs(struct kvm_vcpu *vcpu,
	return 0;
	return 0;
}
}


#define VIRTUAL_SGI_PENDING_OFFSET      0x3F0
static unsigned long vgic_v3_uaccess_read_pending(struct kvm_vcpu *vcpu,
static unsigned long vgic_v3_uaccess_read_pending(struct kvm_vcpu *vcpu,
						  gpa_t addr, unsigned int len)
						  gpa_t addr, unsigned int len)
{
{
@@ -327,13 +333,28 @@ static unsigned long vgic_v3_uaccess_read_pending(struct kvm_vcpu *vcpu,
		bool state = irq->pending_latch;
		bool state = irq->pending_latch;


		if (vgic_direct_sgi_or_ppi(irq)) {
		if (vgic_direct_sgi_or_ppi(irq)) {
			if (vgic_irq_is_sgi(irq->intid) &&
			    (kvm_vgic_global_state.flags &
			     FLAGS_WORKAROUND_HIP09_ERRATUM_162200806))  {
				struct its_vpe *vpe;
				void *va;
				u8 *ptr;
				int mask;

				vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
				mask = BIT(irq->intid % BITS_PER_BYTE);
				va = page_address(vpe->vpt_page);
				ptr = va + VIRTUAL_SGI_PENDING_OFFSET +
				      irq->intid / BITS_PER_BYTE;
				state = *ptr & mask;
			} else {
				int err;
				int err;

				err = irq_get_irqchip_state(irq->host_irq,
				err = irq_get_irqchip_state(irq->host_irq,
						    IRQCHIP_STATE_PENDING,
						    IRQCHIP_STATE_PENDING,
						    &state);
						    &state);
				WARN_ON(err);
				WARN_ON(err);
			}
			}
		}


		if (state)
		if (state)
			value |= (1U << i);
			value |= (1U << i);
+3 −0
Original line number Original line Diff line number Diff line
@@ -5,6 +5,9 @@
#ifndef __KVM_ARM_VGIC_MMIO_H__
#ifndef __KVM_ARM_VGIC_MMIO_H__
#define __KVM_ARM_VGIC_MMIO_H__
#define __KVM_ARM_VGIC_MMIO_H__


#define FLAGS_WORKAROUND_HIP09_ERRATUM_162200803    (1ULL << 4)
#define FLAGS_WORKAROUND_HIP09_ERRATUM_162200806    (1ULL << 5)

struct vgic_register_region {
struct vgic_register_region {
	unsigned int reg_offset;
	unsigned int reg_offset;
	unsigned int len;
	unsigned int len;
+6 −2
Original line number Original line Diff line number Diff line
@@ -3208,6 +3208,7 @@ static int allocate_vpe_l1_table(void)
	unsigned int psz = SZ_64K;
	unsigned int psz = SZ_64K;
	unsigned int np, epp, esz;
	unsigned int np, epp, esz;
	struct page *page;
	struct page *page;
	bool indirect;


	if (!gic_rdists->has_rvpeid)
	if (!gic_rdists->has_rvpeid)
		return 0;
		return 0;
@@ -3242,10 +3243,12 @@ static int allocate_vpe_l1_table(void)


	/* First probe the page size */
	/* First probe the page size */
	val = FIELD_PREP(GICR_VPROPBASER_4_1_PAGE_SIZE, GIC_PAGE_SIZE_64K);
	val = FIELD_PREP(GICR_VPROPBASER_4_1_PAGE_SIZE, GIC_PAGE_SIZE_64K);
	val |= GICR_VPROPBASER_4_1_INDIRECT;
	gicr_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
	gicr_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
	val = gicr_read_vpropbaser(vlpi_base + GICR_VPROPBASER);
	val = gicr_read_vpropbaser(vlpi_base + GICR_VPROPBASER);
	gpsz = FIELD_GET(GICR_VPROPBASER_4_1_PAGE_SIZE, val);
	gpsz = FIELD_GET(GICR_VPROPBASER_4_1_PAGE_SIZE, val);
	esz = FIELD_GET(GICR_VPROPBASER_4_1_ENTRY_SIZE, val);
	esz = FIELD_GET(GICR_VPROPBASER_4_1_ENTRY_SIZE, val);
	indirect = !!(val & GICR_VPROPBASER_4_1_INDIRECT);


	switch (gpsz) {
	switch (gpsz) {
	default:
	default:
@@ -3278,7 +3281,7 @@ static int allocate_vpe_l1_table(void)
	 * If we need more than just a single L1 page, flag the table
	 * If we need more than just a single L1 page, flag the table
	 * as indirect and compute the number of required L1 pages.
	 * as indirect and compute the number of required L1 pages.
	 */
	 */
	if (epp < ITS_MAX_VPEID) {
	if (epp < ITS_MAX_VPEID && indirect) {
		int nl2;
		int nl2;


		val |= GICR_VPROPBASER_4_1_INDIRECT;
		val |= GICR_VPROPBASER_4_1_INDIRECT;
@@ -3289,7 +3292,8 @@ static int allocate_vpe_l1_table(void)
		/* Number of L1 pages to point to the L2 pages */
		/* Number of L1 pages to point to the L2 pages */
		npg = DIV_ROUND_UP(nl2 * SZ_8, psz);
		npg = DIV_ROUND_UP(nl2 * SZ_8, psz);
	} else {
	} else {
		npg = 1;
		npg = DIV_ROUND_UP(ITS_MAX_VPEID, epp);
		npg = clamp_val(npg, 1, (GICR_VPROPBASER_4_1_SIZE + 1));
	}
	}


	val |= FIELD_PREP(GICR_VPROPBASER_4_1_SIZE, npg - 1);
	val |= FIELD_PREP(GICR_VPROPBASER_4_1_SIZE, npg - 1);
+36 −0
Original line number Original line Diff line number Diff line
@@ -36,6 +36,8 @@
#define FLAGS_WORKAROUND_GICR_WAKER_MSM8996	(1ULL << 0)
#define FLAGS_WORKAROUND_GICR_WAKER_MSM8996	(1ULL << 0)
#define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539	(1ULL << 1)
#define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539	(1ULL << 1)
#define FLAGS_WORKAROUND_MTK_GICR_SAVE		(1ULL << 2)
#define FLAGS_WORKAROUND_MTK_GICR_SAVE		(1ULL << 2)
#define FLAGS_WORKAROUND_HIP09_ERRATUM_162200803	(1ULL << 4)
#define FLAGS_WORKAROUND_HIP09_ERRATUM_162200806	(1ULL << 5)


#define GIC_IRQ_TYPE_PARTITION	(GIC_IRQ_TYPE_LPI + 1)
#define GIC_IRQ_TYPE_PARTITION	(GIC_IRQ_TYPE_LPI + 1)


@@ -1700,6 +1702,24 @@ static bool gic_enable_quirk_hip06_07(void *data)
	return false;
	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 bool __maybe_unused gic_enable_quirk_hip09_162200806(void *data)
{
	struct gic_chip_data *d = data;

	d->flags |= FLAGS_WORKAROUND_HIP09_ERRATUM_162200806;

	return true;
}

static const struct gic_quirk gic_quirks[] = {
static const struct gic_quirk gic_quirks[] = {
	{
	{
		.desc	= "GICv3: Qualcomm MSM8996 broken firmware",
		.desc	= "GICv3: Qualcomm MSM8996 broken firmware",
@@ -1736,6 +1756,18 @@ static const struct gic_quirk gic_quirks[] = {
		.mask	= 0xe8f00fff,
		.mask	= 0xe8f00fff,
		.init	= gic_enable_quirk_cavium_38539,
		.init	= gic_enable_quirk_cavium_38539,
	},
	},
	{
		.desc	= "GICv3: HIP09 erratum 162200803",
		.iidr	= 0x01050736,
		.mask	= 0xffffffff,
		.init	= gic_enable_quirk_hip09_162200803,
	},
	{
		.desc	= "GICv3: HIP09 erratum 162200806",
		.iidr	= 0x01050736,
		.mask	= 0xffffffff,
		.init	= gic_enable_quirk_hip09_162200806,
	},
	{
	{
	}
	}
};
};
@@ -2036,6 +2068,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 = gic_data.rdists.has_vlpis;
	gic_v3_kvm_info.has_v4_1 = gic_data.rdists.has_rvpeid;
	gic_v3_kvm_info.has_v4_1 = gic_data.rdists.has_rvpeid;
	gic_v3_kvm_info.has_vtimer = gic_data.rdists.has_vtimer;
	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);
	gic_set_kvm_info(&gic_v3_kvm_info);
}
}


@@ -2353,6 +2387,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 = gic_data.rdists.has_vlpis;
	gic_v3_kvm_info.has_v4_1 = gic_data.rdists.has_rvpeid;
	gic_v3_kvm_info.has_v4_1 = gic_data.rdists.has_rvpeid;
	gic_v3_kvm_info.has_vtimer = gic_data.rdists.has_vtimer;
	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);
	gic_set_kvm_info(&gic_v3_kvm_info);
}
}


Loading