diff options
author | Yongbok Kim <yongbok.kim@imgtec.com> | 2015-06-01 12:13:23 +0100 |
---|---|---|
committer | Leon Alrae <leon.alrae@imgtec.com> | 2015-06-11 10:13:28 +0100 |
commit | 3b4afc9e75ab1a95f33e41f462921093f8a109c4 (patch) | |
tree | d2f9bcad2f99fc11209b1d59993abf96700611ad | |
parent | be3a8c53b4f18bcc51a462d977cc61a0f46ebb1c (diff) |
softmmu: Add probe_write()
Probe for whether the specified guest write access is permitted.
If it is not permitted then an exception will be taken in the same
way as if this were a real write access (and we will not return).
Otherwise the function will return, and there will be a valid
entry in the TLB for this access.
Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
-rw-r--r-- | include/exec/exec-all.h | 2 | ||||
-rw-r--r-- | softmmu_template.h | 22 |
2 files changed, 24 insertions, 0 deletions
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 2f7a4f1700..2573e8c36e 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -105,6 +105,8 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr, hwaddr paddr, MemTxAttrs attrs, int prot, int mmu_idx, target_ulong size); void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr); +void probe_write(CPUArchState *env, target_ulong addr, int mmu_idx, + uintptr_t retaddr); #else static inline void tlb_flush_page(CPUState *cpu, target_ulong addr) { diff --git a/softmmu_template.h b/softmmu_template.h index 39f571b0ca..d42d89d541 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -548,6 +548,28 @@ glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, helper_te_st_name(env, addr, val, oi, GETRA()); } +#if DATA_SIZE == 1 +/* Probe for whether the specified guest write access is permitted. + * If it is not permitted then an exception will be taken in the same + * way as if this were a real write access (and we will not return). + * Otherwise the function will return, and there will be a valid + * entry in the TLB for this access. + */ +void probe_write(CPUArchState *env, target_ulong addr, int mmu_idx, + uintptr_t retaddr) +{ + int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write; + + if ((addr & TARGET_PAGE_MASK) + != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { + /* TLB entry is for a different page */ + if (!VICTIM_TLB_HIT(addr_write)) { + tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr); + } + } +} +#endif #endif /* !defined(SOFTMMU_CODE_ACCESS) */ #undef READ_ACCESS_TYPE |