From nobody Sun Apr 28 08:59:10 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 1488172798731649.6412461151575; Sun, 26 Feb 2017 21:19:58 -0800 (PST) Received: from localhost ([::1]:50435 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDj3-0006aC-5R for importer@patchew.org; Mon, 27 Feb 2017 00:19:57 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35227) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDc9-0000hA-Ez for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ciDc6-0006k9-7m for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:49 -0500 Received: from ozlabs.org ([103.22.144.67]:59961) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ciDc5-0006ih-KX; Mon, 27 Feb 2017 00:12:46 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vWqbH1ylCz9sN9; Mon, 27 Feb 2017 16:12:42 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1488172363; bh=uHW6uq6szUnK0DQ+hebO9KEJR7kZT67ON74U6o3gK8U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KwoC5xBGyXYxtzrYvdHGFuJwsfkOLz3y9pGz11jIkuYSmaE2h+2//JEJ16i2+BYmL h94DQVwH5eIt06G24D+4+a9KipbIcVLHjJScI5iflr99wOIEb/80KkeNB7ow2SfAbc di64JVqAT4yGrJ+KEAe3GIhGo7FWylHMcI7eufo0= From: David Gibson To: qemu-ppc@nongnu.org, aik@ozlabs.ru, sjitindarsingh@gmail.com, aneesh.kumar@linux.vnet.ibm.com Date: Mon, 27 Feb 2017 16:12:31 +1100 Message-Id: <20170227051239.2680-2-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170227051239.2680-1-david@gibson.dropbear.id.au> References: <20170227051239.2680-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] [PATCHv2 1/9] target/ppc: Fix KVM-HV HPTE accessors 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, 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" When a 'pseries' guest is running with KVM-HV, the guest's hashed page table (HPT) is stored within the host kernel, so it is not directly accessible to qemu. Most of the time, qemu doesn't need to access it: we're using the hardware MMU, and KVM itself implements the guest hypercalls for manipulating the HPT. However, qemu does need access to the in-KVM HPT to implement get_phys_page_debug() for the benefit of the gdbstub, and maybe for other debug operations. To allow this, 7c43bca "target-ppc: Fix page table lookup with kvm enabled" added kvmppc_hash64_read_pteg() to target/ppc/kvm.c to read in a batch of HPTEs from the KVM table. Unfortunately, there are a couple of problems with this: First, the name of the function implies it always reads a whole PTEG from the HPT, but in fact in some cases it's used to grab individual HPTEs (which ends up pulling 8 HPTEs, not aligned to a PTEG from the kernel). Second, and more importantly, the code to read the HPTEs from KVM is simply wrong, in general. The data from the fd that KVM provides is designed mostly for compact migration rather than this sort of one-off access, and so needs some decoding for this purpose. The current code will work in some cases, but if there are invalid HPTEs then it will not get sane results. This patch rewrite the HPTE reading function to have a simpler interface (just read n HPTEs into a caller provided buffer), and to correctly decode the stream from the kernel. For consistency we also clean up the similar function for altering HPTEs within KVM (introduced in c138593 "target-ppc: Update ppc_hash64_store_hpte to support updating in-kernel htab"). Cc: Aneesh Kumar K.V Signed-off-by: David Gibson --- target/ppc/cpu.h | 1 + target/ppc/kvm.c | 126 +++++++++++++++++++++++---------------------= ---- target/ppc/kvm_ppc.h | 20 ++------ target/ppc/mmu-hash64.c | 8 +-- target/ppc/mmu-hash64.h | 2 +- 5 files changed, 73 insertions(+), 84 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index b559b67..c022984 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -228,6 +228,7 @@ 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..79c1da6 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -2596,89 +2596,85 @@ void kvm_arch_init_irq_routing(KVMState *s) { } =20 -struct kvm_get_htab_buf { - struct kvm_get_htab_header header; - /* - * We require one extra byte for read - */ - target_ulong hpte[(HPTES_PER_GROUP * 2) + 1]; -}; - -uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, target_ulong pte_index) +void kvmppc_read_hptes(ppc_hash_pte64_t *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_fd ghf =3D { + .flags =3D 0, + .start_index =3D ptex, + }; + int fd, rc; + int i; =20 - ghf.flags =3D 0; - ghf.start_index =3D pte_index; - htab_fd =3D kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf); - if (htab_fd < 0) { - goto error_out; + fd =3D kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf); + if (fd < 0) { + hw_error("kvmppc_read_hptes: Unable to open HPT fd"); } =20 - hpte_buf =3D g_malloc0(sizeof(*hpte_buf)); - /* - * Read the hpte group - */ - if (read(htab_fd, hpte_buf, sizeof(*hpte_buf)) < 0) { - goto out_close; - } + i =3D 0; + while (i < n) { + struct kvm_get_htab_header *hdr; + int m =3D n < HPTES_PER_GROUP ? n : HPTES_PER_GROUP; + char buf[sizeof(*hdr) + m * HASH_PTE_SIZE_64]; =20 - close(htab_fd); - return (uint64_t)(uintptr_t) hpte_buf->hpte; + rc =3D read(fd, buf, sizeof(buf)); + if (rc < 0) { + hw_error("kvmppc_read_hptes: Unable to read HPTEs"); + } =20 -out_close: - g_free(hpte_buf); - close(htab_fd); -error_out: - return 0; -} + hdr =3D (struct kvm_get_htab_header *)buf; + while ((i < n) && ((char *)hdr < (buf + rc))) { + int invalid =3D hdr->n_invalid; =20 -void kvmppc_hash64_free_pteg(uint64_t token) -{ - struct kvm_get_htab_buf *htab_buf; + if (hdr->index !=3D (ptex + i)) { + hw_error("kvmppc_read_hptes: Unexpected HPTE index %"PRIu32 + " !=3D (%"HWADDR_PRIu" + %d", hdr->index, ptex, i= ); + } + + memcpy(hptes + i, hdr + 1, HASH_PTE_SIZE_64 * hdr->n_valid); + i +=3D hdr->n_valid; =20 - htab_buf =3D container_of((void *)(uintptr_t) token, struct kvm_get_ht= ab_buf, - hpte); - g_free(htab_buf); - return; + if ((n - i) < invalid) { + invalid =3D n - i; + } + memset(hptes + i, 0, invalid * HASH_PTE_SIZE_64); + i +=3D hdr->n_invalid; + + hdr =3D (struct kvm_get_htab_header *) + ((char *)(hdr + 1) + HASH_PTE_SIZE_64 * hdr->n_valid); + } + } + + close(fd); } =20 -void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index, - target_ulong pte0, target_ulong pte1) +void kvmppc_write_hpte(hwaddr ptex, uint64_t pte0, uint64_t pte1) { - int htab_fd; + int fd, rc; struct kvm_get_htab_fd ghf; - struct kvm_get_htab_buf hpte_buf; + struct { + struct kvm_get_htab_header hdr; + uint64_t pte0; + uint64_t pte1; + } buf; =20 ghf.flags =3D 0; ghf.start_index =3D 0; /* Ignored */ - htab_fd =3D kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf); - if (htab_fd < 0) { - goto error_out; - } - - 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; - /* - * Write the hpte entry. - * CAUTION: write() has the warn_unused_result attribute. Hence we - * need to check the return value, even though we do nothing. - */ - if (write(htab_fd, &hpte_buf, sizeof(hpte_buf)) < 0) { - goto out_close; + fd =3D kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf); + if (fd < 0) { + hw_error("kvmppc_write_hpte: Unable to open HPT fd"); } =20 -out_close: - close(htab_fd); - return; + buf.hdr.n_valid =3D 1; + buf.hdr.n_invalid =3D 0; + buf.hdr.index =3D ptex; + buf.pte0 =3D cpu_to_be64(pte0); + buf.pte1 =3D cpu_to_be64(pte1); =20 -error_out: - return; + rc =3D write(fd, &buf, sizeof(buf)); + if (rc !=3D sizeof(buf)) { + hw_error("kvmppc_write_hpte: Unable to update KVM HPT"); + } + close(fd); } =20 int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index 8da2ee4..8e9f42d 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -49,11 +49,8 @@ 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); +void kvmppc_read_hptes(ppc_hash_pte64_t *hptes, hwaddr ptex, int n); +void kvmppc_write_hpte(hwaddr ptex, uint64_t pte0, uint64_t pte1); bool kvmppc_has_cap_fixup_hcalls(void); bool kvmppc_has_cap_htm(void); int kvmppc_enable_hwrng(void); @@ -234,20 +231,13 @@ 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) +static inline void kvmppc_read_hptes(ppc_hash_pte64_t *hptes, + hwaddr ptex, int n) { abort(); } =20 -static inline void kvmppc_hash64_write_pte(CPUPPCState *env, - target_ulong pte_index, - target_ulong pte0, target_ulong= pte1) +static inline void kvmppc_write_hpte(hwaddr ptex, uint64_t pte0, uint64_t = pte1) { abort(); } diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index 76669ed..862e50e 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -438,10 +438,12 @@ uint64_t ppc_hash64_start_access(PowerPCCPU *cpu, tar= get_ulong pte_index) =20 pte_offset =3D pte_index * HASH_PTE_SIZE_64; if (cpu->env.external_htab =3D=3D MMU_HASH64_KVM_MANAGED_HPT) { + ppc_hash_pte64_t *pteg =3D g_malloc(HASH_PTEG_SIZE_64); /* * HTAB is controlled by KVM. Fetch the PTEG into a new buffer. */ - token =3D kvmppc_hash64_read_pteg(cpu, pte_index); + kvmppc_read_hptes(pteg, pte_index, HPTES_PER_GROUP); + token =3D (uint64_t)(uintptr_t)pteg; } else if (cpu->env.external_htab) { /* * HTAB is controlled by QEMU. Just point to the internally @@ -457,7 +459,7 @@ uint64_t ppc_hash64_start_access(PowerPCCPU *cpu, targe= t_ulong pte_index) void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t token) { if (cpu->env.external_htab =3D=3D MMU_HASH64_KVM_MANAGED_HPT) { - kvmppc_hash64_free_pteg(token); + g_free((void *)token); } } =20 @@ -916,7 +918,7 @@ void ppc_hash64_store_hpte(PowerPCCPU *cpu, CPUPPCState *env =3D &cpu->env; =20 if (env->external_htab =3D=3D MMU_HASH64_KVM_MANAGED_HPT) { - kvmppc_hash64_write_pte(env, pte_index, pte0, pte1); + kvmppc_write_hpte(pte_index, pte0, pte1); return; } =20 diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h index 7a0b7fc..73aeaa3 100644 --- a/target/ppc/mmu-hash64.h +++ b/target/ppc/mmu-hash64.h @@ -127,7 +127,7 @@ static inline target_ulong ppc_hash64_load_hpte1(PowerP= CCPU *cpu, } } =20 -typedef struct { +typedef struct ppc_hash_pte64 { uint64_t pte0, pte1; } ppc_hash_pte64_t; =20 --=20 2.9.3 From nobody Sun Apr 28 08:59:10 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 1488172481472167.0275216668374; Sun, 26 Feb 2017 21:14:41 -0800 (PST) Received: from localhost ([::1]:50406 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDdw-0001sB-1s for importer@patchew.org; Mon, 27 Feb 2017 00:14:40 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35229) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDc9-0000hB-FF for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ciDc6-0006iv-5h for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:49 -0500 Received: from ozlabs.org ([103.22.144.67]:38383) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ciDc5-0006iX-IY; Mon, 27 Feb 2017 00:12:46 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vWqbH0S3qz9sN4; Mon, 27 Feb 2017 16:12:42 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1488172363; bh=Qfw5yAazRygQroGoxoGvCLav+AjOVCRh608jXU5kTmw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SlZ7PFOkfYsyZEbhSz4bOeQkiF/7bSGlbbg9ZtkhEZTPn4Jpq43Z7U35LGBefD5sN EaUbUmKIujDwIWJnsTNPiAMUwQITZCkQ9M9X9re09RMdzlcssmnS8vKZt+r7JOXols ryON54E0/aioWemTxgJOI8Unej391OkWJrNnTpcw= From: David Gibson To: qemu-ppc@nongnu.org, aik@ozlabs.ru, sjitindarsingh@gmail.com, aneesh.kumar@linux.vnet.ibm.com Date: Mon, 27 Feb 2017 16:12:32 +1100 Message-Id: <20170227051239.2680-3-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170227051239.2680-1-david@gibson.dropbear.id.au> References: <20170227051239.2680-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] [PATCHv2 2/9] 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, 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 Sun Apr 28 08:59:10 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 1488172500719778.8775394531773; Sun, 26 Feb 2017 21:15:00 -0800 (PST) Received: from localhost ([::1]:50408 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDeF-0002AR-EP for importer@patchew.org; Mon, 27 Feb 2017 00:14:59 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35225) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDc9-0000h9-EK for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ciDc6-0006k4-6l for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:49 -0500 Received: from ozlabs.org ([103.22.144.67]:58117) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ciDc5-0006ik-S5; Mon, 27 Feb 2017 00:12:46 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vWqbH4xlyz9sNF; Mon, 27 Feb 2017 16:12:43 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1488172363; bh=UxsNyehHepV4pHHIDC0h3dKkRtumsVc/hQYhoeE3KHE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lqLHutpMJRH+JwevVTjndYOZha0LUh0ho+HY14FgJegWXo7K7QTVy2LOhHFd1RhI8 EI2iBcnGFspnazMG/LG3UDGfZyXfuedApDZW5f6M8sl8SCly8r3SgtrwO954v1ORTB 77rdmfgfOHoUKS6Iyui7CCP60Lhi8vbg9mXS8wd8= From: David Gibson To: qemu-ppc@nongnu.org, aik@ozlabs.ru, sjitindarsingh@gmail.com, aneesh.kumar@linux.vnet.ibm.com Date: Mon, 27 Feb 2017 16:12:33 +1100 Message-Id: <20170227051239.2680-4-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170227051239.2680-1-david@gibson.dropbear.id.au> References: <20170227051239.2680-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] [PATCHv2 3/9] 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, 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 c022984..2a94e76 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1301,8 +1301,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 Sun Apr 28 08:59:10 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 1488172734706421.4568640062188; Sun, 26 Feb 2017 21:18:54 -0800 (PST) Received: from localhost ([::1]:50432 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDi1-0005gR-4X for importer@patchew.org; Mon, 27 Feb 2017 00:18:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35199) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDc8-0000gy-2R for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ciDc7-0006kX-1Y for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:48 -0500 Received: from ozlabs.org ([2401:3900:2:1::2]:58807) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ciDc6-0006il-K3; Mon, 27 Feb 2017 00:12:46 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vWqbH3rWRz9sN8; Mon, 27 Feb 2017 16:12:43 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1488172363; bh=9cASAEL+0zS6wCMn6Dc5tusVs2owSaRJ/SW/zzH0W5k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ok+j0J2PW6XscGiaLUmgMbh1W7oK9piAn9/4BU/k4IWAMI85VMCsxcPDkQjiBnFYx SNFjS6ChX+PrL9SKznVs96fDgvSKNRc6EEKBVohxoY//IXdq7UpivrKl+KpUX53tz5 9ryLYEraf/LAiIvBY+CYBst7+sk5/LU9FRuUp9/Y= From: David Gibson To: qemu-ppc@nongnu.org, aik@ozlabs.ru, sjitindarsingh@gmail.com, aneesh.kumar@linux.vnet.ibm.com Date: Mon, 27 Feb 2017 16:12:34 +1100 Message-Id: <20170227051239.2680-5-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170227051239.2680-1-david@gibson.dropbear.id.au> References: <20170227051239.2680-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] [PATCHv2 4/9] 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, 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 Sun Apr 28 08:59:10 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 1488172744063864.57911288923; Sun, 26 Feb 2017 21:19:04 -0800 (PST) Received: from localhost ([::1]:50434 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDiA-0005nh-J9 for importer@patchew.org; Mon, 27 Feb 2017 00:19:02 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35332) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDcF-0000mI-CJ for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ciDc9-0006lg-Na for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:52 -0500 Received: from ozlabs.org ([2401:3900:2:1::2]:48705) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ciDc9-0006kP-0g; Mon, 27 Feb 2017 00:12:49 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vWqbH5xPbz9sNC; Mon, 27 Feb 2017 16:12:43 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1488172363; bh=3Oxt8vAwXA0sIOiUBdpsD+OHi4Og2Bxslaa42gmKQbc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pzERn5T2wZ/JpxU03Y8QRccrlF0r/GsJOo+KZkThylnGuybGFJUmphI6YEUMuElNt hI1Boxwt6wTYOAe/5FNP0jcn/LVDE2aPe5SwDJsh7EZAtJ5RkEndwvDA45oiFCktAH eqm5OS3hgeiIiMy03vSPm4xOCyacWqva3pbH+Ik0= From: David Gibson To: qemu-ppc@nongnu.org, aik@ozlabs.ru, sjitindarsingh@gmail.com, aneesh.kumar@linux.vnet.ibm.com Date: Mon, 27 Feb 2017 16:12:35 +1100 Message-Id: <20170227051239.2680-6-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170227051239.2680-1-david@gibson.dropbear.id.au> References: <20170227051239.2680-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] [PATCHv2 5/9] 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, 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 or KVM-PR) 3) Within the host kernel - a pseries machine using KVM-HV 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 several HPTEs from the kernel as a batch (usually a whole PTEG). 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 map_hptes() and unmap_hptes() to make their operation more obvious. Second, map_hptes() 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 --- hw/ppc/spapr_hcall.c | 36 ++++++++--------- target/ppc/cpu.h | 2 +- target/ppc/mmu-hash64.c | 103 +++++++++++++++++++++++++-------------------= ---- target/ppc/mmu-hash64.h | 46 ++++++++------------- 4 files changed, 89 insertions(+), 98 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 2a94e76..051298b 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -223,7 +223,7 @@ 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; diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index 862e50e..f503c69 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,35 +432,43 @@ 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; + 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) { - ppc_hash_pte64_t *pteg =3D g_malloc(HASH_PTEG_SIZE_64); /* - * HTAB is controlled by KVM. Fetch the PTEG into a new buffer. + * HTAB is controlled by KVM. Fetch into temporary buffer */ - kvmppc_read_hptes(pteg, pte_index, HPTES_PER_GROUP); - token =3D (uint64_t)(uintptr_t)pteg; + hptes =3D g_malloc(HASH_PTEG_SIZE_64); + kvmppc_read_hptes(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", __func__); + } } - 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) { - g_free((void *)token); + g_free((void *)hptes); + } 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 @@ -507,18 +516,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)) { @@ -538,11 +547,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. */ @@ -554,8 +563,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 @@ -598,9 +606,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, @@ -609,10 +617,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, @@ -710,7 +718,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; @@ -794,8 +802,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); @@ -808,7 +816,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 @@ -851,8 +859,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 */ @@ -869,7 +876,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 @@ -902,8 +909,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 @@ -911,30 +918,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_write_hpte(pte_index, pte0, pte1); + kvmppc_write_hpte(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 73aeaa3..edd687b 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 ppc_hash_pte64 { - uint64_t pte0, pte1; -} ppc_hash_pte64_t; - #endif /* CONFIG_USER_ONLY */ =20 #endif /* MMU_HASH64_H */ --=20 2.9.3 From nobody Sun Apr 28 08:59:10 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 1488172969637676.5687731454448; Sun, 26 Feb 2017 21:22:49 -0800 (PST) Received: from localhost ([::1]:50454 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDlo-0000dQ-2d for importer@patchew.org; Mon, 27 Feb 2017 00:22:48 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35334) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDcF-0000mQ-He for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ciDc9-0006ls-TQ for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:52 -0500 Received: from ozlabs.org ([2401:3900:2:1::2]:54645) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ciDc9-0006kR-3p; Mon, 27 Feb 2017 00:12:49 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vWqbJ0LzNz9sNM; Mon, 27 Feb 2017 16:12:43 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1488172364; bh=bgp7ILU8AnLeQOfVisV0NuUbFv3I6xICwvaiZNyMDmI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=R4bFrHAGNjpKqxj4R5RfG5fdo/FRBLSEVJ0SntO0IWbScvLznM77NIjcDwaRkez38 Mc9Nka/ycjw1aD4zH4IR3YmzRx5b4QhXtwhAPq/A/wGyQBjP2/dc3CaT/PmbbBCmbY SBH8PbMAoJsqDRMOySqr9F8Ccg45qjZHJuFzkABQ= From: David Gibson To: qemu-ppc@nongnu.org, aik@ozlabs.ru, sjitindarsingh@gmail.com, aneesh.kumar@linux.vnet.ibm.com Date: Mon, 27 Feb 2017 16:12:36 +1100 Message-Id: <20170227051239.2680-7-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170227051239.2680-1-david@gibson.dropbear.id.au> References: <20170227051239.2680-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] [PATCHv2 6/9] 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, 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 | 11 ----------- target/ppc/machine.c | 1 - target/ppc/mmu-hash32.c | 14 +++++++------- target/ppc/mmu-hash32.h | 26 ++++++++++++++++++++------ target/ppc/mmu-hash64.c | 35 +++++++++++++++-------------------- target/ppc/mmu-hash64.h | 13 +++++++++++++ target/ppc/mmu_helper.c | 31 ++++++++++++++++--------------- 8 files changed, 73 insertions(+), 62 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 051298b..aaf79f5 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -306,14 +306,6 @@ union ppc_tlb_t { #define TLB_MAS 3 #endif =20 -#define SDR_32_HTABORG 0xFFFF0000UL -#define SDR_32_HTABMASK 0x000001FFUL - -#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 +998,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..2ed4888 100644 --- a/target/ppc/mmu-hash32.h +++ b/target/ppc/mmu-hash32.h @@ -44,6 +44,8 @@ int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr ad= dress, int rw, /* * Hash page table definitions */ +#define SDR_32_HTABORG 0xFFFF0000UL +#define SDR_32_HTABMASK 0x000001FFUL =20 #define HPTES_PER_GROUP 8 #define HASH_PTE_SIZE_32 8 @@ -65,42 +67,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 f503c69..38a6912 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"); @@ -450,10 +444,11 @@ const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCC= PU *cpu, * accessible PTEG. */ hptes =3D (ppc_hash_pte64_t *)(cpu->env.external_htab + pte_offset= ); - } else if (cpu->env.htab_base) { + } 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", __func__); } @@ -514,13 +509,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; @@ -598,14 +592,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) { @@ -614,8 +609,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= ); } @@ -933,9 +928,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 edd687b..5914a08 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 Sun Apr 28 08:59:10 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 1488173011905945.3684845988922; Sun, 26 Feb 2017 21:23:31 -0800 (PST) Received: from localhost ([::1]:50456 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDmU-0001CN-JO for importer@patchew.org; Mon, 27 Feb 2017 00:23:30 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35296) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDcB-0000j4-KQ for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ciDc8-0006l9-W9 for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:51 -0500 Received: from ozlabs.org ([103.22.144.67]:42663) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ciDc8-0006kL-Cg; Mon, 27 Feb 2017 00:12:48 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vWqbJ0sBKz9sNJ; Mon, 27 Feb 2017 16:12:43 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1488172364; bh=/QwdtXcBtADJW5LqSoHaprayIxrU/Qcllh79GkNDMhA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bSy1s9LNUz5HM1y2TQyCbaRv+JRoB9fLA7fLoLr2bg8G20Vgt4IeAQUeTSqwH5tHy T8PFE1wJ3qL2ba+KQTo9kw3Owarh531OPEbg7h5YFcrJtuevZa8gVZoBiZnBMtBTJY sG5GCe0xGT5nd64FY2k/6dpebAYHug/6Yo9Bp+rg= From: David Gibson To: qemu-ppc@nongnu.org, aik@ozlabs.ru, sjitindarsingh@gmail.com, aneesh.kumar@linux.vnet.ibm.com Date: Mon, 27 Feb 2017 16:12:37 +1100 Message-Id: <20170227051239.2680-8-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170227051239.2680-1-david@gibson.dropbear.id.au> References: <20170227051239.2680-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] [PATCHv2 7/9] 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, 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 | 60 ++++++++++++++++++++++++++++++ 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 | 99 ++++++++++++++++-----------------------------= ---- target/ppc/mmu-hash64.h | 7 +++- target/ppc/mmu_helper.c | 3 +- 10 files changed, 125 insertions(+), 88 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 0b57aad..e0bb9bc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1053,6 +1053,62 @@ 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 into temporary buffer + */ + ppc_hash_pte64_t *hptes =3D g_malloc(n * HASH_PTE_SIZE_64); + kvmppc_read_hptes(hptes, ptex, n); + return hptes; + } + + /* + * 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) { + g_free((void *)hptes); + } + + /* 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_write_hpte(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; @@ -2913,6 +2969,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 aaf79f5..4e7fc2c 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -999,8 +999,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]; @@ -1208,6 +1206,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 79c1da6..acc40ec 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 2ed4888..898021f 100644 --- a/target/ppc/mmu-hash32.h +++ b/target/ppc/mmu-hash32.h @@ -80,10 +80,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 @@ -91,29 +89,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 38a6912..8fe0e78 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,29 +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) { - 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 into temporary buffer - */ - hptes =3D g_malloc(HASH_PTEG_SIZE_64); - kvmppc_read_hptes(hptes, ptex, n); - } else if (cpu->env.external_htab) { - /* - * 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 (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", __func__); - } + 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", __func__); } return hptes; } @@ -459,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) { - g_free((void *)hptes); - } 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, @@ -916,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_write_hpte(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 5914a08..c8d3458 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 From nobody Sun Apr 28 08:59:10 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 1488172958852519.7577919466497; Sun, 26 Feb 2017 21:22:38 -0800 (PST) Received: from localhost ([::1]:50453 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDld-0000TK-F4 for importer@patchew.org; Mon, 27 Feb 2017 00:22:37 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35234) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDc9-0000hI-M9 for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ciDc8-0006kp-J1 for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:49 -0500 Received: from ozlabs.org ([103.22.144.67]:37569) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ciDc8-0006kJ-7C; Mon, 27 Feb 2017 00:12:48 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vWqbH6n7Cz9sNH; Mon, 27 Feb 2017 16:12:43 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1488172363; bh=DPdRpLCFXPYzeW8+rXS5CucvOgakdkzEZAbM6ppiX4E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JeHoLAFBam52J6C2p7tzY6pctSmPP8ggosgLJuqogs7bPHXF1rSUnrVRX4u6Ws/5H ALX/Criv5aoXgaWhrUWBcRCDMnCPrZnW5QIS3acLsQljrDkCQ3Q34bnNvx/4NF+1GK eMlgBupzcltRjtTOPW2nkM83ocWdnkGBF/8tHobU= From: David Gibson To: qemu-ppc@nongnu.org, aik@ozlabs.ru, sjitindarsingh@gmail.com, aneesh.kumar@linux.vnet.ibm.com Date: Mon, 27 Feb 2017 16:12:38 +1100 Message-Id: <20170227051239.2680-9-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170227051239.2680-1-david@gibson.dropbear.id.au> References: <20170227051239.2680-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] [PATCHv2 8/9] target/ppc: Remove the function ppc_hash64_set_sdr1() 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, 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" From: Suraj Jitindar Singh The function ppc_hash64_set_sdr1 basically checked the htabsize and set an error if it was too big, otherwise it just stored the value in SPR_SDR1. Given that the only function which calls ppc_hash64_set_sdr1() is ppc_store_sdr1(), why not handle the checking in ppc_store_sdr1() to avoid the extra function call. Note that ppc_store_sdr1() already stores the value in SPR_SDR1 anyway, so we were doing it twice. Signed-off-by: Suraj Jitindar Singh [dwg: Remove unnecessary error temporary] Signed-off-by: David Gibson --- target/ppc/mmu-hash64.c | 18 ------------------ target/ppc/mmu-hash64.h | 3 --- target/ppc/mmu_helper.c | 11 +++++------ 3 files changed, 5 insertions(+), 27 deletions(-) diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index 8fe0e78..d44f2bb 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -289,24 +289,6 @@ target_ulong helper_load_slb_vsid(CPUPPCState *env, ta= rget_ulong rb) return rt; } =20 -/* - * 64-bit hash table MMU handling - */ -void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong value, - Error **errp) -{ - CPUPPCState *env =3D &cpu->env; - target_ulong htabsize =3D value & SDR_64_HTABSIZE; - - if (htabsize > 28) { - error_setg(errp, - "Invalid HTABSIZE 0x" TARGET_FMT_lx" stored in SDR1", - htabsize); - return; - } - env->spr[SPR_SDR1] =3D value; -} - static int ppc_hash64_pte_prot(PowerPCCPU *cpu, ppc_slb_t *slb, ppc_hash_pte64_t pte) { diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h index c8d3458..9c74823 100644 --- a/target/ppc/mmu-hash64.h +++ b/target/ppc/mmu-hash64.h @@ -109,9 +109,6 @@ static inline hwaddr ppc_hash64_hpt_mask(PowerPCCPU *cp= u) 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); - struct ppc_hash_pte64 { uint64_t pte0, pte1; }; diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c index 0176ab6..3bc8030 100644 --- a/target/ppc/mmu_helper.c +++ b/target/ppc/mmu_helper.c @@ -28,6 +28,7 @@ #include "exec/cpu_ldst.h" #include "exec/log.h" #include "helper_regs.h" +#include "qemu/error-report.h" =20 //#define DEBUG_MMU //#define DEBUG_BATS @@ -2006,13 +2007,11 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong = value) assert(!cpu->vhyp); #if defined(TARGET_PPC64) if (env->mmu_model & POWERPC_MMU_64) { - PowerPCCPU *cpu =3D ppc_env_get_cpu(env); - Error *local_err =3D NULL; + target_ulong htabsize =3D value & SDR_64_HTABSIZE; =20 - ppc_hash64_set_sdr1(cpu, value, &local_err); - if (local_err) { - error_report_err(local_err); - error_free(local_err); + if (htabsize > 28) { + error_report("Invalid HTABSIZE 0x" TARGET_FMT_lx" stored in SD= R1", + htabsize); return; } } --=20 2.9.3 From nobody Sun Apr 28 08:59:10 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 1488172537145724.8978289130018; Sun, 26 Feb 2017 21:15:37 -0800 (PST) Received: from localhost ([::1]:50409 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDep-0002fH-VA for importer@patchew.org; Mon, 27 Feb 2017 00:15:36 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35244) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciDc9-0000hY-VH for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ciDc8-0006kw-Og for qemu-devel@nongnu.org; Mon, 27 Feb 2017 00:12:49 -0500 Received: from ozlabs.org ([103.22.144.67]:43479) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ciDc8-0006kN-DI; Mon, 27 Feb 2017 00:12:48 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vWqbJ1KxYz9sNL; Mon, 27 Feb 2017 16:12:43 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1488172364; bh=QSU2yHdywcm26Y/XlGsx89RWxvN8Bi6x+f/3qOp6Nds=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=B/jHN42PVTzYiPwm1Ry40iD/aVqMVIUeAPSS7KsXtDKfQdCD2al1gXpIbQF2tZznZ RKnenH8s62GSA0nUeKnmP8WBcfQvwdsO2JpG3TGJgILdOVD23MvrM3x8Ee8hAWZC2T GHE6ggPpSm429KaMEZ/7mN1doL+E+dDPzpoWUFYE= From: David Gibson To: qemu-ppc@nongnu.org, aik@ozlabs.ru, sjitindarsingh@gmail.com, aneesh.kumar@linux.vnet.ibm.com Date: Mon, 27 Feb 2017 16:12:39 +1100 Message-Id: <20170227051239.2680-10-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170227051239.2680-1-david@gibson.dropbear.id.au> References: <20170227051239.2680-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] [PATCHv2 9/9] target/ppc: Correct SDR1 masking 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, 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" SDR_64_HTABORG, which indicates the bits of the SDR1 register to use for the base of a 64-bit machine's hashed page table (HPT) isn't correct. It includes the top 46 bits of the register, but in fact the top 4 bits must be zero (according to the ISA v2.07). No actual implementation has supported close to 2^60 bytes of physical address space, so it's kind of irrelevant, but we might as well correct this. In addition, although we checked for bad size values in SDR1, we never reported an error if entirely invalid bits were set there. Add this check to ppc_store_sdr1(). Reported-by: Suraj Jitindar Singh Signed-off-by: David Gibson --- target/ppc/mmu-hash64.h | 2 +- target/ppc/mmu_helper.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h index 9c74823..54f1e37 100644 --- a/target/ppc/mmu-hash64.h +++ b/target/ppc/mmu-hash64.h @@ -56,7 +56,7 @@ void ppc_hash64_update_rmls(CPUPPCState *env); * Hash page table definitions */ =20 -#define SDR_64_HTABORG 0xFFFFFFFFFFFC0000ULL +#define SDR_64_HTABORG 0x0FFFFFFFFFFC0000ULL #define SDR_64_HTABSIZE 0x000000000000001FULL =20 #define HPTES_PER_GROUP 8 diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c index 3bc8030..a1af3d6 100644 --- a/target/ppc/mmu_helper.c +++ b/target/ppc/mmu_helper.c @@ -2007,8 +2007,14 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong v= alue) assert(!cpu->vhyp); #if defined(TARGET_PPC64) if (env->mmu_model & POWERPC_MMU_64) { + target_ulong sdr_mask =3D SDR_64_HTABORG | SDR_64_HTABSIZE; target_ulong htabsize =3D value & SDR_64_HTABSIZE; =20 + if (value & ~sdr_mask) { + error_report("Invalid bits 0x"TARGET_FMT_lx" set in SDR1", + value & ~sdr_mask); + value &=3D sdr_mask; + } if (htabsize > 28) { error_report("Invalid HTABSIZE 0x" TARGET_FMT_lx" stored in SD= R1", htabsize); --=20 2.9.3