Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Mark Brown <broonie@kernel.org>
To: Catalin Marinas <catalin.marinas@arm.com>,
	 Will Deacon <will@kernel.org>, Shuah Khan <shuah@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>, Oliver Upton <oupton@kernel.org>,
	 Fuad Tabba <fuad.tabba@linux.dev>,
	Mark Rutland <mark.rutland@arm.com>,
	 linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	 linux-kselftest@vger.kernel.org, Mark Brown <broonie@kernel.org>
Subject: [PATCH 09/11] kselftest/arm64: Build KVM guest versions of the fp-stress loads
Date: Tue, 01 Sep 2026 18:06:49 +0100	[thread overview]
Message-ID: <20260901-arm64-fp-stress-kvm-v1-9-31bce995b49b@kernel.org> (raw)
In-Reply-To: <20260901-arm64-fp-stress-kvm-v1-0-31bce995b49b@kernel.org>

Now that all the Linux specifics have been factored out of the load
programs that fp-stress uses and we have a simple VMM we can build
versions for running with that VMM.  Provide an asm-utils-kvm.S with
startup code that's easier in the guest and implementations of the
functions that the programs call, writing output to the fixed address
expected by the VMM and using PSCI to shut down on error.

The programs are built into flat binaries to simplify the VMM, this is a
bit more Makefile effort but it's all fairly standard for bare metal
programming.

We install single instruction BRK handlers for all exceptions with the
expectation that the VMM will trap BRKs and log exception state, we do
not expect to trigger any exceptions in normal operation.

We log the current EL to help with diagnostics.

Since we're constantly reading and writing the contents of the floating
point registers to and from memory there is fairly heavy memory traffic.
We do not currently turn the MMU on so on hardware the number of
iterations a test does will be very much lower that that seen on the
host, this can be addressed in future.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 tools/testing/selftests/arm64/fp/.gitignore        |  3 +
 tools/testing/selftests/arm64/fp/Makefile          | 40 +++++++++-
 tools/testing/selftests/arm64/fp/asm-utils-kvm.S   | 86 ++++++++++++++++++++++
 .../testing/selftests/arm64/fp/fp-stress-kvm.lds.S | 58 +++++++++++++++
 4 files changed, 186 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore
index 229a5c65b65f..7a788b23ae76 100644
--- a/tools/testing/selftests/arm64/fp/.gitignore
+++ b/tools/testing/selftests/arm64/fp/.gitignore
@@ -1,6 +1,7 @@
 fp-pidbench
 fp-ptrace
 fp-stress
+fp-stress-kvm.lds
 fp-stress-vmm
 fpsimd-test
 kernel-test
@@ -17,3 +18,5 @@ za-ptrace
 za-test
 zt-ptrace
 zt-test
+*-kvm.bin
+*-kvm.elf
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index 3c4e17a34776..5322cb66f0a9 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -21,17 +21,41 @@ TEST_GEN_PROGS_EXTENDED := fp-pidbench fp-stress-vmm fpsimd-test \
 	zt-test \
 	vlset
 TEST_PROGS_EXTENDED := fpsimd-stress sve-stress ssve-stress za-stress
+TEST_GEN_FILES := \
+	fpsimd-test-kvm.bin \
+	sve-test-kvm.bin \
+	ssve-test-kvm.bin \
+	za-test-kvm.bin \
+	zt-test-kvm.bin
 
 EXTRA_CLEAN += $(OUTPUT)/asm-utils.o $(OUTPUT)/asm-utils-linux.o \
-	$(OUTPUT)/rdvl.o $(OUTPUT)/za-fork-asm.o
+	$(OUTPUT)/rdvl.o $(OUTPUT)/za-fork-asm.o \
+	$(patsubst %.bin,%.elf,$(TEST_GEN_FILES)) \
+	$(KVM_LDS)
 
 ASM_UTILS_LINUX := $(OUTPUT)/asm-utils.o $(OUTPUT)/asm-utils-linux.o
+ASM_UTILS_KVM := asm-utils.S asm-utils-kvm.S
+
+OBJCOPY ?= $(CROSS_COMPILE)objcopy
 
 # For sysreg definitons
 ARCH_INCLUDES := $(KHDR_INCLUDES) -I$(top_srcdir)/tools/arch/arm64/include \
 	-I$(top_srcdir)/tools/include \
 	-I$(top_srcdir)/tools/include/generated
 
