Skip to content

Commit

Permalink
target/riscv/cpu_helper.c: Fix mxr bit behavior
Browse files Browse the repository at this point in the history
According to RISCV Specification sect 9.5 on two stage translation when
V=1 the vsstatus(mstatus in QEMU's terms) field MXR, which makes
execute-only pages readable, only overrides VS-stage page protection.
Setting MXR at HS-level(mstatus_hs), however, overrides both VS-stage
and G-stage execute-only permissions.

The hypervisor extension changes the behavior of MXR\MPV\MPRV bits.
Due to RISCV Specification sect. 9.4.1 when MPRV=1, explicit memory
accesses are translated and protected, and endianness is applied, as
though the current virtualization mode were set to MPV and the current
nominal privilege mode were set to MPP. vsstatus.MXR makes readable
those pages marked executable at the VS translation stage.

Fixes: 36a1866 ("target/riscv: Implement second stage MMU")

Signed-off-by: Ivan Klokov <ivan.klokov@syntacore.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20231121071757.7178-3-ivan.klokov@syntacore.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 6bca4d7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
  • Loading branch information
Ivan Klokov authored and Michael Tokarev committed Nov 29, 2023
1 parent 87ff608 commit 6f51114
Showing 1 changed file with 20 additions and 4 deletions.
24 changes: 20 additions & 4 deletions target/riscv/cpu_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -989,13 +989,29 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
prot |= PAGE_WRITE;
}
if (pte & PTE_X) {
bool mxr;
bool mxr = false;

if (first_stage == true) {
/*
* Use mstatus for first stage or for the second stage without
* virt_enabled (MPRV+MPV)
*/
if (first_stage || !env->virt_enabled) {
mxr = get_field(env->mstatus, MSTATUS_MXR);
} else {
mxr = get_field(env->vsstatus, MSTATUS_MXR);
}

/* MPRV+MPV case, check VSSTATUS */
if (first_stage && two_stage && !env->virt_enabled) {
mxr |= get_field(env->vsstatus, MSTATUS_MXR);
}

/*
* Setting MXR at HS-level overrides both VS-stage and G-stage
* execute-only permissions
*/
if (env->virt_enabled) {
mxr |= get_field(env->mstatus_hs, MSTATUS_MXR);
}

if (mxr) {
prot |= PAGE_READ;
}
Expand Down

0 comments on commit 6f51114

Please sign in to comment.