Skip to content

Commit 3b4fe25

Browse files
committed
arch: correct the riscv64 module-band comment, and separate two axes
The riscv64 header said modules sit ABOVE the image's _end. They do not: MODULES_VADDR is _end - 2 GiB and MODULES_END is _start, so the band runs below the image, the same side as s390. What actually differs between the two is which end of the image the band's low edge is pinned to, and that is what decides where MODULES_END_TO_TEXT_OFFSET lands — on the text base for s390, on _end for riscv64, which is why module_text_bound then subtracts a minimum image size there. Say that instead. DIRECTMAP_STATIC and TEXT_TRACKS_DIRECTMAP answer different questions — one gates the compile-time linear-map projections, the other whether a physical bound may reach the virtual text base — but they hold the same value on all twelve supported architectures, so no in-tree header demonstrates the difference and neither can be inferred from the other by example. Record both shapes that would separate them, and that the pair must be picked by the question being asked.
1 parent 5c4fedb commit 3b4fe25

2 files changed

Lines changed: 40 additions & 6 deletions

File tree

src/include/kasld/api.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,31 @@ __extension__ _Static_assert((unsigned long)KERNEL_PHYS_MAX >
237237
/* DIRECTMAP_STATIC and TEXT_TRACKS_DIRECTMAP must be declared by every arch
238238
* header — no defaults. Forcing each arch author to make the decision
239239
* explicitly is the whole point. See the arch-header contract banner above
240-
* for the 0/1 semantics. */
240+
* for the 0/1 semantics.
241+
*
242+
* The two answer different questions, and both are read on their own:
243+
* DIRECTMAP_STATIC decides whether phys_to_directmap_virt() and
244+
* directmap_virt_to_phys() are defined at all, so it gates every compile-time
245+
* linear-map projection; TEXT_TRACKS_DIRECTMAP decides whether a physical
246+
* bound may propagate to the virtual text base.
247+
*
248+
* They nonetheless hold the SAME value on every architecture supported today,
249+
* so no in-tree arch demonstrates the difference and neither can be inferred
250+
* from the other by example. Pick by the question being asked, not by what a
251+
* neighbouring header happens to say. The pair separates as soon as an arch
252+
* fixes one of the two independently:
253+
*
254+
* DIRECTMAP_STATIC=1, TEXT_TRACKS_DIRECTMAP=0 — the linear map sits at its
255+
* compile-time address while the image is randomized independently of it
256+
* (x86_64 built without RANDOMIZE_MEMORY is exactly this shape; KASLD models
257+
* x86_64 with DIRECTMAP_STATIC=0 because it cannot prove the build).
258+
*
259+
* DIRECTMAP_STATIC=0, TEXT_TRACKS_DIRECTMAP=1 — text keeps a fixed offset
260+
* inside a linear map whose own base is randomized, so the offset is known
261+
* but neither endpoint is.
262+
*
263+
* Treating them as one flag would silently pick a side on whichever arch
264+
* arrives first. */
241265
#ifndef DIRECTMAP_STATIC
242266
#error "arch header must define DIRECTMAP_STATIC (0 or 1)"
243267
#endif

src/include/kasld/arch/riscv64.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,21 @@
9696

9797
// Module region is anchored to kernel _end (shifts with KASLR)
9898
#define MODULES_RELATIVE_TO_TEXT 1
99-
// MODULES_BELOW_TEXT_START selects the s390-style "Case B" placement
100-
// (module band sits below the image). riscv64 puts modules ABOVE the
101-
// image's _end, so explicitly 0 — needed (not just implicit-zero) so
102-
// -Wundef does not fire at the `#if MODULES_BELOW_TEXT_START` sites in
103-
// orchestrator.c + rules/module_text_bound.c (those sites are gated on
99+
// MODULES_BELOW_TEXT_START selects which end of the image the band is
100+
// measured from, which decides what MODULES_END_TO_TEXT_OFFSET added to the
101+
// lowest module address yields. Both riscv64 and s390 place the band below
102+
// the image; they differ in what its low edge is pinned to:
103+
//
104+
// s390 (1): MODULES_END = round_down(_text), low edge = that - 2 GiB,
105+
// so lowest module + offset bounds the TEXT BASE directly.
106+
// riscv64 (0): MODULES_VADDR = _end - 2 GiB (MODULES_END = _start), so the
107+
// low edge tracks _end and lowest module + offset bounds _END;
108+
// module_text_bound then subtracts a minimum image size to
109+
// reach the text base.
110+
//
111+
// Explicit 0 rather than implicit-zero so -Wundef does not fire at the
112+
// `#if MODULES_BELOW_TEXT_START` sites in orchestrator.c +
113+
// rules/module_text_bound.c (those sites are gated on
104114
// MODULES_RELATIVE_TO_TEXT so they're only reachable on riscv64 + s390).
105115
#define MODULES_BELOW_TEXT_START 0
106116
#define MODULES_END_TO_TEXT_OFFSET 0x80000000ul /* 2 GiB */

0 commit comments

Comments
 (0)