diff mbox

[v3,1/3] KVM: PPC: epapr: Factor out the epapr init

Message ID 1328868141-17364-1-git-send-email-yu.liu@freescale.com (mailing list archive)
State Not Applicable
Headers show

Commit Message

Liu Yu-B13201 Feb. 10, 2012, 10:02 a.m. UTC
from the kvm guest paravirt init code.

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
v3:
apply the epapr init for all ppc platform

 arch/powerpc/Kconfig                    |    4 +++
 arch/powerpc/include/asm/epapr_hcalls.h |    8 +++++
 arch/powerpc/kernel/Makefile            |    1 +
 arch/powerpc/kernel/epapr_para.c        |   46 +++++++++++++++++++++++++++++++
 arch/powerpc/kernel/kvm.c               |   13 +++------
 arch/powerpc/kvm/Kconfig                |    1 +
 6 files changed, 64 insertions(+), 9 deletions(-)
 create mode 100644 arch/powerpc/kernel/epapr_para.c

Comments

Scott Wood Feb. 10, 2012, 6:39 p.m. UTC | #1
On 02/10/2012 04:02 AM, Liu Yu wrote:
> from the kvm guest paravirt init code.
> 
> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> ---
> v3:
> apply the epapr init for all ppc platform
> 
>  arch/powerpc/Kconfig                    |    4 +++
>  arch/powerpc/include/asm/epapr_hcalls.h |    8 +++++
>  arch/powerpc/kernel/Makefile            |    1 +
>  arch/powerpc/kernel/epapr_para.c        |   46 +++++++++++++++++++++++++++++++
>  arch/powerpc/kernel/kvm.c               |   13 +++------
>  arch/powerpc/kvm/Kconfig                |    1 +
>  6 files changed, 64 insertions(+), 9 deletions(-)
>  create mode 100644 arch/powerpc/kernel/epapr_para.c
> 
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 47682b6..00bd508 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -196,6 +196,10 @@ config EPAPR_BOOT
>  	  Used to allow a board to specify it wants an ePAPR compliant wrapper.
>  	default n
>  
> +config EPAPR_PARA
> +	bool
> +	default n

EPAPR_PARAVIRT

>  config DEFAULT_UIMAGE
>  	bool
>  	help
> diff --git a/arch/powerpc/include/asm/epapr_hcalls.h b/arch/powerpc/include/asm/epapr_hcalls.h
> index f3b0c2c..c4b86e4 100644
> --- a/arch/powerpc/include/asm/epapr_hcalls.h
> +++ b/arch/powerpc/include/asm/epapr_hcalls.h
> @@ -148,6 +148,14 @@
>  #define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5"
>  #define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4"
>  
> +extern u32 *epapr_hcall_insts;
> +extern int epapr_hcall_insts_len;
> +
> +static inline void epapr_get_hcall_insts(u32 **instp, int *lenp)
> +{
> +	*instp = epapr_hcall_insts;
> +	*lenp = epapr_hcall_insts_len;
> +}

Why do we need a function for this?  Why is the public interface
anything other than "invoke a hypercall"?

> +static int __init epapr_para_init(void)
> +{
> +	struct device_node *hyper_node;
> +	u32 *insts;
> +	int len;
> +
> +	hyper_node = of_find_node_by_path("/hypervisor");
> +	if (!hyper_node)
> +		return -ENODEV;
> +
> +	insts = (u32*)of_get_property(hyper_node, "hcall-instructions", &len);

Do not cast away that const.

> @@ -535,18 +536,12 @@ EXPORT_SYMBOL_GPL(kvm_hypercall);
>  static int kvm_para_setup(void)
>  {
>  	extern u32 kvm_hypercall_start;
> -	struct device_node *hyper_node;
>  	u32 *insts;
>  	int len, i;
>  
> -	hyper_node = of_find_node_by_path("/hypervisor");
> -	if (!hyper_node)
> -		return -1;
> -
> -	insts = (u32*)of_get_property(hyper_node, "hcall-instructions", &len);
> -	if (len % 4)
> -		return -1;
> -	if (len > (4 * 4))
> +	insts = epapr_hcall_insts;
> +	len = epapr_hcall_insts_len;
> +	if (insts == NULL)
>  		return -1;
>  
>  	for (i = 0; i < (len / 4); i++)

Why are you still doing the patching inside kvm.c?

-Scott
Liu Yu-B13201 Feb. 13, 2012, 5:47 a.m. UTC | #2
> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Saturday, February 11, 2012 2:40 AM
> To: Liu Yu-B13201
> Cc: agraf@suse.de; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org;
> linuxppc-dev@ozlabs.org; Wood Scott-B07421
> Subject: Re: [PATCH v3 1/3] KVM: PPC: epapr: Factor out the epapr init
> 
> On 02/10/2012 04:02 AM, Liu Yu wrote:
> > from the kvm guest paravirt init code.
> >
> > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > ---
> > v3:
> > apply the epapr init for all ppc platform
> >
> >  arch/powerpc/Kconfig                    |    4 +++
> >  arch/powerpc/include/asm/epapr_hcalls.h |    8 +++++
> >  arch/powerpc/kernel/Makefile            |    1 +
> >  arch/powerpc/kernel/epapr_para.c        |   46
> +++++++++++++++++++++++++++++++
> >  arch/powerpc/kernel/kvm.c               |   13 +++------
> >  arch/powerpc/kvm/Kconfig                |    1 +
> >  6 files changed, 64 insertions(+), 9 deletions(-)  create mode 100644
> > arch/powerpc/kernel/epapr_para.c
> >
> > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index
> > 47682b6..00bd508 100644
> > --- a/arch/powerpc/Kconfig
> > +++ b/arch/powerpc/Kconfig
> > @@ -196,6 +196,10 @@ config EPAPR_BOOT
> >  	  Used to allow a board to specify it wants an ePAPR compliant
> wrapper.
> >  	default n
> >
> > +config EPAPR_PARA
> > +	bool
> > +	default n
> 
> EPAPR_PARAVIRT
> 
> >  config DEFAULT_UIMAGE
> >  	bool
> >  	help
> > diff --git a/arch/powerpc/include/asm/epapr_hcalls.h
> > b/arch/powerpc/include/asm/epapr_hcalls.h
> > index f3b0c2c..c4b86e4 100644
> > --- a/arch/powerpc/include/asm/epapr_hcalls.h
> > +++ b/arch/powerpc/include/asm/epapr_hcalls.h
> > @@ -148,6 +148,14 @@
> >  #define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5"
> >  #define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4"
> >
> > +extern u32 *epapr_hcall_insts;
> > +extern int epapr_hcall_insts_len;
> > +
> > +static inline void epapr_get_hcall_insts(u32 **instp, int *lenp) {
> > +	*instp = epapr_hcall_insts;
> > +	*lenp = epapr_hcall_insts_len;
> > +}
> 
> Why do we need a function for this?  Why is the public interface anything
> other than "invoke a hypercall"?
> 
> > +static int __init epapr_para_init(void) {
> > +	struct device_node *hyper_node;
> > +	u32 *insts;
> > +	int len;
> > +
> > +	hyper_node = of_find_node_by_path("/hypervisor");
> > +	if (!hyper_node)
> > +		return -ENODEV;
> > +
> > +	insts = (u32*)of_get_property(hyper_node, "hcall-instructions",
> > +&len);
> 
> Do not cast away that const.
> 
> > @@ -535,18 +536,12 @@ EXPORT_SYMBOL_GPL(kvm_hypercall);  static int
> > kvm_para_setup(void)  {
> >  	extern u32 kvm_hypercall_start;
> > -	struct device_node *hyper_node;
> >  	u32 *insts;
> >  	int len, i;
> >
> > -	hyper_node = of_find_node_by_path("/hypervisor");
> > -	if (!hyper_node)
> > -		return -1;
> > -
> > -	insts = (u32*)of_get_property(hyper_node, "hcall-instructions",
> &len);
> > -	if (len % 4)
> > -		return -1;
> > -	if (len > (4 * 4))
> > +	insts = epapr_hcall_insts;
> > +	len = epapr_hcall_insts_len;
> > +	if (insts == NULL)
> >  		return -1;
> >
> >  	for (i = 0; i < (len / 4); i++)
> 
> Why are you still doing the patching inside kvm.c?
> 

Do you mean we should move kvm_hypercall_start() into epapr bit?

Thanks,
Yu
Scott Wood Feb. 13, 2012, 5:15 p.m. UTC | #3
On 02/12/2012 11:47 PM, Liu Yu-B13201 wrote:
> 
> 
>> -----Original Message-----
>> From: Wood Scott-B07421
>> Sent: Saturday, February 11, 2012 2:40 AM
>> To: Liu Yu-B13201
>> Cc: agraf@suse.de; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org;
>> linuxppc-dev@ozlabs.org; Wood Scott-B07421
>> Subject: Re: [PATCH v3 1/3] KVM: PPC: epapr: Factor out the epapr init
>>
>> Why are you still doing the patching inside kvm.c?
>>
> 
> Do you mean we should move kvm_hypercall_start() into epapr bit?

Yes.  This is an ePAPR mechanism; KVM just happens to be a user of it.

We should also update arch/powerpc/include/asm/epapr_hcalls.h to use
this mechanism.

-Scott
diff mbox

Patch

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 47682b6..00bd508 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -196,6 +196,10 @@  config EPAPR_BOOT
 	  Used to allow a board to specify it wants an ePAPR compliant wrapper.
 	default n
 
+config EPAPR_PARA
+	bool
+	default n
+
 config DEFAULT_UIMAGE
 	bool
 	help
diff --git a/arch/powerpc/include/asm/epapr_hcalls.h b/arch/powerpc/include/asm/epapr_hcalls.h
index f3b0c2c..c4b86e4 100644
--- a/arch/powerpc/include/asm/epapr_hcalls.h
+++ b/arch/powerpc/include/asm/epapr_hcalls.h
@@ -148,6 +148,14 @@ 
 #define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5"
 #define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4"
 
+extern u32 *epapr_hcall_insts;
+extern int epapr_hcall_insts_len;
+
+static inline void epapr_get_hcall_insts(u32 **instp, int *lenp)
+{
+	*instp = epapr_hcall_insts;
+	*lenp = epapr_hcall_insts_len;
+}
 
 /*
  * We use "uintptr_t" to define a register because it's guaranteed to be a
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index ce4f7f1..1e41c76 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -134,6 +134,7 @@  ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC),)
 obj-y				+= ppc_save_regs.o
 endif
 
+obj-$(CONFIG_EPAPR_PARA)	+= epapr_para.o
 obj-$(CONFIG_KVM_GUEST)		+= kvm.o kvm_emul.o
 
 # Disable GCOV in odd or sensitive code
diff --git a/arch/powerpc/kernel/epapr_para.c b/arch/powerpc/kernel/epapr_para.c
new file mode 100644
index 0000000..7e1561a
--- /dev/null
+++ b/arch/powerpc/kernel/epapr_para.c
@@ -0,0 +1,46 @@ 
+/*
+ * ePAPR para-virtualization support.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ */
+
+#include <linux/of.h>
+#include <asm/epapr_hcalls.h>
+#include <asm/cacheflush.h>
+
+u32 *epapr_hcall_insts;
+int epapr_hcall_insts_len;
+
+static int __init epapr_para_init(void)
+{
+	struct device_node *hyper_node;
+	u32 *insts;
+	int len;
+
+	hyper_node = of_find_node_by_path("/hypervisor");
+	if (!hyper_node)
+		return -ENODEV;
+
+	insts = (u32*)of_get_property(hyper_node, "hcall-instructions", &len);
+	if (!(len % 4) && (len >= (4 * 4))) {
+		epapr_hcall_insts = insts;
+		epapr_hcall_insts_len = len;
+	}
+
+	return 0;
+}
+
+early_initcall(epapr_para_init);
diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
index b06bdae..2e03ab8 100644
--- a/arch/powerpc/kernel/kvm.c
+++ b/arch/powerpc/kernel/kvm.c
@@ -28,6 +28,7 @@ 
 #include <asm/sections.h>
 #include <asm/cacheflush.h>
 #include <asm/disassemble.h>
+#include <asm/epapr_hcalls.h>
 
 #define KVM_MAGIC_PAGE		(-4096L)
 #define magic_var(x) KVM_MAGIC_PAGE + offsetof(struct kvm_vcpu_arch_shared, x)
@@ -535,18 +536,12 @@  EXPORT_SYMBOL_GPL(kvm_hypercall);
 static int kvm_para_setup(void)
 {
 	extern u32 kvm_hypercall_start;
-	struct device_node *hyper_node;
 	u32 *insts;
 	int len, i;
 
-	hyper_node = of_find_node_by_path("/hypervisor");
-	if (!hyper_node)
-		return -1;
-
-	insts = (u32*)of_get_property(hyper_node, "hcall-instructions", &len);
-	if (len % 4)
-		return -1;
-	if (len > (4 * 4))
+	insts = epapr_hcall_insts;
+	len = epapr_hcall_insts_len;
+	if (insts == NULL)
 		return -1;
 
 	for (i = 0; i < (len / 4); i++)
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 78133de..cd1ee68 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -20,6 +20,7 @@  config KVM
 	bool
 	select PREEMPT_NOTIFIERS
 	select ANON_INODES
+	select EPAPR_PARA
 
 config KVM_BOOK3S_HANDLER
 	bool