4.14.143-stable review
Subsystems (2)
Greg Kroah-Hartman
maintainercover 4.14.143-stable review
This is the start of the stable review cycle for the 4.14.143 release. There are 40 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 Tue 10 Sep 2019 12:09:36 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.143-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.14.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.14.143-rc1
John S. Gruber <[email protected]>
x86/boot: Preserve boot_params.secure_boot from sanitizing
Eric Dumazet <[email protected]>
mld: fix memory leak in mld_del_delrec()
Vlad Buslov <[email protected]>
net: sched: act_sample: fix psample group handling on overwrite
Eric Dumazet <[email protected]>
tcp: remove empty skb from write queue in error cases
Willem de Bruijn <[email protected]>
tcp: inherit timestamp on mtu probe
Chen-Yu Tsai <[email protected]>
net: stmmac: dwmac-rk: Don't fail if phy regulator is absent
Cong Wang <[email protected]>
net_sched: fix a NULL pointer deref in ipt action
Feng Sun <[email protected]>
net: fix skb use after free in netpoll
Linus Torvalds <[email protected]>
Revert "x86/apic: Include the LDR when clearing out APIC registers"
Martin Sperl <[email protected]>
spi: bcm2835aux: fix corruptions for longer spi transfers
Martin Sperl <[email protected]>
spi: bcm2835aux: remove dangerous uncontrolled read of fifo
Martin Sperl <[email protected]>
spi: bcm2835aux: unifying code between polling and interrupt driven code
Luis Henriques <[email protected]>
libceph: allow ceph_buffer_put() to receive a NULL ceph_buffer
Andrew Jones <[email protected]>
KVM: arm/arm64: Only skip MMIO insn once
Luis Henriques <[email protected]>
ceph: fix buffer free while holding i_ceph_lock in fill_inode()
Luis Henriques <[email protected]>
ceph: fix buffer free while holding i_ceph_lock in __ceph_build_xattrs_blob()
Luis Henriques <[email protected]>
ceph: fix buffer free while holding i_ceph_lock in __ceph_setxattr()
Wenwen Wang <[email protected]>
IB/mlx4: Fix memory leaks
Vitaly Kuznetsov <[email protected]>
Tools: hv: kvp: eliminate 'may be used uninitialized' warning
Dexuan Cui <[email protected]>
Input: hyperv-keyboard: Use in-place iterator API in the channel callback
Benjamin Tissoires <[email protected]>
HID: cp2112: prevent sleeping function called from invalid context
Andrea Righi <[email protected]>
kprobes: Fix potential deadlock in kprobe_optimizer()
Tho Vu <[email protected]>
ravb: Fix use-after-free ravb_tstamp_skb
Wenwen Wang <[email protected]>
wimax/i2400m: fix a memory leak bug
Wenwen Wang <[email protected]>
net: kalmia: fix memory leaks
Wenwen Wang <[email protected]>
cx82310_eth: fix a memory leak bug
Darrick J. Wong <[email protected]>
vfs: fix page locking deadlocks when deduping files
Wenwen Wang <[email protected]>
lan78xx: Fix memory leaks
Wenwen Wang <[email protected]>
net: myri10ge: fix memory leaks
Wenwen Wang <[email protected]>
liquidio: add cleanup in octeon_setup_iq()
Wenwen Wang <[email protected]>
cxgb4: fix a memory leak bug
Alexandre Courbot <[email protected]>
drm/mediatek: set DMA max segment size
Alexandre Courbot <[email protected]>
drm/mediatek: use correct device to import PRIME buffers
YueHaibing <[email protected]>
gpio: Fix build error of function redefinition
Thomas Falcon <[email protected]>
ibmveth: Convert multicast list size for little-endian system
Fabian Henneke <[email protected]>
Bluetooth: hidp: Let hidp_send_message return number of queued bytes
Matthias Kaehlcke <[email protected]>
Bluetooth: btqca: Add a short delay before downloading the NVM
Nathan Chancellor <[email protected]>
net: tc35815: Explicitly check NET_IP_ALIGN is not zero in tc35815_rx
Dexuan Cui <[email protected]>
hv_netvsc: Fix a warning of suspicious RCU usage
Fuqian Huang <[email protected]>
net: tundra: tsi108: use spin_lock_irqsave instead of spin_lock_irq in IRQ context
-------------
Diffstat:
Makefile | 4 +- arch/x86/include/asm/bootparam_utils.h | 1 + arch/x86/kernel/apic/apic.c | 4 -- drivers/bluetooth/btqca.c | 3 ++ drivers/gpu/drm/mediatek/mtk_drm_drv.c | 49 +++++++++++++++-- drivers/gpu/drm/mediatek/mtk_drm_drv.h | 2 + drivers/hid/hid-cp2112.c | 8 ++- drivers/infiniband/hw/mlx4/mad.c | 4 +- drivers/input/serio/hyperv-keyboard.c | 35 +++--------- .../net/ethernet/cavium/liquidio/request_manager.c | 4 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 4 +- drivers/net/ethernet/ibm/ibmveth.c | 9 ++-- drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 2 +- drivers/net/ethernet/renesas/ravb_main.c | 8 ++- drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 6 +-- drivers/net/ethernet/toshiba/tc35815.c | 2 +- drivers/net/ethernet/tundra/tsi108_eth.c | 5 +- drivers/net/hyperv/netvsc_drv.c | 9 +++- drivers/net/usb/cx82310_eth.c | 3 +- drivers/net/usb/kalmia.c | 6 +-- drivers/net/usb/lan78xx.c | 8 +-- drivers/net/wimax/i2400m/fw.c | 4 +- drivers/spi/spi-bcm2835aux.c | 62 +++++++--------------- fs/ceph/caps.c | 5 +- fs/ceph/inode.c | 7 +-- fs/ceph/snap.c | 4 +- fs/ceph/super.h | 2 +- fs/ceph/xattr.c | 19 +++++-- fs/read_write.c | 49 ++++++++++++++--- include/linux/ceph/buffer.h | 3 +- include/linux/gpio.h | 24 --------- include/net/act_api.h | 4 +- include/net/psample.h | 1 + kernel/kprobes.c | 8 +-- net/bluetooth/hidp/core.c | 9 +++- net/core/netpoll.c | 6 +-- net/ipv4/tcp.c | 29 ++++++---- net/ipv4/tcp_output.c | 3 +- net/ipv6/mcast.c | 5 +- net/psample/psample.c | 2 +- net/sched/act_bpf.c | 2 +- net/sched/act_connmark.c | 2 +- net/sched/act_csum.c | 2 +- net/sched/act_gact.c | 2 +- net/sched/act_ife.c | 2 +- net/sched/act_ipt.c | 11 ++-- net/sched/act_mirred.c | 2 +- net/sched/act_nat.c | 2 +- net/sched/act_pedit.c | 2 +- net/sched/act_police.c | 2 +- net/sched/act_sample.c | 7 ++- net/sched/act_simple.c | 2 +- net/sched/act_skbedit.c | 2 +- net/sched/act_skbmod.c | 2 +- net/sched/act_tunnel_key.c | 2 +- net/sched/act_vlan.c | 2 +- tools/hv/hv_kvp_daemon.c | 2 +- virt/kvm/arm/mmio.c | 7 +++ 58 files changed, 278 insertions(+), 199 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/40 net: tundra: tsi108: use spin_lock_irqsave instead of spin_lock_irq in IRQ context
[ Upstream commit 8c25d0887a8bd0e1ca2074ac0c6dff173787a83b ]
As spin_unlock_irq will enable interrupts.
Function tsi108_stat_carry is called from interrupt handler tsi108_irq. Interrupts are enabled in interrupt handler.
Use spin_lock_irqsave/spin_unlock_irqrestore instead of spin_(un)lock_irq in IRQ context to avoid this.
--- drivers/net/ethernet/tundra/tsi108_eth.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/ethernet/tundra/tsi108_eth.c +3 -2
@@ -381,9 +381,10 @@ tsi108_stat_carry_one(int carry, int carry_bit, int carry_shift,static void tsi108_stat_carry (struct net_device *dev) {struct tsi108_prv_data *data =netdev_priv (dev); +unsigned long flags;u32 carry1, carry2; -spin_lock_irq (&data->misclock); +spin_lock_irqsave (&data->misclock, flags); carry1 =TSI_READ (TSI108_STAT_CARRY1 ); carry2 =TSI_READ (TSI108_STAT_CARRY2 );
@@ -451,7 +452,7 @@ static void tsi108_stat_carry(struct net_device *dev)TSI108_STAT_TXPAUSEDROP_CARRY , &data->tx_pause_drop); -spin_unlock_irq (&data->misclock); +spin_unlock_irqrestore (&data->misclock, flags); }/* Read a stat counter atomically with respect to carries.
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 2/40 hv_netvsc: Fix a warning of suspicious RCU usage
In reply to Greg Kroah-Hartman[ Upstream commit 6d0d779dca73cd5acb649c54f81401f93098b298 ]
This fixes a warning of "suspicious rcu_dereference_check() usage" when nload runs.
--- drivers/net/hyperv/netvsc_drv.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/net/hyperv/netvsc_drv.c +7 -2
@@ -1170,12 +1170,15 @@ static void netvsc_get_stats64(struct net_device *net, struct rtnl_link_stats64 *t) {struct net_device_context *ndev_ctx =netdev_priv (net); -struct netvsc_device *nvdev =rcu_dereference_rtnl (ndev_ctx->nvdev); +struct netvsc_device *nvdev;struct netvsc_vf_pcpu_stats vf_tot;int i; +rcu_read_lock (); + + nvdev =rcu_dereference (ndev_ctx->nvdev);if (!nvdev) -return ; + goto out;netdev_stats_to_stats64 (t, &net->stats);
@@ -1214,6 +1217,8 @@ static void netvsc_get_stats64(struct net_device *net, t->rx_packets += packets; t->multicast += multicast; } +out: +rcu_read_unlock (); }static int netvsc_set_mac_addr (struct net_device *ndev,void *p)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 3/40 net: tc35815: Explicitly check NET_IP_ALIGN is not zero in tc35815_rx
In reply to Greg Kroah-Hartman[ Upstream commit 125b7e0949d4e72b15c2b1a1590f8cece985a918 ]
clang warns:
drivers/net/ethernet/toshiba/tc35815.c:1507:30: warning: use of logical '&&' with constant operand [-Wconstant-logical-operand]
if (!HAVE_DMA_RXALIGN(lp) && NET_IP_ALIGN)
^ ~~~~~~~~~~~~
drivers/net/ethernet/toshiba/tc35815.c:1507:30: note: use '&' for a
bitwise operation
if (!HAVE_DMA_RXALIGN(lp) && NET_IP_ALIGN)
^~
&
drivers/net/ethernet/toshiba/tc35815.c:1507:30: note: remove constant to
silence this warning
if (!HAVE_DMA_RXALIGN(lp) && NET_IP_ALIGN)
~^~~~~~~~~~~~~~~1 warning generated.
Explicitly check that NET_IP_ALIGN is not zero, which matches how this is checked in other parts of the tree. Because NET_IP_ALIGN is a build time constant, this check will be constant folded away during optimization.
--- drivers/net/ethernet/toshiba/tc35815.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/toshiba/tc35815.c +1 -1
@@ -1497,7 +1497,7 @@ tc35815_rx(struct net_device *dev, int limit)pci_unmap_single (lp->pci_dev, lp->rx_skbs[cur_bd].skb_dma,RX_BUF_SIZE ,PCI_DMA_FROMDEVICE ); -if (!HAVE_DMA_RXALIGN (lp) &&NET_IP_ALIGN ) +if (!HAVE_DMA_RXALIGN (lp) &&NET_IP_ALIGN !=0 )memmove (skb->data, skb->data -NET_IP_ALIGN , pkt_len); data =skb_put (skb, pkt_len);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 4/40 Bluetooth: btqca: Add a short delay before downloading the NVM
In reply to Greg Kroah-Hartman[ Upstream commit 8059ba0bd0e4694e51c2ee6438a77b325f06c0d5 ]
On WCN3990 downloading the NVM sometimes fails with a "TLV response size mismatch" error:
[ 174.949955] Bluetooth: btqca.c:qca_download_firmware() hci0: QCA Downloading qca/crnv21.bin [ 174.958718] Bluetooth: btqca.c:qca_tlv_send_segment() hci0: QCA TLV response size mismatch
It seems the controller needs a short time after downloading the firmware before it is ready for the NVM. A delay as short as 1 ms seems sufficient, make it 10 ms just in case. No event is received during the delay, hence we don't just silently drop an extra event.
--- drivers/bluetooth/btqca.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/bluetooth/btqca.c +3 -0
@@ -363,6 +363,9 @@ int qca_uart_setup_rome(struct hci_dev *hdev, uint8_t baudrate)return err; } +/* Give the controller some time to get ready to receive the NVM */ +msleep (10 ); +/* Download NVM configuration */ config.type =TLV_TYPE_NVM ; snprintf(config.fwname, sizeof(config.fwname), "qca/nvm_%08x.bin",
Signature · 1 line
2.20.1
Re: [PATCH 4.14 04/40] Bluetooth: btqca: Add a short delay before downloading the NVM
Quoted 7 lines · Greg Kroah-Hartman
[ Upstream commit
8059ba0bd0e4694e51c2ee6438a77b325f06c0d5]On WCN3990 downloading the NVM sometimes fails with a "TLV response size mismatch" error:
[ 174.949955] Bluetooth: btqca.c:qca_download_firmware() hci0: QCA Downloading qca/crnv21.bin [ 174.958718] Bluetooth: btqca.c:qca_tlv_send_segment() hci0: QCA TLV response size mismatch
WC3990 support was only added in 4.19, so this shouldn't be needed in older kernels, but it shouldn't do any harm either ;-)
Quoted 26 lines
It seems the controller needs a short time after downloading the firmware before it is ready for the NVM. A delay as short as 1 ms seems sufficient, make it 10 ms just in case. No event is received during the delay, hence we don't just silently drop an extra event.
Signed-off-by Matthias Kaehlcke <[email protected]>Signed-off-by Marcel Holtmann <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- drivers/bluetooth/btqca.c | 3 +++ 1 file changed, 3 insertions(+)drivers/bluetooth/btqca.c +3
-0@@ -363,6 +363,9 @@ int qca_uart_setup_rome(struct hci_dev *hdev, uint8_t baudrate)return err; } +/* Give the controller some time to get ready to receive the NVM */ +msleep (10 ); +/* Download NVM configuration */ config.type =TLV_TYPE_NVM ; snprintf(config.fwname, sizeof(config.fwname), "qca/nvm_%08x.bin",
Greg Kroah-Hartman
maintainerPATCH 5/40 Bluetooth: hidp: Let hidp_send_message return number of queued bytes
In reply to Greg Kroah-Hartman[ Upstream commit 48d9cc9d85dde37c87abb7ac9bbec6598ba44b56 ]
Let hidp_send_message return the number of successfully queued bytes instead of an unconditional 0.
With the return value fixed to 0, other drivers relying on hidp, such as hidraw, can not return meaningful values from their respective implementations of write(). In particular, with the current behavior, a hidraw device's write() will have different return values depending on whether the device is connected via USB or Bluetooth, which makes it harder to abstract away the transport layer.
--- net/bluetooth/hidp/core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
net/bluetooth/hidp/core.c +7 -2
@@ -101,6 +101,7 @@ static int hidp_send_message(struct hidp_session *session, struct socket *sock, {struct sk_buff *skb;struct sock *sk = sock->sk; +int ret;BT_DBG ("session %p data %p size %d" , session, data, size);
@@ -114,13 +115,17 @@ static int hidp_send_message(struct hidp_session *session, struct socket *sock, }skb_put_u8 (skb, hdr); -if (data && size >0 ) +if (data && size >0 ) {skb_put_data (skb, data, size); + ret = size; + }else { + ret =0 ; + }skb_queue_tail (transmit, skb);wake_up_interruptible (sk_sleep (sk)); -return 0 ; +return ret; } static int hidp_send_ctrl_message(struct hidp_session *session,
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 6/40 ibmveth: Convert multicast list size for little-endian system
In reply to Greg Kroah-Hartman[ Upstream commit 66cf4710b23ab2adda11155684a2c8826f4fe732 ]
The ibm,mac-address-filters property defines the maximum number of addresses the hypervisor's multicast filter list can support. It is encoded as a big-endian integer in the OF device tree, but the virtual ethernet driver does not convert it for use by little-endian systems. As a result, the driver is not behaving as it should on affected systems when a large number of multicast addresses are assigned to the device.
--- drivers/net/ethernet/ibm/ibmveth.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/net/ethernet/ibm/ibmveth.c +5 -4
@@ -1618,7 +1618,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)struct net_device *netdev;struct ibmveth_adapter *adapter;unsigned char *mac_addr_p; -unsigned int *mcastFilterSize_p; +__be32 *mcastFilterSize_p;long ret;unsigned long ret_attr;
@@ -1640,8 +1640,9 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)return -EINVAL ; } - mcastFilterSize_p = (unsigned int *)vio_get_attribute (dev, -VETH_MCAST_FILTER_SIZE ,NULL ); + mcastFilterSize_p = (__be32 *)vio_get_attribute (dev, +VETH_MCAST_FILTER_SIZE , +NULL );if (!mcastFilterSize_p) {dev_err (&dev->dev,"Can't find VETH_MCAST_FILTER_SIZE " "attribute\n" );
@@ -1658,7 +1659,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) adapter->vdev = dev; adapter->netdev = netdev; - adapter->mcastFilterSize = *mcastFilterSize_p; + adapter->mcastFilterSize =be32_to_cpu (*mcastFilterSize_p); adapter->pool_config =0 ;netif_napi_add (netdev, &adapter->napi, ibmveth_poll,16 );
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 7/40 gpio: Fix build error of function redefinition
In reply to Greg Kroah-Hartman[ Upstream commit 68e03b85474a51ec1921b4d13204782594ef7223 ]
when do randbuilding, I got this error:
In file included from drivers/hwmon/pmbus/ucd9000.c:19:0:./include/linux/gpio/driver.h:576:1: error: redefinition of gpiochip_add_pin_range
gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, ^~~~~~~~~~~~~~~~~~~~~~
In file included from drivers/hwmon/pmbus/ucd9000.c:18:0:./include/linux/gpio.h:245:1: note: previous definition of gpiochip_add_pin_range was here
gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, ^~~~~~~~~~~~~~~~~~~~~~
--- include/linux/gpio.h | 24 ------------------------ 1 file changed, 24 deletions(-)
include/linux/gpio.h +0 -24
@@ -230,30 +230,6 @@ static inline int irq_to_gpio(unsigned irq)return -EINVAL ; } -static inline int -gpiochip_add_pin_range (struct gpio_chip *chip,const char *pinctl_name, -unsigned int gpio_offset,unsigned int pin_offset, -unsigned int npins) -{ -WARN_ON (1 ); -return -EINVAL ; -} - -static inline int -gpiochip_add_pingroup_range (struct gpio_chip *chip, -struct pinctrl_dev *pctldev, -unsigned int gpio_offset,const char *pin_group) -{ -WARN_ON (1 ); -return -EINVAL ; -} - -static inline void -gpiochip_remove_pin_ranges (struct gpio_chip *chip) -{ -WARN_ON (1 ); -} -static inline int devm_gpio_request (struct device *dev,unsigned gpio,const char *label) {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 8/40 drm/mediatek: use correct device to import PRIME buffers
In reply to Greg Kroah-Hartman[ Upstream commit 4c6f3196e6ea111c456c6086dc3f57d4706b0b2d ]
PRIME buffers should be imported using the DMA device. To this end, use a custom import function that mimics drm_gem_prime_import_dev(), but passes the correct device.
--- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
drivers/gpu/drm/mediatek/mtk_drm_drv.c +13 -1
@@ -287,6 +287,18 @@ static const struct file_operations mtk_drm_fops = { .compat_ioctl = drm_compat_ioctl, }; +/* +* We need to override this because the device used to import the memory is +* not dev->dev, as drm_gem_prime_import() expects. +*/ +struct drm_gem_object *mtk_drm_gem_prime_import (struct drm_device *dev, +struct dma_buf *dma_buf) +{ +struct mtk_drm_private *private = dev->dev_private; + +return drm_gem_prime_import_dev (dev, dma_buf, private->dma_dev); +} +static struct drm_driver mtk_drm_driver = { .driver_features =DRIVER_MODESET |DRIVER_GEM |DRIVER_PRIME |DRIVER_ATOMIC ,
@@ -298,7 +310,7 @@ static struct drm_driver mtk_drm_driver = { .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_export = drm_gem_prime_export, - .gem_prime_import = drm_gem_prime_import, + .gem_prime_import = mtk_drm_gem_prime_import, .gem_prime_get_sg_table = mtk_gem_prime_get_sg_table, .gem_prime_import_sg_table = mtk_gem_prime_import_sg_table, .gem_prime_mmap = mtk_drm_gem_mmap_buf,
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 9/40 drm/mediatek: set DMA max segment size
In reply to Greg Kroah-Hartman[ Upstream commit 070955558e820b9a89c570b91b1f21762f62b288 ]
This driver requires imported PRIME buffers to appear contiguously in its IO address space. Make sure this is the case by setting the maximum DMA segment size to a more suitable value than the default 64KB.
--- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 35 ++++++++++++++++++++++++-- drivers/gpu/drm/mediatek/mtk_drm_drv.h | 2 ++ 2 files changed, 35 insertions(+), 2 deletions(-)
drivers/gpu/drm/mediatek/mtk_drm_drv.c +33 -2
@@ -185,6 +185,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)struct mtk_drm_private *private = drm->dev_private;struct platform_device *pdev;struct device_node *np; +struct device *dma_dev;int ret;if (!iommu_present (&platform_bus_type))
@@ -242,7 +243,29 @@ static int mtk_drm_kms_init(struct drm_device *drm) goto err_component_unbind; } - private->dma_dev = &pdev->dev; + dma_dev = &pdev->dev; + private->dma_dev = dma_dev; + +/* +* Configure the DMA segment size to make sure we get contiguous IOVA +* when importing PRIME buffers. +*/ +if (!dma_dev->dma_parms) { + private->dma_parms_allocated = true; + dma_dev->dma_parms = +devm_kzalloc (drm->dev,sizeof (*dma_dev->dma_parms), +GFP_KERNEL ); + } +if (!dma_dev->dma_parms) { + ret = -ENOMEM ; + goto err_component_unbind; + } + + ret =dma_set_max_seg_size (dma_dev, (unsigned int )DMA_BIT_MASK (32 )); +if (ret) { +dev_err (dma_dev,"Failed to set DMA segment size\n" ); + goto err_unset_dma_parms; + }/* * We don't use the drm_irq_install() helpers provided by the DRM
@@ -252,13 +275,16 @@ static int mtk_drm_kms_init(struct drm_device *drm) drm->irq_enabled = true; ret =drm_vblank_init (drm,MAX_CRTC );if (ret <0 ) - goto err_component_unbind; + goto err_unset_dma_parms;drm_kms_helper_poll_init (drm);drm_mode_config_reset (drm);return 0 ; +err_unset_dma_parms: +if (private->dma_parms_allocated) + dma_dev->dma_parms =NULL ; err_component_unbind:component_unbind_all (drm->dev, drm); err_config_cleanup:
@@ -269,9 +295,14 @@ err_config_cleanup:static void mtk_drm_kms_deinit (struct drm_device *drm) { +struct mtk_drm_private *private = drm->dev_private; +drm_kms_helper_poll_fini (drm);drm_atomic_helper_shutdown (drm); +if (private->dma_parms_allocated) + private->dma_dev->dma_parms =NULL ; +component_unbind_all (drm->dev, drm);drm_mode_config_cleanup (drm); }
drivers/gpu/drm/mediatek/mtk_drm_drv.h +2 -0
@@ -56,6 +56,8 @@ struct mtk_drm_private { } commit;struct drm_atomic_state *suspend_state; + +bool dma_parms_allocated; };extern struct platform_driver mtk_ddp_driver;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 10/40 cxgb4: fix a memory leak bug
In reply to Greg Kroah-Hartman[ Upstream commit c554336efa9bbc28d6ec14efbee3c7d63c61a34f ]
In blocked_fl_write(), 't' is not deallocated if bitmap_parse_user() fails, leading to a memory leak bug. To fix this issue, free t before returning the error.
--- drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c +3 -1
@@ -2777,8 +2777,10 @@ static ssize_t blocked_fl_write(struct file *filp, const char __user *ubuf,return -ENOMEM ; err =bitmap_parse_user (ubuf, count, t, adap->sge.egr_sz); -if (err) +if (err) { +kvfree (t);return err; + }bitmap_copy (adap->sge.blocked_fl, t, adap->sge.egr_sz);kvfree (t);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 11/40 liquidio: add cleanup in octeon_setup_iq()
In reply to Greg Kroah-Hartman[ Upstream commit 6f967f8b1be7001b31c46429f2ee7d275af2190f ]
If oct->fn_list.enable_io_queues() fails, no cleanup is executed, leading to memory/resource leaks. To fix this issue, invoke octeon_delete_instr_queue() before returning from the function.
--- drivers/net/ethernet/cavium/liquidio/request_manager.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/cavium/liquidio/request_manager.c +3 -1
@@ -232,8 +232,10 @@ int octeon_setup_iq(struct octeon_device *oct, } oct->num_iqs++; -if (oct->fn_list.enable_io_queues (oct)) +if (oct->fn_list.enable_io_queues (oct)) { +octeon_delete_instr_queue (oct, iq_no);return 1 ; + }return 0 ; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 12/40 net: myri10ge: fix memory leaks
In reply to Greg Kroah-Hartman[ Upstream commit 20fb7c7a39b5c719e2e619673b5f5729ee7d2306 ]
In myri10ge_probe(), myri10ge_alloc_slices() is invoked to allocate slices related structures. Later on, myri10ge_request_irq() is used to get an irq. However, if this process fails, the allocated slices related structures are not deallocated, leading to memory leaks. To fix this issue, revise the target label of the goto statement to 'abort_with_slices'.
--- drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/myricom/myri10ge/myri10ge.c +1 -1
@@ -3922,7 +3922,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)* setup (if available). */ status =myri10ge_request_irq (mgp);if (status !=0 ) - goto abort_with_firmware; + goto abort_with_slices;myri10ge_free_irq (mgp);/* Save configuration space to be restored if the
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 13/40 lan78xx: Fix memory leaks
In reply to Greg Kroah-Hartman[ Upstream commit b9cbf8a64865b50fd0f4a3915fa00ac7365cdf8f ]
In lan78xx_probe(), a new urb is allocated through usb_alloc_urb() and saved to 'dev->urb_intr'. However, in the following execution, if an error occurs, 'dev->urb_intr' is not deallocated, leading to memory leaks. To fix this issue, invoke usb_free_urb() to free the allocated urb before returning from the function.
--- drivers/net/usb/lan78xx.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/net/usb/lan78xx.c +5 -3
@@ -3645,7 +3645,7 @@ static int lan78xx_probe(struct usb_interface *intf, ret =register_netdev (netdev);if (ret !=0 ) {netif_err (dev, probe, netdev,"couldn't register the device\n" ); - goto out3; + goto out4; }usb_set_intfdata (intf, dev);
@@ -3660,12 +3660,14 @@ static int lan78xx_probe(struct usb_interface *intf, ret =lan78xx_phy_init (dev);if (ret <0 ) - goto out4; + goto out5;return 0 ; -out4: +out5:unregister_netdev (netdev); +out4: +usb_free_urb (dev->urb_intr); out3:lan78xx_unbind (dev, intf); out2:
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 14/40 vfs: fix page locking deadlocks when deduping files
In reply to Greg Kroah-Hartman[ Upstream commit edc58dd0123b552453a74369bd0c8d890b497b4b ]
When dedupe wants to use the page cache to compare parts of two files for dedupe, we must be very careful to handle locking correctly. The current code doesn't do this. It must lock and unlock the page only once if the two pages are the same, since the overlapping range check doesn't catch this when blocksize < pagesize. If the pages are distinct but from the same file, we must observe page locking order and lock them in order of increasing offset to avoid clashing with writeback locking.
--- fs/read_write.c | 49 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 8 deletions(-)
fs/read_write.c +41 -8
@@ -1882,10 +1882,7 @@ int vfs_clone_file_range(struct file *file_in, loff_t pos_in, }EXPORT_SYMBOL (vfs_clone_file_range); -/* -* Read a page's worth of file data into the page cache. Return the page -* locked. -*/ +/* Read a page's worth of file data into the page cache. */ static struct page *vfs_dedupe_get_page (struct inode *inode,loff_t offset) {struct address_space *mapping;
@@ -1901,10 +1898,32 @@ static struct page *vfs_dedupe_get_page(struct inode *inode, loff_t offset)put_page (page);return ERR_PTR (-EIO ); } -lock_page (page);return page; } +/* +* Lock two pages, ensuring that we lock in offset order if the pages are from +* the same file. +*/ +static void vfs_lock_two_pages (struct page *page1,struct page *page2) +{ +/* Always lock in order of increasing index. */ +if (page1->index > page2->index) +swap (page1, page2); + +lock_page (page1); +if (page1 != page2) +lock_page (page2); +} + +/* Unlock two pages, being careful not to unlock the same page twice. */ +static void vfs_unlock_two_pages (struct page *page1,struct page *page2) +{ +unlock_page (page1); +if (page1 != page2) +unlock_page (page2); +} +/* * Compare extents of two files to see if they are the same. * Caller must have locked both inodes to prevent write races.
@@ -1942,10 +1961,24 @@ int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff, dest_page =vfs_dedupe_get_page (dest, destoff);if (IS_ERR (dest_page)) { error =PTR_ERR (dest_page); -unlock_page (src_page);put_page (src_page); goto out_error; } + +vfs_lock_two_pages (src_page, dest_page); + +/* +* Now that we've locked both pages, make sure they're still +* mapped to the file data we're interested in. If not, +* someone is invalidating pages on us and we lose. +*/ +if (!PageUptodate (src_page) || !PageUptodate (dest_page) || + src_page->mapping != src->i_mapping || + dest_page->mapping != dest->i_mapping) { + same = false; + goto unlock; + } + src_addr =kmap_atomic (src_page); dest_addr =kmap_atomic (dest_page);
@@ -1957,8 +1990,8 @@ int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff,kunmap_atomic (dest_addr);kunmap_atomic (src_addr); -unlock_page (dest_page); -unlock_page (src_page); +unlock: +vfs_unlock_two_pages (src_page, dest_page);put_page (dest_page);put_page (src_page);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 15/40 cx82310_eth: fix a memory leak bug
In reply to Greg Kroah-Hartman[ Upstream commit 1eca92eef18719027d394bf1a2d276f43e7cf886 ]
In cx82310_bind(), 'dev->partial_data' is allocated through kmalloc(). Then, the execution waits for the firmware to become ready. If the firmware is not ready in time, the execution is terminated. However, the allocated 'dev->partial_data' is not deallocated on this path, leading to a memory leak bug. To fix this issue, free 'dev->partial_data' before returning the error.
--- drivers/net/usb/cx82310_eth.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/usb/cx82310_eth.c +2 -1
@@ -175,7 +175,8 @@ static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf) }if (!timeout) {dev_err (&udev->dev,"firmware not ready in time\n" ); -return -ETIMEDOUT ; + ret = -ETIMEDOUT ; + goto err; }/* enable ethernet mode (?) */
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 16/40 net: kalmia: fix memory leaks
In reply to Greg Kroah-Hartman[ Upstream commit f1472cb09f11ddb41d4be84f0650835cb65a9073 ]
In kalmia_init_and_get_ethernet_addr(), 'usb_buf' is allocated through kmalloc(). In the following execution, if the 'status' returned by kalmia_send_init_packet() is not 0, 'usb_buf' is not deallocated, leading to memory leaks. To fix this issue, add the 'out' label to free 'usb_buf'.
--- drivers/net/usb/kalmia.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/usb/kalmia.c +3 -3
@@ -117,16 +117,16 @@ kalmia_init_and_get_ethernet_addr(struct usbnet *dev, u8 *ethernet_addr) status =kalmia_send_init_packet (dev, usb_buf,sizeof (init_msg_1) /sizeof (init_msg_1[0 ]), usb_buf,24 );if (status !=0 ) -return status; + goto out;memcpy (usb_buf, init_msg_2,12 ); status =kalmia_send_init_packet (dev, usb_buf,sizeof (init_msg_2) /sizeof (init_msg_2[0 ]), usb_buf,28 );if (status !=0 ) -return status; + goto out;memcpy (ethernet_addr, usb_buf +10 ,ETH_ALEN ); - +out:kfree (usb_buf);return status; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 17/40 wimax/i2400m: fix a memory leak bug
In reply to Greg Kroah-Hartman[ Upstream commit 44ef3a03252844a8753479b0cea7f29e4a804bdc ]
In i2400m_barker_db_init(), 'options_orig' is allocated through kstrdup() to hold the original command line options. Then, the options are parsed. However, if an error occurs during the parsing process, 'options_orig' is not deallocated, leading to a memory leak bug. To fix this issue, free 'options_orig' before returning the error.
--- drivers/net/wimax/i2400m/fw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/wimax/i2400m/fw.c +3 -1
@@ -351,13 +351,15 @@ int i2400m_barker_db_init(const char *_options) } result =i2400m_barker_db_add (barker);if (result <0 ) - goto error_add; + goto error_parse_add; }kfree (options_orig); }return 0 ; +error_parse_add: error_parse: +kfree (options_orig); error_add:kfree (i2400m_barker_db);return result;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 18/40 ravb: Fix use-after-free ravb_tstamp_skb
In reply to Greg Kroah-Hartman[ Upstream commit cfef46d692efd852a0da6803f920cc756eea2855 ]
When a Tx timestamp is requested, a pointer to the skb is stored in the ravb_tstamp_skb struct. This was done without an skb_get. There exists the possibility that the skb could be freed by ravb_tx_free (when ravb_tx_free is called from ravb_start_xmit) before the timestamp was processed, leading to a use-after-free bug.
Use skb_get when filling a ravb_tstamp_skb struct, and add appropriate frees/consumes when a ravb_tstamp_skb struct is freed.
--- drivers/net/ethernet/renesas/ravb_main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/ethernet/renesas/ravb_main.c +6 -2
@@ -1,6 +1,6 @@/* Renesas Ethernet AVB device driver * -* Copyright (C) 2014-2015 Renesas Electronics Corporation +* Copyright (C) 2014-2019 Renesas Electronics Corporation * Copyright (C) 2015 Renesas Solutions Corp. * Copyright (C) 2015-2016 Cogent Embedded, Inc. <[email protected]> *
@@ -513,7 +513,10 @@ static void ravb_get_tx_tstamp(struct net_device *ndev)kfree (ts_skb);if (tag == tfa_tag) {skb_tstamp_tx (skb, &shhwtstamps); +dev_consume_skb_any (skb);break ; + }else { +dev_kfree_skb_any (skb); } }ravb_modify (ndev,TCCR ,TCCR_TFR ,TCCR_TFR );
@@ -1576,7 +1579,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) DMA_TO_DEVICE); goto unmap; } - ts_skb->skb = skb; + ts_skb->skb =skb_get (skb); ts_skb->tag = priv->ts_skb_tag++; priv->ts_skb_tag &=0x3ff ;list_add_tail (&ts_skb->list, &priv->ts_skb_list);
@@ -1704,6 +1707,7 @@ static int ravb_close(struct net_device *ndev)/* Clear the timestamp list */ list_for_each_entry_safe (ts_skb, ts_skb2, &priv->ts_skb_list, list) {list_del (&ts_skb->list); +kfree_skb (ts_skb->skb);kfree (ts_skb); }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 19/40 kprobes: Fix potential deadlock in kprobe_optimizer()
In reply to Greg Kroah-Hartman[ Upstream commit f1c6ece23729257fb46562ff9224cf5f61b818da ]
lockdep reports the following deadlock scenario:
WARNING: possible circular locking dependency detected
kworker/1:1/48 is trying to acquire lock:
000000008d7a62b2 (text_mutex){+.+.}, at: kprobe_optimizer+0x163/0x290
but task is already holding lock:
00000000850b5e2d (module_mutex){+.+.}, at: kprobe_optimizer+0x31/0x290
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (module_mutex){+.+.}:
__mutex_lock+0xac/0x9f0
mutex_lock_nested+0x1b/0x20
set_all_modules_text_rw+0x22/0x90
ftrace_arch_code_modify_prepare+0x1c/0x20
ftrace_run_update_code+0xe/0x30
ftrace_startup_enable+0x2e/0x50
ftrace_startup+0xa7/0x100
register_ftrace_function+0x27/0x70
arm_kprobe+0xb3/0x130
enable_kprobe+0x83/0xa0
enable_trace_kprobe.part.0+0x2e/0x80
kprobe_register+0x6f/0xc0
perf_trace_event_init+0x16b/0x270
perf_kprobe_init+0xa7/0xe0
perf_kprobe_event_init+0x3e/0x70
perf_try_init_event+0x4a/0x140
perf_event_alloc+0x93a/0xde0
__do_sys_perf_event_open+0x19f/0xf30
__x64_sys_perf_event_open+0x20/0x30
do_syscall_64+0x65/0x1d0
entry_SYSCALL_64_after_hwframe+0x49/0xbe-> #0 (text_mutex){+.+.}:
__lock_acquire+0xfcb/0x1b60
lock_acquire+0xca/0x1d0
__mutex_lock+0xac/0x9f0
mutex_lock_nested+0x1b/0x20
kprobe_optimizer+0x163/0x290
process_one_work+0x22b/0x560
worker_thread+0x50/0x3c0
kthread+0x112/0x150
ret_from_fork+0x3a/0x50other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(module_mutex);
lock(text_mutex);
lock(module_mutex); lock(text_mutex);
*** DEADLOCK ***
As a reproducer I've been using bcc's funccount.py
(https://github.com/iovisor/bcc/blob/master/tools/funccount.py),
for example:
# ./funccount.py '*interrupt*'
That immediately triggers the lockdep splat.
Fix by acquiring text_mutex before module_mutex in kprobe_optimizer().
--- kernel/kprobes.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
kernel/kprobes.c +4 -4
@@ -483,6 +483,7 @@ static DECLARE_DELAYED_WORK(optimizing_work, kprobe_optimizer);*/ static void do_optimize_kprobes (void ) { +lockdep_assert_held (&text_mutex);/* * The optimization/unoptimization refers online_cpus via * stop_machine() and cpu-hotplug modifies online_cpus.
@@ -500,9 +501,7 @@ static void do_optimize_kprobes(void) list_empty(&optimizing_list))return ; -mutex_lock (&text_mutex);arch_optimize_kprobes (&optimizing_list); -mutex_unlock (&text_mutex); }/*
@@ -513,6 +512,7 @@ static void do_unoptimize_kprobes(void) {struct optimized_kprobe *op, *tmp; +lockdep_assert_held (&text_mutex);/* See comment in do_optimize_kprobes() */ lockdep_assert_cpus_held ();
@@ -520,7 +520,6 @@ static void do_unoptimize_kprobes(void)if (list_empty (&unoptimizing_list))return ; -mutex_lock (&text_mutex);arch_unoptimize_kprobes (&unoptimizing_list, &freeing_list);/* Loop free_list for disarming */ list_for_each_entry_safe (op, tmp, &freeing_list, list) {
@@ -537,7 +536,6 @@ static void do_unoptimize_kprobes(void) }else list_del_init (&op->list); } -mutex_unlock (&text_mutex); }/* Reclaim all kprobes on the free_list */
@@ -563,6 +561,7 @@ static void kprobe_optimizer(struct work_struct *work) {mutex_lock (&kprobe_mutex);cpus_read_lock (); +mutex_lock (&text_mutex);/* Lock modules while optimizing kprobes */ mutex_lock (&module_mutex);
@@ -590,6 +589,7 @@ static void kprobe_optimizer(struct work_struct *work)do_free_cleaned_kprobes ();mutex_unlock (&module_mutex); +mutex_unlock (&text_mutex);cpus_read_unlock ();mutex_unlock (&kprobe_mutex);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 20/40 HID: cp2112: prevent sleeping function called from invalid context
In reply to Greg Kroah-Hartman[ Upstream commit 2d05dba2b25ecb0f8fc3a0b4eb2232da6454a47b ]
When calling request_threaded_irq() with a CP2112, the function cp2112_gpio_irq_startup() is called in a IRQ context.
Therefore we can not sleep, and we can not callcp2112_gpio_direction_input() there.
Move the call to cp2112_gpio_direction_input() earlier to have a working driver.
--- drivers/hid/hid-cp2112.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/hid/hid-cp2112.c +6 -2
@@ -1149,8 +1149,6 @@ static unsigned int cp2112_gpio_irq_startup(struct irq_data *d)INIT_DELAYED_WORK (&dev->gpio_poll_worker, cp2112_gpio_poll_callback); -cp2112_gpio_direction_input (gc, d->hwirq); -if (!dev->gpio_poll) { dev->gpio_poll = true;schedule_delayed_work (&dev->gpio_poll_worker,0 );
@@ -1198,6 +1196,12 @@ static int __maybe_unused cp2112_allocate_irq(struct cp2112_device *dev,return PTR_ERR (dev->desc[pin]); } + ret =cp2112_gpio_direction_input (&dev->gc, pin); +if (ret <0 ) { +dev_err (dev->gc.parent,"Failed to set GPIO to input dir\n" ); + goto err_desc; + } + ret =gpiochip_lock_as_irq (&dev->gc, pin);if (ret) {dev_err (dev->gc.parent,"Failed to lock GPIO as interrupt\n" );
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 21/40 Input: hyperv-keyboard: Use in-place iterator API in the channel callback
In reply to Greg Kroah-Hartman[ Upstream commit d09bc83640d524b8467a660db7b1d15e6562a1de ]
Simplify the ring buffer handling with the in-place API.
Also avoid the dynamic allocation and the memory leak in the channel callback function.
--- drivers/input/serio/hyperv-keyboard.c | 35 +++++---------------------- 1 file changed, 6 insertions(+), 29 deletions(-)
drivers/input/serio/hyperv-keyboard.c +6 -29
@@ -245,40 +245,17 @@ static void hv_kbd_handle_received_packet(struct hv_device *hv_dev,static void hv_kbd_on_channel_callback (void *context) { +struct vmpacket_descriptor *desc;struct hv_device *hv_dev = context; -void *buffer; -int bufferlen =0x100 ;/* Start with sensible size */ u32 bytes_recvd;u64 req_id; -int error; - buffer =kmalloc (bufferlen,GFP_ATOMIC ); -if (!buffer) -return ; - -while (1 ) { - error =vmbus_recvpacket_raw (hv_dev->channel, buffer, bufferlen, - &bytes_recvd, &req_id); -switch (error) { -case 0 : -if (bytes_recvd ==0 ) { -kfree (buffer); -return ; - } - -hv_kbd_handle_received_packet (hv_dev, buffer, - bytes_recvd, req_id); -break ; + foreach_vmbus_pkt(desc, hv_dev->channel) { + bytes_recvd = desc->len8 *8 ; + req_id = desc->trans_id; -case -ENOBUFS : -kfree (buffer); -/* Handle large packet */ - bufferlen = bytes_recvd; - buffer =kmalloc (bytes_recvd,GFP_ATOMIC ); -if (!buffer) -return ; -break ; - } +hv_kbd_handle_received_packet (hv_dev, desc, bytes_recvd, + req_id); } }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 22/40 Tools: hv: kvp: eliminate may be used uninitialized warning
In reply to Greg Kroah-Hartman[ Upstream commit 89eb4d8d25722a0a0194cf7fa47ba602e32a6da7 ]
When building hv_kvp_daemon GCC-8.3 complains:
hv_kvp_daemon.c: In function ‘kvp_get_ip_info.constprop’:
hv_kvp_daemon.c:812:30: warning: ‘ip_buffer’ may be used uninitialized in this function [-Wmaybe-uninitialized]
struct hv_kvp_ipaddr_value *ip_buffer;
this seems to be a false positive: we only use ip_buffer when op == KVP_OP_GET_IP_INFO and it is only unset when op == KVP_OP_ENUMERATE.
Silence the warning by initializing ip_buffer to NULL.
--- tools/hv/hv_kvp_daemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/hv/hv_kvp_daemon.c +1 -1
@@ -867,7 +867,7 @@ kvp_get_ip_info(int family, char *if_name, int op,int sn_offset =0 ;int error =0 ;char *buffer; -struct hv_kvp_ipaddr_value *ip_buffer; +struct hv_kvp_ipaddr_value *ip_buffer =NULL ;char cidr_mask[5 ];/* /xyz */ int weight;int i;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 23/40 IB/mlx4: Fix memory leaks
In reply to Greg Kroah-Hartman[ Upstream commit 5c1baaa82cea2c815a5180ded402a7cd455d1810 ]
In mlx4_ib_alloc_pv_bufs(), 'tun_qp->tx_ring' is allocated through kcalloc(). However, it is not always deallocated in the following execution if an error occurs, leading to memory leaks. To fix this issue, free 'tun_qp->tx_ring' whenever an error occurs.
--- drivers/infiniband/hw/mlx4/mad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/hw/mlx4/mad.c +2 -2
@@ -1680,8 +1680,6 @@ tx_err: tx_buf_size, DMA_TO_DEVICE);kfree (tun_qp->tx_ring[i].buf.addr); } -kfree (tun_qp->tx_ring); - tun_qp->tx_ring =NULL ; i =MLX4_NUM_TUNNEL_BUFS ; err:while (i >0 ) {
@@ -1690,6 +1688,8 @@ err: rx_buf_size, DMA_FROM_DEVICE);kfree (tun_qp->ring[i].addr); } +kfree (tun_qp->tx_ring); + tun_qp->tx_ring =NULL ;kfree (tun_qp->ring); tun_qp->ring =NULL ;return -ENOMEM ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 24/40 ceph: fix buffer free while holding i_ceph_lock in __ceph_setxattr()
In reply to Greg Kroah-Hartman[ Upstream commit 86968ef21596515958d5f0a40233d02be78ecec0 ]
Calling ceph_buffer_put() in __ceph_setxattr() may end up freeing the i_xattrs.prealloc_blob buffer while holding the i_ceph_lock. This can be fixed by postponing the call until later, when the lock is released.
The following backtrace was triggered by fstests generic/117.
BUG: sleeping function called from invalid context at mm/vmalloc.c:2283
in_atomic(): 1, irqs_disabled(): 0, pid: 650, name: fsstress
3 locks held by fsstress/650:
#0: 00000000870a0fe8 (sb_writers#8){.+.+}, at: mnt_want_write+0x20/0x50
#1: 00000000ba0c4c74 (&type->i_mutex_dir_key#6){++++}, at: vfs_setxattr+0x55/0xa0
#2: 000000008dfbb3f2 (&(&ci->i_ceph_lock)->rlock){+.+.}, at: __ceph_setxattr+0x297/0x810
CPU: 1 PID: 650 Comm: fsstress Not tainted 5.2.0+ #437
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58-prebuilt.qemu.org 04/01/2014
Call Trace:
dump_stack+0x67/0x90
___might_sleep.cold+0x9f/0xb1
vfree+0x4b/0x60
ceph_buffer_release+0x1b/0x60
__ceph_setxattr+0x2b4/0x810
__vfs_setxattr+0x66/0x80
__vfs_setxattr_noperm+0x59/0xf0
vfs_setxattr+0x81/0xa0
setxattr+0x115/0x230
? filename_lookup+0xc9/0x140
? rcu_read_lock_sched_held+0x74/0x80
? rcu_sync_lockdep_assert+0x2e/0x60
? __sb_start_write+0x142/0x1a0
? mnt_want_write+0x20/0x50
path_setxattr+0xba/0xd0
__x64_sys_lsetxattr+0x24/0x30
do_syscall_64+0x50/0x1c0
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x7ff23514359a--- fs/ceph/xattr.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
fs/ceph/xattr.c +6 -2
@@ -955,6 +955,7 @@ int __ceph_setxattr(struct inode *inode, const char *name,struct ceph_inode_info *ci =ceph_inode (inode);struct ceph_mds_client *mdsc =ceph_sb_to_client (inode->i_sb)->mdsc;struct ceph_cap_flush *prealloc_cf =NULL ; +struct ceph_buffer *old_blob =NULL ;int issued;int err;int dirty =0 ;
@@ -1023,13 +1024,15 @@ retry:struct ceph_buffer *blob;spin_unlock (&ci->i_ceph_lock); -dout (" preaallocating new blob size=%d\n" , required_blob_size); +ceph_buffer_put (old_blob);/* Shouldn't be required */ +dout (" pre-allocating new blob size=%d\n" , required_blob_size); blob =ceph_buffer_new (required_blob_size,GFP_NOFS );if (!blob) goto do_sync_unlocked;spin_lock (&ci->i_ceph_lock); +/* prealloc_blob can't be released while holding i_ceph_lock */ if (ci->i_xattrs.prealloc_blob) -ceph_buffer_put (ci->i_xattrs.prealloc_blob); + old_blob = ci->i_xattrs.prealloc_blob; ci->i_xattrs.prealloc_blob = blob; goto retry; }
@@ -1045,6 +1048,7 @@ retry: }spin_unlock (&ci->i_ceph_lock); +ceph_buffer_put (old_blob);if (lock_snap_rwsem)up_read (&mdsc->snap_rwsem);if (dirty)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 25/40 ceph: fix buffer free while holding i_ceph_lock in __ceph_build_xattrs_blob()
In reply to Greg Kroah-Hartman[ Upstream commit 12fe3dda7ed89c95cc0ef7abc001ad1ad3e092f8 ]
Calling ceph_buffer_put() in __ceph_build_xattrs_blob() may result in freeing the i_xattrs.blob buffer while holding the i_ceph_lock. This can be fixed by having this function returning the old blob buffer and have the callers of this function freeing it when the lock is released.
The following backtrace was triggered by fstests generic/117.
BUG: sleeping function called from invalid context at mm/vmalloc.c:2283
in_atomic(): 1, irqs_disabled(): 0, pid: 649, name: fsstress
4 locks held by fsstress/649:
#0: 00000000a7478e7e (&type->s_umount_key#19){++++}, at: iterate_supers+0x77/0xf0
#1: 00000000f8de1423 (&(&ci->i_ceph_lock)->rlock){+.+.}, at: ceph_check_caps+0x7b/0xc60
#2: 00000000562f2b27 (&s->s_mutex){+.+.}, at: ceph_check_caps+0x3bd/0xc60
#3: 00000000f83ce16a (&mdsc->snap_rwsem){++++}, at: ceph_check_caps+0x3ed/0xc60
CPU: 1 PID: 649 Comm: fsstress Not tainted 5.2.0+ #439
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58-prebuilt.qemu.org 04/01/2014
Call Trace:
dump_stack+0x67/0x90
___might_sleep.cold+0x9f/0xb1
vfree+0x4b/0x60
ceph_buffer_release+0x1b/0x60
__ceph_build_xattrs_blob+0x12b/0x170
__send_cap+0x302/0x540
? __lock_acquire+0x23c/0x1e40
? __mark_caps_flushing+0x15c/0x280
? _raw_spin_unlock+0x24/0x30
ceph_check_caps+0x5f0/0xc60
ceph_flush_dirty_caps+0x7c/0x150
? __ia32_sys_fdatasync+0x20/0x20
ceph_sync_fs+0x5a/0x130
iterate_supers+0x8f/0xf0
ksys_sync+0x4f/0xb0
__ia32_sys_sync+0xa/0x10
do_syscall_64+0x50/0x1c0
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x7fc6409ab617--- fs/ceph/caps.c | 5 ++++- fs/ceph/snap.c | 4 +++- fs/ceph/super.h | 2 +- fs/ceph/xattr.c | 11 ++++++++--- 4 files changed, 16 insertions(+), 6 deletions(-)
fs/ceph/caps.c +4 -1
@@ -1162,6 +1162,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, {struct ceph_inode_info *ci = cap->ci;struct inode *inode = &ci->vfs_inode; +struct ceph_buffer *old_blob =NULL ;struct cap_msg_args arg;int held, revoking, dropping;int wake =0 ;
@@ -1227,7 +1228,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, ci->i_requested_max_size = arg.max_size;if (flushing &CEPH_CAP_XATTR_EXCL ) { -__ceph_build_xattrs_blob (ci); + old_blob =__ceph_build_xattrs_blob (ci); arg.xattr_version = ci->i_xattrs.version; arg.xattr_buf = ci->i_xattrs.blob; }else {
@@ -1262,6 +1263,8 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,spin_unlock (&ci->i_ceph_lock); +ceph_buffer_put (old_blob); + ret =send_cap_msg (&arg);if (ret <0 ) {dout ("error sending cap msg, must requeue %p\n" , inode);
fs/ceph/snap.c +3 -1
@@ -460,6 +460,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci)struct inode *inode = &ci->vfs_inode;struct ceph_cap_snap *capsnap;struct ceph_snap_context *old_snapc, *new_snapc; +struct ceph_buffer *old_blob =NULL ;int used, dirty; capsnap =kzalloc (sizeof (*capsnap),GFP_NOFS );
@@ -536,7 +537,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) capsnap->gid = inode->i_gid;if (dirty &CEPH_CAP_XATTR_EXCL ) { -__ceph_build_xattrs_blob (ci); + old_blob =__ceph_build_xattrs_blob (ci); capsnap->xattr_blob =ceph_buffer_get (ci->i_xattrs.blob); capsnap->xattr_version = ci->i_xattrs.version;
@@ -579,6 +580,7 @@ update_snapc: }spin_unlock (&ci->i_ceph_lock); +ceph_buffer_put (old_blob);kfree (capsnap);ceph_put_snap_context (old_snapc); }
fs/ceph/super.h +1 -1
@@ -835,7 +835,7 @@ extern int ceph_getattr(const struct path *path, struct kstat *stat,int __ceph_setxattr (struct inode *,const char *,const void *,size_t ,int );ssize_t __ceph_getxattr (struct inode *,const char *,void *,size_t );extern ssize_t ceph_listxattr (struct dentry *,char *,size_t ); -extern void __ceph_build_xattrs_blob (struct ceph_inode_info *ci); +extern struct ceph_buffer *__ceph_build_xattrs_blob (struct ceph_inode_info *ci);extern void __ceph_destroy_xattrs (struct ceph_inode_info *ci);extern void __init ceph_xattr_init (void );extern void ceph_xattr_exit (void );
fs/ceph/xattr.c +8 -3
@@ -681,12 +681,15 @@ static int __get_required_blob_size(struct ceph_inode_info *ci, int name_size,/* * If there are dirty xattrs, reencode xattrs into the prealloc_blob -* and swap into place. +* and swap into place. It returns the old i_xattrs.blob (or NULL) so +* that it can be freed by the caller as the i_ceph_lock is likely to be +* held. */ -void __ceph_build_xattrs_blob (struct ceph_inode_info *ci) +struct ceph_buffer *__ceph_build_xattrs_blob (struct ceph_inode_info *ci) {struct rb_node *p;struct ceph_inode_xattr *xattr =NULL ; +struct ceph_buffer *old_blob =NULL ;void *dest;dout ("__build_xattrs_blob %p\n" , &ci->vfs_inode);
@@ -717,12 +720,14 @@ void __ceph_build_xattrs_blob(struct ceph_inode_info *ci) dest - ci->i_xattrs.prealloc_blob->vec.iov_base;if (ci->i_xattrs.blob) -ceph_buffer_put (ci->i_xattrs.blob); + old_blob = ci->i_xattrs.blob; ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; ci->i_xattrs.prealloc_blob =NULL ; ci->i_xattrs.dirty = false; ci->i_xattrs.version++; } + +return old_blob; }static inline int __get_request_mask (struct inode *in) {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 26/40 ceph: fix buffer free while holding i_ceph_lock in fill_inode()
In reply to Greg Kroah-Hartman[ Upstream commit af8a85a41734f37b67ba8ce69d56b685bee4ac48 ]
Calling ceph_buffer_put() in fill_inode() may result in freeing the i_xattrs.blob buffer while holding the i_ceph_lock. This can be fixed by postponing the call until later, when the lock is released.
The following backtrace was triggered by fstests generic/070.
BUG: sleeping function called from invalid context at mm/vmalloc.c:2283
in_atomic(): 1, irqs_disabled(): 0, pid: 3852, name: kworker/0:4
6 locks held by kworker/0:4/3852:
#0: 000000004270f6bb ((wq_completion)ceph-msgr){+.+.}, at: process_one_work+0x1b8/0x5f0
#1: 00000000eb420803 ((work_completion)(&(&con->work)->work)){+.+.}, at: process_one_work+0x1b8/0x5f0
#2: 00000000be1c53a4 (&s->s_mutex){+.+.}, at: dispatch+0x288/0x1476
#3: 00000000559cb958 (&mdsc->snap_rwsem){++++}, at: dispatch+0x2eb/0x1476
#4: 000000000d5ebbae (&req->r_fill_mutex){+.+.}, at: dispatch+0x2fc/0x1476
#5: 00000000a83d0514 (&(&ci->i_ceph_lock)->rlock){+.+.}, at: fill_inode.isra.0+0xf8/0xf70
CPU: 0 PID: 3852 Comm: kworker/0:4 Not tainted 5.2.0+ #441
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58-prebuilt.qemu.org 04/01/2014
Workqueue: ceph-msgr ceph_con_workfn
Call Trace:
dump_stack+0x67/0x90
___might_sleep.cold+0x9f/0xb1
vfree+0x4b/0x60
ceph_buffer_release+0x1b/0x60
fill_inode.isra.0+0xa9b/0xf70
ceph_fill_trace+0x13b/0xc70
? dispatch+0x2eb/0x1476
dispatch+0x320/0x1476
? __mutex_unlock_slowpath+0x4d/0x2a0
ceph_con_workfn+0xc97/0x2ec0
? process_one_work+0x1b8/0x5f0
process_one_work+0x244/0x5f0
worker_thread+0x4d/0x3e0
kthread+0x105/0x140
? process_one_work+0x5f0/0x5f0
? kthread_park+0x90/0x90
ret_from_fork+0x3a/0x50--- fs/ceph/inode.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/ceph/inode.c +4 -3
@@ -730,6 +730,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page,int issued =0 , implemented, new_issued;struct timespec mtime, atime, ctime;struct ceph_buffer *xattr_blob =NULL ; +struct ceph_buffer *old_blob =NULL ;struct ceph_string *pool_ns =NULL ;struct ceph_cap *new_cap =NULL ;int err =0 ;
@@ -847,7 +848,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page,if ((ci->i_xattrs.version ==0 || !(issued &CEPH_CAP_XATTR_EXCL )) &&le64_to_cpu (info->xattr_version) > ci->i_xattrs.version) {if (ci->i_xattrs.blob) -ceph_buffer_put (ci->i_xattrs.blob); + old_blob = ci->i_xattrs.blob; ci->i_xattrs.blob = xattr_blob;if (xattr_blob) memcpy(ci->i_xattrs.blob->vec.iov_base,
@@ -993,8 +994,8 @@ static int fill_inode(struct inode *inode, struct page *locked_page, out:if (new_cap)ceph_put_cap (mdsc, new_cap); -if (xattr_blob) -ceph_buffer_put (xattr_blob); +ceph_buffer_put (old_blob); +ceph_buffer_put (xattr_blob);ceph_put_string (pool_ns);return err; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 27/40 KVM: arm/arm64: Only skip MMIO insn once
In reply to Greg Kroah-Hartman[ Upstream commit 2113c5f62b7423e4a72b890bd479704aa85c81ba ]
If after an MMIO exit to userspace a VCPU is immediately run with an immediate_exit request, such as when a signal is delivered or an MMIO emulation completion is needed, then the VCPU completes the MMIO emulation and immediately returns to userspace. As the exit_reason does not get changed from KVM_EXIT_MMIO in these cases we have to be careful not to complete the MMIO emulation again, when the VCPU is eventually run again, because the emulation does an instruction skip (and doing too many skips would be a waste of guest code :-) We need to use additional VCPU state to track if the emulation is complete. As luck would have it, we already have 'mmio_needed', which even appears to be used in this way by other architectures already.
--- virt/kvm/arm/mmio.c | 7 +++++++ 1 file changed, 7 insertions(+)
virt/kvm/arm/mmio.c +7 -0
@@ -98,6 +98,12 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run)unsigned int len;int mask; +/* Detect an already handled MMIO return */ +if (unlikely (!vcpu->mmio_needed)) +return 0 ; + + vcpu->mmio_needed =0 ; +if (!run->mmio.is_write) { len = run->mmio.len;if (len >sizeof (unsigned long ))
@@ -200,6 +206,7 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, run->mmio.is_write = is_write; run->mmio.phys_addr = fault_ipa; run->mmio.len = len; + vcpu->mmio_needed =1 ;if (!ret) {/* We handled the access successfully in the kernel. */
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 28/40 libceph: allow ceph_buffer_put() to receive a NULL ceph_buffer
In reply to Greg Kroah-Hartman[ Upstream commit 5c498950f730aa17c5f8a2cdcb903524e4002ed2 ]
--- include/linux/ceph/buffer.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
include/linux/ceph/buffer.h +2 -1
@@ -30,7 +30,8 @@ static inline struct ceph_buffer *ceph_buffer_get(struct ceph_buffer *b)static inline void ceph_buffer_put (struct ceph_buffer *b) { -kref_put (&b->kref, ceph_buffer_release); +if (b) +kref_put (&b->kref, ceph_buffer_release); }extern int ceph_decode_buffer (struct ceph_buffer **b,void **p,void *end);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 29/40 spi: bcm2835aux: unifying code between polling and interrupt driven code
In reply to Greg Kroah-Hartman[ Upstream commit 7188a6f0eee3f1fae5d826cfc6d569657ff950ec ]
Sharing more code between polling and interrupt-driven mode.
--- drivers/spi/spi-bcm2835aux.c | 51 +++++++++++++----------------------- 1 file changed, 18 insertions(+), 33 deletions(-)
drivers/spi/spi-bcm2835aux.c +18 -33
@@ -178,23 +178,13 @@ static void bcm2835aux_spi_reset_hw(struct bcm2835aux_spi *bs) BCM2835_AUX_SPI_CNTL0_CLEARFIFO); } -static irqreturn_t bcm2835aux_spi_interrupt (int irq,void *dev_id) +static void bcm2835aux_spi_transfer_helper (struct bcm2835aux_spi *bs) { -struct spi_master *master = dev_id; -struct bcm2835aux_spi *bs =spi_master_get_devdata (master); -irqreturn_t ret =IRQ_NONE ; - -/* IRQ may be shared, so return if our interrupts are disabled */ -if (!(bcm2835aux_rd (bs,BCM2835_AUX_SPI_CNTL1 ) & - (BCM2835_AUX_SPI_CNTL1_TXEMPTY |BCM2835_AUX_SPI_CNTL1_IDLE ))) -return ret; -/* check if we have data to read */ while (bs->rx_len && (!(bcm2835aux_rd (bs,BCM2835_AUX_SPI_STAT ) &BCM2835_AUX_SPI_STAT_RX_EMPTY ))) {bcm2835aux_rd_fifo (bs); - ret =IRQ_HANDLED ; }/* check if we have data to write */
@@ -203,7 +193,6 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id) (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & BCM2835_AUX_SPI_STAT_TX_FULL))) {bcm2835aux_wr_fifo (bs); - ret =IRQ_HANDLED ; }/* and check if we have reached "done" */
@@ -211,8 +200,21 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id) (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & BCM2835_AUX_SPI_STAT_BUSY))) {bcm2835aux_rd_fifo (bs); - ret =IRQ_HANDLED ; } +} + +static irqreturn_t bcm2835aux_spi_interrupt (int irq,void *dev_id) +{ +struct spi_master *master = dev_id; +struct bcm2835aux_spi *bs =spi_master_get_devdata (master); + +/* IRQ may be shared, so return if our interrupts are disabled */ +if (!(bcm2835aux_rd (bs,BCM2835_AUX_SPI_CNTL1 ) & + (BCM2835_AUX_SPI_CNTL1_TXEMPTY |BCM2835_AUX_SPI_CNTL1_IDLE ))) +return IRQ_NONE ; + +/* do common fifo handling */ +bcm2835aux_spi_transfer_helper (bs);if (!bs->tx_len) {/* disable tx fifo empty interrupt */
@@ -226,8 +228,7 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)complete (&master->xfer_completion); } -/* and return */ -return ret; +return IRQ_HANDLED ; } static int __bcm2835aux_spi_transfer_one_irq(struct spi_master *master,
@@ -273,7 +274,6 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master, {struct bcm2835aux_spi *bs =spi_master_get_devdata (master);unsigned long timeout; -u32 stat;/* configure spi */ bcm2835aux_wr (bs,BCM2835_AUX_SPI_CNTL1 , bs->cntl[1 ]);
@@ -284,24 +284,9 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master,/* loop until finished the transfer */ while (bs->rx_len) { -/* read status */ - stat =bcm2835aux_rd (bs,BCM2835_AUX_SPI_STAT ); - -/* fill in tx fifo with remaining data */ -if ((bs->tx_len) && (!(stat &BCM2835_AUX_SPI_STAT_TX_FULL ))) { -bcm2835aux_wr_fifo (bs); -continue ; - } -/* read data from fifo for both cases */ -if (!(stat &BCM2835_AUX_SPI_STAT_RX_EMPTY )) { -bcm2835aux_rd_fifo (bs); -continue ; - } -if (!(stat &BCM2835_AUX_SPI_STAT_BUSY )) { -bcm2835aux_rd_fifo (bs); -continue ; - } +/* do common fifo handling */ +bcm2835aux_spi_transfer_helper (bs);/* there is still data pending to read check the timeout */ if (bs->rx_len &&time_after (jiffies, timeout)) {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 30/40 spi: bcm2835aux: remove dangerous uncontrolled read of fifo
In reply to Greg Kroah-Hartman[ Upstream commit c7de8500fd8ecbb544846dd5f11dca578c3777e1 ]
This read of the fifo is a potential candidate for a race condition as the spi transfer is not necessarily finished and so can lead to an early read of the fifo that still misses data.
So it has been removed.
--- drivers/spi/spi-bcm2835aux.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/spi/spi-bcm2835aux.c +0 -7
@@ -194,13 +194,6 @@ static void bcm2835aux_spi_transfer_helper(struct bcm2835aux_spi *bs) BCM2835_AUX_SPI_STAT_TX_FULL))) {bcm2835aux_wr_fifo (bs); } - -/* and check if we have reached "done" */ -while (bs->rx_len && - (!(bcm2835aux_rd (bs,BCM2835_AUX_SPI_STAT ) & -BCM2835_AUX_SPI_STAT_BUSY ))) { -bcm2835aux_rd_fifo (bs); - } }static irqreturn_t bcm2835aux_spi_interrupt (int irq,void *dev_id)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 31/40 spi: bcm2835aux: fix corruptions for longer spi transfers
In reply to Greg Kroah-Hartman[ Upstream commit 73b114ee7db1750c0b535199fae383b109bd61d0 ]
On long running tests with a mcp2517fd can controller it showed that on rare occations the data read shows corruptions for longer spi transfers.
Example of a 22 byte transfer:
expected (as captured on logic analyzer):
FF FF 78 00 00 00 08 06 00 00 91 20 77 56 84 85 86 87 88 89 8a 8b
read by the driver:
FF FF 78 00 00 00 08 06 00 00 91 20 77 56 84 88 89 8a 00 00 8b 9b
To fix this use BCM2835_AUX_SPI_STAT_RX_LVL to determine when we may read data from the fifo reliably without any corruption.
Surprisingly the only values ever empirically read in BCM2835_AUX_SPI_STAT_RX_LVL are 0x00, 0x10, 0x20 and 0x30.
So whenever the mask is not 0 we can read from the fifo in a safe manner.
The patch has now been tested intensively and we are no longer able to reproduce the "RX" issue any longer.
--- drivers/spi/spi-bcm2835aux.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/spi/spi-bcm2835aux.c +4 -4
@@ -180,12 +180,12 @@ static void bcm2835aux_spi_reset_hw(struct bcm2835aux_spi *bs)static void bcm2835aux_spi_transfer_helper (struct bcm2835aux_spi *bs) { +u32 stat =bcm2835aux_rd (bs,BCM2835_AUX_SPI_STAT ); +/* check if we have data to read */ -while (bs->rx_len && - (!(bcm2835aux_rd (bs,BCM2835_AUX_SPI_STAT ) & -BCM2835_AUX_SPI_STAT_RX_EMPTY ))) { +for (; bs->rx_len && (stat &BCM2835_AUX_SPI_STAT_RX_LVL ); + stat =bcm2835aux_rd (bs,BCM2835_AUX_SPI_STAT ))bcm2835aux_rd_fifo (bs); - }/* check if we have data to write */ while (bs->tx_len &&
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 32/40 Revert "x86/apic: Include the LDR when clearing out APIC registers"
In reply to Greg Kroah-Hartman[ Upstream commit 950b07c14e8c59444e2359f15fd70ed5112e11a0 ]
This reverts commit 558682b5291937a70748d36fd9ba757fb25b99ae.
Chris Wilson reports that it breaks his CPU hotplug test scripts. In particular, it breaks offlining and then re-onlining the boot CPU, which we treat specially (and the BIOS does too).
The symptoms are that we can offline the CPU, but it then does not come back online again:
smpboot: CPU 0 is now offline
smpboot: Booting Node 0 Processor 0 APIC 0x0
smpboot: do_boot_cpu failed(-1) to wakeup CPU#0
Thomas says he knows why it's broken (my personal suspicion: our magic handling of the "cpu0_logical_apicid" thing), but for 5.3 the right fix is to just revert it, since we've never touched the LDR bits before, and it's not worth the risk to do anything else at this stage.
[ Hotpluging of the boot CPU is special anyway, and should be off by
default. See the "BOOTPARAM_HOTPLUG_CPU0" config option and the cpu0_hotplug kernel parameter.
In general you should not do it, and it has various known limitations (hibernate and suspend require the boot CPU, for example).
But it should work, even if the boot CPU is special and needs careful
treatment - Linus ]
--- arch/x86/kernel/apic/apic.c | 4 ---- 1 file changed, 4 deletions(-)
arch/x86/kernel/apic/apic.c +0 -4
@@ -1148,10 +1148,6 @@ void clear_local_APIC(void)apic_write (APIC_LVT0 , v |APIC_LVT_MASKED ); v =apic_read (APIC_LVT1 );apic_write (APIC_LVT1 , v |APIC_LVT_MASKED ); -if (!x2apic_enabled ()) { - v =apic_read (APIC_LDR ) & ~APIC_LDR_MASK ; -apic_write (APIC_LDR , v); - }if (maxlvt >=4 ) { v =apic_read (APIC_LVTPC );apic_write (APIC_LVTPC , v |APIC_LVT_MASKED );
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 33/40 net: fix skb use after free in netpoll
In reply to Greg Kroah-HartmanFrom: Feng Sun <[email protected]>
[ Upstream commit 2c1644cf6d46a8267d79ed95cb9b563839346562 ]
After commit baeababb5b85d5c4e6c917efe2a1504179438d3b
("tun: return NET_XMIT_DROP for dropped packets"),
when tun_net_xmit drop packets, it will free skb and return NET_XMIT_DROP, netpoll_send_skb_on_dev will run into following use after free cases:
1. retry netpoll_start_xmit with freed skb;
2. queue freed skb in npinfo->txq.queue_process will also run into use after free case.
hit netpoll_send_skb_on_dev first case with following kernel log:
[ 117.864773] kernel BUG at mm/slub.c:306! [ 117.864773] invalid opcode: 0000 [#1] SMP PTI [ 117.864774] CPU: 3 PID: 2627 Comm: loop_printmsg Kdump: loaded Tainted: P OE 5.3.0-050300rc5-generic #201908182231 [ 117.864775] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 [ 117.864775] RIP: 0010:kmem_cache_free+0x28d/0x2b0 [ 117.864781] Call Trace: [ 117.864781] ? tun_net_xmit+0x21c/0x460 [ 117.864781] kfree_skbmem+0x4e/0x60 [ 117.864782] kfree_skb+0x3a/0xa0 [ 117.864782] tun_net_xmit+0x21c/0x460 [ 117.864782] netpoll_start_xmit+0x11d/0x1b0 [ 117.864788] netpoll_send_skb_on_dev+0x1b8/0x200 [ 117.864789] __br_forward+0x1b9/0x1e0 [bridge] [ 117.864789] ? skb_clone+0x53/0xd0 [ 117.864790] ? __skb_clone+0x2e/0x120 [ 117.864790] deliver_clone+0x37/0x50 [bridge] [ 117.864790] maybe_deliver+0x89/0xc0 [bridge] [ 117.864791] br_flood+0x6c/0x130 [bridge] [ 117.864791] br_dev_xmit+0x315/0x3c0 [bridge] [ 117.864792] netpoll_start_xmit+0x11d/0x1b0 [ 117.864792] netpoll_send_skb_on_dev+0x1b8/0x200 [ 117.864792] netpoll_send_udp+0x2c6/0x3e8 [ 117.864793] write_msg+0xd9/0xf0 [netconsole] [ 117.864793] console_unlock+0x386/0x4e0 [ 117.864793] vprintk_emit+0x17e/0x280 [ 117.864794] vprintk_default+0x29/0x50 [ 117.864794] vprintk_func+0x4c/0xbc [ 117.864794] printk+0x58/0x6f [ 117.864795] loop_fun+0x24/0x41 [printmsg_loop] [ 117.864795] kthread+0x104/0x140 [ 117.864795] ? 0xffffffffc05b1000 [ 117.864796] ? kthread_park+0x80/0x80 [ 117.864796] ret_from_fork+0x35/0x40
--- net/core/netpoll.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/core/netpoll.c +3 -3
@@ -122,7 +122,7 @@ static void queue_process(struct work_st txq =netdev_get_tx_queue (dev, q_index);HARD_TX_LOCK (dev, txq,smp_processor_id ());if (netif_xmit_frozen_or_stopped (txq) || -netpoll_start_xmit (skb, dev, txq) !=NETDEV_TX_OK ) { + !dev_xmit_complete (netpoll_start_xmit (skb, dev, txq))) {skb_queue_head (&npinfo->txq, skb);HARD_TX_UNLOCK (dev, txq);local_irq_restore (flags);
@@ -357,7 +357,7 @@ void netpoll_send_skb_on_dev(struct netpHARD_TX_UNLOCK (dev, txq); -if (status ==NETDEV_TX_OK ) +if (dev_xmit_complete (status))break ; }
@@ -374,7 +374,7 @@ void netpoll_send_skb_on_dev(struct netp } -if (status !=NETDEV_TX_OK ) { +if (!dev_xmit_complete (status)) {skb_queue_tail (&npinfo->txq, skb);schedule_delayed_work (&npinfo->tx_work,0 ); }
Greg Kroah-Hartman
maintainerPATCH 34/40 net_sched: fix a NULL pointer deref in ipt action
In reply to Greg Kroah-HartmanFrom: Cong Wang <[email protected]>
[ Upstream commit 981471bd3abf4d572097645d765391533aac327d ]
The net pointer in struct xt_tgdtor_param is not explicitly initialized therefore is still NULL when dereferencing it. So we have to find a way to pass the correct net pointer to ipt_destroy_target().
The best way I find is just saving the net pointer inside the per netns struct tcf_idrinfo, which could make this patch smaller.
--- include/net/act_api.h | 4 +++- net/sched/act_bpf.c | 2 +- net/sched/act_connmark.c | 2 +- net/sched/act_csum.c | 2 +- net/sched/act_gact.c | 2 +- net/sched/act_ife.c | 2 +- net/sched/act_ipt.c | 11 ++++++----- net/sched/act_mirred.c | 2 +- net/sched/act_nat.c | 2 +- net/sched/act_pedit.c | 2 +- net/sched/act_police.c | 2 +- net/sched/act_sample.c | 2 +- net/sched/act_simple.c | 2 +- net/sched/act_skbedit.c | 2 +- net/sched/act_skbmod.c | 2 +- net/sched/act_tunnel_key.c | 2 +- net/sched/act_vlan.c | 2 +- 17 files changed, 24 insertions(+), 21 deletions(-)
include/net/act_api.h +3 -1
@@ -14,6 +14,7 @@struct tcf_idrinfo {spinlock_t lock;struct idr action_idr; +struct net *net; };struct tc_action_ops ;
@@ -104,7 +105,7 @@ struct tc_action_net { };static inline -int tc_action_net_init (struct tc_action_net *tn, +int tc_action_net_init (struct net *net,struct tc_action_net *tn,const struct tc_action_ops *ops) {int err =0 ;
@@ -113,6 +114,7 @@ int tc_action_net_init(struct tc_action_if (!tn->idrinfo)return -ENOMEM ; tn->ops = ops; + tn->idrinfo->net = net;spin_lock_init (&tn->idrinfo->lock);idr_init (&tn->idrinfo->action_idr);return err;
net/sched/act_bpf.c +1 -1
@@ -402,7 +402,7 @@ static __net_init int bpf_init_net(struc {struct tc_action_net *tn =net_generic (net, bpf_net_id); -return tc_action_net_init (tn, &act_bpf_ops); +return tc_action_net_init (net, tn, &act_bpf_ops); } static void __net_exit bpf_exit_net(struct net *net)
net/sched/act_connmark.c +1 -1
@@ -206,7 +206,7 @@ static __net_init int connmark_init_net( {struct tc_action_net *tn =net_generic (net, connmark_net_id); -return tc_action_net_init (tn, &act_connmark_ops); +return tc_action_net_init (net, tn, &act_connmark_ops); } static void __net_exit connmark_exit_net(struct net *net)
net/sched/act_csum.c +1 -1
@@ -632,7 +632,7 @@ static __net_init int csum_init_net(stru {struct tc_action_net *tn =net_generic (net, csum_net_id); -return tc_action_net_init (tn, &act_csum_ops); +return tc_action_net_init (net, tn, &act_csum_ops); } static void __net_exit csum_exit_net(struct net *net)
net/sched/act_gact.c +1 -1
@@ -232,7 +232,7 @@ static __net_init int gact_init_net(stru {struct tc_action_net *tn =net_generic (net, gact_net_id); -return tc_action_net_init (tn, &act_gact_ops); +return tc_action_net_init (net, tn, &act_gact_ops); } static void __net_exit gact_exit_net(struct net *net)
net/sched/act_ife.c +1 -1
@@ -837,7 +837,7 @@ static __net_init int ife_init_net(struc {struct tc_action_net *tn =net_generic (net, ife_net_id); -return tc_action_net_init (tn, &act_ife_ops); +return tc_action_net_init (net, tn, &act_ife_ops); } static void __net_exit ife_exit_net(struct net *net)
net/sched/act_ipt.c +6 -5
@@ -65,12 +65,13 @@ static int ipt_init_target(struct net *nreturn 0 ; } -static void ipt_destroy_target (struct xt_entry_target *t) +static void ipt_destroy_target (struct xt_entry_target *t,struct net *net) {struct xt_tgdtor_param par = { .target = t->u.kernel.target, .targinfo = t->data, .family =NFPROTO_IPV4 , + .net = net, };if (par.target->destroy !=NULL ) par.target->destroy (&par);
@@ -82,7 +83,7 @@ static void tcf_ipt_release(struct tc_acstruct tcf_ipt *ipt =to_ipt (a);if (ipt->tcfi_t) { -ipt_destroy_target (ipt->tcfi_t); +ipt_destroy_target (ipt->tcfi_t, a->idrinfo->net);kfree (ipt->tcfi_t); }kfree (ipt->tcfi_tname);
@@ -172,7 +173,7 @@ static int __tcf_ipt_init(struct net *nespin_lock_bh (&ipt->tcf_lock);if (ret !=ACT_P_CREATED ) { -ipt_destroy_target (ipt->tcfi_t); +ipt_destroy_target (ipt->tcfi_t, net);kfree (ipt->tcfi_tname);kfree (ipt->tcfi_t); }
@@ -337,7 +338,7 @@ static __net_init int ipt_init_net(struc {struct tc_action_net *tn =net_generic (net, ipt_net_id); -return tc_action_net_init (tn, &act_ipt_ops); +return tc_action_net_init (net, tn, &act_ipt_ops); } static void __net_exit ipt_exit_net(struct net *net)
@@ -387,7 +388,7 @@ static __net_init int xt_init_net(struct {struct tc_action_net *tn =net_generic (net, xt_net_id); -return tc_action_net_init (tn, &act_xt_ops); +return tc_action_net_init (net, tn, &act_xt_ops); } static void __net_exit xt_exit_net(struct net *net)
net/sched/act_mirred.c +1 -1
@@ -343,7 +343,7 @@ static __net_init int mirred_init_net(st {struct tc_action_net *tn =net_generic (net, mirred_net_id); -return tc_action_net_init (tn, &act_mirred_ops); +return tc_action_net_init (net, tn, &act_mirred_ops); } static void __net_exit mirred_exit_net(struct net *net)
net/sched/act_nat.c +1 -1
@@ -307,7 +307,7 @@ static __net_init int nat_init_net(struc {struct tc_action_net *tn =net_generic (net, nat_net_id); -return tc_action_net_init (tn, &act_nat_ops); +return tc_action_net_init (net, tn, &act_nat_ops); } static void __net_exit nat_exit_net(struct net *net)
net/sched/act_pedit.c +1 -1
@@ -458,7 +458,7 @@ static __net_init int pedit_init_net(str {struct tc_action_net *tn =net_generic (net, pedit_net_id); -return tc_action_net_init (tn, &act_pedit_ops); +return tc_action_net_init (net, tn, &act_pedit_ops); } static void __net_exit pedit_exit_net(struct net *net)
net/sched/act_police.c +1 -1
@@ -331,7 +331,7 @@ static __net_init int police_init_net(st {struct tc_action_net *tn =net_generic (net, police_net_id); -return tc_action_net_init (tn, &act_police_ops); +return tc_action_net_init (net, tn, &act_police_ops); } static void __net_exit police_exit_net(struct net *net)
net/sched/act_sample.c +1 -1
@@ -249,7 +249,7 @@ static __net_init int sample_init_net(st {struct tc_action_net *tn =net_generic (net, sample_net_id); -return tc_action_net_init (tn, &act_sample_ops); +return tc_action_net_init (net, tn, &act_sample_ops); } static void __net_exit sample_exit_net(struct net *net)
net/sched/act_simple.c +1 -1
@@ -198,7 +198,7 @@ static __net_init int simp_init_net(stru {struct tc_action_net *tn =net_generic (net, simp_net_id); -return tc_action_net_init (tn, &act_simp_ops); +return tc_action_net_init (net, tn, &act_simp_ops); } static void __net_exit simp_exit_net(struct net *net)
net/sched/act_skbedit.c +1 -1
@@ -239,7 +239,7 @@ static __net_init int skbedit_init_net(s {struct tc_action_net *tn =net_generic (net, skbedit_net_id); -return tc_action_net_init (tn, &act_skbedit_ops); +return tc_action_net_init (net, tn, &act_skbedit_ops); } static void __net_exit skbedit_exit_net(struct net *net)
net/sched/act_skbmod.c +1 -1
@@ -267,7 +267,7 @@ static __net_init int skbmod_init_net(st {struct tc_action_net *tn =net_generic (net, skbmod_net_id); -return tc_action_net_init (tn, &act_skbmod_ops); +return tc_action_net_init (net, tn, &act_skbmod_ops); } static void __net_exit skbmod_exit_net(struct net *net)
net/sched/act_tunnel_key.c +1 -1
@@ -324,7 +324,7 @@ static __net_init int tunnel_key_init_ne {struct tc_action_net *tn =net_generic (net, tunnel_key_net_id); -return tc_action_net_init (tn, &act_tunnel_key_ops); +return tc_action_net_init (net, tn, &act_tunnel_key_ops); } static void __net_exit tunnel_key_exit_net(struct net *net)
net/sched/act_vlan.c +1 -1
@@ -271,7 +271,7 @@ static __net_init int vlan_init_net(stru {struct tc_action_net *tn =net_generic (net, vlan_net_id); -return tc_action_net_init (tn, &act_vlan_ops); +return tc_action_net_init (net, tn, &act_vlan_ops); } static void __net_exit vlan_exit_net(struct net *net)
Greg Kroah-Hartman
maintainerPATCH 35/40 net: stmmac: dwmac-rk: Dont fail if phy regulator is absent
In reply to Greg Kroah-HartmanFrom: Chen-Yu Tsai <[email protected]>
[ Upstream commit 3b25528e1e355c803e73aa326ce657b5606cda73 ]
The devicetree binding lists the phy phy as optional. As such, the driver should not bail out if it can't find a regulator. Instead it should just skip the remaining regulator related code and continue on normally.
Skip the remainder of phy_power_on() if a regulator supply isn't available. This also gets rid of the bogus return code.
--- drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +2 -4
@@ -1145,10 +1145,8 @@ static int phy_power_on(struct rk_priv_dint ret;struct device *dev = &bsp_priv->pdev->dev; -if (!ldo) { -dev_err (dev,"no regulator found\n" ); -return -1 ; - } +if (!ldo) +return 0 ;if (enable) { ret =regulator_enable (ldo);
Greg Kroah-Hartman
maintainerPATCH 36/40 tcp: inherit timestamp on mtu probe
In reply to Greg Kroah-HartmanFrom: Willem de Bruijn <[email protected]>
[ Upstream commit 888a5c53c0d8be6e98bc85b677f179f77a647873 ]
TCP associates tx timestamp requests with a byte in the bytestream. If merging skbs in tcp_mtu_probe, migrate the tstamp request.
Similar to MSG_EOR, do not allow moving a timestamp from any segment in the probe but the last. This to avoid merging multiple timestamps.
Tested with the packetdrill script at
https://github.com/wdebruij/packetdrill/commits/mtu_probe-1
--- net/ipv4/tcp_output.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv4/tcp_output.c +2 -1
@@ -2025,7 +2025,7 @@ static bool tcp_can_coalesce_send_queue_if (len <= skb->len)break ; -if (unlikely (TCP_SKB_CB (skb)->eor)) +if (unlikely (TCP_SKB_CB (skb)->eor) ||tcp_has_tx_tstamp (skb))return false; len -= skb->len;
@@ -2148,6 +2148,7 @@ static int tcp_mtu_probe(struct sock *sk* we need to propagate it to the new skb. */ TCP_SKB_CB (nskb)->eor =TCP_SKB_CB (skb)->eor; +tcp_skb_collapse_tstamp (nskb, skb);tcp_unlink_write_queue (skb, sk);sk_wmem_free_skb (sk, skb); }else {
Greg Kroah-Hartman
maintainerPATCH 37/40 tcp: remove empty skb from write queue in error cases
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit fdfc5c8594c24c5df883583ebd286321a80e0a67 ]
Vladimir Rutsky reported stuck TCP sessions after memory pressure events. Edge Trigger epoll() user would never receive an EPOLLOUT notification allowing them to retry a sendmsg().
Jason tested the case of sk_stream_alloc_skb() returning NULL, but there are other paths that could lead both sendmsg() and sendpage() to return -1 (EAGAIN), with an empty skb queued on the write queue.
This patch makes sure we remove this empty skb so that Jason code can detect that the queue is empty, and call sk->sk_write_space(sk) accordingly.
--- net/ipv4/tcp.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-)
net/ipv4/tcp.c +20 -9
@@ -914,6 +914,22 @@ static int tcp_send_mss(struct sock *sk,return mss_now; } +/* In some cases, both sendpage() and sendmsg() could have added +* an skb to the write queue, but failed adding payload on it. +* We need to remove it to consume less memory, but more +* importantly be able to generate EPOLLOUT for Edge Trigger epoll() +* users. +*/ +static void tcp_remove_empty_skb (struct sock *sk,struct sk_buff *skb) +{ +if (skb && !skb->len) { +tcp_unlink_write_queue (skb, sk); +if (tcp_write_queue_empty (sk)) +tcp_chrono_stop (sk,TCP_CHRONO_BUSY ); +sk_wmem_free_skb (sk, skb); + } +} +ssize_t do_tcp_sendpages (struct sock *sk,struct page *page,int offset,size_t size,int flags) {
@@ -1034,6 +1050,7 @@ out:return copied; do_error: +tcp_remove_empty_skb (sk,tcp_write_queue_tail (sk));if (copied) goto out; out_err:
@@ -1412,17 +1429,11 @@ out_nopush:sock_zerocopy_put (uarg);return copied + copied_syn; +do_error: + skb =tcp_write_queue_tail (sk); do_fault: -if (!skb->len) { -tcp_unlink_write_queue (skb, sk); -/* It is the one place in all of TCP, except connection -* reset, where we can be unlinking the send_head. -*/ -tcp_check_send_head (sk, skb); -sk_wmem_free_skb (sk, skb); - } +tcp_remove_empty_skb (sk, skb); -do_error:if (copied + copied_syn) goto out; out_err:
Greg Kroah-Hartman
maintainerPATCH 38/40 net: sched: act_sample: fix psample group handling on overwrite
In reply to Greg Kroah-HartmanFrom: Vlad Buslov <[email protected]>
[ Upstream commit dbf47a2a094edf58983265e323ca4bdcdb58b5ee ]
Action sample doesn't properly handle psample_group pointer in overwrite case. Following issues need to be fixed:
- In tcf_sample_init() function RCU_INIT_POINTER() is used to set s->psample_group, even though we neither setting the pointer to NULL, nor preventing concurrent readers from accessing the pointer in some way. Use rcu_swap_protected() instead to safely reset the pointer.
- Old value of s->psample_group is not released or deallocated in any way, which results resource leak. Use psample_group_put() on non-NULL value obtained with rcu_swap_protected().
- The function psample_group_put() that released reference to struct psample_group pointed by rcu-pointer s->psample_group doesn't respect rcu grace period when deallocating it. Extend struct psample_group with rcu head and use kfree_rcu when freeing it.
--- include/net/psample.h | 1 + net/psample/psample.c | 2 +- net/sched/act_sample.c | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-)
include/net/psample.h +1 -0
@@ -12,6 +12,7 @@ struct psample_group {u32 group_num;u32 refcount;u32 seq; +struct rcu_head rcu; };struct psample_group *psample_group_get (struct net *net,u32 group_num);
net/psample/psample.c +1 -1
@@ -156,7 +156,7 @@ static void psample_group_destroy(struct {psample_group_notify (group,PSAMPLE_CMD_DEL_GROUP );list_del (&group->list); -kfree (group); +kfree_rcu (group, rcu); } static struct psample_group *
net/sched/act_sample.c +4 -1
@@ -92,13 +92,16 @@ static int tcf_sample_init(struct net *ntcf_idr_release (*a, bind);return -ENOMEM ; } -RCU_INIT_POINTER (s->psample_group, psample_group); +rcu_swap_protected (s->psample_group, psample_group, +lockdep_is_held (&s->tcf_lock));if (tb[TCA_SAMPLE_TRUNC_SIZE ]) { s->truncate = true; s->trunc_size =nla_get_u32 (tb[TCA_SAMPLE_TRUNC_SIZE ]); } +if (psample_group) +psample_group_put (psample_group);if (ret ==ACT_P_CREATED )tcf_idr_insert (tn, *a);return ret;
Greg Kroah-Hartman
maintainerPATCH 39/40 mld: fix memory leak in mld_del_delrec()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit a84d016479896b5526a2cc54784e6ffc41c9d6f6 ]
Similar to the fix done for IPv4 in commit e5b1c6c6277d ("igmp: fix memory leak in igmpv3_del_delrec()"), we need to make sure mca_tomb and mca_sources are not blindly overwritten.
Using swap() then a call to ip6_mc_clear_src() will take care of the missing free.
BUG: memory leak
unreferenced object 0xffff888117d9db00 (size 64):
comm "syz-executor247", pid 6918, jiffies 4294943989 (age 25.350s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 fe 88 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000005b463030>] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline]
[<000000005b463030>] slab_post_alloc_hook mm/slab.h:522 [inline]
[<000000005b463030>] slab_alloc mm/slab.c:3319 [inline]
[<000000005b463030>] kmem_cache_alloc_trace+0x145/0x2c0 mm/slab.c:3548
[<00000000939cbf94>] kmalloc include/linux/slab.h:552 [inline]
[<00000000939cbf94>] kzalloc include/linux/slab.h:748 [inline]
[<00000000939cbf94>] ip6_mc_add1_src net/ipv6/mcast.c:2236 [inline]
[<00000000939cbf94>] ip6_mc_add_src+0x31f/0x420 net/ipv6/mcast.c:2356
[<00000000d8972221>] ip6_mc_source+0x4a8/0x600 net/ipv6/mcast.c:449
[<000000002b203d0d>] do_ipv6_setsockopt.isra.0+0x1b92/0x1dd0 net/ipv6/ipv6_sockglue.c:748
[<000000001f1e2d54>] ipv6_setsockopt+0x89/0xd0 net/ipv6/ipv6_sockglue.c:944
[<00000000c8f7bdf9>] udpv6_setsockopt+0x4e/0x90 net/ipv6/udp.c:1558
[<000000005a9a0c5e>] sock_common_setsockopt+0x38/0x50 net/core/sock.c:3139
[<00000000910b37b2>] __sys_setsockopt+0x10f/0x220 net/socket.c:2084
[<00000000e9108023>] __do_sys_setsockopt net/socket.c:2100 [inline]
[<00000000e9108023>] __se_sys_setsockopt net/socket.c:2097 [inline]
[<00000000e9108023>] __x64_sys_setsockopt+0x26/0x30 net/socket.c:2097
[<00000000f4818160>] do_syscall_64+0x76/0x1a0 arch/x86/entry/common.c:296
[<000000008d367e8f>] entry_SYSCALL_64_after_hwframe+0x44/0xa9--- net/ipv6/mcast.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/ipv6/mcast.c +3 -2
@@ -772,12 +772,13 @@ static void mld_del_delrec(struct inet6_ im->idev = pmc->idev; im->mca_crcount = idev->mc_qrv;if (im->mca_sfmode ==MCAST_INCLUDE ) { - im->mca_tomb = pmc->mca_tomb; - im->mca_sources = pmc->mca_sources; +swap (im->mca_tomb, pmc->mca_tomb); +swap (im->mca_sources, pmc->mca_sources);for (psf = im->mca_sources; psf; psf = psf->sf_next) psf->sf_crcount = im->mca_crcount; }in6_dev_put (pmc->idev); +ip6_mc_clear_src (pmc);kfree (pmc); }spin_unlock_bh (&im->mca_lock);
Greg Kroah-Hartman
maintainerPATCH 40/40 x86/boot: Preserve boot_params.secure_boot from sanitizing
In reply to Greg Kroah-HartmanFrom: John S. Gruber <[email protected]>
commit 29d9a0b50736768f042752070e5cdf4e4d4c00df upstream.
Commit
a90118c445cc ("x86/boot: Save fields explicitly, zero out everything else")
now zeroes the secure boot setting information (enabled/disabled/...) passed by the boot loader or by the kernel's EFI handover mechanism.
The problem manifests itself with signed kernels using the EFI handoff protocol with grub and the kernel loses the information whether secure boot is enabled in the firmware, i.e., the log message "Secure boot enabled" becomes "Secure boot could not be determined".
efi_main() arch/x86/boot/compressed/eboot.c sets this field early but it is subsequently zeroed by the above referenced commit.
Include boot_params.secure_boot in the preserve field list.
[ bp: restructure commit message and massage. ]
--- arch/x86/include/asm/bootparam_utils.h | 1 + 1 file changed, 1 insertion(+)
arch/x86/include/asm/bootparam_utils.h +1 -0
@@ -71,6 +71,7 @@ static void sanitize_boot_params(structBOOT_PARAM_PRESERVE (eddbuf_entries),BOOT_PARAM_PRESERVE (edd_mbr_sig_buf_entries),BOOT_PARAM_PRESERVE (edd_mbr_sig_buffer), +BOOT_PARAM_PRESERVE (secure_boot),BOOT_PARAM_PRESERVE (hdr),BOOT_PARAM_PRESERVE (e820_table), BOOT_PARAM_PRESERVE(eddbuf),
stable-rc/linux-4.14.y boot: 80 boots: 0 failed, 80 passed (v4.14.142-40-g6b6c4e3151f3)
stable-rc/linux-4.14.y boot: 80 boots: 0 failed, 80 passed (v4.14.142-40-g6b6c4e3151f3)
Full Boot Summary: https://kernelci.org/boot/all/job/stable-rc/branch/linux-4.14.y/kernel/v4.14.142-40-g6b6c4e3151f3/
Full Build Summary: https://kernelci.org/build/stable-rc/branch/linux-4.14.y/kernel/v4.14.142-40-g6b6c4e3151f3/
Tree: stable-rc
Branch: linux-4.14.y
Git Describe: v4.14.142-40-g6b6c4e3151f3
Git Commit: 6b6c4e3151f31a94bec9c9c14906b1fd3cef2d87
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
Tested: 37 unique boards, 16 SoC families, 10 builds out of 201
---
For more info write to <[email protected]>
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.143 release. There are 40 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 Tue 10 Sep 2019 12:09:36 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.143-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.14.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
Summary
------------------------------------------------------------------------
kernel: 4.14.143-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-4.14.y
git commit: 9ea9c62091b32680f7e107f593241ab0edd80f81
git describe: v4.14.142-41-g9ea9c62091b3
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.14-oe/build/v4.14.142-41-g9ea9c62091b3
No regressions (compared to build v4.14.142)
No fixes (compared to build v4.14.142)
Ran 23700 total tests in the following environments and test suites.
Environments
--------------
- dragonboard-410c - arm64
- hi6220-hikey - arm64
- i386
- juno-r2 - arm64
- qemu_arm
- qemu_arm64
- qemu_i386
- qemu_x86_64
- x15 - arm
- x86_64
Test Suites
-----------
* build
* install-android-platform-tools-r2600
* kselftest
* libhugetlbfs
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-containers-tests
* ltp-cpuhotplug-tests
* ltp-cve-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-nptl-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-syscalls-tests
* ltp-timers-tests
* perf
* spectre-meltdown-checker-test
* v4l2-compliance
* network-basic-tests
* ltp-open-posix-tests
* kvm-unit-tests
* kselftest-vsyscall-mode-native
* kselftest-vsyscall-mode-none
* ssuite
Signature · 2 lines
Linaro LKFT https://lkft.linaro.org
Built and booted on my x86 machine. NO dmesg regressions found.
Thank you
Bharath
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.143 release. There are 40 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 Tue 10 Sep 2019 12:09:36 PM UTC. Anything received after that time might be too late.
Build results:
total: 172 pass: 172 fail: 0 Qemu test results: total: 372 pass: 372 fail: 0
Guenter
Jon Hunter
maintainerQuoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.143 release. There are 40 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 Tue 10 Sep 2019 12:09:36 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.143-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.14.y
and the diffstat can be found below.thanks,
greg k-h
All tests are passing for Tegra ...
Test results for stable-v4.14:
8 builds: 8 pass, 0 fail
16 boots: 16 pass, 0 fail
24 tests: 24 pass, 0 failLinux version: 4.14.143-rc1-g9ea9c62091b3
Boards tested: tegra124-jetson-tk1, tegra20-ventana,
tegra210-p2371-2180, tegra30-cardhu-a04
Cheers
Jon
Signature · 1 line
nvpublic