Kernel v6.17-rc4 with STATIC_CALL_SELFTEST=y enabled fails to boot at early stage (PowerMac G4 DP)

15 messages, 5 authors, 2025-09-05 · open the first message on its own page

Kernel v6.17-rc4 with STATIC_CALL_SELFTEST=y enabled fails to boot at early stage (PowerMac G4 DP)

From: Erhard Furtner <hidden>
Date: 2025-09-03 22:50:17

Greetings!

In a conversation with Andrew about his page table check code for 
PowerPC he found out there seems to be a general problem of the code 
patching code on ppc:

 > I note that STATIC_CALL_SELFTEST seems to fail, which could be but isn't
 > necessarily related.

 > Specifically, it looks like code patching fails if the instruction 
being patched
 > is in an __init function, and in this case, that occurs due to
 > page_table_check_pte_clear() being inlined into ptep_clear(), which 
is in turn
 > inlined into pte_clear_tests() in debug_vm_pgtable.c which is marked 
__init.
 > Very curious!

Indeed, when I enable STATIC_CALL_SELFTEST=y on my G4 the kernel fails 
to boot at an early stage, the OpenFirmware console showing only:

done
found display   : /pci@f0000000/ATY,AlteracParent@10/ATY,Alterac_B@1, 
opening...

Without STATIC_CALL_SELFTEST the kernel boots just fine.

Kernel .config attached.

Regards,
Erhard

Re: Kernel v6.17-rc4 with STATIC_CALL_SELFTEST=y enabled fails to boot at early stage (PowerMac G4 DP)

From: Christophe Leroy <hidden>
Date: 2025-09-04 07:50:38

Hi Erhard,

Le 04/09/2025 à 00:44, Erhard Furtner a écrit :
Greetings!

In a conversation with Andrew about his page table check code for 
PowerPC he found out there seems to be a general problem of the code 
patching code on ppc:

 > I note that STATIC_CALL_SELFTEST seems to fail, which could be but isn't
 > necessarily related.

 > Specifically, it looks like code patching fails if the instruction 
being patched
 > is in an __init function, and in this case, that occurs due to
 > page_table_check_pte_clear() being inlined into ptep_clear(), which 
is in turn
 > inlined into pte_clear_tests() in debug_vm_pgtable.c which is marked 
__init.
 > Very curious!

Indeed, when I enable STATIC_CALL_SELFTEST=y on my G4 the kernel fails 
to boot at an early stage, the OpenFirmware console showing only:

done
found display   : /pci@f0000000/ATY,AlteracParent@10/ATY,Alterac_B@1, 
opening...

Without STATIC_CALL_SELFTEST the kernel boots just fine.

Kernel .config attached.
With your .config, on QEMU I get the following. I will investigate.

