From 555924d95327941de903305683d34a6b9abdc5e6 Mon Sep 17 00:00:00 2001 From: lutong Date: Fri, 7 Nov 2025 14:15:36 +0800 Subject: [PATCH 1/5] KVM: arm64: Deactivate the spurious vtimer interrupt commit 387b558fec9f8b0d3e0a4d48b5912301c1477bdd openEuler when hypervisor receives a vtimer interrupt but ISTATUS is 0, kvm_timer_update_irq will not be executed to inject this interrupt into the VM. Since EOImode is 1 and the timer interrupt has IRQD_FORWARDED_TO_VCPU flag, hypervisor will not write ICC_DIR_EL1 to deactivate the interrupt. This interrupt remains in active state, blocking subsequent interrupt from being process. Fixes: ("KVM: arm/arm64: arch_timer: Assign the phys timer on VHE systems") Signed-off-by: Kunkun Jiang Signed-off-by: Jia Qingtong Signed-off-by: Chengfei Huang Signed-off-by: Lutong Signed-off-by: Xie Xiaodong <624338359@qq.com> --- arch/arm64/kvm/arch_timer.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 70c1fb6c217e..94fe11382343 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -227,6 +227,14 @@ static void soft_timer_cancel(struct hrtimer *hrt) hrtimer_cancel(hrt); } +static inline void set_timer_irq_phys_active(struct arch_timer_context *ctx, bool active) +{ + int r; + + r = irq_set_irqchip_state(ctx->host_timer_irq, IRQCHIP_STATE_ACTIVE, active); + WARN_ON(r); +} + static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id) { struct kvm_vcpu *vcpu = *(struct kvm_vcpu **)dev_id; @@ -251,6 +259,8 @@ static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id) if (kvm_timer_should_fire(ctx)) kvm_timer_update_irq(vcpu, true, ctx); + else + set_timer_irq_phys_active(ctx, false); if (userspace_irqchip(vcpu->kvm) && !static_branch_unlikely(&has_gic_active_state)) @@ -665,13 +675,6 @@ static void timer_restore_state(struct arch_timer_context *ctx) local_irq_restore(flags); } -static inline void set_timer_irq_phys_active(struct arch_timer_context *ctx, bool active) -{ - int r; - r = irq_set_irqchip_state(ctx->host_timer_irq, IRQCHIP_STATE_ACTIVE, active); - WARN_ON(r); -} - static void kvm_timer_vcpu_load_gic(struct arch_timer_context *ctx) { struct kvm_vcpu *vcpu = ctx->vcpu; -- Gitee From 169565f5fa57f4143d3a6312ff85683df5b1b01e Mon Sep 17 00:00:00 2001 From: Xiang Chen Date: Wed, 10 Apr 2024 10:09:32 +0800 Subject: [PATCH 2/5] irqchip/gicv3-its: Add workaround for hip09 ITS erratum 162100801 commit 931d277db5ac43a9fefac1d984914ae3fc540328 openEuler When enabled GICv4.1 in hip09, there are some invalid vPE configurations in configuration table for some situations, which will cause some vSGI interrupts lost. To fix the issue, need to send vinvall command after vmovp. Signed-off-by: Nianyao Tang Signed-off-by: Xiang Chen Signed-off-by: CaiJian Signed-off-by: Xie Xiaodong <624338359@qq.com> --- Documentation/arch/arm64/silicon-errata.rst | 3 ++ arch/arm64/Kconfig | 10 ++++++ arch/arm64/configs/tencent.config | 3 ++ drivers/irqchip/irq-gic-v3-its.c | 36 ++++++++++++++++----- 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst index 7aced13b12c4..ae3f162707eb 100644 --- a/Documentation/arch/arm64/silicon-errata.rst +++ b/Documentation/arch/arm64/silicon-errata.rst @@ -254,6 +254,9 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Hisilicon | HIP09 | #162102203 | HISILICON_ERRATUM_162102203 | +----------------+-----------------+-----------------+-----------------------------+ +| Hisilicon | Hip09 | #162100801 | HISILICON_ERRATUM_162100801 | ++----------------+-----------------+-----------------+-----------------------------+ ++----------------+-----------------+-----------------+-----------------------------+ | 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 4322fce134cb..ebef39c7e454 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1268,6 +1268,16 @@ config HISILICON_ERRATUM_162102203 be lost. If unsure, say N. +config HISILICON_ERRATUM_162100801 + bool "Hip09 162100801 erratum support" + default y + help + When enabled GICv4.1 in hip09, there are some invalid vPE config + in configuration tables for some situation, which will cause vSGI + interrupts lost. So fix it by sending vinvall commands after vmovp. + + If unsure, say Y. + config QCOM_FALKOR_ERRATUM_1003 bool "Falkor E1003: Incorrect translation due to ASID change" diff --git a/arch/arm64/configs/tencent.config b/arch/arm64/configs/tencent.config index 23373f2e6b18..056650c6da6f 100644 --- a/arch/arm64/configs/tencent.config +++ b/arch/arm64/configs/tencent.config @@ -1773,8 +1773,11 @@ CONFIG_CPU_INSPECTOR_ATF=m # end of CPU Inspect CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y CONFIG_HISILICON_ERRATUM_162102203=y + # # ARMv8.6 architectural features # CONFIG_ARM64_TWED=y # end of ARMv8.6 architectural features + +CONFIG_HISILICON_ERRATUM_162100801=y diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index d705851c53e1..afa5ecf9d4ae 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -50,6 +50,7 @@ #define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1) #define ITS_FLAGS_WORKAROUND_CAVIUM_23144 (1ULL << 2) #define ITS_FLAGS_FORCE_NON_SHAREABLE (1ULL << 3) +#define ITS_FLAGS_WORKAROUND_HISILICON_162100801 (1ULL << 4) #define RD_LOCAL_LPI_ENABLED BIT(0) #define RD_LOCAL_PENDTABLE_PREALLOCATED BIT(1) @@ -1401,6 +1402,14 @@ static void its_send_vmapp(struct its_node *its, its_send_single_vcommand(its, its_build_vmapp_cmd, &desc); } +static void its_send_vinvall(struct its_node *its, struct its_vpe *vpe) +{ + struct its_cmd_desc desc; + + desc.its_vinvall_cmd.vpe = vpe; + its_send_single_vcommand(its, its_build_vinvall_cmd, &desc); +} + static void its_send_vmovp(struct its_vpe *vpe) { struct its_cmd_desc desc = {}; @@ -1440,19 +1449,14 @@ static void its_send_vmovp(struct its_vpe *vpe) desc.its_vmovp_cmd.col = &its->collections[col_id]; its_send_single_vcommand(its, its_build_vmovp_cmd, &desc); + if (is_v4_1(its) && (its->flags & + ITS_FLAGS_WORKAROUND_HISILICON_162100801)) + its_send_vinvall(its, vpe); } raw_spin_unlock_irqrestore(&vmovp_lock, flags); } -static void its_send_vinvall(struct its_node *its, struct its_vpe *vpe) -{ - struct its_cmd_desc desc; - - desc.its_vinvall_cmd.vpe = vpe; - its_send_single_vcommand(its, its_build_vinvall_cmd, &desc); -} - static void its_send_vinv(struct its_device *dev, u32 event_id) { struct its_cmd_desc desc; @@ -4863,6 +4867,14 @@ static bool its_set_non_coherent(void *data) return true; } +static bool __maybe_unused its_enable_quirk_hip09_162100801(void *data) +{ + struct its_node *its = data; + + its->flags |= ITS_FLAGS_WORKAROUND_HISILICON_162100801; + return true; +} + static const struct gic_quirk its_quirks[] = { #ifdef CONFIG_CAVIUM_ERRATUM_22375 { @@ -4909,6 +4921,14 @@ static const struct gic_quirk its_quirks[] = { .init = its_enable_quirk_hip07_161600802, }, #endif +#ifdef CONFIG_HISILICON_ERRATUM_162100801 + { + .desc = "ITS: Hip09 erratum 162100801", + .iidr = 0x00051736, + .mask = 0xffffffff, + .init = its_enable_quirk_hip09_162100801, + }, +#endif #ifdef CONFIG_ROCKCHIP_ERRATUM_3588001 { .desc = "ITS: Rockchip erratum RK3588001", -- Gitee From 14e04af8f169d7b2d3f573749e6fbfa24ab2eb6c Mon Sep 17 00:00:00 2001 From: Nianyao Tang Date: Thu, 15 May 2025 14:53:59 +0000 Subject: [PATCH 3/5] irqchip/gic-v4.1: Use local 4_1 ITS to generate VSGI commit f1a3fac4095c7bc0b30e2aa9921c232af8faeae0 upstream On multi-node GICv4.1 system, VSGI senders always use one certain 4_1 ITS, because find_4_1_its() returns the first its_node in the list, regardless of which node the VSGI sender is on. This brings guest VSGI performance drop when VM is not running on the same node as this returned ITS. On a 2-socket environment, each with one ITS and 32 cpu, GICv4.1 enabled, 4U8G guest, 4 vcpu is running on same socket. When the VM is on socket0, kvm-unit-tests ipi_hw result is 850ns. When the VM is on socket1, it is 750ns. The reason is that the VSGI sender always uses the last reported ITS (that on socket1) to inject VSGI. The access from a CPU to a other-socket ITS will cost 100ns more compared to an access to the local ITS. Using the local ITS results in a 12% reduction in IPI latency. Modify find_4_1_its() to return the first per-CPU local_4_1_its, which is initialized when the VPE table is inherited from the ITS or from another CPU. If it fails to find a local 4_1 ITS, it returns any 4_1 ITS like before. Suggested-by: Marc Zyngier Signed-off-by: Nianyao Tang Signed-off-by: Thomas Gleixner Reviewed-by: Marc Zyngier Signed-off-by: Xie Xiaodong <624338359@qq.com> Link: https://lore.kernel.org/all/20250515145359.2795959-1-tangnianyao@huawei.com --- drivers/irqchip/irq-gic-v3-its.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index afa5ecf9d4ae..27bcc807c02d 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -127,6 +127,8 @@ struct its_node { int vlpi_redist_offset; }; +static DEFINE_PER_CPU(struct its_node *, local_4_1_its); + #define is_v4(its) (!!((its)->typer & GITS_TYPER_VLPIS)) #define is_v4_1(its) (!!((its)->typer & GITS_TYPER_VMAPP)) #define device_ids(its) (FIELD_GET(GITS_TYPER_DEVBITS, (its)->typer) + 1) @@ -2809,6 +2811,7 @@ static u64 inherit_vpe_l1_table_from_its(void) } val |= FIELD_PREP(GICR_VPROPBASER_4_1_SIZE, GITS_BASER_NR_PAGES(baser) - 1); + *this_cpu_ptr(&local_4_1_its) = its; return val; } @@ -2846,6 +2849,7 @@ static u64 inherit_vpe_l1_table_from_rd(cpumask_t **mask) gic_data_rdist()->vpe_l1_base = gic_data_rdist_cpu(cpu)->vpe_l1_base; *mask = gic_data_rdist_cpu(cpu)->vpe_table_mask; + *this_cpu_ptr(&local_4_1_its) = *per_cpu_ptr(&local_4_1_its, cpu); return val; } @@ -4163,7 +4167,7 @@ static struct irq_chip its_vpe_irq_chip = { static struct its_node *find_4_1_its(void) { - static struct its_node *its = NULL; + struct its_node *its = *this_cpu_ptr(&local_4_1_its); if (!its) { list_for_each_entry(its, &its_nodes, entry) { -- Gitee From be1c3cfc465622bf0c4e8b89e19893e85ca0031c Mon Sep 17 00:00:00 2001 From: Zhou Wang Date: Fri, 29 Aug 2025 11:18:28 +0800 Subject: [PATCH 4/5] irqchip/gicv3-its: Add workaround for HIP09/HIP10/HIP10C/HIP12 erratum 162100803/162200807/162400807/165010802 commit 36fc586982d7eb2e7893fef8e00c78db4d2b4c41 openEuler HIP09/HIP10/HIP10C ITS have a problem, an ITS RAS will be reported in some cases when GICv4.1 is enable. A workaround is that set ITT size to max value(0xf) when doing MAPD with V = 1, and avoid to send MAPD with V = 0 to hardware. Just clear V field in ITS device table and clear ITS cache to implement MAPD with V = 0 instead. Signed-off-by: Zhou Wang Reviewed-by: Nianyao Tang Reviewed-by: Kunkun Jiang Signed-off-by: Jian Cai Signed-off-by: Xie Xiaodong <624338359@qq.com> --- arch/arm64/Kconfig | 12 ++++ drivers/irqchip/irq-gic-v3-its.c | 120 +++++++++++++++++++++++++++---- 2 files changed, 118 insertions(+), 14 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index ebef39c7e454..2843b6be308b 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1278,6 +1278,18 @@ config HISILICON_ERRATUM_162100801 If unsure, say Y. +config HISILICON_ERRATUM_162100803 + bool "Hip09/10/10c/12 162100803/162200807/162400807/165010802 erratum support" + default y + help + There is a hardware conflict between vSGI and vLPI, fix it by + configure a max ITS ITT size 0xf when doing MAPD with V = 1, clear V + field in ITS device table and clear ITS cache to implement MAPD with + V = 0 instead. Hip09/10/10c/12 have this same problem, just use + HISILICON_ERRATUM_162100803 as the compile macro and + ITS_FLAGS_WORKAROUND_HISILICON_162100803 as ITS flag for convenience + + If unsure, say Y. config QCOM_FALKOR_ERRATUM_1003 bool "Falkor E1003: Incorrect translation due to ASID change" diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 27bcc807c02d..2969bb07ec93 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -51,6 +51,7 @@ #define ITS_FLAGS_WORKAROUND_CAVIUM_23144 (1ULL << 2) #define ITS_FLAGS_FORCE_NON_SHAREABLE (1ULL << 3) #define ITS_FLAGS_WORKAROUND_HISILICON_162100801 (1ULL << 4) +#define ITS_FLAGS_WORKAROUND_HISILICON_162100803 (1ULL << 5) #define RD_LOCAL_LPI_ENABLED BIT(0) #define RD_LOCAL_PENDTABLE_PREALLOCATED BIT(1) @@ -715,7 +716,12 @@ static struct its_collection *its_build_mapd_cmd(struct its_node *its, its_encode_cmd(cmd, GITS_CMD_MAPD); its_encode_devid(cmd, desc->its_mapd_cmd.dev->device_id); - its_encode_size(cmd, size - 1); + + if (its->flags & ITS_FLAGS_WORKAROUND_HISILICON_162100803) + its_encode_size(cmd, 0xf); + else + its_encode_size(cmd, size - 1); + its_encode_itt(cmd, itt_addr); its_encode_valid(cmd, desc->its_mapd_cmd.valid); @@ -724,6 +730,61 @@ static struct its_collection *its_build_mapd_cmd(struct its_node *its, return NULL; } +static struct its_baser *its_get_baser(struct its_node *its, u32 type) +{ + int i; + + for (i = 0; i < GITS_BASER_NR_REGS; i++) { + if (GITS_BASER_TYPE(its->tables[i].val) == type) + return &its->tables[i]; + } + + return NULL; +} + +static struct its_collection +*its_build_mapd_cmd_hisi_quirk(struct its_node *its, struct its_cmd_block *cmd, + struct its_cmd_desc *desc) +{ + struct its_baser *baser = its_get_baser(its, GITS_BASER_TYPE_DEVICE); + u32 devid = desc->its_mapd_cmd.dev->device_id; + void *base = baser->base; + u32 *dt_entry; + void __iomem *its_func_en = its->sgir_base + 0x80; + u32 tmp, tmp1, mask = 1 << 19; + int i = 100; + + /* + * The device table is flat. Modify v to 0 in the dt entry of devid, + * dt entry format as below: word0: [0-31] ITT address; word1: [0-7] + * ITT address, [8-12]: ITT size, [13]: V + */ + dt_entry = (u32 *)(base + devid * 8 + 4); + *dt_entry &= ~(1 << 13); + + dsb(ishst); + + /* + * Invalidate cache by a private register GITS_FUNC_EN, whose offset + * is 0x20080 of ITS base address. GICv4.1 already maps sgir_base + * (offset is 0x20000), so address of GITS_FUNC_EN can be got by + * sgir_base + 0x80. Bit 16 is used to clear DT cache, the flip of + * bit 19 indicates that DT cache has been cleared. + */ + while (--i) { + tmp = readl_relaxed(its_func_en) & mask; + writel_relaxed(tmp | (1 << 16), its_func_en); + tmp1 = readl_relaxed(its_func_en) & mask; + if (tmp != tmp1) + break; + } + + if (i == 0) + WARN_ON(1); + + return NULL; +} + static struct its_collection *its_build_mapc_cmd(struct its_node *its, struct its_cmd_block *cmd, struct its_cmd_desc *desc) @@ -1305,11 +1366,18 @@ static void its_send_inv(struct its_device *dev, u32 event_id) static void its_send_mapd(struct its_device *dev, int valid) { struct its_cmd_desc desc; + its_cmd_builder_t fn; + + if (dev->its->flags & ITS_FLAGS_WORKAROUND_HISILICON_162100803 && + valid == 0) + fn = its_build_mapd_cmd_hisi_quirk; + else + fn = its_build_mapd_cmd; desc.its_mapd_cmd.dev = dev; desc.its_mapd_cmd.valid = !!valid; - its_send_single_command(dev->its, its_build_mapd_cmd, &desc); + its_send_single_command(dev->its, fn, &desc); } static void its_send_mapc(struct its_node *its, struct its_collection *col, @@ -3384,18 +3452,6 @@ static struct its_device *its_find_device(struct its_node *its, u32 dev_id) return its_dev; } -static struct its_baser *its_get_baser(struct its_node *its, u32 type) -{ - int i; - - for (i = 0; i < GITS_BASER_NR_REGS; i++) { - if (GITS_BASER_TYPE(its->tables[i].val) == type) - return &its->tables[i]; - } - - return NULL; -} - static bool its_alloc_table_entry(struct its_node *its, struct its_baser *baser, u32 id) { @@ -4879,6 +4935,16 @@ static bool __maybe_unused its_enable_quirk_hip09_162100801(void *data) return true; } +static bool __maybe_unused its_enable_quirk_162100803(void *data) +{ + struct its_node *its = data; + + if (is_v4_1(its)) + its->flags |= ITS_FLAGS_WORKAROUND_HISILICON_162100803; + + return true; +} + static const struct gic_quirk its_quirks[] = { #ifdef CONFIG_CAVIUM_ERRATUM_22375 { @@ -4933,6 +4999,32 @@ static const struct gic_quirk its_quirks[] = { .init = its_enable_quirk_hip09_162100801, }, #endif +#ifdef CONFIG_HISILICON_ERRATUM_162100803 + { + .desc = "ITS: Hip09 erratum 162100803", + .iidr = 0x00051736, + .mask = 0xffffffff, + .init = its_enable_quirk_162100803, + }, + { + .desc = "ITS: Hip10 erratum 162200807", + .iidr = 0x01051736, + .mask = 0xffffffff, + .init = its_enable_quirk_162100803, + }, + { + .desc = "ITS: Hip10c erratum 162400807", + .iidr = 0x00061736, + .mask = 0xffffffff, + .init = its_enable_quirk_162100803, + }, + { + .desc = "ITS: Hip12 erratum 165010802", + .iidr = 0x00070736, + .mask = 0xffffffff, + .init = its_enable_quirk_162100803, + }, +#endif #ifdef CONFIG_ROCKCHIP_ERRATUM_3588001 { .desc = "ITS: Rockchip erratum RK3588001", -- Gitee From cd75a9c5003facca9ba434a87196487817d2762c Mon Sep 17 00:00:00 2001 From: Jian Cai Date: Fri, 29 Aug 2025 11:21:23 +0800 Subject: [PATCH 5/5] tencentconfig: Add CONFIG_HISILICON_ERRATUM_162100803 commit d2d1851235f2031f692eec5639bfb362d996bf1e openEuler Add CONFIG_HISILICON_ERRATUM_162100803 into openeuler_defconfig. Signed-off-by: Jian Cai Signed-off-by: Xie Xiaodong <624338359@qq.com> --- arch/arm64/configs/tencent.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/tencent.config b/arch/arm64/configs/tencent.config index 056650c6da6f..92b0cf9cfe42 100644 --- a/arch/arm64/configs/tencent.config +++ b/arch/arm64/configs/tencent.config @@ -1781,3 +1781,4 @@ CONFIG_ARM64_TWED=y # end of ARMv8.6 architectural features CONFIG_HISILICON_ERRATUM_162100801=y +CONFIG_HISILICON_ERRATUM_162100803=y \ No newline at end of file -- Gitee