Re: [PATCH v3 0/3] sparc32: allow a kernel loaded away from the start of RAM

From: Andreas Larsson

Date: Wed Oct 07 2026 - 01:28:29 EST


On 2026-09-28 22:06, Magnus Lindholm wrote:
> Many years ago I ran Linux on my SPARCstation hardware and tried to keep
> up with new releases, but somewhere around 3.x I hit a wall, sooner for
> SMP builds since they are larger. As the kernel grew it simply became too
> big for SILO to load. On this machine the last one that fit was 2.6.32,
> at 2598956 bytes against a 2605056 byte window: six kilobytes to spare.
> 3.12 was 184KB over. Fixing it turned out to need more than SILO changes,
> the kernel side needed work too, and I never got around to giving it
> serious thought. I recently dusted off my old SPARCs and picked the
> journey back up.
>
> Link to SILO repo containing fixes:
> https://github.com/linmag7/silo/tree/release
>
> A current sparc32 kernel no longer fits in the window SILO loads into:
> 0x4000 up to SILO's own text at 0x280000, about 2.5MB. Loading it higher
> instead exposes two places that assume the kernel sits at the start of
> RAM.
>
> Patch 1 is an independent pre-existing bug. viking_flush_page() and
> viking_mxcc_flush_page() compute a physical address as vaddr -
> PAGE_OFFSET, which is __pa() without phys_base. It is wrong regardless of
> the rest of this series; it simply cannot be observed while phys_base is
> zero. When it is not, iommu_flush_iotlb() flushes the wrong page, the
> IOMMU walks stale IOPTEs and every DMA transfer fails. It comes first so
> that no commit in the series leaves Viking DMA broken.
>
> Patch 2 makes setup_arch() discover a non-zero phys_base. It takes it from
> the lowest sp_banks[] entry today, and phys_base is the offset __pa() and
> __va() are defined in terms of, so once the kernel is loaded elsewhere
> every early translation is wrong by the difference, including the physical
> addresses written into page table descriptors. The tablewalker then
> follows pointers into pages holding nothing, while the same tables read
> back correctly through the nocache view, and the machine stops right after
> the context table pointer is installed with no console left to say why.
> The probe is the architecture's existing __get_phys(), which already
> implements it for sun4m and sun4d. The probe and diagnostic are limited
> to those platforms, avoiding a bogus kernel address on LEON.
>
> Patch 3 sets HdrS to 0x0300, the protocol level that tells a boot loader
> the kernel supports being located somewhere other than physical 0x4000.
>
> No change in behaviour when phys_base is zero.
>
> Changes since v2:
> - restrict the PAGE_OFFSET probe and diagnostic to sun4m and sun4d,
> avoiding a bogus kernel address on LEON (Andreas Larsson)
> - fix the diagnostic wording to "RAM starts at" (Andreas Larsson)
>
> Patches 1 and 3 are unchanged from v2.
>
> Changes since v1:
> - drop the (unsigned int) casts and print with %lx (Sam Ravnborg)
> - always report RAM start and kernel start, not only when they differ
> (Sam Ravnborg); in v3 this reporting is limited to sun4m and sun4d
> - collect Reviewed-by from Sam Ravnborg on patches 1 and 3
>
> Patches 1 and 3 are unchanged from v1 apart from the collected tag.
>
> The v2 series was tested on a SPARCstation 20 booting from SCSI to a
> full userspace, with and without an initramfs, using a SILO carrying the
> matching loader changes. Also boot tested under qemu-system-sparc -M
> SS-5, and build tested for LEON and plain sparc32_defconfig. Each commit
> builds on its own.
> The v3 version has been build and boot-tested on the SS-20. Emulation
> cannot exercise patch 1: microSPARC-II takes a different cache flush
> path, and qemu models no write-back cache, so a missed flush has no
> consequence there.
>
> The cost is the RAM below the load address, which the loader chooses.
>
> Magnus Lindholm (3):
> sparc32: honour phys_base in the viking cache flush routines
> sparc32: derive phys_base from the PAGE_OFFSET mapping
> sparc32: advertise relocatable kernel with HdrS 0x0300
>
> arch/sparc/kernel/head_32.S | 2 +-
> arch/sparc/kernel/setup_32.c | 40 ++++++++++++++++++++++++++++++++++++
> arch/sparc/mm/viking.S | 6 ++++++
> 3 files changed, 47 insertions(+), 1 deletion(-)
>

Tested on LEON.

Reviewed-by: Andreas Larsson <andreas@xxxxxxxxxxx>
Tested-by: Andreas Larsson <andreas@xxxxxxxxxxx>

Picking this up to my for-next.

Thanks,
Andreas