[    0.000000] Kernel panic - not syncing: arch_static_call_transform: 
patching failed func_a+0x0/0x10 at 0x0
[    0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 
6.17.0-rc4-PMacG4+ #1628 PREEMPTLAZY
[    0.000000] Hardware name: PowerMac3,1 7400 0xc0209 PowerMac
[    0.000000] Call Trace:
[    0.000000] [c0dd7e60] [c0810e54] dump_stack_lvl+0x70/0x8c (unreliable)
[    0.000000] [c0dd7e80] [c004b220] vpanic+0x114/0x2e4
[    0.000000] [c0dd7eb0] [c004b45c] arch_set_bit+0x0/0x38
[    0.000000] [c0dd7f00] [c00155fc] arch_static_call_transform+0xec/0x1e8
[    0.000000] [c0dd7f30] [c0176944] __static_call_init+0x110/0x288
[    0.000000] [c0dd7f80] [c0c19ab0] static_call_init+0x4c/0x9c
[    0.000000] [c0dd7fa0] [c0c02e00] start_kernel+0x7c/0x664
[    0.000000] [c0dd7ff0] [000035d0] 0x35d0
[    0.000000] Rebooting in 40 seconds..

Christophe

Re: Kernel v6.17-rc4 with STATIC_CALL_SELFTEST=y enabled fails to boot at early stage (PowerMac G4 DP)

From: Madhavan Srinivasan <maddy@linux.ibm.com>
Date: 2025-09-04 08:41:11


On 9/4/25 1:01 PM, Christophe Leroy wrote:
Hi Erhard,

Le 04/09/2025 à 00:44, Erhard Furtner a écrit :
quoted
Greetings!

In a conversation with Andrew about his page table check code for PowerPC he found out there seems to be a general problem of the code patching code on ppc:

 > I note that STATIC_CALL_SELFTEST seems to fail, which could be but isn't
 > necessarily related.

 > Specifically, it looks like code patching fails if the instruction being patched
 > is in an __init function, and in this case, that occurs due to
 > page_table_check_pte_clear() being inlined into ptep_clear(), which is in turn
 > inlined into pte_clear_tests() in debug_vm_pgtable.c which is marked __init.
 > Very curious!

Indeed, when I enable STATIC_CALL_SELFTEST=y on my G4 the kernel fails to boot at an early stage, the OpenFirmware console showing only:

done
found display   : /pci@f0000000/ATY,AlteracParent@10/ATY,Alterac_B@1, opening...

Without STATIC_CALL_SELFTEST the kernel boots just fine.

Kernel .config attached.
With your .config, on QEMU I get the following. I will investigate.

[    0.000000] Kernel panic - not syncing: arch_static_call_transform: patching failed func_a+0x0/0x10 at 0x0
[    0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.17.0-rc4-PMacG4+ #1628 PREEMPTLAZY
[    0.000000] Hardware name: PowerMac3,1 7400 0xc0209 PowerMac
[    0.000000] Call Trace:
I am using qemu with -M mac99 and it boots 

Hardware name: PowerMac3,1 7400 0xc0209 PowerMac
printk: legacy bootconsole [udbg0] enabled
-----------------------------------------------------
phys_mem_size     = 0x8000000
dcache_bsize      = 0x20

I am missing something here. Digging some more

Maddy

[    0.000000] [c0dd7e60] [c0810e54] dump_stack_lvl+0x70/0x8c (unreliable)
[    0.000000] [c0dd7e80] [c004b220] vpanic+0x114/0x2e4
[    0.000000] [c0dd7eb0] [c004b45c] arch_set_bit+0x0/0x38
[    0.000000] [c0dd7f00] [c00155fc] arch_static_call_transform+0xec/0x1e8
[    0.000000] [c0dd7f30] [c0176944] __static_call_init+0x110/0x288
[    0.000000] [c0dd7f80] [c0c19ab0] static_call_init+0x4c/0x9c
[    0.000000] [c0dd7fa0] [c0c02e00] start_kernel+0x7c/0x664
[    0.000000] [c0dd7ff0] [000035d0] 0x35d0
[    0.000000] Rebooting in 40 seconds..

Christophe

Re: Kernel v6.17-rc4 with STATIC_CALL_SELFTEST=y enabled fails to boot at early stage (PowerMac G4 DP)

From: Madhavan Srinivasan <maddy@linux.ibm.com>
Date: 2025-09-04 09:03:57


On 9/4/25 2:15 PM, Christophe Leroy wrote:

Le 04/09/2025 à 10:40, Madhavan Srinivasan a écrit :
quoted

On 9/4/25 1:01 PM, Christophe Leroy wrote:
quoted
Hi Erhard,

Le 04/09/2025 à 00:44, Erhard Furtner a écrit :
quoted
Greetings!

In a conversation with Andrew about his page table check code for PowerPC he found out there seems to be a general problem of the code patching code on ppc:

  > I note that STATIC_CALL_SELFTEST seems to fail, which could be but isn't
  > necessarily related.

  > Specifically, it looks like code patching fails if the instruction being patched
  > is in an __init function, and in this case, that occurs due to
  > page_table_check_pte_clear() being inlined into ptep_clear(), which is in turn
  > inlined into pte_clear_tests() in debug_vm_pgtable.c which is marked __init.
  > Very curious!

Indeed, when I enable STATIC_CALL_SELFTEST=y on my G4 the kernel fails to boot at an early stage, the OpenFirmware console showing only:

done
found display   : /pci@f0000000/ATY,AlteracParent@10/ATY,Alterac_B@1, opening...

Without STATIC_CALL_SELFTEST the kernel boots just fine.

Kernel .config attached.
With your .config, on QEMU I get the following. I will investigate.

[    0.000000] Kernel panic - not syncing: arch_static_call_transform: patching failed func_a+0x0/0x10 at 0x0
[    0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.17.0-rc4-PMacG4+ #1628 PREEMPTLAZY
[    0.000000] Hardware name: PowerMac3,1 7400 0xc0209 PowerMac
[    0.000000] Call Trace:
I am using qemu with -M mac99 and it boots

Hardware name: PowerMac3,1 7400 0xc0209 PowerMac
printk: legacy bootconsole [udbg0] enabled
-----------------------------------------------------
phys_mem_size     = 0x8000000
dcache_bsize      = 0x20

I am missing something here. Digging some more

Did you use the .config provided by Erhard ?
Oops. sorry for the noise

Maddy
Christophe

Re: Kernel v6.17-rc4 with STATIC_CALL_SELFTEST=y enabled fails to boot at early stage (PowerMac G4 DP)

From: Christophe Leroy <hidden>
Date: 2025-09-04 09:50:43

Hi Again,

Le 04/09/2025 à 09:31, Christophe Leroy a écrit :
Hi Erhard,

Le 04/09/2025 à 00:44, Erhard Furtner a écrit :
quoted
Greetings!

In a conversation with Andrew about his page table check code for 
PowerPC he found out there seems to be a general problem of the code 
patching code on ppc:

 > I note that STATIC_CALL_SELFTEST seems to fail, which could be but 
isn't
 > necessarily related.

 > Specifically, it looks like code patching fails if the instruction 
being patched
 > is in an __init function, and in this case, that occurs due to
 > page_table_check_pte_clear() being inlined into ptep_clear(), which 
is in turn
 > inlined into pte_clear_tests() in debug_vm_pgtable.c which is 
marked __init.
 > Very curious!

Indeed, when I enable STATIC_CALL_SELFTEST=y on my G4 the kernel fails 
to boot at an early stage, the OpenFirmware console showing only:

done
found display   : /pci@f0000000/ATY,AlteracParent@10/ATY,Alterac_B@1, 
opening...

Without STATIC_CALL_SELFTEST the kernel boots just fine.

Kernel .config attached.
With your .config, on QEMU I get the following. I will investigate.

[    0.000000] Kernel panic - not syncing: arch_static_call_transform: 
patching failed func_a+0x0/0x10 at 0x0
[    0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.17.0- 
rc4-PMacG4+ #1628 PREEMPTLAZY
[    0.000000] Hardware name: PowerMac3,1 7400 0xc0209 PowerMac
[    0.000000] Call Trace:
[    0.000000] [c0dd7e60] [c0810e54] dump_stack_lvl+0x70/0x8c (unreliable)
[    0.000000] [c0dd7e80] [c004b220] vpanic+0x114/0x2e4
[    0.000000] [c0dd7eb0] [c004b45c] arch_set_bit+0x0/0x38
[    0.000000] [c0dd7f00] [c00155fc] arch_static_call_transform+0xec/0x1e8
[    0.000000] [c0dd7f30] [c0176944] __static_call_init+0x110/0x288
[    0.000000] [c0dd7f80] [c0c19ab0] static_call_init+0x4c/0x9c
[    0.000000] [c0dd7fa0] [c0c02e00] start_kernel+0x7c/0x664
[    0.000000] [c0dd7ff0] [000035d0] 0x35d0
[    0.000000] Rebooting in 40 seconds..
The problem comes from the following in arch/powerpc/include/asm/pgtable.h :

/*
  * Protection used for kernel text. We want the debuggers to be able to
  * set breakpoints anywhere, so don't write protect the kernel text
  * on platforms where such control is possible.
  */
#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || 
defined(CONFIG_BDI_SWITCH) || \
	defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE)
#define PAGE_KERNEL_TEXT	PAGE_KERNEL_X
#else
#define PAGE_KERNEL_TEXT	PAGE_KERNEL_ROX
#endif

I don't know what the best fix is at the moment. This probably comes 
from the old days when we didn't have CONFIG_STRICT_KERNEL_RWX. Would it 
nowadays be acceptable to inconditionnally set:

	#define PAGE_KERNEL_TEXT	PAGE_KERNEL_X

It propably would, taking into account it is used exclusively on powerpc/32:

arch/powerpc/mm/book3s32/mmu.c:         setibat(i++, PAGE_OFFSET + base, 
base, size, PAGE_KERNEL_TEXT);
arch/powerpc/mm/book3s32/mmu.c:         setibat(i++, PAGE_OFFSET + base, 
base, size, PAGE_KERNEL_TEXT);
arch/powerpc/mm/pgtable_32.c:           map_kernel_page(v, p, ktext ? 
PAGE_KERNEL_TEXT : PAGE_KERNEL);

Christophe

Re: Kernel v6.17-rc4 with STATIC_CALL_SELFTEST=y enabled fails to boot at early stage (PowerMac G4 DP)

From: Andrew Donnellan <hidden>
Date: 2025-09-04 09:58:11

On Thu, 2025-09-04 at 14:33 +0530, Madhavan Srinivasan wrote:
quoted
quoted
I am using qemu with -M mac99 and it boots

Hardware name: PowerMac3,1 7400 0xc0209 PowerMac
printk: legacy bootconsole [udbg0] enabled
-----------------------------------------------------
phys_mem_size     = 0x8000000
dcache_bsize      = 0x20

I am missing something here. Digging some more

Did you use the .config provided by Erhard ?
Oops. sorry for the noise
I noticed that I don't hit this using defconfigs (with JUMP_LABEL and
STATIC_CALL_SELFTEST manually enabled), so I did some config bisection with
Erhard's config.

It looks like you need CONFIG_KFENCE=y, and CONFIG_XMON=n.

Attached is a minimal config for current mainline, allnoconfig + CONFIG_PPC_PMAC
(so I can get console output in qemu) + CONFIG_KFENCE + CONFIG_JUMP_LABEL +
CONFIG_STATIC_CALL_SELFTEST.

Running with qemu-system-ppc -M mac99, we get the below.

Christophe: I'm not exactly sure what changes when you enable/disable KFENCE on
book3s32, but it looks to me like it affects whether .init.text is mapped using
BATs or not?

Andrew

---------------------------------
quoted
=============================================================
OpenBIOS 1.1 [Feb 12 2025 13:02]
Configuration device id QEMU version 1 machine id 1
CPUs: 1
Memory: 128M
UUID: 00000000-0000-0000-0000-000000000000
CPU type PowerPC,G4
milliseconds isn't unique.
Welcome to OpenBIOS v1.1 built on Feb 12 2025 13:02
quoted
[ppc] Kernel already loaded (0x01000000 + 0x004fcb28) (initrd 0x00000000 +
0x00000000)
quoted
[ppc] Kernel command line: console=serial
switching to new context:
OF stdout device is: /pci@f2000000/mac-io@c/escc@13000/ch-a@13020
Preparing to boot Linux version 6.17.0-rc4+ (ajd@jarvis.ozlabs.ibm.com)
(powerpc64-linux-gnu-gcc (GCC) 15.2.1 20250808 (Red Hat Cross 15.2.1-1), GNU ld
version 2.44-1.fc42) #2 Thu Sep  4 16:21:41 AEST 2025
Detected machine type: 00000400
command line:  
memory layout at init:
  memory_limit : 00000000 (16 MB aligned)
  alloc_bottom : 01501000
  alloc_top    : 08000000
  alloc_top_hi : 08000000
  rmo_top      : 08000000
  ram_top      : 08000000
found display   : /pci@f2000000/QEMU,VGA@e, opening... done
copying OF device tree...
Building dt strings...
Building dt structure...
Device tree strings 0x01502000 -> 0x015010a4
Device tree struct  0x01503000 -> 0x07de7eb0
Quiescing Open Firmware ...
Booting Linux via __start() @ 0x01000000 ...
Hello World !
Total memory = 128MB; using 256kB for hash table
Linux version 6.17.0-rc4+ (ajd@jarvis.ozlabs.ibm.com) (powerpc64-linux-gnu-gcc
(GCC) 15.2.1 20250808 (Red Hat Cross 15.2.1-1), GNU ld version 2.44-1.fc42) #2
Thu Sep  4 16:21:41 AEST 2025
OF: reserved mem: Reserved memory: No reserved-memory node in the DT
ioremap() called early from pmac_feature_init+0xe0/0xb00. Use early_ioremap()
instead
Found UniNorth memory controller & host bridge @ 0xf8000000 revision: 0x07
Mapped at 0xffb9e000
ioremap() called early from probe_one_macio+0x134/0x24c. Use early_ioremap()
instead
Found a Keylargo mac-io controller, rev: 0, mapped at 0x(ptrval)
PowerMac motherboard: PowerMac G4 AGP Graphics
ioremap() called early from udbg_scc_init+0x190/0x398. Use early_ioremap()
instead
Hardware name: PowerMac3,1 7400 0xc0209 PowerMac
printk: legacy bootconsole [udbg0] enabled
-----------------------------------------------------
phys_mem_size     = 0x8000000
dcache_bsize      = 0x20
icache_bsize      = 0x20
cpu_features      = 0x000000000401a008
  possible        = 0x00000000277de008
  always          = 0x0000000000000000
cpu_user_features = 0x8c000001 0x00000000
mmu_features      = 0x00000001
Hash_size         = 0x40000
Hash_mask         = 0xfff
-----------------------------------------------------
ioremap() called early from pmac_setup_arch+0x110/0x224. Use early_ioremap()
instead
WARNING ! Your machine is CUDA-based but your kernel
          wasn't compiled with CONFIG_ADB_CUDA option !
Zone ranges:
  DMA      [mem 0x0000000000000000-0x0000000007ffffff]
  Normal   empty
Movable zone start for each node
Early memory node ranges
  node   0: [mem 0x0000000000000000-0x0000000007ffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x0000000007ffffff]
Kernel panic - not syncing: arch_static_call_transform: patching failed
func_a+0x0/0x8 at 0x0
CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.17.0-rc4+ #2 NONE 
Hardware name: PowerMac3,1 7400 0xc0209 PowerMac
Call Trace:
[c04b9eb0] [c0292e00] dump_stack_lvl+0x50/0x78 (unreliable)
[c04b9ed0] [c002d19c] vpanic+0xfc/0x2b4
[c04b9f00] [c002d3b0] cpu_mitigations_off+0x0/0x14
[c04b9f40] [c00127ac] fixup_cpc710_pci64+0x0/0x20
[c04b9f70] [c035082c] static_call_init+0x108/0x140
[c04b9fa0] [c0342ed0] start_kernel+0x78/0x4a8
[c04b9ff0] [00003500] 0x3500
Rebooting in 180 seconds..
-- 
Andrew Donnellan    OzLabs, ADL Canberra
ajd@linux.ibm.com   IBM Australia Limited

Re: Kernel v6.17-rc4 with STATIC_CALL_SELFTEST=y enabled fails to boot at early stage (PowerMac G4 DP)

From: Christophe Leroy <hidden>
Date: 2025-09-04 10:20:40


Le 04/09/2025 à 10:40, Madhavan Srinivasan a écrit :

On 9/4/25 1:01 PM, Christophe Leroy wrote:
quoted
Hi Erhard,

Le 04/09/2025 à 00:44, Erhard Furtner a écrit :
quoted
Greetings!

In a conversation with Andrew about his page table check code for PowerPC he found out there seems to be a general problem of the code patching code on ppc:

  > I note that STATIC_CALL_SELFTEST seems to fail, which could be but isn't
  > necessarily related.

  > Specifically, it looks like code patching fails if the instruction being patched
  > is in an __init function, and in this case, that occurs due to
  > page_table_check_pte_clear() being inlined into ptep_clear(), which is in turn
  > inlined into pte_clear_tests() in debug_vm_pgtable.c which is marked __init.
  > Very curious!

Indeed, when I enable STATIC_CALL_SELFTEST=y on my G4 the kernel fails to boot at an early stage, the OpenFirmware console showing only:

done
found display   : /pci@f0000000/ATY,AlteracParent@10/ATY,Alterac_B@1, opening...

Without STATIC_CALL_SELFTEST the kernel boots just fine.

Kernel .config attached.
With your .config, on QEMU I get the following. I will investigate.

[    0.000000] Kernel panic - not syncing: arch_static_call_transform: patching failed func_a+0x0/0x10 at 0x0
[    0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.17.0-rc4-PMacG4+ #1628 PREEMPTLAZY
[    0.000000] Hardware name: PowerMac3,1 7400 0xc0209 PowerMac
[    0.000000] Call Trace:
I am using qemu with -M mac99 and it boots

Hardware name: PowerMac3,1 7400 0xc0209 PowerMac
printk: legacy bootconsole [udbg0] enabled
-----------------------------------------------------
phys_mem_size     = 0x8000000
dcache_bsize      = 0x20

I am missing something here. Digging some more

Did you use the .config provided by Erhard ?

Christophe

Re: Kernel v6.17-rc4 with STATIC_CALL_SELFTEST=y enabled fails to boot at early stage (PowerMac G4 DP)

From: Christophe Leroy <hidden>
Date: 2025-09-04 10:20:56


Le 04/09/2025 à 11:57, Andrew Donnellan a écrit :
On Thu, 2025-09-04 at 14:33 +0530, Madhavan Srinivasan wrote:
quoted
quoted
quoted
I am using qemu with -M mac99 and it boots

Hardware name: PowerMac3,1 7400 0xc0209 PowerMac
printk: legacy bootconsole [udbg0] enabled
-----------------------------------------------------
phys_mem_size     = 0x8000000
dcache_bsize      = 0x20

I am missing something here. Digging some more

Did you use the .config provided by Erhard ?
Oops. sorry for the noise
I noticed that I don't hit this using defconfigs (with JUMP_LABEL and
STATIC_CALL_SELFTEST manually enabled), so I did some config bisection with
Erhard's config.

It looks like you need CONFIG_KFENCE=y, and CONFIG_XMON=n.

Attached is a minimal config for current mainline, allnoconfig + CONFIG_PPC_PMAC
(so I can get console output in qemu) + CONFIG_KFENCE + CONFIG_JUMP_LABEL +
CONFIG_STATIC_CALL_SELFTEST.

Running with qemu-system-ppc -M mac99, we get the below.

Christophe: I'm not exactly sure what changes when you enable/disable KFENCE on
book3s32, but it looks to me like it affects whether .init.text is mapped using
BATs or not?
As I said in previous response, the problem seems to come from here:

arch/powerpc/include/asm/pgtable.h :

/*
  * Protection used for kernel text. We want the debuggers to be able to
  * set breakpoints anywhere, so don't write protect the kernel text
  * on platforms where such control is possible.
  */
#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || 
defined(CONFIG_BDI_SWITCH) || \
     defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE)
#define PAGE_KERNEL_TEXT    PAGE_KERNEL_X
#else
#define PAGE_KERNEL_TEXT    PAGE_KERNEL_ROX
#endif

If you have neither CONFIG_KGDB nor CONFIG_XMON nor CONFIG_BDI_SWITCH 
nor CONFIG_KPROBES or CONFIG_DYNAMIC_FTRACE, kernel text is mapped 
Read-Only.

Using BATs or not shouldn't make any difference because:

With BATs we do:
arch/powerpc/mm/book3s32/mmu.c:         setibat(i++, PAGE_OFFSET + base, 
base, size, PAGE_KERNEL_TEXT);
arch/powerpc/mm/book3s32/mmu.c:         setibat(i++, PAGE_OFFSET + base, 
base, size, PAGE_KERNEL_TEXT);

Without BATs we do:
arch/powerpc/mm/pgtable_32.c:           map_kernel_page(v, p, ktext ? 
PAGE_KERNEL_TEXT : PAGE_KERNEL);


Andrew

---------------------------------
quoted
quoted
=============================================================
OpenBIOS 1.1 [Feb 12 2025 13:02]
Configuration device id QEMU version 1 machine id 1
CPUs: 1
Memory: 128M
UUID: 00000000-0000-0000-0000-000000000000
CPU type PowerPC,G4
milliseconds isn't unique.
Welcome to OpenBIOS v1.1 built on Feb 12 2025 13:02
quoted
quoted
[ppc] Kernel already loaded (0x01000000 + 0x004fcb28) (initrd 0x00000000 +
0x00000000)
quoted
quoted
[ppc] Kernel command line: console=serial
switching to new context:
OF stdout device is: /pci@f2000000/mac-io@c/escc@13000/ch-a@13020
Preparing to boot Linux version 6.17.0-rc4+ (ajd@jarvis.ozlabs.ibm.com)
(powerpc64-linux-gnu-gcc (GCC) 15.2.1 20250808 (Red Hat Cross 15.2.1-1), GNU ld
version 2.44-1.fc42) #2 Thu Sep  4 16:21:41 AEST 2025
Detected machine type: 00000400
command line:
memory layout at init:
   memory_limit : 00000000 (16 MB aligned)
   alloc_bottom : 01501000
   alloc_top    : 08000000
   alloc_top_hi : 08000000
   rmo_top      : 08000000
   ram_top      : 08000000
found display   : /pci@f2000000/QEMU,VGA@e, opening... done
copying OF device tree...
Building dt strings...
Building dt structure...
Device tree strings 0x01502000 -> 0x015010a4
Device tree struct  0x01503000 -> 0x07de7eb0
Quiescing Open Firmware ...
Booting Linux via __start() @ 0x01000000 ...
Hello World !
Total memory = 128MB; using 256kB for hash table
Linux version 6.17.0-rc4+ (ajd@jarvis.ozlabs.ibm.com) (powerpc64-linux-gnu-gcc
(GCC) 15.2.1 20250808 (Red Hat Cross 15.2.1-1), GNU ld version 2.44-1.fc42) #2
Thu Sep  4 16:21:41 AEST 2025
OF: reserved mem: Reserved memory: No reserved-memory node in the DT
ioremap() called early from pmac_feature_init+0xe0/0xb00. Use early_ioremap()
instead
Found UniNorth memory controller & host bridge @ 0xf8000000 revision: 0x07
Mapped at 0xffb9e000
ioremap() called early from probe_one_macio+0x134/0x24c. Use early_ioremap()
instead
Found a Keylargo mac-io controller, rev: 0, mapped at 0x(ptrval)
PowerMac motherboard: PowerMac G4 AGP Graphics
ioremap() called early from udbg_scc_init+0x190/0x398. Use early_ioremap()
instead
Hardware name: PowerMac3,1 7400 0xc0209 PowerMac
printk: legacy bootconsole [udbg0] enabled
-----------------------------------------------------
phys_mem_size     = 0x8000000
dcache_bsize      = 0x20
icache_bsize      = 0x20
cpu_features      = 0x000000000401a008
   possible        = 0x00000000277de008
   always          = 0x0000000000000000
cpu_user_features = 0x8c000001 0x00000000
mmu_features      = 0x00000001
Hash_size         = 0x40000
Hash_mask         = 0xfff
-----------------------------------------------------
ioremap() called early from pmac_setup_arch+0x110/0x224. Use early_ioremap()
instead
WARNING ! Your machine is CUDA-based but your kernel
           wasn't compiled with CONFIG_ADB_CUDA option !
Zone ranges:
   DMA      [mem 0x0000000000000000-0x0000000007ffffff]
   Normal   empty
Movable zone start for each node
Early memory node ranges
   node   0: [mem 0x0000000000000000-0x0000000007ffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x0000000007ffffff]
Kernel panic - not syncing: arch_static_call_transform: patching failed
func_a+0x0/0x8 at 0x0
CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.17.0-rc4+ #2 NONE
Hardware name: PowerMac3,1 7400 0xc0209 PowerMac
Call Trace:
[c04b9eb0] [c0292e00] dump_stack_lvl+0x50/0x78 (unreliable)
[c04b9ed0] [c002d19c] vpanic+0xfc/0x2b4
[c04b9f00] [c002d3b0] cpu_mitigations_off+0x0/0x14
[c04b9f40] [c00127ac] fixup_cpc710_pci64+0x0/0x20
[c04b9f70] [c035082c] static_call_init+0x108/0x140
[c04b9fa0] [c0342ed0] start_kernel+0x78/0x4a8
[c04b9ff0] [00003500] 0x3500
Rebooting in 180 seconds..

[PATCH] powerpc/32: Remove PAGE_KERNEL_TEXT to fix startup failure

From: Christophe Leroy <hidden>
Date: 2025-09-04 16:50:35

PAGE_KERNEL_TEXT is an old macro that is used to tell kernel whether
kernel text has to be mapped read-only or read-write based on build
time options.

But nowadays, with functionnalities like jump_labels, static links,
etc ... more only less all kernels need to be read-write at some
point, and some combinations of configs failed to work due to
innacurate setting of PAGE_KERNEL_TEXT. On the other hand, today
we have CONFIG_STRICT_KERNEL_RWX which implements a more controlled
access to kernel modifications.

Instead of trying to keep PAGE_KERNEL_TEXT accurate with all
possible options that may imply kernel text modification, always
set kernel text read-write at startup and rely on
CONFIG_STRICT_KERNEL_RWX to provide accurate protection.

Reported-by: Erhard Furtner <redacted>
Closes: https://lore.kernel.org/all/342b4120-911c-4723-82ec-d8c9b03a8aef@mailbox.org/
Signed-off-by: Christophe Leroy <redacted>
---
 arch/powerpc/include/asm/pgtable.h | 12 ------------
 arch/powerpc/mm/book3s32/mmu.c     |  4 ++--
 arch/powerpc/mm/pgtable_32.c       |  2 +-
 3 files changed, 3 insertions(+), 15 deletions(-)
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index 93d77ad5a92f..d8f944a5a037 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -20,18 +20,6 @@ struct mm_struct;
 #include <asm/nohash/pgtable.h>
 #endif /* !CONFIG_PPC_BOOK3S */
 
-/*
- * Protection used for kernel text. We want the debuggers to be able to
- * set breakpoints anywhere, so don't write protect the kernel text
- * on platforms where such control is possible.
- */
-#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) || \
-	defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE)
-#define PAGE_KERNEL_TEXT	PAGE_KERNEL_X
-#else
-#define PAGE_KERNEL_TEXT	PAGE_KERNEL_ROX
-#endif
-
 /* Make modules code happy. We don't set RO yet */
 #define PAGE_KERNEL_EXEC	PAGE_KERNEL_X
 
diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c
index be9c4106e22f..c42ecdf94e48 100644
--- a/arch/powerpc/mm/book3s32/mmu.c
+++ b/arch/powerpc/mm/book3s32/mmu.c
@@ -204,7 +204,7 @@ int mmu_mark_initmem_nx(void)
 
 	for (i = 0; i < nb - 1 && base < top;) {
 		size = bat_block_size(base, top);
-		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
+		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_X);
 		base += size;
 	}
 	if (base < top) {
@@ -215,7 +215,7 @@ int mmu_mark_initmem_nx(void)
 				pr_warn("Some RW data is getting mapped X. "
 					"Adjust CONFIG_DATA_SHIFT to avoid that.\n");
 		}
-		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
+		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_X);
 		base += size;
 	}
 	for (; i < nb; i++)
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 15276068f657..0c9ef705803e 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -104,7 +104,7 @@ static void __init __mapin_ram_chunk(unsigned long offset, unsigned long top)
 	p = memstart_addr + s;
 	for (; s < top; s += PAGE_SIZE) {
 		ktext = core_kernel_text(v);
-		map_kernel_page(v, p, ktext ? PAGE_KERNEL_TEXT : PAGE_KERNEL);
+		map_kernel_page(v, p, ktext ? PAGE_KERNEL_X : PAGE_KERNEL);
 		v += PAGE_SIZE;
 		p += PAGE_SIZE;
 	}
-- 
2.49.0

Re: [PATCH] powerpc/32: Remove PAGE_KERNEL_TEXT to fix startup failure

From: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Date: 2025-09-05 04:49:52

Christophe Leroy [off-list ref] writes:
PAGE_KERNEL_TEXT is an old macro that is used to tell kernel whether
kernel text has to be mapped read-only or read-write based on build
time options.

But nowadays, with functionnalities like jump_labels, static links,
etc ... more only less all kernels need to be read-write at some
point, and some combinations of configs failed to work due to
innacurate setting of PAGE_KERNEL_TEXT. On the other hand, today
we have CONFIG_STRICT_KERNEL_RWX which implements a more controlled
access to kernel modifications.

Instead of trying to keep PAGE_KERNEL_TEXT accurate with all
possible options that may imply kernel text modification, always
set kernel text read-write at startup and rely on
CONFIG_STRICT_KERNEL_RWX to provide accurate protection.

Reported-by: Erhard Furtner <redacted>
Closes: https://lore.kernel.org/all/342b4120-911c-4723-82ec-d8c9b03a8aef@mailbox.org/
Signed-off-by: Christophe Leroy <redacted>
---
 arch/powerpc/include/asm/pgtable.h | 12 ------------
 arch/powerpc/mm/book3s32/mmu.c     |  4 ++--
 arch/powerpc/mm/pgtable_32.c       |  2 +-
 3 files changed, 3 insertions(+), 15 deletions(-)
AFAIU - mmu_mark_initmem_nx gets called during kernel_init() which is
way after static call initialization correct? i.e.

start_kernel
  ...
  jump_label_init()
  static_call_init()
  ...
  ...
  rest_init()      /* Do the rest non-__init'ed, we're now alive */
    kernel_init()
      free_initmem() -> mark_initmem_nx() -> __mark_initmem_nx -> mmu_mark_initmem_nx() 
      mark_readonly()
        if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX) && rodata_enabled) {
           jump_label_init_ro()
           mark_rodata_ro() -> ....
           ...
        ...

Then I guess we mainly only need __mapin_ram_chunk() to be PAGE_KERNEL_X (RWX)
instead of PAGE_KERNEL_TEXT (ROX), isn't it?

Let me quickly validate it... 
...Ok, so I was able to get just this diff to be working. 

Thoughts?
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 15276068f657..0c9ef705803e 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -104,7 +104,7 @@ static void __init __mapin_ram_chunk(unsigned long offset, unsigned long top)
        p = memstart_addr + s;
        for (; s < top; s += PAGE_SIZE) {
                ktext = core_kernel_text(v);
-               map_kernel_page(v, p, ktext ? PAGE_KERNEL_TEXT : PAGE_KERNEL);
+               map_kernel_page(v, p, ktext ? PAGE_KERNEL_X : PAGE_KERNEL);
                v += PAGE_SIZE;
                p += PAGE_SIZE;
        }

-ritesh


quoted hunk
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index 93d77ad5a92f..d8f944a5a037 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -20,18 +20,6 @@ struct mm_struct;
 #include <asm/nohash/pgtable.h>
 #endif /* !CONFIG_PPC_BOOK3S */
 
-/*
- * Protection used for kernel text. We want the debuggers to be able to
- * set breakpoints anywhere, so don't write protect the kernel text
- * on platforms where such control is possible.
- */
-#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) || \
-	defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE)
-#define PAGE_KERNEL_TEXT	PAGE_KERNEL_X
-#else
-#define PAGE_KERNEL_TEXT	PAGE_KERNEL_ROX
-#endif
-
 /* Make modules code happy. We don't set RO yet */
 #define PAGE_KERNEL_EXEC	PAGE_KERNEL_X
 
diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c
index be9c4106e22f..c42ecdf94e48 100644
--- a/arch/powerpc/mm/book3s32/mmu.c
+++ b/arch/powerpc/mm/book3s32/mmu.c
@@ -204,7 +204,7 @@ int mmu_mark_initmem_nx(void)
 
 	for (i = 0; i < nb - 1 && base < top;) {
 		size = bat_block_size(base, top);
-		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
+		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_X);
 		base += size;
 	}
 	if (base < top) {
@@ -215,7 +215,7 @@ int mmu_mark_initmem_nx(void)
 				pr_warn("Some RW data is getting mapped X. "
 					"Adjust CONFIG_DATA_SHIFT to avoid that.\n");
 		}
-		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
+		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_X);
 		base += size;
 	}
 	for (; i < nb; i++)
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 15276068f657..0c9ef705803e 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -104,7 +104,7 @@ static void __init __mapin_ram_chunk(unsigned long offset, unsigned long top)
 	p = memstart_addr + s;
 	for (; s < top; s += PAGE_SIZE) {
 		ktext = core_kernel_text(v);
-		map_kernel_page(v, p, ktext ? PAGE_KERNEL_TEXT : PAGE_KERNEL);
+		map_kernel_page(v, p, ktext ? PAGE_KERNEL_X : PAGE_KERNEL);
 		v += PAGE_SIZE;
 		p += PAGE_SIZE;
 	}
-- 
2.49.0

Re: [PATCH] powerpc/32: Remove PAGE_KERNEL_TEXT to fix startup failure

From: Christophe Leroy <hidden>
Date: 2025-09-05 05:20:35


Le 05/09/2025 à 05:55, Ritesh Harjani a écrit :
Christophe Leroy [off-list ref] writes:
quoted
PAGE_KERNEL_TEXT is an old macro that is used to tell kernel whether
kernel text has to be mapped read-only or read-write based on build
time options.

But nowadays, with functionnalities like jump_labels, static links,
etc ... more only less all kernels need to be read-write at some
point, and some combinations of configs failed to work due to
innacurate setting of PAGE_KERNEL_TEXT. On the other hand, today
we have CONFIG_STRICT_KERNEL_RWX which implements a more controlled
access to kernel modifications.

Instead of trying to keep PAGE_KERNEL_TEXT accurate with all
possible options that may imply kernel text modification, always
set kernel text read-write at startup and rely on
CONFIG_STRICT_KERNEL_RWX to provide accurate protection.

Reported-by: Erhard Furtner <redacted>
Closes: https://lore.kernel.org/all/342b4120-911c-4723-82ec-d8c9b03a8aef@mailbox.org/
Signed-off-by: Christophe Leroy <redacted>
---
  arch/powerpc/include/asm/pgtable.h | 12 ------------
  arch/powerpc/mm/book3s32/mmu.c     |  4 ++--
  arch/powerpc/mm/pgtable_32.c       |  2 +-
  3 files changed, 3 insertions(+), 15 deletions(-)
AFAIU - mmu_mark_initmem_nx gets called during kernel_init() which is
way after static call initialization correct? i.e.

start_kernel
   ...
   jump_label_init()
   static_call_init()
   ...
   ...
   rest_init()      /* Do the rest non-__init'ed, we're now alive */
     kernel_init()
       free_initmem() -> mark_initmem_nx() -> __mark_initmem_nx -> mmu_mark_initmem_nx()
       mark_readonly()
         if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX) && rodata_enabled) {
            jump_label_init_ro()
            mark_rodata_ro() -> ....
            ...
         ...

Then I guess we mainly only need __mapin_ram_chunk() to be PAGE_KERNEL_X (RWX)
instead of PAGE_KERNEL_TEXT (ROX), isn't it?

Let me quickly validate it...
...Ok, so I was able to get just this diff to be working.

Thoughts?
setibat() doesn't take into account whether it is RO or RW. Only X or NX 
is taken into account, so it doesn't matter whether it is X or ROX.

Then allthough you are right in principle, once the PAGE_KERNEL_TEXT is 
removed from __mapin_ram_chunk() it becomes completely useless, so 
better get rid of PAGE_KERNEL_TEXT completely.
quoted hunk
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 15276068f657..0c9ef705803e 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -104,7 +104,7 @@ static void __init __mapin_ram_chunk(unsigned long offset, unsigned long top)
         p = memstart_addr + s;
         for (; s < top; s += PAGE_SIZE) {
                 ktext = core_kernel_text(v);
-               map_kernel_page(v, p, ktext ? PAGE_KERNEL_TEXT : PAGE_KERNEL);
+               map_kernel_page(v, p, ktext ? PAGE_KERNEL_X : PAGE_KERNEL);
                 v += PAGE_SIZE;
                 p += PAGE_SIZE;
         }

-ritesh


quoted
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index 93d77ad5a92f..d8f944a5a037 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -20,18 +20,6 @@ struct mm_struct;
  #include <asm/nohash/pgtable.h>
  #endif /* !CONFIG_PPC_BOOK3S */
  
-/*
- * Protection used for kernel text. We want the debuggers to be able to
- * set breakpoints anywhere, so don't write protect the kernel text
- * on platforms where such control is possible.
- */
-#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) || \
-	defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE)
-#define PAGE_KERNEL_TEXT	PAGE_KERNEL_X
-#else
-#define PAGE_KERNEL_TEXT	PAGE_KERNEL_ROX
-#endif
-
  /* Make modules code happy. We don't set RO yet */
  #define PAGE_KERNEL_EXEC	PAGE_KERNEL_X
  
diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c
index be9c4106e22f..c42ecdf94e48 100644
--- a/arch/powerpc/mm/book3s32/mmu.c
+++ b/arch/powerpc/mm/book3s32/mmu.c
@@ -204,7 +204,7 @@ int mmu_mark_initmem_nx(void)
  
  	for (i = 0; i < nb - 1 && base < top;) {
  		size = bat_block_size(base, top);
-		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
+		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_X);
  		base += size;
  	}
  	if (base < top) {
@@ -215,7 +215,7 @@ int mmu_mark_initmem_nx(void)
  				pr_warn("Some RW data is getting mapped X. "
  					"Adjust CONFIG_DATA_SHIFT to avoid that.\n");
  		}
-		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
+		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_X);
  		base += size;
  	}
  	for (; i < nb; i++)
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 15276068f657..0c9ef705803e 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -104,7 +104,7 @@ static void __init __mapin_ram_chunk(unsigned long offset, unsigned long top)
  	p = memstart_addr + s;
  	for (; s < top; s += PAGE_SIZE) {
  		ktext = core_kernel_text(v);
-		map_kernel_page(v, p, ktext ? PAGE_KERNEL_TEXT : PAGE_KERNEL);
+		map_kernel_page(v, p, ktext ? PAGE_KERNEL_X : PAGE_KERNEL);
  		v += PAGE_SIZE;
  		p += PAGE_SIZE;
  	}
-- 
2.49.0

Re: [PATCH] powerpc/32: Remove PAGE_KERNEL_TEXT to fix startup failure

From: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Date: 2025-09-05 05:44:08

Christophe Leroy [off-list ref] writes:
Le 05/09/2025 à 05:55, Ritesh Harjani a écrit :
quoted
Christophe Leroy [off-list ref] writes:
quoted
PAGE_KERNEL_TEXT is an old macro that is used to tell kernel whether
kernel text has to be mapped read-only or read-write based on build
time options.

But nowadays, with functionnalities like jump_labels, static links,
etc ... more only less all kernels need to be read-write at some
point, and some combinations of configs failed to work due to
innacurate setting of PAGE_KERNEL_TEXT. On the other hand, today
we have CONFIG_STRICT_KERNEL_RWX which implements a more controlled
access to kernel modifications.

Instead of trying to keep PAGE_KERNEL_TEXT accurate with all
possible options that may imply kernel text modification, always
set kernel text read-write at startup and rely on
CONFIG_STRICT_KERNEL_RWX to provide accurate protection.

Reported-by: Erhard Furtner <redacted>
Closes: https://lore.kernel.org/all/342b4120-911c-4723-82ec-d8c9b03a8aef@mailbox.org/
Signed-off-by: Christophe Leroy <redacted>
---
  arch/powerpc/include/asm/pgtable.h | 12 ------------
  arch/powerpc/mm/book3s32/mmu.c     |  4 ++--
  arch/powerpc/mm/pgtable_32.c       |  2 +-
  3 files changed, 3 insertions(+), 15 deletions(-)
AFAIU - mmu_mark_initmem_nx gets called during kernel_init() which is
way after static call initialization correct? i.e.

start_kernel
   ...
   jump_label_init()
   static_call_init()
   ...
   ...
   rest_init()      /* Do the rest non-__init'ed, we're now alive */
     kernel_init()
       free_initmem() -> mark_initmem_nx() -> __mark_initmem_nx -> mmu_mark_initmem_nx()
       mark_readonly()
         if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX) && rodata_enabled) {
            jump_label_init_ro()
            mark_rodata_ro() -> ....
            ...
         ...

Then I guess we mainly only need __mapin_ram_chunk() to be PAGE_KERNEL_X (RWX)
instead of PAGE_KERNEL_TEXT (ROX), isn't it?

Let me quickly validate it...
...Ok, so I was able to get just this diff to be working.

Thoughts?
setibat() doesn't take into account whether it is RO or RW. Only X or NX 
is taken into account, so it doesn't matter whether it is X or ROX.

Then allthough you are right in principle, once the PAGE_KERNEL_TEXT is 
removed from __mapin_ram_chunk() it becomes completely useless, so 
better get rid of PAGE_KERNEL_TEXT completely.
Aah yes, I checked the function setibat() and as you mentioned, it
doesn't honour RW permission anyways. Can we please update the same in
the commit message too? That makes it more clear then. 

-ritesh

Re: [PATCH] powerpc/32: Remove PAGE_KERNEL_TEXT to fix startup failure

From: Andrew Donnellan <hidden>
Date: 2025-09-05 06:57:42

On Thu, 2025-09-04 at 18:33 +0200, Christophe Leroy wrote:
PAGE_KERNEL_TEXT is an old macro that is used to tell kernel whether
kernel text has to be mapped read-only or read-write based on build
time options.

But nowadays, with functionnalities like jump_labels, static links,
etc ... more only less all kernels need to be read-write at some
point, and some combinations of configs failed to work due to
innacurate setting of PAGE_KERNEL_TEXT. On the other hand, today
we have CONFIG_STRICT_KERNEL_RWX which implements a more controlled
access to kernel modifications.

Instead of trying to keep PAGE_KERNEL_TEXT accurate with all
possible options that may imply kernel text modification, always
set kernel text read-write at startup and rely on
CONFIG_STRICT_KERNEL_RWX to provide accurate protection.

Reported-by: Erhard Furtner <redacted>
Closes:
https://lore.kernel.org/all/342b4120-911c-4723-82ec-d8c9b03a8aef@mailbox.org/
Signed-off-by: Christophe Leroy <redacted>
The original issue that Erhard and I were investigating was why the latest
version of the PowerPC page table check series[0] was failing on his G4, when
built as part of a config with many other debugging options enabled.

With further instrumentation, it turns out that this was due to a failed
instruction patch while setting up a jump label for the
page_table_check_disabled static key, which was being checked in
page_table_check_pte_clear(), which was in turn inlined ultimately into
debug_vm_pgtable().

This patch seems to fix the problem, so:

Tested-by: Andrew Donnellan <redacted>

But I'm still curious about why I only see the issue when:

  (a) CONFIG_KFENCE=y (even when disabled using kfence.sample_interval=0) -
noting that changing CONFIG_KFENCE doesn't change the definition of
PAGE_KERNEL_TEXT; and

  (b) when the jump label ends up in a __init function (removing __init from
debug_vm_pgtable() and its associated functions, or changing the code in such a
way that the static key check doesn't get inlined, resolves the issue, and
similarly for test_static_call_init() when CONFIG_STATIC_CALL_SELFTEST=y).

I don't understand the mm code well enough to make sense of this.

[0] https://lore.kernel.org/all/20250813062614.51759-1-ajd@linux.ibm.com/

-- 
Andrew Donnellan    OzLabs, ADL Canberra
ajd@linux.ibm.com   IBM Australia Limited

Re: [PATCH] powerpc/32: Remove PAGE_KERNEL_TEXT to fix startup failure

From: Christophe Leroy <hidden>
Date: 2025-09-05 10:20:35


Le 05/09/2025 à 08:57, Andrew Donnellan a écrit :
On Thu, 2025-09-04 at 18:33 +0200, Christophe Leroy wrote:
quoted
PAGE_KERNEL_TEXT is an old macro that is used to tell kernel whether
kernel text has to be mapped read-only or read-write based on build
time options.

But nowadays, with functionnalities like jump_labels, static links,
etc ... more only less all kernels need to be read-write at some
point, and some combinations of configs failed to work due to
innacurate setting of PAGE_KERNEL_TEXT. On the other hand, today
we have CONFIG_STRICT_KERNEL_RWX which implements a more controlled
access to kernel modifications.

Instead of trying to keep PAGE_KERNEL_TEXT accurate with all
possible options that may imply kernel text modification, always
set kernel text read-write at startup and rely on
CONFIG_STRICT_KERNEL_RWX to provide accurate protection.

Reported-by: Erhard Furtner <redacted>
Closes:
https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Fall%2F342b4120-911c-4723-82ec-d8c9b03a8aef%40mailbox.org%2F&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7Ce1df868f94284b06db0508ddec497516%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C638926522413828188%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=cqhzYIshhwKJluL2U2ULuNYoQ1CR1ZP0nsl5pb3wHd4%3D&reserved=0
Signed-off-by: Christophe Leroy <redacted>
The original issue that Erhard and I were investigating was why the latest
version of the PowerPC page table check series[0] was failing on his G4, when
built as part of a config with many other debugging options enabled.

With further instrumentation, it turns out that this was due to a failed
instruction patch while setting up a jump label for the
page_table_check_disabled static key, which was being checked in
page_table_check_pte_clear(), which was in turn inlined ultimately into
debug_vm_pgtable().

This patch seems to fix the problem, so:

Tested-by: Andrew Donnellan <redacted>

But I'm still curious about why I only see the issue when:

   (a) CONFIG_KFENCE=y (even when disabled using kfence.sample_interval=0) -
noting that changing CONFIG_KFENCE doesn't change the definition of
PAGE_KERNEL_TEXT; and

   (b) when the jump label ends up in a __init function (removing __init from
debug_vm_pgtable() and its associated functions, or changing the code in such a
way that the static key check doesn't get inlined, resolves the issue, and
similarly for test_static_call_init() when CONFIG_STATIC_CALL_SELFTEST=y).

I don't understand the mm code well enough to make sense of this.
That makes sense. When CONFIG_KFENCE is selected, only text and rodata 
are mapped with BATs. Everything else including inittext is mapped with 
pages. When CONFIG_KFENCE and CONFIG_DEBUG_PAGEALLOC are not selected, 
we map as much as possible with BATs.

And as you can see below, BATs are mapped with PAGE_KERNEL_X not with 
PAGE_KERNEL_TEXT.

Everything happen here below:

static unsigned long __init __mmu_mapin_ram(unsigned long base, unsigned 
long top)
{
	int idx;

	while ((idx = find_free_bat()) != -1 && base != top) {
		unsigned int size = bat_block_size(base, top);

		if (size < 128 << 10)
			break;
		setbat(idx, PAGE_OFFSET + base, base, size, PAGE_KERNEL_X);
		base += size;
	}

	return base;
}

unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
{
	unsigned long done;
	unsigned long border = (unsigned long)__srwx_boundary - PAGE_OFFSET;
	unsigned long size;

	size = roundup_pow_of_two((unsigned long)_einittext - PAGE_OFFSET);
	setibat(0, PAGE_OFFSET, 0, size, PAGE_KERNEL_X);

	if (debug_pagealloc_enabled_or_kfence()) {
		pr_debug_once("Read-Write memory mapped without BATs\n");
		if (base >= border)
			return base;
		if (top >= border)
			top = border;
	}

	if (!strict_kernel_rwx_enabled() || base >= border || top <= border)
		return __mmu_mapin_ram(base, top);

	done = __mmu_mapin_ram(base, border);
	if (done != border)
		return done;

	return __mmu_mapin_ram(border, top);
}

[0] https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Fall%2F20250813062614.51759-1-ajd%40linux.ibm.com%2F&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7Ce1df868f94284b06db0508ddec497516%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C638926522413849910%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=1slIkZ4krf2sWUaKJ%2FayEX8t9dKpfsrDiAxZRohKfRQ%3D&reserved=0

Re: [PATCH] powerpc/32: Remove PAGE_KERNEL_TEXT to fix startup failure

From: Erhard Furtner <hidden>
Date: 2025-09-05 14:30:09

On 9/4/25 18:33, Christophe Leroy wrote:
PAGE_KERNEL_TEXT is an old macro that is used to tell kernel whether
kernel text has to be mapped read-only or read-write based on build
time options.

But nowadays, with functionnalities like jump_labels, static links,
etc ... more only less all kernels need to be read-write at some
point, and some combinations of configs failed to work due to
innacurate setting of PAGE_KERNEL_TEXT. On the other hand, today
we have CONFIG_STRICT_KERNEL_RWX which implements a more controlled
access to kernel modifications.

Instead of trying to keep PAGE_KERNEL_TEXT accurate with all
possible options that may imply kernel text modification, always
set kernel text read-write at startup and rely on
CONFIG_STRICT_KERNEL_RWX to provide accurate protection.
I can confirm your patch fixes the startup failure for my G4 .config. 
Thanks!

Regards,
Erhard
quoted hunk
Reported-by: Erhard Furtner <redacted>
Closes: https://lore.kernel.org/all/342b4120-911c-4723-82ec-d8c9b03a8aef@mailbox.org/
Signed-off-by: Christophe Leroy <redacted>
---
  arch/powerpc/include/asm/pgtable.h | 12 ------------
  arch/powerpc/mm/book3s32/mmu.c     |  4 ++--
  arch/powerpc/mm/pgtable_32.c       |  2 +-
  3 files changed, 3 insertions(+), 15 deletions(-)
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index 93d77ad5a92f..d8f944a5a037 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -20,18 +20,6 @@ struct mm_struct;
  #include <asm/nohash/pgtable.h>
  #endif /* !CONFIG_PPC_BOOK3S */
  
-/*
- * Protection used for kernel text. We want the debuggers to be able to
- * set breakpoints anywhere, so don't write protect the kernel text
- * on platforms where such control is possible.
- */
-#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) || \
-	defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE)
-#define PAGE_KERNEL_TEXT	PAGE_KERNEL_X
-#else
-#define PAGE_KERNEL_TEXT	PAGE_KERNEL_ROX
-#endif
-
  /* Make modules code happy. We don't set RO yet */
  #define PAGE_KERNEL_EXEC	PAGE_KERNEL_X
  
diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c
index be9c4106e22f..c42ecdf94e48 100644
--- a/arch/powerpc/mm/book3s32/mmu.c
+++ b/arch/powerpc/mm/book3s32/mmu.c
@@ -204,7 +204,7 @@ int mmu_mark_initmem_nx(void)
  
  	for (i = 0; i < nb - 1 && base < top;) {
  		size = bat_block_size(base, top);
-		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
+		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_X);
  		base += size;
  	}
  	if (base < top) {
@@ -215,7 +215,7 @@ int mmu_mark_initmem_nx(void)
  				pr_warn("Some RW data is getting mapped X. "
  					"Adjust CONFIG_DATA_SHIFT to avoid that.\n");
  		}
-		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
+		setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_X);
  		base += size;
  	}
  	for (; i < nb; i++)
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 15276068f657..0c9ef705803e 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -104,7 +104,7 @@ static void __init __mapin_ram_chunk(unsigned long offset, unsigned long top)
  	p = memstart_addr + s;
  	for (; s < top; s += PAGE_SIZE) {
  		ktext = core_kernel_text(v);
-		map_kernel_page(v, p, ktext ? PAGE_KERNEL_TEXT : PAGE_KERNEL);
+		map_kernel_page(v, p, ktext ? PAGE_KERNEL_X : PAGE_KERNEL);
  		v += PAGE_SIZE;
  		p += PAGE_SIZE;
  	}

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help