[PATCH v7 25/25] tests: add test with interrupted memory accesses on rv64

Julian Ganz posted 25 patches 4 months ago
Maintainers: "Alex Bennée" <alex.bennee@linaro.org>, Alexandre Iooss <erdnaxe@crans.org>, Mahmoud Mandour <ma.mandourr@gmail.com>, Pierrick Bouvier <pierrick.bouvier@linaro.org>, Richard Henderson <richard.henderson@linaro.org>, Peter Maydell <peter.maydell@linaro.org>, Michael Rolnik <mrolnik@gmail.com>, Helge Deller <deller@gmx.de>, Paolo Bonzini <pbonzini@redhat.com>, Eduardo Habkost <eduardo@habkost.net>, Song Gao <gaosong@loongson.cn>, Laurent Vivier <laurent@vivier.eu>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Aurelien Jarno <aurelien@aurel32.net>, Jiaxun Yang <jiaxun.yang@flygoat.com>, Aleksandar Rikalo <arikalo@gmail.com>, Stafford Horne <shorne@gmail.com>, Nicholas Piggin <npiggin@gmail.com>, Chinmay Rath <rathc@linux.ibm.com>, Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <dbarboza@ventanamicro.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>, Yoshinori Sato <yoshinori.sato@nifty.com>, David Hildenbrand <david@redhat.com>, Ilya Leoshkevich <iii@linux.ibm.com>, Thomas Huth <thuth@redhat.com>, Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>, Artyom Tarasenko <atar4qemu@gmail.com>, Bastian Koppelmann <kbastian@mail.uni-paderborn.de>, Max Filippov <jcmvbkbc@gmail.com>
There is a newer version of this series
[PATCH v7 25/25] tests: add test with interrupted memory accesses on rv64
Posted by Julian Ganz 4 months ago
This test aims at catching API misbehaviour w.r.t. the interaction
between interrupts and memory accesses, such as the bug fixed in

    27f347e6a1d269c533633c812321cabb249eada8

Because the condition for triggering misbehaviour may not be
deterministic and the cross-section between memory accesses and
interrupt handlers may be small, we have to place our trust in large
numbers. Instead of guessing/trying an arbitrary, fixed loop-bound, we
decided to loop for a fixed amount of real-time. This avoids the test
running into a time-out on slower machines while enabling a high number
of possible interactions on faster machines.

Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Signed-off-by: Julian Ganz <neither@nut.email>
---
 tests/tcg/riscv64/Makefile.softmmu-target |  6 ++
 tests/tcg/riscv64/interruptedmemory.S     | 67 +++++++++++++++++++++++
 2 files changed, 73 insertions(+)
 create mode 100644 tests/tcg/riscv64/interruptedmemory.S

diff --git a/tests/tcg/riscv64/Makefile.softmmu-target b/tests/tcg/riscv64/Makefile.softmmu-target
index 1a71a78653..d8f92b8e61 100644
--- a/tests/tcg/riscv64/Makefile.softmmu-target
+++ b/tests/tcg/riscv64/Makefile.softmmu-target
@@ -30,5 +30,11 @@ run-plugin-doubletrap: doubletrap
 	  $(QEMU) -plugin ../plugins/libdiscons.so -d plugin -D $*.pout \
 	  $(QEMU_OPTS)$<)
 
+EXTRA_RUNS += run-plugin-interruptedmemory
+run-plugin-interruptedmemory: interruptedmemory
+	$(call run-test, $<, \
+	  $(QEMU) -plugin ../plugins/libdiscons.so -d plugin -D $*.pout \
+	  $(QEMU_OPTS)$<)
+
 # We don't currently support the multiarch system tests
 undefine MULTIARCH_TESTS
diff --git a/tests/tcg/riscv64/interruptedmemory.S b/tests/tcg/riscv64/interruptedmemory.S
new file mode 100644
index 0000000000..a32d672849
--- /dev/null
+++ b/tests/tcg/riscv64/interruptedmemory.S
@@ -0,0 +1,67 @@
+	.option norvc
+
+	.text
+	.global _start
+_start:
+	# Set up trap vector
+	lla	t0, trap
+	csrw	mtvec, t0
+
+	# Set up timer
+	lui	t1, 0x02004
+	sd	zero, 0(t1) # MTIMECMP0
+
+	# Enable timer interrupts
+	li	t0, 0x80
+	csrrs	zero, mie, t0
+	csrrsi	zero, mstatus, 0x8
+
+	# Find out when to stop
+	call	rtc_get
+	li	t0, 60
+	slli	t0, t0, 30 # Approx. 10e9 ns
+	add	t0, t0, a0
+
+	# Loop with memory accesses
+	la	t1, semiargs
+0:
+	ld	t2, 0(t1)
+	sd	t2, 0(t1)
+	call	rtc_get
+	bltu	a0, t0, 0b
+
+	li	a0, 0
+	lla	a1, semiargs
+	li	t0, 0x20026	# ADP_Stopped_ApplicationExit
+	sd	t0, 0(a1)
+	sd	a0, 8(a1)
+	li	a0, 0x20	# TARGET_SYS_EXIT_EXTENDED
+
+	# Semihosting call sequence
+	.balign	16
+	slli	zero, zero, 0x1f
+	ebreak
+	srai	zero, zero, 0x7
+	j	.
+
+rtc_get:
+	# Get current time from the goldfish RTC
+	lui	t3, 0x0101
+	lw	a0, 0(t3)
+	lw	t3, 4(t3)
+	slli	t3, t3, 32
+	add	a0, a0, t3
+	ret
+
+trap:
+	lui	t5, 0x0200c
+	ld	t6, -0x8(t5) # MTIME
+	addi	t6, t6, 100
+	lui	t5, 0x02004
+	sd	t6, 0(t5) # MTIMECMP
+	mret
+
+	.data
+	.balign	16
+semiargs:
+	.space	16
-- 
2.49.1
Re: [PATCH v7 25/25] tests: add test with interrupted memory accesses on rv64
Posted by Alex Bennée 3 months, 3 weeks ago
Julian Ganz <neither@nut.email> writes:

> This test aims at catching API misbehaviour w.r.t. the interaction
> between interrupts and memory accesses, such as the bug fixed in
>
>     27f347e6a1d269c533633c812321cabb249eada8

Even better the abbrev with title:

  27f347e6a1d (accel/tcg: also suppress asynchronous IRQs for cpu_io_recompile)

> Because the condition for triggering misbehaviour may not be
> deterministic and the cross-section between memory accesses and
> interrupt handlers may be small, we have to place our trust in large
> numbers. Instead of guessing/trying an arbitrary, fixed loop-bound, we
> decided to loop for a fixed amount of real-time. This avoids the test
> running into a time-out on slower machines while enabling a high number
> of possible interactions on faster machines.
>
> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> Signed-off-by: Julian Ganz <neither@nut.email>
> ---
>  tests/tcg/riscv64/Makefile.softmmu-target |  6 ++
>  tests/tcg/riscv64/interruptedmemory.S     | 67 +++++++++++++++++++++++
>  2 files changed, 73 insertions(+)
>  create mode 100644 tests/tcg/riscv64/interruptedmemory.S
>
> diff --git a/tests/tcg/riscv64/Makefile.softmmu-target b/tests/tcg/riscv64/Makefile.softmmu-target
> index 1a71a78653..d8f92b8e61 100644
> --- a/tests/tcg/riscv64/Makefile.softmmu-target
> +++ b/tests/tcg/riscv64/Makefile.softmmu-target
> @@ -30,5 +30,11 @@ run-plugin-doubletrap: doubletrap
>  	  $(QEMU) -plugin ../plugins/libdiscons.so -d plugin -D $*.pout \
>  	  $(QEMU_OPTS)$<)
>  
> +EXTRA_RUNS += run-plugin-interruptedmemory
> +run-plugin-interruptedmemory: interruptedmemory
> +	$(call run-test, $<, \
> +	  $(QEMU) -plugin ../plugins/libdiscons.so -d plugin -D $*.pout \
> +	  $(QEMU_OPTS)$<)

