* [PATCH AUTOSEL 5.5 094/542] s390/pci: Fix possible deadlock in recover_store()
[not found] <20200214154854.6746-1-sashal@kernel.org>
@ 2020-02-14 15:41 ` Sasha Levin
2020-02-17 9:31 ` Niklas Schnelle
2020-02-14 15:41 ` [PATCH AUTOSEL 5.5 122/542] KVM: s390: ENOTSUPP -> EOPNOTSUPP fixups Sasha Levin
` (3 subsequent siblings)
4 siblings, 1 reply; 7+ messages in thread
From: Sasha Levin @ 2020-02-14 15:41 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Niklas Schnelle, Peter Oberparleiter, Vasily Gorbik, Sasha Levin,
linux-s390
From: Niklas Schnelle <schnelle@linux.ibm.com>
[ Upstream commit 576c75e36c689bec6a940e807bae27291ab0c0de ]
With zpci_disable() working, lockdep detected a potential deadlock
(lockdep output at the end).
The deadlock is between recovering a PCI function via the
/sys/bus/pci/devices/<dev>/recover
attribute vs powering it off via
/sys/bus/pci/slots/<slot>/power.
The fix is analogous to the changes in commit 0ee223b2e1f6 ("scsi: core:
Avoid that SCSI device removal through sysfs triggers a deadlock")
that fixed a potential deadlock on removing a SCSI device via sysfs.
[ 204.830107] ======================================================
[ 204.830109] WARNING: possible circular locking dependency detected
[ 204.830111] 5.5.0-rc2-06072-gbc03ecc9a672 #6 Tainted: G W
[ 204.830112] ------------------------------------------------------
[ 204.830113] bash/1034 is trying to acquire lock:
[ 204.830115] 0000000192a1a610 (kn->count#200){++++}, at: kernfs_remove_by_name_ns+0x5c/0xa8
[ 204.830122]
but task is already holding lock:
[ 204.830123] 00000000c16134a8 (pci_rescan_remove_lock){+.+.}, at: pci_stop_and_remove_bus_device_locked+0x26/0x48
[ 204.830128]
which lock already depends on the new lock.
[ 204.830129]
the existing dependency chain (in reverse order) is:
[ 204.830130]
-> #1 (pci_rescan_remove_lock){+.+.}:
[ 204.830134] validate_chain+0x93a/0xd08
[ 204.830136] __lock_acquire+0x4ae/0x9d0
[ 204.830137] lock_acquire+0x114/0x280
[ 204.830140] __mutex_lock+0xa2/0x960
[ 204.830142] mutex_lock_nested+0x32/0x40
[ 204.830145] recover_store+0x4c/0xa8
[ 204.830147] kernfs_fop_write+0xe6/0x218
[ 204.830151] vfs_write+0xb0/0x1b8
[ 204.830152] ksys_write+0x6c/0xf8
[ 204.830154] system_call+0xd8/0x2d8
[ 204.830155]
-> #0 (kn->count#200){++++}:
[ 204.830187] check_noncircular+0x1e6/0x240
[ 204.830189] check_prev_add+0xfc/0xdb0
[ 204.830190] validate_chain+0x93a/0xd08
[ 204.830192] __lock_acquire+0x4ae/0x9d0
[ 204.830193] lock_acquire+0x114/0x280
[ 204.830194] __kernfs_remove.part.0+0x2e4/0x360
[ 204.830196] kernfs_remove_by_name_ns+0x5c/0xa8
[ 204.830198] remove_files.isra.0+0x4c/0x98
[ 204.830199] sysfs_remove_group+0x66/0xc8
[ 204.830201] sysfs_remove_groups+0x46/0x68
[ 204.830204] device_remove_attrs+0x52/0x90
[ 204.830207] device_del+0x182/0x418
[ 204.830208] pci_remove_bus_device+0x8a/0x130
[ 204.830210] pci_stop_and_remove_bus_device_locked+0x3a/0x48
[ 204.830212] disable_slot+0x68/0x100
[ 204.830213] power_write_file+0x7c/0x130
[ 204.830215] kernfs_fop_write+0xe6/0x218
[ 204.830217] vfs_write+0xb0/0x1b8
[ 204.830218] ksys_write+0x6c/0xf8
[ 204.830220] system_call+0xd8/0x2d8
[ 204.830221]
other info that might help us debug this:
[ 204.830223] Possible unsafe locking scenario:
[ 204.830224] CPU0 CPU1
[ 204.830225] ---- ----
[ 204.830226] lock(pci_rescan_remove_lock);
[ 204.830227] lock(kn->count#200);
[ 204.830229] lock(pci_rescan_remove_lock);
[ 204.830231] lock(kn->count#200);
[ 204.830233]
*** DEADLOCK ***
[ 204.830234] 4 locks held by bash/1034:
[ 204.830235] #0: 00000001b6fbc498 (sb_writers#4){.+.+}, at: vfs_write+0x158/0x1b8
[ 204.830239] #1: 000000018c9f5090 (&of->mutex){+.+.}, at: kernfs_fop_write+0xaa/0x218
[ 204.830242] #2: 00000001f7da0810 (kn->count#235){.+.+}, at: kernfs_fop_write+0xb6/0x218
[ 204.830245] #3: 00000000c16134a8 (pci_rescan_remove_lock){+.+.}, at: pci_stop_and_remove_bus_device_locked+0x26/0x48
[ 204.830248]
stack backtrace:
[ 204.830250] CPU: 2 PID: 1034 Comm: bash Tainted: G W 5.5.0-rc2-06072-gbc03ecc9a672 #6
[ 204.830252] Hardware name: IBM 8561 T01 703 (LPAR)
[ 204.830253] Call Trace:
[ 204.830257] [<00000000c05e10c0>] show_stack+0x88/0xf0
[ 204.830260] [<00000000c112dca4>] dump_stack+0xa4/0xe0
[ 204.830261] [<00000000c0694c06>] check_noncircular+0x1e6/0x240
[ 204.830263] [<00000000c0695bec>] check_prev_add+0xfc/0xdb0
[ 204.830264] [<00000000c06971da>] validate_chain+0x93a/0xd08
[ 204.830266] [<00000000c06994c6>] __lock_acquire+0x4ae/0x9d0
[ 204.830267] [<00000000c069867c>] lock_acquire+0x114/0x280
[ 204.830269] [<00000000c09ca15c>] __kernfs_remove.part.0+0x2e4/0x360
[ 204.830270] [<00000000c09cb5c4>] kernfs_remove_by_name_ns+0x5c/0xa8
[ 204.830272] [<00000000c09cee14>] remove_files.isra.0+0x4c/0x98
[ 204.830274] [<00000000c09cf2ae>] sysfs_remove_group+0x66/0xc8
[ 204.830276] [<00000000c09cf356>] sysfs_remove_groups+0x46/0x68
[ 204.830278] [<00000000c0e3dfe2>] device_remove_attrs+0x52/0x90
[ 204.830280] [<00000000c0e40382>] device_del+0x182/0x418
[ 204.830281] [<00000000c0dcfd7a>] pci_remove_bus_device+0x8a/0x130
[ 204.830283] [<00000000c0dcfe92>] pci_stop_and_remove_bus_device_locked+0x3a/0x48
[ 204.830285] [<00000000c0de7190>] disable_slot+0x68/0x100
[ 204.830286] [<00000000c0de6514>] power_write_file+0x7c/0x130
[ 204.830288] [<00000000c09cc846>] kernfs_fop_write+0xe6/0x218
[ 204.830290] [<00000000c08f3480>] vfs_write+0xb0/0x1b8
[ 204.830291] [<00000000c08f378c>] ksys_write+0x6c/0xf8
[ 204.830293] [<00000000c1154374>] system_call+0xd8/0x2d8
[ 204.830294] INFO: lockdep is turned off.
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/pci/pci_sysfs.c | 63 ++++++++++++++++++++++++++-------------
1 file changed, 42 insertions(+), 21 deletions(-)
diff --git a/arch/s390/pci/pci_sysfs.c b/arch/s390/pci/pci_sysfs.c
index a433ba01a3175..215f17437a4f6 100644
--- a/arch/s390/pci/pci_sysfs.c
+++ b/arch/s390/pci/pci_sysfs.c
@@ -13,6 +13,8 @@
#include <linux/stat.h>
#include <linux/pci.h>
+#include "../../../drivers/pci/pci.h"
+
#include <asm/sclp.h>
#define zpci_attr(name, fmt, member) \
@@ -49,31 +51,50 @@ static DEVICE_ATTR_RO(mio_enabled);
static ssize_t recover_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
+ struct kernfs_node *kn;
struct pci_dev *pdev = to_pci_dev(dev);
struct zpci_dev *zdev = to_zpci(pdev);
- int ret;
-
- if (!device_remove_file_self(dev, attr))
- return count;
-
+ int ret = 0;
+
+ /* Can't use device_remove_self() here as that would lead us to lock
+ * the pci_rescan_remove_lock while holding the device' kernfs lock.
+ * This would create a possible deadlock with disable_slot() which is
+ * not directly protected by the device' kernfs lock but takes it
+ * during the device removal which happens under
+ * pci_rescan_remove_lock.
+ *
+ * This is analogous to sdev_store_delete() in
+ * drivers/scsi/scsi_sysfs.c
+ */
+ kn = sysfs_break_active_protection(&dev->kobj, &attr->attr);
+ WARN_ON_ONCE(!kn);
+ /* device_remove_file() serializes concurrent calls ignoring all but
+ * the first
+ */
+ device_remove_file(dev, attr);
+
+ /* A concurrent call to recover_store() may slip between
+ * sysfs_break_active_protection() and the sysfs file removal.
+ * Once it unblocks from pci_lock_rescan_remove() the original pdev
+ * will already be removed.
+ */
pci_lock_rescan_remove();
- pci_stop_and_remove_bus_device(pdev);
- ret = zpci_disable_device(zdev);
- if (ret)
- goto error;
-
- ret = zpci_enable_device(zdev);
- if (ret)
- goto error;
-
- pci_rescan_bus(zdev->bus);
+ if (pci_dev_is_added(pdev)) {
+ pci_stop_and_remove_bus_device(pdev);
+ ret = zpci_disable_device(zdev);
+ if (ret)
+ goto out;
+
+ ret = zpci_enable_device(zdev);
+ if (ret)
+ goto out;
+ pci_rescan_bus(zdev->bus);
+ }
+out:
pci_unlock_rescan_remove();
-
- return count;
-
-error:
- pci_unlock_rescan_remove();
- return ret;
+ if (kn)
+ sysfs_unbreak_active_protection(kn);
+ return ret ? ret : count;
}
static DEVICE_ATTR_WO(recover);
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH AUTOSEL 5.5 122/542] KVM: s390: ENOTSUPP -> EOPNOTSUPP fixups
[not found] <20200214154854.6746-1-sashal@kernel.org>
2020-02-14 15:41 ` [PATCH AUTOSEL 5.5 094/542] s390/pci: Fix possible deadlock in recover_store() Sasha Levin
@ 2020-02-14 15:41 ` Sasha Levin
2020-02-14 15:47 ` [PATCH AUTOSEL 5.5 433/542] s390: adjust -mpacked-stack support check for clang 10 Sasha Levin
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2020-02-14 15:41 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Christian Borntraeger, Julian Wiedmann, Cornelia Huck,
Thomas Huth, Sasha Levin, kvm, linux-s390
From: Christian Borntraeger <borntraeger@de.ibm.com>
[ Upstream commit c611990844c28c61ca4b35ff69d3a2ae95ccd486 ]
There is no ENOTSUPP for userspace.
Reported-by: Julian Wiedmann <jwi@linux.ibm.com>
Fixes: 519783935451 ("KVM: s390: introduce ais mode modify function")
Fixes: 2c1a48f2e5ed ("KVM: S390: add new group for flic")
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/kvm/interrupt.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 165dea4c7f193..c06c89d370a73 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -2190,7 +2190,7 @@ static int flic_ais_mode_get_all(struct kvm *kvm, struct kvm_device_attr *attr)
return -EINVAL;
if (!test_kvm_facility(kvm, 72))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
mutex_lock(&fi->ais_lock);
ais.simm = fi->simm;
@@ -2499,7 +2499,7 @@ static int modify_ais_mode(struct kvm *kvm, struct kvm_device_attr *attr)
int ret = 0;
if (!test_kvm_facility(kvm, 72))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
if (copy_from_user(&req, (void __user *)attr->addr, sizeof(req)))
return -EFAULT;
@@ -2579,7 +2579,7 @@ static int flic_ais_mode_set_all(struct kvm *kvm, struct kvm_device_attr *attr)
struct kvm_s390_ais_all ais;
if (!test_kvm_facility(kvm, 72))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
if (copy_from_user(&ais, (void __user *)attr->addr, sizeof(ais)))
return -EFAULT;
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH AUTOSEL 5.5 433/542] s390: adjust -mpacked-stack support check for clang 10
[not found] <20200214154854.6746-1-sashal@kernel.org>
2020-02-14 15:41 ` [PATCH AUTOSEL 5.5 094/542] s390/pci: Fix possible deadlock in recover_store() Sasha Levin
2020-02-14 15:41 ` [PATCH AUTOSEL 5.5 122/542] KVM: s390: ENOTSUPP -> EOPNOTSUPP fixups Sasha Levin
@ 2020-02-14 15:47 ` Sasha Levin
2020-02-14 15:47 ` [PATCH AUTOSEL 5.5 434/542] s390/ftrace: generate traced function stack frame Sasha Levin
2020-02-14 15:47 ` [PATCH AUTOSEL 5.5 435/542] s390: fix __EMIT_BUG() macro Sasha Levin
4 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2020-02-14 15:47 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Vasily Gorbik, Heiko Carstens, Sasha Levin, linux-s390,
clang-built-linux
From: Vasily Gorbik <gor@linux.ibm.com>
[ Upstream commit 253b3c4b2920e07ce9e2b18800b9b65245e2fafa ]
clang 10 introduces -mpacked-stack compiler option implementation. At the
same time currently it does not support a combination of -mpacked-stack
and -mbackchain. This leads to the following build error:
clang: error: unsupported option '-mpacked-stack with -mbackchain' for
target 's390x-ibm-linux'
If/when clang adds support for a combination of -mpacked-stack and
-mbackchain it would also require -msoft-float (like gcc does). According
to Ulrich Weigand "stack slot assigned to the kernel backchain overlaps
the stack slot assigned to the FPR varargs (both are required to be
placed immediately after the saved r15 slot if present)."
Extend -mpacked-stack compiler option support check to include all 3
options -mpacked-stack -mbackchain -msoft-float which must present to
support -mpacked-stack with -mbackchain.
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index ba8556bb0fb15..e0e3a465bbfd6 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -69,7 +69,7 @@ cflags-y += -Wa,-I$(srctree)/arch/$(ARCH)/include
#
cflags-$(CONFIG_FRAME_POINTER) += -fno-optimize-sibling-calls
-ifeq ($(call cc-option-yn,-mpacked-stack),y)
+ifeq ($(call cc-option-yn,-mpacked-stack -mbackchain -msoft-float),y)
cflags-$(CONFIG_PACK_STACK) += -mpacked-stack -D__PACK_STACK
aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK
endif
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH AUTOSEL 5.5 434/542] s390/ftrace: generate traced function stack frame
[not found] <20200214154854.6746-1-sashal@kernel.org>
` (2 preceding siblings ...)
2020-02-14 15:47 ` [PATCH AUTOSEL 5.5 433/542] s390: adjust -mpacked-stack support check for clang 10 Sasha Levin
@ 2020-02-14 15:47 ` Sasha Levin
2020-02-14 15:47 ` [PATCH AUTOSEL 5.5 435/542] s390: fix __EMIT_BUG() macro Sasha Levin
4 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2020-02-14 15:47 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Vasily Gorbik, Sven Schnelle, Heiko Carstens, Sasha Levin,
linux-s390
From: Vasily Gorbik <gor@linux.ibm.com>
[ Upstream commit 45f7a0da600d3c409b5ad8d5ddddacd98ddc8840 ]
Currently backtrace from ftraced function does not contain ftraced
function itself. e.g. for "path_openat":
arch_stack_walk+0x15c/0x2d8
stack_trace_save+0x50/0x68
stack_trace_call+0x15e/0x3d8
ftrace_graph_caller+0x0/0x1c <-- ftrace code
do_filp_open+0x7c/0xe8 <-- ftraced function caller
do_open_execat+0x76/0x1b8
open_exec+0x52/0x78
load_elf_binary+0x180/0x1160
search_binary_handler+0x8e/0x288
load_script+0x2a8/0x2b8
search_binary_handler+0x8e/0x288
__do_execve_file.isra.39+0x6fa/0xb40
__s390x_sys_execve+0x56/0x68
system_call+0xdc/0x2d8
Ftraced function is expected in the backtrace by ftrace kselftests, which
are now failing. It would also be nice to have it for clarity reasons.
"ftrace_caller" itself is called without stack frame allocated for it
and does not store its caller (ftraced function). Instead it simply
allocates a stack frame for "ftrace_trace_function" and sets backchain
to point to ftraced function stack frame (which contains ftraced function
caller in saved r14).
To fix this issue make "ftrace_caller" allocate a stack frame
for itself just to store ftraced function for the stack unwinder.
As a result backtrace looks like the following:
arch_stack_walk+0x15c/0x2d8
stack_trace_save+0x50/0x68
stack_trace_call+0x15e/0x3d8
ftrace_graph_caller+0x0/0x1c <-- ftrace code
path_openat+0x6/0xd60 <-- ftraced function
do_filp_open+0x7c/0xe8 <-- ftraced function caller
do_open_execat+0x76/0x1b8
open_exec+0x52/0x78
load_elf_binary+0x180/0x1160
search_binary_handler+0x8e/0x288
load_script+0x2a8/0x2b8
search_binary_handler+0x8e/0x288
__do_execve_file.isra.39+0x6fa/0xb40
__s390x_sys_execve+0x56/0x68
system_call+0xdc/0x2d8
Reported-by: Sven Schnelle <sven.schnelle@ibm.com>
Tested-by: Sven Schnelle <sven.schnelle@ibm.com>
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/kernel/mcount.S | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S
index c3597d2e2ae0e..f942341429b1c 100644
--- a/arch/s390/kernel/mcount.S
+++ b/arch/s390/kernel/mcount.S
@@ -26,6 +26,12 @@ ENDPROC(ftrace_stub)
#define STACK_PTREGS (STACK_FRAME_OVERHEAD)
#define STACK_PTREGS_GPRS (STACK_PTREGS + __PT_GPRS)
#define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW)
+#ifdef __PACK_STACK
+/* allocate just enough for r14, r15 and backchain */
+#define TRACED_FUNC_FRAME_SIZE 24
+#else
+#define TRACED_FUNC_FRAME_SIZE STACK_FRAME_OVERHEAD
+#endif
ENTRY(_mcount)
BR_EX %r14
@@ -40,9 +46,16 @@ ENTRY(ftrace_caller)
#if !(defined(CC_USING_HOTPATCH) || defined(CC_USING_NOP_MCOUNT))
aghi %r0,MCOUNT_RETURN_FIXUP
#endif
- aghi %r15,-STACK_FRAME_SIZE
+ # allocate stack frame for ftrace_caller to contain traced function
+ aghi %r15,-TRACED_FUNC_FRAME_SIZE
stg %r1,__SF_BACKCHAIN(%r15)
+ stg %r0,(__SF_GPRS+8*8)(%r15)
+ stg %r15,(__SF_GPRS+9*8)(%r15)
+ # allocate pt_regs and stack frame for ftrace_trace_function
+ aghi %r15,-STACK_FRAME_SIZE
stg %r1,(STACK_PTREGS_GPRS+15*8)(%r15)
+ aghi %r1,-TRACED_FUNC_FRAME_SIZE
+ stg %r1,__SF_BACKCHAIN(%r15)
stg %r0,(STACK_PTREGS_PSW+8)(%r15)
stmg %r2,%r14,(STACK_PTREGS_GPRS+2*8)(%r15)
#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH AUTOSEL 5.5 435/542] s390: fix __EMIT_BUG() macro
[not found] <20200214154854.6746-1-sashal@kernel.org>
` (3 preceding siblings ...)
2020-02-14 15:47 ` [PATCH AUTOSEL 5.5 434/542] s390/ftrace: generate traced function stack frame Sasha Levin
@ 2020-02-14 15:47 ` Sasha Levin
4 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2020-02-14 15:47 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Sven Schnelle, Heiko Carstens, Vasily Gorbik, Sasha Levin,
linux-s390
From: Sven Schnelle <svens@linux.ibm.com>
[ Upstream commit 17248ea0367465f4aaef728f6af661ed38e38cf1 ]
Setting a kprobe on getname_flags() failed:
$ echo 'p:tmr1 getname_flags +0(%r2):ustring' > kprobe_events
-bash: echo: write error: Invalid argument
Debugging the kprobes code showed that the address of
getname_flags() is contained in the __bug_table. Kprobes
doesn't allow to set probes at BUG() locations.
$ objdump -j __bug_table -x build/fs/namei.o
[..]
0000000000000108 R_390_PC32 .text+0x00000000000075a8
000000000000010c R_390_PC32 .L223+0x0000000000000004
I was expecting getname_flags() to start with a BUG(), but:
7598: e3 20 10 00 00 04 lg %r2,0(%r1)
759e: c0 f4 00 00 00 00 jg 759e <putname+0x7e>
75a0: R_390_PLT32DBL kmem_cache_free+0x2
75a4: a7 f4 00 01 j 75a6 <putname+0x86>
00000000000075a8 <getname_flags>:
75a8: c0 04 00 00 00 00 brcl 0,75a8 <getname_flags>
75ae: eb 6f f0 48 00 24 stmg %r6,%r15,72(%r15)
75b4: b9 04 00 ef lgr %r14,%r15
75b8: e3 f0 ff a8 ff 71 lay %r15,-88(%r15)
So the BUG() is actually the last opcode of the previous function.
Fix this by switching to using the MONITOR CALL (MC) instruction,
and set the entry in __bug_table to the beginning of that MC.
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/boot/head.S | 2 +-
arch/s390/include/asm/bug.h | 16 ++++++--------
arch/s390/kernel/entry.h | 1 +
arch/s390/kernel/pgm_check.S | 2 +-
arch/s390/kernel/traps.c | 41 +++++++++++++++++++++++++++++++-----
5 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/arch/s390/boot/head.S b/arch/s390/boot/head.S
index 4b86a8d3c1219..dae10961d0724 100644
--- a/arch/s390/boot/head.S
+++ b/arch/s390/boot/head.S
@@ -329,7 +329,7 @@ ENTRY(startup_kdump)
.quad .Lduct # cr5: primary-aste origin
.quad 0 # cr6: I/O interrupts
.quad 0 # cr7: secondary space segment table
- .quad 0 # cr8: access registers translation
+ .quad 0x0000000000008000 # cr8: access registers translation
.quad 0 # cr9: tracing off
.quad 0 # cr10: tracing off
.quad 0 # cr11: tracing off
diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h
index a2b11ac00f607..7725f8006fdfb 100644
--- a/arch/s390/include/asm/bug.h
+++ b/arch/s390/include/asm/bug.h
@@ -10,15 +10,14 @@
#define __EMIT_BUG(x) do { \
asm_inline volatile( \
- "0: j 0b+2\n" \
- "1:\n" \
+ "0: mc 0,0\n" \
".section .rodata.str,\"aMS\",@progbits,1\n" \
- "2: .asciz \""__FILE__"\"\n" \
+ "1: .asciz \""__FILE__"\"\n" \
".previous\n" \
".section __bug_table,\"awM\",@progbits,%2\n" \
- "3: .long 1b-3b,2b-3b\n" \
+ "2: .long 0b-2b,1b-2b\n" \
" .short %0,%1\n" \
- " .org 3b+%2\n" \
+ " .org 2b+%2\n" \
".previous\n" \
: : "i" (__LINE__), \
"i" (x), \
@@ -29,12 +28,11 @@
#define __EMIT_BUG(x) do { \
asm_inline volatile( \
- "0: j 0b+2\n" \
- "1:\n" \
+ "0: mc 0,0\n" \
".section __bug_table,\"awM\",@progbits,%1\n" \
- "2: .long 1b-2b\n" \
+ "1: .long 0b-1b\n" \
" .short %0\n" \
- " .org 2b+%1\n" \
+ " .org 1b+%1\n" \
".previous\n" \
: : "i" (x), \
"i" (sizeof(struct bug_entry))); \
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index b2956d49b6ad7..1d3927e01a5fd 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -45,6 +45,7 @@ void specification_exception(struct pt_regs *regs);
void transaction_exception(struct pt_regs *regs);
void translation_exception(struct pt_regs *regs);
void vector_exception(struct pt_regs *regs);
+void monitor_event_exception(struct pt_regs *regs);
void do_per_trap(struct pt_regs *regs);
void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str);
diff --git a/arch/s390/kernel/pgm_check.S b/arch/s390/kernel/pgm_check.S
index 59dee9d3bebf1..eee3a482195a6 100644
--- a/arch/s390/kernel/pgm_check.S
+++ b/arch/s390/kernel/pgm_check.S
@@ -81,7 +81,7 @@ PGM_CHECK_DEFAULT /* 3c */
PGM_CHECK_DEFAULT /* 3d */
PGM_CHECK_DEFAULT /* 3e */
PGM_CHECK_DEFAULT /* 3f */
-PGM_CHECK_DEFAULT /* 40 */
+PGM_CHECK(monitor_event_exception) /* 40 */
PGM_CHECK_DEFAULT /* 41 */
PGM_CHECK_DEFAULT /* 42 */
PGM_CHECK_DEFAULT /* 43 */
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 164c0282b41ae..dc75588d78943 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -53,11 +53,6 @@ void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str)
if (fixup)
regs->psw.addr = extable_fixup(fixup);
else {
- enum bug_trap_type btt;
-
- btt = report_bug(regs->psw.addr, regs);
- if (btt == BUG_TRAP_TYPE_WARN)
- return;
die(regs, str);
}
}
@@ -245,6 +240,27 @@ void space_switch_exception(struct pt_regs *regs)
do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event");
}
+void monitor_event_exception(struct pt_regs *regs)
+{
+ const struct exception_table_entry *fixup;
+
+ if (user_mode(regs))
+ return;
+
+ switch (report_bug(regs->psw.addr - (regs->int_code >> 16), regs)) {
+ case BUG_TRAP_TYPE_NONE:
+ fixup = s390_search_extables(regs->psw.addr);
+ if (fixup)
+ regs->psw.addr = extable_fixup(fixup);
+ break;
+ case BUG_TRAP_TYPE_WARN:
+ break;
+ case BUG_TRAP_TYPE_BUG:
+ die(regs, "monitor event");
+ break;
+ }
+}
+
void kernel_stack_overflow(struct pt_regs *regs)
{
bust_spinlocks(1);
@@ -255,8 +271,23 @@ void kernel_stack_overflow(struct pt_regs *regs)
}
NOKPROBE_SYMBOL(kernel_stack_overflow);
+static void test_monitor_call(void)
+{
+ int val = 1;
+
+ asm volatile(
+ " mc 0,0\n"
+ "0: xgr %0,%0\n"
+ "1:\n"
+ EX_TABLE(0b,1b)
+ : "+d" (val));
+ if (!val)
+ panic("Monitor call doesn't work!\n");
+}
+
void __init trap_init(void)
{
sort_extable(__start_dma_ex_table, __stop_dma_ex_table);
local_mcck_enable();
+ test_monitor_call();
}
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH AUTOSEL 5.5 094/542] s390/pci: Fix possible deadlock in recover_store()
2020-02-14 15:41 ` [PATCH AUTOSEL 5.5 094/542] s390/pci: Fix possible deadlock in recover_store() Sasha Levin
@ 2020-02-17 9:31 ` Niklas Schnelle
2020-02-20 16:11 ` Sasha Levin
0 siblings, 1 reply; 7+ messages in thread
From: Niklas Schnelle @ 2020-02-17 9:31 UTC (permalink / raw)
To: Sasha Levin
Cc: linux-kernel, stable, Peter Oberparleiter, Vasily Gorbik,
linux-s390
On Fri, Feb 14, 2020 at 10:41:26AM -0500, Sasha Levin wrote:
> From: Niklas Schnelle <schnelle@linux.ibm.com>
>
> [ Upstream commit 576c75e36c689bec6a940e807bae27291ab0c0de ]
>
> With zpci_disable() working, lockdep detected a potential deadlock
> (lockdep output at the end).
>
> The deadlock is between recovering a PCI function via the
>
> /sys/bus/pci/devices/<dev>/recover
>
> attribute vs powering it off via
>
> /sys/bus/pci/slots/<slot>/power.
>
> The fix is analogous to the changes in commit 0ee223b2e1f6 ("scsi: core:
> Avoid that SCSI device removal through sysfs triggers a deadlock")
> that fixed a potential deadlock on removing a SCSI device via sysfs.
[ ... snip ... ]
While technically useful on its own this commit really should go together with
the following upstream commit:
17cdec960cf776b20b1fb08c622221babe591d51
("s390/pci: Recover handle in clp_set_pci_fn()")
While the problem fixed here is independent, writing to the power/recover
attributes will often fail due to an inconsistent function handle without the
second commit.
In particular without it a PCI function in the error state can not be
recovered or powered off.
I would recommend adding the second commit to the backports as well.
Thanks,
Niklas Schnelle
--
Niklas Schnelle
Linux on Z Development
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH AUTOSEL 5.5 094/542] s390/pci: Fix possible deadlock in recover_store()
2020-02-17 9:31 ` Niklas Schnelle
@ 2020-02-20 16:11 ` Sasha Levin
0 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2020-02-20 16:11 UTC (permalink / raw)
To: Niklas Schnelle
Cc: linux-kernel, stable, Peter Oberparleiter, Vasily Gorbik,
linux-s390
On Mon, Feb 17, 2020 at 10:31:56AM +0100, Niklas Schnelle wrote:
>On Fri, Feb 14, 2020 at 10:41:26AM -0500, Sasha Levin wrote:
>> From: Niklas Schnelle <schnelle@linux.ibm.com>
>>
>> [ Upstream commit 576c75e36c689bec6a940e807bae27291ab0c0de ]
>>
>> With zpci_disable() working, lockdep detected a potential deadlock
>> (lockdep output at the end).
>>
>> The deadlock is between recovering a PCI function via the
>>
>> /sys/bus/pci/devices/<dev>/recover
>>
>> attribute vs powering it off via
>>
>> /sys/bus/pci/slots/<slot>/power.
>>
>> The fix is analogous to the changes in commit 0ee223b2e1f6 ("scsi: core:
>> Avoid that SCSI device removal through sysfs triggers a deadlock")
>> that fixed a potential deadlock on removing a SCSI device via sysfs.
>[ ... snip ... ]
>
>While technically useful on its own this commit really should go together with
>the following upstream commit:
>
>17cdec960cf776b20b1fb08c622221babe591d51
>("s390/pci: Recover handle in clp_set_pci_fn()")
>
>While the problem fixed here is independent, writing to the power/recover
>attributes will often fail due to an inconsistent function handle without the
>second commit.
>In particular without it a PCI function in the error state can not be
>recovered or powered off.
>
>I would recommend adding the second commit to the backports as well.
I took that commit as well, thank you.
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2020-02-20 16:11 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20200214154854.6746-1-sashal@kernel.org>
2020-02-14 15:41 ` [PATCH AUTOSEL 5.5 094/542] s390/pci: Fix possible deadlock in recover_store() Sasha Levin
2020-02-17 9:31 ` Niklas Schnelle
2020-02-20 16:11 ` Sasha Levin
2020-02-14 15:41 ` [PATCH AUTOSEL 5.5 122/542] KVM: s390: ENOTSUPP -> EOPNOTSUPP fixups Sasha Levin
2020-02-14 15:47 ` [PATCH AUTOSEL 5.5 433/542] s390: adjust -mpacked-stack support check for clang 10 Sasha Levin
2020-02-14 15:47 ` [PATCH AUTOSEL 5.5 434/542] s390/ftrace: generate traced function stack frame Sasha Levin
2020-02-14 15:47 ` [PATCH AUTOSEL 5.5 435/542] s390: fix __EMIT_BUG() macro Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).