---
target/ppc/mmu-hash64.c | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index 900f906990..a0c90df3ce 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -770,7 +770,8 @@ static bool ppc_hash64_use_vrma(CPUPPCState *env)
}
}
-static void ppc_hash64_set_isi(CPUState *cs, int mmu_idx, uint64_t error_code)
+static void ppc_hash64_set_isi(CPUState *cs, int mmu_idx, uint64_t slb_vsid,
+ uint64_t error_code)
{
CPUPPCState *env = &POWERPC_CPU(cs)->env;
bool vpm;
@@ -782,13 +783,15 @@ static void ppc_hash64_set_isi(CPUState *cs, int mmu_idx,
uint64_t error_code)
}
if (vpm && !mmuidx_hv(mmu_idx)) {
cs->exception_index = POWERPC_EXCP_HISI;
+ env->spr[SPR_ASDR] = slb_vsid;
} else {
cs->exception_index = POWERPC_EXCP_ISI;
}
env->error_code = error_code;
}
-static void ppc_hash64_set_dsi(CPUState *cs, int mmu_idx, uint64_t dar, uint64_t dsisr)
+static void ppc_hash64_set_dsi(CPUState *cs, int mmu_idx, uint64_t slb_vsid,
+ uint64_t dar, uint64_t dsisr)
{
CPUPPCState *env = &POWERPC_CPU(cs)->env;
bool vpm;
@@ -802,6 +805,7 @@ static void ppc_hash64_set_dsi(CPUState *cs, int mmu_idx,
uint64_t dar, uint64_t
cs->exception_index = POWERPC_EXCP_HDSI;
env->spr[SPR_HDAR] = dar;
env->spr[SPR_HDSISR] = dsisr;
+ env->spr[SPR_ASDR] = slb_vsid;
} else {
cs->exception_index = POWERPC_EXCP_DSI;
env->spr[SPR_DAR] = dar;
@@ -963,13 +967,13 @@ bool ppc_hash64_xlate(PowerPCCPU *cpu, vaddr eaddr,
MMUAccessType access_type,
}
switch (access_type) {
case MMU_INST_FETCH:
- ppc_hash64_set_isi(cs, mmu_idx, SRR1_PROTFAULT);
+ ppc_hash64_set_isi(cs, mmu_idx, 0, SRR1_PROTFAULT);
break;
case MMU_DATA_LOAD:
- ppc_hash64_set_dsi(cs, mmu_idx, eaddr, DSISR_PROTFAULT);
+ ppc_hash64_set_dsi(cs, mmu_idx, 0, eaddr, DSISR_PROTFAULT);
break;
case MMU_DATA_STORE:
- ppc_hash64_set_dsi(cs, mmu_idx, eaddr,
+ ppc_hash64_set_dsi(cs, mmu_idx, 0, eaddr,
DSISR_PROTFAULT | DSISR_ISSTORE);
break;
default:
@@ -1022,7 +1026,7 @@ bool ppc_hash64_xlate(PowerPCCPU *cpu, vaddr eaddr,
MMUAccessType access_type,
/* 3. Check for segment level no-execute violation */
if (access_type == MMU_INST_FETCH && (slb->vsid & SLB_VSID_N)) {
if (guest_visible) {
- ppc_hash64_set_isi(cs, mmu_idx, SRR1_NOEXEC_GUARD);
+ ppc_hash64_set_isi(cs, mmu_idx, slb->vsid, SRR1_NOEXEC_GUARD);
}
return false;
}
@@ -1035,13 +1039,14 @@ bool ppc_hash64_xlate(PowerPCCPU *cpu, vaddr eaddr,
MMUAccessType access_type,
}
switch (access_type) {
case MMU_INST_FETCH:
- ppc_hash64_set_isi(cs, mmu_idx, SRR1_NOPTE);
+ ppc_hash64_set_isi(cs, mmu_idx, slb->vsid, SRR1_NOPTE);
break;
case MMU_DATA_LOAD:
- ppc_hash64_set_dsi(cs, mmu_idx, eaddr, DSISR_NOPTE);
+ ppc_hash64_set_dsi(cs, mmu_idx, slb->vsid, eaddr, DSISR_NOPTE);
break;
case MMU_DATA_STORE:
- ppc_hash64_set_dsi(cs, mmu_idx, eaddr, DSISR_NOPTE |
DSISR_ISSTORE);
+ ppc_hash64_set_dsi(cs, mmu_idx, slb->vsid, eaddr,
+ DSISR_NOPTE | DSISR_ISSTORE);
break;
default:
g_assert_not_reached();
@@ -1075,7 +1080,7 @@ bool ppc_hash64_xlate(PowerPCCPU *cpu, vaddr eaddr,
MMUAccessType access_type,
if (PAGE_EXEC & ~amr_prot) {
srr1 |= SRR1_IAMR; /* Access violates virt pg class key prot
*/
}
- ppc_hash64_set_isi(cs, mmu_idx, srr1);
+ ppc_hash64_set_isi(cs, mmu_idx, slb->vsid, srr1);
} else {
int dsisr = 0;
if (need_prot & ~pp_prot) {
@@ -1087,7 +1092,7 @@ bool ppc_hash64_xlate(PowerPCCPU *cpu, vaddr eaddr,
MMUAccessType access_type,
if (need_prot & ~amr_prot) {
dsisr |= DSISR_AMR;
}
- ppc_hash64_set_dsi(cs, mmu_idx, eaddr, dsisr);
+ ppc_hash64_set_dsi(cs, mmu_idx, slb->vsid, eaddr, dsisr);
}
return false;
}