mirror of https://gitee.com/openkylin/qemu.git
PPC: booke206: Check for TLB overrun
Our internal helpers to fetch TLB entries were not able to tell us that an entry doesn't even exist. Pass an error out if we hit such a case to not accidently pass beyond the TLB array. Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
6d3db821c1
commit
3f162d119e
|
@ -2112,6 +2112,10 @@ static inline ppcmas_tlb_t *booke206_get_tlbm(CPUState *env, const int tlbn,
|
|||
ea &= (1 << (tlb_bits - ways_bits)) - 1;
|
||||
r = (ea << ways_bits) | way;
|
||||
|
||||
if (r >= booke206_tlb_size(env, tlbn)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* bump up to tlbn index */
|
||||
for (i = 0; i < tlbn; i++) {
|
||||
r += booke206_tlb_size(env, i);
|
||||
|
|
|
@ -1448,6 +1448,9 @@ static int mmubooke206_get_physical_address(CPUState *env, mmu_ctx_t *ctx,
|
|||
|
||||
for (j = 0; j < ways; j++) {
|
||||
tlb = booke206_get_tlbm(env, i, address, j);
|
||||
if (!tlb) {
|
||||
continue;
|
||||
}
|
||||
ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address,
|
||||
rw, access_type);
|
||||
if (ret != -1) {
|
||||
|
|
|
@ -4260,6 +4260,12 @@ void helper_booke206_tlbwe(void)
|
|||
|
||||
tlb = booke206_cur_tlb(env);
|
||||
|
||||
if (!tlb) {
|
||||
helper_raise_exception_err(POWERPC_EXCP_PROGRAM,
|
||||
POWERPC_EXCP_INVAL |
|
||||
POWERPC_EXCP_INVAL_INVAL);
|
||||
}
|
||||
|
||||
/* check that we support the targeted size */
|
||||
size_tlb = (env->spr[SPR_BOOKE_MAS1] & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
|
||||
size_ps = booke206_tlbnps(env, tlbn);
|
||||
|
@ -4311,7 +4317,11 @@ void helper_booke206_tlbre(void)
|
|||
ppcmas_tlb_t *tlb = NULL;
|
||||
|
||||
tlb = booke206_cur_tlb(env);
|
||||
booke206_tlb_to_mas(env, tlb);
|
||||
if (!tlb) {
|
||||
env->spr[SPR_BOOKE_MAS1] = 0;
|
||||
} else {
|
||||
booke206_tlb_to_mas(env, tlb);
|
||||
}
|
||||
}
|
||||
|
||||
void helper_booke206_tlbsx(target_ulong address)
|
||||
|
@ -4330,6 +4340,10 @@ void helper_booke206_tlbsx(target_ulong address)
|
|||
for (j = 0; j < ways; j++) {
|
||||
tlb = booke206_get_tlbm(env, i, address, j);
|
||||
|
||||
if (!tlb) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ppcmas_tlb_check(env, tlb, &raddr, address, spid)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -4373,6 +4387,9 @@ static inline void booke206_invalidate_ea_tlb(CPUState *env, int tlbn,
|
|||
|
||||
for (i = 0; i < ways; i++) {
|
||||
ppcmas_tlb_t *tlb = booke206_get_tlbm(env, tlbn, ea, i);
|
||||
if (!tlb) {
|
||||
continue;
|
||||
}
|
||||
mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
|
||||
if (((tlb->mas2 & MAS2_EPN_MASK) == (ea & mask)) &&
|
||||
!(tlb->mas1 & MAS1_IPROT)) {
|
||||
|
@ -4453,6 +4470,9 @@ void helper_booke206_tlbilx3(target_ulong address)
|
|||
|
||||
for (j = 0; j < ways; j++) {
|
||||
tlb = booke206_get_tlbm(env, i, address, j);
|
||||
if (!tlb) {
|
||||
continue;
|
||||
}
|
||||
if ((ppcmas_tlb_check(env, tlb, NULL, address, pid) != 0) ||
|
||||
(tlb->mas1 & MAS1_IPROT) ||
|
||||
((tlb->mas1 & MAS1_IND) != ind) ||
|
||||
|
|
|
@ -6088,6 +6088,7 @@ static void gen_tlbwe_booke206(DisasContext *ctx)
|
|||
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
||||
return;
|
||||
}
|
||||
gen_update_nip(ctx, ctx->nip - 4);
|
||||
gen_helper_booke206_tlbwe();
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue