From: Greg Kroah-Hartman Date: Mon, 26 Aug 2013 18:56:10 +0000 (-0700) Subject: 3.10-stable patches X-Git-Tag: v3.0.94~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=656552432a253cec9f0b349bf36a36fc5818dafe;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: hostap-copying-wrong-data-prism2_ioctl_giwaplist.patch iwlwifi-dvm-fix-calling-ieee80211_chswitch_done-with-null.patch iwlwifi-pcie-disable-l1-active-after-pci_enable_device.patch libata-apply-behavioral-quirks-to-sil3826-pmp.patch mei-don-t-have-to-clean-the-state-on-power-up.patch mei-me-fix-reset-state-machine.patch mei-me-fix-waiting-for-hw-ready.patch revert-x86-get_unmapped_area-use-proper-mmap-base-for-bottom-up-direction.patch sata_fsl-save-irqs-while-coalescing.patch scsi-lpfc-don-t-force-config_generic_csum-on.patch scsi-sg-fix-user-memory-corruption-when-sg_io-is-interrupted-by-a-signal.patch scsi-zfcp-fix-lock-imbalance-by-reworking-request-queue-locking.patch x86-get_unmapped_area-access-mmap_legacy_base-through-mm_struct-member.patch x86-xen-do-not-identity-map-unusable-regions-in-the-machine-e820.patch zfcp-fix-schedule-inside-lock-in-scsi_device-list-loops.patch --- diff --git a/queue-3.10/hostap-copying-wrong-data-prism2_ioctl_giwaplist.patch b/queue-3.10/hostap-copying-wrong-data-prism2_ioctl_giwaplist.patch new file mode 100644 index 00000000000..becde56d02f --- /dev/null +++ b/queue-3.10/hostap-copying-wrong-data-prism2_ioctl_giwaplist.patch @@ -0,0 +1,34 @@ +From 909bd5926d474e275599094acad986af79671ac9 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 9 Aug 2013 12:52:31 +0300 +Subject: Hostap: copying wrong data prism2_ioctl_giwaplist() + +From: Dan Carpenter + +commit 909bd5926d474e275599094acad986af79671ac9 upstream. + +We want the data stored in "addr" and "qual", but the extra ampersands +mean we are copying stack data instead. + +Signed-off-by: Dan Carpenter +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/hostap/hostap_ioctl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/hostap/hostap_ioctl.c ++++ b/drivers/net/wireless/hostap/hostap_ioctl.c +@@ -523,9 +523,9 @@ static int prism2_ioctl_giwaplist(struct + + data->length = prism2_ap_get_sta_qual(local, addr, qual, IW_MAX_AP, 1); + +- memcpy(extra, &addr, sizeof(struct sockaddr) * data->length); ++ memcpy(extra, addr, sizeof(struct sockaddr) * data->length); + data->flags = 1; /* has quality information */ +- memcpy(extra + sizeof(struct sockaddr) * data->length, &qual, ++ memcpy(extra + sizeof(struct sockaddr) * data->length, qual, + sizeof(struct iw_quality) * data->length); + + kfree(addr); diff --git a/queue-3.10/iwlwifi-dvm-fix-calling-ieee80211_chswitch_done-with-null.patch b/queue-3.10/iwlwifi-dvm-fix-calling-ieee80211_chswitch_done-with-null.patch new file mode 100644 index 00000000000..e197946b5de --- /dev/null +++ b/queue-3.10/iwlwifi-dvm-fix-calling-ieee80211_chswitch_done-with-null.patch @@ -0,0 +1,61 @@ +From 9186a1fd9ed190739423db84bc344d258ef3e3d7 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Fri, 26 Jul 2013 15:29:09 +0200 +Subject: iwlwifi: dvm: fix calling ieee80211_chswitch_done() with NULL + +From: Stanislaw Gruszka + +commit 9186a1fd9ed190739423db84bc344d258ef3e3d7 upstream. + +If channel switch is pending and we remove interface we can +crash like showed below due to passing NULL vif to mac80211: + +BUG: unable to handle kernel paging request at fffffffffffff8cc +IP: [] strnlen+0xd/0x40 +Call Trace: + [] string.isra.3+0x3e/0xd0 + [] vsnprintf+0x219/0x640 + [] vscnprintf+0x11/0x30 + [] vprintk_emit+0x115/0x4f0 + [] printk+0x61/0x63 + [] ieee80211_chswitch_done+0xaf/0xd0 [mac80211] + [] iwl_chswitch_done+0x34/0x40 [iwldvm] + [] iwlagn_commit_rxon+0x2a3/0xdc0 [iwldvm] + [] ? iwlagn_set_rxon_chain+0x180/0x2c0 [iwldvm] + [] iwl_set_mode+0x36/0x40 [iwldvm] + [] iwlagn_mac_remove_interface+0x8d/0x1b0 [iwldvm] + [] ieee80211_do_stop+0x29d/0x7f0 [mac80211] + +This is because we nulify ctx->vif in iwlagn_mac_remove_interface() +before calling some other functions that teardown interface. To fix +just check ctx->vif on iwl_chswitch_done(). We should not call +ieee80211_chswitch_done() as channel switch works were already canceled +by mac80211 in ieee80211_do_stop() -> ieee80211_mgd_stop(). + +Resolve: +https://bugzilla.redhat.com/show_bug.cgi?id=979581 + +Reported-by: Lukasz Jagiello +Signed-off-by: Stanislaw Gruszka +Reviewed-by: Emmanuel Grumbach +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/iwlwifi/dvm/mac80211.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c ++++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c +@@ -1059,7 +1059,10 @@ void iwl_chswitch_done(struct iwl_priv * + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + +- if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) ++ if (!test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) ++ return; ++ ++ if (ctx->vif) + ieee80211_chswitch_done(ctx->vif, is_success); + } + diff --git a/queue-3.10/iwlwifi-pcie-disable-l1-active-after-pci_enable_device.patch b/queue-3.10/iwlwifi-pcie-disable-l1-active-after-pci_enable_device.patch new file mode 100644 index 00000000000..3923313e73c --- /dev/null +++ b/queue-3.10/iwlwifi-pcie-disable-l1-active-after-pci_enable_device.patch @@ -0,0 +1,46 @@ +From eabc4ac5d7606a57ee2b7308cb7323ea8f60183b Mon Sep 17 00:00:00 2001 +From: Emmanuel Grumbach +Date: Mon, 29 Jul 2013 23:05:18 +0300 +Subject: iwlwifi: pcie: disable L1 Active after pci_enable_device + +From: Emmanuel Grumbach + +commit eabc4ac5d7606a57ee2b7308cb7323ea8f60183b upstream. + +As Arjan pointed out, we mustn't do anything related to PCI +configuration until the device is properly enabled with +pci_enable_device(). + +Reported-by: Arjan van de Ven +Signed-off-by: Emmanuel Grumbach +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/iwlwifi/pcie/trans.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/iwlwifi/pcie/trans.c ++++ b/drivers/net/wireless/iwlwifi/pcie/trans.c +@@ -1481,16 +1481,16 @@ struct iwl_trans *iwl_trans_pcie_alloc(s + spin_lock_init(&trans_pcie->reg_lock); + init_waitqueue_head(&trans_pcie->ucode_write_waitq); + +- /* W/A - seems to solve weird behavior. We need to remove this if we +- * don't want to stay in L1 all the time. This wastes a lot of power */ +- pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | +- PCIE_LINK_STATE_CLKPM); +- + if (pci_enable_device(pdev)) { + err = -ENODEV; + goto out_no_pci; + } + ++ /* W/A - seems to solve weird behavior. We need to remove this if we ++ * don't want to stay in L1 all the time. This wastes a lot of power */ ++ pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | ++ PCIE_LINK_STATE_CLKPM); ++ + pci_set_master(pdev); + + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); diff --git a/queue-3.10/libata-apply-behavioral-quirks-to-sil3826-pmp.patch b/queue-3.10/libata-apply-behavioral-quirks-to-sil3826-pmp.patch new file mode 100644 index 00000000000..508ac181dee --- /dev/null +++ b/queue-3.10/libata-apply-behavioral-quirks-to-sil3826-pmp.patch @@ -0,0 +1,66 @@ +From 8ffff94d20b7eb446e848e0046107d51b17a20a8 Mon Sep 17 00:00:00 2001 +From: Terry Suereth +Date: Sat, 17 Aug 2013 15:53:12 -0400 +Subject: libata: apply behavioral quirks to sil3826 PMP + +From: Terry Suereth + +commit 8ffff94d20b7eb446e848e0046107d51b17a20a8 upstream. + +Fixing support for the Silicon Image 3826 port multiplier, by applying +to it the same quirks applied to the Silicon Image 3726. Specifically +fixes the repeated timeout/reset process which previously afflicted +the 3726, as described from line 290. Slightly based on notes from: + +https://bugzilla.redhat.com/show_bug.cgi?id=890237 + +Signed-off-by: Terry Suereth +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/libata-pmp.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/ata/libata-pmp.c ++++ b/drivers/ata/libata-pmp.c +@@ -289,24 +289,24 @@ static int sata_pmp_configure(struct ata + + /* Disable sending Early R_OK. + * With "cached read" HDD testing and multiple ports busy on a SATA +- * host controller, 3726 PMP will very rarely drop a deferred ++ * host controller, 3x26 PMP will very rarely drop a deferred + * R_OK that was intended for the host. Symptom will be all + * 5 drives under test will timeout, get reset, and recover. + */ +- if (vendor == 0x1095 && devid == 0x3726) { ++ if (vendor == 0x1095 && (devid == 0x3726 || devid == 0x3826)) { + u32 reg; + + err_mask = sata_pmp_read(&ap->link, PMP_GSCR_SII_POL, ®); + if (err_mask) { + rc = -EIO; +- reason = "failed to read Sil3726 Private Register"; ++ reason = "failed to read Sil3x26 Private Register"; + goto fail; + } + reg &= ~0x1; + err_mask = sata_pmp_write(&ap->link, PMP_GSCR_SII_POL, reg); + if (err_mask) { + rc = -EIO; +- reason = "failed to write Sil3726 Private Register"; ++ reason = "failed to write Sil3x26 Private Register"; + goto fail; + } + } +@@ -383,8 +383,8 @@ static void sata_pmp_quirks(struct ata_p + u16 devid = sata_pmp_gscr_devid(gscr); + struct ata_link *link; + +- if (vendor == 0x1095 && devid == 0x3726) { +- /* sil3726 quirks */ ++ if (vendor == 0x1095 && (devid == 0x3726 || devid == 0x3826)) { ++ /* sil3x26 quirks */ + ata_for_each_link(link, ap, EDGE) { + /* link reports offline after LPM */ + link->flags |= ATA_LFLAG_NO_LPM; diff --git a/queue-3.10/mei-don-t-have-to-clean-the-state-on-power-up.patch b/queue-3.10/mei-don-t-have-to-clean-the-state-on-power-up.patch new file mode 100644 index 00000000000..2dee177ba63 --- /dev/null +++ b/queue-3.10/mei-don-t-have-to-clean-the-state-on-power-up.patch @@ -0,0 +1,32 @@ +From 99f22c4ef24cf87b0dae6aabe6b5e620b62961d9 Mon Sep 17 00:00:00 2001 +From: Tomas Winkler +Date: Wed, 17 Jul 2013 15:13:16 +0300 +Subject: mei: don't have to clean the state on power up + +From: Tomas Winkler + +commit 99f22c4ef24cf87b0dae6aabe6b5e620b62961d9 upstream. + +When powering up, we don't have to clean up the device state +nothing is connected. + +Tested-by: Shuah Khan +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mei/init.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/misc/mei/init.c ++++ b/drivers/misc/mei/init.c +@@ -143,7 +143,8 @@ void mei_reset(struct mei_device *dev, i + + dev->hbm_state = MEI_HBM_IDLE; + +- if (dev->dev_state != MEI_DEV_INITIALIZING) { ++ if (dev->dev_state != MEI_DEV_INITIALIZING && ++ dev->dev_state != MEI_DEV_POWER_UP) { + if (dev->dev_state != MEI_DEV_DISABLED && + dev->dev_state != MEI_DEV_POWER_DOWN) + dev->dev_state = MEI_DEV_RESETTING; diff --git a/queue-3.10/mei-me-fix-reset-state-machine.patch b/queue-3.10/mei-me-fix-reset-state-machine.patch new file mode 100644 index 00000000000..50fc03dfac3 --- /dev/null +++ b/queue-3.10/mei-me-fix-reset-state-machine.patch @@ -0,0 +1,35 @@ +From 315a383ad7dbd484fafb93ef08038e3dbafbb7a8 Mon Sep 17 00:00:00 2001 +From: Tomas Winkler +Date: Wed, 17 Jul 2013 15:13:15 +0300 +Subject: mei: me: fix reset state machine + +From: Tomas Winkler + +commit 315a383ad7dbd484fafb93ef08038e3dbafbb7a8 upstream. + +ME HW ready bit is down after hw reset was asserted or on error. +Only on error we need to enter the reset flow, additional reset +need to be prevented when reset was triggered during +initialization , power up/down or a reset is already in progress + +Tested-by: Shuah Khan +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mei/hw-me.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/misc/mei/hw-me.c ++++ b/drivers/misc/mei/hw-me.c +@@ -482,7 +482,9 @@ irqreturn_t mei_me_irq_thread_handler(in + /* check if ME wants a reset */ + if (!mei_hw_is_ready(dev) && + dev->dev_state != MEI_DEV_RESETTING && +- dev->dev_state != MEI_DEV_INITIALIZING) { ++ dev->dev_state != MEI_DEV_INITIALIZING && ++ dev->dev_state != MEI_DEV_POWER_DOWN && ++ dev->dev_state != MEI_DEV_POWER_UP) { + dev_dbg(&dev->pdev->dev, "FW not ready.\n"); + mei_reset(dev, 1); + mutex_unlock(&dev->device_lock); diff --git a/queue-3.10/mei-me-fix-waiting-for-hw-ready.patch b/queue-3.10/mei-me-fix-waiting-for-hw-ready.patch new file mode 100644 index 00000000000..b8be800d43b --- /dev/null +++ b/queue-3.10/mei-me-fix-waiting-for-hw-ready.patch @@ -0,0 +1,48 @@ +From dab9bf41b23fe700c4a74133e41eb6a21706031e Mon Sep 17 00:00:00 2001 +From: Tomas Winkler +Date: Wed, 17 Jul 2013 15:13:17 +0300 +Subject: mei: me: fix waiting for hw ready + +From: Tomas Winkler + +commit dab9bf41b23fe700c4a74133e41eb6a21706031e upstream. + +1. MEI_INTEROP_TIMEOUT is in seconds not in jiffies +so we use mei_secs_to_jiffies macro +While cold boot is fast this is relevant in resume +2. wait_event_interruptible_timeout can return with +-ERESTARTSYS so do not override it with -ETIMEDOUT +3.Adjust error message + +Tested-by: Shuah Khan +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mei/hw-me.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/drivers/misc/mei/hw-me.c ++++ b/drivers/misc/mei/hw-me.c +@@ -238,14 +238,18 @@ static int mei_me_hw_ready_wait(struct m + if (mei_me_hw_is_ready(dev)) + return 0; + ++ dev->recvd_hw_ready = false; + mutex_unlock(&dev->device_lock); + err = wait_event_interruptible_timeout(dev->wait_hw_ready, +- dev->recvd_hw_ready, MEI_INTEROP_TIMEOUT); ++ dev->recvd_hw_ready, ++ mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT)); + mutex_lock(&dev->device_lock); + if (!err && !dev->recvd_hw_ready) { ++ if (!err) ++ err = -ETIMEDOUT; + dev_err(&dev->pdev->dev, +- "wait hw ready failed. status = 0x%x\n", err); +- return -ETIMEDOUT; ++ "wait hw ready failed. status = %d\n", err); ++ return err; + } + + dev->recvd_hw_ready = false; diff --git a/queue-3.10/revert-x86-get_unmapped_area-use-proper-mmap-base-for-bottom-up-direction.patch b/queue-3.10/revert-x86-get_unmapped_area-use-proper-mmap-base-for-bottom-up-direction.patch new file mode 100644 index 00000000000..1da2c0ab7ee --- /dev/null +++ b/queue-3.10/revert-x86-get_unmapped_area-use-proper-mmap-base-for-bottom-up-direction.patch @@ -0,0 +1,67 @@ +From 5ea80f76a56605a190a7ea16846c82aa63dbd0aa Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Thu, 22 Aug 2013 09:13:06 -0700 +Subject: Revert "x86 get_unmapped_area(): use proper mmap base for bottom-up direction" + +From: Linus Torvalds + +commit 5ea80f76a56605a190a7ea16846c82aa63dbd0aa upstream. + +This reverts commit df54d6fa54275ce59660453e29d1228c2b45a826. + +The commit isn't necessarily wrong, but because it recalculates the +random mmap_base every time, it seems to confuse user memory allocators +that expect contiguous mmap allocations even when the mmap address isn't +specified. + +In particular, the MATLAB Java runtime seems to be unhappy. See + + https://bugzilla.kernel.org/show_bug.cgi?id=60774 + +So we'll want to apply the random offset only once, and Radu has a patch +for that. Revert this older commit in order to apply the other one. + +Reported-by: Jeff Shorey +Cc: Radu Caragea +Cc: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/sys_x86_64.c | 2 +- + arch/x86/mm/mmap.c | 2 +- + include/linux/sched.h | 1 - + 3 files changed, 2 insertions(+), 3 deletions(-) + +--- a/arch/x86/kernel/sys_x86_64.c ++++ b/arch/x86/kernel/sys_x86_64.c +@@ -101,7 +101,7 @@ static void find_start_end(unsigned long + *begin = new_begin; + } + } else { +- *begin = mmap_legacy_base(); ++ *begin = TASK_UNMAPPED_BASE; + *end = TASK_SIZE; + } + } +--- a/arch/x86/mm/mmap.c ++++ b/arch/x86/mm/mmap.c +@@ -98,7 +98,7 @@ static unsigned long mmap_base(void) + * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64 + * does, but not when emulating X86_32 + */ +-unsigned long mmap_legacy_base(void) ++static unsigned long mmap_legacy_base(void) + { + if (mmap_is_ia32()) + return TASK_UNMAPPED_BASE; +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -314,7 +314,6 @@ struct nsproxy; + struct user_namespace; + + #ifdef CONFIG_MMU +-extern unsigned long mmap_legacy_base(void); + extern void arch_pick_mmap_layout(struct mm_struct *mm); + extern unsigned long + arch_get_unmapped_area(struct file *, unsigned long, unsigned long, diff --git a/queue-3.10/sata_fsl-save-irqs-while-coalescing.patch b/queue-3.10/sata_fsl-save-irqs-while-coalescing.patch new file mode 100644 index 00000000000..0b6f4329131 --- /dev/null +++ b/queue-3.10/sata_fsl-save-irqs-while-coalescing.patch @@ -0,0 +1,126 @@ +From 99bbdfa6bdcb4bdf5be914a48e9b46941bf30819 Mon Sep 17 00:00:00 2001 +From: Anthony Foiani +Date: Mon, 19 Aug 2013 19:20:30 -0600 +Subject: sata_fsl: save irqs while coalescing + +From: Anthony Foiani + +commit 99bbdfa6bdcb4bdf5be914a48e9b46941bf30819 upstream. + +Before this patch, I was seeing the following lockdep splat on my +MPC8315 (PPC32) target: + + [ 9.086051] ================================= + [ 9.090393] [ INFO: inconsistent lock state ] + [ 9.094744] 3.9.7-ajf-gc39503d #1 Not tainted + [ 9.099087] --------------------------------- + [ 9.103432] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. + [ 9.109431] scsi_eh_1/39 [HC1[1]:SC0[0]:HE0:SE1] takes: + [ 9.114642] (&(&host->lock)->rlock){?.+...}, at: [] sata_fsl_interrupt+0x50/0x250 + [ 9.123137] {HARDIRQ-ON-W} state was registered at: + [ 9.128004] [] lock_acquire+0x90/0xf4 + [ 9.132737] [] _raw_spin_lock+0x34/0x4c + [ 9.137645] [] fsl_sata_set_irq_coalescing+0x68/0x100 + [ 9.143750] [] sata_fsl_init_controller+0xa8/0xc0 + [ 9.149505] [] sata_fsl_probe+0x17c/0x2e8 + [ 9.154568] [] driver_probe_device+0x90/0x248 + [ 9.159987] [] __driver_attach+0xc4/0xc8 + [ 9.164964] [] bus_for_each_dev+0x5c/0xa8 + [ 9.170028] [] bus_add_driver+0x100/0x26c + [ 9.175091] [] driver_register+0x88/0x198 + [ 9.180155] [] do_one_initcall+0x58/0x1b4 + [ 9.185226] [] kernel_init_freeable+0x118/0x1c0 + [ 9.190823] [] kernel_init+0x18/0x108 + [ 9.195542] [] ret_from_kernel_thread+0x64/0x6c + [ 9.201142] irq event stamp: 160 + [ 9.204366] hardirqs last enabled at (159): [] _raw_spin_unlock_irq+0x30/0x50 + [ 9.212469] hardirqs last disabled at (160): [] reenable_mmu+0x30/0x88 + [ 9.219867] softirqs last enabled at (144): [] __do_softirq+0x168/0x218 + [ 9.227435] softirqs last disabled at (137): [] irq_exit+0xa8/0xb4 + [ 9.234481] + [ 9.234481] other info that might help us debug this: + [ 9.240995] Possible unsafe locking scenario: + [ 9.240995] + [ 9.246898] CPU0 + [ 9.249337] ---- + [ 9.251776] lock(&(&host->lock)->rlock); + [ 9.255878] + [ 9.258492] lock(&(&host->lock)->rlock); + [ 9.262765] + [ 9.262765] *** DEADLOCK *** + [ 9.262765] + [ 9.268684] no locks held by scsi_eh_1/39. + [ 9.272767] + [ 9.272767] stack backtrace: + [ 9.277117] Call Trace: + [ 9.279589] [cfff9da0] [c0008504] show_stack+0x48/0x150 (unreliable) + [ 9.285972] [cfff9de0] [c0447d5c] print_usage_bug.part.35+0x268/0x27c + [ 9.292425] [cfff9e10] [c006ace4] mark_lock+0x2ac/0x658 + [ 9.297660] [cfff9e40] [c006b7e4] __lock_acquire+0x754/0x1840 + [ 9.303414] [cfff9ee0] [c006cdb8] lock_acquire+0x90/0xf4 + [ 9.308745] [cfff9f20] [c043ef04] _raw_spin_lock+0x34/0x4c + [ 9.314250] [cfff9f30] [c02f4168] sata_fsl_interrupt+0x50/0x250 + [ 9.320187] [cfff9f70] [c0079ff0] handle_irq_event_percpu+0x90/0x254 + [ 9.326547] [cfff9fc0] [c007a1fc] handle_irq_event+0x48/0x78 + [ 9.332220] [cfff9fe0] [c007c95c] handle_level_irq+0x9c/0x104 + [ 9.337981] [cfff9ff0] [c000d978] call_handle_irq+0x18/0x28 + [ 9.343568] [cc7139f0] [c000608c] do_IRQ+0xf0/0x1a8 + [ 9.348464] [cc713a20] [c000fc8c] ret_from_except+0x0/0x14 + [ 9.353983] --- Exception: 501 at _raw_spin_unlock_irq+0x40/0x50 + [ 9.353983] LR = _raw_spin_unlock_irq+0x30/0x50 + [ 9.364839] [cc713af0] [c043db10] wait_for_common+0xac/0x188 + [ 9.370513] [cc713b30] [c02ddee4] ata_exec_internal_sg+0x2b0/0x4f0 + [ 9.376699] [cc713be0] [c02de18c] ata_exec_internal+0x68/0xa8 + [ 9.382454] [cc713c20] [c02de4b8] ata_dev_read_id+0x158/0x594 + [ 9.388205] [cc713ca0] [c02ec244] ata_eh_recover+0xd88/0x13d0 + [ 9.393962] [cc713d20] [c02f2520] sata_pmp_error_handler+0xc0/0x8ac + [ 9.400234] [cc713dd0] [c02ecdc8] ata_scsi_port_error_handler+0x464/0x5e8 + [ 9.407023] [cc713e10] [c02ecfd0] ata_scsi_error+0x84/0xb8 + [ 9.412528] [cc713e40] [c02c4974] scsi_error_handler+0xd8/0x47c + [ 9.418457] [cc713eb0] [c004737c] kthread+0xa8/0xac + [ 9.423355] [cc713f40] [c000f6b8] ret_from_kernel_thread+0x64/0x6c + +This fix was suggested by Bhushan Bharat , and +was discussed in email at: + + http://linuxppc.10917.n7.nabble.com/MPC8315-reboot-failure-lockdep-splat-possibly-related-tp75162.html + +Same patch successfully tested with 3.9.7. linux-next compiled but +not tested on hardware. + +This patch is based off linux-next tag next-20130819 +(which is commit 66a01bae29d11916c09f9f5a937cafe7d402e4a5 ) + +Signed-off-by: Anthony Foiani +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/sata_fsl.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/ata/sata_fsl.c ++++ b/drivers/ata/sata_fsl.c +@@ -293,6 +293,7 @@ static void fsl_sata_set_irq_coalescing( + { + struct sata_fsl_host_priv *host_priv = host->private_data; + void __iomem *hcr_base = host_priv->hcr_base; ++ unsigned long flags; + + if (count > ICC_MAX_INT_COUNT_THRESHOLD) + count = ICC_MAX_INT_COUNT_THRESHOLD; +@@ -305,12 +306,12 @@ static void fsl_sata_set_irq_coalescing( + (count > ICC_MIN_INT_COUNT_THRESHOLD)) + ticks = ICC_SAFE_INT_TICKS; + +- spin_lock(&host->lock); ++ spin_lock_irqsave(&host->lock, flags); + iowrite32((count << 24 | ticks), hcr_base + ICC); + + intr_coalescing_count = count; + intr_coalescing_ticks = ticks; +- spin_unlock(&host->lock); ++ spin_unlock_irqrestore(&host->lock, flags); + + DPRINTK("interrupt coalescing, count = 0x%x, ticks = %x\n", + intr_coalescing_count, intr_coalescing_ticks); diff --git a/queue-3.10/scsi-lpfc-don-t-force-config_generic_csum-on.patch b/queue-3.10/scsi-lpfc-don-t-force-config_generic_csum-on.patch new file mode 100644 index 00000000000..f496d80733d --- /dev/null +++ b/queue-3.10/scsi-lpfc-don-t-force-config_generic_csum-on.patch @@ -0,0 +1,41 @@ +From f5944daa0a72316077435c18a6571e73ed338332 Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Thu, 8 Aug 2013 17:47:34 +1000 +Subject: SCSI: lpfc: Don't force CONFIG_GENERIC_CSUM on + +From: Anton Blanchard + +commit f5944daa0a72316077435c18a6571e73ed338332 upstream. + +We want ppc64 to be able to select between optimised assembly +checksum routines in big endian and the generic lib/checksum.c +routines in little endian. + +The lpfc driver is forcing CONFIG_GENERIC_CSUM on which means +we are unable to make the decision to enable it in the arch +Kconfig. If the option exists it is always forced on. + +This got introduced in 3.10 via commit 6a7252fdb0c3 ([SCSI] lpfc: +fix up Kconfig dependencies). I spoke to Randy about it and +the original issue was with CRC_T10DIF not being defined. + +As such, remove the select of CONFIG_GENERIC_CSUM. + +Signed-off-by: Anton Blanchard +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/Kconfig | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/scsi/Kconfig ++++ b/drivers/scsi/Kconfig +@@ -1353,7 +1353,6 @@ config SCSI_LPFC + tristate "Emulex LightPulse Fibre Channel Support" + depends on PCI && SCSI + select SCSI_FC_ATTRS +- select GENERIC_CSUM + select CRC_T10DIF + help + This lpfc driver supports the Emulex LightPulse diff --git a/queue-3.10/scsi-sg-fix-user-memory-corruption-when-sg_io-is-interrupted-by-a-signal.patch b/queue-3.10/scsi-sg-fix-user-memory-corruption-when-sg_io-is-interrupted-by-a-signal.patch new file mode 100644 index 00000000000..a3c596aecf5 --- /dev/null +++ b/queue-3.10/scsi-sg-fix-user-memory-corruption-when-sg_io-is-interrupted-by-a-signal.patch @@ -0,0 +1,128 @@ +From 35dc248383bbab0a7203fca4d722875bc81ef091 Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Mon, 5 Aug 2013 17:55:01 -0700 +Subject: SCSI: sg: Fix user memory corruption when SG_IO is interrupted by a signal + +From: Roland Dreier + +commit 35dc248383bbab0a7203fca4d722875bc81ef091 upstream. + +There is a nasty bug in the SCSI SG_IO ioctl that in some circumstances +leads to one process writing data into the address space of some other +random unrelated process if the ioctl is interrupted by a signal. +What happens is the following: + + - A process issues an SG_IO ioctl with direction DXFER_FROM_DEV (ie the + underlying SCSI command will transfer data from the SCSI device to + the buffer provided in the ioctl) + + - Before the command finishes, a signal is sent to the process waiting + in the ioctl. This will end up waking up the sg_ioctl() code: + + result = wait_event_interruptible(sfp->read_wait, + (srp_done(sfp, srp) || sdp->detached)); + + but neither srp_done() nor sdp->detached is true, so we end up just + setting srp->orphan and returning to userspace: + + srp->orphan = 1; + write_unlock_irq(&sfp->rq_list_lock); + return result; /* -ERESTARTSYS because signal hit process */ + + At this point the original process is done with the ioctl and + blithely goes ahead handling the signal, reissuing the ioctl, etc. + + - Eventually, the SCSI command issued by the first ioctl finishes and + ends up in sg_rq_end_io(). At the end of that function, we run through: + + write_lock_irqsave(&sfp->rq_list_lock, iflags); + if (unlikely(srp->orphan)) { + if (sfp->keep_orphan) + srp->sg_io_owned = 0; + else + done = 0; + } + srp->done = done; + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + + if (likely(done)) { + /* Now wake up any sg_read() that is waiting for this + * packet. + */ + wake_up_interruptible(&sfp->read_wait); + kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN); + kref_put(&sfp->f_ref, sg_remove_sfp); + } else { + INIT_WORK(&srp->ew.work, sg_rq_end_io_usercontext); + schedule_work(&srp->ew.work); + } + + Since srp->orphan *is* set, we set done to 0 (assuming the + userspace app has not set keep_orphan via an SG_SET_KEEP_ORPHAN + ioctl), and therefore we end up scheduling sg_rq_end_io_usercontext() + to run in a workqueue. + + - In workqueue context we go through sg_rq_end_io_usercontext() -> + sg_finish_rem_req() -> blk_rq_unmap_user() -> ... -> + bio_uncopy_user() -> __bio_copy_iov() -> copy_to_user(). + + The key point here is that we are doing copy_to_user() on a + workqueue -- that is, we're on a kernel thread with current->mm + equal to whatever random previous user process was scheduled before + this kernel thread. So we end up copying whatever data the SCSI + command returned to the virtual address of the buffer passed into + the original ioctl, but it's quite likely we do this copying into a + different address space! + +As suggested by James Bottomley , +add a check for current->mm (which is NULL if we're on a kernel thread +without a real userspace address space) in bio_uncopy_user(), and skip +the copy if we're on a kernel thread. + +There's no reason that I can think of for any caller of bio_uncopy_user() +to want to do copying on a kernel thread with a random active userspace +address space. + +Huge thanks to Costa Sapuntzakis for the +original pointer to this bug in the sg code. + +Signed-off-by: Roland Dreier +Tested-by: David Milburn +Cc: Jens Axboe +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + fs/bio.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +--- a/fs/bio.c ++++ b/fs/bio.c +@@ -1045,12 +1045,22 @@ static int __bio_copy_iov(struct bio *bi + int bio_uncopy_user(struct bio *bio) + { + struct bio_map_data *bmd = bio->bi_private; +- int ret = 0; ++ struct bio_vec *bvec; ++ int ret = 0, i; + +- if (!bio_flagged(bio, BIO_NULL_MAPPED)) +- ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs, +- bmd->nr_sgvecs, bio_data_dir(bio) == READ, +- 0, bmd->is_our_pages); ++ if (!bio_flagged(bio, BIO_NULL_MAPPED)) { ++ /* ++ * if we're in a workqueue, the request is orphaned, so ++ * don't copy into a random user address space, just free. ++ */ ++ if (current->mm) ++ ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs, ++ bmd->nr_sgvecs, bio_data_dir(bio) == READ, ++ 0, bmd->is_our_pages); ++ else if (bmd->is_our_pages) ++ bio_for_each_segment_all(bvec, bio, i) ++ __free_page(bvec->bv_page); ++ } + bio_free_map_data(bmd); + bio_put(bio); + return ret; diff --git a/queue-3.10/scsi-zfcp-fix-lock-imbalance-by-reworking-request-queue-locking.patch b/queue-3.10/scsi-zfcp-fix-lock-imbalance-by-reworking-request-queue-locking.patch new file mode 100644 index 00000000000..aebab528cb1 --- /dev/null +++ b/queue-3.10/scsi-zfcp-fix-lock-imbalance-by-reworking-request-queue-locking.patch @@ -0,0 +1,158 @@ +From d79ff142624e1be080ad8d09101f7004d79c36e1 Mon Sep 17 00:00:00 2001 +From: Martin Peschke +Date: Thu, 22 Aug 2013 17:45:36 +0200 +Subject: SCSI: zfcp: fix lock imbalance by reworking request queue locking + +From: Martin Peschke + +commit d79ff142624e1be080ad8d09101f7004d79c36e1 upstream. + +This patch adds wait_event_interruptible_lock_irq_timeout(), which is a +straight-forward descendant of wait_event_interruptible_timeout() and +wait_event_interruptible_lock_irq(). + +The zfcp driver used to call wait_event_interruptible_timeout() +in combination with some intricate and error-prone locking. Using +wait_event_interruptible_lock_irq_timeout() as a replacement +nicely cleans up that locking. + +This rework removes a situation that resulted in a locking imbalance +in zfcp_qdio_sbal_get(): + +BUG: workqueue leaked lock or atomic: events/1/0xffffff00/10 + last function: zfcp_fc_wka_port_offline+0x0/0xa0 [zfcp] + +It was introduced by commit c2af7545aaff3495d9bf9a7608c52f0af86fb194 +"[SCSI] zfcp: Do not wait for SBALs on stopped queue", which had a new +code path related to ZFCP_STATUS_ADAPTER_QDIOUP that took an early exit +without a required lock being held. The problem occured when a +special, non-SCSI I/O request was being submitted in process context, +when the adapter's queues had been torn down. In this case the bug +surfaced when the Fibre Channel port connection for a well-known address +was closed during a concurrent adapter shut-down procedure, which is a +rare constellation. + +This patch also fixes these warnings from the sparse tool (make C=1): + +drivers/s390/scsi/zfcp_qdio.c:224:12: warning: context imbalance in + 'zfcp_qdio_sbal_check' - wrong count at exit +drivers/s390/scsi/zfcp_qdio.c:244:5: warning: context imbalance in + 'zfcp_qdio_sbal_get' - unexpected unlock + +Last but not least, we get rid of that crappy lock-unlock-lock +sequence at the beginning of the critical section. + +It is okay to call zfcp_erp_adapter_reopen() with req_q_lock held. + +Reported-by: Mikulas Patocka +Reported-by: Heiko Carstens +Signed-off-by: Martin Peschke +Signed-off-by: Steffen Maier +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/s390/scsi/zfcp_qdio.c | 8 +---- + include/linux/wait.h | 57 ++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 59 insertions(+), 6 deletions(-) + +--- a/drivers/s390/scsi/zfcp_qdio.c ++++ b/drivers/s390/scsi/zfcp_qdio.c +@@ -224,11 +224,9 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_ + + static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio) + { +- spin_lock_irq(&qdio->req_q_lock); + if (atomic_read(&qdio->req_q_free) || + !(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) + return 1; +- spin_unlock_irq(&qdio->req_q_lock); + return 0; + } + +@@ -246,9 +244,8 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio + { + long ret; + +- spin_unlock_irq(&qdio->req_q_lock); +- ret = wait_event_interruptible_timeout(qdio->req_q_wq, +- zfcp_qdio_sbal_check(qdio), 5 * HZ); ++ ret = wait_event_interruptible_lock_irq_timeout(qdio->req_q_wq, ++ zfcp_qdio_sbal_check(qdio), qdio->req_q_lock, 5 * HZ); + + if (!(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) + return -EIO; +@@ -262,7 +259,6 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio + zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1"); + } + +- spin_lock_irq(&qdio->req_q_lock); + return -EIO; + } + +--- a/include/linux/wait.h ++++ b/include/linux/wait.h +@@ -805,6 +805,63 @@ do { \ + __ret; \ + }) + ++#define __wait_event_interruptible_lock_irq_timeout(wq, condition, \ ++ lock, ret) \ ++do { \ ++ DEFINE_WAIT(__wait); \ ++ \ ++ for (;;) { \ ++ prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); \ ++ if (condition) \ ++ break; \ ++ if (signal_pending(current)) { \ ++ ret = -ERESTARTSYS; \ ++ break; \ ++ } \ ++ spin_unlock_irq(&lock); \ ++ ret = schedule_timeout(ret); \ ++ spin_lock_irq(&lock); \ ++ if (!ret) \ ++ break; \ ++ } \ ++ finish_wait(&wq, &__wait); \ ++} while (0) ++ ++/** ++ * wait_event_interruptible_lock_irq_timeout - sleep until a condition gets true or a timeout elapses. ++ * The condition is checked under the lock. This is expected ++ * to be called with the lock taken. ++ * @wq: the waitqueue to wait on ++ * @condition: a C expression for the event to wait for ++ * @lock: a locked spinlock_t, which will be released before schedule() ++ * and reacquired afterwards. ++ * @timeout: timeout, in jiffies ++ * ++ * The process is put to sleep (TASK_INTERRUPTIBLE) until the ++ * @condition evaluates to true or signal is received. The @condition is ++ * checked each time the waitqueue @wq is woken up. ++ * ++ * wake_up() has to be called after changing any variable that could ++ * change the result of the wait condition. ++ * ++ * This is supposed to be called while holding the lock. The lock is ++ * dropped before going to sleep and is reacquired afterwards. ++ * ++ * The function returns 0 if the @timeout elapsed, -ERESTARTSYS if it ++ * was interrupted by a signal, and the remaining jiffies otherwise ++ * if the condition evaluated to true before the timeout elapsed. ++ */ ++#define wait_event_interruptible_lock_irq_timeout(wq, condition, lock, \ ++ timeout) \ ++({ \ ++ int __ret = timeout; \ ++ \ ++ if (!(condition)) \ ++ __wait_event_interruptible_lock_irq_timeout( \ ++ wq, condition, lock, __ret); \ ++ __ret; \ ++}) ++ + + /* + * These are the old interfaces to sleep waiting for an event. diff --git a/queue-3.10/series b/queue-3.10/series index bf5b3420ace..f94c481b475 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -55,3 +55,18 @@ nilfs2-remove-double-bio_put-in-nilfs_end_bio_write-for-bio_eopnotsupp-error.pat nilfs2-fix-issue-with-counting-number-of-bio-requests-for-bio_eopnotsupp-error-detection.patch drivers-platform-olpc-olpc-ec.c-initialise-earlier.patch usb-phy-fix-build-breakage.patch +sata_fsl-save-irqs-while-coalescing.patch +hostap-copying-wrong-data-prism2_ioctl_giwaplist.patch +libata-apply-behavioral-quirks-to-sil3826-pmp.patch +iwlwifi-dvm-fix-calling-ieee80211_chswitch_done-with-null.patch +iwlwifi-pcie-disable-l1-active-after-pci_enable_device.patch +scsi-zfcp-fix-lock-imbalance-by-reworking-request-queue-locking.patch +zfcp-fix-schedule-inside-lock-in-scsi_device-list-loops.patch +scsi-lpfc-don-t-force-config_generic_csum-on.patch +scsi-sg-fix-user-memory-corruption-when-sg_io-is-interrupted-by-a-signal.patch +revert-x86-get_unmapped_area-use-proper-mmap-base-for-bottom-up-direction.patch +x86-get_unmapped_area-access-mmap_legacy_base-through-mm_struct-member.patch +x86-xen-do-not-identity-map-unusable-regions-in-the-machine-e820.patch +mei-me-fix-reset-state-machine.patch +mei-don-t-have-to-clean-the-state-on-power-up.patch +mei-me-fix-waiting-for-hw-ready.patch diff --git a/queue-3.10/x86-get_unmapped_area-access-mmap_legacy_base-through-mm_struct-member.patch b/queue-3.10/x86-get_unmapped_area-access-mmap_legacy_base-through-mm_struct-member.patch new file mode 100644 index 00000000000..845a0ff5cd9 --- /dev/null +++ b/queue-3.10/x86-get_unmapped_area-access-mmap_legacy_base-through-mm_struct-member.patch @@ -0,0 +1,71 @@ +From 41aacc1eea645c99edbe8fbcf78a97dc9b862adc Mon Sep 17 00:00:00 2001 +From: Radu Caragea +Date: Wed, 21 Aug 2013 20:55:59 +0300 +Subject: x86 get_unmapped_area: Access mmap_legacy_base through mm_struct member + +From: Radu Caragea + +commit 41aacc1eea645c99edbe8fbcf78a97dc9b862adc upstream. + +This is the updated version of df54d6fa5427 ("x86 get_unmapped_area(): +use proper mmap base for bottom-up direction") that only randomizes the +mmap base address once. + +Signed-off-by: Radu Caragea +Reported-and-tested-by: Jeff Shorey +Cc: Andrew Morton +Cc: Michel Lespinasse +Cc: Oleg Nesterov +Cc: Rik van Riel +Cc: Ingo Molnar +Cc: Adrian Sendroiu +Cc: Kamal Mostafa +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/sys_x86_64.c | 2 +- + arch/x86/mm/mmap.c | 6 ++++-- + include/linux/mm_types.h | 1 + + 3 files changed, 6 insertions(+), 3 deletions(-) + +--- a/arch/x86/kernel/sys_x86_64.c ++++ b/arch/x86/kernel/sys_x86_64.c +@@ -101,7 +101,7 @@ static void find_start_end(unsigned long + *begin = new_begin; + } + } else { +- *begin = TASK_UNMAPPED_BASE; ++ *begin = current->mm->mmap_legacy_base; + *end = TASK_SIZE; + } + } +--- a/arch/x86/mm/mmap.c ++++ b/arch/x86/mm/mmap.c +@@ -112,12 +112,14 @@ static unsigned long mmap_legacy_base(vo + */ + void arch_pick_mmap_layout(struct mm_struct *mm) + { ++ mm->mmap_legacy_base = mmap_legacy_base(); ++ mm->mmap_base = mmap_base(); ++ + if (mmap_is_legacy()) { +- mm->mmap_base = mmap_legacy_base(); ++ mm->mmap_base = mm->mmap_legacy_base; + mm->get_unmapped_area = arch_get_unmapped_area; + mm->unmap_area = arch_unmap_area; + } else { +- mm->mmap_base = mmap_base(); + mm->get_unmapped_area = arch_get_unmapped_area_topdown; + mm->unmap_area = arch_unmap_area_topdown; + } +--- a/include/linux/mm_types.h ++++ b/include/linux/mm_types.h +@@ -333,6 +333,7 @@ struct mm_struct { + void (*unmap_area) (struct mm_struct *mm, unsigned long addr); + #endif + unsigned long mmap_base; /* base of mmap area */ ++ unsigned long mmap_legacy_base; /* base of mmap area in bottom-up allocations */ + unsigned long task_size; /* size of task vm space */ + unsigned long cached_hole_size; /* if non-zero, the largest hole below free_area_cache */ + unsigned long free_area_cache; /* first hole of size cached_hole_size or larger */ diff --git a/queue-3.10/x86-xen-do-not-identity-map-unusable-regions-in-the-machine-e820.patch b/queue-3.10/x86-xen-do-not-identity-map-unusable-regions-in-the-machine-e820.patch new file mode 100644 index 00000000000..809c4e7a7f9 --- /dev/null +++ b/queue-3.10/x86-xen-do-not-identity-map-unusable-regions-in-the-machine-e820.patch @@ -0,0 +1,90 @@ +From 3bc38cbceb85881a8eb789ee1aa56678038b1909 Mon Sep 17 00:00:00 2001 +From: David Vrabel +Date: Fri, 16 Aug 2013 15:42:55 +0100 +Subject: x86/xen: do not identity map UNUSABLE regions in the machine E820 + +From: David Vrabel + +commit 3bc38cbceb85881a8eb789ee1aa56678038b1909 upstream. + +If there are UNUSABLE regions in the machine memory map, dom0 will +attempt to map them 1:1 which is not permitted by Xen and the kernel +will crash. + +There isn't anything interesting in the UNUSABLE region that the dom0 +kernel needs access to so we can avoid making the 1:1 mapping and +treat it as RAM. + +We only do this for dom0, as that is where tboot case shows up. +A PV domU could have an UNUSABLE region in its pseudo-physical map +and would need to be handled in another patch. + +This fixes a boot failure on hosts with tboot. + +tboot marks a region in the e820 map as unusable and the dom0 kernel +would attempt to map this region and Xen does not permit unusable +regions to be mapped by guests. + + (XEN) 0000000000000000 - 0000000000060000 (usable) + (XEN) 0000000000060000 - 0000000000068000 (reserved) + (XEN) 0000000000068000 - 000000000009e000 (usable) + (XEN) 0000000000100000 - 0000000000800000 (usable) + (XEN) 0000000000800000 - 0000000000972000 (unusable) + +tboot marked this region as unusable. + + (XEN) 0000000000972000 - 00000000cf200000 (usable) + (XEN) 00000000cf200000 - 00000000cf38f000 (reserved) + (XEN) 00000000cf38f000 - 00000000cf3ce000 (ACPI data) + (XEN) 00000000cf3ce000 - 00000000d0000000 (reserved) + (XEN) 00000000e0000000 - 00000000f0000000 (reserved) + (XEN) 00000000fe000000 - 0000000100000000 (reserved) + (XEN) 0000000100000000 - 0000000630000000 (usable) + +Signed-off-by: David Vrabel +[v1: Altered the patch and description with domU's with UNUSABLE regions] +Signed-off-by: Konrad Rzeszutek Wilk +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/xen/setup.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/arch/x86/xen/setup.c ++++ b/arch/x86/xen/setup.c +@@ -313,6 +313,17 @@ static void xen_align_and_add_e820_regio + e820_add_region(start, end - start, type); + } + ++void xen_ignore_unusable(struct e820entry *list, size_t map_size) ++{ ++ struct e820entry *entry; ++ unsigned int i; ++ ++ for (i = 0, entry = list; i < map_size; i++, entry++) { ++ if (entry->type == E820_UNUSABLE) ++ entry->type = E820_RAM; ++ } ++} ++ + /** + * machine_specific_memory_setup - Hook for machine specific memory setup. + **/ +@@ -353,6 +364,17 @@ char * __init xen_memory_setup(void) + } + BUG_ON(rc); + ++ /* ++ * Xen won't allow a 1:1 mapping to be created to UNUSABLE ++ * regions, so if we're using the machine memory map leave the ++ * region as RAM as it is in the pseudo-physical map. ++ * ++ * UNUSABLE regions in domUs are not handled and will need ++ * a patch in the future. ++ */ ++ if (xen_initial_domain()) ++ xen_ignore_unusable(map, memmap.nr_entries); ++ + /* Make sure the Xen-supplied memory map is well-ordered. */ + sanitize_e820_map(map, memmap.nr_entries, &memmap.nr_entries); + diff --git a/queue-3.10/zfcp-fix-schedule-inside-lock-in-scsi_device-list-loops.patch b/queue-3.10/zfcp-fix-schedule-inside-lock-in-scsi_device-list-loops.patch new file mode 100644 index 00000000000..4abbbab5de1 --- /dev/null +++ b/queue-3.10/zfcp-fix-schedule-inside-lock-in-scsi_device-list-loops.patch @@ -0,0 +1,170 @@ +From 924dd584b198a58aa7cb3efefd8a03326550ce8f Mon Sep 17 00:00:00 2001 +From: Martin Peschke +Date: Thu, 22 Aug 2013 17:45:37 +0200 +Subject: SCSI: zfcp: fix schedule-inside-lock in scsi_device list loops + +From: Martin Peschke + +commit 924dd584b198a58aa7cb3efefd8a03326550ce8f upstream. + +BUG: sleeping function called from invalid context at kernel/workqueue.c:2752 +in_atomic(): 1, irqs_disabled(): 1, pid: 360, name: zfcperp0.0.1700 +CPU: 1 Not tainted 3.9.3+ #69 +Process zfcperp0.0.1700 (pid: 360, task: 0000000075b7e080, ksp: 000000007476bc30) + +Call Trace: +([<00000000001165de>] show_trace+0x106/0x154) + [<00000000001166a0>] show_stack+0x74/0xf4 + [<00000000006ff646>] dump_stack+0xc6/0xd4 + [<000000000017f3a0>] __might_sleep+0x128/0x148 + [<000000000015ece8>] flush_work+0x54/0x1f8 + [<00000000001630de>] __cancel_work_timer+0xc6/0x128 + [<00000000005067ac>] scsi_device_dev_release_usercontext+0x164/0x23c + [<0000000000161816>] execute_in_process_context+0x96/0xa8 + [<00000000004d33d8>] device_release+0x60/0xc0 + [<000000000048af48>] kobject_release+0xa8/0x1c4 + [<00000000004f4bf2>] __scsi_iterate_devices+0xfa/0x130 + [<000003ff801b307a>] zfcp_erp_strategy+0x4da/0x1014 [zfcp] + [<000003ff801b3caa>] zfcp_erp_thread+0xf6/0x2b0 [zfcp] + [<000000000016b75a>] kthread+0xf2/0xfc + [<000000000070c9de>] kernel_thread_starter+0x6/0xc + [<000000000070c9d8>] kernel_thread_starter+0x0/0xc + +Apparently, the ref_count for some scsi_device drops down to zero, +triggering device removal through execute_in_process_context(), while +the lldd error recovery thread iterates through a scsi device list. +Unfortunately, execute_in_process_context() decides to immediately +execute that device removal function, instead of scheduling asynchronous +execution, since it detects process context and thinks it is safe to do +so. But almost all calls to shost_for_each_device() in our lldd are +inside spin_lock_irq, even in thread context. Obviously, schedule() +inside spin_lock_irq sections is a bad idea. + +Change the lldd to use the proper iterator function, +__shost_for_each_device(), in combination with required locking. + +Occurences that need to be changed include all calls in zfcp_erp.c, +since those might be executed in zfcp error recovery thread context +with a lock held. + +Other occurences of shost_for_each_device() in zfcp_fsf.c do not +need to be changed (no process context, no surrounding locking). + +The problem was introduced in Linux 2.6.37 by commit +b62a8d9b45b971a67a0f8413338c230e3117dff5 +"[SCSI] zfcp: Use SCSI device data zfcp_scsi_dev instead of zfcp_unit". + +Reported-by: Christian Borntraeger +Signed-off-by: Martin Peschke +Signed-off-by: Steffen Maier +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/s390/scsi/zfcp_erp.c | 29 ++++++++++++++++++++++------- + 1 file changed, 22 insertions(+), 7 deletions(-) + +--- a/drivers/s390/scsi/zfcp_erp.c ++++ b/drivers/s390/scsi/zfcp_erp.c +@@ -102,10 +102,13 @@ static void zfcp_erp_action_dismiss_port + + if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_INUSE) + zfcp_erp_action_dismiss(&port->erp_action); +- else +- shost_for_each_device(sdev, port->adapter->scsi_host) ++ else { ++ spin_lock(port->adapter->scsi_host->host_lock); ++ __shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) + zfcp_erp_action_dismiss_lun(sdev); ++ spin_unlock(port->adapter->scsi_host->host_lock); ++ } + } + + static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) +@@ -592,9 +595,11 @@ static void _zfcp_erp_lun_reopen_all(str + { + struct scsi_device *sdev; + +- shost_for_each_device(sdev, port->adapter->scsi_host) ++ spin_lock(port->adapter->scsi_host->host_lock); ++ __shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) + _zfcp_erp_lun_reopen(sdev, clear, id, 0); ++ spin_unlock(port->adapter->scsi_host->host_lock); + } + + static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act) +@@ -1435,8 +1440,10 @@ void zfcp_erp_set_adapter_status(struct + atomic_set_mask(common_mask, &port->status); + read_unlock_irqrestore(&adapter->port_list_lock, flags); + +- shost_for_each_device(sdev, adapter->scsi_host) ++ spin_lock_irqsave(adapter->scsi_host->host_lock, flags); ++ __shost_for_each_device(sdev, adapter->scsi_host) + atomic_set_mask(common_mask, &sdev_to_zfcp(sdev)->status); ++ spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags); + } + + /** +@@ -1470,11 +1477,13 @@ void zfcp_erp_clear_adapter_status(struc + } + read_unlock_irqrestore(&adapter->port_list_lock, flags); + +- shost_for_each_device(sdev, adapter->scsi_host) { ++ spin_lock_irqsave(adapter->scsi_host->host_lock, flags); ++ __shost_for_each_device(sdev, adapter->scsi_host) { + atomic_clear_mask(common_mask, &sdev_to_zfcp(sdev)->status); + if (clear_counter) + atomic_set(&sdev_to_zfcp(sdev)->erp_counter, 0); + } ++ spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags); + } + + /** +@@ -1488,16 +1497,19 @@ void zfcp_erp_set_port_status(struct zfc + { + struct scsi_device *sdev; + u32 common_mask = mask & ZFCP_COMMON_FLAGS; ++ unsigned long flags; + + atomic_set_mask(mask, &port->status); + + if (!common_mask) + return; + +- shost_for_each_device(sdev, port->adapter->scsi_host) ++ spin_lock_irqsave(port->adapter->scsi_host->host_lock, flags); ++ __shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) + atomic_set_mask(common_mask, + &sdev_to_zfcp(sdev)->status); ++ spin_unlock_irqrestore(port->adapter->scsi_host->host_lock, flags); + } + + /** +@@ -1512,6 +1524,7 @@ void zfcp_erp_clear_port_status(struct z + struct scsi_device *sdev; + u32 common_mask = mask & ZFCP_COMMON_FLAGS; + u32 clear_counter = mask & ZFCP_STATUS_COMMON_ERP_FAILED; ++ unsigned long flags; + + atomic_clear_mask(mask, &port->status); + +@@ -1521,13 +1534,15 @@ void zfcp_erp_clear_port_status(struct z + if (clear_counter) + atomic_set(&port->erp_counter, 0); + +- shost_for_each_device(sdev, port->adapter->scsi_host) ++ spin_lock_irqsave(port->adapter->scsi_host->host_lock, flags); ++ __shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) { + atomic_clear_mask(common_mask, + &sdev_to_zfcp(sdev)->status); + if (clear_counter) + atomic_set(&sdev_to_zfcp(sdev)->erp_counter, 0); + } ++ spin_unlock_irqrestore(port->adapter->scsi_host->host_lock, flags); + } + + /**