From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44463) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCi3e-00019f-UQ for qemu-devel@nongnu.org; Tue, 14 Jun 2016 02:42:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bCi3X-0005gl-FX for qemu-devel@nongnu.org; Tue, 14 Jun 2016 02:42:41 -0400 Received: from 8.mo177.mail-out.ovh.net ([46.105.61.98]:59053) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCi3X-0005ga-5w for qemu-devel@nongnu.org; Tue, 14 Jun 2016 02:42:35 -0400 Received: from player746.ha.ovh.net (b7.ovh.net [213.186.33.57]) by mo177.mail-out.ovh.net (Postfix) with ESMTP id 2CFAAFF90CE for ; Tue, 14 Jun 2016 08:42:33 +0200 (CEST) References: <1465795496-15071-1-git-send-email-clg@kaod.org> <1465795496-15071-6-git-send-email-clg@kaod.org> <20160614063405.GQ4882@voom.fritz.box> From: =?UTF-8?Q?C=c3=a9dric_Le_Goater?= Message-ID: <575FA752.3070208@kaod.org> Date: Tue, 14 Jun 2016 08:42:26 +0200 MIME-Version: 1.0 In-Reply-To: <20160614063405.GQ4882@voom.fritz.box> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH 05/10] ppc: Fix generation if ISI/DSI vs. HV mode List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: David Gibson Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, Benjamin Herrenschmidt , Andrei Warkentin On 06/14/2016 08:34 AM, David Gibson wrote: > On Mon, Jun 13, 2016 at 07:24:51AM +0200, C=E9dric Le Goater wrote: >> 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 >> --- >> 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..072a952c8bd5 100644 >> --- a/target-ppc/mmu-hash64.c >> +++ b/target-ppc/mmu-hash64.c >> @@ -613,6 +613,47 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPC= CPU *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; >=20 > In the ISI case, you use HISI if !msr_hv.. >=20 >> + } 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; >=20 > ..but in the DSI case you use HDSI if msr_hv. Is that really right? No. I forgot to add this patch from Andrei : https://github.com/legoater/qemu/commit/e218fd3ba945bb0f483f5f12bedbb74d= 897cd5b9 I will send it as a fix. C. =20 >> + 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, v= addr 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,= vaddr 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, = vaddr 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, v= addr 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