Skip to content

Commit 17e9c90

Browse files
committed
Merge tag 'pull-riscv-to-apply-20250319' of https://github.com/alistair23/qemu into staging
Fourth RISC-V PR for 10.0 * Fix broken emulation link * Optimize the memory probing for vector fault-only-first loads * Fix access permission checks for CSR_SSP * Fixes a bug against `ssamoswap` behavior in M-mode * Fix IOMMU process directory table walk * Fix OVERFLOW_BEFORE_WIDEN in rmw_sctrdepth() * Enhance VSTART and VL checks for vector instructions * Fix handling of cpu mask in riscv_hwprobe syscall * Add check for 16-bit aligned PC for different priv versions # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEEaukCtqfKh31tZZKWr3yVEwxTgBMFAmfaehkACgkQr3yVEwxT # gBOagRAAsSC/0Fof5EpXc14zmaw7CtoqSCTHVYXYxIEFjRu2Nj89z1HSlB00ptjZ # g/x5gxJRW8pGarYL6EAKKhk7BpswZ87DbsM/3kQwGraWN/or4SLj12E1V6+UhDi6 # e8qV3oHT8/dMoi/cUc9sM2FNah6gWckxy4QwLzX41jI6wkHe72IC52u9OP6b2ny5 # iky1ThDeQiZmGfj13se9cK1XFNPZgSnJFYD6k9OQTmaMzSShcM64ewv95RfiJbjA # s8kDmXYrrSQbjWyrjf2JIWhm6dFagFW4u/ho5481gZ1ntw1DnqlHXKCEWSPhIBOm # WzvfK0dEkmgtOW0DJ7aBdbDJWNRcYCW3xiuUlHrQ7QDRmwreTrF1mo9sD9KifwIo # NPzScf/O+GPuqDKcV6SfT6rV/Jpr8yaK9WaB/KeDsmhrmsDBn4GCrxu6Z/bLadCy # AnLItH8BCssSIA989VzwN0V3AsJK8cDQiRzM3/Mq8zp2yNvaBbuGLFxvAzV4sFZY # PIc7jhWek8Dw1SxIwuXvh/04iNkQNbnowzCQo7q7Cokf4vQtcTSuLblq3IgAJyDn # eCNXY0SgHNvA6DCxF+ZYAjpgo6ZFusGq1Yq9KzbaH+a3vYOOHhFix4wrFyyApu7+ # 1nBgETtewKfHqo2+GtYr/g1O+WYruf1TC5bCdiWpvvPDR/a7zJM= # =SqiB # -----END PGP SIGNATURE----- # gpg: Signature made Wed 19 Mar 2025 04:02:33 EDT # gpg: using RSA key 6AE902B6A7CA877D6D659296AF7C95130C538013 # gpg: Good signature from "Alistair Francis <[email protected]>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 6AE9 02B6 A7CA 877D 6D65 9296 AF7C 9513 0C53 8013 * tag 'pull-riscv-to-apply-20250319' of https://github.com/alistair23/qemu: target/riscv: Add check for 16-bit aligned PC for different priv versions. linux-user/riscv: Fix handling of cpu mask in riscv_hwprobe syscall target/riscv: fix handling of nop for vstart >= vl in some vector instruction target/riscv: refactor VSTART_CHECK_EARLY_EXIT() to accept vl as a parameter target/riscv/csr.c: fix OVERFLOW_BEFORE_WIDEN in rmw_sctrdepth() hw/riscv/riscv-iommu: Fix process directory table walk target/riscv: fixes a bug against `ssamoswap` behavior in M-mode target/riscv: fix access permission checks for CSR_SSP optimize the memory probing for vector fault-only-first loads. docs/about/emulation: Fix broken link Signed-off-by: Stefan Hajnoczi <[email protected]>
2 parents 1dae461 + ffe4db1 commit 17e9c90

File tree

14 files changed

+214
-143
lines changed

14 files changed

+214
-143
lines changed

