已开启
fix CVEs for kernel_linux_6.6 master (#1024) #406
fix CVEs for kernel_linux_6.6 master (#1024) #406
已开启
wanghao794创建于 7月24日
49 个文件变更+493-354
@@ -107,6 +107,8 @@ static long compat_restore_sigcontext(struct pt_regs *regs,
107 107 
108 /* sc_regs is structured the same as the start of pt_regs */108 /* sc_regs is structured the same as the start of pt_regs */
109 err = __copy_from_user(&cregs, &sc->sc_regs, sizeof(sc->sc_regs));109 err = __copy_from_user(&cregs, &sc->sc_regs, sizeof(sc->sc_regs));
110+ if (unlikely(err))
111+ return err;
110 112 
111 cregs_to_regs(&cregs, regs);113 cregs_to_regs(&cregs, regs);
112 114 
@@ -327,8 +327,8 @@ static int compat_riscv_gpr_set(struct task_struct *target,
327 struct compat_user_regs_struct cregs;327 struct compat_user_regs_struct cregs;
328 328 
329 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &cregs, 0, -1);329 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &cregs, 0, -1);
330- 330+ if (!ret)
331- cregs_to_regs(&cregs, task_pt_regs(target));331+ cregs_to_regs(&cregs, task_pt_regs(target));
332 332 
333 return ret;333 return ret;
334}334}
@@ -689,6 +689,9 @@ static int hci_uart_register_dev(struct hci_uart *hu)
689 689 
690 if (hci_register_dev(hdev) < 0) {690 if (hci_register_dev(hdev) < 0) {
691 BT_ERR("Can't register HCI device");691 BT_ERR("Can't register HCI device");
692+ percpu_down_write(&hu->proto_lock);
693+ clear_bit(HCI_UART_PROTO_INIT, &hu->flags);
694+ percpu_up_write(&hu->proto_lock);
692 hu->proto->close(hu);695 hu->proto->close(hu);
693 hu->hdev = NULL;696 hu->hdev = NULL;
694 hci_free_dev(hdev);697 hci_free_dev(hdev);
@@ -178,7 +178,7 @@ static int mpfs_ccc_register_outputs(struct device *dev, struct mpfs_ccc_out_hw_
178 return dev_err_probe(dev, ret, "failed to register clock id: %d\n",178 return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
179 out_hw->id);179 out_hw->id);
180 180 
181- data->hw_data.hws[out_hw->id] = &out_hw->divider.hw;181+ data->hw_data.hws[out_hw->id - 2] = &out_hw->divider.hw;
182 }182 }
183 183 
184 return 0;184 return 0;
@@ -234,6 +234,10 @@ static int mpfs_ccc_probe(struct platform_device *pdev)
234 unsigned int num_clks;234 unsigned int num_clks;
235 int ret;235 int ret;
236 236 
237+ /*
238+ * If DLLs get added here, mpfs_ccc_register_outputs() currently packs
239+ * sparse clock IDs in the hws array
240+ */
237 num_clks = ARRAY_SIZE(mpfs_ccc_pll_clks) + ARRAY_SIZE(mpfs_ccc_pll0out_clks) +241 num_clks = ARRAY_SIZE(mpfs_ccc_pll_clks) + ARRAY_SIZE(mpfs_ccc_pll0out_clks) +
238 ARRAY_SIZE(mpfs_ccc_pll1out_clks);242 ARRAY_SIZE(mpfs_ccc_pll1out_clks);
239 243 
@@ -10138,6 +10138,11 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
10138 }10138 }
10139 10139 
10140 if (dc_resource_is_dsc_encoding_supported(dc)) {10140 if (dc_resource_is_dsc_encoding_supported(dc)) {
10141+ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
10142+ dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
10143+ dm_new_crtc_state->mode_changed_independent_from_dsc = new_crtc_state->mode_changed;
10144+ }
10145+ 
10141 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {10146 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
10142 if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {10147 if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
10143 ret = add_affected_mst_dsc_crtcs(state, crtc);10148 ret = add_affected_mst_dsc_crtcs(state, crtc);
@@ -737,6 +737,7 @@ struct dm_crtc_state {
737 737 
738 bool freesync_vrr_info_changed;738 bool freesync_vrr_info_changed;
739 739 
740+ bool mode_changed_independent_from_dsc;
740 bool dsc_force_changed;741 bool dsc_force_changed;
741 bool vrr_supported;742 bool vrr_supported;
742 struct mod_freesync_config freesync_config;743 struct mod_freesync_config freesync_config;
@@ -1587,8 +1587,11 @@ int pre_validate_dsc(struct drm_atomic_state *state,
1587 } else {1587 } else {
1588 int ind = find_crtc_index_in_state_by_stream(state, stream);1588 int ind = find_crtc_index_in_state_by_stream(state, stream);
1589 1589 
1590- if (ind >= 0)1590+ if (ind >= 0) {
1591- state->crtcs[ind].new_state->mode_changed = 0;1591+ struct dm_crtc_state *dm_new_crtc_state = to_dm_crtc_state(state->crtcs[ind].new_state);
1592+ 
1593+ dm_new_crtc_state->base.mode_changed = dm_new_crtc_state->mode_changed_independent_from_dsc;
1594+ }
1592 }1595 }
1593 }1596 }
1594clean_exit:1597clean_exit:
@@ -810,7 +810,7 @@ static void cdns_mhdp_fw_cb(const struct firmware *fw, void *context)
810 bridge_attached = mhdp->bridge_attached;810 bridge_attached = mhdp->bridge_attached;
811 spin_unlock(&mhdp->start_lock);811 spin_unlock(&mhdp->start_lock);
812 if (bridge_attached) {812 if (bridge_attached) {
813- if (mhdp->connector.dev)813+ if (mhdp->connector_ptr)
814 drm_kms_helper_hotplug_event(mhdp->bridge.dev);814 drm_kms_helper_hotplug_event(mhdp->bridge.dev);
815 else815 else
816 drm_bridge_hpd_notify(&mhdp->bridge, cdns_mhdp_detect(mhdp));816 drm_bridge_hpd_notify(&mhdp->bridge, cdns_mhdp_detect(mhdp));
@@ -1709,6 +1709,7 @@ static int cdns_mhdp_connector_init(struct cdns_mhdp_device *mhdp)
1709 return ret;1709 return ret;
1710 }1710 }
1711 1711 
1712+ mhdp->connector_ptr = conn;
1712 drm_connector_helper_add(conn, &cdns_mhdp_conn_helper_funcs);1713 drm_connector_helper_add(conn, &cdns_mhdp_conn_helper_funcs);
1713 1714 
1714 ret = drm_display_info_set_bus_formats(&conn->display_info,1715 ret = drm_display_info_set_bus_formats(&conn->display_info,
@@ -1988,17 +1989,25 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge,
1988 struct drm_atomic_state *state = bridge_state->base.state;1989 struct drm_atomic_state *state = bridge_state->base.state;
1989 struct cdns_mhdp_bridge_state *mhdp_state;1990 struct cdns_mhdp_bridge_state *mhdp_state;
1990 struct drm_crtc_state *crtc_state;1991 struct drm_crtc_state *crtc_state;
1991- struct drm_connector *connector;
1992 struct drm_connector_state *conn_state;1992 struct drm_connector_state *conn_state;
1993 struct drm_bridge_state *new_state;1993 struct drm_bridge_state *new_state;
1994 const struct drm_display_mode *mode;1994 const struct drm_display_mode *mode;
1995 u32 resp;1995 u32 resp;
1996- int ret;1996+ int ret = 0;
1997 1997 
1998 dev_dbg(mhdp->dev, "bridge enable\n");1998 dev_dbg(mhdp->dev, "bridge enable\n");
1999 1999 
2000 mutex_lock(&mhdp->link_mutex);2000 mutex_lock(&mhdp->link_mutex);
2001 2001 
2002+ mhdp->connector_ptr = drm_atomic_get_new_connector_for_encoder(state,
2003+ bridge->encoder);
2004+ if (WARN_ON(!mhdp->connector_ptr))
2005+ goto out;
2006+ 
2007+ conn_state = drm_atomic_get_new_connector_state(state, mhdp->connector_ptr);
2008+ if (WARN_ON(!conn_state))
2009+ goto out;
2010+ 
2002 if (mhdp->plugged && !mhdp->link_up) {2011 if (mhdp->plugged && !mhdp->link_up) {
2003 ret = cdns_mhdp_link_up(mhdp);2012 ret = cdns_mhdp_link_up(mhdp);
2004 if (ret < 0)2013 if (ret < 0)
@@ -2018,15 +2027,6 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge,
2018 cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR,2027 cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR,
2019 resp | CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN);2028 resp | CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN);
2020 2029 
2021- connector = drm_atomic_get_new_connector_for_encoder(state,
2022- bridge->encoder);
2023- if (WARN_ON(!connector))
2024- goto out;
2025- 
2026- conn_state = drm_atomic_get_new_connector_state(state, connector);
2027- if (WARN_ON(!conn_state))
2028- goto out;
2029- 
2030 if (mhdp->hdcp_supported &&2030 if (mhdp->hdcp_supported &&
2031 mhdp->hw_state == MHDP_HW_READY &&2031 mhdp->hw_state == MHDP_HW_READY &&
2032 conn_state->content_protection ==2032 conn_state->content_protection ==
@@ -2101,6 +2101,7 @@ static void cdns_mhdp_atomic_disable(struct drm_bridge *bridge,
2101 if (mhdp->info && mhdp->info->ops && mhdp->info->ops->disable)2101 if (mhdp->info && mhdp->info->ops && mhdp->info->ops->disable)
2102 mhdp->info->ops->disable(mhdp);2102 mhdp->info->ops->disable(mhdp);
2103 2103 
2104+ mhdp->connector_ptr = NULL;
2104 mutex_unlock(&mhdp->link_mutex);2105 mutex_unlock(&mhdp->link_mutex);
2105}2106}
2106 2107 
@@ -2366,7 +2367,7 @@ static void cdns_mhdp_modeset_retry_fn(struct work_struct *work)
2366 2367 
2367 mhdp = container_of(work, typeof(*mhdp), modeset_retry_work);2368 mhdp = container_of(work, typeof(*mhdp), modeset_retry_work);
2368 2369 
2369- conn = &mhdp->connector;2370+ conn = mhdp->connector_ptr;
2370 2371 
2371 /* Grab the locks before changing connector property */2372 /* Grab the locks before changing connector property */
2372 mutex_lock(&conn->dev->mode_config.mutex);2373 mutex_lock(&conn->dev->mode_config.mutex);
@@ -2443,7 +2444,7 @@ static void cdns_mhdp_hpd_work(struct work_struct *work)
2443 int ret;2444 int ret;
2444 2445 
2445 ret = cdns_mhdp_update_link_status(mhdp);2446 ret = cdns_mhdp_update_link_status(mhdp);
2446- if (mhdp->connector.dev) {2447+ if (mhdp->connector_ptr) {
2447 if (ret < 0)2448 if (ret < 0)
2448 schedule_work(&mhdp->modeset_retry_work);2449 schedule_work(&mhdp->modeset_retry_work);
2449 else2450 else
@@ -376,6 +376,7 @@ struct cdns_mhdp_device {
376 struct mutex link_mutex;376 struct mutex link_mutex;
377 377 
378 struct drm_connector connector;378 struct drm_connector connector;
lijiawei
lijiaweilijiawei7月27日

[drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h:378] 新增 struct drm_connector *connector_ptr 后,原有的嵌入成员 struct drm_connector connector; 变成死代码。该嵌入结构体不再被使用,但仍然占用内存且容易造成混淆。建议移除 struct drm_connector connector; 或在提交说明中解释保留原因。同时确认所有引用 mhdp->connector 的代码已全部替换为 mhdp->connector_ptr

likedislike
wanghao794
7月28日 评论:
379+ struct drm_connector *connector_ptr;
379 struct drm_bridge bridge;380 struct drm_bridge bridge;
380 381 
381 struct cdns_mhdp_link link;382 struct cdns_mhdp_link link;
@@ -394,7 +394,7 @@ static int _cdns_mhdp_hdcp_disable(struct cdns_mhdp_device *mhdp)
394 int ret;394 int ret;
395 395 
396 dev_dbg(mhdp->dev, "[%s:%d] HDCP is being disabled...\n",396 dev_dbg(mhdp->dev, "[%s:%d] HDCP is being disabled...\n",
397- mhdp->connector.name, mhdp->connector.base.id);397+ mhdp->connector_ptr->name, mhdp->connector_ptr->base.id);
398 398 
399 ret = cdns_mhdp_hdcp_set_config(mhdp, 0, false);399 ret = cdns_mhdp_hdcp_set_config(mhdp, 0, false);
400 400 
@@ -436,6 +436,10 @@ static int cdns_mhdp_hdcp_check_link(struct cdns_mhdp_device *mhdp)
436 int ret = 0;436 int ret = 0;
437 437 
438 mutex_lock(&mhdp->hdcp.mutex);438 mutex_lock(&mhdp->hdcp.mutex);
439+ 
440+ if (!mhdp->connector_ptr)
441+ goto out;
442+ 
439 if (mhdp->hdcp.value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)443 if (mhdp->hdcp.value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
440 goto out;444 goto out;
441 445 
@@ -445,7 +449,7 @@ static int cdns_mhdp_hdcp_check_link(struct cdns_mhdp_device *mhdp)
445 449 
446 dev_err(mhdp->dev,450 dev_err(mhdp->dev,
447 "[%s:%d] HDCP link failed, retrying authentication\n",451 "[%s:%d] HDCP link failed, retrying authentication\n",
448- mhdp->connector.name, mhdp->connector.base.id);452+ mhdp->connector_ptr->name, mhdp->connector_ptr->base.id);
449 453 
450 ret = _cdns_mhdp_hdcp_disable(mhdp);454 ret = _cdns_mhdp_hdcp_disable(mhdp);
451 if (ret) {455 if (ret) {
@@ -487,13 +491,19 @@ static void cdns_mhdp_hdcp_prop_work(struct work_struct *work)
487 struct cdns_mhdp_device *mhdp = container_of(hdcp,491 struct cdns_mhdp_device *mhdp = container_of(hdcp,
488 struct cdns_mhdp_device,492 struct cdns_mhdp_device,
489 hdcp);493 hdcp);
490- struct drm_device *dev = mhdp->connector.dev;494+ struct drm_device *dev = NULL;
491 struct drm_connector_state *state;495 struct drm_connector_state *state;
492 496 
497+ if (mhdp->connector_ptr)
498+ dev = mhdp->connector_ptr->dev;
499+ 
500+ if (!dev)
501+ return;
502+ 
493 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);503 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
494 mutex_lock(&mhdp->hdcp.mutex);504 mutex_lock(&mhdp->hdcp.mutex);
495 if (mhdp->hdcp.value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {505 if (mhdp->hdcp.value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
496- state = mhdp->connector.state;506+ state = mhdp->connector_ptr->state;
497 state->content_protection = mhdp->hdcp.value;507 state->content_protection = mhdp->hdcp.value;
498 }508 }
499 mutex_unlock(&mhdp->hdcp.mutex);509 mutex_unlock(&mhdp->hdcp.mutex);
@@ -597,6 +597,9 @@ v3d_get_multisync_submit_deps(struct drm_file *file_priv,
597 if (multisync.pad)597 if (multisync.pad)
598 return -EINVAL;598 return -EINVAL;
599 599 
600+ if (!multisync.in_sync_count && !multisync.out_sync_count)
601+ return -EINVAL;
602+ 
600 ret = v3d_get_multisync_post_deps(file_priv, data, multisync.out_sync_count,603 ret = v3d_get_multisync_post_deps(file_priv, data, multisync.out_sync_count,
601 multisync.out_syncs);604 multisync.out_syncs);
602 if (ret)605 if (ret)
@@ -118,7 +118,10 @@ static void virtio_gpu_remove(struct virtio_device *vdev)
118 struct drm_device *dev = vdev->priv;118 struct drm_device *dev = vdev->priv;
119 119 
120 drm_dev_unplug(dev);120 drm_dev_unplug(dev);
121- drm_atomic_helper_shutdown(dev);121+ 
122+ if (drm_core_check_feature(dev, DRIVER_ATOMIC))
123+ drm_atomic_helper_shutdown(dev);
124+ 
122 virtio_gpu_deinit(dev);125 virtio_gpu_deinit(dev);
123 drm_dev_put(dev);126 drm_dev_put(dev);
124}127}
@@ -349,7 +349,7 @@ static int adm1266_nvmem_read_blackbox(struct adm1266_data *data, u8 *read_buff)
349{349{
350 int record_count;350 int record_count;
351 char index;351 char index;
352- u8 buf[5];352+ u8 buf[I2C_SMBUS_BLOCK_MAX];
353 int ret;353 int ret;
354 354 
355 ret = i2c_smbus_read_block_data(data->client, ADM1266_BLACKBOX_INFO, buf);355 ret = i2c_smbus_read_block_data(data->client, ADM1266_BLACKBOX_INFO, buf);
@@ -918,13 +918,13 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
918 */918 */
919 if (hwpec)919 if (hwpec)
920 outb_p(inb_p(SMBAUXCTL(priv)) & ~SMBAUXCTL_CRC, SMBAUXCTL(priv));920 outb_p(inb_p(SMBAUXCTL(priv)) & ~SMBAUXCTL_CRC, SMBAUXCTL(priv));
921-out:
922 /*921 /*
923 * Unlock the SMBus device for use by BIOS/ACPI,922 * Unlock the SMBus device for use by BIOS/ACPI,
924 * and clear status flags if not done already.923 * and clear status flags if not done already.
925 */924 */
926 outb_p(SMBHSTSTS_INUSE_STS | STATUS_FLAGS, SMBHSTSTS(priv));925 outb_p(SMBHSTSTS_INUSE_STS | STATUS_FLAGS, SMBHSTSTS(priv));
927 926 
927+out:
928 pm_runtime_mark_last_busy(&priv->pci_dev->dev);928 pm_runtime_mark_last_busy(&priv->pci_dev->dev);
929 pm_runtime_put_autosuspend(&priv->pci_dev->dev);929 pm_runtime_put_autosuspend(&priv->pci_dev->dev);
930 mutex_unlock(&priv->acpi_lock);930 mutex_unlock(&priv->acpi_lock);
@@ -85,9 +85,9 @@ enum {
85};85};
86 86 
87enum {87enum {
88- ADMV1013_SE_MODE_POS = 6,88+ ADMV1013_SE_MODE_POS,
89- ADMV1013_SE_MODE_NEG = 9,89+ ADMV1013_SE_MODE_NEG,
90- ADMV1013_SE_MODE_DIFF = 1290+ ADMV1013_SE_MODE_DIFF,
91};91};
92 92 
93struct admv1013_state {93struct admv1013_state {
@@ -476,10 +476,23 @@ static int admv1013_init(struct admv1013_state *st)
476 if (ret)476 if (ret)
477 return ret;477 return ret;
478 478 
479- data = FIELD_PREP(ADMV1013_QUAD_SE_MODE_MSK, st->quad_se_mode);479+ switch (st->quad_se_mode) {
480+ case ADMV1013_SE_MODE_POS:
481+ data = 6;
482+ break;
483+ case ADMV1013_SE_MODE_NEG:
484+ data = 9;
485+ break;
486+ case ADMV1013_SE_MODE_DIFF:
487+ data = 12;
488+ break;
489+ default:
490+ return -EINVAL;
491+ }
480 492 
481 ret = __admv1013_spi_update_bits(st, ADMV1013_REG_QUAD,493 ret = __admv1013_spi_update_bits(st, ADMV1013_REG_QUAD,
482- ADMV1013_QUAD_SE_MODE_MSK, data);494+ ADMV1013_QUAD_SE_MODE_MSK,
495+ FIELD_PREP(ADMV1013_QUAD_SE_MODE_MSK, data));
483 if (ret)496 if (ret)
484 return ret;497 return ret;
485 498 
@@ -534,28 +547,30 @@ static int admv1013_properties_parse(struct admv1013_state *st)
534 st->det_en = device_property_read_bool(&spi->dev, "adi,detector-enable");547 st->det_en = device_property_read_bool(&spi->dev, "adi,detector-enable");
535 548 
536 ret = device_property_read_string(&spi->dev, "adi,input-mode", &str);549 ret = device_property_read_string(&spi->dev, "adi,input-mode", &str);
537- if (ret)550+ if (!ret) {
551+ if (!strcmp(str, "iq"))
552+ st->input_mode = ADMV1013_IQ_MODE;
553+ else if (!strcmp(str, "if"))
554+ st->input_mode = ADMV1013_IF_MODE;
555+ else
556+ return -EINVAL;
557+ } else {
538 st->input_mode = ADMV1013_IQ_MODE;558 st->input_mode = ADMV1013_IQ_MODE;
539- 559+ }
540- if (!strcmp(str, "iq"))
541- st->input_mode = ADMV1013_IQ_MODE;
542- else if (!strcmp(str, "if"))
543- st->input_mode = ADMV1013_IF_MODE;
544- else
545- return -EINVAL;
546 560 
547 ret = device_property_read_string(&spi->dev, "adi,quad-se-mode", &str);561 ret = device_property_read_string(&spi->dev, "adi,quad-se-mode", &str);
548- if (ret)562+ if (!ret) {
563+ if (!strcmp(str, "diff"))
564+ st->quad_se_mode = ADMV1013_SE_MODE_DIFF;
565+ else if (!strcmp(str, "se-pos"))
566+ st->quad_se_mode = ADMV1013_SE_MODE_POS;
567+ else if (!strcmp(str, "se-neg"))
568+ st->quad_se_mode = ADMV1013_SE_MODE_NEG;
569+ else
570+ return -EINVAL;
571+ } else {
549 st->quad_se_mode = ADMV1013_SE_MODE_DIFF;572 st->quad_se_mode = ADMV1013_SE_MODE_DIFF;
550- 573+ }
551- if (!strcmp(str, "diff"))
552- st->quad_se_mode = ADMV1013_SE_MODE_DIFF;
553- else if (!strcmp(str, "se-pos"))
554- st->quad_se_mode = ADMV1013_SE_MODE_POS;
555- else if (!strcmp(str, "se-neg"))
556- st->quad_se_mode = ADMV1013_SE_MODE_NEG;
557- else
558- return -EINVAL;
559 574 
560 st->reg = devm_regulator_get(&spi->dev, "vcm");575 st->reg = devm_regulator_get(&spi->dev, "vcm");
561 if (IS_ERR(st->reg))576 if (IS_ERR(st->reg))
@@ -72,14 +72,46 @@ void rxe_mr_init_dma(int access, struct rxe_mr *mr)
72 mr->ibmr.type = IB_MR_TYPE_DMA;72 mr->ibmr.type = IB_MR_TYPE_DMA;
73}73}
74 74 
75+/*
76+ * Convert iova to page_info index. The page_info stores pages of size
77+ * PAGE_SIZE, but MRs can have different page sizes. This function
78+ * handles the conversion for all cases:
79+ *
80+ * 1. mr->page_size > PAGE_SIZE:
81+ * The MR's iova may not be aligned to mr->page_size. We use the
82+ * aligned base (iova & page_mask) as reference, then calculate
83+ * which PAGE_SIZE sub-page the iova falls into.
84+ *
85+ * 2. mr->page_size <= PAGE_SIZE:
86+ * Use simple shift arithmetic since each page_info entry corresponds
87+ * to one or more MR pages.
88+ */
75static unsigned long rxe_mr_iova_to_index(struct rxe_mr *mr, u64 iova)89static unsigned long rxe_mr_iova_to_index(struct rxe_mr *mr, u64 iova)
76{90{
77- return (iova >> mr->page_shift) - (mr->ibmr.iova >> mr->page_shift);91+ int idx;
92+ 
93+ if (mr_page_size(mr) > PAGE_SIZE)
94+ idx = (iova - (mr->ibmr.iova & mr->page_mask)) >> PAGE_SHIFT;
95+ else
96+ idx = (iova >> mr->page_shift) -
97+ (mr->ibmr.iova >> mr->page_shift);
98+ 
99+ WARN_ON(idx >= mr->nbuf);
100+ return idx;
78}101}
79 102 
103+/*
104+ * Convert iova to offset within the page_info entry.
105+ *
106+ * For mr_page_size > PAGE_SIZE, the offset is within the system page.
107+ * For mr_page_size <= PAGE_SIZE, the offset is within the MR page size.
108+ */
80static unsigned long rxe_mr_iova_to_page_offset(struct rxe_mr *mr, u64 iova)109static unsigned long rxe_mr_iova_to_page_offset(struct rxe_mr *mr, u64 iova)
81{110{
82- return iova & (mr_page_size(mr) - 1);111+ if (mr_page_size(mr) > PAGE_SIZE)
112+ return iova & (PAGE_SIZE - 1);
113+ else
114+ return iova & (mr_page_size(mr) - 1);
83}115}
84 116 
85static bool is_pmem_page(struct page *pg)117static bool is_pmem_page(struct page *pg)
@@ -93,37 +125,69 @@ static bool is_pmem_page(struct page *pg)
93 125 
94static int rxe_mr_fill_pages_from_sgt(struct rxe_mr *mr, struct sg_table *sgt)126static int rxe_mr_fill_pages_from_sgt(struct rxe_mr *mr, struct sg_table *sgt)
95{127{
96- XA_STATE(xas, &mr->page_list, 0);
97 struct sg_page_iter sg_iter;128 struct sg_page_iter sg_iter;
98 struct page *page;129 struct page *page;
99 bool persistent = !!(mr->access & IB_ACCESS_FLUSH_PERSISTENT);130 bool persistent = !!(mr->access & IB_ACCESS_FLUSH_PERSISTENT);
100 131 
132+ WARN_ON(mr_page_size(mr) != PAGE_SIZE);
133+ 
101 __sg_page_iter_start(&sg_iter, sgt->sgl, sgt->orig_nents, 0);134 __sg_page_iter_start(&sg_iter, sgt->sgl, sgt->orig_nents, 0);
102 if (!__sg_page_iter_next(&sg_iter))135 if (!__sg_page_iter_next(&sg_iter))
103 return 0;136 return 0;
104 137 
105- do {138+ while (true) {
106- xas_lock(&xas);139+ page = sg_page_iter_page(&sg_iter);
107- while (true) {
108- page = sg_page_iter_page(&sg_iter);
109 140 
110- if (persistent && !is_pmem_page(page)) {141+ if (persistent && !is_pmem_page(page)) {
111- rxe_dbg_mr(mr, "Page can't be persistent\n");142+ rxe_dbg_mr(mr, "Page can't be persistent\n");
112- xas_set_err(&xas, -EINVAL);143+ return -EINVAL;
113- break;
114- }
115- 
116- xas_store(&xas, page);
117- if (xas_error(&xas))
118- break;
119- xas_next(&xas);
120- if (!__sg_page_iter_next(&sg_iter))
121- break;
122 }144 }
123- xas_unlock(&xas);
124- } while (xas_nomem(&xas, GFP_KERNEL));
125 145 
126- return xas_error(&xas);146+ mr->page_info[mr->nbuf].page = page;
147+ mr->page_info[mr->nbuf].offset = 0;
148+ mr->nbuf++;
149+ 
150+ if (!__sg_page_iter_next(&sg_iter))
151+ break;
152+ }
153+ 
154+ return 0;
155+}
156+ 
157+static int __alloc_mr_page_info(struct rxe_mr *mr, int num_pages)
158+{
159+ mr->page_info = kcalloc(num_pages, sizeof(struct rxe_mr_page),
160+ GFP_KERNEL);
161+ if (!mr->page_info)
162+ return -ENOMEM;
163+ 
164+ mr->max_allowed_buf = num_pages;
165+ mr->nbuf = 0;
166+ 
167+ return 0;
168+}
169+ 
170+static int alloc_mr_page_info(struct rxe_mr *mr, int num_pages)
171+{
172+ int ret;
173+ 
174+ WARN_ON(mr->num_buf);
175+ ret = __alloc_mr_page_info(mr, num_pages);
176+ if (ret)
177+ return ret;
178+ 
179+ mr->num_buf = num_pages;
180+ 
181+ return 0;
182+}
183+ 
184+static void free_mr_page_info(struct rxe_mr *mr)
185+{
186+ if (!mr->page_info)
187+ return;
188+ 
189+ kfree(mr->page_info);
190+ mr->page_info = NULL;
127}191}
128 192 
129int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova,193int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova,
@@ -134,8 +198,6 @@ int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova,
134 198 
135 rxe_mr_init(access, mr);199 rxe_mr_init(access, mr);
136 200 
137- xa_init(&mr->page_list);
138- 
139 umem = ib_umem_get(&rxe->ib_dev, start, length, access);201 umem = ib_umem_get(&rxe->ib_dev, start, length, access);
140 if (IS_ERR(umem)) {202 if (IS_ERR(umem)) {
141 rxe_dbg_mr(mr, "Unable to pin memory region err = %d\n",203 rxe_dbg_mr(mr, "Unable to pin memory region err = %d\n",
@@ -143,46 +205,24 @@ int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova,
143 return PTR_ERR(umem);205 return PTR_ERR(umem);
144 }206 }
145 207 
208+ err = alloc_mr_page_info(mr, ib_umem_num_pages(umem));
209+ if (err)
210+ goto err2;
211+ 
146 err = rxe_mr_fill_pages_from_sgt(mr, &umem->sgt_append.sgt);212 err = rxe_mr_fill_pages_from_sgt(mr, &umem->sgt_append.sgt);
147- if (err) {213+ if (err)
148- ib_umem_release(umem);214+ goto err1;
149- return err;
150- }
151 215 
152 mr->umem = umem;216 mr->umem = umem;
153 mr->ibmr.type = IB_MR_TYPE_USER;217 mr->ibmr.type = IB_MR_TYPE_USER;
154 mr->state = RXE_MR_STATE_VALID;218 mr->state = RXE_MR_STATE_VALID;
155 219 
156 return 0;220 return 0;
157-}221+err1:
158- 222+ free_mr_page_info(mr);
159-static int rxe_mr_alloc(struct rxe_mr *mr, int num_buf)223+err2:
160-{224+ ib_umem_release(umem);
161- XA_STATE(xas, &mr->page_list, 0);225+ return err;
162- int i = 0;
163- int err;
164- 
165- xa_init(&mr->page_list);
166- 
167- do {
168- xas_lock(&xas);
169- while (i != num_buf) {
170- xas_store(&xas, XA_ZERO_ENTRY);
171- if (xas_error(&xas))
172- break;
173- xas_next(&xas);
174- i++;
175- }
176- xas_unlock(&xas);
177- } while (xas_nomem(&xas, GFP_KERNEL));
178- 
179- err = xas_error(&xas);
180- if (err)
181- return err;
182- 
183- mr->num_buf = num_buf;
184- 
185- return 0;
186}226}
187 227 
188int rxe_mr_init_fast(int max_pages, struct rxe_mr *mr)228int rxe_mr_init_fast(int max_pages, struct rxe_mr *mr)
@@ -192,7 +232,7 @@ int rxe_mr_init_fast(int max_pages, struct rxe_mr *mr)
192 /* always allow remote access for FMRs */232 /* always allow remote access for FMRs */
193 rxe_mr_init(RXE_ACCESS_REMOTE, mr);233 rxe_mr_init(RXE_ACCESS_REMOTE, mr);
194 234 
195- err = rxe_mr_alloc(mr, max_pages);235+ err = alloc_mr_page_info(mr, max_pages);
196 if (err)236 if (err)
197 goto err1;237 goto err1;
198 238 
@@ -205,26 +245,43 @@ int rxe_mr_init_fast(int max_pages, struct rxe_mr *mr)
205 return err;245 return err;
206}246}
207 247 
248+/*
249+ * I) MRs with page_size >= PAGE_SIZE,
250+ * Split a large MR page (mr->page_size) into multiple PAGE_SIZE
251+ * sub-pages and store them in page_info, offset is always 0.
252+ *
253+ * Called when mr->page_size > PAGE_SIZE. Each call to rxe_set_page()
254+ * represents one mr->page_size region, which we must split into
255+ * (mr->page_size >> PAGE_SHIFT) individual pages.
256+ *
257+ * II) MRs with page_size < PAGE_SIZE,
258+ * Save each PAGE_SIZE page and its offset within the system page in page_info.
259+ */
208static int rxe_set_page(struct ib_mr *ibmr, u64 dma_addr)260static int rxe_set_page(struct ib_mr *ibmr, u64 dma_addr)
209{261{
210 struct rxe_mr *mr = to_rmr(ibmr);262 struct rxe_mr *mr = to_rmr(ibmr);
211- struct page *page = ib_virt_dma_to_page(dma_addr);
212 bool persistent = !!(mr->access & IB_ACCESS_FLUSH_PERSISTENT);263 bool persistent = !!(mr->access & IB_ACCESS_FLUSH_PERSISTENT);
213- int err;264+ u32 i, pages_per_mr = mr_page_size(mr) >> PAGE_SHIFT;
214 265 
215- if (persistent && !is_pmem_page(page)) {266+ pages_per_mr = MAX(1, pages_per_mr);
216- rxe_dbg_mr(mr, "Page cannot be persistent\n");267+ 
217- return -EINVAL;268+ for (i = 0; i < pages_per_mr; i++) {
269+ u64 addr = dma_addr + i * PAGE_SIZE;
270+ struct page *sub_page = ib_virt_dma_to_page(addr);
271+ 
272+ if (unlikely(mr->nbuf >= mr->max_allowed_buf))
273+ return -ENOMEM;
274+ 
275+ if (persistent && !is_pmem_page(sub_page)) {
276+ rxe_dbg_mr(mr, "Page cannot be persistent\n");
277+ return -EINVAL;
278+ }
279+ 
280+ mr->page_info[mr->nbuf].page = sub_page;
281+ mr->page_info[mr->nbuf].offset = addr & (PAGE_SIZE - 1);
282+ mr->nbuf++;
218 }283 }
219 284 
220- if (unlikely(mr->nbuf == mr->num_buf))
221- return -ENOMEM;
222- 
223- err = xa_err(xa_store(&mr->page_list, mr->nbuf, page, GFP_KERNEL));
224- if (err)
225- return err;
226- 
227- mr->nbuf++;
228 return 0;285 return 0;
229}286}
230 287 
@@ -234,6 +291,31 @@ int rxe_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sgl,
234 struct rxe_mr *mr = to_rmr(ibmr);291 struct rxe_mr *mr = to_rmr(ibmr);
235 unsigned int page_size = mr_page_size(mr);292 unsigned int page_size = mr_page_size(mr);
236 293 
294+ /*
295+ * Ensure page_size and PAGE_SIZE are compatible for mapping.
296+ * We require one to be a multiple of the other for correct
297+ * iova-to-page conversion.
298+ */
299+ if (!IS_ALIGNED(page_size, PAGE_SIZE) &&
300+ !IS_ALIGNED(PAGE_SIZE, page_size)) {
301+ rxe_dbg_mr(mr, "MR page size %u must be compatible with PAGE_SIZE %lu\n",
302+ page_size, PAGE_SIZE);
303+ return -EINVAL;
304+ }
305+ 
306+ if (mr_page_size(mr) > PAGE_SIZE) {
307+ /* resize page_info if needed */
308+ u32 map_mr_pages = (page_size >> PAGE_SHIFT) * mr->num_buf;
309+ 
310+ if (map_mr_pages > mr->max_allowed_buf) {
311+ rxe_dbg_mr(mr, "requested pages %u exceed max %u\n",
312+ map_mr_pages, mr->max_allowed_buf);
313+ free_mr_page_info(mr);
314+ if (__alloc_mr_page_info(mr, map_mr_pages))
315+ return -ENOMEM;
316+ }
317+ }
318+ 
237 mr->nbuf = 0;319 mr->nbuf = 0;
238 mr->page_shift = ilog2(page_size);320 mr->page_shift = ilog2(page_size);
239 mr->page_mask = ~((u64)page_size - 1);321 mr->page_mask = ~((u64)page_size - 1);
@@ -245,30 +327,30 @@ int rxe_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sgl,
245static int rxe_mr_copy_xarray(struct rxe_mr *mr, u64 iova, void *addr,327static int rxe_mr_copy_xarray(struct rxe_mr *mr, u64 iova, void *addr,
246 unsigned int length, enum rxe_mr_copy_dir dir)328 unsigned int length, enum rxe_mr_copy_dir dir)
247{329{
248- unsigned int page_offset = rxe_mr_iova_to_page_offset(mr, iova);
249- unsigned long index = rxe_mr_iova_to_index(mr, iova);
250 unsigned int bytes;330 unsigned int bytes;
251- struct page *page;331+ u8 *va;
252- void *va;
253 332 
254 while (length) {333 while (length) {
255- page = xa_load(&mr->page_list, index);334+ unsigned long index = rxe_mr_iova_to_index(mr, iova);
256- if (!page)335+ struct rxe_mr_page *info = &mr->page_info[index];
336+ unsigned int page_offset = rxe_mr_iova_to_page_offset(mr, iova);
337+ 
338+ if (!info->page)
257 return -EFAULT;339 return -EFAULT;
258 340 
259- bytes = min_t(unsigned int, length,341+ page_offset += info->offset;
260- mr_page_size(mr) - page_offset);342+ bytes = min_t(unsigned int, length, PAGE_SIZE - page_offset);
261- va = kmap_local_page(page);343+ va = kmap_local_page(info->page);
344+ 
262 if (dir == RXE_FROM_MR_OBJ)345 if (dir == RXE_FROM_MR_OBJ)
263 memcpy(addr, va + page_offset, bytes);346 memcpy(addr, va + page_offset, bytes);
264 else347 else
265 memcpy(va + page_offset, addr, bytes);348 memcpy(va + page_offset, addr, bytes);
266 kunmap_local(va);349 kunmap_local(va);
267 350 
268- page_offset = 0;
269 addr += bytes;351 addr += bytes;
352+ iova += bytes;
270 length -= bytes;353 length -= bytes;
271- index++;
272 }354 }
273 355 
274 return 0;356 return 0;
@@ -423,9 +505,6 @@ int copy_data(
423 505 
424int rxe_flush_pmem_iova(struct rxe_mr *mr, u64 iova, unsigned int length)506int rxe_flush_pmem_iova(struct rxe_mr *mr, u64 iova, unsigned int length)
425{507{
426- unsigned int page_offset;
427- unsigned long index;
428- struct page *page;
429 unsigned int bytes;508 unsigned int bytes;
430 int err;509 int err;
431 u8 *va;510 u8 *va;
@@ -445,15 +524,16 @@ int rxe_flush_pmem_iova(struct rxe_mr *mr, u64 iova, unsigned int length)
445 return err;524 return err;
446 525 
447 while (length > 0) {526 while (length > 0) {
448- index = rxe_mr_iova_to_index(mr, iova);527+ unsigned long index = rxe_mr_iova_to_index(mr, iova);
449- page = xa_load(&mr->page_list, index);528+ struct rxe_mr_page *info = &mr->page_info[index];
450- page_offset = rxe_mr_iova_to_page_offset(mr, iova);529+ unsigned int page_offset = rxe_mr_iova_to_page_offset(mr, iova);
451- if (!page)
452- return -EFAULT;
453- bytes = min_t(unsigned int, length,
454- mr_page_size(mr) - page_offset);
455 530 
456- va = kmap_local_page(page);531+ if (!info->page)
532+ return -EFAULT;
533+ page_offset += info->offset;
534+ bytes = min_t(unsigned int, length, PAGE_SIZE - page_offset);
535+ 
536+ va = kmap_local_page(info->page);
457 arch_wb_cache_pmem(va + page_offset, bytes);537 arch_wb_cache_pmem(va + page_offset, bytes);
458 kunmap_local(va);538 kunmap_local(va);
459 539 
@@ -487,6 +567,7 @@ int rxe_mr_do_atomic_op(struct rxe_mr *mr, u64 iova, int opcode,
487 } else {567 } else {
488 unsigned long index;568 unsigned long index;
489 int err;569 int err;
570+ struct rxe_mr_page *info;
490 571 
491 err = mr_check_range(mr, iova, sizeof(value));572 err = mr_check_range(mr, iova, sizeof(value));
492 if (err) {573 if (err) {
@@ -495,9 +576,12 @@ int rxe_mr_do_atomic_op(struct rxe_mr *mr, u64 iova, int opcode,
495 }576 }
496 page_offset = rxe_mr_iova_to_page_offset(mr, iova);577 page_offset = rxe_mr_iova_to_page_offset(mr, iova);
497 index = rxe_mr_iova_to_index(mr, iova);578 index = rxe_mr_iova_to_index(mr, iova);
498- page = xa_load(&mr->page_list, index);579+ info = &mr->page_info[index];
499- if (!page)580+ if (!info->page)
500 return RESPST_ERR_RKEY_VIOLATION;581 return RESPST_ERR_RKEY_VIOLATION;
582+ 
583+ page_offset += info->offset;
584+ page = info->page;
501 }585 }
502 586 
503 if (unlikely(page_offset & 0x7)) {587 if (unlikely(page_offset & 0x7)) {
@@ -544,6 +628,7 @@ int rxe_mr_do_atomic_write(struct rxe_mr *mr, u64 iova, u64 value)
544 } else {628 } else {
545 unsigned long index;629 unsigned long index;
546 int err;630 int err;
631+ struct rxe_mr_page *info;
547 632 
548 /* See IBA oA19-28 */633 /* See IBA oA19-28 */
549 err = mr_check_range(mr, iova, sizeof(value));634 err = mr_check_range(mr, iova, sizeof(value));
@@ -553,9 +638,12 @@ int rxe_mr_do_atomic_write(struct rxe_mr *mr, u64 iova, u64 value)
553 }638 }
554 page_offset = rxe_mr_iova_to_page_offset(mr, iova);639 page_offset = rxe_mr_iova_to_page_offset(mr, iova);
555 index = rxe_mr_iova_to_index(mr, iova);640 index = rxe_mr_iova_to_index(mr, iova);
556- page = xa_load(&mr->page_list, index);641+ info = &mr->page_info[index];
557- if (!page)642+ if (!info->page)
558 return RESPST_ERR_RKEY_VIOLATION;643 return RESPST_ERR_RKEY_VIOLATION;
644+ 
645+ page_offset += info->offset;
646+ page = info->page;
559 }647 }
560 648 
561 /* See IBA A19.4.2 */649 /* See IBA A19.4.2 */
@@ -727,5 +815,5 @@ void rxe_mr_cleanup(struct rxe_pool_elem *elem)
727 ib_umem_release(mr->umem);815 ib_umem_release(mr->umem);
728 816 
729 if (mr->ibmr.type != IB_MR_TYPE_DMA)817 if (mr->ibmr.type != IB_MR_TYPE_DMA)
730- xa_destroy(&mr->page_list);818+ free_mr_page_info(mr);
731}819}
@@ -297,6 +297,11 @@ static inline int rkey_is_mw(u32 rkey)
297 return (index >= RXE_MIN_MW_INDEX) && (index <= RXE_MAX_MW_INDEX);297 return (index >= RXE_MIN_MW_INDEX) && (index <= RXE_MAX_MW_INDEX);
298}298}
299 299 
300+struct rxe_mr_page {
301+ struct page *page;
302+ unsigned int offset; /* offset in system page */
303+};
304+ 
300struct rxe_mr {305struct rxe_mr {
301 struct rxe_pool_elem elem;306 struct rxe_pool_elem elem;
302 struct ib_mr ibmr;307 struct ib_mr ibmr;
@@ -313,10 +318,13 @@ struct rxe_mr {
313 unsigned int page_shift;318 unsigned int page_shift;
314 u64 page_mask;319 u64 page_mask;
315 320 
321+ /* size of page_info when mr allocated */
316 u32 num_buf;322 u32 num_buf;
323+ /* real size of page_info */
324+ u32 max_allowed_buf;
317 u32 nbuf;325 u32 nbuf;
318 326 
319- struct xarray page_list;327+ struct rxe_mr_page *page_info;
320};328};
321 329 
322static inline unsigned int mr_page_size(struct rxe_mr *mr)330static inline unsigned int mr_page_size(struct rxe_mr *mr)
@@ -1041,7 +1041,12 @@ static int lpg_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
1041 return ret;1041 return ret;
1042 1042 
1043 if (chan->subtype == LPG_SUBTYPE_HI_RES_PWM) {1043 if (chan->subtype == LPG_SUBTYPE_HI_RES_PWM) {
1044- refclk = lpg_clk_rates_hi_res[FIELD_GET(PWM_CLK_SELECT_HI_RES_MASK, val)];1044+ unsigned int clk_idx = FIELD_GET(PWM_CLK_SELECT_HI_RES_MASK, val);
1045+ 
1046+ if (clk_idx >= ARRAY_SIZE(lpg_clk_rates_hi_res))
1047+ return -EINVAL;
1048+ 
1049+ refclk = lpg_clk_rates_hi_res[clk_idx];
1045 resolution = lpg_pwm_resolution_hi_res[FIELD_GET(PWM_SIZE_HI_RES_MASK, val)];1050 resolution = lpg_pwm_resolution_hi_res[FIELD_GET(PWM_SIZE_HI_RES_MASK, val)];
1046 } else {1051 } else {
1047 refclk = lpg_clk_rates[FIELD_GET(PWM_CLK_SELECT_MASK, val)];1052 refclk = lpg_clk_rates[FIELD_GET(PWM_CLK_SELECT_MASK, val)];
@@ -2459,8 +2459,10 @@ static int tun_xdp_one(struct tun_struct *tun,
2459 bool skb_xdp = false;2459 bool skb_xdp = false;
2460 struct page *page;2460 struct page *page;
2461 2461 
2462- if (unlikely(datasize < ETH_HLEN))2462+ if (unlikely(datasize < ETH_HLEN)) {
2463+ put_page(virt_to_head_page(xdp->data));
2463 return -EINVAL;2464 return -EINVAL;
2465+ }
2464 2466 
2465 xdp_prog = rcu_dereference(tun->xdp_prog);2467 xdp_prog = rcu_dereference(tun->xdp_prog);
2466 if (xdp_prog) {2468 if (xdp_prog) {
@@ -2126,6 +2126,11 @@ static int __init epf_ntb_init(void)
2126 2126 
2127 kpcintb_workqueue = alloc_workqueue("kpcintb", WQ_MEM_RECLAIM |2127 kpcintb_workqueue = alloc_workqueue("kpcintb", WQ_MEM_RECLAIM |
2128 WQ_HIGHPRI, 0);2128 WQ_HIGHPRI, 0);
2129+ if (!kpcintb_workqueue) {
2130+ pr_err("Failed to allocate kpcintb workqueue\n");
2131+ return -ENOMEM;
2132+ }
2133+ 
2129 ret = pci_epf_register_driver(&epf_ntb_driver);2134 ret = pci_epf_register_driver(&epf_ntb_driver);
2130 if (ret) {2135 if (ret) {
2131 destroy_workqueue(kpcintb_workqueue);2136 destroy_workqueue(kpcintb_workqueue);
@@ -1450,6 +1450,11 @@ static int __init epf_ntb_init(void)
1450 1450 
1451 kpcintb_workqueue = alloc_workqueue("kpcintb", WQ_MEM_RECLAIM |1451 kpcintb_workqueue = alloc_workqueue("kpcintb", WQ_MEM_RECLAIM |
1452 WQ_HIGHPRI, 0);1452 WQ_HIGHPRI, 0);
1453+ if (!kpcintb_workqueue) {
1454+ pr_err("Failed to allocate kpcintb workqueue\n");
1455+ return -ENOMEM;
1456+ }
1457+ 
1453 ret = pci_epf_register_driver(&epf_ntb_driver);1458 ret = pci_epf_register_driver(&epf_ntb_driver);
1454 if (ret) {1459 if (ret) {
1455 destroy_workqueue(kpcintb_workqueue);1460 destroy_workqueue(kpcintb_workqueue);
@@ -747,6 +747,37 @@ fc_cn_stats_update(u16 event_type, struct fc_fpin_stats *stats)
747 }747 }
748}748}
749 749 
750+static void
751+fc_fpin_pname_stats_update(struct Scsi_Host *shost,
752+ struct fc_rport *attach_rport, u16 event_type,
753+ u32 desc_len, u32 fixed_len, u32 pname_count,
754+ __be64 *pname_list,
755+ void (*stats_update)(u16 event_type,
756+ struct fc_fpin_stats *stats))
757+{
758+ u32 i;
759+ struct fc_rport *rport;
760+ u64 wwpn;
761+ 
762+ if (desc_len < fixed_len)
763+ pname_count = 0;
764+ else
765+ pname_count = min(pname_count, (desc_len - fixed_len) /
766+ sizeof(pname_list[0]));
767+ 
768+ for (i = 0; i < pname_count; i++) {
769+ wwpn = be64_to_cpu(pname_list[i]);
770+ rport = fc_find_rport_by_wwpn(shost, wwpn);
771+ if (rport &&
772+ (rport->roles & FC_PORT_ROLE_FCP_TARGET ||
773+ rport->roles & FC_PORT_ROLE_NVME_TARGET)) {
774+ if (rport == attach_rport)
775+ continue;
776+ stats_update(event_type, &rport->fpin_stats);
777+ }
778+ }
779+}
780+ 
750/*781/*
751 * fc_fpin_li_stats_update - routine to update Link Integrity782 * fc_fpin_li_stats_update - routine to update Link Integrity
752 * event statistics.783 * event statistics.
@@ -757,13 +788,11 @@ fc_cn_stats_update(u16 event_type, struct fc_fpin_stats *stats)
757static void788static void
758fc_fpin_li_stats_update(struct Scsi_Host *shost, struct fc_tlv_desc *tlv)789fc_fpin_li_stats_update(struct Scsi_Host *shost, struct fc_tlv_desc *tlv)
759{790{
760- u8 i;
761 struct fc_rport *rport = NULL;791 struct fc_rport *rport = NULL;
762 struct fc_rport *attach_rport = NULL;792 struct fc_rport *attach_rport = NULL;
763 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);793 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
764 struct fc_fn_li_desc *li_desc = (struct fc_fn_li_desc *)tlv;794 struct fc_fn_li_desc *li_desc = (struct fc_fn_li_desc *)tlv;
765 u16 event_type = be16_to_cpu(li_desc->event_type);795 u16 event_type = be16_to_cpu(li_desc->event_type);
766- u64 wwpn;
767 796 
768 rport = fc_find_rport_by_wwpn(shost,797 rport = fc_find_rport_by_wwpn(shost,
769 be64_to_cpu(li_desc->attached_wwpn));798 be64_to_cpu(li_desc->attached_wwpn));
@@ -774,22 +803,11 @@ fc_fpin_li_stats_update(struct Scsi_Host *shost, struct fc_tlv_desc *tlv)
774 fc_li_stats_update(event_type, &attach_rport->fpin_stats);803 fc_li_stats_update(event_type, &attach_rport->fpin_stats);
775 }804 }
776 805 
777- if (be32_to_cpu(li_desc->pname_count) > 0) {806+ fc_fpin_pname_stats_update(shost, attach_rport, event_type,
778- for (i = 0;807+ be32_to_cpu(li_desc->desc_len),
779- i < be32_to_cpu(li_desc->pname_count);808+ FC_TLV_DESC_LENGTH_FROM_SZ(*li_desc),
780- i++) {809+ be32_to_cpu(li_desc->pname_count),
781- wwpn = be64_to_cpu(li_desc->pname_list[i]);810+ li_desc->pname_list, fc_li_stats_update);
782- rport = fc_find_rport_by_wwpn(shost, wwpn);
783- if (rport &&
784- (rport->roles & FC_PORT_ROLE_FCP_TARGET ||
785- rport->roles & FC_PORT_ROLE_NVME_TARGET)) {
786- if (rport == attach_rport)
787- continue;
788- fc_li_stats_update(event_type,
789- &rport->fpin_stats);
790- }
791- }
792- }
793 811 
794 if (fc_host->port_name == be64_to_cpu(li_desc->attached_wwpn))812 if (fc_host->port_name == be64_to_cpu(li_desc->attached_wwpn))
795 fc_li_stats_update(event_type, &fc_host->fpin_stats);813 fc_li_stats_update(event_type, &fc_host->fpin_stats);
@@ -837,13 +855,11 @@ static void
837fc_fpin_peer_congn_stats_update(struct Scsi_Host *shost,855fc_fpin_peer_congn_stats_update(struct Scsi_Host *shost,
838 struct fc_tlv_desc *tlv)856 struct fc_tlv_desc *tlv)
839{857{
840- u8 i;
841 struct fc_rport *rport = NULL;858 struct fc_rport *rport = NULL;
842 struct fc_rport *attach_rport = NULL;859 struct fc_rport *attach_rport = NULL;
843 struct fc_fn_peer_congn_desc *pc_desc =860 struct fc_fn_peer_congn_desc *pc_desc =
844 (struct fc_fn_peer_congn_desc *)tlv;861 (struct fc_fn_peer_congn_desc *)tlv;
845 u16 event_type = be16_to_cpu(pc_desc->event_type);862 u16 event_type = be16_to_cpu(pc_desc->event_type);
846- u64 wwpn;
847 863 
848 rport = fc_find_rport_by_wwpn(shost,864 rport = fc_find_rport_by_wwpn(shost,
849 be64_to_cpu(pc_desc->attached_wwpn));865 be64_to_cpu(pc_desc->attached_wwpn));
@@ -854,22 +870,11 @@ fc_fpin_peer_congn_stats_update(struct Scsi_Host *shost,
854 fc_cn_stats_update(event_type, &attach_rport->fpin_stats);870 fc_cn_stats_update(event_type, &attach_rport->fpin_stats);
855 }871 }
856 872 
857- if (be32_to_cpu(pc_desc->pname_count) > 0) {873+ fc_fpin_pname_stats_update(shost, attach_rport, event_type,
858- for (i = 0;874+ be32_to_cpu(pc_desc->desc_len),
859- i < be32_to_cpu(pc_desc->pname_count);875+ FC_TLV_DESC_LENGTH_FROM_SZ(*pc_desc),
860- i++) {876+ be32_to_cpu(pc_desc->pname_count),
861- wwpn = be64_to_cpu(pc_desc->pname_list[i]);877+ pc_desc->pname_list, fc_cn_stats_update);
862- rport = fc_find_rport_by_wwpn(shost, wwpn);
863- if (rport &&
864- (rport->roles & FC_PORT_ROLE_FCP_TARGET ||
865- rport->roles & FC_PORT_ROLE_NVME_TARGET)) {
866- if (rport == attach_rport)
867- continue;
868- fc_cn_stats_update(event_type,
869- &rport->fpin_stats);
870- }
871- }
872- }
873}878}
874 879 
875/*880/*
@@ -1338,11 +1338,6 @@ static void s3c64xx_spi_remove(struct platform_device *pdev)
1338 1338 
1339 writel(0, sdd->regs + S3C64XX_SPI_INT_EN);1339 writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
1340 1340 
1341- if (!is_polling(sdd)) {
1342- dma_release_channel(sdd->rx_dma.ch);
1343- dma_release_channel(sdd->tx_dma.ch);
1344- }
1345- 
1346 pm_runtime_put_noidle(&pdev->dev);1341 pm_runtime_put_noidle(&pdev->dev);
lijiawei
lijiaweilijiawei7月27日

[drivers/spi/spi-s3c64xx.c:1341] 此处 pm_runtime_put_noidle 之前原有 dma_release_channel(sdd->rx_dma.ch)dma_release_channel(sdd->tx_dma.ch) 调用被移除。由于这些 DMA 通道是通过 dma_request_chan()(非 devm 版本)分配的,移除释放调用会导致资源泄漏。如果驱动使用 devm 管理这些通道,请确认;否则需恢复 dma_release_channel 调用。

likedislike
wanghao794
7月28日 评论:
1347 pm_runtime_disable(&pdev->dev);1342 pm_runtime_disable(&pdev->dev);
1348 pm_runtime_set_suspended(&pdev->dev);1343 pm_runtime_set_suspended(&pdev->dev);
@@ -461,11 +461,11 @@ static int wpcm_fiu_probe(struct platform_device *pdev)
461 461 
462 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory");462 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory");
463 fiu->memory = devm_ioremap_resource(dev, res);463 fiu->memory = devm_ioremap_resource(dev, res);
464- fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL);
465 if (IS_ERR(fiu->memory)) {464 if (IS_ERR(fiu->memory)) {
466 dev_err(dev, "Failed to map flash memory window\n");465 dev_err(dev, "Failed to map flash memory window\n");
467 return PTR_ERR(fiu->memory);466 return PTR_ERR(fiu->memory);
468 }467 }
468+ fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL);
469 469 
470 fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm");470 fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm");
471 471 
@@ -686,8 +686,10 @@ static int dw8250_probe(struct platform_device *pdev)
686 */686 */
687 if (data->clk) {687 if (data->clk) {
688 err = clk_notifier_register(data->clk, &data->clk_notifier);688 err = clk_notifier_register(data->clk, &data->clk_notifier);
689- if (err)689+ if (err) {
690+ serial8250_unregister_port(data->data.line);
690 return dev_err_probe(dev, err, "Failed to set the clock notifier\n");691 return dev_err_probe(dev, err, "Failed to set the clock notifier\n");
692+ }
691 queue_work(system_unbound_wq, &data->clk_work);693 queue_work(system_unbound_wq, &data->clk_work);
692 }694 }
693 695 
@@ -710,6 +710,8 @@ static void ep_free(struct eventpoll *ep)
710 kfree(ep);710 kfree(ep);
711}711}
712 712 
713+static struct file *epi_fget(const struct epitem *epi);
lijiawei
lijiaweilijiawei7月27日

[fs/eventpoll.c:713] 添加了 static struct file *epi_fget(const struct epitem *epi); 的前向声明,但该函数的实现未出现在本补丁中。请确认 epi_fget 的函数体是否已在此文件的其他位置定义,否则将导致编译错误。

likedislike
wanghao794
7月28日 评论:
714+ 
713/*715/*
714 * Removes a "struct epitem" from the eventpoll RB tree and deallocates716 * Removes a "struct epitem" from the eventpoll RB tree and deallocates
715 * all the associated resources. Must be called with "mtx" held.717 * all the associated resources. Must be called with "mtx" held.
@@ -720,7 +722,7 @@ static void ep_free(struct eventpoll *ep)
720 */722 */
721static bool __ep_remove(struct eventpoll *ep, struct epitem *epi, bool force)723static bool __ep_remove(struct eventpoll *ep, struct epitem *epi, bool force)
722{724{
723- struct file *file = epi->ffd.file;725+ struct file *file;
724 struct epitems_head *to_free;726 struct epitems_head *to_free;
725 struct hlist_head *head;727 struct hlist_head *head;
726 728 
@@ -731,10 +733,23 @@ static bool __ep_remove(struct eventpoll *ep, struct epitem *epi, bool force)
731 */733 */
732 ep_unregister_pollwait(ep, epi);734 ep_unregister_pollwait(ep, epi);
733 735 
736+ /* cheap sync with eventpoll_release_file() */
737+ if (!force && unlikely(READ_ONCE(epi->dying)))
738+ return false;
739+ 
740+ /*
741+ * If we manage to grab a reference it means we're not in
742+ * eventpoll_release_file() and aren't going to be.
743+ */
744+ file = epi_fget(epi);
745+ if (!file)
746+ return false;
747+ 
734 /* Remove the current item from the list of epoll hooks */748 /* Remove the current item from the list of epoll hooks */
735 spin_lock(&file->f_lock);749 spin_lock(&file->f_lock);
736 if (epi->dying && !force) {750 if (epi->dying && !force) {
737 spin_unlock(&file->f_lock);751 spin_unlock(&file->f_lock);
752+ fput(file);
738 return false;753 return false;
739 }754 }
740 755 
@@ -772,6 +787,7 @@ static bool __ep_remove(struct eventpoll *ep, struct epitem *epi, bool force)
772 call_rcu(&epi->rcu, epi_rcu_free);787 call_rcu(&epi->rcu, epi_rcu_free);
773 788 
774 percpu_counter_dec(&ep->user->epoll_watches);789 percpu_counter_dec(&ep->user->epoll_watches);
790+ fput(file);
775 return true;791 return true;
776}792}
777 793 
@@ -478,8 +478,9 @@ void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks)
478{478{
479 atomic_add(blks, &sdp->sd_log_blks_free);479 atomic_add(blks, &sdp->sd_log_blks_free);
480 trace_gfs2_log_blocks(sdp, blks);480 trace_gfs2_log_blocks(sdp, blks);
481- gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <=481+ gfs2_assert_withdraw(sdp, !sdp->sd_jdesc ||
482- sdp->sd_jdesc->jd_blocks);482+ atomic_read(&sdp->sd_log_blks_free) <=
483+ sdp->sd_jdesc->jd_blocks);
483 if (atomic_read(&sdp->sd_log_blks_needed))484 if (atomic_read(&sdp->sd_log_blks_needed))
484 wake_up(&sdp->sd_log_waitq);485 wake_up(&sdp->sd_log_waitq);
485}486}
@@ -1122,6 +1122,7 @@ int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
1122 struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);1122 struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);
1123 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;1123 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
1124 int rc;1124 int rc;
1125+ DECLARE_CRYPTO_WAIT(wait);
1125 struct scatterlist *sg;1126 struct scatterlist *sg;
1126 u8 sign[SMB2_SIGNATURE_SIZE] = {};1127 u8 sign[SMB2_SIGNATURE_SIZE] = {};
1127 u8 key[SMB3_ENC_DEC_KEY_SIZE];1128 u8 key[SMB3_ENC_DEC_KEY_SIZE];
@@ -1208,12 +1209,12 @@ int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
1208 1209 
1209 aead_request_set_crypt(req, sg, sg, crypt_len, iv);1210 aead_request_set_crypt(req, sg, sg, crypt_len, iv);
1210 aead_request_set_ad(req, assoc_data_len);1211 aead_request_set_ad(req, assoc_data_len);
1211- aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);1212+ aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
1213+ CRYPTO_TFM_REQ_MAY_SLEEP,
1214+ crypto_req_done, &wait);
1212 1215 
1213- if (enc)1216+ rc = crypto_wait_req(enc ? crypto_aead_encrypt(req) :
1214- rc = crypto_aead_encrypt(req);1217+ crypto_aead_decrypt(req), &wait);
1215- else
1216- rc = crypto_aead_decrypt(req);
1217 if (rc)1218 if (rc)
1218 goto free_iv;1219 goto free_iv;
1219 1220 
@@ -464,8 +464,12 @@ static inline int compare_guid_key(struct oplock_info *opinfo,
464 const char *guid1, const char *key1)464 const char *guid1, const char *key1)
465{465{
466 const char *guid2, *key2;466 const char *guid2, *key2;
467+ struct ksmbd_conn *conn;
467 468 
468- guid2 = opinfo->conn->ClientGUID;469+ conn = READ_ONCE(opinfo->conn);
470+ if (!conn)
471+ return 0;
472+ guid2 = conn->ClientGUID;
469 key2 = opinfo->o_lease->lease_key;473 key2 = opinfo->o_lease->lease_key;
470 if (!memcmp(guid1, guid2, SMB2_CLIENT_GUID_SIZE) &&474 if (!memcmp(guid1, guid2, SMB2_CLIENT_GUID_SIZE) &&
471 !memcmp(key1, key2, SMB2_LEASE_KEY_SIZE))475 !memcmp(key1, key2, SMB2_LEASE_KEY_SIZE))
@@ -14,7 +14,6 @@ struct tcf_pedit_key_ex {
14struct tcf_pedit_parms {14struct tcf_pedit_parms {
15 struct tc_pedit_key *tcfp_keys;15 struct tc_pedit_key *tcfp_keys;
16 struct tcf_pedit_key_ex *tcfp_keys_ex;16 struct tcf_pedit_key_ex *tcfp_keys_ex;
17- u32 tcfp_off_max_hint;
18 unsigned char tcfp_nkeys;17 unsigned char tcfp_nkeys;
19 unsigned char tcfp_flags;18 unsigned char tcfp_flags;
20 struct rcu_head rcu;19 struct rcu_head rcu;
@@ -1241,7 +1241,7 @@ static ssize_t extract_kvec_to_sg(struct iov_iter *iter,
1241 else1241 else
1242 page = virt_to_page((void *)kaddr);1242 page = virt_to_page((void *)kaddr);
1243 1243 
1244- sg_set_page(sg, page, len, off);1244+ sg_set_page(sg, page, seg, off);
1245 sgtable->nents++;1245 sgtable->nents++;
1246 sg++;1246 sg++;
1247 sg_max--;1247 sg_max--;
@@ -1250,6 +1250,7 @@ static ssize_t extract_kvec_to_sg(struct iov_iter *iter,
1250 kaddr += PAGE_SIZE;1250 kaddr += PAGE_SIZE;
1251 off = 0;1251 off = 0;
1252 } while (len > 0 && sg_max > 0);1252 } while (len > 0 && sg_max > 0);
1253+ ret -= len;
1253 1254 
1254 if (maxsize <= 0 || sg_max == 0)1255 if (maxsize <= 0 || sg_max == 0)
1255 break;1256 break;
@@ -1342,7 +1343,7 @@ ssize_t extract_iter_to_sg(struct iov_iter *iter, size_t maxsize,
1342 struct sg_table *sgtable, unsigned int sg_max,1343 struct sg_table *sgtable, unsigned int sg_max,
1343 iov_iter_extraction_t extraction_flags)1344 iov_iter_extraction_t extraction_flags)
1344{1345{
1345- if (maxsize == 0)1346+ if (maxsize == 0 || sg_max == 0)
1346 return 0;1347 return 0;
1347 1348 
1348 switch (iov_iter_type(iter)) {1349 switch (iov_iter_type(iter)) {
@@ -210,6 +210,12 @@ static int memfd_add_seals(struct file *file, unsigned int seals)
210 goto unlock;210 goto unlock;
211 }211 }
212 212 
213+ /*
214+ * SEAL_EXEC implies SEAL_WRITE, making W^X from the start.
215+ */
216+ if (seals & F_SEAL_EXEC && inode->i_mode & 0111)
217+ seals |= F_SEAL_SHRINK|F_SEAL_GROW|F_SEAL_WRITE|F_SEAL_FUTURE_WRITE;
218+ 
213 if ((seals & F_SEAL_WRITE) && !(*file_seals & F_SEAL_WRITE)) {219 if ((seals & F_SEAL_WRITE) && !(*file_seals & F_SEAL_WRITE)) {
214 error = mapping_deny_writable(file->f_mapping);220 error = mapping_deny_writable(file->f_mapping);
215 if (error)221 if (error)
@@ -222,12 +228,6 @@ static int memfd_add_seals(struct file *file, unsigned int seals)
222 }228 }
223 }229 }
224 230 
225- /*
226- * SEAL_EXEC implys SEAL_WRITE, making W^X from the start.
227- */
228- if (seals & F_SEAL_EXEC && inode->i_mode & 0111)
229- seals |= F_SEAL_SHRINK|F_SEAL_GROW|F_SEAL_WRITE|F_SEAL_FUTURE_WRITE;
230- 
231 *file_seals |= seals;231 *file_seals |= seals;
232 error = 0;232 error = 0;
233 233 
@@ -4348,6 +4348,8 @@ u32 xdp_master_redirect(struct xdp_buff *xdp)
4348 struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);4348 struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
4349 4349 
4350 master = netdev_master_upper_dev_get_rcu(xdp->rxq->dev);4350 master = netdev_master_upper_dev_get_rcu(xdp->rxq->dev);
4351+ if (unlikely(!(master->flags & IFF_UP)))
4352+ return XDP_ABORTED;
4351 slave = master->netdev_ops->ndo_xdp_get_xmit_slave(master, xdp);4353 slave = master->netdev_ops->ndo_xdp_get_xmit_slave(master, xdp);
4352 if (slave && slave != xdp->rxq->dev) {4354 if (slave && slave != xdp->rxq->dev) {
4353 /* The target device is different from the receiving device, so4355 /* The target device is different from the receiving device, so
@@ -1350,16 +1350,13 @@ bool __skb_flow_dissect(const struct net *net,
1350 break;1350 break;
1351 }1351 }
1352 1352 
1353- /* least significant bit of the most significant octet1353+ /* PFC (compressed 1-byte protocol) frames are not processed.
1354- * indicates if protocol field was compressed1354+ * A compressed protocol field has the least significant bit of
1355+ * the most significant octet set, which will fail the following
1356+ * ppp_proto_is_valid(), returning FLOW_DISSECT_RET_OUT_BAD.
1355 */1357 */
1356 ppp_proto = ntohs(hdr->proto);1358 ppp_proto = ntohs(hdr->proto);
1357- if (ppp_proto & 0x0100) {1359+ nhoff += PPPOE_SES_HLEN;
1358- ppp_proto = ppp_proto >> 8;
1359- nhoff += PPPOE_SES_HLEN - 1;
1360- } else {
1361- nhoff += PPPOE_SES_HLEN;
1362- }
1363 1360 
1364 if (ppp_proto == PPP_IP) {1361 if (ppp_proto == PPP_IP) {
1365 proto = htons(ETH_P_IP);1362 proto = htons(ETH_P_IP);
@@ -113,6 +113,9 @@ int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb)
113 if (p->pp_recycle != skb->pp_recycle)113 if (p->pp_recycle != skb->pp_recycle)
114 return -ETOOMANYREFS;114 return -ETOOMANYREFS;
115 115 
116+ if (skb_zcopy(p) || skb_zcopy(skb))
117+ return -ETOOMANYREFS;
118+ 
116 if (unlikely(p->len + len >= netif_get_gro_max_size(p->dev, p) ||119 if (unlikely(p->len + len >= netif_get_gro_max_size(p->dev, p) ||
117 NAPI_GRO_CB(skb)->flush))120 NAPI_GRO_CB(skb)->flush))
118 return -E2BIG;121 return -E2BIG;
@@ -1112,8 +1112,8 @@ static int __ip_append_data(struct sock *sk,
1112 !(rt->dst.dev->features & NETIF_F_SG)))1112 !(rt->dst.dev->features & NETIF_F_SG)))
1113 alloclen = fraglen;1113 alloclen = fraglen;
1114 else {1114 else {
1115- alloclen = fragheaderlen + transhdrlen;1115+ alloclen = fragheaderlen + transhdrlen + fraggap;
1116- pagedlen = datalen - transhdrlen;1116+ pagedlen = datalen - transhdrlen - fraggap;
1117 }1117 }
1118 1118 
1119 alloclen += alloc_extra;1119 alloclen += alloc_extra;
@@ -1694,8 +1694,8 @@ static int __ip6_append_data(struct sock *sk,
1694 !(rt->dst.dev->features & NETIF_F_SG)))1694 !(rt->dst.dev->features & NETIF_F_SG)))
1695 alloclen = fraglen;1695 alloclen = fraglen;
1696 else {1696 else {
1697- alloclen = fragheaderlen + transhdrlen;1697+ alloclen = fragheaderlen + transhdrlen + fraggap;
1698- pagedlen = datalen - transhdrlen;1698+ pagedlen = datalen - transhdrlen - fraggap;
1699 }1699 }
1700 alloclen += alloc_extra;1700 alloclen += alloc_extra;
1701 1701 
@@ -484,6 +484,9 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
484 const struct fib6_nh *nh = sibling->fib6_nh;484 const struct fib6_nh *nh = sibling->fib6_nh;
485 int nh_upper_bound;485 int nh_upper_bound;
486 486 
487+ if (!READ_ONCE(first->fib6_nsiblings))
488+ break;
489+ 
487 nh_upper_bound = atomic_read(&nh->fib_nh_upper_bound);490 nh_upper_bound = atomic_read(&nh->fib_nh_upper_bound);
488 if (hash > nh_upper_bound)491 if (hash > nh_upper_bound)
489 continue;492 continue;
@@ -4822,6 +4822,7 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
4822 u8 sa[ETH_ALEN];4822 u8 sa[ETH_ALEN];
4823 } addrs __aligned(2);4823 } addrs __aligned(2);
4824 struct ieee80211_sta_rx_stats *stats;4824 struct ieee80211_sta_rx_stats *stats;
4825+ u32 encoded_rate;
4825 4826 
4826 /* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write4827 /* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write
4827 * to a common data structure; drivers can implement that per queue4828 * to a common data structure; drivers can implement that per queue
@@ -4924,6 +4925,9 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
4924 /* push the addresses in front */4925 /* push the addresses in front */
4925 memcpy(skb_push(skb, sizeof(addrs)), &addrs, sizeof(addrs));4926 memcpy(skb_push(skb, sizeof(addrs)), &addrs, sizeof(addrs));
4926 4927 
4928+ /* capture before mesh forward may memset or free skb->cb */
4929+ encoded_rate = sta_stats_encode_rate(status);
4930+ 
4927 res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb);4931 res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb);
4928 switch (res) {4932 switch (res) {
4929 case RX_QUEUED:4933 case RX_QUEUED:
@@ -156,7 +156,6 @@ static int nft_inner_parse_l2l3(const struct nft_inner *priv,
156 return -1;156 return -1;
157 157 
158 if (fragoff == 0) {158 if (fragoff == 0) {
159- thoff = nhoff + sizeof(_ip6h);
160 ctx->flags |= NFT_PAYLOAD_CTX_INNER_TH;159 ctx->flags |= NFT_PAYLOAD_CTX_INNER_TH;
161 ctx->inner_thoff = thoff;160 ctx->inner_thoff = thoff;
162 ctx->l4proto = l4proto;161 ctx->l4proto = l4proto;
@@ -16,6 +16,8 @@
16#include <linux/ip.h>16#include <linux/ip.h>
17#include <linux/ipv6.h>17#include <linux/ipv6.h>
18#include <linux/slab.h>18#include <linux/slab.h>
19+#include <linux/overflow.h>
20+#include <asm/unaligned.h>
19#include <net/ipv6.h>21#include <net/ipv6.h>
20#include <net/netlink.h>22#include <net/netlink.h>
21#include <net/pkt_sched.h>23#include <net/pkt_sched.h>
@@ -242,7 +244,6 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
242 goto out_free_ex;244 goto out_free_ex;
243 }245 }
244 246 
245- nparms->tcfp_off_max_hint = 0;
246 nparms->tcfp_flags = parm->flags;247 nparms->tcfp_flags = parm->flags;
247 nparms->tcfp_nkeys = parm->nkeys;248 nparms->tcfp_nkeys = parm->nkeys;
248 249 
@@ -268,14 +269,6 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
268 BITS_PER_TYPE(int) - 1,269 BITS_PER_TYPE(int) - 1,
269 nparms->tcfp_keys[i].shift);270 nparms->tcfp_keys[i].shift);
270 271 
271- /* The AT option can read a single byte, we can bound the actual
272- * value with uchar max.
273- */
274- cur += (0xff & offmask) >> nparms->tcfp_keys[i].shift;
275- 
276- /* Each key touches 4 bytes starting from the computed offset */
277- nparms->tcfp_off_max_hint =
278- max(nparms->tcfp_off_max_hint, cur + 4);
279 }272 }
280 273 
281 p = to_pedit(*a);274 p = to_pedit(*a);
@@ -318,15 +311,12 @@ static void tcf_pedit_cleanup(struct tc_action *a)
318 call_rcu(&parms->rcu, tcf_pedit_cleanup_rcu);311 call_rcu(&parms->rcu, tcf_pedit_cleanup_rcu);
319}312}
320 313 
321-static bool offset_valid(struct sk_buff *skb, int offset)314+static bool offset_valid(struct sk_buff *skb, int offset, int len)
322{315{
323- if (offset > 0 && offset > skb->len)316+ if (offset < -(int)skb_headroom(skb))
324 return false;317 return false;
325 318 
326- if (offset < 0 && -offset > skb_headroom(skb))319+ return offset <= (int)skb->len - len;
327- return false;
328- 
329- return true;
330}320}
331 321 
332static int pedit_l4_skb_offset(struct sk_buff *skb, int *hoffset, const int header_type)322static int pedit_l4_skb_offset(struct sk_buff *skb, int *hoffset, const int header_type)
@@ -393,18 +383,10 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb,
393 struct tcf_pedit_key_ex *tkey_ex;383 struct tcf_pedit_key_ex *tkey_ex;
394 struct tcf_pedit_parms *parms;384 struct tcf_pedit_parms *parms;
395 struct tc_pedit_key *tkey;385 struct tc_pedit_key *tkey;
396- u32 max_offset;
397 int i;386 int i;
398 387 
399 parms = rcu_dereference_bh(p->parms);388 parms = rcu_dereference_bh(p->parms);
400 389 
401- max_offset = (skb_transport_header_was_set(skb) ?
402- skb_transport_offset(skb) :
403- skb_network_offset(skb)) +
404- parms->tcfp_off_max_hint;
405- if (skb_ensure_writable(skb, min(skb->len, max_offset)))
406- goto done;
407- 
408 tcf_lastuse_update(&p->tcf_tm);390 tcf_lastuse_update(&p->tcf_tm);
409 tcf_action_update_bstats(&p->common, skb);391 tcf_action_update_bstats(&p->common, skb);
410 392 
@@ -412,10 +394,11 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb,
412 tkey_ex = parms->tcfp_keys_ex;394 tkey_ex = parms->tcfp_keys_ex;
413 395 
414 for (i = parms->tcfp_nkeys; i > 0; i--, tkey++) {396 for (i = parms->tcfp_nkeys; i > 0; i--, tkey++) {
397+ int write_offset, write_len;
415 int offset = tkey->off;398 int offset = tkey->off;
416 int hoffset = 0;399 int hoffset = 0;
417- u32 *ptr, hdata;400+ u32 cur_val, val;
418- u32 val;401+ u32 *ptr;
419 int rc;402 int rc;
420 403 
421 if (tkey_ex) {404 if (tkey_ex) {
@@ -433,13 +416,15 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb,
433 416 
434 if (tkey->offmask) {417 if (tkey->offmask) {
435 u8 *d, _d;418 u8 *d, _d;
419+ int at_offset;
436 420 
437- if (!offset_valid(skb, hoffset + tkey->at)) {421+ if (check_add_overflow(hoffset, (int)tkey->at, &at_offset) ||
422+ !offset_valid(skb, at_offset, sizeof(_d))) {
438 pr_info_ratelimited("tc action pedit 'at' offset %d out of bounds\n",423 pr_info_ratelimited("tc action pedit 'at' offset %d out of bounds\n",
439 hoffset + tkey->at);424 hoffset + tkey->at);
440 goto bad;425 goto bad;
441 }426 }
442- d = skb_header_pointer(skb, hoffset + tkey->at,427+ d = skb_header_pointer(skb, at_offset,
443 sizeof(_d), &_d);428 sizeof(_d), &_d);
444 if (!d)429 if (!d)
445 goto bad;430 goto bad;
@@ -451,31 +436,51 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb,
451 }436 }
452 }437 }
453 438 
454- if (!offset_valid(skb, hoffset + offset)) {439+ if (check_add_overflow(hoffset, offset, &write_offset)) {
455- pr_info_ratelimited("tc action pedit offset %d out of bounds\n", hoffset + offset);440+ pr_info_ratelimited("tc action pedit offset overflow\n");
456 goto bad;441 goto bad;
457 }442 }
458 443 
459- ptr = skb_header_pointer(skb, hoffset + offset,444+ if (!offset_valid(skb, write_offset, sizeof(*ptr))) {
460- sizeof(hdata), &hdata);445+ pr_info_ratelimited("tc action pedit offset %d out of bounds\n",
461- if (!ptr)446+ write_offset);
462 goto bad;447 goto bad;
448+ }
449+ 
450+ if (write_offset < 0) {
451+ if (skb_cow(skb, -write_offset))
452+ goto bad;
453+ if (write_offset + (int)sizeof(*ptr) > 0) {
454+ if (skb_ensure_writable(skb,
455+ min_t(int, skb->len,
456+ write_offset + (int)sizeof(*ptr))))
457+ goto bad;
458+ }
459+ } else {
460+ if (check_add_overflow(write_offset, (int)sizeof(*ptr),
461+ &write_len))
462+ goto bad;
463+ if (skb_ensure_writable(skb, min_t(int, skb->len,
464+ write_len)))
465+ goto bad;
466+ }
467+ 
468+ ptr = (u32 *)(skb->data + write_offset);
469+ cur_val = get_unaligned(ptr);
463 /* just do it, baby */470 /* just do it, baby */
464 switch (cmd) {471 switch (cmd) {
465 case TCA_PEDIT_KEY_EX_CMD_SET:472 case TCA_PEDIT_KEY_EX_CMD_SET:
466 val = tkey->val;473 val = tkey->val;
467 break;474 break;
468 case TCA_PEDIT_KEY_EX_CMD_ADD:475 case TCA_PEDIT_KEY_EX_CMD_ADD:
469- val = (*ptr + tkey->val) & ~tkey->mask;476+ val = (cur_val + tkey->val) & ~tkey->mask;
470 break;477 break;
471 default:478 default:
472 pr_info_ratelimited("tc action pedit bad command (%d)\n", cmd);479 pr_info_ratelimited("tc action pedit bad command (%d)\n", cmd);
473 goto bad;480 goto bad;
474 }481 }
475 482 
476- *ptr = ((*ptr & tkey->mask) ^ val);483+ put_unaligned((cur_val & tkey->mask) ^ val, ptr);
477- if (ptr == &hdata)
478- skb_store_bits(skb, hoffset + offset, ptr, 4);
479 }484 }
480 485 
481 goto done;486 goto done;
@@ -1204,6 +1204,14 @@ static struct sctp_association *__sctp_rcv_asconf_lookup(
1204 /* Skip over the ADDIP header and find the Address parameter */1204 /* Skip over the ADDIP header and find the Address parameter */
1205 param = (union sctp_addr_param *)(asconf + 1);1205 param = (union sctp_addr_param *)(asconf + 1);
1206 1206 
1207+ /* The whole address parameter must lie within the chunk before
1208+ * af->from_addr_param() reads the variable-length address; otherwise a
1209+ * truncated trailing ASCONF chunk lets it read uninitialized bytes past
1210+ * the parameter.
1211+ */
1212+ if (sizeof(*asconf) + ntohs(param->p.length) > ntohs(ch->length))
1213+ return NULL;
1214+ 
1207 af = sctp_get_af_specific(param_type2af(param->p.type));1215 af = sctp_get_af_specific(param_type2af(param->p.type));
1208 if (unlikely(!af))1216 if (unlikely(!af))
1209 return NULL;1217 return NULL;
@@ -263,9 +263,12 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *t)
263 skb_set_inner_ipproto(skb, IPPROTO_SCTP);263 skb_set_inner_ipproto(skb, IPPROTO_SCTP);
264 label = ip6_make_flowlabel(sock_net(sk), skb, fl6->flowlabel, true, fl6);264 label = ip6_make_flowlabel(sock_net(sk), skb, fl6->flowlabel, true, fl6);
265 265 
266- return udp_tunnel6_xmit_skb(dst, sk, skb, NULL, &fl6->saddr,266+ local_bh_disable();
267- &fl6->daddr, tclass, ip6_dst_hoplimit(dst),267+ udp_tunnel6_xmit_skb(dst, sk, skb, NULL, &fl6->saddr,
268- label, sctp_sk(sk)->udp_port, t->encap_port, false);268+ &fl6->daddr, tclass, ip6_dst_hoplimit(dst),
269+ label, sctp_sk(sk)->udp_port, t->encap_port, false);
270+ local_bh_enable();
271+ return 0;
269}272}
270 273 
271/* Returns the dst cache entry for the given source and destination ip274/* Returns the dst cache entry for the given source and destination ip
@@ -1085,9 +1085,11 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, struct sctp_transport *t)
1085 skb_reset_inner_mac_header(skb);1085 skb_reset_inner_mac_header(skb);
1086 skb_reset_inner_transport_header(skb);1086 skb_reset_inner_transport_header(skb);
1087 skb_set_inner_ipproto(skb, IPPROTO_SCTP);1087 skb_set_inner_ipproto(skb, IPPROTO_SCTP);
1088+ local_bh_disable();
1088 udp_tunnel_xmit_skb((struct rtable *)dst, sk, skb, fl4->saddr,1089 udp_tunnel_xmit_skb((struct rtable *)dst, sk, skb, fl4->saddr,
1089 fl4->daddr, dscp, ip4_dst_hoplimit(dst), df,1090 fl4->daddr, dscp, ip4_dst_hoplimit(dst), df,
1090 sctp_sk(sk)->udp_port, t->encap_port, false, false);1091 sctp_sk(sk)->udp_port, t->encap_port, false, false);
1092+ local_bh_enable();
1091 return 0;1093 return 0;
1092}1094}
1093 1095 
@@ -3361,11 +3361,10 @@ int smc_create_clcsk(struct net *net, struct sock *sk, int family)
3361 return 0;3361 return 0;
3362}3362}
3363 3363 
3364-static int __smc_create(struct net *net, struct socket *sock, int protocol,3364+static int smc_create(struct net *net, struct socket *sock, int protocol,
3365- int kern, struct socket *clcsock)3365+ int kern)
3366{3366{
3367 int family = (protocol == SMCPROTO_SMC6) ? PF_INET6 : PF_INET;3367 int family = (protocol == SMCPROTO_SMC6) ? PF_INET6 : PF_INET;
3368- struct smc_sock *smc;
3369 struct sock *sk;3368 struct sock *sk;
3370 int rc;3369 int rc;
3371 3370 
@@ -3384,88 +3383,17 @@ static int __smc_create(struct net *net, struct socket *sock, int protocol,
3384 if (!sk)3383 if (!sk)
3385 goto out;3384 goto out;
3386 3385 
3387- /* create internal TCP socket for CLC handshake and fallback */3386+ rc = smc_create_clcsk(net, sk, family);
3388- smc = smc_sk(sk);
3389- 
3390- rc = 0;
3391- if (clcsock)
3392- smc->clcsock = clcsock;
3393- else
3394- rc = smc_create_clcsk(net, sk, family);
3395out:3387out:
3396 return rc;3388 return rc;
3397}3389}
3398 3390 
3399-static int smc_create(struct net *net, struct socket *sock, int protocol,
3400- int kern)
3401-{
3402- return __smc_create(net, sock, protocol, kern, NULL);
3403-}
3404- 
3405static const struct net_proto_family smc_sock_family_ops = {3391static const struct net_proto_family smc_sock_family_ops = {
3406 .family = PF_SMC,3392 .family = PF_SMC,
3407 .owner = THIS_MODULE,3393 .owner = THIS_MODULE,
3408 .create = smc_create,3394 .create = smc_create,
3409};3395};
3410 3396 
3411-static int smc_ulp_init(struct sock *sk)
3412-{
3413- struct socket *tcp = sk->sk_socket;
3414- struct net *net = sock_net(sk);
3415- struct socket *smcsock;
3416- int protocol, ret;
3417- 
3418- /* only TCP can be replaced */
3419- if (tcp->type != SOCK_STREAM || sk->sk_protocol != IPPROTO_TCP ||
3420- (sk->sk_family != AF_INET && sk->sk_family != AF_INET6))
3421- return -ESOCKTNOSUPPORT;
3422- /* don't handle wq now */
3423- if (tcp->state != SS_UNCONNECTED || !tcp->file || tcp->wq.fasync_list)
3424- return -ENOTCONN;
3425- 
3426- if (sk->sk_family == AF_INET)
3427- protocol = SMCPROTO_SMC;
3428- else
3429- protocol = SMCPROTO_SMC6;
3430- 
3431- smcsock = sock_alloc();
3432- if (!smcsock)
3433- return -ENFILE;
3434- 
3435- smcsock->type = SOCK_STREAM;
3436- __module_get(THIS_MODULE); /* tried in __tcp_ulp_find_autoload */
3437- ret = __smc_create(net, smcsock, protocol, 1, tcp);
3438- if (ret) {
3439- sock_release(smcsock); /* module_put() which ops won't be NULL */
3440- return ret;
3441- }
3442- 
3443- /* replace tcp socket to smc */
3444- smcsock->file = tcp->file;
3445- smcsock->file->private_data = smcsock;
3446- smcsock->file->f_inode = SOCK_INODE(smcsock); /* replace inode when sock_close */
3447- smcsock->file->f_path.dentry->d_inode = SOCK_INODE(smcsock); /* dput() in __fput */
3448- tcp->file = NULL;
3449- 
3450- return ret;
3451-}
3452- 
3453-static void smc_ulp_clone(const struct request_sock *req, struct sock *newsk,
3454- const gfp_t priority)
3455-{
3456- struct inet_connection_sock *icsk = inet_csk(newsk);
3457- 
3458- /* don't inherit ulp ops to child when listen */
3459- icsk->icsk_ulp_ops = NULL;
3460-}
3461- 
3462-static struct tcp_ulp_ops smc_ulp_ops __read_mostly = {
3463- .name = "smc",
3464- .owner = THIS_MODULE,
3465- .init = smc_ulp_init,
3466- .clone = smc_ulp_clone,
3467-};
3468- 
3469unsigned int smc_net_id;3397unsigned int smc_net_id;
3470 3398 
3471static __net_init int smc_net_init(struct net *net)3399static __net_init int smc_net_init(struct net *net)
@@ -3589,12 +3517,6 @@ static int __init smc_init(void)
3589 goto out_sock;3517 goto out_sock;
3590 }3518 }
3591 3519 
3592- rc = tcp_register_ulp(&smc_ulp_ops);
3593- if (rc) {
3594- pr_err("%s: tcp_ulp_register fails with %d\n", __func__, rc);
3595- goto out_ib;
3596- }
3597- 
3598 static_branch_enable(&tcp_have_smc);3520 static_branch_enable(&tcp_have_smc);
3599 return 0;3521 return 0;
3600 3522 
@@ -3632,7 +3554,6 @@ static int __init smc_init(void)
3632static void __exit smc_exit(void)3554static void __exit smc_exit(void)
3633{3555{
3634 static_branch_disable(&tcp_have_smc);3556 static_branch_disable(&tcp_have_smc);
3635- tcp_unregister_ulp(&smc_ulp_ops);
3636 sock_unregister(PF_SMC);3557 sock_unregister(PF_SMC);
3637 smc_core_exit();3558 smc_core_exit();
3638 smc_ib_unregister_client();3559 smc_ib_unregister_client();
@@ -3657,5 +3578,4 @@ MODULE_AUTHOR("Ursula Braun <ubraun@linux.vnet.ibm.com>");
3657MODULE_DESCRIPTION("smc socket address family");3578MODULE_DESCRIPTION("smc socket address family");
3658MODULE_LICENSE("GPL");3579MODULE_LICENSE("GPL");
3659MODULE_ALIAS_NETPROTO(PF_SMC);3580MODULE_ALIAS_NETPROTO(PF_SMC);
3660-MODULE_ALIAS_TCP_ULP("smc");
3661MODULE_ALIAS_GENL_FAMILY(SMC_GENL_FAMILY_NAME);3581MODULE_ALIAS_GENL_FAMILY(SMC_GENL_FAMILY_NAME);
@@ -3558,15 +3558,14 @@ static int bpf_iter_unix_seq_show(struct seq_file *seq, void *v)
3558 struct bpf_prog *prog;3558 struct bpf_prog *prog;
3559 struct sock *sk = v;3559 struct sock *sk = v;
3560 uid_t uid;3560 uid_t uid;
3561- bool slow;
3562 int ret;3561 int ret;
3563 3562 
3564 if (v == SEQ_START_TOKEN)3563 if (v == SEQ_START_TOKEN)
3565 return 0;3564 return 0;
3566 3565 
3567- slow = lock_sock_fast(sk);3566+ lock_sock(sk);
3568 3567 
3569- if (unlikely(sk_unhashed(sk))) {3568+ if (unlikely(sock_flag(sk, SOCK_DEAD))) {
3570 ret = SEQ_SKIP;3569 ret = SEQ_SKIP;
3571 goto unlock;3570 goto unlock;
3572 }3571 }
@@ -3576,7 +3575,7 @@ static int bpf_iter_unix_seq_show(struct seq_file *seq, void *v)
3576 prog = bpf_iter_get_info(&meta, false);3575 prog = bpf_iter_get_info(&meta, false);
3577 ret = unix_prog_seq_show(prog, &meta, v, uid);3576 ret = unix_prog_seq_show(prog, &meta, v, uid);
3578unlock:3577unlock:
3579- unlock_sock_fast(sk, slow);3578+ release_sock(sk);
3580 return ret;3579 return ret;
3581}3580}
3582 3581 
@@ -552,6 +552,8 @@ static void __unix_gc(struct work_struct *work)
552 struct sk_buff_head hitlist;552 struct sk_buff_head hitlist;
553 struct sk_buff *skb;553 struct sk_buff *skb;
554 554 
555+ WRITE_ONCE(gc_in_progress, true);
556+ 
555 spin_lock(&unix_gc_lock);557 spin_lock(&unix_gc_lock);
556 558 
557 if (!unix_graph_maybe_cyclic) {559 if (!unix_graph_maybe_cyclic) {
@@ -582,7 +584,6 @@ static DECLARE_WORK(unix_gc_work, __unix_gc);
582 584 
583void unix_gc(void)585void unix_gc(void)
584{586{
585- WRITE_ONCE(gc_in_progress, true);
586 queue_work(system_unbound_wq, &unix_gc_work);587 queue_work(system_unbound_wq, &unix_gc_work);
587}588}
588 589 
@@ -674,6 +674,9 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl)
674{674{
675 struct wm_coeff_ctl *ctl = cs_ctl->priv;675 struct wm_coeff_ctl *ctl = cs_ctl->priv;
676 676 
677+ if (!ctl)
678+ return;
679+ 
677 cancel_work_sync(&ctl->work);680 cancel_work_sync(&ctl->work);
678 681 
679 kfree(ctl->name);682 kfree(ctl->name);
@@ -903,9 +903,6 @@ static int audioreach_widget_unload(struct snd_soc_component *scomp,
903 struct audioreach_container *cont;903 struct audioreach_container *cont;
904 struct audioreach_module *mod;904 struct audioreach_module *mod;
905 905 
906- mod = dobj->private;
907- cont = mod->container;
908- 
909 if (w->id == snd_soc_dapm_mixer) {906 if (w->id == snd_soc_dapm_mixer) {
910 /* virtual widget */907 /* virtual widget */
911 struct snd_ar_control *scontrol = dobj->private;908 struct snd_ar_control *scontrol = dobj->private;
@@ -914,6 +911,11 @@ static int audioreach_widget_unload(struct snd_soc_component *scomp,
914 kfree(scontrol);911 kfree(scontrol);
915 return 0;912 return 0;
916 }913 }
914+ mod = dobj->private;
915+ if (!mod)
916+ return 0;
917+ 
918+ cont = mod->container;
917 919 
918 mutex_lock(&apm->lock);920 mutex_lock(&apm->lock);
919 idr_remove(&apm->modules_idr, mod->instance_id);921 idr_remove(&apm->modules_idr, mod->instance_id);