Re: [PATCH v9 0/6] Pointer Masking update for Zjpm v1.0

2024-05-14 Thread Alexey Baturo
>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

2024-05-13 Thread Alexey Baturo
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

2024-05-11 Thread Alexey Baturo
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

2024-05-11 Thread Alexey Baturo
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.

2024-05-11 Thread Alexey Baturo
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, >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 @@ static inline uint32_t vext_get_vlmax(uint32_t vlenb, 
uint32_t vsew,
 void cpu_g

[PATCH v9 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension

2024-05-11 Thread Alexey Baturo
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

2024-05-11 Thread Alexey Baturo
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

2024-05-11 Thread Alexey Baturo
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

2024-05-11 Thread Alexey Baturo
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 RESEND] virtio-net: fix bug 1451 aka "assert(!virtio_net_get_subqueue(nc)->async_tx.elem); "

2024-04-30 Thread Alexey Dobriyan
Reproducer from https://gitlab.com/qemu-project/qemu/-/issues/1451
creates small packet (1 segment, len = 10 == n->guest_hdr_len),
then destroys queue.

"if (n->host_hdr_len != n->guest_hdr_len)" is triggered, if body creates
zero length/zero segment packet as there is nothing after guest header.

qemu_sendv_packet_async() tries to send it.

slirp discards it because it is smaller than Ethernet header,
but returns 0 because tx hooks are supposed to return total length of data.

0 is propagated upwards and is interpreted as "packet has been sent"
which is terrible because queue is being destroyed, nobody is waiting for TX
to complete and assert it triggered.

Fix is discard such empty packets instead of sending them.

Length 1 packets will go via different codepath:

virtqueue_push(q->tx_vq, elem, 0);
virtio_notify(vdev, q->tx_vq);
g_free(elem);

and aren't problematic.

Signed-off-by: Alexey Dobriyan 
---

hopefully better changelog.
use "if (out_num < 1)" so that discard doesn't calculate iov length

 hw/net/virtio-net.c | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 24e5e7d347..3644bfd91b 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -2749,18 +2749,14 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
 out_sg = elem->out_sg;
 if (out_num < 1) {
 virtio_error(vdev, "virtio-net header not in first element");
-virtqueue_detach_element(q->tx_vq, elem, 0);
-g_free(elem);
-return -EINVAL;
+goto detach;
 }
 
 if (n->has_vnet_hdr) {
 if (iov_to_buf(out_sg, out_num, 0, , n->guest_hdr_len) <
 n->guest_hdr_len) {
 virtio_error(vdev, "virtio-net header incorrect");
-virtqueue_detach_element(q->tx_vq, elem, 0);
-g_free(elem);
-return -EINVAL;
+goto detach;
 }
 if (n->needs_vnet_hdr_swap) {
 virtio_net_hdr_swap(vdev, (void *) );
@@ -2791,6 +2787,11 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
  n->guest_hdr_len, -1);
 out_num = sg_num;
 out_sg = sg;
+
+if (out_num < 1) {
+virtio_error(vdev, "virtio-net nothing to send");
+goto detach;
+}
 }
 
 ret = qemu_sendv_packet_async(qemu_get_subqueue(n->nic, queue_index),
@@ -2811,6 +2812,11 @@ drop:
 }
 }
 return num_packets;
+
+detach:
+virtqueue_detach_element(q->tx_vq, elem, 0);
+g_free(elem);
+return -EINVAL;
 }
 
 static void virtio_net_tx_timer(void *opaque);
-- 
2.34.1




[PATCH 1/1] virtio-net: fix bug 1451 aka "assert(!virtio_net_get_subqueue(nc)->async_tx.elem); "

2024-04-09 Thread Alexey Dobriyan
Reproducer from https://gitlab.com/qemu-project/qemu/-/issues/1451
creates small packet (1 segment, len=10 == n->guest_hdr_len),
destroys queue.

"if (n->host_hdr_len != n->guest_hdr_len)" is triggered. There is
nothing after guest header, if body creates zero length/zero segment packet.

qemu_sendv_packet_async() tries to send it.

Packet is discarded inside net_slirp_receive() which returns number of
sent bytes which is 0.

0 is propagated upwards and is interpreted as "zero bytes has been sent"
which is terrible because queue is being destroyed, nobody is waiting
for TX to complete, TX complete hook is _not_ called and
assert(async_tx.elem) is eventually triggered.

The fix is to discard such phantom packets in virtio_net_flush_tx().

