LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* RE: [PATCH 2/3] powerpc/mpic: add global timer support
From: Wang Dongsheng-B40534 @ 2013-03-26  3:29 UTC (permalink / raw)
  To: Wood Scott-B07421
  Cc: Gala Kumar-B11780, linuxppc-dev@lists.ozlabs.org, Li Yang-R58472
In-Reply-To: <1363991395.24790.13@snotra>



> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Saturday, March 23, 2013 6:30 AM
> To: Wang Dongsheng-B40534
> Cc: Wood Scott-B07421; Gala Kumar-B11780; linuxppc-dev@lists.ozlabs.org;
> Li Yang-R58472
> Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
>=20
> On 03/22/2013 01:14:51 AM, Wang Dongsheng-B40534 wrote:
> >
> >
> > > -----Original Message-----
> > > From: Wood Scott-B07421
> > > Sent: Thursday, March 21, 2013 7:00 AM
> > > To: Wang Dongsheng-B40534
> > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > linuxppc-dev@lists.ozlabs.org;
> > > Li Yang-R58472
> > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
> > >
> > > BTW, the input clock frequency has been similarly scaled, yet you
> > don't
> > > try to scrounge up that information to get further precision...
> > >
> > Let's go back patch, do you think the code is repeated?
> > I will remove "if (!(priv->flags & FSL_GLOBAL_TIMER))" branch, there
> > will be no redundant code.
>=20
> I'd rather that branch be kept and the more complicated branch deleted,
> and priv->timerfreq frequency be adjusted on initialization to account
> for the scaler.

static void convert_ticks_to_time(struct timer_group_priv *priv,
                const u64 ticks, struct timeval *time)
{
        u64 tmp_sec;

        time->tv_sec =3D (__kernel_time_t)div_u64(ticks, priv->timerfreq);
        tmp_sec =3D (u64)time->tv_sec * (u64)priv->timerfreq;

        time->tv_usec =3D (__kernel_suseconds_t)
                div_u64((ticks - tmp_sec) * 1000000, priv->timerfreq);

        return;
}

timer_group_get_freq() {
	...
	if (priv->flags & FSL_GLOBAL_TIMER) {
		div =3D (1 << (MPIC_TIMER_TCR_CLKDIV_64 >> 8)) * 8;
		priv->timerfreq /=3D div;
	}
	...
}
Do you want to do that?

^ permalink raw reply

* [PATCH 1/2] powerpc/MPIC: Add get_version API both for internal and external use
From: Jia Hongtao @ 2013-03-26  3:28 UTC (permalink / raw)
  To: linuxppc-dev, galak; +Cc: B07421, hongtao.jia

MPIC version is useful information for both mpic_alloc() and mpic_init().
The patch provide an API to get MPIC version for reusing the code.
Also, some other IP block may need MPIC version for their own use.
The API for external use is also provided.

Signed-off-by: Jia Hongtao <hongtao.jia@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
 arch/powerpc/include/asm/mpic.h |  3 +++
 arch/powerpc/sysdev/mpic.c      | 30 +++++++++++++++++++++++-------
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index c0f9ef9..95053d6 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -393,6 +393,9 @@ struct mpic
 #define	MPIC_REGSET_STANDARD		MPIC_REGSET(0)	/* Original MPIC */
 #define	MPIC_REGSET_TSI108		MPIC_REGSET(1)	/* Tsi108/109 PIC */
 
+/* Get the mpic version */
+extern u32 mpic_primary_get_version(void);
+
 /* Allocate the controller structure and setup the linux irq descs
  * for the range if interrupts passed in. No HW initialization is
  * actually performed.
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index d30e6a6..d6b6fb6 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1165,10 +1165,31 @@ static struct irq_domain_ops mpic_host_ops = {
 	.xlate = mpic_host_xlate,
 };
 
+static u32 mpic_get_version(struct mpic *mpic)
+{
+	u32 brr1;
+
+	brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
+			MPIC_FSL_BRR1);
+
+	return brr1 & MPIC_FSL_BRR1_VER;
+}
+
 /*
  * Exported functions
  */
 
+u32 mpic_primary_get_version(void)
+{
+	u32 brr1;
+	struct mpic *mpic = mpic_primary;
+
+	brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
+			MPIC_FSL_BRR1);
+
+	return brr1 & MPIC_FSL_BRR1_VER;
+}
+
 struct mpic * __init mpic_alloc(struct device_node *node,
 				phys_addr_t phys_addr,
 				unsigned int flags,
@@ -1315,7 +1336,6 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 	mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
 
 	if (mpic->flags & MPIC_FSL) {
-		u32 brr1;
 		int ret;
 
 		/*
@@ -1326,9 +1346,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 		mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs,
 			 MPIC_CPU_THISBASE, 0x1000);
 
-		brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
-				MPIC_FSL_BRR1);
-		fsl_version = brr1 & MPIC_FSL_BRR1_VER;
+		fsl_version = mpic_get_version(mpic);
 
 		/* Error interrupt mask register (EIMR) is required for
 		 * handling individual device error interrupts. EIMR
@@ -1518,9 +1536,7 @@ void __init mpic_init(struct mpic *mpic)
 	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
 
 	if (mpic->flags & MPIC_FSL) {
-		u32 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
-				      MPIC_FSL_BRR1);
-		u32 version = brr1 & MPIC_FSL_BRR1_VER;
+		u32 version = mpic_get_version(mpic);
 
 		/*
 		 * Timer group B is present at the latest in MPIC 3.1 (e.g.
-- 
1.8.0

^ permalink raw reply related

* [PATCH 2/2] powerpc/85xx: workaround for chips with MSI hardware errata
From: Jia Hongtao @ 2013-03-26  3:28 UTC (permalink / raw)
  To: linuxppc-dev, galak; +Cc: B07421, hongtao.jia
In-Reply-To: <1364268527-32068-1-git-send-email-hongtao.jia@freescale.com>

The MPIC version 2.0 has a MSI errata (errata PIC1 of mpc8544), It causes
that neither MSI nor MSI-X can work fine. This is a workaround to allow
MSI-X to function properly.

Signed-off-by: Liu Shuo <soniccat.liu@gmail.com>
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Jia Hongtao <hongtao.jia@freescale.com>
---
 arch/powerpc/sysdev/fsl_msi.c | 47 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 44 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 178c994..d2f8040 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -28,6 +28,8 @@
 #include "fsl_msi.h"
 #include "fsl_pci.h"
 
+#define MSI_HW_ERRATA_ENDIAN 0x00000010
+
 static LIST_HEAD(msi_head);
 
 struct fsl_msi_feature {
@@ -98,8 +100,18 @@ static int fsl_msi_init_allocator(struct fsl_msi *msi_data)
 
 static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type)
 {
-	if (type == PCI_CAP_ID_MSIX)
-		pr_debug("fslmsi: MSI-X untested, trying anyway.\n");
+	struct fsl_msi *msi;
+
+	if (type == PCI_CAP_ID_MSI) {
+		/*
+		 * MPIC version 2.0 has erratum PIC1. For now MSI
+		 * could not work. So check to prevent MSI from
+		 * being used on the board with this erratum.
+		 */
+		list_for_each_entry(msi, &msi_head, list)
+			if (msi->feature & MSI_HW_ERRATA_ENDIAN)
+				return -EINVAL;
+	}
 
 	return 0;
 }
@@ -142,7 +154,17 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
 	msg->address_lo = lower_32_bits(address);
 	msg->address_hi = upper_32_bits(address);
 
-	msg->data = hwirq;
+	/*
+	 * MPIC version 2.0 has erratum PIC1. It causes
+	 * that neither MSI nor MSI-X can work fine.
+	 * This is a workaround to allow MSI-X to function
+	 * properly. It only works for MSI-X, we prevent
+	 * MSI on buggy chips in fsl_msi_check_device().
+	 */
+	if (msi_data->feature & MSI_HW_ERRATA_ENDIAN)
+		msg->data = __swab32(hwirq);
+	else
+		msg->data = hwirq;
 
 	pr_debug("%s: allocated srs: %d, ibs: %d\n",
 		__func__, hwirq / IRQS_PER_MSI_REG, hwirq % IRQS_PER_MSI_REG);
@@ -361,6 +383,15 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev,
 	return 0;
 }
 
+/* MPIC version 2.0 has erratum PIC1 */
+static int mpic_has_errata(void)
+{
+	if (mpic_primary_get_version() == 0x0200)
+		return 1;
+
+	return 0;
+}
+
 static const struct of_device_id fsl_of_msi_ids[];
 static int fsl_of_msi_probe(struct platform_device *dev)
 {
@@ -423,6 +454,16 @@ static int fsl_of_msi_probe(struct platform_device *dev)
 
 	msi->feature = features->fsl_pic_ip;
 
+	if ((features->fsl_pic_ip & FSL_PIC_IP_MASK) == FSL_PIC_IP_MPIC) {
+		rc = mpic_has_errata();
+		if (rc > 0) {
+			msi->feature |= MSI_HW_ERRATA_ENDIAN;
+		} else if (rc < 0) {
+			err = rc;
+			goto error_out;
+		}
+	}
+
 	/*
 	 * Remember the phandle, so that we can match with any PCI nodes
 	 * that have an "fsl,msi" property.
-- 
1.8.0

^ permalink raw reply related

* Re: [PATCH] powerpc: remove two lines of dead code
From: Michael Ellerman @ 2013-03-26  4:12 UTC (permalink / raw)
  To: Paul Bolle; +Cc: Paul Mackerras, linuxppc-dev, linux-kernel
In-Reply-To: <1364207531.1390.271.camel@x61.thuisdomein>

On Mon, Mar 25, 2013 at 11:32:11AM +0100, Paul Bolle wrote:
> Commit c1fb6816fb1b78dd94b673b0fdaa9a7a16e97bd1 ("powerpc: Add
> relocation on exception vector handlers") added two lines of code that
> depend on the macro CONFIG_HVC_SCOM. That macro doesn't exist. Perhaps
> it was intended to use CONFIG_PPC_SCOM here. But since
> "maintence_interrupt" is a typo and there's nothing in arch/powerpc that
> looks like maintenance_interrupt it seems best to just delete these
> lines.

It's cruft from our internal tree that snuck into the patch. I was
meaning to remove it but you beat me to it.

Acked-by: Michael Ellerman <michael@ellerman.id.au>

cheers

^ permalink raw reply

* Re: [PATCH 1/2] powerpc/MPIC: Add get_version API both for internal and external use
From: Michael Ellerman @ 2013-03-26  4:14 UTC (permalink / raw)
  To: Jia Hongtao; +Cc: B07421, linuxppc-dev
In-Reply-To: <1364268527-32068-1-git-send-email-hongtao.jia@freescale.com>

On Tue, Mar 26, 2013 at 11:28:46AM +0800, Jia Hongtao wrote:
> MPIC version is useful information for both mpic_alloc() and mpic_init().
> The patch provide an API to get MPIC version for reusing the code.
> Also, some other IP block may need MPIC version for their own use.
> The API for external use is also provided.
> 
> Signed-off-by: Jia Hongtao <hongtao.jia@freescale.com>
> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
>  arch/powerpc/include/asm/mpic.h |  3 +++
>  arch/powerpc/sysdev/mpic.c      | 30 +++++++++++++++++++++++-------
>  2 files changed, 26 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
> index c0f9ef9..95053d6 100644
> --- a/arch/powerpc/include/asm/mpic.h
> +++ b/arch/powerpc/include/asm/mpic.h
> @@ -393,6 +393,9 @@ struct mpic
>  #define	MPIC_REGSET_STANDARD		MPIC_REGSET(0)	/* Original MPIC */
>  #define	MPIC_REGSET_TSI108		MPIC_REGSET(1)	/* Tsi108/109 PIC */
>  
> +/* Get the mpic version */
> +extern u32 mpic_primary_get_version(void);
> +
>  /* Allocate the controller structure and setup the linux irq descs
>   * for the range if interrupts passed in. No HW initialization is
>   * actually performed.
> diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
> index d30e6a6..d6b6fb6 100644
> --- a/arch/powerpc/sysdev/mpic.c
> +++ b/arch/powerpc/sysdev/mpic.c
> @@ -1165,10 +1165,31 @@ static struct irq_domain_ops mpic_host_ops = {
>  	.xlate = mpic_host_xlate,
>  };
>  
> +static u32 mpic_get_version(struct mpic *mpic)
> +{
> +	u32 brr1;
> +
> +	brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
> +			MPIC_FSL_BRR1);
> +
> +	return brr1 & MPIC_FSL_BRR1_VER;
> +}
> +
>  /*
>   * Exported functions
>   */
>  
> +u32 mpic_primary_get_version(void)
> +{
> +	u32 brr1;
> +	struct mpic *mpic = mpic_primary;
> +
> +	brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
> +			MPIC_FSL_BRR1);
> +
> +	return brr1 & MPIC_FSL_BRR1_VER;
> +}

Why doesn't mpic_primary_get_version() call mpic_get_version() ?

cheers

^ permalink raw reply

* RE: [PATCH 1/2] powerpc/MPIC: Add get_version API both for internal and external use
From: Jia Hongtao-B38951 @ 2013-03-26  4:16 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: Wood Scott-B07421, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <20130326041426.GC22382@concordia>



> -----Original Message-----
> From: Michael Ellerman [mailto:michael@ellerman.id.au]
> Sent: Tuesday, March 26, 2013 12:14 PM
> To: Jia Hongtao-B38951
> Cc: linuxppc-dev@lists.ozlabs.org; galak@kernel.crashing.org; Wood Scott-
> B07421
> Subject: Re: [PATCH 1/2] powerpc/MPIC: Add get_version API both for
> internal and external use
>=20
> On Tue, Mar 26, 2013 at 11:28:46AM +0800, Jia Hongtao wrote:
> > MPIC version is useful information for both mpic_alloc() and
> mpic_init().
> > The patch provide an API to get MPIC version for reusing the code.
> > Also, some other IP block may need MPIC version for their own use.
> > The API for external use is also provided.
> >
> > Signed-off-by: Jia Hongtao <hongtao.jia@freescale.com>
> > Signed-off-by: Li Yang <leoli@freescale.com>
> > ---
> >  arch/powerpc/include/asm/mpic.h |  3 +++
> >  arch/powerpc/sysdev/mpic.c      | 30 +++++++++++++++++++++++-------
> >  2 files changed, 26 insertions(+), 7 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/mpic.h
> > b/arch/powerpc/include/asm/mpic.h index c0f9ef9..95053d6 100644
> > --- a/arch/powerpc/include/asm/mpic.h
> > +++ b/arch/powerpc/include/asm/mpic.h
> > @@ -393,6 +393,9 @@ struct mpic
> >  #define	MPIC_REGSET_STANDARD		MPIC_REGSET(0)	/* Original
> MPIC */
> >  #define	MPIC_REGSET_TSI108		MPIC_REGSET(1)	/* Tsi108/109
> PIC */
> >
> > +/* Get the mpic version */
> > +extern u32 mpic_primary_get_version(void);
> > +
> >  /* Allocate the controller structure and setup the linux irq descs
> >   * for the range if interrupts passed in. No HW initialization is
> >   * actually performed.
> > diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
> > index d30e6a6..d6b6fb6 100644
> > --- a/arch/powerpc/sysdev/mpic.c
> > +++ b/arch/powerpc/sysdev/mpic.c
> > @@ -1165,10 +1165,31 @@ static struct irq_domain_ops mpic_host_ops =3D =
{
> >  	.xlate =3D mpic_host_xlate,
> >  };
> >
> > +static u32 mpic_get_version(struct mpic *mpic) {
> > +	u32 brr1;
> > +
> > +	brr1 =3D _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
> > +			MPIC_FSL_BRR1);
> > +
> > +	return brr1 & MPIC_FSL_BRR1_VER;
> > +}
> > +
> >  /*
> >   * Exported functions
> >   */
> >
> > +u32 mpic_primary_get_version(void)
> > +{
> > +	u32 brr1;
> > +	struct mpic *mpic =3D mpic_primary;
> > +
> > +	brr1 =3D _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
> > +			MPIC_FSL_BRR1);
> > +
> > +	return brr1 & MPIC_FSL_BRR1_VER;
> > +}
>=20
> Why doesn't mpic_primary_get_version() call mpic_get_version() ?
>=20
> cheers

Good idea.

Thanks.
-Hongtao.

^ permalink raw reply

* [PATCH] powerpc: fix annotation of fake_numa_create_new_node()
From: Stephen Rothwell @ 2013-03-26  4:44 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: ppc-dev

[-- Attachment #1: Type: text/plain, Size: 1302 bytes --]

This function has always been marked as __cpuinit, but is only called
from functions marked as __init and references an __initdata variable.
So change its annotation to __init.

Fixes this build warning:

WARNING: arch/powerpc/mm/built-in.o(.cpuinit.text+0x86): Section mismatch in reference from the function .fake_numa_create_new_node() to the variable .init.data:cmdline
The function __cpuinit .fake_numa_create_new_node() references
a variable __initdata cmdline.
If cmdline is only used by .fake_numa_create_new_node then
annotate cmdline with a matching annotation.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/mm/numa.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index bba87ca..715cab7 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -79,7 +79,7 @@ static void __init setup_node_to_cpumask_map(void)
 	dbg("Node to cpumask map for %d nodes\n", nr_node_ids);
 }
 
