diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ec244179fd59..11a7701a6d57 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -374,7 +374,7 @@ jobs: name: ${{ matrix.name }} runs-on: ${{ matrix.os }} env: - QEMU_BUILD_VERSION: 8.0.4 + QEMU_BUILD_VERSION: 8.1.1 strategy: fail-fast: true matrix: ${{ fromJson(needs.determine.outputs.test-matrix) }} @@ -435,7 +435,6 @@ jobs: # quickly. curl https://download.qemu.org/qemu-$QEMU_BUILD_VERSION.tar.xz | tar xJf - cd qemu-$QEMU_BUILD_VERSION - patch -p1 < $GITHUB_WORKSPACE/ci/qemu-cpuinfo.patch ./configure --target-list=${{ matrix.qemu_target }} --prefix=${{ runner.tool_cache}}/qemu --disable-tools --disable-slirp --disable-fdt --disable-capstone --disable-docs ninja -C build install touch ${{ runner.tool_cache }}/qemu/built diff --git a/ci/build-test-matrix.js b/ci/build-test-matrix.js index 35c2c00efd57..298203f5d4de 100644 --- a/ci/build-test-matrix.js +++ b/ci/build-test-matrix.js @@ -91,7 +91,7 @@ const array = [ "target": "riscv64gc-unknown-linux-gnu", "gcc_package": "gcc-riscv64-linux-gnu", "gcc": "riscv64-linux-gnu-gcc", - "qemu": "qemu-riscv64 -cpu rv64,v=true,vlen=256,vext_spec=v1.0,zba=true,zbb=true,zbc=true,zbs=true,zbkb=true -L /usr/riscv64-linux-gnu", + "qemu": "qemu-riscv64 -cpu rv64,v=true,vlen=256,vext_spec=v1.0,zba=true,zbb=true,zbc=true,zbs=true,zbkb=true,zcb=true -L /usr/riscv64-linux-gnu", "qemu_target": "riscv64-linux-user", "name": "Test Linux riscv64", "filter": "linux-riscv64", diff --git a/ci/qemu-cpuinfo.patch b/ci/qemu-cpuinfo.patch deleted file mode 100644 index 261bcb593409..000000000000 --- a/ci/qemu-cpuinfo.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 5d05b046efb079360d0175164ee04947f20f9e66 Mon Sep 17 00:00:00 2001 -From: Afonso Bordado -Date: Tue, 21 Mar 2023 18:45:20 +0000 -Subject: [PATCH] linux-user: Emulate /proc/cpuinfo output for riscv - -RISC-V does not expose all extensions via hwcaps, thus some userspace -applications may want to query these via /proc/cpuinfo. - -Currently when querying this file the host's file is shown instead -which is slightly confusing. Emulate a basic /proc/cpuinfo file -with mmu info and an ISA string. ---- - linux-user/syscall.c | 34 ++++++++++++++++++++++++++++++++-- - tests/tcg/riscv64/cpuinfo.c | 30 ++++++++++++++++++++++++++++++ - 2 files changed, 62 insertions(+), 2 deletions(-) - create mode 100644 tests/tcg/riscv64/cpuinfo.c - -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index 333e6b7026..e6d85e0e8a 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -8231,7 +8231,8 @@ void target_exception_dump(CPUArchState *env, const char *fmt, int code) - } - - #if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN || \ -- defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA) -+ defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA) || \ -+ defined(TARGET_RISCV) - static int is_proc(const char *filename, const char *entry) - { - return strcmp(filename, entry) == 0; -@@ -8309,6 +8310,35 @@ static int open_cpuinfo(CPUArchState *cpu_env, int fd) - } - #endif - -+#if defined(TARGET_RISCV) -+static int open_cpuinfo(CPUArchState *cpu_env, int fd) -+{ -+ int i; -+ int num_cpus = sysconf(_SC_NPROCESSORS_ONLN); -+ RISCVCPU *cpu = env_archcpu(cpu_env); -+ const RISCVCPUConfig *cfg = riscv_cpu_cfg((CPURISCVState *) cpu_env); -+ char *isa_string = riscv_isa_string(cpu); -+ const char *mmu; -+ -+ if (cfg->mmu) { -+ mmu = (cpu_env->xl == MXL_RV32) ? "sv32" : "sv48"; -+ } else { -+ mmu = "none"; -+ } -+ -+ for (i = 0; i < num_cpus; i++) { -+ dprintf(fd, "processor\t: %d\n", i); -+ dprintf(fd, "hart\t\t: %d\n", i); -+ dprintf(fd, "isa\t\t: %s\n", isa_string); -+ dprintf(fd, "mmu\t\t: %s\n", mmu); -+ dprintf(fd, "uarch\t\t: qemu\n\n"); -+ } -+ -+ g_free(isa_string); -+ return 0; -+} -+#endif -+ - #if defined(TARGET_M68K) - static int open_hardware(CPUArchState *cpu_env, int fd) - { -@@ -8333,7 +8363,7 @@ static int do_openat(CPUArchState *cpu_env, int dirfd, const char *pathname, int - #if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN - { "/proc/net/route", open_net_route, is_proc }, - #endif --#if defined(TARGET_SPARC) || defined(TARGET_HPPA) -+#if defined(TARGET_SPARC) || defined(TARGET_HPPA) || defined(TARGET_RISCV) - { "/proc/cpuinfo", open_cpuinfo, is_proc }, - #endif - #if defined(TARGET_M68K) -diff --git a/tests/tcg/riscv64/cpuinfo.c b/tests/tcg/riscv64/cpuinfo.c -new file mode 100644 -index 0000000000..296abd0a8c ---- /dev/null -+++ b/tests/tcg/riscv64/cpuinfo.c -@@ -0,0 +1,30 @@ -+#include -+#include -+#include -+#include -+ -+#define BUFFER_SIZE 1024 -+ -+int main(void) -+{ -+ char buffer[BUFFER_SIZE]; -+ FILE *fp = fopen("/proc/cpuinfo", "r"); -+ assert(fp != NULL); -+ -+ while (fgets(buffer, BUFFER_SIZE, fp) != NULL) { -+ if (strstr(buffer, "processor") != NULL) { -+ assert(strstr(buffer, "processor\t: ") == buffer); -+ } else if (strstr(buffer, "hart") != NULL) { -+ assert(strstr(buffer, "hart\t\t: ") == buffer); -+ } else if (strstr(buffer, "isa") != NULL) { -+ assert(strcmp(buffer, "isa\t\t: rv64imafdc_zicsr_zifencei\n") == 0); -+ } else if (strstr(buffer, "mmu") != NULL) { -+ assert(strcmp(buffer, "mmu\t\t: sv48\n") == 0); -+ } else if (strstr(buffer, "uarch") != NULL) { -+ assert(strcmp(buffer, "uarch\t\t: qemu\n") == 0); -+ } -+ } -+ -+ fclose(fp); -+ return 0; -+} --- -2.34.1 - diff --git a/tests/all/traps.rs b/tests/all/traps.rs index a77443ac209c..cb33af235b49 100644 --- a/tests/all/traps.rs +++ b/tests/all/traps.rs @@ -1347,23 +1347,18 @@ fn wasm_fault_address_reported_by_default() -> Result<()> { )?; let err = Instance::new(&mut store, &module, &[]).unwrap_err(); - // On s390x faulting addressess are rounded to the nearest page boundary - // instead of having the precise address reported. - let mut expected_addr = 0xdeadbeef_u32; - if cfg!(target_arch = "s390x") { - expected_addr &= 0xfffff000; - } - // NB: at this time there's no programmatic access to the fault address // because it's not always available for load/store traps. Only static // memories on 32-bit have this information, but bounds-checked memories // use manual trapping instructions and otherwise don't have a means of // communicating the faulting address at this time. + // + // It looks like the exact reported fault address may not be deterministic, + // so assert that we have the right error message, but not the exact address. let err = format!("{err:?}"); assert!( - err.contains(&format!( - "memory fault at wasm address 0x{expected_addr:x} in linear memory of size 0x10000" - )), + err.contains("memory fault at wasm address ") + && err.contains(" in linear memory of size 0x10000"), "bad error: {err}" ); Ok(())