s390x/mmu: Move DAT protection handling out of mmu_translate_asce()
We'll reuse the ilen and tec definitions in mmu_translate soon also for all other DAT exceptions we inject. Move it to the caller, where we can later pair it up with other protection checks, like IEP. Reviewed-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: David Hildenbrand <david@redhat.com>
This commit is contained in:
parent
a780d096e6
commit
124ada6810
@ -48,20 +48,6 @@ static void trigger_access_exception(CPUS390XState *env, uint32_t type,
|
||||
}
|
||||
}
|
||||
|
||||
static void trigger_prot_fault(CPUS390XState *env, target_ulong vaddr,
|
||||
uint64_t asc, int rw, bool exc)
|
||||
{
|
||||
uint64_t tec;
|
||||
|
||||
tec = vaddr | (rw == MMU_DATA_STORE ? FS_WRITE : FS_READ) | 4 | asc >> 46;
|
||||
|
||||
if (!exc) {
|
||||
return;
|
||||
}
|
||||
|
||||
trigger_access_exception(env, PGM_PROTECTION, ILEN_AUTO, tec);
|
||||
}
|
||||
|
||||
static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr,
|
||||
uint32_t type, uint64_t asc, int rw, bool exc)
|
||||
{
|
||||
@ -229,7 +215,6 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr,
|
||||
int *flags, int rw, bool exc)
|
||||
{
|
||||
int level;
|
||||
int r;
|
||||
|
||||
if (asce & ASCE_REAL_SPACE) {
|
||||
/* direct mapping */
|
||||
@ -277,14 +262,8 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr,
|
||||
break;
|
||||
}
|
||||
|
||||
r = mmu_translate_region(env, vaddr, asc, asce, level, raddr, flags, rw,
|
||||
exc);
|
||||
if (!r && rw == MMU_DATA_STORE && !(*flags & PAGE_WRITE)) {
|
||||
trigger_prot_fault(env, vaddr, asc, rw, exc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return r;
|
||||
return mmu_translate_region(env, vaddr, asc, asce, level, raddr, flags, rw,
|
||||
exc);
|
||||
}
|
||||
|
||||
static void mmu_handle_skey(target_ulong addr, int rw, int *flags)
|
||||
@ -369,6 +348,10 @@ static void mmu_handle_skey(target_ulong addr, int rw, int *flags)
|
||||
int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
|
||||
target_ulong *raddr, int *flags, bool exc)
|
||||
{
|
||||
/* Code accesses have an undefined ilc, let's use 2 bytes. */
|
||||
const int ilen = (rw == MMU_INST_FETCH) ? 2 : ILEN_AUTO;
|
||||
uint64_t tec = (vaddr & TARGET_PAGE_MASK) | (asc >> 46) |
|
||||
(rw == MMU_DATA_STORE ? FS_WRITE : FS_READ);
|
||||
uint64_t asce;
|
||||
int r;
|
||||
|
||||
@ -421,6 +404,16 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
|
||||
return r;
|
||||
}
|
||||
|
||||
/* check for DAT protection */
|
||||
if (unlikely(rw == MMU_DATA_STORE && !(*flags & PAGE_WRITE))) {
|
||||
if (exc) {
|
||||
/* DAT sets bit 61 only */
|
||||
tec |= 0x4;
|
||||
trigger_access_exception(env, PGM_PROTECTION, ilen, tec);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
nodat:
|
||||
/* Convert real address -> absolute address */
|
||||
*raddr = mmu_real2abs(env, *raddr);
|
||||
|
Loading…
Reference in New Issue
Block a user