int prot_need, int mmu_idx,
target_ulong *pphys, int *pprot)
{
+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
CPUState *cs = env_cpu(env);
target_long saddr = addr;
target_ulong phys = 0;
target_ulong pt, index;
int prot = 0;
int ret = MM_K_ACV;
+ MemTxResult txres;
/* Handle physical accesses. */
if (mmu_idx == MMU_PHYS_IDX) {
pt = env->ptbr;
- /*
- * TODO: rather than using ldq_phys_le() to read the page table we should
- * use address_space_ldq() so that we can handle the case when
- * the page table read gives a bus fault, rather than ignoring it.
- * For the existing code the zero data that ldq_phys_le will return for
- * an access to invalid memory will result in our treating the page
- * table as invalid, which may even be the right behaviour.
- */
-
/* L1 page table read. */
index = (addr >> (TARGET_PAGE_BITS + 20)) & 0x3ff;
- L1pte = ldq_phys_le(cs->as, pt + index * 8);
+ L1pte = address_space_ldq_le(cs->as, pt + index * 8, attrs, &txres);
+ if (txres != MEMTX_OK) {
+ /* bus fault */
+ goto exit;
+ }
if (unlikely((L1pte & PTE_VALID) == 0)) {
ret = MM_K_TNV;
/* L2 page table read. */
index = (addr >> (TARGET_PAGE_BITS + 10)) & 0x3ff;
- L2pte = ldq_phys_le(cs->as, pt + index * 8);
+ L2pte = address_space_ldq_le(cs->as, pt + index * 8, attrs, &txres);
+ if (txres != MEMTX_OK) {
+ /* bus fault */
+ goto exit;
+ }
if (unlikely((L2pte & PTE_VALID) == 0)) {
ret = MM_K_TNV;
/* L3 page table read. */
index = (addr >> TARGET_PAGE_BITS) & 0x3ff;
- L3pte = ldq_phys_le(cs->as, pt + index * 8);
+ L3pte = address_space_ldq_le(cs->as, pt + index * 8, attrs, &txres);
+ if (txres != MEMTX_OK) {
+ /* bus fault */
+ goto exit;
+ }
phys = L3pte >> 32 << TARGET_PAGE_BITS;
if (unlikely((L3pte & PTE_VALID) == 0)) {