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"); +
