LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 3/3] mm: introduce ARCH_HAS_PTE_DEVMAP
From: Robin Murphy @ 2019-04-29 17:22 UTC (permalink / raw)
  To: linux-mm
  Cc: Ira Weiny, Anshuman Khandual, x86, linux-kernel,
	Oliver O'Halloran, akpm, linuxppc-dev, Dan Williams
In-Reply-To: <cover.1556555457.git.robin.murphy@arm.com>

ARCH_HAS_ZONE_DEVICE is somewhat meaningless in itself, and combined
with the long-out-of-date comment can lead to the impression than an
architecture may just enable it (since __add_pages() now "comprehends
device memory" for itself) and expect things to work.

In practice, however, ZONE_DEVICE users have little chance of
functioning correctly without __HAVE_ARCH_PTE_DEVMAP, so let's clean
that up the same way as ARCH_HAS_PTE_SPECIAL and make it the proper
dependency so the real situation is clearer.

Cc: x86@kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Michael Ellerman <mpe@ellerman.id.au>
Acked-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Acked-by: Oliver O'Halloran <oohall@gmail.com>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---

v2: Add review tags.

 arch/powerpc/Kconfig                         | 2 +-
 arch/powerpc/include/asm/book3s/64/pgtable.h | 1 -
 arch/x86/Kconfig                             | 2 +-
 arch/x86/include/asm/pgtable.h               | 4 ++--
 arch/x86/include/asm/pgtable_types.h         | 1 -
 include/linux/mm.h                           | 4 ++--
 include/linux/pfn_t.h                        | 4 ++--
 mm/Kconfig                                   | 5 ++---
 mm/gup.c                                     | 2 +-
 9 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 5e3d0853c31d..77e1993bba80 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -135,6 +135,7 @@ config PPC
 	select ARCH_HAS_MMIOWB			if PPC64
 	select ARCH_HAS_PHYS_TO_DMA
 	select ARCH_HAS_PMEM_API                if PPC64
+	select ARCH_HAS_PTE_DEVMAP		if PPC_BOOK3S_64
 	select ARCH_HAS_PTE_SPECIAL
 	select ARCH_HAS_MEMBARRIER_CALLBACKS
 	select ARCH_HAS_SCALED_CPUTIME		if VIRT_CPU_ACCOUNTING_NATIVE && PPC64
@@ -142,7 +143,6 @@ config PPC
 	select ARCH_HAS_TICK_BROADCAST		if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_HAS_UACCESS_FLUSHCACHE	if PPC64
 	select ARCH_HAS_UBSAN_SANITIZE_ALL
-	select ARCH_HAS_ZONE_DEVICE		if PPC_BOOK3S_64
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select ARCH_MIGHT_HAVE_PC_SERIO
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index 581f91be9dd4..02c22ac8f387 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -90,7 +90,6 @@
 #define _PAGE_SOFT_DIRTY	_RPAGE_SW3 /* software: software dirty tracking */
 #define _PAGE_SPECIAL		_RPAGE_SW2 /* software: special page */
 #define _PAGE_DEVMAP		_RPAGE_SW1 /* software: ZONE_DEVICE page */
-#define __HAVE_ARCH_PTE_DEVMAP
 
 /*
  * Drivers request for cache inhibited pte mapping using _PAGE_NO_CACHE
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5ad92419be19..ffd50f27f395 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -60,6 +60,7 @@ config X86
 	select ARCH_HAS_KCOV			if X86_64
 	select ARCH_HAS_MEMBARRIER_SYNC_CORE
 	select ARCH_HAS_PMEM_API		if X86_64
+	select ARCH_HAS_PTE_DEVMAP		if X86_64
 	select ARCH_HAS_PTE_SPECIAL
 	select ARCH_HAS_REFCOUNT
 	select ARCH_HAS_UACCESS_FLUSHCACHE	if X86_64
@@ -69,7 +70,6 @@ config X86
 	select ARCH_HAS_STRICT_MODULE_RWX
 	select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
 	select ARCH_HAS_UBSAN_SANITIZE_ALL
-	select ARCH_HAS_ZONE_DEVICE		if X86_64
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select ARCH_MIGHT_HAVE_ACPI_PDC		if ACPI
 	select ARCH_MIGHT_HAVE_PC_PARPORT
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 2779ace16d23..89a1f6fd48bf 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -254,7 +254,7 @@ static inline int has_transparent_hugepage(void)
 	return boot_cpu_has(X86_FEATURE_PSE);
 }
 
-#ifdef __HAVE_ARCH_PTE_DEVMAP
+#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP
 static inline int pmd_devmap(pmd_t pmd)
 {
 	return !!(pmd_val(pmd) & _PAGE_DEVMAP);
@@ -715,7 +715,7 @@ static inline int pte_present(pte_t a)
 	return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE);
 }
 
-#ifdef __HAVE_ARCH_PTE_DEVMAP
+#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP
 static inline int pte_devmap(pte_t a)
 {
 	return (pte_flags(a) & _PAGE_DEVMAP) == _PAGE_DEVMAP;
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index d6ff0bbdb394..b5e49e6bac63 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -103,7 +103,6 @@
 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
 #define _PAGE_NX	(_AT(pteval_t, 1) << _PAGE_BIT_NX)
 #define _PAGE_DEVMAP	(_AT(u64, 1) << _PAGE_BIT_DEVMAP)
-#define __HAVE_ARCH_PTE_DEVMAP
 #else
 #define _PAGE_NX	(_AT(pteval_t, 0))
 #define _PAGE_DEVMAP	(_AT(pteval_t, 0))
diff --git a/include/linux/mm.h b/include/linux/mm.h
index d76dfb7ac617..fe05c94f23e9 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -504,7 +504,7 @@ struct inode;
 #define page_private(page)		((page)->private)
 #define set_page_private(page, v)	((page)->private = (v))
 
-#if !defined(__HAVE_ARCH_PTE_DEVMAP) || !defined(CONFIG_TRANSPARENT_HUGEPAGE)
+#if !defined(CONFIG_ARCH_HAS_PTE_DEVMAP) || !defined(CONFIG_TRANSPARENT_HUGEPAGE)
 static inline int pmd_devmap(pmd_t pmd)
 {
 	return 0;
@@ -1698,7 +1698,7 @@ static inline void sync_mm_rss(struct mm_struct *mm)
 }
 #endif
 
-#ifndef __HAVE_ARCH_PTE_DEVMAP
+#ifndef CONFIG_ARCH_HAS_PTE_DEVMAP
 static inline int pte_devmap(pte_t pte)
 {
 	return 0;
diff --git a/include/linux/pfn_t.h b/include/linux/pfn_t.h
index 7bb77850c65a..de8bc66b10a4 100644
--- a/include/linux/pfn_t.h
+++ b/include/linux/pfn_t.h
@@ -104,7 +104,7 @@ static inline pud_t pfn_t_pud(pfn_t pfn, pgprot_t pgprot)
 #endif
 #endif
 
-#ifdef __HAVE_ARCH_PTE_DEVMAP
+#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP
 static inline bool pfn_t_devmap(pfn_t pfn)
 {
 	const u64 flags = PFN_DEV|PFN_MAP;
@@ -122,7 +122,7 @@ pmd_t pmd_mkdevmap(pmd_t pmd);
 	defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
 pud_t pud_mkdevmap(pud_t pud);
 #endif
-#endif /* __HAVE_ARCH_PTE_DEVMAP */
+#endif /* CONFIG_ARCH_HAS_PTE_DEVMAP */
 
 #ifdef CONFIG_ARCH_HAS_PTE_SPECIAL
 static inline bool pfn_t_special(pfn_t pfn)
diff --git a/mm/Kconfig b/mm/Kconfig
index 25c71eb8a7db..fcb7ab08e294 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -655,8 +655,7 @@ config IDLE_PAGE_TRACKING
 	  See Documentation/admin-guide/mm/idle_page_tracking.rst for
 	  more details.
 
-# arch_add_memory() comprehends device memory
-config ARCH_HAS_ZONE_DEVICE
+config ARCH_HAS_PTE_DEVMAP
 	bool
 
 config ZONE_DEVICE
@@ -664,7 +663,7 @@ config ZONE_DEVICE
 	depends on MEMORY_HOTPLUG
 	depends on MEMORY_HOTREMOVE
 	depends on SPARSEMEM_VMEMMAP
-	depends on ARCH_HAS_ZONE_DEVICE
+	depends on ARCH_HAS_PTE_DEVMAP
 	select XARRAY_MULTI
 
 	help
diff --git a/mm/gup.c b/mm/gup.c
index f84e22685aaa..72a5c7d1e1a7 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1623,7 +1623,7 @@ static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end,
 }
 #endif /* CONFIG_ARCH_HAS_PTE_SPECIAL */
 
