From nobody Fri May 3 03:20:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487816120880485.29388348943303; Wed, 22 Feb 2017 18:15:20 -0800 (PST) Received: from localhost ([::1]:56011 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cgiwB-0001Fc-GJ for importer@patchew.org; Wed, 22 Feb 2017 21:15:19 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57513) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cgiqo-0004Pe-EF for qemu-devel@nongnu.org; Wed, 22 Feb 2017 21:09:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cgiql-0007ZV-8D for qemu-devel@nongnu.org; Wed, 22 Feb 2017 21:09:46 -0500 Received: from ozlabs.org ([103.22.144.67]:57995) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cgiqk-0007YZ-Sj; Wed, 22 Feb 2017 21:09:43 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vTHjv5vdBz9s7c; Thu, 23 Feb 2017 13:09:39 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1487815779; bh=0hil4157l07wdvvjSuprcoqHYVYjgMnvMRvG43KM+j4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UzLyBuKe+miJXVmWXJPvxA0jvMr5skUn+rG+lDt79t3kClTw7VY46cSyG7gC4u0T5 6ZO3i5OwWRF3wy2wqZwQFPNFL5E82RZ2a7ZUFpAUdCKBG4ex9URhW++hgm+v2OkyeH PzoYmLh/T5D6iPHMbRp+HTyA2WhUs4l+/2IiEyd4= From: David Gibson To: qemu-ppc@nongnu.org, aik@ozlabs.ru, sjitindarsingh@gmail.com Date: Thu, 23 Feb 2017 13:09:31 +1100 Message-Id: <20170223020936.29220-2-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170223020936.29220-1-david@gibson.dropbear.id.au> References: <20170223020936.29220-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 103.22.144.67 Subject: [Qemu-devel] [PATCH 1/6] pseries: Minor cleanups to HPT management hypercalls X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, agraf@suse.de, thuth@redhat.com, mdroth@linux.vnet.ibm.com, qemu-devel@nongnu.org, paulus@samba.org, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" * Standardize on 'ptex' instead of 'pte_index' for HPTE index variables for consistency and brevity * Avoid variables named 'index'; shadowing index(3) from libc can lead to surprising bugs if the variable is removed, because compiler errors might not appear for remaining references * Clarify index calculations in h_enter() - we have two cases, H_EXACT where the exact HPTE slot is given, and !H_EXACT where we search for an empty slot within the hash bucket. Make the calculation more consistent between the cases. Signed-off-by: David Gibson Reviewed-by: Suraj Jitindar Singh --- hw/ppc/spapr_hcall.c | 58 +++++++++++++++++++++++++-----------------------= ---- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 42d20e0..3298a14 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -47,12 +47,12 @@ static bool has_spr(PowerPCCPU *cpu, int spr) return cpu->env.spr_cb[spr].name !=3D NULL; } =20 -static inline bool valid_pte_index(CPUPPCState *env, target_ulong pte_inde= x) +static inline bool valid_ptex(PowerPCCPU *cpu, target_ulong ptex) { /* * hash value/pteg group index is normalized by htab_mask */ - if (((pte_index & ~7ULL) / HPTES_PER_GROUP) & ~env->htab_mask) { + if (((ptex & ~7ULL) / HPTES_PER_GROUP) & ~cpu->env.htab_mask) { return false; } return true; @@ -77,14 +77,13 @@ static bool is_ram_address(sPAPRMachineState *spapr, hw= addr addr) static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { - CPUPPCState *env =3D &cpu->env; target_ulong flags =3D args[0]; - target_ulong pte_index =3D args[1]; + target_ulong ptex =3D args[1]; target_ulong pteh =3D args[2]; target_ulong ptel =3D args[3]; unsigned apshift; target_ulong raddr; - target_ulong index; + target_ulong slot; uint64_t token; =20 apshift =3D ppc_hash64_hpte_page_shift_noslb(cpu, pteh, ptel); @@ -116,25 +115,26 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMac= hineState *spapr, =20 pteh &=3D ~0x60ULL; =20 - if (!valid_pte_index(env, pte_index)) { + if (!valid_ptex(cpu, ptex)) { return H_PARAMETER; } =20 - index =3D 0; + slot =3D ptex & 7ULL; + ptex =3D ptex & ~7ULL; + if (likely((flags & H_EXACT) =3D=3D 0)) { - pte_index &=3D ~7ULL; - token =3D ppc_hash64_start_access(cpu, pte_index); - for (; index < 8; index++) { - if (!(ppc_hash64_load_hpte0(cpu, token, index) & HPTE64_V_VALI= D)) { + token =3D ppc_hash64_start_access(cpu, ptex); + for (slot =3D 0; slot < 8; slot++) { + if (!(ppc_hash64_load_hpte0(cpu, token, slot) & HPTE64_V_VALID= )) { break; } } ppc_hash64_stop_access(cpu, token); - if (index =3D=3D 8) { + if (slot =3D=3D 8) { return H_PTEG_FULL; } } else { - token =3D ppc_hash64_start_access(cpu, pte_index); + token =3D ppc_hash64_start_access(cpu, ptex); if (ppc_hash64_load_hpte0(cpu, token, 0) & HPTE64_V_VALID) { ppc_hash64_stop_access(cpu, token); return H_PTEG_FULL; @@ -142,10 +142,9 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMach= ineState *spapr, ppc_hash64_stop_access(cpu, token); } =20 - ppc_hash64_store_hpte(cpu, pte_index + index, - pteh | HPTE64_V_HPTE_DIRTY, ptel); + ppc_hash64_store_hpte(cpu, ptex + slot, pteh | HPTE64_V_HPTE_DIRTY, pt= el); =20 - args[0] =3D pte_index + index; + args[0] =3D ptex + slot; return H_SUCCESS; } =20 @@ -161,11 +160,10 @@ static RemoveResult remove_hpte(PowerPCCPU *cpu, targ= et_ulong ptex, target_ulong flags, target_ulong *vp, target_ulong *rp) { - CPUPPCState *env =3D &cpu->env; uint64_t token; target_ulong v, r; =20 - if (!valid_pte_index(env, ptex)) { + if (!valid_ptex(cpu, ptex)) { return REMOVE_PARM; } =20 @@ -191,11 +189,11 @@ static target_ulong h_remove(PowerPCCPU *cpu, sPAPRMa= chineState *spapr, { CPUPPCState *env =3D &cpu->env; target_ulong flags =3D args[0]; - target_ulong pte_index =3D args[1]; + target_ulong ptex =3D args[1]; target_ulong avpn =3D args[2]; RemoveResult ret; =20 - ret =3D remove_hpte(cpu, pte_index, avpn, flags, + ret =3D remove_hpte(cpu, ptex, avpn, flags, &args[0], &args[1]); =20 switch (ret) { @@ -291,16 +289,16 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPRM= achineState *spapr, { CPUPPCState *env =3D &cpu->env; target_ulong flags =3D args[0]; - target_ulong pte_index =3D args[1]; + target_ulong ptex =3D args[1]; target_ulong avpn =3D args[2]; uint64_t token; target_ulong v, r; =20 - if (!valid_pte_index(env, pte_index)) { + if (!valid_ptex(cpu, ptex)) { return H_PARAMETER; } =20 - token =3D ppc_hash64_start_access(cpu, pte_index); + token =3D ppc_hash64_start_access(cpu, ptex); v =3D ppc_hash64_load_hpte0(cpu, token, 0); r =3D ppc_hash64_load_hpte1(cpu, token, 0); ppc_hash64_stop_access(cpu, token); @@ -315,13 +313,13 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPRM= achineState *spapr, r |=3D (flags << 55) & HPTE64_R_PP0; r |=3D (flags << 48) & HPTE64_R_KEY_HI; r |=3D flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO); - ppc_hash64_store_hpte(cpu, pte_index, + ppc_hash64_store_hpte(cpu, ptex, (v & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY, 0); - ppc_hash64_tlb_flush_hpte(cpu, pte_index, v, r); + ppc_hash64_tlb_flush_hpte(cpu, ptex, v, r); /* Flush the tlb */ check_tlb_flush(env, true); /* Don't need a memory barrier, due to qemu's global lock */ - ppc_hash64_store_hpte(cpu, pte_index, v | HPTE64_V_HPTE_DIRTY, r); + ppc_hash64_store_hpte(cpu, ptex, v | HPTE64_V_HPTE_DIRTY, r); return H_SUCCESS; } =20 @@ -330,21 +328,21 @@ static target_ulong h_read(PowerPCCPU *cpu, sPAPRMach= ineState *spapr, { CPUPPCState *env =3D &cpu->env; target_ulong flags =3D args[0]; - target_ulong pte_index =3D args[1]; + target_ulong ptex =3D args[1]; uint8_t *hpte; int i, ridx, n_entries =3D 1; =20 - if (!valid_pte_index(env, pte_index)) { + if (!valid_ptex(cpu, ptex)) { return H_PARAMETER; } =20 if (flags & H_READ_4) { /* Clear the two low order bits */ - pte_index &=3D ~(3ULL); + ptex &=3D ~(3ULL); n_entries =3D 4; } =20 - hpte =3D env->external_htab + (pte_index * HASH_PTE_SIZE_64); + hpte =3D env->external_htab + (ptex * HASH_PTE_SIZE_64); =20 for (i =3D 0, ridx =3D 0; i < n_entries; i++) { args[ridx++] =3D ldq_p(hpte); --=20 2.9.3 From nobody Fri May 3 03:20:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487815919880273.34284004860956; Wed, 22 Feb 2017 18:11:59 -0800 (PST) Received: from localhost ([::1]:55988 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cgisw-0005s4-3O for importer@patchew.org; Wed, 22 Feb 2017 21:11:58 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57510) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cgiqo-0004Pb-DL for qemu-devel@nongnu.org; Wed, 22 Feb 2017 21:09:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cgiql-0007Ze-8v for qemu-devel@nongnu.org; Wed, 22 Feb 2017 21:09:46 -0500 Received: from ozlabs.org ([103.22.144.67]:36523) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cgiqk-0007Ye-Sc; Wed, 22 Feb 2017 21:09:43 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vTHjv6zW6z9s7k; Thu, 23 Feb 2017 13:09:39 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1487815779; bh=6yeicWUBn+wM4CPTtqy3GTxZOhheEFpQWslG+n5oCcw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=c63Ixde27WWL/IpH2rwPZXMr72e1Be75LfDh28q3bbyq0zmgabLIT7dMw4RSdZKTD dLZGaHoqPYHDoy7Xx15SXF3itYFUmuHvSuj+cWUeMaPizEb9aVsoQmZg0vwfC7TPrl s35tVzOGX8WiT5KNQCaPRQ9ZuquIZOTwlmxZT3AQ= From: David Gibson To: qemu-ppc@nongnu.org, aik@ozlabs.ru, sjitindarsingh@gmail.com Date: Thu, 23 Feb 2017 13:09:32 +1100 Message-Id: <20170223020936.29220-3-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170223020936.29220-1-david@gibson.dropbear.id.au> References: <20170223020936.29220-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 103.22.144.67 Subject: [Qemu-devel] [PATCH 2/6] target/ppc: Merge cpu_ppc_set_vhyp() with cpu_ppc_set_papr() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, agraf@suse.de, thuth@redhat.com, mdroth@linux.vnet.ibm.com, qemu-devel@nongnu.org, paulus@samba.org, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" cpu_ppc_set_papr() sets up various aspects of CPU state for use with PAPR paravirtualized guests. However, it doesn't set the virtual hypervisor, so callers must also call cpu_ppc_set_vhyp() so that PAPR hypercalls are handled properly. This is a bit silly, so fold setting the virtual hypervisor into cpu_ppc_set_papr(). Signed-off-by: David Gibson Reviewed-by: Suraj Jitindar Singh --- hw/ppc/spapr_cpu_core.c | 3 +-- target/ppc/cpu.h | 3 +-- target/ppc/translate_init.c | 10 +++------- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 55cd045..76563c4 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -57,8 +57,7 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, Powe= rPCCPU *cpu, cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ); =20 /* Enable PAPR mode in TCG or KVM */ - cpu_ppc_set_vhyp(cpu, PPC_VIRTUAL_HYPERVISOR(spapr)); - cpu_ppc_set_papr(cpu); + cpu_ppc_set_papr(cpu, PPC_VIRTUAL_HYPERVISOR(spapr)); =20 if (cpu->max_compat) { Error *local_err =3D NULL; diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 425e79d..f99bcae 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1300,8 +1300,7 @@ void store_booke_tcr (CPUPPCState *env, target_ulong = val); void store_booke_tsr (CPUPPCState *env, target_ulong val); void ppc_tlb_invalidate_all (CPUPPCState *env); void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr); -void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp); -void cpu_ppc_set_papr(PowerPCCPU *cpu); +void cpu_ppc_set_papr(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp); #endif #endif =20 diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c index be35cbd..a1405e9 100644 --- a/target/ppc/translate_init.c +++ b/target/ppc/translate_init.c @@ -8835,18 +8835,14 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) } =20 #if !defined(CONFIG_USER_ONLY) - -void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp) -{ - cpu->vhyp =3D vhyp; -} - -void cpu_ppc_set_papr(PowerPCCPU *cpu) +void cpu_ppc_set_papr(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp) { CPUPPCState *env =3D &cpu->env; ppc_spr_t *lpcr =3D &env->spr_cb[SPR_LPCR]; ppc_spr_t *amor =3D &env->spr_cb[SPR_AMOR]; =20 + cpu->vhyp =3D vhyp; + /* PAPR always has exception vectors in RAM not ROM. To ensure this, * MSR[IP] should never be set. * --=20 2.9.3 From nobody Fri May 3 03:20:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 148781592171646.637343419018066; Wed, 22 Feb 2017 18:12:01 -0800 (PST) Received: from localhost ([::1]:55989 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cgisy-0005uX-9b for importer@patchew.org; Wed, 22 Feb 2017 21:12:00 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57511) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cgiqo-0004Pc-Da for qemu-devel@nongnu.org; Wed, 22 Feb 2017 21:09:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cgiql-0007Zc-8y for qemu-devel@nongnu.org; Wed, 22 Feb 2017 21:09:46 -0500 Received: from ozlabs.org ([103.22.144.67]:48989) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cgiqk-0007Yh-So; Wed, 22 Feb 2017 21:09:43 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vTHjw0t8hz9s7n; Thu, 23 Feb 2017 13:09:39 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1487815780; bh=MSXyXDk9nGPqDj/tI/wIlVN9E307u+azAM442sjqVi8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nOSPknnyxwaW6iRbHS0ikK7DUuGD9vmwupKKsFxLJEF9O2Oy1k22x2UeIQKflu7Jj g6U96f44hzg2PPPckrT0UtZIP/dZk0KkTuMYLI4zVIJxE3Mr8nOkATzYilGmGAMxmh wcG0fvsFrPzsyGxO4/wwH6BTHpUCukxHj9wcUnzI= From: David Gibson To: qemu-ppc@nongnu.org, aik@ozlabs.ru, sjitindarsingh@gmail.com Date: Thu, 23 Feb 2017 13:09:33 +1100 Message-Id: <20170223020936.29220-4-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170223020936.29220-1-david@gibson.dropbear.id.au> References: <20170223020936.29220-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 103.22.144.67 Subject: [Qemu-devel] [PATCH 3/6] target/ppc: SDR1 is a hypervisor resource X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, agraf@suse.de, thuth@redhat.com, mdroth@linux.vnet.ibm.com, qemu-devel@nongnu.org, paulus@samba.org, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" At present the SDR1 register - the base of the system's hashed page table (HPT) - is represented as an SPR with supervisor read and write permission. However, on CPUs which have a hypervisor mode, the SDR1 is a hypervisor only resource. Change the permission checking on the SPR to reflect this. Now that this is done, we don't need to check for an external HPT executing mtsdr1: an external HPT only applies when we're emulating the behaviour of a hypervisor, rather than modelling the CPU's hypervisor mode internally, so if we're permitted to execute mtsdr1, we don't have an external HPT. Signed-off-by: David Gibson Reviewed-by: Suraj Jitindar Singh --- target/ppc/misc_helper.c | 8 +++----- target/ppc/translate_init.c | 20 ++++++++++++++++---- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index ab432ba..fa573dd 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -82,11 +82,9 @@ void helper_store_sdr1(CPUPPCState *env, target_ulong va= l) { PowerPCCPU *cpu =3D ppc_env_get_cpu(env); =20 - if (!env->external_htab) { - if (env->spr[SPR_SDR1] !=3D val) { - ppc_store_sdr1(env, val); - tlb_flush(CPU(cpu)); - } + if (env->spr[SPR_SDR1] !=3D val) { + ppc_store_sdr1(env, val); + tlb_flush(CPU(cpu)); } } =20 diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c index a1405e9..c92435d 100644 --- a/target/ppc/translate_init.c +++ b/target/ppc/translate_init.c @@ -740,10 +740,22 @@ static void gen_spr_ne_601 (CPUPPCState *env) &spr_read_decr, &spr_write_decr, 0x00000000); /* Memory management */ - spr_register(env, SPR_SDR1, "SDR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_sdr1, - 0x00000000); +#ifndef CONFIG_USER_ONLY + if (env->has_hv_mode) { + /* SDR1 is a hypervisor resource on CPUs which have a + * hypervisor mode */ + spr_register_hv(env, SPR_SDR1, "SDR1", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_sdr1, + 0x00000000); + } else { + spr_register(env, SPR_SDR1, "SDR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_sdr1, + 0x00000000); + } +#endif } =20 /* BATs 0-3 */ --=20 2.9.3 From nobody Fri May 3 03:20:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487816240585528.2774885693171; Wed, 22 Feb 2017 18:17:20 -0800 (PST) Received: from localhost ([::1]:56023 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cgiy6-00038u-KI for importer@patchew.org; Wed, 22 Feb 2017 21:17:18 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57516) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cgiqo-0004Pg-FT for qemu-devel@nongnu.org; Wed, 22 Feb 2017 21:09:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cgiql-0007Zs-ON for qemu-devel@nongnu.org; Wed, 22 Feb 2017 21:09:46 -0500 Received: from ozlabs.org ([103.22.144.67]:39213) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cgiqk-0007Yi-Si; Wed, 22 Feb 2017 21:09:43 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vTHjw1bVCz9s7p; Thu, 23 Feb 2017 13:09:40 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1487815780; bh=Susq+YxOTwRWD0KyeSsbMd4ln3R1hfkqu7O483TyDRE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aNWTbdlP0xYwfdGRPfpVrnAzjJ+214AIs4m7JhVineJdJlEVNhT8sIHwO+0uBbCKy VXwyk+Xt1A/GOSNEgW/UXrq/nVt3gKl65GDkRShMOE/Rod8iA4seCJVMzPG7UI7Vwq DNeuo4o2g+vdKrfVa1h+ML8kgqpTW7A8kAQbiLws= From: David Gibson To: qemu-ppc@nongnu.org, aik@ozlabs.ru, sjitindarsingh@gmail.com Date: Thu, 23 Feb 2017 13:09:34 +1100 Message-Id: <20170223020936.29220-5-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170223020936.29220-1-david@gibson.dropbear.id.au> References: <20170223020936.29220-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 103.22.144.67 Subject: [Qemu-devel] [PATCH 4/6] target/ppc: Cleanup HPTE accessors for 64-bit hash MMU X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, agraf@suse.de, thuth@redhat.com, mdroth@linux.vnet.ibm.com, qemu-devel@nongnu.org, paulus@samba.org, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Accesses to the hashed page table (HPT) are complicated by the fact that the HPT could be in one of three places: 1) Within guest memory - when we're emulating a full guest CPU at the hardware level (e.g. powernv, mac99, g3beige) 2) Within qemu, but outside guest memory - when we're emulating user and supervisor instructions within TCG, but instead of emulating the CPU's hypervisor mode, we just emulate a hypervisor's behaviour (pseries in TCG) 3) Within KVM - a pseries machine using KVM acceleration. Mostly accesses to the HPT are handled by KVM, but there are a few cases where qemu needs to access it via a special fd for the purpose. In order to batch accesses to the fd in case (3), we use a somewhat awkward ppc_hash64_start_access() / ppc_hash64_stop_access() pair, which for case (3) reads / releases a whole PTEG from the kernel. For cases (1) & (2) it just returns an address value. The actual HPTE load helpers then need to interpret the returned token differently in the 3 cases. This patch keeps the same basic structure, but simplfiies the details. First start_access() / stop_access() are renamed to get_pteg() and put_pteg() to make their operation more obvious. Second, read_pteg() now always returns a qemu pointer, which can always be used in the same way by the load_hpte() helpers. In case (1) it comes from address_space_map() in case (2) directly from qemu's HPT buffer and in case (3) from a temporary buffer read from the KVM fd. While we're at it, make things a bit more consistent in terms of types and variable names: avoid variables named 'index' (it shadows index(3) which can lead to confusing results), use 'hwaddr ptex' for HPTE indices and uint64_t for each of the HPTE words, use ptex throughout the call stack instead of pte_offset in some places (we still need that at the bottom layer, but nowhere else). Signed-off-by: David Gibson Reviewed-by: Suraj Jitindar Singh --- hw/ppc/spapr_hcall.c | 36 +++++++++--------- target/ppc/cpu.h | 3 +- target/ppc/kvm.c | 25 ++++++------- target/ppc/kvm_ppc.h | 43 ++++++++++------------ target/ppc/mmu-hash64.c | 98 ++++++++++++++++++++++++++-------------------= ---- target/ppc/mmu-hash64.h | 46 ++++++++--------------- 6 files changed, 119 insertions(+), 132 deletions(-) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 3298a14..fd961b5 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -84,7 +84,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachine= State *spapr, unsigned apshift; target_ulong raddr; target_ulong slot; - uint64_t token; + const ppc_hash_pte64_t *hptes; =20 apshift =3D ppc_hash64_hpte_page_shift_noslb(cpu, pteh, ptel); if (!apshift) { @@ -123,23 +123,23 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMac= hineState *spapr, ptex =3D ptex & ~7ULL; =20 if (likely((flags & H_EXACT) =3D=3D 0)) { - token =3D ppc_hash64_start_access(cpu, ptex); + hptes =3D ppc_hash64_map_hptes(cpu, ptex, HPTES_PER_GROUP); for (slot =3D 0; slot < 8; slot++) { - if (!(ppc_hash64_load_hpte0(cpu, token, slot) & HPTE64_V_VALID= )) { + if (!(ppc_hash64_hpte0(cpu, hptes, slot) & HPTE64_V_VALID)) { break; } } - ppc_hash64_stop_access(cpu, token); + ppc_hash64_unmap_hptes(cpu, hptes, ptex, HPTES_PER_GROUP); if (slot =3D=3D 8) { return H_PTEG_FULL; } } else { - token =3D ppc_hash64_start_access(cpu, ptex); - if (ppc_hash64_load_hpte0(cpu, token, 0) & HPTE64_V_VALID) { - ppc_hash64_stop_access(cpu, token); + hptes =3D ppc_hash64_map_hptes(cpu, ptex + slot, 1); + if (ppc_hash64_hpte0(cpu, hptes, 0) & HPTE64_V_VALID) { + ppc_hash64_unmap_hptes(cpu, hptes, ptex + slot, 1); return H_PTEG_FULL; } - ppc_hash64_stop_access(cpu, token); + ppc_hash64_unmap_hptes(cpu, hptes, ptex, 1); } =20 ppc_hash64_store_hpte(cpu, ptex + slot, pteh | HPTE64_V_HPTE_DIRTY, pt= el); @@ -160,17 +160,17 @@ static RemoveResult remove_hpte(PowerPCCPU *cpu, targ= et_ulong ptex, target_ulong flags, target_ulong *vp, target_ulong *rp) { - uint64_t token; + const ppc_hash_pte64_t *hptes; target_ulong v, r; =20 if (!valid_ptex(cpu, ptex)) { return REMOVE_PARM; } =20 - token =3D ppc_hash64_start_access(cpu, ptex); - v =3D ppc_hash64_load_hpte0(cpu, token, 0); - r =3D ppc_hash64_load_hpte1(cpu, token, 0); - ppc_hash64_stop_access(cpu, token); + hptes =3D ppc_hash64_map_hptes(cpu, ptex, 1); + v =3D ppc_hash64_hpte0(cpu, hptes, 0); + r =3D ppc_hash64_hpte1(cpu, hptes, 0); + ppc_hash64_unmap_hptes(cpu, hptes, ptex, 1); =20 if ((v & HPTE64_V_VALID) =3D=3D 0 || ((flags & H_AVPN) && (v & ~0x7fULL) !=3D avpn) || @@ -291,17 +291,17 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPRM= achineState *spapr, target_ulong flags =3D args[0]; target_ulong ptex =3D args[1]; target_ulong avpn =3D args[2]; - uint64_t token; + const ppc_hash_pte64_t *hptes; target_ulong v, r; =20 if (!valid_ptex(cpu, ptex)) { return H_PARAMETER; } =20 - token =3D ppc_hash64_start_access(cpu, ptex); - v =3D ppc_hash64_load_hpte0(cpu, token, 0); - r =3D ppc_hash64_load_hpte1(cpu, token, 0); - ppc_hash64_stop_access(cpu, token); + hptes =3D ppc_hash64_map_hptes(cpu, ptex, 1); + v =3D ppc_hash64_hpte0(cpu, hptes, 0); + r =3D ppc_hash64_hpte1(cpu, hptes, 0); + ppc_hash64_unmap_hptes(cpu, hptes, ptex, 1); =20 if ((v & HPTE64_V_VALID) =3D=3D 0 || ((flags & H_AVPN) && (v & ~0x7fULL) !=3D avpn)) { diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index f99bcae..c89973e 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -223,11 +223,12 @@ enum { typedef struct opc_handler_t opc_handler_t; =20 /*************************************************************************= ****/ -/* Types used to describe some PowerPC registers */ +/* Types used to describe some PowerPC registers etc. */ typedef struct DisasContext DisasContext; typedef struct ppc_spr_t ppc_spr_t; typedef union ppc_avr_t ppc_avr_t; typedef union ppc_tlb_t ppc_tlb_t; +typedef struct ppc_hash_pte64 ppc_hash_pte64_t; =20 /* SPR access micro-ops generations callbacks */ struct ppc_spr_t { diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 52bbea5..9d3e57e 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -2601,17 +2601,17 @@ struct kvm_get_htab_buf { /* * We require one extra byte for read */ - target_ulong hpte[(HPTES_PER_GROUP * 2) + 1]; + ppc_hash_pte64_t hpte[HPTES_PER_GROUP]; }; =20 -uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, target_ulong pte_index) +const ppc_hash_pte64_t *kvmppc_map_hptes(hwaddr ptex, int n) { int htab_fd; struct kvm_get_htab_fd ghf; - struct kvm_get_htab_buf *hpte_buf; + struct kvm_get_htab_buf *hpte_buf; =20 ghf.flags =3D 0; - ghf.start_index =3D pte_index; + ghf.start_index =3D ptex; htab_fd =3D kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf); if (htab_fd < 0) { goto error_out; @@ -2626,7 +2626,7 @@ uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, tar= get_ulong pte_index) } =20 close(htab_fd); - return (uint64_t)(uintptr_t) hpte_buf->hpte; + return hpte_buf->hpte; =20 out_close: g_free(hpte_buf); @@ -2635,18 +2635,15 @@ error_out: return 0; } =20 -void kvmppc_hash64_free_pteg(uint64_t token) +void kvmppc_unmap_hptes(const ppc_hash_pte64_t *hptes, hwaddr ptex, int n) { struct kvm_get_htab_buf *htab_buf; =20 - htab_buf =3D container_of((void *)(uintptr_t) token, struct kvm_get_ht= ab_buf, - hpte); + htab_buf =3D container_of((void *)hptes, struct kvm_get_htab_buf, hpte= ); g_free(htab_buf); - return; } =20 -void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index, - target_ulong pte0, target_ulong pte1) +void kvmppc_hash64_write_pte(hwaddr ptex, uint64_t pte0, uint64_t pte1) { int htab_fd; struct kvm_get_htab_fd ghf; @@ -2661,9 +2658,9 @@ void kvmppc_hash64_write_pte(CPUPPCState *env, target= _ulong pte_index, =20 hpte_buf.header.n_valid =3D 1; hpte_buf.header.n_invalid =3D 0; - hpte_buf.header.index =3D pte_index; - hpte_buf.hpte[0] =3D pte0; - hpte_buf.hpte[1] =3D pte1; + hpte_buf.header.index =3D ptex; + hpte_buf.hpte[0].pte0 =3D pte0; + hpte_buf.hpte[0].pte1 =3D pte1; /* * Write the hpte entry. * CAUTION: write() has the warn_unused_result attribute. Hence we diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index 8da2ee4..3f8fccd 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -41,6 +41,10 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t w= indow_size, int *pfd, int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size); int kvmppc_reset_htab(int shift_hint); uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift); +const ppc_hash_pte64_t *kvmppc_map_hptes(hwaddr ptex, int n); +void kvmppc_unmap_hptes(const ppc_hash_pte64_t *hptes, hwaddr ptex, int n); + +void kvmppc_hash64_write_pte(hwaddr ptex, uint64_t pte0, uint64_t pte1); #endif /* !CONFIG_USER_ONLY */ bool kvmppc_has_cap_epr(void); int kvmppc_define_rtas_kernel_token(uint32_t token, const char *function); @@ -49,11 +53,6 @@ int kvmppc_get_htab_fd(bool write); int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t max_ns); int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index, uint16_t n_valid, uint16_t n_invalid); -uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, target_ulong pte_index); -void kvmppc_hash64_free_pteg(uint64_t token); - -void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index, - target_ulong pte0, target_ulong pte1); bool kvmppc_has_cap_fixup_hcalls(void); bool kvmppc_has_cap_htm(void); int kvmppc_enable_hwrng(void); @@ -199,6 +198,22 @@ static inline bool kvmppc_is_mem_backend_page_size_ok(= char *obj_path) return true; } =20 +static inline const ppc_hash_pte64_t *kvmppc_map_hptes(hwaddr ptex, int n) +{ + abort(); +} + +static inline void kvmppc_unmap_hptes(const ppc_hash_pte64_t *hptes, + hwaddr ptex, int n) +{ + abort(); +} + +static inline void kvmppc_hash64_write_pte(hwaddr ptex, + uint64_t pte0, uint64_t pte1) +{ + abort(); +} #endif /* !CONFIG_USER_ONLY */ =20 static inline bool kvmppc_has_cap_epr(void) @@ -234,24 +249,6 @@ static inline int kvmppc_load_htab_chunk(QEMUFile *f, = int fd, uint32_t index, abort(); } =20 -static inline uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, - target_ulong pte_index) -{ - abort(); -} - -static inline void kvmppc_hash64_free_pteg(uint64_t token) -{ - abort(); -} - -static inline void kvmppc_hash64_write_pte(CPUPPCState *env, - target_ulong pte_index, - target_ulong pte0, target_ulong= pte1) -{ - abort(); -} - static inline bool kvmppc_has_cap_fixup_hcalls(void) { abort(); diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index 76669ed..c59db47 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -27,6 +27,7 @@ #include "kvm_ppc.h" #include "mmu-hash64.h" #include "exec/log.h" +#include "hw/hw.h" =20 //#define DEBUG_SLB =20 @@ -431,33 +432,42 @@ static int ppc_hash64_amr_prot(PowerPCCPU *cpu, ppc_h= ash_pte64_t pte) return prot; } =20 -uint64_t ppc_hash64_start_access(PowerPCCPU *cpu, target_ulong pte_index) +const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCCPU *cpu, + hwaddr ptex, int n) { - uint64_t token =3D 0; - hwaddr pte_offset; + const ppc_hash_pte64_t *hptes =3D NULL; + hwaddr pte_offset =3D ptex * HASH_PTE_SIZE_64; =20 - pte_offset =3D pte_index * HASH_PTE_SIZE_64; if (cpu->env.external_htab =3D=3D MMU_HASH64_KVM_MANAGED_HPT) { /* * HTAB is controlled by KVM. Fetch the PTEG into a new buffer. */ - token =3D kvmppc_hash64_read_pteg(cpu, pte_index); + hptes =3D kvmppc_map_hptes(ptex, n); } else if (cpu->env.external_htab) { /* * HTAB is controlled by QEMU. Just point to the internally * accessible PTEG. */ - token =3D (uint64_t)(uintptr_t) cpu->env.external_htab + pte_offse= t; + hptes =3D (ppc_hash_pte64_t *)(cpu->env.external_htab + pte_offset= ); } else if (cpu->env.htab_base) { - token =3D cpu->env.htab_base + pte_offset; + hwaddr plen =3D n * HASH_PTE_SIZE_64; + hptes =3D address_space_map(CPU(cpu)->as, cpu->env.htab_base + pte= _offset, + &plen, false); + if (plen < (n * HASH_PTE_SIZE_64)) { + hw_error("%s: Unable to map all requested HPTEs\n", __FUNCTION= __); + } } - return token; + return hptes; } =20 -void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t token) +void ppc_hash64_unmap_hptes(PowerPCCPU *cpu, const ppc_hash_pte64_t *hptes, + hwaddr ptex, int n) { if (cpu->env.external_htab =3D=3D MMU_HASH64_KVM_MANAGED_HPT) { - kvmppc_hash64_free_pteg(token); + kvmppc_unmap_hptes(hptes, ptex, n); + } else if (!cpu->env.external_htab) { + address_space_unmap(CPU(cpu)->as, (void *)hptes, n * HASH_PTE_SIZE= _64, + false, n * HASH_PTE_SIZE_64); } } =20 @@ -505,18 +515,18 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu,= hwaddr hash, { CPUPPCState *env =3D &cpu->env; int i; - uint64_t token; + const ppc_hash_pte64_t *pteg; target_ulong pte0, pte1; - target_ulong pte_index; + target_ulong ptex; =20 - pte_index =3D (hash & env->htab_mask) * HPTES_PER_GROUP; - token =3D ppc_hash64_start_access(cpu, pte_index); - if (!token) { + ptex =3D (hash & env->htab_mask) * HPTES_PER_GROUP; + pteg =3D ppc_hash64_map_hptes(cpu, ptex, HPTES_PER_GROUP); + if (!pteg) { return -1; } for (i =3D 0; i < HPTES_PER_GROUP; i++) { - pte0 =3D ppc_hash64_load_hpte0(cpu, token, i); - pte1 =3D ppc_hash64_load_hpte1(cpu, token, i); + pte0 =3D ppc_hash64_hpte0(cpu, pteg, i); + pte1 =3D ppc_hash64_hpte1(cpu, pteg, i); =20 /* This compares V, B, H (secondary) and the AVPN */ if (HPTE64_V_COMPARE(pte0, ptem)) { @@ -536,11 +546,11 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu,= hwaddr hash, */ pte->pte0 =3D pte0; pte->pte1 =3D pte1; - ppc_hash64_stop_access(cpu, token); - return (pte_index + i) * HASH_PTE_SIZE_64; + ppc_hash64_unmap_hptes(cpu, pteg, ptex, HPTES_PER_GROUP); + return ptex + i; } } - ppc_hash64_stop_access(cpu, token); + ppc_hash64_unmap_hptes(cpu, pteg, ptex, HPTES_PER_GROUP); /* * We didn't find a valid entry. */ @@ -552,8 +562,7 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu, ppc_hash_pte64_t *pte, unsigned *pshi= ft) { CPUPPCState *env =3D &cpu->env; - hwaddr pte_offset; - hwaddr hash; + hwaddr hash, ptex; uint64_t vsid, epnmask, epn, ptem; const struct ppc_one_seg_page_size *sps =3D slb->sps; =20 @@ -596,9 +605,9 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu, " vsid=3D" TARGET_FMT_lx " ptem=3D" TARGET_FMT_lx " hash=3D" TARGET_FMT_plx "\n", env->htab_base, env->htab_mask, vsid, ptem, hash); - pte_offset =3D ppc_hash64_pteg_search(cpu, hash, sps, ptem, pte, pshif= t); + ptex =3D ppc_hash64_pteg_search(cpu, hash, sps, ptem, pte, pshift); =20 - if (pte_offset =3D=3D -1) { + if (ptex =3D=3D -1) { /* Secondary PTEG lookup */ ptem |=3D HPTE64_V_SECONDARY; qemu_log_mask(CPU_LOG_MMU, @@ -607,10 +616,10 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu, " hash=3D" TARGET_FMT_plx "\n", env->htab_base, env->htab_mask, vsid, ptem, ~hash); =20 - pte_offset =3D ppc_hash64_pteg_search(cpu, ~hash, sps, ptem, pte, = pshift); + ptex =3D ppc_hash64_pteg_search(cpu, ~hash, sps, ptem, pte, pshift= ); } =20 - return pte_offset; + return ptex; } =20 unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu, @@ -708,7 +717,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr = eaddr, CPUPPCState *env =3D &cpu->env; ppc_slb_t *slb; unsigned apshift; - hwaddr pte_offset; + hwaddr ptex; ppc_hash_pte64_t pte; int pp_prot, amr_prot, prot; uint64_t new_pte1, dsisr; @@ -792,8 +801,8 @@ skip_slb_search: } =20 /* 4. Locate the PTE in the hash table */ - pte_offset =3D ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte, &apshift); - if (pte_offset =3D=3D -1) { + ptex =3D ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte, &apshift); + if (ptex =3D=3D -1) { dsisr =3D 0x40000000; if (rwx =3D=3D 2) { ppc_hash64_set_isi(cs, env, dsisr); @@ -806,7 +815,7 @@ skip_slb_search: return 1; } qemu_log_mask(CPU_LOG_MMU, - "found PTE at offset %08" HWADDR_PRIx "\n", pte_offset); + "found PTE at index %08" HWADDR_PRIx "\n", ptex); =20 /* 5. Check access permissions */ =20 @@ -849,8 +858,7 @@ skip_slb_search: } =20 if (new_pte1 !=3D pte.pte1) { - ppc_hash64_store_hpte(cpu, pte_offset / HASH_PTE_SIZE_64, - pte.pte0, new_pte1); + ppc_hash64_store_hpte(cpu, ptex, pte.pte0, new_pte1); } =20 /* 7. Determine the real address from the PTE */ @@ -867,7 +875,7 @@ hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, = target_ulong addr) { CPUPPCState *env =3D &cpu->env; ppc_slb_t *slb; - hwaddr pte_offset, raddr; + hwaddr ptex, raddr; ppc_hash_pte64_t pte; unsigned apshift; =20 @@ -900,8 +908,8 @@ hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, = target_ulong addr) } } =20 - pte_offset =3D ppc_hash64_htab_lookup(cpu, slb, addr, &pte, &apshift); - if (pte_offset =3D=3D -1) { + ptex =3D ppc_hash64_htab_lookup(cpu, slb, addr, &pte, &apshift); + if (ptex =3D=3D -1) { return -1; } =20 @@ -909,30 +917,28 @@ hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu= , target_ulong addr) & TARGET_PAGE_MASK; } =20 -void ppc_hash64_store_hpte(PowerPCCPU *cpu, - target_ulong pte_index, - target_ulong pte0, target_ulong pte1) +void ppc_hash64_store_hpte(PowerPCCPU *cpu, hwaddr ptex, + uint64_t pte0, uint64_t pte1) { CPUPPCState *env =3D &cpu->env; + hwaddr offset =3D ptex * HASH_PTE_SIZE_64; =20 if (env->external_htab =3D=3D MMU_HASH64_KVM_MANAGED_HPT) { - kvmppc_hash64_write_pte(env, pte_index, pte0, pte1); + kvmppc_hash64_write_pte(ptex, pte0, pte1); return; } =20 - pte_index *=3D HASH_PTE_SIZE_64; if (env->external_htab) { - stq_p(env->external_htab + pte_index, pte0); - stq_p(env->external_htab + pte_index + HASH_PTE_SIZE_64 / 2, pte1); + stq_p(env->external_htab + offset, pte0); + stq_p(env->external_htab + offset + HASH_PTE_SIZE_64 / 2, pte1); } else { - stq_phys(CPU(cpu)->as, env->htab_base + pte_index, pte0); + stq_phys(CPU(cpu)->as, env->htab_base + offset, pte0); stq_phys(CPU(cpu)->as, - env->htab_base + pte_index + HASH_PTE_SIZE_64 / 2, pte1); + env->htab_base + offset + HASH_PTE_SIZE_64 / 2, pte1); } } =20 -void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu, - target_ulong pte_index, +void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu, target_ulong ptex, target_ulong pte0, target_ulong pte1) { /* diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h index 7a0b7fc..8637fe4 100644 --- a/target/ppc/mmu-hash64.h +++ b/target/ppc/mmu-hash64.h @@ -10,8 +10,8 @@ int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot, hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr); int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr address, int rw, int mmu_idx); -void ppc_hash64_store_hpte(PowerPCCPU *cpu, target_ulong index, - target_ulong pte0, target_ulong pte1); +void ppc_hash64_store_hpte(PowerPCCPU *cpu, hwaddr ptex, + uint64_t pte0, uint64_t pte1); void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu, target_ulong pte_index, target_ulong pte0, target_ulong pte1); @@ -96,41 +96,27 @@ void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong = value, void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int shift, Error **errp); =20 -uint64_t ppc_hash64_start_access(PowerPCCPU *cpu, target_ulong pte_index); -void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t token); +struct ppc_hash_pte64 { + uint64_t pte0, pte1; +}; + +const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCCPU *cpu,\ + hwaddr ptex, int n); +void ppc_hash64_unmap_hptes(PowerPCCPU *cpu, const ppc_hash_pte64_t *hptes, + hwaddr ptex, int n); =20 -static inline target_ulong ppc_hash64_load_hpte0(PowerPCCPU *cpu, - uint64_t token, int index) +static inline uint64_t ppc_hash64_hpte0(PowerPCCPU *cpu, + const ppc_hash_pte64_t *hptes, int= i) { - CPUPPCState *env =3D &cpu->env; - uint64_t addr; - - addr =3D token + (index * HASH_PTE_SIZE_64); - if (env->external_htab) { - return ldq_p((const void *)(uintptr_t)addr); - } else { - return ldq_phys(CPU(cpu)->as, addr); - } + return ldq_p(&(hptes[i].pte0)); } =20 -static inline target_ulong ppc_hash64_load_hpte1(PowerPCCPU *cpu, - uint64_t token, int index) +static inline uint64_t ppc_hash64_hpte1(PowerPCCPU *cpu, + const ppc_hash_pte64_t *hptes, int= i) { - CPUPPCState *env =3D &cpu->env; - uint64_t addr; - - addr =3D token + (index * HASH_PTE_SIZE_64) + HASH_PTE_SIZE_64/2; - if (env->external_htab) { - return ldq_p((const void *)(uintptr_t)addr); - } else { - return ldq_phys(CPU(cpu)->as, addr); - } + return ldq_p(&(hptes[i].pte1)); } =20 -typedef struct { - uint64_t pte0, pte1; -} ppc_hash_pte64_t; - #endif /* CONFIG_USER_ONLY */ =20 #endif /* MMU_HASH64_H */ --=20 2.9.3 From nobody Fri May 3 03:20:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487816522118431.72844719511704; Wed, 22 Feb 2017 18:22:02 -0800 (PST) Received: from localhost ([::1]:56047 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cgj2e-00065A-OE for importer@patchew.org; Wed, 22 Feb 2017 21:22:00 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57601) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cgiqr-0004Sb-JR for qemu-devel@nongnu.org; Wed, 22 Feb 2017 21:09:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cgiqo-0007eH-U4 for qemu-devel@nongnu.org; Wed, 22 Feb 2017 21:09:49 -0500 Received: from ozlabs.org ([2401:3900:2:1::2]:50415) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cgiqo-0007a1-62; Wed, 22 Feb 2017 21:09:46 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vTHjw2rcWz9s83; Thu, 23 Feb 2017 13:09:40 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1487815780; bh=6iqfGOyGT0zSdl+Yo6VM6yxKkhhj2njlHHDrnMAh5F8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mpK+nqJzCcFM31khK7+TNIR05LpNFdbMEeM+0tgZJbAv1IPUczk21BuLO/t068fz8 hRC1iZvWlrIcRiMfHjBAi9F8cR7Y8DFgTBq0g2O818bW2VzVMASAFceyF3haLRzkWv PDWQHTnhCoNTlKZHiMg6OVltR7ehBLSn+IMSsjNk= From: David Gibson To: qemu-ppc@nongnu.org, aik@ozlabs.ru, sjitindarsingh@gmail.com Date: Thu, 23 Feb 2017 13:09:35 +1100 Message-Id: <20170223020936.29220-6-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170223020936.29220-1-david@gibson.dropbear.id.au> References: <20170223020936.29220-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PATCH 5/6] target/ppc: Eliminate htab_base and htab_mask variables X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, agraf@suse.de, thuth@redhat.com, mdroth@linux.vnet.ibm.com, qemu-devel@nongnu.org, paulus@samba.org, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" CPUPPCState includes fields htab_base and htab_mask which store the base address (GPA) and size (as a mask) of the guest's hashed page table (HPT). These are set when the SDR1 register is updated. Keeping these in sync with the SDR1 is actually a little bit fiddly, and probably not useful for performance, since keeping them expands the size of CPUPPCState. It also makes some upcoming changes harder to implement. This patch removes these fields, in favour of calculating them directly from the SDR1 contents when necessary. This does make a change to the behaviour of attempting to write a bad value (invalid HPT size) to the SDR1 with an mtspr instruction. Previously, the bad value would be stored in SDR1 and could be retrieved with a later mfspr, but the HPT size as used by the softmmu would be, clamped to the allowed values. Now, writing a bad value is treated as a no-op. An error message is printed in both new and old versions. I'm not sure which behaviour, if either, matches real hardware. I don't think it matters that much, since it's pretty clear that if an OS writes a bad value to SDR1, it's not going to boot. Signed-off-by: David Gibson Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr_hcall.c | 4 ++-- target/ppc/cpu.h | 8 -------- target/ppc/machine.c | 1 - target/ppc/mmu-hash32.c | 14 +++++++------- target/ppc/mmu-hash32.h | 24 ++++++++++++++++++------ target/ppc/mmu-hash64.c | 37 ++++++++++++++++--------------------- target/ppc/mmu-hash64.h | 13 +++++++++++++ target/ppc/mmu_helper.c | 31 ++++++++++++++++--------------- 8 files changed, 72 insertions(+), 60 deletions(-) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index fd961b5..85d96f6 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -50,9 +50,9 @@ static bool has_spr(PowerPCCPU *cpu, int spr) static inline bool valid_ptex(PowerPCCPU *cpu, target_ulong ptex) { /* - * hash value/pteg group index is normalized by htab_mask + * hash value/pteg group index is normalized by HPT mask */ - if (((ptex & ~7ULL) / HPTES_PER_GROUP) & ~cpu->env.htab_mask) { + if (((ptex & ~7ULL) / HPTES_PER_GROUP) & ~ppc_hash64_hpt_mask(cpu)) { return false; } return true; diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index c89973e..c6cd9ab 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -309,11 +309,6 @@ union ppc_tlb_t { #define SDR_32_HTABORG 0xFFFF0000UL #define SDR_32_HTABMASK 0x000001FFUL =20 -#if defined(TARGET_PPC64) -#define SDR_64_HTABORG 0xFFFFFFFFFFFC0000ULL -#define SDR_64_HTABSIZE 0x000000000000001FULL -#endif /* defined(TARGET_PPC64 */ - typedef struct ppc_slb_t ppc_slb_t; struct ppc_slb_t { uint64_t esid; @@ -1006,9 +1001,6 @@ struct CPUPPCState { /* tcg TLB needs flush (deferred slb inval instruction typically) */ #endif /* segment registers */ - hwaddr htab_base; - /* mask used to normalize hash value to PTEG index */ - hwaddr htab_mask; target_ulong sr[32]; /* externally stored hash table */ uint8_t *external_htab; diff --git a/target/ppc/machine.c b/target/ppc/machine.c index df9f7a4..1ccbc8a 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -229,7 +229,6 @@ static int cpu_post_load(void *opaque, int version_id) } =20 if (!env->external_htab) { - /* Restore htab_base and htab_mask variables */ ppc_store_sdr1(env, env->spr[SPR_SDR1]); } =20 diff --git a/target/ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c index 29bace6..03ae3c1 100644 --- a/target/ppc/mmu-hash32.c +++ b/target/ppc/mmu-hash32.c @@ -304,9 +304,9 @@ static int ppc_hash32_direct_store(PowerPCCPU *cpu, tar= get_ulong sr, =20 hwaddr get_pteg_offset32(PowerPCCPU *cpu, hwaddr hash) { - CPUPPCState *env =3D &cpu->env; + target_ulong mask =3D ppc_hash32_hpt_mask(cpu); =20 - return (hash * HASH_PTEG_SIZE_32) & env->htab_mask; + return (hash * HASH_PTEG_SIZE_32) & mask; } =20 static hwaddr ppc_hash32_pteg_search(PowerPCCPU *cpu, hwaddr pteg_off, @@ -339,7 +339,6 @@ static hwaddr ppc_hash32_htab_lookup(PowerPCCPU *cpu, target_ulong sr, target_ulong eaddr, ppc_hash_pte32_t *pte) { - CPUPPCState *env =3D &cpu->env; hwaddr pteg_off, pte_offset; hwaddr hash; uint32_t vsid, pgidx, ptem; @@ -353,21 +352,22 @@ static hwaddr ppc_hash32_htab_lookup(PowerPCCPU *cpu, qemu_log_mask(CPU_LOG_MMU, "htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx " hash " TARGET_FMT_plx "\n", - env->htab_base, env->htab_mask, hash); + ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash); =20 /* Primary PTEG lookup */ qemu_log_mask(CPU_LOG_MMU, "0 htab=3D" TARGET_FMT_plx "/" TARGET_FMT_p= lx " vsid=3D%" PRIx32 " ptem=3D%" PRIx32 " hash=3D" TARGET_FMT_plx "\n", - env->htab_base, env->htab_mask, vsid, ptem, hash); + ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), + vsid, ptem, hash); pteg_off =3D get_pteg_offset32(cpu, hash); pte_offset =3D ppc_hash32_pteg_search(cpu, pteg_off, 0, ptem, pte); if (pte_offset =3D=3D -1) { /* Secondary PTEG lookup */ qemu_log_mask(CPU_LOG_MMU, "1 htab=3D" TARGET_FMT_plx "/" TARGET_F= MT_plx " vsid=3D%" PRIx32 " api=3D%" PRIx32 - " hash=3D" TARGET_FMT_plx "\n", env->htab_base, - env->htab_mask, vsid, ptem, ~hash); + " hash=3D" TARGET_FMT_plx "\n", ppc_hash32_hpt_base(cpu), + ppc_hash32_hpt_mask(cpu), vsid, ptem, ~hash); pteg_off =3D get_pteg_offset32(cpu, ~hash); pte_offset =3D ppc_hash32_pteg_search(cpu, pteg_off, 1, ptem, pte); } diff --git a/target/ppc/mmu-hash32.h b/target/ppc/mmu-hash32.h index 5b9fb08..054be65 100644 --- a/target/ppc/mmu-hash32.h +++ b/target/ppc/mmu-hash32.h @@ -65,42 +65,54 @@ int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr = address, int rw, #define HPTE32_R_WIMG 0x00000078 #define HPTE32_R_PP 0x00000003 =20 +static inline hwaddr ppc_hash32_hpt_base(PowerPCCPU *cpu) +{ + return cpu->env.spr[SPR_SDR1] & SDR_32_HTABORG; +} + +static inline hwaddr ppc_hash32_hpt_mask(PowerPCCPU *cpu) +{ + return ((cpu->env.spr[SPR_SDR1] & SDR_32_HTABMASK) << 16) | 0xFFFF; +} + static inline target_ulong ppc_hash32_load_hpte0(PowerPCCPU *cpu, hwaddr pte_offset) { CPUPPCState *env =3D &cpu->env; + target_ulong base =3D ppc_hash32_hpt_base(cpu); =20 assert(!env->external_htab); /* Not supported on 32-bit for now */ - return ldl_phys(CPU(cpu)->as, env->htab_base + pte_offset); + return ldl_phys(CPU(cpu)->as, base + pte_offset); } =20 static inline target_ulong ppc_hash32_load_hpte1(PowerPCCPU *cpu, hwaddr pte_offset) { + target_ulong base =3D ppc_hash32_hpt_base(cpu); CPUPPCState *env =3D &cpu->env; =20 assert(!env->external_htab); /* Not supported on 32-bit for now */ - return ldl_phys(CPU(cpu)->as, - env->htab_base + pte_offset + HASH_PTE_SIZE_32 / 2); + return ldl_phys(CPU(cpu)->as, base + pte_offset + HASH_PTE_SIZE_32 / 2= ); } =20 static inline void ppc_hash32_store_hpte0(PowerPCCPU *cpu, hwaddr pte_offset, target_ulong = pte0) { CPUPPCState *env =3D &cpu->env; + target_ulong base =3D ppc_hash32_hpt_base(cpu); =20 assert(!env->external_htab); /* Not supported on 32-bit for now */ - stl_phys(CPU(cpu)->as, env->htab_base + pte_offset, pte0); + stl_phys(CPU(cpu)->as, base + pte_offset, pte0); } =20 static inline void ppc_hash32_store_hpte1(PowerPCCPU *cpu, hwaddr pte_offset, target_ulong = pte1) { CPUPPCState *env =3D &cpu->env; + target_ulong base =3D ppc_hash32_hpt_base(cpu); =20 assert(!env->external_htab); /* Not supported on 32-bit for now */ - stl_phys(CPU(cpu)->as, - env->htab_base + pte_offset + HASH_PTE_SIZE_32 / 2, pte1); + stl_phys(CPU(cpu)->as, base + pte_offset + HASH_PTE_SIZE_32 / 2, pte1); } =20 typedef struct { diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index c59db47..bb87777 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -304,15 +304,13 @@ void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulon= g value, CPUPPCState *env =3D &cpu->env; target_ulong htabsize =3D value & SDR_64_HTABSIZE; =20 - env->spr[SPR_SDR1] =3D value; if (htabsize > 28) { error_setg(errp, "Invalid HTABSIZE 0x" TARGET_FMT_lx" stored in SDR1", htabsize); - htabsize =3D 28; + return; } - env->htab_mask =3D (1ULL << (htabsize + 18 - 7)) - 1; - env->htab_base =3D value & SDR_64_HTABORG; + env->spr[SPR_SDR1] =3D value; } =20 void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int shift, @@ -333,10 +331,6 @@ void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void= *hpt, int shift, return; } =20 - /* Not strictly necessary, but makes it clearer that an external - * htab is in use when debugging */ - env->htab_base =3D -1; - if (kvm_enabled()) { if (kvmppc_put_books_sregs(cpu) < 0) { error_setg(errp, "Unable to update SDR1 in KVM"); @@ -448,11 +442,12 @@ const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCC= PU *cpu, * HTAB is controlled by QEMU. Just point to the internally * accessible PTEG. */ - hptes =3D (ppc_hash_pte64_t *)(cpu->env.external_htab + pte_offset= ); - } else if (cpu->env.htab_base) { + hptes =3D (const ppc_hash_pte64_t *)(cpu->env.external_htab + pte_= offset); + } else if (ppc_hash64_hpt_base(cpu)) { + hwaddr base =3D ppc_hash64_hpt_base(cpu); hwaddr plen =3D n * HASH_PTE_SIZE_64; - hptes =3D address_space_map(CPU(cpu)->as, cpu->env.htab_base + pte= _offset, - &plen, false); + hptes =3D address_space_map(CPU(cpu)->as, base + pte_offset, + &plen, false); if (plen < (n * HASH_PTE_SIZE_64)) { hw_error("%s: Unable to map all requested HPTEs\n", __FUNCTION= __); } @@ -513,13 +508,12 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu,= hwaddr hash, target_ulong ptem, ppc_hash_pte64_t *pte, unsigned *pshi= ft) { - CPUPPCState *env =3D &cpu->env; int i; const ppc_hash_pte64_t *pteg; target_ulong pte0, pte1; target_ulong ptex; =20 - ptex =3D (hash & env->htab_mask) * HPTES_PER_GROUP; + ptex =3D (hash & ppc_hash64_hpt_mask(cpu)) * HPTES_PER_GROUP; pteg =3D ppc_hash64_map_hptes(cpu, ptex, HPTES_PER_GROUP); if (!pteg) { return -1; @@ -597,14 +591,15 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu, qemu_log_mask(CPU_LOG_MMU, "htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx " hash " TARGET_FMT_plx "\n", - env->htab_base, env->htab_mask, hash); + ppc_hash64_hpt_base(cpu), ppc_hash64_hpt_mask(cpu), hash); =20 /* Primary PTEG lookup */ qemu_log_mask(CPU_LOG_MMU, "0 htab=3D" TARGET_FMT_plx "/" TARGET_FMT_plx " vsid=3D" TARGET_FMT_lx " ptem=3D" TARGET_FMT_lx " hash=3D" TARGET_FMT_plx "\n", - env->htab_base, env->htab_mask, vsid, ptem, hash); + ppc_hash64_hpt_base(cpu), ppc_hash64_hpt_mask(cpu), + vsid, ptem, hash); ptex =3D ppc_hash64_pteg_search(cpu, hash, sps, ptem, pte, pshift); =20 if (ptex =3D=3D -1) { @@ -613,8 +608,8 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu, qemu_log_mask(CPU_LOG_MMU, "1 htab=3D" TARGET_FMT_plx "/" TARGET_FMT_plx " vsid=3D" TARGET_FMT_lx " api=3D" TARGET_FMT_lx - " hash=3D" TARGET_FMT_plx "\n", env->htab_base, - env->htab_mask, vsid, ptem, ~hash); + " hash=3D" TARGET_FMT_plx "\n", ppc_hash64_hpt_base(cpu), + ppc_hash64_hpt_mask(cpu), vsid, ptem, ~hash); =20 ptex =3D ppc_hash64_pteg_search(cpu, ~hash, sps, ptem, pte, pshift= ); } @@ -932,9 +927,9 @@ void ppc_hash64_store_hpte(PowerPCCPU *cpu, hwaddr ptex, stq_p(env->external_htab + offset, pte0); stq_p(env->external_htab + offset + HASH_PTE_SIZE_64 / 2, pte1); } else { - stq_phys(CPU(cpu)->as, env->htab_base + offset, pte0); - stq_phys(CPU(cpu)->as, - env->htab_base + offset + HASH_PTE_SIZE_64 / 2, pte1); + hwaddr base =3D ppc_hash64_hpt_base(cpu); + stq_phys(CPU(cpu)->as, base + offset, pte0); + stq_phys(CPU(cpu)->as, base + offset + HASH_PTE_SIZE_64 / 2, pte1); } } =20 diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h index 8637fe4..dc0bc99 100644 --- a/target/ppc/mmu-hash64.h +++ b/target/ppc/mmu-hash64.h @@ -56,6 +56,9 @@ void ppc_hash64_update_rmls(CPUPPCState *env); * Hash page table definitions */ =20 +#define SDR_64_HTABORG 0xFFFFFFFFFFFC0000ULL +#define SDR_64_HTABSIZE 0x000000000000001FULL + #define HPTES_PER_GROUP 8 #define HASH_PTE_SIZE_64 16 #define HASH_PTEG_SIZE_64 (HASH_PTE_SIZE_64 * HPTES_PER_GROUP) @@ -91,6 +94,16 @@ void ppc_hash64_update_rmls(CPUPPCState *env); #define HPTE64_V_1TB_SEG 0x4000000000000000ULL #define HPTE64_V_VRMA_MASK 0x4001ffffff000000ULL =20 +static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu) +{ + return cpu->env.spr[SPR_SDR1] & SDR_64_HTABORG; +} + +static inline hwaddr ppc_hash64_hpt_mask(PowerPCCPU *cpu) +{ + return (1ULL << ((cpu->env.spr[SPR_SDR1] & SDR_64_HTABSIZE) + 18 - 7))= - 1; +} + void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong value, Error **errp); void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int shift, diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c index eb2d482..1381635 100644 --- a/target/ppc/mmu_helper.c +++ b/target/ppc/mmu_helper.c @@ -466,6 +466,7 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t = *ctx, static inline int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw, int type) { + PowerPCCPU *cpu =3D ppc_env_get_cpu(env); hwaddr hash; target_ulong vsid; int ds, pr, target_page_bits; @@ -503,7 +504,7 @@ static inline int get_segment_6xx_tlb(CPUPPCState *env,= mmu_ctx_t *ctx, qemu_log_mask(CPU_LOG_MMU, "htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx " hash " TARGET_FMT_plx "\n", - env->htab_base, env->htab_mask, hash); + ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), ha= sh); ctx->hash[0] =3D hash; ctx->hash[1] =3D ~hash; =20 @@ -518,9 +519,11 @@ static inline int get_segment_6xx_tlb(CPUPPCState *env= , mmu_ctx_t *ctx, uint32_t a0, a1, a2, a3; =20 qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_= plx - "\n", env->htab_base, env->htab_mask + 0x80); - for (curaddr =3D env->htab_base; - curaddr < (env->htab_base + env->htab_mask + 0x80); + "\n", ppc_hash32_hpt_base(cpu), + ppc_hash32_hpt_mask(env) + 0x80); + for (curaddr =3D ppc_hash32_hpt_base(cpu); + curaddr < (ppc_hash32_hpt_base(cpu) + + ppc_hash32_hpt_mask(cpu) + 0x80); curaddr +=3D 16) { a0 =3D ldl_phys(cs->as, curaddr); a1 =3D ldl_phys(cs->as, curaddr + 4); @@ -1205,12 +1208,13 @@ static void mmu6xx_dump_BATs(FILE *f, fprintf_funct= ion cpu_fprintf, static void mmu6xx_dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env) { + PowerPCCPU *cpu =3D ppc_env_get_cpu(env); ppc6xx_tlb_t *tlb; target_ulong sr; int type, way, entry, i; =20 - cpu_fprintf(f, "HTAB base =3D 0x%"HWADDR_PRIx"\n", env->htab_base); - cpu_fprintf(f, "HTAB mask =3D 0x%"HWADDR_PRIx"\n", env->htab_mask); + cpu_fprintf(f, "HTAB base =3D 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_base= (cpu)); + cpu_fprintf(f, "HTAB mask =3D 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_mask= (cpu)); =20 cpu_fprintf(f, "\nSegment registers:\n"); for (i =3D 0; i < 32; i++) { @@ -1592,9 +1596,9 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env,= target_ulong address, env->spr[SPR_DCMP] =3D 0x80000000 | ctx.ptem; tlb_miss: env->error_code |=3D ctx.key << 19; - env->spr[SPR_HASH1] =3D env->htab_base + + env->spr[SPR_HASH1] =3D ppc_hash32_hpt_base(cpu) + get_pteg_offset32(cpu, ctx.hash[0]); - env->spr[SPR_HASH2] =3D env->htab_base + + env->spr[SPR_HASH2] =3D ppc_hash32_hpt_base(cpu) + get_pteg_offset32(cpu, ctx.hash[1]); break; case POWERPC_MMU_SOFT_74xx: @@ -1999,7 +2003,6 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong va= lue) { qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value); assert(!env->external_htab); - env->spr[SPR_SDR1] =3D value; #if defined(TARGET_PPC64) if (env->mmu_model & POWERPC_MMU_64) { PowerPCCPU *cpu =3D ppc_env_get_cpu(env); @@ -2009,14 +2012,12 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong = value) if (local_err) { error_report_err(local_err); error_free(local_err); + return; } - } else -#endif /* defined(TARGET_PPC64) */ - { - /* FIXME: Should check for valid HTABMASK values */ - env->htab_mask =3D ((value & SDR_32_HTABMASK) << 16) | 0xFFFF; - env->htab_base =3D value & SDR_32_HTABORG; } +#endif /* defined(TARGET_PPC64) */ + /* FIXME: Should check for valid HTABMASK values in 32-bit case */ + env->spr[SPR_SDR1] =3D value; } =20 /* Segment registers load and store */ --=20 2.9.3 From nobody Fri May 3 03:20:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487816407216652.1526792205502; Wed, 22 Feb 2017 18:20:07 -0800 (PST) Received: from localhost ([::1]:56034 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cgj0n-0004xk-TY for importer@patchew.org; Wed, 22 Feb 2017 21:20:05 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57577) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cgiqq-0004Rn-T2 for qemu-devel@nongnu.org; Wed, 22 Feb 2017 21:09:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cgiqo-0007eN-U4 for qemu-devel@nongnu.org; Wed, 22 Feb 2017 21:09:48 -0500 Received: from ozlabs.org ([2401:3900:2:1::2]:36227) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cgiqo-0007a2-72; Wed, 22 Feb 2017 21:09:46 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vTHjw28LCz9s7s; Thu, 23 Feb 2017 13:09:40 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1487815780; bh=anZFv80y70JAjs7REfKpXiIUBtdvFlRU3euPEJWU7Xc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=V3dNKY/DiJkY72jiMNgIC7SRqJnHvu1hc5UKESK8Sj+O8DACHnEvfdBLCrVhMDf2+ MyLe4+sGtmcQsQFVRUn4FpKp1lKnU8RRYaSluEU9jOsTH7TTYk1VtR4LFPo0/Zt7rg 1M04Fao2izEnwYLxqMHAjSQ0zKL6vJTXfQOB0Yt0= From: David Gibson To: qemu-ppc@nongnu.org, aik@ozlabs.ru, sjitindarsingh@gmail.com Date: Thu, 23 Feb 2017 13:09:36 +1100 Message-Id: <20170223020936.29220-7-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170223020936.29220-1-david@gibson.dropbear.id.au> References: <20170223020936.29220-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PATCH 6/6] target/ppc: Manage external HPT via virtual hypervisor X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, agraf@suse.de, thuth@redhat.com, mdroth@linux.vnet.ibm.com, qemu-devel@nongnu.org, paulus@samba.org, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The pseries machine type implements the behaviour of a PAPR compliant hypervisor, without actually executing such a hypervisor on the virtual CPU. To do this we need some hooks in the CPU code to make hypervisor facilities get redirected to the machine instead of emulated internally. For hypercalls this is managed through the cpu->vhyp field, which points to a QOM interface with a method implementing the hypercall. For the hashed page table (HPT) - also a hypervisor resource - we use an older hack. CPUPPCState has an 'external_htab' field which when non-NULL indicates that the HPT is stored in qemu memory, rather than within the guest's address space. For consistency - and to make some future extensions easier - this merges the external HPT mechanism into the vhyp mechanism. Methods are added to vhyp for the basic operations the core hash MMU code needs: map_hptes() and unmap_hptes() for reading the HPT, store_hpte() for updating it and hpt_mask() to retrieve its size. To match this, the pseries machine now sets these vhyp fields in its existing vhyp class, rather than reaching into the cpu object to set the external_htab field. Signed-off-by: David Gibson Reviewed-by: Suraj Jitindar Singh --- hw/ppc/spapr.c | 58 +++++++++++++++++++++++++++++ hw/ppc/spapr_cpu_core.c | 17 ++++++++- hw/ppc/spapr_hcall.c | 3 +- target/ppc/cpu.h | 10 ++++- target/ppc/kvm.c | 2 +- target/ppc/machine.c | 4 +- target/ppc/mmu-hash32.h | 8 ---- target/ppc/mmu-hash64.c | 98 ++++++++++++++++-----------------------------= ---- target/ppc/mmu-hash64.h | 7 +++- target/ppc/mmu_helper.c | 3 +- 10 files changed, 123 insertions(+), 87 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 5904e64..c159961 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1050,6 +1050,60 @@ static void close_htab_fd(sPAPRMachineState *spapr) spapr->htab_fd =3D -1; } =20 +static hwaddr spapr_hpt_mask(PPCVirtualHypervisor *vhyp) +{ + sPAPRMachineState *spapr =3D SPAPR_MACHINE(vhyp); + + return HTAB_SIZE(spapr) / HASH_PTEG_SIZE_64 - 1; +} + +static const ppc_hash_pte64_t *spapr_map_hptes(PPCVirtualHypervisor *vhyp, + hwaddr ptex, int n) +{ + sPAPRMachineState *spapr =3D SPAPR_MACHINE(vhyp); + hwaddr pte_offset =3D ptex * HASH_PTE_SIZE_64; + + if (!spapr->htab) { + /* + * HTAB is controlled by KVM. Fetch the PTEG into a new buffer. + */ + return kvmppc_map_hptes(ptex, n); + } + + /* + * HTAB is controlled by QEMU. Just point to the internally + * accessible PTEG. + */ + return (const ppc_hash_pte64_t *)(spapr->htab + pte_offset); +} + +static void spapr_unmap_hptes(PPCVirtualHypervisor *vhyp, + const ppc_hash_pte64_t *hptes, + hwaddr ptex, int n) +{ + sPAPRMachineState *spapr =3D SPAPR_MACHINE(vhyp); + + if (!spapr->htab) { + kvmppc_unmap_hptes(hptes, ptex, n); + } + + /* Nothing to do for qemu managed HPT */ +} + +static void spapr_store_hpte(PPCVirtualHypervisor *vhyp, hwaddr ptex, + uint64_t pte0, uint64_t pte1) +{ + sPAPRMachineState *spapr =3D SPAPR_MACHINE(vhyp); + hwaddr offset =3D ptex * HASH_PTE_SIZE_64; + + if (!spapr->htab) { + kvmppc_hash64_write_pte(ptex, pte0, pte1); + } else { + stq_p(spapr->htab + offset, pte0); + stq_p(spapr->htab + offset + HASH_PTE_SIZE_64 / 2, pte1); + } +} + static int spapr_hpt_shift_for_ramsize(uint64_t ramsize) { int shift; @@ -2910,6 +2964,10 @@ static void spapr_machine_class_init(ObjectClass *oc= , void *data) nc->nmi_monitor_handler =3D spapr_nmi; smc->phb_placement =3D spapr_phb_placement; vhc->hypercall =3D emulate_spapr_hypercall; + vhc->hpt_mask =3D spapr_hpt_mask; + vhc->map_hptes =3D spapr_map_hptes; + vhc->unmap_hptes =3D spapr_unmap_hptes; + vhc->store_hpte =3D spapr_store_hpte; } =20 static const TypeInfo spapr_machine_info =3D { diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 76563c4..ddb130f 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -13,10 +13,12 @@ #include "hw/boards.h" #include "qapi/error.h" #include "sysemu/cpus.h" +#include "sysemu/kvm.h" #include "target/ppc/kvm_ppc.h" #include "hw/ppc/ppc.h" #include "target/ppc/mmu-hash64.h" #include "sysemu/numa.h" +#include "qemu/error-report.h" =20 static void spapr_cpu_reset(void *opaque) { @@ -34,8 +36,19 @@ static void spapr_cpu_reset(void *opaque) =20 env->spr[SPR_HIOR] =3D 0; =20 - ppc_hash64_set_external_hpt(cpu, spapr->htab, spapr->htab_shift, - &error_fatal); + /* + * This is a hack for the benefit of KVM PR - it abuses the SDR1 + * slot in kvm_sregs to communicate the userspace address of the + * HPT + */ + if (kvm_enabled()) { + env->spr[SPR_SDR1] =3D (target_ulong)(uintptr_t)spapr->htab + | (spapr->htab_shift - 18); + if (kvmppc_put_books_sregs(cpu) < 0) { + error_report("Unable to update SDR1 in KVM"); + exit(1); + } + } } =20 static void spapr_cpu_destroy(PowerPCCPU *cpu) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 85d96f6..f05a90e 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -326,7 +326,6 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPRMac= hineState *spapr, static target_ulong h_read(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { - CPUPPCState *env =3D &cpu->env; target_ulong flags =3D args[0]; target_ulong ptex =3D args[1]; uint8_t *hpte; @@ -342,7 +341,7 @@ static target_ulong h_read(PowerPCCPU *cpu, sPAPRMachin= eState *spapr, n_entries =3D 4; } =20 - hpte =3D env->external_htab + (ptex * HASH_PTE_SIZE_64); + hpte =3D spapr->htab + (ptex * HASH_PTE_SIZE_64); =20 for (i =3D 0, ridx =3D 0; i < n_entries; i++) { args[ridx++] =3D ldq_p(hpte); diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index c6cd9ab..27b78ca 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1002,8 +1002,6 @@ struct CPUPPCState { #endif /* segment registers */ target_ulong sr[32]; - /* externally stored hash table */ - uint8_t *external_htab; /* BATs */ uint32_t nb_BATs; target_ulong DBAT[2][8]; @@ -1211,6 +1209,14 @@ struct PPCVirtualHypervisor { struct PPCVirtualHypervisorClass { InterfaceClass parent; void (*hypercall)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu); + hwaddr (*hpt_mask)(PPCVirtualHypervisor *vhyp); + const ppc_hash_pte64_t *(*map_hptes)(PPCVirtualHypervisor *vhyp, + hwaddr ptex, int n); + void (*unmap_hptes)(PPCVirtualHypervisor *vhyp, + const ppc_hash_pte64_t *hptes, + hwaddr ptex, int n); + void (*store_hpte)(PPCVirtualHypervisor *vhyp, hwaddr ptex, + uint64_t pte0, uint64_t pte1); }; =20 #define TYPE_PPC_VIRTUAL_HYPERVISOR "ppc-virtual-hypervisor" diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 9d3e57e..c40f6aa 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -1251,7 +1251,7 @@ static int kvmppc_get_books_sregs(PowerPCCPU *cpu) return ret; } =20 - if (!env->external_htab) { + if (!cpu->vhyp) { ppc_store_sdr1(env, sregs.u.s.sdr1); } =20 diff --git a/target/ppc/machine.c b/target/ppc/machine.c index 1ccbc8a..6cb3a48 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -76,7 +76,7 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int ve= rsion_id) qemu_get_betls(f, &env->pb[i]); for (i =3D 0; i < 1024; i++) qemu_get_betls(f, &env->spr[i]); - if (!env->external_htab) { + if (!cpu->vhyp) { ppc_store_sdr1(env, sdr1); } qemu_get_be32s(f, &env->vscr); @@ -228,7 +228,7 @@ static int cpu_post_load(void *opaque, int version_id) env->IBAT[1][i+4] =3D env->spr[SPR_IBAT4U + 2*i + 1]; } =20 - if (!env->external_htab) { + if (!cpu->vhyp) { ppc_store_sdr1(env, env->spr[SPR_SDR1]); } =20 diff --git a/target/ppc/mmu-hash32.h b/target/ppc/mmu-hash32.h index 054be65..644cfe6 100644 --- a/target/ppc/mmu-hash32.h +++ b/target/ppc/mmu-hash32.h @@ -78,10 +78,8 @@ static inline hwaddr ppc_hash32_hpt_mask(PowerPCCPU *cpu) static inline target_ulong ppc_hash32_load_hpte0(PowerPCCPU *cpu, hwaddr pte_offset) { - CPUPPCState *env =3D &cpu->env; target_ulong base =3D ppc_hash32_hpt_base(cpu); =20 - assert(!env->external_htab); /* Not supported on 32-bit for now */ return ldl_phys(CPU(cpu)->as, base + pte_offset); } =20 @@ -89,29 +87,23 @@ static inline target_ulong ppc_hash32_load_hpte1(PowerP= CCPU *cpu, hwaddr pte_offset) { target_ulong base =3D ppc_hash32_hpt_base(cpu); - CPUPPCState *env =3D &cpu->env; =20 - assert(!env->external_htab); /* Not supported on 32-bit for now */ return ldl_phys(CPU(cpu)->as, base + pte_offset + HASH_PTE_SIZE_32 / 2= ); } =20 static inline void ppc_hash32_store_hpte0(PowerPCCPU *cpu, hwaddr pte_offset, target_ulong = pte0) { - CPUPPCState *env =3D &cpu->env; target_ulong base =3D ppc_hash32_hpt_base(cpu); =20 - assert(!env->external_htab); /* Not supported on 32-bit for now */ stl_phys(CPU(cpu)->as, base + pte_offset, pte0); } =20 static inline void ppc_hash32_store_hpte1(PowerPCCPU *cpu, hwaddr pte_offset, target_ulong = pte1) { - CPUPPCState *env =3D &cpu->env; target_ulong base =3D ppc_hash32_hpt_base(cpu); =20 - assert(!env->external_htab); /* Not supported on 32-bit for now */ stl_phys(CPU(cpu)->as, base + pte_offset + HASH_PTE_SIZE_32 / 2, pte1); } =20 diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index bb87777..ce96823 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -38,12 +38,6 @@ #endif =20 /* - * Used to indicate that a CPU has its hash page table (HPT) managed - * within the host kernel - */ -#define MMU_HASH64_KVM_MANAGED_HPT ((void *)-1) - -/* * SLB handling */ =20 @@ -313,31 +307,6 @@ void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong= value, env->spr[SPR_SDR1] =3D value; } =20 -void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int shift, - Error **errp) -{ - CPUPPCState *env =3D &cpu->env; - Error *local_err =3D NULL; - - if (hpt) { - env->external_htab =3D hpt; - } else { - env->external_htab =3D MMU_HASH64_KVM_MANAGED_HPT; - } - ppc_hash64_set_sdr1(cpu, (target_ulong)(uintptr_t)hpt | (shift - 18), - &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - - if (kvm_enabled()) { - if (kvmppc_put_books_sregs(cpu) < 0) { - error_setg(errp, "Unable to update SDR1 in KVM"); - } - } -} - static int ppc_hash64_pte_prot(PowerPCCPU *cpu, ppc_slb_t *slb, ppc_hash_pte64_t pte) { @@ -429,28 +398,24 @@ static int ppc_hash64_amr_prot(PowerPCCPU *cpu, ppc_h= ash_pte64_t pte) const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCCPU *cpu, hwaddr ptex, int n) { - const ppc_hash_pte64_t *hptes =3D NULL; hwaddr pte_offset =3D ptex * HASH_PTE_SIZE_64; + hwaddr base =3D ppc_hash64_hpt_base(cpu); + hwaddr plen =3D n * HASH_PTE_SIZE_64; + const ppc_hash_pte64_t *hptes; + + if (cpu->vhyp) { + PPCVirtualHypervisorClass *vhc =3D + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + return vhc->map_hptes(cpu->vhyp, ptex, n); + } =20 - if (cpu->env.external_htab =3D=3D MMU_HASH64_KVM_MANAGED_HPT) { - /* - * HTAB is controlled by KVM. Fetch the PTEG into a new buffer. - */ - hptes =3D kvmppc_map_hptes(ptex, n); - } else if (cpu->env.external_htab) { - /* - * HTAB is controlled by QEMU. Just point to the internally - * accessible PTEG. - */ - hptes =3D (const ppc_hash_pte64_t *)(cpu->env.external_htab + pte_= offset); - } else if (ppc_hash64_hpt_base(cpu)) { - hwaddr base =3D ppc_hash64_hpt_base(cpu); - hwaddr plen =3D n * HASH_PTE_SIZE_64; - hptes =3D address_space_map(CPU(cpu)->as, base + pte_offset, - &plen, false); - if (plen < (n * HASH_PTE_SIZE_64)) { - hw_error("%s: Unable to map all requested HPTEs\n", __FUNCTION= __); - } + if (!base) { + return NULL; + } + + hptes =3D address_space_map(CPU(cpu)->as, base + pte_offset, &plen, fa= lse); + if (plen < (n * HASH_PTE_SIZE_64)) { + hw_error("%s: Unable to map all requested HPTEs\n", __FUNCTION__); } return hptes; } @@ -458,12 +423,15 @@ const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCC= PU *cpu, void ppc_hash64_unmap_hptes(PowerPCCPU *cpu, const ppc_hash_pte64_t *hptes, hwaddr ptex, int n) { - if (cpu->env.external_htab =3D=3D MMU_HASH64_KVM_MANAGED_HPT) { - kvmppc_unmap_hptes(hptes, ptex, n); - } else if (!cpu->env.external_htab) { - address_space_unmap(CPU(cpu)->as, (void *)hptes, n * HASH_PTE_SIZE= _64, - false, n * HASH_PTE_SIZE_64); + if (cpu->vhyp) { + PPCVirtualHypervisorClass *vhc =3D + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + vhc->unmap_hptes(cpu->vhyp, hptes, ptex, n); + return; } + + address_space_unmap(CPU(cpu)->as, (void *)hptes, n * HASH_PTE_SIZE_64, + false, n * HASH_PTE_SIZE_64); } =20 static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps, @@ -915,22 +883,18 @@ hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu= , target_ulong addr) void ppc_hash64_store_hpte(PowerPCCPU *cpu, hwaddr ptex, uint64_t pte0, uint64_t pte1) { - CPUPPCState *env =3D &cpu->env; + hwaddr base =3D ppc_hash64_hpt_base(cpu); hwaddr offset =3D ptex * HASH_PTE_SIZE_64; =20 - if (env->external_htab =3D=3D MMU_HASH64_KVM_MANAGED_HPT) { - kvmppc_hash64_write_pte(ptex, pte0, pte1); + if (cpu->vhyp) { + PPCVirtualHypervisorClass *vhc =3D + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + vhc->store_hpte(cpu->vhyp, ptex, pte0, pte1); return; } =20 - if (env->external_htab) { - stq_p(env->external_htab + offset, pte0); - stq_p(env->external_htab + offset + HASH_PTE_SIZE_64 / 2, pte1); - } else { - hwaddr base =3D ppc_hash64_hpt_base(cpu); - stq_phys(CPU(cpu)->as, base + offset, pte0); - stq_phys(CPU(cpu)->as, base + offset + HASH_PTE_SIZE_64 / 2, pte1); - } + stq_phys(CPU(cpu)->as, base + offset, pte0); + stq_phys(CPU(cpu)->as, base + offset + HASH_PTE_SIZE_64 / 2, pte1); } =20 void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu, target_ulong ptex, diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h index dc0bc99..9c33e9d 100644 --- a/target/ppc/mmu-hash64.h +++ b/target/ppc/mmu-hash64.h @@ -101,13 +101,16 @@ static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *= cpu) =20 static inline hwaddr ppc_hash64_hpt_mask(PowerPCCPU *cpu) { + if (cpu->vhyp) { + PPCVirtualHypervisorClass *vhc =3D + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + return vhc->hpt_mask(cpu->vhyp); + } return (1ULL << ((cpu->env.spr[SPR_SDR1] & SDR_64_HTABSIZE) + 18 - 7))= - 1; } =20 void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong value, Error **errp); -void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int shift, - Error **errp); =20 struct ppc_hash_pte64 { uint64_t pte0, pte1; diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c index 1381635..0176ab6 100644 --- a/target/ppc/mmu_helper.c +++ b/target/ppc/mmu_helper.c @@ -2001,8 +2001,9 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_= ulong addr) /* Special registers manipulation */ void ppc_store_sdr1(CPUPPCState *env, target_ulong value) { + PowerPCCPU *cpu =3D ppc_env_get_cpu(env); qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value); - assert(!env->external_htab); + assert(!cpu->vhyp); #if defined(TARGET_PPC64) if (env->mmu_model & POWERPC_MMU_64) { PowerPCCPU *cpu =3D ppc_env_get_cpu(env); --=20 2.9.3