+# The guests run with no OS under them at all, link them as flat binaries
+# with the link script placing them where fp-stress-vmm puts their RAM.
+KVM_LDS := $(OUTPUT)/fp-stress-kvm.lds
+KVM_LDFLAGS := -nostdlib -static $(ARCH_INCLUDES) -D__ASSEMBLY__ \
+	-Wl,-T,$(KVM_LDS)
+
+# Supported/required from GNU ld 2.39, not confirmed LLD but after 22.1.2
+COMMA=,
+KVM_LDFLAGS += $(call try-run,$(LD) --warn-rwx-segments -v,-Wl$(COMMA)--warn-rwx-segments)
+
+$(KVM_LDS): fp-stress-kvm.lds.S fp-stress-vmm.h
+	$(CC) -E -P -x c $< -o $@
+
 $(OUTPUT)/fp-stress-vmm: CFLAGS += $(ARCH_INCLUDES)
 
 # Build with nolibc to avoid effects due to libc's clone() support
@@ -61,4 +85,18 @@ $(OUTPUT)/zt-ptrace: zt-ptrace.c
 $(OUTPUT)/zt-test: zt-test.S $(ASM_UTILS_LINUX)
 	$(CC) -nostdlib $^ -o $@
 
+$(OUTPUT)/fpsimd-test-kvm.elf: fpsimd-test.S $(ASM_UTILS_KVM) $(KVM_LDS)
+	$(CC) $(KVM_LDFLAGS) $(filter %.S,$^) -o $@
+$(OUTPUT)/sve-test-kvm.elf: sve-test.S $(ASM_UTILS_KVM) $(KVM_LDS)
+	$(CC) $(KVM_LDFLAGS) $(filter %.S,$^) -o $@
+$(OUTPUT)/ssve-test-kvm.elf: sve-test.S $(ASM_UTILS_KVM) $(KVM_LDS)
+	$(CC) -DSSVE $(KVM_LDFLAGS) $(filter %.S,$^) -o $@
+$(OUTPUT)/za-test-kvm.elf: za-test.S $(ASM_UTILS_KVM) $(KVM_LDS)
+	$(CC) $(KVM_LDFLAGS) $(filter %.S,$^) -o $@
+$(OUTPUT)/zt-test-kvm.elf: zt-test.S $(ASM_UTILS_KVM) $(KVM_LDS)
+	$(CC) $(KVM_LDFLAGS) $(filter %.S,$^) -o $@
+
+$(OUTPUT)/%-kvm.bin: $(OUTPUT)/%-kvm.elf
+	$(OBJCOPY) -O binary $< $@
+
 include ../../lib.mk