-#if defined(__HAVE_ARCH_PTE_DEVMAP) && defined(CONFIG_TRANSPARENT_HUGEPAGE)
+#if defined(CONFIG_ARCH_HAS_PTE_DEVMAP) && defined(CONFIG_TRANSPARENT_HUGEPAGE)
 static int __gup_device_huge(unsigned long pfn, unsigned long addr,
 		unsigned long end, struct page **pages, int *nr)
 {
-- 
2.21.0.dirty


^ permalink raw reply related

* Re: serial drivers polishing
From: Enrico Weigelt, metux IT consult @ 2019-04-29 16:50 UTC (permalink / raw)
  To: Christophe Leroy, Enrico Weigelt, metux IT consult, linux-kernel
  Cc: lorenzo.pieralisi, linux-ia64, macro, andrew, gregkh,
	slemieux.tyco, liviu.dudau, linux-mips, vz, linux, matthias.bgg,
	khilman, linux-serial, sudeep.holla, sparclinux, jacmet,
	linux-amlogic, andriy.shevchenko, linuxppc-dev, davem
In-Reply-To: <7471c418-4058-db7b-b2ed-af9a67fff201@c-s.fr>

On 29.04.19 18:16, Christophe Leroy wrote:

Hi,

> Got the following build  error while compiling for my powerpc board with
> your full series applied. No time to investigate though.

thanks, fixed it. That was the unclean patch where i've forgotten to
add 'rfc' into the title ... turned out that this one needs some
more rework :o

--mtx

-- 
Enrico Weigelt, metux IT consult
Free software and Linux embedded engineering
info@metux.net -- +49-151-27565287

^ permalink raw reply

* Re: [PATCH 22/41] drivers: tty: serial: cpm_uart: fix logging calls
From: Enrico Weigelt, metux IT consult @ 2019-04-29 16:20 UTC (permalink / raw)
  To: Christophe Leroy, Enrico Weigelt, metux IT consult, linux-kernel
  Cc: lorenzo.pieralisi, linux-ia64, macro, andrew, gregkh,
	slemieux.tyco, liviu.dudau, linux-mips, vz, linux, matthias.bgg,
	khilman, linux-serial, sudeep.holla, sparclinux, jacmet,
	linux-amlogic, andriy.shevchenko, linuxppc-dev, davem
In-Reply-To: <a00ba23b-e73e-c964-a6d0-347cb605b8c8@c-s.fr>

On 29.04.19 17:59, Christophe Leroy wrote:

> If we want to do something useful, wouldn't it make more sense to
> introduce the use of dev_err() in order to identify the faulting device
> in the message ?

Well, I could get the struct device* pointer via pinfo.port->dev,
but I wasn't entirely sure that it's always defined before these
functions could be called.

Shall I change it to dev_*() ?


--mtx

-- 
Enrico Weigelt, metux IT consult
Free software and Linux embedded engineering
info@metux.net -- +49-151-27565287

^ permalink raw reply

* Re: serial drivers polishing
From: Christophe Leroy @ 2019-04-29 16:16 UTC (permalink / raw)
  To: Enrico Weigelt, metux IT consult, linux-kernel
  Cc: lorenzo.pieralisi, linux-ia64, macro, andrew, gregkh,
	slemieux.tyco, liviu.dudau, linux-mips, vz, linux, matthias.bgg,
	khilman, linux-serial, sudeep.holla, sparclinux, jacmet,
	linux-amlogic, andriy.shevchenko, linuxppc-dev, davem
In-Reply-To: <1556369542-13247-1-git-send-email-info@metux.net>

Hi,

On 04/27/2019 12:51 PM, Enrico Weigelt, metux IT consult wrote:
> Hello folks,
> 
> 
> here's another attempt of polishing the serial drivers:
> 
> * lots of minor cleanups to make checkpatch happier
>    (eg. formatting, includes, inttypes, ...)
> 
> * use appropriate logging helpers instead of printk()
> 
> * consequent use of mapsize/mapbase fields:
>    the basic idea is, all drivers should fill mapbase/mapbase fields at
>    init time and later only use those fields, instead of hardcoded values
>    (later on, we can add generic helpers for the map/unmap stuff, etc)
> 
> * untwisting serial8250_port_size() at all:
>    move the iomem size probing to initialization time, move out some
>    platform specific magic to corresponding platform code, etc.
> 
> 
> Unfortunately, I don't have the actual hardware to really test all
> the code, so please let me know if there's something broken in here.
> 
> 
> have fun,
> 
> --mtx
> 


Got the following build  error while compiling for my powerpc board with 
your full series applied. No time to investigate though.

   CC      arch/powerpc/kernel/setup-common.o
In file included from ./include/linux/serial_8250.h:14:0,
                  from arch/powerpc/kernel/setup-common.c:33:
./include/linux/serial_core.h: In function ‘uart_memres_set_res’:
./include/linux/serial_core.h:446:18: error: ‘resource’ undeclared 
(first use in this function)
    port->iobase = resource->start;
                   ^
./include/linux/serial_core.h:446:18: note: each undeclared identifier 
is reported only once for each function it appears in
./include/linux/serial_core.h:450:2: error: ‘uart’ undeclared (first use 
in this function)
   uart->mapbase = res->start;
   ^
./include/linux/serial_core.h: In function ‘uart_memres_set_start_len’:
./include/linux/serial_core.h:464:6: error: ‘struct uart_driver’ has no 
member named ‘mapbase’
   uart->mapbase = start;
       ^
./include/linux/serial_core.h:465:6: error: ‘struct uart_driver’ has no 
member named ‘mapsize’
   uart->mapsize = len;
       ^
./include/linux/serial_core.h:466:6: error: ‘struct uart_driver’ has no 
member named ‘iotype’
   uart->iotype  = UPIO_MEM;
       ^
make[3]: *** [arch/powerpc/kernel/setup-common.o] Error 1


Christophe

^ permalink raw reply

* Re: [PATCH 21/41] drivers: tty: serial: cpm_uart: fix includes
From: Christophe Leroy @ 2019-04-29 16:02 UTC (permalink / raw)
  To: Enrico Weigelt, metux IT consult, linux-kernel
  Cc: lorenzo.pieralisi, linux-ia64, macro, andrew, gregkh,
	slemieux.tyco, liviu.dudau, linux-mips, vz, linux, matthias.bgg,
	khilman, linux-serial, sudeep.holla, sparclinux, jacmet,
	linux-amlogic, andriy.shevchenko, linuxppc-dev, davem
In-Reply-To: <1556369542-13247-22-git-send-email-info@metux.net>



Le 27/04/2019 à 14:52, Enrico Weigelt, metux IT consult a écrit :
> Fixing checkpatch warning:
> 
>      WARNING: Use #include <linux/io.h> instead of <asm/io.h>
>      #25: FILE: drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c:25:
>      +#include <asm/io.h>
> 
>      WARNING: Use #include <linux/io.h> instead of <asm/io.h>
>      +#include <asm/io.h>
> 
>      WARNING: Use #include <linux/delay.h> instead of <asm/delay.h>
>      +#include <asm/delay.h>
> 
> Signed-off-by: Enrico Weigelt <info@metux.net>

Reviewed-by: Christophe Leroy <christophe.leroy@c-s.fr>

> ---
>   drivers/tty/serial/cpm_uart/cpm_uart_core.c | 4 ++--
>   drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c | 2 +-
>   2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
> index 374b8bb..c831d31 100644
> --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c
> +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
> @@ -33,10 +33,10 @@
>   #include <linux/gpio.h>
>   #include <linux/of_gpio.h>
>   #include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/delay.h>
>   
> -#include <asm/io.h>
>   #include <asm/irq.h>
> -#include <asm/delay.h>
>   #include <asm/fs_pd.h>
>   #include <asm/udbg.h>
>   
> diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c
> index ef1ae08..40cfcf4 100644
> --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c
> +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c
> @@ -21,8 +21,8 @@
>   #include <linux/device.h>
>   #include <linux/memblock.h>
>   #include <linux/dma-mapping.h>
> +#include <linux/io.h>
>   
> -#include <asm/io.h>
>   #include <asm/irq.h>
>   #include <asm/fs_pd.h>
>   #include <asm/prom.h>
> 

^ permalink raw reply

* Re: [PATCH 20/41] drivers: tty: serial: cpm_uart: use dev_err()/dev_warn() instead of printk()
From: Christophe Leroy @ 2019-04-29 16:02 UTC (permalink / raw)
  To: Enrico Weigelt, metux IT consult, linux-kernel
  Cc: lorenzo.pieralisi, linux-ia64, macro, andrew, gregkh,
	slemieux.tyco, liviu.dudau, linux-mips, vz, linux, matthias.bgg,
	khilman, linux-serial, sudeep.holla, sparclinux, jacmet,
	linux-amlogic, andriy.shevchenko, linuxppc-dev, davem
In-Reply-To: <1556369542-13247-21-git-send-email-info@metux.net>



Le 27/04/2019 à 14:52, Enrico Weigelt, metux IT consult a écrit :
> Using dev_err()/dev_warn() instead of printk() for more consistent output.
> (prints device name, etc).
> 
> Signed-off-by: Enrico Weigelt <info@metux.net>

Reviewed-by: Christophe Leroy <christophe.leroy@c-s.fr>

> ---
>   drivers/tty/serial/cpm_uart/cpm_uart_core.c | 6 +++---
>   drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c | 2 +-
>   2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
> index b929c7a..374b8bb 100644
> --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c
> +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
> @@ -265,7 +265,7 @@ static void cpm_uart_int_rx(struct uart_port *port)
>   		 * later, which will be the next rx-interrupt or a timeout
>   		 */
>   		if (tty_buffer_request_room(tport, i) < i) {
> -			printk(KERN_WARNING "No room in flip buffer\n");
> +			dev_warn(port->dev, "No room in flip buffer\n");
>   			return;
>   		}
>   
> @@ -1155,7 +1155,7 @@ static int cpm_uart_init_port(struct device_node *np,
>   	if (!pinfo->clk) {
>   		data = of_get_property(np, "fsl,cpm-brg", &len);
>   		if (!data || len != 4) {
> -			printk(KERN_ERR "CPM UART %pOFn has no/invalid "
> +			dev_err(port->dev, "CPM UART %pOFn has no/invalid "
>   			                "fsl,cpm-brg property.\n", np);
>   			return -EINVAL;
>   		}
> @@ -1164,7 +1164,7 @@ static int cpm_uart_init_port(struct device_node *np,
>   
>   	data = of_get_property(np, "fsl,cpm-command", &len);
>   	if (!data || len != 4) {
> -		printk(KERN_ERR "CPM UART %pOFn has no/invalid "
> +		dev_err(port->dev, "CPM UART %pOFn has no/invalid "
>   		                "fsl,cpm-command property.\n", np);
>   		return -EINVAL;
>   	}
> diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c
> index 6a1cd03..ef1ae08 100644
> --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c
> +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c
> @@ -67,7 +67,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
>   		return pram;
>   
>   	if (len != 2) {
> -		printk(KERN_WARNING "cpm_uart[%d]: device tree references "
> +		dev_warn(port->dev, "cpm_uart[%d]: device tree references "
>   			"SMC pram, using boot loader/wrapper pram mapping. "
>   			"Please fix your device tree to reference the pram "
>   			"base register instead.\n",
> 

^ permalink raw reply

* Re: [PATCH 37/41] drivers: tty: serial: 8250: simplify io resource size computation
From: Enrico Weigelt, metux IT consult @ 2019-04-29 15:58 UTC (permalink / raw)
  To: John Paul Adrian Glaubitz, Enrico Weigelt, metux IT consult,
	linux-kernel
  Cc: lorenzo.pieralisi, linux-ia64, linux-serial, andrew, gregkh,
	sudeep.holla, liviu.dudau, linux-mips, vz, linux, sparclinux,
	khilman, macro, slemieux.tyco, matthias.bgg, jacmet,
	linux-amlogic, andriy.shevchenko, linuxppc-dev, davem
In-Reply-To: <ba6dd5fa-36f1-902d-1ab4-c99e6a5ea3c2@physik.fu-berlin.de>

On 27.04.19 15:03, John Paul Adrian Glaubitz wrote:
> On 4/27/19 2:52 PM, Enrico Weigelt, metux IT consult wrote:
>> Simpily io resource size computation by setting mapsize field.
>     ^^^^
> Here's a typo

thx. fixed.

--mtx


-- 
Enrico Weigelt, metux IT consult
Free software and Linux embedded engineering
info@metux.net -- +49-151-27565287

^ permalink raw reply

* Re: [PATCH 22/41] drivers: tty: serial: cpm_uart: fix logging calls
From: Christophe Leroy @ 2019-04-29 15:59 UTC (permalink / raw)
  To: Enrico Weigelt, metux IT consult, linux-kernel
  Cc: lorenzo.pieralisi, linux-ia64, macro, andrew, gregkh,
	slemieux.tyco, liviu.dudau, linux-mips, vz, linux, matthias.bgg,
	khilman, linux-serial, sudeep.holla, sparclinux, jacmet,
	linux-amlogic, andriy.shevchenko, linuxppc-dev, davem
In-Reply-To: <1556369542-13247-23-git-send-email-info@metux.net>



Le 27/04/2019 à 14:52, Enrico Weigelt, metux IT consult a écrit :
> Fix checkpatch warnings by using pr_err():
> 
>      WARNING: Prefer [subsystem eg: netdev]_err([subsystem]dev, ... then dev_err(dev, ... then pr_err(...  to printk(KERN_ERR ...
>      #109: FILE: drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c:109:
>      +		printk(KERN_ERR
> 
>      WARNING: Prefer [subsystem eg: netdev]_err([subsystem]dev, ... then dev_err(dev, ... then pr_err(...  to printk(KERN_ERR ...
>      #128: FILE: drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c:128:
>      +		printk(KERN_ERR
> 
>      WARNING: Prefer [subsystem eg: netdev]_err([subsystem]dev, ... then dev_err(dev, ... then pr_err(...  to printk(KERN_ERR ...
>      +           printk(KERN_ERR
> 
>      WARNING: Prefer [subsystem eg: netdev]_err([subsystem]dev, ... then dev_err(dev, ... then pr_err(...  to printk(KERN_ERR ...
>      +           printk(KERN_ERR
> 
> Signed-off-by: Enrico Weigelt <info@metux.net>

Reviewed-by: Christophe Leroy <christophe.leroy@c-s.fr>

But is that really worth doing those changes ?

If we want to do something useful, wouldn't it make more sense to 
introduce the use of dev_err() in order to identify the faulting device 
in the message ?

Christophe

> ---
>   drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c | 6 ++----
>   drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c | 6 ++----
>   2 files changed, 4 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c
> index 56fc527..aed61e9 100644
> --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c
> +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c
> @@ -71,8 +71,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
>   	dpmemsz = sizeof(cbd_t) * (pinfo->rx_nrfifos + pinfo->tx_nrfifos);
>   	dp_offset = cpm_dpalloc(dpmemsz, 8);
>   	if (IS_ERR_VALUE(dp_offset)) {
> -		printk(KERN_ERR
> -		       "cpm_uart_cpm1.c: could not allocate buffer descriptors\n");
> +		pr_err("cpm_uart_cpm1.c: could not allocate buffer descriptors\n");
>   		return -ENOMEM;
>   	}
>   	dp_mem = cpm_dpram_addr(dp_offset);
> @@ -90,8 +89,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
>   
>   	if (mem_addr == NULL) {
>   		cpm_dpfree(dp_offset);
> -		printk(KERN_ERR
> -		       "cpm_uart_cpm1.c: could not allocate coherent memory\n");
> +		pr_err("cpm_uart_cpm1.c: could not allocate coherent memory\n");
>   		return -ENOMEM;
>   	}
>   
> diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c
> index 40cfcf4..a0fccda 100644
> --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c
> +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c
> @@ -106,8 +106,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
>   	dpmemsz = sizeof(cbd_t) * (pinfo->rx_nrfifos + pinfo->tx_nrfifos);
>   	dp_offset = cpm_dpalloc(dpmemsz, 8);
>   	if (IS_ERR_VALUE(dp_offset)) {
> -		printk(KERN_ERR
> -		       "cpm_uart_cpm.c: could not allocate buffer descriptors\n");
> +		pr_err("cpm_uart_cpm.c: could not allocate buffer descriptors\n");
>   		return -ENOMEM;
>   	}
>   
> @@ -125,8 +124,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
>   
>   	if (mem_addr == NULL) {
>   		cpm_dpfree(dp_offset);
> -		printk(KERN_ERR
> -		       "cpm_uart_cpm.c: could not allocate coherent memory\n");
> +		pr_err("cpm_uart_cpm.c: could not allocate coherent memory\n");
>   		return -ENOMEM;
>   	}
>   
> 

^ permalink raw reply

* [PATCH stable v4.4 6/8] powerpc/fsl: Fixed warning: orphan section `__btb_flush_fixup'
From: Diana Craciun @ 2019-04-29 15:49 UTC (permalink / raw)
  To: stable, gregkh; +Cc: Diana Craciun, linuxppc-dev
In-Reply-To: <1556552948-24957-1-git-send-email-diana.craciun@nxp.com>

commit 039daac5526932ec731e4499613018d263af8b3e upstream.

Fixed the following build warning:
powerpc-linux-gnu-ld: warning: orphan section `__btb_flush_fixup' from
`arch/powerpc/kernel/head_44x.o' being placed in section
`__btb_flush_fixup'.

Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/kernel/head_booke.h | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index 384bb4d80520..7b98c7351f6c 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -31,6 +31,16 @@
  */
 #define THREAD_NORMSAVE(offset)	(THREAD_NORMSAVES + (offset * 4))
 
+#ifdef CONFIG_PPC_FSL_BOOK3E
+#define BOOKE_CLEAR_BTB(reg)									\
+START_BTB_FLUSH_SECTION								\
+	BTB_FLUSH(reg)									\
+END_BTB_FLUSH_SECTION
+#else
+#define BOOKE_CLEAR_BTB(reg)
+#endif
+
+
 #define NORMAL_EXCEPTION_PROLOG(intno)						     \
 	mtspr	SPRN_SPRG_WSCRATCH0, r10;	/* save one register */	     \
 	mfspr	r10, SPRN_SPRG_THREAD;					     \
@@ -42,9 +52,7 @@
 	andi.	r11, r11, MSR_PR;	/* check whether user or kernel    */\
 	mr	r11, r1;						     \
 	beq	1f;							     \
-START_BTB_FLUSH_SECTION					\
-	BTB_FLUSH(r11)						\
-END_BTB_FLUSH_SECTION					\
+	BOOKE_CLEAR_BTB(r11)						\
 	/* if from user, start at top of this thread's kernel stack */       \
 	lwz	r11, THREAD_INFO-THREAD(r10);				     \
 	ALLOC_STACK_FRAME(r11, THREAD_SIZE);				     \
@@ -130,9 +138,7 @@ END_BTB_FLUSH_SECTION					\
 	stw	r9,_CCR(r8);		/* save CR on stack		   */\
 	mfspr	r11,exc_level_srr1;	/* check whether user or kernel    */\
 	DO_KVM	BOOKE_INTERRUPT_##intno exc_level_srr1;		             \
-START_BTB_FLUSH_SECTION								\
-	BTB_FLUSH(r10)									\
-END_BTB_FLUSH_SECTION								\
+	BOOKE_CLEAR_BTB(r10)						\
 	andi.	r11,r11,MSR_PR;						     \
 	mfspr	r11,SPRN_SPRG_THREAD;	/* if from user, start at top of   */\
 	lwz	r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
-- 
2.17.1


^ permalink raw reply related

* [PATCH stable v4.4 3/8] powerpc/fsl: Emulate SPRN_BUCSR register
From: Diana Craciun @ 2019-04-29 15:49 UTC (permalink / raw)
  To: stable, gregkh; +Cc: Diana Craciun, linuxppc-dev
In-Reply-To: <1556552948-24957-1-git-send-email-diana.craciun@nxp.com>

commit 98518c4d8728656db349f875fcbbc7c126d4c973 upstream.

In order to flush the branch predictor the guest kernel performs
writes to the BUCSR register which is hypervisor privilleged. However,
the branch predictor is flushed at each KVM entry, so the branch
predictor has been already flushed, so just return as soon as possible
to guest.

Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
[mpe: Tweak comment formatting]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/kvm/e500_emulate.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index 990db69a1d0b..fa88f641ac03 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -277,6 +277,13 @@ int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_va
 		vcpu->arch.pwrmgtcr0 = spr_val;
 		break;
 
+	case SPRN_BUCSR:
+		/*
+		 * If we are here, it means that we have already flushed the
+		 * branch predictor, so just return to guest.
+		 */
+		break;
+
 	/* extra exceptions */
 #ifdef CONFIG_SPE_POSSIBLE
 	case SPRN_IVOR32:
-- 
2.17.1


^ permalink raw reply related

* [PATCH stable v4.4 2/8] powerpc/fsl: Flush branch predictor when entering KVM
From: Diana Craciun @ 2019-04-29 15:49 UTC (permalink / raw)
  To: stable, gregkh; +Cc: Diana Craciun, linuxppc-dev
In-Reply-To: <1556552948-24957-1-git-send-email-diana.craciun@nxp.com>

commit e7aa61f47b23afbec41031bc47ca8d6cb6516abc upstream.

Switching from the guest to host is another place
where the speculative accesses can be exploited.
Flush the branch predictor when entering KVM.

Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/kvm/bookehv_interrupts.S | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/powerpc/kvm/bookehv_interrupts.S b/arch/powerpc/kvm/bookehv_interrupts.S
index 81bd8a07aa51..612b7f6a887f 100644
--- a/arch/powerpc/kvm/bookehv_interrupts.S
+++ b/arch/powerpc/kvm/bookehv_interrupts.S
@@ -75,6 +75,10 @@
 	PPC_LL	r1, VCPU_HOST_STACK(r4)
 	PPC_LL	r2, HOST_R2(r1)
 
+START_BTB_FLUSH_SECTION
+	BTB_FLUSH(r10)
+END_BTB_FLUSH_SECTION
+
 	mfspr	r10, SPRN_PID
 	lwz	r8, VCPU_HOST_PID(r4)
 	PPC_LL	r11, VCPU_SHARED(r4)
-- 
2.17.1


^ permalink raw reply related

* [PATCH stable v4.4 5/8] powerpc/fsl: Sanitize the syscall table for NXP PowerPC 32 bit platforms
From: Diana Craciun @ 2019-04-29 15:49 UTC (permalink / raw)
  To: stable, gregkh; +Cc: Diana Craciun, linuxppc-dev
In-Reply-To: <1556552948-24957-1-git-send-email-diana.craciun@nxp.com>

commit c28218d4abbf4f2035495334d8bfcba64bda4787 upstream.

Used barrier_nospec to sanitize the syscall table.

Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/kernel/entry_32.S | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 3728e617e17e..609bc7d01f13 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -33,6 +33,7 @@
 #include <asm/unistd.h>
 #include <asm/ftrace.h>
 #include <asm/ptrace.h>
+#include <asm/barrier.h>
 
 /*
  * MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE.
@@ -340,6 +341,15 @@ syscall_dotrace_cont:
 	ori	r10,r10,sys_call_table@l
 	slwi	r0,r0,2
 	bge-	66f
+
+	barrier_nospec_asm
+	/*
+	 * Prevent the load of the handler below (based on the user-passed
+	 * system call number) being speculatively executed until the test
+	 * against NR_syscalls and branch to .66f above has
+	 * committed.
+	 */
+
 	lwzx	r10,r10,r0	/* Fetch system call handler [ptr] */
 	mtlr	r10
 	addi	r9,r1,STACK_FRAME_OVERHEAD
-- 
2.17.1


^ permalink raw reply related

* [PATCH stable v4.4 8/8] Documentation: Add nospectre_v1 parameter
From: Diana Craciun @ 2019-04-29 15:49 UTC (permalink / raw)
  To: stable, gregkh; +Cc: Diana Craciun, linuxppc-dev
In-Reply-To: <1556552948-24957-1-git-send-email-diana.craciun@nxp.com>

Currently only supported on powerpc.

Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 Documentation/kernel-parameters.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index f0bdf78420a0..3ff87d5d6fea 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2449,6 +2449,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			legacy floating-point registers on task switch.
 
 	nohugeiomap	[KNL,x86] Disable kernel huge I/O mappings.
+	
+	nospectre_v1	[PPC] Disable mitigations for Spectre Variant 1 (bounds
+			check bypass). With this option data leaks are possible
+			in the system.
 
 	nospectre_v2	[X86,PPC_FSL_BOOK3E] Disable all mitigations for the Spectre variant 2
 			(indirect branch prediction) vulnerability. System may
-- 
2.17.1


^ permalink raw reply related

* Re: [PATCH 23/41] drivers: tty: serial: cpm_uart: fix styling issues
From: Christophe Leroy @ 2019-04-29 15:56 UTC (permalink / raw)
  To: Enrico Weigelt, metux IT consult, linux-kernel
  Cc: lorenzo.pieralisi, linux-ia64, macro, andrew, gregkh,
	slemieux.tyco, liviu.dudau, linux-mips, vz, linux, matthias.bgg,
	khilman, linux-serial, sudeep.holla, sparclinux, jacmet,
	linux-amlogic, andriy.shevchenko, linuxppc-dev, davem
In-Reply-To: <1556369542-13247-24-git-send-email-info@metux.net>



Le 27/04/2019 à 14:52, Enrico Weigelt, metux IT consult a écrit :
> Fix checkpatch errors:

What the main purpose of this change ?

If we apply this, any fix to stable will be a nightmare to backport. Is 
it really worth it ?

Anyway, a couple of comments in the patch below

[...]

> 
> 
> Signed-off-by: Enrico Weigelt <info@metux.net>
> ---
>   drivers/tty/serial/cpm_uart/cpm_uart.h      | 10 +--
>   drivers/tty/serial/cpm_uart/cpm_uart_core.c | 95 ++++++++++++++++-------------
>   drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h |  4 +-
>   drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c |  6 +-
>   4 files changed, 64 insertions(+), 51 deletions(-)

[...]

> 
> @@ -1048,9 +1058,10 @@ static void cpm_uart_early_write(struct uart_cpm_port *pinfo,
>   static int poll_wait_key(char *obuf, struct uart_cpm_port *pinfo)
>   {
>   	u_char		c, *cp;
> -	volatile cbd_t	*bdp;
>   	int		i;
>   
> +	volatile cbd_t	*bdp;
> +

This was likely a false positive from checkpatch. The formatting was 
good, and now it is wrong as it adds an unnecessary blank line.

>   	/* Get the address of the host memory buffer.
>   	 */
>   	bdp = pinfo->rx_cur;

[...]

> diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c
> index a0fccda..154ac19 100644
> --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c
> +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c
> @@ -117,8 +117,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
>   	if (is_con) {
>   		mem_addr = kzalloc(memsz, GFP_NOWAIT);
>   		dma_addr = virt_to_bus(mem_addr);
> -	}
> -	else
> +	} else
>   		mem_addr = dma_alloc_coherent(pinfo->port.dev, memsz, &dma_addr,
>   					      GFP_KERNEL);

Checkpatch should have told you that in case first leg has braces, 
second leg must have braces too even if it's a single line.

Christophe


>   
> @@ -148,7 +147,8 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
>   	dma_free_coherent(pinfo->port.dev, L1_CACHE_ALIGN(pinfo->rx_nrfifos *
>   							  pinfo->rx_fifosize) +
>   			  L1_CACHE_ALIGN(pinfo->tx_nrfifos *
> -					 pinfo->tx_fifosize), (void __force *)pinfo->mem_addr,
> +					 pinfo->tx_fifosize),
> +			  (void __force *)pinfo->mem_addr,
>   			  pinfo->dma_addr);
>   
>   	cpm_dpfree(pinfo->dp_addr);
> 

^ permalink raw reply

* [PATCH stable v4.4 4/8] powerpc/fsl: Flush the branch predictor at each kernel entry (32 bit)
From: Diana Craciun @ 2019-04-29 15:49 UTC (permalink / raw)
  To: stable, gregkh; +Cc: Diana Craciun, linuxppc-dev
In-Reply-To: <1556552948-24957-1-git-send-email-diana.craciun@nxp.com>

commit 7fef436295bf6c05effe682c8797dfcb0deb112a upstream.

In order to protect against speculation attacks on
indirect branches, the branch predictor is flushed at
kernel entry to protect for the following situations:
- userspace process attacking another userspace process
- userspace process attacking the kernel
Basically when the privillege level change (i.e.the kernel
is entered), the branch predictor state is flushed.

Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/kernel/head_booke.h     |  6 ++++++
 arch/powerpc/kernel/head_fsl_booke.S | 15 +++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index a620203f7de3..384bb4d80520 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -42,6 +42,9 @@
 	andi.	r11, r11, MSR_PR;	/* check whether user or kernel    */\
 	mr	r11, r1;						     \
 	beq	1f;							     \
+START_BTB_FLUSH_SECTION					\
+	BTB_FLUSH(r11)						\
+END_BTB_FLUSH_SECTION					\
 	/* if from user, start at top of this thread's kernel stack */       \
 	lwz	r11, THREAD_INFO-THREAD(r10);				     \
 	ALLOC_STACK_FRAME(r11, THREAD_SIZE);				     \
@@ -127,6 +130,9 @@
 	stw	r9,_CCR(r8);		/* save CR on stack		   */\
 	mfspr	r11,exc_level_srr1;	/* check whether user or kernel    */\
 	DO_KVM	BOOKE_INTERRUPT_##intno exc_level_srr1;		             \
+START_BTB_FLUSH_SECTION								\
+	BTB_FLUSH(r10)									\
+END_BTB_FLUSH_SECTION								\
 	andi.	r11,r11,MSR_PR;						     \
 	mfspr	r11,SPRN_SPRG_THREAD;	/* if from user, start at top of   */\
 	lwz	r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index fffd1f96bb1d..275769b6fb0d 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -451,6 +451,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
 	mfcr	r13
 	stw	r13, THREAD_NORMSAVE(3)(r10)
 	DO_KVM	BOOKE_INTERRUPT_DTLB_MISS SPRN_SRR1
+START_BTB_FLUSH_SECTION
+	mfspr r11, SPRN_SRR1
+	andi. r10,r11,MSR_PR
+	beq 1f
+	BTB_FLUSH(r10)
+1:
+END_BTB_FLUSH_SECTION
 	mfspr	r10, SPRN_DEAR		/* Get faulting address */
 
 	/* If we are faulting a kernel address, we have to use the
@@ -545,6 +552,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
 	mfcr	r13
 	stw	r13, THREAD_NORMSAVE(3)(r10)
 	DO_KVM	BOOKE_INTERRUPT_ITLB_MISS SPRN_SRR1
+START_BTB_FLUSH_SECTION
+	mfspr r11, SPRN_SRR1
+	andi. r10,r11,MSR_PR
+	beq 1f
+	BTB_FLUSH(r10)
+1:
+END_BTB_FLUSH_SECTION
+
 	mfspr	r10, SPRN_SRR0		/* Get faulting address */
 
 	/* If we are faulting a kernel address, we have to use the
-- 
2.17.1


^ permalink raw reply related

* [PATCH stable v4.4 7/8] powerpc/fsl: Add FSL_PPC_BOOK3E as supported arch for nospectre_v2 boot arg
From: Diana Craciun @ 2019-04-29 15:49 UTC (permalink / raw)
  To: stable, gregkh; +Cc: Diana Craciun, linuxppc-dev
In-Reply-To: <1556552948-24957-1-git-send-email-diana.craciun@nxp.com>

commit f633a8ad636efb5d4bba1a047d4a0f1ef719aa06 upstream.

Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 Documentation/kernel-parameters.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index da515c535e62..f0bdf78420a0 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2450,7 +2450,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
 	nohugeiomap	[KNL,x86] Disable kernel huge I/O mappings.
 
-	nospectre_v2	[X86] Disable all mitigations for the Spectre variant 2
+	nospectre_v2	[X86,PPC_FSL_BOOK3E] Disable all mitigations for the Spectre variant 2
 			(indirect branch prediction) vulnerability. System may
 			allow data leaks with this option, which is equivalent
 			to spectre_v2=off.
-- 
2.17.1


^ permalink raw reply related

* [PATCH stable v4.4 1/8] powerpc/fsl: Enable runtime patching if nospectre_v2 boot arg is used
From: Diana Craciun @ 2019-04-29 15:49 UTC (permalink / raw)
  To: stable, gregkh; +Cc: Diana Craciun, linuxppc-dev
In-Reply-To: <1556552948-24957-1-git-send-email-diana.craciun@nxp.com>

commit 3bc8ea8603ae4c1e09aca8de229ad38b8091fcb3 upstream.

If the user choses not to use the mitigations, replace
the code sequence with nops.

Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/kernel/setup_32.c | 1 +
 arch/powerpc/kernel/setup_64.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 5a9f035bcd6b..cb37f27bb928 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -323,6 +323,7 @@ void __init setup_arch(char **cmdline_p)
 	if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
 
 	setup_barrier_nospec();
+	setup_spectre_v2();
 
 	paging_init();
 
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 6bb731ababc6..11590f6cb2f9 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -737,6 +737,7 @@ void __init setup_arch(char **cmdline_p)
 		ppc_md.setup_arch();
 
 	setup_barrier_nospec();
+	setup_spectre_v2();
 
 	paging_init();
 
-- 
2.17.1


^ permalink raw reply related

* [PATCH stable v4.4 0/8] missing powerpc spectre backports for 4.4
From: Diana Craciun @ 2019-04-29 15:49 UTC (permalink / raw)
  To: stable, gregkh; +Cc: Diana Craciun, linuxppc-dev

Hi Greg,

These are missing patches from the initial powerpc spectre backports for 4.4.
Please queue them as well if you don't have any objections.

Thanks,

Diana Craciun (8):
  powerpc/fsl: Enable runtime patching if nospectre_v2 boot arg is used
  powerpc/fsl: Flush branch predictor when entering KVM
  powerpc/fsl: Emulate SPRN_BUCSR register
  powerpc/fsl: Flush the branch predictor at each kernel entry (32 bit)
  powerpc/fsl: Sanitize the syscall table for NXP PowerPC 32 bit
    platforms
  powerpc/fsl: Fixed warning: orphan section `__btb_flush_fixup'
  powerpc/fsl: Add FSL_PPC_BOOK3E as supported arch for nospectre_v2
    boot arg
  Documentation: Add nospectre_v1 parameter

 Documentation/kernel-parameters.txt   |  6 +++++-
 arch/powerpc/kernel/entry_32.S        | 10 ++++++++++
 arch/powerpc/kernel/head_booke.h      | 12 ++++++++++++
 arch/powerpc/kernel/head_fsl_booke.S  | 15 +++++++++++++++
 arch/powerpc/kernel/setup_32.c        |  1 +
 arch/powerpc/kernel/setup_64.c        |  1 +
 arch/powerpc/kvm/bookehv_interrupts.S |  4 ++++
 arch/powerpc/kvm/e500_emulate.c       |  7 +++++++
 8 files changed, 55 insertions(+), 1 deletion(-)

-- 
2.17.1


^ permalink raw reply

* Re: [PATCH stable v4.4 00/52] powerpc spectre backports for 4.4
From: Diana Madalina Craciun @ 2019-04-29 15:52 UTC (permalink / raw)
  To: Michael Ellerman, stable@vger.kernel.org,
	gregkh@linuxfoundation.org
  Cc: linuxppc-dev@ozlabs.org, msuchanek@suse.de, npiggin@gmail.com
In-Reply-To: <87lfzuabxr.fsf@concordia.ellerman.id.au>

On 4/28/2019 9:19 AM, Michael Ellerman wrote:
> Diana Madalina Craciun <diana.craciun@nxp.com> writes:
>> Hi Michael,
>>
>> There are some missing NXP Spectre v2 patches. I can send them
>> separately if the series will be accepted. I have merged them, but I did
>> not test them, I was sick today and incapable of doing that.
> No worries, there's no rush :)
>
> Sorry I missed them, I thought I had a list that included everything.
> Which commits was it I missed?
>
> I guess post them as a reply to this thread? That way whether the series
> is merged by Greg or not, there's a record here of what the backports
> look like.

I have sent them as a separate series, but mentioning them here as well:

Diana Craciun (8):
  powerpc/fsl: Enable runtime patching if nospectre_v2 boot arg is used
  powerpc/fsl: Flush branch predictor when entering KVM
  powerpc/fsl: Emulate SPRN_BUCSR register
  powerpc/fsl: Flush the branch predictor at each kernel entry (32 bit)
  powerpc/fsl: Sanitize the syscall table for NXP PowerPC 32 bit
    platforms
  powerpc/fsl: Fixed warning: orphan section `__btb_flush_fixup'
  powerpc/fsl: Add FSL_PPC_BOOK3E as supported arch for nospectre_v2
    boot arg
  Documentation: Add nospectre_v1 parameter

regards

> cheers
>
>> On 4/21/2019 5:21 PM, Michael Ellerman wrote:
>>> -----BEGIN PGP SIGNED MESSAGE-----
>>> Hash: SHA1
>>>
>>> Hi Greg/Sasha,
>>>
>>> Please queue up these powerpc patches for 4.4 if you have no objections.
>>>
>>> cheers
>>>
>>>
>>> Christophe Leroy (1):
>>>   powerpc/fsl: Fix the flush of branch predictor.
>>>
>>> Diana Craciun (10):
>>>   powerpc/64: Disable the speculation barrier from the command line
>>>   powerpc/64: Make stf barrier PPC_BOOK3S_64 specific.
>>>   powerpc/64: Make meltdown reporting Book3S 64 specific
>>>   powerpc/fsl: Add barrier_nospec implementation for NXP PowerPC Book3E
>>>   powerpc/fsl: Add infrastructure to fixup branch predictor flush
>>>   powerpc/fsl: Add macro to flush the branch predictor
>>>   powerpc/fsl: Fix spectre_v2 mitigations reporting
>>>   powerpc/fsl: Add nospectre_v2 command line argument
>>>   powerpc/fsl: Flush the branch predictor at each kernel entry (64bit)
>>>   powerpc/fsl: Update Spectre v2 reporting
>>>
>>> Mauricio Faria de Oliveira (4):
>>>   powerpc/rfi-flush: Differentiate enabled and patched flush types
>>>   powerpc/pseries: Fix clearing of security feature flags
>>>   powerpc: Move default security feature flags
>>>   powerpc/pseries: Restore default security feature flags on setup
>>>
>>> Michael Ellerman (29):
>>>   powerpc/xmon: Add RFI flush related fields to paca dump
>>>   powerpc/pseries: Support firmware disable of RFI flush
>>>   powerpc/powernv: Support firmware disable of RFI flush
>>>   powerpc/rfi-flush: Move the logic to avoid a redo into the debugfs
>>>     code
>>>   powerpc/rfi-flush: Make it possible to call setup_rfi_flush() again
>>>   powerpc/rfi-flush: Always enable fallback flush on pseries
>>>   powerpc/pseries: Add new H_GET_CPU_CHARACTERISTICS flags
>>>   powerpc/rfi-flush: Call setup_rfi_flush() after LPM migration
>>>   powerpc: Add security feature flags for Spectre/Meltdown
>>>   powerpc/pseries: Set or clear security feature flags
>>>   powerpc/powernv: Set or clear security feature flags
>>>   powerpc/64s: Move cpu_show_meltdown()
>>>   powerpc/64s: Enhance the information in cpu_show_meltdown()
>>>   powerpc/powernv: Use the security flags in pnv_setup_rfi_flush()
>>>   powerpc/pseries: Use the security flags in pseries_setup_rfi_flush()
>>>   powerpc/64s: Wire up cpu_show_spectre_v1()
>>>   powerpc/64s: Wire up cpu_show_spectre_v2()
>>>   powerpc/64s: Fix section mismatch warnings from setup_rfi_flush()
>>>   powerpc/64: Use barrier_nospec in syscall entry
>>>   powerpc: Use barrier_nospec in copy_from_user()
>>>   powerpc64s: Show ori31 availability in spectre_v1 sysfs file not v2
>>>   powerpc/64: Add CONFIG_PPC_BARRIER_NOSPEC
>>>   powerpc/64: Call setup_barrier_nospec() from setup_arch()
>>>   powerpc/asm: Add a patch_site macro & helpers for patching
>>>     instructions
>>>   powerpc/64s: Add new security feature flags for count cache flush
>>>   powerpc/64s: Add support for software count cache flush
>>>   powerpc/pseries: Query hypervisor for count cache flush settings
>>>   powerpc/powernv: Query firmware for count cache flush settings
>>>   powerpc/security: Fix spectre_v2 reporting
>>>
>>> Michael Neuling (1):
>>>   powerpc: Avoid code patching freed init sections
>>>
>>> Michal Suchanek (5):
>>>   powerpc/64s: Add barrier_nospec
>>>   powerpc/64s: Add support for ori barrier_nospec patching
>>>   powerpc/64s: Patch barrier_nospec in modules
>>>   powerpc/64s: Enable barrier_nospec based on firmware settings
>>>   powerpc/64s: Enhance the information in cpu_show_spectre_v1()
>>>
>>> Nicholas Piggin (2):
>>>   powerpc/64s: Improve RFI L1-D cache flush fallback
>>>   powerpc/64s: Add support for a store forwarding barrier at kernel
>>>     entry/exit
>>>
>>>  arch/powerpc/Kconfig                         |   7 +-
>>>  arch/powerpc/include/asm/asm-prototypes.h    |  21 +
>>>  arch/powerpc/include/asm/barrier.h           |  21 +
>>>  arch/powerpc/include/asm/code-patching-asm.h |  18 +
>>>  arch/powerpc/include/asm/code-patching.h     |   2 +
>>>  arch/powerpc/include/asm/exception-64s.h     |  35 ++
>>>  arch/powerpc/include/asm/feature-fixups.h    |  40 ++
>>>  arch/powerpc/include/asm/hvcall.h            |   5 +
>>>  arch/powerpc/include/asm/paca.h              |   3 +-
>>>  arch/powerpc/include/asm/ppc-opcode.h        |   1 +
>>>  arch/powerpc/include/asm/ppc_asm.h           |  11 +
>>>  arch/powerpc/include/asm/security_features.h |  92 ++++
>>>  arch/powerpc/include/asm/setup.h             |  23 +-
>>>  arch/powerpc/include/asm/uaccess.h           |  18 +-
>>>  arch/powerpc/kernel/Makefile                 |   1 +
>>>  arch/powerpc/kernel/asm-offsets.c            |   3 +-
>>>  arch/powerpc/kernel/entry_64.S               |  69 +++
>>>  arch/powerpc/kernel/exceptions-64e.S         |  27 +-
>>>  arch/powerpc/kernel/exceptions-64s.S         |  98 +++--
>>>  arch/powerpc/kernel/module.c                 |  10 +-
>>>  arch/powerpc/kernel/security.c               | 433 +++++++++++++++++++
>>>  arch/powerpc/kernel/setup_32.c               |   2 +
>>>  arch/powerpc/kernel/setup_64.c               |  50 +--
>>>  arch/powerpc/kernel/vmlinux.lds.S            |  33 +-
>>>  arch/powerpc/lib/code-patching.c             |  29 ++
>>>  arch/powerpc/lib/feature-fixups.c            | 218 +++++++++-
>>>  arch/powerpc/mm/mem.c                        |   2 +
>>>  arch/powerpc/mm/tlb_low_64e.S                |   7 +
>>>  arch/powerpc/platforms/powernv/setup.c       |  99 +++--
>>>  arch/powerpc/platforms/pseries/mobility.c    |   3 +
>>>  arch/powerpc/platforms/pseries/pseries.h     |   2 +
>>>  arch/powerpc/platforms/pseries/setup.c       |  88 +++-
>>>  arch/powerpc/xmon/xmon.c                     |   2 +
>>>  33 files changed, 1345 insertions(+), 128 deletions(-)
>>>  create mode 100644 arch/powerpc/include/asm/asm-prototypes.h
>>>  create mode 100644 arch/powerpc/include/asm/code-patching-asm.h
>>>  create mode 100644 arch/powerpc/include/asm/security_features.h
>>>  create mode 100644 arch/powerpc/kernel/security.c
>>>
>>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>>> index 58a1fa979655..01b6c00a7060 100644
>>> - --- a/arch/powerpc/Kconfig
>>> +++ b/arch/powerpc/Kconfig
>>> @@ -136,7 +136,7 @@ config PPC
>>>  	select GENERIC_SMP_IDLE_THREAD
>>>  	select GENERIC_CMOS_UPDATE
>>>  	select GENERIC_TIME_VSYSCALL_OLD
>>> - -	select GENERIC_CPU_VULNERABILITIES	if PPC_BOOK3S_64
>>> +	select GENERIC_CPU_VULNERABILITIES	if PPC_BARRIER_NOSPEC
>>>  	select GENERIC_CLOCKEVENTS
>>>  	select GENERIC_CLOCKEVENTS_BROADCAST if SMP
>>>  	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
>>> @@ -162,6 +162,11 @@ config PPC
>>>  	select ARCH_HAS_DMA_SET_COHERENT_MASK
>>>  	select HAVE_ARCH_SECCOMP_FILTER
>>>  
>>> +config PPC_BARRIER_NOSPEC
>>> +    bool
>>> +    default y
>>> +    depends on PPC_BOOK3S_64 || PPC_FSL_BOOK3E
>>> +
>>>  config GENERIC_CSUM
>>>  	def_bool CPU_LITTLE_ENDIAN
>>>  
>>> diff --git a/arch/powerpc/include/asm/asm-prototypes.h b/arch/powerpc/include/asm/asm-prototypes.h
>>> new file mode 100644
>>> index 000000000000..8944c55591cf
>>> - --- /dev/null
>>> +++ b/arch/powerpc/include/asm/asm-prototypes.h
>>> @@ -0,0 +1,21 @@
>>> +#ifndef _ASM_POWERPC_ASM_PROTOTYPES_H
>>> +#define _ASM_POWERPC_ASM_PROTOTYPES_H
>>> +/*
>>> + * This file is for prototypes of C functions that are only called
>>> + * from asm, and any associated variables.
>>> + *
>>> + * Copyright 2016, Daniel Axtens, IBM Corporation.
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU General Public License
>>> + * as published by the Free Software Foundation; either version 2
>>> + * of the License, or (at your option) any later version.
>>> + */
>>> +
>>> +/* Patch sites */
>>> +extern s32 patch__call_flush_count_cache;
>>> +extern s32 patch__flush_count_cache_return;
>>> +
>>> +extern long flush_count_cache;
>>> +
>>> +#endif /* _ASM_POWERPC_ASM_PROTOTYPES_H */
>>> diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h
>>> index b9e16855a037..e7cb72cdb2ba 100644
>>> - --- a/arch/powerpc/include/asm/barrier.h
>>> +++ b/arch/powerpc/include/asm/barrier.h
>>> @@ -92,4 +92,25 @@ do {									\
>>>  #define smp_mb__after_atomic()      smp_mb()
>>>  #define smp_mb__before_spinlock()   smp_mb()
>>>  
>>> +#ifdef CONFIG_PPC_BOOK3S_64
>>> +#define NOSPEC_BARRIER_SLOT   nop
>>> +#elif defined(CONFIG_PPC_FSL_BOOK3E)
>>> +#define NOSPEC_BARRIER_SLOT   nop; nop
>>> +#endif
>>> +
>>> +#ifdef CONFIG_PPC_BARRIER_NOSPEC
>>> +/*
>>> + * Prevent execution of subsequent instructions until preceding branches have
>>> + * been fully resolved and are no longer executing speculatively.
>>> + */
>>> +#define barrier_nospec_asm NOSPEC_BARRIER_FIXUP_SECTION; NOSPEC_BARRIER_SLOT
>>> +
>>> +// This also acts as a compiler barrier due to the memory clobber.
>>> +#define barrier_nospec() asm (stringify_in_c(barrier_nospec_asm) ::: "memory")
>>> +
>>> +#else /* !CONFIG_PPC_BARRIER_NOSPEC */
>>> +#define barrier_nospec_asm
>>> +#define barrier_nospec()
>>> +#endif /* CONFIG_PPC_BARRIER_NOSPEC */
>>> +
>>>  #endif /* _ASM_POWERPC_BARRIER_H */
>>> diff --git a/arch/powerpc/include/asm/code-patching-asm.h b/arch/powerpc/include/asm/code-patching-asm.h
>>> new file mode 100644
>>> index 000000000000..ed7b1448493a
>>> - --- /dev/null
>>> +++ b/arch/powerpc/include/asm/code-patching-asm.h
>>> @@ -0,0 +1,18 @@
>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>> +/*
>>> + * Copyright 2018, Michael Ellerman, IBM Corporation.
>>> + */
>>> +#ifndef _ASM_POWERPC_CODE_PATCHING_ASM_H
>>> +#define _ASM_POWERPC_CODE_PATCHING_ASM_H
>>> +
>>> +/* Define a "site" that can be patched */
>>> +.macro patch_site label name
>>> +	.pushsection ".rodata"
>>> +	.balign 4
>>> +	.global \name
>>> +\name:
>>> +	.4byte	\label - .
>>> +	.popsection
>>> +.endm
>>> +
>>> +#endif /* _ASM_POWERPC_CODE_PATCHING_ASM_H */
>>> diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
>>> index 840a5509b3f1..a734b4b34d26 100644
>>> - --- a/arch/powerpc/include/asm/code-patching.h
>>> +++ b/arch/powerpc/include/asm/code-patching.h
>>> @@ -28,6 +28,8 @@ unsigned int create_cond_branch(const unsigned int *addr,
>>>  				unsigned long target, int flags);
>>>  int patch_branch(unsigned int *addr, unsigned long target, int flags);
>>>  int patch_instruction(unsigned int *addr, unsigned int instr);
>>> +int patch_instruction_site(s32 *addr, unsigned int instr);
>>> +int patch_branch_site(s32 *site, unsigned long target, int flags);
>>>  
>>>  int instr_is_relative_branch(unsigned int instr);
>>>  int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr);
>>> diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
>>> index 9bddbec441b8..3ed536bec462 100644
>>> - --- a/arch/powerpc/include/asm/exception-64s.h
>>> +++ b/arch/powerpc/include/asm/exception-64s.h
>>> @@ -50,6 +50,27 @@
>>>  #define EX_PPR		88	/* SMT thread status register (priority) */
>>>  #define EX_CTR		96
>>>  
>>> +#define STF_ENTRY_BARRIER_SLOT						\
>>> +	STF_ENTRY_BARRIER_FIXUP_SECTION;				\
>>> +	nop;								\
>>> +	nop;								\
>>> +	nop
>>> +
>>> +#define STF_EXIT_BARRIER_SLOT						\
>>> +	STF_EXIT_BARRIER_FIXUP_SECTION;					\
>>> +	nop;								\
>>> +	nop;								\
>>> +	nop;								\
>>> +	nop;								\
>>> +	nop;								\
>>> +	nop
>>> +
>>> +/*
>>> + * r10 must be free to use, r13 must be paca
>>> + */
>>> +#define INTERRUPT_TO_KERNEL						\
>>> +	STF_ENTRY_BARRIER_SLOT
>>> +
>>>  /*
>>>   * Macros for annotating the expected destination of (h)rfid
>>>   *
>>> @@ -66,16 +87,19 @@
>>>  	rfid
>>>  
>>>  #define RFI_TO_USER							\
>>> +	STF_EXIT_BARRIER_SLOT;						\
>>>  	RFI_FLUSH_SLOT;							\
>>>  	rfid;								\
>>>  	b	rfi_flush_fallback
>>>  
>>>  #define RFI_TO_USER_OR_KERNEL						\
>>> +	STF_EXIT_BARRIER_SLOT;						\
>>>  	RFI_FLUSH_SLOT;							\
>>>  	rfid;								\
>>>  	b	rfi_flush_fallback
>>>  
>>>  #define RFI_TO_GUEST							\
>>> +	STF_EXIT_BARRIER_SLOT;						\
>>>  	RFI_FLUSH_SLOT;							\
>>>  	rfid;								\
>>>  	b	rfi_flush_fallback
>>> @@ -84,21 +108,25 @@
>>>  	hrfid
>>>  
>>>  #define HRFI_TO_USER							\
>>> +	STF_EXIT_BARRIER_SLOT;						\
>>>  	RFI_FLUSH_SLOT;							\
>>>  	hrfid;								\
>>>  	b	hrfi_flush_fallback
>>>  
>>>  #define HRFI_TO_USER_OR_KERNEL						\
>>> +	STF_EXIT_BARRIER_SLOT;						\
>>>  	RFI_FLUSH_SLOT;							\
>>>  	hrfid;								\
>>>  	b	hrfi_flush_fallback
>>>  
>>>  #define HRFI_TO_GUEST							\
>>> +	STF_EXIT_BARRIER_SLOT;						\
>>>  	RFI_FLUSH_SLOT;							\
>>>  	hrfid;								\
>>>  	b	hrfi_flush_fallback
>>>  
>>>  #define HRFI_TO_UNKNOWN							\
>>> +	STF_EXIT_BARRIER_SLOT;						\
>>>  	RFI_FLUSH_SLOT;							\
>>>  	hrfid;								\
>>>  	b	hrfi_flush_fallback
>>> @@ -226,6 +254,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
>>>  #define __EXCEPTION_PROLOG_1(area, extra, vec)				\
>>>  	OPT_SAVE_REG_TO_PACA(area+EX_PPR, r9, CPU_FTR_HAS_PPR);		\
>>>  	OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR);		\
>>> +	INTERRUPT_TO_KERNEL;						\
>>>  	SAVE_CTR(r10, area);						\
>>>  	mfcr	r9;							\
>>>  	extra(vec);							\
>>> @@ -512,6 +541,12 @@ label##_relon_hv:						\
>>>  #define _MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra)		\
>>>  	__MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra)
>>>  
>>> +#define MASKABLE_EXCEPTION_OOL(vec, label)				\
>>> +	.globl label##_ool;						\
>>> +label##_ool:								\
>>> +	EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_PR, vec);		\
>>> +	EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_STD);
>>> +
>>>  #define MASKABLE_EXCEPTION_PSERIES(loc, vec, label)			\
>>>  	. = loc;							\
>>>  	.globl label##_pSeries;						\
>>> diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h
>>> index 7068bafbb2d6..145a37ab2d3e 100644
>>> - --- a/arch/powerpc/include/asm/feature-fixups.h
>>> +++ b/arch/powerpc/include/asm/feature-fixups.h
>>> @@ -184,6 +184,22 @@ label##3:					       	\
>>>  	FTR_ENTRY_OFFSET label##1b-label##3b;		\
>>>  	.popsection;
>>>  
>>> +#define STF_ENTRY_BARRIER_FIXUP_SECTION			\
>>> +953:							\
>>> +	.pushsection __stf_entry_barrier_fixup,"a";	\
>>> +	.align 2;					\
>>> +954:							\
>>> +	FTR_ENTRY_OFFSET 953b-954b;			\
>>> +	.popsection;
>>> +
>>> +#define STF_EXIT_BARRIER_FIXUP_SECTION			\
>>> +955:							\
>>> +	.pushsection __stf_exit_barrier_fixup,"a";	\
>>> +	.align 2;					\
>>> +956:							\
>>> +	FTR_ENTRY_OFFSET 955b-956b;			\
>>> +	.popsection;
>>> +
>>>  #define RFI_FLUSH_FIXUP_SECTION				\
>>>  951:							\
>>>  	.pushsection __rfi_flush_fixup,"a";		\
>>> @@ -192,10 +208,34 @@ label##3:					       	\
>>>  	FTR_ENTRY_OFFSET 951b-952b;			\
>>>  	.popsection;
>>>  
>>> +#define NOSPEC_BARRIER_FIXUP_SECTION			\
>>> +953:							\
>>> +	.pushsection __barrier_nospec_fixup,"a";	\
>>> +	.align 2;					\
>>> +954:							\
>>> +	FTR_ENTRY_OFFSET 953b-954b;			\
>>> +	.popsection;
>>> +
>>> +#define START_BTB_FLUSH_SECTION			\
>>> +955:							\
>>> +
>>> +#define END_BTB_FLUSH_SECTION			\
>>> +956:							\
>>> +	.pushsection __btb_flush_fixup,"a";	\
>>> +	.align 2;							\
>>> +957:						\
>>> +	FTR_ENTRY_OFFSET 955b-957b;			\
>>> +	FTR_ENTRY_OFFSET 956b-957b;			\
>>> +	.popsection;
>>>  
>>>  #ifndef __ASSEMBLY__
>>>  
>>> +extern long stf_barrier_fallback;
>>> +extern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup;
>>> +extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup;
>>>  extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
>>> +extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup;
>>> +extern long __start__btb_flush_fixup, __stop__btb_flush_fixup;
>>>  
>>>  #endif
>>>  
>>> diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
>>> index 449bbb87c257..b57db9d09db9 100644
>>> - --- a/arch/powerpc/include/asm/hvcall.h
>>> +++ b/arch/powerpc/include/asm/hvcall.h
>>> @@ -292,10 +292,15 @@
>>>  #define H_CPU_CHAR_L1D_FLUSH_ORI30	(1ull << 61) // IBM bit 2
>>>  #define H_CPU_CHAR_L1D_FLUSH_TRIG2	(1ull << 60) // IBM bit 3
>>>  #define H_CPU_CHAR_L1D_THREAD_PRIV	(1ull << 59) // IBM bit 4
>>> +#define H_CPU_CHAR_BRANCH_HINTS_HONORED	(1ull << 58) // IBM bit 5
>>> +#define H_CPU_CHAR_THREAD_RECONFIG_CTRL	(1ull << 57) // IBM bit 6
>>> +#define H_CPU_CHAR_COUNT_CACHE_DISABLED	(1ull << 56) // IBM bit 7
>>> +#define H_CPU_CHAR_BCCTR_FLUSH_ASSIST	(1ull << 54) // IBM bit 9
>>>  
>>>  #define H_CPU_BEHAV_FAVOUR_SECURITY	(1ull << 63) // IBM bit 0
>>>  #define H_CPU_BEHAV_L1D_FLUSH_PR	(1ull << 62) // IBM bit 1
>>>  #define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR	(1ull << 61) // IBM bit 2
>>> +#define H_CPU_BEHAV_FLUSH_COUNT_CACHE	(1ull << 58) // IBM bit 5
>>>  
>>>  #ifndef __ASSEMBLY__
>>>  #include <linux/types.h>
>>> diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
>>> index 45e2aefece16..08e5df3395fa 100644
>>> - --- a/arch/powerpc/include/asm/paca.h
>>> +++ b/arch/powerpc/include/asm/paca.h
>>> @@ -199,8 +199,7 @@ struct paca_struct {
>>>  	 */
>>>  	u64 exrfi[13] __aligned(0x80);
>>>  	void *rfi_flush_fallback_area;
>>> - -	u64 l1d_flush_congruence;
>>> - -	u64 l1d_flush_sets;
>>> +	u64 l1d_flush_size;
>>>  #endif
>>>  };
>>>  
>>> diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
>>> index 7ab04fc59e24..faf1bb045dee 100644
>>> - --- a/arch/powerpc/include/asm/ppc-opcode.h
>>> +++ b/arch/powerpc/include/asm/ppc-opcode.h
>>> @@ -147,6 +147,7 @@
>>>  #define PPC_INST_LWSYNC			0x7c2004ac
>>>  #define PPC_INST_SYNC			0x7c0004ac
>>>  #define PPC_INST_SYNC_MASK		0xfc0007fe
>>> +#define PPC_INST_ISYNC			0x4c00012c
>>>  #define PPC_INST_LXVD2X			0x7c000698
>>>  #define PPC_INST_MCRXR			0x7c000400
>>>  #define PPC_INST_MCRXR_MASK		0xfc0007fe
>>> diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
>>> index 160bb2311bbb..d219816b3e19 100644
>>> - --- a/arch/powerpc/include/asm/ppc_asm.h
>>> +++ b/arch/powerpc/include/asm/ppc_asm.h
>>> @@ -821,4 +821,15 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,945)
>>>  	.long 0x2400004c  /* rfid				*/
>>>  #endif /* !CONFIG_PPC_BOOK3E */
>>>  #endif /*  __ASSEMBLY__ */
>>> +
>>> +#ifdef CONFIG_PPC_FSL_BOOK3E
>>> +#define BTB_FLUSH(reg)			\
>>> +	lis reg,BUCSR_INIT@h;		\
>>> +	ori reg,reg,BUCSR_INIT@l;	\
>>> +	mtspr SPRN_BUCSR,reg;		\
>>> +	isync;
>>> +#else
>>> +#define BTB_FLUSH(reg)
>>> +#endif /* CONFIG_PPC_FSL_BOOK3E */
>>> +
>>>  #endif /* _ASM_POWERPC_PPC_ASM_H */
>>> diff --git a/arch/powerpc/include/asm/security_features.h b/arch/powerpc/include/asm/security_features.h
>>> new file mode 100644
>>> index 000000000000..759597bf0fd8
>>> - --- /dev/null
>>> +++ b/arch/powerpc/include/asm/security_features.h
>>> @@ -0,0 +1,92 @@
>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>> +/*
>>> + * Security related feature bit definitions.
>>> + *
>>> + * Copyright 2018, Michael Ellerman, IBM Corporation.
>>> + */
>>> +
>>> +#ifndef _ASM_POWERPC_SECURITY_FEATURES_H
>>> +#define _ASM_POWERPC_SECURITY_FEATURES_H
>>> +
>>> +
>>> +extern unsigned long powerpc_security_features;
>>> +extern bool rfi_flush;
>>> +
>>> +/* These are bit flags */
>>> +enum stf_barrier_type {
>>> +	STF_BARRIER_NONE	= 0x1,
>>> +	STF_BARRIER_FALLBACK	= 0x2,
>>> +	STF_BARRIER_EIEIO	= 0x4,
>>> +	STF_BARRIER_SYNC_ORI	= 0x8,
>>> +};
>>> +
>>> +void setup_stf_barrier(void);
>>> +void do_stf_barrier_fixups(enum stf_barrier_type types);
>>> +void setup_count_cache_flush(void);
>>> +
>>> +static inline void security_ftr_set(unsigned long feature)
>>> +{
>>> +	powerpc_security_features |= feature;
>>> +}
>>> +
>>> +static inline void security_ftr_clear(unsigned long feature)
>>> +{
>>> +	powerpc_security_features &= ~feature;
>>> +}
>>> +
>>> +static inline bool security_ftr_enabled(unsigned long feature)
>>> +{
>>> +	return !!(powerpc_security_features & feature);
>>> +}
>>> +
>>> +
>>> +// Features indicating support for Spectre/Meltdown mitigations
>>> +
>>> +// The L1-D cache can be flushed with ori r30,r30,0
>>> +#define SEC_FTR_L1D_FLUSH_ORI30		0x0000000000000001ull
>>> +
>>> +// The L1-D cache can be flushed with mtspr 882,r0 (aka SPRN_TRIG2)
>>> +#define SEC_FTR_L1D_FLUSH_TRIG2		0x0000000000000002ull
>>> +
>>> +// ori r31,r31,0 acts as a speculation barrier
>>> +#define SEC_FTR_SPEC_BAR_ORI31		0x0000000000000004ull
>>> +
>>> +// Speculation past bctr is disabled
>>> +#define SEC_FTR_BCCTRL_SERIALISED	0x0000000000000008ull
>>> +
>>> +// Entries in L1-D are private to a SMT thread
>>> +#define SEC_FTR_L1D_THREAD_PRIV		0x0000000000000010ull
>>> +
>>> +// Indirect branch prediction cache disabled
>>> +#define SEC_FTR_COUNT_CACHE_DISABLED	0x0000000000000020ull
>>> +
>>> +// bcctr 2,0,0 triggers a hardware assisted count cache flush
>>> +#define SEC_FTR_BCCTR_FLUSH_ASSIST	0x0000000000000800ull
>>> +
>>> +
>>> +// Features indicating need for Spectre/Meltdown mitigations
>>> +
>>> +// The L1-D cache should be flushed on MSR[HV] 1->0 transition (hypervisor to guest)
>>> +#define SEC_FTR_L1D_FLUSH_HV		0x0000000000000040ull
>>> +
>>> +// The L1-D cache should be flushed on MSR[PR] 0->1 transition (kernel to userspace)
>>> +#define SEC_FTR_L1D_FLUSH_PR		0x0000000000000080ull
>>> +
>>> +// A speculation barrier should be used for bounds checks (Spectre variant 1)
>>> +#define SEC_FTR_BNDS_CHK_SPEC_BAR	0x0000000000000100ull
>>> +
>>> +// Firmware configuration indicates user favours security over performance
>>> +#define SEC_FTR_FAVOUR_SECURITY		0x0000000000000200ull
>>> +
>>> +// Software required to flush count cache on context switch
>>> +#define SEC_FTR_FLUSH_COUNT_CACHE	0x0000000000000400ull
>>> +
>>> +
>>> +// Features enabled by default
>>> +#define SEC_FTR_DEFAULT \
>>> +	(SEC_FTR_L1D_FLUSH_HV | \
>>> +	 SEC_FTR_L1D_FLUSH_PR | \
>>> +	 SEC_FTR_BNDS_CHK_SPEC_BAR | \
>>> +	 SEC_FTR_FAVOUR_SECURITY)
>>> +
>>> +#endif /* _ASM_POWERPC_SECURITY_FEATURES_H */
>>> diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
>>> index 7916b56f2e60..d299479c770b 100644
>>> - --- a/arch/powerpc/include/asm/setup.h
>>> +++ b/arch/powerpc/include/asm/setup.h
>>> @@ -8,6 +8,7 @@ extern void ppc_printk_progress(char *s, unsigned short hex);
>>>  
>>>  extern unsigned int rtas_data;
>>>  extern unsigned long long memory_limit;
>>> +extern bool init_mem_is_free;
>>>  extern unsigned long klimit;
>>>  extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
>>>  
>>> @@ -36,8 +37,28 @@ enum l1d_flush_type {
>>>  	L1D_FLUSH_MTTRIG	= 0x8,
>>>  };
>>>  
>>> - -void __init setup_rfi_flush(enum l1d_flush_type, bool enable);
>>> +void setup_rfi_flush(enum l1d_flush_type, bool enable);
>>>  void do_rfi_flush_fixups(enum l1d_flush_type types);
>>> +#ifdef CONFIG_PPC_BARRIER_NOSPEC
>>> +void setup_barrier_nospec(void);
>>> +#else
>>> +static inline void setup_barrier_nospec(void) { };
>>> +#endif
>>> +void do_barrier_nospec_fixups(bool enable);
>>> +extern bool barrier_nospec_enabled;
>>> +
>>> +#ifdef CONFIG_PPC_BARRIER_NOSPEC
>>> +void do_barrier_nospec_fixups_range(bool enable, void *start, void *end);
>>> +#else
>>> +static inline void do_barrier_nospec_fixups_range(bool enable, void *start, void *end) { };
>>> +#endif
>>> +
>>> +#ifdef CONFIG_PPC_FSL_BOOK3E
>>> +void setup_spectre_v2(void);
>>> +#else
>>> +static inline void setup_spectre_v2(void) {};
>>> +#endif
>>> +void do_btb_flush_fixups(void);
>>>  
>>>  #endif /* !__ASSEMBLY__ */
>>>  
>>> diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
>>> index 05f1389228d2..e51ce5a0e221 100644
>>> - --- a/arch/powerpc/include/asm/uaccess.h
>>> +++ b/arch/powerpc/include/asm/uaccess.h
>>> @@ -269,6 +269,7 @@ do {								\
>>>  	__chk_user_ptr(ptr);					\
>>>  	if (!is_kernel_addr((unsigned long)__gu_addr))		\
>>>  		might_fault();					\
>>> +	barrier_nospec();					\
>>>  	__get_user_size(__gu_val, __gu_addr, (size), __gu_err);	\
>>>  	(x) = (__typeof__(*(ptr)))__gu_val;			\
>>>  	__gu_err;						\
>>> @@ -283,6 +284,7 @@ do {								\
>>>  	__chk_user_ptr(ptr);					\
>>>  	if (!is_kernel_addr((unsigned long)__gu_addr))		\
>>>  		might_fault();					\
>>> +	barrier_nospec();					\
>>>  	__get_user_size(__gu_val, __gu_addr, (size), __gu_err);	\
>>>  	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
>>>  	__gu_err;						\
>>> @@ -295,8 +297,10 @@ do {								\
>>>  	unsigned long  __gu_val = 0;					\
>>>  	__typeof__(*(ptr)) __user *__gu_addr = (ptr);		\
>>>  	might_fault();							\
>>> - -	if (access_ok(VERIFY_READ, __gu_addr, (size)))			\
>>> +	if (access_ok(VERIFY_READ, __gu_addr, (size))) {		\
>>> +		barrier_nospec();					\
>>>  		__get_user_size(__gu_val, __gu_addr, (size), __gu_err);	\
>>> +	}								\
>>>  	(x) = (__force __typeof__(*(ptr)))__gu_val;				\
>>>  	__gu_err;							\
>>>  })
>>> @@ -307,6 +311,7 @@ do {								\
>>>  	unsigned long __gu_val;					\
>>>  	__typeof__(*(ptr)) __user *__gu_addr = (ptr);	\
>>>  	__chk_user_ptr(ptr);					\
>>> +	barrier_nospec();					\
>>>  	__get_user_size(__gu_val, __gu_addr, (size), __gu_err);	\
>>>  	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
>>>  	__gu_err;						\
>>> @@ -323,8 +328,10 @@ extern unsigned long __copy_tofrom_user(void __user *to,
>>>  static inline unsigned long copy_from_user(void *to,
>>>  		const void __user *from, unsigned long n)
>>>  {
>>> - -	if (likely(access_ok(VERIFY_READ, from, n)))
>>> +	if (likely(access_ok(VERIFY_READ, from, n))) {
>>> +		barrier_nospec();
>>>  		return __copy_tofrom_user((__force void __user *)to, from, n);
>>> +	}
>>>  	memset(to, 0, n);
>>>  	return n;
>>>  }
>>> @@ -359,21 +366,27 @@ static inline unsigned long __copy_from_user_inatomic(void *to,
>>>  
>>>  		switch (n) {
>>>  		case 1:
>>> +			barrier_nospec();
>>>  			__get_user_size(*(u8 *)to, from, 1, ret);
>>>  			break;
>>>  		case 2:
>>> +			barrier_nospec();
>>>  			__get_user_size(*(u16 *)to, from, 2, ret);
>>>  			break;
>>>  		case 4:
>>> +			barrier_nospec();
>>>  			__get_user_size(*(u32 *)to, from, 4, ret);
>>>  			break;
>>>  		case 8:
>>> +			barrier_nospec();
>>>  			__get_user_size(*(u64 *)to, from, 8, ret);
>>>  			break;
>>>  		}
>>>  		if (ret == 0)
>>>  			return 0;
>>>  	}
>>> +
>>> +	barrier_nospec();
>>>  	return __copy_tofrom_user((__force void __user *)to, from, n);
>>>  }
>>>  
>>> @@ -400,6 +413,7 @@ static inline unsigned long __copy_to_user_inatomic(void __user *to,
>>>  		if (ret == 0)
>>>  			return 0;
>>>  	}
>>> +
>>>  	return __copy_tofrom_user(to, (__force const void __user *)from, n);
>>>  }
>>>  
>>> diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
>>> index ba336930d448..22ed3c32fca8 100644
>>> - --- a/arch/powerpc/kernel/Makefile
>>> +++ b/arch/powerpc/kernel/Makefile
>>> @@ -44,6 +44,7 @@ obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_power.o
>>>  obj-$(CONFIG_PPC_BOOK3S_64)	+= mce.o mce_power.o
>>>  obj64-$(CONFIG_RELOCATABLE)	+= reloc_64.o
>>>  obj-$(CONFIG_PPC_BOOK3E_64)	+= exceptions-64e.o idle_book3e.o
>>> +obj-$(CONFIG_PPC_BARRIER_NOSPEC) += security.o
>>>  obj-$(CONFIG_PPC64)		+= vdso64/
>>>  obj-$(CONFIG_ALTIVEC)		+= vecemu.o
>>>  obj-$(CONFIG_PPC_970_NAP)	+= idle_power4.o
>>> diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
>>> index d92705e3a0c1..de3c29c51503 100644
>>> - --- a/arch/powerpc/kernel/asm-offsets.c
>>> +++ b/arch/powerpc/kernel/asm-offsets.c
>>> @@ -245,8 +245,7 @@ int main(void)
>>>  	DEFINE(PACA_IN_MCE, offsetof(struct paca_struct, in_mce));
>>>  	DEFINE(PACA_RFI_FLUSH_FALLBACK_AREA, offsetof(struct paca_struct, rfi_flush_fallback_area));
>>>  	DEFINE(PACA_EXRFI, offsetof(struct paca_struct, exrfi));
>>> - -	DEFINE(PACA_L1D_FLUSH_CONGRUENCE, offsetof(struct paca_struct, l1d_flush_congruence));
>>> - -	DEFINE(PACA_L1D_FLUSH_SETS, offsetof(struct paca_struct, l1d_flush_sets));
>>> +	DEFINE(PACA_L1D_FLUSH_SIZE, offsetof(struct paca_struct, l1d_flush_size));
>>>  #endif
>>>  	DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
>>>  	DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state));
>>> diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
>>> index 59be96917369..6d36a4fb4acf 100644
>>> - --- a/arch/powerpc/kernel/entry_64.S
>>> +++ b/arch/powerpc/kernel/entry_64.S
>>> @@ -25,6 +25,7 @@
>>>  #include <asm/page.h>
>>>  #include <asm/mmu.h>
>>>  #include <asm/thread_info.h>
>>> +#include <asm/code-patching-asm.h>
>>>  #include <asm/ppc_asm.h>
>>>  #include <asm/asm-offsets.h>
>>>  #include <asm/cputable.h>
>>> @@ -36,6 +37,7 @@
>>>  #include <asm/hw_irq.h>
>>>  #include <asm/context_tracking.h>
>>>  #include <asm/tm.h>
>>> +#include <asm/barrier.h>
>>>  #ifdef CONFIG_PPC_BOOK3S
>>>  #include <asm/exception-64s.h>
>>>  #else
>>> @@ -75,6 +77,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
>>>  	std	r0,GPR0(r1)
>>>  	std	r10,GPR1(r1)
>>>  	beq	2f			/* if from kernel mode */
>>> +#ifdef CONFIG_PPC_FSL_BOOK3E
>>> +START_BTB_FLUSH_SECTION
>>> +	BTB_FLUSH(r10)
>>> +END_BTB_FLUSH_SECTION
>>> +#endif
>>>  	ACCOUNT_CPU_USER_ENTRY(r10, r11)
>>>  2:	std	r2,GPR2(r1)
>>>  	std	r3,GPR3(r1)
>>> @@ -177,6 +184,15 @@ system_call:			/* label this so stack traces look sane */
>>>  	clrldi	r8,r8,32
>>>  15:
>>>  	slwi	r0,r0,4
>>> +
>>> +	barrier_nospec_asm
>>> +	/*
>>> +	 * Prevent the load of the handler below (based on the user-passed
>>> +	 * system call number) being speculatively executed until the test
>>> +	 * against NR_syscalls and branch to .Lsyscall_enosys above has
>>> +	 * committed.
>>> +	 */
>>> +
>>>  	ldx	r12,r11,r0	/* Fetch system call handler [ptr] */
>>>  	mtctr   r12
>>>  	bctrl			/* Call handler */
>>> @@ -440,6 +456,57 @@ _GLOBAL(ret_from_kernel_thread)
>>>  	li	r3,0
>>>  	b	.Lsyscall_exit
>>>  
>>> +#ifdef CONFIG_PPC_BOOK3S_64
>>> +
>>> +#define FLUSH_COUNT_CACHE	\
>>> +1:	nop;			\
>>> +	patch_site 1b, patch__call_flush_count_cache
>>> +
>>> +
>>> +#define BCCTR_FLUSH	.long 0x4c400420
>>> +
>>> +.macro nops number
>>> +	.rept \number
>>> +	nop
>>> +	.endr
>>> +.endm
>>> +
>>> +.balign 32
>>> +.global flush_count_cache
>>> +flush_count_cache:
>>> +	/* Save LR into r9 */
>>> +	mflr	r9
>>> +
>>> +	.rept 64
>>> +	bl	.+4
>>> +	.endr
>>> +	b	1f
>>> +	nops	6
>>> +
>>> +	.balign 32
>>> +	/* Restore LR */
>>> +1:	mtlr	r9
>>> +	li	r9,0x7fff
>>> +	mtctr	r9
>>> +
>>> +	BCCTR_FLUSH
>>> +
>>> +2:	nop
>>> +	patch_site 2b patch__flush_count_cache_return
>>> +
>>> +	nops	3
>>> +
>>> +	.rept 278
>>> +	.balign 32
>>> +	BCCTR_FLUSH
>>> +	nops	7
>>> +	.endr
>>> +
>>> +	blr
>>> +#else
>>> +#define FLUSH_COUNT_CACHE
>>> +#endif /* CONFIG_PPC_BOOK3S_64 */
>>> +
>>>  /*
>>>   * This routine switches between two different tasks.  The process
>>>   * state of one is saved on its kernel stack.  Then the state
>>> @@ -503,6 +570,8 @@ BEGIN_FTR_SECTION
>>>  END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
>>>  #endif
>>>  
>>> +	FLUSH_COUNT_CACHE
>>> +
>>>  #ifdef CONFIG_SMP
>>>  	/* We need a sync somewhere here to make sure that if the
>>>  	 * previous task gets rescheduled on another CPU, it sees all
>>> diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
>>> index 5cc93f0b52ca..48ec841ea1bf 100644
>>> - --- a/arch/powerpc/kernel/exceptions-64e.S
>>> +++ b/arch/powerpc/kernel/exceptions-64e.S
>>> @@ -295,7 +295,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
>>>  	andi.	r10,r11,MSR_PR;		/* save stack pointer */	    \
>>>  	beq	1f;			/* branch around if supervisor */   \
>>>  	ld	r1,PACAKSAVE(r13);	/* get kernel stack coming from usr */\
>>> - -1:	cmpdi	cr1,r1,0;		/* check if SP makes sense */	    \
>>> +1:	type##_BTB_FLUSH		\
>>> +	cmpdi	cr1,r1,0;		/* check if SP makes sense */	    \
>>>  	bge-	cr1,exc_##n##_bad_stack;/* bad stack (TODO: out of line) */ \
>>>  	mfspr	r10,SPRN_##type##_SRR0;	/* read SRR0 before touching stack */
>>>  
>>> @@ -327,6 +328,30 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
>>>  #define SPRN_MC_SRR0	SPRN_MCSRR0
>>>  #define SPRN_MC_SRR1	SPRN_MCSRR1
>>>  
>>> +#ifdef CONFIG_PPC_FSL_BOOK3E
>>> +#define GEN_BTB_FLUSH			\
>>> +	START_BTB_FLUSH_SECTION		\
>>> +		beq 1f;			\
>>> +		BTB_FLUSH(r10)			\
>>> +		1:		\
>>> +	END_BTB_FLUSH_SECTION
>>> +
>>> +#define CRIT_BTB_FLUSH			\
>>> +	START_BTB_FLUSH_SECTION		\
>>> +		BTB_FLUSH(r10)		\
>>> +	END_BTB_FLUSH_SECTION
>>> +
>>> +#define DBG_BTB_FLUSH CRIT_BTB_FLUSH
>>> +#define MC_BTB_FLUSH CRIT_BTB_FLUSH
>>> +#define GDBELL_BTB_FLUSH GEN_BTB_FLUSH
>>> +#else
>>> +#define GEN_BTB_FLUSH
>>> +#define CRIT_BTB_FLUSH
>>> +#define DBG_BTB_FLUSH
>>> +#define MC_BTB_FLUSH
>>> +#define GDBELL_BTB_FLUSH
>>> +#endif
>>> +
>>>  #define NORMAL_EXCEPTION_PROLOG(n, intnum, addition)			    \
>>>  	EXCEPTION_PROLOG(n, intnum, GEN, addition##_GEN(n))
>>>  
>>> diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
>>> index 938a30fef031..10e7cec9553d 100644
>>> - --- a/arch/powerpc/kernel/exceptions-64s.S
>>> +++ b/arch/powerpc/kernel/exceptions-64s.S
>>> @@ -36,6 +36,7 @@ BEGIN_FTR_SECTION						\
>>>  END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)				\
>>>  	mr	r9,r13 ;					\
>>>  	GET_PACA(r13) ;						\
>>> +	INTERRUPT_TO_KERNEL ;					\
>>>  	mfspr	r11,SPRN_SRR0 ;					\
>>>  0:
>>>  
>>> @@ -292,7 +293,9 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
>>>  	. = 0x900
>>>  	.globl decrementer_pSeries
>>>  decrementer_pSeries:
>>> - -	_MASKABLE_EXCEPTION_PSERIES(0x900, decrementer, EXC_STD, SOFTEN_TEST_PR)
>>> +	SET_SCRATCH0(r13)
>>> +	EXCEPTION_PROLOG_0(PACA_EXGEN)
>>> +	b	decrementer_ool
>>>  
>>>  	STD_EXCEPTION_HV(0x980, 0x982, hdecrementer)
>>>  
>>> @@ -319,6 +322,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
>>>  	OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR);
>>>  	HMT_MEDIUM;
>>>  	std	r10,PACA_EXGEN+EX_R10(r13)
>>> +	INTERRUPT_TO_KERNEL
>>>  	OPT_SAVE_REG_TO_PACA(PACA_EXGEN+EX_PPR, r9, CPU_FTR_HAS_PPR);
>>>  	mfcr	r9
>>>  	KVMTEST(0xc00)
>>> @@ -607,6 +611,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
>>>  
>>>  	.align	7
>>>  	/* moved from 0xe00 */
>>> +	MASKABLE_EXCEPTION_OOL(0x900, decrementer)
>>>  	STD_EXCEPTION_HV_OOL(0xe02, h_data_storage)
>>>  	KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0xe02)
>>>  	STD_EXCEPTION_HV_OOL(0xe22, h_instr_storage)
>>> @@ -1564,6 +1569,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
>>>  	blr
>>>  #endif
>>>  
>>> +	.balign 16
>>> +	.globl stf_barrier_fallback
>>> +stf_barrier_fallback:
>>> +	std	r9,PACA_EXRFI+EX_R9(r13)
>>> +	std	r10,PACA_EXRFI+EX_R10(r13)
>>> +	sync
>>> +	ld	r9,PACA_EXRFI+EX_R9(r13)
>>> +	ld	r10,PACA_EXRFI+EX_R10(r13)
>>> +	ori	31,31,0
>>> +	.rept 14
>>> +	b	1f
>>> +1:
>>> +	.endr
>>> +	blr
>>> +
>>>  	.globl rfi_flush_fallback
>>>  rfi_flush_fallback:
>>>  	SET_SCRATCH0(r13);
>>> @@ -1571,39 +1591,37 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
>>>  	std	r9,PACA_EXRFI+EX_R9(r13)
>>>  	std	r10,PACA_EXRFI+EX_R10(r13)
>>>  	std	r11,PACA_EXRFI+EX_R11(r13)
>>> - -	std	r12,PACA_EXRFI+EX_R12(r13)
>>> - -	std	r8,PACA_EXRFI+EX_R13(r13)
>>>  	mfctr	r9
>>>  	ld	r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13)
>>> - -	ld	r11,PACA_L1D_FLUSH_SETS(r13)
>>> - -	ld	r12,PACA_L1D_FLUSH_CONGRUENCE(r13)
>>> - -	/*
>>> - -	 * The load adresses are at staggered offsets within cachelines,
>>> - -	 * which suits some pipelines better (on others it should not
>>> - -	 * hurt).
>>> - -	 */
>>> - -	addi	r12,r12,8
>>> +	ld	r11,PACA_L1D_FLUSH_SIZE(r13)
>>> +	srdi	r11,r11,(7 + 3) /* 128 byte lines, unrolled 8x */
>>>  	mtctr	r11
>>>  	DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */
>>>  
>>>  	/* order ld/st prior to dcbt stop all streams with flushing */
>>>  	sync
>>> - -1:	li	r8,0
>>> - -	.rept	8 /* 8-way set associative */
>>> - -	ldx	r11,r10,r8
>>> - -	add	r8,r8,r12
>>> - -	xor	r11,r11,r11	// Ensure r11 is 0 even if fallback area is not
>>> - -	add	r8,r8,r11	// Add 0, this creates a dependency on the ldx
>>> - -	.endr
>>> - -	addi	r10,r10,128 /* 128 byte cache line */
>>> +
>>> +	/*
>>> +	 * The load adresses are at staggered offsets within cachelines,
>>> +	 * which suits some pipelines better (on others it should not
>>> +	 * hurt).
>>> +	 */
>>> +1:
>>> +	ld	r11,(0x80 + 8)*0(r10)
>>> +	ld	r11,(0x80 + 8)*1(r10)
>>> +	ld	r11,(0x80 + 8)*2(r10)
>>> +	ld	r11,(0x80 + 8)*3(r10)
>>> +	ld	r11,(0x80 + 8)*4(r10)
>>> +	ld	r11,(0x80 + 8)*5(r10)
>>> +	ld	r11,(0x80 + 8)*6(r10)
>>> +	ld	r11,(0x80 + 8)*7(r10)
>>> +	addi	r10,r10,0x80*8
>>>  	bdnz	1b
>>>  
>>>  	mtctr	r9
>>>  	ld	r9,PACA_EXRFI+EX_R9(r13)
>>>  	ld	r10,PACA_EXRFI+EX_R10(r13)
>>>  	ld	r11,PACA_EXRFI+EX_R11(r13)
>>> - -	ld	r12,PACA_EXRFI+EX_R12(r13)
>>> - -	ld	r8,PACA_EXRFI+EX_R13(r13)
>>>  	GET_SCRATCH0(r13);
>>>  	rfid
>>>  
>>> @@ -1614,39 +1632,37 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
>>>  	std	r9,PACA_EXRFI+EX_R9(r13)
>>>  	std	r10,PACA_EXRFI+EX_R10(r13)
>>>  	std	r11,PACA_EXRFI+EX_R11(r13)
>>> - -	std	r12,PACA_EXRFI+EX_R12(r13)
>>> - -	std	r8,PACA_EXRFI+EX_R13(r13)
>>>  	mfctr	r9
>>>  	ld	r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13)
>>> - -	ld	r11,PACA_L1D_FLUSH_SETS(r13)
>>> - -	ld	r12,PACA_L1D_FLUSH_CONGRUENCE(r13)
>>> - -	/*
>>> - -	 * The load adresses are at staggered offsets within cachelines,
>>> - -	 * which suits some pipelines better (on others it should not
>>> - -	 * hurt).
>>> - -	 */
>>> - -	addi	r12,r12,8
>>> +	ld	r11,PACA_L1D_FLUSH_SIZE(r13)
>>> +	srdi	r11,r11,(7 + 3) /* 128 byte lines, unrolled 8x */
>>>  	mtctr	r11
>>>  	DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */
>>>  
>>>  	/* order ld/st prior to dcbt stop all streams with flushing */
>>>  	sync
>>> - -1:	li	r8,0
>>> - -	.rept	8 /* 8-way set associative */
>>> - -	ldx	r11,r10,r8
>>> - -	add	r8,r8,r12
>>> - -	xor	r11,r11,r11	// Ensure r11 is 0 even if fallback area is not
>>> - -	add	r8,r8,r11	// Add 0, this creates a dependency on the ldx
>>> - -	.endr
>>> - -	addi	r10,r10,128 /* 128 byte cache line */
>>> +
>>> +	/*
>>> +	 * The load adresses are at staggered offsets within cachelines,
>>> +	 * which suits some pipelines better (on others it should not
>>> +	 * hurt).
>>> +	 */
>>> +1:
>>> +	ld	r11,(0x80 + 8)*0(r10)
>>> +	ld	r11,(0x80 + 8)*1(r10)
>>> +	ld	r11,(0x80 + 8)*2(r10)
>>> +	ld	r11,(0x80 + 8)*3(r10)
>>> +	ld	r11,(0x80 + 8)*4(r10)
>>> +	ld	r11,(0x80 + 8)*5(r10)
>>> +	ld	r11,(0x80 + 8)*6(r10)
>>> +	ld	r11,(0x80 + 8)*7(r10)
>>> +	addi	r10,r10,0x80*8
>>>  	bdnz	1b
>>>  
>>>  	mtctr	r9
>>>  	ld	r9,PACA_EXRFI+EX_R9(r13)
>>>  	ld	r10,PACA_EXRFI+EX_R10(r13)
>>>  	ld	r11,PACA_EXRFI+EX_R11(r13)
>>> - -	ld	r12,PACA_EXRFI+EX_R12(r13)
>>> - -	ld	r8,PACA_EXRFI+EX_R13(r13)
>>>  	GET_SCRATCH0(r13);
>>>  	hrfid
>>>  
>>> diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
>>> index 9547381b631a..ff009be97a42 100644
>>> - --- a/arch/powerpc/kernel/module.c
>>> +++ b/arch/powerpc/kernel/module.c
>>> @@ -67,7 +67,15 @@ int module_finalize(const Elf_Ehdr *hdr,
>>>  		do_feature_fixups(powerpc_firmware_features,
>>>  				  (void *)sect->sh_addr,
>>>  				  (void *)sect->sh_addr + sect->sh_size);
>>> - -#endif
>>> +#endif /* CONFIG_PPC64 */
>>> +
>>> +#ifdef CONFIG_PPC_BARRIER_NOSPEC
>>> +	sect = find_section(hdr, sechdrs, "__spec_barrier_fixup");
>>> +	if (sect != NULL)
>>> +		do_barrier_nospec_fixups_range(barrier_nospec_enabled,
>>> +				  (void *)sect->sh_addr,
>>> +				  (void *)sect->sh_addr + sect->sh_size);
>>> +#endif /* CONFIG_PPC_BARRIER_NOSPEC */
>>>  
>>>  	sect = find_section(hdr, sechdrs, "__lwsync_fixup");
>>>  	if (sect != NULL)
>>> diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c
>>> new file mode 100644
>>> index 000000000000..58f0602a92b9
>>> - --- /dev/null
>>> +++ b/arch/powerpc/kernel/security.c
>>> @@ -0,0 +1,433 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +//
>>> +// Security related flags and so on.
>>> +//
>>> +// Copyright 2018, Michael Ellerman, IBM Corporation.
>>> +
>>> +#include <linux/kernel.h>
>>> +#include <linux/debugfs.h>
>>> +#include <linux/device.h>
>>> +#include <linux/seq_buf.h>
>>> +
>>> +#include <asm/debug.h>
>>> +#include <asm/asm-prototypes.h>
>>> +#include <asm/code-patching.h>
>>> +#include <asm/security_features.h>
>>> +#include <asm/setup.h>
>>> +
>>> +
>>> +unsigned long powerpc_security_features __read_mostly = SEC_FTR_DEFAULT;
>>> +
>>> +enum count_cache_flush_type {
>>> +	COUNT_CACHE_FLUSH_NONE	= 0x1,
>>> +	COUNT_CACHE_FLUSH_SW	= 0x2,
>>> +	COUNT_CACHE_FLUSH_HW	= 0x4,
>>> +};
>>> +static enum count_cache_flush_type count_cache_flush_type = COUNT_CACHE_FLUSH_NONE;
>>> +
>>> +bool barrier_nospec_enabled;
>>> +static bool no_nospec;
>>> +static bool btb_flush_enabled;
>>> +#ifdef CONFIG_PPC_FSL_BOOK3E
>>> +static bool no_spectrev2;
>>> +#endif
>>> +
>>> +static void enable_barrier_nospec(bool enable)
>>> +{
>>> +	barrier_nospec_enabled = enable;
>>> +	do_barrier_nospec_fixups(enable);
>>> +}
>>> +
>>> +void setup_barrier_nospec(void)
>>> +{
>>> +	bool enable;
>>> +
>>> +	/*
>>> +	 * It would make sense to check SEC_FTR_SPEC_BAR_ORI31 below as well.
>>> +	 * But there's a good reason not to. The two flags we check below are
>>> +	 * both are enabled by default in the kernel, so if the hcall is not
>>> +	 * functional they will be enabled.
>>> +	 * On a system where the host firmware has been updated (so the ori
>>> +	 * functions as a barrier), but on which the hypervisor (KVM/Qemu) has
>>> +	 * not been updated, we would like to enable the barrier. Dropping the
>>> +	 * check for SEC_FTR_SPEC_BAR_ORI31 achieves that. The only downside is
>>> +	 * we potentially enable the barrier on systems where the host firmware
>>> +	 * is not updated, but that's harmless as it's a no-op.
>>> +	 */
>>> +	enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) &&
>>> +		 security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR);
>>> +
>>> +	if (!no_nospec)
>>> +		enable_barrier_nospec(enable);
>>> +}
>>> +
>>> +static int __init handle_nospectre_v1(char *p)
>>> +{
>>> +	no_nospec = true;
>>> +
>>> +	return 0;
>>> +}
>>> +early_param("nospectre_v1", handle_nospectre_v1);
>>> +
>>> +#ifdef CONFIG_DEBUG_FS
>>> +static int barrier_nospec_set(void *data, u64 val)
>>> +{
>>> +	switch (val) {
>>> +	case 0:
>>> +	case 1:
>>> +		break;
>>> +	default:
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	if (!!val == !!barrier_nospec_enabled)
>>> +		return 0;
>>> +
>>> +	enable_barrier_nospec(!!val);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int barrier_nospec_get(void *data, u64 *val)
>>> +{
>>> +	*val = barrier_nospec_enabled ? 1 : 0;
>>> +	return 0;
>>> +}
>>> +
>>> +DEFINE_SIMPLE_ATTRIBUTE(fops_barrier_nospec,
>>> +			barrier_nospec_get, barrier_nospec_set, "%llu\n");
>>> +
>>> +static __init int barrier_nospec_debugfs_init(void)
>>> +{
>>> +	debugfs_create_file("barrier_nospec", 0600, powerpc_debugfs_root, NULL,
>>> +			    &fops_barrier_nospec);
>>> +	return 0;
>>> +}
>>> +device_initcall(barrier_nospec_debugfs_init);
>>> +#endif /* CONFIG_DEBUG_FS */
>>> +
>>> +#ifdef CONFIG_PPC_FSL_BOOK3E
>>> +static int __init handle_nospectre_v2(char *p)
>>> +{
>>> +	no_spectrev2 = true;
>>> +
>>> +	return 0;
>>> +}
>>> +early_param("nospectre_v2", handle_nospectre_v2);
>>> +void setup_spectre_v2(void)
>>> +{
>>> +	if (no_spectrev2)
>>> +		do_btb_flush_fixups();
>>> +	else
>>> +		btb_flush_enabled = true;
>>> +}
>>> +#endif /* CONFIG_PPC_FSL_BOOK3E */
>>> +
>>> +#ifdef CONFIG_PPC_BOOK3S_64
>>> +ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
>>> +{
>>> +	bool thread_priv;
>>> +
>>> +	thread_priv = security_ftr_enabled(SEC_FTR_L1D_THREAD_PRIV);
>>> +
>>> +	if (rfi_flush || thread_priv) {
>>> +		struct seq_buf s;
>>> +		seq_buf_init(&s, buf, PAGE_SIZE - 1);
>>> +
>>> +		seq_buf_printf(&s, "Mitigation: ");
>>> +
>>> +		if (rfi_flush)
>>> +			seq_buf_printf(&s, "RFI Flush");
>>> +
>>> +		if (rfi_flush && thread_priv)
>>> +			seq_buf_printf(&s, ", ");
>>> +
>>> +		if (thread_priv)
>>> +			seq_buf_printf(&s, "L1D private per thread");
>>> +
>>> +		seq_buf_printf(&s, "\n");
>>> +
>>> +		return s.len;
>>> +	}
>>> +
>>> +	if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
>>> +	    !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR))
>>> +		return sprintf(buf, "Not affected\n");
>>> +
>>> +	return sprintf(buf, "Vulnerable\n");
>>> +}
>>> +#endif
>>> +
>>> +ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf)
>>> +{
>>> +	struct seq_buf s;
>>> +
>>> +	seq_buf_init(&s, buf, PAGE_SIZE - 1);
>>> +
>>> +	if (security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR)) {
>>> +		if (barrier_nospec_enabled)
>>> +			seq_buf_printf(&s, "Mitigation: __user pointer sanitization");
>>> +		else
>>> +			seq_buf_printf(&s, "Vulnerable");
>>> +
>>> +		if (security_ftr_enabled(SEC_FTR_SPEC_BAR_ORI31))
>>> +			seq_buf_printf(&s, ", ori31 speculation barrier enabled");
>>> +
>>> +		seq_buf_printf(&s, "\n");
>>> +	} else
>>> +		seq_buf_printf(&s, "Not affected\n");
>>> +
>>> +	return s.len;
>>> +}
>>> +
>>> +ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf)
>>> +{
>>> +	struct seq_buf s;
>>> +	bool bcs, ccd;
>>> +
>>> +	seq_buf_init(&s, buf, PAGE_SIZE - 1);
>>> +
>>> +	bcs = security_ftr_enabled(SEC_FTR_BCCTRL_SERIALISED);
>>> +	ccd = security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED);
>>> +
>>> +	if (bcs || ccd) {
>>> +		seq_buf_printf(&s, "Mitigation: ");
>>> +
>>> +		if (bcs)
>>> +			seq_buf_printf(&s, "Indirect branch serialisation (kernel only)");
>>> +
>>> +		if (bcs && ccd)
>>> +			seq_buf_printf(&s, ", ");
>>> +
>>> +		if (ccd)
>>> +			seq_buf_printf(&s, "Indirect branch cache disabled");
>>> +	} else if (count_cache_flush_type != COUNT_CACHE_FLUSH_NONE) {
>>> +		seq_buf_printf(&s, "Mitigation: Software count cache flush");
>>> +
>>> +		if (count_cache_flush_type == COUNT_CACHE_FLUSH_HW)
>>> +			seq_buf_printf(&s, " (hardware accelerated)");
>>> +	} else if (btb_flush_enabled) {
>>> +		seq_buf_printf(&s, "Mitigation: Branch predictor state flush");
>>> +	} else {
>>> +		seq_buf_printf(&s, "Vulnerable");
>>> +	}
>>> +
>>> +	seq_buf_printf(&s, "\n");
>>> +
>>> +	return s.len;
>>> +}
>>> +
>>> +#ifdef CONFIG_PPC_BOOK3S_64
>>> +/*
>>> + * Store-forwarding barrier support.
>>> + */
>>> +
>>> +static enum stf_barrier_type stf_enabled_flush_types;
>>> +static bool no_stf_barrier;
>>> +bool stf_barrier;
>>> +
>>> +static int __init handle_no_stf_barrier(char *p)
>>> +{
>>> +	pr_info("stf-barrier: disabled on command line.");
>>> +	no_stf_barrier = true;
>>> +	return 0;
>>> +}
>>> +
>>> +early_param("no_stf_barrier", handle_no_stf_barrier);
>>> +
>>> +/* This is the generic flag used by other architectures */
>>> +static int __init handle_ssbd(char *p)
>>> +{
>>> +	if (!p || strncmp(p, "auto", 5) == 0 || strncmp(p, "on", 2) == 0 ) {
>>> +		/* Until firmware tells us, we have the barrier with auto */
>>> +		return 0;
>>> +	} else if (strncmp(p, "off", 3) == 0) {
>>> +		handle_no_stf_barrier(NULL);
>>> +		return 0;
>>> +	} else
>>> +		return 1;
>>> +
>>> +	return 0;
>>> +}
>>> +early_param("spec_store_bypass_disable", handle_ssbd);
>>> +
>>> +/* This is the generic flag used by other architectures */
>>> +static int __init handle_no_ssbd(char *p)
>>> +{
>>> +	handle_no_stf_barrier(NULL);
>>> +	return 0;
>>> +}
>>> +early_param("nospec_store_bypass_disable", handle_no_ssbd);
>>> +
>>> +static void stf_barrier_enable(bool enable)
>>> +{
>>> +	if (enable)
>>> +		do_stf_barrier_fixups(stf_enabled_flush_types);
>>> +	else
>>> +		do_stf_barrier_fixups(STF_BARRIER_NONE);
>>> +
>>> +	stf_barrier = enable;
>>> +}
>>> +
>>> +void setup_stf_barrier(void)
>>> +{
>>> +	enum stf_barrier_type type;
>>> +	bool enable, hv;
>>> +
>>> +	hv = cpu_has_feature(CPU_FTR_HVMODE);
>>> +
>>> +	/* Default to fallback in case fw-features are not available */
>>> +	if (cpu_has_feature(CPU_FTR_ARCH_207S))
>>> +		type = STF_BARRIER_SYNC_ORI;
>>> +	else if (cpu_has_feature(CPU_FTR_ARCH_206))
>>> +		type = STF_BARRIER_FALLBACK;
>>> +	else
>>> +		type = STF_BARRIER_NONE;
>>> +
>>> +	enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) &&
>>> +		(security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR) ||
>>> +		 (security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) && hv));
>>> +
>>> +	if (type == STF_BARRIER_FALLBACK) {
>>> +		pr_info("stf-barrier: fallback barrier available\n");
>>> +	} else if (type == STF_BARRIER_SYNC_ORI) {
>>> +		pr_info("stf-barrier: hwsync barrier available\n");
>>> +	} else if (type == STF_BARRIER_EIEIO) {
>>> +		pr_info("stf-barrier: eieio barrier available\n");
>>> +	}
>>> +
>>> +	stf_enabled_flush_types = type;
>>> +
>>> +	if (!no_stf_barrier)
>>> +		stf_barrier_enable(enable);
>>> +}
>>> +
>>> +ssize_t cpu_show_spec_store_bypass(struct device *dev, struct device_attribute *attr, char *buf)
>>> +{
>>> +	if (stf_barrier && stf_enabled_flush_types != STF_BARRIER_NONE) {
>>> +		const char *type;
>>> +		switch (stf_enabled_flush_types) {
>>> +		case STF_BARRIER_EIEIO:
>>> +			type = "eieio";
>>> +			break;
>>> +		case STF_BARRIER_SYNC_ORI:
>>> +			type = "hwsync";
>>> +			break;
>>> +		case STF_BARRIER_FALLBACK:
>>> +			type = "fallback";
>>> +			break;
>>> +		default:
>>> +			type = "unknown";
>>> +		}
>>> +		return sprintf(buf, "Mitigation: Kernel entry/exit barrier (%s)\n", type);
>>> +	}
>>> +
>>> +	if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
>>> +	    !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR))
>>> +		return sprintf(buf, "Not affected\n");
>>> +
>>> +	return sprintf(buf, "Vulnerable\n");
>>> +}
>>> +
>>> +#ifdef CONFIG_DEBUG_FS
>>> +static int stf_barrier_set(void *data, u64 val)
>>> +{
>>> +	bool enable;
>>> +
>>> +	if (val == 1)
>>> +		enable = true;
>>> +	else if (val == 0)
>>> +		enable = false;
>>> +	else
>>> +		return -EINVAL;
>>> +
>>> +	/* Only do anything if we're changing state */
>>> +	if (enable != stf_barrier)
>>> +		stf_barrier_enable(enable);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int stf_barrier_get(void *data, u64 *val)
>>> +{
>>> +	*val = stf_barrier ? 1 : 0;
>>> +	return 0;
>>> +}
>>> +
>>> +DEFINE_SIMPLE_ATTRIBUTE(fops_stf_barrier, stf_barrier_get, stf_barrier_set, "%llu\n");
>>> +
>>> +static __init int stf_barrier_debugfs_init(void)
>>> +{
>>> +	debugfs_create_file("stf_barrier", 0600, powerpc_debugfs_root, NULL, &fops_stf_barrier);
>>> +	return 0;
>>> +}
>>> +device_initcall(stf_barrier_debugfs_init);
>>> +#endif /* CONFIG_DEBUG_FS */
>>> +
>>> +static void toggle_count_cache_flush(bool enable)
>>> +{
>>> +	if (!enable || !security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE)) {
>>> +		patch_instruction_site(&patch__call_flush_count_cache, PPC_INST_NOP);
>>> +		count_cache_flush_type = COUNT_CACHE_FLUSH_NONE;
>>> +		pr_info("count-cache-flush: software flush disabled.\n");
>>> +		return;
>>> +	}
>>> +
>>> +	patch_branch_site(&patch__call_flush_count_cache,
>>> +			  (u64)&flush_count_cache, BRANCH_SET_LINK);
>>> +
>>> +	if (!security_ftr_enabled(SEC_FTR_BCCTR_FLUSH_ASSIST)) {
>>> +		count_cache_flush_type = COUNT_CACHE_FLUSH_SW;
>>> +		pr_info("count-cache-flush: full software flush sequence enabled.\n");
>>> +		return;
>>> +	}
>>> +
>>> +	patch_instruction_site(&patch__flush_count_cache_return, PPC_INST_BLR);
>>> +	count_cache_flush_type = COUNT_CACHE_FLUSH_HW;
>>> +	pr_info("count-cache-flush: hardware assisted flush sequence enabled\n");
>>> +}
>>> +
>>> +void setup_count_cache_flush(void)
>>> +{
>>> +	toggle_count_cache_flush(true);
>>> +}
>>> +
>>> +#ifdef CONFIG_DEBUG_FS
>>> +static int count_cache_flush_set(void *data, u64 val)
>>> +{
>>> +	bool enable;
>>> +
>>> +	if (val == 1)
>>> +		enable = true;
>>> +	else if (val == 0)
>>> +		enable = false;
>>> +	else
>>> +		return -EINVAL;
>>> +
>>> +	toggle_count_cache_flush(enable);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int count_cache_flush_get(void *data, u64 *val)
>>> +{
>>> +	if (count_cache_flush_type == COUNT_CACHE_FLUSH_NONE)
>>> +		*val = 0;
>>> +	else
>>> +		*val = 1;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +DEFINE_SIMPLE_ATTRIBUTE(fops_count_cache_flush, count_cache_flush_get,
>>> +			count_cache_flush_set, "%llu\n");
>>> +
>>> +static __init int count_cache_flush_debugfs_init(void)
>>> +{
>>> +	debugfs_create_file("count_cache_flush", 0600, powerpc_debugfs_root,
>>> +			    NULL, &fops_count_cache_flush);
>>> +	return 0;
>>> +}
>>> +device_initcall(count_cache_flush_debugfs_init);
>>> +#endif /* CONFIG_DEBUG_FS */
>>> +#endif /* CONFIG_PPC_BOOK3S_64 */
>>> diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
>>> index ad8c9db61237..5a9f035bcd6b 100644
>>> - --- a/arch/powerpc/kernel/setup_32.c
>>> +++ b/arch/powerpc/kernel/setup_32.c
>>> @@ -322,6 +322,8 @@ void __init setup_arch(char **cmdline_p)
>>>  		ppc_md.setup_arch();
>>>  	if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
>>>  
>>> +	setup_barrier_nospec();
>>> +
>>>  	paging_init();
>>>  
>>>  	/* Initialize the MMU context management stuff */
>>> diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
>>> index 9eb469bed22b..6bb731ababc6 100644
>>> - --- a/arch/powerpc/kernel/setup_64.c
>>> +++ b/arch/powerpc/kernel/setup_64.c
>>> @@ -736,6 +736,8 @@ void __init setup_arch(char **cmdline_p)
>>>  	if (ppc_md.setup_arch)
>>>  		ppc_md.setup_arch();
>>>  
>>> +	setup_barrier_nospec();
>>> +
>>>  	paging_init();
>>>  
>>>  	/* Initialize the MMU context management stuff */
>>> @@ -873,9 +875,6 @@ static void do_nothing(void *unused)
>>>  
>>>  void rfi_flush_enable(bool enable)
>>>  {
>>> - -	if (rfi_flush == enable)
>>> - -		return;
>>> - -
>>>  	if (enable) {
>>>  		do_rfi_flush_fixups(enabled_flush_types);
>>>  		on_each_cpu(do_nothing, NULL, 1);
>>> @@ -885,11 +884,15 @@ void rfi_flush_enable(bool enable)
>>>  	rfi_flush = enable;
>>>  }
>>>  
>>> - -static void init_fallback_flush(void)
>>> +static void __ref init_fallback_flush(void)
>>>  {
>>>  	u64 l1d_size, limit;
>>>  	int cpu;
>>>  
>>> +	/* Only allocate the fallback flush area once (at boot time). */
>>> +	if (l1d_flush_fallback_area)
>>> +		return;
>>> +
>>>  	l1d_size = ppc64_caches.dsize;
>>>  	limit = min(safe_stack_limit(), ppc64_rma_size);
>>>  
>>> @@ -902,34 +905,23 @@ static void init_fallback_flush(void)
>>>  	memset(l1d_flush_fallback_area, 0, l1d_size * 2);
>>>  
>>>  	for_each_possible_cpu(cpu) {
>>> - -		/*
>>> - -		 * The fallback flush is currently coded for 8-way
>>> - -		 * associativity. Different associativity is possible, but it
>>> - -		 * will be treated as 8-way and may not evict the lines as
>>> - -		 * effectively.
>>> - -		 *
>>> - -		 * 128 byte lines are mandatory.
>>> - -		 */
>>> - -		u64 c = l1d_size / 8;
>>> - -
>>>  		paca[cpu].rfi_flush_fallback_area = l1d_flush_fallback_area;
>>> - -		paca[cpu].l1d_flush_congruence = c;
>>> - -		paca[cpu].l1d_flush_sets = c / 128;
>>> +		paca[cpu].l1d_flush_size = l1d_size;
>>>  	}
>>>  }
>>>  
>>> - -void __init setup_rfi_flush(enum l1d_flush_type types, bool enable)
>>> +void setup_rfi_flush(enum l1d_flush_type types, bool enable)
>>>  {
>>>  	if (types & L1D_FLUSH_FALLBACK) {
>>> - -		pr_info("rfi-flush: Using fallback displacement flush\n");
>>> +		pr_info("rfi-flush: fallback displacement flush available\n");
>>>  		init_fallback_flush();
>>>  	}
>>>  
>>>  	if (types & L1D_FLUSH_ORI)
>>> - -		pr_info("rfi-flush: Using ori type flush\n");
>>> +		pr_info("rfi-flush: ori type flush available\n");
>>>  
>>>  	if (types & L1D_FLUSH_MTTRIG)
>>> - -		pr_info("rfi-flush: Using mttrig type flush\n");
>>> +		pr_info("rfi-flush: mttrig type flush available\n");
>>>  
>>>  	enabled_flush_types = types;
>>>  
>>> @@ -940,13 +932,19 @@ void __init setup_rfi_flush(enum l1d_flush_type types, bool enable)
>>>  #ifdef CONFIG_DEBUG_FS
>>>  static int rfi_flush_set(void *data, u64 val)
>>>  {
>>> +	bool enable;
>>> +
>>>  	if (val == 1)
>>> - -		rfi_flush_enable(true);
>>> +		enable = true;
>>>  	else if (val == 0)
>>> - -		rfi_flush_enable(false);
>>> +		enable = false;
>>>  	else
>>>  		return -EINVAL;
>>>  
>>> +	/* Only do anything if we're changing state */
>>> +	if (enable != rfi_flush)
>>> +		rfi_flush_enable(enable);
>>> +
>>>  	return 0;
>>>  }
>>>  
>>> @@ -965,12 +963,4 @@ static __init int rfi_flush_debugfs_init(void)
>>>  }
>>>  device_initcall(rfi_flush_debugfs_init);
>>>  #endif
>>> - -
>>> - -ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
>>> - -{
>>> - -	if (rfi_flush)
>>> - -		return sprintf(buf, "Mitigation: RFI Flush\n");
>>> - -
>>> - -	return sprintf(buf, "Vulnerable\n");
>>> - -}
>>>  #endif /* CONFIG_PPC_BOOK3S_64 */
>>> diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
>>> index 072a23a17350..876ac9d52afc 100644
>>> - --- a/arch/powerpc/kernel/vmlinux.lds.S
>>> +++ b/arch/powerpc/kernel/vmlinux.lds.S
>>> @@ -73,14 +73,45 @@ SECTIONS
>>>  	RODATA
>>>  
>>>  #ifdef CONFIG_PPC64
>>> +	. = ALIGN(8);
>>> +	__stf_entry_barrier_fixup : AT(ADDR(__stf_entry_barrier_fixup) - LOAD_OFFSET) {
>>> +		__start___stf_entry_barrier_fixup = .;
>>> +		*(__stf_entry_barrier_fixup)
>>> +		__stop___stf_entry_barrier_fixup = .;
>>> +	}
>>> +
>>> +	. = ALIGN(8);
>>> +	__stf_exit_barrier_fixup : AT(ADDR(__stf_exit_barrier_fixup) - LOAD_OFFSET) {
>>> +		__start___stf_exit_barrier_fixup = .;
>>> +		*(__stf_exit_barrier_fixup)
>>> +		__stop___stf_exit_barrier_fixup = .;
>>> +	}
>>> +
>>>  	. = ALIGN(8);
>>>  	__rfi_flush_fixup : AT(ADDR(__rfi_flush_fixup) - LOAD_OFFSET) {
>>>  		__start___rfi_flush_fixup = .;
>>>  		*(__rfi_flush_fixup)
>>>  		__stop___rfi_flush_fixup = .;
>>>  	}
>>> - -#endif
>>> +#endif /* CONFIG_PPC64 */
>>>  
>>> +#ifdef CONFIG_PPC_BARRIER_NOSPEC
>>> +	. = ALIGN(8);
>>> +	__spec_barrier_fixup : AT(ADDR(__spec_barrier_fixup) - LOAD_OFFSET) {
>>> +		__start___barrier_nospec_fixup = .;
>>> +		*(__barrier_nospec_fixup)
>>> +		__stop___barrier_nospec_fixup = .;
>>> +	}
>>> +#endif /* CONFIG_PPC_BARRIER_NOSPEC */
>>> +
>>> +#ifdef CONFIG_PPC_FSL_BOOK3E
>>> +	. = ALIGN(8);
>>> +	__spec_btb_flush_fixup : AT(ADDR(__spec_btb_flush_fixup) - LOAD_OFFSET) {
>>> +		__start__btb_flush_fixup = .;
>>> +		*(__btb_flush_fixup)
>>> +		__stop__btb_flush_fixup = .;
>>> +	}
>>> +#endif
>>>  	EXCEPTION_TABLE(0)
>>>  
>>>  	NOTES :kernel :notes
>>> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
>>> index d5edbeb8eb82..570c06a00db6 100644
>>> - --- a/arch/powerpc/lib/code-patching.c
>>> +++ b/arch/powerpc/lib/code-patching.c
>>> @@ -14,12 +14,25 @@
>>>  #include <asm/page.h>
>>>  #include <asm/code-patching.h>
>>>  #include <asm/uaccess.h>
>>> +#include <asm/setup.h>
>>> +#include <asm/sections.h>
>>>  
>>>  
>>> +static inline bool is_init(unsigned int *addr)
>>> +{
>>> +	return addr >= (unsigned int *)__init_begin && addr < (unsigned int *)__init_end;
>>> +}
>>> +
>>>  int patch_instruction(unsigned int *addr, unsigned int instr)
>>>  {
>>>  	int err;
>>>  
>>> +	/* Make sure we aren't patching a freed init section */
>>> +	if (init_mem_is_free && is_init(addr)) {
>>> +		pr_debug("Skipping init section patching addr: 0x%px\n", addr);
>>> +		return 0;
>>> +	}
>>> +
>>>  	__put_user_size(instr, addr, 4, err);
>>>  	if (err)
>>>  		return err;
>>> @@ -32,6 +45,22 @@ int patch_branch(unsigned int *addr, unsigned long target, int flags)
>>>  	return patch_instruction(addr, create_branch(addr, target, flags));
>>>  }
>>>  
>>> +int patch_branch_site(s32 *site, unsigned long target, int flags)
>>> +{
>>> +	unsigned int *addr;
>>> +
>>> +	addr = (unsigned int *)((unsigned long)site + *site);
>>> +	return patch_instruction(addr, create_branch(addr, target, flags));
>>> +}
>>> +
>>> +int patch_instruction_site(s32 *site, unsigned int instr)
>>> +{
>>> +	unsigned int *addr;
>>> +
>>> +	addr = (unsigned int *)((unsigned long)site + *site);
>>> +	return patch_instruction(addr, instr);
>>> +}
>>> +
>>>  unsigned int create_branch(const unsigned int *addr,
>>>  			   unsigned long target, int flags)
>>>  {
>>> diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
>>> index 3af014684872..7bdfc19a491d 100644
>>> - --- a/arch/powerpc/lib/feature-fixups.c
>>> +++ b/arch/powerpc/lib/feature-fixups.c
>>> @@ -21,7 +21,7 @@
>>>  #include <asm/page.h>
>>>  #include <asm/sections.h>
>>>  #include <asm/setup.h>
>>> - -
>>> +#include <asm/security_features.h>
>>>  
>>>  struct fixup_entry {
>>>  	unsigned long	mask;
>>> @@ -115,6 +115,120 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
>>>  }
>>>  
>>>  #ifdef CONFIG_PPC_BOOK3S_64
>>> +void do_stf_entry_barrier_fixups(enum stf_barrier_type types)
>>> +{
>>> +	unsigned int instrs[3], *dest;
>>> +	long *start, *end;
>>> +	int i;
>>> +
>>> +	start = PTRRELOC(&__start___stf_entry_barrier_fixup),
>>> +	end = PTRRELOC(&__stop___stf_entry_barrier_fixup);
>>> +
>>> +	instrs[0] = 0x60000000; /* nop */
>>> +	instrs[1] = 0x60000000; /* nop */
>>> +	instrs[2] = 0x60000000; /* nop */
>>> +
>>> +	i = 0;
>>> +	if (types & STF_BARRIER_FALLBACK) {
>>> +		instrs[i++] = 0x7d4802a6; /* mflr r10		*/
>>> +		instrs[i++] = 0x60000000; /* branch patched below */
>>> +		instrs[i++] = 0x7d4803a6; /* mtlr r10		*/
>>> +	} else if (types & STF_BARRIER_EIEIO) {
>>> +		instrs[i++] = 0x7e0006ac; /* eieio + bit 6 hint */
>>> +	} else if (types & STF_BARRIER_SYNC_ORI) {
>>> +		instrs[i++] = 0x7c0004ac; /* hwsync		*/
>>> +		instrs[i++] = 0xe94d0000; /* ld r10,0(r13)	*/
>>> +		instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */
>>> +	}
>>> +
>>> +	for (i = 0; start < end; start++, i++) {
>>> +		dest = (void *)start + *start;
>>> +
>>> +		pr_devel("patching dest %lx\n", (unsigned long)dest);
>>> +
>>> +		patch_instruction(dest, instrs[0]);
>>> +
>>> +		if (types & STF_BARRIER_FALLBACK)
>>> +			patch_branch(dest + 1, (unsigned long)&stf_barrier_fallback,
>>> +				     BRANCH_SET_LINK);
>>> +		else
>>> +			patch_instruction(dest + 1, instrs[1]);
>>> +
>>> +		patch_instruction(dest + 2, instrs[2]);
>>> +	}
>>> +
>>> +	printk(KERN_DEBUG "stf-barrier: patched %d entry locations (%s barrier)\n", i,
>>> +		(types == STF_BARRIER_NONE)                  ? "no" :
>>> +		(types == STF_BARRIER_FALLBACK)              ? "fallback" :
>>> +		(types == STF_BARRIER_EIEIO)                 ? "eieio" :
>>> +		(types == (STF_BARRIER_SYNC_ORI))            ? "hwsync"
>>> +		                                           : "unknown");
>>> +}
>>> +
>>> +void do_stf_exit_barrier_fixups(enum stf_barrier_type types)
>>> +{
>>> +	unsigned int instrs[6], *dest;
>>> +	long *start, *end;
>>> +	int i;
>>> +
>>> +	start = PTRRELOC(&__start___stf_exit_barrier_fixup),
>>> +	end = PTRRELOC(&__stop___stf_exit_barrier_fixup);
>>> +
>>> +	instrs[0] = 0x60000000; /* nop */
>>> +	instrs[1] = 0x60000000; /* nop */
>>> +	instrs[2] = 0x60000000; /* nop */
>>> +	instrs[3] = 0x60000000; /* nop */
>>> +	instrs[4] = 0x60000000; /* nop */
>>> +	instrs[5] = 0x60000000; /* nop */
>>> +
>>> +	i = 0;
>>> +	if (types & STF_BARRIER_FALLBACK || types & STF_BARRIER_SYNC_ORI) {
>>> +		if (cpu_has_feature(CPU_FTR_HVMODE)) {
>>> +			instrs[i++] = 0x7db14ba6; /* mtspr 0x131, r13 (HSPRG1) */
>>> +			instrs[i++] = 0x7db04aa6; /* mfspr r13, 0x130 (HSPRG0) */
>>> +		} else {
>>> +			instrs[i++] = 0x7db243a6; /* mtsprg 2,r13	*/
>>> +			instrs[i++] = 0x7db142a6; /* mfsprg r13,1    */
>>> +	        }
>>> +		instrs[i++] = 0x7c0004ac; /* hwsync		*/
>>> +		instrs[i++] = 0xe9ad0000; /* ld r13,0(r13)	*/
>>> +		instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */
>>> +		if (cpu_has_feature(CPU_FTR_HVMODE)) {
>>> +			instrs[i++] = 0x7db14aa6; /* mfspr r13, 0x131 (HSPRG1) */
>>> +		} else {
>>> +			instrs[i++] = 0x7db242a6; /* mfsprg r13,2 */
>>> +		}
>>> +	} else if (types & STF_BARRIER_EIEIO) {
>>> +		instrs[i++] = 0x7e0006ac; /* eieio + bit 6 hint */
>>> +	}
>>> +
>>> +	for (i = 0; start < end; start++, i++) {
>>> +		dest = (void *)start + *start;
>>> +
>>> +		pr_devel("patching dest %lx\n", (unsigned long)dest);
>>> +
>>> +		patch_instruction(dest, instrs[0]);
>>> +		patch_instruction(dest + 1, instrs[1]);
>>> +		patch_instruction(dest + 2, instrs[2]);
>>> +		patch_instruction(dest + 3, instrs[3]);
>>> +		patch_instruction(dest + 4, instrs[4]);
>>> +		patch_instruction(dest + 5, instrs[5]);
>>> +	}
>>> +	printk(KERN_DEBUG "stf-barrier: patched %d exit locations (%s barrier)\n", i,
>>> +		(types == STF_BARRIER_NONE)                  ? "no" :
>>> +		(types == STF_BARRIER_FALLBACK)              ? "fallback" :
>>> +		(types == STF_BARRIER_EIEIO)                 ? "eieio" :
>>> +		(types == (STF_BARRIER_SYNC_ORI))            ? "hwsync"
>>> +		                                           : "unknown");
>>> +}
>>> +
>>> +
>>> +void do_stf_barrier_fixups(enum stf_barrier_type types)
>>> +{
>>> +	do_stf_entry_barrier_fixups(types);
>>> +	do_stf_exit_barrier_fixups(types);
>>> +}
>>> +
>>>  void do_rfi_flush_fixups(enum l1d_flush_type types)
>>>  {
>>>  	unsigned int instrs[3], *dest;
>>> @@ -151,10 +265,110 @@ void do_rfi_flush_fixups(enum l1d_flush_type types)
>>>  		patch_instruction(dest + 2, instrs[2]);
>>>  	}
>>>  
>>> - -	printk(KERN_DEBUG "rfi-flush: patched %d locations\n", i);
>>> +	printk(KERN_DEBUG "rfi-flush: patched %d locations (%s flush)\n", i,
>>> +		(types == L1D_FLUSH_NONE)       ? "no" :
>>> +		(types == L1D_FLUSH_FALLBACK)   ? "fallback displacement" :
>>> +		(types &  L1D_FLUSH_ORI)        ? (types & L1D_FLUSH_MTTRIG)
>>> +							? "ori+mttrig type"
>>> +							: "ori type" :
>>> +		(types &  L1D_FLUSH_MTTRIG)     ? "mttrig type"
>>> +						: "unknown");
>>> +}
>>> +
>>> +void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_end)
>>> +{
>>> +	unsigned int instr, *dest;
>>> +	long *start, *end;
>>> +	int i;
>>> +
>>> +	start = fixup_start;
>>> +	end = fixup_end;
>>> +
>>> +	instr = 0x60000000; /* nop */
>>> +
>>> +	if (enable) {
>>> +		pr_info("barrier-nospec: using ORI speculation barrier\n");
>>> +		instr = 0x63ff0000; /* ori 31,31,0 speculation barrier */
>>> +	}
>>> +
>>> +	for (i = 0; start < end; start++, i++) {
>>> +		dest = (void *)start + *start;
>>> +
>>> +		pr_devel("patching dest %lx\n", (unsigned long)dest);
>>> +		patch_instruction(dest, instr);
>>> +	}
>>> +
>>> +	printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
>>>  }
>>> +
>>>  #endif /* CONFIG_PPC_BOOK3S_64 */
>>>  
>>> +#ifdef CONFIG_PPC_BARRIER_NOSPEC
>>> +void do_barrier_nospec_fixups(bool enable)
>>> +{
>>> +	void *start, *end;
>>> +
>>> +	start = PTRRELOC(&__start___barrier_nospec_fixup),
>>> +	end = PTRRELOC(&__stop___barrier_nospec_fixup);
>>> +
>>> +	do_barrier_nospec_fixups_range(enable, start, end);
>>> +}
>>> +#endif /* CONFIG_PPC_BARRIER_NOSPEC */
>>> +
>>> +#ifdef CONFIG_PPC_FSL_BOOK3E
>>> +void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_end)
>>> +{
>>> +	unsigned int instr[2], *dest;
>>> +	long *start, *end;
>>> +	int i;
>>> +
>>> +	start = fixup_start;
>>> +	end = fixup_end;
>>> +
>>> +	instr[0] = PPC_INST_NOP;
>>> +	instr[1] = PPC_INST_NOP;
>>> +
>>> +	if (enable) {
>>> +		pr_info("barrier-nospec: using isync; sync as speculation barrier\n");
>>> +		instr[0] = PPC_INST_ISYNC;
>>> +		instr[1] = PPC_INST_SYNC;
>>> +	}
>>> +
>>> +	for (i = 0; start < end; start++, i++) {
>>> +		dest = (void *)start + *start;
>>> +
>>> +		pr_devel("patching dest %lx\n", (unsigned long)dest);
>>> +		patch_instruction(dest, instr[0]);
>>> +		patch_instruction(dest + 1, instr[1]);
>>> +	}
>>> +
>>> +	printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
>>> +}
>>> +
>>> +static void patch_btb_flush_section(long *curr)
>>> +{
>>> +	unsigned int *start, *end;
>>> +
>>> +	start = (void *)curr + *curr;
>>> +	end = (void *)curr + *(curr + 1);
>>> +	for (; start < end; start++) {
>>> +		pr_devel("patching dest %lx\n", (unsigned long)start);
>>> +		patch_instruction(start, PPC_INST_NOP);
>>> +	}
>>> +}
>>> +
>>> +void do_btb_flush_fixups(void)
>>> +{
>>> +	long *start, *end;
>>> +
>>> +	start = PTRRELOC(&__start__btb_flush_fixup);
>>> +	end = PTRRELOC(&__stop__btb_flush_fixup);
>>> +
>>> +	for (; start < end; start += 2)
>>> +		patch_btb_flush_section(start);
>>> +}
>>> +#endif /* CONFIG_PPC_FSL_BOOK3E */
>>> +
>>>  void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
>>>  {
>>>  	long *start, *end;
>>> diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
>>> index 22d94c3e6fc4..1efe5ca5c3bc 100644
>>> - --- a/arch/powerpc/mm/mem.c
>>> +++ b/arch/powerpc/mm/mem.c
>>> @@ -62,6 +62,7 @@
>>>  #endif
>>>  
>>>  unsigned long long memory_limit;
>>> +bool init_mem_is_free;
>>>  
>>>  #ifdef CONFIG_HIGHMEM
>>>  pte_t *kmap_pte;
>>> @@ -381,6 +382,7 @@ void __init mem_init(void)
>>>  void free_initmem(void)
>>>  {
>>>  	ppc_md.progress = ppc_printk_progress;
>>> +	init_mem_is_free = true;
>>>  	free_initmem_default(POISON_FREE_INITMEM);
>>>  }
>>>  
>>> diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S
>>> index 29d6987c37ba..5486d56da289 100644
>>> - --- a/arch/powerpc/mm/tlb_low_64e.S
>>> +++ b/arch/powerpc/mm/tlb_low_64e.S
>>> @@ -69,6 +69,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
>>>  	std	r15,EX_TLB_R15(r12)
>>>  	std	r10,EX_TLB_CR(r12)
>>>  #ifdef CONFIG_PPC_FSL_BOOK3E
>>> +START_BTB_FLUSH_SECTION
>>> +	mfspr r11, SPRN_SRR1
>>> +	andi. r10,r11,MSR_PR
>>> +	beq 1f
>>> +	BTB_FLUSH(r10)
>>> +1:
>>> +END_BTB_FLUSH_SECTION
>>>  	std	r7,EX_TLB_R7(r12)
>>>  #endif
>>>  	TLB_MISS_PROLOG_STATS
>>> diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
>>> index c57afc619b20..e14b52c7ebd8 100644
>>> - --- a/arch/powerpc/platforms/powernv/setup.c
>>> +++ b/arch/powerpc/platforms/powernv/setup.c
>>> @@ -37,53 +37,99 @@
>>>  #include <asm/smp.h>
>>>  #include <asm/tm.h>
>>>  #include <asm/setup.h>
>>> +#include <asm/security_features.h>
>>>  
>>>  #include "powernv.h"
>>>  
>>> +
>>> +static bool fw_feature_is(const char *state, const char *name,
>>> +			  struct device_node *fw_features)
>>> +{
>>> +	struct device_node *np;
>>> +	bool rc = false;
>>> +
>>> +	np = of_get_child_by_name(fw_features, name);
>>> +	if (np) {
>>> +		rc = of_property_read_bool(np, state);
>>> +		of_node_put(np);
>>> +	}
>>> +
>>> +	return rc;
>>> +}
>>> +
>>> +static void init_fw_feat_flags(struct device_node *np)
>>> +{
>>> +	if (fw_feature_is("enabled", "inst-spec-barrier-ori31,31,0", np))
>>> +		security_ftr_set(SEC_FTR_SPEC_BAR_ORI31);
>>> +
>>> +	if (fw_feature_is("enabled", "fw-bcctrl-serialized", np))
>>> +		security_ftr_set(SEC_FTR_BCCTRL_SERIALISED);
>>> +
>>> +	if (fw_feature_is("enabled", "inst-l1d-flush-ori30,30,0", np))
>>> +		security_ftr_set(SEC_FTR_L1D_FLUSH_ORI30);
>>> +
>>> +	if (fw_feature_is("enabled", "inst-l1d-flush-trig2", np))
>>> +		security_ftr_set(SEC_FTR_L1D_FLUSH_TRIG2);
>>> +
>>> +	if (fw_feature_is("enabled", "fw-l1d-thread-split", np))
>>> +		security_ftr_set(SEC_FTR_L1D_THREAD_PRIV);
>>> +
>>> +	if (fw_feature_is("enabled", "fw-count-cache-disabled", np))
>>> +		security_ftr_set(SEC_FTR_COUNT_CACHE_DISABLED);
>>> +
>>> +	if (fw_feature_is("enabled", "fw-count-cache-flush-bcctr2,0,0", np))
>>> +		security_ftr_set(SEC_FTR_BCCTR_FLUSH_ASSIST);
>>> +
>>> +	if (fw_feature_is("enabled", "needs-count-cache-flush-on-context-switch", np))
>>> +		security_ftr_set(SEC_FTR_FLUSH_COUNT_CACHE);
>>> +
>>> +	/*
>>> +	 * The features below are enabled by default, so we instead look to see
>>> +	 * if firmware has *disabled* them, and clear them if so.
>>> +	 */
>>> +	if (fw_feature_is("disabled", "speculation-policy-favor-security", np))
>>> +		security_ftr_clear(SEC_FTR_FAVOUR_SECURITY);
>>> +
>>> +	if (fw_feature_is("disabled", "needs-l1d-flush-msr-pr-0-to-1", np))
>>> +		security_ftr_clear(SEC_FTR_L1D_FLUSH_PR);
>>> +
>>> +	if (fw_feature_is("disabled", "needs-l1d-flush-msr-hv-1-to-0", np))
>>> +		security_ftr_clear(SEC_FTR_L1D_FLUSH_HV);
>>> +
>>> +	if (fw_feature_is("disabled", "needs-spec-barrier-for-bound-checks", np))
>>> +		security_ftr_clear(SEC_FTR_BNDS_CHK_SPEC_BAR);
>>> +}
>>> +
>>>  static void pnv_setup_rfi_flush(void)
>>>  {
>>>  	struct device_node *np, *fw_features;
>>>  	enum l1d_flush_type type;
>>> - -	int enable;
>>> +	bool enable;
>>>  
>>>  	/* Default to fallback in case fw-features are not available */
>>>  	type = L1D_FLUSH_FALLBACK;
>>> - -	enable = 1;
>>>  
>>>  	np = of_find_node_by_name(NULL, "ibm,opal");
>>>  	fw_features = of_get_child_by_name(np, "fw-features");
>>>  	of_node_put(np);
>>>  
>>>  	if (fw_features) {
>>> - -		np = of_get_child_by_name(fw_features, "inst-l1d-flush-trig2");
>>> - -		if (np && of_property_read_bool(np, "enabled"))
>>> - -			type = L1D_FLUSH_MTTRIG;
>>> +		init_fw_feat_flags(fw_features);
>>> +		of_node_put(fw_features);
>>>  
>>> - -		of_node_put(np);
>>> +		if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_TRIG2))
>>> +			type = L1D_FLUSH_MTTRIG;
>>>  
>>> - -		np = of_get_child_by_name(fw_features, "inst-l1d-flush-ori30,30,0");
>>> - -		if (np && of_property_read_bool(np, "enabled"))
>>> +		if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_ORI30))
>>>  			type = L1D_FLUSH_ORI;
>>> - -
>>> - -		of_node_put(np);
>>> - -
>>> - -		/* Enable unless firmware says NOT to */
>>> - -		enable = 2;
>>> - -		np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-hv-1-to-0");
>>> - -		if (np && of_property_read_bool(np, "disabled"))
>>> - -			enable--;
>>> - -
>>> - -		of_node_put(np);
>>> - -
>>> - -		np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-pr-0-to-1");
>>> - -		if (np && of_property_read_bool(np, "disabled"))
>>> - -			enable--;
>>> - -
>>> - -		of_node_put(np);
>>> - -		of_node_put(fw_features);
>>>  	}
>>>  
>>> - -	setup_rfi_flush(type, enable > 0);
>>> +	enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && \
>>> +		 (security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR)   || \
>>> +		  security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV));
>>> +
>>> +	setup_rfi_flush(type, enable);
>>> +	setup_count_cache_flush();
>>>  }
>>>  
>>>  static void __init pnv_setup_arch(void)
>>> @@ -91,6 +137,7 @@ static void __init pnv_setup_arch(void)
>>>  	set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
>>>  
>>>  	pnv_setup_rfi_flush();
>>> +	setup_stf_barrier();
>>>  
>>>  	/* Initialize SMP */
>>>  	pnv_smp_init();
>>> diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
>>> index 8dd0c8edefd6..c773396d0969 100644
>>> - --- a/arch/powerpc/platforms/pseries/mobility.c
>>> +++ b/arch/powerpc/platforms/pseries/mobility.c
>>> @@ -314,6 +314,9 @@ void post_mobility_fixup(void)
>>>  		printk(KERN_ERR "Post-mobility device tree update "
>>>  			"failed: %d\n", rc);
>>>  
>>> +	/* Possibly switch to a new RFI flush type */
>>> +	pseries_setup_rfi_flush();
>>> +
>>>  	return;
>>>  }
>>>  
>>> diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
>>> index 8411c27293e4..e7d80797384d 100644
>>> - --- a/arch/powerpc/platforms/pseries/pseries.h
>>> +++ b/arch/powerpc/platforms/pseries/pseries.h
>>> @@ -81,4 +81,6 @@ extern struct pci_controller_ops pseries_pci_controller_ops;
>>>  
>>>  unsigned long pseries_memory_block_size(void);
>>>  
>>> +void pseries_setup_rfi_flush(void);
>>> +
>>>  #endif /* _PSERIES_PSERIES_H */
>>> diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
>>> index dd2545fc9947..9cc976ff7fec 100644
>>> - --- a/arch/powerpc/platforms/pseries/setup.c
>>> +++ b/arch/powerpc/platforms/pseries/setup.c
>>> @@ -67,6 +67,7 @@
>>>  #include <asm/eeh.h>
>>>  #include <asm/reg.h>
>>>  #include <asm/plpar_wrappers.h>
>>> +#include <asm/security_features.h>
>>>  
>>>  #include "pseries.h"
>>>  
>>> @@ -499,37 +500,87 @@ static void __init find_and_init_phbs(void)
>>>  	of_pci_check_probe_only();
>>>  }
>>>  
>>> - -static void pseries_setup_rfi_flush(void)
>>> +static void init_cpu_char_feature_flags(struct h_cpu_char_result *result)
>>> +{
>>> +	/*
>>> +	 * The features below are disabled by default, so we instead look to see
>>> +	 * if firmware has *enabled* them, and set them if so.
>>> +	 */
>>> +	if (result->character & H_CPU_CHAR_SPEC_BAR_ORI31)
>>> +		security_ftr_set(SEC_FTR_SPEC_BAR_ORI31);
>>> +
>>> +	if (result->character & H_CPU_CHAR_BCCTRL_SERIALISED)
>>> +		security_ftr_set(SEC_FTR_BCCTRL_SERIALISED);
>>> +
>>> +	if (result->character & H_CPU_CHAR_L1D_FLUSH_ORI30)
>>> +		security_ftr_set(SEC_FTR_L1D_FLUSH_ORI30);
>>> +
>>> +	if (result->character & H_CPU_CHAR_L1D_FLUSH_TRIG2)
>>> +		security_ftr_set(SEC_FTR_L1D_FLUSH_TRIG2);
>>> +
>>> +	if (result->character & H_CPU_CHAR_L1D_THREAD_PRIV)
>>> +		security_ftr_set(SEC_FTR_L1D_THREAD_PRIV);
>>> +
>>> +	if (result->character & H_CPU_CHAR_COUNT_CACHE_DISABLED)
>>> +		security_ftr_set(SEC_FTR_COUNT_CACHE_DISABLED);
>>> +
>>> +	if (result->character & H_CPU_CHAR_BCCTR_FLUSH_ASSIST)
>>> +		security_ftr_set(SEC_FTR_BCCTR_FLUSH_ASSIST);
>>> +
>>> +	if (result->behaviour & H_CPU_BEHAV_FLUSH_COUNT_CACHE)
>>> +		security_ftr_set(SEC_FTR_FLUSH_COUNT_CACHE);
>>> +
>>> +	/*
>>> +	 * The features below are enabled by default, so we instead look to see
>>> +	 * if firmware has *disabled* them, and clear them if so.
>>> +	 */
>>> +	if (!(result->behaviour & H_CPU_BEHAV_FAVOUR_SECURITY))
>>> +		security_ftr_clear(SEC_FTR_FAVOUR_SECURITY);
>>> +
>>> +	if (!(result->behaviour & H_CPU_BEHAV_L1D_FLUSH_PR))
>>> +		security_ftr_clear(SEC_FTR_L1D_FLUSH_PR);
>>> +
>>> +	if (!(result->behaviour & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR))
>>> +		security_ftr_clear(SEC_FTR_BNDS_CHK_SPEC_BAR);
>>> +}
>>> +
>>> +void pseries_setup_rfi_flush(void)
>>>  {
>>>  	struct h_cpu_char_result result;
>>>  	enum l1d_flush_type types;
>>>  	bool enable;
>>>  	long rc;
>>>  
>>> - -	/* Enable by default */
>>> - -	enable = true;
>>> +	/*
>>> +	 * Set features to the defaults assumed by init_cpu_char_feature_flags()
>>> +	 * so it can set/clear again any features that might have changed after
>>> +	 * migration, and in case the hypercall fails and it is not even called.
>>> +	 */
>>> +	powerpc_security_features = SEC_FTR_DEFAULT;
>>>  
>>>  	rc = plpar_get_cpu_characteristics(&result);
>>> - -	if (rc == H_SUCCESS) {
>>> - -		types = L1D_FLUSH_NONE;
>>> +	if (rc == H_SUCCESS)
>>> +		init_cpu_char_feature_flags(&result);
>>>  
>>> - -		if (result.character & H_CPU_CHAR_L1D_FLUSH_TRIG2)
>>> - -			types |= L1D_FLUSH_MTTRIG;
>>> - -		if (result.character & H_CPU_CHAR_L1D_FLUSH_ORI30)
>>> - -			types |= L1D_FLUSH_ORI;
>>> +	/*
>>> +	 * We're the guest so this doesn't apply to us, clear it to simplify
>>> +	 * handling of it elsewhere.
>>> +	 */
>>> +	security_ftr_clear(SEC_FTR_L1D_FLUSH_HV);
>>>  
>>> - -		/* Use fallback if nothing set in hcall */
>>> - -		if (types == L1D_FLUSH_NONE)
>>> - -			types = L1D_FLUSH_FALLBACK;
>>> +	types = L1D_FLUSH_FALLBACK;
>>>  
>>> - -		if (!(result.behaviour & H_CPU_BEHAV_L1D_FLUSH_PR))
>>> - -			enable = false;
>>> - -	} else {
>>> - -		/* Default to fallback if case hcall is not available */
>>> - -		types = L1D_FLUSH_FALLBACK;
>>> - -	}
>>> +	if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_TRIG2))
>>> +		types |= L1D_FLUSH_MTTRIG;
>>> +
>>> +	if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_ORI30))
>>> +		types |= L1D_FLUSH_ORI;
>>> +
>>> +	enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && \
>>> +		 security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR);
>>>  
>>>  	setup_rfi_flush(types, enable);
>>> +	setup_count_cache_flush();
>>>  }
>>>  
>>>  static void __init pSeries_setup_arch(void)
>>> @@ -549,6 +600,7 @@ static void __init pSeries_setup_arch(void)
>>>  	fwnmi_init();
>>>  
>>>  	pseries_setup_rfi_flush();
>>> +	setup_stf_barrier();
>>>  
>>>  	/* By default, only probe PCI (can be overridden by rtas_pci) */
>>>  	pci_add_flags(PCI_PROBE_ONLY);
>>> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
>>> index 786bf01691c9..83619ebede93 100644
>>> - --- a/arch/powerpc/xmon/xmon.c
>>> +++ b/arch/powerpc/xmon/xmon.c
>>> @@ -2144,6 +2144,8 @@ static void dump_one_paca(int cpu)
>>>  	DUMP(p, slb_cache_ptr, "x");
>>>  	for (i = 0; i < SLB_CACHE_ENTRIES; i++)
>>>  		printf(" slb_cache[%d]:        = 0x%016lx\n", i, p->slb_cache[i]);
>>> +
>>> +	DUMP(p, rfi_flush_fallback_area, "px");
>>>  #endif
>>>  	DUMP(p, dscr_default, "llx");
>>>  #ifdef CONFIG_PPC_BOOK3E
>>> - -- 
>>> 2.20.1
>>>
>>> -----BEGIN PGP SIGNATURE-----
>>>
>>> iQIcBAEBAgAGBQJcvHWhAAoJEFHr6jzI4aWA6nsP/0YskmAfLovcUmERQ7+bIjq6
>>> IcS1T466dvy6MlqeBXU4x8pVgInWeHKEC9XJdkM1lOeib/SLW7Hbz4kgJeOGwFGY
>>> lOTaexrxvsBqPm7f6GC0zbl9obEIIIIUs+TielFQANBgqm+q8Wio+XXPP9bpKeKY
>>> agSpQ3nwL/PYixznbNmN/lP9py5p89LQ0IBcR7dDBGGWJtD/AXeZ9hslsZxPbPtI
>>> nZJ0vdnjuoB2z+hCxfKWlYfLwH0VfoTpqP5x3ALCkvbBr67e8bf6EK8+trnvhyQ8
>>> iLY4bp1pm2epAI0/3NfyEiDMsGjVJ6IFlkyhDkHJgJNu0BGcGOSX2GpyU3juviAK
>>> c95FtBft/i8AwigOMCivg2mN5edYjsSiPoEItwT5KWqgByJsdr5i5mYVx8cUjMOz
>>> iAxLZCdg+UHZYuCBCAO2ZI1G9bVXI1Pa3btMspiCOOOsYGjXGf0oFfKQ+7957hUO
>>> ftYYJoGHlMHiHR1OPas6T3lk6YKF9uvfIDTE3OKw2obHbbRz3u82xoWMRGW503MN
>>> 7WpkpAP7oZ9RgqIWFVhatWy5f+7GFL0akEi4o2tsZHhYlPau7YWo+nToTd87itwt
>>> GBaWJipzge4s13VkhAE+jWFO35Fvwi8uNZ7UgpuKMBECEjkGbtzBTq2MjSF5G8wc
>>> yPEod5jby/Iqb7DkGPVG
>>> =6DnF
>>> -----END PGP SIGNATURE-----
>>>


^ permalink raw reply

* Re: [PATCH 36/41] drivers: tty: serial: 8250: store mmio resource size in port struct
From: Andy Shevchenko @ 2019-04-29 15:39 UTC (permalink / raw)
  To: Enrico Weigelt, metux IT consult
  Cc: sparclinux, lorenzo.pieralisi, linux-ia64, linux-serial, andrew,
	gregkh, sudeep.holla, liviu.dudau, linux-kernel, vz, linux,
	linuxppc-dev, khilman, macro, slemieux.tyco, matthias.bgg, jacmet,
	linux-amlogic, linux-mips, Enrico Weigelt, metux IT consult,
	davem
In-Reply-To: <4bab941a-c2f2-7f1c-9bc2-86c63f171c25@metux.net>

On Mon, Apr 29, 2019 at 04:55:05PM +0200, Enrico Weigelt, metux IT consult wrote:
> On 28.04.19 17:18, Andy Shevchenko wrote:
> > On Sat, Apr 27, 2019 at 02:52:17PM +0200, Enrico Weigelt, metux IT consult wrote:

> >> -	int ret = 0;
> > 
> > This and Co is a separate change that can be done in its own patch.
> 
> I don't really understand :(
> Do you mean the splitting off the retval part from the rest ?

You do two things here: one of them is removing ret and other relative changes.
This should be split to a separate patch.

> > You may increase readability by introducing temporary variables
> > 
> > 	... mapbase = port->mapbase;
> > 	... mapsize = port->mapsize;
> > 	...
> > 	port->membase = ioremap_nocache(mapbase, mapsize);
> > 	...
> 
> Is that really necessary ? Maybe it's just my personal taste, but I
> don't feel the more more verbose one is really easier to read.

Up to Greg. For me it's harder to read all those port-> in several parameters.


-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* Re: [RESEND PATCH v3 09/11] powerpc/mm/radix: mark __radix__flush_tlb_range_psize() as __always_inline
From: Christophe Leroy @ 2019-04-29 15:35 UTC (permalink / raw)
  To: Masahiro Yamada, Andrew Morton, linux-arch
  Cc: linux-s390, Arnd Bergmann, Mathieu Malaterre, x86, Heiko Carstens,
	linux-mips, linux-kernel, Ingo Molnar, linux-mtd, linuxppc-dev,
	linux-arm-kernel
In-Reply-To: <20190423034959.13525-10-yamada.masahiro@socionext.com>



Le 23/04/2019 à 05:49, Masahiro Yamada a écrit :
> This prepares to move CONFIG_OPTIMIZE_INLINING from x86 to a common
> place. We need to eliminate potential issues beforehand.

How did you identify the functions requiring __always_inline as this one 
? Just by 'test and see if it fails', or did you have some script or so ?

Here the problem is that one of the parameters of the function are used 
as "immediate" constraint for the inline assembly, therefore requiring 
the function to always be inline.

I guess this should be explained in the commit log and I'm wondering how 
you ensure that you did identify all functions like this.

Christophe

> 
> If it is enabled for powerpc, the following error is reported:
> 
> arch/powerpc/mm/tlb-radix.c: In function '__radix__flush_tlb_range_psize':
> arch/powerpc/mm/tlb-radix.c:104:2: error: asm operand 3 probably doesn't match constraints [-Werror]
>    asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1)
>    ^~~
> arch/powerpc/mm/tlb-radix.c:104:2: error: impossible constraint in 'asm'
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
> ---
> 
> Changes in v3: None
> Changes in v2:
>    - split into a separate patch
> 
>   arch/powerpc/mm/tlb-radix.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/mm/tlb-radix.c b/arch/powerpc/mm/tlb-radix.c
> index 6a23b9ebd2a1..a2b2848f0ae3 100644
> --- a/arch/powerpc/mm/tlb-radix.c
> +++ b/arch/powerpc/mm/tlb-radix.c
> @@ -928,7 +928,7 @@ void radix__tlb_flush(struct mmu_gather *tlb)
>   	tlb->need_flush_all = 0;
>   }
>   
> -static inline void __radix__flush_tlb_range_psize(struct mm_struct *mm,
> +static __always_inline void __radix__flush_tlb_range_psize(struct mm_struct *mm,
>   				unsigned long start, unsigned long end,
>   				int psize, bool also_pwc)
>   {
> 

^ permalink raw reply

* [PATCH for 5.2 10/12] rseq/selftests: powerpc code signature: generate valid instructions
From: Mathieu Desnoyers @ 2019-04-29 15:28 UTC (permalink / raw)
  To: Shuah Khan
  Cc: Joel Fernandes, Peter Zijlstra, Catalin Marinas, Dave Watson,
	Will Deacon, Andi Kleen, Paul Mackerras, H . Peter Anvin,
	Chris Lameter, Russell King, Ingo Molnar, Michael Kerrisk,
	Paul E . McKenney, Paul Turner, Alan Modra, Boqun Feng,
	Josh Triplett, Steven Rostedt, Ben Maurer, Mathieu Desnoyers,
	Thomas Gleixner, linux-api, linuxppc-dev, linux-kernel,
	Andy Lutomirski, Andrew Morton, Linus Torvalds
In-Reply-To: <20190429152803.7719-1-mathieu.desnoyers@efficios.com>

Use "twui" as the guard instruction for the restartable sequence abort
handler.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <paulus@samba.org>
CC: Michael Ellerman <mpe@ellerman.id.au>
CC: Boqun Feng <boqun.feng@gmail.com>
CC: Peter Zijlstra <peterz@infradead.org>
CC: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
CC: Alan Modra <amodra@gmail.com>
CC: linuxppc-dev@lists.ozlabs.org
---
 tools/testing/selftests/rseq/rseq-ppc.h | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/rseq/rseq-ppc.h b/tools/testing/selftests/rseq/rseq-ppc.h
index 9df18487fa9f..76be90196fe4 100644
--- a/tools/testing/selftests/rseq/rseq-ppc.h
+++ b/tools/testing/selftests/rseq/rseq-ppc.h
@@ -6,7 +6,15 @@
  * (C) Copyright 2016-2018 - Boqun Feng <boqun.feng@gmail.com>
  */
 
-#define RSEQ_SIG	0x53053053
+/*
+ * RSEQ_SIG is used with the following trap instruction:
+ *
+ * powerpc-be:    0f e5 00 0b           twui   r5,11
+ * powerpc64-le:  0b 00 e5 0f           twui   r5,11
+ * powerpc64-be:  0f e5 00 0b           twui   r5,11
+ */
+
+#define RSEQ_SIG	0x0fe5000b
 
 #define rseq_smp_mb()		__asm__ __volatile__ ("sync"	::: "memory", "cc")
 #define rseq_smp_lwsync()	__asm__ __volatile__ ("lwsync"	::: "memory", "cc")
-- 
2.11.0


^ permalink raw reply related

* Re: [PATCH 12/41] drivers: tty: serial: uartlite: use dev_dbg() instead of pr_debug()
From: Peter Korsgaard @ 2019-04-29 15:26 UTC (permalink / raw)
  To: Enrico Weigelt, metux IT consult
  Cc: lorenzo.pieralisi, linux-ia64, macro, andrew, gregkh,
	slemieux.tyco, liviu.dudau, linux-kernel, andriy.shevchenko,
	linux-mips, linux, matthias.bgg, khilman, linux-serial,
	sudeep.holla, sparclinux, jacmet, linux-amlogic, vz, linuxppc-dev,
	davem
In-Reply-To: <1556369542-13247-13-git-send-email-info@metux.net>

>>>>> "Enrico" == Enrico Weigelt, metux IT consult <info@metux.net> writes:

 > Using dev_dbg() instead of pr_debg() for more consistent output.
 > (prints device name, etc).

 > Signed-off-by: Enrico Weigelt <info@metux.net>

Acked-by: Peter Korsgaard <peter@korsgaard.com>

-- 
Bye, Peter Korsgaard

^ permalink raw reply

* Re: [PATCH 16/41] drivers: tty: serial: uartlite: fix overlong lines
From: Peter Korsgaard @ 2019-04-29 15:24 UTC (permalink / raw)
  To: Enrico Weigelt, metux IT consult
  Cc: lorenzo.pieralisi, linux-ia64, macro, andrew, gregkh,
	slemieux.tyco, liviu.dudau, linux-kernel, andriy.shevchenko,
	linux-mips, linux, matthias.bgg, khilman, linux-serial,
	sudeep.holla, sparclinux, jacmet, linux-amlogic, vz, linuxppc-dev,
	davem
In-Reply-To: <1556369542-13247-17-git-send-email-info@metux.net>

>>>>> "Enrico" == Enrico Weigelt, metux IT consult <info@metux.net> writes:

 > Fix checkpatch warnings:
 >     WARNING: line over 80 characters
 >     #283: FILE: drivers/tty/serial/uartlite.c:283:
 >     +	ret = request_irq(port->irq, ulite_isr, IRQF_SHARED | IRQF_TRIGGER_RISING,

 >     WARNING: Missing a blank line after declarations
 >     #577: FILE: drivers/tty/serial/uartlite.c:577:
 >     +	struct earlycon_device *device = console->data;
 >     +	uart_console_write(&device->port, s, n, early_uartlite_putc);

 >     WARNING: line over 80 characters
 >     #590: FILE: drivers/tty/serial/uartlite.c:590:
 >     +OF_EARLYCON_DECLARE(uartlite_b, "xlnx,opb-uartlite-1.00.b", early_uartlite_setup);

 >     WARNING: line over 80 characters
 >     #591: FILE: drivers/tty/serial/uartlite.c:591:
 >     +OF_EARLYCON_DECLARE(uartlite_a, "xlnx,xps-uartlite-1.00.a", early_uartlite_setup);

Given that these are just a few characters more than 80 I don't really
think these changes improve readability.


 > Signed-off-by: Enrico Weigelt <info@metux.net>
 > ---
 >  drivers/tty/serial/uartlite.c | 10 +++++++---
 >  1 file changed, 7 insertions(+), 3 deletions(-)

 > diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c
 > index 6f79353..0140cec 100644
 > --- a/drivers/tty/serial/uartlite.c
 > +++ b/drivers/tty/serial/uartlite.c
 > @@ -280,7 +280,8 @@ static int ulite_startup(struct uart_port *port)
 >  		return ret;
 >  	}
 
 > -	ret = request_irq(port->irq, ulite_isr, IRQF_SHARED | IRQF_TRIGGER_RISING,
 > +	ret = request_irq(port->irq, ulite_isr,
 > +			  IRQF_SHARED | IRQF_TRIGGER_RISING,
 >  			  "uartlite", port);
 >  	if (ret)
 >  		return ret;
 > @@ -574,6 +575,7 @@ static void early_uartlite_write(struct console *console,
 >  				 const char *s, unsigned int n)
 >  {
 >  	struct earlycon_device *device = console->data;
 > +
 >  	uart_console_write(&device->port, s, n, early_uartlite_putc);

Unrelated change?

-- 
Bye, Peter Korsgaard

^ permalink raw reply

* Re: [PATCH 15/41] drivers: tty: serial: uartlite: fix use fix bare 'unsigned'
From: Peter Korsgaard @ 2019-04-29 15:21 UTC (permalink / raw)
  To: Enrico Weigelt, metux IT consult
  Cc: lorenzo.pieralisi, linux-ia64, macro, andrew, gregkh,
	slemieux.tyco, liviu.dudau, linux-kernel, andriy.shevchenko,
	linux-mips, linux, matthias.bgg, khilman, linux-serial,
	sudeep.holla, sparclinux, jacmet, linux-amlogic, vz, linuxppc-dev,
	davem
In-Reply-To: <1556369542-13247-16-git-send-email-info@metux.net>

>>>>> "Enrico" == Enrico Weigelt, metux IT consult <info@metux.net> writes:

 > Fix checkpatch warnings:
 >     WARNING: Prefer 'unsigned int' to bare use of 'unsigned'
 >     #562: FILE: drivers/tty/serial/uartlite.c:562:
 >     +	unsigned retries = 1000000;

 >     WARNING: Prefer 'unsigned int' to bare use of 'unsigned'
 >     #574: FILE: drivers/tty/serial/uartlite.c:574:
 >     +				 const char *s, unsigned n)

s/fix use fix/fix use of/ in Subject. Other than that:

Acked-by: Peter Korsgaard <peter@korsgaard.com>

-- 
Bye, Peter Korsgaard

^ permalink raw reply


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