Examples in Qemu-7.0.0
dongmu opened this issue Β· comments
Hello there,
When executed in Qemu-7.0.0
, an example (compiled with libtock-rs
) crashes with Tock 2.1
. I tried different methods, but failed to figure out the cause. Any reply would be appreciated. Thanks.
Qemu-7.0.0
is configured with: (Qemu is downloaded from the office website without any modification.)
--python=python3 --target-list="riscv32-softmmu riscv64-softmmu arm-softmmu aarch64-softmmu" --disable-vnc --disable-curses --disable-sdl --disable-hax --disable-rdma --enable-debug
The code with libtock-rs
is compiled with:
LIBTOCK_PLATFORM="qemuvirt" cargo run --example "qemuvirtapp" -p libtock --release --target=riscv32imac-unknown-none-elf
Example code: (examples/qemuvirtapp.rs
)
#![no_main]
#![no_std]
use libtock::console::Console;
use libtock::runtime::{set_main, stack_size};
use libtock::alarm::{Alarm, Milliseconds};
set_main! {main}
stack_size! {0x200}
fn main() {
Console::driver_check();
Alarm::sleep_for(Milliseconds(250)).unwrap();
}
ld file: (runtime/layouts/qemuvirt.ld
)
MEMORY {
FLASH (X) : ORIGIN = 0x80100000, LENGTH = 0x100000
RAM (W) : ORIGIN = 0x80202c00, LENGTH = 0x200000
}
TBF_HEADER_SIZE = 0x48;
INCLUDE libtock_layout.ld
One line added into runner/src/elf2tab.rs
for function get_platform_architecture(platform: &str) -> Option<&'static str>
:
"qemuvirt" => Some("riscv32imac"),
Error message:
QEMU RISC-V 32-bit "virt" machine, initialization complete.
Entering main loop.
Loading processes from flash=0x80100000-0x801FFFFF into sram=0x80202C00-0x803FFFFF
Loaded process[0] from flash=0x80100000-0x8010127B into sram=0x80202C00-0x80203AFF = "qemuvirtapp"
[0] function_call @0x80100068(0x80100048, 0x80202c00, 0xf00, 0x80202c00)
[0] memop(0, 0x80202e00) = Success
[0] memop(10, 0x80202e00) = Success
[0] memop(11, 0x80202e00) = Success
[0] cmd(0x1, 0, 0x0, 0x0) = Success
[0] cmd(0x0, 1, 0x0, 0x0) = SuccessU32(32768)
[0] remove_pending_upcalls[0x0:0] = 0 upcall(s) removed
[0] subscribe(0x0, 0, @0x80100ef0, 0x80202dd8) = SubscribeSuccess(0x0, 0)
[0] cmd(0x0, 5, 0x2000, 0x0) = SuccessU32(418502)
[0] schedule[0x0:0] @0x80100ef0(0x6a725, 0x662c6, 0x0, 0x80202dd8) = Ok(())
[0] yield. which: 1
[0] function_call @0x80100ef0(0x6a725, 0x662c6, 0x0, 0x80202dd8)
[0] remove_pending_upcalls[0x0:0] = 0 upcall(s) removed
[0] subscribe(0x0, 0, @0x0, 0x0) = SubscribeSuccess(0x80100ef0, 2149592536)
panicked at 'Process qemuvirtapp had a fault', kernel/src/process_standard.rs:333:17
Kernel version 1827bba
---| No debug queue found. You can set it with the DebugQueue component.
---| RISC-V Machine State |---
Last cause (mcause): Machine external interrupt (interrupt=1, exception code=0x0000000B)
Last value (mtval): 0x00000000
System register dump:
mepc: 0x800051DA mstatus: 0x00000088
mcycle: 0xCEA6F058 minstret: 0xCEA7CB0E
mtvec: 0x80000100
mstatus: 0x00000088
uie: false upie: false
sie: false spie: false
mie: true mpie: true
spp: false
mie: 0x00000888 mip: 0x00000000
usoft: false false
ssoft: false false
msoft: true false
utimer: false false
stimer: false false
mtimer: true false
uext: false false
sext: false false
mext: true false
---| App Status |---
ππ©π©: qemuvirtapp - [Faulted]
Events Queued: 0 Syscall Count: 9 Dropped Upcall Count: 0
Restart Count: 0
Last Syscall: Subscribe { driver_number: 0, subdriver_number: 0, upcall_ptr: 0x0, appdata: 0 }
Completion Code: None
βββββββββββββ€βββββββββββββββββββββββββββββββββββββββββββ
β Address β Region Name Used | Allocated (bytes) β
β0x80203B00ββͺβββββββββββββββββββββββββββββββββββββββββββ
β Grant Ptrs 32
β Upcalls 360
β Process 888
0x80203600 βΌβββββββββββββββββββββββββββββββββββββββββββ
β βΌ Grant 100
0x8020359C βΌβββββββββββββββββββββββββββββββββββββββββββ
β Unused
0x80202E00 βΌβββββββββββββββββββββββββββββββββββββββββββ
β β² Heap 0 | 1948 S
0x80202E00 βΌβββββββββββββββββββββββββββββββββββββββββββ R
β Data 0 | 0 A
0x80202E00 βΌβββββββββββββββββββββββββββββββββββββββββββ M
β βΌ Stack 48 | 512
0x80202DD0 βΌβββββββββββββββββββββββββββββββββββββββββββ
β Unused
0x80202C00 β΄βββββββββββββββββββββββββββββββββββββββββββ
.....
0x8010127C β¬βββββββββββββββββββββββββββββββββββββββββββ F
β App Flash 4660 L
0x80100048 βΌβββββββββββββββββββββββββββββββββββββββββββ A
β Protected 72 S
0x80100000 β΄βββββββββββββββββββββββββββββββββββββββββββ H
R0 : 0x00000000 R16: 0x00000001
R1 : 0x80100FEA R17: 0x007D0000
R2 : 0x80202DD0 R18: 0x00000000
R3 : 0x00000000 R19: 0x00000000
R4 : 0x00000000 R20: 0x00000000
R5 : 0x00000000 R21: 0x00000000
R6 : 0x00000000 R22: 0x00000000
R7 : 0x00000000 R23: 0x00000000
R8 : 0x00000001 R24: 0x00000000
R9 : 0x80100068 R25: 0x00000000
R10: 0x00000082 R26: 0x00000000
R11: 0x80100EF0 R27: 0x00000000
R12: 0x80202DD8 R28: 0x00000000
R13: 0x00000000 R29: 0x00000000
R14: 0x00000001 R30: 0x00000000
R15: 0x00000000 R31: 0x00000000
PC : 0x80101000
mcause: 0x00000001 (Instruction access fault)
mtval: 0x80101000
Total number of grant regions defined: 4
Grant 0 0x0: 0x8020359c Grant 2 : --
Grant 1 0x1: 0x802035b4 Grant 3 : --
PMP regions:
[0]: addr=0x80100000, size=0x0000127C, cfg=0xD (r-x)
[1]: addr=0x80202c00, size=0x00000200, cfg=0xB (rw-)
<unset>
<unset>
<unset>
<unset>
<unset>
<unset>
To debug, run `make lst` in the app's folder
and open the arch.0x80100048.0x80202c00.lst file.
@lschuermann -- I'll walk through what I see, would you mind double-checking my work?
In the app status dump, I see:
mcause: 0x00000001 (Instruction access fault)
which makes me think that PC is pointing at non-executable memory. mtval
is 0x80101000
and PC is 0x80101000
which further supports my theory. However, 0x80101000
falls within the first PMP region in the PMP region dump:
PMP regions:
[0]: addr=0x80100000, size=0x0000127C, cfg=0xD (r-x)
[1]: addr=0x80202c00, size=0x00000200, cfg=0xB (rw-)
which is RX, so I think the fetch should've worked? Maybe this is a kernel bug in PMP configuration?
I could easily be missing or misunderstanding something -- QEMU virtio is not my forte.
It seems like this issue is related to a known-bug in QEMU (starting with at least v7.0.0): tock/tock#3316. This bug unfortunately breaks QEMU's enforcement of the PMP memory protection rules on platforms which feature an MMU (which the QEMU virt
board does), independent of whether the MMU is used or not. Even though these accesses are valid, QEMU raises a fault when an address is accessed but the matching PMP region does not span an entire page of memory.
This bug appears to have been fixed in QEMU mainline as part of a larger refactoring effort around QEMU's Tiny Code Generator (TCG). @dongmu Can you try to reproduce this on QEMU master or v7.2.0-rc2 and see whether the issue is resolved?
This issue is already documented in the board's README, but perhaps we can make it more obvious that application support is broken. As soon as QEMU issues a release containing this fix (likely v7.2.0), we may be able to check the QEMU version and issue a warning accordingly.
Thank you, @lschuermann and @jrvanwhy . I used Tock-2.1
version and did not check Tock-master
. Sorry to duplicate the question here.
Several examples work correctly on Qemu-v7.2.0-rc2
. I will let you know if new issues arise. Thanks.