[PATCH v2] arm64: errata: Add NXP iMX8QM workaround for A53 Cache coherency issue
Ivan T. Ivanov
iivanov at suse.de
Thu Jun 8 11:22:54 PDT 2023
On 06-08 16:32, Mark Rutland wrote:
> On Thu, Jun 08, 2023 at 06:05:54PM +0300, Ivan T. Ivanov wrote:
> > On 06-08 15:16, Mark Rutland wrote:
> > > On Thu, Jun 08, 2023 at 04:39:29PM +0300, Ivan T. Ivanov wrote:
> > > > On 06-02 11:34, Will Deacon wrote:
> > > > > On Thu, Apr 20, 2023 at 02:29:52PM +0300, Ivan T. Ivanov wrote:
>
> > > > > > diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
> > > > > > index 4a79ba100799..265b6334291b 100644
> > > > > > --- a/arch/arm64/kernel/traps.c
> > > > > > +++ b/arch/arm64/kernel/traps.c
> > > > > > @@ -556,6 +556,11 @@ static void user_cache_maint_handler(unsigned long esr, struct pt_regs *regs)
> > > > > > __user_cache_maint("dc civac", address, ret);
> > > > > > break;
> > > > > > case ESR_ELx_SYS64_ISS_CRM_IC_IVAU: /* IC IVAU */
> > > > > > + if (cpus_have_final_cap(ARM64_WORKAROUND_NXP_ERR050104)) {
> > > > > > + asm volatile("ic ialluis");
> > > > >
> > > > > Hmm, one oddity here is that you can pass a faulting address and not see
> > > > > the fault. It looks like that's already IMP DEF, so it's probably ok, but
> > > > > might be worth a comment.
> > > >
> > > > I am not sure what should be expected behavior, but I could
> > > > add comment, sure.
> > >
> > > Another option is to make this:
> > >
> > > case ESR_ELx_SYS64_ISS_CRM_IC_IVAU: /* IC IVAU */
> > > __user_cache_maint("ic ivau", address, ret)
> > > if (cpus_have_final_cap(ARM64_WORKAROUND_NXP_ERR050104) && !ret)
> > > asm volatile("ic ialluis");
> > > break;
> > >
> > > Which'll ensure that if the regular IC IVAU faults we'll handle that, and if
> > > not we'll do the IC IALLUIS.
> > >
> > > I think that looks a bit cleaner, too.
> >
> > What I am afraid is that "ic ivau address" will do cache invalidation of a
> > random address, because of wrong address wiring. So the end result will not
> > be what should be expected.
>
> I don't follow:
>
> - The faulting logic is entirely local (and has to happen before the
> broadcast), so the faulting logic shouldn't be affected by the erratum and
> will use the correct address.
Perhaps is all me really not understanding PoU, so please
bear with me :-). This SoC hasi two CPU clusters.
4x Cortex A53
• 32KB-I and 32KB-D cache
• 1MB Shared L2 Cache
2x Cortex A72
• 48KB-I and 32KB-D cache
• 1MB Shared L2 Cache
If it is all local then how far this broadcast will go? Up to the
L2 cache? But then errata says that: ".. maintenance operations
exchanged between the A53 and A72 core clusters.. " are affected.
So in case of IC IAVU there is no interaction between clusters?
>
> - We're going to do an IC IALLUIS anyway, so we're going to do invalidation of
> *every* address. So randomly invalidating a random address at the same time
> isn't going to cause a functiona problem because we're going to invaldiate
> it anyway.
Yes, but my point was that this random address might generate a translation
error where there shouldn't be one.
>
> > > > > Finally, how come you don't need to upgrade I-cache invalidation by-VA
> > > > > in the kernel? It looks like you're only handling operations trapped
> > > > > from EL0.
> > > >
> > > > Hm, I was thinking that __tlbi() is taking care for this or you mean
> > > > something else, like locations in assembler.h?
> > >
> > > The __tlbi macro handles only TLBI instructions.
> > >
> > > The trap handler above *only* handles IC instructions trapped from userspace;
> >
> > Yep, I get this.
> >
> > > we have IC IVAU instructions elsewhere in the kernel (e.g.
> > > arch/arm64/mm/cache.S).
> >
> > But I have missed this one :-)
>
> Looking again, those all use the common invalidate_icache_by_line macro in
> arch/arm64/include/asm/assembler.h
>
> Lukily that seems to be all:
>
> | [mark at lakrids:~/src/linux]% git grep -iw ivau -- arch/arm64
> | arch/arm64/include/asm/assembler.h: ic ivau, \tmp2 // invalidate I line PoU
> | arch/arm64/kernel/traps.c: case ESR_ELx_SYS64_ISS_CRM_IC_IVAU: /* IC IVAU */
> | arch/arm64/kernel/traps.c: __user_cache_maint("ic ivau", address, ret);
>
> > I think that this is working because these are used only in operations witch
> > work up to the Point of Unification, thus not messing up with caches of the
> > rest of PE.
>
> I think you have a misunderstanding of the architecture, because that doesn't
> make sense. All IC IVAU operations operate to the Point of Unification. That's
> what the 'U' in 'IVAU' stands for. The Point of Unification is the point in the
> memory system where instruction fetches and data fetches see the same thing.
>
> If the VA passed to IC IVAU isn't correctly broadcast, it's broken regardless
> of where that IC IVAU is executed from, because it will leave stale
> instructions in the I-caches of other PEs.
I am totally confused :-) If this is true, and I am not saying it is not,
then we can't expect that IC IVAU will generate correct translation might
fault, no?
Regards,
Ivan
More information about the linux-arm-kernel
mailing list