From: Akihiko Odaki <akihiko.odaki@daynix.com>
To: "Alex Bennée" <alex.bennee@linaro.org>, qemu-devel@nongnu.org
Cc: "Sriram Yagnaraman" <sriram.yagnaraman@ericsson.com>,
"Michael S. Tsirkin" <mst@redhat.com>,
"Dmitry Osipenko" <dmitry.osipenko@collabora.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Peter Maydell" <peter.maydell@linaro.org>,
"John Snow" <jsnow@redhat.com>,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Pierrick Bouvier" <pierrick.bouvier@linaro.org>,
"Peter Xu" <peterx@redhat.com>, "Fabiano Rosas" <farosas@suse.de>,
qemu-arm@nongnu.org, "Thomas Huth" <thuth@redhat.com>,
"Alexandre Iooss" <erdnaxe@crans.org>,
"Gustavo Romero" <gustavo.romero@linaro.org>,
"Markus Armbruster" <armbru@redhat.com>,
"David Hildenbrand" <david@redhat.com>,
"Daniel P. Berrangé" <berrange@redhat.com>,
"Laurent Vivier" <lvivier@redhat.com>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Mahmoud Mandour" <ma.mandourr@gmail.com>,
"Julian Armistead" <julian.armistead@linaro.org>,
"Jim MacArthur" <jim.macarthur@linaro.org>
Subject: Re: [PATCH v4 03/17] tests/tcg: make aarch64 boot.S handle different starting modes
Date: Thu, 5 Jun 2025 17:29:16 +0900 [thread overview]
Message-ID: <e037e38c-dd8d-4f65-b2d5-2629be5f6740@daynix.com> (raw)
In-Reply-To: <20250603110204.838117-4-alex.bennee@linaro.org>
On 2025/06/03 20:01, Alex Bennée wrote:
> Currently the boot.S code assumes everything starts at EL1. This will
> break things like the memory test which will barf on unaligned memory
> access when run at a higher level.
>
> Adapt the boot code to do some basic verification of the starting mode
> and the minimal configuration to move to the lower exception levels.
> With this we can run the memory test with:
>
> -M virt,secure=on
> -M virt,secure=on,virtualization=on
> -M virt,virtualisation=on
>
> If a test needs to be at a particular EL it can use the semihosting
> command line to indicate the level we should execute in.
>
> Cc: Julian Armistead <julian.armistead@linaro.org>
> Cc: Jim MacArthur <jim.macarthur@linaro.org>
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
>
> ---
> v4
> - drop post eret nops
> - proper error string for EL0 error case
> - clamp any invalid target EL value to 1
> v3
> - create system stack so we _exit cleanly
> - normalise EL string before compares
> - catch when we start in a lower EL than we asked for
> - default to EL1 when arg unclear
> v2
> - allow tests to control the final EL we end up at
> - use tabs consistently
> - validate command line arg is between 1 and 3
> ---
> tests/tcg/aarch64/Makefile.softmmu-target | 3 +-
> tests/tcg/aarch64/system/boot.S | 172 +++++++++++++++++++++-
> 2 files changed, 169 insertions(+), 6 deletions(-)
>
> diff --git a/tests/tcg/aarch64/Makefile.softmmu-target b/tests/tcg/aarch64/Makefile.softmmu-target
> index 9c52475b7a..f7a7d2b800 100644
> --- a/tests/tcg/aarch64/Makefile.softmmu-target
> +++ b/tests/tcg/aarch64/Makefile.softmmu-target
> @@ -68,7 +68,8 @@ run-plugin-semiconsole-with-%: semiconsole
>
> # vtimer test needs EL2
> QEMU_EL2_MACHINE=-machine virt,virtualization=on,gic-version=2 -cpu cortex-a57 -smp 4
> -run-vtimer: QEMU_OPTS=$(QEMU_EL2_MACHINE) $(QEMU_BASE_ARGS) -kernel
> +QEMU_EL2_BASE_ARGS=-semihosting-config enable=on,target=native,chardev=output,arg="2"
> +run-vtimer: QEMU_OPTS=$(QEMU_EL2_MACHINE) $(QEMU_EL2_BASE_ARGS) -kernel
>
> # Simple Record/Replay Test
> .PHONY: memory-record
> diff --git a/tests/tcg/aarch64/system/boot.S b/tests/tcg/aarch64/system/boot.S
> index a5df9c173d..8bfa4e4efc 100644
> --- a/tests/tcg/aarch64/system/boot.S
> +++ b/tests/tcg/aarch64/system/boot.S
> @@ -16,6 +16,7 @@
> #define semihosting_call hlt 0xf000
> #define SYS_WRITEC 0x03 /* character to debug channel */
> #define SYS_WRITE0 0x04 /* string to debug channel */
> +#define SYS_GET_CMDLINE 0x15 /* get command line */
> #define SYS_EXIT 0x18
>
> .align 12
> @@ -70,21 +71,172 @@ lower_a32_sync:
> lower_a32_irq:
> lower_a32_fiq:
> lower_a32_serror:
> + adr x1, .unexp_excp
> +exit_msg:
> mov x0, SYS_WRITE0
> - adr x1, .error
> semihosting_call
> mov x0, 1 /* EXIT_FAILURE */
> bl _exit
> /* never returns */
>
> .section .rodata
> -.error:
> - .string "Terminated by exception.\n"
> +.unexp_excp:
> + .string "Unexpected exception.\n"
> +.high_el_msg:
> + .string "Started in lower EL than requested.\n"
> +.unexp_el0:
> + .string "Started in invalid EL.\n"
> +
> + .align 8
> +.get_cmd:
Please do not send a new version without addressing all comments for the
previous versions or at least noting there are unaddressed comments:
https://lore.kernel.org/qemu-devel/7a76e746-9022-48cf-8216-775071e6d631@daynix.com
Following the best practices in docs/devel/submitting-a-patch.rst will
ensure a smoother patch review. It is fine for me if you submit a new
version noting unaddressed comments, but some may disagree.
The same goes "[PATCH v4 11/17] ui/gtk-gl-area: Remove extra draw call
in refresh".
Regards,
Akihiko Odaki
> + .quad cmdline
> + .quad 128
>
> .text
> .align 4
> .global __start
> __start:
> + /*
> + * Initialise the stack for whatever EL we are in before
> + * anything else, we need it to be able to _exit cleanly.
> + * It's smaller than the stack we pass to the C code but we
> + * don't need much.
> + */
> + adrp x0, system_stack_end
> + add x0, x0, :lo12:system_stack_end
> + mov sp, x0
> +
> + /*
> + * The test can set the semihosting command line to the target
> + * EL needed for the test. However if no semihosting args are set we will
> + * end up with -kernel/-append data (see semihosting_arg_fallback).
> + * Keep the normalised target in w11.
> + */
> + mov x0, SYS_GET_CMDLINE
> + adr x1, .get_cmd
> + semihosting_call
> + adrp x10, cmdline
> + add x10, x10, :lo12:cmdline
> + ldrb w11, [x10]
> +
> + /* sanity check, normalise char to EL, clamp to 1 if outside range */
> + subs w11, w11, #'0'
> + b.lt el_default
> + cmp w11, #3
> + b.gt el_default
> + b 1f
> +
> +el_high:
> + adr x1, .high_el_msg
> + b exit_msg
> +
> +el_default:
> + mov w11, #1
> +
> +1:
> + /* Determine current Exception Level */
> + mrs x0, CurrentEL
> + lsr x0, x0, #2 /* CurrentEL[3:2] contains the current EL */
> +
> + /* Are we already in a lower EL than we want? */
> + cmp w11, w0
> + bgt el_high
> +
> + /* Branch based on current EL */
> + cmp x0, #3
> + b.eq setup_el3
> + cmp x0, #2
> + b.eq setup_el2
> + cmp x0, #1
> + b.eq at_testel /* Already at EL1, skip transition */
> +
> + /* Should not be at EL0 - error out */
> + adr x1, .unexp_el0
> + b exit_msg
> +
> +setup_el3:
> + /* Ensure we trap if we get anything wrong */
> + adr x0, vector_table
> + msr vbar_el3, x0
> +
> + /* Does the test want to be at EL3? */
> + cmp w11, #3
> + beq at_testel
> +
> + /* Configure EL3 to for lower states (EL2 or EL1) */
> + mrs x0, scr_el3
> + orr x0, x0, #(1 << 10) /* RW = 1: EL2/EL1 execution state is AArch64 */
> + orr x0, x0, #(1 << 0) /* NS = 1: Non-secure state */
> + msr scr_el3, x0
> +
> + /*
> + * We need to check if EL2 is actually enabled via ID_AA64PFR0_EL1,
> + * otherwise we should just jump straight to EL1.
> + */
> + mrs x0, id_aa64pfr0_el1
> + ubfx x0, x0, #8, #4 /* Extract EL2 field (bits 11:8) */
> + cbz x0, el2_not_present /* If field is 0 no EL2 */
> +
> +
> + /* Prepare SPSR for exception return to EL2 */
> + mov x0, #0x3c9 /* DAIF bits and EL2h mode (9) */
> + msr spsr_el3, x0
> +
> + /* Set EL2 entry point */
> + adr x0, setup_el2
> + msr elr_el3, x0
> +
> + /* Return to EL2 */
> + eret
> +
> +el2_not_present:
> + /* Initialize SCTLR_EL1 with reset value */
> + msr sctlr_el1, xzr
> +
> + /* Set EL1 entry point */
> + adr x0, at_testel
> + msr elr_el3, x0
> +
> + /* Prepare SPSR for exception return to EL1h with interrupts masked */
> + mov x0, #0x3c5 /* DAIF bits and EL1h mode (5) */
> + msr spsr_el3, x0
> +
> + isb /* Synchronization barrier */
> + eret /* Jump to EL1 */
> +
> +setup_el2:
> + /* Ensure we trap if we get anything wrong */
> + adr x0, vector_table
> + msr vbar_el2, x0
> +
> + /* Does the test want to be at EL2? */
> + cmp w11, #2
> + beq at_testel
> +
> + /* Configure EL2 to allow transition to EL1 */
> + mrs x0, hcr_el2
> + orr x0, x0, #(1 << 31) /* RW = 1: EL1 execution state is AArch64 */
> + msr hcr_el2, x0
> +
> + /* Initialize SCTLR_EL1 with reset value */
> + msr sctlr_el1, xzr
> +
> + /* Set EL1 entry point */
> + adr x0, at_testel
> + msr elr_el2, x0
> +
> + /* Prepare SPSR for exception return to EL1 */
> + mov x0, #(0x5 << 0) /* EL1h (SPx), with interrupts disabled */
> + msr spsr_el2, x0
> +
> + /* Return to EL1 */
> + eret
> +
> + /*
> + * At the target EL for the test, usually EL1. Note we still
> + * set everything up as if we were at EL1.
> + */
> +at_testel:
> /* Installs a table of exception vectors to catch and handle all
> exceptions by terminating the process with a diagnostic. */
> adr x0, vector_table
> @@ -100,7 +252,7 @@ __start:
> * maps RAM to the first Gb. The stage2 tables have two 2mb
> * translation block entries covering a series of adjacent
> * 4k pages.
> - */
> + */
>
> /* Stage 1 entry: indexed by IA[38:30] */
> adr x1, . /* phys address */
> @@ -198,7 +350,8 @@ __start:
> orr x0, x0, #(3 << 16)
> msr cpacr_el1, x0
>
> - /* Setup some stack space and enter the test code.
> + /*
> + * Setup some stack space before we enter the test code.
> * Assume everything except the return value is garbage when we
> * return, we won't need it.
> */
> @@ -233,6 +386,11 @@ __sys_outc:
> ret
>
> .data
> +
> + .align 8
> +cmdline:
> + .space 128, 0
> +
> .align 12
>
> /* Translation table
> @@ -246,6 +404,10 @@ ttb_stage2:
> .space 4096, 0
>
> .align 12
> +system_stack:
> + .space 4096, 0
> +system_stack_end:
> +
> stack:
> .space 65536, 0
> stack_end:
next prev parent reply other threads:[~2025-06-05 8:30 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-03 11:01 [PATCH v4 00/17] Maintainer updates for May (testing, plugins, virtio-gpu) - pre-PR Alex Bennée
2025-06-03 11:01 ` [PATCH v4 01/17] tests/docker: expose $HOME/.cache/qemu as docker volume Alex Bennée
2025-06-03 11:01 ` [PATCH v4 02/17] gitlab: disable debug info on CI builds Alex Bennée
2025-06-03 11:01 ` [PATCH v4 03/17] tests/tcg: make aarch64 boot.S handle different starting modes Alex Bennée
2025-06-05 8:29 ` Akihiko Odaki [this message]
2025-06-05 8:51 ` Alex Bennée
2025-06-06 9:53 ` Akihiko Odaki
2025-06-03 11:01 ` [PATCH v4 04/17] tests/qtest: Avoid unaligned access in IGB test Alex Bennée
2025-06-03 11:01 ` [PATCH v4 05/17] contrib/plugins: add a scaling factor to the ips arg Alex Bennée
2025-06-03 11:01 ` [PATCH v4 06/17] contrib/plugins: allow setting of instructions per quantum Alex Bennée
2025-06-03 11:01 ` [PATCH v4 07/17] MAINTAINERS: add myself to virtio-gpu for Odd Fixes Alex Bennée
2025-06-03 11:01 ` [PATCH v4 08/17] MAINTAINERS: add Akihiko and Dmitry as reviewers Alex Bennée
2025-06-05 8:35 ` Akihiko Odaki
2025-06-03 11:01 ` [PATCH v4 09/17] hw/display: re-arrange memory region tracking Alex Bennée
2025-06-05 8:34 ` Akihiko Odaki
2025-06-05 11:57 ` Alex Bennée
2025-06-06 9:40 ` Akihiko Odaki
2025-06-06 10:16 ` Alex Bennée
2025-06-06 15:02 ` Akihiko Odaki
2025-06-08 10:01 ` Akihiko Odaki
2025-06-03 11:01 ` [PATCH v4 10/17] virtio-gpu: refactor async blob unmapping Alex Bennée
2025-06-03 11:01 ` [PATCH v4 11/17] ui/gtk-gl-area: Remove extra draw call in refresh Alex Bennée
2025-06-03 11:01 ` [PATCH v4 12/17] virtio-gpu: support context init multiple timeline Alex Bennée
2025-06-03 11:02 ` [PATCH v4 13/17] include/exec: fix assert in size_memop Alex Bennée
2025-06-03 11:02 ` [PATCH v4 14/17] include/gdbstub: fix include guard in commands.h Alex Bennée
2025-06-03 11:02 ` [PATCH v4 15/17] gdbstub: assert earlier in handle_read_all_regs Alex Bennée
2025-06-03 11:02 ` [PATCH v4 16/17] gdbstub: Implement qGDBServerVersion packet Alex Bennée
2025-06-03 11:02 ` [PATCH v4 17/17] gdbstub: update aarch64-core.xml Alex Bennée
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=e037e38c-dd8d-4f65-b2d5-2629be5f6740@daynix.com \
--to=akihiko.odaki@daynix.com \
--cc=alex.bennee@linaro.org \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=david@redhat.com \
--cc=dmitry.osipenko@collabora.com \
--cc=erdnaxe@crans.org \
--cc=farosas@suse.de \
--cc=gustavo.romero@linaro.org \
--cc=jim.macarthur@linaro.org \
--cc=jsnow@redhat.com \
--cc=julian.armistead@linaro.org \
--cc=lvivier@redhat.com \
--cc=ma.mandourr@gmail.com \
--cc=marcandre.lureau@redhat.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=peterx@redhat.com \
--cc=philmd@linaro.org \
--cc=pierrick.bouvier@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=sriram.yagnaraman@ericsson.com \
--cc=thuth@redhat.com \
/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;
as well as URLs for NNTP newsgroup(s).