* [PATCH v3 1/7] dump_stack: Support adding to the dump stack arch description
From: Michael Ellerman @ 2019-02-07 12:46 UTC (permalink / raw)
To: linuxppc-dev
Cc: linux-arch, pmladek, linux-kernel, sergey.senozhatsky, tj, akpm,
dyoung
Arch code can set a "dump stack arch description string" which is
displayed with oops output to describe the hardware platform.
It is useful to initialise this as early as possible, so that an early
oops will have the hardware description.
However in practice we discover the hardware platform in stages, so it
would be useful to be able to incrementally fill in the hardware
description as we discover it.
This patch adds that ability, by creating dump_stack_add_arch_desc().
If there is no existing string it behaves exactly like
dump_stack_set_arch_desc(). However if there is an existing string it
appends to it, with a leading space.
This makes it easy to call it multiple times from different parts of the
code and get a reasonable looking result.
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
include/linux/printk.h | 5 ++++
lib/dump_stack.c | 58 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+)
v3: No change, just widened Cc list.
v2: Add a smp_wmb() and comment.
v1 is here for reference https://lore.kernel.org/lkml/1430824337-15339-1-git-send-email-mpe@ellerman.id.au/
I'll take this series via the powerpc tree if no one minds?
diff --git a/include/linux/printk.h b/include/linux/printk.h
index 77740a506ebb..d5fb4f960271 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -198,6 +198,7 @@ u32 log_buf_len_get(void);
void log_buf_vmcoreinfo_setup(void);
void __init setup_log_buf(int early);
__printf(1, 2) void dump_stack_set_arch_desc(const char *fmt, ...);
+__printf(1, 2) void dump_stack_add_arch_desc(const char *fmt, ...);
void dump_stack_print_info(const char *log_lvl);
void show_regs_print_info(const char *log_lvl);
extern asmlinkage void dump_stack(void) __cold;
@@ -256,6 +257,10 @@ static inline __printf(1, 2) void dump_stack_set_arch_desc(const char *fmt, ...)
{
}
+static inline __printf(1, 2) void dump_stack_add_arch_desc(const char *fmt, ...)
+{
+}
+
static inline void dump_stack_print_info(const char *log_lvl)
{
}
diff --git a/lib/dump_stack.c b/lib/dump_stack.c
index 5cff72f18c4a..69b710ff92b5 100644
--- a/lib/dump_stack.c
+++ b/lib/dump_stack.c
@@ -35,6 +35,64 @@ void __init dump_stack_set_arch_desc(const char *fmt, ...)
va_end(args);
}
+/**
+ * dump_stack_add_arch_desc - add arch-specific info to show with task dumps
+ * @fmt: printf-style format string
+ * @...: arguments for the format string
+ *
+ * See dump_stack_set_arch_desc() for why you'd want to use this.
+ *
+ * This version adds to any existing string already created with either
+ * dump_stack_set_arch_desc() or dump_stack_add_arch_desc(). If there is an
+ * existing string a space will be prepended to the passed string.
+ */
+void __init dump_stack_add_arch_desc(const char *fmt, ...)
+{
+ va_list args;
+ int pos, len;
+ char *p;
+
+ /*
+ * If there's an existing string we snprintf() past the end of it, and
+ * then turn the terminating NULL of the existing string into a space
+ * to create one string separated by a space.
+ *
+ * If there's no existing string we just snprintf() to the buffer, like
+ * dump_stack_set_arch_desc(), but without calling it because we'd need
+ * a varargs version.
+ */
+ len = strnlen(dump_stack_arch_desc_str, sizeof(dump_stack_arch_desc_str));
+ pos = len;
+
+ if (len)
+ pos++;
+
+ if (pos >= sizeof(dump_stack_arch_desc_str))
+ return; /* Ran out of space */
+
+ p = &dump_stack_arch_desc_str[pos];
+
+ va_start(args, fmt);
+ vsnprintf(p, sizeof(dump_stack_arch_desc_str) - pos, fmt, args);
+ va_end(args);
+
+ if (len) {
+ /*
+ * Order the stores above in vsnprintf() vs the store of the
+ * space below which joins the two strings. Note this doesn't
+ * make the code truly race free because there is no barrier on
+ * the read side. ie. Another CPU might load the uninitialised
+ * tail of the buffer first and then the space below (rather
+ * than the NULL that was there previously), and so print the
+ * uninitialised tail. But the whole string lives in BSS so in
+ * practice it should just see NULLs.
+ */
+ smp_wmb();
+
+ dump_stack_arch_desc_str[len] = ' ';
+ }
+}
+
/**
* dump_stack_print_info - print generic debug info for dump_stack()
* @log_lvl: log level
--
2.20.1
^ permalink raw reply related
* [PATCH v2] powerpc/64: Fix memcmp reading past the end of src/dest
From: Michael Ellerman @ 2019-02-07 11:53 UTC (permalink / raw)
To: linuxppc-dev; +Cc: chandan, daniel, npiggin
Chandan reported that fstests' generic/026 test hit a crash:
BUG: Unable to handle kernel data access at 0xc00000062ac40000
Faulting instruction address: 0xc000000000092240
Oops: Kernel access of bad area, sig: 11 [#1]
LE SMP NR_CPUS=2048 DEBUG_PAGEALLOC NUMA pSeries
CPU: 0 PID: 27828 Comm: chacl Not tainted 5.0.0-rc2-next-20190115-00001-g6de6dba64dda #1
NIP: c000000000092240 LR: c00000000066a55c CTR: 0000000000000000
REGS: c00000062c0c3430 TRAP: 0300 Not tainted (5.0.0-rc2-next-20190115-00001-g6de6dba64dda)
MSR: 8000000002009033 <SF,VEC,EE,ME,IR,DR,RI,LE> CR: 44000842 XER: 20000000
CFAR: 00007fff7f3108ac DAR: c00000062ac40000 DSISR: 40000000 IRQMASK: 0
GPR00: 0000000000000000 c00000062c0c36c0 c0000000017f4c00 c00000000121a660
GPR04: c00000062ac3fff9 0000000000000004 0000000000000020 00000000275b19c4
GPR08: 000000000000000c 46494c4500000000 5347495f41434c5f c0000000026073a0
GPR12: 0000000000000000 c0000000027a0000 0000000000000000 0000000000000000
GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
GPR20: c00000062ea70020 c00000062c0c38d0 0000000000000002 0000000000000002
GPR24: c00000062ac3ffe8 00000000275b19c4 0000000000000001 c00000062ac30000
GPR28: c00000062c0c38d0 c00000062ac30050 c00000062ac30058 0000000000000000
NIP memcmp+0x120/0x690
LR xfs_attr3_leaf_lookup_int+0x53c/0x5b0
Call Trace:
xfs_attr3_leaf_lookup_int+0x78/0x5b0 (unreliable)
xfs_da3_node_lookup_int+0x32c/0x5a0
xfs_attr_node_addname+0x170/0x6b0
xfs_attr_set+0x2ac/0x340
__xfs_set_acl+0xf0/0x230
xfs_set_acl+0xd0/0x160
set_posix_acl+0xc0/0x130
posix_acl_xattr_set+0x68/0x110
__vfs_setxattr+0xa4/0x110
__vfs_setxattr_noperm+0xac/0x240
vfs_setxattr+0x128/0x130
setxattr+0x248/0x600
path_setxattr+0x108/0x120
sys_setxattr+0x28/0x40
system_call+0x5c/0x70
Instruction dump:
7d201c28 7d402428 7c295040 38630008 38840008 408201f0 4200ffe8 2c050000
4182ff6c 20c50008 54c61838 7d201c28 <7d402428> 7d293436 7d4a3436 7c295040
The instruction dump decodes as:
subfic r6,r5,8
rlwinm r6,r6,3,0,28
ldbrx r9,0,r3
ldbrx r10,0,r4 <-
Which shows us doing an 8 byte load from c00000062ac3fff9, which
crosses the page boundary at c00000062ac40000 and faults.
It's not OK for memcmp to read past the end of the source or
destination buffers.
The bug is in the code at the .Lcmp_rest_lt8bytes label. To fix it
test if we have at least 4 bytes to compare and if so do a 4 byte load
and compare. Otherwise, and/or if we have anything left, jump to the
existing code that does byte at a time comparison.
Reported-by: Chandan Rajendra <chandan@linux.ibm.com>
Tested-by: Chandan Rajendra <chandan@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
v2: Use cmpdi not cmpwi as pointed out by Nick. It's a 64-bit reg so
it's clearer to use a 64-bit compare, even if we know the value is
less than 8.
arch/powerpc/lib/memcmp_64.S | 33 +++++++++++++++++++++------------
1 file changed, 21 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/lib/memcmp_64.S b/arch/powerpc/lib/memcmp_64.S
index 844d8e774492..ce4d6ca3a401 100644
--- a/arch/powerpc/lib/memcmp_64.S
+++ b/arch/powerpc/lib/memcmp_64.S
@@ -215,20 +215,29 @@ _GLOBAL_TOC(memcmp)
beq .Lzero
.Lcmp_rest_lt8bytes:
- /* Here we have only less than 8 bytes to compare with. at least s1
- * Address is aligned with 8 bytes.
- * The next double words are load and shift right with appropriate
- * bits.
+ /*
+ * Here we have less than 8 bytes left to compare with. We mustn't read
+ * past the end of either source or dest.
*/
- subfic r6,r5,8
- slwi r6,r6,3
- LD rA,0,r3
- LD rB,0,r4
- srd rA,rA,r6
- srd rB,rB,r6
- cmpld cr0,rA,rB
+
+ /* If we have less than 4 bytes, just do byte at a time */
+ cmpdi cr1, r5, 4
+ blt cr1, .Lshort
+
+ /* Compare 4 bytes */
+ LW rA,0,r3
+ LW rB,0,r4
+ cmplw cr0,rA,rB
bne cr0,.LcmpAB_lightweight
- b .Lzero
+
+ /* If we had exactly 4 bytes left, we're done now */
+ beq cr1, .Lzero
+
+ /* Otherwise do what ever's left a byte at a time */
+ subi r5, r5, 4
+ addi r3, r3, 4
+ addi r4, r4, 4
+ b .Lshort
.Lnon_zero:
mr r3,rC
--
2.20.1
^ permalink raw reply related
* Re: [PATCH v3 1/2] mm: add probe_user_read()
From: Jann Horn @ 2019-02-07 10:26 UTC (permalink / raw)
To: Christophe Leroy
Cc: Kees Cook, kernel list, Mike Rapoport, Linux-MM, Paul Mackerras,
Andrew Morton, linuxppc-dev
In-Reply-To: <39fb6c5a191025378676492e140dc012915ecaeb.1547652372.git.christophe.leroy@c-s.fr>
On Thu, Feb 7, 2019 at 10:22 AM Christophe Leroy
<christophe.leroy@c-s.fr> wrote:
> In powerpc code, there are several places implementing safe
> access to user data. This is sometimes implemented using
> probe_kernel_address() with additional access_ok() verification,
> sometimes with get_user() enclosed in a pagefault_disable()/enable()
> pair, etc. :
> show_user_instructions()
> bad_stack_expansion()
> p9_hmi_special_emu()
> fsl_pci_mcheck_exception()
> read_user_stack_64()
> read_user_stack_32() on PPC64
> read_user_stack_32() on PPC32
> power_pmu_bhrb_to()
>
> In the same spirit as probe_kernel_read(), this patch adds
> probe_user_read().
>
> probe_user_read() does the same as probe_kernel_read() but
> first checks that it is really a user address.
>
> The patch defines this function as a static inline so the "size"
> variable can be examined for const-ness by the check_object_size()
> in __copy_from_user_inatomic()
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> ---
> v3: Moved 'Returns:" comment after description.
> Explained in the commit log why the function is defined static inline
>
> v2: Added "Returns:" comment and removed probe_user_address()
>
> include/linux/uaccess.h | 34 ++++++++++++++++++++++++++++++++++
> 1 file changed, 34 insertions(+)
>
> diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
> index 37b226e8df13..ef99edd63da3 100644
> --- a/include/linux/uaccess.h
> +++ b/include/linux/uaccess.h
> @@ -263,6 +263,40 @@ extern long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count);
> #define probe_kernel_address(addr, retval) \
> probe_kernel_read(&retval, addr, sizeof(retval))
>
> +/**
> + * probe_user_read(): safely attempt to read from a user location
> + * @dst: pointer to the buffer that shall take the data
> + * @src: address to read from
> + * @size: size of the data chunk
> + *
> + * Safely read from address @src to the buffer at @dst. If a kernel fault
> + * happens, handle that and return -EFAULT.
> + *
> + * We ensure that the copy_from_user is executed in atomic context so that
> + * do_page_fault() doesn't attempt to take mmap_sem. This makes
> + * probe_user_read() suitable for use within regions where the caller
> + * already holds mmap_sem, or other locks which nest inside mmap_sem.
> + *
> + * Returns: 0 on success, -EFAULT on error.
> + */
> +
> +#ifndef probe_user_read
> +static __always_inline long probe_user_read(void *dst, const void __user *src,
> + size_t size)
> +{
> + long ret;
> +
> + if (!access_ok(src, size))
> + return -EFAULT;
If this happens in code that's running with KERNEL_DS, the access_ok()
is a no-op. If this helper is only intended for accessing real
userspace memory, it would be more robust to add
set_fs(USER_DS)/set_fs(oldfs) around this thing. Looking at the
functions you're referring to in the commit message, e.g.
show_user_instructions() does an explicit `__access_ok(pc,
NR_INSN_TO_PRINT * sizeof(int), USER_DS)` to get the same effect.
(However, __access_ok() looks like it's horribly broken on x86 from
what I can tell, because it's going to use the generic version that
always returns 1...)
> + pagefault_disable();
> + ret = __copy_from_user_inatomic(dst, src, size);
> + pagefault_enable();
> +
> + return ret ? -EFAULT : 0;
> +}
> +#endif
> +
> #ifndef user_access_begin
> #define user_access_begin(ptr,len) access_ok(ptr, len)
> #define user_access_end() do { } while (0)
> --
> 2.13.3
>
>
^ permalink raw reply
* Re: [PATCH 2/2] powerpc: Fix defconfig choice logic when cross compiling
From: Mathieu Malaterre @ 2019-02-07 10:19 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev
In-Reply-To: <20190207051652.11380-2-mpe@ellerman.id.au>
On Thu, Feb 7, 2019 at 6:20 AM Michael Ellerman <mpe@ellerman.id.au> wrote:
>
> Our logic for choosing defconfig doesn't work well in some situations.
>
> For example if you're on a ppc64le machine but you specify a non-empty
> CROSS_COMPILE, in order to use a non-default toolchain, then defconfig
> will give you ppc64_defconfig (big endian):
>
> $ make CROSS_COMPILE=~/toolchains/gcc-8/bin/powerpc-linux- defconfig
> *** Default configuration is based on 'ppc64_defconfig'
>
> This is because we assume that CROSS_COMPILE being set means we
> can't be on a ppc machine and rather than checking we just default to
> ppc64_defconfig.
>
> We should just ignore CROSS_COMPILE, instead check the machine with
> uname and if it's one of ppc, ppc64 or ppc64le then use that
> defconfig. If it's none of those then we fall back to ppc64_defconfig.
How about shamelessly copying x86:
diff --git a/Makefile b/Makefile
index 3142e67d03f1..041616742142 100644
--- a/Makefile
+++ b/Makefile
@@ -351,6 +351,14 @@ ifeq ($(ARCH),sparc64)
SRCARCH := sparc
endif
+# Additional ARCH settings for ppc
+ifeq ($(ARCH),ppc64)
+ SRCARCH := powerpc
+endif
+ifeq ($(ARCH),ppc64el)
+ SRCARCH := powerpc
+endif
+
# Additional ARCH settings for sh
ifeq ($(ARCH),sh64)
SRCARCH := sh
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 10bf5dc7cdf0..cbb679fb7162 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -34,10 +34,17 @@ ifdef CONFIG_PPC_BOOK3S_32
KBUILD_CFLAGS += -mcpu=powerpc
endif
-# If we're on a ppc/ppc64/ppc64le machine use that defconfig,
otherwise just use
-# ppc64_defconfig because we have nothing better to go on.
-uname := $(shell uname -m)
-KBUILD_DEFCONFIG := $(if $(filter ppc%,$(uname)),$(uname),ppc64)_defconfig
+# select defconfig based on actual architecture
+ifeq ($(ARCH),powerpc)
+ ifeq ($(shell uname -m),ppc64)
+ KBUILD_DEFCONFIG := ppc64_defconfig
+ else
+ KBUILD_DEFCONFIG := ppc_defconfig
+ endif
+else
+ KBUILD_DEFCONFIG := $(ARCH)_defconfig
+endif
+
ifdef CONFIG_PPC64
new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' >
/dev/null; then echo y; else echo n; fi)
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> ---
> arch/powerpc/Makefile | 9 ++++-----
> 1 file changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
> index 70e6e8119aeb..81563986a30e 100644
> --- a/arch/powerpc/Makefile
> +++ b/arch/powerpc/Makefile
> @@ -34,11 +34,10 @@ ifdef CONFIG_PPC_BOOK3S_32
> KBUILD_CFLAGS += -mcpu=powerpc
> endif
>
> -ifeq ($(CROSS_COMPILE),)
> -KBUILD_DEFCONFIG := $(shell uname -m)_defconfig
> -else
> -KBUILD_DEFCONFIG := ppc64_defconfig
> -endif
> +# If we're on a ppc/ppc64/ppc64le machine use that defconfig, otherwise just use
> +# ppc64_defconfig because we have nothing better to go on.
> +uname := $(shell uname -m)
> +KBUILD_DEFCONFIG := $(if $(filter ppc%,$(uname)),$(uname),ppc64)_defconfig
>
> ifdef CONFIG_PPC64
> new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi)
> --
> 2.20.1
>
^ permalink raw reply related
* Re: [PATCH 1/2] powerpc/32: Add ppc_defconfig
From: Mathieu Malaterre @ 2019-02-07 10:17 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev
In-Reply-To: <20190207051652.11380-1-mpe@ellerman.id.au>
On Thu, Feb 7, 2019 at 6:18 AM Michael Ellerman <mpe@ellerman.id.au> wrote:
>
> Add a generic 32-bit defconfig called ppc_defconfig. This means we'll
> have a defconfig matching "uname -m" for all cases.
Looks good to me:
$ make defconfig
*** Default configuration is based on 'ppc_defconfig'
arch/powerpc/configs/ppc_defconfig:175:warning: symbol value 'm'
invalid for NF_TABLES_INET
arch/powerpc/configs/ppc_defconfig:176:warning: symbol value 'm'
invalid for NF_TABLES_NETDEV
arch/powerpc/configs/ppc_defconfig:304:warning: symbol value 'm'
invalid for NF_TABLES_ARP
arch/powerpc/configs/ppc_defconfig:358:warning: symbol value 'm'
invalid for NF_TABLES_BRIDGE
arch/powerpc/configs/ppc_defconfig:1427:warning: symbol value 'm'
invalid for LIRC
#
# configuration written to .config
#
Tested-by: Mathieu Malaterre <malat@debian.org>
> This config is mostly intended for build testing but if someone wants
> to tweak it to get it booting on something that would be fine too.
>
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> ---
> arch/powerpc/Makefile | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
> index ac033341ed55..70e6e8119aeb 100644
> --- a/arch/powerpc/Makefile
> +++ b/arch/powerpc/Makefile
> @@ -367,6 +367,10 @@ PHONY += ppc32_allmodconfig
> $(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/powerpc/configs/book3s_32.config \
> -f $(srctree)/Makefile allmodconfig
>
> +PHONY += ppc_defconfig
> +ppc_defconfig:
> + $(call merge_into_defconfig,book3s_32.config,)
> +
> PHONY += ppc64le_allmodconfig
> ppc64le_allmodconfig:
> $(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/powerpc/configs/le.config \
> --
> 2.20.1
>
^ permalink raw reply
* Re: [PATCH] mtd: powernv: SPDX and comment fixups
From: Boris Brezillon @ 2019-02-07 8:37 UTC (permalink / raw)
To: Joel Stanley
Cc: linuxppc-dev, Marek Vasut, linux-mtd, Richard Weinberger,
Brian Norris, David Woodhouse
In-Reply-To: <20190206003659.27107-1-joel@jms.id.au>
Hello Joel,
On Wed, 6 Feb 2019 11:06:58 +1030
Joel Stanley <joel@jms.id.au> wrote:
> This converts the powernv flash driver to use SPDX, and adds some
> clarifying comments that came out of a discussion on how the mtd driver
> works.
Can you split that in 2 patches, one adding the SPDX header, and the
other one clarifying the driver behavior.
Thanks,
Boris
>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
> drivers/mtd/devices/powernv_flash.c | 20 ++++++++++----------
> 1 file changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/mtd/devices/powernv_flash.c b/drivers/mtd/devices/powernv_flash.c
> index 22f753e555ac..0bf43336c3f7 100644
> --- a/drivers/mtd/devices/powernv_flash.c
> +++ b/drivers/mtd/devices/powernv_flash.c
> @@ -1,17 +1,9 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> /*
> * OPAL PNOR flash MTD abstraction
> *
> * Copyright IBM 2015
> - *
> - * 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.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> - * GNU General Public License for more details.
> */
>
> #include <linux/kernel.h>
> @@ -261,6 +253,14 @@ static int powernv_flash_probe(struct platform_device *pdev)
> * The current flash that skiboot exposes is one contiguous flash chip
> * with an ffs partition at the start, it should prove easier for users
> * to deal with partitions or not as they see fit
> + *
> + * When developing the skiboot MTD driver an experiment with FFS
> + * parsing in the kernel, and exposing a seperate /dev/mtdX for each
> + * partition (eg BOOTKERNEL, PAYLOAD, NVRAM, etc), was done.
> + *
> + * We didn't go with that as it meant users couldn't do a full flash
> + * re-write, as this can cause a partition to change size, and there
> + * wasn't a way to tell the MTD layer that a device has shrunk/grown.
> */
> return mtd_device_register(&data->mtd, NULL, 0);
> }
^ permalink raw reply
* Re: [PATCH v2] powerpc/mm: move a KERN_WARNING message to pr_debug()
From: Laurent Vivier @ 2019-02-07 9:25 UTC (permalink / raw)
To: David Gibson; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20190207030305.GA518@umbus.fritz.box>
On 07/02/2019 04:03, David Gibson wrote:
> On Tue, Feb 05, 2019 at 09:21:33PM +0100, Laurent Vivier wrote:
>> resize_hpt_for_hotplug() reports a warning when it cannot
>> increase the hash page table ("Unable to resize hash page
>> table to target order") but this is not blocking and
>> can make user thinks something has not worked properly.
>> As we move the message to the debug area, report again the
>> ENODEV error.
>>
>> If the operation cannot be done the real error message
>> will be reported by arch_add_memory() if create_section_mapping()
>> fails.
>>
>> Fixes: 7339390d772dd
>> powerpc/pseries: Don't give a warning when HPT resizing isn't available
>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>
> Sorry, I'm pretty dubious about this. It's true that in the case for
> which this bug was filed this is a harmless situation which deserves a
> pr_debug() at most.
>
> But that's not necessarily true in all paths leading to this message.
> It will also trip if we fail to reshrink the HPT after genuinely
> hotunplugging a bunch of memory, in which case failing to release
> expected resources does deserve a warning.
But if there is a real problem this function should return an error and
this error should be managed by the caller.
Moreover, the function that can fail (pseries_lpar_resize_hpt()) has
already a warning for each error case:
ETIMEDOUT: "Unexpected error %d cancelling timed out HPT resize\n"
EIO: "Unexpected error %d from H_RESIZE_HPT_PREPARE\n"
"Unexpected error %d from H_RESIZE_HPT_COMMIT\n
ENOSPC: "Hash collision while resizing HPT\n"
ENODEV has no error message but is already silently ignored.
EINVAL and EPERM have no message but this happens if hcall is not used
correctly and deserve only a pr_debug() I think.
Thanks,
Laurent
^ permalink raw reply
* Re: [PATCH 15/19] KVM: PPC: Book3S HV: add get/set accessors for the source configuration
From: Cédric Le Goater @ 2019-02-07 9:13 UTC (permalink / raw)
To: David Gibson; +Cc: kvm, kvm-ppc, Paul Mackerras, linuxppc-dev
In-Reply-To: <20190207024855.GZ22661@umbus.fritz.box>
On 2/7/19 3:48 AM, David Gibson wrote:
> On Wed, Feb 06, 2019 at 08:07:36AM +0100, Cédric Le Goater wrote:
>> On 2/6/19 2:24 AM, David Gibson wrote:
>>> On Wed, Feb 06, 2019 at 12:23:29PM +1100, David Gibson wrote:
>>>> On Tue, Feb 05, 2019 at 02:03:11PM +0100, Cédric Le Goater wrote:
>>>>> On 2/5/19 6:32 AM, David Gibson wrote:
>>>>>> On Mon, Feb 04, 2019 at 05:07:28PM +0100, Cédric Le Goater wrote:
>>>>>>> On 2/4/19 6:21 AM, David Gibson wrote:
>>>>>>>> On Mon, Jan 07, 2019 at 07:43:27PM +0100, Cédric Le Goater wrote:
>>>>>>>>> Theses are use to capure the XIVE EAS table of the KVM device, the
>>>>>>>>> configuration of the source targets.
>>>>>>>>>
>>>>>>>>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>>>>>>>>> ---
>>>>>>>>> arch/powerpc/include/uapi/asm/kvm.h | 11 ++++
>>>>>>>>> arch/powerpc/kvm/book3s_xive_native.c | 87 +++++++++++++++++++++++++++
>>>>>>>>> 2 files changed, 98 insertions(+)
>>>>>>>>>
>>>>>>>>> diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
>>>>>>>>> index 1a8740629acf..faf024f39858 100644
>>>>>>>>> --- a/arch/powerpc/include/uapi/asm/kvm.h
>>>>>>>>> +++ b/arch/powerpc/include/uapi/asm/kvm.h
>>>>>>>>> @@ -683,9 +683,20 @@ struct kvm_ppc_cpu_char {
>>>>>>>>> #define KVM_DEV_XIVE_SAVE_EQ_PAGES 4
>>>>>>>>> #define KVM_DEV_XIVE_GRP_SOURCES 2 /* 64-bit source attributes */
>>>>>>>>> #define KVM_DEV_XIVE_GRP_SYNC 3 /* 64-bit source attributes */
>>>>>>>>> +#define KVM_DEV_XIVE_GRP_EAS 4 /* 64-bit eas attributes */
>>>>>>>>>
>>>>>>>>> /* Layout of 64-bit XIVE source attribute values */
>>>>>>>>> #define KVM_XIVE_LEVEL_SENSITIVE (1ULL << 0)
>>>>>>>>> #define KVM_XIVE_LEVEL_ASSERTED (1ULL << 1)
>>>>>>>>>
>>>>>>>>> +/* Layout of 64-bit eas attribute values */
>>>>>>>>> +#define KVM_XIVE_EAS_PRIORITY_SHIFT 0
>>>>>>>>> +#define KVM_XIVE_EAS_PRIORITY_MASK 0x7
>>>>>>>>> +#define KVM_XIVE_EAS_SERVER_SHIFT 3
>>>>>>>>> +#define KVM_XIVE_EAS_SERVER_MASK 0xfffffff8ULL
>>>>>>>>> +#define KVM_XIVE_EAS_MASK_SHIFT 32
>>>>>>>>> +#define KVM_XIVE_EAS_MASK_MASK 0x100000000ULL
>>>>>>>>> +#define KVM_XIVE_EAS_EISN_SHIFT 33
>>>>>>>>> +#define KVM_XIVE_EAS_EISN_MASK 0xfffffffe00000000ULL
>>>>>>>>> +
>>>>>>>>> #endif /* __LINUX_KVM_POWERPC_H */
>>>>>>>>> diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c
>>>>>>>>> index f2de1bcf3b35..0468b605baa7 100644
>>>>>>>>> --- a/arch/powerpc/kvm/book3s_xive_native.c
>>>>>>>>> +++ b/arch/powerpc/kvm/book3s_xive_native.c
>>>>>>>>> @@ -525,6 +525,88 @@ static int kvmppc_xive_native_sync(struct kvmppc_xive *xive, long irq, u64 addr)
>>>>>>>>> return 0;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> +static int kvmppc_xive_native_set_eas(struct kvmppc_xive *xive, long irq,
>>>>>>>>> + u64 addr)
>>>>>>>>
>>>>>>>> I'd prefer to avoid the name "EAS" here. IIUC these aren't "raw" EAS
>>>>>>>> values, but rather essentially the "source config" in the terminology
>>>>>>>> of the PAPR hcalls. Which, yes, is basically implemented by setting
>>>>>>>> the EAS, but since it's the PAPR architected state that we need to
>>>>>>>> preserve across migration, I'd prefer to stick as close as we can to
>>>>>>>> the PAPR terminology.
>>>>>>>
>>>>>>> But we don't have an equivalent name in the PAPR specs for the tuple
>>>>>>> (prio, server). We could use the generic 'target' name may be ? even
>>>>>>> if this is usually referring to a CPU number.
>>>>>>
>>>>>> Um.. what? That's about terminology for one of the fields in this
>>>>>> thing, not about the name for the thing itself.
>>>>>>
>>>>>>> Or, IVE (Interrupt Vector Entry) ? which makes some sense.
>>>>>>> This is was the former name in HW. I think we recycle it for KVM.
>>>>>>
>>>>>> That's a terrible idea, which will make a confusing situation even
>>>>>> more confusing.
>>>>>
>>>>> Let's use SOURCE_CONFIG and QUEUE_CONFIG. The KVM ioctls are very
>>>>> similar to the hcalls anyhow.
>>>>
>>>> Yes, I think that's a good idea.
>>>
>>> Actually... AIUI the SET_CONFIG hcalls shouldn't be a fast path.
>>
>> No indeed. I have move them to standard hcalls in the current version.
>>
>>> Can
>>> we simplify things further by removing the hcall implementation from
>>> the kernel entirely, and have qemu implement them by basically just
>>> forwarding them to the appropriate SET_CONFIG ioctl()?
>>
>> Yes. I think we could.
>
> Great!
>
>> The hcalls H_INT_SET_SOURCE_CONFIG and H_INT_SET_QUEUE_CONFIG and
>> the KVM ioctls to set the EQ and the SOURCE configuration have a
>> lot in common. I need to look at how we can plug the KVM ioctl in
>> the hcalls under QEMU.
>>
>> We will have to convert the returned error to respect the PAPR
>> specs or have the ioctls return H_* errors.
>
> I don't think returning H_* values from a kernel call is a good idea.
> Converting errors is kinda ugly, but I still think it's the better
> option. Note that we already have something like this for the HPT
> resizing hcalls.
ok.
>> Let's dig that idea. If we choose that path, QEMU will have an
>> up-to-date EAT and so we won't need to synchronize its state anymore
>> for migration.
>
> I guess so, though I don't see that as essential.
>
>> H_INT_GET_SOURCE_CONFIG can be implemented in QEMU without any KVM
>> ioctl.
>>
>> H_INT_GET_QUEUE_INFO could be implemented in QEMU. I need to check
>> how we return the address of the END ESB in sPAPR. We haven't paid
>> much attention to these pages because they are not used under Linux
>> and today the address is returned by OPAL.
>>
>> H_INT_GET_QUEUE_CONFIG is a little more problematic because we need
>> to query into the XIVE HW the EQ index and toggle bit. OPAL support
>> is required for that. But we could reduce the KVM support to the
>> ioctl querying these EQ information.
>
> Right, and we'd need an ioctl() like that for migration anyway, yes?
Yes. it is the same need.
>> H_INT_ESB could be entirely done under QEMU.
>
> This one can actually happen on fairly hot paths, so I think doing
> that in qemu probably isn't a good idea.
I agree It would nice to have some performance.
This hcall is used when LSIs are involved, which is not really a common
configuration. There are no OPAL calls involved. And we are duplicating
code at the KVM level to retrigger the interrupt when the level is still
asserted.
I will benchmark the two options before making a choice.
C.
>> H_INT_SYNC and H_INT_RESET can not.
>>
>> H_INT_GET_OS_REPORTING_LINE and H_INT_SET_OS_REPORTING_LINE are not
>> implemented.
>>
>> C.
>>
>
^ permalink raw reply
* Re: [PATCH v2] powerpc/mm: move a KERN_WARNING message to pr_debug()
From: Laurent Vivier @ 2019-02-07 9:13 UTC (permalink / raw)
To: Michael Ellerman, linux-kernel; +Cc: linuxppc-dev, David Gibson
In-Reply-To: <8736p0kyiy.fsf@concordia.ellerman.id.au>
On 07/02/2019 05:33, Michael Ellerman wrote:
> Hi Laurent,
>
> I'm not sure I'm convinced about this one. It seems like we're just
> throwing away the warning because it's annoying.
>
> Laurent Vivier <lvivier@redhat.com> writes:
>> resize_hpt_for_hotplug() reports a warning when it cannot
>> increase the hash page table ("Unable to resize hash page
>> table to target order") but this is not blocking and
>> can make user thinks something has not worked properly.
>
> Something did not work properly, the resize didn't work properly. Right?
>
>> As we move the message to the debug area, report again the
>> ENODEV error.
>>
>> If the operation cannot be done the real error message
>> will be reported by arch_add_memory() if create_section_mapping()
>> fails.
>
> Can you explain that more. Isn't the fact that the resize failed "the
> real error message"?
In arch_add_memory(), after calling resize_hpt_for_hotplug() it calls
create_section_mapping() and if create_section_mapping() fails we will
have the error message "Unable to create mapping for hot added memory"
and the real exit (EFAULT).
>
>> Fixes: 7339390d772dd
>> powerpc/pseries: Don't give a warning when HPT resizing isn't available
>
> This should all be on one line, and formatted as:
>
> Fixes: 7339390d772d ("powerpc/pseries: Don't give a warning when HPT resizing isn't available")
>
> See Documentation/process/submitting-patches.rst for more info and how
> to configure git to do it automatically for you.
Thank you, I didn't know the format was documented.
Thanks,
Laurent
^ permalink raw reply
* Re: [PATCH 06/19] KVM: PPC: Book3S HV: add a GET_ESB_FD control to the XIVE native device
From: Cédric Le Goater @ 2019-02-07 9:03 UTC (permalink / raw)
To: David Gibson; +Cc: kvm, kvm-ppc, Paul Mackerras, linuxppc-dev
In-Reply-To: <20190207024950.GA22661@umbus.fritz.box>
On 2/7/19 3:49 AM, David Gibson wrote:
> On Wed, Feb 06, 2019 at 08:21:10AM +0100, Cédric Le Goater wrote:
>> On 2/6/19 2:23 AM, David Gibson wrote:
>>> On Tue, Feb 05, 2019 at 01:55:40PM +0100, Cédric Le Goater wrote:
>>>> On 2/5/19 6:28 AM, David Gibson wrote:
>>>>> On Mon, Feb 04, 2019 at 12:30:39PM +0100, Cédric Le Goater wrote:
>>>>>> On 2/4/19 5:45 AM, David Gibson wrote:
>>>>>>> On Mon, Jan 07, 2019 at 07:43:18PM +0100, Cédric Le Goater wrote:
>>>>>>>> This will let the guest create a memory mapping to expose the ESB MMIO
>>>>>>>> regions used to control the interrupt sources, to trigger events, to
>>>>>>>> EOI or to turn off the sources.
>>>>>>>>
>>>>>>>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>>>>>>>> ---
>>>>>>>> arch/powerpc/include/uapi/asm/kvm.h | 4 ++
>>>>>>>> arch/powerpc/kvm/book3s_xive_native.c | 97 +++++++++++++++++++++++++++
>>>>>>>> 2 files changed, 101 insertions(+)
>>>>>>>>
>>>>>>>> diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
>>>>>>>> index 8c876c166ef2..6bb61ba141c2 100644
>>>>>>>> --- a/arch/powerpc/include/uapi/asm/kvm.h
>>>>>>>> +++ b/arch/powerpc/include/uapi/asm/kvm.h
>>>>>>>> @@ -675,4 +675,8 @@ struct kvm_ppc_cpu_char {
>>>>>>>> #define KVM_XICS_PRESENTED (1ULL << 43)
>>>>>>>> #define KVM_XICS_QUEUED (1ULL << 44)
>>>>>>>>
>>>>>>>> +/* POWER9 XIVE Native Interrupt Controller */
>>>>>>>> +#define KVM_DEV_XIVE_GRP_CTRL 1
>>>>>>>> +#define KVM_DEV_XIVE_GET_ESB_FD 1
>>>>>>>
>>>>>>> Introducing a new FD for ESB and TIMA seems overkill. Can't you get
>>>>>>> to both with an mmap() directly on the xive device fd? Using the
>>>>>>> offset to distinguish which one to map, obviously.
>>>>>>
>>>>>> The page offset would define some sort of user API. It seems feasible.
>>>>>> But I am not sure this would be practical in the future if we need to
>>>>>> tune the length.
>>>>>
>>>>> Um.. why not? I mean, yes the XIVE supports rather a lot of
>>>>> interrupts, but we have 64-bits of offset we can play with - we can
>>>>> leave room for billions of ESB slots and still have room for billions
>>>>> of VPs.
>>>>
>>>> So the first 4 pages could be the TIMA pages and then would come
>>>> the pages for the interrupt ESBs. I think that we can have different
>>>> vm_fault handler for each mapping.
>>>
>>> Um.. no, I'm saying you don't need to tightly pack them. So you could
>>> have the ESB pages at 0, the TIMA at, say offset 2^60.
>>
>> Well, we know that the TIMA is 4 pages wide and is "directly" related
>> with the KVM interrupt device. So being at offset 0 seems a good idea.
>> While the ESB segment is of a variable size depending on the number
>> of IRQs and it can come after I think.
>>
>>>> I wonder how this will work out with pass-through. As Paul said in
>>>> a previous email, it would be better to let QEMU request a new
>>>> mapping to handle the ESB pages of the device being passed through.
>>>> I guess this is not a special case, just another offset and length.
>>>
>>> Right, if we need multiple "chunks" of ESB pages we can given them
>>> each their own terabyte or several. No need to be stingy with address
>>> space.
>>
>> You can not put them anywhere. They should map the same interrupt range
>> of ESB pages, overlapping with the underlying segment of IPI ESB pages.
>
> I don't really follow what you're saying here.
What we want the guest to access in terms of ESB pages is something like
below, VMA0 being the initial mapping done by QEMU at offset 0x0, the IPI
ESB pages being populated on the demand with the loads and the stores from
the guest :
0x0 0x1100 0x1200 0x1300
ranges | CPU IPIs .. | VIO | PCI LSI | MSIs
+-+-+-+-+-+-+-...-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- ....
VMA0 IPI ESB | | | | | | | | | | | | | | | | | | | | | | | | |
pages +-+-+-+-+-+-+-...-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- ....
A device is passed through and the driver requests MSIs.
We now want the guest to access the HW ESB pages for the requested IRQs
but still the initial IPI ESB pages for the others. Something like below :
0x0 0x1100 0x1200 0x1300
ranges | CPU IPIs .. | VIO | PCI LSI | MSIs
+-+-+-+-+-+-+-...-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- ....
VMA0 IPI ESB | | | | | | | | | | | | | | | | | | | | | | | | |
pages +-+-+-+-+-+-+-...-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- ....
VMA1 PHB ESB +-------+
pages | | | | |
+-------+
The VMA1 is the result of a new mmap() being done at an offset depending on
the first IRQ number requested by the driver.
This is because the vm_fault handler uses the page offset to find the
associated KVM IRQ struct containing the addresses of the EOI and trigger
pages in the underlying hardware, which will be the PHB in case of a
passthrough device.
From there, the VMA1 mmap() pointer will be used to create a 'ram device'
memory region which will be mapped on top of the initial ESB memory region
in QEMU. This will override the initial IPI ESB pages with the PHB ESB pages
in the guest ESB address space.
That's the plan I have in mind as suggested by Paul if I understood it well.
The mechanics are more complex than the patch zapping the PTEs from the VMA
but it's also safer.
C.
^ permalink raw reply
* Re: [PATCH 00/19] KVM: PPC: Book3S HV: add XIVE native exploitation mode
From: Cédric Le Goater @ 2019-02-07 8:31 UTC (permalink / raw)
To: David Gibson; +Cc: kvm, kvm-ppc, linuxppc-dev
In-Reply-To: <20190207025111.GB22661@umbus.fritz.box>
On 2/7/19 3:51 AM, David Gibson wrote:
> On Wed, Feb 06, 2019 at 08:35:24AM +0100, Cédric Le Goater wrote:
>> On 2/6/19 2:18 AM, David Gibson wrote:
>>> On Wed, Feb 06, 2019 at 09:13:15AM +1100, Paul Mackerras wrote:
>>>> On Tue, Feb 05, 2019 at 12:31:28PM +0100, Cédric Le Goater wrote:
>>>>>>>> As for nesting, I suggest for the foreseeable future we stick to XICS
>>>>>>>> emulation in nested guests.
>>>>>>>
>>>>>>> ok. so no kernel_irqchip at all. hmm.
>>>>>
>>>>> I was confused with what Paul calls 'XICS emulation'. It's not the QEMU
>>>>> XICS emulated device but the XICS-over-XIVE KVM device, the KVM XICS
>>>>> device KVM uses when under a P9 processor.
>>>>
>>>> Actually there are two separate implementations of XICS emulation in
>>>> KVM. The first (older) one is almost entirely a software emulation
>>>> but does have some cases where it accesses an underlying XICS device
>>>> in order to make some things faster (IPIs and pass-through of a device
>>>> interrupt to a guest). The other, newer one is the XICS-on-XIVE
>>>> emulation that Ben wrote, which uses the XIVE hardware pretty heavily.
>>>> My patch was about making the the older code work when there is no
>>>> XICS available to the host.
>>>
>>> Ah, right. To clarify my earlier statements in light of this:
>>>
>>> * We definitely want some sort of kernel-XICS available in a nested
>>> guest. AIUI, this is now accomplished, so, Yay!
>>>
>>> * Implementing the L2 XICS in terms of L1's PAPR-XIVE would be a
>>> bonus, but it's a much lower priority.
>>
>> Yes. In this case, the L1 KVM-HV should not advertise KVM_CAP_PPC_IRQ_XIVE
>> to QEMU which will restrict CAS to the XICS only interrupt mode.
>
> Uh... no... we shouldn't change what's available to the guest based on
> host configuration only. We should just stop advertising the CAP
> saying that *KVM implemented* is available
yes. that is what I meant.
> so that qemu will fall back to userspace XIVE emulation.
even if kernel_irqchip is required ?
Today, QEMU just fails to start. With the dual mode, the interrupt mode
is negotiated at CAS time and when merged, the KVM device will be created
at reset. In case of failure, QEMU will abort.
I am not saying it is not possible but we will need some internal
infrastructure to handle dynamically the fall back to userspace emulation.
C.
^ permalink raw reply
* Re: [PATCH] powerpc/44x: Force PCI on for CURRITUCK
From: Geert Uytterhoeven @ 2019-02-07 8:18 UTC (permalink / raw)
To: Michael Ellerman
Cc: Bjorn Helgaas, Linuxppc-dev, Randy Dunlap, Christoph Hellwig
In-Reply-To: <20190207024935.30456-1-mpe@ellerman.id.au>
Hi Michael,
On Thu, Feb 7, 2019 at 3:49 AM Michael Ellerman <mpe@ellerman.id.au> wrote:
> The recent rework of PCI kconfig symbols exposed an existing bug in
> the CURRITUCK kconfig logic.
>
> It selects PPC4xx_PCI_EXPRESS which depends on PCI, but PCI is user
> selectable and might be disabled, leading to a warning:
>
> WARNING: unmet direct dependencies detected for PPC4xx_PCI_EXPRESS
> Depends on [n]: PCI [=n] && 4xx [=y]
> Selected by [y]:
> - CURRITUCK [=y] && PPC_47x [=y]
>
> Prior to commit eb01d42a7778 ("PCI: consolidate PCI config entry in
> drivers/pci") PCI was enabled by default for currituck_defconfig so we
> didn't see the warning. The bad logic was still there, it just
> required someone disabling PCI in their .config to hit it.
>
> Fix it by forcing PCI on for CURRITUCK, which seems was always the
> expectation anyway.
>
> Fixes: eb01d42a7778 ("PCI: consolidate PCI config entry in drivers/pci")
> Reported-by: Randy Dunlap <rdunlap@infradead.org>
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> ---
> arch/powerpc/platforms/44x/Kconfig | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
> index 4a9a72d01c3c..35be81fd2dc2 100644
> --- a/arch/powerpc/platforms/44x/Kconfig
> +++ b/arch/powerpc/platforms/44x/Kconfig
> @@ -180,6 +180,7 @@ config CURRITUCK
> depends on PPC_47x
> select SWIOTLB
> select 476FPE
> + select FORCE_PCI
> select PPC4xx_PCI_EXPRESS
Would "select PPC4xx_PCI_EXPRESS if PCI" be a suitable alternative?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH 1/2] powerpc/64s: Work around spurious warning on old gccs with -fsanitize-coverage
From: Segher Boessenkool @ 2019-02-07 7:49 UTC (permalink / raw)
To: Andrew Donnellan; +Cc: syzkaller, linuxppc-dev, dvyukov
In-Reply-To: <630e392b-e9a7-6b1e-e3d8-c5382f94e5d7@au1.ibm.com>
On Thu, Feb 07, 2019 at 05:59:48PM +1100, Andrew Donnellan wrote:
> On 7/2/19 5:37 pm, Segher Boessenkool wrote:
> >On Thu, Feb 07, 2019 at 04:33:23PM +1100, Andrew Donnellan wrote:
> >>Some older gccs (<GCC 7), when invoked with -fsanitize-coverage=trace-pc,
> >>cause a spurious uninitialised variable warning in dt_cpu_ftrs.c:
> >>
> >> arch/powerpc/kernel/dt_cpu_ftrs.c: In function
> >> ‘cpufeatures_process_feature’:
> >> arch/powerpc/kernel/dt_cpu_ftrs.c:686:7: warning: ‘m’ may be used
> >> uninitialized in this function [-Wmaybe-uninitialized]
> >> if (m->cpu_ftr_bit_mask)
> >
> >It seems to me the warning is correct? If enable_unknown is false and no
> >cpu_feature is found, it will in
> >
> > if (m->cpu_ftr_bit_mask)
> > cur_cpu_spec->cpu_features |= m->cpu_ftr_bit_mask;
> >
> >enable random features (whatever was last in the table), or indeed access
> >via NULL if the table is length 0? So maybe this should be
> >
> > if (known && m->cpu_ftr_bit_mask)
> > cur_cpu_spec->cpu_features |= m->cpu_ftr_bit_mask;
> >
> >instead? (The code would be much clearer if all the known vs. !known
> >codepath was fully separated here).
>
> The table is never length 0, it's a statically defined array.
Sure, and presumably that is why newer GCC doesn't warn. But what about
the other point? Is this code ever correct? Enabling random features
(in cur_cpu_spec->cpu_features) when the name isn't found seems wrong.
Segher
^ permalink raw reply
* [PATCH v3 5/5] powerpc/perf: Trace imc PMU functions
From: Anju T Sudhakar @ 2019-02-07 7:03 UTC (permalink / raw)
To: mpe; +Cc: maddy, linuxppc-dev, linux-kernel, anju
In-Reply-To: <20190207070312.5150-1-anju@linux.vnet.ibm.com>
Add PMU functions to support trace-imc and define the format for
trace-imc events.
Signed-off-by: Anju T Sudhakar <anju@linux.vnet.ibm.com>
Reviewed-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/perf/imc-pmu.c | 197 +++++++++++++++++++++++++++++++++++-
1 file changed, 196 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index 1f09265c8fb0..0f1a30f11f6a 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -52,7 +52,7 @@ static struct imc_pmu *imc_event_to_pmu(struct perf_event *event)
return container_of(event->pmu, struct imc_pmu, pmu);
}
-PMU_FORMAT_ATTR(event, "config:0-40");
+PMU_FORMAT_ATTR(event, "config:0-61");
PMU_FORMAT_ATTR(offset, "config:0-31");
PMU_FORMAT_ATTR(rvalue, "config:32");
PMU_FORMAT_ATTR(mode, "config:33-40");
@@ -69,6 +69,25 @@ static struct attribute_group imc_format_group = {
.attrs = imc_format_attrs,
};
+/* Format attribute for imc trace-mode */
+PMU_FORMAT_ATTR(cpmc_reserved, "config:0-19");
+PMU_FORMAT_ATTR(cpmc_event, "config:20-27");
+PMU_FORMAT_ATTR(cpmc_samplesel, "config:28-29");
+PMU_FORMAT_ATTR(cpmc_load, "config:30-61");
+static struct attribute *trace_imc_format_attrs[] = {
+ &format_attr_event.attr,
+ &format_attr_cpmc_reserved.attr,
+ &format_attr_cpmc_event.attr,
+ &format_attr_cpmc_samplesel.attr,
+ &format_attr_cpmc_load.attr,
+ NULL,
+};
+
+static struct attribute_group trace_imc_format_group = {
+ .name = "format",
+ .attrs = trace_imc_format_attrs,
+};
+
/* Get the cpumask printed to a buffer "buf" */
static ssize_t imc_pmu_cpumask_get_attr(struct device *dev,
struct device_attribute *attr,
@@ -1120,6 +1139,173 @@ static int trace_imc_cpu_init(void)
ppc_trace_imc_cpu_offline);
}
+static u64 get_trace_imc_event_base_addr(void)
+{
+ return (u64)per_cpu(trace_imc_mem, smp_processor_id());
+}
+
+/*
+ * Function to parse trace-imc data obtained
+ * and to prepare the perf sample.
+ */
+static int trace_imc_prepare_sample(struct trace_imc_data *mem,
+ struct perf_sample_data *data,
+ u64 *prev_tb,
+ struct perf_event_header *header,
+ struct perf_event *event)
+{
+ /* Sanity checks for a valid record */
+ if (be64_to_cpu(READ_ONCE(mem->tb1)) > *prev_tb)
+ *prev_tb = be64_to_cpu(READ_ONCE(mem->tb1));
+ else
+ return -EINVAL;
+
+ if ((be64_to_cpu(READ_ONCE(mem->tb1)) & IMC_TRACE_RECORD_TB1_MASK) !=
+ be64_to_cpu(READ_ONCE(mem->tb2)))
+ return -EINVAL;
+
+ /* Prepare perf sample */
+ data->ip = be64_to_cpu(READ_ONCE(mem->ip));
+ data->period = event->hw.last_period;
+
+ header->type = PERF_RECORD_SAMPLE;
+ header->size = sizeof(*header) + event->header_size;
+ header->misc = 0;
+
+ if (is_kernel_addr(data->ip))
+ header->misc |= PERF_RECORD_MISC_KERNEL;
+ else
+ header->misc |= PERF_RECORD_MISC_USER;
+
+ perf_event_header__init_id(header, data, event);
+
+ return 0;
+}
+
+static void dump_trace_imc_data(struct perf_event *event)
+{
+ struct trace_imc_data *mem;
+ int i, ret;
+ u64 prev_tb = 0;
+
+ mem = (struct trace_imc_data *)get_trace_imc_event_base_addr();
+ for (i = 0; i < (trace_imc_mem_size / sizeof(struct trace_imc_data));
+ i++, mem++) {
+ struct perf_sample_data data;
+ struct perf_event_header header;
+
+ ret = trace_imc_prepare_sample(mem, &data, &prev_tb, &header, event);
+ if (ret) /* Exit, if not a valid record */
+ break;
+ else {
+ /* If this is a valid record, create the sample */
+ struct perf_output_handle handle;
+
+ if (perf_output_begin(&handle, event, header.size))
+ return;
+
+ perf_output_sample(&handle, &header, &data, event);
+ perf_output_end(&handle);
+ }
+ }
+}
+
+static int trace_imc_event_add(struct perf_event *event, int flags)
+{
+ /* Enable the sched_task to start the engine */
+ perf_sched_cb_inc(event->ctx->pmu);
+ return 0;
+}
+
+static void trace_imc_event_read(struct perf_event *event)
+{
+ dump_trace_imc_data(event);
+}
+
+static void trace_imc_event_stop(struct perf_event *event, int flags)
+{
+ trace_imc_event_read(event);
+}
+
+static void trace_imc_event_start(struct perf_event *event, int flags)
+{
+ return;
+}
+
+static void trace_imc_event_del(struct perf_event *event, int flags)
+{
+ perf_sched_cb_dec(event->ctx->pmu);
+}
+
+void trace_imc_pmu_sched_task(struct perf_event_context *ctx,
+ bool sched_in)
+{
+ int core_id = smp_processor_id() / threads_per_core;
+ struct imc_pmu_ref *ref;
+ u64 local_mem, ldbar_value;
+
+ /* Set trace-imc bit in ldbar and load ldbar with per-thread memory address */
+ local_mem = get_trace_imc_event_base_addr();
+ ldbar_value = ((u64)local_mem & THREAD_IMC_LDBAR_MASK) | TRACE_IMC_ENABLE;
+
+ ref = &core_imc_refc[core_id];
+ if (!ref)
+ return;
+
+ if (sched_in) {
+ mtspr(SPRN_LDBAR, ldbar_value);
+ mutex_lock(&ref->lock);
+ if (ref->refc == 0) {
+ if (opal_imc_counters_start(OPAL_IMC_COUNTERS_TRACE,
+ get_hard_smp_processor_id(smp_processor_id()))) {
+ mutex_unlock(&ref->lock);
+ pr_err("trace-imc: Unable to start the counters for core %d\n", core_id);
+ mtspr(SPRN_LDBAR, 0);
+ return;
+ }
+ }
+ ++ref->refc;
+ mutex_unlock(&ref->lock);
+ } else {
+ mtspr(SPRN_LDBAR, 0);
+ mutex_lock(&ref->lock);
+ ref->refc--;
+ if (ref->refc == 0) {
+ if (opal_imc_counters_stop(OPAL_IMC_COUNTERS_TRACE,
+ get_hard_smp_processor_id(smp_processor_id()))) {
+ mutex_unlock(&ref->lock);
+ pr_err("trace-imc: Unable to stop the counters for core %d\n", core_id);
+ return;
+ }
+ } else if (ref->refc < 0) {
+ ref->refc = 0;
+ }
+ mutex_unlock(&ref->lock);
+ }
+ return;
+}
+
+static int trace_imc_event_init(struct perf_event *event)
+{
+ struct task_struct *target;
+
+ if (event->attr.type != event->pmu->type)
+ return -ENOENT;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ /* Return if this is a couting event */
+ if (event->attr.sample_period == 0)
+ return -ENOENT;
+
+ event->hw.idx = -1;
+ target = event->hw.target;
+
+ event->pmu->task_ctx_nr = perf_hw_context;
+ return 0;
+}
+
/* update_pmu_ops : Populate the appropriate operations for "pmu" */
static int update_pmu_ops(struct imc_pmu *pmu)
{
@@ -1149,6 +1335,15 @@ static int update_pmu_ops(struct imc_pmu *pmu)
pmu->pmu.cancel_txn = thread_imc_pmu_cancel_txn;
pmu->pmu.commit_txn = thread_imc_pmu_commit_txn;
break;
+ case IMC_DOMAIN_TRACE:
+ pmu->pmu.event_init = trace_imc_event_init;
+ pmu->pmu.add = trace_imc_event_add;
+ pmu->pmu.del = trace_imc_event_del;
+ pmu->pmu.start = trace_imc_event_start;
+ pmu->pmu.stop = trace_imc_event_stop;
+ pmu->pmu.read = trace_imc_event_read;
+ pmu->pmu.sched_task = trace_imc_pmu_sched_task;
+ pmu->attr_groups[IMC_FORMAT_ATTR] = &trace_imc_format_group;
default:
break;
}
--
2.17.1
^ permalink raw reply related
* [PATCH v3 4/5] powerpc/perf: Trace imc events detection and cpuhotplug
From: Anju T Sudhakar @ 2019-02-07 7:03 UTC (permalink / raw)
To: mpe; +Cc: maddy, linuxppc-dev, linux-kernel, anju
In-Reply-To: <20190207070312.5150-1-anju@linux.vnet.ibm.com>
Patch detects trace-imc events, does memory initilizations for each online
cpu, and registers cpuhotplug call-backs.
Signed-off-by: Anju T Sudhakar <anju@linux.vnet.ibm.com>
Reviewed-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/perf/imc-pmu.c | 91 +++++++++++++++++++++++
arch/powerpc/platforms/powernv/opal-imc.c | 3 +
include/linux/cpuhotplug.h | 1 +
3 files changed, 95 insertions(+)
diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index 5ca80545a849..1f09265c8fb0 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -43,6 +43,10 @@ static DEFINE_PER_CPU(u64 *, thread_imc_mem);
static struct imc_pmu *thread_imc_pmu;
static int thread_imc_mem_size;
+/* Trace IMC data structures */
+static DEFINE_PER_CPU(u64 *, trace_imc_mem);
+static int trace_imc_mem_size;
+
static struct imc_pmu *imc_event_to_pmu(struct perf_event *event)
{
return container_of(event->pmu, struct imc_pmu, pmu);
@@ -1068,6 +1072,54 @@ static void thread_imc_event_del(struct perf_event *event, int flags)
imc_event_update(event);
}
+/*
+ * Allocate a page of memory for each cpu, and load LDBAR with 0.
+ */
+static int trace_imc_mem_alloc(int cpu_id, int size)
+{
+ u64 *local_mem = per_cpu(trace_imc_mem, cpu_id);
+ int phys_id = cpu_to_node(cpu_id), rc = 0;
+
+ if (!local_mem) {
+ local_mem = page_address(alloc_pages_node(phys_id,
+ GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE |
+ __GFP_NOWARN, get_order(size)));
+ if (!local_mem)
+ return -ENOMEM;
+ per_cpu(trace_imc_mem, cpu_id) = local_mem;
+
+ /* Initialise the counters for trace mode */
+ rc = opal_imc_counters_init(OPAL_IMC_COUNTERS_TRACE, __pa((void *)local_mem),
+ get_hard_smp_processor_id(cpu_id));
+ if (rc) {
+ pr_info("IMC:opal init failed for trace imc\n");
+ return rc;
+ }
+ }
+
+ mtspr(SPRN_LDBAR, 0);
+ return 0;
+}
+
+static int ppc_trace_imc_cpu_online(unsigned int cpu)
+{
+ return trace_imc_mem_alloc(cpu, trace_imc_mem_size);
+}
+
+static int ppc_trace_imc_cpu_offline(unsigned int cpu)
+{
+ mtspr(SPRN_LDBAR, 0);
+ return 0;
+}
+
+static int trace_imc_cpu_init(void)
+{
+ return cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_TRACE_IMC_ONLINE,
+ "perf/powerpc/imc_trace:online",
+ ppc_trace_imc_cpu_online,
+ ppc_trace_imc_cpu_offline);
+}
+
/* update_pmu_ops : Populate the appropriate operations for "pmu" */
static int update_pmu_ops(struct imc_pmu *pmu)
{
@@ -1189,6 +1241,17 @@ static void cleanup_all_thread_imc_memory(void)
}
}
+static void cleanup_all_trace_imc_memory(void)
+{
+ int i, order = get_order(trace_imc_mem_size);
+
+ for_each_online_cpu(i) {
+ if (per_cpu(trace_imc_mem, i))
+ free_pages((u64)per_cpu(trace_imc_mem, i), order);
+
+ }
+}
+
/* Function to free the attr_groups which are dynamically allocated */
static void imc_common_mem_free(struct imc_pmu *pmu_ptr)
{
@@ -1230,6 +1293,11 @@ static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr)
cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE);
cleanup_all_thread_imc_memory();
}
+
+ if (pmu_ptr->domain == IMC_DOMAIN_TRACE) {
+ cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_TRACE_IMC_ONLINE);
+ cleanup_all_trace_imc_memory();
+ }
}
/*
@@ -1312,6 +1380,21 @@ static int imc_mem_init(struct imc_pmu *pmu_ptr, struct device_node *parent,
thread_imc_pmu = pmu_ptr;
break;
+ case IMC_DOMAIN_TRACE:
+ /* Update the pmu name */
+ pmu_ptr->pmu.name = kasprintf(GFP_KERNEL, "%s%s", s, "_imc");
+ if (!pmu_ptr->pmu.name)
+ return -ENOMEM;
+
+ trace_imc_mem_size = pmu_ptr->counter_mem_size;
+ for_each_online_cpu(cpu) {
+ res = trace_imc_mem_alloc(cpu, trace_imc_mem_size);
+ if (res) {
+ cleanup_all_trace_imc_memory();
+ goto err;
+ }
+ }
+ break;
default:
return -EINVAL;
}
@@ -1384,6 +1467,14 @@ int init_imc_pmu(struct device_node *parent, struct imc_pmu *pmu_ptr, int pmu_id
goto err_free_mem;
}
+ break;
+ case IMC_DOMAIN_TRACE:
+ ret = trace_imc_cpu_init();
+ if (ret) {
+ cleanup_all_trace_imc_memory();
+ goto err_free_mem;
+ }
+
break;
default:
return -EINVAL; /* Unknown domain */
diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c
index 58a07948c76e..dedc9ae22662 100644
--- a/arch/powerpc/platforms/powernv/opal-imc.c
+++ b/arch/powerpc/platforms/powernv/opal-imc.c
@@ -284,6 +284,9 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
case IMC_TYPE_THREAD:
domain = IMC_DOMAIN_THREAD;
break;
+ case IMC_TYPE_TRACE:
+ domain = IMC_DOMAIN_TRACE;
+ break;
default:
pr_warn("IMC Unknown Device type \n");
domain = -1;
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index fd586d0301e7..2a437f4a46b6 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -169,6 +169,7 @@ enum cpuhp_state {
CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE,
CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE,
CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE,
+ CPUHP_AP_PERF_POWERPC_TRACE_IMC_ONLINE,
CPUHP_AP_WATCHDOG_ONLINE,
CPUHP_AP_WORKQUEUE_ONLINE,
CPUHP_AP_RCUTREE_ONLINE,
--
2.17.1
^ permalink raw reply related
* [PATCH v3 3/5] powerpc/perf: Add privileged access check for thread_imc
From: Anju T Sudhakar @ 2019-02-07 7:03 UTC (permalink / raw)
To: mpe; +Cc: maddy, linuxppc-dev, linux-kernel, anju
In-Reply-To: <20190207070312.5150-1-anju@linux.vnet.ibm.com>
From: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Add code to restrict user access to thread_imc pmu since
some event report privilege level information.
Fixes: f74c89bd80fb3 ('powerpc/perf: Add thread IMC PMU support')
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Signed-off-by: Anju T Sudhakar <anju@linux.vnet.ibm.com>
---
arch/powerpc/perf/imc-pmu.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index 3bef46f8417d..5ca80545a849 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -877,6 +877,9 @@ static int thread_imc_event_init(struct perf_event *event)
if (event->attr.type != event->pmu->type)
return -ENOENT;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
/* Sampling not supported */
if (event->hw.sample_period)
return -EINVAL;
--
2.17.1
^ permalink raw reply related
* [PATCH v3 2/5] powerpc/perf: Rearrange setting of ldbar for thread-imc
From: Anju T Sudhakar @ 2019-02-07 7:03 UTC (permalink / raw)
To: mpe; +Cc: maddy, linuxppc-dev, linux-kernel, anju
In-Reply-To: <20190207070312.5150-1-anju@linux.vnet.ibm.com>
LDBAR holds the memory address allocated for each cpu. For thread-imc
the mode bit (i.e bit 1) of LDBAR is set to accumulation.
Currently, ldbar is loaded with per cpu memory address and mode set to
accumulation at boot time.
To enable trace-imc, the mode bit of ldbar should be set to 'trace'. So to
accommodate trace-mode of IMC, reposition setting of ldbar for thread-imc
to thread_imc_event_add(). Also reset ldbar at thread_imc_event_del().
Signed-off-by: Anju T Sudhakar <anju@linux.vnet.ibm.com>
Reviewed-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/perf/imc-pmu.c | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index f292a3f284f1..3bef46f8417d 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -806,8 +806,11 @@ static int core_imc_event_init(struct perf_event *event)
}
/*
- * Allocates a page of memory for each of the online cpus, and write the
- * physical base address of that page to the LDBAR for that cpu.
+ * Allocates a page of memory for each of the online cpus, and load
+ * LDBAR with 0.
+ * The physical base address of the page allocated for a cpu will be
+ * written to the LDBAR for that cpu, when the thread-imc event
+ * is added.
*
* LDBAR Register Layout:
*
@@ -825,7 +828,7 @@ static int core_imc_event_init(struct perf_event *event)
*/
static int thread_imc_mem_alloc(int cpu_id, int size)
{
- u64 ldbar_value, *local_mem = per_cpu(thread_imc_mem, cpu_id);
+ u64 *local_mem = per_cpu(thread_imc_mem, cpu_id);
int nid = cpu_to_node(cpu_id);
if (!local_mem) {
@@ -842,9 +845,7 @@ static int thread_imc_mem_alloc(int cpu_id, int size)
per_cpu(thread_imc_mem, cpu_id) = local_mem;
}
- ldbar_value = ((u64)local_mem & THREAD_IMC_LDBAR_MASK) | THREAD_IMC_ENABLE;
-
- mtspr(SPRN_LDBAR, ldbar_value);
+ mtspr(SPRN_LDBAR, 0);
return 0;
}
@@ -995,6 +996,7 @@ static int thread_imc_event_add(struct perf_event *event, int flags)
{
int core_id;
struct imc_pmu_ref *ref;
+ u64 ldbar_value, *local_mem = per_cpu(thread_imc_mem, smp_processor_id());
if (flags & PERF_EF_START)
imc_event_start(event, flags);
@@ -1003,6 +1005,9 @@ static int thread_imc_event_add(struct perf_event *event, int flags)
return -EINVAL;
core_id = smp_processor_id() / threads_per_core;
+ ldbar_value = ((u64)local_mem & THREAD_IMC_LDBAR_MASK) | THREAD_IMC_ENABLE;
+ mtspr(SPRN_LDBAR, ldbar_value);
+
/*
* imc pmus are enabled only when it is used.
* See if this is triggered for the first time.
@@ -1034,11 +1039,7 @@ static void thread_imc_event_del(struct perf_event *event, int flags)
int core_id;
struct imc_pmu_ref *ref;
- /*
- * Take a snapshot and calculate the delta and update
- * the event counter values.
- */
- imc_event_update(event);
+ mtspr(SPRN_LDBAR, 0);
core_id = smp_processor_id() / threads_per_core;
ref = &core_imc_refc[core_id];
@@ -1057,6 +1058,11 @@ static void thread_imc_event_del(struct perf_event *event, int flags)
ref->refc = 0;
}
mutex_unlock(&ref->lock);
+ /*
+ * Take a snapshot and calculate the delta and update
+ * the event counter values.
+ */
+ imc_event_update(event);
}
/* update_pmu_ops : Populate the appropriate operations for "pmu" */
--
2.17.1
^ permalink raw reply related
* [PATCH v3 0/5] powerpc/perf: IMC trace-mode support
From: Anju T Sudhakar @ 2019-02-07 7:03 UTC (permalink / raw)
To: mpe; +Cc: maddy, linuxppc-dev, linux-kernel, anju
IMC (In-Memory collection counters) is a hardware monitoring facility
that collects large number of hardware performance events.
POWER9 support two modes for IMC which are the Accumulation mode and
Trace mode. In Accumulation mode, event counts are accumulated in system
Memory. Hypervisor then reads the posted counts periodically or when
requested. In IMC Trace mode, event counted is fixed for cycles and on
each overflow, hardware snapshots the program counter along with other
details and writes into memory pointed by LDBAR(ring buffer memory,
hardware wraps around). LDBAR has bit which indicates the IMC trace-mode.
Trace-IMC Implementation:
--------------------------
To enable trace-imc, we need to
* Add trace node in the DTS file for power9, so that the new trace node can
be discovered by the kernel.
Information included in the DTS file are as follows, (a snippet from
the ima-catalog)
TRACE_IMC: trace-events {
#address-cells = <0x1>;
#size-cells = <0x1>;
event@10200000 {
event-name = "cycles" ;
reg = <0x10200000 0x8>;
desc = "Reference cycles" ;
};
};
trace@0 {
compatible = "ibm,imc-counters";
events-prefix = "trace_";
reg = <0x0 0x8>;
events = < &TRACE_IMC >;
type = <0x2>;
size = <0x40000>;
};
OP-BUILD changes needed to include the "trace node" is already pulled in
to the ima-catalog repo.
ps://github.com/open-power/op-build/commit/d3e75dc26d1283d7d5eb444bff1ec9e40d5dfc07
* Enchance the opal_imc_counters_* calls to support this new trace mode
in imc. Add support to initialize the trace-mode scom.
TRACE_IMC_SCOM bit representation:
0:1 : SAMPSEL
2:33 : CPMC_LOAD
34:40 : CPMC1SEL
41:47 : CPMC2SEL
48:50 : BUFFERSIZE
51:63 : RESERVED
CPMC_LOAD contains the sampling duration. SAMPSEL and CPMC*SEL determines
the event to count. BUFFRSIZE indicates the memory range. On each overflow,
hardware snapshots program counter along with other details and update the
memory and reloads the CMPC_LOAD value for the next sampling duration.
IMC hardware does not support exceptions, so it quietly wraps around if
memory buffer reaches the end.
Link to the skiboot patches to enhance the opal_imc_counters_* calls:
https://lists.ozlabs.org/pipermail/skiboot/2018-December/012878.html
https://lists.ozlabs.org/pipermail/skiboot/2018-December/012879.html
https://lists.ozlabs.org/pipermail/skiboot/2018-December/012882.html
https://lists.ozlabs.org/pipermail/skiboot/2018-December/012880.html
https://lists.ozlabs.org/pipermail/skiboot/2018-December/012881.html
https://lists.ozlabs.org/pipermail/skiboot/2018-December/012883.html
* Set LDBAR spr to enable imc-trace mode.
LDBAR Layout:
0 : Enable/Disable
1 : 0 -> Accumulation Mode
1 -> Trace Mode
2:3 : Reserved
4-6 : PB scope
7 : Reserved
8:50 : Counter Address
51:63 : Reserved
----------------
Key benefit of imc trace-mode is, each sample record contains the address
pointer along with other information. So that, we can profile the IP
without interrupting the application.
Performance data using 'perf top' with and without trace-imc event:
When the application is monitored with trace-imc event, we dont take any
PMI interrupts.
PMI interrupts count when `perf top` command is executed without trac-imc event.
# perf top
12.53% [kernel] [k] arch_cpu_idle
11.32% [kernel] [k] rcu_idle_enter
10.76% [kernel] [k] __next_timer_interrupt
9.49% [kernel] [k] find_next_bit
8.06% [kernel] [k] rcu_dynticks_eqs_exit
7.82% [kernel] [k] do_idle
5.71% [kernel] [k] tick_nohz_idle_stop_tic
[-----------------------]
# cat /proc/interrupts (a snippet from the output)
9944 1072 804 804 1644 804 1306
804 804 804 804 804 804 804
804 804 1961 1602 804 804 1258
[-----------------------------------------------------------------]
803 803 803 803 803 803 803
803 803 803 803 804 804 804
804 804 804 804 804 804 803
803 803 803 803 803 1306 803
803 Performance monitoring interrupts
`perf top` with trace-imc (right after 'perf top' without trace-imc event):
# perf top -e trace_imc/trace_cycles/
12.50% [kernel] [k] arch_cpu_idle
11.81% [kernel] [k] __next_timer_interrupt
11.22% [kernel] [k] rcu_idle_enter
10.25% [kernel] [k] find_next_bit
7.91% [kernel] [k] do_idle
7.69% [kernel] [k] rcu_dynticks_eqs_exit
5.20% [kernel] [k] tick_nohz_idle_stop_tick
[-----------------------]
# cat /proc/interrupts (a snippet from the output)
9944 1072 804 804 1644 804 1306
804 804 804 804 804 804 804
804 804 1961 1602 804 804 1258
[-----------------------------------------------------------------]
803 803 803 803 803 803 803
803 803 803 804 804 804 804
804 804 804 804 804 804 803
803 803 803 803 803 1306 803
803 Performance monitoring interrupts
The PMI interrupts count remains the same.
Changelog:
From v2 -> v3
--------------
* Redefined the event format for trace-imc.
Suggestions/comments are welcome.
Anju T Sudhakar (4):
powerpc/include: Add data structures and macros for IMC trace mode
powerpc/perf: Rearrange setting of ldbar for thread-imc
powerpc/perf: Trace imc events detection and cpuhotplug
powerpc/perf: Trace imc PMU functions
Madhavan Srinivasan (1):
powerpc/perf: Add privileged access check for thread_imc
arch/powerpc/include/asm/imc-pmu.h | 39 +++
arch/powerpc/include/asm/opal-api.h | 1 +
arch/powerpc/perf/imc-pmu.c | 319 +++++++++++++++++++++-
arch/powerpc/platforms/powernv/opal-imc.c | 3 +
include/linux/cpuhotplug.h | 1 +
5 files changed, 351 insertions(+), 12 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH v3 1/5] powerpc/include: Add data structures and macros for IMC trace mode
From: Anju T Sudhakar @ 2019-02-07 7:03 UTC (permalink / raw)
To: mpe; +Cc: maddy, linuxppc-dev, linux-kernel, anju
In-Reply-To: <20190207070312.5150-1-anju@linux.vnet.ibm.com>
Add the macros needed for IMC (In-Memory Collection Counters) trace-mode
and data structure to hold the trace-imc record data.
Also, add the new type "OPAL_IMC_COUNTERS_TRACE" in 'opal-api.h', since
there is a new switch case added in the opal-calls for IMC.
Signed-off-by: Anju T Sudhakar <anju@linux.vnet.ibm.com>
Reviewed-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/imc-pmu.h | 39 +++++++++++++++++++++++++++++
arch/powerpc/include/asm/opal-api.h | 1 +
2 files changed, 40 insertions(+)
diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h
index 69f516ecb2fd..7c2ef0e42661 100644
--- a/arch/powerpc/include/asm/imc-pmu.h
+++ b/arch/powerpc/include/asm/imc-pmu.h
@@ -33,6 +33,7 @@
*/
#define THREAD_IMC_LDBAR_MASK 0x0003ffffffffe000ULL
#define THREAD_IMC_ENABLE 0x8000000000000000ULL
+#define TRACE_IMC_ENABLE 0x4000000000000000ULL
/*
* For debugfs interface for imc-mode and imc-command
@@ -59,6 +60,34 @@ struct imc_events {
char *scale;
};
+/*
+ * Trace IMC hardware updates a 64bytes record on
+ * Core Performance Monitoring Counter (CPMC)
+ * overflow. Here is the layout for the trace imc record
+ *
+ * DW 0 : Timebase
+ * DW 1 : Program Counter
+ * DW 2 : PIDR information
+ * DW 3 : CPMC1
+ * DW 4 : CPMC2
+ * DW 5 : CPMC3
+ * Dw 6 : CPMC4
+ * DW 7 : Timebase
+ * .....
+ *
+ * The following is the data structure to hold trace imc data.
+ */
+struct trace_imc_data {
+ u64 tb1;
+ u64 ip;
+ u64 val;
+ u64 cpmc1;
+ u64 cpmc2;
+ u64 cpmc3;
+ u64 cpmc4;
+ u64 tb2;
+};
+
/* Event attribute array index */
#define IMC_FORMAT_ATTR 0
#define IMC_EVENT_ATTR 1
@@ -68,6 +97,13 @@ struct imc_events {
/* PMU Format attribute macros */
#define IMC_EVENT_OFFSET_MASK 0xffffffffULL
+/*
+ * Macro to mask bits 0:21 of first double word(which is the timebase) to
+ * compare with 8th double word (timebase) of trace imc record data.
+ */
+#define IMC_TRACE_RECORD_TB1_MASK 0x3ffffffffffULL
+
+
/*
* Device tree parser code detects IMC pmu support and
* registers new IMC pmus. This structure will hold the
@@ -113,6 +149,7 @@ struct imc_pmu_ref {
enum {
IMC_TYPE_THREAD = 0x1,
+ IMC_TYPE_TRACE = 0x2,
IMC_TYPE_CORE = 0x4,
IMC_TYPE_CHIP = 0x10,
};
@@ -123,6 +160,8 @@ enum {
#define IMC_DOMAIN_NEST 1
#define IMC_DOMAIN_CORE 2
#define IMC_DOMAIN_THREAD 3
+/* For trace-imc the domain is still thread but it operates in trace-mode */
+#define IMC_DOMAIN_TRACE 4
extern int init_imc_pmu(struct device_node *parent,
struct imc_pmu *pmu_ptr, int pmu_id);
diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
index 870fb7b239ea..a4130b21b159 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -1118,6 +1118,7 @@ enum {
enum {
OPAL_IMC_COUNTERS_NEST = 1,
OPAL_IMC_COUNTERS_CORE = 2,
+ OPAL_IMC_COUNTERS_TRACE = 3,
};
--
2.17.1
^ permalink raw reply related
* Re: [PATCH 1/2] powerpc/64s: Work around spurious warning on old gccs with -fsanitize-coverage
From: Andrew Donnellan @ 2019-02-07 6:59 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: syzkaller, linuxppc-dev, dvyukov
In-Reply-To: <20190207063736.GS14180@gate.crashing.org>
On 7/2/19 5:37 pm, Segher Boessenkool wrote:
> On Thu, Feb 07, 2019 at 04:33:23PM +1100, Andrew Donnellan wrote:
>> Some older gccs (<GCC 7), when invoked with -fsanitize-coverage=trace-pc,
>> cause a spurious uninitialised variable warning in dt_cpu_ftrs.c:
>>
>> arch/powerpc/kernel/dt_cpu_ftrs.c: In function ‘cpufeatures_process_feature’:
>> arch/powerpc/kernel/dt_cpu_ftrs.c:686:7: warning: ‘m’ may be used uninitialized in this function [-Wmaybe-uninitialized]
>> if (m->cpu_ftr_bit_mask)
>
> It seems to me the warning is correct? If enable_unknown is false and no
> cpu_feature is found, it will in
>
> if (m->cpu_ftr_bit_mask)
> cur_cpu_spec->cpu_features |= m->cpu_ftr_bit_mask;
>
> enable random features (whatever was last in the table), or indeed access
> via NULL if the table is length 0? So maybe this should be
>
> if (known && m->cpu_ftr_bit_mask)
> cur_cpu_spec->cpu_features |= m->cpu_ftr_bit_mask;
>
> instead? (The code would be much clearer if all the known vs. !known
> codepath was fully separated here).
The table is never length 0, it's a statically defined array.
>
>
> Segher
>
--
Andrew Donnellan OzLabs, ADL Canberra
andrew.donnellan@au1.ibm.com IBM Australia Limited
^ permalink raw reply
* Re: [PATCH 1/2] powerpc/64s: Work around spurious warning on old gccs with -fsanitize-coverage
From: Segher Boessenkool @ 2019-02-07 6:37 UTC (permalink / raw)
To: Andrew Donnellan; +Cc: syzkaller, linuxppc-dev, dvyukov
In-Reply-To: <20190207053324.17541-1-andrew.donnellan@au1.ibm.com>
On Thu, Feb 07, 2019 at 04:33:23PM +1100, Andrew Donnellan wrote:
> Some older gccs (<GCC 7), when invoked with -fsanitize-coverage=trace-pc,
> cause a spurious uninitialised variable warning in dt_cpu_ftrs.c:
>
> arch/powerpc/kernel/dt_cpu_ftrs.c: In function ‘cpufeatures_process_feature’:
> arch/powerpc/kernel/dt_cpu_ftrs.c:686:7: warning: ‘m’ may be used uninitialized in this function [-Wmaybe-uninitialized]
> if (m->cpu_ftr_bit_mask)
It seems to me the warning is correct? If enable_unknown is false and no
cpu_feature is found, it will in
if (m->cpu_ftr_bit_mask)
cur_cpu_spec->cpu_features |= m->cpu_ftr_bit_mask;
enable random features (whatever was last in the table), or indeed access
via NULL if the table is length 0? So maybe this should be
if (known && m->cpu_ftr_bit_mask)
cur_cpu_spec->cpu_features |= m->cpu_ftr_bit_mask;
instead? (The code would be much clearer if all the known vs. !known
codepath was fully separated here).
Segher
^ permalink raw reply
* [PATCH 0/1] Start conversion of PowerPC docs
From: Tobin C. Harding @ 2019-02-07 6:03 UTC (permalink / raw)
To: Michael Ellerman
Cc: linux-kernel, linux-doc, linuxppc-dev, Tobin C. Harding,
Jonathan Corbet
Hi Michael,
As discussed at LCA here is the start to the docs conversion for PowerPC
to RST.
This applies cleanly on top of the mainline (5.20-rc5) and Jon's tree
(docs-next branch).
I'm guessing it should go in through the PowerPC tree because I doubt
you want to review this Jon, it's one big single patch (all blame for
that falls on mpe ;)
This patch converts all the files that do _not_ contain ASCII art - I'm
not sure how to go about doing those, suggestions please.
From the commit message:
- Add SPDX license identifier to each new RST file.
.. SPDX-License-Identifier: GPL-2.0
- User correct heading adornments.
- Make all lines < 72 characters in width.
- Use correct indentation for code blocks, add syntax highlighting
- Sparingly use double ticks if it makes the files easier to parse
both in text and on the web.
- Fix any super obvious typos (lean towards not making changes so that
we don't introduce errors).
Edited as text files (obviously) and formatted as HTML to verify
rendering, no other formats verified.
thanks,
Tobin.
Tobin C. Harding (1):
docs: powerpc: Convert docs to RST format.
Documentation/index.rst | 1 +
Documentation/powerpc/DAWR-POWER9.rst | 60 ++++
Documentation/powerpc/DAWR-POWER9.txt | 58 ---
Documentation/powerpc/bootwrapper.rst | 140 ++++++++
Documentation/powerpc/bootwrapper.txt | 141 --------
Documentation/powerpc/conf.py | 10 +
Documentation/powerpc/cpu_features.rst | 62 ++++
Documentation/powerpc/cpu_features.txt | 56 ---
.../powerpc/eeh-pci-error-recovery.rst | 319 +++++++++++++++++
.../powerpc/eeh-pci-error-recovery.txt | 334 ------------------
Documentation/powerpc/index.rst | 21 ++
Documentation/powerpc/isa-versions.rst | 234 ++++++++----
Documentation/powerpc/mpc52xx.rst | 52 +++
Documentation/powerpc/mpc52xx.txt | 39 --
Documentation/powerpc/pmu-ebb.rst | 148 ++++++++
Documentation/powerpc/pmu-ebb.txt | 137 -------
Documentation/powerpc/ptrace.rst | 177 ++++++++++
Documentation/powerpc/ptrace.txt | 151 --------
.../{syscall64-abi.txt => syscall64-abi.rst} | 80 +++--
.../powerpc/transactional_memory.rst | 259 ++++++++++++++
.../powerpc/transactional_memory.txt | 244 -------------
21 files changed, 1460 insertions(+), 1263 deletions(-)
create mode 100644 Documentation/powerpc/DAWR-POWER9.rst
delete mode 100644 Documentation/powerpc/DAWR-POWER9.txt
create mode 100644 Documentation/powerpc/bootwrapper.rst
delete mode 100644 Documentation/powerpc/bootwrapper.txt
create mode 100644 Documentation/powerpc/conf.py
create mode 100644 Documentation/powerpc/cpu_features.rst
delete mode 100644 Documentation/powerpc/cpu_features.txt
create mode 100644 Documentation/powerpc/eeh-pci-error-recovery.rst
delete mode 100644 Documentation/powerpc/eeh-pci-error-recovery.txt
create mode 100644 Documentation/powerpc/index.rst
create mode 100644 Documentation/powerpc/mpc52xx.rst
delete mode 100644 Documentation/powerpc/mpc52xx.txt
create mode 100644 Documentation/powerpc/pmu-ebb.rst
delete mode 100644 Documentation/powerpc/pmu-ebb.txt
create mode 100644 Documentation/powerpc/ptrace.rst
delete mode 100644 Documentation/powerpc/ptrace.txt
rename Documentation/powerpc/{syscall64-abi.txt => syscall64-abi.rst} (58%)
create mode 100644 Documentation/powerpc/transactional_memory.rst
delete mode 100644 Documentation/powerpc/transactional_memory.txt
--
2.20.1
^ permalink raw reply
* [PATCH 1/1] docs: powerpc: Convert to RST format
From: Tobin C. Harding @ 2019-02-07 6:03 UTC (permalink / raw)
To: Michael Ellerman
Cc: linux-kernel, linux-doc, linuxppc-dev, Tobin C. Harding,
Jonathan Corbet
In-Reply-To: <20190207060316.3221-1-tobin@kernel.org>
The PowerPC docs have yet to be converted to RST format. Let's kick it
off by doing all the files that _don't_ contain ASCII art.
- Add SPDX license identifier to each new RST file.
.. SPDX-License-Identifier: GPL-2.0
- User correct heading adornments.
- Make all lines < 72 characters in width.
- Use correct indentation for code blocks, add syntax highlighting
- Sparingly use double ticks if it makes the files easier to parse
both in text and on the web.
- Fix any super obvious typos (lean towards not making changes so that
we don't introduce errors).
Edited as text files (obviously) and formatted as HTML to verify
rendering, no other formats verified.
Convert docs to RST format, adding license.
Signed-off-by: Tobin C. Harding <tobin@kernel.org>
---
Documentation/index.rst | 1 +
Documentation/powerpc/DAWR-POWER9.rst | 60 ++++
Documentation/powerpc/DAWR-POWER9.txt | 58 ---
Documentation/powerpc/bootwrapper.rst | 140 ++++++++
Documentation/powerpc/bootwrapper.txt | 141 --------
Documentation/powerpc/conf.py | 10 +
Documentation/powerpc/cpu_features.rst | 62 ++++
Documentation/powerpc/cpu_features.txt | 56 ---
.../powerpc/eeh-pci-error-recovery.rst | 319 +++++++++++++++++
.../powerpc/eeh-pci-error-recovery.txt | 334 ------------------
Documentation/powerpc/index.rst | 21 ++
Documentation/powerpc/isa-versions.rst | 234 ++++++++----
Documentation/powerpc/mpc52xx.rst | 52 +++
Documentation/powerpc/mpc52xx.txt | 39 --
Documentation/powerpc/pmu-ebb.rst | 148 ++++++++
Documentation/powerpc/pmu-ebb.txt | 137 -------
Documentation/powerpc/ptrace.rst | 177 ++++++++++
Documentation/powerpc/ptrace.txt | 151 --------
.../{syscall64-abi.txt => syscall64-abi.rst} | 80 +++--
.../powerpc/transactional_memory.rst | 259 ++++++++++++++
.../powerpc/transactional_memory.txt | 244 -------------
21 files changed, 1460 insertions(+), 1263 deletions(-)
create mode 100644 Documentation/powerpc/DAWR-POWER9.rst
delete mode 100644 Documentation/powerpc/DAWR-POWER9.txt
create mode 100644 Documentation/powerpc/bootwrapper.rst
delete mode 100644 Documentation/powerpc/bootwrapper.txt
create mode 100644 Documentation/powerpc/conf.py
create mode 100644 Documentation/powerpc/cpu_features.rst
delete mode 100644 Documentation/powerpc/cpu_features.txt
create mode 100644 Documentation/powerpc/eeh-pci-error-recovery.rst
delete mode 100644 Documentation/powerpc/eeh-pci-error-recovery.txt
create mode 100644 Documentation/powerpc/index.rst
create mode 100644 Documentation/powerpc/mpc52xx.rst
delete mode 100644 Documentation/powerpc/mpc52xx.txt
create mode 100644 Documentation/powerpc/pmu-ebb.rst
delete mode 100644 Documentation/powerpc/pmu-ebb.txt
create mode 100644 Documentation/powerpc/ptrace.rst
delete mode 100644 Documentation/powerpc/ptrace.txt
rename Documentation/powerpc/{syscall64-abi.txt => syscall64-abi.rst} (58%)
create mode 100644 Documentation/powerpc/transactional_memory.rst
delete mode 100644 Documentation/powerpc/transactional_memory.txt
diff --git a/Documentation/index.rst b/Documentation/index.rst
index c858c2e66e36..e0cf2e4a78cf 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -101,6 +101,7 @@ implementation.
:maxdepth: 2
sh/index
+ powerpc/index
Filesystem Documentation
------------------------
diff --git a/Documentation/powerpc/DAWR-POWER9.rst b/Documentation/powerpc/DAWR-POWER9.rst
new file mode 100644
index 000000000000..0af7c9567931
--- /dev/null
+++ b/Documentation/powerpc/DAWR-POWER9.rst
@@ -0,0 +1,60 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=====================
+DAWR issues on POWER9
+=====================
+
+On POWER9 the DAWR can cause a checkstop if it points to cache inhibited
+(CI) memory. Currently Linux has no way to disinguish CI memory when
+configuring the DAWR, so (for now) the DAWR is disabled by this commit::
+
+ commit 9654153158d3e0684a1bdb76dbababdb7111d5a0
+ Author: Michael Neuling <mikey@neuling.org>
+ Date: Tue Mar 27 15:37:24 2018 +1100
+ powerpc: Disable DAWR in the base POWER9 CPU features
+
+Technical details
+=================
+
+DAWR has 6 different ways of being set.
+
+1. ptrace
+2. h_set_mode(DAWR)
+3. h_set_dabr()
+4. kvmppc_set_one_reg()
+5. xmon
+
+For ptrace, we now advertise zero breakpoints on POWER9 via the
+PPC_PTRACE_GETHWDBGINFO call. This results in GDB falling back to
+software emulation of the watchpoint (which is slow).
+
+h_set_mode(DAWR) and h_set_dabr() will now return an error to the guest
+on a POWER9 host. Current Linux guests ignore this error, so they will
+silently not get the DAWR.
+
+kvmppc_set_one_reg() will store the value in the vcpu but won't actually
+set it on POWER9 hardware. This is done so we don't break migration from
+POWER8 to POWER9, at the cost of silently losing the DAWR on the
+migration.
+
+For xmon, the 'bd' command will return an error on P9.
+
+Consequences for users
+======================
+
+For GDB watchpoints (ie 'watch' command) on POWER9 bare metal , GDB will
+accept the command. Unfortunately since there is no hardware support for
+the watchpoint, GDB will software emulate the watchpoint making it run
+very slowly.
+
+The same will also be true for any guests started on a POWER9 host. The
+watchpoint will fail and GDB will fall back to software emulation.
+
+If a guest is started on a POWER8 host, GDB will accept the watchpoint
+and configure the hardware to use the DAWR. This will run at full speed
+since it can use the hardware emulation. Unfortunately if this guest is
+migrated to a POWER9 host, the watchpoint will be lost on the
+POWER9. Loads and stores to the watchpoint locations will not be trapped
+in GDB. The watchpoint is remembered, so if the guest is migrated back
+to the POWER8 host, it will start working again.
+
diff --git a/Documentation/powerpc/DAWR-POWER9.txt b/Documentation/powerpc/DAWR-POWER9.txt
deleted file mode 100644
index 2feaa6619658..000000000000
--- a/Documentation/powerpc/DAWR-POWER9.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-DAWR issues on POWER9
-============================
-
-On POWER9 the DAWR can cause a checkstop if it points to cache
-inhibited (CI) memory. Currently Linux has no way to disinguish CI
-memory when configuring the DAWR, so (for now) the DAWR is disabled by
-this commit:
-
- commit 9654153158d3e0684a1bdb76dbababdb7111d5a0
- Author: Michael Neuling <mikey@neuling.org>
- Date: Tue Mar 27 15:37:24 2018 +1100
- powerpc: Disable DAWR in the base POWER9 CPU features
-
-Technical Details:
-============================
-
-DAWR has 6 different ways of being set.
-1) ptrace
-2) h_set_mode(DAWR)
-3) h_set_dabr()
-4) kvmppc_set_one_reg()
-5) xmon
-
-For ptrace, we now advertise zero breakpoints on POWER9 via the
-PPC_PTRACE_GETHWDBGINFO call. This results in GDB falling back to
-software emulation of the watchpoint (which is slow).
-
-h_set_mode(DAWR) and h_set_dabr() will now return an error to the
-guest on a POWER9 host. Current Linux guests ignore this error, so
-they will silently not get the DAWR.
-
-kvmppc_set_one_reg() will store the value in the vcpu but won't
-actually set it on POWER9 hardware. This is done so we don't break
-migration from POWER8 to POWER9, at the cost of silently losing the
-DAWR on the migration.
-
-For xmon, the 'bd' command will return an error on P9.
-
-Consequences for users
-============================
-
-For GDB watchpoints (ie 'watch' command) on POWER9 bare metal , GDB
-will accept the command. Unfortunately since there is no hardware
-support for the watchpoint, GDB will software emulate the watchpoint
-making it run very slowly.
-
-The same will also be true for any guests started on a POWER9
-host. The watchpoint will fail and GDB will fall back to software
-emulation.
-
-If a guest is started on a POWER8 host, GDB will accept the watchpoint
-and configure the hardware to use the DAWR. This will run at full
-speed since it can use the hardware emulation. Unfortunately if this
-guest is migrated to a POWER9 host, the watchpoint will be lost on the
-POWER9. Loads and stores to the watchpoint locations will not be
-trapped in GDB. The watchpoint is remembered, so if the guest is
-migrated back to the POWER8 host, it will start working again.
-
diff --git a/Documentation/powerpc/bootwrapper.rst b/Documentation/powerpc/bootwrapper.rst
new file mode 100644
index 000000000000..fd12c4fcd300
--- /dev/null
+++ b/Documentation/powerpc/bootwrapper.rst
@@ -0,0 +1,140 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+========================
+The PowerPC boot wrapper
+========================
+
+Copyright (C) Secret Lab Technologies Ltd.
+
+PowerPC image targets compresses and wraps the kernel image (vmlinux)
+with a boot wrapper to make it usable by the system firmware. There is
+no standard PowerPC firmware interface, so the boot wrapper is designed
+to be adaptable for each kind of image that needs to be built.
+
+The boot wrapper can be found in the arch/powerpc/boot/ directory. The
+Makefile in that directory has targets for all the available image
+types. The different image types are used to support all of the various
+firmware interfaces found on PowerPC platforms. OpenFirmware is the
+most commonly used firmware type on general purpose PowerPC systems from
+Apple, IBM and others. U-Boot is typically found on embedded PowerPC
+hardware, but there are a handful of other firmware implementations
+which are also popular. Each firmware interface requires a different
+image format.
+
+The boot wrapper is built from the makefile in
+arch/powerpc/boot/Makefile and it uses the wrapper script
+(arch/powerpc/boot/wrapper) to generate target image. The details of
+the build system is discussed in the next section. Currently, the
+following image format targets exist:
+
+- ``cuImage.%``: Backwards compatible uImage for older version of U-Boot
+ (for versions that don't understand the device tree). This image
+ embeds a device tree blob inside the image. The boot wrapper, kernel
+ and device tree are all embedded inside the U-Boot uImage file format
+ with boot wrapper code that extracts data from the old bd_info
+ structure and loads the data into the device tree before jumping into
+ the kernel. Because of the series of #ifdefs found in the bd_info
+ structure used in the old U-Boot interfaces, cuImages are platform
+ specific. Each specific U-Boot platform has a different platform init
+ file which populates the embedded device tree with data from the
+ platform specific bd_info file. The platform specific cuImage
+ platform init code can be found in arch/powerpc/boot/cuboot.*.c.
+ Selection of the correct cuImage init code for a specific board can be
+ found in the wrapper structure.
+
+- ``dtbImage.%``: Similar to zImage, except device tree blob is embedded
+ inside the image instead of provided by firmware. The output image
+ file can be either an elf file or a flat binary depending on the
+ platform. dtbImages are used on systems which do not have an
+ interface for passing a device tree directly. dtbImages are similar
+ to simpleImages except that dtbImages have platform specific code for
+ extracting data from the board firmware, but simpleImages do not talk
+ to the firmware at all. PlayStation 3 support uses dtbImage. So do
+ Embedded Planet boards using the PlanetCore firmware. Board specific
+ initialization code is typically found in a file named
+ arch/powerpc/boot/<platform>.c; but this can be overridden by the
+ wrapper script.
+
+- ``simpleImage.%``: Firmware independent compressed image that does not
+ depend on any particular firmware interface and embeds a device tree
+ blob. This image is a flat binary that can be loaded to any location
+ in RAM and jumped to. Firmware cannot pass any configuration data to
+ the kernel with this image type and it depends entirely on the
+ embedded device tree for all information. The simpleImage is useful
+ for booting systems with an unknown firmware interface or for booting
+ from a debugger when no firmware is present (such as on the Xilinx
+ Virtex platform). The only assumption that simpleImage makes is that
+ RAM is correctly initialized and that the MMU is either off or has RAM
+ mapped to base address 0. simpleImage also supports inserting special
+ platform specific initialization code to the start of the bootup
+ sequence. The virtex405 platform uses this feature to ensure that the
+ cache is invalidated before caching is enabled. Platform specific
+ initialization code is added as part of the wrapper script and is
+ keyed on the image target name. For example, all
+ simpleImage.virtex405-* targets will add the virtex405-head.S
+ initialization code (This also means that the dts file for virtex405
+ targets should be named (virtex405-<board>.dts). Search the wrapper
+ script for 'virtex405' and see the file
+ arch/powerpc/boot/virtex405-head.S for details.
+
+- ``treeImage.%``: Image format for used with OpenBIOS firmware found on some
+ ppc4xx hardware. This image embeds a device tree blob inside the
+ image.
+
+- ``uImage``: Native image format used by U-Boot. The uImage target does
+ not add any boot code. It just wraps a compressed vmlinux in the
+ uImage data structure. This image requires a version of U-Boot that
+ is able to pass a device tree to the kernel at boot. If using an
+ older version of U-Boot, then you need to use a cuImage instead.
+- ``zImage.%``: Image format which does not embed a device tree. Used by
+ OpenFirmware and other firmware interfaces which are able to supply a
+ device tree. This image expects firmware to provide the device tree
+ at boot. Typically, if you have general purpose PowerPC hardware then
+ you want this image format.
+
+Image types which embed a device tree blob (simpleImage, dtbImage,
+treeImage, and cuImage) all generate the device tree blob from a file in
+the arch/powerpc/boot/dts/ directory. The Makefile selects the correct
+device tree source based on the name of the target. Therefore, if the
+kernel is built with 'make treeImage.walnut
+simpleImage.virtex405-ml403', then the build system will use
+arch/powerpc/boot/dts/walnut.dts to build treeImage.walnut and
+arch/powerpc/boot/dts/virtex405-ml403.dts to build the
+simpleImage.virtex405-ml403.
+
+Two special targets called 'zImage' and 'zImage.initrd' also exist.
+These targets build all the default images as selected by the kernel
+configuration. Default images are selected by the boot wrapper Makefile
+(arch/powerpc/boot/Makefile) by adding targets to the $image-y variable.
+Look at the Makefile to see which default image targets are available.
+
+How it is built
+===============
+
+arch/powerpc is designed to support multiplatform kernels, which means
+that a single vmlinux image can be booted on many different target
+boards. It also means that the boot wrapper must be able to wrap for
+many kinds of images on a single build. The design decision was made to
+not use any conditional compilation code (#ifdef, etc) in the boot
+wrapper source code. All of the boot wrapper pieces are buildable at
+any time regardless of the kernel configuration. Building all the
+wrapper bits on every kernel build also ensures that obscure parts of
+the wrapper are at the very least compile tested in a large variety of
+environments.
+
+The wrapper is adapted for different image types at link time by linking
+in just the wrapper bits that are appropriate for the image type. The
+'wrapper script' (found in arch/powerpc/boot/wrapper) is called by the
+Makefile and is responsible for selecting the correct wrapper bits for
+the image type. The arguments are well documented in the script's
+comment block, so they are not repeated here. However, it is worth
+mentioning that the script uses the -p (platform) argument as the main
+method of deciding which wrapper bits to compile in. Look for the large
+'case "$platform" in' block in the middle of the script. This is also
+the place where platform specific fixups can be selected by changing the
+link order.
+
+In particular, care should be taken when working with cuImages. cuImage
+wrapper bits are very board specific and care should be taken to make
+sure the target you are trying to build is supported by the wrapper
+bits.
diff --git a/Documentation/powerpc/bootwrapper.txt b/Documentation/powerpc/bootwrapper.txt
deleted file mode 100644
index d60fced5e1cc..000000000000
--- a/Documentation/powerpc/bootwrapper.txt
+++ /dev/null
@@ -1,141 +0,0 @@
-The PowerPC boot wrapper
-------------------------
-Copyright (C) Secret Lab Technologies Ltd.
-
-PowerPC image targets compresses and wraps the kernel image (vmlinux) with
-a boot wrapper to make it usable by the system firmware. There is no
-standard PowerPC firmware interface, so the boot wrapper is designed to
-be adaptable for each kind of image that needs to be built.
-
-The boot wrapper can be found in the arch/powerpc/boot/ directory. The
-Makefile in that directory has targets for all the available image types.
-The different image types are used to support all of the various firmware
-interfaces found on PowerPC platforms. OpenFirmware is the most commonly
-used firmware type on general purpose PowerPC systems from Apple, IBM and
-others. U-Boot is typically found on embedded PowerPC hardware, but there
-are a handful of other firmware implementations which are also popular. Each
-firmware interface requires a different image format.
-
-The boot wrapper is built from the makefile in arch/powerpc/boot/Makefile and
-it uses the wrapper script (arch/powerpc/boot/wrapper) to generate target
-image. The details of the build system is discussed in the next section.
-Currently, the following image format targets exist:
-
- cuImage.%: Backwards compatible uImage for older version of
- U-Boot (for versions that don't understand the device
- tree). This image embeds a device tree blob inside
- the image. The boot wrapper, kernel and device tree
- are all embedded inside the U-Boot uImage file format
- with boot wrapper code that extracts data from the old
- bd_info structure and loads the data into the device
- tree before jumping into the kernel.
- Because of the series of #ifdefs found in the
- bd_info structure used in the old U-Boot interfaces,
- cuImages are platform specific. Each specific
- U-Boot platform has a different platform init file
- which populates the embedded device tree with data
- from the platform specific bd_info file. The platform
- specific cuImage platform init code can be found in
- arch/powerpc/boot/cuboot.*.c. Selection of the correct
- cuImage init code for a specific board can be found in
- the wrapper structure.
- dtbImage.%: Similar to zImage, except device tree blob is embedded
- inside the image instead of provided by firmware. The
- output image file can be either an elf file or a flat
- binary depending on the platform.
- dtbImages are used on systems which do not have an
- interface for passing a device tree directly.
- dtbImages are similar to simpleImages except that
- dtbImages have platform specific code for extracting
- data from the board firmware, but simpleImages do not
- talk to the firmware at all.
- PlayStation 3 support uses dtbImage. So do Embedded
- Planet boards using the PlanetCore firmware. Board
- specific initialization code is typically found in a
- file named arch/powerpc/boot/<platform>.c; but this
- can be overridden by the wrapper script.
- simpleImage.%: Firmware independent compressed image that does not
- depend on any particular firmware interface and embeds
- a device tree blob. This image is a flat binary that
- can be loaded to any location in RAM and jumped to.
- Firmware cannot pass any configuration data to the
- kernel with this image type and it depends entirely on
- the embedded device tree for all information.
- The simpleImage is useful for booting systems with
- an unknown firmware interface or for booting from
- a debugger when no firmware is present (such as on
- the Xilinx Virtex platform). The only assumption that
- simpleImage makes is that RAM is correctly initialized
- and that the MMU is either off or has RAM mapped to
- base address 0.
- simpleImage also supports inserting special platform
- specific initialization code to the start of the bootup
- sequence. The virtex405 platform uses this feature to
- ensure that the cache is invalidated before caching
- is enabled. Platform specific initialization code is
- added as part of the wrapper script and is keyed on
- the image target name. For example, all
- simpleImage.virtex405-* targets will add the
- virtex405-head.S initialization code (This also means
- that the dts file for virtex405 targets should be
- named (virtex405-<board>.dts). Search the wrapper
- script for 'virtex405' and see the file
- arch/powerpc/boot/virtex405-head.S for details.
- treeImage.%; Image format for used with OpenBIOS firmware found
- on some ppc4xx hardware. This image embeds a device
- tree blob inside the image.
- uImage: Native image format used by U-Boot. The uImage target
- does not add any boot code. It just wraps a compressed
- vmlinux in the uImage data structure. This image
- requires a version of U-Boot that is able to pass
- a device tree to the kernel at boot. If using an older
- version of U-Boot, then you need to use a cuImage
- instead.
- zImage.%: Image format which does not embed a device tree.
- Used by OpenFirmware and other firmware interfaces
- which are able to supply a device tree. This image
- expects firmware to provide the device tree at boot.
- Typically, if you have general purpose PowerPC
- hardware then you want this image format.
-
-Image types which embed a device tree blob (simpleImage, dtbImage, treeImage,
-and cuImage) all generate the device tree blob from a file in the
-arch/powerpc/boot/dts/ directory. The Makefile selects the correct device
-tree source based on the name of the target. Therefore, if the kernel is
-built with 'make treeImage.walnut simpleImage.virtex405-ml403', then the
-build system will use arch/powerpc/boot/dts/walnut.dts to build
-treeImage.walnut and arch/powerpc/boot/dts/virtex405-ml403.dts to build
-the simpleImage.virtex405-ml403.
-
-Two special targets called 'zImage' and 'zImage.initrd' also exist. These
-targets build all the default images as selected by the kernel configuration.
-Default images are selected by the boot wrapper Makefile
-(arch/powerpc/boot/Makefile) by adding targets to the $image-y variable. Look
-at the Makefile to see which default image targets are available.
-
-How it is built
----------------
-arch/powerpc is designed to support multiplatform kernels, which means
-that a single vmlinux image can be booted on many different target boards.
-It also means that the boot wrapper must be able to wrap for many kinds of
-images on a single build. The design decision was made to not use any
-conditional compilation code (#ifdef, etc) in the boot wrapper source code.
-All of the boot wrapper pieces are buildable at any time regardless of the
-kernel configuration. Building all the wrapper bits on every kernel build
-also ensures that obscure parts of the wrapper are at the very least compile
-tested in a large variety of environments.
-
-The wrapper is adapted for different image types at link time by linking in
-just the wrapper bits that are appropriate for the image type. The 'wrapper
-script' (found in arch/powerpc/boot/wrapper) is called by the Makefile and
-is responsible for selecting the correct wrapper bits for the image type.
-The arguments are well documented in the script's comment block, so they
-are not repeated here. However, it is worth mentioning that the script
-uses the -p (platform) argument as the main method of deciding which wrapper
-bits to compile in. Look for the large 'case "$platform" in' block in the
-middle of the script. This is also the place where platform specific fixups
-can be selected by changing the link order.
-
-In particular, care should be taken when working with cuImages. cuImage
-wrapper bits are very board specific and care should be taken to make sure
-the target you are trying to build is supported by the wrapper bits.
diff --git a/Documentation/powerpc/conf.py b/Documentation/powerpc/conf.py
new file mode 100644
index 000000000000..aba67e9e8235
--- /dev/null
+++ b/Documentation/powerpc/conf.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8; mode: python -*-
+
+project = 'PowerPC Documentation'
+
+tags.add("subproject")
+
+latex_documents = [
+ ('index', 'powerpc.tex', 'Linux Kernel Development Documentation',
+ 'The kernel development community', 'manual'),
+]
diff --git a/Documentation/powerpc/cpu_features.rst b/Documentation/powerpc/cpu_features.rst
new file mode 100644
index 000000000000..fe0b71c23559
--- /dev/null
+++ b/Documentation/powerpc/cpu_features.rst
@@ -0,0 +1,62 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============
+CPU Features
+============
+
+Hollis Blanchard <hollis@austin.ibm.com>
+5 Jun 2002
+
+This document describes the system (including self-modifying code) used
+in the PPC Linux kernel to support a variety of PowerPC CPUs without
+requiring compile-time selection.
+
+Early in the boot process the ppc32 kernel detects the current CPU type
+and chooses a set of features accordingly. Some examples include Altivec
+support, split instruction and data caches, and if the CPU supports the
+DOZE and NAP sleep modes.
+
+Detection of the feature set is simple. A list of processors can be
+found in arch/powerpc/kernel/cputable.c. The PVR register is masked and
+compared with each value in the list. If a match is found, the
+cpu_features of cur_cpu_spec is assigned to the feature bitmask for this
+processor and a __setup_cpu function is called.
+
+C code may test ``cur_cpu_spec[smp_processor_id()]->cpu_features`` for a
+particular feature bit. This is done in quite a few places, for example
+in ppc_setup_l2cr().
+
+Implementing cpufeatures in assembly is a little more involved. There
+are several paths that are performance-critical and would suffer if an
+array index, structure dereference, and conditional branch were
+added. To avoid the performance penalty but still allow for runtime
+(rather than compile-time) CPU selection, unused code is replaced by
+'nop' instructions. This nop'ing is based on CPU 0's capabilities, so a
+multi-processor system with non-identical processors will not work (but
+such a system would likely have other problems anyways).
+
+After detecting the processor type, the kernel patches out sections of
+code that shouldn't be used by writing nop's over it. Using cpufeatures
+requires just 2 macros (found in arch/powerpc/include/asm/cputable.h),
+as seen in head.S transfer_to_handler::
+
+ #ifdef CONFIG_ALTIVEC
+ BEGIN_FTR_SECTION
+ mfspr r22,SPRN_VRSAVE /* if G4, save vrsave register value */
+ stw r22,THREAD_VRSAVE(r23)
+ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+ #endif /* CONFIG_ALTIVEC */
+
+If CPU 0 supports Altivec, the code is left untouched. If it doesn't,
+both instructions are replaced with nop's.
+
+The END_FTR_SECTION macro has two simpler variations:
+END_FTR_SECTION_IFSET and END_FTR_SECTION_IFCLR. These simply test if a
+flag is set (in ``cur_cpu_spec[0]->cpu_features``) or is cleared,
+respectively. These two macros should be used in the majority of cases.
+
+The END_FTR_SECTION macros are implemented by storing information about
+this code in the '__ftr_fixup' ELF section. When do_cpu_ftr_fixups
+(arch/powerpc/kernel/misc.S) is invoked, it will iterate over the
+records in __ftr_fixup, and if the required feature is not present it
+will loop writing nop's from each BEGIN_FTR_SECTION to END_FTR_SECTION.
diff --git a/Documentation/powerpc/cpu_features.txt b/Documentation/powerpc/cpu_features.txt
deleted file mode 100644
index ae09df8722c8..000000000000
--- a/Documentation/powerpc/cpu_features.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-Hollis Blanchard <hollis@austin.ibm.com>
-5 Jun 2002
-
-This document describes the system (including self-modifying code) used in the
-PPC Linux kernel to support a variety of PowerPC CPUs without requiring
-compile-time selection.
-
-Early in the boot process the ppc32 kernel detects the current CPU type and
-chooses a set of features accordingly. Some examples include Altivec support,
-split instruction and data caches, and if the CPU supports the DOZE and NAP
-sleep modes.
-
-Detection of the feature set is simple. A list of processors can be found in
-arch/powerpc/kernel/cputable.c. The PVR register is masked and compared with
-each value in the list. If a match is found, the cpu_features of cur_cpu_spec
-is assigned to the feature bitmask for this processor and a __setup_cpu
-function is called.
-
-C code may test 'cur_cpu_spec[smp_processor_id()]->cpu_features' for a
-particular feature bit. This is done in quite a few places, for example
-in ppc_setup_l2cr().
-
-Implementing cpufeatures in assembly is a little more involved. There are
-several paths that are performance-critical and would suffer if an array
-index, structure dereference, and conditional branch were added. To avoid the
-performance penalty but still allow for runtime (rather than compile-time) CPU
-selection, unused code is replaced by 'nop' instructions. This nop'ing is
-based on CPU 0's capabilities, so a multi-processor system with non-identical
-processors will not work (but such a system would likely have other problems
-anyways).
-
-After detecting the processor type, the kernel patches out sections of code
-that shouldn't be used by writing nop's over it. Using cpufeatures requires
-just 2 macros (found in arch/powerpc/include/asm/cputable.h), as seen in head.S
-transfer_to_handler:
-
- #ifdef CONFIG_ALTIVEC
- BEGIN_FTR_SECTION
- mfspr r22,SPRN_VRSAVE /* if G4, save vrsave register value */
- stw r22,THREAD_VRSAVE(r23)
- END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
- #endif /* CONFIG_ALTIVEC */
-
-If CPU 0 supports Altivec, the code is left untouched. If it doesn't, both
-instructions are replaced with nop's.
-
-The END_FTR_SECTION macro has two simpler variations: END_FTR_SECTION_IFSET
-and END_FTR_SECTION_IFCLR. These simply test if a flag is set (in
-cur_cpu_spec[0]->cpu_features) or is cleared, respectively. These two macros
-should be used in the majority of cases.
-
-The END_FTR_SECTION macros are implemented by storing information about this
-code in the '__ftr_fixup' ELF section. When do_cpu_ftr_fixups
-(arch/powerpc/kernel/misc.S) is invoked, it will iterate over the records in
-__ftr_fixup, and if the required feature is not present it will loop writing
-nop's from each BEGIN_FTR_SECTION to END_FTR_SECTION.
diff --git a/Documentation/powerpc/eeh-pci-error-recovery.rst b/Documentation/powerpc/eeh-pci-error-recovery.rst
new file mode 100644
index 000000000000..2abae1e0a428
--- /dev/null
+++ b/Documentation/powerpc/eeh-pci-error-recovery.rst
@@ -0,0 +1,319 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==========================
+PCI Bus EEH Error Recovery
+==========================
+
+Linas Vepstas
+<linas@austin.ibm.com>
+12 January 2005
+
+
+Overview
+========
+
+The IBM POWER-based pSeries and iSeries computers include PCI bus
+controller chips that have extended capabilities for detecting and
+reporting a large variety of PCI bus error conditions. These features
+go under the name of "EEH", for "Enhanced Error Handling". The EEH
+hardware features allow PCI bus errors to be cleared and a PCI card to
+be "rebooted", without also having to reboot the operating system.
+
+This is in contrast to traditional PCI error handling, where the PCI
+chip is wired directly to the CPU, and an error would cause a CPU
+machine-check/check-stop condition, halting the CPU entirely. Another
+"traditional" technique is to ignore such errors, which can lead to data
+corruption, both of user data or of kernel data, hung/unresponsive
+adapters, or system crashes/lockups. Thus, the idea behind EEH is that
+the operating system can become more reliable and robust by protecting
+it from PCI errors, and giving the OS the ability to "reboot"/recover
+individual PCI devices.
+
+Future systems from other vendors, based on the PCI-E specification, may
+contain similar features.
+
+
+Causes of EEH Errors
+====================
+
+EEH was originally designed to guard against hardware failure, such as
+PCI cards dying from heat, humidity, dust, vibration and bad electrical
+connections. The vast majority of EEH errors seen in "real life" are due
+to either poorly seated PCI cards, or, unfortunately quite commonly, due
+to device driver bugs, device firmware bugs, and sometimes PCI card
+hardware bugs.
+
+The most common software bug, is one that causes the device to attempt
+to DMA to a location in system memory that has not been reserved for DMA
+access for that card. This is a powerful feature, as it prevents what;
+otherwise, would have been silent memory corruption caused by the bad
+DMA. A number of device driver bugs have been found and fixed in this
+way over the past few years. Other possible causes of EEH errors
+include data or address line parity errors (for example, due to poor
+electrical connectivity due to a poorly seated card), and PCI-X
+split-completion errors (due to software, device firmware, or device PCI
+hardware bugs). The vast majority of "true hardware failures" can be
+cured by physically removing and re-seating the PCI card.
+
+
+Detection and Recovery
+======================
+
+In the following discussion, a generic overview of how to detect and
+recover from EEH errors will be presented. This is followed by an
+overview of how the current implementation in the Linux kernel does it.
+The actual implementation is subject to change, and some of the finer
+points are still being debated. These may in turn be swayed if or when
+other architectures implement similar functionality.
+
+When a PCI Host Bridge (PHB, the bus controller connecting the PCI bus
+to the system CPU electronics complex) detects a PCI error condition, it
+will "isolate" the affected PCI card. Isolation will block all writes
+(either to the card from the system, or from the card to the system),
+and it will cause all reads to return all-ff's (0xff, 0xffff, 0xffffffff
+for 8/16/32-bit reads). This value was chosen because it is the same
+value you would get if the device was physically unplugged from the
+slot. This includes access to PCI memory, I/O space, and PCI config
+space. Interrupts; however, will continued to be delivered.
+
+Detection and recovery are performed with the aid of ppc64 firmware.
+The programming interfaces in the Linux kernel into the firmware are
+referred to as RTAS (Run-Time Abstraction Services). The Linux kernel
+does not (should not) access the EEH function in the PCI chipsets
+directly, primarily because there are a number of different chipsets out
+there, each with different interfaces and quirks. The firmware provides
+a uniform abstraction layer that will work with all pSeries and iSeries
+hardware (and be forwards-compatible).
+
+If the OS or device driver suspects that a PCI slot has been
+EEH-isolated, there is a firmware call it can make to determine if this
+is the case. If so, then the device driver should put itself into a
+consistent state (given that it won't be able to complete any pending
+work) and start recovery of the card. Recovery normally would consist
+of resetting the PCI device (holding the PCI #RST line high for two
+seconds), followed by setting up the device config space (the base
+address registers (BAR's), latency timer, cache line size, interrupt
+line, and so on). This is followed by a reinitialization of the device
+driver. In a worst-case scenario, the power to the card can be toggled,
+at least on hot-plug-capable slots. In principle, layers far above the
+device driver probably do not need to know that the PCI card has been
+"rebooted" in this way; ideally, there should be at most a pause in
+Ethernet/disk/USB I/O while the card is being reset.
+
+If the card cannot be recovered after three or four resets, the
+kernel/device driver should assume the worst-case scenario, that the
+card has died completely, and report this error to the sysadmin. In
+addition, error messages are reported through RTAS and also through
+syslogd (/var/log/messages) to alert the sysadmin of PCI resets. The
+correct way to deal with failed adapters is to use the standard PCI
+hotplug tools to remove and replace the dead card.
+
+
+Current PPC64 Linux EEH Implementation
+======================================
+
+At this time, a generic EEH recovery mechanism has been implemented, so
+that individual device drivers do not need to be modified to support EEH
+recovery. This generic mechanism piggy-backs on the PCI hotplug
+infrastructure, and percolates events up through the userspace/udev
+infrastructure. Following is a detailed description of how this is
+accomplished.
+
+EEH must be enabled in the PHB's very early during the boot process, and
+if a PCI slot is hot-plugged. The former is performed by eeh_init() in
+arch/powerpc/platforms/pseries/eeh.c, and the later by
+drivers/pci/hotplug/pSeries_pci.c calling in to the eeh.c code. EEH
+must be enabled before a PCI scan of the device can proceed. Current
+Power5 hardware will not work unless EEH is enabled; although older
+Power4 can run with it disabled. Effectively, EEH can no longer be
+turned off. PCI devices *must* be registered with the EEH code; the EEH
+code needs to know about the I/O address ranges of the PCI device in
+order to detect an error. Given an arbitrary address, the routine
+pci_get_device_by_addr() will find the pci device associated with that
+address (if any).
+
+The default arch/powerpc/include/asm/io.h macros readb(), inb(), insb(),
+etc. include a check to see if the i/o read returned all-0xff's. If so,
+these make a call to eeh_dn_check_failure(), which in turn asks the
+firmware if the all-ff's value is the sign of a true EEH error. If it
+is not, processing continues as normal. The grand total number of these
+false alarms or "false positives" can be seen in /proc/ppc64/eeh
+(subject to change). Normally, almost all of these occur during boot,
+when the PCI bus is scanned, where a large number of 0xff reads are part
+of the bus scan procedure.
+
+If a frozen slot is detected, code in
+arch/powerpc/platforms/pseries/eeh.c will print a stack trace to syslog
+(/var/log/messages). This stack trace has proven to be very useful to
+device-driver authors for finding out at what point the EEH error was
+detected, as the error itself usually occurs slightly beforehand.
+
+Next, it uses the Linux kernel notifier chain/work queue mechanism to
+allow any interested parties to find out about the failure. Device
+drivers, or other parts of the kernel, can use
+``eeh_register_notifier(struct notifier_block *)`` to find out about EEH
+events. The event will include a pointer to the pci device, the device
+node and some state info. Receivers of the event can "do as they wish";
+the default handler will be described further in this section.
+
+To assist in the recovery of the device, eeh.c exports the following
+functions:
+
+- rtas_set_slot_reset() -- assert the PCI #RST line for 1/8th of a
+ second.
+- rtas_configure_bridge() -- ask firmware to configure any PCI bridges
+ located topologically under the pci slot.
+- eeh_save_bars() and eeh_restore_bars(): save and restore the PCI
+ config-space info for a device and any devices under it.
+
+A handler for the EEH notifier_block events is implemented in
+drivers/pci/hotplug/pSeries_pci.c, called handle_eeh_events(). It saves
+the device BAR's and then calls rpaphp_unconfig_pci_adapter(). This
+last call causes the device driver for the card to be stopped, which
+causes uevents to go out to user space. This triggers user-space scripts
+that might issue commands such as "ifdown eth0" for ethernet cards, and
+so on. This handler then sleeps for 5 seconds, hoping to give the
+user-space scripts enough time to complete. It then resets the PCI
+card, reconfigures the device BAR's, and any bridges underneath. It then
+calls rpaphp_enable_pci_slot(), which restarts the device driver and
+triggers more user-space events (for example, calling "ifup eth0" for
+ethernet cards).
+
+
+Device Shutdown and User-Space Events
+=====================================
+
+This section documents what happens when a pci slot is unconfigured,
+focusing on how the device driver gets shut down, and on how the events
+get delivered to user-space scripts.
+
+Following is an example sequence of events that cause a device driver
+close function to be called during the first phase of an EEH reset. The
+following sequence is an example of the pcnet32 device driver.::
+
+ rpa_php_unconfig_pci_adapter (struct slot *) { // in rpaphp_pci.c
+ calls
+ pci_remove_bus_device (struct pci_dev *) { // in /drivers/pci/remove.c
+ calls
+ pci_destroy_dev (struct pci_dev *) {
+ calls
+ device_unregister (&dev->dev) } // in /drivers/base/core.c
+ calls
+ device_del (struct device *) {
+ calls
+ bus_remove_device() { // in /drivers/base/bus.c
+ calls
+ device_release_driver() {
+ calls
+ struct device_driver->remove() // which is just
+ pci_device_remove() { // in /drivers/pci/pci_driver.c
+ calls
+ struct pci_driver->remove() // which is just
+ pcnet32_remove_one() { // in /drivers/net/pcnet32.c
+ calls
+ unregister_netdev() { // in /net/core/dev.c
+ calls
+ dev_close() { // in /net/core/dev.c
+ calls dev->stop(); // which is just
+ pcnet32_close() { // in pcnet32.c
+ which does what you wanted to stop the device
+ }
+ }
+ }
+ which frees pcnet32 device driver memory
+ }
+ }}}}}}
+
+
+ in drivers/pci/pci_driver.c,
+ struct device_driver->remove() is just pci_device_remove()
+ which calls struct pci_driver->remove() which is pcnet32_remove_one()
+ which calls unregister_netdev() (in net/core/dev.c)
+ which calls dev_close() (in net/core/dev.c)
+ which calls dev->stop() which is pcnet32_close()
+ which then does the appropriate shutdown.
+
+
+Following is the analogous stack trace for events sent to user-space
+when the pci device is unconfigured.::
+
+ rpa_php_unconfig_pci_adapter() { // in rpaphp_pci.c
+ calls
+ pci_remove_bus_device (struct pci_dev *) { // in /drivers/pci/remove.c
+ calls
+ pci_destroy_dev (struct pci_dev *) {
+ calls
+ device_unregister (&dev->dev) { // in /drivers/base/core.c
+ calls
+ device_del(struct device * dev) { // in /drivers/base/core.c
+ calls
+ kobject_del() { // in /libs/kobject.c
+ calls
+ kobject_uevent() { // in /libs/kobject.c
+ calls
+ kset_uevent() { // in /lib/kobject.c
+ calls
+ kset->uevent_ops->uevent() // which is really just
+ a call to
+ dev_uevent() { // in /drivers/base/core.c
+ calls
+ dev->bus->uevent() // which is really just a call to
+ pci_uevent () { // in drivers/pci/hotplug.c
+ which prints device name, etc....
+ }
+ }
+ then kobject_uevent() sends a netlink uevent to userspace
+ --> userspace uevent
+ (during early boot, nobody listens to netlink events and
+ kobject_uevent() executes uevent_helper[], which runs the
+ event process /sbin/hotplug)
+ }
+ }
+ kobject_del() then calls sysfs_remove_dir(), which would
+ trigger any user-space daemon that was watching /sysfs,
+ and notice the delete event.
+
+
+Pro's and Con's of the Current Design
+=====================================
+
+There are several issues with the current EEH software recovery design,
+which may be addressed in future revisions. But first, note that the
+big plus of the current design is that no changes need to be made to
+individual device drivers, so that the current design throws a wide net.
+The biggest negative of the design is that it potentially disturbs
+network daemons and file systems that didn't need to be disturbed.
+
+- A minor complaint is that resetting the network card causes user-space
+ back-to-back ifdown/ifup burps that potentially disturb network
+ daemons, that didn't need to even know that the pci card was being
+ rebooted.
+
+- A more serious concern is that the same reset, for SCSI devices,
+ causes havoc to mounted file systems. Scripts cannot post-facto
+ unmount a file system without flushing pending buffers, but this is
+ impossible, because I/O has already been stopped. Thus, ideally, the
+ reset should happen at or below the block layer, so that the file
+ systems are not disturbed.
+
+ Reiserfs does not tolerate errors returned from the block device.
+ Ext3fs seems to be tolerant, retrying reads/writes until it does
+ succeed. Both have been only lightly tested in this scenario.
+
+ The SCSI-generic subsystem already has built-in code for performing
+ SCSI device resets, SCSI bus resets, and SCSI host-bus-adapter (HBA)
+ resets. These are cascaded into a chain of attempted resets if a SCSI
+ command fails. These are completely hidden from the block layer. It
+ would be very natural to add an EEH reset into this chain of events.
+
+- If a SCSI error occurs for the root device, all is lost unless the
+ sysadmin had the foresight to run /bin, /sbin, /etc, /var and so on,
+ out of ramdisk/tmpfs.
+
+
+Conclusions
+===========
+
+There's forward progress ...
+
+
diff --git a/Documentation/powerpc/eeh-pci-error-recovery.txt b/Documentation/powerpc/eeh-pci-error-recovery.txt
deleted file mode 100644
index 678189280bb4..000000000000
--- a/Documentation/powerpc/eeh-pci-error-recovery.txt
+++ /dev/null
@@ -1,334 +0,0 @@
-
-
- PCI Bus EEH Error Recovery
- --------------------------
- Linas Vepstas
- <linas@austin.ibm.com>
- 12 January 2005
-
-
-Overview:
----------
-The IBM POWER-based pSeries and iSeries computers include PCI bus
-controller chips that have extended capabilities for detecting and
-reporting a large variety of PCI bus error conditions. These features
-go under the name of "EEH", for "Enhanced Error Handling". The EEH
-hardware features allow PCI bus errors to be cleared and a PCI
-card to be "rebooted", without also having to reboot the operating
-system.
-
-This is in contrast to traditional PCI error handling, where the
-PCI chip is wired directly to the CPU, and an error would cause
-a CPU machine-check/check-stop condition, halting the CPU entirely.
-Another "traditional" technique is to ignore such errors, which
-can lead to data corruption, both of user data or of kernel data,
-hung/unresponsive adapters, or system crashes/lockups. Thus,
-the idea behind EEH is that the operating system can become more
-reliable and robust by protecting it from PCI errors, and giving
-the OS the ability to "reboot"/recover individual PCI devices.
-
-Future systems from other vendors, based on the PCI-E specification,
-may contain similar features.
-
-
-Causes of EEH Errors
---------------------
-EEH was originally designed to guard against hardware failure, such
-as PCI cards dying from heat, humidity, dust, vibration and bad
-electrical connections. The vast majority of EEH errors seen in
-"real life" are due to either poorly seated PCI cards, or,
-unfortunately quite commonly, due to device driver bugs, device firmware
-bugs, and sometimes PCI card hardware bugs.
-
-The most common software bug, is one that causes the device to
-attempt to DMA to a location in system memory that has not been
-reserved for DMA access for that card. This is a powerful feature,
-as it prevents what; otherwise, would have been silent memory
-corruption caused by the bad DMA. A number of device driver
-bugs have been found and fixed in this way over the past few
-years. Other possible causes of EEH errors include data or
-address line parity errors (for example, due to poor electrical
-connectivity due to a poorly seated card), and PCI-X split-completion
-errors (due to software, device firmware, or device PCI hardware bugs).
-The vast majority of "true hardware failures" can be cured by
-physically removing and re-seating the PCI card.
-
-
-Detection and Recovery
-----------------------
-In the following discussion, a generic overview of how to detect
-and recover from EEH errors will be presented. This is followed
-by an overview of how the current implementation in the Linux
-kernel does it. The actual implementation is subject to change,
-and some of the finer points are still being debated. These
-may in turn be swayed if or when other architectures implement
-similar functionality.
-
-When a PCI Host Bridge (PHB, the bus controller connecting the
-PCI bus to the system CPU electronics complex) detects a PCI error
-condition, it will "isolate" the affected PCI card. Isolation
-will block all writes (either to the card from the system, or
-from the card to the system), and it will cause all reads to
-return all-ff's (0xff, 0xffff, 0xffffffff for 8/16/32-bit reads).
-This value was chosen because it is the same value you would
-get if the device was physically unplugged from the slot.
-This includes access to PCI memory, I/O space, and PCI config
-space. Interrupts; however, will continued to be delivered.
-
-Detection and recovery are performed with the aid of ppc64
-firmware. The programming interfaces in the Linux kernel
-into the firmware are referred to as RTAS (Run-Time Abstraction
-Services). The Linux kernel does not (should not) access
-the EEH function in the PCI chipsets directly, primarily because
-there are a number of different chipsets out there, each with
-different interfaces and quirks. The firmware provides a
-uniform abstraction layer that will work with all pSeries
-and iSeries hardware (and be forwards-compatible).
-
-If the OS or device driver suspects that a PCI slot has been
-EEH-isolated, there is a firmware call it can make to determine if
-this is the case. If so, then the device driver should put itself
-into a consistent state (given that it won't be able to complete any
-pending work) and start recovery of the card. Recovery normally
-would consist of resetting the PCI device (holding the PCI #RST
-line high for two seconds), followed by setting up the device
-config space (the base address registers (BAR's), latency timer,
-cache line size, interrupt line, and so on). This is followed by a
-reinitialization of the device driver. In a worst-case scenario,
-the power to the card can be toggled, at least on hot-plug-capable
-slots. In principle, layers far above the device driver probably
-do not need to know that the PCI card has been "rebooted" in this
-way; ideally, there should be at most a pause in Ethernet/disk/USB
-I/O while the card is being reset.
-
-If the card cannot be recovered after three or four resets, the
-kernel/device driver should assume the worst-case scenario, that the
-card has died completely, and report this error to the sysadmin.
-In addition, error messages are reported through RTAS and also through
-syslogd (/var/log/messages) to alert the sysadmin of PCI resets.
-The correct way to deal with failed adapters is to use the standard
-PCI hotplug tools to remove and replace the dead card.
-
-
-Current PPC64 Linux EEH Implementation
---------------------------------------
-At this time, a generic EEH recovery mechanism has been implemented,
-so that individual device drivers do not need to be modified to support
-EEH recovery. This generic mechanism piggy-backs on the PCI hotplug
-infrastructure, and percolates events up through the userspace/udev
-infrastructure. Following is a detailed description of how this is
-accomplished.
-
-EEH must be enabled in the PHB's very early during the boot process,
-and if a PCI slot is hot-plugged. The former is performed by
-eeh_init() in arch/powerpc/platforms/pseries/eeh.c, and the later by
-drivers/pci/hotplug/pSeries_pci.c calling in to the eeh.c code.
-EEH must be enabled before a PCI scan of the device can proceed.
-Current Power5 hardware will not work unless EEH is enabled;
-although older Power4 can run with it disabled. Effectively,
-EEH can no longer be turned off. PCI devices *must* be
-registered with the EEH code; the EEH code needs to know about
-the I/O address ranges of the PCI device in order to detect an
-error. Given an arbitrary address, the routine
-pci_get_device_by_addr() will find the pci device associated
-with that address (if any).
-
-The default arch/powerpc/include/asm/io.h macros readb(), inb(), insb(),
-etc. include a check to see if the i/o read returned all-0xff's.
-If so, these make a call to eeh_dn_check_failure(), which in turn
-asks the firmware if the all-ff's value is the sign of a true EEH
-error. If it is not, processing continues as normal. The grand
-total number of these false alarms or "false positives" can be
-seen in /proc/ppc64/eeh (subject to change). Normally, almost
-all of these occur during boot, when the PCI bus is scanned, where
-a large number of 0xff reads are part of the bus scan procedure.
-
-If a frozen slot is detected, code in
-arch/powerpc/platforms/pseries/eeh.c will print a stack trace to
-syslog (/var/log/messages). This stack trace has proven to be very
-useful to device-driver authors for finding out at what point the EEH
-error was detected, as the error itself usually occurs slightly
-beforehand.
-
-Next, it uses the Linux kernel notifier chain/work queue mechanism to
-allow any interested parties to find out about the failure. Device
-drivers, or other parts of the kernel, can use
-eeh_register_notifier(struct notifier_block *) to find out about EEH
-events. The event will include a pointer to the pci device, the
-device node and some state info. Receivers of the event can "do as
-they wish"; the default handler will be described further in this
-section.
-
-To assist in the recovery of the device, eeh.c exports the
-following functions:
-
-rtas_set_slot_reset() -- assert the PCI #RST line for 1/8th of a second
-rtas_configure_bridge() -- ask firmware to configure any PCI bridges
- located topologically under the pci slot.
-eeh_save_bars() and eeh_restore_bars(): save and restore the PCI
- config-space info for a device and any devices under it.
-
-
-A handler for the EEH notifier_block events is implemented in
-drivers/pci/hotplug/pSeries_pci.c, called handle_eeh_events().
-It saves the device BAR's and then calls rpaphp_unconfig_pci_adapter().
-This last call causes the device driver for the card to be stopped,
-which causes uevents to go out to user space. This triggers
-user-space scripts that might issue commands such as "ifdown eth0"
-for ethernet cards, and so on. This handler then sleeps for 5 seconds,
-hoping to give the user-space scripts enough time to complete.
-It then resets the PCI card, reconfigures the device BAR's, and
-any bridges underneath. It then calls rpaphp_enable_pci_slot(),
-which restarts the device driver and triggers more user-space
-events (for example, calling "ifup eth0" for ethernet cards).
-
-
-Device Shutdown and User-Space Events
--------------------------------------
-This section documents what happens when a pci slot is unconfigured,
-focusing on how the device driver gets shut down, and on how the
-events get delivered to user-space scripts.
-
-Following is an example sequence of events that cause a device driver
-close function to be called during the first phase of an EEH reset.
-The following sequence is an example of the pcnet32 device driver.
-
- rpa_php_unconfig_pci_adapter (struct slot *) // in rpaphp_pci.c
- {
- calls
- pci_remove_bus_device (struct pci_dev *) // in /drivers/pci/remove.c
- {
- calls
- pci_destroy_dev (struct pci_dev *)
- {
- calls
- device_unregister (&dev->dev) // in /drivers/base/core.c
- {
- calls
- device_del (struct device *)
- {
- calls
- bus_remove_device() // in /drivers/base/bus.c
- {
- calls
- device_release_driver()
- {
- calls
- struct device_driver->remove() which is just
- pci_device_remove() // in /drivers/pci/pci_driver.c
- {
- calls
- struct pci_driver->remove() which is just
- pcnet32_remove_one() // in /drivers/net/pcnet32.c
- {
- calls
- unregister_netdev() // in /net/core/dev.c
- {
- calls
- dev_close() // in /net/core/dev.c
- {
- calls dev->stop();
- which is just pcnet32_close() // in pcnet32.c
- {
- which does what you wanted
- to stop the device
- }
- }
- }
- which
- frees pcnet32 device driver memory
- }
- }}}}}}
-
-
- in drivers/pci/pci_driver.c,
- struct device_driver->remove() is just pci_device_remove()
- which calls struct pci_driver->remove() which is pcnet32_remove_one()
- which calls unregister_netdev() (in net/core/dev.c)
- which calls dev_close() (in net/core/dev.c)
- which calls dev->stop() which is pcnet32_close()
- which then does the appropriate shutdown.
-
----
-Following is the analogous stack trace for events sent to user-space
-when the pci device is unconfigured.
-
-rpa_php_unconfig_pci_adapter() { // in rpaphp_pci.c
- calls
- pci_remove_bus_device (struct pci_dev *) { // in /drivers/pci/remove.c
- calls
- pci_destroy_dev (struct pci_dev *) {
- calls
- device_unregister (&dev->dev) { // in /drivers/base/core.c
- calls
- device_del(struct device * dev) { // in /drivers/base/core.c
- calls
- kobject_del() { //in /libs/kobject.c
- calls
- kobject_uevent() { // in /libs/kobject.c
- calls
- kset_uevent() { // in /lib/kobject.c
- calls
- kset->uevent_ops->uevent() // which is really just
- a call to
- dev_uevent() { // in /drivers/base/core.c
- calls
- dev->bus->uevent() which is really just a call to
- pci_uevent () { // in drivers/pci/hotplug.c
- which prints device name, etc....
- }
- }
- then kobject_uevent() sends a netlink uevent to userspace
- --> userspace uevent
- (during early boot, nobody listens to netlink events and
- kobject_uevent() executes uevent_helper[], which runs the
- event process /sbin/hotplug)
- }
- }
- kobject_del() then calls sysfs_remove_dir(), which would
- trigger any user-space daemon that was watching /sysfs,
- and notice the delete event.
-
-
-Pro's and Con's of the Current Design
--------------------------------------
-There are several issues with the current EEH software recovery design,
-which may be addressed in future revisions. But first, note that the
-big plus of the current design is that no changes need to be made to
-individual device drivers, so that the current design throws a wide net.
-The biggest negative of the design is that it potentially disturbs
-network daemons and file systems that didn't need to be disturbed.
-
--- A minor complaint is that resetting the network card causes
- user-space back-to-back ifdown/ifup burps that potentially disturb
- network daemons, that didn't need to even know that the pci
- card was being rebooted.
-
--- A more serious concern is that the same reset, for SCSI devices,
- causes havoc to mounted file systems. Scripts cannot post-facto
- unmount a file system without flushing pending buffers, but this
- is impossible, because I/O has already been stopped. Thus,
- ideally, the reset should happen at or below the block layer,
- so that the file systems are not disturbed.
-
- Reiserfs does not tolerate errors returned from the block device.
- Ext3fs seems to be tolerant, retrying reads/writes until it does
- succeed. Both have been only lightly tested in this scenario.
-
- The SCSI-generic subsystem already has built-in code for performing
- SCSI device resets, SCSI bus resets, and SCSI host-bus-adapter
- (HBA) resets. These are cascaded into a chain of attempted
- resets if a SCSI command fails. These are completely hidden
- from the block layer. It would be very natural to add an EEH
- reset into this chain of events.
-
--- If a SCSI error occurs for the root device, all is lost unless
- the sysadmin had the foresight to run /bin, /sbin, /etc, /var
- and so on, out of ramdisk/tmpfs.
-
-
-Conclusions
------------
-There's forward progress ...
-
-
diff --git a/Documentation/powerpc/index.rst b/Documentation/powerpc/index.rst
new file mode 100644
index 000000000000..21e05d09bb42
--- /dev/null
+++ b/Documentation/powerpc/index.rst
@@ -0,0 +1,21 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=====================
+PowerPC Documentation
+=====================
+
+Documentation relating to the PowerPC architecture.
+
+.. toctree::
+ :maxdepth: 2
+
+ DAWR-POWER9
+ bootwrapper
+ cpu_features
+ eeh-pci-error-recovery
+ isa-versions
+ mpc52xx
+ pmu-ebb
+ ptrace
+ syscall64-abi
+ transactional_memory
diff --git a/Documentation/powerpc/isa-versions.rst b/Documentation/powerpc/isa-versions.rst
index 812e20cc898c..946ea9c264de 100644
--- a/Documentation/powerpc/isa-versions.rst
+++ b/Documentation/powerpc/isa-versions.rst
@@ -1,74 +1,176 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==========================
CPU to ISA Version Mapping
==========================
Mapping of some CPU versions to relevant ISA versions.
-========= ====================
-CPU Architecture version
-========= ====================
-Power9 Power ISA v3.0B
-Power8 Power ISA v2.07
-Power7 Power ISA v2.06
-Power6 Power ISA v2.05
-PA6T Power ISA v2.04
-Cell PPU - Power ISA v2.02 with some minor exceptions
- - Plus Altivec/VMX ~= 2.03
-Power5++ Power ISA v2.04 (no VMX)
-Power5+ Power ISA v2.03
-Power5 - PowerPC User Instruction Set Architecture Book I v2.02
- - PowerPC Virtual Environment Architecture Book II v2.02
- - PowerPC Operating Environment Architecture Book III v2.02
-PPC970 - PowerPC User Instruction Set Architecture Book I v2.01
- - PowerPC Virtual Environment Architecture Book II v2.01
- - PowerPC Operating Environment Architecture Book III v2.01
- - Plus Altivec/VMX ~= 2.03
-========= ====================
+.. flat-table::
+ :widths: 2 6
+
+ * - CPU
+ - Architecture version
+
+ * - Power9
+ - Power ISA v3.0B
+
+ * - Power8
+ - Power ISA v2.07
+
+ * - Power7
+ - Power ISA v2.06
+
+ * - Power6
+ - Power ISA v2.05
+
+ * - PA6T
+ - Power ISA v2.04
+
+ * - Cell PPU
+ - Power ISA v2.02 with some minor exceptions
+
+ * - Cell PPU
+ - Plus Altivec/VMX ~= 2.03
+
+ * - Power5++
+ - Power ISA v2.04 (no VMX)
+
+ * - Power5+
+ - Power ISA v2.03
+
+ * - Power5
+ - PowerPC User Instruction Set Architecture Book I v2.02
+
+ * - Power5
+ - PowerPC Virtual Environment Architecture Book II v2.02
+
+ * - Power5
+ - PowerPC Operating Environment Architecture Book III v2.02
+
+ * - PPC970
+ - PowerPC User Instruction Set Architecture Book I v2.01
+
+ * - PPC970
+ - PowerPC Virtual Environment Architecture Book II v2.01
+
+ * - PPC970
+ - PowerPC Operating Environment Architecture Book III v2.01
+
+ * - PPC970
+ - Plus Altivec/VMX ~= 2.03
Key Features
-------------
-
-========== ==================
-CPU VMX (aka. Altivec)
-========== ==================
-Power9 Yes
-Power8 Yes
-Power7 Yes
-Power6 Yes
-PA6T Yes
-Cell PPU Yes
-Power5++ No
-Power5+ No
-Power5 No
-PPC970 Yes
-========== ==================
-
-========== ====
-CPU VSX
-========== ====
-Power9 Yes
-Power8 Yes
-Power7 Yes
-Power6 No
-PA6T No
-Cell PPU No
-Power5++ No
-Power5+ No
-Power5 No
-PPC970 No
-========== ====
-
-========== ====================
-CPU Transactional Memory
-========== ====================
-Power9 Yes (* see transactional_memory.txt)
-Power8 Yes
-Power7 No
-Power6 No
-PA6T No
-Cell PPU No
-Power5++ No
-Power5+ No
-Power5 No
-PPC970 No
-========== ====================
+============
+
+
+.. flat-table::
+ :widths: 2 6
+
+ * - CPU
+ - VMX (aka. Altivec)
+
+ * - Power9
+ - Yes
+
+ * - Power8
+ - Yes
+
+ * - Power7
+ - Yes
+
+ * - Power6
+ - Yes
+
+ * - PA6T
+ - Yes
+
+ * - Cell PPU
+ - Yes
+
+ * - Power5++
+ - No
+
+ * - Power5+
+ - No
+
+ * - Power5
+ - No
+
+ * - PPC970
+ - Yes
+
+
+
+.. flat-table::
+ :widths: 2 6
+
+ * - CPU
+ - VMX (aka. Altivec)
+
+ * - Power9
+ - Yes
+
+ * - Power8
+ - Yes
+
+ * - Power7
+ - Yes
+
+ * - Power6
+ - No
+
+ * - PA6T
+ - No
+
+ * - Cell PPU
+ - No
+
+ * - Power5++
+ - No
+
+ * - Power5+
+ - No
+
+ * - Power5
+ - No
+
+ * - PPC970
+ - No
+
+.. flat-table::
+ :widths: 2 6
+
+ * - CPU
+ - Transactional Memory
+
+ * - Power9
+ - Yes
+
+ * - Power8
+ - Yes
+
+ * - Power7
+ - No
+
+ * - Power6
+ - No
+
+ * - PA6T
+ - No
+
+ * - Cell PPU
+ - No
+
+ * - Power5++
+ - No
+
+ * - Power5+
+ - No
+
+ * - Power5
+ - No
+
+ * - PPC970
+ - No
diff --git a/Documentation/powerpc/mpc52xx.rst b/Documentation/powerpc/mpc52xx.rst
new file mode 100644
index 000000000000..d7f51a3f96ad
--- /dev/null
+++ b/Documentation/powerpc/mpc52xx.rst
@@ -0,0 +1,52 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=============================
+Linux 2.6.x on MPC52xx family
+=============================
+
+For the latest info, go to http://www.246tNt.com/mpc52xx/
+
+To compile/use
+==============
+
+- U-Boot
+
+Edit Makefile to set ARCH=ppc & CROSS_COMPILE=... (also EXTRAVERSION if
+you wish to). Then run::
+
+ # make lite5200_defconfig
+ # make uImage
+
+Then, on U-boot::
+
+ => tftpboot 200000 uImage
+ => tftpboot 400000 pRamdisk
+ => bootm 200000 400000
+
+- DBug
+
+Edit Makefile to set ARCH=ppc & CROSS_COMPILE=... (also EXTRAVERSION if
+you wish to). Then run::
+
+ # make lite5200_defconfig
+ # cp your_initrd.gz arch/ppc/boot/images/ramdisk.image.gz
+ # make zImage.initrd
+ # make
+
+Then in DBug::
+
+ DBug> dn -i zImage.initrd.lite5200
+
+
+Some remarks
+============
+
+- The port is named mpc52xxx, and config options are PPC_MPC52xx. The
+ MGT5100 is not supported, and I'm not sure anyone is interesting in
+ working on it so. I didn't took 5xxx because there's apparently a lot
+ of 5xxx that have nothing to do with the MPC5200. I also included the
+ 'MPC' for the same reason.
+
+- Of course, I inspired myself from the 2.4 port. If you think I forgot
+ to mention you/your company in the copyright of some code, I'll
+ correct it ASAP.
diff --git a/Documentation/powerpc/mpc52xx.txt b/Documentation/powerpc/mpc52xx.txt
deleted file mode 100644
index 0d540a31ea1a..000000000000
--- a/Documentation/powerpc/mpc52xx.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-Linux 2.6.x on MPC52xx family
------------------------------
-
-For the latest info, go to http://www.246tNt.com/mpc52xx/
-
-To compile/use :
-
- - U-Boot:
- # <edit Makefile to set ARCH=ppc & CROSS_COMPILE=... ( also EXTRAVERSION
- if you wish to ).
- # make lite5200_defconfig
- # make uImage
-
- then, on U-boot:
- => tftpboot 200000 uImage
- => tftpboot 400000 pRamdisk
- => bootm 200000 400000
-
- - DBug:
- # <edit Makefile to set ARCH=ppc & CROSS_COMPILE=... ( also EXTRAVERSION
- if you wish to ).
- # make lite5200_defconfig
- # cp your_initrd.gz arch/ppc/boot/images/ramdisk.image.gz
- # make zImage.initrd
- # make
-
- then in DBug:
- DBug> dn -i zImage.initrd.lite5200
-
-
-Some remarks :
- - The port is named mpc52xxx, and config options are PPC_MPC52xx. The MGT5100
- is not supported, and I'm not sure anyone is interesting in working on it
- so. I didn't took 5xxx because there's apparently a lot of 5xxx that have
- nothing to do with the MPC5200. I also included the 'MPC' for the same
- reason.
- - Of course, I inspired myself from the 2.4 port. If you think I forgot to
- mention you/your company in the copyright of some code, I'll correct it
- ASAP.
diff --git a/Documentation/powerpc/pmu-ebb.rst b/Documentation/powerpc/pmu-ebb.rst
new file mode 100644
index 000000000000..85a606adc5a6
--- /dev/null
+++ b/Documentation/powerpc/pmu-ebb.rst
@@ -0,0 +1,148 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+========================
+PMU Event Based Branches
+========================
+
+Event Based Branches (EBBs) are a feature which allows the hardware to
+branch directly to a specified user space address when certain events
+occur.
+
+The full specification is available in Power ISA v2.07:
+
+ https://www.power.org/documentation/power-isa-version-2-07/
+
+One type of event for which EBBs can be configured is PMU exceptions.
+This document describes the API for configuring the Power PMU to
+generate EBBs, using the Linux perf_events API.
+
+
+Terminology
+===========
+
+Throughout this document we will refer to an "EBB event" or "EBB
+events". This just refers to a struct perf_event which has set the "EBB"
+flag in its attr.config. All events which can be configured on the
+hardware PMU are possible "EBB events".
+
+
+Background
+==========
+
+When a PMU EBB occurs it is delivered to the currently running process.
+As such EBBs can only sensibly be used by programs for self-monitoring.
+
+It is a feature of the perf_events API that events can be created on
+other processes, subject to standard permission checks. This is also
+true of EBB events, however unless the target process enables EBBs (via
+mtspr(BESCR)) no EBBs will ever be delivered.
+
+This makes it possible for a process to enable EBBs for itself, but not
+actually configure any events. At a later time another process can come
+along and attach an EBB event to the process, which will then cause EBBs
+to be delivered to the first process. It's not clear if this is
+actually useful.
+
+When the PMU is configured for EBBs, all PMU interrupts are delivered to
+the user process. This means once an EBB event is scheduled on the PMU,
+no non-EBB events can be configured. This means that EBB events can not
+be run concurrently with regular 'perf' commands, or any other perf
+events.
+
+It is however safe to run 'perf' commands on a process which is using
+EBBs. The kernel will in general schedule the EBB event, and perf will
+be notified that its events could not run.
+
+The exclusion between EBB events and regular events is implemented using
+the existing "pinned" and "exclusive" attributes of perf_events. This
+means EBB events will be given priority over other events, unless they
+are also pinned. If an EBB event and a regular event are both pinned,
+then whichever is enabled first will be scheduled and the other will be
+put in error state. See the section below titled "Enabling an EBB
+event" for more information.
+
+
+Creating an EBB event
+=====================
+
+To request that an event is counted using EBB, the event code should
+have bit 63 set.
+
+EBB events must be created with a particular, and restrictive, set of
+attributes - this is so that they interoperate correctly with the rest
+of the perf_events subsystem.
+
+An EBB event must be created with the "pinned" and "exclusive"
+attributes set. Note that if you are creating a group of EBB events,
+only the leader can have these attributes set.
+
+An EBB event must NOT set any of the "inherit", "sample_period", "freq"
+or "enable_on_exec" attributes.
+
+An EBB event must be attached to a task. This is specified to
+perf_event_open() by passing a pid value, typically 0 indicating the
+current task.
+
+All events in a group must agree on whether they want EBB. That is all
+events must request EBB, or none may request EBB.
+
+EBB events must specify the PMC they are to be counted on. This ensures
+userspace is able to reliably determine which PMC the event is scheduled
+on.
+
+
+Enabling an EBB event
+=====================
+
+Once an EBB event has been successfully opened, it must be enabled with
+the perf_events API. This can be achieved either via the ioctl()
+interface, or the prctl() interface.
+
+However, due to the design of the perf_events API, enabling an event
+does not guarantee that it has been scheduled on the PMU. To ensure
+that the EBB event has been scheduled on the PMU, you must perform a
+read() on the event. If the read() returns EOF, then the event has not
+been scheduled and EBBs are not enabled.
+
+This behaviour occurs because the EBB event is pinned and exclusive.
+When the EBB event is enabled it will force all other non-pinned events
+off the PMU. In this case the enable will be successful. However if
+there is already an event pinned on the PMU then the enable will not be
+successful.
+
+
+Reading an EBB event
+====================
+
+It is possible to read() from an EBB event. However the results are
+meaningless. Because interrupts are being delivered to the user process
+the kernel is not able to count the event, and so will return a junk
+value.
+
+
+Closing an EBB event
+====================
+
+When an EBB event is finished with, you can close it using close() as
+for any regular event. If this is the last EBB event the PMU will be
+deconfigured and no further PMU EBBs will be delivered.
+
+
+EBB Handler
+===========
+
+The EBB handler is just regular userspace code, however it must be
+written in the style of an interrupt handler. When the handler is
+entered all registers are live (possibly) and so must be saved somehow
+before the handler can invoke other code.
+
+It's up to the program how to handle this. For C programs a relatively
+simple option is to create an interrupt frame on the stack and save
+registers there.
+
+Fork
+====
+
+EBB events are not inherited across fork. If the child process wishes
+to use EBBs it should open a new event for itself. Similarly the EBB
+state in BESCR/EBBHR/EBBRR is cleared across fork().
diff --git a/Documentation/powerpc/pmu-ebb.txt b/Documentation/powerpc/pmu-ebb.txt
deleted file mode 100644
index 73cd163dbfb8..000000000000
--- a/Documentation/powerpc/pmu-ebb.txt
+++ /dev/null
@@ -1,137 +0,0 @@
-PMU Event Based Branches
-========================
-
-Event Based Branches (EBBs) are a feature which allows the hardware to
-branch directly to a specified user space address when certain events occur.
-
-The full specification is available in Power ISA v2.07:
-
- https://www.power.org/documentation/power-isa-version-2-07/
-
-One type of event for which EBBs can be configured is PMU exceptions. This
-document describes the API for configuring the Power PMU to generate EBBs,
-using the Linux perf_events API.
-
-
-Terminology
------------
-
-Throughout this document we will refer to an "EBB event" or "EBB events". This
-just refers to a struct perf_event which has set the "EBB" flag in its
-attr.config. All events which can be configured on the hardware PMU are
-possible "EBB events".
-
-
-Background
-----------
-
-When a PMU EBB occurs it is delivered to the currently running process. As such
-EBBs can only sensibly be used by programs for self-monitoring.
-
-It is a feature of the perf_events API that events can be created on other
-processes, subject to standard permission checks. This is also true of EBB
-events, however unless the target process enables EBBs (via mtspr(BESCR)) no
-EBBs will ever be delivered.
-
-This makes it possible for a process to enable EBBs for itself, but not
-actually configure any events. At a later time another process can come along
-and attach an EBB event to the process, which will then cause EBBs to be
-delivered to the first process. It's not clear if this is actually useful.
-
-
-When the PMU is configured for EBBs, all PMU interrupts are delivered to the
-user process. This means once an EBB event is scheduled on the PMU, no non-EBB
-events can be configured. This means that EBB events can not be run
-concurrently with regular 'perf' commands, or any other perf events.
-
-It is however safe to run 'perf' commands on a process which is using EBBs. The
-kernel will in general schedule the EBB event, and perf will be notified that
-its events could not run.
-
-The exclusion between EBB events and regular events is implemented using the
-existing "pinned" and "exclusive" attributes of perf_events. This means EBB
-events will be given priority over other events, unless they are also pinned.
-If an EBB event and a regular event are both pinned, then whichever is enabled
-first will be scheduled and the other will be put in error state. See the
-section below titled "Enabling an EBB event" for more information.
-
-
-Creating an EBB event
----------------------
-
-To request that an event is counted using EBB, the event code should have bit
-63 set.
-
-EBB events must be created with a particular, and restrictive, set of
-attributes - this is so that they interoperate correctly with the rest of the
-perf_events subsystem.
-
-An EBB event must be created with the "pinned" and "exclusive" attributes set.
-Note that if you are creating a group of EBB events, only the leader can have
-these attributes set.
-
-An EBB event must NOT set any of the "inherit", "sample_period", "freq" or
-"enable_on_exec" attributes.
-
-An EBB event must be attached to a task. This is specified to perf_event_open()
-by passing a pid value, typically 0 indicating the current task.
-
-All events in a group must agree on whether they want EBB. That is all events
-must request EBB, or none may request EBB.
-
-EBB events must specify the PMC they are to be counted on. This ensures
-userspace is able to reliably determine which PMC the event is scheduled on.
-
-
-Enabling an EBB event
----------------------
-
-Once an EBB event has been successfully opened, it must be enabled with the
-perf_events API. This can be achieved either via the ioctl() interface, or the
-prctl() interface.
-
-However, due to the design of the perf_events API, enabling an event does not
-guarantee that it has been scheduled on the PMU. To ensure that the EBB event
-has been scheduled on the PMU, you must perform a read() on the event. If the
-read() returns EOF, then the event has not been scheduled and EBBs are not
-enabled.
-
-This behaviour occurs because the EBB event is pinned and exclusive. When the
-EBB event is enabled it will force all other non-pinned events off the PMU. In
-this case the enable will be successful. However if there is already an event
-pinned on the PMU then the enable will not be successful.
-
-
-Reading an EBB event
---------------------
-
-It is possible to read() from an EBB event. However the results are
-meaningless. Because interrupts are being delivered to the user process the
-kernel is not able to count the event, and so will return a junk value.
-
-
-Closing an EBB event
---------------------
-
-When an EBB event is finished with, you can close it using close() as for any
-regular event. If this is the last EBB event the PMU will be deconfigured and
-no further PMU EBBs will be delivered.
-
-
-EBB Handler
------------
-
-The EBB handler is just regular userspace code, however it must be written in
-the style of an interrupt handler. When the handler is entered all registers
-are live (possibly) and so must be saved somehow before the handler can invoke
-other code.
-
-It's up to the program how to handle this. For C programs a relatively simple
-option is to create an interrupt frame on the stack and save registers there.
-
-Fork
-----
-
-EBB events are not inherited across fork. If the child process wishes to use
-EBBs it should open a new event for itself. Similarly the EBB state in
-BESCR/EBBHR/EBBRR is cleared across fork().
diff --git a/Documentation/powerpc/ptrace.rst b/Documentation/powerpc/ptrace.rst
new file mode 100644
index 000000000000..34372054740e
--- /dev/null
+++ b/Documentation/powerpc/ptrace.rst
@@ -0,0 +1,177 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+======
+PTRACE
+======
+
+GDB intends to support the following hardware debug features of BookE
+processors:
+
+- 4 hardware breakpoints (IAC)
+- 2 hardware watchpoints (read, write and read-write) (DAC)
+- 2 value conditions for the hardware watchpoints (DVC)
+
+For that, we need to extend ptrace so that GDB can query and set these
+resources. Since we're extending, we're trying to create an interface
+that's extendable and that covers both BookE and server processors, so
+that GDB doesn't need to special-case each of them. We added the
+following 3 new ptrace requests.
+
+
+PTRACE_PPC_GETHWDEBUGINFO
+=========================
+
+Query for GDB to discover the hardware debug features. The main info to
+be returned here is the minimum alignment for the hardware watchpoints.
+BookE processors don't have restrictions here, but server processors
+have an 8-byte alignment restriction for hardware watchpoints. We'd like
+to avoid adding special cases to GDB based on what it sees in AUXV.
+
+Since we're at it, we added other useful info that the kernel can return
+to GDB: this query will return the number of hardware breakpoints,
+hardware watchpoints and whether it supports a range of addresses and a
+condition. The query will fill the following structure provided by the
+requesting process.
+
+ .. code-block:: c
+
+ struct ppc_debug_info {
+ unit32_t version;
+ unit32_t num_instruction_bps;
+ unit32_t num_data_bps;
+ unit32_t num_condition_regs;
+ unit32_t data_bp_alignment;
+ unit32_t sizeof_condition; /* size of the DVC register */
+ uint64_t features; /* bitmask of the individual flags */
+ };
+
+features will have bits indicating whether there is support for:
+
+ .. code-block:: c
+
+ #define PPC_DEBUG_FEATURE_INSN_BP_RANGE 0x1
+ #define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x2
+ #define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x4
+ #define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x8
+ #define PPC_DEBUG_FEATURE_DATA_BP_DAWR 0x10
+
+PTRACE_SETHWDEBUG
+=================
+
+Sets a hardware breakpoint or watchpoint, according to the provided
+structure:
+
+ .. code-block:: c
+
+ struct ppc_hw_breakpoint {
+ uint32_t version;
+ #define PPC_BREAKPOINT_TRIGGER_EXECUTE 0x1
+ #define PPC_BREAKPOINT_TRIGGER_READ 0x2
+ #define PPC_BREAKPOINT_TRIGGER_WRITE 0x4
+ uint32_t trigger_type; /* only some combinations allowed */
+ #define PPC_BREAKPOINT_MODE_EXACT 0x0
+ #define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE 0x1
+ #define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE 0x2
+ #define PPC_BREAKPOINT_MODE_MASK 0x3
+ uint32_t addr_mode; /* address match mode */
+
+ #define PPC_BREAKPOINT_CONDITION_MODE 0x3
+ #define PPC_BREAKPOINT_CONDITION_NONE 0x0
+ #define PPC_BREAKPOINT_CONDITION_AND 0x1
+ #define PPC_BREAKPOINT_CONDITION_EXACT 0x1 /* different name for the same thing as above */
+ #define PPC_BREAKPOINT_CONDITION_OR 0x2
+ #define PPC_BREAKPOINT_CONDITION_AND_OR 0x3
+ #define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000 /* byte enable bits */
+ #define PPC_BREAKPOINT_CONDITION_BE(n) (1<<((n)+16))
+ uint32_t condition_mode; /* break/watchpoint condition flags */
+
+ uint64_t addr;
+ uint64_t addr2;
+ uint64_t condition_value;
+ };
+
+A request specifies one event, not necessarily just one register to be
+set. For instance, if the request is for a watchpoint with a condition,
+both the DAC and DVC registers will be set in the same request.
+
+With this GDB can ask for all kinds of hardware breakpoints and
+watchpoints that the BookE supports. COMEFROM breakpoints available in
+server processors are not contemplated, but that is out of the scope of
+this work.
+
+ptrace will return an integer (handle) uniquely identifying the
+breakpoint or watchpoint just created. This integer will be used in the
+PTRACE_DELHWDEBUG request to ask for its removal. Return -ENOSPC if the
+requested breakpoint can't be allocated on the registers.
+
+**Some examples of using the structure to:**
+
+Set a breakpoint in the first breakpoint register:
+::
+
+ p.version = PPC_DEBUG_CURRENT_VERSION;
+ p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
+ p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
+ p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
+ p.addr = (uint64_t) address;
+ p.addr2 = 0;
+ p.condition_value = 0;
+
+Set a watchpoint which triggers on reads in the second watchpoint
+register:
+
+::
+
+ p.version = PPC_DEBUG_CURRENT_VERSION;
+ p.trigger_type = PPC_BREAKPOINT_TRIGGER_READ;
+ p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
+ p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
+ p.addr = (uint64_t) address;
+ p.addr2 = 0;
+ p.condition_value = 0;
+
+Set a watchpoint which triggers only with a specific value:
+::
+
+ p.version = PPC_DEBUG_CURRENT_VERSION;
+ p.trigger_type = PPC_BREAKPOINT_TRIGGER_READ;
+ p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
+ p.condition_mode = PPC_BREAKPOINT_CONDITION_AND | PPC_BREAKPOINT_CONDITION_BE_ALL;
+ p.addr = (uint64_t) address;
+ p.addr2 = 0;
+ p.condition_value = (uint64_t) condition;
+
+Set a ranged hardware breakpoint:
+::
+
+ p.version = PPC_DEBUG_CURRENT_VERSION;
+ p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
+ p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
+ p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
+ p.addr = (uint64_t) begin_range;
+ p.addr2 = (uint64_t) end_range;
+ p.condition_value = 0;
+
+Set a watchpoint in server processors (BookS):
+::
+
+ p.version = 1;
+ p.trigger_type = PPC_BREAKPOINT_TRIGGER_RW;
+ p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
+ or
+ p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
+
+ p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
+ p.addr = (uint64_t) begin_range;
+ /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, where
+ * addr2 - addr <= 8 Bytes.
+ */
+ p.addr2 = (uint64_t) end_range;
+ p.condition_value = 0;
+
+PTRACE_DELHWDEBUG
+=================
+
+Takes an integer which identifies an existing breakpoint or watchpoint
+(i.e., the value returned from PTRACE_SETHWDEBUG), and deletes the
+corresponding breakpoint or watchpoint..
diff --git a/Documentation/powerpc/ptrace.txt b/Documentation/powerpc/ptrace.txt
deleted file mode 100644
index 99c5ce88d0fe..000000000000
--- a/Documentation/powerpc/ptrace.txt
+++ /dev/null
@@ -1,151 +0,0 @@
-GDB intends to support the following hardware debug features of BookE
-processors:
-
-4 hardware breakpoints (IAC)
-2 hardware watchpoints (read, write and read-write) (DAC)
-2 value conditions for the hardware watchpoints (DVC)
-
-For that, we need to extend ptrace so that GDB can query and set these
-resources. Since we're extending, we're trying to create an interface
-that's extendable and that covers both BookE and server processors, so
-that GDB doesn't need to special-case each of them. We added the
-following 3 new ptrace requests.
-
-1. PTRACE_PPC_GETHWDEBUGINFO
-
-Query for GDB to discover the hardware debug features. The main info to
-be returned here is the minimum alignment for the hardware watchpoints.
-BookE processors don't have restrictions here, but server processors have
-an 8-byte alignment restriction for hardware watchpoints. We'd like to avoid
-adding special cases to GDB based on what it sees in AUXV.
-
-Since we're at it, we added other useful info that the kernel can return to
-GDB: this query will return the number of hardware breakpoints, hardware
-watchpoints and whether it supports a range of addresses and a condition.
-The query will fill the following structure provided by the requesting process:
-
-struct ppc_debug_info {
- unit32_t version;
- unit32_t num_instruction_bps;
- unit32_t num_data_bps;
- unit32_t num_condition_regs;
- unit32_t data_bp_alignment;
- unit32_t sizeof_condition; /* size of the DVC register */
- uint64_t features; /* bitmask of the individual flags */
-};
-
-features will have bits indicating whether there is support for:
-
-#define PPC_DEBUG_FEATURE_INSN_BP_RANGE 0x1
-#define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x2
-#define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x4
-#define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x8
-#define PPC_DEBUG_FEATURE_DATA_BP_DAWR 0x10
-
-2. PTRACE_SETHWDEBUG
-
-Sets a hardware breakpoint or watchpoint, according to the provided structure:
-
-struct ppc_hw_breakpoint {
- uint32_t version;
-#define PPC_BREAKPOINT_TRIGGER_EXECUTE 0x1
-#define PPC_BREAKPOINT_TRIGGER_READ 0x2
-#define PPC_BREAKPOINT_TRIGGER_WRITE 0x4
- uint32_t trigger_type; /* only some combinations allowed */
-#define PPC_BREAKPOINT_MODE_EXACT 0x0
-#define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE 0x1
-#define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE 0x2
-#define PPC_BREAKPOINT_MODE_MASK 0x3
- uint32_t addr_mode; /* address match mode */
-
-#define PPC_BREAKPOINT_CONDITION_MODE 0x3
-#define PPC_BREAKPOINT_CONDITION_NONE 0x0
-#define PPC_BREAKPOINT_CONDITION_AND 0x1
-#define PPC_BREAKPOINT_CONDITION_EXACT 0x1 /* different name for the same thing as above */
-#define PPC_BREAKPOINT_CONDITION_OR 0x2
-#define PPC_BREAKPOINT_CONDITION_AND_OR 0x3
-#define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000 /* byte enable bits */
-#define PPC_BREAKPOINT_CONDITION_BE(n) (1<<((n)+16))
- uint32_t condition_mode; /* break/watchpoint condition flags */
-
- uint64_t addr;
- uint64_t addr2;
- uint64_t condition_value;
-};
-
-A request specifies one event, not necessarily just one register to be set.
-For instance, if the request is for a watchpoint with a condition, both the
-DAC and DVC registers will be set in the same request.
-
-With this GDB can ask for all kinds of hardware breakpoints and watchpoints
-that the BookE supports. COMEFROM breakpoints available in server processors
-are not contemplated, but that is out of the scope of this work.
-
-ptrace will return an integer (handle) uniquely identifying the breakpoint or
-watchpoint just created. This integer will be used in the PTRACE_DELHWDEBUG
-request to ask for its removal. Return -ENOSPC if the requested breakpoint
-can't be allocated on the registers.
-
-Some examples of using the structure to:
-
-- set a breakpoint in the first breakpoint register
-
- p.version = PPC_DEBUG_CURRENT_VERSION;
- p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
- p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
- p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
- p.addr = (uint64_t) address;
- p.addr2 = 0;
- p.condition_value = 0;
-
-- set a watchpoint which triggers on reads in the second watchpoint register
-
- p.version = PPC_DEBUG_CURRENT_VERSION;
- p.trigger_type = PPC_BREAKPOINT_TRIGGER_READ;
- p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
- p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
- p.addr = (uint64_t) address;
- p.addr2 = 0;
- p.condition_value = 0;
-
-- set a watchpoint which triggers only with a specific value
-
- p.version = PPC_DEBUG_CURRENT_VERSION;
- p.trigger_type = PPC_BREAKPOINT_TRIGGER_READ;
- p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
- p.condition_mode = PPC_BREAKPOINT_CONDITION_AND | PPC_BREAKPOINT_CONDITION_BE_ALL;
- p.addr = (uint64_t) address;
- p.addr2 = 0;
- p.condition_value = (uint64_t) condition;
-
-- set a ranged hardware breakpoint
-
- p.version = PPC_DEBUG_CURRENT_VERSION;
- p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
- p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
- p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
- p.addr = (uint64_t) begin_range;
- p.addr2 = (uint64_t) end_range;
- p.condition_value = 0;
-
-- set a watchpoint in server processors (BookS)
-
- p.version = 1;
- p.trigger_type = PPC_BREAKPOINT_TRIGGER_RW;
- p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
- or
- p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
-
- p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
- p.addr = (uint64_t) begin_range;
- /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, where
- * addr2 - addr <= 8 Bytes.
- */
- p.addr2 = (uint64_t) end_range;
- p.condition_value = 0;
-
-3. PTRACE_DELHWDEBUG
-
-Takes an integer which identifies an existing breakpoint or watchpoint
-(i.e., the value returned from PTRACE_SETHWDEBUG), and deletes the
-corresponding breakpoint or watchpoint..
diff --git a/Documentation/powerpc/syscall64-abi.txt b/Documentation/powerpc/syscall64-abi.rst
similarity index 58%
rename from Documentation/powerpc/syscall64-abi.txt
rename to Documentation/powerpc/syscall64-abi.rst
index fa716a0d88bd..396832f6c34f 100644
--- a/Documentation/powerpc/syscall64-abi.txt
+++ b/Documentation/powerpc/syscall64-abi.rst
@@ -1,3 +1,5 @@
+.. SPDX-License-Identifier: GPL-2.0
+
===============================================
Power Architecture 64-bit Linux system call ABI
===============================================
@@ -5,73 +7,77 @@ Power Architecture 64-bit Linux system call ABI
syscall
=======
-syscall calling sequence[*] matches the Power Architecture 64-bit ELF ABI
-specification C function calling sequence, including register preservation
-rules, with the following differences.
+syscall calling sequence :sub:`[*]` matches the Power Architecture 64-bit ELF
+ABI specification C function calling sequence, including register
+preservation rules, with the following differences.
-[*] Some syscalls (typically low-level management functions) may have
- different calling sequences (e.g., rt_sigreturn).
+:sub:`[*]` Some syscalls (typically low-level management functions) may
+have different calling sequences (e.g., rt_sigreturn).
Parameters and return value
---------------------------
The system call number is specified in r0.
-There is a maximum of 6 integer parameters to a syscall, passed in r3-r8.
+There is a maximum of 6 integer parameters to a syscall, passed in
+r3-r8.
-Both a return value and a return error code are returned. cr0.SO is the return
-error code, and r3 is the return value or error code. When cr0.SO is clear,
-the syscall succeeded and r3 is the return value. When cr0.SO is set, the
-syscall failed and r3 is the error code that generally corresponds to errno.
+Both a return value and a return error code are returned. cr0.SO is the
+return error code, and r3 is the return value or error code. When cr0.SO
+is clear, the syscall succeeded and r3 is the return value. When cr0.SO
+is set, the syscall failed and r3 is the error code that generally
+corresponds to errno.
Stack
-----
-System calls do not modify the caller's stack frame. For example, the caller's
-stack frame LR and CR save fields are not used.
+System calls do not modify the caller's stack frame. For example, the
+caller's stack frame LR and CR save fields are not used.
Register preservation rules
---------------------------
Register preservation rules match the ELF ABI calling sequence with the
-following differences:
+following differences::
-r0: Volatile. (System call number.)
-r3: Volatile. (Parameter 1, and return value.)
-r4-r8: Volatile. (Parameters 2-6.)
-cr0: Volatile (cr0.SO is the return error condition)
-cr1, cr5-7: Nonvolatile.
-lr: Nonvolatile.
+ r0: Volatile. (System call number.)
+ r3: Volatile. (Parameter 1, and return value.)
+ r4-r8: Volatile. (Parameters 2-6.)
+ cr0: Volatile (cr0.SO is the return error condition)
+ cr1, cr5-7: Nonvolatile.
+ lr: Nonvolatile.
All floating point and vector data registers as well as control and status
registers are nonvolatile.
Invocation
----------
-The syscall is performed with the sc instruction, and returns with execution
-continuing at the instruction following the sc instruction.
+The syscall is performed with the sc instruction, and returns with
+execution continuing at the instruction following the sc instruction.
Transactional Memory
--------------------
-Syscall behavior can change if the processor is in transactional or suspended
-transaction state, and the syscall can affect the behavior of the transaction.
+Syscall behavior can change if the processor is in transactional or
+suspended transaction state, and the syscall can affect the behavior of the
+transaction.
If the processor is in suspended state when a syscall is made, the syscall
will be performed as normal, and will return as normal. The syscall will be
-performed in suspended state, so its side effects will be persistent according
-to the usual transactional memory semantics. A syscall may or may not result
-in the transaction being doomed by hardware.
+performed in suspended state, so its side effects will be persistent
+according to the usual transactional memory semantics. A syscall may or may
+not result in the transaction being doomed by hardware.
If the processor is in transactional state when a syscall is made, then the
-behavior depends on the presence of PPC_FEATURE2_HTM_NOSC in the AT_HWCAP2 ELF
-auxiliary vector.
+behavior depends on the presence of PPC_FEATURE2_HTM_NOSC in the AT_HWCAP2
+ELF auxiliary vector.
-- If present, which is the case for newer kernels, then the syscall will not
- be performed and the transaction will be doomed by the kernel with the
- failure code TM_CAUSE_SYSCALL | TM_CAUSE_PERSISTENT in the TEXASR SPR.
+- If present, which is the case for newer kernels, then the syscall will
+ not be performed and the transaction will be doomed by the kernel with
+ the failure code TM_CAUSE_SYSCALL | TM_CAUSE_PERSISTENT in the TEXASR
+ SPR.
- If not present (older kernels), then the kernel will suspend the
transactional state and the syscall will proceed as in the case of a
suspended state syscall, and will resume the transactional state before
- returning to the caller. This case is not well defined or supported, so this
- behavior should not be relied upon.
+ returning to the caller. This case is not well defined or supported, so
+ this behavior should not be relied upon.
vsyscall
@@ -96,10 +102,10 @@ lr: Volatile.
Invocation
----------
-The vsyscall is performed with a branch-with-link instruction to the vsyscall
-function address.
+The vsyscall is performed with a branch-with-link instruction to the
+vsyscall function address.
Transactional Memory
--------------------
-vsyscalls will run in the same transactional state as the caller. A vsyscall
-may or may not result in the transaction being doomed by hardware.
+vsyscalls will run in the same transactional state as the caller. A
+vsyscall may or may not result in the transaction being doomed by hardware.
diff --git a/Documentation/powerpc/transactional_memory.rst b/Documentation/powerpc/transactional_memory.rst
new file mode 100644
index 000000000000..5fcfd6bd16f0
--- /dev/null
+++ b/Documentation/powerpc/transactional_memory.rst
@@ -0,0 +1,259 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============================
+Transactional Memory support
+============================
+
+POWER kernel support for this feature is currently limited to supporting
+its use by user programs. It is not currently used by the kernel
+itself.
+
+This file aims to sum up how it is supported by Linux and what behaviour
+you can expect from your user programs.
+
+
+Basic overview
+==============
+
+Hardware Transactional Memory is supported on POWER8 processors, and is
+a feature that enables a different form of atomic memory access.
+Several new instructions are presented to delimit transactions;
+transactions are guaranteed to either complete atomically or roll back
+and undo any partial changes.
+
+A simple transaction looks like this::
+
+ begin_move_money:
+ tbegin
+ beq abort_handler
+
+ ld r4, SAVINGS_ACCT(r3)
+ ld r5, CURRENT_ACCT(r3)
+ subi r5, r5, 1
+ addi r4, r4, 1
+ std r4, SAVINGS_ACCT(r3)
+ std r5, CURRENT_ACCT(r3)
+
+ tend
+
+ b continue
+
+ abort_handler:
+ ... test for odd failures ...
+
+ /* Retry the transaction if it failed because it conflicted with
+ * someone else: */
+ b begin_move_money
+
+
+The 'tbegin' instruction denotes the start point, and 'tend' the end
+point. Between these points the processor is in 'Transactional' state;
+any memory references will complete in one go if there are no conflicts
+with other transactional or non-transactional accesses within the
+system. In this example, the transaction completes as though it were
+normal straight-line code IF no other processor has touched
+SAVINGS_ACCT(r3) or CURRENT_ACCT(r3); an atomic move of money from the
+current account to the savings account has been performed. Even though
+the normal ld/std instructions are used (note no lwarx/stwcx), either
+*both* SAVINGS_ACCT(r3) and CURRENT_ACCT(r3) will be updated, or neither
+will be updated.
+
+If, in the meantime, there is a conflict with the locations accessed by
+the transaction, the transaction will be aborted by the CPU. Register
+and memory state will roll back to that at the 'tbegin', and control
+will continue from 'tbegin+4'. The branch to abort_handler will be
+taken this second time; the abort handler can check the cause of the
+failure, and retry.
+
+Checkpointed registers include all GPRs, FPRs, VRs/VSRs, LR, CCR/CR,
+CTR, FPCSR and a few other status/flag regs; see the ISA for details.
+
+Causes of transaction aborts
+============================
+
+- Conflicts with cache lines used by other processors.
+- Signals.
+- Context switches.
+- See the ISA for full documentation of everything that will abort
+ transactions.
+
+
+
+Syscalls
+========
+
+Syscalls made from within an active transaction will not be performed
+and the transaction will be doomed by the kernel with the failure code
+TM_CAUSE_SYSCALL | TM_CAUSE_PERSISTENT.
+
+Syscalls made from within a suspended transaction are performed as
+normal and the transaction is not explicitly doomed by the kernel.
+However, what the kernel does to perform the syscall may result in the
+transaction being doomed by the hardware. The syscall is performed in
+suspended mode so any side effects will be persistent, independent of
+transaction success or failure. No guarantees are provided by the
+kernel about which syscalls will affect transaction success.
+
+Care must be taken when relying on syscalls to abort during active
+transactions if the calls are made via a library. Libraries may cache
+values (which may give the appearance of success) or perform operations
+that cause transaction failure before entering the kernel (which may
+produce different failure codes). Examples are glibc's getpid() and
+lazy symbol resolution.
+
+
+Signals
+=======
+
+Delivery of signals (both sync and async) during transactions provides a
+second thread state (ucontext/mcontext) to represent the second
+transactional register state. Signal delivery 'treclaim's to capture
+both register states, so signals abort transactions. The usual
+ucontext_t passed to the signal handler represents the
+checkpointed/original register state; the signal appears to have arisen
+at 'tbegin+4'.
+
+If the sighandler ucontext has uc_link set, a second ucontext has been
+delivered. For future compatibility the MSR.TS field should be checked
+to determine the transactional state -- if so, the second ucontext in
+uc->uc_link represents the active transactional registers at the point
+of the signal.
+
+For 64-bit processes, uc->uc_mcontext.regs->msr is a full 64-bit MSR and
+its TS field shows the transactional mode.
+
+For 32-bit processes, the mcontext's MSR register is only 32 bits; the
+top 32 bits are stored in the MSR of the second ucontext, i.e. in
+uc->uc_link->uc_mcontext.regs->msr. The top word contains the
+transactional state TS.
+
+However, basic signal handlers don't need to be aware of transactions
+and simply returning from the handler will deal with things correctly:
+
+Transaction-aware signal handlers can read the transactional register
+state from the second ucontext. This will be necessary for crash
+handlers to determine, for example, the address of the instruction
+causing the SIGSEGV.
+
+Example signal handler:
+
+ .. code-block:: c
+
+ void crash_handler(int sig, siginfo_t *si, void *uc)
+ {
+ ucontext_t *ucp = uc;
+ ucontext_t *transactional_ucp = ucp->uc_link;
+
+ if (ucp_link) {
+ u64 msr = ucp->uc_mcontext.regs->msr;
+ /* May have transactional ucontext! */
+ #ifndef __powerpc64__
+ msr |= ((u64)transactional_ucp->uc_mcontext.regs->msr) << 32;
+ #endif
+ if (MSR_TM_ACTIVE(msr)) {
+ /* Yes, we crashed during a transaction. Oops. */
+ fprintf(stderr, "Transaction to be restarted at 0x%llx, but "
+ "crashy instruction was at 0x%llx\n",
+ ucp->uc_mcontext.regs->nip,
+ transactional_ucp->uc_mcontext.regs->nip);
+ }
+ }
+
+ fix_the_problem(ucp->dar);
+ }
+
+When in an active transaction that takes a signal, we need to be careful
+with the stack. It's possible that the stack has moved back up after
+the tbegin. The obvious case here is when the tbegin is called inside a
+function that returns before a tend. In this case, the stack is part of
+the checkpointed transactional memory state. If we write over this non
+transactionally or in suspend, we are in trouble because if we get a tm
+abort, the program counter and stack pointer will be back at the tbegin
+but our in memory stack won't be valid anymore.
+
+To avoid this, when taking a signal in an active transaction, we need to
+use the stack pointer from the checkpointed state, rather than the
+speculated state. This ensures that the signal context (written tm
+suspended) will be written below the stack required for the rollback.
+The transaction is aborted because of the treclaim, so any memory
+written between the tbegin and the signal will be rolled back anyway.
+
+For signals taken in non-TM or suspended mode, we use the
+normal/non-checkpointed stack pointer.
+
+Any transaction initiated inside a sighandler and suspended on return
+from the sighandler to the kernel will get reclaimed and discarded.
+
+Failure cause codes used by kernel
+==================================
+
+These are defined in <asm/reg.h>, and distinguish different reasons why
+the kernel aborted a transaction::
+
+ TM_CAUSE_RESCHED Thread was rescheduled.
+ TM_CAUSE_TLBI Software TLB invalid.
+ TM_CAUSE_FAC_UNAV FP/VEC/VSX unavailable trap.
+ TM_CAUSE_SYSCALL Syscall from active transaction.
+ TM_CAUSE_SIGNAL Signal delivered.
+ TM_CAUSE_MISC Currently unused.
+ TM_CAUSE_ALIGNMENT Alignment fault.
+ TM_CAUSE_EMULATE Emulation that touched memory.
+
+These can be checked by the user program's abort handler as TEXASR[0:7].
+If bit 7 is set, it indicates that the error is consider persistent.
+For example a TM_CAUSE_ALIGNMENT will be persistent while a
+TM_CAUSE_RESCHED will not.
+
+GDB
+===
+
+GDB and ptrace are not currently TM-aware. If one stops during a
+transaction, it looks like the transaction has just started (the
+checkpointed state is presented). The transaction cannot then be
+continued and will take the failure handler route. Furthermore, the
+transactional 2nd register state will be inaccessible. GDB can
+currently be used on programs using TM, but not sensibly in parts within
+transactions.
+
+POWER9
+======
+
+TM on POWER9 has issues with storing the complete register state. This
+is described in this commit::
+
+ commit 4bb3c7a0208fc13ca70598efd109901a7cd45ae7
+ Author: Paul Mackerras <paulus@ozlabs.org>
+ Date: Wed Mar 21 21:32:01 2018 +1100
+ KVM: PPC: Book3S HV: Work around transactional memory bugs in POWER9
+
+To account for this different POWER9 chips have TM enabled in different
+ways.
+
+On POWER9N DD2.01 and below, TM is disabled. ie HWCAP2[PPC_FEATURE2_HTM]
+is not set.
+
+On POWER9N DD2.1 TM is configured by firmware to always abort a
+transaction when tm suspend occurs. So tsuspend will cause a transaction
+to be aborted and rolled back. Kernel exceptions will also cause the
+transaction to be aborted and rolled back and the exception will not
+occur. If userspace constructs a sigcontext that enables TM suspend, the
+sigcontext will be rejected by the kernel. This mode is advertised to
+users with HWCAP2[PPC_FEATURE2_HTM_NO_SUSPEND] set.
+HWCAP2[PPC_FEATURE2_HTM] is not set in this mode.
+
+On POWER9N DD2.2 and above, KVM and POWERVM emulate TM for guests (as
+described in commit 4bb3c7a0208f), hence TM is enabled for guests
+ie. HWCAP2[PPC_FEATURE2_HTM] is set for guest userspace. Guests that
+makes heavy use of TM suspend (tsuspend or kernel suspend) will result
+in traps into the hypervisor and hence will suffer a performance
+degradation. Host userspace has TM disabled ie. HWCAP2[PPC_FEATURE2_HTM]
+is not set. (although we make enable it at some point in the future if
+we bring the emulation into host userspace context switching).
+
+POWER9C DD1.2 and above are only available with POWERVM and hence Linux
+only runs as a guest. On these systems TM is emulated like on POWER9N
+DD2.2.
+
+Guest migration from POWER8 to POWER9 will work with POWER9N DD2.2 and
+POWER9C DD1.2. Since earlier POWER9 processors don't support TM
+emulation, migration from POWER8 to POWER9 is not supported there.
diff --git a/Documentation/powerpc/transactional_memory.txt b/Documentation/powerpc/transactional_memory.txt
deleted file mode 100644
index 52c023e14f26..000000000000
--- a/Documentation/powerpc/transactional_memory.txt
+++ /dev/null
@@ -1,244 +0,0 @@
-Transactional Memory support
-============================
-
-POWER kernel support for this feature is currently limited to supporting
-its use by user programs. It is not currently used by the kernel itself.
-
-This file aims to sum up how it is supported by Linux and what behaviour you
-can expect from your user programs.
-
-
-Basic overview
-==============
-
-Hardware Transactional Memory is supported on POWER8 processors, and is a
-feature that enables a different form of atomic memory access. Several new
-instructions are presented to delimit transactions; transactions are
-guaranteed to either complete atomically or roll back and undo any partial
-changes.
-
-A simple transaction looks like this:
-
-begin_move_money:
- tbegin
- beq abort_handler
-
- ld r4, SAVINGS_ACCT(r3)
- ld r5, CURRENT_ACCT(r3)
- subi r5, r5, 1
- addi r4, r4, 1
- std r4, SAVINGS_ACCT(r3)
- std r5, CURRENT_ACCT(r3)
-
- tend
-
- b continue
-
-abort_handler:
- ... test for odd failures ...
-
- /* Retry the transaction if it failed because it conflicted with
- * someone else: */
- b begin_move_money
-
-
-The 'tbegin' instruction denotes the start point, and 'tend' the end point.
-Between these points the processor is in 'Transactional' state; any memory
-references will complete in one go if there are no conflicts with other
-transactional or non-transactional accesses within the system. In this
-example, the transaction completes as though it were normal straight-line code
-IF no other processor has touched SAVINGS_ACCT(r3) or CURRENT_ACCT(r3); an
-atomic move of money from the current account to the savings account has been
-performed. Even though the normal ld/std instructions are used (note no
-lwarx/stwcx), either *both* SAVINGS_ACCT(r3) and CURRENT_ACCT(r3) will be
-updated, or neither will be updated.
-
-If, in the meantime, there is a conflict with the locations accessed by the
-transaction, the transaction will be aborted by the CPU. Register and memory
-state will roll back to that at the 'tbegin', and control will continue from
-'tbegin+4'. The branch to abort_handler will be taken this second time; the
-abort handler can check the cause of the failure, and retry.
-
-Checkpointed registers include all GPRs, FPRs, VRs/VSRs, LR, CCR/CR, CTR, FPCSR
-and a few other status/flag regs; see the ISA for details.
-
-Causes of transaction aborts
-============================
-
-- Conflicts with cache lines used by other processors
-- Signals
-- Context switches
-- See the ISA for full documentation of everything that will abort transactions.
-
-
-Syscalls
-========
-
-Syscalls made from within an active transaction will not be performed and the
-transaction will be doomed by the kernel with the failure code TM_CAUSE_SYSCALL
-| TM_CAUSE_PERSISTENT.
-
-Syscalls made from within a suspended transaction are performed as normal and
-the transaction is not explicitly doomed by the kernel. However, what the
-kernel does to perform the syscall may result in the transaction being doomed
-by the hardware. The syscall is performed in suspended mode so any side
-effects will be persistent, independent of transaction success or failure. No
-guarantees are provided by the kernel about which syscalls will affect
-transaction success.
-
-Care must be taken when relying on syscalls to abort during active transactions
-if the calls are made via a library. Libraries may cache values (which may
-give the appearance of success) or perform operations that cause transaction
-failure before entering the kernel (which may produce different failure codes).
-Examples are glibc's getpid() and lazy symbol resolution.
-
-
-Signals
-=======
-
-Delivery of signals (both sync and async) during transactions provides a second
-thread state (ucontext/mcontext) to represent the second transactional register
-state. Signal delivery 'treclaim's to capture both register states, so signals
-abort transactions. The usual ucontext_t passed to the signal handler
-represents the checkpointed/original register state; the signal appears to have
-arisen at 'tbegin+4'.
-
-If the sighandler ucontext has uc_link set, a second ucontext has been
-delivered. For future compatibility the MSR.TS field should be checked to
-determine the transactional state -- if so, the second ucontext in uc->uc_link
-represents the active transactional registers at the point of the signal.
-
-For 64-bit processes, uc->uc_mcontext.regs->msr is a full 64-bit MSR and its TS
-field shows the transactional mode.
-
-For 32-bit processes, the mcontext's MSR register is only 32 bits; the top 32
-bits are stored in the MSR of the second ucontext, i.e. in
-uc->uc_link->uc_mcontext.regs->msr. The top word contains the transactional
-state TS.
-
-However, basic signal handlers don't need to be aware of transactions
-and simply returning from the handler will deal with things correctly:
-
-Transaction-aware signal handlers can read the transactional register state
-from the second ucontext. This will be necessary for crash handlers to
-determine, for example, the address of the instruction causing the SIGSEGV.
-
-Example signal handler:
-
- void crash_handler(int sig, siginfo_t *si, void *uc)
- {
- ucontext_t *ucp = uc;
- ucontext_t *transactional_ucp = ucp->uc_link;
-
- if (ucp_link) {
- u64 msr = ucp->uc_mcontext.regs->msr;
- /* May have transactional ucontext! */
-#ifndef __powerpc64__
- msr |= ((u64)transactional_ucp->uc_mcontext.regs->msr) << 32;
-#endif
- if (MSR_TM_ACTIVE(msr)) {
- /* Yes, we crashed during a transaction. Oops. */
- fprintf(stderr, "Transaction to be restarted at 0x%llx, but "
- "crashy instruction was at 0x%llx\n",
- ucp->uc_mcontext.regs->nip,
- transactional_ucp->uc_mcontext.regs->nip);
- }
- }
-
- fix_the_problem(ucp->dar);
- }
-
-When in an active transaction that takes a signal, we need to be careful with
-the stack. It's possible that the stack has moved back up after the tbegin.
-The obvious case here is when the tbegin is called inside a function that
-returns before a tend. In this case, the stack is part of the checkpointed
-transactional memory state. If we write over this non transactionally or in
-suspend, we are in trouble because if we get a tm abort, the program counter and
-stack pointer will be back at the tbegin but our in memory stack won't be valid
-anymore.
-
-To avoid this, when taking a signal in an active transaction, we need to use
-the stack pointer from the checkpointed state, rather than the speculated
-state. This ensures that the signal context (written tm suspended) will be
-written below the stack required for the rollback. The transaction is aborted
-because of the treclaim, so any memory written between the tbegin and the
-signal will be rolled back anyway.
-
-For signals taken in non-TM or suspended mode, we use the
-normal/non-checkpointed stack pointer.
-
-Any transaction initiated inside a sighandler and suspended on return
-from the sighandler to the kernel will get reclaimed and discarded.
-
-Failure cause codes used by kernel
-==================================
-
-These are defined in <asm/reg.h>, and distinguish different reasons why the
-kernel aborted a transaction:
-
- TM_CAUSE_RESCHED Thread was rescheduled.
- TM_CAUSE_TLBI Software TLB invalid.
- TM_CAUSE_FAC_UNAV FP/VEC/VSX unavailable trap.
- TM_CAUSE_SYSCALL Syscall from active transaction.
- TM_CAUSE_SIGNAL Signal delivered.
- TM_CAUSE_MISC Currently unused.
- TM_CAUSE_ALIGNMENT Alignment fault.
- TM_CAUSE_EMULATE Emulation that touched memory.
-
-These can be checked by the user program's abort handler as TEXASR[0:7]. If
-bit 7 is set, it indicates that the error is consider persistent. For example
-a TM_CAUSE_ALIGNMENT will be persistent while a TM_CAUSE_RESCHED will not.
-
-GDB
-===
-
-GDB and ptrace are not currently TM-aware. If one stops during a transaction,
-it looks like the transaction has just started (the checkpointed state is
-presented). The transaction cannot then be continued and will take the failure
-handler route. Furthermore, the transactional 2nd register state will be
-inaccessible. GDB can currently be used on programs using TM, but not sensibly
-in parts within transactions.
-
-POWER9
-======
-
-TM on POWER9 has issues with storing the complete register state. This
-is described in this commit:
-
- commit 4bb3c7a0208fc13ca70598efd109901a7cd45ae7
- Author: Paul Mackerras <paulus@ozlabs.org>
- Date: Wed Mar 21 21:32:01 2018 +1100
- KVM: PPC: Book3S HV: Work around transactional memory bugs in POWER9
-
-To account for this different POWER9 chips have TM enabled in
-different ways.
-
-On POWER9N DD2.01 and below, TM is disabled. ie
-HWCAP2[PPC_FEATURE2_HTM] is not set.
-
-On POWER9N DD2.1 TM is configured by firmware to always abort a
-transaction when tm suspend occurs. So tsuspend will cause a
-transaction to be aborted and rolled back. Kernel exceptions will also
-cause the transaction to be aborted and rolled back and the exception
-will not occur. If userspace constructs a sigcontext that enables TM
-suspend, the sigcontext will be rejected by the kernel. This mode is
-advertised to users with HWCAP2[PPC_FEATURE2_HTM_NO_SUSPEND] set.
-HWCAP2[PPC_FEATURE2_HTM] is not set in this mode.
-
-On POWER9N DD2.2 and above, KVM and POWERVM emulate TM for guests (as
-described in commit 4bb3c7a0208f), hence TM is enabled for guests
-ie. HWCAP2[PPC_FEATURE2_HTM] is set for guest userspace. Guests that
-makes heavy use of TM suspend (tsuspend or kernel suspend) will result
-in traps into the hypervisor and hence will suffer a performance
-degradation. Host userspace has TM disabled
-ie. HWCAP2[PPC_FEATURE2_HTM] is not set. (although we make enable it
-at some point in the future if we bring the emulation into host
-userspace context switching).
-
-POWER9C DD1.2 and above are only available with POWERVM and hence
-Linux only runs as a guest. On these systems TM is emulated like on
-POWER9N DD2.2.
-
-Guest migration from POWER8 to POWER9 will work with POWER9N DD2.2 and
-POWER9C DD1.2. Since earlier POWER9 processors don't support TM
-emulation, migration from POWER8 to POWER9 is not supported there.
--
2.20.1
^ permalink raw reply related
* Re: [PATCH] powerpc/powernv/idle: Restore IAMR after idle
From: Russell Currey @ 2019-02-07 6:33 UTC (permalink / raw)
To: Nicholas Piggin, linuxppc-dev
In-Reply-To: <1549515373.con208q1rq.astroid@bobo.none>
On Thu, 2019-02-07 at 15:08 +1000, Nicholas Piggin wrote:
> Russell Currey's on February 6, 2019 4:28 pm:
> > Without restoring the IAMR after idle, execution prevention on
> > POWER9
> > with Radix MMU is overwritten and the kernel can freely execute
> > userspace without
> > faulting.
> >
> > This is necessary when returning from any stop state that modifies
> > user
> > state, as well as hypervisor state.
> >
> > To test how this fails without this patch, load the lkdtm driver
> > and
> > do the following:
> >
> > echo EXEC_USERSPACE > /sys/kernel/debug/provoke-crash/DIRECT
> >
> > which won't fault, then boot the kernel with powersave=off, where
> > it
> > will fault. Applying this patch will fix this.
> >
> > Fixes: 3b10d0095a1e ("powerpc/mm/radix: Prevent kernel execution of
> > user
> > space")
> > Cc: <stable@vger.kernel.org>
> > Signed-off-by: Russell Currey <ruscur@russell.cc>
>
> Good catch and debugging. This really should be a quirk, we don't
> want
> to have to restore this thing on a thread switch.
>
> Can we put it under a CONFIG option if we're not using IAMR?
I don't exactly know when we do or don't use the IAMR (since the only
thing I've used it for is radix). When wouldn't we care about
restoring it on hash?
>
> > ---
> > arch/powerpc/include/asm/cpuidle.h | 1 +
> > arch/powerpc/kernel/asm-offsets.c | 1 +
> > arch/powerpc/kernel/idle_book3s.S | 20 ++++++++++++++++++++
> > 3 files changed, 22 insertions(+)
> >
> > diff --git a/arch/powerpc/include/asm/cpuidle.h
> > b/arch/powerpc/include/asm/cpuidle.h
> > index 43e5f31fe64d..ad67dbe59498 100644
> > --- a/arch/powerpc/include/asm/cpuidle.h
> > +++ b/arch/powerpc/include/asm/cpuidle.h
> > @@ -77,6 +77,7 @@ struct stop_sprs {
> > u64 mmcr1;
> > u64 mmcr2;
> > u64 mmcra;
> > + u64 iamr;
> > };
> >
> > #define PNV_IDLE_NAME_LEN 16
> > diff --git a/arch/powerpc/kernel/asm-offsets.c
> > b/arch/powerpc/kernel/asm-offsets.c
> > index 9ffc72ded73a..10e0314c2b0d 100644
> > --- a/arch/powerpc/kernel/asm-offsets.c
> > +++ b/arch/powerpc/kernel/asm-offsets.c
> > @@ -774,6 +774,7 @@ int main(void)
> > STOP_SPR(STOP_MMCR1, mmcr1);
> > STOP_SPR(STOP_MMCR2, mmcr2);
> > STOP_SPR(STOP_MMCRA, mmcra);
> > + STOP_SPR(STOP_IAMR, iamr);
> > #endif
> >
> > DEFINE(PPC_DBELL_SERVER, PPC_DBELL_SERVER);
> > diff --git a/arch/powerpc/kernel/idle_book3s.S
> > b/arch/powerpc/kernel/idle_book3s.S
> > index 7f5ac2e8581b..bb4f552f6c7e 100644
> > --- a/arch/powerpc/kernel/idle_book3s.S
> > +++ b/arch/powerpc/kernel/idle_book3s.S
> > @@ -200,6 +200,12 @@ pnv_powersave_common:
> > /* Continue saving state */
> > SAVE_GPR(2, r1)
> > SAVE_NVGPRS(r1)
> > +
> > +BEGIN_FTR_SECTION
> > + mfspr r5, SPRN_IAMR
> > + std r5, STOP_IAMR(r13)
> > +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> > +
> > mfcr r5
> > std r5,_CCR(r1)
> > std r1,PACAR1(r13)
> > @@ -924,6 +930,13 @@ BEGIN_FTR_SECTION
> > END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
> > REST_NVGPRS(r1)
> > REST_GPR(2, r1)
> > +
> > +BEGIN_FTR_SECTION
> > + ld r4, STOP_IAMR(r13)
> > + mtspr SPRN_IAMR, r4
> > + isync
> > +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
>
> Sigh, good old isync. Suspect you'll get away without it, mtmsrd L=0
> just below is architecturally guaranteeing a CSI, so just add a
> comment
> there, might save a flush.
Makes sense, I wanted to be super safe with this, will drop the isync
and try to execute userspace nonstop and see if there are any (non)
failures.
>
> > +
> > ld r4,PACAKMSR(r13)
> > ld r5,_LINK(r1)
> > ld r6,_CCR(r1)
> > @@ -946,6 +959,13 @@ pnv_wakeup_noloss:
> > BEGIN_FTR_SECTION
> > CHECK_HMI_INTERRUPT
> > END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
> > +
> > +BEGIN_FTR_SECTION
> > + ld r4, STOP_IAMR(r13)
> > + mtspr SPRN_IAMR, r4
> > + isync
> > +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
>
> For the noloss part, it should mean really nothing lost including
> GPRs,
> so I think IAMR *should* be okay here.
Sweet, will drop.
Thanks for the review!
>
> Thanks,
> Nick
^ permalink raw reply
* Re: [PATCH] powerpc/powernv/idle: Restore IAMR after idle
From: Russell Currey @ 2019-02-07 6:28 UTC (permalink / raw)
To: Michael Ellerman, linuxppc-dev
In-Reply-To: <875ztwkyqu.fsf@concordia.ellerman.id.au>
On Thu, 2019-02-07 at 15:29 +1100, Michael Ellerman wrote:
> Russell Currey <ruscur@russell.cc> writes:
> >
> > Fixes: 3b10d0095a1e ("powerpc/mm/radix: Prevent kernel execution of
> > user
> > space")
>
> Don't word wrap the fixes line please.
My bad, will teach my editor :)
> > Cc: <stable@vger.kernel.org>
> > Signed-off-by: Russell Currey <ruscur@russell.cc>
> > ---
> > arch/powerpc/include/asm/cpuidle.h | 1 +
> > arch/powerpc/kernel/asm-offsets.c | 1 +
> > arch/powerpc/kernel/idle_book3s.S | 20 ++++++++++++++++++++
> > 3 files changed, 22 insertions(+)
> >
> > diff --git a/arch/powerpc/include/asm/cpuidle.h
> > b/arch/powerpc/include/asm/cpuidle.h
> > index 43e5f31fe64d..ad67dbe59498 100644
> > --- a/arch/powerpc/include/asm/cpuidle.h
> > +++ b/arch/powerpc/include/asm/cpuidle.h
> > @@ -77,6 +77,7 @@ struct stop_sprs {
> > u64 mmcr1;
> > u64 mmcr2;
> > u64 mmcra;
> > + u64 iamr;
> > };
>
> We don't actually need to put this in the paca anymore.
>
> > diff --git a/arch/powerpc/kernel/idle_book3s.S
> > b/arch/powerpc/kernel/idle_book3s.S
> > index 7f5ac2e8581b..bb4f552f6c7e 100644
> > --- a/arch/powerpc/kernel/idle_book3s.S
> > +++ b/arch/powerpc/kernel/idle_book3s.S
> > @@ -200,6 +200,12 @@ pnv_powersave_common:
> > /* Continue saving state */
> > SAVE_GPR(2, r1)
> > SAVE_NVGPRS(r1)
> > +
> > +BEGIN_FTR_SECTION
> > + mfspr r5, SPRN_IAMR
> > + std r5, STOP_IAMR(r13)
> > +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
>
> We have space for a full pt_regs on the stack, and we're not using it
> all.
>
> We don't have a specific slot for the IAMR (we may want to in
> future),
> but for now you could follow the time-honoured tradition of (ab)using
> the _DAR slot, with an appropriate comment.
I read this, then did it, and when writing the comment I thought I was
clever using "(ab)use". I then reread this and realised I just
subconsciously stole it.
Thanks for the review.
> cheers
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox