From patchwork Mon Jun 30 15:34:55 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mihai Caraman X-Patchwork-Id: 365658 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id F28AB140110 for ; Tue, 1 Jul 2014 01:35:42 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754381AbaF3Pfe (ORCPT ); Mon, 30 Jun 2014 11:35:34 -0400 Received: from mail-bl2lp0210.outbound.protection.outlook.com ([207.46.163.210]:52488 "EHLO na01-bl2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754360AbaF3Pfb (ORCPT ); Mon, 30 Jun 2014 11:35:31 -0400 Received: from CH1PR03CA004.namprd03.prod.outlook.com (10.255.156.149) by DM2PR03MB509.namprd03.prod.outlook.com (10.141.87.12) with Microsoft SMTP Server (TLS) id 15.0.974.11; Mon, 30 Jun 2014 15:35:09 +0000 Received: from BN1AFFO11FD021.protection.gbl (10.255.156.132) by CH1PR03CA004.outlook.office365.com (10.255.156.149) with Microsoft SMTP Server (TLS) id 15.0.974.11 via Frontend Transport; Mon, 30 Jun 2014 15:35:09 +0000 Received: from az84smr01.freescale.net (192.88.158.2) by BN1AFFO11FD021.mail.protection.outlook.com (10.58.52.81) with Microsoft SMTP Server (TLS) id 15.0.969.12 via Frontend Transport; Mon, 30 Jun 2014 15:35:09 +0000 Received: from fsr-fed1764-012.ea.freescale.net (fsr-fed1764-012-010171073213.ea.freescale.net [10.171.73.213]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id s5UFZ0Nh029673; Mon, 30 Jun 2014 08:35:06 -0700 From: Mihai Caraman To: CC: , , Mihai Caraman Subject: [PATCH 4/6 v2] KVM: PPC: Book3E: Add AltiVec support Date: Mon, 30 Jun 2014 18:34:55 +0300 Message-ID: <1404142497-6430-5-git-send-email-mihai.caraman@freescale.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1404142497-6430-1-git-send-email-mihai.caraman@freescale.com> References: <1404142497-6430-1-git-send-email-mihai.caraman@freescale.com> X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:192.88.158.2; CTRY:US; IPV:CAL; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(6009001)(199002)(189002)(74502001)(102836001)(83072002)(85852003)(85306003)(104166001)(62966002)(33646001)(86362001)(92566001)(48376002)(77982001)(20776003)(47776003)(92726001)(50466002)(76482001)(64706001)(93916002)(80022001)(50986999)(87936001)(88136002)(89996001)(26826002)(76176999)(79102001)(81342001)(81542001)(84676001)(46102001)(44976005)(99396002)(6806004)(19580395003)(83322001)(19580405001)(69596002)(68736004)(97736001)(104016002)(95666004)(36756003)(77156001)(2351001)(107046002)(229853001)(31966008)(87286001)(50226001)(4396001)(81156004)(74662001)(21056001)(106466001)(105606002)(211663006)(32563001); DIR:OUT; SFP:; SCL:1; SRVR:DM2PR03MB509; H:az84smr01.freescale.net; FPR:; MLV:ovrnspm; PTR:InfoDomainNonexistent; MX:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Antispam: BCL:0;PCL:0;RULEID: X-Forefront-PRVS: 0258E7CCD4 Received-SPF: Fail (: domain of freescale.com does not designate 192.88.158.2 as permitted sender) receiver=; client-ip=192.88.158.2; helo=az84smr01.freescale.net; Authentication-Results: spf=fail (sender IP is 192.88.158.2) smtp.mailfrom=mihai.caraman@freescale.com; X-OriginatorOrg: freescale.com Sender: kvm-ppc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org Add KVM Book3E AltiVec support. KVM Book3E FPU support gracefully reuse host infrastructure so follow the same approach for AltiVec. Signed-off-by: Mihai Caraman --- v2: - integrate Paul's FP/VMX/VSX changes arch/powerpc/kvm/booke.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 4cc9b26..4ba75f6 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -100,6 +100,19 @@ static inline bool kvmppc_supports_spe(void) return false; } +/* + * Always returns true if AltiVec unit is present, + * see kvmppc_core_check_processor_compat(). + */ +static inline bool kvmppc_supports_altivec(void) +{ +#ifdef CONFIG_ALTIVEC + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + return true; +#endif + return false; +} + #ifdef CONFIG_SPE void kvmppc_vcpu_disable_spe(struct kvm_vcpu *vcpu) { @@ -178,6 +191,40 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu *vcpu) #endif } +/* + * Simulate AltiVec unavailable fault to load guest state + * from thread to AltiVec unit. + * It requires to be called with preemption disabled. + */ +static inline void kvmppc_load_guest_altivec(struct kvm_vcpu *vcpu) +{ +#ifdef CONFIG_ALTIVEC + if (kvmppc_supports_altivec()) { + if (!(current->thread.regs->msr & MSR_VEC)) { + enable_kernel_altivec(); + load_vr_state(&vcpu->arch.vr); + current->thread.vr_save_area = &vcpu->arch.vr; + current->thread.regs->msr |= MSR_VEC; + } + } +#endif +} + +/* + * Save guest vcpu AltiVec state into thread. + * It requires to be called with preemption disabled. + */ +static inline void kvmppc_save_guest_altivec(struct kvm_vcpu *vcpu) +{ +#ifdef CONFIG_ALTIVEC + if (kvmppc_supports_altivec()) { + if (current->thread.regs->msr & MSR_VEC) + giveup_altivec(current); + current->thread.vr_save_area = NULL; + } +#endif +} + static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu) { /* Synchronize guest's desire to get debug interrupts into shadow MSR */ @@ -749,6 +796,17 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) kvmppc_load_guest_fp(vcpu); #endif +#ifdef CONFIG_ALTIVEC + /* Save userspace AltiVec state in stack */ + if (kvmppc_supports_altivec()) + enable_kernel_altivec(); + /* + * Since we can't trap on MSR_VEC in GS-mode, we consider the guest + * as always using the AltiVec. + */ + kvmppc_load_guest_altivec(vcpu); +#endif + /* Switch to guest debug context */ debug = vcpu->arch.shadow_dbg_reg; switch_booke_debug_regs(&debug); @@ -771,6 +829,10 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) kvmppc_save_guest_fp(vcpu); #endif +#ifdef CONFIG_ALTIVEC + kvmppc_save_guest_altivec(vcpu); +#endif + out: vcpu->mode = OUTSIDE_GUEST_MODE; return ret; @@ -1014,7 +1076,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, break; case BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL: { - if (kvmppc_supports_spe()) { + if (kvmppc_supports_spe() || kvmppc_supports_altivec()) { bool enabled = false; #if !defined(CONFIG_KVM_BOOKE_HV) && defined(CONFIG_SPE) @@ -1040,7 +1102,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, } case BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST: - if (kvmppc_supports_spe()) { + if (kvmppc_supports_spe() || kvmppc_supports_altivec()) { kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_DATA_ALTIVEC_ASSIST); r = RESUME_GUEST; @@ -1249,6 +1311,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, /* interrupts now hard-disabled */ kvmppc_fix_ee_before_entry(); kvmppc_load_guest_fp(vcpu); + kvmppc_load_guest_altivec(vcpu); } }