Signed-off-by: Alexey Dobriyan 
---
 hw/net/virtio-net.c | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 58014a92ad..e156f1d78c 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -2765,18 +2765,14 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
 out_sg = elem->out_sg;
 if (out_num < 1) {
 virtio_error(vdev, "virtio-net header not in first element");
-virtqueue_detach_element(q->tx_vq, elem, 0);
-g_free(elem);
-return -EINVAL;
+goto detach;
 }
 
 if (n->has_vnet_hdr) {
 if (iov_to_buf(out_sg, out_num, 0, , n->guest_hdr_len) <
 n->guest_hdr_len) {
 virtio_error(vdev, "virtio-net header incorrect");
-virtqueue_detach_element(q->tx_vq, elem, 0);
-g_free(elem);
-return -EINVAL;
+goto detach;
 }
 if (n->needs_vnet_hdr_swap) {
 virtio_net_hdr_swap(vdev, (void *) );
@@ -2807,6 +2803,11 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
  n->guest_hdr_len, -1);
 out_num = sg_num;
 out_sg = sg;
+
+if (out_num < 1) {
+virtio_error(vdev, "virtio-net nothing to send");
+goto detach;
+}
 }
 
 ret = qemu_sendv_packet_async(qemu_get_subqueue(n->nic, queue_index),
@@ -2827,6 +2828,11 @@ drop:
 }
 }
 return num_packets;
+
+detach:
+virtqueue_detach_element(q->tx_vq, elem, 0);
+g_free(elem);
+return -EINVAL;
 }
 
 static void virtio_net_tx_timer(void *opaque);
-- 
2.43.0




Re: [PATCH 1/1] virtio-net: fix bug 1451 aka "assert(!virtio_net_get_subqueue(nc)->async_tx.elem);"

2024-04-09 Thread Alexey Dobriyan
On Tue, Apr 09, 2024 at 12:41:39PM -0400, Michael S. Tsirkin wrote:
> On Tue, Apr 09, 2024 at 07:37:04PM +0300, Alexey Dobriyan wrote:
> > On Tue, Apr 09, 2024 at 02:51:38AM -0400, Michael S. Tsirkin wrote:
> > > On Fri, Apr 05, 2024 at 02:20:15PM +0300, Alexey Dobriyan wrote:
> > > > Don't send zero length packets in virtio_net_flush_tx().
> > > > 
> > > > Reproducer from https://gitlab.com/qemu-project/qemu/-/issues/1451
> > > > creates small packet (1 segment, len = 10 == n->guest_hdr_len),
> > > > destroys queue.
> > > > 
> > > > "if (n->host_hdr_len != n->guest_hdr_len)" is triggered, if body creates
> > > > zero length/zero segment packet, because there is nothing after guest
> > > > header.
> > > > 
> > > > qemu_sendv_packet_async() tries to send it.
> > > > 
> > > > slirp discards it because it is smaller than Ethernet header,
> > > > but returns 0.
> > > 
> > > won't the same issue trigger with a 1 byte packet
> > > as opposed to a 0 byte packet though?
> > 
> > I don't think so. Only "return 0" is problematic from 
> > qemu_sendv_packet_async().
> > ->deliver hooks are supposed to return total length, so 1 should be fine.
> 
> 
> But you said it's smaller than Ethernet is the problem?

No, the problem is iov_cnt=0 packet is being generated, which enters
qemu_sendv_packet_async(), discarded inside slirp driver, but
net_slirp_receive() returns 0 which is the length of meaningless packet.
which is propagated upwards.

> > > > 0 length is propagated upwards and is interpreted as "packet has been 
> > > > sent"
> > > > which is terrible because queue is being destroyed, nothing has been 
> > > > sent,
> > > > nobody is waiting for TX to complete and assert it triggered.
> > > > 
> > > > Signed-off-by: Alexey Dobriyan 
> > > > ---
> > > >  hw/net/virtio-net.c | 18 --
> > > >  1 file changed, 12 insertions(+), 6 deletions(-)
> > > > 
> > > > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > > > index 58014a92ad..258633f885 100644
> > > > --- a/hw/net/virtio-net.c
> > > > +++ b/hw/net/virtio-net.c
> > > > @@ -2765,18 +2765,14 @@ static int32_t 
> > > > virtio_net_flush_tx(VirtIONetQueue *q)
> > > >  out_sg = elem->out_sg;
> > > >  if (out_num < 1) {
> > > >  virtio_error(vdev, "virtio-net header not in first 
> > > > element");
> > > > -virtqueue_detach_element(q->tx_vq, elem, 0);
> > > > -g_free(elem);
> > > > -return -EINVAL;
> > > > +goto detach;
> > > >  }
> > > >  
> > > >  if (n->has_vnet_hdr) {
> > > >  if (iov_to_buf(out_sg, out_num, 0, , 
> > > > n->guest_hdr_len) <
> > > >  n->guest_hdr_len) {
> > > >  virtio_error(vdev, "virtio-net header incorrect");
> > > > -virtqueue_detach_element(q->tx_vq, elem, 0);
> > > > -g_free(elem);
> > > > -return -EINVAL;
> > > > +goto detach;
> > > >  }
> > > >  if (n->needs_vnet_hdr_swap) {
> > > >  virtio_net_hdr_swap(vdev, (void *) );
> > > > @@ -2807,6 +2803,11 @@ static int32_t 
> > > > virtio_net_flush_tx(VirtIONetQueue *q)
> > > >   n->guest_hdr_len, -1);
> > > >  out_num = sg_num;
> > > >  out_sg = sg;
> > > > +
> > > > +if (iov_size(out_sg, out_num) == 0) {
> > > > +virtio_error(vdev, "virtio-net nothing to send");
> > > > +goto detach;
> > > > +}
> > > >  }
> > > >  
> > > >  ret = qemu_sendv_packet_async(qemu_get_subqueue(n->nic, 
> > > > queue_index),
> > > > @@ -2827,6 +2828,11 @@ drop:
> > > >  }
> > > >  }
> > > >  return num_packets;
> > > > +
> > > > +detach:
> > > > +virtqueue_detach_element(q->tx_vq, elem, 0);
> > > > +g_free(elem);
> > > > +return -EINVAL;
> > > >  }
> > > >  
> > > >  static void virtio_net_tx_timer(void *opaque);
> > > > -- 
> > > > 2.34.1
> > > 
> 



