qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Akihiko Odaki <akihiko.odaki@daynix.com>
To: "Alex Bennée" <alex.bennee@linaro.org>, qemu-devel@nongnu.org
Cc: "Philippe Mathieu-Daudé" <philmd@linaro.org>,
	"David Hildenbrand" <david@redhat.com>,
	"Dmitry Osipenko" <dmitry.osipenko@collabora.com>,
	"Laurent Vivier" <lvivier@redhat.com>,
	qemu-arm@nongnu.org, "Mahmoud Mandour" <ma.mandourr@gmail.com>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Pierrick Bouvier" <pierrick.bouvier@linaro.org>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Sriram Yagnaraman" <sriram.yagnaraman@ericsson.com>,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>,
	"Peter Xu" <peterx@redhat.com>,
	"Daniel P. Berrangé" <berrange@redhat.com>,
	"John Snow" <jsnow@redhat.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	"Thomas Huth" <thuth@redhat.com>,
	"Fabiano Rosas" <farosas@suse.de>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	"Alexandre Iooss" <erdnaxe@crans.org>,
	"Julian Armistead" <julian.armistead@linaro.org>,
	"Jim MacArthur" <jim.macarthur@linaro.org>
Subject: Re: [PATCH v2 03/14] tests/tcg: make aarch64 boot.S handle different starting modes
Date: Sat, 10 May 2025 13:21:47 +0900	[thread overview]
Message-ID: <d2429cfd-d1b1-435c-b202-7f90f7365bf2@daynix.com> (raw)
In-Reply-To: <20250506125715.232872-4-alex.bennee@linaro.org>

On 2025/05/06 21:57, 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>
> 
> ---
> 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           | 135 +++++++++++++++++++++-
>   2 files changed, 136 insertions(+), 2 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..a52d28c881 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
> @@ -81,10 +82,137 @@ lower_a32_serror:
>   .error:
>   	.string "Terminated by exception.\n"
>   
> +	.align 8
> +.get_cmd:

This label is prefixed with a dot, which is inconsistent with the other 
labels except ".error".

I guess ".error" is prefixed with a dot to make it local, but a local 
symbol needs to be prefixed with ".L" instead according to:
https://sourceware.org/binutils/docs-2.41/as/Symbol-Names.html#Local-Symbol-Names

 > A local symbol is any symbol beginning with certain local label
 > prefixes. By default, the local label prefix is ‘.L’ for ELF systems
 > or ‘L’ for traditional a.out systems, but each target may have its own
 > set of local label prefixes. On the HPPA local symbols begin with
 > ‘L$’.

> +	.quad	cmdline
> +	.quad	128
> +
>   	.text
>   	.align 4
>   	.global __start
>   __start:
> +	/*
> +	 * The test can set the semihosting command line to the target
> +	 * EL needed for the test. Keep that in w11.
> +	 */
> +	mov	x0, SYS_GET_CMDLINE
> +	adr	x1, .get_cmd
> +	semihosting_call
> +	adrp	x10, cmdline
> +	add	x10, x10, :lo12:cmdline
 > +	ldrb	w11, [x10]> +	cbz	w11, 2f
> +
> +	/* sanity check, clamp to 1 if invalid */
> +	cmp w11, #'0'
> +	b.lt 1f
> +	cmp w11, #'4'
> +	b.ge 1f
> +	sub	w11, w11, #'0'
> +	b 2f
> +1:	mov w11, #1
> +
> +2:

This "sanity check" made me wonder what it is for. This code is simply 
unnecessary if any unknown values are to be ignored and is a bit 
misleading to have this code as it looks like it adds an additional 
behavior. "sub w11, w11, #'0'" is also unnecessary; we can compare w11 
with '2' and '3' later instead.

The patch message says this sanity check was added with v2 so I looked 
for a previous review and found this:
https://lore.kernel.org/qemu-devel/svmkvs.2mf5q4qhsfz83@linaro.org/

 > cmp w11, #'0'
 > b.lt curr_sp0_sync
 > cmp w11, #'4'
 > b.ge curr_sp0_sync