docs/about/emulation.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ for that architecture.
171171
- Unified Hosting Interface (MD01069)
172172
* - RISC-V
173173
- System and User-mode
174-
- https://github.com/riscv/riscv-semihosting-spec/blob/main/riscv-semihosting-spec.adoc
174+
- https://github.com/riscv-non-isa/riscv-semihosting/blob/main/riscv-semihosting.adoc
175175
* - Xtensa
176176
- System
177177
- Tensilica ISS SIMCALL

hw/riscv/riscv-iommu-bits.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,12 +415,16 @@ enum riscv_iommu_fq_causes {
415415
#define RISCV_IOMMU_DC_MSIPTP_MODE_OFF 0
416416
#define RISCV_IOMMU_DC_MSIPTP_MODE_FLAT 1
417417

418+
/* 2.2 Process Directory Table */
419+
#define RISCV_IOMMU_PDTE_VALID BIT_ULL(0)
420+
#define RISCV_IOMMU_PDTE_PPN RISCV_IOMMU_PPN_FIELD
421+
418422
/* Translation attributes fields */
419423
#define RISCV_IOMMU_PC_TA_V BIT_ULL(0)
420424
#define RISCV_IOMMU_PC_TA_RESERVED GENMASK_ULL(63, 32)
421425

422426
/* First stage context fields */
423-
#define RISCV_IOMMU_PC_FSC_PPN GENMASK_ULL(43, 0)
427+
#define RISCV_IOMMU_PC_FSC_PPN RISCV_IOMMU_ATP_PPN_FIELD
424428
#define RISCV_IOMMU_PC_FSC_RESERVED GENMASK_ULL(59, 44)
425429

426430
enum riscv_iommu_fq_ttypes {

hw/riscv/riscv-iommu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,10 +1042,10 @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx)
10421042
return RISCV_IOMMU_FQ_CAUSE_PDT_LOAD_FAULT;
10431043
}
10441044
le64_to_cpus(&de);
1045-
if (!(de & RISCV_IOMMU_PC_TA_V)) {
1045+
if (!(de & RISCV_IOMMU_PDTE_VALID)) {
10461046
return RISCV_IOMMU_FQ_CAUSE_PDT_INVALID;
10471047
}
1048-
addr = PPN_PHYS(get_field(de, RISCV_IOMMU_PC_FSC_PPN));
1048+
addr = PPN_PHYS(get_field(de, RISCV_IOMMU_PDTE_PPN));
10491049
}
10501050

10511051
riscv_iommu_hpm_incr_ctr(s, ctx, RISCV_IOMMU_HPMEVENT_PD_WALK);

linux-user/syscall.c

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9119,35 +9119,38 @@ static void risc_hwprobe_fill_pairs(CPURISCVState *env,
91199119
}
91209120
}
91219121