Re: [PATCH 1/1] virtio-net: fix bug 1451 aka "assert(!virtio_net_get_subqueue(nc)->async_tx.elem);"

2024-04-09 Thread Alexey Dobriyan
On Tue, Apr 09, 2024 at 02:51:38AM -0400, Michael S. Tsirkin wrote:
> On Fri, Apr 05, 2024 at 02:20:15PM +0300, Alexey Dobriyan wrote:
> > Don't send zero length packets in virtio_net_flush_tx().
> > 
> > Reproducer from https://gitlab.com/qemu-project/qemu/-/issues/1451
> > creates small packet (1 segment, len = 10 == n->guest_hdr_len),
> > destroys queue.
> > 
> > "if (n->host_hdr_len != n->guest_hdr_len)" is triggered, if body creates
> > zero length/zero segment packet, because there is nothing after guest
> > header.
> > 
> > qemu_sendv_packet_async() tries to send it.
> > 
> > slirp discards it because it is smaller than Ethernet header,
> > but returns 0.
> 
> won't the same issue trigger with a 1 byte packet
> as opposed to a 0 byte packet though?

I don't think so. Only "return 0" is problematic from qemu_sendv_packet_async().
->deliver hooks are supposed to return total length, so 1 should be fine.

> > 0 length is propagated upwards and is interpreted as "packet has been sent"
> > which is terrible because queue is being destroyed, nothing has been sent,
> > nobody is waiting for TX to complete and assert it triggered.
> > 
> > Signed-off-by: Alexey Dobriyan 
> > ---
> >  hw/net/virtio-net.c | 18 --
> >  1 file changed, 12 insertions(+), 6 deletions(-)
> > 
> > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > index 58014a92ad..258633f885 100644
> > --- a/hw/net/virtio-net.c
> > +++ b/hw/net/virtio-net.c
> > @@ -2765,18 +2765,14 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue 
> > *q)
> >  out_sg = elem->out_sg;
> >  if (out_num < 1) {
> >  virtio_error(vdev, "virtio-net header not in first element");
> > -virtqueue_detach_element(q->tx_vq, elem, 0);
> > -g_free(elem);
> > -return -EINVAL;
> > +goto detach;
> >  }
> >  
> >  if (n->has_vnet_hdr) {
> >  if (iov_to_buf(out_sg, out_num, 0, , n->guest_hdr_len) <
> >  n->guest_hdr_len) {
> >  virtio_error(vdev, "virtio-net header incorrect");
> > -virtqueue_detach_element(q->tx_vq, elem, 0);
> > -g_free(elem);
> > -return -EINVAL;
> > +goto detach;
> >  }
> >  if (n->needs_vnet_hdr_swap) {
> >  virtio_net_hdr_swap(vdev, (void *) );
> > @@ -2807,6 +2803,11 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
> >   n->guest_hdr_len, -1);
> >  out_num = sg_num;
> >  out_sg = sg;
> > +
> > +if (iov_size(out_sg, out_num) == 0) {
> > +virtio_error(vdev, "virtio-net nothing to send");
> > +goto detach;
> > +}
> >  }
> >  
> >  ret = qemu_sendv_packet_async(qemu_get_subqueue(n->nic, 
> > queue_index),
> > @@ -2827,6 +2828,11 @@ drop:
> >  }
> >  }
> >  return num_packets;
> > +
> > +detach:
> > +virtqueue_detach_element(q->tx_vq, elem, 0);
> > +g_free(elem);
> > +return -EINVAL;
> >  }
> >  
> >  static void virtio_net_tx_timer(void *opaque);
> > -- 
> > 2.34.1
> 



Re: [PATCH 1/1] virtio-net: fix bug 1451 aka "assert(!virtio_net_get_subqueue(nc)->async_tx.elem);"