-static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn,
+static int __init fake_numa_create_new_node(unsigned long end_pfn,
 						unsigned int *nid)
 {
 	unsigned long long mem;
-- 
1.8.1

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply related

* Re: [PATCH 3/3] cpufreq: Add cpufreq driver for Freescale e500mc SOCs
From: Viresh Kumar @ 2013-03-26  5:03 UTC (permalink / raw)
  To: Yuantian.Tang; +Cc: rjw, linuxppc-dev, cpufreq, linux-pm
In-Reply-To: <1364265391-26077-3-git-send-email-Yuantian.Tang@freescale.com>

On Tue, Mar 26, 2013 at 8:06 AM,  <Yuantian.Tang@freescale.com> wrote:
> diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc
> index e76992f..6339db4 100644
> --- a/drivers/cpufreq/Kconfig.powerpc
> +++ b/drivers/cpufreq/Kconfig.powerpc
> @@ -5,3 +5,13 @@ config CPU_FREQ_MAPLE
>         help
>           This adds support for frequency switching on Maple 970FX
>           Evaluation Board and compatible boards (IBM JS2x blades).
> +
> +config PPC_CORENET_CPUFREQ
> +       tristate "CPU frequency scaling driver for Freescale E500MC SoCs"
> +       depends on PPC_E500MC

depends on OF and COMMON_CLK too?

> +       select CPU_FREQ_TABLE
> +       select CLK_PPC_CORENET
> +       help
> +         This adds the CPUFreq driver support for Freescale e500mc,
> +         e5500 and e6500 series SoCs which are capable of changing
> +         the CPU's frequency dynamically.
> diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
> index 863fd18..2416559 100644
> --- a/drivers/cpufreq/Makefile
> +++ b/drivers/cpufreq/Makefile

> diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c

> +#include <linux/module.h>
> +#include <linux/types.h>
> +#include <linux/errno.h>
> +#include <linux/kernel.h>
> +#include <linux/cpufreq.h>
> +#include <linux/init.h>
> +#include <linux/mutex.h>
> +#include <linux/slab.h>
> +#include <linux/of.h>
> +#include <linux/io.h>
> +#include <linux/clk-provider.h>

You shouldn't need this normally.

> +#include <linux/cpu.h>

Keep them in alphabetical order, so that we don't anyone twice by mistake.

> +/**
> + * struct cpufreq_data - cpufreq driver data
> + * @cpus_per_cluster: CPU numbers per cluster
> + * @cpufreq_lock: the mutex lock
> + */
> +struct cpufreq_data {
> +       int     cpus_per_cluster;
> +       struct mutex cpufreq_lock;
> +};
> +
> +/**
> + * struct cpu_data - per CPU data struct

For your case where you have 8 cpus in a cluster, only one of 8 variables
would be used... Better to create an array of struct with elements:
cpu and data.

> + * @np: the node of CPU
> + * @parent: the parent node of np
> + * @table: frequency table point
> + */
> +struct cpu_data {
> +       struct device_node  *np;
> +       struct device_node  *parent;
> +       struct cpufreq_frequency_table *table;
> +};
> +
> +static DEFINE_PER_CPU(struct cpu_data, cpu_data);
> +static struct cpufreq_data freq_data;
> +
> +static unsigned int corenet_cpufreq_get_speed(unsigned int cpu)
> +{
> +       struct clk *clk;
> +       struct cpu_data *data = &per_cpu(cpu_data, cpu);
> +
> +       clk = of_clk_get(data->np, 0);

You want to do this everytime? Want to store it?

> +       return clk_get_rate(clk) / 1000;
> +}
> +
> +/* reduce the duplicated frequency in frequency table */
> +static int freq_table_redup(struct cpufreq_frequency_table *freq_table,
> +               int cur)
> +{
> +       int i;
> +
> +       for (i = 0; i < cur; i++) {
> +               if (freq_table[i].frequency == CPUFREQ_ENTRY_INVALID ||
> +                       freq_table[i].frequency != freq_table[cur].frequency)
> +                       continue;
> +
> +               freq_table[cur].index = -1;

don't need this.

> +               freq_table[cur].frequency = CPUFREQ_ENTRY_INVALID;
> +               break;
> +       }
> +
> +       return (i == cur) ? 0 : 1;

return value isn't used by caller.

> +}
> +
> +static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> +{
> +       unsigned int cpu = policy->cpu;
> +       int i, count;
> +       struct clk *clk;
> +       struct cpufreq_frequency_table *table;
> +       struct cpu_data *data;
> +
> +       data = &per_cpu(cpu_data, cpu);
> +       data->np = of_get_cpu_node(cpu, NULL);
> +       if (!data->np)
> +               return -ENODEV;
> +
> +       data->parent = of_parse_phandle(data->np, "clocks", 0);

You need to details your DTB bindings in Documentation/devicetree/bindings and
cc devicetree-discuss@lists.ozlabs.org.

> +       if (!data->parent)
> +               return -ENODEV;

of_node_put(np)??

> +
> +       count = of_property_count_strings(data->parent, "clock-names");
> +       table = kcalloc(count + 1,

kzalloc??

> +                       sizeof(struct cpufreq_frequency_table), GFP_KERNEL);

sizeof(*table)

> +       if (!table)
> +               return -ENOMEM;
> +
> +       for (i = cpu; i < freq_data.cpus_per_cluster + cpu; i++)
> +               cpumask_set_cpu(i, policy->cpus);
> +
> +       for (i = 0; i < count; i++) {
> +               table[i].index = i;
> +               clk = of_clk_get(data->parent, i);
> +               table[i].frequency = clk_get_rate(clk) / 1000;
> +               freq_table_redup(table, i);

Don't call it everytime, fix all these in a single call.

> +       }
> +       table[i].index = -1;

-1 ??

> +       table[i].frequency = CPUFREQ_TABLE_END;
> +
> +       data->table = table;
> +       cpufreq_frequency_table_get_attr(table, cpu);

This must be done only when init() passed. What if
cpufreq_frequency_table_cpuinfo() failed?

> +
> +       /* FIXME: what's the actual transition time? in ns */
> +       policy->cpuinfo.transition_latency = 2000;

CPUFREQ_ETERNAL??

> +       policy->cur = corenet_cpufreq_get_speed(policy->cpu);
> +
> +       /* set the min and max frequency properly */
> +       return cpufreq_frequency_table_cpuinfo(policy, table);
> +}
> +
> +static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
> +{
> +       cpufreq_frequency_table_put_attr(policy->cpu);
> +
> +       return 0;
> +}
> +
> +static int corenet_cpufreq_verify(struct cpufreq_policy *policy)
> +{
> +       struct cpufreq_frequency_table *table;
> +
> +       table = (&per_cpu(cpu_data, policy->cpu))->table;
> +       if (!table)
> +               return -EINVAL;

This should never be true.

> +       return cpufreq_frequency_table_verify(policy, table);
> +}
> +
> +static int corenet_cpufreq_target(struct cpufreq_policy *policy,
> +               unsigned int target_freq, unsigned int relation)
> +{
> +       struct cpufreq_freqs freqs;
> +       unsigned int new;
> +       struct clk *clk, *parent;
> +       int ret;
> +       struct cpu_data *data = &per_cpu(cpu_data, policy->cpu);
> +
> +       cpufreq_frequency_table_target(policy, data->table,
> +                       target_freq, relation, &new);
> +
> +       if (policy->cur == data->table[new].frequency)
> +               return 0;
> +
> +       freqs.old = policy->cur;
> +       freqs.new = data->table[new].frequency;
> +       freqs.cpu = policy->cpu;
> +
> +       mutex_lock(&freq_data.cpufreq_lock);
> +       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
> +
> +       clk = of_clk_get(data->np, 0);
> +       parent = of_clk_get(data->parent, new);
> +       ret = clk_set_parent(clk, parent);
> +       if (ret) {
> +               mutex_unlock(&freq_data.cpufreq_lock);
> +               return ret;
> +       }
> +
> +       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
> +       mutex_unlock(&freq_data.cpufreq_lock);
> +
> +       return 0;
> +}
> +
> +static struct freq_attr *corenet_cpu_clks_attr[] = {
> +       &cpufreq_freq_attr_scaling_available_freqs,
> +       NULL,
> +};
> +
> +static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
> +       .name           = "ppc_cpufreq",
> +       .owner          = THIS_MODULE,
> +       .flags          = CPUFREQ_CONST_LOOPS,
> +       .init           = corenet_cpufreq_cpu_init,
> +       .exit           = __exit_p(corenet_cpufreq_cpu_exit),
> +       .verify         = corenet_cpufreq_verify,
> +       .target         = corenet_cpufreq_target,
> +       .get            = corenet_cpufreq_get_speed,
> +       .attr           = corenet_cpu_clks_attr,
> +};
> +
> +static const struct of_device_id node_matches[] __initconst = {
> +       { .compatible = "fsl,qoriq-clockgen-1.0", .data = (void *)1, },
> +       { .compatible = "fsl,qoriq-clockgen-2", .data = (void *)8, },
> +       {}
> +};
> +
> +static int __init ppc_corenet_cpufreq_init(void)
> +{
> +       int ret = 0;
> +       struct device_node  *np;
> +       const struct of_device_id *match;
> +
> +       np = of_find_matching_node(NULL, node_matches);
> +       if (!np)
> +               return -ENODEV;
> +
> +       match = of_match_node(node_matches, np);
> +       freq_data.cpus_per_cluster = (long)match->data;
> +       mutex_init(&freq_data.cpufreq_lock);
> +       of_node_put(np);
> +
> +       ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
> +       if (ret)
> +               return ret;
> +
> +       pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
> +
> +       return ret;
> +}
> +
> +static void __exit ppc_corenet_cpufreq_exit(void)
> +{
> +       cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> +}
> +
> +module_init(ppc_corenet_cpufreq_init);
> +module_exit(ppc_corenet_cpufreq_exit);

Place them right below their respective functions without any blank
line in between.

> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
> +MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SOCs");

^ permalink raw reply

* [PATCH V2] powerpc/MPIC: Add get_version API both for internal and external use
From: Jia Hongtao @ 2013-03-26  5:28 UTC (permalink / raw)
  To: linuxppc-dev, galak; +Cc: B07421, hongtao.jia

MPIC version is useful information for both mpic_alloc() and mpic_init().
The patch provide an API to get MPIC version for reusing the code.
Also, some other IP block may need MPIC version for their own use.
The API for external use is also provided.

Signed-off-by: Jia Hongtao <hongtao.jia@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
Changes for V2:
* Using mpic_get_version() to implement mpic_primary_get_version()

 arch/powerpc/include/asm/mpic.h |  3 +++
 arch/powerpc/sysdev/mpic.c      | 26 +++++++++++++++++++-------
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index c0f9ef9..7d1222d 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -393,6 +393,9 @@ struct mpic
 #define	MPIC_REGSET_STANDARD		MPIC_REGSET(0)	/* Original MPIC */
 #define	MPIC_REGSET_TSI108		MPIC_REGSET(1)	/* Tsi108/109 PIC */
 
+/* Get the version of primary MPIC */
+extern u32 mpic_primary_get_version(void);
+
 /* Allocate the controller structure and setup the linux irq descs
  * for the range if interrupts passed in. No HW initialization is
  * actually performed.
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index d30e6a6..c893a4b 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1165,10 +1165,27 @@ static struct irq_domain_ops mpic_host_ops = {
 	.xlate = mpic_host_xlate,
 };
 
+static u32 mpic_get_version(struct mpic *mpic)
+{
+	u32 brr1;
+
+	brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
+			MPIC_FSL_BRR1);
+
+	return brr1 & MPIC_FSL_BRR1_VER;
+}
+
 /*
  * Exported functions
  */
 
+u32 mpic_primary_get_version(void)
+{
+	struct mpic *mpic = mpic_primary;
+
+	return mpic_get_version(mpic);
+}
+
 struct mpic * __init mpic_alloc(struct device_node *node,
 				phys_addr_t phys_addr,
 				unsigned int flags,
@@ -1315,7 +1332,6 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 	mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
 
 	if (mpic->flags & MPIC_FSL) {
-		u32 brr1;
 		int ret;
 
 		/*
@@ -1326,9 +1342,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 		mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs,
 			 MPIC_CPU_THISBASE, 0x1000);
 
-		brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
-				MPIC_FSL_BRR1);
-		fsl_version = brr1 & MPIC_FSL_BRR1_VER;
+		fsl_version = mpic_get_version(mpic);
 
 		/* Error interrupt mask register (EIMR) is required for
 		 * handling individual device error interrupts. EIMR
@@ -1518,9 +1532,7 @@ void __init mpic_init(struct mpic *mpic)
 	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
 
 	if (mpic->flags & MPIC_FSL) {
-		u32 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
-				      MPIC_FSL_BRR1);
-		u32 version = brr1 & MPIC_FSL_BRR1_VER;
+		u32 version = mpic_get_version(mpic);
 
 		/*
 		 * Timer group B is present at the latest in MPIC 3.1 (e.g.
-- 
1.8.0

^ permalink raw reply related

* Re: [PATCH v2 1/4] uprobes: add trap variant helper
From: Srikar Dronamraju @ 2013-03-26 12:06 UTC (permalink / raw)
  To: Ananth N Mavinakayanahalli; +Cc: ppcdev, lkml, oleg
In-Reply-To: <20130322151627.GB20010@in.ibm.com>

* Ananth N Mavinakayanahalli <ananth@in.ibm.com> [2013-03-22 20:46:27]:

> From: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
> 
> Some architectures like powerpc have multiple variants of the trap
> instruction. Introduce an additional helper is_trap_insn() for run-time
> handling of non-uprobe traps on such architectures.
> 
> While there, change is_swbp_at_addr() to is_trap_at_addr() for reading
> clarity.
> 
> With this change, the uprobe registration path will supercede any trap
> instruction inserted at the requested location, while taking care of
> delivering the SIGTRAP for cases where the trap notification came in
> for an address without a uprobe. See [1] for a more detailed explanation.
> 
> [1] https://lists.ozlabs.org/pipermail/linuxppc-dev/2013-March/104771.html
> 
> This change was suggested by Oleg Nesterov.
> 
> Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>

Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>

> ---
>  include/linux/uprobes.h |    1 +
>  kernel/events/uprobes.c |   32 ++++++++++++++++++++++++++++----
>  2 files changed, 29 insertions(+), 4 deletions(-)
> 
> Index: linux-3.9-rc3/include/linux/uprobes.h
> ===================================================================
> --- linux-3.9-rc3.orig/include/linux/uprobes.h
> +++ linux-3.9-rc3/include/linux/uprobes.h
> @@ -100,6 +100,7 @@ struct uprobes_state {
>  extern int __weak set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr);
>  extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr);
>  extern bool __weak is_swbp_insn(uprobe_opcode_t *insn);
> +extern bool __weak is_trap_insn(uprobe_opcode_t *insn);
>  extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
>  extern int uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool);
>  extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
> Index: linux-3.9-rc3/kernel/events/uprobes.c
> ===================================================================
> --- linux-3.9-rc3.orig/kernel/events/uprobes.c
> +++ linux-3.9-rc3/kernel/events/uprobes.c
> @@ -173,6 +173,20 @@ bool __weak is_swbp_insn(uprobe_opcode_t
>  	return *insn == UPROBE_SWBP_INSN;
>  }
> 
> +/**
> + * is_trap_insn - check if instruction is breakpoint instruction.
> + * @insn: instruction to be checked.
> + * Default implementation of is_trap_insn
> + * Returns true if @insn is a breakpoint instruction.
> + *
> + * This function is needed for the case where an architecture has multiple
> + * trap instructions (like powerpc).
> + */
> +bool __weak is_trap_insn(uprobe_opcode_t *insn)
> +{
> +	return is_swbp_insn(insn);
> +}
> +
>  static void copy_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t *opcode)
>  {
>  	void *kaddr = kmap_atomic(page);
> @@ -185,6 +199,15 @@ static int verify_opcode(struct page *pa
>  	uprobe_opcode_t old_opcode;
>  	bool is_swbp;
> 
> +	/*
> +	 * Note: We only check if the old_opcode is UPROBE_SWBP_INSN here.
> +	 * We do not check if it is any other 'trap variant' which could
> +	 * be conditional trap instruction such as the one powerpc supports.
> +	 *
> +	 * The logic is that we do not care if the underlying instruction
> +	 * is a trap variant; uprobes always wins over any other (gdb)
> +	 * breakpoint.
> +	 */
>  	copy_opcode(page, vaddr, &old_opcode);
>  	is_swbp = is_swbp_insn(&old_opcode);
> 
> @@ -204,7 +227,7 @@ static int verify_opcode(struct page *pa
>   * Expect the breakpoint instruction to be the smallest size instruction for
>   * the architecture. If an arch has variable length instruction and the
>   * breakpoint instruction is not of the smallest length instruction
> - * supported by that architecture then we need to modify is_swbp_at_addr and
> + * supported by that architecture then we need to modify is_trap_at_addr and
>   * write_opcode accordingly. This would never be a problem for archs that
>   * have fixed length instructions.
>   */
> @@ -1431,7 +1454,7 @@ static void mmf_recalc_uprobes(struct mm
>  	clear_bit(MMF_HAS_UPROBES, &mm->flags);
>  }
> 
> -static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr)
> +static int is_trap_at_addr(struct mm_struct *mm, unsigned long vaddr)
>  {
>  	struct page *page;
>  	uprobe_opcode_t opcode;
> @@ -1452,7 +1475,8 @@ static int is_swbp_at_addr(struct mm_str
>  	copy_opcode(page, vaddr, &opcode);
>  	put_page(page);
>   out:
> -	return is_swbp_insn(&opcode);
> +	/* This needs to return true for any variant of the trap insn */
> +	return is_trap_insn(&opcode);
>  }
> 
>  static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp)
> @@ -1472,7 +1496,7 @@ static struct uprobe *find_active_uprobe
>  		}
> 
>  		if (!uprobe)
> -			*is_swbp = is_swbp_at_addr(mm, bp_vaddr);
> +			*is_swbp = is_trap_at_addr(mm, bp_vaddr);
>  	} else {
>  		*is_swbp = -EFAULT;
>  	}

-- 
Thanks and Regards
Srikar Dronamraju

^ permalink raw reply

* Re: [PATCH v2 2/4] uprobes: refuse uprobe on trap variants
From: Srikar Dronamraju @ 2013-03-26 12:06 UTC (permalink / raw)
  To: Ananth N Mavinakayanahalli; +Cc: ppcdev, lkml, oleg
In-Reply-To: <20130322151758.GC20010@in.ibm.com>

* Ananth N Mavinakayanahalli <ananth@in.ibm.com> [2013-03-22 20:47:58]:

> From: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
> 
> Refuse to place a uprobe if a trap variant already exists in the
> file copy at the address.
> 
> Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>

Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>

> ---
>  kernel/events/uprobes.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> Index: linux-3.9-rc3/kernel/events/uprobes.c
> ===================================================================
> --- linux-3.9-rc3.orig/kernel/events/uprobes.c
> +++ linux-3.9-rc3/kernel/events/uprobes.c
> @@ -573,7 +573,7 @@ static int prepare_uprobe(struct uprobe
>  		goto out;
> 
>  	ret = -ENOTSUPP;
> -	if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn))
> +	if (is_trap_insn((uprobe_opcode_t *)uprobe->arch.insn))
>  		goto out;
> 
>  	ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, vaddr);

