tests: add test with interrupted memory accesses on rv64

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

    27f347e6a1
    (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.

The test program sends a single '.' per 1000000 loads/stores over the
serial. This output is not captured, but may be used by developers to
gauge the number of possible interactions.

Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-32-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
This commit is contained in:
Julian Ganz 2025-10-27 11:03:38 +00:00 committed by Alex Bennée
parent 3c0b1fc078
commit 5241645c47
2 changed files with 103 additions and 0 deletions

View file

@ -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

View file

@ -0,0 +1,97 @@
.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
# Set up UART
lui t1, 0x10000
li a0, 0x80 # DLAB=1
sb a0, 3(t1)
li a0, 1 # Full speed
sw a0, 0(t1)
li a0, 0x03 # 8N1, DLAB=0
sb a0, 3(t1)
# Run test for around 60s
call rtc_get
li t0, 30
slli t0, t0, 30 # Approx. 10e9 ns
add t0, t0, a0
0:
# Tight loop with memory accesses
li a1, 1000000
la a2, semiargs
1:
ld a0, 0(a2)
sd a0, 0(a2)
addi a1, a1, -1
bnez a1, 1b
li a0, '.'
call send_byte
call rtc_get
bltu a0, t0, 0b
li a0, '\n'
call send_byte
# Exit
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
send_byte:
# Send a single byte over the serial
lui t3, 0x10000
lb a1, 5(t3)
andi a1, a1, 0x20
beqz a1, send_byte
sb a0, 0(t3)
ret
.balign 4
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