2024-04-09 Thread Alexey Dobriyan
On Mon, Apr 08, 2024 at 03:26:35PM +0800, Jason Wang wrote:
> On Fri, Apr 5, 2024 at 7:22 PM Alexey Dobriyan  
> wrote:
> >
> > Don't send zero length packets in virtio_net_flush_tx().
> >
> > Reproducer from https://gitlab.com/qemu-project/qemu/-/issues/1451
> > creates small packet (1 segment, len = 10 == n->guest_hdr_len),
> > destroys queue.
> >
> > "if (n->host_hdr_len != n->guest_hdr_len)" is triggered, if body creates
> > zero length/zero segment packet, because there is nothing after guest
> > header.
> 
> And in this case host_hdr_len is 0.

Yes.

> > qemu_sendv_packet_async() tries to send it.
> >
> > slirp discards it because it is smaller than Ethernet header,
> > but returns 0.
> >
> > 0 length is propagated upwards and is interpreted as "packet has been sent"
> > which is terrible because queue is being destroyed, nothing has been sent,
> > nobody is waiting for TX to complete and assert it triggered.

> > @@ -2807,6 +2803,11 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
> >   n->guest_hdr_len, -1);
> >  out_num = sg_num;
> >  out_sg = sg;
> > +
> > +if (iov_size(out_sg, out_num) == 0) {
> > +virtio_error(vdev, "virtio-net nothing to send");
> > +goto detach;
> > +}
> 
> Nit, I think we can do this check before the iov_copy()?

I'd rather check for "badness" right before emitting packet.

> >  }
> >
> >  ret = qemu_sendv_packet_async(qemu_get_subqueue(n->nic, 
> > queue_index),
> > @@ -2827,6 +2828,11 @@ drop:
> >  }
> >  }
> >  return num_packets;
> > +
> > +detach:
> > +virtqueue_detach_element(q->tx_vq, elem, 0);
> > +g_free(elem);
> > +return -EINVAL;
> >  }
> >
> >  static void virtio_net_tx_timer(void *opaque);
> > --
> > 2.34.1
> >
> 



[PATCH 1/1] virtio-net: fix bug 1451 aka "assert(!virtio_net_get_subqueue(nc)->async_tx.elem); "

2024-04-05 Thread Alexey Dobriyan
Don't send zero length packets in virtio_net_flush_tx().

Reproducer from https://gitlab.com/qemu-project/qemu/-/issues/1451
creates small packet (1 segment, len = 10 == n->guest_hdr_len),
destroys queue.

"if (n->host_hdr_len != n->guest_hdr_len)" is triggered, if body creates
zero length/zero segment packet, because there is nothing after guest
header.

qemu_sendv_packet_async() tries to send it.

slirp discards it because it is smaller than Ethernet header,
but returns 0.

0 length is propagated upwards and is interpreted as "packet has been sent"
which is terrible because queue is being destroyed, nothing has been sent,
nobody is waiting for TX to complete and assert it triggered.

Signed-off-by: Alexey Dobriyan 
---
 hw/net/virtio-net.c | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 58014a92ad..258633f885 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -2765,18 +2765,14 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
 out_sg = elem->out_sg;
 if (out_num < 1) {
 virtio_error(vdev, "virtio-net header not in first element");
-virtqueue_detach_element(q->tx_vq, elem, 0);
-g_free(elem);
-return -EINVAL;
+goto detach;
 }
 
 if (n->has_vnet_hdr) {
 if (iov_to_buf(out_sg, out_num, 0, , n->guest_hdr_len) <
 n->guest_hdr_len) {
 virtio_error(vdev, "virtio-net header incorrect");
-virtqueue_detach_element(q->tx_vq, elem, 0);
-g_free(elem);
-return -EINVAL;
+goto detach;
 }
 if (n->needs_vnet_hdr_swap) {
 virtio_net_hdr_swap(vdev, (void *) );
@@ -2807,6 +2803,11 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
  n->guest_hdr_len, -1);
 out_num = sg_num;
 out_sg = sg;
+
+if (iov_size(out_sg, out_num) == 0) {
+virtio_error(vdev, "virtio-net nothing to send");
+goto detach;
+}
 }
 
 ret = qemu_sendv_packet_async(qemu_get_subqueue(n->nic, queue_index),
@@ -2827,6 +2828,11 @@ drop:
 }
 }
 return num_packets;
+
+detach:
+virtqueue_detach_element(q->tx_vq, elem, 0);
+g_free(elem);
+return -EINVAL;
 }
 
 static void virtio_net_tx_timer(void *opaque);
-- 
2.34.1




