Skip to contentSkip to conversation

4.11.9-stable review

PATCH In review Greg Kroah-Hartman 2 participants 81 messages Jul 3, 2017 – Jul 4, 2017

Subsystems (2)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 4.11.9-stable review

This is the start of the stable review cycle for the 4.11.9 release. There are 84 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 Jul 5 13:33:30 UTC 2017. 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.11.9-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.11.y
and the diffstat can be found below.

thanks,

greg k-h

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

Greg Kroah-Hartman <[email protected]>

    Linux 4.11.9-rc1

Wanpeng Li <[email protected]>
KVM: nVMX: Fix exception injection

Radim Krčmář <[email protected]>
KVM: x86: zero base3 of unusable segments

Radim Krčmář <[email protected]>
KVM: x86/vPMU: fix undefined shift in intel_pmu_refresh()

Ladi Prosek <[email protected]>
KVM: x86: fix emulation of RSM and IRET instructions

Thomas Petazzoni <[email protected]>
mtd: nand: fsmc: fix NAND width handling

Kamal Dasu <[email protected]>
mtd: nand: brcmnand: Check flash #WP pin status before nand erase/program

Arnd Bergmann <[email protected]>
infiniband: hns: avoid gcc-7.0.1 warning for uninitialized data

Suravee Suthikulpanit <[email protected]>
iommu/amd: Fix interrupt remapping when disable guest_mode

Pan Bian <[email protected]>
iommu/amd: Fix incorrect error handling in amd_iommu_bind_pasid()

Robin Murphy <[email protected]>
iommu/dma: Don't reserve PCI I/O windows

Eric Ren <[email protected]>
ocfs2: fix deadlock caused by recursive locking in xattr

Junxiao Bi <[email protected]>
ocfs2: o2hb: revert hb threshold to keep compatible

Andy Lutomirski <[email protected]>
x86/mm: Fix flush_tlb_page() on Xen

Joerg Roedel <[email protected]>
x86/mpx: Correctly report do_mpx_bt_fault() failures to user-space

Kan Liang <[email protected]>
perf/x86: Fix spurious NMI with PEBS Load Latency event

Baoquan He <[email protected]>
x86/boot/KASLR: Fix kexec crash due to 'virt_addr' calculation bug

Thomas Gleixner <[email protected]>
x86/mshyperv: Remove excess #includes from mshyperv.h

Josh Poimboeuf <[email protected]>
Revert "x86/entry: Fix the end of the stack for newly forked tasks"

Arnaldo Carvalho de Melo <[email protected]>
tools arch: Sync arch/x86/lib/memcpy_64.S with the kernel

Christophe JAILLET <[email protected]>
ARM: davinci: PM: Do not free useful resources in normal path in 'davinci_pm_init'

Christophe JAILLET <[email protected]>
ARM: davinci: PM: Free resources in error handling path in 'davinci_pm_init'

Doug Berger <[email protected]>
ARM: 8685/1: ensure memblock-limit is pmd-aligned

Lorenzo Pieralisi <[email protected]>
ARM64/ACPI: Fix BAD_MADT_GICC_ENTRY() macro implementation

Timmy Li <[email protected]>
ARM64: PCI: Fix struct acpi_pci_root_ops allocation failure path

Eric Anholt <[email protected]>
watchdog: bcm281xx: Fix use of uninitialized spinlock.

Dan Carpenter <[email protected]>
xfrm: Oops on error in pfkey_msg2xfrm_state()

Dan Carpenter <[email protected]>
xfrm: NULL dereference on allocation failure

Sabrina Dubroca <[email protected]>
xfrm: fix stack access out of bounds with CONFIG_XFRM_SUB_POLICY

Hangbin Liu <[email protected]>
xfrm: move xfrm_garbage_collect out of xfrm_policy_flush

Yossi Kuperman <[email protected]>
xfrm6: Fix IPv6 payload_len in xfrm6_transport_finish

Juergen Gross <[email protected]>
xen/blkback: don't free be structure too early

Ard Biesheuvel <[email protected]>
mm/vmalloc.c: huge-vmap: fail gracefully on unexpected huge vmap mappings

Thomas Gleixner <[email protected]>
pinctrl/amd: Use regular interrupt instead of chained

Baoquan He <[email protected]>
x86/mm: Fix boot crash caused by incorrect loop count calculation in sync_global_pgds()

Vallish Vaidyeshwara <[email protected]>
dm thin: do not queue freed thin mapping for next stage processing

Deepak Rawat <[email protected]>
drm/vmwgfx: Free hash table allocated by cmdbuf managed res mgr

Kan Liang <[email protected]>
perf/x86/intel/uncore: Fix wrong box pointer check

Vikas Shivappa <[email protected]>
x86/intel_rdt: Fix memory leak on mount failure

Bartosz Golaszewski <[email protected]>
gpiolib: fix filtering out unwanted events

Miklos Szeredi <[email protected]>
ovl: copy-up: don't unlock between lookup and link

Benjamin Coddington <[email protected]>
Revert "NFS: nfs_rename() handle -ERESTARTSYS dentry left behind"

Trond Myklebust <[email protected]>
NFSv4.1: Fix a race in nfs4_proc_layoutget

Benjamin Coddington <[email protected]>
NFSv4.2: Don't send mode again in post-EXCLUSIVE4_1 SETATTR with umask

Hui Wang <[email protected]>
ALSA: hda - set input_path bitmap to zero after moving it to new place

Takashi Iwai <[email protected]>
ALSA: hda - Fix endless loop of codec configure

Paul Burton <[email protected]>
MIPS: Fix IRQ tracing & lockdep when rescheduling

Paul Burton <[email protected]>
MIPS: pm-cps: Drop manual cache-line alignment of ready_count

James Hogan <[email protected]>
MIPS: Avoid accidental raw backtrace

Karl Beldan <[email protected]>
MIPS: head: Reorder instructions missing a delay slot

Juergen Gross <[email protected]>
xen/blkback: don't use xen_blkif_get() in xen-blkback kthread

Kinglong Mee <[email protected]>
NFSv4.x/callback: Create the callback service through svc_create_pooled

Eric Leblond <[email protected]>
netfilter: synproxy: fix conntrackd interaction

Serhey Popovych <[email protected]>
rtnetlink: add IFLA_GROUP to ifla_policy

Serhey Popovych <[email protected]>
ipv6: Do not leak throw route references

Gao Feng <[email protected]>
net: 8021q: Fix one possible panic caused by BUG_ON in free_netdev

Wei Wang <[email protected]>

    decnet: always not take dst->__refcnt when inserting dst into hash table

Maor Dickman <[email protected]>
net/mlx5e: Fix timestamping capabilities reporting

Eli Cohen <[email protected]>
net/mlx5: Wait for FW readiness before initializing command interface

Or Gerlitz <[email protected]>
net/mlx5e: Avoid doing a cleanup call if the profile doesn't have it

Chris Mi <[email protected]>
net/mlx5e: Fix min inline value for VF rep SQs

Xin Long <[email protected]>
sctp: return next obj by passing pos + 1 into sctp_transport_get_idx

Xin Long <[email protected]>
ipv6: fix calling in6_ifa_hold incorrectly for dad work

Jesper Dangaard Brouer <[email protected]>
net: don't global ICMP rate limit packets originating from loopback

Bjørn Mork <[email protected]>
qmi_wwan: new Telewell and Sierra device IDs

WANG Cong <[email protected]>
igmp: add a missing spin_lock_init()

WANG Cong <[email protected]>
igmp: acquire pmc lock for ip_mc_clear_src()

Christian Perle <[email protected]>
proc: snmp6: Use correct type in memset

Majd Dibbiny <[email protected]>
net/mlx5: Enable 4K UAR only when page size is bigger than 4K

Tal Gilboa <[email protected]>
net/mlx5e: Fix wrong indications in DIM due to counter wraparound

Tal Gilboa <[email protected]>
net/mlx5e: Added BW check for DIM decision mechanism

Huy Nguyen <[email protected]>
net/mlx5: Remove several module events out of ethtool stats

Jia-Ju Bai <[email protected]>
net: tipc: Fix a sleep-in-atomic bug in tipc_msg_reverse

Jia-Ju Bai <[email protected]>
net: caif: Fix a sleep-in-atomic bug in cfpkt_create_pfx

Xin Long <[email protected]>
sctp: disable BH in sctp_for_each_endpoint

Krister Johansen <[email protected]>
Fix an intermittent pr_emerg warning about lo becoming free.

Mateusz Jurczyk <[email protected]>
af_unix: Add sockaddr length checks before accessing sa_family in bind and connect handlers

David Ahern <[email protected]>
net: vrf: Make add_fib_rules per network namespace flag

David Ahern <[email protected]>
net: ipv6: Release route when device is unregistering

Mintz, Yuval <[email protected]>
net: Zero ifla_vf_info in rtnl_fill_vfinfo()

Mateusz Jurczyk <[email protected]>
decnet: dn_rtmsg: Improve input length sanitization in dnrmg_receive_user_skb

Johannes Berg <[email protected]>
mac80211: free netdev on dev_alloc_name() error

Stephen Rothwell <[email protected]>
net: s390: fix up for "Fix inconsistent teardown and release of private netdev state"

David S. Miller <[email protected]>
net: Fix inconsistent teardown and release of private netdev state.

Alexander Potapenko <[email protected]>
net: don't call strlen on non-terminated string in dev_set_alias()

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

Diffstat:

 Makefile                                           |  4 +-
 arch/arm/mach-davinci/pm.c                         |  7 +-
 arch/arm/mm/mmu.c                                  |  8 +-
 arch/arm64/include/asm/acpi.h                      |  6 +-
 arch/arm64/kernel/pci.c                            |  4 +-
 arch/mips/kernel/entry.S                           |  3 +
 arch/mips/kernel/head.S                            |  2 +-
 arch/mips/kernel/pm-cps.c                          |  9 +--
 arch/mips/kernel/traps.c                           |  2 +
 arch/x86/boot/compressed/kaslr.c                   |  3 -
 arch/x86/boot/compressed/misc.c                    |  4 +-
 arch/x86/boot/compressed/misc.h                    |  2 -
 arch/x86/entry/entry_32.S                          | 30 ++++---
 arch/x86/entry/entry_64.S                          | 11 +--
 arch/x86/events/intel/core.c                       |  2 +-
 arch/x86/events/intel/ds.c                         |  2 +-
 arch/x86/events/intel/uncore.c                     |  2 +-
 arch/x86/events/perf_event.h                       |  1 +
 arch/x86/include/asm/kvm_emulate.h                 |  4 +-
 arch/x86/include/asm/mshyperv.h                    |  3 +-
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c           |  4 +-
 arch/x86/kvm/emulate.c                             | 16 ++--
 arch/x86/kvm/pmu_intel.c                           |  2 +-
 arch/x86/kvm/vmx.c                                 |  2 +-
 arch/x86/kvm/x86.c                                 | 17 +++-
 arch/x86/mm/init_64.c                              |  8 +-
 arch/x86/mm/mpx.c                                  | 10 +--
 arch/x86/mm/tlb.c                                  |  4 +-
 drivers/block/xen-blkback/blkback.c                |  3 -
 drivers/block/xen-blkback/xenbus.c                 |  7 +-
 drivers/gpio/gpiolib.c                             |  3 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c         |  1 +
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c         |  1 +
 drivers/iommu/amd_iommu.c                          |  6 +-
 drivers/iommu/amd_iommu_v2.c                       |  2 +-
 drivers/iommu/dma-iommu.c                          |  3 +-
 drivers/md/dm-thin.c                               | 26 +++----
 drivers/mtd/nand/brcmnand/brcmnand.c               | 61 ++++++++++++++-
 drivers/mtd/nand/fsmc_nand.c                       | 13 ++--
 drivers/net/bonding/bond_main.c                    |  6 +-
 drivers/net/caif/caif_hsi.c                        |  2 +-
 drivers/net/caif/caif_serial.c                     |  2 +-
 drivers/net/caif/caif_spi.c                        |  2 +-
 drivers/net/caif/caif_virtio.c                     |  2 +-
 drivers/net/can/slcan.c                            |  7 +-
 drivers/net/can/vcan.c                             |  2 +-
 drivers/net/dummy.c                                |  4 +-
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c    |  2 +-
 drivers/net/ethernet/mellanox/mlx5/core/en.h       |  8 +-
 .../net/ethernet/mellanox/mlx5/core/en_ethtool.c   |  8 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c  |  3 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_rep.c   |  2 +
 drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c | 45 ++++++-----
 drivers/net/ethernet/mellanox/mlx5/core/en_stats.h | 11 +--
 drivers/net/ethernet/mellanox/mlx5/core/main.c     | 20 ++++-
 drivers/net/geneve.c                               |  2 +-
 drivers/net/gtp.c                                  |  2 +-
 drivers/net/hamradio/6pack.c                       |  2 +-
 drivers/net/hamradio/bpqether.c                    |  2 +-
 drivers/net/ifb.c                                  |  4 +-
 drivers/net/ipvlan/ipvlan_main.c                   |  2 +-
 drivers/net/loopback.c                             |  4 +-
 drivers/net/macsec.c                               |  4 +-
 drivers/net/macvlan.c                              |  2 +-
 drivers/net/nlmon.c                                |  2 +-
 drivers/net/slip/slip.c                            |  7 +-
 drivers/net/team/team.c                            |  4 +-
 drivers/net/tun.c                                  |  4 +-
 drivers/net/usb/cdc-phonet.c                       |  2 +-
 drivers/net/usb/qmi_wwan.c                         |  4 +
 drivers/net/veth.c                                 |  4 +-
 drivers/net/vrf.c                                  | 38 +++++++--
 drivers/net/vxlan.c                                |  2 +-
 drivers/net/wan/dlci.c                             |  2 +-
 drivers/net/wan/hdlc_fr.c                          |  2 +-
 drivers/net/wan/lapbether.c                        |  2 +-
 drivers/net/wireless/ath/ath6kl/main.c             |  2 +-
 .../broadcom/brcm80211/brcmfmac/cfg80211.c         |  1 -
 .../wireless/broadcom/brcm80211/brcmfmac/core.c    |  3 +-
 drivers/net/wireless/intersil/hostap/hostap_main.c |  2 +-
 drivers/net/wireless/mac80211_hwsim.c              |  2 +-
 drivers/net/wireless/marvell/mwifiex/main.c        |  2 +-
 drivers/pinctrl/pinctrl-amd.c                      | 91 ++++++++++------------
 drivers/s390/net/netiucv.c                         |  4 +-
 drivers/staging/rtl8188eu/os_dep/mon.c             |  2 +-
 drivers/usb/gadget/function/f_phonet.c             |  2 +-
 drivers/watchdog/bcm_kona_wdt.c                    |  3 +-
 fs/nfs/callback.c                                  |  2 +-
 fs/nfs/dir.c                                       | 51 ++++++------
 fs/nfs/nfs4proc.c                                  |  5 +-
 fs/ocfs2/cluster/heartbeat.c                       |  8 +-
 fs/ocfs2/dlmglue.c                                 |  4 +
 fs/ocfs2/xattr.c                                   | 23 +++---
 fs/overlayfs/copy_up.c                             | 24 +++---
 include/linux/netdevice.h                          | 12 ++-
 include/net/xfrm.h                                 | 10 ---
 mm/vmalloc.c                                       | 15 +++-
 net/8021q/vlan.c                                   |  3 +-
 net/8021q/vlan_dev.c                               |  4 +-
 net/batman-adv/soft-interface.c                    |  5 +-
 net/bluetooth/6lowpan.c                            |  2 +-
 net/bridge/br_device.c                             |  2 +-
 net/caif/cfpkt_skbuff.c                            |  6 +-
 net/caif/chnl_net.c                                |  4 +-
 net/core/dev.c                                     | 11 ++-
 net/core/dst.c                                     | 14 ++++
 net/core/rtnetlink.c                               |  5 +-
 net/decnet/dn_route.c                              | 14 +---
 net/decnet/netfilter/dn_rtmsg.c                    |  4 +-
 net/hsr/hsr_device.c                               |  4 +-
 net/ieee802154/6lowpan/core.c                      |  2 +-
 net/ipv4/icmp.c                                    |  8 +-
 net/ipv4/igmp.c                                    | 22 ++++--
 net/ipv4/ip_tunnel.c                               |  4 +-
 net/ipv4/ipmr.c                                    |  2 +-
 net/ipv6/addrconf.c                                |  6 +-
 net/ipv6/fib6_rules.c                              | 22 ++----
 net/ipv6/icmp.c                                    |  2 +-
 net/ipv6/ip6_fib.c                                 |  3 +-
 net/ipv6/ip6_gre.c                                 |  9 ++-
 net/ipv6/ip6_tunnel.c                              |  8 +-
 net/ipv6/ip6_vti.c                                 |  8 +-
 net/ipv6/ip6mr.c                                   |  2 +-
 net/ipv6/proc.c                                    |  2 +-
 net/ipv6/route.c                                   |  1 +
 net/ipv6/sit.c                                     |  6 +-
 net/ipv6/xfrm6_input.c                             |  2 +-
 net/irda/irlan/irlan_eth.c                         |  2 +-
 net/key/af_key.c                                   | 19 ++++-
 net/l2tp/l2tp_eth.c                                |  2 +-
 net/mac80211/iface.c                               |  7 +-
 net/mac802154/iface.c                              |  7 +-
 net/netfilter/nf_conntrack_netlink.c               |  4 +
 net/openvswitch/vport-internal_dev.c               |  4 +-
 net/phonet/pep-gprs.c                              |  2 +-
 net/sctp/socket.c                                  |  9 +--
 net/tipc/msg.c                                     |  2 +-
 net/unix/af_unix.c                                 |  7 +-
 net/xfrm/xfrm_policy.c                             | 51 ------------
 net/xfrm/xfrm_user.c                               |  1 +
 sound/pci/hda/hda_codec.h                          |  2 +
 sound/pci/hda/hda_controller.c                     |  8 +-
 sound/pci/hda/hda_generic.c                        |  1 +
 tools/arch/x86/lib/memcpy_64.S                     |  2 +-
 144 files changed, 604 insertions(+), 502 deletions(-)
author maintainer
#1 lore raw

PATCH 1/84 net: dont call strlen on non-terminated string in dev_set_alias()

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Alexander Potapenko <[email protected]>

[ Upstream commit c28294b941232931fbd714099798eb7aa7e865d7 ]

KMSAN reported a use of uninitialized memory in dev_set_alias(), which was caused by calling strlcpy() (which in turn called strlen()) on the user-supplied non-terminated string.

---
 net/core/dev.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/core/dev.c +2 -1
@@ -1251,8 +1251,9 @@ int dev_set_alias(struct net_device *dev
 	if (!new_ifalias)
 		return -ENOMEM;
 	dev->ifalias = new_ifalias;
+	memcpy(dev->ifalias, alias, len);
+	dev->ifalias[len] = 0;
 
-	strlcpy(dev->ifalias, alias, len+1);
 	return len;
 }
 
author maintainer
#2 lore raw

PATCH 2/84 net: Fix inconsistent teardown and release of private netdev state.

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: "David S. Miller" <[email protected]>

[ Upstream commit cf124db566e6b036b8bcbe8decbed740bdfac8c6 ]

Network devices can allocate reasources and private memory using netdev_ops->ndo_init(). However, the release of these resources can occur in one of two different places.

Either netdev_ops->ndo_uninit() or netdev->destructor().

The decision of which operation frees the resources depends upon whether it is necessary for all netdev refs to be released before it is safe to perform the freeing.

netdev_ops->ndo_uninit() presumably can occur right after the NETDEV_UNREGISTER notifier completes and the unicast and multicast address lists are flushed.

netdev->destructor(), on the other hand, does not run until the netdev references all go away.

Further complicating the situation is that netdev->destructor() almost universally does also a free_netdev().

This creates a problem for the logic in register_netdevice(). Because all callers of register_netdevice() manage the freeing of the netdev, and invoke free_netdev(dev) if register_netdevice() fails.

If netdev_ops->ndo_init() succeeds, but something else fails inside of register_netdevice(), it does call ndo_ops->ndo_uninit(). But it is not able to invoke netdev->destructor().

This is because netdev->destructor() will do a free_netdev() and then the caller of register_netdevice() will do the same.

However, this means that the resources that would normally be released by netdev->destructor() will not be.

Over the years drivers have added local hacks to deal with this, by invoking their destructor parts by hand when register_netdevice() fails.

Many drivers do not try to deal with this, and instead we have leaks.

Let's close this hole by formalizing the distinction between what private things need to be freed up by netdev->destructor() and whether the driver needs unregister_netdevice() to perform the free_netdev().

netdev->priv_destructor() performs all actions to free up the private resources that used to be freed by netdev->destructor(), except for free_netdev().

netdev->needs_free_netdev is a boolean that indicates whether free_netdev() should be done at the end of unregister_netdevice().

Now, register_netdevice() can sanely release all resources after ndo_ops->ndo_init() succeeds, by invoking both ndo_ops->ndo_uninit() and netdev->priv_destructor().

And at the end of unregister_netdevice(), we invoke netdev->priv_destructor() and optionally call free_netdev().

---
 drivers/net/bonding/bond_main.c                             |    6 +++---
 drivers/net/caif/caif_hsi.c                                 |    2 +-
 drivers/net/caif/caif_serial.c                              |    2 +-
 drivers/net/caif/caif_spi.c                                 |    2 +-
 drivers/net/caif/caif_virtio.c                              |    2 +-
 drivers/net/can/slcan.c                                     |    7 +++----
 drivers/net/can/vcan.c                                      |    2 +-
 drivers/net/dummy.c                                         |    4 ++--
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c             |    2 +-
 drivers/net/geneve.c                                        |    2 +-
 drivers/net/gtp.c                                           |    2 +-
 drivers/net/hamradio/6pack.c                                |    2 +-
 drivers/net/hamradio/bpqether.c                             |    2 +-
 drivers/net/ifb.c                                           |    4 ++--
 drivers/net/ipvlan/ipvlan_main.c                            |    2 +-
 drivers/net/loopback.c                                      |    4 ++--
 drivers/net/macsec.c                                        |    4 ++--
 drivers/net/macvlan.c                                       |    2 +-
 drivers/net/nlmon.c                                         |    2 +-
 drivers/net/slip/slip.c                                     |    7 +++----
 drivers/net/team/team.c                                     |    4 ++--
 drivers/net/tun.c                                           |    4 ++--
 drivers/net/usb/cdc-phonet.c                                |    2 +-
 drivers/net/veth.c                                          |    4 ++--
 drivers/net/vrf.c                                           |    2 +-
 drivers/net/vxlan.c                                         |    2 +-
 drivers/net/wan/dlci.c                                      |    2 +-
 drivers/net/wan/hdlc_fr.c                                   |    2 +-
 drivers/net/wan/lapbether.c                                 |    2 +-
 drivers/net/wireless/ath/ath6kl/main.c                      |    2 +-
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |    1 -
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c     |    3 ++-
 drivers/net/wireless/intersil/hostap/hostap_main.c          |    2 +-
 drivers/net/wireless/mac80211_hwsim.c                       |    2 +-
 drivers/net/wireless/marvell/mwifiex/main.c                 |    2 +-
 drivers/staging/rtl8188eu/os_dep/mon.c                      |    2 +-
 drivers/usb/gadget/function/f_phonet.c                      |    2 +-
 include/linux/netdevice.h                                   |    7 ++++---
 net/8021q/vlan_dev.c                                        |    4 ++--
 net/batman-adv/soft-interface.c                             |    5 ++---
 net/bluetooth/6lowpan.c                                     |    2 +-
 net/bridge/br_device.c                                      |    2 +-
 net/caif/chnl_net.c                                         |    4 ++--
 net/core/dev.c                                              |    8 ++++++--
 net/hsr/hsr_device.c                                        |    4 ++--
 net/ieee802154/6lowpan/core.c                               |    2 +-
 net/ipv4/ip_tunnel.c                                        |    4 ++--
 net/ipv4/ipmr.c                                             |    2 +-
 net/ipv6/ip6_gre.c                                          |    9 +++++----
 net/ipv6/ip6_tunnel.c                                       |    8 ++++----
 net/ipv6/ip6_vti.c                                          |    8 ++++----
 net/ipv6/ip6mr.c                                            |    2 +-
 net/ipv6/sit.c                                              |    6 +++---
 net/irda/irlan/irlan_eth.c                                  |    2 +-
 net/l2tp/l2tp_eth.c                                         |    2 +-
 net/mac80211/iface.c                                        |    6 +++---
 net/mac802154/iface.c                                       |    7 +++----
 net/openvswitch/vport-internal_dev.c                        |    4 ++--
 net/phonet/pep-gprs.c                                       |    2 +-
 59 files changed, 102 insertions(+), 100 deletions(-)
drivers/net/bonding/bond_main.c +3 -3
@@ -4163,7 +4163,6 @@ static void bond_destructor(struct net_d
 	struct bonding *bond = netdev_priv(bond_dev);
 	if (bond->wq)
 		destroy_workqueue(bond->wq);
-	free_netdev(bond_dev);
 }
 
 void bond_setup(struct net_device *bond_dev)
