commit:     47a920430b421062371b9f82f620bc48ca5f5602
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Fri Apr 16 11:17:03 2021 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Fri Apr 16 11:17:12 2021 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=47a92043

Linux patch 4.14.231

Signed-off-by: Alice Ferrazzi <alicef <AT> gentoo.org>

 0000_README               |    4 +
 1230_linux-4.14.231.patch | 3301 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 3305 insertions(+)

diff --git a/0000_README b/0000_README
index 34eb3e8..8c683a8 100644
--- a/0000_README
+++ b/0000_README
@@ -963,6 +963,10 @@ Patch:  1229_linux-4.14.230.patch
 From:   https://www.kernel.org
 Desc:   Linux 4.14.230
 
+Patch:  1230_linux-4.14.231.patch
+From:   https://www.kernel.org
+Desc:   Linux 4.14.231
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1230_linux-4.14.231.patch b/1230_linux-4.14.231.patch
new file mode 100644
index 0000000..9a6d297
--- /dev/null
+++ b/1230_linux-4.14.231.patch
@@ -0,0 +1,3301 @@
+diff --git a/Makefile b/Makefile
+index 09989cdd5caba..cee830aea284c 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 4
+ PATCHLEVEL = 14
+-SUBLEVEL = 230
++SUBLEVEL = 231
+ EXTRAVERSION =
+ NAME = Petit Gorille
+ 
+diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts 
b/arch/arm/boot/dts/armada-385-turris-omnia.dts
+index 06831e1e3f808..6c2d96cbd7cdb 100644
+--- a/arch/arm/boot/dts/armada-385-turris-omnia.dts
++++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts
+@@ -269,6 +269,7 @@
+               status = "okay";
+               compatible = "ethernet-phy-id0141.0DD1", 
"ethernet-phy-ieee802.3-c22";
+               reg = <1>;
++              marvell,reg-init = <3 18 0 0x4985>;
+ 
+               /* irq is connected to &pcawan pin 7 */
+       };
+diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi 
b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
+index 25b0704c60549..d2c31eae9fef5 100644
+--- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
+@@ -423,6 +423,7 @@
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
++      vmmc-supply = <&vdd_sd1_reg>;
+       status = "disabled";
+ };
+ 
+@@ -432,5 +433,6 @@
+                    &pinctrl_usdhc3_cdwp>;
+       cd-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>;
++      vmmc-supply = <&vdd_sd0_reg>;
+       status = "disabled";
+ };
+diff --git a/arch/arm64/include/asm/kvm_arm.h 
b/arch/arm64/include/asm/kvm_arm.h
+index f88611e241f0e..72ed11292df3b 100644
+--- a/arch/arm64/include/asm/kvm_arm.h
++++ b/arch/arm64/include/asm/kvm_arm.h
+@@ -191,6 +191,7 @@
+ #define CPTR_EL2_DEFAULT      0x000033ff
+ 
+ /* Hyp Debug Configuration Register bits */
++#define MDCR_EL2_TTRF         (1 << 19)
+ #define MDCR_EL2_TPMS         (1 << 14)
+ #define MDCR_EL2_E2PB_MASK    (UL(0x3))
+ #define MDCR_EL2_E2PB_SHIFT   (UL(12))
+diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
+index 174aa12fb8b1f..1481e18aa5ca0 100644
+--- a/arch/arm64/kernel/cpufeature.c
++++ b/arch/arm64/kernel/cpufeature.c
+@@ -230,7 +230,6 @@ static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
+        * of support.
+        */
+       S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, 
ID_AA64DFR0_PMUVER_SHIFT, 4, 0),
+-      ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, 
ID_AA64DFR0_TRACEVER_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, 
ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6),
+       ARM64_FTR_END,
+ };
+diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
+index dbadfaf850a7d..2da4f45ab0bbd 100644
+--- a/arch/arm64/kvm/debug.c
++++ b/arch/arm64/kvm/debug.c
+@@ -96,6 +96,7 @@ void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu)
+  *  - Debug ROM Address (MDCR_EL2_TDRA)
+  *  - OS related registers (MDCR_EL2_TDOSA)
+  *  - Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB)
++ *  - Self-hosted Trace Filter controls (MDCR_EL2_TTRF)
+  *
+  * Additionally, KVM only traps guest accesses to the debug registers if
+  * the guest is not actively using them (see the KVM_ARM64_DEBUG_DIRTY
+@@ -118,6 +119,7 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
+       vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK;
+       vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM |
+                               MDCR_EL2_TPMS |
++                              MDCR_EL2_TTRF |
+                               MDCR_EL2_TPMCR |
+                               MDCR_EL2_TDRA |
+                               MDCR_EL2_TDOSA);
+diff --git a/arch/ia64/include/asm/ptrace.h b/arch/ia64/include/asm/ptrace.h
+index 7ff574d56429c..f31e07fc936d9 100644
+--- a/arch/ia64/include/asm/ptrace.h
++++ b/arch/ia64/include/asm/ptrace.h
+@@ -54,8 +54,7 @@
+ 
+ static inline unsigned long user_stack_pointer(struct pt_regs *regs)
+ {
+-      /* FIXME: should this be bspstore + nr_dirty regs? */
+-      return regs->ar_bspstore;
++      return regs->r12;
+ }
+ 
+ static inline int is_syscall_success(struct pt_regs *regs)
+@@ -79,11 +78,6 @@ static inline long regs_return_value(struct pt_regs *regs)
+       unsigned long __ip = instruction_pointer(regs);                 \
+       (__ip & ~3UL) + ((__ip & 3UL) << 2);                            \
+ })
+-/*
+- * Why not default?  Because user_stack_pointer() on ia64 gives register
+- * stack backing store instead...
+- */
+-#define current_user_stack_pointer() (current_pt_regs()->r12)
+ 
+   /* given a pointer to a task_struct, return the user's pt_regs */
+ # define task_pt_regs(t)              (((struct pt_regs *) ((char *) (t) + 
IA64_STK_OFFSET)) - 1)
+diff --git a/arch/parisc/include/asm/cmpxchg.h 
b/arch/parisc/include/asm/cmpxchg.h
+index 0689585758717..a736dc59bbef8 100644
+--- a/arch/parisc/include/asm/cmpxchg.h
++++ b/arch/parisc/include/asm/cmpxchg.h
+@@ -72,7 +72,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned 
long new_, int size)
+ #endif
+       case 4: return __cmpxchg_u32((unsigned int *)ptr,
+                                    (unsigned int)old, (unsigned int)new_);
+-      case 1: return __cmpxchg_u8((u8 *)ptr, (u8)old, (u8)new_);
++      case 1: return __cmpxchg_u8((u8 *)ptr, old & 0xff, new_ & 0xff);
+       }
+       __cmpxchg_called_with_bad_pointer();
+       return old;
+diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c
+index af013b4244d34..2da0273597989 100644
+--- a/arch/s390/kernel/cpcmd.c
++++ b/arch/s390/kernel/cpcmd.c
+@@ -37,10 +37,12 @@ static int diag8_noresponse(int cmdlen)
+ 
+ static int diag8_response(int cmdlen, char *response, int *rlen)
+ {
++      unsigned long _cmdlen = cmdlen | 0x40000000L;
++      unsigned long _rlen = *rlen;
+       register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
+       register unsigned long reg3 asm ("3") = (addr_t) response;
+-      register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L;
+-      register unsigned long reg5 asm ("5") = *rlen;
++      register unsigned long reg4 asm ("4") = _cmdlen;
++      register unsigned long reg5 asm ("5") = _rlen;
+ 
+       asm volatile(
+               "       diag    %2,%0,0x8\n"
+diff --git a/block/bio.c b/block/bio.c
+index 1384f97908822..30df1b45dde84 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -312,7 +312,7 @@ static struct bio *__bio_chain_endio(struct bio *bio)
+ {
+       struct bio *parent = bio->bi_private;
+ 
+-      if (!parent->bi_status)
++      if (bio->bi_status && !parent->bi_status)
+               parent->bi_status = bio->bi_status;
+       bio_put(bio);
+       return parent;
+diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
+index 6231714ef3c8f..cee9e42ce5478 100644
+--- a/drivers/char/agp/Kconfig
++++ b/drivers/char/agp/Kconfig
+@@ -125,7 +125,7 @@ config AGP_HP_ZX1
+ 
+ config AGP_PARISC
+       tristate "HP Quicksilver AGP support"
+-      depends on AGP && PARISC && 64BIT
++      depends on AGP && PARISC && 64BIT && IOMMU_SBA
+       help
+         This option gives you AGP GART support for the HP Quicksilver
+         AGP bus adapter on HP PA-RISC machines (Ok, just on the C8000
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 4289c519af1be..971a9a5006af0 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -3018,20 +3018,19 @@ int clk_notifier_register(struct clk *clk, struct 
notifier_block *nb)
+       /* search the list of notifiers for this clk */
+       list_for_each_entry(cn, &clk_notifier_list, node)
+               if (cn->clk == clk)
+-                      break;
++                      goto found;
+ 
+       /* if clk wasn't in the notifier list, allocate new clk_notifier */
+-      if (cn->clk != clk) {
+-              cn = kzalloc(sizeof(*cn), GFP_KERNEL);
+-              if (!cn)
+-                      goto out;
++      cn = kzalloc(sizeof(*cn), GFP_KERNEL);
++      if (!cn)
++              goto out;
+ 
+-              cn->clk = clk;
+-              srcu_init_notifier_head(&cn->notifier_head);
++      cn->clk = clk;
++      srcu_init_notifier_head(&cn->notifier_head);
+ 
+-              list_add(&cn->node, &clk_notifier_list);
+-      }
++      list_add(&cn->node, &clk_notifier_list);
+ 
++found:
+       ret = srcu_notifier_chain_register(&cn->notifier_head, nb);
+ 
+       clk->core->notifier_count++;
+@@ -3056,32 +3055,28 @@ EXPORT_SYMBOL_GPL(clk_notifier_register);
+  */
+ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
+ {
+-      struct clk_notifier *cn = NULL;
+-      int ret = -EINVAL;
++      struct clk_notifier *cn;
++      int ret = -ENOENT;
+ 
+       if (!clk || !nb)
+               return -EINVAL;
+ 
+       clk_prepare_lock();
+ 
+-      list_for_each_entry(cn, &clk_notifier_list, node)
+-              if (cn->clk == clk)
+-                      break;
+-
+-      if (cn->clk == clk) {
+-              ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb);
++      list_for_each_entry(cn, &clk_notifier_list, node) {
++              if (cn->clk == clk) {
++                      ret = 
srcu_notifier_chain_unregister(&cn->notifier_head, nb);
+ 
+-              clk->core->notifier_count--;
++                      clk->core->notifier_count--;
+ 
+-              /* XXX the notifier code should handle this better */
+-              if (!cn->notifier_head.head) {
+-                      srcu_cleanup_notifier_head(&cn->notifier_head);
+-                      list_del(&cn->node);
+-                      kfree(cn);
++                      /* XXX the notifier code should handle this better */
++                      if (!cn->notifier_head.head) {
++                              srcu_cleanup_notifier_head(&cn->notifier_head);
++                              list_del(&cn->node);
++                              kfree(cn);
++                      }
++                      break;
+               }
+-
+-      } else {
+-              ret = -ENOENT;
+       }
+ 
+       clk_prepare_unlock();
+diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c
+index aa7a6e6a15b65..14918896811d6 100644
+--- a/drivers/clk/socfpga/clk-gate.c
++++ b/drivers/clk/socfpga/clk-gate.c
+@@ -107,7 +107,7 @@ static unsigned long socfpga_clk_recalc_rate(struct clk_hw 
*hwclk,
+               val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift;
+               val &= GENMASK(socfpgaclk->width - 1, 0);
+               /* Check for GPIO_DB_CLK by its offset */
+-              if ((int) socfpgaclk->div_reg & SOCFPGA_GPIO_DB_CLK_OFFSET)
++              if ((uintptr_t) socfpgaclk->div_reg & 
SOCFPGA_GPIO_DB_CLK_OFFSET)
+                       div = val + 1;
+               else
+                       div = (1 << val);
+diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
+index d38648a7ef2db..d88ac6f2222ae 100644
+--- a/drivers/gpu/drm/imx/imx-ldb.c
++++ b/drivers/gpu/drm/imx/imx-ldb.c
+@@ -206,6 +206,11 @@ static void imx_ldb_encoder_enable(struct drm_encoder 
*encoder)
+       int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
+       int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder);
+ 
++      if (mux < 0 || mux >= ARRAY_SIZE(ldb->clk_sel)) {
++              dev_warn(ldb->dev, "%s: invalid mux %d\n", __func__, mux);
++              return;
++      }
++
+       drm_panel_prepare(imx_ldb_ch->panel);
+ 
+       if (dual) {
+@@ -264,6 +269,11 @@ imx_ldb_encoder_atomic_mode_set(struct drm_encoder 
*encoder,
+       int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder);
+       u32 bus_format = imx_ldb_ch->bus_format;
+ 
++      if (mux < 0 || mux >= ARRAY_SIZE(ldb->clk_sel)) {
++              dev_warn(ldb->dev, "%s: invalid mux %d\n", __func__, mux);
++              return;
++      }
++
+       if (mode->clock > 170000) {
+               dev_warn(ldb->dev,
+                        "%s: mode exceeds 170 MHz pixel clock\n", __func__);
+diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
+index 9f2aa45560e62..39065a5d50fc3 100644
+--- a/drivers/i2c/i2c-core-base.c
++++ b/drivers/i2c/i2c-core-base.c
+@@ -262,13 +262,14 @@ EXPORT_SYMBOL_GPL(i2c_recover_bus);
+ static void i2c_init_recovery(struct i2c_adapter *adap)
+ {
+       struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
+-      char *err_str;
++      char *err_str, *err_level = KERN_ERR;
+ 
+       if (!bri)
+               return;
+ 
+       if (!bri->recover_bus) {
+-              err_str = "no recover_bus() found";
++              err_str = "no suitable method provided";
++              err_level = KERN_DEBUG;
+               goto err;
+       }
+ 
+@@ -296,7 +297,7 @@ static void i2c_init_recovery(struct i2c_adapter *adap)
+ 
+       return;
+  err:
+-      dev_err(&adap->dev, "Not using recovery: %s\n", err_str);
++      dev_printk(err_level, &adap->dev, "Not using recovery: %s\n", err_str);
+       adap->bus_recovery_info = NULL;
+ }
+ 
+diff --git a/drivers/infiniband/hw/cxgb4/cm.c 
b/drivers/infiniband/hw/cxgb4/cm.c
+index 72e2031993fb2..2ea87fe1184d1 100644
+--- a/drivers/infiniband/hw/cxgb4/cm.c
++++ b/drivers/infiniband/hw/cxgb4/cm.c
+@@ -3498,7 +3498,8 @@ int c4iw_destroy_listen(struct iw_cm_id *cm_id)
+               c4iw_init_wr_wait(&ep->com.wr_wait);
+               err = cxgb4_remove_server(
+                               ep->com.dev->rdev.lldi.ports[0], ep->stid,
+-                              ep->com.dev->rdev.lldi.rxq_ids[0], true);
++                              ep->com.dev->rdev.lldi.rxq_ids[0],
++                              ep->com.local_addr.ss_family == AF_INET6);
+               if (err)
+                       goto done;
+               err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait,
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c 
b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+index c9d86d50bf886..3c73eaae5388c 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+@@ -882,7 +882,7 @@ static int peak_usb_create_dev(const struct 
peak_usb_adapter *peak_usb_adapter,
+       if (dev->adapter->dev_set_bus) {
+               err = dev->adapter->dev_set_bus(dev, 0);
+               if (err)
+-                      goto lbl_unregister_candev;
++                      goto adap_dev_free;
+       }
+ 
+       /* get device number early */
+@@ -894,6 +894,10 @@ static int peak_usb_create_dev(const struct 
peak_usb_adapter *peak_usb_adapter,
+ 
+       return 0;
+ 
++adap_dev_free:
++      if (dev->adapter->dev_free)
++              dev->adapter->dev_free(dev);
++
+ lbl_unregister_candev:
+       unregister_candev(netdev);
+ 
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h 
b/drivers/net/ethernet/amd/xgbe/xgbe.h
+index 95d4b56448c68..cd0459b0055bb 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
++++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
+@@ -176,9 +176,9 @@
+ #define XGBE_DMA_SYS_AWCR     0x30303030
+ 
+ /* DMA cache settings - PCI device */
+-#define XGBE_DMA_PCI_ARCR     0x00000003
+-#define XGBE_DMA_PCI_AWCR     0x13131313
+-#define XGBE_DMA_PCI_AWARCR   0x00000313
++#define XGBE_DMA_PCI_ARCR     0x000f0f0f
++#define XGBE_DMA_PCI_AWCR     0x0f0f0f0f
++#define XGBE_DMA_PCI_AWARCR   0x00000f0f
+ 
+ /* DMA channel interrupt modes */
+ #define XGBE_IRQ_MODE_EDGE    0
+diff --git a/drivers/net/ethernet/freescale/gianfar.c 
b/drivers/net/ethernet/freescale/gianfar.c
+index b3b7b98eb32c1..c89a5a80c9c8b 100644
+--- a/drivers/net/ethernet/freescale/gianfar.c
++++ b/drivers/net/ethernet/freescale/gianfar.c
+@@ -485,7 +485,11 @@ static struct net_device_stats *gfar_get_stats(struct 
net_device *dev)
+ 
+ static int gfar_set_mac_addr(struct net_device *dev, void *p)
+ {
+-      eth_mac_addr(dev, p);
++      int ret;
++
++      ret = eth_mac_addr(dev, p);
++      if (ret)
++              return ret;
+ 
+       gfar_set_mac_for_addr(dev, 0, dev->dev_addr);
+ 
+diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c
+index 8e2cbc88df98b..2c4274453c156 100644
+--- a/drivers/net/ieee802154/atusb.c
++++ b/drivers/net/ieee802154/atusb.c
+@@ -346,6 +346,7 @@ static int atusb_alloc_urbs(struct atusb *atusb, int n)
+                       return -ENOMEM;
+               }
+               usb_anchor_urb(urb, &atusb->idle_urbs);
++              usb_free_urb(urb);
+               n--;
+       }
+       return 0;
+diff --git a/drivers/net/phy/bcm-phy-lib.c b/drivers/net/phy/bcm-phy-lib.c
+index d5e0833d69b9b..66e4ef8ed3454 100644
+--- a/drivers/net/phy/bcm-phy-lib.c
++++ b/drivers/net/phy/bcm-phy-lib.c
+@@ -198,7 +198,7 @@ EXPORT_SYMBOL_GPL(bcm_phy_enable_apd);
+ 
+ int bcm_phy_set_eee(struct phy_device *phydev, bool enable)
+ {
+-      int val;
++      int val, mask = 0;
+ 
+       /* Enable EEE at PHY level */
+       val = phy_read_mmd(phydev, MDIO_MMD_AN, BRCM_CL45VEN_EEE_CONTROL);
+@@ -217,10 +217,15 @@ int bcm_phy_set_eee(struct phy_device *phydev, bool 
enable)
+       if (val < 0)
+               return val;
+ 
++      if (phydev->supported & SUPPORTED_1000baseT_Full)
++              mask |= MDIO_EEE_1000T;
++      if (phydev->supported & SUPPORTED_100baseT_Full)
++              mask |= MDIO_EEE_100TX;
++
+       if (enable)
+-              val |= (MDIO_EEE_100TX | MDIO_EEE_1000T);
++              val |= mask;
+       else
+-              val &= ~(MDIO_EEE_100TX | MDIO_EEE_1000T);
++              val &= ~mask;
+ 
+       phy_write_mmd(phydev, MDIO_MMD_AN, BCM_CL45VEN_EEE_ADV, (u32)val);
+ 
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index abf9c9952b799..2bf58239bd4b4 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -75,6 +75,14 @@
+ #include <linux/skb_array.h>
+ #include <linux/bpf.h>
+ #include <linux/bpf_trace.h>
++#include <linux/ieee802154.h>
++#include <linux/if_ltalk.h>
++#include <uapi/linux/if_fddi.h>
++#include <uapi/linux/if_hippi.h>
++#include <uapi/linux/if_fc.h>
++#include <net/ax25.h>
++#include <net/rose.h>
++#include <net/6lowpan.h>
+ 
+ #include <linux/uaccess.h>
+ 
+@@ -2292,6 +2300,45 @@ unlock:
+       return ret;
+ }
+ 
++/* Return correct value for tun->dev->addr_len based on tun->dev->type. */
++static unsigned char tun_get_addr_len(unsigned short type)
++{
++      switch (type) {
++      case ARPHRD_IP6GRE:
++      case ARPHRD_TUNNEL6:
++              return sizeof(struct in6_addr);
++      case ARPHRD_IPGRE:
++      case ARPHRD_TUNNEL:
++      case ARPHRD_SIT:
++              return 4;
++      case ARPHRD_ETHER:
++              return ETH_ALEN;
++      case ARPHRD_IEEE802154:
++      case ARPHRD_IEEE802154_MONITOR:
++              return IEEE802154_EXTENDED_ADDR_LEN;
++      case ARPHRD_PHONET_PIPE:
++      case ARPHRD_PPP:
++      case ARPHRD_NONE:
++              return 0;
++      case ARPHRD_6LOWPAN:
++              return EUI64_ADDR_LEN;
++      case ARPHRD_FDDI:
++              return FDDI_K_ALEN;
++      case ARPHRD_HIPPI:
++              return HIPPI_ALEN;
++      case ARPHRD_IEEE802:
++              return FC_ALEN;
++      case ARPHRD_ROSE:
++              return ROSE_ADDR_LEN;
++      case ARPHRD_NETROM:
++              return AX25_ADDR_LEN;
++      case ARPHRD_LOCALTLK:
++              return LTALK_ALEN;
++      default:
++              return 0;
++      }
++}
++
+ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
+                           unsigned long arg, int ifreq_len)
+ {
+@@ -2434,6 +2481,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned 
int cmd,
+                       ret = -EBUSY;
+               } else {
+                       tun->dev->type = (int) arg;
++                      tun->dev->addr_len = tun_get_addr_len(tun->dev->type);
+                       tun_debug(KERN_INFO, tun, "linktype set to %d\n",
+                                 tun->dev->type);
+                       ret = 0;
+diff --git a/drivers/regulator/bd9571mwv-regulator.c 
b/drivers/regulator/bd9571mwv-regulator.c
+index c67a83d53c4cb..167c05029f9e8 100644
+--- a/drivers/regulator/bd9571mwv-regulator.c
++++ b/drivers/regulator/bd9571mwv-regulator.c
+@@ -119,7 +119,7 @@ static struct regulator_ops vid_ops = {
+ 
+ static struct regulator_desc regulators[] = {
+       BD9571MWV_REG("VD09", "vd09", VD09, avs_ops, 0, 0x7f,
+-                    0x80, 600000, 10000, 0x3c),
++                    0x6f, 600000, 10000, 0x3c),
+       BD9571MWV_REG("VD18", "vd18", VD18, vid_ops, BD9571MWV_VD18_VID, 0xf,
+                     16, 1625000, 25000, 0),
+       BD9571MWV_REG("VD25", "vd25", VD25, vid_ops, BD9571MWV_VD25_VID, 0xf,
+@@ -128,7 +128,7 @@ static struct regulator_desc regulators[] = {
+                     11, 2800000, 100000, 0),
+       BD9571MWV_REG("DVFS", "dvfs", DVFS, reg_ops,
+                     BD9571MWV_DVFS_MONIVDAC, 0x7f,
+-                    0x80, 600000, 10000, 0x3c),
++                    0x6f, 600000, 10000, 0x3c),
+ };
+ 
+ static int bd9571mwv_regulator_probe(struct platform_device *pdev)
+diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
+index 90892a360c61c..06b6d7afc5671 100644
+--- a/drivers/soc/fsl/qbman/qman.c
++++ b/drivers/soc/fsl/qbman/qman.c
+@@ -146,7 +146,7 @@ struct qm_eqcr_entry {
+       __be32 tag;
+       struct qm_fd fd;
+       u8 __reserved3[32];
+-} __packed;
++} __packed __aligned(8);
+ #define QM_EQCR_VERB_VBIT             0x80
+ #define QM_EQCR_VERB_CMD_MASK         0x61    /* but only one value; */
+ #define QM_EQCR_VERB_CMD_ENQUEUE      0x01
+diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c
+index c6be9923502b5..1b3aad59d6c96 100644
+--- a/drivers/usb/usbip/stub_dev.c
++++ b/drivers/usb/usbip/stub_dev.c
+@@ -77,6 +77,7 @@ static ssize_t store_sockfd(struct device *dev, struct 
device_attribute *attr,
+ 
+               dev_info(dev, "stub up\n");
+ 
++              mutex_lock(&sdev->ud.sysfs_lock);
+               spin_lock_irq(&sdev->ud.lock);
+ 
+               if (sdev->ud.status != SDEV_ST_AVAILABLE) {
+@@ -101,13 +102,13 @@ static ssize_t store_sockfd(struct device *dev, struct 
device_attribute *attr,
+               tcp_rx = kthread_create(stub_rx_loop, &sdev->ud, "stub_rx");
+               if (IS_ERR(tcp_rx)) {
+                       sockfd_put(socket);
+-                      return -EINVAL;
++                      goto unlock_mutex;
+               }
+               tcp_tx = kthread_create(stub_tx_loop, &sdev->ud, "stub_tx");
+               if (IS_ERR(tcp_tx)) {
+                       kthread_stop(tcp_rx);
+                       sockfd_put(socket);
+-                      return -EINVAL;
++                      goto unlock_mutex;
+               }
+ 
+               /* get task structs now */
+@@ -126,6 +127,8 @@ static ssize_t store_sockfd(struct device *dev, struct 
device_attribute *attr,
+               wake_up_process(sdev->ud.tcp_rx);
+               wake_up_process(sdev->ud.tcp_tx);
+ 
++              mutex_unlock(&sdev->ud.sysfs_lock);
++
+       } else {
+               dev_info(dev, "stub down\n");
+ 
+@@ -136,6 +139,7 @@ static ssize_t store_sockfd(struct device *dev, struct 
device_attribute *attr,
+               spin_unlock_irq(&sdev->ud.lock);
+ 
+               usbip_event_add(&sdev->ud, SDEV_EVENT_DOWN);
++              mutex_unlock(&sdev->ud.sysfs_lock);
+       }
+ 
+       return count;
+@@ -144,6 +148,8 @@ sock_err:
+       sockfd_put(socket);
+ err:
+       spin_unlock_irq(&sdev->ud.lock);
++unlock_mutex:
++      mutex_unlock(&sdev->ud.sysfs_lock);
+       return -EINVAL;
+ }
+ static DEVICE_ATTR(usbip_sockfd, S_IWUSR, NULL, store_sockfd);
+@@ -309,6 +315,7 @@ static struct stub_device *stub_device_alloc(struct 
usb_device *udev)
+       sdev->ud.side           = USBIP_STUB;
+       sdev->ud.status         = SDEV_ST_AVAILABLE;
+       spin_lock_init(&sdev->ud.lock);
++      mutex_init(&sdev->ud.sysfs_lock);
+       sdev->ud.tcp_socket     = NULL;
+       sdev->ud.sockfd         = -1;
+ 
+diff --git a/drivers/usb/usbip/usbip_common.h 
b/drivers/usb/usbip/usbip_common.h
+index 59097145cfc02..d740aa8a12319 100644
+--- a/drivers/usb/usbip/usbip_common.h
++++ b/drivers/usb/usbip/usbip_common.h
+@@ -277,6 +277,9 @@ struct usbip_device {
+       /* lock for status */
+       spinlock_t lock;
+ 
++      /* mutex for synchronizing sysfs store paths */
++      struct mutex sysfs_lock;
++
+       int sockfd;
+       struct socket *tcp_socket;
+ 
+diff --git a/drivers/usb/usbip/usbip_event.c b/drivers/usb/usbip/usbip_event.c
+index f8f7f3803a99c..01eaae1f265b2 100644
+--- a/drivers/usb/usbip/usbip_event.c
++++ b/drivers/usb/usbip/usbip_event.c
+@@ -84,6 +84,7 @@ static void event_handler(struct work_struct *work)
+       while ((ud = get_event()) != NULL) {
+               usbip_dbg_eh("pending event %lx\n", ud->event);
+ 
++              mutex_lock(&ud->sysfs_lock);
+               /*
+                * NOTE: shutdown must come first.
+                * Shutdown the device.
+@@ -104,6 +105,7 @@ static void event_handler(struct work_struct *work)
+                       ud->eh_ops.unusable(ud);
+                       unset_event(ud, USBIP_EH_UNUSABLE);
+               }
++              mutex_unlock(&ud->sysfs_lock);
+ 
+               wake_up(&ud->eh_waitq);
+       }
+diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c
+index d87159e6c716d..9833f307d70e4 100644
+--- a/drivers/usb/usbip/vhci_hcd.c
++++ b/drivers/usb/usbip/vhci_hcd.c
+@@ -1115,6 +1115,7 @@ static void vhci_device_init(struct vhci_device *vdev)
+       vdev->ud.side   = USBIP_VHCI;
+       vdev->ud.status = VDEV_ST_NULL;
+       spin_lock_init(&vdev->ud.lock);
++      mutex_init(&vdev->ud.sysfs_lock);
+ 
+       INIT_LIST_HEAD(&vdev->priv_rx);
+       INIT_LIST_HEAD(&vdev->priv_tx);
+diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c
+index 4f0f65540888f..aa329d752015d 100644
+--- a/drivers/usb/usbip/vhci_sysfs.c
++++ b/drivers/usb/usbip/vhci_sysfs.c
+@@ -199,6 +199,8 @@ static int vhci_port_disconnect(struct vhci_hcd *vhci_hcd, 
__u32 rhport)
+ 
+       usbip_dbg_vhci_sysfs("enter\n");
+ 
++      mutex_lock(&vdev->ud.sysfs_lock);
++
+       /* lock */
+       spin_lock_irqsave(&vhci->lock, flags);
+       spin_lock(&vdev->ud.lock);
+@@ -209,6 +211,7 @@ static int vhci_port_disconnect(struct vhci_hcd *vhci_hcd, 
__u32 rhport)
+               /* unlock */
+               spin_unlock(&vdev->ud.lock);
+               spin_unlock_irqrestore(&vhci->lock, flags);
++              mutex_unlock(&vdev->ud.sysfs_lock);
+ 
+               return -EINVAL;
+       }
+@@ -219,6 +222,8 @@ static int vhci_port_disconnect(struct vhci_hcd *vhci_hcd, 
__u32 rhport)
+ 
+       usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN);
+ 
++      mutex_unlock(&vdev->ud.sysfs_lock);
++
+       return 0;
+ }
+ 
+@@ -363,30 +368,36 @@ static ssize_t store_attach(struct device *dev, struct 
device_attribute *attr,
+       else
+               vdev = &vhci->vhci_hcd_hs->vdev[rhport];
+ 
++      mutex_lock(&vdev->ud.sysfs_lock);
++
+       /* Extract socket from fd. */
+       socket = sockfd_lookup(sockfd, &err);
+       if (!socket) {
+               dev_err(dev, "failed to lookup sock");
+-              return -EINVAL;
++              err = -EINVAL;
++              goto unlock_mutex;
+       }
+       if (socket->type != SOCK_STREAM) {
+               dev_err(dev, "Expecting SOCK_STREAM - found %d",
+                       socket->type);
+               sockfd_put(socket);
+-              return -EINVAL;
++              err = -EINVAL;
++              goto unlock_mutex;
+       }
+ 
+       /* create threads before locking */
+       tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx");
+       if (IS_ERR(tcp_rx)) {
+               sockfd_put(socket);
+-              return -EINVAL;
++              err = -EINVAL;
++              goto unlock_mutex;
+       }
+       tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx");
+       if (IS_ERR(tcp_tx)) {
+               kthread_stop(tcp_rx);
+               sockfd_put(socket);
+-              return -EINVAL;
++              err = -EINVAL;
++              goto unlock_mutex;
+       }
+ 
+       /* get task structs now */
+@@ -411,7 +422,8 @@ static ssize_t store_attach(struct device *dev, struct 
device_attribute *attr,
+                * Will be retried from userspace
+                * if there's another free port.
+                */
+-              return -EBUSY;
++              err = -EBUSY;
++              goto unlock_mutex;
+       }
+ 
+       dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n",
+@@ -436,7 +448,15 @@ static ssize_t store_attach(struct device *dev, struct 
device_attribute *attr,
+ 
+       rh_port_connect(vdev, speed);
+ 
++      dev_info(dev, "Device attached\n");
++
++      mutex_unlock(&vdev->ud.sysfs_lock);
++
+       return count;
++
++unlock_mutex:
++      mutex_unlock(&vdev->ud.sysfs_lock);
++      return err;
+ }
+ static DEVICE_ATTR(attach, S_IWUSR, NULL, store_attach);
+ 
+diff --git a/drivers/usb/usbip/vudc_sysfs.c b/drivers/usb/usbip/vudc_sysfs.c
+index e3f7c76d19562..f44d98eeb36ac 100644
+--- a/drivers/usb/usbip/vudc_sysfs.c
++++ b/drivers/usb/usbip/vudc_sysfs.c
+@@ -103,8 +103,9 @@ unlock:
+ }
+ static BIN_ATTR_RO(dev_desc, sizeof(struct usb_device_descriptor));
+ 
+-static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr,
+-                   const char *in, size_t count)
++static ssize_t store_sockfd(struct device *dev,
++                               struct device_attribute *attr,
++                               const char *in, size_t count)
+ {
+       struct vudc *udc = (struct vudc *) dev_get_drvdata(dev);
+       int rv;
+@@ -113,6 +114,8 @@ static ssize_t store_sockfd(struct device *dev, struct 
device_attribute *attr,
+       struct socket *socket;
+       unsigned long flags;
+       int ret;
++      struct task_struct *tcp_rx = NULL;
++      struct task_struct *tcp_tx = NULL;
+ 
+       rv = kstrtoint(in, 0, &sockfd);
+       if (rv != 0)
+@@ -158,24 +161,47 @@ static ssize_t store_sockfd(struct device *dev, struct 
device_attribute *attr,
+                       goto sock_err;
+               }
+ 
+-              udc->ud.tcp_socket = socket;
+-
++              /* unlock and create threads and get tasks */
+               spin_unlock_irq(&udc->ud.lock);
+               spin_unlock_irqrestore(&udc->lock, flags);
+ 
+-              udc->ud.tcp_rx = kthread_get_run(&v_rx_loop,
+-                                                  &udc->ud, "vudc_rx");
+-              udc->ud.tcp_tx = kthread_get_run(&v_tx_loop,
+-                                                  &udc->ud, "vudc_tx");
++              tcp_rx = kthread_create(&v_rx_loop, &udc->ud, "vudc_rx");
++              if (IS_ERR(tcp_rx)) {
++                      sockfd_put(socket);
++                      return -EINVAL;
++              }
++              tcp_tx = kthread_create(&v_tx_loop, &udc->ud, "vudc_tx");
++              if (IS_ERR(tcp_tx)) {
++                      kthread_stop(tcp_rx);
++                      sockfd_put(socket);
++                      return -EINVAL;
++              }
++
++              /* get task structs now */
++              get_task_struct(tcp_rx);
++              get_task_struct(tcp_tx);
+ 
++              /* lock and update udc->ud state */
+               spin_lock_irqsave(&udc->lock, flags);
+               spin_lock_irq(&udc->ud.lock);
++
++              udc->ud.tcp_socket = socket;
++              udc->ud.tcp_rx = tcp_rx;
++              udc->ud.tcp_rx = tcp_tx;
+               udc->ud.status = SDEV_ST_USED;
++
+               spin_unlock_irq(&udc->ud.lock);
+ 
+               do_gettimeofday(&udc->start_time);
+               v_start_timer(udc);
+               udc->connected = 1;
++
++              spin_unlock_irqrestore(&udc->lock, flags);
++
++              wake_up_process(udc->ud.tcp_rx);
++              wake_up_process(udc->ud.tcp_tx);
++              return count;
++
+       } else {
+               if (!udc->connected) {
+                       dev_err(dev, "Device not connected");
+diff --git a/drivers/xen/events/events_base.c 
b/drivers/xen/events/events_base.c
+index fae2a536acc67..b370144682ed5 100644
+--- a/drivers/xen/events/events_base.c
++++ b/drivers/xen/events/events_base.c
+@@ -221,7 +221,7 @@ static int xen_irq_info_common_setup(struct irq_info *info,
+       info->evtchn = evtchn;
+       info->cpu = cpu;
+       info->mask_reason = EVT_MASK_REASON_EXPLICIT;
+-      spin_lock_init(&info->lock);
++      raw_spin_lock_init(&info->lock);
+ 
+       ret = set_evtchn_to_irq(evtchn, irq);
+       if (ret < 0)
+@@ -373,28 +373,28 @@ static void do_mask(struct irq_info *info, u8 reason)
+ {
+       unsigned long flags;
+ 
+-      spin_lock_irqsave(&info->lock, flags);
++      raw_spin_lock_irqsave(&info->lock, flags);
+ 
+       if (!info->mask_reason)
+               mask_evtchn(info->evtchn);
+ 
+       info->mask_reason |= reason;
+ 
+-      spin_unlock_irqrestore(&info->lock, flags);
++      raw_spin_unlock_irqrestore(&info->lock, flags);
+ }
+ 
+ static void do_unmask(struct irq_info *info, u8 reason)
+ {
+       unsigned long flags;
+ 
+-      spin_lock_irqsave(&info->lock, flags);
++      raw_spin_lock_irqsave(&info->lock, flags);
+ 
+       info->mask_reason &= ~reason;
+ 
+       if (!info->mask_reason)
+               unmask_evtchn(info->evtchn);
+ 
+-      spin_unlock_irqrestore(&info->lock, flags);
++      raw_spin_unlock_irqrestore(&info->lock, flags);
+ }
+ 
+ #ifdef CONFIG_X86
+@@ -1782,7 +1782,7 @@ static void lateeoi_ack_dynirq(struct irq_data *data)
+ 
+       if (VALID_EVTCHN(evtchn)) {
+               do_mask(info, EVT_MASK_REASON_EOI_PENDING);
+-              event_handler_exit(info);
++              ack_dynirq(data);
+       }
+ }
+ 
+@@ -1793,7 +1793,7 @@ static void lateeoi_mask_ack_dynirq(struct irq_data 
*data)
+ 
+       if (VALID_EVTCHN(evtchn)) {
+               do_mask(info, EVT_MASK_REASON_EXPLICIT);
+-              event_handler_exit(info);
++              ack_dynirq(data);
+       }
+ }
+ 
+diff --git a/drivers/xen/events/events_internal.h 
b/drivers/xen/events/events_internal.h
+index 3df6f28b75e69..cc37b711491ce 100644
+--- a/drivers/xen/events/events_internal.h
++++ b/drivers/xen/events/events_internal.h
+@@ -47,7 +47,7 @@ struct irq_info {
+       unsigned short eoi_cpu; /* EOI must happen on this cpu */
+       unsigned int irq_epoch; /* If eoi_cpu valid: irq_epoch of event */
+       u64 eoi_time;           /* Time in jiffies when to EOI. */
+-      spinlock_t lock;
++      raw_spinlock_t lock;
+ 
+       union {
+               unsigned short virq;
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index e7c46368cf696..73be08ea135f6 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -3607,7 +3607,6 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
+               cifs_sb->prepath = kstrdup(pvolume_info->prepath, GFP_KERNEL);
+               if (cifs_sb->prepath == NULL)
+                       return -ENOMEM;
+-              cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
+       }
+ 
+       return 0;
+diff --git a/fs/direct-io.c b/fs/direct-io.c
+index 30bf22c989dee..8d9689aac5f4c 100644
+--- a/fs/direct-io.c
++++ b/fs/direct-io.c
+@@ -857,6 +857,7 @@ submit_page_section(struct dio *dio, struct dio_submit 
*sdio, struct page *page,
+                   struct buffer_head *map_bh)
+ {
+       int ret = 0;
++      int boundary = sdio->boundary;  /* dio_send_cur_page may clear it */
+ 
+       if (dio->op == REQ_OP_WRITE) {
+               /*
+@@ -895,10 +896,10 @@ submit_page_section(struct dio *dio, struct dio_submit 
*sdio, struct page *page,
+       sdio->cur_page_fs_offset = sdio->block_in_file << sdio->blkbits;
+ out:
+       /*
+-       * If sdio->boundary then we want to schedule the IO now to
++       * If boundary then we want to schedule the IO now to
+        * avoid metadata seeks.
+        */
+-      if (sdio->boundary) {
++      if (boundary) {
+               ret = dio_send_cur_page(dio, sdio, map_bh);
+               if (sdio->bio)
+                       dio_bio_submit(dio, sdio);
+diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
+index bcf95ec1bc31d..56bfed0a58731 100644
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -989,11 +989,13 @@ void gfs2_freeze_func(struct work_struct *work)
+ static int gfs2_freeze(struct super_block *sb)
+ {
+       struct gfs2_sbd *sdp = sb->s_fs_info;
+-      int error = 0;
++      int error;
+ 
+       mutex_lock(&sdp->sd_freeze_mutex);
+-      if (atomic_read(&sdp->sd_freeze_state) != SFS_UNFROZEN)
++      if (atomic_read(&sdp->sd_freeze_state) != SFS_UNFROZEN) {
++              error = -EBUSY;
+               goto out;
++      }
+ 
+       if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) {
+               error = -EINVAL;
+@@ -1035,10 +1037,10 @@ static int gfs2_unfreeze(struct super_block *sb)
+       struct gfs2_sbd *sdp = sb->s_fs_info;
+ 
+       mutex_lock(&sdp->sd_freeze_mutex);
+-        if (atomic_read(&sdp->sd_freeze_state) != SFS_FROZEN ||
++      if (atomic_read(&sdp->sd_freeze_state) != SFS_FROZEN ||
+           !gfs2_holder_initialized(&sdp->sd_freeze_gh)) {
+               mutex_unlock(&sdp->sd_freeze_mutex);
+-                return 0;
++              return -EINVAL;
+       }
+ 
+       gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
+diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
+index 7de0c9562b707..ca2b575a1e461 100644
+--- a/fs/ocfs2/aops.c
++++ b/fs/ocfs2/aops.c
+@@ -2309,7 +2309,7 @@ static int ocfs2_dio_end_io_write(struct inode *inode,
+       struct ocfs2_alloc_context *meta_ac = NULL;
+       handle_t *handle = NULL;
+       loff_t end = offset + bytes;
+-      int ret = 0, credits = 0, locked = 0;
++      int ret = 0, credits = 0;
+ 
+       ocfs2_init_dealloc_ctxt(&dealloc);
+ 
+@@ -2320,13 +2320,6 @@ static int ocfs2_dio_end_io_write(struct inode *inode,
+           !dwc->dw_orphaned)
+               goto out;
+ 
+-      /* ocfs2_file_write_iter will get i_mutex, so we need not lock if we
+-       * are in that context. */
+-      if (dwc->dw_writer_pid != task_pid_nr(current)) {
+-              inode_lock(inode);
+-              locked = 1;
+-      }
+-
+       ret = ocfs2_inode_lock(inode, &di_bh, 1);
+       if (ret < 0) {
+               mlog_errno(ret);
+@@ -2401,8 +2394,6 @@ out:
+       if (meta_ac)
+               ocfs2_free_alloc_context(meta_ac);
+       ocfs2_run_deallocs(osb, &dealloc);
+-      if (locked)
+-              inode_unlock(inode);
+       ocfs2_dio_free_write_ctx(inode, dwc);
+ 
+       return ret;
+diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
+index dc455d45a66ae..baf5c4028fd62 100644
+--- a/fs/ocfs2/file.c
++++ b/fs/ocfs2/file.c
+@@ -1250,22 +1250,24 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr 
*attr)
+                               goto bail_unlock;
+                       }
+               }
++              down_write(&OCFS2_I(inode)->ip_alloc_sem);
+               handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS +
+                                          2 * ocfs2_quota_trans_credits(sb));
+               if (IS_ERR(handle)) {
+                       status = PTR_ERR(handle);
+                       mlog_errno(status);
+-                      goto bail_unlock;
++                      goto bail_unlock_alloc;
+               }
+               status = __dquot_transfer(inode, transfer_to);
+               if (status < 0)
+                       goto bail_commit;
+       } else {
++              down_write(&OCFS2_I(inode)->ip_alloc_sem);
+               handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
+               if (IS_ERR(handle)) {
+                       status = PTR_ERR(handle);
+                       mlog_errno(status);
+-                      goto bail_unlock;
++                      goto bail_unlock_alloc;
+               }
+       }
+ 
+@@ -1278,6 +1280,8 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr 
*attr)
+ 
+ bail_commit:
+       ocfs2_commit_trans(osb, handle);
++bail_unlock_alloc:
++      up_write(&OCFS2_I(inode)->ip_alloc_sem);
+ bail_unlock:
+       if (status && inode_locked) {
+               ocfs2_inode_unlock_tracker(inode, 1, &oh, had_lock);
+diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
+index 6ffa181598e61..c4b8602ea6f57 100644
+--- a/include/linux/mlx5/mlx5_ifc.h
++++ b/include/linux/mlx5/mlx5_ifc.h
+@@ -324,11 +324,11 @@ struct mlx5_ifc_flow_table_prop_layout_bits {
+       u8         reserved_at_60[0x18];
+       u8         log_max_ft_num[0x8];
+ 
+-      u8         reserved_at_80[0x18];
++      u8         reserved_at_80[0x10];
++      u8         log_max_flow_counter[0x8];
+       u8         log_max_destination[0x8];
+ 
+-      u8         log_max_flow_counter[0x8];
+-      u8         reserved_at_a8[0x10];
++      u8         reserved_at_a0[0x18];
+       u8         log_max_flow[0x8];
+ 
+       u8         reserved_at_c0[0x40];
+diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
+index 3e26e5dd9546a..48afea1b8b4e5 100644
+--- a/include/linux/virtio_net.h
++++ b/include/linux/virtio_net.h
+@@ -62,6 +62,8 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
+                       return -EINVAL;
+       }
+ 
++      skb_reset_mac_header(skb);
++
+       if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+               u16 start = __virtio16_to_cpu(little_endian, hdr->csum_start);
+               u16 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
+diff --git a/include/net/red.h b/include/net/red.h
+index 8fe55b8b2fb81..ff07a7cedf685 100644
+--- a/include/net/red.h
++++ b/include/net/red.h
+@@ -171,9 +171,9 @@ static inline void red_set_vars(struct red_vars *v)
+ static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog,
+                                   u8 Scell_log, u8 *stab)
+ {
+-      if (fls(qth_min) + Wlog > 32)
++      if (fls(qth_min) + Wlog >= 32)
+               return false;
+-      if (fls(qth_max) + Wlog > 32)
++      if (fls(qth_max) + Wlog >= 32)
+               return false;
+       if (Scell_log >= 32)
+               return false;
+diff --git a/include/uapi/linux/ncsi.h b/include/uapi/linux/ncsi.h
+new file mode 100644
+index 0000000000000..4c292ecbb748f
+--- /dev/null
++++ b/include/uapi/linux/ncsi.h
+@@ -0,0 +1,115 @@
++/*
++ * Copyright Samuel Mendoza-Jonas, IBM Corporation 2018.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#ifndef __UAPI_NCSI_NETLINK_H__
++#define __UAPI_NCSI_NETLINK_H__
++
++/**
++ * enum ncsi_nl_commands - supported NCSI commands
++ *
++ * @NCSI_CMD_UNSPEC: unspecified command to catch errors
++ * @NCSI_CMD_PKG_INFO: list package and channel attributes. Requires
++ *    NCSI_ATTR_IFINDEX. If NCSI_ATTR_PACKAGE_ID is specified returns the
++ *    specific package and its channels - otherwise a dump request returns
++ *    all packages and their associated channels.
++ * @NCSI_CMD_SET_INTERFACE: set preferred package and channel combination.
++ *    Requires NCSI_ATTR_IFINDEX and the preferred NCSI_ATTR_PACKAGE_ID and
++ *    optionally the preferred NCSI_ATTR_CHANNEL_ID.
++ * @NCSI_CMD_CLEAR_INTERFACE: clear any preferred package/channel combination.
++ *    Requires NCSI_ATTR_IFINDEX.
++ * @NCSI_CMD_MAX: highest command number
++ */
++enum ncsi_nl_commands {
++      NCSI_CMD_UNSPEC,
++      NCSI_CMD_PKG_INFO,
++      NCSI_CMD_SET_INTERFACE,
++      NCSI_CMD_CLEAR_INTERFACE,
++
++      __NCSI_CMD_AFTER_LAST,
++      NCSI_CMD_MAX = __NCSI_CMD_AFTER_LAST - 1
++};
++
++/**
++ * enum ncsi_nl_attrs - General NCSI netlink attributes
++ *
++ * @NCSI_ATTR_UNSPEC: unspecified attributes to catch errors
++ * @NCSI_ATTR_IFINDEX: ifindex of network device using NCSI
++ * @NCSI_ATTR_PACKAGE_LIST: nested array of NCSI_PKG_ATTR attributes
++ * @NCSI_ATTR_PACKAGE_ID: package ID
++ * @NCSI_ATTR_CHANNEL_ID: channel ID
++ * @NCSI_ATTR_MAX: highest attribute number
++ */
++enum ncsi_nl_attrs {
++      NCSI_ATTR_UNSPEC,
++      NCSI_ATTR_IFINDEX,
++      NCSI_ATTR_PACKAGE_LIST,
++      NCSI_ATTR_PACKAGE_ID,
++      NCSI_ATTR_CHANNEL_ID,
++
++      __NCSI_ATTR_AFTER_LAST,
++      NCSI_ATTR_MAX = __NCSI_ATTR_AFTER_LAST - 1
++};
++
++/**
++ * enum ncsi_nl_pkg_attrs - NCSI netlink package-specific attributes
++ *
++ * @NCSI_PKG_ATTR_UNSPEC: unspecified attributes to catch errors
++ * @NCSI_PKG_ATTR: nested array of package attributes
++ * @NCSI_PKG_ATTR_ID: package ID
++ * @NCSI_PKG_ATTR_FORCED: flag signifying a package has been set as preferred
++ * @NCSI_PKG_ATTR_CHANNEL_LIST: nested array of NCSI_CHANNEL_ATTR attributes
++ * @NCSI_PKG_ATTR_MAX: highest attribute number
++ */
++enum ncsi_nl_pkg_attrs {
++      NCSI_PKG_ATTR_UNSPEC,
++      NCSI_PKG_ATTR,
++      NCSI_PKG_ATTR_ID,
++      NCSI_PKG_ATTR_FORCED,
++      NCSI_PKG_ATTR_CHANNEL_LIST,
++
++      __NCSI_PKG_ATTR_AFTER_LAST,
++      NCSI_PKG_ATTR_MAX = __NCSI_PKG_ATTR_AFTER_LAST - 1
++};
++
++/**
++ * enum ncsi_nl_channel_attrs - NCSI netlink channel-specific attributes
++ *
++ * @NCSI_CHANNEL_ATTR_UNSPEC: unspecified attributes to catch errors
++ * @NCSI_CHANNEL_ATTR: nested array of channel attributes
++ * @NCSI_CHANNEL_ATTR_ID: channel ID
++ * @NCSI_CHANNEL_ATTR_VERSION_MAJOR: channel major version number
++ * @NCSI_CHANNEL_ATTR_VERSION_MINOR: channel minor version number
++ * @NCSI_CHANNEL_ATTR_VERSION_STR: channel version string
++ * @NCSI_CHANNEL_ATTR_LINK_STATE: channel link state flags
++ * @NCSI_CHANNEL_ATTR_ACTIVE: channels with this flag are in
++ *    NCSI_CHANNEL_ACTIVE state
++ * @NCSI_CHANNEL_ATTR_FORCED: flag signifying a channel has been set as
++ *    preferred
++ * @NCSI_CHANNEL_ATTR_VLAN_LIST: nested array of NCSI_CHANNEL_ATTR_VLAN_IDs
++ * @NCSI_CHANNEL_ATTR_VLAN_ID: VLAN ID being filtered on this channel
++ * @NCSI_CHANNEL_ATTR_MAX: highest attribute number
++ */
++enum ncsi_nl_channel_attrs {
++      NCSI_CHANNEL_ATTR_UNSPEC,
++      NCSI_CHANNEL_ATTR,
++      NCSI_CHANNEL_ATTR_ID,
++      NCSI_CHANNEL_ATTR_VERSION_MAJOR,
++      NCSI_CHANNEL_ATTR_VERSION_MINOR,
++      NCSI_CHANNEL_ATTR_VERSION_STR,
++      NCSI_CHANNEL_ATTR_LINK_STATE,
++      NCSI_CHANNEL_ATTR_ACTIVE,
++      NCSI_CHANNEL_ATTR_FORCED,
++      NCSI_CHANNEL_ATTR_VLAN_LIST,
++      NCSI_CHANNEL_ATTR_VLAN_ID,
++
++      __NCSI_CHANNEL_ATTR_AFTER_LAST,
++      NCSI_CHANNEL_ATTR_MAX = __NCSI_CHANNEL_ATTR_AFTER_LAST - 1
++};
++
++#endif /* __UAPI_NCSI_NETLINK_H__ */
+diff --git a/kernel/workqueue.c b/kernel/workqueue.c
+index 79fcec674485f..bc32ed4a4cf32 100644
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -1379,7 +1379,6 @@ static void __queue_work(int cpu, struct 
workqueue_struct *wq,
+        */
+       WARN_ON_ONCE(!irqs_disabled());
+ 
+-      debug_work_activate(work);
+ 
+       /* if draining, only works from the same workqueue are allowed */
+       if (unlikely(wq->flags & __WQ_DRAINING) &&
+@@ -1462,6 +1461,7 @@ retry:
+               worklist = &pwq->delayed_works;
+       }
+ 
++      debug_work_activate(work);
+       insert_work(pwq, work, worklist, work_flags);
+ 
+       spin_unlock(&pwq->pool->lock);
+diff --git a/net/batman-adv/translation-table.c 
b/net/batman-adv/translation-table.c
+index dbc516824175b..9cef38f6cb4de 100644
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -902,6 +902,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node 
*orig_node,
+       hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
+               tt_vlan->vid = htons(vlan->vid);
+               tt_vlan->crc = htonl(vlan->tt.crc);
++              tt_vlan->reserved = 0;
+ 
+               tt_vlan++;
+       }
+@@ -985,6 +986,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv 
*bat_priv,
+ 
+               tt_vlan->vid = htons(vlan->vid);
+               tt_vlan->crc = htonl(vlan->tt.crc);
++              tt_vlan->reserved = 0;
+ 
+               tt_vlan++;
+       }
+diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
+index d3cbb32587187..c0930b9fe848b 100644
+--- a/net/ieee802154/nl-mac.c
++++ b/net/ieee802154/nl-mac.c
+@@ -559,9 +559,7 @@ ieee802154_llsec_parse_key_id(struct genl_info *info,
+       desc->mode = nla_get_u8(info->attrs[IEEE802154_ATTR_LLSEC_KEY_MODE]);
+ 
+       if (desc->mode == IEEE802154_SCF_KEY_IMPLICIT) {
+-              if (!info->attrs[IEEE802154_ATTR_PAN_ID] &&
+-                  !(info->attrs[IEEE802154_ATTR_SHORT_ADDR] ||
+-                    info->attrs[IEEE802154_ATTR_HW_ADDR]))
++              if (!info->attrs[IEEE802154_ATTR_PAN_ID])
+                       return -EINVAL;
+ 
+               desc->device_addr.pan_id = 
nla_get_shortaddr(info->attrs[IEEE802154_ATTR_PAN_ID]);
+@@ -570,6 +568,9 @@ ieee802154_llsec_parse_key_id(struct genl_info *info,
+                       desc->device_addr.mode = IEEE802154_ADDR_SHORT;
+                       desc->device_addr.short_addr = 
nla_get_shortaddr(info->attrs[IEEE802154_ATTR_SHORT_ADDR]);
+               } else {
++                      if (!info->attrs[IEEE802154_ATTR_HW_ADDR])
++                              return -EINVAL;
++
+                       desc->device_addr.mode = IEEE802154_ADDR_LONG;
+                       desc->device_addr.extended_addr = 
nla_get_hwaddr(info->attrs[IEEE802154_ATTR_HW_ADDR]);
+               }
+diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
+index 99f6c254ea777..b10b297e76b78 100644
+--- a/net/ieee802154/nl802154.c
++++ b/net/ieee802154/nl802154.c
+@@ -836,8 +836,13 @@ nl802154_send_iface(struct sk_buff *msg, u32 portid, u32 
seq, int flags,
+               goto nla_put_failure;
+ 
+ #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
++      if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
++              goto out;
++
+       if (nl802154_get_llsec_params(msg, rdev, wpan_dev) < 0)
+               goto nla_put_failure;
++
++out:
+ #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
+ 
+       genlmsg_end(msg, hdr);
+@@ -1402,6 +1407,9 @@ static int nl802154_set_llsec_params(struct sk_buff *skb,
+       u32 changed = 0;
+       int ret;
+ 
++      if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
++              return -EOPNOTSUPP;
++
+       if (info->attrs[NL802154_ATTR_SEC_ENABLED]) {
+               u8 enabled;
+ 
+@@ -1562,7 +1570,8 @@ static int nl802154_add_llsec_key(struct sk_buff *skb, 
struct genl_info *info)
+       struct ieee802154_llsec_key_id id = { };
+       u32 commands[NL802154_CMD_FRAME_NR_IDS / 32] = { };
+ 
+-      if (nla_parse_nested(attrs, NL802154_KEY_ATTR_MAX,
++      if (!info->attrs[NL802154_ATTR_SEC_KEY] ||
++          nla_parse_nested(attrs, NL802154_KEY_ATTR_MAX,
+                            info->attrs[NL802154_ATTR_SEC_KEY],
+                            nl802154_key_policy, info->extack))
+               return -EINVAL;
+@@ -1612,7 +1621,8 @@ static int nl802154_del_llsec_key(struct sk_buff *skb, 
struct genl_info *info)
+       struct nlattr *attrs[NL802154_KEY_ATTR_MAX + 1];
+       struct ieee802154_llsec_key_id id;
+ 
+-      if (nla_parse_nested(attrs, NL802154_KEY_ATTR_MAX,
++      if (!info->attrs[NL802154_ATTR_SEC_KEY] ||
++          nla_parse_nested(attrs, NL802154_KEY_ATTR_MAX,
+                            info->attrs[NL802154_ATTR_SEC_KEY],
+                            nl802154_key_policy, info->extack))
+               return -EINVAL;
+@@ -1780,7 +1790,8 @@ static int nl802154_del_llsec_dev(struct sk_buff *skb, 
struct genl_info *info)
+       struct nlattr *attrs[NL802154_DEV_ATTR_MAX + 1];
+       __le64 extended_addr;
+ 
+-      if (nla_parse_nested(attrs, NL802154_DEV_ATTR_MAX,
++      if (!info->attrs[NL802154_ATTR_SEC_DEVICE] ||
++          nla_parse_nested(attrs, NL802154_DEV_ATTR_MAX,
+                            info->attrs[NL802154_ATTR_SEC_DEVICE],
+                            nl802154_dev_policy, info->extack))
+               return -EINVAL;
+@@ -1940,7 +1951,8 @@ static int nl802154_del_llsec_devkey(struct sk_buff 
*skb, struct genl_info *info
+       struct ieee802154_llsec_device_key key;
+       __le64 extended_addr;
+ 
+-      if (nla_parse_nested(attrs, NL802154_DEVKEY_ATTR_MAX,
++      if (!info->attrs[NL802154_ATTR_SEC_DEVKEY] ||
++          nla_parse_nested(attrs, NL802154_DEVKEY_ATTR_MAX,
+                            info->attrs[NL802154_ATTR_SEC_DEVKEY],
+                            nl802154_devkey_policy, info->extack))
+               return -EINVAL;
+@@ -2115,6 +2127,9 @@ static int nl802154_del_llsec_seclevel(struct sk_buff 
*skb,
+       struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
+       struct ieee802154_llsec_seclevel sl;
+ 
++      if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
++              return -EOPNOTSUPP;
++
+       if (!info->attrs[NL802154_ATTR_SEC_LEVEL] ||
+           llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL],
+                                &sl) < 0)
+diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
+index 6dd727e0a72f6..13a46066546db 100644
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -1196,6 +1196,8 @@ static int translate_compat_table(struct net *net,
+       if (!newinfo)
+               goto out_unlock;
+ 
++      memset(newinfo->entries, 0, size);
++
+       newinfo->number = compatr->num_entries;
+       for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
+               newinfo->hook_entry[i] = compatr->hook_entry[i];
+diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
+index 0d1a2cda1bfb1..a4039ac65b546 100644
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -1432,6 +1432,8 @@ translate_compat_table(struct net *net,
+       if (!newinfo)
+               goto out_unlock;
+ 
++      memset(newinfo->entries, 0, size);
++
+       newinfo->number = compatr->num_entries;
+       for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+               newinfo->hook_entry[i] = compatr->hook_entry[i];
+diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
+index 90f5bf2502a73..d0d5e43727307 100644
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -1449,6 +1449,8 @@ translate_compat_table(struct net *net,
+       if (!newinfo)
+               goto out_unlock;
+ 
++      memset(newinfo->entries, 0, size);
++
+       newinfo->number = compatr->num_entries;
+       for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+               newinfo->hook_entry[i] = compatr->hook_entry[i];
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index ddcaca5979b1d..76e10019a0e9f 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -3283,9 +3283,11 @@ static int ip6_route_multipath_add(struct fib6_config 
*cfg,
+                * nexthops have been replaced by first new, the rest should
+                * be added to it.
+                */
+-              cfg->fc_nlinfo.nlh->nlmsg_flags &= ~(NLM_F_EXCL |
+-                                                   NLM_F_REPLACE);
+-              cfg->fc_nlinfo.nlh->nlmsg_flags |= NLM_F_CREATE;
++              if (cfg->fc_nlinfo.nlh) {
++                      cfg->fc_nlinfo.nlh->nlmsg_flags &= ~(NLM_F_EXCL |
++                                                           NLM_F_REPLACE);
++                      cfg->fc_nlinfo.nlh->nlmsg_flags |= NLM_F_CREATE;
++              }
+               nhn++;
+       }
+ 
+diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c
+index 1e1c9b20bab7f..ed1b9876d5458 100644
+--- a/net/mac802154/llsec.c
++++ b/net/mac802154/llsec.c
+@@ -160,7 +160,7 @@ err_tfm0:
+       crypto_free_skcipher(key->tfm0);
+ err_tfm:
+       for (i = 0; i < ARRAY_SIZE(key->tfm); i++)
+-              if (key->tfm[i])
++              if (!IS_ERR_OR_NULL(key->tfm[i]))
+                       crypto_free_aead(key->tfm[i]);
+ 
+       kzfree(key);
+diff --git a/net/ncsi/Makefile b/net/ncsi/Makefile
+index dd12b564f2e7e..436ef68331f2b 100644
+--- a/net/ncsi/Makefile
++++ b/net/ncsi/Makefile
+@@ -1,4 +1,4 @@
+ #
+ # Makefile for NCSI API
+ #
+-obj-$(CONFIG_NET_NCSI) += ncsi-cmd.o ncsi-rsp.o ncsi-aen.o ncsi-manage.o
++obj-$(CONFIG_NET_NCSI) += ncsi-cmd.o ncsi-rsp.o ncsi-aen.o ncsi-manage.o 
ncsi-netlink.o
+diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h
+index d30f7bd741d06..8055e3965cef2 100644
+--- a/net/ncsi/internal.h
++++ b/net/ncsi/internal.h
+@@ -68,15 +68,6 @@ enum {
+       NCSI_MODE_MAX
+ };
+ 
+-enum {
+-      NCSI_FILTER_BASE        = 0,
+-      NCSI_FILTER_VLAN        = 0,
+-      NCSI_FILTER_UC,
+-      NCSI_FILTER_MC,
+-      NCSI_FILTER_MIXED,
+-      NCSI_FILTER_MAX
+-};
+-
+ struct ncsi_channel_version {
+       u32 version;            /* Supported BCD encoded NCSI version */
+       u32 alpha2;             /* Supported BCD encoded NCSI version */
+@@ -98,11 +89,18 @@ struct ncsi_channel_mode {
+       u32 data[8];    /* Data entries                */
+ };
+ 
+-struct ncsi_channel_filter {
+-      u32 index;      /* Index of channel filters          */
+-      u32 total;      /* Total entries in the filter table */
+-      u64 bitmap;     /* Bitmap of valid entries           */
+-      u32 data[];     /* Data for the valid entries        */
++struct ncsi_channel_mac_filter {
++      u8      n_uc;
++      u8      n_mc;
++      u8      n_mixed;
++      u64     bitmap;
++      unsigned char   *addrs;
++};
++
++struct ncsi_channel_vlan_filter {
++      u8      n_vids;
++      u64     bitmap;
++      u16     *vids;
+ };
+ 
+ struct ncsi_channel_stats {
+@@ -186,7 +184,9 @@ struct ncsi_channel {
+       struct ncsi_channel_version version;
+       struct ncsi_channel_cap     caps[NCSI_CAP_MAX];
+       struct ncsi_channel_mode    modes[NCSI_MODE_MAX];
+-      struct ncsi_channel_filter  *filters[NCSI_FILTER_MAX];
++      /* Filtering Settings */
++      struct ncsi_channel_mac_filter  mac_filter;
++      struct ncsi_channel_vlan_filter vlan_filter;
+       struct ncsi_channel_stats   stats;
+       struct {
+               struct timer_list   timer;
+@@ -276,6 +276,8 @@ struct ncsi_dev_priv {
+       unsigned int        package_num;     /* Number of packages         */
+       struct list_head    packages;        /* List of packages           */
+       struct ncsi_channel *hot_channel;    /* Channel was ever active    */
++      struct ncsi_package *force_package;  /* Force a specific package   */
++      struct ncsi_channel *force_channel;  /* Force a specific channel   */
+       struct ncsi_request requests[256];   /* Request table              */
+       unsigned int        request_id;      /* Last used request ID       */
+ #define NCSI_REQ_START_IDX    1
+@@ -318,9 +320,6 @@ extern spinlock_t ncsi_dev_lock;
+       list_for_each_entry_rcu(nc, &np->channels, node)
+ 
+ /* Resources */
+-int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data);
+-int ncsi_add_filter(struct ncsi_channel *nc, int table, void *data);
+-int ncsi_remove_filter(struct ncsi_channel *nc, int table, int index);
+ void ncsi_start_channel_monitor(struct ncsi_channel *nc);
+ void ncsi_stop_channel_monitor(struct ncsi_channel *nc);
+ struct ncsi_channel *ncsi_find_channel(struct ncsi_package *np,
+diff --git a/net/ncsi/ncsi-aen.c b/net/ncsi/ncsi-aen.c
+index f135938bf781e..67e708e98ccf0 100644
+--- a/net/ncsi/ncsi-aen.c
++++ b/net/ncsi/ncsi-aen.c
+@@ -73,6 +73,9 @@ static int ncsi_aen_handler_lsc(struct ncsi_dev_priv *ndp,
+       ncm->data[2] = data;
+       ncm->data[4] = ntohl(lsc->oem_status);
+ 
++      netdev_info(ndp->ndev.dev, "NCSI: LSC AEN - channel %u state %s\n",
++                  nc->id, data & 0x1 ? "up" : "down");
++
+       chained = !list_empty(&nc->link);
+       state = nc->state;
+       spin_unlock_irqrestore(&nc->lock, flags);
+@@ -145,6 +148,8 @@ static int ncsi_aen_handler_hncdsc(struct ncsi_dev_priv 
*ndp,
+       ncm = &nc->modes[NCSI_MODE_LINK];
+       hncdsc = (struct ncsi_aen_hncdsc_pkt *)h;
+       ncm->data[3] = ntohl(hncdsc->status);
++      netdev_info(ndp->ndev.dev, "NCSI: HNCDSC AEN - channel %u state %s\n",
++                  nc->id, ncm->data[3] & 0x3 ? "up" : "down");
+       if (!list_empty(&nc->link) ||
+           nc->state != NCSI_CHANNEL_ACTIVE) {
+               spin_unlock_irqrestore(&nc->lock, flags);
+@@ -212,10 +217,18 @@ int ncsi_aen_handler(struct ncsi_dev_priv *ndp, struct 
sk_buff *skb)
+       }
+ 
+       ret = ncsi_validate_aen_pkt(h, nah->payload);
+-      if (ret)
++      if (ret) {
++              netdev_warn(ndp->ndev.dev,
++                          "NCSI: 'bad' packet ignored for AEN type 0x%x\n",
++                          h->type);
+               goto out;
++      }
+ 
+       ret = nah->handler(ndp, h);
++      if (ret)
++              netdev_err(ndp->ndev.dev,
++                         "NCSI: Handler for AEN type 0x%x returned %d\n",
++                         h->type, ret);
+ out:
+       consume_skb(skb);
+       return ret;
+diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c
+index 28c42b22b7489..dbe8aec6c57bb 100644
+--- a/net/ncsi/ncsi-manage.c
++++ b/net/ncsi/ncsi-manage.c
+@@ -12,7 +12,6 @@
+ #include <linux/init.h>
+ #include <linux/netdevice.h>
+ #include <linux/skbuff.h>
+-#include <linux/netlink.h>
+ 
+ #include <net/ncsi.h>
+ #include <net/net_namespace.h>
+@@ -23,129 +22,11 @@
+ 
+ #include "internal.h"
+ #include "ncsi-pkt.h"
++#include "ncsi-netlink.h"
+ 
+ LIST_HEAD(ncsi_dev_list);
+ DEFINE_SPINLOCK(ncsi_dev_lock);
+ 
+-static inline int ncsi_filter_size(int table)
+-{
+-      int sizes[] = { 2, 6, 6, 6 };
+-
+-      BUILD_BUG_ON(ARRAY_SIZE(sizes) != NCSI_FILTER_MAX);
+-      if (table < NCSI_FILTER_BASE || table >= NCSI_FILTER_MAX)
+-              return -EINVAL;
+-
+-      return sizes[table];
+-}
+-
+-u32 *ncsi_get_filter(struct ncsi_channel *nc, int table, int index)
+-{
+-      struct ncsi_channel_filter *ncf;
+-      int size;
+-
+-      ncf = nc->filters[table];
+-      if (!ncf)
+-              return NULL;
+-
+-      size = ncsi_filter_size(table);
+-      if (size < 0)
+-              return NULL;
+-
+-      return ncf->data + size * index;
+-}
+-
+-/* Find the first active filter in a filter table that matches the given
+- * data parameter. If data is NULL, this returns the first active filter.
+- */
+-int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data)
+-{
+-      struct ncsi_channel_filter *ncf;
+-      void *bitmap;
+-      int index, size;
+-      unsigned long flags;
+-
+-      ncf = nc->filters[table];
+-      if (!ncf)
+-              return -ENXIO;
+-
+-      size = ncsi_filter_size(table);
+-      if (size < 0)
+-              return size;
+-
+-      spin_lock_irqsave(&nc->lock, flags);
+-      bitmap = (void *)&ncf->bitmap;
+-      index = -1;
+-      while ((index = find_next_bit(bitmap, ncf->total, index + 1))
+-             < ncf->total) {
+-              if (!data || !memcmp(ncf->data + size * index, data, size)) {
+-                      spin_unlock_irqrestore(&nc->lock, flags);
+-                      return index;
+-              }
+-      }
+-      spin_unlock_irqrestore(&nc->lock, flags);
+-
+-      return -ENOENT;
+-}
+-
+-int ncsi_add_filter(struct ncsi_channel *nc, int table, void *data)
+-{
+-      struct ncsi_channel_filter *ncf;
+-      int index, size;
+-      void *bitmap;
+-      unsigned long flags;
+-
+-      size = ncsi_filter_size(table);
+-      if (size < 0)
+-              return size;
+-
+-      index = ncsi_find_filter(nc, table, data);
+-      if (index >= 0)
+-              return index;
+-
+-      ncf = nc->filters[table];
+-      if (!ncf)
+-              return -ENODEV;
+-
+-      spin_lock_irqsave(&nc->lock, flags);
+-      bitmap = (void *)&ncf->bitmap;
+-      do {
+-              index = find_next_zero_bit(bitmap, ncf->total, 0);
+-              if (index >= ncf->total) {
+-                      spin_unlock_irqrestore(&nc->lock, flags);
+-                      return -ENOSPC;
+-              }
+-      } while (test_and_set_bit(index, bitmap));
+-
+-      memcpy(ncf->data + size * index, data, size);
+-      spin_unlock_irqrestore(&nc->lock, flags);
+-
+-      return index;
+-}
+-
+-int ncsi_remove_filter(struct ncsi_channel *nc, int table, int index)
+-{
+-      struct ncsi_channel_filter *ncf;
+-      int size;
+-      void *bitmap;
+-      unsigned long flags;
+-
+-      size = ncsi_filter_size(table);
+-      if (size < 0)
+-              return size;
+-
+-      ncf = nc->filters[table];
+-      if (!ncf || index >= ncf->total)
+-              return -ENODEV;
+-
+-      spin_lock_irqsave(&nc->lock, flags);
+-      bitmap = (void *)&ncf->bitmap;
+-      if (test_and_clear_bit(index, bitmap))
+-              memset(ncf->data + size * index, 0, size);
+-      spin_unlock_irqrestore(&nc->lock, flags);
+-
+-      return 0;
+-}
+-
+ static void ncsi_report_link(struct ncsi_dev_priv *ndp, bool force_down)
+ {
+       struct ncsi_dev *nd = &ndp->ndev;
+@@ -203,13 +84,20 @@ static void ncsi_channel_monitor(unsigned long data)
+       monitor_state = nc->monitor.state;
+       spin_unlock_irqrestore(&nc->lock, flags);
+ 
+-      if (!enabled || chained) {
+-              ncsi_stop_channel_monitor(nc);
+-              return;
+-      }
++      if (!enabled)
++              return;         /* expected race disabling timer */
++      if (WARN_ON_ONCE(chained))
++              goto bad_state;
++
+       if (state != NCSI_CHANNEL_INACTIVE &&
+           state != NCSI_CHANNEL_ACTIVE) {
+-              ncsi_stop_channel_monitor(nc);
++bad_state:
++              netdev_warn(ndp->ndev.dev,
++                          "Bad NCSI monitor state channel %d 0x%x %s queue\n",
++                          nc->id, state, chained ? "on" : "off");
++              spin_lock_irqsave(&nc->lock, flags);
++              nc->monitor.enabled = false;
++              spin_unlock_irqrestore(&nc->lock, flags);
+               return;
+       }
+ 
+@@ -229,15 +117,16 @@ static void ncsi_channel_monitor(unsigned long data)
+       case NCSI_CHANNEL_MONITOR_WAIT ... NCSI_CHANNEL_MONITOR_WAIT_MAX:
+               break;
+       default:
++              netdev_err(ndp->ndev.dev, "NCSI Channel %d timed out!\n",
++                         nc->id);
+               if (!(ndp->flags & NCSI_DEV_HWA)) {
+                       ncsi_report_link(ndp, true);
+                       ndp->flags |= NCSI_DEV_RESHUFFLE;
+               }
+ 
+-              ncsi_stop_channel_monitor(nc);
+-
+               ncm = &nc->modes[NCSI_MODE_LINK];
+               spin_lock_irqsave(&nc->lock, flags);
++              nc->monitor.enabled = false;
+               nc->state = NCSI_CHANNEL_INVISIBLE;
+               ncm->data[2] &= ~0x1;
+               spin_unlock_irqrestore(&nc->lock, flags);
+@@ -338,20 +227,13 @@ struct ncsi_channel *ncsi_add_channel(struct 
ncsi_package *np, unsigned char id)
+ static void ncsi_remove_channel(struct ncsi_channel *nc)
+ {
+       struct ncsi_package *np = nc->package;
+-      struct ncsi_channel_filter *ncf;
+       unsigned long flags;
+-      int i;
+ 
+-      /* Release filters */
+       spin_lock_irqsave(&nc->lock, flags);
+-      for (i = 0; i < NCSI_FILTER_MAX; i++) {
+-              ncf = nc->filters[i];
+-              if (!ncf)
+-                      continue;
+ 
+-              nc->filters[i] = NULL;
+-              kfree(ncf);
+-      }
++      /* Release filters */
++      kfree(nc->mac_filter.addrs);
++      kfree(nc->vlan_filter.vids);
+ 
+       nc->state = NCSI_CHANNEL_INACTIVE;
+       spin_unlock_irqrestore(&nc->lock, flags);
+@@ -669,32 +551,26 @@ error:
+ static int clear_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc,
+                        struct ncsi_cmd_arg *nca)
+ {
++      struct ncsi_channel_vlan_filter *ncf;
++      unsigned long flags;
++      void *bitmap;
+       int index;
+-      u32 *data;
+       u16 vid;
+ 
+-      index = ncsi_find_filter(nc, NCSI_FILTER_VLAN, NULL);
+-      if (index < 0) {
+-              /* Filter table empty */
+-              return -1;
+-      }
++      ncf = &nc->vlan_filter;
++      bitmap = &ncf->bitmap;
+ 
+-      data = ncsi_get_filter(nc, NCSI_FILTER_VLAN, index);
+-      if (!data) {
+-              netdev_err(ndp->ndev.dev,
+-                         "ncsi: failed to retrieve filter %d\n", index);
+-              /* Set the VLAN id to 0 - this will still disable the entry in
+-               * the filter table, but we won't know what it was.
+-               */
+-              vid = 0;
+-      } else {
+-              vid = *(u16 *)data;
++      spin_lock_irqsave(&nc->lock, flags);
++      index = find_next_bit(bitmap, ncf->n_vids, 0);
++      if (index >= ncf->n_vids) {
++              spin_unlock_irqrestore(&nc->lock, flags);
++              return -1;
+       }
++      vid = ncf->vids[index];
+ 
+-      netdev_printk(KERN_DEBUG, ndp->ndev.dev,
+-                    "ncsi: removed vlan tag %u at index %d\n",
+-                    vid, index + 1);
+-      ncsi_remove_filter(nc, NCSI_FILTER_VLAN, index);
++      clear_bit(index, bitmap);
++      ncf->vids[index] = 0;
++      spin_unlock_irqrestore(&nc->lock, flags);
+ 
+       nca->type = NCSI_PKT_CMD_SVF;
+       nca->words[1] = vid;
+@@ -710,45 +586,55 @@ static int clear_one_vid(struct ncsi_dev_priv *ndp, 
struct ncsi_channel *nc,
+ static int set_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc,
+                      struct ncsi_cmd_arg *nca)
+ {
++      struct ncsi_channel_vlan_filter *ncf;
+       struct vlan_vid *vlan = NULL;
+-      int index = 0;
++      unsigned long flags;
++      int i, index;
++      void *bitmap;
++      u16 vid;
++
++      if (list_empty(&ndp->vlan_vids))
++              return -1;
++
++      ncf = &nc->vlan_filter;
++      bitmap = &ncf->bitmap;
+ 
++      spin_lock_irqsave(&nc->lock, flags);
++
++      rcu_read_lock();
+       list_for_each_entry_rcu(vlan, &ndp->vlan_vids, list) {
+-              index = ncsi_find_filter(nc, NCSI_FILTER_VLAN, &vlan->vid);
+-              if (index < 0) {
+-                      /* New tag to add */
+-                      netdev_printk(KERN_DEBUG, ndp->ndev.dev,
+-                                    "ncsi: new vlan id to set: %u\n",
+-                                    vlan->vid);
++              vid = vlan->vid;
++              for (i = 0; i < ncf->n_vids; i++)
++                      if (ncf->vids[i] == vid) {
++                              vid = 0;
++                              break;
++                      }
++              if (vid)
+                       break;
+-              }
+-              netdev_printk(KERN_DEBUG, ndp->ndev.dev,
+-                            "vid %u already at filter pos %d\n",
+-                            vlan->vid, index);
+       }
++      rcu_read_unlock();
+ 
+-      if (!vlan || index >= 0) {
+-              netdev_printk(KERN_DEBUG, ndp->ndev.dev,
+-                            "no vlan ids left to set\n");
++      if (!vid) {
++              /* No VLAN ID is not set */
++              spin_unlock_irqrestore(&nc->lock, flags);
+               return -1;
+       }
+ 
+-      index = ncsi_add_filter(nc, NCSI_FILTER_VLAN, &vlan->vid);
+-      if (index < 0) {
++      index = find_next_zero_bit(bitmap, ncf->n_vids, 0);
++      if (index < 0 || index >= ncf->n_vids) {
+               netdev_err(ndp->ndev.dev,
+-                         "Failed to add new VLAN tag, error %d\n", index);
+-              if (index == -ENOSPC)
+-                      netdev_err(ndp->ndev.dev,
+-                                 "Channel %u already has all VLAN filters 
set\n",
+-                                 nc->id);
++                         "Channel %u already has all VLAN filters set\n",
++                         nc->id);
++              spin_unlock_irqrestore(&nc->lock, flags);
+               return -1;
+       }
+ 
+-      netdev_printk(KERN_DEBUG, ndp->ndev.dev,
+-                    "ncsi: set vid %u in packet, index %u\n",
+-                    vlan->vid, index + 1);
++      ncf->vids[index] = vid;
++      set_bit(index, bitmap);
++      spin_unlock_irqrestore(&nc->lock, flags);
++
+       nca->type = NCSI_PKT_CMD_SVF;
+-      nca->words[1] = vlan->vid;
++      nca->words[1] = vid;
+       /* HW filter index starts at 1 */
+       nca->bytes[6] = index + 1;
+       nca->bytes[7] = 0x01;
+@@ -784,8 +670,11 @@ static void ncsi_configure_channel(struct ncsi_dev_priv 
*ndp)
+               nca.package = np->id;
+               nca.channel = NCSI_RESERVED_CHANNEL;
+               ret = ncsi_xmit_cmd(&nca);
+-              if (ret)
++              if (ret) {
++                      netdev_err(ndp->ndev.dev,
++                                 "NCSI: Failed to transmit CMD_SP\n");
+                       goto error;
++              }
+ 
+               nd->state = ncsi_dev_state_config_cis;
+               break;
+@@ -797,8 +686,11 @@ static void ncsi_configure_channel(struct ncsi_dev_priv 
*ndp)
+               nca.package = np->id;
+               nca.channel = nc->id;
+               ret = ncsi_xmit_cmd(&nca);
+-              if (ret)
++              if (ret) {
++                      netdev_err(ndp->ndev.dev,
++                                 "NCSI: Failed to transmit CMD_CIS\n");
+                       goto error;
++              }
+ 
+               nd->state = ncsi_dev_state_config_clear_vids;
+               break;
+@@ -895,10 +787,16 @@ static void ncsi_configure_channel(struct ncsi_dev_priv 
*ndp)
+               }
+ 
+               ret = ncsi_xmit_cmd(&nca);
+-              if (ret)
++              if (ret) {
++                      netdev_err(ndp->ndev.dev,
++                                 "NCSI: Failed to transmit CMD %x\n",
++                                 nca.type);
+                       goto error;
++              }
+               break;
+       case ncsi_dev_state_config_done:
++              netdev_printk(KERN_DEBUG, ndp->ndev.dev,
++                            "NCSI: channel %u config done\n", nc->id);
+               spin_lock_irqsave(&nc->lock, flags);
+               if (nc->reconfigure_needed) {
+                       /* This channel's configuration has been updated
+@@ -925,6 +823,9 @@ static void ncsi_configure_channel(struct ncsi_dev_priv 
*ndp)
+               } else {
+                       hot_nc = NULL;
+                       nc->state = NCSI_CHANNEL_INACTIVE;
++                      netdev_warn(ndp->ndev.dev,
++                                  "NCSI: channel %u link down after config\n",
++                                  nc->id);
+               }
+               spin_unlock_irqrestore(&nc->lock, flags);
+ 
+@@ -937,8 +838,8 @@ static void ncsi_configure_channel(struct ncsi_dev_priv 
*ndp)
+               ncsi_process_next_channel(ndp);
+               break;
+       default:
+-              netdev_warn(dev, "Wrong NCSI state 0x%x in config\n",
+-                          nd->state);
++              netdev_alert(dev, "Wrong NCSI state 0x%x in config\n",
++                           nd->state);
+       }
+ 
+       return;
+@@ -949,20 +850,37 @@ error:
+ 
+ static int ncsi_choose_active_channel(struct ncsi_dev_priv *ndp)
+ {
+-      struct ncsi_package *np;
+-      struct ncsi_channel *nc, *found, *hot_nc;
++      struct ncsi_package *np, *force_package;
++      struct ncsi_channel *nc, *found, *hot_nc, *force_channel;
+       struct ncsi_channel_mode *ncm;
+       unsigned long flags;
+ 
+       spin_lock_irqsave(&ndp->lock, flags);
+       hot_nc = ndp->hot_channel;
++      force_channel = ndp->force_channel;
++      force_package = ndp->force_package;
+       spin_unlock_irqrestore(&ndp->lock, flags);
+ 
++      /* Force a specific channel whether or not it has link if we have been
++       * configured to do so
++       */
++      if (force_package && force_channel) {
++              found = force_channel;
++              ncm = &found->modes[NCSI_MODE_LINK];
++              if (!(ncm->data[2] & 0x1))
++                      netdev_info(ndp->ndev.dev,
++                                  "NCSI: Channel %u forced, but it is link 
down\n",
++                                  found->id);
++              goto out;
++      }
++
+       /* The search is done once an inactive channel with up
+        * link is found.
+        */
+       found = NULL;
+       NCSI_FOR_EACH_PACKAGE(ndp, np) {
++              if (ndp->force_package && np != ndp->force_package)
++                      continue;
+               NCSI_FOR_EACH_CHANNEL(np, nc) {
+                       spin_lock_irqsave(&nc->lock, flags);
+ 
+@@ -990,10 +908,17 @@ static int ncsi_choose_active_channel(struct 
ncsi_dev_priv *ndp)
+       }
+ 
+       if (!found) {
++              netdev_warn(ndp->ndev.dev,
++                          "NCSI: No channel found with link\n");
+               ncsi_report_link(ndp, true);
+               return -ENODEV;
+       }
+ 
++      ncm = &found->modes[NCSI_MODE_LINK];
++      netdev_printk(KERN_DEBUG, ndp->ndev.dev,
++                    "NCSI: Channel %u added to queue (link %s)\n",
++                    found->id, ncm->data[2] & 0x1 ? "up" : "down");
++
+ out:
+       spin_lock_irqsave(&ndp->lock, flags);
+       list_add_tail_rcu(&found->link, &ndp->channel_queue);
+@@ -1055,6 +980,8 @@ static int ncsi_enable_hwa(struct ncsi_dev_priv *ndp)
+ 
+       /* We can have no channels in extremely case */
+       if (list_empty(&ndp->channel_queue)) {
++              netdev_err(ndp->ndev.dev,
++                         "NCSI: No available channels for HWA\n");
+               ncsi_report_link(ndp, false);
+               return -ENOENT;
+       }
+@@ -1223,6 +1150,9 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)
+ 
+       return;
+ error:
++      netdev_err(ndp->ndev.dev,
++                 "NCSI: Failed to transmit cmd 0x%x during probe\n",
++                 nca.type);
+       ncsi_report_link(ndp, true);
+ }
+ 
+@@ -1276,10 +1206,14 @@ int ncsi_process_next_channel(struct ncsi_dev_priv 
*ndp)
+       switch (old_state) {
+       case NCSI_CHANNEL_INACTIVE:
+               ndp->ndev.state = ncsi_dev_state_config;
++              netdev_info(ndp->ndev.dev, "NCSI: configuring channel %u\n",
++                          nc->id);
+               ncsi_configure_channel(ndp);
+               break;
+       case NCSI_CHANNEL_ACTIVE:
+               ndp->ndev.state = ncsi_dev_state_suspend;
++              netdev_info(ndp->ndev.dev, "NCSI: suspending channel %u\n",
++                          nc->id);
+               ncsi_suspend_channel(ndp);
+               break;
+       default:
+@@ -1299,6 +1233,8 @@ out:
+               return ncsi_choose_active_channel(ndp);
+       }
+ 
++      netdev_printk(KERN_DEBUG, ndp->ndev.dev,
++                    "NCSI: No more channels to process\n");
+       ncsi_report_link(ndp, false);
+       return -ENODEV;
+ }
+@@ -1390,7 +1326,7 @@ static int ncsi_kick_channels(struct ncsi_dev_priv *ndp)
+                                               ncsi_dev_state_config ||
+                                               !list_empty(&nc->link)) {
+                                       netdev_printk(KERN_DEBUG, nd->dev,
+-                                                    "ncsi: channel %p marked 
dirty\n",
++                                                    "NCSI: channel %p marked 
dirty\n",
+                                                     nc);
+                                       nc->reconfigure_needed = true;
+                               }
+@@ -1410,7 +1346,7 @@ static int ncsi_kick_channels(struct ncsi_dev_priv *ndp)
+                       spin_unlock_irqrestore(&ndp->lock, flags);
+ 
+                       netdev_printk(KERN_DEBUG, nd->dev,
+-                                    "ncsi: kicked channel %p\n", nc);
++                                    "NCSI: kicked channel %p\n", nc);
+                       n++;
+               }
+       }
+@@ -1431,7 +1367,7 @@ int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 
proto, u16 vid)
+ 
+       nd = ncsi_find_dev(dev);
+       if (!nd) {
+-              netdev_warn(dev, "ncsi: No net_device?\n");
++              netdev_warn(dev, "NCSI: No net_device?\n");
+               return 0;
+       }
+ 
+@@ -1442,7 +1378,7 @@ int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 
proto, u16 vid)
+               n_vids++;
+               if (vlan->vid == vid) {
+                       netdev_printk(KERN_DEBUG, dev,
+-                                    "vid %u already registered\n", vid);
++                                    "NCSI: vid %u already registered\n", vid);
+                       return 0;
+               }
+       }
+@@ -1461,7 +1397,7 @@ int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 
proto, u16 vid)
+       vlan->vid = vid;
+       list_add_rcu(&vlan->list, &ndp->vlan_vids);
+ 
+-      netdev_printk(KERN_DEBUG, dev, "Added new vid %u\n", vid);
++      netdev_printk(KERN_DEBUG, dev, "NCSI: Added new vid %u\n", vid);
+ 
+       found = ncsi_kick_channels(ndp) != 0;
+ 
+@@ -1481,7 +1417,7 @@ int ncsi_vlan_rx_kill_vid(struct net_device *dev, __be16 
proto, u16 vid)
+ 
+       nd = ncsi_find_dev(dev);
+       if (!nd) {
+-              netdev_warn(dev, "ncsi: no net_device?\n");
++              netdev_warn(dev, "NCSI: no net_device?\n");
+               return 0;
+       }
+ 
+@@ -1491,14 +1427,14 @@ int ncsi_vlan_rx_kill_vid(struct net_device *dev, 
__be16 proto, u16 vid)
+       list_for_each_entry_safe(vlan, tmp, &ndp->vlan_vids, list)
+               if (vlan->vid == vid) {
+                       netdev_printk(KERN_DEBUG, dev,
+-                                    "vid %u found, removing\n", vid);
++                                    "NCSI: vid %u found, removing\n", vid);
+                       list_del_rcu(&vlan->list);
+                       found = true;
+                       kfree(vlan);
+               }
+ 
+       if (!found) {
+-              netdev_err(dev, "ncsi: vid %u wasn't registered!\n", vid);
++              netdev_err(dev, "NCSI: vid %u wasn't registered!\n", vid);
+               return -EINVAL;
+       }
+ 
+@@ -1562,6 +1498,9 @@ struct ncsi_dev *ncsi_register_dev(struct net_device 
*dev,
+       ndp->ptype.dev = dev;
+       dev_add_pack(&ndp->ptype);
+ 
++      /* Set up generic netlink interface */
++      ncsi_init_netlink(dev);
++
+       return nd;
+ }
+ EXPORT_SYMBOL_GPL(ncsi_register_dev);
+@@ -1581,10 +1520,12 @@ int ncsi_start_dev(struct ncsi_dev *nd)
+               return 0;
+       }
+ 
+-      if (ndp->flags & NCSI_DEV_HWA)
++      if (ndp->flags & NCSI_DEV_HWA) {
++              netdev_info(ndp->ndev.dev, "NCSI: Enabling HWA mode\n");
+               ret = ncsi_enable_hwa(ndp);
+-      else
++      } else {
+               ret = ncsi_choose_active_channel(ndp);
++      }
+ 
+       return ret;
+ }
+@@ -1615,6 +1556,7 @@ void ncsi_stop_dev(struct ncsi_dev *nd)
+               }
+       }
+ 
++      netdev_printk(KERN_DEBUG, ndp->ndev.dev, "NCSI: Stopping device\n");
+       ncsi_report_link(ndp, true);
+ }
+ EXPORT_SYMBOL_GPL(ncsi_stop_dev);
+@@ -1638,6 +1580,8 @@ void ncsi_unregister_dev(struct ncsi_dev *nd)
+ #endif
+       spin_unlock_irqrestore(&ncsi_dev_lock, flags);
+ 
++      ncsi_unregister_netlink(nd->dev);
++
+       kfree(ndp);
+ }
+ EXPORT_SYMBOL_GPL(ncsi_unregister_dev);
+diff --git a/net/ncsi/ncsi-netlink.c b/net/ncsi/ncsi-netlink.c
+new file mode 100644
+index 0000000000000..9073911ac97b3
+--- /dev/null
++++ b/net/ncsi/ncsi-netlink.c
+@@ -0,0 +1,415 @@
++/*
++ * Copyright Samuel Mendoza-Jonas, IBM Corporation 2018.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/if_arp.h>
++#include <linux/rtnetlink.h>
++#include <linux/etherdevice.h>
++#include <linux/module.h>
++#include <net/genetlink.h>
++#include <net/ncsi.h>
++#include <linux/skbuff.h>
++#include <net/sock.h>
++#include <uapi/linux/ncsi.h>
++
++#include "internal.h"
++#include "ncsi-netlink.h"
++
++static struct genl_family ncsi_genl_family;
++
++static const struct nla_policy ncsi_genl_policy[NCSI_ATTR_MAX + 1] = {
++      [NCSI_ATTR_IFINDEX] =           { .type = NLA_U32 },
++      [NCSI_ATTR_PACKAGE_LIST] =      { .type = NLA_NESTED },
++      [NCSI_ATTR_PACKAGE_ID] =        { .type = NLA_U32 },
++      [NCSI_ATTR_CHANNEL_ID] =        { .type = NLA_U32 },
++};
++
++static struct ncsi_dev_priv *ndp_from_ifindex(struct net *net, u32 ifindex)
++{
++      struct ncsi_dev_priv *ndp;
++      struct net_device *dev;
++      struct ncsi_dev *nd;
++      struct ncsi_dev;
++
++      if (!net)
++              return NULL;
++
++      dev = dev_get_by_index(net, ifindex);
++      if (!dev) {
++              pr_err("NCSI netlink: No device for ifindex %u\n", ifindex);
++              return NULL;
++      }
++
++      nd = ncsi_find_dev(dev);
++      ndp = nd ? TO_NCSI_DEV_PRIV(nd) : NULL;
++
++      dev_put(dev);
++      return ndp;
++}
++
++static int ncsi_write_channel_info(struct sk_buff *skb,
++                                 struct ncsi_dev_priv *ndp,
++                                 struct ncsi_channel *nc)
++{
++      struct ncsi_channel_vlan_filter *ncf;
++      struct ncsi_channel_mode *m;
++      struct nlattr *vid_nest;
++      int i;
++
++      nla_put_u32(skb, NCSI_CHANNEL_ATTR_ID, nc->id);
++      m = &nc->modes[NCSI_MODE_LINK];
++      nla_put_u32(skb, NCSI_CHANNEL_ATTR_LINK_STATE, m->data[2]);
++      if (nc->state == NCSI_CHANNEL_ACTIVE)
++              nla_put_flag(skb, NCSI_CHANNEL_ATTR_ACTIVE);
++      if (ndp->force_channel == nc)
++              nla_put_flag(skb, NCSI_CHANNEL_ATTR_FORCED);
++
++      nla_put_u32(skb, NCSI_CHANNEL_ATTR_VERSION_MAJOR, nc->version.version);
++      nla_put_u32(skb, NCSI_CHANNEL_ATTR_VERSION_MINOR, nc->version.alpha2);
++      nla_put_string(skb, NCSI_CHANNEL_ATTR_VERSION_STR, nc->version.fw_name);
++
++      vid_nest = nla_nest_start(skb, NCSI_CHANNEL_ATTR_VLAN_LIST);
++      if (!vid_nest)
++              return -ENOMEM;
++      ncf = &nc->vlan_filter;
++      i = -1;
++      while ((i = find_next_bit((void *)&ncf->bitmap, ncf->n_vids,
++                                i + 1)) < ncf->n_vids) {
++              if (ncf->vids[i])
++                      nla_put_u16(skb, NCSI_CHANNEL_ATTR_VLAN_ID,
++                                  ncf->vids[i]);
++      }
++      nla_nest_end(skb, vid_nest);
++
++      return 0;
++}
++
++static int ncsi_write_package_info(struct sk_buff *skb,
++                                 struct ncsi_dev_priv *ndp, unsigned int id)
++{
++      struct nlattr *pnest, *cnest, *nest;
++      struct ncsi_package *np;
++      struct ncsi_channel *nc;
++      bool found;
++      int rc;
++
++      if (id > ndp->package_num) {
++              netdev_info(ndp->ndev.dev, "NCSI: No package with id %u\n", id);
++              return -ENODEV;
++      }
++
++      found = false;
++      NCSI_FOR_EACH_PACKAGE(ndp, np) {
++              if (np->id != id)
++                      continue;
++              pnest = nla_nest_start(skb, NCSI_PKG_ATTR);
++              if (!pnest)
++                      return -ENOMEM;
++              nla_put_u32(skb, NCSI_PKG_ATTR_ID, np->id);
++              if (ndp->force_package == np)
++                      nla_put_flag(skb, NCSI_PKG_ATTR_FORCED);
++              cnest = nla_nest_start(skb, NCSI_PKG_ATTR_CHANNEL_LIST);
++              if (!cnest) {
++                      nla_nest_cancel(skb, pnest);
++                      return -ENOMEM;
++              }
++              NCSI_FOR_EACH_CHANNEL(np, nc) {
++                      nest = nla_nest_start(skb, NCSI_CHANNEL_ATTR);
++                      if (!nest) {
++                              nla_nest_cancel(skb, cnest);
++                              nla_nest_cancel(skb, pnest);
++                              return -ENOMEM;
++                      }
++                      rc = ncsi_write_channel_info(skb, ndp, nc);
++                      if (rc) {
++                              nla_nest_cancel(skb, nest);
++                              nla_nest_cancel(skb, cnest);
++                              nla_nest_cancel(skb, pnest);
++                              return rc;
++                      }
++                      nla_nest_end(skb, nest);
++              }
++              nla_nest_end(skb, cnest);
++              nla_nest_end(skb, pnest);
++              found = true;
++      }
++
++      if (!found)
++              return -ENODEV;
++
++      return 0;
++}
++
++static int ncsi_pkg_info_nl(struct sk_buff *msg, struct genl_info *info)
++{
++      struct ncsi_dev_priv *ndp;
++      unsigned int package_id;
++      struct sk_buff *skb;
++      struct nlattr *attr;
++      void *hdr;
++      int rc;
++
++      if (!info || !info->attrs)
++              return -EINVAL;
++
++      if (!info->attrs[NCSI_ATTR_IFINDEX])
++              return -EINVAL;
++
++      if (!info->attrs[NCSI_ATTR_PACKAGE_ID])
++              return -EINVAL;
++
++      ndp = ndp_from_ifindex(genl_info_net(info),
++                             nla_get_u32(info->attrs[NCSI_ATTR_IFINDEX]));
++      if (!ndp)
++              return -ENODEV;
++
++      skb = genlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
++      if (!skb)
++              return -ENOMEM;
++
++      hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
++                        &ncsi_genl_family, 0, NCSI_CMD_PKG_INFO);
++      if (!hdr) {
++              kfree(skb);
++              return -EMSGSIZE;
++      }
++
++      package_id = nla_get_u32(info->attrs[NCSI_ATTR_PACKAGE_ID]);
++
++      attr = nla_nest_start(skb, NCSI_ATTR_PACKAGE_LIST);
++      rc = ncsi_write_package_info(skb, ndp, package_id);
++
++      if (rc) {
++              nla_nest_cancel(skb, attr);
++              goto err;
++      }
++
++      nla_nest_end(skb, attr);
++
++      genlmsg_end(skb, hdr);
++      return genlmsg_reply(skb, info);
++
++err:
++      genlmsg_cancel(skb, hdr);
++      kfree(skb);
++      return rc;
++}
++
++static int ncsi_pkg_info_all_nl(struct sk_buff *skb,
++                              struct netlink_callback *cb)
++{
++      struct nlattr *attrs[NCSI_ATTR_MAX];
++      struct ncsi_package *np, *package;
++      struct ncsi_dev_priv *ndp;
++      unsigned int package_id;
++      struct nlattr *attr;
++      void *hdr;
++      int rc;
++
++      rc = genlmsg_parse(cb->nlh, &ncsi_genl_family, attrs, NCSI_ATTR_MAX,
++                         ncsi_genl_policy, NULL);
++      if (rc)
++              return rc;
++
++      if (!attrs[NCSI_ATTR_IFINDEX])
++              return -EINVAL;
++
++      ndp = ndp_from_ifindex(get_net(sock_net(skb->sk)),
++                             nla_get_u32(attrs[NCSI_ATTR_IFINDEX]));
++
++      if (!ndp)
++              return -ENODEV;
++
++      package_id = cb->args[0];
++      package = NULL;
++      NCSI_FOR_EACH_PACKAGE(ndp, np)
++              if (np->id == package_id)
++                      package = np;
++
++      if (!package)
++              return 0; /* done */
++
++      hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
++                        &ncsi_genl_family, 0,  NCSI_CMD_PKG_INFO);
++      if (!hdr) {
++              rc = -EMSGSIZE;
++              goto err;
++      }
++
++      attr = nla_nest_start(skb, NCSI_ATTR_PACKAGE_LIST);
++      rc = ncsi_write_package_info(skb, ndp, package->id);
++      if (rc) {
++              nla_nest_cancel(skb, attr);
++              goto err;
++      }
++
++      nla_nest_end(skb, attr);
++      genlmsg_end(skb, hdr);
++
++      cb->args[0] = package_id + 1;
++
++      return skb->len;
++err:
++      genlmsg_cancel(skb, hdr);
++      return rc;
++}
++
++static int ncsi_set_interface_nl(struct sk_buff *msg, struct genl_info *info)
++{
++      struct ncsi_package *np, *package;
++      struct ncsi_channel *nc, *channel;
++      u32 package_id, channel_id;
++      struct ncsi_dev_priv *ndp;
++      unsigned long flags;
++
++      if (!info || !info->attrs)
++              return -EINVAL;
++
++      if (!info->attrs[NCSI_ATTR_IFINDEX])
++              return -EINVAL;
++
++      if (!info->attrs[NCSI_ATTR_PACKAGE_ID])
++              return -EINVAL;
++
++      ndp = ndp_from_ifindex(get_net(sock_net(msg->sk)),
++                             nla_get_u32(info->attrs[NCSI_ATTR_IFINDEX]));
++      if (!ndp)
++              return -ENODEV;
++
++      package_id = nla_get_u32(info->attrs[NCSI_ATTR_PACKAGE_ID]);
++      package = NULL;
++
++      spin_lock_irqsave(&ndp->lock, flags);
++
++      NCSI_FOR_EACH_PACKAGE(ndp, np)
++              if (np->id == package_id)
++                      package = np;
++      if (!package) {
++              /* The user has set a package that does not exist */
++              return -ERANGE;
++      }
++
++      channel = NULL;
++      if (!info->attrs[NCSI_ATTR_CHANNEL_ID]) {
++              /* Allow any channel */
++              channel_id = NCSI_RESERVED_CHANNEL;
++      } else {
++              channel_id = nla_get_u32(info->attrs[NCSI_ATTR_CHANNEL_ID]);
++              NCSI_FOR_EACH_CHANNEL(package, nc)
++                      if (nc->id == channel_id)
++                              channel = nc;
++      }
++
++      if (channel_id != NCSI_RESERVED_CHANNEL && !channel) {
++              /* The user has set a channel that does not exist on this
++               * package
++               */
++              netdev_info(ndp->ndev.dev, "NCSI: Channel %u does not exist!\n",
++                          channel_id);
++              return -ERANGE;
++      }
++
++      ndp->force_package = package;
++      ndp->force_channel = channel;
++      spin_unlock_irqrestore(&ndp->lock, flags);
++
++      netdev_info(ndp->ndev.dev, "Set package 0x%x, channel 0x%x%s as 
preferred\n",
++                  package_id, channel_id,
++                  channel_id == NCSI_RESERVED_CHANNEL ? " (any)" : "");
++
++      /* Bounce the NCSI channel to set changes */
++      ncsi_stop_dev(&ndp->ndev);
++      ncsi_start_dev(&ndp->ndev);
++
++      return 0;
++}
++
++static int ncsi_clear_interface_nl(struct sk_buff *msg, struct genl_info 
*info)
++{
++      struct ncsi_dev_priv *ndp;
++      unsigned long flags;
++
++      if (!info || !info->attrs)
++              return -EINVAL;
++
++      if (!info->attrs[NCSI_ATTR_IFINDEX])
++              return -EINVAL;
++
++      ndp = ndp_from_ifindex(get_net(sock_net(msg->sk)),
++                             nla_get_u32(info->attrs[NCSI_ATTR_IFINDEX]));
++      if (!ndp)
++              return -ENODEV;
++
++      /* Clear any override */
++      spin_lock_irqsave(&ndp->lock, flags);
++      ndp->force_package = NULL;
++      ndp->force_channel = NULL;
++      spin_unlock_irqrestore(&ndp->lock, flags);
++      netdev_info(ndp->ndev.dev, "NCSI: Cleared preferred package/channel\n");
++
++      /* Bounce the NCSI channel to set changes */
++      ncsi_stop_dev(&ndp->ndev);
++      ncsi_start_dev(&ndp->ndev);
++
++      return 0;
++}
++
++static const struct genl_ops ncsi_ops[] = {
++      {
++              .cmd = NCSI_CMD_PKG_INFO,
++              .policy = ncsi_genl_policy,
++              .doit = ncsi_pkg_info_nl,
++              .dumpit = ncsi_pkg_info_all_nl,
++              .flags = 0,
++      },
++      {
++              .cmd = NCSI_CMD_SET_INTERFACE,
++              .policy = ncsi_genl_policy,
++              .doit = ncsi_set_interface_nl,
++              .flags = GENL_ADMIN_PERM,
++      },
++      {
++              .cmd = NCSI_CMD_CLEAR_INTERFACE,
++              .policy = ncsi_genl_policy,
++              .doit = ncsi_clear_interface_nl,
++              .flags = GENL_ADMIN_PERM,
++      },
++};
++
++static struct genl_family ncsi_genl_family __ro_after_init = {
++      .name = "NCSI",
++      .version = 0,
++      .maxattr = NCSI_ATTR_MAX,
++      .module = THIS_MODULE,
++      .ops = ncsi_ops,
++      .n_ops = ARRAY_SIZE(ncsi_ops),
++};
++
++int ncsi_init_netlink(struct net_device *dev)
++{
++      int rc;
++
++      rc = genl_register_family(&ncsi_genl_family);
++      if (rc)
++              netdev_err(dev, "ncsi: failed to register netlink family\n");
++
++      return rc;
++}
++
++int ncsi_unregister_netlink(struct net_device *dev)
++{
++      int rc;
++
++      rc = genl_unregister_family(&ncsi_genl_family);
++      if (rc)
++              netdev_err(dev, "ncsi: failed to unregister netlink family\n");
++
++      return rc;
++}
+diff --git a/net/ncsi/ncsi-netlink.h b/net/ncsi/ncsi-netlink.h
+new file mode 100644
+index 0000000000000..91a5c256f8c4f
+--- /dev/null
++++ b/net/ncsi/ncsi-netlink.h
+@@ -0,0 +1,20 @@
++/*
++ * Copyright Samuel Mendoza-Jonas, IBM Corporation 2018.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#ifndef __NCSI_NETLINK_H__
++#define __NCSI_NETLINK_H__
++
++#include <linux/netdevice.h>
++
++#include "internal.h"
++
++int ncsi_init_netlink(struct net_device *dev);
++int ncsi_unregister_netlink(struct net_device *dev);
++
++#endif /* __NCSI_NETLINK_H__ */
+diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
+index bbedcf48d71c2..42878d843c3c3 100644
+--- a/net/ncsi/ncsi-rsp.c
++++ b/net/ncsi/ncsi-rsp.c
+@@ -146,7 +146,7 @@ static int ncsi_rsp_handler_ec(struct ncsi_request *nr)
+ 
+       ncm = &nc->modes[NCSI_MODE_ENABLE];
+       if (ncm->enable)
+-              return -EBUSY;
++              return 0;
+ 
+       ncm->enable = 1;
+       return 0;
+@@ -173,7 +173,7 @@ static int ncsi_rsp_handler_dc(struct ncsi_request *nr)
+ 
+       ncm = &nc->modes[NCSI_MODE_ENABLE];
+       if (!ncm->enable)
+-              return -EBUSY;
++              return 0;
+ 
+       ncm->enable = 0;
+       return 0;
+@@ -217,7 +217,7 @@ static int ncsi_rsp_handler_ecnt(struct ncsi_request *nr)
+ 
+       ncm = &nc->modes[NCSI_MODE_TX_ENABLE];
+       if (ncm->enable)
+-              return -EBUSY;
++              return 0;
+ 
+       ncm->enable = 1;
+       return 0;
+@@ -239,7 +239,7 @@ static int ncsi_rsp_handler_dcnt(struct ncsi_request *nr)
+ 
+       ncm = &nc->modes[NCSI_MODE_TX_ENABLE];
+       if (!ncm->enable)
+-              return -EBUSY;
++              return 0;
+ 
+       ncm->enable = 1;
+       return 0;
+@@ -263,7 +263,7 @@ static int ncsi_rsp_handler_ae(struct ncsi_request *nr)
+       /* Check if the AEN has been enabled */
+       ncm = &nc->modes[NCSI_MODE_AEN];
+       if (ncm->enable)
+-              return -EBUSY;
++              return 0;
+ 
+       /* Update to AEN configuration */
+       cmd = (struct ncsi_cmd_ae_pkt *)skb_network_header(nr->cmd);
+@@ -334,9 +334,9 @@ static int ncsi_rsp_handler_svf(struct ncsi_request *nr)
+       struct ncsi_rsp_pkt *rsp;
+       struct ncsi_dev_priv *ndp = nr->ndp;
+       struct ncsi_channel *nc;
+-      struct ncsi_channel_filter *ncf;
+-      unsigned short vlan;
+-      int ret;
++      struct ncsi_channel_vlan_filter *ncf;
++      unsigned long flags;
++      void *bitmap;
+ 
+       /* Find the package and channel */
+       rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
+@@ -346,22 +346,23 @@ static int ncsi_rsp_handler_svf(struct ncsi_request *nr)
+               return -ENODEV;
+ 
+       cmd = (struct ncsi_cmd_svf_pkt *)skb_network_header(nr->cmd);
+-      ncf = nc->filters[NCSI_FILTER_VLAN];
+-      if (!ncf)
+-              return -ENOENT;
+-      if (cmd->index >= ncf->total)
++      ncf = &nc->vlan_filter;
++      if (cmd->index > ncf->n_vids)
+               return -ERANGE;
+ 
+-      /* Add or remove the VLAN filter */
++      /* Add or remove the VLAN filter. Remember HW indexes from 1 */
++      spin_lock_irqsave(&nc->lock, flags);
++      bitmap = &ncf->bitmap;
+       if (!(cmd->enable & 0x1)) {
+-              /* HW indexes from 1 */
+-              ret = ncsi_remove_filter(nc, NCSI_FILTER_VLAN, cmd->index - 1);
++              if (test_and_clear_bit(cmd->index - 1, bitmap))
++                      ncf->vids[cmd->index - 1] = 0;
+       } else {
+-              vlan = ntohs(cmd->vlan);
+-              ret = ncsi_add_filter(nc, NCSI_FILTER_VLAN, &vlan);
++              set_bit(cmd->index - 1, bitmap);
++              ncf->vids[cmd->index - 1] = ntohs(cmd->vlan);
+       }
++      spin_unlock_irqrestore(&nc->lock, flags);
+ 
+-      return ret;
++      return 0;
+ }
+ 
+ static int ncsi_rsp_handler_ev(struct ncsi_request *nr)
+@@ -382,7 +383,7 @@ static int ncsi_rsp_handler_ev(struct ncsi_request *nr)
+       /* Check if VLAN mode has been enabled */
+       ncm = &nc->modes[NCSI_MODE_VLAN];
+       if (ncm->enable)
+-              return -EBUSY;
++              return 0;
+ 
+       /* Update to VLAN mode */
+       cmd = (struct ncsi_cmd_ev_pkt *)skb_network_header(nr->cmd);
+@@ -409,7 +410,7 @@ static int ncsi_rsp_handler_dv(struct ncsi_request *nr)
+       /* Check if VLAN mode has been enabled */
+       ncm = &nc->modes[NCSI_MODE_VLAN];
+       if (!ncm->enable)
+-              return -EBUSY;
++              return 0;
+ 
+       /* Update to VLAN mode */
+       ncm->enable = 0;
+@@ -422,8 +423,12 @@ static int ncsi_rsp_handler_sma(struct ncsi_request *nr)
+       struct ncsi_rsp_pkt *rsp;
+       struct ncsi_dev_priv *ndp = nr->ndp;
+       struct ncsi_channel *nc;
+-      struct ncsi_channel_filter *ncf;
++      struct ncsi_channel_mac_filter *ncf;
++      unsigned long flags;
+       void *bitmap;
++      bool enabled;
++      int index;
++
+ 
+       /* Find the package and channel */
+       rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
+@@ -436,34 +441,23 @@ static int ncsi_rsp_handler_sma(struct ncsi_request *nr)
+        * isn't supported yet.
+        */
+       cmd = (struct ncsi_cmd_sma_pkt *)skb_network_header(nr->cmd);
+-      switch (cmd->at_e >> 5) {
+-      case 0x0:       /* UC address */
+-              ncf = nc->filters[NCSI_FILTER_UC];
+-              break;
+-      case 0x1:       /* MC address */
+-              ncf = nc->filters[NCSI_FILTER_MC];
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
++      enabled = cmd->at_e & 0x1;
++      ncf = &nc->mac_filter;
++      bitmap = &ncf->bitmap;
+ 
+-      /* Sanity check on the filter */
+-      if (!ncf)
+-              return -ENOENT;
+-      else if (cmd->index >= ncf->total)
++      if (cmd->index > ncf->n_uc + ncf->n_mc + ncf->n_mixed)
+               return -ERANGE;
+ 
+-      bitmap = &ncf->bitmap;
+-      if (cmd->at_e & 0x1) {
+-              if (test_and_set_bit(cmd->index, bitmap))
+-                      return -EBUSY;
+-              memcpy(ncf->data + 6 * cmd->index, cmd->mac, 6);
++      index = (cmd->index - 1) * ETH_ALEN;
++      spin_lock_irqsave(&nc->lock, flags);
++      if (enabled) {
++              set_bit(cmd->index - 1, bitmap);
++              memcpy(&ncf->addrs[index], cmd->mac, ETH_ALEN);
+       } else {
+-              if (!test_and_clear_bit(cmd->index, bitmap))
+-                      return -EBUSY;
+-
+-              memset(ncf->data + 6 * cmd->index, 0, 6);
++              clear_bit(cmd->index - 1, bitmap);
++              memset(&ncf->addrs[index], 0, ETH_ALEN);
+       }
++      spin_unlock_irqrestore(&nc->lock, flags);
+ 
+       return 0;
+ }
+@@ -485,7 +479,7 @@ static int ncsi_rsp_handler_ebf(struct ncsi_request *nr)
+       /* Check if broadcast filter has been enabled */
+       ncm = &nc->modes[NCSI_MODE_BC];
+       if (ncm->enable)
+-              return -EBUSY;
++              return 0;
+ 
+       /* Update to broadcast filter mode */
+       cmd = (struct ncsi_cmd_ebf_pkt *)skb_network_header(nr->cmd);
+@@ -511,7 +505,7 @@ static int ncsi_rsp_handler_dbf(struct ncsi_request *nr)
+       /* Check if broadcast filter isn't enabled */
+       ncm = &nc->modes[NCSI_MODE_BC];
+       if (!ncm->enable)
+-              return -EBUSY;
++              return 0;
+ 
+       /* Update to broadcast filter mode */
+       ncm->enable = 0;
+@@ -538,7 +532,7 @@ static int ncsi_rsp_handler_egmf(struct ncsi_request *nr)
+       /* Check if multicast filter has been enabled */
+       ncm = &nc->modes[NCSI_MODE_MC];
+       if (ncm->enable)
+-              return -EBUSY;
++              return 0;
+ 
+       /* Update to multicast filter mode */
+       cmd = (struct ncsi_cmd_egmf_pkt *)skb_network_header(nr->cmd);
+@@ -564,7 +558,7 @@ static int ncsi_rsp_handler_dgmf(struct ncsi_request *nr)
+       /* Check if multicast filter has been enabled */
+       ncm = &nc->modes[NCSI_MODE_MC];
+       if (!ncm->enable)
+-              return -EBUSY;
++              return 0;
+ 
+       /* Update to multicast filter mode */
+       ncm->enable = 0;
+@@ -591,7 +585,7 @@ static int ncsi_rsp_handler_snfc(struct ncsi_request *nr)
+       /* Check if flow control has been enabled */
+       ncm = &nc->modes[NCSI_MODE_FC];
+       if (ncm->enable)
+-              return -EBUSY;
++              return 0;
+ 
+       /* Update to flow control mode */
+       cmd = (struct ncsi_cmd_snfc_pkt *)skb_network_header(nr->cmd);
+@@ -634,9 +628,7 @@ static int ncsi_rsp_handler_gc(struct ncsi_request *nr)
+       struct ncsi_rsp_gc_pkt *rsp;
+       struct ncsi_dev_priv *ndp = nr->ndp;
+       struct ncsi_channel *nc;
+-      struct ncsi_channel_filter *ncf;
+-      size_t size, entry_size;
+-      int cnt, i;
++      size_t size;
+ 
+       /* Find the channel */
+       rsp = (struct ncsi_rsp_gc_pkt *)skb_network_header(nr->rsp);
+@@ -658,64 +650,40 @@ static int ncsi_rsp_handler_gc(struct ncsi_request *nr)
+       nc->caps[NCSI_CAP_VLAN].cap = rsp->vlan_mode &
+                                     NCSI_CAP_VLAN_MASK;
+ 
+-      /* Build filters */
+-      for (i = 0; i < NCSI_FILTER_MAX; i++) {
+-              switch (i) {
+-              case NCSI_FILTER_VLAN:
+-                      cnt = rsp->vlan_cnt;
+-                      entry_size = 2;
+-                      break;
+-              case NCSI_FILTER_MIXED:
+-                      cnt = rsp->mixed_cnt;
+-                      entry_size = 6;
+-                      break;
+-              case NCSI_FILTER_MC:
+-                      cnt = rsp->mc_cnt;
+-                      entry_size = 6;
+-                      break;
+-              case NCSI_FILTER_UC:
+-                      cnt = rsp->uc_cnt;
+-                      entry_size = 6;
+-                      break;
+-              default:
+-                      continue;
+-              }
+-
+-              if (!cnt || nc->filters[i])
+-                      continue;
+-
+-              size = sizeof(*ncf) + cnt * entry_size;
+-              ncf = kzalloc(size, GFP_ATOMIC);
+-              if (!ncf) {
+-                      pr_warn("%s: Cannot alloc filter table (%d)\n",
+-                              __func__, i);
+-                      return -ENOMEM;
+-              }
+-
+-              ncf->index = i;
+-              ncf->total = cnt;
+-              if (i == NCSI_FILTER_VLAN) {
+-                      /* Set VLAN filters active so they are cleared in
+-                       * first configuration state
+-                       */
+-                      ncf->bitmap = U64_MAX;
+-              } else {
+-                      ncf->bitmap = 0x0ul;
+-              }
+-              nc->filters[i] = ncf;
+-      }
++      size = (rsp->uc_cnt + rsp->mc_cnt + rsp->mixed_cnt) * ETH_ALEN;
++      nc->mac_filter.addrs = kzalloc(size, GFP_ATOMIC);
++      if (!nc->mac_filter.addrs)
++              return -ENOMEM;
++      nc->mac_filter.n_uc = rsp->uc_cnt;
++      nc->mac_filter.n_mc = rsp->mc_cnt;
++      nc->mac_filter.n_mixed = rsp->mixed_cnt;
++
++      nc->vlan_filter.vids = kcalloc(rsp->vlan_cnt,
++                                     sizeof(*nc->vlan_filter.vids),
++                                     GFP_ATOMIC);
++      if (!nc->vlan_filter.vids)
++              return -ENOMEM;
++      /* Set VLAN filters active so they are cleared in the first
++       * configuration state
++       */
++      nc->vlan_filter.bitmap = U64_MAX;
++      nc->vlan_filter.n_vids = rsp->vlan_cnt;
+ 
+       return 0;
+ }
+ 
+ static int ncsi_rsp_handler_gp(struct ncsi_request *nr)
+ {
+-      struct ncsi_rsp_gp_pkt *rsp;
++      struct ncsi_channel_vlan_filter *ncvf;
++      struct ncsi_channel_mac_filter *ncmf;
+       struct ncsi_dev_priv *ndp = nr->ndp;
++      struct ncsi_rsp_gp_pkt *rsp;
+       struct ncsi_channel *nc;
+-      unsigned short enable, vlan;
++      unsigned short enable;
+       unsigned char *pdata;
+-      int table, i;
++      unsigned long flags;
++      void *bitmap;
++      int i;
+ 
+       /* Find the channel */
+       rsp = (struct ncsi_rsp_gp_pkt *)skb_network_header(nr->rsp);
+@@ -749,36 +717,33 @@ static int ncsi_rsp_handler_gp(struct ncsi_request *nr)
+       /* MAC addresses filter table */
+       pdata = (unsigned char *)rsp + 48;
+       enable = rsp->mac_enable;
++      ncmf = &nc->mac_filter;
++      spin_lock_irqsave(&nc->lock, flags);
++      bitmap = &ncmf->bitmap;
+       for (i = 0; i < rsp->mac_cnt; i++, pdata += 6) {
+-              if (i >= (nc->filters[NCSI_FILTER_UC]->total +
+-                        nc->filters[NCSI_FILTER_MC]->total))
+-                      table = NCSI_FILTER_MIXED;
+-              else if (i >= nc->filters[NCSI_FILTER_UC]->total)
+-                      table = NCSI_FILTER_MC;
+-              else
+-                      table = NCSI_FILTER_UC;
+-
+               if (!(enable & (0x1 << i)))
+-                      continue;
+-
+-              if (ncsi_find_filter(nc, table, pdata) >= 0)
+-                      continue;
++                      clear_bit(i, bitmap);
++              else
++                      set_bit(i, bitmap);
+ 
+-              ncsi_add_filter(nc, table, pdata);
++              memcpy(&ncmf->addrs[i * ETH_ALEN], pdata, ETH_ALEN);
+       }
++      spin_unlock_irqrestore(&nc->lock, flags);
+ 
+       /* VLAN filter table */
+       enable = ntohs(rsp->vlan_enable);
++      ncvf = &nc->vlan_filter;
++      bitmap = &ncvf->bitmap;
++      spin_lock_irqsave(&nc->lock, flags);
+       for (i = 0; i < rsp->vlan_cnt; i++, pdata += 2) {
+               if (!(enable & (0x1 << i)))
+-                      continue;
+-
+-              vlan = ntohs(*(__be16 *)pdata);
+-              if (ncsi_find_filter(nc, NCSI_FILTER_VLAN, &vlan) >= 0)
+-                      continue;
++                      clear_bit(i, bitmap);
++              else
++                      set_bit(i, bitmap);
+ 
+-              ncsi_add_filter(nc, NCSI_FILTER_VLAN, &vlan);
++              ncvf->vids[i] = ntohs(*(__be16 *)pdata);
+       }
++      spin_unlock_irqrestore(&nc->lock, flags);
+ 
+       return 0;
+ }
+@@ -1032,11 +997,19 @@ int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device 
*dev,
+       if (payload < 0)
+               payload = ntohs(hdr->length);
+       ret = ncsi_validate_rsp_pkt(nr, payload);
+-      if (ret)
++      if (ret) {
++              netdev_warn(ndp->ndev.dev,
++                          "NCSI: 'bad' packet ignored for type 0x%x\n",
++                          hdr->type);
+               goto out;
++      }
+ 
+       /* Process the packet */
+       ret = nrh->handler(nr);
++      if (ret)
++              netdev_err(ndp->ndev.dev,
++                         "NCSI: Handler for packet type 0x%x returned %d\n",
++                         hdr->type, ret);
+ out:
+       ncsi_free_request(nr);
+       return ret;
+diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
+index 43a22968e8664..e1b1e6a0f8878 100644
+--- a/net/netfilter/x_tables.c
++++ b/net/netfilter/x_tables.c
+@@ -638,7 +638,7 @@ void xt_compat_match_from_user(struct xt_entry_match *m, 
void **dstptr,
+ {
+       const struct xt_match *match = m->u.kernel.match;
+       struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m;
+-      int pad, off = xt_compat_match_offset(match);
++      int off = xt_compat_match_offset(match);
+       u_int16_t msize = cm->u.user.match_size;
+       char name[sizeof(m->u.user.name)];
+ 
+@@ -648,9 +648,6 @@ void xt_compat_match_from_user(struct xt_entry_match *m, 
void **dstptr,
+               match->compat_from_user(m->data, cm->data);
+       else
+               memcpy(m->data, cm->data, msize - sizeof(*cm));
+-      pad = XT_ALIGN(match->matchsize) - match->matchsize;
+-      if (pad > 0)
+-              memset(m->data + match->matchsize, 0, pad);
+ 
+       msize += off;
+       m->u.user.match_size = msize;
+@@ -993,7 +990,7 @@ void xt_compat_target_from_user(struct xt_entry_target *t, 
void **dstptr,
+ {
+       const struct xt_target *target = t->u.kernel.target;
+       struct compat_xt_entry_target *ct = (struct compat_xt_entry_target *)t;
+-      int pad, off = xt_compat_target_offset(target);
++      int off = xt_compat_target_offset(target);
+       u_int16_t tsize = ct->u.user.target_size;
+       char name[sizeof(t->u.user.name)];
+ 
+@@ -1003,9 +1000,6 @@ void xt_compat_target_from_user(struct xt_entry_target 
*t, void **dstptr,
+               target->compat_from_user(t->data, ct->data);
+       else
+               memcpy(t->data, ct->data, tsize - sizeof(*ct));
+-      pad = XT_ALIGN(target->targetsize) - target->targetsize;
+-      if (pad > 0)
+-              memset(t->data + target->targetsize, 0, pad);
+ 
+       tsize += off;
+       t->u.user.target_size = tsize;
+diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
+index 694a43c05eb9b..0c2c88a2f0b05 100644
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -120,11 +120,13 @@ static int llcp_sock_bind(struct socket *sock, struct 
sockaddr *addr, int alen)
+                                         llcp_sock->service_name_len,
+                                         GFP_KERNEL);
+       if (!llcp_sock->service_name) {
++              nfc_llcp_local_put(llcp_sock->local);
+               ret = -ENOMEM;
+               goto put_dev;
+       }
+       llcp_sock->ssap = nfc_llcp_get_sdp_ssap(local, llcp_sock);
+       if (llcp_sock->ssap == LLCP_SAP_MAX) {
++              nfc_llcp_local_put(llcp_sock->local);
+               kfree(llcp_sock->service_name);
+               llcp_sock->service_name = NULL;
+               ret = -EADDRINUSE;
+@@ -684,6 +686,10 @@ static int llcp_sock_connect(struct socket *sock, struct 
sockaddr *_addr,
+               ret = -EISCONN;
+               goto error;
+       }
++      if (sk->sk_state == LLCP_CONNECTING) {
++              ret = -EINPROGRESS;
++              goto error;
++      }
+ 
+       dev = nfc_get_device(addr->dev_idx);
+       if (dev == NULL) {
+@@ -715,6 +721,7 @@ static int llcp_sock_connect(struct socket *sock, struct 
sockaddr *_addr,
+       llcp_sock->local = nfc_llcp_local_get(local);
+       llcp_sock->ssap = nfc_llcp_get_local_ssap(local);
+       if (llcp_sock->ssap == LLCP_SAP_MAX) {
++              nfc_llcp_local_put(llcp_sock->local);
+               ret = -ENOMEM;
+               goto put_dev;
+       }
+@@ -752,8 +759,11 @@ static int llcp_sock_connect(struct socket *sock, struct 
sockaddr *_addr,
+ 
+ sock_unlink:
+       nfc_llcp_put_ssap(local, llcp_sock->ssap);
++      nfc_llcp_local_put(llcp_sock->local);
+ 
+       nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
++      kfree(llcp_sock->service_name);
++      llcp_sock->service_name = NULL;
+ 
+ put_dev:
+       nfc_put_device(dev);
+diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
+index 9fe6b427afed0..5d8c095ec5eca 100644
+--- a/net/sched/sch_teql.c
++++ b/net/sched/sch_teql.c
+@@ -138,6 +138,9 @@ teql_destroy(struct Qdisc *sch)
+       struct teql_sched_data *dat = qdisc_priv(sch);
+       struct teql_master *master = dat->m;
+ 
++      if (!master)
++              return;
++
+       prev = master->slaves;
+       if (prev) {
+               do {
+diff --git a/net/tipc/socket.c b/net/tipc/socket.c
+index 44ede9ab78985..6fd5e1a7a336e 100644
+--- a/net/tipc/socket.c
++++ b/net/tipc/socket.c
+@@ -840,7 +840,7 @@ void tipc_sk_mcast_rcv(struct net *net, struct 
sk_buff_head *arrvq,
+               spin_lock_bh(&inputq->lock);
+               if (skb_peek(arrvq) == skb) {
+                       skb_queue_splice_tail_init(&tmpq, inputq);
+-                      kfree_skb(__skb_dequeue(arrvq));
++                      __skb_dequeue(arrvq);
+               }
+               spin_unlock_bh(&inputq->lock);
+               __skb_queue_purge(&tmpq);
+diff --git a/net/wireless/sme.c b/net/wireless/sme.c
+index 8344153800e27..c9158360154a4 100644
+--- a/net/wireless/sme.c
++++ b/net/wireless/sme.c
+@@ -530,7 +530,7 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev,
+               cfg80211_sme_free(wdev);
+       }
+ 
+-      if (WARN_ON(wdev->conn))
++      if (wdev->conn)
+               return -EINPROGRESS;
+ 
+       wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL);
+diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
+index dfd30a80ece8e..8a32a276bd705 100644
+--- a/sound/drivers/aloop.c
++++ b/sound/drivers/aloop.c
+@@ -1062,6 +1062,14 @@ static int loopback_mixer_new(struct loopback 
*loopback, int notify)
+                                       return -ENOMEM;
+                               kctl->id.device = dev;
+                               kctl->id.subdevice = substr;
++
++                              /* Add the control before copying the id so that
++                               * the numid field of the id is set in the copy.
++                               */
++                              err = snd_ctl_add(card, kctl);
++                              if (err < 0)
++                                      return err;
++
+                               switch (idx) {
+                               case ACTIVE_IDX:
+                                       setup->active_id = kctl->id;
+@@ -1078,9 +1086,6 @@ static int loopback_mixer_new(struct loopback *loopback, 
int notify)
+                               default:
+                                       break;
+                               }
+-                              err = snd_ctl_add(card, kctl);
+-                              if (err < 0)
+-                                      return err;
+                       }
+               }
+       }
+diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
+index 9ed4557009542..228ab7bd314d6 100644
+--- a/sound/soc/codecs/wm8960.c
++++ b/sound/soc/codecs/wm8960.c
+@@ -710,7 +710,13 @@ int wm8960_configure_pll(struct snd_soc_codec *codec, int 
freq_in,
+       best_freq_out = -EINVAL;
+       *sysclk_idx = *dac_idx = *bclk_idx = -1;
+ 
+-      for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) {
++      /*
++       * From Datasheet, the PLL performs best when f2 is between
++       * 90MHz and 100MHz, the desired sysclk output is 11.2896MHz
++       * or 12.288MHz, then sysclkdiv = 2 is the best choice.
++       * So search sysclk_divs from 2 to 1 other than from 1 to 2.
++       */
++      for (i = ARRAY_SIZE(sysclk_divs) - 1; i >= 0; --i) {
+               if (sysclk_divs[i] == -1)
+                       continue;
+               for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
+diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c 
b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+index 3a645fc425cd4..cdc0f22a57ee3 100644
+--- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c
++++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+@@ -508,14 +508,14 @@ static struct snd_soc_dai_driver sst_platform_dai[] = {
+               .channels_min = SST_STEREO,
+               .channels_max = SST_STEREO,
+               .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
+-              .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
++              .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       },
+       .capture = {
+               .stream_name = "Headset Capture",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
+-              .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
++              .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       },
+ },
+ {
+@@ -526,7 +526,7 @@ static struct snd_soc_dai_driver sst_platform_dai[] = {
+               .channels_min = SST_STEREO,
+               .channels_max = SST_STEREO,
+               .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
+-              .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
++              .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       },
+ },
+ {
+diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
+index baa9007464ed7..700779ca82d01 100644
+--- a/sound/soc/sunxi/sun4i-codec.c
++++ b/sound/soc/sunxi/sun4i-codec.c
+@@ -1199,6 +1199,7 @@ static struct snd_soc_card 
*sun4i_codec_create_card(struct device *dev)
+               return ERR_PTR(-ENOMEM);
+ 
+       card->dev               = dev;
++      card->owner             = THIS_MODULE;
+       card->name              = "sun4i-codec";
+       card->dapm_widgets      = sun4i_codec_card_dapm_widgets;
+       card->num_dapm_widgets  = ARRAY_SIZE(sun4i_codec_card_dapm_widgets);
+@@ -1231,6 +1232,7 @@ static struct snd_soc_card 
*sun6i_codec_create_card(struct device *dev)
+               return ERR_PTR(-ENOMEM);
+ 
+       card->dev               = dev;
++      card->owner             = THIS_MODULE;
+       card->name              = "A31 Audio Codec";
+       card->dapm_widgets      = sun6i_codec_card_dapm_widgets;
+       card->num_dapm_widgets  = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
+@@ -1284,6 +1286,7 @@ static struct snd_soc_card 
*sun8i_a23_codec_create_card(struct device *dev)
+               return ERR_PTR(-ENOMEM);
+ 
+       card->dev               = dev;
++      card->owner             = THIS_MODULE;
+       card->name              = "A23 Audio Codec";
+       card->dapm_widgets      = sun6i_codec_card_dapm_widgets;
+       card->num_dapm_widgets  = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
+@@ -1322,6 +1325,7 @@ static struct snd_soc_card 
*sun8i_h3_codec_create_card(struct device *dev)
+               return ERR_PTR(-ENOMEM);
+ 
+       card->dev               = dev;
++      card->owner             = THIS_MODULE;
+       card->name              = "H3 Audio Codec";
+       card->dapm_widgets      = sun6i_codec_card_dapm_widgets;
+       card->num_dapm_widgets  = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
+@@ -1360,6 +1364,7 @@ static struct snd_soc_card 
*sun8i_v3s_codec_create_card(struct device *dev)
+               return ERR_PTR(-ENOMEM);
+ 
+       card->dev               = dev;
++      card->owner             = THIS_MODULE;
+       card->name              = "V3s Audio Codec";
+       card->dapm_widgets      = sun6i_codec_card_dapm_widgets;
+       card->num_dapm_widgets  = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
+diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
+index a49f27aa0c95a..9d42a2821ecb9 100644
+--- a/tools/perf/util/map.c
++++ b/tools/perf/util/map.c
+@@ -93,8 +93,7 @@ static inline bool replace_android_lib(const char *filename, 
char *newfilename)
+       if (!strncmp(filename, "/system/lib/", 12)) {
+               char *ndk, *app;
+               const char *arch;
+-              size_t ndk_length;
+-              size_t app_length;
++              int ndk_length, app_length;
+ 
+               ndk = getenv("NDK_ROOT");
+               app = getenv("APP_PLATFORM");
+@@ -122,8 +121,8 @@ static inline bool replace_android_lib(const char 
*filename, char *newfilename)
+               if (new_length > PATH_MAX)
+                       return false;
+               snprintf(newfilename, new_length,
+-                      "%s/platforms/%s/arch-%s/usr/lib/%s",
+-                      ndk, app, arch, libname);
++                      "%.*s/platforms/%.*s/arch-%s/usr/lib/%s",
++                      ndk_length, ndk, app_length, app, arch, libname);
+ 
+               return true;
+       }

Reply via email to