* [PULL 01/26] hw/riscv/riscv-iommu: Fix MSI table size limit
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
@ 2025-10-03 3:26 ` alistair23
2025-10-03 3:26 ` [PULL 02/26] docs/interop/firmware: Add riscv64 to FirmwareArchitecture alistair23
` (26 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:26 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Andrew Jones, Daniel Henrique Barboza,
Alistair Francis
From: Andrew Jones <ajones@ventanamicro.com>
The MSI table is not limited to 4k. The only constraint the table has
is that its base address must be aligned to its size, ensuring no
offsets of the table size will overrun when added to the base address
(see "8.5. MSI page tables" of the AIA spec).
Fixes: 0c54acb8243d ("hw/riscv: add RISC-V IOMMU base emulation")
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20250904132723.614507-2-ajones@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/riscv/riscv-iommu.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
index 96a7fbdefc..155190d032 100644
--- a/hw/riscv/riscv-iommu.c
+++ b/hw/riscv/riscv-iommu.c
@@ -558,6 +558,7 @@ static MemTxResult riscv_iommu_msi_write(RISCVIOMMUState *s,
MemTxResult res;
dma_addr_t addr;
uint64_t intn;
+ size_t offset;
uint32_t n190;
uint64_t pte[2];
int fault_type = RISCV_IOMMU_FQ_TTYPE_UADDR_WR;
@@ -565,16 +566,18 @@ static MemTxResult riscv_iommu_msi_write(RISCVIOMMUState *s,
/* Interrupt File Number */
intn = riscv_iommu_pext_u64(PPN_DOWN(gpa), ctx->msi_addr_mask);
- if (intn >= 256) {
+ offset = intn * sizeof(pte);
+
+ /* fetch MSI PTE */
+ addr = PPN_PHYS(get_field(ctx->msiptp, RISCV_IOMMU_DC_MSIPTP_PPN));
+ if (addr & offset) {
/* Interrupt file number out of range */
res = MEMTX_ACCESS_ERROR;
cause = RISCV_IOMMU_FQ_CAUSE_MSI_LOAD_FAULT;
goto err;
}
- /* fetch MSI PTE */
- addr = PPN_PHYS(get_field(ctx->msiptp, RISCV_IOMMU_DC_MSIPTP_PPN));
- addr = addr | (intn * sizeof(pte));
+ addr |= offset;
res = dma_memory_read(s->target_as, addr, &pte, sizeof(pte),
MEMTXATTRS_UNSPECIFIED);
if (res != MEMTX_OK) {
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 02/26] docs/interop/firmware: Add riscv64 to FirmwareArchitecture
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
2025-10-03 3:26 ` [PULL 01/26] hw/riscv/riscv-iommu: Fix MSI table size limit alistair23
@ 2025-10-03 3:26 ` alistair23
2025-10-03 3:26 ` [PULL 03/26] linux-user/syscall.c: sync RISC-V hwprobe with Linux alistair23
` (25 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:26 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Andrea Bolognani, Kashyap Chamarthy, Alistair Francis
From: Andrea Bolognani <abologna@redhat.com>
Descriptors using this value have been shipped for years
by distros, so we just need to update the spec to match
reality.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Kashyap Chamarthy <kchamart@redhat.com>
Message-ID: <20250910121501.676219-1-abologna@redhat.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
docs/interop/firmware.json | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/docs/interop/firmware.json b/docs/interop/firmware.json
index 6bbe2cce0a..ccbfaf828d 100644
--- a/docs/interop/firmware.json
+++ b/docs/interop/firmware.json
@@ -85,12 +85,14 @@
#
# @loongarch64: 64-bit LoongArch. (since: 7.1)
#
+# @riscv64: 64-bit RISC-V.
+#
# @x86_64: 64-bit x86.
#
# Since: 3.0
##
{ 'enum' : 'FirmwareArchitecture',
- 'data' : [ 'aarch64', 'arm', 'i386', 'loongarch64', 'x86_64' ] }
+ 'data' : [ 'aarch64', 'arm', 'i386', 'loongarch64', 'riscv64', 'x86_64' ] }
##
# @FirmwareTarget:
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 03/26] linux-user/syscall.c: sync RISC-V hwprobe with Linux
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
2025-10-03 3:26 ` [PULL 01/26] hw/riscv/riscv-iommu: Fix MSI table size limit alistair23
2025-10-03 3:26 ` [PULL 02/26] docs/interop/firmware: Add riscv64 to FirmwareArchitecture alistair23
@ 2025-10-03 3:26 ` alistair23
2025-10-03 3:26 ` [PULL 04/26] target/riscv: implement MonitorDef HMP API alistair23
` (24 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:26 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Daniel Henrique Barboza, Alistair Francis
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
It has been awhile since the last sync. Let's bring QEMU hwprobe support
on par with Linux 6.17-rc4.
A lot of new RISCV_HWPROBE_KEY_* entities are added but this patch is
only adding support for ZICBOM_BLOCK_SIZE.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250903164043.2828336-1-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
linux-user/syscall.c | 89 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 1a5f2a03f9..d78b2029fa 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9023,6 +9023,29 @@ static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count)
#define RISCV_HWPROBE_EXT_ZTSO (1ULL << 33)
#define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34)
#define RISCV_HWPROBE_EXT_ZICOND (1ULL << 35)
+#define RISCV_HWPROBE_EXT_ZIHINTPAUSE (1ULL << 36)
+#define RISCV_HWPROBE_EXT_ZVE32X (1ULL << 37)
+#define RISCV_HWPROBE_EXT_ZVE32F (1ULL << 38)
+#define RISCV_HWPROBE_EXT_ZVE64X (1ULL << 39)
+#define RISCV_HWPROBE_EXT_ZVE64F (1ULL << 40)
+#define RISCV_HWPROBE_EXT_ZVE64D (1ULL << 41)
+#define RISCV_HWPROBE_EXT_ZIMOP (1ULL << 42)
+#define RISCV_HWPROBE_EXT_ZCA (1ULL << 43)
+#define RISCV_HWPROBE_EXT_ZCB (1ULL << 44)
+#define RISCV_HWPROBE_EXT_ZCD (1ULL << 45)
+#define RISCV_HWPROBE_EXT_ZCF (1ULL << 46)
+#define RISCV_HWPROBE_EXT_ZCMOP (1ULL << 47)
+#define RISCV_HWPROBE_EXT_ZAWRS (1ULL << 48)
+#define RISCV_HWPROBE_EXT_SUPM (1ULL << 49)
+#define RISCV_HWPROBE_EXT_ZICNTR (1ULL << 50)
+#define RISCV_HWPROBE_EXT_ZIHPM (1ULL << 51)
+#define RISCV_HWPROBE_EXT_ZFBFMIN (1ULL << 52)
+#define RISCV_HWPROBE_EXT_ZVFBFMIN (1ULL << 53)
+#define RISCV_HWPROBE_EXT_ZVFBFWMA (1ULL << 54)
+#define RISCV_HWPROBE_EXT_ZICBOM (1ULL << 55)
+#define RISCV_HWPROBE_EXT_ZAAMO (1ULL << 56)
+#define RISCV_HWPROBE_EXT_ZALRSC (1ULL << 57)
+#define RISCV_HWPROBE_EXT_ZABHA (1ULL << 58)
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
@@ -9033,6 +9056,22 @@ static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count)
#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
#define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6
+#define RISCV_HWPROBE_KEY_HIGHEST_VIRT_ADDRESS 7
+#define RISCV_HWPROBE_KEY_TIME_CSR_FREQ 8
+#define RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF 9
+#define RISCV_HWPROBE_MISALIGNED_SCALAR_UNKNOWN 0
+#define RISCV_HWPROBE_MISALIGNED_SCALAR_EMULATED 1
+#define RISCV_HWPROBE_MISALIGNED_SCALAR_SLOW 2
+#define RISCV_HWPROBE_MISALIGNED_SCALAR_FAST 3
+#define RISCV_HWPROBE_MISALIGNED_SCALAR_UNSUPPORTED 4
+#define RISCV_HWPROBE_KEY_MISALIGNED_VECTOR_PERF 10
+#define RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN 0
+#define RISCV_HWPROBE_MISALIGNED_VECTOR_SLOW 2
+#define RISCV_HWPROBE_MISALIGNED_VECTOR_FAST 3
+#define RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED 4
+#define RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0 11
+#define RISCV_HWPROBE_KEY_ZICBOM_BLOCK_SIZE 12
+#define RISCV_HWPROBE_KEY_VENDOR_EXT_SIFIVE_0 13
struct riscv_hwprobe {
abi_llong key;
@@ -9141,6 +9180,52 @@ static void risc_hwprobe_fill_pairs(CPURISCVState *env,
RISCV_HWPROBE_EXT_ZACAS : 0;
value |= cfg->ext_zicond ?
RISCV_HWPROBE_EXT_ZICOND : 0;
+ value |= cfg->ext_zihintpause ?
+ RISCV_HWPROBE_EXT_ZIHINTPAUSE : 0;
+ value |= cfg->ext_zve32x ?
+ RISCV_HWPROBE_EXT_ZVE32X : 0;
+ value |= cfg->ext_zve32f ?
+ RISCV_HWPROBE_EXT_ZVE32F : 0;
+ value |= cfg->ext_zve64x ?
+ RISCV_HWPROBE_EXT_ZVE64X : 0;
+ value |= cfg->ext_zve64f ?
+ RISCV_HWPROBE_EXT_ZVE64F : 0;
+ value |= cfg->ext_zve64d ?
+ RISCV_HWPROBE_EXT_ZVE64D : 0;
+ value |= cfg->ext_zimop ?
+ RISCV_HWPROBE_EXT_ZIMOP : 0;
+ value |= cfg->ext_zca ?
+ RISCV_HWPROBE_EXT_ZCA : 0;
+ value |= cfg->ext_zcb ?
+ RISCV_HWPROBE_EXT_ZCB : 0;
+ value |= cfg->ext_zcd ?
+ RISCV_HWPROBE_EXT_ZCD : 0;
+ value |= cfg->ext_zcf ?
+ RISCV_HWPROBE_EXT_ZCF : 0;
+ value |= cfg->ext_zcmop ?
+ RISCV_HWPROBE_EXT_ZCMOP : 0;
+ value |= cfg->ext_zawrs ?
+ RISCV_HWPROBE_EXT_ZAWRS : 0;
+ value |= cfg->ext_supm ?
+ RISCV_HWPROBE_EXT_SUPM : 0;
+ value |= cfg->ext_zicntr ?
+ RISCV_HWPROBE_EXT_ZICNTR : 0;
+ value |= cfg->ext_zihpm ?
+ RISCV_HWPROBE_EXT_ZIHPM : 0;
+ value |= cfg->ext_zfbfmin ?
+ RISCV_HWPROBE_EXT_ZFBFMIN : 0;
+ value |= cfg->ext_zvfbfmin ?
+ RISCV_HWPROBE_EXT_ZVFBFMIN : 0;
+ value |= cfg->ext_zvfbfwma ?
+ RISCV_HWPROBE_EXT_ZVFBFWMA : 0;
+ value |= cfg->ext_zicbom ?
+ RISCV_HWPROBE_EXT_ZICBOM : 0;
+ value |= cfg->ext_zaamo ?
+ RISCV_HWPROBE_EXT_ZAAMO : 0;
+ value |= cfg->ext_zalrsc ?
+ RISCV_HWPROBE_EXT_ZALRSC : 0;
+ value |= cfg->ext_zabha ?
+ RISCV_HWPROBE_EXT_ZABHA : 0;
__put_user(value, &pair->value);
break;
case RISCV_HWPROBE_KEY_CPUPERF_0:
@@ -9150,6 +9235,10 @@ static void risc_hwprobe_fill_pairs(CPURISCVState *env,
value = cfg->ext_zicboz ? cfg->cboz_blocksize : 0;
__put_user(value, &pair->value);
break;
+ case RISCV_HWPROBE_KEY_ZICBOM_BLOCK_SIZE:
+ value = cfg->ext_zicbom ? cfg->cbom_blocksize : 0;
+ __put_user(value, &pair->value);
+ break;
default:
__put_user(-1, &pair->key);
break;
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 04/26] target/riscv: implement MonitorDef HMP API
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (2 preceding siblings ...)
2025-10-03 3:26 ` [PULL 03/26] linux-user/syscall.c: sync RISC-V hwprobe with Linux alistair23
@ 2025-10-03 3:26 ` alistair23
2025-10-03 3:26 ` [PULL 05/26] roms/opensbi: Update to v1.7 alistair23
` (23 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:26 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Daniel Henrique Barboza, Dr. David Alan Gilbert,
Alistair Francis
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
The MonitorDef API is related to two HMP monitor commands: 'p' and 'x':
(qemu) help p
print|p /fmt expr -- print expression value (use $reg for CPU register access)
(qemu) help x
x /fmt addr -- virtual memory dump starting at 'addr'
For x86, one of the few targets that implements it, it is possible to
print the PC register value with $pc and use the PC value in the 'x'
command as well.
Those 2 commands are hooked into get_monitor_def(), called by
exp_unary() in hmp.c. The function tries to fetch a reg value in two
ways: by reading them directly via a target_monitor_defs array or using
a target_get_monitor_def() helper. In RISC-V we have *A LOT* of
registers and this number will keep getting bigger, so we're opting out
of an array declaration.
We're able to retrieve all regs but vregs because the API only fits an
uint64_t and vregs have 'vlen' size that are bigger than that.
With this patch we can do things such as:
- print CSRs and use their val in expressions:
(qemu) p $mstatus
0xa000000a0
(qemu) p $mstatus & 0xFF
0xa0
- dump the next 10 insn from virtual memory starting at x1 (ra):
(qemu) x/10i $ra
0xffffffff80958aea: a9bff0ef jal ra,-1382 # 0xffffffff80958584
0xffffffff80958aee: 10016073 csrrsi zero,sstatus,2
0xffffffff80958af2: 60a2 ld ra,8(sp)
0xffffffff80958af4: 6402 ld s0,0(sp)
0xffffffff80958af6: 0141 addi sp,sp,16
0xffffffff80958af8: 8082 ret
0xffffffff80958afa: 10016073 csrrsi zero,sstatus,2
0xffffffff80958afe: 8082 ret
0xffffffff80958b00: 1141 addi sp,sp,-16
0xffffffff80958b02: e422 sd s0,8(sp)
(qemu)
Suggested-by: Dr. David Alan Gilbert <dave@treblig.org>
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250703130815.1592493-1-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 1 +
target/riscv/riscv-qmp-cmds.c | 148 ++++++++++++++++++++++++++++++++++
2 files changed, 149 insertions(+)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4a862da615..738e68fa6e 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -592,6 +592,7 @@ static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
extern const char * const riscv_int_regnames[];
extern const char * const riscv_int_regnamesh[];
extern const char * const riscv_fpr_regnames[];
+extern const char * const riscv_rvv_regnames[];
const char *riscv_cpu_get_trap_name(target_ulong cause, bool async);
int riscv_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c
index 8a1856c50e..b63de8dd45 100644
--- a/target/riscv/riscv-qmp-cmds.c
+++ b/target/riscv/riscv-qmp-cmds.c
@@ -31,6 +31,10 @@
#include "qapi/qobject-input-visitor.h"
#include "qapi/visitor.h"
#include "qom/qom-qobject.h"
+#include "qemu/ctype.h"
+#include "qemu/qemu-print.h"
+#include "monitor/hmp.h"
+#include "monitor/hmp-target.h"
#include "system/kvm.h"
#include "system/tcg.h"
#include "cpu-qom.h"
@@ -240,3 +244,147 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
return expansion_info;
}
+
+/*
+ * We have way too many potential CSRs and regs being added
+ * regularly to register them in a static array.
+ *
+ * Declare an empty array instead, making get_monitor_def() use
+ * the target_get_monitor_def() API directly.
+ */
+const MonitorDef monitor_defs[] = { { } };
+const MonitorDef *target_monitor_defs(void)
+{
+ return monitor_defs;
+}
+
+static bool reg_is_ulong_integer(CPURISCVState *env, const char *name,
+ target_ulong *val, bool is_gprh)
+{
+ const char * const *reg_names;
+ target_ulong *vals;
+
+ if (is_gprh) {
+ reg_names = riscv_int_regnamesh;
+ vals = env->gprh;
+ } else {
+ reg_names = riscv_int_regnames;
+ vals = env->gpr;
+ }
+
+ for (int i = 0; i < 32; i++) {
+ g_autofree char *reg_name = g_strdup(reg_names[i]);
+ char *reg1 = strtok(reg_name, "/");
+ char *reg2 = strtok(NULL, "/");
+
+ if (strcasecmp(reg1, name) == 0 ||
+ (reg2 && strcasecmp(reg2, name) == 0)) {
+ *val = vals[i];
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool reg_is_u64_fpu(CPURISCVState *env, const char *name, uint64_t *val)
+{
+ if (qemu_tolower(name[0]) != 'f') {
+ return false;
+ }
+
+ for (int i = 0; i < 32; i++) {
+ g_autofree char *reg_name = g_strdup(riscv_fpr_regnames[i]);
+ char *reg1 = strtok(reg_name, "/");
+ char *reg2 = strtok(NULL, "/");
+
+ if (strcasecmp(reg1, name) == 0 ||
+ (reg2 && strcasecmp(reg2, name) == 0)) {
+ *val = env->fpr[i];
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool reg_is_vreg(const char *name)
+{
+ if (qemu_tolower(name[0]) != 'v' || strlen(name) > 3) {
+ return false;
+ }
+
+ for (int i = 0; i < 32; i++) {
+ if (strcasecmp(name, riscv_rvv_regnames[i]) == 0) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
+{
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
+ target_ulong val = 0;
+ uint64_t val64 = 0;
+ int i;
+
+ if (reg_is_ulong_integer(env, name, &val, false) ||
+ reg_is_ulong_integer(env, name, &val, true)) {
+ *pval = val;
+ return 0;
+ }
+
+ if (reg_is_u64_fpu(env, name, &val64)) {
+ *pval = val64;
+ return 0;
+ }
+
+ if (reg_is_vreg(name)) {
+ if (!riscv_has_ext(env, RVV)) {
+ return -EINVAL;
+ }
+
+ qemu_printf("Unable to print the value of vector "
+ "vreg '%s' from this API\n", name);
+
+ /*
+ * We're returning 0 because returning -EINVAL triggers
+ * an 'unknown register' message in exp_unary() later,
+ * which feels ankward after our own error message.
+ */
+ *pval = 0;
+ return 0;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(csr_ops); i++) {
+ RISCVException res;
+ int csrno = i;
+
+ /*
+ * Early skip when possible since we're going
+ * through a lot of NULL entries.
+ */
+ if (csr_ops[csrno].predicate == NULL) {
+ continue;
+ }
+
+ if (strcasecmp(csr_ops[csrno].name, name) != 0) {
+ continue;
+ }
+
+ res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
+
+ /*
+ * Rely on the smode, hmode, etc, predicates within csr.c
+ * to do the filtering of the registers that are present.
+ */
+ if (res == RISCV_EXCP_NONE) {
+ *pval = val;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 05/26] roms/opensbi: Update to v1.7
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (3 preceding siblings ...)
2025-10-03 3:26 ` [PULL 04/26] target/riscv: implement MonitorDef HMP API alistair23
@ 2025-10-03 3:26 ` alistair23
2025-10-03 3:26 ` [PULL 06/26] hw/char: sifive_uart: Raise IRQ according to the Tx/Rx watermark thresholds alistair23
` (22 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:26 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Daniel Henrique Barboza, Alistair Francis
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Update OpenSBI and the pre-built opensbi32 and opensbi64 images to
version 1.7.
It has been almost an year since we last updated OpenSBI (at the time,
up to v1.5.1) and we're missing a lot of good stuff from both v1.6 and
v1.7, including SBI 3.0 and RPMI 1.0.
The changelog is too large and tedious to post in the commit msg so I
encourage refering to [1] and [2] to see the new features we're adding
into the QEMU roms.
[1] https://github.com/riscv-software-src/opensbi/releases/tag/v1.6
[2] https://github.com/riscv-software-src/opensbi/releases/tag/v1.7
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
.../opensbi-riscv32-generic-fw_dynamic.bin | Bin 268312 -> 268752 bytes
.../opensbi-riscv64-generic-fw_dynamic.bin | Bin 272504 -> 273048 bytes
roms/opensbi | 2 +-
3 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
index b2e740010b..02be3a72a8 100644
Binary files a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin differ
diff --git a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin
index 018b4731a7..cce35c65c2 100644
Binary files a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin differ
diff --git a/roms/opensbi b/roms/opensbi
index 43cace6c36..a32a910691 160000
--- a/roms/opensbi
+++ b/roms/opensbi
@@ -1 +1 @@
-Subproject commit 43cace6c3671e5172d0df0a8963e552bb04b7b20
+Subproject commit a32a91069119e7a5aa31e6bc51d5e00860be3d80
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 06/26] hw/char: sifive_uart: Raise IRQ according to the Tx/Rx watermark thresholds
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (4 preceding siblings ...)
2025-10-03 3:26 ` [PULL 05/26] roms/opensbi: Update to v1.7 alistair23
@ 2025-10-03 3:26 ` alistair23
2025-10-03 3:26 ` [PULL 07/26] hw/char: sifive_uart: Avoid pushing Tx FIFO when size is zero alistair23
` (21 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:26 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Frank Chang, Emmanuel Blot, Alistair Francis
From: Frank Chang <frank.chang@sifive.com>
Currently, the SiFive UART raises an IRQ whenever:
1. ie.txwm is enabled.
2. ie.rxwm is enabled and the Rx FIFO is not empty.
It does not check the watermark thresholds set by software. However,
since commit [1] changed the SiFive UART character printing from
synchronous to asynchronous, Tx overflows may occur, causing characters
to be dropped when running Linux because:
1. The Linux SiFive UART driver sets the transmit watermark level to 1
[2], meaning a transmit watermark interrupt is raised whenever a
character is enqueued into the Tx FIFO.
2. Upon receiving a transmit watermark interrupt, the Linux driver
transfers up to a full Tx FIFO's worth of characters from the Linux
serial transmit buffer [3], without checking the txdata.full flag
before transferring multiple characters [4].
To fix this issue, we must honor the Tx/Rx watermark thresholds and
raise interrupts only when the Tx threshold is exceeded or the Rx
threshold is undercut.
[1] 53c1557b230986ab6320a58e1b2c26216ecd86d5
[2] https://github.com/torvalds/linux/blob/master/drivers/tty/serial/sifive.c#L1039
[3] https://github.com/torvalds/linux/blob/master/drivers/tty/serial/sifive.c#L538
[4] https://github.com/torvalds/linux/blob/master/drivers/tty/serial/sifive.c#L291
Signed-off-by: Frank Chang <frank.chang@sifive.com>
Signed-off-by: Emmanuel Blot <emmanuel.blot@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250911160647.5710-2-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/char/sifive_uart.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/hw/char/sifive_uart.c b/hw/char/sifive_uart.c
index 9bc697a67b..138c31fcab 100644
--- a/hw/char/sifive_uart.c
+++ b/hw/char/sifive_uart.c
@@ -35,16 +35,17 @@
*/
/* Returns the state of the IP (interrupt pending) register */
-static uint64_t sifive_uart_ip(SiFiveUARTState *s)
+static uint32_t sifive_uart_ip(SiFiveUARTState *s)
{
- uint64_t ret = 0;
+ uint32_t ret = 0;
- uint64_t txcnt = SIFIVE_UART_GET_TXCNT(s->txctrl);
- uint64_t rxcnt = SIFIVE_UART_GET_RXCNT(s->rxctrl);
+ uint32_t txcnt = SIFIVE_UART_GET_TXCNT(s->txctrl);
+ uint32_t rxcnt = SIFIVE_UART_GET_RXCNT(s->rxctrl);
- if (txcnt != 0) {
+ if (fifo8_num_used(&s->tx_fifo) < txcnt) {
ret |= SIFIVE_UART_IP_TXWM;
}
+
if (s->rx_fifo_len > rxcnt) {
ret |= SIFIVE_UART_IP_RXWM;
}
@@ -55,15 +56,14 @@ static uint64_t sifive_uart_ip(SiFiveUARTState *s)
static void sifive_uart_update_irq(SiFiveUARTState *s)
{
int cond = 0;
- if ((s->ie & SIFIVE_UART_IE_TXWM) ||
- ((s->ie & SIFIVE_UART_IE_RXWM) && s->rx_fifo_len)) {
+ uint32_t ip = sifive_uart_ip(s);
+
+ if (((ip & SIFIVE_UART_IP_TXWM) && (s->ie & SIFIVE_UART_IE_TXWM)) ||
+ ((ip & SIFIVE_UART_IP_RXWM) && (s->ie & SIFIVE_UART_IE_RXWM))) {
cond = 1;
}
- if (cond) {
- qemu_irq_raise(s->irq);
- } else {
- qemu_irq_lower(s->irq);
- }
+
+ qemu_set_irq(s->irq, cond);
}
static gboolean sifive_uart_xmit(void *do_not_use, GIOCondition cond,
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 07/26] hw/char: sifive_uart: Avoid pushing Tx FIFO when size is zero
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (5 preceding siblings ...)
2025-10-03 3:26 ` [PULL 06/26] hw/char: sifive_uart: Raise IRQ according to the Tx/Rx watermark thresholds alistair23
@ 2025-10-03 3:26 ` alistair23
2025-10-03 3:27 ` [PULL 08/26] hw/char: sifive_uart: Remove outdated comment about Tx FIFO alistair23
` (20 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:26 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Frank Chang, Alistair Francis
From: Frank Chang <frank.chang@sifive.com>
There's no need to call fifo8_push_all() when size is zero.
Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250911160647.5710-3-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/char/sifive_uart.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/hw/char/sifive_uart.c b/hw/char/sifive_uart.c
index 138c31fcab..401f869680 100644
--- a/hw/char/sifive_uart.c
+++ b/hw/char/sifive_uart.c
@@ -122,7 +122,9 @@ static void sifive_uart_write_tx_fifo(SiFiveUARTState *s, const uint8_t *buf,
qemu_log_mask(LOG_GUEST_ERROR, "sifive_uart: TX FIFO overflow");
}
- fifo8_push_all(&s->tx_fifo, buf, size);
+ if (size > 0) {
+ fifo8_push_all(&s->tx_fifo, buf, size);
+ }
if (fifo8_is_full(&s->tx_fifo)) {
s->txfifo |= SIFIVE_UART_TXFIFO_FULL;
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 08/26] hw/char: sifive_uart: Remove outdated comment about Tx FIFO
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (6 preceding siblings ...)
2025-10-03 3:26 ` [PULL 07/26] hw/char: sifive_uart: Avoid pushing Tx FIFO when size is zero alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 09/26] hw/char: sifive_uart: Add newline to error message alistair23
` (19 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Frank Chang, Alistair Francis
From: Frank Chang <frank.chang@sifive.com>
Since Tx FIFO is now implemented using "qemu/fifo8.h", remove the comment
that no longer reflects the current implementation.
Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250911160647.5710-4-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/char/sifive_uart.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/hw/char/sifive_uart.c b/hw/char/sifive_uart.c
index 401f869680..baef0bd9c2 100644
--- a/hw/char/sifive_uart.c
+++ b/hw/char/sifive_uart.c
@@ -28,12 +28,6 @@
#define TX_INTERRUPT_TRIGGER_DELAY_NS 100
-/*
- * Not yet implemented:
- *
- * Transmit FIFO using "qemu/fifo8.h"
- */
-
/* Returns the state of the IP (interrupt pending) register */
static uint32_t sifive_uart_ip(SiFiveUARTState *s)
{
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 09/26] hw/char: sifive_uart: Add newline to error message
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (7 preceding siblings ...)
2025-10-03 3:27 ` [PULL 08/26] hw/char: sifive_uart: Remove outdated comment about Tx FIFO alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 10/26] hw/intc: Save time_delta in RISC-V mtimer VMState alistair23
` (18 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Frank Chang, Alistair Francis
From: Frank Chang <frank.chang@sifive.com>
Adds a missing newline character to the error message.
Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250911160647.5710-5-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/char/sifive_uart.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/char/sifive_uart.c b/hw/char/sifive_uart.c
index baef0bd9c2..e7357d585a 100644
--- a/hw/char/sifive_uart.c
+++ b/hw/char/sifive_uart.c
@@ -113,7 +113,7 @@ static void sifive_uart_write_tx_fifo(SiFiveUARTState *s, const uint8_t *buf,
if (size > fifo8_num_free(&s->tx_fifo)) {
size = fifo8_num_free(&s->tx_fifo);
- qemu_log_mask(LOG_GUEST_ERROR, "sifive_uart: TX FIFO overflow");
+ qemu_log_mask(LOG_GUEST_ERROR, "sifive_uart: TX FIFO overflow.\n");
}
if (size > 0) {
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 10/26] hw/intc: Save time_delta in RISC-V mtimer VMState
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (8 preceding siblings ...)
2025-10-03 3:27 ` [PULL 09/26] hw/char: sifive_uart: Add newline to error message alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 11/26] migration: Add support for a variable-length array of UINT32 pointers alistair23
` (17 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, TANG Tiancheng, LIU Zhiwei, Daniel Henrique Barboza,
Alistair Francis
From: TANG Tiancheng <lyndra@linux.alibaba.com>
In QEMU's RISC-V ACLINT timer model, 'mtime' is not stored directly as a
state variable. It is computed on demand as:
mtime = rtc_r + time_delta
where:
- 'rtc_r' is the current VM virtual time (in ticks) obtained via
cpu_riscv_read_rtc_raw() from QEMU_CLOCK_VIRTUAL.
- 'time_delta' is an offset applied when the guest writes a new 'mtime'
value via riscv_aclint_mtimer_write():
time_delta = value - rtc_r
Under this design, 'rtc_r' is assumed to be monotonically increasing
during VM execution. Even if the guest writes an 'mtime' value smaller
than the current one (making 'time_delta' negative in signed arithmetic,
or underflow in unsigned arithmetic), the computed 'mtime' remains
correct because 'rtc_r_new > rtc_r_old':
mtime_new = rtc_r_new + (value - rtc_r_old)
However, this monotonicity assumption breaks on snapshot load.
Before restoring a snapshot, QEMU resets the guest, which calls
riscv_aclint_mtimer_reset_enter() to set 'mtime' to 0 and recompute
'time_delta' as:
time_delta = 0 - rtc_r_reset
Here, the time_delta differs from the value that was present when the
snapshot was saved. As a result, subsequent reads produce a fixed offset
from the true mtime.
This can be observed with the 'date' command inside the guest: after loading
a snapshot, the reported time appears "frozen" at the save point, and only
resumes correctly after the guest has run long enough to compensate for the
erroneous offset.
The fix is to treat 'time_delta' as part of the device's migratable
state and save/restore it via vmstate. This preserves the correct
relation between 'rtc_r' and 'mtime' across snapshot save/load, ensuring
'mtime' continues incrementing from the precise saved value after
restore.
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Signed-off-by: TANG Tiancheng <lyndra@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250911-timers-v3-1-60508f640050@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/intc/riscv_aclint.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
index 4623cfa029..318a9c8248 100644
--- a/hw/intc/riscv_aclint.c
+++ b/hw/intc/riscv_aclint.c
@@ -323,9 +323,10 @@ static void riscv_aclint_mtimer_reset_enter(Object *obj, ResetType type)
static const VMStateDescription vmstate_riscv_mtimer = {
.name = "riscv_mtimer",
- .version_id = 1,
- .minimum_version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
.fields = (const VMStateField[]) {
+ VMSTATE_UINT64(time_delta, RISCVAclintMTimerState),
VMSTATE_VARRAY_UINT32(timecmp, RISCVAclintMTimerState,
num_harts, 0,
vmstate_info_uint64, uint64_t),
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 11/26] migration: Add support for a variable-length array of UINT32 pointers
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (9 preceding siblings ...)
2025-10-03 3:27 ` [PULL 10/26] hw/intc: Save time_delta in RISC-V mtimer VMState alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 12/26] hw/intc: Save timers array in RISC-V mtimer VMState alistair23
` (16 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, TANG Tiancheng, LIU Zhiwei, Peter Xu,
Alistair Francis
From: TANG Tiancheng <lyndra@linux.alibaba.com>
Add support for defining a vmstate field which is a variable-length array
of pointers, and use this to define a VMSTATE_TIMER_PTR_VARRAY() which allows
a variable-length array of QEMUTimer* to be used by devices.
Message-id: 20250909-timers-v1-0-7ee18a9d8f4b@linux.alibaba.com
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: TANG Tiancheng <lyndra@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250911-timers-v3-2-60508f640050@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
include/migration/vmstate.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 1ff7bd9ac4..1cfddf31b5 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -522,6 +522,16 @@ extern const VMStateInfo vmstate_info_qlist;
.offset = vmstate_offset_array(_s, _f, _type*, _n), \
}
+#define VMSTATE_VARRAY_OF_POINTER_UINT32(_field, _state, _field_num, _version, _info, _type) { \
+ .name = (stringify(_field)), \
+ .version_id = (_version), \
+ .num_offset = vmstate_offset_value(_state, _field_num, uint32_t), \
+ .info = &(_info), \
+ .size = sizeof(_type), \
+ .flags = VMS_VARRAY_UINT32 | VMS_ARRAY_OF_POINTER | VMS_POINTER, \
+ .offset = vmstate_offset_pointer(_state, _field, _type), \
+}
+
#define VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, _num, _version, _vmsd, _type) { \
.name = (stringify(_field)), \
.version_id = (_version), \
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 12/26] hw/intc: Save timers array in RISC-V mtimer VMState
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (10 preceding siblings ...)
2025-10-03 3:27 ` [PULL 11/26] migration: Add support for a variable-length array of UINT32 pointers alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 13/26] target/riscv: Save stimer and vstimer in CPU vmstate alistair23
` (15 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, TANG Tiancheng, LIU Zhiwei, Alistair Francis
From: TANG Tiancheng <lyndra@linux.alibaba.com>
The current 'timecmp' field in vmstate_riscv_mtimer is insufficient to keep
timers functional after migration.
If an mtimer's entry in 'mtimer->timers' is active at the time the snapshot
is taken, it means riscv_aclint_mtimer_write_timecmp() has written to
'mtimecmp' and scheduled a timer into QEMU's main loop 'timer_list'.
During snapshot save, these active timers must also be migrated; otherwise,
after snapshot load there is no mechanism to restore 'mtimer->timers' back
into the 'timer_list', and any pending timer events would be lost.
QEMU's migration framework commonly uses VMSTATE_TIMER_xxx macros to save
and restore 'QEMUTimer' variables. However, 'timers' is a pointer array
with variable length, and vmstate.h did not previously provide a helper
macro for such type.
This commit adds a new macro, 'VMSTATE_TIMER_PTR_VARRAY', to handle saving
and restoring a variable-length array of 'QEMUTimer *'. We then use this
macro to migrate the 'mtimer->timers' array, ensuring that timer events
remain scheduled correctly after snapshot load.
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Signed-off-by: TANG Tiancheng <lyndra@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250911-timers-v3-3-60508f640050@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
include/hw/intc/riscv_aclint.h | 4 ++++
hw/intc/riscv_aclint.c | 6 ++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/include/hw/intc/riscv_aclint.h b/include/hw/intc/riscv_aclint.h
index 693415eb6d..4b7406eec0 100644
--- a/include/hw/intc/riscv_aclint.h
+++ b/include/hw/intc/riscv_aclint.h
@@ -80,4 +80,8 @@ enum {
RISCV_ACLINT_SWI_SIZE = 0x4000
};
+#define VMSTATE_TIMER_PTR_VARRAY(_f, _s, _f_n) \
+VMSTATE_VARRAY_OF_POINTER_UINT32(_f, _s, _f_n, 0, vmstate_info_timer, \
+ QEMUTimer *)
+
#endif
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
index 318a9c8248..9f4c36e965 100644
--- a/hw/intc/riscv_aclint.c
+++ b/hw/intc/riscv_aclint.c
@@ -323,13 +323,15 @@ static void riscv_aclint_mtimer_reset_enter(Object *obj, ResetType type)
static const VMStateDescription vmstate_riscv_mtimer = {
.name = "riscv_mtimer",
- .version_id = 2,
- .minimum_version_id = 2,
+ .version_id = 3,
+ .minimum_version_id = 3,
.fields = (const VMStateField[]) {
VMSTATE_UINT64(time_delta, RISCVAclintMTimerState),
VMSTATE_VARRAY_UINT32(timecmp, RISCVAclintMTimerState,
num_harts, 0,
vmstate_info_uint64, uint64_t),
+ VMSTATE_TIMER_PTR_VARRAY(timers, RISCVAclintMTimerState,
+ num_harts),
VMSTATE_END_OF_LIST()
}
};
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 13/26] target/riscv: Save stimer and vstimer in CPU vmstate
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (11 preceding siblings ...)
2025-10-03 3:27 ` [PULL 12/26] hw/intc: Save timers array in RISC-V mtimer VMState alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 14/26] target/riscv/kvm: Use riscv_cpu_is_32bit() when handling SBI_DBCN reg alistair23
` (14 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, TANG Tiancheng, LIU Zhiwei, Daniel Henrique Barboza,
Alistair Francis
From: TANG Tiancheng <lyndra@linux.alibaba.com>
vmstate_riscv_cpu was missing env.stimer and env.vstimer.
Without migrating these QEMUTimer fields, active S/VS-mode
timer events are lost after snapshot or migration.
Add VMSTATE_TIMER_PTR() entries to save and restore them.
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Signed-off-by: TANG Tiancheng <lyndra@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250911-timers-v3-4-60508f640050@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/machine.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 1600ec44f0..51e0567ed3 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -400,6 +400,30 @@ static const VMStateDescription vmstate_ssp = {
}
};
+static bool sstc_timer_needed(void *opaque)
+{
+ RISCVCPU *cpu = opaque;
+ CPURISCVState *env = &cpu->env;
+
+ if (!cpu->cfg.ext_sstc) {
+ return false;
+ }
+
+ return env->stimer != NULL || env->vstimer != NULL;
+}
+
+static const VMStateDescription vmstate_sstc = {
+ .name = "cpu/timer",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = sstc_timer_needed,
+ .fields = (const VMStateField[]) {
+ VMSTATE_TIMER_PTR(env.stimer, RISCVCPU),
+ VMSTATE_TIMER_PTR(env.vstimer, RISCVCPU),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
const VMStateDescription vmstate_riscv_cpu = {
.name = "cpu",
.version_id = 10,
@@ -476,6 +500,7 @@ const VMStateDescription vmstate_riscv_cpu = {
&vmstate_elp,
&vmstate_ssp,
&vmstate_ctr,
+ &vmstate_sstc,
NULL
}
};
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 14/26] target/riscv/kvm: Use riscv_cpu_is_32bit() when handling SBI_DBCN reg
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (12 preceding siblings ...)
2025-10-03 3:27 ` [PULL 13/26] target/riscv: Save stimer and vstimer in CPU vmstate alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 15/26] target/riscv: use riscv_csrr in riscv_csr_read alistair23
` (13 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Philippe Mathieu-Daudé, Alistair Francis,
Andrew Jones
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Use the existing riscv_cpu_is_32bit() helper to check for 32-bit CPU.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Message-ID: <20250924164515.51782-1-philmd@linaro.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/kvm/kvm-cpu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 5c19062c19..187c2c9501 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -1588,7 +1588,7 @@ static void kvm_riscv_handle_sbi_dbcn(CPUState *cs, struct kvm_run *run)
* Handle the case where a 32 bit CPU is running in a
* 64 bit addressing env.
*/
- if (riscv_cpu_mxl(&cpu->env) == MXL_RV32) {
+ if (riscv_cpu_is_32bit(cpu)) {
addr |= (uint64_t)run->riscv_sbi.args[2] << 32;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 15/26] target/riscv: use riscv_csrr in riscv_csr_read
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (13 preceding siblings ...)
2025-10-03 3:27 ` [PULL 14/26] target/riscv/kvm: Use riscv_cpu_is_32bit() when handling SBI_DBCN reg alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 16/26] qemu/osdep: align memory allocations to 2M on RISC-V alistair23
` (12 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, stove, Daniel Henrique Barboza, Alistair Francis
From: stove <stove@rivosinc.com>
Commit 38c83e8d3a33 ("target/riscv: raise an exception when CSRRS/CSRRC
writes a read-only CSR") changed the behavior of riscv_csrrw, which
would formerly be treated as read-only if the write mask were set to 0.
Fixes an exception being raised when accessing read-only vector CSRs
like vtype.
Fixes: 38c83e8d3a33 ("target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR")
Signed-off-by: stove <stove@rivosinc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20250827203617.79947-1-stove@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 738e68fa6e..2c2266415e 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -874,7 +874,7 @@ static inline void riscv_csr_write(CPURISCVState *env, int csrno,
static inline target_ulong riscv_csr_read(CPURISCVState *env, int csrno)
{
target_ulong val = 0;
- riscv_csrrw(env, csrno, &val, 0, 0, 0);
+ riscv_csrr(env, csrno, &val);
return val;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 16/26] qemu/osdep: align memory allocations to 2M on RISC-V
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (14 preceding siblings ...)
2025-10-03 3:27 ` [PULL 15/26] target/riscv: use riscv_csrr in riscv_csr_read alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 17/26] target/riscv: do not use translator_ldl in opcode_at alistair23
` (11 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Xuemei Liu, David Hildenbrand, Alistair Francis
From: Xuemei Liu <liu.xuemei1@zte.com.cn>
Similar to other architectures (e.g., x86_64, aarch64), utilizing THP on RISC-V
KVM requires 2MiB-aligned memory blocks.
Signed-off-by: Xuemei Liu <liu.xuemei1@zte.com.cn>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-ID: <20250924131803656Yqt9ZJKfevWkInaGppFdE@zte.com.cn>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
include/qemu/osdep.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 1b38cb7e45..6de6c0c4e5 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -561,7 +561,7 @@ int madvise(char *, size_t, int);
#if defined(__linux__) && \
(defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) \
- || defined(__powerpc64__))
+ || defined(__powerpc64__) || defined(__riscv))
/* Use 2 MiB alignment so transparent hugepages can be used by KVM.
Valgrind does not support alignments larger than 1 MiB,
therefore we need special code which handles running on Valgrind. */
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 17/26] target/riscv: do not use translator_ldl in opcode_at
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (15 preceding siblings ...)
2025-10-03 3:27 ` [PULL 16/26] qemu/osdep: align memory allocations to 2M on RISC-V alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 18/26] target/riscv: Fix the mepc when sspopchk triggers the exception alistair23
` (10 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Vladimir Isaev, Richard Henderson, Alistair Francis
From: Vladimir Isaev <vladimir.isaev@syntacore.com>
opcode_at is used only in semihosting checks to match opcodes with expected
pattern.
This is not a translator and if we got following assert if page is not in TLB:
qemu-system-riscv64: ../accel/tcg/translator.c:363: record_save: Assertion
`offset == db->record_start + db->record_len' failed.
Fixes: 1f9c4462334f ("target/riscv: Use translator_ld* for everything")
Signed-off-by: Vladimir Isaev <vladimir.isaev@syntacore.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250815140633.86920-1-vladimir.isaev@syntacore.com>
[ Changes by AF:
- Fixup header includes after rebase
]
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/translate.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 9ddef2d6e2..6fc06c71f5 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -24,6 +24,7 @@
#include "exec/helper-gen.h"
#include "exec/target_page.h"
#include "exec/translator.h"
+#include "accel/tcg/cpu-ldst.h"
#include "exec/translation-block.h"
#include "exec/log.h"
#include "semihosting/semihost.h"
@@ -1166,7 +1167,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
CPUState *cpu = ctx->cs;
CPURISCVState *env = cpu_env(cpu);
- return translator_ldl(env, &ctx->base, pc);
+ return cpu_ldl_code(env, pc);
}
#define SS_MMU_INDEX(ctx) (ctx->mem_idx | MMU_IDX_SS_WRITE)
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 18/26] target/riscv: Fix the mepc when sspopchk triggers the exception
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (16 preceding siblings ...)
2025-10-03 3:27 ` [PULL 17/26] target/riscv: do not use translator_ldl in opcode_at alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 19/26] target/riscv: Fix SSP CSR error handling in VU/VS mode alistair23
` (9 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Jim Shu, Alistair Francis
From: Jim Shu <jim.shu@sifive.com>
When sspopchk is in the middle of TB and triggers the SW check
exception, it should update PC from gen_update_pc(). If not, RISC-V mepc
CSR will get wrong PC address which is still at the start of TB.
Signed-off-by: Jim Shu <jim.shu@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250924074818.230010-2-jim.shu@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/insn_trans/trans_rvzicfiss.c.inc | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/riscv/insn_trans/trans_rvzicfiss.c.inc b/target/riscv/insn_trans/trans_rvzicfiss.c.inc
index b0096adcd0..45686af4d6 100644
--- a/target/riscv/insn_trans/trans_rvzicfiss.c.inc
+++ b/target/riscv/insn_trans/trans_rvzicfiss.c.inc
@@ -40,6 +40,7 @@ static bool trans_sspopchk(DisasContext *ctx, arg_sspopchk *a)
tcg_gen_brcond_tl(TCG_COND_EQ, data, rs1, skip);
tcg_gen_st_tl(tcg_constant_tl(RISCV_EXCP_SW_CHECK_BCFI_TVAL),
tcg_env, offsetof(CPURISCVState, sw_check_code));
+ gen_update_pc(ctx, 0);
gen_helper_raise_exception(tcg_env,
tcg_constant_i32(RISCV_EXCP_SW_CHECK));
gen_set_label(skip);
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 19/26] target/riscv: Fix SSP CSR error handling in VU/VS mode
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (17 preceding siblings ...)
2025-10-03 3:27 ` [PULL 18/26] target/riscv: Fix the mepc when sspopchk triggers the exception alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 20/26] target/riscv: Fix ssamoswap error handling alistair23
` (8 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Jim Shu, Alistair Francis
From: Jim Shu <jim.shu@sifive.com>
In VU/VS mode, accessing $ssp CSR will trigger the virtual instruction
exception instead of illegal instruction exception if SSE is disabled
via xenvcfg CSRs.
This is from RISC-V CFI v1.0 spec ch2.2.4. Shadow Stack Pointer
Signed-off-by: Jim Shu <jim.shu@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250924074818.230010-3-jim.shu@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/csr.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 3c8989f522..ea36eccb3d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -203,6 +203,8 @@ static RISCVException cfi_ss(CPURISCVState *env, int csrno)
#if !defined(CONFIG_USER_ONLY)
if (env->debugger) {
return RISCV_EXCP_NONE;
+ } else if (env->virt_enabled) {
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
#endif
return RISCV_EXCP_ILLEGAL_INST;
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 20/26] target/riscv: Fix ssamoswap error handling
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (18 preceding siblings ...)
2025-10-03 3:27 ` [PULL 19/26] target/riscv: Fix SSP CSR error handling in VU/VS mode alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 21/26] target/riscv: rvv: Replace checking V by checking Zve32x alistair23
` (7 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Jim Shu, Alistair Francis
From: Jim Shu <jim.shu@sifive.com>
Follow the RISC-V CFI v1.0 spec [1] to fix the exception type
when ssamoswap is disabled by xSSE.
[1] RISC-V CFI spec v1.0, ch2.7 Atomic Swap from a Shadow Stack Location
Signed-off-by: Jim Shu <jim.shu@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250924074818.230010-4-jim.shu@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/helper.h | 5 ++
target/riscv/op_helper.c | 49 +++++++++++++++++++
target/riscv/insn_trans/trans_rvzicfiss.c.inc | 8 +++
3 files changed, 62 insertions(+)
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index f712b1c368..c82bacdc39 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1284,3 +1284,8 @@ DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
DEF_HELPER_5(vsm4k_vi, void, ptr, ptr, i32, env, i32)
DEF_HELPER_4(vsm4r_vv, void, ptr, ptr, env, i32)
DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)
+
+/* CFI (zicfiss) helpers */
+#ifndef CONFIG_USER_ONLY
+DEF_HELPER_1(ssamoswap_disabled, void, env)
+#endif
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 110292e84d..8382aa94cb 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -717,4 +717,53 @@ target_ulong helper_hyp_hlvx_wu(CPURISCVState *env, target_ulong addr)
return cpu_ldl_code_mmu(env, addr, oi, ra);
}
+void helper_ssamoswap_disabled(CPURISCVState *env)
+{
+ int exception = RISCV_EXCP_ILLEGAL_INST;
+
+ /*
+ * Here we follow the RISC-V CFI spec [1] to implement the exception type
+ * of ssamoswap* instruction.
+ *
+ * [1] RISC-V CFI spec v1.0, ch2.7 Atomic Swap from a Shadow Stack Location
+ *
+ * Note: We have already checked some conditions in trans_* functions:
+ * 1. The effective priv mode is not M-mode.
+ * 2. The xSSE specific to the effictive priv mode is disabled.
+ */
+ if (!get_field(env->menvcfg, MENVCFG_SSE)) {
+ /*
+ * Disabled M-mode SSE always trigger illegal instruction when
+ * current priv mode is not M-mode.
+ */
+ exception = RISCV_EXCP_ILLEGAL_INST;
+ goto done;
+ }
+
+ if (!riscv_has_ext(env, RVS)) {
+ /* S-mode is not implemented */
+ exception = RISCV_EXCP_ILLEGAL_INST;
+ goto done;
+ } else if (env->virt_enabled) {
+ /*
+ * VU/VS-mode with disabled xSSE will trigger the virtual instruction
+ * exception.
+ */
+ exception = RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ goto done;
+ } else {
+ /*
+ * U-mode with disabled S-mode SSE will trigger the illegal instruction
+ * exception.
+ *
+ * Note: S-mode is already handled in the disabled M-mode SSE case.
+ */
+ exception = RISCV_EXCP_ILLEGAL_INST;
+ goto done;
+ }
+
+done:
+ riscv_raise_exception(env, exception, GETPC());
+}
+
#endif /* !CONFIG_USER_ONLY */
diff --git a/target/riscv/insn_trans/trans_rvzicfiss.c.inc b/target/riscv/insn_trans/trans_rvzicfiss.c.inc
index 45686af4d6..f4a1c12ca0 100644
--- a/target/riscv/insn_trans/trans_rvzicfiss.c.inc
+++ b/target/riscv/insn_trans/trans_rvzicfiss.c.inc
@@ -91,7 +91,11 @@ static bool trans_ssamoswap_w(DisasContext *ctx, arg_amoswap_w *a)
}
if (!ctx->bcfi_enabled) {
+#ifndef CONFIG_USER_ONLY
+ gen_helper_ssamoswap_disabled(tcg_env);
+#else
return false;
+#endif
}
TCGv dest = dest_gpr(ctx, a->rd);
@@ -116,7 +120,11 @@ static bool trans_ssamoswap_d(DisasContext *ctx, arg_amoswap_w *a)
}
if (!ctx->bcfi_enabled) {
+#ifndef CONFIG_USER_ONLY
+ gen_helper_ssamoswap_disabled(tcg_env);
+#else
return false;
+#endif
}
TCGv dest = dest_gpr(ctx, a->rd);
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 21/26] target/riscv: rvv: Replace checking V by checking Zve32x
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (19 preceding siblings ...)
2025-10-03 3:27 ` [PULL 20/26] target/riscv: Fix ssamoswap error handling alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 22/26] target/riscv: rvv: Modify minimum VLEN according to enabled vector extensions alistair23
` (6 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Max Chou, Alistair Francis
From: Max Chou <max.chou@sifive.com>
The Zve32x extension will be applied by the V and Zve* extensions.
Therefore we can replace the original V checking with Zve32x checking for both
the V and Zve* extensions.
Signed-off-by: Max Chou <max.chou@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250923090729.1887406-2-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.c | 2 +-
target/riscv/csr.c | 3 ++-
target/riscv/machine.c | 3 ++-
target/riscv/riscv-qmp-cmds.c | 2 +-
target/riscv/tcg/tcg-cpu.c | 2 +-
5 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d055ddf462..a877018ab0 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -604,7 +604,7 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
}
}
}
- if (riscv_has_ext(env, RVV) && (flags & CPU_DUMP_VPU)) {
+ if (riscv_cpu_cfg(env)->ext_zve32x && (flags & CPU_DUMP_VPU)) {
static const int dump_rvv_csrs[] = {
CSR_VSTART,
CSR_VXSAT,
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index ea36eccb3d..5c91658c3d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -2005,7 +2005,8 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
if (riscv_has_ext(env, RVF)) {
mask |= MSTATUS_FS;
}
- if (riscv_has_ext(env, RVV)) {
+
+ if (riscv_cpu_cfg(env)->ext_zve32x) {
mask |= MSTATUS_VS;
}
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 51e0567ed3..18d790af0d 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -131,7 +131,8 @@ static bool vector_needed(void *opaque)
RISCVCPU *cpu = opaque;
CPURISCVState *env = &cpu->env;
- return riscv_has_ext(env, RVV);
+ return kvm_enabled() ? riscv_has_ext(env, RVV) :
+ riscv_cpu_cfg(env)->ext_zve32x;
}
static const VMStateDescription vmstate_vector = {
diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c
index b63de8dd45..c499f9b9a7 100644
--- a/target/riscv/riscv-qmp-cmds.c
+++ b/target/riscv/riscv-qmp-cmds.c
@@ -342,7 +342,7 @@ int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
}
if (reg_is_vreg(name)) {
- if (!riscv_has_ext(env, RVV)) {
+ if (!riscv_cpu_cfg(env)->ext_zve32x) {
return -EINVAL;
}
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 143ab079d4..b3b7f14503 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -661,7 +661,7 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
return;
}
- if (riscv_has_ext(env, RVV)) {
+ if (cpu->cfg.ext_zve32x) {
riscv_cpu_validate_v(env, &cpu->cfg, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 22/26] target/riscv: rvv: Modify minimum VLEN according to enabled vector extensions
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (20 preceding siblings ...)
2025-10-03 3:27 ` [PULL 21/26] target/riscv: rvv: Replace checking V by checking Zve32x alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 23/26] target/riscv: rvv: Fix vslide1[up|down].vx unexpected result when XLEN=32 and SEW=64 alistair23
` (5 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Max Chou, Alistair Francis
From: Max Chou <max.chou@sifive.com>
According to the RISC-V unprivileged specification, the VLEN should be greater
or equal to the ELEN. This commit modifies the minimum VLEN based on the vector
extensions and introduces a check rule for VLEN and ELEN.
Extension Minimum VLEN
* V 128
* Zve64[d|f|x] 64
* Zve32[f|x] 32
Signed-off-by: Max Chou <max.chou@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250923090729.1887406-3-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/tcg/tcg-cpu.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index b3b7f14503..1150bd1469 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -417,12 +417,21 @@ static void riscv_cpu_validate_misa_priv(CPURISCVState *env, Error **errp)
static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,
Error **errp)
{
+ uint32_t min_vlen;
uint32_t vlen = cfg->vlenb << 3;
- if (vlen > RV_VLEN_MAX || vlen < 128) {
+ if (riscv_has_ext(env, RVV)) {
+ min_vlen = 128;
+ } else if (cfg->ext_zve64x) {
+ min_vlen = 64;
+ } else if (cfg->ext_zve32x) {
+ min_vlen = 32;
+ }
+
+ if (vlen > RV_VLEN_MAX || vlen < min_vlen) {
error_setg(errp,
"Vector extension implementation only supports VLEN "
- "in the range [128, %d]", RV_VLEN_MAX);
+ "in the range [%d, %d]", min_vlen, RV_VLEN_MAX);
return;
}
@@ -432,6 +441,12 @@ static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,
"in the range [8, 64]");
return;
}
+
+ if (vlen < cfg->elen) {
+ error_setg(errp, "Vector extension implementation requires VLEN "
+ "to be greater than or equal to ELEN");
+ return;
+ }
}
static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 23/26] target/riscv: rvv: Fix vslide1[up|down].vx unexpected result when XLEN=32 and SEW=64
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (21 preceding siblings ...)
2025-10-03 3:27 ` [PULL 22/26] target/riscv: rvv: Modify minimum VLEN according to enabled vector extensions alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 24/26] hw/riscv/riscv-iommu: Fixup PDT Nested Walk alistair23
` (4 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, Max Chou, Alistair Francis
From: Max Chou <max.chou@sifive.com>
When XLEN is 32 and SEW is 64, the original implementation of
vslide1up.vx and vslide1down.vx helper functions fills the 32-bit value
of rs1 into the first element of the destination vector register (rd),
which is a 64-bit element.
This commit attempted to resolve the issue by extending the rs1 value
to 64 bits during the TCG translation phase to ensure that the helper
functions won't lost the higer 32 bits.
Signed-off-by: Max Chou <max.chou@sifive.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250124073325.2467664-1-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/helper.h | 16 ++++----
target/riscv/vector_helper.c | 20 +++++-----
target/riscv/insn_trans/trans_rvv.c.inc | 50 ++++++++++++++++++++++++-
3 files changed, 66 insertions(+), 20 deletions(-)
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index c82bacdc39..b785456ee0 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1101,14 +1101,14 @@ DEF_HELPER_6(vslidedown_vx_b, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vslidedown_vx_h, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vslidedown_vx_w, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vslidedown_vx_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vslide1up_vx_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vslide1up_vx_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vslide1up_vx_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vslide1up_vx_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vslide1down_vx_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vslide1down_vx_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vslide1down_vx_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vslide1down_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslide1up_vx_b, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vslide1up_vx_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vslide1up_vx_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vslide1up_vx_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vslide1down_vx_b, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vslide1down_vx_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vslide1down_vx_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vslide1down_vx_d, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfslide1up_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfslide1up_vf_w, void, ptr, ptr, i64, ptr, env, i32)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 7c67d67a13..41ea223106 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -5198,11 +5198,11 @@ GEN_VEXT_VSLIE1UP(16, H2)
GEN_VEXT_VSLIE1UP(32, H4)
GEN_VEXT_VSLIE1UP(64, H8)
-#define GEN_VEXT_VSLIDE1UP_VX(NAME, BITWIDTH) \
-void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
- CPURISCVState *env, uint32_t desc) \
-{ \
- vslide1up_##BITWIDTH(vd, v0, s1, vs2, env, desc); \
+#define GEN_VEXT_VSLIDE1UP_VX(NAME, BITWIDTH) \
+void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \
+ CPURISCVState *env, uint32_t desc) \
+{ \
+ vslide1up_##BITWIDTH(vd, v0, s1, vs2, env, desc); \
}
/* vslide1up.vx vd, vs2, rs1, vm # vd[0]=x[rs1], vd[i+1] = vs2[i] */
@@ -5249,11 +5249,11 @@ GEN_VEXT_VSLIDE1DOWN(16, H2)
GEN_VEXT_VSLIDE1DOWN(32, H4)
GEN_VEXT_VSLIDE1DOWN(64, H8)
-#define GEN_VEXT_VSLIDE1DOWN_VX(NAME, BITWIDTH) \
-void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
- CPURISCVState *env, uint32_t desc) \
-{ \
- vslide1down_##BITWIDTH(vd, v0, s1, vs2, env, desc); \
+#define GEN_VEXT_VSLIDE1DOWN_VX(NAME, BITWIDTH) \
+void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \
+ CPURISCVState *env, uint32_t desc) \
+{ \
+ vslide1down_##BITWIDTH(vd, v0, s1, vs2, env, desc); \
}
/* vslide1down.vx vd, vs2, rs1, vm # vd[i] = vs2[i+1], vd[vl-1]=x[rs1] */
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 71f98fb350..f4b5460340 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3561,7 +3561,6 @@ static bool slideup_check(DisasContext *s, arg_rmrr *a)
}
GEN_OPIVX_TRANS(vslideup_vx, slideup_check)
-GEN_OPIVX_TRANS(vslide1up_vx, slideup_check)
GEN_OPIVI_TRANS(vslideup_vi, IMM_ZX, vslideup_vx, slideup_check)
static bool slidedown_check(DisasContext *s, arg_rmrr *a)
@@ -3572,9 +3571,56 @@ static bool slidedown_check(DisasContext *s, arg_rmrr *a)
}
GEN_OPIVX_TRANS(vslidedown_vx, slidedown_check)
-GEN_OPIVX_TRANS(vslide1down_vx, slidedown_check)
GEN_OPIVI_TRANS(vslidedown_vi, IMM_ZX, vslidedown_vx, slidedown_check)
+typedef void gen_helper_vslide1_vx(TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_ptr,
+ TCGv_env, TCGv_i32);
+
+#define GEN_OPIVX_VSLIDE1_TRANS(NAME, CHECK) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
+{ \
+ if (CHECK(s, a)) { \
+ static gen_helper_vslide1_vx * const fns[4] = { \
+ gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
+ gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
+ }; \
+ \
+ TCGv_ptr dest, src2, mask; \
+ TCGv_i64 src1; \
+ TCGv_i32 desc; \
+ uint32_t data = 0; \
+ \
+ dest = tcg_temp_new_ptr(); \
+ mask = tcg_temp_new_ptr(); \
+ src2 = tcg_temp_new_ptr(); \
+ src1 = tcg_temp_new_i64(); \
+ \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
+ desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlenb, \
+ s->cfg_ptr->vlenb, data)); \
+ \
+ tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, a->rd)); \
+ tcg_gen_addi_ptr(src2, tcg_env, vreg_ofs(s, a->rs2)); \
+ tcg_gen_addi_ptr(mask, tcg_env, vreg_ofs(s, 0)); \
+ tcg_gen_ext_tl_i64(src1, get_gpr(s, a->rs1, EXT_SIGN)); \
+ \
+ fns[s->sew](dest, mask, src1, src2, tcg_env, desc); \
+ \
+ tcg_gen_movi_tl(cpu_vstart, 0); \
+ finalize_rvv_inst(s); \
+ \
+ return true; \
+ } \
+ return false; \
+}
+
+GEN_OPIVX_VSLIDE1_TRANS(vslide1up_vx, slideup_check)
+GEN_OPIVX_VSLIDE1_TRANS(vslide1down_vx, slidedown_check)
+
/* Vector Floating-Point Slide Instructions */
static bool fslideup_check(DisasContext *s, arg_rmrr *a)
{
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 24/26] hw/riscv/riscv-iommu: Fixup PDT Nested Walk
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (22 preceding siblings ...)
2025-10-03 3:27 ` [PULL 23/26] target/riscv: rvv: Fix vslide1[up|down].vx unexpected result when XLEN=32 and SEW=64 alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 25/26] target/riscv: Fix endianness swap on compressed instructions alistair23
` (3 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Guo Ren (Alibaba DAMO Academy), qemu-stable,
Sebastien Boeuf, Tomasz Jeznach, Weiwei Li, Nutty Liu, Chen Pei,
Fangyu Yu , Alistair Francis
From: "Guo Ren (Alibaba DAMO Academy)" <guoren@kernel.org>
Current implementation is wrong when iohgatp != bare. The RISC-V
IOMMU specification has defined that the PDT is based on GPA, not
SPA. So this patch fixes the problem, making PDT walk correctly
when the G-stage table walk is enabled.
Fixes: 0c54acb8243d ("hw/riscv: add RISC-V IOMMU base emulation")
Cc: qemu-stable@nongnu.org
Cc: Sebastien Boeuf <seb@rivosinc.com>
Cc: Tomasz Jeznach <tjeznach@rivosinc.com>
Reviewed-by: Weiwei Li <liwei1518@gmail.com>
Reviewed-by: Nutty Liu <liujingqi@lanxincomputing.com>
Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
Tested-by: Chen Pei <cp0613@linux.alibaba.com>
Tested-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
Message-ID: <20250913041233.972870-1-guoren@kernel.org>
[ Changes by AF:
- Add braces to if statements
]
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/riscv/riscv-iommu.c | 143 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 141 insertions(+), 2 deletions(-)
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
index 155190d032..b33c7fe325 100644
--- a/hw/riscv/riscv-iommu.c
+++ b/hw/riscv/riscv-iommu.c
@@ -869,6 +869,145 @@ static bool riscv_iommu_validate_process_ctx(RISCVIOMMUState *s,
return true;
}
+/**
+ * pdt_memory_read: PDT wrapper of dma_memory_read.
+ *
+ * @s: IOMMU Device State
+ * @ctx: Device Translation Context with devid and pasid set
+ * @addr: address within that address space
+ * @buf: buffer with the data transferred
+ * @len: length of the data transferred
+ * @attrs: memory transaction attributes
+ */
+static MemTxResult pdt_memory_read(RISCVIOMMUState *s,
+ RISCVIOMMUContext *ctx,
+ dma_addr_t addr,
+ void *buf, dma_addr_t len,
+ MemTxAttrs attrs)
+{
+ uint64_t gatp_mode, pte;
+ struct {
+ unsigned char step;
+ unsigned char levels;
+ unsigned char ptidxbits;
+ unsigned char ptesize;
+ } sc;
+ MemTxResult ret;
+ dma_addr_t base = addr;
+
+ /* G stages translation mode */
+ gatp_mode = get_field(ctx->gatp, RISCV_IOMMU_ATP_MODE_FIELD);
+ if (gatp_mode == RISCV_IOMMU_DC_IOHGATP_MODE_BARE) {
+ goto out;
+ }
+
+ /* G stages translation tables root pointer */
+ base = PPN_PHYS(get_field(ctx->gatp, RISCV_IOMMU_ATP_PPN_FIELD));
+
+ /* Start at step 0 */
+ sc.step = 0;
+
+ if (s->fctl & RISCV_IOMMU_FCTL_GXL) {
+ /* 32bit mode for GXL == 1 */
+ switch (gatp_mode) {
+ case RISCV_IOMMU_DC_IOHGATP_MODE_SV32X4:
+ if (!(s->cap & RISCV_IOMMU_CAP_SV32X4)) {
+ return MEMTX_ACCESS_ERROR;
+ }
+ sc.levels = 2;
+ sc.ptidxbits = 10;
+ sc.ptesize = 4;
+ break;
+ default:
+ return MEMTX_ACCESS_ERROR;
+ }
+ } else {
+ /* 64bit mode for GXL == 0 */
+ switch (gatp_mode) {
+ case RISCV_IOMMU_DC_IOHGATP_MODE_SV39X4:
+ if (!(s->cap & RISCV_IOMMU_CAP_SV39X4)) {
+ return MEMTX_ACCESS_ERROR;
+ }
+ sc.levels = 3;
+ sc.ptidxbits = 9;
+ sc.ptesize = 8;
+ break;
+ case RISCV_IOMMU_DC_IOHGATP_MODE_SV48X4:
+ if (!(s->cap & RISCV_IOMMU_CAP_SV48X4)) {
+ return MEMTX_ACCESS_ERROR;
+ }
+ sc.levels = 4;
+ sc.ptidxbits = 9;
+ sc.ptesize = 8;
+ break;
+ case RISCV_IOMMU_DC_IOHGATP_MODE_SV57X4:
+ if (!(s->cap & RISCV_IOMMU_CAP_SV57X4)) {
+ return MEMTX_ACCESS_ERROR;
+ }
+ sc.levels = 5;
+ sc.ptidxbits = 9;
+ sc.ptesize = 8;
+ break;
+ default:
+ return MEMTX_ACCESS_ERROR;
+ }
+ }
+
+ do {
+ const unsigned va_bits = (sc.step ? 0 : 2) + sc.ptidxbits;
+ const unsigned va_skip = TARGET_PAGE_BITS + sc.ptidxbits *
+ (sc.levels - 1 - sc.step);
+ const unsigned idx = (addr >> va_skip) & ((1 << va_bits) - 1);
+ const dma_addr_t pte_addr = base + idx * sc.ptesize;
+
+ /* Address range check before first level lookup */
+ if (!sc.step) {
+ const uint64_t va_mask = (1ULL << (va_skip + va_bits)) - 1;
+ if ((addr & va_mask) != addr) {
+ return MEMTX_ACCESS_ERROR;
+ }
+ }
+
+ /* Read page table entry */
+ if (sc.ptesize == 4) {
+ uint32_t pte32 = 0;
+ ret = ldl_le_dma(s->target_as, pte_addr, &pte32, attrs);
+ pte = pte32;
+ } else {
+ ret = ldq_le_dma(s->target_as, pte_addr, &pte, attrs);
+ }
+ if (ret != MEMTX_OK) {
+ return ret;
+ }
+
+ sc.step++;
+ hwaddr ppn = pte >> PTE_PPN_SHIFT;
+
+ if (!(pte & PTE_V)) {
+ return MEMTX_ACCESS_ERROR; /* Invalid PTE */
+ } else if (!(pte & (PTE_R | PTE_W | PTE_X))) {
+ base = PPN_PHYS(ppn); /* Inner PTE, continue walking */
+ } else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
+ return MEMTX_ACCESS_ERROR; /* Reserved leaf PTE flags: PTE_W */
+ } else if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) {
+ return MEMTX_ACCESS_ERROR; /* Reserved leaf PTE flags: PTE_W + PTE_X */
+ } else if (ppn & ((1ULL << (va_skip - TARGET_PAGE_BITS)) - 1)) {
+ return MEMTX_ACCESS_ERROR; /* Misaligned PPN */
+ } else {
+ /* Leaf PTE, translation completed. */
+ base = PPN_PHYS(ppn) | (addr & ((1ULL << va_skip) - 1));
+ break;
+ }
+
+ if (sc.step == sc.levels) {
+ return MEMTX_ACCESS_ERROR; /* Can't find leaf PTE */
+ }
+ } while (1);
+
+out:
+ return dma_memory_read(s->target_as, base, buf, len, attrs);
+}
+
/*
* RISC-V IOMMU Device Context Loopkup - Device Directory Tree Walk
*
@@ -1041,7 +1180,7 @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx)
*/
const int split = depth * 9 + 8;
addr |= ((ctx->process_id >> split) << 3) & ~TARGET_PAGE_MASK;
- if (dma_memory_read(s->target_as, addr, &de, sizeof(de),
+ if (pdt_memory_read(s, ctx, addr, &de, sizeof(de),
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
return RISCV_IOMMU_FQ_CAUSE_PDT_LOAD_FAULT;
}
@@ -1056,7 +1195,7 @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx)
/* Leaf entry in PDT */
addr |= (ctx->process_id << 4) & ~TARGET_PAGE_MASK;
- if (dma_memory_read(s->target_as, addr, &dc.ta, sizeof(uint64_t) * 2,
+ if (pdt_memory_read(s, ctx, addr, &dc.ta, sizeof(uint64_t) * 2,
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
return RISCV_IOMMU_FQ_CAUSE_PDT_LOAD_FAULT;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 25/26] target/riscv: Fix endianness swap on compressed instructions
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (23 preceding siblings ...)
2025-10-03 3:27 ` [PULL 24/26] hw/riscv/riscv-iommu: Fixup PDT Nested Walk alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 3:27 ` [PULL 26/26] docs: riscv-iommu: Update status of kernel support alistair23
` (2 subsequent siblings)
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, vhaudiquet, Valentin Haudiquet, qemu-stable,
Anton Johansson, Daniel Henrique Barboza, Heinrich Schuchardt,
Richard Henderson, Alistair Francis
From: vhaudiquet <vhaudiquet343@hotmail.fr>
Three instructions were not using the endianness swap flag, which resulted in a bug on big-endian architectures.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3131
Buglink: https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/2123828
Fixes: e0a3054f18e ("target/riscv: add support for Zcb extension")
Signed-off-by: Valentin Haudiquet <valentin.haudiquet@canonical.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Anton Johansson <anjo@rev.ng>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250929115543.1648157-1-valentin.haudiquet@canonical.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/insn_trans/trans_rvzce.c.inc | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc b/target/riscv/insn_trans/trans_rvzce.c.inc
index c77c2b927b..dd15af0f54 100644
--- a/target/riscv/insn_trans/trans_rvzce.c.inc
+++ b/target/riscv/insn_trans/trans_rvzce.c.inc
@@ -88,13 +88,13 @@ static bool trans_c_lbu(DisasContext *ctx, arg_c_lbu *a)
static bool trans_c_lhu(DisasContext *ctx, arg_c_lhu *a)
{
REQUIRE_ZCB(ctx);
- return gen_load(ctx, a, MO_UW);
+ return gen_load(ctx, a, MO_TEUW);
}
static bool trans_c_lh(DisasContext *ctx, arg_c_lh *a)
{
REQUIRE_ZCB(ctx);
- return gen_load(ctx, a, MO_SW);
+ return gen_load(ctx, a, MO_TESW);
}
static bool trans_c_sb(DisasContext *ctx, arg_c_sb *a)
@@ -106,7 +106,7 @@ static bool trans_c_sb(DisasContext *ctx, arg_c_sb *a)
static bool trans_c_sh(DisasContext *ctx, arg_c_sh *a)
{
REQUIRE_ZCB(ctx);
- return gen_store(ctx, a, MO_UW);
+ return gen_store(ctx, a, MO_TEUW);
}
#define X_S0 8
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PULL 26/26] docs: riscv-iommu: Update status of kernel support
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (24 preceding siblings ...)
2025-10-03 3:27 ` [PULL 25/26] target/riscv: Fix endianness swap on compressed instructions alistair23
@ 2025-10-03 3:27 ` alistair23
2025-10-03 17:33 ` [PULL 00/26] riscv-to-apply queue Richard Henderson
2025-10-08 14:13 ` Michael Tokarev
27 siblings, 0 replies; 32+ messages in thread
From: alistair23 @ 2025-10-03 3:27 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, Joel Stanley, Daniel Henrique Barboza,
Alistair Francis
From: Joel Stanley <joel@jms.id.au>
The iommu Linux kernel support is now upstream. VFIO is still
downstream at this stage.
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Signed-off-by: Joel Stanley <joel@jms.id.au>
Message-ID: <20250814001452.504510-1-joel@jms.id.au>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
docs/specs/riscv-iommu.rst | 35 +++++++++++++----------------------
1 file changed, 13 insertions(+), 22 deletions(-)
diff --git a/docs/specs/riscv-iommu.rst b/docs/specs/riscv-iommu.rst
index 991d376fdc..571a6a6cc9 100644
--- a/docs/specs/riscv-iommu.rst
+++ b/docs/specs/riscv-iommu.rst
@@ -30,15 +30,15 @@ This will add a RISC-V IOMMU PCI device in the board following any additional
PCI parameters (like PCI bus address). The behavior of the RISC-V IOMMU is
defined by the spec but its operation is OS dependent.
-As of this writing the existing Linux kernel support `linux-v8`_, not yet merged,
-does not have support for features like VFIO passthrough. The IOMMU emulation
-was tested using a public Ventana Micro Systems kernel repository in
-`ventana-linux`_. This kernel is based on `linux-v8`_ with additional patches that
-enable features like KVM VFIO passthrough with irqbypass. Until the kernel support
-is feature complete feel free to use the kernel available in the Ventana Micro Systems
-mirror.
-
-The current Linux kernel support will use the IOMMU device to create IOMMU groups
+Linux kernel iommu support was merged in v6.13. QEMU IOMMU emulation can be
+used with mainline kernels for simple IOMMU PCIe support.
+
+As of v6.17, it does not have support for features like VFIO passthrough.
+There is a `VFIO`_ RFC series that is not yet merged. The public Ventana Micro
+Systems kernel repository in `ventana-linux`_ can be used for testing the VFIO
+functions.
+
+The v6.13+ Linux kernel support uses the IOMMU device to create IOMMU groups
with any eligible cards available in the system, regardless of factors such as the
order in which the devices are added in the command line.
@@ -49,7 +49,7 @@ IOMMU kernel driver behaves:
$ qemu-system-riscv64 \
-M virt,aia=aplic-imsic,aia-guests=5 \
- -device riscv-iommu-pci,addr=1.0,vendor-id=0x1efd,device-id=0xedf1 \
+ -device riscv-iommu-pci,addr=1.0 \
-device e1000e,netdev=net1 -netdev user,id=net1,net=192.168.0.0/24 \
-device e1000e,netdev=net2 -netdev user,id=net2,net=192.168.200.0/24 \
(...)
@@ -58,21 +58,11 @@ IOMMU kernel driver behaves:
-M virt,aia=aplic-imsic,aia-guests=5 \
-device e1000e,netdev=net1 -netdev user,id=net1,net=192.168.0.0/24 \
-device e1000e,netdev=net2 -netdev user,id=net2,net=192.168.200.0/24 \
- -device riscv-iommu-pci,addr=1.0,vendor-id=0x1efd,device-id=0xedf1 \
+ -device riscv-iommu-pci,addr=3.0 \
(...)
Both will create iommu groups for the two e1000e cards.
-Another thing to notice on `linux-v8`_ and `ventana-linux`_ is that the kernel driver
-considers an IOMMU identified as a Rivos device, i.e. it uses Rivos vendor ID. To
-use the riscv-iommu-pci device with the existing kernel support we need to emulate
-a Rivos PCI IOMMU by setting 'vendor-id' and 'device-id':
-
-.. code-block:: bash
-
- $ qemu-system-riscv64 -M virt \
- -device riscv-iommu-pci,vendor-id=0x1efd,device-id=0xedf1 (...)
-
Several options are available to control the capabilities of the device, namely:
- "bus": the bus that the IOMMU device uses
@@ -84,6 +74,7 @@ Several options are available to control the capabilities of the device, namely:
- "g-stage": enable g-stage support
- "hpm-counters": number of hardware performance counters available. Maximum value is 31.
Default value is 31. Use 0 (zero) to disable HPM support
+- "vendor-id"/"device-id": pci device ID. Defaults to 1b36:0014 (Redhat)
riscv-iommu-sys device
----------------------
@@ -111,6 +102,6 @@ riscv-iommu options:
.. _iommu1.0.0: https://github.com/riscv-non-isa/riscv-iommu/releases/download/v1.0.0/riscv-iommu.pdf
-.. _linux-v8: https://lore.kernel.org/linux-riscv/cover.1718388908.git.tjeznach@rivosinc.com/
+.. _VFIO: https://lore.kernel.org/linux-riscv/20241114161845.502027-17-ajones@ventanamicro.com/
.. _ventana-linux: https://github.com/ventanamicro/linux/tree/dev-upstream
--
2.51.0
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PULL 00/26] riscv-to-apply queue
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (25 preceding siblings ...)
2025-10-03 3:27 ` [PULL 26/26] docs: riscv-iommu: Update status of kernel support alistair23
@ 2025-10-03 17:33 ` Richard Henderson
2025-10-08 14:13 ` Michael Tokarev
27 siblings, 0 replies; 32+ messages in thread
From: Richard Henderson @ 2025-10-03 17:33 UTC (permalink / raw)
To: qemu-devel
On 10/2/25 20:26, alistair23@gmail.com wrote:
> From: Alistair Francis<alistair.francis@wdc.com>
>
> The following changes since commit 29b77c1a2db2d796bc3847852a5c8dc2a1e6e83b:
>
> Merge tag 'rust-ci-pull-request' ofhttps://gitlab.com/marcandre.lureau/qemu into staging (2025-09-30 09:29:38 -0700)
>
> are available in the Git repository at:
>
> https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20251003-3
>
> for you to fetch changes up to ad2a0aa2824b1dac9f61bac33980e866e9a88856:
>
> docs: riscv-iommu: Update status of kernel support (2025-10-03 13:17:04 +1000)
>
> ----------------------------------------------------------------
> First RISC-V PR for 10.2
>
> * Fix MSI table size limit
> * Add riscv64 to FirmwareArchitecture
> * Sync RISC-V hwprobe with Linux
> * Implement MonitorDef HMP API
> * Update OpenSBI to v1.7
> * Fix SiFive UART character drop issue and minor refactors
> * Fix RISC-V timer migration issues
> * Use riscv_cpu_is_32bit() when handling SBI_DBCN reg
> * Use riscv_csrr in riscv_csr_read
> * Align memory allocations to 2M on RISC-V
> * Do not use translator_ldl in opcode_at
> * Minor fixes of RISC-V CFI
> * Modify minimum VLEN rule
> * Fix vslide1[up|down].vx unexpected result when XLEN=32 and SEW=64
> * Fixup IOMMU PDT Nested Walk
> * Fix endianness swap on compressed instructions
> * Update status of IOMMU kernel support
Applied, thanks. Please update https://wiki.qemu.org/ChangeLog/10.2 as appropriate.
r~
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PULL 00/26] riscv-to-apply queue
2025-10-03 3:26 [PULL 00/26] riscv-to-apply queue alistair23
` (26 preceding siblings ...)
2025-10-03 17:33 ` [PULL 00/26] riscv-to-apply queue Richard Henderson
@ 2025-10-08 14:13 ` Michael Tokarev
2025-10-09 2:46 ` Alistair Francis
27 siblings, 1 reply; 32+ messages in thread
From: Michael Tokarev @ 2025-10-08 14:13 UTC (permalink / raw)
To: alistair23, qemu-devel, qemu-stable
Cc: Alistair Francis, Frank Chang, Jim Shu, Vladimir Isaev, stove
On 10/3/25 06:26, alistair23@gmail.com wrote:
> From: Alistair Francis <alistair.francis@wdc.com>
> First RISC-V PR for 10.2
>
> * Fix MSI table size limit
> * Add riscv64 to FirmwareArchitecture
> * Sync RISC-V hwprobe with Linux
> * Implement MonitorDef HMP API
> * Update OpenSBI to v1.7
> * Fix SiFive UART character drop issue and minor refactors
> * Fix RISC-V timer migration issues
> * Use riscv_cpu_is_32bit() when handling SBI_DBCN reg
> * Use riscv_csrr in riscv_csr_read
> * Align memory allocations to 2M on RISC-V
> * Do not use translator_ldl in opcode_at
> * Minor fixes of RISC-V CFI
> * Modify minimum VLEN rule
> * Fix vslide1[up|down].vx unexpected result when XLEN=32 and SEW=64
> * Fixup IOMMU PDT Nested Walk
> * Fix endianness swap on compressed instructions
> * Update status of IOMMU kernel support
Hi!
Is there anything in there which is worth picking up for the active
stable releases of qemu, which are 10.0.x (lts) and 10.1.x?
From the patch descriptions, it seems like quite a few changes in
there are worth to be back-ported. For example:
- target/riscv: rvv: Fix vslide1[up|down].vx unexpected result
when XLEN=32 and SEW=64
- target/riscv: Fix ssamoswap error handling
- target/riscv: Fix SSP CSR error handling in VU/VS mode
- target/riscv: Fix the mepc when sspopchk triggers the exception
- target/riscv: use riscv_csrr in riscv_csr_read
- hw/char: sifive_uart: Raise IRQ according to the Tx/Rx
watermark thresholds
This is just from reading the commit messages, - I haven't looked
at the actual changes in the code. Maybe some other changes should
be picked up too.
I already picked up VLEN fixes, "MSI table size limit" and
"do not use translator_ldl in opcode_at" (and I'm still unsure
about the latter).
Some changes has been Cc'd qemu-stable before, so I picked these
up too, eg "Fix endianness swap on compressed instructions" and
"Fixup PDT Nested Walk".
Some other changes, like the timer array/time delta, does not look
like possibilities for the older series due to incompatibility in
migration they bring.
Thanks,
/mjt
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PULL 00/26] riscv-to-apply queue
2025-10-08 14:13 ` Michael Tokarev
@ 2025-10-09 2:46 ` Alistair Francis
0 siblings, 0 replies; 32+ messages in thread
From: Alistair Francis @ 2025-10-09 2:46 UTC (permalink / raw)
To: Michael Tokarev
Cc: qemu-devel, qemu-stable, Alistair Francis, Frank Chang, Jim Shu,
Vladimir Isaev, stove
On Thu, Oct 9, 2025 at 12:13 AM Michael Tokarev <mjt@tls.msk.ru> wrote:
>
> On 10/3/25 06:26, alistair23@gmail.com wrote:
> > From: Alistair Francis <alistair.francis@wdc.com>
>
> > First RISC-V PR for 10.2
> >
> > * Fix MSI table size limit
> > * Add riscv64 to FirmwareArchitecture
> > * Sync RISC-V hwprobe with Linux
> > * Implement MonitorDef HMP API
> > * Update OpenSBI to v1.7
> > * Fix SiFive UART character drop issue and minor refactors
> > * Fix RISC-V timer migration issues
> > * Use riscv_cpu_is_32bit() when handling SBI_DBCN reg
> > * Use riscv_csrr in riscv_csr_read
> > * Align memory allocations to 2M on RISC-V
> > * Do not use translator_ldl in opcode_at
> > * Minor fixes of RISC-V CFI
> > * Modify minimum VLEN rule
> > * Fix vslide1[up|down].vx unexpected result when XLEN=32 and SEW=64
> > * Fixup IOMMU PDT Nested Walk
> > * Fix endianness swap on compressed instructions
> > * Update status of IOMMU kernel support
>
> Hi!
>
> Is there anything in there which is worth picking up for the active
> stable releases of qemu, which are 10.0.x (lts) and 10.1.x?
>
> From the patch descriptions, it seems like quite a few changes in
> there are worth to be back-ported. For example:
>
> - target/riscv: rvv: Fix vslide1[up|down].vx unexpected result
> when XLEN=32 and SEW=64
Yes
> - target/riscv: Fix ssamoswap error handling
> - target/riscv: Fix SSP CSR error handling in VU/VS mode
> - target/riscv: Fix the mepc when sspopchk triggers the exception
Yes
> - target/riscv: use riscv_csrr in riscv_csr_read
Yes
> - hw/char: sifive_uart: Raise IRQ according to the Tx/Rx
> watermark thresholds
Yes
>
> This is just from reading the commit messages, - I haven't looked
> at the actual changes in the code. Maybe some other changes should
> be picked up too.
>
> I already picked up VLEN fixes, "MSI table size limit" and
> "do not use translator_ldl in opcode_at" (and I'm still unsure
> about the latter).
>
> Some changes has been Cc'd qemu-stable before, so I picked these
> up too, eg "Fix endianness swap on compressed instructions" and
> "Fixup PDT Nested Walk".
Thank you. I think that's all that should be back ported
>
> Some other changes, like the timer array/time delta, does not look
> like possibilities for the older series due to incompatibility in
> migration they bring.
Agreed
Alistair
>
> Thanks,
>
> /mjt
^ permalink raw reply [flat|nested] 32+ messages in thread