[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 18/50] target/riscv: Apply pointer masking for virtualized memory
From: |
Alistair Francis |
Subject: |
[PULL 18/50] target/riscv: Apply pointer masking for virtualized memory accesses |
Date: |
Fri, 17 Jan 2025 15:55:20 +1000 |
From: Alexey Baturo <baturo.alexey@gmail.com>
Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250106102346.1100149-7-baturo.alexey@gmail.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 1 +
target/riscv/internals.h | 54 ++++++++++++++++++++++++++++++++++++
target/riscv/cpu_helper.c | 19 +++++++++++++
target/riscv/op_helper.c | 16 +++++------
target/riscv/vector_helper.c | 21 --------------
5 files changed, 82 insertions(+), 29 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index f22e43c662..5e7152200f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -777,6 +777,7 @@ bool riscv_cpu_is_32bit(RISCVCPU *cpu);
bool riscv_cpu_virt_mem_enabled(CPURISCVState *env);
RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env);
+RISCVPmPmm riscv_pm_get_virt_pmm(CPURISCVState *env);
uint32_t riscv_pm_get_pmlen(RISCVPmPmm pmm);
RISCVException riscv_csrr(CPURISCVState *env, int csrno,
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 76934eaa7b..67291933f8 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -145,4 +145,58 @@ static inline float16 check_nanbox_h(CPURISCVState *env,
uint64_t f)
/* Our implementation of CPUClass::has_work */
bool riscv_cpu_has_work(CPUState *cs);
+/* Zjpm addr masking routine */
+static inline target_ulong adjust_addr_body(CPURISCVState *env,
+ target_ulong addr,
+ bool is_virt_addr)
+{
+ RISCVPmPmm pmm = PMM_FIELD_DISABLED;
+ uint32_t pmlen = 0;
+ bool signext = false;
+
+ /* do nothing for rv32 mode */
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ return addr;
+ }
+
+ /* get pmm field depending on whether addr is */
+ if (is_virt_addr) {
+ pmm = riscv_pm_get_virt_pmm(env);
+ } else {
+ pmm = riscv_pm_get_pmm(env);
+ }
+
+ /* if pointer masking is disabled, return original addr */
+ if (pmm == PMM_FIELD_DISABLED) {
+ return addr;
+ }
+
+ if (!is_virt_addr) {
+ signext = riscv_cpu_virt_mem_enabled(env);
+ }
+ addr = addr << pmlen;
+ pmlen = riscv_pm_get_pmlen(pmm);
+
+ /* sign/zero extend masked address by N-1 bit */
+ if (signext) {
+ addr = (target_long)addr >> pmlen;
+ } else {
+ addr = addr >> pmlen;
+ }
+
+ return addr;
+}
+
+static inline target_ulong adjust_addr(CPURISCVState *env,
+ target_ulong addr)
+{
+ return adjust_addr_body(env, addr, false);
+}
+
+static inline target_ulong adjust_addr_virt(CPURISCVState *env,
+ target_ulong addr)
+{
+ return adjust_addr_body(env, addr, true);
+}
+
#endif
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 8728541b99..2e307e4ea5 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -263,6 +263,25 @@ RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env)
#endif
}
+RISCVPmPmm riscv_pm_get_virt_pmm(CPURISCVState *env)
+{
+#ifndef CONFIG_USER_ONLY
+ int priv_mode = cpu_address_mode(env);
+
+ if (priv_mode == PRV_U) {
+ return get_field(env->hstatus, HSTATUS_HUPMM);
+ } else {
+ if (get_field(env->hstatus, HSTATUS_SPVP)) {
+ return get_field(env->henvcfg, HENVCFG_PMM);
+ } else {
+ return get_field(env->senvcfg, SENVCFG_PMM);
+ }
+ }
+#else
+ return PMM_FIELD_DISABLED;
+#endif
+}
+
bool riscv_cpu_virt_mem_enabled(CPURISCVState *env)
{
#ifndef CONFIG_USER_ONLY
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 29de8eb43d..952ef8b3ec 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -479,7 +479,7 @@ target_ulong helper_hyp_hlv_bu(CPURISCVState *env,
target_ulong addr)
int mmu_idx = check_access_hlsv(env, false, ra);
MemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
- return cpu_ldb_mmu(env, addr, oi, ra);
+ return cpu_ldb_mmu(env, adjust_addr_virt(env, addr), oi, ra);
}
target_ulong helper_hyp_hlv_hu(CPURISCVState *env, target_ulong addr)
@@ -488,7 +488,7 @@ target_ulong helper_hyp_hlv_hu(CPURISCVState *env,
target_ulong addr)
int mmu_idx = check_access_hlsv(env, false, ra);
MemOpIdx oi = make_memop_idx(MO_TEUW, mmu_idx);
- return cpu_ldw_mmu(env, addr, oi, ra);
+ return cpu_ldw_mmu(env, adjust_addr_virt(env, addr), oi, ra);
}
target_ulong helper_hyp_hlv_wu(CPURISCVState *env, target_ulong addr)
@@ -497,7 +497,7 @@ target_ulong helper_hyp_hlv_wu(CPURISCVState *env,
target_ulong addr)
int mmu_idx = check_access_hlsv(env, false, ra);
MemOpIdx oi = make_memop_idx(MO_TEUL, mmu_idx);
- return cpu_ldl_mmu(env, addr, oi, ra);
+ return cpu_ldl_mmu(env, adjust_addr_virt(env, addr), oi, ra);
}
target_ulong helper_hyp_hlv_d(CPURISCVState *env, target_ulong addr)
@@ -506,7 +506,7 @@ target_ulong helper_hyp_hlv_d(CPURISCVState *env,
target_ulong addr)
int mmu_idx = check_access_hlsv(env, false, ra);
MemOpIdx oi = make_memop_idx(MO_TEUQ, mmu_idx);
- return cpu_ldq_mmu(env, addr, oi, ra);
+ return cpu_ldq_mmu(env, adjust_addr_virt(env, addr), oi, ra);
}
void helper_hyp_hsv_b(CPURISCVState *env, target_ulong addr, target_ulong val)
@@ -515,7 +515,7 @@ void helper_hyp_hsv_b(CPURISCVState *env, target_ulong
addr, target_ulong val)
int mmu_idx = check_access_hlsv(env, false, ra);
MemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
- cpu_stb_mmu(env, addr, val, oi, ra);
+ cpu_stb_mmu(env, adjust_addr_virt(env, addr), val, oi, ra);
}
void helper_hyp_hsv_h(CPURISCVState *env, target_ulong addr, target_ulong val)
@@ -524,7 +524,7 @@ void helper_hyp_hsv_h(CPURISCVState *env, target_ulong
addr, target_ulong val)
int mmu_idx = check_access_hlsv(env, false, ra);
MemOpIdx oi = make_memop_idx(MO_TEUW, mmu_idx);
- cpu_stw_mmu(env, addr, val, oi, ra);
+ cpu_stw_mmu(env, adjust_addr_virt(env, addr), val, oi, ra);
}
void helper_hyp_hsv_w(CPURISCVState *env, target_ulong addr, target_ulong val)
@@ -533,7 +533,7 @@ void helper_hyp_hsv_w(CPURISCVState *env, target_ulong
addr, target_ulong val)
int mmu_idx = check_access_hlsv(env, false, ra);
MemOpIdx oi = make_memop_idx(MO_TEUL, mmu_idx);
- cpu_stl_mmu(env, addr, val, oi, ra);
+ cpu_stl_mmu(env, adjust_addr_virt(env, addr), val, oi, ra);
}
void helper_hyp_hsv_d(CPURISCVState *env, target_ulong addr, target_ulong val)
@@ -542,7 +542,7 @@ void helper_hyp_hsv_d(CPURISCVState *env, target_ulong
addr, target_ulong val)
int mmu_idx = check_access_hlsv(env, false, ra);
MemOpIdx oi = make_memop_idx(MO_TEUQ, mmu_idx);
- cpu_stq_mmu(env, addr, val, oi, ra);
+ cpu_stq_mmu(env, adjust_addr_virt(env, addr), val, oi, ra);
}
/*
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 0eea124b66..5386e3b97c 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -105,27 +105,6 @@ static inline uint32_t vext_max_elems(uint32_t desc,
uint32_t log2_esz)
return scale < 0 ? vlenb >> -scale : vlenb << scale;
}
-static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
-{
- if (riscv_cpu_mxl(env) == MXL_RV32) {
- return 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;
-}
-
/*
* This function checks watchpoint before real load operation.
*
--
2.47.1
- [PULL 08/50] target/riscv: add shvsatpa, (continued)
- [PULL 08/50] target/riscv: add shvsatpa, Alistair Francis, 2025/01/17
- [PULL 09/50] target/riscv: add shgatpa, Alistair Francis, 2025/01/17
- [PULL 10/50] target/riscv/tcg: add sha, Alistair Francis, 2025/01/17
- [PULL 11/50] target/riscv: use RISCVException enum in exception helpers, Alistair Francis, 2025/01/17
- [PULL 12/50] target/riscv: add trace in riscv_raise_exception(), Alistair Francis, 2025/01/17
- [PULL 13/50] target/riscv: Remove obsolete pointer masking extension code., Alistair Francis, 2025/01/17
- [PULL 14/50] target/riscv: Add new CSR fields for S{sn, mn, m}pm extensions as part of Zjpm v1.0, Alistair Francis, 2025/01/17
- [PULL 15/50] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking, Alistair Francis, 2025/01/17
- [PULL 16/50] target/riscv: Add pointer masking tb flags, Alistair Francis, 2025/01/17
- [PULL 17/50] target/riscv: Update address modify functions to take into account pointer masking, Alistair Francis, 2025/01/17
- [PULL 18/50] target/riscv: Apply pointer masking for virtualized memory accesses,
Alistair Francis <=
- [PULL 19/50] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension, Alistair Francis, 2025/01/17
- [PULL 20/50] target/riscv: Add 'ext_smrnmi' in the RISCVCPUConfig, Alistair Francis, 2025/01/17
- [PULL 21/50] target/riscv: Add Smrnmi CSRs, Alistair Francis, 2025/01/17
- [PULL 22/50] target/riscv: Handle Smrnmi interrupt and exception, Alistair Francis, 2025/01/17
- [PULL 23/50] target/riscv: Add Smrnmi mnret instruction, Alistair Francis, 2025/01/17
- [PULL 24/50] target/riscv: Add Smrnmi cpu extension, Alistair Francis, 2025/01/17
- [PULL 25/50] target/riscv: Add Zicfilp support for Smrnmi, Alistair Francis, 2025/01/17
- [PULL 26/50] target/riscv: Have kvm_riscv_get_timebase_frequency() take RISCVCPU cpu, Alistair Francis, 2025/01/17
- [PULL 27/50] hw/riscv/virt: Remove unnecessary use of &first_cpu, Alistair Francis, 2025/01/17
- [PULL 28/50] target/riscv: Add properties for Indirect CSR Access extension, Alistair Francis, 2025/01/17