From patchwork Thu Jan 5 09:06:52 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liu Yu-B13201 X-Patchwork-Id: 134452 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 8DF5A100842 for ; Thu, 5 Jan 2012 20:57:33 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754820Ab2AEJ5b (ORCPT ); Thu, 5 Jan 2012 04:57:31 -0500 Received: from tx2ehsobe004.messaging.microsoft.com ([65.55.88.14]:14430 "EHLO TX2EHSOBE009.bigfish.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751300Ab2AEJ53 (ORCPT ); Thu, 5 Jan 2012 04:57:29 -0500 Received: from mail50-tx2-R.bigfish.com (10.9.14.254) by TX2EHSOBE009.bigfish.com (10.9.40.29) with Microsoft SMTP Server id 14.1.225.23; Thu, 5 Jan 2012 09:57:29 +0000 Received: from mail50-tx2 (localhost [127.0.0.1]) by mail50-tx2-R.bigfish.com (Postfix) with ESMTP id EDCDE680099; Thu, 5 Jan 2012 09:57:28 +0000 (UTC) X-SpamScore: 0 X-BigFish: VS0(zzzz1202hzz8275bhz2dh2a8h668h839h66h) X-Spam-TCS-SCL: 5:0 X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI Received: from mail50-tx2 (localhost.localdomain [127.0.0.1]) by mail50-tx2 (MessageSwitch) id 1325757448553669_23667; Thu, 5 Jan 2012 09:57:28 +0000 (UTC) Received: from TX2EHSMHS019.bigfish.com (unknown [10.9.14.238]) by mail50-tx2.bigfish.com (Postfix) with ESMTP id 75CF650004A; Thu, 5 Jan 2012 09:57:28 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by TX2EHSMHS019.bigfish.com (10.9.99.119) with Microsoft SMTP Server (TLS) id 14.1.225.23; Thu, 5 Jan 2012 09:57:28 +0000 Received: from az33smr02.freescale.net (10.64.34.200) by 039-SN1MMR1-001.039d.mgd.msft.net (10.84.1.13) with Microsoft SMTP Server id 14.1.355.3; Thu, 5 Jan 2012 03:57:27 -0600 Received: from localhost (rock.ap.freescale.net [10.193.20.106]) by az33smr02.freescale.net (8.13.1/8.13.0) with ESMTP id q059vQqm029343; Thu, 5 Jan 2012 03:57:27 -0600 (CST) From: Liu Yu To: , , CC: , , , , Liu Yu Subject: [PATCH v2 3/3] KVM: PPC: epapr: install ev_idle hcall for e500 guest Date: Thu, 5 Jan 2012 17:06:52 +0800 Message-ID: <1325754412-29963-2-git-send-email-yu.liu@freescale.com> X-Mailer: git-send-email 1.6.4 In-Reply-To: <1325754412-29963-1-git-send-email-yu.liu@freescale.com> References: <1325754412-29963-1-git-send-email-yu.liu@freescale.com> MIME-Version: 1.0 X-OriginatorOrg: freescale.com Sender: kvm-ppc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org If the guest hypervisor node contains "has-idle" property. Signed-off-by: Liu Yu --- v2: 1. move the idle code into assembly. 2. move the part that check "has-idle" into epapr code. arch/powerpc/include/asm/epapr_hcalls.h | 1 + arch/powerpc/include/asm/machdep.h | 5 +++++ arch/powerpc/kernel/epapr_para.c | 4 ++++ arch/powerpc/kernel/idle_e500.S | 17 +++++++++++++++++ arch/powerpc/kernel/kvm.c | 24 ++++++++++++++++++++++++ 5 files changed, 51 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/epapr_hcalls.h b/arch/powerpc/include/asm/epapr_hcalls.h index c4b86e4..566805e 100644 --- a/arch/powerpc/include/asm/epapr_hcalls.h +++ b/arch/powerpc/include/asm/epapr_hcalls.h @@ -150,6 +150,7 @@ extern u32 *epapr_hcall_insts; extern int epapr_hcall_insts_len; +extern bool epapr_hcall_has_idle; static inline void epapr_get_hcall_insts(u32 **instp, int *lenp) { diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 47cacdd..7e56abf 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -255,6 +255,11 @@ extern void power4_idle(void); extern void power7_idle(void); extern void ppc6xx_idle(void); extern void book3e_idle(void); +#ifdef CONFIG_KVM_GUEST +extern void e500_ev_idle(unsigned long *, unsigned long *, unsigned long, + unsigned long (*)(unsigned long *, unsigned long *, + unsigned long)); +#endif /* * ppc_md contains a copy of the machine description structure for the diff --git a/arch/powerpc/kernel/epapr_para.c b/arch/powerpc/kernel/epapr_para.c index 714dcb3..1f37ddf 100644 --- a/arch/powerpc/kernel/epapr_para.c +++ b/arch/powerpc/kernel/epapr_para.c @@ -22,6 +22,7 @@ u32 *epapr_hcall_insts; int epapr_hcall_insts_len; +bool epapr_hcall_has_idle; static int __init epapr_para_init(void) { @@ -39,6 +40,9 @@ static int __init epapr_para_init(void) epapr_hcall_insts_len = len; } + if (of_get_property(hyper_node, "has-idle", NULL)) + epapr_hcall_has_idle = true; + return 0; } diff --git a/arch/powerpc/kernel/idle_e500.S b/arch/powerpc/kernel/idle_e500.S index 3e2b95c..6ea95f0 100644 --- a/arch/powerpc/kernel/idle_e500.S +++ b/arch/powerpc/kernel/idle_e500.S @@ -85,6 +85,23 @@ END_FTR_SECTION_IFSET(CPU_FTR_L2CSR|CPU_FTR_CAN_NAP) 2: b 2b #endif /* !E500MC */ +#ifdef CONFIG_KVM_GUEST +/* + * r3 contains the pointer to in[8] + * r4 contains the pointer to out[8] + * r5 contains the hcall vendor and nr + * r6 contains the handler which send hcall + */ +_GLOBAL(e500_ev_idle) + rlwinm r7,r1,0,0,31-THREAD_SHIFT /* current thread_info */ + lwz r8,TI_LOCAL_FLAGS(r7) /* set napping bit */ + ori r8,r8,_TLF_NAPPING /* so when we take an exception */ + stw r8,TI_LOCAL_FLAGS(r7) /* it will return to our caller */ + wrteei 1 + mtctr r6 + bctr +#endif /* KVM_GUEST */ + /* * Return from NAP/DOZE mode, restore some CPU specific registers, * r2 containing physical address of current. diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c index 82a9137..8952e12 100644 --- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c @@ -29,6 +29,7 @@ #include #include #include +#include #define KVM_MAGIC_PAGE (-4096L) #define magic_var(x) KVM_MAGIC_PAGE + offsetof(struct kvm_vcpu_arch_shared, x) @@ -578,6 +579,25 @@ static __init void kvm_free_tmp(void) } } +static void kvm_hcall_idle(void) +{ +#ifdef CONFIG_KVM_E500 + ulong in[8]; + ulong out[8]; + + e500_ev_idle(in, out, HC_VENDOR_EPAPR | HC_EV_IDLE, kvm_hypercall); +#endif +} + +static bool kvm_para_has_idle(void) +{ +#ifdef CONFIG_BOOKE + return epapr_hcall_has_idle; +#else + return false; +#endif +} + static int __init kvm_guest_init(void) { if (!kvm_para_available()) @@ -594,6 +614,10 @@ static int __init kvm_guest_init(void) powersave_nap = 1; #endif + /* Install hcall based power_save for guest kernel */ + if (kvm_para_has_idle()) + ppc_md.power_save = kvm_hcall_idle; + free_tmp: kvm_free_tmp();