-- 
Thanks and Regards
Srikar Dronamraju

^ permalink raw reply

* Re: [PATCH v2 3/4] uprobes/powerpc: teach uprobes to ignore gdb breakpoints
From: Srikar Dronamraju @ 2013-03-26 12:06 UTC (permalink / raw)
  To: Ananth N Mavinakayanahalli; +Cc: ppcdev, lkml, oleg
In-Reply-To: <20130322151838.GD20010@in.ibm.com>

* Ananth N Mavinakayanahalli <ananth@in.ibm.com> [2013-03-22 20:48:38]:

> From: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
> 
> Powerpc has many trap variants that could be used by entities like gdb.
> Currently, running gdb on a program being traced by uprobes causes an
> endless loop since uprobes doesn't understand that the trap was inserted
> by some other entity and a SIGTRAP needs to be delivered.
> 
> Teach uprobes to ignore breakpoints that do not belong to it.
> 
> Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>

Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>

> ---
>  arch/powerpc/kernel/uprobes.c |   10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> Index: linux-3.9-rc3/arch/powerpc/kernel/uprobes.c
> ===================================================================
> --- linux-3.9-rc3.orig/arch/powerpc/kernel/uprobes.c
> +++ linux-3.9-rc3/arch/powerpc/kernel/uprobes.c
> @@ -31,6 +31,16 @@
>  #define UPROBE_TRAP_NR	UINT_MAX
> 
>  /**
> + * is_trap_insn - check if the instruction is a trap variant
> + * @insn: instruction to be checked.
> + * Returns true if @insn is a trap variant.
> + */
> +bool is_trap_insn(uprobe_opcode_t *insn)
> +{
> +	return (is_trap(*insn));
> +}
> +
> +/**
>   * arch_uprobe_analyze_insn
>   * @mm: the probed address space.
>   * @arch_uprobe: the probepoint information.

-- 
Thanks and Regards
Srikar Dronamraju

^ permalink raw reply

* Re: [PATCH v2 4/4] uprobes/powerpc: remove additional trap instruction check
From: Srikar Dronamraju @ 2013-03-26 12:07 UTC (permalink / raw)
  To: Ananth N Mavinakayanahalli; +Cc: ppcdev, lkml, oleg
In-Reply-To: <20130322151946.GE20010@in.ibm.com>

* Ananth N Mavinakayanahalli <ananth@in.ibm.com> [2013-03-22 20:49:46]:

> From: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
> 
> prepare_uprobe() already checks if the underlying unstruction
> (on file) is a trap variant. We don't need to check this again.
> 
> Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>

Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>

> ---
>  arch/powerpc/kernel/uprobes.c |    6 ------
>  1 file changed, 6 deletions(-)
> 
> Index: linux-3.9-rc3/arch/powerpc/kernel/uprobes.c
> ===================================================================
> --- linux-3.9-rc3.orig/arch/powerpc/kernel/uprobes.c
> +++ linux-3.9-rc3/arch/powerpc/kernel/uprobes.c
> @@ -53,12 +53,6 @@ int arch_uprobe_analyze_insn(struct arch
>  	if (addr & 0x03)
>  		return -EINVAL;
> 
> -	/*
> -	 * We currently don't support a uprobe on an already
> -	 * existing breakpoint instruction underneath
> -	 */
> -	if (is_trap(auprobe->ainsn))
> -		return -ENOTSUPP;
>  	return 0;
>  }
> 

-- 
Thanks and Regards
Srikar Dronamraju

^ permalink raw reply

* [PATCH v3, part4 28/39] mm/ppc: prepare for removing num_physpages and simplify mem_init()
From: Jiang Liu @ 2013-03-26 15:54 UTC (permalink / raw)
  To: Andrew Morton, David Rientjes
  Cc: linux-arch, James Bottomley, David Howells, Jiang Liu,
	Wen Congyang, linux-mm, linux-kernel, Michal Hocko, Minchan Kim,
	Paul Mackerras, Mel Gorman, Mark Salter, linuxppc-dev,
	Sergei Shtylyov, KAMEZAWA Hiroyuki, Jianguo Wu
In-Reply-To: <1364313298-17336-1-git-send-email-jiang.liu@huawei.com>

Prepare for removing num_physpages and simplify mem_init().

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-kernel@vger.kernel.org
---
Hi all,
	Sorry for my mistake that my previous patch series has been screwed up.
So I regenerate a third version and also set up a git tree at:
	git://github.com/jiangliu/linux.git mem_init
	Any help to review and test are welcomed!

	Regards!
	Gerry
---
 arch/powerpc/mm/mem.c |   56 +++++++++++--------------------------------------
 1 file changed, 12 insertions(+), 44 deletions(-)

diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 0e154a9..8aba687 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -303,46 +303,27 @@ void __init paging_init(void)
 
 void __init mem_init(void)
 {
-#ifdef CONFIG_NEED_MULTIPLE_NODES
-	int nid;
-#endif
-	pg_data_t *pgdat;
-	unsigned long i;
-	struct page *page;
-	unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
-
 #ifdef CONFIG_SWIOTLB
 	swiotlb_init(0);
 #endif
 
-	num_physpages = memblock_phys_mem_size() >> PAGE_SHIFT;
 	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
 
 #ifdef CONFIG_NEED_MULTIPLE_NODES
-        for_each_online_node(nid) {
-		if (NODE_DATA(nid)->node_spanned_pages != 0) {
-			printk("freeing bootmem node %d\n", nid);
-			free_all_bootmem_node(NODE_DATA(nid));
-		}
+	{
+		pg_data_t *pgdat;
+
+		for_each_online_pgdat(pgdat)
+			if (pgdat->node_spanned_pages != 0) {
+				printk("freeing bootmem node %d\n",
+					pgdat->node_id);
+				free_all_bootmem_node(pgdat);
+			}
 	}
 #else
 	max_mapnr = max_pfn;
 	free_all_bootmem();
 #endif
-	for_each_online_pgdat(pgdat) {
-		for (i = 0; i < pgdat->node_spanned_pages; i++) {
-			if (!pfn_valid(pgdat->node_start_pfn + i))
-				continue;
-			page = pgdat_page_nr(pgdat, i);
-			if (PageReserved(page))
-				reservedpages++;
-		}
-	}
-
-	codesize = (unsigned long)&_sdata - (unsigned long)&_stext;
-	datasize = (unsigned long)&_edata - (unsigned long)&_sdata;
-	initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin;
-	bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start;
 
 #ifdef CONFIG_HIGHMEM
 	{
@@ -352,13 +333,9 @@ void __init mem_init(void)
 		for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) {
 			phys_addr_t paddr = (phys_addr_t)pfn << PAGE_SHIFT;
 			struct page *page = pfn_to_page(pfn);
-			if (memblock_is_reserved(paddr))
-				continue;
-			free_highmem_page(page);
-			reservedpages--;
+			if (!memblock_is_reserved(paddr))
+				free_highmem_page(page);
 		}
-		printk(KERN_DEBUG "High memory: %luk\n",
-		       totalhigh_pages << (PAGE_SHIFT-10));
 	}
 #endif /* CONFIG_HIGHMEM */
 
@@ -371,16 +348,7 @@ void __init mem_init(void)
 		(mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) - 1;
 #endif
 
-	printk(KERN_INFO "Memory: %luk/%luk available (%luk kernel code, "
-	       "%luk reserved, %luk data, %luk bss, %luk init)\n",
-		nr_free_pages() << (PAGE_SHIFT-10),
-		num_physpages << (PAGE_SHIFT-10),
-		codesize >> 10,
-		reservedpages << (PAGE_SHIFT-10),
-		datasize >> 10,
-		bsssize >> 10,
-		initsize >> 10);
-
+	mem_init_print_info(NULL);
 #ifdef CONFIG_PPC32
 	pr_info("Kernel virtual memory layout:\n");
 	pr_info("  * 0x%08lx..0x%08lx  : fixmap\n", FIXADDR_START, FIXADDR_TOP);
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH 2/3] powerpc/mpic: add global timer support
From: Scott Wood @ 2013-03-26 17:31 UTC (permalink / raw)
  To: Wang Dongsheng-B40534
  Cc: Wood Scott-B07421, Gala Kumar-B11780,
	linuxppc-dev@lists.ozlabs.org, Li Yang-R58472
In-Reply-To: <ABB05CD9C9F68C46A5CEDC7F15439259EBAA0F@039-SN2MPN1-022.039d.mgd.msft.net>

On 03/25/2013 10:29:58 PM, Wang Dongsheng-B40534 wrote:
>=20
>=20
> > -----Original Message-----
> > From: Wood Scott-B07421
> > Sent: Saturday, March 23, 2013 6:30 AM
> > To: Wang Dongsheng-B40534
> > Cc: Wood Scott-B07421; Gala Kumar-B11780; =20
> linuxppc-dev@lists.ozlabs.org;
> > Li Yang-R58472
> > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
> >
> > On 03/22/2013 01:14:51 AM, Wang Dongsheng-B40534 wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Wood Scott-B07421
> > > > Sent: Thursday, March 21, 2013 7:00 AM
> > > > To: Wang Dongsheng-B40534
> > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > linuxppc-dev@lists.ozlabs.org;
> > > > Li Yang-R58472
> > > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
> > > >
> > > > BTW, the input clock frequency has been similarly scaled, yet =20
> you
> > > don't
> > > > try to scrounge up that information to get further precision...
> > > >
> > > Let's go back patch, do you think the code is repeated?
> > > I will remove "if (!(priv->flags & FSL_GLOBAL_TIMER))" branch, =20
> there
> > > will be no redundant code.
> >
> > I'd rather that branch be kept and the more complicated branch =20
> deleted,
> > and priv->timerfreq frequency be adjusted on initialization to =20
> account
> > for the scaler.
>=20
> static void convert_ticks_to_time(struct timer_group_priv *priv,
>                 const u64 ticks, struct timeval *time)
> {
>         u64 tmp_sec;
>=20
>         time->tv_sec =3D (__kernel_time_t)div_u64(ticks, =20
> priv->timerfreq);
>         tmp_sec =3D (u64)time->tv_sec * (u64)priv->timerfreq;
>=20
>         time->tv_usec =3D (__kernel_suseconds_t)
>                 div_u64((ticks - tmp_sec) * 1000000, priv->timerfreq);
>=20
>         return;
> }
>=20
> timer_group_get_freq() {
> 	...
> 	if (priv->flags & FSL_GLOBAL_TIMER) {
> 		div =3D (1 << (MPIC_TIMER_TCR_CLKDIV_64 >> 8)) * 8;
> 		priv->timerfreq /=3D div;
> 	}
> 	...
> }
> Do you want to do that?

	if (priv->flags & FSL_GLOBAL_TIMER)
		priv->timerfreq /=3D 64;

...but otherwise yes.

-Scott=

^ permalink raw reply

* Re: [PATCH] [RFC] powerpc: Add VDSO version of time
From: Adhemerval Zanella @ 2013-03-26 17:32 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <514B0DCD.5020209@linux.vnet.ibm.com>

Hi all,

Just sending a ping about this patch.

On 21-03-2013 10:40, Adhemerval Zanella wrote:
> On 20-03-2013 02:00, Benjamin Herrenschmidt wrote:
>> On Tue, 2013-03-19 at 16:55 -0300, Adhemerval Zanella wrote:
>>> I focused on 64 bit kernel, do I need to provide a scheme for 32 bits
>>> as well?
>> You did provide both 32 and 64-bit VDSO implementations so 32-bit
>> kernels should be covered.
> Indeed and thanks for the reply. Any objection or request about including it?
>
> Thanks.
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>

^ permalink raw reply

* Re: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup support
From: Scott Wood @ 2013-03-26 17:35 UTC (permalink / raw)
  To: Wang Dongsheng-B40534
  Cc: Wood Scott-B07421, Gala Kumar-B11780,
	linuxppc-dev@lists.ozlabs.org, Li Yang-R58472,
	Zhao Chenhui-B35336
In-Reply-To: <ABB05CD9C9F68C46A5CEDC7F15439259EBA9F7@039-SN2MPN1-022.039d.mgd.msft.net>

