commit:     eb7f5355d16dd286a80799b2b09edcf34b287852
Author:     Arisu Tachibana <alicef <AT> gentoo <DOT> org>
AuthorDate: Tue Feb 17 00:34:18 2026 +0000
Commit:     Arisu Tachibana <alicef <AT> gentoo <DOT> org>
CommitDate: Tue Feb 17 00:34:18 2026 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=eb7f5355

Linux patch 6.6.125

Signed-off-by: Arisu Tachibana <alicef <AT> gentoo.org>

 0000_README              |    4 +
 1124_linux-6.6.125.patch | 1213 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1217 insertions(+)

diff --git a/0000_README b/0000_README
index 652f2ae8..f56653ca 100644
--- a/0000_README
+++ b/0000_README
@@ -539,6 +539,10 @@ Patch:  1123_linux-6.6.124.patch
 From:   https://www.kernel.org
 Desc:   Linux 6.6.124
 
+Patch:  1124_linux-6.6.125.patch
+From:   https://www.kernel.org
+Desc:   Linux 6.6.125
+
 Patch:  1510_fs-enable-link-security-restrictions-by-default.patch
 From:   
http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch
 Desc:   Enable link security restrictions by default.

diff --git a/1124_linux-6.6.125.patch b/1124_linux-6.6.125.patch
new file mode 100644
index 00000000..7e128894
--- /dev/null
+++ b/1124_linux-6.6.125.patch
@@ -0,0 +1,1213 @@
+diff --git a/Makefile b/Makefile
+index 4ec8ec24a35414..4a944e80769044 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 6
+-SUBLEVEL = 124
++SUBLEVEL = 125
+ EXTRAVERSION =
+ NAME = Pinguïn Aangedreven
+ 
+diff --git a/drivers/base/base.h b/drivers/base/base.h
+index 0b491449b022a1..35e14bebbfb2c2 100644
+--- a/drivers/base/base.h
++++ b/drivers/base/base.h
+@@ -165,9 +165,18 @@ void device_set_deferred_probe_reason(const struct device 
*dev, struct va_format
+ static inline int driver_match_device(struct device_driver *drv,
+                                     struct device *dev)
+ {
++      device_lock_assert(dev);
++
+       return drv->bus->match ? drv->bus->match(dev, drv) : 1;
+ }
+ 
++static inline int driver_match_device_locked(struct device_driver *drv,
++                                           struct device *dev)
++{
++      guard(device)(dev);
++      return driver_match_device(drv, dev);
++}
++
+ static inline void dev_sync_state(struct device *dev)
+ {
+       if (dev->bus->sync_state)
+diff --git a/drivers/base/bus.c b/drivers/base/bus.c
+index b97e13a52c3308..27f8442a3aa9dd 100644
+--- a/drivers/base/bus.c
++++ b/drivers/base/bus.c
+@@ -263,7 +263,7 @@ static ssize_t bind_store(struct device_driver *drv, const 
char *buf,
+       int err = -ENODEV;
+ 
+       dev = bus_find_device_by_name(bus, NULL, buf);
+-      if (dev && driver_match_device(drv, dev)) {
++      if (dev && driver_match_device_locked(drv, dev)) {
+               err = device_driver_attach(drv, dev);
+               if (!err) {
+                       /* success */
+diff --git a/drivers/base/dd.c b/drivers/base/dd.c
+index 7e2fb159bb895b..07f1332dd3a440 100644
+--- a/drivers/base/dd.c
++++ b/drivers/base/dd.c
+@@ -1169,7 +1169,7 @@ static int __driver_attach(struct device *dev, void 
*data)
+        * is an error.
+        */
+ 
+-      ret = driver_match_device(drv, dev);
++      ret = driver_match_device_locked(drv, dev);
+       if (ret == 0) {
+               /* no match */
+               return 0;
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 1309e9318bdb55..eaeacdadb20232 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -516,6 +516,8 @@ static const struct usb_device_id quirks_table[] = {
+                                                    BTUSB_WIDEBAND_SPEECH },
+       { USB_DEVICE(0x2001, 0x332a), .driver_info = BTUSB_REALTEK |
+                                                    BTUSB_WIDEBAND_SPEECH },
++      { USB_DEVICE(0x7392, 0xe611), .driver_info = BTUSB_REALTEK |
++                                                   BTUSB_WIDEBAND_SPEECH },
+ 
+       /* Realtek 8852AE Bluetooth devices */
+       { USB_DEVICE(0x0bda, 0x2852), .driver_info = BTUSB_REALTEK |
+diff --git a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c 
b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
+index c4250e5fcf8f7b..11dfbd4beba9cd 100644
+--- a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
++++ b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
+@@ -1336,7 +1336,7 @@ static ssize_t ucode_load_store(struct device *dev,
+       int del_grp_idx = -1;
+       int ucode_idx = 0;
+ 
+-      if (strlen(buf) > OTX_CPT_UCODE_NAME_LENGTH)
++      if (count >= OTX_CPT_UCODE_NAME_LENGTH)
+               return -EINVAL;
+ 
+       eng_grps = container_of(attr, struct otx_cpt_eng_grps, ucode_load_attr);
+diff --git a/drivers/crypto/omap-crypto.c b/drivers/crypto/omap-crypto.c
+index a4cc6bf146ec09..0345c9383d5097 100644
+--- a/drivers/crypto/omap-crypto.c
++++ b/drivers/crypto/omap-crypto.c
+@@ -21,7 +21,7 @@ static int omap_crypto_copy_sg_lists(int total, int bs,
+       struct scatterlist *tmp;
+ 
+       if (!(flags & OMAP_CRYPTO_FORCE_SINGLE_ENTRY)) {
+-              new_sg = kmalloc_array(n, sizeof(*sg), GFP_KERNEL);
++              new_sg = kmalloc_array(n, sizeof(*new_sg), GFP_KERNEL);
+               if (!new_sg)
+                       return -ENOMEM;
+ 
+diff --git a/drivers/crypto/virtio/virtio_crypto_core.c 
b/drivers/crypto/virtio/virtio_crypto_core.c
+index b909c6a2bf1c34..6ec9a95b4db073 100644
+--- a/drivers/crypto/virtio/virtio_crypto_core.c
++++ b/drivers/crypto/virtio/virtio_crypto_core.c
+@@ -77,15 +77,20 @@ static void virtcrypto_done_task(unsigned long data)
+       struct data_queue *data_vq = (struct data_queue *)data;
+       struct virtqueue *vq = data_vq->vq;
+       struct virtio_crypto_request *vc_req;
++      unsigned long flags;
+       unsigned int len;
+ 
++      spin_lock_irqsave(&data_vq->lock, flags);
+       do {
+               virtqueue_disable_cb(vq);
+               while ((vc_req = virtqueue_get_buf(vq, &len)) != NULL) {
++                      spin_unlock_irqrestore(&data_vq->lock, flags);
+                       if (vc_req->alg_cb)
+                               vc_req->alg_cb(vc_req, len);
++                      spin_lock_irqsave(&data_vq->lock, flags);
+               }
+       } while (!virtqueue_enable_cb(vq));
++      spin_unlock_irqrestore(&data_vq->lock, flags);
+ }
+ 
+ static void virtcrypto_dataq_callback(struct virtqueue *vq)
+diff --git a/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c 
b/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c
+index 23c41d87d835ff..487f60e35df193 100644
+--- a/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c
++++ b/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c
+@@ -550,8 +550,6 @@ int virtio_crypto_skcipher_crypt_req(
+       if (ret < 0)
+               return ret;
+ 
+-      virtqueue_kick(data_vq->vq);
+-
+       return 0;
+ }
+ 
+diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
+index a927680c66f88d..772fddc02b8181 100644
+--- a/drivers/gpio/gpio-omap.c
++++ b/drivers/gpio/gpio-omap.c
+@@ -799,10 +799,13 @@ static struct platform_device omap_mpuio_device = {
+ 
+ static inline void omap_mpuio_init(struct gpio_bank *bank)
+ {
+-      platform_set_drvdata(&omap_mpuio_device, bank);
++      static bool registered;
+ 
+-      if (platform_driver_register(&omap_mpuio_driver) == 0)
+-              (void) platform_device_register(&omap_mpuio_device);
++      platform_set_drvdata(&omap_mpuio_device, bank);
++      if (!registered) {
++              (void)platform_device_register(&omap_mpuio_device);
++              registered = true;
++      }
+ }
+ 
+ /*---------------------------------------------------------------------*/
+@@ -1575,13 +1578,24 @@ static struct platform_driver omap_gpio_driver = {
+  */
+ static int __init omap_gpio_drv_reg(void)
+ {
+-      return platform_driver_register(&omap_gpio_driver);
++      int ret;
++
++      ret = platform_driver_register(&omap_mpuio_driver);
++      if (ret)
++              return ret;
++
++      ret = platform_driver_register(&omap_gpio_driver);
++      if (ret)
++              platform_driver_unregister(&omap_mpuio_driver);
++
++      return ret;
+ }
+ postcore_initcall(omap_gpio_drv_reg);
+ 
+ static void __exit omap_gpio_exit(void)
+ {
+       platform_driver_unregister(&omap_gpio_driver);
++      platform_driver_unregister(&omap_mpuio_driver);
+ }
+ module_exit(omap_gpio_exit);
+ 
+diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
+index dc62f141f40382..ff438be4c186e1 100644
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -431,6 +431,8 @@ static void sfp_quirk_ubnt_uf_instant(const struct 
sfp_eeprom_id *id,
+        */
+       linkmode_zero(modes);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, modes);
++      phy_interface_zero(interfaces);
++      __set_bit(PHY_INTERFACE_MODE_1000BASEX, interfaces);
+ }
+ 
+ #define SFP_QUIRK(_v, _p, _m, _f) \
+diff --git a/drivers/net/wireless/realtek/rtw88/main.c 
b/drivers/net/wireless/realtek/rtw88/main.c
+index 0d0b5123b5fe28..c7396ae9256b9b 100644
+--- a/drivers/net/wireless/realtek/rtw88/main.c
++++ b/drivers/net/wireless/realtek/rtw88/main.c
+@@ -2401,10 +2401,10 @@ void rtw_core_enable_beacon(struct rtw_dev *rtwdev, 
bool enable)
+ 
+       if (enable) {
+               rtw_write32_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
+-              rtw_write32_clr(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE);
++              rtw_write8_clr(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE);
+       } else {
+               rtw_write32_clr(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
+-              rtw_write32_set(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE);
++              rtw_write8_set(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE);
+       }
+ }
+ 
+diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
+index d2bddca7045aa1..4cef9a34934380 100644
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -3356,9 +3356,6 @@ login_logout:
+                           atomic_read(&fcport->state) == FCS_ONLINE) ||
+                               do_delete) {
+                               if (fcport->loop_id != FC_NO_LOOP_ID) {
+-                                      if (fcport->flags & FCF_FCP2_DEVICE)
+-                                              continue;
+-
+                                       ql_log(ql_log_warn, vha, 0x20f0,
+                                              "%s %d %8phC post del sess\n",
+                                              __func__, __LINE__,
+@@ -3625,8 +3622,8 @@ int qla_fab_async_scan(scsi_qla_host_t *vha, srb_t *sp)
+       if (vha->scan.scan_flags & SF_SCANNING) {
+               spin_unlock_irqrestore(&vha->work_lock, flags);
+               ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2012,
+-                  "%s: scan active\n", __func__);
+-              return rval;
++                  "%s: scan active for sp:%p\n", __func__, sp);
++              goto done_free_sp;
+       }
+       vha->scan.scan_flags |= SF_SCANNING;
+       if (!sp)
+@@ -3791,23 +3788,25 @@ int qla_fab_async_scan(scsi_qla_host_t *vha, srb_t *sp)
+       return rval;
+ 
+ done_free_sp:
+-      if (sp->u.iocb_cmd.u.ctarg.req) {
+-              dma_free_coherent(&vha->hw->pdev->dev,
+-                  sp->u.iocb_cmd.u.ctarg.req_allocated_size,
+-                  sp->u.iocb_cmd.u.ctarg.req,
+-                  sp->u.iocb_cmd.u.ctarg.req_dma);
+-              sp->u.iocb_cmd.u.ctarg.req = NULL;
+-      }
+-      if (sp->u.iocb_cmd.u.ctarg.rsp) {
+-              dma_free_coherent(&vha->hw->pdev->dev,
+-                  sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
+-                  sp->u.iocb_cmd.u.ctarg.rsp,
+-                  sp->u.iocb_cmd.u.ctarg.rsp_dma);
+-              sp->u.iocb_cmd.u.ctarg.rsp = NULL;
+-      }
++      if (sp) {
++              if (sp->u.iocb_cmd.u.ctarg.req) {
++                      dma_free_coherent(&vha->hw->pdev->dev,
++                          sp->u.iocb_cmd.u.ctarg.req_allocated_size,
++                          sp->u.iocb_cmd.u.ctarg.req,
++                          sp->u.iocb_cmd.u.ctarg.req_dma);
++                      sp->u.iocb_cmd.u.ctarg.req = NULL;
++              }
++              if (sp->u.iocb_cmd.u.ctarg.rsp) {
++                      dma_free_coherent(&vha->hw->pdev->dev,
++                          sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
++                          sp->u.iocb_cmd.u.ctarg.rsp,
++                          sp->u.iocb_cmd.u.ctarg.rsp_dma);
++                      sp->u.iocb_cmd.u.ctarg.rsp = NULL;
++              }
+ 
+-      /* ref: INIT */
+-      kref_put(&sp->cmd_kref, qla2x00_sp_release);
++              /* ref: INIT */
++              kref_put(&sp->cmd_kref, qla2x00_sp_release);
++      }
+ 
+       spin_lock_irqsave(&vha->work_lock, flags);
+       vha->scan.scan_flags &= ~SF_SCANNING;
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index e881d704b45d1b..b736575e2d9fc8 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -1859,15 +1859,6 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct 
event_arg *ea)
+       case RSCN_PORT_ADDR:
+               fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1);
+               if (fcport) {
+-                      if (ql2xfc2target &&
+-                          fcport->flags & FCF_FCP2_DEVICE &&
+-                          atomic_read(&fcport->state) == FCS_ONLINE) {
+-                              ql_dbg(ql_dbg_disc, vha, 0x2115,
+-                                     "Delaying session delete for FCP2 
portid=%06x %8phC ",
+-                                      fcport->d_id.b24, fcport->port_name);
+-                              return;
+-                      }
+-
+                       if (vha->hw->flags.edif_enabled && DBELL_ACTIVE(vha)) {
+                               /*
+                                * On ipsec start by remote port, Target port
+@@ -2471,8 +2462,23 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host 
*vha, struct event_arg *ea)
+           ea->sp->gen1, fcport->rscn_gen,
+           ea->data[0], ea->data[1], ea->iop[0], ea->iop[1]);
+ 
+-      if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
+-          (fcport->fw_login_state == DSC_LS_PRLI_PEND)) {
++      if (fcport->fw_login_state == DSC_LS_PLOGI_PEND) {
++              ql_dbg(ql_dbg_disc, vha, 0x20ea,
++                  "%s %d %8phC Remote is trying to login\n",
++                  __func__, __LINE__, fcport->port_name);
++              /*
++               * If we get here, there is port thats already logged in,
++               * but it's state has not moved ahead. Recheck with FW on
++               * what state it is in and proceed ahead
++               */
++              if (!N2N_TOPO(vha->hw)) {
++                      fcport->fw_login_state = DSC_LS_PRLI_COMP;
++                      qla24xx_post_gpdb_work(vha, fcport, 0);
++              }
++              return;
++      }
++
++      if (fcport->fw_login_state == DSC_LS_PRLI_PEND) {
+               ql_dbg(ql_dbg_disc, vha, 0x20ea,
+                   "%s %d %8phC Remote is trying to login\n",
+                   __func__, __LINE__, fcport->port_name);
+diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
+index ae2bea27a18a67..38214f8e30fa6d 100644
+--- a/drivers/scsi/qla2xxx/qla_isr.c
++++ b/drivers/scsi/qla2xxx/qla_isr.c
+@@ -1676,13 +1676,28 @@ skip_rio:
+ 
+                       /* Port logout */
+                       fcport = qla2x00_find_fcport_by_loopid(vha, mb[1]);
+-                      if (!fcport)
++                      if (!fcport) {
++                              ql_dbg(ql_dbg_async, vha, 0x5011,
++                                      "Could not find fcport:%04x %04x 
%04x\n",
++                                      mb[1], mb[2], mb[3]);
+                               break;
+-                      if (atomic_read(&fcport->state) != FCS_ONLINE)
++                      }
++
++                      if (atomic_read(&fcport->state) != FCS_ONLINE) {
++                              ql_dbg(ql_dbg_async, vha, 0x5012,
++                                      "Port state is not online State:0x%x 
\n",
++                                      atomic_read(&fcport->state));
++                              ql_dbg(ql_dbg_async, vha, 0x5012,
++                                      "Scheduling session for deletion \n");
++                              fcport->logout_on_delete = 0;
++                              qlt_schedule_sess_for_deletion(fcport);
+                               break;
++                      }
++
+                       ql_dbg(ql_dbg_async, vha, 0x508a,
+                           "Marking port lost loopid=%04x portid=%06x.\n",
+                           fcport->loop_id, fcport->d_id.b24);
++
+                       if (qla_ini_mode_enabled(vha)) {
+                               fcport->logout_on_delete = 0;
+                               qlt_schedule_sess_for_deletion(fcport);
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index d10389ee92ba4b..b08abdf5ebf4e7 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -1194,7 +1194,8 @@ qla2x00_wait_for_hba_ready(scsi_qla_host_t *vha)
+       while ((qla2x00_reset_active(vha) || ha->dpc_active ||
+               ha->flags.mbox_busy) ||
+              test_bit(FX00_RESET_RECOVERY, &vha->dpc_flags) ||
+-             test_bit(FX00_TARGET_SCAN, &vha->dpc_flags)) {
++             test_bit(FX00_TARGET_SCAN, &vha->dpc_flags) ||
++             (vha->scan.scan_flags & SF_SCANNING)) {
+               if (test_bit(UNLOADING, &base_vha->dpc_flags))
+                       break;
+               msleep(1000);
+diff --git a/drivers/spi/spi-cadence-quadspi.c 
b/drivers/spi/spi-cadence-quadspi.c
+index eed88aba2cfe92..3e7bf76be22bb7 100644
+--- a/drivers/spi/spi-cadence-quadspi.c
++++ b/drivers/spi/spi-cadence-quadspi.c
+@@ -100,6 +100,8 @@ struct cqspi_st {
+       bool                    apb_ahb_hazard;
+ 
+       bool                    is_jh7110; /* Flag for StarFive JH7110 SoC */
++      refcount_t              refcount;
++      refcount_t              inflight_ops;
+ };
+ 
+ struct cqspi_driver_platdata {
+@@ -705,6 +707,9 @@ static int cqspi_indirect_read_execute(struct 
cqspi_flash_pdata *f_pdata,
+       u8 *rxbuf_end = rxbuf + n_rx;
+       int ret = 0;
+ 
++      if (!refcount_read(&cqspi->refcount))
++              return -ENODEV;
++
+       writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR);
+       writel(remaining, reg_base + CQSPI_REG_INDIRECTRDBYTES);
+ 
+@@ -1021,6 +1026,9 @@ static int cqspi_indirect_write_execute(struct 
cqspi_flash_pdata *f_pdata,
+       unsigned int write_bytes;
+       int ret;
+ 
++      if (!refcount_read(&cqspi->refcount))
++              return -ENODEV;
++
+       writel(to_addr, reg_base + CQSPI_REG_INDIRECTWRSTARTADDR);
+       writel(remaining, reg_base + CQSPI_REG_INDIRECTWRBYTES);
+ 
+@@ -1412,11 +1420,29 @@ static int cqspi_mem_process(struct spi_mem *mem, 
const struct spi_mem_op *op)
+ static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
+ {
+       int ret;
++      struct cqspi_st *cqspi = 
spi_controller_get_devdata(mem->spi->controller);
++
++      if (refcount_read(&cqspi->inflight_ops) == 0)
++              return -ENODEV;
++
++      if (!refcount_read(&cqspi->refcount))
++              return -EBUSY;
++
++      refcount_inc(&cqspi->inflight_ops);
++
++      if (!refcount_read(&cqspi->refcount)) {
++              if (refcount_read(&cqspi->inflight_ops))
++                      refcount_dec(&cqspi->inflight_ops);
++              return -EBUSY;
++      }
+ 
+       ret = cqspi_mem_process(mem, op);
+       if (ret)
+               dev_err(&mem->spi->dev, "operation failed with %d\n", ret);
+ 
++      if (refcount_read(&cqspi->inflight_ops) > 1)
++              refcount_dec(&cqspi->inflight_ops);
++
+       return ret;
+ }
+ 
+@@ -1847,6 +1873,9 @@ static int cqspi_probe(struct platform_device *pdev)
+               }
+       }
+ 
++      refcount_set(&cqspi->refcount, 1);
++      refcount_set(&cqspi->inflight_ops, 1);
++
+       ret = devm_request_irq(dev, irq, cqspi_irq_handler, 0,
+                              pdev->name, cqspi);
+       if (ret) {
+@@ -1899,6 +1928,11 @@ static void cqspi_remove(struct platform_device *pdev)
+ {
+       struct cqspi_st *cqspi = platform_get_drvdata(pdev);
+ 
++      refcount_set(&cqspi->refcount, 0);
++
++      if (!refcount_dec_and_test(&cqspi->inflight_ops))
++              cqspi_wait_idle(cqspi);
++
+       spi_unregister_controller(cqspi->host);
+       cqspi_controller_enable(cqspi, 0);
+ 
+diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
+index 78ebdf20c1efa3..4703e2a935684b 100644
+--- a/fs/nfsd/nfsctl.c
++++ b/fs/nfsd/nfsctl.c
+@@ -1526,17 +1526,24 @@ static __net_init int nfsd_net_init(struct net *net)
+       retval = nfsd_stat_counters_init(nn);
+       if (retval)
+               goto out_repcache_error;
++
+       memset(&nn->nfsd_svcstats, 0, sizeof(nn->nfsd_svcstats));
+       nn->nfsd_svcstats.program = &nfsd_program;
++      if (!nfsd_proc_stat_init(net)) {
++              retval = -ENOMEM;
++              goto out_proc_error;
++      }
++
+       nn->nfsd_versions = NULL;
+       nn->nfsd4_minorversions = NULL;
+       nfsd4_init_leases_net(nn);
+       get_random_bytes(&nn->siphash_key, sizeof(nn->siphash_key));
+       seqlock_init(&nn->writeverf_lock);
+-      nfsd_proc_stat_init(net);
+ 
+       return 0;
+ 
++out_proc_error:
++      nfsd_stat_counters_destroy(nn);
+ out_repcache_error:
+       nfsd_idmap_shutdown(net);
+ out_idmap_error:
+diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c
+index 9f606fa08bd4b8..0a629a18831f19 100644
+--- a/fs/nfsd/stats.c
++++ b/fs/nfsd/stats.c
+@@ -115,11 +115,11 @@ void nfsd_stat_counters_destroy(struct nfsd_net *nn)
+       nfsd_percpu_counters_destroy(nn->counter, NFSD_STATS_COUNTERS_NUM);
+ }
+ 
+-void nfsd_proc_stat_init(struct net *net)
++struct proc_dir_entry *nfsd_proc_stat_init(struct net *net)
+ {
+       struct nfsd_net *nn = net_generic(net, nfsd_net_id);
+ 
+-      svc_proc_register(net, &nn->nfsd_svcstats, &nfsd_proc_ops);
++      return svc_proc_register(net, &nn->nfsd_svcstats, &nfsd_proc_ops);
+ }
+ 
+ void nfsd_proc_stat_shutdown(struct net *net)
+diff --git a/fs/nfsd/stats.h b/fs/nfsd/stats.h
+index d2753e975dfd34..b1f7d21cbcd12c 100644
+--- a/fs/nfsd/stats.h
++++ b/fs/nfsd/stats.h
+@@ -15,7 +15,7 @@ void nfsd_percpu_counters_reset(struct percpu_counter 
*counters, int num);
+ void nfsd_percpu_counters_destroy(struct percpu_counter *counters, int num);
+ int nfsd_stat_counters_init(struct nfsd_net *nn);
+ void nfsd_stat_counters_destroy(struct nfsd_net *nn);
+-void nfsd_proc_stat_init(struct net *net);
++struct proc_dir_entry *nfsd_proc_stat_init(struct net *net);
+ void nfsd_proc_stat_shutdown(struct net *net);
+ 
+ static inline void nfsd_stats_rc_hits_inc(struct nfsd_net *nn)
+diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
+index 58ca7c936393c4..aa39cdce59930b 100644
+--- a/fs/nilfs2/sufile.c
++++ b/fs/nilfs2/sufile.c
+@@ -1091,6 +1091,9 @@ int nilfs_sufile_trim_fs(struct inode *sufile, struct 
fstrim_range *range)
+       else
+               end_block = start_block + len - 1;
+ 
++      if (end_block < nilfs->ns_first_data_block)
++              goto out;
++
+       segnum = nilfs_get_segnum_of_block(nilfs, start_block);
+       segnum_end = nilfs_get_segnum_of_block(nilfs, end_block);
+ 
+@@ -1188,6 +1191,7 @@ int nilfs_sufile_trim_fs(struct inode *sufile, struct 
fstrim_range *range)
+ out_sem:
+       up_read(&NILFS_MDT(sufile)->mi_sem);
+ 
++out:
+       range->len = ndiscarded << nilfs->ns_blocksize_bits;
+       return ret;
+ }
+diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h
+index bc8a812ff95f8b..96697c78b3a650 100644
+--- a/fs/smb/client/cached_dir.h
++++ b/fs/smb/client/cached_dir.h
+@@ -34,10 +34,10 @@ struct cached_fid {
+       struct list_head entry;
+       struct cached_fids *cfids;
+       const char *path;
+-      bool has_lease:1;
+-      bool is_open:1;
+-      bool on_list:1;
+-      bool file_all_info_is_valid:1;
++      bool has_lease;
++      bool is_open;
++      bool on_list;
++      bool file_all_info_is_valid;
+       unsigned long time; /* jiffies of when lease was taken */
+       struct kref refcount;
+       struct cifs_fid fid;
+diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c
+index 80050b2178980a..598601a4bf92c7 100644
+--- a/fs/smb/server/server.c
++++ b/fs/smb/server/server.c
+@@ -126,21 +126,21 @@ static int __process_request(struct ksmbd_work *work, 
struct ksmbd_conn *conn,
+ andx_again:
+       if (command >= conn->max_cmds) {
+               conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER);
+-              return SERVER_HANDLER_CONTINUE;
++              return SERVER_HANDLER_ABORT;
+       }
+ 
+       cmds = &conn->cmds[command];
+       if (!cmds->proc) {
+               ksmbd_debug(SMB, "*** not implemented yet cmd = %x\n", command);
+               conn->ops->set_rsp_status(work, STATUS_NOT_IMPLEMENTED);
+-              return SERVER_HANDLER_CONTINUE;
++              return SERVER_HANDLER_ABORT;
+       }
+ 
+       if (work->sess && conn->ops->is_sign_req(work, command)) {
+               ret = conn->ops->check_sign_req(work);
+               if (!ret) {
+                       conn->ops->set_rsp_status(work, STATUS_ACCESS_DENIED);
+-                      return SERVER_HANDLER_CONTINUE;
++                      return SERVER_HANDLER_ABORT;
+               }
+       }
+ 
+diff --git a/fs/smb/server/transport_tcp.c b/fs/smb/server/transport_tcp.c
+index 08275db6446c2b..d05af46257cf4f 100644
+--- a/fs/smb/server/transport_tcp.c
++++ b/fs/smb/server/transport_tcp.c
+@@ -41,6 +41,7 @@ static struct ksmbd_transport_ops ksmbd_tcp_transport_ops;
+ 
+ static void tcp_stop_kthread(struct task_struct *kthread);
+ static struct interface *alloc_iface(char *ifname);
++static void ksmbd_tcp_disconnect(struct ksmbd_transport *t);
+ 
+ #define KSMBD_TRANS(t)        (&(t)->transport)
+ #define TCP_TRANS(t)  ((struct tcp_transport *)container_of(t, \
+@@ -219,7 +220,7 @@ static int ksmbd_tcp_new_connection(struct socket 
*client_sk)
+       if (IS_ERR(handler)) {
+               pr_err("cannot start conn thread\n");
+               rc = PTR_ERR(handler);
+-              free_transport(t);
++              ksmbd_tcp_disconnect(KSMBD_TRANS(t));
+       }
+       return rc;
+ 
+diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
+index 9f25cfd96f980f..4b805d7f5769f7 100644
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -1859,16 +1859,26 @@ static void __reset_counters(struct pm_nl_pernet 
*pernet)
+ static int mptcp_nl_cmd_flush_addrs(struct sk_buff *skb, struct genl_info 
*info)
+ {
+       struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
+-      LIST_HEAD(free_list);
++      struct list_head free_list;
+ 
+       spin_lock_bh(&pernet->lock);
+-      list_splice_init(&pernet->local_addr_list, &free_list);
++      free_list = pernet->local_addr_list;
++      INIT_LIST_HEAD_RCU(&pernet->local_addr_list);
+       __reset_counters(pernet);
+       pernet->next_id = 1;
+       bitmap_zero(pernet->id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
+       spin_unlock_bh(&pernet->lock);
+-      mptcp_nl_remove_addrs_list(sock_net(skb->sk), &free_list);
++
++      if (free_list.next == &pernet->local_addr_list)
++              return 0;
++
+       synchronize_rcu();
++
++      /* Adjust the pointers to free_list instead of pernet->local_addr_list 
*/
++      free_list.prev->next = &free_list;
++      free_list.next->prev = &free_list;
++
++      mptcp_nl_remove_addrs_list(sock_net(skb->sk), &free_list);
+       __flush_addrs(&free_list);
+       return 0;
+ }
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 120d9bd53321ca..a0a5d19fa8506b 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -6615,7 +6615,7 @@ static int nft_setelem_catchall_insert(const struct net 
*net,
+               }
+       }
+ 
+-      catchall = kmalloc(sizeof(*catchall), GFP_KERNEL);
++      catchall = kmalloc(sizeof(*catchall), GFP_KERNEL_ACCOUNT);
+       if (!catchall)
+               return -ENOMEM;
+ 
+diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
+index 52cdfee17f73f1..7ca4f0d21fe2a2 100644
+--- a/net/netfilter/nft_compat.c
++++ b/net/netfilter/nft_compat.c
+@@ -535,7 +535,7 @@ nft_match_large_init(const struct nft_ctx *ctx, const 
struct nft_expr *expr,
+       struct xt_match *m = expr->ops->data;
+       int ret;
+ 
+-      priv->info = kmalloc(XT_ALIGN(m->matchsize), GFP_KERNEL);
++      priv->info = kmalloc(XT_ALIGN(m->matchsize), GFP_KERNEL_ACCOUNT);
+       if (!priv->info)
+               return -ENOMEM;
+ 
+@@ -808,7 +808,7 @@ nft_match_select_ops(const struct nft_ctx *ctx,
+               goto err;
+       }
+ 
+-      ops = kzalloc(sizeof(struct nft_expr_ops), GFP_KERNEL);
++      ops = kzalloc(sizeof(struct nft_expr_ops), GFP_KERNEL_ACCOUNT);
+       if (!ops) {
+               err = -ENOMEM;
+               goto err;
+@@ -898,7 +898,7 @@ nft_target_select_ops(const struct nft_ctx *ctx,
+               goto err;
+       }
+ 
+-      ops = kzalloc(sizeof(struct nft_expr_ops), GFP_KERNEL);
++      ops = kzalloc(sizeof(struct nft_expr_ops), GFP_KERNEL_ACCOUNT);
+       if (!ops) {
+               err = -ENOMEM;
+               goto err;
+diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c
+index 5defe6e4fd9820..e3558813799579 100644
+--- a/net/netfilter/nft_log.c
++++ b/net/netfilter/nft_log.c
+@@ -163,7 +163,7 @@ static int nft_log_init(const struct nft_ctx *ctx,
+ 
+       nla = tb[NFTA_LOG_PREFIX];
+       if (nla != NULL) {
+-              priv->prefix = kmalloc(nla_len(nla) + 1, GFP_KERNEL);
++              priv->prefix = kmalloc(nla_len(nla) + 1, GFP_KERNEL_ACCOUNT);
+               if (priv->prefix == NULL)
+                       return -ENOMEM;
+               nla_strscpy(priv->prefix, nla, nla_len(nla) + 1);
+diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
+index 8c8eb14d647b07..05cd1e6e6a2f61 100644
+--- a/net/netfilter/nft_meta.c
++++ b/net/netfilter/nft_meta.c
+@@ -952,7 +952,7 @@ static int nft_secmark_obj_init(const struct nft_ctx *ctx,
+       if (tb[NFTA_SECMARK_CTX] == NULL)
+               return -EINVAL;
+ 
+-      priv->ctx = nla_strdup(tb[NFTA_SECMARK_CTX], GFP_KERNEL);
++      priv->ctx = nla_strdup(tb[NFTA_SECMARK_CTX], GFP_KERNEL_ACCOUNT);
+       if (!priv->ctx)
+               return -ENOMEM;
+ 
+diff --git a/net/netfilter/nft_numgen.c b/net/netfilter/nft_numgen.c
+index 7d29db7c2ac0f0..bd058babfc820c 100644
+--- a/net/netfilter/nft_numgen.c
++++ b/net/netfilter/nft_numgen.c
+@@ -66,7 +66,7 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
+       if (priv->offset + priv->modulus - 1 < priv->offset)
+               return -EOVERFLOW;
+ 
+-      priv->counter = kmalloc(sizeof(*priv->counter), GFP_KERNEL);
++      priv->counter = kmalloc(sizeof(*priv->counter), GFP_KERNEL_ACCOUNT);
+       if (!priv->counter)
+               return -ENOMEM;
+ 
+diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
+index ebd0f704c863c3..c3ada6798d4a3f 100644
+--- a/net/netfilter/nft_set_pipapo.c
++++ b/net/netfilter/nft_set_pipapo.c
+@@ -610,6 +610,30 @@ static void *nft_pipapo_get(const struct net *net, const 
struct nft_set *set,
+                        nft_genmask_cur(net), get_jiffies_64());
+ }
+ 
++
++/**
++ * lt_calculate_size() - Get storage size for lookup table with overflow check
++ * @groups:   Amount of bit groups
++ * @bb:               Number of bits grouped together in lookup table buckets
++ * @bsize:    Size of each bucket in lookup table, in longs
++ *
++ * Return: allocation size including alignment overhead, negative on overflow
++ */
++static ssize_t lt_calculate_size(unsigned int groups, unsigned int bb,
++                               unsigned int bsize)
++{
++      ssize_t ret = groups * NFT_PIPAPO_BUCKETS(bb) * sizeof(long);
++
++      if (check_mul_overflow(ret, bsize, &ret))
++              return -1;
++      if (check_add_overflow(ret, NFT_PIPAPO_ALIGN_HEADROOM, &ret))
++              return -1;
++      if (ret > INT_MAX)
++              return -1;
++
++      return ret;
++}
++
+ /**
+  * pipapo_resize() - Resize lookup or mapping table, or both
+  * @f:                Field containing lookup and mapping tables
+@@ -628,6 +652,7 @@ static int pipapo_resize(struct nft_pipapo_field *f, int 
old_rules, int rules)
+       union nft_pipapo_map_bucket *new_mt, *old_mt = f->mt;
+       size_t new_bucket_size, copy;
+       int group, bucket;
++      ssize_t lt_size;
+ 
+       new_bucket_size = DIV_ROUND_UP(rules, BITS_PER_LONG);
+ #ifdef NFT_PIPAPO_ALIGN
+@@ -643,10 +668,11 @@ static int pipapo_resize(struct nft_pipapo_field *f, int 
old_rules, int rules)
+       else
+               copy = new_bucket_size;
+ 
+-      new_lt = kvzalloc(f->groups * NFT_PIPAPO_BUCKETS(f->bb) *
+-                        new_bucket_size * sizeof(*new_lt) +
+-                        NFT_PIPAPO_ALIGN_HEADROOM,
+-                        GFP_KERNEL);
++      lt_size = lt_calculate_size(f->groups, f->bb, new_bucket_size);
++      if (lt_size < 0)
++              return -ENOMEM;
++
++      new_lt = kvzalloc(lt_size, GFP_KERNEL_ACCOUNT);
+       if (!new_lt)
+               return -ENOMEM;
+ 
+@@ -845,7 +871,7 @@ static void pipapo_lt_bits_adjust(struct nft_pipapo_field 
*f)
+ {
+       unsigned long *new_lt;
+       int groups, bb;
+-      size_t lt_size;
++      ssize_t lt_size;
+ 
+       lt_size = f->groups * NFT_PIPAPO_BUCKETS(f->bb) * f->bsize *
+                 sizeof(*f->lt);
+@@ -855,15 +881,17 @@ static void pipapo_lt_bits_adjust(struct 
nft_pipapo_field *f)
+               groups = f->groups * 2;
+               bb = NFT_PIPAPO_GROUP_BITS_LARGE_SET;
+ 
+-              lt_size = groups * NFT_PIPAPO_BUCKETS(bb) * f->bsize *
+-                        sizeof(*f->lt);
++              lt_size = lt_calculate_size(groups, bb, f->bsize);
++              if (lt_size < 0)
++                      return;
+       } else if (f->bb == NFT_PIPAPO_GROUP_BITS_LARGE_SET &&
+                  lt_size < NFT_PIPAPO_LT_SIZE_LOW) {
+               groups = f->groups / 2;
+               bb = NFT_PIPAPO_GROUP_BITS_SMALL_SET;
+ 
+-              lt_size = groups * NFT_PIPAPO_BUCKETS(bb) * f->bsize *
+-                        sizeof(*f->lt);
++              lt_size = lt_calculate_size(groups, bb, f->bsize);
++              if (lt_size < 0)
++                      return;
+ 
+               /* Don't increase group width if the resulting lookup table size
+                * would exceed the upper size threshold for a "small" set.
+@@ -874,7 +902,7 @@ static void pipapo_lt_bits_adjust(struct nft_pipapo_field 
*f)
+               return;
+       }
+ 
+-      new_lt = kvzalloc(lt_size + NFT_PIPAPO_ALIGN_HEADROOM, GFP_KERNEL);
++      new_lt = kvzalloc(lt_size, GFP_KERNEL_ACCOUNT);
+       if (!new_lt)
+               return;
+ 
+@@ -1150,7 +1178,7 @@ static int pipapo_realloc_scratch(struct 
nft_pipapo_match *clone,
+               scratch = kzalloc_node(struct_size(scratch, map,
+                                                  bsize_max * 2) +
+                                      NFT_PIPAPO_ALIGN_HEADROOM,
+-                                     GFP_KERNEL, cpu_to_node(i));
++                                     GFP_KERNEL_ACCOUNT, cpu_to_node(i));
+               if (!scratch) {
+                       /* On failure, there's no need to undo previous
+                        * allocations: this means that some scratch maps have
+@@ -1323,7 +1351,7 @@ static struct nft_pipapo_match *pipapo_clone(struct 
nft_pipapo_match *old)
+       struct nft_pipapo_match *new;
+       int i;
+ 
+-      new = kmalloc(struct_size(new, f, old->field_count), GFP_KERNEL);
++      new = kmalloc(struct_size(new, f, old->field_count), 
GFP_KERNEL_ACCOUNT);
+       if (!new)
+               return ERR_PTR(-ENOMEM);
+ 
+@@ -1347,13 +1375,15 @@ static struct nft_pipapo_match *pipapo_clone(struct 
nft_pipapo_match *old)
+ 
+       for (i = 0; i < old->field_count; i++) {
+               unsigned long *new_lt;
++              ssize_t lt_size;
+ 
+               memcpy(dst, src, offsetof(struct nft_pipapo_field, lt));
+ 
+-              new_lt = kvzalloc(src->groups * NFT_PIPAPO_BUCKETS(src->bb) *
+-                                src->bsize * sizeof(*dst->lt) +
+-                                NFT_PIPAPO_ALIGN_HEADROOM,
+-                                GFP_KERNEL);
++              lt_size = lt_calculate_size(src->groups, src->bb, src->bsize);
++              if (lt_size < 0)
++                      goto out_lt;
++
++              new_lt = kvzalloc(lt_size, GFP_KERNEL_ACCOUNT);
+               if (!new_lt)
+                       goto out_lt;
+ 
+@@ -1367,7 +1397,7 @@ static struct nft_pipapo_match *pipapo_clone(struct 
nft_pipapo_match *old)
+               if (src->rules > (INT_MAX / sizeof(*src->mt)))
+                       goto out_mt;
+ 
+-              dst->mt = kvmalloc(src->rules * sizeof(*src->mt), GFP_KERNEL);
++              dst->mt = kvmalloc(src->rules * sizeof(*src->mt), 
GFP_KERNEL_ACCOUNT);
+               if (!dst->mt)
+                       goto out_mt;
+ 
+diff --git a/net/netfilter/nft_tunnel.c b/net/netfilter/nft_tunnel.c
+index 3e3ae29dde3359..f77a5bf6991138 100644
+--- a/net/netfilter/nft_tunnel.c
++++ b/net/netfilter/nft_tunnel.c
+@@ -503,13 +503,14 @@ static int nft_tunnel_obj_init(const struct nft_ctx *ctx,
+                       return err;
+       }
+ 
+-      md = metadata_dst_alloc(priv->opts.len, METADATA_IP_TUNNEL, GFP_KERNEL);
++      md = metadata_dst_alloc(priv->opts.len, METADATA_IP_TUNNEL,
++                              GFP_KERNEL_ACCOUNT);
+       if (!md)
+               return -ENOMEM;
+ 
+       memcpy(&md->u.tun_info, &info, sizeof(info));
+ #ifdef CONFIG_DST_CACHE
+-      err = dst_cache_init(&md->u.tun_info.dst_cache, GFP_KERNEL);
++      err = dst_cache_init(&md->u.tun_info.dst_cache, GFP_KERNEL_ACCOUNT);
+       if (err < 0) {
+               metadata_dst_free(md);
+               return err;
+diff --git a/tools/testing/selftests/net/mptcp/pm_netlink.sh 
b/tools/testing/selftests/net/mptcp/pm_netlink.sh
+index 3528e730e4d37c..c089d4e06d5999 100755
+--- a/tools/testing/selftests/net/mptcp/pm_netlink.sh
++++ b/tools/testing/selftests/net/mptcp/pm_netlink.sh
+@@ -127,6 +127,10 @@ id 8 flags signal 10.0.1.8" "id limit"
+ ip netns exec $ns1 ./pm_nl_ctl flush
+ check "ip netns exec $ns1 ./pm_nl_ctl dump" "" "flush addrs"
+ 
++ip netns exec $ns1 ./pm_nl_ctl add 10.0.1.1 flags unknown
++check "ip netns exec $ns1 ./pm_nl_ctl dump" "id 1 flags  10.0.1.1" "ignore 
unknown flags"
++ip netns exec $ns1 ./pm_nl_ctl flush
++
+ ip netns exec $ns1 ./pm_nl_ctl limits 9 1 2>/dev/null
+ check "ip netns exec $ns1 ./pm_nl_ctl limits" "$default_limits" "rcv addrs 
above hard limit"
+ 
+diff --git a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c 
b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
+index 234c267dd2aad3..f586f1272bd784 100644
+--- a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
++++ b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
+@@ -29,6 +29,8 @@
+ #define IPPROTO_MPTCP 262
+ #endif
+ 
++#define MPTCP_PM_ADDR_FLAG_UNKNOWN _BITUL(7)
++
+ static void syntax(char *argv[])
+ {
+       fprintf(stderr, "%s 
add|ann|rem|csf|dsf|get|set|del|flush|dump|events|listen|accept [<args>]\n", 
argv[0]);
+@@ -825,6 +827,8 @@ int add_addr(int fd, int pm_family, int argc, char *argv[])
+                                       flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
+                               else if (!strcmp(tok, "fullmesh"))
+                                       flags |= MPTCP_PM_ADDR_FLAG_FULLMESH;
++                              else if (!strcmp(tok, "unknown"))
++                                      flags |= MPTCP_PM_ADDR_FLAG_UNKNOWN;
+                               else
+                                       error(1, errno,
+                                             "unknown flag %s", argv[arg]);
+@@ -1030,6 +1034,13 @@ static void print_addr(struct rtattr *attrs, int len)
+                                       printf(",");
+                       }
+ 
++                      if (flags & MPTCP_PM_ADDR_FLAG_UNKNOWN) {
++                              printf("unknown");
++                              flags &= ~MPTCP_PM_ADDR_FLAG_UNKNOWN;
++                              if (flags)
++                                      printf(",");
++                      }
++
+                       /* bump unknown flags, if any */
+                       if (flags)
+                               printf("0x%x", flags);
+diff --git a/tools/testing/vsock/control.c b/tools/testing/vsock/control.c
+index d2deb4b15b943c..0066e0324d35c6 100644
+--- a/tools/testing/vsock/control.c
++++ b/tools/testing/vsock/control.c
+@@ -27,6 +27,7 @@
+ 
+ #include "timeout.h"
+ #include "control.h"
++#include "util.h"
+ 
+ static int control_fd = -1;
+ 
+@@ -50,7 +51,6 @@ void control_init(const char *control_host,
+ 
+       for (ai = result; ai; ai = ai->ai_next) {
+               int fd;
+-              int val = 1;
+ 
+               fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+               if (fd < 0)
+@@ -65,11 +65,8 @@ void control_init(const char *control_host,
+                       break;
+               }
+ 
+-              if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
+-                             &val, sizeof(val)) < 0) {
+-                      perror("setsockopt");
+-                      exit(EXIT_FAILURE);
+-              }
++              setsockopt_int_check(fd, SOL_SOCKET, SO_REUSEADDR, 1,
++                                   "setsockopt SO_REUSEADDR");
+ 
+               if (bind(fd, ai->ai_addr, ai->ai_addrlen) < 0)
+                       goto next;
+diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
+index 751fe7c6632eac..e67e26636f5796 100644
+--- a/tools/testing/vsock/util.c
++++ b/tools/testing/vsock/util.c
+@@ -12,6 +12,7 @@
+ #include <stdint.h>
+ #include <stdlib.h>
+ #include <signal.h>
++#include <string.h>
+ #include <unistd.h>
+ #include <assert.h>
+ #include <sys/epoll.h>
+@@ -420,3 +421,145 @@ unsigned long hash_djb2(const void *data, size_t len)
+ 
+       return hash;
+ }
++
++/* Set "unsigned long long" socket option and check that it's indeed set */
++void setsockopt_ull_check(int fd, int level, int optname,
++                        unsigned long long val, char const *errmsg)
++{
++      unsigned long long chkval;
++      socklen_t chklen;
++      int err;
++
++      err = setsockopt(fd, level, optname, &val, sizeof(val));
++      if (err) {
++              fprintf(stderr, "setsockopt err: %s (%d)\n",
++                      strerror(errno), errno);
++              goto fail;
++      }
++
++      chkval = ~val; /* just make storage != val */
++      chklen = sizeof(chkval);
++
++      err = getsockopt(fd, level, optname, &chkval, &chklen);
++      if (err) {
++              fprintf(stderr, "getsockopt err: %s (%d)\n",
++                      strerror(errno), errno);
++              goto fail;
++      }
++
++      if (chklen != sizeof(chkval)) {
++              fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val),
++                      chklen);
++              goto fail;
++      }
++
++      if (chkval != val) {
++              fprintf(stderr, "value mismatch: set %llu got %llu\n", val,
++                      chkval);
++              goto fail;
++      }
++      return;
++fail:
++      fprintf(stderr, "%s  val %llu\n", errmsg, val);
++      exit(EXIT_FAILURE);
++;
++}
++
++/* Set "int" socket option and check that it's indeed set */
++void setsockopt_int_check(int fd, int level, int optname, int val,
++                        char const *errmsg)
++{
++      int chkval;
++      socklen_t chklen;
++      int err;
++
++      err = setsockopt(fd, level, optname, &val, sizeof(val));
++      if (err) {
++              fprintf(stderr, "setsockopt err: %s (%d)\n",
++                      strerror(errno), errno);
++              goto fail;
++      }
++
++      chkval = ~val; /* just make storage != val */
++      chklen = sizeof(chkval);
++
++      err = getsockopt(fd, level, optname, &chkval, &chklen);
++      if (err) {
++              fprintf(stderr, "getsockopt err: %s (%d)\n",
++                      strerror(errno), errno);
++              goto fail;
++      }
++
++      if (chklen != sizeof(chkval)) {
++              fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val),
++                      chklen);
++              goto fail;
++      }
++
++      if (chkval != val) {
++              fprintf(stderr, "value mismatch: set %d got %d\n", val, chkval);
++              goto fail;
++      }
++      return;
++fail:
++      fprintf(stderr, "%s val %d\n", errmsg, val);
++      exit(EXIT_FAILURE);
++}
++
++static void mem_invert(unsigned char *mem, size_t size)
++{
++      size_t i;
++
++      for (i = 0; i < size; i++)
++              mem[i] = ~mem[i];
++}
++
++/* Set "timeval" socket option and check that it's indeed set */
++void setsockopt_timeval_check(int fd, int level, int optname,
++                            struct timeval val, char const *errmsg)
++{
++      struct timeval chkval;
++      socklen_t chklen;
++      int err;
++
++      err = setsockopt(fd, level, optname, &val, sizeof(val));
++      if (err) {
++              fprintf(stderr, "setsockopt err: %s (%d)\n",
++                      strerror(errno), errno);
++              goto fail;
++      }
++
++       /* just make storage != val */
++      chkval = val;
++      mem_invert((unsigned char *)&chkval, sizeof(chkval));
++      chklen = sizeof(chkval);
++
++      err = getsockopt(fd, level, optname, &chkval, &chklen);
++      if (err) {
++              fprintf(stderr, "getsockopt err: %s (%d)\n",
++                      strerror(errno), errno);
++              goto fail;
++      }
++
++      if (chklen != sizeof(chkval)) {
++              fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val),
++                      chklen);
++              goto fail;
++      }
++
++      if (memcmp(&chkval, &val, sizeof(val)) != 0) {
++              fprintf(stderr, "value mismatch: set %ld:%ld got %ld:%ld\n",
++                      val.tv_sec, val.tv_usec, chkval.tv_sec, chkval.tv_usec);
++              goto fail;
++      }
++      return;
++fail:
++      fprintf(stderr, "%s val %ld:%ld\n", errmsg, val.tv_sec, val.tv_usec);
++      exit(EXIT_FAILURE);
++}
++
++void enable_so_zerocopy_check(int fd)
++{
++      setsockopt_int_check(fd, SOL_SOCKET, SO_ZEROCOPY, 1,
++                           "setsockopt SO_ZEROCOPY");
++}
+diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
+index fb99208a95eab7..a05438851919c7 100644
+--- a/tools/testing/vsock/util.h
++++ b/tools/testing/vsock/util.h
+@@ -50,4 +50,11 @@ void list_tests(const struct test_case *test_cases);
+ void skip_test(struct test_case *test_cases, size_t test_cases_len,
+              const char *test_id_str);
+ unsigned long hash_djb2(const void *data, size_t len);
++void setsockopt_ull_check(int fd, int level, int optname,
++                        unsigned long long val, char const *errmsg);
++void setsockopt_int_check(int fd, int level, int optname, int val,
++                        char const *errmsg);
++void setsockopt_timeval_check(int fd, int level, int optname,
++                            struct timeval val, char const *errmsg);
++void enable_so_zerocopy_check(int fd);
+ #endif /* UTIL_H */
+diff --git a/tools/testing/vsock/vsock_test.c 
b/tools/testing/vsock/vsock_test.c
+index 793d688cd4da6d..01ad8cfa9bde37 100644
+--- a/tools/testing/vsock/vsock_test.c
++++ b/tools/testing/vsock/vsock_test.c
+@@ -503,17 +503,13 @@ static void test_seqpacket_msg_bounds_server(const 
struct test_opts *opts)
+ 
+       sock_buf_size = SOCK_BUF_SIZE;
+ 
+-      if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE,
+-                     &sock_buf_size, sizeof(sock_buf_size))) {
+-              perror("setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)");
+-              exit(EXIT_FAILURE);
+-      }
++      setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE,
++                           sock_buf_size,
++                           "setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)");
+ 
+-      if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
+-                     &sock_buf_size, sizeof(sock_buf_size))) {
+-              perror("setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
+-              exit(EXIT_FAILURE);
+-      }
++      setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
++                           sock_buf_size,
++                           "setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
+ 
+       /* Ready to receive data. */
+       control_writeln("SRVREADY");
+@@ -648,10 +644,8 @@ static void test_seqpacket_timeout_client(const struct 
test_opts *opts)
+       tv.tv_sec = RCVTIMEO_TIMEOUT_SEC;
+       tv.tv_usec = 0;
+ 
+-      if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv)) == 
-1) {
+-              perror("setsockopt(SO_RCVTIMEO)");
+-              exit(EXIT_FAILURE);
+-      }
++      setsockopt_timeval_check(fd, SOL_SOCKET, SO_RCVTIMEO, tv,
++                               "setsockopt(SO_RCVTIMEO)");
+ 
+       read_enter_ns = current_nsec();
+ 
+@@ -928,11 +922,8 @@ static void test_stream_poll_rcvlowat_client(const struct 
test_opts *opts)
+               exit(EXIT_FAILURE);
+       }
+ 
+-      if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT,
+-                     &lowat_val, sizeof(lowat_val))) {
+-              perror("setsockopt(SO_RCVLOWAT)");
+-              exit(EXIT_FAILURE);
+-      }
++      setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT,
++                           lowat_val, "setsockopt(SO_RCVLOWAT)");
+ 
+       control_expectln("SRVSENT");
+ 


Reply via email to