[PATCH] powerpc/kasan: require memintrinsic prefix support for KASAN

2 views
Skip to first unread message

Mukesh Kumar Chaurasiya (IBM)

unread,
Sep 8, 2026, 2:50:04 AMSep 8
to ma...@linux.ibm.com, m...@ellerman.id.au, npi...@gmail.com, chl...@kernel.org, ryabin...@gmail.com, gli...@google.com, andre...@gmail.com, dvy...@google.com, vincenzo...@arm.com, p...@kernel.org, pal...@dabbelt.com, a...@eecs.berkeley.edu, al...@ghiti.fr, ke...@kernel.org, mkch...@gmail.com, amac...@linux.ibm.com, rites...@gmail.com, ro...@kernel.org, say...@linux.ibm.com, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linux...@lists.infradead.org, linux-h...@vger.kernel.org, Venkat Rao Bagalkote
powerpc unconditionally selects GENERIC_ENTRY. The GENERIC_ENTRY
infrastructure relies on the compiler emitting __asan_mem*() calls at
instrumented mem*() sites rather than plain memset/memcpy/memmove, so
that entry/exit paths calling those functions are not instrumented.

This assumption is encoded in two places:

mm/kasan/shadow.c:
#if !defined(CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX) &&
!defined(CONFIG_GENERIC_ENTRY)

include/linux/fortify-string.h:
#if !defined(CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX) &&
!defined(CONFIG_GENERIC_ENTRY)

When GENERIC_ENTRY is set, both guards suppress the C wrappers for
memset/memcpy/memmove and the __underlying_mem*() redirections. This
is only safe when the compiler supports the prefixed __asan_mem*()
intrinsics. On older toolchains (e.g. GCC 9) that lack this support,
plain mem*() calls from instrumented code fall through to the raw
assembly implementations in mem_64.S / copy_32.S, completely bypassing
the KASAN shadow check.

Other arches with GENERIC_ENTRY (x86, s390, loongarch, riscv) do not
hit this because their CI toolchains are always new enough to support
the prefix flag.

Background: the !GENERIC_ENTRY guard was introduced by commit 69d4c0d32186
("entry, kasan, x86: Disallow overriding mem*() functions", Peter Zijlstra,
Jan 2023). The root problem is that the KASAN C wrappers override the
linker symbol memset/memcpy/memmove globally, so any call from noinstr or
__no_sanitize_address code (e.g. irqentry_enter/irqentry_exit) would still
reach the KASAN shadow-check wrapper -- at a point where KASAN invariants
may not hold. The compiler prefix approach (Marco Elver, Feb 2023,
commit 51287dcb00cc) solves this by having the compiler emit __asan_memset
at instrumented call sites and bare memset inside __no_sanitize_address
functions, splitting the decision at code-generation time rather than at
link time.

A manual C-level override cannot replicate this split: a single linker
symbol cannot be made to resolve differently depending on the caller.

x86 also placed its raw memset/memcpy/memmove implementations in
.noinstr.text (same commit, 69d4c0d32186), which is the other half of
the fix: noinstr callers hit the raw assembly directly, safely bypassing
KASAN. PowerPC has not done this. Placing mem_64.S / memcpy_64.S /
copy_32.S implementations in .noinstr.text would be the complementary
long-term fix that could re-enable KASAN on older toolchains, but it
requires care around linker stub overflow on large PPC64 kernels (the
same reason powerpc uses NOKPROBE_SYMBOL rather than noinstr for its
interrupt handlers -- see the comment in asm/interrupt.h). That work
is left as a follow-up.

For now, introduce PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX, an arch-local
compiler probe that mirrors the same check as CC_HAS_KASAN_MEMINTRINSIC_PREFIX
in lib/Kconfig.kasan but lives outside the 'if KASAN' block to avoid a
recursive dependency (CC_HAS_KASAN_MEMINTRINSIC_PREFIX depends on KASAN
which depends on HAVE_ARCH_KASAN). Gate the three HAVE_ARCH_KASAN selects
on this new symbol so that KASAN is not offered as a config option on
toolchains that cannot support it correctly with GENERIC_ENTRY.

Since KASAN on powerpc now unconditionally implies
CC_HAS_KASAN_MEMINTRINSIC_PREFIX, the old !CC_HAS_KASAN_MEMINTRINSIC_PREFIX
code paths in asm/kasan.h and asm/string.h are dead. Clean them up:

- asm/kasan.h: remove the dual-entry-point variant of _GLOBAL_KASAN /
_GLOBAL_TOC_KASAN / EXPORT_SYMBOL_KASAN that emitted both memset and
__memset as entry points to the same assembly. These aliases were only
needed so the C KASAN wrappers in shadow.c could call __memset() to
reach raw memory ops; with the compiler prefix approach the wrappers are
not used at all for mem* on powerpc.

- asm/string.h: remove the separate __memset/__memcpy/__memmove symbol
declarations and the memset/memcpy/memmove macro redirections for
uninstrumented files that were needed on old toolchains. Simplify the
CONFIG_KASAN block to just the three #define aliases (which are still
used by shadow.c as raw backends).

- cputable.c, prom_init.c: update stale comments that said GCC replaces
memcpy() with __memcpy() under KASAN; with the prefix flag it emits
__asan_memcpy() instead.

Reported-by: Venkat Rao Bagalkote <venk...@linux.ibm.com>
Closes: https://lore.kernel.org/all/96dae110-f79b-4e54...@linux.ibm.com
Signed-off-by: Mukesh Kumar Chaurasiya (IBM) <mkch...@gmail.com>
---
arch/powerpc/Kconfig | 10 +++++++---
arch/powerpc/include/asm/kasan.h | 19 ++++++++-----------
arch/powerpc/include/asm/string.h | 25 +++++--------------------
arch/powerpc/kernel/cputable.c | 6 +++---
arch/powerpc/kernel/prom_init.c | 4 ++--
5 files changed, 25 insertions(+), 39 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 2580e27e4328..b27ed9739eea 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -7,6 +7,10 @@ config CC_HAS_ELFV2
config CC_HAS_PREFIXED
def_bool PPC64 && $(cc-option, -mcpu=power10 -mprefixed)

+config PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
+ def_bool (CC_IS_CLANG && $(cc-option,-fsanitize=kernel-address -mllvm -asan-kernel-mem-intrinsic-prefix=1)) || \
+ (CC_IS_GCC && $(cc-option,-fsanitize=kernel-address --param asan-kernel-mem-intrinsic-prefix=1))
+
config CC_HAS_PCREL
# Clang has a bug (https://github.com/llvm/llvm-project/issues/62372)
# where pcrel code is not generated if -msoft-float, -mno-altivec, or
@@ -220,9 +224,9 @@ config PPC
select HAVE_ARCH_HUGE_VMAP if PPC_RADIX_MMU || PPC_8xx
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE
- select HAVE_ARCH_KASAN if PPC32 && PAGE_SHIFT <= 14
- select HAVE_ARCH_KASAN if PPC_RADIX_MMU
- select HAVE_ARCH_KASAN if PPC_BOOK3E_64
+ select HAVE_ARCH_KASAN if PPC32 && PAGE_SHIFT <= 14 && PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
+ select HAVE_ARCH_KASAN if PPC_RADIX_MMU && PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
+ select HAVE_ARCH_KASAN if PPC_BOOK3E_64 && PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN
select HAVE_ARCH_KCSAN
select HAVE_ARCH_KFENCE if ARCH_SUPPORTS_DEBUG_PAGEALLOC
diff --git a/arch/powerpc/include/asm/kasan.h b/arch/powerpc/include/asm/kasan.h
index a690e7da53c2..ffada5f51b2b 100644
--- a/arch/powerpc/include/asm/kasan.h
+++ b/arch/powerpc/include/asm/kasan.h
@@ -2,20 +2,17 @@
#ifndef __ASM_KASAN_H
#define __ASM_KASAN_H

