[PATCH v2] powerpc: warn on emulation of dcbz instruction in kernel mode

LEROY Christophe christophe.leroy2 at cs-soprasteria.com
Thu Aug 22 15:25:10 AEST 2024


+ CC Christoph Hellwig

Hi,

Le 22/08/2024 à 00:39, Christian Lamparter a écrit :
> [Vous ne recevez pas souvent de courriers de
> christian.lamparter at isd.uni-stuttgart.de. Découvrez pourquoi ceci est
> important à https://aka.ms/LearnAboutSenderIdentification ]
>
> Sorry to write a reply to this old mail. But after years, I finally
> decided to tackle an "old" problem that has come up...
> And unfortunately it is related to this patch. But let me explain.
>
> On 9/16/21 4:52 PM, Christophe Leroy wrote:
>> dcbz instruction shouldn't be used on non-cached memory. Using
>> it on non-cached memory can result in alignment exception and
>> implies a heavy handling.
>>
>> Instead of silentely emulating the instruction and resulting in high
>> performance degradation, warn whenever an alignment exception is
>> taken in kernel mode due to dcbz, so that the user is made aware that
>> dcbz instruction has been used unexpectedly by the kernel.
>
>
>
> The devices that are affected are APM821xx: MyBook Live, Meraki MX60,
> Netgear WNDR4700, ...
> All these have this "splat" during boot:
>

...

>
> what happens is that the EMAC (ethernet driver) uses a
> dma_alloc_coherent here:


...

> and this results in a call to dma_direct_allocation(), which has one
> innocent looking memset():


memset() can't be used on non-cached memory, memset_io() has to be used
instead.

...

> And of course, this triggers the WARNING above. As for why memset uses
> that dcbz... this is explained in:
...

>
> could this WARN_ON_ONCE maybe be downgraded to a single pr_info_once?
> I don't see how to tackle this "neatly" in a better way.

Can you try with the change below ?

diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 4480a3cd92e0..e2bee5fcc172 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -283,13 +283,15 @@ void *dma_direct_alloc(struct device *dev, size_t
size,
                                __builtin_return_address(0));
                if (!ret)
                        goto out_free_pages;
+
+               memset_io(ret, 0, size);
        } else {
                ret = page_address(page);
                if (dma_set_decrypted(dev, ret, size))
                        goto out_leak_pages;
-       }

-       memset(ret, 0, size);
+               memset(ret, 0, size);
+       }

        if (set_uncached) {
                arch_dma_prep_coherent(page, size);



>
> BugLink:
> <https://github.com/openwrt/openwrt/pull/14037#issuecomment-2302485414>
>


More information about the Linuxppc-dev mailing list