Skip to content

Commit f82e62d

Browse files
Zhou WangKAGA-KOKO
Zhou Wang
authored andcommitted
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 <[email protected]> Co-developed-by: Nianyao Tang <[email protected]> Signed-off-by: Nianyao Tang <[email protected]> Signed-off-by: Zhou Wang <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Marc Zyngier <[email protected]>
1 parent 12aaf67 commit f82e62d

File tree

3 files changed

+52
-11
lines changed

3 files changed

+52
-11
lines changed

Documentation/arch/arm64/silicon-errata.rst

+2
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ stable kernels.
258258
| Hisilicon | Hip{08,09,10,10C| #162001900 | N/A |
259259
| | ,11} SMMU PMCG | | |
260260
+----------------+-----------------+-----------------+-----------------------------+
261+
| Hisilicon | Hip09 | #162100801 | HISILICON_ERRATUM_162100801 |
262+
+----------------+-----------------+-----------------+-----------------------------+
261263
+----------------+-----------------+-----------------+-----------------------------+
262264
| Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 |
263265
+----------------+-----------------+-----------------+-----------------------------+

arch/arm64/Kconfig

+11
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,17 @@ config HISILICON_ERRATUM_161600802
12361236

12371237
If unsure, say Y.
12381238

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+
12391250
config QCOM_FALKOR_ERRATUM_1003
12401251
bool "Falkor E1003: Incorrect translation due to ASID change"
12411252
default y

drivers/irqchip/irq-gic-v3-its.c

+39-11
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1)
4848
#define ITS_FLAGS_WORKAROUND_CAVIUM_23144 (1ULL << 2)
4949
#define ITS_FLAGS_FORCE_NON_SHAREABLE (1ULL << 3)
50+
#define ITS_FLAGS_WORKAROUND_HISILICON_162100801 (1ULL << 4)
5051

5152
#define RD_LOCAL_LPI_ENABLED BIT(0)
5253
#define RD_LOCAL_PENDTABLE_PREALLOCATED BIT(1)
@@ -64,6 +65,7 @@ static u32 lpi_id_bits;
6465
#define LPI_PENDBASE_SZ ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K)
6566

6667
static u8 __ro_after_init lpi_prop_prio;
68+
static struct its_node *find_4_1_its(void);
6769

6870
/*
6971
* Collection structure - just an ID, and a redistributor address to
@@ -3883,13 +3885,28 @@ static void its_vpe_db_proxy_move(struct its_vpe *vpe, int from, int to)
38833885
raw_spin_unlock_irqrestore(&vpe_proxy.lock, flags);
38843886
}
38853887

3888+
static void its_vpe_4_1_invall_locked(int cpu, struct its_vpe *vpe)
3889+
{
3890+
void __iomem *rdbase;
3891+
u64 val;
3892+
3893+
val = GICR_INVALLR_V;
3894+
val |= FIELD_PREP(GICR_INVALLR_VPEID, vpe->vpe_id);
3895+
3896+
guard(raw_spinlock)(&gic_data_rdist_cpu(cpu)->rd_lock);
3897+
rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base;
3898+
gic_write_lpir(val, rdbase + GICR_INVALLR);
3899+
wait_for_syncr(rdbase);
3900+
}
3901+
38863902
static int its_vpe_set_affinity(struct irq_data *d,
38873903
const struct cpumask *mask_val,
38883904
bool force)
38893905
{
38903906
struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
38913907
unsigned int from, cpu = nr_cpu_ids;
38923908
struct cpumask *table_mask;
3909+
struct its_node *its;
38933910
unsigned long flags;
38943911

38953912
/*
@@ -3952,6 +3969,11 @@ static int its_vpe_set_affinity(struct irq_data *d,
39523969
vpe->col_idx = cpu;
39533970

39543971
its_send_vmovp(vpe);
3972+
3973+
its = find_4_1_its();
3974+
if (its && its->flags & ITS_FLAGS_WORKAROUND_HISILICON_162100801)
3975+
its_vpe_4_1_invall_locked(cpu, vpe);
3976+
39553977
its_vpe_db_proxy_move(vpe, from, cpu);
39563978

39573979
out:
@@ -4259,22 +4281,12 @@ static void its_vpe_4_1_deschedule(struct its_vpe *vpe,
42594281

42604282
static void its_vpe_4_1_invall(struct its_vpe *vpe)
42614283
{
4262-
void __iomem *rdbase;
42634284
unsigned long flags;
4264-
u64 val;
42654285
int cpu;
42664286

4267-
val = GICR_INVALLR_V;
4268-
val |= FIELD_PREP(GICR_INVALLR_VPEID, vpe->vpe_id);
4269-
42704287
/* Target the redistributor this vPE is currently known on */
42714288
cpu = vpe_to_cpuid_lock(vpe, &flags);
4272-
raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock);
4273-
rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base;
4274-
gic_write_lpir(val, rdbase + GICR_INVALLR);
4275-
4276-
wait_for_syncr(rdbase);
4277-
raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock);
4289+
its_vpe_4_1_invall_locked(cpu, vpe);
42784290
vpe_to_cpuid_unlock(vpe, flags);
42794291
}
42804292

@@ -4867,6 +4879,14 @@ static bool its_set_non_coherent(void *data)
48674879
return true;
48684880
}
48694881

4882+
static bool __maybe_unused its_enable_quirk_hip09_162100801(void *data)
4883+
{
4884+
struct its_node *its = data;
4885+
4886+
its->flags |= ITS_FLAGS_WORKAROUND_HISILICON_162100801;
4887+
return true;
4888+
}
4889+
48704890
static const struct gic_quirk its_quirks[] = {
48714891
#ifdef CONFIG_CAVIUM_ERRATUM_22375
48724892
{
@@ -4913,6 +4933,14 @@ static const struct gic_quirk its_quirks[] = {
49134933
.init = its_enable_quirk_hip07_161600802,
49144934
},
49154935
#endif
4936+
#ifdef CONFIG_HISILICON_ERRATUM_162100801
4937+
{
4938+
.desc = "ITS: Hip09 erratum 162100801",
4939+
.iidr = 0x00051736,
4940+
.mask = 0xffffffff,
4941+
.init = its_enable_quirk_hip09_162100801,
4942+
},
4943+
#endif
49164944
#ifdef CONFIG_ROCKCHIP_ERRATUM_3588001
49174945
{
49184946
.desc = "ITS: Rockchip erratum RK3588001",

0 commit comments

Comments
 (0)