alpha: catch up on architecture Kconfig options
Matt Turner
maintainercover alpha: catch up on architecture Kconfig options
Alpha is missing a long list of Kconfig options that other architectures have picked up over the years, some of them for no better reason than nobody having gone through the list. I diffed the select statements in every other arch/*/Kconfig against arch/alpha/Kconfig and worked through what turned up. This series is the result: two fixes it depends on, and the options that are either free or close to it.
The patches are ordered from least to most contentious, so the front of the series can be applied on its own if the tail needs discussion.
Patches 1-2 are fixes. arch_irqs_disabled_flags() only reported interrupts as disabled at IPL_MAX, but PALcode enters handlers at the IPL of the interrupt being delivered, so a device or timer handler answered that interrupts were enabled. handle_irq() also called irq_to_desc() before irq_enter(), running generic code with the preempt count still saying task context and RCU not yet watching. Both matter on their own; patches 23 and 24 are what made them visible.
Patches 3-11 are one-line selects with no Alpha code behind them:
instrumentation (UBSAN, gcov, kmemleak), EDAC, and four properties Alpha has always had but never declared (LL/SC atomics, hardware multiply, __int128, the existing asm/compiler.h, and the non-overlapping user and kernel address spaces).
Patches 12-17 add a small amount of code: an empty thread_struct whitelist, _PAGE_SPECIAL on a free PTE bit, the page table check helpers, and then the three things that follow from those - the page table helper self test, lockless GUP, and the early memtest. Note that early_memtest() is called from arch_mm_preinit() rather than paging_init(), because Alpha calls paging_init() from setup_arch(), before parse_early_param() has seen the memtest= option.
Patches 18-20 change something visible. Unhandled user faults now print the usual message under the debug.exception-trace sysctl. .eh_frame is
discarded: gcc emits it for Alpha regardless of -fno-asynchronous-unwind-tables, it was allocated in the loaded image, and nothing consumes it, since the stack trace code scans for text addresses rather than unwinding DWARF. That is worth about 1.1MB. With that and the relocation sections placed explicitly, the kernel links with no orphans left, so the last of the three asks the linker to say so.
Patches 21-24 are the ones I expect to draw comment. Patch 22 adds a uapi header, so the perf register numbering is an ABI decision. Patch 23 is SPARSE_IRQ: without it Marvel carries a 12.6MB static irq_desc[] in .data for 32768 possible interrupts, of which a real ES47 uses 87, and the kernel links at a fixed address just above the console reservation where that 12.6MB is the difference between fitting and not. Patch 24 instruments the entry assembly for lockdep hardirq tracking.
Tested with gcc 17 under QEMU (-M clipper -smp 2, an ALPHA_GENERIC build) with PROVE_LOCKING enabled: no splats, early_memtest passes all four patterns over the free memblock ranges with nothing reserved, debug_vm_pgtable validates with no warning, a vmsplice() of an anonymous mapping through pin_user_pages_fast() returns the right data, and an unhandled SIGSEGV prints the new trace line. Patch 23 was tested on an AlphaServer ES47.
Not included, and worth mentioning: ARCH_HAS_KCOV. A kernel with KCOV_INSTRUMENT_ALL boots and runs, but CONFIG_KCOV_SELFTEST panics. The self test deliberately arms kcov with no coverage area so that any instrumented function reached from interrupt context faults, checking that nothing escapes the window before the preempt count says hardirq. On Alpha something does. Patch 2 fixes one such site; the panic survives it, so the entry paths need an audit first.
Also available at:
git://git.kernel.org/pub/scm/linux/kernel/git/mattst88/alpha.git arch-kconfig-options
Matt Turner (24):
alpha: fix arch_irqs_disabled_flags() to treat any raised IPL as
disabled
alpha: enter hardirq context before looking up the irq descriptor
alpha: select ARCH_HAS_UBSAN
alpha: select ARCH_HAS_GCOV_PROFILE_ALL
alpha: select HAVE_DEBUG_KMEMLEAK
alpha: select EDAC_SUPPORT
alpha: select ARCH_SUPPORTS_ATOMIC_RMW
alpha: select ARCH_HAS_FAST_MULTIPLIER
alpha: select ARCH_SUPPORTS_INT128
alpha: select HAVE_ARCH_COMPILER_H
alpha: select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
alpha: add HAVE_ARCH_THREAD_STRUCT_WHITELIST support
alpha: add ARCH_HAS_PTE_SPECIAL support
alpha: add ARCH_SUPPORTS_PAGE_TABLE_CHECK support
alpha: select ARCH_HAS_DEBUG_VM_PGTABLE
alpha: select HAVE_GUP_FAST
alpha: select ARCH_USE_MEMTEST
alpha: select SYSCTL_EXCEPTION_TRACE
alpha: discard .eh_frame and the relocation sections
alpha: select ARCH_WANT_LD_ORPHAN_WARN
alpha: select ARCH_WANT_IRQS_OFF_ACTIVATE_MM
alpha: add HAVE_PERF_REGS and HAVE_PERF_USER_STACK_DUMP support
alpha: select SPARSE_IRQ
alpha: add TRACE_IRQFLAGS_SUPPORT
arch/alpha/Kconfig | 21 ++++++ arch/alpha/include/asm/irqflags.h | 2 +- arch/alpha/include/asm/perf_regs.h | 7 ++ arch/alpha/include/asm/pgtable.h | 21 +++++- arch/alpha/include/asm/processor.h | 7 ++ arch/alpha/include/uapi/asm/perf_regs.h | 34 ++++++++++ arch/alpha/kernel/Makefile | 1 +
arch/alpha/kernel/entry.S | 54 +++++++++++++Matt Turner (24):
alpha: fix arch_irqs_disabled_flags() to treat any raised IPL as
disabled
alpha: enter hardirq context before looking up the irq descriptor
alpha: select ARCH_HAS_UBSAN
alpha: select ARCH_HAS_GCOV_PROFILE_ALL
alpha: select HAVE_DEBUG_KMEMLEAK
alpha: select EDAC_SUPPORT
alpha: select ARCH_SUPPORTS_ATOMIC_RMW
alpha: select ARCH_HAS_FAST_MULTIPLIER
alpha: select ARCH_SUPPORTS_INT128
alpha: select HAVE_ARCH_COMPILER_H
alpha: select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
alpha: add HAVE_ARCH_THREAD_STRUCT_WHITELIST support
alpha: add ARCH_HAS_PTE_SPECIAL support
alpha: add ARCH_SUPPORTS_PAGE_TABLE_CHECK support
alpha: select ARCH_HAS_DEBUG_VM_PGTABLE
alpha: select HAVE_GUP_FAST
alpha: select ARCH_USE_MEMTEST
alpha: select SYSCTL_EXCEPTION_TRACE
alpha: discard .eh_frame and the relocation sections
alpha: select ARCH_WANT_LD_ORPHAN_WARN
alpha: select ARCH_WANT_IRQS_OFF_ACTIVATE_MM
alpha: add HAVE_PERF_REGS and HAVE_PERF_USER_STACK_DUMP support
alpha: select SPARSE_IRQ
alpha: add TRACE_IRQFLAGS_SUPPORT
arch/alpha/Kconfig | 21 ++++++ arch/alpha/include/asm/irqflags.h | 2 +- arch/alpha/include/asm/perf_regs.h | 7 ++ arch/alpha/include/asm/pgtable.h | 21 +++++- arch/alpha/include/asm/processor.h | 7 ++ arch/alpha/include/uapi/asm/perf_regs.h | 34 ++++++++++ arch/alpha/kernel/Makefile | 1 + arch/alpha/kernel/entry.S | 54 +++++++++++++--- arch/alpha/kernel/irq.c | 9 ++- arch/alpha/kernel/irq_alpha.c | 13 ++++ arch/alpha/kernel/perf_regs.c | 86 +++++++++++++++++++++++++ arch/alpha/kernel/vmlinux.lds.S | 11 ++++ arch/alpha/mm/fault.c | 29 +++++++++ arch/alpha/mm/init.c | 5 ++ 14 files changed, 287 insertions(+), 13 deletions(-) create mode 100644 arch/alpha/include/asm/perf_regs.h create mode 100644 arch/alpha/include/uapi/asm/perf_regs.h create mode 100644 arch/alpha/kernel/perf_regs.c
Signature · 1 line
2.54.0
Matt Turner
maintainerPATCH 1/24 alpha: fix arch_irqs_disabled_flags() to treat any raised IPL as disabled
arch_irqs_disabled_flags() only reported interrupts as disabled at IPL_MAX, but the kernel is not the only thing that sets the IPL. PALcode raises PS.IPL to the level of the interrupt being delivered before entering the handler, so a handler entered for a device interrupt runs at IPL_DEV0 or IPL_DEV1, and the timer at IPL_TIMER. Interrupts at and below that level are blocked, but arch_irqs_disabled() answered that interrupts were enabled.
Treat any IPL above IPL_MIN, the level arch_local_irq_enable() restores, as interrupts disabled. This matters as soon as lockdep is asked to track hardirq state, where irqs_disabled() is expected to be true inside an interrupt handler.
--- arch/alpha/include/asm/irqflags.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/alpha/include/asm/irqflags.h +1 -1
@@ -57,7 +57,7 @@ static inline void arch_local_irq_restore(unsigned long flags)static inline bool arch_irqs_disabled_flags (unsigned long flags) { -return (flags &7 ) ==IPL_MAX ; +return (flags &7 ) >IPL_MIN ; }static inline bool arch_irqs_disabled (void )
Signature · 1 line
2.54.0
Magnus Lindholm
maintainerRe: [PATCH 01/24] alpha: fix arch_irqs_disabled_flags() to treat any raised IPL as disabled
Hi, Matt
Quoted 9 lines · Matt Turner
arch_irqs_disabled_flags()only reported interrupts as disabled atIPL_MAX, but the kernel is not the only thing that sets the IPL. PALcode raises PS.IPL to the level of the interrupt being delivered before entering the handler, so a handler entered for a device interrupt runs atIPL_DEV0orIPL_DEV1, and the timer atIPL_TIMER. Interrupts at and below that level are blocked, butarch_irqs_disabled()answered that interrupts were enabled.
Quoted 5 lines
Treat any IPL above
IPL_MIN, the levelarch_local_irq_enable()restores, as interrupts disabled. This matters as soon as lockdep is asked to track hardirq state, whereirqs_disabled()is expected to be true inside an interrupt handler.
Hi Matt,
Thanks for the explanation, but I still do not think that treating every raised IPL as "IRQs disabled" is correct.
The Alpha Architecture Reference Manual, Section 19.1.2, says that an interrupt is delivered when its IPL is greater than the IPL in the current PS. Table 19-1 in Section 19.2 documents the OSF PAL IPL range from 0 to 7. An intermediate IPL therefore masks only interrupts at or below that priority; higher-priority interrupts remain enabled. Only IPL 7 masks all OS-visible interrupt levels.
The 21164 Hardware Reference Manual, Section 4.15.3, states the same
rule: an interrupt is enabled when the current IPL is less than the interrupt's target IPL.
Thus, IPL_MIN means interrupts are enabled, an intermediate IPL is only a partial mask, and IPL_MAX masks all interrupt levels.
I therefore think arch_irqs_disabled_flags() should retain the meaning of fully disabled local IRQs:
return (flags & 7) == IPL_MAX;
If lockdep or generic entry requires IRQs to be disabled on entry, I think the entry code should first raise the live IPL to IPL_MAX, rather than report an intermediate IPL as fully disabled.
Regards,
Magnus
Matt Turner
maintainerPATCH 2/24 alpha: enter hardirq context before looking up the irq descriptor
In reply to Matt Turnerhandle_irq() called irq_to_desc() before irq_enter(), so that lookup ran with the preempt count still saying task context and with RCU not yet watching. Generic code called from an interrupt handler should see hardirq context, and irq_to_desc() is more than an array index once SPARSE_IRQ is in use.
Move irq_enter() to the top of the function and add the matching irq_exit() to the invalid interrupt path.
--- arch/alpha/kernel/irq.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
arch/alpha/kernel/irq.c +6 -3
@@ -107,18 +107,21 @@ handle_irq(int irq)* handled by some other CPU. (or is disabled) */ static unsigned int illegal_count=0 ; -struct irq_desc *desc =irq_to_desc (irq); - +struct irq_desc *desc; + +irq_enter (); + + desc =irq_to_desc (irq);if (!desc || ((unsigned ) irq >ACTUAL_NR_IRQS && illegal_count <MAX_ILLEGAL_IRQS )) { irq_err_count++; illegal_count++;printk (KERN_CRIT "device_interrupt: invalid interrupt %d\n" , irq); +irq_exit ();return ; } -irq_enter ();generic_handle_irq_desc (desc);irq_exit (); }
Signature · 1 line
2.54.0
Magnus Lindholm
maintainerRe: [PATCH 02/24] alpha: enter hardirq context before looking up the irq descriptor
Hi Matt,
Quoted 46 lines · Matt Turner
handle_irq()calledirq_to_desc()beforeirq_enter(), so that lookup ran with the preempt count still saying task context and with RCU not yet watching. Generic code called from an interrupt handler should see hardirq context, andirq_to_desc()is more than an array index onceSPARSE_IRQis in use.Move
irq_enter()to the top of the function and add the matchingirq_exit()to the invalid interrupt path.Assisted-by Claude:claude-opus-5Signed-off-by Matt Turner <[email protected]>--- arch/alpha/kernel/irq.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)arch/alpha/kernel/irq.c +6
-4@@ -107,18 +107,21 @@ handle_irq(int irq)* handled by some other CPU. (or is disabled) */ static unsigned int illegal_count=0 ; -struct irq_desc *desc =irq_to_desc (irq); - +struct irq_desc *desc; + +irq_enter (); + + desc =irq_to_desc (irq);if (!desc || ((unsigned ) irq >ACTUAL_NR_IRQS && illegal_count <MAX_ILLEGAL_IRQS )) { irq_err_count++; illegal_count++;printk (KERN_CRIT "device_interrupt: invalid interrupt %d\n" , irq); +irq_exit ();return ; } -irq_enter ();generic_handle_irq_desc (desc);irq_exit (); } --
Quoted 2 lines
2.54.0
Going over this code again, I noticed what may be redundant hardirq accounting in the existing device-interrupt path.
For type 3 interrupts, do_entInt() already wraps alpha_mv.device_interrupt() in irq_enter()/irq_exit(). The platform dispatcher then calls handle_irq(), which enters and exits hardirq context again. Therefore, irq_to_desc() is already reached in hardirq context before this patch. The patch moves it from nesting level one to level two rather than from task context to hardirq context.
The RTC path does not have the outer irq_enter(), so the change is needed there.
Would it be cleaner for do_entInt() to own the hardirq context for both paths and remove the pair from handle_irq()? Or is there another caller which requires handle_irq() to manage it itself?
I tested the patch on a two-CPU UP2000 with lockdep, IRQ flag tracing, and sparse IRQs enabled. SCSI and network interrupts operated normally, I observed no lockdep or IRQ-related warnings, and debug_locks remained enabled in /proc/lockdep_stats.
Regards
Magnus
Matt Turner
maintainerRe: [PATCH 02/24] alpha: enter hardirq context before looking up the irq descriptor
Quoted 66 lines · Magnus Lindholm
Hi Matt,
Quoted 46 lines · Matt Turner
handle_irq()calledirq_to_desc()beforeirq_enter(), so that lookup ran with the preempt count still saying task context and with RCU not yet watching. Generic code called from an interrupt handler should see hardirq context, andirq_to_desc()is more than an array index onceSPARSE_IRQis in use.Move
irq_enter()to the top of the function and add the matchingirq_exit()to the invalid interrupt path.Assisted-by Claude:claude-opus-5Signed-off-by Matt Turner <[email protected]>--- arch/alpha/kernel/irq.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)arch/alpha/kernel/irq.c +6
-4@@ -107,18 +107,21 @@ handle_irq(int irq)* handled by some other CPU. (or is disabled) */ static unsigned int illegal_count=0 ; -struct irq_desc *desc =irq_to_desc (irq); - +struct irq_desc *desc; + +irq_enter (); + + desc =irq_to_desc (irq);if (!desc || ((unsigned ) irq >ACTUAL_NR_IRQS && illegal_count <MAX_ILLEGAL_IRQS )) { irq_err_count++; illegal_count++;printk (KERN_CRIT "device_interrupt: invalid interrupt %d\n" , irq); +irq_exit ();return ; } -irq_enter ();generic_handle_irq_desc (desc);irq_exit (); } --Quoted 2 lines
2.54.0
Going over this code again, I noticed what may be redundant hardirq accounting in the existing device-interrupt path.
For type 3 interrupts,
do_entInt()already wrapsalpha_mv.device_interrupt()in irq_enter()/irq_exit(). The platform dispatcher then callshandle_irq(), which enters and exits hardirq context again. Therefore,irq_to_desc()is already reached in hardirq context before this patch. The patch moves it from nesting level one to level two rather than from task context to hardirq context.The RTC path does not have the outer
irq_enter(), so the change is needed there.
Quoted 8 lines
Would it be cleaner for
do_entInt()to own the hardirq context for both paths and remove the pair fromhandle_irq()? Or is there another caller which requireshandle_irq()to manage it itself?I tested the patch on a two-CPU UP2000 with lockdep, IRQ flag tracing, and sparse IRQs enabled. SCSI and network interrupts operated normally, I observed no lockdep or IRQ-related warnings, and
debug_locksremained enabled in/proc/lockdep_stats.
Hi Magnus,
Good question. Yes, do_entInt() should own irq_enter()/irq_exit() for the RTC and device-interrupt cases too, same as it already does for IPI, machine-check, and perf. RTC and device-interrupt are the only two that don't, and only because handle_irq() does it internally.
There's a wrinkle. A bunch of device_interrupt() implementations call handle_irq() in a loop over several pending vectors: sys_takara.c, sys_eiger.c, sys_alcor.c, sys_dp264.c, sys_cabriolet.c, sys_noritake.c, sys_mikasa.c, sys_rx164.c, irq_pyxis.c, irq_i8259.c. Right now each of those handle_irq() calls enters and exits hardirq context on its own, so one hardware interrupt that demuxes to N IRQs does N enter/exit pairs. Moving the pair up to do_entInt() collapses that to one per hardware interrupt, matching how the IPI/machine-check/perf cases already work.
I don't see anything in the per-machine device_interrupt() bodies that needs task context before the first handle_irq() call -- it's all vector decode. But I've only got one Marvel box to boot-test on, so I'm not comfortable folding the reshuffle into this patch without at least reading through the other machine types more carefully.
I'll send it as a follow-up on top of the series rather than reworking patch 2. Easier to drop if something turns out to care. Let me know if you think that's wrong.
Thanks,
Matt
Magnus Lindholm
maintainerRe: [PATCH 02/24] alpha: enter hardirq context before looking up the irq descriptor
Hi Matt,
Quoted 100 lines · Matt Turner
Quoted 66 lines · Magnus Lindholm
Hi Matt,
Quoted 46 lines · Matt Turner
handle_irq()calledirq_to_desc()beforeirq_enter(), so that lookup ran with the preempt count still saying task context and with RCU not yet watching. Generic code called from an interrupt handler should see hardirq context, andirq_to_desc()is more than an array index onceSPARSE_IRQis in use.Move
irq_enter()to the top of the function and add the matchingirq_exit()to the invalid interrupt path.Assisted-by Claude:claude-opus-5Signed-off-by Matt Turner <[email protected]>--- arch/alpha/kernel/irq.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)arch/alpha/kernel/irq.c +6
-4@@ -107,18 +107,21 @@ handle_irq(int irq)* handled by some other CPU. (or is disabled) */ static unsigned int illegal_count=0 ; -struct irq_desc *desc =irq_to_desc (irq); - +struct irq_desc *desc; + +irq_enter (); + + desc =irq_to_desc (irq);if (!desc || ((unsigned ) irq >ACTUAL_NR_IRQS && illegal_count <MAX_ILLEGAL_IRQS )) { irq_err_count++; illegal_count++;printk (KERN_CRIT "device_interrupt: invalid interrupt %d\n" , irq); +irq_exit ();return ; } -irq_enter ();generic_handle_irq_desc (desc);irq_exit (); } --Quoted 2 lines
2.54.0
Going over this code again, I noticed what may be redundant hardirq accounting in the existing device-interrupt path.
For type 3 interrupts,
do_entInt()already wrapsalpha_mv.device_interrupt()in irq_enter()/irq_exit(). The platform dispatcher then callshandle_irq(), which enters and exits hardirq context again. Therefore,irq_to_desc()is already reached in hardirq context before this patch. The patch moves it from nesting level one to level two rather than from task context to hardirq context.The RTC path does not have the outer
irq_enter(), so the change is needed there.Quoted 8 lines
Would it be cleaner for
do_entInt()to own the hardirq context for both paths and remove the pair fromhandle_irq()? Or is there another caller which requireshandle_irq()to manage it itself?I tested the patch on a two-CPU UP2000 with lockdep, IRQ flag tracing, and sparse IRQs enabled. SCSI and network interrupts operated normally, I observed no lockdep or IRQ-related warnings, and
debug_locksremained enabled in/proc/lockdep_stats.Hi Magnus,
Good question. Yes,
do_entInt()should own irq_enter()/irq_exit() for the RTC and device-interrupt cases too, same as it already does for IPI, machine-check, and perf. RTC and device-interrupt are the only two that don't, and only becausehandle_irq()does it internally.There's a wrinkle. A bunch of
device_interrupt()implementations callhandle_irq()in a loop over several pending vectors:sys_takara.c,sys_eiger.c,sys_alcor.c,sys_dp264.c,sys_cabriolet.c,sys_noritake.c,sys_mikasa.c,sys_rx164.c,irq_pyxis.c,irq_i8259.c. Right now each of thosehandle_irq()calls enters and exits hardirq context on its own, so one hardware interrupt that demuxes to N IRQs does N enter/exit pairs. Moving the pair up todo_entInt()collapses that to one per hardware interrupt, matching how the IPI/machine-check/perf cases already work.I don't see anything in the per-machine
device_interrupt()bodies that needs task context before the firsthandle_irq()call -- it's all vector decode. But I've only got one Marvel box to boot-test on, so I'm not comfortable folding the reshuffle into this patch without at least reading through the other machine types more carefully.
Quoted 4 lines
I'll send it as a follow-up on top of the series rather than reworking patch 2. Easier to drop if something turns out to care. Let me know if you think that's wrong.
That sounds like a good plan, we treat that as a follow-up once this has landed.
Regards
Magnus
Matt Turner
maintainerPATCH 3/24 alpha: select ARCH_HAS_UBSAN
In reply to Matt TurnerGCC's undefined behavior sanitizer has no architecture-specific runtime requirements. Enable it for Alpha to allow UBSAN instrumentation of the kernel.
--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +1 -0
@@ -5,6 +5,7 @@ config ALPHA select ARCH_32BIT_USTAT_F_TINODE select ARCH_HAS_CURRENT_STACK_POINTER select ARCH_HAS_DMA_OPS if PCI + select ARCH_HAS_UBSAN select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_SERIO select ARCH_MODULE_NEEDS_WEAK_PER_CPU if SMP
Signature · 1 line
2.54.0
Re: [PATCH 03/24] alpha: select ARCH_HAS_UBSAN
Hi Matt,
Quoted 5 lines · Matt Turner
GCC's undefined behavior sanitizer has no architecture-specific runtime requirements. Enable it for Alpha to allow UBSAN instrumentation of the kernel.
I tested this patch on top of my rebased Alpha GENERIC_ENTRY patch on an AlphaServer ES40. The kernel built and booted successfully with CONFIG_UBSAN=y, and the UBSAN instrumentation is active.
CONFIG_UBSAN_ALIGNMENT did expose a misaligned struct bucket_table allocation in lib/rhashtable.c. This appears to be a generic rhashtable allocation-alignment issue rather than an Alpha UBSAN problem.
Regards,
Magnus
Re: [PATCH 03/24] alpha: select ARCH_HAS_UBSAN
Quoted 9 lines · Magnus Lindholm
Quoted 5 lines · Matt Turner
GCC's undefined behavior sanitizer has no architecture-specific runtime requirements. Enable it for Alpha to allow UBSAN instrumentation of the kernel.
I tested this patch on top of my rebased Alpha
GENERIC_ENTRYpatch on an AlphaServer ES40. The kernel built and booted successfully withCONFIG_UBSAN=y, and the UBSAN instrumentation is active.
So have I, on an XP1000 and ES45.
Quoted 3 lines
CONFIG_UBSAN_ALIGNMENTdid expose a misaligned structbucket_tableallocation inlib/rhashtable.c. This appears to be a generic rhashtable allocation-alignment issue rather than an Alpha UBSAN problem.
But in my case the kernel vomited copious misaligned access reports, so many that it took quite a few minutes to boot and I lost much of the kernel log before disks were mounted. A few examples that were recorded later in the boot on the ES45:
Sep 03 21:12:36 electro kernel: UBSAN: misaligned-access in net/core/dev.c:1401:2 Sep 03 21:12:36 electro kernel: member access within misaligned address (____ptrval____) for type 'struct net_device' Sep 03 21:12:36 electro kernel: which requires 64 byte alignment
Sep 03 21:12:36 electro kernel: UBSAN: misaligned-access in kernel/signal.c:4362:4 Sep 03 21:12:36 electro kernel: member access within misaligned address 0000000058e1e939 for type 'struct task_struct' Sep 03 21:12:36 electro kernel: which requires 64 byte alignment
Sep 03 21:13:04 electro kernel: UBSAN: misaligned-access in drivers/net/ethernet/intel/e100.c:1941:36 Sep 03 21:13:04 electro kernel: member access within misaligned address 000000001c866fa6 for type 'struct rfd' Sep 03 21:13:04 electro kernel: which requires 4 byte alignment
Interestingly "kernel unaligned acc" in /proc/cpuinfo remained at zero, which really makes me wonder whether these reports are all false-positives.
This kernel was cross-compiled with: "alpha-linux-gnu-gcc (Debian 14.2.0-19)"
Cheers,
Michael.
Magnus Lindholm
maintainerRe: [PATCH 03/24] alpha: select ARCH_HAS_UBSAN
Hi Michael,
Quoted 31 lines · Michael Cree
Quoted 9 lines · Magnus Lindholm
Quoted 5 lines · Matt Turner
GCC's undefined behavior sanitizer has no architecture-specific runtime requirements. Enable it for Alpha to allow UBSAN instrumentation of the kernel.
I tested this patch on top of my rebased Alpha
GENERIC_ENTRYpatch on an AlphaServer ES40. The kernel built and booted successfully withCONFIG_UBSAN=y, and the UBSAN instrumentation is active.So have I, on an XP1000 and ES45.
Quoted 3 lines
CONFIG_UBSAN_ALIGNMENTdid expose a misaligned structbucket_tableallocation inlib/rhashtable.c. This appears to be a generic rhashtable allocation-alignment issue rather than an Alpha UBSAN problem.But in my case the kernel vomited copious misaligned access reports, so many that it took quite a few minutes to boot and I lost much of the kernel log before disks were mounted. A few examples that were recorded later in the boot on the ES45:
Sep 03 21:12:36 electro kernel: UBSAN: misaligned-access in net/core/dev.c:1401:2 Sep 03 21:12:36 electro kernel: member access within misaligned address (____ptrval____) for type 'struct net_device' Sep 03 21:12:36 electro kernel: which requires 64 byte alignmentSep 03 21:12:36 electro kernel: UBSAN: misaligned-access in kernel/signal.c:4362:4 Sep 03 21:12:36 electro kernel: member access within misaligned address 0000000058e1e939 for type 'struct task_struct' Sep 03 21:12:36 electro kernel: which requires 64 byte alignment
Quoted 8 lines
Sep 03 21:13:04 electro kernel: UBSAN: misaligned-access in drivers/net/ethernet/intel/e100.c:1941:36 Sep 03 21:13:04 electro kernel: member access within misaligned address 000000001c866fa6 for type 'struct rfd' Sep 03 21:13:04 electro kernel: which requires 4 byte alignmentInterestingly "kernel unaligned acc" in
/proc/cpuinforemained at zero, which really makes me wonder whether these reports are all false-positives.
Good question, had to dig deeper here,
Not false positives - real UB, but harmless, and I tracked down why. for_each_thread() and for_each_netdev_rcu() are list_for_each_entry
macros: their loop computes container_of() once extra per traversal, unconditionally, to test for end-of-list. That test compares against the list head (&signal->thread_head, &net->dev_base_head), which lives in a different struct entirely (signal_struct, net) - not task_struct/net_device. At the real end of the list, container_of() still subtracts offsetof(task_struct, thread_node) from that head's address anyway, producing a pointer that looks nothing like a real task_struct. It's used only for a pointer-value comparison, never dereferenced - confirmed with a printk inside find_alive_thread()'s loop body that never fired even when UBSAN caught the same line. Zero unaligned-access count follows directly: nothing ever loads or stores through it.
If it's worth fixing rather than living with: the sentinel comparison in list_entry_rcu()/list_for_each_entry_rcu() only needs the raw pointer value, not a type-checked container_of(). Splitting that one use into an unchecked pointer subtraction for the loop-termination test, keeping checked container_of() for the real element on every other iteration, would remove the false trigger without losing any real coverage. Not alpha-specific, so probably wants a wider list than this one if someone wants to pick it up.
e100.c's struct rfd is unrelated: casts skb->data (not guaranteed 4-byte aligned) to struct rfd *, writes via put_unaligned_le32() - UB in the cast, safe access after.
Not alpha-specific either - list_for_each_entry is everywhere. CONFIG_UBSAN_ALIGNMENT just defaults on for us (!HAVE_EFFICIENT_UNALIGNED_ACCESS) and off elsewhere. Confirmed on the UP2000+ rather than assumed: 7 reports, "kernel unaligned acc: 0" never moved.
Magnus
Re: [PATCH 03/24] alpha: select ARCH_HAS_UBSAN
Hi Magnus,
Quoted 20 lines · Magnus Lindholm
Quoted 19 lines · Michael Cree
Quoted 9 lines · Magnus Lindholm
Quoted 5 lines · Matt Turner
GCC's undefined behavior sanitizer has no architecture-specific runtime requirements. Enable it for Alpha to allow UBSAN instrumentation of the kernel.
I tested this patch on top of my rebased Alpha
GENERIC_ENTRYpatch on an AlphaServer ES40. The kernel built and booted successfully withCONFIG_UBSAN=y, and the UBSAN instrumentation is active.So have I, on an XP1000 and ES45.
Quoted 3 lines
CONFIG_UBSAN_ALIGNMENTdid expose a misaligned structbucket_tableallocation inlib/rhashtable.c. This appears to be a generic rhashtable allocation-alignment issue rather than an Alpha UBSAN problem.But in my case the kernel vomited copious misaligned access reports,
Quoted 7 lines
Quoted 4 lines
Interestingly "kernel unaligned acc" in
/proc/cpuinforemained at zero, which really makes me wonder whether these reports are all false-positives.Good question, had to dig deeper here,
Not false positives - real UB, but harmless, and I tracked down why.
Thanks for taking time to find the explanation. So, technical UB but no consequence for operation.
Cheers,
Michael.
Matt Turner
maintainerPATCH 4/24 alpha: select ARCH_HAS_GCOV_PROFILE_ALL
In reply to Matt TurnerGCC's gcov instrumentation (-fprofile-arcs -ftest-coverage) has no architecture-specific runtime requirements. Enable GCOV_PROFILE_ALL support for Alpha to allow whole-kernel code coverage analysis.
--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +1 -0
@@ -5,6 +5,7 @@ config ALPHA select ARCH_32BIT_USTAT_F_TINODE select ARCH_HAS_CURRENT_STACK_POINTER select ARCH_HAS_DMA_OPS if PCI + select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_UBSAN select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_SERIO
Signature · 1 line
2.54.0
Re: [PATCH 04/24] alpha: select ARCH_HAS_GCOV_PROFILE_ALL
Hi Matt,
Quoted 24 lines · Matt Turner
GCC's gcov instrumentation (-fprofile-arcs -ftest-coverage) has no architecture-specific runtime requirements. Enable
GCOV_PROFILE_ALLsupport for Alpha to allow whole-kernel code coverage analysis.Assisted-by Claude:claude-opus-4-6Signed-off-by Matt Turner <[email protected]>--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)arch/alpha/Kconfig +1
-1@@ -5,6 +5,7 @@ config ALPHA select ARCH_32BIT_USTAT_F_TINODE select ARCH_HAS_CURRENT_STACK_POINTER select ARCH_HAS_DMA_OPS if PCI + select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_UBSAN select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_SERIO --
Quoted 2 lines
2.54.0
I built and booted this on a two-CPU UP2000 with GCOV_KERNEL and GCOV_PROFILE_ALL enabled. Debugfs exposed 1226 .gcda files, including the expected arch/alpha objects. I observed no GCOV-related errors or kernel warnings.
This also appears to warrant changing Alpha from "TODO" to "ok" in Documentation/features/debug/gcov-profile-all/arch-support.txt.
Regards,
Magnus
Matt Turner
maintainerPATCH 5/24 alpha: select HAVE_DEBUG_KMEMLEAK
In reply to Matt TurnerKmemleak needs no architecture support beyond the standard linker script symbols for the data and bss sections, which Alpha already provides, and a scan of the kernel stacks, which is done generically.
--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +1 -0
@@ -17,6 +17,7 @@ config ALPHA select PCI_DOMAINS if PCI select PCI_SYSCALL if PCI select HAVE_ASM_MODVERSIONS + select HAVE_DEBUG_KMEMLEAK select HAVE_PAGE_SIZE_8KB select HAVE_PCSPKR_PLATFORM select HAVE_PERF_EVENTS
Signature · 1 line
2.54.0
Re: [PATCH 05/24] alpha: select HAVE_DEBUG_KMEMLEAK
Hi Matt,
Quoted 5 lines · Matt Turner
Kmemleak needs no architecture support beyond the standard linker script symbols for the data and bss sections, which Alpha already provides, and a scan of the kernel stacks, which is done generically.
I tested this on an AlphaServer ES40 with CONFIG_DEBUG_KMEMLEAK=y. The kernel built and booted successfully, and a manual kmemleak scan completed normally.
The scan reported three suspected allocations from the sym53c8xx_2 driver. These appear unrelated to this patch and may be false positives caused by references stored in DMA-coherent memory. Either way, the patch looks good to me.
Matt Turner
maintainerPATCH 6/24 alpha: select EDAC_SUPPORT
In reply to Matt TurnerThe EDAC core builds and works on Alpha; it only needs the architecture to declare support. There is no Alpha memory controller driver yet, but the core is what a future driver, or the existing machine check error decoding in err_ev6.c and err_ev7.c, would report through.
--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +1 -0
@@ -30,6 +30,7 @@ config ALPHA select ARCH_WANT_IPC_PARSE_VERSION select ARCH_HAVE_NMI_SAFE_CMPXCHG select AUDIT_ARCH + select EDAC_SUPPORT select GENERIC_CPU_VULNERABILITIES select GENERIC_SMP_IDLE_THREAD select HAS_IOPORT
Signature · 1 line
2.54.0
Re: [PATCH 06/24] alpha: select EDAC_SUPPORT
Hi Matt,
Quoted 6 lines · Matt Turner
The EDAC core builds and works on Alpha; it only needs the architecture to declare support. There is no Alpha memory controller driver yet, but the core is what a future driver, or the existing machine check error decoding in
err_ev6.canderr_ev7.c, would report through.
I tested this on an AlphaServer ES40 with CONFIG_RAS=y and CONFIG_EDAC=y. The kernel built and booted successfully, and the generic EDAC sysfs hierarchy was created under /sys/devices/system/edac/mc.
Possibly we could adapt this to have EDAC support, I know it was mentioned on the list:
https://lore.kernel.org/linux-alpha/[email protected]/
Either way, this looks good to me,
Matt Turner
maintainerPATCH 7/24 alpha: select ARCH_SUPPORTS_ATOMIC_RMW
In reply to Matt TurnerAlpha has native LL/SC instructions (LDL_L/STL_C, LDQ_L/STQ_C) that provide atomic read-modify-write capability, and already selects ARCH_HAVE_NMI_SAFE_CMPXCHG.
Selecting ARCH_SUPPORTS_ATOMIC_RMW enables MUTEX_SPIN_ON_OWNER and RWSEM_SPIN_ON_OWNER on SMP, allowing optimistic spinning on contended locks rather than immediately sleeping.
--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +1 -0
@@ -12,6 +12,7 @@ config ALPHA select ARCH_MODULE_NEEDS_WEAK_PER_CPU if SMP select ARCH_NO_PREEMPT select ARCH_NO_SG_CHAIN + select ARCH_SUPPORTS_ATOMIC_RMW select ARCH_USE_CMPXCHG_LOCKREF select FORCE_PCI select PCI_DOMAINS if PCI
Signature · 1 line
2.54.0
Re: [PATCH 07/24] alpha: select ARCH_SUPPORTS_ATOMIC_RMW
Hi Matt,
Quoted 9 lines · Matt Turner
Alpha has native LL/SC instructions (LDL_L/STL_C, LDQ_L/STQ_C) that provide atomic read-modify-write capability, and already selects
ARCH_HAVE_NMI_SAFE_CMPXCHG.Selecting
ARCH_SUPPORTS_ATOMIC_RMWenablesMUTEX_SPIN_ON_OWNERandRWSEM_SPIN_ON_OWNERon SMP, allowing optimistic spinning on contended locks rather than immediately sleeping.
I tested this on an AlphaServer ES40 with four CPUs and CONFIG_PROVE_LOCKING=y, CONFIG_DEBUG_MUTEXES=y, and CONFIG_DEBUG_RWSEMS=y.
Both the mutex_lock and rwsem_lock locktorture tests completed successfully under contention across all four CPUs.
Regards,
Magnus
Matt Turner
maintainerPATCH 8/24 alpha: select ARCH_HAS_FAST_MULTIPLIER
In reply to Matt TurnerAll Alpha CPUs have hardware integer multiply (MULL/MULQ). EV4 and EV5 implement it in microcode; EV56 and later have fast single-cycle multiply. Since no EV4 system is likely to run a modern kernel, select this unconditionally to enable multiply-based fast paths in hweight and string routines.
--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +1 -0
@@ -5,6 +5,7 @@ config ALPHA select ARCH_32BIT_USTAT_F_TINODE select ARCH_HAS_CURRENT_STACK_POINTER select ARCH_HAS_DMA_OPS if PCI + select ARCH_HAS_FAST_MULTIPLIER select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_UBSAN select ARCH_MIGHT_HAVE_PC_PARPORT
Signature · 1 line
2.54.0
Re: [PATCH 08/24] alpha: select ARCH_HAS_FAST_MULTIPLIER
Hi Matt,
Quoted 7 lines · Matt Turner
All Alpha CPUs have hardware integer multiply (MULL/MULQ). EV4 and EV5 implement it in microcode; EV56 and later have fast single-cycle multiply. Since no EV4 system is likely to run a modern kernel, select this unconditionally to enable multiply-based fast paths in hweight and string routines.
I tested this on an AlphaServer ES40 (EV67). A test module exercised the multiplication-based memchr_inv() path with offsets 0 through 7, buffer lengths from 17 through 257 bytes, four fill values, and mismatches at the beginning, middle, and end of each buffer. All tests passed.
On EV67, hweight uses the native CTPOP instruction, so the generic multiplication-based hweight path is not selected by this configuration.
Regards,
Magnus
Matt Turner
maintainerPATCH 9/24 alpha: select ARCH_SUPPORTS_INT128
In reply to Matt Turnergcc supports __int128 on Alpha, and the 64x64 to 128-bit multiply that the users in the scheduler and in lib/ care about maps onto mulq/umulh rather than an out-of-line libgcc helper.
Gate the select on CC_HAS_INT128 as the other 64-bit architectures do.
--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +1 -0
@@ -14,6 +14,7 @@ config ALPHA select ARCH_NO_PREEMPT select ARCH_NO_SG_CHAIN select ARCH_SUPPORTS_ATOMIC_RMW + select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 select ARCH_USE_CMPXCHG_LOCKREF select FORCE_PCI select PCI_DOMAINS if PCI
Signature · 1 line
2.54.0
Re: [PATCH 09/24] alpha: select ARCH_SUPPORTS_INT128
Hi Matt,
Quoted 7 lines · Matt Turner
gcc supports
__int128on Alpha, and the 64x64 to 128-bit multiply that the users in the scheduler and inlib/care about maps onto mulq/umulh rather than an out-of-line libgcc helper.Gate the select on
CC_HAS_INT128as the other 64-bit architectures do.
I tested this on an AlphaServer ES40 with CONFIG_ARCH_SUPPORTS_INT128=y. The kernel built and booted successfully, and the bits KUnit suite passed, including genmask_u128_test:
# bits-test: pass:6 fail:0 skip:0 total:6
ok 1 bits-test
Matt Turner
maintainerPATCH 10/24 alpha: select HAVE_ARCH_COMPILER_H
In reply to Matt TurnerAlpha already provides asm/compiler.h (wrapping uapi/asm/compiler.h) which defines architecture-specific compiler intrinsics like __kernel_cmpbge, __kernel_cttz, __kernel_ctlz, and __kernel_ctpop.
Selecting HAVE_ARCH_COMPILER_H causes linux/compiler_types.h to include asm/compiler.h, making these definitions available consistently.
--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +1 -0
@@ -19,6 +19,7 @@ config ALPHA select FORCE_PCI select PCI_DOMAINS if PCI select PCI_SYSCALL if PCI + select HAVE_ARCH_COMPILER_H select HAVE_ASM_MODVERSIONS select HAVE_DEBUG_KMEMLEAK select HAVE_PAGE_SIZE_8KB
Signature · 1 line
2.54.0
Re: [PATCH 10/24] alpha: select HAVE_ARCH_COMPILER_H
Hi Matt,
Quoted 7 lines · Matt Turner
Alpha already provides
asm/compiler.h(wrappinguapi/asm/compiler.h) which defines architecture-specific compiler intrinsics like__kernel_cmpbge,__kernel_cttz,__kernel_ctlz, and__kernel_ctpop.Selecting
HAVE_ARCH_COMPILER_Hcauseslinux/compiler_types.hto includeasm/compiler.h, making these definitions available consistently.
I tested this on an AlphaServer ES40. The kernel built and booted successfully with CONFIG_HAVE_ARCH_COMPILER_H=y, and the in-tree test_bitops module completed without errors.
While testing this patch, the FFS KUnit suite exposed a separate, pre-existing issue in the EV67 Alpha fls64() implementation. The zero-input tests failed with the contradictory diagnostic:
Expected fls64(input) == 0, but
fls64(input) == 0 (0x0)
The EV67 implementation passes zero to __kernel_ctlz(), which GCC maps to __builtin_clzl(). The result of __builtin_clzl(0) is undefined, so the compiler can optimize the comparison inconsistently with the value returned by the Alpha ctlz instruction.
I verified the diagnosis by changing fls64() to handle zero explicitly:
return word ? 64 - __kernel_ctlz(word) : 0;
With that change, the FFS KUnit result improved from 8/9 to 9/9 tests passing.
This appears unrelated to this patch, since asm/bitops.h already included asm/compiler.h directly before HAVE_ARCH_COMPILER_H was selected. I am mentioning it here since this patch led to the issue being discovered.
Matt Turner
maintainerPATCH 11/24 alpha: select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
In reply to Matt TurnerAlpha has a clean split between user and kernel address spaces: user space occupies 0x0000000000000000-0x000003ffffffffff (TASK_SIZE), while kernel space uses KSEG and vmalloc regions near the top of the 64-bit address space. These are strictly non-overlapping.
This enables optimizations in BPF and tracing that can skip address range checks when user and kernel pointers are distinguishable by address alone.
--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +1 -0
@@ -7,6 +7,7 @@ config ALPHA select ARCH_HAS_DMA_OPS if PCI select ARCH_HAS_FAST_MULTIPLIER select ARCH_HAS_GCOV_PROFILE_ALL + select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE select ARCH_HAS_UBSAN select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_SERIO
Signature · 1 line
2.54.0
Re: [PATCH 11/24] alpha: select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
Hi Matt,
Quoted 10 lines · Matt Turner
Alpha has a clean split between user and kernel address spaces: user space occupies 0x0000000000000000-0x000003ffffffffff (
TASK_SIZE), while kernel space uses KSEG and vmalloc regions near the top of the 64-bit address space. These are strictly non-overlapping.This enables optimizations in BPF and tracing that can skip address range checks when user and kernel pointers are distinguishable by address alone.
I tested this on an AlphaServer ES40. The kernel built and booted successfully with CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y.
I verified that userspace mappings were below TASK_SIZE (0x0000040000000000), while the kernel text was in the high Alpha kernel address range:
0x000002000025a000 highest observed userspace mapping 0xfffffc0000310000 _stext
This confirms that the observed user and kernel virtual address ranges are non-overlapping.
Matt Turner
maintainerPATCH 12/24 alpha: add HAVE_ARCH_THREAD_STRUCT_WHITELIST support
In reply to Matt TurnerAlpha's thread_struct is empty (all per-thread state lives in thread_info), so the whitelist is trivially empty. This is more explicit than the generic fallback, which computes the full thread_struct size as copyable.
--- arch/alpha/Kconfig | 1 + arch/alpha/include/asm/processor.h | 7 +++++++ 2 files changed, 8 insertions(+)
arch/alpha/Kconfig +1 -0
@@ -42,6 +42,7 @@ config ALPHA select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_SECCOMP select HAVE_ARCH_SECCOMP_FILTER + select HAVE_ARCH_THREAD_STRUCT_WHITELIST select HAVE_ARCH_TRACEHOOK select HAVE_MOD_ARCH_SPECIFIC select LOCK_MM_AND_FIND_VMA
arch/alpha/include/asm/processor.h +7 -0
@@ -26,6 +26,13 @@struct thread_struct { };#define INIT_THREAD { } +static inline void arch_thread_struct_whitelist (unsigned long *offset, +unsigned long *size) +{ + *offset =0 ; + *size =0 ; +} +/* Do necessary setup to start up a newly executed thread. */ struct pt_regs ;extern void start_thread (struct pt_regs *,unsigned long ,unsigned long );
Signature · 1 line
2.54.0
Re: [PATCH 12/24] alpha: add HAVE_ARCH_THREAD_STRUCT_WHITELIST support
Hi Matt,
Quoted 8 lines · Matt Turner
Alpha's
thread_structis empty (all per-thread state lives inthread_info), so the whitelist is trivially empty. This is more explicit than the generic fallback, which computes the fullthread_structsize as copyable.Assisted-by Claude:claude-opus-4-6Signed-off-by Matt Turner <[email protected]>
I tested this on an AlphaServer ES40 withCONFIG_HARDENED_USERCOPY=y.
The task_struct slab reports a zero-sized usercopy region, as expected for Alpha's empty thread_struct:
$ cat /sys/kernel/slab/task_struct/usersize 0
The usercopy KUnit suite also passed all tests:
# usercopy: pass:4 fail:0 skip:0 total:4
ok 1 usercopy
Matt Turner
maintainerPATCH 13/24 alpha: add ARCH_HAS_PTE_SPECIAL support
In reply to Matt TurnerAdd _PAGE_SPECIAL using bit 19 (0x80000), which is unused in the Alpha PTE layout. This enables pte_special()/pte_mkspecial() for marking PTEs that are not backed by struct page (VDSO mappings, zero page, io_remap_pfn_range, etc.).
Include _PAGE_SPECIAL in _PAGE_CHG_MASK so it is preserved across pte_modify() calls.
--- arch/alpha/Kconfig | 1 + arch/alpha/include/asm/pgtable.h | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-)
arch/alpha/Kconfig +1 -0
@@ -8,6 +8,7 @@ config ALPHA select ARCH_HAS_FAST_MULTIPLIER select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE + select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_UBSAN select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_SERIO
arch/alpha/include/asm/pgtable.h +4 -1
@@ -73,6 +73,7 @@ struct vm_area_struct;/* .. and these are ours ... */ #define _PAGE_DIRTY 0x20000#define _PAGE_ACCESSED 0x40000 +#define _PAGE_SPECIAL 0x80000/* We borrow bit 39 to store the exclusive marker in swap PTEs. */ #define _PAGE_SWP_EXCLUSIVE 0x8000000000UL
@@ -94,7 +95,7 @@ struct vm_area_struct;#define _PFN_MASK 0xFFFFFFFF00000000UL#define _PAGE_TABLE (_PAGE_VALID | __DIRTY_BITS | __ACCESS_BITS) -#define _PAGE_CHG_MASK (_PFN_MASK | __DIRTY_BITS | __ACCESS_BITS) +#define _PAGE_CHG_MASK (_PFN_MASK | __DIRTY_BITS | __ACCESS_BITS | _PAGE_SPECIAL)/* * All the normal masks have the "page accessed" bits on, as any time they are used,
@@ -238,6 +239,8 @@ extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~(__ACCESS_BITS); retextern inline pte_t pte_mkwrite_novma (pte_t pte){pte_val (pte) &= ~_PAGE_FOW;return pte; }extern inline pte_t pte_mkdirty (pte_t pte) {pte_val (pte) |= __DIRTY_BITS;return pte; }extern inline pte_t pte_mkyoung (pte_t pte) {pte_val (pte) |= __ACCESS_BITS;return pte; } +extern inline int pte_special (pte_t pte) {return pte_val (pte) & _PAGE_SPECIAL; } +extern inline pte_t pte_mkspecial (pte_t pte) {pte_val (pte) |= _PAGE_SPECIAL;return pte; }/* * The smp_rmb() in the following functions are required to order the load of
Signature · 1 line
2.54.0
Re: [PATCH 13/24] alpha: add ARCH_HAS_PTE_SPECIAL support
Hi Matt,
Quoted 11 lines · Matt Turner
Add
_PAGE_SPECIALusing bit 19 (0x80000), which is unused in the Alpha PTE layout. This enables pte_special()/pte_mkspecial() for marking PTEs that are not backed by struct page (VDSO mappings, zero page,io_remap_pfn_range, etc.).Include
_PAGE_SPECIALin_PAGE_CHG_MASKso it is preserved acrosspte_modify()calls.Assisted-by Claude:claude-opus-4-6Signed-off-by Matt Turner <[email protected]>
I tested this on an AlphaServer ES40 withCONFIG_ARCH_HAS_PTE_SPECIAL=y.
A focused anonymous-memory test faulted in 256 shared zero pages, changed their protections from read-write to read-only and back, and then wrote to every page to trigger replacement with private COW pages.
The test completed successfully, all data checks passed, and no page-table or bad-PTE warnings appeared in dmesg.
Matt Turner
maintainerPATCH 14/24 alpha: add ARCH_SUPPORTS_PAGE_TABLE_CHECK support
In reply to Matt TurnerAdd the page table check helpers needed for CONFIG_PAGE_TABLE_CHECK and select ARCH_SUPPORTS_PAGE_TABLE_CHECK in Kconfig.
Alpha does not support huge pages, so pmd_user_accessible_page() and pud_user_accessible_page() always return false. pte_user_accessible_page() checks for present PTEs with user read access (_PAGE_URE).
--- arch/alpha/Kconfig | 1 + arch/alpha/include/asm/pgtable.h | 16 ++++++++++++++++ 2 files changed, 17 insertions(+)
arch/alpha/Kconfig +1 -0
@@ -17,6 +17,7 @@ config ALPHA select ARCH_NO_SG_CHAIN select ARCH_SUPPORTS_ATOMIC_RMW select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 + select ARCH_SUPPORTS_PAGE_TABLE_CHECK select ARCH_USE_CMPXCHG_LOCKREF select FORCE_PCI select PCI_DOMAINS if PCI
arch/alpha/include/asm/pgtable.h +16 -0
@@ -232,6 +232,22 @@ extern inline void pud_clear(pud_t * pudp) { pud_val(*pudp) = 0; }extern inline int pte_write (pte_t pte) {return !(pte_val (pte) & _PAGE_FOW); }extern inline int pte_dirty (pte_t pte) {return pte_val (pte) & _PAGE_DIRTY; }extern inline int pte_young (pte_t pte) {return pte_val (pte) & _PAGE_ACCESSED; } +extern inline int pte_user (pte_t pte) {return pte_val (pte) & _PAGE_URE; } + +static inline bool pte_user_accessible_page (pte_t pte,unsigned long addr) +{ +return pte_present (pte) &&pte_user (pte); +} + +static inline bool pmd_user_accessible_page (pmd_t pmd,unsigned long addr) +{ +return false; +} + +static inline bool pud_user_accessible_page (pud_t pud,unsigned long addr) +{ +return false; +}extern inline pte_t pte_wrprotect (pte_t pte) {pte_val (pte) |= _PAGE_FOW;return pte; }extern inline pte_t pte_mkclean (pte_t pte) {pte_val (pte) &= ~(__DIRTY_BITS);return pte; }
Signature · 1 line
2.54.0
Magnus Lindholm
maintainerRe: [PATCH 14/24] alpha: add ARCH_SUPPORTS_PAGE_TABLE_CHECK support
Hi Matt,
Quoted 8 lines · Matt Turner
Add the page table check helpers needed for
CONFIG_PAGE_TABLE_CHECKand selectARCH_SUPPORTS_PAGE_TABLE_CHECKinKconfig.Alpha does not support huge pages, so
pmd_user_accessible_page()andpud_user_accessible_page()always return false.pte_user_accessible_page()checks for present PTEs with user read access (_PAGE_URE).
This patch does not build with CONFIG_PAGE_TABLE_CHECK enabled on v7.3-rc1.
Commit cf8771ca4cdb ("mm/page_table_check: Pass mm_struct to pxx_user_accessible_page()") changed these helpers from:
pte_user_accessible_page(pte, addr)
to:
pte_user_accessible_page(mm, addr, pte)
The Alpha definitions added here still use the old two-argument API. The same applies to pmd_user_accessible_page() and pud_user_accessible_page().
Could you update the helpers to use the new three-argument signatures?
Regards,
Magnus
Matt Turner
maintainerPATCH 15/24 alpha: select ARCH_HAS_DEBUG_VM_PGTABLE
In reply to Matt TurnerCONFIG_DEBUG_VM_PGTABLE runs a boot-time self test over the page table
helpers: the protection bit accessors, pte_modify(), the swap entry encoding including the exclusive marker, and, where the architecture supports them, the huge page helpers. Alpha implements everything the test needs for a three-level page table without huge page support.
--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +1 -0
@@ -4,6 +4,7 @@ config ALPHA default y select ARCH_32BIT_USTAT_F_TINODE select ARCH_HAS_CURRENT_STACK_POINTER + select ARCH_HAS_DEBUG_VM_PGTABLE select ARCH_HAS_DMA_OPS if PCI select ARCH_HAS_FAST_MULTIPLIER select ARCH_HAS_GCOV_PROFILE_ALL
Signature · 1 line
2.54.0
Re: [PATCH 15/24] alpha: select ARCH_HAS_DEBUG_VM_PGTABLE
Hi Matt,
Quoted 26 lines · Matt Turner
CONFIG_DEBUG_VM_PGTABLEruns a boot-time self test over the page table
helpers: the protection bit accessors,pte_modify(), the swap entry encoding including the exclusive marker, and, where the architecture supports them, the huge page helpers. Alpha implements everything the test needs for a three-level page table without huge page support.Assisted-by Claude:claude-opus-5Signed-off-by Matt Turner <[email protected]>--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)arch/alpha/Kconfig +1
-1@@ -4,6 +4,7 @@ config ALPHA default y select ARCH_32BIT_USTAT_F_TINODE select ARCH_HAS_CURRENT_STACK_POINTER + select ARCH_HAS_DEBUG_VM_PGTABLE select ARCH_HAS_DMA_OPS if PCI select ARCH_HAS_FAST_MULTIPLIER select ARCH_HAS_GCOV_PROFILE_ALL --
Quoted 2 lines
2.54.0
I applied this manually on top of v7.3-rc1 plus Alpha GENERIC_ENTRY v5. The Kconfig hunk needed a trivial context adjustment.
I built and booted it on a two-CPU UP2000 with ARCH_HAS_DEBUG_VM_PGTABLE and DEBUG_VM_PGTABLE enabled. The boot-time page-table helper validation ran without warnings.
This also appears to warrant changing Alpha from "TODO" to "ok" in Documentation/features/debug/debug-vm-pgtable/arch-support.txt.
Regards,
Magnus
Matt Turner
maintainerPATCH 16/24 alpha: select HAVE_GUP_FAST
In reply to Matt TurnerThe lockless GUP fast path needs the architecture to distinguish PTEs with no struct page behind them and to keep page table pages alive while a walker holds no lock. Alpha now has ARCH_HAS_PTE_SPECIAL, and it has selected MMU_GATHER_RCU_TABLE_FREE for a long time, so both requirements are met.
PTEs are a single 64-bit word on Alpha, so the lockless reads that the generic walker performs cannot tear, and no arch-specific gup_fast_permitted() or ptep_get_lockless() is needed.
--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +1 -0
@@ -26,6 +26,7 @@ config ALPHA select HAVE_ARCH_COMPILER_H select HAVE_ASM_MODVERSIONS select HAVE_DEBUG_KMEMLEAK + select HAVE_GUP_FAST select HAVE_PAGE_SIZE_8KB select HAVE_PCSPKR_PLATFORM select HAVE_PERF_EVENTS
Signature · 1 line
2.54.0
Re: [PATCH 16/24] alpha: select HAVE_GUP_FAST
Hi Matt,
Quoted 7 lines · Matt Turner
The lockless GUP fast path needs the architecture to distinguish PTEs with no struct page behind them and to keep page table pages alive while a walker holds no lock. Alpha now has
ARCH_HAS_PTE_SPECIAL, and it has selectedMMU_GATHER_RCU_TABLE_FREEfor a long time, so both requirements are met.
Quoted 6 lines
PTEs are a single 64-bit word on Alpha, so the lockless reads that the generic walker performs cannot tear, and no arch-specific
gup_fast_permitted()orptep_get_lockless()is needed.Assisted-by Claude:claude-opus-5Signed-off-by Matt Turner <[email protected]>
I tested this on an Alpha UP2000 with CONFIG_HAVE_GUP_FAST=y, CONFIG_ARCH_HAS_PTE_SPECIAL=y, and CONFIG_MMU_GATHER_RCU_TABLE_FREE=y.
The in-tree gup_test completed the get_user_pages_fast() and pin_user_pages_fast() benchmarks with both read-only and writable pins. Each case ran ten iterations over a 16 MiB mapping, fetching 123 pages per call.
All four cases completed with ioctl status 0 and no failures.
Matt Turner
maintainerPATCH 17/24 alpha: select ARCH_USE_MEMTEST
In reply to Matt TurnerWire up the generic early memtest from arch_mm_preinit(), which runs after parse_early_param() has picked up the memtest= command line option and before memblock_free_all() hands the memory to the buddy allocator. paging_init() would be the natural place, but Alpha calls it from setup_arch(), before the option is parsed, so the test would never run.
The test range starts at the first DRAM address rather than physical zero because low memory on Alpha is owned by the console and PALcode.
Tested under QEMU with memtest=4: all four patterns pass over the free memblock ranges, with no bad memory reserved.
--- arch/alpha/Kconfig | 1 + arch/alpha/mm/init.c | 5 +++++ 2 files changed, 6 insertions(+)
arch/alpha/Kconfig +1 -0
@@ -20,6 +20,7 @@ config ALPHA select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 select ARCH_SUPPORTS_PAGE_TABLE_CHECK select ARCH_USE_CMPXCHG_LOCKREF + select ARCH_USE_MEMTEST select FORCE_PCI select PCI_DOMAINS if PCI select PCI_SYSCALL if PCI
arch/alpha/mm/init.c +5 -0
@@ -226,6 +226,11 @@ void __init paging_init(void)memset (absolute_pointer (ZERO_PGE ),0 ,PAGE_SIZE ); } +void __init arch_mm_preinit (void ) +{ +early_memtest (memblock_start_of_DRAM (),PFN_PHYS (max_low_pfn)); +} +#if defined(CONFIG_ALPHA_GENERIC ) || defined(CONFIG_ALPHA_SRM )void srm_paging_stop (void )
Signature · 1 line
2.54.0
Re: [PATCH 17/24] alpha: select ARCH_USE_MEMTEST
Quoted 7 lines · Matt Turner
Wire up the generic early memtest from
arch_mm_preinit(), which runs afterparse_early_param()has picked up the memtest= command line option and beforememblock_free_all()hands the memory to the buddy allocator.paging_init()would be the natural place, but Alpha calls it fromsetup_arch(), before the option is parsed, so the test would never run.
Quoted 8 lines
The test range starts at the first DRAM address rather than physical zero because low memory on Alpha is owned by the console and PALcode.
Tested under QEMU with memtest=4: all four patterns pass over the free memblock ranges, with no bad memory reserved.
Assisted-by Claude:claude-opus-5Signed-off-by Matt Turner <[email protected]>
I tested this on an Alpha UP2000 with CONFIG_MEMTEST=y and memtest=4. The early memory test completed successfully and reported:
EarlyMemtestBad: 0 kB
It would also be useful to add ALPHA to the memtest= architecture list in Documentation/admin-guide/kernel-parameters.txt.
Matt Turner
maintainerPATCH 18/24 alpha: select SYSCTL_EXCEPTION_TRACE
In reply to Matt TurnerReport unhandled user faults the way other architectures do, and hook up the debug.exception-trace sysctl that controls the reporting.
The message gives the faulting address, the PC and the user stack pointer, and is rate limited.
--- arch/alpha/Kconfig | 1 + arch/alpha/mm/fault.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+)
arch/alpha/Kconfig +1 -0
@@ -59,6 +59,7 @@ config ALPHA select MMU_GATHER_NO_RANGE select MMU_GATHER_RCU_TABLE_FREE select SPARSEMEM_EXTREME if SPARSEMEM + select SYSCTL_EXCEPTION_TRACE select ZONE_DMA select TRACE_IRQFLAGS_SUPPORT select ARCH_WANT_FRAME_POINTERS
arch/alpha/mm/fault.c +29 -0
@@ -27,8 +27,32 @@#include <linux/uaccess.h> #include <linux/perf_event.h> +#include <asm/pal.h> +extern void die_if_kernel (char *,struct pt_regs *,long ,unsigned long *); +int show_unhandled_signals =1 ; + +static void +show_signal_msg (struct pt_regs *regs,unsigned long address,int signo, +const char *desc) +{ +const char *level; + +if (!show_unhandled_signals || !unhandled_signal (current, signo)) +return ; +if (!printk_ratelimit ()) +return ; + +/* Losing init is fatal, so shout about it. */ + level =task_pid_nr (current) >1 ?KERN_INFO :KERN_EMERG ; + +printk ("%s%s[%d]: %s at %016lx pc %016lx sp %016lx\n" , + level, current->comm,task_pid_nr (current), desc, + address, regs->pc,rdusp ()); +print_vma_addr (KERN_CONT " in " , regs->pc); +printk (KERN_CONT "\n" ); +}/* * Force a new ASN for a task.
@@ -217,12 +241,17 @@ do_page_fault(unsigned long address, unsigned long mmcsr,mmap_read_unlock (mm);/* Send a sigbus, regardless of whether we were in kernel or user mode. */ +if (user_mode (regs)) +show_signal_msg (regs, address,SIGBUS ,"bus error" );force_sig_fault (SIGBUS ,BUS_ADRERR , (void __user *) address);if (!user_mode (regs)) goto no_context;return ; do_sigsegv: +show_signal_msg (regs, address,SIGSEGV , + si_code ==SEGV_MAPERR ?"unmapped access" + :"access violation" );force_sig_fault (SIGSEGV , si_code, (void __user *) address);return ;
Signature · 1 line
2.54.0
Re: [PATCH 18/24] alpha: select SYSCTL_EXCEPTION_TRACE
Hi Matt,
Quoted 10 lines · Matt Turner
Report unhandled user faults the way other architectures do, and hook up the debug.exception-trace sysctl that controls the reporting.
The message gives the faulting address, the PC and the user stack pointer, and is rate limited.
Assisted-by Claude:claude-opus-5Signed-off-by Matt Turner <[email protected]>---
I tested this on an Alpha UP2000. With debug.exception-trace=1, unhandled SEGV_MAPERR and SEGV_ACCERR faults produced the expected "unmapped access" and "access violation" messages.
With debug.exception-trace=0, both processes still received SIGSEGV, but no additional messages were written to the kernel log.
Matt Turner
maintainerPATCH 19/24 alpha: discard .eh_frame and the relocation sections
In reply to Matt Turnergcc emits .eh_frame for Alpha even though the kernel builds with -fno-asynchronous-unwind-tables, and nothing in the kernel consumes it:
the stack trace code scans the stack for text addresses rather than unwinding DWARF. It was allocated in the loaded image, so dropping it shrinks vmlinux by about 1.1MB for a Marvel SMP configuration.
The .rela* sections are equally useless, as the kernel image is not relocatable. The linker was already dropping their contents.
Both were being placed as orphan sections, which is what drew attention to them.
--- arch/alpha/kernel/vmlinux.lds.S | 11 +++++++++++ 1 file changed, 11 insertions(+)
arch/alpha/kernel/vmlinux.lds.S +11 -0
@@ -76,5 +76,16 @@ SECTIONS MODINFO ELF_DETAILS + /* + * gcc emits .eh_frame for Alpha even with + * -fno-asynchronous-unwind-tables, and the kernel has no DWARF + * unwinder to consume it. The relocation sections are likewise + * useless as the kernel image is not relocatable. + */ + /DISCARD/ : { + *(.eh_frame) + *(.rela .rela*) + } + DISCARDS }
Signature · 1 line
2.54.0
Re: [PATCH 19/24] alpha: discard .eh_frame and the relocation sections
Hi Matt,
Quoted 10 lines · Matt Turner
gcc emits .eh_frame for Alpha even though the kernel builds with -fno-asynchronous-unwind-tables, and nothing in the kernel consumes it:
the stack trace code scans the stack for text addresses rather than unwinding DWARF. It was allocated in the loaded image, so dropping it shrinks vmlinux by about 1.1MB for a Marvel SMP configuration.The .rela* sections are equally useless, as the kernel image is not relocatable. The linker was already dropping their contents.
Quoted 6 lines
Both were being placed as orphan sections, which is what drew attention to them.
Assisted-by Claude:claude-opus-5Signed-off-by Matt Turner <[email protected]>---
I verified that .eh_frame and .rela* sections were present in the linker input objects but absent from the final vmlinux. The resulting compressed kernel image also booted successfully on an Alpha UP2000.
Matt Turner
maintainerPATCH 20/24 alpha: select ARCH_WANT_LD_ORPHAN_WARN
In reply to Matt TurnerWith .eh_frame and the relocation sections now placed explicitly, an Alpha kernel links with no orphan sections left, so ask the linker to warn if new ones appear.
--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +1 -0
@@ -38,6 +38,7 @@ config ALPHA select AUTO_IRQ_AFFINITY if SMP select GENERIC_IRQ_SHOW select ARCH_WANT_IPC_PARSE_VERSION + select ARCH_WANT_LD_ORPHAN_WARN select ARCH_HAVE_NMI_SAFE_CMPXCHG select AUDIT_ARCH select EDAC_SUPPORT
Signature · 1 line
2.54.0
Re: [PATCH 20/24] alpha: select ARCH_WANT_LD_ORPHAN_WARN
Hi Matt,
Quoted 7 lines · Matt Turner
With .eh_frame and the relocation sections now placed explicitly, an Alpha kernel links with no orphan sections left, so ask the linker to warn if new ones appear.
Assisted-by Claude:claude-opus-5Signed-off-by Matt Turner <[email protected]>
Build tested this for Alpla, looks good to me.
Quoted 19 lines
--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)arch/alpha/Kconfig +1
-1@@ -38,6 +38,7 @@ config ALPHA select AUTO_IRQ_AFFINITY if SMP select GENERIC_IRQ_SHOW select ARCH_WANT_IPC_PARSE_VERSION + select ARCH_WANT_LD_ORPHAN_WARN select ARCH_HAVE_NMI_SAFE_CMPXCHG select AUDIT_ARCH select EDAC_SUPPORT --2.54.0
Matt Turner
maintainerPATCH 21/24 alpha: select ARCH_WANT_IRQS_OFF_ACTIVATE_MM
In reply to Matt Turneractivate_mm() on Alpha calls __load_new_mm_context() which assigns a new ASID and invokes PALcode swpctx. On SMP, an interrupt arriving between the ASID update and the page table switch could see inconsistent state. Ensure activate_mm() is called with interrupts disabled during exec.
--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/alpha/Kconfig +1 -0
@@ -37,6 +37,7 @@ config ALPHA select GENERIC_PCI_IOMAP select AUTO_IRQ_AFFINITY if SMP select GENERIC_IRQ_SHOW + select ARCH_WANT_IRQS_OFF_ACTIVATE_MM select ARCH_WANT_IPC_PARSE_VERSION select ARCH_WANT_LD_ORPHAN_WARN select ARCH_HAVE_NMI_SAFE_CMPXCHG
Signature · 1 line
2.54.0
Re: [PATCH 21/24] alpha: select ARCH_WANT_IRQS_OFF_ACTIVATE_MM
Hi Matt,
Quoted 26 lines · Matt Turner
activate_mm()on Alpha calls__load_new_mm_context()which assigns a new ASID and invokes PALcode swpctx. On SMP, an interrupt arriving between the ASID update and the page table switch could see inconsistent state. Ensureactivate_mm()is called with interrupts disabled during exec.Assisted-by Claude:claude-opus-4-6Signed-off-by Matt Turner <[email protected]>--- arch/alpha/Kconfig | 1 + 1 file changed, 1 insertion(+)arch/alpha/Kconfig +1
-1@@ -37,6 +37,7 @@ config ALPHA select GENERIC_PCI_IOMAP select AUTO_IRQ_AFFINITY if SMP select GENERIC_IRQ_SHOW + select ARCH_WANT_IRQS_OFF_ACTIVATE_MM select ARCH_WANT_IPC_PARSE_VERSION select ARCH_WANT_LD_ORPHAN_WARN select ARCH_HAVE_NMI_SAFE_CMPXCHG --
Quoted 2 lines
2.54.0
I tested this on a two-CPU Alpha UP2000. I ran 20,000 successive execve() operations pinned to each online CPU. All executions completed successfully, with no MMU, ASN, or page-table errors in the kernel log.
Magnus
Matt Turner
maintainerPATCH 22/24 alpha: add HAVE_PERF_REGS and HAVE_PERF_USER_STACK_DUMP support
In reply to Matt TurnerImplement the perf register sampling interface for Alpha. This enables perf to capture register state and user stack dumps with samples, supporting --call-graph dwarf.
The perf_regs enum exposes the registers available in pt_regs: r0-r8, r16-r28, gp, pc, and ps. Registers r9-r15 are callee-saved and live in switch_stack, not pt_regs, so they are not included.
A switch statement maps perf register indices to pt_regs fields since Alpha's pt_regs layout is non-contiguous (unlike architectures where direct array indexing works).
--- arch/alpha/Kconfig | 2 + arch/alpha/include/asm/perf_regs.h | 7 ++ arch/alpha/include/uapi/asm/perf_regs.h | 34 ++++++++++ arch/alpha/kernel/Makefile | 1 + arch/alpha/kernel/perf_regs.c | 86 +++++++++++++++++++++++++ 5 files changed, 130 insertions(+) create mode 100644 arch/alpha/include/asm/perf_regs.h create mode 100644 arch/alpha/include/uapi/asm/perf_regs.h create mode 100644 arch/alpha/kernel/perf_regs.c
arch/alpha/Kconfig +2 -0
@@ -31,6 +31,8 @@ config ALPHA select HAVE_PAGE_SIZE_8KB select HAVE_PCSPKR_PLATFORM select HAVE_PERF_EVENTS + select HAVE_PERF_REGS + select HAVE_PERF_USER_STACK_DUMP select NEED_DMA_MAP_STATE select NEED_SG_DMA_LENGTH select GENERIC_IRQ_PROBE
arch/alpha/include/asm/perf_regs.h new file +7 -0
@@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_ALPHA_PERF_REGS_H +#define _ASM_ALPHA_PERF_REGS_H + +#include <uapi/asm/perf_regs.h> + +#endif /* _ASM_ALPHA_PERF_REGS_H */
arch/alpha/include/uapi/asm/perf_regs.h new file +34 -0
@@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_ASM_ALPHA_PERF_REGS_H +#define _UAPI_ASM_ALPHA_PERF_REGS_H + +enum perf_event_alpha_regs { +PERF_REG_ALPHA_R0 , +PERF_REG_ALPHA_R1 , +PERF_REG_ALPHA_R2 , +PERF_REG_ALPHA_R3 , +PERF_REG_ALPHA_R4 , +PERF_REG_ALPHA_R5 , +PERF_REG_ALPHA_R6 , +PERF_REG_ALPHA_R7 , +PERF_REG_ALPHA_R8 , +PERF_REG_ALPHA_R16 , +PERF_REG_ALPHA_R17 , +PERF_REG_ALPHA_R18 , +PERF_REG_ALPHA_R19 , +PERF_REG_ALPHA_R20 , +PERF_REG_ALPHA_R21 , +PERF_REG_ALPHA_R22 , +PERF_REG_ALPHA_R23 , +PERF_REG_ALPHA_R24 , +PERF_REG_ALPHA_R25 , +PERF_REG_ALPHA_R26 , +PERF_REG_ALPHA_R27 , +PERF_REG_ALPHA_R28 , +PERF_REG_ALPHA_GP , +PERF_REG_ALPHA_PC , +PERF_REG_ALPHA_PS , +PERF_REG_ALPHA_MAX , +}; + +#endif /* _UAPI_ASM_ALPHA_PERF_REGS_H */
arch/alpha/kernel/Makefile +1 -0
@@ -18,6 +18,7 @@ obj-$(CONFIG_PCI) += pci.o pci_iommu.o pci-sysfs.o obj-$(CONFIG_SRM_ENV) += srm_env.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_PERF_EVENTS) += perf_event.o +obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o obj-$(CONFIG_RTC_DRV_ALPHA) += rtc.o obj-$(CONFIG_AUDIT) += audit.o
arch/alpha/kernel/perf_regs.c new file +86 -0
86 lines not on this page · raw message
Signature · 1 line
2.54.0
Magnus Lindholm
maintainerRe: [PATCH 22/24] alpha: add HAVE_PERF_REGS and HAVE_PERF_USER_STACK_DUMP support
Hi Matt,
Quoted 5 lines · Matt Turner
Implement the perf register sampling interface for Alpha. This enables perf to capture register state and user stack dumps with samples, supporting --call-graph dwarf.
Quoted 8 lines
The
perf_regsenum exposes the registers available inpt_regs: r0-r8, r16-r28, gp, pc, and ps. Registers r9-r15 are callee-saved and live inswitch_stack, notpt_regs, so they are not included.A switch statement maps perf register indices to
pt_regsfields since Alpha'spt_regslayout is non-contiguous (unlike architectures where direct array indexing works).
I tested this on an Alpha UP2000. Basic perf recording works, but user-register and user-stack sampling still appear to need some additional work.
perf record --user-regs=? reports an empty register list, since tools/perf does not yet provide the Alpha register mask, names, or IP/SP mappings. Adding DWARF call-graph sampling consequently fails with EINVAL. I think the corresponding tools/perf support could be added as a separate patch in this series.
There also appears to be one kernel-side issue with user-stack sampling. The generic code obtains the stack pointer through user_stack_pointer(regs), which returns regs->usp on Alpha.
Alpha already has alpha_snapshot_usp(), which initializes this field for user-mode register frames, but it is currently local to traps.c and is only called from do_entArith() and do_entIF(). The interrupt entry path through do_entInt() does not call it.
Perhaps alpha_snapshot_usp() could be moved to a shared header and called near the beginning of do_entInt(), before dispatching the interrupt. That would ensure that perf_irq() receives a valid regs->usp for interrupts taken from userspace, without adding this work to the SAVE_ALL assembly macro.
The perf register ABI also appears to be missing SP. This could be provided using current_user_stack_pointer(), as in the older Alpha implementation.
I have some older Alpha kernel and tools/perf patches which implement similar support. They target an older API, but I will send them off-list in case any of the code is useful. Please feel free to reuse or adapt whatever helps.
Regards,
Magnus
Matt Turner
maintainerPATCH 23/24 alpha: select SPARSE_IRQ
In reply to Matt TurnerNR_IRQS on Alpha is sized for the largest configuration each platform supports, and for Marvel that is 32 PIDs, or 32784 interrupts. Without SPARSE_IRQ that becomes a static irq_desc[] array of 12.6 MB in .data, carried by every Marvel and every generic kernel regardless of how many interrupts the machine actually has. A real ES47 uses 87 of them.
That is not just wasted memory, it constrains where the kernel can be loaded. The image links at a fixed 0xfffffc0001010000, just above the console's low memory reservation, and with memory striping enabled the console leaves only about 16 MB of usable low memory before the rest is relocated to an interleaved aperture. A 12.6 MB array of mostly unused interrupt descriptors is the difference between fitting and not.
Alpha already goes through irq_to_desc() rather than indexing irq_desc[] directly, so nothing stands in the way. The platforms do wire up their interrupts by number, though, which needs the descriptors to exist by then, so provide arch_probe_nr_irqs() returning the machine vector's count instead of taking the NR_IRQS_LEGACY default. Without it every interrupt above 15 would have no descriptor and the handler setup would be silently dropped.
Tested on an ES47 (Marvel, 2 EV7z): boots with all device interrupts working, and .data drops by 12.6 MB, from 15.7 MB to 3.1 MB.
--- arch/alpha/Kconfig | 1 + arch/alpha/kernel/irq_alpha.c | 13 +++++++++++++ 2 files changed, 14 insertions(+)
arch/alpha/Kconfig +1 -0
@@ -62,6 +62,7 @@ config ALPHA select CPU_NO_EFFICIENT_FFS if !ALPHA_EV67 select MMU_GATHER_NO_RANGE select MMU_GATHER_RCU_TABLE_FREE + select SPARSE_IRQ select SPARSEMEM_EXTREME if SPARSEMEM select SYSCTL_EXCEPTION_TRACE select ZONE_DMA
arch/alpha/kernel/irq_alpha.c +13 -0
@@ -148,6 +148,19 @@ common_init_isa_dma(void)outb (0 ,DMA2_CLR_MASK_REG ); } +/* +* The platforms wire up their interrupts by calling into the generic irq +* code with fixed interrupt numbers, so the descriptors have to exist by +* then. Preallocate the machine's full complement rather than take the +* NR_IRQS_LEGACY default, which would leave everything above IRQ 15 +* without a descriptor and silently drop the handler setup. +*/ +int __init +arch_probe_nr_irqs (void ) +{ +return alpha_mv.nr_irqs; +} +void __init init_IRQ (void ) {
Signature · 1 line
2.54.0
Magnus Lindholm
maintainerRe: [PATCH 23/24] alpha: select SPARSE_IRQ
Hi Matt,
Quoted 22 lines · Matt Turner
NR_IRQSon Alpha is sized for the largest configuration each platform supports, and for Marvel that is 32 PIDs, or 32784 interrupts. WithoutSPARSE_IRQthat becomes a static irq_desc[] array of 12.6 MB in .data, carried by every Marvel and every generic kernel regardless of how many interrupts the machine actually has. A real ES47 uses 87 of them.That is not just wasted memory, it constrains where the kernel can be loaded. The image links at a fixed
0xfffffc0001010000, just above the console's low memory reservation, and with memory striping enabled the console leaves only about 16 MB of usable low memory before the rest is relocated to an interleaved aperture. A 12.6 MB array of mostly unused interrupt descriptors is the difference between fitting and not.Alpha already goes through
irq_to_desc()rather than indexing irq_desc[] directly, so nothing stands in the way. The platforms do wire up their interrupts by number, though, which needs the descriptors to exist by then, so providearch_probe_nr_irqs()returning the machine vector's count instead of taking theNR_IRQS_LEGACYdefault. Without it every interrupt above 15 would have no descriptor and the handler setup would be silently dropped.
Quoted 7 lines
Tested on an ES47 (Marvel, 2 EV7z): boots with all device interrupts working, and .data drops by 12.6 MB, from 15.7 MB to 3.1 MB.
--- arch/alpha/Kconfig | 1 + arch/alpha/kernel/irq_alpha.c | 13 +++++++++++++ 2 files changed, 14 insertions(+)
This patch appears to be missing your Signed-off-by tag.
Tested on a two-CPU UP2000 with CONFIG_SPARSE_IRQ=y. The kernel booted successfully and created IRQ descriptors 0 through 63. SCSI devices on IRQs 19 and 27 and Ethernet on IRQ 43 operated normally, with their interrupt counts increasing. I observed no IRQ setup failures or other IRQ-related warnings.
Regards
Magnus
Matt Turner
maintainerPATCH 24/24 alpha: add TRACE_IRQFLAGS_SUPPORT
In reply to Matt TurnerInstrument the entry/exit assembly to track hardirq state for lockdep.
TRACE_IRQS_OFF is called after SAVE_ALL at each exception/interrupt entry point and at syscall entry. TRACE_IRQS_ON is called at restore_all before returning to userspace, where PAL_rti will restore the user IPL (re-enabling interrupts).
The function call clobbers caller-saved registers, so the TRACE_IRQS_OFF macro reloads $0 and $16-$18 from the pt_regs frame. $8 (current_thread_info) is preserved because it is declared as a global register variable.
Together with the previously added STACKTRACE_SUPPORT and LOCKDEP_SUPPORT, this enables LOCK_DEBUGGING_SUPPORT on Alpha.
--- arch/alpha/kernel/entry.S | 54 +++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 8 deletions(-)
arch/alpha/kernel/entry.S +46 -8
@@ -241,6 +241,36 @@ .cfi_adjust_cfa_offset -SWITCH_STACK_SIZE .endm +/* + * Trace hardirq state changes for lockdep. TRACE_IRQS_OFF is called + * after SAVE_ALL at each entry point where PALcode enters with IPL + * raised (interrupts disabled). TRACE_IRQS_ON is called before + * returning to userspace, where PAL_rti will restore the user IPL. + * + * The function call clobbers caller-saved registers; $8 is preserved + * because it is declared as a global register variable for + * current_thread_info. We reload $0 and $16-$18 from the pt_regs + * frame that SAVE_ALL created, since entry points pass those to their + * C handlers. + */ +.macro TRACE_IRQS_OFF +#ifdef CONFIG_TRACE_IRQFLAGS + jsr $26, trace_hardirqs_off + ldgp $gp, 0($26) + ldq $0, 0($sp) + ldq $16, 160($sp) + ldq $17, 168($sp) + ldq $18, 176($sp) +#endif +.endm + +.macro TRACE_IRQS_ON +#ifdef CONFIG_TRACE_IRQFLAGS + jsr $26, trace_hardirqs_on + ldgp $gp, 0($26) +#endif +.endm + /* * Non-syscall kernel entry points. */
@@ -248,8 +278,9 @@ CFI_START_OSF_FRAME entInt SAVE_ALL lda $8, 0x3fff - lda $26, ret_from_sys_call bic $sp, $8, $8 + TRACE_IRQS_OFF + lda $26, ret_from_sys_call mov $sp, $19 jsr $31, do_entInt CFI_END_OSF_FRAME entInt
@@ -257,14 +288,18 @@ CFI_END_OSF_FRAME entInt CFI_START_OSF_FRAME entArith SAVE_ALL lda $8, 0x3fff - lda $26, ret_from_sys_call bic $sp, $8, $8 + TRACE_IRQS_OFF + lda $26, ret_from_sys_call mov $sp, $18 jsr $31, do_entArith CFI_END_OSF_FRAME entArith CFI_START_OSF_FRAME entMM SAVE_ALL + lda $8, 0x3fff + bic $sp, $8, $8 + TRACE_IRQS_OFF /* save $9 - $15 so the inline exception code can manipulate them. */ subq $sp, 64, $sp .cfi_adjust_cfa_offset 64
@@ -284,8 +319,6 @@ CFI_START_OSF_FRAME entMM .cfi_rel_offset $15, 48 addq $sp, 64, $19 /* handle the fault */ - lda $8, 0x3fff - bic $sp, $8, $8 jsr $26, do_page_fault /* reload the registers after the exception code played. */ ldq $9, 0($sp)
@@ -311,8 +344,9 @@ CFI_END_OSF_FRAME entMM CFI_START_OSF_FRAME entIF SAVE_ALL lda $8, 0x3fff - lda $26, ret_from_sys_call bic $sp, $8, $8 + TRACE_IRQS_OFF + lda $26, ret_from_sys_call mov $sp, $17 jsr $31, do_entIF CFI_END_OSF_FRAME entIF
@@ -451,6 +485,9 @@ entUnaUser: .cfi_restore $0 .cfi_adjust_cfa_offset -256 SAVE_ALL /* setup normal kernel stack */ + lda $8, 0x3fff + bic $sp, $8, $8 + TRACE_IRQS_OFF lda $sp, -64($sp) .cfi_adjust_cfa_offset 64 stq $9, 0($sp)
@@ -467,9 +504,7 @@ entUnaUser: .cfi_rel_offset $13, 32 .cfi_rel_offset $14, 40 .cfi_rel_offset $15, 48 - lda $8, 0x3fff addq $sp, 64, $19 - bic $sp, $8, $8 jsr $26, do_entUnaUser ldq $9, 0($sp) ldq $10, 8($sp)
@@ -493,8 +528,9 @@ CFI_END_OSF_FRAME entUna CFI_START_OSF_FRAME entDbg SAVE_ALL lda $8, 0x3fff - lda $26, ret_from_sys_call bic $sp, $8, $8 + TRACE_IRQS_OFF + lda $26, ret_from_sys_call mov $sp, $16 jsr $31, do_entDbg CFI_END_OSF_FRAME entDbg
@@ -543,6 +579,7 @@ entSys: lda $8, 0x3fff bic $sp, $8, $8 + TRACE_IRQS_OFF lda $4, NR_syscalls($31) stq $16, SP_OFF+24($sp) lda $5, sys_call_table
@@ -586,6 +623,7 @@ ret_to_user: and $17, _TIF_WORK_MASK, $2 bne $2, work_pending restore_all: + TRACE_IRQS_ON ldl $2, TI_STATUS($8) and $2, TS_SAVED_FP | TS_RESTORE_FP, $3 bne $3, restore_fpu
Signature · 1 line
2.54.0
Magnus Lindholm
maintainerRe: [PATCH 24/24] alpha: add TRACE_IRQFLAGS_SUPPORT
Hi Matt,
Quoted 13 lines · Matt Turner
Instrument the entry/exit assembly to track hardirq state for lockdep.
TRACE_IRQS_OFFis called afterSAVE_ALLat each exception/interrupt entry point and at syscall entry.TRACE_IRQS_ONis called atrestore_allbefore returning to userspace, wherePAL_rtiwill restore the user IPL (re-enabling interrupts).The function call clobbers caller-saved registers, so the
TRACE_IRQS_OFFmacro reloads $0 and $16-$18 from thept_regsframe. $8 (current_thread_info) is preserved because it is declared as a global register variable.
Quoted 5 lines
Together with the previously added
STACKTRACE_SUPPORTandLOCKDEP_SUPPORT, this enablesLOCK_DEBUGGING_SUPPORTon Alpha.Assisted-by Claude:claude-opus-4-6Signed-off-by Matt Turner <[email protected]>
I think this patch needs to be rebased on top of Alpha GENERIC_ENTRY v5. Both patches are based on entry.S blob 9f2608de2544 and modify the same entry and return paths, so they cannot currently be applied in either order.
With GENERIC_ENTRY, the syscall IRQ-state transitions are already handled by syscall_enter_from_user_mode_randomize_stack() and syscall_exit_to_user_mode(). Non-syscall user returns go through exit_to_user_mode(), which also performs the final hardirqs-on transition.
The interrupt path already calls raw_local_irq_disable() and updates the lockdep state in do_entInt(), while kernel-mode PAL returns retain the Alpha-specific lockdep_on_restore() handling.
Adding TRACE_IRQS_OFF to entSys and TRACE_IRQS_ON to restore_all would therefore duplicate the generic-entry transitions. I think the patch should instead be rebased and limited to any entry paths which remain uncovered after GENERIC_ENTRY v5 is applied.
Keeping these transitions in the generic C entry helpers where possible would also avoid additional register-save and restore logic in entry.S.
Regards,
Magnus
Magnus Lindholm
maintainerHi Matt,
Quoted 58 lines · Matt Turner
Alpha is missing a long list of
Kconfigoptions that other architectures have picked up over the years, some of them for no better reason than nobody having gone through the list. I diffed the select statements in every otherarch/*/Kconfigagainstarch/alpha/Kconfigand worked through what turned up. This series is the result: two fixes it depends on, and the options that are either free or close to it.The patches are ordered from least to most contentious, so the front of the series can be applied on its own if the tail needs discussion.
Patches 1-2 are fixes.
arch_irqs_disabled_flags()only reported interrupts as disabled atIPL_MAX, but PALcode enters handlers at the IPL of the interrupt being delivered, so a device or timer handler answered that interrupts were enabled.handle_irq()also calledirq_to_desc()beforeirq_enter(), running generic code with the preempt count still saying task context and RCU not yet watching. Both matter on their own; patches 23 and 24 are what made them visible.Patches 3-11 are one-line selects with no Alpha code behind them:
instrumentation (UBSAN, gcov, kmemleak), EDAC, and four properties Alpha has always had but never declared (LL/SC atomics, hardware multiply,__int128, the existingasm/compiler.h, and the non-overlapping user and kernel address spaces).Patches 12-17 add a small amount of code: an empty
thread_structwhitelist,_PAGE_SPECIALon a free PTE bit, the page table check helpers, and then the three things that follow from those - the page table helper self test, lockless GUP, and the early memtest. Note thatearly_memtest()is called fromarch_mm_preinit()rather thanpaging_init(), because Alpha callspaging_init()fromsetup_arch(), beforeparse_early_param()has seen the memtest= option.Patches 18-20 change something visible. Unhandled user faults now print the usual message under the debug.exception-trace sysctl. .eh_frame is
discarded: gcc emits it for Alpha regardless of -fno-asynchronous-unwind-tables, it was allocated in the loaded image, and nothing consumes it, since the stack trace code scans for text addresses rather than unwinding DWARF. That is worth about 1.1MB. With that and the relocation sections placed explicitly, the kernel links with no orphans left, so the last of the three asks the linker to say so.Patches 21-24 are the ones I expect to draw comment. Patch 22 adds a uapi header, so the perf register numbering is an ABI decision. Patch 23 is
SPARSE_IRQ: without it Marvel carries a 12.6MB static irq_desc[] in .data for 32768 possible interrupts, of which a real ES47 uses 87, and the kernel links at a fixed address just above the console reservation where that 12.6MB is the difference between fitting and not. Patch 24 instruments the entry assembly for lockdep hardirq tracking.Tested with gcc 17 under QEMU (-M clipper -smp 2, an
ALPHA_GENERICbuild) withPROVE_LOCKINGenabled: no splats,early_memtestpasses all four patterns over the free memblock ranges with nothing reserved,debug_vm_pgtablevalidates with no warning, avmsplice()of an anonymous mapping throughpin_user_pages_fast()returns the right data, and an unhandled SIGSEGV prints the new trace line. Patch 23 was tested on an AlphaServer ES47.
Quoted 8 lines
Not included, and worth mentioning:
ARCH_HAS_KCOV. A kernel withKCOV_INSTRUMENT_ALLboots and runs, butCONFIG_KCOV_SELFTESTpanics. The self test deliberately arms kcov with no coverage area so that any instrumented function reached from interrupt context faults, checking that nothing escapes the window before the preempt count says hardirq. On Alpha something does. Patch 2 fixes one such site; the panic survives it, so the entry paths need an audit first.
Thanks for taking the time to do this! This is a nice collection of patches. I've started on the review and testing, I will keep at it.
As general feedback for the series, I noticed that several of the corresponding architecture feature matrices still list Alpha as TODO. The Alpha entries should be changed to "ok" for:
ARCH_HAS_GCOV_PROFILE_ALL
HAVE_DEBUG_KMEMLEAK
ARCH_HAS_PTE_SPECIAL
ARCH_HAS_DEBUG_VM_PGTABLE
HAVE_PERF_REGS
HAVE_PERF_USER_STACK_DUMP
These correspond to patches 4, 5, 13, 15, and 22. It would probably be best to include each documentation update in the patch which enables the corresponding feature.
It would also be helpful if the next revision were rebased onto v7.3-rc1 and applied cleanly on top of my Alpha GENERIC_ENTRY v5 series. I am currently testing only the patches which applied successfully.
Alpha GENERIC_ENTRY v5 series is available here:
https://lore.kernel.org/linux-alpha/[email protected]/T/#t
Regards,
Magnus
Matt Turner
maintainerQuoted 84 lines · Magnus Lindholm
Hi Matt,
Quoted 58 lines · Matt Turner
Alpha is missing a long list of
Kconfigoptions that other architectures have picked up over the years, some of them for no better reason than nobody having gone through the list. I diffed the select statements in every otherarch/*/Kconfigagainstarch/alpha/Kconfigand worked through what turned up. This series is the result: two fixes it depends on, and the options that are either free or close to it.The patches are ordered from least to most contentious, so the front of the series can be applied on its own if the tail needs discussion.
Patches 1-2 are fixes.
arch_irqs_disabled_flags()only reported interrupts as disabled atIPL_MAX, but PALcode enters handlers at the IPL of the interrupt being delivered, so a device or timer handler answered that interrupts were enabled.handle_irq()also calledirq_to_desc()beforeirq_enter(), running generic code with the preempt count still saying task context and RCU not yet watching. Both matter on their own; patches 23 and 24 are what made them visible.Patches 3-11 are one-line selects with no Alpha code behind them:
instrumentation (UBSAN, gcov, kmemleak), EDAC, and four properties Alpha has always had but never declared (LL/SC atomics, hardware multiply,__int128, the existingasm/compiler.h, and the non-overlapping user and kernel address spaces).Patches 12-17 add a small amount of code: an empty
thread_structwhitelist,_PAGE_SPECIALon a free PTE bit, the page table check helpers, and then the three things that follow from those - the page table helper self test, lockless GUP, and the early memtest. Note thatearly_memtest()is called fromarch_mm_preinit()rather thanpaging_init(), because Alpha callspaging_init()fromsetup_arch(), beforeparse_early_param()has seen the memtest= option.Patches 18-20 change something visible. Unhandled user faults now print the usual message under the debug.exception-trace sysctl. .eh_frame is
discarded: gcc emits it for Alpha regardless of -fno-asynchronous-unwind-tables, it was allocated in the loaded image, and nothing consumes it, since the stack trace code scans for text addresses rather than unwinding DWARF. That is worth about 1.1MB. With that and the relocation sections placed explicitly, the kernel links with no orphans left, so the last of the three asks the linker to say so.Patches 21-24 are the ones I expect to draw comment. Patch 22 adds a uapi header, so the perf register numbering is an ABI decision. Patch 23 is
SPARSE_IRQ: without it Marvel carries a 12.6MB static irq_desc[] in .data for 32768 possible interrupts, of which a real ES47 uses 87, and the kernel links at a fixed address just above the console reservation where that 12.6MB is the difference between fitting and not. Patch 24 instruments the entry assembly for lockdep hardirq tracking.Tested with gcc 17 under QEMU (-M clipper -smp 2, an
ALPHA_GENERICbuild) withPROVE_LOCKINGenabled: no splats,early_memtestpasses all four patterns over the free memblock ranges with nothing reserved,debug_vm_pgtablevalidates with no warning, avmsplice()of an anonymous mapping throughpin_user_pages_fast()returns the right data, and an unhandled SIGSEGV prints the new trace line. Patch 23 was tested on an AlphaServer ES47.Quoted 8 lines
Not included, and worth mentioning:
ARCH_HAS_KCOV. A kernel withKCOV_INSTRUMENT_ALLboots and runs, butCONFIG_KCOV_SELFTESTpanics. The self test deliberately arms kcov with no coverage area so that any instrumented function reached from interrupt context faults, checking that nothing escapes the window before the preempt count says hardirq. On Alpha something does. Patch 2 fixes one such site; the panic survives it, so the entry paths need an audit first.Thanks for taking the time to do this! This is a nice collection of patches. I've started on the review and testing, I will keep at it.
As general feedback for the series, I noticed that several of the corresponding architecture feature matrices still list Alpha as TODO. The Alpha entries should be changed to "ok" for:
ARCH_HAS_GCOV_PROFILE_ALL
HAVE_DEBUG_KMEMLEAK
ARCH_HAS_PTE_SPECIAL
ARCH_HAS_DEBUG_VM_PGTABLE
HAVE_PERF_REGS
HAVE_PERF_USER_STACK_DUMP
Quoted 3 lines
These correspond to patches 4, 5, 13, 15, and 22. It would probably be best to include each documentation update in the patch which enables the corresponding feature.
Oh, definitely. Thanks for catching that.
Quoted 6 lines
It would also be helpful if the next revision were rebased onto v7.3-rc1 and applied cleanly on top of my Alpha
GENERIC_ENTRYv5 series. I am currently testing only the patches which applied successfully.Alpha
GENERIC_ENTRYv5 series is available here:
https://lore.kernel.org/linux-alpha/[email protected]/T/#t
Perfect, I will do it!