From nobody Tue Oct 14 10:37:14 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1588828058; cv=none; d=zohomail.com; s=zohoarc; b=Z2VoJ1Nn4xpeBdpkbF7J0Y8y4vSgvoUJl2tOznwnpgYHe4sIDkcniCCgkGG3es8zn+CFjQMKMC2j2OYxksKfhFVnurd/j4R3fg8qqveksih3zkgn46ARUdYYGTlC5EvES0N16xsR+pzL6sNug4zaWYIv/a9chre778eyzh2pzqw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1588828058; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=SCNZvUSf+nOWwO7v+dONeXC1lUirSyogaNv6buyl+UM=; b=QgatbS4TZYZY7P7Al/wh7S1WGjSSWHW4if2hlqf5WZ7eDEB3daMNfuWAGpoqMoi302QziMjex4o1GwfutOsll70CDTG+UCljdbnYHjazpmpjSKwxouEh5yB6pAtVUDFQGYwL6DGIdA9F+KwH0ZfeAXNhmX5vaxBUAGnStAOYLwQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1588828058011560.0169357036847; Wed, 6 May 2020 22:07:38 -0700 (PDT) Received: from localhost ([::1]:51020 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jWYky-0005J1-LM for importer@patchew.org; Thu, 07 May 2020 01:07:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33584) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jWYhy-0007hO-Rr; Thu, 07 May 2020 01:04:30 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:41053) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jWYhw-0007gC-SQ; Thu, 07 May 2020 01:04:30 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 49HhFp4mghz9sTJ; Thu, 7 May 2020 15:04:14 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1588827854; bh=gvaiURSsSB2zDC9qKjqVsfG3wv1W9zvbaUwk6sqo0Pg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AHsZ0+EHmPVHgwlJCda+DVhk99zu/BmbtrjcruWE7uoM77MWtMtrPD7bm4nba5EYG ReMlEZPJCJWe1t1ZCrTFV1aUYmHmc2DyAgnNqXM4GTrgdx76rdO6l+DGCOdHbX5xSK tPQ98wNwjzYkYdlfpIDNM3tY10K/qoTE4FqtqfDY= From: David Gibson To: peter.maydell@linaro.org Subject: [PULL 12/18] target/ppc: Introduce ppc_radix64_xlate() for Radix tree translation Date: Thu, 7 May 2020 15:02:22 +1000 Message-Id: <20200507050228.802395-13-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200507050228.802395-1-david@gibson.dropbear.id.au> References: <20200507050228.802395-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: aik@ozlabs.ru, qemu-devel@nongnu.org, npiggin@gmail.com, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, Suraj Jitindar Singh , David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) From: C=C3=A9dric Le Goater This is moving code under a new ppc_radix64_xlate() routine shared by the MMU Radix page fault handler and the 'get_phys_page_debug' PPC callback. The difference being that 'get_phys_page_debug' does not generate exceptions. The specific part of process-scoped Radix translation is moved under ppc_radix64_process_scoped_xlate() in preparation of the future support for partition-scoped Radix translation. Routines raising the exceptions now take a 'cause_excp' bool to cover the 'get_phys_page_debug' case. It should be functionally equivalent. Signed-off-by: Suraj Jitindar Singh Signed-off-by: C=C3=A9dric Le Goater Message-Id: <20200403140056.59465-2-clg@kaod.org> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- target/ppc/mmu-radix64.c | 219 ++++++++++++++++++++++----------------- 1 file changed, 123 insertions(+), 96 deletions(-) diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c index d2422d1c54..4b0d0ff50a 100644 --- a/target/ppc/mmu-radix64.c +++ b/target/ppc/mmu-radix64.c @@ -219,17 +219,127 @@ static bool validate_pate(PowerPCCPU *cpu, uint64_t = lpid, ppc_v3_pate_t *pate) return true; } =20 +static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx, + vaddr eaddr, uint64_t pid, + ppc_v3_pate_t pate, hwaddr *g_= raddr, + int *g_prot, int *g_page_size, + bool cause_excp) +{ + CPUState *cs =3D CPU(cpu); + uint64_t offset, size, prtbe_addr, prtbe0, pte; + int fault_cause =3D 0; + hwaddr pte_addr; + + /* Index Process Table by PID to Find Corresponding Process Table Entr= y */ + offset =3D pid * sizeof(struct prtb_entry); + size =3D 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12); + if (offset >=3D size) { + /* offset exceeds size of the process table */ + if (cause_excp) { + ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_NOPTE); + } + return 1; + } + prtbe_addr =3D (pate.dw1 & PATE1_R_PRTB) + offset; + prtbe0 =3D ldq_phys(cs->as, prtbe_addr); + + /* Walk Radix Tree from Process Table Entry to Convert EA to RA */ + *g_page_size =3D PRTBE_R_GET_RTS(prtbe0); + pte =3D ppc_radix64_walk_tree(cpu, eaddr & R_EADDR_MASK, + prtbe0 & PRTBE_R_RPDB, prtbe0 & PRTBE_R_RP= DS, + g_raddr, g_page_size, &fault_cause, &pte_a= ddr); + + if (!(pte & R_PTE_VALID) || + ppc_radix64_check_prot(cpu, rwx, pte, &fault_cause, g_prot)) { + /* No valid pte or access denied due to protection */ + if (cause_excp) { + ppc_radix64_raise_si(cpu, rwx, eaddr, fault_cause); + } + return 1; + } + + ppc_radix64_set_rc(cpu, rwx, pte, pte_addr, g_prot); + + return 0; +} + +static int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx, + bool relocation, + hwaddr *raddr, int *psizep, int *protp, + bool cause_excp) +{ + uint64_t lpid =3D 0, pid =3D 0; + ppc_v3_pate_t pate; + int psize, prot; + hwaddr g_raddr; + + /* Virtual Mode Access - get the fully qualified address */ + if (!ppc_radix64_get_fully_qualified_addr(&cpu->env, eaddr, &lpid, &pi= d)) { + if (cause_excp) { + ppc_radix64_raise_segi(cpu, rwx, eaddr); + } + return 1; + } + + /* Get Process Table */ + if (cpu->vhyp) { + PPCVirtualHypervisorClass *vhc; + vhc =3D PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + vhc->get_pate(cpu->vhyp, &pate); + } else { + if (!ppc64_v3_get_pate(cpu, lpid, &pate)) { + if (cause_excp) { + ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_NOPTE); + } + return 1; + } + if (!validate_pate(cpu, lpid, &pate)) { + if (cause_excp) { + ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_R_BADCONFIG); + } + return 1; + } + /* We don't support guest mode yet */ + if (lpid !=3D 0) { + error_report("PowerNV guest support Unimplemented"); + exit(1); + } + } + + *psizep =3D INT_MAX; + *protp =3D PAGE_READ | PAGE_WRITE | PAGE_EXEC; + + /* + * Perform process-scoped translation if relocation enabled. + * + * - Translates an effective address to a host real address in + * quadrants 0 and 3 when HV=3D1. + */ + if (relocation) { + int ret =3D ppc_radix64_process_scoped_xlate(cpu, rwx, eaddr, pid, + pate, &g_raddr, &prot, + &psize, cause_excp); + if (ret) { + return ret; + } + *psizep =3D MIN(*psizep, psize); + *protp &=3D prot; + } else { + g_raddr =3D eaddr & R_EADDR_MASK; + } + + *raddr =3D g_raddr; + return 0; +} + int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx, int mmu_idx) { CPUState *cs =3D CPU(cpu); CPUPPCState *env =3D &cpu->env; - PPCVirtualHypervisorClass *vhc; - hwaddr raddr, pte_addr; - uint64_t lpid =3D 0, pid =3D 0, offset, size, prtbe0, pte; - int page_size, prot, fault_cause =3D 0; - ppc_v3_pate_t pate; + int page_size, prot; bool relocation; + hwaddr raddr; =20 assert(!(msr_hv && cpu->vhyp)); assert((rwx =3D=3D 0) || (rwx =3D=3D 1) || (rwx =3D=3D 2)); @@ -262,55 +372,12 @@ int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vad= dr eaddr, int rwx, TARGET_FMT_lx "\n", env->spr[SPR_LPCR]); } =20 - /* Virtual Mode Access - get the fully qualified address */ - if (!ppc_radix64_get_fully_qualified_addr(env, eaddr, &lpid, &pid)) { - ppc_radix64_raise_segi(cpu, rwx, eaddr); + /* Translate eaddr to raddr (where raddr is addr qemu needs for access= ) */ + if (ppc_radix64_xlate(cpu, eaddr, rwx, relocation, &raddr, + &page_size, &prot, true)) { return 1; } =20 - /* Get Process Table */ - if (cpu->vhyp) { - vhc =3D PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); - vhc->get_pate(cpu->vhyp, &pate); - } else { - if (!ppc64_v3_get_pate(cpu, lpid, &pate)) { - ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_NOPTE); - return 1; - } - if (!validate_pate(cpu, lpid, &pate)) { - ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_R_BADCONFIG); - } - /* We don't support guest mode yet */ - if (lpid !=3D 0) { - error_report("PowerNV guest support Unimplemented"); - exit(1); - } - } - - /* Index Process Table by PID to Find Corresponding Process Table Entr= y */ - offset =3D pid * sizeof(struct prtb_entry); - size =3D 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12); - if (offset >=3D size) { - /* offset exceeds size of the process table */ - ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_NOPTE); - return 1; - } - prtbe0 =3D ldq_phys(cs->as, (pate.dw1 & PATE1_R_PRTB) + offset); - - /* Walk Radix Tree from Process Table Entry to Convert EA to RA */ - page_size =3D PRTBE_R_GET_RTS(prtbe0); - pte =3D ppc_radix64_walk_tree(cpu, eaddr & R_EADDR_MASK, - prtbe0 & PRTBE_R_RPDB, prtbe0 & PRTBE_R_RP= DS, - &raddr, &page_size, &fault_cause, &pte_add= r); - if (!pte || ppc_radix64_check_prot(cpu, rwx, pte, &fault_cause, &prot)= ) { - /* Couldn't get pte or access denied due to protection */ - ppc_radix64_raise_si(cpu, rwx, eaddr, fault_cause); - return 1; - } - - /* Update Reference and Change Bits */ - ppc_radix64_set_rc(cpu, rwx, pte, pte_addr, &prot); - tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK, prot, mmu_idx, 1UL << page_size); return 0; @@ -318,58 +385,18 @@ int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vad= dr eaddr, int rwx, =20 hwaddr ppc_radix64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong eaddr) { - CPUState *cs =3D CPU(cpu); CPUPPCState *env =3D &cpu->env; - PPCVirtualHypervisorClass *vhc; - hwaddr raddr, pte_addr; - uint64_t lpid =3D 0, pid =3D 0, offset, size, prtbe0, pte; - int page_size, fault_cause =3D 0; - ppc_v3_pate_t pate; + int psize, prot; + hwaddr raddr; =20 /* Handle Real Mode */ - if (msr_dr =3D=3D 0) { + if ((msr_dr =3D=3D 0) && (msr_hv || cpu->vhyp)) { /* In real mode top 4 effective addr bits (mostly) ignored */ return eaddr & 0x0FFFFFFFFFFFFFFFULL; } =20 - /* Virtual Mode Access - get the fully qualified address */ - if (!ppc_radix64_get_fully_qualified_addr(env, eaddr, &lpid, &pid)) { - return -1; - } - - /* Get Process Table */ - if (cpu->vhyp) { - vhc =3D PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); - vhc->get_pate(cpu->vhyp, &pate); - } else { - if (!ppc64_v3_get_pate(cpu, lpid, &pate)) { - return -1; - } - if (!validate_pate(cpu, lpid, &pate)) { - return -1; - } - /* We don't support guest mode yet */ - if (lpid !=3D 0) { - error_report("PowerNV guest support Unimplemented"); - exit(1); - } - } - - /* Index Process Table by PID to Find Corresponding Process Table Entr= y */ - offset =3D pid * sizeof(struct prtb_entry); - size =3D 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12); - if (offset >=3D size) { - /* offset exceeds size of the process table */ - return -1; - } - prtbe0 =3D ldq_phys(cs->as, (pate.dw1 & PATE1_R_PRTB) + offset); - - /* Walk Radix Tree from Process Table Entry to Convert EA to RA */ - page_size =3D PRTBE_R_GET_RTS(prtbe0); - pte =3D ppc_radix64_walk_tree(cpu, eaddr & R_EADDR_MASK, - prtbe0 & PRTBE_R_RPDB, prtbe0 & PRTBE_R_RP= DS, - &raddr, &page_size, &fault_cause, &pte_add= r); - if (!pte) { + if (ppc_radix64_xlate(cpu, eaddr, 0, msr_dr, &raddr, &psize, + &prot, false)) { return -1; } =20 --=20 2.26.2