Re: [PATCH] powerpc/rtasd: Improve unknown error logging

2018-10-09 Thread Vasant Hegde

On 10/10/2018 10:53 AM, Oliver O'Halloran wrote:

Currently when we get an unknown RTAS event it prints the type as
"Unknown" and no other useful information. Add the raw type code to the
log message so that we have something to work off.


Yeah. Useful one.

Reviewed-by: Vasant Hegde 

-Vasant



Signed-off-by: Oliver O'Halloran 
---
  arch/powerpc/kernel/rtasd.c | 6 --
  1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 44d66c33d59d..6fafc82c04b0 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -150,8 +150,10 @@ static void printk_log_rtas(char *buf, int len)
} else {
struct rtas_error_log *errlog = (struct rtas_error_log *)buf;

-   printk(RTAS_DEBUG "event: %d, Type: %s, Severity: %d\n",
-  error_log_cnt, rtas_event_type(rtas_error_type(errlog)),
+   printk(RTAS_DEBUG "event: %d, Type: %s (%d), Severity: %d\n",
+  error_log_cnt,
+  rtas_event_type(rtas_error_type(errlog)),
+  rtas_error_type(errlog),
   rtas_error_severity(errlog));
}
  }





Re: [PATCH] powerpc/topology: Update numa mask when cpu node mapping changes

2018-10-09 Thread Srikar Dronamraju
* Srikar Dronamraju  [2018-10-10 09:54:46]:

> Commit 2ea626306810 ("powerpc/topology: Get topology for shared
> processors at boot") will update the cpu node topology for shared lpars
> on PowerVM.
> 
> However shared lpars on PowerVM also support VPHN and PRRN events.
> On receiving a VPHN, PRRN events, cpu to node mapping might change.
> 
> Scheduler maintains sched_domains_numa_masks[], which is currently not
> updated on cpu to node mapping changes. This can lead to machine
> regressions and performance regressions.

s/regressions and performance regressions./hangs or performance hit./

> 
> Fix numa_update_cpu_topology() to update sched_domains_numa_masks[].
> 

-- 
Thanks and Regards
Srikar Dronamraju



[PATCH] powerpc/rtasd: Improve unknown error logging

2018-10-09 Thread Oliver O'Halloran
Currently when we get an unknown RTAS event it prints the type as
"Unknown" and no other useful information. Add the raw type code to the
log message so that we have something to work off.

Signed-off-by: Oliver O'Halloran 
---
 arch/powerpc/kernel/rtasd.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 44d66c33d59d..6fafc82c04b0 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -150,8 +150,10 @@ static void printk_log_rtas(char *buf, int len)
} else {
struct rtas_error_log *errlog = (struct rtas_error_log *)buf;
 
-   printk(RTAS_DEBUG "event: %d, Type: %s, Severity: %d\n",
-  error_log_cnt, rtas_event_type(rtas_error_type(errlog)),
+   printk(RTAS_DEBUG "event: %d, Type: %s (%d), Severity: %d\n",
+  error_log_cnt,
+  rtas_event_type(rtas_error_type(errlog)),
+  rtas_error_type(errlog),
   rtas_error_severity(errlog));
}
 }
-- 
2.9.5



[PATCH 4/4] powerpc: Add -Wimplicit-fallthrough to arch CFLAGS

2018-10-09 Thread Michael Ellerman
Warn whenever a switch statement has a fallthrough without a comment
annotating it.

Signed-off-by: Michael Ellerman 
---
 arch/powerpc/Kbuild | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/Kbuild b/arch/powerpc/Kbuild
index 86b261d6bde5..ef625f1db576 100644
--- a/arch/powerpc/Kbuild
+++ b/arch/powerpc/Kbuild
@@ -1,4 +1,5 @@
 subdir-ccflags-y := $(call cc-option, -Wvla)
+subdir-ccflags-y += $(call cc-option, -Wimplicit-fallthrough)
 subdir-ccflags-$(CONFIG_PPC_WERROR) += -Werror
 
 obj-y += kernel/
-- 
2.17.1



[PATCH 3/4] powerpc: Add -Wvla to arch CFLAGS

2018-10-09 Thread Michael Ellerman
Upstream has declared that Variable Length Array's (VLAs) are a bad
idea, and eventually -Wvla will be added to the top-level Makefile. We
can go one better and make sure we don't introduce any more by adding
it to the arch Makefile.

Signed-off-by: Michael Ellerman 
---
 arch/powerpc/Kbuild | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/Kbuild b/arch/powerpc/Kbuild
index 1625a06802ca..86b261d6bde5 100644
--- a/arch/powerpc/Kbuild
+++ b/arch/powerpc/Kbuild
@@ -1,4 +1,5 @@
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
+subdir-ccflags-y := $(call cc-option, -Wvla)
+subdir-ccflags-$(CONFIG_PPC_WERROR) += -Werror
 
 obj-y += kernel/
 obj-y += mm/
-- 
2.17.1



[PATCH 2/4] powerpc: Add -Werror at arch/powerpc level

2018-10-09 Thread Michael Ellerman
Back when I added -Werror in commit ba55bd74360e ("powerpc: Add
configurable -Werror for arch/powerpc") I did it by adding it to most
of the arch Makefiles.

At the time we excluded math-emu, because apparently it didn't build
cleanly. But that seems to have been fixed somewhere in the interim.

So move the -Werror addition to the top-level of the arch, this saves
us from repeating it in every Makefile and means we won't forget to
add it to any new sub-dirs.

Signed-off-by: Michael Ellerman 
---
 arch/powerpc/Kbuild| 2 ++
 arch/powerpc/kernel/Makefile   | 2 --
 arch/powerpc/kernel/trace/Makefile | 2 --
 arch/powerpc/kvm/Makefile  | 2 --
 arch/powerpc/lib/Makefile  | 2 --
 arch/powerpc/mm/Makefile   | 2 --
 arch/powerpc/oprofile/Makefile | 1 -
 arch/powerpc/perf/Makefile | 1 -
 arch/powerpc/platforms/Makefile| 2 --
 arch/powerpc/sysdev/Makefile   | 3 ---
 arch/powerpc/sysdev/xics/Makefile  | 1 -
 arch/powerpc/sysdev/xive/Makefile  | 1 -
 arch/powerpc/xmon/Makefile | 2 --
 13 files changed, 2 insertions(+), 21 deletions(-)

diff --git a/arch/powerpc/Kbuild b/arch/powerpc/Kbuild
index 690a498da050..1625a06802ca 100644
--- a/arch/powerpc/Kbuild
+++ b/arch/powerpc/Kbuild
@@ -1,3 +1,5 @@
+subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
+
 obj-y += kernel/
 obj-y += mm/
 obj-y += lib/
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 85ffa488dfb5..006e391814ed 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -5,8 +5,6 @@
 
 CFLAGS_ptrace.o+= -DUTS_MACHINE='"$(UTS_MACHINE)"'
 
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-
 ifdef CONFIG_PPC64
 CFLAGS_prom_init.o += $(NO_MINIMAL_TOC)
 endif
diff --git a/arch/powerpc/kernel/trace/Makefile 
b/arch/powerpc/kernel/trace/Makefile
index d868ba42032f..b1725ad3e13d 100644
--- a/arch/powerpc/kernel/trace/Makefile
+++ b/arch/powerpc/kernel/trace/Makefile
@@ -3,8 +3,6 @@
 # Makefile for the powerpc trace subsystem
 #
 
-subdir-ccflags-$(CONFIG_PPC_WERROR):= -Werror
-
 ifdef CONFIG_FUNCTION_TRACER
 # do not trace tracer code
 CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index f872c04bb5b1..e9d579921a96 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -3,8 +3,6 @@
 # Makefile for Kernel-based Virtual Machine module
 #
 
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-
 ccflags-y := -Ivirt/kvm -Iarch/powerpc/kvm
 KVM := ../../../virt/kvm
 
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 670286808928..703afa1808ed 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -3,8 +3,6 @@
 # Makefile for ppc-specific library files..
 #
 
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-
 ccflags-$(CONFIG_PPC64):= $(NO_MINIMAL_TOC)
 
 CFLAGS_REMOVE_code-patching.o = $(CC_FLAGS_FTRACE)
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index cdf6a9960046..90e103ab44fb 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -3,8 +3,6 @@
 # Makefile for the linux ppc-specific parts of the memory manager.
 #
 
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-
 ccflags-$(CONFIG_PPC64):= $(NO_MINIMAL_TOC)
 
 obj-y  := fault.o mem.o pgtable.o mmap.o \
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index 7a7834c39f64..8d26d7416481 100644
--- a/arch/powerpc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
 
 ccflags-$(CONFIG_PPC64):= $(NO_MINIMAL_TOC)
 
diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index 82986d2acd9b..ab26df5bacb9 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
 
 obj-$(CONFIG_PERF_EVENTS)  += callchain.o perf_regs.o
 
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index e46bb7ea710f..143d4417f6cc 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -1,7 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-
 obj-$(CONFIG_FSL_ULI1575)  += fsl_uli1575.o
 
 obj-$(CONFIG_PPC_PMAC) += powermac/
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index f730539074c4..2caa4defdfb6 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -1,5 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
 
 ccflags-$(CONFIG_PPC64):= $(NO_MINIMAL_TOC)
 
@@ -56,8 +55,6 @@ obj-$(CONFIG_PPC_SCOM)+= scom.o
 
 obj-$(CONFIG_PPC_EARLY_DEBUG_MEMCONS)  += udbg_memcons.o
 
-subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
-
 

[PATCH 1/4] powerpc: Move core kernel logic into arch/powerpc/Kbuild

2018-10-09 Thread Michael Ellerman
This is a nice cleanup, arch/powerpc/Makefile is long and messy so
moving this out helps a little.

It also allows us to do:

  $ make arch/powerpc

Which can be helpful if you just want to compile test some changes to
arch code and not link everything.

Finally it also gives us a single place to do subdir-cc-flags
assignments which affect the whole of arch/powerpc, which we will do
in a future patch.

Signed-off-by: Michael Ellerman 
---
 arch/powerpc/Kbuild   | 14 ++
 arch/powerpc/Makefile | 14 ++
 2 files changed, 16 insertions(+), 12 deletions(-)
 create mode 100644 arch/powerpc/Kbuild

diff --git a/arch/powerpc/Kbuild b/arch/powerpc/Kbuild
new file mode 100644
index ..690a498da050
--- /dev/null
+++ b/arch/powerpc/Kbuild
@@ -0,0 +1,14 @@
+obj-y += kernel/
+obj-y += mm/
+obj-y += lib/
+obj-y += sysdev/
+obj-y += platforms/
+obj-y += math-emu/
+obj-y += crypto/
+obj-y += net/
+
+obj-$(CONFIG_XMON) += xmon/
+obj-$(CONFIG_KVM)  += kvm/
+
+obj-$(CONFIG_PERF_EVENTS) += perf/
+obj-$(CONFIG_KEXEC_FILE)  += purgatory/
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 974103254aed..e623abaa573e 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -269,18 +269,8 @@ head-$(CONFIG_PPC_FPU) += 
arch/powerpc/kernel/fpu.o
 head-$(CONFIG_ALTIVEC) += arch/powerpc/kernel/vector.o
 head-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE)  += arch/powerpc/kernel/prom_init.o
 
-core-y += arch/powerpc/kernel/ \
-  arch/powerpc/mm/ \
-  arch/powerpc/lib/ \
-  arch/powerpc/sysdev/ \
-  arch/powerpc/platforms/ \
-  arch/powerpc/math-emu/ \
-  arch/powerpc/crypto/ \
-  arch/powerpc/net/
-core-$(CONFIG_XMON)+= arch/powerpc/xmon/
-core-$(CONFIG_KVM) += arch/powerpc/kvm/
-core-$(CONFIG_PERF_EVENTS) += arch/powerpc/perf/
-core-$(CONFIG_KEXEC_FILE)  += arch/powerpc/purgatory/
+# See arch/powerpc/Kbuild for content of core part of the kernel
+core-y += arch/powerpc/
 
 drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
 
-- 
2.17.1



Re: [PATCH 21/36] dt-bindings: arm: Convert TI davinci board/soc bindings to json-schema

2018-10-09 Thread Sekhar Nori
On Friday 05 October 2018 10:28 PM, Rob Herring wrote:
> Convert TI Davinci SoC bindings to DT schema format using json-schema.
> 
> Cc: Sekhar Nori 
> Cc: Kevin Hilman 
> Cc: Mark Rutland 
> Cc: devicet...@vger.kernel.org
> Signed-off-by: Rob Herring 
> ---
>  .../devicetree/bindings/arm/davinci.txt   | 25 --
>  .../bindings/arm/ti/ti,davinci.yaml   | 26 +++
>  2 files changed, 26 insertions(+), 25 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/arm/davinci.txt
>  create mode 100644 Documentation/devicetree/bindings/arm/ti/ti,davinci.yaml
> 
> diff --git a/Documentation/devicetree/bindings/arm/davinci.txt 
> b/Documentation/devicetree/bindings/arm/davinci.txt
> deleted file mode 100644
> index 715622c36260..
> --- a/Documentation/devicetree/bindings/arm/davinci.txt
> +++ /dev/null
> @@ -1,25 +0,0 @@
> -Texas Instruments DaVinci Platforms Device Tree Bindings
> -
> -
> -DA850/OMAP-L138/AM18x Evaluation Module (EVM) board
> -Required root node properties:
> -- compatible = "ti,da850-evm", "ti,da850";
> -
> -DA850/OMAP-L138/AM18x L138/C6748 Development Kit (LCDK) board
> -Required root node properties:
> -- compatible = "ti,da850-lcdk", "ti,da850";
> -
> -EnBW AM1808 based CMC board
> -Required root node properties:
> -- compatible = "enbw,cmc", "ti,da850;
> -
> -LEGO MINDSTORMS EV3 (AM1808 based)
> -Required root node properties:
> -- compatible = "lego,ev3", "ti,da850";
> -
> -Generic DaVinci Boards
> ---
> -
> -DA850/OMAP-L138/AM18x generic board
> -Required root node properties:
> -- compatible = "ti,da850";
> diff --git a/Documentation/devicetree/bindings/arm/ti/ti,davinci.yaml 
> b/Documentation/devicetree/bindings/arm/ti/ti,davinci.yaml
> new file mode 100644
> index ..2675cae91a60
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/ti/ti,davinci.yaml
> @@ -0,0 +1,26 @@
> +# SPDX-License-Identifier: None
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/bindings/arm/davinci.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Texas Instruments DaVinci Platforms Device Tree Bindings
> +
> +maintainers:
> +  - Sekhar Nori 
> +description: |
> +  DA850/OMAP-L138/AM18x based boards
> +
> +
> +properties:
> +  $nodename:
> +const: '/'
> +  compatible:
> +items:
> +  - enum:
> +  - ti,da850-evm
> +  - ti,da850-lcdk
> +  - enbw,cmc
> +  - lego,ev3

The boards had some reasonable human readable description earlier, which
has been lost now. Is there a way to bring that back?

Apart from that, looks good to me.

Thanks,
Sekhar

> +  - const: ti,da850
> +...
> -- 
> 2.17.1
> 



[PATCH] powerpc/topology: Update numa mask when cpu node mapping changes

2018-10-09 Thread Srikar Dronamraju
Commit 2ea626306810 ("powerpc/topology: Get topology for shared
processors at boot") will update the cpu node topology for shared lpars
on PowerVM.

However shared lpars on PowerVM also support VPHN and PRRN events.
On receiving a VPHN, PRRN events, cpu to node mapping might change.

Scheduler maintains sched_domains_numa_masks[], which is currently not
updated on cpu to node mapping changes. This can lead to machine
regressions and performance regressions.

Fix numa_update_cpu_topology() to update sched_domains_numa_masks[].

Signed-off-by: Srikar Dronamraju 
---
 arch/powerpc/mm/numa.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 3ea5b05ee6be..bf34384aa314 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1424,6 +1425,19 @@ int numa_update_cpu_topology(bool cpus_locked)
changed = 1;
}
 
+   /*
+* Scheduler maintains a sched_domain_numa_masks table that needs to
+* be updated whenever cpu-node mapping changes. Cpu-node mapping
+* change only with vphn and prrn.
+*/
+   if (!(topology_inited && (vphn_enabled || prrn_enabled)))
+   goto out;
+
+   for_each_cpu(cpu, _cpus) {
+   sched_cpu_deactivate(cpu);
+   sched_cpu_activate(cpu);
+   }
+
 out:
kfree(updates);
topology_update_needed = 0;
-- 
2.12.3



[PATCH 2/2] powerpc/boot: Build boot wrapper with optimisations

2018-10-09 Thread Joel Stanley
The boot wrapper is currently built with -Os. By building with O2 we
can meaningfully reduce the time decompressing the kernel.

I tested by comparing 10 runs of each option in Qemu and on hardware.
The kernel is compressed with KERNEL_XZ built with GCC 8.2.0-7ubuntu1.
The values are counts of the timebase.

Qemu TCG powernv Power8:

  OsO2O3
 median   10221123889   62015184386568186825
 stddev1361267211429090641 657930076
 improvement39.33%35.74%

Palmetto Power8:

  OsO2O3
 median   50279 50599  35790
 stddev   992144533 627130655  623721078
 improvement   36.79% 37.13%

Romulus Power9:

  OsO2O3
 median   670312391 454733720  448881398
 stddev  157569107276 108760
 improvement   32.16% 33.03%

TCG was quite noisy, with every few runs producing an outlier. Even so,
O2 is faster than O3. On hardware the numbers were less noisy and O3 is
slightly faster than O2.

The wrapper size increases when moving from Os. Comparing zImage.epapr
to the existing Os build using bloat-o-meter:

  Before=43401, After=56837 (13KB), chg +30.96%
  Before=43401, After=64305 (20KB), chg +48.16%

I chose O2 for a balance between Qemu and hardware speed up.

Signed-off-by: Joel Stanley 
---
 arch/powerpc/boot/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 739ef8d43b91..c6c5a1a6627d 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -32,7 +32,7 @@ else
 endif
 
 BOOTCFLAGS:= -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
--fno-strict-aliasing -Os -msoft-float -mno-altivec -mno-vsx \
+-fno-strict-aliasing -O2 -msoft-float -mno-altivec -mno-vsx \
 -pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
 -D$(compress-y)
 
-- 
2.17.1



[PATCH 1/2] powerpc/boot: Disable vector instructions

2018-10-09 Thread Joel Stanley
This will avoid auto-vectorisation when building with higher
optimisation levels.

We don't know if the machine can support VSX and even if it's present
it's probably not going to be enabled at this point in boot.

Signed-off-by: Joel Stanley 
---
 arch/powerpc/boot/Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 0fb96c26136f..739ef8d43b91 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -32,8 +32,8 @@ else
 endif
 
 BOOTCFLAGS:= -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
--fno-strict-aliasing -Os -msoft-float -pipe \
--fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
+-fno-strict-aliasing -Os -msoft-float -mno-altivec -mno-vsx \
+-pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
 -D$(compress-y)
 
 ifdef CONFIG_PPC64_BOOT_WRAPPER
-- 
2.17.1



[PATCH 0/2] powerpc/boot: Build wrapper with optimisations

2018-10-09 Thread Joel Stanley
We currently build the wrapper with Os. This builds it with O2 instead,
reducing boot time when decompressing a compressed kernel. See patch
2 for details.

I've given this a spin with CONFIG_KERNEL_XZ on P9 and P8 as the
petitboot kernel.

Joel Stanley (2):
  powerpc/boot: Disable vector instructions
  powerpc/boot: Build boot wrapper with optimisations

 arch/powerpc/boot/Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

-- 
2.17.1



Re: [PATCH 15/36] dt-bindings: arm: Convert Actions Semi bindings to jsonschema

2018-10-09 Thread Joe Perches
On Sat, 2018-10-06 at 12:40 +0200, Andreas Färber wrote:
> > +++ b/Documentation/devicetree/bindings/arm/actions.yaml
[]
> > +
> > +title: Actions Semi platforms device tree bindings
> > +
> > +maintainers:
> > +  - Andreas Färber 
> 
> Mani is now officially reviewer and the closest I have to a
> co-maintainer. I suggest we add him here in some form. I assume this is
> independent of MAINTAINERS patterns though, or will get_maintainers.pl
> parse this, too?

It _could_, if using the get_maintainers --file-emails option.
Ideally, it would be added to the MAINTAINERS somewhere.




Re: [PATCH 05/16] of: overlay: use prop add changeset entry for property in new nodes

2018-10-09 Thread Frank Rowand
On 10/09/18 13:28, Alan Tull wrote:
> On Thu, Oct 4, 2018 at 11:14 PM  wrote:
>>
>> From: Frank Rowand 
>>
> 
> Hi Frank,
> 
>> The changeset entry 'update property' was used for new properties in
>> an overlay instead of 'add property'.
>>
>> The decision of whether to use 'update property' was based on whether
>> the property already exists in the subtree where the node is being
>> spliced into.  At the top level of creating a changeset describing the
>> overlay, the target node is in the live devicetree, so checking whether
>> the property exists in the target node returns the correct result.
>> As soon as the changeset creation algorithm recurses into a new node,
>> the target is no longer in the live devicetree, but is instead in the
>> detached overlay tree, thus all properties are incorrectly found to
>> already exist in the target.
> 
> When I applied an overlay (that added a few gpio controllers, etc),
> the node names for nodes added from the overlay end up NULL.   It

I'll look at this tonight.

-Frank


> seems related to this patch and the next one.  I haven't completely
> root caused this but if I back out to before this patch, the situation
> is fixed.
> 
> root@arria10:~/unit_tests# ls /sys/bus/platform/drivers/altera_gpio/
> bind ff200010.  ff200020.  ff200030.
> uevent   unbind
> 
> root@arria10:~/unit_tests# ls /sys/bus/platform/drivers/altera_freeze_br/
> bind ff200450.  uevent   unbind
> 
> Alan
> 
>>
>> This fix will expose another devicetree bug that will be fixed
>> in the following patch in the series.
>>
>> When this patch is applied the errors reported by the devictree
>> unittest will change, and the unittest results will change from:
>>
>>### dt-test ### end of unittest - 210 passed, 0 failed
>>
>> to
>>
>>### dt-test ### end of unittest - 203 passed, 7 failed
>>
>> Signed-off-by: Frank Rowand 
>> ---
>>  drivers/of/overlay.c | 112 
>> ++-
>>  1 file changed, 74 insertions(+), 38 deletions(-)
>>
>> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
>> index 32cfee68f2e3..0b0904f44bc7 100644
>> --- a/drivers/of/overlay.c
>> +++ b/drivers/of/overlay.c
>> @@ -24,6 +24,26 @@
>>  #include "of_private.h"
>>
>>  /**
>> + * struct target - info about current target node as recursing through 
>> overlay
>> + * @np:node where current level of overlay will be 
>> applied
>> + * @in_livetree:   @np is a node in the live devicetree
>> + *
>> + * Used in the algorithm to create the portion of a changeset that describes
>> + * an overlay fragment, which is a devicetree subtree.  Initially @np is a 
>> node
>> + * in the live devicetree where the overlay subtree is targeted to be 
>> grafted
>> + * into.  When recursing to the next level of the overlay subtree, the 
>> target
>> + * also recurses to the next level of the live devicetree, as long as 
>> overlay
>> + * subtree node also exists in the live devicetree.  When a node in the 
>> overlay
>> + * subtree does not exist at the same level in the live devicetree, 
>> target->np
>> + * points to a newly allocated node, and all subsequent targets in the 
>> subtree
>> + * will be newly allocated nodes.
>> + */
>> +struct target {
>> +   struct device_node *np;
>> +   bool in_livetree;
>> +};
>> +
>> +/**
>>   * struct fragment - info about fragment nodes in overlay expanded device 
>> tree
>>   * @target:target of the overlay operation
>>   * @overlay:   pointer to the __overlay__ node
>> @@ -72,8 +92,7 @@ static int devicetree_corrupt(void)
>>  }
>>
>>  static int build_changeset_next_level(struct overlay_changeset *ovcs,
>> -   struct device_node *target_node,
>> -   const struct device_node *overlay_node);
>> +   struct target *target, const struct device_node 
>> *overlay_node);
>>
>>  /*
>>   * of_resolve_phandles() finds the largest phandle in the live tree.
>> @@ -257,14 +276,17 @@ static struct property *dup_and_fixup_symbol_prop(
>>  /**
>>   * add_changeset_property() - add @overlay_prop to overlay changeset
>>   * @ovcs:  overlay changeset
>> - * @target_node:   where to place @overlay_prop in live tree
>> + * @target:where @overlay_prop will be placed
>>   * @overlay_prop:  property to add or update, from overlay tree
>>   * @is_symbols_prop:   1 if @overlay_prop is from node "/__symbols__"
>>   *
>> - * If @overlay_prop does not already exist in @target_node, add changeset 
>> entry
>> - * to add @overlay_prop in @target_node, else add changeset entry to update
>> + * If @overlay_prop does not already exist in live devicetree, add changeset
>> + * entry to add @overlay_prop in @target, else add changeset entry to update
>>   * value of @overlay_prop.
>>   *
>> + * @target may be either in the live devicetree or in a new subtree that
>> + * is contained in the changeset.
>> + *
>>   * Some special properties are not 

[PATCH 2/2] powerpc/boot: Fix opal console in boot wrapper

2018-10-09 Thread Joel Stanley
As of commit 10c77dba40ff ("powerpc/boot: Fix build failure in 32-bit
boot wrapper") the opal code is hidden behind CONFIG_PPC64_BOOT_WRAPPER,
but the boot wrapper avoids include/linux, so it does not get the normal
Kconfig flags.

We can drop the guard entirely as in commit f8e8e69cea49 ("powerpc/boot:
Only build OPAL code when necessary") the makefile only includes opal.c
in the build if CONFIG_PPC64_BOOT_WRAPPER is set.

Fixes: 10c77dba40ff ("powerpc/boot: Fix build failure in 32-bit boot wrapper")
Signed-off-by: Joel Stanley 
---
I wrote this patch before the kconfig one. We could use autoconf.h, or
fold this in, but I think the clean up of the redundant ifdef is cleaner.

 arch/powerpc/boot/opal.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/arch/powerpc/boot/opal.c b/arch/powerpc/boot/opal.c
index 0272570d02de..dfb199ef5b94 100644
--- a/arch/powerpc/boot/opal.c
+++ b/arch/powerpc/boot/opal.c
@@ -13,8 +13,6 @@
 #include 
 #include "../include/asm/opal-api.h"
 
-#ifdef CONFIG_PPC64_BOOT_WRAPPER
-
 /* Global OPAL struct used by opal-call.S */
 struct opal {
u64 base;
@@ -101,9 +99,3 @@ int opal_console_init(void *devp, struct serial_console_data 
*scdp)
 
return 0;
 }
-#else
-int opal_console_init(void *devp, struct serial_console_data *scdp)
-{
-   return -1;
-}
-#endif /* __powerpc64__ */
-- 
2.17.1



[PATCH 1/2] powerpc/boot: Expose Kconfig symbols to wrapper

2018-10-09 Thread Joel Stanley
Currently the wrapper is built without including anything in
$(src)/include/, which means there are no CONFIG_ symbols defined. This
means the platform specific serial drivers were never enabled.

We now copy the definitions into the boot directory, so any C file can
now include autoconf.h to depend on configuration options.