Something went wrong with substitutions there because I see:

  timeout -s KILL --foreground 120  /home/alex/lsrc/qemu.git/builds/all/qemu-system-riscv64 -plugin ../plugins/libdiscons.so -d plugin -D .pout -M virt -display none -semihosting -device loader,file=interruptedmemory

There doesn't seem to be any output either when I run it manually -
should we be checking the output and at least confirming we are
detecting the right sort of events?

> +
>  # We don't currently support the multiarch system tests
>  undefine MULTIARCH_TESTS
> diff --git a/tests/tcg/riscv64/interruptedmemory.S b/tests/tcg/riscv64/interruptedmemory.S
> new file mode 100644
> index 0000000000..a32d672849
> --- /dev/null
> +++ b/tests/tcg/riscv64/interruptedmemory.S
> @@ -0,0 +1,67 @@
> +	.option norvc
> +
> +	.text
> +	.global _start
> +_start:
> +	# Set up trap vector
> +	lla	t0, trap
> +	csrw	mtvec, t0
> +
> +	# Set up timer
> +	lui	t1, 0x02004
> +	sd	zero, 0(t1) # MTIMECMP0
> +
> +	# Enable timer interrupts
> +	li	t0, 0x80
> +	csrrs	zero, mie, t0
> +	csrrsi	zero, mstatus, 0x8
> +
> +	# Find out when to stop
> +	call	rtc_get
> +	li	t0, 60
> +	slli	t0, t0, 30 # Approx. 10e9 ns
> +	add	t0, t0, a0

The runtime of 60s seems quite long for a tcg test. Can we not show
stuff happening in a shorter period of time?

> +
> +	# Loop with memory accesses
> +	la	t1, semiargs
> +0:
> +	ld	t2, 0(t1)
> +	sd	t2, 0(t1)
> +	call	rtc_get
> +	bltu	a0, t0, 0b
> +
> +	li	a0, 0
> +	lla	a1, semiargs
> +	li	t0, 0x20026	# ADP_Stopped_ApplicationExit
> +	sd	t0, 0(a1)
> +	sd	a0, 8(a1)
> +	li	a0, 0x20	# TARGET_SYS_EXIT_EXTENDED
> +
> +	# Semihosting call sequence
> +	.balign	16
> +	slli	zero, zero, 0x1f
> +	ebreak
> +	srai	zero, zero, 0x7
> +	j	.
> +
> +rtc_get:
> +	# Get current time from the goldfish RTC
> +	lui	t3, 0x0101
> +	lw	a0, 0(t3)
> +	lw	t3, 4(t3)
> +	slli	t3, t3, 32
> +	add	a0, a0, t3
> +	ret
> +
> +trap:
> +	lui	t5, 0x0200c
> +	ld	t6, -0x8(t5) # MTIME
> +	addi	t6, t6, 100
> +	lui	t5, 0x02004
> +	sd	t6, 0(t5) # MTIMECMP
> +	mret
> +
> +	.data
> +	.balign	16
> +semiargs:
> +	.space	16

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro
Re: [PATCH v7 25/25] tests: add test with interrupted memory accesses on rv64
Posted by Julian Ganz 3 months, 3 weeks ago
Hi Alex,

October 14, 2025 at 2:47 PM, "Alex Bennée" wrote:
> Julian Ganz <neither@nut.email> writes:
> 
> > 
> > This test aims at catching API misbehaviour w.r.t. the interaction
> >  between interrupts and memory accesses, such as the bug fixed in
> > 
> >  27f347e6a1d269c533633c812321cabb249eada8
> > 
> Even better the abbrev with title:
> 
>  27f347e6a1d (accel/tcg: also suppress asynchronous IRQs for cpu_io_recompile)

