Skip to content

Commit 390191c

Browse files
davidhildenbrandhuth
authored andcommitted
s390x/mmu_helper: move address validation into mmu_translate*()
Let's move address validation into mmu_translate() and mmu_translate_real(). This allows for checking whether an absolute address is valid before looking up the storage key. We can now get rid of the ram_size check. Interestingly, we're already handling LOAD REAL ADDRESS wrong, because a) We're not supposed to touch storage keys b) We're not supposed to convert to an absolute address Let's use a fake, negative MMUAccessType to teach mmu_translate() to fix that handling and to not perform address validation. Signed-off-by: David Hildenbrand <[email protected]> Reviewed-by: Thomas Huth <[email protected]> Message-Id: <[email protected]> Signed-off-by: Thomas Huth <[email protected]>
1 parent e0b11f2 commit 390191c

File tree

4 files changed

+24
-29
lines changed

4 files changed

+24
-29
lines changed

target/s390x/mmu_helper.c

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -301,14 +301,13 @@ static void mmu_handle_skey(target_ulong addr, int rw, int *flags)
301301
{
302302
static S390SKeysClass *skeyclass;
303303
static S390SKeysState *ss;
304-
MachineState *ms = MACHINE(qdev_get_machine());
305304
uint8_t key;
306305
int rc;
307306

308-
if (unlikely(addr >= ms->ram_size)) {
309-
return;
310-
}
311-
307+
/*
308+
* We expect to be called with an absolute address that has already been
309+
* validated, such that we can reliably use it to lookup the storage key.
310+
*/
312311
if (unlikely(!ss)) {
313312
ss = s390_get_skeys_device();
314313
skeyclass = S390_SKEYS_GET_CLASS(ss);
@@ -370,7 +369,7 @@ static void mmu_handle_skey(target_ulong addr, int rw, int *flags)
370369
/**
371370
* Translate a virtual (logical) address into a physical (absolute) address.
372371
* @param vaddr the virtual address
373-
* @param rw 0 = read, 1 = write, 2 = code fetch
372+
* @param rw 0 = read, 1 = write, 2 = code fetch, < 0 = load real address
374373
* @param asc address space control (one of the PSW_ASC_* modes)
375374
* @param raddr the translated address is stored to this pointer
376375
* @param flags the PAGE_READ/WRITE/EXEC flags are stored to this pointer
@@ -449,10 +448,17 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
449448
}
450449

451450
nodat:
452-
/* Convert real address -> absolute address */
453-
*raddr = mmu_real2abs(env, *raddr);
451+
if (rw >= 0) {
452+
/* Convert real address -> absolute address */
453+
*raddr = mmu_real2abs(env, *raddr);
454454

455-
mmu_handle_skey(*raddr, rw, flags);
455+
if (!mmu_absolute_addr_valid(*raddr, rw == MMU_DATA_STORE)) {
456+
*tec = 0; /* unused */
457+
return PGM_ADDRESSING;
458+
}
459+
460+
mmu_handle_skey(*raddr, rw, flags);
461+
}
456462
return 0;
457463
}
458464

@@ -473,12 +479,6 @@ static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
473479
if (ret) {
474480
return ret;
475481
}
476-
if (!address_space_access_valid(&address_space_memory, pages[i],
477-
TARGET_PAGE_SIZE, is_write,
478-
MEMTXATTRS_UNSPECIFIED)) {
479-
*tec = 0; /* unused */
480-
return PGM_ADDRESSING;
481-
}
482482
addr += TARGET_PAGE_SIZE;
483483
}
484484

@@ -588,6 +588,12 @@ int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
588588

589589
*addr = mmu_real2abs(env, raddr & TARGET_PAGE_MASK);
590590

591+
if (!mmu_absolute_addr_valid(*addr, rw == MMU_DATA_STORE)) {
592+
/* unused */
593+
*tec = 0;
594+
return PGM_ADDRESSING;
595+
}
596+
591597
mmu_handle_skey(*addr, rw, flags);
592598
return 0;
593599
}

target/s390x/s390x-internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,8 @@ void probe_write_access(CPUS390XState *env, uint64_t addr, uint64_t len,
374374

375375
/* mmu_helper.c */
376376
bool mmu_absolute_addr_valid(target_ulong addr, bool is_write);
377+
/* Special access mode only valid for mmu_translate() */
378+
#define MMU_S390_LRA -1
377379
int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
378380
target_ulong *raddr, int *flags, uint64_t *tec);
379381
int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,

target/s390x/tcg/excp_helper.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -150,19 +150,6 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
150150
g_assert_not_reached();
151151
}
152152

153-
/* check out of RAM access */
154-
if (!excp &&
155-
!address_space_access_valid(&address_space_memory, raddr,
156-
TARGET_PAGE_SIZE, access_type,
157-
MEMTXATTRS_UNSPECIFIED)) {
158-
MachineState *ms = MACHINE(qdev_get_machine());
159-
qemu_log_mask(CPU_LOG_MMU,
160-
"%s: raddr %" PRIx64 " > ram_size %" PRIx64 "\n",
161-
__func__, (uint64_t)raddr, (uint64_t)ms->ram_size);
162-
excp = PGM_ADDRESSING;
163-
tec = 0; /* unused */
164-
}
165-
166153
env->tlb_fill_exc = excp;
167154
env->tlb_fill_tec = tec;
168155

target/s390x/tcg/mem_helper.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2455,7 +2455,7 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
24552455
tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, GETPC());
24562456
}
24572457

2458-
exc = mmu_translate(env, addr, 0, asc, &ret, &flags, &tec);
2458+
exc = mmu_translate(env, addr, MMU_S390_LRA, asc, &ret, &flags, &tec);
24592459
if (exc) {
24602460
cc = 3;
24612461
ret = exc | 0x80000000;

0 commit comments

Comments
 (0)