Fixes: 866bfc75f40e ("powerpc: conditionally compile platform-specific serial 
drivers")
Signed-off-by: Joel Stanley 
---
 arch/powerpc/boot/.gitignore | 1 +
 arch/powerpc/boot/Makefile   | 7 ++-
 arch/powerpc/boot/serial.c   | 1 +
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/boot/.gitignore b/arch/powerpc/boot/.gitignore
index f92d0530ceb1..32034a0cc554 100644
--- a/arch/powerpc/boot/.gitignore
+++ b/arch/powerpc/boot/.gitignore
@@ -44,4 +44,5 @@ fdt_sw.c
 fdt_wip.c
 libfdt.h
 libfdt_internal.h
+autoconf.h
 
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 0fb96c26136f..eeed74e0dfca 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -197,9 +197,14 @@ $(obj)/empty.c:
 $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S
$(Q)cp $< $@
 
+$(obj)/serial.c: $(obj)/autoconf.h
+
+$(obj)/autoconf.h: $(obj)/%: $(srctree)/include/generated/%
+   $(Q)cp $< $@
+
 clean-files := $(zlib-) $(zlibheader-) $(zliblinuxheader-) \
$(zlib-decomp-) $(libfdt) $(libfdtheader) \
-   empty.c zImage.coff.lds zImage.ps3.lds zImage.lds
+   autoconf.h empty.c zImage.coff.lds zImage.ps3.lds zImage.lds
 
 quiet_cmd_bootcc = BOOTCC  $@
   cmd_bootcc = $(BOOTCC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c
index 48e3743faedf..f045f8494bf9 100644
--- a/arch/powerpc/boot/serial.c
+++ b/arch/powerpc/boot/serial.c
@@ -18,6 +18,7 @@
 #include "stdio.h"
 #include "io.h"
 #include "ops.h"
+#include "autoconf.h"
 
 static int serial_open(void)
 {
-- 
2.17.1



[PATCH 0/2] powerpc/boot: Fix serial output in boot wrapper

2018-10-09 Thread Joel Stanley
While doing some work on the wrapper I noticed we no longer get serial
output on a powernv system. This is because we compile out the opal
code.

As it turns out, none of the system-specific serial outputs will be
compiled in. This series fixes that. Tested on Qemu powernv, Romulus and
Palmetto.

Joel Stanley (2):
  powerpc/boot: Expose Kconfig symbols to wrapper
  powerpc/boot: Fix opal console in boot wrapper

 arch/powerpc/boot/.gitignore | 1 +
 arch/powerpc/boot/Makefile   | 7 ++-
 arch/powerpc/boot/opal.c | 8 
 arch/powerpc/boot/serial.c   | 1 +
 4 files changed, 8 insertions(+), 9 deletions(-)

-- 
2.17.1



Re: [PATCH] memblock: stop using implicit alignement to SMP_CACHE_BYTES

2018-10-09 Thread Paul Burton
Hi Mike,

On Fri, Oct 05, 2018 at 12:07:04AM +0300, Mike Rapoport wrote:
> When a memblock allocation APIs are called with align = 0, the alignment is
> implicitly set to SMP_CACHE_BYTES.
> 
> Replace all such uses of memblock APIs with the 'align' parameter explicitly
> set to SMP_CACHE_BYTES and stop implicit alignment assignment in the
> memblock internal allocation functions.
> 
>%
> 
> Suggested-by: Michal Hocko 
> Signed-off-by: Mike Rapoport 

  Acked-by: Paul Burton  # MIPS part

Thanks,
Paul


[PATCH v04 4/4] migration/memory: Support 'ibm,dynamic-memory-v2'

2018-10-09 Thread Michael Bringmann
migration/memory: This patch adds recognition for changes to the
associativity of memory blocks described by 'ibm,dynamic-memory-v2'.
If the associativity of an LMB has changed, it should be readded to
the system in order to update local and general kernel data structures.
This patch builds upon previous enhancements that scan the device-tree
"ibm,dynamic-memory" properties using the base LMB array, and a copy
derived from the updated properties.

Signed-off-by: Michael Bringmann 
---
 arch/powerpc/platforms/pseries/hotplug-memory.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c 
b/arch/powerpc/platforms/pseries/hotplug-memory.c
index a7ca22e..233ef02 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -1180,7 +1180,8 @@ static int pseries_memory_notifier(struct notifier_block 
*nb,
err = pseries_remove_mem_node(rd->dn);
break;
case OF_RECONFIG_UPDATE_PROPERTY:
-   if (!strcmp(rd->prop->name, "ibm,dynamic-memory")) {
+   if (!strcmp(rd->prop->name, "ibm,dynamic-memory") ||
+   !strcmp(rd->prop->name, "ibm,dynamic-memory-v2")) {
struct drmem_lmb_info *dinfo =
drmem_lmbs_init(rd->prop);
if (!dinfo)



[PATCH v04 3/4] migration/memory: Evaluate LMB assoc changes

2018-10-09 Thread Michael Bringmann
migration/memory: This patch adds code that recognizes changes to
the associativity of memory blocks described by the device-tree
properties in order to drive equivalent 'hotplug' operations to
update local and general kernel data structures to reflect those
changes.  These differences may include:

* Evaluate 'ibm,dynamic-memory' properties when processing the
  updated device-tree properties of the system during Post Migration
  events (migration_store).  The new functionality looks for changes
  to the aa_index values for each drc_index/LMB to identify any memory
  blocks that should be readded.

* In an LPAR migration scenario, the "ibm,associativity-lookup-arrays"
  property may change.  In the event that a row of the array differs,
  locate all assigned memory blocks with that 'aa_index' and 're-add'
  them to the system memory block data structures.  In the process of
  the 're-add', the system routines will update the corresponding entry
  for the memory in the LMB structures and any other relevant kernel
  data structures.

A number of previous extensions made to the DRMEM code for scanning
device-tree properties and creating LMB arrays are used here to
ensure that the resulting code is simpler and more usable:

* Use new paired list iterator for the DRMEM LMB info arrays to find
  differences in old and new versions of properties.
* Use new iterator for copies of the DRMEM info arrays to evaluate
  completely new structures.
* Combine common code for parsing and evaluating memory description
  properties based on the DRMEM LMB array model to greatly simplify
  extension from the older property 'ibm,dynamic-memory' to the new
  property model of 'ibm,dynamic-memory-v2'.

For support, add a new pseries hotplug action for DLPAR operations,
PSERIES_HP_ELOG_ACTION_READD_MULTIPLE.  It is a variant of the READD
operation which performs the action upon multiple instances of the
resource at one time.  The operation is to be triggered by device-tree
analysis of updates by RTAS events analyzed by 'migation_store' during
post-migration processing.  It will be used for memory updates,
initially.

Signed-off-by: Michael Bringmann 
---
Changes in v04:
  -- Move dlpar_memory_readd_multiple() function definition and use
 into previous patch along with action constant definition.
  -- Correct spacing in patch
Changes in v03:
  -- Modify the code that parses the memory affinity attributes to
 mark relevant DRMEM LMB array entries using the internal_flags
 mechanism instead of generate unique hotplug actions for each
 memory block to be readded.  The change is intended to both
 simplify the code, and to require fewer resources on systems
 with huge amounts of memory.
  -- Save up notice about any all LMB entries until the end of the
 'migration_store' operation at which point a single action is
 queued to scan the entire DRMEM array.
  -- Add READD_MULTIPLE function for memory that scans the DRMEM
 array to identify multiple entries that were marked previously.
 The corresponding memory blocks are to be readded to the system
 to update relevant data structures outside of the powerpc-
 specific code.
  -- Change dlpar_memory_pmt_changes_action to directly queue worker
 to pseries work queue.
---
 arch/powerpc/platforms/pseries/hotplug-memory.c |  189 +++
 arch/powerpc/platforms/pseries/mobility.c   |4 
 arch/powerpc/platforms/pseries/pseries.h|4 
 3 files changed, 163 insertions(+), 34 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c 
b/arch/powerpc/platforms/pseries/hotplug-memory.c
index bf2420a..a7ca22e 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -534,8 +534,11 @@ static int dlpar_memory_readd_by_index(u32 drc_index)
}
}
 
-   if (!lmb_found)
-   rc = -EINVAL;
+   if (!lmb_found) {
+   pr_info("Failed to update memory for drc index %lx\n",
+   (unsigned long) drc_index);
+   return -EINVAL;
+   }
 
if (rc)
pr_info("Failed to update memory at %llx\n",
@@ -1002,13 +1005,43 @@ static int pseries_add_mem_node(struct device_node *np)
return (ret < 0) ? -EINVAL : 0;
 }
 
-static int pseries_update_drconf_memory(struct of_reconfig_data *pr)
+static int pmt_changes = 0;
+
+void dlpar_memory_pmt_changes_set(void)
+{
+   pmt_changes = 1;
+}
+
+void dlpar_memory_pmt_changes_clear(void)
+{
+   pmt_changes = 0;
+}
+
+int dlpar_memory_pmt_changes(void)
+{
+   return pmt_changes;
+}
+
+void dlpar_memory_pmt_changes_action(void)
+{
+   if (dlpar_memory_pmt_changes()) {
+   struct pseries_hp_errorlog hp_errlog;
+
+   hp_errlog.resource = PSERIES_HP_ELOG_RESOURCE_MEM;
+   hp_errlog.action = PSERIES_HP_ELOG_ACTION_READD_MULTIPLE;
+   hp_errlog.id_type = 0;
+

[PATCH v04 3/5] migration/memory: Add hotplug READD_MULTIPLE

2018-10-09 Thread Michael Bringmann
migration/memory: This patch adds a new pseries hotplug action
for CPU and memory operations, PSERIES_HP_ELOG_ACTION_READD_MULTIPLE.
This is a variant of the READD operation which performs the action
upon multiple instances of the resource at one time.  The operation
is to be triggered by device-tree analysis of updates by RTAS events
analyzed by 'migation_store' during post-migration processing.  It
will be used for memory updates, initially.

Signed-off-by: Michael Bringmann 
---
Changes in v04:
  -- Move init of 'lmb->internal_flags' in init_drmem_v2_lmbs to
 previous patch.
  -- Pull in implementation of dlpar_memory_readd_multiple() to go
 with operation flag.
---
 arch/powerpc/include/asm/rtas.h |1 +
 arch/powerpc/platforms/pseries/hotplug-memory.c |   31 +++
 2 files changed, 32 insertions(+)

diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 0183e95..cc00451 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -333,6 +333,7 @@ struct pseries_hp_errorlog {
 #define PSERIES_HP_ELOG_ACTION_ADD 1
 #define PSERIES_HP_ELOG_ACTION_REMOVE  2
 #define PSERIES_HP_ELOG_ACTION_READD   3
+#define PSERIES_HP_ELOG_ACTION_READD_MULTIPLE  4
 
 #define PSERIES_HP_ELOG_ID_DRC_NAME1
 #define PSERIES_HP_ELOG_ID_DRC_INDEX   2
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c 
b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 9a15d39..bf2420a 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -546,6 +546,30 @@ static int dlpar_memory_readd_by_index(u32 drc_index)
return rc;
 }
 
+static int dlpar_memory_readd_multiple(void)
+{
+   struct drmem_lmb *lmb;
+   int rc;
+
+   pr_info("Attempting to update multiple LMBs\n");
+
+   for_each_drmem_lmb(lmb) {
+   if (drmem_lmb_update(lmb)) {
+   rc = dlpar_remove_lmb(lmb);
+
+   if (!rc) {
+   rc = dlpar_add_lmb(lmb);
+   if (rc)
+   dlpar_release_drc(lmb->drc_index);
+   }
+
+   drmem_remove_lmb_update(lmb);
+   }
+   }
+
+   return rc;
+}
+
 static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index)
 {
struct drmem_lmb *lmb, *start_lmb, *end_lmb;
@@ -646,6 +670,10 @@ static int dlpar_memory_readd_by_index(u32 drc_index)
 {
return -EOPNOTSUPP;
 }
+static int dlpar_memory_readd_multiple(void)
+{
+   return -EOPNOTSUPP;
+}
 
 static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index)
 {
@@ -923,6 +951,9 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
drc_index = hp_elog->_drc_u.drc_index;
rc = dlpar_memory_readd_by_index(drc_index);
break;
+   case PSERIES_HP_ELOG_ACTION_READD_MULTIPLE:
+   rc = dlpar_memory_readd_multiple();
+   break;
default:
pr_err("Invalid action (%d) specified\n", hp_elog->action);
rc = -EINVAL;



[PATCH v04 2/5] powerpc/drmem: Add internal_flags feature

2018-10-09 Thread Michael Bringmann
powerpc/drmem: Add internal_flags field to each LMB to allow
marking of kernel software-specific operations that need not
be exported to other users.  For instance, if information about
selected LMBs needs to be maintained for subsequent passes
through the system, it can be encoded into the LMB array itself
without requiring the allocation and maintainance of additional
data structures.

Signed-off-by: Michael Bringmann 
---
Changes in v04:
  -- Add another initialization of 'lmb->internal_flags' to
 init_drmem_v2_lmbs.
---
 arch/powerpc/include/asm/drmem.h |   18 ++
 arch/powerpc/mm/drmem.c  |3 +++
 2 files changed, 21 insertions(+)

diff --git a/arch/powerpc/include/asm/drmem.h b/arch/powerpc/include/asm/drmem.h
index 1fbb684..6c5df92 100644
--- a/arch/powerpc/include/asm/drmem.h
+++ b/arch/powerpc/include/asm/drmem.h
@@ -17,6 +17,7 @@ struct drmem_lmb {
u32 drc_index;
u32 aa_index;
u32 flags;
+   u32 internal_flags;
 };
 
 struct drmem_lmb_info {
@@ -101,6 +102,23 @@ static inline bool drmem_lmb_reserved(struct drmem_lmb 
*lmb)
return lmb->flags & DRMEM_LMB_RESERVED;
 }
 
+#define DRMEM_LMBINT_UPDATE0x0001
+
+static inline void drmem_mark_lmb_update(struct drmem_lmb *lmb)
+{
+   lmb->internal_flags |= DRMEM_LMBINT_UPDATE;
+}
+
+static inline void drmem_remove_lmb_update(struct drmem_lmb *lmb)
+{
+   lmb->internal_flags &= ~DRMEM_LMBINT_UPDATE;
+}
+
+static inline bool drmem_lmb_update(struct drmem_lmb *lmb)
+{
+   return lmb->internal_flags & DRMEM_LMBINT_UPDATE;
+}
+
 u64 drmem_lmb_memory_max(void);
 void __init walk_drmem_lmbs(struct device_node *dn,
void (*func)(struct drmem_lmb *, const __be32 **));
diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c
index 13d2abb..2228586 100644
--- a/arch/powerpc/mm/drmem.c
+++ b/arch/powerpc/mm/drmem.c
@@ -207,6 +207,7 @@ static void read_drconf_v1_cell(struct drmem_lmb *lmb,
 
lmb->aa_index = of_read_number(p++, 1);
lmb->flags = of_read_number(p++, 1);
+   lmb->internal_flags = 0;
 
*prop = p;
 }
@@ -265,6 +266,7 @@ static void __walk_drmem_v2_lmbs(const __be32 *prop, const 
__be32 *usm,
 
lmb.aa_index = dr_cell.aa_index;
lmb.flags = dr_cell.flags;
+   lmb.internal_flags = 0;
 
func(, );
}
@@ -420,6 +422,7 @@ static void init_drmem_v2_lmbs(const __be32 *prop,
 
lmb->aa_index = dr_cell.aa_index;
lmb->flags = dr_cell.flags;
+   lmb->internal_flags = 0;
}
}
 }



[PATCH v04 1/5] powerpc/drmem: Export 'dynamic-memory' loader

2018-10-09 Thread Michael Bringmann
powerpc/drmem: Export many of the functions of DRMEM to parse
"ibm,dynamic-memory" and "ibm,dynamic-memory-v2" during hotplug
operations and for Post Migration events.

Also modify the DRMEM initialization code to allow it to,

* Be called after system initialization
* Provide a separate user copy of the LMB array that is produces
* Free the user copy upon request

In addition, a couple of changes were made to make the creation
of additional copies of the LMB array more useful including,

* Add new iterator to work through a pair of drmem_info arrays.
* Modify DRMEM code to replace usages of dt_root_addr_cells, and
  dt_mem_next_cell, as these are only available at first boot.

Signed-off-by: Michael Bringmann 
---
 arch/powerpc/include/asm/drmem.h |   15 
 arch/powerpc/mm/drmem.c  |   75 --
 2 files changed, 70 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/include/asm/drmem.h b/arch/powerpc/include/asm/drmem.h
index 7c1d8e7..1fbb684 100644
--- a/arch/powerpc/include/asm/drmem.h
+++ b/arch/powerpc/include/asm/drmem.h
@@ -35,6 +35,18 @@ struct drmem_lmb_info {
_info->lmbs[0],   \
_info->lmbs[drmem_info->n_lmbs - 1])
 
+#define for_each_dinfo_lmb(dinfo, lmb) \
+   for_each_drmem_lmb_in_range((lmb),  \
+   >lmbs[0],\
+   >lmbs[dinfo->n_lmbs - 1])
+
+#define for_each_pair_dinfo_lmb(dinfo1, lmb1, dinfo2, lmb2)\
+   for ((lmb1) = (>lmbs[0]),   \
+(lmb2) = (>lmbs[0]);   \
+((lmb1) <= (>lmbs[dinfo1->n_lmbs - 1])) && \
+((lmb2) <= (>lmbs[dinfo2->n_lmbs - 1]));   \
+(lmb1)++, (lmb2)++)
+
 /*
  * The of_drconf_cell_v1 struct defines the layout of the LMB data
  * specified in the ibm,dynamic-memory device tree property.
@@ -94,6 +106,9 @@ void __init walk_drmem_lmbs(struct device_node *dn,
void (*func)(struct drmem_lmb *, const __be32 **));
 int drmem_update_dt(void);
 
+struct drmem_lmb_info *drmem_lmbs_init(struct property *prop);
+void drmem_lmbs_free(struct drmem_lmb_info *dinfo);
+
 #ifdef CONFIG_PPC_PSERIES
 void __init walk_drmem_lmbs_early(unsigned long node,
void (*func)(struct drmem_lmb *, const __be32 **));
diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c
index 3f18036..13d2abb 100644
--- a/arch/powerpc/mm/drmem.c
+++ b/arch/powerpc/mm/drmem.c
@@ -20,6 +20,7 @@
 
 static struct drmem_lmb_info __drmem_info;
 struct drmem_lmb_info *drmem_info = &__drmem_info;
+static int n_root_addr_cells;
 
 u64 drmem_lmb_memory_max(void)
 {
@@ -193,12 +194,13 @@ int drmem_update_dt(void)
return rc;
 }
 
-static void __init read_drconf_v1_cell(struct drmem_lmb *lmb,
+static void read_drconf_v1_cell(struct drmem_lmb *lmb,
   const __be32 **prop)
 {
const __be32 *p = *prop;
 
-   lmb->base_addr = dt_mem_next_cell(dt_root_addr_cells, );
+   lmb->base_addr = of_read_number(p, n_root_addr_cells);
+   p += n_root_addr_cells;
lmb->drc_index = of_read_number(p++, 1);
 
p++; /* skip reserved field */
@@ -209,7 +211,7 @@ static void __init read_drconf_v1_cell(struct drmem_lmb 
*lmb,
*prop = p;
 }
 
-static void __init __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm,
+static void __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm,
void (*func)(struct drmem_lmb *, const __be32 **))
 {
struct drmem_lmb lmb;
@@ -225,13 +227,14 @@ static void __init __walk_drmem_v1_lmbs(const __be32 
*prop, const __be32 *usm,
}
 }
 
-static void __init read_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell,
+static void read_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell,
   const __be32 **prop)
 {
const __be32 *p = *prop;
 
dr_cell->seq_lmbs = of_read_number(p++, 1);
-   dr_cell->base_addr = dt_mem_next_cell(dt_root_addr_cells, );
+   dr_cell->base_addr = of_read_number(p, n_root_addr_cells);
+   p += n_root_addr_cells;
dr_cell->drc_index = of_read_number(p++, 1);
dr_cell->aa_index = of_read_number(p++, 1);
dr_cell->flags = of_read_number(p++, 1);
@@ -239,7 +242,7 @@ static void __init read_drconf_v2_cell(struct 
of_drconf_cell_v2 *dr_cell,
*prop = p;
 }
 
-static void __init __walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm,
+static void __walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm,
void (*func)(struct drmem_lmb *, const __be32 **))
 {
struct of_drconf_cell_v2 dr_cell;
@@ -275,6 +278,9 @@ void __init walk_drmem_lmbs_early(unsigned long node,
const __be32 *prop, *usm;
int len;
 
+   if (n_root_addr_cells == 0)
+   n_root_addr_cells = dt_root_addr_cells;

[PATCH v04 0/5] powerpc/migration: Affinity fix for memory

2018-10-09 Thread Michael Bringmann
The migration of LPARs across Power systems affects many attributes
including that of the associativity of memory blocks.  The patches
in this set execute when a system is coming up fresh upon a migration
target.  They are intended to,

* Recognize changes to the associativity of memory recorded in
  internal data structures when compared to the latest copies in
  the device tree (e.g. ibm,dynamic-memory, ibm,dynamic-memory-v2).
* Recognize changes to the associativity mapping (e.g. ibm,
  associativity-lookup-arrays), locate all assigned memory blocks
  corresponding to each changed row, and readd all such blocks.
* Generate calls to other code layers to reset the data structures
  related to associativity of memory.
* Re-register the 'changed' entities into the target system.
  Re-registration of memory blocks mostly entails acting as if they
  have been newly hot-added into the target system.

This code builds upon features introduced in a previous patch set
that updates CPUs for affinity changes that may occur during LPM.

Signed-off-by: Michael Bringmann 

Michael Bringmann (5):
  powerpc/drmem: Export 'dynamic-memory' loader
  powerpc/drmem: Add internal_flags feature
  migration/memory: Add hotplug flags READD_MULTIPLE
  migration/memory: Evaluate LMB assoc changes
  migration/memory: Support 'ibm,dynamic-memory-v2'
---
Changes in v04:
  -- Move dlpar_memory_readd_multiple() to patch with new ACTION
 constant.
  -- Move init of 'lmb->internal_flags' in init_drmem_v2_lmbs to
 patch with other references to flag.
  -- Correct spacing in one of the patches
Changes in v03:
  -- Change operation to tag changed LMBs in DRMEM array instead of
 queuing a potentially huge number of structures.
  -- Added another hotplug queue event for CPU/memory operations
  -- Added internal_flags feature to DRMEM
  -- Improve the patch description language for the patch set.
  -- Revise patch set to queue worker for memory association
 updates directly to pseries worker queue.



Re: [PATCH 05/16] of: overlay: use prop add changeset entry for property in new nodes

2018-10-09 Thread Alan Tull
On Thu, Oct 4, 2018 at 11:14 PM  wrote:
>
> From: Frank Rowand 
>

Hi Frank,

> The changeset entry 'update property' was used for new properties in
> an overlay instead of 'add property'.
>
> The decision of whether to use 'update property' was based on whether
> the property already exists in the subtree where the node is being
> spliced into.  At the top level of creating a changeset describing the
> overlay, the target node is in the live devicetree, so checking whether
> the property exists in the target node returns the correct result.
> As soon as the changeset creation algorithm recurses into a new node,
> the target is no longer in the live devicetree, but is instead in the
> detached overlay tree, thus all properties are incorrectly found to
> already exist in the target.

When I applied an overlay (that added a few gpio controllers, etc),
the node names for nodes added from the overlay end up NULL.   It
seems related to this patch and the next one.  I haven't completely
root caused this but if I back out to before this patch, the situation
is fixed.

root@arria10:~/unit_tests# ls /sys/bus/platform/drivers/altera_gpio/
bind ff200010.  ff200020.  ff200030.
uevent   unbind

root@arria10:~/unit_tests# ls /sys/bus/platform/drivers/altera_freeze_br/
bind ff200450.  uevent   unbind

Alan

>
> This fix will expose another devicetree bug that will be fixed
> in the following patch in the series.
>
> When this patch is applied the errors reported by the devictree
> unittest will change, and the unittest results will change from:
>
>### dt-test ### end of unittest - 210 passed, 0 failed
>
> to
>
>### dt-test ### end of unittest - 203 passed, 7 failed
>
> Signed-off-by: Frank Rowand 
> ---
>  drivers/of/overlay.c | 112 
> ++-
>  1 file changed, 74 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
> index 32cfee68f2e3..0b0904f44bc7 100644
> --- a/drivers/of/overlay.c
> +++ b/drivers/of/overlay.c
> @@ -24,6 +24,26 @@
>  #include "of_private.h"
>
>  /**
> + * struct target - info about current target node as recursing through 
> overlay
> + * @np:node where current level of overlay will be 
> applied
> + * @in_livetree:   @np is a node in the live devicetree
> + *
> + * Used in the algorithm to create the portion of a changeset that describes
> + * an overlay fragment, which is a devicetree subtree.  Initially @np is a 
> node
> + * in the live devicetree where the overlay subtree is targeted to be grafted
> + * into.  When recursing to the next level of the overlay subtree, the target
> + * also recurses to the next level of the live devicetree, as long as overlay
> + * subtree node also exists in the live devicetree.  When a node in the 
> overlay
> + * subtree does not exist at the same level in the live devicetree, 
> target->np
> + * points to a newly allocated node, and all subsequent targets in the 
> subtree
> + * will be newly allocated nodes.
> + */
> +struct target {
> +   struct device_node *np;
> +   bool in_livetree;
> +};
> +
> +/**
>   * struct fragment - info about fragment nodes in overlay expanded device 
> tree
>   * @target:target of the overlay operation
>   * @overlay:   pointer to the __overlay__ node
> @@ -72,8 +92,7 @@ static int devicetree_corrupt(void)
>  }
>
>  static int build_changeset_next_level(struct overlay_changeset *ovcs,
> -   struct device_node *target_node,
> -   const struct device_node *overlay_node);
> +   struct target *target, const struct device_node 
> *overlay_node);
>
>  /*
>   * of_resolve_phandles() finds the largest phandle in the live tree.
> @@ -257,14 +276,17 @@ static struct property *dup_and_fixup_symbol_prop(
>  /**
>   * add_changeset_property() - add @overlay_prop to overlay changeset
>   * @ovcs:  overlay changeset
> - * @target_node:   where to place @overlay_prop in live tree
> + * @target:where @overlay_prop will be placed
>   * @overlay_prop:  property to add or update, from overlay tree
>   * @is_symbols_prop:   1 if @overlay_prop is from node "/__symbols__"
>   *
> - * If @overlay_prop does not already exist in @target_node, add changeset 
> entry
> - * to add @overlay_prop in @target_node, else add changeset entry to update
> + * If @overlay_prop does not already exist in live devicetree, add changeset
> + * entry to add @overlay_prop in @target, else add changeset entry to update
>   * value of @overlay_prop.
>   *
> + * @target may be either in the live devicetree or in a new subtree that
> + * is contained in the changeset.
> + *
>   * Some special properties are not updated (no error returned).
>   *
>   * Update of property in symbols node is not allowed.
> @@ -273,20 +295,22 @@ static struct property *dup_and_fixup_symbol_prop(
>   * invalid @overlay.
>   */
>  static int 

[PATCH v02] powerpc/mobility: Extend start/stop topology update scope

2018-10-09 Thread Michael Bringmann
The PPC mobility code may receive RTAS requests to perform PRRN
topology changes at any time, including during LPAR migration
operations.  In some configurations where the affinity of CPUs
or memory is being changed on that platform, the PRRN requests
may apply or refer to outdated information prior to the complete
update of the device-tree.  This patch changes the duration for
which topology updates are suppressed during LPAR migrations from
just the rtas_ibm_suspend_me / 'ibm,suspend-me' call(s) to cover
the entire 'migration_store' operation to allow all changes to
the device-tree to be applied prior to accepting and applying any
PRRN requests.

For tracking purposes, pr_info notices are added to the functions
start_topology_update() and stop_topology_update() of 'numa.c'.

Signed-off-by: Michael Bringmann 
---
Changes in v02:
  -- Rebase to latest powerpc next tree.
---
 arch/powerpc/kernel/rtas.c|2 --
 arch/powerpc/mm/numa.c|6 ++
 arch/powerpc/platforms/pseries/mobility.c |5 +
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 2c7ed31..e02ac37 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -982,7 +982,6 @@ int rtas_ibm_suspend_me(u64 handle)
}
 
cpu_hotplug_disable();
-   stop_topology_update();
 
/* Call function on all CPUs.  One of us will make the
 * rtas call
@@ -995,7 +994,6 @@ int rtas_ibm_suspend_me(u64 handle)
if (atomic_read() != 0)
printk(KERN_ERR "Error doing global join\n");
 
-   start_topology_update();
cpu_hotplug_enable();
 
/* Take down CPUs not online prior to suspend */
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index b5a71ba..0ade0a1 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1518,6 +1518,10 @@ int start_topology_update(void)
}
}
 
+   pr_info("Starting topology update%s%s\n",
+   (prrn_enabled ? " prrn_enabled" : ""),
+   (vphn_enabled ? " vphn_enabled" : ""));
+
return rc;
 }
 
@@ -1539,6 +1543,8 @@ int stop_topology_update(void)
rc = del_timer_sync(_timer);
}
 
+   pr_info("Stopping topology update\n");
+
return rc;
 }
 
