From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59404) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bFTYo-00029M-QU for qemu-devel@nongnu.org; Tue, 21 Jun 2016 17:50:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bFTYk-0001Aj-UD for qemu-devel@nongnu.org; Tue, 21 Jun 2016 17:50:18 -0400 Received: from 12.mo1.mail-out.ovh.net ([87.98.162.229]:43027) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bFTYk-0001AN-Ia for qemu-devel@nongnu.org; Tue, 21 Jun 2016 17:50:14 -0400 Received: from player770.ha.ovh.net (b7.ovh.net [213.186.33.57]) by mo1.mail-out.ovh.net (Postfix) with ESMTP id 83723FF9BDD for ; Tue, 21 Jun 2016 23:50:13 +0200 (CEST) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 21 Jun 2016 23:48:50 +0200 Message-Id: <1466545735-2555-6-git-send-email-clg@kaod.org> In-Reply-To: <1466545735-2555-1-git-send-email-clg@kaod.org> References: <1466545735-2555-1-git-send-email-clg@kaod.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH v2 05/10] ppc: Fix generation if ISI/DSI vs. HV mode List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-ppc@nongnu.org Cc: David Gibson , Alexander Graf , qemu-devel@nongnu.org, Benjamin Herrenschmidt , Cedric Le Goater From: Benjamin Herrenschmidt Under some circumstances, we need to direct ISI and DSI interrupts at the hypervisor, turning them into HISI/HDSI, and using different SPRs (HDSISR and HDAR) depending on the combination of MSR_DR and the corresponding VPM bits in LPCR. This moves part of the code into helpers that are fixed to select the right exception type and registers. On pre-P7 processors, LPCR is 0 which provides the old behaviour of directing the interrupts at the supervisor. Thanks to Andrei Warkentin for finding a bug when HV=3D1 Signed-off-by: Benjamin Herrenschmidt Reviewed-by: David Gibson [clg: Merged a fix on POWERPC_EXCP_HDSI fixing the condition on msr_hv, from Andrei Warkentin ] Signed-off-by: C=C3=A9dric Le Goater --- target-ppc/mmu-hash64.c | 69 +++++++++++++++++++++++++++++++++++--------= ------ 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c index 668da5e22653..5b7b5e9eb10c 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -613,6 +613,47 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU= *cpu, return 0; } =20 +static void ppc_hash64_set_isi(CPUState *cs, CPUPPCState *env, + uint64_t error_code) +{ + bool vpm; + + if (msr_ir) { + vpm =3D !!(env->spr[SPR_LPCR] & LPCR_VPM1); + } else { + vpm =3D !!(env->spr[SPR_LPCR] & LPCR_VPM0); + } + if (vpm && !msr_hv) { + cs->exception_index =3D POWERPC_EXCP_HISI; + } else { + cs->exception_index =3D POWERPC_EXCP_ISI; + } + env->error_code =3D error_code; +} + +static void ppc_hash64_set_dsi(CPUState *cs, CPUPPCState *env, uint64_t = dar, + uint64_t dsisr) +{ + bool vpm; + + if (msr_dr) { + vpm =3D !!(env->spr[SPR_LPCR] & LPCR_VPM1); + } else { + vpm =3D !!(env->spr[SPR_LPCR] & LPCR_VPM0); + } + if (vpm && !msr_hv) { + cs->exception_index =3D POWERPC_EXCP_HDSI; + env->spr[SPR_HDAR] =3D dar; + env->spr[SPR_HDSISR] =3D dsisr; + } else { + cs->exception_index =3D POWERPC_EXCP_DSI; + env->spr[SPR_DAR] =3D dar; + env->spr[SPR_DSISR] =3D dsisr; + } + env->error_code =3D 0; +} + + int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx, int mmu_idx) { @@ -623,7 +664,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vadd= r eaddr, hwaddr pte_offset; ppc_hash_pte64_t pte; int pp_prot, amr_prot, prot; - uint64_t new_pte1; + uint64_t new_pte1, dsisr; const int need_prot[] =3D {PAGE_READ, PAGE_WRITE, PAGE_EXEC}; hwaddr raddr; =20 @@ -657,26 +698,21 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, va= ddr eaddr, =20 /* 3. Check for segment level no-execute violation */ if ((rwx =3D=3D 2) && (slb->vsid & SLB_VSID_N)) { - cs->exception_index =3D POWERPC_EXCP_ISI; - env->error_code =3D 0x10000000; + ppc_hash64_set_isi(cs, env, 0x10000000); return 1; } =20 /* 4. Locate the PTE in the hash table */ pte_offset =3D ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte); if (pte_offset =3D=3D -1) { + dsisr =3D 0x40000000; if (rwx =3D=3D 2) { - cs->exception_index =3D POWERPC_EXCP_ISI; - env->error_code =3D 0x40000000; + ppc_hash64_set_isi(cs, env, dsisr); } else { - cs->exception_index =3D POWERPC_EXCP_DSI; - env->error_code =3D 0; - env->spr[SPR_DAR] =3D eaddr; if (rwx =3D=3D 1) { - env->spr[SPR_DSISR] =3D 0x42000000; - } else { - env->spr[SPR_DSISR] =3D 0x40000000; + dsisr |=3D 0x02000000; } + ppc_hash64_set_dsi(cs, env, eaddr, dsisr); } return 1; } @@ -705,14 +741,9 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vad= dr eaddr, /* Access right violation */ qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n"); if (rwx =3D=3D 2) { - cs->exception_index =3D POWERPC_EXCP_ISI; - env->error_code =3D 0x08000000; + ppc_hash64_set_isi(cs, env, 0x08000000); } else { - target_ulong dsisr =3D 0; - - cs->exception_index =3D POWERPC_EXCP_DSI; - env->error_code =3D 0; - env->spr[SPR_DAR] =3D eaddr; + dsisr =3D 0; if (need_prot[rwx] & ~pp_prot) { dsisr |=3D 0x08000000; } @@ -722,7 +753,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vadd= r eaddr, if (need_prot[rwx] & ~amr_prot) { dsisr |=3D 0x00200000; } - env->spr[SPR_DSISR] =3D dsisr; + ppc_hash64_set_dsi(cs, env, eaddr, dsisr); } return 1; } --=20 2.1.4