Now I get the original intent; it was to raise an error instead of 
simply ignoring unknown values. However I also see a few problems with 
this original code:
- It still ignores unknown strings that are longer than one character.
- curr_sp0_sync leads to the code that writes a message saying 
"Terminated by exception.", which is incorrect.
- "cmp w11, #'0'" is unnecessary if you check the value after "sub	w11, 
w11, #'0'".

> +	/* Determine current Exception Level */
> +	mrs	x0, CurrentEL
> +	lsr	x0, x0, #2	  /* CurrentEL[3:2] contains the current EL */
> +
> +	/* 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 */
> +	b	curr_sp0_sync
> +
> +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
> +	nop

Why is a nop placed here?

> +
> +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
> +
> +	nop
> +
> +	/*
> +	 * 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 +228,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 */
> @@ -233,6 +361,11 @@ __sys_outc:
>   	ret
>   
>   	.data
> +
> +	.align 8
> +cmdline:
> +	.space 128, 0
> +
>   	.align	12
>   
>   	/* Translation table



  reply	other threads:[~2025-05-10  4:22 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-06 12:57 [PATCH v2 00/14] Maintainer updates for May (testing, plugins, virtio-gpu) Alex Bennée
2025-05-06 12:57 ` [PATCH v2 01/14] tests/docker: expose $HOME/.cache/qemu as docker volume Alex Bennée
2025-05-06 12:57 ` [PATCH v2 02/14] gitlab: disable debug info on CI builds Alex Bennée
2025-05-06 12:57 ` [PATCH v2 03/14] tests/tcg: make aarch64 boot.S handle different starting modes Alex Bennée
2025-05-10  4:21   ` Akihiko Odaki [this message]
2025-05-14 13:51     ` Alex Bennée
2025-05-06 12:57 ` [PATCH v2 04/14] Running with --enable-ubsan leads to a qtest failure Alex Bennée
2025-05-10  4:27   ` Akihiko Odaki
2025-05-06 12:57 ` [PATCH v2 05/14] contrib/plugins: add a scaling factor to the ips arg Alex Bennée
2025-05-10  4:42   ` Akihiko Odaki
2025-05-19 14:54     ` Alex Bennée
2025-05-19 23:24       ` Akihiko Odaki
2025-05-06 12:57 ` [PATCH v2 06/14] contrib/plugins: allow setting of instructions per quantum Alex Bennée
2025-05-10  4:45   ` Akihiko Odaki
2025-05-19 15:14     ` Alex Bennée
2025-05-06 12:57 ` [PATCH v2 07/14] MAINTAINERS: add myself to virtio-gpu for Odd Fixes Alex Bennée
2025-05-06 12:57 ` [PATCH v2 08/14] MAINTAINERS: add Akihiko and Dmitry as reviewers Alex Bennée
2025-05-06 12:57 ` [PATCH v2 09/14] hw/display: re-arrange memory region tracking Alex Bennée
2025-05-06 12:57 ` [PATCH v2 10/14] virtio-gpu: fix hang under TCG when unmapping blob Alex Bennée
2025-05-06 12:57 ` [PATCH v2 11/14] virtio-gpu: refactor async blob unmapping Alex Bennée
2025-05-06 12:57 ` [PATCH v2 12/14] ui/gtk-gl-area: Remove extra draw call in refresh Alex Bennée
2025-05-10  4:52   ` Akihiko Odaki
2025-05-10 12:12     ` Dmitry Osipenko
2025-05-11  4:47       ` Akihiko Odaki
2025-05-12 17:01         ` Kim, Dongwon
2025-05-18  4:56           ` Akihiko Odaki
2025-05-06 12:57 ` [PATCH v2 13/14] docs: Create a uniquelabel Sphinx extension Alex Bennée
2025-05-06 12:57 ` [PATCH v2 14/14] docs: Use uniquelabel in qemu-block-drivers.rst.inc 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=d2429cfd-d1b1-435c-b202-7f90f7365bf2@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=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).