From: Kunkun Jiang jiangkunkun@huawei.com
driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I9KBKD
-------------------------------------------------------------
For gicv4.1 of hip09, it has a soc bug with the status of vpe pending is inaccurate, so read the pending status from memory to fix the issue.
Signed-off-by: Kunkun Jiang jiangkunkun@huawei.com Signed-off-by: Xiang Chen chenxiang66@hisilicon.com --- Documentation/arch/arm64/silicon-errata.rst | 2 ++ arch/arm64/Kconfig | 10 ++++++++++ arch/arm64/configs/openeuler_defconfig | 1 + arch/arm64/kvm/vgic/vgic-mmio.c | 17 +++++++++++++++++ arch/arm64/kvm/vgic/vgic-mmio.h | 1 + drivers/irqchip/irq-gic-v3.c | 18 ++++++++++++++++++ 6 files changed, 49 insertions(+)
diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst index 1b1c5b8d90a9..17c636068603 100644 --- a/Documentation/arch/arm64/silicon-errata.rst +++ b/Documentation/arch/arm64/silicon-errata.rst @@ -215,6 +215,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Hisilicon | Hip09 | #162200803 | HISILICON_ERRATUM_162200803 | +----------------+-----------------+-----------------+-----------------------------+ +| Hisilicon | Hip09 | #162200806 | HISILICON_ERRATUM_162200806 | ++----------------+-----------------+-----------------+-----------------------------+ | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | +----------------+-----------------+-----------------+-----------------------------+ | Qualcomm Tech. | Kryo/Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 | diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 3bfee070e863..d09dc7a9818f 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1247,6 +1247,16 @@ config HISILICON_ERRATUM_162200803
If unsure, say Y.
+config HISILICON_ERRATUM_162200806 + bool "Hisilicon erratum 162200806" + default y + help + For gicv4.1 of hip09, it has a soc bug with the status of + vpe pending is inaccurate, so read the pending status from + memory to fix the issue. + + If unsure, say Y. + config QCOM_FALKOR_ERRATUM_1003 bool "Falkor E1003: Incorrect translation due to ASID change" default y diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index b38681daeabc..8a78dda28ce8 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -435,6 +435,7 @@ CONFIG_HISILICON_ERRATUM_162102203=y CONFIG_HISILICON_ERRATUM_162100801=y CONFIG_HISILICON_ERRATUM_162100602=y CONFIG_HISILICON_ERRATUM_162200803=y +CONFIG_HISILICON_ERRATUM_162200806=y CONFIG_QCOM_FALKOR_ERRATUM_1003=y CONFIG_QCOM_FALKOR_ERRATUM_1009=y CONFIG_QCOM_QDF2400_ERRATUM_0065=y diff --git a/arch/arm64/kvm/vgic/vgic-mmio.c b/arch/arm64/kvm/vgic/vgic-mmio.c index 59b81e5ce1d8..56549ee4313c 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio.c +++ b/arch/arm64/kvm/vgic/vgic-mmio.c @@ -228,6 +228,7 @@ int vgic_uaccess_write_cenable(struct kvm_vcpu *vcpu, return 0; }
+#define VIRTUAL_SGI_PENDING_OFFSET 0x3F0 static unsigned long __read_pending(struct kvm_vcpu *vcpu, gpa_t addr, unsigned int len, bool is_user) @@ -235,6 +236,7 @@ static unsigned long __read_pending(struct kvm_vcpu *vcpu, u32 intid = VGIC_ADDR_TO_INTID(addr, 1); u32 value = 0; int i; + struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
/* Loop over all IRQs affected by this read */ for (i = 0; i < len * 8; i++) { @@ -255,6 +257,21 @@ static unsigned long __read_pending(struct kvm_vcpu *vcpu, if (vgic_direct_sgi_or_ppi(irq)) { int err;
+ if (irq->hw && vgic_irq_is_sgi(irq->intid) && + (kvm_vgic_global_state.flags & + FLAGS_WORKAROUND_HIP09_ERRATUM_162200806)) { + void *va; + u8 *ptr; + int mask; + bool is_pending; + + mask = BIT(irq->intid % BITS_PER_BYTE); + va = page_address(vpe->vpt_page); + ptr = va + VIRTUAL_SGI_PENDING_OFFSET + + irq->intid / BITS_PER_BYTE; + is_pending = *ptr & mask; + } + val = false; err = irq_get_irqchip_state(irq->host_irq, IRQCHIP_STATE_PENDING, diff --git a/arch/arm64/kvm/vgic/vgic-mmio.h b/arch/arm64/kvm/vgic/vgic-mmio.h index 55f49933e304..0477ec95e96c 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio.h +++ b/arch/arm64/kvm/vgic/vgic-mmio.h @@ -6,6 +6,7 @@ #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 { unsigned int reg_offset; diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 2ef910e14ac0..c8d2878d73d3 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -42,6 +42,7 @@ #define FLAGS_WORKAROUND_MTK_GICR_SAVE (1ULL << 2) #define FLAGS_WORKAROUND_ASR_ERRATUM_8601001 (1ULL << 3) #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)
@@ -1972,6 +1973,15 @@ static bool gic_enable_quirk_hip09_162200803(void *data) return true; }
+static bool 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[] = { { .desc = "GICv3: Qualcomm MSM8996 broken firmware", @@ -2050,6 +2060,14 @@ static const struct gic_quirk gic_quirks[] = { .mask = 0xffffffff, .init = gic_enable_quirk_hip09_162200803, }, +#endif +#ifdef CONFIG_HISILICON_ERRATUM_162200806 + { + .desc = "GICv3: HIP09 erratum 162200806", + .iidr = 0x01050736, + .mask = 0xffffffff, + .init = gic_enable_quirk_hip09_162200806, + }, #endif { }