diff options
author | David Hildenbrand <david@redhat.com> | 2017-09-26 20:33:14 +0200 |
---|---|---|
committer | Cornelia Huck <cohuck@redhat.com> | 2017-10-06 10:53:02 +0200 |
commit | fb66944df92f4cf28b6f66232f82b9dd46ddcdb2 (patch) | |
tree | 3fe9b7de69a395e979920daa85742a28c50e5ca8 /target/s390x/excp_helper.c | |
parent | 0bd695a960bf05f27ad6d710d2b64059037574ce (diff) |
s390x/tcg: add MMU for real addresses
This makes it easy to access real addresses (prefix) and in addition
checks for valid memory addresses, which is missing when using e.g.
stl_phys().
We can later reuse it to implement low address protection checks (then
we might even decide to introduce yet another MMU for absolute
addresses, just for handling storage keys and low address protection).
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20170926183318.12995-3-david@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'target/s390x/excp_helper.c')
-rw-r--r-- | target/s390x/excp_helper.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c index 308605d9ed..3e4349d00b 100644 --- a/target/s390x/excp_helper.c +++ b/target/s390x/excp_helper.c @@ -88,8 +88,8 @@ int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr orig_vaddr, { S390CPU *cpu = S390_CPU(cs); CPUS390XState *env = &cpu->env; - uint64_t asc = cpu_mmu_idx_to_asc(mmu_idx); target_ulong vaddr, raddr; + uint64_t asc; int prot; DPRINTF("%s: address 0x%" VADDR_PRIx " rw %d mmu_idx %d\n", @@ -98,14 +98,21 @@ int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr orig_vaddr, orig_vaddr &= TARGET_PAGE_MASK; vaddr = orig_vaddr; - /* 31-Bit mode */ - if (!(env->psw.mask & PSW_MASK_64)) { - vaddr &= 0x7fffffff; - } - - if (mmu_translate(env, vaddr, rw, asc, &raddr, &prot, true)) { - /* Translation ended in exception */ - return 1; + if (mmu_idx < MMU_REAL_IDX) { + asc = cpu_mmu_idx_to_asc(mmu_idx); + /* 31-Bit mode */ + if (!(env->psw.mask & PSW_MASK_64)) { + vaddr &= 0x7fffffff; + } + if (mmu_translate(env, vaddr, rw, asc, &raddr, &prot, true)) { + return 1; + } + } else if (mmu_idx == MMU_REAL_IDX) { + if (mmu_translate_real(env, vaddr, rw, &raddr, &prot)) { + return 1; + } + } else { + abort(); } /* check out of RAM access */ |