{
static S390SKeysClass *skeyclass;
static S390SKeysState *ss;
- MachineState *ms = MACHINE(qdev_get_machine());
uint8_t key;
int rc;
- if (unlikely(addr >= ms->ram_size)) {
- return;
- }
-
+ /*
+ * We expect to be called with an absolute address that has already been
+ * validated, such that we can reliably use it to lookup the storage key.
+ */
if (unlikely(!ss)) {
ss = s390_get_skeys_device();
skeyclass = S390_SKEYS_GET_CLASS(ss);
/**
* Translate a virtual (logical) address into a physical (absolute) address.
* @param vaddr the virtual address
- * @param rw 0 = read, 1 = write, 2 = code fetch
+ * @param rw 0 = read, 1 = write, 2 = code fetch, < 0 = load real address
* @param asc address space control (one of the PSW_ASC_* modes)
* @param raddr the translated address is stored to this pointer
* @param flags the PAGE_READ/WRITE/EXEC flags are stored to this pointer
}
nodat:
- /* Convert real address -> absolute address */
- *raddr = mmu_real2abs(env, *raddr);
+ if (rw >= 0) {
+ /* Convert real address -> absolute address */
+ *raddr = mmu_real2abs(env, *raddr);
- mmu_handle_skey(*raddr, rw, flags);
+ if (!mmu_absolute_addr_valid(*raddr, rw == MMU_DATA_STORE)) {
+ *tec = 0; /* unused */
+ return PGM_ADDRESSING;
+ }
+
+ mmu_handle_skey(*raddr, rw, flags);
+ }
return 0;
}
if (ret) {
return ret;
}
- if (!address_space_access_valid(&address_space_memory, pages[i],
- TARGET_PAGE_SIZE, is_write,
- MEMTXATTRS_UNSPECIFIED)) {
- *tec = 0; /* unused */
- return PGM_ADDRESSING;
- }
addr += TARGET_PAGE_SIZE;
}
*addr = mmu_real2abs(env, raddr & TARGET_PAGE_MASK);
+ if (!mmu_absolute_addr_valid(*addr, rw == MMU_DATA_STORE)) {
+ /* unused */
+ *tec = 0;
+ return PGM_ADDRESSING;
+ }
+
mmu_handle_skey(*addr, rw, flags);
return 0;
}
/* mmu_helper.c */
bool mmu_absolute_addr_valid(target_ulong addr, bool is_write);
+/* Special access mode only valid for mmu_translate() */
+#define MMU_S390_LRA -1
int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
target_ulong *raddr, int *flags, uint64_t *tec);
int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
g_assert_not_reached();
}
- /* check out of RAM access */
- if (!excp &&
- !address_space_access_valid(&address_space_memory, raddr,
- TARGET_PAGE_SIZE, access_type,
- MEMTXATTRS_UNSPECIFIED)) {
- MachineState *ms = MACHINE(qdev_get_machine());
- qemu_log_mask(CPU_LOG_MMU,
- "%s: raddr %" PRIx64 " > ram_size %" PRIx64 "\n",
- __func__, (uint64_t)raddr, (uint64_t)ms->ram_size);
- excp = PGM_ADDRESSING;
- tec = 0; /* unused */
- }
-
env->tlb_fill_exc = excp;
env->tlb_fill_tec = tec;
tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, GETPC());
}
- exc = mmu_translate(env, addr, 0, asc, &ret, &flags, &tec);
+ exc = mmu_translate(env, addr, MMU_S390_LRA, asc, &ret, &flags, &tec);
if (exc) {
cc = 3;
ret = exc | 0x80000000;