[PATCH] irqchip/gicv3-its: Add workaround for HIP09/HIP10/HIP10C erratum 162100803/162200807/162400807

Zhou Wang wangzhou1 at hisilicon.com
Mon Sep 15 07:06:35 PDT 2025


On 2025/9/15 20:23, Marc Zyngier wrote:
> On Wed, 10 Sep 2025 04:27:15 +0100,
> Zhou Wang <wangzhou1 at hisilicon.com> wrote:
>>

[...]

>>>
>>> You are telling the ITS that it is allowed to go and access
>>> unspecified data (16 bit worth of translations). That's not
>>> acceptable. If you *have* to do that, then override the size in the
>>> driver code to actually allocate the corresponding memory.
>>
>> Then we have to override the ITT memory to 2 ^ 16 * 8 for one device
>> :(
> 
> But what's the alternative? Letting the ITS speculate in random
> memory, possibly under the control of userspace or a guest? I don't
> think that's acceptable.

Seems that only a bad device who could send an interrupt which is not be
declared may bring a problem here.

Not sure how dose userspace or a guest make a problem here?

> 
> [...]
> 
>>>> +	/*
>>>> +	 * Cache invalidate 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;
>>>> +	}
>>>
>>> Please define these bits so that they have names instead of using raw
>>> values. Why do you need to write bit 16 every time? Surely once you
>>> have written it *once*, the HW remember what it has been told to do?
>>
>> HW will not remember it, so we have to write bit 16 every time.
>>
>>>
>>> And frankly, using readl_relaxed_poll_timeout_atomic should be the
>>> right thing to do.
>>
>> The HW logic is that write bit 16 will trigger DT cache clear in one HW cycle
>> or not. NOT that waiting bit 19 to flip.
> 
> Huh. This sounds crazy... Please document this.

OK.

> 
> [...]
> 
>>>> +#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,
>>>
>>> Can you try to merge these three entries and adjust the mask
>>> accordingly? mask=0xeffcffff should do the trick, assuming that you
>>> don't have any other hardware overlapping this.
>>
>> The iidrs are different, how to merge these entries?
> 
> By using the mask:
> 
> 	{
> 		.desc = "ITS: Hip10 erratum, will eat your vSGIs",
> 		.iidr = 0x01051736,
> 		.mask = 0xeffcffff,
> 		.init = its_enable_quirk_162100803,
> 	},
> 
> will match all three platforms, assuming I got the mask correctly.

iidrs are differet, so one iidr can not match all. e.g.
for iidr = 0x00061736, mask with 0xeffcffff will be 0x00041736, which
will not be 0x01051736.

>  
>>
>>>
>>>> +	},
>>>> +#endif
>>>>  #ifdef CONFIG_ROCKCHIP_ERRATUM_3588001
>>>>  	{
>>>>  		.desc   = "ITS: Rockchip erratum RK3588001",
>>>
>>> If the HW is this bad, and that this only affects virtual interrupts,
>>> why don't you simply disable GICv4 support? Messing with the internals
>>> of the ITS tables feels like a pretty bad idea. Or as I suggested
>>> above, get the firmware to ignore RAS events from the ITS.
>>
>> The hack is ugly, but we want to try to save vSGI direct
>> injection...
> 
> Well, if you think this is worth it...
> 
> 	M.
> 



More information about the linux-arm-kernel mailing list