From patchwork Thu Dec 12 12:55:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 13905153 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1A162213E70; Thu, 12 Dec 2024 12:56:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734008181; cv=none; b=BqxcH5IcqRGmaVaRfFCjq3bwscDQd+tWd1jDA0NwxLl1lzddPoh8OtQ9lC5zd9uG6XjC0wC50Uyd9AinLolD4KlYWCjblSGVm1ExlCjusd9Yrt5eoP8qvGMTXZc+dkXHb8xghJPa9lQeze6wmE7sM2coDvjdlDTqMr5pt/tMk60= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734008181; c=relaxed/simple; bh=efromQNaSZKwIG6IrPqB9gna+nBiIAeh+SsmLpAB8Q0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=b2q1w0TCNbzGb/3Nut+VTqMqDsf2PPDMD3WaKj2oHxiWM0FiyeM/UznCwf+Q1Pj23CY1wuqL++3JzhFjvva0/Qhtsg/Ja3Oyv118gbWh+MfJ9QJSk/hmh7gxSVliQrflul9HOIQ8kmtRNh2N9PvFn65cRVtzpp6MGK9LIwJD29c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MBEKFaSX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MBEKFaSX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0C74BC4CED0; Thu, 12 Dec 2024 12:56:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734008181; bh=efromQNaSZKwIG6IrPqB9gna+nBiIAeh+SsmLpAB8Q0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MBEKFaSXYbNmchylyDbjOrkVxfas/R0SkxnKHAqzHcoOku1uQ3dKVxMHJNyvIh0AC aEJ+PVYDWCJq7Jm1+SZE3dpXSlZUAgGjA1KGx+BbWMJGdL5oi4gudOjmNJPXAK/kdv 7HA3VxFgEy5O7iGVZOHuOCLgSQFZUCu7nWiSAuLJ+kpv2e1JIuyYxo1P/c/Ah0cY7v 13d0dJ7SK1j4OLiW8LRLhYPZ5aW8nzGO74iTTW6NoPVXao9UNDH3wSYfdzQIydyqch iTvKP2Ffqvb1TiH4iE/qjwHH+nnTNLdROIKekYfMADWh4CBQNSr65lB0OQEk5jqno8 6popEdMmWxHmg== From: Arnd Bergmann To: kvm@vger.kernel.org Cc: Arnd Bergmann , Thomas Bogendoerfer , Huacai Chen , Jiaxun Yang , Michael Ellerman , Nicholas Piggin , Christophe Leroy , Naveen N Rao , Madhavan Srinivasan , Alexander Graf , Crystal Wood , Anup Patel , Atish Patra , Paul Walmsley , Palmer Dabbelt , Albert Ou , Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Vitaly Kuznetsov , David Woodhouse , Paul Durrant , Marc Zyngier , linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org Subject: [RFC 2/5] powerpc: kvm: drop 32-bit booke Date: Thu, 12 Dec 2024 13:55:13 +0100 Message-Id: <20241212125516.467123-3-arnd@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241212125516.467123-1-arnd@kernel.org> References: <20241212125516.467123-1-arnd@kernel.org> Precedence: bulk X-Mailing-List: linux-mips@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Arnd Bergmann KVM on PowerPC BookE was introduced in 2008 and supported IBM 44x, Freescale e500v2 (32-bit mpc85xx, QuorIQ P1/P2), e500mc (32bit QorIQ P2/P3/P4), e5500 (64-bit QorIQ P5/T1) and e6500 (64-bit QorIQ T2/T4). Support for 44x was dropped in 2014 as it was seeing very little use, but e500v2 and e500mc are still supported as most of the code is shared with the 64-bit e5500/e6500 implementation. The last of those 32-bit chips were introduced in 2010 but not widely adopted when the following 64-bit PowerPC and Arm variants ended up being more successful. The 64-bit e5500/e6500 are still known to be used with KVM, but I could not find any evidence of continued use of the 32-bit ones, so drop discontinue those in order to simplify the implementation. The changes are purely mechanical, dropping all #ifdef checks for CONFIG_64BIT, CONFIG_KVM_E500V2, CONFIG_KVM_E500MC, CONFIG_KVM_BOOKE_HV, CONFIG_PPC_85xx, CONFIG_PPC_FPU, CONFIG_SPE and CONFIG_SPE_POSSIBLE, which are all known on e5500/e6500. Support for 64-bit hosts remains unchanged, for both 32-bit and 64-bit guests. Link: https://lore.kernel.org/lkml/Z1B1phcpbiYWLgCD@google.com/ Signed-off-by: Arnd Bergmann --- arch/powerpc/include/asm/kvm_book3s_32.h | 36 -- arch/powerpc/include/asm/kvm_booke.h | 4 - arch/powerpc/include/asm/kvm_booke_hv_asm.h | 2 - arch/powerpc/kvm/Kconfig | 22 +- arch/powerpc/kvm/Makefile | 15 - arch/powerpc/kvm/book3s_32_mmu_host.c | 396 -------------- arch/powerpc/kvm/booke.c | 268 ---------- arch/powerpc/kvm/booke.h | 8 - arch/powerpc/kvm/booke_emulate.c | 44 -- arch/powerpc/kvm/booke_interrupts.S | 535 ------------------- arch/powerpc/kvm/bookehv_interrupts.S | 102 ---- arch/powerpc/kvm/e500.c | 553 -------------------- arch/powerpc/kvm/e500.h | 40 -- arch/powerpc/kvm/e500_emulate.c | 100 ---- arch/powerpc/kvm/e500_mmu_host.c | 54 -- arch/powerpc/kvm/e500mc.c | 5 +- arch/powerpc/kvm/trace_booke.h | 14 - 17 files changed, 4 insertions(+), 2194 deletions(-) delete mode 100644 arch/powerpc/include/asm/kvm_book3s_32.h delete mode 100644 arch/powerpc/kvm/book3s_32_mmu_host.c delete mode 100644 arch/powerpc/kvm/booke_interrupts.S delete mode 100644 arch/powerpc/kvm/e500.c diff --git a/arch/powerpc/include/asm/kvm_book3s_32.h b/arch/powerpc/include/asm/kvm_book3s_32.h deleted file mode 100644 index e9d2e8463105..000000000000 --- a/arch/powerpc/include/asm/kvm_book3s_32.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * - * Copyright SUSE Linux Products GmbH 2010 - * - * Authors: Alexander Graf - */ - -#ifndef __ASM_KVM_BOOK3S_32_H__ -#define __ASM_KVM_BOOK3S_32_H__ - -static inline struct kvmppc_book3s_shadow_vcpu *svcpu_get(struct kvm_vcpu *vcpu) -{ - return vcpu->arch.shadow_vcpu; -} - -static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu) -{ -} - -#define PTE_SIZE 12 -#define VSID_ALL 0 -#define SR_INVALID 0x00000001 /* VSID 1 should always be unused */ -#define SR_KP 0x20000000 -#define PTE_V 0x80000000 -#define PTE_SEC 0x00000040 -#define PTE_M 0x00000010 -#define PTE_R 0x00000100 -#define PTE_C 0x00000080 - -#define SID_SHIFT 28 -#define ESID_MASK 0xf0000000 -#define VSID_MASK 0x00fffffff0000000ULL -#define VPN_SHIFT 12 - -#endif /* __ASM_KVM_BOOK3S_32_H__ */ diff --git a/arch/powerpc/include/asm/kvm_booke.h b/arch/powerpc/include/asm/kvm_booke.h index 7c3291aa8922..59349cb5a94c 100644 --- a/arch/powerpc/include/asm/kvm_booke.h +++ b/arch/powerpc/include/asm/kvm_booke.h @@ -109,10 +109,6 @@ static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) static inline bool kvmppc_supports_magic_page(struct kvm_vcpu *vcpu) { /* Magic page is only supported on e500v2 */ -#ifdef CONFIG_KVM_E500V2 - return true; -#else return false; -#endif } #endif /* __ASM_KVM_BOOKE_H__ */ diff --git a/arch/powerpc/include/asm/kvm_booke_hv_asm.h b/arch/powerpc/include/asm/kvm_booke_hv_asm.h index 7487ef582121..5bc10d113575 100644 --- a/arch/powerpc/include/asm/kvm_booke_hv_asm.h +++ b/arch/powerpc/include/asm/kvm_booke_hv_asm.h @@ -54,14 +54,12 @@ * Only the bolted version of TLB miss exception handlers is supported now. */ .macro DO_KVM intno srr1 -#ifdef CONFIG_KVM_BOOKE_HV BEGIN_FTR_SECTION mtocrf 0x80, r11 /* check MSR[GS] without clobbering reg */ bf 3, 1975f b kvmppc_handler_\intno\()_\srr1 1975: END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV) -#endif .endm #endif /*__ASSEMBLY__ */ diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index dbfdc126bf14..e2230ea512cf 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -185,25 +185,9 @@ config KVM_EXIT_TIMING If unsure, say N. -config KVM_E500V2 - bool "KVM support for PowerPC E500v2 processors" - depends on PPC_E500 && !PPC_E500MC - depends on !CONTEXT_TRACKING_USER - select KVM - select KVM_MMIO - select KVM_GENERIC_MMU_NOTIFIER - help - Support running unmodified E500 guest kernels in virtual machines on - E500v2 host processors. - - This module provides access to the hardware capabilities through - a character device node named /dev/kvm. - - If unsure, say N. - config KVM_E500MC - bool "KVM support for PowerPC E500MC/E5500/E6500 processors" - depends on PPC_E500MC + bool "KVM support for PowerPC E5500/E6500 processors" + depends on PPC_E500MC && 64BIT depends on !CONTEXT_TRACKING_USER select KVM select KVM_MMIO @@ -211,7 +195,7 @@ config KVM_E500MC select KVM_GENERIC_MMU_NOTIFIER help Support running unmodified E500MC/E5500/E6500 guest kernels in - virtual machines on E500MC/E5500/E6500 host processors. + virtual machines on E5500/E6500 host processors. This module provides access to the hardware capabilities through a character device node named /dev/kvm. diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 4bd9d1230869..294f27439f7f 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -11,20 +11,6 @@ common-objs-y += powerpc.o emulate_loadstore.o obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o obj-$(CONFIG_KVM_BOOK3S_HANDLER) += book3s_exports.o -AFLAGS_booke_interrupts.o := -I$(objtree)/$(obj) - -kvm-e500-objs := \ - $(common-objs-y) \ - emulate.o \ - booke.o \ - booke_emulate.o \ - booke_interrupts.o \ - e500.o \ - e500_mmu.o \ - e500_mmu_host.o \ - e500_emulate.o -kvm-objs-$(CONFIG_KVM_E500V2) := $(kvm-e500-objs) - kvm-e500mc-objs := \ $(common-objs-y) \ emulate.o \ @@ -127,7 +113,6 @@ kvm-objs-$(CONFIG_KVM_MPIC) += mpic.o kvm-y += $(kvm-objs-m) $(kvm-objs-y) -obj-$(CONFIG_KVM_E500V2) += kvm.o obj-$(CONFIG_KVM_E500MC) += kvm.o obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o obj-$(CONFIG_KVM_BOOK3S_32) += kvm.o diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c deleted file mode 100644 index 5b7212edbb13..000000000000 --- a/arch/powerpc/kvm/book3s_32_mmu_host.c +++ /dev/null @@ -1,396 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 SUSE Linux Products GmbH. All rights reserved. - * - * Authors: - * Alexander Graf - */ - -#include - -#include -#include -#include -#include -#include -#include -#include "book3s.h" - -/* #define DEBUG_MMU */ -/* #define DEBUG_SR */ - -#ifdef DEBUG_MMU -#define dprintk_mmu(a, ...) printk(KERN_INFO a, __VA_ARGS__) -#else -#define dprintk_mmu(a, ...) do { } while(0) -#endif - -#ifdef DEBUG_SR -#define dprintk_sr(a, ...) printk(KERN_INFO a, __VA_ARGS__) -#else -#define dprintk_sr(a, ...) do { } while(0) -#endif - -#if PAGE_SHIFT != 12 -#error Unknown page size -#endif - -#ifdef CONFIG_SMP -#error XXX need to grab mmu_hash_lock -#endif - -#ifdef CONFIG_PTE_64BIT -#error Only 32 bit pages are supported for now -#endif - -static ulong htab; -static u32 htabmask; - -void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte) -{ - volatile u32 *pteg; - - /* Remove from host HTAB */ - pteg = (u32*)pte->slot; - pteg[0] = 0; - - /* And make sure it's gone from the TLB too */ - asm volatile ("sync"); - asm volatile ("tlbie %0" : : "r" (pte->pte.eaddr) : "memory"); - asm volatile ("sync"); - asm volatile ("tlbsync"); -} - -/* We keep 512 gvsid->hvsid entries, mapping the guest ones to the array using - * a hash, so we don't waste cycles on looping */ -static u16 kvmppc_sid_hash(struct kvm_vcpu *vcpu, u64 gvsid) -{ - return (u16)(((gvsid >> (SID_MAP_BITS * 7)) & SID_MAP_MASK) ^ - ((gvsid >> (SID_MAP_BITS * 6)) & SID_MAP_MASK) ^ - ((gvsid >> (SID_MAP_BITS * 5)) & SID_MAP_MASK) ^ - ((gvsid >> (SID_MAP_BITS * 4)) & SID_MAP_MASK) ^ - ((gvsid >> (SID_MAP_BITS * 3)) & SID_MAP_MASK) ^ - ((gvsid >> (SID_MAP_BITS * 2)) & SID_MAP_MASK) ^ - ((gvsid >> (SID_MAP_BITS * 1)) & SID_MAP_MASK) ^ - ((gvsid >> (SID_MAP_BITS * 0)) & SID_MAP_MASK)); -} - - -static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid) -{ - struct kvmppc_sid_map *map; - u16 sid_map_mask; - - if (kvmppc_get_msr(vcpu) & MSR_PR) - gvsid |= VSID_PR; - - sid_map_mask = kvmppc_sid_hash(vcpu, gvsid); - map = &to_book3s(vcpu)->sid_map[sid_map_mask]; - if (map->guest_vsid == gvsid) { - dprintk_sr("SR: Searching 0x%llx -> 0x%llx\n", - gvsid, map->host_vsid); - return map; - } - - map = &to_book3s(vcpu)->sid_map[SID_MAP_MASK - sid_map_mask]; - if (map->guest_vsid == gvsid) { - dprintk_sr("SR: Searching 0x%llx -> 0x%llx\n", - gvsid, map->host_vsid); - return map; - } - - dprintk_sr("SR: Searching 0x%llx -> not found\n", gvsid); - return NULL; -} - -static u32 *kvmppc_mmu_get_pteg(struct kvm_vcpu *vcpu, u32 vsid, u32 eaddr, - bool primary) -{ - u32 page, hash; - ulong pteg = htab; - - page = (eaddr & ~ESID_MASK) >> 12; - - hash = ((vsid ^ page) << 6); - if (!primary) - hash = ~hash; - - hash &= htabmask; - - pteg |= hash; - - dprintk_mmu("htab: %lx | hash: %x | htabmask: %x | pteg: %lx\n", - htab, hash, htabmask, pteg); - - return (u32*)pteg; -} - -extern char etext[]; - -int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte, - bool iswrite) -{ - struct page *page; - kvm_pfn_t hpaddr; - u64 vpn; - u64 vsid; - struct kvmppc_sid_map *map; - volatile u32 *pteg; - u32 eaddr = orig_pte->eaddr; - u32 pteg0, pteg1; - register int rr = 0; - bool primary = false; - bool evict = false; - struct hpte_cache *pte; - int r = 0; - bool writable; - - /* Get host physical address for gpa */ - hpaddr = kvmppc_gpa_to_pfn(vcpu, orig_pte->raddr, iswrite, &writable, &page); - if (is_error_noslot_pfn(hpaddr)) { - printk(KERN_INFO "Couldn't get guest page for gpa %lx!\n", - orig_pte->raddr); - r = -EINVAL; - goto out; - } - hpaddr <<= PAGE_SHIFT; - - /* and write the mapping ea -> hpa into the pt */ - vcpu->arch.mmu.esid_to_vsid(vcpu, orig_pte->eaddr >> SID_SHIFT, &vsid); - map = find_sid_vsid(vcpu, vsid); - if (!map) { - kvmppc_mmu_map_segment(vcpu, eaddr); - map = find_sid_vsid(vcpu, vsid); - } - BUG_ON(!map); - - vsid = map->host_vsid; - vpn = (vsid << (SID_SHIFT - VPN_SHIFT)) | - ((eaddr & ~ESID_MASK) >> VPN_SHIFT); -next_pteg: - if (rr == 16) { - primary = !primary; - evict = true; - rr = 0; - } - - pteg = kvmppc_mmu_get_pteg(vcpu, vsid, eaddr, primary); - - /* not evicting yet */ - if (!evict && (pteg[rr] & PTE_V)) { - rr += 2; - goto next_pteg; - } - - dprintk_mmu("KVM: old PTEG: %p (%d)\n", pteg, rr); - dprintk_mmu("KVM: %08x - %08x\n", pteg[0], pteg[1]); - dprintk_mmu("KVM: %08x - %08x\n", pteg[2], pteg[3]); - dprintk_mmu("KVM: %08x - %08x\n", pteg[4], pteg[5]); - dprintk_mmu("KVM: %08x - %08x\n", pteg[6], pteg[7]); - dprintk_mmu("KVM: %08x - %08x\n", pteg[8], pteg[9]); - dprintk_mmu("KVM: %08x - %08x\n", pteg[10], pteg[11]); - dprintk_mmu("KVM: %08x - %08x\n", pteg[12], pteg[13]); - dprintk_mmu("KVM: %08x - %08x\n", pteg[14], pteg[15]); - - pteg0 = ((eaddr & 0x0fffffff) >> 22) | (vsid << 7) | PTE_V | - (primary ? 0 : PTE_SEC); - pteg1 = hpaddr | PTE_M | PTE_R | PTE_C; - - if (orig_pte->may_write && writable) { - pteg1 |= PP_RWRW; - mark_page_dirty(vcpu->kvm, orig_pte->raddr >> PAGE_SHIFT); - } else { - pteg1 |= PP_RWRX; - } - - if (orig_pte->may_execute) - kvmppc_mmu_flush_icache(hpaddr >> PAGE_SHIFT); - - local_irq_disable(); - - if (pteg[rr]) { - pteg[rr] = 0; - asm volatile ("sync"); - } - pteg[rr + 1] = pteg1; - pteg[rr] = pteg0; - asm volatile ("sync"); - - local_irq_enable(); - - dprintk_mmu("KVM: new PTEG: %p\n", pteg); - dprintk_mmu("KVM: %08x - %08x\n", pteg[0], pteg[1]); - dprintk_mmu("KVM: %08x - %08x\n", pteg[2], pteg[3]); - dprintk_mmu("KVM: %08x - %08x\n", pteg[4], pteg[5]); - dprintk_mmu("KVM: %08x - %08x\n", pteg[6], pteg[7]); - dprintk_mmu("KVM: %08x - %08x\n", pteg[8], pteg[9]); - dprintk_mmu("KVM: %08x - %08x\n", pteg[10], pteg[11]); - dprintk_mmu("KVM: %08x - %08x\n", pteg[12], pteg[13]); - dprintk_mmu("KVM: %08x - %08x\n", pteg[14], pteg[15]); - - - /* Now tell our Shadow PTE code about the new page */ - - pte = kvmppc_mmu_hpte_cache_next(vcpu); - if (!pte) { - kvm_release_page_unused(page); - r = -EAGAIN; - goto out; - } - - dprintk_mmu("KVM: %c%c Map 0x%llx: [%lx] 0x%llx (0x%llx) -> %lx\n", - orig_pte->may_write ? 'w' : '-', - orig_pte->may_execute ? 'x' : '-', - orig_pte->eaddr, (ulong)pteg, vpn, - orig_pte->vpage, hpaddr); - - pte->slot = (ulong)&pteg[rr]; - pte->host_vpn = vpn; - pte->pte = *orig_pte; - pte->pfn = hpaddr >> PAGE_SHIFT; - - kvmppc_mmu_hpte_cache_map(vcpu, pte); - - kvm_release_page_clean(page); -out: - return r; -} - -void kvmppc_mmu_unmap_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte) -{ - kvmppc_mmu_pte_vflush(vcpu, pte->vpage, 0xfffffffffULL); -} - -static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid) -{ - struct kvmppc_sid_map *map; - struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); - u16 sid_map_mask; - static int backwards_map = 0; - - if (kvmppc_get_msr(vcpu) & MSR_PR) - gvsid |= VSID_PR; - - /* We might get collisions that trap in preceding order, so let's - map them differently */ - - sid_map_mask = kvmppc_sid_hash(vcpu, gvsid); - if (backwards_map) - sid_map_mask = SID_MAP_MASK - sid_map_mask; - - map = &to_book3s(vcpu)->sid_map[sid_map_mask]; - - /* Make sure we're taking the other map next time */ - backwards_map = !backwards_map; - - /* Uh-oh ... out of mappings. Let's flush! */ - if (vcpu_book3s->vsid_next >= VSID_POOL_SIZE) { - vcpu_book3s->vsid_next = 0; - memset(vcpu_book3s->sid_map, 0, - sizeof(struct kvmppc_sid_map) * SID_MAP_NUM); - kvmppc_mmu_pte_flush(vcpu, 0, 0); - kvmppc_mmu_flush_segments(vcpu); - } - map->host_vsid = vcpu_book3s->vsid_pool[vcpu_book3s->vsid_next]; - vcpu_book3s->vsid_next++; - - map->guest_vsid = gvsid; - map->valid = true; - - return map; -} - -int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr) -{ - u32 esid = eaddr >> SID_SHIFT; - u64 gvsid; - u32 sr; - struct kvmppc_sid_map *map; - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - int r = 0; - - if (vcpu->arch.mmu.esid_to_vsid(vcpu, esid, &gvsid)) { - /* Invalidate an entry */ - svcpu->sr[esid] = SR_INVALID; - r = -ENOENT; - goto out; - } - - map = find_sid_vsid(vcpu, gvsid); - if (!map) - map = create_sid_map(vcpu, gvsid); - - map->guest_esid = esid; - sr = map->host_vsid | SR_KP; - svcpu->sr[esid] = sr; - - dprintk_sr("MMU: mtsr %d, 0x%x\n", esid, sr); - -out: - svcpu_put(svcpu); - return r; -} - -void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu) -{ - int i; - struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); - - dprintk_sr("MMU: flushing all segments (%d)\n", ARRAY_SIZE(svcpu->sr)); - for (i = 0; i < ARRAY_SIZE(svcpu->sr); i++) - svcpu->sr[i] = SR_INVALID; - - svcpu_put(svcpu); -} - -void kvmppc_mmu_destroy_pr(struct kvm_vcpu *vcpu) -{ - int i; - - kvmppc_mmu_hpte_destroy(vcpu); - preempt_disable(); - for (i = 0; i < SID_CONTEXTS; i++) - __destroy_context(to_book3s(vcpu)->context_id[i]); - preempt_enable(); -} - -int kvmppc_mmu_init_pr(struct kvm_vcpu *vcpu) -{ - struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); - int err; - ulong sdr1; - int i; - int j; - - for (i = 0; i < SID_CONTEXTS; i++) { - err = __init_new_context(); - if (err < 0) - goto init_fail; - vcpu3s->context_id[i] = err; - - /* Remember context id for this combination */ - for (j = 0; j < 16; j++) - vcpu3s->vsid_pool[(i * 16) + j] = CTX_TO_VSID(err, j); - } - - vcpu3s->vsid_next = 0; - - /* Remember where the HTAB is */ - asm ( "mfsdr1 %0" : "=r"(sdr1) ); - htabmask = ((sdr1 & 0x1FF) << 16) | 0xFFC0; - htab = (ulong)__va(sdr1 & 0xffff0000); - - kvmppc_mmu_hpte_init(vcpu); - - return 0; - -init_fail: - for (j = 0; j < i; j++) { - if (!vcpu3s->context_id[j]) - continue; - - __destroy_context(to_book3s(vcpu)->context_id[j]); - } - - return -1; -} diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 6a5be025a8af..1e3a7e0456b9 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -34,8 +34,6 @@ #define CREATE_TRACE_POINTS #include "trace_booke.h" -unsigned long kvmppc_booke_handlers; - const struct _kvm_stats_desc kvm_vm_stats_desc[] = { KVM_GENERIC_VM_STATS(), STATS_DESC_ICOUNTER(VM, num_2M_pages), @@ -109,42 +107,6 @@ void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu) } } -#ifdef CONFIG_SPE -void kvmppc_vcpu_disable_spe(struct kvm_vcpu *vcpu) -{ - preempt_disable(); - enable_kernel_spe(); - kvmppc_save_guest_spe(vcpu); - disable_kernel_spe(); - vcpu->arch.shadow_msr &= ~MSR_SPE; - preempt_enable(); -} - -static void kvmppc_vcpu_enable_spe(struct kvm_vcpu *vcpu) -{ - preempt_disable(); - enable_kernel_spe(); - kvmppc_load_guest_spe(vcpu); - disable_kernel_spe(); - vcpu->arch.shadow_msr |= MSR_SPE; - preempt_enable(); -} - -static void kvmppc_vcpu_sync_spe(struct kvm_vcpu *vcpu) -{ - if (vcpu->arch.shared->msr & MSR_SPE) { - if (!(vcpu->arch.shadow_msr & MSR_SPE)) - kvmppc_vcpu_enable_spe(vcpu); - } else if (vcpu->arch.shadow_msr & MSR_SPE) { - kvmppc_vcpu_disable_spe(vcpu); - } -} -#else -static void kvmppc_vcpu_sync_spe(struct kvm_vcpu *vcpu) -{ -} -#endif - /* * Load up guest vcpu FP state if it's needed. * It also set the MSR_FP in thread so that host know @@ -156,7 +118,6 @@ static void kvmppc_vcpu_sync_spe(struct kvm_vcpu *vcpu) */ static inline void kvmppc_load_guest_fp(struct kvm_vcpu *vcpu) { -#ifdef CONFIG_PPC_FPU if (!(current->thread.regs->msr & MSR_FP)) { enable_kernel_fp(); load_fp_state(&vcpu->arch.fp); @@ -164,7 +125,6 @@ static inline void kvmppc_load_guest_fp(struct kvm_vcpu *vcpu) current->thread.fp_save_area = &vcpu->arch.fp; current->thread.regs->msr |= MSR_FP; } -#endif } /* @@ -173,21 +133,9 @@ static inline void kvmppc_load_guest_fp(struct kvm_vcpu *vcpu) */ static inline void kvmppc_save_guest_fp(struct kvm_vcpu *vcpu) { -#ifdef CONFIG_PPC_FPU if (current->thread.regs->msr & MSR_FP) giveup_fpu(current); current->thread.fp_save_area = NULL; -#endif -} - -static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu *vcpu) -{ -#if defined(CONFIG_PPC_FPU) && !defined(CONFIG_KVM_BOOKE_HV) - /* We always treat the FP bit as enabled from the host - perspective, so only need to adjust the shadow MSR */ - vcpu->arch.shadow_msr &= ~MSR_FP; - vcpu->arch.shadow_msr |= vcpu->arch.shared->msr & MSR_FP; -#endif } /* @@ -228,23 +176,16 @@ static inline void kvmppc_save_guest_altivec(struct kvm_vcpu *vcpu) static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu) { /* Synchronize guest's desire to get debug interrupts into shadow MSR */ -#ifndef CONFIG_KVM_BOOKE_HV vcpu->arch.shadow_msr &= ~MSR_DE; vcpu->arch.shadow_msr |= vcpu->arch.shared->msr & MSR_DE; -#endif /* Force enable debug interrupts when user space wants to debug */ if (vcpu->guest_debug) { -#ifdef CONFIG_KVM_BOOKE_HV /* * Since there is no shadow MSR, sync MSR_DE into the guest * visible MSR. */ vcpu->arch.shared->msr |= MSR_DE; -#else - vcpu->arch.shadow_msr |= MSR_DE; - vcpu->arch.shared->msr &= ~MSR_DE; -#endif } } @@ -256,15 +197,11 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr) { u32 old_msr = vcpu->arch.shared->msr; -#ifdef CONFIG_KVM_BOOKE_HV new_msr |= MSR_GS; -#endif vcpu->arch.shared->msr = new_msr; kvmppc_mmu_msr_notify(vcpu, old_msr); - kvmppc_vcpu_sync_spe(vcpu); - kvmppc_vcpu_sync_fpu(vcpu); kvmppc_vcpu_sync_debug(vcpu); } @@ -457,11 +394,6 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, case BOOKE_IRQPRIO_ITLB_MISS: case BOOKE_IRQPRIO_SYSCALL: case BOOKE_IRQPRIO_FP_UNAVAIL: -#ifdef CONFIG_SPE_POSSIBLE - case BOOKE_IRQPRIO_SPE_UNAVAIL: - case BOOKE_IRQPRIO_SPE_FP_DATA: - case BOOKE_IRQPRIO_SPE_FP_ROUND: -#endif #ifdef CONFIG_ALTIVEC case BOOKE_IRQPRIO_ALTIVEC_UNAVAIL: case BOOKE_IRQPRIO_ALTIVEC_ASSIST: @@ -543,17 +475,14 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, } new_msr &= msr_mask; -#if defined(CONFIG_64BIT) if (vcpu->arch.epcr & SPRN_EPCR_ICM) new_msr |= MSR_CM; -#endif kvmppc_set_msr(vcpu, new_msr); if (!keep_irq) clear_bit(priority, &vcpu->arch.pending_exceptions); } -#ifdef CONFIG_KVM_BOOKE_HV /* * If an interrupt is pending but masked, raise a guest doorbell * so that we are notified when the guest enables the relevant @@ -565,7 +494,6 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, kvmppc_set_pending_interrupt(vcpu, INT_CLASS_CRIT); if (vcpu->arch.pending_exceptions & BOOKE_IRQPRIO_MACHINE_CHECK) kvmppc_set_pending_interrupt(vcpu, INT_CLASS_MC); -#endif return allowed; } @@ -737,10 +665,8 @@ int kvmppc_core_check_requests(struct kvm_vcpu *vcpu) if (kvm_check_request(KVM_REQ_PENDING_TIMER, vcpu)) update_timer_ints(vcpu); -#if defined(CONFIG_KVM_E500V2) || defined(CONFIG_KVM_E500MC) if (kvm_check_request(KVM_REQ_TLB_FLUSH, vcpu)) kvmppc_core_flush_tlb(vcpu); -#endif if (kvm_check_request(KVM_REQ_WATCHDOG, vcpu)) { vcpu->run->exit_reason = KVM_EXIT_WATCHDOG; @@ -774,7 +700,6 @@ int kvmppc_vcpu_run(struct kvm_vcpu *vcpu) } /* interrupts now hard-disabled */ -#ifdef CONFIG_PPC_FPU /* Save userspace FPU state in stack */ enable_kernel_fp(); @@ -783,7 +708,6 @@ int kvmppc_vcpu_run(struct kvm_vcpu *vcpu) * as always using the FPU. */ kvmppc_load_guest_fp(vcpu); -#endif #ifdef CONFIG_ALTIVEC /* Save userspace AltiVec state in stack */ @@ -814,9 +738,7 @@ int kvmppc_vcpu_run(struct kvm_vcpu *vcpu) switch_booke_debug_regs(&debug); current->thread.debug = debug; -#ifdef CONFIG_PPC_FPU kvmppc_save_guest_fp(vcpu); -#endif #ifdef CONFIG_ALTIVEC kvmppc_save_guest_altivec(vcpu); @@ -948,12 +870,10 @@ static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu, kvmppc_fill_pt_regs(®s); timer_interrupt(®s); break; -#if defined(CONFIG_PPC_DOORBELL) case BOOKE_INTERRUPT_DOORBELL: kvmppc_fill_pt_regs(®s); doorbell_exception(®s); break; -#endif case BOOKE_INTERRUPT_MACHINE_CHECK: /* FIXME */ break; @@ -1172,49 +1092,6 @@ int kvmppc_handle_exit(struct kvm_vcpu *vcpu, unsigned int exit_nr) r = RESUME_GUEST; break; -#ifdef CONFIG_SPE - case BOOKE_INTERRUPT_SPE_UNAVAIL: { - if (vcpu->arch.shared->msr & MSR_SPE) - kvmppc_vcpu_enable_spe(vcpu); - else - kvmppc_booke_queue_irqprio(vcpu, - BOOKE_IRQPRIO_SPE_UNAVAIL); - r = RESUME_GUEST; - break; - } - - case BOOKE_INTERRUPT_SPE_FP_DATA: - kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_DATA); - r = RESUME_GUEST; - break; - - case BOOKE_INTERRUPT_SPE_FP_ROUND: - kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_ROUND); - r = RESUME_GUEST; - break; -#elif defined(CONFIG_SPE_POSSIBLE) - case BOOKE_INTERRUPT_SPE_UNAVAIL: - /* - * Guest wants SPE, but host kernel doesn't support it. Send - * an "unimplemented operation" program check to the guest. - */ - kvmppc_core_queue_program(vcpu, ESR_PUO | ESR_SPV); - r = RESUME_GUEST; - break; - - /* - * These really should never happen without CONFIG_SPE, - * as we should never enable the real MSR[SPE] in the guest. - */ - case BOOKE_INTERRUPT_SPE_FP_DATA: - case BOOKE_INTERRUPT_SPE_FP_ROUND: - printk(KERN_CRIT "%s: unexpected SPE interrupt %u at %08lx\n", - __func__, exit_nr, vcpu->arch.regs.nip); - run->hw.hardware_exit_reason = exit_nr; - r = RESUME_HOST; - break; -#endif /* CONFIG_SPE_POSSIBLE */ - /* * On cores with Vector category, KVM is loaded only if CONFIG_ALTIVEC, * see kvmppc_e500mc_check_processor_compat(). @@ -1250,7 +1127,6 @@ int kvmppc_handle_exit(struct kvm_vcpu *vcpu, unsigned int exit_nr) r = RESUME_GUEST; break; -#ifdef CONFIG_KVM_BOOKE_HV case BOOKE_INTERRUPT_HV_SYSCALL: if (!(vcpu->arch.shared->msr & MSR_PR)) { kvmppc_set_gpr(vcpu, 3, kvmppc_kvm_pv(vcpu)); @@ -1264,21 +1140,6 @@ int kvmppc_handle_exit(struct kvm_vcpu *vcpu, unsigned int exit_nr) r = RESUME_GUEST; break; -#else - case BOOKE_INTERRUPT_SYSCALL: - if (!(vcpu->arch.shared->msr & MSR_PR) && - (((u32)kvmppc_get_gpr(vcpu, 0)) == KVM_SC_MAGIC_R0)) { - /* KVM PV hypercalls */ - kvmppc_set_gpr(vcpu, 3, kvmppc_kvm_pv(vcpu)); - r = RESUME_GUEST; - } else { - /* Guest syscalls */ - kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SYSCALL); - } - kvmppc_account_exit(vcpu, SYSCALL_EXITS); - r = RESUME_GUEST; - break; -#endif case BOOKE_INTERRUPT_DTLB_MISS: { unsigned long eaddr = vcpu->arch.fault_dear; @@ -1286,17 +1147,6 @@ int kvmppc_handle_exit(struct kvm_vcpu *vcpu, unsigned int exit_nr) gpa_t gpaddr; gfn_t gfn; -#ifdef CONFIG_KVM_E500V2 - if (!(vcpu->arch.shared->msr & MSR_PR) && - (eaddr & PAGE_MASK) == vcpu->arch.magic_page_ea) { - kvmppc_map_magic(vcpu); - kvmppc_account_exit(vcpu, DTLB_VIRT_MISS_EXITS); - r = RESUME_GUEST; - - break; - } -#endif - /* Check the guest TLB. */ gtlb_index = kvmppc_mmu_dtlb_index(vcpu, eaddr); if (gtlb_index < 0) { @@ -1680,14 +1530,6 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, case KVM_REG_PPC_IAC2: *val = get_reg_val(id, vcpu->arch.dbg_reg.iac2); break; -#if CONFIG_PPC_ADV_DEBUG_IACS > 2 - case KVM_REG_PPC_IAC3: - *val = get_reg_val(id, vcpu->arch.dbg_reg.iac3); - break; - case KVM_REG_PPC_IAC4: - *val = get_reg_val(id, vcpu->arch.dbg_reg.iac4); - break; -#endif case KVM_REG_PPC_DAC1: *val = get_reg_val(id, vcpu->arch.dbg_reg.dac1); break; @@ -1699,11 +1541,9 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, *val = get_reg_val(id, epr); break; } -#if defined(CONFIG_64BIT) case KVM_REG_PPC_EPCR: *val = get_reg_val(id, vcpu->arch.epcr); break; -#endif case KVM_REG_PPC_TCR: *val = get_reg_val(id, vcpu->arch.tcr); break; @@ -1736,14 +1576,6 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, case KVM_REG_PPC_IAC2: vcpu->arch.dbg_reg.iac2 = set_reg_val(id, *val); break; -#if CONFIG_PPC_ADV_DEBUG_IACS > 2 - case KVM_REG_PPC_IAC3: - vcpu->arch.dbg_reg.iac3 = set_reg_val(id, *val); - break; - case KVM_REG_PPC_IAC4: - vcpu->arch.dbg_reg.iac4 = set_reg_val(id, *val); - break; -#endif case KVM_REG_PPC_DAC1: vcpu->arch.dbg_reg.dac1 = set_reg_val(id, *val); break; @@ -1755,13 +1587,11 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, kvmppc_set_epr(vcpu, new_epr); break; } -#if defined(CONFIG_64BIT) case KVM_REG_PPC_EPCR: { u32 new_epcr = set_reg_val(id, *val); kvmppc_set_epcr(vcpu, new_epcr); break; } -#endif case KVM_REG_PPC_OR_TSR: { u32 tsr_bits = set_reg_val(id, *val); kvmppc_set_tsr_bits(vcpu, tsr_bits); @@ -1849,14 +1679,10 @@ void kvmppc_core_flush_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot) void kvmppc_set_epcr(struct kvm_vcpu *vcpu, u32 new_epcr) { -#if defined(CONFIG_64BIT) vcpu->arch.epcr = new_epcr; -#ifdef CONFIG_KVM_BOOKE_HV vcpu->arch.shadow_epcr &= ~SPRN_EPCR_GICM; if (vcpu->arch.epcr & SPRN_EPCR_ICM) vcpu->arch.shadow_epcr |= SPRN_EPCR_GICM; -#endif -#endif } void kvmppc_set_tcr(struct kvm_vcpu *vcpu, u32 new_tcr) @@ -1910,16 +1736,6 @@ static int kvmppc_booke_add_breakpoint(struct debug_reg *dbg_reg, dbg_reg->dbcr0 |= DBCR0_IAC2; dbg_reg->iac2 = addr; break; -#if CONFIG_PPC_ADV_DEBUG_IACS > 2 - case 2: - dbg_reg->dbcr0 |= DBCR0_IAC3; - dbg_reg->iac3 = addr; - break; - case 3: - dbg_reg->dbcr0 |= DBCR0_IAC4; - dbg_reg->iac4 = addr; - break; -#endif default: return -EINVAL; } @@ -1956,8 +1772,6 @@ static int kvmppc_booke_add_watchpoint(struct debug_reg *dbg_reg, uint64_t addr, static void kvm_guest_protect_msr(struct kvm_vcpu *vcpu, ulong prot_bitmap, bool set) { - /* XXX: Add similar MSR protection for BookE-PR */ -#ifdef CONFIG_KVM_BOOKE_HV BUG_ON(prot_bitmap & ~(MSRP_UCLEP | MSRP_DEP | MSRP_PMMP)); if (set) { if (prot_bitmap & MSR_UCLE) @@ -1974,7 +1788,6 @@ static void kvm_guest_protect_msr(struct kvm_vcpu *vcpu, ulong prot_bitmap, if (prot_bitmap & MSR_PMM) vcpu->arch.shadow_msrp &= ~MSRP_PMMP; } -#endif } int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, enum xlate_instdata xlid, @@ -1983,21 +1796,6 @@ int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, enum xlate_instdata xlid, int gtlb_index; gpa_t gpaddr; -#ifdef CONFIG_KVM_E500V2 - if (!(vcpu->arch.shared->msr & MSR_PR) && - (eaddr & PAGE_MASK) == vcpu->arch.magic_page_ea) { - pte->eaddr = eaddr; - pte->raddr = (vcpu->arch.magic_page_pa & PAGE_MASK) | - (eaddr & ~PAGE_MASK); - pte->vpage = eaddr >> PAGE_SHIFT; - pte->may_read = true; - pte->may_write = true; - pte->may_execute = true; - - return 0; - } -#endif - /* Check the guest TLB. */ switch (xlid) { case XLATE_INST: @@ -2054,23 +1852,12 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, /* Code below handles only HW breakpoints */ dbg_reg = &(vcpu->arch.dbg_reg); -#ifdef CONFIG_KVM_BOOKE_HV /* * On BookE-HV (e500mc) the guest is always executed with MSR.GS=1 * DBCR1 and DBCR2 are set to trigger debug events when MSR.PR is 0 */ dbg_reg->dbcr1 = 0; dbg_reg->dbcr2 = 0; -#else - /* - * On BookE-PR (e500v2) the guest is always executed with MSR.PR=1 - * We set DBCR1 and DBCR2 to only trigger debug events when MSR.PR - * is set. - */ - dbg_reg->dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US | DBCR1_IAC3US | - DBCR1_IAC4US; - dbg_reg->dbcr2 = DBCR2_DAC1US | DBCR2_DAC2US; -#endif if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) goto out; @@ -2141,12 +1928,6 @@ int kvmppc_core_vcpu_create(struct kvm_vcpu *vcpu) kvmppc_set_gpr(vcpu, 1, (16<<20) - 8); /* -8 for the callee-save LR slot */ kvmppc_set_msr(vcpu, 0); -#ifndef CONFIG_KVM_BOOKE_HV - vcpu->arch.shadow_msr = MSR_USER | MSR_IS | MSR_DS; - vcpu->arch.shadow_pid = 1; - vcpu->arch.shared->msr = 0; -#endif - /* Eye-catching numbers so we know if the guest takes an interrupt * before it's programmed its own IVPR/IVORs. */ vcpu->arch.ivpr = 0x55550000; @@ -2184,59 +1965,10 @@ void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) int __init kvmppc_booke_init(void) { -#ifndef CONFIG_KVM_BOOKE_HV - unsigned long ivor[16]; - unsigned long *handler = kvmppc_booke_handler_addr; - unsigned long max_ivor = 0; - unsigned long handler_len; - int i; - - /* We install our own exception handlers by hijacking IVPR. IVPR must - * be 16-bit aligned, so we need a 64KB allocation. */ - kvmppc_booke_handlers = __get_free_pages(GFP_KERNEL | __GFP_ZERO, - VCPU_SIZE_ORDER); - if (!kvmppc_booke_handlers) - return -ENOMEM; - - /* XXX make sure our handlers are smaller than Linux's */ - - /* Copy our interrupt handlers to match host IVORs. That way we don't - * have to swap the IVORs on every guest/host transition. */ - ivor[0] = mfspr(SPRN_IVOR0); - ivor[1] = mfspr(SPRN_IVOR1); - ivor[2] = mfspr(SPRN_IVOR2); - ivor[3] = mfspr(SPRN_IVOR3); - ivor[4] = mfspr(SPRN_IVOR4); - ivor[5] = mfspr(SPRN_IVOR5); - ivor[6] = mfspr(SPRN_IVOR6); - ivor[7] = mfspr(SPRN_IVOR7); - ivor[8] = mfspr(SPRN_IVOR8); - ivor[9] = mfspr(SPRN_IVOR9); - ivor[10] = mfspr(SPRN_IVOR10); - ivor[11] = mfspr(SPRN_IVOR11); - ivor[12] = mfspr(SPRN_IVOR12); - ivor[13] = mfspr(SPRN_IVOR13); - ivor[14] = mfspr(SPRN_IVOR14); - ivor[15] = mfspr(SPRN_IVOR15); - - for (i = 0; i < 16; i++) { - if (ivor[i] > max_ivor) - max_ivor = i; - - handler_len = handler[i + 1] - handler[i]; - memcpy((void *)kvmppc_booke_handlers + ivor[i], - (void *)handler[i], handler_len); - } - - handler_len = handler[max_ivor + 1] - handler[max_ivor]; - flush_icache_range(kvmppc_booke_handlers, kvmppc_booke_handlers + - ivor[max_ivor] + handler_len); -#endif /* !BOOKE_HV */ return 0; } void __exit kvmppc_booke_exit(void) { - free_pages(kvmppc_booke_handlers, VCPU_SIZE_ORDER); kvm_exit(); } diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h index 9c5b8e76014f..72a8d2a0b0a2 100644 --- a/arch/powerpc/kvm/booke.h +++ b/arch/powerpc/kvm/booke.h @@ -21,15 +21,8 @@ #define BOOKE_IRQPRIO_ALIGNMENT 2 #define BOOKE_IRQPRIO_PROGRAM 3 #define BOOKE_IRQPRIO_FP_UNAVAIL 4 -#ifdef CONFIG_SPE_POSSIBLE -#define BOOKE_IRQPRIO_SPE_UNAVAIL 5 -#define BOOKE_IRQPRIO_SPE_FP_DATA 6 -#define BOOKE_IRQPRIO_SPE_FP_ROUND 7 -#endif -#ifdef CONFIG_PPC_E500MC #define BOOKE_IRQPRIO_ALTIVEC_UNAVAIL 5 #define BOOKE_IRQPRIO_ALTIVEC_ASSIST 6 -#endif #define BOOKE_IRQPRIO_SYSCALL 8 #define BOOKE_IRQPRIO_AP_UNAVAIL 9 #define BOOKE_IRQPRIO_DTLB_MISS 10 @@ -59,7 +52,6 @@ (1 << BOOKE_IRQPRIO_WATCHDOG) | \ (1 << BOOKE_IRQPRIO_CRITICAL)) -extern unsigned long kvmppc_booke_handlers; extern unsigned long kvmppc_booke_handler_addr[]; void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr); diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c index d8d38aca71bd..131159caa0ec 100644 --- a/arch/powerpc/kvm/booke_emulate.c +++ b/arch/powerpc/kvm/booke_emulate.c @@ -163,30 +163,6 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) debug_inst = true; vcpu->arch.dbg_reg.iac2 = spr_val; break; -#if CONFIG_PPC_ADV_DEBUG_IACS > 2 - case SPRN_IAC3: - /* - * If userspace is debugging guest then guest - * can not access debug registers. - */ - if (vcpu->guest_debug) - break; - - debug_inst = true; - vcpu->arch.dbg_reg.iac3 = spr_val; - break; - case SPRN_IAC4: - /* - * If userspace is debugging guest then guest - * can not access debug registers. - */ - if (vcpu->guest_debug) - break; - - debug_inst = true; - vcpu->arch.dbg_reg.iac4 = spr_val; - break; -#endif case SPRN_DAC1: /* * If userspace is debugging guest then guest @@ -296,9 +272,7 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) case SPRN_IVPR: vcpu->arch.ivpr = spr_val; -#ifdef CONFIG_KVM_BOOKE_HV mtspr(SPRN_GIVPR, spr_val); -#endif break; case SPRN_IVOR0: vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = spr_val; @@ -308,9 +282,7 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) break; case SPRN_IVOR2: vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = spr_val; -#ifdef CONFIG_KVM_BOOKE_HV mtspr(SPRN_GIVOR2, spr_val); -#endif break; case SPRN_IVOR3: vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = spr_val; @@ -329,9 +301,7 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) break; case SPRN_IVOR8: vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = spr_val; -#ifdef CONFIG_KVM_BOOKE_HV mtspr(SPRN_GIVOR8, spr_val); -#endif break; case SPRN_IVOR9: vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = spr_val; @@ -357,14 +327,10 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) case SPRN_MCSR: vcpu->arch.mcsr &= ~spr_val; break; -#if defined(CONFIG_64BIT) case SPRN_EPCR: kvmppc_set_epcr(vcpu, spr_val); -#ifdef CONFIG_KVM_BOOKE_HV mtspr(SPRN_EPCR, vcpu->arch.shadow_epcr); -#endif break; -#endif default: emulated = EMULATE_FAIL; } @@ -411,14 +377,6 @@ int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) case SPRN_IAC2: *spr_val = vcpu->arch.dbg_reg.iac2; break; -#if CONFIG_PPC_ADV_DEBUG_IACS > 2 - case SPRN_IAC3: - *spr_val = vcpu->arch.dbg_reg.iac3; - break; - case SPRN_IAC4: - *spr_val = vcpu->arch.dbg_reg.iac4; - break; -#endif case SPRN_DAC1: *spr_val = vcpu->arch.dbg_reg.dac1; break; @@ -497,11 +455,9 @@ int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) case SPRN_MCSR: *spr_val = vcpu->arch.mcsr; break; -#if defined(CONFIG_64BIT) case SPRN_EPCR: *spr_val = vcpu->arch.epcr; break; -#endif default: emulated = EMULATE_FAIL; diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S deleted file mode 100644 index 205545d820a1..000000000000 --- a/arch/powerpc/kvm/booke_interrupts.S +++ /dev/null @@ -1,535 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * - * Copyright IBM Corp. 2007 - * Copyright 2011 Freescale Semiconductor, Inc. - * - * Authors: Hollis Blanchard - */ - -#include -#include -#include -#include -#include - -/* The host stack layout: */ -#define HOST_R1 0 /* Implied by stwu. */ -#define HOST_CALLEE_LR 4 -#define HOST_RUN 8 -/* r2 is special: it holds 'current', and it made nonvolatile in the - * kernel with the -ffixed-r2 gcc option. */ -#define HOST_R2 12 -#define HOST_CR 16 -#define HOST_NV_GPRS 20 -#define __HOST_NV_GPR(n) (HOST_NV_GPRS + ((n - 14) * 4)) -#define HOST_NV_GPR(n) __HOST_NV_GPR(__REG_##n) -#define HOST_MIN_STACK_SIZE (HOST_NV_GPR(R31) + 4) -#define HOST_STACK_SIZE (((HOST_MIN_STACK_SIZE + 15) / 16) * 16) /* Align. */ -#define HOST_STACK_LR (HOST_STACK_SIZE + 4) /* In caller stack frame. */ - -#define NEED_INST_MASK ((1< #include -#ifdef CONFIG_64BIT #include #include #include -#else -#include "../kernel/head_booke.h" /* for THREAD_NORMSAVE() */ -#endif #define LONGBYTES (BITS_PER_LONG / 8) @@ -155,7 +151,6 @@ END_BTB_FLUSH_SECTION b kvmppc_resume_host .endm -#ifdef CONFIG_64BIT /* Exception types */ #define EX_GEN 1 #define EX_GDBELL 2 @@ -273,99 +268,6 @@ kvm_handler BOOKE_INTERRUPT_DEBUG, EX_PARAMS(CRIT), \ SPRN_CSRR0, SPRN_CSRR1, 0 kvm_handler BOOKE_INTERRUPT_LRAT_ERROR, EX_PARAMS(GEN), \ SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR | NEED_ESR) -#else -/* - * For input register values, see arch/powerpc/include/asm/kvm_booke_hv_asm.h - */ -.macro kvm_handler intno srr0, srr1, flags -_GLOBAL(kvmppc_handler_\intno\()_\srr1) - PPC_LL r11, THREAD_KVM_VCPU(r10) - PPC_STL r3, VCPU_GPR(R3)(r11) - mfspr r3, SPRN_SPRG_RSCRATCH0 - PPC_STL r4, VCPU_GPR(R4)(r11) - PPC_LL r4, THREAD_NORMSAVE(0)(r10) - PPC_STL r5, VCPU_GPR(R5)(r11) - PPC_STL r13, VCPU_CR(r11) - mfspr r5, \srr0 - PPC_STL r3, VCPU_GPR(R10)(r11) - PPC_LL r3, THREAD_NORMSAVE(2)(r10) - PPC_STL r6, VCPU_GPR(R6)(r11) - PPC_STL r4, VCPU_GPR(R11)(r11) - mfspr r6, \srr1 - PPC_STL r7, VCPU_GPR(R7)(r11) - PPC_STL r8, VCPU_GPR(R8)(r11) - PPC_STL r9, VCPU_GPR(R9)(r11) - PPC_STL r3, VCPU_GPR(R13)(r11) - mfctr r7 - PPC_STL r12, VCPU_GPR(R12)(r11) - PPC_STL r7, VCPU_CTR(r11) - mr r4, r11 - kvm_handler_common \intno, \srr0, \flags -.endm - -.macro kvm_lvl_handler intno scratch srr0, srr1, flags -_GLOBAL(kvmppc_handler_\intno\()_\srr1) - mfspr r10, SPRN_SPRG_THREAD - PPC_LL r11, THREAD_KVM_VCPU(r10) - PPC_STL r3, VCPU_GPR(R3)(r11) - mfspr r3, \scratch - PPC_STL r4, VCPU_GPR(R4)(r11) - PPC_LL r4, GPR9(r8) - PPC_STL r5, VCPU_GPR(R5)(r11) - PPC_STL r9, VCPU_CR(r11) - mfspr r5, \srr0 - PPC_STL r3, VCPU_GPR(R8)(r11) - PPC_LL r3, GPR10(r8) - PPC_STL r6, VCPU_GPR(R6)(r11) - PPC_STL r4, VCPU_GPR(R9)(r11) - mfspr r6, \srr1 - PPC_LL r4, GPR11(r8) - PPC_STL r7, VCPU_GPR(R7)(r11) - PPC_STL r3, VCPU_GPR(R10)(r11) - mfctr r7 - PPC_STL r12, VCPU_GPR(R12)(r11) - PPC_STL r13, VCPU_GPR(R13)(r11) - PPC_STL r4, VCPU_GPR(R11)(r11) - PPC_STL r7, VCPU_CTR(r11) - mr r4, r11 - kvm_handler_common \intno, \srr0, \flags -.endm - -kvm_lvl_handler BOOKE_INTERRUPT_CRITICAL, \ - SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0 -kvm_lvl_handler BOOKE_INTERRUPT_MACHINE_CHECK, \ - SPRN_SPRG_RSCRATCH_MC, SPRN_MCSRR0, SPRN_MCSRR1, 0 -kvm_handler BOOKE_INTERRUPT_DATA_STORAGE, \ - SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR | NEED_ESR) -kvm_handler BOOKE_INTERRUPT_INST_STORAGE, SPRN_SRR0, SPRN_SRR1, NEED_ESR -kvm_handler BOOKE_INTERRUPT_EXTERNAL, SPRN_SRR0, SPRN_SRR1, 0 -kvm_handler BOOKE_INTERRUPT_ALIGNMENT, \ - SPRN_SRR0, SPRN_SRR1, (NEED_DEAR | NEED_ESR) -kvm_handler BOOKE_INTERRUPT_PROGRAM, SPRN_SRR0, SPRN_SRR1, (NEED_ESR | NEED_EMU) -kvm_handler BOOKE_INTERRUPT_FP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0 -kvm_handler BOOKE_INTERRUPT_SYSCALL, SPRN_SRR0, SPRN_SRR1, 0 -kvm_handler BOOKE_INTERRUPT_AP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0 -kvm_handler BOOKE_INTERRUPT_DECREMENTER, SPRN_SRR0, SPRN_SRR1, 0 -kvm_handler BOOKE_INTERRUPT_FIT, SPRN_SRR0, SPRN_SRR1, 0 -kvm_lvl_handler BOOKE_INTERRUPT_WATCHDOG, \ - SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0 -kvm_handler BOOKE_INTERRUPT_DTLB_MISS, \ - SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR | NEED_ESR) -kvm_handler BOOKE_INTERRUPT_ITLB_MISS, SPRN_SRR0, SPRN_SRR1, 0 -kvm_handler BOOKE_INTERRUPT_PERFORMANCE_MONITOR, SPRN_SRR0, SPRN_SRR1, 0 -kvm_handler BOOKE_INTERRUPT_DOORBELL, SPRN_SRR0, SPRN_SRR1, 0 -kvm_lvl_handler BOOKE_INTERRUPT_DOORBELL_CRITICAL, \ - SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0 -kvm_handler BOOKE_INTERRUPT_HV_PRIV, SPRN_SRR0, SPRN_SRR1, NEED_EMU -kvm_handler BOOKE_INTERRUPT_HV_SYSCALL, SPRN_SRR0, SPRN_SRR1, 0 -kvm_handler BOOKE_INTERRUPT_GUEST_DBELL, SPRN_GSRR0, SPRN_GSRR1, 0 -kvm_lvl_handler BOOKE_INTERRUPT_GUEST_DBELL_CRIT, \ - SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0 -kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \ - SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0 -kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \ - SPRN_SPRG_RSCRATCH_DBG, SPRN_DSRR0, SPRN_DSRR1, 0 -#endif /* Registers: * SPRG_SCRATCH0: guest r10 @@ -382,17 +284,13 @@ _GLOBAL(kvmppc_resume_host) PPC_STL r5, VCPU_LR(r4) mfspr r7, SPRN_SPRG5 stw r3, VCPU_VRSAVE(r4) -#ifdef CONFIG_64BIT PPC_LL r3, PACA_SPRG_VDSO(r13) -#endif mfspr r5, SPRN_SPRG9 PPC_STD(r6, VCPU_SHARED_SPRG4, r11) mfspr r8, SPRN_SPRG6 PPC_STD(r7, VCPU_SHARED_SPRG5, r11) mfspr r9, SPRN_SPRG7 -#ifdef CONFIG_64BIT mtspr SPRN_SPRG_VDSO_WRITE, r3 -#endif PPC_STD(r5, VCPU_SPRG9, r4) PPC_STD(r8, VCPU_SHARED_SPRG6, r11) mfxer r3 diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c deleted file mode 100644 index b0f695428733..000000000000 --- a/arch/powerpc/kvm/e500.c +++ /dev/null @@ -1,553 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved. - * - * Author: Yu Liu, - * - * Description: - * This file is derived from arch/powerpc/kvm/44x.c, - * by Hollis Blanchard . - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "../mm/mmu_decl.h" -#include "booke.h" -#include "e500.h" - -struct id { - unsigned long val; - struct id **pentry; -}; - -#define NUM_TIDS 256 - -/* - * This table provide mappings from: - * (guestAS,guestTID,guestPR) --> ID of physical cpu - * guestAS [0..1] - * guestTID [0..255] - * guestPR [0..1] - * ID [1..255] - * Each vcpu keeps one vcpu_id_table. - */ -struct vcpu_id_table { - struct id id[2][NUM_TIDS][2]; -}; - -/* - * This table provide reversed mappings of vcpu_id_table: - * ID --> address of vcpu_id_table item. - * Each physical core has one pcpu_id_table. - */ -struct pcpu_id_table { - struct id *entry[NUM_TIDS]; -}; - -static DEFINE_PER_CPU(struct pcpu_id_table, pcpu_sids); - -/* This variable keeps last used shadow ID on local core. - * The valid range of shadow ID is [1..255] */ -static DEFINE_PER_CPU(unsigned long, pcpu_last_used_sid); - -/* - * Allocate a free shadow id and setup a valid sid mapping in given entry. - * A mapping is only valid when vcpu_id_table and pcpu_id_table are match. - * - * The caller must have preemption disabled, and keep it that way until - * it has finished with the returned shadow id (either written into the - * TLB or arch.shadow_pid, or discarded). - */ -static inline int local_sid_setup_one(struct id *entry) -{ - unsigned long sid; - int ret = -1; - - sid = __this_cpu_inc_return(pcpu_last_used_sid); - if (sid < NUM_TIDS) { - __this_cpu_write(pcpu_sids.entry[sid], entry); - entry->val = sid; - entry->pentry = this_cpu_ptr(&pcpu_sids.entry[sid]); - ret = sid; - } - - /* - * If sid == NUM_TIDS, we've run out of sids. We return -1, and - * the caller will invalidate everything and start over. - * - * sid > NUM_TIDS indicates a race, which we disable preemption to - * avoid. - */ - WARN_ON(sid > NUM_TIDS); - - return ret; -} - -/* - * Check if given entry contain a valid shadow id mapping. - * An ID mapping is considered valid only if - * both vcpu and pcpu know this mapping. - * - * The caller must have preemption disabled, and keep it that way until - * it has finished with the returned shadow id (either written into the - * TLB or arch.shadow_pid, or discarded). - */ -static inline int local_sid_lookup(struct id *entry) -{ - if (entry && entry->val != 0 && - __this_cpu_read(pcpu_sids.entry[entry->val]) == entry && - entry->pentry == this_cpu_ptr(&pcpu_sids.entry[entry->val])) - return entry->val; - return -1; -} - -/* Invalidate all id mappings on local core -- call with preempt disabled */ -static inline void local_sid_destroy_all(void) -{ - __this_cpu_write(pcpu_last_used_sid, 0); - memset(this_cpu_ptr(&pcpu_sids), 0, sizeof(pcpu_sids)); -} - -static void *kvmppc_e500_id_table_alloc(struct kvmppc_vcpu_e500 *vcpu_e500) -{ - vcpu_e500->idt = kzalloc(sizeof(struct vcpu_id_table), GFP_KERNEL); - return vcpu_e500->idt; -} - -static void kvmppc_e500_id_table_free(struct kvmppc_vcpu_e500 *vcpu_e500) -{ - kfree(vcpu_e500->idt); - vcpu_e500->idt = NULL; -} - -/* Map guest pid to shadow. - * We use PID to keep shadow of current guest non-zero PID, - * and use PID1 to keep shadow of guest zero PID. - * So that guest tlbe with TID=0 can be accessed at any time */ -static void kvmppc_e500_recalc_shadow_pid(struct kvmppc_vcpu_e500 *vcpu_e500) -{ - preempt_disable(); - vcpu_e500->vcpu.arch.shadow_pid = kvmppc_e500_get_sid(vcpu_e500, - get_cur_as(&vcpu_e500->vcpu), - get_cur_pid(&vcpu_e500->vcpu), - get_cur_pr(&vcpu_e500->vcpu), 1); - vcpu_e500->vcpu.arch.shadow_pid1 = kvmppc_e500_get_sid(vcpu_e500, - get_cur_as(&vcpu_e500->vcpu), 0, - get_cur_pr(&vcpu_e500->vcpu), 1); - preempt_enable(); -} - -/* Invalidate all mappings on vcpu */ -static void kvmppc_e500_id_table_reset_all(struct kvmppc_vcpu_e500 *vcpu_e500) -{ - memset(vcpu_e500->idt, 0, sizeof(struct vcpu_id_table)); - - /* Update shadow pid when mappings are changed */ - kvmppc_e500_recalc_shadow_pid(vcpu_e500); -} - -/* Invalidate one ID mapping on vcpu */ -static inline void kvmppc_e500_id_table_reset_one( - struct kvmppc_vcpu_e500 *vcpu_e500, - int as, int pid, int pr) -{ - struct vcpu_id_table *idt = vcpu_e500->idt; - - BUG_ON(as >= 2); - BUG_ON(pid >= NUM_TIDS); - BUG_ON(pr >= 2); - - idt->id[as][pid][pr].val = 0; - idt->id[as][pid][pr].pentry = NULL; - - /* Update shadow pid when mappings are changed */ - kvmppc_e500_recalc_shadow_pid(vcpu_e500); -} - -/* - * Map guest (vcpu,AS,ID,PR) to physical core shadow id. - * This function first lookup if a valid mapping exists, - * if not, then creates a new one. - * - * The caller must have preemption disabled, and keep it that way until - * it has finished with the returned shadow id (either written into the - * TLB or arch.shadow_pid, or discarded). - */ -unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500, - unsigned int as, unsigned int gid, - unsigned int pr, int avoid_recursion) -{ - struct vcpu_id_table *idt = vcpu_e500->idt; - int sid; - - BUG_ON(as >= 2); - BUG_ON(gid >= NUM_TIDS); - BUG_ON(pr >= 2); - - sid = local_sid_lookup(&idt->id[as][gid][pr]); - - while (sid <= 0) { - /* No mapping yet */ - sid = local_sid_setup_one(&idt->id[as][gid][pr]); - if (sid <= 0) { - _tlbil_all(); - local_sid_destroy_all(); - } - - /* Update shadow pid when mappings are changed */ - if (!avoid_recursion) - kvmppc_e500_recalc_shadow_pid(vcpu_e500); - } - - return sid; -} - -unsigned int kvmppc_e500_get_tlb_stid(struct kvm_vcpu *vcpu, - struct kvm_book3e_206_tlb_entry *gtlbe) -{ - return kvmppc_e500_get_sid(to_e500(vcpu), get_tlb_ts(gtlbe), - get_tlb_tid(gtlbe), get_cur_pr(vcpu), 0); -} - -void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid) -{ - struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); - - if (vcpu->arch.pid != pid) { - vcpu_e500->pid[0] = vcpu->arch.pid = pid; - kvmppc_e500_recalc_shadow_pid(vcpu_e500); - } -} - -/* gtlbe must not be mapped by more than one host tlbe */ -void kvmppc_e500_tlbil_one(struct kvmppc_vcpu_e500 *vcpu_e500, - struct kvm_book3e_206_tlb_entry *gtlbe) -{ - struct vcpu_id_table *idt = vcpu_e500->idt; - unsigned int pr, tid, ts; - int pid; - u32 val, eaddr; - unsigned long flags; - - ts = get_tlb_ts(gtlbe); - tid = get_tlb_tid(gtlbe); - - preempt_disable(); - - /* One guest ID may be mapped to two shadow IDs */ - for (pr = 0; pr < 2; pr++) { - /* - * The shadow PID can have a valid mapping on at most one - * host CPU. In the common case, it will be valid on this - * CPU, in which case we do a local invalidation of the - * specific address. - * - * If the shadow PID is not valid on the current host CPU, - * we invalidate the entire shadow PID. - */ - pid = local_sid_lookup(&idt->id[ts][tid][pr]); - if (pid <= 0) { - kvmppc_e500_id_table_reset_one(vcpu_e500, ts, tid, pr); - continue; - } - - /* - * The guest is invalidating a 4K entry which is in a PID - * that has a valid shadow mapping on this host CPU. We - * search host TLB to invalidate it's shadow TLB entry, - * similar to __tlbil_va except that we need to look in AS1. - */ - val = (pid << MAS6_SPID_SHIFT) | MAS6_SAS; - eaddr = get_tlb_eaddr(gtlbe); - - local_irq_save(flags); - - mtspr(SPRN_MAS6, val); - asm volatile("tlbsx 0, %[eaddr]" : : [eaddr] "r" (eaddr)); - val = mfspr(SPRN_MAS1); - if (val & MAS1_VALID) { - mtspr(SPRN_MAS1, val & ~MAS1_VALID); - asm volatile("tlbwe"); - } - - local_irq_restore(flags); - } - - preempt_enable(); -} - -void kvmppc_e500_tlbil_all(struct kvmppc_vcpu_e500 *vcpu_e500) -{ - kvmppc_e500_id_table_reset_all(vcpu_e500); -} - -void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr) -{ - /* Recalc shadow pid since MSR changes */ - kvmppc_e500_recalc_shadow_pid(to_e500(vcpu)); -} - -static void kvmppc_core_vcpu_load_e500(struct kvm_vcpu *vcpu, int cpu) -{ - kvmppc_booke_vcpu_load(vcpu, cpu); - - /* Shadow PID may be expired on local core */ - kvmppc_e500_recalc_shadow_pid(to_e500(vcpu)); -} - -static void kvmppc_core_vcpu_put_e500(struct kvm_vcpu *vcpu) -{ -#ifdef CONFIG_SPE - if (vcpu->arch.shadow_msr & MSR_SPE) - kvmppc_vcpu_disable_spe(vcpu); -#endif - - kvmppc_booke_vcpu_put(vcpu); -} - -static int kvmppc_e500_check_processor_compat(void) -{ - int r; - - if (strcmp(cur_cpu_spec->cpu_name, "e500v2") == 0) - r = 0; - else - r = -ENOTSUPP; - - return r; -} - -static void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500) -{ - struct kvm_book3e_206_tlb_entry *tlbe; - - /* Insert large initial mapping for guest. */ - tlbe = get_entry(vcpu_e500, 1, 0); - tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOK3E_PAGESZ_256M); - tlbe->mas2 = 0; - tlbe->mas7_3 = E500_TLB_SUPER_PERM_MASK; - - /* 4K map for serial output. Used by kernel wrapper. */ - tlbe = get_entry(vcpu_e500, 1, 1); - tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOK3E_PAGESZ_4K); - tlbe->mas2 = (0xe0004500 & 0xFFFFF000) | MAS2_I | MAS2_G; - tlbe->mas7_3 = (0xe0004500 & 0xFFFFF000) | E500_TLB_SUPER_PERM_MASK; -} - -int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu) -{ - struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); - - kvmppc_e500_tlb_setup(vcpu_e500); - - /* Registers init */ - vcpu->arch.pvr = mfspr(SPRN_PVR); - vcpu_e500->svr = mfspr(SPRN_SVR); - - vcpu->arch.cpu_type = KVM_CPU_E500V2; - - return 0; -} - -static int kvmppc_core_get_sregs_e500(struct kvm_vcpu *vcpu, - struct kvm_sregs *sregs) -{ - struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); - - sregs->u.e.features |= KVM_SREGS_E_ARCH206_MMU | KVM_SREGS_E_SPE | - KVM_SREGS_E_PM; - sregs->u.e.impl_id = KVM_SREGS_E_IMPL_FSL; - - sregs->u.e.impl.fsl.features = 0; - sregs->u.e.impl.fsl.svr = vcpu_e500->svr; - sregs->u.e.impl.fsl.hid0 = vcpu_e500->hid0; - sregs->u.e.impl.fsl.mcar = vcpu_e500->mcar; - - sregs->u.e.ivor_high[0] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; - sregs->u.e.ivor_high[1] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA]; - sregs->u.e.ivor_high[2] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND]; - sregs->u.e.ivor_high[3] = - vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]; - - kvmppc_get_sregs_ivor(vcpu, sregs); - kvmppc_get_sregs_e500_tlb(vcpu, sregs); - return 0; -} - -static int kvmppc_core_set_sregs_e500(struct kvm_vcpu *vcpu, - struct kvm_sregs *sregs) -{ - struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); - int ret; - - if (sregs->u.e.impl_id == KVM_SREGS_E_IMPL_FSL) { - vcpu_e500->svr = sregs->u.e.impl.fsl.svr; - vcpu_e500->hid0 = sregs->u.e.impl.fsl.hid0; - vcpu_e500->mcar = sregs->u.e.impl.fsl.mcar; - } - - ret = kvmppc_set_sregs_e500_tlb(vcpu, sregs); - if (ret < 0) - return ret; - - if (!(sregs->u.e.features & KVM_SREGS_E_IVOR)) - return 0; - - if (sregs->u.e.features & KVM_SREGS_E_SPE) { - vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = - sregs->u.e.ivor_high[0]; - vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = - sregs->u.e.ivor_high[1]; - vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = - sregs->u.e.ivor_high[2]; - } - - if (sregs->u.e.features & KVM_SREGS_E_PM) { - vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = - sregs->u.e.ivor_high[3]; - } - - return kvmppc_set_sregs_ivor(vcpu, sregs); -} - -static int kvmppc_get_one_reg_e500(struct kvm_vcpu *vcpu, u64 id, - union kvmppc_one_reg *val) -{ - int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val); - return r; -} - -static int kvmppc_set_one_reg_e500(struct kvm_vcpu *vcpu, u64 id, - union kvmppc_one_reg *val) -{ - int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val); - return r; -} - -static int kvmppc_core_vcpu_create_e500(struct kvm_vcpu *vcpu) -{ - struct kvmppc_vcpu_e500 *vcpu_e500; - int err; - - BUILD_BUG_ON(offsetof(struct kvmppc_vcpu_e500, vcpu) != 0); - vcpu_e500 = to_e500(vcpu); - - if (kvmppc_e500_id_table_alloc(vcpu_e500) == NULL) - return -ENOMEM; - - err = kvmppc_e500_tlb_init(vcpu_e500); - if (err) - goto uninit_id; - - vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO); - if (!vcpu->arch.shared) { - err = -ENOMEM; - goto uninit_tlb; - } - - return 0; - -uninit_tlb: - kvmppc_e500_tlb_uninit(vcpu_e500); -uninit_id: - kvmppc_e500_id_table_free(vcpu_e500); - return err; -} - -static void kvmppc_core_vcpu_free_e500(struct kvm_vcpu *vcpu) -{ - struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); - - free_page((unsigned long)vcpu->arch.shared); - kvmppc_e500_tlb_uninit(vcpu_e500); - kvmppc_e500_id_table_free(vcpu_e500); -} - -static int kvmppc_core_init_vm_e500(struct kvm *kvm) -{ - return 0; -} - -static void kvmppc_core_destroy_vm_e500(struct kvm *kvm) -{ -} - -static struct kvmppc_ops kvm_ops_e500 = { - .get_sregs = kvmppc_core_get_sregs_e500, - .set_sregs = kvmppc_core_set_sregs_e500, - .get_one_reg = kvmppc_get_one_reg_e500, - .set_one_reg = kvmppc_set_one_reg_e500, - .vcpu_load = kvmppc_core_vcpu_load_e500, - .vcpu_put = kvmppc_core_vcpu_put_e500, - .vcpu_create = kvmppc_core_vcpu_create_e500, - .vcpu_free = kvmppc_core_vcpu_free_e500, - .init_vm = kvmppc_core_init_vm_e500, - .destroy_vm = kvmppc_core_destroy_vm_e500, - .emulate_op = kvmppc_core_emulate_op_e500, - .emulate_mtspr = kvmppc_core_emulate_mtspr_e500, - .emulate_mfspr = kvmppc_core_emulate_mfspr_e500, - .create_vcpu_debugfs = kvmppc_create_vcpu_debugfs_e500, -}; - -static int __init kvmppc_e500_init(void) -{ - int r, i; - unsigned long ivor[3]; - /* Process remaining handlers above the generic first 16 */ - unsigned long *handler = &kvmppc_booke_handler_addr[16]; - unsigned long handler_len; - unsigned long max_ivor = 0; - - r = kvmppc_e500_check_processor_compat(); - if (r) - goto err_out; - - r = kvmppc_booke_init(); - if (r) - goto err_out; - - /* copy extra E500 exception handlers */ - ivor[0] = mfspr(SPRN_IVOR32); - ivor[1] = mfspr(SPRN_IVOR33); - ivor[2] = mfspr(SPRN_IVOR34); - for (i = 0; i < 3; i++) { - if (ivor[i] > ivor[max_ivor]) - max_ivor = i; - - handler_len = handler[i + 1] - handler[i]; - memcpy((void *)kvmppc_booke_handlers + ivor[i], - (void *)handler[i], handler_len); - } - handler_len = handler[max_ivor + 1] - handler[max_ivor]; - flush_icache_range(kvmppc_booke_handlers, kvmppc_booke_handlers + - ivor[max_ivor] + handler_len); - - r = kvm_init(sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE); - if (r) - goto err_out; - kvm_ops_e500.owner = THIS_MODULE; - kvmppc_pr_ops = &kvm_ops_e500; - -err_out: - return r; -} - -static void __exit kvmppc_e500_exit(void) -{ - kvmppc_pr_ops = NULL; - kvmppc_booke_exit(); -} - -module_init(kvmppc_e500_init); -module_exit(kvmppc_e500_exit); -MODULE_ALIAS_MISCDEV(KVM_MINOR); -MODULE_ALIAS("devname:kvm"); diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h index 6d0d329cbb35..325c190cc771 100644 --- a/arch/powerpc/kvm/e500.h +++ b/arch/powerpc/kvm/e500.h @@ -46,10 +46,6 @@ struct tlbe_priv { struct tlbe_ref ref; }; -#ifdef CONFIG_KVM_E500V2 -struct vcpu_id_table; -#endif - struct kvmppc_e500_tlb_params { int entries, ways, sets; }; @@ -88,13 +84,6 @@ struct kvmppc_vcpu_e500 { /* Minimum and maximum address mapped my TLB1 */ unsigned long tlb1_min_eaddr; unsigned long tlb1_max_eaddr; - -#ifdef CONFIG_KVM_E500V2 - u32 pid[E500_PID_NUM]; - - /* vcpu id table */ - struct vcpu_id_table *idt; -#endif }; static inline struct kvmppc_vcpu_e500 *to_e500(struct kvm_vcpu *vcpu) @@ -140,12 +129,6 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id, int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val); -#ifdef CONFIG_KVM_E500V2 -unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500, - unsigned int as, unsigned int gid, - unsigned int pr, int avoid_recursion); -#endif - /* TLB helper functions */ static inline unsigned int get_tlb_size(const struct kvm_book3e_206_tlb_entry *tlbe) @@ -257,13 +240,6 @@ static inline int tlbe_is_host_safe(const struct kvm_vcpu *vcpu, if (!get_tlb_v(tlbe)) return 0; -#ifndef CONFIG_KVM_BOOKE_HV - /* Does it match current guest AS? */ - /* XXX what about IS != DS? */ - if (get_tlb_ts(tlbe) != !!(vcpu->arch.shared->msr & MSR_IS)) - return 0; -#endif - gpa = get_tlb_raddr(tlbe); if (!gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT)) /* Mapping is not for RAM. */ @@ -283,7 +259,6 @@ void kvmppc_e500_tlbil_one(struct kvmppc_vcpu_e500 *vcpu_e500, struct kvm_book3e_206_tlb_entry *gtlbe); void kvmppc_e500_tlbil_all(struct kvmppc_vcpu_e500 *vcpu_e500); -#ifdef CONFIG_KVM_BOOKE_HV #define kvmppc_e500_get_tlb_stid(vcpu, gtlbe) get_tlb_tid(gtlbe) #define get_tlbmiss_tid(vcpu) get_cur_pid(vcpu) #define get_tlb_sts(gtlbe) (gtlbe->mas1 & MAS1_TS) @@ -306,21 +281,6 @@ static inline int get_lpid(struct kvm_vcpu *vcpu) { return get_thread_specific_lpid(vcpu->kvm->arch.lpid); } -#else -unsigned int kvmppc_e500_get_tlb_stid(struct kvm_vcpu *vcpu, - struct kvm_book3e_206_tlb_entry *gtlbe); - -static inline unsigned int get_tlbmiss_tid(struct kvm_vcpu *vcpu) -{ - struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); - unsigned int tidseld = (vcpu->arch.shared->mas4 >> 16) & 0xf; - - return vcpu_e500->pid[tidseld]; -} - -/* Force TS=1 for all guest mappings. */ -#define get_tlb_sts(gtlbe) (MAS1_TS) -#endif /* !BOOKE_HV */ static inline bool has_feature(const struct kvm_vcpu *vcpu, enum vcpu_ftr ftr) diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index 051102d50c31..0173eea26b83 100644 --- a/arch/powerpc/kvm/e500_emulate.c +++ b/arch/powerpc/kvm/e500_emulate.c @@ -28,7 +28,6 @@ #define XOP_TLBILX 18 #define XOP_EHPRIV 270 -#ifdef CONFIG_KVM_E500MC static int dbell2prio(ulong param) { int msg = param & PPC_DBELL_TYPE_MASK; @@ -81,7 +80,6 @@ static int kvmppc_e500_emul_msgsnd(struct kvm_vcpu *vcpu, int rb) return EMULATE_DONE; } -#endif static int kvmppc_e500_emul_ehpriv(struct kvm_vcpu *vcpu, unsigned int inst, int *advance) @@ -142,7 +140,6 @@ int kvmppc_core_emulate_op_e500(struct kvm_vcpu *vcpu, emulated = kvmppc_e500_emul_dcbtls(vcpu); break; -#ifdef CONFIG_KVM_E500MC case XOP_MSGSND: emulated = kvmppc_e500_emul_msgsnd(vcpu, rb); break; @@ -150,7 +147,6 @@ int kvmppc_core_emulate_op_e500(struct kvm_vcpu *vcpu, case XOP_MSGCLR: emulated = kvmppc_e500_emul_msgclr(vcpu, rb); break; -#endif case XOP_TLBRE: emulated = kvmppc_e500_emul_tlbre(vcpu); @@ -207,44 +203,6 @@ int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_va int emulated = EMULATE_DONE; switch (sprn) { -#ifndef CONFIG_KVM_BOOKE_HV - case SPRN_PID: - kvmppc_set_pid(vcpu, spr_val); - break; - case SPRN_PID1: - if (spr_val != 0) - return EMULATE_FAIL; - vcpu_e500->pid[1] = spr_val; - break; - case SPRN_PID2: - if (spr_val != 0) - return EMULATE_FAIL; - vcpu_e500->pid[2] = spr_val; - break; - case SPRN_MAS0: - vcpu->arch.shared->mas0 = spr_val; - break; - case SPRN_MAS1: - vcpu->arch.shared->mas1 = spr_val; - break; - case SPRN_MAS2: - vcpu->arch.shared->mas2 = spr_val; - break; - case SPRN_MAS3: - vcpu->arch.shared->mas7_3 &= ~(u64)0xffffffff; - vcpu->arch.shared->mas7_3 |= spr_val; - break; - case SPRN_MAS4: - vcpu->arch.shared->mas4 = spr_val; - break; - case SPRN_MAS6: - vcpu->arch.shared->mas6 = spr_val; - break; - case SPRN_MAS7: - vcpu->arch.shared->mas7_3 &= (u64)0xffffffff; - vcpu->arch.shared->mas7_3 |= (u64)spr_val << 32; - break; -#endif case SPRN_L1CSR0: vcpu_e500->l1csr0 = spr_val; vcpu_e500->l1csr0 &= ~(L1CSR0_DCFI | L1CSR0_CLFC); @@ -281,17 +239,6 @@ int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_va break; /* extra exceptions */ -#ifdef CONFIG_SPE_POSSIBLE - case SPRN_IVOR32: - vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = spr_val; - break; - case SPRN_IVOR33: - vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = spr_val; - break; - case SPRN_IVOR34: - vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = spr_val; - break; -#endif #ifdef CONFIG_ALTIVEC case SPRN_IVOR32: vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_UNAVAIL] = spr_val; @@ -303,14 +250,12 @@ int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_va case SPRN_IVOR35: vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = spr_val; break; -#ifdef CONFIG_KVM_BOOKE_HV case SPRN_IVOR36: vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL] = spr_val; break; case SPRN_IVOR37: vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT] = spr_val; break; -#endif default: emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, spr_val); } @@ -324,38 +269,6 @@ int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong *spr_v int emulated = EMULATE_DONE; switch (sprn) { -#ifndef CONFIG_KVM_BOOKE_HV - case SPRN_PID: - *spr_val = vcpu_e500->pid[0]; - break; - case SPRN_PID1: - *spr_val = vcpu_e500->pid[1]; - break; - case SPRN_PID2: - *spr_val = vcpu_e500->pid[2]; - break; - case SPRN_MAS0: - *spr_val = vcpu->arch.shared->mas0; - break; - case SPRN_MAS1: - *spr_val = vcpu->arch.shared->mas1; - break; - case SPRN_MAS2: - *spr_val = vcpu->arch.shared->mas2; - break; - case SPRN_MAS3: - *spr_val = (u32)vcpu->arch.shared->mas7_3; - break; - case SPRN_MAS4: - *spr_val = vcpu->arch.shared->mas4; - break; - case SPRN_MAS6: - *spr_val = vcpu->arch.shared->mas6; - break; - case SPRN_MAS7: - *spr_val = vcpu->arch.shared->mas7_3 >> 32; - break; -#endif case SPRN_DECAR: *spr_val = vcpu->arch.decar; break; @@ -413,17 +326,6 @@ int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong *spr_v break; /* extra exceptions */ -#ifdef CONFIG_SPE_POSSIBLE - case SPRN_IVOR32: - *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; - break; - case SPRN_IVOR33: - *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA]; - break; - case SPRN_IVOR34: - *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND]; - break; -#endif #ifdef CONFIG_ALTIVEC case SPRN_IVOR32: *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_UNAVAIL]; @@ -435,14 +337,12 @@ int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong *spr_v case SPRN_IVOR35: *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]; break; -#ifdef CONFIG_KVM_BOOKE_HV case SPRN_IVOR36: *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL]; break; case SPRN_IVOR37: *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT]; break; -#endif default: emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, spr_val); } diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c index e5a145b578a4..f808fdc4bb85 100644 --- a/arch/powerpc/kvm/e500_mmu_host.c +++ b/arch/powerpc/kvm/e500_mmu_host.c @@ -50,16 +50,6 @@ static inline u32 e500_shadow_mas3_attrib(u32 mas3, int usermode) /* Mask off reserved bits. */ mas3 &= MAS3_ATTRIB_MASK; -#ifndef CONFIG_KVM_BOOKE_HV - if (!usermode) { - /* Guest is in supervisor mode, - * so we need to translate guest - * supervisor permissions into user permissions. */ - mas3 &= ~E500_TLB_USER_PERM_MASK; - mas3 |= (mas3 & E500_TLB_SUPER_PERM_MASK) << 1; - } - mas3 |= E500_TLB_SUPER_PERM_MASK; -#endif return mas3; } @@ -78,16 +68,12 @@ static inline void __write_host_tlbe(struct kvm_book3e_206_tlb_entry *stlbe, mtspr(SPRN_MAS2, (unsigned long)stlbe->mas2); mtspr(SPRN_MAS3, (u32)stlbe->mas7_3); mtspr(SPRN_MAS7, (u32)(stlbe->mas7_3 >> 32)); -#ifdef CONFIG_KVM_BOOKE_HV mtspr(SPRN_MAS8, MAS8_TGS | get_thread_specific_lpid(lpid)); -#endif asm volatile("isync; tlbwe" : : : "memory"); -#ifdef CONFIG_KVM_BOOKE_HV /* Must clear mas8 for other host tlbwe's */ mtspr(SPRN_MAS8, 0); isync(); -#endif local_irq_restore(flags); trace_kvm_booke206_stlb_write(mas0, stlbe->mas8, stlbe->mas1, @@ -153,34 +139,6 @@ static void write_stlbe(struct kvmppc_vcpu_e500 *vcpu_e500, preempt_enable(); } -#ifdef CONFIG_KVM_E500V2 -/* XXX should be a hook in the gva2hpa translation */ -void kvmppc_map_magic(struct kvm_vcpu *vcpu) -{ - struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); - struct kvm_book3e_206_tlb_entry magic; - ulong shared_page = ((ulong)vcpu->arch.shared) & PAGE_MASK; - unsigned int stid; - kvm_pfn_t pfn; - - pfn = (kvm_pfn_t)virt_to_phys((void *)shared_page) >> PAGE_SHIFT; - get_page(pfn_to_page(pfn)); - - preempt_disable(); - stid = kvmppc_e500_get_sid(vcpu_e500, 0, 0, 0, 0); - - magic.mas1 = MAS1_VALID | MAS1_TS | MAS1_TID(stid) | - MAS1_TSIZE(BOOK3E_PAGESZ_4K); - magic.mas2 = vcpu->arch.magic_page_ea | MAS2_M; - magic.mas7_3 = ((u64)pfn << PAGE_SHIFT) | - MAS3_SW | MAS3_SR | MAS3_UW | MAS3_UR; - magic.mas8 = 0; - - __write_host_tlbe(&magic, MAS0_TLBSEL(1) | MAS0_ESEL(tlbcam_index), 0); - preempt_enable(); -} -#endif - void inval_gtlbe_on_host(struct kvmppc_vcpu_e500 *vcpu_e500, int tlbsel, int esel) { @@ -616,7 +574,6 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr, } } -#ifdef CONFIG_KVM_BOOKE_HV int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, enum instruction_fetch_type type, unsigned long *instr) { @@ -646,11 +603,7 @@ int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, mas1 = mfspr(SPRN_MAS1); mas2 = mfspr(SPRN_MAS2); mas3 = mfspr(SPRN_MAS3); -#ifdef CONFIG_64BIT mas7_mas3 = mfspr(SPRN_MAS7_MAS3); -#else - mas7_mas3 = ((u64)mfspr(SPRN_MAS7) << 32) | mas3; -#endif local_irq_restore(flags); /* @@ -706,13 +659,6 @@ int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, return EMULATE_DONE; } -#else -int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, - enum instruction_fetch_type type, unsigned long *instr) -{ - return EMULATE_AGAIN; -} -#endif /************* MMU Notifiers *************/ diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index e476e107a932..844b2d6b6b49 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c @@ -202,10 +202,7 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu) struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); vcpu->arch.shadow_epcr = SPRN_EPCR_DSIGS | SPRN_EPCR_DGTMI | \ - SPRN_EPCR_DUVD; -#ifdef CONFIG_64BIT - vcpu->arch.shadow_epcr |= SPRN_EPCR_ICM; -#endif + SPRN_EPCR_DUVD | SPRN_EPCR_ICM; vcpu->arch.shadow_msrp = MSRP_UCLEP | MSRP_PMMP; vcpu->arch.pvr = mfspr(SPRN_PVR); diff --git a/arch/powerpc/kvm/trace_booke.h b/arch/powerpc/kvm/trace_booke.h index eff6e82dbcd4..dbc54059327f 100644 --- a/arch/powerpc/kvm/trace_booke.h +++ b/arch/powerpc/kvm/trace_booke.h @@ -135,25 +135,11 @@ TRACE_EVENT(kvm_booke206_ref_release, __entry->pfn, __entry->flags) ); -#ifdef CONFIG_SPE_POSSIBLE -#define kvm_trace_symbol_irqprio_spe \ - {BOOKE_IRQPRIO_SPE_UNAVAIL, "SPE_UNAVAIL"}, \ - {BOOKE_IRQPRIO_SPE_FP_DATA, "SPE_FP_DATA"}, \ - {BOOKE_IRQPRIO_SPE_FP_ROUND, "SPE_FP_ROUND"}, -#else -#define kvm_trace_symbol_irqprio_spe -#endif - -#ifdef CONFIG_PPC_E500MC #define kvm_trace_symbol_irqprio_e500mc \ {BOOKE_IRQPRIO_ALTIVEC_UNAVAIL, "ALTIVEC_UNAVAIL"}, \ {BOOKE_IRQPRIO_ALTIVEC_ASSIST, "ALTIVEC_ASSIST"}, -#else -#define kvm_trace_symbol_irqprio_e500mc -#endif #define kvm_trace_symbol_irqprio \ - kvm_trace_symbol_irqprio_spe \ kvm_trace_symbol_irqprio_e500mc \ {BOOKE_IRQPRIO_DATA_STORAGE, "DATA_STORAGE"}, \ {BOOKE_IRQPRIO_INST_STORAGE, "INST_STORAGE"}, \