Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PATCH 4.4 011/192] [PATCH 011/135] igb: dont unmap NULL hw_addr

161 views
Skip to first unread message

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:06 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 73bf8048d7c86a20a59d427e55deb1a778e94df7 ]

I've got a startech thunderbolt dock someone loaned me, which among other
things, has the following device in it:

08:00.0 Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev 03)

This hotplugs just fine (kernel 4.2.0 plus a patch or two here):

[ 863.020315] igb: Intel(R) Gigabit Ethernet Network Driver - version 5.2.18-k
[ 863.020316] igb: Copyright (c) 2007-2014 Intel Corporation.
[ 863.028657] igb 0000:08:00.0: enabling device (0000 -> 0002)
[ 863.062089] igb 0000:08:00.0: added PHC on eth0
[ 863.062090] igb 0000:08:00.0: Intel(R) Gigabit Ethernet Network Connection
[ 863.062091] igb 0000:08:00.0: eth0: (PCIe:2.5Gb/s:Width x1) e8:ea:6a:00:1b:2a
[ 863.062194] igb 0000:08:00.0: eth0: PBA No: 000200-000
[ 863.062196] igb 0000:08:00.0: Using MSI-X interrupts. 4 rx queue(s), 4 tx queue(s)
[ 863.064889] igb 0000:08:00.0 enp8s0: renamed from eth0

But disconnecting it is another story:

[ 1002.807932] igb 0000:08:00.0: removed PHC on enp8s0
[ 1002.807944] igb 0000:08:00.0 enp8s0: PCIe link lost, device now detached
[ 1003.341141] ------------[ cut here ]------------
[ 1003.341148] WARNING: CPU: 0 PID: 199 at lib/iomap.c:43 bad_io_access+0x38/0x40()
[ 1003.341149] Bad IO access at port 0x0 ()
[ 1003.342767] Modules linked in: snd_usb_audio snd_usbmidi_lib snd_rawmidi igb dca firewire_ohci firewire_core crc_itu_t rfcomm ctr ccm arc4 iwlmvm mac80211 fuse xt_CHECKSUM ipt_MASQUERADE
nf_nat_masquerade_ipv4 tun ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_conntrack ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat
nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat
nf_conntrack iptable_mangle iptable_security iptable_raw iptable_filter bnep dm_mirror dm_region_hash dm_log dm_mod coretemp x86_pkg_temp_thermal intel_powerclamp kvm_intel snd_hda_codec_hdmi kvm
crct10dif_pclmul crc32_pclmul ghash_clmulni_intel drbg
[ 1003.342793] ansi_cprng aesni_intel hp_wmi aes_x86_64 iTCO_wdt lrw iTCO_vendor_support ppdev gf128mul sparse_keymap glue_helper ablk_helper cryptd snd_hda_codec_realtek snd_hda_codec_generic
microcode snd_hda_intel uvcvideo iwlwifi snd_hda_codec videobuf2_vmalloc videobuf2_memops snd_hda_core videobuf2_core snd_hwdep btusb v4l2_common btrtl snd_seq btbcm btintel videodev cfg80211
snd_seq_device rtsx_pci_ms bluetooth pcspkr input_leds i2c_i801 media parport_pc memstick rfkill sg lpc_ich snd_pcm 8250_fintek parport joydev snd_timer snd soundcore hp_accel ie31200_edac
mei_me lis3lv02d edac_core input_polldev mei hp_wireless shpchp tpm_infineon sch_fq_codel nfsd auth_rpcgss nfs_acl lockd grace sunrpc ip_tables autofs4 xfs libcrc32c sd_mod sr_mod cdrom
rtsx_pci_sdmmc mmc_core crc32c_intel serio_raw rtsx_pci
[ 1003.342822] nouveau ahci libahci mxm_wmi e1000e xhci_pci hwmon ptp drm_kms_helper pps_core xhci_hcd ttm wmi video ipv6
[ 1003.342839] CPU: 0 PID: 199 Comm: kworker/0:2 Not tainted 4.2.0-2.el7_UNSUPPORTED.x86_64 #1
[ 1003.342840] Hardware name: Hewlett-Packard HP ZBook 15 G2/2253, BIOS M70 Ver. 01.07 02/26/2015
[ 1003.342843] Workqueue: pciehp-3 pciehp_power_thread
[ 1003.342844] ffffffff81a90655 ffff8804866d3b48 ffffffff8164763a 0000000000000000
[ 1003.342846] ffff8804866d3b98 ffff8804866d3b88 ffffffff8107134a ffff8804866d3b88
[ 1003.342847] ffff880486f46000 ffff88046c8a8000 ffff880486f46840 ffff88046c8a8098
[ 1003.342848] Call Trace:
[ 1003.342852] [<ffffffff8164763a>] dump_stack+0x45/0x57
[ 1003.342855] [<ffffffff8107134a>] warn_slowpath_common+0x8a/0xc0
[ 1003.342857] [<ffffffff810713c6>] warn_slowpath_fmt+0x46/0x50
[ 1003.342859] [<ffffffff8133719e>] ? pci_disable_msix+0x3e/0x50
[ 1003.342860] [<ffffffff812f6328>] bad_io_access+0x38/0x40
[ 1003.342861] [<ffffffff812f6567>] pci_iounmap+0x27/0x40
[ 1003.342865] [<ffffffffa0b728d7>] igb_remove+0xc7/0x160 [igb]
[ 1003.342867] [<ffffffff8132189f>] pci_device_remove+0x3f/0xc0
[ 1003.342869] [<ffffffff81433426>] __device_release_driver+0x96/0x130
[ 1003.342870] [<ffffffff814334e3>] device_release_driver+0x23/0x30
[ 1003.342871] [<ffffffff8131b404>] pci_stop_bus_device+0x94/0xa0
[ 1003.342872] [<ffffffff8131b3ad>] pci_stop_bus_device+0x3d/0xa0
[ 1003.342873] [<ffffffff8131b3ad>] pci_stop_bus_device+0x3d/0xa0
[ 1003.342874] [<ffffffff8131b516>] pci_stop_and_remove_bus_device+0x16/0x30
[ 1003.342876] [<ffffffff81333f5b>] pciehp_unconfigure_device+0x9b/0x180
[ 1003.342877] [<ffffffff81333a73>] pciehp_disable_slot+0x43/0xb0
[ 1003.342878] [<ffffffff81333b6d>] pciehp_power_thread+0x8d/0xb0
[ 1003.342885] [<ffffffff810881b2>] process_one_work+0x152/0x3d0
[ 1003.342886] [<ffffffff8108854a>] worker_thread+0x11a/0x460
[ 1003.342887] [<ffffffff81088430>] ? process_one_work+0x3d0/0x3d0
[ 1003.342890] [<ffffffff8108ddd9>] kthread+0xc9/0xe0
[ 1003.342891] [<ffffffff8108dd10>] ? kthread_create_on_node+0x180/0x180
[ 1003.342893] [<ffffffff8164e29f>] ret_from_fork+0x3f/0x70
[ 1003.342894] [<ffffffff8108dd10>] ? kthread_create_on_node+0x180/0x180
[ 1003.342895] ---[ end trace 65a77e06d5aa9358 ]---

Upon looking at the igb driver, I see that igb_rd32() attempted to read from
hw_addr and failed, so it set hw->hw_addr to NULL and spit out the message
in the log output above, "PCIe link lost, device now detached".

Well, now that hw_addr is NULL, the attempt to call pci_iounmap is obviously
not going to go well. As suggested by Mark Rustad, do something similar to
what ixgbe does, and save a copy of hw_addr as adapter->io_addr, so we can
still call pci_iounmap on it on teardown. Additionally, for consistency,
make the pci_iomap call assignment directly to io_addr, so map and unmap
match.

Signed-off-by: Jarod Wilson <ja...@redhat.com>
Tested-by: Aaron Brown <aaron....@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey....@intel.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/net/ethernet/intel/igb/igb.h | 2 ++
drivers/net/ethernet/intel/igb/igb_main.c | 10 ++++++----
2 files changed, 8 insertions(+), 4 deletions(-)

--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -389,6 +389,8 @@ struct igb_adapter {
u16 link_speed;
u16 link_duplex;

+ u8 __iomem *io_addr; /* Mainly for iounmap use */
+
struct work_struct reset_task;
struct work_struct watchdog_task;
bool fc_autoneg;
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -2294,9 +2294,11 @@ static int igb_probe(struct pci_dev *pde
adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);

err = -EIO;
- hw->hw_addr = pci_iomap(pdev, 0, 0);
- if (!hw->hw_addr)
+ adapter->io_addr = pci_iomap(pdev, 0, 0);
+ if (!adapter->io_addr)
goto err_ioremap;
+ /* hw->hw_addr can be altered, we'll use adapter->io_addr for unmap */
+ hw->hw_addr = adapter->io_addr;

netdev->netdev_ops = &igb_netdev_ops;
igb_set_ethtool_ops(netdev);
@@ -2656,7 +2658,7 @@ err_sw_init:
#ifdef CONFIG_PCI_IOV
igb_disable_sriov(pdev);
#endif
- pci_iounmap(pdev, hw->hw_addr);
+ pci_iounmap(pdev, adapter->io_addr);
err_ioremap:
free_netdev(netdev);
err_alloc_etherdev:
@@ -2823,7 +2825,7 @@ static void igb_remove(struct pci_dev *p

igb_clear_interrupt_scheme(adapter);

- pci_iounmap(pdev, hw->hw_addr);
+ pci_iounmap(pdev, adapter->io_addr);
if (hw->flash_address)
iounmap(hw->flash_address);
pci_release_selected_regions(pdev,

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:06 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit a42e7a369ea2b73a554a85dea7d6243af51cd4f0 ]

This patch fixes the memory leak which would be seen otherwise when user
programs flow-director filter using ethtool (sideband filter programming).

When ethtool is used to program flow directory filter, 'raw_buf' gets
allocated and it is supposed to be freed as part of queue cleanup. But
check of 'tx_buffer->skb' was preventing it from being freed.

Change-ID: Ief4f0a1a32a653180498bf6e987c1b4342ab8923
Signed-off-by: Kiran Patil <kiran...@intel.com>
Tested-by: Andrew Bowers <andrewx...@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey....@intel.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/net/ethernet/intel/i40e/i40e_txrx.c | 19 ++++++++++++++-----
drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 10 +++++-----
2 files changed, 19 insertions(+), 10 deletions(-)

--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -235,6 +235,9 @@ static int i40e_add_del_fdir_udpv4(struc
"Filter deleted for PCTYPE %d loc = %d\n",
fd_data->pctype, fd_data->fd_id);
}
+ if (err)
+ kfree(raw_packet);
+
return err ? -EOPNOTSUPP : 0;
}

@@ -312,6 +315,9 @@ static int i40e_add_del_fdir_tcpv4(struc
fd_data->pctype, fd_data->fd_id);
}

+ if (err)
+ kfree(raw_packet);
+
return err ? -EOPNOTSUPP : 0;
}

@@ -387,6 +393,9 @@ static int i40e_add_del_fdir_ipv4(struct
}
}

+ if (err)
+ kfree(raw_packet);
+
return err ? -EOPNOTSUPP : 0;
}

@@ -526,11 +535,7 @@ static void i40e_unmap_and_free_tx_resou
struct i40e_tx_buffer *tx_buffer)
{
if (tx_buffer->skb) {
- if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
- kfree(tx_buffer->raw_buf);
- else
- dev_kfree_skb_any(tx_buffer->skb);
-
+ dev_kfree_skb_any(tx_buffer->skb);
if (dma_unmap_len(tx_buffer, len))
dma_unmap_single(ring->dev,
dma_unmap_addr(tx_buffer, dma),
@@ -542,6 +547,10 @@ static void i40e_unmap_and_free_tx_resou
dma_unmap_len(tx_buffer, len),
DMA_TO_DEVICE);
}
+
+ if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
+ kfree(tx_buffer->raw_buf);
+
tx_buffer->next_to_watch = NULL;
tx_buffer->skb = NULL;
dma_unmap_len_set(tx_buffer, len, 0);
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
@@ -51,11 +51,7 @@ static void i40e_unmap_and_free_tx_resou
struct i40e_tx_buffer *tx_buffer)
{
if (tx_buffer->skb) {
- if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
- kfree(tx_buffer->raw_buf);
- else
- dev_kfree_skb_any(tx_buffer->skb);
-
+ dev_kfree_skb_any(tx_buffer->skb);
if (dma_unmap_len(tx_buffer, len))
dma_unmap_single(ring->dev,
dma_unmap_addr(tx_buffer, dma),
@@ -67,6 +63,10 @@ static void i40e_unmap_and_free_tx_resou
dma_unmap_len(tx_buffer, len),
DMA_TO_DEVICE);
}
+
+ if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
+ kfree(tx_buffer->raw_buf);
+
tx_buffer->next_to_watch = NULL;
tx_buffer->skb = NULL;
dma_unmap_len_set(tx_buffer, len, 0);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:07 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit e00e23bceba48a8f0c94fefe26948404cbd43d0a ]

This patch addresses two issues.

First is the fact that the fm10k_mbx_free_irq was assuming msix_entries was
valid and that will not always be the case. As such we need to add a check
for if it is NULL.

Second is the fact that we weren't freeing the IRQ if the mailbox API
returned an error on trying to connect.

Signed-off-by: Alexander Duyck <adu...@mirantis.com>
Reviewed-by: Bruce Allan <bruce....@intel.com>
Tested-by: Krishneil Singh <Krishnei...@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey....@intel.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)

--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
@@ -1122,6 +1122,10 @@ void fm10k_mbx_free_irq(struct fm10k_int
struct fm10k_hw *hw = &interface->hw;
int itr_reg;

+ /* no mailbox IRQ to free if MSI-X is not enabled */
+ if (!interface->msix_entries)
+ return;
+
/* disconnect the mailbox */
hw->mbx.ops.disconnect(hw, &hw->mbx);

@@ -1444,10 +1448,15 @@ int fm10k_mbx_request_irq(struct fm10k_i
err = fm10k_mbx_request_irq_pf(interface);
else
err = fm10k_mbx_request_irq_vf(interface);
+ if (err)
+ return err;

/* connect mailbox */
- if (!err)
- err = hw->mbx.ops.connect(hw, &hw->mbx);
+ err = hw->mbx.ops.connect(hw, &hw->mbx);
+
+ /* if the mailbox failed to connect, then free IRQ */
+ if (err)
+ fm10k_mbx_free_irq(interface);

return err;
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:08 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 5d6002b7b822c7423e75d4651e6790bfb5642b1b ]

This patch corrects an issue in which the polling routine would increase
the budget for Rx to at least 1 per queue if multiple queues were present.
This would result in Rx packets being processed when the budget was 0 which
is meant to indicate that no Rx can be handled.

Signed-off-by: Alexander Duyck <adu...@mirantis.com>
Tested-by: Darin Miller <darin.j...@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey....@intel.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -2786,7 +2786,8 @@ int ixgbe_poll(struct napi_struct *napi,
ixgbe_for_each_ring(ring, q_vector->tx)
clean_complete &= !!ixgbe_clean_tx_irq(q_vector, ring);

- if (!ixgbe_qv_lock_napi(q_vector))
+ /* Exit if we are called by netpoll or busy polling is active */
+ if ((budget <= 0) || !ixgbe_qv_lock_napi(q_vector))
return budget;

/* attempt to distribute budget to each queue fairly, but don't allow

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:08 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 4360ca9c24388e44cb0e14861a62fff43cf225c0 ]

Fix external loopback failure.

Rx sequence reassembly was incorrect.

Signed-off-by: Dick Kennedy <dick.k...@avagotech.com>
Signed-off-by: James Smart <james...@avagotech.com>
Reviewed-by: Hannes Reinicke <ha...@suse.de>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/scsi/lpfc/lpfc_sli.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)

--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -14842,10 +14842,12 @@ lpfc_fc_frame_add(struct lpfc_vport *vpo
struct lpfc_dmabuf *h_buf;
struct hbq_dmabuf *seq_dmabuf = NULL;
struct hbq_dmabuf *temp_dmabuf = NULL;
+ uint8_t found = 0;

INIT_LIST_HEAD(&dmabuf->dbuf.list);
dmabuf->time_stamp = jiffies;
new_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
+
/* Use the hdr_buf to find the sequence that this frame belongs to */
list_for_each_entry(h_buf, &vport->rcv_buffer_list, list) {
temp_hdr = (struct fc_frame_header *)h_buf->virt;
@@ -14885,7 +14887,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vpo
return seq_dmabuf;
}
/* find the correct place in the sequence to insert this frame */
- list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) {
+ d_buf = list_entry(seq_dmabuf->dbuf.list.prev, typeof(*d_buf), list);
+ while (!found) {
temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf);
temp_hdr = (struct fc_frame_header *)temp_dmabuf->hbuf.virt;
/*
@@ -14895,9 +14898,17 @@ lpfc_fc_frame_add(struct lpfc_vport *vpo
if (be16_to_cpu(new_hdr->fh_seq_cnt) >
be16_to_cpu(temp_hdr->fh_seq_cnt)) {
list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list);
- return seq_dmabuf;
+ found = 1;
+ break;
}
+
+ if (&d_buf->list == &seq_dmabuf->dbuf.list)
+ break;
+ d_buf = list_entry(d_buf->list.prev, typeof(*d_buf), list);
}
+
+ if (found)
+ return seq_dmabuf;
return NULL;
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:11 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit d6de08cc46269899988b4f40acc7337279693d4b ]

Fix the FLOGI discovery logic to comply with T11 standards

We weren't properly setting fabric parameters, such as R_A_TOV and E_D_TOV,
when we registered the vfi object in default configs and pt2pt configs.
Revise to now pass service params with the values to the firmware and
ensure they are reset on link bounce. Required reworking the call sequence
in the discovery threads.

Signed-off-by: Dick Kennedy <dick.k...@avagotech.com>
Signed-off-by: James Smart <james...@avagotech.com>
Reviewed-by: Hannes Reinicke <ha...@suse.de>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/scsi/lpfc/lpfc_crtn.h | 1
drivers/scsi/lpfc/lpfc_els.c | 342 ++++++++++++++++---------------------
drivers/scsi/lpfc/lpfc_hbadisc.c | 12 -
drivers/scsi/lpfc/lpfc_nportdisc.c | 124 ++++++++-----
4 files changed, 240 insertions(+), 239 deletions(-)

--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -72,6 +72,7 @@ void lpfc_cancel_all_vport_retry_delay_t
void lpfc_retry_pport_discovery(struct lpfc_hba *);
void lpfc_release_rpi(struct lpfc_hba *, struct lpfc_vport *, uint16_t);

+void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -455,9 +455,9 @@ int
lpfc_issue_reg_vfi(struct lpfc_vport *vport)
{
struct lpfc_hba *phba = vport->phba;
- LPFC_MBOXQ_t *mboxq;
+ LPFC_MBOXQ_t *mboxq = NULL;
struct lpfc_nodelist *ndlp;
- struct lpfc_dmabuf *dmabuf;
+ struct lpfc_dmabuf *dmabuf = NULL;
int rc = 0;

/* move forward in case of SLI4 FC port loopback test and pt2pt mode */
@@ -471,25 +471,33 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vp
}
}

- dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
- if (!dmabuf) {
+ mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ if (!mboxq) {
rc = -ENOMEM;
goto fail;
}
- dmabuf->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &dmabuf->phys);
- if (!dmabuf->virt) {
- rc = -ENOMEM;
- goto fail_free_dmabuf;
- }

- mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
- if (!mboxq) {
- rc = -ENOMEM;
- goto fail_free_coherent;
+ /* Supply CSP's only if we are fabric connect or pt-to-pt connect */
+ if ((vport->fc_flag & FC_FABRIC) || (vport->fc_flag & FC_PT2PT)) {
+ dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+ if (!dmabuf) {
+ rc = -ENOMEM;
+ goto fail;
+ }
+ dmabuf->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &dmabuf->phys);
+ if (!dmabuf->virt) {
+ rc = -ENOMEM;
+ goto fail;
+ }
+ memcpy(dmabuf->virt, &phba->fc_fabparam,
+ sizeof(struct serv_parm));
}
+
vport->port_state = LPFC_FABRIC_CFG_LINK;
- memcpy(dmabuf->virt, &phba->fc_fabparam, sizeof(vport->fc_sparam));
- lpfc_reg_vfi(mboxq, vport, dmabuf->phys);
+ if (dmabuf)
+ lpfc_reg_vfi(mboxq, vport, dmabuf->phys);
+ else
+ lpfc_reg_vfi(mboxq, vport, 0);

mboxq->mbox_cmpl = lpfc_mbx_cmpl_reg_vfi;
mboxq->vport = vport;
@@ -497,17 +505,19 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vp
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
if (rc == MBX_NOT_FINISHED) {
rc = -ENXIO;
- goto fail_free_mbox;
+ goto fail;
}
return 0;

-fail_free_mbox:
- mempool_free(mboxq, phba->mbox_mem_pool);
-fail_free_coherent:
- lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys);
-fail_free_dmabuf:
- kfree(dmabuf);
fail:
+ if (mboxq)
+ mempool_free(mboxq, phba->mbox_mem_pool);
+ if (dmabuf) {
+ if (dmabuf->virt)
+ lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys);
+ kfree(dmabuf);
+ }
+
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
"0289 Issue Register VFI failed: Err %d\n", rc);
@@ -711,9 +721,10 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_v
* For FC we need to do some special processing because of the SLI
* Port's default settings of the Common Service Parameters.
*/
- if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC) {
+ if ((phba->sli_rev == LPFC_SLI_REV4) &&
+ (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC)) {
/* If physical FC port changed, unreg VFI and ALL VPIs / RPIs */
- if ((phba->sli_rev == LPFC_SLI_REV4) && fabric_param_changed)
+ if (fabric_param_changed)
lpfc_unregister_fcf_prep(phba);

/* This should just update the VFI CSPs*/
@@ -824,13 +835,21 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vp

spin_lock_irq(shost->host_lock);
vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
+ vport->fc_flag |= FC_PT2PT;
spin_unlock_irq(shost->host_lock);

- phba->fc_edtov = FF_DEF_EDTOV;
- phba->fc_ratov = FF_DEF_RATOV;
+ /* If physical FC port changed, unreg VFI and ALL VPIs / RPIs */
+ if ((phba->sli_rev == LPFC_SLI_REV4) && phba->fc_topology_changed) {
+ lpfc_unregister_fcf_prep(phba);
+
+ spin_lock_irq(shost->host_lock);
+ vport->fc_flag &= ~FC_VFI_REGISTERED;
+ spin_unlock_irq(shost->host_lock);
+ phba->fc_topology_changed = 0;
+ }
+
rc = memcmp(&vport->fc_portname, &sp->portName,
sizeof(vport->fc_portname));
- memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));

if (rc >= 0) {
/* This side will initiate the PLOGI */
@@ -839,38 +858,14 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vp
spin_unlock_irq(shost->host_lock);

/*
- * N_Port ID cannot be 0, set our to LocalID the other
- * side will be RemoteID.
+ * N_Port ID cannot be 0, set our Id to LocalID
+ * the other side will be RemoteID.
*/

/* not equal */
if (rc)
vport->fc_myDID = PT2PT_LocalID;

- mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
- if (!mbox)
- goto fail;
-
- lpfc_config_link(phba, mbox);
-
- mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
- mbox->vport = vport;
- rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
- if (rc == MBX_NOT_FINISHED) {
- mempool_free(mbox, phba->mbox_mem_pool);
- goto fail;
- }
-
- /*
- * For SLI4, the VFI/VPI are registered AFTER the
- * Nport with the higher WWPN sends the PLOGI with
- * an assigned NPortId.
- */
-
- /* not equal */
- if ((phba->sli_rev == LPFC_SLI_REV4) && rc)
- lpfc_issue_reg_vfi(vport);
-
/* Decrement ndlp reference count indicating that ndlp can be
* safely released when other references to it are done.
*/
@@ -912,29 +907,20 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vp
/* If we are pt2pt with another NPort, force NPIV off! */
phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED;

- spin_lock_irq(shost->host_lock);
- vport->fc_flag |= FC_PT2PT;
- spin_unlock_irq(shost->host_lock);
- /* If physical FC port changed, unreg VFI and ALL VPIs / RPIs */
- if ((phba->sli_rev == LPFC_SLI_REV4) && phba->fc_topology_changed) {
- lpfc_unregister_fcf_prep(phba);
+ mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ if (!mbox)
+ goto fail;

- /* The FC_VFI_REGISTERED flag will get clear in the cmpl
- * handler for unreg_vfi, but if we don't force the
- * FC_VFI_REGISTERED flag then the reg_vfi mailbox could be
- * built with the update bit set instead of just the vp bit to
- * change the Nport ID. We need to have the vp set and the
- * Upd cleared on topology changes.
- */
- spin_lock_irq(shost->host_lock);
- vport->fc_flag &= ~FC_VFI_REGISTERED;
- spin_unlock_irq(shost->host_lock);
- phba->fc_topology_changed = 0;
- lpfc_issue_reg_vfi(vport);
+ lpfc_config_link(phba, mbox);
+
+ mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link;
+ mbox->vport = vport;
+ rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
+ if (rc == MBX_NOT_FINISHED) {
+ mempool_free(mbox, phba->mbox_mem_pool);
+ goto fail;
}

- /* Start discovery - this should just do CLEAR_LA */
- lpfc_disc_start(vport);
return 0;
fail:
return -ENXIO;
@@ -1157,6 +1143,7 @@ flogifail:
spin_lock_irq(&phba->hbalock);
phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
spin_unlock_irq(&phba->hbalock);
+
lpfc_nlp_put(ndlp);

if (!lpfc_error_lost_link(irsp)) {
@@ -3898,6 +3885,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vpor
IOCB_t *oldcmd;
struct lpfc_iocbq *elsiocb;
uint8_t *pcmd;
+ struct serv_parm *sp;
uint16_t cmdsize;
int rc;
ELS_PKT *els_pkt_ptr;
@@ -3927,6 +3915,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vpor
"Issue ACC: did:x%x flg:x%x",
ndlp->nlp_DID, ndlp->nlp_flag, 0);
break;
+ case ELS_CMD_FLOGI:
case ELS_CMD_PLOGI:
cmdsize = (sizeof(struct serv_parm) + sizeof(uint32_t));
elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
@@ -3944,10 +3933,34 @@ lpfc_els_rsp_acc(struct lpfc_vport *vpor

*((uint32_t *) (pcmd)) = ELS_CMD_ACC;
pcmd += sizeof(uint32_t);
- memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
+ sp = (struct serv_parm *)pcmd;
+
+ if (flag == ELS_CMD_FLOGI) {
+ /* Copy the received service parameters back */
+ memcpy(sp, &phba->fc_fabparam,
+ sizeof(struct serv_parm));
+
+ /* Clear the F_Port bit */
+ sp->cmn.fPort = 0;
+
+ /* Mark all class service parameters as invalid */
+ sp->cls1.classValid = 0;
+ sp->cls2.classValid = 0;
+ sp->cls3.classValid = 0;
+ sp->cls4.classValid = 0;
+
+ /* Copy our worldwide names */
+ memcpy(&sp->portName, &vport->fc_sparam.portName,
+ sizeof(struct lpfc_name));
+ memcpy(&sp->nodeName, &vport->fc_sparam.nodeName,
+ sizeof(struct lpfc_name));
+ } else {
+ memcpy(pcmd, &vport->fc_sparam,
+ sizeof(struct serv_parm));
+ }

lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
- "Issue ACC PLOGI: did:x%x flg:x%x",
+ "Issue ACC FLOGI/PLOGI: did:x%x flg:x%x",
ndlp->nlp_DID, ndlp->nlp_flag, 0);
break;
case ELS_CMD_PRLO:
@@ -5739,7 +5752,6 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vp
IOCB_t *icmd = &cmdiocb->iocb;
struct serv_parm *sp;
LPFC_MBOXQ_t *mbox;
- struct ls_rjt stat;
uint32_t cmd, did;
int rc;
uint32_t fc_flag = 0;
@@ -5765,135 +5777,92 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vp
return 1;
}

- if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1))) {
- /* For a FLOGI we accept, then if our portname is greater
- * then the remote portname we initiate Nport login.
- */
+ (void) lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1);

- rc = memcmp(&vport->fc_portname, &sp->portName,
- sizeof(struct lpfc_name));

- if (!rc) {
- if (phba->sli_rev < LPFC_SLI_REV4) {
- mbox = mempool_alloc(phba->mbox_mem_pool,
- GFP_KERNEL);
- if (!mbox)
- return 1;
- lpfc_linkdown(phba);
- lpfc_init_link(phba, mbox,
- phba->cfg_topology,
- phba->cfg_link_speed);
- mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0;
- mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
- mbox->vport = vport;
- rc = lpfc_sli_issue_mbox(phba, mbox,
- MBX_NOWAIT);
- lpfc_set_loopback_flag(phba);
- if (rc == MBX_NOT_FINISHED)
- mempool_free(mbox, phba->mbox_mem_pool);
- return 1;
- } else {
- /* abort the flogi coming back to ourselves
- * due to external loopback on the port.
- */
- lpfc_els_abort_flogi(phba);
- return 0;
- }
- } else if (rc > 0) { /* greater than */
- spin_lock_irq(shost->host_lock);
- vport->fc_flag |= FC_PT2PT_PLOGI;
- spin_unlock_irq(shost->host_lock);
+ /*
+ * If our portname is greater than the remote portname,
+ * then we initiate Nport login.
+ */

- /* If we have the high WWPN we can assign our own
- * myDID; otherwise, we have to WAIT for a PLOGI
- * from the remote NPort to find out what it
- * will be.
- */
- vport->fc_myDID = PT2PT_LocalID;
- } else
- vport->fc_myDID = PT2PT_RemoteID;
+ rc = memcmp(&vport->fc_portname, &sp->portName,
+ sizeof(struct lpfc_name));

- /*
- * The vport state should go to LPFC_FLOGI only
- * AFTER we issue a FLOGI, not receive one.
+ if (!rc) {
+ if (phba->sli_rev < LPFC_SLI_REV4) {
+ mbox = mempool_alloc(phba->mbox_mem_pool,
+ GFP_KERNEL);
+ if (!mbox)
+ return 1;
+ lpfc_linkdown(phba);
+ lpfc_init_link(phba, mbox,
+ phba->cfg_topology,
+ phba->cfg_link_speed);
+ mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0;
+ mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+ mbox->vport = vport;
+ rc = lpfc_sli_issue_mbox(phba, mbox,
+ MBX_NOWAIT);
+ lpfc_set_loopback_flag(phba);
+ if (rc == MBX_NOT_FINISHED)
+ mempool_free(mbox, phba->mbox_mem_pool);
+ return 1;
+ }
+
+ /* abort the flogi coming back to ourselves
+ * due to external loopback on the port.
*/
+ lpfc_els_abort_flogi(phba);
+ return 0;
+
+ } else if (rc > 0) { /* greater than */
spin_lock_irq(shost->host_lock);
- fc_flag = vport->fc_flag;
- port_state = vport->port_state;
- vport->fc_flag |= FC_PT2PT;
- vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
+ vport->fc_flag |= FC_PT2PT_PLOGI;
spin_unlock_irq(shost->host_lock);
- lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
- "3311 Rcv Flogi PS x%x new PS x%x "
- "fc_flag x%x new fc_flag x%x\n",
- port_state, vport->port_state,
- fc_flag, vport->fc_flag);

- /*
- * We temporarily set fc_myDID to make it look like we are
- * a Fabric. This is done just so we end up with the right
- * did / sid on the FLOGI ACC rsp.
+ /* If we have the high WWPN we can assign our own
+ * myDID; otherwise, we have to WAIT for a PLOGI
+ * from the remote NPort to find out what it
+ * will be.
*/
- did = vport->fc_myDID;
- vport->fc_myDID = Fabric_DID;
-
+ vport->fc_myDID = PT2PT_LocalID;
} else {
- /* Reject this request because invalid parameters */
- stat.un.b.lsRjtRsvd0 = 0;
- stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
- stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
- stat.un.b.vendorUnique = 0;
-
- /*
- * We temporarily set fc_myDID to make it look like we are
- * a Fabric. This is done just so we end up with the right
- * did / sid on the FLOGI LS_RJT rsp.
- */
- did = vport->fc_myDID;
- vport->fc_myDID = Fabric_DID;
-
- lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
- NULL);
+ vport->fc_myDID = PT2PT_RemoteID;
+ }

- /* Now lets put fc_myDID back to what its supposed to be */
- vport->fc_myDID = did;
+ /*
+ * The vport state should go to LPFC_FLOGI only
+ * AFTER we issue a FLOGI, not receive one.
+ */
+ spin_lock_irq(shost->host_lock);
+ fc_flag = vport->fc_flag;
+ port_state = vport->port_state;
+ vport->fc_flag |= FC_PT2PT;
+ vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
+ spin_unlock_irq(shost->host_lock);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "3311 Rcv Flogi PS x%x new PS x%x "
+ "fc_flag x%x new fc_flag x%x\n",
+ port_state, vport->port_state,
+ fc_flag, vport->fc_flag);

- return 1;
- }
+ /*
+ * We temporarily set fc_myDID to make it look like we are
+ * a Fabric. This is done just so we end up with the right
+ * did / sid on the FLOGI ACC rsp.
+ */
+ did = vport->fc_myDID;
+ vport->fc_myDID = Fabric_DID;

- /* send our FLOGI first */
- if (vport->port_state < LPFC_FLOGI) {
- vport->fc_myDID = 0;
- lpfc_initial_flogi(vport);
- vport->fc_myDID = Fabric_DID;
- }
+ memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));

/* Send back ACC */
- lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL);
+ lpfc_els_rsp_acc(vport, ELS_CMD_FLOGI, cmdiocb, ndlp, NULL);

/* Now lets put fc_myDID back to what its supposed to be */
vport->fc_myDID = did;

- if (!(vport->fc_flag & FC_PT2PT_PLOGI)) {
-
- mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
- if (!mbox)
- goto fail;
-
- lpfc_config_link(phba, mbox);
-
- mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
- mbox->vport = vport;
- rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
- if (rc == MBX_NOT_FINISHED) {
- mempool_free(mbox, phba->mbox_mem_pool);
- goto fail;
- }
- }
-
return 0;
-fail:
- return 1;
}

/**
@@ -7345,7 +7314,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *p

/* reject till our FLOGI completes */
if ((vport->port_state < LPFC_FABRIC_CFG_LINK) &&
- (cmd != ELS_CMD_FLOGI)) {
+ (cmd != ELS_CMD_FLOGI)) {
rjt_err = LSRJT_UNABLE_TPC;
rjt_exp = LSEXP_NOTHING_MORE;
goto lsrjt;
@@ -7381,6 +7350,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *p
rjt_exp = LSEXP_NOTHING_MORE;
break;
}
+
if (vport->port_state < LPFC_DISC_AUTH) {
if (!(phba->pport->fc_flag & FC_PT2PT) ||
(phba->pport->fc_flag & FC_PT2PT_PLOGI)) {
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1083,7 +1083,7 @@ out:
}


-static void
+void
lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
struct lpfc_vport *vport = pmb->vport;
@@ -1113,8 +1113,10 @@ lpfc_mbx_cmpl_local_config_link(struct l
/* Start discovery by sending a FLOGI. port_state is identically
* LPFC_FLOGI while waiting for FLOGI cmpl
*/
- if (vport->port_state != LPFC_FLOGI || vport->fc_flag & FC_PT2PT_PLOGI)
+ if (vport->port_state != LPFC_FLOGI)
lpfc_initial_flogi(vport);
+ else if (vport->fc_flag & FC_PT2PT)
+ lpfc_disc_start(vport);
return;

out:
@@ -2963,8 +2965,10 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *p

out_free_mem:
mempool_free(mboxq, phba->mbox_mem_pool);
- lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys);
- kfree(dmabuf);
+ if (dmabuf) {
+ lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys);
+ kfree(dmabuf);
+ }
return;
}

--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -280,38 +280,12 @@ lpfc_rcv_plogi(struct lpfc_vport *vport,
uint32_t *lp;
IOCB_t *icmd;
struct serv_parm *sp;
+ uint32_t ed_tov;
LPFC_MBOXQ_t *mbox;
struct ls_rjt stat;
int rc;

memset(&stat, 0, sizeof (struct ls_rjt));
- if (vport->port_state <= LPFC_FDISC) {
- /* Before responding to PLOGI, check for pt2pt mode.
- * If we are pt2pt, with an outstanding FLOGI, abort
- * the FLOGI and resend it first.
- */
- if (vport->fc_flag & FC_PT2PT) {
- lpfc_els_abort_flogi(phba);
- if (!(vport->fc_flag & FC_PT2PT_PLOGI)) {
- /* If the other side is supposed to initiate
- * the PLOGI anyway, just ACC it now and
- * move on with discovery.
- */
- phba->fc_edtov = FF_DEF_EDTOV;
- phba->fc_ratov = FF_DEF_RATOV;
- /* Start discovery - this should just do
- CLEAR_LA */
- lpfc_disc_start(vport);
- } else
- lpfc_initial_flogi(vport);
- } else {
- stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY;
- stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
- lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,
- ndlp, NULL);
- return 0;
- }
- }
pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
lp = (uint32_t *) pcmd->virt;
sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
@@ -404,30 +378,46 @@ lpfc_rcv_plogi(struct lpfc_vport *vport,
/* Check for Nport to NPort pt2pt protocol */
if ((vport->fc_flag & FC_PT2PT) &&
!(vport->fc_flag & FC_PT2PT_PLOGI)) {
-
/* rcv'ed PLOGI decides what our NPortId will be */
vport->fc_myDID = icmd->un.rcvels.parmRo;
- mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
- if (mbox == NULL)
- goto out;
- lpfc_config_link(phba, mbox);
- mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
- mbox->vport = vport;
- rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
- if (rc == MBX_NOT_FINISHED) {
- mempool_free(mbox, phba->mbox_mem_pool);
- goto out;
+
+ ed_tov = be32_to_cpu(sp->cmn.e_d_tov);
+ if (sp->cmn.edtovResolution) {
+ /* E_D_TOV ticks are in nanoseconds */
+ ed_tov = (phba->fc_edtov + 999999) / 1000000;
}
+
/*
- * For SLI4, the VFI/VPI are registered AFTER the
- * Nport with the higher WWPN sends us a PLOGI with
- * our assigned NPortId.
+ * For pt-to-pt, use the larger EDTOV
+ * RATOV = 2 * EDTOV
*/
+ if (ed_tov > phba->fc_edtov)
+ phba->fc_edtov = ed_tov;
+ phba->fc_ratov = (2 * phba->fc_edtov) / 1000;
+
+ memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
+
+ /* Issue config_link / reg_vfi to account for updated TOV's */
+
if (phba->sli_rev == LPFC_SLI_REV4)
lpfc_issue_reg_vfi(vport);
+ else {
+ mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ if (mbox == NULL)
+ goto out;
+ lpfc_config_link(phba, mbox);
+ mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+ mbox->vport = vport;
+ rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
+ if (rc == MBX_NOT_FINISHED) {
+ mempool_free(mbox, phba->mbox_mem_pool);
+ goto out;
+ }
+ }

lpfc_can_disctmo(vport);
}
+
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!mbox)
goto out;
@@ -1038,7 +1028,9 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_
uint32_t *lp;
IOCB_t *irsp;
struct serv_parm *sp;
+ uint32_t ed_tov;
LPFC_MBOXQ_t *mbox;
+ int rc;

cmdiocb = (struct lpfc_iocbq *) arg;
rspiocb = cmdiocb->context_un.rsp_iocb;
@@ -1053,6 +1045,16 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_
if (irsp->ulpStatus)
goto out;

+ mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ if (!mbox) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0133 PLOGI: no memory for reg_login "
+ "Data: x%x x%x x%x x%x\n",
+ ndlp->nlp_DID, ndlp->nlp_state,
+ ndlp->nlp_flag, ndlp->nlp_rpi);
+ goto out;
+ }
+
pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;

prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
@@ -1094,14 +1096,38 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_
ndlp->nlp_maxframe =
((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;

- mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
- if (!mbox) {
- lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
- "0133 PLOGI: no memory for reg_login "
- "Data: x%x x%x x%x x%x\n",
- ndlp->nlp_DID, ndlp->nlp_state,
- ndlp->nlp_flag, ndlp->nlp_rpi);
- goto out;
+ if ((vport->fc_flag & FC_PT2PT) &&
+ (vport->fc_flag & FC_PT2PT_PLOGI)) {
+ ed_tov = be32_to_cpu(sp->cmn.e_d_tov);
+ if (sp->cmn.edtovResolution) {
+ /* E_D_TOV ticks are in nanoseconds */
+ ed_tov = (phba->fc_edtov + 999999) / 1000000;
+ }
+
+ /*
+ * Use the larger EDTOV
+ * RATOV = 2 * EDTOV for pt-to-pt
+ */
+ if (ed_tov > phba->fc_edtov)
+ phba->fc_edtov = ed_tov;
+ phba->fc_ratov = (2 * phba->fc_edtov) / 1000;
+
+ memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
+
+ /* Issue config_link / reg_vfi to account for updated TOV's */
+ if (phba->sli_rev == LPFC_SLI_REV4) {
+ lpfc_issue_reg_vfi(vport);
+ } else {
+ lpfc_config_link(phba, mbox);
+
+ mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+ mbox->vport = vport;
+ rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
+ if (rc == MBX_NOT_FINISHED) {
+ mempool_free(mbox, phba->mbox_mem_pool);
+ goto out;
+ }
+ }
}

lpfc_unreg_rpi(vport, ndlp);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:11 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 69eea95c48857c9dfcac120d6acea43027627b28 ]

DMA addresses returned from map_page() are calculated by using an iommu
bitmap plus a start_dma offset. The size of this bitmap is based on the main
memory size. If we have more than (4 TB - start_dma) main memory, the DMA
address calculation will also produce addresses > 4 TB. Such addresses
cannot be inserted in the 3-level DMA page table, instead the entries
modulo 4 TB will be overwritten.

Fix this by restricting the iommu bitmap size to (4 TB - start_dma).
Also set zdev->end_dma to the actual end address of the usable
range, instead of the theoretical maximum as reported by the hardware,
which fixes a sanity check in dma_map() and also the IOMMU API domain
geometry aperture calculation.

Signed-off-by: Gerald Schaefer <gerald....@de.ibm.com>
Reviewed-by: Sebastian Ott <seb...@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwi...@de.ibm.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
arch/s390/include/asm/pci_dma.h | 2 ++
arch/s390/pci/pci.c | 3 +--
arch/s390/pci/pci_dma.c | 19 ++++++++++++++-----
3 files changed, 17 insertions(+), 7 deletions(-)

--- a/arch/s390/include/asm/pci_dma.h
+++ b/arch/s390/include/asm/pci_dma.h
@@ -23,6 +23,8 @@ enum zpci_ioat_dtype {
#define ZPCI_IOTA_FS_2G 2
#define ZPCI_KEY (PAGE_DEFAULT_KEY << 5)

+#define ZPCI_TABLE_SIZE_RT (1UL << 42)
+
#define ZPCI_IOTA_STO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_ST)
#define ZPCI_IOTA_RTTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RT)
#define ZPCI_IOTA_RSTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RS)
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -701,8 +701,7 @@ static int zpci_restore(struct device *d
goto out;

zpci_map_resources(pdev);
- zpci_register_ioat(zdev, 0, zdev->start_dma + PAGE_OFFSET,
- zdev->start_dma + zdev->iommu_size - 1,
+ zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
(u64) zdev->dma_table);

out:
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -458,7 +458,19 @@ int zpci_dma_init_device(struct zpci_dev
goto out_clean;
}

- zdev->iommu_size = (unsigned long) high_memory - PAGE_OFFSET;
+ /*
+ * Restrict the iommu bitmap size to the minimum of the following:
+ * - main memory size
+ * - 3-level pagetable address limit minus start_dma offset
+ * - DMA address range allowed by the hardware (clp query pci fn)
+ *
+ * Also set zdev->end_dma to the actual end address of the usable
+ * range, instead of the theoretical maximum as reported by hardware.
+ */
+ zdev->iommu_size = min3((u64) high_memory,
+ ZPCI_TABLE_SIZE_RT - zdev->start_dma,
+ zdev->end_dma - zdev->start_dma + 1);
+ zdev->end_dma = zdev->start_dma + zdev->iommu_size - 1;
zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT;
zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8);
if (!zdev->iommu_bitmap) {
@@ -466,10 +478,7 @@ int zpci_dma_init_device(struct zpci_dev
goto out_reg;
}

- rc = zpci_register_ioat(zdev,
- 0,
- zdev->start_dma + PAGE_OFFSET,
- zdev->start_dma + zdev->iommu_size - 1,
+ rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
(u64) zdev->dma_table);
if (rc)
goto out_reg;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:11 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 092c96a8ab9d1bd60ada2ed385cc364ce084180e ]

Need to properly handle the max link rate in the dpcd.
This prevents some cases where 5.4 Ghz is selected when
it shouldn't be.

v2: simplify logic, add array bounds check

Reviewed-by: Tom St Denis <tom.s...@amd.com>
Signed-off-by: Alex Deucher <alexande...@amd.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/gpu/drm/radeon/atombios_dp.c | 108 +++++++++++----------------------
drivers/gpu/drm/radeon/radeon_dp_mst.c | 12 ++-
drivers/gpu/drm/radeon/radeon_mode.h | 6 +
3 files changed, 49 insertions(+), 77 deletions(-)

--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -302,77 +302,31 @@ static int convert_bpc_to_bpp(int bpc)
return bpc * 3;
}

-/* get the max pix clock supported by the link rate and lane num */
-static int dp_get_max_dp_pix_clock(int link_rate,
- int lane_num,
- int bpp)
-{
- return (link_rate * lane_num * 8) / bpp;
-}
-
/***** radeon specific DP functions *****/

-int radeon_dp_get_max_link_rate(struct drm_connector *connector,
- const u8 dpcd[DP_DPCD_SIZE])
-{
- int max_link_rate;
-
- if (radeon_connector_is_dp12_capable(connector))
- max_link_rate = min(drm_dp_max_link_rate(dpcd), 540000);
- else
- max_link_rate = min(drm_dp_max_link_rate(dpcd), 270000);
-
- return max_link_rate;
-}
-
-/* First get the min lane# when low rate is used according to pixel clock
- * (prefer low rate), second check max lane# supported by DP panel,
- * if the max lane# < low rate lane# then use max lane# instead.
- */
-static int radeon_dp_get_dp_lane_number(struct drm_connector *connector,
- const u8 dpcd[DP_DPCD_SIZE],
- int pix_clock)
+int radeon_dp_get_dp_link_config(struct drm_connector *connector,
+ const u8 dpcd[DP_DPCD_SIZE],
+ unsigned pix_clock,
+ unsigned *dp_lanes, unsigned *dp_rate)
{
int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector));
- int max_link_rate = radeon_dp_get_max_link_rate(connector, dpcd);
- int max_lane_num = drm_dp_max_lane_count(dpcd);
- int lane_num;
- int max_dp_pix_clock;
-
- for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) {
- max_dp_pix_clock = dp_get_max_dp_pix_clock(max_link_rate, lane_num, bpp);
- if (pix_clock <= max_dp_pix_clock)
- break;
- }
-
- return lane_num;
-}
-
-static int radeon_dp_get_dp_link_clock(struct drm_connector *connector,
- const u8 dpcd[DP_DPCD_SIZE],
- int pix_clock)
-{
- int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector));
- int lane_num, max_pix_clock;
-
- if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
- ENCODER_OBJECT_ID_NUTMEG)
- return 270000;
-
- lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock);
- max_pix_clock = dp_get_max_dp_pix_clock(162000, lane_num, bpp);
- if (pix_clock <= max_pix_clock)
- return 162000;
- max_pix_clock = dp_get_max_dp_pix_clock(270000, lane_num, bpp);
- if (pix_clock <= max_pix_clock)
- return 270000;
- if (radeon_connector_is_dp12_capable(connector)) {
- max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp);
- if (pix_clock <= max_pix_clock)
- return 540000;
+ static const unsigned link_rates[3] = { 162000, 270000, 540000 };
+ unsigned max_link_rate = drm_dp_max_link_rate(dpcd);
+ unsigned max_lane_num = drm_dp_max_lane_count(dpcd);
+ unsigned lane_num, i, max_pix_clock;
+
+ for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) {
+ for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) {
+ max_pix_clock = (lane_num * link_rates[i] * 8) / bpp;
+ if (max_pix_clock >= pix_clock) {
+ *dp_lanes = lane_num;
+ *dp_rate = link_rates[i];
+ return 0;
+ }
+ }
}

- return radeon_dp_get_max_link_rate(connector, dpcd);
+ return -EINVAL;
}

static u8 radeon_dp_encoder_service(struct radeon_device *rdev,
@@ -491,6 +445,7 @@ void radeon_dp_set_link_config(struct dr
{
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_connector_atom_dig *dig_connector;
+ int ret;

if (!radeon_connector->con_priv)
return;
@@ -498,10 +453,14 @@ void radeon_dp_set_link_config(struct dr

if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
- dig_connector->dp_clock =
- radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock);
- dig_connector->dp_lane_count =
- radeon_dp_get_dp_lane_number(connector, dig_connector->dpcd, mode->clock);
+ ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd,
+ mode->clock,
+ &dig_connector->dp_lane_count,
+ &dig_connector->dp_clock);
+ if (ret) {
+ dig_connector->dp_clock = 0;
+ dig_connector->dp_lane_count = 0;
+ }
}
}

@@ -510,7 +469,8 @@ int radeon_dp_mode_valid_helper(struct d
{
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_connector_atom_dig *dig_connector;
- int dp_clock;
+ unsigned dp_clock, dp_lanes;
+ int ret;

if ((mode->clock > 340000) &&
(!radeon_connector_is_dp12_capable(connector)))
@@ -520,8 +480,12 @@ int radeon_dp_mode_valid_helper(struct d
return MODE_CLOCK_HIGH;
dig_connector = radeon_connector->con_priv;

- dp_clock =
- radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock);
+ ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd,
+ mode->clock,
+ &dp_lanes,
+ &dp_clock);
+ if (ret)
+ return MODE_CLOCK_HIGH;

if ((dp_clock == 540000) &&
(!radeon_connector_is_dp12_capable(connector)))
--- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -525,11 +525,17 @@ static bool radeon_mst_mode_fixup(struct
drm_mode_set_crtcinfo(adjusted_mode, 0);
{
struct radeon_connector_atom_dig *dig_connector;
+ int ret;

dig_connector = mst_enc->connector->con_priv;
- dig_connector->dp_lane_count = drm_dp_max_lane_count(dig_connector->dpcd);
- dig_connector->dp_clock = radeon_dp_get_max_link_rate(&mst_enc->connector->base,
- dig_connector->dpcd);
+ ret = radeon_dp_get_dp_link_config(&mst_enc->connector->base,
+ dig_connector->dpcd, adjusted_mode->clock,
+ &dig_connector->dp_lane_count,
+ &dig_connector->dp_clock);
+ if (ret) {
+ dig_connector->dp_lane_count = 0;
+ dig_connector->dp_clock = 0;
+ }
DRM_DEBUG_KMS("dig clock %p %d %d\n", dig_connector,
dig_connector->dp_lane_count, dig_connector->dp_clock);
}
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -757,8 +757,10 @@ extern u8 radeon_dp_getsinktype(struct r
extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
struct drm_connector *connector);
-int radeon_dp_get_max_link_rate(struct drm_connector *connector,
- const u8 *dpcd);
+extern int radeon_dp_get_dp_link_config(struct drm_connector *connector,
+ const u8 *dpcd,
+ unsigned pix_clock,
+ unsigned *dp_lanes, unsigned *dp_rate);
extern void radeon_dp_set_rx_power_state(struct drm_connector *connector,
u8 power_state);
extern void radeon_dp_aux_init(struct radeon_connector *radeon_connector);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:11 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 97a8df90875f72ba3b4c3320759fd93cea743261 ]

While we steal the encoder away from the connector the connector may
be updated to use a different encoder.

Without this change if 2 connectors swap encoders one of them will
end up without a crtc.

Signed-off-by: Maarten Lankhorst <maarten....@linux.intel.com>
Reviewed-by: Gustavo Padovan <gustavo...@collabora.co.uk>
Signed-off-by: Daniel Vetter <daniel...@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1452160762-30487-5-git-se...@linux.intel.com
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/gpu/drm/drm_atomic_helper.c | 4 ----
1 file changed, 4 deletions(-)

--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -108,7 +108,6 @@ steal_encoder(struct drm_atomic_state *s
struct drm_crtc_state *crtc_state;
struct drm_connector *connector;
struct drm_connector_state *connector_state;
- int ret;

/*
* We can only steal an encoder coming from a connector, which means we
@@ -139,9 +138,6 @@ steal_encoder(struct drm_atomic_state *s
if (IS_ERR(connector_state))
return PTR_ERR(connector_state);

- ret = drm_atomic_set_crtc_for_connector(connector_state, NULL);
- if (ret)
- return ret;
connector_state->best_encoder = NULL;
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:11 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 1b5df59e50874b9034c0fa389cd52b65f1f93292 ]

An idr warning is reported when a context is release after the capi card
is unbound from the cxl driver via sysfs. Below are the steps to
reproduce:

1. Create multiple afu contexts in an user-space application using libcxl.
2. Unbind capi card from cxl using command of form
echo <capi-card-pci-addr> > /sys/bus/pci/drivers/cxl-pci/unbind
3. Exit/kill the application owning afu contexts.

After above steps a warning message is usually seen in the kernel logs
of the form "idr_remove called for id=<context-id> which is not
allocated."

This is caused by the function cxl_release_afu which destroys the
contexts_idr table. So when a context is release no entry for context pe
is found in the contexts_idr table and idr code prints this warning.

This patch fixes this issue by increasing & decreasing the ref-count on
the afu device when a context is initialized or when its freed
respectively. This prevents the afu from being released until all the
afu contexts have been released. The patch introduces two new functions
namely cxl_afu_get/put that manage the ref-count on the afu device.

Also the patch removes code inside cxl_dev_context_init that increases ref
on the afu device as its guaranteed to be alive during this function.

Reported-by: Ian Munsie <imu...@au1.ibm.com>
Signed-off-by: Vaibhav Jain <vai...@linux.vnet.ibm.com>
Acked-by: Ian Munsie <imu...@au1.ibm.com>
Signed-off-by: Michael Ellerman <m...@ellerman.id.au>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/misc/cxl/api.c | 4 ----
drivers/misc/cxl/context.c | 9 +++++++++
drivers/misc/cxl/cxl.h | 12 ++++++++++++
drivers/misc/cxl/file.c | 19 +++++++++++--------
4 files changed, 32 insertions(+), 12 deletions(-)

--- a/drivers/misc/cxl/api.c
+++ b/drivers/misc/cxl/api.c
@@ -25,7 +25,6 @@ struct cxl_context *cxl_dev_context_init

afu = cxl_pci_to_afu(dev);

- get_device(&afu->dev);
ctx = cxl_context_alloc();
if (IS_ERR(ctx)) {
rc = PTR_ERR(ctx);
@@ -61,7 +60,6 @@ err_mapping:
err_ctx:
kfree(ctx);
err_dev:
- put_device(&afu->dev);
return ERR_PTR(rc);
}
EXPORT_SYMBOL_GPL(cxl_dev_context_init);
@@ -87,8 +85,6 @@ int cxl_release_context(struct cxl_conte
if (ctx->status >= STARTED)
return -EBUSY;

- put_device(&ctx->afu->dev);
-
cxl_context_free(ctx);

return 0;
--- a/drivers/misc/cxl/context.c
+++ b/drivers/misc/cxl/context.c
@@ -97,6 +97,12 @@ int cxl_context_init(struct cxl_context
ctx->pe = i;
ctx->elem = &ctx->afu->spa[i];
ctx->pe_inserted = false;
+
+ /*
+ * take a ref on the afu so that it stays alive at-least till
+ * this context is reclaimed inside reclaim_ctx.
+ */
+ cxl_afu_get(afu);
return 0;
}

@@ -278,6 +284,9 @@ static void reclaim_ctx(struct rcu_head
if (ctx->irq_bitmap)
kfree(ctx->irq_bitmap);

+ /* Drop ref to the afu device taken during cxl_context_init */
+ cxl_afu_put(ctx->afu);
+
kfree(ctx);
}

--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -403,6 +403,18 @@ struct cxl_afu {
bool enabled;
};

+/* AFU refcount management */
+static inline struct cxl_afu *cxl_afu_get(struct cxl_afu *afu)
+{
+
+ return (get_device(&afu->dev) == NULL) ? NULL : afu;
+}
+
+static inline void cxl_afu_put(struct cxl_afu *afu)
+{
+ put_device(&afu->dev);
+}
+

struct cxl_irq_name {
struct list_head list;
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -67,7 +67,13 @@ static int __afu_open(struct inode *inod
spin_unlock(&adapter->afu_list_lock);
goto err_put_adapter;
}
- get_device(&afu->dev);
+
+ /*
+ * taking a ref to the afu so that it doesn't go away
+ * for rest of the function. This ref is released before
+ * we return.
+ */
+ cxl_afu_get(afu);
spin_unlock(&adapter->afu_list_lock);

if (!afu->current_mode)
@@ -90,13 +96,12 @@ static int __afu_open(struct inode *inod
file->private_data = ctx;
cxl_ctx_get();

- /* Our ref on the AFU will now hold the adapter */
- put_device(&adapter->dev);
-
- return 0;
+ /* indicate success */
+ rc = 0;

err_put_afu:
- put_device(&afu->dev);
+ /* release the ref taken earlier */
+ cxl_afu_put(afu);
err_put_adapter:
put_device(&adapter->dev);
return rc;
@@ -131,8 +136,6 @@ int afu_release(struct inode *inode, str
mutex_unlock(&ctx->mapping_lock);
}

- put_device(&ctx->afu->dev);
-
/*
* At this this point all bottom halfs have finished and we should be
* getting no more IRQs from the hardware for this context. Once it's

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:11 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 0e4425ed641f3eef67c892bc541949cd745a9ba9 ]

The driver was being called by VLAN, bonding, teaming operations
that expected to be able to hold locks like rcu_read_lock().

This causes the driver to be held to the requirement to not sleep,
and was found by the kernel debug options for checking sleep
inside critical section, and the locking validator.

Change-ID: Ibc68c835f5ffa8ffe0638ffe910a66fc5649a7f7
Signed-off-by: Jesse Brandeburg <jesse.br...@intel.com>
Tested-by: Andrew Bowers <andrewx...@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey....@intel.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 44 ++++++++++++----------------
1 file changed, 20 insertions(+), 24 deletions(-)

--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -1547,9 +1547,11 @@ static int i40e_set_mac(struct net_devic
spin_unlock_bh(&vsi->mac_filter_list_lock);
}

- i40e_sync_vsi_filters(vsi, false);
ether_addr_copy(netdev->dev_addr, addr->sa_data);
-
+ /* schedule our worker thread which will take care of
+ * applying the new filter changes
+ */
+ i40e_service_event_schedule(vsi->back);
return 0;
}

@@ -2112,12 +2114,7 @@ int i40e_sync_vsi_filters(struct i40e_vs
*/
if (pf->cur_promisc != cur_promisc) {
pf->cur_promisc = cur_promisc;
- if (grab_rtnl)
- i40e_do_reset_safe(pf,
- BIT(__I40E_PF_RESET_REQUESTED));
- else
- i40e_do_reset(pf,
- BIT(__I40E_PF_RESET_REQUESTED));
+ set_bit(__I40E_PF_RESET_REQUESTED, &pf->state);
}
} else {
ret = i40e_aq_set_vsi_unicast_promiscuous(
@@ -2377,16 +2374,13 @@ int i40e_vsi_add_vlan(struct i40e_vsi *v
}
}

- /* Make sure to release before sync_vsi_filter because that
- * function will lock/unlock as necessary
- */
spin_unlock_bh(&vsi->mac_filter_list_lock);

- if (test_bit(__I40E_DOWN, &vsi->back->state) ||
- test_bit(__I40E_RESET_RECOVERY_PENDING, &vsi->back->state))
- return 0;
-
- return i40e_sync_vsi_filters(vsi, false);
+ /* schedule our worker thread which will take care of
+ * applying the new filter changes
+ */
+ i40e_service_event_schedule(vsi->back);
+ return 0;
}

/**
@@ -2459,16 +2453,13 @@ int i40e_vsi_kill_vlan(struct i40e_vsi *
}
}

- /* Make sure to release before sync_vsi_filter because that
- * function with lock/unlock as necessary
- */
spin_unlock_bh(&vsi->mac_filter_list_lock);

- if (test_bit(__I40E_DOWN, &vsi->back->state) ||
- test_bit(__I40E_RESET_RECOVERY_PENDING, &vsi->back->state))
- return 0;
-
- return i40e_sync_vsi_filters(vsi, false);
+ /* schedule our worker thread which will take care of
+ * applying the new filter changes
+ */
+ i40e_service_event_schedule(vsi->back);
+ return 0;
}

/**
@@ -2711,6 +2702,11 @@ static void i40e_config_xps_tx_ring(stru
netif_set_xps_queue(ring->netdev, mask, ring->queue_index);
free_cpumask_var(mask);
}
+
+ /* schedule our worker thread which will take care of
+ * applying the new filter changes
+ */
+ i40e_service_event_schedule(vsi->back);
}

/**

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:11 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit be06998f96ecb93938ad2cce46c4289bf7cf45bc ]

The combined effect of commits 6423fc3416 ("igb: do not re-init SR-IOV
during probe") and ceee3450b3 ("igb: make sure SR-IOV init uses the
right number of queues") causes VFs no longer getting set up, leading
to NULL pointer dereferences due to the adapter's ->vf_data being NULL
while ->vfs_allocated_count is non-zero. The first commit not only
neglected the side effect of igb_sriov_reinit() that the second commit
tried to account for, but also that of setting IGB_FLAG_HAS_MSIX,
without which igb_enable_sriov() is effectively a no-op. Calling
igb_{,re}set_interrupt_capability() as done here seems to address this,
but I'm not sure whether this is better than sinply reverting the other
two commits.

Signed-off-by: Jan Beulich <jbeu...@suse.com>
Tested-by: Aaron Brown <aaron....@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey....@intel.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/net/ethernet/intel/igb/igb_main.c | 7 +++++++
1 file changed, 7 insertions(+)

--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -2858,6 +2858,13 @@ static void igb_probe_vfs(struct igb_ada
if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211))
return;

+ /* Of the below we really only want the effect of getting
+ * IGB_FLAG_HAS_MSIX set (if available), without which
+ * igb_enable_sriov() has no effect.
+ */
+ igb_set_interrupt_capability(adapter, true);
+ igb_reset_interrupt_capability(adapter);
+
pci_sriov_set_totalvfs(pdev, 7);
igb_enable_sriov(pdev, max_vfs);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:11 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 4f2f017c6101ab2ba202d6059c238c15577ad38b ]

HW/NVM sets a limit of no less than 256 bytes for MSS. Stack can send as
low as 76 bytes MSS. This patch lowers the HW limit to 64 bytes to avoid
MDDs from firing and causing a reset when the MSS is lower than 256.

Change-ID: I36b500a6bb227d283c3e321a7718e0672b11fab0
Signed-off-by: Anjali Singhai Jain <anjali....@intel.com>
Tested-by: Andrew Bowers <andrewx...@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey....@intel.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)

--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -6685,6 +6685,7 @@ static void i40e_reset_and_rebuild(struc
struct i40e_hw *hw = &pf->hw;
u8 set_fc_aq_fail = 0;
i40e_status ret;
+ u32 val;
u32 v;

/* Now we wait for GRST to settle out.
@@ -6823,6 +6824,20 @@ static void i40e_reset_and_rebuild(struc
}
}

+ /* Reconfigure hardware for allowing smaller MSS in the case
+ * of TSO, so that we avoid the MDD being fired and causing
+ * a reset in the case of small MSS+TSO.
+ */
+#define I40E_REG_MSS 0x000E64DC
+#define I40E_REG_MSS_MIN_MASK 0x3FF0000
+#define I40E_64BYTE_MSS 0x400000
+ val = rd32(hw, I40E_REG_MSS);
+ if ((val & I40E_REG_MSS_MIN_MASK) > I40E_64BYTE_MSS) {
+ val &= ~I40E_REG_MSS_MIN_MASK;
+ val |= I40E_64BYTE_MSS;
+ wr32(hw, I40E_REG_MSS, val);
+ }
+
if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
(pf->hw.aq.fw_maj_ver < 4)) {
msleep(75);
@@ -10183,6 +10198,7 @@ static int i40e_probe(struct pci_dev *pd
u16 link_status;
int err;
u32 len;
+ u32 val;
u32 i;
u8 set_fc_aq_fail;

@@ -10493,6 +10509,17 @@ static int i40e_probe(struct pci_dev *pd
i40e_stat_str(&pf->hw, err),
i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));

+ /* Reconfigure hardware for allowing smaller MSS in the case
+ * of TSO, so that we avoid the MDD being fired and causing
+ * a reset in the case of small MSS+TSO.
+ */
+ val = rd32(hw, I40E_REG_MSS);
+ if ((val & I40E_REG_MSS_MIN_MASK) > I40E_64BYTE_MSS) {
+ val &= ~I40E_REG_MSS_MIN_MASK;
+ val |= I40E_64BYTE_MSS;
+ wr32(hw, I40E_REG_MSS, val);
+ }
+
if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
(pf->hw.aq.fw_maj_ver < 4)) {
msleep(75);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:11 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 0d9bfe9123cfde59bf5c2e375b59d2a7d5061c4c ]

Measurement characteristics are allocated during channel path
registration but not freed during deregistration. Fix this by
embedding these characteristics inside struct channel_path.

Signed-off-by: Sebastian Ott <seb...@linux.vnet.ibm.com>
Reviewed-by: Peter Oberparleiter <obe...@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwi...@de.ibm.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/s390/cio/chp.c | 6 +++---
drivers/s390/cio/chp.h | 2 +-
drivers/s390/cio/chsc.c | 16 ++--------------
3 files changed, 6 insertions(+), 18 deletions(-)

--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -139,11 +139,11 @@ static ssize_t chp_measurement_chars_rea

device = container_of(kobj, struct device, kobj);
chp = to_channelpath(device);
- if (!chp->cmg_chars)
+ if (chp->cmg == -1)
return 0;

- return memory_read_from_buffer(buf, count, &off,
- chp->cmg_chars, sizeof(struct cmg_chars));
+ return memory_read_from_buffer(buf, count, &off, &chp->cmg_chars,
+ sizeof(chp->cmg_chars));
}

static struct bin_attribute chp_measurement_chars_attr = {
--- a/drivers/s390/cio/chp.h
+++ b/drivers/s390/cio/chp.h
@@ -48,7 +48,7 @@ struct channel_path {
/* Channel-measurement related stuff: */
int cmg;
int shared;
- void *cmg_chars;
+ struct cmg_chars cmg_chars;
};

/* Return channel_path struct for given chpid. */
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -967,22 +967,19 @@ static void
chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv,
struct cmg_chars *chars)
{
- struct cmg_chars *cmg_chars;
int i, mask;

- cmg_chars = chp->cmg_chars;
for (i = 0; i < NR_MEASUREMENT_CHARS; i++) {
mask = 0x80 >> (i + 3);
if (cmcv & mask)
- cmg_chars->values[i] = chars->values[i];
+ chp->cmg_chars.values[i] = chars->values[i];
else
- cmg_chars->values[i] = 0;
+ chp->cmg_chars.values[i] = 0;
}
}

int chsc_get_channel_measurement_chars(struct channel_path *chp)
{
- struct cmg_chars *cmg_chars;
int ccode, ret;

struct {
@@ -1006,11 +1003,6 @@ int chsc_get_channel_measurement_chars(s
u32 data[NR_MEASUREMENT_CHARS];
} __attribute__ ((packed)) *scmc_area;

- chp->cmg_chars = NULL;
- cmg_chars = kmalloc(sizeof(*cmg_chars), GFP_KERNEL);
- if (!cmg_chars)
- return -ENOMEM;
-
spin_lock_irq(&chsc_page_lock);
memset(chsc_page, 0, PAGE_SIZE);
scmc_area = chsc_page;
@@ -1042,14 +1034,10 @@ int chsc_get_channel_measurement_chars(s
/* No cmg-dependent data. */
goto out;
}
- chp->cmg_chars = cmg_chars;
chsc_initialize_cmg_chars(chp, scmc_area->cmcv,
(struct cmg_chars *) &scmc_area->data);
out:
spin_unlock_irq(&chsc_page_lock);
- if (!chp->cmg_chars)
- kfree(cmg_chars);
-
return ret;
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:14 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 91815d8aa7e2f45d30e51caa297061ad893628d9 ]

This patch adds codec ID (0x8086280b) for Kabylake display codec
and apply the hsw fix-ups to Kabylake.

Signed-off-by: Libin Yang <libin...@linux.intel.com>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
sound/pci/hda/patch_hdmi.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -51,8 +51,10 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't
#define is_broadwell(codec) ((codec)->core.vendor_id == 0x80862808)
#define is_skylake(codec) ((codec)->core.vendor_id == 0x80862809)
#define is_broxton(codec) ((codec)->core.vendor_id == 0x8086280a)
+#define is_kabylake(codec) ((codec)->core.vendor_id == 0x8086280b)
#define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec) \
- || is_skylake(codec) || is_broxton(codec))
+ || is_skylake(codec) || is_broxton(codec) \
+ || is_kabylake(codec))

#define is_valleyview(codec) ((codec)->core.vendor_id == 0x80862882)
#define is_cherryview(codec) ((codec)->core.vendor_id == 0x80862883)
@@ -3584,6 +3586,7 @@ HDA_CODEC_ENTRY(0x80862807, "Haswell HDM
HDA_CODEC_ENTRY(0x80862808, "Broadwell HDMI", patch_generic_hdmi),
HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI", patch_generic_hdmi),
HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI", patch_generic_hdmi),
+HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI", patch_generic_hdmi),
HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_generic_hdmi),
HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_generic_hdmi),

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:14 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 1dff76b92f69051e579bdc131e01500da9fa2a91 ]

The following message can be observed on the Ubuntu v3.13.0-65 with KASan
backported:

==================================================================
BUG: KASan: use after free in task_numa_find_cpu+0x64c/0x890 at addr ffff880dd393ecd8
Read of size 8 by task qemu-system-x86/3998900
=============================================================================
BUG kmalloc-128 (Tainted: G B ): kasan: bad access detected
-----------------------------------------------------------------------------

INFO: Allocated in task_numa_fault+0xc1b/0xed0 age=41980 cpu=18 pid=3998890
__slab_alloc+0x4f8/0x560
__kmalloc+0x1eb/0x280
task_numa_fault+0xc1b/0xed0
do_numa_page+0x192/0x200
handle_mm_fault+0x808/0x1160
__do_page_fault+0x218/0x750
do_page_fault+0x1a/0x70
page_fault+0x28/0x30
SyS_poll+0x66/0x1a0
system_call_fastpath+0x1a/0x1f
INFO: Freed in task_numa_free+0x1d2/0x200 age=62 cpu=18 pid=0
__slab_free+0x2ab/0x3f0
kfree+0x161/0x170
task_numa_free+0x1d2/0x200
finish_task_switch+0x1d2/0x210
__schedule+0x5d4/0xc60
schedule_preempt_disabled+0x40/0xc0
cpu_startup_entry+0x2da/0x340
start_secondary+0x28f/0x360
Call Trace:
[<ffffffff81a6ce35>] dump_stack+0x45/0x56
[<ffffffff81244aed>] print_trailer+0xfd/0x170
[<ffffffff8124ac36>] object_err+0x36/0x40
[<ffffffff8124cbf9>] kasan_report_error+0x1e9/0x3a0
[<ffffffff8124d260>] kasan_report+0x40/0x50
[<ffffffff810dda7c>] ? task_numa_find_cpu+0x64c/0x890
[<ffffffff8124bee9>] __asan_load8+0x69/0xa0
[<ffffffff814f5c38>] ? find_next_bit+0xd8/0x120
[<ffffffff810dda7c>] task_numa_find_cpu+0x64c/0x890
[<ffffffff810de16c>] task_numa_migrate+0x4ac/0x7b0
[<ffffffff810de523>] numa_migrate_preferred+0xb3/0xc0
[<ffffffff810e0b88>] task_numa_fault+0xb88/0xed0
[<ffffffff8120ef02>] do_numa_page+0x192/0x200
[<ffffffff81211038>] handle_mm_fault+0x808/0x1160
[<ffffffff810d7dbd>] ? sched_clock_cpu+0x10d/0x160
[<ffffffff81068c52>] ? native_load_tls+0x82/0xa0
[<ffffffff81a7bd68>] __do_page_fault+0x218/0x750
[<ffffffff810c2186>] ? hrtimer_try_to_cancel+0x76/0x160
[<ffffffff81a6f5e7>] ? schedule_hrtimeout_range_clock.part.24+0xf7/0x1c0
[<ffffffff81a7c2ba>] do_page_fault+0x1a/0x70
[<ffffffff81a772e8>] page_fault+0x28/0x30
[<ffffffff8128cbd4>] ? do_sys_poll+0x1c4/0x6d0
[<ffffffff810e64f6>] ? enqueue_task_fair+0x4b6/0xaa0
[<ffffffff810233c9>] ? sched_clock+0x9/0x10
[<ffffffff810cf70a>] ? resched_task+0x7a/0xc0
[<ffffffff810d0663>] ? check_preempt_curr+0xb3/0x130
[<ffffffff8128b5c0>] ? poll_select_copy_remaining+0x170/0x170
[<ffffffff810d3bc0>] ? wake_up_state+0x10/0x20
[<ffffffff8112a28f>] ? drop_futex_key_refs.isra.14+0x1f/0x90
[<ffffffff8112d40e>] ? futex_requeue+0x3de/0xba0
[<ffffffff8112e49e>] ? do_futex+0xbe/0x8f0
[<ffffffff81022c89>] ? read_tsc+0x9/0x20
[<ffffffff8111bd9d>] ? ktime_get_ts+0x12d/0x170
[<ffffffff8108f699>] ? timespec_add_safe+0x59/0xe0
[<ffffffff8128d1f6>] SyS_poll+0x66/0x1a0
[<ffffffff81a830dd>] system_call_fastpath+0x1a/0x1f

As commit 1effd9f19324 ("sched/numa: Fix unsafe get_task_struct() in
task_numa_assign()") points out, the rcu_read_lock() cannot protect the
task_struct from being freed in the finish_task_switch(). And the bug
happens in the process of calculation of imp which requires the access of
p->numa_faults being freed in the following path:

do_exit()
current->flags |= PF_EXITING;
release_task()
~~delayed_put_task_struct()~~
schedule()
...
...
rq->curr = next;
context_switch()
finish_task_switch()
put_task_struct()
__put_task_struct()
task_numa_free()

The fix here to get_task_struct() early before end of dst_rq->lock to
protect the calculation process and also put_task_struct() in the
corresponding point if finally the dst_rq->curr somehow cannot be
assigned.

Additional credit to Liang Chen who helped fix the error logic and add the
put_task_struct() to the place it missed.

Signed-off-by: Gavin Guo <gavi...@canonical.com>
Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org>
Cc: Andrea Arcangeli <aarc...@redhat.com>
Cc: Andrew Morton <ak...@linux-foundation.org>
Cc: Hugh Dickins <hu...@google.com>
Cc: Linus Torvalds <torv...@linux-foundation.org>
Cc: Mel Gorman <mgo...@suse.de>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Rik van Riel <ri...@redhat.com>
Cc: Thomas Gleixner <tg...@linutronix.de>
Cc: jay.vo...@canonical.com
Cc: liang...@canonical.com
Link: http://lkml.kernel.org/r/1453264618-17645-1-gi...@canonical.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
kernel/sched/fair.c | 30 +++++++++++++++++++++++-------
1 file changed, 23 insertions(+), 7 deletions(-)

--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1191,8 +1191,6 @@ static void task_numa_assign(struct task
{
if (env->best_task)
put_task_struct(env->best_task);
- if (p)
- get_task_struct(p);

env->best_task = p;
env->best_imp = imp;
@@ -1260,20 +1258,30 @@ static void task_numa_compare(struct tas
long imp = env->p->numa_group ? groupimp : taskimp;
long moveimp = imp;
int dist = env->dist;
+ bool assigned = false;

rcu_read_lock();

raw_spin_lock_irq(&dst_rq->lock);
cur = dst_rq->curr;
/*
- * No need to move the exiting task, and this ensures that ->curr
- * wasn't reaped and thus get_task_struct() in task_numa_assign()
- * is safe under RCU read lock.
- * Note that rcu_read_lock() itself can't protect from the final
- * put_task_struct() after the last schedule().
+ * No need to move the exiting task or idle task.
*/
if ((cur->flags & PF_EXITING) || is_idle_task(cur))
cur = NULL;
+ else {
+ /*
+ * The task_struct must be protected here to protect the
+ * p->numa_faults access in the task_weight since the
+ * numa_faults could already be freed in the following path:
+ * finish_task_switch()
+ * --> put_task_struct()
+ * --> __put_task_struct()
+ * --> task_numa_free()
+ */
+ get_task_struct(cur);
+ }
+
raw_spin_unlock_irq(&dst_rq->lock);

/*
@@ -1357,6 +1365,7 @@ balance:
*/
if (!load_too_imbalanced(src_load, dst_load, env)) {
imp = moveimp - 1;
+ put_task_struct(cur);
cur = NULL;
goto assign;
}
@@ -1382,9 +1391,16 @@ balance:
env->dst_cpu = select_idle_sibling(env->p, env->dst_cpu);

assign:
+ assigned = true;
task_numa_assign(env, cur, imp);
unlock:
rcu_read_unlock();
+ /*
+ * The dst_rq->curr isn't assigned. The protection for task_struct is
+ * finished.
+ */
+ if (cur && !assigned)
+ put_task_struct(cur);
}

static void task_numa_find_cpu(struct task_numa_env *env,

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:14 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 1418c3458118c6969d08e23aa377da7e2a7be36c ]

When a lot (many hundreds) of MAC or VLAN filters are added at one time,
we can overflow the Admin Queue buffer size with all the requests.
Unfortunately, the driver would then calculate the message size
incorrectly, causing it to be rejected by the PF. Furthermore, there was
no mechanism to trigger another request to allow for configuring the
rest of the filters that didn't fit into the first request.

To fix this, recalculate the correct buffer size when we detect the
overflow condition instead of just assuming the max buffer size. Also,
don't clear the request bit in adapter->aq_required when we have an
overflow, so that the rest of the filters can be processed later.

Change-ID: Idd7cbbc5af31315e0dcb1b10e6a02ad9817ce65c
Signed-off-by: Mitch Williams <mitch.a....@intel.com>
Tested-by: Andrew Bowers <andrewx...@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey....@intel.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c | 32 +++++++++++++++-----
1 file changed, 24 insertions(+), 8 deletions(-)

--- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
@@ -391,6 +391,7 @@ void i40evf_add_ether_addrs(struct i40ev
struct i40e_virtchnl_ether_addr_list *veal;
int len, i = 0, count = 0;
struct i40evf_mac_filter *f;
+ bool more = false;

if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
/* bail because we already have a command pending */
@@ -415,7 +416,9 @@ void i40evf_add_ether_addrs(struct i40ev
count = (I40EVF_MAX_AQ_BUF_SIZE -
sizeof(struct i40e_virtchnl_ether_addr_list)) /
sizeof(struct i40e_virtchnl_ether_addr);
- len = I40EVF_MAX_AQ_BUF_SIZE;
+ len = sizeof(struct i40e_virtchnl_ether_addr_list) +
+ (count * sizeof(struct i40e_virtchnl_ether_addr));
+ more = true;
}

veal = kzalloc(len, GFP_ATOMIC);
@@ -431,7 +434,8 @@ void i40evf_add_ether_addrs(struct i40ev
f->add = false;
}
}
- adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_MAC_FILTER;
+ if (!more)
+ adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_MAC_FILTER;
i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS,
(u8 *)veal, len);
kfree(veal);
@@ -450,6 +454,7 @@ void i40evf_del_ether_addrs(struct i40ev
struct i40e_virtchnl_ether_addr_list *veal;
struct i40evf_mac_filter *f, *ftmp;
int len, i = 0, count = 0;
+ bool more = false;

if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
/* bail because we already have a command pending */
@@ -474,7 +479,9 @@ void i40evf_del_ether_addrs(struct i40ev
count = (I40EVF_MAX_AQ_BUF_SIZE -
sizeof(struct i40e_virtchnl_ether_addr_list)) /
sizeof(struct i40e_virtchnl_ether_addr);
- len = I40EVF_MAX_AQ_BUF_SIZE;
+ len = sizeof(struct i40e_virtchnl_ether_addr_list) +
+ (count * sizeof(struct i40e_virtchnl_ether_addr));
+ more = true;
}
veal = kzalloc(len, GFP_ATOMIC);
if (!veal)
@@ -490,7 +497,8 @@ void i40evf_del_ether_addrs(struct i40ev
kfree(f);
}
}
- adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_MAC_FILTER;
+ if (!more)
+ adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_MAC_FILTER;
i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS,
(u8 *)veal, len);
kfree(veal);
@@ -509,6 +517,7 @@ void i40evf_add_vlans(struct i40evf_adap
struct i40e_virtchnl_vlan_filter_list *vvfl;
int len, i = 0, count = 0;
struct i40evf_vlan_filter *f;
+ bool more = false;

if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
/* bail because we already have a command pending */
@@ -534,7 +543,9 @@ void i40evf_add_vlans(struct i40evf_adap
count = (I40EVF_MAX_AQ_BUF_SIZE -
sizeof(struct i40e_virtchnl_vlan_filter_list)) /
sizeof(u16);
- len = I40EVF_MAX_AQ_BUF_SIZE;
+ len = sizeof(struct i40e_virtchnl_vlan_filter_list) +
+ (count * sizeof(u16));
+ more = true;
}
vvfl = kzalloc(len, GFP_ATOMIC);
if (!vvfl)
@@ -549,7 +560,8 @@ void i40evf_add_vlans(struct i40evf_adap
f->add = false;
}
}
- adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
+ if (!more)
+ adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);
kfree(vvfl);
}
@@ -567,6 +579,7 @@ void i40evf_del_vlans(struct i40evf_adap
struct i40e_virtchnl_vlan_filter_list *vvfl;
struct i40evf_vlan_filter *f, *ftmp;
int len, i = 0, count = 0;
+ bool more = false;

if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
/* bail because we already have a command pending */
@@ -592,7 +605,9 @@ void i40evf_del_vlans(struct i40evf_adap
count = (I40EVF_MAX_AQ_BUF_SIZE -
sizeof(struct i40e_virtchnl_vlan_filter_list)) /
sizeof(u16);
- len = I40EVF_MAX_AQ_BUF_SIZE;
+ len = sizeof(struct i40e_virtchnl_vlan_filter_list) +
+ (count * sizeof(u16));
+ more = true;
}
vvfl = kzalloc(len, GFP_ATOMIC);
if (!vvfl)
@@ -608,7 +623,8 @@ void i40evf_del_vlans(struct i40evf_adap
kfree(f);
}
}
- adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
+ if (!more)
+ adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_VLAN, (u8 *)vvfl, len);
kfree(vvfl);
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:16 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit f11999987bc0b5559ab56dedc6f4ca32fab5438a ]

Clean the whole mac filter list when resetting after an intermediate
add or delete push to the firmware. The code had evolved from using
a list from the stack to a heap allocation, but the memset() didn't
follow the change correctly. This now cleans the whole list rather
that just part of the first element.

Change-ID: I4cd03d5a103b7407dd8556a3a231e800f2d6f2d5
Reported-by: Rasmus Villemoes <li...@rasmusvillemoes.dk>
Signed-off-by: Shannon Nelson <shannon...@intel.com>
Tested-by: Andrew Bowers <andrewx...@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey....@intel.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)

--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -1973,11 +1973,13 @@ int i40e_sync_vsi_filters(struct i40e_vs

/* Now process 'del_list' outside the lock */
if (!list_empty(&tmp_del_list)) {
+ int del_list_size;
+
filter_list_len = pf->hw.aq.asq_buf_size /
sizeof(struct i40e_aqc_remove_macvlan_element_data);
- del_list = kcalloc(filter_list_len,
- sizeof(struct i40e_aqc_remove_macvlan_element_data),
- GFP_KERNEL);
+ del_list_size = filter_list_len *
+ sizeof(struct i40e_aqc_remove_macvlan_element_data);
+ del_list = kzalloc(del_list_size, GFP_KERNEL);
if (!del_list) {
i40e_cleanup_add_list(&tmp_add_list);

@@ -2009,7 +2011,7 @@ int i40e_sync_vsi_filters(struct i40e_vs
NULL);
aq_err = pf->hw.aq.asq_last_status;
num_del = 0;
- memset(del_list, 0, sizeof(*del_list));
+ memset(del_list, 0, del_list_size);

if (ret && aq_err != I40E_AQ_RC_ENOENT)
dev_err(&pf->pdev->dev,
@@ -2042,13 +2044,14 @@ int i40e_sync_vsi_filters(struct i40e_vs
}

if (!list_empty(&tmp_add_list)) {
+ int add_list_size;

/* do all the adds now */
filter_list_len = pf->hw.aq.asq_buf_size /
sizeof(struct i40e_aqc_add_macvlan_element_data),
- add_list = kcalloc(filter_list_len,
- sizeof(struct i40e_aqc_add_macvlan_element_data),
- GFP_KERNEL);
+ add_list_size = filter_list_len *
+ sizeof(struct i40e_aqc_add_macvlan_element_data);
+ add_list = kzalloc(add_list_size, GFP_KERNEL);
if (!add_list) {
/* Purge element from temporary lists */
i40e_cleanup_add_list(&tmp_add_list);
@@ -2086,7 +2089,7 @@ int i40e_sync_vsi_filters(struct i40e_vs

if (ret)
break;
- memset(add_list, 0, sizeof(*add_list));
+ memset(add_list, 0, add_list_size);
}
/* Entries from tmp_add_list were cloned from MAC
* filter list, hence clean those cloned entries

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:17 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit c90261dcd86e4eb5c9c1627fde037e902db8aefa ]

Fix crash in fcp command completion path.

Missed null check.

Signed-off-by: Dick Kennedy <dick.k...@avagotech.com>
Signed-off-by: James Smart <james...@avagotech.com>
Reviewed-by: Hannes Reinicke <ha...@suse.de>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/scsi/lpfc/lpfc_scsi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -3908,9 +3908,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba
uint32_t logit = LOG_FCP;

/* Sanity check on return of outstanding command */
- if (!(lpfc_cmd->pCmd))
- return;
cmd = lpfc_cmd->pCmd;
+ if (!cmd)
+ return;
shost = cmd->device->host;

lpfc_cmd->result = (pIocbOut->iocb.un.ulpWord[4] & IOERR_PARAM_MASK);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:19 PM9/12/16
to
Many thanks for the majority of these patches to Sasha Levin, who dug
them out of Canonical's 4.4 kernel tree. I have no idea why they never
sent them in for inclusion on their own :(

This is the start of the stable review cycle for the 4.4.21 release.
There are 192 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.

Responses should be made by Wed Sep 14 15:21:31 UTC 2016.
Anything received after that time might be too late.

The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.21-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y
and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <gre...@linuxfoundation.org>
Linux 4.4.21-rc1

Nicolai Stange <nics...@gmail.com>
lib/mpi: mpi_write_sgl(): fix skipping of leading zero limbs

Mika BÃ¥tsman <mbat...@mvista.com>
regulator: anatop: allow regulator to be in bypass mode

Krzysztof Kozlowski <k.koz...@samsung.com>
hwrng: exynos - Disable runtime PM on probe failure

Sai Gurrappadi <sgurr...@nvidia.com>
cpufreq: Fix GOV_LIMITS handling for the userspace governor

James Hogan <james...@imgtec.com>
metag: Fix atomic_*_return inline asm constraints

Tyrel Datwyler <tyr...@linux.vnet.ibm.com>
scsi: fix upper bounds check of sense key in scsi_sense_key_string()

Vegard Nossum <vegard...@oracle.com>
ALSA: timer: fix NULL pointer dereference on memory allocation failure

Vegard Nossum <vegard...@oracle.com>
ALSA: timer: fix division by zero after SNDRV_TIMER_IOCTL_CONTINUE

Vegard Nossum <vegard...@oracle.com>
ALSA: timer: fix NULL pointer dereference in read()/ioctl() race

Kai-Heng Feng <kai.he...@canonical.com>
ALSA: hda - Enable subwoofer on Dell Inspiron 7559

Shrirang Bagul <shriran...@canonical.com>
ALSA: hda - Add headset mic quirk for Dell Inspiron 5468

Takashi Iwai <ti...@suse.de>
ALSA: rawmidi: Fix possible deadlock with virmidi registration

Takashi Sakamoto <o-ta...@sakamocchi.jp>
ALSA: fireworks: accessing to user space outside spinlock

Takashi Sakamoto <o-ta...@sakamocchi.jp>
ALSA: firewire-tascam: accessing to user space outside spinlock

Ken Lin <ken...@advantech.com.tw>
ALSA: usb-audio: Add sample rate inquiry quirk for B850V3 CP2114

Horia Geantă <horia....@nxp.com>
crypto: caam - fix IV loading for authenc (giv)decryption

Oleg Nesterov <ol...@redhat.com>
uprobes: Fix the memcg accounting

Wanpeng Li <wanpe...@hotmail.com>
x86/apic: Do not init irq remapping if ioapic is disabled

Benjamin Coddington <bcod...@redhat.com>
vhost/scsi: fix reuse of &vq->iov[out] in response

Kent Overstreet <kent.ov...@gmail.com>
bcache: RESERVE_PRIO is too small by one when prio_buckets() is a power of two.

Vincent Stehlé <vincent...@intel.com>
ubifs: Fix assertion in layout_in_gaps()

Miklos Szeredi <msze...@redhat.com>
ovl: fix workdir creation

Miklos Szeredi <msze...@redhat.com>
ovl: listxattr: use strnlen()

Miklos Szeredi <msze...@redhat.com>
ovl: remove posix_acl_default from workdir

Miklos Szeredi <msze...@redhat.com>
ovl: don't copy up opaqueness

Al Viro <vi...@zeniv.linux.org.uk>
wrappers for ->i_mutex access

Al Viro <vi...@zeniv.linux.org.uk>
lustre: remove unused declaration

John Stultz <john....@linaro.org>
timekeeping: Avoid taking lock in NMI path with CONFIG_DEBUG_TIMEKEEPING

John Stultz <john....@linaro.org>
timekeeping: Cap array access in timekeeping_debug

Dave Chinner <dchi...@redhat.com>
xfs: fix superblock inprogress check

Christoph Huber <c.h...@bct-electronic.com>
ASoC: atmel_ssc_dai: Don't unconditionally reset SSC on stream startup

Rob Clark <robd...@gmail.com>
drm/msm: fix use of copy_from_user() while holding spinlock

Daniel Vetter <daniel...@ffwll.ch>
drm: Reject page_flip for !DRIVER_MODESET

Christian König <christia...@amd.com>
drm/radeon: fix radeon_move_blit on 32bit systems

Martin Schwidefsky <schwi...@de.ibm.com>
s390/sclp_ctl: fix potential information leak with /dev/sclp

Kangjie Lu <kang...@gmail.com>
rds: fix an infoleak in rds_inc_info_copy

Michael Neuling <mi...@neuling.org>
powerpc/tm: Avoid SLB faults in treclaim/trecheckpoint when RI=0

Gabriel Krisman Bertazi <kri...@linux.vnet.ibm.com>
nvme: Call pci_disable_device on the error path.

Balbir Singh <bsing...@gmail.com>
cgroup: reduce read locked section of cgroup_threadgroup_rwsem during fork

Ming Lei <ming...@canonical.com>
block: make sure a big bio is split into at most 256 bvecs

Bart Van Assche <bart.va...@sandisk.com>
block: Fix race triggered by blk_set_queue_dying()

Daeho Jeong <daeho...@samsung.com>
ext4: avoid modifying checksum fields directly during checksum verification

Jan Kara <ja...@suse.cz>
ext4: avoid deadlock when expanding inode size

Jan Kara <ja...@suse.cz>
ext4: properly align shifted xattrs when expanding inodes

Jan Kara <ja...@suse.cz>
ext4: fix xattr shifting when expanding inodes part 2

Jan Kara <ja...@suse.cz>
ext4: fix xattr shifting when expanding inodes

Theodore Ts'o <ty...@mit.edu>
ext4: validate that metadata blocks do not overlap superblock

Tyler Hicks <tyh...@canonical.com>
net: Use ns_capable_noaudit() when determining net sysctl permissions

Tyler Hicks <tyh...@canonical.com>
kernel: Add noaudit variant of ns_capable()

David Howells <dhow...@redhat.com>
KEYS: Fix ASN.1 indefinite length object parsing

Jake Oshins <ja...@microsoft.com>
drivers:hv: Lock access to hyperv_mmio resource tree

Manoj N. Kumar <ma...@linux.vnet.ibm.com>
cxlflash: Move to exponential back-off when cmd_room is not available

Florian Westphal <f...@strlen.de>
netfilter: x_tables: check for size overflow

Alex Deucher <alexande...@amd.com>
drm/amdgpu/cz: enable/disable vce dpm even if vce pg is disabled

Seth Forshee <seth.f...@canonical.com>
cred: Reject inodes with invalid ids in set_create_file_as()

Seth Forshee <seth.f...@canonical.com>
fs: Check for invalid i_uid in may_follow_link()

Carol L Soto <cls...@linux.vnet.ibm.com>
IB/IPoIB: Do not set skb truesize since using one linearskb

Eric Dumazet <edum...@google.com>
udp: properly support MSG_PEEK with truncated buffers

Haren Myneni <ha...@linux.vnet.ibm.com>
crypto: nx-842 - Mask XERS0 bit in return value

Matthew R. Ochs <mro...@linux.vnet.ibm.com>
cxlflash: Fix to avoid virtual LUN failover failure

Manoj Kumar <ma...@linux.vnet.ibm.com>
cxlflash: Fix to escalate LINK_RESET also on port 1

Richard Alpe <richar...@ericsson.com>
tipc: fix nl compat regression for link statistics

Kangjie Lu <kang...@gmail.com>
tipc: fix an infoleak in tipc_nl_compat_link_dump

Florian Westphal <f...@strlen.de>
netfilter: x_tables: check for size overflow

Tedd Ho-Jeong An <ted...@intel.com>
Bluetooth: Add support for Intel Bluetooth device 8265 [8087:0a2b]

Ville Syrjälä <ville....@linux.intel.com>
drm/i915: Check VBT for port presence in addition to the strap on VLV/CHV

Chris Wilson <ch...@chris-wilson.co.uk>
drm/i915: Only ignore eDP ports that are connected

Pavel Rojtberg <rojt...@gmail.com>
Input: xpad - move pending clear to the correct location

Sunil Goutham <sgou...@cavium.com>
net: thunderx: Fix link status reporting

Vitaly Kuznetsov <vkuz...@redhat.com>
x86/hyperv: Avoid reporting bogus NMI status for Gen2 instances

Leonidas Da Silva Barbosa <leos...@linux.vnet.ibm.com>
crypto: vmx - IV size failing on skcipher API

Matthias Schwarzott <zz...@gentoo.org>
tda10071: Fix dependency to REGMAP_I2C

Anton Blanchard <an...@samba.org>
crypto: vmx - Fix ABI detection

Paulo Flabiano Smorigo <pfsm...@linux.vnet.ibm.com>
crypto: vmx - comply with ABIs that specify vrsave as reserved.

Benjamin Tissoires <benjamin....@redhat.com>
HID: core: prevent out-of-bound readings

James Smart <james...@broadcom.com>
lpfc: Fix DMA faults observed upon plugging loopback connector

Christoph Hellwig <h...@lst.de>
block: fix blk_rq_get_max_sectors for driver private requests

Ganapatrao Kulkarni <gkul...@caviumnetworks.com>
irqchip/gicv3-its: numa: Enable workaround for Cavium thunderx erratum 23144

Vitaly Kuznetsov <vkuz...@redhat.com>
clocksource: Allow unregistering the watchdog

Zhao Lei <zha...@cn.fujitsu.com>
btrfs: Continue write in case of can_not_nocow

Keith Busch <keith...@intel.com>
blk-mq: End unstarted requests on dying queue

Manoj N. Kumar <ma...@linux.vnet.ibm.com>
cxlflash: Fix to resolve dead-lock during EEH recovery

Dave Airlie <air...@redhat.com>
drm/radeon/mst: fix regression in lane/link handling.

Al Viro <vi...@zeniv.linux.org.uk>
ecryptfs: fix handling of directory opening

Maruthi Srinivas Bayyavarapu <Maruthi.B...@amd.com>
ALSA: hda: add AMD Polaris-10/11 AZ PCI IDs with proper driver caps

Chris Wilson <ch...@chris-wilson.co.uk>
drm: Balance error path for GEM handle allocation

John Stultz <john....@linaro.org>
ntp: Fix ADJ_SETOFFSET being used w/ ADJ_NANO

John Stultz <john....@linaro.org>
time: Verify time values in adjtimex ADJ_SETOFFSET to avoid overflow

Pavel Rojtberg <rojt...@gmail.com>
Input: xpad - correctly handle concurrent LED and FF requests

Sunil Goutham <sgou...@cavium.com>
net: thunderx: Fix receive packet stats

Sunil Goutham <sgou...@cavium.com>
net: thunderx: Fix for multiqset not configured upon interface toggle

Vikas Shivappa <vikas.s...@linux.intel.com>
perf/x86/cqm: Fix CQM memory leak and notifier leak

Vikas Shivappa <vikas.s...@linux.intel.com>
perf/x86/cqm: Fix CQM handling of grouping events into a cache_group

Harald Freudenberger <fre...@linux.vnet.ibm.com>
s390/crypto: provide correct file mode at device register.

Johannes Weiner <han...@cmpxchg.org>
proc: revert /proc/<pid>/maps [stack:TID] annotation

Dasaratharaman Chandramouli <dasaratharama...@intel.com>
intel_idle: Support for Intel Xeon Phi Processor x200 Product Family

Manoj N. Kumar <ma...@linux.vnet.ibm.com>
cxlflash: Fix to avoid unnecessary scan with internal LUNs

Vitaly Kuznetsov <vkuz...@redhat.com>
Drivers: hv: vmbus: don't manipulate with clocksources on crash

Vitaly Kuznetsov <vkuz...@redhat.com>
Drivers: hv: vmbus: avoid scheduling in interrupt context in vmbus_initiate_unload()

Vitaly Kuznetsov <vkuz...@redhat.com>
Drivers: hv: vmbus: avoid infinite loop in init_vp_index()

Ching Huang <chin...@areca.com.tw>
arcmsr: fixes not release allocated resource

Ching Huang <chin...@areca.com.tw>
arcmsr: fixed getting wrong configuration data

Gerald Schaefer <gerald....@de.ibm.com>
s390/pci_dma: fix DMA table corruption with > 4 TB main memory

Gal Pressman <ga...@mellanox.com>
net/mlx5e: Don't modify CQ before it was created

Gal Pressman <ga...@mellanox.com>
net/mlx5e: Don't try to modify CQ moderation if it is not supported

Adrian Hunter <adrian...@intel.com>
mmc: sdhci: Do not BUG on invalid vdd

Aviv Greenberg <avi...@gmail.com>
UVC: Add support for R200 depth camera

Gavin Guo <gavi...@canonical.com>
sched/numa: Fix use-after-free bug in the task_numa_compare

Libin Yang <libin...@linux.intel.com>
ALSA: hda - add codec support for Kabylake display audio codec

Ville Syrjälä <ville....@linux.intel.com>
drm/i915: Fix hpd live status bits for g4x

Parthasarathy Bhuvaragan <parthasarath...@ericsson.com>
tipc: fix nullptr crash during subscription cancel

Andrew Pinski <api...@cavium.com>
arm64: Add workaround for Cavium erratum 27456

Sunil Goutham <sgou...@cavium.com>
net: thunderx: Fix for Qset error due to CQ full

Alex Deucher <alexande...@amd.com>
drm/radeon: fix dp link rate selection (v2)

Alex Deucher <alexande...@amd.com>
drm/amdgpu: fix dp link rate selection (v2)

Swapnil Nagle <swapni...@purestorage.com>
qla2xxx: Use ATIO type to send correct tmr response

Adrian Hunter <adrian...@intel.com>
mmc: sdhci: 64-bit DMA actually has 4-byte alignment

Maarten Lankhorst <maarten....@linux.intel.com>
drm/atomic: Do not unset crtc when an encoder is stolen

Michał Winiarski <michal.w...@intel.com>
drm/i915/skl: Add missing SKL ids

Imre Deak <imre...@intel.com>
drm/i915/bxt: update list of PCIIDs

Marc Zyngier <marc.z...@arm.com>
hrtimer: Catch illegal clockids

Anjali Singhai Jain <anjali....@intel.com>
i40e/i40evf: Fix RSS rx-flow-hash configuration through ethtool

Suganath prabu Subramani <suganath-pra...@avagotech.com>
mpt3sas: Fix for Asynchronous completion of timedout IO and task abort of timedout IO.

Tomas Henzl <the...@redhat.com>
mpt3sas: A correction in unmap_resources

Colin Ian King <colin...@canonical.com>
net: cavium: liquidio: fix check for in progress flag

Tirumalesh Chalamarla <tchal...@caviumnetworks.com>
arm64: KVM: Configure TCR_EL2.PS at runtime

Tirumalesh Chalamarla <tchal...@caviumnetworks.com>
irqchip/gic-v3: Make sure read from ICC_IAR1_EL1 is visible on redestributor

Vladimir Zapolskiy <v...@mleia.com>
pwm: lpc32xx: fix and simplify duty cycle and period calculations

Vladimir Zapolskiy <v...@mleia.com>
pwm: lpc32xx: correct number of PWM channels from 2 to 1

Stefan Agner <ste...@agner.ch>
pwm: fsl-ftm: Fix clock enable/disable when using PM

Tomas Henzl <the...@redhat.com>
megaraid_sas: Add an i/o barrier

Sumit Saxena <sumit....@avagotech.com>
megaraid_sas: Fix SMAP issue

Sumit Saxena <sumit....@avagotech.com>
megaraid_sas: Do not allow PCI access during OCR

Sebastian Ott <seb...@linux.vnet.ibm.com>
s390/cio: update measurement characteristics

Sebastian Ott <seb...@linux.vnet.ibm.com>
s390/cio: ensure consistent measurement state

Sebastian Ott <seb...@linux.vnet.ibm.com>
s390/cio: fix measurement characteristics memleak

Ursula Braun <ubr...@linux.vnet.ibm.com>
qeth: initialize net_device with carrier off

James Smart <james...@avagotech.com>
lpfc: Fix external loopback failure.

James Smart <james...@avagotech.com>
lpfc: Fix mbox reuse in PLOGI completion

James Smart <james...@avagotech.com>
lpfc: Fix RDP Speed reporting.

James Smart <james...@avagotech.com>
lpfc: Fix crash in fcp command completion path.

James Smart <james...@avagotech.com>
lpfc: Fix driver crash when module parameter lpfc_fcp_io_channel set to 16

James Smart <james...@avagotech.com>
lpfc: Fix RegLogin failed error seen on Lancer FC during port bounce

James Smart <james...@avagotech.com>
lpfc: Fix the FLOGI discovery logic to comply with T11 standards

James Smart <james...@avagotech.com>
lpfc: Fix FCF Infinite loop in lpfc_sli4_fcf_rr_next_index_get.

Uma Krishnan <ukr...@linux.vnet.ibm.com>
cxl: Enable PCI device ID for future IBM CXL adapter

Brian Norris <computer...@gmail.com>
cxl: fix build for GCC 4.6.x

Manoj Kumar <ma...@linux.vnet.ibm.com>
cxlflash: Enable device id for future IBM CXL adapter

Manoj Kumar <ma...@linux.vnet.ibm.com>
cxlflash: Resolve oops in wait_port_offline

Manoj Kumar <ma...@linux.vnet.ibm.com>
cxlflash: Fix to resolve cmd leak after host reset

Vaibhav Jain <vai...@linux.vnet.ibm.com>
cxl: Fix DSI misses when the context owning task exits

Vaibhav Jain <vai...@linux.vnet.ibm.com>
cxl: Fix possible idr warning when contexts are released

Dexuan Cui <de...@microsoft.com>
Drivers: hv: vmbus: fix rescind-offer handling for device without a driver

Dexuan Cui <de...@microsoft.com>
Drivers: hv: vmbus: serialize process_chn_event() and vmbus_close_internal()

Olaf Hering <ol...@aepfle.de>
Drivers: hv: vss: run only on supported host versions

Andrey Smetanin <asme...@virtuozzo.com>
drivers/hv: cleanup synic msrs if vmbus connect failed

Olaf Hering <ol...@aepfle.de>
Drivers: hv: util: catch allocation errors

Olaf Hering <ol...@aepfle.de>
tools: hv: report ENOSPC errors in hv_fcopy_daemon

Olaf Hering <ol...@aepfle.de>
Drivers: hv: utils: run polling callback always in interrupt context

K. Y. Srinivasan <k...@microsoft.com>
Drivers: hv: util: Increase the timeout for util services

Matias Bjørling <m...@bjorling.me>
lightnvm: fix missing grown bad block type

Wenwei Tao <ww.ta...@gmail.com>
lightnvm: fix locking and mempool in rrpc_lun_gc

Wenwei Tao <ww.ta...@gmail.com>
lightnvm: unlock rq and free ppa_list on submission fail

Javier Gonzalez <jav...@javigon.com>
lightnvm: add check after mempool allocation

Chao Yu <chao...@samsung.com>
lightnvm: fix incorrect nr_free_blocks stat

Wenwei Tao <ww.ta...@gmail.com>
lightnvm: fix bio submission issue

Dan Carpenter <dan.ca...@oracle.com>
cxlflash: a couple off by one bugs

Alexander Duyck <adu...@mirantis.com>
fm10k: Cleanup exception handling for mailbox interrupt

Alexander Duyck <adu...@mirantis.com>
fm10k: Cleanup MSI-X interrupts in case of failure

Jacob Keller <jacob.e...@intel.com>
fm10k: reinitialize queuing scheme after calling init_hw

Jacob Keller <jacob.e...@intel.com>
fm10k: always check init_hw for errors

Jacob Keller <jacob.e...@intel.com>
fm10k: reset max_queues on init_hw_vf failure

Alexander Duyck <adu...@mirantis.com>
fm10k: Fix handling of NAPI budget when multiple queues are enabled per vector

Jacob Keller <jacob.e...@intel.com>
fm10k: Correct MTU for jumbo frames

Jacob Keller <jacob.e...@intel.com>
fm10k: do not assume VF always has 1 queue

Loc Ho <l...@apm.com>
clk: xgene: Fix divider with non-zero shift value

Dmitry Fleytman <dmi...@daynix.com>
e1000e: fix division by zero on jumbo MTUs

Dmitriy Vyukov <dvy...@google.com>
e1000: fix data race between tx_ring->next_to_clean

Alexander Duyck <adu...@mirantis.com>
ixgbe: Fix handling of NAPI budget when multiple queues are enabled per vector

Jan Beulich <JBeu...@suse.com>
igb: fix NULL derefs due to skipped SR-IOV enabling

Todd Fujinaka <todd.f...@intel.com>
igb: use the correct i210 register for EEMNGCTL

Jarod Wilson <ja...@redhat.com>
igb: don't unmap NULL hw_addr

Anjali Singhai Jain <anjali....@intel.com>
i40e: Fix Rx hash reported to the stack by our driver

Shannon Nelson <shannon...@intel.com>
i40e: clean whole mac filter list

Mitch Williams <mitch.a....@intel.com>
i40evf: check rings before freeing resources

Mitch Williams <mitch.a....@intel.com>
i40e: don't add zero MAC filter

Mitch Williams <mitch.a....@intel.com>
i40e: properly delete VF MAC filters

Kiran Patil <kiran...@intel.com>
i40e: Fix memory leaks, sideband filter programming

Jesse Brandeburg <jesse.br...@intel.com>
i40e: fix: do not sleep in netdev_ops

Anjali Singhai Jain <anjali....@intel.com>
i40e/i40evf: Fix RS bit update in Tx path and disable force WB workaround

Mitch Williams <mitch.a....@intel.com>
i40evf: handle many MAC filters correctly

Anjali Singhai Jain <anjali....@intel.com>
i40e: Workaround fix for mss < 256 issue


-------------

Diffstat:

Documentation/filesystems/proc.txt | 9 +-
Makefile | 4 +-
arch/arm64/Kconfig | 20 ++
arch/arm64/include/asm/arch_gicv3.h | 1 +
arch/arm64/include/asm/cpufeature.h | 3 +-
arch/arm64/include/asm/kvm_arm.h | 2 -
arch/arm64/kernel/cpu_errata.c | 9 +
arch/arm64/kvm/hyp-init.S | 13 +-
arch/arm64/mm/proc.S | 12 +
arch/metag/include/asm/atomic_lnkget.h | 2 +-
arch/powerpc/include/asm/icswx.h | 1 +
arch/powerpc/kernel/tm.S | 61 +++-
arch/s390/crypto/prng.c | 2 +
arch/s390/include/asm/pci_dma.h | 2 +
arch/s390/pci/pci.c | 3 +-
arch/s390/pci/pci_dma.c | 19 +-
arch/x86/kernel/apic/apic.c | 3 +
arch/x86/kernel/cpu/mshyperv.c | 12 +
arch/x86/kernel/cpu/perf_event_intel_cqm.c | 56 +++-
block/blk-core.c | 4 +-
block/blk-merge.c | 22 ++
block/blk-mq.c | 6 +-
drivers/bluetooth/btusb.c | 11 +-
drivers/char/hw_random/exynos-rng.c | 9 +-
drivers/clk/clk-xgene.c | 3 +-
drivers/cpufreq/cpufreq_userspace.c | 43 ++-
drivers/crypto/caam/caamalg.c | 77 ++---
drivers/crypto/nx/nx-842-powernv.c | 12 +-
drivers/crypto/vmx/aes_cbc.c | 2 +-
drivers/crypto/vmx/aes_ctr.c | 2 +-
drivers/crypto/vmx/ppc-xlate.pl | 20 ++
drivers/gpu/drm/amd/amdgpu/atombios_dp.c | 96 ++----
drivers/gpu/drm/amd/amdgpu/cz_dpm.c | 4 +-
drivers/gpu/drm/drm_atomic_helper.c | 4 -
drivers/gpu/drm/drm_crtc.c | 3 +
drivers/gpu/drm/drm_gem.c | 29 +-
drivers/gpu/drm/i915/i915_drv.h | 3 +
drivers/gpu/drm/i915/i915_reg.h | 15 +-
drivers/gpu/drm/i915/intel_bios.c | 39 +++
drivers/gpu/drm/i915/intel_display.c | 40 ++-
drivers/gpu/drm/i915/intel_dp.c | 26 +-
drivers/gpu/drm/i915/intel_drv.h | 2 +-
drivers/gpu/drm/i915/intel_hdmi.c | 3 +
drivers/gpu/drm/msm/msm_gem_submit.c | 27 +-
drivers/gpu/drm/radeon/atombios_dp.c | 108 ++----
drivers/gpu/drm/radeon/radeon_dp_mst.c | 4 +-
drivers/gpu/drm/radeon/radeon_mode.h | 6 +-
drivers/gpu/drm/radeon/radeon_ttm.c | 4 +-
drivers/hid/hid-core.c | 3 +
drivers/hv/channel.c | 27 +-
drivers/hv/channel_mgmt.c | 61 +++-
drivers/hv/hv.c | 10 +-
drivers/hv/hv_fcopy.c | 37 +-
drivers/hv/hv_kvp.c | 31 +-
drivers/hv/hv_snapshot.c | 34 +-
drivers/hv/hv_utils_transport.c | 9 +-
drivers/hv/hyperv_vmbus.h | 11 +-
drivers/hv/vmbus_drv.c | 35 +-
drivers/idle/intel_idle.c | 25 ++
drivers/infiniband/ulp/ipoib/ipoib_ib.c | 2 -
drivers/input/joystick/xpad.c | 322 ++++++++++++------
drivers/irqchip/irq-gic-v3-its.c | 49 ++-
drivers/lightnvm/gennvm.c | 3 +-
drivers/lightnvm/rrpc.c | 24 +-
drivers/md/bcache/super.c | 2 +-
drivers/media/dvb-frontends/Kconfig | 2 +-
drivers/media/usb/uvc/uvc_driver.c | 20 ++
drivers/media/usb/uvc/uvcvideo.h | 12 +
drivers/misc/cxl/Makefile | 2 +-
drivers/misc/cxl/api.c | 6 +-
drivers/misc/cxl/context.c | 15 +-
drivers/misc/cxl/cxl.h | 15 +
drivers/misc/cxl/fault.c | 129 +++++--
drivers/misc/cxl/file.c | 25 +-
drivers/misc/cxl/pci.c | 1 +
drivers/mmc/host/sdhci.c | 35 +-
drivers/mmc/host/sdhci.h | 21 +-
drivers/net/ethernet/cavium/liquidio/lio_main.c | 2 +-
drivers/net/ethernet/cavium/thunder/nic.h | 9 +
drivers/net/ethernet/cavium/thunder/nic_main.c | 6 +
drivers/net/ethernet/cavium/thunder/nic_reg.h | 2 +-
drivers/net/ethernet/cavium/thunder/nicvf_main.c | 12 +-
drivers/net/ethernet/cavium/thunder/nicvf_queues.c | 8 +-
drivers/net/ethernet/cavium/thunder/nicvf_queues.h | 3 +-
drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 91 +++--
drivers/net/ethernet/cavium/thunder/thunder_bgx.h | 2 +
drivers/net/ethernet/intel/e1000/e1000.h | 7 +-
drivers/net/ethernet/intel/e1000/e1000_main.c | 5 +-
drivers/net/ethernet/intel/e1000e/netdev.c | 6 +-
drivers/net/ethernet/intel/fm10k/fm10k.h | 2 +-
drivers/net/ethernet/intel/fm10k/fm10k_main.c | 8 +-
drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 65 +++-
drivers/net/ethernet/intel/fm10k/fm10k_type.h | 1 +
drivers/net/ethernet/intel/fm10k/fm10k_vf.c | 16 +-
drivers/net/ethernet/intel/i40e/i40e.h | 2 +
drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 14 +-
drivers/net/ethernet/intel/i40e/i40e_main.c | 126 +++++--
drivers/net/ethernet/intel/i40e/i40e_txrx.c | 73 ++--
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 23 +-
drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 182 ++++++----
drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 2 +
drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c | 40 +--
drivers/net/ethernet/intel/i40evf/i40evf_main.c | 6 +
.../net/ethernet/intel/i40evf/i40evf_virtchnl.c | 32 +-
drivers/net/ethernet/intel/igb/e1000_82575.c | 1 +
drivers/net/ethernet/intel/igb/e1000_i210.c | 27 ++
drivers/net/ethernet/intel/igb/e1000_i210.h | 1 +
drivers/net/ethernet/intel/igb/e1000_regs.h | 1 +
drivers/net/ethernet/intel/igb/igb.h | 2 +
drivers/net/ethernet/intel/igb/igb_main.c | 17 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +-
.../net/ethernet/mellanox/mlx5/core/en_ethtool.c | 12 +
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 12 +-
drivers/nvme/host/pci.c | 2 +-
drivers/pwm/pwm-fsl-ftm.c | 58 ++--
drivers/pwm/pwm-lpc32xx.c | 55 ++-
drivers/regulator/anatop-regulator.c | 2 +-
drivers/s390/char/sclp_ctl.c | 12 +-
drivers/s390/cio/chp.c | 21 +-
drivers/s390/cio/chp.h | 2 +-
drivers/s390/cio/chsc.c | 43 +--
drivers/s390/net/qeth_l2_main.c | 1 +
drivers/s390/net/qeth_l3_main.c | 1 +
drivers/scsi/arcmsr/arcmsr_hba.c | 26 +-
drivers/scsi/constants.c | 5 +-
drivers/scsi/cxlflash/common.h | 2 +
drivers/scsi/cxlflash/main.c | 69 +++-
drivers/scsi/cxlflash/main.h | 4 +-
drivers/scsi/cxlflash/superpipe.c | 19 +-
drivers/scsi/cxlflash/vlun.c | 2 +
drivers/scsi/lpfc/lpfc_crtn.h | 1 +
drivers/scsi/lpfc/lpfc_els.c | 373 ++++++++++-----------
drivers/scsi/lpfc/lpfc_hbadisc.c | 20 +-
drivers/scsi/lpfc/lpfc_init.c | 9 +-
drivers/scsi/lpfc/lpfc_mbox.c | 10 +-
drivers/scsi/lpfc/lpfc_nportdisc.c | 134 +++++---
drivers/scsi/lpfc/lpfc_scsi.c | 4 +-
drivers/scsi/lpfc/lpfc_sli.c | 23 +-
drivers/scsi/megaraid/megaraid_sas.h | 2 +
drivers/scsi/megaraid/megaraid_sas_base.c | 268 +++++----------
drivers/scsi/megaraid/megaraid_sas_fusion.c | 1 +
drivers/scsi/mpt3sas/mpt3sas_base.c | 24 +-
drivers/scsi/mpt3sas/mpt3sas_base.h | 5 +-
drivers/scsi/mpt3sas/mpt3sas_ctl.c | 2 +-
drivers/scsi/mpt3sas/mpt3sas_scsih.c | 12 +-
drivers/scsi/qla2xxx/qla_target.c | 2 +-
.../staging/lustre/lustre/llite/llite_internal.h | 2 -
drivers/vhost/scsi.c | 6 +-
fs/btrfs/file.c | 37 +-
fs/ecryptfs/file.c | 71 +++-
fs/ext4/inode.c | 40 ++-
fs/ext4/namei.c | 9 +-
fs/ext4/super.c | 36 +-
fs/ext4/xattr.c | 66 ++--
fs/namei.c | 4 +-
fs/overlayfs/copy_up.c | 2 +
fs/overlayfs/inode.c | 19 +-
fs/overlayfs/overlayfs.h | 1 +
fs/overlayfs/super.c | 19 ++
fs/proc/task_mmu.c | 66 ++--
fs/proc/task_nommu.c | 49 ++-
fs/ubifs/tnc_commit.c | 2 +-
fs/xfs/libxfs/xfs_sb.c | 3 +-
include/drm/i915_pciids.h | 6 +-
include/linux/blkdev.h | 2 +-
include/linux/capability.h | 5 +
include/linux/fs.h | 29 +-
include/linux/lightnvm.h | 5 +-
include/linux/mm.h | 3 +-
include/linux/perf_event.h | 1 +
include/linux/time.h | 26 ++
include/uapi/linux/hyperv.h | 1 +
include/uapi/linux/videodev2.h | 3 +
include/uapi/scsi/cxlflash_ioctl.h | 10 +
kernel/capability.c | 46 ++-
kernel/cred.c | 2 +
kernel/events/uprobes.c | 5 +-
kernel/fork.c | 4 +-
kernel/sched/fair.c | 30 +-
kernel/time/clocksource.c | 52 ++-
kernel/time/hrtimer.c | 7 +-
kernel/time/ntp.c | 20 +-
kernel/time/timekeeping.c | 7 +-
kernel/time/timekeeping_debug.c | 9 +-
lib/asn1_decoder.c | 16 +-
lib/mpi/mpicoder.c | 21 +-
mm/util.c | 27 +-
net/ipv4/udp.c | 6 +-
net/ipv6/udp.c | 6 +-
net/netfilter/x_tables.c | 6 +
net/rds/recv.c | 2 +
net/sysctl_net.c | 2 +-
net/tipc/netlink_compat.c | 3 +-
net/tipc/subscr.c | 3 +-
sound/core/rawmidi.c | 4 +-
sound/core/timer.c | 20 +-
sound/firewire/fireworks/fireworks.h | 1 -
sound/firewire/fireworks/fireworks_hwdep.c | 71 ++--
sound/firewire/fireworks/fireworks_proc.c | 4 +-
sound/firewire/fireworks/fireworks_transaction.c | 5 +-
sound/firewire/tascam/tascam-hwdep.c | 33 +-
sound/pci/hda/hda_intel.c | 4 +
sound/pci/hda/patch_hdmi.c | 5 +-
sound/pci/hda/patch_realtek.c | 15 +
sound/soc/atmel/atmel_ssc_dai.c | 5 +-
sound/usb/quirks.c | 1 +
tools/hv/hv_fcopy_daemon.c | 20 +-
207 files changed, 3034 insertions(+), 1812 deletions(-)

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:19 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 9d5de93f6d543b356e39e225988ef443a7bce34c ]

The driver may not be able to set the power correctly but that
is not a reason to BUG().

Signed-off-by: Adrian Hunter <adrian...@intel.com>
Reviewed-by: Venu Byravarasu <vbyra...@nvidia.com>
Signed-off-by: Ulf Hansson <ulf.h...@linaro.org>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/mmc/host/sdhci.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1315,7 +1315,9 @@ static void sdhci_set_power(struct sdhci
pwr = SDHCI_POWER_330;
break;
default:
- BUG();
+ WARN(1, "%s: Invalid vdd %#x\n",
+ mmc_hostname(host->mmc), vdd);
+ break;
}
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:21 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 0e8d5b5975401c83641efd5d4595e6cdbe9e9e2f ]

VF drivers must detect how many queues are available. Previously, the
driver assumed that each VF has at minimum 1 queue. This assumption is
incorrect, since it is possible that the PF has not yet assigned the
queues to the VF by the time the VF checks. To resolve this, we added a
check first to ensure that the first queue is infact owned by the VF at
init_hw_vf time. However, the code flow did not reset hw->mac.max_queues
to 0. In some cases, such as during reinit flows, we call init_hw_vf
without clearing the previous value of hw->mac.max_queues. Due to this,
when init_hw_vf errors out, if its error code is not properly handled
the VF driver may still believe it has queues which no longer belong to
it. Fix this by clearing the hw->mac.max_queues on exit due to errors.

Signed-off-by: Jacob Keller <jacob.e...@intel.com>
Reviewed-by: Bruce Allan <bruce....@intel.com>
Tested-by: Krishneil Singh <Krishnei...@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey....@intel.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/net/ethernet/intel/fm10k/fm10k_vf.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)

--- a/drivers/net/ethernet/intel/fm10k/fm10k_vf.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_vf.c
@@ -105,8 +105,10 @@ static s32 fm10k_init_hw_vf(struct fm10k

/* verify we have at least 1 queue */
if (!~fm10k_read_reg(hw, FM10K_TXQCTL(0)) ||
- !~fm10k_read_reg(hw, FM10K_RXQCTL(0)))
- return FM10K_ERR_NO_RESOURCES;
+ !~fm10k_read_reg(hw, FM10K_RXQCTL(0))) {
+ err = FM10K_ERR_NO_RESOURCES;
+ goto reset_max_queues;
+ }

/* determine how many queues we have */
for (i = 1; tqdloc0 && (i < FM10K_MAX_QUEUES_POOL); i++) {
@@ -124,7 +126,7 @@ static s32 fm10k_init_hw_vf(struct fm10k
/* shut down queues we own and reset DMA configuration */
err = fm10k_disable_queues_generic(hw, i);
if (err)
- return err;
+ goto reset_max_queues;

/* record maximum queue count */
hw->mac.max_queues = i;
@@ -134,6 +136,11 @@ static s32 fm10k_init_hw_vf(struct fm10k
FM10K_TXQCTL_VID_MASK) >> FM10K_TXQCTL_VID_SHIFT;

return 0;
+
+reset_max_queues:
+ hw->mac.max_queues = 0;
+
+ return err;
}

/* This structure defines the attibutes to be parsed below */

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:28 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 11c71cb4ab7cd901b9d6f0ff267c102778c1c8ef ]

This patch will do synhronization between OCR function and AEN function
using "reset_mutex" lock. reset_mutex will be acquired only in the
first half of the AEN function which issues a DCMD. Second half of the
function which calls SCSI API (scsi_add_device/scsi_remove_device)
should be out of reset_mutex to avoid deadlock between scsi_eh thread
and driver.

During chip reset (inside OCR function), there should not be any PCI
access and AEN function (which is called in delayed context) may be
firing DCMDs (doing PCI writes) when chip reset is happening in parallel
which will cause FW fault. This patch will solve the problem by making
AEN thread and OCR thread mutually exclusive.

Signed-off-by: Sumit Saxena <sumit....@avagotech.com>
Signed-off-by: Kashyap Desai <kashya...@avagotech.com>
Reviewed-by: Tomas Henzl <the...@redhat.com>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/scsi/megaraid/megaraid_sas.h | 2
drivers/scsi/megaraid/megaraid_sas_base.c | 254 +++++++++---------------------
2 files changed, 82 insertions(+), 174 deletions(-)

--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1083,6 +1083,8 @@ struct megasas_ctrl_info {

#define VD_EXT_DEBUG 0

+#define SCAN_PD_CHANNEL 0x1
+#define SCAN_VD_CHANNEL 0x2

enum MR_SCSI_CMD_TYPE {
READ_WRITE_LDIO = 0,
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -5476,7 +5476,6 @@ static int megasas_probe_one(struct pci_
spin_lock_init(&instance->hba_lock);
spin_lock_init(&instance->completion_lock);

- mutex_init(&instance->aen_mutex);
mutex_init(&instance->reset_mutex);

/*
@@ -6443,10 +6442,10 @@ static int megasas_mgmt_ioctl_aen(struct
}
spin_unlock_irqrestore(&instance->hba_lock, flags);

- mutex_lock(&instance->aen_mutex);
+ mutex_lock(&instance->reset_mutex);
error = megasas_register_aen(instance, aen.seq_num,
aen.class_locale_word);
- mutex_unlock(&instance->aen_mutex);
+ mutex_unlock(&instance->reset_mutex);
return error;
}

@@ -6648,6 +6647,7 @@ megasas_aen_polling(struct work_struct *
int i, j, doscan = 0;
u32 seq_num, wait_time = MEGASAS_RESET_WAIT_TIME;
int error;
+ u8 dcmd_ret = 0;

if (!instance) {
printk(KERN_ERR "invalid instance!\n");
@@ -6660,16 +6660,7 @@ megasas_aen_polling(struct work_struct *
wait_time = MEGASAS_ROUTINE_WAIT_TIME_VF;

/* Don't run the event workqueue thread if OCR is running */
- for (i = 0; i < wait_time; i++) {
- if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL)
- break;
- if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
- dev_notice(&instance->pdev->dev, "%s waiting for "
- "controller reset to finish for scsi%d\n",
- __func__, instance->host->host_no);
- }
- msleep(1000);
- }
+ mutex_lock(&instance->reset_mutex);

instance->ev = NULL;
host = instance->host;
@@ -6677,212 +6668,127 @@ megasas_aen_polling(struct work_struct *
megasas_decode_evt(instance);

switch (le32_to_cpu(instance->evt_detail->code)) {
- case MR_EVT_PD_INSERTED:
- if (megasas_get_pd_list(instance) == 0) {
- for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
- for (j = 0;
- j < MEGASAS_MAX_DEV_PER_CHANNEL;
- j++) {
-
- pd_index =
- (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
-
- sdev1 = scsi_device_lookup(host, i, j, 0);
-
- if (instance->pd_list[pd_index].driveState
- == MR_PD_STATE_SYSTEM) {
- if (!sdev1)
- scsi_add_device(host, i, j, 0);
-
- if (sdev1)
- scsi_device_put(sdev1);
- }
- }
- }
- }
- doscan = 0;
- break;

+ case MR_EVT_PD_INSERTED:
case MR_EVT_PD_REMOVED:
- if (megasas_get_pd_list(instance) == 0) {
- for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
- for (j = 0;
- j < MEGASAS_MAX_DEV_PER_CHANNEL;
- j++) {
-
- pd_index =
- (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
-
- sdev1 = scsi_device_lookup(host, i, j, 0);
-
- if (instance->pd_list[pd_index].driveState
- == MR_PD_STATE_SYSTEM) {
- if (sdev1)
- scsi_device_put(sdev1);
- } else {
- if (sdev1) {
- scsi_remove_device(sdev1);
- scsi_device_put(sdev1);
- }
- }
- }
- }
- }
- doscan = 0;
+ dcmd_ret = megasas_get_pd_list(instance);
+ if (dcmd_ret == 0)
+ doscan = SCAN_PD_CHANNEL;
break;

case MR_EVT_LD_OFFLINE:
case MR_EVT_CFG_CLEARED:
case MR_EVT_LD_DELETED:
- if (!instance->requestorId ||
- megasas_get_ld_vf_affiliation(instance, 0)) {
- if (megasas_ld_list_query(instance,
- MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
- megasas_get_ld_list(instance);
- for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
- for (j = 0;
- j < MEGASAS_MAX_DEV_PER_CHANNEL;
- j++) {
-
- ld_index =
- (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
-
- sdev1 = scsi_device_lookup(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
-
- if (instance->ld_ids[ld_index]
- != 0xff) {
- if (sdev1)
- scsi_device_put(sdev1);
- } else {
- if (sdev1) {
- scsi_remove_device(sdev1);
- scsi_device_put(sdev1);
- }
- }
- }
- }
- doscan = 0;
- }
- break;
case MR_EVT_LD_CREATED:
if (!instance->requestorId ||
- megasas_get_ld_vf_affiliation(instance, 0)) {
- if (megasas_ld_list_query(instance,
- MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
- megasas_get_ld_list(instance);
- for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
- for (j = 0;
- j < MEGASAS_MAX_DEV_PER_CHANNEL;
- j++) {
- ld_index =
- (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
-
- sdev1 = scsi_device_lookup(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
-
- if (instance->ld_ids[ld_index]
- != 0xff) {
- if (!sdev1)
- scsi_add_device(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
- }
- if (sdev1)
- scsi_device_put(sdev1);
- }
- }
- doscan = 0;
- }
+ (instance->requestorId && megasas_get_ld_vf_affiliation(instance, 0)))
+ dcmd_ret = megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST);
+
+ if (dcmd_ret == 0)
+ doscan = SCAN_VD_CHANNEL;
+
break;
+
case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
case MR_EVT_FOREIGN_CFG_IMPORTED:
case MR_EVT_LD_STATE_CHANGE:
- doscan = 1;
+ dcmd_ret = megasas_get_pd_list(instance);
+
+ if (dcmd_ret != 0)
+ break;
+
+ if (!instance->requestorId ||
+ (instance->requestorId && megasas_get_ld_vf_affiliation(instance, 0)))
+ dcmd_ret = megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST);
+
+ if (dcmd_ret != 0)
+ break;
+
+ doscan = SCAN_VD_CHANNEL | SCAN_PD_CHANNEL;
+ dev_info(&instance->pdev->dev, "scanning for scsi%d...\n",
+ instance->host->host_no);
break;
+
case MR_EVT_CTRL_PROP_CHANGED:
- megasas_get_ctrl_info(instance);
- break;
+ dcmd_ret = megasas_get_ctrl_info(instance);
+ break;
default:
doscan = 0;
break;
}
} else {
dev_err(&instance->pdev->dev, "invalid evt_detail!\n");
+ mutex_unlock(&instance->reset_mutex);
kfree(ev);
return;
}

- if (doscan) {
- dev_info(&instance->pdev->dev, "scanning for scsi%d...\n",
- instance->host->host_no);
- if (megasas_get_pd_list(instance) == 0) {
- for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
- for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
- pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j;
- sdev1 = scsi_device_lookup(host, i, j, 0);
- if (instance->pd_list[pd_index].driveState ==
- MR_PD_STATE_SYSTEM) {
- if (!sdev1) {
- scsi_add_device(host, i, j, 0);
- }
- if (sdev1)
- scsi_device_put(sdev1);
- } else {
- if (sdev1) {
- scsi_remove_device(sdev1);
- scsi_device_put(sdev1);
- }
+ mutex_unlock(&instance->reset_mutex);
+
+ if (doscan & SCAN_PD_CHANNEL) {
+ for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
+ for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
+ pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j;
+ sdev1 = scsi_device_lookup(host, i, j, 0);
+ if (instance->pd_list[pd_index].driveState ==
+ MR_PD_STATE_SYSTEM) {
+ if (!sdev1)
+ scsi_add_device(host, i, j, 0);
+ else
+ scsi_device_put(sdev1);
+ } else {
+ if (sdev1) {
+ scsi_remove_device(sdev1);
+ scsi_device_put(sdev1);
}
}
}
}
+ }

- if (!instance->requestorId ||
- megasas_get_ld_vf_affiliation(instance, 0)) {
- if (megasas_ld_list_query(instance,
- MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
- megasas_get_ld_list(instance);
- for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
- for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL;
- j++) {
- ld_index =
- (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
-
- sdev1 = scsi_device_lookup(host,
- MEGASAS_MAX_PD_CHANNELS + i, j, 0);
- if (instance->ld_ids[ld_index]
- != 0xff) {
- if (!sdev1)
- scsi_add_device(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
- else
- scsi_device_put(sdev1);
- } else {
- if (sdev1) {
- scsi_remove_device(sdev1);
- scsi_device_put(sdev1);
- }
+ if (doscan & SCAN_VD_CHANNEL) {
+ for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
+ for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
+ ld_index = (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
+ sdev1 = scsi_device_lookup(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
+ if (instance->ld_ids[ld_index] != 0xff) {
+ if (!sdev1)
+ scsi_add_device(host, MEGASAS_MAX_PD_CHANNELS + i, j, 0);
+ else
+ scsi_device_put(sdev1);
+ } else {
+ if (sdev1) {
+ scsi_remove_device(sdev1);
+ scsi_device_put(sdev1);
}
}
}
}
}

- if (instance->aen_cmd != NULL) {
- kfree(ev);
- return ;
- }
-
- seq_num = le32_to_cpu(instance->evt_detail->seq_num) + 1;
+ if (dcmd_ret == 0)
+ seq_num = le32_to_cpu(instance->evt_detail->seq_num) + 1;
+ else
+ seq_num = instance->last_seq_num;

/* Register AEN with FW for latest sequence number plus 1 */
class_locale.members.reserved = 0;
class_locale.members.locale = MR_EVT_LOCALE_ALL;
class_locale.members.class = MR_EVT_CLASS_DEBUG;
- mutex_lock(&instance->aen_mutex);
+
+ if (instance->aen_cmd != NULL) {
+ kfree(ev);
+ return;
+ }
+
+ mutex_lock(&instance->reset_mutex);
error = megasas_register_aen(instance, seq_num,
class_locale.word);
- mutex_unlock(&instance->aen_mutex);
-
if (error)
- dev_err(&instance->pdev->dev, "register aen failed error %x\n", error);
+ dev_err(&instance->pdev->dev,
+ "register aen failed error %x\n", error);

+ mutex_unlock(&instance->reset_mutex);
kfree(ev);
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:10:28 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit d7236ac368212bd6fc8b45f050136ee53e6a6f2d ]

The function value inside se_cmd can change if the TMR is cancelled.
Use original ATIO Type to correctly determine CTIO response.

Signed-off-by: Swapnil Nagle <swapni...@purestroage.com>
Signed-off-by: Himanshu Madhani <himanshu...@qlogic.com>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/scsi/qla2xxx/qla_target.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1578,7 +1578,7 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt
qlt_send_notify_ack(vha, &mcmd->orig_iocb.imm_ntfy,
0, 0, 0, 0, 0, 0);
else {
- if (mcmd->se_cmd.se_tmr_req->function == TMR_ABORT_TASK)
+ if (mcmd->orig_iocb.atio.u.raw.entry_type == ABTS_RECV_24XX)
qlt_24xx_send_abts_resp(vha, &mcmd->orig_iocb.abts,
mcmd->fc_tm_rsp, false);
else

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:12:07 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 81e7517723fc17396ba91f59312b3177266ddbda ]

Fix RDP Speed reporting.

Signed-off-by: Dick Kennedy <dick.k...@avagotech.com>
Signed-off-by: James Smart <james...@avagotech.com>
Reviewed-by: Hannes Reinicke <ha...@suse.de>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/scsi/lpfc/lpfc_els.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)

--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -4698,28 +4698,25 @@ lpfc_rdp_res_speed(struct fc_rdp_port_sp

desc->tag = cpu_to_be32(RDP_PORT_SPEED_DESC_TAG);

- switch (phba->sli4_hba.link_state.speed) {
- case LPFC_FC_LA_SPEED_1G:
+ switch (phba->fc_linkspeed) {
+ case LPFC_LINK_SPEED_1GHZ:
rdp_speed = RDP_PS_1GB;
break;
- case LPFC_FC_LA_SPEED_2G:
+ case LPFC_LINK_SPEED_2GHZ:
rdp_speed = RDP_PS_2GB;
break;
- case LPFC_FC_LA_SPEED_4G:
+ case LPFC_LINK_SPEED_4GHZ:
rdp_speed = RDP_PS_4GB;
break;
- case LPFC_FC_LA_SPEED_8G:
+ case LPFC_LINK_SPEED_8GHZ:
rdp_speed = RDP_PS_8GB;
break;
- case LPFC_FC_LA_SPEED_10G:
+ case LPFC_LINK_SPEED_10GHZ:
rdp_speed = RDP_PS_10GB;
break;
- case LPFC_FC_LA_SPEED_16G:
+ case LPFC_LINK_SPEED_16GHZ:
rdp_speed = RDP_PS_16GB;
break;
- case LPFC_FC_LA_SPEED_32G:
- rdp_speed = RDP_PS_32GB;
- break;
default:
rdp_speed = RDP_PS_UNKNOWN;
break;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:07 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------


From: Seth Forshee <seth.f...@canonical.com>

[ Upstream commit 5f65e5ca286126a60f62c8421b77c2018a482b8a ]

Using INVALID_[UG]ID for the LSM file creation context doesn't
make sense, so return an error if the inode passed to
set_create_file_as() has an invalid id.

Signed-off-by: Seth Forshee <seth.f...@canonical.com>
Acked-by: Serge Hallyn <serge....@canonical.com>
Signed-off-by: Eric W. Biederman <ebie...@xmission.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
kernel/cred.c | 2 ++
1 file changed, 2 insertions(+)

--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -689,6 +689,8 @@ EXPORT_SYMBOL(set_security_override_from
*/
int set_create_files_as(struct cred *new, struct inode *inode)
{
+ if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
+ return -EINVAL;
new->fsuid = inode->i_uid;
new->fsgid = inode->i_gid;
return security_kernel_create_files_as(new, inode);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:08 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tyler Hicks <tyh...@canonical.com>

commit 98f368e9e2630a3ce3e80fb10fb2e02038cf9578 upstream.

When checking the current cred for a capability in a specific user
namespace, it isn't always desirable to have the LSMs audit the check.
This patch adds a noaudit variant of ns_capable() for when those
situations arise.

The common logic between ns_capable() and the new ns_capable_noaudit()
is moved into a single, shared function to keep duplicated code to a
minimum and ease maintainability.

Signed-off-by: Tyler Hicks <tyh...@canonical.com>
Acked-by: Serge E. Hallyn <serge....@ubuntu.com>
Signed-off-by: James Morris <james.l...@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
include/linux/capability.h | 5 ++++
kernel/capability.c | 46 +++++++++++++++++++++++++++++++++++----------
2 files changed, 41 insertions(+), 10 deletions(-)

--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -214,6 +214,7 @@ extern bool has_ns_capability_noaudit(st
struct user_namespace *ns, int cap);
extern bool capable(int cap);
extern bool ns_capable(struct user_namespace *ns, int cap);
+extern bool ns_capable_noaudit(struct user_namespace *ns, int cap);
#else
static inline bool has_capability(struct task_struct *t, int cap)
{
@@ -241,6 +242,10 @@ static inline bool ns_capable(struct use
{
return true;
}
+static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap)
+{
+ return true;
+}
#endif /* CONFIG_MULTIUSER */
extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -361,6 +361,24 @@ bool has_capability_noaudit(struct task_
return has_ns_capability_noaudit(t, &init_user_ns, cap);
}

+static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit)
+{
+ int capable;
+
+ if (unlikely(!cap_valid(cap))) {
+ pr_crit("capable() called with invalid cap=%u\n", cap);
+ BUG();
+ }
+
+ capable = audit ? security_capable(current_cred(), ns, cap) :
+ security_capable_noaudit(current_cred(), ns, cap);
+ if (capable == 0) {
+ current->flags |= PF_SUPERPRIV;
+ return true;
+ }
+ return false;
+}
+
/**
* ns_capable - Determine if the current task has a superior capability in effect
* @ns: The usernamespace we want the capability in
@@ -374,19 +392,27 @@ bool has_capability_noaudit(struct task_
*/
bool ns_capable(struct user_namespace *ns, int cap)
{
- if (unlikely(!cap_valid(cap))) {
- pr_crit("capable() called with invalid cap=%u\n", cap);
- BUG();
- }
-
- if (security_capable(current_cred(), ns, cap) == 0) {
- current->flags |= PF_SUPERPRIV;
- return true;
- }
- return false;
+ return ns_capable_common(ns, cap, true);
}
EXPORT_SYMBOL(ns_capable);

+/**
+ * ns_capable_noaudit - Determine if the current task has a superior capability
+ * (unaudited) in effect
+ * @ns: The usernamespace we want the capability in
+ * @cap: The capability to be tested for
+ *
+ * Return true if the current task has the given superior capability currently
+ * available for use, false if not.
+ *
+ * This sets PF_SUPERPRIV on the task if the capability is available on the
+ * assumption that it's about to be used.
+ */
+bool ns_capable_noaudit(struct user_namespace *ns, int cap)
+{
+ return ns_capable_common(ns, cap, false);
+}
+EXPORT_SYMBOL(ns_capable_noaudit);

/**
* capable - Determine if the current task has a superior capability in effect

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:08 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oleg Nesterov <ol...@redhat.com>

commit 6c4687cc17a788a6dd8de3e27dbeabb7cbd3e066 upstream.

__replace_page() wronlgy calls mem_cgroup_cancel_charge() in "success" path,
it should only do this if page_check_address() fails.

This means that every enable/disable leads to unbalanced mem_cgroup_uncharge()
from put_page(old_page), it is trivial to underflow the page_counter->count
and trigger OOM.

Reported-and-tested-by: Brenden Blanco <bbl...@plumgrid.com>
Signed-off-by: Oleg Nesterov <ol...@redhat.com>
Reviewed-by: Johannes Weiner <han...@cmpxchg.org>
Acked-by: Michal Hocko <mho...@kernel.org>
Cc: Alexander Shishkin <alexander...@linux.intel.com>
Cc: Alexei Starovoitov <alexei.st...@gmail.com>
Cc: Arnaldo Carvalho de Melo <ac...@kernel.org>
Cc: Arnaldo Carvalho de Melo <ac...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Linus Torvalds <torv...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <tg...@linutronix.de>
Cc: Vladimir Davydov <vdav...@virtuozzo.com>
Fixes: 00501b531c47 ("mm: memcontrol: rewrite charge API")
Link: http://lkml.kernel.org/r/20160817153...@redhat.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
kernel/events/uprobes.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -171,8 +171,10 @@ static int __replace_page(struct vm_area
mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
err = -EAGAIN;
ptep = page_check_address(page, mm, addr, &ptl, 0);
- if (!ptep)
+ if (!ptep) {
+ mem_cgroup_cancel_charge(kpage, memcg);
goto unlock;
+ }

get_page(kpage);
page_add_new_anon_rmap(kpage, vma, addr);
@@ -199,7 +201,6 @@ static int __replace_page(struct vm_area

err = 0;
unlock:
- mem_cgroup_cancel_charge(kpage, memcg);
mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
unlock_page(page);
return err;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:08 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------


From: "Manoj N. Kumar" <ma...@linux.vnet.ibm.com>

[ Upstream commit ea76543127da32dec28af0a13ea1b06625fc085e ]

While profiling the cxlflash_queuecommand() path under a heavy load it
was found that number of retries to find cmd_room was fairly high.

There are two problems with the current back-off:
a) It starts with a udelay of 0
b) It backs-off linearly

Tried several approaches (a higher multiple 10*n, 100*n, as well as n^2,
2^n) and found that the exponential back-off(2^n) approach had the least
overall cost. Cost as being defined as overall time spent waiting.

The fix is to change the linear back-off to an exponential back-off.
This solution also takes care of the problem with the initial
delay (starts with 1 usec).

Signed-off-by: Manoj N. Kumar <ma...@linux.vnet.ibm.com>
Acked-by: Matthew R. Ochs <mro...@linux.vnet.ibm.com>
Reviewed-by: Johannes Thumshirn <jthum...@suse.de>
Signed-off-by: Uma Krishnan <ukr...@linux.vnet.ibm.com>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/scsi/cxlflash/main.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

--- a/drivers/scsi/cxlflash/main.c
+++ b/drivers/scsi/cxlflash/main.c
@@ -289,7 +289,7 @@ static void context_reset(struct afu_cmd
atomic64_set(&afu->room, room);
if (room)
goto write_rrin;
- udelay(nretry);
+ udelay(1 << nretry);
} while (nretry++ < MC_ROOM_RETRY_CNT);

pr_err("%s: no cmd_room to send reset\n", __func__);
@@ -303,7 +303,7 @@ write_rrin:
if (rrin != 0x1)
break;
/* Double delay each time */
- udelay(2 << nretry);
+ udelay(1 << nretry);
} while (nretry++ < MC_ROOM_RETRY_CNT);
}

@@ -338,7 +338,7 @@ retry:
atomic64_set(&afu->room, room);
if (room)
goto write_ioarrin;
- udelay(nretry);
+ udelay(1 << nretry);
} while (nretry++ < MC_ROOM_RETRY_CNT);

dev_err(dev, "%s: no cmd_room to send 0x%X\n",
@@ -352,7 +352,7 @@ retry:
* afu->room.
*/
if (nretry++ < MC_ROOM_RETRY_CNT) {
- udelay(nretry);
+ udelay(1 << nretry);
goto retry;
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:08 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit dd4e17ab704269bce71402285f5e8b9ac24b1eff ]

Recently, in commit 37cf4dc3370f I forgot to check if the timeval being passed
was actually a timespec (as is signaled with ADJ_NANO).

This resulted in that patch breaking ADJ_SETOFFSET users who set
ADJ_NANO, by rejecting valid timespecs that were compared with
valid timeval ranges.

This patch addresses this by checking for the ADJ_NANO flag and
using the timepsec check instead in that case.

Reported-by: Harald Hoyer <har...@redhat.com>
Reported-by: Kay Sievers <k...@vrfy.org>
Fixes: 37cf4dc3370f "time: Verify time values in adjtimex ADJ_SETOFFSET to avoid overflow"
Signed-off-by: John Stultz <john....@linaro.org>
Cc: Sasha Levin <sasha...@oracle.com>
Cc: Richard Cochran <richard...@gmail.com>
Cc: Prarit Bhargava <pra...@redhat.com>
Cc: David Herrmann <dh.he...@gmail.com>
Link: http://lkml.kernel.org/r/1453417415-19110-2-git...@linaro.org
Signed-off-by: Thomas Gleixner <tg...@linutronix.de>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
kernel/time/ntp.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)

--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -679,8 +679,18 @@ int ntp_validate_timex(struct timex *txc
if (!capable(CAP_SYS_TIME))
return -EPERM;

- if (!timeval_inject_offset_valid(&txc->time))
- return -EINVAL;
+ if (txc->modes & ADJ_NANO) {
+ struct timespec ts;
+
+ ts.tv_sec = txc->time.tv_sec;
+ ts.tv_nsec = txc->time.tv_usec;
+ if (!timespec_inject_offset_valid(&ts))
+ return -EINVAL;
+
+ } else {
+ if (!timeval_inject_offset_valid(&txc->time))
+ return -EINVAL;
+ }
}

/*

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:08 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Benjamin Coddington <bcod...@redhat.com>

commit a77ec83a57890240c546df00ca5df1cdeedb1cc3 upstream.

The address of the iovec &vq->iov[out] is not guaranteed to contain the scsi
command's response iovec throughout the lifetime of the command. Rather, it
is more likely to contain an iovec from an immediately following command
after looping back around to vhost_get_vq_desc(). Pass along the iovec
entirely instead.

Fixes: 79c14141a487 ("vhost/scsi: Convert completion path to use copy_to_iter")
Signed-off-by: Benjamin Coddington <bcod...@redhat.com>
Signed-off-by: Michael S. Tsirkin <m...@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
drivers/vhost/scsi.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -88,7 +88,7 @@ struct vhost_scsi_cmd {
struct scatterlist *tvc_prot_sgl;
struct page **tvc_upages;
/* Pointer to response header iovec */
- struct iovec *tvc_resp_iov;
+ struct iovec tvc_resp_iov;
/* Pointer to vhost_scsi for our device */
struct vhost_scsi *tvc_vhost;
/* Pointer to vhost_virtqueue for the cmd */
@@ -557,7 +557,7 @@ static void vhost_scsi_complete_cmd_work
memcpy(v_rsp.sense, cmd->tvc_sense_buf,
se_cmd->scsi_sense_length);

- iov_iter_init(&iov_iter, READ, cmd->tvc_resp_iov,
+ iov_iter_init(&iov_iter, READ, &cmd->tvc_resp_iov,
cmd->tvc_in_iovs, sizeof(v_rsp));
ret = copy_to_iter(&v_rsp, sizeof(v_rsp), &iov_iter);
if (likely(ret == sizeof(v_rsp))) {
@@ -1054,7 +1054,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *
}
cmd->tvc_vhost = vs;
cmd->tvc_vq = vq;
- cmd->tvc_resp_iov = &vq->iov[out];
+ cmd->tvc_resp_iov = vq->iov[out];
cmd->tvc_in_iovs = in;

pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n",

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:08 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit a0af53b511423cca93900066512379e21586d7dd ]

This patch adds support for Intel Bluetooth device 8265 also known
as Windstorm Peak (WsP).

T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 6 Spd=12 MxCh= 0
D: Ver= 2.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=8087 ProdID=0a2b Rev= 0.10
C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=1ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms

Signed-off-by: Tedd Ho-Jeong An <ted...@intel.com>
Signed-off-by: Marcel Holtmann <mar...@holtmann.org>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/bluetooth/btusb.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)

--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -2056,12 +2056,13 @@ static int btusb_setup_intel_new(struct
return -EINVAL;
}

- /* At the moment only the hardware variant iBT 3.0 (LnP/SfP) is
- * supported by this firmware loading method. This check has been
- * put in place to ensure correct forward compatibility options
- * when newer hardware variants come along.
+ /* At the moment the iBT 3.0 hardware variants 0x0b (LnP/SfP)
+ * and 0x0c (WsP) are supported by this firmware loading method.
+ *
+ * This check has been put in place to ensure correct forward
+ * compatibility options when newer hardware variants come along.
*/
- if (ver->hw_variant != 0x0b) {
+ if (ver->hw_variant != 0x0b && ver->hw_variant != 0x0c) {
BT_ERR("%s: Unsupported Intel hardware variant (%u)",
hdev->name, ver->hw_variant);
kfree_skb(skb);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:08 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Kai-Heng Feng <kai.he...@canonical.com>

commit fd06c77eb9200b53d421da5fffe0dcd894b5d72a upstream.

The subwoofer on Inspiron 7559 was disabled originally.
Applying a pin fixup to node 0x1b can enable it and make it work.

Old pin: 0x411111f0
New pin: 0x90170151

Signed-off-by: Kai-Heng Feng <kai.he...@canonical.com>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
sound/pci/hda/patch_realtek.c | 11 +++++++++++
1 file changed, 11 insertions(+)

--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4840,6 +4840,7 @@ enum {
ALC221_FIXUP_HP_FRONT_MIC,
ALC292_FIXUP_TPT460,
ALC298_FIXUP_SPK_VOLUME,
+ ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
};

static const struct hda_fixup alc269_fixups[] = {
@@ -5501,6 +5502,15 @@ static const struct hda_fixup alc269_fix
.chained = true,
.chain_id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
},
+ [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = (const struct hda_pintbl[]) {
+ { 0x1b, 0x90170151 },
+ { }
+ },
+ .chained = true,
+ .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
+ },
};

static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -5545,6 +5555,7 @@ static const struct snd_pci_quirk alc269
SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
+ SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:09 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 5f985d88bac34e7f3b4403118eab072902a0b392 ]

It might happen that we try to free an already freed pointer.

Reported-by: Maurizio Lombardi <mlom...@redhat.com>
Signed-off-by: Tomas Henzl <the...@redhat.com>
Acked-by: Chaitra P B <chaitra...@avagotech.com>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/scsi/mpt3sas/mpt3sas_base.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -2020,8 +2020,10 @@ mpt3sas_base_unmap_resources(struct MPT3
_base_free_irq(ioc);
_base_disable_msix(ioc);

- if (ioc->msix96_vector)
+ if (ioc->msix96_vector) {
kfree(ioc->replyPostRegisterIndex);
+ ioc->replyPostRegisterIndex = NULL;
+ }

if (ioc->chip_phys) {
iounmap(ioc->chip);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:09 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 65376df582174ffcec9e6471bf5b0dd79ba05e4a ]

Commit b76437579d13 ("procfs: mark thread stack correctly in
proc/<pid>/maps") added [stack:TID] annotation to /proc/<pid>/maps.

Finding the task of a stack VMA requires walking the entire thread list,
turning this into quadratic behavior: a thousand threads means a
thousand stacks, so the rendering of /proc/<pid>/maps needs to look at a
million combinations.

The cost is not in proportion to the usefulness as described in the
patch.

Drop the [stack:TID] annotation to make /proc/<pid>/maps (and
/proc/<pid>/numa_maps) usable again for higher thread counts.

The [stack] annotation inside /proc/<pid>/task/<tid>/maps is retained, as
identifying the stack VMA there is an O(1) operation.

Siddesh said:
"The end users needed a way to identify thread stacks programmatically and
there wasn't a way to do that. I'm afraid I no longer remember (or have
access to the resources that would aid my memory since I changed
employers) the details of their requirement. However, I did do this on my
own time because I thought it was an interesting project for me and nobody
really gave any feedback then as to its utility, so as far as I am
concerned you could roll back the main thread maps information since the
information is available in the thread-specific files"

Signed-off-by: Johannes Weiner <han...@cmpxchg.org>
Cc: "Kirill A. Shutemov" <kir...@shutemov.name>
Cc: Siddhesh Poyarekar <siddhesh....@gmail.com>
Cc: Shaohua Li <sh...@fb.com>
Signed-off-by: Andrew Morton <ak...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torv...@linux-foundation.org>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
Documentation/filesystems/proc.txt | 9 +----
fs/proc/task_mmu.c | 66 ++++++++++++-------------------------
fs/proc/task_nommu.c | 49 +++++++++++----------------
include/linux/mm.h | 3 -
mm/util.c | 27 ---------------
5 files changed, 48 insertions(+), 106 deletions(-)

--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -346,7 +346,7 @@ address perms offset dev in
a7cb1000-a7cb2000 ---p 00000000 00:00 0
a7cb2000-a7eb2000 rw-p 00000000 00:00 0
a7eb2000-a7eb3000 ---p 00000000 00:00 0
-a7eb3000-a7ed5000 rw-p 00000000 00:00 0 [stack:1001]
+a7eb3000-a7ed5000 rw-p 00000000 00:00 0
a7ed5000-a8008000 r-xp 00000000 03:00 4222 /lib/libc.so.6
a8008000-a800a000 r--p 00133000 03:00 4222 /lib/libc.so.6
a800a000-a800b000 rw-p 00135000 03:00 4222 /lib/libc.so.6
@@ -378,7 +378,6 @@ is not associated with a file:

[heap] = the heap of the program
[stack] = the stack of the main process
- [stack:1001] = the stack of the thread with tid 1001
[vdso] = the "virtual dynamic shared object",
the kernel system call handler

@@ -386,10 +385,8 @@ is not associated with a file:

The /proc/PID/task/TID/maps is a view of the virtual memory from the viewpoint
of the individual tasks of a process. In this file you will see a mapping marked
-as [stack] if that task sees it as a stack. This is a key difference from the
-content of /proc/PID/maps, where you will see all mappings that are being used
-as stack by all of those tasks. Hence, for the example above, the task-level
-map, i.e. /proc/PID/task/TID/maps for thread 1001 will look like this:
+as [stack] if that task sees it as a stack. Hence, for the example above, the
+task-level map, i.e. /proc/PID/task/TID/maps for thread 1001 will look like this:

08048000-08049000 r-xp 00000000 03:00 8312 /opt/test
08049000-0804a000 rw-p 00001000 03:00 8312 /opt/test
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -248,23 +248,29 @@ static int do_maps_open(struct inode *in
sizeof(struct proc_maps_private));
}

-static pid_t pid_of_stack(struct proc_maps_private *priv,
- struct vm_area_struct *vma, bool is_pid)
+/*
+ * Indicate if the VMA is a stack for the given task; for
+ * /proc/PID/maps that is the stack of the main task.
+ */
+static int is_stack(struct proc_maps_private *priv,
+ struct vm_area_struct *vma, int is_pid)
{
- struct inode *inode = priv->inode;
- struct task_struct *task;
- pid_t ret = 0;
+ int stack = 0;
+
+ if (is_pid) {
+ stack = vma->vm_start <= vma->vm_mm->start_stack &&
+ vma->vm_end >= vma->vm_mm->start_stack;
+ } else {
+ struct inode *inode = priv->inode;
+ struct task_struct *task;

- rcu_read_lock();
- task = pid_task(proc_pid(inode), PIDTYPE_PID);
- if (task) {
- task = task_of_stack(task, vma, is_pid);
+ rcu_read_lock();
+ task = pid_task(proc_pid(inode), PIDTYPE_PID);
if (task)
- ret = task_pid_nr_ns(task, inode->i_sb->s_fs_info);
+ stack = vma_is_stack_for_task(vma, task);
+ rcu_read_unlock();
}
- rcu_read_unlock();
-
- return ret;
+ return stack;
}

static void
@@ -324,8 +330,6 @@ show_map_vma(struct seq_file *m, struct

name = arch_vma_name(vma);
if (!name) {
- pid_t tid;
-
if (!mm) {
name = "[vdso]";
goto done;
@@ -337,21 +341,8 @@ show_map_vma(struct seq_file *m, struct
goto done;
}

- tid = pid_of_stack(priv, vma, is_pid);
- if (tid != 0) {
- /*
- * Thread stack in /proc/PID/task/TID/maps or
- * the main process stack.
- */
- if (!is_pid || (vma->vm_start <= mm->start_stack &&
- vma->vm_end >= mm->start_stack)) {
- name = "[stack]";
- } else {
- /* Thread stack in /proc/PID/maps */
- seq_pad(m, ' ');
- seq_printf(m, "[stack:%d]", tid);
- }
- }
+ if (is_stack(priv, vma, is_pid))
+ name = "[stack]";
}

done:
@@ -1566,19 +1557,8 @@ static int show_numa_map(struct seq_file
seq_file_path(m, file, "\n\t= ");
} else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
seq_puts(m, " heap");
- } else {
- pid_t tid = pid_of_stack(proc_priv, vma, is_pid);
- if (tid != 0) {
- /*
- * Thread stack in /proc/PID/task/TID/maps or
- * the main process stack.
- */
- if (!is_pid || (vma->vm_start <= mm->start_stack &&
- vma->vm_end >= mm->start_stack))
- seq_puts(m, " stack");
- else
- seq_printf(m, " stack:%d", tid);
- }
+ } else if (is_stack(proc_priv, vma, is_pid)) {
+ seq_puts(m, " stack");
}

if (is_vm_hugetlb_page(vma))
--- a/fs/proc/task_nommu.c
+++ b/fs/proc/task_nommu.c
@@ -123,23 +123,26 @@ unsigned long task_statm(struct mm_struc
return size;
}

-static pid_t pid_of_stack(struct proc_maps_private *priv,
- struct vm_area_struct *vma, bool is_pid)
+static int is_stack(struct proc_maps_private *priv,
+ struct vm_area_struct *vma, int is_pid)
{
- struct inode *inode = priv->inode;
- struct task_struct *task;
- pid_t ret = 0;
-
- rcu_read_lock();
- task = pid_task(proc_pid(inode), PIDTYPE_PID);
- if (task) {
- task = task_of_stack(task, vma, is_pid);
+ struct mm_struct *mm = vma->vm_mm;
+ int stack = 0;
+
+ if (is_pid) {
+ stack = vma->vm_start <= mm->start_stack &&
+ vma->vm_end >= mm->start_stack;
+ } else {
+ struct inode *inode = priv->inode;
+ struct task_struct *task;
+
+ rcu_read_lock();
+ task = pid_task(proc_pid(inode), PIDTYPE_PID);
if (task)
- ret = task_pid_nr_ns(task, inode->i_sb->s_fs_info);
+ stack = vma_is_stack_for_task(vma, task);
+ rcu_read_unlock();
}
- rcu_read_unlock();
-
- return ret;
+ return stack;
}

/*
@@ -181,21 +184,9 @@ static int nommu_vma_show(struct seq_fil
if (file) {
seq_pad(m, ' ');
seq_file_path(m, file, "");
- } else if (mm) {
- pid_t tid = pid_of_stack(priv, vma, is_pid);
-
- if (tid != 0) {
- seq_pad(m, ' ');
- /*
- * Thread stack in /proc/PID/task/TID/maps or
- * the main process stack.
- */
- if (!is_pid || (vma->vm_start <= mm->start_stack &&
- vma->vm_end >= mm->start_stack))
- seq_printf(m, "[stack]");
- else
- seq_printf(m, "[stack:%d]", tid);
- }
+ } else if (mm && is_stack(priv, vma, is_pid)) {
+ seq_pad(m, ' ');
+ seq_printf(m, "[stack]");
}

seq_putc(m, '\n');
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1311,8 +1311,7 @@ static inline int stack_guard_page_end(s
!vma_growsup(vma->vm_next, addr);
}

-extern struct task_struct *task_of_stack(struct task_struct *task,
- struct vm_area_struct *vma, bool in_group);
+int vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t);

extern unsigned long move_page_tables(struct vm_area_struct *vma,
unsigned long old_addr, struct vm_area_struct *new_vma,
--- a/mm/util.c
+++ b/mm/util.c
@@ -199,36 +199,11 @@ void __vma_link_list(struct mm_struct *m
}

/* Check if the vma is being used as a stack by this task */
-static int vm_is_stack_for_task(struct task_struct *t,
- struct vm_area_struct *vma)
+int vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t)
{
return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t));
}

-/*
- * Check if the vma is being used as a stack.
- * If is_group is non-zero, check in the entire thread group or else
- * just check in the current task. Returns the task_struct of the task
- * that the vma is stack for. Must be called under rcu_read_lock().
- */
-struct task_struct *task_of_stack(struct task_struct *task,
- struct vm_area_struct *vma, bool in_group)
-{
- if (vm_is_stack_for_task(task, vma))
- return task;
-
- if (in_group) {
- struct task_struct *t;
-
- for_each_thread(task, t) {
- if (vm_is_stack_for_task(t, vma))
- return t;
- }
- }
-
- return NULL;
-}
-
#if defined(CONFIG_MMU) && !defined(HAVE_ARCH_PICK_MMAP_LAYOUT)
void arch_pick_mmap_layout(struct mm_struct *mm)
{

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:09 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Martin Schwidefsky <schwi...@de.ibm.com>

commit 532c34b5fbf1687df63b3fcd5b2846312ac943c6 upstream.

The sclp_ctl_ioctl_sccb function uses two copy_from_user calls to
retrieve the sclp request from user space. The first copy_from_user
fetches the length of the request which is stored in the first two
bytes of the request. The second copy_from_user gets the complete
sclp request, but this copies the length field a second time.
A malicious user may have changed the length in the meantime.

Reported-by: Pengfei Wang <wpengf...@gmail.com>
Reviewed-by: Michael Holzheu <hol...@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwi...@de.ibm.com>
Signed-off-by: Juerg Haefliger <juerg.h...@hpe.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
drivers/s390/char/sclp_ctl.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)

--- a/drivers/s390/char/sclp_ctl.c
+++ b/drivers/s390/char/sclp_ctl.c
@@ -56,6 +56,7 @@ static int sclp_ctl_ioctl_sccb(void __us
{
struct sclp_ctl_sccb ctl_sccb;
struct sccb_header *sccb;
+ unsigned long copied;
int rc;

if (copy_from_user(&ctl_sccb, user_area, sizeof(ctl_sccb)))
@@ -65,14 +66,15 @@ static int sclp_ctl_ioctl_sccb(void __us
sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!sccb)
return -ENOMEM;
- if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sizeof(*sccb))) {
+ copied = PAGE_SIZE -
+ copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), PAGE_SIZE);
+ if (offsetof(struct sccb_header, length) +
+ sizeof(sccb->length) > copied || sccb->length > copied) {
rc = -EFAULT;
goto out_free;
}
- if (sccb->length > PAGE_SIZE || sccb->length < 8)
- return -EINVAL;
- if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sccb->length)) {
- rc = -EFAULT;
+ if (sccb->length < 8) {
+ rc = -EINVAL;
goto out_free;
}
rc = sclp_sync_request(ctl_sccb.cmdw, sccb);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:09 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------


From: Jake Oshins <ja...@microsoft.com>

[ Upstream commit e16dad6bfe1437aaee565f875a6713ca7ce81bdf ]

In existing code, this tree of resources is created
in single-threaded code and never modified after it is
created, and thus needs no locking. This patch introduces
a semaphore for tree access, as other patches in this
series introduce run-time modifications of this resource
tree which can happen on multiple threads.

Signed-off-by: Jake Oshins <ja...@microsoft.com>
Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
---
drivers/hv/vmbus_drv.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)

--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -105,6 +105,7 @@ static struct notifier_block hyperv_pani
};

struct resource *hyperv_mmio;
+DEFINE_SEMAPHORE(hyperv_mmio_lock);

static int vmbus_exists(void)
{
@@ -1140,7 +1141,10 @@ int vmbus_allocate_mmio(struct resource
resource_size_t range_min, range_max, start, local_min, local_max;
const char *dev_n = dev_name(&device_obj->device);
u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
- int i;
+ int i, retval;
+
+ retval = -ENXIO;
+ down(&hyperv_mmio_lock);

for (iter = hyperv_mmio; iter; iter = iter->sibling) {
if ((iter->start >= max) || (iter->end <= min))
@@ -1177,13 +1181,17 @@ int vmbus_allocate_mmio(struct resource
for (; start + size - 1 <= local_max; start += align) {
*new = request_mem_region_exclusive(start, size,
dev_n);
- if (*new)
- return 0;
+ if (*new) {
+ retval = 0;
+ goto exit;
+ }
}
}
}

- return -ENXIO;
+exit:
+ up(&hyperv_mmio_lock);
+ return retval;
}
EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:10 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 603ecce95f4817074a724a889cd88c3c8210f933 ]

When switching to the internal LUN defined on the
IBM CXL flash adapter, there is an unnecessary
scan occurring on the second port. This scan leads
to the following extra lines in the log:

Dec 17 10:09:00 tul83p1 kernel: [ 3708.561134] cxlflash 0008:00:00.0: cxlflash_queuecommand: (scp=c0000000fc1f0f00) 11/1/0/0 cdb=(A0000000-00000000-10000000-00000000)
Dec 17 10:09:00 tul83p1 kernel: [ 3708.561147] process_cmd_err: cmd failed afu_rc=32 scsi_rc=0 fc_rc=0 afu_extra=0xE, scsi_extra=0x0, fc_extra=0x0

By definition, both of the internal LUNs are on the first port/channel.

When the lun_mode is switched to internal LUN the
same value for host->max_channel is retained. This
causes an unnecessary scan over the second port/channel.

This fix alters the host->max_channel to 0 (1 port), if internal
LUNs are configured and switches it back to 1 (2 ports) while
going back to external LUNs.

Signed-off-by: Manoj N. Kumar <ma...@linux.vnet.ibm.com>
Acked-by: Matthew R. Ochs <mro...@linux.vnet.ibm.com>
Reviewed-by: Uma Krishnan <ukr...@linux.vnet.ibm.com>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/scsi/cxlflash/main.c | 10 ++++++++++
1 file changed, 10 insertions(+)

--- a/drivers/scsi/cxlflash/main.c
+++ b/drivers/scsi/cxlflash/main.c
@@ -2149,6 +2149,16 @@ static ssize_t lun_mode_store(struct dev
rc = kstrtouint(buf, 10, &lun_mode);
if (!rc && (lun_mode < 5) && (lun_mode != afu->internal_lun)) {
afu->internal_lun = lun_mode;
+
+ /*
+ * When configured for internal LUN, there is only one channel,
+ * channel number 0, else there will be 2 (default).
+ */
+ if (afu->internal_lun)
+ shost->max_channel = 0;
+ else
+ shost->max_channel = NUM_FC_PORTS - 1;
+
afu_reset(cfg);
scsi_scan_host(cfg->host);
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:10 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 635f6b0893cff193a1774881ebb1e4a4b9a7fead ]

When a cxlflash adapter goes into EEH recovery and multiple processes
(each having established its own context) are active, the EEH recovery
can hang if the processes attempt to recover in parallel. The symptom
logged after a couple of minutes is:

INFO: task eehd:48 blocked for more than 120 seconds.
Not tainted 4.5.0-491-26f710d+ #1
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
eehd 0 48 2
Call Trace:
__switch_to+0x2f0/0x410
__schedule+0x300/0x980
schedule+0x48/0xc0
rwsem_down_write_failed+0x294/0x410
down_write+0x88/0xb0
cxlflash_pci_error_detected+0x100/0x1c0 [cxlflash]
cxl_vphb_error_detected+0x88/0x110 [cxl]
cxl_pci_error_detected+0xb0/0x1d0 [cxl]
eeh_report_error+0xbc/0x130
eeh_pe_dev_traverse+0x94/0x160
eeh_handle_normal_event+0x17c/0x450
eeh_handle_event+0x184/0x370
eeh_event_handler+0x1c8/0x1d0
kthread+0x110/0x130
ret_from_kernel_thread+0x5c/0xa4
INFO: task blockio:33215 blocked for more than 120 seconds.

Not tainted 4.5.0-491-26f710d+ #1
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
blockio 0 33215 33213
Call Trace:
0x1 (unreliable)
__switch_to+0x2f0/0x410
__schedule+0x300/0x980
schedule+0x48/0xc0
rwsem_down_read_failed+0x124/0x1d0
down_read+0x68/0x80
cxlflash_ioctl+0x70/0x6f0 [cxlflash]
scsi_ioctl+0x3b0/0x4c0
sg_ioctl+0x960/0x1010
do_vfs_ioctl+0xd8/0x8c0
SyS_ioctl+0xd4/0xf0
system_call+0x38/0xb4
INFO: task eehd:48 blocked for more than 120 seconds.

The hang is because of a 3 way dead-lock:

Process A holds the recovery mutex, and waits for eehd to complete.
Process B holds the semaphore and waits for the recovery mutex.
eehd waits for semaphore.

The fix is to have Process B above release the semaphore before
attempting to acquire the recovery mutex. This will allow
eehd to proceed to completion.

Signed-off-by: Manoj N. Kumar <ma...@linux.vnet.ibm.com>
Reviewed-by: Matthew R. Ochs <mro...@linux.vnet.ibm.com>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/scsi/cxlflash/superpipe.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)

--- a/drivers/scsi/cxlflash/superpipe.c
+++ b/drivers/scsi/cxlflash/superpipe.c
@@ -1590,6 +1590,13 @@ err1:
* place at the same time and the failure was due to CXL services being
* unable to keep up.
*
+ * As this routine is called on ioctl context, it holds the ioctl r/w
+ * semaphore that is used to drain ioctls in recovery scenarios. The
+ * implementation to achieve the pacing described above (a local mutex)
+ * requires that the ioctl r/w semaphore be dropped and reacquired to
+ * avoid a 3-way deadlock when multiple process recoveries operate in
+ * parallel.
+ *
* Because a user can detect an error condition before the kernel, it is
* quite possible for this routine to act as the kernel's EEH detection
* source (MMIO read of mbox_r). Because of this, there is a window of
@@ -1617,9 +1624,17 @@ static int cxlflash_afu_recover(struct s
int rc = 0;

atomic_inc(&cfg->recovery_threads);
+ up_read(&cfg->ioctl_rwsem);
rc = mutex_lock_interruptible(mutex);
+ down_read(&cfg->ioctl_rwsem);
if (rc)
goto out;
+ rc = check_state(cfg);
+ if (rc) {
+ dev_err(dev, "%s: Failed state! rc=%d\n", __func__, rc);
+ rc = -ENODEV;
+ goto out;
+ }

dev_dbg(dev, "%s: reason 0x%016llX rctxid=%016llX\n",
__func__, recover->reason, rctxid);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:10 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: James Hogan <james...@imgtec.com>

commit 096a8b6d5e7ab9f8ca3d2474b3ca6a1fe79e0371 upstream.

The argument i of atomic_*_return() operations is given to inline asm
with the "bd" constraint, which means "An Op2 register where Op1 is a
data unit register and the instruction supports O2R", however Op1 is
constrained by "da" which allows an address unit register to be used.

Fix the constraint to use "br", meaning "An Op2 register and the
instruction supports O2R", i.e. not requiring Op1 to be a data unit
register.

Fixes: d6dfe2509da9 ("locking,arch,metag: Fold atomic_ops")
Signed-off-by: James Hogan <james...@imgtec.com>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: linux...@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
arch/metag/include/asm/atomic_lnkget.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/metag/include/asm/atomic_lnkget.h
+++ b/arch/metag/include/asm/atomic_lnkget.h
@@ -61,7 +61,7 @@ static inline int atomic_##op##_return(i
" CMPT %0, #HI(0x02000000)\n" \
" BNZ 1b\n" \
: "=&d" (temp), "=&da" (result) \
- : "da" (&v->counter), "bd" (i) \
+ : "da" (&v->counter), "br" (i) \
: "cc"); \
\
smp_mb(); \

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:10 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit f21018427cb007a0894c36ad702990ab639cbbb4 ]

Driver private request types should not get the artifical cap for the
FS requests. This is important to use the full device capabilities
for internal command or NVMe pass through commands.

Signed-off-by: Christoph Hellwig <h...@lst.de>
Reported-by: Jeff Lien <Jeff...@hgst.com>
Tested-by: Jeff Lien <Jeff...@hgst.com>
Reviewed-by: Keith Busch <keith...@intel.com>

Updated by me to use an explicit check for the one command type that
does support extended checking, instead of relying on the ordering
of the enum command values - as suggested by Keith.

Signed-off-by: Jens Axboe <ax...@fb.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
include/linux/blkdev.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -890,7 +890,7 @@ static inline unsigned int blk_rq_get_ma
{
struct request_queue *q = rq->q;

- if (unlikely(rq->cmd_type == REQ_TYPE_BLOCK_PC))
+ if (unlikely(rq->cmd_type != REQ_TYPE_FS))
return q->limits.max_hw_sectors;

if (!q->limits.chunk_sectors || (rq->cmd_flags & REQ_DISCARD))

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:10 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 50220dead1650609206efe91f0cc116132d59b3f ]

Plugging a Logitech DJ receiver with KASAN activated raises a bunch of
out-of-bound readings.

The fields are allocated up to MAX_USAGE, meaning that potentially, we do
not have enough fields to fit the incoming values.
Add checks and silence KASAN.

Signed-off-by: Benjamin Tissoires <benjamin....@redhat.com>
Signed-off-by: Jiri Kosina <jko...@suse.cz>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/hid/hid-core.c | 3 +++
1 file changed, 3 insertions(+)

--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1251,6 +1251,7 @@ static void hid_input_field(struct hid_d
/* Ignore report if ErrorRollOver */
if (!(field->flags & HID_MAIN_ITEM_VARIABLE) &&
value[n] >= min && value[n] <= max &&
+ value[n] - min < field->maxusage &&
field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1)
goto exit;
}
@@ -1263,11 +1264,13 @@ static void hid_input_field(struct hid_d
}

if (field->value[n] >= min && field->value[n] <= max
+ && field->value[n] - min < field->maxusage
&& field->usage[field->value[n] - min].hid
&& search(value, field->value[n], count))
hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt);

if (value[n] >= min && value[n] <= max
+ && value[n] - min < field->maxusage
&& field->usage[value[n] - min].hid
&& search(field->value, value[n], count))
hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:10 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit ae09c765109293b600ba9169aa3d632e1ac1a843 ]

Driver didn't program the REG_VFI mailbox correctly, giving the adapter
bad addresses.

Signed-off-by: Dick Kennedy <dick.k...@avagotech.com>
Signed-off-by: James Smart <james...@avagotech.com>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/scsi/lpfc/lpfc_mbox.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -2145,10 +2145,12 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, str
reg_vfi->wwn[1] = cpu_to_le32(reg_vfi->wwn[1]);
reg_vfi->e_d_tov = phba->fc_edtov;
reg_vfi->r_a_tov = phba->fc_ratov;
- reg_vfi->bde.addrHigh = putPaddrHigh(phys);
- reg_vfi->bde.addrLow = putPaddrLow(phys);
- reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam);
- reg_vfi->bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+ if (phys) {
+ reg_vfi->bde.addrHigh = putPaddrHigh(phys);
+ reg_vfi->bde.addrLow = putPaddrLow(phys);
+ reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam);
+ reg_vfi->bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+ }
bf_set(lpfc_reg_vfi_nport_id, reg_vfi, vport->fc_myDID);

/* Only FC supports upd bit */

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:10 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miklos Szeredi <msze...@redhat.com>

commit 7cb35119d067191ce9ebc380a599db0b03cbd9d9 upstream.

Be defensive about what underlying fs provides us in the returned xattr
list buffer. If it's not properly null terminated, bail out with a warning
insead of BUG.

Signed-off-by: Miklos Szeredi <msze...@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
fs/overlayfs/inode.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)

--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -277,7 +277,8 @@ ssize_t ovl_listxattr(struct dentry *den
struct path realpath;
enum ovl_path_type type = ovl_path_real(dentry, &realpath);
ssize_t res;
- int off;
+ size_t len;
+ char *s;

res = vfs_listxattr(realpath.dentry, list, size);
if (res <= 0 || size == 0)
@@ -287,17 +288,19 @@ ssize_t ovl_listxattr(struct dentry *den
return res;

/* filter out private xattrs */
- for (off = 0; off < res;) {
- char *s = list + off;
- size_t slen = strlen(s) + 1;
+ for (s = list, len = res; len;) {
+ size_t slen = strnlen(s, len) + 1;

- BUG_ON(off + slen > res);
+ /* underlying fs providing us with an broken xattr list? */
+ if (WARN_ON(slen > len))
+ return -EIO;

+ len -= slen;
if (ovl_is_private_xattr(s)) {
res -= slen;
- memmove(s, s + slen, res - off);
+ memmove(s, s + slen, len);
} else {
- off += slen;
+ s += slen;
}
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:10 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 37cf4dc3370fbca0344e23bb96446eb2c3548ba7 ]

For adjtimex()'s ADJ_SETOFFSET, make sure the tv_usec value is
sane. We might multiply them later which can cause an overflow
and undefined behavior.

This patch introduces new helper functions to simplify the
checking code and adds comments to clarify

Orginally this patch was by Sasha Levin, but I've basically
rewritten it, so he should get credit for finding the issue
and I should get the blame for any mistakes made since.

Also, credit to Richard Cochran for the phrasing used in the
comment for what is considered valid here.

Cc: Sasha Levin <sasha...@oracle.com>
Cc: Richard Cochran <richard...@gmail.com>
Cc: Thomas Gleixner <tg...@linutronix.de>
Reported-by: Sasha Levin <sasha...@oracle.com>
Signed-off-by: John Stultz <john....@linaro.org>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
include/linux/time.h | 26 ++++++++++++++++++++++++++
kernel/time/ntp.c | 10 ++++++++--
kernel/time/timekeeping.c | 2 +-
3 files changed, 35 insertions(+), 3 deletions(-)

--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -125,6 +125,32 @@ static inline bool timeval_valid(const s

extern struct timespec timespec_trunc(struct timespec t, unsigned gran);

+/*
+ * Validates if a timespec/timeval used to inject a time offset is valid.
+ * Offsets can be postive or negative. The value of the timeval/timespec
+ * is the sum of its fields, but *NOTE*: the field tv_usec/tv_nsec must
+ * always be non-negative.
+ */
+static inline bool timeval_inject_offset_valid(const struct timeval *tv)
+{
+ /* We don't check the tv_sec as it can be positive or negative */
+
+ /* Can't have more microseconds then a second */
+ if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC)
+ return false;
+ return true;
+}
+
+static inline bool timespec_inject_offset_valid(const struct timespec *ts)
+{
+ /* We don't check the tv_sec as it can be positive or negative */
+
+ /* Can't have more nanoseconds then a second */
+ if (ts->tv_nsec < 0 || ts->tv_nsec >= NSEC_PER_SEC)
+ return false;
+ return true;
+}
+
#define CURRENT_TIME (current_kernel_time())
#define CURRENT_TIME_SEC ((struct timespec) { get_seconds(), 0 })

--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -674,8 +674,14 @@ int ntp_validate_timex(struct timex *txc
return -EINVAL;
}

- if ((txc->modes & ADJ_SETOFFSET) && (!capable(CAP_SYS_TIME)))
- return -EPERM;
+ if (txc->modes & ADJ_SETOFFSET) {
+ /* In order to inject time, you gotta be super-user! */
+ if (!capable(CAP_SYS_TIME))
+ return -EPERM;
+
+ if (!timeval_inject_offset_valid(&txc->time))
+ return -EINVAL;
+ }

/*
* Check for potential multiplication overflows that can
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -958,7 +958,7 @@ int timekeeping_inject_offset(struct tim
struct timespec64 ts64, tmp;
int ret = 0;

- if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)
+ if (!timespec_inject_offset_valid(ts))
return -EINVAL;

ts64 = timespec_to_timespec64(*ts);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:11 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jan Kara <ja...@suse.cz>

commit 418c12d08dc64a45107c467ec1ba29b5e69b0715 upstream.

When multiple xattrs need to be moved out of inode, we did not properly
recompute total size of xattr headers in the inode and the new header
position. Thus when moving the second and further xattr we asked
ext4_xattr_shift_entries() to move too much and from the wrong place,
resulting in possible xattr value corruption or general memory
corruption.

Signed-off-by: Jan Kara <ja...@suse.cz>
Signed-off-by: Theodore Ts'o <ty...@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
fs/ext4/xattr.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -1423,6 +1423,7 @@ retry:
error = ext4_xattr_ibody_set(handle, inode, &i, is);
if (error)
goto cleanup;
+ total_ino -= entry_size;

entry = IFIRST(header);
if (entry_size + EXT4_XATTR_SIZE(size) >= isize_diff)
@@ -1433,11 +1434,11 @@ retry:
ext4_xattr_shift_entries(entry, -shift_bytes,
(void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
EXT4_I(inode)->i_extra_isize + shift_bytes,
- (void *)header, total_ino - entry_size,
- inode->i_sb->s_blocksize);
+ (void *)header, total_ino, inode->i_sb->s_blocksize);

isize_diff -= shift_bytes;
EXT4_I(inode)->i_extra_isize += shift_bytes;
+ header = IHDR(inode, raw_inode);

i.name = b_entry_name;
i.value = buffer;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:11 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 79fd8e706637a5c7c41f9498fe0fbfb437abfdc8 ]

When we pick a CPU to use for a new subchannel we try find a non-used one
on the appropriate NUMA node, we keep track of them with the
primary->alloced_cpus_in_node mask. Under normal circumstances we don't run
out of available CPUs but it is possible when we we don't initialize some
cpus in Linux, e.g. when we boot with 'nr_cpus=' limitation.

Avoid the infinite loop in init_vp_index() by checking that we still have
non-used CPUs in the alloced_cpus_in_node mask and resetting it in case
we don't.

Signed-off-by: Vitaly Kuznetsov <vkuz...@redhat.com>
Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/hv/channel_mgmt.c | 11 +++++++++++
1 file changed, 11 insertions(+)

--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -459,6 +459,17 @@ static void init_vp_index(struct vmbus_c
cpumask_of_node(primary->numa_node));

cur_cpu = -1;
+
+ /*
+ * Normally Hyper-V host doesn't create more subchannels than there
+ * are VCPUs on the node but it is possible when not all present VCPUs
+ * on the node are initialized by guest. Clear the alloced_cpus_in_node
+ * to start over.
+ */
+ if (cpumask_equal(&primary->alloced_cpus_in_node,
+ cpumask_of_node(primary->numa_node)))
+ cpumask_clear(&primary->alloced_cpus_in_node);
+
while (true) {
cur_cpu = cpumask_next(cur_cpu, &available_mask);
if (cur_cpu >= nr_cpu_ids) {

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:11 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 0d3d054b43719ef33232677ba27ba6097afdafbc ]

IV size was zero on CBC and CTR modes,
causing a bug triggered by skcipher.

Fixing this adding a correct size.

Signed-off-by: Leonidas Da Silva Barbosa <leos...@linux.vnet.ibm.com>
Signed-off-by: Paulo Smorigo <pfsm...@linux.vnet.ibm.com>
Signed-off-by: Herbert Xu <her...@gondor.apana.org.au>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/crypto/vmx/aes_cbc.c | 2 +-
drivers/crypto/vmx/aes_ctr.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/crypto/vmx/aes_cbc.c
+++ b/drivers/crypto/vmx/aes_cbc.c
@@ -191,7 +191,7 @@ struct crypto_alg p8_aes_cbc_alg = {
.cra_init = p8_aes_cbc_init,
.cra_exit = p8_aes_cbc_exit,
.cra_blkcipher = {
- .ivsize = 0,
+ .ivsize = AES_BLOCK_SIZE,
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
.setkey = p8_aes_cbc_setkey,
--- a/drivers/crypto/vmx/aes_ctr.c
+++ b/drivers/crypto/vmx/aes_ctr.c
@@ -175,7 +175,7 @@ struct crypto_alg p8_aes_ctr_alg = {
.cra_init = p8_aes_ctr_init,
.cra_exit = p8_aes_ctr_exit,
.cra_blkcipher = {
- .ivsize = 0,
+ .ivsize = AES_BLOCK_SIZE,
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
.setkey = p8_aes_ctr_setkey,

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:11 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tyrel Datwyler <tyr...@linux.vnet.ibm.com>

commit a87eeb900dbb9f8202f96604d56e47e67c936b9d upstream.

Commit 655ee63cf371 ("scsi constants: command, sense key + additional
sense string") added a "Completed" sense string with key 0xF to
snstext[], but failed to updated the upper bounds check of the sense key
in scsi_sense_key_string().

Fixes: 655ee63cf371 ("[SCSI] scsi constants: command, sense key + additional sense strings")
Signed-off-by: Tyrel Datwyler <tyr...@linux.vnet.ibm.com>
Reviewed-by: Bart Van Assche <bart.va...@sandisk.com>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
drivers/scsi/constants.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -1181,8 +1181,9 @@ static const char * const snstext[] = {

/* Get sense key string or NULL if not available */
const char *
-scsi_sense_key_string(unsigned char key) {
- if (key <= 0xE)
+scsi_sense_key_string(unsigned char key)
+{
+ if (key < ARRAY_SIZE(snstext))
return snstext[key];
return NULL;
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:12 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vegard Nossum <vegard...@oracle.com>

commit 11749e086b2766cccf6217a527ef5c5604ba069c upstream.

I got this with syzkaller:

==================================================================
BUG: KASAN: null-ptr-deref on address 0000000000000020
Read of size 32 by task syz-executor/22519
CPU: 1 PID: 22519 Comm: syz-executor Not tainted 4.8.0-rc2+ #169
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org 04/01/2
014
0000000000000001 ffff880111a17a00 ffffffff81f9f141 ffff880111a17a90
ffff880111a17c50 ffff880114584a58 ffff880114584a10 ffff880111a17a80
ffffffff8161fe3f ffff880100000000 ffff880118d74a48 ffff880118d74a68
Call Trace:
[<ffffffff81f9f141>] dump_stack+0x83/0xb2
[<ffffffff8161fe3f>] kasan_report_error+0x41f/0x4c0
[<ffffffff8161ff74>] kasan_report+0x34/0x40
[<ffffffff82c84b54>] ? snd_timer_user_read+0x554/0x790
[<ffffffff8161e79e>] check_memory_region+0x13e/0x1a0
[<ffffffff8161e9c1>] kasan_check_read+0x11/0x20
[<ffffffff82c84b54>] snd_timer_user_read+0x554/0x790
[<ffffffff82c84600>] ? snd_timer_user_info_compat.isra.5+0x2b0/0x2b0
[<ffffffff817d0831>] ? proc_fault_inject_write+0x1c1/0x250
[<ffffffff817d0670>] ? next_tgid+0x2a0/0x2a0
[<ffffffff8127c278>] ? do_group_exit+0x108/0x330
[<ffffffff8174653a>] ? fsnotify+0x72a/0xca0
[<ffffffff81674dfe>] __vfs_read+0x10e/0x550
[<ffffffff82c84600>] ? snd_timer_user_info_compat.isra.5+0x2b0/0x2b0
[<ffffffff81674cf0>] ? do_sendfile+0xc50/0xc50
[<ffffffff81745e10>] ? __fsnotify_update_child_dentry_flags+0x60/0x60
[<ffffffff8143fec6>] ? kcov_ioctl+0x56/0x190
[<ffffffff81e5ada2>] ? common_file_perm+0x2e2/0x380
[<ffffffff81746b0e>] ? __fsnotify_parent+0x5e/0x2b0
[<ffffffff81d93536>] ? security_file_permission+0x86/0x1e0
[<ffffffff816728f5>] ? rw_verify_area+0xe5/0x2b0
[<ffffffff81675355>] vfs_read+0x115/0x330
[<ffffffff81676371>] SyS_read+0xd1/0x1a0
[<ffffffff816762a0>] ? vfs_write+0x4b0/0x4b0
[<ffffffff82001c2c>] ? __this_cpu_preempt_check+0x1c/0x20
[<ffffffff8150455a>] ? __context_tracking_exit.part.4+0x3a/0x1e0
[<ffffffff816762a0>] ? vfs_write+0x4b0/0x4b0
[<ffffffff81005524>] do_syscall_64+0x1c4/0x4e0
[<ffffffff810052fc>] ? syscall_return_slowpath+0x16c/0x1d0
[<ffffffff83c3276a>] entry_SYSCALL64_slow_path+0x25/0x25
==================================================================

There are a couple of problems that I can see:

- ioctl(SNDRV_TIMER_IOCTL_SELECT), which potentially sets
tu->queue/tu->tqueue to NULL on memory allocation failure, so read()
would get a NULL pointer dereference like the above splat

- the same ioctl() can free tu->queue/to->tqueue which means read()
could potentially see (and dereference) the freed pointer

We can fix both by taking the ioctl_lock mutex when dereferencing
->queue/->tqueue, since that's always held over all the ioctl() code.

Just looking at the code I find it likely that there are more problems
here such as tu->qhead pointing outside the buffer if the size is
changed concurrently using SNDRV_TIMER_IOCTL_PARAMS.

Signed-off-by: Vegard Nossum <vegard...@oracle.com>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
sound/core/timer.c | 2 ++
1 file changed, 2 insertions(+)

--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1967,6 +1967,7 @@ static ssize_t snd_timer_user_read(struc
tu->qused--;
spin_unlock_irq(&tu->qlock);

+ mutex_lock(&tu->ioctl_lock);
if (tu->tread) {
if (copy_to_user(buffer, &tu->tqueue[qhead],
sizeof(struct snd_timer_tread)))
@@ -1976,6 +1977,7 @@ static ssize_t snd_timer_user_read(struc
sizeof(struct snd_timer_read)))
err = -EFAULT;
}
+ mutex_unlock(&tu->ioctl_lock);

spin_lock_irq(&tu->qlock);
if (err < 0)

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:12 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Krzysztof Kozlowski <k.koz...@samsung.com>

commit 48a61e1e2af8020f11a2b8f8dc878144477623c6 upstream.

Add proper error path (for disabling runtime PM) when registering of
hwrng fails.

Fixes: b329669ea0b5 ("hwrng: exynos - Add support for Exynos random number generator")
Signed-off-by: Krzysztof Kozlowski <k.koz...@samsung.com>
Signed-off-by: Herbert Xu <her...@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
drivers/char/hw_random/exynos-rng.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

--- a/drivers/char/hw_random/exynos-rng.c
+++ b/drivers/char/hw_random/exynos-rng.c
@@ -118,6 +118,7 @@ static int exynos_rng_probe(struct platf
{
struct exynos_rng *exynos_rng;
struct resource *res;
+ int ret;

exynos_rng = devm_kzalloc(&pdev->dev, sizeof(struct exynos_rng),
GFP_KERNEL);
@@ -145,7 +146,13 @@ static int exynos_rng_probe(struct platf
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_enable(&pdev->dev);

- return devm_hwrng_register(&pdev->dev, &exynos_rng->rng);
+ ret = devm_hwrng_register(&pdev->dev, &exynos_rng->rng);
+ if (ret) {
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ }
+
+ return ret;
}

#ifdef CONFIG_PM

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:12 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Daniel Vetter <daniel...@ffwll.ch>

commit 6f00975c619064a18c23fd3aced325ae165a73b9 upstream.

Somehow this one slipped through, which means drivers without modeset
support can be oopsed (since those also don't call
drm_mode_config_init, which means the crtc lookup will chase an
uninitalized idr).

Reported-by: Alexander Potapenko <gli...@google.com>
Cc: Alexander Potapenko <gli...@google.com>
Signed-off-by: Daniel Vetter <daniel...@intel.com>
Reviewed-by: Chris Wilson <ch...@chris-wilson.co.uk>
Signed-off-by: Dave Airlie <air...@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
drivers/gpu/drm/drm_crtc.c | 3 +++
1 file changed, 3 insertions(+)

--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -5231,6 +5231,9 @@ int drm_mode_page_flip_ioctl(struct drm_
unsigned long flags;
int ret = -EINVAL;

+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return -EINVAL;
+
if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
page_flip->reserved != 0)
return -EINVAL;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:12 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: John Stultz <john....@linaro.org>

commit 27727df240c7cc84f2ba6047c6f18d5addfd25ef upstream.

When I added some extra sanity checking in timekeeping_get_ns() under
CONFIG_DEBUG_TIMEKEEPING, I missed that the NMI safe __ktime_get_fast_ns()
method was using timekeeping_get_ns().

Thus the locking added to the debug checks broke the NMI-safety of
__ktime_get_fast_ns().

This patch open-codes the timekeeping_get_ns() logic for
__ktime_get_fast_ns(), so can avoid any deadlocks in NMI.

Fixes: 4ca22c2648f9 "timekeeping: Add warnings when overflows or underflows are observed"
Reported-by: Steven Rostedt <ros...@goodmis.org>
Reported-by: Peter Zijlstra <pet...@infradead.org>
Signed-off-by: John Stultz <john....@linaro.org>
Link: http://lkml.kernel.org/r/1471993702-29148-2-git...@linaro.org
Signed-off-by: Thomas Gleixner <tg...@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
kernel/time/timekeeping.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -383,7 +383,10 @@ static __always_inline u64 __ktime_get_f
do {
seq = raw_read_seqcount_latch(&tkf->seq);
tkr = tkf->base + (seq & 0x01);
- now = ktime_to_ns(tkr->base) + timekeeping_get_ns(tkr);
+ now = ktime_to_ns(tkr->base);
+
+ now += clocksource_delta(tkr->read(tkr->clock),
+ tkr->cycle_last, tkr->mask);
} while (read_seqcount_retry(&tkf->seq, seq));

return now;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:12 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vegard Nossum <vegard...@oracle.com>

commit 8ddc05638ee42b18ba4fe99b5fb647fa3ad20456 upstream.

I hit this with syzkaller:

kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] PREEMPT SMP KASAN
CPU: 0 PID: 1327 Comm: a.out Not tainted 4.8.0-rc2+ #190
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org 04/01/2014
task: ffff88011278d600 task.stack: ffff8801120c0000
RIP: 0010:[<ffffffff82c8ba07>] [<ffffffff82c8ba07>] snd_hrtimer_start+0x77/0x100
RSP: 0018:ffff8801120c7a60 EFLAGS: 00010006
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000007
RDX: 0000000000000009 RSI: 1ffff10023483091 RDI: 0000000000000048
RBP: ffff8801120c7a78 R08: ffff88011a5cf768 R09: ffff88011a5ba790
R10: 0000000000000002 R11: ffffed00234b9ef1 R12: ffff880114843980
R13: ffffffff84213c00 R14: ffff880114843ab0 R15: 0000000000000286
FS: 00007f72958f3700(0000) GS:ffff88011aa00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000603001 CR3: 00000001126ab000 CR4: 00000000000006f0
Stack:
ffff880114843980 ffff880111eb2dc0 ffff880114843a34 ffff8801120c7ad0
ffffffff82c81ab1 0000000000000000 ffffffff842138e0 0000000100000000
ffff880111eb2dd0 ffff880111eb2dc0 0000000000000001 ffff880111eb2dc0
Call Trace:
[<ffffffff82c81ab1>] snd_timer_start1+0x331/0x670
[<ffffffff82c85bfd>] snd_timer_start+0x5d/0xa0
[<ffffffff82c8795e>] snd_timer_user_ioctl+0x88e/0x2830
[<ffffffff8159f3a0>] ? __follow_pte.isra.49+0x430/0x430
[<ffffffff82c870d0>] ? snd_timer_pause+0x80/0x80
[<ffffffff815a26fa>] ? do_wp_page+0x3aa/0x1c90
[<ffffffff8132762f>] ? put_prev_entity+0x108f/0x21a0
[<ffffffff82c870d0>] ? snd_timer_pause+0x80/0x80
[<ffffffff816b0733>] do_vfs_ioctl+0x193/0x1050
[<ffffffff813510af>] ? cpuacct_account_field+0x12f/0x1a0
[<ffffffff816b05a0>] ? ioctl_preallocate+0x200/0x200
[<ffffffff81002f2f>] ? syscall_trace_enter+0x3cf/0xdb0
[<ffffffff815045ba>] ? __context_tracking_exit.part.4+0x9a/0x1e0
[<ffffffff81002b60>] ? exit_to_usermode_loop+0x190/0x190
[<ffffffff82001a97>] ? check_preemption_disabled+0x37/0x1e0
[<ffffffff81d93889>] ? security_file_ioctl+0x89/0xb0
[<ffffffff816b167f>] SyS_ioctl+0x8f/0xc0
[<ffffffff816b15f0>] ? do_vfs_ioctl+0x1050/0x1050
[<ffffffff81005524>] do_syscall_64+0x1c4/0x4e0
[<ffffffff83c32b2a>] entry_SYSCALL64_slow_path+0x25/0x25
Code: c7 c7 c4 b9 c8 82 48 89 d9 4c 89 ee e8 63 88 7f fe e8 7e 46 7b fe 48 8d 7b 48 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <0f> b6 04 02 84 c0 74 04 84 c0 7e 65 80 7b 48 00 74 0e e8 52 46
RIP [<ffffffff82c8ba07>] snd_hrtimer_start+0x77/0x100
RSP <ffff8801120c7a60>
---[ end trace 5955b08db7f2b029 ]---

This can happen if snd_hrtimer_open() fails to allocate memory and
returns an error, which is currently not checked by snd_timer_open():

ioctl(SNDRV_TIMER_IOCTL_SELECT)
- snd_timer_user_tselect()
- snd_timer_close()
- snd_hrtimer_close()
- (struct snd_timer *) t->private_data = NULL
- snd_timer_open()
- snd_hrtimer_open()
- kzalloc() fails; t->private_data is still NULL

ioctl(SNDRV_TIMER_IOCTL_START)
- snd_timer_user_start()
- snd_timer_start()
- snd_timer_start1()
- snd_hrtimer_start()
- t->private_data == NULL // boom

Signed-off-by: Vegard Nossum <vegard...@oracle.com>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
sound/core/timer.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)

--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -296,8 +296,21 @@ int snd_timer_open(struct snd_timer_inst
get_device(&timer->card->card_dev);
timeri->slave_class = tid->dev_sclass;
timeri->slave_id = slave_id;
- if (list_empty(&timer->open_list_head) && timer->hw.open)
- timer->hw.open(timer);
+
+ if (list_empty(&timer->open_list_head) && timer->hw.open) {
+ int err = timer->hw.open(timer);
+ if (err) {
+ kfree(timeri->owner);
+ kfree(timeri);
+
+ if (timer->card)
+ put_device(&timer->card->card_dev);
+ module_put(timer->module);
+ mutex_unlock(&register_mutex);
+ return err;
+ }
+ }
+
list_add_tail(&timeri->open_list, &timer->open_list_head);
snd_timer_check_master(timeri);
mutex_unlock(&register_mutex);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:12 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit ada2f634cd50d050269b67b4e2966582387e7c27 ]

Fixes the hotcpu notifier leak and other global variable memory leaks
during CQM (cache quality of service monitoring) initialization.

Signed-off-by: Vikas Shivappa <vikas.s...@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org>
Reviewed-by: Tony Luck <tony...@intel.com>
Acked-by: Thomas Gleixner <tg...@linutronix.de>
Cc: Alexander Shishkin <alexander...@linux.intel.com>
Cc: Andy Lutomirski <lu...@amacapital.net>
Cc: Arnaldo Carvalho de Melo <ac...@redhat.com>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Brian Gerst <brg...@gmail.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Denys Vlasenko <dvla...@redhat.com>
Cc: H. Peter Anvin <h...@zytor.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Linus Torvalds <torv...@linux-foundation.org>
Cc: Matt Fleming <ma...@codeblueprint.co.uk>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Stephane Eranian <era...@google.com>
Cc: Vince Weaver <vincent...@maine.edu>
Cc: fengh...@intel.com
Cc: h.pete...@intel.com
Cc: ravi.v....@intel.com
Cc: vikas.s...@intel.com
Link: http://lkml.kernel.org/r/1457652732-4499-3-git-s...@linux.intel.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
arch/x86/kernel/cpu/perf_event_intel_cqm.c | 43 +++++++++++++++++++++--------
1 file changed, 32 insertions(+), 11 deletions(-)

--- a/arch/x86/kernel/cpu/perf_event_intel_cqm.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_cqm.c
@@ -211,6 +211,20 @@ static void __put_rmid(u32 rmid)
list_add_tail(&entry->list, &cqm_rmid_limbo_lru);
}

+static void cqm_cleanup(void)
+{
+ int i;
+
+ if (!cqm_rmid_ptrs)
+ return;
+
+ for (i = 0; i < cqm_max_rmid; i++)
+ kfree(cqm_rmid_ptrs[i]);
+
+ kfree(cqm_rmid_ptrs);
+ cqm_rmid_ptrs = NULL;
+}
+
static int intel_cqm_setup_rmid_cache(void)
{
struct cqm_rmid_entry *entry;
@@ -218,7 +232,7 @@ static int intel_cqm_setup_rmid_cache(vo
int r = 0;

nr_rmids = cqm_max_rmid + 1;
- cqm_rmid_ptrs = kmalloc(sizeof(struct cqm_rmid_entry *) *
+ cqm_rmid_ptrs = kzalloc(sizeof(struct cqm_rmid_entry *) *
nr_rmids, GFP_KERNEL);
if (!cqm_rmid_ptrs)
return -ENOMEM;
@@ -249,11 +263,9 @@ static int intel_cqm_setup_rmid_cache(vo
mutex_unlock(&cache_mutex);

return 0;
-fail:
- while (r--)
- kfree(cqm_rmid_ptrs[r]);

- kfree(cqm_rmid_ptrs);
+fail:
+ cqm_cleanup();
return -ENOMEM;
}

@@ -1322,7 +1334,7 @@ static const struct x86_cpu_id intel_cqm

static int __init intel_cqm_init(void)
{
- char *str, scale[20];
+ char *str = NULL, scale[20];
int i, cpu, ret;

if (!x86_match_cpu(intel_cqm_match))
@@ -1382,16 +1394,25 @@ static int __init intel_cqm_init(void)
cqm_pick_event_reader(i);
}

- __perf_cpu_notifier(intel_cqm_cpu_notifier);
-
ret = perf_pmu_register(&intel_cqm_pmu, "intel_cqm", -1);
- if (ret)
+ if (ret) {
pr_err("Intel CQM perf registration failed: %d\n", ret);
- else
- pr_info("Intel CQM monitoring enabled\n");
+ goto out;
+ }
+
+ pr_info("Intel CQM monitoring enabled\n");

+ /*
+ * Register the hot cpu notifier once we are sure cqm
+ * is enabled to avoid notifier leak.
+ */
+ __perf_cpu_notifier(intel_cqm_cpu_notifier);
out:
cpu_notifier_register_done();
+ if (ret) {
+ kfree(str);
+ cqm_cleanup();
+ }

return ret;
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:12 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dave Chinner <dchi...@redhat.com>

commit f3d7ebdeb2c297bd26272384e955033493ca291c upstream.

>From inspection, the superblock sb_inprogress check is done in the
verifier and triggered only for the primary superblock via a
"bp->b_bn == XFS_SB_DADDR" check.

Unfortunately, the primary superblock is an uncached buffer, and
hence it is configured by xfs_buf_read_uncached() with:

bp->b_bn = XFS_BUF_DADDR_NULL; /* always null for uncached buffers */

And so this check never triggers. Fix it.

Signed-off-by: Dave Chinner <dchi...@redhat.com>
Reviewed-by: Brian Foster <bfo...@redhat.com>
Reviewed-by: Christoph Hellwig <h...@lst.de>
Signed-off-by: Dave Chinner <da...@fromorbit.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
fs/xfs/libxfs/xfs_sb.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -581,7 +581,8 @@ xfs_sb_verify(
* Only check the in progress field for the primary superblock as
* mkfs.xfs doesn't clear it from secondary superblocks.
*/
- return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR,
+ return xfs_mount_validate_sb(mp, &sb,
+ bp->b_maps[0].bm_bn == XFS_SB_DADDR,
check_version);
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:13 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit a59e0f5795fe52dad42a99c00287e3766153b312 ]

Go directly to ending a request if it wasn't started. Previously, completing a
request may invoke a driver callback for a request it didn't initialize.

Signed-off-by: Keith Busch <keith...@intel.com>
Reviewed-by: Sagi Grimberg <sa...@mellanox.com>
Reviewed-by: Johannes Thumshirn <jthumshirn at suse.de>
Acked-by: Christoph Hellwig <h...@lst.de>
Signed-off-by: Jens Axboe <ax...@fb.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
block/blk-mq.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -601,8 +601,10 @@ static void blk_mq_check_expired(struct
* If a request wasn't started before the queue was
* marked dying, kill it here or it'll go unnoticed.
*/
- if (unlikely(blk_queue_dying(rq->q)))
- blk_mq_complete_request(rq, -EIO);
+ if (unlikely(blk_queue_dying(rq->q))) {
+ rq->errors = -EIO;
+ blk_mq_end_request(rq, rq->errors);
+ }
return;
}
if (rq->cmd_flags & REQ_NO_TIMEOUT)

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:13 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 6e35c04cf633e55648acb9ccabff42aa37bd4044 ]

This patch fixes the Hash PCTYPE enable for X722 since it supports
a broader selection of PCTYPES for TCP and UDP.

This patch also fixes a bug in XL710, X710, X722 support for RSS,
as of now we cannot reduce the (4)tuple for RSS for TCP/IPv4/IPV6 or
UDP/IPv4/IPv6 packets since this requires a product feature change
that comes in a later release.

A VF should never be allowed to change the tuples for RSS for any
PCTYPE since that's a global setting for the device in case of i40e
devices.

Change-ID: I0ee7203c9b24813260f58f3220798bc9d9ac4a12
Signed-off-by: Anjali Singhai Jain <anjali....@intel.com>
Tested-by: Andrew Bowers <andrewx...@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey....@intel.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 14 ++-----
drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c | 40 ++++-----------------
2 files changed, 12 insertions(+), 42 deletions(-)

--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -2164,8 +2164,7 @@ static int i40e_set_rss_hash_opt(struct
case TCP_V4_FLOW:
switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
case 0:
- hena &= ~BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
- break;
+ return -EINVAL;
case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
break;
@@ -2176,8 +2175,7 @@ static int i40e_set_rss_hash_opt(struct
case TCP_V6_FLOW:
switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
case 0:
- hena &= ~BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
- break;
+ return -EINVAL;
case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
break;
@@ -2188,9 +2186,7 @@ static int i40e_set_rss_hash_opt(struct
case UDP_V4_FLOW:
switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
case 0:
- hena &= ~(BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
- BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));
- break;
+ return -EINVAL;
case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));
@@ -2202,9 +2198,7 @@ static int i40e_set_rss_hash_opt(struct
case UDP_V6_FLOW:
switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
case 0:
- hena &= ~(BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
- BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));
- break;
+ return -EINVAL;
case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));
--- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
@@ -477,54 +477,30 @@ static int i40evf_set_rss_hash_opt(struc

switch (nfc->flow_type) {
case TCP_V4_FLOW:
- switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
- case 0:
- hena &= ~BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
- break;
- case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+ if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3))
hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
- break;
- default:
+ else
return -EINVAL;
- }
break;
case TCP_V6_FLOW:
- switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
- case 0:
- hena &= ~BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
- break;
- case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+ if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3))
hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
- break;
- default:
+ else
return -EINVAL;
- }
break;
case UDP_V4_FLOW:
- switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
- case 0:
- hena &= ~(BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
- BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));
- break;
- case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+ if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));
- break;
- default:
+ } else {
return -EINVAL;
}
break;
case UDP_V6_FLOW:
- switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
- case 0:
- hena &= ~(BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
- BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));
- break;
- case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+ if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));
- break;
- default:
+ } else {
return -EINVAL;
}
break;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:13 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 03d1fb3a65783979f23bd58b5a0387e6992d9e26 ]

Track msix of each IO and use the same msix for issuing abort to timed
out IO. With this driver will process IO's reply first followed by TM.

Signed-off-by: Suganath prabu Subramani <suganath-pra...@avagotech.com>
Signed-off-by: Chaitra P B <chaitra...@avagotech.com>
Reviewed-by: Tomas Henzl <the...@redhat.com>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/scsi/mpt3sas/mpt3sas_base.c | 20 +++++++++++---------
drivers/scsi/mpt3sas/mpt3sas_base.h | 5 ++++-
drivers/scsi/mpt3sas/mpt3sas_ctl.c | 2 +-
drivers/scsi/mpt3sas/mpt3sas_scsih.c | 12 +++++++++---
4 files changed, 25 insertions(+), 14 deletions(-)

--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -2242,6 +2242,12 @@ mpt3sas_base_get_reply_virt_addr(struct
return ioc->reply + (phys_addr - (u32)ioc->reply_dma);
}

+static inline u8
+_base_get_msix_index(struct MPT3SAS_ADAPTER *ioc)
+{
+ return ioc->cpu_msix_table[raw_smp_processor_id()];
+}
+
/**
* mpt3sas_base_get_smid - obtain a free smid from internal queue
* @ioc: per adapter object
@@ -2302,6 +2308,7 @@ mpt3sas_base_get_smid_scsiio(struct MPT3
request->scmd = scmd;
request->cb_idx = cb_idx;
smid = request->smid;
+ request->msix_io = _base_get_msix_index(ioc);
list_del(&request->tracker_list);
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
return smid;
@@ -2424,12 +2431,6 @@ _base_writeq(__u64 b, volatile void __io
}
#endif

-static inline u8
-_base_get_msix_index(struct MPT3SAS_ADAPTER *ioc)
-{
- return ioc->cpu_msix_table[raw_smp_processor_id()];
-}
-
/**
* mpt3sas_base_put_smid_scsi_io - send SCSI_IO request to firmware
* @ioc: per adapter object
@@ -2483,18 +2484,19 @@ mpt3sas_base_put_smid_fast_path(struct M
* mpt3sas_base_put_smid_hi_priority - send Task Managment request to firmware
* @ioc: per adapter object
* @smid: system request message index
- *
+ * @msix_task: msix_task will be same as msix of IO incase of task abort else 0.
* Return nothing.
*/
void
-mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+ u16 msix_task)
{
Mpi2RequestDescriptorUnion_t descriptor;
u64 *request = (u64 *)&descriptor;

descriptor.HighPriority.RequestFlags =
MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
- descriptor.HighPriority.MSIxIndex = 0;
+ descriptor.HighPriority.MSIxIndex = msix_task;
descriptor.HighPriority.SMID = cpu_to_le16(smid);
descriptor.HighPriority.LMID = 0;
descriptor.HighPriority.Reserved1 = 0;
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -643,6 +643,7 @@ struct chain_tracker {
* @cb_idx: callback index
* @direct_io: To indicate whether I/O is direct (WARPDRIVE)
* @tracker_list: list of free request (ioc->free_list)
+ * @msix_io: IO's msix
*/
struct scsiio_tracker {
u16 smid;
@@ -651,6 +652,7 @@ struct scsiio_tracker {
u8 direct_io;
struct list_head chain_list;
struct list_head tracker_list;
+ u16 msix_io;
};

/**
@@ -1213,7 +1215,8 @@ void mpt3sas_base_put_smid_scsi_io(struc
u16 handle);
void mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid,
u16 handle);
-void mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid);
+void mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc,
+ u16 smid, u16 msix_task);
void mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid);
void mpt3sas_base_initialize_callback_handler(void);
u8 mpt3sas_base_register_callback_handler(MPT_CALLBACK cb_func);
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -817,7 +817,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPT
tm_request->DevHandle));
ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz,
data_in_dma, data_in_sz);
- mpt3sas_base_put_smid_hi_priority(ioc, smid);
+ mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
break;
}
case MPI2_FUNCTION_SMP_PASSTHROUGH:
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2193,6 +2193,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_AD
unsigned long timeleft;
struct scsiio_tracker *scsi_lookup = NULL;
int rc;
+ u16 msix_task = 0;

if (m_type == TM_MUTEX_ON)
mutex_lock(&ioc->tm_cmds.mutex);
@@ -2256,7 +2257,12 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_AD
int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
mpt3sas_scsih_set_tm_flag(ioc, handle);
init_completion(&ioc->tm_cmds.done);
- mpt3sas_base_put_smid_hi_priority(ioc, smid);
+ if ((type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK) &&
+ (scsi_lookup->msix_io < ioc->reply_queue_count))
+ msix_task = scsi_lookup->msix_io;
+ else
+ msix_task = 0;
+ mpt3sas_base_put_smid_hi_priority(ioc, smid, msix_task);
timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
if (!(ioc->tm_cmds.status & MPT3_CMD_COMPLETE)) {
pr_err(MPT3SAS_FMT "%s: timeout\n",
@@ -3151,7 +3157,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER
mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
mpi_request->DevHandle = cpu_to_le16(handle);
mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
- mpt3sas_base_put_smid_hi_priority(ioc, smid);
+ mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL);

out:
@@ -3332,7 +3338,7 @@ _scsih_tm_tr_volume_send(struct MPT3SAS_
mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
mpi_request->DevHandle = cpu_to_le16(handle);
mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
- mpt3sas_base_put_smid_hi_priority(ioc, smid);
+ mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
}

/**

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:14 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Nicolai Stange <nics...@gmail.com>

commit f2d1362ff7d266b3d2b1c764d6c2ef4a3b457f23 upstream.

Currently, if the number of leading zeros is greater than fits into a
complete limb, mpi_write_sgl() skips them by iterating over them limb-wise.

However, it fails to adjust its internal leading zeros tracking variable,
lzeros, accordingly: it does a

p -= sizeof(alimb);
continue;

which should really have been a

lzeros -= sizeof(alimb);
continue;

Since lzeros never decreases if its initial value >= sizeof(alimb), nothing
gets copied by mpi_write_sgl() in that case.

Instead of skipping the high order zero limbs within the loop as shown
above, fix the issue by adjusting the copying loop's bounds.

Fixes: 2d4d1eea540b ("lib/mpi: Add mpi sgl helpers")
Signed-off-by: Nicolai Stange <nics...@gmail.com>
Signed-off-by: Herbert Xu <her...@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
lib/mpi/mpicoder.c | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)

--- a/lib/mpi/mpicoder.c
+++ b/lib/mpi/mpicoder.c
@@ -367,7 +367,9 @@ int mpi_write_to_sgl(MPI a, struct scatt
buf_len = sgl->length;
p2 = sg_virt(sgl);

- for (i = a->nlimbs - 1; i >= 0; i--) {
+ for (i = a->nlimbs - 1 - lzeros / BYTES_PER_MPI_LIMB,
+ lzeros %= BYTES_PER_MPI_LIMB;
+ i >= 0; i--) {
alimb = a->d[i];
p = (u8 *)&alimb2;
#if BYTES_PER_MPI_LIMB == 4
@@ -388,17 +390,12 @@ int mpi_write_to_sgl(MPI a, struct scatt
#error please implement for this limb size.
#endif
if (lzeros > 0) {
- if (lzeros >= sizeof(alimb)) {
- p -= sizeof(alimb);
- continue;
- } else {
- mpi_limb_t *limb1 = (void *)p - sizeof(alimb);
- mpi_limb_t *limb2 = (void *)p - sizeof(alimb)
- + lzeros;
- *limb1 = *limb2;
- p -= lzeros;
- y = lzeros;
- }
+ mpi_limb_t *limb1 = (void *)p - sizeof(alimb);
+ mpi_limb_t *limb2 = (void *)p - sizeof(alimb)
+ + lzeros;
+ *limb1 = *limb2;
+ p -= lzeros;
+ y = lzeros;
lzeros -= sizeof(alimb);
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:14 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sai Gurrappadi <sgurr...@nvidia.com>

commit e43e94c1eda76dabd686ddf6f7825f54d747b310 upstream.

Currently, the userspace governor only updates frequency on GOV_LIMITS
if policy->cur falls outside policy->{min/max}. However, it is also
necessary to update current frequency on GOV_LIMITS to match the user
requested value if it can be achieved within the new policy->{max/min}.

This was previously the behaviour in the governor until commit d1922f0
("cpufreq: Simplify userspace governor") which incorrectly assumed that
policy->cur == user requested frequency via scaling_setspeed. This won't
be true if the user requested frequency falls outside policy->{min/max}.
Ex: a temporary thermal cap throttled the user requested frequency.

Fix this by storing the user requested frequency in a seperate variable.
The governor will then try to achieve this request on every GOV_LIMITS
change.

Fixes: d1922f02562f (cpufreq: Simplify userspace governor)
Signed-off-by: Sai Gurrappadi <sgurr...@nvidia.com>
Acked-by: Viresh Kumar <viresh...@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j...@intel.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
drivers/cpufreq/cpufreq_userspace.c | 43 +++++++++++++++++++++++++++++++-----
1 file changed, 38 insertions(+), 5 deletions(-)

--- a/drivers/cpufreq/cpufreq_userspace.c
+++ b/drivers/cpufreq/cpufreq_userspace.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/slab.h>

static DEFINE_PER_CPU(unsigned int, cpu_is_managed);
static DEFINE_MUTEX(userspace_mutex);
@@ -31,6 +32,7 @@ static DEFINE_MUTEX(userspace_mutex);
static int cpufreq_set(struct cpufreq_policy *policy, unsigned int freq)
{
int ret = -EINVAL;
+ unsigned int *setspeed = policy->governor_data;

pr_debug("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq);

@@ -38,6 +40,8 @@ static int cpufreq_set(struct cpufreq_po
if (!per_cpu(cpu_is_managed, policy->cpu))
goto err;

+ *setspeed = freq;
+
ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
err:
mutex_unlock(&userspace_mutex);
@@ -49,19 +53,45 @@ static ssize_t show_speed(struct cpufreq
return sprintf(buf, "%u\n", policy->cur);
}

+static int cpufreq_userspace_policy_init(struct cpufreq_policy *policy)
+{
+ unsigned int *setspeed;
+
+ setspeed = kzalloc(sizeof(*setspeed), GFP_KERNEL);
+ if (!setspeed)
+ return -ENOMEM;
+
+ policy->governor_data = setspeed;
+ return 0;
+}
+
static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
unsigned int event)
{
+ unsigned int *setspeed = policy->governor_data;
unsigned int cpu = policy->cpu;
int rc = 0;

+ if (event == CPUFREQ_GOV_POLICY_INIT)
+ return cpufreq_userspace_policy_init(policy);
+
+ if (!setspeed)
+ return -EINVAL;
+
switch (event) {
+ case CPUFREQ_GOV_POLICY_EXIT:
+ mutex_lock(&userspace_mutex);
+ policy->governor_data = NULL;
+ kfree(setspeed);
+ mutex_unlock(&userspace_mutex);
+ break;
case CPUFREQ_GOV_START:
BUG_ON(!policy->cur);
pr_debug("started managing cpu %u\n", cpu);

mutex_lock(&userspace_mutex);
per_cpu(cpu_is_managed, cpu) = 1;
+ *setspeed = policy->cur;
mutex_unlock(&userspace_mutex);
break;
case CPUFREQ_GOV_STOP:
@@ -69,20 +99,23 @@ static int cpufreq_governor_userspace(st

mutex_lock(&userspace_mutex);
per_cpu(cpu_is_managed, cpu) = 0;
+ *setspeed = 0;
mutex_unlock(&userspace_mutex);
break;
case CPUFREQ_GOV_LIMITS:
mutex_lock(&userspace_mutex);
- pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz\n",
- cpu, policy->min, policy->max,
- policy->cur);
+ pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n",
+ cpu, policy->min, policy->max, policy->cur, *setspeed);

- if (policy->max < policy->cur)
+ if (policy->max < *setspeed)
__cpufreq_driver_target(policy, policy->max,
CPUFREQ_RELATION_H);
- else if (policy->min > policy->cur)
+ else if (policy->min > *setspeed)
__cpufreq_driver_target(policy, policy->min,
CPUFREQ_RELATION_L);
+ else
+ __cpufreq_driver_target(policy, *setspeed,
+ CPUFREQ_RELATION_L);
mutex_unlock(&userspace_mutex);
break;
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:15 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jan Kara <ja...@suse.cz>

commit 2e81a4eeedcaa66e35f58b81e0755b87057ce392 upstream.

When we need to move xattrs into external xattr block, we call
ext4_xattr_block_set() from ext4_expand_extra_isize_ea(). That may end
up calling ext4_mark_inode_dirty() again which will recurse back into
the inode expansion code leading to deadlocks.

Protect from recursion using EXT4_STATE_NO_EXPAND inode flag and move
its management into ext4_expand_extra_isize_ea() since its manipulation
is safe there (due to xattr_sem) from possible races with
ext4_xattr_set_handle() which plays with it as well.

Signed-off-by: Jan Kara <ja...@suse.cz>
Signed-off-by: Theodore Ts'o <ty...@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
fs/ext4/inode.c | 2 --
fs/ext4/xattr.c | 19 +++++++++++++------
2 files changed, 13 insertions(+), 8 deletions(-)

--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5186,8 +5186,6 @@ int ext4_mark_inode_dirty(handle_t *hand
sbi->s_want_extra_isize,
iloc, handle);
if (ret) {
- ext4_set_inode_state(inode,
- EXT4_STATE_NO_EXPAND);
if (mnt_count !=
le16_to_cpu(sbi->s_es->s_mnt_count)) {
ext4_warning(inode->i_sb,
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -1269,12 +1269,14 @@ int ext4_expand_extra_isize_ea(struct in
int isize_diff; /* How much do we need to grow i_extra_isize */

down_write(&EXT4_I(inode)->xattr_sem);
+ /*
+ * Set EXT4_STATE_NO_EXPAND to avoid recursion when marking inode dirty
+ */
+ ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND);
retry:
isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize;
- if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) {
- up_write(&EXT4_I(inode)->xattr_sem);
- return 0;
- }
+ if (EXT4_I(inode)->i_extra_isize >= new_extra_isize)
+ goto out;

header = IHDR(inode, raw_inode);
entry = IFIRST(header);
@@ -1299,8 +1301,7 @@ retry:
(void *)header, total_ino,
inode->i_sb->s_blocksize);
EXT4_I(inode)->i_extra_isize = new_extra_isize;
- error = 0;
- goto cleanup;
+ goto out;
}

/*
@@ -1460,6 +1461,8 @@ retry:
kfree(bs);
}
brelse(bh);
+out:
+ ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND);
up_write(&EXT4_I(inode)->xattr_sem);
return 0;

@@ -1471,6 +1474,10 @@ cleanup:
kfree(is);
kfree(bs);
brelse(bh);
+ /*
+ * We deliberately leave EXT4_STATE_NO_EXPAND set here since inode
+ * size expansion failed.
+ */
up_write(&EXT4_I(inode)->xattr_sem);
return error;
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:15 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ken Lin <ken...@advantech.com.tw>

commit 83d9956b7e6b310c1062df7894257251c625b22e upstream.

Avoid getting sample rate on B850V3 CP2114 as it is unsupported and
causes noisy "current rate is different from the runtime rate" messages
when playback starts.

Signed-off-by: Ken Lin <ken...@advantech.com.tw>
Signed-off-by: Akshay Bhat <aksha...@timesys.com>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
sound/usb/quirks.c | 1 +
1 file changed, 1 insertion(+)

--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1142,6 +1142,7 @@ bool snd_usb_get_sample_rate_quirk(struc
case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */
case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */
case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
+ case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */
case USB_ID(0x1de7, 0x0013): /* Phoenix Audio MT202exe */
case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */
case USB_ID(0x1de7, 0x0114): /* Phoenix Audio MT202pcs */

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:15 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------


From: Florian Westphal <f...@strlen.de>

[ Upstream commit d157bd761585605b7882935ffb86286919f62ea1 ]

Ben Hawkes says:
integer overflow in xt_alloc_table_info, which on 32-bit systems can
lead to small structure allocation and a copy_from_user based heap
corruption.

Reported-by: Ben Hawkes <haw...@google.com>
Signed-off-by: Florian Westphal <f...@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
net/netfilter/x_tables.c | 3 +++
1 file changed, 3 insertions(+)

--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -900,6 +900,9 @@ struct xt_table_info *xt_alloc_table_inf
if (sz < sizeof(*info))
return NULL;

+ if (sz < sizeof(*info))
+ return NULL;
+
/* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */
if ((SMP_ALIGN(size) >> PAGE_SHIFT) + 2 > totalram_pages)
return NULL;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:16 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vegard Nossum <vegard...@oracle.com>

commit 6b760bb2c63a9e322c0e4a0b5daf335ad93d5a33 upstream.

I got this:

divide error: 0000 [#1] PREEMPT SMP KASAN
CPU: 1 PID: 1327 Comm: a.out Not tainted 4.8.0-rc2+ #189
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org 04/01/2014
task: ffff8801120a9580 task.stack: ffff8801120b0000
RIP: 0010:[<ffffffff82c8bd9a>] [<ffffffff82c8bd9a>] snd_hrtimer_callback+0x1da/0x3f0
RSP: 0018:ffff88011aa87da8 EFLAGS: 00010006
RAX: 0000000000004f76 RBX: ffff880112655e88 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffff880112655ea0 RDI: 0000000000000001
RBP: ffff88011aa87e00 R08: ffff88013fff905c R09: ffff88013fff9048
R10: ffff88013fff9050 R11: 00000001050a7b8c R12: ffff880114778a00
R13: ffff880114778ab4 R14: ffff880114778b30 R15: 0000000000000000
FS: 00007f071647c700(0000) GS:ffff88011aa80000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000603001 CR3: 0000000112021000 CR4: 00000000000006e0
Stack:
0000000000000000 ffff880114778ab8 ffff880112655ea0 0000000000004f76
ffff880112655ec8 ffff880112655e80 ffff880112655e88 ffff88011aa98fc0
00000000b97ccf2b dffffc0000000000 ffff88011aa98fc0 ffff88011aa87ef0
Call Trace:
<IRQ>
[<ffffffff813abce7>] __hrtimer_run_queues+0x347/0xa00
[<ffffffff82c8bbc0>] ? snd_hrtimer_close+0x130/0x130
[<ffffffff813ab9a0>] ? retrigger_next_event+0x1b0/0x1b0
[<ffffffff813ae1a6>] ? hrtimer_interrupt+0x136/0x4b0
[<ffffffff813ae220>] hrtimer_interrupt+0x1b0/0x4b0
[<ffffffff8120f91e>] local_apic_timer_interrupt+0x6e/0xf0
[<ffffffff81227ad3>] ? kvm_guest_apic_eoi_write+0x13/0xc0
[<ffffffff83c35086>] smp_apic_timer_interrupt+0x76/0xa0
[<ffffffff83c3416c>] apic_timer_interrupt+0x8c/0xa0
<EOI>
[<ffffffff83c3239c>] ? _raw_spin_unlock_irqrestore+0x2c/0x60
[<ffffffff82c8185d>] snd_timer_start1+0xdd/0x670
[<ffffffff82c87015>] snd_timer_continue+0x45/0x80
[<ffffffff82c88100>] snd_timer_user_ioctl+0x1030/0x2830
[<ffffffff8159f3a0>] ? __follow_pte.isra.49+0x430/0x430
[<ffffffff82c870d0>] ? snd_timer_pause+0x80/0x80
[<ffffffff815a26fa>] ? do_wp_page+0x3aa/0x1c90
[<ffffffff815aa4f8>] ? handle_mm_fault+0xbc8/0x27f0
[<ffffffff815a9930>] ? __pmd_alloc+0x370/0x370
[<ffffffff82c870d0>] ? snd_timer_pause+0x80/0x80
[<ffffffff816b0733>] do_vfs_ioctl+0x193/0x1050
[<ffffffff816b05a0>] ? ioctl_preallocate+0x200/0x200
[<ffffffff81002f2f>] ? syscall_trace_enter+0x3cf/0xdb0
[<ffffffff815045ba>] ? __context_tracking_exit.part.4+0x9a/0x1e0
[<ffffffff81002b60>] ? exit_to_usermode_loop+0x190/0x190
[<ffffffff82001a97>] ? check_preemption_disabled+0x37/0x1e0
[<ffffffff81d93889>] ? security_file_ioctl+0x89/0xb0
[<ffffffff816b167f>] SyS_ioctl+0x8f/0xc0
[<ffffffff816b15f0>] ? do_vfs_ioctl+0x1050/0x1050
[<ffffffff81005524>] do_syscall_64+0x1c4/0x4e0
[<ffffffff83c32b2a>] entry_SYSCALL64_slow_path+0x25/0x25
Code: e8 fc 42 7b fe 8b 0d 06 8a 50 03 49 0f af cf 48 85 c9 0f 88 7c 01 00 00 48 89 4d a8 e8 e0 42 7b fe 48 8b 45 c0 48 8b 4d a8 48 99 <48> f7 f9 49 01 c7 e8 cb 42 7b fe 48 8b 55 d0 48 b8 00 00 00 00
RIP [<ffffffff82c8bd9a>] snd_hrtimer_callback+0x1da/0x3f0
RSP <ffff88011aa87da8>
---[ end trace 6aa380f756a21074 ]---

The problem happens when you call ioctl(SNDRV_TIMER_IOCTL_CONTINUE) on a
completely new/unused timer -- it will have ->sticks == 0, which causes a
divide by 0 in snd_hrtimer_callback().

Signed-off-by: Vegard Nossum <vegard...@oracle.com>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
sound/core/timer.c | 1 +
1 file changed, 1 insertion(+)

--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -837,6 +837,7 @@ int snd_timer_new(struct snd_card *card,
timer->tmr_subdevice = tid->subdevice;
if (id)
strlcpy(timer->id, id, sizeof(timer->id));
+ timer->sticks = 1;
INIT_LIST_HEAD(&timer->device_list);
INIT_LIST_HEAD(&timer->open_list_head);
INIT_LIST_HEAD(&timer->active_list_head);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:16 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------


From: Seth Forshee <seth.f...@canonical.com>

[ Upstream commit 2d7f9e2ad35e4e7a3086231f19bfab33c6a8a64a ]

Filesystem uids which don't map into a user namespace may result
in inode->i_uid being INVALID_UID. A symlink and its parent
could have different owners in the filesystem can both get
mapped to INVALID_UID, which may result in following a symlink
when this would not have otherwise been permitted when protected
symlinks are enabled.

Signed-off-by: Seth Forshee <seth.f...@canonical.com>
Acked-by: Serge Hallyn <serge....@canonical.com>
Signed-off-by: Eric W. Biederman <ebie...@xmission.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
fs/namei.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -887,6 +887,7 @@ static inline int may_follow_link(struct
{
const struct inode *inode;
const struct inode *parent;
+ kuid_t puid;

if (!sysctl_protected_symlinks)
return 0;
@@ -902,7 +903,8 @@ static inline int may_follow_link(struct
return 0;

/* Allowed if parent directory and link owner match. */
- if (uid_eq(parent->i_uid, inode->i_uid))
+ puid = parent->i_uid;
+ if (uid_valid(puid) && uid_eq(puid, inode->i_uid))
return 0;

if (nd->flags & LOOKUP_RCU)

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:16 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: John Stultz <john....@linaro.org>

commit a4f8f6667f099036c88f231dcad4cf233652c824 upstream.

It was reported that hibernation could fail on the 2nd attempt, where the
system hangs at hibernate() -> syscore_resume() -> i8237A_resume() ->
claim_dma_lock(), because the lock has already been taken.

However there is actually no other process would like to grab this lock on
that problematic platform.

Further investigation showed that the problem is triggered by setting
/sys/power/pm_trace to 1 before the 1st hibernation.

Since once pm_trace is enabled, the rtc becomes unmeaningful after suspend,
and meanwhile some BIOSes would like to adjust the 'invalid' RTC (e.g, smaller
than 1970) to the release date of that motherboard during POST stage, thus
after resumed, it may seem that the system had a significant long sleep time
which is a completely meaningless value.

Then in timekeeping_resume -> tk_debug_account_sleep_time, if the bit31 of the
sleep time happened to be set to 1, fls() returns 32 and we add 1 to
sleep_time_bin[32], which causes an out of bounds array access and therefor
memory being overwritten.

As depicted by System.map:
0xffffffff81c9d080 b sleep_time_bin
0xffffffff81c9d100 B dma_spin_lock
the dma_spin_lock.val is set to 1, which caused this problem.

This patch adds a sanity check in tk_debug_account_sleep_time()
to ensure we don't index past the sleep_time_bin array.

[jstultz: Problem diagnosed and original patch by Chen Yu, I've solved the
issue slightly differently, but borrowed his excelent explanation of the
issue here.]

Fixes: 5c83545f24ab "power: Add option to log time spent in suspend"
Reported-by: Janek Kozicki <cos...@gmail.com>
Reported-by: Chen Yu <yu.c...@intel.com>
Signed-off-by: John Stultz <john....@linaro.org>
Cc: linu...@vger.kernel.org
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Xunlei Pang <xp...@redhat.com>
Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
Cc: Zhang Rui <rui....@intel.com>
Link: http://lkml.kernel.org/r/1471993702-29148-3-git...@linaro.org
Signed-off-by: Thomas Gleixner <tg...@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
kernel/time/timekeeping_debug.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

--- a/kernel/time/timekeeping_debug.c
+++ b/kernel/time/timekeeping_debug.c
@@ -23,7 +23,9 @@

#include "timekeeping_internal.h"

-static unsigned int sleep_time_bin[32] = {0};
+#define NUM_BINS 32
+
+static unsigned int sleep_time_bin[NUM_BINS] = {0};

static int tk_debug_show_sleep_time(struct seq_file *s, void *data)
{
@@ -69,6 +71,9 @@ late_initcall(tk_debug_sleep_time_init);

void tk_debug_account_sleep_time(struct timespec64 *t)
{
- sleep_time_bin[fls(t->tv_sec)]++;
+ /* Cap bin index so we don't overflow the array */
+ int bin = min(fls(t->tv_sec), NUM_BINS-1);
+
+ sleep_time_bin[bin]++;
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:17 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------


From: "Matthew R. Ochs" <mro...@linux.vnet.ibm.com>

[ Upstream commit d5e26bb1d812ba74f29b6bcbc88c3dbfb3eed824 ]

Applications which use virtual LUN's that are backed by a physical LUN
over both adapter ports may experience an I/O failure in the event of a
link loss (e.g. cable pull).

Virtual LUNs may be accessed through one or both ports of the adapter.
This access is encoded in the translation entries that comprise the
virtual LUN and used by the AFU for load-balancing I/O and handling
failover scenarios. In a link loss scenario, even though the AFU is able
to maintain connectivity to the LUN, it is up to the application to
retry the failed I/O. When applications are unaware of the virtual LUN's
underlying topology, they are unable to make a sound decision of when to
retry an I/O and therefore are forced to make their reaction to a failed
I/O absolute. The result is either a failure to retry I/O or increased
latency for scenarios where a retry is pointless.

To remedy this scenario, provide feedback back to the application on
virtual LUN creation as to which ports the LUN may be accessed. LUN's
spanning both ports are candidates for a retry in a presence of an I/O
failure.

Signed-off-by: Matthew R. Ochs <mro...@linux.vnet.ibm.com>
Acked-by: Manoj Kumar <ma...@linux.vnet.ibm.com>
Reviewed-by: Uma Krishnan <ukr...@linux.vnet.ibm.com>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/scsi/cxlflash/vlun.c | 2 ++
include/uapi/scsi/cxlflash_ioctl.h | 10 ++++++++++
2 files changed, 12 insertions(+)

--- a/drivers/scsi/cxlflash/vlun.c
+++ b/drivers/scsi/cxlflash/vlun.c
@@ -1008,6 +1008,8 @@ int cxlflash_disk_virtual_open(struct sc
virt->last_lba = last_lba;
virt->rsrc_handle = rsrc_handle;

+ if (lli->port_sel == BOTH_PORTS)
+ virt->hdr.return_flags |= DK_CXLFLASH_ALL_PORTS_ACTIVE;
out:
if (likely(ctxi))
put_context(ctxi);
--- a/include/uapi/scsi/cxlflash_ioctl.h
+++ b/include/uapi/scsi/cxlflash_ioctl.h
@@ -31,6 +31,16 @@ struct dk_cxlflash_hdr {
};

/*
+ * Return flag definitions available to all ioctls
+ *
+ * Similar to the input flags, these are grown from the bottom-up with the
+ * intention that ioctl-specific return flag definitions would grow from the
+ * top-down, allowing the two sets to co-exist. While not required/enforced
+ * at this time, this provides future flexibility.
+ */
+#define DK_CXLFLASH_ALL_PORTS_ACTIVE 0x0000000000000001ULL
+
+/*
* Notes:
* -----
* The 'context_id' field of all ioctl structures contains the context

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:17 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 985dd4360fdf2533fe48a33a4a2094f2e4718dc0 ]

Add PCIIDs for new versions of the SOC, based on BSpec. Also add the
name of the versions as code comment where this is available. The new
versions don't have any changes visible to the kernel driver.

Signed-off-by: Imre Deak <imre...@intel.com>
Reviewed-by: Mika Kuoppala <mika.k...@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1453989852-13569-1-gi...@intel.com
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
include/drm/i915_pciids.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

--- a/include/drm/i915_pciids.h
+++ b/include/drm/i915_pciids.h
@@ -289,6 +289,8 @@
#define INTEL_BXT_IDS(info) \
INTEL_VGA_DEVICE(0x0A84, info), \
INTEL_VGA_DEVICE(0x1A84, info), \
- INTEL_VGA_DEVICE(0x5A84, info)
+ INTEL_VGA_DEVICE(0x1A85, info), \
+ INTEL_VGA_DEVICE(0x5A84, info), /* APL HD Graphics 505 */ \
+ INTEL_VGA_DEVICE(0x5A85, info) /* APL HD Graphics 500 */

#endif /* _I915_PCIIDS_H */

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:20 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------


From: Eric Dumazet <edum...@google.com>

[ Upstream commit 197c949e7798fbf28cfadc69d9ca0c2abbf93191 ]

Backport of this upstream commit into stable kernels :
89c22d8c3b27 ("net: Fix skb csum races when peeking")
exposed a bug in udp stack vs MSG_PEEK support, when user provides
a buffer smaller than skb payload.

In this case,
skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr),
msg->msg_iov);
returns -EFAULT.

This bug does not happen in upstream kernels since Al Viro did a great
job to replace this into :
skb_copy_and_csum_datagram_msg(skb, sizeof(struct udphdr), msg);
This variant is safe vs short buffers.

For the time being, instead reverting Herbert Xu patch and add back
skb->ip_summed invalid changes, simply store the result of
udp_lib_checksum_complete() so that we avoid computing the checksum a
second time, and avoid the problematic
skb_copy_and_csum_datagram_iovec() call.

This patch can be applied on recent kernels as it avoids a double
checksumming, then backported to stable kernels as a bug fix.

Signed-off-by: Eric Dumazet <edum...@google.com>
Acked-by: Herbert Xu <her...@gondor.apana.org.au>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
net/ipv4/udp.c | 6 ++++--
net/ipv6/udp.c | 6 ++++--
2 files changed, 8 insertions(+), 4 deletions(-)

--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1275,6 +1275,7 @@ int udp_recvmsg(struct sock *sk, struct
int peeked, off = 0;
int err;
int is_udplite = IS_UDPLITE(sk);
+ bool checksum_valid = false;
bool slow;

if (flags & MSG_ERRQUEUE)
@@ -1300,11 +1301,12 @@ try_again:
*/

if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
- if (udp_lib_checksum_complete(skb))
+ checksum_valid = !udp_lib_checksum_complete(skb);
+ if (!checksum_valid)
goto csum_copy_err;
}

- if (skb_csum_unnecessary(skb))
+ if (checksum_valid || skb_csum_unnecessary(skb))
err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
msg, copied);
else {
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -402,6 +402,7 @@ int udpv6_recvmsg(struct sock *sk, struc
int peeked, off = 0;
int err;
int is_udplite = IS_UDPLITE(sk);
+ bool checksum_valid = false;
int is_udp4;
bool slow;

@@ -433,11 +434,12 @@ try_again:
*/

if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
- if (udp_lib_checksum_complete(skb))
+ checksum_valid = !udp_lib_checksum_complete(skb);
+ if (!checksum_valid)
goto csum_copy_err;
}

- if (skb_csum_unnecessary(skb))
+ if (checksum_valid || skb_csum_unnecessary(skb))
err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
msg, copied);
else {

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:20 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jan Kara <ja...@suse.cz>

commit d0141191a20289f8955c1e03dad08e42e6f71ca9 upstream.

The code in ext4_expand_extra_isize_ea() treated new_extra_isize
argument sometimes as the desired target i_extra_isize and sometimes as
the amount by which we need to grow current i_extra_isize. These happen
to coincide when i_extra_isize is 0 which used to be the common case and
so nobody noticed this until recently when we added i_projid to the
inode and so i_extra_isize now needs to grow from 28 to 32 bytes.

The result of these bugs was that we sometimes unnecessarily decided to
move xattrs out of inode even if there was enough space and we often
ended up corrupting in-inode xattrs because arguments to
ext4_xattr_shift_entries() were just wrong. This could demonstrate
itself as BUG_ON in ext4_xattr_shift_entries() triggering.

Fix the problem by introducing new isize_diff variable and use it where
appropriate.

Reported-by: Dave Chinner <da...@fromorbit.com>
Signed-off-by: Jan Kara <ja...@suse.cz>
Signed-off-by: Theodore Ts'o <ty...@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
fs/ext4/xattr.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)

--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -1264,11 +1264,13 @@ int ext4_expand_extra_isize_ea(struct in
size_t min_offs, free;
int total_ino;
void *base, *start, *end;
- int extra_isize = 0, error = 0, tried_min_extra_isize = 0;
+ int error = 0, tried_min_extra_isize = 0;
int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
+ int isize_diff; /* How much do we need to grow i_extra_isize */

down_write(&EXT4_I(inode)->xattr_sem);
retry:
+ isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize;
if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) {
up_write(&EXT4_I(inode)->xattr_sem);
return 0;
@@ -1289,7 +1291,7 @@ retry:
total_ino = sizeof(struct ext4_xattr_ibody_header);

free = ext4_xattr_free_space(last, &min_offs, base, &total_ino);
- if (free >= new_extra_isize) {
+ if (free >= isize_diff) {
entry = IFIRST(header);
ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize
- new_extra_isize, (void *)raw_inode +
@@ -1321,7 +1323,7 @@ retry:
end = bh->b_data + bh->b_size;
min_offs = end - base;
free = ext4_xattr_free_space(first, &min_offs, base, NULL);
- if (free < new_extra_isize) {
+ if (free < isize_diff) {
if (!tried_min_extra_isize && s_min_extra_isize) {
tried_min_extra_isize++;
new_extra_isize = s_min_extra_isize;
@@ -1335,7 +1337,7 @@ retry:
free = inode->i_sb->s_blocksize;
}

- while (new_extra_isize > 0) {
+ while (isize_diff > 0) {
size_t offs, size, entry_size;
struct ext4_xattr_entry *small_entry = NULL;
struct ext4_xattr_info i = {
@@ -1366,7 +1368,7 @@ retry:
EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) +
EXT4_XATTR_LEN(last->e_name_len);
if (total_size <= free && total_size < min_total_size) {
- if (total_size < new_extra_isize) {
+ if (total_size < isize_diff) {
small_entry = last;
} else {
entry = last;
@@ -1423,20 +1425,19 @@ retry:
goto cleanup;

entry = IFIRST(header);
- if (entry_size + EXT4_XATTR_SIZE(size) >= new_extra_isize)
- shift_bytes = new_extra_isize;
+ if (entry_size + EXT4_XATTR_SIZE(size) >= isize_diff)
+ shift_bytes = isize_diff;
else
shift_bytes = entry_size + size;
/* Adjust the offsets and shift the remaining entries ahead */
- ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize -
- shift_bytes, (void *)raw_inode +
- EXT4_GOOD_OLD_INODE_SIZE + extra_isize + shift_bytes,
+ ext4_xattr_shift_entries(entry, -shift_bytes,
+ (void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
+ EXT4_I(inode)->i_extra_isize + shift_bytes,
(void *)header, total_ino - entry_size,
inode->i_sb->s_blocksize);

- extra_isize += shift_bytes;
- new_extra_isize -= shift_bytes;
- EXT4_I(inode)->i_extra_isize = extra_isize;
+ isize_diff -= shift_bytes;
+ EXT4_I(inode)->i_extra_isize += shift_bytes;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:23 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 5d2be1422e02ccd697ccfcd45c85b4a26e6178e2 ]

link_info.str is a char array of size 60. Memory after the NULL
byte is not initialized. Sending the whole object out can cause
a leak.

Signed-off-by: Kangjie Lu <kj...@gatech.edu>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
net/tipc/netlink_compat.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/net/tipc/netlink_compat.c
+++ b/net/tipc/netlink_compat.c
@@ -574,7 +574,8 @@ static int tipc_nl_compat_link_dump(stru

link_info.dest = nla_get_flag(link[TIPC_NLA_LINK_DEST]);
link_info.up = htonl(nla_get_flag(link[TIPC_NLA_LINK_UP]));
- strcpy(link_info.str, nla_data(link[TIPC_NLA_LINK_NAME]));
+ nla_strlcpy(link_info.str, nla_data(link[TIPC_NLA_LINK_NAME]),
+ TIPC_MAX_LINK_NAME);

return tipc_add_tlv(msg->rep, TIPC_TLV_LINK_INFO,
&link_info, sizeof(link_info));

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:24 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 19a6d156a7bd080f3a855a40a4a08ab475e34b4a ]

smatch detected a suspicious looking bitop condition:

drivers/net/ethernet/cavium/liquidio/lio_main.c:2529
handle_timestamp() warn: suspicious bitop condition

(skb_shinfo(skb)->tx_flags | SKBTX_IN_PROGRESS is always non-zero,
so the logic is definitely not correct. Use & to mask the correct
bit.

Signed-off-by: Colin Ian King <colin...@canonical.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/net/ethernet/cavium/liquidio/lio_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -2526,7 +2526,7 @@ static void handle_timestamp(struct octe

octeon_swap_8B_data(&resp->timestamp, 1);

- if (unlikely((skb_shinfo(skb)->tx_flags | SKBTX_IN_PROGRESS) != 0)) {
+ if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) != 0)) {
struct skb_shared_hwtstamps ts;
u64 ns = resp->timestamp;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:25 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Shrirang Bagul <shriran...@canonical.com>

commit 311042d1b67d9a1856a8e1294e7729fb86f64014 upstream.

This patch enables headset microphone on some variants of
Dell Inspiron 5468. (Dell SSID 0x07ad)

BugLink: https://bugs.launchpad.net/bugs/1617900
Signed-off-by: Shrirang Bagul <shriran...@canonical.com>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
sound/pci/hda/patch_realtek.c | 4 ++++
1 file changed, 4 insertions(+)

--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -5879,6 +5879,10 @@ static const struct snd_hda_pin_quirk al
{0x12, 0x90a60170},
{0x14, 0x90170120},
{0x21, 0x02211030}),
+ SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell Inspiron 5468", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ {0x12, 0x90a60180},
+ {0x14, 0x90170120},
+ {0x21, 0x02211030}),
SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC256_STANDARD_PINS),
SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:26 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 4efc6939a83c54fb3417541be48991afd0290ba3 ]

otherwise we lose ff commands: https://github.com/paroj/xpad/issues/27

Signed-off-by: Pavel Rojtberg <rojt...@gmail.com>
Cc: sta...@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry....@gmail.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/input/joystick/xpad.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -718,6 +718,7 @@ static bool xpad_prepare_next_out_packet
if (packet) {
memcpy(xpad->odata, packet->data, packet->len);
xpad->irq_out->transfer_buffer_length = packet->len;
+ packet->pending = false;
return true;
}

@@ -757,7 +758,6 @@ static void xpad_irq_out(struct urb *urb
switch (status) {
case 0:
/* success */
- xpad->out_packets[xpad->last_out_packet].pending = false;
xpad->irq_out_active = xpad_prepare_next_out_packet(xpad);
break;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:20:30 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 251e2d25bfb72b69edd414abfa42a41191d9657a ]

Fixed getting wrong configuration data of adapter type B and type D.

Signed-off-by: Ching Huang <chin...@areca.com.tw>
Reviewed-by: Hannes Reinicke <ha...@suse.de>
Reviewed-by: Johannes Thumshirn <jthum...@suse.de>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/scsi/arcmsr/arcmsr_hba.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)

--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -2694,15 +2694,15 @@ static bool arcmsr_hbaB_get_config(struc
acb->firm_model,
acb->firm_version);

- acb->signature = readl(&reg->message_rwbuffer[1]);
+ acb->signature = readl(&reg->message_rwbuffer[0]);
/*firm_signature,1,00-03*/
- acb->firm_request_len = readl(&reg->message_rwbuffer[2]);
+ acb->firm_request_len = readl(&reg->message_rwbuffer[1]);
/*firm_request_len,1,04-07*/
- acb->firm_numbers_queue = readl(&reg->message_rwbuffer[3]);
+ acb->firm_numbers_queue = readl(&reg->message_rwbuffer[2]);
/*firm_numbers_queue,2,08-11*/
- acb->firm_sdram_size = readl(&reg->message_rwbuffer[4]);
+ acb->firm_sdram_size = readl(&reg->message_rwbuffer[3]);
/*firm_sdram_size,3,12-15*/
- acb->firm_hd_channels = readl(&reg->message_rwbuffer[5]);
+ acb->firm_hd_channels = readl(&reg->message_rwbuffer[4]);
/*firm_ide_channels,4,16-19*/
acb->firm_cfg_version = readl(&reg->message_rwbuffer[25]); /*firm_cfg_version,25,100-103*/
/*firm_ide_channels,4,16-19*/
@@ -2880,15 +2880,15 @@ static bool arcmsr_hbaD_get_config(struc
iop_device_map++;
count--;
}
- acb->signature = readl(&reg->msgcode_rwbuffer[1]);
+ acb->signature = readl(&reg->msgcode_rwbuffer[0]);
/*firm_signature,1,00-03*/
- acb->firm_request_len = readl(&reg->msgcode_rwbuffer[2]);
+ acb->firm_request_len = readl(&reg->msgcode_rwbuffer[1]);
/*firm_request_len,1,04-07*/
- acb->firm_numbers_queue = readl(&reg->msgcode_rwbuffer[3]);
+ acb->firm_numbers_queue = readl(&reg->msgcode_rwbuffer[2]);
/*firm_numbers_queue,2,08-11*/
- acb->firm_sdram_size = readl(&reg->msgcode_rwbuffer[4]);
+ acb->firm_sdram_size = readl(&reg->msgcode_rwbuffer[3]);
/*firm_sdram_size,3,12-15*/
- acb->firm_hd_channels = readl(&reg->msgcode_rwbuffer[5]);
+ acb->firm_hd_channels = readl(&reg->msgcode_rwbuffer[4]);
/*firm_hd_channels,4,16-19*/
acb->firm_cfg_version = readl(&reg->msgcode_rwbuffer[25]);
pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n",

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:25:41 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <ti...@suse.de>

commit 816f318b2364262a51024096da7ca3b84e78e3b5 upstream.

When a seq-virmidi driver is initialized, it registers a rawmidi
instance with its callback to create an associated seq kernel client.
Currently it's done throughly in rawmidi's register_mutex context.
Recently it was found that this may lead to a deadlock another rawmidi
device that is being attached with the sequencer is accessed, as both
open with the same register_mutex. This was actually triggered by
syzkaller, as Dmitry Vyukov reported:

======================================================
[ INFO: possible circular locking dependency detected ]
4.8.0-rc1+ #11 Not tainted
-------------------------------------------------------
syz-executor/7154 is trying to acquire lock:
(register_mutex#5){+.+.+.}, at: [<ffffffff84fd6d4b>] snd_rawmidi_kernel_open+0x4b/0x260 sound/core/rawmidi.c:341

but task is already holding lock:
(&grp->list_mutex){++++.+}, at: [<ffffffff850138bb>] check_and_subscribe_port+0x5b/0x5c0 sound/core/seq/seq_ports.c:495

which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:

-> #1 (&grp->list_mutex){++++.+}:
[<ffffffff8147a3a8>] lock_acquire+0x208/0x430 kernel/locking/lockdep.c:3746
[<ffffffff863f6199>] down_read+0x49/0xc0 kernel/locking/rwsem.c:22
[< inline >] deliver_to_subscribers sound/core/seq/seq_clientmgr.c:681
[<ffffffff85005c5e>] snd_seq_deliver_event+0x35e/0x890 sound/core/seq/seq_clientmgr.c:822
[<ffffffff85006e96>] > snd_seq_kernel_client_dispatch+0x126/0x170 sound/core/seq/seq_clientmgr.c:2418
[<ffffffff85012c52>] snd_seq_system_broadcast+0xb2/0xf0 sound/core/seq/seq_system.c:101
[<ffffffff84fff70a>] snd_seq_create_kernel_client+0x24a/0x330 sound/core/seq/seq_clientmgr.c:2297
[< inline >] snd_virmidi_dev_attach_seq sound/core/seq/seq_virmidi.c:383
[<ffffffff8502d29f>] snd_virmidi_dev_register+0x29f/0x750 sound/core/seq/seq_virmidi.c:450
[<ffffffff84fd208c>] snd_rawmidi_dev_register+0x30c/0xd40 sound/core/rawmidi.c:1645
[<ffffffff84f816d3>] __snd_device_register.part.0+0x63/0xc0 sound/core/device.c:164
[< inline >] __snd_device_register sound/core/device.c:162
[<ffffffff84f8235d>] snd_device_register_all+0xad/0x110 sound/core/device.c:212
[<ffffffff84f7546f>] snd_card_register+0xef/0x6c0 sound/core/init.c:749
[<ffffffff85040b7f>] snd_virmidi_probe+0x3ef/0x590 sound/drivers/virmidi.c:123
[<ffffffff833ebf7b>] platform_drv_probe+0x8b/0x170 drivers/base/platform.c:564
......

-> #0 (register_mutex#5){+.+.+.}:
[< inline >] check_prev_add kernel/locking/lockdep.c:1829
[< inline >] check_prevs_add kernel/locking/lockdep.c:1939
[< inline >] validate_chain kernel/locking/lockdep.c:2266
[<ffffffff814791f4>] __lock_acquire+0x4d44/0x4d80 kernel/locking/lockdep.c:3335
[<ffffffff8147a3a8>] lock_acquire+0x208/0x430 kernel/locking/lockdep.c:3746
[< inline >] __mutex_lock_common kernel/locking/mutex.c:521
[<ffffffff863f0ef1>] mutex_lock_nested+0xb1/0xa20 kernel/locking/mutex.c:621
[<ffffffff84fd6d4b>] snd_rawmidi_kernel_open+0x4b/0x260 sound/core/rawmidi.c:341
[<ffffffff8502e7c7>] midisynth_subscribe+0xf7/0x350 sound/core/seq/seq_midi.c:188
[< inline >] subscribe_port sound/core/seq/seq_ports.c:427
[<ffffffff85013cc7>] check_and_subscribe_port+0x467/0x5c0 sound/core/seq/seq_ports.c:510
[<ffffffff85015da9>] snd_seq_port_connect+0x2c9/0x500 sound/core/seq/seq_ports.c:579
[<ffffffff850079b8>] snd_seq_ioctl_subscribe_port+0x1d8/0x2b0 sound/core/seq/seq_clientmgr.c:1480
[<ffffffff84ffe9e4>] snd_seq_do_ioctl+0x184/0x1e0 sound/core/seq/seq_clientmgr.c:2225
[<ffffffff84ffeae8>] snd_seq_kernel_client_ctl+0xa8/0x110 sound/core/seq/seq_clientmgr.c:2440
[<ffffffff85027664>] snd_seq_oss_midi_open+0x3b4/0x610 sound/core/seq/oss/seq_oss_midi.c:375
[<ffffffff85023d67>] snd_seq_oss_synth_setup_midi+0x107/0x4c0 sound/core/seq/oss/seq_oss_synth.c:281
[<ffffffff8501b0a8>] snd_seq_oss_open+0x748/0x8d0 sound/core/seq/oss/seq_oss_init.c:274
[<ffffffff85019d8a>] odev_open+0x6a/0x90 sound/core/seq/oss/seq_oss.c:138
[<ffffffff84f7040f>] soundcore_open+0x30f/0x640 sound/sound_core.c:639
......

other info that might help us debug this:

Possible unsafe locking scenario:

CPU0 CPU1
---- ----
lock(&grp->list_mutex);
lock(register_mutex#5);
lock(&grp->list_mutex);
lock(register_mutex#5);

*** DEADLOCK ***
======================================================

The fix is to simply move the registration parts in
snd_rawmidi_dev_register() to the outside of the register_mutex lock.
The lock is needed only to manage the linked list, and it's not
necessarily to cover the whole initialization process.

Reported-by: Dmitry Vyukov <dvy...@google.com>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
sound/core/rawmidi.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -1633,11 +1633,13 @@ static int snd_rawmidi_dev_register(stru
return -EBUSY;
}
list_add_tail(&rmidi->list, &snd_rawmidi_devices);
+ mutex_unlock(&register_mutex);
err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI,
rmidi->card, rmidi->device,
&snd_rawmidi_f_ops, rmidi, &rmidi->dev);
if (err < 0) {
rmidi_err(rmidi, "unable to register\n");
+ mutex_lock(&register_mutex);
list_del(&rmidi->list);
mutex_unlock(&register_mutex);
return err;
@@ -1645,6 +1647,7 @@ static int snd_rawmidi_dev_register(stru
if (rmidi->ops && rmidi->ops->dev_register &&
(err = rmidi->ops->dev_register(rmidi)) < 0) {
snd_unregister_device(&rmidi->dev);
+ mutex_lock(&register_mutex);
list_del(&rmidi->list);
mutex_unlock(&register_mutex);
return err;
@@ -1677,7 +1680,6 @@ static int snd_rawmidi_dev_register(stru
}
}
#endif /* CONFIG_SND_OSSEMUL */
- mutex_unlock(&register_mutex);
sprintf(name, "midi%d", rmidi->device);
entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root);
if (entry) {

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:25:43 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miklos Szeredi <msze...@redhat.com>

commit c11b9fdd6a612f376a5e886505f1c54c16d8c380 upstream.

Clear out posix acl xattrs on workdir and also reset the mode after
creation so that an inherited sgid bit is cleared.

Signed-off-by: Miklos Szeredi <msze...@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
fs/overlayfs/super.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -763,6 +763,10 @@ retry:
struct kstat stat = {
.mode = S_IFDIR | 0,
};
+ struct iattr attr = {
+ .ia_valid = ATTR_MODE,
+ .ia_mode = stat.mode,
+ };

if (work->d_inode) {
err = -EEXIST;
@@ -778,6 +782,21 @@ retry:
err = ovl_create_real(dir, work, &stat, NULL, NULL, true);
if (err)
goto out_dput;
+
+ err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_DEFAULT);
+ if (err && err != -ENODATA)
+ goto out_dput;
+
+ err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_ACCESS);
+ if (err && err != -ENODATA)
+ goto out_dput;
+
+ /* Clear any inherited mode bits */
+ inode_lock(work->d_inode);
+ err = notify_change(work, &attr, NULL);
+ inode_unlock(work->d_inode);
+ if (err)
+ goto out_dput;
}
out_unlock:
mutex_unlock(&dir->i_mutex);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:25:55 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Michael Neuling <mi...@neuling.org>

commit 190ce8693c23eae09ba5f303a83bf2fbeb6478b1 upstream.

Currently we have 2 segments that are bolted for the kernel linear
mapping (ie 0xc000... addresses). This is 0 to 1TB and also the kernel
stacks. Anything accessed outside of these regions may need to be
faulted in. (In practice machines with TM always have 1T segments)

If a machine has < 2TB of memory we never fault on the kernel linear
mapping as these two segments cover all physical memory. If a machine
has > 2TB of memory, there may be structures outside of these two
segments that need to be faulted in. This faulting can occur when
running as a guest as the hypervisor may remove any SLB that's not
bolted.

When we treclaim and trecheckpoint we have a window where we need to
run with the userspace GPRs. This means that we no longer have a valid
stack pointer in r1. For this window we therefore clear MSR RI to
indicate that any exceptions taken at this point won't be able to be
handled. This means that we can't take segment misses in this RI=0
window.

In this RI=0 region, we currently access the thread_struct for the
process being context switched to or from. This thread_struct access
may cause a segment fault since it's not guaranteed to be covered by
the two bolted segment entries described above.

We've seen this with a crash when running as a guest with > 2TB of
memory on PowerVM:

Unrecoverable exception 4100 at c00000000004f138
Oops: Unrecoverable exception, sig: 6 [#1]
SMP NR_CPUS=2048 NUMA pSeries
CPU: 1280 PID: 7755 Comm: kworker/1280:1 Tainted: G X 4.4.13-46-default #1
task: c000189001df4210 ti: c000189001d5c000 task.ti: c000189001d5c000
NIP: c00000000004f138 LR: 0000000010003a24 CTR: 0000000010001b20
REGS: c000189001d5f730 TRAP: 4100 Tainted: G X (4.4.13-46-default)
MSR: 8000000100001031 <SF,ME,IR,DR,LE> CR: 24000048 XER: 00000000
CFAR: c00000000004ed18 SOFTE: 0
GPR00: ffffffffc58d7b60 c000189001d5f9b0 00000000100d7d00 000000003a738288
GPR04: 0000000000002781 0000000000000006 0000000000000000 c0000d1f4d889620
GPR08: 000000000000c350 00000000000008ab 00000000000008ab 00000000100d7af0
GPR12: 00000000100d7ae8 00003ffe787e67a0 0000000000000000 0000000000000211
GPR16: 0000000010001b20 0000000000000000 0000000000800000 00003ffe787df110
GPR20: 0000000000000001 00000000100d1e10 0000000000000000 00003ffe787df050
GPR24: 0000000000000003 0000000000010000 0000000000000000 00003fffe79e2e30
GPR28: 00003fffe79e2e68 00000000003d0f00 00003ffe787e67a0 00003ffe787de680
NIP [c00000000004f138] restore_gprs+0xd0/0x16c
LR [0000000010003a24] 0x10003a24
Call Trace:
[c000189001d5f9b0] [c000189001d5f9f0] 0xc000189001d5f9f0 (unreliable)
[c000189001d5fb90] [c00000000001583c] tm_recheckpoint+0x6c/0xa0
[c000189001d5fbd0] [c000000000015c40] __switch_to+0x2c0/0x350
[c000189001d5fc30] [c0000000007e647c] __schedule+0x32c/0x9c0
[c000189001d5fcb0] [c0000000007e6b58] schedule+0x48/0xc0
[c000189001d5fce0] [c0000000000deabc] worker_thread+0x22c/0x5b0
[c000189001d5fd80] [c0000000000e7000] kthread+0x110/0x130
[c000189001d5fe30] [c000000000009538] ret_from_kernel_thread+0x5c/0xa4
Instruction dump:
7cb103a6 7cc0e3a6 7ca222a6 78a58402 38c00800 7cc62838 08860000 7cc000a6
38a00006 78c60022 7cc62838 0b060000 <e8c701a0> 7ccff120 e8270078 e8a70098
---[ end trace 602126d0a1dedd54 ]---

This fixes this by copying the required data from the thread_struct to
the stack before we clear MSR RI. Then once we clear RI, we only access
the stack, guaranteeing there's no segment miss.

We also tighten the region over which we set RI=0 on the treclaim()
path. This may have a slight performance impact since we're adding an
mtmsr instruction.

Fixes: 090b9284d725 ("powerpc/tm: Clear MSR RI in non-recoverable TM code")
Signed-off-by: Michael Neuling <mi...@neuling.org>
Reviewed-by: Cyril Bur <cyri...@gmail.com>
Signed-off-by: Michael Ellerman <m...@ellerman.id.au>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
arch/powerpc/kernel/tm.S | 61 +++++++++++++++++++++++++++++++++--------------
1 file changed, 44 insertions(+), 17 deletions(-)

--- a/arch/powerpc/kernel/tm.S
+++ b/arch/powerpc/kernel/tm.S
@@ -110,17 +110,11 @@ _GLOBAL(tm_reclaim)
std r3, STK_PARAM(R3)(r1)
SAVE_NVGPRS(r1)

- /* We need to setup MSR for VSX register save instructions. Here we
- * also clear the MSR RI since when we do the treclaim, we won't have a
- * valid kernel pointer for a while. We clear RI here as it avoids
- * adding another mtmsr closer to the treclaim. This makes the region
- * maked as non-recoverable wider than it needs to be but it saves on
- * inserting another mtmsrd later.
- */
+ /* We need to setup MSR for VSX register save instructions. */
mfmsr r14
mr r15, r14
ori r15, r15, MSR_FP
- li r16, MSR_RI
+ li r16, 0
ori r16, r16, MSR_EE /* IRQs hard off */
andc r15, r15, r16
oris r15, r15, MSR_VEC@h
@@ -176,7 +170,17 @@ dont_backup_fp:
1: tdeqi r6, 0
EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0

- /* The moment we treclaim, ALL of our GPRs will switch
+ /* Clear MSR RI since we are about to change r1, EE is already off. */
+ li r4, 0
+ mtmsrd r4, 1
+
+ /*
+ * BE CAREFUL HERE:
+ * At this point we can't take an SLB miss since we have MSR_RI
+ * off. Load only to/from the stack/paca which are in SLB bolted regions
+ * until we turn MSR RI back on.
+ *
+ * The moment we treclaim, ALL of our GPRs will switch
* to user register state. (FPRs, CCR etc. also!)
* Use an sprg and a tm_scratch in the PACA to shuffle.
*/
@@ -197,6 +201,11 @@ dont_backup_fp:

/* Store the PPR in r11 and reset to decent value */
std r11, GPR11(r1) /* Temporary stash */
+
+ /* Reset MSR RI so we can take SLB faults again */
+ li r11, MSR_RI
+ mtmsrd r11, 1
+
mfspr r11, SPRN_PPR
HMT_MEDIUM

@@ -397,11 +406,6 @@ restore_gprs:
ld r5, THREAD_TM_DSCR(r3)
ld r6, THREAD_TM_PPR(r3)

- /* Clear the MSR RI since we are about to change R1. EE is already off
- */
- li r4, 0
- mtmsrd r4, 1
-
REST_GPR(0, r7) /* GPR0 */
REST_2GPRS(2, r7) /* GPR2-3 */
REST_GPR(4, r7) /* GPR4 */
@@ -439,10 +443,33 @@ restore_gprs:
ld r6, _CCR(r7)
mtcr r6

- REST_GPR(1, r7) /* GPR1 */
- REST_GPR(5, r7) /* GPR5-7 */
REST_GPR(6, r7)
- ld r7, GPR7(r7)
+
+ /*
+ * Store r1 and r5 on the stack so that we can access them
+ * after we clear MSR RI.
+ */
+
+ REST_GPR(5, r7)
+ std r5, -8(r1)
+ ld r5, GPR1(r7)
+ std r5, -16(r1)
+
+ REST_GPR(7, r7)
+
+ /* Clear MSR RI since we are about to change r1. EE is already off */
+ li r5, 0
+ mtmsrd r5, 1
+
+ /*
+ * BE CAREFUL HERE:
+ * At this point we can't take an SLB miss since we have MSR_RI
+ * off. Load only to/from the stack/paca which are in SLB bolted regions
+ * until we turn MSR RI back on.
+ */
+
+ ld r5, -8(r1)
+ ld r1, -16(r1)

/* Commit register state as checkpointed state: */
TRECHKPT

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:25:56 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Balbir Singh <bsing...@gmail.com>

commit 568ac888215c7fb2fabe8ea739b00ec3c1f5d440 upstream.

cgroup_threadgroup_rwsem is acquired in read mode during process exit
and fork. It is also grabbed in write mode during
__cgroups_proc_write(). I've recently run into a scenario with lots
of memory pressure and OOM and I am beginning to see

systemd

__switch_to+0x1f8/0x350
__schedule+0x30c/0x990
schedule+0x48/0xc0
percpu_down_write+0x114/0x170
__cgroup_procs_write.isra.12+0xb8/0x3c0
cgroup_file_write+0x74/0x1a0
kernfs_fop_write+0x188/0x200
__vfs_write+0x6c/0xe0
vfs_write+0xc0/0x230
SyS_write+0x6c/0x110
system_call+0x38/0xb4

This thread is waiting on the reader of cgroup_threadgroup_rwsem to
exit. The reader itself is under memory pressure and has gone into
reclaim after fork. There are times the reader also ends up waiting on
oom_lock as well.

__switch_to+0x1f8/0x350
__schedule+0x30c/0x990
schedule+0x48/0xc0
jbd2_log_wait_commit+0xd4/0x180
ext4_evict_inode+0x88/0x5c0
evict+0xf8/0x2a0
dispose_list+0x50/0x80
prune_icache_sb+0x6c/0x90
super_cache_scan+0x190/0x210
shrink_slab.part.15+0x22c/0x4c0
shrink_zone+0x288/0x3c0
do_try_to_free_pages+0x1dc/0x590
try_to_free_pages+0xdc/0x260
__alloc_pages_nodemask+0x72c/0xc90
alloc_pages_current+0xb4/0x1a0
page_table_alloc+0xc0/0x170
__pte_alloc+0x58/0x1f0
copy_page_range+0x4ec/0x950
copy_process.isra.5+0x15a0/0x1870
_do_fork+0xa8/0x4b0
ppc_clone+0x8/0xc

In the meanwhile, all processes exiting/forking are blocked almost
stalling the system.

This patch moves the threadgroup_change_begin from before
cgroup_fork() to just before cgroup_canfork(). There is no nee to
worry about threadgroup changes till the task is actually added to the
threadgroup. This avoids having to call reclaim with
cgroup_threadgroup_rwsem held.

tj: Subject and description edits.

Signed-off-by: Balbir Singh <bsing...@gmail.com>
Acked-by: Zefan Li <liz...@huawei.com>
Cc: Oleg Nesterov <ol...@redhat.com>
Cc: Andrew Morton <ak...@linux-foundation.org>
Signed-off-by: Tejun Heo <t...@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
kernel/fork.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1369,7 +1369,6 @@ static struct task_struct *copy_process(
p->real_start_time = ktime_get_boot_ns();
p->io_context = NULL;
p->audit_context = NULL;
- threadgroup_change_begin(current);
cgroup_fork(p);
#ifdef CONFIG_NUMA
p->mempolicy = mpol_dup(p->mempolicy);
@@ -1521,6 +1520,7 @@ static struct task_struct *copy_process(
INIT_LIST_HEAD(&p->thread_group);
p->task_works = NULL;

+ threadgroup_change_begin(current);
/*
* Ensure that the cgroup subsystem policies allow the new process to be
* forked. It should be noted the the new process's css_set can be changed
@@ -1621,6 +1621,7 @@ static struct task_struct *copy_process(
bad_fork_cancel_cgroup:
cgroup_cancel_fork(p, cgrp_ss_priv);
bad_fork_free_pid:
+ threadgroup_change_end(current);
if (pid != &init_struct_pid)
free_pid(pid);
bad_fork_cleanup_io:
@@ -1651,7 +1652,6 @@ bad_fork_cleanup_policy:
mpol_put(p->mempolicy);
bad_fork_cleanup_threadgroup_lock:
#endif
- threadgroup_change_end(current);
delayacct_tsk_free(p);
bad_fork_cleanup_count:
atomic_dec(&p->cred->user->processes);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:26:02 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Manoj Kumar <ma...@linux.vnet.ibm.com>

[ Upstream commit a9be294ecb3b9dc82b15625631b153f871181d16 ]

The original fix to escalate a 'login timed out' error to a LINK_RESET
was only made for one of the two ports on the card. This fix resolves
the same issue for the second port (port 1).

Signed-off-by: Manoj N. Kumar <ma...@linux.vnet.ibm.com>
Acked-by: Matthew R. Ochs <mro...@linux.vnet.ibm.com>
Reviewed-by: Uma Krishnan <ukr...@linux.vnet.ibm.com>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/scsi/cxlflash/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/scsi/cxlflash/main.c
+++ b/drivers/scsi/cxlflash/main.c
@@ -1141,7 +1141,7 @@ static const struct asyc_intr_info ainfo
{SISL_ASTATUS_FC1_OTHER, "other error", 1, CLR_FC_ERROR | LINK_RESET},
{SISL_ASTATUS_FC1_LOGO, "target initiated LOGO", 1, 0},
{SISL_ASTATUS_FC1_CRC_T, "CRC threshold exceeded", 1, LINK_RESET},
- {SISL_ASTATUS_FC1_LOGI_R, "login timed out, retrying", 1, 0},
+ {SISL_ASTATUS_FC1_LOGI_R, "login timed out, retrying", 1, LINK_RESET},
{SISL_ASTATUS_FC1_LOGI_F, "login failed", 1, CLR_FC_ERROR},
{SISL_ASTATUS_FC1_LOGI_S, "login succeeded", 1, SCAN_HOST},
{SISL_ASTATUS_FC1_LINK_DN, "link down", 1, 0},

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:26:14 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Kent Overstreet <kent.ov...@gmail.com>

commit acc9cf8c66c66b2cbbdb4a375537edee72be64df upstream.

This patch fixes a cachedev registration-time allocation deadlock.
This can deadlock on boot if your initrd auto-registeres bcache devices:

Allocator thread:
[ 720.727614] INFO: task bcache_allocato:3833 blocked for more than 120 seconds.
[ 720.732361] [<ffffffff816eeac7>] schedule+0x37/0x90
[ 720.732963] [<ffffffffa05192b8>] bch_bucket_alloc+0x188/0x360 [bcache]
[ 720.733538] [<ffffffff810e6950>] ? prepare_to_wait_event+0xf0/0xf0
[ 720.734137] [<ffffffffa05302bd>] bch_prio_write+0x19d/0x340 [bcache]
[ 720.734715] [<ffffffffa05190bf>] bch_allocator_thread+0x3ff/0x470 [bcache]
[ 720.735311] [<ffffffff816ee41c>] ? __schedule+0x2dc/0x950
[ 720.735884] [<ffffffffa0518cc0>] ? invalidate_buckets+0x980/0x980 [bcache]

Registration thread:
[ 720.710403] INFO: task bash:3531 blocked for more than 120 seconds.
[ 720.715226] [<ffffffff816eeac7>] schedule+0x37/0x90
[ 720.715805] [<ffffffffa05235cd>] __bch_btree_map_nodes+0x12d/0x150 [bcache]
[ 720.716409] [<ffffffffa0522d30>] ? bch_btree_insert_check_key+0x1c0/0x1c0 [bcache]
[ 720.717008] [<ffffffffa05236e4>] bch_btree_insert+0xf4/0x170 [bcache]
[ 720.717586] [<ffffffff810e6950>] ? prepare_to_wait_event+0xf0/0xf0
[ 720.718191] [<ffffffffa0527d9a>] bch_journal_replay+0x14a/0x290 [bcache]
[ 720.718766] [<ffffffff810cc90d>] ? ttwu_do_activate.constprop.94+0x5d/0x70
[ 720.719369] [<ffffffff810cf684>] ? try_to_wake_up+0x1d4/0x350
[ 720.719968] [<ffffffffa05317d0>] run_cache_set+0x580/0x8e0 [bcache]
[ 720.720553] [<ffffffffa053302e>] register_bcache+0xe2e/0x13b0 [bcache]
[ 720.721153] [<ffffffff81354cef>] kobj_attr_store+0xf/0x20
[ 720.721730] [<ffffffff812a2dad>] sysfs_kf_write+0x3d/0x50
[ 720.722327] [<ffffffff812a225a>] kernfs_fop_write+0x12a/0x180
[ 720.722904] [<ffffffff81225177>] __vfs_write+0x37/0x110
[ 720.723503] [<ffffffff81228048>] ? __sb_start_write+0x58/0x110
[ 720.724100] [<ffffffff812cedb3>] ? security_file_permission+0x23/0xa0
[ 720.724675] [<ffffffff812258a9>] vfs_write+0xa9/0x1b0
[ 720.725275] [<ffffffff8102479c>] ? do_audit_syscall_entry+0x6c/0x70
[ 720.725849] [<ffffffff81226755>] SyS_write+0x55/0xd0
[ 720.726451] [<ffffffff8106a390>] ? do_page_fault+0x30/0x80
[ 720.727045] [<ffffffff816f2cae>] system_call_fastpath+0x12/0x71

The fifo code in upstream bcache can't use the last element in the buffer,
which was the cause of the bug: if you asked for a power of two size,
it'd give you a fifo that could hold one less than what you asked for
rather than allocating a buffer twice as big.

Signed-off-by: Kent Overstreet <kent.ov...@gmail.com>
Tested-by: Eric Wheeler <bca...@linux.ewheeler.net>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
drivers/md/bcache/super.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1818,7 +1818,7 @@ static int cache_alloc(struct cache_sb *
free = roundup_pow_of_two(ca->sb.nbuckets) >> 10;

if (!init_fifo(&ca->free[RESERVE_BTREE], 8, GFP_KERNEL) ||
- !init_fifo(&ca->free[RESERVE_PRIO], prio_buckets(ca), GFP_KERNEL) ||
+ !init_fifo_exact(&ca->free[RESERVE_PRIO], prio_buckets(ca), GFP_KERNEL) ||
!init_fifo(&ca->free[RESERVE_MOVINGGC], free, GFP_KERNEL) ||
!init_fifo(&ca->free[RESERVE_NONE], free, GFP_KERNEL) ||
!init_fifo(&ca->free_inc, free << 2, GFP_KERNEL) ||

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:26:29 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 6a480a7842545ec520a91730209ec0bae41694c1 ]

First of all, trying to open them r/w is idiocy; it's guaranteed to fail.
Moreover, assigning ->f_pos and assuming that everything will work is
blatantly broken - try that with e.g. tmpfs as underlying layer and watch
the fireworks. There may be a non-trivial amount of state associated with
current IO position, well beyond the numeric offset. Using the single
struct file associated with underlying inode is really not a good idea;
we ought to open one for each ecryptfs directory struct file.

Additionally, file_operations both for directories and non-directories are
full of pointless methods; non-directories should *not* have ->iterate(),
directories should not have ->flush(), ->fasync() and ->splice_read().

Signed-off-by: Al Viro <vi...@zeniv.linux.org.uk>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
fs/ecryptfs/file.c | 71 +++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 55 insertions(+), 16 deletions(-)

--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -112,7 +112,6 @@ static int ecryptfs_readdir(struct file
.sb = inode->i_sb,
};
lower_file = ecryptfs_file_to_lower(file);
- lower_file->f_pos = ctx->pos;
rc = iterate_dir(lower_file, &buf.ctx);
ctx->pos = buf.ctx.pos;
if (rc < 0)
@@ -236,14 +235,6 @@ static int ecryptfs_open(struct inode *i
}
ecryptfs_set_file_lower(
file, ecryptfs_inode_to_private(inode)->lower_file);
- if (d_is_dir(ecryptfs_dentry)) {
- ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
- mutex_lock(&crypt_stat->cs_mutex);
- crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
- mutex_unlock(&crypt_stat->cs_mutex);
- rc = 0;
- goto out;
- }
rc = read_or_initialize_metadata(ecryptfs_dentry);
if (rc)
goto out_put;
@@ -260,6 +251,45 @@ out:
return rc;
}

+/**
+ * ecryptfs_dir_open
+ * @inode: inode speciying file to open
+ * @file: Structure to return filled in
+ *
+ * Opens the file specified by inode.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+static int ecryptfs_dir_open(struct inode *inode, struct file *file)
+{
+ struct dentry *ecryptfs_dentry = file->f_path.dentry;
+ /* Private value of ecryptfs_dentry allocated in
+ * ecryptfs_lookup() */
+ struct ecryptfs_file_info *file_info;
+ struct file *lower_file;
+
+ /* Released in ecryptfs_release or end of function if failure */
+ file_info = kmem_cache_zalloc(ecryptfs_file_info_cache, GFP_KERNEL);
+ ecryptfs_set_file_private(file, file_info);
+ if (unlikely(!file_info)) {
+ ecryptfs_printk(KERN_ERR,
+ "Error attempting to allocate memory\n");
+ return -ENOMEM;
+ }
+ lower_file = dentry_open(ecryptfs_dentry_to_lower_path(ecryptfs_dentry),
+ file->f_flags, current_cred());
+ if (IS_ERR(lower_file)) {
+ printk(KERN_ERR "%s: Error attempting to initialize "
+ "the lower file for the dentry with name "
+ "[%pd]; rc = [%ld]\n", __func__,
+ ecryptfs_dentry, PTR_ERR(lower_file));
+ kmem_cache_free(ecryptfs_file_info_cache, file_info);
+ return PTR_ERR(lower_file);
+ }
+ ecryptfs_set_file_lower(file, lower_file);
+ return 0;
+}
+
static int ecryptfs_flush(struct file *file, fl_owner_t td)
{
struct file *lower_file = ecryptfs_file_to_lower(file);
@@ -280,6 +310,19 @@ static int ecryptfs_release(struct inode
return 0;
}

+static int ecryptfs_dir_release(struct inode *inode, struct file *file)
+{
+ fput(ecryptfs_file_to_lower(file));
+ kmem_cache_free(ecryptfs_file_info_cache,
+ ecryptfs_file_to_private(file));
+ return 0;
+}
+
+static loff_t ecryptfs_dir_llseek(struct file *file, loff_t offset, int whence)
+{
+ return vfs_llseek(ecryptfs_file_to_lower(file), offset, whence);
+}
+
static int
ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
{
@@ -359,20 +402,16 @@ const struct file_operations ecryptfs_di
#ifdef CONFIG_COMPAT
.compat_ioctl = ecryptfs_compat_ioctl,
#endif
- .open = ecryptfs_open,
- .flush = ecryptfs_flush,
- .release = ecryptfs_release,
+ .open = ecryptfs_dir_open,
+ .release = ecryptfs_dir_release,
.fsync = ecryptfs_fsync,
- .fasync = ecryptfs_fasync,
- .splice_read = generic_file_splice_read,
- .llseek = default_llseek,
+ .llseek = ecryptfs_dir_llseek,
};

const struct file_operations ecryptfs_main_fops = {
.llseek = generic_file_llseek,
.read_iter = ecryptfs_read_update_atime,
.write_iter = generic_file_write_iter,
- .iterate = ecryptfs_readdir,
.unlocked_ioctl = ecryptfs_unlocked_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = ecryptfs_compat_ioctl,

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:26:31 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bart Van Assche <bart.va...@sandisk.com>

commit 1b856086813be9371929b6cc62045f9fd470f5a0 upstream.

blk_set_queue_dying() can be called while another thread is
submitting I/O or changing queue flags, e.g. through dm_stop_queue().
Hence protect the QUEUE_FLAG_DYING flag change with locking.

Signed-off-by: Bart Van Assche <bart.va...@sandisk.com>
Cc: Christoph Hellwig <h...@lst.de>
Cc: Mike Snitzer <sni...@redhat.com>
Signed-off-by: Jens Axboe <ax...@fb.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
block/blk-core.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -515,7 +515,9 @@ EXPORT_SYMBOL_GPL(blk_queue_bypass_end);

void blk_set_queue_dying(struct request_queue *q)
{
- queue_flag_set_unlocked(QUEUE_FLAG_DYING, q);
+ spin_lock_irq(q->queue_lock);
+ queue_flag_set(QUEUE_FLAG_DYING, q);
+ spin_unlock_irq(q->queue_lock);

if (q->mq_ops)
blk_mq_wake_waiters(q);

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:26:45 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 6a9bab79bb79bd9b2eda16f0aba1b4c43f677be9 ]

When a interface is assigned morethan 8 queues and the logical interface
is toggled i.e down & up, additional queues or qsets are not initialized
as secondary qset count is being set to zero while tearing down.

Signed-off-by: Sunil Goutham <sgou...@cavium.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/net/ethernet/cavium/thunder/nicvf_main.c | 1 -
1 file changed, 1 deletion(-)

--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -1117,7 +1117,6 @@ int nicvf_stop(struct net_device *netdev

/* Clear multiqset info */
nic->pnicvf = nic;
- nic->sqs_count = 0;

return 0;
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:26:59 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rob Clark <robd...@gmail.com>

commit 89f82cbb0d5c0ab768c8d02914188aa2211cd2e3 upstream.

Use instead __copy_from_user_inatomic() and fallback to slow-path where
we drop and re-aquire the lock in case of fault.

Reported-by: Vaishali Thakkar <vaishali...@oracle.com>
Signed-off-by: Rob Clark <robd...@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
drivers/gpu/drm/msm/msm_gem_submit.c | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)

--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -55,6 +55,14 @@ static struct msm_gem_submit *submit_cre
return submit;
}

+static inline unsigned long __must_check
+copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
+{
+ if (access_ok(VERIFY_READ, from, n))
+ return __copy_from_user_inatomic(to, from, n);
+ return -EFAULT;
+}
+
static int submit_lookup_objects(struct msm_gem_submit *submit,
struct drm_msm_gem_submit *args, struct drm_file *file)
{
@@ -62,6 +70,7 @@ static int submit_lookup_objects(struct
int ret = 0;

spin_lock(&file->table_lock);
+ pagefault_disable();

for (i = 0; i < args->nr_bos; i++) {
struct drm_msm_gem_submit_bo submit_bo;
@@ -70,10 +79,15 @@ static int submit_lookup_objects(struct
void __user *userptr =
to_user_ptr(args->bos + (i * sizeof(submit_bo)));

- ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo));
- if (ret) {
- ret = -EFAULT;
- goto out_unlock;
+ ret = copy_from_user_inatomic(&submit_bo, userptr, sizeof(submit_bo));
+ if (unlikely(ret)) {
+ pagefault_enable();
+ spin_unlock(&file->table_lock);
+ ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo));
+ if (ret)
+ goto out;
+ spin_lock(&file->table_lock);
+ pagefault_disable();
}

if (submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) {
@@ -113,9 +127,12 @@ static int submit_lookup_objects(struct
}

out_unlock:
- submit->nr_bos = i;
+ pagefault_enable();
spin_unlock(&file->table_lock);

+out:
+ submit->nr_bos = i;
+
return ret;
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:27:04 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Sakamoto <o-ta...@sakamocchi.jp>

commit 6b1ca4bcadf9ef077cc5f03c6822ba276ed14902 upstream.

In hwdep interface of fireworks driver, accessing to user space is in a
critical section with disabled local interrupt. Depending on architecture,
accessing to user space can cause page fault exception. Then local
processor stores machine status and handles the synchronous event. A
handler corresponding to the event can call task scheduler to wait for
preparing pages. In a case of usage of single core processor, the state to
disable local interrupt is worse because it don't handle usual interrupts
from hardware.

This commit fixes this bug, performing the accessing outside spinlock. This
commit also gives up counting the number of queued response messages to
simplify ring-buffer management.

Reported-by: Vaishali Thakkar <vaishali...@oracle.com>
Fixes: 555e8a8f7f14('ALSA: fireworks: Add command/response functionality into hwdep interface')
Signed-off-by: Takashi Sakamoto <o-ta...@sakamocchi.jp>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
sound/firewire/fireworks/fireworks.h | 1
sound/firewire/fireworks/fireworks_hwdep.c | 71 ++++++++++++++++-------
sound/firewire/fireworks/fireworks_proc.c | 4 -
sound/firewire/fireworks/fireworks_transaction.c | 5 -
4 files changed, 56 insertions(+), 25 deletions(-)

--- a/sound/firewire/fireworks/fireworks.h
+++ b/sound/firewire/fireworks/fireworks.h
@@ -106,7 +106,6 @@ struct snd_efw {
u8 *resp_buf;
u8 *pull_ptr;
u8 *push_ptr;
- unsigned int resp_queues;
};

int snd_efw_transaction_cmd(struct fw_unit *unit,
--- a/sound/firewire/fireworks/fireworks_hwdep.c
+++ b/sound/firewire/fireworks/fireworks_hwdep.c
@@ -25,6 +25,7 @@ hwdep_read_resp_buf(struct snd_efw *efw,
{
unsigned int length, till_end, type;
struct snd_efw_transaction *t;
+ u8 *pull_ptr;
long count = 0;

if (remained < sizeof(type) + sizeof(struct snd_efw_transaction))
@@ -38,8 +39,17 @@ hwdep_read_resp_buf(struct snd_efw *efw,
buf += sizeof(type);

/* write into buffer as many responses as possible */
- while (efw->resp_queues > 0) {
- t = (struct snd_efw_transaction *)(efw->pull_ptr);
+ spin_lock_irq(&efw->lock);
+
+ /*
+ * When another task reaches here during this task's access to user
+ * space, it picks up current position in buffer and can read the same
+ * series of responses.
+ */
+ pull_ptr = efw->pull_ptr;
+
+ while (efw->push_ptr != pull_ptr) {
+ t = (struct snd_efw_transaction *)(pull_ptr);
length = be32_to_cpu(t->length) * sizeof(__be32);

/* confirm enough space for this response */
@@ -49,26 +59,39 @@ hwdep_read_resp_buf(struct snd_efw *efw,
/* copy from ring buffer to user buffer */
while (length > 0) {
till_end = snd_efw_resp_buf_size -
- (unsigned int)(efw->pull_ptr - efw->resp_buf);
+ (unsigned int)(pull_ptr - efw->resp_buf);
till_end = min_t(unsigned int, length, till_end);

- if (copy_to_user(buf, efw->pull_ptr, till_end))
+ spin_unlock_irq(&efw->lock);
+
+ if (copy_to_user(buf, pull_ptr, till_end))
return -EFAULT;

- efw->pull_ptr += till_end;
- if (efw->pull_ptr >= efw->resp_buf +
- snd_efw_resp_buf_size)
- efw->pull_ptr -= snd_efw_resp_buf_size;
+ spin_lock_irq(&efw->lock);
+
+ pull_ptr += till_end;
+ if (pull_ptr >= efw->resp_buf + snd_efw_resp_buf_size)
+ pull_ptr -= snd_efw_resp_buf_size;

length -= till_end;
buf += till_end;
count += till_end;
remained -= till_end;
}
-
- efw->resp_queues--;
}

+ /*
+ * All of tasks can read from the buffer nearly simultaneously, but the
+ * last position for each task is different depending on the length of
+ * given buffer. Here, for simplicity, a position of buffer is set by
+ * the latest task. It's better for a listening application to allow one
+ * thread to read from the buffer. Unless, each task can read different
+ * sequence of responses depending on variation of buffer length.
+ */
+ efw->pull_ptr = pull_ptr;
+
+ spin_unlock_irq(&efw->lock);
+
return count;
}

@@ -76,14 +99,17 @@ static long
hwdep_read_locked(struct snd_efw *efw, char __user *buf, long count,
loff_t *offset)
{
- union snd_firewire_event event;
+ union snd_firewire_event event = {
+ .lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS,
+ };

- memset(&event, 0, sizeof(event));
+ spin_lock_irq(&efw->lock);

- event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
event.lock_status.status = (efw->dev_lock_count > 0);
efw->dev_lock_changed = false;

+ spin_unlock_irq(&efw->lock);
+
count = min_t(long, count, sizeof(event.lock_status));

if (copy_to_user(buf, &event, count))
@@ -98,10 +124,15 @@ hwdep_read(struct snd_hwdep *hwdep, char
{
struct snd_efw *efw = hwdep->private_data;
DEFINE_WAIT(wait);
+ bool dev_lock_changed;
+ bool queued;

spin_lock_irq(&efw->lock);

- while ((!efw->dev_lock_changed) && (efw->resp_queues == 0)) {
+ dev_lock_changed = efw->dev_lock_changed;
+ queued = efw->push_ptr != efw->pull_ptr;
+
+ while (!dev_lock_changed && !queued) {
prepare_to_wait(&efw->hwdep_wait, &wait, TASK_INTERRUPTIBLE);
spin_unlock_irq(&efw->lock);
schedule();
@@ -109,15 +140,17 @@ hwdep_read(struct snd_hwdep *hwdep, char
if (signal_pending(current))
return -ERESTARTSYS;
spin_lock_irq(&efw->lock);
+ dev_lock_changed = efw->dev_lock_changed;
+ queued = efw->push_ptr != efw->pull_ptr;
}

- if (efw->dev_lock_changed)
+ spin_unlock_irq(&efw->lock);
+
+ if (dev_lock_changed)
count = hwdep_read_locked(efw, buf, count, offset);
- else if (efw->resp_queues > 0)
+ else if (queued)
count = hwdep_read_resp_buf(efw, buf, count, offset);

- spin_unlock_irq(&efw->lock);
-
return count;
}

@@ -160,7 +193,7 @@ hwdep_poll(struct snd_hwdep *hwdep, stru
poll_wait(file, &efw->hwdep_wait, wait);

spin_lock_irq(&efw->lock);
- if (efw->dev_lock_changed || (efw->resp_queues > 0))
+ if (efw->dev_lock_changed || efw->pull_ptr != efw->push_ptr)
events = POLLIN | POLLRDNORM;
else
events = 0;
--- a/sound/firewire/fireworks/fireworks_proc.c
+++ b/sound/firewire/fireworks/fireworks_proc.c
@@ -188,8 +188,8 @@ proc_read_queues_state(struct snd_info_e
else
consumed = (unsigned int)(efw->push_ptr - efw->pull_ptr);

- snd_iprintf(buffer, "%d %d/%d\n",
- efw->resp_queues, consumed, snd_efw_resp_buf_size);
+ snd_iprintf(buffer, "%d/%d\n",
+ consumed, snd_efw_resp_buf_size);
}

static void
--- a/sound/firewire/fireworks/fireworks_transaction.c
+++ b/sound/firewire/fireworks/fireworks_transaction.c
@@ -121,11 +121,11 @@ copy_resp_to_buf(struct snd_efw *efw, vo
size_t capacity, till_end;
struct snd_efw_transaction *t;

- spin_lock_irq(&efw->lock);
-
t = (struct snd_efw_transaction *)data;
length = min_t(size_t, be32_to_cpu(t->length) * sizeof(u32), length);

+ spin_lock_irq(&efw->lock);
+
if (efw->push_ptr < efw->pull_ptr)
capacity = (unsigned int)(efw->pull_ptr - efw->push_ptr);
else
@@ -155,7 +155,6 @@ copy_resp_to_buf(struct snd_efw *efw, vo
}

/* for hwdep */
- efw->resp_queues++;
wake_up(&efw->hwdep_wait);

*rcode = RCODE_COMPLETE;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:30:07 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tyler Hicks <tyh...@canonical.com>

commit d6e0d306449bcb5fa3c80e7a3edf11d45abf9ae9 upstream.

The capability check should not be audited since it is only being used
to determine the inode permissions. A failed check does not indicate a
violation of security policy but, when an LSM is enabled, a denial audit
message was being generated.

The denial audit message caused confusion for some application authors
because root-running Go applications always triggered the denial. To
prevent this confusion, the capability check in net_ctl_permissions() is
switched to the noaudit variant.

BugLink: https://launchpad.net/bugs/1465724

Signed-off-by: Tyler Hicks <tyh...@canonical.com>
Acked-by: Serge E. Hallyn <serge....@ubuntu.com>
Signed-off-by: James Morris <james.l...@oracle.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
net/sysctl_net.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/sysctl_net.c
+++ b/net/sysctl_net.c
@@ -46,7 +46,7 @@ static int net_ctl_permissions(struct ct
kgid_t root_gid = make_kgid(net->user_ns, 0);

/* Allow network administrator to have same access as root. */
- if (ns_capable(net->user_ns, CAP_NET_ADMIN) ||
+ if (ns_capable_noaudit(net->user_ns, CAP_NET_ADMIN) ||
uid_eq(root_uid, current_euid())) {
int mode = (table->mode >> 6) & 7;
return (mode << 6) | (mode << 3) | mode;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:30:07 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 3f4c68cfde30caa1f6d8368fd19590671411ade2 ]

Check for SMU RX local/remote faults along with SPU LINK
status. Otherwise at times link is UP at our end but DOWN
at link partner's side. Also due to an issue in BGX it's
rarely seen that initialization doesn't happen properly
and SMU RX reports faults with everything fine at SPU.
This patch tries to reinitialize LMAC to fix it.

Also fixed LMAC disable sequence to properly bring down link.

Signed-off-by: Sunil Goutham <sgou...@cavium.com>
Signed-off-by: Tao Wang <tao....@cavium.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 91 ++++++++++++++--------
drivers/net/ethernet/cavium/thunder/thunder_bgx.h | 2
2 files changed, 62 insertions(+), 31 deletions(-)

--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -549,7 +549,9 @@ static int bgx_xaui_check_link(struct lm
}

/* Clear rcvflt bit (latching high) and read it back */
- bgx_reg_modify(bgx, lmacid, BGX_SPUX_STATUS2, SPU_STATUS2_RCVFLT);
+ if (bgx_reg_read(bgx, lmacid, BGX_SPUX_STATUS2) & SPU_STATUS2_RCVFLT)
+ bgx_reg_modify(bgx, lmacid,
+ BGX_SPUX_STATUS2, SPU_STATUS2_RCVFLT);
if (bgx_reg_read(bgx, lmacid, BGX_SPUX_STATUS2) & SPU_STATUS2_RCVFLT) {
dev_err(&bgx->pdev->dev, "Receive fault, retry training\n");
if (bgx->use_training) {
@@ -568,13 +570,6 @@ static int bgx_xaui_check_link(struct lm
return -1;
}

- /* Wait for MAC RX to be ready */
- if (bgx_poll_reg(bgx, lmacid, BGX_SMUX_RX_CTL,
- SMU_RX_CTL_STATUS, true)) {
- dev_err(&bgx->pdev->dev, "SMU RX link not okay\n");
- return -1;
- }
-
/* Wait for BGX RX to be idle */
if (bgx_poll_reg(bgx, lmacid, BGX_SMUX_CTL, SMU_CTL_RX_IDLE, false)) {
dev_err(&bgx->pdev->dev, "SMU RX not idle\n");
@@ -587,29 +582,30 @@ static int bgx_xaui_check_link(struct lm
return -1;
}

- if (bgx_reg_read(bgx, lmacid, BGX_SPUX_STATUS2) & SPU_STATUS2_RCVFLT) {
- dev_err(&bgx->pdev->dev, "Receive fault\n");
- return -1;
- }
-
- /* Receive link is latching low. Force it high and verify it */
- bgx_reg_modify(bgx, lmacid, BGX_SPUX_STATUS1, SPU_STATUS1_RCV_LNK);
- if (bgx_poll_reg(bgx, lmacid, BGX_SPUX_STATUS1,
- SPU_STATUS1_RCV_LNK, false)) {
- dev_err(&bgx->pdev->dev, "SPU receive link down\n");
- return -1;
- }
-
+ /* Clear receive packet disable */
cfg = bgx_reg_read(bgx, lmacid, BGX_SPUX_MISC_CONTROL);
cfg &= ~SPU_MISC_CTL_RX_DIS;
bgx_reg_write(bgx, lmacid, BGX_SPUX_MISC_CONTROL, cfg);
- return 0;
+
+ /* Check for MAC RX faults */
+ cfg = bgx_reg_read(bgx, lmacid, BGX_SMUX_RX_CTL);
+ /* 0 - Link is okay, 1 - Local fault, 2 - Remote fault */
+ cfg &= SMU_RX_CTL_STATUS;
+ if (!cfg)
+ return 0;
+
+ /* Rx local/remote fault seen.
+ * Do lmac reinit to see if condition recovers
+ */
+ bgx_lmac_xaui_init(bgx, lmacid, bgx->lmac_type);
+
+ return -1;
}

static void bgx_poll_for_link(struct work_struct *work)
{
struct lmac *lmac;
- u64 link;
+ u64 spu_link, smu_link;

lmac = container_of(work, struct lmac, dwork.work);

@@ -619,8 +615,11 @@ static void bgx_poll_for_link(struct wor
bgx_poll_reg(lmac->bgx, lmac->lmacid, BGX_SPUX_STATUS1,
SPU_STATUS1_RCV_LNK, false);

- link = bgx_reg_read(lmac->bgx, lmac->lmacid, BGX_SPUX_STATUS1);
- if (link & SPU_STATUS1_RCV_LNK) {
+ spu_link = bgx_reg_read(lmac->bgx, lmac->lmacid, BGX_SPUX_STATUS1);
+ smu_link = bgx_reg_read(lmac->bgx, lmac->lmacid, BGX_SMUX_RX_CTL);
+
+ if ((spu_link & SPU_STATUS1_RCV_LNK) &&
+ !(smu_link & SMU_RX_CTL_STATUS)) {
lmac->link_up = 1;
if (lmac->bgx->lmac_type == BGX_MODE_XLAUI)
lmac->last_speed = 40000;
@@ -634,9 +633,15 @@ static void bgx_poll_for_link(struct wor
}

if (lmac->last_link != lmac->link_up) {
+ if (lmac->link_up) {
+ if (bgx_xaui_check_link(lmac)) {
+ /* Errors, clear link_up state */
+ lmac->link_up = 0;
+ lmac->last_speed = SPEED_UNKNOWN;
+ lmac->last_duplex = DUPLEX_UNKNOWN;
+ }
+ }
lmac->last_link = lmac->link_up;
- if (lmac->link_up)
- bgx_xaui_check_link(lmac);
}

queue_delayed_work(lmac->check_link, &lmac->dwork, HZ * 2);
@@ -708,7 +713,7 @@ static int bgx_lmac_enable(struct bgx *b
static void bgx_lmac_disable(struct bgx *bgx, u8 lmacid)
{
struct lmac *lmac;
- u64 cmrx_cfg;
+ u64 cfg;

lmac = &bgx->lmac[lmacid];
if (lmac->check_link) {
@@ -717,9 +722,33 @@ static void bgx_lmac_disable(struct bgx
destroy_workqueue(lmac->check_link);
}

- cmrx_cfg = bgx_reg_read(bgx, lmacid, BGX_CMRX_CFG);
- cmrx_cfg &= ~(1 << 15);
- bgx_reg_write(bgx, lmacid, BGX_CMRX_CFG, cmrx_cfg);
+ /* Disable packet reception */
+ cfg = bgx_reg_read(bgx, lmacid, BGX_CMRX_CFG);
+ cfg &= ~CMR_PKT_RX_EN;
+ bgx_reg_write(bgx, lmacid, BGX_CMRX_CFG, cfg);
+
+ /* Give chance for Rx/Tx FIFO to get drained */
+ bgx_poll_reg(bgx, lmacid, BGX_CMRX_RX_FIFO_LEN, (u64)0x1FFF, true);
+ bgx_poll_reg(bgx, lmacid, BGX_CMRX_TX_FIFO_LEN, (u64)0x3FFF, true);
+
+ /* Disable packet transmission */
+ cfg = bgx_reg_read(bgx, lmacid, BGX_CMRX_CFG);
+ cfg &= ~CMR_PKT_TX_EN;
+ bgx_reg_write(bgx, lmacid, BGX_CMRX_CFG, cfg);
+
+ /* Disable serdes lanes */
+ if (!lmac->is_sgmii)
+ bgx_reg_modify(bgx, lmacid,
+ BGX_SPUX_CONTROL1, SPU_CTL_LOW_POWER);
+ else
+ bgx_reg_modify(bgx, lmacid,
+ BGX_GMP_PCS_MRX_CTL, PCS_MRX_CTL_PWR_DN);
+
+ /* Disable LMAC */
+ cfg = bgx_reg_read(bgx, lmacid, BGX_CMRX_CFG);
+ cfg &= ~CMR_EN;
+ bgx_reg_write(bgx, lmacid, BGX_CMRX_CFG, cfg);
+
bgx_flush_dmac_addrs(bgx, lmacid);

if ((bgx->lmac_type != BGX_MODE_XFI) &&
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
@@ -41,6 +41,7 @@
#define BGX_CMRX_RX_STAT10 0xC0
#define BGX_CMRX_RX_BP_DROP 0xC8
#define BGX_CMRX_RX_DMAC_CTL 0x0E8
+#define BGX_CMRX_RX_FIFO_LEN 0x108
#define BGX_CMR_RX_DMACX_CAM 0x200
#define RX_DMACX_CAM_EN BIT_ULL(48)
#define RX_DMACX_CAM_LMACID(x) (x << 49)
@@ -50,6 +51,7 @@
#define BGX_CMR_CHAN_MSK_AND 0x450
#define BGX_CMR_BIST_STATUS 0x460
#define BGX_CMR_RX_LMACS 0x468
+#define BGX_CMRX_TX_FIFO_LEN 0x518
#define BGX_CMRX_TX_STAT0 0x600
#define BGX_CMRX_TX_STAT1 0x608
#define BGX_CMRX_TX_STAT2 0x610

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:30:07 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------


From: David Howells <dhow...@redhat.com>

[ Upstream commit 23c8a812dc3c621009e4f0e5342aa4e2ede1ceaa ]

This fixes CVE-2016-0758.

In the ASN.1 decoder, when the length field of an ASN.1 value is extracted,
it isn't validated against the remaining amount of data before being added
to the cursor. With a sufficiently large size indicated, the check:

datalen - dp < 2

may then fail due to integer overflow.

Fix this by checking the length indicated against the amount of remaining
data in both places a definite length is determined.

Whilst we're at it, make the following changes:

(1) Check the maximum size of extended length does not exceed the capacity
of the variable it's being stored in (len) rather than the type that
variable is assumed to be (size_t).

(2) Compare the EOC tag to the symbolic constant ASN1_EOC rather than the
integer 0.

(3) To reduce confusion, move the initialisation of len outside of:

for (len = 0; n > 0; n--) {

since it doesn't have anything to do with the loop counter n.

Signed-off-by: David Howells <dhow...@redhat.com>
Reviewed-by: Mimi Zohar <zo...@linux.vnet.ibm.com>
Acked-by: David Woodhouse <David.W...@intel.com>
Acked-by: Peter Jones <pjo...@redhat.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
lib/asn1_decoder.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)

--- a/lib/asn1_decoder.c
+++ b/lib/asn1_decoder.c
@@ -74,7 +74,7 @@ next_tag:

/* Extract a tag from the data */
tag = data[dp++];
- if (tag == 0) {
+ if (tag == ASN1_EOC) {
/* It appears to be an EOC. */
if (data[dp++] != 0)
goto invalid_eoc;
@@ -96,10 +96,8 @@ next_tag:

/* Extract the length */
len = data[dp++];
- if (len <= 0x7f) {
- dp += len;
- goto next_tag;
- }
+ if (len <= 0x7f)
+ goto check_length;

if (unlikely(len == ASN1_INDEFINITE_LENGTH)) {
/* Indefinite length */
@@ -110,14 +108,18 @@ next_tag:
}

n = len - 0x80;
- if (unlikely(n > sizeof(size_t) - 1))
+ if (unlikely(n > sizeof(len) - 1))
goto length_too_long;
if (unlikely(n > datalen - dp))
goto data_overrun_error;
- for (len = 0; n > 0; n--) {
+ len = 0;
+ for (; n > 0; n--) {
len <<= 8;
len |= data[dp++];
}
+check_length:
+ if (len > datalen - dp)
+ goto data_overrun_error;
dp += len;
goto next_tag;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:30:07 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Al Viro <vi...@zeniv.linux.org.uk>

commit 57b8f112cfe6622ddddb8c2641206bb5fa8a112d upstream.

Signed-off-by: Al Viro <vi...@zeniv.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
drivers/staging/lustre/lustre/llite/llite_internal.h | 2 --
1 file changed, 2 deletions(-)

--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -631,8 +631,6 @@ struct ll_file_data {

struct lov_stripe_md;

-extern spinlock_t inode_lock;
-
extern struct dentry *llite_root;
extern struct kset *llite_kset;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:30:07 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Gabriel Krisman Bertazi <kri...@linux.vnet.ibm.com>


Commit 5706aca74fe4 ("NVMe: Don't unmap controller registers on reset"),
which backported b00a726a9fd8 to the 4.4.y kernel introduced a
regression in which it didn't call pci_disable_device in the error path
of nvme_pci_enable.

Reported-by: Jiri Slaby <jsl...@suse.cz>
Embarassed-developer: Gabriel Krisman Bertazi <kri...@linux.vnet.ibm.com>
Signed-off-by: Gabriel Krisman Bertazi <kri...@linux.vnet.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
drivers/nvme/host/pci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -2725,7 +2725,7 @@ static int nvme_pci_enable(struct nvme_d
return 0;

disable:
- pci_release_regions(pdev);
+ pci_disable_device(pdev);

return result;
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:30:07 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Sakamoto <o-ta...@sakamocchi.jp>

commit 04b2d9c9c319277ad4fbbb71855c256a9f4d5f98 upstream.

In hwdep interface of firewire-tascam driver, accessing to user space is
in a critical section with disabled local interrupt. Depending on
architecture, accessing to user space can cause page fault exception. Then
local processor stores machine status and handle the synchronous event. A
handler corresponding to the event can call task scheduler to wait for
preparing pages. In a case of usage of single core processor, the state to
disable local interrupt is worse because it doesn't handle usual interrupts
from hardware.

This commit fixes this bug, by performing the accessing outside spinlock.

Reported-by: Vaishali Thakkar <vaishali...@oracle.com>
Fixes: e5e0c3dd257b('ALSA: firewire-tascam: add hwdep interface')
Signed-off-by: Takashi Sakamoto <o-ta...@sakamocchi.jp>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
sound/firewire/tascam/tascam-hwdep.c | 33 +++++++++++----------------------
1 file changed, 11 insertions(+), 22 deletions(-)

--- a/sound/firewire/tascam/tascam-hwdep.c
+++ b/sound/firewire/tascam/tascam-hwdep.c
@@ -16,31 +16,14 @@

#include "tascam.h"

-static long hwdep_read_locked(struct snd_tscm *tscm, char __user *buf,
- long count)
-{
- union snd_firewire_event event;
-
- memset(&event, 0, sizeof(event));
-
- event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
- event.lock_status.status = (tscm->dev_lock_count > 0);
- tscm->dev_lock_changed = false;
-
- count = min_t(long, count, sizeof(event.lock_status));
-
- if (copy_to_user(buf, &event, count))
- return -EFAULT;
-
- return count;
-}
-
static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
loff_t *offset)
{
struct snd_tscm *tscm = hwdep->private_data;
DEFINE_WAIT(wait);
- union snd_firewire_event event;
+ union snd_firewire_event event = {
+ .lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS,
+ };

spin_lock_irq(&tscm->lock);

@@ -54,10 +37,16 @@ static long hwdep_read(struct snd_hwdep
spin_lock_irq(&tscm->lock);
}

- memset(&event, 0, sizeof(event));
- count = hwdep_read_locked(tscm, buf, count);
+ event.lock_status.status = (tscm->dev_lock_count > 0);
+ tscm->dev_lock_changed = false;
+
spin_unlock_irq(&tscm->lock);

+ count = min_t(long, count, sizeof(event.lock_status));
+
+ if (copy_to_user(buf, &event, count))
+ return -EFAULT;
+
return count;
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:30:07 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miklos Szeredi <msze...@redhat.com>

commit e1ff3dd1ae52cef5b5373c8cc4ad949c2c25a71c upstream.

Workdir creation fails in latest kernel.

Fix by allowing EOPNOTSUPP as a valid return value from
vfs_removexattr(XATTR_NAME_POSIX_ACL_*). Upper filesystem may not support
ACL and still be perfectly able to support overlayfs.

Reported-by: Martin Ziegler <zie...@uni-freiburg.de>
Signed-off-by: Miklos Szeredi <msze...@redhat.com>
Fixes: c11b9fdd6a61 ("ovl: remove posix_acl_default from workdir")
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
fs/overlayfs/super.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -784,11 +784,11 @@ retry:
goto out_dput;

err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_DEFAULT);
- if (err && err != -ENODATA)
+ if (err && err != -ENODATA && err != -EOPNOTSUPP)
goto out_dput;

err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_ACCESS);
- if (err && err != -ENODATA)
+ if (err && err != -ENODATA && err != -EOPNOTSUPP)
goto out_dput;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:30:07 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Al Viro <vi...@zeniv.linux.org.uk>

commit 5955102c9984fa081b2d570cfac75c97eecf8f3b upstream

parallel to mutex_{lock,unlock,trylock,is_locked,lock_nested},
inode_foo(inode) being mutex_foo(&inode->i_mutex).

Please, use those for access to ->i_mutex; over the coming cycle
->i_mutex will become rwsem, with ->lookup() done with it held
only shared.

Signed-off-by: Al Viro <vi...@zeniv.linux.org.uk>
[only the fs.h change included to make backports easier - gregkh]
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
include/linux/fs.h | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)

--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -710,6 +710,31 @@ enum inode_i_mutex_lock_class
I_MUTEX_PARENT2,
};

+static inline void inode_lock(struct inode *inode)
+{
+ mutex_lock(&inode->i_mutex);
+}
+
+static inline void inode_unlock(struct inode *inode)
+{
+ mutex_unlock(&inode->i_mutex);
+}
+
+static inline int inode_trylock(struct inode *inode)
+{
+ return mutex_trylock(&inode->i_mutex);
+}
+
+static inline int inode_is_locked(struct inode *inode)
+{
+ return mutex_is_locked(&inode->i_mutex);
+}
+
+static inline void inode_lock_nested(struct inode *inode, unsigned subclass)
+{
+ mutex_lock_nested(&inode->i_mutex, subclass);
+}
+
void lock_two_nondirectories(struct inode *, struct inode*);
void unlock_two_nondirectories(struct inode *, struct inode*);

@@ -3029,8 +3054,8 @@ static inline bool dir_emit_dots(struct
}
static inline bool dir_relax(struct inode *inode)
{
- mutex_unlock(&inode->i_mutex);
- mutex_lock(&inode->i_mutex);
+ inode_unlock(inode);
+ inode_lock(inode);
return !IS_DEADDIR(inode);
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:30:07 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 4da2e26a2a32b174878744bd0f07db180c875f26 ]

btrfs failed in xfstests btrfs/080 with -o nodatacow.

Can be reproduced by following script:
DEV=/dev/vdg
MNT=/mnt/tmp

umount $DEV &>/dev/null
mkfs.btrfs -f $DEV
mount -o nodatacow $DEV $MNT

dd if=/dev/zero of=$MNT/test bs=1 count=2048 &
btrfs subvolume snapshot -r $MNT $MNT/test_snap &
wait
--
We can see dd failed on NO_SPACE.

Reason:
__btrfs_buffered_write should run cow write when no_cow impossible,
and current code is designed with above logic.
But check_can_nocow() have 2 type of return value(0 and <0) on
can_not_no_cow, and current code only continue write on first case,
the second case happened in doing subvolume.

Fix:
Continue write when check_can_nocow() return 0 and <0.

Reviewed-by: Filipe Manana <fdma...@suse.com>
Signed-off-by: Zhao Lei <zha...@cn.fujitsu.com>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
fs/btrfs/file.c | 37 +++++++++++++++++--------------------
1 file changed, 17 insertions(+), 20 deletions(-)

--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1526,27 +1526,24 @@ static noinline ssize_t __btrfs_buffered

reserve_bytes = num_pages << PAGE_CACHE_SHIFT;

- if (BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
- BTRFS_INODE_PREALLOC)) {
- ret = check_can_nocow(inode, pos, &write_bytes);
- if (ret < 0)
- break;
- if (ret > 0) {
- /*
- * For nodata cow case, no need to reserve
- * data space.
- */
- only_release_metadata = true;
- /*
- * our prealloc extent may be smaller than
- * write_bytes, so scale down.
- */
- num_pages = DIV_ROUND_UP(write_bytes + offset,
- PAGE_CACHE_SIZE);
- reserve_bytes = num_pages << PAGE_CACHE_SHIFT;
- goto reserve_metadata;
- }
+ if ((BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
+ BTRFS_INODE_PREALLOC)) &&
+ check_can_nocow(inode, pos, &write_bytes) > 0) {
+ /*
+ * For nodata cow case, no need to reserve
+ * data space.
+ */
+ only_release_metadata = true;
+ /*
+ * our prealloc extent may be smaller than
+ * write_bytes, so scale down.
+ */
+ num_pages = DIV_ROUND_UP(write_bytes + offset,
+ PAGE_CACHE_SIZE);
+ reserve_bytes = num_pages << PAGE_CACHE_SHIFT;
+ goto reserve_metadata;
}
+
ret = btrfs_check_data_free_space(inode, pos, write_bytes);
if (ret < 0)
break;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:30:08 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Kangjie Lu <kang...@gmail.com>

commit 4116def2337991b39919f3b448326e21c40e0dbb upstream.

The last field "flags" of object "minfo" is not initialized.
Copying this object out may leak kernel stack data.
Assign 0 to it to avoid leak.

Signed-off-by: Kangjie Lu <kj...@gatech.edu>
Acked-by: Santosh Shilimkar <santosh....@oracle.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Juerg Haefliger <juerg.h...@hpe.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
net/rds/recv.c | 2 ++
1 file changed, 2 insertions(+)

--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -545,5 +545,7 @@ void rds_inc_info_copy(struct rds_incomi
minfo.fport = inc->i_hdr.h_dport;
}

+ minfo.flags = 0;
+
rds_info_copy(iter, &minfo, sizeof(minfo));
}

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:30:08 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit d157bd761585605b7882935ffb86286919f62ea1 ]

Ben Hawkes says:
integer overflow in xt_alloc_table_info, which on 32-bit systems can
lead to small structure allocation and a copy_from_user based heap
corruption.

Reported-by: Ben Hawkes <haw...@google.com>
Signed-off-by: Florian Westphal <f...@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
net/netfilter/x_tables.c | 3 +++
1 file changed, 3 insertions(+)

--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -897,6 +897,9 @@ struct xt_table_info *xt_alloc_table_inf
struct xt_table_info *info = NULL;
size_t sz = sizeof(*info) + size;

+ if (sz < sizeof(*info))
+ return NULL;
+
/* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */
if ((SMP_ALIGN(size) >> PAGE_SHIFT) + 2 > totalram_pages)
return NULL;

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:30:08 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------

[ Upstream commit 55e77a3e8297581c919b45adcc4d0815b69afa84 ]

Fix incorrect use of nla_strlcpy() where the first NLA_HDRLEN bytes
of the link name where left out.

Making the output of tipc-config -ls look something like:
Link statistics:
dcast-link
1:data0-1.1.2:data0
1:data0-1.1.3:data0

Also, for the record, the patch that introduce this regression
claims "Sending the whole object out can cause a leak". Which isn't
very likely as this is a compat layer, where the data we are parsing
is generated by us and we know the string to be NULL terminated. But
you can of course never be to secure.

Fixes: 5d2be1422e02 (tipc: fix an infoleak in tipc_nl_compat_link_dump)
Signed-off-by: Richard Alpe <richar...@ericsson.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
net/tipc/netlink_compat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/tipc/netlink_compat.c
+++ b/net/tipc/netlink_compat.c
@@ -574,7 +574,7 @@ static int tipc_nl_compat_link_dump(stru

link_info.dest = nla_get_flag(link[TIPC_NLA_LINK_DEST]);
link_info.up = htonl(nla_get_flag(link[TIPC_NLA_LINK_UP]));
- nla_strlcpy(link_info.str, nla_data(link[TIPC_NLA_LINK_NAME]),
+ nla_strlcpy(link_info.str, link[TIPC_NLA_LINK_NAME],
TIPC_MAX_LINK_NAME);

return tipc_add_tlv(msg->rep, TIPC_TLV_LINK_INFO,

Greg Kroah-Hartman

unread,
Sep 12, 2016, 1:30:08 PM9/12/16
to
4.4-stable review patch. If anyone has any objections, please let me know.

------------------


From: Haren Myneni <ha...@linux.vnet.ibm.com>

[ Upstream commit 6333ed8f26cf77311088d2e2b7cf16d8480bcbb2 ]

NX842 coprocessor sets 3rd bit in CR register with XER[S0] which is
nothing to do with NX request. Since this bit can be set with other
valuable return status, mast this bit.

One of other bits (INITIATED, BUSY or REJECTED) will be returned for
any given NX request.

Signed-off-by: Haren Myneni <ha...@us.ibm.com>
Signed-off-by: Herbert Xu <her...@gondor.apana.org.au>
Signed-off-by: Sasha Levin <alexand...@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
arch/powerpc/include/asm/icswx.h | 1 +
drivers/crypto/nx/nx-842-powernv.c | 12 ++++++++----
2 files changed, 9 insertions(+), 4 deletions(-)

--- a/arch/powerpc/include/asm/icswx.h
+++ b/arch/powerpc/include/asm/icswx.h
@@ -164,6 +164,7 @@ struct coprocessor_request_block {
#define ICSWX_INITIATED (0x8)
#define ICSWX_BUSY (0x4)
#define ICSWX_REJECTED (0x2)
+#define ICSWX_XERS0 (0x1) /* undefined or set from XERSO. */

static inline int icswx(__be32 ccw, struct coprocessor_request_block *crb)
{
--- a/drivers/crypto/nx/nx-842-powernv.c
+++ b/drivers/crypto/nx/nx-842-powernv.c
@@ -442,6 +442,14 @@ static int nx842_powernv_function(const
(unsigned int)ccw,
(unsigned int)be32_to_cpu(crb->ccw));

+ /*
+ * NX842 coprocessor sets 3rd bit in CR register with XER[S0].
+ * XER[S0] is the integer summary overflow bit which is nothing
+ * to do NX. Since this bit can be set with other return values,
+ * mask this bit.
+ */
+ ret &= ~ICSWX_XERS0;
+
switch (ret) {
case ICSWX_INITIATED:
ret = wait_for_csb(wmem, csb);
@@ -454,10 +462,6 @@ static int nx842_powernv_function(const
pr_err_ratelimited("ICSWX rejected\n");
ret = -EPROTO;
break;
- default:
- pr_err_ratelimited("Invalid ICSWX return code %x\n", ret);
- ret = -EPROTO;
- break;
}

if (!ret)
It is loading more messages.
0 new messages