9122-
static int cpu_set_valid(abi_long arg3, abi_long arg4)
9122+
/*
9123+
* If the cpumask_t of (target_cpus, cpusetsize) cannot be read: -EFAULT.
9124+
* If the cpumast_t has no bits set: -EINVAL.
9125+
* Otherwise the cpumask_t contains some bit set: 0.
9126+
* Unlike the kernel, we do not mask cpumask_t by the set of online cpus,
9127+
* nor bound the search by cpumask_size().
9128+
*/
9129+
static int nonempty_cpu_set(abi_ulong cpusetsize, abi_ptr target_cpus)
91239130
{
9124-
int ret, i, tmp;
9125-
size_t host_mask_size, target_mask_size;
9126-
unsigned long *host_mask;
9127-
9128-
/*
9129-
* cpu_set_t represent CPU masks as bit masks of type unsigned long *.
9130-
* arg3 contains the cpu count.
9131-
*/
9132-
tmp = (8 * sizeof(abi_ulong));
9133-
target_mask_size = ((arg3 + tmp - 1) / tmp) * sizeof(abi_ulong);
9134-
host_mask_size = (target_mask_size + (sizeof(*host_mask) - 1)) &
9135-
~(sizeof(*host_mask) - 1);
9136-
9137-
host_mask = alloca(host_mask_size);
9138-
9139-
ret = target_to_host_cpu_mask(host_mask, host_mask_size,
9140-
arg4, target_mask_size);
9141-
if (ret != 0) {
9142-
return ret;
9143-
}
9131+
unsigned char *p = lock_user(VERIFY_READ, target_cpus, cpusetsize, 1);
9132+
int ret = -TARGET_EFAULT;
91449133

9145-
for (i = 0 ; i < host_mask_size / sizeof(*host_mask); i++) {
9146-
if (host_mask[i] != 0) {
9147-
return 0;
9134+
if (p) {
9135+
ret = -TARGET_EINVAL;
9136+
/*
9137+
* Since we only care about the empty/non-empty state of the cpumask_t
9138+
* not the individual bits, we do not need to repartition the bits
9139+
* from target abi_ulong to host unsigned long.
9140+
*
9141+
* Note that the kernel does not round up cpusetsize to a multiple of
9142+
* sizeof(abi_ulong). After bounding cpusetsize by cpumask_size(),
9143+
* it copies exactly cpusetsize bytes into a zeroed buffer.
9144+
*/
9145+
for (abi_ulong i = 0; i < cpusetsize; ++i) {
9146+
if (p[i]) {
9147+
ret = 0;
9148+
break;
9149+
}
91489150
}
9151+
unlock_user(p, target_cpus, 0);
91499152
}
9150-
return -TARGET_EINVAL;
9153+
return ret;
91519154
}
91529155

91539156
static abi_long do_riscv_hwprobe(CPUArchState *cpu_env, abi_long arg1,
@@ -9164,7 +9167,7 @@ static abi_long do_riscv_hwprobe(CPUArchState *cpu_env, abi_long arg1,
91649167

91659168
/* check cpu_set */
91669169
if (arg3 != 0) {
9167-
ret = cpu_set_valid(arg3, arg4);
9170+
ret = nonempty_cpu_set(arg3, arg4);
91689171
if (ret != 0) {
91699172
return ret;
91709173
}

target/riscv/cpu.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,18 @@ static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env)
765765
}
766766
#endif
767767

768+
static inline bool riscv_cpu_allow_16bit_insn(const RISCVCPUConfig *cfg,
769+
target_long priv_ver,
770+
uint32_t misa_ext)
771+
{
772+
/* In priv spec version 1.12 or newer, C always implies Zca */
773+
if (priv_ver >= PRIV_VERSION_1_12_0) {
774+
return cfg->ext_zca;
775+
} else {
776+
return misa_ext & RVC;
777+
}
778+
}
779+
768780
/*
769781
* Encode LMUL to lmul as follows:
770782
* LMUL vlmul lmul

target/riscv/csr.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,11 @@ static RISCVException cfi_ss(CPURISCVState *env, int csrno)
192192
return RISCV_EXCP_ILLEGAL_INST;
193193
}
194194

195+
/* If ext implemented, M-mode always have access to SSP CSR */
196+
if (env->priv == PRV_M) {
197+
return RISCV_EXCP_NONE;
198+
}
199+
195200
/* if bcfi not active for current env, access to csr is illegal */
196201
if (!cpu_get_bcfien(env)) {
197202
#if !defined(CONFIG_USER_ONLY)
@@ -4297,7 +4302,7 @@ static RISCVException rmw_sctrdepth(CPURISCVState *env, int csrno,
42974302
}
42984303

42994304
/* Update sctrstatus.WRPTR with a legal value */
4300-
depth = 16 << depth;
4305+
depth = 16ULL << depth;
43014306
env->sctrstatus =
43024307
env->sctrstatus & (~SCTRSTATUS_WRPTR_MASK | (depth - 1));
43034308
}

target/riscv/insn_trans/trans_rvi.c.inc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,9 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
151151
tcg_gen_ext32s_tl(target_pc, target_pc);
152152
}
153153

154-
if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) {
154+
if (!riscv_cpu_allow_16bit_insn(ctx->cfg_ptr,
155+
ctx->priv_ver,
156+
ctx->misa_ext)) {
155157
TCGv t0 = tcg_temp_new();
156158

157159
misaligned = gen_new_label();
@@ -300,7 +302,9 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
300302

301303
gen_set_label(l); /* branch taken */
302304

303-
if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca &&
305+
if (!riscv_cpu_allow_16bit_insn(ctx->cfg_ptr,
306+
ctx->priv_ver,
307+
ctx->misa_ext) &&
304308
(a->imm & 0x3)) {
305309
/* misaligned */
306310
TCGv target_pc = tcg_temp_new();

target/riscv/insn_trans/trans_rvzicfiss.c.inc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@
1515
* You should have received a copy of the GNU General Public License along with
1616
* this program. If not, see <http://www.gnu.org/licenses/>.
1717
*/
18+
19+
#define REQUIRE_ZICFISS(ctx) do { \
20+
if (!ctx->cfg_ptr->ext_zicfiss) { \
21+
return false; \
22+
} \
23+
} while (0)
24+
1825
static bool trans_sspopchk(DisasContext *ctx, arg_sspopchk *a)
1926
{
2027
if (!ctx->bcfi_enabled) {
@@ -77,6 +84,11 @@ static bool trans_ssrdp(DisasContext *ctx, arg_ssrdp *a)
7784
static bool trans_ssamoswap_w(DisasContext *ctx, arg_amoswap_w *a)
7885
{
7986
REQUIRE_A_OR_ZAAMO(ctx);
87+
REQUIRE_ZICFISS(ctx);
88+
if (ctx->priv == PRV_M) {
89+
generate_exception(ctx, RISCV_EXCP_STORE_AMO_ACCESS_FAULT);
90+
}
91+
8092
if (!ctx->bcfi_enabled) {
8193
return false;
8294
}
@@ -97,6 +109,11 @@ static bool trans_ssamoswap_d(DisasContext *ctx, arg_amoswap_w *a)
97109
{
98110
REQUIRE_64BIT(ctx);
99111
REQUIRE_A_OR_ZAAMO(ctx);
112+
REQUIRE_ZICFISS(ctx);
113+
if (ctx->priv == PRV_M) {
114+
generate_exception(ctx, RISCV_EXCP_STORE_AMO_ACCESS_FAULT);
115+
}
116+
100117
if (!ctx->bcfi_enabled) {
101118
return false;
102119
}

target/riscv/op_helper.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,9 @@ target_ulong helper_sret(CPURISCVState *env)
279279
}
280280

281281
target_ulong retpc = env->sepc;
282-
if (!riscv_has_ext(env, RVC) && (retpc & 0x3)) {
282+
if (!riscv_cpu_allow_16bit_insn(&env_archcpu(env)->cfg,
283+
env->priv_ver,
284+
env->misa_ext) && (retpc & 0x3)) {
283285
riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
284286
}
285287

@@ -357,7 +359,9 @@ static void check_ret_from_m_mode(CPURISCVState *env, target_ulong retpc,
357359
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
358360
}
359361

360-
if (!riscv_has_ext(env, RVC) && (retpc & 0x3)) {
362+
if (!riscv_cpu_allow_16bit_insn(&env_archcpu(env)->cfg,
363+
env->priv_ver,
364+
env->misa_ext) && (retpc & 0x3)) {
361365
riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
362366
}
363367

target/riscv/translate.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,9 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
606606
TCGv succ_pc = dest_gpr(ctx, rd);
607607

608608
/* check misaligned: */
609-
if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) {
609+
if (!riscv_cpu_allow_16bit_insn(ctx->cfg_ptr,
610+
ctx->priv_ver,
611+
ctx->misa_ext)) {
610612
if ((imm & 0x3) != 0) {
611613
TCGv target_pc = tcg_temp_new();
612614
gen_pc_plus_diff(target_pc, ctx, imm);

0 commit comments

Comments
 (0)