@samitouri / QOSamiQemu / commits / 0f64c97d23

target/riscv: Fix pointer masking PMM field selection logic

mstatus.MPV only records the previous virtualization state, and does not affect pointer masking according to the Zjpm specification. This patch rewrites riscv_pm_get_pmm() to follow the architectural definition of Smmpm, Smnpm, and Ssnpm. The resulting PMM selection logic for each mode is summarized below: * mstatus.MXR = 1: pointer masking disabled * Smmpm + Smnpm + Ssnpm: M-mode: mseccfg.PMM S-mode: menvcfg.PMM U-mode: senvcfg.PMM VS-mode: henvcfg.PMM VU-mode: senvcfg.PMM * Smmpm + Smnpm (RVS implemented): M-mode: mseccfg.PMM S-mode: menvcfg.PMM U/VS/VU: disabled (Ssnpm not present) * Smmpm + Smnpm (RVS not implemented): M-mode: mseccfg.PMM U-mode: menvcfg.PMM S/VS/VU: disabled (no S-mode) * Smmpm only: M-mode: mseccfg.PMM Other existing modes: pointer masking disabled Signed-off-by: Frank Chang <frank.chang@sifive.com> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20260421093715.2995067-4-frank.chang@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Frank Chang committed Apr 21, 2026 at 17:37 UTC 0f64c97d23abfe77a70d94319020ca6789aee5a1
1 file changed +44 -7
target/riscv/cpu_helper.c
+44 -7
@@ -131,13 +131,47 @@ bool riscv_env_smode_dbltrp_enabled(CPURISCVState *env, bool virt)
131 #endif
132 }
133
134 +/*
135 + * Returns the effective PMM field.
136 + *
137 + * @env: CPURISCVState
138 + *
139 + * The PMM field selection logic for each effective privilege mode
140 + * is as follows:
141 + *
142 + * - mstatus.MXR = 1: disabled
143 + *
144 + * - Smmpm + Smnpm + Ssnpm:
145 + * M-mode: mseccfg.PMM
146 + * S-mode: menvcfg.PMM
147 + * U-mode: senvcfg.PMM
148 + * VS-mode: henvcfg.PMM
149 + * VU-mode: senvcfg.PMM
150 + *
151 + * - Smmpm + Smnpm (RVS implemented):
152 + * M-mode: mseccfg.PMM
153 + * S-mode: menvcfg.PMM
154 + * U/VS/VU: disabled (Ssnpm not present)
155 + *
156 + * - Smmpm + Smnpm (RVS not implemented):
157 + * M-mode: mseccfg.PMM
158 + * U-mode: menvcfg.PMM
159 + * S/VS/VU: disabled (no S-mode)
160 + *
161 + * - Smmpm only:
162 + * M-mode: mseccfg.PMM
163 + * Other existing modes: disabled
164 + */
165 RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env)
166 {
167 #ifndef CONFIG_USER_ONLY
137 - int priv_mode = cpu_address_mode(env);
168 + int priv_mode;
169 + bool virt;
170 +
171 + riscv_cpu_eff_priv(env, &priv_mode, &virt);
172
139 - if (get_field(env->mstatus, MSTATUS_MPRV) &&
140 - get_field(env->mstatus, MSTATUS_MXR)) {
173 + if ((priv_mode != PRV_M && get_field(env->mstatus, MSTATUS_MXR)) ||
174 + (virt && get_field(env->vsstatus, MSTATUS_MXR))) {
175 return PMM_FIELD_DISABLED;
176 }
177
@@ -149,12 +183,14 @@ RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env)
183 }
184 break;
185 case PRV_S:
152 - if (riscv_cpu_cfg(env)->ext_smnpm) {
153 - if (get_field(env->mstatus, MSTATUS_MPV)) {
154 - return get_field(env->henvcfg, HENVCFG_PMM);
155 - } else {
186 + if (!virt) {
187 + if (riscv_cpu_cfg(env)->ext_smnpm) {
188 return get_field(env->menvcfg, MENVCFG_PMM);
189 }
190 + } else {
191 + if (riscv_cpu_cfg(env)->ext_ssnpm) {
192 + return get_field(env->henvcfg, HENVCFG_PMM);
193 + }
194 }
195 break;
196 case PRV_U:
@@ -171,6 +207,7 @@ RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env)
207 default:
208 g_assert_not_reached();
209 }
210 +
211 return PMM_FIELD_DISABLED;
212 #else
213 return PMM_FIELD_DISABLED;