Will do.

> > Because the condition for triggering misbehaviour may not be
> >  deterministic and the cross-section between memory accesses and
> >  interrupt handlers may be small, we have to place our trust in large
> >  numbers. Instead of guessing/trying an arbitrary, fixed loop-bound, we
> >  decided to loop for a fixed amount of real-time. This avoids the test
> >  running into a time-out on slower machines while enabling a high number
> >  of possible interactions on faster machines.
> > 
> >  Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> >  Signed-off-by: Julian Ganz <neither@nut.email>
> >  ---
> >  tests/tcg/riscv64/Makefile.softmmu-target | 6 ++
> >  tests/tcg/riscv64/interruptedmemory.S | 67 +++++++++++++++++++++++
> >  2 files changed, 73 insertions(+)
> >  create mode 100644 tests/tcg/riscv64/interruptedmemory.S
> > 
> >  diff --git a/tests/tcg/riscv64/Makefile.softmmu-target b/tests/tcg/riscv64/Makefile.softmmu-target
> >  index 1a71a78653..d8f92b8e61 100644
> >  --- a/tests/tcg/riscv64/Makefile.softmmu-target
> >  +++ b/tests/tcg/riscv64/Makefile.softmmu-target
> >  @@ -30,5 +30,11 @@ run-plugin-doubletrap: doubletrap
> >  $(QEMU) -plugin ../plugins/libdiscons.so -d plugin -D $*.pout \
> >  $(QEMU_OPTS)$<)
> >  
> >  +EXTRA_RUNS += run-plugin-interruptedmemory
> >  +run-plugin-interruptedmemory: interruptedmemory
> >  + $(call run-test, $<, \
> >  + $(QEMU) -plugin ../plugins/libdiscons.so -d plugin -D $*.pout \
> >  + $(QEMU_OPTS)$<)
> > 
> Something went wrong with substitutions there because I see:
> 
>  timeout -s KILL --foreground 120 /home/alex/lsrc/qemu.git/builds/all/qemu-system-riscv64 -plugin ../plugins/libdiscons.so -d plugin -D .pout -M virt -display none -semihosting -device loader,file=interruptedmemory

I fail to see the issue right now. I'll have to dig a bit and compare
this to other tests.

> There doesn't seem to be any output either when I run it manually -
> should we be checking the output and at least confirming we are
> detecting the right sort of events?

The test currently only communicates success and failure via the return
value (via semihosting). I can add additional output. Printing at least
the final result is probably a good idea.

> > +
> >  # We don't currently support the multiarch system tests
> >  undefine MULTIARCH_TESTS
> >  diff --git a/tests/tcg/riscv64/interruptedmemory.S b/tests/tcg/riscv64/interruptedmemory.S
> >  new file mode 100644
> >  index 0000000000..a32d672849
> >  --- /dev/null
> >  +++ b/tests/tcg/riscv64/interruptedmemory.S
> >  @@ -0,0 +1,67 @@
> >  + .option norvc
> >  +
> >  + .text
> >  + .global _start
> >  +_start:
> >  + # Set up trap vector
> >  + lla t0, trap
> >  + csrw mtvec, t0
> >  +
> >  + # Set up timer
> >  + lui t1, 0x02004
> >  + sd zero, 0(t1) # MTIMECMP0
> >  +
> >  + # Enable timer interrupts
> >  + li t0, 0x80
> >  + csrrs zero, mie, t0
> >  + csrrsi zero, mstatus, 0x8
> >  +
> >  + # Find out when to stop
> >  + call rtc_get
> >  + li t0, 60
> >  + slli t0, t0, 30 # Approx. 10e9 ns
> >  + add t0, t0, a0
> > 
> The runtime of 60s seems quite long for a tcg test. Can we not show
> stuff happening in a shorter period of time?

I can simply reduce the time, e.g. to 30s. I can also add some output
every X iteratins or every second (with the number of iterations) so we
get an idea how many chances we had to trigger the regression.

Regards,
Julian