-#if defined(CONFIG_KASAN) && !defined(CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX)
-#define _GLOBAL_KASAN(fn) \
- _GLOBAL(fn); \
- _GLOBAL(__##fn)
-#define _GLOBAL_TOC_KASAN(fn) \
- _GLOBAL_TOC(fn); \
- _GLOBAL_TOC(__##fn)
-#define EXPORT_SYMBOL_KASAN(fn) \
- EXPORT_SYMBOL(__##fn)
-#else /* CONFIG_KASAN && !CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */
+/*
+ * powerpc requires CC_HAS_KASAN_MEMINTRINSIC_PREFIX whenever KASAN is
+ * enabled (see PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX in arch/powerpc/Kconfig),
+ * so the compiler always emits __asan_mem*() at instrumented call sites and
+ * bare mem*() inside __no_sanitize_address / noinstr code. The old dual
+ * entry-point trick (_GLOBAL_KASAN emitting both memset and __memset) is
+ * therefore never needed.
+ */
#define _GLOBAL_KASAN(fn) _GLOBAL(fn)
#define _GLOBAL_TOC_KASAN(fn) _GLOBAL_TOC(fn)
#define EXPORT_SYMBOL_KASAN(fn)
-#endif /* CONFIG_KASAN && !CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */

#ifndef __ASSEMBLER__

diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h
index 1981bd4036b5..743126e3dcc1 100644
--- a/arch/powerpc/include/asm/string.h
+++ b/arch/powerpc/include/asm/string.h
@@ -29,29 +29,14 @@ extern void * memchr(const void *,int,__kernel_size_t);
void memcpy_flushcache(void *dest, const void *src, size_t size);

#ifdef CONFIG_KASAN
-/* __mem variants are used by KASAN to implement instrumented meminstrinsics. */
-#ifdef CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
+/*
+ * powerpc requires CC_HAS_KASAN_MEMINTRINSIC_PREFIX whenever KASAN is
+ * enabled, so the compiler emits __asan_mem*() at instrumented sites.
+ * The raw mem* symbols are always safe to call directly.
+ */
#define __memset memset
#define __memcpy memcpy
#define __memmove memmove
-#else /* CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */
-void *__memset(void *s, int c, __kernel_size_t count);
-void *__memcpy(void *to, const void *from, __kernel_size_t n);
-void *__memmove(void *to, const void *from, __kernel_size_t n);
-#ifndef __SANITIZE_ADDRESS__
-/*
- * For files that are not instrumented (e.g. mm/slub.c) we
- * should use not instrumented version of mem* functions.
- */
-#define memcpy(dst, src, len) __memcpy(dst, src, len)
-#define memmove(dst, src, len) __memmove(dst, src, len)
-#define memset(s, c, n) __memset(s, c, n)
-
-#ifndef __NO_FORTIFY
-#define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */
-#endif
-#endif /* !__SANITIZE_ADDRESS__ */
-#endif /* CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */
#endif /* CONFIG_KASAN */

#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 6f6801da9dc1..44115f904c2c 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -36,8 +36,8 @@ void __init set_cur_cpu_spec(struct cpu_spec *s)

t = PTRRELOC(t);
/*
- * use memcpy() instead of *t = *s so that GCC replaces it
- * by __memcpy() when KASAN is active
+ * use memcpy() instead of *t = *s so that the compiler replaces it
+ * by __asan_memcpy() when KASAN is active
*/
memcpy(t, s, sizeof(*t));

@@ -55,7 +55,7 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset,

/*
* Copy everything, then do fixups. Use memcpy() instead of *t = *s
- * so that GCC replaces it by __memcpy() when KASAN is active
+ * so that the compiler replaces it by __asan_memcpy() when KASAN is active
*/
memcpy(t, s, sizeof(*t));

diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index eb9f556b0937..b763720c68b6 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -1365,8 +1365,8 @@ static void __init prom_check_platform_support(void)
/*
* First copy the architecture vec template
*
- * use memcpy() instead of *vec = *vec_template so that GCC replaces it
- * by __memcpy() when KASAN is active
+ * use memcpy() instead of *vec = *vec_template so that the compiler
+ * replaces it by __asan_memcpy() when KASAN is active
*/
memcpy(&ibm_architecture_vec, &ibm_architecture_vec_template,
sizeof(ibm_architecture_vec));
--
2.55.0

Venkat Rao Bagalkote

unread,
Sep 8, 2026, 4:39:21 AMSep 8
to Mukesh Kumar Chaurasiya (IBM), ma...@linux.ibm.com, m...@ellerman.id.au, npi...@gmail.com, chl...@kernel.org, ryabin...@gmail.com, gli...@google.com, andre...@gmail.com, dvy...@google.com, vincenzo...@arm.com, p...@kernel.org, pal...@dabbelt.com, a...@eecs.berkeley.edu, al...@ghiti.fr, ke...@kernel.org, amac...@linux.ibm.com, rites...@gmail.com, ro...@kernel.org, say...@linux.ibm.com, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linux...@lists.infradead.org, linux-h...@vger.kernel.org
Tested-by: Venkat Rao Bagalkote <venk...@linux.ibm.com>


Regards,

Venkat.

Christophe Leroy (CS GROUP)

unread,
Sep 8, 2026, 5:59:26 AMSep 8
to Mukesh Kumar Chaurasiya (IBM), ma...@linux.ibm.com, m...@ellerman.id.au, npi...@gmail.com, ryabin...@gmail.com, gli...@google.com, andre...@gmail.com, dvy...@google.com, vincenzo...@arm.com, p...@kernel.org, pal...@dabbelt.com, a...@eecs.berkeley.edu, al...@ghiti.fr, ke...@kernel.org, amac...@linux.ibm.com, rites...@gmail.com, ro...@kernel.org, say...@linux.ibm.com, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linux...@lists.infradead.org, linux-h...@vger.kernel.org, Venkat Rao Bagalkote
This explanation belongs to the commit message not to the source code.

> #define _GLOBAL_KASAN(fn) _GLOBAL(fn)
> #define _GLOBAL_TOC_KASAN(fn) _GLOBAL_TOC(fn)
> #define EXPORT_SYMBOL_KASAN(fn)
> -#endif /* CONFIG_KASAN && !CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */
>
> #ifndef __ASSEMBLER__
>
> diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h
> index 1981bd4036b5..743126e3dcc1 100644
> --- a/arch/powerpc/include/asm/string.h
> +++ b/arch/powerpc/include/asm/string.h
> @@ -29,29 +29,14 @@ extern void * memchr(const void *,int,__kernel_size_t);
> void memcpy_flushcache(void *dest, const void *src, size_t size);
>
> #ifdef CONFIG_KASAN
> -/* __mem variants are used by KASAN to implement instrumented meminstrinsics. */
> -#ifdef CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
> +/*
> + * powerpc requires CC_HAS_KASAN_MEMINTRINSIC_PREFIX whenever KASAN is
> + * enabled, so the compiler emits __asan_mem*() at instrumented sites.
> + * The raw mem* symbols are always safe to call directly.
> + */

This explanation belongs to the commit message not to the source code.
Does the initial problem still exist with the new __asan_memcpy()
approach ? If not the comment should be removed.


> memcpy(t, s, sizeof(*t));
>
> @@ -55,7 +55,7 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset,
>
> /*
> * Copy everything, then do fixups. Use memcpy() instead of *t = *s
> - * so that GCC replaces it by __memcpy() when KASAN is active
> + * so that the compiler replaces it by __asan_memcpy() when KASAN is active

Does the initial problem still exist with the new __asan_memcpy()
approach ? If not the comment should be removed.

> */
> memcpy(t, s, sizeof(*t));
>
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index eb9f556b0937..b763720c68b6 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -1365,8 +1365,8 @@ static void __init prom_check_platform_support(void)
> /*
> * First copy the architecture vec template
> *
> - * use memcpy() instead of *vec = *vec_template so that GCC replaces it
> - * by __memcpy() when KASAN is active
> + * use memcpy() instead of *vec = *vec_template so that the compiler
> + * replaces it by __asan_memcpy() when KASAN is active

Does the initial problem still exist with the new __asan_memcpy()
approach ? If not the comment should be removed.

> */
> memcpy(&ibm_architecture_vec, &ibm_architecture_vec_template,
> sizeof(ibm_architecture_vec));

Mukesh Kumar Chaurasiya

unread,
Sep 11, 2026, 1:40:02 PMSep 11
to Christophe Leroy (CS GROUP), ma...@linux.ibm.com, m...@ellerman.id.au, npi...@gmail.com, ryabin...@gmail.com, gli...@google.com, andre...@gmail.com, dvy...@google.com, vincenzo...@arm.com, p...@kernel.org, pal...@dabbelt.com, a...@eecs.berkeley.edu, al...@ghiti.fr, ke...@kernel.org, amac...@linux.ibm.com, rites...@gmail.com, ro...@kernel.org, say...@linux.ibm.com, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linux...@lists.infradead.org, linux-h...@vger.kernel.org, Venkat Rao Bagalkote
On Tue, Sep 08, 2026 at 11:59:14AM +0200, Christophe Leroy (CS GROUP) wrote:
>
>
[...]
> > --- a/arch/powerpc/include/asm/kasan.h
> > +++ b/arch/powerpc/include/asm/kasan.h
> > @@ -2,20 +2,17 @@
> > #ifndef __ASM_KASAN_H
> > #define __ASM_KASAN_H
> > -#if defined(CONFIG_KASAN) && !defined(CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX)
> > -#define _GLOBAL_KASAN(fn) \
> > - _GLOBAL(fn); \
> > - _GLOBAL(__##fn)
> > -#define _GLOBAL_TOC_KASAN(fn) \
> > - _GLOBAL_TOC(fn); \
> > - _GLOBAL_TOC(__##fn)
> > -#define EXPORT_SYMBOL_KASAN(fn) \
> > - EXPORT_SYMBOL(__##fn)
> > -#else /* CONFIG_KASAN && !CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */
> > +/*
> > + * powerpc requires CC_HAS_KASAN_MEMINTRINSIC_PREFIX whenever KASAN is
> > + * enabled (see PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX in arch/powerpc/Kconfig),
> > + * so the compiler always emits __asan_mem*() at instrumented call sites and
> > + * bare mem*() inside __no_sanitize_address / noinstr code. The old dual
> > + * entry-point trick (_GLOBAL_KASAN emitting both memset and __memset) is
> > + * therefore never needed.
> > + */
>
> This explanation belongs to the commit message not to the source code.
>
Hey Christophe,

Sure i'll move this and rest ahead.

[...]
> > diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
> > index 6f6801da9dc1..44115f904c2c 100644
> > --- a/arch/powerpc/kernel/cputable.c
> > +++ b/arch/powerpc/kernel/cputable.c
> > @@ -36,8 +36,8 @@ void __init set_cur_cpu_spec(struct cpu_spec *s)
> > t = PTRRELOC(t);
> > /*
> > - * use memcpy() instead of *t = *s so that GCC replaces it
> > - * by __memcpy() when KASAN is active
> > + * use memcpy() instead of *t = *s so that the compiler replaces it
> > + * by __asan_memcpy() when KASAN is active
> > */
>
> Does the initial problem still exist with the new __asan_memcpy() approach ?
> If not the comment should be removed.
>
Hey Christophe,

Thanks for pointing it out, i took a deeper look into this, here's my
understanding on it.

On PowerPC during very early boot the kernel is loaded by the
bootloader/firmware at some physical address, but the kernel was linked
expecting it to run at KERNELBASE(virtual address like
0xc000000000000000). The MMU mapping that makes that virtual address
valid hasn't been set up yet. So far for a window of early boot, code is
executing at the physical load address while all symbol addresses in the
binary refer to the virtual linked address. reloc_offset() computes the
gap between these two and PTRRELOC applies it to any pointer.

So PTRRELOC(&the_cpu_spec) gives the physical address where the struct
actually lives in memory right now, not where the linker thinks it lives.

Why *t = *s would be wrong?

In set_cur_cpu_spec:

struct cpu_spec *t = &the_cpu_spec; // linked (virtual) address
t = PTRRELOC(t); // physical address — where it actually is
memcpy(t, s, sizeof(*t)); // copy into the right place

If you wrote *t = *s instead, the compiler generates a struct assignment.
For a large struct like cpu_spec, GCC is free to implement that however
it likes — including emitting a call to memcpy(). But crucially, a
compiler-generated memcpy call resolves through the GOT/PLT or direct
symbol — which points to the linked virtual address of memcpy, not the
physical address. At this point in boot, calling through the wrong
address would jump to garbage or an unmapped page.

memcpy(t, s, sizeof(*t)) written explicitly is different: t is already
the corrected physical address, s points into the cpu_specs table which
has also been PTRRELOC'd. The explicit call goes through the normal
early-boot call mechanism which is safe.

The original comment said:

"use memcpy() instead of *t = *s so that GCC replaces it by __memcpy()
when KASAN is active"

This was added because under the old KASAN scheme
(!CC_HAS_KASAN_MEMINTRINSIC_PREFIX), KASAN overrode the memset/memcpy
linker symbols globally with C wrappers that called kasan_check_range().
If the compiler turned *t = *s into an implicit memcpy(), that would hit
the KASAN wrapper — calling kasan_check_range() at a point in early boot
where the KASAN shadow isn't mapped yet, causing a crash.

Writing memcpy(t, s, sizeof(*t)) explicitly made GCC emit __memcpy()
(the raw assembly alias exposed by _GLOBAL_KASAN) instead of the
KASAN-wrapped memcpy(), bypassing the shadow check.

That was the secondary reason. The primary reason that t is a
PTRRELOC-adjusted physical pointer and the copy must go through it
correctly was never stated.

So the KASAN comment is not required but i think we still need to state
why memcpy is required. For PTRRELOC adjustment, comment should reflect
that.

I'll update the comment and commit message and send out a new version.

Regards,
Mukesh

Mukesh Kumar Chaurasiya (IBM)

unread,
Sep 11, 2026, 2:06:49 PMSep 11
to ma...@linux.ibm.com, m...@ellerman.id.au, npi...@gmail.com, chl...@kernel.org, ryabin...@gmail.com, gli...@google.com, andre...@gmail.com, dvy...@google.com, vincenzo...@arm.com, p...@kernel.org, pal...@dabbelt.com, a...@eecs.berkeley.edu, al...@ghiti.fr, ke...@kernel.org, mkch...@gmail.com, rites...@gmail.com, amac...@linux.ibm.com, mah...@linux.ibm.com, nikh...@linux.ibm.com, ro...@kernel.org, say...@linux.ibm.com, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linux...@lists.infradead.org, linux-h...@vger.kernel.org, Venkat Rao Bagalkote
reach raw memory ops; with the compiler prefix approach those wrappers
are not used for mem* on powerpc.

- asm/string.h: remove the separate __memset/__memcpy/__memmove symbol
declarations and the memset/memcpy/memmove macro redirections for
uninstrumented files that were needed on old toolchains. Simplify the
CONFIG_KASAN block to just the three #define aliases (still used by
shadow.c as raw backends to bypass KASAN checking).

- cputable.c, prom_init.c: the original comments said "use memcpy() so
GCC emits __memcpy() under KASAN". The real reason is that these run
pre-relocation: the destination pointer is PTRRELOC-adjusted to its
current physical address, and the kernel is loaded at a different
address than it was linked at. A struct assignment (*t = *s) may cause
the compiler to emit an implicit memcpy() call that resolves through
the unrelocated virtual symbol address -- before the MMU mapping is set
up -- jumping to garbage. An explicit memcpy(t, ...) uses the already-
corrected pointer and is safe. Update the comments accordingly.
Tested-by: Venkat Rao Bagalkote <venk...@linux.ibm.com>
Signed-off-by: Mukesh Kumar Chaurasiya (IBM) <mkch...@gmail.com>
---
Changelog:

V1 -> V2:
- Comments reworded
- Commit message reworded
V1: https://lore.kernel.org/all/20260908064948.9...@gmail.com

arch/powerpc/Kconfig | 10 +++++++---
arch/powerpc/include/asm/kasan.h | 11 -----------
arch/powerpc/include/asm/string.h | 21 +--------------------
arch/powerpc/kernel/cputable.c | 14 +++++++++++---
arch/powerpc/kernel/prom_init.c | 10 ++++++----
5 files changed, 25 insertions(+), 41 deletions(-)
index a690e7da53c2..d62756b87ba4 100644
--- a/arch/powerpc/include/asm/kasan.h
+++ b/arch/powerpc/include/asm/kasan.h
@@ -2,20 +2,9 @@
#ifndef __ASM_KASAN_H
#define __ASM_KASAN_H

-#if defined(CONFIG_KASAN) && !defined(CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX)
-#define _GLOBAL_KASAN(fn) \
- _GLOBAL(fn); \
- _GLOBAL(__##fn)
-#define _GLOBAL_TOC_KASAN(fn) \
- _GLOBAL_TOC(fn); \
- _GLOBAL_TOC(__##fn)
-#define EXPORT_SYMBOL_KASAN(fn) \
- EXPORT_SYMBOL(__##fn)
-#else /* CONFIG_KASAN && !CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */
#define _GLOBAL_KASAN(fn) _GLOBAL(fn)
#define _GLOBAL_TOC_KASAN(fn) _GLOBAL_TOC(fn)
#define EXPORT_SYMBOL_KASAN(fn)
-#endif /* CONFIG_KASAN && !CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */

#ifndef __ASSEMBLER__

diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h
index 1981bd4036b5..72b5c93a2b84 100644
--- a/arch/powerpc/include/asm/string.h
+++ b/arch/powerpc/include/asm/string.h
@@ -29,29 +29,10 @@ extern void * memchr(const void *,int,__kernel_size_t);
void memcpy_flushcache(void *dest, const void *src, size_t size);

#ifdef CONFIG_KASAN
-/* __mem variants are used by KASAN to implement instrumented meminstrinsics. */
-#ifdef CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
+/* Used by mm/kasan/shadow.c as raw backends to bypass KASAN checking. */
#define __memset memset
#define __memcpy memcpy
#define __memmove memmove
-#else /* CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */
-void *__memset(void *s, int c, __kernel_size_t count);
-void *__memcpy(void *to, const void *from, __kernel_size_t n);
-void *__memmove(void *to, const void *from, __kernel_size_t n);
-#ifndef __SANITIZE_ADDRESS__
-/*
- * For files that are not instrumented (e.g. mm/slub.c) we
- * should use not instrumented version of mem* functions.
- */
-#define memcpy(dst, src, len) __memcpy(dst, src, len)
-#define memmove(dst, src, len) __memmove(dst, src, len)
-#define memset(s, c, n) __memset(s, c, n)
-
-#ifndef __NO_FORTIFY
-#define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */
-#endif
-#endif /* !__SANITIZE_ADDRESS__ */
-#endif /* CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */
#endif /* CONFIG_KASAN */

#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 6f6801da9dc1..233b5c650d1e 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -36,8 +36,12 @@ void __init set_cur_cpu_spec(struct cpu_spec *s)

t = PTRRELOC(t);
/*
- * use memcpy() instead of *t = *s so that GCC replaces it
- * by __memcpy() when KASAN is active
+ * Use memcpy() instead of *t = *s because t is a PTRRELOC-adjusted
+ * pointer and this code runs before the MMU mapping is established.
+ * A struct assignment is a compiler-generated aggregate copy whose
+ * implementation is not under our control in relocation-sensitive code;
+ * memcpy() ensures the adjusted pointer is explicitly passed to the
+ * copy routine.
*/
memcpy(t, s, sizeof(*t));

@@ -55,7 +59,11 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset,

/*
* Copy everything, then do fixups. Use memcpy() instead of *t = *s
- * so that GCC replaces it by __memcpy() when KASAN is active
+ * because t is a PTRRELOC-adjusted pointer and this code runs before
+ * the MMU mapping is established. A struct assignment is a
+ * compiler-generated aggregate copy whose implementation is not under
+ * our control in relocation-sensitive code; memcpy() ensures the
+ * adjusted pointer is explicitly passed to the copy routine.
*/
memcpy(t, s, sizeof(*t));

diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index eb9f556b0937..d6d7f1ede319 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -1363,10 +1363,12 @@ static void __init prom_check_platform_support(void)
"ibm,arch-vec-5-platform-support");

/*
- * First copy the architecture vec template
- *
- * use memcpy() instead of *vec = *vec_template so that GCC replaces it
- * by __memcpy() when KASAN is active
+ * First copy the architecture vec template. Use memcpy() instead of
+ * a struct assignment because this code runs before the MMU mapping
+ * is established. A struct assignment is a compiler-generated
+ * aggregate copy whose implementation is not under our control in
+ * relocation-sensitive code; memcpy() ensures the adjusted pointer
+ * is explicitly passed to the copy routine.

Christophe Leroy (CS GROUP)

unread,
Sep 12, 2026, 1:35:44 PMSep 12
to Mukesh Kumar Chaurasiya, ma...@linux.ibm.com, m...@ellerman.id.au, npi...@gmail.com, ryabin...@gmail.com, gli...@google.com, andre...@gmail.com, dvy...@google.com, vincenzo...@arm.com, p...@kernel.org, pal...@dabbelt.com, a...@eecs.berkeley.edu, al...@ghiti.fr, ke...@kernel.org, amac...@linux.ibm.com, rites...@gmail.com, ro...@kernel.org, say...@linux.ibm.com, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linux...@lists.infradead.org, linux-h...@vger.kernel.org, Venkat Rao Bagalkote
Hi Mukesh,
Explanation based on kernel v5.10

The problem was not linked to PTRRELOC, the t = PTRRELOC(t) followed by
*t = *s works well in term of adressing, regardless of whether
CONFIG_KASAN is enabled or not.

The problem is that with *t = *s, gcc emits a call to memcpy(). When
CONFIG_KASAN is enabled, memcpy() is instrumented. But we don't want
cputable.o instrumented as we have KASAN_SANITIZE_cputable.o := n in
Makefile.

In asm/string.h we have:

#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
/*
* For files that are not instrumented (e.g. mm/slub.c) we
* should use not instrumented version of mem* functions.
*/
#define memcpy(dst, src, len) __memcpy(dst, src, len)
#define memmove(dst, src, len) __memmove(dst, src, len)
#define memset(s, c, n) __memset(s, c, n)

Because in non-instrumented files like cputable.o we want memcpy() to be
replaced at buildtime by __memcpy() to skip KASAN instrumentation. But
this is resolved by pre-processing, and pre-processor doesn't know that
the compiler will emit a call to memcpy().

By replacing *t = *s by the memcpy(), the pre-processor replaces
memcpy() by __memcpy() when CONFIG_KASAN is enabled.

See the difference:

This is v5.10

00000000 <set_cur_cpu_spec>:
0: 94 21 ff e0 stwu r1,-32(r1)
4: 7c 69 1b 78 mr r9,r3
8: bf c1 00 18 stmw r30,24(r1)
c: 3f e0 00 00 lis r31,0
e: R_PPC_ADDR16_HA .data..read_mostly
10: 3b ff 00 00 addi r31,r31,0
12: R_PPC_ADDR16_LO .data..read_mostly
14: 7c 08 02 a6 mflr r0
18: 7d 3e 4b 78 mr r30,r9
1c: 7f e3 fb 78 mr r3,r31
20: 90 01 00 24 stw r0,36(r1)
24: 48 00 00 01 bl 24 <set_cur_cpu_spec+0x24>
24: R_PPC_REL24 add_reloc_offset
28: 7f c4 f3 78 mr r4,r30
2c: 38 a0 00 58 li r5,88
30: 48 00 00 01 bl 30 <set_cur_cpu_spec+0x30>
30: R_PPC_REL24 __memcpy
34: 38 7f 00 58 addi r3,r31,88
38: 48 00 00 01 bl 38 <set_cur_cpu_spec+0x38>
38: R_PPC_REL24 add_reloc_offset
3c: 93 e3 00 00 stw r31,0(r3)
40: 80 01 00 24 lwz r0,36(r1)
44: 83 c1 00 18 lwz r30,24(r1)
48: 83 e1 00 1c lwz r31,28(r1)
4c: 7c 08 03 a6 mtlr r0
50: 38 21 00 20 addi r1,r1,32
54: 4e 80 00 20 blr

This is v5.10 with commit adcf59187e270 reverted:

00000000 <set_cur_cpu_spec>:
0: 94 21 ff e0 stwu r1,-32(r1)
4: 7c 69 1b 78 mr r9,r3
8: bf c1 00 18 stmw r30,24(r1)
c: 3f e0 00 00 lis r31,0
e: R_PPC_ADDR16_HA .data..read_mostly
10: 3b ff 00 00 addi r31,r31,0
12: R_PPC_ADDR16_LO .data..read_mostly
14: 7c 08 02 a6 mflr r0
18: 7d 3e 4b 78 mr r30,r9
1c: 7f e3 fb 78 mr r3,r31
20: 90 01 00 24 stw r0,36(r1)
24: 48 00 00 01 bl 24 <set_cur_cpu_spec+0x24>
24: R_PPC_REL24 add_reloc_offset
28: 7f c4 f3 78 mr r4,r30
2c: 38 a0 00 58 li r5,88
30: 48 00 00 01 bl 30 <set_cur_cpu_spec+0x30>
30: R_PPC_REL24 memcpy
34: 38 7f 00 58 addi r3,r31,88
38: 48 00 00 01 bl 38 <set_cur_cpu_spec+0x38>
38: R_PPC_REL24 add_reloc_offset
3c: 93 e3 00 00 stw r31,0(r3)
40: 80 01 00 24 lwz r0,36(r1)
44: 83 c1 00 18 lwz r30,24(r1)
48: 83 e1 00 1c lwz r31,28(r1)
4c: 7c 08 03 a6 mtlr r0
50: 38 21 00 20 addi r1,r1,32
54: 4e 80 00 20 blr

So my question is ? Do we still have this issue nowadays ?

Christophe

Christophe Leroy (CS GROUP)

unread,
Sep 12, 2026, 2:53:27 PMSep 12
to Mukesh Kumar Chaurasiya, ma...@linux.ibm.com, m...@ellerman.id.au, npi...@gmail.com, ryabin...@gmail.com, gli...@google.com, andre...@gmail.com, dvy...@google.com, vincenzo...@arm.com, p...@kernel.org, pal...@dabbelt.com, a...@eecs.berkeley.edu, al...@ghiti.fr, ke...@kernel.org, amac...@linux.ibm.com, rites...@gmail.com, ro...@kernel.org, say...@linux.ibm.com, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linux...@lists.infradead.org, linux-h...@vger.kernel.org, Venkat Rao Bagalkote
I now did the same test with v7.2 without and with adcf59187e270
reverted. I both cases I get memcpy().

Christophe

Christophe Leroy (CS GROUP)

unread,
Sep 12, 2026, 2:55:44 PMSep 12
to Mukesh Kumar Chaurasiya (IBM), ma...@linux.ibm.com, m...@ellerman.id.au, npi...@gmail.com, ryabin...@gmail.com, gli...@google.com, andre...@gmail.com, dvy...@google.com, vincenzo...@arm.com, p...@kernel.org, pal...@dabbelt.com, a...@eecs.berkeley.edu, al...@ghiti.fr, ke...@kernel.org, rites...@gmail.com, amac...@linux.ibm.com, mah...@linux.ibm.com, nikh...@linux.ibm.com, ro...@kernel.org, say...@linux.ibm.com, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linux...@lists.infradead.org, linux-h...@vger.kernel.org, Venkat Rao Bagalkote
Hi Mukesh,
Nope, see my other email.
This comment is wrong, see my response to your explanation. I think the
comment should be removed completely, now it is possible to use *t = *s
without any issue again.


> */
> memcpy(t, s, sizeof(*t));
>
> @@ -55,7 +59,11 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset,
>
> /*
> * Copy everything, then do fixups. Use memcpy() instead of *t = *s
> - * so that GCC replaces it by __memcpy() when KASAN is active
> + * because t is a PTRRELOC-adjusted pointer and this code runs before
> + * the MMU mapping is established. A struct assignment is a
> + * compiler-generated aggregate copy whose implementation is not under
> + * our control in relocation-sensitive code; memcpy() ensures the
> + * adjusted pointer is explicitly passed to the copy routine.

Same

> */
> memcpy(t, s, sizeof(*t));
>
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index eb9f556b0937..d6d7f1ede319 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -1363,10 +1363,12 @@ static void __init prom_check_platform_support(void)
> "ibm,arch-vec-5-platform-support");
>
> /*
> - * First copy the architecture vec template
> - *
> - * use memcpy() instead of *vec = *vec_template so that GCC replaces it
> - * by __memcpy() when KASAN is active
> + * First copy the architecture vec template. Use memcpy() instead of
> + * a struct assignment because this code runs before the MMU mapping
> + * is established. A struct assignment is a compiler-generated
> + * aggregate copy whose implementation is not under our control in
> + * relocation-sensitive code; memcpy() ensures the adjusted pointer
> + * is explicitly passed to the copy routine.

Same.

> */
> memcpy(&ibm_architecture_vec, &ibm_architecture_vec_template,
> sizeof(ibm_architecture_vec));

Mukesh Kumar Chaurasiya

unread,
Sep 15, 2026, 2:05:08 AMSep 15
to Christophe Leroy (CS GROUP), ma...@linux.ibm.com, m...@ellerman.id.au, npi...@gmail.com, ryabin...@gmail.com, gli...@google.com, andre...@gmail.com, dvy...@google.com, vincenzo...@arm.com, p...@kernel.org, pal...@dabbelt.com, a...@eecs.berkeley.edu, al...@ghiti.fr, ke...@kernel.org, amac...@linux.ibm.com, rites...@gmail.com, ro...@kernel.org, say...@linux.ibm.com, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linux...@lists.infradead.org, linux-h...@vger.kernel.org, Venkat Rao Bagalkote
Oh I got it now. Thanks for the detailed explanation. Yeah the comment
is not required anymore.

I'll send out a V3.

Thanks and Regards,
Mukesh

Mukesh Kumar Chaurasiya

unread,
Sep 15, 2026, 5:15:47 AMSep 15
to Christophe Leroy (CS GROUP), ma...@linux.ibm.com, m...@ellerman.id.au, npi...@gmail.com, ryabin...@gmail.com, gli...@google.com, andre...@gmail.com, dvy...@google.com, vincenzo...@arm.com, p...@kernel.org, pal...@dabbelt.com, a...@eecs.berkeley.edu, al...@ghiti.fr, ke...@kernel.org, rites...@gmail.com, amac...@linux.ibm.com, mah...@linux.ibm.com, nikh...@linux.ibm.com, ro...@kernel.org, say...@linux.ibm.com, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linux...@lists.infradead.org, linux-h...@vger.kernel.org, Venkat Rao Bagalkote
> > - cputable.c, prom_init.c: the original comments said "use memcpy() so
> > GCC emits __memcpy() under KASAN". The real reason is that these run
> > pre-relocation: the destination pointer is PTRRELOC-adjusted to its
> > current physical address, and the kernel is loaded at a different
> > address than it was linked at. A struct assignment (*t = *s) may cause
> > the compiler to emit an implicit memcpy() call that resolves through
> > the unrelocated virtual symbol address -- before the MMU mapping is set
> > up -- jumping to garbage. An explicit memcpy(t, ...) uses the already-
> > corrected pointer and is safe. Update the comments accordingly.
>
> Nope, see my other email.
>
Got it. I'll remove this.
> > diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
> > index 6f6801da9dc1..233b5c650d1e 100644
> > --- a/arch/powerpc/kernel/cputable.c
> > +++ b/arch/powerpc/kernel/cputable.c
> > @@ -36,8 +36,12 @@ void __init set_cur_cpu_spec(struct cpu_spec *s)
> > t = PTRRELOC(t);
> > /*
> > - * use memcpy() instead of *t = *s so that GCC replaces it
> > - * by __memcpy() when KASAN is active
> > + * Use memcpy() instead of *t = *s because t is a PTRRELOC-adjusted
> > + * pointer and this code runs before the MMU mapping is established.
> > + * A struct assignment is a compiler-generated aggregate copy whose
> > + * implementation is not under our control in relocation-sensitive code;
> > + * memcpy() ensures the adjusted pointer is explicitly passed to the
> > + * copy routine.
>
> This comment is wrong, see my response to your explanation. I think the
> comment should be removed completely, now it is possible to use *t = *s
> without any issue again.
>
>
yeah i'll fix this.
> > */
> > memcpy(t, s, sizeof(*t));
> > @@ -55,7 +59,11 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset,
> > /*
> > * Copy everything, then do fixups. Use memcpy() instead of *t = *s
> > - * so that GCC replaces it by __memcpy() when KASAN is active
> > + * because t is a PTRRELOC-adjusted pointer and this code runs before
> > + * the MMU mapping is established. A struct assignment is a
> > + * compiler-generated aggregate copy whose implementation is not under
> > + * our control in relocation-sensitive code; memcpy() ensures the
> > + * adjusted pointer is explicitly passed to the copy routine.
>
> Same
>
Sure.
> > */
> > memcpy(t, s, sizeof(*t));
> > diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> > index eb9f556b0937..d6d7f1ede319 100644
> > --- a/arch/powerpc/kernel/prom_init.c
> > +++ b/arch/powerpc/kernel/prom_init.c
> > @@ -1363,10 +1363,12 @@ static void __init prom_check_platform_support(void)
> > "ibm,arch-vec-5-platform-support");
> > /*
> > - * First copy the architecture vec template
> > - *
> > - * use memcpy() instead of *vec = *vec_template so that GCC replaces it
> > - * by __memcpy() when KASAN is active
> > + * First copy the architecture vec template. Use memcpy() instead of
> > + * a struct assignment because this code runs before the MMU mapping
> > + * is established. A struct assignment is a compiler-generated
> > + * aggregate copy whose implementation is not under our control in
> > + * relocation-sensitive code; memcpy() ensures the adjusted pointer
> > + * is explicitly passed to the copy routine.
>
> Same.
>
Sure.
> > */
> > memcpy(&ibm_architecture_vec, &ibm_architecture_vec_template,
> > sizeof(ibm_architecture_vec));
>

Mukesh Kumar Chaurasiya (IBM)

unread,
Sep 15, 2026, 6:09:55 AMSep 15
to ma...@linux.ibm.com, m...@ellerman.id.au, npi...@gmail.com, chl...@kernel.org, ryabin...@gmail.com, gli...@google.com, andre...@gmail.com, dvy...@google.com, vincenzo...@arm.com, p...@kernel.org, pal...@dabbelt.com, a...@eecs.berkeley.edu, al...@ghiti.fr, ke...@kernel.org, mkch...@gmail.com, amac...@linux.ibm.com, rites...@gmail.com, nikh...@linux.ibm.com, mah...@linux.ibm.com, ro...@kernel.org, say...@linux.ibm.com, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linux...@lists.infradead.org, linux-h...@vger.kernel.org, Venkat Rao Bagalkote
- cputable.c, prom_init.c: the memcpy is not required now as the manual
instrumentation of memcpy is removed. Hence directly use *dest = *src
for this.

Reported-by: Venkat Rao Bagalkote <venk...@linux.ibm.com>
Closes: https://lore.kernel.org/all/96dae110-f79b-4e54...@linux.ibm.com
Tested-by: Venkat Rao Bagalkote <venk...@linux.ibm.com>
Signed-off-by: Mukesh Kumar Chaurasiya (IBM) <mkch...@gmail.com>
---
Changelog:
V2 -> V3:
- *dest = *src used instead of memcpy in cputable.c and prom_init.c
V2: https://lore.kernel.org/all/20260911180536.32...@gmail.com

V1 -> V2:
- Comments reworded
- Commit message reworded
V1: https://lore.kernel.org/all/20260908064948.9...@gmail.com

arch/powerpc/Kconfig | 10 +++++++---
arch/powerpc/include/asm/kasan.h | 11 -----------
arch/powerpc/include/asm/string.h | 21 +--------------------
arch/powerpc/kernel/cputable.c | 14 ++------------
arch/powerpc/kernel/prom_init.c | 10 ++--------
5 files changed, 12 insertions(+), 54 deletions(-)
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 6f6801da9dc1..6356b5c6be7b 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -35,12 +35,7 @@ void __init set_cur_cpu_spec(struct cpu_spec *s)
struct cpu_spec *t = &the_cpu_spec;

t = PTRRELOC(t);
- /*
- * use memcpy() instead of *t = *s so that GCC replaces it
- * by __memcpy() when KASAN is active
- */
- memcpy(t, s, sizeof(*t));
-
+ *t = *s;
*PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
}

@@ -52,12 +47,7 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset,

t = PTRRELOC(t);
old = *t;
-
- /*
- * Copy everything, then do fixups. Use memcpy() instead of *t = *s
- * so that GCC replaces it by __memcpy() when KASAN is active
- */
- memcpy(t, s, sizeof(*t));
+ *t = *s;

/*
* If we are overriding a previous value derived from the real
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index eb9f556b0937..e8e071024da5 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -1362,14 +1362,8 @@ static void __init prom_check_platform_support(void)
int prop_len = prom_getproplen(prom.chosen,
"ibm,arch-vec-5-platform-support");

- /*
- * First copy the architecture vec template
- *
- * use memcpy() instead of *vec = *vec_template so that GCC replaces it
- * by __memcpy() when KASAN is active
- */
- memcpy(&ibm_architecture_vec, &ibm_architecture_vec_template,
- sizeof(ibm_architecture_vec));
+ /* First copy the architecture vec template */
+ ibm_architecture_vec = ibm_architecture_vec_template;

prom_strscpy_pad(ibm_architecture_vec.vec7.os_id, linux_banner, 256);

--
2.55.0

Christophe Leroy (CS GROUP)

unread,
Sep 16, 2026, 7:09:52 AMSep 16
to Mukesh Kumar Chaurasiya (IBM), ma...@linux.ibm.com, m...@ellerman.id.au, npi...@gmail.com, ryabin...@gmail.com, gli...@google.com, andre...@gmail.com, dvy...@google.com, vincenzo...@arm.com, p...@kernel.org, pal...@dabbelt.com, a...@eecs.berkeley.edu, al...@ghiti.fr, ke...@kernel.org, amac...@linux.ibm.com, rites...@gmail.com, nikh...@linux.ibm.com, mah...@linux.ibm.com, ro...@kernel.org, say...@linux.ibm.com, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linux...@lists.infradead.org, linux-h...@vger.kernel.org, Venkat Rao Bagalkote
Reviewed-by: Christophe Leroy (CS GROUP) <chl...@kernel.org>

> ---
> Changelog:
> V2 -> V3:
> - *dest = *src used instead of memcpy in cputable.c and prom_init.c

We could have left the memcpy() there but I'm fine either way. What was
important was to remove the comment as it was valid only for the
non-CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX case.

If for some reason you have to send a new version, it would be good to
mention it is a revert of commit adcf59187e27 ("powerpc: don't use
direct assignation during early boot.") as it is not necessary anymore
with CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX

Christophe

Mukesh Kumar Chaurasiya

unread,
Sep 16, 2026, 9:52:43 AMSep 16
to Christophe Leroy (CS GROUP), ma...@linux.ibm.com, m...@ellerman.id.au, npi...@gmail.com, ryabin...@gmail.com, gli...@google.com, andre...@gmail.com, dvy...@google.com, vincenzo...@arm.com, p...@kernel.org, pal...@dabbelt.com, a...@eecs.berkeley.edu, al...@ghiti.fr, ke...@kernel.org, amac...@linux.ibm.com, rites...@gmail.com, nikh...@linux.ibm.com, mah...@linux.ibm.com, ro...@kernel.org, say...@linux.ibm.com, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linux...@lists.infradead.org, linux-h...@vger.kernel.org, Venkat Rao Bagalkote
On Wed, Sep 16, 2026 at 01:09:41PM +0200, Christophe Leroy (CS GROUP) wrote:
I thought this would make the code look simpler.
> If for some reason you have to send a new version, it would be good to
> mention it is a revert of commit adcf59187e27 ("powerpc: don't use direct
> assignation during early boot.") as it is not necessary anymore with
> CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
>
I can send out a new version, it's just a commit message change.
> Christophe
>
Thanks for all the effort in review and explanation.

Regards,
Mukesh

Andrey Ryabinin

unread,
Sep 16, 2026, 12:17:38 PMSep 16
to Mukesh Kumar Chaurasiya (IBM), ma...@linux.ibm.com, m...@ellerman.id.au, npi...@gmail.com, chl...@kernel.org, gli...@google.com, andre...@gmail.com, dvy...@google.com, vincenzo...@arm.com, p...@kernel.org, pal...@dabbelt.com, a...@eecs.berkeley.edu, al...@ghiti.fr, ke...@kernel.org, amac...@linux.ibm.com, rites...@gmail.com, nikh...@linux.ibm.com, mah...@linux.ibm.com, ro...@kernel.org, say...@linux.ibm.com, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linux...@lists.infradead.org, linux-h...@vger.kernel.org, Venkat Rao Bagalkote
"Mukesh Kumar Chaurasiya (IBM)" <mkch...@gmail.com> writes:

Hi,
I fed this patch to an AI for review, and the review results are included below.
Please take a look. From my side, I agree with all of the points
raised by AI in the
review, and I think they all need to be addressed. There is also a diff with
the suggested changes at the very end of this mail.


> powerpc unconditionally selects GENERIC_ENTRY. The GENERIC_ENTRY
> infrastructure relies on the compiler emitting __asan_mem*() calls at
> instrumented mem*() sites rather than plain memset/memcpy/memmove, so
> that entry/exit paths calling those functions are not instrumented.
>
> [ ... ]
>
> When GENERIC_ENTRY is set, both guards suppress the C wrappers for
> memset/memcpy/memmove and the __underlying_mem*() redirections. This
> is only safe when the compiler supports the prefixed __asan_mem*()
> intrinsics. On older toolchains (e.g. GCC 9) that lack this support,
> plain mem*() calls from instrumented code fall through to the raw
> assembly implementations in mem_64.S / copy_32.S, completely bypassing
> the KASAN shadow check.
>
> Other arches with GENERIC_ENTRY (x86, s390, loongarch, riscv) do not
> hit this because their CI toolchains are always new enough to support
> the prefix flag.
>
> [ ... ]
>
> Reported-by: Venkat Rao Bagalkote <venk...@linux.ibm.com>
> Closes: https://lore.kernel.org/all/96dae110-f79b-4e54...@linux.ibm.com
> Tested-by: Venkat Rao Bagalkote <venk...@linux.ibm.com>
> Signed-off-by: Mukesh Kumar Chaurasiya (IBM) <mkch...@gmail.com>

The thread in the Closes: link is about an early boot hang, but the
commit message only describes mem*() calls bypassing the shadow check.
Bypassed checks would lose coverage, not hang the machine. Is the
mechanism of the hang understood?

Looking at the state before this commit, the !CC_HAS_KASAN_MEMINTRINSIC_PREFIX
macros that bee25f97ad24 ("powerpc: Enable GENERIC_ENTRY feature") added to
asm/kasan.h emit two ELFv2 global entry points back to back:

#define _GLOBAL_TOC_KASAN(fn)
_GLOBAL_TOC(fn);
_GLOBAL_TOC(__##fn)

With the _GLOBAL_TOC() definition from asm/ppc_asm.h that expands, for
memcpy_64.S, to:

memcpy:
0: addis r2,r12,(.TOC.-0b)@ha
addi r2,r2,(.TOC.-0b)@l
.localentry memcpy,.-memcpy <- local entry is memcpy+8
__memcpy:
0: addis r2,r12,(.TOC.-0b)@ha <- this is memcpy+8
addi r2,r2,(.TOC.-0b)@l
.localentry __memcpy,.-__memcpy

Assembling exactly that for powerpc64le gives memcpy st_other 0x60
(local entry offset 8), and memcpy+8 is the __memcpy TOC prologue.

Every same-TOC caller of memcpy() or memmove() is resolved by the
linker to the local entry, so it lands on that second prologue with r12
holding whatever the caller left there, and returns with r2 pointing
at garbage. Same-TOC callers do not reload r2 after the call. With
GENERIC_ENTRY, mm/kasan/shadow.c no longer provides memcpy(), so on a
toolchain without the prefix parameter every instrumented file calls
the memcpy symbol directly and hits this. That matches an early hang
that only shows up with GCC 9.

This commit makes the hang go away because the dual-entry macro is
deleted, but the commit message attributes the fix to something else.
Could the message describe the r2 corruption, and since this repairs a
regression from the GENERIC_ENTRY conversion, should it carry:

Fixes: bee25f97ad24 ("powerpc: Enable GENERIC_ENTRY feature")

On the claim that other GENERIC_ENTRY architectures "do not hit this
because their CI toolchains are always new enough": x86, s390, riscv
and loongarch with GCC 8 to 12 build exactly the same configuration,
CONFIG_KASAN=y without CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX, and
run with mem*() unchecked. scripts/Makefile.kasan documents that as
the intended behaviour:

# Instrument memcpy/memset/memmove calls by using instrumented __asan_mem*()
# instead. With compilers that don't support this option, compiler-inserted
# memintrinsics won't be checked by KASAN on GENERIC_ENTRY architectures.

and mm/kasan/kasan_test_c.c skips the affected tests with "Test
requires checked mem*()". So the situation the message describes is
the accepted upstream state for old toolchains, not something specific
to powerpc.

> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 2580e27e4328..b27ed9739eea 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -7,6 +7,10 @@ config CC_HAS_ELFV2
> config CC_HAS_PREFIXED
> def_bool PPC64 && $(cc-option, -mcpu=power10 -mprefixed)
>
> +config PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
> + def_bool (CC_IS_CLANG && $(cc-option,-fsanitize=kernel-address -mllvm -asan-kernel-mem-intrinsic-prefix=1)) || \
> + (CC_IS_GCC && $(cc-option,-fsanitize=kernel-address --param asan-kernel-mem-intrinsic-prefix=1))
> +
> config CC_HAS_PCREL
> # Clang has a bug (https://github.com/llvm/llvm-project/issues/62372)
> # where pcrel code is not generated if -msoft-float, -mno-altivec, or

[ ... ]

> @@ -220,9 +224,9 @@ config PPC
> select HAVE_ARCH_HUGE_VMAP if PPC_RADIX_MMU || PPC_8xx
> select HAVE_ARCH_JUMP_LABEL
> select HAVE_ARCH_JUMP_LABEL_RELATIVE
> - select HAVE_ARCH_KASAN if PPC32 && PAGE_SHIFT <= 14
> - select HAVE_ARCH_KASAN if PPC_RADIX_MMU
> - select HAVE_ARCH_KASAN if PPC_BOOK3E_64
> + select HAVE_ARCH_KASAN if PPC32 && PAGE_SHIFT <= 14 && PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
> + select HAVE_ARCH_KASAN if PPC_RADIX_MMU && PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
> + select HAVE_ARCH_KASAN if PPC_BOOK3E_64 && PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
> select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN
> select HAVE_ARCH_KCSAN
> select HAVE_ARCH_KFENCE if ARCH_SUPPORTS_DEBUG_PAGEALLOC

This drops KASAN from powerpc entirely for GCC 8 through 12, which are
inside the supported range in Documentation/process/changes.rst (GNU C
8.1 minimum). An existing .config with CONFIG_KASAN=y silently loses
it on olddefconfig once HAVE_ARCH_KASAN is no longer selected.

Given that the actual breakage is the broken memcpy/memmove entry
points, is it necessary to go this far? Keeping one _GLOBAL_TOC()
prologue for __memcpy and making memcpy a plain alias of it (a second
label plus a matching .localentry, or a global entry that branches to
__memcpy) would restore the pre-GENERIC_ENTRY behaviour, with mem*()
unchecked on old compilers exactly like the other GENERIC_ENTRY
architectures. That also keeps a Fixes-tagged backport candidate from
removing a feature on stable kernels.


> diff --git a/arch/powerpc/include/asm/kasan.h b/arch/powerpc/include/asm/kasan.h
> index a690e7da53c2..d62756b87ba4 100644
> --- a/arch/powerpc/include/asm/kasan.h
> +++ b/arch/powerpc/include/asm/kasan.h
> @@ -2,20 +2,9 @@
> #ifndef __ASM_KASAN_H
> #define __ASM_KASAN_H
>
> -#if defined(CONFIG_KASAN) && !defined(CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX)
> -#define _GLOBAL_KASAN(fn) \
> - _GLOBAL(fn); \
> - _GLOBAL(__##fn)
> -#define _GLOBAL_TOC_KASAN(fn) \
> - _GLOBAL_TOC(fn); \
> - _GLOBAL_TOC(__##fn)
> -#define EXPORT_SYMBOL_KASAN(fn) \
> - EXPORT_SYMBOL(__##fn)
> -#else /* CONFIG_KASAN && !CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */
> #define _GLOBAL_KASAN(fn) _GLOBAL(fn)
> #define _GLOBAL_TOC_KASAN(fn) _GLOBAL_TOC(fn)
> #define EXPORT_SYMBOL_KASAN(fn)
> -#endif /* CONFIG_KASAN && !CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */
>
> #ifndef __ASSEMBLER__
>

this isn't a bug, but after this change _GLOBAL_KASAN(), _GLOBAL_TOC_KASAN()
and EXPORT_SYMBOL_KASAN() are unconditional identity macros with a single
empty one. Should the five users in mem_64.S, memcpy_64.S and copy_32.S
switch to _GLOBAL()/_GLOBAL_TOC() and the macros go away?

Related leftover: arch/powerpc/kernel/prom_init_check.sh still has

has_renamed_memintrinsics()
{
grep -q "^CONFIG_KASAN=y$" "${KCONFIG_CONFIG}" && \
! grep -q
"^CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX=y" "${KCONFIG_CONFIG}"
}

if has_renamed_memintrinsics
then
MEM_FUNCS="__memcpy __memset"

which can no longer be true on powerpc after this commit. Should that
branch be removed in the same cleanup?

> diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h
> index 1981bd4036b5..72b5c93a2b84 100644
> --- a/arch/powerpc/include/asm/string.h
> +++ b/arch/powerpc/include/asm/string.h
> @@ -29,29 +29,10 @@ extern void * memchr(const void *,int,__kernel_size_t);
> void memcpy_flushcache(void *dest, const void *src, size_t size);
>
> #ifdef CONFIG_KASAN
> -/* __mem variants are used by KASAN to implement instrumented meminstrinsics. */
> -#ifdef CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
> +/* Used by mm/kasan/shadow.c as raw backends to bypass KASAN checking. */
> #define __memset memset

this isn't a bug, but the new comment names only mm/kasan/shadow.c.
The same __memset()/__memcpy() names are used by mm/kasan/generic.c as
well (DEFINE_ASAN_SET_SHADOW() and release_alloc_meta()), so would
"used by mm/kasan as raw backends" be more accurate?


---
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b27ed9739eea..2580e27e4328 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -7,10 +7,6 @@ config CC_HAS_ELFV2
config CC_HAS_PREFIXED
def_bool PPC64 && $(cc-option, -mcpu=power10 -mprefixed)

-config PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
- def_bool (CC_IS_CLANG && $(cc-option,-fsanitize=kernel-address
-mllvm -asan-kernel-mem-intrinsic-prefix=1)) || \
- (CC_IS_GCC && $(cc-option,-fsanitize=kernel-address --param
asan-kernel-mem-intrinsic-prefix=1))
-
config CC_HAS_PCREL
# Clang has a bug (https://github.com/llvm/llvm-project/issues/62372)
# where pcrel code is not generated if -msoft-float, -mno-altivec, or
@@ -224,9 +220,9 @@ config PPC
select HAVE_ARCH_HUGE_VMAP if PPC_RADIX_MMU || PPC_8xx
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE
- select HAVE_ARCH_KASAN if PPC32 && PAGE_SHIFT <= 14 &&
PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
- select HAVE_ARCH_KASAN if PPC_RADIX_MMU &&
PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
- select HAVE_ARCH_KASAN if PPC_BOOK3E_64 &&
PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
+ select HAVE_ARCH_KASAN if PPC32 && PAGE_SHIFT <= 14
+ select HAVE_ARCH_KASAN if PPC_RADIX_MMU
+ select HAVE_ARCH_KASAN if PPC_BOOK3E_64
select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN
select HAVE_ARCH_KCSAN
select HAVE_ARCH_KFENCE if ARCH_SUPPORTS_DEBUG_PAGEALLOC
diff --git a/arch/powerpc/include/asm/kasan.h b/arch/powerpc/include/asm/kasan.h
index d62756b87ba4..599a9e02af02 100644
--- a/arch/powerpc/include/asm/kasan.h
+++ b/arch/powerpc/include/asm/kasan.h
@@ -2,10 +2,6 @@
#ifndef __ASM_KASAN_H
#define __ASM_KASAN_H

-#define _GLOBAL_KASAN(fn) _GLOBAL(fn)
-#define _GLOBAL_TOC_KASAN(fn) _GLOBAL_TOC(fn)
-#define EXPORT_SYMBOL_KASAN(fn)
-
#ifndef __ASSEMBLER__

#include <asm/page.h>
diff --git a/arch/powerpc/kernel/prom_init_check.sh
b/arch/powerpc/kernel/prom_init_check.sh
index 3090b97258ae..3155cc722e48 100644
--- a/arch/powerpc/kernel/prom_init_check.sh
+++ b/arch/powerpc/kernel/prom_init_check.sh
@@ -13,21 +13,8 @@
# If you really need to reference something from prom_init.o add
# it to the list below:

-has_renamed_memintrinsics()
-{
- grep -q "^CONFIG_KASAN=y$" "${KCONFIG_CONFIG}" && \
- ! grep -q "^CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX=y" "${KCONFIG_CONFIG}"
-}
-
-if has_renamed_memintrinsics
-then
- MEM_FUNCS="__memcpy __memset"
-else
- MEM_FUNCS="memcpy memset"
-fi
-
WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush
-_end enter_prom $MEM_FUNCS reloc_offset __secondary_hold
+_end enter_prom memcpy memset reloc_offset __secondary_hold
__secondary_hold_acknowledge __secondary_hold_spinloop __start
logo_linux_clut224 btext_prepare_BAT
reloc_got2 kernstart_addr memstart_addr linux_banner _stext
diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S
index 933b685e7ab6..97eb9ca0cc23 100644
--- a/arch/powerpc/lib/copy_32.S
+++ b/arch/powerpc/lib/copy_32.S
@@ -10,7 +10,6 @@
#include <asm/errno.h>
#include <asm/ppc_asm.h>
#include <asm/code-patching-asm.h>
-#include <asm/kasan.h>

#define COPY_16_BYTES \
lwz r7,4(r4); \
@@ -87,7 +86,7 @@ EXPORT_SYMBOL(memset16)
* We therefore skip the optimised bloc that uses dcbz. This jump is
* replaced by a nop once cache is active. This is done in machine_init()
*/
-_GLOBAL_KASAN(memset)
+_GLOBAL(memset)
cmplwi 0,r5,4
blt 7f

@@ -147,7 +146,6 @@ _GLOBAL_KASAN(memset)
bdnz 9b
blr
EXPORT_SYMBOL(memset)
-EXPORT_SYMBOL_KASAN(memset)

/*
* This version uses dcbz on the complete cache lines in the
@@ -160,12 +158,12 @@ EXPORT_SYMBOL_KASAN(memset)
* We therefore jump to generic_memcpy which doesn't use dcbz. This jump is
* replaced by a nop once cache is active. This is done in machine_init()
*/
-_GLOBAL_KASAN(memmove)
+_GLOBAL(memmove)
cmplw 0,r3,r4
bgt backwards_memcpy
/* fall through */

-_GLOBAL_KASAN(memcpy)
+_GLOBAL(memcpy)
1: b generic_memcpy
patch_site 1b, patch__memcpy_nocache

@@ -241,8 +239,6 @@ _GLOBAL_KASAN(memcpy)
65: blr
EXPORT_SYMBOL(memcpy)
EXPORT_SYMBOL(memmove)
-EXPORT_SYMBOL_KASAN(memcpy)
-EXPORT_SYMBOL_KASAN(memmove)

generic_memcpy:
srwi. r7,r5,3
diff --git a/arch/powerpc/lib/mem_64.S b/arch/powerpc/lib/mem_64.S
index 6fd06cd20faa..40eaedd31486 100644
--- a/arch/powerpc/lib/mem_64.S
+++ b/arch/powerpc/lib/mem_64.S
@@ -8,7 +8,6 @@
#include <asm/processor.h>
#include <asm/errno.h>
#include <asm/ppc_asm.h>
-#include <asm/kasan.h>

#ifndef CONFIG_KASAN
_GLOBAL(__memset16)
@@ -29,7 +28,7 @@ EXPORT_SYMBOL(__memset32)
EXPORT_SYMBOL(__memset64)
#endif

-_GLOBAL_KASAN(memset)
+_GLOBAL(memset)
neg r0,r3
rlwimi r4,r4,8,16,23
andi. r0,r0,7 /* # bytes to be 8-byte aligned */
@@ -95,9 +94,8 @@ _GLOBAL_KASAN(memset)
stb r4,0(r6)
blr
EXPORT_SYMBOL(memset)
-EXPORT_SYMBOL_KASAN(memset)

-_GLOBAL_TOC_KASAN(memmove)
+_GLOBAL_TOC(memmove)
cmplw 0,r3,r4
bgt backwards_memcpy
b memcpy
@@ -139,4 +137,3 @@ _GLOBAL(backwards_memcpy)
mtctr r7
b 1b
EXPORT_SYMBOL(memmove)
-EXPORT_SYMBOL_KASAN(memmove)
diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S
index b5a67e20143f..0cedd455231a 100644
--- a/arch/powerpc/lib/memcpy_64.S
+++ b/arch/powerpc/lib/memcpy_64.S
@@ -7,7 +7,6 @@
#include <asm/ppc_asm.h>
#include <asm/asm-compat.h>
#include <asm/feature-fixups.h>
-#include <asm/kasan.h>

#ifndef SELFTEST_CASE
/* For big-endian, 0 == most CPUs, 1 == POWER6, 2 == Cell */
@@ -15,7 +14,7 @@
#endif

.align 7
-_GLOBAL_TOC_KASAN(memcpy)
+_GLOBAL_TOC(memcpy)
BEGIN_FTR_SECTION
#ifdef __LITTLE_ENDIAN__
cmpdi cr7,r5,0
@@ -227,4 +226,3 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
blr
#endif
EXPORT_SYMBOL(memcpy)
-EXPORT_SYMBOL_KASAN(memcpy)

Mukesh Kumar Chaurasiya

unread,
Sep 18, 2026, 1:41:08 AMSep 18
to Andrey Ryabinin, ma...@linux.ibm.com, m...@ellerman.id.au, npi...@gmail.com, chl...@kernel.org, gli...@google.com, andre...@gmail.com, dvy...@google.com, vincenzo...@arm.com, p...@kernel.org, pal...@dabbelt.com, a...@eecs.berkeley.edu, al...@ghiti.fr, ke...@kernel.org, amac...@linux.ibm.com, rites...@gmail.com, nikh...@linux.ibm.com, mah...@linux.ibm.com, ro...@kernel.org, say...@linux.ibm.com, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linux...@lists.infradead.org, linux-h...@vger.kernel.org, Venkat Rao Bagalkote
On Wed, Sep 16, 2026 at 11:17:36AM -0500, Andrey Ryabinin wrote:
> "Mukesh Kumar Chaurasiya (IBM)" <mkch...@gmail.com> writes:
>
> Hi,
> I fed this patch to an AI for review, and the review results are included below.
> Please take a look. From my side, I agree with all of the points
> raised by AI in the
> review, and I think they all need to be addressed. There is also a diff with
> the suggested changes at the very end of this mail.
>
>
Hey Andrey,

Thanks for the effort.
Yeah the commit message needs to clearly specify the corruption of r2,
and the Fixes tag should be there.
Ok, yeah this is too aggressive. I will rectify this in next revision.
Yes it should be. It's a dead code now.
Yeah this seems like it could work. Letme try this.


Thanks,
Mukesh
Reply all
Reply to author
Forward
0 new messages