Skip to content

Commit

Permalink
riscv: don't look at SUM when accessing memory from a debugger context
Browse files Browse the repository at this point in the history
Previously the qemu monitor and gdbstub looked at SUM and refused to
perform accesses to user memory if it is off, which was an impediment to
debugging.

Signed-off-by: Jade Fink <qemu@jade.fyi>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20210406113109.1031033-1-qemu@jade.fyi
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
  • Loading branch information
Jade Fink authored and alistair23 committed May 11, 2021
1 parent 1742054 commit 11c27c6
Showing 1 changed file with 12 additions and 8 deletions.
20 changes: 12 additions & 8 deletions target/riscv/cpu_helper.c
Expand Up @@ -342,12 +342,14 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
* @first_stage: Are we in first stage translation?
* Second stage is used for hypervisor guest translation
* @two_stage: Are we going to perform two stage translation
* @is_debug: Is this access from a debugger or the monitor?
*/
static int get_physical_address(CPURISCVState *env, hwaddr *physical,
int *prot, target_ulong addr,
target_ulong *fault_pte_addr,
int access_type, int mmu_idx,
bool first_stage, bool two_stage)
bool first_stage, bool two_stage,
bool is_debug)
{
/* NOTE: the env->pc value visible here will not be
* correct, but the value visible to the exception handler
Expand Down Expand Up @@ -416,7 +418,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
widened = 2;
}
/* status.SUM will be ignored if execute on background */
sum = get_field(env->mstatus, MSTATUS_SUM) || use_background;
sum = get_field(env->mstatus, MSTATUS_SUM) || use_background || is_debug;
switch (vm) {
case VM_1_10_SV32:
levels = 2; ptidxbits = 10; ptesize = 4; break;
Expand Down Expand Up @@ -475,7 +477,8 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
/* Do the second stage translation on the base PTE address. */
int vbase_ret = get_physical_address(env, &vbase, &vbase_prot,
base, NULL, MMU_DATA_LOAD,
mmu_idx, false, true);
mmu_idx, false, true,
is_debug);

if (vbase_ret != TRANSLATE_SUCCESS) {
if (fault_pte_addr) {
Expand Down Expand Up @@ -666,13 +669,13 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
int mmu_idx = cpu_mmu_index(&cpu->env, false);

if (get_physical_address(env, &phys_addr, &prot, addr, NULL, 0, mmu_idx,
true, riscv_cpu_virt_enabled(env))) {
true, riscv_cpu_virt_enabled(env), true)) {
return -1;
}

if (riscv_cpu_virt_enabled(env)) {
if (get_physical_address(env, &phys_addr, &prot, phys_addr, NULL,
0, mmu_idx, false, true)) {
0, mmu_idx, false, true, true)) {
return -1;
}
}
Expand Down Expand Up @@ -768,7 +771,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
/* Two stage lookup */
ret = get_physical_address(env, &pa, &prot, address,
&env->guest_phys_fault_addr, access_type,
mmu_idx, true, true);
mmu_idx, true, true, false);

/*
* A G-stage exception may be triggered during two state lookup.
Expand All @@ -790,7 +793,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
im_address = pa;

ret = get_physical_address(env, &pa, &prot2, im_address, NULL,
access_type, mmu_idx, false, true);
access_type, mmu_idx, false, true,
false);

qemu_log_mask(CPU_LOG_MMU,
"%s 2nd-stage address=%" VADDR_PRIx " ret %d physical "
Expand Down Expand Up @@ -825,7 +829,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
} else {
/* Single stage lookup */
ret = get_physical_address(env, &pa, &prot, address, NULL,
access_type, mmu_idx, true, false);
access_type, mmu_idx, true, false, false);

qemu_log_mask(CPU_LOG_MMU,
"%s address=%" VADDR_PRIx " ret %d physical "
Expand Down

0 comments on commit 11c27c6

Please sign in to comment.