From patchwork Mon Jun 3 20:54:24 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mihai Caraman X-Patchwork-Id: 2655091 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 81981DFE82 for ; Mon, 3 Jun 2013 20:54:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758531Ab3FCUys (ORCPT ); Mon, 3 Jun 2013 16:54:48 -0400 Received: from co9ehsobe005.messaging.microsoft.com ([207.46.163.28]:41599 "EHLO co9outboundpool.messaging.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757435Ab3FCUyp (ORCPT ); Mon, 3 Jun 2013 16:54:45 -0400 Received: from mail134-co9-R.bigfish.com (10.236.132.249) by CO9EHSOBE014.bigfish.com (10.236.130.77) with Microsoft SMTP Server id 14.1.225.23; Mon, 3 Jun 2013 20:54:44 +0000 Received: from mail134-co9 (localhost [127.0.0.1]) by mail134-co9-R.bigfish.com (Postfix) with ESMTP id 4B378480715; Mon, 3 Jun 2013 20:54:44 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 4 X-BigFish: VS4(zcb8k551bizzz1f42h1ee6h1de0h1fdah1202h1e76h1d1ah1d2ah1fc6hzz8275bhz2dh2a8h668h839hd24he5bhf0ah1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1ad9h1b0ah1d0ch1d2eh1d3fh1dfeh1dffh1155h) Received: from mail134-co9 (localhost.localdomain [127.0.0.1]) by mail134-co9 (MessageSwitch) id 1370292882145590_2276; Mon, 3 Jun 2013 20:54:42 +0000 (UTC) Received: from CO9EHSMHS015.bigfish.com (unknown [10.236.132.250]) by mail134-co9.bigfish.com (Postfix) with ESMTP id 15F8F3C0281; Mon, 3 Jun 2013 20:54:42 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by CO9EHSMHS015.bigfish.com (10.236.130.25) with Microsoft SMTP Server (TLS) id 14.1.225.23; Mon, 3 Jun 2013 20:54:35 +0000 Received: from az84smr01.freescale.net (10.64.34.197) by 039-SN1MMR1-005.039d.mgd.msft.net (10.84.1.17) with Microsoft SMTP Server (TLS) id 14.2.328.11; Mon, 3 Jun 2013 20:55:43 +0000 Received: from mcaraman-VirtualBox.ea.freescale.net (mcaraman-VirtualBox.ea.freescale.net [10.171.73.14]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id r53KsSWo030131; Mon, 3 Jun 2013 13:54:32 -0700 From: Mihai Caraman To: CC: , , Mihai Caraman Subject: [RFC PATCH 2/6] KVM: PPC: Book3E: Refactor SPE_FP exit handling Date: Mon, 3 Jun 2013 23:54:24 +0300 Message-ID: <1370292868-2697-3-git-send-email-mihai.caraman@freescale.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1370292868-2697-1-git-send-email-mihai.caraman@freescale.com> References: <1370292868-2697-1-git-send-email-mihai.caraman@freescale.com> MIME-Version: 1.0 X-OriginatorOrg: freescale.com Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org SPE_FP interrupts are shared with ALTIVEC. Refactor SPE_FP exit handling to detect KVM support for the featured unit at run-time, in order to accommodate ALTIVEC later. Signed-off-by: Mihai Caraman --- arch/powerpc/kvm/booke.c | 80 ++++++++++++++++++++++++++++++++++------------ 1 files changed, 59 insertions(+), 21 deletions(-) diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 1020119..d082bbc 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -822,6 +822,15 @@ static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu, } } +static inline bool kvmppc_supports_spe(void) +{ +#ifdef CONFIG_SPE + if (cpu_has_feature(CPU_FTR_SPE)) + return true; +#endif + return false; +} + /** * kvmppc_handle_exit * @@ -931,42 +940,71 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, 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); + /* + * The interrupt is shared, KVM support for the featured unit + * is detected at run-time. + */ + bool handled = false; + + if (kvmppc_supports_spe()) { +#ifdef CONFIG_SPE + if (cpu_has_feature(CPU_FTR_SPE)) + if (vcpu->arch.shared->msr & MSR_SPE) { + kvmppc_vcpu_enable_spe(vcpu); + handled = true; + } +#endif + if (!handled) + kvmppc_booke_queue_irqprio(vcpu, + BOOKE_IRQPRIO_SPE_UNAVAIL); + } else { + /* + * 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; } case BOOKE_INTERRUPT_SPE_FP_DATA: - kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_DATA); - r = RESUME_GUEST; + /* + * The interrupt is shared, KVM support for the featured unit + * is detected at run-time. + */ + if (kvmppc_supports_spe()) { + kvmppc_booke_queue_irqprio(vcpu, + BOOKE_IRQPRIO_SPE_FP_DATA); + r = RESUME_GUEST; + } else { + /* + * These really should never happen without CONFIG_SPE, + * as we should never enable the real MSR[SPE] in the + * guest. + */ + printk(KERN_CRIT "%s: unexpected SPE interrupt %u at \ + %08lx\n", __func__, exit_nr, vcpu->arch.pc); + run->hw.hardware_exit_reason = exit_nr; + r = RESUME_HOST; + } + break; case BOOKE_INTERRUPT_SPE_FP_ROUND: +#ifdef CONFIG_SPE kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_ROUND); r = RESUME_GUEST; break; #else - case BOOKE_INTERRUPT_SPE_UNAVAIL: /* - * Guest wants SPE, but host kernel doesn't support it. Send - * an "unimplemented operation" program check to the guest. + * These really should never happen without CONFIG_SPE, + * as we should never enable the real MSR[SPE] in 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.pc); run->hw.hardware_exit_reason = exit_nr;