From e340eca90ee18547027a6d5745ffabf7d173dfcc Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 14 Aug 2016 13:53:17 -0700 Subject: [PATCH 01/17] powerpc: cputhreads: Add missing include file Powerpc builds may fail with the following build error. Error log: In file included from ./arch/powerpc/include/asm/mmu_context.h:11:0, from ./include/linux/mmu_context.h:4, from mm/mmu_context.c:8: ./arch/powerpc/include/asm/cputhreads.h: In function 'get_tensr': ./arch/powerpc/include/asm/cputhreads.h:101:2: error: implicit declaration of function 'cpu_has_feature' The problem can be triggered by configuring ppc64e_defconfig and selecting CONFIG_TICK_CPU_ACCOUNTING instead of CONFIG_VIRT_CPU_ACCOUNTING_NATIVE. Fixes: b92a226e5284 ("powerpc: Move cpu_has_feature() to a separate file") Signed-off-by: Guenter Roeck Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/cputhreads.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h index 666bef4ebfae..9377bdf42eb8 100644 --- a/arch/powerpc/include/asm/cputhreads.h +++ b/arch/powerpc/include/asm/cputhreads.h @@ -3,6 +3,7 @@ #ifndef __ASSEMBLY__ #include +#include /* * Mapping of threads to cores From aded76bac54d1dd0a9c9203aa29a78423edc4cde Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sun, 14 Aug 2016 21:42:17 +0200 Subject: [PATCH 02/17] drivers/macintosh: Delete owner assignment The field "owner" is set by core. Thus delete an extra initialisation. Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci Signed-off-by: Markus Elfring Signed-off-by: Benjamin Herrenschmidt --- drivers/macintosh/ams/ams-i2c.c | 1 - drivers/macintosh/windfarm_pm112.c | 1 - drivers/macintosh/windfarm_pm72.c | 1 - drivers/macintosh/windfarm_rm31.c | 1 - 4 files changed, 4 deletions(-) diff --git a/drivers/macintosh/ams/ams-i2c.c b/drivers/macintosh/ams/ams-i2c.c index 978eda8d6678..8a3ba565106f 100644 --- a/drivers/macintosh/ams/ams-i2c.c +++ b/drivers/macintosh/ams/ams-i2c.c @@ -73,7 +73,6 @@ MODULE_DEVICE_TABLE(i2c, ams_id); static struct i2c_driver ams_i2c_driver = { .driver = { .name = "ams", - .owner = THIS_MODULE, }, .probe = ams_i2c_probe, .remove = ams_i2c_remove, diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c index 3024685e4cca..96d16fca68b2 100644 --- a/drivers/macintosh/windfarm_pm112.c +++ b/drivers/macintosh/windfarm_pm112.c @@ -668,7 +668,6 @@ static struct platform_driver wf_pm112_driver = { .remove = wf_pm112_remove, .driver = { .name = "windfarm", - .owner = THIS_MODULE, }, }; diff --git a/drivers/macintosh/windfarm_pm72.c b/drivers/macintosh/windfarm_pm72.c index 2f506b9d5a52..e88cfb36a74d 100644 --- a/drivers/macintosh/windfarm_pm72.c +++ b/drivers/macintosh/windfarm_pm72.c @@ -789,7 +789,6 @@ static struct platform_driver wf_pm72_driver = { .remove = wf_pm72_remove, .driver = { .name = "windfarm", - .owner = THIS_MODULE, }, }; diff --git a/drivers/macintosh/windfarm_rm31.c b/drivers/macintosh/windfarm_rm31.c index 82fc86a90c1a..bdfcb8a8bfbb 100644 --- a/drivers/macintosh/windfarm_rm31.c +++ b/drivers/macintosh/windfarm_rm31.c @@ -682,7 +682,6 @@ static struct platform_driver wf_rm31_driver = { .remove = wf_rm31_remove, .driver = { .name = "windfarm", - .owner = THIS_MODULE, }, }; From e72e799c0901b689c83468623cfcb85df431e882 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 15 Aug 2016 22:07:54 +0200 Subject: [PATCH 03/17] powerpc/512x: Delete unnecessary assignment for the field "owner" The field "owner" is set by the core. Thus delete an unneeded initialisation. Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci Signed-off-by: Markus Elfring Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/512x/mpc512x_lpbfifo.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c b/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c index 8eb82b043dd8..d93dd4acf40b 100644 --- a/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c +++ b/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c @@ -528,7 +528,6 @@ static struct platform_driver mpc512x_lpbfifo_driver = { .remove = mpc512x_lpbfifo_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = mpc512x_lpbfifo_match, }, }; From f5ed841ce75ca33f413c394110d6dc002c097b01 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 15 Aug 2016 22:36:05 +0200 Subject: [PATCH 04/17] powerpc: mpc8349emitx: Delete unnecessary assignment for the field "owner" The field "owner" is set by the core. Thus delete an unneeded initialisation. Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci Signed-off-by: Markus Elfring Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index dbcd0303afed..63c5ab6489c9 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -222,7 +222,6 @@ static const struct of_device_id mcu_of_match_table[] = { static struct i2c_driver mcu_driver = { .driver = { .name = "mcu-mpc8349emitx", - .owner = THIS_MODULE, .of_match_table = mcu_of_match_table, }, .probe = mcu_probe, From 6f38a8b9a45833495dc878c335c5431cd98a16ed Mon Sep 17 00:00:00 2001 From: Andrew Donnellan Date: Thu, 18 Aug 2016 17:35:14 +1000 Subject: [PATCH 05/17] cxl: use pcibios_free_controller_deferred() when removing vPHBs When cxl removes a vPHB, it's possible that the pci_controller may be freed before all references to the devices on the vPHB have been released. This in turn causes an invalid memory access when the devices are eventually released, as pcibios_release_device() attempts to call the phb's release_device hook. In cxl_pci_vphb_remove(), remove the existing call to pcibios_free_controller(). Instead, use pcibios_free_controller_deferred() to free the pci_controller after all devices have been released. Export pci_set_host_bridge_release() so we can do this. Cc: stable@vger.kernel.org Signed-off-by: Andrew Donnellan Reviewed-by: Matthew R. Ochs Acked-by: Ian Munsie Signed-off-by: Benjamin Herrenschmidt --- drivers/misc/cxl/vphb.c | 10 +++++++++- drivers/pci/host-bridge.c | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c index 7ada5f1b7bb6..3519acebfdab 100644 --- a/drivers/misc/cxl/vphb.c +++ b/drivers/misc/cxl/vphb.c @@ -230,6 +230,11 @@ int cxl_pci_vphb_add(struct cxl_afu *afu) if (phb->bus == NULL) return -ENXIO; + /* Set release hook on root bus */ + pci_set_host_bridge_release(to_pci_host_bridge(phb->bus->bridge), + pcibios_free_controller_deferred, + (void *) phb); + /* Claim resources. This might need some rework as well depending * whether we are doing probe-only or not, like assigning unassigned * resources etc... @@ -256,7 +261,10 @@ void cxl_pci_vphb_remove(struct cxl_afu *afu) afu->phb = NULL; pci_remove_root_bus(phb->bus); - pcibios_free_controller(phb); + /* + * We don't free phb here - that's handled by + * pcibios_free_controller_deferred() + */ } static bool _cxl_pci_is_vphb_device(struct pci_controller *phb) diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c index 5f4a2e04c8d7..add66236215c 100644 --- a/drivers/pci/host-bridge.c +++ b/drivers/pci/host-bridge.c @@ -44,6 +44,7 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge, bridge->release_fn = release_fn; bridge->release_data = release_data; } +EXPORT_SYMBOL_GPL(pci_set_host_bridge_release); void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, struct resource *res) From 2dd9c11b9d4dfbd6c070eab7b81197f65e82f1a0 Mon Sep 17 00:00:00 2001 From: Mauricio Faria de Oliveira Date: Thu, 11 Aug 2016 17:25:40 -0300 Subject: [PATCH 06/17] powerpc/pseries: use pci_host_bridge.release_fn() to kfree(phb) This patch leverages 'struct pci_host_bridge' from the PCI subsystem in order to free the pci_controller only after the last reference to its devices is dropped (avoiding an oops in pcibios_release_device() if the last reference is dropped after pcibios_free_controller()). The patch relies on pci_host_bridge.release_fn() (and .release_data), which is called automatically by the PCI subsystem when the root bus is released (i.e., the last reference is dropped). Those fields are set via pci_set_host_bridge_release() (e.g. in the platform-specific implementation of pcibios_root_bridge_prepare()). It introduces the 'pcibios_free_controller_deferred()' .release_fn() and it expects .release_data to hold a pointer to the pci_controller. The function implictly calls 'pcibios_free_controller()', so an user must *NOT* explicitly call it if using the new _deferred() callback. The functionality is enabled for pseries (although it isn't platform specific, and may be used by cxl). Details on not-so-elegant design choices: - Use 'pci_host_bridge.release_data' field as pointer to associated 'struct pci_controller' so *not* to 'pci_bus_to_host(bridge->bus)' in pcibios_free_controller_deferred(). That's because pci_remove_root_bus() sets 'host_bridge->bus = NULL' (so, if the last reference is released after pci_remove_root_bus() runs, which eventually reaches pcibios_free_controller_deferred(), that would hit a null pointer dereference). The cxl/vphb.c code calls pci_remove_root_bus(), and the cxl folks are interested in this fix. Test-case #1 (hold references) # ls -ld /sys/block/sd* | grep -m1 0021:01:00.0 <...> /sys/block/sdaa -> ../devices/pci0021:01/0021:01:00.0/<...> # ls -ld /sys/block/sd* | grep -m1 0021:01:00.1 <...> /sys/block/sdab -> ../devices/pci0021:01/0021:01:00.1/<...> # cat >/dev/sdaa & pid1=$! # cat >/dev/sdab & pid2=$! # drmgr -w 5 -d 1 -c phb -s 'PHB 33' -r Validating PHB DLPAR capability...yes. [ 594.306719] pci_hp_remove_devices: PCI: Removing devices on bus 0021:01 [ 594.306738] pci_hp_remove_devices: Removing 0021:01:00.0... ... [ 598.236381] pci_hp_remove_devices: Removing 0021:01:00.1... ... [ 611.972077] pci_bus 0021:01: busn_res: [bus 01-ff] is released [ 611.972140] rpadlpar_io: slot PHB 33 removed # kill -9 $pid1 # kill -9 $pid2 [ 632.918088] pcibios_free_controller_deferred: domain 33, dynamic 1 Test-case #2 (don't hold references) # drmgr -w 5 -d 1 -c phb -s 'PHB 33' -r Validating PHB DLPAR capability...yes. [ 916.357363] pci_hp_remove_devices: PCI: Removing devices on bus 0021:01 [ 916.357386] pci_hp_remove_devices: Removing 0021:01:00.0... ... [ 920.566527] pci_hp_remove_devices: Removing 0021:01:00.1... ... [ 933.955873] pci_bus 0021:01: busn_res: [bus 01-ff] is released [ 933.955977] pcibios_free_controller_deferred: domain 33, dynamic 1 [ 933.955999] rpadlpar_io: slot PHB 33 removed Suggested-By: Gavin Shan Signed-off-by: Mauricio Faria de Oliveira Reviewed-by: Gavin Shan Reviewed-by: Andrew Donnellan Tested-by: Andrew Donnellan # cxl Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/pci-bridge.h | 1 + arch/powerpc/kernel/pci-common.c | 36 ++++++++++++++++++++++ arch/powerpc/platforms/pseries/pci.c | 4 +++ arch/powerpc/platforms/pseries/pci_dlpar.c | 7 +++-- 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index b5e88e4a171a..c0309c59bed8 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -301,6 +301,7 @@ extern void pci_process_bridge_OF_ranges(struct pci_controller *hose, /* Allocate & free a PCI host bridge structure */ extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev); extern void pcibios_free_controller(struct pci_controller *phb); +extern void pcibios_free_controller_deferred(struct pci_host_bridge *bridge); #ifdef CONFIG_PCI extern int pcibios_vaddr_is_ioport(void __iomem *address); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 7fdf324d5b51..e58908066b0e 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -153,6 +153,42 @@ void pcibios_free_controller(struct pci_controller *phb) } EXPORT_SYMBOL_GPL(pcibios_free_controller); +/* + * This function is used to call pcibios_free_controller() + * in a deferred manner: a callback from the PCI subsystem. + * + * _*DO NOT*_ call pcibios_free_controller() explicitly if + * this is used (or it may access an invalid *phb pointer). + * + * The callback occurs when all references to the root bus + * are dropped (e.g., child buses/devices and their users). + * + * It's called as .release_fn() of 'struct pci_host_bridge' + * which is associated with the 'struct pci_controller.bus' + * (root bus) - it expects .release_data to hold a pointer + * to 'struct pci_controller'. + * + * In order to use it, register .release_fn()/release_data + * like this: + * + * pci_set_host_bridge_release(bridge, + * pcibios_free_controller_deferred + * (void *) phb); + * + * e.g. in the pcibios_root_bridge_prepare() callback from + * pci_create_root_bus(). + */ +void pcibios_free_controller_deferred(struct pci_host_bridge *bridge) +{ + struct pci_controller *phb = (struct pci_controller *) + bridge->release_data; + + pr_debug("domain %d, dynamic %d\n", phb->global_number, phb->is_dynamic); + + pcibios_free_controller(phb); +} +EXPORT_SYMBOL_GPL(pcibios_free_controller_deferred); + /* * The function is used to return the minimal alignment * for memory or I/O windows of the associated P2P bridge. diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c index fe16a50700de..09eba5a9929a 100644 --- a/arch/powerpc/platforms/pseries/pci.c +++ b/arch/powerpc/platforms/pseries/pci.c @@ -119,6 +119,10 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge) bus = bridge->bus; + /* Rely on the pcibios_free_controller_deferred() callback. */ + pci_set_host_bridge_release(bridge, pcibios_free_controller_deferred, + (void *) pci_bus_to_host(bus)); + dn = pcibios_get_phb_of_node(bus); if (!dn) return 0; diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index 906dbaa97fe2..547fd13e4f8e 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -106,8 +106,11 @@ int remove_phb_dynamic(struct pci_controller *phb) release_resource(res); } - /* Free pci_controller data structure */ - pcibios_free_controller(phb); + /* + * The pci_controller data structure is freed by + * the pcibios_free_controller_deferred() callback; + * see pseries_root_bridge_prepare(). + */ return 0; } From 6096481649ac27466cf2b453f185b43f680bf541 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Wed, 17 Aug 2016 12:03:05 +0200 Subject: [PATCH 07/17] powerpc/powernv/pci: fix iterator signedness Unsigned type is always non-negative, so the loop could not end in case condition is never true. The problem has been detected using semantic patch scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci Signed-off-by: Andrzej Hajda Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powernv/pci-ioda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index fd9444f9fb0c..13218263e66e 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -149,7 +149,7 @@ static void pnv_ioda_reserve_pe(struct pnv_phb *phb, int pe_no) static struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb *phb) { - unsigned long pe = phb->ioda.total_pe_num - 1; + long pe; for (pe = phb->ioda.total_pe_num - 1; pe >= 0; pe--) { if (!test_and_set_bit(pe, phb->ioda.pe_alloc)) From 8a39b05f086904c3b2e04e4db3d81f30c0eae6ae Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Tue, 16 Aug 2016 10:57:34 -0400 Subject: [PATCH 08/17] powerpc: migrate exception table users off module.h and onto extable.h These files were only including module.h for exception table related functions. We've now separated that content out into its own file "extable.h" so now move over to that and avoid all the extra header content in module.h that we don't really need to compile these files. Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Paul Gortmaker Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/kprobes.c | 2 +- arch/powerpc/kernel/traps.c | 3 ++- arch/powerpc/mm/fault.c | 2 +- arch/powerpc/platforms/embedded6xx/holly.c | 2 +- arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | 2 +- arch/powerpc/sysdev/fsl_rio.c | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 3ed8ec09b5c9..e785cc9e1ecd 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 2cb589264cb7..62859ebe0062 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -25,7 +25,8 @@ #include #include #include -#include +#include +#include /* print_modules */ #include #include #include diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index a4db22f65021..bb1ffc559f38 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/powerpc/platforms/embedded6xx/holly.c b/arch/powerpc/platforms/embedded6xx/holly.c index dafba1057a47..dfd310031549 100644 --- a/arch/powerpc/platforms/embedded6xx/holly.c +++ b/arch/powerpc/platforms/embedded6xx/holly.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index 80804f9916ee..f97bab8e37a2 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 68e7c0dd2e45..3cc7cace194a 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -23,7 +23,7 @@ */ #include -#include +#include #include #include #include From 19ab58d19ef6291bab07c8e7110f3198c23432c1 Mon Sep 17 00:00:00 2001 From: Boqun Feng Date: Tue, 16 Aug 2016 19:50:12 +0800 Subject: [PATCH 09/17] powerpc, hotplug: Avoid to touch non-existent cpumasks. We observed a kernel oops when running a PPC guest with config NR_CPUS=4 and qemu option "-smp cores=1,threads=8": [ 30.634781] Unable to handle kernel paging request for data at address 0xc00000014192eb17 [ 30.636173] Faulting instruction address: 0xc00000000003e5cc [ 30.637069] Oops: Kernel access of bad area, sig: 11 [#1] [ 30.637877] SMP NR_CPUS=4 NUMA pSeries [ 30.638471] Modules linked in: [ 30.638949] CPU: 3 PID: 27 Comm: migration/3 Not tainted 4.7.0-07963-g9714b26 #1 [ 30.640059] task: c00000001e29c600 task.stack: c00000001e2a8000 [ 30.640956] NIP: c00000000003e5cc LR: c00000000003e550 CTR: 0000000000000000 [ 30.642001] REGS: c00000001e2ab8e0 TRAP: 0300 Not tainted (4.7.0-07963-g9714b26) [ 30.643139] MSR: 8000000102803033 CR: 22004084 XER: 00000000 [ 30.644583] CFAR: c000000000009e98 DAR: c00000014192eb17 DSISR: 40000000 SOFTE: 0 GPR00: c00000000140a6b8 c00000001e2abb60 c0000000016dd300 0000000000000003 GPR04: 0000000000000000 0000000000000004 c0000000016e5920 0000000000000008 GPR08: 0000000000000004 c00000014192eb17 0000000000000000 0000000000000020 GPR12: c00000000140a6c0 c00000000ffffc00 c0000000000d3ea8 c00000001e005680 GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 GPR20: 0000000000000000 c00000001e6b3a00 0000000000000000 0000000000000001 GPR24: c00000001ff85138 c00000001ff85130 000000001eb6f000 0000000000000001 GPR28: 0000000000000000 c0000000017014e0 0000000000000000 0000000000000018 [ 30.653882] NIP [c00000000003e5cc] __cpu_disable+0xcc/0x190 [ 30.654713] LR [c00000000003e550] __cpu_disable+0x50/0x190 [ 30.655528] Call Trace: [ 30.655893] [c00000001e2abb60] [c00000000003e550] __cpu_disable+0x50/0x190 (unreliable) [ 30.657280] [c00000001e2abbb0] [c0000000000aca0c] take_cpu_down+0x5c/0x100 [ 30.658365] [c00000001e2abc10] [c000000000163918] multi_cpu_stop+0x1a8/0x1e0 [ 30.659617] [c00000001e2abc60] [c000000000163cc0] cpu_stopper_thread+0xf0/0x1d0 [ 30.660737] [c00000001e2abd20] [c0000000000d8d70] smpboot_thread_fn+0x290/0x2a0 [ 30.661879] [c00000001e2abd80] [c0000000000d3fa8] kthread+0x108/0x130 [ 30.662876] [c00000001e2abe30] [c000000000009968] ret_from_kernel_thread+0x5c/0x74 [ 30.664017] Instruction dump: [ 30.664477] 7bde1f24 38a00000 787f1f24 3b600001 39890008 7d204b78 7d05e214 7d0b07b4 [ 30.665642] 796b1f24 7d26582a 7d204a14 7d29f214 <7d4048a8> 7d4a3878 7d4049ad 40c2fff4 [ 30.666854] ---[ end trace 32643b7195717741 ]--- The reason of this is that in __cpu_disable(), when we try to set the cpu_sibling_mask or cpu_core_mask of the sibling CPUs of the disabled one, we don't check whether the current configuration employs those sibling CPUs(hw threads). And if a CPU is not employed by a configuration, the percpu structures cpu_{sibling,core}_mask are not allocated, therefore accessing those cpumasks will result in problems as above. This patch fixes this problem by adding an addition check on whether the id is no less than nr_cpu_ids in the sibling CPU iteration code. Signed-off-by: Boqun Feng Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 25a39052bf6b..9c6f3fd58059 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -830,7 +830,7 @@ int __cpu_disable(void) /* Update sibling maps */ base = cpu_first_thread_sibling(cpu); - for (i = 0; i < threads_per_core; i++) { + for (i = 0; i < threads_per_core && base + i < nr_cpu_ids; i++) { cpumask_clear_cpu(cpu, cpu_sibling_mask(base + i)); cpumask_clear_cpu(base + i, cpu_sibling_mask(cpu)); cpumask_clear_cpu(cpu, cpu_core_mask(base + i)); From 66443efa83dc73775100b7442962ce2cb0d4472e Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 12 Aug 2016 21:45:52 +1000 Subject: [PATCH 10/17] powerpc/prom: Fix sub-processor option passed to ibm, client-architecture-support When booting from an OpenFirmware which supports it, we use the "ibm,client-architecture-support" firmware call to communicate our capabilities to firmware. The format of the structure we pass to firmware is specified in PAPR (Power Architecture Platform Requirements), or the public version LoPAPR (Linux on Power Architecture Platform Reference). Referring to table 244 in LoPAPR v1.1, option vector 5 contains a 4 byte field at bytes 17-20 for the "Platform Facilities Enable". This is followed by a 1 byte field at byte 21 for "Sub-Processor Represenation Level". Comparing to the code, there we have the Platform Facilities options (OV5_PFO_*) at byte 17, but we fail to pad that field out to its full width of 4 bytes. This means the OV5_SUB_PROCESSORS option is incorrectly placed at byte 18. Fix it by adding zero bytes for bytes 18, 19, 20, and comment the bytes to hopefully make it clearer in future. As far as I'm aware nothing actually consumes this value at this time, so the effect of this bug is nil in practice. It does mean we've been incorrectly setting bit 15 of the "Platform Facilities Enable" option for the past ~3 1/2 years, so we should avoid allocating that bit to anything else in future. Fixes: df77c7992029 ("powerpc/pseries: Update ibm,architecture.vec for PAPR 2.7/POWER8") Signed-off-by: Michael Ellerman Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/prom_init.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 4e74fc588a3f..d3eff99e938c 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -695,7 +695,7 @@ unsigned char ibm_architecture_vec[] = { OV4_MIN_ENT_CAP, /* minimum VP entitled capacity */ /* option vector 5: PAPR/OF options */ - VECTOR_LENGTH(18), /* length */ + VECTOR_LENGTH(21), /* length */ 0, /* don't ignore, don't halt */ OV5_FEAT(OV5_LPAR) | OV5_FEAT(OV5_SPLPAR) | OV5_FEAT(OV5_LARGE_PAGES) | OV5_FEAT(OV5_DRCONF_MEMORY) | OV5_FEAT(OV5_DONATE_DEDICATE_CPU) | @@ -726,8 +726,11 @@ unsigned char ibm_architecture_vec[] = { 0, 0, OV5_FEAT(OV5_PFO_HW_RNG) | OV5_FEAT(OV5_PFO_HW_ENCR) | - OV5_FEAT(OV5_PFO_HW_842), - OV5_FEAT(OV5_SUB_PROCESSORS), + OV5_FEAT(OV5_PFO_HW_842), /* Byte 17 */ + 0, /* Byte 18 */ + 0, /* Byte 19 */ + 0, /* Byte 20 */ + OV5_FEAT(OV5_SUB_PROCESSORS), /* Byte 21 */ /* option vector 6: IBM PAPR hints */ VECTOR_LENGTH(3), /* length */ From 3f3b5dc14c25254d3fe98115c71b2a1f3ed97798 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Wed, 10 Aug 2016 20:48:42 +1000 Subject: [PATCH 11/17] powerpc/pseries: PACA save area fix for general exception vs MCE MCE must not use PACA_EXGEN. When a general exception enables MSR_RI, that means SPRN_SRR[01] and SPRN_SPRG are no longer used. However the PACA save area is still in use. Acked-by: Mahesh Salgaonkar Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/exceptions-64s.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index df6d45eb4115..034b7eaf68d2 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -969,14 +969,14 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) machine_check_common: mfspr r10,SPRN_DAR - std r10,PACA_EXGEN+EX_DAR(r13) + std r10,PACA_EXMC+EX_DAR(r13) mfspr r10,SPRN_DSISR - stw r10,PACA_EXGEN+EX_DSISR(r13) + stw r10,PACA_EXMC+EX_DSISR(r13) EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) FINISH_NAP RECONCILE_IRQ_STATE(r10, r11) - ld r3,PACA_EXGEN+EX_DAR(r13) - lwz r4,PACA_EXGEN+EX_DSISR(r13) + ld r3,PACA_EXMC+EX_DAR(r13) + lwz r4,PACA_EXMC+EX_DSISR(r13) std r3,_DAR(r1) std r4,_DSISR(r1) bl save_nvgprs From a74599a5041979ae83aec7a6d5c8df9131db2ce6 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Wed, 10 Aug 2016 20:48:43 +1000 Subject: [PATCH 12/17] powerpc/pseries: PACA save area fix for MCE vs MCE MCE must not enable MSR_RI until PACA_EXMC is no longer being used. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/exceptions-64s.S | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 034b7eaf68d2..bffec73dbffc 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -485,7 +485,23 @@ machine_check_fwnmi: EXCEPTION_PROLOG_0(PACA_EXMC) machine_check_pSeries_0: EXCEPTION_PROLOG_1(PACA_EXMC, KVMTEST, 0x200) - EXCEPTION_PROLOG_PSERIES_1(machine_check_common, EXC_STD) + /* + * The following is essentially EXCEPTION_PROLOG_PSERIES_1 with the + * difference that MSR_RI is not enabled, because PACA_EXMC is being + * used, so nested machine check corrupts it. machine_check_common + * enables MSR_RI. + */ + ld r12,PACAKBASE(r13) + ld r10,PACAKMSR(r13) + xori r10,r10,MSR_RI + mfspr r11,SPRN_SRR0 + LOAD_HANDLER(r12, machine_check_common) + mtspr SPRN_SRR0,r12 + mfspr r12,SPRN_SRR1 + mtspr SPRN_SRR1,r10 + rfid + b . /* prevent speculative execution */ + KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200) KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300) KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380) @@ -977,6 +993,9 @@ machine_check_common: RECONCILE_IRQ_STATE(r10, r11) ld r3,PACA_EXMC+EX_DAR(r13) lwz r4,PACA_EXMC+EX_DSISR(r13) + /* Enable MSR_RI when finished with PACA_EXMC */ + li r10,MSR_RI + mtmsrd r10,1 std r3,_DAR(r1) std r4,_DSISR(r1) bl save_nvgprs From 41017a7579cf49cb5513e17df1570dc918760079 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 11 Aug 2016 10:50:40 +0200 Subject: [PATCH 13/17] powerpc: sysdev: cpm: fix gpio save_regs functions of_mm_gpiochip_add_data() calls mm_gc->save_regs() before setting the data. Therefore ->save_regs() cannot use gpiochip_get_data() [ 0.275940] Unable to handle kernel paging request for data at address 0x00000130 [ 0.283120] Faulting instruction address: 0xc01b44cc [ 0.288175] Oops: Kernel access of bad area, sig: 11 [#1] [ 0.293343] PREEMPT CMPC885 [ 0.296141] CPU: 0 PID: 1 Comm: swapper Not tainted 4.7.0-g65124df-dirty #68 [ 0.304131] task: c6074000 ti: c6080000 task.ti: c6080000 [ 0.309459] NIP: c01b44cc LR: c0011720 CTR: c0011708 [ 0.314372] REGS: c6081d90 TRAP: 0300 Not tainted (4.7.0-g65124df-dirty) [ 0.322267] MSR: 00009032 CR: 24000028 XER: 20000000 [ 0.328813] DAR: 00000130 DSISR: c0000000 GPR00: c01b6d0c c6081e40 c6074000 c6017000 c9028000 c601d028 c6081dd8 00000000 GPR08: c601d028 00000000 ffffffff 00000001 24000044 00000000 c0002790 00000000 GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 c05643b0 00000083 GPR24: c04a1a6c c0560000 c04a8308 c04c6480 c0012498 c6017000 c7ffcc78 c6017000 [ 0.360806] NIP [c01b44cc] gpiochip_get_data+0x4/0xc [ 0.365684] LR [c0011720] cpm1_gpio16_save_regs+0x18/0x44 [ 0.370972] Call Trace: [ 0.373451] [c6081e50] [c01b6d0c] of_mm_gpiochip_add_data+0x70/0xdc [ 0.379624] [c6081e70] [c00124c0] cpm_init_par_io+0x28/0x118 [ 0.385238] [c6081e80] [c04a8ac0] do_one_initcall+0xb0/0x17c [ 0.390819] [c6081ef0] [c04a8cbc] kernel_init_freeable+0x130/0x1dc [ 0.396924] [c6081f30] [c00027a4] kernel_init+0x14/0x110 [ 0.402177] [c6081f40] [c000b424] ret_from_kernel_thread+0x5c/0x64 [ 0.408233] Instruction dump: [ 0.411168] 4182fafc 3f80c040 48234c6d 3bc0fff0 3b9c5ed0 4bfffaf4 81290020 712a0004 [ 0.418825] 4182fb34 48234c51 4bfffb2c 81230004 <80690130> 4e800020 7c0802a6 9421ffe0 [ 0.426763] ---[ end trace fe4113ee21d72ffa ]--- fixes: e65078f1f3490 ("powerpc: sysdev: cpm1: use gpiochip data pointer") fixes: a14a2d484b386 ("powerpc: cpm_common: use gpiochip data pointer") Cc: stable@vger.kernel.org Signed-off-by: Christophe Leroy Reviewed-by: Linus Walleij Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/sysdev/cpm1.c | 6 ++++-- arch/powerpc/sysdev/cpm_common.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index 6c110994d902..81d49476c47e 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c @@ -534,7 +534,8 @@ struct cpm1_gpio16_chip { static void cpm1_gpio16_save_regs(struct of_mm_gpio_chip *mm_gc) { - struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); + struct cpm1_gpio16_chip *cpm1_gc = + container_of(mm_gc, struct cpm1_gpio16_chip, mm_gc); struct cpm_ioport16 __iomem *iop = mm_gc->regs; cpm1_gc->cpdata = in_be16(&iop->dat); @@ -649,7 +650,8 @@ struct cpm1_gpio32_chip { static void cpm1_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc) { - struct cpm1_gpio32_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); + struct cpm1_gpio32_chip *cpm1_gc = + container_of(mm_gc, struct cpm1_gpio32_chip, mm_gc); struct cpm_ioport32b __iomem *iop = mm_gc->regs; cpm1_gc->cpdata = in_be32(&iop->dat); diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 911456d17713..947f42007734 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c @@ -94,7 +94,8 @@ struct cpm2_gpio32_chip { static void cpm2_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc) { - struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(&mm_gc->gc); + struct cpm2_gpio32_chip *cpm2_gc = + container_of(mm_gc, struct cpm2_gpio32_chip, mm_gc); struct cpm2_ioports __iomem *iop = mm_gc->regs; cpm2_gc->cpdata = in_be32(&iop->dat); From 7c379526d7e71d2041c8ca0bd9af4888916a14b9 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 11 Aug 2016 15:07:43 +0200 Subject: [PATCH 14/17] powerpc: move hmi.c to arch/powerpc/kvm/ hmi.c functions are unused unless sibling_subcore_state is nonzero, and that in turn happens only if KVM is in use. So move the code to arch/powerpc/kvm/, putting it under CONFIG_KVM_BOOK3S_HV_POSSIBLE rather than CONFIG_PPC_BOOK3S_64. The sibling_subcore_state is also included in struct paca_struct only if KVM is supported by the kernel. Cc: Daniel Axtens Cc: Michael Ellerman Cc: Mahesh Salgaonkar Cc: Paul Mackerras Cc: linuxppc-dev@lists.ozlabs.org Cc: kvm-ppc@vger.kernel.org Cc: kvm@vger.kernel.org Signed-off-by: Paolo Bonzini Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/hmi.h | 2 +- arch/powerpc/include/asm/paca.h | 12 +++++++----- arch/powerpc/kernel/Makefile | 2 +- arch/powerpc/kvm/Makefile | 1 + arch/powerpc/{kernel/hmi.c => kvm/book3s_hv_hmi.c} | 0 5 files changed, 10 insertions(+), 7 deletions(-) rename arch/powerpc/{kernel/hmi.c => kvm/book3s_hv_hmi.c} (100%) diff --git a/arch/powerpc/include/asm/hmi.h b/arch/powerpc/include/asm/hmi.h index 88b4901ac4ee..85b7a1a21e22 100644 --- a/arch/powerpc/include/asm/hmi.h +++ b/arch/powerpc/include/asm/hmi.h @@ -21,7 +21,7 @@ #ifndef __ASM_PPC64_HMI_H__ #define __ASM_PPC64_HMI_H__ -#ifdef CONFIG_PPC_BOOK3S_64 +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE #define CORE_TB_RESYNC_REQ_BIT 63 #define MAX_SUBCORE_PER_CORE 4 diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 148303e7771f..6a6792bb39fb 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -183,11 +183,6 @@ struct paca_struct { */ u16 in_mce; u8 hmi_event_available; /* HMI event is available */ - /* - * Bitmap for sibling subcore status. See kvm/book3s_hv_ras.c for - * more details - */ - struct sibling_subcore_state *sibling_subcore_state; #endif /* Stuff for accurate time accounting */ @@ -202,6 +197,13 @@ struct paca_struct { struct kvmppc_book3s_shadow_vcpu shadow_vcpu; #endif struct kvmppc_host_state kvm_hstate; +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE + /* + * Bitmap for sibling subcore status. See kvm/book3s_hv_ras.c for + * more details + */ + struct sibling_subcore_state *sibling_subcore_state; +#endif #endif }; diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index b2027a5cf508..fe4c075bcf50 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -41,7 +41,7 @@ obj-$(CONFIG_VDSO32) += vdso32/ obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o -obj-$(CONFIG_PPC_BOOK3S_64) += mce.o mce_power.o hmi.o +obj-$(CONFIG_PPC_BOOK3S_64) += mce.o mce_power.o obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o obj-$(CONFIG_PPC64) += vdso64/ obj-$(CONFIG_ALTIVEC) += vecemu.o diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 1f9e5529e692..855d4b95d752 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -78,6 +78,7 @@ kvm-book3s_64-builtin-xics-objs-$(CONFIG_KVM_XICS) := \ ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HANDLER) += \ + book3s_hv_hmi.o \ book3s_hv_rmhandlers.o \ book3s_hv_rm_mmu.o \ book3s_hv_ras.o \ diff --git a/arch/powerpc/kernel/hmi.c b/arch/powerpc/kvm/book3s_hv_hmi.c similarity index 100% rename from arch/powerpc/kernel/hmi.c rename to arch/powerpc/kvm/book3s_hv_hmi.c From cc7786d3ee7e3c979799db834b528db2c0834c2e Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Mon, 25 Jul 2016 14:26:51 +1000 Subject: [PATCH 15/17] powerpc/tm: do not use r13 for tabort_syscall tabort_syscall runs with RI=1, so a nested recoverable machine check will load the paca into r13 and overwrite what we loaded it with, because exceptions returning to privileged mode do not restore r13. Fixes: b4b56f9ecab4 (powerpc/tm: Abort syscalls in active transactions) Cc: stable@vger.kernel.org Signed-off-by: Nick Piggin Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/entry_64.S | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 6b8bc0dd09d4..5afd03e5e8b8 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -368,13 +368,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) tabort_syscall: /* Firstly we need to enable TM in the kernel */ mfmsr r10 - li r13, 1 - rldimi r10, r13, MSR_TM_LG, 63-MSR_TM_LG + li r9, 1 + rldimi r10, r9, MSR_TM_LG, 63-MSR_TM_LG mtmsrd r10, 0 /* tabort, this dooms the transaction, nothing else */ - li r13, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT) - TABORT(R13) + li r9, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT) + TABORT(R9) /* * Return directly to userspace. We have corrupted user register state, @@ -382,8 +382,8 @@ tabort_syscall: * resume after the tbegin of the aborted transaction with the * checkpointed register state. */ - li r13, MSR_RI - andc r10, r10, r13 + li r9, MSR_RI + andc r10, r10, r9 mtmsrd r10, 1 mtspr SPRN_SRR0, r11 mtspr SPRN_SRR1, r12 From a9cbf0b2195b695cbeeeecaa4e2770948c212e9a Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 22 Aug 2016 12:17:44 +0530 Subject: [PATCH 16/17] powerpc/powernv : Drop reference added by kset_find_obj() In a situation, where Linux kernel gets notified about duplicate error log from OPAL, it is been observed that kernel fails to remove sysfs entries (/sys/firmware/opal/elog/0xXXXXXXXX) of such error logs. This is because, we currently search the error log/dump kobject in the kset list via 'kset_find_obj()' routine. Which eventually increment the reference count by one, once it founds the kobject. So, unless we decrement the reference count by one after it found the kobject, we would not be able to release the kobject properly later. This patch adds the 'kobject_put()' which was missing earlier. Signed-off-by: Mukesh Ojha Cc: stable@vger.kernel.org Reviewed-by: Vasant Hegde Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powernv/opal-dump.c | 7 ++++++- arch/powerpc/platforms/powernv/opal-elog.c | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c index 2ee96431f736..4c827826c05e 100644 --- a/arch/powerpc/platforms/powernv/opal-dump.c +++ b/arch/powerpc/platforms/powernv/opal-dump.c @@ -370,6 +370,7 @@ static irqreturn_t process_dump(int irq, void *data) uint32_t dump_id, dump_size, dump_type; struct dump_obj *dump; char name[22]; + struct kobject *kobj; rc = dump_read_info(&dump_id, &dump_size, &dump_type); if (rc != OPAL_SUCCESS) @@ -381,8 +382,12 @@ static irqreturn_t process_dump(int irq, void *data) * that gracefully and not create two conflicting * entries. */ - if (kset_find_obj(dump_kset, name)) + kobj = kset_find_obj(dump_kset, name); + if (kobj) { + /* Drop reference added by kset_find_obj() */ + kobject_put(kobj); return 0; + } dump = create_dump_obj(dump_id, dump_size, dump_type); if (!dump) diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c index 37f959bf392e..f2344cbd2f46 100644 --- a/arch/powerpc/platforms/powernv/opal-elog.c +++ b/arch/powerpc/platforms/powernv/opal-elog.c @@ -247,6 +247,7 @@ static irqreturn_t elog_event(int irq, void *data) uint64_t elog_type; int rc; char name[2+16+1]; + struct kobject *kobj; rc = opal_get_elog_size(&id, &size, &type); if (rc != OPAL_SUCCESS) { @@ -269,8 +270,12 @@ static irqreturn_t elog_event(int irq, void *data) * that gracefully and not create two conflicting * entries. */ - if (kset_find_obj(elog_kset, name)) + kobj = kset_find_obj(elog_kset, name); + if (kobj) { + /* Drop reference added by kset_find_obj() */ + kobject_put(kobj); return IRQ_HANDLED; + } create_elog_obj(log_id, elog_size, elog_type); From 78a3e8889b4b6b99775ed954696ff3e017f5d19b Mon Sep 17 00:00:00 2001 From: Cyril Bur Date: Tue, 23 Aug 2016 10:46:17 +1000 Subject: [PATCH 17/17] powerpc: signals: Discard transaction state from signal frames Userspace can begin and suspend a transaction within the signal handler which means they might enter sys_rt_sigreturn() with the processor in suspended state. sys_rt_sigreturn() wants to restore process context (which may have been in a transaction before signal delivery). To do this it must restore TM SPRS. To achieve this, any transaction initiated within the signal frame must be discarded in order to be able to restore TM SPRs as TM SPRs can only be manipulated non-transactionally.. >From the PowerPC ISA: TM Bad Thing Exception [Category: Transactional Memory] An attempt is made to execute a mtspr targeting a TM register in other than Non-transactional state. Not doing so results in a TM Bad Thing: [12045.221359] Kernel BUG at c000000000050a40 [verbose debug info unavailable] [12045.221470] Unexpected TM Bad Thing exception at c000000000050a40 (msr 0x201033) [12045.221540] Oops: Unrecoverable exception, sig: 6 [#1] [12045.221586] SMP NR_CPUS=2048 NUMA PowerNV [12045.221634] Modules linked in: xt_CHECKSUM iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp bridge stp llc ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter ip_tables x_tables kvm_hv kvm uio_pdrv_genirq ipmi_powernv uio powernv_rng ipmi_msghandler autofs4 ses enclosure scsi_transport_sas bnx2x ipr mdio libcrc32c [12045.222167] CPU: 68 PID: 6178 Comm: sigreturnpanic Not tainted 4.7.0 #34 [12045.222224] task: c0000000fce38600 ti: c0000000fceb4000 task.ti: c0000000fceb4000 [12045.222293] NIP: c000000000050a40 LR: c0000000000163bc CTR: 0000000000000000 [12045.222361] REGS: c0000000fceb7ac0 TRAP: 0700 Not tainted (4.7.0) [12045.222418] MSR: 9000000300201033 CR: 28444280 XER: 20000000 [12045.222625] CFAR: c0000000000163b8 SOFTE: 0 PACATMSCRATCH: 900000014280f033 GPR00: 01100000b8000001 c0000000fceb7d40 c00000000139c100 c0000000fce390d0 GPR04: 900000034280f033 0000000000000000 0000000000000000 0000000000000000 GPR08: 0000000000000000 b000000000001033 0000000000000001 0000000000000000 GPR12: 0000000000000000 c000000002926400 0000000000000000 0000000000000000 GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 GPR20: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 GPR24: 0000000000000000 00003ffff98cadd0 00003ffff98cb470 0000000000000000 GPR28: 900000034280f033 c0000000fceb7ea0 0000000000000001 c0000000fce390d0 [12045.223535] NIP [c000000000050a40] tm_restore_sprs+0xc/0x1c [12045.223584] LR [c0000000000163bc] tm_recheckpoint+0x5c/0xa0 [12045.223630] Call Trace: [12045.223655] [c0000000fceb7d80] [c000000000026e74] sys_rt_sigreturn+0x494/0x6c0 [12045.223738] [c0000000fceb7e30] [c0000000000092e0] system_call+0x38/0x108 [12045.223806] Instruction dump: [12045.223841] 7c800164 4e800020 7c0022a6 f80304a8 7c0222a6 f80304b0 7c0122a6 f80304b8 [12045.223955] 4e800020 e80304a8 7c0023a6 e80304b0 <7c0223a6> e80304b8 7c0123a6 4e800020 [12045.224074] ---[ end trace cb8002ee240bae76 ]--- It isn't clear exactly if there is really a use case for userspace returning with a suspended transaction, however, doing so doesn't (on its own) constitute a bad frame. As such, this patch simply discards the transactional state of the context calling the sigreturn and continues. Reported-by: Laurent Dufour Signed-off-by: Cyril Bur Tested-by: Laurent Dufour Reviewed-by: Laurent Dufour Acked-by: Simon Guo Signed-off-by: Benjamin Herrenschmidt --- Documentation/powerpc/transactional_memory.txt | 2 ++ arch/powerpc/kernel/signal_32.c | 14 ++++++++++++++ arch/powerpc/kernel/signal_64.c | 14 ++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/Documentation/powerpc/transactional_memory.txt b/Documentation/powerpc/transactional_memory.txt index ba0a2a4a54ba..e32fdbb4c9a7 100644 --- a/Documentation/powerpc/transactional_memory.txt +++ b/Documentation/powerpc/transactional_memory.txt @@ -167,6 +167,8 @@ 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 ================================== diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index b6aa378aff63..a7daf749b97f 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -1226,7 +1226,21 @@ long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16); if (!access_ok(VERIFY_READ, rt_sf, sizeof(*rt_sf))) goto bad; + #ifdef CONFIG_PPC_TRANSACTIONAL_MEM + /* + * If there is a transactional state then throw it away. + * The purpose of a sigreturn is to destroy all traces of the + * signal frame, this includes any transactional state created + * within in. We only check for suspended as we can never be + * active in the kernel, we are active, there is nothing better to + * do than go ahead and Bad Thing later. + * The cause is not important as there will never be a + * recheckpoint so it's not user visible. + */ + if (MSR_TM_SUSPENDED(mfmsr())) + tm_reclaim_current(0); + if (__get_user(tmp, &rt_sf->uc.uc_link)) goto bad; uc_transact = (struct ucontext __user *)(uintptr_t)tmp; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 7e49984d4331..70409bb90a95 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -676,7 +676,21 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set))) goto badframe; set_current_blocked(&set); + #ifdef CONFIG_PPC_TRANSACTIONAL_MEM + /* + * If there is a transactional state then throw it away. + * The purpose of a sigreturn is to destroy all traces of the + * signal frame, this includes any transactional state created + * within in. We only check for suspended as we can never be + * active in the kernel, we are active, there is nothing better to + * do than go ahead and Bad Thing later. + * The cause is not important as there will never be a + * recheckpoint so it's not user visible. + */ + if (MSR_TM_SUSPENDED(mfmsr())) + tm_reclaim_current(0); + if (__get_user(msr, &uc->uc_mcontext.gp_regs[PT_MSR])) goto badframe; if (MSR_TM_ACTIVE(msr)) {