1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | The following changes since commit 1dae461a913f9da88df05de6e2020d3134356f2e: |
---|---|---|---|
2 | 2 | ||
3 | The following changes since commit c5fbdd60cf1fb52f01bdfe342b6fa65d5343e1b1: | 3 | Update version for v10.0.0-rc0 release (2025-03-18 10:18:14 -0400) |
4 | |||
5 | Merge tag 'qemu-sparc-20211121' of git://github.com/mcayland/qemu into staging (2021-11-21 14:12:25 +0100) | ||
6 | 4 | ||
7 | are available in the Git repository at: | 5 | are available in the Git repository at: |
8 | 6 | ||
9 | git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20211122 | 7 | https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20250319 |
10 | 8 | ||
11 | for you to fetch changes up to 526e7443027c71fe7b04c29df529e1f9f425f9e3: | 9 | for you to fetch changes up to ffe4db11f8aed79c7ec7d3ebd92674a1cfab4fe7: |
12 | 10 | ||
13 | hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset (2021-11-22 10:46:22 +1000) | 11 | target/riscv: Add check for 16-bit aligned PC for different priv versions. (2025-03-19 17:11:46 +1000) |
14 | 12 | ||
15 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
16 | Seventh RISC-V PR for QEMU 6.2 | 14 | Fourth RISC-V PR for 10.0 |
17 | 15 | ||
18 | - Deprecate IF_NONE for SiFive OTP | 16 | * Fix broken emulation link |
19 | - Don't reset SiFive OTP content | 17 | * Optimize the memory probing for vector fault-only-first loads |
18 | * Fix access permission checks for CSR_SSP | ||
19 | * Fixes a bug against `ssamoswap` behavior in M-mode | ||
20 | * Fix IOMMU process directory table walk | ||
21 | * Fix OVERFLOW_BEFORE_WIDEN in rmw_sctrdepth() | ||
22 | * Enhance VSTART and VL checks for vector instructions | ||
23 | * Fix handling of cpu mask in riscv_hwprobe syscall | ||
24 | * Add check for 16-bit aligned PC for different priv versions | ||
20 | 25 | ||
21 | ---------------------------------------------------------------- | 26 | ---------------------------------------------------------------- |
22 | Philippe Mathieu-Daudé (1): | 27 | Chao Liu (2): |
23 | hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset | 28 | target/riscv: refactor VSTART_CHECK_EARLY_EXIT() to accept vl as a parameter |
29 | target/riscv: fix handling of nop for vstart >= vl in some vector instruction | ||
24 | 30 | ||
25 | Thomas Huth (1): | 31 | Daniel Henrique Barboza (1): |
26 | hw/misc/sifive_u_otp: Use IF_PFLASH for the OTP device instead of IF_NONE | 32 | target/riscv/csr.c: fix OVERFLOW_BEFORE_WIDEN in rmw_sctrdepth() |
27 | 33 | ||
28 | docs/about/deprecated.rst | 6 ++++++ | 34 | Deepak Gupta (2): |
29 | hw/misc/sifive_u_otp.c | 22 +++++++++++++--------- | 35 | target/riscv: fix access permission checks for CSR_SSP |
30 | 2 files changed, 19 insertions(+), 9 deletions(-) | 36 | target/riscv: fixes a bug against `ssamoswap` behavior in M-mode |
31 | 37 | ||
38 | Jason Chien (1): | ||
39 | hw/riscv/riscv-iommu: Fix process directory table walk | ||
40 | |||
41 | Paolo Savini (1): | ||
42 | optimize the memory probing for vector fault-only-first loads. | ||
43 | |||
44 | Richard Henderson (1): | ||
45 | linux-user/riscv: Fix handling of cpu mask in riscv_hwprobe syscall | ||
46 | |||
47 | Santiago Monserrat Campanello (1): | ||
48 | docs/about/emulation: Fix broken link | ||
49 | |||
50 | Yu-Ming Chang (1): | ||
51 | target/riscv: Add check for 16-bit aligned PC for different priv versions. | ||
52 | |||
53 | docs/about/emulation.rst | 2 +- | ||
54 | hw/riscv/riscv-iommu-bits.h | 6 +- | ||
55 | target/riscv/cpu.h | 12 ++ | ||
56 | target/riscv/vector_internals.h | 12 +- | ||
57 | hw/riscv/riscv-iommu.c | 4 +- | ||
58 | linux-user/syscall.c | 55 ++++---- | ||
59 | target/riscv/csr.c | 7 +- | ||
60 | target/riscv/op_helper.c | 8 +- | ||
61 | target/riscv/translate.c | 4 +- | ||
62 | target/riscv/vcrypto_helper.c | 32 ++--- | ||
63 | target/riscv/vector_helper.c | 186 ++++++++++++++------------ | ||
64 | target/riscv/vector_internals.c | 4 +- | ||
65 | target/riscv/insn_trans/trans_rvi.c.inc | 8 +- | ||
66 | target/riscv/insn_trans/trans_rvzicfiss.c.inc | 17 +++ | ||
67 | 14 files changed, 214 insertions(+), 143 deletions(-) | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Santiago Monserrat Campanello <santimonserr@gmail.com> | ||
1 | 2 | ||
3 | semihosting link to risc-v changed | ||
4 | |||
5 | Signed-off-by: Santiago Monserrat Campanello <santimonserr@gmail.com> | ||
6 | Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2717 | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Reviewed-by: Thomas Huth <thuth@redhat.com> | ||
9 | Message-ID: <20250305102632.91376-1-santimonserr@gmail.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | docs/about/emulation.rst | 2 +- | ||
13 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
14 | |||
15 | diff --git a/docs/about/emulation.rst b/docs/about/emulation.rst | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/docs/about/emulation.rst | ||
18 | +++ b/docs/about/emulation.rst | ||
19 | @@ -XXX,XX +XXX,XX @@ for that architecture. | ||
20 | - Unified Hosting Interface (MD01069) | ||
21 | * - RISC-V | ||
22 | - System and User-mode | ||
23 | - - https://github.com/riscv/riscv-semihosting-spec/blob/main/riscv-semihosting-spec.adoc | ||
24 | + - https://github.com/riscv-non-isa/riscv-semihosting/blob/main/riscv-semihosting.adoc | ||
25 | * - Xtensa | ||
26 | - System | ||
27 | - Tensilica ISS SIMCALL | ||
28 | -- | ||
29 | 2.48.1 | diff view generated by jsdifflib |
1 | From: Philippe Mathieu-Daudé <f4bug@amsat.org> | 1 | From: Paolo Savini <paolo.savini@embecosm.com> |
---|---|---|---|
2 | 2 | ||
3 | Once a "One Time Programmable" is programmed, it shouldn't be reset. | 3 | Fault-only-first loads in the RISC-V vector extension need to update |
4 | the vl with the element index that causes an exception. | ||
5 | In order to ensure this the emulation of this instruction used to probe the | ||
6 | memory covered by the load operation with a loop that iterated over each element | ||
7 | so that when a flag was raised it was possible to set the vl to the | ||
8 | corresponding element index. | ||
9 | This loop was executed every time whether an exception happened or not. | ||
4 | 10 | ||
5 | Do not re-initialize the OTP content in the DeviceReset handler, | 11 | This commit removes the per element memory probing from the main execution path |
6 | initialize it once in the DeviceRealize one. | 12 | and adds a broad memory probing first. If this probing raises any flag that is |
13 | not a watchpoint flag (that per standard is allowed by this instruction) we | ||
14 | proceed with the per element probing to find the index of the element causing | ||
15 | the exception and set vl to such index. | ||
7 | 16 | ||
8 | Fixes: 9fb45c62ae8 ("riscv: sifive: Implement a model for SiFive FU540 OTP") | 17 | Signed-off-by: Paolo Savini <paolo.savini@embecosm.com> |
9 | Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 18 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 19 | Message-ID: <20250221155320.59159-2-paolo.savini@embecosm.com> |
11 | Message-Id: <20211119104757.331579-1-f4bug@amsat.org> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 20 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
13 | --- | 21 | --- |
14 | hw/misc/sifive_u_otp.c | 13 +++++-------- | 22 | target/riscv/vector_helper.c | 103 ++++++++++++++++++++--------------- |
15 | 1 file changed, 5 insertions(+), 8 deletions(-) | 23 | 1 file changed, 58 insertions(+), 45 deletions(-) |
16 | 24 | ||
17 | diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c | 25 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c |
18 | index XXXXXXX..XXXXXXX 100644 | 26 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/hw/misc/sifive_u_otp.c | 27 | --- a/target/riscv/vector_helper.c |
20 | +++ b/hw/misc/sifive_u_otp.c | 28 | +++ b/target/riscv/vector_helper.c |
21 | @@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp) | 29 | @@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base, CPURISCVState *env, |
22 | 30 | uint32_t esz = 1 << log2_esz; | |
23 | if (blk_pread(s->blk, 0, s->fuse, filesize) != filesize) { | 31 | uint32_t msize = nf * esz; |
24 | error_setg(errp, "failed to read the initial flash content"); | 32 | uint32_t vma = vext_vma(desc); |
25 | + return; | 33 | - target_ulong addr, offset, remain, page_split, elems; |
34 | + target_ulong addr, addr_probe, addr_i, offset, remain, page_split, elems; | ||
35 | int mmu_index = riscv_env_mmu_index(env, false); | ||
36 | + int flags; | ||
37 | + void *host; | ||
38 | |||
39 | VSTART_CHECK_EARLY_EXIT(env); | ||
40 | |||
41 | - /* probe every access */ | ||
42 | - for (i = env->vstart; i < env->vl; i++) { | ||
43 | - if (!vm && !vext_elem_mask(v0, i)) { | ||
44 | - continue; | ||
45 | - } | ||
46 | - addr = adjust_addr(env, base + i * (nf << log2_esz)); | ||
47 | - if (i == 0) { | ||
48 | - /* Allow fault on first element. */ | ||
49 | - probe_pages(env, addr, nf << log2_esz, ra, MMU_DATA_LOAD); | ||
50 | - } else { | ||
51 | - remain = nf << log2_esz; | ||
52 | - while (remain > 0) { | ||
53 | - void *host; | ||
54 | - int flags; | ||
55 | - | ||
56 | - offset = -(addr | TARGET_PAGE_MASK); | ||
57 | - | ||
58 | - /* Probe nonfault on subsequent elements. */ | ||
59 | - flags = probe_access_flags(env, addr, offset, MMU_DATA_LOAD, | ||
60 | - mmu_index, true, &host, 0); | ||
61 | - | ||
62 | - /* | ||
63 | - * Stop if invalid (unmapped) or mmio (transaction may fail). | ||
64 | - * Do not stop if watchpoint, as the spec says that | ||
65 | - * first-fault should continue to access the same | ||
66 | - * elements regardless of any watchpoint. | ||
67 | - */ | ||
68 | - if (flags & ~TLB_WATCHPOINT) { | ||
69 | - vl = i; | ||
70 | - goto ProbeSuccess; | ||
71 | - } | ||
72 | - if (remain <= offset) { | ||
73 | - break; | ||
74 | + addr = base + ((env->vstart * nf) << log2_esz); | ||
75 | + page_split = -(addr | TARGET_PAGE_MASK); | ||
76 | + /* Get number of elements */ | ||
77 | + elems = page_split / msize; | ||
78 | + if (unlikely(env->vstart + elems >= env->vl)) { | ||
79 | + elems = env->vl - env->vstart; | ||
80 | + } | ||
81 | + | ||
82 | + /* Check page permission/pmp/watchpoint/etc. */ | ||
83 | + flags = probe_access_flags(env, adjust_addr(env, addr), elems * msize, | ||
84 | + MMU_DATA_LOAD, mmu_index, true, &host, ra); | ||
85 | + | ||
86 | + /* If we are crossing a page check also the second page. */ | ||
87 | + if (env->vl > elems) { | ||
88 | + addr_probe = addr + (elems << log2_esz); | ||
89 | + flags |= probe_access_flags(env, adjust_addr(env, addr_probe), | ||
90 | + elems * msize, MMU_DATA_LOAD, mmu_index, | ||
91 | + true, &host, ra); | ||
92 | + } | ||
93 | + | ||
94 | + if (flags & ~TLB_WATCHPOINT) { | ||
95 | + /* probe every access */ | ||
96 | + for (i = env->vstart; i < env->vl; i++) { | ||
97 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
98 | + continue; | ||
99 | + } | ||
100 | + addr_i = adjust_addr(env, base + i * (nf << log2_esz)); | ||
101 | + if (i == 0) { | ||
102 | + /* Allow fault on first element. */ | ||
103 | + probe_pages(env, addr_i, nf << log2_esz, ra, MMU_DATA_LOAD); | ||
104 | + } else { | ||
105 | + remain = nf << log2_esz; | ||
106 | + while (remain > 0) { | ||
107 | + offset = -(addr_i | TARGET_PAGE_MASK); | ||
108 | + | ||
109 | + /* Probe nonfault on subsequent elements. */ | ||
110 | + flags = probe_access_flags(env, addr_i, offset, | ||
111 | + MMU_DATA_LOAD, mmu_index, true, | ||
112 | + &host, 0); | ||
113 | + | ||
114 | + /* | ||
115 | + * Stop if invalid (unmapped) or mmio (transaction may | ||
116 | + * fail). Do not stop if watchpoint, as the spec says that | ||
117 | + * first-fault should continue to access the same | ||
118 | + * elements regardless of any watchpoint. | ||
119 | + */ | ||
120 | + if (flags & ~TLB_WATCHPOINT) { | ||
121 | + vl = i; | ||
122 | + goto ProbeSuccess; | ||
123 | + } | ||
124 | + if (remain <= offset) { | ||
125 | + break; | ||
126 | + } | ||
127 | + remain -= offset; | ||
128 | + addr_i = adjust_addr(env, addr_i + offset); | ||
129 | } | ||
130 | - remain -= offset; | ||
131 | - addr = adjust_addr(env, addr + offset); | ||
26 | } | 132 | } |
27 | } | 133 | } |
28 | } | 134 | } |
29 | -} | 135 | @@ -XXX,XX +XXX,XX @@ ProbeSuccess: |
136 | |||
137 | if (env->vstart < env->vl) { | ||
138 | if (vm) { | ||
139 | - /* Calculate the page range of first page */ | ||
140 | - addr = base + ((env->vstart * nf) << log2_esz); | ||
141 | - page_split = -(addr | TARGET_PAGE_MASK); | ||
142 | - /* Get number of elements */ | ||
143 | - elems = page_split / msize; | ||
144 | - if (unlikely(env->vstart + elems >= env->vl)) { | ||
145 | - elems = env->vl - env->vstart; | ||
146 | - } | ||
30 | - | 147 | - |
31 | -static void sifive_u_otp_reset(DeviceState *dev) | 148 | /* Load/store elements in the first page */ |
32 | -{ | 149 | if (likely(elems)) { |
33 | - SiFiveUOTPState *s = SIFIVE_U_OTP(dev); | 150 | vext_page_ldst_us(env, vd, addr, elems, nf, max_elems, |
34 | |||
35 | /* Initialize all fuses' initial value to 0xFFs */ | ||
36 | memset(s->fuse, 0xff, sizeof(s->fuse)); | ||
37 | @@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_reset(DeviceState *dev) | ||
38 | serial_data = s->serial; | ||
39 | if (blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD, | ||
40 | &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) { | ||
41 | - error_report("write error index<%d>", index); | ||
42 | + error_setg(errp, "failed to write index<%d>", index); | ||
43 | + return; | ||
44 | } | ||
45 | |||
46 | serial_data = ~(s->serial); | ||
47 | if (blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD, | ||
48 | &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) { | ||
49 | - error_report("write error index<%d>", index + 1); | ||
50 | + error_setg(errp, "failed to write index<%d>", index + 1); | ||
51 | + return; | ||
52 | } | ||
53 | } | ||
54 | |||
55 | @@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_class_init(ObjectClass *klass, void *data) | ||
56 | |||
57 | device_class_set_props(dc, sifive_u_otp_properties); | ||
58 | dc->realize = sifive_u_otp_realize; | ||
59 | - dc->reset = sifive_u_otp_reset; | ||
60 | } | ||
61 | |||
62 | static const TypeInfo sifive_u_otp_info = { | ||
63 | -- | 151 | -- |
64 | 2.31.1 | 152 | 2.48.1 |
65 | |||
66 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Deepak Gupta <debug@rivosinc.com> | ||
1 | 2 | ||
3 | Commit:8205bc1 ("target/riscv: introduce ssp and enabling controls for | ||
4 | zicfiss") introduced CSR_SSP but it mis-interpreted the spec on access | ||
5 | to CSR_SSP in M-mode. Gated to CSR_SSP is not gated via `xSSE`. But | ||
6 | rather rules clearly specified in section "22.2.1. Shadow Stack Pointer | ||
7 | (ssp) CSR access contr" in the priv spec. | ||
8 | |||
9 | Fixes: 8205bc127a83 ("target/riscv: introduce ssp and enabling controls | ||
10 | for zicfiss". Thanks to Adam Zabrocki for bringing this to attention. | ||
11 | |||
12 | Reported-by: Adam Zabrocki <azabrocki@nvidia.com> | ||
13 | Signed-off-by: Deepak Gupta <debug@rivosinc.com> | ||
14 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | Message-ID: <20250306064636.452396-1-debug@rivosinc.com> | ||
16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
17 | --- | ||
18 | target/riscv/csr.c | 5 +++++ | ||
19 | 1 file changed, 5 insertions(+) | ||
20 | |||
21 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/target/riscv/csr.c | ||
24 | +++ b/target/riscv/csr.c | ||
25 | @@ -XXX,XX +XXX,XX @@ static RISCVException cfi_ss(CPURISCVState *env, int csrno) | ||
26 | return RISCV_EXCP_ILLEGAL_INST; | ||
27 | } | ||
28 | |||
29 | + /* If ext implemented, M-mode always have access to SSP CSR */ | ||
30 | + if (env->priv == PRV_M) { | ||
31 | + return RISCV_EXCP_NONE; | ||
32 | + } | ||
33 | + | ||
34 | /* if bcfi not active for current env, access to csr is illegal */ | ||
35 | if (!cpu_get_bcfien(env)) { | ||
36 | #if !defined(CONFIG_USER_ONLY) | ||
37 | -- | ||
38 | 2.48.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Deepak Gupta <debug@rivosinc.com> | ||
1 | 2 | ||
3 | Commit f06bfe3dc38c ("target/riscv: implement zicfiss instructions") adds | ||
4 | `ssamoswap` instruction. `ssamoswap` takes the code-point from existing | ||
5 | reserved encoding (and not a zimop like other shadow stack instructions). | ||
6 | If shadow stack is not enabled (via xenvcfg.SSE) and effective priv is | ||
7 | less than M then `ssamoswap` must result in an illegal instruction | ||
8 | exception. However if effective priv is M, then `ssamoswap` results in | ||
9 | store/AMO access fault. See Section "22.2.3. Shadow Stack Memory | ||
10 | Protection" of priv spec. | ||
11 | |||
12 | Fixes: f06bfe3dc38c ("target/riscv: implement zicfiss instructions") | ||
13 | |||
14 | Reported-by: Ved Shanbhogue <ved@rivosinc.com> | ||
15 | Signed-off-by: Deepak Gupta <debug@rivosinc.com> | ||
16 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
17 | Message-ID: <20250306064636.452396-2-debug@rivosinc.com> | ||
18 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
19 | --- | ||
20 | target/riscv/insn_trans/trans_rvzicfiss.c.inc | 17 +++++++++++++++++ | ||
21 | 1 file changed, 17 insertions(+) | ||
22 | |||
23 | diff --git a/target/riscv/insn_trans/trans_rvzicfiss.c.inc b/target/riscv/insn_trans/trans_rvzicfiss.c.inc | ||
24 | index XXXXXXX..XXXXXXX 100644 | ||
25 | --- a/target/riscv/insn_trans/trans_rvzicfiss.c.inc | ||
26 | +++ b/target/riscv/insn_trans/trans_rvzicfiss.c.inc | ||
27 | @@ -XXX,XX +XXX,XX @@ | ||
28 | * You should have received a copy of the GNU General Public License along with | ||
29 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
30 | */ | ||
31 | + | ||
32 | +#define REQUIRE_ZICFISS(ctx) do { \ | ||
33 | + if (!ctx->cfg_ptr->ext_zicfiss) { \ | ||
34 | + return false; \ | ||
35 | + } \ | ||
36 | +} while (0) | ||
37 | + | ||
38 | static bool trans_sspopchk(DisasContext *ctx, arg_sspopchk *a) | ||
39 | { | ||
40 | if (!ctx->bcfi_enabled) { | ||
41 | @@ -XXX,XX +XXX,XX @@ static bool trans_ssrdp(DisasContext *ctx, arg_ssrdp *a) | ||
42 | static bool trans_ssamoswap_w(DisasContext *ctx, arg_amoswap_w *a) | ||
43 | { | ||
44 | REQUIRE_A_OR_ZAAMO(ctx); | ||
45 | + REQUIRE_ZICFISS(ctx); | ||
46 | + if (ctx->priv == PRV_M) { | ||
47 | + generate_exception(ctx, RISCV_EXCP_STORE_AMO_ACCESS_FAULT); | ||
48 | + } | ||
49 | + | ||
50 | if (!ctx->bcfi_enabled) { | ||
51 | return false; | ||
52 | } | ||
53 | @@ -XXX,XX +XXX,XX @@ static bool trans_ssamoswap_d(DisasContext *ctx, arg_amoswap_w *a) | ||
54 | { | ||
55 | REQUIRE_64BIT(ctx); | ||
56 | REQUIRE_A_OR_ZAAMO(ctx); | ||
57 | + REQUIRE_ZICFISS(ctx); | ||
58 | + if (ctx->priv == PRV_M) { | ||
59 | + generate_exception(ctx, RISCV_EXCP_STORE_AMO_ACCESS_FAULT); | ||
60 | + } | ||
61 | + | ||
62 | if (!ctx->bcfi_enabled) { | ||
63 | return false; | ||
64 | } | ||
65 | -- | ||
66 | 2.48.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Jason Chien <jason.chien@sifive.com> | ||
1 | 2 | ||
3 | The PPN field in a non-leaf PDT entry is positioned differently from that | ||
4 | in a leaf PDT entry. The original implementation incorrectly used the leaf | ||
5 | entry's PPN mask to extract the PPN from a non-leaf entry, leading to an | ||
6 | erroneous page table walk. | ||
7 | |||
8 | This commit introduces new macros to properly define the fields for | ||
9 | non-leaf PDT entries and corrects the page table walk. | ||
10 | |||
11 | Signed-off-by: Jason Chien <jason.chien@sifive.com> | ||
12 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
13 | Message-ID: <20250301173751.9446-1-jason.chien@sifive.com> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | --- | ||
16 | hw/riscv/riscv-iommu-bits.h | 6 +++++- | ||
17 | hw/riscv/riscv-iommu.c | 4 ++-- | ||
18 | 2 files changed, 7 insertions(+), 3 deletions(-) | ||
19 | |||
20 | diff --git a/hw/riscv/riscv-iommu-bits.h b/hw/riscv/riscv-iommu-bits.h | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/hw/riscv/riscv-iommu-bits.h | ||
23 | +++ b/hw/riscv/riscv-iommu-bits.h | ||
24 | @@ -XXX,XX +XXX,XX @@ enum riscv_iommu_fq_causes { | ||
25 | #define RISCV_IOMMU_DC_MSIPTP_MODE_OFF 0 | ||
26 | #define RISCV_IOMMU_DC_MSIPTP_MODE_FLAT 1 | ||
27 | |||
28 | +/* 2.2 Process Directory Table */ | ||
29 | +#define RISCV_IOMMU_PDTE_VALID BIT_ULL(0) | ||
30 | +#define RISCV_IOMMU_PDTE_PPN RISCV_IOMMU_PPN_FIELD | ||
31 | + | ||
32 | /* Translation attributes fields */ | ||
33 | #define RISCV_IOMMU_PC_TA_V BIT_ULL(0) | ||
34 | #define RISCV_IOMMU_PC_TA_RESERVED GENMASK_ULL(63, 32) | ||
35 | |||
36 | /* First stage context fields */ | ||
37 | -#define RISCV_IOMMU_PC_FSC_PPN GENMASK_ULL(43, 0) | ||
38 | +#define RISCV_IOMMU_PC_FSC_PPN RISCV_IOMMU_ATP_PPN_FIELD | ||
39 | #define RISCV_IOMMU_PC_FSC_RESERVED GENMASK_ULL(59, 44) | ||
40 | |||
41 | enum riscv_iommu_fq_ttypes { | ||
42 | diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c | ||
43 | index XXXXXXX..XXXXXXX 100644 | ||
44 | --- a/hw/riscv/riscv-iommu.c | ||
45 | +++ b/hw/riscv/riscv-iommu.c | ||
46 | @@ -XXX,XX +XXX,XX @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx) | ||
47 | return RISCV_IOMMU_FQ_CAUSE_PDT_LOAD_FAULT; | ||
48 | } | ||
49 | le64_to_cpus(&de); | ||
50 | - if (!(de & RISCV_IOMMU_PC_TA_V)) { | ||
51 | + if (!(de & RISCV_IOMMU_PDTE_VALID)) { | ||
52 | return RISCV_IOMMU_FQ_CAUSE_PDT_INVALID; | ||
53 | } | ||
54 | - addr = PPN_PHYS(get_field(de, RISCV_IOMMU_PC_FSC_PPN)); | ||
55 | + addr = PPN_PHYS(get_field(de, RISCV_IOMMU_PDTE_PPN)); | ||
56 | } | ||
57 | |||
58 | riscv_iommu_hpm_incr_ctr(s, ctx, RISCV_IOMMU_HPMEVENT_PD_WALK); | ||
59 | -- | ||
60 | 2.48.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
1 | 2 | ||
3 | Coverity found the following issue: | ||
4 | |||
5 | >>> CID 1593156: Integer handling issues (OVERFLOW_BEFORE_WIDEN) | ||
6 | >>> Potentially overflowing expression "0x10 << depth" with type | ||
7 | "int" (32 bits, signed) is evaluated using 32-bit arithmetic, and then | ||
8 | used in a context that expects an expression of type "uint64_t" (64 | ||
9 | bits, unsigned). | ||
10 | 4299 depth = 16 << depth; | ||
11 | |||
12 | Fix it by forcing the expression to be 64 bits wide by using '16ULL'. | ||
13 | |||
14 | Resolves: Coverity CID 1593156 | ||
15 | Fixes: c48bd18eae ("target/riscv: Add support for Control Transfer Records extension CSRs.") | ||
16 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
17 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
18 | Message-ID: <20250307124602.1905754-1-dbarboza@ventanamicro.com> | ||
19 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
20 | --- | ||
21 | target/riscv/csr.c | 2 +- | ||
22 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
23 | |||
24 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
25 | index XXXXXXX..XXXXXXX 100644 | ||
26 | --- a/target/riscv/csr.c | ||
27 | +++ b/target/riscv/csr.c | ||
28 | @@ -XXX,XX +XXX,XX @@ static RISCVException rmw_sctrdepth(CPURISCVState *env, int csrno, | ||
29 | } | ||
30 | |||
31 | /* Update sctrstatus.WRPTR with a legal value */ | ||
32 | - depth = 16 << depth; | ||
33 | + depth = 16ULL << depth; | ||
34 | env->sctrstatus = | ||
35 | env->sctrstatus & (~SCTRSTATUS_WRPTR_MASK | (depth - 1)); | ||
36 | } | ||
37 | -- | ||
38 | 2.48.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Chao Liu <lc00631@tecorigin.com> | ||
1 | 2 | ||
3 | Some vector instructions are special, such as the vlm.v instruction, | ||
4 | where setting its vl actually sets evl = (vl + 7) >> 3. To improve | ||
5 | maintainability, we will uniformly use VSTART_CHECK_EARLY_EXIT() to | ||
6 | check for the condition vstart >= vl. This function will also handle | ||
7 | cases involving evl. | ||
8 | |||
9 | Fixes: df4252b2ec ("target/riscv/vector_helpers: do early exit when | ||
10 | vstart >= vl") | ||
11 | Signed-off-by: Chao Liu <lc00631@tecorigin.com> | ||
12 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
13 | Message-ID: <f575979874e323a9e0da7796aa391c7d87e56f88.1741573286.git.lc00631@tecorigin.com> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | --- | ||
16 | target/riscv/vector_internals.h | 12 +++--- | ||
17 | target/riscv/vcrypto_helper.c | 32 +++++++-------- | ||
18 | target/riscv/vector_helper.c | 69 ++++++++++++++++----------------- | ||
19 | target/riscv/vector_internals.c | 4 +- | ||
20 | 4 files changed, 57 insertions(+), 60 deletions(-) | ||
21 | |||
22 | diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h | ||
23 | index XXXXXXX..XXXXXXX 100644 | ||
24 | --- a/target/riscv/vector_internals.h | ||
25 | +++ b/target/riscv/vector_internals.h | ||
26 | @@ -XXX,XX +XXX,XX @@ | ||
27 | #include "tcg/tcg-gvec-desc.h" | ||
28 | #include "internals.h" | ||
29 | |||
30 | -#define VSTART_CHECK_EARLY_EXIT(env) do { \ | ||
31 | - if (env->vstart >= env->vl) { \ | ||
32 | - env->vstart = 0; \ | ||
33 | - return; \ | ||
34 | - } \ | ||
35 | +#define VSTART_CHECK_EARLY_EXIT(env, vl) do { \ | ||
36 | + if (env->vstart >= vl) { \ | ||
37 | + env->vstart = 0; \ | ||
38 | + return; \ | ||
39 | + } \ | ||
40 | } while (0) | ||
41 | |||
42 | static inline uint32_t vext_nf(uint32_t desc) | ||
43 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
44 | uint32_t vma = vext_vma(desc); \ | ||
45 | uint32_t i; \ | ||
46 | \ | ||
47 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
48 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
49 | \ | ||
50 | for (i = env->vstart; i < vl; i++) { \ | ||
51 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
52 | diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c | ||
53 | index XXXXXXX..XXXXXXX 100644 | ||
54 | --- a/target/riscv/vcrypto_helper.c | ||
55 | +++ b/target/riscv/vcrypto_helper.c | ||
56 | @@ -XXX,XX +XXX,XX @@ static inline void xor_round_key(AESState *round_state, AESState *round_key) | ||
57 | uint32_t total_elems = vext_get_total_elems(env, desc, 4); \ | ||
58 | uint32_t vta = vext_vta(desc); \ | ||
59 | \ | ||
60 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
61 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
62 | \ | ||
63 | for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \ | ||
64 | AESState round_key; \ | ||
65 | @@ -XXX,XX +XXX,XX @@ static inline void xor_round_key(AESState *round_state, AESState *round_key) | ||
66 | uint32_t total_elems = vext_get_total_elems(env, desc, 4); \ | ||
67 | uint32_t vta = vext_vta(desc); \ | ||
68 | \ | ||
69 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
70 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
71 | \ | ||
72 | for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \ | ||
73 | AESState round_key; \ | ||
74 | @@ -XXX,XX +XXX,XX @@ void HELPER(vaeskf1_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm, | ||
75 | uint32_t total_elems = vext_get_total_elems(env, desc, 4); | ||
76 | uint32_t vta = vext_vta(desc); | ||
77 | |||
78 | - VSTART_CHECK_EARLY_EXIT(env); | ||
79 | + VSTART_CHECK_EARLY_EXIT(env, vl); | ||
80 | |||
81 | uimm &= 0b1111; | ||
82 | if (uimm > 10 || uimm == 0) { | ||
83 | @@ -XXX,XX +XXX,XX @@ void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm, | ||
84 | uint32_t total_elems = vext_get_total_elems(env, desc, 4); | ||
85 | uint32_t vta = vext_vta(desc); | ||
86 | |||
87 | - VSTART_CHECK_EARLY_EXIT(env); | ||
88 | + VSTART_CHECK_EARLY_EXIT(env, vl); | ||
89 | |||
90 | uimm &= 0b1111; | ||
91 | if (uimm > 14 || uimm < 2) { | ||
92 | @@ -XXX,XX +XXX,XX @@ void HELPER(vsha2ms_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env, | ||
93 | uint32_t total_elems; | ||
94 | uint32_t vta = vext_vta(desc); | ||
95 | |||
96 | - VSTART_CHECK_EARLY_EXIT(env); | ||
97 | + VSTART_CHECK_EARLY_EXIT(env, env->vl); | ||
98 | |||
99 | for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { | ||
100 | if (sew == MO_32) { | ||
101 | @@ -XXX,XX +XXX,XX @@ void HELPER(vsha2ch32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env, | ||
102 | uint32_t total_elems; | ||
103 | uint32_t vta = vext_vta(desc); | ||
104 | |||
105 | - VSTART_CHECK_EARLY_EXIT(env); | ||
106 | + VSTART_CHECK_EARLY_EXIT(env, env->vl); | ||
107 | |||
108 | for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { | ||
109 | vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i, | ||
110 | @@ -XXX,XX +XXX,XX @@ void HELPER(vsha2ch64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env, | ||
111 | uint32_t total_elems; | ||
112 | uint32_t vta = vext_vta(desc); | ||
113 | |||
114 | - VSTART_CHECK_EARLY_EXIT(env); | ||
115 | + VSTART_CHECK_EARLY_EXIT(env, env->vl); | ||
116 | |||
117 | for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { | ||
118 | vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i, | ||
119 | @@ -XXX,XX +XXX,XX @@ void HELPER(vsha2cl32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env, | ||
120 | uint32_t total_elems; | ||
121 | uint32_t vta = vext_vta(desc); | ||
122 | |||
123 | - VSTART_CHECK_EARLY_EXIT(env); | ||
124 | + VSTART_CHECK_EARLY_EXIT(env, env->vl); | ||
125 | |||
126 | for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { | ||
127 | vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i, | ||
128 | @@ -XXX,XX +XXX,XX @@ void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env, | ||
129 | uint32_t total_elems; | ||
130 | uint32_t vta = vext_vta(desc); | ||
131 | |||
132 | - VSTART_CHECK_EARLY_EXIT(env); | ||
133 | + VSTART_CHECK_EARLY_EXIT(env, env->vl); | ||
134 | |||
135 | for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { | ||
136 | vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i, | ||
137 | @@ -XXX,XX +XXX,XX @@ void HELPER(vsm3me_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr, | ||
138 | uint32_t *vs1 = vs1_vptr; | ||
139 | uint32_t *vs2 = vs2_vptr; | ||
140 | |||
141 | - VSTART_CHECK_EARLY_EXIT(env); | ||
142 | + VSTART_CHECK_EARLY_EXIT(env, env->vl); | ||
143 | |||
144 | for (int i = env->vstart / 8; i < env->vl / 8; i++) { | ||
145 | uint32_t w[24]; | ||
146 | @@ -XXX,XX +XXX,XX @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm, | ||
147 | uint32_t *vs2 = vs2_vptr; | ||
148 | uint32_t v1[8], v2[8], v3[8]; | ||
149 | |||
150 | - VSTART_CHECK_EARLY_EXIT(env); | ||
151 | + VSTART_CHECK_EARLY_EXIT(env, env->vl); | ||
152 | |||
153 | for (int i = env->vstart / 8; i < env->vl / 8; i++) { | ||
154 | for (int k = 0; k < 8; k++) { | ||
155 | @@ -XXX,XX +XXX,XX @@ void HELPER(vghsh_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr, | ||
156 | uint32_t vta = vext_vta(desc); | ||
157 | uint32_t total_elems = vext_get_total_elems(env, desc, 4); | ||
158 | |||
159 | - VSTART_CHECK_EARLY_EXIT(env); | ||
160 | + VSTART_CHECK_EARLY_EXIT(env, env->vl); | ||
161 | |||
162 | for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { | ||
163 | uint64_t Y[2] = {vd[i * 2 + 0], vd[i * 2 + 1]}; | ||
164 | @@ -XXX,XX +XXX,XX @@ void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env, | ||
165 | uint32_t vta = vext_vta(desc); | ||
166 | uint32_t total_elems = vext_get_total_elems(env, desc, 4); | ||
167 | |||
168 | - VSTART_CHECK_EARLY_EXIT(env); | ||
169 | + VSTART_CHECK_EARLY_EXIT(env, env->vl); | ||
170 | |||
171 | for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { | ||
172 | uint64_t Y[2] = {brev8(vd[i * 2 + 0]), brev8(vd[i * 2 + 1])}; | ||
173 | @@ -XXX,XX +XXX,XX @@ void HELPER(vsm4k_vi)(void *vd, void *vs2, uint32_t uimm5, CPURISCVState *env, | ||
174 | uint32_t esz = sizeof(uint32_t); | ||
175 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
176 | |||
177 | - VSTART_CHECK_EARLY_EXIT(env); | ||
178 | + VSTART_CHECK_EARLY_EXIT(env, env->vl); | ||
179 | |||
180 | for (uint32_t i = group_start; i < group_end; ++i) { | ||
181 | uint32_t vstart = i * egs; | ||
182 | @@ -XXX,XX +XXX,XX @@ void HELPER(vsm4r_vv)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc) | ||
183 | uint32_t esz = sizeof(uint32_t); | ||
184 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
185 | |||
186 | - VSTART_CHECK_EARLY_EXIT(env); | ||
187 | + VSTART_CHECK_EARLY_EXIT(env, env->vl); | ||
188 | |||
189 | for (uint32_t i = group_start; i < group_end; ++i) { | ||
190 | uint32_t vstart = i * egs; | ||
191 | @@ -XXX,XX +XXX,XX @@ void HELPER(vsm4r_vs)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc) | ||
192 | uint32_t esz = sizeof(uint32_t); | ||
193 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
194 | |||
195 | - VSTART_CHECK_EARLY_EXIT(env); | ||
196 | + VSTART_CHECK_EARLY_EXIT(env, env->vl); | ||
197 | |||
198 | for (uint32_t i = group_start; i < group_end; ++i) { | ||
199 | uint32_t vstart = i * egs; | ||
200 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
201 | index XXXXXXX..XXXXXXX 100644 | ||
202 | --- a/target/riscv/vector_helper.c | ||
203 | +++ b/target/riscv/vector_helper.c | ||
204 | @@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base, target_ulong stride, | ||
205 | uint32_t esz = 1 << log2_esz; | ||
206 | uint32_t vma = vext_vma(desc); | ||
207 | |||
208 | - VSTART_CHECK_EARLY_EXIT(env); | ||
209 | + VSTART_CHECK_EARLY_EXIT(env, env->vl); | ||
210 | |||
211 | for (i = env->vstart; i < env->vl; env->vstart = ++i) { | ||
212 | k = 0; | ||
213 | @@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, | ||
214 | uint32_t msize = nf * esz; | ||
215 | int mmu_index = riscv_env_mmu_index(env, false); | ||
216 | |||
217 | - if (env->vstart >= evl) { | ||
218 | - env->vstart = 0; | ||
219 | - return; | ||
220 | - } | ||
221 | + VSTART_CHECK_EARLY_EXIT(env, evl); | ||
222 | |||
223 | #if defined(CONFIG_USER_ONLY) | ||
224 | /* | ||
225 | @@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base, | ||
226 | uint32_t esz = 1 << log2_esz; | ||
227 | uint32_t vma = vext_vma(desc); | ||
228 | |||
229 | - VSTART_CHECK_EARLY_EXIT(env); | ||
230 | + VSTART_CHECK_EARLY_EXIT(env, env->vl); | ||
231 | |||
232 | /* load bytes from guest memory */ | ||
233 | for (i = env->vstart; i < env->vl; env->vstart = ++i) { | ||
234 | @@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base, CPURISCVState *env, | ||
235 | int flags; | ||
236 | void *host; | ||
237 | |||
238 | - VSTART_CHECK_EARLY_EXIT(env); | ||
239 | + VSTART_CHECK_EARLY_EXIT(env, env->vl); | ||
240 | |||
241 | addr = base + ((env->vstart * nf) << log2_esz); | ||
242 | page_split = -(addr | TARGET_PAGE_MASK); | ||
243 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
244 | uint32_t vta = vext_vta(desc); \ | ||
245 | uint32_t i; \ | ||
246 | \ | ||
247 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
248 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
249 | \ | ||
250 | for (i = env->vstart; i < vl; i++) { \ | ||
251 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
252 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
253 | uint32_t vta = vext_vta(desc); \ | ||
254 | uint32_t i; \ | ||
255 | \ | ||
256 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
257 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
258 | \ | ||
259 | for (i = env->vstart; i < vl; i++) { \ | ||
260 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
261 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
262 | uint32_t vta_all_1s = vext_vta_all_1s(desc); \ | ||
263 | uint32_t i; \ | ||
264 | \ | ||
265 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
266 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
267 | \ | ||
268 | for (i = env->vstart; i < vl; i++) { \ | ||
269 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
270 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
271 | uint32_t vta_all_1s = vext_vta_all_1s(desc); \ | ||
272 | uint32_t i; \ | ||
273 | \ | ||
274 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
275 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
276 | \ | ||
277 | for (i = env->vstart; i < vl; i++) { \ | ||
278 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
279 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
280 | uint32_t vma = vext_vma(desc); \ | ||
281 | uint32_t i; \ | ||
282 | \ | ||
283 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
284 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
285 | \ | ||
286 | for (i = env->vstart; i < vl; i++) { \ | ||
287 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
288 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
289 | uint32_t vma = vext_vma(desc); \ | ||
290 | uint32_t i; \ | ||
291 | \ | ||
292 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
293 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
294 | \ | ||
295 | for (i = env->vstart; i < vl; i++) { \ | ||
296 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
297 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
298 | uint32_t vma = vext_vma(desc); \ | ||
299 | uint32_t i; \ | ||
300 | \ | ||
301 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
302 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
303 | \ | ||
304 | for (i = env->vstart; i < vl; i++) { \ | ||
305 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
306 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
307 | uint32_t vma = vext_vma(desc); \ | ||
308 | uint32_t i; \ | ||
309 | \ | ||
310 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
311 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
312 | \ | ||
313 | for (i = env->vstart; i < vl; i++) { \ | ||
314 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
315 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vs1, CPURISCVState *env, \ | ||
316 | uint32_t vta = vext_vta(desc); \ | ||
317 | uint32_t i; \ | ||
318 | \ | ||
319 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
320 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
321 | \ | ||
322 | for (i = env->vstart; i < vl; i++) { \ | ||
323 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
324 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, uint64_t s1, CPURISCVState *env, \ | ||
325 | uint32_t vta = vext_vta(desc); \ | ||
326 | uint32_t i; \ | ||
327 | \ | ||
328 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
329 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
330 | \ | ||
331 | for (i = env->vstart; i < vl; i++) { \ | ||
332 | *((ETYPE *)vd + H(i)) = (ETYPE)s1; \ | ||
333 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
334 | uint32_t vta = vext_vta(desc); \ | ||
335 | uint32_t i; \ | ||
336 | \ | ||
337 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
338 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
339 | \ | ||
340 | for (i = env->vstart; i < vl; i++) { \ | ||
341 | ETYPE *vt = (!vext_elem_mask(v0, i) ? vs2 : vs1); \ | ||
342 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
343 | uint32_t vta = vext_vta(desc); \ | ||
344 | uint32_t i; \ | ||
345 | \ | ||
346 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
347 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
348 | \ | ||
349 | for (i = env->vstart; i < vl; i++) { \ | ||
350 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
351 | @@ -XXX,XX +XXX,XX @@ vext_vv_rm_1(void *vd, void *v0, void *vs1, void *vs2, | ||
352 | uint32_t vl, uint32_t vm, int vxrm, | ||
353 | opivv2_rm_fn *fn, uint32_t vma, uint32_t esz) | ||
354 | { | ||
355 | - VSTART_CHECK_EARLY_EXIT(env); | ||
356 | + VSTART_CHECK_EARLY_EXIT(env, vl); | ||
357 | |||
358 | for (uint32_t i = env->vstart; i < vl; i++) { | ||
359 | if (!vm && !vext_elem_mask(v0, i)) { | ||
360 | @@ -XXX,XX +XXX,XX @@ vext_vx_rm_1(void *vd, void *v0, target_long s1, void *vs2, | ||
361 | uint32_t vl, uint32_t vm, int vxrm, | ||
362 | opivx2_rm_fn *fn, uint32_t vma, uint32_t esz) | ||
363 | { | ||
364 | - VSTART_CHECK_EARLY_EXIT(env); | ||
365 | + VSTART_CHECK_EARLY_EXIT(env, vl); | ||
366 | |||
367 | for (uint32_t i = env->vstart; i < vl; i++) { | ||
368 | if (!vm && !vext_elem_mask(v0, i)) { | ||
369 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
370 | uint32_t vma = vext_vma(desc); \ | ||
371 | uint32_t i; \ | ||
372 | \ | ||
373 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
374 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
375 | \ | ||
376 | for (i = env->vstart; i < vl; i++) { \ | ||
377 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
378 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, \ | ||
379 | uint32_t vma = vext_vma(desc); \ | ||
380 | uint32_t i; \ | ||
381 | \ | ||
382 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
383 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
384 | \ | ||
385 | for (i = env->vstart; i < vl; i++) { \ | ||
386 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
387 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
388 | uint32_t vma = vext_vma(desc); \ | ||
389 | uint32_t i; \ | ||
390 | \ | ||
391 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
392 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
393 | \ | ||
394 | if (vl == 0) { \ | ||
395 | return; \ | ||
396 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
397 | uint32_t vma = vext_vma(desc); \ | ||
398 | uint32_t i; \ | ||
399 | \ | ||
400 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
401 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
402 | \ | ||
403 | for (i = env->vstart; i < vl; i++) { \ | ||
404 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
405 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
406 | uint32_t vma = vext_vma(desc); \ | ||
407 | uint32_t i; \ | ||
408 | \ | ||
409 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
410 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
411 | \ | ||
412 | for (i = env->vstart; i < vl; i++) { \ | ||
413 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
414 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
415 | uint32_t vta = vext_vta(desc); \ | ||
416 | uint32_t i; \ | ||
417 | \ | ||
418 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
419 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
420 | \ | ||
421 | for (i = env->vstart; i < vl; i++) { \ | ||
422 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
423 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
424 | uint32_t i; \ | ||
425 | int a, b; \ | ||
426 | \ | ||
427 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
428 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
429 | \ | ||
430 | for (i = env->vstart; i < vl; i++) { \ | ||
431 | a = vext_elem_mask(vs1, i); \ | ||
432 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, CPURISCVState *env, uint32_t desc) \ | ||
433 | uint32_t vma = vext_vma(desc); \ | ||
434 | int i; \ | ||
435 | \ | ||
436 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
437 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
438 | \ | ||
439 | for (i = env->vstart; i < vl; i++) { \ | ||
440 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
441 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
442 | uint32_t vma = vext_vma(desc); \ | ||
443 | target_ulong offset = s1, i_min, i; \ | ||
444 | \ | ||
445 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
446 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
447 | \ | ||
448 | i_min = MAX(env->vstart, offset); \ | ||
449 | for (i = i_min; i < vl; i++) { \ | ||
450 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
451 | uint32_t vma = vext_vma(desc); \ | ||
452 | target_ulong i_max, i_min, i; \ | ||
453 | \ | ||
454 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
455 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
456 | \ | ||
457 | i_min = MIN(s1 < vlmax ? vlmax - s1 : 0, vl); \ | ||
458 | i_max = MAX(i_min, env->vstart); \ | ||
459 | @@ -XXX,XX +XXX,XX @@ static void vslide1up_##BITWIDTH(void *vd, void *v0, uint64_t s1, \ | ||
460 | uint32_t vma = vext_vma(desc); \ | ||
461 | uint32_t i; \ | ||
462 | \ | ||
463 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
464 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
465 | \ | ||
466 | for (i = env->vstart; i < vl; i++) { \ | ||
467 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
468 | @@ -XXX,XX +XXX,XX @@ static void vslide1down_##BITWIDTH(void *vd, void *v0, uint64_t s1, \ | ||
469 | uint32_t vma = vext_vma(desc); \ | ||
470 | uint32_t i; \ | ||
471 | \ | ||
472 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
473 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
474 | \ | ||
475 | for (i = env->vstart; i < vl; i++) { \ | ||
476 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
477 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
478 | uint64_t index; \ | ||
479 | uint32_t i; \ | ||
480 | \ | ||
481 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
482 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
483 | \ | ||
484 | for (i = env->vstart; i < vl; i++) { \ | ||
485 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
486 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
487 | uint64_t index = s1; \ | ||
488 | uint32_t i; \ | ||
489 | \ | ||
490 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
491 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
492 | \ | ||
493 | for (i = env->vstart; i < vl; i++) { \ | ||
494 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
495 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
496 | uint32_t vma = vext_vma(desc); \ | ||
497 | uint32_t i; \ | ||
498 | \ | ||
499 | - VSTART_CHECK_EARLY_EXIT(env); \ | ||
500 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
501 | \ | ||
502 | for (i = env->vstart; i < vl; i++) { \ | ||
503 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
504 | diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c | ||
505 | index XXXXXXX..XXXXXXX 100644 | ||
506 | --- a/target/riscv/vector_internals.c | ||
507 | +++ b/target/riscv/vector_internals.c | ||
508 | @@ -XXX,XX +XXX,XX @@ void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2, | ||
509 | uint32_t vma = vext_vma(desc); | ||
510 | uint32_t i; | ||
511 | |||
512 | - VSTART_CHECK_EARLY_EXIT(env); | ||
513 | + VSTART_CHECK_EARLY_EXIT(env, vl); | ||
514 | |||
515 | for (i = env->vstart; i < vl; i++) { | ||
516 | if (!vm && !vext_elem_mask(v0, i)) { | ||
517 | @@ -XXX,XX +XXX,XX @@ void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2, | ||
518 | uint32_t vma = vext_vma(desc); | ||
519 | uint32_t i; | ||
520 | |||
521 | - VSTART_CHECK_EARLY_EXIT(env); | ||
522 | + VSTART_CHECK_EARLY_EXIT(env, vl); | ||
523 | |||
524 | for (i = env->vstart; i < vl; i++) { | ||
525 | if (!vm && !vext_elem_mask(v0, i)) { | ||
526 | -- | ||
527 | 2.48.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Chao Liu <lc00631@tecorigin.com> | ||
1 | 2 | ||
3 | Recently, when I was writing a RISCV test, I found that when VL is set to 0, the | ||
4 | instruction should be nop, but when I tested it, I found that QEMU will treat | ||
5 | all elements as tail elements, and in the case of VTA=1, write all elements | ||
6 | to 1. | ||
7 | |||
8 | After troubleshooting, it was found that the vext_vx_rm_1 function was called in | ||
9 | the vext_vx_rm_2, and then the vext_set_elems_1s function was called to process | ||
10 | the tail element, but only VSTART >= vl was checked in the vext_vx_rm_1 | ||
11 | function, which caused the tail element to still be processed even if it was | ||
12 | returned in advance. | ||
13 | |||
14 | So I've made the following change: | ||
15 | |||
16 | Put VSTART_CHECK_EARLY_EXIT(env) at the beginning of the vext_vx_rm_2 function, | ||
17 | so that the VSTART register is checked correctly. | ||
18 | |||
19 | Fixes: df4252b2ec ("target/riscv/vector_helpers: do early exit when | ||
20 | vstart >= vl") | ||
21 | Signed-off-by: Chao Liu <lc00631@tecorigin.com> | ||
22 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
23 | Message-ID: <b2649f14915150be4c602d63cd3ea4adf47e9d75.1741573286.git.lc00631@tecorigin.com> | ||
24 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
25 | --- | ||
26 | target/riscv/vector_helper.c | 18 ++++++++++++++---- | ||
27 | 1 file changed, 14 insertions(+), 4 deletions(-) | ||
28 | |||
29 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
30 | index XXXXXXX..XXXXXXX 100644 | ||
31 | --- a/target/riscv/vector_helper.c | ||
32 | +++ b/target/riscv/vector_helper.c | ||
33 | @@ -XXX,XX +XXX,XX @@ vext_vv_rm_1(void *vd, void *v0, void *vs1, void *vs2, | ||
34 | uint32_t vl, uint32_t vm, int vxrm, | ||
35 | opivv2_rm_fn *fn, uint32_t vma, uint32_t esz) | ||
36 | { | ||
37 | - VSTART_CHECK_EARLY_EXIT(env, vl); | ||
38 | - | ||
39 | for (uint32_t i = env->vstart; i < vl; i++) { | ||
40 | if (!vm && !vext_elem_mask(v0, i)) { | ||
41 | /* set masked-off elements to 1s */ | ||
42 | @@ -XXX,XX +XXX,XX @@ vext_vv_rm_2(void *vd, void *v0, void *vs1, void *vs2, | ||
43 | uint32_t vta = vext_vta(desc); | ||
44 | uint32_t vma = vext_vma(desc); | ||
45 | |||
46 | + VSTART_CHECK_EARLY_EXIT(env, vl); | ||
47 | + | ||
48 | switch (env->vxrm) { | ||
49 | case 0: /* rnu */ | ||
50 | vext_vv_rm_1(vd, v0, vs1, vs2, | ||
51 | @@ -XXX,XX +XXX,XX @@ vext_vx_rm_1(void *vd, void *v0, target_long s1, void *vs2, | ||
52 | uint32_t vl, uint32_t vm, int vxrm, | ||
53 | opivx2_rm_fn *fn, uint32_t vma, uint32_t esz) | ||
54 | { | ||
55 | - VSTART_CHECK_EARLY_EXIT(env, vl); | ||
56 | - | ||
57 | for (uint32_t i = env->vstart; i < vl; i++) { | ||
58 | if (!vm && !vext_elem_mask(v0, i)) { | ||
59 | /* set masked-off elements to 1s */ | ||
60 | @@ -XXX,XX +XXX,XX @@ vext_vx_rm_2(void *vd, void *v0, target_long s1, void *vs2, | ||
61 | uint32_t vta = vext_vta(desc); | ||
62 | uint32_t vma = vext_vma(desc); | ||
63 | |||
64 | + VSTART_CHECK_EARLY_EXIT(env, vl); | ||
65 | + | ||
66 | switch (env->vxrm) { | ||
67 | case 0: /* rnu */ | ||
68 | vext_vx_rm_1(vd, v0, s1, vs2, | ||
69 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
70 | uint32_t i; \ | ||
71 | TD s1 = *((TD *)vs1 + HD(0)); \ | ||
72 | \ | ||
73 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
74 | + \ | ||
75 | for (i = env->vstart; i < vl; i++) { \ | ||
76 | TS2 s2 = *((TS2 *)vs2 + HS2(i)); \ | ||
77 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
78 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
79 | uint32_t i; \ | ||
80 | TD s1 = *((TD *)vs1 + HD(0)); \ | ||
81 | \ | ||
82 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
83 | + \ | ||
84 | for (i = env->vstart; i < vl; i++) { \ | ||
85 | TS2 s2 = *((TS2 *)vs2 + HS2(i)); \ | ||
86 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
87 | @@ -XXX,XX +XXX,XX @@ static void vmsetm(void *vd, void *v0, void *vs2, CPURISCVState *env, | ||
88 | int i; | ||
89 | bool first_mask_bit = false; | ||
90 | |||
91 | + VSTART_CHECK_EARLY_EXIT(env, vl); | ||
92 | + | ||
93 | for (i = env->vstart; i < vl; i++) { | ||
94 | if (!vm && !vext_elem_mask(v0, i)) { | ||
95 | /* set masked-off elements to 1s */ | ||
96 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, CPURISCVState *env, \ | ||
97 | uint32_t sum = 0; \ | ||
98 | int i; \ | ||
99 | \ | ||
100 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
101 | + \ | ||
102 | for (i = env->vstart; i < vl; i++) { \ | ||
103 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
104 | /* set masked-off elements to 1s */ \ | ||
105 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
106 | uint32_t vta = vext_vta(desc); \ | ||
107 | uint32_t num = 0, i; \ | ||
108 | \ | ||
109 | + VSTART_CHECK_EARLY_EXIT(env, vl); \ | ||
110 | + \ | ||
111 | for (i = env->vstart; i < vl; i++) { \ | ||
112 | if (!vext_elem_mask(vs1, i)) { \ | ||
113 | continue; \ | ||
114 | -- | ||
115 | 2.48.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Richard Henderson <richard.henderson@linaro.org> | ||
1 | 2 | ||
3 | The third argument of the syscall contains the size of the | ||
4 | cpu mask in bytes, not bits. Nor is the size rounded up to | ||
5 | a multiple of sizeof(abi_ulong). | ||
6 | |||
7 | Cc: qemu-stable@nongnu.org | ||
8 | Reported-by: Andreas Schwab <schwab@suse.de> | ||
9 | Fixes: 9e1c7d982d7 ("linux-user/riscv: Add syscall riscv_hwprobe") | ||
10 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Message-ID: <20250308225902.1208237-3-richard.henderson@linaro.org> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | linux-user/syscall.c | 55 +++++++++++++++++++++++--------------------- | ||
16 | 1 file changed, 29 insertions(+), 26 deletions(-) | ||
17 | |||
18 | diff --git a/linux-user/syscall.c b/linux-user/syscall.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/linux-user/syscall.c | ||
21 | +++ b/linux-user/syscall.c | ||
22 | @@ -XXX,XX +XXX,XX @@ static void risc_hwprobe_fill_pairs(CPURISCVState *env, | ||
23 | } | ||
24 | } | ||
25 | |||
26 | -static int cpu_set_valid(abi_long arg3, abi_long arg4) | ||
27 | +/* | ||
28 | + * If the cpumask_t of (target_cpus, cpusetsize) cannot be read: -EFAULT. | ||
29 | + * If the cpumast_t has no bits set: -EINVAL. | ||
30 | + * Otherwise the cpumask_t contains some bit set: 0. | ||
31 | + * Unlike the kernel, we do not mask cpumask_t by the set of online cpus, | ||
32 | + * nor bound the search by cpumask_size(). | ||
33 | + */ | ||
34 | +static int nonempty_cpu_set(abi_ulong cpusetsize, abi_ptr target_cpus) | ||
35 | { | ||
36 | - int ret, i, tmp; | ||
37 | - size_t host_mask_size, target_mask_size; | ||
38 | - unsigned long *host_mask; | ||
39 | - | ||
40 | - /* | ||
41 | - * cpu_set_t represent CPU masks as bit masks of type unsigned long *. | ||
42 | - * arg3 contains the cpu count. | ||
43 | - */ | ||
44 | - tmp = (8 * sizeof(abi_ulong)); | ||
45 | - target_mask_size = ((arg3 + tmp - 1) / tmp) * sizeof(abi_ulong); | ||
46 | - host_mask_size = (target_mask_size + (sizeof(*host_mask) - 1)) & | ||
47 | - ~(sizeof(*host_mask) - 1); | ||
48 | - | ||
49 | - host_mask = alloca(host_mask_size); | ||
50 | - | ||
51 | - ret = target_to_host_cpu_mask(host_mask, host_mask_size, | ||
52 | - arg4, target_mask_size); | ||
53 | - if (ret != 0) { | ||
54 | - return ret; | ||
55 | - } | ||
56 | + unsigned char *p = lock_user(VERIFY_READ, target_cpus, cpusetsize, 1); | ||
57 | + int ret = -TARGET_EFAULT; | ||
58 | |||
59 | - for (i = 0 ; i < host_mask_size / sizeof(*host_mask); i++) { | ||
60 | - if (host_mask[i] != 0) { | ||
61 | - return 0; | ||
62 | + if (p) { | ||
63 | + ret = -TARGET_EINVAL; | ||
64 | + /* | ||
65 | + * Since we only care about the empty/non-empty state of the cpumask_t | ||
66 | + * not the individual bits, we do not need to repartition the bits | ||
67 | + * from target abi_ulong to host unsigned long. | ||
68 | + * | ||
69 | + * Note that the kernel does not round up cpusetsize to a multiple of | ||
70 | + * sizeof(abi_ulong). After bounding cpusetsize by cpumask_size(), | ||
71 | + * it copies exactly cpusetsize bytes into a zeroed buffer. | ||
72 | + */ | ||
73 | + for (abi_ulong i = 0; i < cpusetsize; ++i) { | ||
74 | + if (p[i]) { | ||
75 | + ret = 0; | ||
76 | + break; | ||
77 | + } | ||
78 | } | ||
79 | + unlock_user(p, target_cpus, 0); | ||
80 | } | ||
81 | - return -TARGET_EINVAL; | ||
82 | + return ret; | ||
83 | } | ||
84 | |||
85 | static abi_long do_riscv_hwprobe(CPUArchState *cpu_env, abi_long arg1, | ||
86 | @@ -XXX,XX +XXX,XX @@ static abi_long do_riscv_hwprobe(CPUArchState *cpu_env, abi_long arg1, | ||
87 | |||
88 | /* check cpu_set */ | ||
89 | if (arg3 != 0) { | ||
90 | - ret = cpu_set_valid(arg3, arg4); | ||
91 | + ret = nonempty_cpu_set(arg3, arg4); | ||
92 | if (ret != 0) { | ||
93 | return ret; | ||
94 | } | ||
95 | -- | ||
96 | 2.48.1 | diff view generated by jsdifflib |
1 | From: Thomas Huth <thuth@redhat.com> | 1 | From: Yu-Ming Chang <yumin686@andestech.com> |
---|---|---|---|
2 | 2 | ||
3 | Configuring a drive with "if=none" is meant for creation of a backend | 3 | For privilege version 1.12 or newer, C always implies Zca. We can only |
4 | only, it should not get automatically assigned to a device frontend. | 4 | check ext_zca to allow 16-bit aligned PC addresses. For older privilege |
5 | Use "if=pflash" for the One-Time-Programmable device instead (like | 5 | versions, we only check C. |
6 | it is e.g. also done for the efuse device in hw/arm/xlnx-zcu102.c). | ||
7 | 6 | ||
8 | Since the old way of configuring the device has already been published | 7 | Signed-off-by: Yu-Ming Chang <yumin686@andestech.com> |
9 | with the previous QEMU versions, we cannot remove this immediately, but | ||
10 | have to deprecate it and support it for at least two more releases. | ||
11 | |||
12 | Signed-off-by: Thomas Huth <thuth@redhat.com> | ||
13 | Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
14 | Reviewed-by: Markus Armbruster <armbru@redhat.com> | ||
15 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
16 | Message-id: 20211119102549.217755-1-thuth@redhat.com | 9 | Message-ID: <174184718265.10540.10120024221661781046-0@git.sr.ht> |
17 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
18 | --- | 11 | --- |
19 | docs/about/deprecated.rst | 6 ++++++ | 12 | target/riscv/cpu.h | 12 ++++++++++++ |
20 | hw/misc/sifive_u_otp.c | 9 ++++++++- | 13 | target/riscv/op_helper.c | 8 ++++++-- |
21 | 2 files changed, 14 insertions(+), 1 deletion(-) | 14 | target/riscv/translate.c | 4 +++- |
15 | target/riscv/insn_trans/trans_rvi.c.inc | 8 ++++++-- | ||
16 | 4 files changed, 27 insertions(+), 5 deletions(-) | ||
22 | 17 | ||
23 | diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst | 18 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h |
24 | index XXXXXXX..XXXXXXX 100644 | 19 | index XXXXXXX..XXXXXXX 100644 |
25 | --- a/docs/about/deprecated.rst | 20 | --- a/target/riscv/cpu.h |
26 | +++ b/docs/about/deprecated.rst | 21 | +++ b/target/riscv/cpu.h |
27 | @@ -XXX,XX +XXX,XX @@ as short-form boolean values, and passed to plugins as ``arg_name=on``. | 22 | @@ -XXX,XX +XXX,XX @@ static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env) |
28 | However, short-form booleans are deprecated and full explicit ``arg_name=on`` | 23 | } |
29 | form is preferred. | 24 | #endif |
30 | 25 | ||
31 | +``-drive if=none`` for the sifive_u OTP device (since 6.2) | 26 | +static inline bool riscv_cpu_allow_16bit_insn(const RISCVCPUConfig *cfg, |
32 | +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | 27 | + target_long priv_ver, |
28 | + uint32_t misa_ext) | ||
29 | +{ | ||
30 | + /* In priv spec version 1.12 or newer, C always implies Zca */ | ||
31 | + if (priv_ver >= PRIV_VERSION_1_12_0) { | ||
32 | + return cfg->ext_zca; | ||
33 | + } else { | ||
34 | + return misa_ext & RVC; | ||
35 | + } | ||
36 | +} | ||
33 | + | 37 | + |
34 | +Using ``-drive if=none`` to configure the OTP device of the sifive_u | 38 | /* |
35 | +RISC-V machine is deprecated. Use ``-drive if=pflash`` instead. | 39 | * Encode LMUL to lmul as follows: |
36 | + | 40 | * LMUL vlmul lmul |
37 | 41 | diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c | |
38 | QEMU Machine Protocol (QMP) commands | ||
39 | ------------------------------------ | ||
40 | diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | 42 | index XXXXXXX..XXXXXXX 100644 |
42 | --- a/hw/misc/sifive_u_otp.c | 43 | --- a/target/riscv/op_helper.c |
43 | +++ b/hw/misc/sifive_u_otp.c | 44 | +++ b/target/riscv/op_helper.c |
44 | @@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp) | 45 | @@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env) |
45 | TYPE_SIFIVE_U_OTP, SIFIVE_U_OTP_REG_SIZE); | 46 | } |
46 | sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); | 47 | |
47 | 48 | target_ulong retpc = env->sepc; | |
48 | - dinfo = drive_get_next(IF_NONE); | 49 | - if (!riscv_has_ext(env, RVC) && (retpc & 0x3)) { |
49 | + dinfo = drive_get_next(IF_PFLASH); | 50 | + if (!riscv_cpu_allow_16bit_insn(&env_archcpu(env)->cfg, |
50 | + if (!dinfo) { | 51 | + env->priv_ver, |
51 | + dinfo = drive_get_next(IF_NONE); | 52 | + env->misa_ext) && (retpc & 0x3)) { |
52 | + if (dinfo) { | 53 | riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC()); |
53 | + warn_report("using \"-drive if=none\" for the OTP is deprecated, " | 54 | } |
54 | + "use \"-drive if=pflash\" instead."); | 55 | |
55 | + } | 56 | @@ -XXX,XX +XXX,XX @@ static void check_ret_from_m_mode(CPURISCVState *env, target_ulong retpc, |
56 | + } | 57 | riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); |
57 | if (dinfo) { | 58 | } |
58 | int ret; | 59 | |
59 | uint64_t perm; | 60 | - if (!riscv_has_ext(env, RVC) && (retpc & 0x3)) { |
61 | + if (!riscv_cpu_allow_16bit_insn(&env_archcpu(env)->cfg, | ||
62 | + env->priv_ver, | ||
63 | + env->misa_ext) && (retpc & 0x3)) { | ||
64 | riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC()); | ||
65 | } | ||
66 | |||
67 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
68 | index XXXXXXX..XXXXXXX 100644 | ||
69 | --- a/target/riscv/translate.c | ||
70 | +++ b/target/riscv/translate.c | ||
71 | @@ -XXX,XX +XXX,XX @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm) | ||
72 | TCGv succ_pc = dest_gpr(ctx, rd); | ||
73 | |||
74 | /* check misaligned: */ | ||
75 | - if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) { | ||
76 | + if (!riscv_cpu_allow_16bit_insn(ctx->cfg_ptr, | ||
77 | + ctx->priv_ver, | ||
78 | + ctx->misa_ext)) { | ||
79 | if ((imm & 0x3) != 0) { | ||
80 | TCGv target_pc = tcg_temp_new(); | ||
81 | gen_pc_plus_diff(target_pc, ctx, imm); | ||
82 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | ||
83 | index XXXXXXX..XXXXXXX 100644 | ||
84 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | ||
85 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | ||
86 | @@ -XXX,XX +XXX,XX @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a) | ||
87 | tcg_gen_ext32s_tl(target_pc, target_pc); | ||
88 | } | ||
89 | |||
90 | - if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) { | ||
91 | + if (!riscv_cpu_allow_16bit_insn(ctx->cfg_ptr, | ||
92 | + ctx->priv_ver, | ||
93 | + ctx->misa_ext)) { | ||
94 | TCGv t0 = tcg_temp_new(); | ||
95 | |||
96 | misaligned = gen_new_label(); | ||
97 | @@ -XXX,XX +XXX,XX @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) | ||
98 | |||
99 | gen_set_label(l); /* branch taken */ | ||
100 | |||
101 | - if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca && | ||
102 | + if (!riscv_cpu_allow_16bit_insn(ctx->cfg_ptr, | ||
103 | + ctx->priv_ver, | ||
104 | + ctx->misa_ext) && | ||
105 | (a->imm & 0x3)) { | ||
106 | /* misaligned */ | ||
107 | TCGv target_pc = tcg_temp_new(); | ||
60 | -- | 108 | -- |
61 | 2.31.1 | 109 | 2.48.1 |
62 | |||
63 | diff view generated by jsdifflib |