diff --git a/tools/testing/selftests/arm64/fp/asm-utils-kvm.S b/tools/testing/selftests/arm64/fp/asm-utils-kvm.S
new file mode 100644
index 000000000000..422d6425ab56
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/asm-utils-kvm.S
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Utility functions for assembly code programs run under fp-stress-vmm.
+//
+// Copyright 2026, Arm Ltd
+
+#include <asm/sysreg.h>
+
+#include "assembler.h"
+#include "asm-offsets.h"
+#include "fp-stress-vmm.h"
+
+#define PSCI_0_2_FN_SYSTEM_OFF		0x84000008
+
+// Print a single character x0 to the console
+// Clobbers x1
+function putc
+	movz	x1, #(CONSOLE_BASE >> 16), lsl #16
+	strb	w0, [x1]
+	ret
+endfunction
+.globl	putc
+
+// Print a \0 terminated string starting at address x0 to the console.
+// Doesn't use putc as a slight optimisation.
+// Clobbers x0-x3
+function puts
+	mov	x2, x0
+	movz	x3, #(CONSOLE_BASE >> 16), lsl #16
+
+0:	ldrb	w0, [x2], #1
+	cbz	w0, 1f
+	strb	w0, [x3]
+	b	0b
+
+1:	ret
+endfunction
+.globl	puts
+
+// Report errors to the host by shutting down, there is no other reason one
+// of these test programs should exit.
+function exit_error
+	movz	x0, #(PSCI_0_2_FN_SYSTEM_OFF >> 16), lsl #16
+	movk	x0, #(PSCI_0_2_FN_SYSTEM_OFF & 0xffff)
+	hvc	#0
+
+0:	b	0b		// PSCI should not have returned
+endfunction
+.globl	exit_error
+
+// Exception vectors.  We have no handlers for anything so each entry
+// just BRKs with its own number.
+	.balign	2048
+vectors:
+	.irp	vector, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+	.balign	0x80
+	brk	#\vector
+	.endr
+
+// Main program entry point.
+//
+// The VMM starts us at the very start of the image so the link script
+// places .text.boot first.
+	.section .text.boot, "ax"
+.globl _start
+function _start
+	// Vectors that report any exception we take to the VMM.
+	adr	x0, vectors
+	msr	VBAR_EL1, x0
+
+	// The VMM sizes our RAM as the image plus GUEST_EXTRA_RAM, put the
+	// stack at the top of that so it grows down away from the image.
+	ldr	x0, =_end
+	ldr	x1, =GUEST_EXTRA_RAM
+	add	x0, x0, x1
+	and	x0, x0, #~15
+	mov	sp, x0
+
+	// Log the current EL for diagnostic purposes.
+	puts	"EL:\t\tEL"
+	mrs	x0, CurrentEL
+	ubfx	x0, x0, #2, #2
+	bl	putdecn
+
+	b	main
+endfunction
diff --git a/tools/testing/selftests/arm64/fp/fp-stress-kvm.lds.S b/tools/testing/selftests/arm64/fp/fp-stress-kvm.lds.S
new file mode 100644
index 000000000000..f1d44f0ae49c
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/fp-stress-kvm.lds.S
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Link script for the flat binary builds of the fp-stress loads which run
+ * as guests under fp-stress-vmm.
+ *
+ * The VMM loads the image at the start of the guest RAM and starts the
+ * guest there so the startup code has to be first in the image, it is in
+ * .text.boot for that.
+ */
+
+#include "fp-stress-vmm.h"
+
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+
+SECTIONS
+{
+	. = GUEST_RAM_BASE;
+
+	.text : {
+		*(.text.boot)
+		*(.text)
+		*(.text.*)
+	}
+
+	.rodata : {
+		*(.rodata)
+		*(.rodata.*)
+	}
+
+	.data : {
+		*(.data)
+		*(.data.*)
+	}
+
+	.bss : {
+		*(.bss)
+		*(.bss.*)
+		*(COMMON)
+	}
+
+	. = ALIGN(16);
+	_end = .;
+
+	/DISCARD/ : {
+		*(.note*)
+		*(.comment)
+		*(.eh_frame*)
+	}
+}
+
+/*
+ * The VMM sizes the guest RAM from the size of the image file and the
+ * guest puts its stack immediately above _end, anything allocated but not
+ * present in the file would leave the two disagreeing about where the RAM
+ * ends.
+ */
+ASSERT(SIZEOF(.bss) == 0, "fp-stress guests must not have a .bss")

-- 
2.47.3



  parent reply	other threads:[~2026-09-01 17:10 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-01 17:06 [PATCH 00/11] kselftest/arm64: Add coverage of interactions with KVM to fp-stress Mark Brown
2026-09-01 17:06 ` [PATCH 01/11] kselftest/arm64: Factor Linux syscalls out of asm-utils.S Mark Brown
2026-09-01 17:06 ` [PATCH 02/11] kselftest/arm64: Factor shared signal handlers out of fp-stress loads Mark Brown
2026-09-01 17:06 ` [PATCH 03/11] kselftest/arm64: Move exit calls " Mark Brown
2026-09-01 17:06 ` [PATCH 04/11] kselftest/arm64: Use exit_error() rather than SIGABRT in fp-stress Mark Brown
2026-09-01 17:06 ` [PATCH 05/11] kselftest/arm64: Exit with an error code on data mismatches " Mark Brown
2026-09-01 17:06 ` [PATCH 06/11] kselftest/arm64: Factor startup code out of fp-stress load programs Mark Brown
2026-09-01 17:06 ` [PATCH 07/11] kselftest/arm64: Remove the sched_yield()s from the fp-stress loads Mark Brown
2026-09-01 17:06 ` [PATCH 08/11] kselftest/arm64: Add a very simple VMM for use in fp-stress Mark Brown
2026-09-01 17:06 ` Mark Brown [this message]
2026-09-01 17:06 ` [PATCH 10/11] kselftest/arm64: Use execv() to start fp-stress test loads Mark Brown
2026-09-01 17:06 ` [PATCH 11/11] kselftest/arm64: Run KVM guests from fp-stress Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260901-arm64-fp-stress-kvm-v1-9-31bce995b49b@kernel.org \
    --to=broonie@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=fuad.tabba@linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=maz@kernel.org \
    --cc=oupton@kernel.org \
    --cc=shuah@kernel.org \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox