commit:     14f12480ad6b16cf57a809d5a3da6987b3cbe8ed
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Nov 10 15:13:38 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Nov 10 15:13:38 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=14f12480

Linux patch 4.9.333

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README              |   4 +
 1332_linux-4.9.333.patch | 786 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 790 insertions(+)

diff --git a/0000_README b/0000_README
index d1f8d301..0d65a523 100644
--- a/0000_README
+++ b/0000_README
@@ -1375,6 +1375,10 @@ Patch:  1331_linux-4.9.332.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.9.332
 
+Patch:  1332_linux-4.9.333.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.9.333
+
 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/1332_linux-4.9.333.patch b/1332_linux-4.9.333.patch
new file mode 100644
index 00000000..0087565c
--- /dev/null
+++ b/1332_linux-4.9.333.patch
@@ -0,0 +1,786 @@
+diff --git a/Makefile b/Makefile
+index c5d6b0b2bbb78..f5da71aa3608b 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 9
+-SUBLEVEL = 332
++SUBLEVEL = 333
+ EXTRAVERSION =
+ NAME = Roaring Lionus
+ 
+diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
+index c068027ac55f2..bc3fb0b0e9fdc 100644
+--- a/arch/x86/kvm/cpuid.c
++++ b/arch/x86/kvm/cpuid.c
+@@ -647,6 +647,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 
*entry, u32 function,
+                       g_phys_as = phys_as;
+ 
+               entry->eax = g_phys_as | (virt_as << 8);
++              entry->ecx &= ~(GENMASK(31, 16) | GENMASK(11, 8));
+               entry->edx = 0;
+               /*
+                * IBRS, IBPB and VIRT_SSBD aren't necessarily present in
+diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
+index 16e24085fc8b1..f658a5ad3b4d0 100644
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -750,8 +750,7 @@ static int linearize(struct x86_emulate_ctxt *ctxt,
+                          ctxt->mode, linear);
+ }
+ 
+-static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst,
+-                           enum x86emul_mode mode)
++static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst)
+ {
+       ulong linear;
+       int rc;
+@@ -761,41 +760,71 @@ static inline int assign_eip(struct x86_emulate_ctxt 
*ctxt, ulong dst,
+ 
+       if (ctxt->op_bytes != sizeof(unsigned long))
+               addr.ea = dst & ((1UL << (ctxt->op_bytes << 3)) - 1);
+-      rc = __linearize(ctxt, addr, &max_size, 1, false, true, mode, &linear);
++      rc = __linearize(ctxt, addr, &max_size, 1, false, true, ctxt->mode, 
&linear);
+       if (rc == X86EMUL_CONTINUE)
+               ctxt->_eip = addr.ea;
+       return rc;
+ }
+ 
++static inline int emulator_recalc_and_set_mode(struct x86_emulate_ctxt *ctxt)
++{
++      u64 efer;
++      struct desc_struct cs;
++      u16 selector;
++      u32 base3;
++
++      ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
++
++      if (!(ctxt->ops->get_cr(ctxt, 0) & X86_CR0_PE)) {
++              /* Real mode. cpu must not have long mode active */
++              if (efer & EFER_LMA)
++                      return X86EMUL_UNHANDLEABLE;
++              ctxt->mode = X86EMUL_MODE_REAL;
++              return X86EMUL_CONTINUE;
++      }
++
++      if (ctxt->eflags & X86_EFLAGS_VM) {
++              /* Protected/VM86 mode. cpu must not have long mode active */
++              if (efer & EFER_LMA)
++                      return X86EMUL_UNHANDLEABLE;
++              ctxt->mode = X86EMUL_MODE_VM86;
++              return X86EMUL_CONTINUE;
++      }
++
++      if (!ctxt->ops->get_segment(ctxt, &selector, &cs, &base3, VCPU_SREG_CS))
++              return X86EMUL_UNHANDLEABLE;
++
++      if (efer & EFER_LMA) {
++              if (cs.l) {
++                      /* Proper long mode */
++                      ctxt->mode = X86EMUL_MODE_PROT64;
++              } else if (cs.d) {
++                      /* 32 bit compatibility mode*/
++                      ctxt->mode = X86EMUL_MODE_PROT32;
++              } else {
++                      ctxt->mode = X86EMUL_MODE_PROT16;
++              }
++      } else {
++              /* Legacy 32 bit / 16 bit mode */
++              ctxt->mode = cs.d ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
++      }
++
++      return X86EMUL_CONTINUE;
++}
++
+ static inline int assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst)
+ {
+-      return assign_eip(ctxt, dst, ctxt->mode);
++      return assign_eip(ctxt, dst);
+ }
+ 
+-static int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst,
+-                        const struct desc_struct *cs_desc)
++static int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst)
+ {
+-      enum x86emul_mode mode = ctxt->mode;
+-      int rc;
++      int rc = emulator_recalc_and_set_mode(ctxt);
+ 
+-#ifdef CONFIG_X86_64
+-      if (ctxt->mode >= X86EMUL_MODE_PROT16) {
+-              if (cs_desc->l) {
+-                      u64 efer = 0;
++      if (rc != X86EMUL_CONTINUE)
++              return rc;
+ 
+-                      ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
+-                      if (efer & EFER_LMA)
+-                              mode = X86EMUL_MODE_PROT64;
+-              } else
+-                      mode = X86EMUL_MODE_PROT32; /* temporary value */
+-      }
+-#endif
+-      if (mode == X86EMUL_MODE_PROT16 || mode == X86EMUL_MODE_PROT32)
+-              mode = cs_desc->d ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
+-      rc = assign_eip(ctxt, dst, mode);
+-      if (rc == X86EMUL_CONTINUE)
+-              ctxt->mode = mode;
+-      return rc;
++      return assign_eip(ctxt, dst);
+ }
+ 
+ static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
+@@ -2197,7 +2226,7 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
+       if (rc != X86EMUL_CONTINUE)
+               return rc;
+ 
+-      rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc);
++      rc = assign_eip_far(ctxt, ctxt->src.val);
+       /* Error handling is not implemented. */
+       if (rc != X86EMUL_CONTINUE)
+               return X86EMUL_UNHANDLEABLE;
+@@ -2278,7 +2307,7 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
+                                      &new_desc);
+       if (rc != X86EMUL_CONTINUE)
+               return rc;
+-      rc = assign_eip_far(ctxt, eip, &new_desc);
++      rc = assign_eip_far(ctxt, eip);
+       /* Error handling is not implemented. */
+       if (rc != X86EMUL_CONTINUE)
+               return X86EMUL_UNHANDLEABLE;
+@@ -2881,6 +2910,7 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt)
+       ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS);
+ 
+       ctxt->_eip = rdx;
++      ctxt->mode = usermode;
+       *reg_write(ctxt, VCPU_REGS_RSP) = rcx;
+ 
+       return X86EMUL_CONTINUE;
+@@ -3466,7 +3496,7 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt)
+       if (rc != X86EMUL_CONTINUE)
+               return rc;
+ 
+-      rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc);
++      rc = assign_eip_far(ctxt, ctxt->src.val);
+       if (rc != X86EMUL_CONTINUE)
+               goto fail;
+ 
+@@ -3613,11 +3643,25 @@ static int em_movbe(struct x86_emulate_ctxt *ctxt)
+ 
+ static int em_cr_write(struct x86_emulate_ctxt *ctxt)
+ {
+-      if (ctxt->ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val))
++      int cr_num = ctxt->modrm_reg;
++      int r;
++
++      if (ctxt->ops->set_cr(ctxt, cr_num, ctxt->src.val))
+               return emulate_gp(ctxt, 0);
+ 
+       /* Disable writeback. */
+       ctxt->dst.type = OP_NONE;
++
++      if (cr_num == 0) {
++              /*
++               * CR0 write might have updated CR0.PE and/or CR0.PG
++               * which can affect the cpu's execution mode.
++               */
++              r = emulator_recalc_and_set_mode(ctxt);
++              if (r != X86EMUL_CONTINUE)
++                      return r;
++      }
++
+       return X86EMUL_CONTINUE;
+ }
+ 
+diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
+index 55fcdb798002b..e4071768333df 100644
+--- a/drivers/ata/pata_legacy.c
++++ b/drivers/ata/pata_legacy.c
+@@ -292,9 +292,10 @@ static void pdc20230_set_piomode(struct ata_port *ap, 
struct ata_device *adev)
+       outb(inb(0x1F4) & 0x07, 0x1F4);
+ 
+       rt = inb(0x1F3);
+-      rt &= 0x07 << (3 * adev->devno);
++      rt &= ~(0x07 << (3 * !adev->devno));
+       if (pio)
+-              rt |= (1 + 3 * pio) << (3 * adev->devno);
++              rt |= (1 + 3 * pio) << (3 * !adev->devno);
++      outb(rt, 0x1F3);
+ 
+       udelay(100);
+       outb(inb(0x1F2) | 0x01, 0x1F2);
+diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
+index c65a5d0af555b..4b750c99819ac 100644
+--- a/drivers/i2c/busses/i2c-xiic.c
++++ b/drivers/i2c/busses/i2c-xiic.c
+@@ -897,6 +897,7 @@ static struct platform_driver xiic_i2c_driver = {
+ 
+ module_platform_driver(xiic_i2c_driver);
+ 
++MODULE_ALIAS("platform:" DRIVER_NAME);
+ MODULE_AUTHOR("[email protected]");
+ MODULE_DESCRIPTION("Xilinx I2C bus driver");
+ MODULE_LICENSE("GPL v2");
+diff --git a/drivers/isdn/hardware/mISDN/netjet.c 
b/drivers/isdn/hardware/mISDN/netjet.c
+index feada9d7cbcc2..a549a18e46194 100644
+--- a/drivers/isdn/hardware/mISDN/netjet.c
++++ b/drivers/isdn/hardware/mISDN/netjet.c
+@@ -970,7 +970,7 @@ nj_release(struct tiger_hw *card)
+       }
+       if (card->irq > 0)
+               free_irq(card->irq, card);
+-      if (card->isac.dch.dev.dev.class)
++      if (device_is_registered(&card->isac.dch.dev.dev))
+               mISDN_unregister_device(&card->isac.dch.dev);
+ 
+       for (i = 0; i < 2; i++) {
+diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c
+index f5a06a6fb297f..5cd53b2c47c75 100644
+--- a/drivers/isdn/mISDN/core.c
++++ b/drivers/isdn/mISDN/core.c
+@@ -242,11 +242,12 @@ mISDN_register_device(struct mISDNdevice *dev,
+       if (debug & DEBUG_CORE)
+               printk(KERN_DEBUG "mISDN_register %s %d\n",
+                      dev_name(&dev->dev), dev->id);
++      dev->dev.class = &mISDN_class;
++
+       err = create_stack(dev);
+       if (err)
+               goto error1;
+ 
+-      dev->dev.class = &mISDN_class;
+       dev->dev.platform_data = dev;
+       dev->dev.parent = parent;
+       dev_set_drvdata(&dev->dev, dev);
+@@ -258,8 +259,8 @@ mISDN_register_device(struct mISDNdevice *dev,
+ 
+ error3:
+       delete_stack(dev);
+-      return err;
+ error1:
++      put_device(&dev->dev);
+       return err;
+ 
+ }
+diff --git a/drivers/media/dvb-frontends/drxk_hard.c 
b/drivers/media/dvb-frontends/drxk_hard.c
+index c595adc61c6f4..f6cf1b0b992c5 100644
+--- a/drivers/media/dvb-frontends/drxk_hard.c
++++ b/drivers/media/dvb-frontends/drxk_hard.c
+@@ -6697,7 +6697,7 @@ static int drxk_read_snr(struct dvb_frontend *fe, u16 
*snr)
+ static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+ {
+       struct drxk_state *state = fe->demodulator_priv;
+-      u16 err;
++      u16 err = 0;
+ 
+       dprintk(1, "\n");
+ 
+diff --git a/drivers/net/ethernet/freescale/fec_main.c 
b/drivers/net/ethernet/freescale/fec_main.c
+index c06ac5f66a17c..98a665538dbe9 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -577,7 +577,7 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, 
struct sk_buff *skb,
+               dev_kfree_skb_any(skb);
+               if (net_ratelimit())
+                       netdev_err(ndev, "Tx DMA memory map failed\n");
+-              return NETDEV_TX_BUSY;
++              return NETDEV_TX_OK;
+       }
+ 
+       bdp->cbd_datlen = cpu_to_fec16(size);
+@@ -639,7 +639,7 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
+                       dev_kfree_skb_any(skb);
+                       if (net_ratelimit())
+                               netdev_err(ndev, "Tx DMA memory map failed\n");
+-                      return NETDEV_TX_BUSY;
++                      return NETDEV_TX_OK;
+               }
+       }
+ 
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
+index 0fa6e2da4b5a2..2aecc5ee91330 100644
+--- a/drivers/net/phy/mdio_bus.c
++++ b/drivers/net/phy/mdio_bus.c
+@@ -335,7 +335,7 @@ int __mdiobus_register(struct mii_bus *bus, struct module 
*owner)
+               bus->reset(bus);
+ 
+       for (i = 0; i < PHY_MAX_ADDR; i++) {
+-              if ((bus->phy_mask & (1 << i)) == 0) {
++              if ((bus->phy_mask & BIT(i)) == 0) {
+                       struct phy_device *phydev;
+ 
+                       phydev = mdiobus_scan(bus, i);
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
+index 6afcf86b9ba29..4b24122908321 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
+@@ -237,6 +237,10 @@ static void brcmf_fweh_event_worker(struct work_struct 
*work)
+                         brcmf_fweh_event_name(event->code), event->code,
+                         event->emsg.ifidx, event->emsg.bsscfgidx,
+                         event->emsg.addr);
++              if (event->emsg.bsscfgidx >= BRCMF_MAX_IFS) {
++                      brcmf_err("invalid bsscfg index: %u\n", 
event->emsg.bsscfgidx);
++                      goto event_free;
++              }
+ 
+               /* convert event message */
+               emsg_be = &event->emsg;
+diff --git a/drivers/nfc/nfcmrvl/i2c.c b/drivers/nfc/nfcmrvl/i2c.c
+index bb546cabe8090..91d7ef11aba34 100644
+--- a/drivers/nfc/nfcmrvl/i2c.c
++++ b/drivers/nfc/nfcmrvl/i2c.c
+@@ -151,10 +151,15 @@ static int nfcmrvl_i2c_nci_send(struct nfcmrvl_private 
*priv,
+                       ret = -EREMOTEIO;
+               } else
+                       ret = 0;
++      }
++
++      if (ret) {
+               kfree_skb(skb);
++              return ret;
+       }
+ 
+-      return ret;
++      consume_skb(skb);
++      return 0;
+ }
+ 
+ static void nfcmrvl_i2c_nci_update_config(struct nfcmrvl_private *priv,
+diff --git a/drivers/nfc/s3fwrn5/core.c b/drivers/nfc/s3fwrn5/core.c
+index 64b58455e620b..f23a1e4d7e1e7 100644
+--- a/drivers/nfc/s3fwrn5/core.c
++++ b/drivers/nfc/s3fwrn5/core.c
+@@ -108,11 +108,15 @@ static int s3fwrn5_nci_send(struct nci_dev *ndev, struct 
sk_buff *skb)
+       }
+ 
+       ret = s3fwrn5_write(info, skb);
+-      if (ret < 0)
++      if (ret < 0) {
+               kfree_skb(skb);
++              mutex_unlock(&info->mutex);
++              return ret;
++      }
+ 
++      consume_skb(skb);
+       mutex_unlock(&info->mutex);
+-      return ret;
++      return 0;
+ }
+ 
+ static int s3fwrn5_nci_post_setup(struct nci_dev *ndev)
+diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
+index 144c77dfe4b19..eb9137faccf74 100644
+--- a/drivers/parisc/iosapic.c
++++ b/drivers/parisc/iosapic.c
+@@ -889,6 +889,7 @@ int iosapic_serial_irq(struct parisc_device *dev)
+ 
+       return vi->txn_irq;
+ }
++EXPORT_SYMBOL(iosapic_serial_irq);
+ #endif
+ 
+ 
+diff --git a/drivers/staging/media/s5p-cec/s5p_cec.c 
b/drivers/staging/media/s5p-cec/s5p_cec.c
+index bebd44d9bd51a..f6d1d98431a77 100644
+--- a/drivers/staging/media/s5p-cec/s5p_cec.c
++++ b/drivers/staging/media/s5p-cec/s5p_cec.c
+@@ -112,6 +112,8 @@ static irqreturn_t s5p_cec_irq_handler(int irq, void *priv)
+                               dev_dbg(cec->dev, "Buffer overrun (worker did 
not process previous message)\n");
+                       cec->rx = STATE_BUSY;
+                       cec->msg.len = status >> 24;
++                      if (cec->msg.len > CEC_MAX_MSG_SIZE)
++                              cec->msg.len = CEC_MAX_MSG_SIZE;
+                       cec->msg.rx_status = CEC_RX_STATUS_OK;
+                       s5p_cec_get_rx_buf(cec, cec->msg.len,
+                                       cec->msg.msg);
+diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
+index 899834776b360..3487b762dd143 100644
+--- a/drivers/tty/serial/8250/Kconfig
++++ b/drivers/tty/serial/8250/Kconfig
+@@ -105,7 +105,7 @@ config SERIAL_8250_CONSOLE
+ 
+ config SERIAL_8250_GSC
+       tristate
+-      depends on SERIAL_8250 && GSC
++      depends on SERIAL_8250 && PARISC
+       default SERIAL_8250
+ 
+ config SERIAL_8250_DMA
+diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
+index 92f80ed642194..a18b3d193689a 100644
+--- a/fs/btrfs/export.c
++++ b/fs/btrfs/export.c
+@@ -56,7 +56,7 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int 
*max_len,
+ }
+ 
+ struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
+-                              u64 root_objectid, u32 generation,
++                              u64 root_objectid, u64 generation,
+                               int check_generation)
+ {
+       struct btrfs_fs_info *fs_info = btrfs_sb(sb);
+diff --git a/fs/btrfs/export.h b/fs/btrfs/export.h
+index 7a305e5549991..c7950e0a2f95a 100644
+--- a/fs/btrfs/export.h
++++ b/fs/btrfs/export.h
+@@ -17,7 +17,7 @@ struct btrfs_fid {
+ } __attribute__ ((packed));
+ 
+ struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
+-                              u64 root_objectid, u32 generation,
++                              u64 root_objectid, u64 generation,
+                               int check_generation);
+ struct dentry *btrfs_get_parent(struct dentry *child);
+ 
+diff --git a/fs/btrfs/tests/qgroup-tests.c b/fs/btrfs/tests/qgroup-tests.c
+index e0aa6b9786fa4..ef9ff6dda1739 100644
+--- a/fs/btrfs/tests/qgroup-tests.c
++++ b/fs/btrfs/tests/qgroup-tests.c
+@@ -249,8 +249,10 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
+ 
+       ret = insert_normal_tree_ref(root, nodesize, nodesize, 0,
+                               BTRFS_FS_TREE_OBJECTID);
+-      if (ret)
++      if (ret) {
++              ulist_free(old_roots);
+               return ret;
++      }
+ 
+       ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots);
+       if (ret) {
+@@ -283,8 +285,10 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
+       }
+ 
+       ret = remove_extent_item(root, nodesize, nodesize);
+-      if (ret)
++      if (ret) {
++              ulist_free(old_roots);
+               return -EINVAL;
++      }
+ 
+       ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots);
+       if (ret) {
+@@ -346,8 +350,10 @@ static int test_multiple_refs(struct btrfs_root *root,
+ 
+       ret = insert_normal_tree_ref(root, nodesize, nodesize, 0,
+                               BTRFS_FS_TREE_OBJECTID);
+-      if (ret)
++      if (ret) {
++              ulist_free(old_roots);
+               return ret;
++      }
+ 
+       ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots);
+       if (ret) {
+@@ -379,8 +385,10 @@ static int test_multiple_refs(struct btrfs_root *root,
+ 
+       ret = add_tree_ref(root, nodesize, nodesize, 0,
+                       BTRFS_FIRST_FREE_OBJECTID);
+-      if (ret)
++      if (ret) {
++              ulist_free(old_roots);
+               return ret;
++      }
+ 
+       ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots);
+       if (ret) {
+@@ -418,8 +426,10 @@ static int test_multiple_refs(struct btrfs_root *root,
+ 
+       ret = remove_extent_ref(root, nodesize, nodesize, 0,
+                               BTRFS_FIRST_FREE_OBJECTID);
+-      if (ret)
++      if (ret) {
++              ulist_free(old_roots);
+               return ret;
++      }
+ 
+       ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots);
+       if (ret) {
+diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
+index 6967ab3306e7d..fd603352adc81 100644
+--- a/fs/ext4/migrate.c
++++ b/fs/ext4/migrate.c
+@@ -450,7 +450,8 @@ int ext4_ext_migrate(struct inode *inode)
+        * already is extent-based, error out.
+        */
+       if (!ext4_has_feature_extents(inode->i_sb) ||
+-          (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
++          ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) ||
++          ext4_has_inline_data(inode))
+               return -EINVAL;
+ 
+       if (S_ISLNK(inode->i_mode) && inode->i_blocks == 0)
+diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
+index 48baa92846e5f..7c28a90c03406 100644
+--- a/fs/nfs/nfs4client.c
++++ b/fs/nfs/nfs4client.c
+@@ -326,6 +326,7 @@ int nfs40_init_client(struct nfs_client *clp)
+       ret = nfs4_setup_slot_table(tbl, NFS4_MAX_SLOT_TABLE,
+                                       "NFSv4.0 transport Slot table");
+       if (ret) {
++              nfs4_shutdown_slot_table(tbl);
+               kfree(tbl);
+               return ret;
+       }
+diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
+index 466c07bd06295..dcb2c8b4a14d9 100644
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -1656,6 +1656,7 @@ static void nfs4_state_mark_reclaim_helper(struct 
nfs_client *clp,
+ 
+ static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp)
+ {
++      set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state);
+       /* Mark all delegations for reclaim */
+       nfs_delegation_mark_reclaim(clp);
+       nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_reboot);
+@@ -2487,6 +2488,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
+                       if (status < 0)
+                               goto out_error;
+                       nfs4_state_end_reclaim_reboot(clp);
++                      continue;
+               }
+ 
+               /* Detect expired delegations... */
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index ec04a7ea55377..6933449840359 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -3541,7 +3541,8 @@ done:
+                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+                                          sizeof(rfc), (unsigned long) &rfc, 
endptr - ptr);
+ 
+-                      if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
++                      if (remote_efs &&
++                          test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
+                               chan->remote_id = efs.id;
+                               chan->remote_stype = efs.stype;
+                               chan->remote_msdu = le16_to_cpu(efs.msdu);
+@@ -6247,6 +6248,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan,
+                              struct l2cap_ctrl *control,
+                              struct sk_buff *skb, u8 event)
+ {
++      struct l2cap_ctrl local_control;
+       int err = 0;
+       bool skb_in_use = false;
+ 
+@@ -6271,15 +6273,32 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan,
+                       chan->buffer_seq = chan->expected_tx_seq;
+                       skb_in_use = true;
+ 
++                      /* l2cap_reassemble_sdu may free skb, hence invalidate
++                       * control, so make a copy in advance to use it after
++                       * l2cap_reassemble_sdu returns and to avoid the race
++                       * condition, for example:
++                       *
++                       * The current thread calls:
++                       *   l2cap_reassemble_sdu
++                       *     chan->ops->recv == l2cap_sock_recv_cb
++                       *       __sock_queue_rcv_skb
++                       * Another thread calls:
++                       *   bt_sock_recvmsg
++                       *     skb_recv_datagram
++                       *     skb_free_datagram
++                       * Then the current thread tries to access control, but
++                       * it was freed by skb_free_datagram.
++                       */
++                      local_control = *control;
+                       err = l2cap_reassemble_sdu(chan, skb, control);
+                       if (err)
+                               break;
+ 
+-                      if (control->final) {
++                      if (local_control.final) {
+                               if (!test_and_clear_bit(CONN_REJ_ACT,
+                                                       &chan->conn_state)) {
+-                                      control->final = 0;
+-                                      l2cap_retransmit_all(chan, control);
++                                      local_control.final = 0;
++                                      l2cap_retransmit_all(chan, 
&local_control);
+                                       l2cap_ertm_send(chan);
+                               }
+                       }
+@@ -6659,11 +6678,27 @@ static int l2cap_rx(struct l2cap_chan *chan, struct 
l2cap_ctrl *control,
+ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl 
*control,
+                          struct sk_buff *skb)
+ {
++      /* l2cap_reassemble_sdu may free skb, hence invalidate control, so store
++       * the txseq field in advance to use it after l2cap_reassemble_sdu
++       * returns and to avoid the race condition, for example:
++       *
++       * The current thread calls:
++       *   l2cap_reassemble_sdu
++       *     chan->ops->recv == l2cap_sock_recv_cb
++       *       __sock_queue_rcv_skb
++       * Another thread calls:
++       *   bt_sock_recvmsg
++       *     skb_recv_datagram
++       *     skb_free_datagram
++       * Then the current thread tries to access control, but it was freed by
++       * skb_free_datagram.
++       */
++      u16 txseq = control->txseq;
++
+       BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
+              chan->rx_state);
+ 
+-      if (l2cap_classify_txseq(chan, control->txseq) ==
+-          L2CAP_TXSEQ_EXPECTED) {
++      if (l2cap_classify_txseq(chan, txseq) == L2CAP_TXSEQ_EXPECTED) {
+               l2cap_pass_to_tx(chan, control);
+ 
+               BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
+@@ -6686,8 +6721,8 @@ static int l2cap_stream_rx(struct l2cap_chan *chan, 
struct l2cap_ctrl *control,
+               }
+       }
+ 
+-      chan->last_acked_seq = control->txseq;
+-      chan->expected_tx_seq = __next_seq(chan, control->txseq);
++      chan->last_acked_seq = txseq;
++      chan->expected_tx_seq = __next_seq(chan, txseq);
+ 
+       return 0;
+ }
+@@ -6925,6 +6960,7 @@ static void l2cap_data_channel(struct l2cap_conn *conn, 
u16 cid,
+                               return;
+                       }
+ 
++                      l2cap_chan_hold(chan);
+                       l2cap_chan_lock(chan);
+               } else {
+                       BT_DBG("unknown cid 0x%4.4x", cid);
+diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
+index ecde2102d1adf..c84290d7cc392 100644
+--- a/net/netfilter/ipvs/ip_vs_conn.c
++++ b/net/netfilter/ipvs/ip_vs_conn.c
+@@ -1240,8 +1240,8 @@ static inline int todrop_entry(struct ip_vs_conn *cp)
+        * The drop rate array needs tuning for real environments.
+        * Called from timer bh only => no locking
+        */
+-      static const char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
+-      static char todrop_counter[9] = {0};
++      static const signed char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
++      static signed char todrop_counter[9] = {0};
+       int i;
+ 
+       /* if the conn entry hasn't lasted for 60 seconds, don't drop it.
+diff --git a/net/rose/rose_link.c b/net/rose/rose_link.c
+index c76638cc2cd53..4e02634e4a660 100644
+--- a/net/rose/rose_link.c
++++ b/net/rose/rose_link.c
+@@ -241,6 +241,9 @@ void rose_transmit_clear_request(struct rose_neigh *neigh, 
unsigned int lci, uns
+       unsigned char *dptr;
+       int len;
+ 
++      if (!neigh->dev)
++              return;
++
+       len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN + 3;
+ 
+       if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
+diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
+index d6abf5c5a5b82..27142950827a6 100644
+--- a/net/sched/sch_red.c
++++ b/net/sched/sch_red.c
+@@ -61,6 +61,7 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc 
*sch,
+ {
+       struct red_sched_data *q = qdisc_priv(sch);
+       struct Qdisc *child = q->qdisc;
++      unsigned int len;
+       int ret;
+ 
+       q->vars.qavg = red_calc_qavg(&q->parms,
+@@ -96,9 +97,10 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc 
*sch,
+               break;
+       }
+ 
++      len = qdisc_pkt_len(skb);
+       ret = qdisc_enqueue(skb, child, to_free);
+       if (likely(ret == NET_XMIT_SUCCESS)) {
+-              qdisc_qstats_backlog_inc(sch, skb);
++              sch->qstats.backlog += len;
+               sch->q.qlen++;
+       } else if (net_xmit_drop_count(ret)) {
+               q->stats.pdrop++;
+diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
+index 1904fc542025d..2cd789ddc2ab8 100644
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -3333,6 +3333,64 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
+       }
+ },
+ 
++/*
++ * MacroSilicon MS2100/MS2106 based AV capture cards
++ *
++ * These claim 96kHz 1ch in the descriptors, but are actually 48kHz 2ch.
++ * They also need QUIRK_AUDIO_ALIGN_TRANSFER, which makes one wonder if
++ * they pretend to be 96kHz mono as a workaround for stereo being broken
++ * by that...
++ *
++ * They also have an issue with initial stream alignment that causes the
++ * channels to be swapped and out of phase, which is dealt with in quirks.c.
++ */
++{
++      .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
++                     USB_DEVICE_ID_MATCH_INT_CLASS |
++                     USB_DEVICE_ID_MATCH_INT_SUBCLASS,
++      .idVendor = 0x534d,
++      .idProduct = 0x0021,
++      .bInterfaceClass = USB_CLASS_AUDIO,
++      .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
++      .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
++              .vendor_name = "MacroSilicon",
++              .product_name = "MS210x",
++              .ifnum = QUIRK_ANY_INTERFACE,
++              .type = QUIRK_COMPOSITE,
++              .data = &(const struct snd_usb_audio_quirk[]) {
++                      {
++                              .ifnum = 2,
++                              .type = QUIRK_AUDIO_ALIGN_TRANSFER,
++                      },
++                      {
++                              .ifnum = 2,
++                              .type = QUIRK_AUDIO_STANDARD_MIXER,
++                      },
++                      {
++                              .ifnum = 3,
++                              .type = QUIRK_AUDIO_FIXED_ENDPOINT,
++                              .data = &(const struct audioformat) {
++                                      .formats = SNDRV_PCM_FMTBIT_S16_LE,
++                                      .channels = 2,
++                                      .iface = 3,
++                                      .altsetting = 1,
++                                      .altset_idx = 1,
++                                      .attributes = 0,
++                                      .endpoint = 0x82,
++                                      .ep_attr = USB_ENDPOINT_XFER_ISOC |
++                                              USB_ENDPOINT_SYNC_ASYNC,
++                                      .rates = SNDRV_PCM_RATE_CONTINUOUS,
++                                      .rate_min = 48000,
++                                      .rate_max = 48000,
++                              }
++                      },
++                      {
++                              .ifnum = -1
++                      }
++              }
++      }
++},
++
+ /*
+  * MacroSilicon MS2109 based HDMI capture cards
+  *
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 02b4d0638e008..df7cb07f7cad6 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1129,6 +1129,7 @@ void snd_usb_set_format_quirk(struct snd_usb_substream 
*subs,
+       case USB_ID(0x041e, 0x3f19): /* E-Mu 0204 USB */
+               set_format_emu_quirk(subs, fmt);
+               break;
++      case USB_ID(0x534d, 0x0021): /* MacroSilicon MS2100/MS2106 */
+       case USB_ID(0x534d, 0x2109): /* MacroSilicon MS2109 */
+               subs->stream_offset_adj = 2;
+               break;

Reply via email to