* Re: Dead mappings and drivers in MTD
From: Olof Johansson @ 2013-03-11 16:20 UTC (permalink / raw)
To: dedekind1; +Cc: linuxppc-dev, linux-mtd, LKML, linux-arm-kernel
In-Reply-To: <1363016099.3348.47.camel@sauron.fi.intel.com>
On Mon, Mar 11, 2013 at 8:34 AM, Artem Bityutskiy <dedekind1@gmail.com> wrote:
> Hi MTD folks,
>
> we have huge amount of drivers, espacially mapping drives in
> 'drivers/mtd', and for sure may of them are for ancient devices which
> are long dead and not supported by modern kernels anyway. I would like
> to do a small clean-up. It is difficult to judge which ones are dead for
> me, so I am asking the community to help. Thanks!
>
> There are few easy cases - some drivers depend on Kconfig symbols which
> are not defined anywhere - I guess these are clear candidates for
> removal. For example this one:
>
> config MTD_DBOX2
> tristate "CFI Flash device mapped on D-Box2"
> depends on DBOX2 && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD
> help
> This enables access routines for the flash chips on the Nokia/Sagem
> D-Box 2 board. If you have one of these boards and would like to use
>
> Grepping for "DBOX2" gives nothing.
In 2.6.14, it dropped two dependencies that used to be there for PPC32
and 8xx. There still was no DBOX2 symbol to fulfill that dependency
back then.
Take it out, if someone finds a user later on it can always be
reverted. Seems very very unlikely in this case.
-Olof
^ permalink raw reply
* Re: Dead mappings and drivers in MTD
From: Artem Bityutskiy @ 2013-03-11 16:43 UTC (permalink / raw)
To: Olof Johansson
Cc: linux-pcmcia, LKML, linuxppc-dev, linux-m68k, linux-mtd,
linux-arm-kernel
In-Reply-To: <CAOesGMhy6YceRr3T4ZALhYeSQfEuASO+ajJy1Htwws=OMtvrTg@mail.gmail.com>
On Mon, 2013-03-11 at 09:20 -0700, Olof Johansson wrote:
> On Mon, Mar 11, 2013 at 8:34 AM, Artem Bityutskiy <dedekind1@gmail.com> wrote:
> > Hi MTD folks,
> >
> > we have huge amount of drivers, espacially mapping drives in
> > 'drivers/mtd', and for sure may of them are for ancient devices which
> > are long dead and not supported by modern kernels anyway. I would like
> > to do a small clean-up. It is difficult to judge which ones are dead for
> > me, so I am asking the community to help. Thanks!
> >
> > There are few easy cases - some drivers depend on Kconfig symbols which
> > are not defined anywhere - I guess these are clear candidates for
> > removal. For example this one:
> >
> > config MTD_DBOX2
> > tristate "CFI Flash device mapped on D-Box2"
> > depends on DBOX2 && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD
> > help
> > This enables access routines for the flash chips on the Nokia/Sagem
> > D-Box 2 board. If you have one of these boards and would like to use
> >
> > Grepping for "DBOX2" gives nothing.
>
> In 2.6.14, it dropped two dependencies that used to be there for PPC32
> and 8xx. There still was no DBOX2 symbol to fulfill that dependency
> back then.
>
> Take it out, if someone finds a user later on it can always be
> reverted. Seems very very unlikely in this case.
I agree, thanks. I've quickly went through all the MTD map drivers and
found many candidates for removal. I did not prepare a patch-set yet,
but the below commit messages from my tree should give enough info about
what I am thinking to remove.
Author: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Date: Mon Mar 11 18:24:37 2013 +0200
mtd: remove the mbx860 map driver
This driver depends on CONFIG_MBX which is not defined anywhere, which means
this driver is dead.
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
drivers/mtd/maps/Kconfig | 9 --
drivers/mtd/maps/Makefile | 1 -
drivers/mtd/maps/ixp2000.c | 253 --------------------------------------------
3 files changed, 263 deletions(-)
commit 3e8b189c4fad6196333fb2069ab1f183b652a81d
Author: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Date: Mon Mar 11 18:10:06 2013 +0200
mtd: remove the dilnetpc map driver support
This driver is marked as broken for very long time. Most probably this board is
just something ancient no one cares about anyway.
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
drivers/mtd/maps/Kconfig | 16 --
drivers/mtd/maps/Makefile | 1 -
drivers/mtd/maps/dilnetpc.c | 496 -------------------------------------------
3 files changed, 513 deletions(-)
commit e9313043d5bb4b2429b60092ebd9974598b5b62d
Author: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Date: Mon Mar 11 18:07:35 2013 +0200
mtd: remove the tqm8xxl map driver
This driver depends on the CONFIG_TQM8xxL symbol, which is not defined
anywhere, which means that this driver is dead.
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
drivers/mtd/maps/Kconfig | 10 --
drivers/mtd/maps/Makefile | 1 -
drivers/mtd/maps/tqm8xxl.c | 249 --------------------------------------------
3 files changed, 260 deletions(-)
commit 1b17ddb0219d9ab6b96a2bc22331d89ac4ca4539
Author: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Date: Mon Mar 11 18:05:13 2013 +0200
pcmcia: remove RPX board stuff
The RPX board is not supported by the kernel because CONFIG_RPXCLASSIC and
CONFIG_RPXLITE symbols and not defined anywhere. Clean-up the m8xx_pcmcia
driver a little bit.
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
drivers/pcmcia/m8xx_pcmcia.c | 81 ------------------------------------------
1 file changed, 81 deletions(-)
commit 518fa5d9718cbe00ed3de3798761cc051dcef04b
Author: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Date: Mon Mar 11 18:03:11 2013 +0200
m68k: remove rpxlite stuff
The CONFIG_RPXLITE is not defined anywhere, which means that this board is not
supported anyway, and we can clean-up commproc.h a little.
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
arch/m68k/include/asm/commproc.h | 17 -----------------
1 file changed, 17 deletions(-)
commit de70cc56d0c067275c3cac5659196d9ef4043888
Author: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Date: Mon Mar 11 18:01:02 2013 +0200
mtd: maps: kill the rpxlite map driver
This driver depends on the CONFIG_RPXCLASSIC and CONFIG_RPXLITE symbols, which
are not defined anywhere, and this means that this driver is dead.
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
drivers/mtd/maps/Kconfig | 10 -------
drivers/mtd/maps/Makefile | 1 -
drivers/mtd/maps/rpxlite.c | 64 --------------------------------------------
3 files changed, 75 deletions(-)
commit 1ebbc11e1e2a143308689af47bb766824c035285
Author: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Date: Mon Mar 11 17:56:31 2013 +0200
pcmcia: remove Motorolla MBX860 support
The CONFIG_MBX symbol is not defined anywhere in the kernel tree, which means
this platform is not supported by the Linux kernel and we can remove the
corresponding code from the 'm8xx_pcmcia' driver.
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
drivers/pcmcia/m8xx_pcmcia.c | 59 ------------------------------------------
1 file changed, 59 deletions(-)
commit 61f417243e1157d436ac04b1307f40b2996a4923
Author: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Date: Mon Mar 11 17:54:11 2013 +0200
mtd: remove the mbx860 map driver
This driver depends on CONFIG_MBX which is not defined anywhere, which means
this driver is dead.
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
drivers/mtd/maps/Kconfig | 8 ----
drivers/mtd/maps/Makefile | 1 -
drivers/mtd/maps/mbx860.c | 98 ---------------------------------------------
3 files changed, 107 deletions(-)
commit 55c159005c92a7ce8234c6d0072d8d2f6e45a57d
Author: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Date: Mon Mar 11 17:42:54 2013 +0200
mtd: remove the dmv182 map driver
This driver depends on the CONFIG_DMV182 symbol which is not defined anywhere,
and this means that this driver is dead.
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
drivers/mtd/maps/Kconfig | 9 ---
drivers/mtd/maps/Makefile | 1 -
drivers/mtd/maps/dmv182.c | 146 ---------------------------------------------
3 files changed, 156 deletions(-)
commit 750b26e3b17a148a7a7d64026088d1e29f9cd118
Author: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Date: Mon Mar 11 17:38:43 2013 +0200
mtd: remove the dbox2-flash map driver
This driver depends on the CONFIG_DBOX2 symbol which does not exist in
the kernel, which means the driver is dead.
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
drivers/mtd/maps/Kconfig | 8 ---
drivers/mtd/maps/Makefile | 1 -
drivers/mtd/maps/dbox2-flash.c | 123 ----------------------------------------
3 files changed, 132 deletions(-)
--
Best Regards,
Artem Bityutskiy
^ permalink raw reply
* Re: [PATCH] Make PCIe hotplug work with Freescale PCIe controllers
From: Kumar Gala @ 2013-03-11 17:17 UTC (permalink / raw)
To: Rojhalat Ibrahim; +Cc: linuxppc-dev
In-Reply-To: <3989200.gO920IVs04@pcimr>
On Mar 11, 2013, at 9:47 AM, Rojhalat Ibrahim wrote:
> Hi,
>=20
> this issue was brought up before.=20
> See this thread: =
https://lists.ozlabs.org/pipermail/linuxppc-dev/2012-July/099529.html
>=20
> The following patch works for me.
> Hot-added devices appear after "echo 1 > /sys/bus/pci/rescan".
> I tested it with a P5020DS development system.
>=20
> Signed-off-by: Rojhalat Ibrahim <imr@rtschenk.de>
> ---
> arch/powerpc/sysdev/indirect_pci.c | 53 =
++++++++++++++++++++++++++++++-------
> 1 file changed, 44 insertions(+), 9 deletions(-)
Rather than do it this way, we should do something like:
fsl_indirect_read_config() {
link check
if (link)
indirect_read_config()
}
and just add fsl_indirect_{r,w}_config into fsl_pci.c
- k
>=20
> diff --git a/arch/powerpc/sysdev/indirect_pci.c =
b/arch/powerpc/sysdev/indirect_pci.c
> index 82fdad8..aa36009 100644
> --- a/arch/powerpc/sysdev/indirect_pci.c
> +++ b/arch/powerpc/sysdev/indirect_pci.c
> @@ -20,22 +20,19 @@
> #include <asm/pci-bridge.h>
> #include <asm/machdep.h>
>=20
> +#ifdef CONFIG_FSL_PCI
> +#include <sysdev/fsl_pci.h>
> +#endif
> +
> static int
> -indirect_read_config(struct pci_bus *bus, unsigned int devfn, int =
offset,
> - int len, u32 *val)
> +read_config_no_link_check(struct pci_bus *bus, unsigned int devfn, =
int offset,
> + int len, u32 *val)
> {
> struct pci_controller *hose =3D pci_bus_to_host(bus);
> volatile void __iomem *cfg_data;
> u8 cfg_type =3D 0;
> u32 bus_no, reg;
>=20
> - if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK) {
> - if (bus->number !=3D hose->first_busno)
> - return PCIBIOS_DEVICE_NOT_FOUND;
> - if (devfn !=3D 0)
> - return PCIBIOS_DEVICE_NOT_FOUND;
> - }
> -
> if (ppc_md.pci_exclude_device)
> if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
> return PCIBIOS_DEVICE_NOT_FOUND;
> @@ -78,6 +75,44 @@ indirect_read_config(struct pci_bus *bus, unsigned =
int devfn, int offset,
> return PCIBIOS_SUCCESSFUL;
> }
>=20
> +#ifdef CONFIG_FSL_PCI
> +static int fsl_pcie_check_link(struct pci_bus *bus)
> +{
> + struct pci_controller *hose =3D pci_bus_to_host(bus);
> + u32 val =3D 0;
> +
> + read_config_no_link_check(bus, 0, PCIE_LTSSM, 4, &val);
> + if (val < PCIE_LTSSM_L0) {
> + hose->indirect_type |=3D PPC_INDIRECT_TYPE_NO_PCIE_LINK;
> + return 1;
> + } else {
> + hose->indirect_type &=3D =
~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
> + return 0;
> + }
> +}
> +#endif
> +
> +static int
> +indirect_read_config(struct pci_bus *bus, unsigned int devfn, int =
offset,
> + int len, u32 *val)
> +{
> + struct pci_controller *hose =3D pci_bus_to_host(bus);
> +
> +#ifdef CONFIG_FSL_PCI
> + if ((bus->number =3D=3D hose->first_busno) && (devfn =3D=3D 0)) =
{
> + fsl_pcie_check_link(bus);
> + }
> +#endif
> + if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK) {
> + if (bus->number !=3D hose->first_busno)
> + return PCIBIOS_DEVICE_NOT_FOUND;
> + if (devfn !=3D 0)
> + return PCIBIOS_DEVICE_NOT_FOUND;
> + }
> +
> + return read_config_no_link_check(bus, devfn, offset, len, val);
> +}
> +
> static int
> indirect_write_config(struct pci_bus *bus, unsigned int devfn, int =
offset,
> int len, u32 val)
^ permalink raw reply
* Re: Linux kernel 3.x problems on PowerMac G5
From: Phileas Fogg @ 2013-03-11 19:31 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linuxppc-dev, Denis Kirjanov, Andreas Schwab, Aaro Koskinen
In-Reply-To: <1362919948.4534.1.camel@pasglop>
On 03/10/2013 01:52 PM, Benjamin Herrenschmidt wrote:
> On Sun, 2013-03-10 at 11:53 +0100, Phileas Fogg wrote:
>> Good news :) I found the bug.
>> MMU features were not set properly for PPC970MP DD1.0 which,
>> unfortunately, my machine has.
>> Damn, one line fix but one week searching.
>> Linux 3.8.2 boots without problems now :)
>
> Nice one ! I didn't think anybody shipped a DD1.0 chip ! :-)
>
> Looks like some typo/thinko in the cputable and you are one of the very
> rare victims of it. I'll fix that up. Regarding the IDE problem, can you
> shoot a note to Tejun who wrote that patch (and CC me) ? I do recommend
> switching to libata but we should still fix the problem with legacy IDE.
>
> Cheers,
> Ben.
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
The IDE-CD bug appears to be already fixed. I tested g5_defconfig with
Linux 3.8.2 and it boots OK. I think i saw a commit regarding this issue
in git.
Regards
^ permalink raw reply
* Re: [PATCH] powerpc: Use PTR_RET instead of IS_ERR/PTR_ERR
From: Geoff Levand @ 2013-03-11 21:36 UTC (permalink / raw)
To: Adrian-Leonard Radu
Cc: cbe-oss-dev, fweisbec, akinobu.mita, rostedt, linux-kernel,
paulus, anton, john.stultz, linuxppc-dev, cascardo
In-Reply-To: <1362920820-11073-1-git-send-email-ady8radu@gmail.com>
On Sun, 2013-03-10 at 15:07 +0200, Adrian-Leonard Radu wrote:
> Signed-off-by: Adrian-Leonard Radu <ady8radu@gmail.com>
> ---
> arch/powerpc/kernel/iommu.c | 2 +-
> arch/powerpc/kernel/time.c | 4 +---
> arch/powerpc/platforms/ps3/time.c | 4 +---
> arch/powerpc/sysdev/rtc_cmos_setup.c | 5 +----
> 4 files changed, 4 insertions(+), 11 deletions(-)
ps3 part looks OK, thanks.
Acked-by: Geoff Levand <geoff@infradead.org>
^ permalink raw reply
* [PATCH] powerpc: Remove last traces of POWER4_ONLY
From: Paul Bolle @ 2013-03-11 23:44 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras
Cc: linuxppc-dev, Anton Blanchard, linux-kernel
The Kconfig symbol POWER4_ONLY got removed in commit
694caf0255dcab506d1e174c96a65ab65d96e108 ("powerpc: Remove
CONFIG_POWER4_ONLY"). Remove its last traces.
Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
---
Untested.
arch/powerpc/platforms/Kconfig.cputype | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index cea2f09..18e3b76 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -124,9 +124,8 @@ config 6xx
select PPC_HAVE_PMU_SUPPORT
config POWER3
- bool
depends on PPC64 && PPC_BOOK3S
- default y if !POWER4_ONLY
+ def_bool y
config POWER4
depends on PPC64 && PPC_BOOK3S
@@ -145,8 +144,7 @@ config TUNE_CELL
but somewhat slower on other machines. This option only changes
the scheduling of instructions, not the selection of instructions
itself, so the resulting kernel will keep running on all other
- machines. When building a kernel that is supposed to run only
- on Cell, you should also select the POWER4_ONLY option.
+ machines.
# this is temp to handle compat with arch=ppc
config 8xx
--
1.7.11.7
^ permalink raw reply related
* [PATCH] powerpc: remove outdated default
From: Paul Bolle @ 2013-03-12 0:21 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras; +Cc: linuxppc-dev, linux-kernel
The Kconfig symbol PCI_PERMEDIA got removed in v2.6.24, through commit
e6b6e3ffb9ee8926f9f2f7dc9147df73e27d5828 ("[POWERPC] Remove APUS support
from arch/ppc"). Remove its last occurrence.
Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
---
Tested with "make ARCH=powerpc menuconfig" using ps3_defconfig, both
before and after this patch. ("!4xx && !CPM2 && !8xx" is true for ps3,
and it uses PPC_PCI_CHOICE.) Nothing seemed to change. Which makes
sense, as defaulting to an undefined symbol should be a nop.
arch/powerpc/Kconfig | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b89d7eb..3d566c3 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -744,7 +744,6 @@ config PCI
bool "PCI support" if PPC_PCI_CHOICE
default y if !40x && !CPM2 && !8xx && !PPC_83xx \
&& !PPC_85xx && !PPC_86xx && !GAMECUBE_COMMON
- default PCI_PERMEDIA if !4xx && !CPM2 && !8xx
default PCI_QSPAN if !4xx && !CPM2 && 8xx
select ARCH_SUPPORTS_MSI
select GENERIC_PCI_IOMAP
--
1.7.11.7
^ permalink raw reply related
* Re: [PATCH] arch/powerpc/kernel: using %12.12s instead of %12s for avoiding memory overflow.
From: Chen Gang @ 2013-03-12 0:39 UTC (permalink / raw)
To: benh, paulus; +Cc: linuxppc-dev
In-Reply-To: <5100B53C.3030109@asianux.com>
Hello Benjamin Herrenschmidt:
how about this patch ? is it correct ?
thanks.
:-)
gchen.
于 2013年01月24日 12:14, Chen Gang 写道:
>
> for tmp_part->header.name:
> it is "Terminating null required only for names < 12 chars".
> so need to limit the %.12s for it in printk
>
> additional info:
>
> %12s limit the width, not for the original string output length
> if name length is more than 12, it still can be fully displayed.
> if name length is less than 12, the ' ' will be filled before name.
>
> %.12s truly limit the original string output length (precision)
>
>
> Signed-off-by: Chen Gang <gang.chen@asianux.com>
> ---
> arch/powerpc/kernel/nvram_64.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
> index bec1e93..57bf6d2 100644
> --- a/arch/powerpc/kernel/nvram_64.c
> +++ b/arch/powerpc/kernel/nvram_64.c
> @@ -202,7 +202,7 @@ static void __init nvram_print_partitions(char * label)
> printk(KERN_WARNING "--------%s---------\n", label);
> printk(KERN_WARNING "indx\t\tsig\tchks\tlen\tname\n");
> list_for_each_entry(tmp_part, &nvram_partitions, partition) {
> - printk(KERN_WARNING "%4d \t%02x\t%02x\t%d\t%12s\n",
> + printk(KERN_WARNING "%4d \t%02x\t%02x\t%d\t%12.12s\n",
> tmp_part->index, tmp_part->header.signature,
> tmp_part->header.checksum, tmp_part->header.length,
> tmp_part->header.name);
>
--
Chen Gang
Asianux Corporation
^ permalink raw reply
* Re: [PATCH -V2 2/2] powerpc: Update kernel VSID range
From: Geoff Levand @ 2013-03-12 0:41 UTC (permalink / raw)
To: benh; +Cc: phileas-fogg, linuxppc-dev, paulus, Aneesh Kumar K.V
In-Reply-To: <1360942778-21795-2-git-send-email-aneesh.kumar@linux.vnet.ibm.com>
Hi,
On Fri, 2013-02-15 at 21:09 +0530, Aneesh Kumar K.V wrote:
> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
>
> This patch change the kernel VSID range so that we limit VSID_BITS to 37.
> This enables us to support 64TB with 65 bit VA (37+28). Without this patch
> we have boot hangs on platforms that only support 65 bit VA.
I didn't seen this fix go in for 3.8. Did I miss it, or is there some
reason we don't want it?
I need this to boot PS3.
-Geoff
^ permalink raw reply
* Re: [PATCH -V2 2/2] powerpc: Update kernel VSID range
From: Benjamin Herrenschmidt @ 2013-03-12 1:05 UTC (permalink / raw)
To: Geoff Levand; +Cc: phileas-fogg, linuxppc-dev, paulus, Aneesh Kumar K.V
In-Reply-To: <1363048897.3155.16.camel@smoke>
On Mon, 2013-03-11 at 17:41 -0700, Geoff Levand wrote:
> I didn't seen this fix go in for 3.8. Did I miss it, or is there some
> reason we don't want it?
>
> I need this to boot PS3.
Working on it. There's a couple of issues, among others testing on STAB
and a couple of comments from David, I'm hoping to have that sorted some
time today.
Ben.
^ permalink raw reply
* Re: [PATCH] edac/85xx: Add PCIe error interrupt edac support
From: Chunhe Lan @ 2013-03-12 2:32 UTC (permalink / raw)
To: Gala Kumar-B11780; +Cc: <linuxppc-dev@lists.ozlabs.org>
In-Reply-To: <CF1EE7AED478CD48A05574C8E2DA142D7485E6@039-SN1MPN1-004.039d.mgd.msft.net>
On 03/09/2013 03:22 AM, Gala Kumar-B11780 wrote:
> On Mar 8, 2013, at 2:32 AM, Chunhe Lan wrote:
>
>> Adding pcie error interrupt edac support for mpc85xx, p3041, p4080,
>> and p5020. The mpc85xx uses the legacy interrupt report mechanism -
>> the error interrupts are reported directly to mpic. While, the p3041/
>> p4080/p5020 attaches the most of error interrupts to interrupt zero.
>> And report error interrupts to mpic via interrupt 0.
>>
>> This patch can handle both of them.
>>
>> Signed-off-by: Chunhe Lan <Chunhe.Lan@freescale.com>
>> ---
>> drivers/edac/mpc85xx_edac.c | 169 ++++++++++++++++++++++++++++++++++++++++---
>> drivers/edac/mpc85xx_edac.h | 7 ++
>> 2 files changed, 165 insertions(+), 11 deletions(-)
> Does this also work on T4 / PCIe controller rev3.0?
No, it does not work on T4.
>> diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
>> index 42a840d..085b6b3 100644
>> --- a/drivers/edac/mpc85xx_edac.c
>> +++ b/drivers/edac/mpc85xx_edac.c
>> @@ -1,5 +1,6 @@
>> /*
>> * Freescale MPC85xx Memory Controller kenel module
>> + * Copyright (c) 2013 Freescale Semiconductor, Inc.
>> *
>> * Author: Dave Jiang <djiang@mvista.com>
>> *
>> @@ -196,6 +197,120 @@ static void mpc85xx_pci_check(struct edac_pci_ctl_info *pci)
>> edac_pci_handle_npe(pci, pci->ctl_name);
>> }
>>
>> +static void mpc85xx_pcie_check(struct edac_pci_ctl_info *pci)
>> +{
>> + struct mpc85xx_pci_pdata *pdata = pci->pvt_info;
>> + u32 err_detect;
>> +
>> + err_detect = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR);
>> +
>> + pr_err("PCIE error(s) detected\n");
>> + pr_err("PCIE ERR_DR register: 0x%08x\n", err_detect);
>> + pr_err("PCIE ERR_CAP_STAT register: 0x%08x\n",
>> + in_be32(pdata->pci_vbase + MPC85XX_PCI_GAS_TIMR));
>> + pr_err("PCIE ERR_CAP_R0 register: 0x%08x\n",
>> + in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R0));
>> + pr_err("PCIE ERR_CAP_R1 register: 0x%08x\n",
>> + in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R1));
>> + pr_err("PCIE ERR_CAP_R2 register: 0x%08x\n",
>> + in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R2));
>> + pr_err("PCIE ERR_CAP_R3 register: 0x%08x\n",
>> + in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R3));
>> +
>> + /* clear error bits */
>> + out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, err_detect);
>> +}
>> +
>> +/*
>> + * This function is for error interrupt ORed mechanism.
>> + * This mechanism attaches most functions' error interrupts to interrupt 0.
>> + * And report error interrupt to mpic via interrupt 0.
>> + * EIMR0 - Error Interrupt Mask Register 0.
>> + *
>> + * This function check whether the device support error interrupt ORed
>> + * mechanism via device tree. If supported, umask pcie error interrupt
>> + * bit in EIMR0.
>> + */
>> +static int mpc85xx_err_int_en(struct platform_device *op)
>> +{
>> + u32 *int_cell;
>> + struct device_node *np;
>> + void __iomem *mpic_base;
>> + u32 reg_tmp;
>> + u32 int_len;
>> + struct resource r;
>> + int res;
>> +
>> + if (!op->dev.of_node)
>> + return -EINVAL;
>> +
>> + /*
>> + * Unmask pcie error interrupt bit in EIMR0.
>> + * Extend interrupt specifier has 4 cells.
>> + * For the 3rd cell:
>> + * 0 -- normal interrupt;
>> + * 1 -- error interrupt.
>> + */
>> + int_cell = (u32 *)of_get_property(op->dev.of_node, "interrupts",
>> + &int_len);
>
>> + if ((int_len/sizeof(u32)) == 4) {
>> + /* soc has error interrupt integration handling mechanism */
>> + if (*(int_cell + 2) == 1) {
>> + np = of_find_node_by_type(NULL, "open-pic");
>> +
>> + if (of_address_to_resource(np, 0, &r)) {
>> + pr_err("%s: Failed to map mpic regs\n",
>> + __func__);
>> + of_node_put(np);
>> + res = -ENOMEM;
>> + goto err;
>> + }
>> +
>> + if (!request_mem_region(r.start, r.end - r.start + 1,
>> + "mpic")) {
>> + pr_err("%s: Error when requesting mem region\n",
>> + __func__);
>> + res = -EBUSY;
>> + goto err;
>> + }
>> +
>> + mpic_base = ioremap(r.start, r.end - r.start + 1);
>> + if (!mpic_base) {
>> + pr_err("%s: Unable to map mpic regs\n",
>> + __func__);
>> + res = -ENOMEM;
>> + goto err_ioremap;
>> + }
>> +
>> + reg_tmp = in_be32(mpic_base + MPC85XX_MPIC_EIMR0);
>> + out_be32(mpic_base + MPC85XX_MPIC_EIMR0, reg_tmp &
>> + ~(1 << (31 - *(int_cell + 3))));
>> + iounmap(mpic_base);
>> + release_mem_region(r.start, r.end - r.start + 1);
>> + of_node_put(np);
>> + }
>> + }
>> +
> Why is this all needed, we have handling of error interrupts in the kernel already?
Yes, you are right. This is not needed, and I will remove it.
Thanks,
-Chunhe
>
> - k
>
^ permalink raw reply
* powerpc/ptrace: Fix brk.len used uninitialised
From: Michael Neuling @ 2013-03-12 2:42 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, Philippe De Muyter
In-Reply-To: <20130308102422.GA25184@frolo.macqel>
With some CONFIGS it's possible that in ppc_set_hwdebug, brk.len is
uninitialised before being used. It has been reported that GCC 4.2 will
produce the following error in this case:
arch/powerpc/kernel/ptrace.c:1479: warning: 'brk.len' is used uninitialized in this function
arch/powerpc/kernel/ptrace.c:1381: note: 'brk.len' was declared here
This patch corrects this.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Reported-by: Philippe De Muyter <phdm@macqel.be>
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 245c1b6..f9b30c6 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1428,6 +1428,7 @@ static long ppc_set_hwdebug(struct task_struct *child,
brk.address = bp_info->addr & ~7UL;
brk.type = HW_BRK_TYPE_TRANSLATE;
+ brk.len = 8;
if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
brk.type |= HW_BRK_TYPE_READ;
if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
^ permalink raw reply related
* Re: [PATCH -V2 2/2] powerpc: Update kernel VSID range
From: Aneesh Kumar K.V @ 2013-03-12 2:58 UTC (permalink / raw)
To: benh, paulus, phileas-fogg, geoff; +Cc: linuxppc-dev
In-Reply-To: <1360942778-21795-2-git-send-email-aneesh.kumar@linux.vnet.ibm.com>
Ben, Paul,
Any update on this ?
-aneesh
"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> writes:
> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
>
> This patch change the kernel VSID range so that we limit VSID_BITS to 37.
> This enables us to support 64TB with 65 bit VA (37+28). Without this patch
> we have boot hangs on platforms that only support 65 bit VA.
>
> With this patch we now have proto vsid generated as below:
>
> We first generate a 37-bit "proto-VSID". Proto-VSIDs are generated
> from mmu context id and effective segment id of the address.
>
> For user processes max context id is limited to ((1ul << 19) - 6)
> for kernel space, we use the top 4 context ids to map address as below
> 0x7fffc - [ 0xc000000000000000 - 0xc0003fffffffffff ]
> 0x7fffd - [ 0xd000000000000000 - 0xd0003fffffffffff ]
> 0x7fffe - [ 0xe000000000000000 - 0xe0003fffffffffff ]
> 0x7ffff - [ 0xf000000000000000 - 0xf0003fffffffffff ]
>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/mmu-hash64.h | 115 +++++++++++++++++----------------
> arch/powerpc/kernel/exceptions-64s.S | 37 ++++++++---
> arch/powerpc/mm/hash_utils_64.c | 20 ++++--
> arch/powerpc/mm/mmu_context_hash64.c | 12 +---
> arch/powerpc/mm/slb_low.S | 44 +++++++++----
> arch/powerpc/mm/tlb_hash64.c | 2 +-
> 6 files changed, 136 insertions(+), 94 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
> index 5f8c2bd..35bb51e 100644
> --- a/arch/powerpc/include/asm/mmu-hash64.h
> +++ b/arch/powerpc/include/asm/mmu-hash64.h
> @@ -343,17 +343,16 @@ extern void slb_set_size(u16 size);
> /*
> * VSID allocation (256MB segment)
> *
> - * We first generate a 38-bit "proto-VSID". For kernel addresses this
> - * is equal to the ESID | 1 << 37, for user addresses it is:
> - * (context << USER_ESID_BITS) | (esid & ((1U << USER_ESID_BITS) - 1)
> + * We first generate a 37-bit "proto-VSID". Proto-VSIDs are generated
> + * from mmu context id and effective segment id of the address.
> *
> - * This splits the proto-VSID into the below range
> - * 0 - (2^(CONTEXT_BITS + USER_ESID_BITS) - 1) : User proto-VSID range
> - * 2^(CONTEXT_BITS + USER_ESID_BITS) - 2^(VSID_BITS) : Kernel proto-VSID range
> - *
> - * We also have CONTEXT_BITS + USER_ESID_BITS = VSID_BITS - 1
> - * That is, we assign half of the space to user processes and half
> - * to the kernel.
> + * For user processes max context id is limited to ((1ul << 19) - 6)
> + * for kernel space, we use the top 4 context ids to map address as below
> + * NOTE: each context only support 64TB now.
> + * 0x7fffc - [ 0xc000000000000000 - 0xc0003fffffffffff ]
> + * 0x7fffd - [ 0xd000000000000000 - 0xd0003fffffffffff ]
> + * 0x7fffe - [ 0xe000000000000000 - 0xe0003fffffffffff ]
> + * 0x7ffff - [ 0xf000000000000000 - 0xf0003fffffffffff ]
> *
> * The proto-VSIDs are then scrambled into real VSIDs with the
> * multiplicative hash:
> @@ -363,22 +362,19 @@ extern void slb_set_size(u16 size);
> * VSID_MULTIPLIER is prime, so in particular it is
> * co-prime to VSID_MODULUS, making this a 1:1 scrambling function.
> * Because the modulus is 2^n-1 we can compute it efficiently without
> - * a divide or extra multiply (see below).
> - *
> - * This scheme has several advantages over older methods:
> + * a divide or extra multiply (see below). The scramble function gives
> + * robust scattering in the hash * table (at least based on some initial
> + * results).
> *
> - * - We have VSIDs allocated for every kernel address
> - * (i.e. everything above 0xC000000000000000), except the very top
> - * segment, which simplifies several things.
> + * We also consider VSID 0 special. We use VSID 0 for slb entries mapping
> + * bad address. This enables us to consolidate bad address handling in
> + * hash_page.
> *
> - * - We allow for USER_ESID_BITS significant bits of ESID and
> - * CONTEXT_BITS bits of context for user addresses.
> - * i.e. 64T (46 bits) of address space for up to half a million contexts.
> - *
> - * - The scramble function gives robust scattering in the hash
> - * table (at least based on some initial results). The previous
> - * method was more susceptible to pathological cases giving excessive
> - * hash collisions.
> + * We also need to avoid the last segment of the last context, because that
> + * would give a protovsid of 0x1fffffffff. That will result in a VSID 0
> + * because of the modulo operation in vsid scramble. But the vmemmap
> + * (which is what uses region 0xf) will never be close to 64TB in size
> + * (it's 56 bytes per page of system memory).
> */
>
> #define CONTEXT_BITS 19
> @@ -386,15 +382,25 @@ extern void slb_set_size(u16 size);
> #define USER_ESID_BITS_1T 6
>
> /*
> + * 256MB segment
> + * The proto-VSID space has 2^(CONTEX_BITS + USER_ESID_BITS) - 1 segments
> + * available for user + kernel mapping. The top 4 contexts are used for
> + * kernel mapping. Each segment contains 2^28 bytes. Each
> + * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts
> + * (19 == 37 + 28 - 46).
> + */
> +#define MAX_CONTEXT ((ASM_CONST(1) << CONTEXT_BITS) - 1)
> +
> +/*
> * This should be computed such that protovosid * vsid_mulitplier
> * doesn't overflow 64 bits. It should also be co-prime to vsid_modulus
> */
> #define VSID_MULTIPLIER_256M ASM_CONST(12538073) /* 24-bit prime */
> -#define VSID_BITS_256M (CONTEXT_BITS + USER_ESID_BITS + 1)
> +#define VSID_BITS_256M (CONTEXT_BITS + USER_ESID_BITS)
> #define VSID_MODULUS_256M ((1UL<<VSID_BITS_256M)-1)
>
> #define VSID_MULTIPLIER_1T ASM_CONST(12538073) /* 24-bit prime */
> -#define VSID_BITS_1T (CONTEXT_BITS + USER_ESID_BITS_1T + 1)
> +#define VSID_BITS_1T (CONTEXT_BITS + USER_ESID_BITS_1T)
> #define VSID_MODULUS_1T ((1UL<<VSID_BITS_1T)-1)
>
>
> @@ -422,7 +428,8 @@ extern void slb_set_size(u16 size);
> srdi rx,rt,VSID_BITS_##size; \
> clrldi rt,rt,(64-VSID_BITS_##size); \
> add rt,rt,rx; /* add high and low bits */ \
> - /* Now, r3 == VSID (mod 2^36-1), and lies between 0 and \
> + /* NOTE: explanation based on VSID_BITS_##size = 36 \
> + * Now, r3 == VSID (mod 2^36-1), and lies between 0 and \
> * 2^36-1+2^28-1. That in particular means that if r3 >= \
> * 2^36-1, then r3+1 has the 2^36 bit set. So, if r3+1 has \
> * the bit clear, r3 already has the answer we want, if it \
> @@ -514,34 +521,6 @@ typedef struct {
> })
> #endif /* 1 */
>
> -/*
> - * This is only valid for addresses >= PAGE_OFFSET
> - * The proto-VSID space is divided into two class
> - * User: 0 to 2^(CONTEXT_BITS + USER_ESID_BITS) -1
> - * kernel: 2^(CONTEXT_BITS + USER_ESID_BITS) to 2^(VSID_BITS) - 1
> - *
> - * With KERNEL_START at 0xc000000000000000, the proto vsid for
> - * the kernel ends up with 0xc00000000 (36 bits). With 64TB
> - * support we need to have kernel proto-VSID in the
> - * [2^37 to 2^38 - 1] range due to the increased USER_ESID_BITS.
> - */
> -static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
> -{
> - unsigned long proto_vsid;
> - /*
> - * We need to make sure proto_vsid for the kernel is
> - * >= 2^(CONTEXT_BITS + USER_ESID_BITS[_1T])
> - */
> - if (ssize == MMU_SEGSIZE_256M) {
> - proto_vsid = ea >> SID_SHIFT;
> - proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS));
> - return vsid_scramble(proto_vsid, 256M);
> - }
> - proto_vsid = ea >> SID_SHIFT_1T;
> - proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS_1T));
> - return vsid_scramble(proto_vsid, 1T);
> -}
> -
> /* Returns the segment size indicator for a user address */
> static inline int user_segment_size(unsigned long addr)
> {
> @@ -551,10 +530,15 @@ static inline int user_segment_size(unsigned long addr)
> return MMU_SEGSIZE_256M;
> }
>
> -/* This is only valid for user addresses (which are below 2^44) */
> static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
> int ssize)
> {
> + /*
> + * Bad address. We return VSID 0 for that
> + */
> + if ((ea & ~REGION_MASK) >= PGTABLE_RANGE)
> + return 0;
> +
> if (ssize == MMU_SEGSIZE_256M)
> return vsid_scramble((context << USER_ESID_BITS)
> | (ea >> SID_SHIFT), 256M);
> @@ -562,6 +546,25 @@ static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
> | (ea >> SID_SHIFT_1T), 1T);
> }
>
> +/*
> + * This is only valid for addresses >= PAGE_OFFSET
> + *
> + * For kernel space, we use the top 4 context ids to map address as below
> + * 0x7fffc - [ 0xc000000000000000 - 0xc0003fffffffffff ]
> + * 0x7fffd - [ 0xd000000000000000 - 0xd0003fffffffffff ]
> + * 0x7fffe - [ 0xe000000000000000 - 0xe0003fffffffffff ]
> + * 0x7ffff - [ 0xf000000000000000 - 0xf0003fffffffffff ]
> + */
> +static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
> +{
> + unsigned long context;
> +
> + /*
> + * kernel take the top 4 context from the available range
> + */
> + context = (MAX_CONTEXT - 3) + ((ea >> 60) - 0xc);
> + return get_vsid(context, ea, ssize);
> +}
> #endif /* __ASSEMBLY__ */
>
> #endif /* _ASM_POWERPC_MMU_HASH64_H_ */
> diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
> index 4665e82..0e9c48c 100644
> --- a/arch/powerpc/kernel/exceptions-64s.S
> +++ b/arch/powerpc/kernel/exceptions-64s.S
> @@ -1268,20 +1268,39 @@ do_ste_alloc:
> _GLOBAL(do_stab_bolted)
> stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
> std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */
> + mfspr r11,SPRN_DAR /* ea */
>
> + /*
> + * check for bad kernel/user address
> + * (ea & ~REGION_MASK) >= PGTABLE_RANGE
> + */
> + clrldi r9,r11,4
> + li r10,-1
> + clrldi r10,r10,(64 - 46)
> + cmpld cr7,r9,r10
> + li r9,0 /* VSID = 0 for bad address */
> + bgt cr7,0f
> +
> + /*
> + * Calculate VSID:
> + * This is the kernel vsid, we take the top for context from
> + * the range. context = (MAX_CONTEXT - 3) + ((ea >> 60) - 0xc)
> + * Here we know that (ea >> 60) == 0xc
> + */
> + lis r9,8
> + subi r9,r9,(3 + 1) /* context */
> +
> + srdi r10,r11,SID_SHIFT
> + rldimi r10,r9,USER_ESID_BITS,0 /* proto vsid */
> + ASM_VSID_SCRAMBLE(r10, r9, 256M)
> + rldic r9,r10,12,16 /* r9 = vsid << 12 */
> +
> +0:
> /* Hash to the primary group */
> ld r10,PACASTABVIRT(r13)
> - mfspr r11,SPRN_DAR
> - srdi r11,r11,28
> + srdi r11,r11,SID_SHIFT
> rldimi r10,r11,7,52 /* r10 = first ste of the group */
>
> - /* Calculate VSID */
> - /* This is a kernel address, so protovsid = ESID | 1 << 37 */
> - li r9,0x1
> - rldimi r11,r9,(CONTEXT_BITS + USER_ESID_BITS),0
> - ASM_VSID_SCRAMBLE(r11, r9, 256M)
> - rldic r9,r11,12,16 /* r9 = vsid << 12 */
> -
> /* Search the primary group for a free entry */
> 1: ld r11,0(r10) /* Test valid bit of the current ste */
> andi. r11,r11,0x80
> diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
> index 3a292be..bfeab83 100644
> --- a/arch/powerpc/mm/hash_utils_64.c
> +++ b/arch/powerpc/mm/hash_utils_64.c
> @@ -194,6 +194,11 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
> unsigned long vpn = hpt_vpn(vaddr, vsid, ssize);
> unsigned long tprot = prot;
>
> + /*
> + * If we hit a bad address return error.
> + */
> + if (!vsid)
> + return -1;
> /* Make kernel text executable */
> if (overlaps_kernel_text(vaddr, vaddr + step))
> tprot &= ~HPTE_R_N;
> @@ -921,11 +926,6 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
> DBG_LOW("hash_page(ea=%016lx, access=%lx, trap=%lx\n",
> ea, access, trap);
>
> - if ((ea & ~REGION_MASK) >= PGTABLE_RANGE) {
> - DBG_LOW(" out of pgtable range !\n");
> - return 1;
> - }
> -
> /* Get region & vsid */
> switch (REGION_ID(ea)) {
> case USER_REGION_ID:
> @@ -956,6 +956,11 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
> }
> DBG_LOW(" mm=%p, mm->pgdir=%p, vsid=%016lx\n", mm, mm->pgd, vsid);
>
> + /* Bad address. */
> + if (!vsid) {
> + DBG_LOW("Bad address!\n");
> + return 1;
> + }
> /* Get pgdir */
> pgdir = mm->pgd;
> if (pgdir == NULL)
> @@ -1125,6 +1130,8 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
> /* Get VSID */
> ssize = user_segment_size(ea);
> vsid = get_vsid(mm->context.id, ea, ssize);
> + if (!vsid)
> + return;
>
> /* Hash doesn't like irqs */
> local_irq_save(flags);
> @@ -1217,6 +1224,9 @@ static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi)
> hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize);
> hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
>
> + /* Don't create HPTE entries for bad address */
> + if (!vsid)
> + return;
> ret = ppc_md.hpte_insert(hpteg, vpn, __pa(vaddr),
> mode, HPTE_V_BOLTED,
> mmu_linear_psize, mmu_kernel_ssize);
> diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c
> index 40bc5b0..59cd773 100644
> --- a/arch/powerpc/mm/mmu_context_hash64.c
> +++ b/arch/powerpc/mm/mmu_context_hash64.c
> @@ -29,15 +29,6 @@
> static DEFINE_SPINLOCK(mmu_context_lock);
> static DEFINE_IDA(mmu_context_ida);
>
> -/*
> - * 256MB segment
> - * The proto-VSID space has 2^(CONTEX_BITS + USER_ESID_BITS) - 1 segments
> - * available for user mappings. Each segment contains 2^28 bytes. Each
> - * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts
> - * (19 == 37 + 28 - 46).
> - */
> -#define MAX_CONTEXT ((1UL << CONTEXT_BITS) - 1)
> -
> int __init_new_context(void)
> {
> int index;
> @@ -56,7 +47,8 @@ again:
> else if (err)
> return err;
>
> - if (index > MAX_CONTEXT) {
> + if (index > (MAX_CONTEXT - 4)) {
> + /* Top 4 context id values are used for kernel */
> spin_lock(&mmu_context_lock);
> ida_remove(&mmu_context_ida, index);
> spin_unlock(&mmu_context_lock);
> diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
> index 1a16ca2..c066d00 100644
> --- a/arch/powerpc/mm/slb_low.S
> +++ b/arch/powerpc/mm/slb_low.S
> @@ -31,13 +31,20 @@
> * No other registers are examined or changed.
> */
> _GLOBAL(slb_allocate_realmode)
> - /* r3 = faulting address */
> + /*
> + * check for bad kernel/user address
> + * (ea & ~REGION_MASK) >= PGTABLE_RANGE
> + */
> + clrldi r9,r3,4
> + li r10,-1
> + clrldi r10,r10,(64 - 46)
> + cmpld cr7,r9,r10
> + bgt cr7,8f
>
> srdi r9,r3,60 /* get region */
> - srdi r10,r3,28 /* get esid */
> cmpldi cr7,r9,0xc /* cmp PAGE_OFFSET for later use */
>
> - /* r3 = address, r10 = esid, cr7 = <> PAGE_OFFSET */
> + /* r3 = address, cr7 = <> PAGE_OFFSET */
> blt cr7,0f /* user or kernel? */
>
> /* kernel address: proto-VSID = ESID */
> @@ -56,18 +63,26 @@ _GLOBAL(slb_allocate_realmode)
> */
> _GLOBAL(slb_miss_kernel_load_linear)
> li r11,0
> - li r9,0x1
> + /*
> + * context = (MAX_CONTEXT - 3) + ((ea >> 60) - 0xc)
> + */
> + srdi r9,r3,60
> + subi r9,r9,(0xc + 3 + 1)
> + lis r10, 8
> + add r9,r9,r10
> + srdi r10,r3,SID_SHIFT /* get esid */
> /*
> * for 1T we shift 12 bits more. slb_finish_load_1T will do
> * the necessary adjustment
> */
> - rldimi r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0
> + rldimi r10,r9,USER_ESID_BITS,0
> BEGIN_FTR_SECTION
> b slb_finish_load
> END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
> b slb_finish_load_1T
>
> 1:
> + srdi r10,r3,SID_SHIFT /* get esid */
> #ifdef CONFIG_SPARSEMEM_VMEMMAP
> /* Check virtual memmap region. To be patches at kernel boot */
> cmpldi cr0,r9,0xf
> @@ -91,23 +106,26 @@ _GLOBAL(slb_miss_kernel_load_vmemmap)
> _GLOBAL(slb_miss_kernel_load_io)
> li r11,0
> 6:
> - li r9,0x1
> + /*
> + * context = (MAX_CONTEXT - 3) + ((ea >> 60) - 0xc)
> + */
> + srdi r9,r3,60
> + subi r9,r9,(0xc + 3 + 1)
> + lis r10,8
> + add r9,r9,r10
> + srdi r10,r3,SID_SHIFT
> /*
> * for 1T we shift 12 bits more. slb_finish_load_1T will do
> * the necessary adjustment
> */
> - rldimi r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0
> + rldimi r10,r9,USER_ESID_BITS,0
> BEGIN_FTR_SECTION
> b slb_finish_load
> END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
> b slb_finish_load_1T
>
> -0: /* user address: proto-VSID = context << 15 | ESID. First check
> - * if the address is within the boundaries of the user region
> - */
> - srdi. r9,r10,USER_ESID_BITS
> - bne- 8f /* invalid ea bits set */
> -
> +0:
> + srdi r10,r3,SID_SHIFT /* get esid */
>
> /* when using slices, we extract the psize off the slice bitmaps
> * and then we need to get the sllp encoding off the mmu_psize_defs
> diff --git a/arch/powerpc/mm/tlb_hash64.c b/arch/powerpc/mm/tlb_hash64.c
> index 0d82ef5..023ec8a 100644
> --- a/arch/powerpc/mm/tlb_hash64.c
> +++ b/arch/powerpc/mm/tlb_hash64.c
> @@ -82,11 +82,11 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
> if (!is_kernel_addr(addr)) {
> ssize = user_segment_size(addr);
> vsid = get_vsid(mm->context.id, addr, ssize);
> - WARN_ON(vsid == 0);
> } else {
> vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
> ssize = mmu_kernel_ssize;
> }
> + WARN_ON(vsid == 0);
> vpn = hpt_vpn(addr, vsid, ssize);
> rpte = __real_pte(__pte(pte), ptep);
>
> --
> 1.7.10
^ permalink raw reply
* Re: [PATCH -V2 2/2] powerpc: Update kernel VSID range
From: Benjamin Herrenschmidt @ 2013-03-12 3:02 UTC (permalink / raw)
To: Aneesh Kumar K.V; +Cc: phileas-fogg, geoff, paulus, linuxppc-dev
In-Reply-To: <87d2v5mihn.fsf@linux.vnet.ibm.com>
On Tue, 2013-03-12 at 08:28 +0530, Aneesh Kumar K.V wrote:
> Ben, Paul,
>
> Any update on this ?
Paul and David are reviewing it and I was trying to test on POWER3 (STAB
vs. SLB) but ended up bisecting instead why POWER3 stopped working in
3.4 ... :-)
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH -V2 2/2] powerpc: Update kernel VSID range
From: David Gibson @ 2013-03-12 4:25 UTC (permalink / raw)
To: Aneesh Kumar K.V; +Cc: phileas-fogg, paulus, linuxppc-dev, geoff
In-Reply-To: <1360942778-21795-2-git-send-email-aneesh.kumar@linux.vnet.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 19212 bytes --]
On Fri, Feb 15, 2013 at 09:09:38PM +0530, Aneesh Kumar K.V wrote:
> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
>
> This patch change the kernel VSID range so that we limit VSID_BITS to 37.
> This enables us to support 64TB with 65 bit VA (37+28). Without this patch
> we have boot hangs on platforms that only support 65 bit VA.
>
> With this patch we now have proto vsid generated as below:
>
> We first generate a 37-bit "proto-VSID". Proto-VSIDs are generated
> from mmu context id and effective segment id of the address.
>
> For user processes max context id is limited to ((1ul << 19) - 6)
> for kernel space, we use the top 4 context ids to map address as below
> 0x7fffc - [ 0xc000000000000000 - 0xc0003fffffffffff ]
> 0x7fffd - [ 0xd000000000000000 - 0xd0003fffffffffff ]
> 0x7fffe - [ 0xe000000000000000 - 0xe0003fffffffffff ]
> 0x7ffff - [ 0xf000000000000000 - 0xf0003fffffffffff ]
>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/mmu-hash64.h | 115 +++++++++++++++++----------------
> arch/powerpc/kernel/exceptions-64s.S | 37 ++++++++---
> arch/powerpc/mm/hash_utils_64.c | 20 ++++--
> arch/powerpc/mm/mmu_context_hash64.c | 12 +---
> arch/powerpc/mm/slb_low.S | 44 +++++++++----
> arch/powerpc/mm/tlb_hash64.c | 2 +-
> 6 files changed, 136 insertions(+), 94 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
> index 5f8c2bd..35bb51e 100644
> --- a/arch/powerpc/include/asm/mmu-hash64.h
> +++ b/arch/powerpc/include/asm/mmu-hash64.h
> @@ -343,17 +343,16 @@ extern void slb_set_size(u16 size);
> /*
> * VSID allocation (256MB segment)
> *
> - * We first generate a 38-bit "proto-VSID". For kernel addresses this
> - * is equal to the ESID | 1 << 37, for user addresses it is:
> - * (context << USER_ESID_BITS) | (esid & ((1U << USER_ESID_BITS) - 1)
> + * We first generate a 37-bit "proto-VSID". Proto-VSIDs are generated
> + * from mmu context id and effective segment id of the address.
> *
> - * This splits the proto-VSID into the below range
> - * 0 - (2^(CONTEXT_BITS + USER_ESID_BITS) - 1) : User proto-VSID range
> - * 2^(CONTEXT_BITS + USER_ESID_BITS) - 2^(VSID_BITS) : Kernel proto-VSID range
> - *
> - * We also have CONTEXT_BITS + USER_ESID_BITS = VSID_BITS - 1
> - * That is, we assign half of the space to user processes and half
> - * to the kernel.
> + * For user processes max context id is limited to ((1ul << 19) - 6)
> + * for kernel space, we use the top 4 context ids to map address as below
> + * NOTE: each context only support 64TB now.
> + * 0x7fffc - [ 0xc000000000000000 - 0xc0003fffffffffff ]
> + * 0x7fffd - [ 0xd000000000000000 - 0xd0003fffffffffff ]
> + * 0x7fffe - [ 0xe000000000000000 - 0xe0003fffffffffff ]
> + * 0x7ffff - [ 0xf000000000000000 - 0xf0003fffffffffff ]
> *
> * The proto-VSIDs are then scrambled into real VSIDs with the
> * multiplicative hash:
> @@ -363,22 +362,19 @@ extern void slb_set_size(u16 size);
> * VSID_MULTIPLIER is prime, so in particular it is
> * co-prime to VSID_MODULUS, making this a 1:1 scrambling function.
> * Because the modulus is 2^n-1 we can compute it efficiently without
> - * a divide or extra multiply (see below).
> - *
> - * This scheme has several advantages over older methods:
> + * a divide or extra multiply (see below). The scramble function gives
> + * robust scattering in the hash * table (at least based on some initial
> + * results).
> *
> - * - We have VSIDs allocated for every kernel address
> - * (i.e. everything above 0xC000000000000000), except the very top
> - * segment, which simplifies several things.
> + * We also consider VSID 0 special. We use VSID 0 for slb entries mapping
> + * bad address. This enables us to consolidate bad address handling in
> + * hash_page.
> *
> - * - We allow for USER_ESID_BITS significant bits of ESID and
> - * CONTEXT_BITS bits of context for user addresses.
> - * i.e. 64T (46 bits) of address space for up to half a million contexts.
> - *
> - * - The scramble function gives robust scattering in the hash
> - * table (at least based on some initial results). The previous
> - * method was more susceptible to pathological cases giving excessive
> - * hash collisions.
> + * We also need to avoid the last segment of the last context, because that
> + * would give a protovsid of 0x1fffffffff. That will result in a VSID 0
> + * because of the modulo operation in vsid scramble. But the vmemmap
> + * (which is what uses region 0xf) will never be close to 64TB in size
> + * (it's 56 bytes per page of system memory).
> */
>
> #define CONTEXT_BITS 19
> @@ -386,15 +382,25 @@ extern void slb_set_size(u16 size);
> #define USER_ESID_BITS_1T 6
USER_ESID_BITS should probably be renamed just ESID_BITS, since it's
now relevant to kernel addresses too.
> /*
> + * 256MB segment
> + * The proto-VSID space has 2^(CONTEX_BITS + USER_ESID_BITS) - 1 segments
> + * available for user + kernel mapping. The top 4 contexts are used for
> + * kernel mapping. Each segment contains 2^28 bytes. Each
> + * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts
> + * (19 == 37 + 28 - 46).
> + */
> +#define MAX_CONTEXT ((ASM_CONST(1) << CONTEXT_BITS) - 1)
Hrm. I think it would be clearer to have MAX_CONTEXT (still) be the
maximum usable *user* context (i.e. 0x80000 - 5) and put the kernel
ones above that still.
> +
> +/*
> * This should be computed such that protovosid * vsid_mulitplier
> * doesn't overflow 64 bits. It should also be co-prime to vsid_modulus
> */
> #define VSID_MULTIPLIER_256M ASM_CONST(12538073) /* 24-bit prime */
> -#define VSID_BITS_256M (CONTEXT_BITS + USER_ESID_BITS + 1)
> +#define VSID_BITS_256M (CONTEXT_BITS + USER_ESID_BITS)
> #define VSID_MODULUS_256M ((1UL<<VSID_BITS_256M)-1)
>
> #define VSID_MULTIPLIER_1T ASM_CONST(12538073) /* 24-bit prime */
> -#define VSID_BITS_1T (CONTEXT_BITS + USER_ESID_BITS_1T + 1)
> +#define VSID_BITS_1T (CONTEXT_BITS + USER_ESID_BITS_1T)
> #define VSID_MODULUS_1T ((1UL<<VSID_BITS_1T)-1)
>
>
> @@ -422,7 +428,8 @@ extern void slb_set_size(u16 size);
> srdi rx,rt,VSID_BITS_##size; \
> clrldi rt,rt,(64-VSID_BITS_##size); \
> add rt,rt,rx; /* add high and low bits */ \
> - /* Now, r3 == VSID (mod 2^36-1), and lies between 0 and \
> + /* NOTE: explanation based on VSID_BITS_##size = 36 \
> + * Now, r3 == VSID (mod 2^36-1), and lies between 0 and \
> * 2^36-1+2^28-1. That in particular means that if r3 >= \
> * 2^36-1, then r3+1 has the 2^36 bit set. So, if r3+1 has \
> * the bit clear, r3 already has the answer we want, if it \
> @@ -514,34 +521,6 @@ typedef struct {
> })
> #endif /* 1 */
>
> -/*
> - * This is only valid for addresses >= PAGE_OFFSET
> - * The proto-VSID space is divided into two class
> - * User: 0 to 2^(CONTEXT_BITS + USER_ESID_BITS) -1
> - * kernel: 2^(CONTEXT_BITS + USER_ESID_BITS) to 2^(VSID_BITS) - 1
> - *
> - * With KERNEL_START at 0xc000000000000000, the proto vsid for
> - * the kernel ends up with 0xc00000000 (36 bits). With 64TB
> - * support we need to have kernel proto-VSID in the
> - * [2^37 to 2^38 - 1] range due to the increased USER_ESID_BITS.
> - */
> -static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
> -{
> - unsigned long proto_vsid;
> - /*
> - * We need to make sure proto_vsid for the kernel is
> - * >= 2^(CONTEXT_BITS + USER_ESID_BITS[_1T])
> - */
> - if (ssize == MMU_SEGSIZE_256M) {
> - proto_vsid = ea >> SID_SHIFT;
> - proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS));
> - return vsid_scramble(proto_vsid, 256M);
> - }
> - proto_vsid = ea >> SID_SHIFT_1T;
> - proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS_1T));
> - return vsid_scramble(proto_vsid, 1T);
> -}
> -
> /* Returns the segment size indicator for a user address */
> static inline int user_segment_size(unsigned long addr)
> {
> @@ -551,10 +530,15 @@ static inline int user_segment_size(unsigned long addr)
> return MMU_SEGSIZE_256M;
> }
>
> -/* This is only valid for user addresses (which are below 2^44) */
> static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
> int ssize)
> {
> + /*
> + * Bad address. We return VSID 0 for that
> + */
> + if ((ea & ~REGION_MASK) >= PGTABLE_RANGE)
> + return 0;
> +
> if (ssize == MMU_SEGSIZE_256M)
> return vsid_scramble((context << USER_ESID_BITS)
> | (ea >> SID_SHIFT), 256M);
> @@ -562,6 +546,25 @@ static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
> | (ea >> SID_SHIFT_1T), 1T);
> }
>
> +/*
> + * This is only valid for addresses >= PAGE_OFFSET
> + *
> + * For kernel space, we use the top 4 context ids to map address as below
> + * 0x7fffc - [ 0xc000000000000000 - 0xc0003fffffffffff ]
> + * 0x7fffd - [ 0xd000000000000000 - 0xd0003fffffffffff ]
> + * 0x7fffe - [ 0xe000000000000000 - 0xe0003fffffffffff ]
> + * 0x7ffff - [ 0xf000000000000000 - 0xf0003fffffffffff ]
> + */
> +static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
> +{
> + unsigned long context;
> +
> + /*
> + * kernel take the top 4 context from the available range
> + */
> + context = (MAX_CONTEXT - 3) + ((ea >> 60) - 0xc);
> + return get_vsid(context, ea, ssize);
> +}
> #endif /* __ASSEMBLY__ */
>
> #endif /* _ASM_POWERPC_MMU_HASH64_H_ */
> diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
> index 4665e82..0e9c48c 100644
> --- a/arch/powerpc/kernel/exceptions-64s.S
> +++ b/arch/powerpc/kernel/exceptions-64s.S
> @@ -1268,20 +1268,39 @@ do_ste_alloc:
> _GLOBAL(do_stab_bolted)
The stab path certainly hasn't been tested, since we've been broken on
stab machines for a long time.
> stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
> std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */
> + mfspr r11,SPRN_DAR /* ea */
>
> + /*
> + * check for bad kernel/user address
> + * (ea & ~REGION_MASK) >= PGTABLE_RANGE
> + */
> + clrldi r9,r11,4
> + li r10,-1
> + clrldi r10,r10,(64 - 46)
> + cmpld cr7,r9,r10
You can replace the above 4 instructions with just:
rldicr. r9,r11,4,(64-46-4)
> + li r9,0 /* VSID = 0 for bad address */
> + bgt cr7,0f
> +
> + /*
> + * Calculate VSID:
> + * This is the kernel vsid, we take the top for context from
> + * the range. context = (MAX_CONTEXT - 3) + ((ea >> 60) - 0xc)
> + * Here we know that (ea >> 60) == 0xc
> + */
> + lis r9,8
> + subi r9,r9,(3 + 1) /* context */
> +
> + srdi r10,r11,SID_SHIFT
> + rldimi r10,r9,USER_ESID_BITS,0 /* proto vsid */
> + ASM_VSID_SCRAMBLE(r10, r9, 256M)
> + rldic r9,r10,12,16 /* r9 = vsid << 12 */
> +
> +0:
> /* Hash to the primary group */
> ld r10,PACASTABVIRT(r13)
> - mfspr r11,SPRN_DAR
> - srdi r11,r11,28
> + srdi r11,r11,SID_SHIFT
> rldimi r10,r11,7,52 /* r10 = first ste of the group */
>
> - /* Calculate VSID */
> - /* This is a kernel address, so protovsid = ESID | 1 << 37 */
> - li r9,0x1
> - rldimi r11,r9,(CONTEXT_BITS + USER_ESID_BITS),0
> - ASM_VSID_SCRAMBLE(r11, r9, 256M)
> - rldic r9,r11,12,16 /* r9 = vsid << 12 */
> -
> /* Search the primary group for a free entry */
> 1: ld r11,0(r10) /* Test valid bit of the current ste */
> andi. r11,r11,0x80
> diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
> index 3a292be..bfeab83 100644
> --- a/arch/powerpc/mm/hash_utils_64.c
> +++ b/arch/powerpc/mm/hash_utils_64.c
> @@ -194,6 +194,11 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
> unsigned long vpn = hpt_vpn(vaddr, vsid, ssize);
> unsigned long tprot = prot;
>
> + /*
> + * If we hit a bad address return error.
> + */
> + if (!vsid)
> + return -1;
> /* Make kernel text executable */
> if (overlaps_kernel_text(vaddr, vaddr + step))
> tprot &= ~HPTE_R_N;
> @@ -921,11 +926,6 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
> DBG_LOW("hash_page(ea=%016lx, access=%lx, trap=%lx\n",
> ea, access, trap);
>
> - if ((ea & ~REGION_MASK) >= PGTABLE_RANGE) {
> - DBG_LOW(" out of pgtable range !\n");
> - return 1;
> - }
> -
Hrm. This test is conceptually different, even if the logic is the
same as the vsid availablility test you may have performed earlier.
Perhaps add BUILD_BUG_ON()s to ensure that they really are the same.
> /* Get region & vsid */
> switch (REGION_ID(ea)) {
> case USER_REGION_ID:
> @@ -956,6 +956,11 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
> }
> DBG_LOW(" mm=%p, mm->pgdir=%p, vsid=%016lx\n", mm, mm->pgd, vsid);
>
> + /* Bad address. */
> + if (!vsid) {
> + DBG_LOW("Bad address!\n");
> + return 1;
> + }
> /* Get pgdir */
> pgdir = mm->pgd;
> if (pgdir == NULL)
> @@ -1125,6 +1130,8 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
> /* Get VSID */
> ssize = user_segment_size(ea);
> vsid = get_vsid(mm->context.id, ea, ssize);
> + if (!vsid)
> + return;
>
> /* Hash doesn't like irqs */
> local_irq_save(flags);
> @@ -1217,6 +1224,9 @@ static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi)
> hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize);
> hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
>
> + /* Don't create HPTE entries for bad address */
> + if (!vsid)
> + return;
> ret = ppc_md.hpte_insert(hpteg, vpn, __pa(vaddr),
> mode, HPTE_V_BOLTED,
> mmu_linear_psize, mmu_kernel_ssize);
> diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c
> index 40bc5b0..59cd773 100644
> --- a/arch/powerpc/mm/mmu_context_hash64.c
> +++ b/arch/powerpc/mm/mmu_context_hash64.c
> @@ -29,15 +29,6 @@
> static DEFINE_SPINLOCK(mmu_context_lock);
> static DEFINE_IDA(mmu_context_ida);
>
> -/*
> - * 256MB segment
> - * The proto-VSID space has 2^(CONTEX_BITS + USER_ESID_BITS) - 1 segments
> - * available for user mappings. Each segment contains 2^28 bytes. Each
> - * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts
> - * (19 == 37 + 28 - 46).
> - */
> -#define MAX_CONTEXT ((1UL << CONTEXT_BITS) - 1)
> -
> int __init_new_context(void)
> {
> int index;
> @@ -56,7 +47,8 @@ again:
> else if (err)
> return err;
>
> - if (index > MAX_CONTEXT) {
> + if (index > (MAX_CONTEXT - 4)) {
> + /* Top 4 context id values are used for kernel */
This change would not be necessary if you changed MAX_CONTEXT as
suggested above.
> spin_lock(&mmu_context_lock);
> ida_remove(&mmu_context_ida, index);
> spin_unlock(&mmu_context_lock);
> diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
> index 1a16ca2..c066d00 100644
> --- a/arch/powerpc/mm/slb_low.S
> +++ b/arch/powerpc/mm/slb_low.S
> @@ -31,13 +31,20 @@
> * No other registers are examined or changed.
> */
> _GLOBAL(slb_allocate_realmode)
> - /* r3 = faulting address */
> + /*
> + * check for bad kernel/user address
> + * (ea & ~REGION_MASK) >= PGTABLE_RANGE
> + */
> + clrldi r9,r3,4
> + li r10,-1
> + clrldi r10,r10,(64 - 46)
> + cmpld cr7,r9,r10
> + bgt cr7,8f
As in the stab path, you can accomplish this with a single rldicr.
>
> srdi r9,r3,60 /* get region */
> - srdi r10,r3,28 /* get esid */
> cmpldi cr7,r9,0xc /* cmp PAGE_OFFSET for later use */
>
> - /* r3 = address, r10 = esid, cr7 = <> PAGE_OFFSET */
> + /* r3 = address, cr7 = <> PAGE_OFFSET */
> blt cr7,0f /* user or kernel? */
>
> /* kernel address: proto-VSID = ESID */
> @@ -56,18 +63,26 @@ _GLOBAL(slb_allocate_realmode)
> */
> _GLOBAL(slb_miss_kernel_load_linear)
> li r11,0
> - li r9,0x1
> + /*
> + * context = (MAX_CONTEXT - 3) + ((ea >> 60) - 0xc)
> + */
> + srdi r9,r3,60
> + subi r9,r9,(0xc + 3 + 1)
> + lis r10, 8
> + add r9,r9,r10
Hrm. You can avoid clobbering r10, which I assume is why you removed
the computation of esid from the common path by doing this instead:
rldicl r9,r3,4,62
addis r9,r9,8
subi r9,r9,4
> + srdi r10,r3,SID_SHIFT /* get esid */
> /*
> * for 1T we shift 12 bits more. slb_finish_load_1T will do
> * the necessary adjustment
> */
> - rldimi r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0
> + rldimi r10,r9,USER_ESID_BITS,0
> BEGIN_FTR_SECTION
> b slb_finish_load
> END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
> b slb_finish_load_1T
>
> 1:
> + srdi r10,r3,SID_SHIFT /* get esid */
> #ifdef CONFIG_SPARSEMEM_VMEMMAP
> /* Check virtual memmap region. To be patches at kernel boot */
> cmpldi cr0,r9,0xf
> @@ -91,23 +106,26 @@ _GLOBAL(slb_miss_kernel_load_vmemmap)
> _GLOBAL(slb_miss_kernel_load_io)
> li r11,0
> 6:
> - li r9,0x1
> + /*
> + * context = (MAX_CONTEXT - 3) + ((ea >> 60) - 0xc)
> + */
> + srdi r9,r3,60
> + subi r9,r9,(0xc + 3 + 1)
> + lis r10,8
> + add r9,r9,r10
> + srdi r10,r3,SID_SHIFT
Same here. Can you put the kernel context calculation into a common
path? In fact, now that kernel vsids, like user vsids are made of a
context and vsid component, can you put the rldimi which combines them
into a common path for both kernel and user addresses?
> /*
> * for 1T we shift 12 bits more. slb_finish_load_1T will do
> * the necessary adjustment
> */
> - rldimi r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0
> + rldimi r10,r9,USER_ESID_BITS,0
> BEGIN_FTR_SECTION
> b slb_finish_load
> END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
> b slb_finish_load_1T
>
> -0: /* user address: proto-VSID = context << 15 | ESID. First check
> - * if the address is within the boundaries of the user region
> - */
> - srdi. r9,r10,USER_ESID_BITS
> - bne- 8f /* invalid ea bits set */
> -
> +0:
> + srdi r10,r3,SID_SHIFT /* get esid */
>
> /* when using slices, we extract the psize off the slice bitmaps
> * and then we need to get the sllp encoding off the mmu_psize_defs
> diff --git a/arch/powerpc/mm/tlb_hash64.c b/arch/powerpc/mm/tlb_hash64.c
> index 0d82ef5..023ec8a 100644
> --- a/arch/powerpc/mm/tlb_hash64.c
> +++ b/arch/powerpc/mm/tlb_hash64.c
> @@ -82,11 +82,11 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
> if (!is_kernel_addr(addr)) {
> ssize = user_segment_size(addr);
> vsid = get_vsid(mm->context.id, addr, ssize);
> - WARN_ON(vsid == 0);
> } else {
> vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
> ssize = mmu_kernel_ssize;
> }
> + WARN_ON(vsid == 0);
> vpn = hpt_vpn(addr, vsid, ssize);
> rpte = __real_pte(__pte(pte), ptep);
>
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* [PATCH 03/18] powerpc: remove cast for kmalloc/kzalloc return value
From: Zhang Yanfei @ 2013-03-12 4:54 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Andrew Morton
Cc: linuxppc-dev, linux-kernel@vger.kernel.org
In-Reply-To: <513EB23D.7020303@cn.fujitsu.com>
remove cast for kmalloc/kzalloc return value.
Signed-off-by: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: linuxppc-dev@lists.ozlabs.org
---
arch/powerpc/kernel/nvram_64.c | 3 +--
arch/powerpc/kvm/book3s_pr.c | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index bec1e93..48fbc2b 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -511,8 +511,7 @@ int __init nvram_scan_partitions(void)
"detected: 0-length partition\n");
goto out;
}
- tmp_part = (struct nvram_partition *)
- kmalloc(sizeof(struct nvram_partition), GFP_KERNEL);
+ tmp_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL);
err = -ENOMEM;
if (!tmp_part) {
printk(KERN_ERR "nvram_scan_partitions: kmalloc failed\n");
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 5e93438..dbdc15a 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -1039,7 +1039,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
if (!vcpu_book3s)
goto out;
- vcpu_book3s->shadow_vcpu = (struct kvmppc_book3s_shadow_vcpu *)
+ vcpu_book3s->shadow_vcpu =
kzalloc(sizeof(*vcpu_book3s->shadow_vcpu), GFP_KERNEL);
if (!vcpu_book3s->shadow_vcpu)
goto free_vcpu;
--
1.7.1
^ permalink raw reply related
* [PATCH 1/2][RFC] PowerPC/85xx: Add clock nodes support
From: Yuantian.Tang @ 2013-03-12 7:07 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tang Yuantian, devicetree-discuss, R58472
From: Tang Yuantian <Yuantian.Tang@freescale.com>
Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
---
take p5020 for example.
arch/powerpc/boot/dts/fsl/p5020si-post.dtsi | 44 ++++++++++++++++++++++++++-
arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi | 2 +
2 files changed, 45 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi
index 9ea77c3..2db0d3c 100644
--- a/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi
@@ -337,9 +337,51 @@
};
clockgen: global-utilities@e1000 {
- compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0";
+ compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0", "fixed-clock";
reg = <0xe1000 0x1000>;
clock-frequency = <0>;
+ clock-output-names = "sysclk";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pll1: pll1@800 {
+ #clock-cells = <1>;
+ reg = <0x800>;
+ compatible = "fsl,core-pll-clock";
+ clocks = <&clockgen>;
+ clock-output-names = "pll1", "pll1-div2", "pll1-div4";
+ };
+
+ pll2: pll2@820 {
+ #clock-cells = <1>;
+ reg = <0x820>;
+ compatible = "fsl,core-pll-clock";
+ clocks = <&clockgen>;
+ clock-output-names = "pll2", "pll2-div2", "pll2-div4";
+ };
+
+ mux0: mux0@0 {
+ #clock-cells = <0>;
+ reg = <0x0>;
+ compatible = "fsl,core-mux-clock";
+ clocks = <&pll1 0>, <&pll1 1>, <&pll1 2>,
+ <&pll2 0>, <&pll2 1>, <&pll2 2>;
+ clock-names = "pll1_0", "pll1_1", "pll1_2",
+ "pll2_0", "pll2_1", "pll2_2";
+ clock-output-names = "cmux0";
+ };
+
+ mux1: mux1@20 {
+ #clock-cells = <0>;
+ reg = <0x20>;
+ compatible = "fsl,core-mux-clock";
+ clocks = <&pll1 0>, <&pll1 1>, <&pll1 2>,
+ <&pll2 0>, <&pll2 1>, <&pll2 2>;
+ clock-names = "pll1_0", "pll1_1", "pll1_2",
+ "pll2_0", "pll2_1", "pll2_2";
+ clock-output-names = "cmux1";
+ };
};
rcpm: global-utilities@e2000 {
diff --git a/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi
index 8df47fc..fe1a2e6 100644
--- a/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi
@@ -88,6 +88,7 @@
cpu0: PowerPC,e5500@0 {
device_type = "cpu";
reg = <0>;
+ clocks = <&mux0>;
next-level-cache = <&L2_0>;
L2_0: l2-cache {
next-level-cache = <&cpc>;
@@ -96,6 +97,7 @@
cpu1: PowerPC,e5500@1 {
device_type = "cpu";
reg = <1>;
+ clocks = <&mux1>;
next-level-cache = <&L2_1>;
L2_1: l2-cache {
next-level-cache = <&cpc>;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 2/2][RFC] clk: add PowerPC corenet clock support
From: Yuantian.Tang @ 2013-03-12 7:07 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tang Yuantian, devicetree-discuss, R58472
In-Reply-To: <1363072053-32736-1-git-send-email-Yuantian.Tang@freescale.com>
From: Tang Yuantian <Yuantian.Tang@freescale.com>
This adds the clock driver support for Freescale E500MC, E5500,
E6500 series SoCs using common clock framework.
Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
---
arch/powerpc/platforms/Kconfig.cputype | 1 +
drivers/clk/Kconfig | 7 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-ppc-corenet.c | 262 ++++++++++++++++++++++++++++++++
4 files changed, 271 insertions(+), 0 deletions(-)
create mode 100644 drivers/clk/clk-ppc-corenet.c
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 72afd28..dc3a56b 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -159,6 +159,7 @@ config E500
config PPC_E500MC
bool "e500mc Support"
select PPC_FPU
+ select COMMON_CLK
depends on E500
help
This must be enabled for running on e500mc (and derivatives
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index a47e6ee..ecb663d 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -63,6 +63,13 @@ config CLK_TWL6040
McPDM. McPDM module is using the external bit clock on the McPDM bus
as functional clock.
+config CLK_PPC_CORENET
+ bool "Clock driver for PowerPC corenet platforms"
+ depends on PPC_E500MC
+ ---help---
+ This adds the clock driver support for Freescale PowerPC corenet
+ platforms using common clock framework.
+
endmenu
source "drivers/clk/mvebu/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index ee90e87..9e7750c 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_ARCH_U8500) += ux500/
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
obj-$(CONFIG_ARCH_SUNXI) += clk-sunxi.o
obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o
+obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o
# Chip specific
obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c
new file mode 100644
index 0000000..a7bfb02
--- /dev/null
+++ b/drivers/clk/clk-ppc-corenet.c
@@ -0,0 +1,262 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk-provider.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+struct cmux_clk {
+ struct clk_hw hw;
+ void __iomem *reg;
+};
+
+#define PLL_KILL (1 << 31)
+#define CLKSEL_SHIFT 27
+
+#define to_cmux_clk(p) container_of(p, struct cmux_clk, hw)
+
+static const int idx_val[9] = {0, 1, 2, 4, 5, 6, 8, 9, 10};
+static const int val_idx[12] = {0, 1, 2, 0, 3, 4, 5, 0, 6, 7, 8, 0};
+
+static void __iomem *base;
+
+static int cmux_set_parent(struct clk_hw *hw, u8 idx)
+{
+ struct cmux_clk *clk = to_cmux_clk(hw);
+ u32 clksel;
+
+ clksel = (idx_val[idx] & 0xf) << CLKSEL_SHIFT;
+ iowrite32be(clksel, clk->reg);
+
+ return 0;
+}
+
+static u8 cmux_get_parent(struct clk_hw *hw)
+{
+ struct cmux_clk *clk = to_cmux_clk(hw);
+ u32 val;
+
+ val = ioread32be(clk->reg);
+ val = (val >> CLKSEL_SHIFT) & 0xf;
+
+ return val_idx[val];
+}
+
+const struct clk_ops cmux_ops = {
+ .get_parent = cmux_get_parent,
+ .set_parent = cmux_set_parent,
+};
+
+static void __init core_mux_init(struct device_node *np)
+{
+ struct clk *clk;
+ struct clk_init_data init;
+ struct cmux_clk *cmux_clk;
+ int rc, count, i;
+ u32 offset;
+ const char *clk_name;
+ const char **parent_names;
+
+ rc = of_property_read_u32(np, "reg", &offset);
+ if (rc) {
+ pr_err("%s: could not get reg property\n", np->name);
+ return;
+ }
+
+ /* get the input clock source count */
+ count = of_property_count_strings(np, "clock-names");
+ if (count < 0) {
+ pr_err("%s: get clock count error\n", np->name);
+ return;
+ }
+ parent_names = kzalloc((sizeof(char *) * count), GFP_KERNEL);
+ if (!parent_names) {
+ pr_err("%s: could not allocate parent_names\n", __func__);
+ return;
+ }
+
+ for (i = 0; i < count; i++)
+ parent_names[i] = of_clk_get_parent_name(np, i);
+
+ cmux_clk = kzalloc(sizeof(struct cmux_clk), GFP_KERNEL);
+ if (!cmux_clk) {
+ pr_err("%s: could not allocate cmux_clk\n", __func__);
+ goto err_name;
+ }
+ cmux_clk->reg = base + offset;
+
+ rc = of_property_read_string_index(np, "clock-output-names",
+ 0, &clk_name);
+ if (rc) {
+ pr_err("%s: read clock names error\n", np->name);
+ goto err_clk;
+ }
+
+ init.name = clk_name;
+ init.ops = &cmux_ops;
+ init.flags = 0;
+ init.parent_names = parent_names;
+ init.num_parents = count;
+ cmux_clk->hw.init = &init;
+
+ clk = clk_register(NULL, &cmux_clk->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: could not register clock\n", clk_name);
+ goto err_clk;
+ }
+
+ rc = of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ if (rc) {
+ pr_err("Could not register clock provider for node:%s\n",
+ np->name);
+ goto err_clk;
+ }
+ goto err_name;
+
+err_clk:
+ kfree(cmux_clk);
+err_name:
+ /* free *_names because they are reallocated when registered */
+ kfree(parent_names);
+}
+
+static void __init core_pll_init(struct device_node *np)
+{
+ u32 offset, mult;
+ int i, rc, count;
+ const char *clk_name, *parent_name;
+ struct clk_onecell_data *onecell_data;
+ struct clk **subclks;
+
+ rc = of_property_read_u32(np, "reg", &offset);
+ if (rc) {
+ pr_err("%s: could not get reg property\n", np->name);
+ return;
+ }
+
+ /* get the multiple of PLL */
+ mult = ioread32be(base + offset);
+
+ /* check if this PLL is disabled */
+ if (mult & PLL_KILL) {
+ pr_debug("PLL:%s is disabled\n", np->name);
+ return;
+ }
+ mult = (mult >> 1) & 0x3f;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ if (!parent_name) {
+ pr_err("PLL: %s must have a parent\n", np->name);
+ return;
+ }
+
+ count = of_property_count_strings(np, "clock-output-names");
+ if (count < 0 || count > 4) {
+ pr_err("%s: clock is not supported\n", np->name);
+ return;
+ }
+
+ subclks = kzalloc(sizeof(struct clk *) * count, GFP_KERNEL);
+ if (!subclks) {
+ pr_err("%s: could not allocate subclks\n", __func__);
+ return;
+ }
+
+ onecell_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
+ if (!onecell_data) {
+ pr_err("%s: could not allocate onecell_data\n", __func__);
+ goto err_clks;
+ }
+
+ for (i = 0; i < count; i++) {
+ rc = of_property_read_string_index(np, "clock-output-names",
+ i, &clk_name);
+ if (rc) {
+ pr_err("%s: could not get clock names\n", np->name);
+ goto err_cell;
+ }
+
+ /*
+ * when count == 4, there are 4 output clocks:
+ * /1, /2, /3, /4 respectively
+ * when count < 4, there are at least 2 output clocks:
+ * /1, /2, (/4, if count == 3) respectively.
+ */
+ if (count == 4)
+ subclks[i] = clk_register_fixed_factor(NULL, clk_name,
+ parent_name, 0, mult, 1 + i);
+ else
+
+ subclks[i] = clk_register_fixed_factor(NULL, clk_name,
+ parent_name, 0, mult, 1 << i);
+
+ if (IS_ERR(subclks[i])) {
+ pr_err("%s: could not register clock\n", clk_name);
+ goto err_cell;
+ }
+ }
+
+ onecell_data->clks = subclks;
+ onecell_data->clk_num = count;
+
+ rc = of_clk_add_provider(np, of_clk_src_onecell_get, onecell_data);
+ if (rc) {
+ pr_err("Could not register clk provider for node:%s\n",
+ np->name);
+ goto err_cell;
+ }
+
+ return;
+err_cell:
+ kfree(onecell_data);
+err_clks:
+ kfree(subclks);
+}
+
+static const struct of_device_id clk_match[] __initconst = {
+ { .compatible = "fixed-clock", .data = of_fixed_clk_setup, },
+ { .compatible = "fsl,core-pll-clock", .data = core_pll_init, },
+ { .compatible = "fsl,core-mux-clock", .data = core_mux_init, },
+ {}
+};
+
+static int __init ppc_corenet_clk_probe(struct platform_device *pdev)
+{
+ struct device_node *np;
+
+ np = pdev->dev.of_node;
+ base = of_iomap(np, 0);
+ if (!base) {
+ dev_err(&pdev->dev, "iomap error\n");
+ return -ENOMEM;
+ }
+ of_clk_init(clk_match);
+
+ return 0;
+}
+
+static const struct of_device_id ppc_corenet_clk_ids[] __initconst = {
+ { .compatible = "fsl,qoriq-clockgen-1.0", },
+ { .compatible = "fsl,qoriq-clockgen-2", },
+ {}
+};
+
+static struct platform_driver ppc_corenet_clk_driver = {
+ .driver = {
+ .name = "ppc_corenet_clock",
+ .owner = THIS_MODULE,
+ .of_match_table = ppc_corenet_clk_ids,
+ },
+ .probe = ppc_corenet_clk_probe,
+};
+
+static int __init ppc_corenet_clk_init(void)
+{
+ return platform_driver_register(&ppc_corenet_clk_driver);
+}
+subsys_initcall(ppc_corenet_clk_init);
+
+MODULE_AUTHOR("Tang Yuantian: <Yuantian.Tang@freescale.com>");
+MODULE_DESCRIPTION("Clock Driver for Freescale PowerPC Corenet Platform");
+MODULE_LICENSE("GPL");
--
1.7.0.4
^ permalink raw reply related
* [PATCH][V3] powerpc: remove the PPC_CLOCK dependency
From: Yuantian.Tang @ 2013-03-12 6:43 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev, R58472, Tang Yuantian
From: Tang Yuantian <Yuantian.Tang@freescale.com>
Config FSL_SOC does not depend on PPC_CLOCK anymore since the following
commit got merged: 93abe8e (clk: add non CONFIG_HAVE_CLK routines)
Config CPM does not use PPC_CLOCK either currently. So remove them.
PPC_CLOCK also keeps Freescale PowerPC archtecture from supporting COMMON_CLK.
Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
---
v3: modified the description
v2: correct the title
arch/powerpc/Kconfig | 1 -
arch/powerpc/platforms/Kconfig | 1 -
2 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 352f416..383485b 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -655,7 +655,6 @@ config SBUS
config FSL_SOC
bool
select HAVE_CAN_FLEXCAN if NET && CAN
- select PPC_CLOCK
config FSL_PCI
bool
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index e7a896a..aba81cd 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -343,7 +343,6 @@ config FSL_ULI1575
config CPM
bool
- select PPC_CLOCK
config OF_RTC
bool
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH -V2 2/2] powerpc: Update kernel VSID range
From: Aneesh Kumar K.V @ 2013-03-12 7:19 UTC (permalink / raw)
To: David Gibson; +Cc: phileas-fogg, paulus, linuxppc-dev, geoff
In-Reply-To: <20130312042547.GC9351@truffula.fritz.box>
David Gibson <dwg@au1.ibm.com> writes:
> On Fri, Feb 15, 2013 at 09:09:38PM +0530, Aneesh Kumar K.V wrote:
>> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
>>
.... snip....
>> - * - We allow for USER_ESID_BITS significant bits of ESID and
>> - * CONTEXT_BITS bits of context for user addresses.
>> - * i.e. 64T (46 bits) of address space for up to half a million contexts.
>> - *
>> - * - The scramble function gives robust scattering in the hash
>> - * table (at least based on some initial results). The previous
>> - * method was more susceptible to pathological cases giving excessive
>> - * hash collisions.
>> + * We also need to avoid the last segment of the last context, because that
>> + * would give a protovsid of 0x1fffffffff. That will result in a VSID 0
>> + * because of the modulo operation in vsid scramble. But the vmemmap
>> + * (which is what uses region 0xf) will never be close to 64TB in size
>> + * (it's 56 bytes per page of system memory).
>> */
>>
>> #define CONTEXT_BITS 19
>> @@ -386,15 +382,25 @@ extern void slb_set_size(u16 size);
>> #define USER_ESID_BITS_1T 6
>
> USER_ESID_BITS should probably be renamed just ESID_BITS, since it's
> now relevant to kernel addresses too.
Done. I added this as a patch on top of the series.
>
>> /*
>> + * 256MB segment
>> + * The proto-VSID space has 2^(CONTEX_BITS + USER_ESID_BITS) - 1 segments
>> + * available for user + kernel mapping. The top 4 contexts are used for
>> + * kernel mapping. Each segment contains 2^28 bytes. Each
>> + * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts
>> + * (19 == 37 + 28 - 46).
>> + */
>> +#define MAX_CONTEXT ((ASM_CONST(1) << CONTEXT_BITS) - 1)
>
> Hrm. I think it would be clearer to have MAX_CONTEXT (still) be the
> maximum usable *user* context (i.e. 0x80000 - 5) and put the kernel
> ones above that still.
>
Done as
-#define MAX_CONTEXT ((ASM_CONST(1) << CONTEXT_BITS) - 1)
+#define MAX_USER_CONTEXT ((ASM_CONST(1) << CONTEXT_BITS) - 5)
Also updated the reference of MAX_CONTEXT in the code to
MAX_USER_CONTEXT
>> +
>> +/*
>> * This should be computed such that protovosid * vsid_mulitplier
>> * doesn't overflow 64 bits. It should also be co-prime to vsid_modulus
>> */
>> #define VSID_MULTIPLIER_256M ASM_CONST(12538073) /* 24-bit prime */
>> -#define VSID_BITS_256M (CONTEXT_BITS + USER_ESID_BITS + 1)
>> +#define VSID_BITS_256M (CONTEXT_BITS + USER_ESID_BITS)
>> #define VSID_MODULUS_256M ((1UL<<VSID_BITS_256M)-1)
>>
>> #define VSID_MULTIPLIER_1T ASM_CONST(12538073) /* 24-bit prime */
>> -#define VSID_BITS_1T (CONTEXT_BITS + USER_ESID_BITS_1T + 1)
>> +#define VSID_BITS_1T (CONTEXT_BITS + USER_ESID_BITS_1T)
>> #define VSID_MODULUS_1T ((1UL<<VSID_BITS_1T)-1)
>>
>>
.... snip......
>> #endif /* _ASM_POWERPC_MMU_HASH64_H_ */
>> diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
>> index 4665e82..0e9c48c 100644
>> --- a/arch/powerpc/kernel/exceptions-64s.S
>> +++ b/arch/powerpc/kernel/exceptions-64s.S
>> @@ -1268,20 +1268,39 @@ do_ste_alloc:
>> _GLOBAL(do_stab_bolted)
>
> The stab path certainly hasn't been tested, since we've been broken on
> stab machines for a long time.
>
>> stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
>> std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */
>> + mfspr r11,SPRN_DAR /* ea */
>>
>> + /*
>> + * check for bad kernel/user address
>> + * (ea & ~REGION_MASK) >= PGTABLE_RANGE
>> + */
>> + clrldi r9,r11,4
>> + li r10,-1
>> + clrldi r10,r10,(64 - 46)
>> + cmpld cr7,r9,r10
>
> You can replace the above 4 instructions with just:
> rldicr. r9,r11,4,(64-46-4)
>
nice, updated as below
- clrldi r9,r11,4
- li r10,-1
- clrldi r10,r10,(64 - 46)
- cmpld cr7,r9,r10
+ rldicr. r9,r11,4,(64 - 46 - 4)
li r9,0 /* VSID = 0 for bad address */
- bgt cr7,0f
+ bne- 0f
>> + li r9,0 /* VSID = 0 for bad address */
>> + bgt cr7,0f
>> +
>> + /*
.... snip....
>> diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
>> index 3a292be..bfeab83 100644
>> --- a/arch/powerpc/mm/hash_utils_64.c
>> +++ b/arch/powerpc/mm/hash_utils_64.c
>> @@ -194,6 +194,11 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
>> unsigned long vpn = hpt_vpn(vaddr, vsid, ssize);
>> unsigned long tprot = prot;
>>
>> + /*
>> + * If we hit a bad address return error.
>> + */
>> + if (!vsid)
>> + return -1;
>> /* Make kernel text executable */
>> if (overlaps_kernel_text(vaddr, vaddr + step))
>> tprot &= ~HPTE_R_N;
>> @@ -921,11 +926,6 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
>> DBG_LOW("hash_page(ea=%016lx, access=%lx, trap=%lx\n",
>> ea, access, trap);
>>
>> - if ((ea & ~REGION_MASK) >= PGTABLE_RANGE) {
>> - DBG_LOW(" out of pgtable range !\n");
>> - return 1;
>> - }
>> -
>
> Hrm. This test is conceptually different, even if the logic is the
> same as the vsid availablility test you may have performed earlier.
> Perhaps add BUILD_BUG_ON()s to ensure that they really are the same.
>
can you elaborate that ? What BUILD_BUG_ON test are you suggesting ?
>
>> /* Get region & vsid */
>> switch (REGION_ID(ea)) {
>> case USER_REGION_ID:
>> @@ -956,6 +956,11 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
>> }
>> DBG_LOW(" mm=%p, mm->pgdir=%p, vsid=%016lx\n", mm, mm->pgd, vsid);
>>
>> + /* Bad address. */
>> + if (!vsid) {
>> + DBG_LOW("Bad address!\n");
>> + return 1;
>> + }
>> /* Get pgdir */
>> pgdir = mm->pgd;
>> if (pgdir == NULL)
>> @@ -1125,6 +1130,8 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
>> /* Get VSID */
>> ssize = user_segment_size(ea);
>> vsid = get_vsid(mm->context.id, ea, ssize);
>> + if (!vsid)
>> + return;
>>
>> /* Hash doesn't like irqs */
>> local_irq_save(flags);
>> @@ -1217,6 +1224,9 @@ static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi)
>> hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize);
>> hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
>>
>> + /* Don't create HPTE entries for bad address */
>> + if (!vsid)
>> + return;
>> ret = ppc_md.hpte_insert(hpteg, vpn, __pa(vaddr),
>> mode, HPTE_V_BOLTED,
>> mmu_linear_psize, mmu_kernel_ssize);
>> diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c
>> index 40bc5b0..59cd773 100644
>> --- a/arch/powerpc/mm/mmu_context_hash64.c
>> +++ b/arch/powerpc/mm/mmu_context_hash64.c
>> @@ -29,15 +29,6 @@
>> static DEFINE_SPINLOCK(mmu_context_lock);
>> static DEFINE_IDA(mmu_context_ida);
>>
>> -/*
>> - * 256MB segment
>> - * The proto-VSID space has 2^(CONTEX_BITS + USER_ESID_BITS) - 1 segments
>> - * available for user mappings. Each segment contains 2^28 bytes. Each
>> - * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts
>> - * (19 == 37 + 28 - 46).
>> - */
>> -#define MAX_CONTEXT ((1UL << CONTEXT_BITS) - 1)
>> -
>> int __init_new_context(void)
>> {
>> int index;
>> @@ -56,7 +47,8 @@ again:
>> else if (err)
>> return err;
>>
>> - if (index > MAX_CONTEXT) {
>> + if (index > (MAX_CONTEXT - 4)) {
>> + /* Top 4 context id values are used for kernel */
>
> This change would not be necessary if you changed MAX_CONTEXT as
> suggested above.
>
done now have
- if (index > (MAX_CONTEXT - 4)) {
- /* Top 4 context id values are used for kernel */
+ if (index > (MAX_USER_CONTEXT) {
>> spin_lock(&mmu_context_lock);
>> ida_remove(&mmu_context_ida, index);
>> spin_unlock(&mmu_context_lock);
>> diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
>> index 1a16ca2..c066d00 100644
>> --- a/arch/powerpc/mm/slb_low.S
>> +++ b/arch/powerpc/mm/slb_low.S
>> @@ -31,13 +31,20 @@
>> * No other registers are examined or changed.
>> */
>> _GLOBAL(slb_allocate_realmode)
>> - /* r3 = faulting address */
>> + /*
>> + * check for bad kernel/user address
>> + * (ea & ~REGION_MASK) >= PGTABLE_RANGE
>> + */
>> + clrldi r9,r3,4
>> + li r10,-1
>> + clrldi r10,r10,(64 - 46)
>> + cmpld cr7,r9,r10
>> + bgt cr7,8f
>
> As in the stab path, you can accomplish this with a single rldicr.
>
>>
>> srdi r9,r3,60 /* get region */
>> - srdi r10,r3,28 /* get esid */
>> cmpldi cr7,r9,0xc /* cmp PAGE_OFFSET for later use */
>>
>> - /* r3 = address, r10 = esid, cr7 = <> PAGE_OFFSET */
>> + /* r3 = address, cr7 = <> PAGE_OFFSET */
>> blt cr7,0f /* user or kernel? */
>>
>> /* kernel address: proto-VSID = ESID */
>> @@ -56,18 +63,26 @@ _GLOBAL(slb_allocate_realmode)
>> */
>> _GLOBAL(slb_miss_kernel_load_linear)
>> li r11,0
>> - li r9,0x1
>> + /*
>> + * context = (MAX_CONTEXT - 3) + ((ea >> 60) - 0xc)
>> + */
>> + srdi r9,r3,60
>> + subi r9,r9,(0xc + 3 + 1)
>> + lis r10, 8
>> + add r9,r9,r10
>
> Hrm. You can avoid clobbering r10, which I assume is why you removed
> the computation of esid from the common path by doing this instead:
>
> rldicl r9,r3,4,62
> addis r9,r9,8
> subi r9,r9,4
nice. Updated. I am inlining the final patch below.
>
>> + srdi r10,r3,SID_SHIFT /* get esid */
>> /*
>> * for 1T we shift 12 bits more. slb_finish_load_1T will do
>> * the necessary adjustment
>> */
>> - rldimi r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0
>> + rldimi r10,r9,USER_ESID_BITS,0
>> BEGIN_FTR_SECTION
>> b slb_finish_load
>> END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
>> b slb_finish_load_1T
>>
>> 1:
>> + srdi r10,r3,SID_SHIFT /* get esid */
>> #ifdef CONFIG_SPARSEMEM_VMEMMAP
>> /* Check virtual memmap region. To be patches at kernel boot */
>> cmpldi cr0,r9,0xf
>> @@ -91,23 +106,26 @@ _GLOBAL(slb_miss_kernel_load_vmemmap)
>> _GLOBAL(slb_miss_kernel_load_io)
>> li r11,0
>> 6:
>> - li r9,0x1
>> + /*
>> + * context = (MAX_CONTEXT - 3) + ((ea >> 60) - 0xc)
>> + */
>> + srdi r9,r3,60
>> + subi r9,r9,(0xc + 3 + 1)
>> + lis r10,8
>> + add r9,r9,r10
>> + srdi r10,r3,SID_SHIFT
>
> Same here. Can you put the kernel context calculation into a common
> path? In fact, now that kernel vsids, like user vsids are made of a
> context and vsid component, can you put the rldimi which combines them
> into a common path for both kernel and user addresses?
will do.
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index ffa0c48..f0351b5 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1274,12 +1274,9 @@ _GLOBAL(do_stab_bolted)
* check for bad kernel/user address
* (ea & ~REGION_MASK) >= PGTABLE_RANGE
*/
- clrldi r9,r11,4
- li r10,-1
- clrldi r10,r10,(64 - 46)
- cmpld cr7,r9,r10
+ rldicr. r9,r11,4,(64 - 46 - 4)
li r9,0 /* VSID = 0 for bad address */
- bgt cr7,0f
+ bne- 0f
/*
* Calculate VSID:
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index 80fd644..349411e 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -35,16 +35,14 @@ _GLOBAL(slb_allocate_realmode)
* check for bad kernel/user address
* (ea & ~REGION_MASK) >= PGTABLE_RANGE
*/
- clrldi r9,r3,4
- li r10,-1
- clrldi r10,r10,(64 - 46)
- cmpld cr7,r9,r10
- bgt cr7,8f
+ rldicr. r9,r3,4,(64 - 46 - 4)
+ bne- 8f
srdi r9,r3,60 /* get region */
+ srdi r10,r3,SID_SHIFT /* get esid */
cmpldi cr7,r9,0xc /* cmp PAGE_OFFSET for later use */
- /* r3 = address, cr7 = <> PAGE_OFFSET */
+ /* r3 = address, r10 = esid, cr7 = <> PAGE_OFFSET */
blt cr7,0f /* user or kernel? */
/* kernel address: proto-VSID = ESID */
@@ -66,11 +64,10 @@ _GLOBAL(slb_miss_kernel_load_linear)
/*
* context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1
*/
- srdi r9,r3,60
- subi r9,r9,(0xc + 4)
- lis r10, 8
- add r9,r9,r10
- srdi r10,r3,SID_SHIFT /* get esid */
+ rldicl r9,r3,4,62
+ addis r9,r9,8
+ subi r9,r9,4
+
/*
* for 1T we shift 12 bits more. slb_finish_load_1T will do
* the necessary adjustment
@@ -82,7 +79,6 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
b slb_finish_load_1T
1:
- srdi r10,r3,SID_SHIFT /* get esid */
#ifdef CONFIG_SPARSEMEM_VMEMMAP
/* Check virtual memmap region. To be patches at kernel boot */
cmpldi cr0,r9,0xf
@@ -109,11 +105,9 @@ _GLOBAL(slb_miss_kernel_load_vmemmap)
/*
* context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1
*/
- srdi r9,r3,60
- subi r9,r9,(0xc + 4)
- lis r10,8
- add r9,r9,r10
- srdi r10,r3,SID_SHIFT
+ rldicl r9,r3,4,62
+ addis r9,r9,8
+ subi r9,r9,4
/*
* for 1T we shift 12 bits more. slb_finish_load_1T will do
* the necessary adjustment
@@ -125,8 +119,6 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
b slb_finish_load_1T
0:
- srdi r10,r3,SID_SHIFT /* get esid */
-
/* when using slices, we extract the psize off the slice bitmaps
* and then we need to get the sllp encoding off the mmu_psize_defs
* array.
^ permalink raw reply related
* RE: [PATCH V4] powerpc/85xx: Add machine check handler to fix PCIe erratum on mpc85xx
From: Jia Hongtao-B38951 @ 2013-03-12 7:40 UTC (permalink / raw)
To: Wood Scott-B07421
Cc: David Laight, linuxppc-dev@lists.ozlabs.org, Stuart Yoder
In-Reply-To: <1362790153.29198.11@snotra>
> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Saturday, March 09, 2013 8:49 AM
> To: Jia Hongtao-B38951
> Cc: Wood Scott-B07421; David Laight; linuxppc-dev@lists.ozlabs.org;
> Stuart Yoder
> Subject: Re: [PATCH V4] powerpc/85xx: Add machine check handler to fix
> PCIe erratum on mpc85xx
>=20
> On 03/08/2013 02:01:46 AM, Jia Hongtao-B38951 wrote:
> >
> >
> > > -----Original Message-----
> > > From: Wood Scott-B07421
> > > Sent: Friday, March 08, 2013 12:38 AM
> > > To: Jia Hongtao-B38951
> > > Cc: David Laight; Wood Scott-B07421; linuxppc-dev@lists.ozlabs.org;
> > > Stuart Yoder
> > > Subject: Re: [PATCH V4] powerpc/85xx: Add machine check handler to
> > fix
> > > PCIe erratum on mpc85xx
> > >
> > > On 03/07/2013 02:06:05 AM, Jia Hongtao-B38951 wrote:
> > > > Here is the ideas from Scott:
> > > > "
> > > > > + if (is_in_pci_mem_space(addr)) {
> > > > > + inst =3D *(unsigned int *)regs->nip;
> > > >
> > > > Be careful about taking a fault here. A simple TLB miss should be
> > > > safe given that we shouldn't be accessing PCIe in the middle of
> > > > exception code, but what if the mapping has gone away (e.g. a
> > > > userspace driver had its code munmap()ed or swapped out)? What if
> > > > permissions allow execute but not read (not sure if Linux will
> > allow
> > > > this, but the hardware does)?
> > > >
> > > > What if it happened in a KVM guest? You can't access guest
> > addresses
> > > > directly.
> > > > "
> > >
> > > That means you need to be careful about how you read the
> > instruction, not
> > > that you shouldn't do it at all.
> > >
> > > -Scott
> >
> > I agree.
> >
> > Do you have a more secure way to get the instruction?
> > Or what should be done to avoid permission break issue?
>=20
> probe_kernel_address() should take care of userspace issues. As for
> KVM, if you see MSR_GS set, bail out and don't apply the workaround.
> Let KVM/QEMU deal with it as it wishes (e.g. reflect to the guest and
> let its machine check handler do the skipping). On PR-mode KVM (e.g.
> on e500v2-based chips) there is no MSR_GS and it just looks like
> userspace code -- for now just pretend it is user mode.
>=20
> -Scott
Hi Scott,
Is that OK if I use the following code?
u32 inst;
int ret;
if (is_in_pci_mem_space(addr)) {
if (!user_mode(regs)) {
ret =3D probe_kernel_address(regs->nip, inst);
if (!ret) {
rd =3D get_rt(inst);
regs->gpr[rd] =3D 0xffffffff;
}
}
regs->nip +=3D 4;
return 1;
}
Thanks.
-Hongtao.
^ permalink raw reply
* [PATCH] powerpc/85xx: workaround for chips with MSI hardware errata
From: Jia Hongtao @ 2013-03-12 7:48 UTC (permalink / raw)
To: linuxppc-dev, galak; +Cc: B07421, b38951
The MPIC chip with 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 <B38951@freescale.com>
---
arch/powerpc/sysdev/fsl_msi.c | 60 +++++++++++++++++++++++++++++++++++++++-
arch/powerpc/sysdev/fsl_msi.h | 2 +
2 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 178c994..0dea680 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -98,8 +98,20 @@ 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)
{
+ struct fsl_msi *msi;
+
if (type == PCI_CAP_ID_MSIX)
pr_debug("fslmsi: MSI-X untested, trying anyway.\n");
+ else if (type == PCI_CAP_ID_MSI)
+ /*
+ * MPIC chip with 2.0 version 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.
+ */
+ list_for_each_entry(msi, &msi_head, list)
+ if (msi->feature & MSI_HW_ERRATA_ENDIAN)
+ return -EINVAL;
return 0;
}
@@ -142,7 +154,11 @@ 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;
+ /* See the comment 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,13 +377,43 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev,
return 0;
}
+/* MPIC chip with 2.0 version has erratum PIC1 */
+static int mpic_has_errata(struct platform_device *dev)
+{
+ struct device_node *mpic_node;
+
+ mpic_node = of_irq_find_parent(dev->dev.of_node);
+ if (mpic_node) {
+ u32 *reg_base, brr1 = 0;
+ /* Get the PIC reg base */
+ reg_base = of_iomap(mpic_node, 0);
+ of_node_put(mpic_node);
+ if (!reg_base) {
+ dev_err(&dev->dev, "ioremap problem failed.\n");
+ return -EIO;
+ }
+
+ /* Get the mpic chip version from block revision register 1 */
+ brr1 = in_be32(reg_base + MPIC_FSL_BRR1);
+ iounmap(reg_base);
+ if ((brr1 & MPIC_FSL_BRR1_VER) == 0x0200)
+ return 1;
+ } else {
+ dev_err(&dev->dev, "MSI can't find his parent mpic node.\n");
+ of_node_put(mpic_node);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
static const struct of_device_id fsl_of_msi_ids[];
static int fsl_of_msi_probe(struct platform_device *dev)
{
const struct of_device_id *match;
struct fsl_msi *msi;
struct resource res;
- int err, i, j, irq_index, count;
+ int err, i, j, irq_index, count, errata;
int rc;
const u32 *p;
const struct fsl_msi_feature *features;
@@ -423,6 +469,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) {
+ errata = mpic_has_errata(dev);
+ if (errata > 0) {
+ msi->feature |= MSI_HW_ERRATA_ENDIAN;
+ } else if (errata < 0) {
+ err = errata;
+ goto error_out;
+ }
+ }
+
/*
* Remember the phandle, so that we can match with any PCI nodes
* that have an "fsl,msi" property.
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h
index 8225f86..7389e8e 100644
--- a/arch/powerpc/sysdev/fsl_msi.h
+++ b/arch/powerpc/sysdev/fsl_msi.h
@@ -25,6 +25,8 @@
#define FSL_PIC_IP_IPIC 0x00000002
#define FSL_PIC_IP_VMPIC 0x00000003
+#define MSI_HW_ERRATA_ENDIAN 0x00000010
+
struct fsl_msi {
struct irq_domain *irqhost;
--
1.7.5.1
^ permalink raw reply related
* Re: [PATCH] Make PCIe hotplug work with Freescale PCIe controllers
From: Rojhalat Ibrahim @ 2013-03-12 9:23 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <179EA411-594D-4774-903A-6C0445A01747@kernel.crashing.org>
On Monday 11 March 2013 12:17:42 Kumar Gala wrote:
>
> Rather than do it this way, we should do something like:
>
> fsl_indirect_read_config() {
> link check
> if (link)
> indirect_read_config()
> }
>
> and just add fsl_indirect_{r,w}_config into fsl_pci.c
>
> - k
>
Ok, how about this:
Signed-off-by: Rojhalat Ibrahim <imr@rtschenk.de>
---
arch/powerpc/sysdev/fsl_pci.c | 49
++++++++++++++++++++++++++++++++++++++----
1 file changed, 45 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 682084d..693db9f 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -36,6 +36,8 @@
static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
+static struct pci_ops *indirect_pci_ops;
+
static void quirk_fsl_pcie_header(struct pci_dev *dev)
{
u8 hdr_type;
@@ -64,6 +66,45 @@ static int __init fsl_pcie_check_link(struct pci_controller
*hose)
return 0;
}
+static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 *val)
+{
+ struct pci_controller *hose = pci_bus_to_host(bus);
+
+ // check the link status
+ if ((bus->number == hose->first_busno) && (devfn == 0)) {
+ u32 ltssm = 0;
+ indirect_pci_ops->read(bus, 0, PCIE_LTSSM, 4, <ssm);
+ if (ltssm < PCIE_LTSSM_L0) {
+ hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+ } else {
+ hose->indirect_type &= ~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+ }
+ }
+ return indirect_pci_ops->read(bus, devfn, offset, len, val);
+}
+
+static int fsl_indirect_write_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 val)
+{
+ return indirect_pci_ops->write(bus, devfn, offset, len, val);
+}
+
+static struct pci_ops fsl_indirect_pci_ops =
+{
+ .read = fsl_indirect_read_config,
+ .write = fsl_indirect_write_config,
+};
+
+static void __init fsl_setup_indirect_pci(struct pci_controller* hose,
+ resource_size_t cfg_addr,
+ resource_size_t cfg_data, u32 flags)
+{
+ setup_indirect_pci(hose, cfg_addr, cfg_data, flags);
+ indirect_pci_ops = hose->ops;
+ hose->ops = &fsl_indirect_pci_ops;
+}
+
#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
#define MAX_PHYS_ADDR_BITS 40
@@ -461,8 +502,8 @@ int __init fsl_add_bridge(struct platform_device *pdev,
int is_primary)
hose->first_busno = bus_range ? bus_range[0] : 0x0;
hose->last_busno = bus_range ? bus_range[1] : 0xff;
- setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
- PPC_INDIRECT_TYPE_BIG_ENDIAN);
+ fsl_setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
+ PPC_INDIRECT_TYPE_BIG_ENDIAN);
if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
/* For PCIE read HEADER_TYPE to identify controler mode */
@@ -766,8 +807,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
if (ret)
goto err0;
} else {
- setup_indirect_pci(hose, rsrc_cfg.start,
- rsrc_cfg.start + 4, 0);
+ fsl_setup_indirect_pci(hose, rsrc_cfg.start,
+ rsrc_cfg.start + 4, 0);
}
printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
^ permalink raw reply related
* Re: [PATCH 5/6][v4]: perf: Create a sysfs entry for Power event format
From: Paul Mackerras @ 2013-03-12 9:27 UTC (permalink / raw)
To: Sukadev Bhattiprolu
Cc: Andi Kleen, Peter Zijlstra, robert.richter, Anton Blanchard,
linux-kernel, Stephane Eranian, linuxppc-dev, Ingo Molnar,
Arnaldo Carvalho de Melo, Jiri Olsa
In-Reply-To: <20130306054826.GA14627@us.ibm.com>
On Tue, Mar 05, 2013 at 09:48:26PM -0800, Sukadev Bhattiprolu wrote:
> Michael Ellerman [michael@ellerman.id.au] wrote:
> | I suspect Arnaldo was either waiting for an ACK from Ben, or was
> | expecting Ben to take it?
>
> Arnaldo, here is an updated patch. If it is acked by Paul Mackerras,
> Michael Ellerman or Ben, will you add it to your tree so the whole
> patchset comes from one place ?
>
> Sukadev
>
> ---
> >From 50c7a46f14083c0ed10d66b7aed66ba76e798550 Mon Sep 17 00:00:00 2001
> From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> Date: Tue, 5 Mar 2013 21:20:56 -0800
> Subject: [PATCH] [PATCH 5/6][v4]: perf Create a sysfs format entry for Power7 events
>
> Create a sysfs entry, '/sys/bus/event_source/devices/cpu/format/event'
> which describes the format of the POWER7 PMU events.
>
> This code is based on corresponding code in x86.
>
> Changelog[v4]: [Michael Ellerman, Paul Mckerras] The event format is different
> for other POWER cpus. So move the code to POWER7-specific,
> power7-pmu.c Also, the POWER7 format uses bits 0-19 not 0-20.
>
> Changelog[v2]: [Jiri Osla] Use PMU_FORMAT_ATTR rather than duplicating code.
>
> Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Paul Mackerras <paulus@samba.org>
^ permalink raw reply
* RE: [PATCH V4] powerpc/85xx: Add machine check handler to fix PCIe erratum on mpc85xx
From: David Laight @ 2013-03-12 9:47 UTC (permalink / raw)
To: Jia Hongtao-B38951, Wood Scott-B07421; +Cc: linuxppc-dev, Stuart Yoder
In-Reply-To: <412C8208B4A0464FA894C5F0C278CD5D01C15369@039-SN1MPN1-003.039d.mgd.msft.net>
> Is that OK if I use the following code?
...
> if (is_in_pci_mem_space(addr)) {
> if (!user_mode(regs)) {
> ret =3D probe_kernel_address(regs->nip, inst);
>=20
> if (!ret) {
> rd =3D get_rt(inst);
> regs->gpr[rd] =3D 0xffffffff;
> }
> }
Don't you need to check that the instruction is actually
a memory read?
I also know that there are people mapping PCIe addresses
directly into userspace for 'simple' access to things like
fpga devices.
I suspect that such devices are the ones likely to generate
the faulting cycles. So you probably do want to handle
faults from normal userspace addresses.
David
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox