Re: [PATCH v9 0/6] Pointer Masking update for Zjpm v1.0
Hi Daniel, Let's try to push it before EOY. I'm planning to start working on it in the first half of November. Does that work for you? Thanks вт, 29 окт. 2024 г. в 20:40, Daniel Henrique Barboza < dbarb...@ventanamicro.com>: > Hi Alexey, > > > Do you have plans to post a new version of this series? Aside from a few > comments > it seems like this was almost there. > > We might not be able to get it merged in time for this current release > (code freeze > is Nov 5th) but we can get it in Alistair's tree for the next release. > > > Thanks, > > Daniel > > On 5/11/24 7:10 AM, Alexey Baturo wrote: > > From: Alexey Baturo > > > > Hi, > > > > It looks like Pointer Masking spec has reached v1.0 and been frozen, > > rebasing on riscv-to-apply.next branch and resubmitting patches. > > > > Thanks. > > > > [v8]: > > Rebasing patches on current qemu branch and resubmitting them. > > > > > > [v7]: > > I'm terribly sorry, but previous rebase went wrong and somehow I missed > it. > > This time I double-checked rebased version. > > This patch series is properly rebased on > https://github.com/alistair23/qemu/tree/riscv-to-apply.next > > > > [v6]: > > This patch series is rebased on > https://github.com/alistair23/qemu/tree/riscv-to-apply.next > > > > [v5]: > > This patch series targets Zjpm v0.8 extension. > > The spec itself could be found here: > https://github.com/riscv/riscv-j-extension/blob/8088461d8d66a7676872b61c908cbeb7cf5c5d1d/zjpm-spec.pdf > > This patch series is updated after the suggested comments: > > - add "x-" to the extension names to indicate experimental > > > > [v4]: > > Patch series updated after the suggested comments: > > - removed J-letter extension as it's unused > > - renamed and fixed function to detect if address should be sign-extended > > - zeroed unused context variables and moved computation logic to another > patch > > - bumped pointer masking version_id and minimum_version_id by 1 > > > > [v3]: > > There patches are updated after Richard's comments: > > - moved new tb flags to the end > > - used tcg_gen_(s)extract to get the final address > > - properly handle CONFIG_USER_ONLY > > > > [v2]: > > As per Richard's suggestion I made pmm field part of tb_flags. > > It allowed to get rid of global variable to store pmlen. > > Also it allowed to simplify all the machinery around it. > > > > [v1]: > > It looks like Zjpm v0.8 is almost frozen and we don't expect it change > drastically anymore. > > Compared to the original implementation with explicit base and mask > CSRs, we now only have > > several fixed options for number of masked bits which are set using > existing CSRs. > > The changes have been tested with handwritten assembly tests and LLVM > HWASAN > > test suite. > > > > Alexey Baturo (6): > >target/riscv: Remove obsolete pointer masking extension code. > >target/riscv: Add new CSR fields for S{sn,mn,m}pm extensions as part > > of Zjpm v0.8 > >target/riscv: Add helper functions to calculate current number of > > masked bits for pointer masking > >target/riscv: Add pointer masking tb flags > >target/riscv: Update address modify functions to take into account > > pointer masking > >target/riscv: Enable updates for pointer masking variables and thus > > enable pointer masking extension > > > > target/riscv/cpu.c | 21 +-- > > target/riscv/cpu.h | 46 +++-- > > target/riscv/cpu_bits.h | 90 +- > > target/riscv/cpu_cfg.h | 3 + > > target/riscv/cpu_helper.c| 97 +- > > target/riscv/csr.c | 337 ++- > > target/riscv/machine.c | 20 +-- > > target/riscv/pmp.c | 13 +- > > target/riscv/pmp.h | 11 +- > > target/riscv/tcg/tcg-cpu.c | 5 +- > > target/riscv/translate.c | 46 ++--- > > target/riscv/vector_helper.c | 15 +- > > 12 files changed, 158 insertions(+), 546 deletions(-) > > >
Re: [PATCH v9 0/6] Pointer Masking update for Zjpm v1.0
>The cover letter says that this implements version 1.0 of the spec, this sounds like it doesn't. Yeah, sorry about the confusion. Yes, the patch is actually for v0.8 but as you've correctly mentioned v0.8 has not so much differences to v1.0. > Instead of constantly removing and re-adding the code I was talking about only one removing the existing code and replacing it with current patches and then making updates on top of them. >Do you mind fixing that and addressing the other comments/concerns Sure пн, 13 мая 2024 г. в 14:32, Alistair Francis : > On Mon, May 13, 2024 at 9:14 PM Alistair Francis > wrote: > > > > On Mon, May 13, 2024 at 9:05 PM Alexey Baturo > wrote: > > > > > > Hi, > > > > > > > Hi, any change from v0.8 to v1.0? > > > Not in the patches that were sent. I'd still suggest applying a > step-by-step approach with cleaning up old code and establishing the new > mechanisms first and then updating the code to match the spec 100%. Also I > heard Martin has some arch compliance tests for J-ext somewhere. > > > > The cover letter says that this implements version 1.0 of the spec, > > this sounds like it doesn't. > > > > Also, it's better to make the changes on top of the current code. > > Instead of constantly removing and re-adding the code. Which is then > > hard to review. Especially as I'm guessing there isn't a huge > > difference between v0.8 and v1.0. > > > > > @Alistair Francis @liwei does this approach sound reasonable to you? > > > > > > >Also, this needs another rebase > > > Sure, no problem at all. I'll rebase and re-send them later today. > > Sorry, it did apply correctly! That was my mistake. > > But this series generates a warning. Do you mind fixing that and > addressing the other comments/concerns > > Alistair > > > > > Thanks. Can you be very clear which version of the spec you have > > developed and tested against as well. > > > > Alistair >
Re: [PATCH v9 0/6] Pointer Masking update for Zjpm v1.0
Hi, > Hi, any change from v0.8 to v1.0? Not in the patches that were sent. I'd still suggest applying a step-by-step approach with cleaning up old code and establishing the new mechanisms first and then updating the code to match the spec 100%. Also I heard Martin has some arch compliance tests for J-ext somewhere. @Alistair Francis @liwei does this approach sound reasonable to you? >Also, this needs another rebase Sure, no problem at all. I'll rebase and re-send them later today. Thanks пн, 13 мая 2024 г. в 13:25, Alistair Francis : > On Sun, May 12, 2024 at 12:44 AM liwei wrote: > > > > > > On 2024/5/11 18:10, Alexey Baturo wrote: > > > From: Alexey Baturo > > > > > > Hi, > > > > > > It looks like Pointer Masking spec has reached v1.0 and been frozen, > > > rebasing on riscv-to-apply.next branch and resubmitting patches. > > > > Hi, any change from v0.8 to v1.0? > > Good question. > > Also, this needs another rebase. Sorry, it seems to always have > conflicts. If you re-send I'll apply it right away > > Alistair > > > > > Regards, > > > > Weiwei Li > > > > > > > > Thanks. > > > > > > [v8]: > > > Rebasing patches on current qemu branch and resubmitting them. > > > > > > > > > [v7]: > > > I'm terribly sorry, but previous rebase went wrong and somehow I > missed it. > > > This time I double-checked rebased version. > > > This patch series is properly rebased on > https://github.com/alistair23/qemu/tree/riscv-to-apply.next > > > > > > [v6]: > > > This patch series is rebased on > https://github.com/alistair23/qemu/tree/riscv-to-apply.next > > > > > > [v5]: > > > This patch series targets Zjpm v0.8 extension. > > > The spec itself could be found here: > https://github.com/riscv/riscv-j-extension/blob/8088461d8d66a7676872b61c908cbeb7cf5c5d1d/zjpm-spec.pdf > > > This patch series is updated after the suggested comments: > > > - add "x-" to the extension names to indicate experimental > > > > > > [v4]: > > > Patch series updated after the suggested comments: > > > - removed J-letter extension as it's unused > > > - renamed and fixed function to detect if address should be > sign-extended > > > - zeroed unused context variables and moved computation logic to > another patch > > > - bumped pointer masking version_id and minimum_version_id by 1 > > > > > > [v3]: > > > There patches are updated after Richard's comments: > > > - moved new tb flags to the end > > > - used tcg_gen_(s)extract to get the final address > > > - properly handle CONFIG_USER_ONLY > > > > > > [v2]: > > > As per Richard's suggestion I made pmm field part of tb_flags. > > > It allowed to get rid of global variable to store pmlen. > > > Also it allowed to simplify all the machinery around it. > > > > > > [v1]: > > > It looks like Zjpm v0.8 is almost frozen and we don't expect it change > drastically anymore. > > > Compared to the original implementation with explicit base and mask > CSRs, we now only have > > > several fixed options for number of masked bits which are set using > existing CSRs. > > > The changes have been tested with handwritten assembly tests and LLVM > HWASAN > > > test suite. > > > > > > Alexey Baturo (6): > > >target/riscv: Remove obsolete pointer masking extension code. > > >target/riscv: Add new CSR fields for S{sn,mn,m}pm extensions as part > > > of Zjpm v0.8 > > >target/riscv: Add helper functions to calculate current number of > > > masked bits for pointer masking > > >target/riscv: Add pointer masking tb flags > > >target/riscv: Update address modify functions to take into account > > > pointer masking > > >target/riscv: Enable updates for pointer masking variables and thus > > > enable pointer masking extension > > > > > > target/riscv/cpu.c | 21 +-- > > > target/riscv/cpu.h | 46 +++-- > > > target/riscv/cpu_bits.h | 90 +- > > > target/riscv/cpu_cfg.h | 3 + > > > target/riscv/cpu_helper.c| 97 +- > > > target/riscv/csr.c | 337 > ++- > > > target/riscv/machine.c | 20 +-- > > > target/riscv/pmp.c | 13 +- > > > target/riscv/pmp.h | 11 +- > > > target/riscv/tcg/tcg-cpu.c | 5 +- > > > target/riscv/translate.c | 46 ++--- > > > target/riscv/vector_helper.c | 15 +- > > > 12 files changed, 158 insertions(+), 546 deletions(-) > > > > > >
[PATCH v9 5/6] target/riscv: Update address modify functions to take into account pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis --- target/riscv/translate.c | 22 -- target/riscv/vector_helper.c | 13 + 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 3f578d6dd8..da46e636f8 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -580,8 +580,10 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_addi_tl(addr, src1, imm); -if (get_address_xl(ctx) == MXL_RV32) { -tcg_gen_ext32u_tl(addr, addr); +if (ctx->addr_signed) { +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width); +} else { +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width); } return addr; @@ -594,8 +596,10 @@ static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_add_tl(addr, src1, offs); -if (get_xl(ctx) == MXL_RV32) { -tcg_gen_ext32u_tl(addr, addr); +if (ctx->addr_signed) { +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width); +} else { +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width); } return addr; } @@ -1188,8 +1192,14 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; -ctx->addr_width = 0; -ctx->addr_signed = false; +if (get_xl(ctx) == MXL_RV32) { +ctx->addr_width = 32; +ctx->addr_signed = false; +} else { +int pm_pmm = FIELD_EX32(tb_flags, TB_FLAGS, PM_PMM); +ctx->addr_width = 64 - riscv_pm_get_pmlen(pm_pmm); +ctx->addr_signed = FIELD_EX32(tb_flags, TB_FLAGS, PM_SIGNEXTEND); +} ctx->ztso = cpu->cfg.ext_ztso; ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 39ba2a09dd..28861cc509 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -104,6 +104,19 @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz) static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr) { +RISCVPmPmm pmm = riscv_pm_get_pmm(env); +if (pmm == PMM_FIELD_DISABLED) { +return addr; +} +int pmlen = riscv_pm_get_pmlen(pmm); +bool signext = riscv_cpu_virt_mem_enabled(env); +addr = addr << pmlen; +/* sign/zero extend masked address by N-1 bit */ +if (signext) { +addr = (target_long)addr >> pmlen; +} else { +addr = addr >> pmlen; +} return addr; } -- 2.34.1
[PATCH v9 4/6] target/riscv: Add pointer masking tb flags
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis --- target/riscv/cpu.h| 3 +++ target/riscv/cpu_helper.c | 3 +++ target/riscv/translate.c | 5 + 3 files changed, 11 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 9cac723b19..bbf3a0f64e 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -564,6 +564,9 @@ FIELD(TB_FLAGS, ITRIGGER, 20, 1) FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) FIELD(TB_FLAGS, PRIV, 22, 2) FIELD(TB_FLAGS, AXL, 24, 2) +/* If pointer masking should be applied and address sign extended */ +FIELD(TB_FLAGS, PM_PMM, 26, 2) +FIELD(TB_FLAGS, PM_SIGNEXTEND, 28, 1) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index e4a127ca84..3f2473bd73 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -68,6 +68,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, RISCVCPU *cpu = env_archcpu(env); RISCVExtStatus fs, vs; uint32_t flags = 0; +bool pm_signext = riscv_cpu_virt_mem_enabled(env); *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc; *cs_base = 0; @@ -138,6 +139,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, flags = FIELD_DP32(flags, TB_FLAGS, VS, vs); flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl); flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext); *pflags = flags; } diff --git a/target/riscv/translate.c b/target/riscv/translate.c index e5b339b1fa..3f578d6dd8 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -103,6 +103,9 @@ typedef struct DisasContext { bool vl_eq_vlmax; CPUState *cs; TCGv zero; +/* actual address width */ +uint8_t addr_width; +bool addr_signed; /* Ztso */ bool ztso; /* Use icount trigger for native debug */ @@ -1185,6 +1188,8 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; +ctx->addr_width = 0; +ctx->addr_signed = false; ctx->ztso = cpu->cfg.ext_ztso; ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); -- 2.34.1
[PATCH v9 1/6] target/riscv: Remove obsolete pointer masking extension code.
From: Alexey Baturo Zjpm v0.8 is almost frozen and it's much simplier compared to the existing one: The newer version doesn't allow to specify custom mask or base for masking. Instead it allows only certain options for masking top bits. Signed-off-by: Alexey Baturo Acked-by: Alistair Francis --- target/riscv/cpu.c | 13 +- target/riscv/cpu.h | 30 +--- target/riscv/cpu_bits.h | 87 -- target/riscv/cpu_helper.c| 52 -- target/riscv/csr.c | 326 --- target/riscv/machine.c | 14 +- target/riscv/tcg/tcg-cpu.c | 5 +- target/riscv/translate.c | 27 +-- target/riscv/vector_helper.c | 2 +- 9 files changed, 13 insertions(+), 543 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index a74f0eb29c..1e350e9bd8 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -42,7 +42,7 @@ /* RISC-V CPU definitions */ static const char riscv_single_letter_exts[] = "IEMAFDQCBPVH"; const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV, - RVC, RVS, RVU, RVH, RVJ, RVG, RVB, 0}; + RVC, RVS, RVU, RVH, RVG, RVB, 0}; /* * From vector_helper.c @@ -795,13 +795,6 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) CSR_MSCRATCH, CSR_SSCRATCH, CSR_SATP, -CSR_MMTE, -CSR_UPMBASE, -CSR_UPMMASK, -CSR_SPMBASE, -CSR_SPMMASK, -CSR_MPMBASE, -CSR_MPMMASK, }; for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) { @@ -981,8 +974,6 @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type) } i++; } -/* mmte is supposed to have pm.current hardwired to 1 */ -env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT); /* * Bits 10, 6, 2 and 12 of mideleg are read only 1 when the Hypervisor @@ -1004,7 +995,6 @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type) pmp_unlock_entries(env); #endif env->xl = riscv_cpu_mxl(env); -riscv_cpu_update_mask(env); cs->exception_index = RISCV_EXCP_NONE; env->load_res = -1; set_default_nan_mode(1, &env->fp_status); @@ -1395,7 +1385,6 @@ static const MISAExtInfo misa_ext_info_arr[] = { MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"), MISA_EXT_INFO(RVU, "u", "User-level instructions"), MISA_EXT_INFO(RVH, "h", "Hypervisor"), -MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"), MISA_EXT_INFO(RVV, "v", "Vector operations"), MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"), MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)") diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index e0dd1828b5..232521bb87 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -66,7 +66,6 @@ typedef struct CPUArchState CPURISCVState; #define RVS RV('S') #define RVU RV('U') #define RVH RV('H') -#define RVJ RV('J') #define RVG RV('G') #define RVB RV('B') @@ -393,17 +392,6 @@ struct CPUArchState { /* True if in debugger mode. */ bool debugger; -/* - * CSRs for PointerMasking extension - */ -target_ulong mmte; -target_ulong mpmmask; -target_ulong mpmbase; -target_ulong spmmask; -target_ulong spmbase; -target_ulong upmmask; -target_ulong upmbase; - /* CSRs for execution environment configuration */ uint64_t menvcfg; uint64_t mstateen[SMSTATEEN_MAX_COUNT]; @@ -412,9 +400,6 @@ struct CPUArchState { target_ulong senvcfg; uint64_t henvcfg; #endif -target_ulong cur_pmmask; -target_ulong cur_pmbase; - /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */ @@ -563,16 +548,14 @@ FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 16, 2) /* If PointerMasking should be applied */ -FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1) -FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1) -FIELD(TB_FLAGS, VTA, 20, 1) -FIELD(TB_FLAGS, VMA, 21, 1) +FIELD(TB_FLAGS, VTA, 18, 1) +FIELD(TB_FLAGS, VMA, 19, 1) /* Native debug itrigger */ -FIELD(TB_FLAGS, ITRIGGER, 22, 1) +FIELD(TB_FLAGS, ITRIGGER, 20, 1) /* Virtual mode enabled */ -FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) -FIELD(TB_FLAGS, PRIV, 24, 2) -FIELD(TB_FLAGS, AXL, 26, 2) +FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) +FIELD(TB_FLAGS, PRIV, 22, 2) +FIELD(TB_FLAGS, AXL, 24, 2) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) @@ -705,7 +688,6 @@
[PATCH v9 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/cpu.c | 8 1 file changed, 8 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 1e350e9bd8..b3b3a6275f 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -192,6 +192,9 @@ const RISCVIsaExtData isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval), ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot), ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt), +ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_12_0, ext_ssnpm), +ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_12_0, ext_smnpm), +ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_12_0, ext_smmpm), ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba), ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb), ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs), @@ -1565,6 +1568,11 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = { /* These are experimental so mark with 'x-' */ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = { +/* Zjpm v0.8 extensions */ +MULTI_EXT_CFG_BOOL("x-ssnpm", ext_ssnpm, false), +MULTI_EXT_CFG_BOOL("x-smnpm", ext_smnpm, false), +MULTI_EXT_CFG_BOOL("x-smmpm", ext_smmpm, false), + DEFINE_PROP_END_OF_LIST(), }; -- 2.34.1
[PATCH v9 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/cpu.h| 5 target/riscv/cpu_helper.c | 58 +++ 2 files changed, 63 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 52b6ba73c8..9cac723b19 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -698,8 +698,13 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, bool riscv_cpu_is_32bit(RISCVCPU *cpu); +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env); +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env); +int riscv_pm_get_pmlen(RISCVPmPmm pmm); + RISCVException riscv_csrr(CPURISCVState *env, int csrno, target_ulong *ret_value); + RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index bf58350669..e4a127ca84 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -142,6 +142,64 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, *pflags = flags; } +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env) +{ +int pmm = 0; +#ifndef CONFIG_USER_ONLY +int priv_mode = cpu_address_mode(env); +/* Get current PMM field */ +switch (priv_mode) { +case PRV_M: +pmm = riscv_cpu_cfg(env)->ext_smmpm ? + get_field(env->mseccfg, MSECCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_S: +pmm = riscv_cpu_cfg(env)->ext_smnpm ? + get_field(env->menvcfg, MENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_U: +pmm = riscv_cpu_cfg(env)->ext_ssnpm ? + get_field(env->senvcfg, SENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +default: +g_assert_not_reached(); +} +#endif +return pmm; +} + +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env) +{ +bool virt_mem_en = false; +#ifndef CONFIG_USER_ONLY +int satp_mode = 0; +int priv_mode = cpu_address_mode(env); +/* Get current PMM field */ +if (riscv_cpu_mxl(env) == MXL_RV32) { +satp_mode = get_field(env->satp, SATP32_MODE); +} else { +satp_mode = get_field(env->satp, SATP64_MODE); +} +virt_mem_en = ((satp_mode != VM_1_10_MBARE) && (priv_mode != PRV_M)); +#endif +return virt_mem_en; +} + +int riscv_pm_get_pmlen(RISCVPmPmm pmm) +{ +switch (pmm) { +case PMM_FIELD_DISABLED: +return 0; +case PMM_FIELD_PMLEN7: +return 7; +case PMM_FIELD_PMLEN16: +return 16; +default: +g_assert_not_reached(); +} +return -1; +} + #ifndef CONFIG_USER_ONLY /* -- 2.34.1
[PATCH v9 0/6] Pointer Masking update for Zjpm v1.0
From: Alexey Baturo Hi, It looks like Pointer Masking spec has reached v1.0 and been frozen, rebasing on riscv-to-apply.next branch and resubmitting patches. Thanks. [v8]: Rebasing patches on current qemu branch and resubmitting them. [v7]: I'm terribly sorry, but previous rebase went wrong and somehow I missed it. This time I double-checked rebased version. This patch series is properly rebased on https://github.com/alistair23/qemu/tree/riscv-to-apply.next [v6]: This patch series is rebased on https://github.com/alistair23/qemu/tree/riscv-to-apply.next [v5]: This patch series targets Zjpm v0.8 extension. The spec itself could be found here: https://github.com/riscv/riscv-j-extension/blob/8088461d8d66a7676872b61c908cbeb7cf5c5d1d/zjpm-spec.pdf This patch series is updated after the suggested comments: - add "x-" to the extension names to indicate experimental [v4]: Patch series updated after the suggested comments: - removed J-letter extension as it's unused - renamed and fixed function to detect if address should be sign-extended - zeroed unused context variables and moved computation logic to another patch - bumped pointer masking version_id and minimum_version_id by 1 [v3]: There patches are updated after Richard's comments: - moved new tb flags to the end - used tcg_gen_(s)extract to get the final address - properly handle CONFIG_USER_ONLY [v2]: As per Richard's suggestion I made pmm field part of tb_flags. It allowed to get rid of global variable to store pmlen. Also it allowed to simplify all the machinery around it. [v1]: It looks like Zjpm v0.8 is almost frozen and we don't expect it change drastically anymore. Compared to the original implementation with explicit base and mask CSRs, we now only have several fixed options for number of masked bits which are set using existing CSRs. The changes have been tested with handwritten assembly tests and LLVM HWASAN test suite. Alexey Baturo (6): target/riscv: Remove obsolete pointer masking extension code. target/riscv: Add new CSR fields for S{sn,mn,m}pm extensions as part of Zjpm v0.8 target/riscv: Add helper functions to calculate current number of masked bits for pointer masking target/riscv: Add pointer masking tb flags target/riscv: Update address modify functions to take into account pointer masking target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension target/riscv/cpu.c | 21 +-- target/riscv/cpu.h | 46 +++-- target/riscv/cpu_bits.h | 90 +- target/riscv/cpu_cfg.h | 3 + target/riscv/cpu_helper.c| 97 +- target/riscv/csr.c | 337 ++- target/riscv/machine.c | 20 +-- target/riscv/pmp.c | 13 +- target/riscv/pmp.h | 11 +- target/riscv/tcg/tcg-cpu.c | 5 +- target/riscv/translate.c | 46 ++--- target/riscv/vector_helper.c | 15 +- 12 files changed, 158 insertions(+), 546 deletions(-) -- 2.34.1
[PATCH v9 2/6] target/riscv: Add new CSR fields for S{sn, mn, m}pm extensions as part of Zjpm v0.8
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/cpu.h | 8 target/riscv/cpu_bits.h | 3 +++ target/riscv/cpu_cfg.h | 3 +++ target/riscv/csr.c | 11 +++ target/riscv/machine.c | 10 +++--- target/riscv/pmp.c | 13 ++--- target/riscv/pmp.h | 11 ++- 7 files changed, 48 insertions(+), 11 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 232521bb87..52b6ba73c8 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -121,6 +121,14 @@ typedef enum { EXT_STATUS_DIRTY, } RISCVExtStatus; +/* Enum holds PMM field values for Zjpm v0.8 extension */ +typedef enum { +PMM_FIELD_DISABLED = 0, +PMM_FIELD_RESERVED = 1, +PMM_FIELD_PMLEN7 = 2, +PMM_FIELD_PMLEN16 = 3, +} RISCVPmPmm; + #define MMU_USER_IDX 3 #define MAX_RISCV_PMPS (16) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index da16ba236a..13ce2218d1 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -708,6 +708,7 @@ typedef enum RISCVException { #define MENVCFG_CBIE (3UL << 4) #define MENVCFG_CBCFE BIT(6) #define MENVCFG_CBZE BIT(7) +#define MENVCFG_PMM(3ULL << 32) #define MENVCFG_ADUE (1ULL << 61) #define MENVCFG_PBMTE (1ULL << 62) #define MENVCFG_STCE (1ULL << 63) @@ -721,11 +722,13 @@ typedef enum RISCVException { #define SENVCFG_CBIE MENVCFG_CBIE #define SENVCFG_CBCFE MENVCFG_CBCFE #define SENVCFG_CBZE MENVCFG_CBZE +#define SENVCFG_PMMMENVCFG_PMM #define HENVCFG_FIOM MENVCFG_FIOM #define HENVCFG_CBIE MENVCFG_CBIE #define HENVCFG_CBCFE MENVCFG_CBCFE #define HENVCFG_CBZE MENVCFG_CBZE +#define HENVCFG_PMMMENVCFG_PMM #define HENVCFG_ADUE MENVCFG_ADUE #define HENVCFG_PBMTE MENVCFG_PBMTE #define HENVCFG_STCE MENVCFG_STCE diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index e1e4f32698..9ecdc792c5 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -120,6 +120,9 @@ struct RISCVCPUConfig { bool ext_ssaia; bool ext_sscofpmf; bool ext_smepmp; +bool ext_ssnpm; +bool ext_smnpm; +bool ext_smmpm; bool rvv_ta_all_1s; bool rvv_ma_all_1s; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 4b2c932564..45b548eb0b 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -530,6 +530,9 @@ static RISCVException have_mseccfg(CPURISCVState *env, int csrno) if (riscv_cpu_cfg(env)->ext_zkr) { return RISCV_EXCP_NONE; } +if (riscv_cpu_cfg(env)->ext_smmpm) { +return RISCV_EXCP_NONE; +} return RISCV_EXCP_ILLEGAL_INST; } @@ -2083,6 +2086,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, (cfg->ext_sstc ? MENVCFG_STCE : 0) | (cfg->ext_svadu ? MENVCFG_ADUE : 0); } +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & MENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= MENVCFG_PMM; +} env->menvcfg = (env->menvcfg & ~mask) | (val & mask); return RISCV_EXCP_NONE; @@ -2127,6 +2134,10 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, target_ulong val) { uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE; +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & SENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= SENVCFG_PMM; +} RISCVException ret; ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG); diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 64ab66e332..28f373 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -152,15 +152,19 @@ static const VMStateDescription vmstate_vector = { static bool pointermasking_needed(void *opaque) { -return false; +RISCVCPU *cpu = opaque; +return cpu->cfg.ext_ssnpm || cpu->cfg.ext_smnpm || cpu->cfg.ext_smmpm; } static const VMStateDescription vmstate_pointermasking = { .name = "cpu/pointer_masking", -.version_id = 1, -.minimum_version_id = 1, +.version_id = 2, +.minimum_version_id = 2, .needed = pointermasking_needed, .fields = (const VMStateField[]) { +VMSTATE_UINTTL(env.mseccfg, RISCVCPU), +VMSTATE_UINTTL(env.senvcfg, RISCVCPU), +VMSTATE_UINTTL(env.menvcfg, RISCVCPU), VMSTATE_END_OF_LIST() } }; diff --git a/targe
[PATCH v8 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/cpu.c | 8 1 file changed, 8 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 73c69f3d0a..9e3bf6c5c5 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -190,6 +190,9 @@ const RISCVIsaExtData isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval), ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot), ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt), +ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_12_0, ext_ssnpm), +ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_12_0, ext_smnpm), +ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_12_0, ext_smmpm), ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba), ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb), ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs), @@ -1561,6 +1564,11 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = { /* These are experimental so mark with 'x-' */ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = { +/* Zjpm v0.8 extensions */ +MULTI_EXT_CFG_BOOL("x-ssnpm", ext_ssnpm, false), +MULTI_EXT_CFG_BOOL("x-smnpm", ext_smnpm, false), +MULTI_EXT_CFG_BOOL("x-smmpm", ext_smmpm, false), + DEFINE_PROP_END_OF_LIST(), }; -- 2.34.1
[PATCH v8 4/6] target/riscv: Add pointer masking tb flags
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis --- target/riscv/cpu.h| 3 +++ target/riscv/cpu_helper.c | 3 +++ target/riscv/translate.c | 5 + 3 files changed, 11 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 0112b568a0..404f6ec50d 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -566,6 +566,9 @@ FIELD(TB_FLAGS, ITRIGGER, 20, 1) FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) FIELD(TB_FLAGS, PRIV, 22, 2) FIELD(TB_FLAGS, AXL, 24, 2) +/* If pointer masking should be applied and address sign extended */ +FIELD(TB_FLAGS, PM_PMM, 26, 2) +FIELD(TB_FLAGS, PM_SIGNEXTEND, 28, 1) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index a563451c48..4dea564fd8 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -68,6 +68,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, RISCVCPU *cpu = env_archcpu(env); RISCVExtStatus fs, vs; uint32_t flags = 0; +bool pm_signext = riscv_cpu_virt_mem_enabled(env); *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc; *cs_base = 0; @@ -138,6 +139,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, flags = FIELD_DP32(flags, TB_FLAGS, VS, vs); flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl); flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext); *pflags = flags; } diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 3382eb0a5f..a85a2abf2e 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -103,6 +103,9 @@ typedef struct DisasContext { bool vl_eq_vlmax; CPUState *cs; TCGv zero; +/* actual address width */ +uint8_t addr_width; +bool addr_signed; /* Ztso */ bool ztso; /* Use icount trigger for native debug */ @@ -1180,6 +1183,8 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; +ctx->addr_width = 0; +ctx->addr_signed = false; ctx->ztso = cpu->cfg.ext_ztso; ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); -- 2.34.1
[PATCH v8 5/6] target/riscv: Update address modify functions to take into account pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis --- target/riscv/translate.c | 22 -- target/riscv/vector_helper.c | 13 + 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index a85a2abf2e..99c5c6a530 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -581,8 +581,10 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_addi_tl(addr, src1, imm); -if (get_address_xl(ctx) == MXL_RV32) { -tcg_gen_ext32u_tl(addr, addr); +if (ctx->addr_signed) { +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width); +} else { +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width); } return addr; @@ -595,8 +597,10 @@ static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_add_tl(addr, src1, offs); -if (get_xl(ctx) == MXL_RV32) { -tcg_gen_ext32u_tl(addr, addr); +if (ctx->addr_signed) { +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width); +} else { +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width); } return addr; } @@ -1183,8 +1187,14 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; -ctx->addr_width = 0; -ctx->addr_signed = false; +if (get_xl(ctx) == MXL_RV32) { +ctx->addr_width = 32; +ctx->addr_signed = false; +} else { +int pm_pmm = FIELD_EX32(tb_flags, TB_FLAGS, PM_PMM); +ctx->addr_width = 64 - riscv_pm_get_pmlen(pm_pmm); +ctx->addr_signed = FIELD_EX32(tb_flags, TB_FLAGS, PM_SIGNEXTEND); +} ctx->ztso = cpu->cfg.ext_ztso; ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 4934b43722..c77fbd8929 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -104,6 +104,19 @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz) static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr) { +RISCVPmPmm pmm = riscv_pm_get_pmm(env); +if (pmm == PMM_FIELD_DISABLED) { +return addr; +} +int pmlen = riscv_pm_get_pmlen(pmm); +bool signext = riscv_cpu_virt_mem_enabled(env); +addr = addr << pmlen; +/* sign/zero extend masked address by N-1 bit */ +if (signext) { +addr = (target_long)addr >> pmlen; +} else { +addr = addr >> pmlen; +} return addr; } -- 2.34.1
[PATCH v8 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/cpu.h| 4 +++ target/riscv/cpu_helper.c | 58 +++ 2 files changed, 62 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index b694cc62bf..0112b568a0 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -700,6 +700,10 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, bool riscv_cpu_is_32bit(RISCVCPU *cpu); +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env); +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env); +int riscv_pm_get_pmlen(RISCVPmPmm pmm); + RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index d20bffdd5a..a563451c48 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -142,6 +142,64 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, *pflags = flags; } +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env) +{ +int pmm = 0; +#ifndef CONFIG_USER_ONLY +int priv_mode = cpu_address_mode(env); +/* Get current PMM field */ +switch (priv_mode) { +case PRV_M: +pmm = riscv_cpu_cfg(env)->ext_smmpm ? + get_field(env->mseccfg, MSECCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_S: +pmm = riscv_cpu_cfg(env)->ext_smnpm ? + get_field(env->menvcfg, MENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_U: +pmm = riscv_cpu_cfg(env)->ext_ssnpm ? + get_field(env->senvcfg, SENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +default: +g_assert_not_reached(); +} +#endif +return pmm; +} + +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env) +{ +bool virt_mem_en = false; +#ifndef CONFIG_USER_ONLY +int satp_mode = 0; +int priv_mode = cpu_address_mode(env); +/* Get current PMM field */ +if (riscv_cpu_mxl(env) == MXL_RV32) { +satp_mode = get_field(env->satp, SATP32_MODE); +} else { +satp_mode = get_field(env->satp, SATP64_MODE); +} +virt_mem_en = ((satp_mode != VM_1_10_MBARE) && (priv_mode != PRV_M)); +#endif +return virt_mem_en; +} + +int riscv_pm_get_pmlen(RISCVPmPmm pmm) +{ +switch (pmm) { +case PMM_FIELD_DISABLED: +return 0; +case PMM_FIELD_PMLEN7: +return 7; +case PMM_FIELD_PMLEN16: +return 16; +default: +g_assert_not_reached(); +} +return -1; +} + #ifndef CONFIG_USER_ONLY /* -- 2.34.1
[PATCH v8 2/6] target/riscv: Add new CSR fields for S{sn, mn, m}pm extensions as part of Zjpm v0.8
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/cpu.h | 8 target/riscv/cpu_bits.h | 3 +++ target/riscv/cpu_cfg.h | 3 +++ target/riscv/csr.c | 11 +++ target/riscv/machine.c | 10 +++--- target/riscv/pmp.c | 13 ++--- target/riscv/pmp.h | 11 ++- 7 files changed, 48 insertions(+), 11 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index cfad5281a1..b694cc62bf 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -123,6 +123,14 @@ typedef enum { EXT_STATUS_DIRTY, } RISCVExtStatus; +/* Enum holds PMM field values for Zjpm v0.8 extension */ +typedef enum { +PMM_FIELD_DISABLED = 0, +PMM_FIELD_RESERVED = 1, +PMM_FIELD_PMLEN7 = 2, +PMM_FIELD_PMLEN16 = 3, +} RISCVPmPmm; + #define MMU_USER_IDX 3 #define MAX_RISCV_PMPS (16) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 5098d2d613..e9e6e1f952 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -708,6 +708,7 @@ typedef enum RISCVException { #define MENVCFG_CBIE (3UL << 4) #define MENVCFG_CBCFE BIT(6) #define MENVCFG_CBZE BIT(7) +#define MENVCFG_PMM(3ULL << 32) #define MENVCFG_ADUE (1ULL << 61) #define MENVCFG_PBMTE (1ULL << 62) #define MENVCFG_STCE (1ULL << 63) @@ -721,11 +722,13 @@ typedef enum RISCVException { #define SENVCFG_CBIE MENVCFG_CBIE #define SENVCFG_CBCFE MENVCFG_CBCFE #define SENVCFG_CBZE MENVCFG_CBZE +#define SENVCFG_PMMMENVCFG_PMM #define HENVCFG_FIOM MENVCFG_FIOM #define HENVCFG_CBIE MENVCFG_CBIE #define HENVCFG_CBCFE MENVCFG_CBCFE #define HENVCFG_CBZE MENVCFG_CBZE +#define HENVCFG_PMMMENVCFG_PMM #define HENVCFG_ADUE MENVCFG_ADUE #define HENVCFG_PBMTE MENVCFG_PBMTE #define HENVCFG_STCE MENVCFG_STCE diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index 2040b90da0..963de724c2 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -118,6 +118,9 @@ struct RISCVCPUConfig { bool ext_ssaia; bool ext_sscofpmf; bool ext_smepmp; +bool ext_ssnpm; +bool ext_smnpm; +bool ext_smmpm; bool rvv_ta_all_1s; bool rvv_ma_all_1s; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index ffb5a1102e..69c0279c12 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -530,6 +530,9 @@ static RISCVException have_mseccfg(CPURISCVState *env, int csrno) if (riscv_cpu_cfg(env)->ext_zkr) { return RISCV_EXCP_NONE; } +if (riscv_cpu_cfg(env)->ext_smmpm) { +return RISCV_EXCP_NONE; +} return RISCV_EXCP_ILLEGAL_INST; } @@ -2080,6 +2083,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, (cfg->ext_sstc ? MENVCFG_STCE : 0) | (cfg->ext_svadu ? MENVCFG_ADUE : 0); } +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & MENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= MENVCFG_PMM; +} env->menvcfg = (env->menvcfg & ~mask) | (val & mask); return RISCV_EXCP_NONE; @@ -2124,6 +2131,10 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, target_ulong val) { uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE; +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & SENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= SENVCFG_PMM; +} RISCVException ret; ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG); diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 64ab66e332..28f373 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -152,15 +152,19 @@ static const VMStateDescription vmstate_vector = { static bool pointermasking_needed(void *opaque) { -return false; +RISCVCPU *cpu = opaque; +return cpu->cfg.ext_ssnpm || cpu->cfg.ext_smnpm || cpu->cfg.ext_smmpm; } static const VMStateDescription vmstate_pointermasking = { .name = "cpu/pointer_masking", -.version_id = 1, -.minimum_version_id = 1, +.version_id = 2, +.minimum_version_id = 2, .needed = pointermasking_needed, .fields = (const VMStateField[]) { +VMSTATE_UINTTL(env.mseccfg, RISCVCPU), +VMSTATE_UINTTL(env.senvcfg, RISCVCPU), +VMSTATE_UINTTL(env.menvcfg, RISCVCPU), VMSTATE_END_OF_LIST() } }; diff --git a/targe
[PATCH v8 0/6] Pointer Masking update for Zjpm v0.8
From: Alexey Baturo Hi, Rebasing patches on current qemu branch and resubmitting them. Thanks. [v7]: I'm terribly sorry, but previous rebase went wrong and somehow I missed it. This time I double-checked rebased version. This patch series is properly rebased on https://github.com/alistair23/qemu/tree/riscv-to-apply.next [v6]: This patch series is rebased on https://github.com/alistair23/qemu/tree/riscv-to-apply.next [v5]: This patch series targets Zjpm v0.8 extension. The spec itself could be found here: https://github.com/riscv/riscv-j-extension/blob/8088461d8d66a7676872b61c908cbeb7cf5c5d1d/zjpm-spec.pdf This patch series is updated after the suggested comments: - add "x-" to the extension names to indicate experimental [v4]: Patch series updated after the suggested comments: - removed J-letter extension as it's unused - renamed and fixed function to detect if address should be sign-extended - zeroed unused context variables and moved computation logic to another patch - bumped pointer masking version_id and minimum_version_id by 1 [v3]: There patches are updated after Richard's comments: - moved new tb flags to the end - used tcg_gen_(s)extract to get the final address - properly handle CONFIG_USER_ONLY [v2]: As per Richard's suggestion I made pmm field part of tb_flags. It allowed to get rid of global variable to store pmlen. Also it allowed to simplify all the machinery around it. [v1]: It looks like Zjpm v0.8 is almost frozen and we don't expect it change drastically anymore. Compared to the original implementation with explicit base and mask CSRs, we now only have several fixed options for number of masked bits which are set using existing CSRs. The changes have been tested with handwritten assembly tests and LLVM HWASAN test suite. Alexey Baturo (6): target/riscv: Remove obsolete pointer masking extension code. target/riscv: Add new CSR fields for S{sn,mn,m}pm extensions as part of Zjpm v0.8 target/riscv: Add helper functions to calculate current number of masked bits for pointer masking target/riscv: Add pointer masking tb flags target/riscv: Update address modify functions to take into account pointer masking target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension target/riscv/cpu.c | 21 +-- target/riscv/cpu.h | 45 +++-- target/riscv/cpu_bits.h | 90 +- target/riscv/cpu_cfg.h | 3 + target/riscv/cpu_helper.c| 97 +- target/riscv/csr.c | 337 ++- target/riscv/machine.c | 20 +-- target/riscv/pmp.c | 13 +- target/riscv/pmp.h | 11 +- target/riscv/tcg/tcg-cpu.c | 5 +- target/riscv/translate.c | 46 ++--- target/riscv/vector_helper.c | 15 +- 12 files changed, 157 insertions(+), 546 deletions(-) -- 2.34.1
[PATCH v8 1/6] target/riscv: Remove obsolete pointer masking extension code.
From: Alexey Baturo Zjpm v0.8 is almost frozen and it's much simplier compared to the existing one: The newer version doesn't allow to specify custom mask or base for masking. Instead it allows only certain options for masking top bits. Signed-off-by: Alexey Baturo Acked-by: Alistair Francis --- target/riscv/cpu.c | 13 +- target/riscv/cpu.h | 30 +--- target/riscv/cpu_bits.h | 87 -- target/riscv/cpu_helper.c| 52 -- target/riscv/csr.c | 326 --- target/riscv/machine.c | 14 +- target/riscv/tcg/tcg-cpu.c | 5 +- target/riscv/translate.c | 27 +-- target/riscv/vector_helper.c | 2 +- 9 files changed, 13 insertions(+), 543 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index c160b9216b..73c69f3d0a 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -42,7 +42,7 @@ /* RISC-V CPU definitions */ static const char riscv_single_letter_exts[] = "IEMAFDQCBPVH"; const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV, - RVC, RVS, RVU, RVH, RVJ, RVG, RVB, 0}; + RVC, RVS, RVU, RVH, RVG, RVB, 0}; /* * From vector_helper.c @@ -793,13 +793,6 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) CSR_MSCRATCH, CSR_SSCRATCH, CSR_SATP, -CSR_MMTE, -CSR_UPMBASE, -CSR_UPMMASK, -CSR_SPMBASE, -CSR_SPMMASK, -CSR_MPMBASE, -CSR_MPMMASK, }; for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) { @@ -979,8 +972,6 @@ static void riscv_cpu_reset_hold(Object *obj) } i++; } -/* mmte is supposed to have pm.current hardwired to 1 */ -env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT); /* * Bits 10, 6, 2 and 12 of mideleg are read only 1 when the Hypervisor @@ -1002,7 +993,6 @@ static void riscv_cpu_reset_hold(Object *obj) pmp_unlock_entries(env); #endif env->xl = riscv_cpu_mxl(env); -riscv_cpu_update_mask(env); cs->exception_index = RISCV_EXCP_NONE; env->load_res = -1; set_default_nan_mode(1, &env->fp_status); @@ -1393,7 +1383,6 @@ static const MISAExtInfo misa_ext_info_arr[] = { MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"), MISA_EXT_INFO(RVU, "u", "User-level instructions"), MISA_EXT_INFO(RVH, "h", "Hypervisor"), -MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"), MISA_EXT_INFO(RVV, "v", "Vector operations"), MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"), MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)") diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 3b1a02b944..cfad5281a1 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -68,7 +68,6 @@ typedef struct CPUArchState CPURISCVState; #define RVS RV('S') #define RVU RV('U') #define RVH RV('H') -#define RVJ RV('J') #define RVG RV('G') #define RVB RV('B') @@ -395,17 +394,6 @@ struct CPUArchState { /* True if in debugger mode. */ bool debugger; -/* - * CSRs for PointerMasking extension - */ -target_ulong mmte; -target_ulong mpmmask; -target_ulong mpmbase; -target_ulong spmmask; -target_ulong spmbase; -target_ulong upmmask; -target_ulong upmbase; - /* CSRs for execution environment configuration */ uint64_t menvcfg; uint64_t mstateen[SMSTATEEN_MAX_COUNT]; @@ -414,9 +402,6 @@ struct CPUArchState { target_ulong senvcfg; uint64_t henvcfg; #endif -target_ulong cur_pmmask; -target_ulong cur_pmbase; - /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */ @@ -565,16 +550,14 @@ FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 16, 2) /* If PointerMasking should be applied */ -FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1) -FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1) -FIELD(TB_FLAGS, VTA, 20, 1) -FIELD(TB_FLAGS, VMA, 21, 1) +FIELD(TB_FLAGS, VTA, 18, 1) +FIELD(TB_FLAGS, VMA, 19, 1) /* Native debug itrigger */ -FIELD(TB_FLAGS, ITRIGGER, 22, 1) +FIELD(TB_FLAGS, ITRIGGER, 20, 1) /* Virtual mode enabled */ -FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) -FIELD(TB_FLAGS, PRIV, 24, 2) -FIELD(TB_FLAGS, AXL, 26, 2) +FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) +FIELD(TB_FLAGS, PRIV, 22, 2) +FIELD(TB_FLAGS, AXL, 24, 2) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) @@ -707,7 +690,6 @@ static inline uint32_t vext_get_vlm
[PATCH v7 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/cpu.c | 9 + 1 file changed, 9 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index ded84f2e09..23d1692b59 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -175,6 +175,9 @@ const RISCVIsaExtData isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval), ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot), ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt), +ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_12_0, ext_ssnpm), +ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_12_0, ext_smnpm), +ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_12_0, ext_smmpm), ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba), ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb), ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs), @@ -1496,6 +1499,12 @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = { MULTI_EXT_CFG_BOOL("x-zvfbfmin", ext_zvfbfmin, false), MULTI_EXT_CFG_BOOL("x-zvfbfwma", ext_zvfbfwma, false), +/* Zjpm v0.8 extensions */ +MULTI_EXT_CFG_BOOL("x-ssnpm", ext_ssnpm, false), +MULTI_EXT_CFG_BOOL("x-smnpm", ext_smnpm, false), +MULTI_EXT_CFG_BOOL("x-smmpm", ext_smmpm, false), + + DEFINE_PROP_END_OF_LIST(), }; -- 2.34.1
[PATCH v7 1/6] target/riscv: Remove obsolete pointer masking extension code.
From: Alexey Baturo Zjpm v0.8 is almost frozen and it's much simplier compared to the existing one: The newer version doesn't allow to specify custom mask or base for masking. Instead it allows only certain options for masking top bits. Signed-off-by: Alexey Baturo Acked-by: Alistair Francis --- target/riscv/cpu.c | 13 +- target/riscv/cpu.h | 30 +--- target/riscv/cpu_bits.h | 87 -- target/riscv/cpu_helper.c| 52 -- target/riscv/csr.c | 326 --- target/riscv/machine.c | 14 +- target/riscv/tcg/tcg-cpu.c | 5 +- target/riscv/translate.c | 27 +-- target/riscv/vector_helper.c | 2 +- 9 files changed, 13 insertions(+), 543 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 88e8cc8681..ded84f2e09 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -41,7 +41,7 @@ /* RISC-V CPU definitions */ static const char riscv_single_letter_exts[] = "IEMAFDQCBPVH"; const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV, - RVC, RVS, RVU, RVH, RVJ, RVG, RVB, 0}; + RVC, RVS, RVU, RVH, RVG, RVB, 0}; /* * From vector_helper.c @@ -786,13 +786,6 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) CSR_MSCRATCH, CSR_SSCRATCH, CSR_SATP, -CSR_MMTE, -CSR_UPMBASE, -CSR_UPMMASK, -CSR_SPMBASE, -CSR_SPMMASK, -CSR_MPMBASE, -CSR_MPMMASK, }; for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) { @@ -967,8 +960,6 @@ static void riscv_cpu_reset_hold(Object *obj) } i++; } -/* mmte is supposed to have pm.current hardwired to 1 */ -env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT); /* * Bits 10, 6, 2 and 12 of mideleg are read only 1 when the Hypervisor @@ -990,7 +981,6 @@ static void riscv_cpu_reset_hold(Object *obj) pmp_unlock_entries(env); #endif env->xl = riscv_cpu_mxl(env); -riscv_cpu_update_mask(env); cs->exception_index = RISCV_EXCP_NONE; env->load_res = -1; set_default_nan_mode(1, &env->fp_status); @@ -1349,7 +1339,6 @@ static const MISAExtInfo misa_ext_info_arr[] = { MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"), MISA_EXT_INFO(RVU, "u", "User-level instructions"), MISA_EXT_INFO(RVH, "h", "Hypervisor"), -MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"), MISA_EXT_INFO(RVV, "v", "Vector operations"), MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"), MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)") diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 5138187727..c64ed19741 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -67,7 +67,6 @@ typedef struct CPUArchState CPURISCVState; #define RVS RV('S') #define RVU RV('U') #define RVH RV('H') -#define RVJ RV('J') #define RVG RV('G') #define RVB RV('B') @@ -395,17 +394,6 @@ struct CPUArchState { /* True if in debugger mode. */ bool debugger; -/* - * CSRs for PointerMasking extension - */ -target_ulong mmte; -target_ulong mpmmask; -target_ulong mpmbase; -target_ulong spmmask; -target_ulong spmbase; -target_ulong upmmask; -target_ulong upmbase; - /* CSRs for execution environment configuration */ uint64_t menvcfg; uint64_t mstateen[SMSTATEEN_MAX_COUNT]; @@ -414,9 +402,6 @@ struct CPUArchState { target_ulong senvcfg; uint64_t henvcfg; #endif -target_ulong cur_pmmask; -target_ulong cur_pmbase; - /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */ @@ -564,16 +549,14 @@ FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 16, 2) /* If PointerMasking should be applied */ -FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1) -FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1) -FIELD(TB_FLAGS, VTA, 20, 1) -FIELD(TB_FLAGS, VMA, 21, 1) +FIELD(TB_FLAGS, VTA, 18, 1) +FIELD(TB_FLAGS, VMA, 19, 1) /* Native debug itrigger */ -FIELD(TB_FLAGS, ITRIGGER, 22, 1) +FIELD(TB_FLAGS, ITRIGGER, 20, 1) /* Virtual mode enabled */ -FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) -FIELD(TB_FLAGS, PRIV, 24, 2) -FIELD(TB_FLAGS, AXL, 26, 2) +FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) +FIELD(TB_FLAGS, PRIV, 22, 2) +FIELD(TB_FLAGS, AXL, 24, 2) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) @@ -706,7 +689,6 @@ static inline uint32_t vext_get_vlm
[PATCH v7 0/6] Pointer Masking update for Zjpm v0.8
From: Alexey Baturo Hi, I'm terribly sorry, but previous rebase went wrong and somehow I missed it. This time I double-checked rebased version. This patch series is properly rebased on https://github.com/alistair23/qemu/tree/riscv-to-apply.next Thanks [v6]: This patch series is rebased on https://github.com/alistair23/qemu/tree/riscv-to-apply.next [v5]: This patch series targets Zjpm v0.8 extension. The spec itself could be found here: https://github.com/riscv/riscv-j-extension/blob/8088461d8d66a7676872b61c908cbeb7cf5c5d1d/zjpm-spec.pdf This patch series is updated after the suggested comments: - add "x-" to the extension names to indicate experimental [v4]: Patch series updated after the suggested comments: - removed J-letter extension as it's unused - renamed and fixed function to detect if address should be sign-extended - zeroed unused context variables and moved computation logic to another patch - bumped pointer masking version_id and minimum_version_id by 1 [v3]: There patches are updated after Richard's comments: - moved new tb flags to the end - used tcg_gen_(s)extract to get the final address - properly handle CONFIG_USER_ONLY [v2]: As per Richard's suggestion I made pmm field part of tb_flags. It allowed to get rid of global variable to store pmlen. Also it allowed to simplify all the machinery around it. [v1]: It looks like Zjpm v0.8 is almost frozen and we don't expect it change drastically anymore. Compared to the original implementation with explicit base and mask CSRs, we now only have several fixed options for number of masked bits which are set using existing CSRs. The changes have been tested with handwritten assembly tests and LLVM HWASAN test suite. Alexey Baturo (6): target/riscv: Remove obsolete pointer masking extension code. target/riscv: Add new CSR fields for S{sn,mn,m}pm extensions as part of Zjpm v0.8 target/riscv: Add helper functions to calculate current number of masked bits for pointer masking target/riscv: Add pointer masking tb flags target/riscv: Update address modify functions to take into account pointer masking target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension target/riscv/cpu.c | 22 ++- target/riscv/cpu.h | 45 +++-- target/riscv/cpu_bits.h | 90 +- target/riscv/cpu_cfg.h | 3 + target/riscv/cpu_helper.c| 97 +- target/riscv/csr.c | 337 ++- target/riscv/machine.c | 20 +-- target/riscv/pmp.c | 13 +- target/riscv/pmp.h | 11 +- target/riscv/tcg/tcg-cpu.c | 5 +- target/riscv/translate.c | 46 ++--- target/riscv/vector_helper.c | 15 +- 12 files changed, 158 insertions(+), 546 deletions(-) -- 2.34.1
[PATCH v7 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/cpu.h| 4 +++ target/riscv/cpu_helper.c | 58 +++ 2 files changed, 62 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 4c0d7142a5..23a166a91f 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -699,6 +699,10 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, bool riscv_cpu_is_32bit(RISCVCPU *cpu); +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env); +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env); +int riscv_pm_get_pmlen(RISCVPmPmm pmm); + RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index aedd5bef50..bef7917668 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -142,6 +142,64 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, *pflags = flags; } +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env) +{ +int pmm = 0; +#ifndef CONFIG_USER_ONLY +int priv_mode = cpu_address_mode(env); +/* Get current PMM field */ +switch (priv_mode) { +case PRV_M: +pmm = riscv_cpu_cfg(env)->ext_smmpm ? + get_field(env->mseccfg, MSECCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_S: +pmm = riscv_cpu_cfg(env)->ext_smnpm ? + get_field(env->menvcfg, MENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_U: +pmm = riscv_cpu_cfg(env)->ext_ssnpm ? + get_field(env->senvcfg, SENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +default: +g_assert_not_reached(); +} +#endif +return pmm; +} + +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env) +{ +bool virt_mem_en = false; +#ifndef CONFIG_USER_ONLY +int satp_mode = 0; +int priv_mode = cpu_address_mode(env); +/* Get current PMM field */ +if (riscv_cpu_mxl(env) == MXL_RV32) { +satp_mode = get_field(env->satp, SATP32_MODE); +} else { +satp_mode = get_field(env->satp, SATP64_MODE); +} +virt_mem_en = ((satp_mode != VM_1_10_MBARE) && (priv_mode != PRV_M)); +#endif +return virt_mem_en; +} + +int riscv_pm_get_pmlen(RISCVPmPmm pmm) +{ +switch (pmm) { +case PMM_FIELD_DISABLED: +return 0; +case PMM_FIELD_PMLEN7: +return 7; +case PMM_FIELD_PMLEN16: +return 16; +default: +g_assert_not_reached(); +} +return -1; +} + #ifndef CONFIG_USER_ONLY /* -- 2.34.1
[PATCH v7 5/6] target/riscv: Update address modify functions to take into account pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis --- target/riscv/translate.c | 22 -- target/riscv/vector_helper.c | 13 + 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 6bc338bd1f..89f10744a2 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -579,8 +579,10 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_addi_tl(addr, src1, imm); -if (get_address_xl(ctx) == MXL_RV32) { -tcg_gen_ext32u_tl(addr, addr); +if (ctx->addr_signed) { +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width); +} else { +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width); } return addr; @@ -593,8 +595,10 @@ static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_add_tl(addr, src1, offs); -if (get_xl(ctx) == MXL_RV32) { -tcg_gen_ext32u_tl(addr, addr); +if (ctx->addr_signed) { +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width); +} else { +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width); } return addr; } @@ -1180,8 +1184,14 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; -ctx->addr_width = 0; -ctx->addr_signed = false; +if (get_xl(ctx) == MXL_RV32) { +ctx->addr_width = 32; +ctx->addr_signed = false; +} else { +int pm_pmm = FIELD_EX32(tb_flags, TB_FLAGS, PM_PMM); +ctx->addr_width = 64 - riscv_pm_get_pmlen(pm_pmm); +ctx->addr_signed = FIELD_EX32(tb_flags, TB_FLAGS, PM_SIGNEXTEND); +} ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); ctx->virt_inst_excp = false; diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index f6be88dcf0..9d1d627d64 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -105,6 +105,19 @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz) static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr) { +RISCVPmPmm pmm = riscv_pm_get_pmm(env); +if (pmm == PMM_FIELD_DISABLED) { +return addr; +} +int pmlen = riscv_pm_get_pmlen(pmm); +bool signext = riscv_cpu_virt_mem_enabled(env); +addr = addr << pmlen; +/* sign/zero extend masked address by N-1 bit */ +if (signext) { +addr = (target_long)addr >> pmlen; +} else { +addr = addr >> pmlen; +} return addr; } -- 2.34.1
[PATCH v7 4/6] target/riscv: Add pointer masking tb flags
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis --- target/riscv/cpu.h| 3 +++ target/riscv/cpu_helper.c | 3 +++ target/riscv/translate.c | 5 + 3 files changed, 11 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 23a166a91f..798d16ef2e 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -565,6 +565,9 @@ FIELD(TB_FLAGS, ITRIGGER, 20, 1) FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) FIELD(TB_FLAGS, PRIV, 22, 2) FIELD(TB_FLAGS, AXL, 24, 2) +/* If pointer masking should be applied and address sign extended */ +FIELD(TB_FLAGS, PM_PMM, 26, 2) +FIELD(TB_FLAGS, PM_SIGNEXTEND, 28, 1) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index bef7917668..29622b649c 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -68,6 +68,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, RISCVCPU *cpu = env_archcpu(env); RISCVExtStatus fs, vs; uint32_t flags = 0; +bool pm_signext = riscv_cpu_virt_mem_enabled(env); *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc; *cs_base = 0; @@ -138,6 +139,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, flags = FIELD_DP32(flags, TB_FLAGS, VS, vs); flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl); flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext); *pflags = flags; } diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 1d5dbf3259..6bc338bd1f 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -103,6 +103,9 @@ typedef struct DisasContext { bool vl_eq_vlmax; CPUState *cs; TCGv zero; +/* actual address width */ +uint8_t addr_width; +bool addr_signed; /* Use icount trigger for native debug */ bool itrigger; /* FRM is known to contain a valid value. */ @@ -1177,6 +1180,8 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; +ctx->addr_width = 0; +ctx->addr_signed = false; ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); ctx->virt_inst_excp = false; -- 2.34.1
[PATCH v7 2/6] target/riscv: Add new CSR fields for S{sn, mn, m}pm extensions as part of Zjpm v0.8
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/cpu.h | 8 target/riscv/cpu_bits.h | 3 +++ target/riscv/cpu_cfg.h | 3 +++ target/riscv/csr.c | 11 +++ target/riscv/machine.c | 10 +++--- target/riscv/pmp.c | 13 ++--- target/riscv/pmp.h | 11 ++- 7 files changed, 48 insertions(+), 11 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index c64ed19741..4c0d7142a5 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -122,6 +122,14 @@ typedef enum { EXT_STATUS_DIRTY, } RISCVExtStatus; +/* Enum holds PMM field values for Zjpm v0.8 extension */ +typedef enum { +PMM_FIELD_DISABLED = 0, +PMM_FIELD_RESERVED = 1, +PMM_FIELD_PMLEN7 = 2, +PMM_FIELD_PMLEN16 = 3, +} RISCVPmPmm; + #define MMU_USER_IDX 3 #define MAX_RISCV_PMPS (16) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 4d8e7ea0d5..5b7ab71e5f 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -716,6 +716,7 @@ typedef enum RISCVException { #define MENVCFG_CBIE (3UL << 4) #define MENVCFG_CBCFE BIT(6) #define MENVCFG_CBZE BIT(7) +#define MENVCFG_PMM(3ULL << 32) #define MENVCFG_ADUE (1ULL << 61) #define MENVCFG_PBMTE (1ULL << 62) #define MENVCFG_STCE (1ULL << 63) @@ -729,11 +730,13 @@ typedef enum RISCVException { #define SENVCFG_CBIE MENVCFG_CBIE #define SENVCFG_CBCFE MENVCFG_CBCFE #define SENVCFG_CBZE MENVCFG_CBZE +#define SENVCFG_PMMMENVCFG_PMM #define HENVCFG_FIOM MENVCFG_FIOM #define HENVCFG_CBIE MENVCFG_CBIE #define HENVCFG_CBCFE MENVCFG_CBCFE #define HENVCFG_CBZE MENVCFG_CBZE +#define HENVCFG_PMMMENVCFG_PMM #define HENVCFG_ADUE MENVCFG_ADUE #define HENVCFG_PBMTE MENVCFG_PBMTE #define HENVCFG_STCE MENVCFG_STCE diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index e241922f89..9e5a089894 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -115,6 +115,9 @@ struct RISCVCPUConfig { bool ext_ssaia; bool ext_sscofpmf; bool ext_smepmp; +bool ext_ssnpm; +bool ext_smnpm; +bool ext_smmpm; bool rvv_ta_all_1s; bool rvv_ma_all_1s; bool svade; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 32a40f2365..431dc4ac1e 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -530,6 +530,9 @@ static RISCVException have_mseccfg(CPURISCVState *env, int csrno) if (riscv_cpu_cfg(env)->ext_zkr) { return RISCV_EXCP_NONE; } +if (riscv_cpu_cfg(env)->ext_smmpm) { +return RISCV_EXCP_NONE; +} return RISCV_EXCP_ILLEGAL_INST; } @@ -2036,6 +2039,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, (cfg->ext_sstc ? MENVCFG_STCE : 0) | (cfg->ext_svadu ? MENVCFG_ADUE : 0); } +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & MENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= MENVCFG_PMM; +} env->menvcfg = (env->menvcfg & ~mask) | (val & mask); return RISCV_EXCP_NONE; @@ -2080,6 +2087,10 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, target_ulong val) { uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE; +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & SENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= SENVCFG_PMM; +} RISCVException ret; ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG); diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 9c71a1a22f..75dec28587 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -152,15 +152,19 @@ static const VMStateDescription vmstate_vector = { static bool pointermasking_needed(void *opaque) { -return false; +RISCVCPU *cpu = opaque; +return cpu->cfg.ext_ssnpm || cpu->cfg.ext_smnpm || cpu->cfg.ext_smmpm; } static const VMStateDescription vmstate_pointermasking = { .name = "cpu/pointer_masking", -.version_id = 1, -.minimum_version_id = 1, +.version_id = 2, +.minimum_version_id = 2, .needed = pointermasking_needed, .fields = (const VMStateField[]) { +VMSTATE_UINTTL(env.mseccfg, RISCVCPU), +VMSTATE_UINTTL(env.senvcfg, RISCVCPU), +VMSTATE_UINTTL(env.menvcfg, RISCVCPU), VMSTATE_END_OF_LIST() } };
[PATCH v6 1/6] target/riscv: Remove obsolete pointer masking extension code.
From: Alexey Baturo Zjpm v0.8 is almost frozen and it's much simplier compared to the existing one: The newer version doesn't allow to specify custom mask or base for masking. Instead it allows only certain options for masking top bits. Signed-off-by: Alexey Baturo Acked-by: Alistair Francis --- target/riscv/cpu.c | 13 +- target/riscv/cpu.h | 32 +++-- target/riscv/cpu_bits.h | 87 target/riscv/cpu_helper.c| 52 - target/riscv/csr.c | 30 - target/riscv/machine.c | 16 +-- target/riscv/tcg/tcg-cpu.c | 5 +-- target/riscv/translate.c | 27 +-- target/riscv/vector_helper.c | 2 +- 9 files changed, 15 insertions(+), 249 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 88e8cc8681..ded84f2e09 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -41,7 +41,7 @@ /* RISC-V CPU definitions */ static const char riscv_single_letter_exts[] = "IEMAFDQCBPVH"; const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV, - RVC, RVS, RVU, RVH, RVJ, RVG, RVB, 0}; + RVC, RVS, RVU, RVH, RVG, RVB, 0}; /* * From vector_helper.c @@ -786,13 +786,6 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) CSR_MSCRATCH, CSR_SSCRATCH, CSR_SATP, -CSR_MMTE, -CSR_UPMBASE, -CSR_UPMMASK, -CSR_SPMBASE, -CSR_SPMMASK, -CSR_MPMBASE, -CSR_MPMMASK, }; for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) { @@ -967,8 +960,6 @@ static void riscv_cpu_reset_hold(Object *obj) } i++; } -/* mmte is supposed to have pm.current hardwired to 1 */ -env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT); /* * Bits 10, 6, 2 and 12 of mideleg are read only 1 when the Hypervisor @@ -990,7 +981,6 @@ static void riscv_cpu_reset_hold(Object *obj) pmp_unlock_entries(env); #endif env->xl = riscv_cpu_mxl(env); -riscv_cpu_update_mask(env); cs->exception_index = RISCV_EXCP_NONE; env->load_res = -1; set_default_nan_mode(1, &env->fp_status); @@ -1349,7 +1339,6 @@ static const MISAExtInfo misa_ext_info_arr[] = { MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"), MISA_EXT_INFO(RVU, "u", "User-level instructions"), MISA_EXT_INFO(RVH, "h", "Hypervisor"), -MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"), MISA_EXT_INFO(RVV, "v", "Vector operations"), MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"), MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)") diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 5138187727..dfa80bf24d 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -67,7 +67,6 @@ typedef struct CPUArchState CPURISCVState; #define RVS RV('S') #define RVU RV('U') #define RVH RV('H') -#define RVJ RV('J') #define RVG RV('G') #define RVB RV('B') @@ -395,18 +394,7 @@ struct CPUArchState { /* True if in debugger mode. */ bool debugger; -/* - * CSRs for PointerMasking extension - */ -target_ulong mmte; -target_ulong mpmmask; -target_ulong mpmbase; -target_ulong spmmask; -target_ulong spmbase; -target_ulong upmmask; -target_ulong upmbase; - -/* CSRs for execution environment configuration */ +/* CSRs for execution enviornment configuration */ uint64_t menvcfg; uint64_t mstateen[SMSTATEEN_MAX_COUNT]; uint64_t hstateen[SMSTATEEN_MAX_COUNT]; @@ -414,8 +402,6 @@ struct CPUArchState { target_ulong senvcfg; uint64_t henvcfg; #endif -target_ulong cur_pmmask; -target_ulong cur_pmbase; /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ @@ -563,17 +549,14 @@ FIELD(TB_FLAGS, VILL, 14, 1) FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 16, 2) -/* If PointerMasking should be applied */ -FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1) -FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1) -FIELD(TB_FLAGS, VTA, 20, 1) -FIELD(TB_FLAGS, VMA, 21, 1) +FIELD(TB_FLAGS, VTA, 18, 1) +FIELD(TB_FLAGS, VMA, 19, 1) /* Native debug itrigger */ -FIELD(TB_FLAGS, ITRIGGER, 22, 1) +FIELD(TB_FLAGS, ITRIGGER, 20, 1) /* Virtual mode enabled */ -FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) -FIELD(TB_FLAGS, PRIV, 24, 2) -FIELD(TB_FLAGS, AXL, 26, 2) +FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) +FIELD(TB_FLAGS, PRIV, 22, 2) +FIELD(TB_FLAGS, AXL, 24, 2) #ifdef TARGET_RISCV32 #d
[PATCH v6 5/6] target/riscv: Update address modify functions to take into account pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis --- target/riscv/translate.c | 22 -- target/riscv/vector_helper.c | 13 + 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index e40a31f8db..f2b00fcdb8 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -579,8 +579,10 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_addi_tl(addr, src1, imm); -if (get_address_xl(ctx) == MXL_RV32) { -tcg_gen_ext32u_tl(addr, addr); +if (ctx->addr_signed) { +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width); +} else { +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width); } return addr; @@ -593,8 +595,10 @@ static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_add_tl(addr, src1, offs); -if (get_xl(ctx) == MXL_RV32) { -tcg_gen_ext32u_tl(addr, addr); +if (ctx->addr_signed) { +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width); +} else { +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width); } return addr; } @@ -1180,8 +1184,14 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; -ctx->addr_width = 0; -ctx->addr_signed = false; +if (get_xl(ctx) == MXL_RV32) { +ctx->addr_width = 32; +ctx->addr_signed = false; +} else { +int pm_pmm = FIELD_EX32(tb_flags, TB_FLAGS, PM_PMM); +ctx->addr_width = 64 - riscv_pm_get_pmlen(pm_pmm); +ctx->addr_signed = FIELD_EX32(tb_flags, TB_FLAGS, PM_SIGNEXTEND); +} ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); ctx->virt_inst_excp = false; diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index f6be88dcf0..9d1d627d64 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -105,6 +105,19 @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz) static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr) { +RISCVPmPmm pmm = riscv_pm_get_pmm(env); +if (pmm == PMM_FIELD_DISABLED) { +return addr; +} +int pmlen = riscv_pm_get_pmlen(pmm); +bool signext = riscv_cpu_virt_mem_enabled(env); +addr = addr << pmlen; +/* sign/zero extend masked address by N-1 bit */ +if (signext) { +addr = (target_long)addr >> pmlen; +} else { +addr = addr >> pmlen; +} return addr; } -- 2.34.1
[PATCH v6 0/6] Pointer Masking update for Zjpm v0.8
From: Alexey Baturo Hi, This patch series is rebased on https://github.com/alistair23/qemu/tree/riscv-to-apply.next Thanks [v5]: This patch series targets Zjpm v0.8 extension. The spec itself could be found here: https://github.com/riscv/riscv-j-extension/blob/8088461d8d66a7676872b61c908cbeb7cf5c5d1d/zjpm-spec.pdf This patch series is updated after the suggested comments: - add "x-" to the extension names to indicate experimental [v4]: Patch series updated after the suggested comments: - removed J-letter extension as it's unused - renamed and fixed function to detect if address should be sign-extended - zeroed unused context variables and moved computation logic to another patch - bumped pointer masking version_id and minimum_version_id by 1 [v3]: There patches are updated after Richard's comments: - moved new tb flags to the end - used tcg_gen_(s)extract to get the final address - properly handle CONFIG_USER_ONLY [v2]: As per Richard's suggestion I made pmm field part of tb_flags. It allowed to get rid of global variable to store pmlen. Also it allowed to simplify all the machinery around it. [v1]: It looks like Zjpm v0.8 is almost frozen and we don't expect it change drastically anymore. Compared to the original implementation with explicit base and mask CSRs, we now only have several fixed options for number of masked bits which are set using existing CSRs. The changes have been tested with handwritten assembly tests and LLVM HWASAN test suite. Alexey Baturo (6): target/riscv: Remove obsolete pointer masking extension code. target/riscv: Add new CSR fields for S{sn,mn,m}pm extensions as part of Zjpm v0.8 target/riscv: Add helper functions to calculate current number of masked bits for pointer masking target/riscv: Add pointer masking tb flags target/riscv: Update address modify functions to take into account pointer masking target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension target/riscv/cpu.c | 22 target/riscv/cpu.h | 47 - target/riscv/cpu_bits.h | 90 ++--- target/riscv/cpu_cfg.h | 3 ++ target/riscv/cpu_helper.c| 97 target/riscv/csr.c | 41 --- target/riscv/machine.c | 22 +++- target/riscv/pmp.c | 13 +++-- target/riscv/pmp.h | 11 ++-- target/riscv/tcg/tcg-cpu.c | 5 +- target/riscv/translate.c | 46 +++-- target/riscv/vector_helper.c | 15 +- 12 files changed, 160 insertions(+), 252 deletions(-) -- 2.34.1
[PATCH v6 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/cpu.h| 4 +++ target/riscv/cpu_helper.c | 58 +++ 2 files changed, 62 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index e03ff3003f..96b554a00e 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -699,6 +699,10 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, bool riscv_cpu_is_32bit(RISCVCPU *cpu); +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env); +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env); +int riscv_pm_get_pmlen(RISCVPmPmm pmm); + RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index aedd5bef50..bef7917668 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -142,6 +142,64 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, *pflags = flags; } +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env) +{ +int pmm = 0; +#ifndef CONFIG_USER_ONLY +int priv_mode = cpu_address_mode(env); +/* Get current PMM field */ +switch (priv_mode) { +case PRV_M: +pmm = riscv_cpu_cfg(env)->ext_smmpm ? + get_field(env->mseccfg, MSECCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_S: +pmm = riscv_cpu_cfg(env)->ext_smnpm ? + get_field(env->menvcfg, MENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_U: +pmm = riscv_cpu_cfg(env)->ext_ssnpm ? + get_field(env->senvcfg, SENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +default: +g_assert_not_reached(); +} +#endif +return pmm; +} + +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env) +{ +bool virt_mem_en = false; +#ifndef CONFIG_USER_ONLY +int satp_mode = 0; +int priv_mode = cpu_address_mode(env); +/* Get current PMM field */ +if (riscv_cpu_mxl(env) == MXL_RV32) { +satp_mode = get_field(env->satp, SATP32_MODE); +} else { +satp_mode = get_field(env->satp, SATP64_MODE); +} +virt_mem_en = ((satp_mode != VM_1_10_MBARE) && (priv_mode != PRV_M)); +#endif +return virt_mem_en; +} + +int riscv_pm_get_pmlen(RISCVPmPmm pmm) +{ +switch (pmm) { +case PMM_FIELD_DISABLED: +return 0; +case PMM_FIELD_PMLEN7: +return 7; +case PMM_FIELD_PMLEN16: +return 16; +default: +g_assert_not_reached(); +} +return -1; +} + #ifndef CONFIG_USER_ONLY /* -- 2.34.1
[PATCH v6 4/6] target/riscv: Add pointer masking tb flags
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis --- target/riscv/cpu.h| 3 +++ target/riscv/cpu_helper.c | 3 +++ target/riscv/translate.c | 5 + 3 files changed, 11 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 96b554a00e..e9eb8df1be 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -565,6 +565,9 @@ FIELD(TB_FLAGS, ITRIGGER, 20, 1) FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) FIELD(TB_FLAGS, PRIV, 22, 2) FIELD(TB_FLAGS, AXL, 24, 2) +/* If pointer masking should be applied and address sign extended */ +FIELD(TB_FLAGS, PM_PMM, 26, 2) +FIELD(TB_FLAGS, PM_SIGNEXTEND, 28, 1) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index bef7917668..29622b649c 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -68,6 +68,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, RISCVCPU *cpu = env_archcpu(env); RISCVExtStatus fs, vs; uint32_t flags = 0; +bool pm_signext = riscv_cpu_virt_mem_enabled(env); *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc; *cs_base = 0; @@ -138,6 +139,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, flags = FIELD_DP32(flags, TB_FLAGS, VS, vs); flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl); flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext); *pflags = flags; } diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 9785ccb03d..e40a31f8db 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -103,6 +103,9 @@ typedef struct DisasContext { bool vl_eq_vlmax; CPUState *cs; TCGv zero; +/* actual address width */ +uint8_t addr_width; +bool addr_signed; /* Use icount trigger for native debug */ bool itrigger; /* FRM is known to contain a valid value. */ @@ -1177,6 +1180,8 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; +ctx->addr_width = 0; +ctx->addr_signed = false; ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); ctx->virt_inst_excp = false; -- 2.34.1
[PATCH v6 2/6] target/riscv: Add new CSR fields for S{sn, mn, m}pm extensions as part of Zjpm v0.8
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/cpu.h | 8 target/riscv/cpu_bits.h | 3 +++ target/riscv/cpu_cfg.h | 3 +++ target/riscv/csr.c | 11 +++ target/riscv/machine.c | 10 +++--- target/riscv/pmp.c | 13 ++--- target/riscv/pmp.h | 11 ++- 7 files changed, 48 insertions(+), 11 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index dfa80bf24d..e03ff3003f 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -122,6 +122,14 @@ typedef enum { EXT_STATUS_DIRTY, } RISCVExtStatus; +/* Enum holds PMM field values for Zjpm v0.8 extension */ +typedef enum { +PMM_FIELD_DISABLED = 0, +PMM_FIELD_RESERVED = 1, +PMM_FIELD_PMLEN7 = 2, +PMM_FIELD_PMLEN16 = 3, +} RISCVPmPmm; + #define MMU_USER_IDX 3 #define MAX_RISCV_PMPS (16) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 4d8e7ea0d5..5b7ab71e5f 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -716,6 +716,7 @@ typedef enum RISCVException { #define MENVCFG_CBIE (3UL << 4) #define MENVCFG_CBCFE BIT(6) #define MENVCFG_CBZE BIT(7) +#define MENVCFG_PMM(3ULL << 32) #define MENVCFG_ADUE (1ULL << 61) #define MENVCFG_PBMTE (1ULL << 62) #define MENVCFG_STCE (1ULL << 63) @@ -729,11 +730,13 @@ typedef enum RISCVException { #define SENVCFG_CBIE MENVCFG_CBIE #define SENVCFG_CBCFE MENVCFG_CBCFE #define SENVCFG_CBZE MENVCFG_CBZE +#define SENVCFG_PMMMENVCFG_PMM #define HENVCFG_FIOM MENVCFG_FIOM #define HENVCFG_CBIE MENVCFG_CBIE #define HENVCFG_CBCFE MENVCFG_CBCFE #define HENVCFG_CBZE MENVCFG_CBZE +#define HENVCFG_PMMMENVCFG_PMM #define HENVCFG_ADUE MENVCFG_ADUE #define HENVCFG_PBMTE MENVCFG_PBMTE #define HENVCFG_STCE MENVCFG_STCE diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index e241922f89..9e5a089894 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -115,6 +115,9 @@ struct RISCVCPUConfig { bool ext_ssaia; bool ext_sscofpmf; bool ext_smepmp; +bool ext_ssnpm; +bool ext_smnpm; +bool ext_smmpm; bool rvv_ta_all_1s; bool rvv_ma_all_1s; bool svade; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 4166cf79a9..07f05906b5 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -530,6 +530,9 @@ static RISCVException have_mseccfg(CPURISCVState *env, int csrno) if (riscv_cpu_cfg(env)->ext_zkr) { return RISCV_EXCP_NONE; } +if (riscv_cpu_cfg(env)->ext_smmpm) { +return RISCV_EXCP_NONE; +} return RISCV_EXCP_ILLEGAL_INST; } @@ -2036,6 +2039,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, (cfg->ext_sstc ? MENVCFG_STCE : 0) | (cfg->ext_svadu ? MENVCFG_ADUE : 0); } +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & MENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= MENVCFG_PMM; +} env->menvcfg = (env->menvcfg & ~mask) | (val & mask); return RISCV_EXCP_NONE; @@ -2080,6 +2087,10 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, target_ulong val) { uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE; +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & SENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= SENVCFG_PMM; +} RISCVException ret; ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG); diff --git a/target/riscv/machine.c b/target/riscv/machine.c index e0878af655..7ae12d0d72 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -152,15 +152,19 @@ static const VMStateDescription vmstate_vector = { static bool pointermasking_needed(void *opaque) { -return false; +RISCVCPU *cpu = opaque; +return cpu->cfg.ext_ssnpm || cpu->cfg.ext_smnpm || cpu->cfg.ext_smmpm; } static const VMStateDescription vmstate_pointermasking = { .name = "cpu/pointer_masking", -.version_id = 1, -.minimum_version_id = 1, +.version_id = 2, +.minimum_version_id = 2, .needed = pointermasking_needed, .fields = (VMStateField[]) { +VMSTATE_UINTTL(env.mseccfg, RISCVCPU), +VMSTATE_UINTTL(env.senvcfg, RISCVCPU), +VMSTATE_UINTTL(env.menvcfg, RISCVCPU), VMSTATE_END_OF_LIST() } }; diff -
[PATCH v6 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/cpu.c | 9 + 1 file changed, 9 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index ded84f2e09..23d1692b59 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -175,6 +175,9 @@ const RISCVIsaExtData isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval), ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot), ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt), +ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_12_0, ext_ssnpm), +ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_12_0, ext_smnpm), +ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_12_0, ext_smmpm), ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba), ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb), ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs), @@ -1496,6 +1499,12 @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = { MULTI_EXT_CFG_BOOL("x-zvfbfmin", ext_zvfbfmin, false), MULTI_EXT_CFG_BOOL("x-zvfbfwma", ext_zvfbfwma, false), +/* Zjpm v0.8 extensions */ +MULTI_EXT_CFG_BOOL("x-ssnpm", ext_ssnpm, false), +MULTI_EXT_CFG_BOOL("x-smnpm", ext_smnpm, false), +MULTI_EXT_CFG_BOOL("x-smmpm", ext_smmpm, false), + + DEFINE_PROP_END_OF_LIST(), }; -- 2.34.1
[PATCH v5 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.h| 4 +++ target/riscv/cpu_helper.c | 58 +++ 2 files changed, 62 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index c9bed5c9fc..1c8979c1c8 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -671,6 +671,10 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, uint64_t *cs_base, uint32_t *pflags); +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env); +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env); +int riscv_pm_get_pmlen(RISCVPmPmm pmm); + RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index a3d477d226..9640e4c2c5 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -139,6 +139,64 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, *pflags = flags; } +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env) +{ +int pmm = 0; +#ifndef CONFIG_USER_ONLY +int priv_mode = cpu_address_mode(env); +/* Get current PMM field */ +switch (priv_mode) { +case PRV_M: +pmm = riscv_cpu_cfg(env)->ext_smmpm ? + get_field(env->mseccfg, MSECCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_S: +pmm = riscv_cpu_cfg(env)->ext_smnpm ? + get_field(env->menvcfg, MENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_U: +pmm = riscv_cpu_cfg(env)->ext_ssnpm ? + get_field(env->senvcfg, SENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +default: +g_assert_not_reached(); +} +#endif +return pmm; +} + +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env) +{ +bool virt_mem_en = false; +#ifndef CONFIG_USER_ONLY +int satp_mode = 0; +int priv_mode = cpu_address_mode(env); +/* Get current PMM field */ +if (riscv_cpu_mxl(env) == MXL_RV32) { +satp_mode = get_field(env->satp, SATP32_MODE); +} else { +satp_mode = get_field(env->satp, SATP64_MODE); +} +virt_mem_en = ((satp_mode != VM_1_10_MBARE) && (priv_mode != PRV_M)); +#endif +return virt_mem_en; +} + +int riscv_pm_get_pmlen(RISCVPmPmm pmm) +{ +switch (pmm) { +case PMM_FIELD_DISABLED: +return 0; +case PMM_FIELD_PMLEN7: +return 7; +case PMM_FIELD_PMLEN16: +return 16; +default: +g_assert_not_reached(); +} +return -1; +} + #ifndef CONFIG_USER_ONLY /* -- 2.34.1
[PATCH v5 5/6] target/riscv: Update address modify functions to take into account pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis --- target/riscv/translate.c | 22 -- target/riscv/vector_helper.c | 13 + 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 2c89d749c0..457de381c7 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -579,8 +579,10 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_addi_tl(addr, src1, imm); -if (get_address_xl(ctx) == MXL_RV32) { -tcg_gen_ext32u_tl(addr, addr); +if (ctx->addr_signed) { +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width); +} else { +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width); } return addr; @@ -593,8 +595,10 @@ static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_add_tl(addr, src1, offs); -if (get_xl(ctx) == MXL_RV32) { -tcg_gen_ext32u_tl(addr, addr); +if (ctx->addr_signed) { +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width); +} else { +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width); } return addr; } @@ -1179,8 +1183,14 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; -ctx->addr_width = 0; -ctx->addr_signed = false; +if (get_xl(ctx) == MXL_RV32) { +ctx->addr_width = 32; +ctx->addr_signed = false; +} else { +int pm_pmm = FIELD_EX32(tb_flags, TB_FLAGS, PM_PMM); +ctx->addr_width = 64 - riscv_pm_get_pmlen(pm_pmm); +ctx->addr_signed = FIELD_EX32(tb_flags, TB_FLAGS, PM_SIGNEXTEND); +} ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); ctx->virt_inst_excp = false; diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 8e7a8e80a0..ff1178723c 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -94,6 +94,19 @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz) static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr) { +RISCVPmPmm pmm = riscv_pm_get_pmm(env); +if (pmm == PMM_FIELD_DISABLED) { +return addr; +} +int pmlen = riscv_pm_get_pmlen(pmm); +bool signext = riscv_cpu_virt_mem_enabled(env); +addr = addr << pmlen; +/* sign/zero extend masked address by N-1 bit */ +if (signext) { +addr = (target_long)addr >> pmlen; +} else { +addr = addr >> pmlen; +} return addr; } -- 2.34.1
[PATCH v5 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.c | 9 + 1 file changed, 9 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index d8de1f1890..bf431ab728 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -153,6 +153,9 @@ const RISCVIsaExtData isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval), ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot), ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt), +ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_12_0, ext_ssnpm), +ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_12_0, ext_smnpm), +ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_12_0, ext_smmpm), ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba), ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb), ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs), @@ -1395,6 +1398,12 @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = { MULTI_EXT_CFG_BOOL("x-zvfbfmin", ext_zvfbfmin, false), MULTI_EXT_CFG_BOOL("x-zvfbfwma", ext_zvfbfwma, false), +/* Zjpm v0.8 extensions */ +MULTI_EXT_CFG_BOOL("x-ssnpm", ext_ssnpm, false), +MULTI_EXT_CFG_BOOL("x-smnpm", ext_smnpm, false), +MULTI_EXT_CFG_BOOL("x-smmpm", ext_smmpm, false), + + DEFINE_PROP_END_OF_LIST(), }; -- 2.34.1
[PATCH v5 4/6] target/riscv: Add pointer masking tb flags
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis --- target/riscv/cpu.h| 3 +++ target/riscv/cpu_helper.c | 3 +++ target/riscv/translate.c | 5 + 3 files changed, 11 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 1c8979c1c8..0284ea418f 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -545,6 +545,9 @@ FIELD(TB_FLAGS, ITRIGGER, 20, 1) FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) FIELD(TB_FLAGS, PRIV, 22, 2) FIELD(TB_FLAGS, AXL, 24, 2) +/* If pointer masking should be applied and address sign extended */ +FIELD(TB_FLAGS, PM_PMM, 26, 2) +FIELD(TB_FLAGS, PM_SIGNEXTEND, 28, 1) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 9640e4c2c5..67bc51e510 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -68,6 +68,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, RISCVCPU *cpu = env_archcpu(env); RISCVExtStatus fs, vs; uint32_t flags = 0; +bool pm_signext = riscv_cpu_virt_mem_enabled(env); *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc; *cs_base = 0; @@ -135,6 +136,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, flags = FIELD_DP32(flags, TB_FLAGS, VS, vs); flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl); flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext); *pflags = flags; } diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 6b4b9a671c..2c89d749c0 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -103,6 +103,9 @@ typedef struct DisasContext { bool vl_eq_vlmax; CPUState *cs; TCGv zero; +/* actual address width */ +uint8_t addr_width; +bool addr_signed; /* Use icount trigger for native debug */ bool itrigger; /* FRM is known to contain a valid value. */ @@ -1176,6 +1179,8 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; +ctx->addr_width = 0; +ctx->addr_signed = false; ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); ctx->virt_inst_excp = false; -- 2.34.1
[PATCH v5 1/6] target/riscv: Remove obsolete pointer masking extension code.
From: Alexey Baturo Zjpm v0.8 is almost frozen and it's much simplier compared to the existing one: The newer version doesn't allow to specify custom mask or base for masking. Instead it allows only certain options for masking top bits. Signed-off-by: Alexey Baturo Acked-by: Alistair Francis --- target/riscv/cpu.c | 13 +- target/riscv/cpu.h | 33 +--- target/riscv/cpu_bits.h | 87 -- target/riscv/cpu_helper.c| 52 -- target/riscv/csr.c | 326 --- target/riscv/machine.c | 14 +- target/riscv/tcg/tcg-cpu.c | 5 +- target/riscv/translate.c | 27 +-- target/riscv/vector_helper.c | 2 +- 9 files changed, 14 insertions(+), 545 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 83c7c0cf07..d8de1f1890 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -40,7 +40,7 @@ /* RISC-V CPU definitions */ static const char riscv_single_letter_exts[] = "IEMAFDQCPVH"; const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV, - RVC, RVS, RVU, RVH, RVJ, RVG, 0}; + RVC, RVS, RVU, RVH, RVG, 0}; /* * From vector_helper.c @@ -710,13 +710,6 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) CSR_MSCRATCH, CSR_SSCRATCH, CSR_SATP, -CSR_MMTE, -CSR_UPMBASE, -CSR_UPMMASK, -CSR_SPMBASE, -CSR_SPMMASK, -CSR_MPMBASE, -CSR_MPMMASK, }; for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) { @@ -891,8 +884,6 @@ static void riscv_cpu_reset_hold(Object *obj) } i++; } -/* mmte is supposed to have pm.current hardwired to 1 */ -env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT); /* * Clear mseccfg and unlock all the PMP entries upon reset. @@ -906,7 +897,6 @@ static void riscv_cpu_reset_hold(Object *obj) pmp_unlock_entries(env); #endif env->xl = riscv_cpu_mxl(env); -riscv_cpu_update_mask(env); cs->exception_index = RISCV_EXCP_NONE; env->load_res = -1; set_default_nan_mode(1, &env->fp_status); @@ -1251,7 +1241,6 @@ static const MISAExtInfo misa_ext_info_arr[] = { MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"), MISA_EXT_INFO(RVU, "u", "User-level instructions"), MISA_EXT_INFO(RVH, "h", "Hypervisor"), -MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"), MISA_EXT_INFO(RVV, "v", "Vector operations"), MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"), }; diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index d74b361be6..a43c8fba57 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -67,7 +67,6 @@ typedef struct CPUArchState CPURISCVState; #define RVS RV('S') #define RVU RV('U') #define RVH RV('H') -#define RVJ RV('J') #define RVG RV('G') extern const uint32_t misa_bits[]; @@ -374,18 +373,7 @@ struct CPUArchState { /* True if in debugger mode. */ bool debugger; -/* - * CSRs for PointerMasking extension - */ -target_ulong mmte; -target_ulong mpmmask; -target_ulong mpmbase; -target_ulong spmmask; -target_ulong spmbase; -target_ulong upmmask; -target_ulong upmbase; - -/* CSRs for execution environment configuration */ +/* CSRs for execution enviornment configuration */ uint64_t menvcfg; uint64_t mstateen[SMSTATEEN_MAX_COUNT]; uint64_t hstateen[SMSTATEEN_MAX_COUNT]; @@ -393,8 +381,6 @@ struct CPUArchState { target_ulong senvcfg; uint64_t henvcfg; #endif -target_ulong cur_pmmask; -target_ulong cur_pmbase; /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ @@ -543,17 +529,14 @@ FIELD(TB_FLAGS, VILL, 14, 1) FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 16, 2) -/* If PointerMasking should be applied */ -FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1) -FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1) -FIELD(TB_FLAGS, VTA, 20, 1) -FIELD(TB_FLAGS, VMA, 21, 1) +FIELD(TB_FLAGS, VTA, 18, 1) +FIELD(TB_FLAGS, VMA, 19, 1) /* Native debug itrigger */ -FIELD(TB_FLAGS, ITRIGGER, 22, 1) +FIELD(TB_FLAGS, ITRIGGER, 20, 1) /* Virtual mode enabled */ -FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) -FIELD(TB_FLAGS, PRIV, 24, 2) -FIELD(TB_FLAGS, AXL, 26, 2) +FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) +FIELD(TB_FLAGS, PRIV, 22, 2) +FIELD(TB_FLAGS, AXL, 24, 2) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) @@ -680,8 +663,6 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulon
[PATCH v5 0/6] Pointer Masking update for Zjpm v0.8
From: Alexey Baturo Hi, This patch series targets Zjpm v0.8 extension. The spec itself could be found here: https://github.com/riscv/riscv-j-extension/blob/8088461d8d66a7676872b61c908cbeb7cf5c5d1d/zjpm-spec.pdf This patch series is updated after the suggested comments: - add "x-" to the extension names to indicate experimental [v4]: Patch series updated after the suggested comments: - removed J-letter extension as it's unused - renamed and fixed function to detect if address should be sign-extended - zeroed unused context variables and moved computation logic to another patch - bumped pointer masking version_id and minimum_version_id by 1 Thanks [v3]: There patches are updated after Richard's comments: - moved new tb flags to the end - used tcg_gen_(s)extract to get the final address - properly handle CONFIG_USER_ONLY Thanks [v2]: As per Richard's suggestion I made pmm field part of tb_flags. It allowed to get rid of global variable to store pmlen. Also it allowed to simplify all the machinery around it. Thanks [v1]: Hi all, It looks like Zjpm v0.8 is almost frozen and we don't expect it change drastically anymore. Compared to the original implementation with explicit base and mask CSRs, we now only have several fixed options for number of masked bits which are set using existing CSRs. The changes have been tested with handwritten assembly tests and LLVM HWASAN test suite. Thanks Alexey Baturo (6): target/riscv: Remove obsolete pointer masking extension code. target/riscv: Add new CSR fields for S{sn,mn,m}pm extensions as part of Zjpm v0.8 target/riscv: Add helper functions to calculate current number of masked bits for pointer masking target/riscv: Add pointer masking tb flags target/riscv: Update address modify functions to take into account pointer masking target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension target/riscv/cpu.c | 22 ++- target/riscv/cpu.h | 46 +++-- target/riscv/cpu_bits.h | 90 +- target/riscv/cpu_cfg.h | 3 + target/riscv/cpu_helper.c| 97 +- target/riscv/csr.c | 337 ++- target/riscv/machine.c | 20 +-- target/riscv/pmp.c | 13 +- target/riscv/pmp.h | 11 +- target/riscv/tcg/tcg-cpu.c | 5 +- target/riscv/translate.c | 46 ++--- target/riscv/vector_helper.c | 15 +- 12 files changed, 158 insertions(+), 547 deletions(-) -- 2.34.1
[PATCH v5 2/6] target/riscv: Add new CSR fields for S{sn, mn, m}pm extensions as part of Zjpm v0.8
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/cpu.h | 8 target/riscv/cpu_bits.h | 3 +++ target/riscv/cpu_cfg.h | 3 +++ target/riscv/csr.c | 11 +++ target/riscv/machine.c | 10 +++--- target/riscv/pmp.c | 13 ++--- target/riscv/pmp.h | 11 ++- 7 files changed, 48 insertions(+), 11 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index a43c8fba57..c9bed5c9fc 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -101,6 +101,14 @@ typedef enum { EXT_STATUS_DIRTY, } RISCVExtStatus; +/* Enum holds PMM field values for Zjpm v0.8 extension */ +typedef enum { +PMM_FIELD_DISABLED = 0, +PMM_FIELD_RESERVED = 1, +PMM_FIELD_PMLEN7 = 2, +PMM_FIELD_PMLEN16 = 3, +} RISCVPmPmm; + #define MMU_USER_IDX 3 #define MAX_RISCV_PMPS (16) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 1c92458a01..7cf1049bf4 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -715,6 +715,7 @@ typedef enum RISCVException { #define MENVCFG_CBIE (3UL << 4) #define MENVCFG_CBCFE BIT(6) #define MENVCFG_CBZE BIT(7) +#define MENVCFG_PMM(3ULL << 32) #define MENVCFG_ADUE (1ULL << 61) #define MENVCFG_PBMTE (1ULL << 62) #define MENVCFG_STCE (1ULL << 63) @@ -728,11 +729,13 @@ typedef enum RISCVException { #define SENVCFG_CBIE MENVCFG_CBIE #define SENVCFG_CBCFE MENVCFG_CBCFE #define SENVCFG_CBZE MENVCFG_CBZE +#define SENVCFG_PMMMENVCFG_PMM #define HENVCFG_FIOM MENVCFG_FIOM #define HENVCFG_CBIE MENVCFG_CBIE #define HENVCFG_CBCFE MENVCFG_CBCFE #define HENVCFG_CBZE MENVCFG_CBZE +#define HENVCFG_PMMMENVCFG_PMM #define HENVCFG_ADUE MENVCFG_ADUE #define HENVCFG_PBMTE MENVCFG_PBMTE #define HENVCFG_STCE MENVCFG_STCE diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index f4605fb190..201f8af6ae 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -113,6 +113,9 @@ struct RISCVCPUConfig { bool ext_ssaia; bool ext_sscofpmf; bool ext_smepmp; +bool ext_ssnpm; +bool ext_smnpm; +bool ext_smmpm; bool rvv_ta_all_1s; bool rvv_ma_all_1s; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index ea4e1ac6ef..a67ba30494 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -527,6 +527,9 @@ static RISCVException have_mseccfg(CPURISCVState *env, int csrno) if (riscv_cpu_cfg(env)->ext_zkr) { return RISCV_EXCP_NONE; } +if (riscv_cpu_cfg(env)->ext_smmpm) { +return RISCV_EXCP_NONE; +} return RISCV_EXCP_ILLEGAL_INST; } @@ -2030,6 +2033,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, (cfg->ext_sstc ? MENVCFG_STCE : 0) | (cfg->ext_svadu ? MENVCFG_ADUE : 0); } +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & MENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= MENVCFG_PMM; +} env->menvcfg = (env->menvcfg & ~mask) | (val & mask); return RISCV_EXCP_NONE; @@ -2074,6 +2081,10 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, target_ulong val) { uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE; +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & SENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= SENVCFG_PMM; +} RISCVException ret; ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG); diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 71ee8bab19..0ad593ed5a 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -152,15 +152,19 @@ static const VMStateDescription vmstate_vector = { static bool pointermasking_needed(void *opaque) { -return false; +RISCVCPU *cpu = opaque; +return cpu->cfg.ext_ssnpm || cpu->cfg.ext_smnpm || cpu->cfg.ext_smmpm; } static const VMStateDescription vmstate_pointermasking = { .name = "cpu/pointer_masking", -.version_id = 1, -.minimum_version_id = 1, +.version_id = 2, +.minimum_version_id = 2, .needed = pointermasking_needed, .fields = (VMStateField[]) { +VMSTATE_UINTTL(env.mseccfg, RISCVCPU), +VMSTATE_UINTTL(env.senvcfg, RISCVCPU), +VMSTATE_UINTTL(env.menvcfg, RISCVCPU), VMSTATE_END_OF_LIST() } }; diff --git a/target/risc
Re: [PATCH v4 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking
Hi, Having the feature to run binaries with pointer masking on qemu-user is really nice, but I see this patch series as an initial support. Obviously there'll be more patches and fixes for pointer masking as soon as arch tests are ready. I suggest supporting qemu-user in the next patches, but make sure we do this before claiming 100% support for pointer masking. @Deepak Gupta what do you think? Thanks сб, 20 янв. 2024 г. в 10:37, Richard Henderson : > On 1/19/24 09:40, Deepak Gupta wrote: > > On Thu, Jan 18, 2024 at 12:50 PM Richard Henderson > > wrote: > >> At some point pointer masking will be in hardware, and the kernel will > gain support for > >> it, and there will likely be a prctl() added for it. At the point the > kernel finalizes > >> the API, you will be able to enable pointer masking for qemu-user. > > > > I am sure I am missing some important detail here, BUT... > > > > How is it different from aarch64 "top byte ignore". > > It is very similar, yes. > > > I think commit: 16c8497 enables top byte ignore for user pointers and > > by default for qemu-user for aarch64 target. > > Not quite, no. > > commit 0e0c030c681730f3ec55ba3b223b608a8f3e8282 > Author: Richard Henderson > Date: Fri Feb 12 10:48:51 2021 -0800 > > linux-user/aarch64: Implement PR_TAGGED_ADDR_ENABLE > > is more relevant. > > > IIRC, user <--> kernel abi is only needed for pointers that are passed > > to the kernel. > > It is also needed to *enable* pointer masking at all. > > For aarch64, TBI has been enabled for user-space since the beginning, but > that is not true > for riscv. Therefore there will be a need for a syscall to opt in and > enable pointer masking. > > > And in the case of qemu-user, we are talking about the host kernel. > > No, we are not. We are always emulating the guest kernel. > > > r~ >
[PATCH v4 2/6] target/riscv: Add new CSR fields for S{sn, mn, m}pm extensions as part of Zjpm v0.8
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.h | 8 target/riscv/cpu_bits.h | 3 +++ target/riscv/cpu_cfg.h | 3 +++ target/riscv/csr.c | 11 +++ target/riscv/machine.c | 10 +++--- target/riscv/pmp.c | 13 ++--- target/riscv/pmp.h | 11 ++- 7 files changed, 48 insertions(+), 11 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index a43c8fba57..c9bed5c9fc 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -101,6 +101,14 @@ typedef enum { EXT_STATUS_DIRTY, } RISCVExtStatus; +/* Enum holds PMM field values for Zjpm v0.8 extension */ +typedef enum { +PMM_FIELD_DISABLED = 0, +PMM_FIELD_RESERVED = 1, +PMM_FIELD_PMLEN7 = 2, +PMM_FIELD_PMLEN16 = 3, +} RISCVPmPmm; + #define MMU_USER_IDX 3 #define MAX_RISCV_PMPS (16) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 1c92458a01..7cf1049bf4 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -715,6 +715,7 @@ typedef enum RISCVException { #define MENVCFG_CBIE (3UL << 4) #define MENVCFG_CBCFE BIT(6) #define MENVCFG_CBZE BIT(7) +#define MENVCFG_PMM(3ULL << 32) #define MENVCFG_ADUE (1ULL << 61) #define MENVCFG_PBMTE (1ULL << 62) #define MENVCFG_STCE (1ULL << 63) @@ -728,11 +729,13 @@ typedef enum RISCVException { #define SENVCFG_CBIE MENVCFG_CBIE #define SENVCFG_CBCFE MENVCFG_CBCFE #define SENVCFG_CBZE MENVCFG_CBZE +#define SENVCFG_PMMMENVCFG_PMM #define HENVCFG_FIOM MENVCFG_FIOM #define HENVCFG_CBIE MENVCFG_CBIE #define HENVCFG_CBCFE MENVCFG_CBCFE #define HENVCFG_CBZE MENVCFG_CBZE +#define HENVCFG_PMMMENVCFG_PMM #define HENVCFG_ADUE MENVCFG_ADUE #define HENVCFG_PBMTE MENVCFG_PBMTE #define HENVCFG_STCE MENVCFG_STCE diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index f4605fb190..201f8af6ae 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -113,6 +113,9 @@ struct RISCVCPUConfig { bool ext_ssaia; bool ext_sscofpmf; bool ext_smepmp; +bool ext_ssnpm; +bool ext_smnpm; +bool ext_smmpm; bool rvv_ta_all_1s; bool rvv_ma_all_1s; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index ea4e1ac6ef..a67ba30494 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -527,6 +527,9 @@ static RISCVException have_mseccfg(CPURISCVState *env, int csrno) if (riscv_cpu_cfg(env)->ext_zkr) { return RISCV_EXCP_NONE; } +if (riscv_cpu_cfg(env)->ext_smmpm) { +return RISCV_EXCP_NONE; +} return RISCV_EXCP_ILLEGAL_INST; } @@ -2030,6 +2033,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, (cfg->ext_sstc ? MENVCFG_STCE : 0) | (cfg->ext_svadu ? MENVCFG_ADUE : 0); } +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & MENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= MENVCFG_PMM; +} env->menvcfg = (env->menvcfg & ~mask) | (val & mask); return RISCV_EXCP_NONE; @@ -2074,6 +2081,10 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, target_ulong val) { uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE; +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & SENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= SENVCFG_PMM; +} RISCVException ret; ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG); diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 71ee8bab19..0ad593ed5a 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -152,15 +152,19 @@ static const VMStateDescription vmstate_vector = { static bool pointermasking_needed(void *opaque) { -return false; +RISCVCPU *cpu = opaque; +return cpu->cfg.ext_ssnpm || cpu->cfg.ext_smnpm || cpu->cfg.ext_smmpm; } static const VMStateDescription vmstate_pointermasking = { .name = "cpu/pointer_masking", -.version_id = 1, -.minimum_version_id = 1, +.version_id = 2, +.minimum_version_id = 2, .needed = pointermasking_needed, .fields = (VMStateField[]) { +VMSTATE_UINTTL(env.mseccfg, RISCVCPU), +VMSTATE_UINTTL(env.senvcfg, RISCVCPU), +VMSTATE_UINTTL(env.menvcfg, RISCVCPU), VMSTATE_END_OF_LIST() } }; diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
[PATCH v4 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.h| 4 +++ target/riscv/cpu_helper.c | 58 +++ 2 files changed, 62 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index c9bed5c9fc..1c8979c1c8 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -671,6 +671,10 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, uint64_t *cs_base, uint32_t *pflags); +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env); +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env); +int riscv_pm_get_pmlen(RISCVPmPmm pmm); + RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index a3d477d226..9640e4c2c5 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -139,6 +139,64 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, *pflags = flags; } +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env) +{ +int pmm = 0; +#ifndef CONFIG_USER_ONLY +int priv_mode = cpu_address_mode(env); +/* Get current PMM field */ +switch (priv_mode) { +case PRV_M: +pmm = riscv_cpu_cfg(env)->ext_smmpm ? + get_field(env->mseccfg, MSECCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_S: +pmm = riscv_cpu_cfg(env)->ext_smnpm ? + get_field(env->menvcfg, MENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_U: +pmm = riscv_cpu_cfg(env)->ext_ssnpm ? + get_field(env->senvcfg, SENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +default: +g_assert_not_reached(); +} +#endif +return pmm; +} + +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env) +{ +bool virt_mem_en = false; +#ifndef CONFIG_USER_ONLY +int satp_mode = 0; +int priv_mode = cpu_address_mode(env); +/* Get current PMM field */ +if (riscv_cpu_mxl(env) == MXL_RV32) { +satp_mode = get_field(env->satp, SATP32_MODE); +} else { +satp_mode = get_field(env->satp, SATP64_MODE); +} +virt_mem_en = ((satp_mode != VM_1_10_MBARE) && (priv_mode != PRV_M)); +#endif +return virt_mem_en; +} + +int riscv_pm_get_pmlen(RISCVPmPmm pmm) +{ +switch (pmm) { +case PMM_FIELD_DISABLED: +return 0; +case PMM_FIELD_PMLEN7: +return 7; +case PMM_FIELD_PMLEN16: +return 16; +default: +g_assert_not_reached(); +} +return -1; +} + #ifndef CONFIG_USER_ONLY /* -- 2.34.1
[PATCH v4 4/6] target/riscv: Add pointer masking tb flags
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Richard Henderson --- target/riscv/cpu.h| 3 +++ target/riscv/cpu_helper.c | 3 +++ target/riscv/translate.c | 5 + 3 files changed, 11 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 1c8979c1c8..0284ea418f 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -545,6 +545,9 @@ FIELD(TB_FLAGS, ITRIGGER, 20, 1) FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) FIELD(TB_FLAGS, PRIV, 22, 2) FIELD(TB_FLAGS, AXL, 24, 2) +/* If pointer masking should be applied and address sign extended */ +FIELD(TB_FLAGS, PM_PMM, 26, 2) +FIELD(TB_FLAGS, PM_SIGNEXTEND, 28, 1) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 9640e4c2c5..67bc51e510 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -68,6 +68,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, RISCVCPU *cpu = env_archcpu(env); RISCVExtStatus fs, vs; uint32_t flags = 0; +bool pm_signext = riscv_cpu_virt_mem_enabled(env); *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc; *cs_base = 0; @@ -135,6 +136,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, flags = FIELD_DP32(flags, TB_FLAGS, VS, vs); flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl); flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext); *pflags = flags; } diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 6b4b9a671c..2c89d749c0 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -103,6 +103,9 @@ typedef struct DisasContext { bool vl_eq_vlmax; CPUState *cs; TCGv zero; +/* actual address width */ +uint8_t addr_width; +bool addr_signed; /* Use icount trigger for native debug */ bool itrigger; /* FRM is known to contain a valid value. */ @@ -1176,6 +1179,8 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; +ctx->addr_width = 0; +ctx->addr_signed = false; ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); ctx->virt_inst_excp = false; -- 2.34.1
[PATCH v4 5/6] target/riscv: Update address modify functions to take into account pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo Reviewed-by: Richard Henderson --- target/riscv/translate.c | 22 -- target/riscv/vector_helper.c | 13 + 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 2c89d749c0..457de381c7 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -579,8 +579,10 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_addi_tl(addr, src1, imm); -if (get_address_xl(ctx) == MXL_RV32) { -tcg_gen_ext32u_tl(addr, addr); +if (ctx->addr_signed) { +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width); +} else { +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width); } return addr; @@ -593,8 +595,10 @@ static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_add_tl(addr, src1, offs); -if (get_xl(ctx) == MXL_RV32) { -tcg_gen_ext32u_tl(addr, addr); +if (ctx->addr_signed) { +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width); +} else { +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width); } return addr; } @@ -1179,8 +1183,14 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; -ctx->addr_width = 0; -ctx->addr_signed = false; +if (get_xl(ctx) == MXL_RV32) { +ctx->addr_width = 32; +ctx->addr_signed = false; +} else { +int pm_pmm = FIELD_EX32(tb_flags, TB_FLAGS, PM_PMM); +ctx->addr_width = 64 - riscv_pm_get_pmlen(pm_pmm); +ctx->addr_signed = FIELD_EX32(tb_flags, TB_FLAGS, PM_SIGNEXTEND); +} ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); ctx->virt_inst_excp = false; diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 8e7a8e80a0..ff1178723c 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -94,6 +94,19 @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz) static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr) { +RISCVPmPmm pmm = riscv_pm_get_pmm(env); +if (pmm == PMM_FIELD_DISABLED) { +return addr; +} +int pmlen = riscv_pm_get_pmlen(pmm); +bool signext = riscv_cpu_virt_mem_enabled(env); +addr = addr << pmlen; +/* sign/zero extend masked address by N-1 bit */ +if (signext) { +addr = (target_long)addr >> pmlen; +} else { +addr = addr >> pmlen; +} return addr; } -- 2.34.1
[PATCH v4 0/6] Pointer Masking update for Zjpm v0.8
From: Alexey Baturo Hi, Patch series updated after the suggested comments: - removed J-letter extension as it's unused - renamed and fixed function to detect if address should be sign-extended - zeroed unused context variables and moved computation logic to another patch - bumped pointer masking version_id and minimum_version_id by 1 Thanks [v3]: There patches are updated after Richard's comments: - moved new tb flags to the end - used tcg_gen_(s)extract to get the final address - properly handle CONFIG_USER_ONLY Thanks [v2]: As per Richard's suggestion I made pmm field part of tb_flags. It allowed to get rid of global variable to store pmlen. Also it allowed to simplify all the machinery around it. Thanks [v1]: Hi all, It looks like Zjpm v0.8 is almost frozen and we don't expect it change drastically anymore. Compared to the original implementation with explicit base and mask CSRs, we now only have several fixed options for number of masked bits which are set using existing CSRs. The changes have been tested with handwritten assembly tests and LLVM HWASAN test suite. Thanks Alexey Baturo (6): target/riscv: Remove obsolete pointer masking extension code. target/riscv: Add new CSR fields for S{sn,mn,m}pm extensions as part of Zjpm v0.8 target/riscv: Add helper functions to calculate current number of masked bits for pointer masking target/riscv: Add pointer masking tb flags target/riscv: Update address modify functions to take into account pointer masking target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension target/riscv/cpu.c | 21 +-- target/riscv/cpu.h | 46 +++-- target/riscv/cpu_bits.h | 90 +- target/riscv/cpu_cfg.h | 3 + target/riscv/cpu_helper.c| 96 +- target/riscv/csr.c | 337 ++- target/riscv/machine.c | 16 +- target/riscv/pmp.c | 13 +- target/riscv/pmp.h | 11 +- target/riscv/tcg/tcg-cpu.c | 5 +- target/riscv/translate.c | 46 ++--- target/riscv/vector_helper.c | 14 +- 12 files changed, 153 insertions(+), 545 deletions(-) -- 2.34.1
[PATCH v4 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.c | 8 1 file changed, 8 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index d8de1f1890..44ebd80aba 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -153,6 +153,9 @@ const RISCVIsaExtData isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval), ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot), ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt), +ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_12_0, ext_ssnpm), +ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_12_0, ext_smnpm), +ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_12_0, ext_smmpm), ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba), ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb), ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs), @@ -1336,6 +1339,11 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = { MULTI_EXT_CFG_BOOL("zmmul", ext_zmmul, false), +/* Zjpm v0.8 extensions */ +MULTI_EXT_CFG_BOOL("ssnpm", ext_ssnpm, false), +MULTI_EXT_CFG_BOOL("smnpm", ext_smnpm, false), +MULTI_EXT_CFG_BOOL("smmpm", ext_smmpm, false), + MULTI_EXT_CFG_BOOL("zca", ext_zca, false), MULTI_EXT_CFG_BOOL("zcb", ext_zcb, false), MULTI_EXT_CFG_BOOL("zcd", ext_zcd, false), -- 2.34.1
[PATCH v4 1/6] target/riscv: Remove obsolete pointer masking extension code.
From: Alexey Baturo Zjpm v0.8 is almost frozen and it's much simplier compared to the existing one: The newer version doesn't allow to specify custom mask or base for masking. Instead it allows only certain options for masking top bits. Signed-off-by: Alexey Baturo --- target/riscv/cpu.c | 13 +- target/riscv/cpu.h | 33 +--- target/riscv/cpu_bits.h | 87 -- target/riscv/cpu_helper.c| 52 -- target/riscv/csr.c | 326 --- target/riscv/machine.c | 14 +- target/riscv/tcg/tcg-cpu.c | 5 +- target/riscv/translate.c | 27 +-- target/riscv/vector_helper.c | 2 +- 9 files changed, 14 insertions(+), 545 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 83c7c0cf07..d8de1f1890 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -40,7 +40,7 @@ /* RISC-V CPU definitions */ static const char riscv_single_letter_exts[] = "IEMAFDQCPVH"; const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV, - RVC, RVS, RVU, RVH, RVJ, RVG, 0}; + RVC, RVS, RVU, RVH, RVG, 0}; /* * From vector_helper.c @@ -710,13 +710,6 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) CSR_MSCRATCH, CSR_SSCRATCH, CSR_SATP, -CSR_MMTE, -CSR_UPMBASE, -CSR_UPMMASK, -CSR_SPMBASE, -CSR_SPMMASK, -CSR_MPMBASE, -CSR_MPMMASK, }; for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) { @@ -891,8 +884,6 @@ static void riscv_cpu_reset_hold(Object *obj) } i++; } -/* mmte is supposed to have pm.current hardwired to 1 */ -env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT); /* * Clear mseccfg and unlock all the PMP entries upon reset. @@ -906,7 +897,6 @@ static void riscv_cpu_reset_hold(Object *obj) pmp_unlock_entries(env); #endif env->xl = riscv_cpu_mxl(env); -riscv_cpu_update_mask(env); cs->exception_index = RISCV_EXCP_NONE; env->load_res = -1; set_default_nan_mode(1, &env->fp_status); @@ -1251,7 +1241,6 @@ static const MISAExtInfo misa_ext_info_arr[] = { MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"), MISA_EXT_INFO(RVU, "u", "User-level instructions"), MISA_EXT_INFO(RVH, "h", "Hypervisor"), -MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"), MISA_EXT_INFO(RVV, "v", "Vector operations"), MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"), }; diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index d74b361be6..a43c8fba57 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -67,7 +67,6 @@ typedef struct CPUArchState CPURISCVState; #define RVS RV('S') #define RVU RV('U') #define RVH RV('H') -#define RVJ RV('J') #define RVG RV('G') extern const uint32_t misa_bits[]; @@ -374,18 +373,7 @@ struct CPUArchState { /* True if in debugger mode. */ bool debugger; -/* - * CSRs for PointerMasking extension - */ -target_ulong mmte; -target_ulong mpmmask; -target_ulong mpmbase; -target_ulong spmmask; -target_ulong spmbase; -target_ulong upmmask; -target_ulong upmbase; - -/* CSRs for execution environment configuration */ +/* CSRs for execution enviornment configuration */ uint64_t menvcfg; uint64_t mstateen[SMSTATEEN_MAX_COUNT]; uint64_t hstateen[SMSTATEEN_MAX_COUNT]; @@ -393,8 +381,6 @@ struct CPUArchState { target_ulong senvcfg; uint64_t henvcfg; #endif -target_ulong cur_pmmask; -target_ulong cur_pmbase; /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ @@ -543,17 +529,14 @@ FIELD(TB_FLAGS, VILL, 14, 1) FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 16, 2) -/* If PointerMasking should be applied */ -FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1) -FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1) -FIELD(TB_FLAGS, VTA, 20, 1) -FIELD(TB_FLAGS, VMA, 21, 1) +FIELD(TB_FLAGS, VTA, 18, 1) +FIELD(TB_FLAGS, VMA, 19, 1) /* Native debug itrigger */ -FIELD(TB_FLAGS, ITRIGGER, 22, 1) +FIELD(TB_FLAGS, ITRIGGER, 20, 1) /* Virtual mode enabled */ -FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) -FIELD(TB_FLAGS, PRIV, 24, 2) -FIELD(TB_FLAGS, AXL, 26, 2) +FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) +FIELD(TB_FLAGS, PRIV, 22, 2) +FIELD(TB_FLAGS, AXL, 24, 2) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) @@ -680,8 +663,6 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) void cpu_get_tb_cpu_
Re: [PATCH v3 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking
I think you're right, thanks. I'll add a check for M-mode as well and I guess I'll have to rename the function. Any ideas on the proper and self-describing name? Thanks пт, 5 янв. 2024 г. в 03:46, Deepak Gupta : > On Wed, Jan 3, 2024 at 10:59 AM Alexey Baturo > wrote: > > + > > +bool riscv_cpu_bare_mode(CPURISCVState *env) > > +{ > > +int satp_mode = 0; > > +#ifndef CONFIG_USER_ONLY > > +if (riscv_cpu_mxl(env) == MXL_RV32) { > > +satp_mode = get_field(env->satp, SATP32_MODE); > > +} else { > > +satp_mode = get_field(env->satp, SATP64_MODE); > > +} > > +#endif > > +return (satp_mode == VM_1_10_MBARE); > > +} > > + > > Assume the CPU was in S or U with satp = non-bare mode but then a > transfer to M-mode happened. > In that case, even though the CPU is in M mode, the above function > will return non-bare mode and enforce > signed extension on M mode pointer masking (if enabled). > > right or am I missing something here? >
Re: [PATCH v3 5/6] target/riscv: Update address modify functions to take into account pointer masking
> +addr = addr << pmlen; > +if (signext) { > +addr = (target_long)addr >> pmlen; > +} else { > +addr = addr >> pmlen; Could you please elaborate a bit more on your concern here? I believe this code works as intended: https://godbolt.org/z/b9c7na13a Thanks пт, 5 янв. 2024 г. в 04:02, Deepak Gupta : > > --- a/target/riscv/vector_helper.c > > +++ b/target/riscv/vector_helper.c > > @@ -94,6 +94,18 @@ static inline uint32_t vext_max_elems(uint32_t desc, > uint32_t log2_esz) > > > > static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong > addr) > > { > > +RISCVPmPmm pmm = riscv_pm_get_pmm(env); > > +if (pmm == PMM_FIELD_DISABLED) > > +return addr; > > +int pmlen = riscv_pm_get_pmlen(pmm); > > +bool signext = !riscv_cpu_bare_mode(env); > > +addr = addr << pmlen; > > +/* sign/zero extend masked address by N-1 bit */ > > +if (signext) { > > +addr = (target_long)addr >> pmlen; > > These look like right shift operations and not sign extensions of N-1 bit > > > +} else { > > +addr = addr >> pmlen; > > Same here. > > > +} > > return addr; > > } > > > > -- > > 2.34.1 > > > > >
Re: [PATCH v3 1/6] target/riscv: Remove obsolete pointer masking extension code.
Sure, I would do it in the next updated series. пт, 5 янв. 2024 г. в 08:04, Alistair Francis : > On Thu, Jan 4, 2024 at 6:33 AM Alexey Baturo > wrote: > > > > From: Alexey Baturo > > > > Zjpm v0.8 is almost frozen and it's much simplier compared to the > existing one: > > The newer version doesn't allow to specify custom mask or base for > masking. > > Instead it allows only certain options for masking top bits. > > > > Signed-off-by: Alexey Baturo > > --- > > target/riscv/cpu.c | 10 -- > > target/riscv/cpu.h | 32 +--- > > target/riscv/cpu_bits.h | 87 -- > > target/riscv/cpu_helper.c| 52 -- > > target/riscv/csr.c | 326 --- > > target/riscv/machine.c | 9 - > > target/riscv/translate.c | 27 +-- > > target/riscv/vector_helper.c | 2 +- > > 8 files changed, 10 insertions(+), 535 deletions(-) > > > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > > index 83c7c0cf07..1e6571ce99 100644 > > --- a/target/riscv/cpu.c > > +++ b/target/riscv/cpu.c > > @@ -710,13 +710,6 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE > *f, int flags) > > CSR_MSCRATCH, > > CSR_SSCRATCH, > > CSR_SATP, > > -CSR_MMTE, > > -CSR_UPMBASE, > > -CSR_UPMMASK, > > -CSR_SPMBASE, > > -CSR_SPMMASK, > > -CSR_MPMBASE, > > -CSR_MPMMASK, > > }; > > > > for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) { > > @@ -891,8 +884,6 @@ static void riscv_cpu_reset_hold(Object *obj) > > } > > i++; > > } > > -/* mmte is supposed to have pm.current hardwired to 1 */ > > -env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT); > > > > /* > > * Clear mseccfg and unlock all the PMP entries upon reset. > > @@ -906,7 +897,6 @@ static void riscv_cpu_reset_hold(Object *obj) > > pmp_unlock_entries(env); > > #endif > > env->xl = riscv_cpu_mxl(env); > > -riscv_cpu_update_mask(env); > > cs->exception_index = RISCV_EXCP_NONE; > > env->load_res = -1; > > set_default_nan_mode(1, &env->fp_status); > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > > index d74b361be6..73f7004936 100644 > > --- a/target/riscv/cpu.h > > +++ b/target/riscv/cpu.h > > @@ -374,18 +374,7 @@ struct CPUArchState { > > /* True if in debugger mode. */ > > bool debugger; > > > > -/* > > - * CSRs for PointerMasking extension > > - */ > > -target_ulong mmte; > > -target_ulong mpmmask; > > -target_ulong mpmbase; > > -target_ulong spmmask; > > -target_ulong spmbase; > > -target_ulong upmmask; > > -target_ulong upmbase; > > - > > -/* CSRs for execution environment configuration */ > > +/* CSRs for execution enviornment configuration */ > > uint64_t menvcfg; > > uint64_t mstateen[SMSTATEEN_MAX_COUNT]; > > uint64_t hstateen[SMSTATEEN_MAX_COUNT]; > > @@ -393,8 +382,6 @@ struct CPUArchState { > > target_ulong senvcfg; > > uint64_t henvcfg; > > #endif > > -target_ulong cur_pmmask; > > -target_ulong cur_pmbase; > > > > /* Fields from here on are preserved across CPU reset. */ > > QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ > > @@ -543,17 +530,14 @@ FIELD(TB_FLAGS, VILL, 14, 1) > > FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) > > /* The combination of MXL/SXL/UXL that applies to the current cpu mode. > */ > > FIELD(TB_FLAGS, XL, 16, 2) > > -/* If PointerMasking should be applied */ > > -FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1) > > -FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1) > > -FIELD(TB_FLAGS, VTA, 20, 1) > > -FIELD(TB_FLAGS, VMA, 21, 1) > > +FIELD(TB_FLAGS, VTA, 18, 1) > > +FIELD(TB_FLAGS, VMA, 19, 1) > > /* Native debug itrigger */ > > -FIELD(TB_FLAGS, ITRIGGER, 22, 1) > > +FIELD(TB_FLAGS, ITRIGGER, 20, 1) > > /* Virtual mode enabled */ > > -FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) > > -FIELD(TB_FLAGS, PRIV, 24, 2) > > -FIELD(TB_FLAGS, AXL, 26, 2) > > +FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) > > +FIELD(TB_FLAGS, PRIV, 22, 2) > > +FIELD(TB_FLAGS, AXL, 24, 2) > > > > #ifdef TARGET_RISCV32 > > #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) > > @@ -680,8
Re: [PATCH v3 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension
I might be wrong here, but right now J in MISA is unused. I think the J-letter extension is still a thing, but current extensions like Zjpm and Zjid follow the Z ext scheme. Do you think it should be removed? пт, 5 янв. 2024 г. в 08:28, Alistair Francis : > On Thu, Jan 4, 2024 at 4:58 AM Alexey Baturo > wrote: > > > > From: Alexey Baturo > > > > Signed-off-by: Alexey Baturo > > --- > > target/riscv/cpu.c | 8 > > 1 file changed, 8 insertions(+) > > > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > > index 1e6571ce99..13389ddc55 100644 > > --- a/target/riscv/cpu.c > > +++ b/target/riscv/cpu.c > > @@ -153,6 +153,9 @@ const RISCVIsaExtData isa_edata_arr[] = { > > ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval), > > ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot), > > ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt), > > +ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_12_0, ext_ssnpm), > > +ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_12_0, ext_smnpm), > > +ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_12_0, ext_smmpm), > > ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba), > > ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb), > > ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs), > > @@ -1337,6 +1340,11 @@ const RISCVCPUMultiExtConfig > riscv_cpu_extensions[] = { > > > > MULTI_EXT_CFG_BOOL("zmmul", ext_zmmul, false), > > > > +/* Zjpm v0.8 extensions */ > > +MULTI_EXT_CFG_BOOL("ssnpm", ext_ssnpm, false), > > +MULTI_EXT_CFG_BOOL("smnpm", ext_smnpm, false), > > +MULTI_EXT_CFG_BOOL("smmpm", ext_smmpm, false), > > What happens to the existing J property? > > > Alistair > > > + > > MULTI_EXT_CFG_BOOL("zca", ext_zca, false), > > MULTI_EXT_CFG_BOOL("zcb", ext_zcb, false), > > MULTI_EXT_CFG_BOOL("zcd", ext_zcd, false), > > -- > > 2.34.1 > > > > >
[PATCH v3 2/6] target/riscv: Add new CSR fields for S{sn, mn, m}pm extensions as part of Zjpm v0.8
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.h | 8 target/riscv/cpu_bits.h | 3 +++ target/riscv/cpu_cfg.h | 3 +++ target/riscv/csr.c | 11 +++ target/riscv/machine.c | 6 -- target/riscv/pmp.c | 13 ++--- target/riscv/pmp.h | 11 ++- 7 files changed, 45 insertions(+), 10 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 73f7004936..bd379ee653 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -102,6 +102,14 @@ typedef enum { EXT_STATUS_DIRTY, } RISCVExtStatus; +/* Enum holds PMM field values for Zjpm v0.8 extension */ +typedef enum { +PMM_FIELD_DISABLED = 0, +PMM_FIELD_RESERVED = 1, +PMM_FIELD_PMLEN7 = 2, +PMM_FIELD_PMLEN16 = 3, +} RISCVPmPmm; + #define MMU_USER_IDX 3 #define MAX_RISCV_PMPS (16) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 1c92458a01..7cf1049bf4 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -715,6 +715,7 @@ typedef enum RISCVException { #define MENVCFG_CBIE (3UL << 4) #define MENVCFG_CBCFE BIT(6) #define MENVCFG_CBZE BIT(7) +#define MENVCFG_PMM(3ULL << 32) #define MENVCFG_ADUE (1ULL << 61) #define MENVCFG_PBMTE (1ULL << 62) #define MENVCFG_STCE (1ULL << 63) @@ -728,11 +729,13 @@ typedef enum RISCVException { #define SENVCFG_CBIE MENVCFG_CBIE #define SENVCFG_CBCFE MENVCFG_CBCFE #define SENVCFG_CBZE MENVCFG_CBZE +#define SENVCFG_PMMMENVCFG_PMM #define HENVCFG_FIOM MENVCFG_FIOM #define HENVCFG_CBIE MENVCFG_CBIE #define HENVCFG_CBCFE MENVCFG_CBCFE #define HENVCFG_CBZE MENVCFG_CBZE +#define HENVCFG_PMMMENVCFG_PMM #define HENVCFG_ADUE MENVCFG_ADUE #define HENVCFG_PBMTE MENVCFG_PBMTE #define HENVCFG_STCE MENVCFG_STCE diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index f4605fb190..201f8af6ae 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -113,6 +113,9 @@ struct RISCVCPUConfig { bool ext_ssaia; bool ext_sscofpmf; bool ext_smepmp; +bool ext_ssnpm; +bool ext_smnpm; +bool ext_smmpm; bool rvv_ta_all_1s; bool rvv_ma_all_1s; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index ea4e1ac6ef..a67ba30494 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -527,6 +527,9 @@ static RISCVException have_mseccfg(CPURISCVState *env, int csrno) if (riscv_cpu_cfg(env)->ext_zkr) { return RISCV_EXCP_NONE; } +if (riscv_cpu_cfg(env)->ext_smmpm) { +return RISCV_EXCP_NONE; +} return RISCV_EXCP_ILLEGAL_INST; } @@ -2030,6 +2033,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, (cfg->ext_sstc ? MENVCFG_STCE : 0) | (cfg->ext_svadu ? MENVCFG_ADUE : 0); } +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & MENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= MENVCFG_PMM; +} env->menvcfg = (env->menvcfg & ~mask) | (val & mask); return RISCV_EXCP_NONE; @@ -2074,6 +2081,10 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, target_ulong val) { uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE; +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & SENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= SENVCFG_PMM; +} RISCVException ret; ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG); diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 860fe56d43..5e9c5b43ab 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -153,9 +153,8 @@ static const VMStateDescription vmstate_vector = { static bool pointermasking_needed(void *opaque) { RISCVCPU *cpu = opaque; -CPURISCVState *env = &cpu->env; -return riscv_has_ext(env, RVJ); +return cpu->cfg.ext_ssnpm || cpu->cfg.ext_smnpm || cpu->cfg.ext_smmpm; } static const VMStateDescription vmstate_pointermasking = { @@ -164,6 +163,9 @@ static const VMStateDescription vmstate_pointermasking = { .minimum_version_id = 1, .needed = pointermasking_needed, .fields = (VMStateField[]) { +VMSTATE_UINTTL(env.mseccfg, RISCVCPU), +VMSTATE_UINTTL(env.senvcfg, RISCVCPU), +VMSTATE_UINTTL(env.menvcfg, RISCVCPU), VMSTATE_END_OF_LIST() } }; diff --git a/target/riscv/pmp.c b/target
[PATCH v3 1/6] target/riscv: Remove obsolete pointer masking extension code.
From: Alexey Baturo Zjpm v0.8 is almost frozen and it's much simplier compared to the existing one: The newer version doesn't allow to specify custom mask or base for masking. Instead it allows only certain options for masking top bits. Signed-off-by: Alexey Baturo --- target/riscv/cpu.c | 10 -- target/riscv/cpu.h | 32 +--- target/riscv/cpu_bits.h | 87 -- target/riscv/cpu_helper.c| 52 -- target/riscv/csr.c | 326 --- target/riscv/machine.c | 9 - target/riscv/translate.c | 27 +-- target/riscv/vector_helper.c | 2 +- 8 files changed, 10 insertions(+), 535 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 83c7c0cf07..1e6571ce99 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -710,13 +710,6 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) CSR_MSCRATCH, CSR_SSCRATCH, CSR_SATP, -CSR_MMTE, -CSR_UPMBASE, -CSR_UPMMASK, -CSR_SPMBASE, -CSR_SPMMASK, -CSR_MPMBASE, -CSR_MPMMASK, }; for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) { @@ -891,8 +884,6 @@ static void riscv_cpu_reset_hold(Object *obj) } i++; } -/* mmte is supposed to have pm.current hardwired to 1 */ -env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT); /* * Clear mseccfg and unlock all the PMP entries upon reset. @@ -906,7 +897,6 @@ static void riscv_cpu_reset_hold(Object *obj) pmp_unlock_entries(env); #endif env->xl = riscv_cpu_mxl(env); -riscv_cpu_update_mask(env); cs->exception_index = RISCV_EXCP_NONE; env->load_res = -1; set_default_nan_mode(1, &env->fp_status); diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index d74b361be6..73f7004936 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -374,18 +374,7 @@ struct CPUArchState { /* True if in debugger mode. */ bool debugger; -/* - * CSRs for PointerMasking extension - */ -target_ulong mmte; -target_ulong mpmmask; -target_ulong mpmbase; -target_ulong spmmask; -target_ulong spmbase; -target_ulong upmmask; -target_ulong upmbase; - -/* CSRs for execution environment configuration */ +/* CSRs for execution enviornment configuration */ uint64_t menvcfg; uint64_t mstateen[SMSTATEEN_MAX_COUNT]; uint64_t hstateen[SMSTATEEN_MAX_COUNT]; @@ -393,8 +382,6 @@ struct CPUArchState { target_ulong senvcfg; uint64_t henvcfg; #endif -target_ulong cur_pmmask; -target_ulong cur_pmbase; /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ @@ -543,17 +530,14 @@ FIELD(TB_FLAGS, VILL, 14, 1) FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 16, 2) -/* If PointerMasking should be applied */ -FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1) -FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1) -FIELD(TB_FLAGS, VTA, 20, 1) -FIELD(TB_FLAGS, VMA, 21, 1) +FIELD(TB_FLAGS, VTA, 18, 1) +FIELD(TB_FLAGS, VMA, 19, 1) /* Native debug itrigger */ -FIELD(TB_FLAGS, ITRIGGER, 22, 1) +FIELD(TB_FLAGS, ITRIGGER, 20, 1) /* Virtual mode enabled */ -FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) -FIELD(TB_FLAGS, PRIV, 24, 2) -FIELD(TB_FLAGS, AXL, 26, 2) +FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) +FIELD(TB_FLAGS, PRIV, 22, 2) +FIELD(TB_FLAGS, AXL, 24, 2) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) @@ -680,8 +664,6 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, uint64_t *cs_base, uint32_t *pflags); -void riscv_cpu_update_mask(CPURISCVState *env); - RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index ebd7917d49..1c92458a01 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -491,37 +491,6 @@ #define CSR_MHPMCOUNTER30H 0xb9e #define CSR_MHPMCOUNTER31H 0xb9f -/* - * User PointerMasking registers - * NB: actual CSR numbers might be changed in future - */ -#define CSR_UMTE0x4c0 -#define CSR_UPMMASK 0x4c1 -#define CSR_UPMBASE 0x4c2 - -/* - * Machine PointerMasking registers - * NB: actual CSR numbers might be changed in future - */ -#define CSR_MMTE0x3c0 -#define CSR_MPMMASK 0x3c1 -#define CSR_MPMBASE 0x3c2 - -/* - * Supervisor PointerMaster registers - * NB: actual CSR numbers might be changed in future - */ -#define CSR_SMTE0x1c0 -#define CSR_SPMMASK 0x1c1 -#
[PATCH v3 4/6] target/riscv: Add pointer masking tb flags
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.h| 3 +++ target/riscv/cpu_helper.c | 3 +++ target/riscv/translate.c | 11 +++ 3 files changed, 17 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index c607a94bba..4df160494f 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -546,6 +546,9 @@ FIELD(TB_FLAGS, ITRIGGER, 20, 1) FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) FIELD(TB_FLAGS, PRIV, 22, 2) FIELD(TB_FLAGS, AXL, 24, 2) +/* If pointer masking should be applied and address sign extended */ +FIELD(TB_FLAGS, PM_PMM, 26, 2) +FIELD(TB_FLAGS, PM_SIGNEXTEND, 28, 1) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 4c34e12ee3..b8d8a622f3 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -68,6 +68,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, RISCVCPU *cpu = env_archcpu(env); RISCVExtStatus fs, vs; uint32_t flags = 0; +bool pm_signext = !riscv_cpu_bare_mode(env); *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc; *cs_base = 0; @@ -135,6 +136,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, flags = FIELD_DP32(flags, TB_FLAGS, VS, vs); flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl); flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext); *pflags = flags; } diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 6b4b9a671c..8ac2819fa5 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -103,6 +103,9 @@ typedef struct DisasContext { bool vl_eq_vlmax; CPUState *cs; TCGv zero; +/* actual address width */ +uint8_t addr_width; +bool addr_signed; /* Use icount trigger for native debug */ bool itrigger; /* FRM is known to contain a valid value. */ @@ -1176,6 +1179,14 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; +if (get_xl(ctx) == MXL_RV32) { +ctx->addr_width = 32; +ctx->addr_signed = false; +} else { +int pm_pmm = FIELD_EX32(tb_flags, TB_FLAGS, PM_PMM); +ctx->addr_width = 64 - riscv_pm_get_pmlen(pm_pmm); +ctx->addr_signed = FIELD_EX32(tb_flags, TB_FLAGS, PM_SIGNEXTEND); +} ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); ctx->virt_inst_excp = false; -- 2.34.1
[PATCH v3 0/6] Pointer Masking update for Zjpm v0.8
From: Alexey Baturo Hi, There patches are updated after Richard's comments: - moved new tb flags to the end - used tcg_gen_(s)extract to get the final address - properly handle CONFIG_USER_ONLY Thanks [v2]: As per Richard's suggestion I made pmm field part of tb_flags. It allowed to get rid of global variable to store pmlen. Also it allowed to simplify all the machinery around it. Thanks [v1]: Hi all, It looks like Zjpm v0.8 is almost frozen and we don't expect it change drastically anymore. Compared to the original implementation with explicit base and mask CSRs, we now only have several fixed options for number of masked bits which are set using existing CSRs. The changes have been tested with handwritten assembly tests and LLVM HWASAN test suite. Thanks Alexey Baturo (6): target/riscv: Remove obsolete pointer masking extension code. target/riscv: Add new CSR fields for S{sn,mn,m}pm extensions as part of Zjpm v0.8 target/riscv: Add helper functions to calculate current number of masked bits for pointer masking target/riscv: Add pointer masking tb flags target/riscv: Update address modify functions to take into account pointer masking target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension target/riscv/cpu.c | 18 +- target/riscv/cpu.h | 45 +++-- target/riscv/cpu_bits.h | 90 +- target/riscv/cpu_cfg.h | 3 + target/riscv/cpu_helper.c| 93 +- target/riscv/csr.c | 337 ++- target/riscv/machine.c | 15 +- target/riscv/pmp.c | 13 +- target/riscv/pmp.h | 11 +- target/riscv/translate.c | 46 ++--- target/riscv/vector_helper.c | 14 +- 11 files changed, 147 insertions(+), 538 deletions(-) -- 2.34.1
[PATCH v3 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.h| 4 +++ target/riscv/cpu_helper.c | 54 +++ 2 files changed, 58 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index bd379ee653..c607a94bba 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -672,6 +672,10 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, uint64_t *cs_base, uint32_t *pflags); +bool riscv_cpu_bare_mode(CPURISCVState *env); +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env); +int riscv_pm_get_pmlen(RISCVPmPmm pmm); + RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index a3d477d226..4c34e12ee3 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -139,6 +139,60 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, *pflags = flags; } +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env) +{ +int pmm = 0; +#ifndef CONFIG_USER_ONLY +int priv_mode = cpu_address_mode(env); +/* Get current PMM field */ +switch (priv_mode) { +case PRV_M: +pmm = riscv_cpu_cfg(env)->ext_smmpm ? + get_field(env->mseccfg, MSECCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_S: +pmm = riscv_cpu_cfg(env)->ext_smnpm ? + get_field(env->menvcfg, MENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_U: +pmm = riscv_cpu_cfg(env)->ext_ssnpm ? + get_field(env->senvcfg, SENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +default: +g_assert_not_reached(); +} +#endif +return pmm; +} + +bool riscv_cpu_bare_mode(CPURISCVState *env) +{ +int satp_mode = 0; +#ifndef CONFIG_USER_ONLY +if (riscv_cpu_mxl(env) == MXL_RV32) { +satp_mode = get_field(env->satp, SATP32_MODE); +} else { +satp_mode = get_field(env->satp, SATP64_MODE); +} +#endif +return (satp_mode == VM_1_10_MBARE); +} + +int riscv_pm_get_pmlen(RISCVPmPmm pmm) +{ +switch (pmm) { +case PMM_FIELD_DISABLED: +return 0; +case PMM_FIELD_PMLEN7: +return 7; +case PMM_FIELD_PMLEN16: +return 16; +default: +g_assert_not_reached(); +} +return -1; +} + #ifndef CONFIG_USER_ONLY /* -- 2.34.1
[PATCH v3 5/6] target/riscv: Update address modify functions to take into account pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/translate.c | 12 target/riscv/vector_helper.c | 12 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 8ac2819fa5..457de381c7 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -579,8 +579,10 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_addi_tl(addr, src1, imm); -if (get_address_xl(ctx) == MXL_RV32) { -tcg_gen_ext32u_tl(addr, addr); +if (ctx->addr_signed) { +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width); +} else { +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width); } return addr; @@ -593,8 +595,10 @@ static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_add_tl(addr, src1, offs); -if (get_xl(ctx) == MXL_RV32) { -tcg_gen_ext32u_tl(addr, addr); +if (ctx->addr_signed) { +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width); +} else { +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width); } return addr; } diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 8e7a8e80a0..b91c21d1f4 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -94,6 +94,18 @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz) static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr) { +RISCVPmPmm pmm = riscv_pm_get_pmm(env); +if (pmm == PMM_FIELD_DISABLED) +return addr; +int pmlen = riscv_pm_get_pmlen(pmm); +bool signext = !riscv_cpu_bare_mode(env); +addr = addr << pmlen; +/* sign/zero extend masked address by N-1 bit */ +if (signext) { +addr = (target_long)addr >> pmlen; +} else { +addr = addr >> pmlen; +} return addr; } -- 2.34.1
[PATCH v3 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.c | 8 1 file changed, 8 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 1e6571ce99..13389ddc55 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -153,6 +153,9 @@ const RISCVIsaExtData isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval), ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot), ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt), +ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_12_0, ext_ssnpm), +ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_12_0, ext_smnpm), +ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_12_0, ext_smmpm), ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba), ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb), ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs), @@ -1337,6 +1340,11 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = { MULTI_EXT_CFG_BOOL("zmmul", ext_zmmul, false), +/* Zjpm v0.8 extensions */ +MULTI_EXT_CFG_BOOL("ssnpm", ext_ssnpm, false), +MULTI_EXT_CFG_BOOL("smnpm", ext_smnpm, false), +MULTI_EXT_CFG_BOOL("smmpm", ext_smmpm, false), + MULTI_EXT_CFG_BOOL("zca", ext_zca, false), MULTI_EXT_CFG_BOOL("zcb", ext_zcb, false), MULTI_EXT_CFG_BOOL("zcd", ext_zcd, false), -- 2.34.1
Re: [PATCH v2 4/6] target/riscv: Add pointer masking tb flags
>Any particular reason to add these in the middle? No actual reason except for previously those flags were there in the middle. I'll move them to the end of the list, that sounds reasonable. >Something to consider as a somewhat unrelated cleanup would be to add an... That's a good idea and I agree we could do it as part of future clean up. Thanks, Richard пт, 29 дек. 2023 г. в 02:33, Richard Henderson : > On 12/24/23 15:48, Alexey Baturo wrote: > > From: Alexey Baturo > > > > Signed-off-by: Alexey Baturo > > --- > > target/riscv/cpu.h| 15 +-- > > target/riscv/cpu_helper.c | 3 +++ > > target/riscv/translate.c | 5 + > > 3 files changed, 17 insertions(+), 6 deletions(-) > > > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > > index c607a94bba..038b86db4b 100644 > > --- a/target/riscv/cpu.h > > +++ b/target/riscv/cpu.h > > @@ -538,14 +538,17 @@ FIELD(TB_FLAGS, VILL, 14, 1) > > FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) > > /* The combination of MXL/SXL/UXL that applies to the current cpu > mode. */ > > FIELD(TB_FLAGS, XL, 16, 2) > > -FIELD(TB_FLAGS, VTA, 18, 1) > > -FIELD(TB_FLAGS, VMA, 19, 1) > > +/* If pointer masking should be applied and address sign extended */ > > +FIELD(TB_FLAGS, PM_PMM, 18, 2) > > +FIELD(TB_FLAGS, PM_SIGNEXTEND, 20, 1) > > +FIELD(TB_FLAGS, VTA, 21, 1) > > +FIELD(TB_FLAGS, VMA, 22, 1) > > /* Native debug itrigger */ > > -FIELD(TB_FLAGS, ITRIGGER, 20, 1) > > +FIELD(TB_FLAGS, ITRIGGER, 23, 1) > > /* Virtual mode enabled */ > > -FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) > > -FIELD(TB_FLAGS, PRIV, 22, 2) > > -FIELD(TB_FLAGS, AXL, 24, 2) > > +FIELD(TB_FLAGS, VIRT_ENABLED, 24, 1) > > +FIELD(TB_FLAGS, PRIV, 25, 2) > > +FIELD(TB_FLAGS, AXL, 27, 2) > > Any particular reason to add these in the middle? > > Something to consider as a somewhat unrelated cleanup would be to add an > eighth MMUIdx for > MMUIdx_M + no translation. This would be used both for MBARE and > internally within > get_physical_address for accessing PTEs. See also the ptw_translate > cleanups in > target/i386 for atomic PTE updates (4a1e9d4d11cd). > > At which point PM_SIGNEXTEND can be replaced by a test vs mmu_idx, saving > a bit in tb_flags. > > Something for later, anyway. > > > r~ >
[PATCH v2 4/6] target/riscv: Add pointer masking tb flags
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.h| 15 +-- target/riscv/cpu_helper.c | 3 +++ target/riscv/translate.c | 5 + 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index c607a94bba..038b86db4b 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -538,14 +538,17 @@ FIELD(TB_FLAGS, VILL, 14, 1) FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 16, 2) -FIELD(TB_FLAGS, VTA, 18, 1) -FIELD(TB_FLAGS, VMA, 19, 1) +/* If pointer masking should be applied and address sign extended */ +FIELD(TB_FLAGS, PM_PMM, 18, 2) +FIELD(TB_FLAGS, PM_SIGNEXTEND, 20, 1) +FIELD(TB_FLAGS, VTA, 21, 1) +FIELD(TB_FLAGS, VMA, 22, 1) /* Native debug itrigger */ -FIELD(TB_FLAGS, ITRIGGER, 20, 1) +FIELD(TB_FLAGS, ITRIGGER, 23, 1) /* Virtual mode enabled */ -FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) -FIELD(TB_FLAGS, PRIV, 22, 2) -FIELD(TB_FLAGS, AXL, 24, 2) +FIELD(TB_FLAGS, VIRT_ENABLED, 24, 1) +FIELD(TB_FLAGS, PRIV, 25, 2) +FIELD(TB_FLAGS, AXL, 27, 2) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 47f325294e..7c33369cf1 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -68,6 +68,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, RISCVCPU *cpu = env_archcpu(env); RISCVExtStatus fs, vs; uint32_t flags = 0; +bool pm_signext = !riscv_cpu_bare_mode(env); *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc; *cs_base = 0; @@ -135,6 +136,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, flags = FIELD_DP32(flags, TB_FLAGS, VS, vs); flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl); flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env)); +flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext); *pflags = flags; } diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 6b4b9a671c..1eb501e0d3 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -103,6 +103,9 @@ typedef struct DisasContext { bool vl_eq_vlmax; CPUState *cs; TCGv zero; +/* pointer masking extension */ +uint8_t pm_pmm; +bool pm_signext; /* Use icount trigger for native debug */ bool itrigger; /* FRM is known to contain a valid value. */ @@ -1176,6 +1179,8 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; +ctx->pm_pmm = FIELD_EX32(tb_flags, TB_FLAGS, PM_PMM); +ctx->pm_signext = FIELD_EX32(tb_flags, TB_FLAGS, PM_SIGNEXTEND); ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); ctx->virt_inst_excp = false; -- 2.34.1
[PATCH v2 2/6] target/riscv: Add new CSR fields for S{sn, mn, m}pm extensions as part of Zjpm v0.8
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.h | 8 target/riscv/cpu_bits.h | 3 +++ target/riscv/cpu_cfg.h | 3 +++ target/riscv/csr.c | 11 +++ target/riscv/machine.c | 6 -- target/riscv/pmp.c | 13 ++--- target/riscv/pmp.h | 11 ++- 7 files changed, 45 insertions(+), 10 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 73f7004936..bd379ee653 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -102,6 +102,14 @@ typedef enum { EXT_STATUS_DIRTY, } RISCVExtStatus; +/* Enum holds PMM field values for Zjpm v0.8 extension */ +typedef enum { +PMM_FIELD_DISABLED = 0, +PMM_FIELD_RESERVED = 1, +PMM_FIELD_PMLEN7 = 2, +PMM_FIELD_PMLEN16 = 3, +} RISCVPmPmm; + #define MMU_USER_IDX 3 #define MAX_RISCV_PMPS (16) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 1c92458a01..7cf1049bf4 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -715,6 +715,7 @@ typedef enum RISCVException { #define MENVCFG_CBIE (3UL << 4) #define MENVCFG_CBCFE BIT(6) #define MENVCFG_CBZE BIT(7) +#define MENVCFG_PMM(3ULL << 32) #define MENVCFG_ADUE (1ULL << 61) #define MENVCFG_PBMTE (1ULL << 62) #define MENVCFG_STCE (1ULL << 63) @@ -728,11 +729,13 @@ typedef enum RISCVException { #define SENVCFG_CBIE MENVCFG_CBIE #define SENVCFG_CBCFE MENVCFG_CBCFE #define SENVCFG_CBZE MENVCFG_CBZE +#define SENVCFG_PMMMENVCFG_PMM #define HENVCFG_FIOM MENVCFG_FIOM #define HENVCFG_CBIE MENVCFG_CBIE #define HENVCFG_CBCFE MENVCFG_CBCFE #define HENVCFG_CBZE MENVCFG_CBZE +#define HENVCFG_PMMMENVCFG_PMM #define HENVCFG_ADUE MENVCFG_ADUE #define HENVCFG_PBMTE MENVCFG_PBMTE #define HENVCFG_STCE MENVCFG_STCE diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index f4605fb190..201f8af6ae 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -113,6 +113,9 @@ struct RISCVCPUConfig { bool ext_ssaia; bool ext_sscofpmf; bool ext_smepmp; +bool ext_ssnpm; +bool ext_smnpm; +bool ext_smmpm; bool rvv_ta_all_1s; bool rvv_ma_all_1s; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index ea4e1ac6ef..a67ba30494 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -527,6 +527,9 @@ static RISCVException have_mseccfg(CPURISCVState *env, int csrno) if (riscv_cpu_cfg(env)->ext_zkr) { return RISCV_EXCP_NONE; } +if (riscv_cpu_cfg(env)->ext_smmpm) { +return RISCV_EXCP_NONE; +} return RISCV_EXCP_ILLEGAL_INST; } @@ -2030,6 +2033,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, (cfg->ext_sstc ? MENVCFG_STCE : 0) | (cfg->ext_svadu ? MENVCFG_ADUE : 0); } +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & MENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= MENVCFG_PMM; +} env->menvcfg = (env->menvcfg & ~mask) | (val & mask); return RISCV_EXCP_NONE; @@ -2074,6 +2081,10 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, target_ulong val) { uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE; +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & SENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= SENVCFG_PMM; +} RISCVException ret; ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG); diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 860fe56d43..5e9c5b43ab 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -153,9 +153,8 @@ static const VMStateDescription vmstate_vector = { static bool pointermasking_needed(void *opaque) { RISCVCPU *cpu = opaque; -CPURISCVState *env = &cpu->env; -return riscv_has_ext(env, RVJ); +return cpu->cfg.ext_ssnpm || cpu->cfg.ext_smnpm || cpu->cfg.ext_smmpm; } static const VMStateDescription vmstate_pointermasking = { @@ -164,6 +163,9 @@ static const VMStateDescription vmstate_pointermasking = { .minimum_version_id = 1, .needed = pointermasking_needed, .fields = (VMStateField[]) { +VMSTATE_UINTTL(env.mseccfg, RISCVCPU), +VMSTATE_UINTTL(env.senvcfg, RISCVCPU), +VMSTATE_UINTTL(env.menvcfg, RISCVCPU), VMSTATE_END_OF_LIST() } }; diff --git a/target/riscv/pmp.c b/target
[PATCH v2 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.h| 4 +++ target/riscv/cpu_helper.c | 54 +++ 2 files changed, 58 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index bd379ee653..c607a94bba 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -672,6 +672,10 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, uint64_t *cs_base, uint32_t *pflags); +bool riscv_cpu_bare_mode(CPURISCVState *env); +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env); +int riscv_pm_get_pmlen(RISCVPmPmm pmm); + RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index a3d477d226..47f325294e 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -139,6 +139,60 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, *pflags = flags; } +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env) +{ +#ifndef CONFIG_USER_ONLY +int priv_mode = cpu_address_mode(env); +int pmm = 0; +/* Get current PMM field */ +switch (priv_mode) { +case PRV_M: +pmm = riscv_cpu_cfg(env)->ext_smmpm ? + get_field(env->mseccfg, MSECCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_S: +pmm = riscv_cpu_cfg(env)->ext_smnpm ? + get_field(env->menvcfg, MENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_U: +pmm = riscv_cpu_cfg(env)->ext_ssnpm ? + get_field(env->senvcfg, SENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +default: +g_assert_not_reached(); +} +return pmm; +#endif +} + +bool riscv_cpu_bare_mode(CPURISCVState *env) +{ +#ifndef CONFIG_USER_ONLY +int satp_mode = 0; +if (riscv_cpu_mxl(env) == MXL_RV32) { +satp_mode = get_field(env->satp, SATP32_MODE); +} else { +satp_mode = get_field(env->satp, SATP64_MODE); +} +return (satp_mode == VM_1_10_MBARE); +#endif +} + +int riscv_pm_get_pmlen(RISCVPmPmm pmm) +{ +switch (pmm) { +case PMM_FIELD_DISABLED: +return 0; +case PMM_FIELD_PMLEN7: +return 7; +case PMM_FIELD_PMLEN16: +return 16; +default: +g_assert_not_reached(); +} +return -1; +} + #ifndef CONFIG_USER_ONLY /* -- 2.34.1
[PATCH v2 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.c | 8 1 file changed, 8 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 1e6571ce99..13389ddc55 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -153,6 +153,9 @@ const RISCVIsaExtData isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval), ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot), ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt), +ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_12_0, ext_ssnpm), +ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_12_0, ext_smnpm), +ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_12_0, ext_smmpm), ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba), ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb), ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs), @@ -1337,6 +1340,11 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = { MULTI_EXT_CFG_BOOL("zmmul", ext_zmmul, false), +/* Zjpm v0.8 extensions */ +MULTI_EXT_CFG_BOOL("ssnpm", ext_ssnpm, false), +MULTI_EXT_CFG_BOOL("smnpm", ext_smnpm, false), +MULTI_EXT_CFG_BOOL("smmpm", ext_smmpm, false), + MULTI_EXT_CFG_BOOL("zca", ext_zca, false), MULTI_EXT_CFG_BOOL("zcb", ext_zcb, false), MULTI_EXT_CFG_BOOL("zcd", ext_zcd, false), -- 2.34.1
[PATCH v2 1/6] target/riscv: Remove obsolete pointer masking extension code.
From: Alexey Baturo Zjpm v0.8 is almost frozen and it's much simplier compared to the existing one: The newer version doesn't allow to specify custom mask or base for masking. Instead it allows only certain options for masking top bits. Signed-off-by: Alexey Baturo --- target/riscv/cpu.c | 10 -- target/riscv/cpu.h | 32 +--- target/riscv/cpu_bits.h | 87 -- target/riscv/cpu_helper.c| 52 -- target/riscv/csr.c | 326 --- target/riscv/machine.c | 9 - target/riscv/translate.c | 27 +-- target/riscv/vector_helper.c | 2 +- 8 files changed, 10 insertions(+), 535 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 83c7c0cf07..1e6571ce99 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -710,13 +710,6 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) CSR_MSCRATCH, CSR_SSCRATCH, CSR_SATP, -CSR_MMTE, -CSR_UPMBASE, -CSR_UPMMASK, -CSR_SPMBASE, -CSR_SPMMASK, -CSR_MPMBASE, -CSR_MPMMASK, }; for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) { @@ -891,8 +884,6 @@ static void riscv_cpu_reset_hold(Object *obj) } i++; } -/* mmte is supposed to have pm.current hardwired to 1 */ -env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT); /* * Clear mseccfg and unlock all the PMP entries upon reset. @@ -906,7 +897,6 @@ static void riscv_cpu_reset_hold(Object *obj) pmp_unlock_entries(env); #endif env->xl = riscv_cpu_mxl(env); -riscv_cpu_update_mask(env); cs->exception_index = RISCV_EXCP_NONE; env->load_res = -1; set_default_nan_mode(1, &env->fp_status); diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index d74b361be6..73f7004936 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -374,18 +374,7 @@ struct CPUArchState { /* True if in debugger mode. */ bool debugger; -/* - * CSRs for PointerMasking extension - */ -target_ulong mmte; -target_ulong mpmmask; -target_ulong mpmbase; -target_ulong spmmask; -target_ulong spmbase; -target_ulong upmmask; -target_ulong upmbase; - -/* CSRs for execution environment configuration */ +/* CSRs for execution enviornment configuration */ uint64_t menvcfg; uint64_t mstateen[SMSTATEEN_MAX_COUNT]; uint64_t hstateen[SMSTATEEN_MAX_COUNT]; @@ -393,8 +382,6 @@ struct CPUArchState { target_ulong senvcfg; uint64_t henvcfg; #endif -target_ulong cur_pmmask; -target_ulong cur_pmbase; /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ @@ -543,17 +530,14 @@ FIELD(TB_FLAGS, VILL, 14, 1) FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 16, 2) -/* If PointerMasking should be applied */ -FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1) -FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1) -FIELD(TB_FLAGS, VTA, 20, 1) -FIELD(TB_FLAGS, VMA, 21, 1) +FIELD(TB_FLAGS, VTA, 18, 1) +FIELD(TB_FLAGS, VMA, 19, 1) /* Native debug itrigger */ -FIELD(TB_FLAGS, ITRIGGER, 22, 1) +FIELD(TB_FLAGS, ITRIGGER, 20, 1) /* Virtual mode enabled */ -FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) -FIELD(TB_FLAGS, PRIV, 24, 2) -FIELD(TB_FLAGS, AXL, 26, 2) +FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) +FIELD(TB_FLAGS, PRIV, 22, 2) +FIELD(TB_FLAGS, AXL, 24, 2) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) @@ -680,8 +664,6 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, uint64_t *cs_base, uint32_t *pflags); -void riscv_cpu_update_mask(CPURISCVState *env); - RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index ebd7917d49..1c92458a01 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -491,37 +491,6 @@ #define CSR_MHPMCOUNTER30H 0xb9e #define CSR_MHPMCOUNTER31H 0xb9f -/* - * User PointerMasking registers - * NB: actual CSR numbers might be changed in future - */ -#define CSR_UMTE0x4c0 -#define CSR_UPMMASK 0x4c1 -#define CSR_UPMBASE 0x4c2 - -/* - * Machine PointerMasking registers - * NB: actual CSR numbers might be changed in future - */ -#define CSR_MMTE0x3c0 -#define CSR_MPMMASK 0x3c1 -#define CSR_MPMBASE 0x3c2 - -/* - * Supervisor PointerMaster registers - * NB: actual CSR numbers might be changed in future - */ -#define CSR_SMTE0x1c0 -#define CSR_SPMMASK 0x1c1 -#
[PATCH v2 5/6] target/riscv: Update address modify functions to take into account pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/translate.c | 23 +-- target/riscv/vector_helper.c | 10 ++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 1eb501e0d3..c0c5030e05 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -575,11 +575,20 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm) /* Compute a canonical address from a register plus offset. */ static TCGv get_address(DisasContext *ctx, int rs1, int imm) { +int pmlen = riscv_pm_get_pmlen(ctx->pm_pmm); TCGv addr = tcg_temp_new(); TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_addi_tl(addr, src1, imm); -if (get_address_xl(ctx) == MXL_RV32) { +if (ctx->pm_pmm) { +tcg_gen_shli_tl(addr, addr, pmlen); +/* sign extend address by first non-masked bit otherwise zero extend */ +if (ctx->pm_signext) { +tcg_gen_sari_tl(addr, addr, pmlen); +} else { +tcg_gen_shri_tl(addr, addr, pmlen); +} +} else if (get_address_xl(ctx) == MXL_RV32) { tcg_gen_ext32u_tl(addr, addr); } @@ -589,11 +598,21 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm) /* Compute a canonical address from a register plus reg offset. */ static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs) { +int pmlen = riscv_pm_get_pmlen(ctx->pm_pmm); TCGv addr = tcg_temp_new(); TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_add_tl(addr, src1, offs); -if (get_xl(ctx) == MXL_RV32) { +/* sign extend address by first non-masked bit */ +if (ctx->pm_pmm) { +tcg_gen_shli_tl(addr, addr, pmlen); +/* sign extend address by first non-masked bit otherwise zero extend */ +if (ctx->pm_signext) { +tcg_gen_sari_tl(addr, addr, pmlen); +} else { +tcg_gen_shri_tl(addr, addr, pmlen); +} +} else if (get_xl(ctx) == MXL_RV32) { tcg_gen_ext32u_tl(addr, addr); } return addr; diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 8e7a8e80a0..faa8f5820d 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -94,6 +94,16 @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz) static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr) { +RISCVPmPmm pmm = riscv_pm_get_pmm(env); +int pmlen = riscv_pm_get_pmlen(pmm); +bool signext = !riscv_cpu_bare_mode(env); +addr = addr << pmlen; +/* sign/zero extend masked address by N-1 bit */ +if (signext) { +addr = (target_long)addr >> pmlen; +} else { +addr = addr >> pmlen; +} return addr; } -- 2.34.1
[PATCH v2 0/6] Pointer Masking update for Zjpm v0.8
Hi, As per Richard's suggestion I made pmm field part of tb_flags. It allowed to get rid of global variable to store pmlen. Also it allowed to simplify all the machinery around it. Thanks [v1]: Hi all, It looks like Zjpm v0.8 is almost frozen and we don't expect it change drastically anymore. Compared to the original implementation with explicit base and mask CSRs, we now only have several fixed options for number of masked bits which are set using existing CSRs. The changes have been tested with handwritten assembly tests and LLVM HWASAN test suite. Thanks Alexey Baturo (6): target/riscv: Remove obsolete pointer masking extension code. target/riscv: Add new CSR fields for S{sn,mn,m}pm extensions as part of Zjpm v0.8 target/riscv: Add helper functions to calculate current number of masked bits for pointer masking target/riscv: Add pointer masking tb flags target/riscv: Update address modify functions to take into account pointer masking target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension target/riscv/cpu.c | 18 +- target/riscv/cpu.h | 45 +++-- target/riscv/cpu_bits.h | 90 +- target/riscv/cpu_cfg.h | 3 + target/riscv/cpu_helper.c| 92 +- target/riscv/csr.c | 337 ++- target/riscv/machine.c | 15 +- target/riscv/pmp.c | 13 +- target/riscv/pmp.h | 11 +- target/riscv/translate.c | 47 ++--- target/riscv/vector_helper.c | 12 +- 11 files changed, 148 insertions(+), 535 deletions(-) -- 2.34.1
Re: [PATCH 3/6] target/riscv: Add pointer masking tb flags
Hi Richard, Thanks for the suggestion. If it's ok to consume another bit(3 bits total) for Pointer Masking flags, I'll do it. >so that the translator can see the true width of the address I guess I'll need a helper to calculate the exact number of bits to shift(0, 7 or 16) based on those 2 extracted bits. Is it ok with you? Thanks пт, 22 дек. 2023 г. в 01:49, Richard Henderson : > On 12/21/23 21:40, Alexey Baturo wrote: > > From: Alexey Baturo > > > > Signed-off-by: Alexey Baturo > > --- > > target/riscv/cpu.h| 19 +-- > > target/riscv/cpu_helper.c | 4 > > target/riscv/translate.c | 10 ++ > > 3 files changed, 27 insertions(+), 6 deletions(-) > > > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > > index f49d4aa52c..2099168950 100644 > > --- a/target/riscv/cpu.h > > +++ b/target/riscv/cpu.h > > @@ -390,6 +390,10 @@ struct CPUArchState { > > target_ulong senvcfg; > > uint64_t henvcfg; > > #endif > > +/* current number of masked top bits by pointer masking */ > > +target_ulong pm_pmlen; > > +/* if pointer masking should do sign extension */ > > +bool pm_signext; > > > > /* Fields from here on are preserved across CPU reset. */ > > QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ > > @@ -538,14 +542,17 @@ FIELD(TB_FLAGS, VILL, 14, 1) > > FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) > > /* The combination of MXL/SXL/UXL that applies to the current cpu > mode. */ > > FIELD(TB_FLAGS, XL, 16, 2) > > -FIELD(TB_FLAGS, VTA, 18, 1) > > -FIELD(TB_FLAGS, VMA, 19, 1) > > +/* If pointer masking should be applied and address sign extended */ > > +FIELD(TB_FLAGS, PM_ENABLED, 18, 1) > > I think it would be better add the entire two bit field here, so that the > translator can > see the true width of the address. You can then use tcg_gen_{s}extract_tl > to perform the > truncation. At which point the 'target_ulong pm_pmlen' is not required. > > > r~ > > > +FIELD(TB_FLAGS, PM_SIGNEXTEND, 19, 1) > > +FIELD(TB_FLAGS, VTA, 20, 1) > > +FIELD(TB_FLAGS, VMA, 21, 1) > > /* Native debug itrigger */ > > -FIELD(TB_FLAGS, ITRIGGER, 20, 1) > > +FIELD(TB_FLAGS, ITRIGGER, 22, 1) > > /* Virtual mode enabled */ > > -FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) > > -FIELD(TB_FLAGS, PRIV, 22, 2) > > -FIELD(TB_FLAGS, AXL, 24, 2) > > +FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) > > +FIELD(TB_FLAGS, PRIV, 24, 2) > > +FIELD(TB_FLAGS, AXL, 25, 2) > > > > #ifdef TARGET_RISCV32 > > #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) > > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c > > index a3d477d226..79cddbd930 100644 > > --- a/target/riscv/cpu_helper.c > > +++ b/target/riscv/cpu_helper.c > > @@ -135,6 +135,10 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr > *pc, > > flags = FIELD_DP32(flags, TB_FLAGS, VS, vs); > > flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl); > > flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env)); > > +if (env->pm_pmlen != 0) { > > +flags = FIELD_DP32(flags, TB_FLAGS, PM_ENABLED, 1); > > +} > > +flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, env->pm_signext); > > > > *pflags = flags; > > } > > diff --git a/target/riscv/translate.c b/target/riscv/translate.c > > index 6b4b9a671c..4c0d526b58 100644 > > --- a/target/riscv/translate.c > > +++ b/target/riscv/translate.c > > @@ -42,6 +42,8 @@ static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, > cpu_vstart; > > static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */ > > static TCGv load_res; > > static TCGv load_val; > > +/* number of top masked address bits by pointer masking extension */ > > +static TCGv pm_pmlen; > > > > /* > >* If an operation is being performed on less than TARGET_LONG_BITS, > > @@ -103,6 +105,9 @@ typedef struct DisasContext { > > bool vl_eq_vlmax; > > CPUState *cs; > > TCGv zero; > > +/* pointer masking extension */ > > +bool pm_enabled; > > +bool pm_signext; > > /* Use icount trigger for native debug */ > > bool itrigger; > > /* FRM is known to contain a valid value. */ > > @@ -1176,6 +1181,8 @@ static void > riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) > > ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); > > ctx->address_xl = FIELD_EX32(tb_flags, TB_FL
[PATCH 3/6] target/riscv: Add pointer masking tb flags
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.h| 19 +-- target/riscv/cpu_helper.c | 4 target/riscv/translate.c | 10 ++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index f49d4aa52c..2099168950 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -390,6 +390,10 @@ struct CPUArchState { target_ulong senvcfg; uint64_t henvcfg; #endif +/* current number of masked top bits by pointer masking */ +target_ulong pm_pmlen; +/* if pointer masking should do sign extension */ +bool pm_signext; /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ @@ -538,14 +542,17 @@ FIELD(TB_FLAGS, VILL, 14, 1) FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 16, 2) -FIELD(TB_FLAGS, VTA, 18, 1) -FIELD(TB_FLAGS, VMA, 19, 1) +/* If pointer masking should be applied and address sign extended */ +FIELD(TB_FLAGS, PM_ENABLED, 18, 1) +FIELD(TB_FLAGS, PM_SIGNEXTEND, 19, 1) +FIELD(TB_FLAGS, VTA, 20, 1) +FIELD(TB_FLAGS, VMA, 21, 1) /* Native debug itrigger */ -FIELD(TB_FLAGS, ITRIGGER, 20, 1) +FIELD(TB_FLAGS, ITRIGGER, 22, 1) /* Virtual mode enabled */ -FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) -FIELD(TB_FLAGS, PRIV, 22, 2) -FIELD(TB_FLAGS, AXL, 24, 2) +FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) +FIELD(TB_FLAGS, PRIV, 24, 2) +FIELD(TB_FLAGS, AXL, 25, 2) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index a3d477d226..79cddbd930 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -135,6 +135,10 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, flags = FIELD_DP32(flags, TB_FLAGS, VS, vs); flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl); flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env)); +if (env->pm_pmlen != 0) { +flags = FIELD_DP32(flags, TB_FLAGS, PM_ENABLED, 1); +} +flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, env->pm_signext); *pflags = flags; } diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 6b4b9a671c..4c0d526b58 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -42,6 +42,8 @@ static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart; static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */ static TCGv load_res; static TCGv load_val; +/* number of top masked address bits by pointer masking extension */ +static TCGv pm_pmlen; /* * If an operation is being performed on less than TARGET_LONG_BITS, @@ -103,6 +105,9 @@ typedef struct DisasContext { bool vl_eq_vlmax; CPUState *cs; TCGv zero; +/* pointer masking extension */ +bool pm_enabled; +bool pm_signext; /* Use icount trigger for native debug */ bool itrigger; /* FRM is known to contain a valid value. */ @@ -1176,6 +1181,8 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; +ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED); +ctx->pm_signext = FIELD_EX32(tb_flags, TB_FLAGS, PM_SIGNEXTEND); ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); ctx->virt_inst_excp = false; @@ -1307,4 +1314,7 @@ void riscv_translate_init(void) "load_res"); load_val = tcg_global_mem_new(tcg_env, offsetof(CPURISCVState, load_val), "load_val"); +/* Assign var with number of pointer masking masked bits to tcg global */ +pm_pmlen = tcg_global_mem_new(tcg_env, offsetof(CPURISCVState, pm_pmlen), + "pmlen"); } -- 2.34.1
[PATCH 4/6] target/riscv: Add functions to calculate current number of masked bits for pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.h| 2 ++ target/riscv/cpu_helper.c | 49 +++ 2 files changed, 51 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 2099168950..9a8e5bc022 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -679,6 +679,8 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, uint64_t *cs_base, uint32_t *pflags); +void riscv_cpu_update_mask(CPURISCVState *env); + RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 79cddbd930..8e2751fef4 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -143,6 +143,55 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, *pflags = flags; } +void riscv_cpu_update_mask(CPURISCVState *env) +{ +#ifndef CONFIG_USER_ONLY +int priv_mode = cpu_address_mode(env); +int pmm = 0; +int pmlen = 0; +int satp_mode = 0; +if (riscv_cpu_mxl(env) == MXL_RV32) { +satp_mode = get_field(env->satp, SATP32_MODE); +} else { +satp_mode = get_field(env->satp, SATP64_MODE); +} +/* Get current PMM field */ +switch (priv_mode) { +case PRV_M: +pmm = riscv_cpu_cfg(env)->ext_smmpm ? + get_field(env->mseccfg, MSECCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_S: +pmm = riscv_cpu_cfg(env)->ext_smnpm ? + get_field(env->menvcfg, MENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_U: +pmm = riscv_cpu_cfg(env)->ext_ssnpm ? + get_field(env->senvcfg, SENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +default: +g_assert_not_reached(); +} +/* Get pmlen from PMM field */ +switch (pmm) { +case PMM_FIELD_DISABLED: +pmlen = 0; +break; +case PMM_FIELD_PMLEN7: +pmlen = 7; +break; +case PMM_FIELD_PMLEN16: +pmlen = 16; +break; +default: +g_assert_not_reached(); +} +/* in bare mode address is not sign extended */ +env->pm_signext = (satp_mode != VM_1_10_MBARE); +env->pm_pmlen = pmlen; +#endif +} + #ifndef CONFIG_USER_ONLY /* -- 2.34.1
[PATCH 0/6] Pointer Masking update for Zjpm v0.8
From: Alexey Baturo Hi all, It looks like Zjpm v0.8 is almost frozen and we don't expect it change drastically anymore. Compared to the original implementation with explicit base and mask CSRs, we now only have several fixed options for number of masked bits which are set using existing CSRs. The changes have been tested with handwritten assembly tests and LLVM HWASAN test suite. Thanks Alexey Baturo (6): target/riscv: Remove obsolete pointer masking extension code. target/riscv: Add new CSR fields for S{sn,mn,m}pm extensions as part of Zjpm v0.8 target/riscv: Add pointer masking tb flags target/riscv: Add functions to calculate current number of masked bits for pointer masking target/riscv: Update address modify functions to take into account pointer masking target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension target/riscv/cpu.c | 17 +- target/riscv/cpu.h | 35 ++-- target/riscv/cpu_bits.h | 85 + target/riscv/cpu_cfg.h | 3 + target/riscv/cpu_helper.c| 88 - target/riscv/csr.c | 339 ++- target/riscv/machine.c | 14 +- target/riscv/pmp.c | 14 +- target/riscv/pmp.h | 11 +- target/riscv/translate.c | 50 +++--- target/riscv/vector_helper.c | 9 +- 11 files changed, 146 insertions(+), 519 deletions(-) -- 2.34.1
[PATCH 1/6] target/riscv: Remove obsolete pointer masking extension code.
From: Alexey Baturo Zjpm v0.8 is almost frozen and it's much simplier compared to the existing one: The newer version doesn't allow to specify custom mask or base for masking. Instead it allows only certain options for masking top bits. Signed-off-by: Alexey Baturo --- target/riscv/cpu.c | 10 -- target/riscv/cpu.h | 32 +--- target/riscv/cpu_bits.h | 82 - target/riscv/cpu_helper.c| 52 -- target/riscv/csr.c | 326 --- target/riscv/machine.c | 9 - target/riscv/translate.c | 27 +-- target/riscv/vector_helper.c | 2 +- 8 files changed, 10 insertions(+), 530 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 83c7c0cf07..1e6571ce99 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -710,13 +710,6 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) CSR_MSCRATCH, CSR_SSCRATCH, CSR_SATP, -CSR_MMTE, -CSR_UPMBASE, -CSR_UPMMASK, -CSR_SPMBASE, -CSR_SPMMASK, -CSR_MPMBASE, -CSR_MPMMASK, }; for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) { @@ -891,8 +884,6 @@ static void riscv_cpu_reset_hold(Object *obj) } i++; } -/* mmte is supposed to have pm.current hardwired to 1 */ -env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT); /* * Clear mseccfg and unlock all the PMP entries upon reset. @@ -906,7 +897,6 @@ static void riscv_cpu_reset_hold(Object *obj) pmp_unlock_entries(env); #endif env->xl = riscv_cpu_mxl(env); -riscv_cpu_update_mask(env); cs->exception_index = RISCV_EXCP_NONE; env->load_res = -1; set_default_nan_mode(1, &env->fp_status); diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index d74b361be6..73f7004936 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -374,18 +374,7 @@ struct CPUArchState { /* True if in debugger mode. */ bool debugger; -/* - * CSRs for PointerMasking extension - */ -target_ulong mmte; -target_ulong mpmmask; -target_ulong mpmbase; -target_ulong spmmask; -target_ulong spmbase; -target_ulong upmmask; -target_ulong upmbase; - -/* CSRs for execution environment configuration */ +/* CSRs for execution enviornment configuration */ uint64_t menvcfg; uint64_t mstateen[SMSTATEEN_MAX_COUNT]; uint64_t hstateen[SMSTATEEN_MAX_COUNT]; @@ -393,8 +382,6 @@ struct CPUArchState { target_ulong senvcfg; uint64_t henvcfg; #endif -target_ulong cur_pmmask; -target_ulong cur_pmbase; /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ @@ -543,17 +530,14 @@ FIELD(TB_FLAGS, VILL, 14, 1) FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 16, 2) -/* If PointerMasking should be applied */ -FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1) -FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1) -FIELD(TB_FLAGS, VTA, 20, 1) -FIELD(TB_FLAGS, VMA, 21, 1) +FIELD(TB_FLAGS, VTA, 18, 1) +FIELD(TB_FLAGS, VMA, 19, 1) /* Native debug itrigger */ -FIELD(TB_FLAGS, ITRIGGER, 22, 1) +FIELD(TB_FLAGS, ITRIGGER, 20, 1) /* Virtual mode enabled */ -FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) -FIELD(TB_FLAGS, PRIV, 24, 2) -FIELD(TB_FLAGS, AXL, 26, 2) +FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) +FIELD(TB_FLAGS, PRIV, 22, 2) +FIELD(TB_FLAGS, AXL, 24, 2) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) @@ -680,8 +664,6 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, uint64_t *cs_base, uint32_t *pflags); -void riscv_cpu_update_mask(CPURISCVState *env); - RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index ebd7917d49..3f9415d68d 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -491,37 +491,6 @@ #define CSR_MHPMCOUNTER30H 0xb9e #define CSR_MHPMCOUNTER31H 0xb9f -/* - * User PointerMasking registers - * NB: actual CSR numbers might be changed in future - */ -#define CSR_UMTE0x4c0 -#define CSR_UPMMASK 0x4c1 -#define CSR_UPMBASE 0x4c2 - -/* - * Machine PointerMasking registers - * NB: actual CSR numbers might be changed in future - */ -#define CSR_MMTE0x3c0 -#define CSR_MPMMASK 0x3c1 -#define CSR_MPMBASE 0x3c2 - -/* - * Supervisor PointerMaster registers - * NB: actual CSR numbers might be changed in future - */ -#define CSR_SMTE0x1c0 -#define CSR_SPMMASK 0x1c1 -#
[PATCH 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.c| 9 + target/riscv/cpu_helper.c | 1 + target/riscv/csr.c| 4 target/riscv/machine.c| 1 + target/riscv/pmp.c| 1 + 5 files changed, 16 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 1e6571ce99..1d20e6a978 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -153,6 +153,9 @@ const RISCVIsaExtData isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval), ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot), ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt), +ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_12_0, ext_ssnpm), +ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_12_0, ext_smnpm), +ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_12_0, ext_smmpm), ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba), ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb), ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs), @@ -897,6 +900,7 @@ static void riscv_cpu_reset_hold(Object *obj) pmp_unlock_entries(env); #endif env->xl = riscv_cpu_mxl(env); +riscv_cpu_update_mask(env); cs->exception_index = RISCV_EXCP_NONE; env->load_res = -1; set_default_nan_mode(1, &env->fp_status); @@ -1337,6 +1341,11 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = { MULTI_EXT_CFG_BOOL("zmmul", ext_zmmul, false), +/* Zjpm v0.8 extensions */ +MULTI_EXT_CFG_BOOL("ssnpm", ext_ssnpm, false), +MULTI_EXT_CFG_BOOL("smnpm", ext_smnpm, false), +MULTI_EXT_CFG_BOOL("smmpm", ext_smmpm, false), + MULTI_EXT_CFG_BOOL("zca", ext_zca, false), MULTI_EXT_CFG_BOOL("zcb", ext_zcb, false), MULTI_EXT_CFG_BOOL("zcd", ext_zcd, false), diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 8e2751fef4..c2bc737dd7 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -723,6 +723,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv) /* tlb_flush is unnecessary as mode is contained in mmu_idx */ env->priv = newpriv; env->xl = cpu_recompute_xl(env); +riscv_cpu_update_mask(env); /* * Clear the load reservation - otherwise a reservation placed in one diff --git a/target/riscv/csr.c b/target/riscv/csr.c index a67ba30494..5336d91dd8 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -1348,6 +1348,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno, env->xl = cpu_recompute_xl(env); } +riscv_cpu_update_mask(env); return RISCV_EXCP_NONE; } @@ -2039,6 +2040,7 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, } env->menvcfg = (env->menvcfg & ~mask) | (val & mask); +riscv_cpu_update_mask(env); return RISCV_EXCP_NONE; } @@ -2093,6 +2095,8 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, } env->senvcfg = (env->senvcfg & ~mask) | (val & mask); + +riscv_cpu_update_mask(env); return RISCV_EXCP_NONE; } diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 5e9c5b43ab..41ad30c8e1 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -261,6 +261,7 @@ static int riscv_cpu_post_load(void *opaque, int version_id) CPURISCVState *env = &cpu->env; env->xl = cpu_recompute_xl(env); +riscv_cpu_update_mask(env); return 0; } diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c index 893ccd58d8..2cc08e58c5 100644 --- a/target/riscv/pmp.c +++ b/target/riscv/pmp.c @@ -607,6 +607,7 @@ void mseccfg_csr_write(CPURISCVState *env, target_ulong val) } env->mseccfg = val; +riscv_cpu_update_mask(env); } /* -- 2.34.1
[PATCH 2/6] target/riscv: Add new CSR fields for S{sn, mn, m}pm extensions as part of Zjpm v0.8
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.h | 8 target/riscv/cpu_bits.h | 3 +++ target/riscv/cpu_cfg.h | 3 +++ target/riscv/csr.c | 11 +++ target/riscv/machine.c | 6 -- target/riscv/pmp.c | 13 ++--- target/riscv/pmp.h | 11 ++- 7 files changed, 45 insertions(+), 10 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 73f7004936..f49d4aa52c 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -102,6 +102,14 @@ typedef enum { EXT_STATUS_DIRTY, } RISCVExtStatus; +/* Enum holds PMM field values for Zjpm v0.8 extension */ +enum { +PMM_FIELD_DISABLED = 0, +PMM_FIELD_RESERVED = 1, +PMM_FIELD_PMLEN7 = 2, +PMM_FIELD_PMLEN16 = 3, +}; + #define MMU_USER_IDX 3 #define MAX_RISCV_PMPS (16) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 3f9415d68d..fcbbdc21c5 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -720,6 +720,7 @@ typedef enum RISCVException { #define MENVCFG_CBIE (3UL << 4) #define MENVCFG_CBCFE BIT(6) #define MENVCFG_CBZE BIT(7) +#define MENVCFG_PMM(3ULL << 32) #define MENVCFG_ADUE (1ULL << 61) #define MENVCFG_PBMTE (1ULL << 62) #define MENVCFG_STCE (1ULL << 63) @@ -733,11 +734,13 @@ typedef enum RISCVException { #define SENVCFG_CBIE MENVCFG_CBIE #define SENVCFG_CBCFE MENVCFG_CBCFE #define SENVCFG_CBZE MENVCFG_CBZE +#define SENVCFG_PMMMENVCFG_PMM #define HENVCFG_FIOM MENVCFG_FIOM #define HENVCFG_CBIE MENVCFG_CBIE #define HENVCFG_CBCFE MENVCFG_CBCFE #define HENVCFG_CBZE MENVCFG_CBZE +#define HENVCFG_PMMMENVCFG_PMM #define HENVCFG_ADUE MENVCFG_ADUE #define HENVCFG_PBMTE MENVCFG_PBMTE #define HENVCFG_STCE MENVCFG_STCE diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index f4605fb190..201f8af6ae 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -113,6 +113,9 @@ struct RISCVCPUConfig { bool ext_ssaia; bool ext_sscofpmf; bool ext_smepmp; +bool ext_ssnpm; +bool ext_smnpm; +bool ext_smmpm; bool rvv_ta_all_1s; bool rvv_ma_all_1s; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index ea4e1ac6ef..a67ba30494 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -527,6 +527,9 @@ static RISCVException have_mseccfg(CPURISCVState *env, int csrno) if (riscv_cpu_cfg(env)->ext_zkr) { return RISCV_EXCP_NONE; } +if (riscv_cpu_cfg(env)->ext_smmpm) { +return RISCV_EXCP_NONE; +} return RISCV_EXCP_ILLEGAL_INST; } @@ -2030,6 +2033,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, (cfg->ext_sstc ? MENVCFG_STCE : 0) | (cfg->ext_svadu ? MENVCFG_ADUE : 0); } +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & MENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= MENVCFG_PMM; +} env->menvcfg = (env->menvcfg & ~mask) | (val & mask); return RISCV_EXCP_NONE; @@ -2074,6 +2081,10 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, target_ulong val) { uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE; +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & SENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= SENVCFG_PMM; +} RISCVException ret; ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG); diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 860fe56d43..5e9c5b43ab 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -153,9 +153,8 @@ static const VMStateDescription vmstate_vector = { static bool pointermasking_needed(void *opaque) { RISCVCPU *cpu = opaque; -CPURISCVState *env = &cpu->env; -return riscv_has_ext(env, RVJ); +return cpu->cfg.ext_ssnpm || cpu->cfg.ext_smnpm || cpu->cfg.ext_smmpm; } static const VMStateDescription vmstate_pointermasking = { @@ -164,6 +163,9 @@ static const VMStateDescription vmstate_pointermasking = { .minimum_version_id = 1, .needed = pointermasking_needed, .fields = (VMStateField[]) { +VMSTATE_UINTTL(env.mseccfg, RISCVCPU), +VMSTATE_UINTTL(env.senvcfg, RISCVCPU), +VMSTATE_UINTTL(env.menvcfg, RISCVCPU), VMSTATE_END_OF_LIST() } }; diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c ind
[PATCH 5/6] target/riscv: Update address modify functions to take into account pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/translate.c | 21 +++-- target/riscv/vector_helper.c | 7 +++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 4c0d526b58..70bbead73b 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -581,7 +581,15 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_addi_tl(addr, src1, imm); -if (get_address_xl(ctx) == MXL_RV32) { +if (ctx->pm_enabled) { +tcg_gen_shl_tl(addr, addr, pm_pmlen); +/* sign extend address by first non-masked bit otherwise zero extend */ +if (ctx->pm_signext) { +tcg_gen_sar_tl(addr, addr, pm_pmlen); +} else { +tcg_gen_shr_tl(addr, addr, pm_pmlen); +} +} else if (get_address_xl(ctx) == MXL_RV32) { tcg_gen_ext32u_tl(addr, addr); } @@ -595,7 +603,16 @@ static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_add_tl(addr, src1, offs); -if (get_xl(ctx) == MXL_RV32) { +/* sign extend address by first non-masked bit */ +if (ctx->pm_enabled) { +tcg_gen_shl_tl(addr, addr, pm_pmlen); +/* sign extend address by first non-masked bit otherwise zero extend */ +if (ctx->pm_signext) { +tcg_gen_sar_tl(addr, addr, pm_pmlen); +} else { +tcg_gen_shr_tl(addr, addr, pm_pmlen); +} +} else if (get_xl(ctx) == MXL_RV32) { tcg_gen_ext32u_tl(addr, addr); } return addr; diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 8e7a8e80a0..d91bdcbbc0 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -94,6 +94,13 @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz) static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr) { +addr = addr << env->pm_pmlen; +/* sign/zero extend masked address by N-1 bit */ +if (env->pm_signext) { +addr = (target_long)addr >> env->pm_pmlen; +} else { +addr = addr >> env->pm_pmlen; +} return addr; } -- 2.34.1
Re: [RFC PATCH v2 1/6] target/riscv: Remove obsolete pointer masking extension code.
Hi Alistair, Thanks for the lightning fast reply! Could you please tell who should bump those numbers and to what values? Do you think I could submit this patch series for the review? Thanks пн, 18 дек. 2023 г. в 06:11, Alistair Francis : > On Sat, Dec 16, 2023 at 11:52 PM Alexey Baturo > wrote: > > > > From: Alexey Baturo > > > > Zjpm v0.8 is almost frozen and it's much simplier compared to the > existing one: > > The newer version doesn't allow to specify custom mask or base for > masking. > > Instead it allows only certain options for masking top bits. > > > > Signed-off-by: Alexey Baturo > > --- > > target/riscv/cpu.c | 10 -- > > target/riscv/cpu.h | 32 +--- > > target/riscv/cpu_bits.h | 82 - > > target/riscv/cpu_helper.c| 52 -- > > target/riscv/csr.c | 326 --- > > target/riscv/machine.c | 9 - > > target/riscv/translate.c | 27 +-- > > target/riscv/vector_helper.c | 2 +- > > 8 files changed, 10 insertions(+), 530 deletions(-) > > > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > > index 83c7c0cf07..1e6571ce99 100644 > > --- a/target/riscv/cpu.c > > +++ b/target/riscv/cpu.c > > @@ -710,13 +710,6 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE > *f, int flags) > > CSR_MSCRATCH, > > CSR_SSCRATCH, > > CSR_SATP, > > -CSR_MMTE, > > -CSR_UPMBASE, > > -CSR_UPMMASK, > > -CSR_SPMBASE, > > -CSR_SPMMASK, > > -CSR_MPMBASE, > > -CSR_MPMMASK, > > }; > > > > for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) { > > @@ -891,8 +884,6 @@ static void riscv_cpu_reset_hold(Object *obj) > > } > > i++; > > } > > -/* mmte is supposed to have pm.current hardwired to 1 */ > > -env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT); > > > > /* > > * Clear mseccfg and unlock all the PMP entries upon reset. > > @@ -906,7 +897,6 @@ static void riscv_cpu_reset_hold(Object *obj) > > pmp_unlock_entries(env); > > #endif > > env->xl = riscv_cpu_mxl(env); > > -riscv_cpu_update_mask(env); > > cs->exception_index = RISCV_EXCP_NONE; > > env->load_res = -1; > > set_default_nan_mode(1, &env->fp_status); > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > > index d74b361be6..73f7004936 100644 > > --- a/target/riscv/cpu.h > > +++ b/target/riscv/cpu.h > > @@ -374,18 +374,7 @@ struct CPUArchState { > > /* True if in debugger mode. */ > > bool debugger; > > > > -/* > > - * CSRs for PointerMasking extension > > - */ > > -target_ulong mmte; > > -target_ulong mpmmask; > > -target_ulong mpmbase; > > -target_ulong spmmask; > > -target_ulong spmbase; > > -target_ulong upmmask; > > -target_ulong upmbase; > > - > > -/* CSRs for execution environment configuration */ > > +/* CSRs for execution enviornment configuration */ > > uint64_t menvcfg; > > uint64_t mstateen[SMSTATEEN_MAX_COUNT]; > > uint64_t hstateen[SMSTATEEN_MAX_COUNT]; > > @@ -393,8 +382,6 @@ struct CPUArchState { > > target_ulong senvcfg; > > uint64_t henvcfg; > > #endif > > -target_ulong cur_pmmask; > > -target_ulong cur_pmbase; > > > > /* Fields from here on are preserved across CPU reset. */ > > QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ > > @@ -543,17 +530,14 @@ FIELD(TB_FLAGS, VILL, 14, 1) > > FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) > > /* The combination of MXL/SXL/UXL that applies to the current cpu mode. > */ > > FIELD(TB_FLAGS, XL, 16, 2) > > -/* If PointerMasking should be applied */ > > -FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1) > > -FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1) > > -FIELD(TB_FLAGS, VTA, 20, 1) > > -FIELD(TB_FLAGS, VMA, 21, 1) > > +FIELD(TB_FLAGS, VTA, 18, 1) > > +FIELD(TB_FLAGS, VMA, 19, 1) > > /* Native debug itrigger */ > > -FIELD(TB_FLAGS, ITRIGGER, 22, 1) > > +FIELD(TB_FLAGS, ITRIGGER, 20, 1) > > /* Virtual mode enabled */ > > -FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) > > -FIELD(TB_FLAGS, PRIV, 24, 2) > > -FIELD(TB_FLAGS, AXL, 26, 2) > > +FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) > > +FIELD(TB_FLAGS, PRIV, 22, 2) > > +FIELD(TB_FLAGS
[RFC PATCH v2 4/6] target/riscv: Add functions to calculate current number of masked bits for pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.h| 2 ++ target/riscv/cpu_helper.c | 49 +++ 2 files changed, 51 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 2099168950..9a8e5bc022 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -679,6 +679,8 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, uint64_t *cs_base, uint32_t *pflags); +void riscv_cpu_update_mask(CPURISCVState *env); + RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 79cddbd930..8e2751fef4 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -143,6 +143,55 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, *pflags = flags; } +void riscv_cpu_update_mask(CPURISCVState *env) +{ +#ifndef CONFIG_USER_ONLY +int priv_mode = cpu_address_mode(env); +int pmm = 0; +int pmlen = 0; +int satp_mode = 0; +if (riscv_cpu_mxl(env) == MXL_RV32) { +satp_mode = get_field(env->satp, SATP32_MODE); +} else { +satp_mode = get_field(env->satp, SATP64_MODE); +} +/* Get current PMM field */ +switch (priv_mode) { +case PRV_M: +pmm = riscv_cpu_cfg(env)->ext_smmpm ? + get_field(env->mseccfg, MSECCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_S: +pmm = riscv_cpu_cfg(env)->ext_smnpm ? + get_field(env->menvcfg, MENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +case PRV_U: +pmm = riscv_cpu_cfg(env)->ext_ssnpm ? + get_field(env->senvcfg, SENVCFG_PMM) : PMM_FIELD_DISABLED; +break; +default: +g_assert_not_reached(); +} +/* Get pmlen from PMM field */ +switch (pmm) { +case PMM_FIELD_DISABLED: +pmlen = 0; +break; +case PMM_FIELD_PMLEN7: +pmlen = 7; +break; +case PMM_FIELD_PMLEN16: +pmlen = 16; +break; +default: +g_assert_not_reached(); +} +/* in bare mode address is not sign extended */ +env->pm_signext = (satp_mode != VM_1_10_MBARE); +env->pm_pmlen = pmlen; +#endif +} + #ifndef CONFIG_USER_ONLY /* -- 2.34.1
[RFC PATCH v2 5/6] target/riscv: Update address modify functions to take into account pointer masking
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/translate.c | 21 +++-- target/riscv/vector_helper.c | 7 +++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 4c0d526b58..70bbead73b 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -581,7 +581,15 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_addi_tl(addr, src1, imm); -if (get_address_xl(ctx) == MXL_RV32) { +if (ctx->pm_enabled) { +tcg_gen_shl_tl(addr, addr, pm_pmlen); +/* sign extend address by first non-masked bit otherwise zero extend */ +if (ctx->pm_signext) { +tcg_gen_sar_tl(addr, addr, pm_pmlen); +} else { +tcg_gen_shr_tl(addr, addr, pm_pmlen); +} +} else if (get_address_xl(ctx) == MXL_RV32) { tcg_gen_ext32u_tl(addr, addr); } @@ -595,7 +603,16 @@ static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_add_tl(addr, src1, offs); -if (get_xl(ctx) == MXL_RV32) { +/* sign extend address by first non-masked bit */ +if (ctx->pm_enabled) { +tcg_gen_shl_tl(addr, addr, pm_pmlen); +/* sign extend address by first non-masked bit otherwise zero extend */ +if (ctx->pm_signext) { +tcg_gen_sar_tl(addr, addr, pm_pmlen); +} else { +tcg_gen_shr_tl(addr, addr, pm_pmlen); +} +} else if (get_xl(ctx) == MXL_RV32) { tcg_gen_ext32u_tl(addr, addr); } return addr; diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 8e7a8e80a0..d91bdcbbc0 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -94,6 +94,13 @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz) static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr) { +addr = addr << env->pm_pmlen; +/* sign/zero extend masked address by N-1 bit */ +if (env->pm_signext) { +addr = (target_long)addr >> env->pm_pmlen; +} else { +addr = addr >> env->pm_pmlen; +} return addr; } -- 2.34.1
[RFC PATCH v2 1/6] target/riscv: Remove obsolete pointer masking extension code.
From: Alexey Baturo Zjpm v0.8 is almost frozen and it's much simplier compared to the existing one: The newer version doesn't allow to specify custom mask or base for masking. Instead it allows only certain options for masking top bits. Signed-off-by: Alexey Baturo --- target/riscv/cpu.c | 10 -- target/riscv/cpu.h | 32 +--- target/riscv/cpu_bits.h | 82 - target/riscv/cpu_helper.c| 52 -- target/riscv/csr.c | 326 --- target/riscv/machine.c | 9 - target/riscv/translate.c | 27 +-- target/riscv/vector_helper.c | 2 +- 8 files changed, 10 insertions(+), 530 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 83c7c0cf07..1e6571ce99 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -710,13 +710,6 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) CSR_MSCRATCH, CSR_SSCRATCH, CSR_SATP, -CSR_MMTE, -CSR_UPMBASE, -CSR_UPMMASK, -CSR_SPMBASE, -CSR_SPMMASK, -CSR_MPMBASE, -CSR_MPMMASK, }; for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) { @@ -891,8 +884,6 @@ static void riscv_cpu_reset_hold(Object *obj) } i++; } -/* mmte is supposed to have pm.current hardwired to 1 */ -env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT); /* * Clear mseccfg and unlock all the PMP entries upon reset. @@ -906,7 +897,6 @@ static void riscv_cpu_reset_hold(Object *obj) pmp_unlock_entries(env); #endif env->xl = riscv_cpu_mxl(env); -riscv_cpu_update_mask(env); cs->exception_index = RISCV_EXCP_NONE; env->load_res = -1; set_default_nan_mode(1, &env->fp_status); diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index d74b361be6..73f7004936 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -374,18 +374,7 @@ struct CPUArchState { /* True if in debugger mode. */ bool debugger; -/* - * CSRs for PointerMasking extension - */ -target_ulong mmte; -target_ulong mpmmask; -target_ulong mpmbase; -target_ulong spmmask; -target_ulong spmbase; -target_ulong upmmask; -target_ulong upmbase; - -/* CSRs for execution environment configuration */ +/* CSRs for execution enviornment configuration */ uint64_t menvcfg; uint64_t mstateen[SMSTATEEN_MAX_COUNT]; uint64_t hstateen[SMSTATEEN_MAX_COUNT]; @@ -393,8 +382,6 @@ struct CPUArchState { target_ulong senvcfg; uint64_t henvcfg; #endif -target_ulong cur_pmmask; -target_ulong cur_pmbase; /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ @@ -543,17 +530,14 @@ FIELD(TB_FLAGS, VILL, 14, 1) FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 16, 2) -/* If PointerMasking should be applied */ -FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1) -FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1) -FIELD(TB_FLAGS, VTA, 20, 1) -FIELD(TB_FLAGS, VMA, 21, 1) +FIELD(TB_FLAGS, VTA, 18, 1) +FIELD(TB_FLAGS, VMA, 19, 1) /* Native debug itrigger */ -FIELD(TB_FLAGS, ITRIGGER, 22, 1) +FIELD(TB_FLAGS, ITRIGGER, 20, 1) /* Virtual mode enabled */ -FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) -FIELD(TB_FLAGS, PRIV, 24, 2) -FIELD(TB_FLAGS, AXL, 26, 2) +FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) +FIELD(TB_FLAGS, PRIV, 22, 2) +FIELD(TB_FLAGS, AXL, 24, 2) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) @@ -680,8 +664,6 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, uint64_t *cs_base, uint32_t *pflags); -void riscv_cpu_update_mask(CPURISCVState *env); - RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index ebd7917d49..3f9415d68d 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -491,37 +491,6 @@ #define CSR_MHPMCOUNTER30H 0xb9e #define CSR_MHPMCOUNTER31H 0xb9f -/* - * User PointerMasking registers - * NB: actual CSR numbers might be changed in future - */ -#define CSR_UMTE0x4c0 -#define CSR_UPMMASK 0x4c1 -#define CSR_UPMBASE 0x4c2 - -/* - * Machine PointerMasking registers - * NB: actual CSR numbers might be changed in future - */ -#define CSR_MMTE0x3c0 -#define CSR_MPMMASK 0x3c1 -#define CSR_MPMBASE 0x3c2 - -/* - * Supervisor PointerMaster registers - * NB: actual CSR numbers might be changed in future - */ -#define CSR_SMTE0x1c0 -#define CSR_SPMMASK 0x1c1 -#
[RFC PATCH v2 2/6] target/riscv: Add new CSR fields for S{sn, mn, m}pm extensions as part of Zjpm v0.8
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.h | 8 target/riscv/cpu_bits.h | 3 +++ target/riscv/cpu_cfg.h | 3 +++ target/riscv/csr.c | 11 +++ target/riscv/machine.c | 6 -- target/riscv/pmp.c | 13 ++--- target/riscv/pmp.h | 11 ++- 7 files changed, 45 insertions(+), 10 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 73f7004936..f49d4aa52c 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -102,6 +102,14 @@ typedef enum { EXT_STATUS_DIRTY, } RISCVExtStatus; +/* Enum holds PMM field values for Zjpm v0.8 extension */ +enum { +PMM_FIELD_DISABLED = 0, +PMM_FIELD_RESERVED = 1, +PMM_FIELD_PMLEN7 = 2, +PMM_FIELD_PMLEN16 = 3, +}; + #define MMU_USER_IDX 3 #define MAX_RISCV_PMPS (16) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 3f9415d68d..fcbbdc21c5 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -720,6 +720,7 @@ typedef enum RISCVException { #define MENVCFG_CBIE (3UL << 4) #define MENVCFG_CBCFE BIT(6) #define MENVCFG_CBZE BIT(7) +#define MENVCFG_PMM(3ULL << 32) #define MENVCFG_ADUE (1ULL << 61) #define MENVCFG_PBMTE (1ULL << 62) #define MENVCFG_STCE (1ULL << 63) @@ -733,11 +734,13 @@ typedef enum RISCVException { #define SENVCFG_CBIE MENVCFG_CBIE #define SENVCFG_CBCFE MENVCFG_CBCFE #define SENVCFG_CBZE MENVCFG_CBZE +#define SENVCFG_PMMMENVCFG_PMM #define HENVCFG_FIOM MENVCFG_FIOM #define HENVCFG_CBIE MENVCFG_CBIE #define HENVCFG_CBCFE MENVCFG_CBCFE #define HENVCFG_CBZE MENVCFG_CBZE +#define HENVCFG_PMMMENVCFG_PMM #define HENVCFG_ADUE MENVCFG_ADUE #define HENVCFG_PBMTE MENVCFG_PBMTE #define HENVCFG_STCE MENVCFG_STCE diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index f4605fb190..201f8af6ae 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -113,6 +113,9 @@ struct RISCVCPUConfig { bool ext_ssaia; bool ext_sscofpmf; bool ext_smepmp; +bool ext_ssnpm; +bool ext_smnpm; +bool ext_smmpm; bool rvv_ta_all_1s; bool rvv_ma_all_1s; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index ea4e1ac6ef..a67ba30494 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -527,6 +527,9 @@ static RISCVException have_mseccfg(CPURISCVState *env, int csrno) if (riscv_cpu_cfg(env)->ext_zkr) { return RISCV_EXCP_NONE; } +if (riscv_cpu_cfg(env)->ext_smmpm) { +return RISCV_EXCP_NONE; +} return RISCV_EXCP_ILLEGAL_INST; } @@ -2030,6 +2033,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, (cfg->ext_sstc ? MENVCFG_STCE : 0) | (cfg->ext_svadu ? MENVCFG_ADUE : 0); } +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & MENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= MENVCFG_PMM; +} env->menvcfg = (env->menvcfg & ~mask) | (val & mask); return RISCV_EXCP_NONE; @@ -2074,6 +2081,10 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, target_ulong val) { uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE; +/* Update PMM field only if the value is valid according to Zjpm v0.8 */ +if (((val & SENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) { +mask |= SENVCFG_PMM; +} RISCVException ret; ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG); diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 860fe56d43..5e9c5b43ab 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -153,9 +153,8 @@ static const VMStateDescription vmstate_vector = { static bool pointermasking_needed(void *opaque) { RISCVCPU *cpu = opaque; -CPURISCVState *env = &cpu->env; -return riscv_has_ext(env, RVJ); +return cpu->cfg.ext_ssnpm || cpu->cfg.ext_smnpm || cpu->cfg.ext_smmpm; } static const VMStateDescription vmstate_pointermasking = { @@ -164,6 +163,9 @@ static const VMStateDescription vmstate_pointermasking = { .minimum_version_id = 1, .needed = pointermasking_needed, .fields = (VMStateField[]) { +VMSTATE_UINTTL(env.mseccfg, RISCVCPU), +VMSTATE_UINTTL(env.senvcfg, RISCVCPU), +VMSTATE_UINTTL(env.menvcfg, RISCVCPU), VMSTATE_END_OF_LIST() } }; diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c ind
[RFC PATCH v2 0/6] Pointer Masking update to Zjpm v0.6.1
From: Alexey Baturo Hi all, It looks like Zjpm v0.8 is almost frozen and we don't expect it change drastically anymore. Compared to the original implementation with explicit base and mask CSRs, we now only have several fixed options for number of masked bits which are set using existing CSRs. Thanks [previous:] This series of patches intends to update RISC-V Pointer Masking implementation to the latest Zjpm v0.6.1 version. The Pointer Masking functionality is simplified compared to previous version of spec. The changes have been tested with handwritten assembly tests and LLVM HWASAN test suite. Thanks Alexey Baturo (6): target/riscv: Remove obsolete pointer masking extension code. target/riscv: Add new CSR fields for S{sn,mn,m}pm extensions as part of Zjpm v0.8 target/riscv: Add pointer masking tb flags target/riscv: Add functions to calculate current number of masked bits for pointer masking target/riscv: Update address modify functions to take into account pointer masking target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension target/riscv/cpu.c | 17 +- target/riscv/cpu.h | 35 ++-- target/riscv/cpu_bits.h | 85 + target/riscv/cpu_cfg.h | 3 + target/riscv/cpu_helper.c| 85 + target/riscv/csr.c | 339 ++- target/riscv/machine.c | 14 +- target/riscv/pmp.c | 14 +- target/riscv/pmp.h | 11 +- target/riscv/translate.c | 50 +++--- target/riscv/vector_helper.c | 9 +- 11 files changed, 143 insertions(+), 519 deletions(-) -- 2.34.1
[RFC PATCH v2 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.c| 9 + target/riscv/cpu_helper.c | 1 + target/riscv/csr.c| 4 target/riscv/machine.c| 1 + target/riscv/pmp.c| 1 + 5 files changed, 16 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 1e6571ce99..1d20e6a978 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -153,6 +153,9 @@ const RISCVIsaExtData isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval), ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot), ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt), +ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_12_0, ext_ssnpm), +ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_12_0, ext_smnpm), +ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_12_0, ext_smmpm), ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba), ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb), ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs), @@ -897,6 +900,7 @@ static void riscv_cpu_reset_hold(Object *obj) pmp_unlock_entries(env); #endif env->xl = riscv_cpu_mxl(env); +riscv_cpu_update_mask(env); cs->exception_index = RISCV_EXCP_NONE; env->load_res = -1; set_default_nan_mode(1, &env->fp_status); @@ -1337,6 +1341,11 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = { MULTI_EXT_CFG_BOOL("zmmul", ext_zmmul, false), +/* Zjpm v0.8 extensions */ +MULTI_EXT_CFG_BOOL("ssnpm", ext_ssnpm, false), +MULTI_EXT_CFG_BOOL("smnpm", ext_smnpm, false), +MULTI_EXT_CFG_BOOL("smmpm", ext_smmpm, false), + MULTI_EXT_CFG_BOOL("zca", ext_zca, false), MULTI_EXT_CFG_BOOL("zcb", ext_zcb, false), MULTI_EXT_CFG_BOOL("zcd", ext_zcd, false), diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 8e2751fef4..c2bc737dd7 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -723,6 +723,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv) /* tlb_flush is unnecessary as mode is contained in mmu_idx */ env->priv = newpriv; env->xl = cpu_recompute_xl(env); +riscv_cpu_update_mask(env); /* * Clear the load reservation - otherwise a reservation placed in one diff --git a/target/riscv/csr.c b/target/riscv/csr.c index a67ba30494..5336d91dd8 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -1348,6 +1348,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno, env->xl = cpu_recompute_xl(env); } +riscv_cpu_update_mask(env); return RISCV_EXCP_NONE; } @@ -2039,6 +2040,7 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, } env->menvcfg = (env->menvcfg & ~mask) | (val & mask); +riscv_cpu_update_mask(env); return RISCV_EXCP_NONE; } @@ -2093,6 +2095,8 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, } env->senvcfg = (env->senvcfg & ~mask) | (val & mask); + +riscv_cpu_update_mask(env); return RISCV_EXCP_NONE; } diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 5e9c5b43ab..41ad30c8e1 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -261,6 +261,7 @@ static int riscv_cpu_post_load(void *opaque, int version_id) CPURISCVState *env = &cpu->env; env->xl = cpu_recompute_xl(env); +riscv_cpu_update_mask(env); return 0; } diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c index 893ccd58d8..2cc08e58c5 100644 --- a/target/riscv/pmp.c +++ b/target/riscv/pmp.c @@ -607,6 +607,7 @@ void mseccfg_csr_write(CPURISCVState *env, target_ulong val) } env->mseccfg = val; +riscv_cpu_update_mask(env); } /* -- 2.34.1
[RFC PATCH v2 3/6] target/riscv: Add pointer masking tb flags
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/cpu.h| 19 +-- target/riscv/cpu_helper.c | 4 target/riscv/translate.c | 10 ++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index f49d4aa52c..2099168950 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -390,6 +390,10 @@ struct CPUArchState { target_ulong senvcfg; uint64_t henvcfg; #endif +/* current number of masked top bits by pointer masking */ +target_ulong pm_pmlen; +/* if pointer masking should do sign extension */ +bool pm_signext; /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ @@ -538,14 +542,17 @@ FIELD(TB_FLAGS, VILL, 14, 1) FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 16, 2) -FIELD(TB_FLAGS, VTA, 18, 1) -FIELD(TB_FLAGS, VMA, 19, 1) +/* If pointer masking should be applied and address sign extended */ +FIELD(TB_FLAGS, PM_ENABLED, 18, 1) +FIELD(TB_FLAGS, PM_SIGNEXTEND, 19, 1) +FIELD(TB_FLAGS, VTA, 20, 1) +FIELD(TB_FLAGS, VMA, 21, 1) /* Native debug itrigger */ -FIELD(TB_FLAGS, ITRIGGER, 20, 1) +FIELD(TB_FLAGS, ITRIGGER, 22, 1) /* Virtual mode enabled */ -FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) -FIELD(TB_FLAGS, PRIV, 22, 2) -FIELD(TB_FLAGS, AXL, 24, 2) +FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) +FIELD(TB_FLAGS, PRIV, 24, 2) +FIELD(TB_FLAGS, AXL, 25, 2) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index a3d477d226..79cddbd930 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -135,6 +135,10 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, flags = FIELD_DP32(flags, TB_FLAGS, VS, vs); flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl); flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env)); +if (env->pm_pmlen != 0) { +flags = FIELD_DP32(flags, TB_FLAGS, PM_ENABLED, 1); +} +flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, env->pm_signext); *pflags = flags; } diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 6b4b9a671c..4c0d526b58 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -42,6 +42,8 @@ static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart; static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */ static TCGv load_res; static TCGv load_val; +/* number of top masked address bits by pointer masking extension */ +static TCGv pm_pmlen; /* * If an operation is being performed on less than TARGET_LONG_BITS, @@ -103,6 +105,9 @@ typedef struct DisasContext { bool vl_eq_vlmax; CPUState *cs; TCGv zero; +/* pointer masking extension */ +bool pm_enabled; +bool pm_signext; /* Use icount trigger for native debug */ bool itrigger; /* FRM is known to contain a valid value. */ @@ -1176,6 +1181,8 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; +ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED); +ctx->pm_signext = FIELD_EX32(tb_flags, TB_FLAGS, PM_SIGNEXTEND); ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); ctx->virt_inst_excp = false; @@ -1307,4 +1314,7 @@ void riscv_translate_init(void) "load_res"); load_val = tcg_global_mem_new(tcg_env, offsetof(CPURISCVState, load_val), "load_val"); +/* Assign var with number of pointer masking masked bits to tcg global */ +pm_pmlen = tcg_global_mem_new(tcg_env, offsetof(CPURISCVState, pm_pmlen), + "pmlen"); } -- 2.34.1
[RFC v1 3/8] target/riscv: Add new bits in CSRs for Zjpm 0.6.1
Signed-off-by: Alexey Baturo --- target/riscv/cpu_bits.h | 6 ++ target/riscv/csr.c | 8 target/riscv/pmp.c | 5 + target/riscv/pmp.h | 12 +++- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 87a741fe66..238f7a13f4 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -714,6 +714,8 @@ typedef enum RISCVException { #define MENVCFG_CBIE (3UL << 4) #define MENVCFG_CBCFE BIT(6) #define MENVCFG_CBZE BIT(7) +#define MENVCFG_SPMEN BIT(8) +#define MENVCFG_SPMENSELF BIT(9) #define MENVCFG_HADE (1ULL << 61) #define MENVCFG_PBMTE (1ULL << 62) #define MENVCFG_STCE (1ULL << 63) @@ -727,11 +729,15 @@ typedef enum RISCVException { #define SENVCFG_CBIE MENVCFG_CBIE #define SENVCFG_CBCFE MENVCFG_CBCFE #define SENVCFG_CBZE MENVCFG_CBZE +#define SENVCFG_UPMEN MENVCFG_SPMEN +#define SENVCFG_UPMENSELF MENVCFG_SPMENSELF #define HENVCFG_FIOM MENVCFG_FIOM #define HENVCFG_CBIE MENVCFG_CBIE #define HENVCFG_CBCFE MENVCFG_CBCFE #define HENVCFG_CBZE MENVCFG_CBZE +#define HENVCFG_HPMEN MENVCFG_SPMEN +#define HENVCFG_HPMENSELF MENVCFG_SPMENSELF #define HENVCFG_HADE MENVCFG_HADE #define HENVCFG_PBMTE MENVCFG_PBMTE #define HENVCFG_STCE MENVCFG_STCE diff --git a/target/riscv/csr.c b/target/riscv/csr.c index a08285e55d..c7e59168d2 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -1942,6 +1942,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, (cfg->ext_sstc ? MENVCFG_STCE : 0) | (cfg->ext_svadu ? MENVCFG_HADE : 0); } +if (riscv_cpu_cfg(env)->ext_smnjpm) { +/* for zjpm v0.6.1 MENVCFG_SPMENSELF should be always 0 */ +mask |= MENVCFG_SPMEN; +} env->menvcfg = (env->menvcfg & ~mask) | (val & mask); return RISCV_EXCP_NONE; @@ -1993,6 +1997,10 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, return ret; } +if (riscv_cpu_cfg(env)->ext_ssnjpm) { +/* for zjpm v0.6.1 SENVCFG_UPMENSELF should be always 0 */ +mask |= SENVCFG_UPMEN; +} env->senvcfg = (env->senvcfg & ~mask) | (val & mask); return RISCV_EXCP_NONE; } diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c index 9d8db493e6..0db49173ef 100644 --- a/target/riscv/pmp.c +++ b/target/riscv/pmp.c @@ -580,6 +580,11 @@ void mseccfg_csr_write(CPURISCVState *env, target_ulong val) val &= ~(MSECCFG_MMWP | MSECCFG_MML | MSECCFG_RLB); } +if (riscv_cpu_cfg(env)->ext_smmjpm) { +/* for zjpm v0.6.1 MSECCFG_MPMENSELF should be always 0 */ +val &= ~MSECCFG_MPMENSELF; +} + env->mseccfg = val; } diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h index cf5c99f8e6..e4a58c9974 100644 --- a/target/riscv/pmp.h +++ b/target/riscv/pmp.h @@ -39,11 +39,13 @@ typedef enum { } pmp_am_t; typedef enum { -MSECCFG_MML = 1 << 0, -MSECCFG_MMWP = 1 << 1, -MSECCFG_RLB = 1 << 2, -MSECCFG_USEED = 1 << 8, -MSECCFG_SSEED = 1 << 9 +MSECCFG_MML = 1 << 0, +MSECCFG_MMWP = 1 << 1, +MSECCFG_RLB = 1 << 2, +MSECCFG_USEED = 1 << 8, +MSECCFG_SSEED = 1 << 9, +MSECCFG_MPMEN = 1 << 10, +MSECCFG_MPMENSELF = 1 << 11 } mseccfg_field_t; typedef struct { -- 2.34.1
[RFC v1 6/8] target/riscv: Add functions to calculate current N masked bits for pointer masking
Signed-off-by: Alexey Baturo --- target/riscv/cpu.h| 6 ++-- target/riscv/cpu_helper.c | 58 +++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 17d0088cb4..c87c4f26a2 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -91,11 +91,9 @@ typedef enum { /* Enum holds maximum for N bits to be ignored depending on privilege level */ typedef enum { PM_BARE_N_BITS = 16, -PM_SV32_N_BITS = 0, PM_SV39_N_BITS = 25, PM_SV48_N_BITS = 16, PM_SV57_N_BITS = 7, -PM_SV64_N_BITS = 0, } RISCVZjpmMaxNBits; #define MMU_USER_IDX 3 @@ -633,6 +631,10 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, uint64_t *cs_base, uint32_t *pflags); +void riscv_cpu_update_mask(CPURISCVState *env); +RISCVZjpmMaxNBits riscv_cpu_pm_get_n_bits(int satp_mode, int priv_mode); +bool riscv_cpu_pm_check_applicable(CPURISCVState *env, int priv_mode); + RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index b3871b0a28..6e68b2fc27 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -144,6 +144,64 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, *pflags = flags; } +/* + * Curernt Zjpm v0.6.1 spec doesn't strictly specify the exact value of N bits. + * It allows it to be dependent on both translation mode and priv level. + * For now let's ignore priv mode and always return max available value. + */ +RISCVZjpmMaxNBits riscv_cpu_pm_get_n_bits(int satp_mode, int priv_mode) +{ +switch (satp_mode) { +case VM_1_10_MBARE: +return PM_BARE_N_BITS; +case VM_1_10_SV39: +return PM_SV39_N_BITS; +case VM_1_10_SV48: +return PM_SV48_N_BITS; +case VM_1_10_SV57: +return PM_SV57_N_BITS; +default: +g_assert_not_reached(); +} +} + +/* For current priv level check if pointer masking should be applied */ +bool riscv_cpu_pm_check_applicable(CPURISCVState *env, int priv_mode) +{ +/* checks if appropriate extension is present and enable bit is set */ +switch (priv_mode) { +case PRV_M: +return riscv_cpu_cfg(env)->ext_smmjpm && env->mseccfg & MSECCFG_MPMEN; +case PRV_S: +return riscv_cpu_cfg(env)->ext_smnjpm && env->menvcfg & MENVCFG_SPMEN; +case PRV_U: +return riscv_cpu_cfg(env)->ext_ssnjpm && env->senvcfg & SENVCFG_UPMEN; +default: +g_assert_not_reached(); +} +g_assert_not_reached(); +return false; +} + +void riscv_cpu_update_mask(CPURISCVState *env) +{ +#ifndef CONFIG_USER_ONLY +int priv_mode = cpu_address_mode(env); +int satp_mode = 0; +if (riscv_cpu_mxl(env) == MXL_RV32) { +satp_mode = get_field(env->satp, SATP32_MODE); +} else { +satp_mode = get_field(env->satp, SATP64_MODE); +} +RISCVZjpmMaxNBits n_bits = riscv_cpu_pm_get_n_bits(satp_mode, priv_mode); +/* in bare mode address is not sign extended */ +env->pm_signext = (satp_mode != VM_1_10_MBARE); +/* if pointer masking is applicable set env variable */ +bool applicable = riscv_cpu_pm_check_applicable(env, priv_mode); +env->pm_n_bits = applicable ? n_bits : 0; +#endif +} + #ifndef CONFIG_USER_ONLY /* -- 2.34.1
[RFC v1 0/8] RISC-V Pointer Masking update to Zjpm v0.6.1
Hi all, This series of patches intends to update RISC-V Pointer Masking implementation to the latest Zjpm v0.6.1 version. The Pointer Masking functionality is simplified compared to previous version of spec. The changes have been tested with handwritten assembly tests and LLVM HWASAN test suite. Thanks Alexey Baturo (8): target/riscv: Remove obsolete pointer masking extension code target/riscv: Add new S{sn,mn,m}jpm extensions as part of Zjpm v0.6.1 target/riscv: Add new bits in CSRs for Zjpm 0.6.1 Add enum with maximum ignored bits depending on privilege level for Zjpm v0.6.1 target/riscv: Add pointer masking tb flags target/riscv: Add functions to calculate current N masked bits for pointer masking target/riscv: Update address modify functions to take into account pointer masking target/riscv: enable updates for pointer masking variables and thus enable pointer masking extension target/riscv/cpu.c | 18 +- target/riscv/cpu.h | 35 ++-- target/riscv/cpu_bits.h | 88 + target/riscv/cpu_cfg.h | 3 + target/riscv/cpu_helper.c| 99 ++- target/riscv/csr.c | 336 ++- target/riscv/machine.c | 14 +- target/riscv/pmp.c | 6 + target/riscv/pmp.h | 12 +- target/riscv/translate.c | 50 +++--- target/riscv/vector_helper.c | 9 +- 11 files changed, 152 insertions(+), 518 deletions(-) -- 2.34.1
[RFC v1 2/8] target/riscv: Add new S{sn, mn, m}jpm extensions as part of Zjpm v0.6.1
Signed-off-by: Alexey Baturo --- target/riscv/cpu.c | 7 +++ target/riscv/cpu_cfg.h | 3 +++ target/riscv/machine.c | 6 -- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index f937820976..af8f16b94f 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -137,6 +137,9 @@ static const struct isa_ext_data isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval), ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot), ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt), +ISA_EXT_DATA_ENTRY(ssnjpm, PRIV_VERSION_1_12_0, ext_ssnjpm), +ISA_EXT_DATA_ENTRY(smnjpm, PRIV_VERSION_1_12_0, ext_smnjpm), +ISA_EXT_DATA_ENTRY(smmjpm, PRIV_VERSION_1_12_0, ext_smmjpm), ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba), ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb), ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs), @@ -1796,6 +1799,10 @@ static Property riscv_cpu_extensions[] = { DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64), DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false), +/* Zjpm v0.6.1 extensions */ +DEFINE_PROP_BOOL("ssnjpm", RISCVCPU, cfg.ext_ssnjpm, false), +DEFINE_PROP_BOOL("smnjpm", RISCVCPU, cfg.ext_smnjpm, false), +DEFINE_PROP_BOOL("smmjpm", RISCVCPU, cfg.ext_smmjpm, false), DEFINE_PROP_BOOL("zca", RISCVCPU, cfg.ext_zca, false), DEFINE_PROP_BOOL("zcb", RISCVCPU, cfg.ext_zcb, false), diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index 2bd9510ba3..9e9eb7cd1d 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -93,6 +93,9 @@ struct RISCVCPUConfig { bool ext_smaia; bool ext_ssaia; bool ext_sscofpmf; +bool ext_ssnjpm; +bool ext_smnjpm; +bool ext_smmjpm; bool rvv_ta_all_1s; bool rvv_ma_all_1s; diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 8b1a109275..d50ff5421f 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -150,9 +150,8 @@ static const VMStateDescription vmstate_vector = { static bool pointermasking_needed(void *opaque) { RISCVCPU *cpu = opaque; -CPURISCVState *env = &cpu->env; -return riscv_has_ext(env, RVJ); +return cpu->cfg.ext_ssnjpm || cpu->cfg.ext_smnjpm || cpu->cfg.ext_smmjpm; } static const VMStateDescription vmstate_pointermasking = { @@ -161,6 +160,9 @@ static const VMStateDescription vmstate_pointermasking = { .minimum_version_id = 1, .needed = pointermasking_needed, .fields = (VMStateField[]) { +VMSTATE_UINTTL(env.mseccfg, RISCVCPU), +VMSTATE_UINTTL(env.senvcfg, RISCVCPU), +VMSTATE_UINTTL(env.menvcfg, RISCVCPU), VMSTATE_END_OF_LIST() } }; -- 2.34.1
[RFC v1 7/8] target/riscv: Update address modify functions to take into account pointer masking
Signed-off-by: Alexey Baturo --- target/riscv/translate.c | 21 +++-- target/riscv/vector_helper.c | 7 +++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 3434ba58b6..4aa0e2b9e1 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -581,7 +581,15 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_addi_tl(addr, src1, imm); -if (get_address_xl(ctx) == MXL_RV32) { +if (ctx->pm_enabled) { +tcg_gen_shl_tl(addr, addr, pm_n_bits); +/* sign extend address by first non-masked bit otherwise zero extend */ +if (ctx->pm_signext) { +tcg_gen_sar_tl(addr, addr, pm_n_bits); +} else { +tcg_gen_shr_tl(addr, addr, pm_n_bits); +} +} else if (get_address_xl(ctx) == MXL_RV32) { tcg_gen_ext32u_tl(addr, addr); } @@ -595,7 +603,16 @@ static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs) TCGv src1 = get_gpr(ctx, rs1, EXT_NONE); tcg_gen_add_tl(addr, src1, offs); -if (get_xl(ctx) == MXL_RV32) { +/* sign extend address by first non-masked bit */ +if (ctx->pm_enabled) { +tcg_gen_shl_tl(addr, addr, pm_n_bits); +/* sign extend address by first non-masked bit otherwise zero extend */ +if (ctx->pm_signext) { +tcg_gen_sar_tl(addr, addr, pm_n_bits); +} else { +tcg_gen_shr_tl(addr, addr, pm_n_bits); +} +} else if (get_xl(ctx) == MXL_RV32) { tcg_gen_ext32u_tl(addr, addr); } return addr; diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index af07e1067d..d3ddc2fd41 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -169,6 +169,13 @@ static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc, static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr) { +addr = addr << env->pm_n_bits; +/* sign/zero extend masked address by N-1 bit */ +if (env->pm_signext) { +addr = (target_long)addr >> env->pm_n_bits; +} else { +addr = addr >> env->pm_n_bits; +} return addr; } -- 2.34.1
[RFC v1 5/8] target/riscv: Add pointer masking tb flags
Signed-off-by: Alexey Baturo --- target/riscv/cpu.h| 19 +-- target/riscv/cpu_helper.c | 4 target/riscv/translate.c | 10 ++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 25fe60476b..17d0088cb4 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -356,6 +356,10 @@ struct CPUArchState { target_ulong senvcfg; uint64_t henvcfg; #endif +/* current number of masked top bits by pointer masking */ +target_ulong pm_n_bits; +/* if pointer masking should do sign extension */ +bool pm_signext; /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ @@ -492,14 +496,17 @@ FIELD(TB_FLAGS, VILL, 14, 1) FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 16, 2) -FIELD(TB_FLAGS, VTA, 18, 1) -FIELD(TB_FLAGS, VMA, 19, 1) +/* If pointer masking should be applied and address sign extended */ +FIELD(TB_FLAGS, PM_ENABLED, 18, 1) +FIELD(TB_FLAGS, PM_SIGNEXTEND, 19, 1) +FIELD(TB_FLAGS, VTA, 20, 1) +FIELD(TB_FLAGS, VMA, 21, 1) /* Native debug itrigger */ -FIELD(TB_FLAGS, ITRIGGER, 20, 1) +FIELD(TB_FLAGS, ITRIGGER, 22, 1) /* Virtual mode enabled */ -FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) -FIELD(TB_FLAGS, PRIV, 22, 2) -FIELD(TB_FLAGS, AXL, 24, 2) +FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) +FIELD(TB_FLAGS, PRIV, 24, 2) +FIELD(TB_FLAGS, AXL, 25, 2) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 57859314e3..b3871b0a28 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -136,6 +136,10 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, flags = FIELD_DP32(flags, TB_FLAGS, VS, vs); flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl); flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env)); +if (env->pm_n_bits != 0) { +flags = FIELD_DP32(flags, TB_FLAGS, PM_ENABLED, 1); +} +flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, env->pm_signext); *pflags = flags; } diff --git a/target/riscv/translate.c b/target/riscv/translate.c index ce47904590..3434ba58b6 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -42,6 +42,8 @@ static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart; static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */ static TCGv load_res; static TCGv load_val; +/* number of top masked address bits by pointer masking extension */ +static TCGv pm_n_bits; /* * If an operation is being performed on less than TARGET_LONG_BITS, @@ -103,6 +105,9 @@ typedef struct DisasContext { bool vl_eq_vlmax; CPUState *cs; TCGv zero; +/* pointer masking extension */ +bool pm_enabled; +bool pm_signext; /* Use icount trigger for native debug */ bool itrigger; /* FRM is known to contain a valid value. */ @@ -1175,6 +1180,8 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL); ctx->cs = cs; +ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED); +ctx->pm_signext = FIELD_EX32(tb_flags, TB_FLAGS, PM_SIGNEXTEND); ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); ctx->zero = tcg_constant_tl(0); ctx->virt_inst_excp = false; @@ -1306,4 +1313,7 @@ void riscv_translate_init(void) "load_res"); load_val = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_val), "load_val"); +/* Assign var with number of pointer masking masked bits to tcg global */ +pm_n_bits = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, pm_n_bits), + "pmbits"); } -- 2.34.1
[RFC v1 1/8] target/riscv: Remove obsolete pointer masking extension code
Signed-off-by: Alexey Baturo --- target/riscv/cpu.c | 12 -- target/riscv/cpu.h | 30 +--- target/riscv/cpu_bits.h | 82 - target/riscv/cpu_helper.c| 52 -- target/riscv/csr.c | 326 --- target/riscv/machine.c | 9 - target/riscv/translate.c | 27 +-- target/riscv/vector_helper.c | 2 +- 8 files changed, 9 insertions(+), 531 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 6b93b04453..f937820976 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -673,13 +673,6 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) CSR_MSCRATCH, CSR_SSCRATCH, CSR_SATP, -CSR_MMTE, -CSR_UPMBASE, -CSR_UPMMASK, -CSR_SPMBASE, -CSR_SPMMASK, -CSR_MPMBASE, -CSR_MPMMASK, }; for (int i = 0; i < ARRAY_SIZE(dump_csrs); ++i) { @@ -893,11 +886,8 @@ static void riscv_cpu_reset_hold(Object *obj) } i++; } -/* mmte is supposed to have pm.current hardwired to 1 */ -env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT); #endif env->xl = riscv_cpu_mxl(env); -riscv_cpu_update_mask(env); cs->exception_index = RISCV_EXCP_NONE; env->load_res = -1; set_default_nan_mode(1, &env->fp_status); @@ -1666,7 +1656,6 @@ static const MISAExtInfo misa_ext_info_arr[] = { MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"), MISA_EXT_INFO(RVU, "u", "User-level instructions"), MISA_EXT_INFO(RVH, "h", "Hypervisor"), -MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"), MISA_EXT_INFO(RVV, "v", "Vector operations"), MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"), }; @@ -1718,7 +1707,6 @@ static RISCVCPUMisaExtConfig misa_ext_cfgs[] = { MISA_CFG(RVS, true), MISA_CFG(RVU, true), MISA_CFG(RVH, true), -MISA_CFG(RVJ, false), MISA_CFG(RVV, false), MISA_CFG(RVG, false), }; diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 6ea22e0eea..62dabfa207 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -338,17 +338,6 @@ struct CPUArchState { /* True if in debugger mode. */ bool debugger; -/* - * CSRs for PointerMasking extension - */ -target_ulong mmte; -target_ulong mpmmask; -target_ulong mpmbase; -target_ulong spmmask; -target_ulong spmbase; -target_ulong upmmask; -target_ulong upmbase; - /* CSRs for execution enviornment configuration */ uint64_t menvcfg; uint64_t mstateen[SMSTATEEN_MAX_COUNT]; @@ -357,8 +346,6 @@ struct CPUArchState { target_ulong senvcfg; uint64_t henvcfg; #endif -target_ulong cur_pmmask; -target_ulong cur_pmbase; /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ @@ -495,17 +482,14 @@ FIELD(TB_FLAGS, VILL, 14, 1) FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 16, 2) -/* If PointerMasking should be applied */ -FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1) -FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1) -FIELD(TB_FLAGS, VTA, 20, 1) -FIELD(TB_FLAGS, VMA, 21, 1) +FIELD(TB_FLAGS, VTA, 18, 1) +FIELD(TB_FLAGS, VMA, 19, 1) /* Native debug itrigger */ -FIELD(TB_FLAGS, ITRIGGER, 22, 1) +FIELD(TB_FLAGS, ITRIGGER, 20, 1) /* Virtual mode enabled */ -FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1) -FIELD(TB_FLAGS, PRIV, 24, 2) -FIELD(TB_FLAGS, AXL, 26, 2) +FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1) +FIELD(TB_FLAGS, PRIV, 22, 2) +FIELD(TB_FLAGS, AXL, 24, 2) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) @@ -632,8 +616,6 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, uint64_t *cs_base, uint32_t *pflags); -void riscv_cpu_update_mask(CPURISCVState *env); - RISCVException riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 59f0ffd9e1..87a741fe66 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -491,37 +491,6 @@ #define CSR_MHPMCOUNTER30H 0xb9e #define CSR_MHPMCOUNTER31H 0xb9f -/* - * User PointerMasking registers - * NB: actual CSR numbers might be changed in future - */ -#define CSR_UMTE0x4c0 -#define CSR_UPMMASK 0x4c1 -#define CSR_UPMBASE 0x4c2 - -/* - * Machine PointerMasking registers - * NB: actual CSR numbers might be changed in future - */ -#define CSR_MMTE
[RFC v1 8/8] target/riscv: enable updates for pointer masking variables and thus enable pointer masking extension
Signed-off-by: Alexey Baturo --- target/riscv/cpu.c| 1 + target/riscv/cpu_helper.c | 1 + target/riscv/csr.c| 4 target/riscv/machine.c| 1 + target/riscv/pmp.c| 1 + 5 files changed, 8 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index af8f16b94f..928d4b5f5c 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -891,6 +891,7 @@ static void riscv_cpu_reset_hold(Object *obj) } #endif env->xl = riscv_cpu_mxl(env); +riscv_cpu_update_mask(env); cs->exception_index = RISCV_EXCP_NONE; env->load_res = -1; set_default_nan_mode(1, &env->fp_status); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 6e68b2fc27..6cc1df4fcb 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -689,6 +689,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv) /* tlb_flush is unnecessary as mode is contained in mmu_idx */ env->priv = newpriv; env->xl = cpu_recompute_xl(env); +riscv_cpu_update_mask(env); /* * Clear the load reservation - otherwise a reservation placed in one diff --git a/target/riscv/csr.c b/target/riscv/csr.c index c7e59168d2..7fe0d83877 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -1321,6 +1321,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno, env->xl = cpu_recompute_xl(env); } +riscv_cpu_update_mask(env); return RISCV_EXCP_NONE; } @@ -1948,6 +1949,7 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, } env->menvcfg = (env->menvcfg & ~mask) | (val & mask); +riscv_cpu_update_mask(env); return RISCV_EXCP_NONE; } @@ -2002,6 +2004,8 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, mask |= SENVCFG_UPMEN; } env->senvcfg = (env->senvcfg & ~mask) | (val & mask); + +riscv_cpu_update_mask(env); return RISCV_EXCP_NONE; } diff --git a/target/riscv/machine.c b/target/riscv/machine.c index d50ff5421f..e63a9fc95f 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -258,6 +258,7 @@ static int riscv_cpu_post_load(void *opaque, int version_id) CPURISCVState *env = &cpu->env; env->xl = cpu_recompute_xl(env); +riscv_cpu_update_mask(env); return 0; } diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c index 0db49173ef..5ca536bac0 100644 --- a/target/riscv/pmp.c +++ b/target/riscv/pmp.c @@ -586,6 +586,7 @@ void mseccfg_csr_write(CPURISCVState *env, target_ulong val) } env->mseccfg = val; +riscv_cpu_update_mask(env); } /* -- 2.34.1
[RFC v1 4/8] Add enum with maximum ignored bits depending on privilege level for Zjpm v0.6.1
Signed-off-by: Alexey Baturo --- target/riscv/cpu.h | 10 ++ 1 file changed, 10 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 62dabfa207..25fe60476b 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -88,6 +88,16 @@ typedef enum { EXT_STATUS_DIRTY, } RISCVExtStatus; +/* Enum holds maximum for N bits to be ignored depending on privilege level */ +typedef enum { +PM_BARE_N_BITS = 16, +PM_SV32_N_BITS = 0, +PM_SV39_N_BITS = 25, +PM_SV48_N_BITS = 16, +PM_SV57_N_BITS = 7, +PM_SV64_N_BITS = 0, +} RISCVZjpmMaxNBits; + #define MMU_USER_IDX 3 #define MAX_RISCV_PMPS (16) -- 2.34.1
[PATCH 0/1] Fix pointer masking functionality for RISC-V
From: Alexey Baturo Hi, This patch fixes a typo which leads to broken pointer masking functionality for RISC-V. Thanks. Alexey Baturo (1): target/riscv: Fix typo and restore Pointer Masking functionality for RISC-V target/riscv/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -- 2.30.2
[PATCH 1/1] target/riscv: Fix typo and restore Pointer Masking functionality for RISC-V
From: Alexey Baturo Signed-off-by: Alexey Baturo --- target/riscv/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 63b04e8a94..86c19ea74e 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -544,7 +544,7 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm) tcg_gen_addi_tl(addr, src1, imm); if (ctx->pm_mask_enabled) { -tcg_gen_and_tl(addr, addr, pm_mask); +tcg_gen_andc_tl(addr, addr, pm_mask); } else if (get_xl(ctx) == MXL_RV32) { tcg_gen_ext32u_tl(addr, addr); } -- 2.30.2
[PATCH v17 7/8] target/riscv: Implement address masking functions required for RISC-V Pointer Masking extension
From: Anatoly Parshintsev Signed-off-by: Anatoly Parshintsev Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis --- target/riscv/cpu.h| 2 ++ target/riscv/cpu_helper.c | 18 ++ target/riscv/translate.c | 39 +-- 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index b2422e3f99..325908287d 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -410,6 +410,8 @@ FIELD(TB_FLAGS, HLSX, 10, 1) FIELD(TB_FLAGS, MSTATUS_HS_FS, 11, 2) /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ FIELD(TB_FLAGS, XL, 13, 2) +/* If PointerMasking should be applied */ +FIELD(TB_FLAGS, PM_ENABLED, 15, 1) #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 0d1132f39d..662228c238 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -107,6 +107,24 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_FS, get_field(env->mstatus_hs, MSTATUS_FS)); } +if (riscv_has_ext(env, RVJ)) { +int priv = flags & TB_FLAGS_PRIV_MMU_MASK; +bool pm_enabled = false; +switch (priv) { +case PRV_U: +pm_enabled = env->mmte & U_PM_ENABLE; +break; +case PRV_S: +pm_enabled = env->mmte & S_PM_ENABLE; +break; +case PRV_M: +pm_enabled = env->mmte & M_PM_ENABLE; +break; +default: +g_assert_not_reached(); +} +flags = FIELD_DP32(flags, TB_FLAGS, PM_ENABLED, pm_enabled); +} #endif flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env)); diff --git a/target/riscv/translate.c b/target/riscv/translate.c index a5e6fa145d..1d57bc97b5 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -36,6 +36,9 @@ static TCGv cpu_gpr[32], cpu_pc, cpu_vl; static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */ static TCGv load_res; static TCGv load_val; +/* globals for PM CSRs */ +static TCGv pm_mask[4]; +static TCGv pm_base[4]; #include "exec/gen-icount.h" @@ -83,6 +86,10 @@ typedef struct DisasContext { TCGv zero; /* Space for 3 operands plus 1 extra for address computation. */ TCGv temp[4]; +/* PointerMasking extension */ +bool pm_enabled; +TCGv pm_mask; +TCGv pm_base; } DisasContext; static inline bool has_ext(DisasContext *ctx, uint32_t ext) @@ -272,11 +279,20 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm) } /* - * Temp stub: generates address adjustment for PointerMasking + * Generates address adjustment for PointerMasking */ static TCGv gen_pm_adjust_address(DisasContext *s, TCGv src) { -return src; +TCGv temp; +if (!s->pm_enabled) { +/* Load unmodified address */ +return src; +} else { +temp = temp_new(s); +tcg_gen_andc_tl(temp, src, s->pm_mask); +tcg_gen_or_tl(temp, temp, s->pm_base); +return temp; +} } #ifndef CONFIG_USER_ONLY @@ -622,6 +638,10 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->cs = cs; ctx->ntemp = 0; memset(ctx->temp, 0, sizeof(ctx->temp)); +ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED); +int priv = tb_flags & TB_FLAGS_PRIV_MMU_MASK; +ctx->pm_mask = pm_mask[priv]; +ctx->pm_base = pm_base[priv]; ctx->zero = tcg_constant_tl(0); } @@ -735,4 +755,19 @@ void riscv_translate_init(void) "load_res"); load_val = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_val), "load_val"); +#ifndef CONFIG_USER_ONLY +/* Assign PM CSRs to tcg globals */ +pm_mask[PRV_U] = + tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmmask), "upmmask"); +pm_base[PRV_U] = + tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmbase), "upmbase"); +pm_mask[PRV_S] = + tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmmask), "spmmask"); +pm_base[PRV_S] = + tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmbase), "spmbase"); +pm_mask[PRV_M] = + tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmmask), "mpmmask"); +pm_base[PRV_M] = + tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmbase), "mpmbase"); +#endif } -- 2.30.2
[PATCH v17 3/8] target/riscv: Support CSRs required for RISC-V PM extension except for the h-mode
Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/cpu.c | 2 + target/riscv/cpu.h | 11 ++ target/riscv/csr.c | 285 + 3 files changed, 298 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 788fa0b11c..6b767a4a0b 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -367,6 +367,8 @@ static void riscv_cpu_reset(DeviceState *dev) env->mcause = 0; env->pc = env->resetvec; env->two_stage_lookup = false; +/* mmte is supposed to have pm.current hardwired to 1 */ +env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT); #endif cs->exception_index = RISCV_EXCP_NONE; env->load_res = -1; diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 1cfc6a53a0..b2422e3f99 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -238,6 +238,17 @@ struct CPURISCVState { /* True if in debugger mode. */ bool debugger; + +/* + * CSRs for PointerMasking extension + */ +target_ulong mmte; +target_ulong mpmmask; +target_ulong mpmbase; +target_ulong spmmask; +target_ulong spmbase; +target_ulong upmmask; +target_ulong upmbase; #endif float_status fp_status; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 69e4d65fcd..9f41954894 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -192,6 +192,16 @@ static RISCVException hmode32(CPURISCVState *env, int csrno) } +/* Checks if PointerMasking registers could be accessed */ +static RISCVException pointer_masking(CPURISCVState *env, int csrno) +{ +/* Check if j-ext is present */ +if (riscv_has_ext(env, RVJ)) { +return RISCV_EXCP_NONE; +} +return RISCV_EXCP_ILLEGAL_INST; +} + static RISCVException pmp(CPURISCVState *env, int csrno) { if (riscv_feature(env, RISCV_FEATURE_PMP)) { @@ -1425,6 +1435,268 @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } +/* + * Functions to access Pointer Masking feature registers + * We have to check if current priv lvl could modify + * csr in given mode + */ +static bool check_pm_current_disabled(CPURISCVState *env, int csrno) +{ +int csr_priv = get_field(csrno, 0x300); +int pm_current; + +/* + * If priv lvls differ that means we're accessing csr from higher priv lvl, + * so allow the access + */ +if (env->priv != csr_priv) { +return false; +} +switch (env->priv) { +case PRV_M: +pm_current = get_field(env->mmte, M_PM_CURRENT); +break; +case PRV_S: +pm_current = get_field(env->mmte, S_PM_CURRENT); +break; +case PRV_U: +pm_current = get_field(env->mmte, U_PM_CURRENT); +break; +default: +g_assert_not_reached(); +} +/* It's same priv lvl, so we allow to modify csr only if pm.current==1 */ +return !pm_current; +} + +static RISCVException read_mmte(CPURISCVState *env, int csrno, +target_ulong *val) +{ +*val = env->mmte & MMTE_MASK; +return RISCV_EXCP_NONE; +} + +static RISCVException write_mmte(CPURISCVState *env, int csrno, + target_ulong val) +{ +uint64_t mstatus; +target_ulong wpri_val = val & MMTE_MASK; + +if (val != wpri_val) { +qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n", + "MMTE: WPRI violation written 0x", val, + "vs expected 0x", wpri_val); +} +/* for machine mode pm.current is hardwired to 1 */ +wpri_val |= MMTE_M_PM_CURRENT; + +/* hardwiring pm.instruction bit to 0, since it's not supported yet */ +wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN); +env->mmte = wpri_val | PM_EXT_DIRTY; + +/* Set XS and SD bits, since PM CSRs are dirty */ +mstatus = env->mstatus | MSTATUS_XS; +write_mstatus(env, csrno, mstatus); +return RISCV_EXCP_NONE; +} + +static RISCVException read_smte(CPURISCVState *env, int csrno, +target_ulong *val) +{ +*val = env->mmte & SMTE_MASK; +return RISCV_EXCP_NONE; +} + +static RISCVException write_smte(CPURISCVState *env, int csrno, + target_ulong val) +{ +target_ulong wpri_val = val & SMTE_MASK; + +if (val != wpri_val) { +qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n", + "SMTE: WPRI violation written 0x", val, + "vs expected 0x", wpri_val); +} + +/* if pm.current==0 we can't modify current PM CSRs */ +if (check_pm_current_disabled(env, csrno)) { +return RISCV_EXCP_NONE; +} + +wpri_val |= (env->mmte & ~SMTE
[PATCH v17 8/8] target/riscv: Allow experimental J-ext to be turned on
Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis Reviewed-by: Bin Meng Reviewed-by: Richard Henderson --- target/riscv/cpu.c | 4 1 file changed, 4 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 16fac64806..7d53125dbc 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -562,6 +562,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) } set_vext_version(env, vext_version); } +if (cpu->cfg.ext_j) { +ext |= RVJ; +} set_misa(env, env->misa_mxl, ext); } @@ -637,6 +640,7 @@ static Property riscv_cpu_properties[] = { DEFINE_PROP_BOOL("x-zbc", RISCVCPU, cfg.ext_zbc, false), DEFINE_PROP_BOOL("x-zbs", RISCVCPU, cfg.ext_zbs, false), DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false), +DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false), DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false), DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec), DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128), -- 2.30.2
[PATCH v17 2/8] target/riscv: Add CSR defines for RISC-V PM extension
Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/cpu_bits.h | 96 + 1 file changed, 96 insertions(+) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index cffcd3a5df..aa0bce4e06 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -334,6 +334,38 @@ #define CSR_MHPMCOUNTER30H 0xb9e #define CSR_MHPMCOUNTER31H 0xb9f +/* + * User PointerMasking registers + * NB: actual CSR numbers might be changed in future + */ +#define CSR_UMTE0x4c0 +#define CSR_UPMMASK 0x4c1 +#define CSR_UPMBASE 0x4c2 + +/* + * Machine PointerMasking registers + * NB: actual CSR numbers might be changed in future + */ +#define CSR_MMTE0x3c0 +#define CSR_MPMMASK 0x3c1 +#define CSR_MPMBASE 0x3c2 + +/* + * Supervisor PointerMaster registers + * NB: actual CSR numbers might be changed in future + */ +#define CSR_SMTE0x1c0 +#define CSR_SPMMASK 0x1c1 +#define CSR_SPMBASE 0x1c2 + +/* + * Hypervisor PointerMaster registers + * NB: actual CSR numbers might be changed in future + */ +#define CSR_VSMTE 0x2c0 +#define CSR_VSPMMASK0x2c1 +#define CSR_VSPMBASE0x2c2 + /* mstatus CSR bits */ #define MSTATUS_UIE 0x0001 #define MSTATUS_SIE 0x0002 @@ -525,4 +557,68 @@ typedef enum RISCVException { #define MIE_UTIE (1 << IRQ_U_TIMER) #define MIE_SSIE (1 << IRQ_S_SOFT) #define MIE_USIE (1 << IRQ_U_SOFT) + +/* General PointerMasking CSR bits*/ +#define PM_ENABLE 0x0001ULL +#define PM_CURRENT 0x0002ULL +#define PM_INSN 0x0004ULL +#define PM_XS_MASK 0x0003ULL + +/* PointerMasking XS bits values */ +#define PM_EXT_DISABLE 0xULL +#define PM_EXT_INITIAL 0x0001ULL +#define PM_EXT_CLEAN0x0002ULL +#define PM_EXT_DIRTY0x0003ULL + +/* Offsets for every pair of control bits per each priv level */ +#define XS_OFFSET0ULL +#define U_OFFSET 2ULL +#define S_OFFSET 5ULL +#define M_OFFSET 8ULL + +#define PM_XS_BITS (PM_XS_MASK << XS_OFFSET) +#define U_PM_ENABLE (PM_ENABLE << U_OFFSET) +#define U_PM_CURRENT (PM_CURRENT << U_OFFSET) +#define U_PM_INSN(PM_INSN<< U_OFFSET) +#define S_PM_ENABLE (PM_ENABLE << S_OFFSET) +#define S_PM_CURRENT (PM_CURRENT << S_OFFSET) +#define S_PM_INSN(PM_INSN<< S_OFFSET) +#define M_PM_ENABLE (PM_ENABLE << M_OFFSET) +#define M_PM_CURRENT (PM_CURRENT << M_OFFSET) +#define M_PM_INSN(PM_INSN<< M_OFFSET) + +/* mmte CSR bits */ +#define MMTE_PM_XS_BITS PM_XS_BITS +#define MMTE_U_PM_ENABLEU_PM_ENABLE +#define MMTE_U_PM_CURRENT U_PM_CURRENT +#define MMTE_U_PM_INSN U_PM_INSN +#define MMTE_S_PM_ENABLES_PM_ENABLE +#define MMTE_S_PM_CURRENT S_PM_CURRENT +#define MMTE_S_PM_INSN S_PM_INSN +#define MMTE_M_PM_ENABLEM_PM_ENABLE +#define MMTE_M_PM_CURRENT M_PM_CURRENT +#define MMTE_M_PM_INSN M_PM_INSN +#define MMTE_MASK(MMTE_U_PM_ENABLE | MMTE_U_PM_CURRENT | MMTE_U_PM_INSN | \ + MMTE_S_PM_ENABLE | MMTE_S_PM_CURRENT | MMTE_S_PM_INSN | \ + MMTE_M_PM_ENABLE | MMTE_M_PM_CURRENT | MMTE_M_PM_INSN | \ + MMTE_PM_XS_BITS) + +/* (v)smte CSR bits */ +#define SMTE_PM_XS_BITS PM_XS_BITS +#define SMTE_U_PM_ENABLEU_PM_ENABLE +#define SMTE_U_PM_CURRENT U_PM_CURRENT +#define SMTE_U_PM_INSN U_PM_INSN +#define SMTE_S_PM_ENABLES_PM_ENABLE +#define SMTE_S_PM_CURRENT S_PM_CURRENT +#define SMTE_S_PM_INSN S_PM_INSN +#define SMTE_MASK(SMTE_U_PM_ENABLE | SMTE_U_PM_CURRENT | SMTE_U_PM_INSN | \ + SMTE_S_PM_ENABLE | SMTE_S_PM_CURRENT | SMTE_S_PM_INSN | \ + SMTE_PM_XS_BITS) + +/* umte CSR bits */ +#define UMTE_U_PM_ENABLEU_PM_ENABLE +#define UMTE_U_PM_CURRENT U_PM_CURRENT +#define UMTE_U_PM_INSN U_PM_INSN +#define UMTE_MASK (UMTE_U_PM_ENABLE | MMTE_U_PM_CURRENT | UMTE_U_PM_INSN) + #endif -- 2.30.2
[PATCH v17 4/8] target/riscv: Add J extension state description
Signed-off-by: Alexey Baturo Reviewed-by: Alistair Francis --- target/riscv/machine.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/target/riscv/machine.c b/target/riscv/machine.c index f64b2a96c1..7b4c739564 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -84,6 +84,14 @@ static bool vector_needed(void *opaque) return riscv_has_ext(env, RVV); } +static bool pointermasking_needed(void *opaque) +{ +RISCVCPU *cpu = opaque; +CPURISCVState *env = &cpu->env; + +return riscv_has_ext(env, RVJ); +} + static const VMStateDescription vmstate_vector = { .name = "cpu/vector", .version_id = 1, @@ -100,6 +108,24 @@ static const VMStateDescription vmstate_vector = { } }; +static const VMStateDescription vmstate_pointermasking = { +.name = "cpu/pointer_masking", +.version_id = 1, +.minimum_version_id = 1, +.needed = pointermasking_needed, +.fields = (VMStateField[]) { +VMSTATE_UINTTL(env.mmte, RISCVCPU), +VMSTATE_UINTTL(env.mpmmask, RISCVCPU), +VMSTATE_UINTTL(env.mpmbase, RISCVCPU), +VMSTATE_UINTTL(env.spmmask, RISCVCPU), +VMSTATE_UINTTL(env.spmbase, RISCVCPU), +VMSTATE_UINTTL(env.upmmask, RISCVCPU), +VMSTATE_UINTTL(env.upmbase, RISCVCPU), + +VMSTATE_END_OF_LIST() +} +}; + static const VMStateDescription vmstate_hyper = { .name = "cpu/hyper", .version_id = 1, @@ -191,6 +217,7 @@ const VMStateDescription vmstate_riscv_cpu = { &vmstate_pmp, &vmstate_hyper, &vmstate_vector, +&vmstate_pointermasking, NULL } }; -- 2.30.2
[PATCH v17 6/8] target/riscv: Support pointer masking for RISC-V for i/c/f/d/a types of instructions
Signed-off-by: Alexey Baturo Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis --- target/riscv/insn_trans/trans_rva.c.inc | 3 +++ target/riscv/insn_trans/trans_rvd.c.inc | 2 ++ target/riscv/insn_trans/trans_rvf.c.inc | 2 ++ target/riscv/insn_trans/trans_rvi.c.inc | 2 ++ target/riscv/translate.c| 8 5 files changed, 17 insertions(+) diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc index 6ea07d89b0..40fe132b04 100644 --- a/target/riscv/insn_trans/trans_rva.c.inc +++ b/target/riscv/insn_trans/trans_rva.c.inc @@ -25,6 +25,7 @@ static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop) if (a->rl) { tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL); } +src1 = gen_pm_adjust_address(ctx, src1); tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop); if (a->aq) { tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ); @@ -44,6 +45,7 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop) TCGLabel *l2 = gen_new_label(); src1 = get_gpr(ctx, a->rs1, EXT_ZERO); +src1 = gen_pm_adjust_address(ctx, src1); tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1); /* @@ -84,6 +86,7 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a, TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); +src1 = gen_pm_adjust_address(ctx, src1); func(dest, src1, src2, ctx->mem_idx, mop); gen_set_gpr(ctx, a->rd, dest); diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc index db9ae15755..64fb0046f7 100644 --- a/target/riscv/insn_trans/trans_rvd.c.inc +++ b/target/riscv/insn_trans/trans_rvd.c.inc @@ -31,6 +31,7 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a) tcg_gen_addi_tl(temp, addr, a->imm); addr = temp; } +addr = gen_pm_adjust_address(ctx, addr); tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEQ); @@ -51,6 +52,7 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a) tcg_gen_addi_tl(temp, addr, a->imm); addr = temp; } +addr = gen_pm_adjust_address(ctx, addr); tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEQ); diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc index bddbd418d9..b5459249c4 100644 --- a/target/riscv/insn_trans/trans_rvf.c.inc +++ b/target/riscv/insn_trans/trans_rvf.c.inc @@ -37,6 +37,7 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a) tcg_gen_addi_tl(temp, addr, a->imm); addr = temp; } +addr = gen_pm_adjust_address(ctx, addr); dest = cpu_fpr[a->rd]; tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL); @@ -59,6 +60,7 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a) tcg_gen_addi_tl(temp, addr, a->imm); addr = temp; } +addr = gen_pm_adjust_address(ctx, addr); tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL); diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc index 91dc438a3a..e51dbc41c5 100644 --- a/target/riscv/insn_trans/trans_rvi.c.inc +++ b/target/riscv/insn_trans/trans_rvi.c.inc @@ -144,6 +144,7 @@ static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop) tcg_gen_addi_tl(temp, addr, a->imm); addr = temp; } +addr = gen_pm_adjust_address(ctx, addr); tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop); gen_set_gpr(ctx, a->rd, dest); @@ -185,6 +186,7 @@ static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop) tcg_gen_addi_tl(temp, addr, a->imm); addr = temp; } +addr = gen_pm_adjust_address(ctx, addr); tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop); return true; diff --git a/target/riscv/translate.c b/target/riscv/translate.c index d38f87d718..a5e6fa145d 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -271,6 +271,14 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm) ctx->base.is_jmp = DISAS_NORETURN; } +/* + * Temp stub: generates address adjustment for PointerMasking + */ +static TCGv gen_pm_adjust_address(DisasContext *s, TCGv src) +{ +return src; +} + #ifndef CONFIG_USER_ONLY /* The states of mstatus_fs are: * 0 = disabled, 1 = initial, 2 = clean, 3 = dirty -- 2.30.2
[PATCH v17 1/8] target/riscv: Add J-extension into RISC-V
Signed-off-by: Alexey Baturo Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis Reviewed-by: Bin Meng --- target/riscv/cpu.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index a33dc30be8..1cfc6a53a0 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -65,6 +65,7 @@ #define RVS RV('S') #define RVU RV('U') #define RVH RV('H') +#define RVJ RV('J') /* S extension denotes that Supervisor mode exists, however it is possible to have a core that support S mode but does not have an MMU and there @@ -291,6 +292,7 @@ struct RISCVCPU { bool ext_s; bool ext_u; bool ext_h; +bool ext_j; bool ext_v; bool ext_zba; bool ext_zbb; -- 2.30.2
[PATCH v17 0/8] RISC-V Pointer Masking implementation
v16: Rebased against the latest tree v15: Renamed pm into pointer_masking in machine state. v14: Addressed Richard's comments from previous series. v13: Rebased QEMU and addressed Richard's comment. v12: Updated function for adjusting address with pointer masking to allocate and use temp register. v11: Addressed a few style issues Alistair mentioned in the previous review. Alexey Baturo (7): target/riscv: Add J-extension into RISC-V target/riscv: Add CSR defines for RISC-V PM extension target/riscv: Support CSRs required for RISC-V PM extension except for the h-mode target/riscv: Add J extension state description target/riscv: Print new PM CSRs in QEMU logs target/riscv: Support pointer masking for RISC-V for i/c/f/d/a types of instructions target/riscv: Allow experimental J-ext to be turned on Anatoly Parshintsev (1): target/riscv: Implement address masking functions required for RISC-V Pointer Masking extension target/riscv/cpu.c | 13 ++ target/riscv/cpu.h | 15 ++ target/riscv/cpu_bits.h | 96 target/riscv/cpu_helper.c | 18 ++ target/riscv/csr.c | 285 target/riscv/insn_trans/trans_rva.c.inc | 3 + target/riscv/insn_trans/trans_rvd.c.inc | 2 + target/riscv/insn_trans/trans_rvf.c.inc | 2 + target/riscv/insn_trans/trans_rvi.c.inc | 2 + target/riscv/machine.c | 27 +++ target/riscv/translate.c| 43 11 files changed, 506 insertions(+) -- 2.30.2