diff mbox

[v5,3/3] xen/arm: introduce xen_early_init, use PSCI on xen

Message ID 1364919374-7836-3-git-send-email-stefano.stabellini@eu.citrix.com (mailing list archive)
State New, archived
Headers show

Commit Message

Stefano Stabellini April 2, 2013, 4:16 p.m. UTC
Split xen_guest_init in two functions, one of them (xen_early_init) is
going to be called very early from setup_arch.

Change machine_desc->smp_init to xen_smp_init if Xen is present on the
platform. xen_smp_init just sets smp_ops to psci_smp_ops.

Introduce a dependency for ARM_PSCI in XEN.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 arch/arm/Kconfig                      |    1 +
 arch/arm/include/asm/xen/hypervisor.h |    6 ++++++
 arch/arm/kernel/setup.c               |    3 +++
 arch/arm/xen/enlighten.c              |   27 ++++++++++++++++++++-------
 4 files changed, 30 insertions(+), 7 deletions(-)

Comments

Nicolas Pitre April 2, 2013, 5:34 p.m. UTC | #1
On Tue, 2 Apr 2013, Stefano Stabellini wrote:

> Split xen_guest_init in two functions, one of them (xen_early_init) is
> going to be called very early from setup_arch.
> 
> Change machine_desc->smp_init to xen_smp_init if Xen is present on the
> platform. xen_smp_init just sets smp_ops to psci_smp_ops.
> 
> Introduce a dependency for ARM_PSCI in XEN.

The Kconfig stuff should be more understandable to "normal" users 
configuring the kernel.  Hence it might make more sense for Xen to 
select PSCI rather than making it a prerequisite.

[...]
> @@ -176,27 +178,30 @@ static int __init xen_secondary_init(unsigned int cpu)
>  	return 0;
>  }
>  
> +static void __init xen_smp_init(void)
> +{
> +	if (psci_smp_available())
> +		smp_set_ops(&psci_smp_ops);
> +}
> +

I still don't understand why you need to do this.  Why can't you just 
rely on the next priority which is to set PSCI ops by default if 
available?  Using this hook for Xen doesn't look justified. As it is, 
you break MCPM.

As I explained to you, MCPM will end up using PSCI as well when 
available, which I think should be sufficient for your concern.


Nicolas
Stefano Stabellini April 3, 2013, 11:28 a.m. UTC | #2
On Tue, 2 Apr 2013, Nicolas Pitre wrote:
> On Tue, 2 Apr 2013, Stefano Stabellini wrote:
> 
> > Split xen_guest_init in two functions, one of them (xen_early_init) is
> > going to be called very early from setup_arch.
> > 
> > Change machine_desc->smp_init to xen_smp_init if Xen is present on the
> > platform. xen_smp_init just sets smp_ops to psci_smp_ops.
> > 
> > Introduce a dependency for ARM_PSCI in XEN.
> 
> The Kconfig stuff should be more understandable to "normal" users 
> configuring the kernel.  Hence it might make more sense for Xen to 
> select PSCI rather than making it a prerequisite.

You are right, I'll do that.


> [...]
> > @@ -176,27 +178,30 @@ static int __init xen_secondary_init(unsigned int cpu)
> >  	return 0;
> >  }
> >  
> > +static void __init xen_smp_init(void)
> > +{
> > +	if (psci_smp_available())
> > +		smp_set_ops(&psci_smp_ops);
> > +}
> > +
> 
> I still don't understand why you need to do this.  Why can't you just 
> rely on the next priority which is to set PSCI ops by default if 
> available?  Using this hook for Xen doesn't look justified. As it is, 
> you break MCPM.
> 
> As I explained to you, MCPM will end up using PSCI as well when 
> available, which I think should be sufficient for your concern.

The smp_init hook is not limited to MCPM or the versatile express
platform. It's a generic hook that can be used by any platform and can
override the platform smp_ops or the psci_smp_ops depending on platform
specific configurations.

Configurations that I am pretty sure won't be available on Xen anyway,
while I am certain that using psci_smp_ops would work.

It seems to me that relying on the fact that only versatile express and
only MCPM use smp_init, even though it might work today, it's very
fragile and could break tomorrow without any of us noticing.
Nicolas Pitre April 3, 2013, 2 p.m. UTC | #3
On Wed, 3 Apr 2013, Stefano Stabellini wrote:

> On Tue, 2 Apr 2013, Nicolas Pitre wrote:
> > On Tue, 2 Apr 2013, Stefano Stabellini wrote:
> > 
> > > @@ -176,27 +178,30 @@ static int __init xen_secondary_init(unsigned int cpu)
> > >  	return 0;
> > >  }
> > >  
> > > +static void __init xen_smp_init(void)
> > > +{
> > > +	if (psci_smp_available())
> > > +		smp_set_ops(&psci_smp_ops);
> > > +}
> > > +
> > 
> > I still don't understand why you need to do this.  Why can't you just 
> > rely on the next priority which is to set PSCI ops by default if 
> > available?  Using this hook for Xen doesn't look justified. As it is, 
> > you break MCPM.
> > 
> > As I explained to you, MCPM will end up using PSCI as well when 
> > available, which I think should be sufficient for your concern.
> 
> The smp_init hook is not limited to MCPM or the versatile express
> platform. It's a generic hook that can be used by any platform and can
> override the platform smp_ops or the psci_smp_ops depending on platform
> specific configurations.
> 
> Configurations that I am pretty sure won't be available on Xen anyway,
> while I am certain that using psci_smp_ops would work.
> 
> It seems to me that relying on the fact that only versatile express and
> only MCPM use smp_init, even though it might work today, it's very
> fragile and could break tomorrow without any of us noticing.

I claim: this breaks MCPM today.

You claim: the alternative _could_ break with Xen tomorrow.

Could we please wait until there is an actual problem with Xen before 
being overly defensive in the code?


Nicolas
Stefano Stabellini April 3, 2013, 2:47 p.m. UTC | #4
On Wed, 3 Apr 2013, Nicolas Pitre wrote:
> On Wed, 3 Apr 2013, Stefano Stabellini wrote:
> 
> > On Tue, 2 Apr 2013, Nicolas Pitre wrote:
> > > On Tue, 2 Apr 2013, Stefano Stabellini wrote:
> > > 
> > > > @@ -176,27 +178,30 @@ static int __init xen_secondary_init(unsigned int cpu)
> > > >  	return 0;
> > > >  }
> > > >  
> > > > +static void __init xen_smp_init(void)
> > > > +{
> > > > +	if (psci_smp_available())
> > > > +		smp_set_ops(&psci_smp_ops);
> > > > +}
> > > > +
> > > 
> > > I still don't understand why you need to do this.  Why can't you just 
> > > rely on the next priority which is to set PSCI ops by default if 
> > > available?  Using this hook for Xen doesn't look justified. As it is, 
> > > you break MCPM.
> > > 
> > > As I explained to you, MCPM will end up using PSCI as well when 
> > > available, which I think should be sufficient for your concern.
> > 
> > The smp_init hook is not limited to MCPM or the versatile express
> > platform. It's a generic hook that can be used by any platform and can
> > override the platform smp_ops or the psci_smp_ops depending on platform
> > specific configurations.
> > 
> > Configurations that I am pretty sure won't be available on Xen anyway,
> > while I am certain that using psci_smp_ops would work.
> > 
> > It seems to me that relying on the fact that only versatile express and
> > only MCPM use smp_init, even though it might work today, it's very
> > fragile and could break tomorrow without any of us noticing.
> 
> I claim: this breaks MCPM today.
>
> You claim: the alternative _could_ break with Xen tomorrow.
> 
> Could we please wait until there is an actual problem with Xen before 
> being overly defensive in the code?

Sorry, I realized that I should have explained myself better.

The smp_init patch together with the MCPM patch series
(http://marc.info/?l=linux-arm-kernel&m=136004188122492) breaks Xen Dom0
SMP support on versatile express *today* (ifndef CONFIG_CLUSTER_PM):
smp_init is not NULL on versatile express anymore therefore smp_init is
going to be called, causing vexpress_smp_ops to be selected even if psci
is on device tree.

On the other hand if this patch was applied, xen_smp_init would override
smp_init making sure that psci_smp_ops is used on Xen and everything
would work as expected.


So as it stands today, we need this patch for regular Xen Dom0 SMP
support.


BTW I have actually tried it on my versatile express machine to make
sure that it is correct :)
diff mbox

Patch

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2c3bdce..66658d3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1891,6 +1891,7 @@  config XEN
 	bool "Xen guest support on ARM (EXPERIMENTAL)"
 	depends on ARM && AEABI && OF
 	depends on CPU_V7 && !CPU_V6
+	depends on ARM_PSCI
 	depends on !GENERIC_ATOMIC64
 	help
 	  Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
diff --git a/arch/arm/include/asm/xen/hypervisor.h b/arch/arm/include/asm/xen/hypervisor.h
index d7ab99a..17b3ea2 100644
--- a/arch/arm/include/asm/xen/hypervisor.h
+++ b/arch/arm/include/asm/xen/hypervisor.h
@@ -16,4 +16,10 @@  static inline enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
 	return PARAVIRT_LAZY_NONE;
 }
 
+#ifdef CONFIG_XEN
+void xen_early_init(void);
+#else
+static inline void xen_early_init(void) { return; }
+#endif
+
 #endif /* _ASM_ARM_XEN_HYPERVISOR_H */
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 7e193df..67d911f 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -55,6 +55,8 @@ 
 #include <asm/unwind.h>
 #include <asm/memblock.h>
 #include <asm/virt.h>
+#include <asm/xen/hypervisor.h>
+#include <xen/xen.h>
 
 #include "atags.h"
 #include "tcm.h"
@@ -768,6 +770,7 @@  void __init setup_arch(char **cmdline_p)
 
 	arm_dt_init_cpu_maps();
 	psci_init();
+	xen_early_init();
 #ifdef CONFIG_SMP
 	if (is_smp()) {
 		if (mdesc->smp_init)
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index b002822..ee09357 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -11,6 +11,8 @@ 
 #include <xen/xenbus.h>
 #include <xen/page.h>
 #include <xen/xen-ops.h>
+#include <asm/mach/arch.h>
+#include <asm/psci.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
 #include <linux/interrupt.h>
@@ -176,27 +178,30 @@  static int __init xen_secondary_init(unsigned int cpu)
 	return 0;
 }
 
+static void __init xen_smp_init(void)
+{
+	if (psci_smp_available())
+		smp_set_ops(&psci_smp_ops);
+}
+
 /*
  * see Documentation/devicetree/bindings/arm/xen.txt for the
  * documentation of the Xen Device Tree format.
  */
 #define GRANT_TABLE_PHYSADDR 0
-static int __init xen_guest_init(void)
+void __init xen_early_init(void)
 {
-	struct xen_add_to_physmap xatp;
-	static struct shared_info *shared_info_page = 0;
 	struct device_node *node;
 	int len;
 	const char *s = NULL;
 	const char *version = NULL;
 	const char *xen_prefix = "xen,xen-";
 	struct resource res;
-	int i;
 
 	node = of_find_compatible_node(NULL, NULL, "xen,xen");
 	if (!node) {
 		pr_debug("No Xen support\n");
-		return 0;
+		return;
 	}
 	s = of_get_property(node, "compatible", &len);
 	if (strlen(xen_prefix) + 3  < len &&
@@ -204,15 +209,23 @@  static int __init xen_guest_init(void)
 		version = s + strlen(xen_prefix);
 	if (version == NULL) {
 		pr_debug("Xen version not found\n");
-		return 0;
+		return;
 	}
 	if (of_address_to_resource(node, GRANT_TABLE_PHYSADDR, &res))
-		return 0;
+		return;
 	xen_hvm_resume_frames = res.start >> PAGE_SHIFT;
 	xen_events_irq = irq_of_parse_and_map(node, 0);
 	pr_info("Xen %s support found, events_irq=%d gnttab_frame_pfn=%lx\n",
 			version, xen_events_irq, xen_hvm_resume_frames);
 	xen_domain_type = XEN_HVM_DOMAIN;
+	machine_desc->smp_init = xen_smp_init;
+}
+
+static int __init xen_guest_init(void)
+{
+	struct xen_add_to_physmap xatp;
+	static struct shared_info *shared_info_page = 0;
+	int i;
 
 	xen_setup_features();
 	if (xen_feature(XENFEAT_dom0))