diff mbox series

[v2,5/5] target/riscv: Add pointer mask support for instruction fetch

Message ID 20230329032346.55185-6-liweiwei@iscas.ac.cn
State New
Headers show
Series target/riscv: Fix pointer mask related support | expand

Commit Message

Weiwei Li March 29, 2023, 3:23 a.m. UTC
Transform the fetch address in cpu_get_tb_cpu_state() when pointer
mask for instruction is enabled.
Enable PC-relative translation when J is enabled.

Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
---
 target/riscv/cpu.c        |  4 ++++
 target/riscv/cpu.h        |  1 +
 target/riscv/cpu_helper.c | 20 +++++++++++++++++++-
 target/riscv/csr.c        |  2 --
 4 files changed, 24 insertions(+), 3 deletions(-)

Comments

Richard Henderson March 29, 2023, 4:36 p.m. UTC | #1
On 3/28/23 20:23, Weiwei Li wrote:
> Transform the fetch address in cpu_get_tb_cpu_state() when pointer
> mask for instruction is enabled.
> Enable PC-relative translation when J is enabled.
> 
> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
> ---
>   target/riscv/cpu.c        |  4 ++++
>   target/riscv/cpu.h        |  1 +
>   target/riscv/cpu_helper.c | 20 +++++++++++++++++++-
>   target/riscv/csr.c        |  2 --
>   4 files changed, 24 insertions(+), 3 deletions(-)
> 
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 646fa31a59..99f0177c6d 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1193,6 +1193,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
>   
>   
>   #ifndef CONFIG_USER_ONLY
> +    if(cpu->cfg.ext_j) {
> +        cs->tcg_cflags |= CF_PCREL;
> +    }

"if ("

Consider enabling it always for system mode.  The reason for the existence of CF_PCREL is 
to improve performance with the guest kernel's address space randomization.  Each guest 
process maps libc.so (et al) at a different virtual address, and this allows those 
translations to be shared.

I would enable CF_PCREL in a separate patch from MMTE_*_PM_INSN.


r~
Weiwei Li March 30, 2023, 1:10 a.m. UTC | #2
On 2023/3/30 00:36, Richard Henderson wrote:
> On 3/28/23 20:23, Weiwei Li wrote:
>> Transform the fetch address in cpu_get_tb_cpu_state() when pointer
>> mask for instruction is enabled.
>> Enable PC-relative translation when J is enabled.
>>
>> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
>> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
>> ---
>>   target/riscv/cpu.c        |  4 ++++
>>   target/riscv/cpu.h        |  1 +
>>   target/riscv/cpu_helper.c | 20 +++++++++++++++++++-
>>   target/riscv/csr.c        |  2 --
>>   4 files changed, 24 insertions(+), 3 deletions(-)
>>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index 646fa31a59..99f0177c6d 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -1193,6 +1193,10 @@ static void riscv_cpu_realize(DeviceState 
>> *dev, Error **errp)
>>       #ifndef CONFIG_USER_ONLY
>> +    if(cpu->cfg.ext_j) {
>> +        cs->tcg_cflags |= CF_PCREL;
>> +    }
>
> "if ("
>
> Consider enabling it always for system mode.  The reason for the 
> existence of CF_PCREL is to improve performance with the guest 
> kernel's address space randomization.  Each guest process maps libc.so 
> (et al) at a different virtual address, and this allows those 
> translations to be shared.
>
> I would enable CF_PCREL in a separate patch from MMTE_*_PM_INSN.

OK. I'll update this in next version.

Regards,

Weiwei Li

>
>
> r~
diff mbox series

Patch

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 646fa31a59..99f0177c6d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1193,6 +1193,10 @@  static void riscv_cpu_realize(DeviceState *dev, Error **errp)
 
 
 #ifndef CONFIG_USER_ONLY
+    if(cpu->cfg.ext_j) {
+        cs->tcg_cflags |= CF_PCREL;
+    }
+
     if (cpu->cfg.ext_sstc) {
         riscv_timer_init(cpu);
     }
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 638e47c75a..57bd9c3279 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -368,6 +368,7 @@  struct CPUArchState {
 #endif
     target_ulong cur_pmmask;
     target_ulong cur_pmbase;
+    bool cur_pminsn;
 
     /* Fields from here on are preserved across CPU reset. */
     QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index f88c503cf4..b683a770fe 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -40,6 +40,19 @@  int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 #endif
 }
 
+static target_ulong adjust_pc_address(CPURISCVState *env, target_ulong pc)
+{
+    target_ulong adjust_pc = pc;
+
+    if (env->cur_pminsn) {
+        adjust_pc = (adjust_pc & ~env->cur_pmmask) | env->cur_pmbase;
+    } else if (env->xl == MXL_RV32) {
+        adjust_pc &= UINT32_MAX;
+    }
+
+    return adjust_pc;
+}
+
 void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
                           target_ulong *cs_base, uint32_t *pflags)
 {
@@ -48,7 +61,7 @@  void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
 
     uint32_t flags = 0;
 
-    *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
+    *pc = adjust_pc_address(env, env->pc);
     *cs_base = 0;
 
     if (cpu->cfg.ext_zve32f) {
@@ -124,6 +137,7 @@  void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
 void riscv_cpu_update_mask(CPURISCVState *env)
 {
     target_ulong mask = -1, base = 0;
+    bool insn = false;
     /*
      * TODO: Current RVJ spec does not specify
      * how the extension interacts with XLEN.
@@ -135,18 +149,21 @@  void riscv_cpu_update_mask(CPURISCVState *env)
             if (env->mmte & M_PM_ENABLE) {
                 mask = env->mpmmask;
                 base = env->mpmbase;
+                insn = env->mmte & MMTE_M_PM_INSN;
             }
             break;
         case PRV_S:
             if (env->mmte & S_PM_ENABLE) {
                 mask = env->spmmask;
                 base = env->spmbase;
+                insn = env->mmte & MMTE_S_PM_INSN;
             }
             break;
         case PRV_U:
             if (env->mmte & U_PM_ENABLE) {
                 mask = env->upmmask;
                 base = env->upmbase;
+                insn = env->mmte & MMTE_U_PM_INSN;
             }
             break;
         default:
@@ -161,6 +178,7 @@  void riscv_cpu_update_mask(CPURISCVState *env)
         env->cur_pmmask = mask;
         env->cur_pmbase = base;
     }
+    env->cur_pminsn = insn;
 }
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 43b9ad4500..0902b64129 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3518,8 +3518,6 @@  static RISCVException write_mmte(CPURISCVState *env, int csrno,
     /* for machine mode pm.current is hardwired to 1 */
     wpri_val |= MMTE_M_PM_CURRENT;
 
-    /* hardwiring pm.instruction bit to 0, since it's not supported yet */
-    wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
     env->mmte = wpri_val | PM_EXT_DIRTY;
     riscv_cpu_update_mask(env);