On 03/25/2013 10:27:24 PM, Wang Dongsheng-B40534 wrote:
>=20
>=20
> > -----Original Message-----
> > From: Wood Scott-B07421
> > Sent: Saturday, March 23, 2013 6:11 AM
> > To: Wang Dongsheng-B40534
> > Cc: Wood Scott-B07421; Gala Kumar-B11780; =20
> linuxppc-dev@lists.ozlabs.org;
> > Zhao Chenhui-B35336; Li Yang-R58472
> > Subject: Re: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup support
> >
> > On 03/22/2013 12:46:24 AM, Wang Dongsheng-B40534 wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Wood Scott-B07421
> > > > Sent: Thursday, March 21, 2013 5:49 AM
> > > > To: Wang Dongsheng-B40534
> > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > linuxppc-dev@lists.ozlabs.org;
> > > > Zhao Chenhui-B35336; Li Yang-R58472
> > > > Subject: Re: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup =20
> support
> > > >
> > > > On 03/19/2013 10:48:53 PM, Wang Dongsheng-B40534 wrote:
> > > > > 	while (*s) {
> > > > > 		if ('0' <=3D *s && *s <=3D '9')
> > > > > 			val =3D *s - '0';
> > > > > 		else if ('a' <=3D _tolower(*s) && _tolower(*s) <=3D =20
> 'f')
> > > > > 			val =3D _tolower(*s) - 'a' + 10;
> > > > > 		else
> > > > > 			break;	//this will break out to =20
> convert.
> > > >
> > > > Really?  How do you know that the next byte after the buffer =20
> isn't a
> > > > valid hex digit?  How do you even know that we won't take a =20
> fault
> > > > accessing it?
> > > >
> > > Under what case is unsafe, please make sense.
> >
> > char buffer[1] =3D { '5' };
> > write(fd, &buffer, 1);
> >
> > What comes after that '5' byte in the pointer you pass to kstrtol?
> >
> The buffer is userspace. It will fall in the kernel space.
> Kernel will get a free page, and copy the buffer to page.
> This page has been cleared before copy to page.
> The page has already have null-terminated.

It doesn't allocate a whole page, it uses kmalloc (not kzalloc!).  Even =20
if kzalloc were used, a larger user buffer could be the exact size of =20
the region that was allocated.

See memdup_user() in mm/util.c

-Scott=

^ permalink raw reply

* [PATCH 0/3] mm: avoid duplication of setup_nr_node_ids()
From: Cody P Schafer @ 2013-03-26 17:45 UTC (permalink / raw)
  To: linux-mm
  Cc: linuxppc-dev, linux-kernel, Ingo Molnar, Paul Mackerras,
	H. Peter Anvin, Andrew Morton, Cody P Schafer, Thomas Gleixner

In arch/powerpc, arch/x86, and mm/page_alloc code to setup nr_node_ids based on
node_possible_map is duplicated.

This patchset switches those copies to calling the function provided by page_alloc.

^ permalink raw reply

* [PATCH 1/3] page_alloc: make setup_nr_node_ids() usable for arch init code
From: Cody P Schafer @ 2013-03-26 17:46 UTC (permalink / raw)
  To: linux-mm
  Cc: linuxppc-dev, linux-kernel, Ingo Molnar, Paul Mackerras,
	H. Peter Anvin, Andrew Morton, Cody P Schafer, Thomas Gleixner
In-Reply-To: <1364319962-30967-1-git-send-email-cody@linux.vnet.ibm.com>

powerpc and x86 were opencoding copies of setup_nr_node_ids(), which
page_alloc provides but makes static. Make it avaliable to the archs in
linux/mm.h.

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
---
 include/linux/mm.h | 6 ++++++
 mm/page_alloc.c    | 6 +-----
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7acc9dc..3405405 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1755,5 +1755,11 @@ static inline unsigned int debug_guardpage_minorder(void) { return 0; }
 static inline bool page_is_guard(struct page *page) { return false; }
 #endif /* CONFIG_DEBUG_PAGEALLOC */
 
+#if MAX_NUMNODES > 1
+void __init setup_nr_node_ids(void);
+#else
+static inline void setup_nr_node_ids(void) {}
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_MM_H */
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 8fcced7..96909bb 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -4710,7 +4710,7 @@ void __paginginit free_area_init_node(int nid, unsigned long *zones_size,
 /*
  * Figure out the number of possible node ids.
  */
-static void __init setup_nr_node_ids(void)
+void __init setup_nr_node_ids(void)
 {
 	unsigned int node;
 	unsigned int highest = 0;
@@ -4719,10 +4719,6 @@ static void __init setup_nr_node_ids(void)
 		highest = node;
 	nr_node_ids = highest + 1;
 }
-#else
-static inline void setup_nr_node_ids(void)
-{
-}
 #endif
 
 /**
-- 
1.8.2

^ permalink raw reply related

* [PATCH 3/3] powerpc/mm/numa: use setup_nr_node_ids() instead of opencoding.
From: Cody P Schafer @ 2013-03-26 17:46 UTC (permalink / raw)
  To: linux-mm
  Cc: linuxppc-dev, linux-kernel, Ingo Molnar, Paul Mackerras,
	H. Peter Anvin, Andrew Morton, Cody P Schafer, Thomas Gleixner
In-Reply-To: <1364319962-30967-1-git-send-email-cody@linux.vnet.ibm.com>

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
---
 arch/powerpc/mm/numa.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index bba87ca..7574ae3 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -62,14 +62,11 @@ static int distance_lookup_table[MAX_NUMNODES][MAX_DISTANCE_REF_POINTS];
  */
 static void __init setup_node_to_cpumask_map(void)
 {
-	unsigned int node, num = 0;
+	unsigned int node;
 
 	/* setup nr_node_ids if not done yet */
-	if (nr_node_ids == MAX_NUMNODES) {
-		for_each_node_mask(node, node_possible_map)
-			num = node;
-		nr_node_ids = num + 1;
-	}
+	if (nr_node_ids == MAX_NUMNODES)
+		setup_nr_node_ids()
 
 	/* allocate the map */
 	for (node = 0; node < nr_node_ids; node++)
-- 
1.8.2

^ permalink raw reply related

* [PATCH 2/3] x86/mm/numa: use setup_nr_node_ids() instead of opencoding.
From: Cody P Schafer @ 2013-03-26 17:46 UTC (permalink / raw)
  To: linux-mm
  Cc: linuxppc-dev, linux-kernel, Ingo Molnar, Paul Mackerras,
	H. Peter Anvin, Andrew Morton, Cody P Schafer, Thomas Gleixner
In-Reply-To: <1364319962-30967-1-git-send-email-cody@linux.vnet.ibm.com>

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
---
 arch/x86/mm/numa.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index 72fe01e..a71c4e2 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -114,14 +114,11 @@ void numa_clear_node(int cpu)
  */
 void __init setup_node_to_cpumask_map(void)
 {
-	unsigned int node, num = 0;
+	unsigned int node;
 
 	/* setup nr_node_ids if not done yet */
-	if (nr_node_ids == MAX_NUMNODES) {
-		for_each_node_mask(node, node_possible_map)
-			num = node;
-		nr_node_ids = num + 1;
-	}
+	if (nr_node_ids == MAX_NUMNODES)
+		setup_nr_node_ids();
 
 	/* allocate the map */
 	for (node = 0; node < nr_node_ids; node++)
-- 
1.8.2

^ permalink raw reply related

* Re: [PATCH 2/3] x86/mm/numa: use setup_nr_node_ids() instead of opencoding.
From: Yinghai Lu @ 2013-03-26 17:56 UTC (permalink / raw)
  To: Cody P Schafer
  Cc: linux-kernel, linux-mm, Ingo Molnar, Paul Mackerras,
	H. Peter Anvin, Andrew Morton, linuxppc-dev, Thomas Gleixner
In-Reply-To: <1364319962-30967-3-git-send-email-cody@linux.vnet.ibm.com>

On Tue, Mar 26, 2013 at 10:46 AM, Cody P Schafer
<cody@linux.vnet.ibm.com> wrote:
> Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
> ---
>  arch/x86/mm/numa.c | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)
>
> diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
> index 72fe01e..a71c4e2 100644
> --- a/arch/x86/mm/numa.c
> +++ b/arch/x86/mm/numa.c
> @@ -114,14 +114,11 @@ void numa_clear_node(int cpu)
>   */
>  void __init setup_node_to_cpumask_map(void)
>  {
> -       unsigned int node, num = 0;
> +       unsigned int node;
>
>         /* setup nr_node_ids if not done yet */
> -       if (nr_node_ids == MAX_NUMNODES) {
> -               for_each_node_mask(node, node_possible_map)
> -                       num = node;
> -               nr_node_ids = num + 1;
> -       }
> +       if (nr_node_ids == MAX_NUMNODES)
> +               setup_nr_node_ids();

For 1 and 2,

Acked-by: Yinghai Lu <yinghai@kernel.org>

^ permalink raw reply

* Re: [PATCHv2 1/3] pci: added pcie_get_speed_cap_mask function
From: Bjorn Helgaas @ 2013-03-26 18:39 UTC (permalink / raw)
  To: Lucas Kannebley Tavares
  Cc: David Airlie, linux-pci@vger.kernel.org, DRI mailing list,
	Alex Deucher, Thadeu Cascardo, Brian King, linuxppc-dev
In-Reply-To: <1363757079-23550-2-git-send-email-lucaskt@linux.vnet.ibm.com>

On Tue, Mar 19, 2013 at 11:24 PM, Lucas Kannebley Tavares
<lucaskt@linux.vnet.ibm.com> wrote:
> Added function to gather the speed cap for a device and return a mask to
> supported speeds. The function is divided into an interface and a weak
> implementation so that architecture-specific functions can be called.
>
> This is the first step in moving function drm_pcie_get_speed_cap_mask
> from the drm subsystem to the pci one.

This still doesn't feel right to me.

I'm definitely not a hardware guy, but my understanding based on the
PCIe spec r3.0, sec 6.11, is that the hardware will automatically
maintain the link at the highest speed supported by both ends of the
link, unless software sets a lower Target Link Speed.  The only users
of this function are some Radeon drivers, and it looks like they only
use it because the hardware doesn't conform to this aspect of the spec
and requires device-specific tweaking.

We already have bus->max_bus_speed, which should tell you the max
speed supported by the upstream component.  Is that enough
information?  Maybe the radeon drivers could simply do something like
this:

    speed = rdev->ddev->pdev->bus->max_bus_speed;
    if (speed == PCI_SPEED_UNKNOWN || speed < PCIE_SPEED_5_0GT)
        return;

In your original email [1], you mentioned a null pointer dereference,
presumably when reading the PCIe capability for dev->pdev->bus->self,
with "self" being NULL.  This only happens for a bus with no upstream
P2P bridge, i.e., self will be NULL only if pdev is on a root bus.
But we also know pdev is a PCIe device, and I think a PCIe device on a
root bus must be a "Root Complex Integrated Endpoint" (PCIe spec sec
1.3.2.3).  Such a device does not have a link at all, so there's no
point in fiddling with its link speed.

I don't see how a radeon device could be an integrated endpoint, but
in your hypervisor environment, maybe it isn't quite spec-compliant in
terms of its attachment.  Can you collect the output of "lspci -vv"?
Maybe that will make things clearer.

In any case, if a radeon device is on a root bus, I think the root bus
max_bus_speed will be PCI_SPEED_UNKNOWN, and if it's not on a root
bus, max_bus_speed should be set correctly based on the upstream PCIe
port.

Bjorn

[1] http://lkml.kernel.org/r/50819140.8030806@linux.vnet.ibm.com

> Signed-off-by: Lucas Kannebley Tavares <lucaskt@linux.vnet.ibm.com>
> ---
>  drivers/pci/pci.c   |   44 ++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/pci.h |    6 ++++++
>  2 files changed, 50 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index b099e00..d94ab79 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -3931,6 +3931,50 @@ static int __init pci_setup(char *str)
>  }
>  early_param("pci", pci_setup);
>
> +int __weak pcibios_get_speed_cap_mask(struct pci_dev *dev, u32 *mask)
> +{
> +       struct pci_dev *root;
> +       u32 lnkcap, lnkcap2;
> +
> +       *mask = 0;
> +       if (!dev)
> +               return -EINVAL;
> +
> +       root = dev->bus->self;
> +
> +       /* we've been informed via and serverworks don't make the cut */
> +       if (root->vendor == PCI_VENDOR_ID_VIA ||
> +           root->vendor == PCI_VENDOR_ID_SERVERWORKS)
> +               return -EINVAL;
> +
> +       pcie_capability_read_dword(root, PCI_EXP_LNKCAP, &lnkcap);
> +       pcie_capability_read_dword(root, PCI_EXP_LNKCAP2, &lnkcap2);
> +
> +       if (lnkcap2) {  /* PCIe r3.0-compliant */
> +               if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_2_5GB)
> +                       *mask |= PCIE_SPEED_25;
> +               if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_5_0GB)
> +                       *mask |= PCIE_SPEED_50;
> +               if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB)
> +                       *mask |= PCIE_SPEED_80;
> +       } else {        /* pre-r3.0 */
> +               if (lnkcap & PCI_EXP_LNKCAP_SLS_2_5GB)
> +                       *mask |= PCIE_SPEED_25;
> +               if (lnkcap & PCI_EXP_LNKCAP_SLS_5_0GB)
> +                       *mask |= (PCIE_SPEED_25 | PCIE_SPEED_50);
> +       }
> +
> +       dev_info(&dev->dev, "probing gen 2 caps for device %x:%x = %x/%x\n",
> +               root->vendor, root->device, lnkcap, lnkcap2);
> +       return 0;
> +}
> +
> +int pcie_get_speed_cap_mask(struct pci_dev *dev, u32 *mask)
> +{
> +       return pcibios_get_speed_cap_mask(dev, mask);
> +}
> +EXPORT_SYMBOL(pcie_get_speed_cap_mask);
> +
>  EXPORT_SYMBOL(pci_reenable_device);
>  EXPORT_SYMBOL(pci_enable_device_io);
>  EXPORT_SYMBOL(pci_enable_device_mem);
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 2461033a..24a2f63 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1861,4 +1861,10 @@ static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
>   */
>  struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev);
>
> +#define PCIE_SPEED_25 1
> +#define PCIE_SPEED_50 2
> +#define PCIE_SPEED_80 4
> +
> +extern int pcie_get_speed_cap_mask(struct pci_dev *dev, u32 *speed_mask);
> +
>  #endif /* LINUX_PCI_H */
> --
> 1.7.4.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH 4/7 v2] KVM: PPC: e500: Add support for EPTCFG register
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm
In-Reply-To: <1364335512-28426-1-git-send-email-mihai.caraman@freescale.com>

EPTCFG register defined by E.PT is accessed unconditionally by Linux guests
in the presence of MAV 2.0. Support it now.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Use has_feature() function

 Documentation/virtual/kvm/api.txt   |    1 +
 arch/powerpc/include/asm/kvm_host.h |    1 +
 arch/powerpc/include/uapi/asm/kvm.h |    1 +
 arch/powerpc/kvm/e500.h             |    5 +++++
 arch/powerpc/kvm/e500_emulate.c     |    9 +++++++++
 arch/powerpc/kvm/e500_mmu.c         |   11 +++++++++++
 6 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index f045377..a1f2200 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1807,6 +1807,7 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_TLB1PS	| 32
   PPC   | KVM_REG_PPC_TLB2PS	| 32
   PPC   | KVM_REG_PPC_TLB3PS	| 32
+  PPC   | KVM_REG_PPC_EPTCFG	| 32
 
 ARM registers are mapped using the lower 32 bits.  The upper 16 of that
 is the register group type, or coprocessor number:
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 3b6cee3..8a48e68 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -504,6 +504,7 @@ struct kvm_vcpu_arch {
 	u32 tlbcfg[4];
 	u32 tlbps[4];
 	u32 mmucfg;
+	u32 eptcfg;
 	u32 epr;
 	u32 crit_save;
 	struct kvmppc_booke_debug_reg dbg_reg;
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 7cfd13f..9d7fbf0 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -443,4 +443,5 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_TLB1PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97)
 #define KVM_REG_PPC_TLB2PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
 #define KVM_REG_PPC_TLB3PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
+#define KVM_REG_PPC_EPTCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a)
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index 795934d..6cfc669 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -24,6 +24,7 @@
 #include <asm/tlb.h>
 
 #define VCPU_FTR_MMU_V2		0
+#define VCPU_FTR_E_PT		1
 
 #define E500_PID_NUM   3
 #define E500_TLB_NUM   2
@@ -309,6 +310,10 @@ static inline bool has_feature(const struct kvm_vcpu *vcpu,
 	case VCPU_FTR_MMU_V2:
 		has_ftr = ((vcpu->arch.mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2);
 		break;
+	case VCPU_FTR_E_PT:
+		has_ftr = ((vcpu->arch.tlbcfg[1] & TLBnCFG_IND) &&
+			   (vcpu->arch.tlbcfg[0] & TLBnCFG_PT));
+		break;
 	default:
 		has_ftr = false;
 	}
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index 12b8de2..b10a012 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -317,6 +317,15 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
 	case SPRN_MMUCFG:
 		*spr_val = vcpu->arch.mmucfg;
 		break;
+	case SPRN_EPTCFG:
+		if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
+			return EMULATE_FAIL;
+		/*
+		 * Legacy Linux guests access EPTCFG register even if the E.PT
+		 * category is disabled in the VM. Give them a chance to live.
+		 */
+		*spr_val = vcpu->arch.eptcfg;
+		break;
 
 	/* extra exceptions */
 	case SPRN_IVOR32:
diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index e354fa1..cf60db1 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -617,6 +617,8 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 		*val = get_reg_val(id, vcpu->arch.shared->mas6);
 	case KVM_REG_PPC_MMUCFG:
 		*val = get_reg_val(id, vcpu->arch.mmucfg);
+	case KVM_REG_PPC_EPTCFG:
+		*val = get_reg_val(id, vcpu->arch.eptcfg);
 	case KVM_REG_PPC_TLB0CFG:
 	case KVM_REG_PPC_TLB1CFG:
 	case KVM_REG_PPC_TLB2CFG:
@@ -668,6 +670,10 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
 			r = -EINVAL;
 		break;
 	}
+	case KVM_REG_PPC_EPTCFG:
+		if (set_reg_val(id, *val) != vcpu->arch.eptcfg)
+			r = -EINVAL;
+		break;
 	case KVM_REG_PPC_TLB0CFG:
 	case KVM_REG_PPC_TLB1CFG:
 	case KVM_REG_PPC_TLB2CFG:
@@ -861,6 +867,11 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
 	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
 
 	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
+		if (has_feature(vcpu, VCPU_FTR_E_PT))
+			vcpu->arch.eptcfg = mfspr(SPRN_EPTCFG);
+		else
+			vcpu->arch.eptcfg = 0;
+
 		vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
 		vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
 	}
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
From: Mihai Caraman @ 2013-03-26 22:05 UTC (permalink / raw)
  To: kvm-ppc; +Cc: Mihai Caraman, linuxppc-dev, kvm
In-Reply-To: <1364335512-28426-1-git-send-email-mihai.caraman@freescale.com>

Embedded.Page Table (E.PT) category in VMs requires indirect tlb entries
emulation which is not supported yet. Configure TLBnCFG to remove E.PT
and E.HV.LRAT categories from VCPUs.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - Remove E.HV.LRAT from vcpus

 arch/powerpc/kvm/e500_mmu.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index cf60db1..0d2a293 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -867,11 +867,17 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
 	vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
 
 	if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
+		vcpu->arch.mmucfg &= ~MMUCFG_LRAT;
+
 		if (has_feature(vcpu, VCPU_FTR_E_PT))
 			vcpu->arch.eptcfg = mfspr(SPRN_EPTCFG);
 		else
 			vcpu->arch.eptcfg = 0;
 
+		/* Guest mmu emulation currently doesn't handle E.PT */
+		vcpu->arch.tlbcfg[0] &= ~TLBnCFG_PT;
+		vcpu->arch.tlbcfg[1] &= ~TLBnCFG_IND;
+
 		vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
 		vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
 	}
-- 
1.7.4.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox