Kernel KVM virtualization development
 help / color / mirror / Atom feed
* [kvm-unit-tests PATCH v2] realmode: load above stack
@ 2026-05-06 13:06 Thomas Huth
  0 siblings, 0 replies; only message in thread
From: Thomas Huth @ 2026-05-06 13:06 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm

From: Paolo Bonzini <pbonzini@redhat.com>

The bottom 32K of memory are generally reserved for use by the BIOS;
for example, traditionally the boot loader is placed at 0x7C00 and
the stack grows below that address.

It turns out that with some versions of clang, realmode.flat has
become big enough that it overlaps the stack used by the multiboot
option ROM loader.  The result is that a couple instructions are
overwritten.  Typically one or two tests fail and that's it...

Move the code above the forbidden region, in real 90s style.

Additionally, we've got to compile the test with -Os now, otherwise
the code might get too big when compiling with older versions of clang
(e.g. Clang v20), so linking fails with:

 x86/realmode.o: In function `realmode_start':
 realmode.c:(.text+0x79): relocation truncated to fit: R_386_16 against `.bss'
 realmode.c:(.text+0x82): relocation truncated to fit: R_386_16 against `.bss'
 realmode.c:(.text+0x8b): relocation truncated to fit: R_386_16 against `.bss'
 realmode.c:(.text+0x94): relocation truncated to fit: R_386_16 against `.bss'

Unfortunately, the -Os triggers compiler warnings in this code
with GCC v16:

 In function ‘test_int’,
     inlined from ‘realmode_start’ at x86/realmode.c:1781:2:
 x86/realmode.c:828:28: error: array subscript 0 is outside array bounds
  of ‘u32[0]’ {aka ‘unsigned int[]’} [-Werror=array-bounds=]
   828 |         *(u32 *)(0x11 * 4) = 0x1000; /* Store a pointer to address 0x1000 in IDT entry 0x11 */
       |         ~~~~~~~~~~~~~~~~~~~^~~~~~~~
 In function ‘realmode_start’:
 cc1: note: source object is likely at address zero
 In function ‘test_sti_inhibit’,
     inlined from ‘realmode_start’ at x86/realmode.c:1782:2:
 x86/realmode.c:841:28: error: array subscript 0 is outside array bounds
  of ‘u32[0]’ {aka ‘unsigned int[]’} [-Werror=array-bounds=]
   841 |         *(u32 *)(0x73 * 4) = 0x1000; /* Store IRQ 11 handler in the IDT */
       |         ~~~~~~~~~~~~~~~~~~~^~~~~~~~
 In function ‘realmode_start’:
 cc1: note: source object is likely at address zero
 cc1: all warnings being treated as errors

... so additionally we also have to compile this test with this warning
disabled now.

Reported-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-ID: <20240604143507.1041901-1-pbonzini@redhat.com>
[thuth: Add -Os and -Wno-array-bounds to CFLAGS to avoid other problems]
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 x86/Makefile.common | 1 +
 x86/realmode.lds    | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/x86/Makefile.common b/x86/Makefile.common
index ef0e09a6..a251dd71 100644
--- a/x86/Makefile.common
+++ b/x86/Makefile.common
@@ -112,6 +112,7 @@ $(TEST_DIR)/realmode.elf: $(TEST_DIR)/realmode.o $(SRCDIR)/$(TEST_DIR)/realmode.
 	      -T $(SRCDIR)/$(TEST_DIR)/realmode.lds $(filter %.o, $^)
 
 $(TEST_DIR)/realmode.o: bits = $(realmode_bits)
+$(TEST_DIR)/realmode.o: CFLAGS += -Os -Wno-array-bounds
 
 $(TEST_DIR)/access_test.$(bin): $(TEST_DIR)/access.o
 
diff --git a/x86/realmode.lds b/x86/realmode.lds
index 0ed3063b..e4782a98 100644
--- a/x86/realmode.lds
+++ b/x86/realmode.lds
@@ -1,6 +1,6 @@
 SECTIONS
 {
-    . = 16K;
+    . = 32K;
     stext = .;
     .text : { *(.init) *(.text) }
     . = ALIGN(4K);
-- 
2.54.0


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-05-06 13:06 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-06 13:06 [kvm-unit-tests PATCH v2] realmode: load above stack Thomas Huth

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox