irqchip/gicv3-its: Add workaround for hip09 ITS erratum 162100801

When enabling GICv4.1 in hip09, VMAPP fails to clear some caches during
the unmap operation, which can causes vSGIs to be lost.

To fix the issue, invalidate the related vPE cache through GICR_INVALLR
after VMOVP.

Suggested-by: Marc Zyngier <maz@kernel.org>
Co-developed-by: Nianyao Tang <tangnianyao@huawei.com>
Signed-off-by: Nianyao Tang <tangnianyao@huawei.com>
Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Marc Zyngier <maz@kernel.org>

authored by Zhou Wang and committed by Thomas Gleixner f82e62d4 12aaf675

Changed files
+52 -11
Documentation
arch
arch
arm64
drivers
+2
Documentation/arch/arm64/silicon-errata.rst
··· 258 258 | Hisilicon | Hip{08,09,10,10C| #162001900 | N/A | 259 259 | | ,11} SMMU PMCG | | | 260 260 +----------------+-----------------+-----------------+-----------------------------+ 261 + | Hisilicon | Hip09 | #162100801 | HISILICON_ERRATUM_162100801 | 262 + +----------------+-----------------+-----------------+-----------------------------+ 261 263 +----------------+-----------------+-----------------+-----------------------------+ 262 264 | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | 263 265 +----------------+-----------------+-----------------+-----------------------------+
+11
arch/arm64/Kconfig
··· 1236 1236 1237 1237 If unsure, say Y. 1238 1238 1239 + config HISILICON_ERRATUM_162100801 1240 + bool "Hip09 162100801 erratum support" 1241 + default y 1242 + help 1243 + When enabling GICv4.1 in hip09, VMAPP will fail to clear some caches 1244 + during unmapping operation, which will cause some vSGIs lost. 1245 + To fix the issue, invalidate related vPE cache through GICR_INVALLR 1246 + after VMOVP. 1247 + 1248 + If unsure, say Y. 1249 + 1239 1250 config QCOM_FALKOR_ERRATUM_1003 1240 1251 bool "Falkor E1003: Incorrect translation due to ASID change" 1241 1252 default y
+39 -11
drivers/irqchip/irq-gic-v3-its.c
··· 47 47 #define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1) 48 48 #define ITS_FLAGS_WORKAROUND_CAVIUM_23144 (1ULL << 2) 49 49 #define ITS_FLAGS_FORCE_NON_SHAREABLE (1ULL << 3) 50 + #define ITS_FLAGS_WORKAROUND_HISILICON_162100801 (1ULL << 4) 50 51 51 52 #define RD_LOCAL_LPI_ENABLED BIT(0) 52 53 #define RD_LOCAL_PENDTABLE_PREALLOCATED BIT(1) ··· 65 64 #define LPI_PENDBASE_SZ ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K) 66 65 67 66 static u8 __ro_after_init lpi_prop_prio; 67 + static struct its_node *find_4_1_its(void); 68 68 69 69 /* 70 70 * Collection structure - just an ID, and a redistributor address to ··· 3885 3883 raw_spin_unlock_irqrestore(&vpe_proxy.lock, flags); 3886 3884 } 3887 3885 3886 + static void its_vpe_4_1_invall_locked(int cpu, struct its_vpe *vpe) 3887 + { 3888 + void __iomem *rdbase; 3889 + u64 val; 3890 + 3891 + val = GICR_INVALLR_V; 3892 + val |= FIELD_PREP(GICR_INVALLR_VPEID, vpe->vpe_id); 3893 + 3894 + guard(raw_spinlock)(&gic_data_rdist_cpu(cpu)->rd_lock); 3895 + rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base; 3896 + gic_write_lpir(val, rdbase + GICR_INVALLR); 3897 + wait_for_syncr(rdbase); 3898 + } 3899 + 3888 3900 static int its_vpe_set_affinity(struct irq_data *d, 3889 3901 const struct cpumask *mask_val, 3890 3902 bool force) ··· 3906 3890 struct its_vpe *vpe = irq_data_get_irq_chip_data(d); 3907 3891 unsigned int from, cpu = nr_cpu_ids; 3908 3892 struct cpumask *table_mask; 3893 + struct its_node *its; 3909 3894 unsigned long flags; 3910 3895 3911 3896 /* ··· 3969 3952 vpe->col_idx = cpu; 3970 3953 3971 3954 its_send_vmovp(vpe); 3955 + 3956 + its = find_4_1_its(); 3957 + if (its && its->flags & ITS_FLAGS_WORKAROUND_HISILICON_162100801) 3958 + its_vpe_4_1_invall_locked(cpu, vpe); 3959 + 3972 3960 its_vpe_db_proxy_move(vpe, from, cpu); 3973 3961 3974 3962 out: ··· 4281 4259 4282 4260 static void its_vpe_4_1_invall(struct its_vpe *vpe) 4283 4261 { 4284 - void __iomem *rdbase; 4285 4262 unsigned long flags; 4286 - u64 val; 4287 4263 int cpu; 4288 - 4289 - val = GICR_INVALLR_V; 4290 - val |= FIELD_PREP(GICR_INVALLR_VPEID, vpe->vpe_id); 4291 4264 4292 4265 /* Target the redistributor this vPE is currently known on */ 4293 4266 cpu = vpe_to_cpuid_lock(vpe, &flags); 4294 - raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock); 4295 - rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base; 4296 - gic_write_lpir(val, rdbase + GICR_INVALLR); 4297 - 4298 - wait_for_syncr(rdbase); 4299 - raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock); 4267 + its_vpe_4_1_invall_locked(cpu, vpe); 4300 4268 vpe_to_cpuid_unlock(vpe, flags); 4301 4269 } 4302 4270 ··· 4879 4867 return true; 4880 4868 } 4881 4869 4870 + static bool __maybe_unused its_enable_quirk_hip09_162100801(void *data) 4871 + { 4872 + struct its_node *its = data; 4873 + 4874 + its->flags |= ITS_FLAGS_WORKAROUND_HISILICON_162100801; 4875 + return true; 4876 + } 4877 + 4882 4878 static const struct gic_quirk its_quirks[] = { 4883 4879 #ifdef CONFIG_CAVIUM_ERRATUM_22375 4884 4880 { ··· 4931 4911 .iidr = 0x00000004, 4932 4912 .mask = 0xffffffff, 4933 4913 .init = its_enable_quirk_hip07_161600802, 4914 + }, 4915 + #endif 4916 + #ifdef CONFIG_HISILICON_ERRATUM_162100801 4917 + { 4918 + .desc = "ITS: Hip09 erratum 162100801", 4919 + .iidr = 0x00051736, 4920 + .mask = 0xffffffff, 4921 + .init = its_enable_quirk_hip09_162100801, 4934 4922 }, 4935 4923 #endif 4936 4924 #ifdef CONFIG_ROCKCHIP_ERRATUM_3588001