[PATCH v8 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension

2024-03-20 Thread Alexey Baturo
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

2024-03-20 Thread Alexey Baturo
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

2024-03-20 Thread Alexey Baturo
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

2024-03-20 Thread Alexey Baturo
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

2024-03-20 Thread Alexey Baturo
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

2024-03-20 Thread Alexey Baturo
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.

2024-03-20 Thread Alexey Baturo
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, >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_vlmax(uint32_t vlenb, 
uint32_t vsew,
 void cpu_get_tb_cpu_state(CPURISCVState *en

[PATCH v7 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension

2024-02-02 Thread Alexey Baturo
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.

2024-02-02 Thread Alexey Baturo
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, >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_vlmax(uint32_t vlenb, 
uint32_t vsew,
 void cpu_get_tb_cpu_state(CPURISCVState *en

[PATCH v7 0/6] Pointer Masking update for Zjpm v0.8

2024-02-02 Thread Alexey Baturo
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

2024-02-02 Thread Alexey Baturo
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

2024-02-02 Thread Alexey Baturo
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

2024-02-02 Thread Alexey Baturo
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

2024-02-02 Thread Alexey Baturo
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.

2024-02-01 Thread Alexey Baturo
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, >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
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
@@ -706,7 +689,6 @@ static inline 

[PATCH v6 5/6] target/riscv: Update address modify functions to take into account pointer masking

2024-02-01 Thread Alexey Baturo
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

2024-02-01 Thread Alexey Baturo
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

2024-02-01 Thread Alexey Baturo
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

2024-02-01 Thread Alexey Baturo
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

2024-02-01 Thread Alexey Baturo
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

2024-02-01 Thread Alexey Baturo
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

2024-01-29 Thread Alexey Baturo
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

2024-01-29 Thread Alexey Baturo
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

2024-01-29 Thread Alexey Baturo
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

2024-01-29 Thread Alexey Baturo
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.

2024-01-29 Thread Alexey Baturo
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, >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_state(CPURISCVState *env, vaddr *p

[PATCH v5 0/6] Pointer Masking update for Zjpm v0.8

2024-01-29 Thread Alexey Baturo
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

2024-01-29 Thread Alexey Baturo
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

2024-01-20 Thread Alexey Baturo
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

2024-01-09 Thread Alexey Baturo
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

2024-01-09 Thread Alexey Baturo
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

2024-01-09 Thread Alexey Baturo
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

2024-01-09 Thread Alexey Baturo
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

2024-01-09 Thread Alexey Baturo
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

2024-01-09 Thread Alexey Baturo
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.

2024-01-09 Thread Alexey Baturo
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, >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_state(CPURISCVState *env, vaddr *pc,
   

Re: [PATCH v3 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking

2024-01-04 Thread Alexey Baturo
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

2024-01-04 Thread Alexey Baturo
> +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.

2024-01-04 Thread Alexey Baturo
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, >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 ui

Re: [PATCH v3 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension

2024-01-04 Thread Alexey Baturo
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

2024-01-03 Thread Alexey Baturo
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 = >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

[PATCH v3 1/6] target/riscv: Remove obsolete pointer masking extension code.

2024-01-03 Thread Alexey Baturo
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, >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
-#define CSR_SPM

[PATCH v3 4/6] target/riscv: Add pointer masking tb flags

2024-01-03 Thread Alexey Baturo
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

2024-01-03 Thread Alexey Baturo
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

2024-01-03 Thread Alexey Baturo
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

2024-01-03 Thread Alexey Baturo
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

2024-01-03 Thread Alexey Baturo
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

2023-12-29 Thread Alexey Baturo
>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

2023-12-23 Thread Alexey Baturo
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

2023-12-23 Thread Alexey Baturo
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 = >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

[PATCH v2 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking

2023-12-23 Thread Alexey Baturo
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

2023-12-23 Thread Alexey Baturo
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.

2023-12-23 Thread Alexey Baturo
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, >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
-#define CSR_SPM

[PATCH v2 5/6] target/riscv: Update address modify functions to take into account pointer masking

2023-12-23 Thread Alexey Baturo
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

2023-12-23 Thread Alexey Baturo
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

2023-12-22 Thread Alexey Baturo
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_FLAGS, AXL);
> > 

Re: [PATCH] ppc/spapr: Fix ubsan warning with unaligned pointer access

2023-12-21 Thread Alexey Kardashevskiy




On 20/12/2023 12:45, Richard Henderson wrote:

On 12/16/23 16:14, Daniel Hoffman wrote:

Found while running QTest with UBsan. Unaligned pointers appear to be
valid, so moving the read to an explicit memcpy to an intermediate.
---
  hw/ppc/vof.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/vof.c b/hw/ppc/vof.c
index e3b430a81f4..609a51c645d 100644
--- a/hw/ppc/vof.c
+++ b/hw/ppc/vof.c
@@ -646,7 +646,10 @@ static void vof_dt_memory_available(void *fdt, 
GArray *claimed, uint64_t base)

  mem0_reg = fdt_getprop(fdt, offset, "reg", );
  g_assert(mem0_reg && proplen == sizeof(uint32_t) * (ac + sc));
  if (sc == 2) {
-    mem0_end = be64_to_cpu(*(uint64_t *)(mem0_reg + 
sizeof(uint32_t) * ac));

+    /* Pointer may be unaligned */
+    uint64_t mem0_end_copy;
+    memcpy(_end_copy, mem0_reg + sizeof(uint32_t) * ac, 
sizeof(mem0_end_copy));

+    mem0_end = be64_to_cpu(mem0_end_copy);


mem0_end = ldq_be_p(mem0_reg + sizeof(uint32_t) * ac);



+1 for ldq_be_p(). Or read lo 32bit chunks and combine. Thanks,




r~


--
Alexey




[PATCH 3/6] target/riscv: Add pointer masking tb flags

2023-12-21 Thread Alexey Baturo
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

2023-12-21 Thread Alexey Baturo
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

2023-12-21 Thread Alexey Baturo
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.

2023-12-21 Thread Alexey Baturo
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, >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
-#define CSR_SPM

[PATCH 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension

2023-12-21 Thread Alexey Baturo
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, >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 = >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

2023-12-21 Thread Alexey Baturo
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 = >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
index 162e88a90

[PATCH 5/6] target/riscv: Update address modify functions to take into account pointer masking

2023-12-21 Thread Alexey Baturo
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.

2023-12-18 Thread Alexey Baturo
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, >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)
> &g

[RFC PATCH v2 4/6] target/riscv: Add functions to calculate current number of masked bits for pointer masking

2023-12-16 Thread Alexey Baturo
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

2023-12-16 Thread Alexey Baturo
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.

2023-12-16 Thread Alexey Baturo
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, >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
-#define CSR_SPM

[RFC PATCH v2 2/6] target/riscv: Add new CSR fields for S{sn, mn, m}pm extensions as part of Zjpm v0.8

2023-12-16 Thread Alexey Baturo
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 = >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
index 162e88a90

[RFC PATCH v2 0/6] Pointer Masking update to Zjpm v0.6.1

2023-12-16 Thread Alexey Baturo
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

2023-12-16 Thread Alexey Baturo
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, >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 = >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

2023-12-16 Thread Alexey Baturo
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




[PULL SUBSYSTEM qemu-pseries] pseries: Update SLOF firmware image

2023-11-21 Thread Alexey Kardashevskiy
The following changes since commit af9264da80073435fd78944bc5a46e695897d7e5:

  Merge tag '20231119-xtensa-1' of https://github.com/OSLL/qemu-xtensa into 
staging (2023-11-20 05:25:19 -0500)

are available in the Git repository at:

  g...@github.com:aik/qemu.git tags/qemu-slof-20231121

for you to fetch changes up to b6838bf9c01c32bfecd5c446c98e788bbfd467d9:

  pseries: Update SLOF firmware image (2023-11-21 19:11:31 +1100)


Alexey Kardashevskiy (1):
  pseries: Update SLOF firmware image

 pc-bios/README   |   2 +-
 pc-bios/slof.bin | Bin 995176 -> 995000 bytes
 roms/SLOF|   2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)


*** Note: this is not for master, this is for pseries

Just an update, nothing major. Thanks everyone for keeping
an eye on this!

Compiled with  gcc-12.1.0-nolibc

Tested with:
 /home/aik/b/q-slof/qemu-system-ppc64 \
-nodefaults \
-chardev stdio,id=STDIO0,signal=off,mux=on \
-device spapr-vty,id=svty0,reg=0x71000110,chardev=STDIO0 \
-mon id=MON0,chardev=STDIO0,mode=readline \
-nographic \
-vga none \
-m 4G \
-kernel /home/aik/t/vml4150le \
-initrd /home/aik/t/le.cpio \
-machine 
pseries,cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken,cap-ccf-assist=off \
-bios pc-bios/slof.bin \
-trace events=/home/aik/qemu_trace_events \
-d guest_errors \
-chardev socket,id=SOCKET0,server=on,wait=off,path=qemu.mon.60616 \
-mon chardev=SOCKET0,mode=control \
-name 60616,debug-threads=on


The complete change log is:

Alexey Kardashevskiy (3):
  Remove ?PICK
  version: update to 20230918
  version: update to 20231121

Bernhard M. Wiedemann (1):
  Allow to override build date with SOURCE_DATE_EPOCH

Jordan Niethe (1):
  virtio-serial: Do not close stdout on quiesce

Kautuk Consul (1):
  virtio-serial: Make read and write methods report failure

Thomas Huth (10):
  lib/libnet/ipv6: Silence compiler warning from Clang
  Fix typos in the board-qemu folder
  Fix typos in the lib/libnet folder
  Fix typos in the remaining lib folders
  Fix typos in the slof folder
  Fix typos in the board-js2x folder
  Fix typos in the llfw folder
  Fix typos in the board-js2x folder
  Fix typos in the clients folder
  Fix remaining typos in various folders




[PULL SUBSYSTEM qemu-pseries] pseries: Update SLOF firmware image

2023-09-18 Thread Alexey Kardashevskiy
The following changes since commit 005ad32358f12fe9313a4a01918a55e60d4f39e5:

  Merge tag 'pull-tpm-2023-09-12-3' of https://github.com/stefanberger/qemu-tpm 
into staging (2023-09-13 13:41:57 -0400)

are available in the Git repository at:

  g...@github.com:aik/qemu.git tags/qemu-slof-20230918

for you to fetch changes up to b4f872c6bcbf71f60326988c76b240318c51bd16:

  pseries: Update SLOF firmware image (2023-09-18 19:14:44 +1000)


Alexey Kardashevskiy (1):
  pseries: Update SLOF firmware image

 pc-bios/README   |   2 +-
 pc-bios/slof.bin | Bin 995176 -> 995000 bytes
 roms/SLOF|   2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)


*** Note: this is not for master, this is for pseries

It's been a while. This fixes compile warning, typos and
a bug with virtio-serial being used after it was shutdown
at "quiesce".

The full changelog is here:

Alexey Kardashevskiy (2):
  Remove ?PICK
  version: update to 20230918

Jordan Niethe (1):
  virtio-serial: Do not close stdout on quiesce

Kautuk Consul (1):
  virtio-serial: Make read and write methods report failure

Thomas Huth (10):
  lib/libnet/ipv6: Silence compiler warning from Clang
  Fix typos in the board-qemu folder
  Fix typos in the lib/libnet folder
  Fix typos in the remaining lib folders
  Fix typos in the slof folder
  Fix typos in the board-js2x folder
  Fix typos in the llfw folder
  Fix typos in the board-js2x folder
  Fix typos in the clients folder
  Fix remaining typos in various folders

Compiled with gcc-12.1.0-nolibc

Tested with (sorry, no KVM):

/home/aik/b/q-slof/qemu-system-ppc64 \
-nodefaults \
-chardev stdio,id=STDIO0,signal=off,mux=on \
-device spapr-vty,id=svty0,reg=0x71000110,chardev=STDIO0 \
-mon id=MON0,chardev=STDIO0,mode=readline \
-nographic \
-vga none \
-m 2G \
-kernel /home/aik/t/vml4150le \
-initrd /home/aik/t/le.cpio \
-machine 
pseries,cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken,cap-ccf-assist=off \
-bios pc-bios/slof.bin \
-trace events=/home/aik/qemu_trace_events \
-d guest_errors \
-chardev socket,id=SOCKET0,server=on,wait=off,path=qemu.mon.604650 \
-mon chardev=SOCKET0,mode=control \
-name 604650,debug-threads=on




Re: [PATCH] MAINTAINERS: Nick Piggin PPC maintainer, other PPC changes

2023-09-18 Thread Alexey Kardashevskiy



On 18/09/2023 16:45, Nicholas Piggin wrote:

On Fri Sep 15, 2023 at 9:05 PM AEST, Daniel Henrique Barboza wrote:

Update all relevant PowerPC entries as follows:

- Nick Piggin is promoted to Maintainer in all qemu-ppc subsystems.
   Nick has  been a solid contributor for the last couple of years and
   has the required knowledge and motivation to drive the boat.

- Greg Kurz is being removed from all qemu-ppc entries. Greg has moved
   to other areas of interest and will retire from qemu-ppc.  Thanks Mr
   Kurz for all the years of service.

- David Gibson was removed as 'Reviewer' from PowerPC TCG CPUs and PPC
   KVM CPUs. Change done per his request.

- Daniel Barboza downgraded from 'Maintainer' to 'Reviewer' in sPAPR and
   PPC KVM CPUs. It has been a long since I last touched those areas and
   it's not justified to be kept as maintainer in them.

- Cedric Le Goater and Daniel Barboza removed as 'Reviewer' in VOF. We
   don't have the required knowledge to justify it.

- VOF support downgraded from 'Maintained' to 'Odd Fixes' since it
   better reflects the current state of the subsystem.



Oh, I forgot:

Acked-by: Nicholas Piggin 




And you also forgot to mention where on github/gitlab the ppc-next 
branch is hosted from now on, for SLOF releases :)  Today I'll use 
qemu/master.





Acked-by: Cédric Le Goater 
Signed-off-by: Daniel Henrique Barboza 
---
  MAINTAINERS | 20 +++-
  1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 00562f924f..c4aa1c1c9f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -298,11 +298,9 @@ F: hw/openrisc/
  F: tests/tcg/openrisc/
  
  PowerPC TCG CPUs

+M: Nicholas Piggin 
  M: Daniel Henrique Barboza 
  R: Cédric Le Goater 
-R: David Gibson 
-R: Greg Kurz 
-R: Nicholas Piggin 
  L: qemu-...@nongnu.org
  S: Odd Fixes
  F: target/ppc/
@@ -438,10 +436,9 @@ F: target/mips/kvm*
  F: target/mips/sysemu/
  
  PPC KVM CPUs

-M: Daniel Henrique Barboza 
+M: Nicholas Piggin 
+R: Daniel Henrique Barboza 
  R: Cédric Le Goater 
-R: David Gibson 
-R: Greg Kurz 
  S: Odd Fixes
  F: target/ppc/kvm.c
  
@@ -1430,10 +1427,10 @@ F: include/hw/rtc/m48t59.h

  F: tests/avocado/ppc_prep_40p.py
  
  sPAPR (pseries)

-M: Daniel Henrique Barboza 
+M: Nicholas Piggin 
+R: Daniel Henrique Barboza 
  R: Cédric Le Goater 
  R: David Gibson 
-R: Greg Kurz 
  R: Harsh Prateek Bora 
  L: qemu-...@nongnu.org
  S: Odd Fixes
@@ -1452,8 +1449,8 @@ F: tests/avocado/ppc_pseries.py
  
  PowerNV (Non-Virtualized)

  M: Cédric Le Goater 
+M: Nicholas Piggin 
  R: Frédéric Barrat 
-R: Nicholas Piggin 
  L: qemu-...@nongnu.org
  S: Odd Fixes
  F: docs/system/ppc/powernv.rst
@@ -1497,12 +1494,9 @@ F: include/hw/pci-host/mv64361.h
  
  Virtual Open Firmware (VOF)

  M: Alexey Kardashevskiy 
-R: Cédric Le Goater 
-R: Daniel Henrique Barboza 
  R: David Gibson 
-R: Greg Kurz 
  L: qemu-...@nongnu.org
-S: Maintained
+S: Odd Fixes
  F: hw/ppc/spapr_vof*
  F: hw/ppc/vof*
  F: include/hw/ppc/vof*




--
Alexey





[RFC v1 3/8] target/riscv: Add new bits in CSRs for Zjpm 0.6.1

2023-09-08 Thread Alexey Baturo
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

2023-09-08 Thread Alexey Baturo
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

2023-09-08 Thread Alexey Baturo
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

2023-09-08 Thread Alexey Baturo
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 = >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

2023-09-08 Thread 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 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

2023-09-08 Thread 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 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

2023-09-08 Thread Alexey Baturo
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, >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_MMTE0

[RFC v1 8/8] target/riscv: enable updates for pointer masking variables and thus enable pointer masking extension

2023-09-08 Thread Alexey Baturo
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, >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 = >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

2023-09-08 Thread Alexey Baturo
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




Re: [sdl-qemu] [PATCH] fix leaks found wtih fuzzing

2023-08-25 Thread Alexey Khoroshilov
On 25.08.2023 12:29, Dmitry Frolov wrote:
> It is true, that there is no problem during runtime
> from the first sight, because the memmory is lost just
> before qemu exits. Nevertheless, this change is necessary,
> because AddressSanitizer is not able to recognize this
> situation and produces crash-report (which is
> false-positive in fact). Lots of False-Positive warnings
> are davaluing problems, found with fuzzing, and thus the
> whole methodology of dynamic analysis.
> This patch eliminates such False-Positive reports,
> and makes every problem, found with fuzzing, more valuable.

It would be good to separe answer to the previous mail and commit message.

> 
> Fixes: 060ab76356 ("gtk: don't exit early in case gtk init fails")
> 
> Signed-off-by: Dmitry Frolov 
> ---
> v2: Moved declarations in the beginning.
> 
>  ui/gtk.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/ui/gtk.c b/ui/gtk.c
> index 8ba41c8f13..23a78787df 100644
> --- a/ui/gtk.c
> +++ b/ui/gtk.c
> @@ -2360,7 +2360,7 @@ static void gtk_display_init(DisplayState *ds, 
> DisplayOptions *opts)
>  {
>  VirtualConsole *vc;
>  
> -GtkDisplayState *s = g_malloc0(sizeof(*s));
> +GtkDisplayState *s;
>  GdkDisplay *window_display;
>  GtkIconTheme *theme;
>  char *dir;
> @@ -2372,6 +2372,7 @@ static void gtk_display_init(DisplayState *ds, 
> DisplayOptions *opts)
>  assert(opts->type == DISPLAY_TYPE_GTK);>  s->opts = opts;
's' is already used here.

>  
> +*s = g_malloc0(sizeof(*s));
s = g_malloc0(sizeof(*s));

>  theme = gtk_icon_theme_get_default();
>  dir = get_relocated_path(CONFIG_QEMU_ICONDIR);
>  gtk_icon_theme_prepend_search_path(theme, dir);


Otherwise, I belive the change makes sense.

--
Alexey Khoroshilov
Linux Verification Center, ISPRAS




  1   2   3   4   5   6   7   8   9   10   >