@@ -4183,7 +4182,8 @@ void bond_setup(struct net_device *bond_
 	bond_dev->netdev_ops = &bond_netdev_ops;
 	bond_dev->ethtool_ops = &bond_ethtool_ops;
 
-	bond_dev->destructor = bond_destructor;
+	bond_dev->needs_free_netdev = true;
+	bond_dev->priv_destructor = bond_destructor;
 
 	SET_NETDEV_DEVTYPE(bond_dev, &bond_type);
 
@@ -4689,7 +4689,7 @@ int bond_create(struct net *net, const c
 
 	rtnl_unlock();
 	if (res < 0)
-		bond_destructor(bond_dev);
+		free_netdev(bond_dev);
 	return res;
 }
 
drivers/net/caif/caif_hsi.c +1 -1
@@ -1121,7 +1121,7 @@ static void cfhsi_setup(struct net_devic
 	dev->flags = IFF_POINTOPOINT | IFF_NOARP;
 	dev->mtu = CFHSI_MAX_CAIF_FRAME_SZ;
 	dev->priv_flags |= IFF_NO_QUEUE;
-	dev->destructor = free_netdev;
+	dev->needs_free_netdev = true;
 	dev->netdev_ops = &cfhsi_netdevops;
 	for (i = 0; i < CFHSI_PRIO_LAST; ++i)
 		skb_queue_head_init(&cfhsi->qhead[i]);
drivers/net/caif/caif_serial.c +1 -1
@@ -428,7 +428,7 @@ static void caifdev_setup(struct net_dev
 	dev->flags = IFF_POINTOPOINT | IFF_NOARP;
 	dev->mtu = CAIF_MAX_MTU;
 	dev->priv_flags |= IFF_NO_QUEUE;
-	dev->destructor = free_netdev;
+	dev->needs_free_netdev = true;
 	skb_queue_head_init(&serdev->head);
 	serdev->common.link_select = CAIF_LINK_LOW_LATENCY;
 	serdev->common.use_frag = true;
drivers/net/caif/caif_spi.c +1 -1
@@ -712,7 +712,7 @@ static void cfspi_setup(struct net_devic
 	dev->flags = IFF_NOARP | IFF_POINTOPOINT;
 	dev->priv_flags |= IFF_NO_QUEUE;
 	dev->mtu = SPI_MAX_PAYLOAD_SIZE;
-	dev->destructor = free_netdev;
+	dev->needs_free_netdev = true;
 	skb_queue_head_init(&cfspi->qhead);
 	skb_queue_head_init(&cfspi->chead);
 	cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
drivers/net/caif/caif_virtio.c +1 -1
@@ -617,7 +617,7 @@ static void cfv_netdev_setup(struct net_
 	netdev->tx_queue_len = 100;
 	netdev->flags = IFF_POINTOPOINT | IFF_NOARP;
 	netdev->mtu = CFV_DEF_MTU_SIZE;
-	netdev->destructor = free_netdev;
+	netdev->needs_free_netdev = true;
 }
 
 /* Create debugfs counters for the device */
drivers/net/can/slcan.c +3 -4
@@ -417,7 +417,7 @@ static int slc_open(struct net_device *d
 static void slc_free_netdev(struct net_device *dev)
 {
 	int i = dev->base_addr;
-	free_netdev(dev);
+
 	slcan_devs[i] = NULL;
 }
 
@@ -436,7 +436,8 @@ static const struct net_device_ops slc_n
 static void slc_setup(struct net_device *dev)
 {
 	dev->netdev_ops		= &slc_netdev_ops;
-	dev->destructor		= slc_free_netdev;
+	dev->needs_free_netdev	= true;
+	dev->priv_destructor	= slc_free_netdev;
 
 	dev->hard_header_len	= 0;
 	dev->addr_len		= 0;
@@ -761,8 +762,6 @@ static void __exit slcan_exit(void)
 		if (sl->tty) {
 			printk(KERN_ERR "%s: tty discipline still running\n",
 			       dev->name);
-			/* Intentionally leak the control block. */
-			dev->destructor = NULL;
 		}
 
 		unregister_netdev(dev);
drivers/net/can/vcan.c +1 -1
@@ -160,7 +160,7 @@ static void vcan_setup(struct net_device
 		dev->flags |= IFF_ECHO;
 
 	dev->netdev_ops		= &vcan_netdev_ops;
-	dev->destructor		= free_netdev;
+	dev->needs_free_netdev	= true;
 }
 
 static struct rtnl_link_ops vcan_link_ops __read_mostly = {
drivers/net/dummy.c +2 -2
@@ -313,7 +313,6 @@ static void dummy_free_netdev(struct net
 	struct dummy_priv *priv = netdev_priv(dev);
 
 	kfree(priv->vfinfo);
-	free_netdev(dev);
 }
 
 static void dummy_setup(struct net_device *dev)
@@ -323,7 +322,8 @@ static void dummy_setup(struct net_devic
 	/* Initialize the device structure. */
 	dev->netdev_ops = &dummy_netdev_ops;
 	dev->ethtool_ops = &dummy_ethtool_ops;
-	dev->destructor = dummy_free_netdev;
+	dev->needs_free_netdev = true;
+	dev->priv_destructor = dummy_free_netdev;
 
 	/* Fill in device structure with ethernet-generic values. */
 	dev->flags |= IFF_NOARP;
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +1 -1
@@ -4530,7 +4530,7 @@ static void dummy_setup(struct net_devic
 	/* Initialize the device structure. */
 	dev->netdev_ops = &cxgb4_mgmt_netdev_ops;
 	dev->ethtool_ops = &cxgb4_mgmt_ethtool_ops;
-	dev->destructor = free_netdev;
+	dev->needs_free_netdev = true;
 }
 
 static int config_mgmt_dev(struct pci_dev *pdev)
drivers/net/geneve.c +1 -1
@@ -1007,7 +1007,7 @@ static void geneve_setup(struct net_devi
 
 	dev->netdev_ops = &geneve_netdev_ops;
 	dev->ethtool_ops = &geneve_ethtool_ops;
-	dev->destructor = free_netdev;
+	dev->needs_free_netdev = true;
 
 	SET_NETDEV_DEVTYPE(dev, &geneve_type);
 
drivers/net/gtp.c +1 -1
@@ -618,7 +618,7 @@ static const struct net_device_ops gtp_n
 static void gtp_link_setup(struct net_device *dev)
 {
 	dev->netdev_ops		= &gtp_netdev_ops;
-	dev->destructor		= free_netdev;
+	dev->needs_free_netdev	= true;
 
 	dev->hard_header_len = 0;
 	dev->addr_len = 0;
drivers/net/hamradio/6pack.c +1 -1
@@ -311,7 +311,7 @@ static void sp_setup(struct net_device *
 {
 	/* Finish setting up the DEVICE info. */
 	dev->netdev_ops		= &sp_netdev_ops;
-	dev->destructor		= free_netdev;
+	dev->needs_free_netdev	= true;
 	dev->mtu		= SIXP_MTU;
 	dev->hard_header_len	= AX25_MAX_HEADER_LEN;
 	dev->header_ops 	= &ax25_header_ops;
drivers/net/hamradio/bpqether.c +1 -1
@@ -476,7 +476,7 @@ static const struct net_device_ops bpq_n
 static void bpq_setup(struct net_device *dev)
 {
 	dev->netdev_ops	     = &bpq_netdev_ops;
-	dev->destructor	     = free_netdev;
+	dev->needs_free_netdev = true;
 
 	memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
 	memcpy(dev->dev_addr,  &ax25_defaddr, AX25_ADDR_LEN);
drivers/net/ifb.c +2 -2
@@ -207,7 +207,6 @@ static void ifb_dev_free(struct net_devi
 		__skb_queue_purge(&txp->tq);
 	}
 	kfree(dp->tx_private);
-	free_netdev(dev);
 }
 
 static void ifb_setup(struct net_device *dev)
@@ -230,7 +229,8 @@ static void ifb_setup(struct net_device
 	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 	netif_keep_dst(dev);
 	eth_hw_addr_random(dev);
-	dev->destructor = ifb_dev_free;
+	dev->needs_free_netdev = true;
+	dev->priv_destructor = ifb_dev_free;
 }
 
 static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
drivers/net/ipvlan/ipvlan_main.c +1 -1
@@ -621,7 +621,7 @@ void ipvlan_link_setup(struct net_device
 	dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
 	dev->priv_flags |= IFF_UNICAST_FLT | IFF_NO_QUEUE;
 	dev->netdev_ops = &ipvlan_netdev_ops;
-	dev->destructor = free_netdev;
+	dev->needs_free_netdev = true;
 	dev->header_ops = &ipvlan_header_ops;
 	dev->ethtool_ops = &ipvlan_ethtool_ops;
 }
drivers/net/loopback.c +2 -2
@@ -145,7 +145,6 @@ static void loopback_dev_free(struct net
 {
 	dev_net(dev)->loopback_dev = NULL;
 	free_percpu(dev->lstats);
-	free_netdev(dev);
 }
 
 static const struct net_device_ops loopback_ops = {
@@ -183,7 +182,8 @@ static void loopback_setup(struct net_de
 	dev->ethtool_ops	= &loopback_ethtool_ops;
 	dev->header_ops		= &eth_header_ops;
 	dev->netdev_ops		= &loopback_ops;
-	dev->destructor		= loopback_dev_free;
+	dev->needs_free_netdev	= true;
+	dev->priv_destructor	= loopback_dev_free;
 }
 
 /* Setup and register the loopback device. */
drivers/net/macsec.c +2 -2
@@ -2994,7 +2994,6 @@ static void macsec_free_netdev(struct ne
 	free_percpu(macsec->secy.tx_sc.stats);
 
 	dev_put(real_dev);
-	free_netdev(dev);
 }
 
 static void macsec_setup(struct net_device *dev)
@@ -3004,7 +3003,8 @@ static void macsec_setup(struct net_devi
 	dev->max_mtu = ETH_MAX_MTU;
 	dev->priv_flags |= IFF_NO_QUEUE;
 	dev->netdev_ops = &macsec_netdev_ops;
-	dev->destructor = macsec_free_netdev;
+	dev->needs_free_netdev = true;
+	dev->priv_destructor = macsec_free_netdev;
 	SET_NETDEV_DEVTYPE(dev, &macsec_type);
 
 	eth_zero_addr(dev->broadcast);
drivers/net/macvlan.c +1 -1
@@ -1089,7 +1089,7 @@ void macvlan_common_setup(struct net_dev
 	netif_keep_dst(dev);
 	dev->priv_flags	       |= IFF_UNICAST_FLT;
 	dev->netdev_ops		= &macvlan_netdev_ops;
-	dev->destructor		= free_netdev;
+	dev->needs_free_netdev	= true;
 	dev->header_ops		= &macvlan_hard_header_ops;
 	dev->ethtool_ops	= &macvlan_ethtool_ops;
 }
drivers/net/nlmon.c +1 -1
@@ -113,7 +113,7 @@ static void nlmon_setup(struct net_devic
 
 	dev->netdev_ops	= &nlmon_ops;
 	dev->ethtool_ops = &nlmon_ethtool_ops;
-	dev->destructor	= free_netdev;
+	dev->needs_free_netdev = true;
 
 	dev->features = NETIF_F_SG | NETIF_F_FRAGLIST |
 			NETIF_F_HIGHDMA | NETIF_F_LLTX;
drivers/net/slip/slip.c +3 -4
@@ -629,7 +629,7 @@ static void sl_uninit(struct net_device
 static void sl_free_netdev(struct net_device *dev)
 {
 	int i = dev->base_addr;
-	free_netdev(dev);
+
 	slip_devs[i] = NULL;
 }
 
@@ -651,7 +651,8 @@ static const struct net_device_ops sl_ne
 static void sl_setup(struct net_device *dev)
 {
 	dev->netdev_ops		= &sl_netdev_ops;
-	dev->destructor		= sl_free_netdev;
+	dev->needs_free_netdev	= true;
+	dev->priv_destructor	= sl_free_netdev;
 
 	dev->hard_header_len	= 0;
 	dev->addr_len		= 0;
@@ -1369,8 +1370,6 @@ static void __exit slip_exit(void)
 		if (sl->tty) {
 			printk(KERN_ERR "%s: tty discipline still running\n",
 			       dev->name);
-			/* Intentionally leak the control block. */
-			dev->destructor = NULL;
 		}
 
 		unregister_netdev(dev);
drivers/net/team/team.c +2 -2
@@ -1643,7 +1643,6 @@ static void team_destructor(struct net_d
 	struct team *team = netdev_priv(dev);
 
 	free_percpu(team->pcpu_stats);
-	free_netdev(dev);
 }
 
 static int team_open(struct net_device *dev)
@@ -2079,7 +2078,8 @@ static void team_setup(struct net_device
 
 	dev->netdev_ops = &team_netdev_ops;
 	dev->ethtool_ops = &team_ethtool_ops;
-	dev->destructor	= team_destructor;
+	dev->needs_free_netdev = true;
+	dev->priv_destructor = team_destructor;
 	dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
 	dev->priv_flags |= IFF_NO_QUEUE;
 	dev->priv_flags |= IFF_TEAM;
drivers/net/tun.c +2 -2
@@ -1560,7 +1560,6 @@ static void tun_free_netdev(struct net_d
 	free_percpu(tun->pcpu_stats);
 	tun_flow_uninit(tun);
 	security_tun_dev_free_security(tun->security);
-	free_netdev(dev);
 }
 
 static void tun_setup(struct net_device *dev)
@@ -1571,7 +1570,8 @@ static void tun_setup(struct net_device
 	tun->group = INVALID_GID;
 
 	dev->ethtool_ops = &tun_ethtool_ops;
-	dev->destructor = tun_free_netdev;
+	dev->needs_free_netdev = true;
+	dev->priv_destructor = tun_free_netdev;
 	/* We prefer our own queue length */
 	dev->tx_queue_len = TUN_READQ_SIZE;
 }
drivers/net/usb/cdc-phonet.c +1 -1
@@ -298,7 +298,7 @@ static void usbpn_setup(struct net_devic
 	dev->addr_len		= 1;
 	dev->tx_queue_len	= 3;
 
-	dev->destructor		= free_netdev;
+	dev->needs_free_netdev	= true;
 }
 
 /*
drivers/net/veth.c +2 -2
@@ -227,7 +227,6 @@ static int veth_dev_init(struct net_devi
 static void veth_dev_free(struct net_device *dev)
 {
 	free_percpu(dev->vstats);
-	free_netdev(dev);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -322,7 +321,8 @@ static void veth_setup(struct net_device
 			       NETIF_F_HW_VLAN_STAG_TX |
 			       NETIF_F_HW_VLAN_CTAG_RX |
 			       NETIF_F_HW_VLAN_STAG_RX);
-	dev->destructor = veth_dev_free;
+	dev->needs_free_netdev = true;
+	dev->priv_destructor = veth_dev_free;
 	dev->max_mtu = ETH_MAX_MTU;
 
 	dev->hw_features = VETH_FEATURES;
drivers/net/vrf.c +1 -1
@@ -1206,7 +1206,7 @@ static void vrf_setup(struct net_device
 	dev->netdev_ops = &vrf_netdev_ops;
 	dev->l3mdev_ops = &vrf_l3mdev_ops;
 	dev->ethtool_ops = &vrf_ethtool_ops;
-	dev->destructor = free_netdev;
+	dev->needs_free_netdev = true;
 
 	/* Fill in device structure with ethernet-generic values. */
 	eth_hw_addr_random(dev);
drivers/net/vxlan.c +1 -1
@@ -2607,7 +2607,7 @@ static void vxlan_setup(struct net_devic
 	eth_hw_addr_random(dev);
 	ether_setup(dev);
 
-	dev->destructor = free_netdev;
+	dev->needs_free_netdev = true;
 	SET_NETDEV_DEVTYPE(dev, &vxlan_type);
 
 	dev->features	|= NETIF_F_LLTX;
drivers/net/wan/dlci.c +1 -1
@@ -475,7 +475,7 @@ static void dlci_setup(struct net_device
 	dev->flags		= 0;
 	dev->header_ops		= &dlci_header_ops;
 	dev->netdev_ops		= &dlci_netdev_ops;
-	dev->destructor		= free_netdev;
+	dev->needs_free_netdev	= true;
 
 	dlp->receive		= dlci_receive;
 
drivers/net/wan/hdlc_fr.c +1 -1
@@ -1106,7 +1106,7 @@ static int fr_add_pvc(struct net_device
 		return -EIO;
 	}
 
-	dev->destructor = free_netdev;
+	dev->needs_free_netdev = true;
 	*get_dev_p(pvc, type) = dev;
 	if (!used) {
 		state(hdlc)->dce_changed = 1;
drivers/net/wan/lapbether.c +1 -1
@@ -306,7 +306,7 @@ static const struct net_device_ops lapbe
 static void lapbeth_setup(struct net_device *dev)
 {
 	dev->netdev_ops	     = &lapbeth_netdev_ops;
-	dev->destructor	     = free_netdev;
+	dev->needs_free_netdev = true;
 	dev->type            = ARPHRD_X25;
 	dev->hard_header_len = 3;
 	dev->mtu             = 1000;
drivers/net/wireless/ath/ath6kl/main.c +1 -1
@@ -1287,7 +1287,7 @@ void init_netdev(struct net_device *dev)
 	struct ath6kl *ar = ath6kl_priv(dev);
 
 	dev->netdev_ops = &ath6kl_netdev_ops;
-	dev->destructor = free_netdev;
+	dev->needs_free_netdev = true;
 	dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
 
 	dev->needed_headroom = ETH_HLEN;
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +0 -1
@@ -5209,7 +5209,6 @@ void brcmf_cfg80211_free_netdev(struct n
 
 	if (vif)
 		brcmf_free_vif(vif);
-	free_netdev(ndev);
 }
 
 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +2 -1
@@ -652,7 +652,8 @@ struct brcmf_if *brcmf_add_if(struct brc
 		if (!ndev)
 			return ERR_PTR(-ENOMEM);
 
-		ndev->destructor = brcmf_cfg80211_free_netdev;
+		ndev->needs_free_netdev = true;
+		ndev->priv_destructor = brcmf_cfg80211_free_netdev;
 		ifp = netdev_priv(ndev);
 		ifp->ndev = ndev;
 		/* store mapping ifidx to bsscfgidx */
drivers/net/wireless/intersil/hostap/hostap_main.c +1 -1
@@ -73,7 +73,7 @@ struct net_device * hostap_add_interface
 	dev->mem_end = mdev->mem_end;
 
 	hostap_setup_dev(dev, local, type);
-	dev->destructor = free_netdev;
+	dev->needs_free_netdev = true;
 
 	sprintf(dev->name, "%s%s", prefix, name);
 	if (!rtnl_locked)
drivers/net/wireless/mac80211_hwsim.c +1 -1
@@ -2807,7 +2807,7 @@ static const struct net_device_ops hwsim
 static void hwsim_mon_setup(struct net_device *dev)
 {
 	dev->netdev_ops = &hwsim_netdev_ops;
-	dev->destructor = free_netdev;
+	dev->needs_free_netdev = true;
 	ether_setup(dev);
 	dev->priv_flags |= IFF_NO_QUEUE;
 	dev->type = ARPHRD_IEEE80211_RADIOTAP;
drivers/net/wireless/marvell/mwifiex/main.c +1 -1
@@ -1277,7 +1277,7 @@ void mwifiex_init_priv_params(struct mwi
 			      struct net_device *dev)
 {
 	dev->netdev_ops = &mwifiex_netdev_ops;
-	dev->destructor = free_netdev;
+	dev->needs_free_netdev = true;
 	/* Initialize private structure */
 	priv->current_key_index = 0;
 	priv->media_connected = false;
drivers/staging/rtl8188eu/os_dep/mon.c +1 -1
@@ -152,7 +152,7 @@ static const struct net_device_ops mon_n
 static void mon_setup(struct net_device *dev)
 {
 	dev->netdev_ops = &mon_netdev_ops;
-	dev->destructor = free_netdev;
+	dev->needs_free_netdev = true;
 	ether_setup(dev);
 	dev->priv_flags |= IFF_NO_QUEUE;
 	dev->type = ARPHRD_IEEE80211;
drivers/usb/gadget/function/f_phonet.c +1 -1
@@ -281,7 +281,7 @@ static void pn_net_setup(struct net_devi
 	dev->tx_queue_len	= 1;
 
 	dev->netdev_ops		= &pn_netdev_ops;
-	dev->destructor		= free_netdev;
+	dev->needs_free_netdev	= true;
 	dev->header_ops		= &phonet_header_ops;
 }
 
include/linux/netdevice.h +4 -3
@@ -1581,8 +1581,8 @@ enum netdev_priv_flags {
  *	@rtnl_link_state:	This enum represents the phases of creating
  *				a new link
  *
- *	@destructor:		Called from unregister,
- *				can be used to call free_netdev
+ *	@needs_free_netdev:	Should unregister perform free_netdev?
+ *	@priv_destructor:	Called from unregister
  *	@npinfo:		XXX: need comments on this one
  * 	@nd_net:		Network namespace this network device is inside
  *
@@ -1838,7 +1838,8 @@ struct net_device {
 		RTNL_LINK_INITIALIZING,
 	} rtnl_link_state:16;
 
-	void (*destructor)(struct net_device *dev);
+	bool needs_free_netdev;
+	void (*priv_destructor)(struct net_device *dev);
 
 #ifdef CONFIG_NETPOLL
 	struct netpoll_info __rcu	*npinfo;
net/8021q/vlan_dev.c +2 -2
@@ -807,7 +807,6 @@ static void vlan_dev_free(struct net_dev
 
 	free_percpu(vlan->vlan_pcpu_stats);
 	vlan->vlan_pcpu_stats = NULL;
-	free_netdev(dev);
 }
 
 void vlan_setup(struct net_device *dev)
@@ -820,7 +819,8 @@ void vlan_setup(struct net_device *dev)
 	netif_keep_dst(dev);
 
 	dev->netdev_ops		= &vlan_netdev_ops;
-	dev->destructor		= vlan_dev_free;
+	dev->needs_free_netdev	= true;
+	dev->priv_destructor	= vlan_dev_free;
 	dev->ethtool_ops	= &vlan_ethtool_ops;
 
 	dev->min_mtu		= 0;
net/batman-adv/soft-interface.c +2 -3
@@ -961,8 +961,6 @@ static void batadv_softif_free(struct ne
 	 * netdev and its private data (bat_priv)
 	 */
 	rcu_barrier();
-
-	free_netdev(dev);
 }
 
 /**
@@ -976,7 +974,8 @@ static void batadv_softif_init_early(str
 	ether_setup(dev);
 
 	dev->netdev_ops = &batadv_netdev_ops;
-	dev->destructor = batadv_softif_free;
+	dev->needs_free_netdev = true;
+	dev->priv_destructor = batadv_softif_free;
 	dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL;
 	dev->priv_flags |= IFF_NO_QUEUE;
 
net/bluetooth/6lowpan.c +1 -1
@@ -653,7 +653,7 @@ static void netdev_setup(struct net_devi
 
 	dev->netdev_ops		= &netdev_ops;
 	dev->header_ops		= &header_ops;
-	dev->destructor		= free_netdev;
+	dev->needs_free_netdev	= true;
 }
 
 static struct device_type bt_type = {
net/bridge/br_device.c +1 -1
@@ -379,7 +379,7 @@ void br_dev_setup(struct net_device *dev
 	ether_setup(dev);
 
 	dev->netdev_ops = &br_netdev_ops;
-	dev->destructor = free_netdev;
+	dev->needs_free_netdev = true;
 	dev->ethtool_ops = &br_ethtool_ops;
 	SET_NETDEV_DEVTYPE(dev, &br_type);
 	dev->priv_flags = IFF_EBRIDGE | IFF_NO_QUEUE;
net/caif/chnl_net.c +2 -2
@@ -392,14 +392,14 @@ static void chnl_net_destructor(struct n
 {
 	struct chnl_net *priv = netdev_priv(dev);
 	caif_free_client(&priv->chnl);
-	free_netdev(dev);
 }
 
 static void ipcaif_net_setup(struct net_device *dev)
 {
 	struct chnl_net *priv;
 	dev->netdev_ops = &netdev_ops;
-	dev->destructor = chnl_net_destructor;
+	dev->needs_free_netdev = true;
+	dev->priv_destructor = chnl_net_destructor;
 	dev->flags |= IFF_NOARP;
 	dev->flags |= IFF_POINTOPOINT;
 	dev->mtu = GPRS_PDP_MTU;
net/core/dev.c +6 -2
@@ -7346,6 +7346,8 @@ out:
 err_uninit:
 	if (dev->netdev_ops->ndo_uninit)
 		dev->netdev_ops->ndo_uninit(dev);
+	if (dev->priv_destructor)
+		dev->priv_destructor(dev);
 	goto out;
 }
 EXPORT_SYMBOL(register_netdevice);
@@ -7553,8 +7555,10 @@ void netdev_run_todo(void)
 		WARN_ON(rcu_access_pointer(dev->ip6_ptr));
 		WARN_ON(dev->dn_ptr);
 
-		if (dev->destructor)
-			dev->destructor(dev);
+		if (dev->priv_destructor)
+			dev->priv_destructor(dev);
+		if (dev->needs_free_netdev)
+			free_netdev(dev);
 
 		/* Report a network device has been unregistered */
 		rtnl_lock();
net/hsr/hsr_device.c +2 -2
@@ -378,7 +378,6 @@ static void hsr_dev_destroy(struct net_d
 	del_timer_sync(&hsr->announce_timer);
 
 	synchronize_rcu();
-	free_netdev(hsr_dev);
 }
 
 static const struct net_device_ops hsr_device_ops = {
@@ -404,7 +403,8 @@ void hsr_dev_setup(struct net_device *de
 	SET_NETDEV_DEVTYPE(dev, &hsr_type);
 	dev->priv_flags |= IFF_NO_QUEUE;
 
-	dev->destructor = hsr_dev_destroy;
+	dev->needs_free_netdev = true;
+	dev->priv_destructor = hsr_dev_destroy;
 
 	dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
 			   NETIF_F_GSO_MASK | NETIF_F_HW_CSUM |
net/ieee802154/6lowpan/core.c +1 -1
@@ -107,7 +107,7 @@ static void lowpan_setup(struct net_devi
 
 	ldev->netdev_ops	= &lowpan_netdev_ops;
 	ldev->header_ops	= &lowpan_header_ops;
-	ldev->destructor	= free_netdev;
+	ldev->needs_free_netdev	= true;
 	ldev->features		|= NETIF_F_NETNS_LOCAL;
 }
 
net/ipv4/ip_tunnel.c +2 -2
@@ -961,7 +961,6 @@ static void ip_tunnel_dev_free(struct ne
 	gro_cells_destroy(&tunnel->gro_cells);
 	dst_cache_destroy(&tunnel->dst_cache);
 	free_percpu(dev->tstats);
-	free_netdev(dev);
 }
 
 void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
@@ -1148,7 +1147,8 @@ int ip_tunnel_init(struct net_device *de
 	struct iphdr *iph = &tunnel->parms.iph;
 	int err;
 
-	dev->destructor	= ip_tunnel_dev_free;
+	dev->needs_free_netdev = true;
+	dev->priv_destructor = ip_tunnel_dev_free;
 	dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
 	if (!dev->tstats)
 		return -ENOMEM;
net/ipv4/ipmr.c +1 -1
@@ -501,7 +501,7 @@ static void reg_vif_setup(struct net_dev
 	dev->mtu		= ETH_DATA_LEN - sizeof(struct iphdr) - 8;
 	dev->flags		= IFF_NOARP;
 	dev->netdev_ops		= &reg_vif_netdev_ops;
-	dev->destructor		= free_netdev;
+	dev->needs_free_netdev	= true;
 	dev->features		|= NETIF_F_NETNS_LOCAL;
 }
 
net/ipv6/ip6_gre.c +5 -4
@@ -986,13 +986,13 @@ static void ip6gre_dev_free(struct net_d
 
 	dst_cache_destroy(&t->dst_cache);
 	free_percpu(dev->tstats);
-	free_netdev(dev);
 }
 
 static void ip6gre_tunnel_setup(struct net_device *dev)
 {
 	dev->netdev_ops = &ip6gre_netdev_ops;
-	dev->destructor = ip6gre_dev_free;
+	dev->needs_free_netdev = true;
+	dev->priv_destructor = ip6gre_dev_free;
 
 	dev->type = ARPHRD_IP6GRE;
 
@@ -1143,7 +1143,7 @@ static int __net_init ip6gre_init_net(st
 	return 0;
 
 err_reg_dev:
-	ip6gre_dev_free(ign->fb_tunnel_dev);
+	free_netdev(ign->fb_tunnel_dev);
 err_alloc_dev:
 	return err;
 }
@@ -1292,7 +1292,8 @@ static void ip6gre_tap_setup(struct net_
 	ether_setup(dev);
 
 	dev->netdev_ops = &ip6gre_tap_netdev_ops;
-	dev->destructor = ip6gre_dev_free;
+	dev->needs_free_netdev = true;
+	dev->priv_destructor = ip6gre_dev_free;
 
 	dev->features |= NETIF_F_NETNS_LOCAL;
 	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
net/ipv6/ip6_tunnel.c +4 -4
@@ -254,7 +254,6 @@ static void ip6_dev_free(struct net_devi
 	gro_cells_destroy(&t->gro_cells);
 	dst_cache_destroy(&t->dst_cache);
 	free_percpu(dev->tstats);
-	free_netdev(dev);
 }
 
 static int ip6_tnl_create2(struct net_device *dev)
@@ -322,7 +321,7 @@ static struct ip6_tnl *ip6_tnl_create(st
 	return t;
 
 failed_free:
-	ip6_dev_free(dev);
+	free_netdev(dev);
 failed:
 	return ERR_PTR(err);
 }
@@ -1772,7 +1771,8 @@ static const struct net_device_ops ip6_t
 static void ip6_tnl_dev_setup(struct net_device *dev)
 {
 	dev->netdev_ops = &ip6_tnl_netdev_ops;
-	dev->destructor = ip6_dev_free;
+	dev->needs_free_netdev = true;
+	dev->priv_destructor = ip6_dev_free;
 
 	dev->type = ARPHRD_TUNNEL6;
 	dev->flags |= IFF_NOARP;
@@ -2211,7 +2211,7 @@ static int __net_init ip6_tnl_init_net(s
 	return 0;
 
 err_register:
-	ip6_dev_free(ip6n->fb_tnl_dev);
+	free_netdev(ip6n->fb_tnl_dev);
 err_alloc_dev:
 	return err;
 }
net/ipv6/ip6_vti.c +4 -4
@@ -180,7 +180,6 @@ vti6_tnl_unlink(struct vti6_net *ip6n, s
 static void vti6_dev_free(struct net_device *dev)
 {
 	free_percpu(dev->tstats);
-	free_netdev(dev);
 }
 
 static int vti6_tnl_create2(struct net_device *dev)
@@ -235,7 +234,7 @@ static struct ip6_tnl *vti6_tnl_create(s
 	return t;
 
 failed_free:
-	vti6_dev_free(dev);
+	free_netdev(dev);
 failed:
 	return NULL;
 }
@@ -841,7 +840,8 @@ static const struct net_device_ops vti6_
 static void vti6_dev_setup(struct net_device *dev)
 {
 	dev->netdev_ops = &vti6_netdev_ops;
-	dev->destructor = vti6_dev_free;
+	dev->needs_free_netdev = true;
+	dev->priv_destructor = vti6_dev_free;
 
 	dev->type = ARPHRD_TUNNEL6;
 	dev->hard_header_len = LL_MAX_HEADER + sizeof(struct ipv6hdr);
@@ -1092,7 +1092,7 @@ static int __net_init vti6_init_net(stru
 	return 0;
 
 err_register:
-	vti6_dev_free(ip6n->fb_tnl_dev);
+	free_netdev(ip6n->fb_tnl_dev);
 err_alloc_dev:
 	return err;
 }
net/ipv6/ip6mr.c +1 -1
@@ -733,7 +733,7 @@ static void reg_vif_setup(struct net_dev
 	dev->mtu		= 1500 - sizeof(struct ipv6hdr) - 8;
 	dev->flags		= IFF_NOARP;
 	dev->netdev_ops		= &reg_vif_netdev_ops;
-	dev->destructor		= free_netdev;
+	dev->needs_free_netdev	= true;
 	dev->features		|= NETIF_F_NETNS_LOCAL;
 }
 
net/ipv6/sit.c +3 -3
@@ -265,7 +265,7 @@ static struct ip_tunnel *ipip6_tunnel_lo
 	return nt;
 
 failed_free:
-	ipip6_dev_free(dev);
+	free_netdev(dev);
 failed:
 	return NULL;
 }
@@ -1333,7 +1333,6 @@ static void ipip6_dev_free(struct net_de
 
 	dst_cache_destroy(&tunnel->dst_cache);
 	free_percpu(dev->tstats);
-	free_netdev(dev);
 }
 
 #define SIT_FEATURES (NETIF_F_SG	   | \
@@ -1348,7 +1347,8 @@ static void ipip6_tunnel_setup(struct ne
 	int t_hlen = tunnel->hlen + sizeof(struct iphdr);
 
 	dev->netdev_ops		= &ipip6_netdev_ops;
-	dev->destructor		= ipip6_dev_free;
+	dev->needs_free_netdev	= true;
+	dev->priv_destructor	= ipip6_dev_free;
 
 	dev->type		= ARPHRD_SIT;
 	dev->hard_header_len	= LL_MAX_HEADER + t_hlen;
net/irda/irlan/irlan_eth.c +1 -1
@@ -65,7 +65,7 @@ static void irlan_eth_setup(struct net_d
 	ether_setup(dev);
 
 	dev->netdev_ops		= &irlan_eth_netdev_ops;
-	dev->destructor		= free_netdev;
+	dev->needs_free_netdev	= true;
 	dev->min_mtu		= 0;
 	dev->max_mtu		= ETH_MAX_MTU;
 
net/l2tp/l2tp_eth.c +1 -1
@@ -133,7 +133,7 @@ static void l2tp_eth_dev_setup(struct ne
 	dev->priv_flags		&= ~IFF_TX_SKB_SHARING;
 	dev->features		|= NETIF_F_LLTX;
 	dev->netdev_ops		= &l2tp_eth_netdev_ops;
-	dev->destructor		= free_netdev;
+	dev->needs_free_netdev	= true;
 }
 
 static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len)
net/mac80211/iface.c +3 -3
@@ -1198,7 +1198,6 @@ static const struct net_device_ops ieee8
 static void ieee80211_if_free(struct net_device *dev)
 {
 	free_percpu(dev->tstats);
-	free_netdev(dev);
 }
 
 static void ieee80211_if_setup(struct net_device *dev)
@@ -1206,7 +1205,8 @@ static void ieee80211_if_setup(struct ne
 	ether_setup(dev);
 	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 	dev->netdev_ops = &ieee80211_dataif_ops;
-	dev->destructor = ieee80211_if_free;
+	dev->needs_free_netdev = true;
+	dev->priv_destructor = ieee80211_if_free;
 }
 
 static void ieee80211_if_setup_no_queue(struct net_device *dev)
@@ -1899,7 +1899,7 @@ int ieee80211_if_add(struct ieee80211_lo
 
 		ret = register_netdevice(ndev);
 		if (ret) {
-			ieee80211_if_free(ndev);
+			free_netdev(ndev);
 			return ret;
 		}
 	}
net/mac802154/iface.c +3 -4
@@ -526,8 +526,6 @@ static void mac802154_wpan_free(struct n
 	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
 
 	mac802154_llsec_destroy(&sdata->sec);
-
-	free_netdev(dev);
 }
 
 static void ieee802154_if_setup(struct net_device *dev)
@@ -593,7 +591,8 @@ ieee802154_setup_sdata(struct ieee802154
 					sdata->dev->dev_addr);
 
 		sdata->dev->header_ops = &mac802154_header_ops;
-		sdata->dev->destructor = mac802154_wpan_free;
+		sdata->dev->needs_free_netdev = true;
+		sdata->dev->priv_destructor = mac802154_wpan_free;
 		sdata->dev->netdev_ops = &mac802154_wpan_ops;
 		sdata->dev->ml_priv = &mac802154_mlme_wpan;
 		wpan_dev->promiscuous_mode = false;
@@ -608,7 +607,7 @@ ieee802154_setup_sdata(struct ieee802154
 
 		break;
 	case NL802154_IFTYPE_MONITOR:
-		sdata->dev->destructor = free_netdev;
+		sdata->dev->needs_free_netdev = true;
 		sdata->dev->netdev_ops = &mac802154_monitor_ops;
 		wpan_dev->promiscuous_mode = true;
 		break;
net/openvswitch/vport-internal_dev.c +2 -2
@@ -94,7 +94,6 @@ static void internal_dev_destructor(stru
 	struct vport *vport = ovs_internal_dev_get_vport(dev);
 
 	ovs_vport_free(vport);
-	free_netdev(dev);
 }
 
 static void
@@ -156,7 +155,8 @@ static void do_setup(struct net_device *
 	netdev->priv_flags &= ~IFF_TX_SKB_SHARING;
 	netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_OPENVSWITCH |
 			      IFF_PHONY_HEADROOM | IFF_NO_QUEUE;
-	netdev->destructor = internal_dev_destructor;
+	netdev->needs_free_netdev = true;
+	netdev->priv_destructor = internal_dev_destructor;
 	netdev->ethtool_ops = &internal_dev_ethtool_ops;
 	netdev->rtnl_link_ops = &internal_dev_link_ops;
 
net/phonet/pep-gprs.c +1 -1
@@ -236,7 +236,7 @@ static void gprs_setup(struct net_device
 	dev->tx_queue_len	= 10;
 
 	dev->netdev_ops		= &gprs_netdev_ops;
-	dev->destructor		= free_netdev;
+	dev->needs_free_netdev	= true;
 }
 
 /*
author maintainer
#3 lore raw

PATCH 3/84 net: s390: fix up for "Fix inconsistent teardown and release of private netdev state"

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Stephen Rothwell <[email protected]>

[ Upstream commit cd1997f6c11483da819a7719aa013093b8003743 ]

---
 drivers/s390/net/netiucv.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/s390/net/netiucv.c +2 -2
@@ -1954,7 +1954,6 @@ static void netiucv_free_netdevice(struc
 		privptr->conn = NULL; privptr->fsm = NULL;
 		/* privptr gets freed by free_netdev() */
 	}
-	free_netdev(dev);
 }
 
 /**
@@ -1972,7 +1971,8 @@ static void netiucv_setup_netdevice(stru
 	dev->mtu	         = NETIUCV_MTU_DEFAULT;
 	dev->min_mtu		 = 576;
 	dev->max_mtu		 = NETIUCV_MTU_MAX;
-	dev->destructor          = netiucv_free_netdevice;
+	dev->needs_free_netdev   = true;
+	dev->priv_destructor     = netiucv_free_netdevice;
 	dev->hard_header_len     = NETIUCV_HDRLEN;
 	dev->addr_len            = 0;
 	dev->type                = ARPHRD_SLIP;
author maintainer
#4 lore raw

PATCH 4/84 mac80211: free netdev on dev_alloc_name() error

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Johannes Berg <[email protected]>

[ Upstream commit c7a61cba71fd151cc7d9ebe53a090e0e61eeebf3 ]

The change to remove free_netdev() from ieee80211_if_free() erroneously didn't add the necessary free_netdev() for when ieee80211_if_free() is called directly in one place, rather than as the priv_destructor. Add the missing call.

Fixes cf124db566e6 ("net: Fix inconsistent teardown and release of private netdev state.")
---
 net/mac80211/iface.c |    1 +
 1 file changed, 1 insertion(+)
net/mac80211/iface.c +1 -0
@@ -1810,6 +1810,7 @@ int ieee80211_if_add(struct ieee80211_lo
 		ret = dev_alloc_name(ndev, ndev->name);
 		if (ret < 0) {
 			ieee80211_if_free(ndev);
+			free_netdev(ndev);
 			return ret;
 		}
 
author maintainer
#5 lore raw

PATCH 5/84 decnet: dn_rtmsg: Improve input length sanitization in dnrmg_receive_user_skb

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Mateusz Jurczyk <[email protected]>

[ Upstream commit dd0da17b209ed91f39872766634ca967c170ada1 ]

Verify that the length of the socket buffer is sufficient to cover the nlmsghdr structure before accessing the nlh->nlmsg_len field for further input sanitization. If the client only supplies 1-3 bytes of data in sk_buff, then nlh->nlmsg_len remains partially uninitialized and contains leftover memory from the corresponding kernel allocation. Operating on such data may result in indeterminate evaluation of the nlmsg_len < sizeof(*nlh) expression.

The bug was discovered by a runtime instrumentation designed to detect use of uninitialized memory in the kernel. The patch prevents this and other similar tools (e.g. KMSAN) from flagging this behavior in the future.

---
 net/decnet/netfilter/dn_rtmsg.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
net/decnet/netfilter/dn_rtmsg.c +3 -1
@@ -102,7 +102,9 @@ static inline void dnrmg_receive_user_sk
 {
 	struct nlmsghdr *nlh = nlmsg_hdr(skb);
 
-	if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
+	if (skb->len < sizeof(*nlh) ||
+	    nlh->nlmsg_len < sizeof(*nlh) ||
+	    skb->len < nlh->nlmsg_len)
 		return;
 
 	if (!netlink_capable(skb, CAP_NET_ADMIN))
author maintainer
#6 lore raw

PATCH 6/84 net: Zero ifla_vf_info in rtnl_fill_vfinfo()

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: "Mintz, Yuval" <[email protected]>

[ Upstream commit 0eed9cf58446b28b233388b7f224cbca268b6986 ]

Some of the structure's fields are not initialized by the rtnetlink. If driver doesn't set those in ndo_get_vf_config(), they'd leak memory to user.

---
 net/core/rtnetlink.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/core/rtnetlink.c +2 -1
@@ -1127,6 +1127,8 @@ static noinline_for_stack int rtnl_fill_
 	struct ifla_vf_mac vf_mac;
 	struct ifla_vf_info ivi;
 
+	memset(&ivi, 0, sizeof(ivi));
+
 	/* Not all SR-IOV capable drivers support the
 	 * spoofcheck and "RSS query enable" query.  Preset to
 	 * -1 so the user space tool can detect that the driver
@@ -1135,7 +1137,6 @@ static noinline_for_stack int rtnl_fill_
 	ivi.spoofchk = -1;
 	ivi.rss_query_en = -1;
 	ivi.trusted = -1;
-	memset(ivi.mac, 0, sizeof(ivi.mac));
 	/* The default value for VF link state is "auto"
 	 * IFLA_VF_LINK_STATE_AUTO which equals zero
 	 */
author maintainer
#7 lore raw

PATCH 7/84 net: ipv6: Release route when device is unregistering

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: David Ahern <[email protected]>

[ Upstream commit 8397ed36b7c585f8d3e06c431f4137309124f78f ]

Roopa reported attempts to delete a bond device that is referenced in a multipath route is hanging:

$ ifdown bond2    # ifupdown2 command that deletes virtual devices
unregister_netdevice: waiting for bond2 to become free. Usage count = 2

Steps to reproduce:
echo 1 > /proc/sys/net/ipv6/conf/all/ignore_routes_with_linkdown
ip link add dev bond12 type bond
ip link add dev bond13 type bond
ip addr add 2001:db8:2::0/64 dev bond12
ip addr add 2001:db8:3::0/64 dev bond13
ip route add 2001:db8:33::0/64 nexthop via 2001:db8:2::2 nexthop via 2001:db8:3::2 ip link del dev bond12
ip link del dev bond13

The root cause is the recent change to keep routes on a linkdown. Update the check to detect when the device is unregistering and release the route for that case.

Fixes a1a22c12060e4 ("net: ipv6: Keep nexthop of multipath route on admin down")
---
 include/linux/netdevice.h |    5 +++++
 net/ipv6/route.c          |    1 +
 2 files changed, 6 insertions(+)
include/linux/netdevice.h +5 -0
@@ -4232,6 +4232,11 @@ static inline const char *netdev_name(co
 	return dev->name;
 }
 
+static inline bool netdev_unregistering(const struct net_device *dev)
+{
+	return dev->reg_state == NETREG_UNREGISTERING;
+}
+
 static inline const char *netdev_reg_state(const struct net_device *dev)
 {
 	switch (dev->reg_state) {
net/ipv6/route.c +1 -0
@@ -2804,6 +2804,7 @@ static int fib6_ifdown(struct rt6_info *
 	if ((rt->dst.dev == dev || !dev) &&
 	    rt != adn->net->ipv6.ip6_null_entry &&
 	    (rt->rt6i_nsiblings == 0 ||
+	     (dev && netdev_unregistering(dev)) ||
 	     !rt->rt6i_idev->cnf.ignore_routes_with_linkdown))
 		return -1;
 
author maintainer
#8 lore raw

PATCH 8/84 net: vrf: Make add_fib_rules per network namespace flag

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: David Ahern <[email protected]>

[ Upstream commit 097d3c9508dc58286344e4a22b300098cf0c1566 ]

Commit 1aa6c4f6b8cd8 ("net: vrf: Add l3mdev rules on first device create") adds the l3mdev FIB rule the first time a VRF device is created. However, it only creates the rule once and only in the namespace the first device is created - which may not be init_net. Fix by using the net_generic capability to make the add_fib_rules flag per network namespace.

Fixes 1aa6c4f6b8cd8 ("net: vrf: Add l3mdev rules on first device create")
---
 drivers/net/vrf.c |   36 ++++++++++++++++++++++++++++++++----
 1 file changed, 32 insertions(+), 4 deletions(-)
drivers/net/vrf.c +32 -4
@@ -36,12 +36,14 @@
 #include <net/addrconf.h>
 #include <net/l3mdev.h>
 #include <net/fib_rules.h>
+#include <net/netns/generic.h>
 
 #define DRV_NAME	"vrf"
 #define DRV_VERSION	"1.0"
 
 #define FIB_RULE_PREF  1000       /* default preference for FIB rules */
-static bool add_fib_rules = true;
+
+static unsigned int vrf_net_id;
 
 struct net_vrf {
 	struct rtable __rcu	*rth;
@@ -1252,6 +1254,8 @@ static int vrf_newlink(struct net *src_n
 		       struct nlattr *tb[], struct nlattr *data[])
 {
 	struct net_vrf *vrf = netdev_priv(dev);
+	bool *add_fib_rules;
+	struct net *net;
 	int err;
 
 	if (!data || !data[IFLA_VRF_TABLE])
@@ -1267,13 +1271,15 @@ static int vrf_newlink(struct net *src_n
 	if (err)
 		goto out;
 
-	if (add_fib_rules) {
+	net = dev_net(dev);
+	add_fib_rules = net_generic(net, vrf_net_id);
+	if (*add_fib_rules) {
 		err = vrf_add_fib_rules(dev);
 		if (err) {
 			unregister_netdevice(dev);
 			goto out;
 		}
-		add_fib_rules = false;
+		*add_fib_rules = false;
 	}
 
 out:
@@ -1356,16 +1362,38 @@ static struct notifier_block vrf_notifie
 	.notifier_call = vrf_device_event,
 };
 
+/* Initialize per network namespace state */
+static int __net_init vrf_netns_init(struct net *net)
+{
+	bool *add_fib_rules = net_generic(net, vrf_net_id);
+
+	*add_fib_rules = true;
+
+	return 0;
+}
+
+static struct pernet_operations vrf_net_ops __net_initdata = {
+	.init = vrf_netns_init,
+	.id   = &vrf_net_id,
+	.size = sizeof(bool),
+};
+
 static int __init vrf_init_module(void)
 {
 	int rc;
 
 	register_netdevice_notifier(&vrf_notifier_block);
 
-	rc = rtnl_link_register(&vrf_link_ops);
+	rc = register_pernet_subsys(&vrf_net_ops);
 	if (rc < 0)
 		goto error;
 
+	rc = rtnl_link_register(&vrf_link_ops);
+	if (rc < 0) {
+		unregister_pernet_subsys(&vrf_net_ops);
+		goto error;
+	}
+
 	return 0;
 
 error:
author maintainer
#9 lore raw

PATCH 9/84 af_unix: Add sockaddr length checks before accessing sa_family in bind and connect handlers

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Mateusz Jurczyk <[email protected]>

[ Upstream commit defbcf2decc903a28d8398aa477b6881e711e3ea ]

Verify that the caller-provided sockaddr structure is large enough to contain the sa_family field, before accessing it in bind() and connect() handlers of the AF_UNIX socket. Since neither syscall enforces a minimum size of the corresponding memory region, very short sockaddrs (zero or one byte long) result in operating on uninitialized memory while referencing .sa_family.

---
 net/unix/af_unix.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
net/unix/af_unix.c +6 -1
@@ -999,7 +999,8 @@ static int unix_bind(struct socket *sock
 	struct path path = { NULL, NULL };
 
 	err = -EINVAL;
-	if (sunaddr->sun_family != AF_UNIX)
+	if (addr_len < offsetofend(struct sockaddr_un, sun_family) ||
+	    sunaddr->sun_family != AF_UNIX)
 		goto out;
 
 	if (addr_len == sizeof(short)) {
@@ -1110,6 +1111,10 @@ static int unix_dgram_connect(struct soc
 	unsigned int hash;
 	int err;
 
+	err = -EINVAL;
+	if (alen < offsetofend(struct sockaddr, sa_family))
+		goto out;
+
 	if (addr->sa_family != AF_UNSPEC) {
 		err = unix_mkname(sunaddr, alen, &hash);
 		if (err < 0)
author maintainer
#10 lore raw

PATCH 10/84 Fix an intermittent pr_emerg warning about lo becoming free.

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Krister Johansen <[email protected]>

[ Upstream commit f186ce61bb8235d80068c390dc2aad7ca427a4c2 ]

It looks like this:

Message from syslogd@flamingo at Apr 26 00:45:00 ...
kernel:unregister_netdevice: waiting for lo to become free. Usage count = 4

They seem to coincide with net namespace teardown.

The message is emitted by netdev_wait_allrefs().

Forced a kdump in netdev_run_todo, but found that the refcount on the lo device was already 0 at the time we got to the panic.

Used bcc to check the blocking in netdev_run_todo. The only places where we're off cpu there are in the rcu_barrier() and msleep() calls. That behavior is expected. The msleep time coincides with the amount of time we spend waiting for the refcount to reach zero; the rcu_barrier() wait times are not excessive.

After looking through the list of callbacks that the netdevice notifiers invoke in this path, it appears that the dst_dev_event is the most interesting. The dst_ifdown path places a hold on the loopback_dev as part of releasing the dev associated with the original dst cache entry. Most of our notifier callbacks are straight-forward, but this one a) looks complex, and b) places a hold on the network interface in question.

I constructed a new bcc script that watches various events in the liftime of a dst cache entry. Note that dst_ifdown will take a hold on the loopback device until the invalidated dst entry gets freed.

[ __dst_free] on DST: ffff883ccabb7900 IF tap1008300eth0 invoked at 1282115677036183

    __dst_free
    rcu_nocb_kthread
    kthread
    ret_from_fork
---
 net/core/dst.c |   14 ++++++++++++++
 1 file changed, 14 insertions(+)
net/core/dst.c +14 -0
@@ -469,6 +469,20 @@ static int dst_dev_event(struct notifier
 		spin_lock_bh(&dst_garbage.lock);
 		dst = dst_garbage.list;
 		dst_garbage.list = NULL;
+		/* The code in dst_ifdown places a hold on the loopback device.
+		 * If the gc entry processing is set to expire after a lengthy
+		 * interval, this hold can cause netdev_wait_allrefs() to hang
+		 * out and wait for a long time -- until the the loopback
+		 * interface is released.  If we're really unlucky, it'll emit
+		 * pr_emerg messages to console too.  Reset the interval here,
+		 * so dst cleanups occur in a more timely fashion.
+		 */
+		if (dst_garbage.timer_inc > DST_GC_INC) {
+			dst_garbage.timer_inc = DST_GC_INC;
+			dst_garbage.timer_expires = DST_GC_MIN;
+			mod_delayed_work(system_wq, &dst_gc_work,
+					 dst_garbage.timer_expires);
+		}
 		spin_unlock_bh(&dst_garbage.lock);
 
 		if (last)
author maintainer
#11 lore raw

PATCH 11/84 sctp: disable BH in sctp_for_each_endpoint

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Xin Long <[email protected]>

[ Upstream commit 581409dacc9176b0de1f6c4ca8d66e13aa8e1b29 ]

Now sctp holds read_lock when foreach sctp_ep_hashtable without disabling BH. If CPU schedules to another thread A at this moment, the thread A may be trying to hold the write_lock with disabling BH.

As BH is disabled and CPU cannot schedule back to the thread holding the read_lock, while the thread A keeps waiting for the read_lock. A dead lock would be triggered by this.

This patch is to fix this dead lock by calling read_lock_bh instead to disable BH when holding the read_lock in sctp_for_each_endpoint.

Fixes 626d16f50f39 ("sctp: export some apis or variables for sctp_diag and reuse some for proc")
---
 net/sctp/socket.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/sctp/socket.c +2 -2
@@ -4586,13 +4586,13 @@ int sctp_for_each_endpoint(int (*cb)(str
 
 	for (head = sctp_ep_hashtable; hash < sctp_ep_hashsize;
 	     hash++, head++) {
-		read_lock(&head->lock);
+		read_lock_bh(&head->lock);
 		sctp_for_each_hentry(epb, &head->chain) {
 			err = cb(sctp_ep(epb), p);
 			if (err)
 				break;
 		}
-		read_unlock(&head->lock);
+		read_unlock_bh(&head->lock);
 	}
 
 	return err;
author maintainer
#12 lore raw

PATCH 12/84 net: caif: Fix a sleep-in-atomic bug in cfpkt_create_pfx

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Jia-Ju Bai <[email protected]>

[ Upstream commit f146e872eb12ebbe92d8e583b2637e0741440db3 ]

The kernel may sleep under a rcu read lock in cfpkt_create_pfx, and the function call path is:
cfcnfg_linkup_rsp (acquire the lock by rcu_read_lock)
cfctrl_linkdown_req

    cfpkt_create
      cfpkt_create_pfx
        alloc_skb(GFP_KERNEL) --> may sleep
cfserl_receive (acquire the lock by rcu_read_lock)
  cfpkt_split
    cfpkt_create_pfx
      alloc_skb(GFP_KERNEL) --> may sleep

There is "in_interrupt" in cfpkt_create_pfx to decide use "GFP_KERNEL" or "GFP_ATOMIC". In this situation, "GFP_KERNEL" is used because the function is called under a rcu read lock, instead in interrupt.

To fix it, only "GFP_ATOMIC" is used in cfpkt_create_pfx.

---
 net/caif/cfpkt_skbuff.c |    6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
net/caif/cfpkt_skbuff.c +1 -5
@@ -81,11 +81,7 @@ static struct cfpkt *cfpkt_create_pfx(u1
 {
 	struct sk_buff *skb;
 
-	if (likely(in_interrupt()))
-		skb = alloc_skb(len + pfx, GFP_ATOMIC);
-	else
-		skb = alloc_skb(len + pfx, GFP_KERNEL);
-
+	skb = alloc_skb(len + pfx, GFP_ATOMIC);
 	if (unlikely(skb == NULL))
 		return NULL;
 
author maintainer
#13 lore raw

PATCH 13/84 net: tipc: Fix a sleep-in-atomic bug in tipc_msg_reverse

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Jia-Ju Bai <[email protected]>

[ Upstream commit 343eba69c6968190d8654b857aea952fed9a6749 ]

The kernel may sleep under a rcu read lock in tipc_msg_reverse, and the function call path is:
tipc_l2_rcv_msg (acquire the lock by rcu_read_lock)
tipc_rcv

    tipc_sk_rcv
      tipc_msg_reverse
        pskb_expand_head(GFP_KERNEL) --> may sleep
tipc_node_broadcast
  tipc_node_xmit_skb
    tipc_node_xmit
      tipc_sk_rcv
        tipc_msg_reverse
          pskb_expand_head(GFP_KERNEL) --> may sleep

To fix it, "GFP_KERNEL" is replaced with "GFP_ATOMIC".

---
 net/tipc/msg.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/tipc/msg.c +1 -1
@@ -508,7 +508,7 @@ bool tipc_msg_reverse(u32 own_node,  str
 	}
 
 	if (skb_cloned(_skb) &&
-	    pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_KERNEL))
+	    pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_ATOMIC))
 		goto exit;
 
 	/* Now reverse the concerned fields */
author maintainer
#14 lore raw

PATCH 14/84 net/mlx5: Remove several module events out of ethtool stats

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Huy Nguyen <[email protected]>

[ Upstream commit f729860a177d097ac44321fb2f7d927a0c54c5a3 ]

Remove the following module event counters out of ethtool stats. The reason for removing these event counters is that these events do not occur without techinician's intervention.
module_pwr_budget_exd
module_long_range
module_no_eeprom
module_enforce_part
module_unknown_id
module_unknown_status
module_plug

Fixes bedb7c909c19 ("net/mlx5e: Add port module event counters to ethtool stats")

Reviewed by: Gal Pressman <[email protected]>

---
 drivers/net/ethernet/mellanox/mlx5/core/en_stats.h |   11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_stats.h +2 -9
@@ -417,20 +417,13 @@ struct mlx5e_stats {
 };
 
 static const struct counter_desc mlx5e_pme_status_desc[] = {
-	{ "module_plug", 0 },
 	{ "module_unplug", 8 },
 };
 
 static const struct counter_desc mlx5e_pme_error_desc[] = {
-	{ "module_pwr_budget_exd", 0 },  /* power budget exceed */
-	{ "module_long_range", 8 },      /* long range for non MLNX cable */
-	{ "module_bus_stuck", 16 },      /* bus stuck (I2C or data shorted) */
-	{ "module_no_eeprom", 24 },      /* no eeprom/retry time out */
-	{ "module_enforce_part", 32 },   /* enforce part number list */
-	{ "module_unknown_id", 40 },     /* unknown identifier */
-	{ "module_high_temp", 48 },      /* high temperature */
+	{ "module_bus_stuck", 16 },       /* bus stuck (I2C or data shorted) */
+	{ "module_high_temp", 48 },       /* high temperature */
 	{ "module_bad_shorted", 56 },    /* bad or shorted cable/module */
-	{ "module_unknown_status", 64 },
 };
 
 #endif /* __MLX5_EN_STATS_H__ */
author maintainer
#15 lore raw

PATCH 15/84 net/mlx5e: Added BW check for DIM decision mechanism

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Tal Gilboa <[email protected]>

[ Upstream commit c3164d2fc48fd4fa0477ab658b644559c3fe9073 ]

DIM (Dynamically-tuned Interrupt Moderation) is a mechanism designed for changing the channel interrupt moderation values in order to reduce CPU overhead for all traffic types.
Until now only interrupt and packet rate were sampled.
We found a scenario on which we get a false indication since a change in DIM caused more aggregation and reduced packet rate while increasing BW.

We now regard a change as succesfull iff:
current_BW > (prev_BW + threshold) or
current_BW ~= prev_BW and current_PR > (prev_PR + threshold) or current_BW ~= prev_BW and current_PR ~= prev_PR and
current_IR < (prev_IR - threshold)
Where BW = Bandwidth, PR = Packet rate and IR = Interrupt rate

Improvements (ConnectX-4Lx 25GbE, single RX queue, LRO off)

    --------------------------------------------------
    packet size | before[Mb/s] | after[Mb/s] | gain  |
    2B          | 343.4        | 359.4       |  4.5% |
    16B         | 2739.7       | 2814.8      |  2.7% |
    64B         | 9739         | 10185.3     |  4.5% |
Fixes cb3c7fd4f839 ("net/mlx5e: Support adaptive RX coalescing")
---
 drivers/net/ethernet/mellanox/mlx5/core/en.h       |    2 +
 drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c |   41 +++++++++++----------
 2 files changed, 24 insertions(+), 19 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en.h +2 -0
@@ -313,12 +313,14 @@ struct mlx5e_dma_info {
 
 struct mlx5e_rx_am_stats {
 	int ppms; /* packets per msec */
+	int bpms; /* bytes per msec */
 	int epms; /* events per msec */
 };
 
 struct mlx5e_rx_am_sample {
 	ktime_t		time;
 	unsigned int	pkt_ctr;
+	unsigned int    byte_ctr;
 	u16		event_ctr;
 };
 
drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c +22 -19

68 lines not on this page · raw message

author maintainer
#16 lore raw

PATCH 16/84 net/mlx5e: Fix wrong indications in DIM due to counter wraparound

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Tal Gilboa <[email protected]>

[ Upstream commit 53acd76ce571e3b71f9205f2d49ab285a9f1aad8 ]

DIM (Dynamically-tuned Interrupt Moderation) is a mechanism designed for changing the channel interrupt moderation values in order to reduce CPU overhead for all traffic types.
Each iteration of the algorithm, DIM calculates the difference in throughput, packet rate and interrupt rate from last iteration in order to make a decision. DIM relies on counters for each metric. When these counters get to their type's max value they wraparound. In this case the delta between 'end' and 'start' samples is negative and when translated to unsigned integers - very high. This results in a false indication to the algorithm and might result in a wrong decision.

The fix calculates the 'distance' between 'end' and 'start' samples in a cyclic way around the relevant type's max value. It can also be viewed as an absolute value around the type's max value instead of around 0.

Testing show higher stability in DIM profile selection and no wraparound issues.

Fixes cb3c7fd4f839 ("net/mlx5e: Support adaptive RX coalescing")
---
 drivers/net/ethernet/mellanox/mlx5/core/en.h       |    8 ++++----
 drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c |   10 +++++++---
 2 files changed, 11 insertions(+), 7 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en.h +4 -4
@@ -318,10 +318,10 @@ struct mlx5e_rx_am_stats {
 };
 
 struct mlx5e_rx_am_sample {
-	ktime_t		time;
-	unsigned int	pkt_ctr;
-	unsigned int    byte_ctr;
-	u16		event_ctr;
+	ktime_t	time;
+	u32	pkt_ctr;
+	u32	byte_ctr;
+	u16	event_ctr;
 };
 
 struct mlx5e_rx_am { /* Adaptive Moderation */
drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c +7 -3
@@ -270,6 +270,8 @@ static void mlx5e_am_sample(struct mlx5e
 }
 
 #define MLX5E_AM_NEVENTS 64
+#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
+#define BIT_GAP(bits, end, start) ((((end) - (start)) + BIT_ULL(bits)) & (BIT_ULL(bits) - 1))
 
 static void mlx5e_am_calc_stats(struct mlx5e_rx_am_sample *start,
 				struct mlx5e_rx_am_sample *end,
@@ -277,8 +279,9 @@ static void mlx5e_am_calc_stats(struct m
 {
 	/* u32 holds up to 71 minutes, should be enough */
 	u32 delta_us = ktime_us_delta(end->time, start->time);
-	unsigned int npkts = end->pkt_ctr - start->pkt_ctr;
-	unsigned int nbytes = end->byte_ctr - start->byte_ctr;
+	u32 npkts = BIT_GAP(BITS_PER_TYPE(u32), end->pkt_ctr, start->pkt_ctr);
+	u32 nbytes = BIT_GAP(BITS_PER_TYPE(u32), end->byte_ctr,
+			     start->byte_ctr);
 
 	if (!delta_us)
 		return;
@@ -311,7 +314,8 @@ void mlx5e_rx_am(struct mlx5e_rq *rq)
 
 	switch (am->state) {
 	case MLX5E_AM_MEASURE_IN_PROGRESS:
-		nevents = rq->cq.event_ctr - am->start_sample.event_ctr;
+		nevents = BIT_GAP(BITS_PER_TYPE(u16), rq->cq.event_ctr,
+				  am->start_sample.event_ctr);
 		if (nevents < MLX5E_AM_NEVENTS)
 			break;
 		mlx5e_am_sample(rq, &end_sample);
author maintainer
#17 lore raw

PATCH 17/84 net/mlx5: Enable 4K UAR only when page size is bigger than 4K

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Majd Dibbiny <[email protected]>

[ Upstream commit 91828bd89940e8145f91751a015bc11bc486aad0 ]

When the page size isn't bigger than 4K, there is no added value of enabling 4K UAR feature in the Firmware.

Modified the condition of enabling the 4K UAR accordingly.

Fixes f502d834950a ("net/mlx5: Activate support for 4K UARs")
---
 drivers/net/ethernet/mellanox/mlx5/core/main.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/main.c +4 -2
@@ -537,8 +537,10 @@ static int handle_hca_cap(struct mlx5_co
 	/* disable cmdif checksum */
 	MLX5_SET(cmd_hca_cap, set_hca_cap, cmdif_checksum, 0);
 
-	/* If the HCA supports 4K UARs use it */
-	if (MLX5_CAP_GEN_MAX(dev, uar_4k))
+	/* Enable 4K UAR only when HCA supports it and page size is bigger
+	 * than 4K.
+	 */
+	if (MLX5_CAP_GEN_MAX(dev, uar_4k) && PAGE_SIZE > 4096)
 		MLX5_SET(cmd_hca_cap, set_hca_cap, uar_4k, 1);
 
 	MLX5_SET(cmd_hca_cap, set_hca_cap, log_uar_page_sz, PAGE_SHIFT - 12);
author maintainer
#18 lore raw

PATCH 18/84 proc: snmp6: Use correct type in memset

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Christian Perle <[email protected]>

[ Upstream commit 3500cd73dff48f28f4ba80c171c4c80034d40f76 ]

Reading /proc/net/snmp6 yields bogus values on 32 bit kernels. Use "u64" instead of "unsigned long" in sizeof().

Fixes 4a4857b1c81e ("proc: Reduce cache miss in snmp6_seq_show")
---
 net/ipv6/proc.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv6/proc.c +1 -1
@@ -219,7 +219,7 @@ static void snmp6_seq_show_item64(struct
 	u64 buff64[SNMP_MIB_MAX];
 	int i;
 
-	memset(buff64, 0, sizeof(unsigned long) * SNMP_MIB_MAX);
+	memset(buff64, 0, sizeof(u64) * SNMP_MIB_MAX);
 
 	snmp_get_cpu_field64_batch(buff64, itemlist, mib, syncpoff);
 	for (i = 0; itemlist[i].name; i++)
author maintainer
#19 lore raw

PATCH 19/84 igmp: acquire pmc lock for ip_mc_clear_src()

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: WANG Cong <[email protected]>

[ Upstream commit c38b7d327aafd1e3ad7ff53eefac990673b65667 ]

Andrey reported a use-after-free in add_grec():

        for (psf = *psf_list; psf; psf = psf_next) {
		...
                psf_next = psf->sf_next;

where the struct ip_sf_list's were already freed by:

 kfree+0xe8/0x2b0 mm/slub.c:3882
 ip_mc_clear_src+0x69/0x1c0 net/ipv4/igmp.c:2078
 ip_mc_dec_group+0x19a/0x470 net/ipv4/igmp.c:1618
 ip_mc_drop_socket+0x145/0x230 net/ipv4/igmp.c:2609
 inet_release+0x4e/0x1c0 net/ipv4/af_inet.c:411
 sock_release+0x8d/0x1e0 net/socket.c:597
 sock_close+0x16/0x20 net/socket.c:1072

This happens because we don't hold pmc->lock in ip_mc_clear_src() and a parallel mr_ifc_timer timer could jump in and access them.

The RCU lock is there but it is merely for pmc itself, this spinlock could actually ensure we don't access them in parallel.

Thanks to Eric and Long for discussion on this bug.

---
 net/ipv4/igmp.c |   21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)
net/ipv4/igmp.c +13 -8
@@ -2071,21 +2071,26 @@ static int ip_mc_add_src(struct in_devic
 
 static void ip_mc_clear_src(struct ip_mc_list *pmc)
 {
-	struct ip_sf_list *psf, *nextpsf;
+	struct ip_sf_list *psf, *nextpsf, *tomb, *sources;
 
-	for (psf = pmc->tomb; psf; psf = nextpsf) {
+	spin_lock_bh(&pmc->lock);
+	tomb = pmc->tomb;
+	pmc->tomb = NULL;
+	sources = pmc->sources;
+	pmc->sources = NULL;
+	pmc->sfmode = MCAST_EXCLUDE;
+	pmc->sfcount[MCAST_INCLUDE] = 0;
+	pmc->sfcount[MCAST_EXCLUDE] = 1;
+	spin_unlock_bh(&pmc->lock);
+
+	for (psf = tomb; psf; psf = nextpsf) {
 		nextpsf = psf->sf_next;
 		kfree(psf);
 	}
-	pmc->tomb = NULL;
-	for (psf = pmc->sources; psf; psf = nextpsf) {
+	for (psf = sources; psf; psf = nextpsf) {
 		nextpsf = psf->sf_next;
 		kfree(psf);
 	}
-	pmc->sources = NULL;
-	pmc->sfmode = MCAST_EXCLUDE;
-	pmc->sfcount[MCAST_INCLUDE] = 0;
-	pmc->sfcount[MCAST_EXCLUDE] = 1;
 }
 
 /* Join a multicast group
author maintainer
#20 lore raw

PATCH 20/84 igmp: add a missing spin_lock_init()

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: WANG Cong <[email protected]>

[ Upstream commit b4846fc3c8559649277e3e4e6b5cec5348a8d208 ]

Andrey reported a lockdep warning on non-initialized spinlock:

INFO: trying to register non-static key.
the code is fine but needs lockdep annotation.
turning off the locking correctness validator.

 CPU: 1 PID: 4099 Comm: a.out Not tainted 4.12.0-rc6+ #9
 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
 Call Trace:
  __dump_stack lib/dump_stack.c:16
  dump_stack+0x292/0x395 lib/dump_stack.c:52
  register_lock_class+0x717/0x1aa0 kernel/locking/lockdep.c:755
  ? 0xffffffffa0000000
  __lock_acquire+0x269/0x3690 kernel/locking/lockdep.c:3255
  lock_acquire+0x22d/0x560 kernel/locking/lockdep.c:3855
  __raw_spin_lock_bh ./include/linux/spinlock_api_smp.h:135
  _raw_spin_lock_bh+0x36/0x50 kernel/locking/spinlock.c:175
  spin_lock_bh ./include/linux/spinlock.h:304
  ip_mc_clear_src+0x27/0x1e0 net/ipv4/igmp.c:2076
  igmpv3_clear_delrec+0xee/0x4f0 net/ipv4/igmp.c:1194
  ip_mc_destroy_dev+0x4e/0x190 net/ipv4/igmp.c:1736

We miss a spin_lock_init() in igmpv3_add_delrec(), probably because previously we never use it on this code path. Since we already unlink it from the global mc_tomb list, it is probably safe not to acquire this spinlock here. It does not harm to have it although, to avoid conditional locking.

Fixes c38b7d327aaf ("igmp: acquire pmc lock for ip_mc_clear_src()")
---
 net/ipv4/igmp.c |    1 +
 1 file changed, 1 insertion(+)
net/ipv4/igmp.c +1 -0
@@ -1112,6 +1112,7 @@ static void igmpv3_add_delrec(struct in_
 	pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
 	if (!pmc)
 		return;
+	spin_lock_init(&pmc->lock);
 	spin_lock_bh(&im->lock);
 	pmc->interface = im->interface;
 	in_dev_hold(in_dev);
author maintainer
#21 lore raw

PATCH 22/84 net: dont global ICMP rate limit packets originating from loopback

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Jesper Dangaard Brouer <[email protected]>

[ Upstream commit 849a44de91636c24cea799cb8ad8c36433feb913 ]

Florian Weimer seems to have a glibc test-case which requires that loopback interfaces does not get ICMP ratelimited. This was broken by commit c0303efeab73 ("net: reduce cycles spend on ICMP replies that gets rate limited").

An ICMP response will usually be routed back-out the same incoming interface. Thus, take advantage of this and skip global ICMP ratelimit when the incoming device is loopback. In the unlikely event that the outgoing it not loopback, due to strange routing policy rules, ICMP rate limiting still works via peer ratelimiting via icmpv4_xrlim_allow(). Thus, we should still comply with RFC1812 (section 4.3.2.8 "Rate Limiting").

This seems to fix the reproducer given by Florian. While still avoiding to perform expensive and unneeded outgoing route lookup for rate limited packets (in the non-loopback case).

Fixes c0303efeab73 ("net: reduce cycles spend on ICMP replies that gets rate limited")
---
 net/ipv4/icmp.c |    8 ++++++--
 net/ipv6/icmp.c |    2 +-
 2 files changed, 7 insertions(+), 3 deletions(-)
net/ipv4/icmp.c +6 -2
@@ -674,8 +674,12 @@ void icmp_send(struct sk_buff *skb_in, i
 	/* Needed by both icmp_global_allow and icmp_xmit_lock */
 	local_bh_disable();
 
-	/* Check global sysctl_icmp_msgs_per_sec ratelimit */
-	if (!icmpv4_global_allow(net, type, code))
+	/* Check global sysctl_icmp_msgs_per_sec ratelimit, unless
+	 * incoming dev is loopback.  If outgoing dev change to not be
+	 * loopback, then peer ratelimit still work (in icmpv4_xrlim_allow)
+	 */
+	if (!(skb_in->dev && (skb_in->dev->flags&IFF_LOOPBACK)) &&
+	      !icmpv4_global_allow(net, type, code))
 		goto out_bh_enable;
 
 	sk = icmp_xmit_lock(net);
net/ipv6/icmp.c +1 -1
@@ -491,7 +491,7 @@ static void icmp6_send(struct sk_buff *s
 	local_bh_disable();
 
 	/* Check global sysctl_icmp_msgs_per_sec ratelimit */
-	if (!icmpv6_global_allow(type))
+	if (!(skb->dev->flags&IFF_LOOPBACK) && !icmpv6_global_allow(type))
 		goto out_bh_enable;
 
 	mip6_addr_swap(skb);
author maintainer
#22 lore raw

PATCH 23/84 ipv6: fix calling in6_ifa_hold incorrectly for dad work

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Xin Long <[email protected]>

[ Upstream commit f8a894b218138888542a5058d0e902378fd0d4ec ]

Now when starting the dad work in addrconf_mod_dad_work, if the dad work is idle and queued, it needs to hold ifa.

The problem is there's one gap in [1], during which if the pending dad work is removed elsewhere. It will miss to hold ifa, but the dad word is still idea and queue.

        if (!delayed_work_pending(&ifp->dad_work))
                in6_ifa_hold(ifp);
                    <--------------[1]
        mod_delayed_work(addrconf_wq, &ifp->dad_work, delay);

An use-after-free issue can be caused by this.

Chen Wei found this issue when WARN_ON(!hlist_unhashed(&ifp->addr_lst)) in net6_ifa_finish_destroy was hit because of it.

As Hannes' suggestion, this patch is to fix it by holding ifa first in addrconf_mod_dad_work, then calling mod_delayed_work and putting ifa if the dad_work is already in queue.

Note that this patch did not choose to fix it with:

  if (!mod_delayed_work(delay))
          in6_ifa_hold(ifp);

As with it, when delay == 0, dad_work would be scheduled immediately, all addrconf_mod_dad_work(0) callings had to be moved under ifp->lock.

---
 net/ipv6/addrconf.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
net/ipv6/addrconf.c +3 -3
@@ -328,9 +328,9 @@ static void addrconf_mod_rs_timer(struct
 static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp,
 				   unsigned long delay)
 {
-	if (!delayed_work_pending(&ifp->dad_work))
-		in6_ifa_hold(ifp);
-	mod_delayed_work(addrconf_wq, &ifp->dad_work, delay);
+	in6_ifa_hold(ifp);
+	if (mod_delayed_work(addrconf_wq, &ifp->dad_work, delay))
+		in6_ifa_put(ifp);
 }
 
 static int snmp6_alloc_dev(struct inet6_dev *idev)
author maintainer
#23 lore raw

PATCH 24/84 sctp: return next obj by passing pos + 1 into sctp_transport_get_idx

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Xin Long <[email protected]>

[ Upstream commit 988c7322116970696211e902b468aefec95b6ec4 ]

In sctp_for_each_transport, pos is used to save how many objs it has dumped. Now it gets the last obj by sctp_transport_get_idx, then gets the next obj by sctp_transport_get_next.

The issue is that in the meanwhile if some objs in transport hashtable are removed and the objs nums are less than pos, sctp_transport_get_idx would return NULL and hti.walker.tbl is NULL as well. At this moment it should stop hti, instead of continue getting the next obj. Or it would cause a NULL pointer dereference in sctp_transport_get_next.

This patch is to pass pos + 1 into sctp_transport_get_idx to get the next obj directly, even if pos > objs nums, it would return NULL and stop hti.

Fixes 626d16f50f39 ("sctp: export some apis or variables for sctp_diag and reuse some for proc")
---
 net/sctp/socket.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
net/sctp/socket.c +2 -3
@@ -4630,9 +4630,8 @@ int sctp_for_each_transport(int (*cb)(st
 	if (err)
 		return err;
 
-	sctp_transport_get_idx(net, &hti, pos);
-	obj = sctp_transport_get_next(net, &hti);
-	for (; obj && !IS_ERR(obj); obj = sctp_transport_get_next(net, &hti)) {
+	obj = sctp_transport_get_idx(net, &hti, pos + 1);
+	for (; !IS_ERR_OR_NULL(obj); obj = sctp_transport_get_next(net, &hti)) {
 		struct sctp_transport *transport = obj;
 
 		if (!sctp_transport_hold(transport))
author maintainer
#24 lore raw

PATCH 25/84 net/mlx5e: Fix min inline value for VF rep SQs

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Chris Mi <[email protected]>

[ Upstream commit 5f195c2c5cba60241004146cd12d71451d6b0fc4 ]

The offending commit only changed the code path for PF/VF, but it didn't take care of VF representors. As a result, since params->tx_min_inline_mode for VF representors is kzalloced to 0 (MLX5_INLINE_MODE_NONE), all VF reps SQs were set to that mode.

This actually works on CX5 by default but broke CX4. Fix that by adding a call to query the min inline mode from the VF rep build up code.

Fixes a6f402e49901 ("net/mlx5e: Tx, no inline copy on ConnectX-5")
---
 drivers/net/ethernet/mellanox/mlx5/core/en_rep.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +2 -0
@@ -424,6 +424,8 @@ static void mlx5e_build_rep_netdev_priv(
 	priv->params.lro_wqe_sz            =
 		MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
 
+	mlx5_query_min_inline(mdev, &priv->params.tx_min_inline_mode);
+
 	priv->mdev                         = mdev;
 	priv->netdev                       = netdev;
 	priv->params.num_channels          = profile->max_nch(mdev);
author maintainer
#25 lore raw

PATCH 26/84 net/mlx5e: Avoid doing a cleanup call if the profile doesnt have it

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Or Gerlitz <[email protected]>

[ Upstream commit 31ac93386d135a6c96de9c8bab406f5ccabf5a4d ]

The error flow of mlx5e_create_netdev calls the cleanup call of the given profile without checking if it exists, fix that.

Currently the VF reps don't register that callback and we crash if getting into error -- can be reproduced by the user doing ctrl^C while attempting to change the sriov mode from legacy to switchdev.

Fixes 26e59d8077a3 '(net/mlx5e: Implement mlx5e interface attach/detach callbacks')
---
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en_main.c +2 -1
@@ -3885,7 +3885,8 @@ struct net_device *mlx5e_create_netdev(s
 	return netdev;
 
 err_cleanup_nic:
-	profile->cleanup(priv);
+	if (profile->cleanup)
+		profile->cleanup(priv);
 	free_netdev(netdev);
 
 	return NULL;
author maintainer
#26 lore raw

PATCH 27/84 net/mlx5: Wait for FW readiness before initializing command interface

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Eli Cohen <[email protected]>

[ Upstream commit 6c780a0267b8a1075f40b39851132eeaefefcff5 ]

Before attempting to initialize the command interface we must wait till the fw_initializing bit is clear.

If we fail to meet this condition the hardware will drop our configuration, specifically the descriptors page address. This scenario can happen when the firmware is still executing an FLR flow and did not finish yet so the driver needs to wait for that to finish.

Fixes e3297246c2c8 ('net/mlx5_core: Wait for FW readiness on startup')
---
 drivers/net/ethernet/mellanox/mlx5/core/main.c |   14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/main.c +12 -2
@@ -175,8 +175,9 @@ static struct mlx5_profile profile[] = {
 	},
 };
 
-#define FW_INIT_TIMEOUT_MILI	2000
-#define FW_INIT_WAIT_MS		2
+#define FW_INIT_TIMEOUT_MILI		2000
+#define FW_INIT_WAIT_MS			2
+#define FW_PRE_INIT_TIMEOUT_MILI	10000
 
 static int wait_fw_init(struct mlx5_core_dev *dev, u32 max_wait_mili)
 {
@@ -1021,6 +1022,15 @@ static int mlx5_load_one(struct mlx5_cor
 	 */
 	dev->state = MLX5_DEVICE_STATE_UP;
 
+	/* wait for firmware to accept initialization segments configurations
+	 */
+	err = wait_fw_init(dev, FW_PRE_INIT_TIMEOUT_MILI);
+	if (err) {
+		dev_err(&dev->pdev->dev, "Firmware over %d MS in pre-initializing state, aborting\n",
+			FW_PRE_INIT_TIMEOUT_MILI);
+		goto out;
+	}
+
 	err = mlx5_cmd_init(dev);
 	if (err) {
 		dev_err(&pdev->dev, "Failed initializing command interface, aborting\n");
author maintainer
#27 lore raw

PATCH 28/84 net/mlx5e: Fix timestamping capabilities reporting

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Maor Dickman <[email protected]>

[ Upstream commit f0b381178b01b831f9907d72f467d6443afdea67 ]

Misuse of (BIT) macro caused to report wrong flags for "Hardware Transmit Timestamp Modes" and "Hardware Receive Filter Modes"

Fixes ef9814deafd0 ('net/mlx5e: Add HW timestamping (TS) support')
---
 drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +4 -4
@@ -1205,11 +1205,11 @@ static int mlx5e_get_ts_info(struct net_
 				 SOF_TIMESTAMPING_RX_HARDWARE |
 				 SOF_TIMESTAMPING_RAW_HARDWARE;
 
-	info->tx_types = (BIT(1) << HWTSTAMP_TX_OFF) |
-			 (BIT(1) << HWTSTAMP_TX_ON);
+	info->tx_types = BIT(HWTSTAMP_TX_OFF) |
+			 BIT(HWTSTAMP_TX_ON);
 
-	info->rx_filters = (BIT(1) << HWTSTAMP_FILTER_NONE) |
-			   (BIT(1) << HWTSTAMP_FILTER_ALL);
+	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
+			   BIT(HWTSTAMP_FILTER_ALL);
 
 	return 0;
 }
author maintainer
#28 lore raw

PATCH 29/84 decnet: always not take dst->__refcnt when inserting dst into hash table

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Wei Wang <[email protected]>

[ Upstream commit 76371d2e3ad1f84426a30ebcd8c3b9b98f4c724f ]

In the existing dn_route.c code, dn_route_output_slow() takes dst->__refcnt before calling dn_insert_route() while dn_route_input_slow() does not take dst->__refcnt before calling dn_insert_route(). This makes the whole routing code very buggy.
In dn_dst_check_expire(), dnrt_free() is called when rt expires. This makes the routes inserted by dn_route_output_slow() not able to be freed as the refcnt is not released.
In dn_dst_gc(), dnrt_drop() is called to release rt which could potentially cause the dst->__refcnt to be dropped to -1.
In dn_run_flush(), dst_free() is called to release all the dst. Again, it makes the dst inserted by dn_route_output_slow() not able to be released and also, it does not wait on the rcu and could potentially cause crash in the path where other users still refer to this dst.

This patch makes sure both input and output path do not take dst->__refcnt before calling dn_insert_route() and also makes sure dnrt_free()/dst_free() is called when removing dst from the hash table. The only difference between those 2 calls is that dnrt_free() waits on the rcu while dst_free() does not.

---
 net/decnet/dn_route.c |   14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)
net/decnet/dn_route.c +4 -10
@@ -188,12 +188,6 @@ static inline void dnrt_free(struct dn_r
 	call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
 }
 
-static inline void dnrt_drop(struct dn_route *rt)
-{
-	dst_release(&rt->dst);
-	call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
-}
-
 static void dn_dst_check_expire(unsigned long dummy)
 {
 	int i;
@@ -248,7 +242,7 @@ static int dn_dst_gc(struct dst_ops *ops
 			}
 			*rtp = rt->dst.dn_next;
 			rt->dst.dn_next = NULL;
-			dnrt_drop(rt);
+			dnrt_free(rt);
 			break;
 		}
 		spin_unlock_bh(&dn_rt_hash_table[i].lock);
@@ -350,7 +344,7 @@ static int dn_insert_route(struct dn_rou
 			dst_use(&rth->dst, now);
 			spin_unlock_bh(&dn_rt_hash_table[hash].lock);
 
-			dnrt_drop(rt);
+			dst_free(&rt->dst);
 			*rp = rth;
 			return 0;
 		}
@@ -380,7 +374,7 @@ static void dn_run_flush(unsigned long d
 		for(; rt; rt = next) {
 			next = rcu_dereference_raw(rt->dst.dn_next);
 			RCU_INIT_POINTER(rt->dst.dn_next, NULL);
-			dst_free((struct dst_entry *)rt);
+			dnrt_free(rt);
 		}
 
 nothing_to_declare:
@@ -1187,7 +1181,7 @@ make_route:
 	if (dev_out->flags & IFF_LOOPBACK)
 		flags |= RTCF_LOCAL;
 
-	rt = dst_alloc(&dn_dst_ops, dev_out, 1, DST_OBSOLETE_NONE, DST_HOST);
+	rt = dst_alloc(&dn_dst_ops, dev_out, 0, DST_OBSOLETE_NONE, DST_HOST);
 	if (rt == NULL)
 		goto e_nobufs;
 
author maintainer
#29 lore raw

PATCH 30/84 net: 8021q: Fix one possible panic caused by BUG_ON in free_netdev

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Gao Feng <[email protected]>

[ Upstream commit 9745e362add89432d2c951272a99b0a5fe4348a9 ]

The register_vlan_device would invoke free_netdev directly, when register_vlan_dev failed. It would trigger the BUG_ON in free_netdev if the dev was already registered. In this case, the netdev would be freed in netdev_run_todo later.

So add one condition check now. Only when dev is not registered, then free it directly.

The following is the part coredump when netdev_upper_dev_link failed in register_vlan_dev. I removed the lines which are too long.

[  411.237457] ------------[ cut here ]------------
[  411.237458] kernel BUG at net/core/dev.c:7998!
[  411.237484] invalid opcode: 0000 [#1] SMP
[  411.237705]  [last unloaded: 8021q]
[  411.237718] CPU: 1 PID: 12845 Comm: vconfig Tainted: G            E   4.12.0-rc5+ #6
[  411.237737] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/02/2015
[  411.237764] task: ffff9cbeb6685580 task.stack: ffffa7d2807d8000
[  411.237782] RIP: 0010:free_netdev+0x116/0x120
[  411.237794] RSP: 0018:ffffa7d2807dbdb0 EFLAGS: 00010297
[  411.237808] RAX: 0000000000000002 RBX: ffff9cbeb6ba8fd8 RCX: 0000000000001878
[  411.237826] RDX: 0000000000000001 RSI: 0000000000000282 RDI: 0000000000000000
[  411.237844] RBP: ffffa7d2807dbdc8 R08: 0002986100029841 R09: 0002982100029801
[  411.237861] R10: 0004000100029980 R11: 0004000100029980 R12: ffff9cbeb6ba9000
[  411.238761] R13: ffff9cbeb6ba9060 R14: ffff9cbe60f1a000 R15: ffff9cbeb6ba9000
[  411.239518] FS:  00007fb690d81700(0000) GS:ffff9cbebb640000(0000) knlGS:0000000000000000
[  411.239949] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  411.240454] CR2: 00007f7115624000 CR3: 0000000077cdf000 CR4: 00000000003406e0
[  411.240936] Call Trace:
[  411.241462]  vlan_ioctl_handler+0x3f1/0x400 [8021q]
[  411.241910]  sock_ioctl+0x18b/0x2c0
[  411.242394]  do_vfs_ioctl+0xa1/0x5d0
[  411.242853]  ? sock_alloc_file+0xa6/0x130
[  411.243465]  SyS_ioctl+0x79/0x90
[  411.243900]  entry_SYSCALL_64_fastpath+0x1e/0xa9
[  411.244425] RIP: 0033:0x7fb69089a357
[  411.244863] RSP: 002b:00007ffcd04e0fc8 EFLAGS: 00000202 ORIG_RAX: 0000000000000010
[  411.245445] RAX: ffffffffffffffda RBX: 00007ffcd04e2884 RCX: 00007fb69089a357
[  411.245903] RDX: 00007ffcd04e0fd0 RSI: 0000000000008983 RDI: 0000000000000003
[  411.246527] RBP: 00007ffcd04e0fd0 R08: 0000000000000000 R09: 1999999999999999
[  411.246976] R10: 000000000000053f R11: 0000000000000202 R12: 0000000000000004
[  411.247414] R13: 00007ffcd04e1128 R14: 00007ffcd04e2888 R15: 0000000000000001
[  411.249129] RIP: free_netdev+0x116/0x120 RSP: ffffa7d2807dbdb0
---
 net/8021q/vlan.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/8021q/vlan.c +2 -1
@@ -277,7 +277,8 @@ static int register_vlan_device(struct n
 	return 0;
 
 out_free_newdev:
-	free_netdev(new_dev);
+	if (new_dev->reg_state == NETREG_UNINITIALIZED)
+		free_netdev(new_dev);
 	return err;
 }
 
author maintainer
#30 lore raw

PATCH 31/84 ipv6: Do not leak throw route references

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Serhey Popovych <[email protected]>

[ Upstream commit 07f615574f8ac499875b21c1142f26308234a92c ]

While commit 73ba57bfae4a ("ipv6: fix backtracking for throw routes") does good job on error propagation to the fib_rules_lookup() in fib rules core framework that also corrects throw routes handling, it does not solve route reference leakage problem happened when we return -EAGAIN to the fib_rules_lookup() and leave routing table entry referenced in arg->result.

If rule with matched throw route isn't last matched in the list we overwrite arg->result losing reference on throw route stored previously forever.

We also partially revert commit ab997ad40839 ("ipv6: fix the incorrect return value of throw route") since we never return routing table entry with dst.error == -EAGAIN when CONFIG_IPV6_MULTIPLE_TABLES is on. Also there is no point to check for RTF_REJECT flag since it is always set throw route.

Fixes 73ba57bfae4a ("ipv6: fix backtracking for throw routes")
---
 net/ipv6/fib6_rules.c |   22 ++++++----------------
 net/ipv6/ip6_fib.c    |    3 +--
 2 files changed, 7 insertions(+), 18 deletions(-)
net/ipv6/fib6_rules.c +6 -16
@@ -32,7 +32,6 @@ struct fib6_rule {
 struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
 				   int flags, pol_lookup_t lookup)
 {
-	struct rt6_info *rt;
 	struct fib_lookup_arg arg = {
 		.lookup_ptr = lookup,
 		.flags = FIB_LOOKUP_NOREF,
@@ -44,21 +43,11 @@ struct dst_entry *fib6_rule_lookup(struc
 	fib_rules_lookup(net->ipv6.fib6_rules_ops,
 			 flowi6_to_flowi(fl6), flags, &arg);
 
-	rt = arg.result;
+	if (arg.result)
+		return arg.result;
 
-	if (!rt) {
-		dst_hold(&net->ipv6.ip6_null_entry->dst);
-		return &net->ipv6.ip6_null_entry->dst;
-	}
-
-	if (rt->rt6i_flags & RTF_REJECT &&
-	    rt->dst.error == -EAGAIN) {
-		ip6_rt_put(rt);
-		rt = net->ipv6.ip6_null_entry;
-		dst_hold(&rt->dst);
-	}
-
-	return &rt->dst;
+	dst_hold(&net->ipv6.ip6_null_entry->dst);
+	return &net->ipv6.ip6_null_entry->dst;
 }
 
 static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
@@ -121,7 +110,8 @@ static int fib6_rule_action(struct fib_r
 			flp6->saddr = saddr;
 		}
 		err = rt->dst.error;
-		goto out;
+		if (err != -EAGAIN)
+			goto out;
 	}
 again:
 	ip6_rt_put(rt);
net/ipv6/ip6_fib.c +1 -2
@@ -289,8 +289,7 @@ struct dst_entry *fib6_rule_lookup(struc
 	struct rt6_info *rt;
 
 	rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, flags);
-	if (rt->rt6i_flags & RTF_REJECT &&
-	    rt->dst.error == -EAGAIN) {
+	if (rt->dst.error == -EAGAIN) {
 		ip6_rt_put(rt);
 		rt = net->ipv6.ip6_null_entry;
 		dst_hold(&rt->dst);
author maintainer
#31 lore raw

PATCH 32/84 rtnetlink: add IFLA_GROUP to ifla_policy

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Serhey Popovych <[email protected]>

[ Upstream commit db833d40ad3263b2ee3b59a1ba168bb3cfed8137 ]

Network interface groups support added while ago, however there is no IFLA_GROUP attribute description in policy and netlink message size calculations until now.

Add IFLA_GROUP attribute to the policy.

Fixes cbda10fa97d7 ("net_device: add support for network device groups")
---
 net/core/rtnetlink.c |    2 ++
 1 file changed, 2 insertions(+)
net/core/rtnetlink.c +2 -0
@@ -934,6 +934,7 @@ static noinline size_t if_nlmsg_size(con
 	       + nla_total_size(1) /* IFLA_LINKMODE */
 	       + nla_total_size(4) /* IFLA_CARRIER_CHANGES */
 	       + nla_total_size(4) /* IFLA_LINK_NETNSID */
+	       + nla_total_size(4) /* IFLA_GROUP */
 	       + nla_total_size(ext_filter_mask
 			        & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */
 	       + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */
@@ -1462,6 +1463,7 @@ static const struct nla_policy ifla_poli
 	[IFLA_LINK_NETNSID]	= { .type = NLA_S32 },
 	[IFLA_PROTO_DOWN]	= { .type = NLA_U8 },
 	[IFLA_XDP]		= { .type = NLA_NESTED },
+	[IFLA_GROUP]		= { .type = NLA_U32 },
 };
 
 static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
author maintainer
#32 lore raw

PATCH 33/84 netfilter: synproxy: fix conntrackd interaction

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Eric Leblond <[email protected]>

commit 87e94dbc210a720a34be5c1174faee5c84be963e upstream.

This patch fixes the creation of connection tracking entry from netlink when synproxy is used. It was missing the addition of the synproxy extension.

This was causing kernel crashes when a conntrack entry created by conntrackd was used after the switch of traffic from active node to the passive node.

---
 net/netfilter/nf_conntrack_netlink.c |    4 ++++
 1 file changed, 4 insertions(+)
net/netfilter/nf_conntrack_netlink.c +4 -0
@@ -45,6 +45,8 @@
 #include <net/netfilter/nf_conntrack_zones.h>
 #include <net/netfilter/nf_conntrack_timestamp.h>
 #include <net/netfilter/nf_conntrack_labels.h>
+#include <net/netfilter/nf_conntrack_seqadj.h>
+#include <net/netfilter/nf_conntrack_synproxy.h>
 #ifdef CONFIG_NF_NAT_NEEDED
 #include <net/netfilter/nf_nat_core.h>
 #include <net/netfilter/nf_nat_l4proto.h>
@@ -1814,6 +1816,8 @@ ctnetlink_create_conntrack(struct net *n
 	nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
 	nf_ct_ecache_ext_add(ct, 0, 0, GFP_ATOMIC);
 	nf_ct_labels_ext_add(ct);
+	nfct_seqadj_ext_add(ct);
+	nfct_synproxy_ext_add(ct);
 
 	/* we must add conntrack extensions before confirmation. */
 	ct->status |= IPS_CONFIRMED;
author maintainer
#33 lore raw

PATCH 34/84 NFSv4.x/callback: Create the callback service through svc_create_pooled

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Kinglong Mee <[email protected]>

commit df807fffaabde625fa9adb82e3e5b88cdaa5709a upstream.

As the comments for svc_set_num_threads() said,
" Destroying threads relies on the service threads filling in rqstp->rq_task, which only the nfs ones do. Assumes the serv has been created using svc_create_pooled()."

If creating service through svc_create(), the svc_pool_map_put() will be called in svc_destroy(), but the pool map isn't used. So that, the reference of pool map will be drop, the next using of pool map will get a zero npools.

[  137.992130] divide error: 0000 [#1] SMP
[  137.992148] Modules linked in: nfsd(E) nfsv4 nfs fscache fuse tun bridge stp llc ip_set nfnetlink vmw_vsock_vmci_transport vsock snd_seq_midi snd_seq_midi_event vmw_balloon coretemp crct10dif_pclmul crc32_pclmul ppdev ghash_clmulni_intel intel_rapl_perf joydev snd_ens1371 gameport snd_ac97_codec ac97_bus snd_seq snd_pcm snd_rawmidi snd_timer snd_seq_device snd soundcore parport_pc parport nfit acpi_cpufreq tpm_tis tpm_tis_core tpm vmw_vmci i2c_piix4 shpchp auth_rpcgss nfs_acl lockd(E) grace sunrpc(E) xfs libcrc32c vmwgfx drm_kms_helper ttm crc32c_intel drm e1000 mptspi scsi_transport_spi serio_raw mptscsih mptbase ata_generic pata_acpi [last unloaded: nfsd]
[  137.992336] CPU: 0 PID: 4514 Comm: rpc.nfsd Tainted: G            E   4.11.0-rc8+ #536
[  137.992777] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/02/2015
[  137.993757] task: ffff955984101d00 task.stack: ffff9873c2604000
[  137.994231] RIP: 0010:svc_pool_for_cpu+0x2b/0x80 [sunrpc]
[  137.994768] RSP: 0018:ffff9873c2607c18 EFLAGS: 00010246
[  137.995227] RAX: 0000000000000000 RBX: ffff95598376f000 RCX: 0000000000000002
[  137.995673] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff9559944aec00
[  137.996156] RBP: ffff9873c2607c18 R08: ffff9559944aec28 R09: 0000000000000000
[  137.996609] R10: 0000000001080002 R11: 0000000000000000 R12: ffff95598376f010
[  137.997063] R13: ffff95598376f018 R14: ffff9559944aec28 R15: ffff9559944aec00
[  137.997584] FS:  00007f755529eb40(0000) GS:ffff9559bb600000(0000) knlGS:0000000000000000
[  137.998048] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  137.998548] CR2: 000055f3aecd9660 CR3: 0000000084290000 CR4: 00000000001406f0
[  137.999052] Call Trace:
[  137.999517]  svc_xprt_do_enqueue+0xef/0x260 [sunrpc]
[  138.000028]  svc_xprt_received+0x47/0x90 [sunrpc]
[  138.000487]  svc_add_new_perm_xprt+0x76/0x90 [sunrpc]
[  138.000981]  svc_addsock+0x14b/0x200 [sunrpc]
[  138.001424]  ? recalc_sigpending+0x1b/0x50
[  138.001860]  ? __getnstimeofday64+0x41/0xd0
[  138.002346]  ? do_gettimeofday+0x29/0x90
[  138.002779]  write_ports+0x255/0x2c0 [nfsd]
[  138.003202]  ? _copy_from_user+0x4e/0x80
[  138.003676]  ? write_recoverydir+0x100/0x100 [nfsd]
[  138.004098]  nfsctl_transaction_write+0x48/0x80 [nfsd]
[  138.004544]  __vfs_write+0x37/0x160
[  138.004982]  ? selinux_file_permission+0xd7/0x110
[  138.005401]  ? security_file_permission+0x3b/0xc0
[  138.005865]  vfs_write+0xb5/0x1a0
[  138.006267]  SyS_write+0x55/0xc0
[  138.006654]  entry_SYSCALL_64_fastpath+0x1a/0xa9
[  138.007071] RIP: 0033:0x7f7554b9dc30
[  138.007437] RSP: 002b:00007ffc9f92c788 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[  138.007807] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007f7554b9dc30
[  138.008168] RDX: 0000000000000002 RSI: 00005640cd536640 RDI: 0000000000000003
[  138.008573] RBP: 00007ffc9f92c780 R08: 0000000000000001 R09: 0000000000000002
[  138.008918] R10: 0000000000000064 R11: 0000000000000246 R12: 0000000000000004
[  138.009254] R13: 00005640cdbf77a0 R14: 00005640cdbf7720 R15: 00007ffc9f92c238
[  138.009610] Code: 0f 1f 44 00 00 48 8b 87 98 00 00 00 55 48 89 e5 48 83 78 08 00 74 10 8b 05 07 42 02 00 83 f8 01 74 40 83 f8 02 74 19 31 c0 31 d2 <f7> b7 88 00 00 00 5d 89 d0 48 c1 e0 07 48 03 87 90 00 00 00 c3
[  138.010664] RIP: svc_pool_for_cpu+0x2b/0x80 [sunrpc] RSP: ffff9873c2607c18
[  138.011061] ---[ end trace b3468224cafa7d11 ]---
---
 fs/nfs/callback.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/callback.c +1 -1
@@ -280,7 +280,7 @@ static struct svc_serv *nfs_callback_cre
 		printk(KERN_WARNING "nfs_callback_create_svc: no kthread, %d users??\n",
 			cb_info->users);
 
-	serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, sv_ops);
+	serv = svc_create_pooled(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, sv_ops);
 	if (!serv) {
 		printk(KERN_ERR "nfs_callback_create_svc: create service failed\n");
 		return ERR_PTR(-ENOMEM);
author maintainer
#34 lore raw

PATCH 36/84 MIPS: head: Reorder instructions missing a delay slot

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Karl Beldan <[email protected]>

commit 25d8b92e0af75d72ce8b99e63e5a449cc0888efa upstream.

In this sequence the 'move' is assumed in the delay slot of the 'beq', but head.S is in reorder mode and the former gets pushed one 'nop' farther by the assembler.

The corrected behavior made booting with an UHI supplied dtb erratic.

Fixes 15f37e158892 ("MIPS: store the appended dtb address in a variable")
Cc Jonas Gorski <[email protected]>

Patchwork: https://patchwork.linux-mips.org/patch/16614/

---
 arch/mips/kernel/head.S |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/kernel/head.S +1 -1
@@ -106,8 +106,8 @@ NESTED(kernel_entry, 16, sp)			# kernel
 	beq		t0, t1, dtb_found
 #endif
 	li		t1, -2
-	beq		a0, t1, dtb_found
 	move		t2, a1
+	beq		a0, t1, dtb_found
 
 	li		t2, 0
 dtb_found:
author maintainer
#35 lore raw

PATCH 37/84 MIPS: Avoid accidental raw backtrace

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: James Hogan <[email protected]>

commit 854236363370995a609a10b03e35fd3dc5e9e4a1 upstream.

Since commit 81a76d7119f6 ("MIPS: Avoid using unwind_stack() with usermode") show_backtrace() invokes the raw backtracer when cp0_status & ST0_KSU indicates user mode to fix issues on EVA kernels where user and kernel address spaces overlap.

However this is used by show_stack() which creates its own pt_regs on the stack and leaves cp0_status uninitialised in most of the code paths. This results in the non deterministic use of the raw back tracer depending on the previous stack content.

show_stack() deals exclusively with kernel mode stacks anyway, so explicitly initialise regs.cp0_status to KSU_KERNEL (i.e. 0) to ensure we get a useful backtrace.

Fixes 81a76d7119f6 ("MIPS: Avoid using unwind_stack() with usermode")

Patchwork: https://patchwork.linux-mips.org/patch/16656/

---
 arch/mips/kernel/traps.c |    2 ++
 1 file changed, 2 insertions(+)
arch/mips/kernel/traps.c +2 -0
@@ -201,6 +201,8 @@ void show_stack(struct task_struct *task
 {
 	struct pt_regs regs;
 	mm_segment_t old_fs = get_fs();
+
+	regs.cp0_status = KSU_KERNEL;
 	if (sp) {
 		regs.regs[29] = (unsigned long)sp;
 		regs.regs[31] = 0;
author maintainer
#36 lore raw

PATCH 38/84 MIPS: pm-cps: Drop manual cache-line alignment of ready_count

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Paul Burton <[email protected]>

commit 161c51ccb7a6faf45ffe09aa5cf1ad85ccdad503 upstream.

We allocate memory for a ready_count variable per-CPU, which is accessed via a cached non-coherent TLB mapping to perform synchronisation between threads within the core using LL/SC instructions. In order to ensure that the variable is contained within its own data cache line we allocate 2 lines worth of memory & align the resulting pointer to a line boundary. This is however unnecessary, since kmalloc is guaranteed to return memory which is at least cache-line aligned (see ARCH_DMA_MINALIGN). Stop the redundant manual alignment.

Besides cleaning up the code & avoiding needless work, this has the side effect of avoiding an arithmetic error found by Bryan on 64 bit systems due to the 32 bit size of the former dlinesz. This led the ready_count variable to have its upper 32b cleared erroneously for MIPS64 kernels, causing problems when ready_count was later used on MIPS64 via cpuidle.

Fixes 3179d37ee1ed ("MIPS: pm-cps: add PM state entry code for CPS systems")

Patchwork: https://patchwork.linux-mips.org/patch/15383/

---
 arch/mips/kernel/pm-cps.c |    9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)
arch/mips/kernel/pm-cps.c +1 -8
@@ -56,7 +56,6 @@ DECLARE_BITMAP(state_support, CPS_PM_STA
  * state. Actually per-core rather than per-CPU.
  */
 static DEFINE_PER_CPU_ALIGNED(u32*, ready_count);
-static DEFINE_PER_CPU_ALIGNED(void*, ready_count_alloc);
 
 /* Indicates online CPUs coupled with the current CPU */
 static DEFINE_PER_CPU_ALIGNED(cpumask_t, online_coupled);
@@ -642,7 +641,6 @@ static int cps_pm_online_cpu(unsigned in
 {
 	enum cps_pm_state state;
 	unsigned core = cpu_data[cpu].core;
-	unsigned dlinesz = cpu_data[cpu].dcache.linesz;
 	void *entry_fn, *core_rc;
 
 	for (state = CPS_PM_NC_WAIT; state < CPS_PM_STATE_COUNT; state++) {
@@ -662,16 +660,11 @@ static int cps_pm_online_cpu(unsigned in
 	}
 
 	if (!per_cpu(ready_count, core)) {
-		core_rc = kmalloc(dlinesz * 2, GFP_KERNEL);
+		core_rc = kmalloc(sizeof(u32), GFP_KERNEL);
 		if (!core_rc) {
 			pr_err("Failed allocate core %u ready_count\n", core);
 			return -ENOMEM;
 		}
-		per_cpu(ready_count_alloc, core) = core_rc;
-
-		/* Ensure ready_count is aligned to a cacheline boundary */
-		core_rc += dlinesz - 1;
-		core_rc = (void *)((unsigned long)core_rc & ~(dlinesz - 1));
 		per_cpu(ready_count, core) = core_rc;
 	}
 
author maintainer
#37 lore raw

PATCH 39/84 MIPS: Fix IRQ tracing & lockdep when rescheduling

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Paul Burton <[email protected]>

commit d8550860d910c6b7b70f830f59003b33daaa52c9 upstream.

When the scheduler sets TIF_NEED_RESCHED & we call into the scheduler from arch/mips/kernel/entry.S we disable interrupts. This is true regardless of whether we reach work_resched from syscall_exit_work, resume_userspace or by looping after calling schedule(). Although we disable interrupts in these paths we don't call trace_hardirqs_off() before calling into C code which may acquire locks, and we therefore leave lockdep with an inconsistent view of whether interrupts are disabled or not when CONFIG_PROVE_LOCKING & CONFIG_DEBUG_LOCKDEP are both enabled.

Without tracing this interrupt state lockdep will print warnings such as the following once a task returns from a syscall via syscall_exit_partial with TIF_NEED_RESCHED set:

[   49.927678] ------------[ cut here ]------------
[   49.934445] WARNING: CPU: 0 PID: 1 at kernel/locking/lockdep.c:3687 check_flags.part.41+0x1dc/0x1e8
[   49.946031] DEBUG_LOCKS_WARN_ON(current->hardirqs_enabled)
[   49.946355] CPU: 0 PID: 1 Comm: init Not tainted 4.10.0-00439-gc9fd5d362289-dirty #197
[   49.963505] Stack : 0000000000000000 ffffffff81bb5d6a 0000000000000006 ffffffff801ce9c4
[   49.974431]         0000000000000000 0000000000000000 0000000000000000 000000000000004a
[   49.985300]         ffffffff80b7e487 ffffffff80a24498 a8000000ff160000 ffffffff80ede8b8
[   49.996194]         0000000000000001 0000000000000000 0000000000000000 0000000077c8030c
[   50.007063]         000000007fd8a510 ffffffff801cd45c 0000000000000000 a8000000ff127c88
[   50.017945]         0000000000000000 ffffffff801cf928 0000000000000001 ffffffff80a24498
[   50.028827]         0000000000000000 0000000000000001 0000000000000000 0000000000000000
[   50.039688]         0000000000000000 a8000000ff127bd0 0000000000000000 ffffffff805509bc
[   50.050575]         00000000140084e0 0000000000000000 0000000000000000 0000000000040a00
[   50.061448]         0000000000000000 ffffffff8010e1b0 0000000000000000 ffffffff805509bc
[   50.072327]         ...
[   50.076087] Call Trace:
[   50.079869] [<ffffffff8010e1b0>] show_stack+0x80/0xa8
[   50.086577] [<ffffffff805509bc>] dump_stack+0x10c/0x190
[   50.093498] [<ffffffff8015dde0>] __warn+0xf0/0x108
[   50.099889] [<ffffffff8015de34>] warn_slowpath_fmt+0x3c/0x48
[   50.107241] [<ffffffff801c15b4>] check_flags.part.41+0x1dc/0x1e8
[   50.114961] [<ffffffff801c239c>] lock_is_held_type+0x8c/0xb0
[   50.122291] [<ffffffff809461b8>] __schedule+0x8c0/0x10f8
[   50.129221] [<ffffffff80946a60>] schedule+0x30/0x98
[   50.135659] [<ffffffff80106278>] work_resched+0x8/0x34
[   50.142397] ---[ end trace 0cb4f6ef5b99fe21 ]---
[   50.148405] possible reason: unannotated irqs-off.
[   50.154600] irq event stamp: 400463
[   50.159566] hardirqs last  enabled at (400463): [<ffffffff8094edc8>] _raw_spin_unlock_irqrestore+0x40/0xa8
[   50.171981] hardirqs last disabled at (400462): [<ffffffff8094eb98>] _raw_spin_lock_irqsave+0x30/0xb0
[   50.183897] softirqs last  enabled at (400450): [<ffffffff8016580c>] __do_softirq+0x4ac/0x6a8
[   50.195015] softirqs last disabled at (400425): [<ffffffff80165e78>] irq_exit+0x110/0x128

Fix this by using the TRACE_IRQS_OFF macro to call trace_hardirqs_off() when CONFIG_TRACE_IRQFLAGS is enabled. This is done before invoking schedule() following the work_resched label because:

1) Interrupts are disabled regardless of the path we take to reach work_resched() & schedule().

2) Performing the tracing here avoids the need to do it in paths which disable interrupts but don't call out to C code before hitting a path which uses the RESTORE_SOME macro that will call trace_hardirqs_on() or trace_hardirqs_off() as appropriate.

We call trace_hardirqs_on() using the TRACE_IRQS_ON macro before calling syscall_trace_leave() for similar reasons, ensuring that lockdep has a consistent view of state after we re-enable interrupts.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")

Patchwork: https://patchwork.linux-mips.org/patch/15385/

---
 arch/mips/kernel/entry.S |    3 +++
 1 file changed, 3 insertions(+)
arch/mips/kernel/entry.S +3 -0
@@ -11,6 +11,7 @@
 #include <asm/asm.h>
 #include <asm/asmmacro.h>
 #include <asm/compiler.h>
+#include <asm/irqflags.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
 #include <asm/stackframe.h>
@@ -119,6 +120,7 @@ work_pending:
 	andi	t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS
 	beqz	t0, work_notifysig
 work_resched:
+	TRACE_IRQS_OFF
 	jal	schedule
 
 	local_irq_disable		# make sure need_resched and
@@ -155,6 +157,7 @@ syscall_exit_work:
 	beqz	t0, work_pending	# trace bit set?
 	local_irq_enable		# could let syscall_trace_leave()
 					# call schedule() instead
+	TRACE_IRQS_ON
 	move	a0, sp
 	jal	syscall_trace_leave
 	b	resume_userspace
author maintainer
#38 lore raw

PATCH 40/84 ALSA: hda - Fix endless loop of codec configure

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Takashi Iwai <[email protected]>

commit d94815f917da770d42c377786dc428f542e38f71 upstream.

azx_codec_configure() loops over the codecs found on the given controller via a linked list. The code used to work in the past, but in the current version, this may lead to an endless loop when a codec binding returns an error.

The culprit is that the snd_hda_codec_configure() unregisters the device upon error, and this eventually deletes the given codec object from the bus. Since the list is initialized via list_del_init(), the next object points to the same device itself. This behavior change was introduced at splitting the HD-audio code code, and forgotten to adapt it here.

For fixing this bug, just use a *_safe() version of list iteration.

Fixes d068ebc25e6e ("ALSA: hda - Move some codes up to hdac_bus struct")
---
 sound/pci/hda/hda_codec.h      |    2 ++
 sound/pci/hda/hda_controller.c |    8 ++++++--
 2 files changed, 8 insertions(+), 2 deletions(-)
sound/pci/hda/hda_codec.h +2 -0
@@ -294,6 +294,8 @@ struct hda_codec {
 
 #define list_for_each_codec(c, bus) \
 	list_for_each_entry(c, &(bus)->core.codec_list, core.list)
+#define list_for_each_codec_safe(c, n, bus)				\
+	list_for_each_entry_safe(c, n, &(bus)->core.codec_list, core.list)
 
 /* snd_hda_codec_read/write optional flags */
 #define HDA_RW_NO_RESPONSE_FALLBACK	(1 << 0)
sound/pci/hda/hda_controller.c +6 -2
@@ -1337,8 +1337,12 @@ EXPORT_SYMBOL_GPL(azx_probe_codecs);
 /* configure each codec instance */
 int azx_codec_configure(struct azx *chip)
 {
-	struct hda_codec *codec;
-	list_for_each_codec(codec, &chip->bus) {
+	struct hda_codec *codec, *next;
+
+	/* use _safe version here since snd_hda_codec_configure() deregisters
+	 * the device upon error and deletes itself from the bus list.
+	 */
+	list_for_each_codec_safe(codec, next, &chip->bus) {
 		snd_hda_codec_configure(codec);
 	}
 	return 0;
author maintainer
#39 lore raw

PATCH 41/84 ALSA: hda - set input_path bitmap to zero after moving it to new place

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Hui Wang <[email protected]>

commit a8f20fd25bdce81a8e41767c39f456d346b63427 upstream.

Recently we met a problem, the codec has valid adcs and input pins, and they can form valid input paths, but the driver does not build valid controls for them like "Mic boost", "Capture Volume" and "Capture Switch".

Through debugging, I found the driver needs to shrink the invalid adcs and input paths for this machine, so it will move the whole column bitmap value to the previous column, after moving it, the driver forgets to set the original column bitmap value to zero, as a result, the driver will invalidate the path whose index value is the original colume bitmap value. After executing this function, all valid input paths are invalidated by a mistake, there are no any valid input paths, so the driver won't build controls for them.

Fixes 3a65bcdc577a ("ALSA: hda - Fix inconsistent input_paths after ADC reduction")
---
 sound/pci/hda/hda_generic.c |    1 +
 1 file changed, 1 insertion(+)
sound/pci/hda/hda_generic.c +1 -0
@@ -3169,6 +3169,7 @@ static int check_dyn_adc_switch(struct h
 						spec->input_paths[i][nums]);
 					spec->input_paths[i][nums] =
 						spec->input_paths[i][n];
+					spec->input_paths[i][n] = 0;
 				}
 			}
 			nums++;
author maintainer
#40 lore raw

PATCH 42/84 NFSv4.2: Dont send mode again in post-EXCLUSIVE4_1 SETATTR with umask

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Benjamin Coddington <[email protected]>

commit 501e7a4689378f8b1690089bfdd4f1e12ec22903 upstream.

Now that we have umask support, we shouldn't re-send the mode in a SETATTR following an exclusive CREATE, or we risk having the same problem fixed in commit 5334c5bdac92 ("NFS: Send attributes in OPEN request for NFS4_CREATE_EXCLUSIVE4_1"), which is that files with S_ISGID will have that bit stripped away.

Fixes dff25ddb4808 ("nfs: add support for the umask attribute")
---
 fs/nfs/nfs4proc.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
fs/nfs/nfs4proc.c +2 -1
@@ -2588,7 +2588,8 @@ static inline void nfs4_exclusive_attrse
 
 	/* Except MODE, it seems harmless of setting twice. */
 	if (opendata->o_arg.createmode != NFS4_CREATE_EXCLUSIVE &&
-		attrset[1] & FATTR4_WORD1_MODE)
+		(attrset[1] & FATTR4_WORD1_MODE ||
+		 attrset[2] & FATTR4_WORD2_MODE_UMASK))
 		sattr->ia_valid &= ~ATTR_MODE;
 
 	if (attrset[2] & FATTR4_WORD2_SECURITY_LABEL)
author maintainer
#41 lore raw

PATCH 43/84 NFSv4.1: Fix a race in nfs4_proc_layoutget

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Trond Myklebust <[email protected]>

commit bd171930e6a3de4f5cffdafbb944e50093dfb59b upstream.

If the task calling layoutget is signalled, then it is possible for the calls to nfs4_sequence_free_slot() and nfs4_layoutget_prepare() to race, in which case we leak a slot.
The fix is to move the call to nfs4_sequence_free_slot() into the nfs4_layoutget_release() so that it gets called at task teardown time.

Fixes 2e80dbe7ac51 ("NFSv4.1: Close callback races for OPEN, LAYOUTGET...")
---
 fs/nfs/nfs4proc.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/nfs4proc.c +1 -1
@@ -8430,6 +8430,7 @@ static void nfs4_layoutget_release(void
 	size_t max_pages = max_response_pages(server);
 
 	dprintk("--> %s\n", __func__);
+	nfs4_sequence_free_slot(&lgp->res.seq_res);
 	nfs4_free_pages(lgp->args.layout.pages, max_pages);
 	pnfs_put_layout_hdr(NFS_I(inode)->layout);
 	put_nfs_open_context(lgp->args.ctx);
@@ -8504,7 +8505,6 @@ nfs4_proc_layoutget(struct nfs4_layoutge
 	/* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */
 	if (status == 0 && lgp->res.layoutp->len)
 		lseg = pnfs_layout_process(lgp);
-	nfs4_sequence_free_slot(&lgp->res.seq_res);
 	rpc_put_task(task);
 	dprintk("<-- %s status=%d\n", __func__, status);
 	if (status)
author maintainer
#42 lore raw

PATCH 44/84 Revert "NFS: nfs_rename() handle -ERESTARTSYS dentry left behind"

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Benjamin Coddington <[email protected]>

commit d9f2950006f110f54444a10442752372ee568289 upstream.

This reverts commit 920b4530fb80430ff30ef83efe21ba1fa5623731 which could call d_move() without holding the directory's i_mutex, and reverts commit d4ea7e3c5c0e341c15b073016dbf3ab6c65f12f3 "NFS: Fix old dentry rehash after move", which was a follow-up fix.

Fixes 920b4530fb80 ("NFS: nfs_rename() handle -ERESTARTSYS dentry left behind")
---
 fs/nfs/dir.c |   51 ++++++++++++++++++++++++---------------------------
 1 file changed, 24 insertions(+), 27 deletions(-)
fs/nfs/dir.c +24 -27
@@ -2002,29 +2002,6 @@ nfs_link(struct dentry *old_dentry, stru
 }
 EXPORT_SYMBOL_GPL(nfs_link);
 
-static void
-nfs_complete_rename(struct rpc_task *task, struct nfs_renamedata *data)
-{
-	struct dentry *old_dentry = data->old_dentry;
-	struct dentry *new_dentry = data->new_dentry;
-	struct inode *old_inode = d_inode(old_dentry);
-	struct inode *new_inode = d_inode(new_dentry);
-
-	nfs_mark_for_revalidate(old_inode);
-
-	switch (task->tk_status) {
-	case 0:
-		if (new_inode != NULL)
-			nfs_drop_nlink(new_inode);
-		d_move(old_dentry, new_dentry);
-		nfs_set_verifier(new_dentry,
-					nfs_save_change_attribute(data->new_dir));
-		break;
-	case -ENOENT:
-		nfs_dentry_handle_enoent(old_dentry);
-	}
-}
-
 /*
  * RENAME
  * FIXME: Some nfsds, like the Linux user space nfsd, may generate a
@@ -2055,7 +2032,7 @@ int nfs_rename(struct inode *old_dir, st
 {
 	struct inode *old_inode = d_inode(old_dentry);
 	struct inode *new_inode = d_inode(new_dentry);
-	struct dentry *dentry = NULL;
+	struct dentry *dentry = NULL, *rehash = NULL;
 	struct rpc_task *task;
 	int error = -EBUSY;
 
@@ -2078,8 +2055,10 @@ int nfs_rename(struct inode *old_dir, st
 		 * To prevent any new references to the target during the
 		 * rename, we unhash the dentry in advance.
 		 */
-		if (!d_unhashed(new_dentry))
+		if (!d_unhashed(new_dentry)) {
 			d_drop(new_dentry);
+			rehash = new_dentry;
+		}
 
 		if (d_count(new_dentry) > 2) {
 			int err;
@@ -2096,6 +2075,7 @@ int nfs_rename(struct inode *old_dir, st
 				goto out;
 
 			new_dentry = dentry;
+			rehash = NULL;
 			new_inode = NULL;
 		}
 	}
@@ -2104,8 +2084,7 @@ int nfs_rename(struct inode *old_dir, st
 	if (new_inode != NULL)
 		NFS_PROTO(new_inode)->return_delegation(new_inode);
 
-	task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry,
-					nfs_complete_rename);
+	task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry, NULL);
 	if (IS_ERR(task)) {
 		error = PTR_ERR(task);
 		goto out;
@@ -2115,9 +2094,27 @@ int nfs_rename(struct inode *old_dir, st
 	if (error == 0)
 		error = task->tk_status;
 	rpc_put_task(task);
+	nfs_mark_for_revalidate(old_inode);
 out:
+	if (rehash)
+		d_rehash(rehash);
 	trace_nfs_rename_exit(old_dir, old_dentry,
 			new_dir, new_dentry, error);
+	if (!error) {
+		if (new_inode != NULL)
+			nfs_drop_nlink(new_inode);
+		/*
+		 * The d_move() should be here instead of in an async RPC completion
+		 * handler because we need the proper locks to move the dentry.  If
+		 * we're interrupted by a signal, the async RPC completion handler
+		 * should mark the directories for revalidation.
+		 */
+		d_move(old_dentry, new_dentry);
+		nfs_set_verifier(new_dentry,
+					nfs_save_change_attribute(new_dir));
+	} else if (error == -ENOENT)
+		nfs_dentry_handle_enoent(old_dentry);
+
 	/* new dentry created? */
 	if (dentry)
 		dput(dentry);
author maintainer
#43 lore raw

PATCH 45/84 ovl: copy-up: dont unlock between lookup and link

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Miklos Szeredi <[email protected]>

commit e85f82ff9b8ef503923a3be8ca6b5fd1908a7f3f upstream.

Nothing prevents mischief on upper layer while we are busy copying up the data.

Move the lookup right before the looked up dentry is actually used.

Fixes 01ad3eb8a073 ("ovl: concurrent copy up of regular files")
---
 fs/overlayfs/copy_up.c |   24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)
fs/overlayfs/copy_up.c +12 -12
@@ -252,15 +252,9 @@ static int ovl_copy_up_locked(struct den
 		.link = link
 	};
 
-	upper = lookup_one_len(dentry->d_name.name, upperdir,
-			       dentry->d_name.len);
-	err = PTR_ERR(upper);
-	if (IS_ERR(upper))
-		goto out;
-
 	err = security_inode_copy_up(dentry, &new_creds);
 	if (err < 0)
-		goto out1;
+		goto out;
 
 	if (new_creds)
 		old_creds = override_creds(new_creds);
@@ -284,7 +278,7 @@ static int ovl_copy_up_locked(struct den
 	}
 
 	if (err)
-		goto out2;
+		goto out;
 
 	if (S_ISREG(stat->mode)) {
 		struct path upperpath;
@@ -317,6 +311,14 @@ static int ovl_copy_up_locked(struct den
 	if (err)
 		goto out_cleanup;
 
+	upper = lookup_one_len(dentry->d_name.name, upperdir,
+			       dentry->d_name.len);
+	if (IS_ERR(upper)) {
+		err = PTR_ERR(upper);
+		upper = NULL;
+		goto out_cleanup;
+	}
+
 	if (tmpfile)
 		err = ovl_do_link(temp, udir, upper, true);
 	else
@@ -330,17 +332,15 @@ static int ovl_copy_up_locked(struct den
 
 	/* Restore timestamps on parent (best effort) */
 	ovl_set_timestamps(upperdir, pstat);
-out2:
+out:
 	dput(temp);
-out1:
 	dput(upper);
-out:
 	return err;
 
 out_cleanup:
 	if (!tmpfile)
 		ovl_cleanup(wdir, temp);
-	goto out2;
+	goto out;
 }
 
 /*
author maintainer
#44 lore raw

PATCH 46/84 gpiolib: fix filtering out unwanted events

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Bartosz Golaszewski <[email protected]>

commit ad537b822577fcc143325786cd6ad50d7b9df31c upstream.

GPIOEVENT_REQUEST_BOTH_EDGES is not a single flag, but a binary OR of GPIOEVENT_REQUEST_RISING_EDGE and GPIOEVENT_REQUEST_FALLING_EDGE.

The expression 'le->eflags & GPIOEVENT_REQUEST_BOTH_EDGES' we'll get evaluated to true even if only one event type was requested.

Fix it by checking both RISING & FALLING flags explicitly.

Fixes 61f922db7221 ("gpio: userspace ABI for reading GPIO line events")
---
 drivers/gpio/gpiolib.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpio/gpiolib.c +2 -1
@@ -708,7 +708,8 @@ static irqreturn_t lineevent_irq_thread(
 
 	ge.timestamp = ktime_get_real_ns();
 
-	if (le->eflags & GPIOEVENT_REQUEST_BOTH_EDGES) {
+	if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE
+	    && le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) {
 		int level = gpiod_get_value_cansleep(le->desc);
 
 		if (level)
author maintainer
#45 lore raw

PATCH 47/84 x86/intel_rdt: Fix memory leak on mount failure

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Vikas Shivappa <[email protected]>

commit 79298acc4ba097e9ab78644e3e38902d73547c92 upstream.

If mount fails, the kn_info directory is not freed causing memory leak.

Add the missing error handling path.

---
 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +3 -1
@@ -767,11 +767,13 @@ static struct dentry *rdt_mount(struct f
 	dentry = kernfs_mount(fs_type, flags, rdt_root,
 			      RDTGROUP_SUPER_MAGIC, NULL);
 	if (IS_ERR(dentry))
-		goto out_cdp;
+		goto out_destroy;
 
 	static_branch_enable(&rdt_enable_key);
 	goto out;
 
+out_destroy:
+	kernfs_remove(kn_info);
 out_cdp:
 	cdp_disable();
 out:
author maintainer
#46 lore raw

PATCH 48/84 perf/x86/intel/uncore: Fix wrong box pointer check

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Kan Liang <[email protected]>

commit 80c65fdb4c6920e332a9781a3de5877594b07522 upstream.

Should not init a NULL box. It will cause system crash. The issue looks like caused by a typo.

This was not noticed because there is no NULL box. Also, for most boxes, they are enabled by default. The init code is not critical.

Fixes fff4b87e594a ("perf/x86/intel/uncore: Make package handling more robust")
---
 arch/x86/events/intel/uncore.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/events/intel/uncore.c +1 -1
@@ -1170,7 +1170,7 @@ static int uncore_event_cpu_online(unsig
 		pmu = type->pmus;
 		for (i = 0; i < type->num_boxes; i++, pmu++) {
 			box = pmu->boxes[pkg];
-			if (!box && atomic_inc_return(&box->refcnt) == 1)
+			if (box && atomic_inc_return(&box->refcnt) == 1)
 				uncore_box_init(box);
 		}
 	}
author maintainer
#47 lore raw

PATCH 49/84 drm/vmwgfx: Free hash table allocated by cmdbuf managed res mgr

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Deepak Rawat <[email protected]>

commit 82fcee526ba8ca2c5d378bdf51b21b7eb058fe3a upstream.

The hash table created during vmw_cmdbuf_res_man_create was never freed. This causes memory leak in context creation. Added the corresponding drm_ht_remove in vmw_cmdbuf_res_man_destroy.

Tested for memory leak by running piglit overnight and kernel memory is not inflated which earlier was.

---
 drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c |    1 +
 1 file changed, 1 insertion(+)
drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c +1 -0
@@ -321,6 +321,7 @@ void vmw_cmdbuf_res_man_destroy(struct v
 	list_for_each_entry_safe(entry, next, &man->list, head)
 		vmw_cmdbuf_res_free(man, entry);
 
+	drm_ht_remove(&man->resources);
 	kfree(man);
 }
 
author maintainer
#48 lore raw

PATCH 50/84 dm thin: do not queue freed thin mapping for next stage processing

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Vallish Vaidyeshwara <[email protected]>

commit 00a0ea33b495ee6149bf5a77ac5807ce87323abb upstream.

process_prepared_discard_passdown_pt1() should cleanup dm_thin_new_mapping in cases of error.

dm_pool_inc_data_range() can fail trying to get a block reference:

metadata operation 'dm_pool_inc_data_range' failed: error = -61

When dm_pool_inc_data_range() fails, dm thin aborts current metadata transaction and marks pool as PM_READ_ONLY. Memory for thin mapping is released as well. However, current thin mapping will be queued onto next stage as part of queue_passdown_pt2() or passdown_endio(). This dangling thin mapping memory when processed and accessed in next stage will lead to device mapper crashing.

Code flow without fix:
-> process_prepared_discard_passdown_pt1(m)
-> dm_thin_remove_range()
-> discard passdown

      --> passdown_endio(m) queues m onto next stage

-> dm_pool_inc_data_range() fails, frees memory m
but does not remove it from next stage queue

-> process_prepared_discard_passdown_pt2(m)
-> processes freed memory m and crashes

One such stack:

Call Trace:
[<ffffffffa037a46f>] dm_cell_release_no_holder+0x2f/0x70 [dm_bio_prison]
[<ffffffffa039b6dc>] cell_defer_no_holder+0x3c/0x80 [dm_thin_pool]
[<ffffffffa039b88b>] process_prepared_discard_passdown_pt2+0x4b/0x90 [dm_thin_pool]
[<ffffffffa0399611>] process_prepared+0x81/0xa0 [dm_thin_pool]
[<ffffffffa039e735>] do_worker+0xc5/0x820 [dm_thin_pool]
[<ffffffff8152bf54>] ? __schedule+0x244/0x680
[<ffffffff81087e72>] ? pwq_activate_delayed_work+0x42/0xb0
[<ffffffff81089f53>] process_one_work+0x153/0x3f0
[<ffffffff8108a71b>] worker_thread+0x12b/0x4b0
[<ffffffff8108a5f0>] ? rescuer_thread+0x350/0x350
[<ffffffff8108fd6a>] kthread+0xca/0xe0
[<ffffffff8108fca0>] ? kthread_park+0x60/0x60
[<ffffffff81530b45>] ret_from_fork+0x25/0x30

The fix is to first take the block ref count for discarded block and then do a passdown discard of this block. If block ref count fails, then bail out aborting current metadata transaction, mark pool as PM_READ_ONLY and also free current thin mapping memory (existing error handling code) without queueing this thin mapping onto next stage of processing. If block ref count succeeds, then passdown discard of this block. Discard callback of passdown_endio() will queue this thin mapping onto next stage of processing.

Code flow with fix:
-> process_prepared_discard_passdown_pt1(m)
-> dm_thin_remove_range()
-> dm_pool_inc_data_range()

      --> if fails, free memory m and bail out
   -> discard passdown
      --> passdown_endio(m) queues m onto next stage
---
 drivers/md/dm-thin.c |   26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)
drivers/md/dm-thin.c +13 -13
@@ -1094,6 +1094,19 @@ static void process_prepared_discard_pas
 		return;
 	}
 
+	/*
+	 * Increment the unmapped blocks.  This prevents a race between the
+	 * passdown io and reallocation of freed blocks.
+	 */
+	r = dm_pool_inc_data_range(pool->pmd, m->data_block, data_end);
+	if (r) {
+		metadata_operation_failed(pool, "dm_pool_inc_data_range", r);
+		bio_io_error(m->bio);
+		cell_defer_no_holder(tc, m->cell);
+		mempool_free(m, pool->mapping_pool);
+		return;
+	}
+
 	discard_parent = bio_alloc(GFP_NOIO, 1);
 	if (!discard_parent) {
 		DMWARN("%s: unable to allocate top level discard bio for passdown. Skipping passdown.",
@@ -1114,19 +1127,6 @@ static void process_prepared_discard_pas
 			end_discard(&op, r);
 		}
 	}
-
-	/*
-	 * Increment the unmapped blocks.  This prevents a race between the
-	 * passdown io and reallocation of freed blocks.
-	 */
-	r = dm_pool_inc_data_range(pool->pmd, m->data_block, data_end);
-	if (r) {
-		metadata_operation_failed(pool, "dm_pool_inc_data_range", r);
-		bio_io_error(m->bio);
-		cell_defer_no_holder(tc, m->cell);
-		mempool_free(m, pool->mapping_pool);
-		return;
-	}
 }
 
 static void process_prepared_discard_passdown_pt2(struct dm_thin_new_mapping *m)
author maintainer
#49 lore raw

PATCH 51/84 x86/mm: Fix boot crash caused by incorrect loop count calculation in sync_global_pgds()

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Baoquan He <[email protected]>

commit fc5f9d5f151c9fff21d3d1d2907b888a5aec3ff7 upstream.

Jeff Moyer reported that on his system with two memory regions 0~64G and 1T~1T+192G, and kernel option "memmap=192G!1024G" added, enabling KASLR will make the system hang intermittently during boot. While adding 'nokaslr' won't.

The back trace is:

 Oops: 0000 [#1] SMP

 RIP: memcpy_erms()
 [ .... ]
 Call Trace:
  pmem_rw_page()
  bdev_read_page()
  do_mpage_readpage()
  mpage_readpages()
  blkdev_readpages()
  __do_page_cache_readahead()
  force_page_cache_readahead()
  page_cache_sync_readahead()
  generic_file_read_iter()
  blkdev_read_iter()
  __vfs_read()
  vfs_read()
  SyS_read()
  entry_SYSCALL_64_fastpath()

This crash happens because the for loop count calculation in sync_global_pgds() is not correct. When a mapping area crosses PGD entries, we should calculate the starting address of region which next PGD covers and assign it to next for loop count, but not add PGDIR_SIZE directly. The old code works right only if the mapping area is an exact multiple of PGDIR_SIZE, otherwize the end region could be skipped so that it can't be synchronized to all other processes from kernel PGD init_mm.pgd.

In Jeff's system, emulated pmem area [1024G, 1216G) is smaller than PGDIR_SIZE. While 'nokaslr' works because PAGE_OFFSET is 1T aligned, it makes this area be mapped inside one PGD entry. With KASLR enabled, this area could cross two PGD entries, then the next PGD entry won't be synced to all other processes. That is why we saw empty PGD.

Fix it.

Cc Andrew Morton <[email protected]>
Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Brian Gerst <[email protected]>
Cc Dan Williams <[email protected]>
Cc Dave Hansen <[email protected]>
Cc Dave Young <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Jinbum Park <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kees Cook <[email protected]>
Cc Kirill A. Shutemov <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Garnier <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc Yasuaki Ishimatsu <[email protected]>
Cc Yinghai Lu <[email protected]>
---
 arch/x86/mm/init_64.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/x86/mm/init_64.c +4 -4
@@ -94,10 +94,10 @@ __setup("noexec32=", nonx32_setup);
  */
 void sync_global_pgds(unsigned long start, unsigned long end)
 {
-	unsigned long address;
+	unsigned long addr;
 
-	for (address = start; address <= end; address += PGDIR_SIZE) {
-		const pgd_t *pgd_ref = pgd_offset_k(address);
+	for (addr = start; addr <= end; addr = ALIGN(addr + 1, PGDIR_SIZE)) {
+		const pgd_t *pgd_ref = pgd_offset_k(addr);
 		struct page *page;
 
 		if (pgd_none(*pgd_ref))
@@ -108,7 +108,7 @@ void sync_global_pgds(unsigned long star
 			pgd_t *pgd;
 			spinlock_t *pgt_lock;
 
-			pgd = (pgd_t *)page_address(page) + pgd_index(address);
+			pgd = (pgd_t *)page_address(page) + pgd_index(addr);
 			/* the pgt_lock only for Xen */
 			pgt_lock = &pgd_page_get_mm(page)->page_table_lock;
 			spin_lock(pgt_lock);
author maintainer
#50 lore raw

PATCH 52/84 pinctrl/amd: Use regular interrupt instead of chained

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Thomas Gleixner <[email protected]>

commit ba714a9c1dea85e0bf2899d02dfeb9c70040427c upstream.

The AMD pinctrl driver uses a chained interrupt to demultiplex the GPIO interrupts. Kevin Vandeventer reported, that his new AMD Ryzen locks up hard on boot when the AMD pinctrl driver is initialized. The reason is an interrupt storm. It's not clear whether that's caused by hardware or firmware or both.

Using chained interrupts on X86 is a dangerous endavour. If a system is misconfigured or the hardware buggy there is no safety net to catch an interrupt storm.

Convert the driver to use a regular interrupt for the demultiplex handler. This allows the interrupt storm detector to catch the malfunction and lets the system boot up.

This should be backported to stable because it's likely that more users run into this problem as the AMD Ryzen machines are spreading.

---
 drivers/pinctrl/pinctrl-amd.c |   91 ++++++++++++++++++------------------------
 1 file changed, 41 insertions(+), 50 deletions(-)
drivers/pinctrl/pinctrl-amd.c +41 -50
@@ -495,64 +495,54 @@ static struct irq_chip amd_gpio_irqchip
 	.flags        = IRQCHIP_SKIP_SET_WAKE,
 };
 
-static void amd_gpio_irq_handler(struct irq_desc *desc)
+#define PIN_IRQ_PENDING	(BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF))
+
+static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
 {
-	u32 i;
-	u32 off;
-	u32 reg;
-	u32 pin_reg;
-	u64 reg64;
-	int handled = 0;
-	unsigned int irq;
+	struct amd_gpio *gpio_dev = dev_id;
+	struct gpio_chip *gc = &gpio_dev->gc;
+	irqreturn_t ret = IRQ_NONE;
+	unsigned int i, irqnr;
 	unsigned long flags;
-	struct irq_chip *chip = irq_desc_get_chip(desc);
-	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
-	struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
+	u32 *regs, regval;
+	u64 status, mask;
 
-	chained_irq_enter(chip, desc);
-	/*enable GPIO interrupt again*/
+	/* Read the wake status */
 	spin_lock_irqsave(&gpio_dev->lock, flags);
-	reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
-	reg64 = reg;
-	reg64 = reg64 << 32;
-
-	reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
-	reg64 |= reg;
+	status = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
+	status <<= 32;
+	status |= readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
 	spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
-	/*
-	 * first 46 bits indicates interrupt status.
-	 * one bit represents four interrupt sources.
-	*/
-	for (off = 0; off < 46 ; off++) {
-		if (reg64 & BIT(off)) {
-			for (i = 0; i < 4; i++) {
-				pin_reg = readl(gpio_dev->base +
-						(off * 4 + i) * 4);
-				if ((pin_reg & BIT(INTERRUPT_STS_OFF)) ||
-					(pin_reg & BIT(WAKE_STS_OFF))) {
-					irq = irq_find_mapping(gc->irqdomain,
-								off * 4 + i);
-					generic_handle_irq(irq);
-					writel(pin_reg,
-						gpio_dev->base
-						+ (off * 4 + i) * 4);
-					handled++;
-				}
-			}
+	/* Bit 0-45 contain the relevant status bits */
+	status &= (1ULL << 46) - 1;
+	regs = gpio_dev->base;
+	for (mask = 1, irqnr = 0; status; mask <<= 1, regs += 4, irqnr += 4) {
+		if (!(status & mask))
+			continue;
+		status &= ~mask;
+
+		/* Each status bit covers four pins */
+		for (i = 0; i < 4; i++) {
+			regval = readl(regs + i);
+			if (!(regval & PIN_IRQ_PENDING))
+				continue;
+			irq = irq_find_mapping(gc->irqdomain, irqnr + i);
+			generic_handle_irq(irq);
+			/* Clear interrupt */
+			writel(regval, regs + i);
+			ret = IRQ_HANDLED;
 		}
 	}
 
-	if (handled == 0)
-		handle_bad_irq(desc);
-
+	/* Signal EOI to the GPIO unit */
 	spin_lock_irqsave(&gpio_dev->lock, flags);
-	reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
-	reg |= EOI_MASK;
-	writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG);
+	regval = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
+	regval |= EOI_MASK;
+	writel(regval, gpio_dev->base + WAKE_INT_MASTER_REG);
 	spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
-	chained_irq_exit(chip, desc);
+	return ret;
 }
 
 static int amd_get_groups_count(struct pinctrl_dev *pctldev)
@@ -821,10 +811,11 @@ static int amd_gpio_probe(struct platfor
 		goto out2;
 	}
 
-	gpiochip_set_chained_irqchip(&gpio_dev->gc,
-				 &amd_gpio_irqchip,
-				 irq_base,
-				 amd_gpio_irq_handler);
+	ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler, 0,
+			       KBUILD_MODNAME, gpio_dev);
+	if (ret)
+		goto out2;
+
 	platform_set_drvdata(pdev, gpio_dev);
 
 	dev_dbg(&pdev->dev, "amd gpio driver loaded\n");
author maintainer
#51 lore raw

PATCH 53/84 mm/vmalloc.c: huge-vmap: fail gracefully on unexpected huge vmap mappings

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Ard Biesheuvel <[email protected]>

commit 029c54b09599573015a5c18dbe59cbdf42742237 upstream.

Existing code that uses vmalloc_to_page() may assume that any address for which is_vmalloc_addr() returns true may be passed into vmalloc_to_page() to retrieve the associated struct page.

This is not un unreasonable assumption to make, but on architectures that have CONFIG_HAVE_ARCH_HUGE_VMAP=y, it no longer holds, and we need to ensure that vmalloc_to_page() does not go off into the weeds trying to dereference huge PUDs or PMDs as table entries.

Given that vmalloc() and vmap() themselves never create huge mappings or deal with compound pages at all, there is no correct answer in this case, so return NULL instead, and issue a warning.

When reading /proc/kcore on arm64, you will hit an oops as soon as you hit the huge mappings used for the various segments that make up the mapping of vmlinux. With this patch applied, you will no longer hit the oops, but the kcore contents willl be incorrect (these regions will be zeroed out)

We are fixing this for kcore specifically, so it avoids vread() for those regions. At least one other problematic user exists, i.e., /dev/kmem, but that is currently broken on arm64 for other reasons.

---
 mm/vmalloc.c |   15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)
mm/vmalloc.c +13 -2
@@ -287,10 +287,21 @@ struct page *vmalloc_to_page(const void
 	if (p4d_none(*p4d))
 		return NULL;
 	pud = pud_offset(p4d, addr);
-	if (pud_none(*pud))
+
+	/*
+	 * Don't dereference bad PUD or PMD (below) entries. This will also
+	 * identify huge mappings, which we may encounter on architectures
+	 * that define CONFIG_HAVE_ARCH_HUGE_VMAP=y. Such regions will be
+	 * identified as vmalloc addresses by is_vmalloc_addr(), but are
+	 * not [unambiguously] associated with a struct page, so there is
+	 * no correct value to return for them.
+	 */
+	WARN_ON_ONCE(pud_bad(*pud));
+	if (pud_none(*pud) || pud_bad(*pud))
 		return NULL;
 	pmd = pmd_offset(pud, addr);
-	if (pmd_none(*pmd))
+	WARN_ON_ONCE(pmd_bad(*pmd));
+	if (pmd_none(*pmd) || pmd_bad(*pmd))
 		return NULL;
 
 	ptep = pte_offset_map(pmd, addr);
author maintainer
#52 lore raw

PATCH 55/84 xfrm6: Fix IPv6 payload_len in xfrm6_transport_finish

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Yossi Kuperman <[email protected]>

commit 7c88e21aefcf86fb41b48b2e04528db5a30fbe18 upstream.

IPv6 payload length indicates the size of the payload, including any extension headers.

In xfrm6_transport_finish, ipv6_hdr(skb)->payload_len is set to the payload size only, regardless of the presence of any extension headers. After ESP GRO transport mode decapsulation, ipv6_rcv trims the packet according to the wrong payload_len, thus corrupting the packet.

Set payload_len to account for extension headers as well.

Fixes 7785bba299a8 ("esp: Add a software GRO codepath")
---
 net/ipv6/xfrm6_input.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv6/xfrm6_input.c +1 -1
@@ -43,8 +43,8 @@ int xfrm6_transport_finish(struct sk_buf
 		return 1;
 #endif
 
-	ipv6_hdr(skb)->payload_len = htons(skb->len);
 	__skb_push(skb, skb->data - skb_network_header(skb));
+	ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
 
 	if (xo && (xo->flags & XFRM_GRO)) {
 		skb_mac_header_rebuild(skb);
author maintainer
#53 lore raw

PATCH 56/84 xfrm: move xfrm_garbage_collect out of xfrm_policy_flush

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Hangbin Liu <[email protected]>

commit 138437f591dd9a42d53c6fed1a3c85e02678851c upstream.

Now we will force to do garbage collection if any policy removed in xfrm_policy_flush(). But during xfrm_net_exit(). We call flow_cache_fini() first and set set fc->percpu to NULL. Then after we call xfrm_policy_fini() -> frxm_policy_flush() -> flow_cache_flush(), we will get NULL pointer dereference when check percpu_empty. The code path looks like:

flow_cache_fini()
- fc->percpu = NULL
xfrm_policy_fini()
- xfrm_policy_flush()
- xfrm_garbage_collect()
- flow_cache_flush()
- flow_cache_percpu_empty()
- fcp = per_cpu_ptr(fc->percpu, cpu)

To reproduce, just add ipsec in netns and then remove the netns.

v2:
As Xin Long suggested, since only two other places need to call it. move xfrm_garbage_collect() outside xfrm_policy_flush().

v3:
Fix subject mismatch after v2 fix.

Fixes 35db06912189 ("xfrm: do the garbage collection after flushing policy")
---
 net/key/af_key.c       |    2 ++
 net/xfrm/xfrm_policy.c |    4 ----
 net/xfrm/xfrm_user.c   |    1 +
 3 files changed, 3 insertions(+), 4 deletions(-)
net/key/af_key.c +2 -0
@@ -2755,6 +2755,8 @@ static int pfkey_spdflush(struct sock *s
 	int err, err2;
 
 	err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, true);
+	if (!err)
+		xfrm_garbage_collect(net);
 	err2 = unicast_flush_resp(sk, hdr);
 	if (err || err2) {
 		if (err == -ESRCH) /* empty table - old silent behavior */
net/xfrm/xfrm_policy.c +0 -4
@@ -1006,10 +1006,6 @@ int xfrm_policy_flush(struct net *net, u
 		err = -ESRCH;
 out:
 	spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
-
-	if (cnt)
-		xfrm_garbage_collect(net);
-
 	return err;
 }
 EXPORT_SYMBOL(xfrm_policy_flush);
net/xfrm/xfrm_user.c +1 -0
@@ -1999,6 +1999,7 @@ static int xfrm_flush_policy(struct sk_b
 			return 0;
 		return err;
 	}
+	xfrm_garbage_collect(net);
 
 	c.data.type = type;
 	c.event = nlh->nlmsg_type;
author maintainer
#54 lore raw

PATCH 57/84 xfrm: fix stack access out of bounds with CONFIG_XFRM_SUB_POLICY

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Sabrina Dubroca <[email protected]>

commit 9b3eb54106cf6acd03f07cf0ab01c13676a226c2 upstream.

When CONFIG_XFRM_SUB_POLICY=y, xfrm_dst stores a copy of the flowi for that dst. Unfortunately, the code that allocates and fills this copy doesn't care about what type of flowi (flowi, flowi4, flowi6) gets passed. In multiple code paths (from raw_sendmsg, from TCP when replying to a FIN, in vxlan, geneve, and gre), the flowi that gets passed to xfrm is actually an on-stack flowi4, so we end up reading stuff from the stack past the end of the flowi4 struct.

Since xfrm_dst->origin isn't used anywhere following commit ca116922afa8 ("xfrm: Eliminate "fl" and "pol" args to xfrm_bundle_ok()."), just get rid of it. xfrm_dst->partner isn't used either, so get rid of that too.

Fixes 9d6ec938019c ("ipv4: Use flowi4 in public route lookup interfaces.")
---
 include/net/xfrm.h     |   10 ----------
 net/xfrm/xfrm_policy.c |   47 -----------------------------------------------
 2 files changed, 57 deletions(-)
include/net/xfrm.h +0 -10
@@ -945,10 +945,6 @@ struct xfrm_dst {
 	struct flow_cache_object flo;
 	struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
 	int num_pols, num_xfrms;
-#ifdef CONFIG_XFRM_SUB_POLICY
-	struct flowi *origin;
-	struct xfrm_selector *partner;
-#endif
 	u32 xfrm_genid;
 	u32 policy_genid;
 	u32 route_mtu_cached;
@@ -964,12 +960,6 @@ static inline void xfrm_dst_destroy(stru
 	dst_release(xdst->route);
 	if (likely(xdst->u.dst.xfrm))
 		xfrm_state_put(xdst->u.dst.xfrm);
-#ifdef CONFIG_XFRM_SUB_POLICY
-	kfree(xdst->origin);
-	xdst->origin = NULL;
-	kfree(xdst->partner);
-	xdst->partner = NULL;
-#endif
 }
 #endif
 
net/xfrm/xfrm_policy.c +0 -47

59 lines not on this page · raw message

author maintainer
#55 lore raw

PATCH 58/84 xfrm: NULL dereference on allocation failure

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Dan Carpenter <[email protected]>

commit e747f64336fc15e1c823344942923195b800aa1e upstream.

The default error code in pfkey_msg2xfrm_state() is -ENOBUFS. We added a new call to security_xfrm_state_alloc() which sets "err" to zero so there several places where we can return ERR_PTR(0) if kmalloc() fails. The caller is expecting error pointers so it leads to a NULL dereference.

Fixes df71837d5024 ("[LSM-IPSec]: Security association restriction.")
---
 net/key/af_key.c |    1 +
 1 file changed, 1 insertion(+)
net/key/af_key.c +1 -0
@@ -1157,6 +1157,7 @@ static struct xfrm_state * pfkey_msg2xfr
 			goto out;
 	}
 
+	err = -ENOBUFS;
 	key = ext_hdrs[SADB_EXT_KEY_AUTH - 1];
 	if (sa->sadb_sa_auth) {
 		int keysize = 0;
author maintainer
#56 lore raw

PATCH 59/84 xfrm: Oops on error in pfkey_msg2xfrm_state()

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Dan Carpenter <[email protected]>

commit 1e3d0c2c70cd3edb5deed186c5f5c75f2b84a633 upstream.

There are some missing error codes here so we accidentally return NULL instead of an error pointer. It results in a NULL pointer dereference.

Fixes df71837d5024 ("[LSM-IPSec]: Security association restriction.")
---
 net/key/af_key.c |   16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
net/key/af_key.c +12 -4
@@ -1169,8 +1169,10 @@ static struct xfrm_state * pfkey_msg2xfr
 		if (key)
 			keysize = (key->sadb_key_bits + 7) / 8;
 		x->aalg = kmalloc(sizeof(*x->aalg) + keysize, GFP_KERNEL);
-		if (!x->aalg)
+		if (!x->aalg) {
+			err = -ENOMEM;
 			goto out;
+		}
 		strcpy(x->aalg->alg_name, a->name);
 		x->aalg->alg_key_len = 0;
 		if (key) {
@@ -1189,8 +1191,10 @@ static struct xfrm_state * pfkey_msg2xfr
 				goto out;
 			}
 			x->calg = kmalloc(sizeof(*x->calg), GFP_KERNEL);
-			if (!x->calg)
+			if (!x->calg) {
+				err = -ENOMEM;
 				goto out;
+			}
 			strcpy(x->calg->alg_name, a->name);
 			x->props.calgo = sa->sadb_sa_encrypt;
 		} else {
@@ -1204,8 +1208,10 @@ static struct xfrm_state * pfkey_msg2xfr
 			if (key)
 				keysize = (key->sadb_key_bits + 7) / 8;
 			x->ealg = kmalloc(sizeof(*x->ealg) + keysize, GFP_KERNEL);
-			if (!x->ealg)
+			if (!x->ealg) {
+				err = -ENOMEM;
 				goto out;
+			}
 			strcpy(x->ealg->alg_name, a->name);
 			x->ealg->alg_key_len = 0;
 			if (key) {
@@ -1250,8 +1256,10 @@ static struct xfrm_state * pfkey_msg2xfr
 		struct xfrm_encap_tmpl *natt;
 
 		x->encap = kmalloc(sizeof(*x->encap), GFP_KERNEL);
-		if (!x->encap)
+		if (!x->encap) {
+			err = -ENOMEM;
 			goto out;
+		}
 
 		natt = x->encap;
 		n_type = ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1];
author maintainer
#57 lore raw

PATCH 60/84 watchdog: bcm281xx: Fix use of uninitialized spinlock.

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Eric Anholt <[email protected]>

commit fedf266f9955d9a019643cde199a2fd9a0259f6f upstream.

The bcm_kona_wdt_set_resolution_reg() call takes the spinlock, so initialize it earlier. Fixes a warning at boot with lock debugging enabled.

---
 drivers/watchdog/bcm_kona_wdt.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/watchdog/bcm_kona_wdt.c +2 -1
@@ -304,6 +304,8 @@ static int bcm_kona_wdt_probe(struct pla
 	if (!wdt)
 		return -ENOMEM;
 
+	spin_lock_init(&wdt->lock);
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	wdt->base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(wdt->base))
@@ -316,7 +318,6 @@ static int bcm_kona_wdt_probe(struct pla
 		return ret;
 	}
 
-	spin_lock_init(&wdt->lock);
 	platform_set_drvdata(pdev, wdt);
 	watchdog_set_drvdata(&bcm_kona_wdt_wdd, wdt);
 	bcm_kona_wdt_wdd.parent = &pdev->dev;
author maintainer
#58 lore raw

PATCH 61/84 ARM64: PCI: Fix struct acpi_pci_root_ops allocation failure path

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Timmy Li <[email protected]>

commit 717902cc93118119a6fce7765da6cf2786987418 upstream.

Commit 093d24a20442 ("arm64: PCI: Manage controller-specific data on per-controller basis") added code to allocate ACPI PCI root_ops dynamically on a per host bridge basis but failed to update the corresponding memory allocation failure path in pci_acpi_scan_root() leading to a potential memory leakage.

Fix it by adding the required kfree call.

Fixes 093d24a20442 ("arm64: PCI: Manage controller-specific data on per-controller basis")
[[email protected]: refactored code, rewrote commit log]
CC Will Deacon <[email protected]>
CC Bjorn Helgaas <[email protected]>
---
 arch/arm64/kernel/pci.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
arch/arm64/kernel/pci.c +3 -1
@@ -191,8 +191,10 @@ struct pci_bus *pci_acpi_scan_root(struc
 		return NULL;
 
 	root_ops = kzalloc_node(sizeof(*root_ops), GFP_KERNEL, node);
-	if (!root_ops)
+	if (!root_ops) {
+		kfree(ri);
 		return NULL;
+	}
 
 	ri->cfg = pci_acpi_setup_ecam_mapping(root);
 	if (!ri->cfg) {
author maintainer
#59 lore raw

PATCH 62/84 ARM64/ACPI: Fix BAD_MADT_GICC_ENTRY() macro implementation

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Lorenzo Pieralisi <[email protected]>

commit cb7cf772d83d2d4e6995c5bb9e0fb59aea8f7080 upstream.

The BAD_MADT_GICC_ENTRY() macro checks if a GICC MADT entry passes muster from an ACPI specification standpoint. Current macro detects the MADT GICC entry length through ACPI firmware version (it changed from 76 to 80 bytes in the transition from ACPI 5.1 to ACPI 6.0 specification) but always uses (erroneously) the ACPICA (latest) struct (ie struct acpi_madt_generic_interrupt - that is 80-bytes long) length to check if the current GICC entry memory record exceeds the MADT table end in memory as defined by the MADT table header itself, which may result in false negatives depending on the ACPI firmware version and how the MADT entries are laid out in memory (ie on ACPI 5.1 firmware MADT GICC entries are 76 bytes long, so by adding 80 to a GICC entry start address in memory the resulting address may well be past the actual MADT end, triggering a false negative).

Fix the BAD_MADT_GICC_ENTRY() macro by reshuffling the condition checks and update them to always use the firmware version specific MADT GICC entry length in order to carry out boundary checks.

Fixes b6cfb277378e ("ACPI / ARM64: add BAD_MADT_GICC_ENTRY() macro")
Cc Julien Grall <[email protected]>
Cc Hanjun Guo <[email protected]>
Cc Al Stone <[email protected]>
---
 arch/arm64/include/asm/acpi.h |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm64/include/asm/acpi.h +3 -3
@@ -23,9 +23,9 @@
 #define ACPI_MADT_GICC_LENGTH	\
 	(acpi_gbl_FADT.header.revision < 6 ? 76 : 80)
 
-#define BAD_MADT_GICC_ENTRY(entry, end)						\
-	(!(entry) || (unsigned long)(entry) + sizeof(*(entry)) > (end) ||	\
-	 (entry)->header.length != ACPI_MADT_GICC_LENGTH)
+#define BAD_MADT_GICC_ENTRY(entry, end)					\
+	(!(entry) || (entry)->header.length != ACPI_MADT_GICC_LENGTH ||	\
+	(unsigned long)(entry) + ACPI_MADT_GICC_LENGTH > (end))
 
 /* Basic configuration for ACPI */
 #ifdef	CONFIG_ACPI
author maintainer
#60 lore raw

PATCH 63/84 ARM: 8685/1: ensure memblock-limit is pmd-aligned

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Doug Berger <[email protected]>

commit 9e25ebfe56ece7541cd10a20d715cbdd148a2e06 upstream.

The pmd containing memblock_limit is cleared by prepare_page_table() which creates the opportunity for early_alloc() to allocate unmapped memory if memblock_limit is not pmd aligned causing a boot-time hang.

Commit 965278dcb8ab ("ARM: 8356/1: mm: handle non-pmd-aligned end of RAM") attempted to resolve this problem, but there is a path through the adjust_lowmem_bounds() routine where if all memory regions start and end on pmd-aligned addresses the memblock_limit will be set to arm_lowmem_limit.

Since arm_lowmem_limit can be affected by the vmalloc early parameter, the value of arm_lowmem_limit may not be pmd-aligned. This commit corrects this oversight such that memblock_limit is always rounded down to pmd-alignment.

Fixes 965278dcb8ab ("ARM: 8356/1: mm: handle non-pmd-aligned end of RAM")
---
 arch/arm/mm/mmu.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm/mm/mmu.c +4 -4
@@ -1216,15 +1216,15 @@ void __init adjust_lowmem_bounds(void)
 
 	high_memory = __va(arm_lowmem_limit - 1) + 1;
 
+	if (!memblock_limit)
+		memblock_limit = arm_lowmem_limit;
+
 	/*
 	 * Round the memblock limit down to a pmd size.  This
 	 * helps to ensure that we will allocate memory from the
 	 * last full pmd, which should be mapped.
 	 */
-	if (memblock_limit)
-		memblock_limit = round_down(memblock_limit, PMD_SIZE);
-	if (!memblock_limit)
-		memblock_limit = arm_lowmem_limit;
+	memblock_limit = round_down(memblock_limit, PMD_SIZE);
 
 	if (!IS_ENABLED(CONFIG_HIGHMEM) || cache_is_vipt_aliasing()) {
 		if (memblock_end_of_DRAM() > arm_lowmem_limit) {
author maintainer
#61 lore raw

PATCH 64/84 ARM: davinci: PM: Free resources in error handling path in davinci_pm_init

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Christophe JAILLET <[email protected]>

commit f3f6cc814f9cb61cfb738af2b126a8bf19e5ab4c upstream.

If 'sram_alloc' fails, we need to free already allocated resources.

Fixes aa9aa1ec2df6 ("ARM: davinci: PM: rework init, remove platform device")
---
 arch/arm/mach-davinci/pm.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
arch/arm/mach-davinci/pm.c +4 -1
@@ -154,7 +154,8 @@ int __init davinci_pm_init(void)
 	davinci_sram_suspend = sram_alloc(davinci_cpu_suspend_sz, NULL);
 	if (!davinci_sram_suspend) {
 		pr_err("PM: cannot allocate SRAM memory\n");
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto no_sram_mem;
 	}
 
 	davinci_sram_push(davinci_sram_suspend, davinci_cpu_suspend,
@@ -162,6 +163,8 @@ int __init davinci_pm_init(void)
 
 	suspend_set_ops(&davinci_pm_ops);
 
+no_sram_mem:
+	iounmap(pm_config.ddrpsc_reg_base);
 no_ddrpsc_mem:
 	iounmap(pm_config.ddrpll_reg_base);
 no_ddrpll_mem:
author maintainer
#62 lore raw

PATCH 65/84 ARM: davinci: PM: Do not free useful resources in normal path in davinci_pm_init

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Christophe JAILLET <[email protected]>

commit 95d7c1f18bf8ac03b0fc48eac1f1b11f867765b8 upstream.

It is wrong to iounmap resources in the normal path of davinci_pm_init()

The 3 ioremap'ed fields of 'pm_config' can be accessed later on in other functions, so we should return 'success' instead of unrolling everything.

Fixes aa9aa1ec2df6 ("ARM: davinci: PM: rework init, remove platform device")
[[email protected]: commit message and minor style fixes]
---
 arch/arm/mach-davinci/pm.c |    2 ++
 1 file changed, 2 insertions(+)
arch/arm/mach-davinci/pm.c +2 -0
@@ -163,6 +163,8 @@ int __init davinci_pm_init(void)
 
 	suspend_set_ops(&davinci_pm_ops);
 
+	return 0;
+
 no_sram_mem:
 	iounmap(pm_config.ddrpsc_reg_base);
 no_ddrpsc_mem:
author maintainer
#63 lore raw

PATCH 66/84 tools arch: Sync arch/x86/lib/memcpy_64.S with the kernel

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Arnaldo Carvalho de Melo <[email protected]>

commit e883d09c9eb2ffddfd057c17e6a0cef446ec8c9b upstream.

Just a minor fix done in:

Fixes 26a37ab319a2 ("x86/mce: Fix copy/paste error in exception table entries")
---
 tools/arch/x86/lib/memcpy_64.S |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/arch/x86/lib/memcpy_64.S +1 -1
@@ -286,7 +286,7 @@ ENDPROC(memcpy_mcsafe_unrolled)
 	_ASM_EXTABLE_FAULT(.L_copy_leading_bytes, .L_memcpy_mcsafe_fail)
 	_ASM_EXTABLE_FAULT(.L_cache_w0, .L_memcpy_mcsafe_fail)
 	_ASM_EXTABLE_FAULT(.L_cache_w1, .L_memcpy_mcsafe_fail)
-	_ASM_EXTABLE_FAULT(.L_cache_w3, .L_memcpy_mcsafe_fail)
+	_ASM_EXTABLE_FAULT(.L_cache_w2, .L_memcpy_mcsafe_fail)
 	_ASM_EXTABLE_FAULT(.L_cache_w3, .L_memcpy_mcsafe_fail)
 	_ASM_EXTABLE_FAULT(.L_cache_w4, .L_memcpy_mcsafe_fail)
 	_ASM_EXTABLE_FAULT(.L_cache_w5, .L_memcpy_mcsafe_fail)
author maintainer
#64 lore raw

PATCH 67/84 Revert "x86/entry: Fix the end of the stack for newly forked tasks"

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Josh Poimboeuf <[email protected]>

commit ebd574994c63164d538a197172157318f58ac647 upstream.

Petr Mladek reported the following warning when loading the livepatch sample module:

  WARNING: CPU: 1 PID: 3699 at arch/x86/kernel/stacktrace.c:132 save_stack_trace_tsk_reliable+0x133/0x1a0
  ...
  Call Trace:
   __schedule+0x273/0x820
   schedule+0x36/0x80
   kthreadd+0x305/0x310
   ? kthread_create_on_cpu+0x80/0x80
   ? icmp_echo.part.32+0x50/0x50
   ret_from_fork+0x2c/0x40

That warning means the end of the stack is no longer recognized as such for newly forked tasks. The problem was introduced with the following commit:

ff3f7e2475bb ("x86/entry: Fix the end of the stack for newly forked tasks")

... which was completely misguided. It only partially fixed the reported issue, and it introduced another bug in the process. None of the other entry code saves the frame pointer before calling into C code, so it doesn't make sense for ret_from_fork to do so either.

Contrary to what I originally thought, the original issue wasn't related to newly forked tasks. It was actually related to ftrace. When entry code calls into a function which then calls into an ftrace handler, the stack frame looks different than normal.

The original issue will be fixed in the unwinder, in a subsequent patch.

---
 arch/x86/entry/entry_32.S |   30 +++++++++++++++++++-----------
 arch/x86/entry/entry_64.S |   11 ++++-------
 2 files changed, 23 insertions(+), 18 deletions(-)
arch/x86/entry/entry_32.S +19 -11
@@ -255,6 +255,23 @@ ENTRY(__switch_to_asm)
 END(__switch_to_asm)
 
 /*
+ * The unwinder expects the last frame on the stack to always be at the same
+ * offset from the end of the page, which allows it to validate the stack.
+ * Calling schedule_tail() directly would break that convention because its an
+ * asmlinkage function so its argument has to be pushed on the stack.  This
+ * wrapper creates a proper "end of stack" frame header before the call.
+ */
+ENTRY(schedule_tail_wrapper)
+	FRAME_BEGIN
+
+	pushl	%eax
+	call	schedule_tail
+	popl	%eax
+
+	FRAME_END
+	ret
+ENDPROC(schedule_tail_wrapper)
+/*
  * A newly forked process directly context switches into this address.
  *
  * eax: prev task we switched from
@@ -262,24 +279,15 @@ END(__switch_to_asm)
  * edi: kernel thread arg
  */
 ENTRY(ret_from_fork)
-	FRAME_BEGIN		/* help unwinder find end of stack */
-
-	/*
-	 * schedule_tail() is asmlinkage so we have to put its 'prev' argument
-	 * on the stack.
-	 */
-	pushl	%eax
-	call	schedule_tail
-	popl	%eax
+	call	schedule_tail_wrapper
 
 	testl	%ebx, %ebx
 	jnz	1f		/* kernel threads are uncommon */
 
 2:
 	/* When we fork, we trace the syscall return in the child, too. */
-	leal	FRAME_OFFSET(%esp), %eax
+	movl    %esp, %eax
 	call    syscall_return_slowpath
-	FRAME_END
 	jmp     restore_all
 
 	/* kernel thread */
arch/x86/entry/entry_64.S +4 -7
@@ -36,7 +36,6 @@
 #include <asm/smap.h>
 #include <asm/pgtable_types.h>
 #include <asm/export.h>
-#include <asm/frame.h>
 #include <linux/err.h>
 
 .code64
@@ -409,19 +408,17 @@ END(__switch_to_asm)
  * r12: kernel thread arg
  */
 ENTRY(ret_from_fork)
-	FRAME_BEGIN			/* help unwinder find end of stack */
 	movq	%rax, %rdi
-	call	schedule_tail		/* rdi: 'prev' task parameter */
+	call	schedule_tail			/* rdi: 'prev' task parameter */
 
-	testq	%rbx, %rbx		/* from kernel_thread? */
-	jnz	1f			/* kernel threads are uncommon */
+	testq	%rbx, %rbx			/* from kernel_thread? */
+	jnz	1f				/* kernel threads are uncommon */
 
 2:
-	leaq	FRAME_OFFSET(%rsp),%rdi	/* pt_regs pointer */
+	movq	%rsp, %rdi
 	call	syscall_return_slowpath	/* returns with IRQs disabled */
 	TRACE_IRQS_ON			/* user mode is traced as IRQS on */
 	SWAPGS
-	FRAME_END
 	jmp	restore_regs_and_iret
 
 1:
author maintainer
#65 lore raw

PATCH 68/84 x86/mshyperv: Remove excess #includes from mshyperv.h

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Thomas Gleixner <[email protected]>

commit 26fcd952d5c977a94ac64bb44ed409e37607b2c9 upstream.

A recent commit included linux/slab.h in linux/irq.h. This breaks the build of vdso32 on a 64-bit kernel.

The reason is that linux/irq.h gets included into the vdso code via linux/interrupt.h which is included from asm/mshyperv.h. That makes the 32-bit vdso compile fail, because slab.h includes the pgtable headers for 64-bit on a 64-bit build.

Neither linux/clocksource.h nor linux/interrupt.h are needed in the mshyperv.h header file itself - it has a dependency on <linux/atomic.h>.

Remove the includes and unbreak the build.

Cc K. Y. Srinivasan <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Vitaly Kuznetsov <[email protected]>
Fixes dee863b571b0 ("hv: export current Hyper-V clocksource")
---
 arch/x86/include/asm/mshyperv.h |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
arch/x86/include/asm/mshyperv.h +1 -2
@@ -2,8 +2,7 @@
 #define _ASM_X86_MSHYPER_H
 
 #include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/clocksource.h>
+#include <linux/atomic.h>
 #include <asm/hyperv.h>
 
 /*
author maintainer
#66 lore raw

PATCH 69/84 x86/boot/KASLR: Fix kexec crash due to virt_addr calculation bug

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Baoquan He <[email protected]>

commit 8eabf42ae5237e6b699aeac687b5b629e3537c8d upstream.

Kernel text KASLR is separated into physical address and virtual address randomization. And for virtual address randomization, we only randomiza to get an offset between 16M and KERNEL_IMAGE_SIZE. So the initial value of 'virt_addr' should be LOAD_PHYSICAL_ADDR, but not the original kernel loading address 'output'.

The bug will cause kernel boot failure if kernel is loaded at a different position than the address, 16M, which is decided at compiled time. Kexec/kdump is such practical case.

To fix it, just assign LOAD_PHYSICAL_ADDR to virt_addr as initial value.

Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
Fixes 8391c73 ("x86/KASLR: Randomize virtual address separately")
---
 arch/x86/boot/compressed/kaslr.c |    3 ---
 arch/x86/boot/compressed/misc.c  |    4 ++--
 arch/x86/boot/compressed/misc.h  |    2 --
 3 files changed, 2 insertions(+), 7 deletions(-)
arch/x86/boot/compressed/kaslr.c +0 -3
@@ -564,9 +564,6 @@ void choose_random_location(unsigned lon
 {
 	unsigned long random_addr, min_addr;
 
-	/* By default, keep output position unchanged. */
-	*virt_addr = *output;
-
 	if (cmdline_find_option_bool("nokaslr")) {
 		warn("KASLR disabled: 'nokaslr' on cmdline.");
 		return;
arch/x86/boot/compressed/misc.c +2 -2
@@ -338,7 +338,7 @@ asmlinkage __visible void *extract_kerne
 				  unsigned long output_len)
 {
 	const unsigned long kernel_total_size = VO__end - VO__text;
-	unsigned long virt_addr = (unsigned long)output;
+	unsigned long virt_addr = LOAD_PHYSICAL_ADDR;
 
 	/* Retain x86 boot parameters pointer passed from startup_32/64. */
 	boot_params = rmode;
@@ -397,7 +397,7 @@ asmlinkage __visible void *extract_kerne
 #ifndef CONFIG_RELOCATABLE
 	if ((unsigned long)output != LOAD_PHYSICAL_ADDR)
 		error("Destination address does not match LOAD_PHYSICAL_ADDR");
-	if ((unsigned long)output != virt_addr)
+	if (virt_addr != LOAD_PHYSICAL_ADDR)
 		error("Destination virtual address changed when not relocatable");
 #endif
 
arch/x86/boot/compressed/misc.h +0 -2
@@ -81,8 +81,6 @@ static inline void choose_random_locatio
 					  unsigned long output_size,
 					  unsigned long *virt_addr)
 {
-	/* No change from existing output location. */
-	*virt_addr = *output;
 }
 #endif
 
author maintainer
#67 lore raw

PATCH 70/84 perf/x86: Fix spurious NMI with PEBS Load Latency event

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Kan Liang <[email protected]>

commit fd583ad1563bec5f00140e1f2444adbcd331caad upstream.

Spurious NMIs will be observed with the following command:

while :; do

    perf record -bae "cpu/umask=0x01,event=0xcd,ldlat=0x80/pp"
                  -e "cpu/umask=0x03,event=0x0/"
                  -e "cpu/umask=0x02,event=0x0/"
                  -e cycles,branches,cache-misses
                  -e cache-references -- sleep 10

done

The bug was introduced by commit:

8077eca079a2 ("perf/x86/pebs: Add workaround for broken OVFL status on HSW+")

That commit clears the status bits for the counters used for PEBS events, by masking the whole 64 bits pebs_enabled. However, only the low 32 bits of both status and pebs_enabled are reserved for PEBS-able counters.

For status bits 32-34 are fixed counter overflow bits. For pebs_enabled bits 32-34 are for PEBS Load Latency.

In the test case, the PEBS Load Latency event and fixed counter event could overflow at the same time. The fixed counter overflow bit will be cleared by mistake. Once it is cleared, the fixed counter overflow never be processed, which finally trigger spurious NMI.

Correct the PEBS enabled mask by ignoring the non-PEBS bits.

Cc Alexander Shishkin <[email protected]>
Cc Arnaldo Carvalho de Melo <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc Vince Weaver <[email protected]>
Fixes 8077eca079a2 ("perf/x86/pebs: Add workaround for broken OVFL status on HSW+")
---
 arch/x86/events/intel/core.c |    2 +-
 arch/x86/events/intel/ds.c   |    2 +-
 arch/x86/events/perf_event.h |    1 +
 3 files changed, 3 insertions(+), 2 deletions(-)
arch/x86/events/intel/core.c +1 -1
@@ -2130,7 +2130,7 @@ again:
 	 * counters from the GLOBAL_STATUS mask and we always process PEBS
 	 * events via drain_pebs().
 	 */
-	status &= ~cpuc->pebs_enabled;
+	status &= ~(cpuc->pebs_enabled & PEBS_COUNTER_MASK);
 
 	/*
 	 * PEBS overflow sets bit 62 in the global status register
arch/x86/events/intel/ds.c +1 -1
@@ -1222,7 +1222,7 @@ get_next_pebs_record_by_bit(void *base,
 
 			/* clear non-PEBS bit and re-check */
 			pebs_status = p->status & cpuc->pebs_enabled;
-			pebs_status &= (1ULL << MAX_PEBS_EVENTS) - 1;
+			pebs_status &= PEBS_COUNTER_MASK;
 			if (pebs_status == (1 << bit))
 				return at;
 		}
arch/x86/events/perf_event.h +1 -0
@@ -79,6 +79,7 @@ struct amd_nb {
 
 /* The maximal number of PEBS events: */
 #define MAX_PEBS_EVENTS		8
+#define PEBS_COUNTER_MASK	((1ULL << MAX_PEBS_EVENTS) - 1)
 
 /*
  * Flags PEBS can handle without an PMI.
author maintainer
#68 lore raw

PATCH 71/84 x86/mpx: Correctly report do_mpx_bt_fault() failures to user-space

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Joerg Roedel <[email protected]>

commit 5ed386ec09a5d75bcf073967e55e895c2607a5c3 upstream.

When this function fails it just sends a SIGSEGV signal to user-space using force_sig(). This signal is missing essential information about the cause, e.g. the trap_nr or an error code.

Fix this by propagating the error to the only caller of mpx_handle_bd_fault(), do_bounds(), which sends the correct SIGSEGV signal to the process.

Cc Andy Lutomirski <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Brian Gerst <[email protected]>
Cc Dave Hansen <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
Fixes fe3d197f84319 ('x86, mpx: On-demand kernel allocation of bounds tables')
---
 arch/x86/mm/mpx.c |   10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)
arch/x86/mm/mpx.c +1 -9
@@ -526,15 +526,7 @@ int mpx_handle_bd_fault(void)
 	if (!kernel_managing_mpx_tables(current->mm))
 		return -EINVAL;
 
-	if (do_mpx_bt_fault()) {
-		force_sig(SIGSEGV, current);
-		/*
-		 * The force_sig() is essentially "handling" this
-		 * exception, so we do not pass up the error
-		 * from do_mpx_bt_fault().
-		 */
-	}
-	return 0;
+	return do_mpx_bt_fault();
 }
 
 /*
author maintainer
#69 lore raw

PATCH 72/84 x86/mm: Fix flush_tlb_page() on Xen

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Andy Lutomirski <[email protected]>

commit dbd68d8e84c606673ebbcf15862f8c155fa92326 upstream.

flush_tlb_page() passes a bogus range to flush_tlb_others() and expects the latter to fix it up. native_flush_tlb_others() has the fixup but Xen's version doesn't. Move the fixup to flush_tlb_others().

AFAICS the only real effect is that, without this fix, Xen would flush everything instead of just the one page on remote vCPUs in when flush_tlb_page() was called.

Cc Andrew Morton <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Brian Gerst <[email protected]>
Cc Dave Hansen <[email protected]>
Cc Denys Vlasenko <[email protected]>
Cc H. Peter Anvin <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Juergen Gross <[email protected]>
Cc Konrad Rzeszutek Wilk <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Nadav Amit <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Rik van Riel <[email protected]>
Cc Thomas Gleixner <[email protected]>
Fixes e7b52ffd45a6 ("x86/flush_tlb: try flush_tlb_single one by one in flush_tlb_range")
---
 arch/x86/mm/tlb.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
arch/x86/mm/tlb.c +1 -3
@@ -263,8 +263,6 @@ void native_flush_tlb_others(const struc
 {
 	struct flush_tlb_info info;
 
-	if (end == 0)
-		end = start + PAGE_SIZE;
 	info.flush_mm = mm;
 	info.flush_start = start;
 	info.flush_end = end;
@@ -393,7 +391,7 @@ void flush_tlb_page(struct vm_area_struc
 	}
 
 	if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids)
-		flush_tlb_others(mm_cpumask(mm), mm, start, 0UL);
+		flush_tlb_others(mm_cpumask(mm), mm, start, start + PAGE_SIZE);
 
 	preempt_enable();
 }
author maintainer
#70 lore raw

PATCH 73/84 ocfs2: o2hb: revert hb threshold to keep compatible

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Junxiao Bi <[email protected]>

commit 33496c3c3d7b88dcbe5e55aa01288b05646c6aca upstream.

Configfs is the interface for ocfs2-tools to set configure to kernel and $configfs_dir/cluster/$clustername/heartbeat/dead_threshold is the one used to configure heartbeat dead threshold. Kernel has a default value of it but user can set O2CB_HEARTBEAT_THRESHOLD in /etc/sysconfig/o2cb to override it.

Commit 45b997737a80 ("ocfs2/cluster: use per-attribute show and store methods") changed heartbeat dead threshold name while ocfs2-tools did not, so ocfs2-tools won't set this configurable and the default value is always used. So revert it.

Fixes 45b997737a80 ("ocfs2/cluster: use per-attribute show and store methods")
Cc Mark Fasheh <[email protected]>
Cc Joel Becker <[email protected]>
---
 fs/ocfs2/cluster/heartbeat.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
fs/ocfs2/cluster/heartbeat.c +4 -4
@@ -2242,13 +2242,13 @@ unlock:
 	spin_unlock(&o2hb_live_lock);
 }
 
-static ssize_t o2hb_heartbeat_group_threshold_show(struct config_item *item,
+static ssize_t o2hb_heartbeat_group_dead_threshold_show(struct config_item *item,
 		char *page)
 {
 	return sprintf(page, "%u\n", o2hb_dead_threshold);
 }
 
-static ssize_t o2hb_heartbeat_group_threshold_store(struct config_item *item,
+static ssize_t o2hb_heartbeat_group_dead_threshold_store(struct config_item *item,
 		const char *page, size_t count)
 {
 	unsigned long tmp;
@@ -2297,11 +2297,11 @@ static ssize_t o2hb_heartbeat_group_mode
 
 }
 
-CONFIGFS_ATTR(o2hb_heartbeat_group_, threshold);
+CONFIGFS_ATTR(o2hb_heartbeat_group_, dead_threshold);
 CONFIGFS_ATTR(o2hb_heartbeat_group_, mode);
 
 static struct configfs_attribute *o2hb_heartbeat_group_attrs[] = {
-	&o2hb_heartbeat_group_attr_threshold,
+	&o2hb_heartbeat_group_attr_dead_threshold,
 	&o2hb_heartbeat_group_attr_mode,
 	NULL,
 };
author maintainer
#71 lore raw

PATCH 74/84 ocfs2: fix deadlock caused by recursive locking in xattr

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Eric Ren <[email protected]>

commit 8818efaaacb78c60a9d90c5705b6c99b75d7d442 upstream.

Another deadlock path caused by recursive locking is reported. This kind of issue was introduced since commit 743b5f1434f5 ("ocfs2: take inode lock in ocfs2_iop_set/get_acl()"). Two deadlock paths have been fixed by commit b891fa5024a9 ("ocfs2: fix deadlock issue when taking inode lock at vfs entry points"). Yes, we intend to fix this kind of case in incremental way, because it's hard to find out all possible paths at once.

This one can be reproduced like this. On node1, cp a large file from home directory to ocfs2 mountpoint. While on node2, run setfacl/getfacl. Both nodes will hang up there. The backtraces:

On node1:

  __ocfs2_cluster_lock.isra.39+0x357/0x740 [ocfs2]
  ocfs2_inode_lock_full_nested+0x17d/0x840 [ocfs2]
  ocfs2_write_begin+0x43/0x1a0 [ocfs2]
  generic_perform_write+0xa9/0x180
  __generic_file_write_iter+0x1aa/0x1d0
  ocfs2_file_write_iter+0x4f4/0xb40 [ocfs2]
  __vfs_write+0xc3/0x130
  vfs_write+0xb1/0x1a0
  SyS_write+0x46/0xa0

On node2:

  __ocfs2_cluster_lock.isra.39+0x357/0x740 [ocfs2]
  ocfs2_inode_lock_full_nested+0x17d/0x840 [ocfs2]
  ocfs2_xattr_set+0x12e/0xe80 [ocfs2]
  ocfs2_set_acl+0x22d/0x260 [ocfs2]
  ocfs2_iop_set_acl+0x65/0xb0 [ocfs2]
  set_posix_acl+0x75/0xb0
  posix_acl_xattr_set+0x49/0xa0
  __vfs_setxattr+0x69/0x80
  __vfs_setxattr_noperm+0x72/0x1a0
  vfs_setxattr+0xa7/0xb0
  setxattr+0x12d/0x190
  path_setxattr+0x9f/0xb0
  SyS_setxattr+0x14/0x20

Fix this one by using ocfs2_inode_{lock|unlock}_tracker, which is exported by commit 439a36b8ef38 ("ocfs2/dlmglue: prepare tracking logic to avoid recursive cluster lock").

---
 fs/ocfs2/dlmglue.c |    4 ++++
 fs/ocfs2/xattr.c   |   23 +++++++++++++----------
 2 files changed, 17 insertions(+), 10 deletions(-)
fs/ocfs2/dlmglue.c +4 -0
@@ -2591,6 +2591,10 @@ void ocfs2_inode_unlock_tracker(struct i
 	struct ocfs2_lock_res *lockres;
 
 	lockres = &OCFS2_I(inode)->ip_inode_lockres;
+	/* had_lock means that the currect process already takes the cluster
+	 * lock previously. If had_lock is 1, we have nothing to do here, and
+	 * it will get unlocked where we got the lock.
+	 */
 	if (!had_lock) {
 		ocfs2_remove_holder(lockres, oh);
 		ocfs2_inode_unlock(inode, ex);
fs/ocfs2/xattr.c +13 -10
@@ -1328,20 +1328,21 @@ static int ocfs2_xattr_get(struct inode
 			   void *buffer,
 			   size_t buffer_size)
 {
-	int ret;
+	int ret, had_lock;
 	struct buffer_head *di_bh = NULL;
+	struct ocfs2_lock_holder oh;
 
-	ret = ocfs2_inode_lock(inode, &di_bh, 0);
-	if (ret < 0) {
-		mlog_errno(ret);
-		return ret;
+	had_lock = ocfs2_inode_lock_tracker(inode, &di_bh, 0, &oh);
+	if (had_lock < 0) {
+		mlog_errno(had_lock);
+		return had_lock;
 	}
 	down_read(&OCFS2_I(inode)->ip_xattr_sem);
 	ret = ocfs2_xattr_get_nolock(inode, di_bh, name_index,
 				     name, buffer, buffer_size);
 	up_read(&OCFS2_I(inode)->ip_xattr_sem);
 
-	ocfs2_inode_unlock(inode, 0);
+	ocfs2_inode_unlock_tracker(inode, 0, &oh, had_lock);
 
 	brelse(di_bh);
 
@@ -3537,11 +3538,12 @@ int ocfs2_xattr_set(struct inode *inode,
 {
 	struct buffer_head *di_bh = NULL;
 	struct ocfs2_dinode *di;
-	int ret, credits, ref_meta = 0, ref_credits = 0;
+	int ret, credits, had_lock, ref_meta = 0, ref_credits = 0;
 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 	struct inode *tl_inode = osb->osb_tl_inode;
 	struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, NULL, };
 	struct ocfs2_refcount_tree *ref_tree = NULL;
+	struct ocfs2_lock_holder oh;
 
 	struct ocfs2_xattr_info xi = {
 		.xi_name_index = name_index,
@@ -3572,8 +3574,9 @@ int ocfs2_xattr_set(struct inode *inode,
 		return -ENOMEM;
 	}
 
-	ret = ocfs2_inode_lock(inode, &di_bh, 1);
-	if (ret < 0) {
+	had_lock = ocfs2_inode_lock_tracker(inode, &di_bh, 1, &oh);
+	if (had_lock < 0) {
+		ret = had_lock;
 		mlog_errno(ret);
 		goto cleanup_nolock;
 	}
@@ -3670,7 +3673,7 @@ cleanup:
 		if (ret)
 			mlog_errno(ret);
 	}
-	ocfs2_inode_unlock(inode, 1);
+	ocfs2_inode_unlock_tracker(inode, 1, &oh, had_lock);
 cleanup_nolock:
 	brelse(di_bh);
 	brelse(xbs.xattr_bh);
author maintainer
#72 lore raw

PATCH 75/84 iommu/dma: Dont reserve PCI I/O windows

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Robin Murphy <[email protected]>

commit 938f1bbe35e3a7cb07e1fa7c512e2ef8bb866bdf upstream.

Even if a host controller's CPU-side MMIO windows into PCI I/O space do happen to leak into PCI memory space such that it might treat them as peer addresses, trying to reserve the corresponding I/O space addresses doesn't do anything to help solve that problem. Stop doing a silly thing.

Fixes fade1ec055dc ("iommu/dma: Avoid PCI host bridge windows")
---
 drivers/iommu/dma-iommu.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/iommu/dma-iommu.c +1 -2
@@ -175,8 +175,7 @@ static void iova_reserve_pci_windows(str
 	unsigned long lo, hi;
 
 	resource_list_for_each_entry(window, &bridge->windows) {
-		if (resource_type(window->res) != IORESOURCE_MEM &&
-		    resource_type(window->res) != IORESOURCE_IO)
+		if (resource_type(window->res) != IORESOURCE_MEM)
 			continue;
 
 		lo = iova_pfn(iovad, window->res->start - window->offset);
author maintainer
#73 lore raw

PATCH 76/84 iommu/amd: Fix incorrect error handling in amd_iommu_bind_pasid()

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Pan Bian <[email protected]>

commit 73dbd4a4230216b6a5540a362edceae0c9b4876b upstream.

In function amd_iommu_bind_pasid(), the control flow jumps to label out_free when pasid_state->mm and mm is NULL. And mmput(mm) is called. In function mmput(mm), mm is referenced without validation. This will result in a NULL dereference bug. This patch fixes the bug.

Fixes f0aac63b873b ('iommu/amd: Don't hold a reference to mm_struct')
---
 drivers/iommu/amd_iommu_v2.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/amd_iommu_v2.c +1 -1
@@ -696,9 +696,9 @@ out_clear_state:
 
 out_unregister:
 	mmu_notifier_unregister(&pasid_state->mn, mm);
+	mmput(mm);
 
 out_free:
-	mmput(mm);
 	free_pasid_state(pasid_state);
 
 out:
author maintainer
#74 lore raw

PATCH 77/84 iommu/amd: Fix interrupt remapping when disable guest_mode

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Suravee Suthikulpanit <[email protected]>

commit 84a21dbdef0b96d773599c33c2afbb002198d303 upstream.

Pass-through devices to VM guest can get updated IRQ affinity information via irq_set_affinity() when not running in guest mode. Currently, AMD IOMMU driver in GA mode ignores the updated information if the pass-through device is setup to use vAPIC regardless of guest_mode. This could cause invalid interrupt remapping.

Also, the guest_mode bit should be set and cleared only when SVM updates posted-interrupt interrupt remapping information.

Cc Joerg Roedel <[email protected]>
Fixes d98de49a53e48 ('iommu/amd: Enable vAPIC interrupt remapping mode by default')
---
 drivers/iommu/amd_iommu.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/iommu/amd_iommu.c +2 -4
@@ -3879,11 +3879,9 @@ static void irte_ga_prepare(void *entry,
 			    u8 vector, u32 dest_apicid, int devid)
 {
 	struct irte_ga *irte = (struct irte_ga *) entry;
-	struct iommu_dev_data *dev_data = search_dev_data(devid);
 
 	irte->lo.val                      = 0;
 	irte->hi.val                      = 0;
-	irte->lo.fields_remap.guest_mode  = dev_data ? dev_data->use_vapic : 0;
 	irte->lo.fields_remap.int_type    = delivery_mode;
 	irte->lo.fields_remap.dm          = dest_mode;
 	irte->hi.fields.vector            = vector;
@@ -3939,10 +3937,10 @@ static void irte_ga_set_affinity(void *e
 	struct irte_ga *irte = (struct irte_ga *) entry;
 	struct iommu_dev_data *dev_data = search_dev_data(devid);
 
-	if (!dev_data || !dev_data->use_vapic) {
+	if (!dev_data || !dev_data->use_vapic ||
+	    !irte->lo.fields_remap.guest_mode) {
 		irte->hi.fields.vector = vector;
 		irte->lo.fields_remap.destination = dest_apicid;
-		irte->lo.fields_remap.guest_mode = 0;
 		modify_irte_ga(devid, index, irte, NULL);
 	}
 }
author maintainer
#75 lore raw

PATCH 78/84 infiniband: hns: avoid gcc-7.0.1 warning for uninitialized data

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Arnd Bergmann <[email protected]>

commit 5b0ff9a00755d4d9c209033a77f1ed8f3186fe5c upstream.

hns_roce_v1_cq_set_ci() calls roce_set_bit() on an uninitialized field, which will then change only a few of its bits, causing a warning with the latest gcc:

infiniband/hw/hns/hns_roce_hw_v1.c: In function 'hns_roce_v1_cq_set_ci':
infiniband/hw/hns/hns_roce_hw_v1.c:1854:23: error: 'doorbell[1]' is used uninitialized in this function [-Werror=uninitialized]
roce_set_bit(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_HW_SYNS_S, 1);

The code is actually correct since we always set all bits of the port_vlan field, but gcc correctly points out that the first access does contain uninitialized data.

This initializes the field to zero first before setting the individual bits.

Fixes 9a4435375cd1 ("IB/hns: Add driver files for hns RoCE driver")
---
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c |    1 +
 1 file changed, 1 insertion(+)
drivers/infiniband/hw/hns/hns_roce_hw_v1.c +1 -0
@@ -1851,6 +1851,7 @@ void hns_roce_v1_cq_set_ci(struct hns_ro
 	u32 doorbell[2];
 
 	doorbell[0] = cons_index & ((hr_cq->cq_depth << 1) - 1);
+	doorbell[1] = 0;
 	roce_set_bit(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_HW_SYNS_S, 1);
 	roce_set_field(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_M,
 		       ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_S, 3);
author maintainer
#76 lore raw

PATCH 79/84 mtd: nand: brcmnand: Check flash #WP pin status before nand erase/program

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Kamal Dasu <[email protected]>

commit 9d2ee0a60b8bd9bef2a0082c533736d6a7b39873 upstream.

On brcmnand controller v6.x and v7.x, the #WP pin is controlled through the NAND_WP bit in CS_SELECT register.

The driver currently assumes that toggling the #WP pin is instantaneously enabling/disabling write-protection, but it actually takes some time to propagate the new state to the internal NAND chip logic. This behavior is sometime causing data corruptions when an erase/program operation is executed before write-protection has really been disabled.

Fixes 27c5b17cd1b1 ("mtd: nand: add NAND driver "library" for Broadcom STB NAND controller")
---
 drivers/mtd/nand/brcmnand/brcmnand.c |   61 +++++++++++++++++++++++++++++++++--
 1 file changed, 58 insertions(+), 3 deletions(-)
drivers/mtd/nand/brcmnand/brcmnand.c +58 -3
@@ -101,6 +101,9 @@ struct brcm_nand_dma_desc {
 #define BRCMNAND_MIN_BLOCKSIZE	(8 * 1024)
 #define BRCMNAND_MIN_DEVSIZE	(4ULL * 1024 * 1024)
 
+#define NAND_CTRL_RDY			(INTFC_CTLR_READY | INTFC_FLASH_READY)
+#define NAND_POLL_STATUS_TIMEOUT_MS	100
+
 /* Controller feature flags */
 enum {
 	BRCMNAND_HAS_1K_SECTORS			= BIT(0),
@@ -765,6 +768,31 @@ enum {
 	CS_SELECT_AUTO_DEVICE_ID_CFG		= BIT(30),
 };
 
+static int bcmnand_ctrl_poll_status(struct brcmnand_controller *ctrl,
+				    u32 mask, u32 expected_val,
+				    unsigned long timeout_ms)
+{
+	unsigned long limit;
+	u32 val;
+
+	if (!timeout_ms)
+		timeout_ms = NAND_POLL_STATUS_TIMEOUT_MS;
+
+	limit = jiffies + msecs_to_jiffies(timeout_ms);
+	do {
+		val = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS);
+		if ((val & mask) == expected_val)
+			return 0;
+
+		cpu_relax();
+	} while (time_after(limit, jiffies));
+
+	dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
+		 expected_val, val & mask);
+
+	return -ETIMEDOUT;
+}
+
 static inline void brcmnand_set_wp(struct brcmnand_controller *ctrl, bool en)
 {
 	u32 val = en ? CS_SELECT_NAND_WP : 0;
@@ -1024,12 +1052,39 @@ static void brcmnand_wp(struct mtd_info
 
 	if ((ctrl->features & BRCMNAND_HAS_WP) && wp_on == 1) {
 		static int old_wp = -1;
+		int ret;
 
 		if (old_wp != wp) {
 			dev_dbg(ctrl->dev, "WP %s\n", wp ? "on" : "off");
 			old_wp = wp;
 		}
+
+		/*
+		 * make sure ctrl/flash ready before and after
+		 * changing state of #WP pin
+		 */
+		ret = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY |
+					       NAND_STATUS_READY,
+					       NAND_CTRL_RDY |
+					       NAND_STATUS_READY, 0);
+		if (ret)
+			return;
+
 		brcmnand_set_wp(ctrl, wp);
+		chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
+		/* NAND_STATUS_WP 0x00 = protected, 0x80 = not protected */
+		ret = bcmnand_ctrl_poll_status(ctrl,
+					       NAND_CTRL_RDY |
+					       NAND_STATUS_READY |
+					       NAND_STATUS_WP,
+					       NAND_CTRL_RDY |
+					       NAND_STATUS_READY |
+					       (wp ? 0 : NAND_STATUS_WP), 0);
+
+		if (ret)
+			dev_err_ratelimited(&host->pdev->dev,
+					    "nand #WP expected %s\n",
+					    wp ? "on" : "off");
 	}
 }
 
@@ -1157,15 +1212,15 @@ static irqreturn_t brcmnand_dma_irq(int
 static void brcmnand_send_cmd(struct brcmnand_host *host, int cmd)
 {
 	struct brcmnand_controller *ctrl = host->ctrl;
-	u32 intfc;
+	int ret;
 
 	dev_dbg(ctrl->dev, "send native cmd %d addr_lo 0x%x\n", cmd,
 		brcmnand_read_reg(ctrl, BRCMNAND_CMD_ADDRESS));
 	BUG_ON(ctrl->cmd_pending != 0);
 	ctrl->cmd_pending = cmd;
 
-	intfc = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS);
-	WARN_ON(!(intfc & INTFC_CTLR_READY));
+	ret = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0);
+	WARN_ON(ret);
 
 	mb(); /* flush previous writes */
 	brcmnand_write_reg(ctrl, BRCMNAND_CMD_START,
author maintainer
#77 lore raw

PATCH 80/84 mtd: nand: fsmc: fix NAND width handling

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Thomas Petazzoni <[email protected]>

commit ee56874f23e5c11576540bd695177a5ebc4f4352 upstream.

In commit eea628199d5b ("mtd: Add device-tree support to fsmc_nand"), Device Tree support was added to the fmsc_nand driver. However, this code has a bug in how it handles the bank-width DT property to set the bus width.

Indeed, in the function fsmc_nand_probe_config_dt() that parses the Device Tree, it sets pdata->width to either 8 or 16 depending on the value of the bank-width DT property.

Then, the ->probe() function will test if pdata->width is equal to FSMC_NAND_BW16 (which is 2) to set NAND_BUSWIDTH_16 in nand->options. Therefore, with the DT probing, this condition will never match.

This commit fixes that by removing the "width" field from fsmc_nand_platform_data and instead have the fsmc_nand_probe_config_dt() function directly set the appropriate nand->options value.

It is worth mentioning that if this commit gets backported to older kernels, prior to the drop of non-DT probing, then non-DT probing will be broken because nand->options will no longer be set to NAND_BUSWIDTH_16.

Fixes eea628199d5b ("mtd: Add device-tree support to fsmc_nand")
---
 drivers/mtd/nand/fsmc_nand.c |   13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)
drivers/mtd/nand/fsmc_nand.c +5 -8
@@ -150,7 +150,6 @@ struct fsmc_nand_platform_data {
 	struct mtd_partition	*partitions;
 	unsigned int		nr_partitions;
 	unsigned int		options;
-	unsigned int		width;
 	unsigned int		bank;
 
 	enum access_mode	mode;
@@ -844,18 +843,19 @@ static int fsmc_nand_probe_config_dt(str
 	u32 val;
 	int ret;
 
-	/* Set default NAND width to 8 bits */
-	pdata->width = 8;
+	pdata->options = 0;
+
 	if (!of_property_read_u32(np, "bank-width", &val)) {
 		if (val == 2) {
-			pdata->width = 16;
+			pdata->options |= NAND_BUSWIDTH_16;
 		} else if (val != 1) {
 			dev_err(&pdev->dev, "invalid bank-width %u\n", val);
 			return -EINVAL;
 		}
 	}
+
 	if (of_get_property(np, "nand-skip-bbtscan", NULL))
-		pdata->options = NAND_SKIP_BBTSCAN;
+		pdata->options |= NAND_SKIP_BBTSCAN;
 
 	pdata->nand_timings = devm_kzalloc(&pdev->dev,
 				sizeof(*pdata->nand_timings), GFP_KERNEL);
@@ -992,9 +992,6 @@ static int __init fsmc_nand_probe(struct
 	nand->badblockbits = 7;
 	nand_set_flash_node(nand, np);
 
-	if (pdata->width == FSMC_NAND_BW16)
-		nand->options |= NAND_BUSWIDTH_16;
-
 	switch (host->mode) {
 	case USE_DMA_ACCESS:
 		dma_cap_zero(mask);
author maintainer
#78 lore raw

PATCH 81/84 KVM: x86: fix emulation of RSM and IRET instructions

In reply to Greg Kroah-Hartman

4.11-stable review patch. If anyone has any objections, please let me know.

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

From: Ladi Prosek <[email protected]>

commit 6ed071f051e12cf7baa1b69d3becb8f232fdfb7b upstream.

On AMD, the effect of set_nmi_mask called by emulate_iret_real and em_rsm on hflags is reverted later on in x86_emulate_instruction where hflags are overwritten with ctxt->emul_flags (the kvm_set_hflags call). This manifests as a hang when rebooting Windows VMs with QEMU, OVMF, and >1 vcpu.

Instead of trying to merge ctxt->emul_flags into vcpu->arch.hflags after an instruction is emulated, this commit deletes emul_flags altogether and makes the emulator access vcpu->arch.hflags using two new accessors. This way all changes, on the emulator side as well as in functions called from the emulator and accessing vcpu state with emul_to_vcpu, are preserved.

More details on the bug and its manifestation with Windows and OVMF:

It's a KVM bug in the interaction between SMI/SMM and NMI, specific to AMD. I believe that the SMM part explains why we started seeing this only with OVMF.

KVM masks and unmasks NMI when entering and leaving SMM. When KVM emulates the RSM instruction in em_rsm, the set_nmi_mask call doesn't stick because later on in x86_emulate_instruction we overwrite arch.hflags with ctxt->emul_flags, effectively reverting the effect of the set_nmi_mask call. The AMD-specific hflag of interest here is HF_NMI_MASK.

When rebooting the system, Windows sends an NMI IPI to all but the current cpu to shut them down. Only after all of them are parked in HLT will the initiating cpu finish the restart. If NMI is masked, other cpus never get the memo and the initiating cpu spins forever, waiting for hal!HalpInterruptProcessorsStarted to drop. That's the symptom we observe.

Fixes a584539b24b8 ("KVM: x86: pass the whole hflags field to emulator and back")
---
 arch/x86/include/asm/kvm_emulate.h |    4 +++-
 arch/x86/kvm/emulate.c             |   16 +++++++++-------
 arch/x86/kvm/x86.c                 |   15 ++++++++++++---
 3 files changed, 24 insertions(+), 11 deletions(-)
arch/x86/include/asm/kvm_emulate.h +3 -1
@@ -221,6 +221,9 @@ struct x86_emulate_ops {
 	void (*get_cpuid)(struct x86_emulate_ctxt *ctxt,
 			  u32 *eax, u32 *ebx, u32 *ecx, u32 *edx);
 	void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked);
+
+	unsigned (*get_hflags)(struct x86_emulate_ctxt *ctxt);
+	void (*set_hflags)(struct x86_emulate_ctxt *ctxt, unsigned hflags);
 };
 
 typedef u32 __attribute__((vector_size(16))) sse128_t;
@@ -290,7 +293,6 @@ struct x86_emulate_ctxt {
 
 	/* interruptibility state, as a result of execution of STI or MOV SS */
 	int interruptibility;
-	int emul_flags;
 
 	bool perm_ok; /* do not check permissions if true */
 	bool ud;	/* inject an #UD if host doesn't support insn */
arch/x86/kvm/emulate.c +9 -7
@@ -2547,7 +2547,7 @@ static int em_rsm(struct x86_emulate_ctx
 	u64 smbase;
 	int ret;
 
-	if ((ctxt->emul_flags & X86EMUL_SMM_MASK) == 0)
+	if ((ctxt->ops->get_hflags(ctxt) & X86EMUL_SMM_MASK) == 0)
 		return emulate_ud(ctxt);
 
 	/*
@@ -2596,11 +2596,11 @@ static int em_rsm(struct x86_emulate_ctx
 		return X86EMUL_UNHANDLEABLE;
 	}
 
-	if ((ctxt->emul_flags & X86EMUL_SMM_INSIDE_NMI_MASK) == 0)
+	if ((ctxt->ops->get_hflags(ctxt) & X86EMUL_SMM_INSIDE_NMI_MASK) == 0)
 		ctxt->ops->set_nmi_mask(ctxt, false);
 
-	ctxt->emul_flags &= ~X86EMUL_SMM_INSIDE_NMI_MASK;
-	ctxt->emul_flags &= ~X86EMUL_SMM_MASK;
+	ctxt->ops->set_hflags(ctxt, ctxt->ops->get_hflags(ctxt) &
+		~(X86EMUL_SMM_INSIDE_NMI_MASK | X86EMUL_SMM_MASK));
 	return X86EMUL_CONTINUE;
 }
 
@@ -5317,6 +5317,7 @@ int x86_emulate_insn(struct x86_emulate_
 	const struct x86_emulate_ops *ops = ctxt->ops;
 	int rc = X86EMUL_CONTINUE;
 	int saved_dst_type = ctxt->dst.type;
+	unsigned emul_flags;
 
 	ctxt->mem_read.pos = 0;
 
@@ -5331,6 +5332,7 @@ int x86_emulate_insn(struct x86_emulate_
 		goto done;
 	}
 
+	emul_flags = ctxt->ops->get_hflags(ctxt);
 	if (unlikely(ctxt->d &
 		     (No64|Undefined|Sse|Mmx|Intercept|CheckPerm|Priv|Prot|String))) {
 		if ((ctxt->mode == X86EMUL_MODE_PROT64 && (ctxt->d & No64)) ||
@@ -5364,7 +5366,7 @@ int x86_emulate_insn(struct x86_emulate_
 				fetch_possible_mmx_operand(ctxt, &ctxt->dst);
 		}
 
-		if (unlikely(ctxt->emul_flags & X86EMUL_GUEST_MASK) && ctxt->intercept) {
+		if (unlikely(emul_flags & X86EMUL_GUEST_MASK) && ctxt->intercept) {
 			rc = emulator_check_intercept(ctxt, ctxt->intercept,
 						      X86_ICPT_PRE_EXCEPT);
 			if (rc != X86EMUL_CONTINUE)
@@ -5393,7 +5395,7 @@ int x86_emulate_insn(struct x86_emulate_
 				goto done;
 		}
 
-		if (unlikely(ctxt->emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
+		if (unlikely(emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
 			rc = emulator_check_intercept(ctxt, ctxt->intercept,
 						      X86_ICPT_POST_EXCEPT);
 			if (rc != X86EMUL_CONTINUE)
@@ -5447,7 +5449,7 @@ int x86_emulate_insn(struct x86_emulate_
 
 special_insn:
 
-	if (unlikely(ctxt->emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
+	if (unlikely(emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
 		rc = emulator_check_intercept(ctxt, ctxt->intercept,
 					      X86_ICPT_POST_MEMACCESS);
 		if (rc != X86EMUL_CONTINUE)
arch/x86/kvm/x86.c +12 -3
@@ -5248,6 +5248,16 @@ static void emulator_set_nmi_mask(struct
 	kvm_x86_ops->set_nmi_mask(emul_to_vcpu(ctxt), masked);
 }
 
+static unsigned emulator_get_hflags(struct x86_emulate_ctxt *ctxt)
+{
+	return emul_to_vcpu(ctxt)->arch.hflags;
+}
+
+static void emulator_set_hflags(struct x86_emulate_ctxt *ctxt, unsigned emul_flags)
+{
+	kvm_set_hflags(emul_to_vcpu(ctxt), emul_flags);
+}
+
 static const struct x86_emulate_ops emulate_ops = {
 	.read_gpr            = emulator_read_gpr,
 	.write_gpr           = emulator_write_gpr,
@@ -5287,6 +5297,8 @@ static const struct x86_emulate_ops emul
 	.intercept           = emulator_intercept,
 	.get_cpuid           = emulator_get_cpuid,
 	.set_nmi_mask        = emulator_set_nmi_mask,
+	.get_hflags          = emulator_get_hflags,
+	.set_hflags          = emulator_set_hflags,
 };
 
 static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)
@@ -5341,7 +5353,6 @@ static void init_emulate_ctxt(struct kvm
 	BUILD_BUG_ON(HF_GUEST_MASK != X86EMUL_GUEST_MASK);
 	BUILD_BUG_ON(HF_SMM_MASK != X86EMUL_SMM_MASK);
 	BUILD_BUG_ON(HF_SMM_INSIDE_NMI_MASK != X86EMUL_SMM_INSIDE_NMI_MASK);
-	ctxt->emul_flags = vcpu->arch.hflags;
 
 	init_decode_cache(ctxt);
 	vcpu->arch.emulate_regs_need_sync_from_vcpu = false;
@@ -5744,8 +5755,6 @@ restart:
 		unsigned long rflags = kvm_x86_ops->get_rflags(vcpu);
 		toggle_interruptibility(vcpu, ctxt->interruptibility);
 		vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
-		if (vcpu->arch.hflags != ctxt->emul_flags)
-			kvm_set_hflags(vcpu, ctxt->emul_flags);
 		kvm_rip_write(vcpu, ctxt->eip);
 		if (r == EMULATE_DONE &&
 		    (ctxt->tf || (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)))
#79 lore raw
In reply to Greg Kroah-Hartman
Quoted 8 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 4.11.9 release. There are 84 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 Jul 5 13:33:30 UTC 2017. Anything received after that time might be too late.

Build results:

	total: 145 pass: 143 fail: 2

Failed builds:
arm:allmodconfig
arm:omap2plus_defconfig

Qemu test results:

	total: 122 pass: 119 fail: 3

Failed tests:
arm:beagle:omap2plus_defconfig:omap3-beagle arm:beaglexm:omap2plus_defconfig:omap3-beagle-xm arm:overo:omap2plus_defconfig:omap3-overo-tobi

Details are available at http://kerneltests.org/builders.

The common build error is:

drivers/hsi/clients/ssi_protocol.c: In function 'ssip_pn_setup':
drivers/hsi/clients/ssi_protocol.c:1068:5: error: 'struct net_device' has no member named 'destructor'

Bisect points to commit 1469d4b7e6 ("net: Fix inconsistent teardown and release of private net dev state.") as the culprit for the build failures. Reverting that patch fixes the problem.

Guenter

author maintainer
#80 lore raw
Quoted 25 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 4.11.9 release. There are 84 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 Jul 5 13:33:30 UTC 2017. Anything received after that time might be too late.

Build results:

	total: 145 pass: 143 fail: 2

Failed builds:
arm:allmodconfig
arm:omap2plus_defconfig

Qemu test results:

	total: 122 pass: 119 fail: 3

Failed tests:
arm:beagle:omap2plus_defconfig:omap3-beagle arm:beaglexm:omap2plus_defconfig:omap3-beagle-xm arm:overo:omap2plus_defconfig:omap3-overo-tobi

Details are available at http://kerneltests.org/builders.

Quoted 8 lines

The common build error is:

drivers/hsi/clients/ssi_protocol.c: In function 'ssip_pn_setup':
drivers/hsi/clients/ssi_protocol.c:1068:5: error: 'struct net_device' has no member named 'destructor'

Bisect points to commit 1469d4b7e6 ("net: Fix inconsistent teardown and release of private net dev state.") as the culprit for the build failures. Reverting that patch fixes the problem.

Ah, looks like we need to add commit ed66e50d9587 ("hsi: Fix build regression due to netdev destructor fix.") to the tree to fix this up, let me go queue it up now...

thanks,

greg k-h