diff --git a/arch/powerpc/platforms/pseries/mobility.c 
b/arch/powerpc/platforms/pseries/mobility.c
index 2f0f512..7da222d 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -367,6 +367,8 @@ static ssize_t migration_store(struct class *class,
if (rc)
return rc;
 
+   stop_topology_update();
+
do {
rc = rtas_ibm_suspend_me(streamid);
if (rc == -EAGAIN)
@@ -377,6 +379,9 @@ static ssize_t migration_store(struct class *class,
return rc;
 
post_mobility_fixup();
+
+   start_topology_update();
+
return count;
 }
 



Re: [PATCH 09/16] of: overlay: validate overlay properties #address-cells and #size-cells

2018-10-09 Thread Alan Tull
On Mon, Oct 8, 2018 at 7:02 PM Frank Rowand  wrote:
>
> On 10/08/18 11:46, Alan Tull wrote:
> > On Mon, Oct 8, 2018 at 10:57 AM Alan Tull  wrote:
> >>
> >> On Thu, Oct 4, 2018 at 11:14 PM  wrote:
> >>>
> >>> From: Frank Rowand 
> >>>
> >>> If overlay properties #address-cells or #size-cells are already in
> >>> the live devicetree for any given node, then the values in the
> >>> overlay must match the values in the live tree.
> >>
> >> Hi Frank,
> >>
> >> I'm starting some FPGA testing on this patchset applied to v4.19-rc7.
> >> That applied cleanly; if that's not the best base to test against,
> >> please let me know.
>
> I would expect -rc7 to be ok to test against.  I'm doing the development
> of it on -rc1.
>
> Thanks for the testing.
>

I'll try to be quick about it, but I expect it will take a few days to
hit everything and explain it here.

>
> >> On a very simple overlay, I'm seeing this patch's warning catching
> >> things other than #address-cells or #size-cells.
>
> #address-cells and #size-cells escape the warning for properties on an
> existing (non-overlay) node if the existing node already contains them
> as a special case.  Those two properties are needed in the overlay to
> avoid dtc compiler warnings.  If the same properties already exist in
> the base devicetree and have the same values as in the overlay then
> there is no need to add property update changeset entries in the overlay
> changeset.  Since there will not be changeset entries for those two
> properties, there will be no memory leak when the changeset is removed.
>
> The special casing of #address-cells and #size-cells is part of the
> fix patches that are a result of the validation patches.  Thus a little
> bit less memory leaking than we have today.

Makes sense.  Thanks for the explanation.

>
>
> > What it's warning about are new properties being added to an existing
> > node.  So !prop is true and !of_node_check_flag(target->np,
> > OF_OVERLAY) also is true.  Is that a potential memory leak as you are
> > warning?  If so, your code is working as planned and you'll just need
> > to document that also in the header.
>
> Yes, you are accurately describing what the check is catching.
>
> The memory leak (on release) is because the memory allocated for overlay
> properties is released when the reference count of the node they are
> attached is decremented to zero, but only if the node is a dynamic flagged
> node (as overlays are).  The memory allocated for the overlay properties
> will not be freed in this case because the node is not a dynamic node.
>
>
> >> I'm just getting
> >> started looking at this, will spend time understanding this better and
> >> I'll test other overlays.  The warnings were:
> >>
> >> Applying dtbo: socfpga_overlay.dtb
> >> [   33.117881] fpga_manager fpga0: writing soc_system.rbf to Altera
> >> SOCFPGA FPGA Manager
> >> [   33.575223] OF: overlay: WARNING: add_changeset_property(), memory
> >> leak will occur if overlay removed.  Property:
> >> /soc/base-fpga-region/firmware-name
> >> [   33.588584] OF: overlay: WARNING: add_changeset_property(), memory
> >> leak will occur if overlay removed.  Property:
> >> /soc/base-fpga-region/fpga-bridges
> >> [   33.601856] OF: overlay: WARNING: add_changeset_property(), memory
> >> leak will occur if overlay removed.  Property:
> >> /soc/base-fpga-region/ranges
>
> Are there properties in /soc/base-fpga-region/ in the base devicetree?

It looks like this:
   base_fpga_region {
#address-cells = <0x1>;
#size-cells = <0x1>;
compatible = "fpga-region";
fpga-mgr = <_mgr>;
};

It is used as a target for applying DT overlays for FPGA reprogramming.

>
> If not, then that node could be removed from the base devicetree and first 
> created
> in an overlay.

I'll give it a try and report back!

> If so, is it possible to add an additional level of node, 
> /soc/base-fpga-region/foo,
> which would contain the properties that are warned about above?  Then the 
> properties
> would be children of an overlay node and the memory would be freed on overlay
> release.

I expect that would not be hard.  The of-fpga-region.c driver would
only need small changes to know where to expect the properties it is
looking for.

And when the child nodes in the overlay are added to the live tree,
they would be under the added fake level. That shouldn't be a problem
either, it would just be different.

> This is not actually a suggestion that should be implemented right now, just 
> trying
> to understand the possible alternatives, because this would result in an 
> arbitrary
> fake level in the tree (which I don't like).

Yeah I don't love it either, but for the sake of discussion, it's
worth the mention.  I'm open for suggestions here definitely.  But yes
adding the fake level might make the DT code implementation more
straightforward at the cost of something that 

Re: [PATCH 13/36] dt-bindings: arm: Convert PMU binding to json-schema

2018-10-09 Thread Rob Herring
On Tue, Oct 9, 2018 at 6:57 AM Will Deacon  wrote:
>
> Hi Rob,
>
> On Fri, Oct 05, 2018 at 11:58:25AM -0500, Rob Herring wrote:
> > Convert ARM PMU binding to DT schema format using json-schema.
> >
> > Cc: Will Deacon 
> > Cc: Mark Rutland 
> > Cc: linux-arm-ker...@lists.infradead.org
> > Cc: devicet...@vger.kernel.org
> > Signed-off-by: Rob Herring 
> > ---
> >  Documentation/devicetree/bindings/arm/pmu.txt | 70 --
> >  .../devicetree/bindings/arm/pmu.yaml  | 96 +++
> >  2 files changed, 96 insertions(+), 70 deletions(-)
> >  delete mode 100644 Documentation/devicetree/bindings/arm/pmu.txt
> >  create mode 100644 Documentation/devicetree/bindings/arm/pmu.yaml
>
> [...]
>
> > -- interrupts : 1 combined interrupt or 1 per core. If the interrupt is a 
> > per-cpu
> > -   interrupt (PPI) then 1 interrupt should be specified.
>
> [...]
>
> > +  interrupts:
> > +oneOf:
> > +  - maxItems: 1
> > +  - minItems: 2
> > +maxItems: 8
> > +description: 1 interrupt per core.
> > +
> > +  interrupts-extended:
> > +$ref: '#/properties/interrupts'
>
> This seems like a semantic different between the two representations, or am
> I missing something here? Specifically, both the introduction of
> interrupts-extended and also dropping any mention of using a single per-cpu
> interrupt (the single combined case is no longer support by Linux; not sure
> if you want to keep it in the binding).

'interrupts-extended' was implied before as it is always supported and
outside the scope of the binding. But now it is needed to validate
bindings. There must be some use of it and that's why I added it.
However, thinking some more about this, I think it may be better to
have the tools add this in automatically whenever we have an
interrupts property.

I guess the single interrupt case is less obvious now with no
description (it's the first list item of 'oneOf'). The schema If the
single interrupt is not supported, then we can drop it here.

Rob


[PATCH] powerpc: remove redundant 'default n' from Kconfig-s

2018-10-09 Thread Bartlomiej Zolnierkiewicz
'default n' is the default value for any bool or tristate Kconfig
setting so there is no need to write it explicitly.

Also since commit f467c5640c29 ("kconfig: only write '# CONFIG_FOO
is not set' for visible symbols") the Kconfig behavior is the same
regardless of 'default n' being present or not:

...
One side effect of (and the main motivation for) this change is making
the following two definitions behave exactly the same:

config FOO
bool

config FOO
bool
default n

With this change, neither of these will generate a
'# CONFIG_FOO is not set' line (assuming FOO isn't selected/implied).
That might make it clearer to people that a bare 'default n' is
redundant.
...

Signed-off-by: Bartlomiej Zolnierkiewicz 
---
 arch/powerpc/Kconfig   |   14 --
 arch/powerpc/Kconfig.debug |6 --
 arch/powerpc/platforms/40x/Kconfig |9 -
 arch/powerpc/platforms/44x/Kconfig |   22 --
 arch/powerpc/platforms/82xx/Kconfig|1 -
 arch/powerpc/platforms/Kconfig |   21 -
 arch/powerpc/platforms/Kconfig.cputype |4 
 arch/powerpc/platforms/cell/Kconfig|3 ---
 arch/powerpc/platforms/maple/Kconfig   |1 -
 arch/powerpc/platforms/pasemi/Kconfig  |1 -
 arch/powerpc/platforms/powernv/Kconfig |1 -
 arch/powerpc/platforms/ps3/Kconfig |2 --
 arch/powerpc/platforms/pseries/Kconfig |2 --
 arch/powerpc/sysdev/Kconfig|5 -
 arch/powerpc/sysdev/xive/Kconfig   |3 ---
 15 files changed, 95 deletions(-)

Index: b/arch/powerpc/Kconfig
===
--- a/arch/powerpc/Kconfig  2018-10-09 17:32:25.059264623 +0200
+++ b/arch/powerpc/Kconfig  2018-10-09 17:32:25.055264623 +0200
@@ -285,12 +285,10 @@ config ARCH_MAY_HAVE_PC_FDC
 
 config PPC_UDBG_16550
bool
-   default n
 
 config GENERIC_TBSYNC
bool
default y if PPC32 && SMP
-   default n
 
 config AUDIT_ARCH
bool
@@ -309,13 +307,11 @@ config EPAPR_BOOT
bool
help
  Used to allow a board to specify it wants an ePAPR compliant wrapper.
-   default n
 
 config DEFAULT_UIMAGE
bool
help
  Used to allow a board to specify it wants a uImage built by default
-   default n
 
 config ARCH_HIBERNATION_POSSIBLE
bool
@@ -329,11 +325,9 @@ config ARCH_SUSPEND_POSSIBLE
 
 config PPC_DCR_NATIVE
bool
-   default n
 
 config PPC_DCR_MMIO
bool
-   default n
 
 config PPC_DCR
bool
@@ -344,7 +338,6 @@ config PPC_OF_PLATFORM_PCI
bool
depends on PCI
depends on PPC64 # not supported on 32 bits yet
-   default n
 
 config ARCH_SUPPORTS_DEBUG_PAGEALLOC
depends on PPC32 || PPC_BOOK3S_64
@@ -447,14 +440,12 @@ config PPC_TRANSACTIONAL_MEM
depends on SMP
select ALTIVEC
select VSX
-   default n
---help---
  Support user-mode Transactional Memory on POWERPC.
 
 config LD_HEAD_STUB_CATCH
bool "Reserve 256 bytes to cope with linker stubs in HEAD text" if 
EXPERT
depends on PPC64
-   default n
help
  Very large kernels can cause linker branch stubs to be generated by
  code in head_64.S, which moves the head text sections out of their
@@ -557,7 +548,6 @@ config RELOCATABLE
 config RELOCATABLE_TEST
bool "Test relocatable kernel"
depends on (PPC64 && RELOCATABLE)
-   default n
help
  This runs the relocatable kernel at the address it was initially
  loaded at, which tends to be non-zero and therefore test the
@@ -769,7 +759,6 @@ config PPC_SUBPAGE_PROT
 
 config PPC_COPRO_BASE
bool
-   default n
 
 config SCHED_SMT
bool "SMT (Hyperthreading) scheduler support"
@@ -870,7 +859,6 @@ config PPC_INDIRECT_PCI
bool
depends on PCI
default y if 40x || 44x
-   default n
 
 config EISA
bool
@@ -967,7 +955,6 @@ source "drivers/pcmcia/Kconfig"
 
 config HAS_RAPIDIO
bool
-   default n
 
 config RAPIDIO
tristate "RapidIO support"
@@ -990,7 +977,6 @@ endmenu
 
 config NONSTATIC_KERNEL
bool
-   default n
 
 menu "Advanced setup"
depends on PPC32
Index: b/arch/powerpc/Kconfig.debug
===
--- a/arch/powerpc/Kconfig.debug2018-10-09 17:32:25.059264623 +0200
+++ b/arch/powerpc/Kconfig.debug2018-10-09 17:32:25.055264623 +0200
@@ -2,7 +2,6 @@
 
 config PPC_DISABLE_WERROR
bool "Don't build arch/powerpc code with -Werror"
-   default n
help
  This option tells the compiler NOT to build the code under
  arch/powerpc with the -Werror flag (which means warnings
@@ -56,7 +55,6 @@ config PPC_EMULATED_STATS
 

Re: [PATCH v3 03/24] drivers/block/z2ram: use ioremap_wt() instead of __ioremap(_PAGE_WRITETHRU)

2018-10-09 Thread Geert Uytterhoeven
Hi Bart,

CC debian-68k, linux-m68k

On Tue, Oct 9, 2018 at 5:00 PM Bart Van Assche  wrote:
> On Tue, 2018-10-09 at 13:51 +, Christophe Leroy wrote:
> > _PAGE_WRITETHRU is a target specific flag. Prefer generic functions.
> >
> > Acked-by: Geert Uytterhoeven 
> > Signed-off-by: Christophe Leroy 
>
> Hi Geert,
>
> All patches that have been applied to this driver since 2005 are API 
> refactoring
> patches. I haven't found any patches in the history of this driver that seem 
> to
> have been submitted by a user of this driver. Do you perhaps know whether 
> anyone
> is using this driver?

The z2ram is a very simple driver, used to configure (slower) Zorro II RAM as
a swap device.  So I'm not so surprised no one submitted functional patches.

I believe it's still being used.
Probably it could be modified to use mtdram.

Gr{oetje,eeting}s,

Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds


Re: [PATCH v3 03/24] drivers/block/z2ram: use ioremap_wt() instead of __ioremap(_PAGE_WRITETHRU)

2018-10-09 Thread Bart Van Assche
On Tue, 2018-10-09 at 13:51 +, Christophe Leroy wrote:
> _PAGE_WRITETHRU is a target specific flag. Prefer generic functions.
> 
> Acked-by: Geert Uytterhoeven 
> Signed-off-by: Christophe Leroy 

Hi Geert,

All patches that have been applied to this driver since 2005 are API refactoring
patches. I haven't found any patches in the history of this driver that seem to
have been submitted by a user of this driver. Do you perhaps know whether anyone
is using this driver?

Thanks,

Bart.



Re: [PATCH v2 -next] powerpc/pseries/memory-hotplug: Fix return value type of find_aa_index

2018-10-09 Thread YueHaibing
On 2018/10/9 15:00, Michael Ellerman wrote:
> YueHaibing  writes:
>> 'aa_index' is defined as an unsigned value, but find_aa_index
>> may return -1 when dlpar_clone_property fails. So we use an rc
>> value to track the validation of finding the aa_index instead
>> of the 'aa_index' value itself
>>
>> Fixes: c05a5a40969e ("powerpc/pseries: Dynamic add entires to associativity 
>> lookup array")
>> Signed-off-by: YueHaibing 
>> ---
>> v2: use 'rc' track the validation of aa_index
> 
> Thanks for sending a v2, some more comments ...
> 
>> diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c 
>> b/arch/powerpc/platforms/pseries/hotplug-memory.c
>> index 9a15d39..796e68b 100644
>> --- a/arch/powerpc/platforms/pseries/hotplug-memory.c
>> +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
>> @@ -101,13 +101,12 @@ static struct property *dlpar_clone_property(struct 
>> property *prop,
>>  return new_prop;
>>  }
>>  
>> -static u32 find_aa_index(struct device_node *dr_node,
>> - struct property *ala_prop, const u32 *lmb_assoc)
>> +static int find_aa_index(struct device_node *dr_node, struct property 
>> *ala_prop,
>> + const u32 *lmb_assoc, u32 *aa_index)
>>  {
>>  u32 *assoc_arrays;
>> -u32 aa_index;
>>  int aa_arrays, aa_array_entries, aa_array_sz;
>> -int i, index;
>> +int i, index, rc = -1;
> 
> It's preferable to leave rc uninitialised until we actually need to
> initialise it, that gives the compiler the chance to warn us if we use
> it inadvertently before that.
> 
>>  
>>  /*
>>   * The ibm,associativity-lookup-arrays property is defined to be
>> @@ -121,18 +120,18 @@ static u32 find_aa_index(struct device_node *dr_node,
>>  aa_array_entries = be32_to_cpu(assoc_arrays[1]);
>>  aa_array_sz = aa_array_entries * sizeof(u32);
>>  
>> -aa_index = -1;
> 
> So that would be here:
>   rc = -1;
> 
> But ..
> 
>>  for (i = 0; i < aa_arrays; i++) {
>>  index = (i * aa_array_entries) + 2;
>>  
>>  if (memcmp(_arrays[index], _assoc[1], aa_array_sz))
>>  continue;
>>  
>> -aa_index = i;
>> +*aa_index = i;
>> +rc = 0;
>>  break;
>>  }
> 
> The 'rc' variable is basically a boolean now, it means "we found something".
> 
> And all we do with it in the found case (rc = 0) is test it below and return.
> 
> So can't we just return directly in the for loop above, rather than breaking?
> 
> In which case we don't need the rc variable at all.
> 
> And the whole function may as well return bool, rather than int.
> 
> Does that make sense?

Yes, will do that in v3.

> 
> cheers
> 
>> -if (aa_index == -1) {
>> +if (rc == -1) {
>>  struct property *new_prop;
>>  u32 new_prop_size;
>>  
>> @@ -157,10 +156,11 @@ static u32 find_aa_index(struct device_node *dr_node,
>>   * number of entries - 1 since we added its associativity
>>   * to the end of the lookup array.
>>   */
>> -aa_index = be32_to_cpu(assoc_arrays[0]) - 1;
>> +*aa_index = be32_to_cpu(assoc_arrays[0]) - 1;
>> +rc = 0;
>>  }
>>  
>> -return aa_index;
>> +return rc;
>>  }
>>  
>>  static int update_lmb_associativity_index(struct drmem_lmb *lmb)
> 
> .
> 



[PATCH v3 -next] powerpc/pseries/memory-hotplug: Fix return value type of find_aa_index

2018-10-09 Thread YueHaibing
'aa_index' is defined as an unsigned value, but find_aa_index
may return -1 when dlpar_clone_property fails. So change 
find_aa_index return value type to bool, which indicate 'aa_index'
whether found or not.

Fixes: c05a5a40969e ("powerpc/pseries: Dynamic add entires to associativity 
lookup array")
Signed-off-by: YueHaibing 
---
v3: change find_aa_index return type to bool
v2: use 'rc' track the validation of aa_index
---
 arch/powerpc/platforms/pseries/hotplug-memory.c | 61 -
 1 file changed, 28 insertions(+), 33 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c 
b/arch/powerpc/platforms/pseries/hotplug-memory.c
index d26a771..4db510f 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -101,11 +101,12 @@ static struct property *dlpar_clone_property(struct 
property *prop,
return new_prop;
 }
 
-static u32 find_aa_index(struct device_node *dr_node,
-struct property *ala_prop, const u32 *lmb_assoc)
+static bool find_aa_index(struct device_node *dr_node,
+struct property *ala_prop,
+const u32 *lmb_assoc, u32 *aa_index)
 {
-   u32 *assoc_arrays;
-   u32 aa_index;
+   u32 *assoc_arrays, new_prop_size;
+   struct property *new_prop;
int aa_arrays, aa_array_entries, aa_array_sz;
int i, index;
 
@@ -121,46 +122,39 @@ static u32 find_aa_index(struct device_node *dr_node,
aa_array_entries = be32_to_cpu(assoc_arrays[1]);
aa_array_sz = aa_array_entries * sizeof(u32);
 
-   aa_index = -1;
for (i = 0; i < aa_arrays; i++) {
index = (i * aa_array_entries) + 2;
 
if (memcmp(_arrays[index], _assoc[1], aa_array_sz))
continue;
 
-   aa_index = i;
-   break;
+   *aa_index = i;
+   return true;
}
 
-   if (aa_index == -1) {
-   struct property *new_prop;
-   u32 new_prop_size;
-
-   new_prop_size = ala_prop->length + aa_array_sz;
-   new_prop = dlpar_clone_property(ala_prop, new_prop_size);
-   if (!new_prop)
-   return -1;
-
-   assoc_arrays = new_prop->value;
+   new_prop_size = ala_prop->length + aa_array_sz;
+   new_prop = dlpar_clone_property(ala_prop, new_prop_size);
+   if (!new_prop)
+   return false;
 
-   /* increment the number of entries in the lookup array */
-   assoc_arrays[0] = cpu_to_be32(aa_arrays + 1);
+   assoc_arrays = new_prop->value;
 
-   /* copy the new associativity into the lookup array */
-   index = aa_arrays * aa_array_entries + 2;
-   memcpy(_arrays[index], _assoc[1], aa_array_sz);
+   /* increment the number of entries in the lookup array */
+   assoc_arrays[0] = cpu_to_be32(aa_arrays + 1);
 
-   of_update_property(dr_node, new_prop);
+   /* copy the new associativity into the lookup array */
+   index = aa_arrays * aa_array_entries + 2;
+   memcpy(_arrays[index], _assoc[1], aa_array_sz);
 
-   /*
-* The associativity lookup array index for this lmb is
-* number of entries - 1 since we added its associativity
-* to the end of the lookup array.
-*/
-   aa_index = be32_to_cpu(assoc_arrays[0]) - 1;
-   }
+   of_update_property(dr_node, new_prop);
 
-   return aa_index;
+   /*
+* The associativity lookup array index for this lmb is
+* number of entries - 1 since we added its associativity
+* to the end of the lookup array.
+*/
+   *aa_index = be32_to_cpu(assoc_arrays[0]) - 1;
+   return true;
 }
 
 static int update_lmb_associativity_index(struct drmem_lmb *lmb)
@@ -169,6 +163,7 @@ static int update_lmb_associativity_index(struct drmem_lmb 
*lmb)
struct property *ala_prop;
const u32 *lmb_assoc;
u32 aa_index;
+   bool is_found;
 
parent = of_find_node_by_path("/");
if (!parent)
@@ -200,11 +195,11 @@ static int update_lmb_associativity_index(struct 
drmem_lmb *lmb)
return -ENODEV;
}
 
-   aa_index = find_aa_index(dr_node, ala_prop, lmb_assoc);
+   is_found = find_aa_index(dr_node, ala_prop, lmb_assoc, _index);
 
dlpar_free_cc_nodes(lmb_node);
 
-   if (aa_index < 0) {
+   if (!is_found) {
pr_err("Could not find LMB associativity\n");
return -1;
}
-- 
2.7.0




[PATCH v3 24/24] powerpc/book3s64: Avoid multiple endian conversion in pte helpers

2018-10-09 Thread Christophe Leroy
In the same spirit as already done in pte query helpers,
this patch changes pte setting helpers to perform endian
conversions on the constants rather than on the pte value.

In the meantime, it changes pte_access_permitted() to use
pte helpers for the same reason.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/book3s/64/pgtable.h | 71 +---
 1 file changed, 32 insertions(+), 39 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h 
b/arch/powerpc/include/asm/book3s/64/pgtable.h
index cf8dbd5f8f03..f0c79f370cf0 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -506,12 +506,12 @@ static inline bool pte_soft_dirty(pte_t pte)
 
 static inline pte_t pte_mksoft_dirty(pte_t pte)
 {
-   return __pte(pte_val(pte) | _PAGE_SOFT_DIRTY);
+   return __pte_raw(pte_raw(pte) | cpu_to_be64(_PAGE_SOFT_DIRTY));
 }
 
 static inline pte_t pte_clear_soft_dirty(pte_t pte)
 {
-   return __pte(pte_val(pte) & ~_PAGE_SOFT_DIRTY);
+   return __pte_raw(pte_raw(pte) & cpu_to_be64(~_PAGE_SOFT_DIRTY));
 }
 #endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
 
@@ -532,7 +532,7 @@ static inline pte_t pte_mk_savedwrite(pte_t pte)
 */
VM_BUG_ON((pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT | _PAGE_RWX | 
_PAGE_PRIVILEGED)) !=
  cpu_to_be64(_PAGE_PRESENT | _PAGE_PRIVILEGED));
-   return __pte(pte_val(pte) & ~_PAGE_PRIVILEGED);
+   return __pte_raw(pte_raw(pte) & cpu_to_be64(~_PAGE_PRIVILEGED));
 }
 
 #define pte_clear_savedwrite pte_clear_savedwrite
@@ -542,14 +542,14 @@ static inline pte_t pte_clear_savedwrite(pte_t pte)
 * Used by KSM subsystem to make a protnone pte readonly.
 */
VM_BUG_ON(!pte_protnone(pte));
-   return __pte(pte_val(pte) | _PAGE_PRIVILEGED);
+   return __pte_raw(pte_raw(pte) | cpu_to_be64(_PAGE_PRIVILEGED));
 }
 #else
 #define pte_clear_savedwrite pte_clear_savedwrite
 static inline pte_t pte_clear_savedwrite(pte_t pte)
 {
VM_WARN_ON(1);
-   return __pte(pte_val(pte) & ~_PAGE_WRITE);
+   return __pte_raw(pte_raw(pte) & cpu_to_be64(~_PAGE_WRITE));
 }
 #endif /* CONFIG_NUMA_BALANCING */
 
@@ -578,25 +578,22 @@ static inline bool arch_pte_access_permitted(u64 pte, 
bool write, bool execute)
 }
 #endif /* CONFIG_PPC_MEM_KEYS */
 
+static inline bool pte_user(pte_t pte)
+{
+   return !(pte_raw(pte) & cpu_to_be64(_PAGE_PRIVILEGED));
+}
+
 #define pte_access_permitted pte_access_permitted
 static inline bool pte_access_permitted(pte_t pte, bool write)
 {
-   unsigned long pteval = pte_val(pte);
-   /* Also check for pte_user */
-   unsigned long clear_pte_bits = _PAGE_PRIVILEGED;
/*
 * _PAGE_READ is needed for any access and will be
 * cleared for PROT_NONE
 */
-   unsigned long need_pte_bits = _PAGE_PRESENT | _PAGE_READ;
-
-   if (write)
-   need_pte_bits |= _PAGE_WRITE;
-
-   if ((pteval & need_pte_bits) != need_pte_bits)
+   if (!pte_present(pte) || !pte_user(pte) || !pte_read(pte))
return false;
 
-   if ((pteval & clear_pte_bits) == clear_pte_bits)
+   if (write && !pte_write(pte))
return false;
 
return arch_pte_access_permitted(pte_val(pte), write, 0);
@@ -625,32 +622,32 @@ static inline pte_t pte_wrprotect(pte_t pte)
 {
if (unlikely(pte_savedwrite(pte)))
return pte_clear_savedwrite(pte);
-   return __pte(pte_val(pte) & ~_PAGE_WRITE);
+   return __pte_raw(pte_raw(pte) & cpu_to_be64(~_PAGE_WRITE));
 }
 
 static inline pte_t pte_exprotect(pte_t pte)
 {
-   return __pte(pte_val(pte) & ~_PAGE_EXEC);
+   return __pte_raw(pte_raw(pte) & cpu_to_be64(~_PAGE_EXEC));
 }
 
 static inline pte_t pte_mkclean(pte_t pte)
 {
-   return __pte(pte_val(pte) & ~_PAGE_DIRTY);
+   return __pte_raw(pte_raw(pte) & cpu_to_be64(~_PAGE_DIRTY));
 }
 
 static inline pte_t pte_mkold(pte_t pte)
 {
-   return __pte(pte_val(pte) & ~_PAGE_ACCESSED);
+   return __pte_raw(pte_raw(pte) & cpu_to_be64(~_PAGE_ACCESSED));
 }
 
 static inline pte_t pte_mkexec(pte_t pte)
 {
-   return __pte(pte_val(pte) | _PAGE_EXEC);
+   return __pte_raw(pte_raw(pte) | cpu_to_be64(_PAGE_EXEC));
 }
 
 static inline pte_t pte_mkpte(pte_t pte)
 {
-   return __pte(pte_val(pte) | _PAGE_PTE);
+   return __pte_raw(pte_raw(pte) | cpu_to_be64(_PAGE_PTE));
 }
 
 static inline pte_t pte_mkwrite(pte_t pte)
@@ -658,22 +655,22 @@ static inline pte_t pte_mkwrite(pte_t pte)
/*
 * write implies read, hence set both
 */
-   return __pte(pte_val(pte) | _PAGE_RW);
+   return __pte_raw(pte_raw(pte) | cpu_to_be64(_PAGE_RW));
 }
 
 static inline pte_t pte_mkdirty(pte_t pte)
 {
-   return __pte(pte_val(pte) | _PAGE_DIRTY | _PAGE_SOFT_DIRTY);
+   return __pte_raw(pte_raw(pte) | cpu_to_be64(_PAGE_DIRTY | 
_PAGE_SOFT_DIRTY));
 }
 
 static inline pte_t pte_mkyoung(pte_t 

[PATCH v3 23/24] powerpc/8xx: change name of a few page flags to avoid confusion

2018-10-09 Thread Christophe Leroy
_PAGE_PRIVILEGED corresponds to the SH bit which doesn't protect
against user access but only disables ASID verification on kernel
accesses. User access is controlled with _PMD_USER flag.

Name it _PAGE_SH instead of _PAGE_PRIVILEGED

_PAGE_HUGE corresponds to the SPS bit which doesn't really tells
that's it is a huge page but only that it is not a 4k page.

Name it _PAGE_SPS instead of _PAGE_HUGE

Reviewed-by: Aneesh Kumar K.V 
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/nohash/32/pte-8xx.h | 28 ++--
 arch/powerpc/kernel/head_8xx.S   |  6 +++---
 arch/powerpc/mm/8xx_mmu.c|  2 +-
 arch/powerpc/mm/dump_linuxpagetables-8xx.c   |  2 +-
 4 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/include/asm/nohash/32/pte-8xx.h 
b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
index 2b4669b3badb..1c57efac089d 100644
--- a/arch/powerpc/include/asm/nohash/32/pte-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
@@ -29,10 +29,10 @@
  */
 
 /* Definitions for 8xx embedded chips. */
-#define _PAGE_PRESENT  0x0001  /* Page is valid */
-#define _PAGE_NO_CACHE 0x0002  /* I: cache inhibit */
-#define _PAGE_PRIVILEGED   0x0004  /* No ASID (context) compare */
-#define _PAGE_HUGE 0x0008  /* SPS: Small Page Size (1 if 16k, 512k or 8M)*/
+#define _PAGE_PRESENT  0x0001  /* V: Page is valid */
+#define _PAGE_NO_CACHE 0x0002  /* CI: cache inhibit */
+#define _PAGE_SH   0x0004  /* SH: No ASID (context) compare */
+#define _PAGE_SPS  0x0008  /* SPS: Small Page Size (1 if 16k, 512k or 8M)*/
 #define _PAGE_DIRTY0x0100  /* C: page changed */
 
 /* These 4 software bits must be masked out when the L2 entry is loaded
@@ -50,15 +50,15 @@
 #define _PAGE_COHERENT 0
 #define _PAGE_WRITETHRU0
 
-#define _PAGE_KERNEL_RO(_PAGE_PRIVILEGED | _PAGE_RO)
-#define _PAGE_KERNEL_ROX   (_PAGE_PRIVILEGED | _PAGE_RO | _PAGE_EXEC)
-#define _PAGE_KERNEL_RW(_PAGE_PRIVILEGED | _PAGE_DIRTY)
-#define _PAGE_KERNEL_RWX   (_PAGE_PRIVILEGED | _PAGE_DIRTY | _PAGE_EXEC)
+#define _PAGE_KERNEL_RO(_PAGE_SH | _PAGE_RO)
+#define _PAGE_KERNEL_ROX   (_PAGE_SH | _PAGE_RO | _PAGE_EXEC)
+#define _PAGE_KERNEL_RW(_PAGE_SH | _PAGE_DIRTY)
+#define _PAGE_KERNEL_RWX   (_PAGE_SH | _PAGE_DIRTY | _PAGE_EXEC)
 
 /* Mask of bits returned by pte_pgprot() */
 #define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_NO_CACHE | \
 _PAGE_ACCESSED | _PAGE_RO | _PAGE_NA | \
-_PAGE_PRIVILEGED | _PAGE_DIRTY | _PAGE_EXEC)
+_PAGE_SH | _PAGE_DIRTY | _PAGE_EXEC)
 
 #define _PMD_PRESENT   0x0001
 #define _PMD_PRESENT_MASK  _PMD_PRESENT
@@ -74,7 +74,7 @@
 #define PTE_ATOMIC_UPDATES 1
 
 #ifdef CONFIG_PPC_16K_PAGES
-#define _PAGE_PSIZE_PAGE_HUGE
+#define _PAGE_PSIZE_PAGE_SPS
 #else
 #define _PAGE_PSIZE0
 #endif
@@ -115,28 +115,28 @@ static inline pte_t pte_mkwrite(pte_t pte)
 
 static inline bool pte_user(pte_t pte)
 {
-   return !(pte_val(pte) & _PAGE_PRIVILEGED);
+   return !(pte_val(pte) & _PAGE_SH);
 }
 
 #define pte_user pte_user
 
 static inline pte_t pte_mkprivileged(pte_t pte)
 {
-   return __pte(pte_val(pte) | _PAGE_PRIVILEGED);
+   return __pte(pte_val(pte) | _PAGE_SH);
 }
 
 #define pte_mkprivileged pte_mkprivileged
 
 static inline pte_t pte_mkuser(pte_t pte)
 {
-   return __pte(pte_val(pte) & ~_PAGE_PRIVILEGED);
+   return __pte(pte_val(pte) & ~_PAGE_SH);
 }
 
 #define pte_mkuser pte_mkuser
 
 static inline pte_t pte_mkhuge(pte_t pte)
 {
-   return __pte(pte_val(pte) | _PAGE_HUGE);
+   return __pte(pte_val(pte) | _PAGE_SPS);
 }
 
 #define pte_mkhuge pte_mkhuge
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 6582f824d620..134a573a9f2d 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -642,7 +642,7 @@ DTLBMissIMMR:
mtspr   SPRN_MD_TWC, r10
mfspr   r10, SPRN_IMMR  /* Get current IMMR */
rlwinm  r10, r10, 0, 0xfff8 /* Get 512 kbytes boundary */
-   ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_PRIVILEGED | _PAGE_DIRTY | \
+   ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SH | _PAGE_DIRTY | \
  _PAGE_PRESENT | _PAGE_NO_CACHE
mtspr   SPRN_MD_RPN, r10/* Update TLB entry */
 
@@ -660,7 +660,7 @@ DTLBMissLinear:
li  r11, MD_PS8MEG | MD_SVALID | M_APG2
mtspr   SPRN_MD_TWC, r11
rlwinm  r10, r10, 0, 0x0f80 /* 8xx supports max 256Mb RAM */
-   ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_PRIVILEGED | _PAGE_DIRTY | \
+   ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SH | _PAGE_DIRTY | \
  _PAGE_PRESENT
mtspr   SPRN_MD_RPN, r10/* Update TLB entry */
 
@@ -679,7 +679,7 @@ ITLBMissLinear:
li  r11, MI_PS8MEG | MI_SVALID | M_APG2

[PATCH v3 22/24] powerpc/mm: Get rid of pte-common.h

2018-10-09 Thread Christophe Leroy
Do not include pte-common.h in nohash/32/pgtable.h

As that was the last includer, get rid of pte-common.h

Reviewed-by: Aneesh Kumar K.V 
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/nohash/32/pgtable.h | 23 +--
 arch/powerpc/include/asm/pte-common.h| 25 -
 2 files changed, 21 insertions(+), 27 deletions(-)
 delete mode 100644 arch/powerpc/include/asm/pte-common.h

diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h 
b/arch/powerpc/include/asm/nohash/32/pgtable.h
index ce9270a0ea42..d2908a8038e8 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -128,8 +128,27 @@ extern int icache_44x_need_flush;
 #include 
 #endif
 
-/* And here we include common definitions */
-#include 
+/* Location of the PFN in the PTE. Most 32-bit platforms use the same
+ * as _PAGE_SHIFT here (ie, naturally aligned).
+ * Platform who don't just pre-define the value so we don't override it here
+ */
+#ifndef PTE_RPN_SHIFT
+#define PTE_RPN_SHIFT  (PAGE_SHIFT)
+#endif
+
+/* The mask covered by the RPN must be a ULL on 32-bit platforms with
+ * 64-bit PTEs
+ */
+#if defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT)
+#define PTE_RPN_MASK   (~((1ULL << PTE_RPN_SHIFT) - 1))
+#else
+#define PTE_RPN_MASK   (~((1UL << PTE_RPN_SHIFT) - 1))
+#endif
+
+/* _PAGE_CHG_MASK masks of bits that are to be preserved across
+ * pgprot changes
+ */
+#define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_DIRTY | _PAGE_ACCESSED | 
_PAGE_SPECIAL)
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/powerpc/include/asm/pte-common.h 
b/arch/powerpc/include/asm/pte-common.h
deleted file mode 100644
index ff01368a175a..
--- a/arch/powerpc/include/asm/pte-common.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Included from asm/pgtable-*.h only ! */
-
-/* Location of the PFN in the PTE. Most 32-bit platforms use the same
- * as _PAGE_SHIFT here (ie, naturally aligned).
- * Platform who don't just pre-define the value so we don't override it here
- */
-#ifndef PTE_RPN_SHIFT
-#define PTE_RPN_SHIFT  (PAGE_SHIFT)
-#endif
-
-/* The mask covered by the RPN must be a ULL on 32-bit platforms with
- * 64-bit PTEs
- */
-#if defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT)
-#define PTE_RPN_MASK   (~((1ULL<

[PATCH v3 21/24] powerpc/mm: Define platform default caches related flags

2018-10-09 Thread Christophe Leroy
Cache related flags like _PAGE_COHERENT and _PAGE_WRITETHRU
are defined on most platforms. The platforms not defining
them don't define any alternative. So we can give them a NUL
value directly for those platforms directly.

Reviewed-by: Aneesh Kumar K.V 
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/nohash/32/pte-40x.h |  3 +++
 arch/powerpc/include/asm/nohash/32/pte-8xx.h |  4 
 arch/powerpc/include/asm/pte-common.h| 11 ---
 3 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/include/asm/nohash/32/pte-40x.h 
b/arch/powerpc/include/asm/nohash/32/pte-40x.h
index ab043b3e9b99..7a8b3c94592f 100644
--- a/arch/powerpc/include/asm/nohash/32/pte-40x.h
+++ b/arch/powerpc/include/asm/nohash/32/pte-40x.h
@@ -53,6 +53,9 @@
 /* No page size encoding in the linux PTE */
 #define _PAGE_PSIZE0
 
+/* cache related flags non existing on 40x */
+#define _PAGE_COHERENT 0
+
 #define _PAGE_KERNEL_RO0
 #define _PAGE_KERNEL_ROX   _PAGE_EXEC
 #define _PAGE_KERNEL_RW(_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
diff --git a/arch/powerpc/include/asm/nohash/32/pte-8xx.h 
b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
index b899c3c877ac..2b4669b3badb 100644
--- a/arch/powerpc/include/asm/nohash/32/pte-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
@@ -46,6 +46,10 @@
 #define _PAGE_NA   0x0200  /* Supervisor NA, User no access */
 #define _PAGE_RO   0x0600  /* Supervisor RO, User no access */
 
+/* cache related flags non existing on 8xx */
+#define _PAGE_COHERENT 0
+#define _PAGE_WRITETHRU0
+
 #define _PAGE_KERNEL_RO(_PAGE_PRIVILEGED | _PAGE_RO)
 #define _PAGE_KERNEL_ROX   (_PAGE_PRIVILEGED | _PAGE_RO | _PAGE_EXEC)
 #define _PAGE_KERNEL_RW(_PAGE_PRIVILEGED | _PAGE_DIRTY)
diff --git a/arch/powerpc/include/asm/pte-common.h 
b/arch/powerpc/include/asm/pte-common.h
index 1a2102f8b1e7..ff01368a175a 100644
--- a/arch/powerpc/include/asm/pte-common.h
+++ b/arch/powerpc/include/asm/pte-common.h
@@ -1,17 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /* Included from asm/pgtable-*.h only ! */
 
-/*
- * Some bits are only used on some cpu families... Make sure that all
- * the undefined gets a sensible default
- */
-#ifndef _PAGE_COHERENT
-#define _PAGE_COHERENT 0
-#endif
-#ifndef _PAGE_WRITETHRU
-#define _PAGE_WRITETHRU0
-#endif
-
 /* Location of the PFN in the PTE. Most 32-bit platforms use the same
  * as _PAGE_SHIFT here (ie, naturally aligned).
  * Platform who don't just pre-define the value so we don't override it here
-- 
2.13.3



[PATCH v3 20/24] powerpc/mm: Allow platforms to redefine some helpers

2018-10-09 Thread Christophe Leroy
The 40xx defines _PAGE_HWWRITE while others don't.
The 8xx defines _PAGE_RO instead of _PAGE_RW.
The 8xx defines _PAGE_PRIVILEGED instead of _PAGE_USER.
The 8xx defines _PAGE_HUGE and _PAGE_NA while others don't.

Lets those platforms redefine pte_write(), pte_wrprotect() and
pte_mkwrite() and get _PAGE_RO and _PAGE_HWWRITE off the common
helpers.

Lets the 8xx redefine pte_user(), pte_mkprivileged() and pte_mkuser()
and get rid of _PAGE_PRIVILEGED and _PAGE_USER default values.

Lets the 8xx redefine pte_mkhuge() and get rid of
_PAGE_HUGE default value.

Reviewed-by: Aneesh Kumar K.V 
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/nohash/32/pgtable.h | 16 -
 arch/powerpc/include/asm/nohash/32/pte-40x.h | 16 +
 arch/powerpc/include/asm/nohash/32/pte-8xx.h | 51 
 arch/powerpc/include/asm/nohash/64/pgtable.h |  4 ---
 arch/powerpc/include/asm/nohash/pgtable.h| 24 +
 arch/powerpc/include/asm/pte-common.h| 24 -
 6 files changed, 91 insertions(+), 44 deletions(-)

diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h 
b/arch/powerpc/include/asm/nohash/32/pgtable.h
index a4156da4a7a4..ce9270a0ea42 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -136,14 +136,12 @@ extern int icache_44x_need_flush;
 #define pte_clear(mm, addr, ptep) \
do { pte_update(ptep, ~0, 0); } while (0)
 
+#ifndef pte_mkwrite
 static inline pte_t pte_mkwrite(pte_t pte)
 {
-   pte_basic_t ptev;
-
-   ptev = pte_val(pte) & ~_PAGE_RO;
-   ptev |= _PAGE_RW;
-   return __pte(ptev);
+   return __pte(pte_val(pte) | _PAGE_RW);
 }
+#endif
 
 static inline pte_t pte_mkdirty(pte_t pte)
 {
@@ -155,14 +153,12 @@ static inline pte_t pte_mkyoung(pte_t pte)
return __pte(pte_val(pte) | _PAGE_ACCESSED);
 }
 
+#ifndef pte_wrprotect
 static inline pte_t pte_wrprotect(pte_t pte)
 {
-   pte_basic_t ptev;
-
-   ptev = pte_val(pte) & ~(_PAGE_RW | _PAGE_HWWRITE);
-   ptev |= _PAGE_RO;
-   return __pte(ptev);
+   return __pte(pte_val(pte) & ~_PAGE_RW);
 }
+#endif
 
 static inline pte_t pte_mkexec(pte_t pte)
 {
diff --git a/arch/powerpc/include/asm/nohash/32/pte-40x.h 
b/arch/powerpc/include/asm/nohash/32/pte-40x.h
index 2b48bc289a4d..ab043b3e9b99 100644
--- a/arch/powerpc/include/asm/nohash/32/pte-40x.h
+++ b/arch/powerpc/include/asm/nohash/32/pte-40x.h
@@ -87,5 +87,21 @@
 #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
 #define PAGE_READONLY_X__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
 
+#ifndef __ASSEMBLY__
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+   return __pte(pte_val(pte) & ~(_PAGE_RW | _PAGE_HWWRITE));
+}
+
+#define pte_wrprotect pte_wrprotect
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+   return __pte(pte_val(pte) & ~(_PAGE_DIRTY | _PAGE_HWWRITE));
+}
+
+#define pte_mkclean pte_mkclean
+#endif
+
 #endif /* __KERNEL__ */
 #endif /*  _ASM_POWERPC_NOHASH_32_PTE_40x_H */
diff --git a/arch/powerpc/include/asm/nohash/32/pte-8xx.h 
b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
index d06fc45bd9ac..b899c3c877ac 100644
--- a/arch/powerpc/include/asm/nohash/32/pte-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
@@ -87,5 +87,56 @@
 #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_RO)
 #define PAGE_READONLY_X__pgprot(_PAGE_BASE | _PAGE_RO | _PAGE_EXEC)
 
+#ifndef __ASSEMBLY__
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+   return __pte(pte_val(pte) | _PAGE_RO);
+}
+
+#define pte_wrprotect pte_wrprotect
+
+static inline int pte_write(pte_t pte)
+{
+   return !(pte_val(pte) & _PAGE_RO);
+}
+
+#define pte_write pte_write
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+   return __pte(pte_val(pte) & ~_PAGE_RO);
+}
+
+#define pte_mkwrite pte_mkwrite
+
+static inline bool pte_user(pte_t pte)
+{
+   return !(pte_val(pte) & _PAGE_PRIVILEGED);
+}
+
+#define pte_user pte_user
+
+static inline pte_t pte_mkprivileged(pte_t pte)
+{
+   return __pte(pte_val(pte) | _PAGE_PRIVILEGED);
+}
+
+#define pte_mkprivileged pte_mkprivileged
+
+static inline pte_t pte_mkuser(pte_t pte)
+{
+   return __pte(pte_val(pte) & ~_PAGE_PRIVILEGED);
+}
+
+#define pte_mkuser pte_mkuser
+
+static inline pte_t pte_mkhuge(pte_t pte)
+{
+   return __pte(pte_val(pte) | _PAGE_HUGE);
+}
+
+#define pte_mkhuge pte_mkhuge
+#endif
+
 #endif /* __KERNEL__ */
 #endif /*  _ASM_POWERPC_NOHASH_32_PTE_8xx_H */
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h 
b/arch/powerpc/include/asm/nohash/64/pgtable.h
index 9ccea94b3d4e..f272e4599803 100644
--- a/arch/powerpc/include/asm/nohash/64/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
@@ -90,11 +90,7 @@
  */
 #include 
 
-#define _PAGE_HWWRITE  0
 #define _PAGE_SAO  0
-#define _PAGE_RO 0
-#define _PAGE_NA 0
-#define _PAGE_HUGE 0
 
 #define PTE_RPN_MASK   (~((1UL << PTE_RPN_SHIFT) - 1))
 
diff --git 

[PATCH v3 19/24] powerpc/nohash/64: do not include pte-common.h

2018-10-09 Thread Christophe Leroy
nohash/64 only uses book3e PTE flags, so it doesn't need pte-common.h

This also allows to drop PAGE_SAO and H_PAGE_4K_PFN from pte_common.h
as they are only used by PPC64

Reviewed-by: Aneesh Kumar K.V 
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/nohash/64/pgtable.h | 16 -
 arch/powerpc/include/asm/nohash/pgtable.h| 27 +
 arch/powerpc/include/asm/pte-common.h| 35 
 3 files changed, 42 insertions(+), 36 deletions(-)

diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h 
b/arch/powerpc/include/asm/nohash/64/pgtable.h
index b7d65d4b61be..9ccea94b3d4e 100644
--- a/arch/powerpc/include/asm/nohash/64/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
@@ -89,7 +89,21 @@
  * Include the PTE bits definitions
  */
 #include 
-#include 
+
+#define _PAGE_HWWRITE  0
+#define _PAGE_SAO  0
+#define _PAGE_RO 0
+#define _PAGE_NA 0
+#define _PAGE_HUGE 0
+
+#define PTE_RPN_MASK   (~((1UL << PTE_RPN_SHIFT) - 1))
+
+/* _PAGE_CHG_MASK masks of bits that are to be preserved across
+ * pgprot changes
+ */
+#define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_DIRTY | _PAGE_ACCESSED | 
_PAGE_SPECIAL)
+
+#define H_PAGE_4K_PFN 0
 
 #ifndef __ASSEMBLY__
 /* pte_clear moved to later in this file */
diff --git a/arch/powerpc/include/asm/nohash/pgtable.h 
b/arch/powerpc/include/asm/nohash/pgtable.h
index 8de3b7eb88b0..d3feeac19467 100644
--- a/arch/powerpc/include/asm/nohash/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/pgtable.h
@@ -8,6 +8,33 @@
 #include 
 #endif
 
+/* Permission masks used for kernel mappings */
+#define PAGE_KERNEL__pgprot(_PAGE_BASE | _PAGE_KERNEL_RW)
+#define PAGE_KERNEL_NC __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | 
_PAGE_NO_CACHE)
+#define PAGE_KERNEL_NCG__pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
+_PAGE_NO_CACHE | _PAGE_GUARDED)
+#define PAGE_KERNEL_X  __pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX)
+#define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO)
+#define PAGE_KERNEL_ROX__pgprot(_PAGE_BASE | _PAGE_KERNEL_ROX)
+
+/* Protection used for kernel text. We want the debuggers to be able to
+ * set breakpoints anywhere, so don't write protect the kernel text
+ * on platforms where such control is possible.
+ */
+#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) 
||\
+   defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE)
+#define PAGE_KERNEL_TEXT   PAGE_KERNEL_X
+#else
+#define PAGE_KERNEL_TEXT   PAGE_KERNEL_ROX
+#endif
+
+/* Make modules code happy. We don't set RO yet */
+#define PAGE_KERNEL_EXEC   PAGE_KERNEL_X
+
+/* Advertise special mapping type for AGP */
+#define PAGE_AGP   (PAGE_KERNEL_NC)
+#define HAVE_PAGE_AGP
+
 #ifndef __ASSEMBLY__
 
 /* Generic accessors to PTE bits */
diff --git a/arch/powerpc/include/asm/pte-common.h 
b/arch/powerpc/include/asm/pte-common.h
index cce60b3ba7d4..4d594039bca5 100644
--- a/arch/powerpc/include/asm/pte-common.h
+++ b/arch/powerpc/include/asm/pte-common.h
@@ -14,9 +14,6 @@
 #ifndef _PAGE_WRITETHRU
 #define _PAGE_WRITETHRU0
 #endif
-#ifndef _PAGE_SAO
-#define _PAGE_SAO  0
-#endif
 /* _PAGE_RO and _PAGE_RW shall not be defined at the same time */
 #ifndef _PAGE_RO
 #define _PAGE_RO 0
@@ -61,35 +58,3 @@
  */
 #define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_DIRTY | \
  _PAGE_ACCESSED | _PAGE_SPECIAL)
-
-/* Permission masks used for kernel mappings */
-#define PAGE_KERNEL__pgprot(_PAGE_BASE | _PAGE_KERNEL_RW)
-#define PAGE_KERNEL_NC __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
-_PAGE_NO_CACHE)
-#define PAGE_KERNEL_NCG__pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
-_PAGE_NO_CACHE | _PAGE_GUARDED)
-#define PAGE_KERNEL_X  __pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX)
-#define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO)
-#define PAGE_KERNEL_ROX__pgprot(_PAGE_BASE | _PAGE_KERNEL_ROX)
-
-/* Protection used for kernel text. We want the debuggers to be able to
- * set breakpoints anywhere, so don't write protect the kernel text
- * on platforms where such control is possible.
- */
-#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) 
||\
-   defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE)
-#define PAGE_KERNEL_TEXT   PAGE_KERNEL_X
-#else
-#define PAGE_KERNEL_TEXT   PAGE_KERNEL_ROX
-#endif
-
-/* Make modules code happy. We don't set RO yet */
-#define PAGE_KERNEL_EXEC   PAGE_KERNEL_X
-
-/* Advertise special mapping type for AGP */
-#define PAGE_AGP   (PAGE_KERNEL_NC)
-#define HAVE_PAGE_AGP
-
-#ifndef H_PAGE_4K_PFN
-#define H_PAGE_4K_PFN 0
-#endif
-- 
2.13.3



[PATCH v3 18/24] powerpc/mm: Distribute platform specific PAGE and PMD flags and definitions

2018-10-09 Thread Christophe Leroy
The base kernel PAGE_ definition sets are more or less platform
specific. Lets distribute them close to platform _PAGE_XXX flags
definition, and customise them to their exact platform flags.

Also defines _PAGE_PSIZE and _PTE_NONE_MASK for each platform
allthough they are defined as 0.

Do the same with _PMD flags like _PMD_USER and _PMD_PRESENT_MASK

Reviewed-by: Aneesh Kumar K.V 
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/nohash/32/pte-40x.h   | 29 ++
 arch/powerpc/include/asm/nohash/32/pte-44x.h   | 35 
 arch/powerpc/include/asm/nohash/32/pte-8xx.h   | 27 +
 arch/powerpc/include/asm/nohash/32/pte-fsl-booke.h | 38 +
 arch/powerpc/include/asm/nohash/pte-book3e.h   | 30 ++
 arch/powerpc/include/asm/pte-common.h  | 66 --
 6 files changed, 159 insertions(+), 66 deletions(-)

diff --git a/arch/powerpc/include/asm/nohash/32/pte-40x.h 
b/arch/powerpc/include/asm/nohash/32/pte-40x.h
index bb4b3a4b92a0..2b48bc289a4d 100644
--- a/arch/powerpc/include/asm/nohash/32/pte-40x.h
+++ b/arch/powerpc/include/asm/nohash/32/pte-40x.h
@@ -50,13 +50,42 @@
 #define _PAGE_EXEC 0x200   /* hardware: EX permission */
 #define _PAGE_ACCESSED 0x400   /* software: R: page referenced */
 
+/* No page size encoding in the linux PTE */
+#define _PAGE_PSIZE0
+
+#define _PAGE_KERNEL_RO0
+#define _PAGE_KERNEL_ROX   _PAGE_EXEC
+#define _PAGE_KERNEL_RW(_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
+#define _PAGE_KERNEL_RWX   (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE | 
_PAGE_EXEC)
+
 #define _PMD_PRESENT   0x400   /* PMD points to page of PTEs */
+#define _PMD_PRESENT_MASK  _PMD_PRESENT
 #define _PMD_BAD   0x802
 #define _PMD_SIZE_4M   0x0c0
 #define _PMD_SIZE_16M  0x0e0
+#define _PMD_USER  0
+
+#define _PTE_NONE_MASK 0
 
 /* Until my rework is finished, 40x still needs atomic PTE updates */
 #define PTE_ATOMIC_UPDATES 1
 
+/* Mask of bits returned by pte_pgprot() */
+#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_NO_CACHE | \
+_PAGE_WRITETHRU | _PAGE_USER | _PAGE_ACCESSED | \
+_PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | _PAGE_EXEC)
+
+#define _PAGE_BASE_NC  (_PAGE_PRESENT | _PAGE_ACCESSED)
+#define _PAGE_BASE (_PAGE_BASE_NC)
+
+/* Permission masks used to generate the __P and __S table */
+#define PAGE_NONE  __pgprot(_PAGE_BASE)
+#define PAGE_SHARED__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
+#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | 
_PAGE_EXEC)
+#define PAGE_COPY  __pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_COPY_X__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+#define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_READONLY_X__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+
 #endif /* __KERNEL__ */
 #endif /*  _ASM_POWERPC_NOHASH_32_PTE_40x_H */
diff --git a/arch/powerpc/include/asm/nohash/32/pte-44x.h 
b/arch/powerpc/include/asm/nohash/32/pte-44x.h
index f812c0272364..8d6b268a986f 100644
--- a/arch/powerpc/include/asm/nohash/32/pte-44x.h
+++ b/arch/powerpc/include/asm/nohash/32/pte-44x.h
@@ -85,14 +85,49 @@
 #define _PAGE_NO_CACHE 0x0400  /* H: I bit */
 #define _PAGE_WRITETHRU0x0800  /* H: W bit */
 
+/* No page size encoding in the linux PTE */
+#define _PAGE_PSIZE0
+
+#define _PAGE_KERNEL_RO0
+#define _PAGE_KERNEL_ROX   _PAGE_EXEC
+#define _PAGE_KERNEL_RW(_PAGE_DIRTY | _PAGE_RW)
+#define _PAGE_KERNEL_RWX   (_PAGE_DIRTY | _PAGE_RW | _PAGE_EXEC)
+
+/* Mask of bits returned by pte_pgprot() */
+#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
+_PAGE_WRITETHRU | _PAGE_USER | _PAGE_ACCESSED | \
+_PAGE_RW | _PAGE_DIRTY | _PAGE_EXEC)
+
 /* TODO: Add large page lowmem mapping support */
 #define _PMD_PRESENT   0
 #define _PMD_PRESENT_MASK (PAGE_MASK)
 #define _PMD_BAD   (~PAGE_MASK)
+#define _PMD_USER  0
 
 /* ERPN in a PTE never gets cleared, ignore it */
 #define _PTE_NONE_MASK 0xULL
 
+/*
+ * We define 2 sets of base prot bits, one for basic pages (ie,
+ * cacheable kernel and user pages) and one for non cacheable
+ * pages. We always set _PAGE_COHERENT when SMP is enabled or
+ * the processor might need it for DMA coherency.
+ */
+#define _PAGE_BASE_NC  (_PAGE_PRESENT | _PAGE_ACCESSED)
+#if defined(CONFIG_SMP)
+#define _PAGE_BASE (_PAGE_BASE_NC | _PAGE_COHERENT)
+#else
+#define _PAGE_BASE (_PAGE_BASE_NC)
+#endif
+
+/* Permission masks used to generate the __P and __S table */
+#define PAGE_NONE  __pgprot(_PAGE_BASE)
+#define PAGE_SHARED__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
+#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | 
_PAGE_EXEC)
+#define PAGE_COPY  __pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_COPY_X  

[PATCH v3 17/24] powerpc/mm: Move pte_user() into nohash/pgtable.h

2018-10-09 Thread Christophe Leroy
Now the pte-common.h is only for nohash platforms, lets
move pte_user() helper out of pte-common.h to put it
together with other helpers.

Reviewed-by: Aneesh Kumar K.V 
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/nohash/pgtable.h | 10 ++
 arch/powerpc/include/asm/pte-common.h | 13 -
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/include/asm/nohash/pgtable.h 
b/arch/powerpc/include/asm/nohash/pgtable.h
index 062d96233673..8de3b7eb88b0 100644
--- a/arch/powerpc/include/asm/nohash/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/pgtable.h
@@ -52,6 +52,16 @@ static inline bool pte_hw_valid(pte_t pte)
 }
 
 /*
+ * Don't just check for any non zero bits in __PAGE_USER, since for book3e
+ * and PTE_64BIT, PAGE_KERNEL_X contains _PAGE_BAP_SR which is also in
+ * _PAGE_USER.  Need to explicitly match _PAGE_BAP_UR bit in that case too.
+ */
+static inline bool pte_user(pte_t pte)
+{
+   return (pte_val(pte) & (_PAGE_USER | _PAGE_PRIVILEGED)) == _PAGE_USER;
+}
+
+/*
  * We only find page table entry in the last level
  * Hence no need for other accessors
  */
diff --git a/arch/powerpc/include/asm/pte-common.h 
b/arch/powerpc/include/asm/pte-common.h
index 3a8ec18ffd22..556a914ff845 100644
--- a/arch/powerpc/include/asm/pte-common.h
+++ b/arch/powerpc/include/asm/pte-common.h
@@ -66,19 +66,6 @@
 #define _PTE_NONE_MASK 0
 #endif
 
-#ifndef __ASSEMBLY__
-
-/*
- * Don't just check for any non zero bits in __PAGE_USER, since for book3e
- * and PTE_64BIT, PAGE_KERNEL_X contains _PAGE_BAP_SR which is also in
- * _PAGE_USER.  Need to explicitly match _PAGE_BAP_UR bit in that case too.
- */
-static inline bool pte_user(pte_t pte)
-{
-   return (pte_val(pte) & (_PAGE_USER | _PAGE_PRIVILEGED)) == _PAGE_USER;
-}
-#endif /* __ASSEMBLY__ */
-
 /* Location of the PFN in the PTE. Most 32-bit platforms use the same
  * as _PAGE_SHIFT here (ie, naturally aligned).
  * Platform who don't just pre-define the value so we don't override it here
-- 
2.13.3



[PATCH v3 16/24] powerpc/book3s/32: do not include pte-common.h

2018-10-09 Thread Christophe Leroy
As done for book3s/64, add necessary flags/defines in
book3s/32/pgtable.h and do not include pte-common.h

It allows in the meantime to remove all related hash
definitions from pte-common.h and to also remove
_PAGE_EXEC default as _PAGE_EXEC is defined on all
platforms except book3s/32.

Reviewed-by: Aneesh Kumar K.V 
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/book3s/32/pgtable.h | 97 ++--
 arch/powerpc/include/asm/pte-common.h| 16 +
 2 files changed, 96 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h 
b/arch/powerpc/include/asm/book3s/32/pgtable.h
index a0dc3a3eef33..c28e8c6a27c2 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -8,7 +8,97 @@
 #include 
 
 /* And here we include common definitions */
-#include 
+
+#define _PAGE_KERNEL_RO0
+#define _PAGE_KERNEL_ROX   0
+#define _PAGE_KERNEL_RW(_PAGE_DIRTY | _PAGE_RW)
+#define _PAGE_KERNEL_RWX   (_PAGE_DIRTY | _PAGE_RW)
+
+#define _PAGE_HPTEFLAGS _PAGE_HASHPTE
+
+#ifndef __ASSEMBLY__
+
+static inline bool pte_user(pte_t pte)
+{
+   return pte_val(pte) & _PAGE_USER;
+}
+#endif /* __ASSEMBLY__ */
+
+/* Location of the PFN in the PTE. Most 32-bit platforms use the same
+ * as _PAGE_SHIFT here (ie, naturally aligned).
+ * Platform who don't just pre-define the value so we don't override it here
+ */
+#define PTE_RPN_SHIFT  (PAGE_SHIFT)
+
+/* The mask covered by the RPN must be a ULL on 32-bit platforms with
+ * 64-bit PTEs
+ */
+#ifdef CONFIG_PTE_64BIT
+#define PTE_RPN_MASK   (~((1ULL << PTE_RPN_SHIFT) - 1))
+#else
+#define PTE_RPN_MASK   (~((1UL << PTE_RPN_SHIFT) - 1))
+#endif
+
+/* _PAGE_CHG_MASK masks of bits that are to be preserved across
+ * pgprot changes
+ */
+#define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HASHPTE | _PAGE_DIRTY | \
+_PAGE_ACCESSED | _PAGE_SPECIAL)
+
+/* Mask of bits returned by pte_pgprot() */
+#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
+_PAGE_WRITETHRU | _PAGE_USER | _PAGE_ACCESSED | \
+_PAGE_RW | _PAGE_DIRTY)
+
+/*
+ * We define 2 sets of base prot bits, one for basic pages (ie,
+ * cacheable kernel and user pages) and one for non cacheable
+ * pages. We always set _PAGE_COHERENT when SMP is enabled or
+ * the processor might need it for DMA coherency.
+ */
+#define _PAGE_BASE_NC  (_PAGE_PRESENT | _PAGE_ACCESSED)
+#define _PAGE_BASE (_PAGE_BASE_NC | _PAGE_COHERENT)
+
+/* Permission masks used to generate the __P and __S table,
+ *
+ * Note:__pgprot is defined in arch/powerpc/include/asm/page.h
+ *
+ * Write permissions imply read permissions for now.
+ */
+#define PAGE_NONE  __pgprot(_PAGE_BASE)
+#define PAGE_SHARED__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
+#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
+#define PAGE_COPY  __pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_COPY_X__pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_READONLY_X__pgprot(_PAGE_BASE | _PAGE_USER)
+
+/* Permission masks used for kernel mappings */
+#define PAGE_KERNEL__pgprot(_PAGE_BASE | _PAGE_KERNEL_RW)
+#define PAGE_KERNEL_NC __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | 
_PAGE_NO_CACHE)
+#define PAGE_KERNEL_NCG__pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
+_PAGE_NO_CACHE | _PAGE_GUARDED)
+#define PAGE_KERNEL_X  __pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX)
+#define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO)
+#define PAGE_KERNEL_ROX__pgprot(_PAGE_BASE | _PAGE_KERNEL_ROX)
+
+/* Protection used for kernel text. We want the debuggers to be able to
+ * set breakpoints anywhere, so don't write protect the kernel text
+ * on platforms where such control is possible.
+ */
+#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) 
||\
+   defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE)
+#define PAGE_KERNEL_TEXT   PAGE_KERNEL_X
+#else
+#define PAGE_KERNEL_TEXT   PAGE_KERNEL_ROX
+#endif
+
+/* Make modules code happy. We don't set RO yet */
+#define PAGE_KERNEL_EXEC   PAGE_KERNEL_X
+
+/* Advertise special mapping type for AGP */
+#define PAGE_AGP   (PAGE_KERNEL_NC)
+#define HAVE_PAGE_AGP
 
 #define PTE_INDEX_SIZE PTE_SHIFT
 #define PMD_INDEX_SIZE 0
@@ -219,7 +309,7 @@ static inline pte_t ptep_get_and_clear(struct mm_struct 
*mm, unsigned long addr,
 static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
  pte_t *ptep)
 {
-   pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO);
+   pte_update(ptep, _PAGE_RW, 0);
 }
 static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
   unsigned long addr, pte_t *ptep)
@@ -235,9 +325,8 @@ static 

[PATCH v3 15/24] powerpc/mm: move __P and __S tables in the common pgtable.h

2018-10-09 Thread Christophe Leroy
__P and __S flags are the same for all platform and should remain
as is in the future, so avoid duplication.

Reviewed-by: Aneesh Kumar K.V 
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/book3s/64/pgtable.h | 20 
 arch/powerpc/include/asm/pgtable.h   | 19 +++
 arch/powerpc/include/asm/pte-common.h| 20 
 3 files changed, 19 insertions(+), 40 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h 
b/arch/powerpc/include/asm/book3s/64/pgtable.h
index f80f436834a1..cf8dbd5f8f03 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -151,8 +151,6 @@
  * Write permissions imply read permissions for now (we could make write-only
  * pages on BookE but we don't bother for now). Execute permission control is
  * possible on platforms that define _PAGE_EXEC
- *
- * Note due to the way vm flags are laid out, the bits are XWR
  */
 #define PAGE_NONE  __pgprot(_PAGE_BASE | _PAGE_PRIVILEGED)
 #define PAGE_SHARED__pgprot(_PAGE_BASE | _PAGE_RW)
@@ -162,24 +160,6 @@
 #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_READ)
 #define PAGE_READONLY_X__pgprot(_PAGE_BASE | _PAGE_READ | _PAGE_EXEC)
 
-#define __P000 PAGE_NONE
-#define __P001 PAGE_READONLY
-#define __P010 PAGE_COPY
-#define __P011 PAGE_COPY
-#define __P100 PAGE_READONLY_X
-#define __P101 PAGE_READONLY_X
-#define __P110 PAGE_COPY_X
-#define __P111 PAGE_COPY_X
-
-#define __S000 PAGE_NONE
-#define __S001 PAGE_READONLY
-#define __S010 PAGE_SHARED
-#define __S011 PAGE_SHARED
-#define __S100 PAGE_READONLY_X
-#define __S101 PAGE_READONLY_X
-#define __S110 PAGE_SHARED_X
-#define __S111 PAGE_SHARED_X
-
 /* Permission masks used for kernel mappings */
 #define PAGE_KERNEL__pgprot(_PAGE_BASE | _PAGE_KERNEL_RW)
 #define PAGE_KERNEL_NC __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
diff --git a/arch/powerpc/include/asm/pgtable.h 
b/arch/powerpc/include/asm/pgtable.h
index 14c79a7dc855..fb4b85bba110 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -20,6 +20,25 @@ struct mm_struct;
 #include 
 #endif /* !CONFIG_PPC_BOOK3S */
 
+/* Note due to the way vm flags are laid out, the bits are XWR */
+#define __P000 PAGE_NONE
+#define __P001 PAGE_READONLY
+#define __P010 PAGE_COPY
+#define __P011 PAGE_COPY
+#define __P100 PAGE_READONLY_X
+#define __P101 PAGE_READONLY_X
+#define __P110 PAGE_COPY_X
+#define __P111 PAGE_COPY_X
+
+#define __S000 PAGE_NONE
+#define __S001 PAGE_READONLY
+#define __S010 PAGE_SHARED
+#define __S011 PAGE_SHARED
+#define __S100 PAGE_READONLY_X
+#define __S101 PAGE_READONLY_X
+#define __S110 PAGE_SHARED_X
+#define __S111 PAGE_SHARED_X
+
 #ifndef __ASSEMBLY__
 
 #include 
diff --git a/arch/powerpc/include/asm/pte-common.h 
b/arch/powerpc/include/asm/pte-common.h
index 5a5ba43bdf98..4860dae76dae 100644
--- a/arch/powerpc/include/asm/pte-common.h
+++ b/arch/powerpc/include/asm/pte-common.h
@@ -139,8 +139,6 @@ static inline bool pte_user(pte_t pte)
  * Write permissions imply read permissions for now (we could make write-only
  * pages on BookE but we don't bother for now). Execute permission control is
  * possible on platforms that define _PAGE_EXEC
- *
- * Note due to the way vm flags are laid out, the bits are XWR
  */
 #define PAGE_NONE  __pgprot(_PAGE_BASE | _PAGE_NA)
 #define PAGE_SHARED__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
@@ -153,24 +151,6 @@ static inline bool pte_user(pte_t pte)
 #define PAGE_READONLY_X__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RO | \
 _PAGE_EXEC)
 
-#define __P000 PAGE_NONE
-#define __P001 PAGE_READONLY
-#define __P010 PAGE_COPY
-#define __P011 PAGE_COPY
-#define __P100 PAGE_READONLY_X
-#define __P101 PAGE_READONLY_X
-#define __P110 PAGE_COPY_X
-#define __P111 PAGE_COPY_X
-
-#define __S000 PAGE_NONE
-#define __S001 PAGE_READONLY
-#define __S010 PAGE_SHARED
-#define __S011 PAGE_SHARED
-#define __S100 PAGE_READONLY_X
-#define __S101 PAGE_READONLY_X
-#define __S110 PAGE_SHARED_X
-#define __S111 PAGE_SHARED_X
-
 /* Permission masks used for kernel mappings */
 #define PAGE_KERNEL__pgprot(_PAGE_BASE | _PAGE_KERNEL_RW)
 #define PAGE_KERNEL_NC __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
-- 
2.13.3



[PATCH v3 14/24] powerpc/mm: drop unused page flags

2018-10-09 Thread Christophe Leroy
The following page flags in pte-common.h can be dropped:

_PAGE_ENDIAN is only used in mm/fsl_booke_mmu.c and is defined in
asm/nohash/32/pte-fsl-booke.h

_PAGE_4K_PFN is nowhere defined nor used

_PAGE_READ, _PAGE_WRITE and _PAGE_PTE are only defined and used
in book3s/64

The following page flags in book3s/64/pgtable.h can be dropped as
they are not used on this platform nor by common code.

_PAGE_NA, _PAGE_RO, _PAGE_USER and _PAGE_PSIZE

Reviewed-by: Aneesh Kumar K.V 
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/book3s/64/pgtable.h | 10 +-
 arch/powerpc/include/asm/pte-common.h| 17 +
 2 files changed, 2 insertions(+), 25 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h 
b/arch/powerpc/include/asm/book3s/64/pgtable.h
index c8564762b6f0..f80f436834a1 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -14,10 +14,6 @@
  */
 #define _PAGE_BIT_SWAP_TYPE0
 
-#define _PAGE_NA   0
-#define _PAGE_RO   0
-#define _PAGE_USER 0
-
 #define _PAGE_EXEC 0x1 /* execute permission */
 #define _PAGE_WRITE0x2 /* write access allowed */
 #define _PAGE_READ 0x4 /* read access allowed */
@@ -123,10 +119,6 @@
 #define _PAGE_KERNEL_RWX   (_PAGE_PRIVILEGED | _PAGE_DIRTY |   \
 _PAGE_RW | _PAGE_EXEC)
 /*
- * No page size encoding in the linux PTE
- */
-#define _PAGE_PSIZE0
-/*
  * _PAGE_CHG_MASK masks of bits that are to be preserved across
  * pgprot changes
  */
@@ -149,7 +141,7 @@
  * pages. We always set _PAGE_COHERENT when SMP is enabled or
  * the processor might need it for DMA coherency.
  */
-#define _PAGE_BASE_NC  (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_PSIZE)
+#define _PAGE_BASE_NC  (_PAGE_PRESENT | _PAGE_ACCESSED)
 #define _PAGE_BASE (_PAGE_BASE_NC)
 
 /* Permission masks used to generate the __P and __S table,
diff --git a/arch/powerpc/include/asm/pte-common.h 
b/arch/powerpc/include/asm/pte-common.h
index bef56141a549..5a5ba43bdf98 100644
--- a/arch/powerpc/include/asm/pte-common.h
+++ b/arch/powerpc/include/asm/pte-common.h
@@ -14,18 +14,12 @@
 #ifndef _PAGE_EXEC
 #define _PAGE_EXEC 0
 #endif
-#ifndef _PAGE_ENDIAN
-#define _PAGE_ENDIAN   0
-#endif
 #ifndef _PAGE_COHERENT
 #define _PAGE_COHERENT 0
 #endif
 #ifndef _PAGE_WRITETHRU
 #define _PAGE_WRITETHRU0
 #endif
-#ifndef _PAGE_4K_PFN
-#define _PAGE_4K_PFN   0
-#endif
 #ifndef _PAGE_SAO
 #define _PAGE_SAO  0
 #endif
@@ -39,9 +33,6 @@
 #define _PAGE_RW 0
 #endif
 
-#ifndef _PAGE_PTE
-#define _PAGE_PTE 0
-#endif
 /* At least one of _PAGE_PRIVILEGED or _PAGE_USER must be defined */
 #ifndef _PAGE_PRIVILEGED
 #define _PAGE_PRIVILEGED 0
@@ -122,7 +113,7 @@ static inline bool pte_user(pte_t pte)
 
 /* Mask of bits returned by pte_pgprot() */
 #define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
-_PAGE_WRITETHRU | _PAGE_ENDIAN | _PAGE_4K_PFN | \
+_PAGE_WRITETHRU | \
 _PAGE_USER | _PAGE_ACCESSED | _PAGE_RO | _PAGE_NA | \
 _PAGE_PRIVILEGED | \
 _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | _PAGE_EXEC)
@@ -208,12 +199,6 @@ static inline bool pte_user(pte_t pte)
 #define PAGE_AGP   (PAGE_KERNEL_NC)
 #define HAVE_PAGE_AGP
 
-#ifndef _PAGE_READ
-/* if not defined, we should not find _PAGE_WRITE too */
-#define _PAGE_READ 0
-#define _PAGE_WRITE _PAGE_RW
-#endif
-
 #ifndef H_PAGE_4K_PFN
 #define H_PAGE_4K_PFN 0
 #endif
-- 
2.13.3



[PATCH v3 13/24] powerpc/mm: Split dump_pagelinuxtables flag_array table

2018-10-09 Thread Christophe Leroy
To reduce the complexity of flag_array, and allow the removal of
default 0 value of non existing flags, lets have one flag_array
table for each platform family with only the really existing flags.

Reviewed-by: Aneesh Kumar K.V 
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/mm/Makefile|   7 ++
 arch/powerpc/mm/dump_linuxpagetables-8xx.c  |  82 +
 arch/powerpc/mm/dump_linuxpagetables-book3s64.c | 115 ++
 arch/powerpc/mm/dump_linuxpagetables-generic.c  |  82 +
 arch/powerpc/mm/dump_linuxpagetables.c  | 155 +---
 arch/powerpc/mm/dump_linuxpagetables.h  |  19 +++
 6 files changed, 307 insertions(+), 153 deletions(-)
 create mode 100644 arch/powerpc/mm/dump_linuxpagetables-8xx.c
 create mode 100644 arch/powerpc/mm/dump_linuxpagetables-book3s64.c
 create mode 100644 arch/powerpc/mm/dump_linuxpagetables-generic.c
 create mode 100644 arch/powerpc/mm/dump_linuxpagetables.h

diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index cdf6a9960046..3c844bdd16c4 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -43,5 +43,12 @@ obj-$(CONFIG_HIGHMEM)+= highmem.o
 obj-$(CONFIG_PPC_COPRO_BASE)   += copro_fault.o
 obj-$(CONFIG_SPAPR_TCE_IOMMU)  += mmu_context_iommu.o
 obj-$(CONFIG_PPC_PTDUMP)   += dump_linuxpagetables.o
+ifdef CONFIG_PPC_PTDUMP
+obj-$(CONFIG_4xx)  += dump_linuxpagetables-generic.o
+obj-$(CONFIG_PPC_8xx)  += dump_linuxpagetables-8xx.o
+obj-$(CONFIG_PPC_BOOK3E_MMU)   += dump_linuxpagetables-generic.o
+obj-$(CONFIG_PPC_BOOK3S_32)+= dump_linuxpagetables-generic.o
+obj-$(CONFIG_PPC_BOOK3S_64)+= dump_linuxpagetables-book3s64.o
+endif
 obj-$(CONFIG_PPC_HTDUMP)   += dump_hashpagetable.o
 obj-$(CONFIG_PPC_MEM_KEYS) += pkeys.o
diff --git a/arch/powerpc/mm/dump_linuxpagetables-8xx.c 
b/arch/powerpc/mm/dump_linuxpagetables-8xx.c
new file mode 100644
index ..33f52a97975b
--- /dev/null
+++ b/arch/powerpc/mm/dump_linuxpagetables-8xx.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * From split of dump_linuxpagetables.c
+ * Copyright 2016, Rashmica Gupta, IBM Corp.
+ *
+ */
+#include 
+#include 
+
+#include "dump_linuxpagetables.h"
+
+static const struct flag_info flag_array[] = {
+   {
+   .mask   = _PAGE_PRIVILEGED,
+   .val= 0,
+   .set= "user",
+   .clear  = "",
+   }, {
+   .mask   = _PAGE_RO | _PAGE_NA,
+   .val= 0,
+   .set= "rw",
+   }, {
+   .mask   = _PAGE_RO | _PAGE_NA,
+   .val= _PAGE_RO,
+   .set= "r ",
+   }, {
+   .mask   = _PAGE_RO | _PAGE_NA,
+   .val= _PAGE_NA,
+   .set= "  ",
+   }, {
+   .mask   = _PAGE_EXEC,
+   .val= _PAGE_EXEC,
+   .set= " X ",
+   .clear  = "   ",
+   }, {
+   .mask   = _PAGE_PRESENT,
+   .val= _PAGE_PRESENT,
+   .set= "present",
+   .clear  = "   ",
+   }, {
+   .mask   = _PAGE_GUARDED,
+   .val= _PAGE_GUARDED,
+   .set= "guarded",
+   .clear  = "   ",
+   }, {
+   .mask   = _PAGE_DIRTY,
+   .val= _PAGE_DIRTY,
+   .set= "dirty",
+   .clear  = " ",
+   }, {
+   .mask   = _PAGE_ACCESSED,
+   .val= _PAGE_ACCESSED,
+   .set= "accessed",
+   .clear  = "",
+   }, {
+   .mask   = _PAGE_NO_CACHE,
+   .val= _PAGE_NO_CACHE,
+   .set= "no cache",
+   .clear  = "",
+   }, {
+   .mask   = _PAGE_SPECIAL,
+   .val= _PAGE_SPECIAL,
+   .set= "special",
+   }
+};
+
+struct pgtable_level pg_level[5] = {
+   {
+   }, { /* pgd */
+   .flag   = flag_array,
+   .num= ARRAY_SIZE(flag_array),
+   }, { /* pud */
+   .flag   = flag_array,
+   .num= ARRAY_SIZE(flag_array),
+   }, { /* pmd */
+   .flag   = flag_array,
+   .num= ARRAY_SIZE(flag_array),
+   }, { /* pte */
+   .flag   = flag_array,
+   .num= ARRAY_SIZE(flag_array),
+   },
+};
diff --git a/arch/powerpc/mm/dump_linuxpagetables-book3s64.c 
b/arch/powerpc/mm/dump_linuxpagetables-book3s64.c
new file mode 100644
index ..a637e612b205
--- /dev/null
+++ b/arch/powerpc/mm/dump_linuxpagetables-book3s64.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * From split of dump_linuxpagetables.c
+ * Copyright 2016, Rashmica Gupta, IBM Corp.
+ *
+ */
+#include 
+#include 
+
+#include "dump_linuxpagetables.h"
+
+static const struct flag_info 

[PATCH v3 12/24] powerpc/mm: use pte helpers in generic code

2018-10-09 Thread Christophe Leroy
Get rid of platform specific _PAGE_ in powerpc common code and
use helpers instead.

mm/dump_linuxpagetables.c will be handled separately

Reviewed-by: Aneesh Kumar K.V 
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/book3s/32/pgtable.h |  9 +++--
 arch/powerpc/include/asm/nohash/32/pgtable.h | 12 
 arch/powerpc/include/asm/nohash/pgtable.h|  3 +--
 arch/powerpc/mm/pgtable.c| 21 +++--
 arch/powerpc/mm/pgtable_32.c | 15 ---
 arch/powerpc/mm/pgtable_64.c | 14 +++---
 arch/powerpc/xmon/xmon.c | 12 +++-
 7 files changed, 41 insertions(+), 45 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h 
b/arch/powerpc/include/asm/book3s/32/pgtable.h
index a6ca799e0eb5..a0dc3a3eef33 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -331,17 +331,14 @@ static inline bool pte_ci(pte_t pte)
 #define pte_access_permitted pte_access_permitted
 static inline bool pte_access_permitted(pte_t pte, bool write)
 {
-   unsigned long pteval = pte_val(pte);
/*
 * A read-only access is controlled by _PAGE_USER bit.
 * We have _PAGE_READ set for WRITE and EXECUTE
 */
-   unsigned long need_pte_bits = _PAGE_PRESENT | _PAGE_USER;
-
-   if (write)
-   need_pte_bits |= _PAGE_WRITE;
+   if (!pte_present(pte) || !pte_user(pte) || !pte_read(pte))
+   return false;
 
-   if ((pteval & need_pte_bits) != need_pte_bits)
+   if (write && !pte_write(pte))
return false;
 
return true;
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h 
b/arch/powerpc/include/asm/nohash/32/pgtable.h
index 6fecfd7854f5..a4156da4a7a4 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -277,7 +277,10 @@ static inline pte_t ptep_get_and_clear(struct mm_struct 
*mm, unsigned long addr,
 static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
  pte_t *ptep)
 {
-   pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO);
+   unsigned long clr = ~pte_val(pte_wrprotect(__pte(~0)));
+   unsigned long set = pte_val(pte_wrprotect(__pte(0)));
+
+   pte_update(ptep, clr, set);
 }
 static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
   unsigned long addr, pte_t *ptep)
@@ -291,9 +294,10 @@ static inline void __ptep_set_access_flags(struct 
vm_area_struct *vma,
   unsigned long address,
   int psize)
 {
-   unsigned long set = pte_val(entry) &
-   (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
-   unsigned long clr = ~pte_val(entry) & (_PAGE_RO | _PAGE_NA);
+   pte_t pte_set = 
pte_mkyoung(pte_mkdirty(pte_mkwrite(pte_mkexec(__pte(0);
+   pte_t pte_clr = 
pte_mkyoung(pte_mkdirty(pte_mkwrite(pte_mkexec(__pte(~0);
+   unsigned long set = pte_val(entry) & pte_val(pte_set);
+   unsigned long clr = ~pte_val(entry) & ~pte_val(pte_clr);
 
pte_update(ptep, clr, set);
 
diff --git a/arch/powerpc/include/asm/nohash/pgtable.h 
b/arch/powerpc/include/asm/nohash/pgtable.h
index b256e38a047c..062d96233673 100644
--- a/arch/powerpc/include/asm/nohash/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/pgtable.h
@@ -32,8 +32,7 @@ static inline pgprot_t pte_pgprot(pte_t pte)  { return 
__pgprot(pte_val(pte) & PA
  */
 static inline int pte_protnone(pte_t pte)
 {
-   return (pte_val(pte) &
-   (_PAGE_PRESENT | _PAGE_USER)) == _PAGE_PRESENT;
+   return pte_present(pte) && !pte_user(pte);
 }
 
 static inline int pmd_protnone(pmd_t pmd)
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index f97d9c3760e3..ca4b1f7ac39d 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -44,20 +44,13 @@ static inline int is_exec_fault(void)
 static inline int pte_looks_normal(pte_t pte)
 {
 
-#if defined(CONFIG_PPC_BOOK3S_64)
-   if ((pte_val(pte) & (_PAGE_PRESENT | _PAGE_SPECIAL)) == _PAGE_PRESENT) {
+   if (pte_present(pte) && !pte_special(pte)) {
if (pte_ci(pte))
return 0;
if (pte_user(pte))
return 1;
}
return 0;
-#else
-   return (pte_val(pte) &
-   (_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE | _PAGE_USER |
-_PAGE_PRIVILEGED)) ==
-   (_PAGE_PRESENT | _PAGE_USER);
-#endif
 }
 
 static struct page *maybe_pte_to_page(pte_t pte)
@@ -117,7 +110,7 @@ static pte_t set_pte_filter(pte_t pte)
struct page *pg;
 
/* No exec permission in the first place, move on */
-   if (!(pte_val(pte) & _PAGE_EXEC) || !pte_looks_normal(pte))
+   if 

[PATCH v3 11/24] powerpc/mm: don't use _PAGE_EXEC for calling hash_preload()

2018-10-09 Thread Christophe Leroy
The 'access' parameter of hash_preload() is either 0 or _PAGE_EXEC.
Among the two versions of hash_preload(), only the PPC64 one is
doing something with this 'access' parameter.

In order to remove the use of _PAGE_EXEC outside platform code,
'access' parameter is replaced by 'is_exec' which will be either
true of false, and the PPC64 version of hash_preload() creates
the access flag based on 'is_exec'.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/mm/hash_utils_64.c | 3 ++-
 arch/powerpc/mm/mem.c   | 9 +
 arch/powerpc/mm/mmu_decl.h  | 2 +-
 arch/powerpc/mm/pgtable_32.c| 2 +-
 arch/powerpc/mm/ppc_mmu_32.c| 2 +-
 5 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 8ff03c7205a0..854edc3722e0 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -1482,7 +1482,7 @@ static bool should_hash_preload(struct mm_struct *mm, 
unsigned long ea)
 #endif
 
 void hash_preload(struct mm_struct *mm, unsigned long ea,
- unsigned long access, unsigned long trap)
+ bool is_exec, unsigned long trap)
 {
int hugepage_shift;
unsigned long vsid;
@@ -1490,6 +1490,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
pte_t *ptep;
unsigned long flags;
int rc, ssize, update_flags = 0;
+   unsigned long access = _PAGE_PRESENT | _PAGE_READ | (is_exec ? 
_PAGE_EXEC : 0);
 
BUG_ON(REGION_ID(ea) != USER_REGION_ID);
 
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index cb421aeb7674..dd949d6649a2 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -509,7 +509,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned 
long address,
 * We don't need to worry about _PAGE_PRESENT here because we are
 * called with either mm->page_table_lock held or ptl lock held
 */
-   unsigned long access, trap;
+   unsigned long trap;
+   bool is_exec;
 
if (radix_enabled()) {
prefetch((void *)address);
@@ -531,16 +532,16 @@ void update_mmu_cache(struct vm_area_struct *vma, 
unsigned long address,
trap = current->thread.regs ? TRAP(current->thread.regs) : 0UL;
switch (trap) {
case 0x300:
-   access = 0UL;
+   is_exec = false;
break;
case 0x400:
-   access = _PAGE_EXEC;
+   is_exec = true;
break;
default:
return;
}
 
-   hash_preload(vma->vm_mm, address, access, trap);
+   hash_preload(vma->vm_mm, address, is_exec, trap);
 #endif /* CONFIG_PPC_STD_MMU */
 #if (defined(CONFIG_PPC_BOOK3E_64) || defined(CONFIG_PPC_FSL_BOOK3E)) \
&& defined(CONFIG_HUGETLB_PAGE)
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index e5d779eed181..dd7f9b951d25 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -82,7 +82,7 @@ static inline void _tlbivax_bcast(unsigned long address, 
unsigned int pid,
 #else /* CONFIG_PPC_MMU_NOHASH */
 
 extern void hash_preload(struct mm_struct *mm, unsigned long ea,
-unsigned long access, unsigned long trap);
+bool is_exec, unsigned long trap);
 
 
 extern void _tlbie(unsigned long address);
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 0bbc7b7d8a05..01f348938328 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -261,7 +261,7 @@ static void __init __mapin_ram_chunk(unsigned long offset, 
unsigned long top)
map_kernel_page(v, p, ktext ? PAGE_KERNEL_TEXT : PAGE_KERNEL);
 #ifdef CONFIG_PPC_STD_MMU_32
if (ktext)
-   hash_preload(_mm, v, 0, 0x300);
+   hash_preload(_mm, v, false, 0x300);
 #endif
v += PAGE_SIZE;
p += PAGE_SIZE;
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index bea6c544e38f..38a793bfca37 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -163,7 +163,7 @@ void __init setbat(int index, unsigned long virt, 
phys_addr_t phys,
  * Preload a translation in the hash table
  */
 void hash_preload(struct mm_struct *mm, unsigned long ea,
- unsigned long access, unsigned long trap)
+ bool is_exec, unsigned long trap)
 {
pmd_t *pmd;
 
-- 
2.13.3



[PATCH v3 09/24] powerpc/mm: move some nohash pte helpers in nohash/[32:64]/pgtable.h

2018-10-09 Thread Christophe Leroy
In order to allow their use in nohash/32/pgtable.h, we have to move the
following helpers in nohash/[32:64]/pgtable.h:
- pte_mkwrite()
- pte_mkdirty()
- pte_mkyoung()
- pte_wrprotect()

Reviewed-by: Aneesh Kumar K.V 
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/nohash/32/pgtable.h | 28 
 arch/powerpc/include/asm/nohash/64/pgtable.h | 20 
 arch/powerpc/include/asm/nohash/pgtable.h| 28 
 3 files changed, 48 insertions(+), 28 deletions(-)

diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h 
b/arch/powerpc/include/asm/nohash/32/pgtable.h
index a7f44498ab6f..4373f8c44b6d 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -136,6 +136,34 @@ extern int icache_44x_need_flush;
 #define pte_clear(mm, addr, ptep) \
do { pte_update(ptep, ~0, 0); } while (0)
 
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+   pte_basic_t ptev;
+
+   ptev = pte_val(pte) & ~_PAGE_RO;
+   ptev |= _PAGE_RW;
+   return __pte(ptev);
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+   return __pte(pte_val(pte) | _PAGE_DIRTY);
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+   return __pte(pte_val(pte) | _PAGE_ACCESSED);
+}
+
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+   pte_basic_t ptev;
+
+   ptev = pte_val(pte) & ~(_PAGE_RW | _PAGE_HWWRITE);
+   ptev |= _PAGE_RO;
+   return __pte(ptev);
+}
+
 #define pmd_none(pmd)  (!pmd_val(pmd))
 #definepmd_bad(pmd)(pmd_val(pmd) & _PMD_BAD)
 #definepmd_present(pmd)(pmd_val(pmd) & _PMD_PRESENT_MASK)
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h 
b/arch/powerpc/include/asm/nohash/64/pgtable.h
index 513b6e9e62c6..72dac522aa66 100644
--- a/arch/powerpc/include/asm/nohash/64/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
@@ -94,6 +94,26 @@
 #ifndef __ASSEMBLY__
 /* pte_clear moved to later in this file */
 
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+   return __pte(pte_val(pte) | _PAGE_RW);
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+   return __pte(pte_val(pte) | _PAGE_DIRTY);
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+   return __pte(pte_val(pte) | _PAGE_ACCESSED);
+}
+
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+   return __pte(pte_val(pte) & ~_PAGE_RW);
+}
+
 #define PMD_BAD_BITS   (PTE_TABLE_SIZE-1)
 #define PUD_BAD_BITS   (PMD_TABLE_SIZE-1)
 
diff --git a/arch/powerpc/include/asm/nohash/pgtable.h 
b/arch/powerpc/include/asm/nohash/pgtable.h
index 5b82e44c4231..c746e9e784cd 100644
--- a/arch/powerpc/include/asm/nohash/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/pgtable.h
@@ -77,15 +77,6 @@ static inline unsigned long pte_pfn(pte_t pte)   {
return pte_val(pte) >> PTE_RPN_SHIFT; }
 
 /* Generic modifiers for PTE bits */
-static inline pte_t pte_wrprotect(pte_t pte)
-{
-   pte_basic_t ptev;
-
-   ptev = pte_val(pte) & ~(_PAGE_RW | _PAGE_HWWRITE);
-   ptev |= _PAGE_RO;
-   return __pte(ptev);
-}
-
 static inline pte_t pte_mkclean(pte_t pte)
 {
return __pte(pte_val(pte) & ~(_PAGE_DIRTY | _PAGE_HWWRITE));
@@ -96,25 +87,6 @@ static inline pte_t pte_mkold(pte_t pte)
return __pte(pte_val(pte) & ~_PAGE_ACCESSED);
 }
 
-static inline pte_t pte_mkwrite(pte_t pte)
-{
-   pte_basic_t ptev;
-
-   ptev = pte_val(pte) & ~_PAGE_RO;
-   ptev |= _PAGE_RW;
-   return __pte(ptev);
-}
-
-static inline pte_t pte_mkdirty(pte_t pte)
-{
-   return __pte(pte_val(pte) | _PAGE_DIRTY);
-}
-
-static inline pte_t pte_mkyoung(pte_t pte)
-{
-   return __pte(pte_val(pte) | _PAGE_ACCESSED);
-}
-
 static inline pte_t pte_mkspecial(pte_t pte)
 {
return __pte(pte_val(pte) | _PAGE_SPECIAL);
-- 
2.13.3



[PATCH v3 10/24] powerpc/mm: add pte helpers to query and change pte flags

2018-10-09 Thread Christophe Leroy
In order to avoid using generic _PAGE_XXX flags in powerpc
core functions, define helpers for all needed flags:
- pte_mkuser() and pte_mkprivileged() to set/unset and/or
unset/set _PAGE_USER and/or _PAGE_PRIVILEGED
- pte_hashpte() to check if _PAGE_HASHPTE is set.
- pte_ci() check if cache is inhibited (already existing on book3s/64)
- pte_exprotect() to protect against execution
- pte_exec() and pte_mkexec() to query and set page execution
- pte_mkpte() to set _PAGE_PTE flag.
- pte_hw_valid() to check _PAGE_PRESENT since pte_present does
something different on book3s/64.

On book3s/32 there is no exec protection, so pte_mkexec() and
pte_exprotect() are nops and pte_exec() returns always true.

Reviewed-by: Aneesh Kumar K.V 
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/book3s/32/pgtable.h | 41 
 arch/powerpc/include/asm/book3s/64/pgtable.h | 35 
 arch/powerpc/include/asm/nohash/32/pgtable.h |  5 
 arch/powerpc/include/asm/nohash/64/pgtable.h |  5 
 arch/powerpc/include/asm/nohash/pgtable.h| 28 +++
 5 files changed, 114 insertions(+)

diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h 
b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 3127cc529aa1..a6ca799e0eb5 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -301,6 +301,7 @@ static inline int pte_dirty(pte_t pte)  { 
return !!(pte_val(pte) & _PAGE_DIRTY);
 static inline int pte_young(pte_t pte) { return !!(pte_val(pte) & 
_PAGE_ACCESSED); }
 static inline int pte_special(pte_t pte)   { return !!(pte_val(pte) & 
_PAGE_SPECIAL); }
 static inline int pte_none(pte_t pte)  { return (pte_val(pte) & 
~_PTE_NONE_MASK) == 0; }
+static inline bool pte_exec(pte_t pte) { return true; }
 static inline pgprot_t pte_pgprot(pte_t pte)   { return __pgprot(pte_val(pte) 
& PAGE_PROT_BITS); }
 
 static inline int pte_present(pte_t pte)
@@ -308,6 +309,21 @@ static inline int pte_present(pte_t pte)
return pte_val(pte) & _PAGE_PRESENT;
 }
 
+static inline bool pte_hw_valid(pte_t pte)
+{
+   return pte_val(pte) & _PAGE_PRESENT;
+}
+
+static inline bool pte_hashpte(pte_t pte)
+{
+   return !!(pte_val(pte) & _PAGE_HASHPTE);
+}
+
+static inline bool pte_ci(pte_t pte)
+{
+   return !!(pte_val(pte) & _PAGE_NO_CACHE);
+}
+
 /*
  * We only find page table entry in the last level
  * Hence no need for other accessors
@@ -354,6 +370,11 @@ static inline pte_t pte_wrprotect(pte_t pte)
return __pte(pte_val(pte) & ~_PAGE_RW);
 }
 
+static inline pte_t pte_exprotect(pte_t pte)
+{
+   return pte;
+}
+
 static inline pte_t pte_mkclean(pte_t pte)
 {
return __pte(pte_val(pte) & ~_PAGE_DIRTY);
@@ -364,6 +385,16 @@ static inline pte_t pte_mkold(pte_t pte)
return __pte(pte_val(pte) & ~_PAGE_ACCESSED);
 }
 
+static inline pte_t pte_mkexec(pte_t pte)
+{
+   return pte;
+}
+
+static inline pte_t pte_mkpte(pte_t pte)
+{
+   return pte;
+}
+
 static inline pte_t pte_mkwrite(pte_t pte)
 {
return __pte(pte_val(pte) | _PAGE_RW);
@@ -389,6 +420,16 @@ static inline pte_t pte_mkhuge(pte_t pte)
return pte;
 }
 
+static inline pte_t pte_mkprivileged(pte_t pte)
+{
+   return __pte(pte_val(pte) & ~_PAGE_USER);
+}
+
+static inline pte_t pte_mkuser(pte_t pte)
+{
+   return __pte(pte_val(pte) | _PAGE_USER);
+}
+
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h 
b/arch/powerpc/include/asm/book3s/64/pgtable.h
index d4327f494371..c8564762b6f0 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -519,6 +519,11 @@ static inline int pte_special(pte_t pte)
return !!(pte_raw(pte) & cpu_to_be64(_PAGE_SPECIAL));
 }
 
+static inline bool pte_exec(pte_t pte)
+{
+   return !!(pte_raw(pte) & cpu_to_be64(_PAGE_EXEC));
+}
+
 static inline pgprot_t pte_pgprot(pte_t pte)   { return __pgprot(pte_val(pte) 
& PAGE_PROT_BITS); }
 
 #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
@@ -587,6 +592,11 @@ static inline int pte_present(pte_t pte)
return !!(pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT | _PAGE_INVALID));
 }
 
+static inline bool pte_hw_valid(pte_t pte)
+{
+   return !!(pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT));
+}
+
 #ifdef CONFIG_PPC_MEM_KEYS
 extern bool arch_pte_access_permitted(u64 pte, bool write, bool execute);
 #else
@@ -646,6 +656,11 @@ static inline pte_t pte_wrprotect(pte_t pte)
return __pte(pte_val(pte) & ~_PAGE_WRITE);
 }
 
+static inline pte_t pte_exprotect(pte_t pte)
+{
+   return __pte(pte_val(pte) & ~_PAGE_EXEC);
+}
+
 static inline pte_t pte_mkclean(pte_t pte)
 {
return __pte(pte_val(pte) & ~_PAGE_DIRTY);
@@ -656,6 +671,16 @@ static inline pte_t pte_mkold(pte_t pte)
return 

[PATCH v3 08/24] powerpc/mm: don't use _PAGE_EXEC in book3s/32

2018-10-09 Thread Christophe Leroy
book3s/32 doesn't define _PAGE_EXEC, so no need to use it.

All other platforms define _PAGE_EXEC so no need to check
it is not NUL when not book3s/32.

Reviewed-by: Aneesh Kumar K.V 
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/book3s/32/pgtable.h | 2 +-
 arch/powerpc/mm/pgtable.c| 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h 
b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 7a9f0ed599ff..3127cc529aa1 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -234,7 +234,7 @@ static inline void __ptep_set_access_flags(struct 
vm_area_struct *vma,
   int psize)
 {
unsigned long set = pte_val(entry) &
-   (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
+   (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW);
unsigned long clr = ~pte_val(entry) & _PAGE_RO;
 
pte_update(ptep, clr, set);
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index aee04b209b51..f97d9c3760e3 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -73,7 +73,7 @@ static struct page *maybe_pte_to_page(pte_t pte)
return page;
 }
 
-#if defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0
+#ifdef CONFIG_PPC_BOOK3S
 
 /* Server-style MMU handles coherency when hashing if HW exec permission
  * is supposed per page (currently 64-bit only). If not, then, we always
@@ -106,7 +106,7 @@ static pte_t set_access_flags_filter(pte_t pte, struct 
vm_area_struct *vma,
return pte;
 }
 
-#else /* defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0 */
+#else /* CONFIG_PPC_BOOK3S */
 
 /* Embedded type MMU with HW exec support. This is a bit more complicated
  * as we don't have two bits to spare for _PAGE_EXEC and _PAGE_HWEXEC so
@@ -179,7 +179,7 @@ static pte_t set_access_flags_filter(pte_t pte, struct 
vm_area_struct *vma,
return __pte(pte_val(pte) | _PAGE_EXEC);
 }
 
-#endif /* !(defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0) */
+#endif /* CONFIG_PPC_BOOK3S */
 
 /*
  * set_pte stores a linux PTE into the linux page table.
-- 
2.13.3



[PATCH v3 07/24] powerpc: handover page flags with a pgprot_t parameter

2018-10-09 Thread Christophe Leroy
In order to avoid multiple conversions, handover directly a
pgprot_t to map_kernel_page() as already done for radix.

Do the same for __ioremap_caller() and __ioremap_at().

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/book3s/32/pgtable.h |  2 +-
 arch/powerpc/include/asm/book3s/64/hash.h|  3 +--
 arch/powerpc/include/asm/book3s/64/pgtable.h |  7 +++---
 arch/powerpc/include/asm/fixmap.h|  2 +-
 arch/powerpc/include/asm/io.h|  4 +--
 arch/powerpc/include/asm/machdep.h   |  2 +-
 arch/powerpc/include/asm/nohash/32/pgtable.h |  2 +-
 arch/powerpc/include/asm/nohash/64/pgtable.h |  3 +--
 arch/powerpc/kernel/io-workarounds.c |  4 +--
 arch/powerpc/kernel/isa-bridge.c |  6 ++---
 arch/powerpc/kernel/pci_64.c |  2 +-
 arch/powerpc/lib/code-patching.c |  3 +--
 arch/powerpc/mm/8xx_mmu.c|  3 +--
 arch/powerpc/mm/dma-noncoherent.c|  2 +-
 arch/powerpc/mm/mem.c|  4 +--
 arch/powerpc/mm/pgtable-book3e.c |  9 +++
 arch/powerpc/mm/pgtable-hash64.c |  7 +++---
 arch/powerpc/mm/pgtable_32.c | 37 +---
 arch/powerpc/mm/pgtable_64.c | 37 ++--
 drivers/pcmcia/electra_cf.c  |  2 +-
 20 files changed, 64 insertions(+), 77 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h 
b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 751cf931bb3f..7a9f0ed599ff 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -292,7 +292,7 @@ static inline void __ptep_set_access_flags(struct 
vm_area_struct *vma,
 #define __pte_to_swp_entry(pte)((swp_entry_t) { pte_val(pte) 
>> 3 })
 #define __swp_entry_to_pte(x)  ((pte_t) { (x).val << 3 })
 
-int map_kernel_page(unsigned long va, phys_addr_t pa, int flags);
+int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
 
 /* Generic accessors to PTE bits */
 static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & 
_PAGE_RW);}
diff --git a/arch/powerpc/include/asm/book3s/64/hash.h 
b/arch/powerpc/include/asm/book3s/64/hash.h
index fcf8b10a209f..247aff9cc6ba 100644
--- a/arch/powerpc/include/asm/book3s/64/hash.h
+++ b/arch/powerpc/include/asm/book3s/64/hash.h
@@ -201,8 +201,7 @@ static inline void hpte_do_hugepage_flush(struct mm_struct 
*mm,
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
 
-extern int hash__map_kernel_page(unsigned long ea, unsigned long pa,
-unsigned long flags);
+int hash__map_kernel_page(unsigned long ea, unsigned long pa, pgprot_t prot);
 extern int __meminit hash__vmemmap_create_mapping(unsigned long start,
  unsigned long page_size,
  unsigned long phys);
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h 
b/arch/powerpc/include/asm/book3s/64/pgtable.h
index f108e2ce7f64..d4327f494371 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -1030,17 +1030,16 @@ extern struct page *pgd_page(pgd_t pgd);
 #define pgd_ERROR(e) \
pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
 
-static inline int map_kernel_page(unsigned long ea, unsigned long pa,
- unsigned long flags)
+static inline int map_kernel_page(unsigned long ea, unsigned long pa, pgprot_t 
prot)
 {
if (radix_enabled()) {
 #if defined(CONFIG_PPC_RADIX_MMU) && defined(DEBUG_VM)
unsigned long page_size = 1 << 
mmu_psize_defs[mmu_io_psize].shift;
WARN((page_size != PAGE_SIZE), "I/O page size != PAGE_SIZE");
 #endif
-   return radix__map_kernel_page(ea, pa, __pgprot(flags), 
PAGE_SIZE);
+   return radix__map_kernel_page(ea, pa, prot, PAGE_SIZE);
}
-   return hash__map_kernel_page(ea, pa, flags);
+   return hash__map_kernel_page(ea, pa, prot);
 }
 
 static inline int __meminit vmemmap_create_mapping(unsigned long start,
diff --git a/arch/powerpc/include/asm/fixmap.h 
b/arch/powerpc/include/asm/fixmap.h
index 41cc15c14eee..b9fbed84ddca 100644
--- a/arch/powerpc/include/asm/fixmap.h
+++ b/arch/powerpc/include/asm/fixmap.h
@@ -72,7 +72,7 @@ enum fixed_addresses {
 static inline void __set_fixmap(enum fixed_addresses idx,
phys_addr_t phys, pgprot_t flags)
 {
-   map_kernel_page(fix_to_virt(idx), phys, pgprot_val(flags));
+   map_kernel_page(fix_to_virt(idx), phys, flags);
 }
 
 #endif /* !__ASSEMBLY__ */
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index cdccab3938db..0a034519957d 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -786,12 +786,12 @@ extern void iounmap(volatile void __iomem *addr);
 extern void 

[PATCH v3 06/24] powerpc/mm: properly set PAGE_KERNEL flags in ioremap()

2018-10-09 Thread Christophe Leroy
Set PAGE_KERNEL directly in the caller and do not rely on a
hack adding PAGE_KERNEL flags when _PAGE_PRESENT is not set.

As already done for PPC64, use pgprot_cache() helpers instead of
_PAGE_XXX flags in PPC32 ioremap() derived functions.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/nohash/pgtable.h |  2 ++
 arch/powerpc/kernel/isa-bridge.c  |  6 +++---
 arch/powerpc/kernel/pci_64.c  |  2 +-
 arch/powerpc/mm/pgtable_32.c  | 28 
 arch/powerpc/mm/pgtable_64.c  | 10 +++---
 arch/powerpc/platforms/4xx/ocm.c  |  7 ++-
 drivers/pcmcia/electra_cf.c   |  2 +-
 7 files changed, 24 insertions(+), 33 deletions(-)

diff --git a/arch/powerpc/include/asm/nohash/pgtable.h 
b/arch/powerpc/include/asm/nohash/pgtable.h
index b321c82b3624..5b82e44c4231 100644
--- a/arch/powerpc/include/asm/nohash/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/pgtable.h
@@ -197,6 +197,8 @@ extern int ptep_set_access_flags(struct vm_area_struct 
*vma, unsigned long addre
 #if _PAGE_WRITETHRU != 0
 #define pgprot_cached_wthru(prot) (__pgprot((pgprot_val(prot) & 
~_PAGE_CACHE_CTL) | \
_PAGE_COHERENT | _PAGE_WRITETHRU))
+#else
+#define pgprot_cached_wthru(prot)  pgprot_noncached(prot)
 #endif
 
 #define pgprot_cached_noncoherent(prot) \
diff --git a/arch/powerpc/kernel/isa-bridge.c b/arch/powerpc/kernel/isa-bridge.c
index 1df6c74aa731..072e384f8c86 100644
--- a/arch/powerpc/kernel/isa-bridge.c
+++ b/arch/powerpc/kernel/isa-bridge.c
@@ -110,14 +110,14 @@ static void pci_process_ISA_OF_ranges(struct device_node 
*isa_node,
size = 0x1;
 
__ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE,
-size, pgprot_val(pgprot_noncached(__pgprot(0;
+size, pgprot_val(pgprot_noncached(PAGE_KERNEL)));
return;
 
 inval_range:
printk(KERN_ERR "no ISA IO ranges or unexpected isa range, "
   "mapping 64k\n");
__ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE,
-0x1, pgprot_val(pgprot_noncached(__pgprot(0;
+0x1, pgprot_val(pgprot_noncached(PAGE_KERNEL)));
 }
 
 
@@ -253,7 +253,7 @@ void __init isa_bridge_init_non_pci(struct device_node *np)
 */
isa_io_base = ISA_IO_BASE;
__ioremap_at(pbase, (void *)ISA_IO_BASE,
-size, pgprot_val(pgprot_noncached(__pgprot(0;
+size, pgprot_val(pgprot_noncached(PAGE_KERNEL)));
 
pr_debug("ISA: Non-PCI bridge is %pOF\n", np);
 }
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index dff28f903512..64bb4dd2b8f1 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -159,7 +159,7 @@ static int pcibios_map_phb_io_space(struct pci_controller 
*hose)
 
/* Establish the mapping */
if (__ioremap_at(phys_page, area->addr, size_page,
-pgprot_val(pgprot_noncached(__pgprot(0 == NULL)
+pgprot_val(pgprot_noncached(PAGE_KERNEL))) == NULL)
return -ENOMEM;
 
/* Fixup hose IO resource */
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 4c3adde09d95..6a81a2446c47 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -76,32 +76,36 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long 
address)
 void __iomem *
 ioremap(phys_addr_t addr, unsigned long size)
 {
-   return __ioremap_caller(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED,
-   __builtin_return_address(0));
+   unsigned long flags = pgprot_val(pgprot_noncached(PAGE_KERNEL));
+
+   return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(ioremap);
 
 void __iomem *
 ioremap_wc(phys_addr_t addr, unsigned long size)
 {
-   return __ioremap_caller(addr, size, _PAGE_NO_CACHE,
-   __builtin_return_address(0));
+   unsigned long flags = pgprot_val(pgprot_noncached_wc(PAGE_KERNEL));
+
+   return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(ioremap_wc);
 
 void __iomem *
 ioremap_wt(phys_addr_t addr, unsigned long size)
 {
-   return __ioremap_caller(addr, size, _PAGE_WRITETHRU,
-   __builtin_return_address(0));
+   unsigned long flags = pgprot_val(pgprot_cached_wthru(PAGE_KERNEL));
+
+   return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(ioremap_wt);
 
 void __iomem *
 ioremap_coherent(phys_addr_t addr, unsigned long size)
 {
-   return __ioremap_caller(addr, size, _PAGE_COHERENT,
-   __builtin_return_address(0));
+   unsigned long flags = pgprot_val(pgprot_cached(PAGE_KERNEL));
+
+   return __ioremap_caller(addr, size, flags, 

[PATCH v3 05/24] powerpc: don't use ioremap_prot() nor __ioremap() unless really needed.

2018-10-09 Thread Christophe Leroy
In many places, ioremap_prot() and __ioremap() can be replaced with
higher level functions like ioremap(), ioremap_coherent(),
ioremap_cache(), ioremap_wc() ...

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/kernel/btext.c   | 2 +-
 arch/powerpc/kernel/crash_dump.c  | 2 +-
 arch/powerpc/platforms/85xx/smp.c | 4 ++--
 arch/powerpc/platforms/pasemi/dma_lib.c   | 2 +-
 arch/powerpc/platforms/ps3/spu.c  | 3 +--
 arch/powerpc/sysdev/fsl_85xx_cache_sram.c | 8 
 6 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
index b2072d5bbf2b..b4241ed1456e 100644
--- a/arch/powerpc/kernel/btext.c
+++ b/arch/powerpc/kernel/btext.c
@@ -163,7 +163,7 @@ void btext_map(void)
offset = ((unsigned long) dispDeviceBase) - base;
size = dispDeviceRowBytes * dispDeviceRect[3] + offset
+ dispDeviceRect[0];
-   vbase = __ioremap(base, size, 
pgprot_val(pgprot_noncached_wc(__pgprot(0;
+   vbase = ioremap_wc(base, size);
if (!vbase)
return;
logicalDisplayBase = vbase + offset;
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index d10ad258d41a..bbdc4706c159 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -110,7 +110,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
vaddr = __va(paddr);
csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf);
} else {
-   vaddr = __ioremap(paddr, PAGE_SIZE, 0);
+   vaddr = ioremap_cache(paddr, PAGE_SIZE);
csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf);
iounmap(vaddr);
}
diff --git a/arch/powerpc/platforms/85xx/smp.c 
b/arch/powerpc/platforms/85xx/smp.c
index 7e966f4cf19a..fff72425727a 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -216,8 +216,8 @@ static int smp_85xx_start_cpu(int cpu)
 
/* Map the spin table */
if (ioremappable)
-   spin_table = ioremap_prot(*cpu_rel_addr,
-   sizeof(struct epapr_spin_table), _PAGE_COHERENT);
+   spin_table = ioremap_coherent(*cpu_rel_addr,
+ sizeof(struct epapr_spin_table));
else
spin_table = phys_to_virt(*cpu_rel_addr);
 
diff --git a/arch/powerpc/platforms/pasemi/dma_lib.c 
b/arch/powerpc/platforms/pasemi/dma_lib.c
index c80f72c370ae..53384eb42a76 100644
--- a/arch/powerpc/platforms/pasemi/dma_lib.c
+++ b/arch/powerpc/platforms/pasemi/dma_lib.c
@@ -576,7 +576,7 @@ int pasemi_dma_init(void)
res.start = 0xfd80;
res.end = res.start + 0x1000;
}
-   dma_status = __ioremap(res.start, resource_size(), 0);
+   dma_status = ioremap_cache(res.start, resource_size());
pci_dev_put(iob_pdev);
 
for (i = 0; i < MAX_TXCH; i++)
diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c
index b54850845466..7746c2a3c509 100644
--- a/arch/powerpc/platforms/ps3/spu.c
+++ b/arch/powerpc/platforms/ps3/spu.c
@@ -215,8 +215,7 @@ static int __init setup_areas(struct spu *spu)
goto fail_ioremap;
}
 
-   spu->local_store = (__force void *)ioremap_prot(spu->local_store_phys,
-   LS_SIZE, pgprot_val(pgprot_noncached_wc(__pgprot(0;
+   spu->local_store = (__force void *)ioremap_wc(spu->local_store_phys, 
LS_SIZE);
 
if (!spu->local_store) {
pr_debug("%s:%d: ioremap local_store failed\n",
diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c 
b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
index 00ccf3e4fcb4..15cbdd4fde06 100644
--- a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
+++ b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
@@ -107,11 +107,11 @@ int __init instantiate_cache_sram(struct platform_device 
*dev,
goto out_free;
}
 
-   cache_sram->base_virt = ioremap_prot(cache_sram->base_phys,
-   cache_sram->size, _PAGE_COHERENT | PAGE_KERNEL);
+   cache_sram->base_virt = ioremap_coherent(cache_sram->base_phys,
+cache_sram->size);
if (!cache_sram->base_virt) {
-   dev_err(>dev, "%pOF: ioremap_prot failed\n",
-   dev->dev.of_node);
+   dev_err(>dev, "%pOF: ioremap_coherent failed\n",
+   dev->dev.of_node);
ret = -ENOMEM;
goto out_release;
}
-- 
2.13.3



[PATCH v3 04/24] soc/fsl/qbman: use ioremap_cache() instead of ioremap_prot(0)

2018-10-09 Thread Christophe Leroy
ioremap_prot() with flag set to 0 relies on a hack in
__ioremap_caller() which adds PAGE_KERNEL flags when the
handed flags don't look like a valid set of flags
(ie don't include _PAGE_PRESENT)

The intention being to map cached memory, use ioremap_cache() instead.

Signed-off-by: Christophe Leroy 
---
 drivers/soc/fsl/qbman/qman_ccsr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/fsl/qbman/qman_ccsr.c 
b/drivers/soc/fsl/qbman/qman_ccsr.c
index 79cba58387a5..0fbb201346c7 100644
--- a/drivers/soc/fsl/qbman/qman_ccsr.c
+++ b/drivers/soc/fsl/qbman/qman_ccsr.c
@@ -418,7 +418,7 @@ static size_t fqd_sz, pfdr_sz;
 static int zero_priv_mem(phys_addr_t addr, size_t sz)
 {
/* map as cacheable, non-guarded */
-   void __iomem *tmpp = ioremap_prot(addr, sz, 0);
+   void __iomem *tmpp = ioremap_cache(addr, sz);
 
if (!tmpp)
return -ENOMEM;
-- 
2.13.3



[PATCH v3 03/24] drivers/block/z2ram: use ioremap_wt() instead of __ioremap(_PAGE_WRITETHRU)

2018-10-09 Thread Christophe Leroy
_PAGE_WRITETHRU is a target specific flag. Prefer generic functions.

Acked-by: Geert Uytterhoeven 
Signed-off-by: Christophe Leroy 
---
 drivers/block/z2ram.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
index d0c5bc4e0703..cfbd70520eeb 100644
--- a/drivers/block/z2ram.c
+++ b/drivers/block/z2ram.c
@@ -190,8 +190,7 @@ static int z2_open(struct block_device *bdev, fmode_t mode)
vfree(vmalloc (size));
}
 
-   vaddr = (unsigned long) __ioremap (paddr, size, 
-  _PAGE_WRITETHRU);
+   vaddr = (unsigned long)ioremap_wt(paddr, size);
 
 #else
vaddr = (unsigned long)z_remap_nocache_nonser(paddr, size);
-- 
2.13.3



[PATCH v3 02/24] drivers/video/fbdev: use ioremap_wc/wt() instead of __ioremap()

2018-10-09 Thread Christophe Leroy
_PAGE_NO_CACHE is a platform specific flag. In addition, this flag
is misleading because one would think it requests a noncached page
whereas a noncached page is _PAGE_NO_CACHE | _PAGE_GUARDED

_PAGE_NO_CACHE alone means write combined noncached page, so lets
use ioremap_wc() instead.

_PAGE_WRITETHRU is also platform specific flag. Use ioremap_wt()
instead.

Signed-off-by: Christophe Leroy 
---
 drivers/video/fbdev/chipsfb.c|  3 +--
 drivers/video/fbdev/controlfb.c  |  5 +
 drivers/video/fbdev/platinumfb.c |  5 +
 drivers/video/fbdev/valkyriefb.c | 12 ++--
 4 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/video/fbdev/chipsfb.c b/drivers/video/fbdev/chipsfb.c
index f103665cad43..40182ed85648 100644
--- a/drivers/video/fbdev/chipsfb.c
+++ b/drivers/video/fbdev/chipsfb.c
@@ -27,7 +27,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 #include 
@@ -401,7 +400,7 @@ static int chipsfb_pci_init(struct pci_dev *dp, const 
struct pci_device_id *ent)
 #endif /* CONFIG_PMAC_BACKLIGHT */
 
 #ifdef CONFIG_PPC
-   p->screen_base = __ioremap(addr, 0x20, _PAGE_NO_CACHE);
+   p->screen_base = ioremap_wc(addr, 0x20);
 #else
p->screen_base = ioremap(addr, 0x20);
 #endif
diff --git a/drivers/video/fbdev/controlfb.c b/drivers/video/fbdev/controlfb.c
index 8d14b29aafea..9cb0ef7ac29e 100644
--- a/drivers/video/fbdev/controlfb.c
+++ b/drivers/video/fbdev/controlfb.c
@@ -48,9 +48,7 @@
 #include 
 #include 
 #include 
-#include 
 #include 
-#include 
 #include 
 
 #include "macmodes.h"
@@ -715,8 +713,7 @@ static int __init control_of_init(struct device_node *dp)
goto error_out;
}
/* map at most 8MB for the frame buffer */
-   p->frame_buffer = __ioremap(p->frame_buffer_phys, 0x80,
-   _PAGE_WRITETHRU);
+   p->frame_buffer = ioremap_wt(p->frame_buffer_phys, 0x80);
 
if (!p->control_regs_phys ||
!request_mem_region(p->control_regs_phys, p->control_regs_size,
diff --git a/drivers/video/fbdev/platinumfb.c b/drivers/video/fbdev/platinumfb.c
index 377d3399a3ad..bf6b7fb83cf4 100644
--- a/drivers/video/fbdev/platinumfb.c
+++ b/drivers/video/fbdev/platinumfb.c
@@ -32,9 +32,7 @@
 #include 
 #include 
 #include 
-#include 
 #include 
-#include 
 
 #include "macmodes.h"
 #include "platinumfb.h"
@@ -577,8 +575,7 @@ static int platinumfb_probe(struct platform_device* odev)
 
/* frame buffer - map only 4MB */
pinfo->frame_buffer_phys = pinfo->rsrc_fb.start;
-   pinfo->frame_buffer = __ioremap(pinfo->rsrc_fb.start, 0x40,
-   _PAGE_WRITETHRU);
+   pinfo->frame_buffer = ioremap_wt(pinfo->rsrc_fb.start, 0x40);
pinfo->base_frame_buffer = pinfo->frame_buffer;
 
/* registers */
diff --git a/drivers/video/fbdev/valkyriefb.c b/drivers/video/fbdev/valkyriefb.c
index 275fb98236d3..d51c3a8009cb 100644
--- a/drivers/video/fbdev/valkyriefb.c
+++ b/drivers/video/fbdev/valkyriefb.c
@@ -54,13 +54,11 @@
 #include 
 #include 
 #include 
-#include 
 #ifdef CONFIG_MAC
 #include 
 #else
 #include 
 #endif
-#include 
 
 #include "macmodes.h"
 #include "valkyriefb.h"
@@ -318,7 +316,7 @@ static void __init valkyrie_choose_mode(struct 
fb_info_valkyrie *p)
 int __init valkyriefb_init(void)
 {
struct fb_info_valkyrie *p;
-   unsigned long frame_buffer_phys, cmap_regs_phys, flags;
+   unsigned long frame_buffer_phys, cmap_regs_phys;
int err;
char *option = NULL;
 
@@ -337,7 +335,6 @@ int __init valkyriefb_init(void)
/* Hardcoded addresses... welcome to 68k Macintosh country :-) */
frame_buffer_phys = 0xf900;
cmap_regs_phys = 0x50f24000;
-   flags = IOMAP_NOCACHE_SER; /* IOMAP_WRITETHROUGH?? */
 #else /* ppc (!CONFIG_MAC) */
{
struct device_node *dp;
@@ -354,7 +351,6 @@ int __init valkyriefb_init(void)
 
frame_buffer_phys = r.start;
cmap_regs_phys = r.start + 0x304000;
-   flags = _PAGE_WRITETHRU;
}
 #endif /* ppc (!CONFIG_MAC) */
 
@@ -369,7 +365,11 @@ int __init valkyriefb_init(void)
}
p->total_vram = 0x10;
p->frame_buffer_phys = frame_buffer_phys;
-   p->frame_buffer = __ioremap(frame_buffer_phys, p->total_vram, flags);
+#ifdef CONFIG_MAC
+   p->frame_buffer = ioremap_nocache(frame_buffer_phys, p->total_vram);
+#else
+   p->frame_buffer = ioremap_wt(frame_buffer_phys, p->total_vram);
+#endif
p->cmap_regs_phys = cmap_regs_phys;
p->cmap_regs = ioremap(p->cmap_regs_phys, 0x1000);
p->valkyrie_regs_phys = cmap_regs_phys+0x6000;
-- 
2.13.3



[PATCH v3 01/24] powerpc/32: Add ioremap_wt() and ioremap_coherent()

2018-10-09 Thread Christophe Leroy
Other arches have ioremap_wt() to map IO areas write-through.
Implement it on PPC as well in order to avoid drivers using
__ioremap(_PAGE_WRITETHRU)

Also implement ioremap_coherent() to avoid drivers using
__ioremap(_PAGE_COHERENT)

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/io.h |  9 +
 arch/powerpc/mm/pgtable_32.c  | 16 
 arch/powerpc/mm/pgtable_64.c  | 10 ++
 3 files changed, 35 insertions(+)

diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index e0331e754568..cdccab3938db 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -3,6 +3,9 @@
 #ifdef __KERNEL__
 
 #define ARCH_HAS_IOREMAP_WC
+#ifdef CONFIG_PPC32
+#define ARCH_HAS_IOREMAP_WT
+#endif
 
 /*
  * This program is free software; you can redistribute it and/or
@@ -746,6 +749,10 @@ static inline void iosync(void)
  *
  * * ioremap_wc enables write combining
  *
+ * * ioremap_wt enables write through
+ *
+ * * ioremap_coherent maps coherent cached memory
+ *
  * * iounmap undoes such a mapping and can be hooked
  *
  * * __ioremap_at (and the pending __iounmap_at) are low level functions to
@@ -767,6 +774,8 @@ extern void __iomem *ioremap(phys_addr_t address, unsigned 
long size);
 extern void __iomem *ioremap_prot(phys_addr_t address, unsigned long size,
  unsigned long flags);
 extern void __iomem *ioremap_wc(phys_addr_t address, unsigned long size);
+void __iomem *ioremap_wt(phys_addr_t address, unsigned long size);
+void __iomem *ioremap_coherent(phys_addr_t address, unsigned long size);
 #define ioremap_nocache(addr, size)ioremap((addr), (size))
 #define ioremap_uc(addr, size) ioremap((addr), (size))
 #define ioremap_cache(addr, size) \
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 120a49bfb9c6..4c3adde09d95 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -90,6 +90,22 @@ ioremap_wc(phys_addr_t addr, unsigned long size)
 EXPORT_SYMBOL(ioremap_wc);
 
 void __iomem *
+ioremap_wt(phys_addr_t addr, unsigned long size)
+{
+   return __ioremap_caller(addr, size, _PAGE_WRITETHRU,
+   __builtin_return_address(0));
+}
+EXPORT_SYMBOL(ioremap_wt);
+
+void __iomem *
+ioremap_coherent(phys_addr_t addr, unsigned long size)
+{
+   return __ioremap_caller(addr, size, _PAGE_COHERENT,
+   __builtin_return_address(0));
+}
+EXPORT_SYMBOL(ioremap_coherent);
+
+void __iomem *
 ioremap_prot(phys_addr_t addr, unsigned long size, unsigned long flags)
 {
/* writeable implies dirty for kernel addresses */
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index e15e63079ba8..c0f356d9b135 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -222,6 +222,16 @@ void __iomem * ioremap_wc(phys_addr_t addr, unsigned long 
size)
return __ioremap_caller(addr, size, flags, caller);
 }
 
+void __iomem *ioremap_coherent(phys_addr_t addr, unsigned long size)
+{
+   unsigned long flags = pgprot_val(pgprot_cached(__pgprot(0)));
+   void *caller = __builtin_return_address(0);
+
+   if (ppc_md.ioremap)
+   return ppc_md.ioremap(addr, size, flags, caller);
+   return __ioremap_caller(addr, size, flags, caller);
+}
+
 void __iomem * ioremap_prot(phys_addr_t addr, unsigned long size,
 unsigned long flags)
 {
-- 
2.13.3



[PATCH v3 00/24] ban the use of _PAGE_XXX flags outside platform specific code

2018-10-09 Thread Christophe Leroy
Today flags like for instance _PAGE_RW or _PAGE_USER are used through
common parts of code.
Using those directly in common parts of code have proven to lead to
mistakes or misbehaviour, because their use is not always as trivial
as one could think.

For instance, (flags & _PAGE_USER) == 0 isn't enough to tell
that a page is a kernel page, because some targets are using
_PAGE_PRIVILEDGED and not _PAGE_USER, so the test has to be 
(flags & (_PAGE_USER | _PAGE_PRIVILEDGED)) == _PAGE_PRIVILEDGED
This has too (bad) consequences:

 - All targets must define every bit, even the unsupported ones,
   leading to a lot of useless #define _PAGE_XXX 0
 - If someone forgets to take into account all possible _PAGE_XXX bits
   for the case, we can get unexpected behaviour on some targets.

This becomes even more complex when we come to using _PAGE_RW.
Testing (flags & _PAGE_RW) is not enough to test whether a page
if writable or not, because:

 - Some targets have _PAGE_RO instead, which has to be unset to tell
   a page is writable
 - Some targets have _PAGE_R and _PAGE_W, in which case
   _PAGE_RW = _PAGE_R | _PAGE_W
 - Even knowing whether a page is readable is not always trivial because:
   - Some targets requires to check that _PAGE_R is set to ensure page
   is readable
   - Some targets requires to check that _PAGE_NA is not set
   - Some targets requires to check that _PAGE_RO or _PAGE_RW is set

Etc 

In order to work around all those issues and minimise the risks of errors,
this serie aims at removing all use of _PAGE_XXX flags from powerpc code
and always use pte_xxx() and pte_mkxxx() accessors instead. Those accessors
are then defined in platform specific parts of the kernel code.

Compared to the RFC, v2 adds three things:
- A work on ioremap() alike functions: properly set the base flags
  by all callers and removed the hack which sets the base flags when
  the caller don't give them.
- _PAGE_EXEC flag is replaced by a bool in the call to hash_preload()
- Optimisation of pte_mkXXX() helpers on book3s64 to avoid multiple
endian conversions.

v2:
 - Takes into account comments received on the RFC.
 - compilation test result: 
http://kisskb.ellerman.id.au/kisskb/head/51b7f5d55900688c7c07cdb945d34b3314befa36/

v3:
 - rebased on lastest 'merge' powerpc branch
 - added a new helper pte_hw_valid() and using it in set_pte_at(), see 
discussion at https://patchwork.ozlabs.org/patch/972630/
 - compilation result: 
http://kisskb.ellerman.id.au/kisskb/head/914a399c8f1434f3c52013e625fb1665571033ef/

Christophe Leroy (24):
  powerpc/32: Add ioremap_wt() and ioremap_coherent()
  drivers/video/fbdev: use ioremap_wc/wt() instead of __ioremap()
  drivers/block/z2ram: use ioremap_wt() instead of
__ioremap(_PAGE_WRITETHRU)
  soc/fsl/qbman: use ioremap_cache() instead of ioremap_prot(0)
  powerpc: don't use ioremap_prot() nor __ioremap() unless really
needed.
  powerpc/mm: properly set PAGE_KERNEL flags in ioremap()
  powerpc: handover page flags with a pgprot_t parameter
  powerpc/mm: don't use _PAGE_EXEC in book3s/32
  powerpc/mm: move some nohash pte helpers in nohash/[32:64]/pgtable.h
  powerpc/mm: add pte helpers to query and change pte flags
  powerpc/mm: don't use _PAGE_EXEC for calling hash_preload()
  powerpc/mm: use pte helpers in generic code
  powerpc/mm: Split dump_pagelinuxtables flag_array table
  powerpc/mm: drop unused page flags
  powerpc/mm: move __P and __S tables in the common pgtable.h
  powerpc/book3s/32: do not include pte-common.h
  powerpc/mm: Move pte_user() into nohash/pgtable.h
  powerpc/mm: Distribute platform specific PAGE and PMD flags and
definitions
  powerpc/nohash/64: do not include pte-common.h
  powerpc/mm: Allow platforms to redefine some helpers
  powerpc/mm: Define platform default caches related flags
  powerpc/mm: Get rid of pte-common.h
  powerpc/8xx: change name of a few page flags to avoid confusion
  powerpc/book3s64: Avoid multiple endian conversion in pte helpers

 arch/powerpc/include/asm/book3s/32/pgtable.h   | 151 --
 arch/powerpc/include/asm/book3s/64/hash.h  |   3 +-
 arch/powerpc/include/asm/book3s/64/pgtable.h   | 133 +++--
 arch/powerpc/include/asm/fixmap.h  |   2 +-
 arch/powerpc/include/asm/io.h  |  13 +-
 arch/powerpc/include/asm/machdep.h |   2 +-
 arch/powerpc/include/asm/nohash/32/pgtable.h   |  66 ++-
 arch/powerpc/include/asm/nohash/32/pte-40x.h   |  48 +
 arch/powerpc/include/asm/nohash/32/pte-44x.h   |  35 
 arch/powerpc/include/asm/nohash/32/pte-8xx.h   |  92 -
 arch/powerpc/include/asm/nohash/32/pte-fsl-booke.h |  38 
 arch/powerpc/include/asm/nohash/64/pgtable.h   |  40 +++-
 arch/powerpc/include/asm/nohash/pgtable.h  |  98 ++---
 arch/powerpc/include/asm/nohash/pte-book3e.h   |  30 +++
 arch/powerpc/include/asm/pgtable.h |  19 ++
 arch/powerpc/include/asm/pte-common.h  

[PATCH 07/33] powerpc/dma: untangle vio_dma_mapping_ops from dma_iommu_ops

2018-10-09 Thread Christoph Hellwig
vio_dma_mapping_ops currently does a lot of indirect calls through
dma_iommu_ops, which not only make the code harder to follow but are
also expensive in the post-spectre world.  Unwind the indirect calls
by calling the ppc_iommu_* or iommu_* APIs directly applicable, or
just use the dma_iommu_* methods directly where we can.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/include/asm/iommu.h |  1 +
 arch/powerpc/kernel/dma-iommu.c  |  2 +-
 arch/powerpc/platforms/pseries/vio.c | 87 
 3 files changed, 38 insertions(+), 52 deletions(-)

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index ab3a4fba38e3..26b7cc176a99 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -244,6 +244,7 @@ static inline int __init tce_iommu_bus_notifier_init(void)
 }
 #endif /* !CONFIG_IOMMU_API */
 
+u64 dma_iommu_get_required_mask(struct device *dev);
 int dma_iommu_mapping_error(struct device *dev, dma_addr_t dma_addr);
 
 #else
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index 2ca6cfaebf65..0613278abf9f 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -92,7 +92,7 @@ int dma_iommu_dma_supported(struct device *dev, u64 mask)
return 1;
 }
 
-static u64 dma_iommu_get_required_mask(struct device *dev)
+u64 dma_iommu_get_required_mask(struct device *dev)
 {
struct iommu_table *tbl = get_iommu_table_base(dev);
u64 mask;
diff --git a/arch/powerpc/platforms/pseries/vio.c 
b/arch/powerpc/platforms/pseries/vio.c
index 49e04ec19238..1dfff53ebd7f 100644
--- a/arch/powerpc/platforms/pseries/vio.c
+++ b/arch/powerpc/platforms/pseries/vio.c
@@ -492,7 +492,9 @@ static void *vio_dma_iommu_alloc_coherent(struct device 
*dev, size_t size,
return NULL;
}
 
-   ret = dma_iommu_ops.alloc(dev, size, dma_handle, flag, attrs);
+   ret = iommu_alloc_coherent(dev, get_iommu_table_base(dev), size,
+   dma_handle, dev->coherent_dma_mask, flag,
+   dev_to_node(dev));
if (unlikely(ret == NULL)) {
vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE));
atomic_inc(>cmo.allocs_failed);
@@ -507,8 +509,7 @@ static void vio_dma_iommu_free_coherent(struct device *dev, 
size_t size,
 {
struct vio_dev *viodev = to_vio_dev(dev);
 
-   dma_iommu_ops.free(dev, size, vaddr, dma_handle, attrs);
-
+   iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle);
vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE));
 }
 
@@ -518,22 +519,22 @@ static dma_addr_t vio_dma_iommu_map_page(struct device 
*dev, struct page *page,
  unsigned long attrs)
 {
struct vio_dev *viodev = to_vio_dev(dev);
-   struct iommu_table *tbl;
+   struct iommu_table *tbl = get_iommu_table_base(dev);
dma_addr_t ret = IOMMU_MAPPING_ERROR;
 
-   tbl = get_iommu_table_base(dev);
-   if (vio_cmo_alloc(viodev, roundup(size, IOMMU_PAGE_SIZE(tbl {
-   atomic_inc(>cmo.allocs_failed);
-   return ret;
-   }
-
-   ret = dma_iommu_ops.map_page(dev, page, offset, size, direction, attrs);
-   if (unlikely(dma_mapping_error(dev, ret))) {
-   vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE(tbl)));
-   atomic_inc(>cmo.allocs_failed);
-   }
-
+   if (vio_cmo_alloc(viodev, roundup(size, IOMMU_PAGE_SIZE(tbl
+   goto out_fail;
+   ret = iommu_map_page(dev, tbl, page, offset, size, device_to_mask(dev),
+   direction, attrs);
+   if (unlikely(ret == IOMMU_MAPPING_ERROR))
+   goto out_deallocate;
return ret;
+
+out_deallocate:
+   vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE(tbl)));
+out_fail:
+   atomic_inc(>cmo.allocs_failed);
+   return IOMMU_MAPPING_ERROR;
 }
 
 static void vio_dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle,
@@ -542,11 +543,9 @@ static void vio_dma_iommu_unmap_page(struct device *dev, 
dma_addr_t dma_handle,
 unsigned long attrs)
 {
struct vio_dev *viodev = to_vio_dev(dev);
-   struct iommu_table *tbl;
-
-   tbl = get_iommu_table_base(dev);
-   dma_iommu_ops.unmap_page(dev, dma_handle, size, direction, attrs);
+   struct iommu_table *tbl = get_iommu_table_base(dev);
 
+   iommu_unmap_page(tbl, dma_handle, size, direction, attrs);
vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE(tbl)));
 }
 
@@ -555,34 +554,32 @@ static int vio_dma_iommu_map_sg(struct device *dev, 
struct scatterlist *sglist,
 unsigned long attrs)
 {
struct vio_dev *viodev = to_vio_dev(dev);
-   struct iommu_table *tbl;
+   struct iommu_table *tbl = get_iommu_table_base(dev);
struct 

[PATCH 05/33] powerpc/dma: split the two __dma_alloc_coherent implementations

2018-10-09 Thread Christoph Hellwig
The implemementation for the CONFIG_NOT_COHERENT_CACHE case doesn't share
any code with the one for systems with coherent caches.  Split it off
and merge it with the helpers in dma-noncoherent.c that have no other
callers.

Signed-off-by: Christoph Hellwig 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/include/asm/dma-mapping.h |  5 -
 arch/powerpc/kernel/dma.c  | 14 ++
 arch/powerpc/mm/dma-noncoherent.c  | 15 +++
 arch/powerpc/platforms/44x/warp.c  |  2 +-
 4 files changed, 10 insertions(+), 26 deletions(-)

diff --git a/arch/powerpc/include/asm/dma-mapping.h 
b/arch/powerpc/include/asm/dma-mapping.h
index f2a4a7142b1e..dacd0f93f2b2 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -39,9 +39,6 @@ extern int dma_nommu_mmap_coherent(struct device *dev,
  * to ensure it is consistent.
  */
 struct device;
-extern void *__dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *handle, gfp_t gfp);
-extern void __dma_free_coherent(size_t size, void *vaddr);
 extern void __dma_sync(void *vaddr, size_t size, int direction);
 extern void __dma_sync_page(struct page *page, unsigned long offset,
 size_t size, int direction);
@@ -52,8 +49,6 @@ extern unsigned long __dma_get_coherent_pfn(unsigned long 
cpu_addr);
  * Cache coherent cores.
  */
 
-#define __dma_alloc_coherent(dev, gfp, size, handle)   NULL
-#define __dma_free_coherent(size, addr)((void)0)
 #define __dma_sync(addr, size, rw) ((void)0)
 #define __dma_sync_page(pg, off, sz, rw)   ((void)0)
 
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 6551685a4ed0..d6deb458bb91 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -62,18 +62,12 @@ static int dma_nommu_dma_supported(struct device *dev, u64 
mask)
 #endif
 }
 
+#ifndef CONFIG_NOT_COHERENT_CACHE
 void *__dma_nommu_alloc_coherent(struct device *dev, size_t size,
  dma_addr_t *dma_handle, gfp_t flag,
  unsigned long attrs)
 {
void *ret;
-#ifdef CONFIG_NOT_COHERENT_CACHE
-   ret = __dma_alloc_coherent(dev, size, dma_handle, flag);
-   if (ret == NULL)
-   return NULL;
-   *dma_handle += get_dma_offset(dev);
-   return ret;
-#else
struct page *page;
int node = dev_to_node(dev);
 #ifdef CONFIG_FSL_SOC
@@ -110,19 +104,15 @@ void *__dma_nommu_alloc_coherent(struct device *dev, 
size_t size,
*dma_handle = __pa(ret) + get_dma_offset(dev);
 
return ret;
-#endif
 }
 
 void __dma_nommu_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle,
unsigned long attrs)
 {
-#ifdef CONFIG_NOT_COHERENT_CACHE
-   __dma_free_coherent(size, vaddr);
-#else
free_pages((unsigned long)vaddr, get_order(size));
-#endif
 }
+#endif /* !CONFIG_NOT_COHERENT_CACHE */
 
 static void *dma_nommu_alloc_coherent(struct device *dev, size_t size,
   dma_addr_t *dma_handle, gfp_t flag,
diff --git a/arch/powerpc/mm/dma-noncoherent.c 
b/arch/powerpc/mm/dma-noncoherent.c
index 382528475433..965ce3d19f5a 100644
--- a/arch/powerpc/mm/dma-noncoherent.c
+++ b/arch/powerpc/mm/dma-noncoherent.c
@@ -29,7 +29,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 
 #include 
@@ -151,8 +151,8 @@ static struct ppc_vm_region *ppc_vm_region_find(struct 
ppc_vm_region *head, unsi
  * Allocate DMA-coherent memory space and return both the kernel remapped
  * virtual and bus address for that space.
  */
-void *
-__dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, 
gfp_t gfp)
+void *__dma_nommu_alloc_coherent(struct device *dev, size_t size,
+   dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
struct page *page;
struct ppc_vm_region *c;
@@ -223,7 +223,7 @@ __dma_alloc_coherent(struct device *dev, size_t size, 
dma_addr_t *handle, gfp_t
/*
 * Set the "dma handle"
 */
-   *handle = page_to_phys(page);
+   *dma_handle = phys_to_dma(dev, page_to_phys(page));
 
do {
SetPageReserved(page);
@@ -249,12 +249,12 @@ __dma_alloc_coherent(struct device *dev, size_t size, 
dma_addr_t *handle, gfp_t
  no_page:
return NULL;
 }
-EXPORT_SYMBOL(__dma_alloc_coherent);
 
 /*
  * free a page as defined by the above mapping.
  */
-void __dma_free_coherent(size_t size, void *vaddr)
+void __dma_nommu_free_coherent(struct device *dev, size_t size, void *vaddr,
+   dma_addr_t dma_handle, unsigned long attrs)
 {
struct ppc_vm_region *c;
unsigned long flags, addr;
@@ -309,7 +309,6 @@ void __dma_free_coherent(size_t size, void *vaddr)
   __func__, 

[PATCH 02/33] powerpc/dma: remove the unused ARCH_HAS_DMA_MMAP_COHERENT define

2018-10-09 Thread Christoph Hellwig
Signed-off-by: Christoph Hellwig 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/include/asm/dma-mapping.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/powerpc/include/asm/dma-mapping.h 
b/arch/powerpc/include/asm/dma-mapping.h
index 8fa394520af6..f2a4a7142b1e 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -112,7 +112,5 @@ extern int dma_set_mask(struct device *dev, u64 dma_mask);
 
 extern u64 __dma_get_required_mask(struct device *dev);
 
-#define ARCH_HAS_DMA_MMAP_COHERENT
-
 #endif /* __KERNEL__ */
 #endif /* _ASM_DMA_MAPPING_H */
-- 
2.19.0



use generic DMA mapping code in powerpc V3

2018-10-09 Thread Christoph Hellwig
Hi all,

this series switches the powerpc port to use the generic swiotlb and
noncoherent dma ops, and to use more generic code for the coherent
direct mapping, as well as removing a lot of dead code.

The changes since v1 are to big to list and v2 was not posted in public.

As this series is very large and depends on the dma-mapping tree I've
also published a git tree:

git://git.infradead.org/users/hch/misc.git powerpc-dma.3

Gitweb:


http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/powerpc-dma.3


[PATCH 01/33] powerpc: use mm zones more sensibly

2018-10-09 Thread Christoph Hellwig
Powerpc has somewhat odd usage where ZONE_DMA is used for all memory on
common 64-bit configfs, and ZONE_DMA32 is used for 31-bit schemes.

Move to a scheme closer to what other architectures use (and I dare to
say the intent of the system):

 - ZONE_DMA: optionally for memory < 31-bit
 - ZONE_NORMAL: everything addressable by the kernel
 - ZONE_HIGHMEM: memory > 32-bit for 32-bit kernels

Also provide information on how ZONE_DMA is used by defining
ARCH_ZONE_DMA_BITS.

Contains various fixes from Benjamin Herrenschmidt.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/Kconfig  |  6 +--
 arch/powerpc/include/asm/page.h   |  2 +
 arch/powerpc/include/asm/pgtable.h|  1 -
 arch/powerpc/kernel/dma-swiotlb.c |  6 +--
 arch/powerpc/kernel/dma.c |  7 +--
 arch/powerpc/mm/mem.c | 50 +++
 arch/powerpc/platforms/85xx/corenet_generic.c | 10 
 arch/powerpc/platforms/85xx/qemu_e500.c   |  9 
 include/linux/mmzone.h|  2 +-
 9 files changed, 24 insertions(+), 69 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a80669209155..06996df07cad 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -380,7 +380,7 @@ config PPC_ADV_DEBUG_DAC_RANGE
depends on PPC_ADV_DEBUG_REGS && 44x
default y
 
-config ZONE_DMA32
+config ZONE_DMA
bool
default y if PPC64
 
@@ -879,10 +879,6 @@ config ISA
  have an IBM RS/6000 or pSeries machine, say Y.  If you have an
  embedded board, consult your board documentation.
 
-config ZONE_DMA
-   bool
-   default y
-
 config GENERIC_ISA_DMA
bool
depends on ISA_DMA_API
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index f6a1265face2..fc8c9ac0c6be 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -354,4 +354,6 @@ typedef struct page *pgtable_t;
 #endif /* __ASSEMBLY__ */
 #include 
 
+#define ARCH_ZONE_DMA_BITS 31
+
 #endif /* _ASM_POWERPC_PAGE_H */
diff --git a/arch/powerpc/include/asm/pgtable.h 
b/arch/powerpc/include/asm/pgtable.h
index 14c79a7dc855..9bafb38e959e 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -37,7 +37,6 @@ extern unsigned long empty_zero_page[];
 
 extern pgd_t swapper_pg_dir[];
 
-void limit_zone_pfn(enum zone_type zone, unsigned long max_pfn);
 int dma_pfn_limit_to_zone(u64 pfn_limit);
 extern void paging_init(void);
 
diff --git a/arch/powerpc/kernel/dma-swiotlb.c 
b/arch/powerpc/kernel/dma-swiotlb.c
index 88f3963ca30f..93a4622563c6 100644
--- a/arch/powerpc/kernel/dma-swiotlb.c
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -108,12 +108,8 @@ int __init swiotlb_setup_bus_notifier(void)
 
 void __init swiotlb_detect_4g(void)
 {
-   if ((memblock_end_of_DRAM() - 1) > 0x) {
+   if ((memblock_end_of_DRAM() - 1) > 0x)
ppc_swiotlb_enable = 1;
-#ifdef CONFIG_ZONE_DMA32
-   limit_zone_pfn(ZONE_DMA32, (1ULL << 32) >> PAGE_SHIFT);
-#endif
-   }
 }
 
 static int __init check_swiotlb_enabled(void)
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index dbfc7056d7df..6551685a4ed0 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -50,7 +50,7 @@ static int dma_nommu_dma_supported(struct device *dev, u64 
mask)
return 1;
 
 #ifdef CONFIG_FSL_SOC
-   /* Freescale gets another chance via ZONE_DMA/ZONE_DMA32, however
+   /* Freescale gets another chance via ZONE_DMA, however
 * that will have to be refined if/when they support iommus
 */
return 1;
@@ -94,13 +94,10 @@ void *__dma_nommu_alloc_coherent(struct device *dev, size_t 
size,
}
 
switch (zone) {
+#ifdef CONFIG_ZONE_DMA
case ZONE_DMA:
flag |= GFP_DMA;
break;
-#ifdef CONFIG_ZONE_DMA32
-   case ZONE_DMA32:
-   flag |= GFP_DMA32;
-   break;
 #endif
};
 #endif /* CONFIG_FSL_SOC */
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 5c8530d0c611..8bff7e893bde 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -69,15 +69,12 @@ pte_t *kmap_pte;
 EXPORT_SYMBOL(kmap_pte);
 pgprot_t kmap_prot;
 EXPORT_SYMBOL(kmap_prot);
-#define TOP_ZONE ZONE_HIGHMEM
 
 static inline pte_t *virt_to_kpte(unsigned long vaddr)
 {
return pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr),
vaddr), vaddr), vaddr);
 }
-#else
-#define TOP_ZONE ZONE_NORMAL
 #endif
 
 int page_is_ram(unsigned long pfn)
@@ -246,35 +243,19 @@ static int __init mark_nonram_nosave(void)
 }
 #endif
 
-static bool zone_limits_final;
-
-/*
- * The memory zones past TOP_ZONE are managed by generic mm code.
- * These should be set to zero since that's what every other
- * architecture does.
- */
-static unsigned long 

[PATCH 03/33] powerpc/dma: remove the unused ISA_DMA_THRESHOLD export

2018-10-09 Thread Christoph Hellwig
Signed-off-by: Christoph Hellwig 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/kernel/setup_32.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 8c507be12c3c..3cc2e449594c 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -59,7 +59,6 @@ unsigned long ISA_DMA_THRESHOLD;
 unsigned int DMA_MODE_READ;
 unsigned int DMA_MODE_WRITE;
 
-EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
 EXPORT_SYMBOL(DMA_MODE_READ);
 EXPORT_SYMBOL(DMA_MODE_WRITE);
 
-- 
2.19.0



[PATCH 06/33] powerpc/dma: remove the no-op dma_nommu_unmap_{page, sg} routines

2018-10-09 Thread Christoph Hellwig
These methods are optional, no need to implement no-op versions.

Signed-off-by: Christoph Hellwig 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/kernel/dma.c | 16 
 1 file changed, 16 deletions(-)

diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index d6deb458bb91..7078d72baec2 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -197,12 +197,6 @@ static int dma_nommu_map_sg(struct device *dev, struct 
scatterlist *sgl,
return nents;
 }
 
-static void dma_nommu_unmap_sg(struct device *dev, struct scatterlist *sg,
-   int nents, enum dma_data_direction direction,
-   unsigned long attrs)
-{
-}
-
 static u64 dma_nommu_get_required_mask(struct device *dev)
 {
u64 end, mask;
@@ -228,14 +222,6 @@ static inline dma_addr_t dma_nommu_map_page(struct device 
*dev,
return page_to_phys(page) + offset + get_dma_offset(dev);
 }
 
-static inline void dma_nommu_unmap_page(struct device *dev,
-dma_addr_t dma_address,
-size_t size,
-enum dma_data_direction direction,
-unsigned long attrs)
-{
-}
-
 #ifdef CONFIG_NOT_COHERENT_CACHE
 static inline void dma_nommu_sync_sg(struct device *dev,
struct scatterlist *sgl, int nents,
@@ -261,10 +247,8 @@ const struct dma_map_ops dma_nommu_ops = {
.free   = dma_nommu_free_coherent,
.mmap   = dma_nommu_mmap_coherent,
.map_sg = dma_nommu_map_sg,
-   .unmap_sg   = dma_nommu_unmap_sg,
.dma_supported  = dma_nommu_dma_supported,
.map_page   = dma_nommu_map_page,
-   .unmap_page = dma_nommu_unmap_page,
.get_required_mask  = dma_nommu_get_required_mask,
 #ifdef CONFIG_NOT_COHERENT_CACHE
.sync_single_for_cpu= dma_nommu_sync_single,
-- 
2.19.0



[PATCH 32/33] powerpc/dma: use generic direct and swiotlb ops

2018-10-09 Thread Christoph Hellwig
 - The ppc32 case of dma_nommu_dma_supported already was a no-op, and the
   64-bit case came to the same conclusion as dma_direct_supported, so
   replace it with the generic version.

 - supports CMA

 - Note that the cache maintainance in the existing code is a bit odd
   as it implements both the sync_to_device and sync_to_cpu callouts,
   but never flushes caches when unmapping.  This patch keeps both
   directions arounds, which will lead to more flushing than the previous
   implementation.  Someone more familar with the required CPUs should
   eventually take a look and optimize the cache flush handling if needed.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/Kconfig   |   1 +
 arch/powerpc/include/asm/dma-mapping.h |  40 --
 arch/powerpc/include/asm/pgtable.h |   1 -
 arch/powerpc/include/asm/swiotlb.h |   2 -
 arch/powerpc/kernel/Makefile   |   2 +-
 arch/powerpc/kernel/dma-iommu.c|  11 +-
 arch/powerpc/kernel/dma-swiotlb.c  |  24 +---
 arch/powerpc/kernel/dma.c  | 190 -
 arch/powerpc/kernel/pci-common.c   |   2 +-
 arch/powerpc/kernel/setup-common.c |   2 +-
 arch/powerpc/mm/dma-noncoherent.c  |  35 +++--
 arch/powerpc/mm/mem.c  |  19 ---
 arch/powerpc/platforms/44x/warp.c  |   2 +-
 arch/powerpc/platforms/Kconfig.cputype |   2 +
 arch/powerpc/platforms/cell/iommu.c|   4 +-
 arch/powerpc/platforms/pasemi/iommu.c  |   2 +-
 arch/powerpc/platforms/pasemi/setup.c  |   2 +-
 arch/powerpc/platforms/pseries/vio.c   |   7 +
 arch/powerpc/sysdev/fsl_pci.c  |   2 +-
 drivers/misc/cxl/vphb.c|   2 +-
 20 files changed, 49 insertions(+), 303 deletions(-)
 delete mode 100644 arch/powerpc/kernel/dma.c

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 7ea01687995d..7d29524533b4 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -155,6 +155,7 @@ config PPC
select CLONE_BACKWARDS
select DCACHE_WORD_ACCESS   if PPC64 && CPU_LITTLE_ENDIAN
select DYNAMIC_FTRACE   if FUNCTION_TRACER
+   select DMA_DIRECT_OPS
select EDAC_ATOMIC_SCRUB
select EDAC_SUPPORT
select GENERIC_ATOMIC64 if PPC32
diff --git a/arch/powerpc/include/asm/dma-mapping.h 
b/arch/powerpc/include/asm/dma-mapping.h
index ababad4b07a7..a59c42879194 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -18,45 +18,6 @@
 #include 
 #include 
 
-/* Some dma direct funcs must be visible for use in other dma_ops */
-extern void *__dma_nommu_alloc_coherent(struct device *dev, size_t size,
-dma_addr_t *dma_handle, gfp_t flag,
-unsigned long attrs);
-extern void __dma_nommu_free_coherent(struct device *dev, size_t size,
-  void *vaddr, dma_addr_t dma_handle,
-  unsigned long attrs);
-int dma_nommu_map_sg(struct device *dev, struct scatterlist *sgl,
-   int nents, enum dma_data_direction direction,
-   unsigned long attrs);
-dma_addr_t dma_nommu_map_page(struct device *dev, struct page *page,
-   unsigned long offset, size_t size,
-   enum dma_data_direction dir, unsigned long attrs);
-int dma_nommu_dma_supported(struct device *dev, u64 mask);
-
-#ifdef CONFIG_NOT_COHERENT_CACHE
-/*
- * DMA-consistent mapping functions for PowerPCs that don't support
- * cache snooping.  These allocate/free a region of uncached mapped
- * memory space for use with DMA devices.  Alternatively, you could
- * allocate the space "normally" and use the cache management functions
- * to ensure it is consistent.
- */
-struct device;
-extern void __dma_sync(void *vaddr, size_t size, int direction);
-extern void __dma_sync_page(struct page *page, unsigned long offset,
-size_t size, int direction);
-extern unsigned long __dma_get_coherent_pfn(unsigned long cpu_addr);
-
-#else /* ! CONFIG_NOT_COHERENT_CACHE */
-/*
- * Cache coherent cores.
- */
-
-#define __dma_sync(addr, size, rw) ((void)0)
-#define __dma_sync_page(pg, off, sz, rw)   ((void)0)
-
-#endif /* ! CONFIG_NOT_COHERENT_CACHE */
-
 static inline unsigned long device_to_mask(struct device *dev)
 {
if (dev->dma_mask && *dev->dma_mask)
@@ -71,7 +32,6 @@ static inline unsigned long device_to_mask(struct device *dev)
 #ifdef CONFIG_PPC64
 extern const struct dma_map_ops dma_iommu_ops;
 #endif
-extern const struct dma_map_ops dma_nommu_ops;
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
diff --git a/arch/powerpc/include/asm/pgtable.h 
b/arch/powerpc/include/asm/pgtable.h
index 9bafb38e959e..853372fe1001 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -37,7 +37,6 @@ extern unsigned long 

[PATCH 30/33] powerpc/dma: remove set_dma_offset

2018-10-09 Thread Christoph Hellwig
There is no good reason for this helper, just opencode it.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/include/asm/dma-mapping.h| 6 --
 arch/powerpc/kernel/pci-common.c  | 2 +-
 arch/powerpc/platforms/cell/iommu.c   | 4 ++--
 arch/powerpc/platforms/powernv/pci-ioda.c | 6 +++---
 arch/powerpc/platforms/pseries/iommu.c| 7 ++-
 arch/powerpc/sysdev/dart_iommu.c  | 2 +-
 arch/powerpc/sysdev/fsl_pci.c | 2 +-
 drivers/misc/cxl/vphb.c   | 2 +-
 8 files changed, 11 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/include/asm/dma-mapping.h 
b/arch/powerpc/include/asm/dma-mapping.h
index 2d0879b0acf3..e12439ae8211 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -87,11 +87,5 @@ static inline const struct dma_map_ops 
*get_arch_dma_ops(struct bus_type *bus)
return NULL;
 }
 
-static inline void set_dma_offset(struct device *dev, dma_addr_t off)
-{
-   if (dev)
-   dev->archdata.dma_offset = off;
-}
-
 #endif /* __KERNEL__ */
 #endif /* _ASM_DMA_MAPPING_H */
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index a84707680525..fca2b0bafd82 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -966,7 +966,7 @@ static void pcibios_setup_device(struct pci_dev *dev)
 
/* Hook up default DMA ops */
set_dma_ops(>dev, pci_dma_ops);
-   set_dma_offset(>dev, PCI_DRAM_OFFSET);
+   dev->dev.archdata.dma_offset = PCI_DRAM_OFFSET;
 
/* Additional platform DMA/iommu setup */
phb = pci_bus_to_host(dev->bus);
diff --git a/arch/powerpc/platforms/cell/iommu.c 
b/arch/powerpc/platforms/cell/iommu.c
index 93c7e4aef571..997ee0f5fc2f 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -577,10 +577,10 @@ static void cell_dma_dev_setup(struct device *dev)
u64 addr = cell_iommu_get_fixed_address(dev);
 
if (addr != OF_BAD_ADDR)
-   set_dma_offset(dev, addr + dma_iommu_fixed_base);
+   dev->archdata.dma_offset = addr + dma_iommu_fixed_base;
set_iommu_table_base(dev, cell_get_iommu_table(dev));
} else {
-   set_dma_offset(dev, cell_dma_nommu_offset);
+   dev->archdata.dma_offset = cell_dma_nommu_offset;
}
 }
 
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 5748b62e2e86..e2333e10598d 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1660,7 +1660,7 @@ static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb 
*phb, struct pci_dev *pdev
 
pe = >ioda.pe_array[pdn->pe_number];
WARN_ON(get_dma_ops(>dev) != _iommu_ops);
-   set_dma_offset(>dev, pe->tce_bypass_base);
+   pdev->dev.archdata.dma_offset = pe->tce_bypass_base;
set_iommu_table_base(>dev, pe->table_group.tables[0]);
/*
 * Note: iommu_add_device() will fail here as
@@ -1773,7 +1773,7 @@ static bool pnv_pci_ioda_iommu_bypass_supported(struct 
pci_dev *pdev,
if (rc)
return rc;
/* 4GB offset bypasses 32-bit space */
-   set_dma_offset(>dev, (1ULL << 32));
+   pdev->dev.archdata.dma_offset = (1ULL << 32);
return true;
}
 
@@ -1788,7 +1788,7 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe,
 
list_for_each_entry(dev, >devices, bus_list) {
set_iommu_table_base(>dev, pe->table_group.tables[0]);
-   set_dma_offset(>dev, pe->tce_bypass_base);
+   dev->dev.archdata.dma_offset = pe->tce_bypass_base;
if (add_to_group)
iommu_add_device(>dev);
 
diff --git a/arch/powerpc/platforms/pseries/iommu.c 
b/arch/powerpc/platforms/pseries/iommu.c
index 8965d174c53b..a2ff20d154fe 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -1197,7 +1197,6 @@ static bool iommu_bypass_supported_pSeriesLP(struct 
pci_dev *pdev, u64 dma_mask)
 {
struct device_node *dn = pci_device_to_OF_node(pdev), *pdn;
const __be32 *dma_window = NULL;
-   u64 dma_offset;
 
/* only attempt to use a new window if 64-bit DMA is requested */
if (dma_mask < DMA_BIT_MASK(64))
@@ -1219,11 +1218,9 @@ static bool iommu_bypass_supported_pSeriesLP(struct 
pci_dev *pdev, u64 dma_mask)
}
 
if (pdn && PCI_DN(pdn)) {
-   dma_offset = enable_ddw(pdev, pdn);
-   if (dma_offset != 0) {
-   set_dma_offset(>dev, dma_offset);
+   pdev->dev.archdata.dma_offset = enable_ddw(pdev, pdn);
+   if (pdev->dev.archdata.dma_offset)
return true;
-   }
}
 
return false;
diff 

[PATCH 33/33] powerpc/dma: trim the fat from

2018-10-09 Thread Christoph Hellwig
There is no need to provide anything but get_arch_dma_ops to
.  More the remaining declarations to 
and drop all the includes.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/include/asm/dma-mapping.h | 29 --
 arch/powerpc/include/asm/iommu.h   | 10 +
 arch/powerpc/platforms/44x/ppc476.c|  1 +
 3 files changed, 11 insertions(+), 29 deletions(-)

diff --git a/arch/powerpc/include/asm/dma-mapping.h 
b/arch/powerpc/include/asm/dma-mapping.h
index a59c42879194..565d6f74b189 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -1,37 +1,9 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) 2004 IBM
- *
- * Implements the generic device dma API for powerpc.
- * the pci and vio busses
  */
 #ifndef _ASM_DMA_MAPPING_H
 #define _ASM_DMA_MAPPING_H
-#ifdef __KERNEL__
-
-#include 
-#include 
-/* need struct page definitions */
-#include 
-#include 
-#include 
-#include 
-#include 
-
-static inline unsigned long device_to_mask(struct device *dev)
-{
-   if (dev->dma_mask && *dev->dma_mask)
-   return *dev->dma_mask;
-   /* Assume devices without mask can take 32 bit addresses */
-   return 0xul;
-}
-
-/*
- * Available generic sets of operations
- */
-#ifdef CONFIG_PPC64
-extern const struct dma_map_ops dma_iommu_ops;
-#endif
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
@@ -43,5 +15,4 @@ static inline const struct dma_map_ops 
*get_arch_dma_ops(struct bus_type *bus)
return NULL;
 }
 
-#endif /* __KERNEL__ */
 #endif /* _ASM_DMA_MAPPING_H */
diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 264d04f1dcd1..db745575e6a4 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -334,5 +334,15 @@ extern bool iommu_fixed_is_weak;
 #define iommu_fixed_is_weak false
 #endif
 
+extern const struct dma_map_ops dma_iommu_ops;
+
+static inline unsigned long device_to_mask(struct device *dev)
+{
+   if (dev->dma_mask && *dev->dma_mask)
+   return *dev->dma_mask;
+   /* Assume devices without mask can take 32 bit addresses */
+   return 0xul;
+}
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_IOMMU_H */
diff --git a/arch/powerpc/platforms/44x/ppc476.c 
b/arch/powerpc/platforms/44x/ppc476.c
index e55933f9cd55..a5e61e5c16e2 100644
--- a/arch/powerpc/platforms/44x/ppc476.c
+++ b/arch/powerpc/platforms/44x/ppc476.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
-- 
2.19.0



[PATCH 26/33] powerpc/fsl_pci: simplify fsl_pci_dma_set_mask

2018-10-09 Thread Christoph Hellwig
swiotlb will only bounce buffer the effectice dma address for the device
is smaller than the actual DMA range.  Instead of flipping between the
swiotlb and nommu ops for FSL SOCs that have the second outbound window
just don't set the bus dma_mask in this case.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/sysdev/fsl_pci.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index f136567a5ed5..296ffabc9386 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -143,7 +143,7 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 
dma_mask)
 * mapping that allows addressing any RAM address from across PCI.
 */
if (dev_is_pci(dev) && dma_mask >= pci64_dma_offset * 2 - 1) {
-   set_dma_ops(dev, _nommu_ops);
+   dev->bus_dma_mask = 0;
set_dma_offset(dev, pci64_dma_offset);
}
 
@@ -403,10 +403,6 @@ static void setup_pci_atmu(struct pci_controller *hose)
out_be32(>piw[win_idx].piwar,  piwar);
}
 
-   /*
-* install our own dma_set_mask handler to fixup dma_ops
-* and dma_offset
-*/
ppc_md.dma_set_mask = fsl_pci_dma_set_mask;
 
pr_info("%pOF: Setup 64-bit PCI DMA window\n", 
hose->dn);
-- 
2.19.0



[PATCH 31/33] powerpc/dma: remove dma_nommu_mmap_coherent

2018-10-09 Thread Christoph Hellwig
The coherent cache version of this function already is functionally
identicall to the default version, and by defining the
arch_dma_coherent_to_pfn hook the same is ture for the noncoherent
version as well.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/include/asm/dma-mapping.h |  4 
 arch/powerpc/kernel/dma-iommu.c|  1 -
 arch/powerpc/kernel/dma-swiotlb.c  |  1 -
 arch/powerpc/kernel/dma.c  | 19 ---
 arch/powerpc/mm/dma-noncoherent.c  |  7 +--
 arch/powerpc/platforms/Kconfig.cputype |  1 +
 arch/powerpc/platforms/pseries/vio.c   |  1 -
 7 files changed, 6 insertions(+), 28 deletions(-)

diff --git a/arch/powerpc/include/asm/dma-mapping.h 
b/arch/powerpc/include/asm/dma-mapping.h
index e12439ae8211..ababad4b07a7 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -25,10 +25,6 @@ extern void *__dma_nommu_alloc_coherent(struct device *dev, 
size_t size,
 extern void __dma_nommu_free_coherent(struct device *dev, size_t size,
   void *vaddr, dma_addr_t dma_handle,
   unsigned long attrs);
-extern int dma_nommu_mmap_coherent(struct device *dev,
-   struct vm_area_struct *vma,
-   void *cpu_addr, dma_addr_t handle,
-   size_t size, unsigned long attrs);
 int dma_nommu_map_sg(struct device *dev, struct scatterlist *sgl,
int nents, enum dma_data_direction direction,
unsigned long attrs);
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index 7fa3636636fa..2e682004959f 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -172,7 +172,6 @@ int dma_iommu_mapping_error(struct device *dev, dma_addr_t 
dma_addr)
 const struct dma_map_ops dma_iommu_ops = {
.alloc  = dma_iommu_alloc_coherent,
.free   = dma_iommu_free_coherent,
-   .mmap   = dma_nommu_mmap_coherent,
.map_sg = dma_iommu_map_sg,
.unmap_sg   = dma_iommu_unmap_sg,
.dma_supported  = dma_iommu_dma_supported,
diff --git a/arch/powerpc/kernel/dma-swiotlb.c 
b/arch/powerpc/kernel/dma-swiotlb.c
index d33caff8c684..c6f8519f8d4e 100644
--- a/arch/powerpc/kernel/dma-swiotlb.c
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -42,7 +42,6 @@ unsigned int ppc_swiotlb_enable;
 const struct dma_map_ops powerpc_swiotlb_dma_ops = {
.alloc = __dma_nommu_alloc_coherent,
.free = __dma_nommu_free_coherent,
-   .mmap = dma_nommu_mmap_coherent,
.map_sg = swiotlb_map_sg_attrs,
.unmap_sg = swiotlb_unmap_sg_attrs,
.dma_supported = swiotlb_dma_supported,
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 7f7f3a069b63..92cc402d249f 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -113,24 +113,6 @@ void __dma_nommu_free_coherent(struct device *dev, size_t 
size,
 }
 #endif /* !CONFIG_NOT_COHERENT_CACHE */
 
-int dma_nommu_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
-void *cpu_addr, dma_addr_t handle, size_t size,
-unsigned long attrs)
-{
-   unsigned long pfn;
-
-#ifdef CONFIG_NOT_COHERENT_CACHE
-   vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-   pfn = __dma_get_coherent_pfn((unsigned long)cpu_addr);
-#else
-   pfn = page_to_pfn(virt_to_page(cpu_addr));
-#endif
-   return remap_pfn_range(vma, vma->vm_start,
-  pfn + vma->vm_pgoff,
-  vma->vm_end - vma->vm_start,
-  vma->vm_page_prot);
-}
-
 int dma_nommu_map_sg(struct device *dev, struct scatterlist *sgl,
int nents, enum dma_data_direction direction,
unsigned long attrs)
@@ -184,7 +166,6 @@ static inline void dma_nommu_sync_single(struct device *dev,
 const struct dma_map_ops dma_nommu_ops = {
.alloc  = __dma_nommu_alloc_coherent,
.free   = __dma_nommu_free_coherent,
-   .mmap   = dma_nommu_mmap_coherent,
.map_sg = dma_nommu_map_sg,
.dma_supported  = dma_nommu_dma_supported,
.map_page   = dma_nommu_map_page,
diff --git a/arch/powerpc/mm/dma-noncoherent.c 
b/arch/powerpc/mm/dma-noncoherent.c
index 965ce3d19f5a..a016c9c356d5 100644
--- a/arch/powerpc/mm/dma-noncoherent.c
+++ b/arch/powerpc/mm/dma-noncoherent.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -400,14 +401,16 @@ EXPORT_SYMBOL(__dma_sync_page);
 
 /*
  * Return the PFN for a given cpu virtual address returned by
- * __dma_nommu_alloc_coherent. This is used by 

[PATCH 29/33] powerpc/dma: remove get_dma_offset

2018-10-09 Thread Christoph Hellwig
Just fold the calculation into __phys_to_dma/__dma_to_phys as those are
the only places that should know about it.

Signed-off-by: Christoph Hellwig 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/include/asm/dma-direct.h  |  8 ++--
 arch/powerpc/include/asm/dma-mapping.h | 16 
 2 files changed, 6 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/include/asm/dma-direct.h 
b/arch/powerpc/include/asm/dma-direct.h
index 92d8aed86422..a2912b47102c 100644
--- a/arch/powerpc/include/asm/dma-direct.h
+++ b/arch/powerpc/include/asm/dma-direct.h
@@ -13,11 +13,15 @@ static inline bool dma_capable(struct device *dev, 
dma_addr_t addr, size_t size)
 
 static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
-   return paddr + get_dma_offset(dev);
+   if (!dev)
+   return paddr + PCI_DRAM_OFFSET;
+   return paddr + dev->archdata.dma_offset;
 }
 
 static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr)
 {
-   return daddr - get_dma_offset(dev);
+   if (!dev)
+   return daddr - PCI_DRAM_OFFSET;
+   return daddr - dev->archdata.dma_offset;
 }
 #endif /* ASM_POWERPC_DMA_DIRECT_H */
diff --git a/arch/powerpc/include/asm/dma-mapping.h 
b/arch/powerpc/include/asm/dma-mapping.h
index 7694985f05ee..2d0879b0acf3 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -87,22 +87,6 @@ static inline const struct dma_map_ops 
*get_arch_dma_ops(struct bus_type *bus)
return NULL;
 }
 
-/*
- * get_dma_offset()
- *
- * Get the dma offset on configurations where the dma address can be determined
- * from the physical address by looking at a simple offset.  Direct dma and
- * swiotlb use this function, but it is typically not used by implementations
- * with an iommu.
- */
-static inline dma_addr_t get_dma_offset(struct device *dev)
-{
-   if (dev)
-   return dev->archdata.dma_offset;
-
-   return PCI_DRAM_OFFSET;
-}
-
 static inline void set_dma_offset(struct device *dev, dma_addr_t off)
 {
if (dev)
-- 
2.19.0



[PATCH 27/33] dma-mapping, powerpc: simplify the arch dma_set_mask override

2018-10-09 Thread Christoph Hellwig
Instead of letting the architecture supply all of dma_set_mask just
give it an additional hook selected by Kconfig.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/Kconfig   |  1 +
 arch/powerpc/include/asm/dma-mapping.h |  3 ---
 arch/powerpc/kernel/dma-swiotlb.c  |  8 
 arch/powerpc/kernel/dma.c  | 12 
 arch/powerpc/sysdev/fsl_pci.c  |  4 
 include/linux/dma-mapping.h| 11 ---
 kernel/dma/Kconfig |  3 +++
 7 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 7097019d8907..7ea01687995d 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -126,6 +126,7 @@ config PPC
# Please keep this list sorted alphabetically.
#
select ARCH_HAS_DEVMEM_IS_ALLOWED
+   select ARCH_HAS_DMA_SET_MASKif SWIOTLB
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_GCOV_PROFILE_ALL
diff --git a/arch/powerpc/include/asm/dma-mapping.h 
b/arch/powerpc/include/asm/dma-mapping.h
index b1999880fc61..7694985f05ee 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -109,8 +109,5 @@ static inline void set_dma_offset(struct device *dev, 
dma_addr_t off)
dev->archdata.dma_offset = off;
 }
 
-#define HAVE_ARCH_DMA_SET_MASK 1
-extern int dma_set_mask(struct device *dev, u64 dma_mask);
-
 #endif /* __KERNEL__ */
 #endif /* _ASM_DMA_MAPPING_H */
diff --git a/arch/powerpc/kernel/dma-swiotlb.c 
b/arch/powerpc/kernel/dma-swiotlb.c
index e05d95ff50ad..dba216dd70fd 100644
--- a/arch/powerpc/kernel/dma-swiotlb.c
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -22,6 +22,14 @@
 #include 
 #include 
 
+bool arch_dma_set_mask(struct device *dev, u64 dma_mask)
+{
+   if (!ppc_md.dma_set_mask)
+   return 0;
+   return ppc_md.dma_set_mask(dev, dma_mask);
+}
+EXPORT_SYMBOL(arch_dma_set_mask);
+
 unsigned int ppc_swiotlb_enable;
 
 /*
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index e3d2c15b209c..795afe387c91 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -197,18 +197,6 @@ const struct dma_map_ops dma_nommu_ops = {
 };
 EXPORT_SYMBOL(dma_nommu_ops);
 
-int dma_set_mask(struct device *dev, u64 dma_mask)
-{
-   if (ppc_md.dma_set_mask)
-   return ppc_md.dma_set_mask(dev, dma_mask);
-
-   if (!dev->dma_mask || !dma_supported(dev, dma_mask))
-   return -EIO;
-   *dev->dma_mask = dma_mask;
-   return 0;
-}
-EXPORT_SYMBOL(dma_set_mask);
-
 static int __init dma_init(void)
 {
 #ifdef CONFIG_IBMVIO
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 296ffabc9386..cb91a3d113d1 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -135,9 +135,6 @@ static inline void setup_swiotlb_ops(struct pci_controller 
*hose) {}
 
 static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
 {
-   if (!dev->dma_mask || !dma_supported(dev, dma_mask))
-   return -EIO;
-
/*
 * Fix up PCI devices that are able to DMA to the large inbound
 * mapping that allows addressing any RAM address from across PCI.
@@ -147,7 +144,6 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 
dma_mask)
set_dma_offset(dev, pci64_dma_offset);
}
 
-   *dev->dma_mask = dma_mask;
return 0;
 }
 
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 15bd41447025..8dd19e66c0e5 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -598,18 +598,23 @@ static inline int dma_supported(struct device *dev, u64 
mask)
return ops->dma_supported(dev, mask);
 }
 
-#ifndef HAVE_ARCH_DMA_SET_MASK
+#ifdef CONFIG_ARCH_HAS_DMA_SET_MASK
+bool arch_dma_set_mask(struct device *dev, u64 mask);
+#else
+#define arch_dma_set_mask(dev, mask)   true
+#endif
+
 static inline int dma_set_mask(struct device *dev, u64 mask)
 {
if (!dev->dma_mask || !dma_supported(dev, mask))
return -EIO;
-
+   if (!arch_dma_set_mask(dev, mask))
+   return -EIO;
dma_check_mask(dev, mask);
 
*dev->dma_mask = mask;
return 0;
 }
-#endif
 
 static inline u64 dma_get_mask(struct device *dev)
 {
diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig
index 645c7a2ecde8..951045c90c2c 100644
--- a/kernel/dma/Kconfig
+++ b/kernel/dma/Kconfig
@@ -16,6 +16,9 @@ config ARCH_DMA_ADDR_T_64BIT
 config ARCH_HAS_DMA_COHERENCE_H
bool
 
+config ARCH_HAS_DMA_SET_MASK
+   bool
+
 config HAVE_GENERIC_DMA_COHERENT
bool
 
-- 
2.19.0



[PATCH 28/33] powerpc/dma: use phys_to_dma instead of get_dma_offset

2018-10-09 Thread Christoph Hellwig
Use the standard portable helper instead of the powerpc specific one,
which is about to go away.

Signed-off-by: Christoph Hellwig 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/kernel/dma-swiotlb.c |  2 +-
 arch/powerpc/kernel/dma.c | 10 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/dma-swiotlb.c 
b/arch/powerpc/kernel/dma-swiotlb.c
index dba216dd70fd..d33caff8c684 100644
--- a/arch/powerpc/kernel/dma-swiotlb.c
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -11,7 +11,7 @@
  *
  */
 
-#include 
+#include 
 #include 
 #include 
 #include 
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 795afe387c91..7f7f3a069b63 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -6,7 +6,7 @@
  */
 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -42,7 +42,7 @@ static u64 __maybe_unused get_pfn_limit(struct device *dev)
 int dma_nommu_dma_supported(struct device *dev, u64 mask)
 {
 #ifdef CONFIG_PPC64
-   u64 limit = get_dma_offset(dev) + (memblock_end_of_DRAM() - 1);
+   u64 limit = phys_to_dma(dev, (memblock_end_of_DRAM() - 1));
 
/* Limit fits in the mask, we are good */
if (mask >= limit)
@@ -100,7 +100,7 @@ void *__dma_nommu_alloc_coherent(struct device *dev, size_t 
size,
return NULL;
ret = page_address(page);
memset(ret, 0, size);
-   *dma_handle = __pa(ret) + get_dma_offset(dev);
+   *dma_handle = phys_to_dma(dev,__pa(ret));
 
return ret;
 }
@@ -139,7 +139,7 @@ int dma_nommu_map_sg(struct device *dev, struct scatterlist 
*sgl,
int i;
 
for_each_sg(sgl, sg, nents, i) {
-   sg->dma_address = sg_phys(sg) + get_dma_offset(dev);
+   sg->dma_address = phys_to_dma(dev, sg_phys(sg));
sg->dma_length = sg->length;
 
if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
@@ -158,7 +158,7 @@ dma_addr_t dma_nommu_map_page(struct device *dev, struct 
page *page,
if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
__dma_sync_page(page, offset, size, dir);
 
-   return page_to_phys(page) + offset + get_dma_offset(dev);
+   return phys_to_dma(dev, page_to_phys(page)) + offset;
 }
 
 #ifdef CONFIG_NOT_COHERENT_CACHE
-- 
2.19.0



[PATCH 21/33] powerpc/dma: remove get_pci_dma_ops

2018-10-09 Thread Christoph Hellwig
This function is only used by the Cell iommu code, which can keep track
if it is using the iommu internally just as good.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/include/asm/pci.h  |  2 --
 arch/powerpc/kernel/pci-common.c|  6 --
 arch/powerpc/platforms/cell/iommu.c | 17 -
 3 files changed, 8 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index a01d2e3d6ff9..4f7cf0a7f89d 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -52,10 +52,8 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev 
*dev, int channel)
 
 #ifdef CONFIG_PCI
 extern void set_pci_dma_ops(const struct dma_map_ops *dma_ops);
-extern const struct dma_map_ops *get_pci_dma_ops(void);
 #else  /* CONFIG_PCI */
 #define set_pci_dma_ops(d)
-#define get_pci_dma_ops()  NULL
 #endif
 
 #ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 88e4f69a09e5..a84707680525 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -69,12 +69,6 @@ void set_pci_dma_ops(const struct dma_map_ops *dma_ops)
pci_dma_ops = dma_ops;
 }
 
-const struct dma_map_ops *get_pci_dma_ops(void)
-{
-   return pci_dma_ops;
-}
-EXPORT_SYMBOL(get_pci_dma_ops);
-
 /*
  * This function should run under locking protection, specifically
  * hose_spinlock.
diff --git a/arch/powerpc/platforms/cell/iommu.c 
b/arch/powerpc/platforms/cell/iommu.c
index fb51f78035ce..93c7e4aef571 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -544,6 +544,7 @@ static struct cbe_iommu *cell_iommu_for_node(int nid)
 static unsigned long cell_dma_nommu_offset;
 
 static unsigned long dma_iommu_fixed_base;
+static bool cell_iommu_enabled;
 
 /* iommu_fixed_is_weak is set if booted with iommu_fixed=weak */
 bool iommu_fixed_is_weak;
@@ -572,16 +573,14 @@ static u64 cell_iommu_get_fixed_address(struct device 
*dev);
 
 static void cell_dma_dev_setup(struct device *dev)
 {
-   if (get_pci_dma_ops() == _iommu_ops) {
+   if (cell_iommu_enabled) {
u64 addr = cell_iommu_get_fixed_address(dev);
 
if (addr != OF_BAD_ADDR)
set_dma_offset(dev, addr + dma_iommu_fixed_base);
set_iommu_table_base(dev, cell_get_iommu_table(dev));
-   } else if (get_pci_dma_ops() == _nommu_ops) {
-   set_dma_offset(dev, cell_dma_nommu_offset);
} else {
-   BUG();
+   set_dma_offset(dev, cell_dma_nommu_offset);
}
 }
 
@@ -599,11 +598,11 @@ static int cell_of_bus_notify(struct notifier_block *nb, 
unsigned long action,
if (action != BUS_NOTIFY_ADD_DEVICE)
return 0;
 
-   /* We use the PCI DMA ops */
-   dev->dma_ops = get_pci_dma_ops();
-
+   if (cell_iommu_enabled)
+   dev->dma_ops = _iommu_ops;
+   else
+   dev->dma_ops = _nommu_ops;
cell_dma_dev_setup(dev);
-
return 0;
 }
 
@@ -1091,7 +1090,7 @@ static int __init cell_iommu_init(void)
cell_pci_iommu_bypass_supported;
}
set_pci_dma_ops(_iommu_ops);
-
+   cell_iommu_enabled = true;
  bail:
/* Register callbacks on OF platform device addition/removal
 * to handle linking them to the right DMA operations
-- 
2.19.0



[PATCH 25/33] cxl: drop the dma_set_mask callback from vphb

2018-10-09 Thread Christoph Hellwig
The CXL code never even looks at the dma mask, so there is no good
reason for this sanity check.  Remove it because it gets in the way
of the dma ops refactoring.

Signed-off-by: Christoph Hellwig 
---
 drivers/misc/cxl/vphb.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c
index 7908633d9204..49da2f744bbf 100644
--- a/drivers/misc/cxl/vphb.c
+++ b/drivers/misc/cxl/vphb.c
@@ -11,17 +11,6 @@
 #include 
 #include "cxl.h"
 
-static int cxl_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
-{
-   if (dma_mask < DMA_BIT_MASK(64)) {
-   pr_info("%s only 64bit DMA supported on CXL", __func__);
-   return -EIO;
-   }
-
-   *(pdev->dev.dma_mask) = dma_mask;
-   return 0;
-}
-
 static int cxl_pci_probe_mode(struct pci_bus *bus)
 {
return PCI_PROBE_NORMAL;
@@ -220,7 +209,6 @@ static struct pci_controller_ops cxl_pci_controller_ops =
.reset_secondary_bus = cxl_pci_reset_secondary_bus,
.setup_msi_irqs = cxl_setup_msi_irqs,
.teardown_msi_irqs = cxl_teardown_msi_irqs,
-   .dma_set_mask = cxl_dma_set_mask,
 };
 
 int cxl_pci_vphb_add(struct cxl_afu *afu)
-- 
2.19.0



[PATCH 24/33] powerpc/dma: fix an off-by-one in dma_capable

2018-10-09 Thread Christoph Hellwig
We need to compare the last byte in the dma range and not the one after it
for the bus_dma_mask, just like we do for the regular dma_mask.  Fix this
cleanly by merging the two comparisms into one.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/include/asm/dma-direct.h | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/dma-direct.h 
b/arch/powerpc/include/asm/dma-direct.h
index e00ab5d0612d..92d8aed86422 100644
--- a/arch/powerpc/include/asm/dma-direct.h
+++ b/arch/powerpc/include/asm/dma-direct.h
@@ -4,15 +4,11 @@
 
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t 
size)
 {
-#ifdef CONFIG_SWIOTLB
-   if (dev->bus_dma_mask && addr + size > dev->bus_dma_mask)
-   return false;
-#endif
-
if (!dev->dma_mask)
return false;
 
-   return addr + size - 1 <= *dev->dma_mask;
+   return addr + size - 1 <=
+   min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
 }
 
 static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
-- 
2.19.0



[PATCH 23/33] powerpc/dma: remove max_direct_dma_addr

2018-10-09 Thread Christoph Hellwig
The max_direct_dma_addr duplicates the bus_dma_mask field in struct
device.  Use the generic field instead.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/include/asm/device.h |  3 ---
 arch/powerpc/include/asm/dma-direct.h |  4 +---
 arch/powerpc/kernel/dma-swiotlb.c | 20 
 arch/powerpc/kernel/dma.c |  5 ++---
 arch/powerpc/sysdev/fsl_pci.c |  3 +--
 5 files changed, 4 insertions(+), 31 deletions(-)

diff --git a/arch/powerpc/include/asm/device.h 
b/arch/powerpc/include/asm/device.h
index 3814e1c2d4bc..a130be13ee83 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -38,9 +38,6 @@ struct dev_archdata {
 #ifdef CONFIG_IOMMU_API
void*iommu_domain;
 #endif
-#ifdef CONFIG_SWIOTLB
-   dma_addr_t  max_direct_dma_addr;
-#endif
 #ifdef CONFIG_PPC64
struct pci_dn   *pci_data;
 #endif
diff --git a/arch/powerpc/include/asm/dma-direct.h 
b/arch/powerpc/include/asm/dma-direct.h
index 7702875aabb7..e00ab5d0612d 100644
--- a/arch/powerpc/include/asm/dma-direct.h
+++ b/arch/powerpc/include/asm/dma-direct.h
@@ -5,9 +5,7 @@
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t 
size)
 {
 #ifdef CONFIG_SWIOTLB
-   struct dev_archdata *sd = >archdata;
-
-   if (sd->max_direct_dma_addr && addr + size > sd->max_direct_dma_addr)
+   if (dev->bus_dma_mask && addr + size > dev->bus_dma_mask)
return false;
 #endif
 
diff --git a/arch/powerpc/kernel/dma-swiotlb.c 
b/arch/powerpc/kernel/dma-swiotlb.c
index 60cb86338233..e05d95ff50ad 100644
--- a/arch/powerpc/kernel/dma-swiotlb.c
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -24,21 +24,6 @@
 
 unsigned int ppc_swiotlb_enable;
 
-static u64 swiotlb_powerpc_get_required(struct device *dev)
-{
-   u64 end, mask, max_direct_dma_addr = dev->archdata.max_direct_dma_addr;
-
-   end = memblock_end_of_DRAM();
-   if (max_direct_dma_addr && end > max_direct_dma_addr)
-   end = max_direct_dma_addr;
-   end += get_dma_offset(dev);
-
-   mask = 1ULL << (fls64(end) - 1);
-   mask += mask - 1;
-
-   return mask;
-}
-
 /*
  * At the moment, all platforms that use this code only require
  * swiotlb to be used if we're operating on HIGHMEM.  Since
@@ -60,22 +45,17 @@ const struct dma_map_ops powerpc_swiotlb_dma_ops = {
.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
.sync_sg_for_device = swiotlb_sync_sg_for_device,
.mapping_error = swiotlb_dma_mapping_error,
-   .get_required_mask = swiotlb_powerpc_get_required,
 };
 
 static int ppc_swiotlb_bus_notify(struct notifier_block *nb,
  unsigned long action, void *data)
 {
struct device *dev = data;
-   struct dev_archdata *sd;
 
/* We are only intereted in device addition */
if (action != BUS_NOTIFY_ADD_DEVICE)
return 0;
 
-   sd = >archdata;
-   sd->max_direct_dma_addr = 0;
-
/* May need to bounce if the device can't address all of DRAM */
if ((dma_get_mask(dev) + 1) < memblock_end_of_DRAM())
set_dma_ops(dev, _swiotlb_dma_ops);
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index bef91b8ad064..e3d2c15b209c 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -30,11 +30,10 @@
 static u64 __maybe_unused get_pfn_limit(struct device *dev)
 {
u64 pfn = (dev->coherent_dma_mask >> PAGE_SHIFT) + 1;
-   struct dev_archdata __maybe_unused *sd = >archdata;
 
 #ifdef CONFIG_SWIOTLB
-   if (sd->max_direct_dma_addr && dev->dma_ops == _swiotlb_dma_ops)
-   pfn = min_t(u64, pfn, sd->max_direct_dma_addr >> PAGE_SHIFT);
+   if (dev->bus_dma_mask && dev->dma_ops == _swiotlb_dma_ops)
+   pfn = min_t(u64, pfn, dev->bus_dma_mask >> PAGE_SHIFT);
 #endif
 
return pfn;
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 561f97d698cc..f136567a5ed5 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -117,9 +117,8 @@ static u64 pci64_dma_offset;
 static void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev)
 {
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
-   struct dev_archdata *sd = >dev.archdata;
 
-   sd->max_direct_dma_addr =
+   pdev->dev.bus_dma_mask =
hose->dma_window_base_cur + hose->dma_window_size;
 }
 
-- 
2.19.0



[PATCH 22/33] powerpc/dma: move pci_dma_dev_setup_swiotlb to fsl_pci.c

2018-10-09 Thread Christoph Hellwig
pci_dma_dev_setup_swiotlb is only used by the fsl_pci code, and closely
related to it, so fsl_pci.c seems like a better place for it.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/include/asm/swiotlb.h |  2 --
 arch/powerpc/kernel/dma-swiotlb.c  | 11 ---
 arch/powerpc/sysdev/fsl_pci.c  |  9 +
 3 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/include/asm/swiotlb.h 
b/arch/powerpc/include/asm/swiotlb.h
index f65ecf57b66c..26a0f12b835b 100644
--- a/arch/powerpc/include/asm/swiotlb.h
+++ b/arch/powerpc/include/asm/swiotlb.h
@@ -18,8 +18,6 @@ extern const struct dma_map_ops powerpc_swiotlb_dma_ops;
 extern unsigned int ppc_swiotlb_enable;
 int __init swiotlb_setup_bus_notifier(void);
 
-extern void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev);
-
 #ifdef CONFIG_SWIOTLB
 void swiotlb_detect_4g(void);
 #else
diff --git a/arch/powerpc/kernel/dma-swiotlb.c 
b/arch/powerpc/kernel/dma-swiotlb.c
index 93a4622563c6..60cb86338233 100644
--- a/arch/powerpc/kernel/dma-swiotlb.c
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -63,17 +63,6 @@ const struct dma_map_ops powerpc_swiotlb_dma_ops = {
.get_required_mask = swiotlb_powerpc_get_required,
 };
 
-void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev)
-{
-   struct pci_controller *hose;
-   struct dev_archdata *sd;
-
-   hose = pci_bus_to_host(pdev->bus);
-   sd = >dev.archdata;
-   sd->max_direct_dma_addr =
-   hose->dma_window_base_cur + hose->dma_window_size;
-}
-
 static int ppc_swiotlb_bus_notify(struct notifier_block *nb,
  unsigned long action, void *data)
 {
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 918be816b097..561f97d698cc 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -114,6 +114,15 @@ static struct pci_ops fsl_indirect_pcie_ops =
 static u64 pci64_dma_offset;
 
 #ifdef CONFIG_SWIOTLB
+static void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev)
+{
+   struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+   struct dev_archdata *sd = >dev.archdata;
+
+   sd->max_direct_dma_addr =
+   hose->dma_window_base_cur + hose->dma_window_size;
+}
+
 static void setup_swiotlb_ops(struct pci_controller *hose)
 {
if (ppc_swiotlb_enable) {
-- 
2.19.0



[PATCH 15/33] powerpc/powernv: remove pnv_pci_ioda_pe_single_vendor

2018-10-09 Thread Christoph Hellwig
This function is completely bogus - the fact that two PCIe devices come
from the same vendor has absolutely nothing to say about the DMA
capabilities and characteristics.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 28 ++-
 1 file changed, 2 insertions(+), 26 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index cde710297a4e..913175ba1c10 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1746,31 +1746,6 @@ static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb 
*phb, struct pci_dev *pdev
 */
 }
 
-static bool pnv_pci_ioda_pe_single_vendor(struct pnv_ioda_pe *pe)
-{
-   unsigned short vendor = 0;
-   struct pci_dev *pdev;
-
-   if (pe->device_count == 1)
-   return true;
-
-   /* pe->pdev should be set if it's a single device, pe->pbus if not */
-   if (!pe->pbus)
-   return true;
-
-   list_for_each_entry(pdev, >pbus->devices, bus_list) {
-   if (!vendor) {
-   vendor = pdev->vendor;
-   continue;
-   }
-
-   if (pdev->vendor != vendor)
-   return false;
-   }
-
-   return true;
-}
-
 /*
  * Reconfigure TVE#0 to be usable as 64-bit DMA space.
  *
@@ -1871,7 +1846,8 @@ static int pnv_pci_ioda_dma_set_mask(struct pci_dev 
*pdev, u64 dma_mask)
 */
if (dma_mask >> 32 &&
dma_mask > (memory_hotplug_max() + (1ULL << 32)) &&
-   pnv_pci_ioda_pe_single_vendor(pe) &&
+   /* pe->pdev should be set if it's a single device, pe->pbus 
if not */
+   (pe->device_count == 1 || !pe->pbus) &&
phb->model == PNV_PHB_MODEL_PHB3) {
/* Configure the bypass mode */
rc = pnv_pci_ioda_dma_64bit_bypass(pe);
-- 
2.19.0



[PATCH 19/33] powerpc/pci: remove the dma_set_mask pci_controller ops methods

2018-10-09 Thread Christoph Hellwig
Unused now.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/include/asm/pci-bridge.h | 2 --
 arch/powerpc/kernel/dma.c | 7 ---
 2 files changed, 9 deletions(-)

diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index aace7033fa02..a50703af7db3 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -45,8 +45,6 @@ struct pci_controller_ops {
void(*teardown_msi_irqs)(struct pci_dev *pdev);
 #endif
 
-   int (*dma_set_mask)(struct pci_dev *pdev, u64 dma_mask);
-
void(*shutdown)(struct pci_controller *hose);
 };
 
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 9ca9d2cec4ed..78ef4076e15c 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -267,13 +267,6 @@ int dma_set_mask(struct device *dev, u64 dma_mask)
if (ppc_md.dma_set_mask)
return ppc_md.dma_set_mask(dev, dma_mask);
 
-   if (dev_is_pci(dev)) {
-   struct pci_dev *pdev = to_pci_dev(dev);
-   struct pci_controller *phb = pci_bus_to_host(pdev->bus);
-   if (phb->controller_ops.dma_set_mask)
-   return phb->controller_ops.dma_set_mask(pdev, dma_mask);
-   }
-
if (!dev->dma_mask || !dma_supported(dev, dma_mask))
return -EIO;
*dev->dma_mask = dma_mask;
-- 
2.19.0



[PATCH 20/33] powerpc/dma: remove the iommu fallback for coherent allocations

2018-10-09 Thread Christoph Hellwig
All iommu capable platforms now always use the iommu code with the
internal bypass, so there is not need for this magic anymore.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/Kconfig  |  4 ---
 arch/powerpc/kernel/dma.c | 68 ++-
 2 files changed, 2 insertions(+), 70 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 06996df07cad..7097019d8907 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -119,9 +119,6 @@ config GENERIC_HWEIGHT
bool
default y
 
-config ARCH_HAS_DMA_SET_COHERENT_MASK
-bool
-
 config PPC
bool
default y
@@ -129,7 +126,6 @@ config PPC
# Please keep this list sorted alphabetically.
#
select ARCH_HAS_DEVMEM_IS_ALLOWED
-   select ARCH_HAS_DMA_SET_COHERENT_MASK
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_GCOV_PROFILE_ALL
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 78ef4076e15c..bef91b8ad064 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -114,51 +114,6 @@ void __dma_nommu_free_coherent(struct device *dev, size_t 
size,
 }
 #endif /* !CONFIG_NOT_COHERENT_CACHE */
 
-static void *dma_nommu_alloc_coherent(struct device *dev, size_t size,
-  dma_addr_t *dma_handle, gfp_t flag,
-  unsigned long attrs)
-{
-   struct iommu_table *iommu;
-
-   /* The coherent mask may be smaller than the real mask, check if
-* we can really use the direct ops
-*/
-   if (dma_nommu_dma_supported(dev, dev->coherent_dma_mask))
-   return __dma_nommu_alloc_coherent(dev, size, dma_handle,
-  flag, attrs);
-
-   /* Ok we can't ... do we have an iommu ? If not, fail */
-   iommu = get_iommu_table_base(dev);
-   if (!iommu)
-   return NULL;
-
-   /* Try to use the iommu */
-   return iommu_alloc_coherent(dev, iommu, size, dma_handle,
-   dev->coherent_dma_mask, flag,
-   dev_to_node(dev));
-}
-
-static void dma_nommu_free_coherent(struct device *dev, size_t size,
-void *vaddr, dma_addr_t dma_handle,
-unsigned long attrs)
-{
-   struct iommu_table *iommu;
-
-   /* See comments in dma_nommu_alloc_coherent() */
-   if (dma_nommu_dma_supported(dev, dev->coherent_dma_mask))
-   return __dma_nommu_free_coherent(dev, size, vaddr, dma_handle,
- attrs);
-   /* Maybe we used an iommu ... */
-   iommu = get_iommu_table_base(dev);
-
-   /* If we hit that we should have never allocated in the first
-* place so how come we are freeing ?
-*/
-   if (WARN_ON(!iommu))
-   return;
-   iommu_free_coherent(iommu, size, vaddr, dma_handle);
-}
-
 int dma_nommu_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
 void *cpu_addr, dma_addr_t handle, size_t size,
 unsigned long attrs)
@@ -228,8 +183,8 @@ static inline void dma_nommu_sync_single(struct device *dev,
 #endif
 
 const struct dma_map_ops dma_nommu_ops = {
-   .alloc  = dma_nommu_alloc_coherent,
-   .free   = dma_nommu_free_coherent,
+   .alloc  = __dma_nommu_alloc_coherent,
+   .free   = __dma_nommu_free_coherent,
.mmap   = dma_nommu_mmap_coherent,
.map_sg = dma_nommu_map_sg,
.dma_supported  = dma_nommu_dma_supported,
@@ -243,25 +198,6 @@ const struct dma_map_ops dma_nommu_ops = {
 };
 EXPORT_SYMBOL(dma_nommu_ops);
 
-int dma_set_coherent_mask(struct device *dev, u64 mask)
-{
-   if (!dma_supported(dev, mask)) {
-   /*
-* We need to special case the direct DMA ops which can
-* support a fallback for coherent allocations. There
-* is no dma_op->set_coherent_mask() so we have to do
-* things the hard way:
-*/
-   if (get_dma_ops(dev) != _nommu_ops ||
-   get_iommu_table_base(dev) == NULL ||
-   !dma_iommu_dma_supported(dev, mask))
-   return -EIO;
-   }
-   dev->coherent_dma_mask = mask;
-   return 0;
-}
-EXPORT_SYMBOL(dma_set_coherent_mask);
-
 int dma_set_mask(struct device *dev, u64 dma_mask)
 {
if (ppc_md.dma_set_mask)
-- 
2.19.0



[PATCH 13/33] powerpc/dart: remove dead cleanup code in iommu_init_early_dart

2018-10-09 Thread Christoph Hellwig
If dart_init failed we didn't have a chance to setup dma or controller
ops yet, so there is no point in resetting them.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/sysdev/dart_iommu.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 5ca3e22d0512..ce5dd2048f57 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -428,7 +428,7 @@ void __init iommu_init_early_dart(struct pci_controller_ops 
*controller_ops)
 
/* Initialize the DART HW */
if (dart_init(dn) != 0)
-   goto bail;
+   return;
 
/* Setup bypass if supported */
if (dart_is_u4)
@@ -439,15 +439,6 @@ void __init iommu_init_early_dart(struct 
pci_controller_ops *controller_ops)
 
/* Setup pci_dma ops */
set_pci_dma_ops(_iommu_ops);
-   return;
-
- bail:
-   /* If init failed, use direct iommu and null setup functions */
-   controller_ops->dma_dev_setup = NULL;
-   controller_ops->dma_bus_setup = NULL;
-
-   /* Setup pci_dma ops */
-   set_pci_dma_ops(_nommu_ops);
 }
 
 #ifdef CONFIG_PM
-- 
2.19.0



[PATCH 16/33] powerpc/powernv: remove dead npu-dma code

2018-10-09 Thread Christoph Hellwig
This code has been unused since it was merged and is in the way of
cleaning up the DMA code, thus remove it.

This effectively reverts commit 5d2aa710 ("powerpc/powernv: Add support
for Nvlink NPUs").

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/include/asm/pci.h|   3 -
 arch/powerpc/include/asm/powernv.h|  23 -
 arch/powerpc/platforms/powernv/Makefile   |   2 +-
 arch/powerpc/platforms/powernv/npu-dma.c  | 999 --
 arch/powerpc/platforms/powernv/pci-ioda.c | 243 --
 arch/powerpc/platforms/powernv/pci.h  |  11 -
 6 files changed, 1 insertion(+), 1280 deletions(-)
 delete mode 100644 arch/powerpc/platforms/powernv/npu-dma.c

diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 2af9ded80540..a01d2e3d6ff9 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -127,7 +127,4 @@ extern void pcibios_scan_phb(struct pci_controller *hose);
 
 #endif /* __KERNEL__ */
 
-extern struct pci_dev *pnv_pci_get_gpu_dev(struct pci_dev *npdev);
-extern struct pci_dev *pnv_pci_get_npu_dev(struct pci_dev *gpdev, int index);
-
 #endif /* __ASM_POWERPC_PCI_H */
diff --git a/arch/powerpc/include/asm/powernv.h 
b/arch/powerpc/include/asm/powernv.h
index 2f3ff7a27881..4848a6b3c6b2 100644
--- a/arch/powerpc/include/asm/powernv.h
+++ b/arch/powerpc/include/asm/powernv.h
@@ -11,33 +11,10 @@
 #define _ASM_POWERNV_H
 
 #ifdef CONFIG_PPC_POWERNV
-#define NPU2_WRITE 1
 extern void powernv_set_nmmu_ptcr(unsigned long ptcr);
-extern struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
-   unsigned long flags,
-   void (*cb)(struct npu_context *, void *),
-   void *priv);
-extern void pnv_npu2_destroy_context(struct npu_context *context,
-   struct pci_dev *gpdev);
-extern int pnv_npu2_handle_fault(struct npu_context *context, uintptr_t *ea,
-   unsigned long *flags, unsigned long *status,
-   int count);
-
 void pnv_tm_init(void);
 #else
 static inline void powernv_set_nmmu_ptcr(unsigned long ptcr) { }
-static inline struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
-   unsigned long flags,
-   struct npu_context *(*cb)(struct npu_context *, void *),
-   void *priv) { return ERR_PTR(-ENODEV); }
-static inline void pnv_npu2_destroy_context(struct npu_context *context,
-   struct pci_dev *gpdev) { }
-
-static inline int pnv_npu2_handle_fault(struct npu_context *context,
-   uintptr_t *ea, unsigned long *flags,
-   unsigned long *status, int count) {
-   return -ENODEV;
-}
 
 static inline void pnv_tm_init(void) { }
 static inline void pnv_power9_force_smt4(void) { }
diff --git a/arch/powerpc/platforms/powernv/Makefile 
b/arch/powerpc/platforms/powernv/Makefile
index b540ce8eec55..2b13e9dd137c 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -6,7 +6,7 @@ obj-y   += opal-msglog.o opal-hmi.o 
opal-power.o opal-irqchip.o
 obj-y  += opal-kmsg.o opal-powercap.o opal-psr.o 
opal-sensor-groups.o
 
 obj-$(CONFIG_SMP)  += smp.o subcore.o subcore-asm.o
-obj-$(CONFIG_PCI)  += pci.o pci-ioda.o npu-dma.o pci-ioda-tce.o
+obj-$(CONFIG_PCI)  += pci.o pci-ioda.o pci-ioda-tce.o
 obj-$(CONFIG_CXL_BASE) += pci-cxl.o
 obj-$(CONFIG_EEH)  += eeh-powernv.o
 obj-$(CONFIG_PPC_SCOM) += opal-xscom.o
diff --git a/arch/powerpc/platforms/powernv/npu-dma.c 
b/arch/powerpc/platforms/powernv/npu-dma.c
deleted file mode 100644
index 8006c54a91e3..
--- a/arch/powerpc/platforms/powernv/npu-dma.c
+++ /dev/null
@@ -1,999 +0,0 @@
-/*
- * This file implements the DMA operations for NVLink devices. The NPU
- * devices all point to the same iommu table as the parent PCI device.
- *
- * Copyright Alistair Popple, IBM Corporation 2015.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "powernv.h"
-#include "pci.h"
-
-#define npu_to_phb(x) container_of(x, struct pnv_phb, npu)
-
-/*
- * spinlock to protect initialisation of an npu_context for a particular
- * mm_struct.
- */
-static DEFINE_SPINLOCK(npu_context_lock);
-
-/*
- * When an address shootdown range exceeds this threshold we invalidate the
- * entire TLB on the GPU for the given PID rather than each specific address in
- * the range.
- */
-static uint64_t atsd_threshold = 2 * 1024 * 1024;
-static 

[PATCH 18/33] powerpc/dma: stop overriding dma_get_required_mask

2018-10-09 Thread Christoph Hellwig
The ppc_md and pci_controller_ops methods are unused now and can be
removed.  The dma_nommu implementation is generic to the generic one
except for using max_pfn instead of calling into the memblock API,
and all other dma_map_ops instances implement a method of their own.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/include/asm/device.h  |  2 --
 arch/powerpc/include/asm/dma-mapping.h |  2 --
 arch/powerpc/include/asm/machdep.h |  2 --
 arch/powerpc/include/asm/pci-bridge.h  |  1 -
 arch/powerpc/kernel/dma.c  | 42 --
 drivers/base/platform.c|  2 --
 6 files changed, 51 deletions(-)

diff --git a/arch/powerpc/include/asm/device.h 
b/arch/powerpc/include/asm/device.h
index 1aa53318b4bc..3814e1c2d4bc 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -59,6 +59,4 @@ struct pdev_archdata {
u64 dma_mask;
 };
 
-#define ARCH_HAS_DMA_GET_REQUIRED_MASK
-
 #endif /* _ASM_POWERPC_DEVICE_H */
diff --git a/arch/powerpc/include/asm/dma-mapping.h 
b/arch/powerpc/include/asm/dma-mapping.h
index 59c090b7eaac..b1999880fc61 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -112,7 +112,5 @@ static inline void set_dma_offset(struct device *dev, 
dma_addr_t off)
 #define HAVE_ARCH_DMA_SET_MASK 1
 extern int dma_set_mask(struct device *dev, u64 dma_mask);
 
-extern u64 __dma_get_required_mask(struct device *dev);
-
 #endif /* __KERNEL__ */
 #endif /* _ASM_DMA_MAPPING_H */
diff --git a/arch/powerpc/include/asm/machdep.h 
b/arch/powerpc/include/asm/machdep.h
index a47de82fb8e2..99f06102474e 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -47,9 +47,7 @@ struct machdep_calls {
 #endif
 #endif /* CONFIG_PPC64 */
 
-   /* Platform set_dma_mask and dma_get_required_mask overrides */
int (*dma_set_mask)(struct device *dev, u64 dma_mask);
-   u64 (*dma_get_required_mask)(struct device *dev);
 
int (*probe)(void);
void(*setup_arch)(void); /* Optional, may be NULL */
diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index 5c7a1e7ffc8a..aace7033fa02 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -46,7 +46,6 @@ struct pci_controller_ops {
 #endif
 
int (*dma_set_mask)(struct pci_dev *pdev, u64 dma_mask);
-   u64 (*dma_get_required_mask)(struct pci_dev *pdev);
 
void(*shutdown)(struct pci_controller *hose);
 };
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 716b7eab3ee7..9ca9d2cec4ed 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -197,18 +197,6 @@ int dma_nommu_map_sg(struct device *dev, struct 
scatterlist *sgl,
return nents;
 }
 
-static u64 dma_nommu_get_required_mask(struct device *dev)
-{
-   u64 end, mask;
-
-   end = memblock_end_of_DRAM() + get_dma_offset(dev);
-
-   mask = 1ULL << (fls64(end) - 1);
-   mask += mask - 1;
-
-   return mask;
-}
-
 dma_addr_t dma_nommu_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
enum dma_data_direction dir, unsigned long attrs)
@@ -246,7 +234,6 @@ const struct dma_map_ops dma_nommu_ops = {
.map_sg = dma_nommu_map_sg,
.dma_supported  = dma_nommu_dma_supported,
.map_page   = dma_nommu_map_page,
-   .get_required_mask  = dma_nommu_get_required_mask,
 #ifdef CONFIG_NOT_COHERENT_CACHE
.sync_single_for_cpu= dma_nommu_sync_single,
.sync_single_for_device = dma_nommu_sync_single,
@@ -294,35 +281,6 @@ int dma_set_mask(struct device *dev, u64 dma_mask)
 }
 EXPORT_SYMBOL(dma_set_mask);
 
-u64 __dma_get_required_mask(struct device *dev)
-{
-   const struct dma_map_ops *dma_ops = get_dma_ops(dev);
-
-   if (unlikely(dma_ops == NULL))
-   return 0;
-
-   if (dma_ops->get_required_mask)
-   return dma_ops->get_required_mask(dev);
-
-   return DMA_BIT_MASK(8 * sizeof(dma_addr_t));
-}
-
-u64 dma_get_required_mask(struct device *dev)
-{
-   if (ppc_md.dma_get_required_mask)
-   return ppc_md.dma_get_required_mask(dev);
-
-   if (dev_is_pci(dev)) {
-   struct pci_dev *pdev = to_pci_dev(dev);
-   struct pci_controller *phb = pci_bus_to_host(pdev->bus);
-   if (phb->controller_ops.dma_get_required_mask)
-   return phb->controller_ops.dma_get_required_mask(pdev);
-   }
-
-   return __dma_get_required_mask(dev);
-}
-EXPORT_SYMBOL_GPL(dma_get_required_mask);
-
 static int __init dma_init(void)
 {
 #ifdef CONFIG_IBMVIO
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 

[PATCH 14/33] powerpc/dart: use the generic iommu bypass code

2018-10-09 Thread Christoph Hellwig
Use the generic iommu bypass code instead of overriding set_dma_mask.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/sysdev/dart_iommu.c | 45 +++-
 1 file changed, 15 insertions(+), 30 deletions(-)

diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index ce5dd2048f57..e7d1645a2d2e 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -360,13 +360,6 @@ static void iommu_table_dart_setup(void)
set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map);
 }
 
-static void pci_dma_dev_setup_dart(struct pci_dev *dev)
-{
-   if (dart_is_u4)
-   set_dma_offset(>dev, DART_U4_BYPASS_BASE);
-   set_iommu_table_base(>dev, _table_dart);
-}
-
 static void pci_dma_bus_setup_dart(struct pci_bus *bus)
 {
if (!iommu_table_dart_inited) {
@@ -390,27 +383,16 @@ static bool dart_device_on_pcie(struct device *dev)
return false;
 }
 
-static int dart_dma_set_mask(struct device *dev, u64 dma_mask)
+static void pci_dma_dev_setup_dart(struct pci_dev *dev)
 {
-   if (!dev->dma_mask || !dma_supported(dev, dma_mask))
-   return -EIO;
-
-   /* U4 supports a DART bypass, we use it for 64-bit capable
-* devices to improve performances. However, that only works
-* for devices connected to U4 own PCIe interface, not bridged
-* through hypertransport. We need the device to support at
-* least 40 bits of addresses.
-*/
-   if (dart_device_on_pcie(dev) && dma_mask >= DMA_BIT_MASK(40)) {
-   dev_info(dev, "Using 64-bit DMA iommu bypass\n");
-   set_dma_ops(dev, _nommu_ops);
-   } else {
-   dev_info(dev, "Using 32-bit DMA via iommu\n");
-   set_dma_ops(dev, _iommu_ops);
-   }
+   if (dart_is_u4 && dart_device_on_pcie(>dev))
+   set_dma_offset(>dev, DART_U4_BYPASS_BASE);
+   set_iommu_table_base(>dev, _table_dart);
+}
 
-   *dev->dma_mask = dma_mask;
-   return 0;
+static bool iommu_bypass_supported_dart(struct pci_dev *dev, u64 mask)
+{
+   return dart_is_u4 && dart_device_on_pcie(>dev);
 }
 
 void __init iommu_init_early_dart(struct pci_controller_ops *controller_ops)
@@ -430,12 +412,15 @@ void __init iommu_init_early_dart(struct 
pci_controller_ops *controller_ops)
if (dart_init(dn) != 0)
return;
 
-   /* Setup bypass if supported */
-   if (dart_is_u4)
-   ppc_md.dma_set_mask = dart_dma_set_mask;
-
+   /*
+* U4 supports a DART bypass, we use it for 64-bit capable devices to
+* improve performance.  However, that only works for devices connected
+* to the U4 own PCIe interface, not bridged through hypertransport.
+* We need the device to support at least 40 bits of addresses.
+*/
controller_ops->dma_dev_setup = pci_dma_dev_setup_dart;
controller_ops->dma_bus_setup = pci_dma_bus_setup_dart;
+   controller_ops->iommu_bypass_supported = iommu_bypass_supported_dart;
 
/* Setup pci_dma ops */
set_pci_dma_ops(_iommu_ops);
-- 
2.19.0



[PATCH 17/33] powerpc/powernv: use the generic iommu bypass code

2018-10-09 Thread Christoph Hellwig
Use the generic iommu bypass code instead of overriding set_dma_mask.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 92 ++-
 1 file changed, 25 insertions(+), 67 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index b6db65917bb4..5748b62e2e86 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1739,86 +1739,45 @@ static int pnv_pci_ioda_dma_64bit_bypass(struct 
pnv_ioda_pe *pe)
return -EIO;
 }
 
-static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
+static bool pnv_pci_ioda_iommu_bypass_supported(struct pci_dev *pdev,
+   u64 dma_mask)
 {
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
struct pnv_phb *phb = hose->private_data;
struct pci_dn *pdn = pci_get_pdn(pdev);
struct pnv_ioda_pe *pe;
-   uint64_t top;
-   bool bypass = false;
-   s64 rc;
 
if (WARN_ON(!pdn || pdn->pe_number == IODA_INVALID_PE))
return -ENODEV;
 
pe = >ioda.pe_array[pdn->pe_number];
if (pe->tce_bypass_enabled) {
-   top = pe->tce_bypass_base + memblock_end_of_DRAM() - 1;
-   bypass = (dma_mask >= top);
+   u64 top = pe->tce_bypass_base + memblock_end_of_DRAM() - 1;
+   if (dma_mask >= top)
+   return true;
}
 
-   if (bypass) {
-   dev_info(>dev, "Using 64-bit DMA iommu bypass\n");
-   set_dma_ops(>dev, _nommu_ops);
-   } else {
-   /*
-* If the device can't set the TCE bypass bit but still wants
-* to access 4GB or more, on PHB3 we can reconfigure TVE#0 to
-* bypass the 32-bit region and be usable for 64-bit DMAs.
-* The device needs to be able to address all of this space.
-*/
-   if (dma_mask >> 32 &&
-   dma_mask > (memory_hotplug_max() + (1ULL << 32)) &&
-   /* pe->pdev should be set if it's a single device, pe->pbus 
if not */
-   (pe->device_count == 1 || !pe->pbus) &&
-   phb->model == PNV_PHB_MODEL_PHB3) {
-   /* Configure the bypass mode */
-   rc = pnv_pci_ioda_dma_64bit_bypass(pe);
-   if (rc)
-   return rc;
-   /* 4GB offset bypasses 32-bit space */
-   set_dma_offset(>dev, (1ULL << 32));
-   set_dma_ops(>dev, _nommu_ops);
-   } else if (dma_mask >> 32 && dma_mask != DMA_BIT_MASK(64)) {
-   /*
-* Fail the request if a DMA mask between 32 and 64 bits
-* was requested but couldn't be fulfilled. Ideally we
-* would do this for 64-bits but historically we have
-* always fallen back to 32-bits.
-*/
-   return -ENOMEM;
-   } else {
-   dev_info(>dev, "Using 32-bit DMA via iommu\n");
-   set_dma_ops(>dev, _iommu_ops);
-   }
+   /*
+* If the device can't set the TCE bypass bit but still wants
+* to access 4GB or more, on PHB3 we can reconfigure TVE#0 to
+* bypass the 32-bit region and be usable for 64-bit DMAs.
+* The device needs to be able to address all of this space.
+*/
+   if (dma_mask >> 32 &&
+   dma_mask > (memory_hotplug_max() + (1ULL << 32)) &&
+   /* pe->pdev should be set if it's a single device, pe->pbus if not 
*/
+   (pe->device_count == 1 || !pe->pbus) &&
+   phb->model == PNV_PHB_MODEL_PHB3) {
+   /* Configure the bypass mode */
+   s64 rc = pnv_pci_ioda_dma_64bit_bypass(pe);
+   if (rc)
+   return rc;
+   /* 4GB offset bypasses 32-bit space */
+   set_dma_offset(>dev, (1ULL << 32));
+   return true;
}
-   *pdev->dev.dma_mask = dma_mask;
 
-   return 0;
-}
-
-static u64 pnv_pci_ioda_dma_get_required_mask(struct pci_dev *pdev)
-{
-   struct pci_controller *hose = pci_bus_to_host(pdev->bus);
-   struct pnv_phb *phb = hose->private_data;
-   struct pci_dn *pdn = pci_get_pdn(pdev);
-   struct pnv_ioda_pe *pe;
-   u64 end, mask;
-
-   if (WARN_ON(!pdn || pdn->pe_number == IODA_INVALID_PE))
-   return 0;
-
-   pe = >ioda.pe_array[pdn->pe_number];
-   if (!pe->tce_bypass_enabled)
-   return __dma_get_required_mask(>dev);
-
-
-   end = pe->tce_bypass_base + memblock_end_of_DRAM();
-   mask = 1ULL << (fls64(end) - 1);
-   mask += mask - 1;
-
-   return mask;
+   return false;
 }
 
 static void 

[PATCH 10/33] powerpc/pseries: use the generic iommu bypass code

2018-10-09 Thread Christoph Hellwig
Use the generic iommu bypass code instead of overriding set_dma_mask.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/platforms/pseries/iommu.c | 100 +++--
 1 file changed, 27 insertions(+), 73 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/iommu.c 
b/arch/powerpc/platforms/pseries/iommu.c
index da5716de7f4c..8965d174c53b 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -973,7 +973,7 @@ static LIST_HEAD(failed_ddw_pdn_list);
  * pdn: the parent pe node with the ibm,dma_window property
  * Future: also check if we can remap the base window for our base page size
  *
- * returns the dma offset for use by dma_set_mask
+ * returns the dma offset for use by the direct mapped DMA code.
  */
 static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
 {
@@ -1193,87 +1193,40 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev 
*dev)
iommu_add_device(>dev);
 }
 
-static int dma_set_mask_pSeriesLP(struct device *dev, u64 dma_mask)
+static bool iommu_bypass_supported_pSeriesLP(struct pci_dev *pdev, u64 
dma_mask)
 {
-   bool ddw_enabled = false;
-   struct device_node *pdn, *dn;
-   struct pci_dev *pdev;
+   struct device_node *dn = pci_device_to_OF_node(pdev), *pdn;
const __be32 *dma_window = NULL;
u64 dma_offset;
 
-   if (!dev->dma_mask)
-   return -EIO;
-
-   if (!dev_is_pci(dev))
-   goto check_mask;
-
-   pdev = to_pci_dev(dev);
-
/* only attempt to use a new window if 64-bit DMA is requested */
-   if (!disable_ddw && dma_mask == DMA_BIT_MASK(64)) {
-   dn = pci_device_to_OF_node(pdev);
-   dev_dbg(dev, "node is %pOF\n", dn);
+   if (dma_mask < DMA_BIT_MASK(64))
+   return false;
 
-   /*
-* the device tree might contain the dma-window properties
-* per-device and not necessarily for the bus. So we need to
-* search upwards in the tree until we either hit a dma-window
-* property, OR find a parent with a table already allocated.
-*/
-   for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->table_group;
-   pdn = pdn->parent) {
-   dma_window = of_get_property(pdn, "ibm,dma-window", 
NULL);
-   if (dma_window)
-   break;
-   }
-   if (pdn && PCI_DN(pdn)) {
-   dma_offset = enable_ddw(pdev, pdn);
-   if (dma_offset != 0) {
-   dev_info(dev, "Using 64-bit direct DMA at 
offset %llx\n", dma_offset);
-   set_dma_offset(dev, dma_offset);
-   set_dma_ops(dev, _nommu_ops);
-   ddw_enabled = true;
-   }
-   }
-   }
+   dev_dbg(>dev, "node is %pOF\n", dn);
 
-   /* fall back on iommu ops */
-   if (!ddw_enabled && get_dma_ops(dev) != _iommu_ops) {
-   dev_info(dev, "Restoring 32-bit DMA via iommu\n");
-   set_dma_ops(dev, _iommu_ops);
+   /*
+* the device tree might contain the dma-window properties
+* per-device and not necessarily for the bus. So we need to
+* search upwards in the tree until we either hit a dma-window
+* property, OR find a parent with a table already allocated.
+*/
+   for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->table_group;
+   pdn = pdn->parent) {
+   dma_window = of_get_property(pdn, "ibm,dma-window", NULL);
+   if (dma_window)
+   break;
}
 
-check_mask:
-   if (!dma_supported(dev, dma_mask))
-   return -EIO;
-
-   *dev->dma_mask = dma_mask;
-   return 0;
-}
-
-static u64 dma_get_required_mask_pSeriesLP(struct device *dev)
-{
-   if (!dev->dma_mask)
-   return 0;
-
-   if (!disable_ddw && dev_is_pci(dev)) {
-   struct pci_dev *pdev = to_pci_dev(dev);
-   struct device_node *dn;
-
-   dn = pci_device_to_OF_node(pdev);
-
-   /* search upwards for ibm,dma-window */
-   for (; dn && PCI_DN(dn) && !PCI_DN(dn)->table_group;
-   dn = dn->parent)
-   if (of_get_property(dn, "ibm,dma-window", NULL))
-   break;
-   /* if there is a ibm,ddw-applicable property require 64 bits */
-   if (dn && PCI_DN(dn) &&
-   of_get_property(dn, "ibm,ddw-applicable", NULL))
-   return DMA_BIT_MASK(64);
+   if (pdn && PCI_DN(pdn)) {
+   dma_offset = enable_ddw(pdev, pdn);
+   if (dma_offset != 0) {
+   set_dma_offset(>dev, dma_offset);
+ 

[PATCH 04/33] powerpc/dma: remove the unused dma_iommu_ops export

2018-10-09 Thread Christoph Hellwig
Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/kernel/dma-iommu.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index f9fe2080ceb9..2ca6cfaebf65 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -6,7 +6,6 @@
  * busses using the iommu infrastructure
  */
 
-#include 
 #include 
 
 /*
@@ -123,4 +122,3 @@ struct dma_map_ops dma_iommu_ops = {
.get_required_mask  = dma_iommu_get_required_mask,
.mapping_error  = dma_iommu_mapping_error,
 };
-EXPORT_SYMBOL(dma_iommu_ops);
-- 
2.19.0



[PATCH 11/33] powerpc/cell: move dma direct window setup out of dma_configure

2018-10-09 Thread Christoph Hellwig
Configure the dma settings at device setup time, and stop playing games
with get_pci_dma_ops.  This prepares for using the common dma_configure
code later on.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/platforms/cell/iommu.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/platforms/cell/iommu.c 
b/arch/powerpc/platforms/cell/iommu.c
index 12352a58072a..cce5bf9515e5 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -657,14 +657,21 @@ static const struct dma_map_ops dma_iommu_fixed_ops = {
.mapping_error  = dma_iommu_mapping_error,
 };
 
+static u64 cell_iommu_get_fixed_address(struct device *dev);
+
 static void cell_dma_dev_setup(struct device *dev)
 {
-   if (get_pci_dma_ops() == _iommu_ops)
+   if (get_pci_dma_ops() == _iommu_ops) {
+   u64 addr = cell_iommu_get_fixed_address(dev);
+
+   if (addr != OF_BAD_ADDR)
+   set_dma_offset(dev, addr + dma_iommu_fixed_base);
set_iommu_table_base(dev, cell_get_iommu_table(dev));
-   else if (get_pci_dma_ops() == _nommu_ops)
+   } else if (get_pci_dma_ops() == _nommu_ops) {
set_dma_offset(dev, cell_dma_nommu_offset);
-   else
+   } else {
BUG();
+   }
 }
 
 static void cell_pci_dma_dev_setup(struct pci_dev *dev)
@@ -950,19 +957,14 @@ static int dma_suported_and_switch(struct device *dev, 
u64 dma_mask)
 {
if (dma_mask == DMA_BIT_MASK(64) &&
cell_iommu_get_fixed_address(dev) != OF_BAD_ADDR) {
-   u64 addr = cell_iommu_get_fixed_address(dev) +
-   dma_iommu_fixed_base;
dev_dbg(dev, "iommu: 64-bit OK, using fixed ops\n");
-   dev_dbg(dev, "iommu: fixed addr = %llx\n", addr);
set_dma_ops(dev, _iommu_fixed_ops);
-   set_dma_offset(dev, addr);
return 1;
}
 
if (dma_iommu_dma_supported(dev, dma_mask)) {
dev_dbg(dev, "iommu: not 64-bit, using default ops\n");
-   set_dma_ops(dev, get_pci_dma_ops());
-   cell_dma_dev_setup(dev);
+   set_dma_ops(dev, _iommu_ops);
return 1;
}
 
-- 
2.19.0



[PATCH 09/33] powerpc/pseries: unwind dma_get_required_mask_pSeriesLP a bit

2018-10-09 Thread Christoph Hellwig
Call dma_get_required_mask_pSeriesLP directly instead of dma_iommu_ops
to simply the code a bit.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/platforms/pseries/iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/iommu.c 
b/arch/powerpc/platforms/pseries/iommu.c
index 06f02960b439..da5716de7f4c 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -1273,7 +1273,7 @@ static u64 dma_get_required_mask_pSeriesLP(struct device 
*dev)
return DMA_BIT_MASK(64);
}
 
-   return dma_iommu_ops.get_required_mask(dev);
+   return dma_iommu_get_required_mask(dev);
 }
 
 static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action,
-- 
2.19.0



[PATCH 08/33] powerpc/dma: handle iommu bypass in dma_iommu_ops

2018-10-09 Thread Christoph Hellwig
Add a new iommu_bypass flag to struct dev_archdata so that the dma_iommu
implementation can handle the direct mapping transparently instead of
switiching ops around.  Setting of this flag is controlled by new
pci_controller_ops method.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/include/asm/device.h  |  5 ++
 arch/powerpc/include/asm/dma-mapping.h |  7 +++
 arch/powerpc/include/asm/pci-bridge.h  |  2 +
 arch/powerpc/kernel/dma-iommu.c| 70 +++---
 arch/powerpc/kernel/dma.c  | 17 +++
 5 files changed, 85 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/include/asm/device.h 
b/arch/powerpc/include/asm/device.h
index 0245bfcaac32..1aa53318b4bc 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -19,6 +19,11 @@ struct iommu_table;
  * drivers/macintosh/macio_asic.c
  */
 struct dev_archdata {
+   /*
+* Set to %true if the dma_iommu_ops are requested to use a direct
+* window instead of dynamically mapping memory.
+*/
+   booliommu_bypass : 1;
/*
 * These two used to be a union. However, with the hybrid ops we need
 * both so here we store both a DMA offset for direct mappings and
diff --git a/arch/powerpc/include/asm/dma-mapping.h 
b/arch/powerpc/include/asm/dma-mapping.h
index dacd0f93f2b2..27283eb68c50 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -29,6 +29,13 @@ extern int dma_nommu_mmap_coherent(struct device *dev,
struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t handle,
size_t size, unsigned long attrs);
+int dma_nommu_map_sg(struct device *dev, struct scatterlist *sgl,
+   int nents, enum dma_data_direction direction,
+   unsigned long attrs);
+dma_addr_t dma_nommu_map_page(struct device *dev, struct page *page,
+   unsigned long offset, size_t size,
+   enum dma_data_direction dir, unsigned long attrs);
+int dma_nommu_dma_supported(struct device *dev, u64 mask);
 
 #ifdef CONFIG_NOT_COHERENT_CACHE
 /*
diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index 94d449031b18..5c7a1e7ffc8a 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -19,6 +19,8 @@ struct device_node;
 struct pci_controller_ops {
void(*dma_dev_setup)(struct pci_dev *pdev);
void(*dma_bus_setup)(struct pci_bus *bus);
+   bool(*iommu_bypass_supported)(struct pci_dev *pdev,
+   u64 mask);
 
int (*probe_mode)(struct pci_bus *bus);
 
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index 0613278abf9f..c865e15ad024 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -6,12 +6,30 @@
  * busses using the iommu infrastructure
  */
 
+#include 
+#include 
 #include 
 
 /*
  * Generic iommu implementation
  */
 
+/*
+ * The coherent mask may be smaller than the real mask, check if we can
+ * really use a direct window.
+ */
+static inline bool dma_iommu_alloc_bypass(struct device *dev)
+{
+   return dev->archdata.iommu_bypass &&
+   dma_nommu_dma_supported(dev, dev->coherent_dma_mask);
+}
+
+static inline bool dma_iommu_map_bypass(struct device *dev,
+   unsigned long attrs)
+{
+   return dev->archdata.iommu_bypass;
+}
+
 /* Allocates a contiguous real buffer and creates mappings over it.
  * Returns the virtual address of the buffer and sets dma_handle
  * to the dma address (mapping) of the first page.
@@ -20,6 +38,9 @@ static void *dma_iommu_alloc_coherent(struct device *dev, 
size_t size,
  dma_addr_t *dma_handle, gfp_t flag,
  unsigned long attrs)
 {
+   if (dma_iommu_alloc_bypass(dev))
+   return __dma_nommu_alloc_coherent(dev, size, dma_handle, flag,
+   attrs);
return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size,
dma_handle, dev->coherent_dma_mask, flag,
dev_to_node(dev));
@@ -29,7 +50,11 @@ static void dma_iommu_free_coherent(struct device *dev, 
size_t size,
void *vaddr, dma_addr_t dma_handle,
unsigned long attrs)
 {
-   iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle);
+   if (dma_iommu_alloc_bypass(dev))
+   __dma_nommu_free_coherent(dev, size, vaddr, dma_handle, attrs);
+   else
+   iommu_free_coherent(get_iommu_table_base(dev), size, vaddr,
+   dma_handle);
 }
 
 /* Creates TCEs for a user provided 

[PATCH 12/33] powerpc/cell: use the generic iommu bypass code

2018-10-09 Thread Christoph Hellwig
This gets rid of a lot of clumsy code and finally allows us to mark
dma_iommu_ops const.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/include/asm/dma-mapping.h |   2 +-
 arch/powerpc/include/asm/iommu.h   |   6 ++
 arch/powerpc/kernel/dma-iommu.c|   7 +-
 arch/powerpc/platforms/cell/iommu.c| 143 ++---
 4 files changed, 22 insertions(+), 136 deletions(-)

diff --git a/arch/powerpc/include/asm/dma-mapping.h 
b/arch/powerpc/include/asm/dma-mapping.h
index 27283eb68c50..59c090b7eaac 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -73,7 +73,7 @@ static inline unsigned long device_to_mask(struct device *dev)
  * Available generic sets of operations
  */
 #ifdef CONFIG_PPC64
-extern struct dma_map_ops dma_iommu_ops;
+extern const struct dma_map_ops dma_iommu_ops;
 #endif
 extern const struct dma_map_ops dma_nommu_ops;
 
diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 26b7cc176a99..264d04f1dcd1 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -328,5 +328,11 @@ extern void iommu_release_ownership(struct iommu_table 
*tbl);
 extern enum dma_data_direction iommu_tce_direction(unsigned long tce);
 extern unsigned long iommu_direction_to_tce_perm(enum dma_data_direction dir);
 
+#ifdef CONFIG_PPC_CELL_NATIVE
+extern bool iommu_fixed_is_weak;
+#else
+#define iommu_fixed_is_weak false
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_IOMMU_H */
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index c865e15ad024..7fa3636636fa 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -20,14 +20,15 @@
  */
 static inline bool dma_iommu_alloc_bypass(struct device *dev)
 {
-   return dev->archdata.iommu_bypass &&
+   return dev->archdata.iommu_bypass && !iommu_fixed_is_weak &&
dma_nommu_dma_supported(dev, dev->coherent_dma_mask);
 }
 
 static inline bool dma_iommu_map_bypass(struct device *dev,
unsigned long attrs)
 {
-   return dev->archdata.iommu_bypass;
+   return dev->archdata.iommu_bypass &&
+   (!iommu_fixed_is_weak || (attrs & DMA_ATTR_WEAK_ORDERING));
 }
 
 /* Allocates a contiguous real buffer and creates mappings over it.
@@ -168,7 +169,7 @@ int dma_iommu_mapping_error(struct device *dev, dma_addr_t 
dma_addr)
return dma_addr == IOMMU_MAPPING_ERROR;
 }
 
-struct dma_map_ops dma_iommu_ops = {
+const struct dma_map_ops dma_iommu_ops = {
.alloc  = dma_iommu_alloc_coherent,
.free   = dma_iommu_free_coherent,
.mmap   = dma_nommu_mmap_coherent,
diff --git a/arch/powerpc/platforms/cell/iommu.c 
b/arch/powerpc/platforms/cell/iommu.c
index cce5bf9515e5..fb51f78035ce 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -546,7 +546,7 @@ static unsigned long cell_dma_nommu_offset;
 static unsigned long dma_iommu_fixed_base;
 
 /* iommu_fixed_is_weak is set if booted with iommu_fixed=weak */
-static int iommu_fixed_is_weak;
+bool iommu_fixed_is_weak;
 
 static struct iommu_table *cell_get_iommu_table(struct device *dev)
 {
@@ -568,95 +568,6 @@ static struct iommu_table *cell_get_iommu_table(struct 
device *dev)
return >table;
 }
 
-/* A coherent allocation implies strong ordering */
-
-static void *dma_fixed_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag,
- unsigned long attrs)
-{
-   if (iommu_fixed_is_weak)
-   return iommu_alloc_coherent(dev, cell_get_iommu_table(dev),
-   size, dma_handle,
-   device_to_mask(dev), flag,
-   dev_to_node(dev));
-   else
-   return dma_nommu_ops.alloc(dev, size, dma_handle, flag,
-   attrs);
-}
-
-static void dma_fixed_free_coherent(struct device *dev, size_t size,
-   void *vaddr, dma_addr_t dma_handle,
-   unsigned long attrs)
-{
-   if (iommu_fixed_is_weak)
-   iommu_free_coherent(cell_get_iommu_table(dev), size, vaddr,
-   dma_handle);
-   else
-   dma_nommu_ops.free(dev, size, vaddr, dma_handle, attrs);
-}
-
-static dma_addr_t dma_fixed_map_page(struct device *dev, struct page *page,
-unsigned long offset, size_t size,
-enum dma_data_direction direction,
-unsigned long attrs)
-{
-   if (iommu_fixed_is_weak == (attrs & DMA_ATTR_WEAK_ORDERING))
-   return dma_nommu_ops.map_page(dev, page, offset, size,
-   

Re: [PATCH] powerpc: Fix HMIs on big-endian with CONFIG_RELOCATABLE=y

2018-10-09 Thread Benjamin Herrenschmidt
On Tue, 2018-10-09 at 21:37 +1100, Michael Ellerman wrote:
> Technically yes. But I thought because we build with mcmodel=medium
> we'll never actually get multiple TOCs in the kernel itself, so it
> doesn't actually matter.
> 
> So this seems to work for now:

Ok, fine. I forgot about DOTSYM. Will do for now.

Cheers,
Ben.

> diff --git a/arch/powerpc/kernel/exceptions-64s.S 
> b/arch/powerpc/kernel/exceptions-64s.S
> index 301a6a86a20f..e5566e248a02 100644
> --- a/arch/powerpc/kernel/exceptions-64s.S
> +++ b/arch/powerpc/kernel/exceptions-64s.S
> @@ -1149,7 +1149,7 @@ TRAMP_REAL_BEGIN(hmi_exception_early)
>   EXCEPTION_PROLOG_COMMON_2(PACA_EXGEN)
>   EXCEPTION_PROLOG_COMMON_3(0xe60)
>   addir3,r1,STACK_FRAME_OVERHEAD
> - BRANCH_LINK_TO_FAR(hmi_exception_realmode) /* Function call ABI */
> + BRANCH_LINK_TO_FAR(DOTSYM(hmi_exception_realmode)) /* Function call ABI 
> */
>   cmpdi   cr0,r3,0
>  
>   /* Windup the stack. */
> 
> 
> cheers



Re: [linux-next][bisected e3fbcc7c] build error at drivers/pci/pcie/aer_inject.c:444:6: error: ‘struct pt_regs’ has no member named ‘ip

2018-10-09 Thread Bjorn Helgaas
On Tue, Oct 9, 2018 at 5:40 AM Abdul Haleem  wrote:
>
> On Tue, 2018-10-09 at 20:47 +1100, Michael Ellerman wrote:
> > Abdul Haleem  writes:
> > > Greeting's
> > >
> > > Today's linux-next fails to build on ppc with below error
> > >
> > > drivers/pci/pcie/aer_inject.c: In function ‘aer_inject_ftrace_thunk’:
> > > drivers/pci/pcie/aer_inject.c:444:6: error: ‘struct pt_regs’ has no
> > > member named ‘ip’
> > >   regs->ip = (unsigned long) hook->function;
> > >   ^
> > > make[3]: *** [drivers/pci/pcie/aer_inject.o] Error 1
> > > make[2]: *** [drivers/pci/pcie] Error 2
> > > make[1]: *** [drivers/pci] Error 2
> > >
> > > Machine: Power 9
> > > kernel version: 4.19.0-rc7-next-20181008
> > > gcc version: 4.8.5 20150623
> > > config attached
> > >
> > > Recent code changes from these commits:
> > >
> > > c79ad38b36dd4967d67f83fc48bade37ee041a47 PCI/AER: Abstract AER interrupt 
> > > handling
> > > 7b23285f930a8dedcbf749661cd0f2cc27f79be6 PCI/AER: Reuse existing 
> > > pcie_port_find_device() interface
> > > e3fbcc7c4b130f81ea586183db561fa3ce9c6447 PCI/AER: Covertly inject errors 
> > > with ftrace hooks
> >
> > I don't see this commit in today's linux next (20181009) so presumably
> > someone else has noticed and dropped the commit?
>
> Yes, the commit is dropped from next-20181009, and now build is fine.

I dropped those commits yesterday.


Re: [PATCH v2 3/3] powerpc: machine check interrupt is a non-maskable interrupt

2018-10-09 Thread Nicholas Piggin
On Tue, 9 Oct 2018 14:01:37 +0200
Christophe LEROY  wrote:

> Le 09/10/2018 à 13:16, Nicholas Piggin a écrit :
> > On Tue, 9 Oct 2018 09:36:18 +
> > Christophe Leroy  wrote:
> >   
> >> On 10/09/2018 05:30 AM, Nicholas Piggin wrote:  
> >>> On Tue, 9 Oct 2018 06:46:30 +0200
> >>> Christophe LEROY  wrote:
> >>>  
>  Le 09/10/2018 à 06:32, Nicholas Piggin a écrit :  
> > On Mon, 8 Oct 2018 17:39:11 +0200
> > Christophe LEROY  wrote:
> > 
> >> Hi Nick,
> >>
> >> Le 19/07/2017 à 08:59, Nicholas Piggin a écrit :  
> >>> Use nmi_enter similarly to system reset interrupts. This uses NMI
> >>> printk NMI buffers and turns off various debugging facilities that
> >>> helps avoid tripping on ourselves or other CPUs.
> >>>
> >>> Signed-off-by: Nicholas Piggin 
> >>> ---
> >>>  arch/powerpc/kernel/traps.c | 9 ++---
> >>>  1 file changed, 6 insertions(+), 3 deletions(-)
> >>>
> >>> diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
> >>> index 2849c4f50324..6d31f9d7c333 100644
> >>> --- a/arch/powerpc/kernel/traps.c
> >>> +++ b/arch/powerpc/kernel/traps.c
> >>> @@ -789,8 +789,10 @@ int machine_check_generic(struct pt_regs *regs)
> >>>  
> >>>  void machine_check_exception(struct pt_regs *regs)
> >>>  {
> >>> - enum ctx_state prev_state = exception_enter();
> >>>   int recover = 0;
> >>> + bool nested = in_nmi();
> >>> + if (!nested)
> >>> + nmi_enter();  
> >>
> >> This alters preempt_count, then when die() is called
> >> in_interrupt() returns true allthough the trap didn't happen in
> >> interrupt, so oops_end() panics for "fatal exception in interrupt"
> >> instead of gently sending SIGBUS the faulting app.  
> >
> > Thanks for tracking that down.
> > 
> >> Any idea on how to fix this ?  
> >
> > I would say we have to deliver the sigbus by hand.
> >
> >if ((user_mode(regs)))
> >_exception(SIGBUS, regs, BUS_MCEERR_AR, regs->nip);
> >else
> >die("Machine check", regs, SIGBUS);
> > 
> 
>  And what about all the other things done by 'die()' ?
> 
>  And what if it is a kernel thread ?
> 
>  In one of my boards, I have a kernel thread regularly checking the HW,
>  and if it gets a machine check I expect it to gently stop and the die
>  notification to be delivered to all registered notifiers.
> 
>  Until before this patch, it was working well.  
> >>>
> >>> I guess the alternative is we could check regs->trap for machine
> >>> check in the die test. Complication is having to account for MCE
> >>> in an interrupt handler.
> >>>
> >>>  if (in_interrupt()) {
> >>>   if (!IS_MCHECK_EXC(regs) || (irq_count() - (NMI_OFFSET 
> >>> + HARDIRQ_OFFSET)))
> >>>   panic("Fatal exception in interrupt");
> >>>  }
> >>>
> >>> Something like that might work for you? We needs a ppc64 macro for the
> >>> MCE, and can probably add something like in_nmi_from_interrupt() for
> >>> the second part of the test.  
> >>
> >> Don't know, I'm away from home on business trip so I won't be able to
> >> test anything before next week. However it looks more or less like a
> >> hack, doesn't it ?  
> > 
> > I thought it seemed okay (with the right functions added). Actually it
> > could be a bit nicer to do this, then it works generally :
> > 
> >   if (in_interrupt()) {
> >if (!in_nmi() || in_nmi_from_interrupt())
> >panic("Fatal exception in interrupt");
> >   }  
> 
> 
> Yes looks nice, but:
> 1/ what is in_nmi_from_interrupt() ? Is it (in_nmi() && (in_irq() || 
> in_softirq()) ?

  return (irq_count() - (NMI_OFFSET + HARDIRQ_OFFSET))) != 0;

(basically just in_interrupt() with the nmi_enter undone)

> 2/ what about in_nmi_from_nmi(), how do we detect that ?

Oh good point, I'm not sure. I guess we could irq_enter() in the
nested case, I think that would make in_nmi_from_interrupt()
return true.

Thanks,
Nick


Re: [PATCH v2 3/3] powerpc: machine check interrupt is a non-maskable interrupt

2018-10-09 Thread Christophe LEROY




Le 09/10/2018 à 13:16, Nicholas Piggin a écrit :

On Tue, 9 Oct 2018 09:36:18 +
Christophe Leroy  wrote:


On 10/09/2018 05:30 AM, Nicholas Piggin wrote:

On Tue, 9 Oct 2018 06:46:30 +0200
Christophe LEROY  wrote:
   

Le 09/10/2018 à 06:32, Nicholas Piggin a écrit :

On Mon, 8 Oct 2018 17:39:11 +0200
Christophe LEROY  wrote:
  

Hi Nick,

Le 19/07/2017 à 08:59, Nicholas Piggin a écrit :

Use nmi_enter similarly to system reset interrupts. This uses NMI
printk NMI buffers and turns off various debugging facilities that
helps avoid tripping on ourselves or other CPUs.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/kernel/traps.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 2849c4f50324..6d31f9d7c333 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -789,8 +789,10 @@ int machine_check_generic(struct pt_regs *regs)
 
 void machine_check_exception(struct pt_regs *regs)

 {
-   enum ctx_state prev_state = exception_enter();
int recover = 0;
+   bool nested = in_nmi();
+   if (!nested)
+   nmi_enter();


This alters preempt_count, then when die() is called
in_interrupt() returns true allthough the trap didn't happen in
interrupt, so oops_end() panics for "fatal exception in interrupt"
instead of gently sending SIGBUS the faulting app.


Thanks for tracking that down.
  

Any idea on how to fix this ?


I would say we have to deliver the sigbus by hand.

   if ((user_mode(regs)))
   _exception(SIGBUS, regs, BUS_MCEERR_AR, regs->nip);
   else
   die("Machine check", regs, SIGBUS);
  


And what about all the other things done by 'die()' ?

And what if it is a kernel thread ?

In one of my boards, I have a kernel thread regularly checking the HW,
and if it gets a machine check I expect it to gently stop and the die
notification to be delivered to all registered notifiers.

Until before this patch, it was working well.


I guess the alternative is we could check regs->trap for machine
check in the die test. Complication is having to account for MCE
in an interrupt handler.

 if (in_interrupt()) {
  if (!IS_MCHECK_EXC(regs) || (irq_count() - (NMI_OFFSET + 
HARDIRQ_OFFSET)))
  panic("Fatal exception in interrupt");
 }

Something like that might work for you? We needs a ppc64 macro for the
MCE, and can probably add something like in_nmi_from_interrupt() for
the second part of the test.


Don't know, I'm away from home on business trip so I won't be able to
test anything before next week. However it looks more or less like a
hack, doesn't it ?


I thought it seemed okay (with the right functions added). Actually it
could be a bit nicer to do this, then it works generally :

  if (in_interrupt()) {
   if (!in_nmi() || in_nmi_from_interrupt())
   panic("Fatal exception in interrupt");
  }



Yes looks nice, but:
1/ what is in_nmi_from_interrupt() ? Is it (in_nmi() && (in_irq() || 
in_softirq()) ?

2/ what about in_nmi_from_nmi(), how do we detect that ?

Christophe





What about the following ?


Hmm, in some ways maybe it's nicer. One complication is I would like the
same thing to be available for platform specific machine check
handlers, so then you need to pass is_in_interrupt to them. Which you
can do without any problem... But is it cleaner than the above?

I guess one advantage of yours is that a BUG somewhere in the NMI path
will panic the system. Or is that a disadvantage?

Thanks,
Nick




diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index fd58749b4d6b..1f09033a5103 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -208,7 +208,7 @@ static unsigned long oops_begin(struct pt_regs *regs)
   NOKPROBE_SYMBOL(oops_begin);

   static void oops_end(unsigned long flags, struct pt_regs *regs,
-  int signr)
+int signr, bool is_in_interrupt)
   {
bust_spinlocks(0);
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
@@ -247,7 +247,7 @@ static void oops_end(unsigned long flags, struct
pt_regs *regs,
mdelay(MSEC_PER_SEC);
}

-   if (in_interrupt())
+   if (is_in_interrupt)
panic("Fatal exception in interrupt");
if (panic_on_oops)
panic("Fatal exception");
@@ -288,7 +288,7 @@ static int __die(const char *str, struct pt_regs
*regs, long err)
   }
   NOKPROBE_SYMBOL(__die);

-void die(const char *str, struct pt_regs *regs, long err)
+static void nmi_die(const char *str, struct pt_regs *regs, long err,
bool is_in_interrupt)
   {
unsigned long flags;

@@ -303,7 +303,13 @@ void die(const char *str, struct pt_regs *regs,
long err)
flags = oops_begin(regs);
if (__die(str, regs, err))
err = 

Re: [PATCH 13/36] dt-bindings: arm: Convert PMU binding to json-schema

2018-10-09 Thread Will Deacon
Hi Rob,

On Fri, Oct 05, 2018 at 11:58:25AM -0500, Rob Herring wrote:
> Convert ARM PMU binding to DT schema format using json-schema.
> 
> Cc: Will Deacon 
> Cc: Mark Rutland 
> Cc: linux-arm-ker...@lists.infradead.org
> Cc: devicet...@vger.kernel.org
> Signed-off-by: Rob Herring 
> ---
>  Documentation/devicetree/bindings/arm/pmu.txt | 70 --
>  .../devicetree/bindings/arm/pmu.yaml  | 96 +++
>  2 files changed, 96 insertions(+), 70 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/arm/pmu.txt
>  create mode 100644 Documentation/devicetree/bindings/arm/pmu.yaml

[...]

> -- interrupts : 1 combined interrupt or 1 per core. If the interrupt is a 
> per-cpu
> -   interrupt (PPI) then 1 interrupt should be specified.

[...]

> +  interrupts:
> +oneOf:
> +  - maxItems: 1
> +  - minItems: 2
> +maxItems: 8
> +description: 1 interrupt per core.
> +
> +  interrupts-extended:
> +$ref: '#/properties/interrupts'

This seems like a semantic different between the two representations, or am
I missing something here? Specifically, both the introduction of
interrupts-extended and also dropping any mention of using a single per-cpu
interrupt (the single combined case is no longer support by Linux; not sure
if you want to keep it in the binding).

Will


Re: [PATCH] powerpc: signedness bug in update_flash_db()

2018-10-09 Thread Michael Ellerman
christophe leroy  writes:

> Le 01/10/2018 à 18:44, Dan Carpenter a écrit :
>> The "count < sizeof(struct os_area_db)" comparison is type promoted to
>> size_t so negative values of "count" are treated as very high values and
>> we accidentally return success instead of a negative error code.
>> 
>> This doesn't really change runtime much but it fixes a static checker
>> warning.
>> 
>> Signed-off-by: Dan Carpenter 
>> 
>> diff --git a/arch/powerpc/platforms/ps3/os-area.c 
>> b/arch/powerpc/platforms/ps3/os-area.c
>> index cdbfc5cfd6f3..f5387ad82279 100644
>> --- a/arch/powerpc/platforms/ps3/os-area.c
>> +++ b/arch/powerpc/platforms/ps3/os-area.c
>> @@ -664,7 +664,7 @@ static int update_flash_db(void)
>>  db_set_64(db, _area_db_id_rtc_diff, saved_params.rtc_diff);
>>   
>>  count = os_area_flash_write(db, sizeof(struct os_area_db), pos);
>> -if (count < sizeof(struct os_area_db)) {
>> +if (count < 0 || count < sizeof(struct os_area_db)) {
>
> Why not simply add a cast ? :
>
> if (count < (ssize_t)sizeof(struct os_area_db)) {

The explicit check against 0 is much clearer IMO.

The original author and all reviewers since obviously didn't realise
that count was being implicitly cast, so fixing that with another cast
seems likely to just confuse people even more :)

cheers


Re: [PATCH] powerpc/mobility: Extend start/stop topology update scope

2018-10-09 Thread Michael Ellerman
Michael Bringmann  writes:

> The PPC mobility code may receive RTAS requests to perform PRRN
> topology changes at any time, including during LPAR migration
> operations.  In some configurations where the affinity of CPUs
> or memory is being changed on that platform, the PRRN requests
> may apply or refer to outdated information prior to the complete
> update of the device-tree.  This patch changes the duration for
> which topology updates are suppressed during LPAR migrations from
> just the rtas_ibm_suspend_me / 'ibm,suspend-me' call(s) to cover
> the entire 'migration_store' operation to allow all changes to
> the device-tree to be applied prior to accepting and applying any
> PRRN requests.
>
> For tracking purposes, pr_info notices are added to the functions
> start_topology_update() and stop_topology_update() of 'numa.c'.
>
> Signed-off-by: Michael Bringmann 
> ---
>  arch/powerpc/kernel/rtas.c|4 
>  arch/powerpc/mm/numa.c|6 ++
>  arch/powerpc/platforms/pseries/mobility.c |5 +
>  3 files changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> index 8afd146..28d8b57 100644
> --- a/arch/powerpc/kernel/rtas.c
> +++ b/arch/powerpc/kernel/rtas.c
> @@ -981,8 +981,6 @@ int rtas_ibm_suspend_me(u64 handle)
>   goto out;
>   }
>  
> - stop_topology_update();
> -
>   /* Call function on all CPUs.  One of us will make the
>* rtas call
>*/

This doesn't apply to my next branch, it conflicts with:

  85a88cabad57 ("powerpc/pseries: Disable CPU hotplug across migrations")

Can you please rebase it?

https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/log/?h=next

cheers


Re: [PATCH v03 1/5] powerpc/drmem: Export 'dynamic-memory' loader

2018-10-09 Thread Michael Ellerman
Nathan Fontenot  writes:

> On 10/02/2018 08:00 PM, Michael Ellerman wrote:
>> Michael Bringmann  writes:
>> 
>>> powerpc/drmem: Export many of the functions of DRMEM to parse
>>> "ibm,dynamic-memory" and "ibm,dynamic-memory-v2" during hotplug
>>> operations and for Post Migration events.
>> 
>> This isn't a criticism of your patch, but I think the drmem.c code
>> should be moved into platforms/pseries.
>> 
>> That would then make most of it private to platforms/pseries and we
>> wouldn't need to export things in arch/powerpc/include/asm.
>
> I don't have an issue with moving it to platform/pseries. I originally
> put it in arch/powerpc/mm because the numa code also uses the drmem code.

Yeah, originally the NUMA code was only used on pseries so the
distinction between NUMA and pseries-specific NUMA didn't exist.

But these days we're getting more and more code that is really pseries
(or PAPR) specific, so it might make sense to move it.

I may be wrong, perhaps there isn't a clean split there, but it would be
worth trying.

cheers


  1   2   >