Re: [Help] Microwatt (Zynqwatt) — Kernel halts after Radix MMU init on booting Linux on Zynq version of Microwatt

Mohammad Amin Nili manili.devteam at gmail.com
Sat Nov 22 01:59:11 AEDT 2025


Hi Oliver!

> If you wanted to do something similar you would need to
> implement a udbg driver for your xilinx UART.

Actually this was the key point which finally led me to the
right direction. Thank you SOOO much for your help.
I implemented a udbg driver for Xilinx’s UART, worked
through a number of bugs, and managed to get bash and
userspace to start. During the work I hit two things in the
source that look odd to me; I’d appreciate any pointers or
explanations:

1. There appear to be two ways udbg can be initiated:
- https://elixir.bootlin.com/linux/v6.18-rc5/source/arch/powerpc/kernel/setup_64.c#L378 <https://elixir.bootlin.com/linux/v6.18-rc5/source/arch/powerpc/kernel/setup_64.c#L378>
- https://elixir.bootlin.com/linux/v6.18-rc5/source/init/main.c#L932 <https://elixir.bootlin.com/linux/v6.18-rc5/source/init/main.c#L932>
  -> https://elixir.bootlin.com/linux/v6.18-rc5/source/arch/powerpc/kernel/setup-common.c#L944 <https://elixir.bootlin.com/linux/v6.18-rc5/source/arch/powerpc/kernel/setup-common.c#L944>
  -> https://elixir.bootlin.com/linux/v6.18-rc5/source/arch/powerpc/kernel/setup-common.c#L947 <https://elixir.bootlin.com/linux/v6.18-rc5/source/arch/powerpc/kernel/setup-common.c#L947>

The problem with the *first* (early) path is that a udbg driver
often calls `early_ioremap()` **before** any MMU/memory
setup has completed. The MMU setup for 64-bit happens here:
- https://elixir.bootlin.com/linux/v6.18-rc5/source/arch/powerpc/kernel/setup_64.c#L418 <https://elixir.bootlin.com/linux/v6.18-rc5/source/arch/powerpc/kernel/setup_64.c#L418>

The 32-bit setup (`setup_32.c`) calls `udbg_early_init` *after*
`early_ioremap_init`, so it doesn’t hit this ordering problem:
- https://elixir.bootlin.com/linux/v6.18-rc5/source/arch/powerpc/kernel/setup_32.c#L87 <https://elixir.bootlin.com/linux/v6.18-rc5/source/arch/powerpc/kernel/setup_32.c#L87>

In my case, attempting to initialize the Xilinx udbg driver via
the early path can (and did) cause kernel panics because
`early_ioremap()` runs before the memory/MMU is ready.
Practically, the only reliable place for my driver to initialize
is later in `init/main.c`. Is this the intended/expected behavior
for PPC64? Or am I missing something?

2. I had to inject a busy-wait loop between lines 125–126 in
`kernel/rcu/tiny.c` to prevent a crash when/after switching to
userspace:
- https://elixir.bootlin.com/linux/v6.18-rc5/source/kernel/rcu/tiny.c#L125 <https://elixir.bootlin.com/linux/v6.18-rc5/source/kernel/rcu/tiny.c#L125>

Here is the loop I added:
for (volatile uint32_t i = 0; i < 10; i++);

If I omit that trivial busy-wait, the kernel crashes while/after
switching to userspace with an error LIKE:

[   42.397074] kernel tried to execute exec-protected page (c00c000000000000) - exploit attempt? (uid: 0)
[   42.408148] BUG: Unable to handle kernel instruction fetch
[   42.414964] Faulting instruction address: 0xc00c000000000000
Vector: 400 (Instruction Access) at [c00000000207fae0]
    pc: c00c000000000000
    lr: c00000000008c798: rcu_process_callbacks+0xf8/0x100
    sp: c00000000207fd80
   msr: 900000001000b033
  current = 0xc000000002056300
  paca    = 0xc0000000016e8000	 irqmask: 0x03	 irq_happened: 0x09
    pid   = 10, comm = ksoftirqd/0
Linux version 6.18.0-rc5-00111-g6fa9041b7177-dirty (manili at manili) (powerpc64le-linux-gcc.br_real (Buildroot 2021.11-18033-g83947c7bb6) 14.3.0, GNU ld (GNU Binutils) 2.43.1) #3 Thu Nov 20 09:33:11 EST 2025
enter ? for help
[link register   ] c00000000008c798 rcu_process_callbacks+0xf8/0x100
[c00000000207fd80] c00000000008c748 rcu_process_callbacks+0xa8/0x100 (unreliable)
[c00000000207fe00] c00000000003f320 handle_softirqs+0x1ec/0x23c
[c00000000207ff00] c00000000003f3a8 run_ksoftirqd+0x38/0x58
[c00000000207ff20] c00000000005f9c4 smpboot_thread_fn+0x1a0/0x1a8
[c00000000207ff80] c00000000005b190 kthread+0x1c0/0x1cc
[c00000000207ffe0] c00000000000b160 start_kernel_thread+0x14/0x18
mon>

The exact addresses in the error vary, but the crash
template is the same. My suspicion is that this is a
core/thread synchronization issue. Do you have any
ideas on this issue and why a simple while loop is able
to solve it?

Bests,
Manili
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20251121/b522ecdb/attachment.htm>


More information about the Linuxppc-dev mailing list