From 6fe3981e40ec5bd2c5e7980601e30cb9e8ebc3d5 Mon Sep 17 00:00:00 2001 From: Krupali Dhanvijay Date: Mon, 19 Aug 2024 16:43:46 +0530 Subject: [PATCH 001/138] qcacld-3.0: Update key management in original auth mode for WAPI Currently for WAPI connection auth mode is updated only in key management, but on connect request for validating auth mode, it compared with original key management and failing to connect because of mismatch in auth and cipher suits. To fix this, update auth mode in original key management as well in crypto for WAPI connection. CRs-Fixed: 3901275 Change-Id: I942fbbc68c18d7c8137053b5fc9cb0260109fdcd --- core/hdd/src/wlan_hdd_cfg80211.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 76831317f09b..9edadf77f669 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -21129,7 +21129,10 @@ static void hdd_set_wapi_crypto_key_mgmt_param(struct hdd_adapter *adapter) if (adapter->wapi_info.wapi_auth_mode == WAPI_AUTH_MODE_CERT) HDD_SET_BIT(set_val, WLAN_CRYPTO_KEY_MGMT_WAPI_CERT); + /* Set AKM and original AKM type */ wlan_crypto_set_vdev_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT, set_val); + wlan_crypto_set_vdev_param(vdev, WLAN_CRYPTO_PARAM_ORIG_KEY_MGMT, + set_val); set_val = 0; HDD_SET_BIT(set_val, WLAN_CRYPTO_CIPHER_WAPI_SMS4); From 8cd10f873d824a3ac8e276ce2f1897815fb2e9d1 Mon Sep 17 00:00:00 2001 From: Ravindra Konda Date: Tue, 12 Nov 2024 01:10:17 -0800 Subject: [PATCH 002/138] Release 2.0.8.34Z Release 2.0.8.34Z Change-Id: I1699d8e33c61adc77a6fc10efdd00dc1dd38428b CRs-Fixed: 774533 --- core/mac/inc/qwlan_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h index a57de3022392..c8f76c9a8572 100644 --- a/core/mac/inc/qwlan_version.h +++ b/core/mac/inc/qwlan_version.h @@ -32,9 +32,9 @@ #define QWLAN_VERSION_MAJOR 2 #define QWLAN_VERSION_MINOR 0 #define QWLAN_VERSION_PATCH 8 -#define QWLAN_VERSION_EXTRA "Y" +#define QWLAN_VERSION_EXTRA "Z" #define QWLAN_VERSION_BUILD 34 -#define QWLAN_VERSIONSTR "2.0.8.34Y" +#define QWLAN_VERSIONSTR "2.0.8.34Z" #endif /* QWLAN_VERSION_H */ From 0fd04bae821fa5a27e4896fd02a3a04982b9c83e Mon Sep 17 00:00:00 2001 From: Ratna Deepthi Kudaravalli Date: Fri, 22 Nov 2024 16:13:57 +0530 Subject: [PATCH 003/138] audio-kernel: avoid out of bound read while checking a bit Check for calibration type is within a valid range to avoid out of bound read in checking a bit in a bitmask. Change-Id: Id8b3af47cd8077f460ac60a33d959ccbb6a21692 Signed-off-by: Shimana P (cherry picked from commit 544f150134722543d0f8c834164293de5b25e417) Signed-off-by: Manish Kumar --- asoc/codecs/wcdcal-hwdep.c | 11 ++++++----- dsp/q6afecal-hwdep.c | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/asoc/codecs/wcdcal-hwdep.c b/asoc/codecs/wcdcal-hwdep.c index 7e2b984a9304..a0455fdd104b 100644 --- a/asoc/codecs/wcdcal-hwdep.c +++ b/asoc/codecs/wcdcal-hwdep.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015, 2017-2018, 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. * */ #include @@ -60,17 +61,17 @@ static int wcdcal_hwdep_ioctl_shared(struct snd_hwdep *hw, struct firmware_cal **fw = fw_data->fw; void *data; - if (!test_bit(fw_user.cal_type, fw_data->cal_bit)) { - pr_err("%s: codec didn't set this %d!!\n", - __func__, fw_user.cal_type); - return -EFAULT; - } if (fw_user.cal_type >= WCD9XXX_MAX_CAL || fw_user.cal_type < WCD9XXX_MIN_CAL) { pr_err("%s: wrong cal type sent %d\n", __func__, fw_user.cal_type); return -EFAULT; } + if (!test_bit(fw_user.cal_type, fw_data->cal_bit)) { + pr_err("%s: codec didn't set this %d!!\n", + __func__, fw_user.cal_type); + return -EFAULT; + } if (fw_user.size > cal_size_info[fw_user.cal_type] || fw_user.size <= 0) { pr_err("%s: incorrect firmware size %d for %s\n", diff --git a/dsp/q6afecal-hwdep.c b/dsp/q6afecal-hwdep.c index ef194ff6ac39..401de1e93b19 100644 --- a/dsp/q6afecal-hwdep.c +++ b/dsp/q6afecal-hwdep.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015, 2017 - 2018, 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -61,17 +62,17 @@ static int q6afecal_hwdep_ioctl_shared(struct snd_hwdep *hw, struct firmware_cal **fw = fw_data->fw; void *data; - if (!test_bit(fw_user.cal_type, fw_data->cal_bit)) { - pr_err("%s: q6afe didn't set this %d!!\n", - __func__, fw_user.cal_type); - return -EFAULT; - } if (fw_user.cal_type >= Q6AFE_MAX_CAL || fw_user.cal_type < Q6AFE_MIN_CAL) { pr_err("%s: wrong cal type sent %d\n", __func__, fw_user.cal_type); return -EFAULT; } + if (!test_bit(fw_user.cal_type, fw_data->cal_bit)) { + pr_err("%s: q6afe didn't set this %d!!\n", + __func__, fw_user.cal_type); + return -EFAULT; + } if (fw_user.size > cal_size_info[fw_user.cal_type] || fw_user.size <= 0) { pr_err("%s: incorrect firmware size %d for %s\n", From 619a8993ed87d1cd4180057a290214ce17e871c5 Mon Sep 17 00:00:00 2001 From: spuligil Date: Sat, 28 Dec 2024 06:01:35 -0800 Subject: [PATCH 004/138] fw-api: CL 28338484 - update fw common interface files Change-Id: I89f748116fc4a8557a6bb19a87744c8d3f36f4ff CRs-Fixed: 3830439 --- fw/wmi_unified.h | 22 ++++++++++++++++++---- fw/wmi_version.h | 2 +- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/fw/wmi_unified.h b/fw/wmi_unified.h index 4d231e1a5fdd..a6ce67bac0a3 100644 --- a/fw/wmi_unified.h +++ b/fw/wmi_unified.h @@ -41740,6 +41740,8 @@ typedef struct { #define WMI_ROAM_NEIGHBOR_REPORT_INFO_NUM_OF_NRIE_SET(detail,val) WMI_SET_BITS(detail, 16, 8, val) #define WMI_ROAM_NEIGHBOR_REPORT_INFO_MLO_BAND_INFO_GET(detail) WMI_GET_BITS(detail, 24, 3) #define WMI_ROAM_NEIGHBOR_REPORT_INFO_MLO_BAND_INFO_SET(detail,val) WMI_SET_BITS(detail, 24, 3, val) +#define WMI_ROAM_NEIGHBOR_REPORT_INFO_TX_STATUS_INFO_GET(detail) WMI_GET_BITS(detail, 27, 4) +#define WMI_ROAM_NEIGHBOR_REPORT_INFO_TX_STATUS_INFO_SET(detail,val) WMI_SET_BITS(detail, 27, 4, val) typedef struct { A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_neighbor_report_info_tlv_param */ @@ -41774,7 +41776,9 @@ typedef struct { * wmi_mlo_band_info enum constants * Refer to WMI_ROAM_NEIGHBOR_REPORT_INFO_MLO_BAND_INFO_GET,SET * macros. - * [31:27] : reserved + * [30:27] : neighbor report request TX STATUS, possible values listed in + * WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS + * [31] : reserved * Refer to the above WMI_ROAM_NEIGHBOR_REPORT_INFO_*_GET,_SET macros for * reading and writing these bitfields. */ @@ -41926,9 +41930,19 @@ typedef enum { } WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE; typedef enum { - WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_ACK = 0, - WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_NO_ACK, - WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_FAIL, + WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_ACK = 0, + WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_NO_ACK = 1, + WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_FAIL = 2, + WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_DROP = + WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_FAIL, + WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_FILTERED = 3, + WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TXOP_ABORT = 4, + WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_TID_DEL = 5, + WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_SW_ABORT = 6, + WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_MIG_DROP = 7, + WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_MLO_TID_MIG = 8, + + /* max allowed value is 15, due to this enum's use in a 4-bit bitfield */ } WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS; typedef struct { diff --git a/fw/wmi_version.h b/fw/wmi_version.h index 37f5972c4b92..393316ceff45 100644 --- a/fw/wmi_version.h +++ b/fw/wmi_version.h @@ -37,7 +37,7 @@ #define __WMI_VER_MINOR_ 0 /** WMI revision number has to be incremented when there is a * change that may or may not break compatibility. */ -#define __WMI_REVISION_ 1564 +#define __WMI_REVISION_ 1565 /** The Version Namespace should not be normally changed. Only * host and firmware of the same WMI namespace will work From 95c0c0878056399cd94faa985f6e7a79136646fa Mon Sep 17 00:00:00 2001 From: spuligil Date: Sat, 28 Dec 2024 06:02:59 -0800 Subject: [PATCH 005/138] fw-api: CL 28339144 - update fw common interface files Change-Id: Ib73c9599a02910ae54b8ba02d6952dac5d8b7c87 CRs-Fixed: 3830439 --- fw/wmi_tlv_defs.h | 4 +++- fw/wmi_unified.h | 17 +++++++++++++++++ fw/wmi_version.h | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/fw/wmi_tlv_defs.h b/fw/wmi_tlv_defs.h index ece35c747408..f71d7221f215 100644 --- a/fw/wmi_tlv_defs.h +++ b/fw/wmi_tlv_defs.h @@ -1475,6 +1475,7 @@ typedef enum { WMITLV_TAG_STRUC_wmi_vdev_vbss_peer_pn_info, WMITLV_TAG_STRUC_wmi_vdev_vbss_peer_sn_info, WMITLV_TAG_STRUC_wmi_vdev_vbss_config_event_fixed_param, + WMITLV_TAG_STRUC_wmi_stats_ext_event_vdev_ext2_t, } WMITLV_TAG_ID; /* * IMPORTANT: Please add _ALL_ WMI Commands Here. @@ -6731,7 +6732,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_PEER_ESTIMATED_LINKSPEED_EVENTID); WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_stats_ext_event_fixed_param, wmi_stats_ext_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_partner_link_stats, partner_link_stats, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, partner_link_data, WMITLV_SIZE_VAR) + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, partner_link_data, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_stats_ext_event_vdev_ext2_t, stats_ext2_data, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_STATS_EXT_EVENTID); #define WMITLV_TABLE_WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID(id,op,buf,len) \ diff --git a/fw/wmi_unified.h b/fw/wmi_unified.h index a6ce67bac0a3..e384b4fa619b 100644 --- a/fw/wmi_unified.h +++ b/fw/wmi_unified.h @@ -30265,6 +30265,7 @@ typedef struct { #define WMI_EXT_STATS_VDEV_EXT_MAX_MCS_COUNTERS 32 #define WMI_EXT_STATS_VDEV_EXT_MAX_OPAQUE_DBG_WORDS32 1 +#define WMI_STATS_EXT_EVENT_VDEV_EXT_NSS_COUNTERS_MAX 4 typedef enum wmi_stats_ext_event_vdev_ext_bw_counters { WMI_STATS_EXT_EVENT_VDEV_EXT_BW_COUNTERS_20MHz = 0, @@ -30328,6 +30329,22 @@ typedef struct wmi_stats_ext_event_vdev_ext { A_UINT32 opaque_dbg[WMI_EXT_STATS_VDEV_EXT_MAX_OPAQUE_DBG_WORDS32]; } wmi_stats_ext_event_vdev_ext_t; +typedef struct { + A_UINT32 tlv_header; /* tag = WMITLV_TAG_STRUC_wmi_stats_ext_event_vdev_ext2_t */ + /* Set of TX BW counters */ + A_UINT32 tx_mcs_mpdu[WMI_EXT_STATS_VDEV_EXT_MAX_MCS_COUNTERS]; + /* Set of TX BW counters */ + A_UINT32 tx_bw_mpdu[WMI_STATS_EXT_EVENT_VDEV_EXT_BW_COUNTERS_MAX]; + /* Set of TX NSS counters */ + A_UINT32 tx_nss_mpdu[WMI_STATS_EXT_EVENT_VDEV_EXT_NSS_COUNTERS_MAX]; + /* Set of RX BW counters */ + A_UINT32 rx_mcs_mpdu[WMI_EXT_STATS_VDEV_EXT_MAX_MCS_COUNTERS]; + /* Set of RX BW counters */ + A_UINT32 rx_bw_mpdu[WMI_STATS_EXT_EVENT_VDEV_EXT_BW_COUNTERS_MAX]; + /* Set of RX NSS counters */ + A_UINT32 rx_nss_mpdu[WMI_STATS_EXT_EVENT_VDEV_EXT_NSS_COUNTERS_MAX]; +} wmi_stats_ext_event_vdev_ext2_t; + typedef enum { /** Default: no replay required. */ WMI_PEER_DELETE_NO_REPLAY = 0, diff --git a/fw/wmi_version.h b/fw/wmi_version.h index 393316ceff45..b560b8515db8 100644 --- a/fw/wmi_version.h +++ b/fw/wmi_version.h @@ -37,7 +37,7 @@ #define __WMI_VER_MINOR_ 0 /** WMI revision number has to be incremented when there is a * change that may or may not break compatibility. */ -#define __WMI_REVISION_ 1565 +#define __WMI_REVISION_ 1566 /** The Version Namespace should not be normally changed. Only * host and firmware of the same WMI namespace will work From b285c87bedcc09e399c0926f4d25ba759423b499 Mon Sep 17 00:00:00 2001 From: spuligil Date: Tue, 31 Dec 2024 06:01:23 -0800 Subject: [PATCH 006/138] fw-api: CL 28343275 - update fw common interface files Change-Id: I31c5d4e0ad2e779dcac0780830525890008d0522 CRs-Fixed: 3830439 --- fw/wmi_unified.h | 9 ++++++++- fw/wmi_version.h | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/fw/wmi_unified.h b/fw/wmi_unified.h index e384b4fa619b..e62c41e9abdd 100644 --- a/fw/wmi_unified.h +++ b/fw/wmi_unified.h @@ -17068,7 +17068,8 @@ typedef struct { mlo_link_del_cancel:1, /* rollback of previous dynamic link deletion */ start_as_active:1, /* indicate link should be started in active status */ mlo_ieee_link_id_valid:1, /* indicate if the ieee_link_id in wmi_vdev_start_mlo_params is valid */ - unused: 13; + mlo_ieee_link_id_valid_partner:1, /* indicate if the ieee_link_id in wmi_partner_link_params is valid */ + unused: 12; }; A_UINT32 mlo_flags; }; @@ -17086,6 +17087,12 @@ typedef struct { A_UINT32 hw_link_id; /** hw_link_id: Unique link id across SOCs, got as part of QMI handshake */ wmi_mac_addr vdev_macaddr; /** VDEV MAC address */ wmi_mlo_flags mlo_flags; + /** ieee_link_id: + * Link ID for partner link. + * This field must be ignored unless the mlo_ieee_link_id_valid_partner + * flag is set in mlo_flags. + */ + A_UINT32 ieee_link_id; } wmi_partner_link_params; /* this TLV structure used for pass mlo parameters on vdev create*/ diff --git a/fw/wmi_version.h b/fw/wmi_version.h index b560b8515db8..eb7b36e88938 100644 --- a/fw/wmi_version.h +++ b/fw/wmi_version.h @@ -37,7 +37,7 @@ #define __WMI_VER_MINOR_ 0 /** WMI revision number has to be incremented when there is a * change that may or may not break compatibility. */ -#define __WMI_REVISION_ 1566 +#define __WMI_REVISION_ 1567 /** The Version Namespace should not be normally changed. Only * host and firmware of the same WMI namespace will work From d6cea55b254ce1d500d7c44b569825b5af2ec6fe Mon Sep 17 00:00:00 2001 From: spuligil Date: Fri, 3 Jan 2025 06:01:43 -0800 Subject: [PATCH 007/138] fw-api: CL 28354118 - update fw common interface files Change-Id: I8e02cd6b56ce99feb275cd8ce82a5b976108729f CRs-Fixed: 3830439 --- fw/wmi_unified.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fw/wmi_unified.h b/fw/wmi_unified.h index e62c41e9abdd..2cc50cceb1b5 100644 --- a/fw/wmi_unified.h +++ b/fw/wmi_unified.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2010-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -17038,6 +17038,8 @@ typedef struct { #define WMI_MLO_FLAGS_SET_START_AS_ACTIVE(mlo_flags, value) WMI_SET_BITS(mlo_flags, 17, 1, value) #define WMI_MLO_FLAGS_GET_IEEE_LINK_ID_VALID(mlo_flags) WMI_GET_BITS(mlo_flags, 18, 1) #define WMI_MLO_FLAGS_SET_IEEE_LINK_ID_VALID(mlo_flags, value) WMI_SET_BITS(mlo_flags, 18, 1, value) +#define WMI_MLO_FLAGS_GET_IEEE_LINK_ID_VALID_PARTNER(mlo_flags) WMI_GET_BITS(mlo_flags, 19, 1) +#define WMI_MLO_FLAGS_SET_IEEE_LINK_ID_VALID_PARTNER(mlo_flags, value) WMI_SET_BITS(mlo_flags, 19, 1, value) /* this structure used for passing MLO flags */ typedef struct { From 5505ba5dcb13759c0b6911696eb0cde6ddb9ac4e Mon Sep 17 00:00:00 2001 From: spuligil Date: Tue, 14 Jan 2025 06:03:33 -0800 Subject: [PATCH 008/138] fw-api: CL 28373275 - update fw common interface files Change-Id: I85cf81d7802f7c444291915ef402121302b06fec CRs-Fixed: 3830439 --- fw/wmi_unified.h | 2 ++ fw/wmi_version.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/fw/wmi_unified.h b/fw/wmi_unified.h index 2cc50cceb1b5..86e90f30fd99 100644 --- a/fw/wmi_unified.h +++ b/fw/wmi_unified.h @@ -47694,6 +47694,8 @@ typedef struct { A_UINT32 mode; /* max num of user to decode */ A_UINT32 max_num_user; + /* UL MU sniffer enable */ + A_UINT32 ul_snif_enable; /** * TLV (tag length value) parameters follow setting MU sniffer command * structure. The TLV's are: diff --git a/fw/wmi_version.h b/fw/wmi_version.h index eb7b36e88938..90fddcf65884 100644 --- a/fw/wmi_version.h +++ b/fw/wmi_version.h @@ -37,7 +37,7 @@ #define __WMI_VER_MINOR_ 0 /** WMI revision number has to be incremented when there is a * change that may or may not break compatibility. */ -#define __WMI_REVISION_ 1567 +#define __WMI_REVISION_ 1568 /** The Version Namespace should not be normally changed. Only * host and firmware of the same WMI namespace will work From 5ffed857e8e7eef849de60e49e9775e837d9df07 Mon Sep 17 00:00:00 2001 From: spuligil Date: Tue, 14 Jan 2025 06:06:17 -0800 Subject: [PATCH 009/138] fw-api: CL 28388903 - update fw common interface files Change-Id: I12fe4e4fcc7c7f9a10613458be245b3b1def2f6e CRs-Fixed: 3830439 --- fw/wmi_unified.h | 20 +++++++++++--------- fw/wmi_version.h | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/fw/wmi_unified.h b/fw/wmi_unified.h index 86e90f30fd99..33c6542a2e7e 100644 --- a/fw/wmi_unified.h +++ b/fw/wmi_unified.h @@ -49653,15 +49653,17 @@ typedef struct { #define WMI_PEER_ACTIVE_TRAFFIC_TYPE_BACKGROUND_S 2 /* bits 3-15 are reserved for new non-interactive traffic types */ -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_GAMING_M 0x00010000 -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_GAMING_S 16 -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VOIP_M 0x00020000 -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VOIP_S 17 -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VIDEO_CONF_M 0x00040000 -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VIDEO_CONF_S 18 -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_WEB_BROWSING_M 0x00080000 -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_WEB_BROWSING_S 19 -/* bits 20-31 are reserved for new interactive traffic types */ +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_GAMING_M 0x00010000 +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_GAMING_S 16 +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VOIP_M 0x00020000 +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VOIP_S 17 +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VIDEO_CONF_M 0x00040000 +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VIDEO_CONF_S 18 +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_WEB_BROWSING_M 0x00080000 +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_WEB_BROWSING_S 19 +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_APERIODIC_BURST_TRAFFIC_1_M 0x00100000 +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_APERIODIC_BURST_TRAFFIC_1_S 20 +/* bits 21-31 are reserved for new interactive traffic types */ typedef struct { A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_active_traffic_map_cmd_fixed_param */ diff --git a/fw/wmi_version.h b/fw/wmi_version.h index 90fddcf65884..da3b00300b4c 100644 --- a/fw/wmi_version.h +++ b/fw/wmi_version.h @@ -37,7 +37,7 @@ #define __WMI_VER_MINOR_ 0 /** WMI revision number has to be incremented when there is a * change that may or may not break compatibility. */ -#define __WMI_REVISION_ 1568 +#define __WMI_REVISION_ 1569 /** The Version Namespace should not be normally changed. Only * host and firmware of the same WMI namespace will work From 364ba901fa9e5b9865601618f3d9c9d0bdace283 Mon Sep 17 00:00:00 2001 From: spuligil Date: Tue, 14 Jan 2025 06:04:55 -0800 Subject: [PATCH 010/138] fw-api: CL 28373291 - update fw common interface files Change-Id: Iffb3535c6da7656dd06804cdae0fecf23cd2c508 CRs-Fixed: 3830439 --- fw/htt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fw/htt.h b/fw/htt.h index ba5b42d6e3e6..3f4182029fc6 100644 --- a/fw/htt.h +++ b/fw/htt.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -15328,7 +15328,7 @@ typedef enum { } while (0) #define HTT_RX_ADDBA_EXTN_WIN_SIZE_GET(word) \ - (((word) & HTT_RX_ADDBA_WIN_SIZE_M) >> HTT_RX_ADDBA_WIN_SIZE_S) + (((word) & HTT_RX_ADDBA_EXTN_WIN_SIZE_M) >> HTT_RX_ADDBA_EXTN_WIN_SIZE_S) #define HTT_RX_ADDBA_EXTN_BYTES 8 From 7d60cb1b3c087ab023d5864815deaaa3f46678b5 Mon Sep 17 00:00:00 2001 From: spuligil Date: Tue, 14 Jan 2025 06:01:44 -0800 Subject: [PATCH 011/138] fw-api: CL 28361807 - update fw common interface files Change-Id: I54b02474ec45ddcc21b31e0fb530439f413db4eb CRs-Fixed: 3830439 --- fw/wlan_module_ids.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fw/wlan_module_ids.h b/fw/wlan_module_ids.h index d1abb8186655..0ba84fea8be3 100644 --- a/fw/wlan_module_ids.h +++ b/fw/wlan_module_ids.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -191,8 +191,10 @@ typedef enum { WLAN_MODULE_PHYLIB_RRI, /* 0x94 */ WLAN_MODULE_PHYLIB_SSCAN, /* 0x95 */ WLAN_MODULE_PHYLIB_RSVD, /* 0x96 */ + WLAN_MODULE_USD, /* 0x97 */ WLAN_MODULE_C2C, /* 0x98 */ + WLAN_MODULE_VBSS, /* 0x99 */ WLAN_MODULE_ID_MAX, From 0f92eef2ebca7bdebc1f56124b2dd524c5382d04 Mon Sep 17 00:00:00 2001 From: spuligil Date: Thu, 16 Jan 2025 06:01:32 -0800 Subject: [PATCH 012/138] fw-api: CL 28429679 - update fw common interface files Change-Id: I2f71c26784746aa8f5107c8c0d63929d9eda37d7 CRs-Fixed: 3830439 --- fw/wmi_services.h | 3 ++- fw/wmi_tlv_defs.h | 7 ++++++- fw/wmi_unified.h | 3 +++ fw/wmi_version.h | 4 ++-- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/fw/wmi_services.h b/fw/wmi_services.h index fda83ef79812..b82c7bd1fc45 100644 --- a/fw/wmi_services.h +++ b/fw/wmi_services.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -694,6 +694,7 @@ typedef enum { WMI_SERVICE_TWT_P2P_GO_CONCURRENCY_SUPPORT = 435, /* Indicates FW supports TWT in P2P GO concurrency mode */ WMI_SERVICE_UMAC_MIGRATION_SUPPORT = 436, /* Indicates that FW supports UMAC migration */ WMI_SERVICE_STA_TWT_STATS_EXT = 437, /* FW supports additional info in TWT stats and ADD COMPLETION Event */ + WMI_SERVICE_OPT_DP_DIAG_SUPPORT = 438, /* FW supports diag QDATA feature */ WMI_MAX_EXT2_SERVICE diff --git a/fw/wmi_tlv_defs.h b/fw/wmi_tlv_defs.h index f71d7221f215..96f7d8385f12 100644 --- a/fw/wmi_tlv_defs.h +++ b/fw/wmi_tlv_defs.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2010-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -2371,6 +2371,7 @@ typedef enum { OP(WMI_MLO_LINK_RECONFIG_START_INDICATION_EVENTID) \ OP(WMI_PDEV_WIFI_RADAR_CAPABILITIES_EVENTID) \ OP(WMI_VDEV_VBSS_CONFIG_EVENTID) \ + OP(WMI_OPT_DP_DIAG_EVENTID) \ /* add new EVT_LIST elements above this line */ @@ -6246,6 +6247,10 @@ WMITLV_CREATE_PARAM_STRUC(WMI_READ_DATA_FROM_FLASH_EVENTID); WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_DIAG_EVENTID); +#define WMITLV_TABLE_WMI_OPT_DP_DIAG_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_OPT_DP_DIAG_EVENTID); + /* IGTK Offload Event */ #define WMITLV_TABLE_WMI_GTK_OFFLOAD_STATUS_EVENTID(id,op,buf,len)\ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param, WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param, fixed_param, WMITLV_SIZE_FIX) diff --git a/fw/wmi_unified.h b/fw/wmi_unified.h index 33c6542a2e7e..d10608810623 100644 --- a/fw/wmi_unified.h +++ b/fw/wmi_unified.h @@ -2407,6 +2407,9 @@ typedef enum { /* WMI event to send scan cached results */ WMI_SCAN_CACHE_RESULT_EVENTID, + /** WMI event for FW diagnostic data sent to host */ + WMI_OPT_DP_DIAG_EVENTID, + /* GPIO Event */ WMI_GPIO_INPUT_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_GPIO), diff --git a/fw/wmi_version.h b/fw/wmi_version.h index da3b00300b4c..fcb6265af056 100644 --- a/fw/wmi_version.h +++ b/fw/wmi_version.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -37,7 +37,7 @@ #define __WMI_VER_MINOR_ 0 /** WMI revision number has to be incremented when there is a * change that may or may not break compatibility. */ -#define __WMI_REVISION_ 1569 +#define __WMI_REVISION_ 1570 /** The Version Namespace should not be normally changed. Only * host and firmware of the same WMI namespace will work From bb8a45801d247ebe5201e1e97d4e890142d6cbf7 Mon Sep 17 00:00:00 2001 From: Madhu Ananthula Date: Fri, 17 Jan 2025 12:15:04 +0530 Subject: [PATCH 013/138] msm: eva: Copy back the validated size to avoid security issue As we are reading the packet from a shared queue, there is a possibility to corrupt the packet->size data of shared queue by malicious FW after validating it in the kernel driver. Change-Id: I9bff8f2daa64054eada37de54fe3fa837d57b22a Signed-off-by: Aniruddh Sharma Signed-off-by: Madhu Ananthula --- drivers/media/platform/msm/cvp/cvp_hfi.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/cvp/cvp_hfi.c b/drivers/media/platform/msm/cvp/cvp_hfi.c index fc4236397575..6f598089406a 100644 --- a/drivers/media/platform/msm/cvp/cvp_hfi.c +++ b/drivers/media/platform/msm/cvp/cvp_hfi.c @@ -717,7 +717,7 @@ static int __read_queue(struct cvp_iface_q_info *qinfo, u8 *packet, u32 *read_ptr; u32 receive_request = 0; u32 read_idx, write_idx; - int rc = 0; + int rc = 0; if (!qinfo || !packet || !pb_tx_req_is_set) { dprintk(CVP_ERR, "Invalid Params\n"); @@ -807,6 +807,12 @@ static int __read_queue(struct cvp_iface_q_info *qinfo, u8 *packet, (u8 *)qinfo->q_array.align_virtual_addr, new_read_idx << 2); } + /* + * Copy back the validated size to avoid security issue. As we are reading + * the packet from a shared queue, there is a possibility to get the + * packet->size data corrupted of shared queue by mallicious FW. + */ + *((u32 *) packet) = packet_size_in_words << 2; } else { dprintk(CVP_WARN, "BAD packet received, read_idx: %#x, pkt_size: %d\n", From 8ee6cd6bef52b65e6afba63310e07891e39eb38e Mon Sep 17 00:00:00 2001 From: Pulkit Singh Tak Date: Mon, 6 Jan 2025 16:28:14 +0530 Subject: [PATCH 014/138] msm: eva: Validating the SFR buffer size before accessing To avoid any OOB write or other security issues, it's good to validate the buffer size before accessing it. Change-Id: Ibfdef21293c9385119cfb6338ef36e20c0fc1f2f Signed-off-by: Pulkit Singh Tak --- drivers/media/platform/msm/cvp/cvp_hfi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/cvp/cvp_hfi.c b/drivers/media/platform/msm/cvp/cvp_hfi.c index fc4236397575..a38603f89ae3 100644 --- a/drivers/media/platform/msm/cvp/cvp_hfi.c +++ b/drivers/media/platform/msm/cvp/cvp_hfi.c @@ -2757,17 +2757,19 @@ skip_power_off: static void __process_sys_error(struct iris_hfi_device *device) { struct cvp_hfi_sfr_struct *vsfr = NULL; + u32 sfr_buf_size = 0; vsfr = (struct cvp_hfi_sfr_struct *)device->sfr.align_virtual_addr; - if (vsfr) { - void *p = memchr(vsfr->rg_data, '\0', vsfr->bufSize); + sfr_buf_size = vsfr->bufSize; + if (vsfr && sfr_buf_size < ALIGNED_SFR_SIZE) { + void *p = memchr(vsfr->rg_data, '\0', sfr_buf_size); /* * SFR isn't guaranteed to be NULL terminated * since SYS_ERROR indicates that Iris is in the * process of crashing. */ if (p == NULL) - vsfr->rg_data[vsfr->bufSize - 1] = '\0'; + vsfr->rg_data[sfr_buf_size - 1] = '\0'; dprintk(CVP_ERR, "SFR Message from FW: %s\n", vsfr->rg_data); From 185fa1292901cdfd279c40b4b721175db7a11ede Mon Sep 17 00:00:00 2001 From: spuligil Date: Sat, 18 Jan 2025 06:01:30 -0800 Subject: [PATCH 015/138] fw-api: CL 28444600 - update fw common interface files Change-Id: Ib916adc77018b385239ac1ca528eca485544f7e9 CRs-Fixed: 3830439 --- fw/wlan_module_ids.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fw/wlan_module_ids.h b/fw/wlan_module_ids.h index 0ba84fea8be3..981bbaef3451 100644 --- a/fw/wlan_module_ids.h +++ b/fw/wlan_module_ids.h @@ -195,7 +195,7 @@ typedef enum { WLAN_MODULE_USD, /* 0x97 */ WLAN_MODULE_C2C, /* 0x98 */ WLAN_MODULE_VBSS, /* 0x99 */ - + WLAN_MODULE_OPT_DATA, /* 0x9a */ WLAN_MODULE_ID_MAX, WLAN_MODULE_ID_INVALID = WLAN_MODULE_ID_MAX, From 02da7c14f258a88cb952526ed7f9393873eaa2e5 Mon Sep 17 00:00:00 2001 From: spuligil Date: Mon, 20 Jan 2025 06:01:33 -0800 Subject: [PATCH 016/138] fw-api: CL 28447311 - update fw common interface files Change-Id: Iff95b330cfcde7872fe8fc31817baa3fd218a078 CRs-Fixed: 3830439 --- fw/wmi_unified.h | 6 ++++++ fw/wmi_version.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/fw/wmi_unified.h b/fw/wmi_unified.h index d10608810623..ad2badd010cd 100644 --- a/fw/wmi_unified.h +++ b/fw/wmi_unified.h @@ -5470,6 +5470,12 @@ typedef struct { #define WMI_RSRC_CFG_HOST_SERVICE_FLAG_OPT_DP_CTRL_REPLENISH_REFILL_RX_BUFFER_SUPPORT_SET(host_service_flags, val) \ WMI_SET_BITS(host_service_flags, 17, 1, val) +/* This bit is used to inform FW VBSS is enabled */ +#define WMI_RSRC_CFG_HOST_SERVICE_FLAG_VBSS_ENABLED_GET(host_service_flags) \ + WMI_GET_BITS(host_service_flags, 18, 1) +#define WMI_RSRC_CFG_HOST_SERVICE_FLAG_VBSS_ENABLED_SET(host_service_flags, val) \ + WMI_SET_BITS(host_service_flags, 18, 1, val) + #define WMI_RSRC_CFG_CARRIER_CFG_CHARTER_ENABLE_GET(carrier_config) \ WMI_GET_BITS(carrier_config, 0, 1) #define WMI_RSRC_CFG_CARRIER_CFG_CHARTER_ENABLE_SET(carrier_config, val) \ diff --git a/fw/wmi_version.h b/fw/wmi_version.h index fcb6265af056..796f76d3dd21 100644 --- a/fw/wmi_version.h +++ b/fw/wmi_version.h @@ -37,7 +37,7 @@ #define __WMI_VER_MINOR_ 0 /** WMI revision number has to be incremented when there is a * change that may or may not break compatibility. */ -#define __WMI_REVISION_ 1570 +#define __WMI_REVISION_ 1571 /** The Version Namespace should not be normally changed. Only * host and firmware of the same WMI namespace will work From f0a7890d5ab7165ee8469cbcba13e2d9f96c8769 Mon Sep 17 00:00:00 2001 From: spuligil Date: Sat, 25 Jan 2025 06:01:35 -0800 Subject: [PATCH 017/138] fw-api: CL 28481760 - update fw common interface files Change-Id: I51bc0a64b92bdce8fd14b9df8f7012dc487d8fd4 CRs-Fixed: 3830439 --- fw/htt.h | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 1 deletion(-) diff --git a/fw/htt.h b/fw/htt.h index 3f4182029fc6..3b0c0b8ef951 100644 --- a/fw/htt.h +++ b/fw/htt.h @@ -265,9 +265,10 @@ * 3.135 Add HTT_HOST4_TO_FW_RXBUF_RING def. * 3.136 Add htt_ext_present flag in htt_tx_tcl_global_seq_metadata. * 3.137 Add more HTT_SDWF_MSDUQ_CFG_IND_ERROR codes. + * 3.138 Add T2H MLO_LATENCY_REQ, H2T _RESP msg defs. */ #define HTT_CURRENT_VERSION_MAJOR 3 -#define HTT_CURRENT_VERSION_MINOR 137 +#define HTT_CURRENT_VERSION_MINOR 138 #define HTT_NUM_TX_FRAG_DESC 1024 @@ -913,6 +914,7 @@ enum htt_h2t_msg_type { HTT_H2T_MSG_TYPE_TX_LATENCY_STATS_CFG = 0x25, HTT_H2T_MSG_TYPE_TX_LCE_SUPER_RULE_SETUP = 0x26, HTT_H2T_MSG_TYPE_SDWF_MSDUQ_RECFG_REQ = 0x27, + HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_RESP = 0x28, /* keep this last */ HTT_H2T_NUM_MSGS @@ -11495,6 +11497,89 @@ PREPACK struct htt_h2t_sdwf_msduq_recfg_req { ((_var) |= ((_val) << HTT_H2T_SDWF_MSDUQ_RECFG_REQUEST_COOKIE_S)); \ } while (0) +/** + * @brief host -> target report MLO latency stats to FW periodically + * + * MSG_TYPE => HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_RESP + * + * @details + * + * |31 24|23 16|15 8|7 0| + * |----------------+----------------+----------------+----------------| + * | avg latency ms | vdev id | msg type | + * |----------------+----------------+----------------+----------------| + * | num of tx MSDUs | avg latency jitter ms | + * |-------------------------------------------------------------------| + * + * @details + * struct htt_h2t_mlo_latency_stats: + * + * The message is interpreted as follows: + * dword0 - b'7:0 - msg_type: Identifies mlo latency stats to fw + * This will be set to 0x28 + * (HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_RESP) + * b'15:8 - vdev id : Indicate which vdev in the pdev is chosen + * as primary + * b'31:16 - avg latency ms: Indicate average MLO latency in a period + * dword1 - b'15:0 - min jitter ms: Indicate avg jitter of MLO latency in a + * period + * b'31:16 - num of tx packet : Indicate how many MSDUs are sent in a + * period + */ + +/* HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_RESP */ +PREPACK struct htt_h2t_mlo_latency_stats { + A_UINT32 msg_type: 8, /* bits 7:0 */ + vdev_id: 8, /* bits 15:8 */ + avg_latency_ms: 16; /* bits 31:16 */ + A_UINT32 avg_jitter_ms: 16, /* bits 15:0 */ + num_of_tx_pkt: 16; /* bits 31:16 */ +} POSTPACK; + +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID_M 0x0000FF00 +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID_S 8 +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID_GET(_var) \ + (((_var) & HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID_M) >> \ + HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID_S) +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID, _val); \ + ((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_VDEV_ID_S)); \ + } while (0) + +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS_M 0xFFFF0000 +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS_S 16 +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS_GET(_var) \ + (((_var) & HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS_M) >> \ + HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS_S) +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS, _val); \ + ((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_LATENCY_MS_S)); \ + } while (0) + +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS_M 0x0000FFFF +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS_S 0 +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS_GET(_var) \ + (((_var) & HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS_M) >> \ + HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS_S) +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS, _val); \ + ((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_AVG_JITTER_MS_S)); \ + } while (0) + +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT_M 0xFFFF0000 +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT_S 16 +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT_GET(_var) \ + (((_var) & HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT_M) >> \ + HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT_S) +#define HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT, _val); \ + ((_var) |= ((_val) << HTT_H2T_MSG_TYPE_MLO_LATENCY_STATS_NUM_OF_TX_PKT_S)); \ + } while (0) + /*=== target -> host messages ===============================================*/ @@ -11569,6 +11654,7 @@ enum htt_t2h_msg_type { HTT_T2H_MSG_TYPE_TX_LATENCY_STATS_PERIODIC_IND = 0x3a, HTT_T2H_MSG_TYPE_TX_LCE_SUPER_RULE_SETUP_DONE = 0x3b, HTT_T2H_MSG_TYPE_SDWF_MSDUQ_CFG_IND = 0x3c, + HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ = 0x3d, HTT_T2H_MSG_TYPE_TEST, @@ -23290,6 +23376,73 @@ PREPACK struct htt_t2h_sdwf_msduq_cfg_ind { ((_var) |= ((_val) << HTT_T2H_MSG_TYPE_SDWF_MSDUQ_CFG_IND_REQUEST_COOKIE_S)); \ } while (0) +/** + * @brief target -> host request for MLO latency stats + * + * MSG_TYPE => HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ + * + * @details + * + * |31 24|23 16| 15 |14 8|7 0| + * |----------------+----------------+------+---------+----------------| + * | periodic interval |enable| vdev id | msg type | + * |-------------------------------------------------------------------| + * + * @details + * struct htt_t2h_mlo_latency_req_t: + * + * The message is interpreted as follows: + * dword0 - b'7:0 - msg_type: Identifies a request for MLO latency stats + * This will be set to 0x3d + * (HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ) + * b'14:8 - vdev id : Indicate which vdev in the pdev is chosen + * as primary + * b'15 - enable: Indicate if request of MLO latency stats is + * enabled + * b'31:16 - periodic interval: Indicate the interval in ms of + * reporting MLO latency stats + */ + +/* HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ */ +PREPACK struct htt_t2h_mlo_latency_req_t { + A_UINT32 msg_type: 8, /* bits 7:0 */ + vdev_id: 7, /* bits 14:8 */ + enable: 1, /* bits 15 */ + periodic_intvl: 16; /* bits 31:16 */ +} POSTPACK; + +#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID_M 0x00007F00 +#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID_S 8 +#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID_GET(_var) \ + (((_var) & HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID_M) >> \ + HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID_S) +#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID, _val); \ + ((_var) |= ((_val) << HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_VDEV_ID_S)); \ + } while (0) + +#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE_M 0x00008000 +#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE_S 15 +#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE_GET(_var) \ + (((_var) & HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE_M) >> \ + HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE_S) +#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE, _val); \ + ((_var) |= ((_val) << HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_ENABLE_S)); \ + } while (0) + +#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL_M 0xFFFF0000 +#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL_S 16 +#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL_GET(_var) \ + (((_var) & HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL_M) >> \ + HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL_S) +#define HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL, _val); \ + ((_var) |= ((_val) << HTT_T2H_MSG_TYPE_MLO_LATENCY_REQ_PERIODIC_INTVL_S)); \ + } while (0) #endif From 82235ad55a9e075270294214dc1a46d613fb4185 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Tue, 3 Dec 2024 09:44:07 +0800 Subject: [PATCH 018/138] jbd2: flush filesystem device before updating tail sequence [ Upstream commit a0851ea9cd555c333795b85ddd908898b937c4e1 ] When committing transaction in jbd2_journal_commit_transaction(), the disk caches for the filesystem device should be flushed before updating the journal tail sequence. However, this step is missed if the journal is not located on the filesystem device. As a result, the filesystem may become inconsistent following a power failure or system crash. Fix it by ensuring that the filesystem device is flushed appropriately. Fixes: 3339578f0578 ("jbd2: cleanup journal tail after transaction commit") Signed-off-by: Zhang Yi Link: https://lore.kernel.org/r/20241203014407.805916-3-yi.zhang@huaweicloud.com Reviewed-by: Jan Kara Signed-off-by: Christian Brauner Signed-off-by: Sasha Levin --- fs/jbd2/commit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 255026497b8c..8c435c11664d 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -770,9 +770,9 @@ start_journal_io: /* * If the journal is not located on the file system device, * then we must flush the file system device before we issue - * the commit record + * the commit record and update the journal tail sequence. */ - if (commit_transaction->t_need_data_flush && + if ((commit_transaction->t_need_data_flush || update_tail) && (journal->j_fs_dev != journal->j_dev) && (journal->j_flags & JBD2_BARRIER)) blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS, NULL); From 9c7c03d0e926762adf3a3a0ba86156fb5e19538b Mon Sep 17 00:00:00 2001 From: Ming-Hung Tsai Date: Thu, 5 Dec 2024 19:41:51 +0800 Subject: [PATCH 019/138] dm array: fix releasing a faulty array block twice in dm_array_cursor_end [ Upstream commit f2893c0804d86230ffb8f1c8703fdbb18648abc8 ] When dm_bm_read_lock() fails due to locking or checksum errors, it releases the faulty block implicitly while leaving an invalid output pointer behind. The caller of dm_bm_read_lock() should not operate on this invalid dm_block pointer, or it will lead to undefined result. For example, the dm_array_cursor incorrectly caches the invalid pointer on reading a faulty array block, causing a double release in dm_array_cursor_end(), then hitting the BUG_ON in dm-bufio cache_put(). Reproduce steps: 1. initialize a cache device dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" dmsetup create cdata --table "0 65536 linear /dev/sdc 8192" dmsetup create corig --table "0 524288 linear /dev/sdc $262144" dd if=/dev/zero of=/dev/mapper/cmeta bs=4k count=1 dmsetup create cache --table "0 524288 cache /dev/mapper/cmeta \ /dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" 2. wipe the second array block offline dmsteup remove cache cmeta cdata corig mapping_root=$(dd if=/dev/sdc bs=1c count=8 skip=192 \ 2>/dev/null | hexdump -e '1/8 "%u\n"') ablock=$(dd if=/dev/sdc bs=1c count=8 skip=$((4096*mapping_root+2056)) \ 2>/dev/null | hexdump -e '1/8 "%u\n"') dd if=/dev/zero of=/dev/sdc bs=4k count=1 seek=$ablock 3. try reopen the cache device dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" dmsetup create cdata --table "0 65536 linear /dev/sdc 8192" dmsetup create corig --table "0 524288 linear /dev/sdc $262144" dmsetup create cache --table "0 524288 cache /dev/mapper/cmeta \ /dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" Kernel logs: (snip) device-mapper: array: array_block_check failed: blocknr 0 != wanted 10 device-mapper: block manager: array validator check failed for block 10 device-mapper: array: get_ablock failed device-mapper: cache metadata: dm_array_cursor_next for mapping failed ------------[ cut here ]------------ kernel BUG at drivers/md/dm-bufio.c:638! Fix by setting the cached block pointer to NULL on errors. In addition to the reproducer described above, this fix can be verified using the "array_cursor/damaged" test in dm-unit: dm-unit run /pdata/array_cursor/damaged --kernel-dir Signed-off-by: Ming-Hung Tsai Fixes: fdd1315aa5f0 ("dm array: introduce cursor api") Reviewed-by: Joe Thornber Signed-off-by: Mike Snitzer Signed-off-by: Sasha Levin --- drivers/md/persistent-data/dm-array.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/md/persistent-data/dm-array.c b/drivers/md/persistent-data/dm-array.c index 185dc60360b5..849eb1b97c43 100644 --- a/drivers/md/persistent-data/dm-array.c +++ b/drivers/md/persistent-data/dm-array.c @@ -907,23 +907,27 @@ static int load_ablock(struct dm_array_cursor *c) if (c->block) unlock_ablock(c->info, c->block); - c->block = NULL; - c->ab = NULL; c->index = 0; r = dm_btree_cursor_get_value(&c->cursor, &key, &value_le); if (r) { DMERR("dm_btree_cursor_get_value failed"); - dm_btree_cursor_end(&c->cursor); + goto out; } else { r = get_ablock(c->info, le64_to_cpu(value_le), &c->block, &c->ab); if (r) { DMERR("get_ablock failed"); - dm_btree_cursor_end(&c->cursor); + goto out; } } + return 0; + +out: + dm_btree_cursor_end(&c->cursor); + c->block = NULL; + c->ab = NULL; return r; } From 28c628d20094899cf974fd22d3f97110cc3074a6 Mon Sep 17 00:00:00 2001 From: Ming-Hung Tsai Date: Thu, 5 Dec 2024 19:41:52 +0800 Subject: [PATCH 020/138] dm array: fix unreleased btree blocks on closing a faulty array cursor [ Upstream commit 626f128ee9c4133b1cfce4be2b34a1508949370e ] The cached block pointer in dm_array_cursor might be NULL if it reaches an unreadable array block, or the array is empty. Therefore, dm_array_cursor_end() should call dm_btree_cursor_end() unconditionally, to prevent leaving unreleased btree blocks. This fix can be verified using the "array_cursor/iterate/empty" test in dm-unit: dm-unit run /pdata/array_cursor/iterate/empty --kernel-dir Signed-off-by: Ming-Hung Tsai Fixes: fdd1315aa5f0 ("dm array: introduce cursor api") Reviewed-by: Joe Thornber Signed-off-by: Mike Snitzer Signed-off-by: Sasha Levin --- drivers/md/persistent-data/dm-array.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/md/persistent-data/dm-array.c b/drivers/md/persistent-data/dm-array.c index 849eb1b97c43..f97de343a398 100644 --- a/drivers/md/persistent-data/dm-array.c +++ b/drivers/md/persistent-data/dm-array.c @@ -950,10 +950,10 @@ EXPORT_SYMBOL_GPL(dm_array_cursor_begin); void dm_array_cursor_end(struct dm_array_cursor *c) { - if (c->block) { + if (c->block) unlock_ablock(c->info, c->block); - dm_btree_cursor_end(&c->cursor); - } + + dm_btree_cursor_end(&c->cursor); } EXPORT_SYMBOL_GPL(dm_array_cursor_end); From e231d0390752f06621e7e8edd2574aaa4acd71c2 Mon Sep 17 00:00:00 2001 From: Ming-Hung Tsai Date: Thu, 5 Dec 2024 19:41:53 +0800 Subject: [PATCH 021/138] dm array: fix cursor index when skipping across block boundaries [ Upstream commit 0bb1968da2737ba68fd63857d1af2b301a18d3bf ] dm_array_cursor_skip() seeks to the target position by loading array blocks iteratively until the specified number of entries to skip is reached. When seeking across block boundaries, it uses dm_array_cursor_next() to step into the next block. dm_array_cursor_skip() must first move the cursor index to the end of the current block; otherwise, the cursor position could incorrectly remain in the same block, causing the actual number of skipped entries to be much smaller than expected. This bug affects cache resizing in v2 metadata and could lead to data loss if the fast device is shrunk during the first-time resume. For example: 1. create a cache metadata consists of 32768 blocks, with a dirty block assigned to the second bitmap block. cache_restore v1.0 is required. cat <> cmeta.xml EOF dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" cache_restore -i cmeta.xml -o /dev/mapper/cmeta --metadata-version=2 2. bring up the cache while attempt to discard all the blocks belonging to the second bitmap block (block# 32576 to 32767). The last command is expected to fail, but it actually succeeds. dmsetup create cdata --table "0 2084864 linear /dev/sdc 8192" dmsetup create corig --table "0 65536 linear /dev/sdc 2105344" dmsetup create cache --table "0 65536 cache /dev/mapper/cmeta \ /dev/mapper/cdata /dev/mapper/corig 64 2 metadata2 writeback smq \ 2 migration_threshold 0" In addition to the reproducer described above, this fix can be verified using the "array_cursor/skip" tests in dm-unit: dm-unit run /pdata/array_cursor/skip/ --kernel-dir Signed-off-by: Ming-Hung Tsai Fixes: 9b696229aa7d ("dm persistent data: add cursor skip functions to the cursor APIs") Reviewed-by: Joe Thornber Signed-off-by: Mike Snitzer Signed-off-by: Sasha Levin --- drivers/md/persistent-data/dm-array.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/md/persistent-data/dm-array.c b/drivers/md/persistent-data/dm-array.c index f97de343a398..4d434d89eadd 100644 --- a/drivers/md/persistent-data/dm-array.c +++ b/drivers/md/persistent-data/dm-array.c @@ -993,6 +993,7 @@ int dm_array_cursor_skip(struct dm_array_cursor *c, uint32_t count) } count -= remaining; + c->index += (remaining - 1); r = dm_array_cursor_next(c); } while (!r); From ca254b28059294a1808e54a03a1f98f1cdb61079 Mon Sep 17 00:00:00 2001 From: Keisuke Nishimura Date: Tue, 29 Oct 2024 19:27:12 +0100 Subject: [PATCH 022/138] ieee802154: ca8210: Add missing check for kfifo_alloc() in ca8210_probe() [ Upstream commit 2c87309ea741341c6722efdf1fb3f50dd427c823 ] ca8210_test_interface_init() returns the result of kfifo_alloc(), which can be non-zero in case of an error. The caller, ca8210_probe(), should check the return value and do error-handling if it fails. Fixes: ded845a781a5 ("ieee802154: Add CA8210 IEEE 802.15.4 device driver") Signed-off-by: Keisuke Nishimura Reviewed-by: Simon Horman Reviewed-by: Miquel Raynal Link: https://lore.kernel.org/20241029182712.318271-1-keisuke.nishimura@inria.fr Signed-off-by: Stefan Schmidt Signed-off-by: Sasha Levin --- drivers/net/ieee802154/ca8210.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c index fdbdc22fe4e5..d394e2b65054 100644 --- a/drivers/net/ieee802154/ca8210.c +++ b/drivers/net/ieee802154/ca8210.c @@ -3124,7 +3124,11 @@ static int ca8210_probe(struct spi_device *spi_device) spi_set_drvdata(priv->spi, priv); if (IS_ENABLED(CONFIG_IEEE802154_CA8210_DEBUGFS)) { cascoda_api_upstream = ca8210_test_int_driver_write; - ca8210_test_interface_init(priv); + ret = ca8210_test_interface_init(priv); + if (ret) { + dev_crit(&spi_device->dev, "ca8210_test_interface_init failed\n"); + goto error; + } } else { cascoda_api_upstream = NULL; } From 0f25193e53a1016c878c78acae6fff49aac58889 Mon Sep 17 00:00:00 2001 From: Antonio Pastor Date: Thu, 2 Jan 2025 20:23:00 -0500 Subject: [PATCH 023/138] net: 802: LLC+SNAP OID:PID lookup on start of skb data [ Upstream commit 1e9b0e1c550c42c13c111d1a31e822057232abc4 ] 802.2+LLC+SNAP frames received by napi_complete_done() with GRO and DSA have skb->transport_header set two bytes short, or pointing 2 bytes before network_header & skb->data. This was an issue as snap_rcv() expected offset to point to SNAP header (OID:PID), causing packet to be dropped. A fix at llc_fixup_skb() (a024e377efed) resets transport_header for any LLC consumers that may care about it, and stops SNAP packets from being dropped, but doesn't fix the problem which is that LLC and SNAP should not use transport_header offset. Ths patch eliminates the use of transport_header offset for SNAP lookup of OID:PID so that SNAP does not rely on the offset at all. The offset is reset after pull for any SNAP packet consumers that may (but shouldn't) use it. Fixes: fda55eca5a33 ("net: introduce skb_transport_header_was_set()") Signed-off-by: Antonio Pastor Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20250103012303.746521-1-antonio.pastor@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/802/psnap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/802/psnap.c b/net/802/psnap.c index 40ab2aea7b31..7431ec077273 100644 --- a/net/802/psnap.c +++ b/net/802/psnap.c @@ -55,11 +55,11 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev, goto drop; rcu_read_lock(); - proto = find_snap_client(skb_transport_header(skb)); + proto = find_snap_client(skb->data); if (proto) { /* Pass the frame on. */ - skb->transport_header += 5; skb_pull_rcsum(skb, 5); + skb_reset_transport_header(skb); rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev); } rcu_read_unlock(); From 736fe12ce67530cd7b46b668c3b0f4194067b314 Mon Sep 17 00:00:00 2001 From: Jason Xing Date: Sun, 31 Mar 2024 17:05:21 +0800 Subject: [PATCH 024/138] tcp/dccp: complete lockless accesses to sk->sk_max_ack_backlog [ Upstream commit 9a79c65f00e2b036e17af3a3a607d7d732b7affb ] Since commit 099ecf59f05b ("net: annotate lockless accesses to sk->sk_max_ack_backlog") decided to handle the sk_max_ack_backlog locklessly, there is one more function mostly called in TCP/DCCP cases. So this patch completes it:) Signed-off-by: Jason Xing Reviewed-by: Eric Dumazet Link: https://lore.kernel.org/r/20240331090521.71965-1-kerneljasonxing@gmail.com Signed-off-by: Jakub Kicinski Stable-dep-of: 3479c7549fb1 ("tcp/dccp: allow a connection when sk_max_ack_backlog is zero") Signed-off-by: Sasha Levin --- include/net/inet_connection_sock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 180ff3ca823a..c81bbfc5f4df 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -285,7 +285,7 @@ static inline int inet_csk_reqsk_queue_len(const struct sock *sk) static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk) { - return inet_csk_reqsk_queue_len(sk) >= sk->sk_max_ack_backlog; + return inet_csk_reqsk_queue_len(sk) >= READ_ONCE(sk->sk_max_ack_backlog); } bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req); From 69c312572ec2543f2f52a1dccf3f95d7be5e6937 Mon Sep 17 00:00:00 2001 From: Zhongqiu Duan Date: Thu, 2 Jan 2025 17:14:26 +0000 Subject: [PATCH 025/138] tcp/dccp: allow a connection when sk_max_ack_backlog is zero [ Upstream commit 3479c7549fb1dfa7a1db4efb7347c7b8ef50de4b ] If the backlog of listen() is set to zero, sk_acceptq_is_full() allows one connection to be made, but inet_csk_reqsk_queue_is_full() does not. When the net.ipv4.tcp_syncookies is zero, inet_csk_reqsk_queue_is_full() will cause an immediate drop before the sk_acceptq_is_full() check in tcp_conn_request(), resulting in no connection can be made. This patch tries to keep consistent with 64a146513f8f ("[NET]: Revert incorrect accept queue backlog changes."). Link: https://lore.kernel.org/netdev/20250102080258.53858-1-kuniyu@amazon.com/ Fixes: ef547f2ac16b ("tcp: remove max_qlen_log") Signed-off-by: Zhongqiu Duan Reviewed-by: Kuniyuki Iwashima Reviewed-by: Jason Xing Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20250102171426.915276-1-dzq.aishenghu0@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- include/net/inet_connection_sock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index c81bbfc5f4df..05f07bf60c89 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -285,7 +285,7 @@ static inline int inet_csk_reqsk_queue_len(const struct sock *sk) static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk) { - return inet_csk_reqsk_queue_len(sk) >= READ_ONCE(sk->sk_max_ack_backlog); + return inet_csk_reqsk_queue_len(sk) > READ_ONCE(sk->sk_max_ack_backlog); } bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req); From 9858f4afeb2e59506e714176bd3e135539a3eeec Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 3 Jan 2025 10:45:46 +0000 Subject: [PATCH 026/138] net_sched: cls_flow: validate TCA_FLOW_RSHIFT attribute [ Upstream commit a039e54397c6a75b713b9ce7894a62e06956aa92 ] syzbot found that TCA_FLOW_RSHIFT attribute was not validated. Right shitfing a 32bit integer is undefined for large shift values. UBSAN: shift-out-of-bounds in net/sched/cls_flow.c:329:23 shift exponent 9445 is too large for 32-bit type 'u32' (aka 'unsigned int') CPU: 1 UID: 0 PID: 54 Comm: kworker/u8:3 Not tainted 6.13.0-rc3-syzkaller-00180-g4f619d518db9 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 Workqueue: ipv6_addrconf addrconf_dad_work Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120 ubsan_epilogue lib/ubsan.c:231 [inline] __ubsan_handle_shift_out_of_bounds+0x3c8/0x420 lib/ubsan.c:468 flow_classify+0x24d5/0x25b0 net/sched/cls_flow.c:329 tc_classify include/net/tc_wrapper.h:197 [inline] __tcf_classify net/sched/cls_api.c:1771 [inline] tcf_classify+0x420/0x1160 net/sched/cls_api.c:1867 sfb_classify net/sched/sch_sfb.c:260 [inline] sfb_enqueue+0x3ad/0x18b0 net/sched/sch_sfb.c:318 dev_qdisc_enqueue+0x4b/0x290 net/core/dev.c:3793 __dev_xmit_skb net/core/dev.c:3889 [inline] __dev_queue_xmit+0xf0e/0x3f50 net/core/dev.c:4400 dev_queue_xmit include/linux/netdevice.h:3168 [inline] neigh_hh_output include/net/neighbour.h:523 [inline] neigh_output include/net/neighbour.h:537 [inline] ip_finish_output2+0xd41/0x1390 net/ipv4/ip_output.c:236 iptunnel_xmit+0x55d/0x9b0 net/ipv4/ip_tunnel_core.c:82 udp_tunnel_xmit_skb+0x262/0x3b0 net/ipv4/udp_tunnel_core.c:173 geneve_xmit_skb drivers/net/geneve.c:916 [inline] geneve_xmit+0x21dc/0x2d00 drivers/net/geneve.c:1039 __netdev_start_xmit include/linux/netdevice.h:5002 [inline] netdev_start_xmit include/linux/netdevice.h:5011 [inline] xmit_one net/core/dev.c:3590 [inline] dev_hard_start_xmit+0x27a/0x7d0 net/core/dev.c:3606 __dev_queue_xmit+0x1b73/0x3f50 net/core/dev.c:4434 Fixes: e5dfb815181f ("[NET_SCHED]: Add flow classifier") Reported-by: syzbot+1dbb57d994e54aaa04d2@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6777bf49.050a0220.178762.0040.GAE@google.com/T/#u Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20250103104546.3714168-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sched/cls_flow.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index 87398af2715a..117c7b038591 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -354,7 +354,8 @@ static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = { [TCA_FLOW_KEYS] = { .type = NLA_U32 }, [TCA_FLOW_MODE] = { .type = NLA_U32 }, [TCA_FLOW_BASECLASS] = { .type = NLA_U32 }, - [TCA_FLOW_RSHIFT] = { .type = NLA_U32 }, + [TCA_FLOW_RSHIFT] = NLA_POLICY_MAX(NLA_U32, + 31 /* BITS_PER_U32 - 1 */), [TCA_FLOW_ADDEND] = { .type = NLA_U32 }, [TCA_FLOW_MASK] = { .type = NLA_U32 }, [TCA_FLOW_XOR] = { .type = NLA_U32 }, From 6429f52ed1a5823d88bad6d21bfe791d81c25bf0 Mon Sep 17 00:00:00 2001 From: Benjamin Coddington Date: Sat, 4 Jan 2025 10:29:45 -0500 Subject: [PATCH 027/138] tls: Fix tls_sw_sendmsg error handling [ Upstream commit b341ca51d2679829d26a3f6a4aa9aee9abd94f92 ] We've noticed that NFS can hang when using RPC over TLS on an unstable connection, and investigation shows that the RPC layer is stuck in a tight loop attempting to transmit, but forever getting -EBADMSG back from the underlying network. The loop begins when tcp_sendmsg_locked() returns -EPIPE to tls_tx_records(), but that error is converted to -EBADMSG when calling the socket's error reporting handler. Instead of converting errors from tcp_sendmsg_locked(), let's pass them along in this path. The RPC layer handles -EPIPE by reconnecting the transport, which prevents the endless attempts to transmit on a broken connection. Signed-off-by: Benjamin Coddington Fixes: a42055e8d2c3 ("net/tls: Add support for async encryption of records for performance") Link: https://patch.msgid.link/9594185559881679d81f071b181a10eb07cd079f.1736004079.git.bcodding@redhat.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/tls/tls_sw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 910da98d6bfb..03f608da594e 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -425,7 +425,7 @@ int tls_tx_records(struct sock *sk, int flags) tx_err: if (rc < 0 && rc != -EAGAIN) - tls_err_abort(sk, -EBADMSG); + tls_err_abort(sk, rc); return rc; } From ec037fe8c0d0f6140e3d8a49c7b29cb5582160b8 Mon Sep 17 00:00:00 2001 From: Krister Johansen Date: Tue, 7 Jan 2025 15:24:58 -0800 Subject: [PATCH 028/138] dm thin: make get_first_thin use rcu-safe list first function commit 80f130bfad1dab93b95683fc39b87235682b8f72 upstream. The documentation in rculist.h explains the absence of list_empty_rcu() and cautions programmers against relying on a list_empty() -> list_first() sequence in RCU safe code. This is because each of these functions performs its own READ_ONCE() of the list head. This can lead to a situation where the list_empty() sees a valid list entry, but the subsequent list_first() sees a different view of list head state after a modification. In the case of dm-thin, this author had a production box crash from a GP fault in the process_deferred_bios path. This function saw a valid list head in get_first_thin() but when it subsequently dereferenced that and turned it into a thin_c, it got the inside of the struct pool, since the list was now empty and referring to itself. The kernel on which this occurred printed both a warning about a refcount_t being saturated, and a UBSAN error for an out-of-bounds cpuid access in the queued spinlock, prior to the fault itself. When the resulting kdump was examined, it was possible to see another thread patiently waiting in thin_dtr's synchronize_rcu. The thin_dtr call managed to pull the thin_c out of the active thins list (and have it be the last entry in the active_thins list) at just the wrong moment which lead to this crash. Fortunately, the fix here is straight forward. Switch get_first_thin() function to use list_first_or_null_rcu() which performs just a single READ_ONCE() and returns NULL if the list is already empty. This was run against the devicemapper test suite's thin-provisioning suites for delete and suspend and no regressions were observed. Signed-off-by: Krister Johansen Fixes: b10ebd34ccca ("dm thin: fix rcu_read_lock being held in code that can sleep") Cc: stable@vger.kernel.org Acked-by: Ming-Hung Tsai Signed-off-by: Mikulas Patocka Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-thin.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 1ce0d5b52746..9e4332233531 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -2325,10 +2325,9 @@ static struct thin_c *get_first_thin(struct pool *pool) struct thin_c *tc = NULL; rcu_read_lock(); - if (!list_empty(&pool->active_thins)) { - tc = list_entry_rcu(pool->active_thins.next, struct thin_c, list); + tc = list_first_or_null_rcu(&pool->active_thins, struct thin_c, list); + if (tc) thin_get(tc); - } rcu_read_unlock(); return tc; From 1031462a944ba0fa83c25ab1111465f8345b5589 Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Wed, 8 Jan 2025 16:34:32 +0100 Subject: [PATCH 029/138] sctp: sysctl: cookie_hmac_alg: avoid using current->nsproxy commit ea62dd1383913b5999f3d16ae99d411f41b528d4 upstream. As mentioned in a previous commit of this series, using the 'net' structure via 'current' is not recommended for different reasons: - Inconsistency: getting info from the reader's/writer's netns vs only from the opener's netns. - current->nsproxy can be NULL in some cases, resulting in an 'Oops' (null-ptr-deref), e.g. when the current task is exiting, as spotted by syzbot [1] using acct(2). The 'net' structure can be obtained from the table->data using container_of(). Note that table->data could also be used directly, as this is the only member needed from the 'net' structure, but that would increase the size of this fix, to use '*data' everywhere 'net->sctp.sctp_hmac_alg' is used. Fixes: 3c68198e7511 ("sctp: Make hmac algorithm selection for cookie generation dynamic") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/67769ecb.050a0220.3a8527.003f.GAE@google.com [1] Suggested-by: Al Viro Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20250108-net-sysctl-current-nsproxy-v1-4-5df34b2083e8@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/sctp/sysctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 238cf1737576..93048978ad1c 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c @@ -441,7 +441,8 @@ static int proc_sctp_do_auth(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - struct net *net = current->nsproxy->net_ns; + struct net *net = container_of(ctl->data, struct net, + sctp.sctp_hmac_alg); struct ctl_table tbl; int new_value, ret; From 10c869a52f266e40f548cc3c565d14930a5edafc Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Wed, 8 Jan 2025 16:34:34 +0100 Subject: [PATCH 030/138] sctp: sysctl: auth_enable: avoid using current->nsproxy commit 15649fd5415eda664ef35780c2013adeb5d9c695 upstream. As mentioned in a previous commit of this series, using the 'net' structure via 'current' is not recommended for different reasons: - Inconsistency: getting info from the reader's/writer's netns vs only from the opener's netns. - current->nsproxy can be NULL in some cases, resulting in an 'Oops' (null-ptr-deref), e.g. when the current task is exiting, as spotted by syzbot [1] using acct(2). The 'net' structure can be obtained from the table->data using container_of(). Note that table->data could also be used directly, but that would increase the size of this fix, while 'sctp.ctl_sock' still needs to be retrieved from 'net' structure. Fixes: b14878ccb7fa ("net: sctp: cache auth_enable per endpoint") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/67769ecb.050a0220.3a8527.003f.GAE@google.com [1] Suggested-by: Al Viro Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20250108-net-sysctl-current-nsproxy-v1-6-5df34b2083e8@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/sctp/sysctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 93048978ad1c..4513d8d45e55 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c @@ -326,7 +326,7 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - struct net *net = current->nsproxy->net_ns; + struct net *net = container_of(ctl->data, struct net, sctp.auth_enable); struct ctl_table tbl; bool changed = false; char *none = "none"; From 8a9315e6f7b2d94c65a1ba476481deddb20fc3ae Mon Sep 17 00:00:00 2001 From: Roman Li Date: Fri, 13 Dec 2024 13:51:07 -0500 Subject: [PATCH 031/138] drm/amd/display: Add check for granularity in dml ceil/floor helpers commit 0881fbc4fd62e00a2b8e102725f76d10351b2ea8 upstream. [Why] Wrapper functions for dcn_bw_ceil2() and dcn_bw_floor2() should check for granularity is non zero to avoid assert and divide-by-zero error in dcn_bw_ functions. [How] Add check for granularity 0. Cc: Mario Limonciello Reviewed-by: Alvin Lee Signed-off-by: Roman Li Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher (cherry picked from commit f6e09701c3eb2ccb8cb0518e0b67f1c69742a4ec) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h index ded71ea82413..8968aa2bf156 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h @@ -67,11 +67,15 @@ static inline double dml_max5(double a, double b, double c, double d, double e) static inline double dml_ceil(double a, double granularity) { + if (granularity == 0) + return 0; return (double) dcn_bw_ceil2(a, granularity); } static inline double dml_floor(double a, double granularity) { + if (granularity == 0) + return 0; return (double) dcn_bw_floor2(a, granularity); } @@ -97,11 +101,15 @@ static inline double dml_ceil_2(double f) static inline double dml_ceil_ex(double x, double granularity) { + if (granularity == 0) + return 0; return (double) dcn_bw_ceil2(x, granularity); } static inline double dml_floor_ex(double x, double granularity) { + if (granularity == 0) + return 0; return (double) dcn_bw_floor2(x, granularity); } From b03307c1a1b01bfa8e972015ae8ae361f52ce801 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 28 Dec 2024 17:48:45 +0100 Subject: [PATCH 032/138] ACPI: resource: Add TongFang GM5HG0A to irq1_edge_low_force_override[] commit 7ed4e4a659d99499dc6968c61970d41b64feeac0 upstream. The TongFang GM5HG0A is a TongFang barebone design which is sold under various brand names. The ACPI IRQ override for the keyboard IRQ must be used on these AMD Zen laptops in order for the IRQ to work. At least on the SKIKK Vanaheim variant the DMI product- and board-name strings have been replaced by the OEM with "Vanaheim" so checking that board-name contains "GM5HG0A" as is usually done for TongFang barebones quirks does not work. The DMI OEM strings do contain "GM5HG0A". I have looked at the dmidecode for a few other TongFang devices and the TongFang code-name string being in the OEM strings seems to be something which is consistently true. Add a quirk checking one of the DMI_OEM_STRING(s) is "GM5HG0A" in the hope that this will work for other OEM versions of the "GM5HG0A" too. Link: https://www.skikk.eu/en/laptops/vanaheim-15-rtx-4060 Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219614 Cc: All applicable Signed-off-by: Hans de Goede Link: https://patch.msgid.link/20241228164845.42381-1-hdegoede@redhat.com Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/resource.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 65567f26d7bd..d82854899475 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -514,6 +514,17 @@ static const struct dmi_system_id asus_laptop[] = { DMI_MATCH(DMI_BOARD_NAME, "16T90SP"), }, }, + { + /* + * TongFang GM5HG0A in case of the SKIKK Vanaheim relabel the + * board-name is changed, so check OEM strings instead. Note + * OEM string matches are always exact matches. + * https://bugzilla.kernel.org/show_bug.cgi?id=219614 + */ + .matches = { + DMI_EXACT_MATCH(DMI_OEM_STRING, "GM5HG0A"), + }, + }, { } }; From 9771233b7ab118bd162d2513765051c220e7a09b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 20 Dec 2024 19:13:52 +0100 Subject: [PATCH 033/138] ACPI: resource: Add Asus Vivobook X1504VAP to irq1_level_low_skip_override[] commit 66d337fede44dcbab4107d37684af8fcab3d648e upstream. Like the Vivobook X1704VAP the X1504VAP has its keyboard IRQ (1) described as ActiveLow in the DSDT, which the kernel overrides to EdgeHigh which breaks the keyboard. Add the X1504VAP to the irq1_level_low_skip_override[] quirk table to fix this. Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219224 Cc: All applicable Signed-off-by: Hans de Goede Link: https://patch.msgid.link/20241220181352.25974-1-hdegoede@redhat.com Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/resource.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index d82854899475..2750518a5d5e 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -442,6 +442,13 @@ static const struct dmi_system_id asus_laptop[] = { DMI_MATCH(DMI_BOARD_NAME, "B2402CBA"), }, }, + { + /* Asus Vivobook X1504VAP */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "X1504VAP"), + }, + }, { /* Asus Vivobook X1704VAP */ .matches = { From 04301fadfb52630efd2838371f52ff311e2a3d3e Mon Sep 17 00:00:00 2001 From: Melissa Wen Date: Tue, 17 Dec 2024 17:45:04 -0300 Subject: [PATCH 034/138] drm/amd/display: increase MAX_SURFACES to the value supported by hw commit 21541bc6b44241e3f791f9e552352d8440b2b29e upstream. As the hw supports up to 4 surfaces, increase the maximum number of surfaces to prevent the DC error when trying to use more than three planes. [drm:dc_state_add_plane [amdgpu]] *ERROR* Surface: can not attach plane_state 000000003e2cb82c! Maximum is: 3 Link: https://gitlab.freedesktop.org/drm/amd/-/issues/3693 Signed-off-by: Melissa Wen Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher (cherry picked from commit b8d6daffc871a42026c3c20bff7b8fa0302298c1) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index a82352a87808..1c14c8295b45 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -41,7 +41,7 @@ #define DC_VER "3.2.48" -#define MAX_SURFACES 3 +#define MAX_SURFACES 4 #define MAX_PLANES 6 #define MAX_STREAMS 6 #define MAX_SINKS_PER_LINK 4 From f8d57de3c8018d49f5bb69b814e3392224bfe285 Mon Sep 17 00:00:00 2001 From: Chukun Pan Date: Sun, 15 Dec 2024 18:00:27 +0800 Subject: [PATCH 035/138] USB: serial: option: add MeiG Smart SRM815 commit c1947d244f807b1f95605b75a4059e7b37b5dcc3 upstream. It looks like SRM815 shares ID with SRM825L. T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=2dee ProdID=4d22 Rev= 4.14 S: Manufacturer=MEIG S: Product=LTE-A Module S: SerialNumber=123456 C:* #Ifs= 5 Cfg#= 1 Atr=80 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Chukun Pan Link: https://lore.kernel.org/lkml/20241215100027.1970930-1-amadeus@jmu.edu.cn/ Link: https://lore.kernel.org/all/4333b4d0-281f-439d-9944-5570cbc4971d@gmail.com/ Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 3ae4ac4d9857..98b18ec3a057 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -621,7 +621,7 @@ static void option_instat_callback(struct urb *urb); /* MeiG Smart Technology products */ #define MEIGSMART_VENDOR_ID 0x2dee -/* MeiG Smart SRM825L based on Qualcomm 315 */ +/* MeiG Smart SRM815/SRM825L based on Qualcomm 315 */ #define MEIGSMART_PRODUCT_SRM825L 0x4d22 /* MeiG Smart SLM320 based on UNISOC UIS8910 */ #define MEIGSMART_PRODUCT_SLM320 0x4d41 @@ -2405,6 +2405,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM770A, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) }, From dffc4f7d2eca68c96aef58bb762805840928e976 Mon Sep 17 00:00:00 2001 From: Michal Hrusecky Date: Tue, 7 Jan 2025 17:08:29 +0100 Subject: [PATCH 036/138] USB: serial: option: add Neoway N723-EA support commit f5b435be70cb126866fa92ffc6f89cda9e112c75 upstream. Update the USB serial option driver to support Neoway N723-EA. ID 2949:8700 Marvell Mobile Composite Device Bus T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=2949 ProdID=8700 Rev= 1.00 S: Manufacturer=Marvell S: Product=Mobile Composite Device Bus S: SerialNumber=200806006809080000 C:* #Ifs= 5 Cfg#= 1 Atr=c0 MxPwr=500mA A: FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=03 I:* If#= 0 Alt= 0 #EPs= 1 Cls=e0(wlcon) Sub=01 Prot=03 Driver=rndis_host E: Ad=87(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=89(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=86(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0e(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 6 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=88(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms Tested successfully connecting to the Internet via rndis interface after dialing via AT commands on If#=4 or If#=6. Not sure of the purpose of the other serial interface. Signed-off-by: Michal Hrusecky Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 98b18ec3a057..79f8e3a043fc 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -2413,6 +2413,7 @@ static const struct usb_device_id option_ids[] = { .driver_info = NCTRL(1) }, { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */ .driver_info = NCTRL(3) }, + { USB_DEVICE_INTERFACE_CLASS(0x2949, 0x8700, 0xff) }, /* Neoway N723-EA */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); From 9d16b310e428ac596bb52d4d890c2c203f6a0234 Mon Sep 17 00:00:00 2001 From: Zicheng Qu Date: Thu, 7 Nov 2024 01:10:14 +0000 Subject: [PATCH 037/138] staging: iio: ad9834: Correct phase range check commit c0599762f0c7e260b99c6b7bceb8eae69b804c94 upstream. User Perspective: When a user sets the phase value, the ad9834_write_phase() is called. The phase register has a 12-bit resolution, so the valid range is 0 to 4095. If the phase offset value of 4096 is input, it effectively exactly equals 0 in the lower 12 bits, meaning no offset. Reasons for the Change: 1) Original Condition (phase > BIT(AD9834_PHASE_BITS)): This condition allows a phase value equal to 2^12, which is 4096. However, this value exceeds the valid 12-bit range, as the maximum valid phase value should be 4095. 2) Modified Condition (phase >= BIT(AD9834_PHASE_BITS)): Ensures that the phase value is within the valid range, preventing invalid datafrom being written. Impact on Subsequent Logic: st->data = cpu_to_be16(addr | phase): If the phase value is 2^12, i.e., 4096 (0001 0000 0000 0000), and addr is AD9834_REG_PHASE0 (1100 0000 0000 0000), then addr | phase results in 1101 0000 0000 0000, occupying DB12. According to the section of WRITING TO A PHASE REGISTER in the datasheet, the MSB 12 PHASE0 bits should be DB11. The original condition leads to incorrect DB12 usage, which contradicts the datasheet and could pose potential issues for future updates if DB12 is used in such related cases. Fixes: 12b9d5bf76bf ("Staging: IIO: DDS: AD9833 / AD9834 driver") Cc: stable@vger.kernel.org Signed-off-by: Zicheng Qu Reviewed-by: Dan Carpenter Link: https://patch.msgid.link/20241107011015.2472600-2-quzicheng@huawei.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/frequency/ad9834.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c index 2e661a905a57..ecf74a65a6f0 100644 --- a/drivers/staging/iio/frequency/ad9834.c +++ b/drivers/staging/iio/frequency/ad9834.c @@ -132,7 +132,7 @@ static int ad9834_write_frequency(struct ad9834_state *st, static int ad9834_write_phase(struct ad9834_state *st, unsigned long addr, unsigned long phase) { - if (phase > BIT(AD9834_PHASE_BITS)) + if (phase >= BIT(AD9834_PHASE_BITS)) return -EINVAL; st->data = cpu_to_be16(addr | phase); From dd4f2d935d580f40f4ce74c80672254ea37b02d3 Mon Sep 17 00:00:00 2001 From: Zicheng Qu Date: Thu, 7 Nov 2024 01:10:15 +0000 Subject: [PATCH 038/138] staging: iio: ad9832: Correct phase range check commit 4636e859ebe0011f41e35fa79bab585b8004e9a3 upstream. User Perspective: When a user sets the phase value, the ad9832_write_phase() is called. The phase register has a 12-bit resolution, so the valid range is 0 to 4095. If the phase offset value of 4096 is input, it effectively exactly equals 0 in the lower 12 bits, meaning no offset. Reasons for the Change: 1) Original Condition (phase > BIT(AD9832_PHASE_BITS)): This condition allows a phase value equal to 2^12, which is 4096. However, this value exceeds the valid 12-bit range, as the maximum valid phase value should be 4095. 2) Modified Condition (phase >= BIT(AD9832_PHASE_BITS)): Ensures that the phase value is within the valid range, preventing invalid datafrom being written. Impact on Subsequent Logic: st->data = cpu_to_be16(addr | phase): If the phase value is 2^12, i.e., 4096 (0001 0000 0000 0000), and addr is AD9832_REG_PHASE0 (1100 0000 0000 0000), then addr | phase results in 1101 0000 0000 0000, occupying DB12. According to the section of WRITING TO A PHASE REGISTER in the datasheet, the MSB 12 PHASE0 bits should be DB11. The original condition leads to incorrect DB12 usage, which contradicts the datasheet and could pose potential issues for future updates if DB12 is used in such related cases. Fixes: ea707584bac1 ("Staging: IIO: DDS: AD9832 / AD9835 driver") Cc: stable@vger.kernel.org Signed-off-by: Zicheng Qu Link: https://patch.msgid.link/20241107011015.2472600-3-quzicheng@huawei.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/frequency/ad9832.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c index d4e04f439865..8097f3fe4688 100644 --- a/drivers/staging/iio/frequency/ad9832.c +++ b/drivers/staging/iio/frequency/ad9832.c @@ -158,7 +158,7 @@ static int ad9832_write_frequency(struct ad9832_state *st, static int ad9832_write_phase(struct ad9832_state *st, unsigned long addr, unsigned long phase) { - if (phase > BIT(AD9832_PHASE_BITS)) + if (phase >= BIT(AD9832_PHASE_BITS)) return -EINVAL; st->phase_data[0] = cpu_to_be16((AD9832_CMD_PHA8BITSW << CMD_SHIFT) | From a5754f733185419d507634d2c0993ce147370ce5 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 1 Jan 2025 22:22:06 +0100 Subject: [PATCH 039/138] usb-storage: Add max sectors quirk for Nokia 208 commit cdef30e0774802df2f87024d68a9d86c3b99ca2a upstream. This fixes data corruption when accessing the internal SD card in mass storage mode. I am actually not too sure why. I didn't figure a straightforward way to reproduce the issue, but i seem to get garbage when issuing a lot (over 50) of large reads (over 120 sectors) are done in a quick succession. That is, time seems to matter here -- larger reads are fine if they are done with some delay between them. But I'm not great at understanding this sort of things, so I'll assume the issue other, smarter, folks were seeing with similar phones is the same problem and I'll just put my quirk next to theirs. The "Software details" screen on the phone is as follows: V 04.06 07-08-13 RM-849 (c) Nokia TL;DR version of the device descriptor: idVendor 0x0421 Nokia Mobile Phones idProduct 0x06c2 bcdDevice 4.06 iManufacturer 1 Nokia iProduct 2 Nokia 208 The patch assumes older firmwares are broken too (I'm unable to test, but no biggie if they aren't I guess), and I have no idea if newer firmware exists. Signed-off-by: Lubomir Rintel Cc: stable Acked-by: Alan Stern Link: https://lore.kernel.org/r/20250101212206.2386207-1-lkundrak@v3.sk Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 606a68bd8059..a6dc2faae85d 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -255,6 +255,13 @@ UNUSUAL_DEV( 0x0421, 0x06aa, 0x1110, 0x1110, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_MAX_SECTORS_64 ), +/* Added by Lubomir Rintel , a very fine chap */ +UNUSUAL_DEV( 0x0421, 0x06c2, 0x0000, 0x0406, + "Nokia", + "Nokia 208", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 ), + #ifdef NO_SDDR09 UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100, "Microtech", From faa0eeaf36257eb655641e1d808dd89c63ed0102 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 8 Jan 2025 11:24:36 +0100 Subject: [PATCH 040/138] USB: serial: cp210x: add Phoenix Contact UPS Device commit 854eee93bd6e3dca619d47087af4d65b2045828e upstream. Phoenix Contact sells UPS Quint devices [1] with a custom datacable [2] that embeds a Silicon Labs converter: Bus 001 Device 003: ID 1b93:1013 Silicon Labs Phoenix Contact UPS Device Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x1b93 idProduct 0x1013 bcdDevice 1.00 iManufacturer 1 Silicon Labs iProduct 2 Phoenix Contact UPS Device iSerial 3 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 0x0020 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 2 Phoenix Contact UPS Device Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 [1] https://www.phoenixcontact.com/en-pc/products/power-supply-unit-quint-ps-1ac-24dc-10-2866763 [2] https://www.phoenixcontact.com/en-il/products/data-cable-preassembled-ifs-usb-datacable-2320500 Reported-by: Giuseppe Corbelli Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 5353fa7e5969..39c9d1f857fc 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -224,6 +224,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */ { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */ + { USB_DEVICE(0x1B93, 0x1013) }, /* Phoenix Contact UPS Device */ { USB_DEVICE(0x1BA4, 0x0002) }, /* Silicon Labs 358x factory default */ { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ { USB_DEVICE(0x1D6F, 0x0010) }, /* Seluxit ApS RF Dongle */ From f5f33fb57aae12e4b0add79e0242f458ea0bc510 Mon Sep 17 00:00:00 2001 From: Lianqin Hu Date: Tue, 17 Dec 2024 07:58:44 +0000 Subject: [PATCH 041/138] usb: gadget: u_serial: Disable ep before setting port to null to fix the crash caused by port being null commit 13014969cbf07f18d62ceea40bd8ca8ec9d36cec upstream. Considering that in some extreme cases, when performing the unbinding operation, gserial_disconnect has cleared gser->ioport, which triggers gadget reconfiguration, and then calls gs_read_complete, resulting in access to a null pointer. Therefore, ep is disabled before gserial_disconnect sets port to null to prevent this from happening. Call trace: gs_read_complete+0x58/0x240 usb_gadget_giveback_request+0x40/0x160 dwc3_remove_requests+0x170/0x484 dwc3_ep0_out_start+0xb0/0x1d4 __dwc3_gadget_start+0x25c/0x720 kretprobe_trampoline.cfi_jt+0x0/0x8 kretprobe_trampoline.cfi_jt+0x0/0x8 udc_bind_to_driver+0x1d8/0x300 usb_gadget_probe_driver+0xa8/0x1dc gadget_dev_desc_UDC_store+0x13c/0x188 configfs_write_iter+0x160/0x1f4 vfs_write+0x2d0/0x40c ksys_write+0x7c/0xf0 __arm64_sys_write+0x20/0x30 invoke_syscall+0x60/0x150 el0_svc_common+0x8c/0xf8 do_el0_svc+0x28/0xa0 el0_svc+0x24/0x84 Fixes: c1dca562be8a ("usb gadget: split out serial core") Cc: stable Suggested-by: Greg Kroah-Hartman Signed-off-by: Lianqin Hu Link: https://lore.kernel.org/r/TYUPR06MB621733B5AC690DBDF80A0DCCD2042@TYUPR06MB6217.apcprd06.prod.outlook.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/u_serial.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index d432f96ec419..ff13887114da 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -1369,6 +1369,10 @@ void gserial_disconnect(struct gserial *gser) /* REVISIT as above: how best to track this? */ port->port_line_coding = gser->port_line_coding; + /* disable endpoints, aborting down any active I/O */ + usb_ep_disable(gser->out); + usb_ep_disable(gser->in); + port->port_usb = NULL; gser->ioport = NULL; if (port->port.count > 0 || port->openclose) { @@ -1378,10 +1382,6 @@ void gserial_disconnect(struct gserial *gser) } spin_unlock_irqrestore(&port->port_lock, flags); - /* disable endpoints, aborting down any active I/O */ - usb_ep_disable(gser->out); - usb_ep_disable(gser->in); - /* finally, free any unused/unusable I/O buffers */ spin_lock_irqsave(&port->port_lock, flags); if (port->port.count == 0 && !port->openclose) From 01af472c23bfe3b084b5e7d1df023a6c82a266ca Mon Sep 17 00:00:00 2001 From: Jun Yan Date: Thu, 12 Dec 2024 22:38:52 +0800 Subject: [PATCH 042/138] USB: usblp: return error when setting unsupported protocol commit 7a3d76a0b60b3f6fc3375e4de2174bab43f64545 upstream. Fix the regression introduced by commit d8c6edfa3f4e ("USB: usblp: don't call usb_set_interface if there's a single alt"), which causes that unsupported protocols can also be set via ioctl when the num_altsetting of the device is 1. Move the check for protocol support to the earlier stage. Fixes: d8c6edfa3f4e ("USB: usblp: don't call usb_set_interface if there's a single alt") Cc: stable Signed-off-by: Jun Yan Link: https://lore.kernel.org/r/20241212143852.671889-1-jerrysteve1101@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usblp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index f27b4aecff3d..759f567538e2 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -1337,11 +1337,12 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol) if (protocol < USBLP_FIRST_PROTOCOL || protocol > USBLP_LAST_PROTOCOL) return -EINVAL; + alts = usblp->protocol[protocol].alt_setting; + if (alts < 0) + return -EINVAL; + /* Don't unnecessarily set the interface if there's a single alt. */ if (usblp->intf->num_altsetting > 1) { - alts = usblp->protocol[protocol].alt_setting; - if (alts < 0) - return -EINVAL; r = usb_set_interface(usblp->dev, usblp->ifnum, alts); if (r < 0) { printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n", From 7369c8ffc2255726ffb6f519c6e2debe28686d94 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Fri, 6 Dec 2024 15:48:17 +0800 Subject: [PATCH 043/138] USB: core: Disable LPM only for non-suspended ports commit 59bfeaf5454b7e764288d84802577f4a99bf0819 upstream. There's USB error when tegra board is shutting down: [ 180.919315] usb 2-3: Failed to set U1 timeout to 0x0,error code -113 [ 180.919995] usb 2-3: Failed to set U1 timeout to 0xa,error code -113 [ 180.920512] usb 2-3: Failed to set U2 timeout to 0x4,error code -113 [ 186.157172] tegra-xusb 3610000.usb: xHCI host controller not responding, assume dead [ 186.157858] tegra-xusb 3610000.usb: HC died; cleaning up [ 186.317280] tegra-xusb 3610000.usb: Timeout while waiting for evaluate context command The issue is caused by disabling LPM on already suspended ports. For USB2 LPM, the LPM is already disabled during port suspend. For USB3 LPM, port won't transit to U1/U2 when it's already suspended in U3, hence disabling LPM is only needed for ports that are not suspended. Cc: Wayne Chang Cc: stable Fixes: d920a2ed8620 ("usb: Disable USB3 LPM at shutdown") Signed-off-by: Kai-Heng Feng Acked-by: Alan Stern Tested-by: Jon Hunter Link: https://lore.kernel.org/r/20241206074817.89189-1-kaihengf@nvidia.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/port.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index 86e8585a5512..f01b0103fe12 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -294,10 +294,11 @@ static int usb_port_runtime_suspend(struct device *dev) static void usb_port_shutdown(struct device *dev) { struct usb_port *port_dev = to_usb_port(dev); + struct usb_device *udev = port_dev->child; - if (port_dev->child) { - usb_disable_usb2_hardware_lpm(port_dev->child); - usb_unlocked_disable_lpm(port_dev->child); + if (udev && !udev->port_is_suspended) { + usb_disable_usb2_hardware_lpm(udev); + usb_unlocked_disable_lpm(udev); } } From b24a6afa564f56e4790edcccc4e04144e5679ae6 Mon Sep 17 00:00:00 2001 From: Ma Ke Date: Wed, 18 Dec 2024 15:13:46 +0800 Subject: [PATCH 044/138] usb: fix reference leak in usb_new_device() commit 0df11fa8cee5a9cf8753d4e2672bb3667138c652 upstream. When device_add(&udev->dev) succeeds and a later call fails, usb_new_device() does not properly call device_del(). As comment of device_add() says, 'if device_add() succeeds, you should call device_del() when you want to get rid of it. If device_add() has not succeeded, use only put_device() to drop the reference count'. Found by code review. Cc: stable Fixes: 9f8b17e643fe ("USB: make usbdevices export their device nodes instead of using a separate class") Signed-off-by: Ma Ke Reviewed-by: Alan Stern Link: https://lore.kernel.org/r/20241218071346.2973980-1-make_ruc2021@163.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 238674fab7ce..686a75c37591 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2592,13 +2592,13 @@ int usb_new_device(struct usb_device *udev) err = sysfs_create_link(&udev->dev.kobj, &port_dev->dev.kobj, "port"); if (err) - goto fail; + goto out_del_dev; err = sysfs_create_link(&port_dev->dev.kobj, &udev->dev.kobj, "device"); if (err) { sysfs_remove_link(&udev->dev.kobj, "port"); - goto fail; + goto out_del_dev; } if (!test_and_set_bit(port1, hub->child_usage_bits)) @@ -2610,6 +2610,8 @@ int usb_new_device(struct usb_device *udev) pm_runtime_put_sync_autosuspend(&udev->dev); return err; +out_del_dev: + device_del(&udev->dev); fail: usb_set_device_state(udev, USB_STATE_NOTATTACHED); pm_runtime_disable(&udev->dev); From bfe60030fcd976e3546e1f73d6d0eb3fea26442e Mon Sep 17 00:00:00 2001 From: Akash M Date: Thu, 19 Dec 2024 18:22:19 +0530 Subject: [PATCH 045/138] usb: gadget: f_fs: Remove WARN_ON in functionfs_bind commit dfc51e48bca475bbee984e90f33fdc537ce09699 upstream. This commit addresses an issue related to below kernel panic where panic_on_warn is enabled. It is caused by the unnecessary use of WARN_ON in functionsfs_bind, which easily leads to the following scenarios. 1.adb_write in adbd 2. UDC write via configfs ================= ===================== ->usb_ffs_open_thread() ->UDC write ->open_functionfs() ->configfs_write_iter() ->adb_open() ->gadget_dev_desc_UDC_store() ->adb_write() ->usb_gadget_register_driver_owner ->driver_register() ->StartMonitor() ->bus_add_driver() ->adb_read() ->gadget_bind_driver() ->configfs_composite_bind() ->usb_add_function() ->open_functionfs() ->ffs_func_bind() ->adb_open() ->functionfs_bind() state !=FFS_ACTIVE> The adb_open, adb_read, and adb_write operations are invoked from the daemon, but trying to bind the function is a process that is invoked by UDC write through configfs, which opens up the possibility of a race condition between the two paths. In this race scenario, the kernel panic occurs due to the WARN_ON from functionfs_bind when panic_on_warn is enabled. This commit fixes the kernel panic by removing the unnecessary WARN_ON. Kernel panic - not syncing: kernel: panic_on_warn set ... [ 14.542395] Call trace: [ 14.542464] ffs_func_bind+0x1c8/0x14a8 [ 14.542468] usb_add_function+0xcc/0x1f0 [ 14.542473] configfs_composite_bind+0x468/0x588 [ 14.542478] gadget_bind_driver+0x108/0x27c [ 14.542483] really_probe+0x190/0x374 [ 14.542488] __driver_probe_device+0xa0/0x12c [ 14.542492] driver_probe_device+0x3c/0x220 [ 14.542498] __driver_attach+0x11c/0x1fc [ 14.542502] bus_for_each_dev+0x104/0x160 [ 14.542506] driver_attach+0x24/0x34 [ 14.542510] bus_add_driver+0x154/0x270 [ 14.542514] driver_register+0x68/0x104 [ 14.542518] usb_gadget_register_driver_owner+0x48/0xf4 [ 14.542523] gadget_dev_desc_UDC_store+0xf8/0x144 [ 14.542526] configfs_write_iter+0xf0/0x138 Fixes: ddf8abd25994 ("USB: f_fs: the FunctionFS driver") Cc: stable Signed-off-by: Akash M Link: https://lore.kernel.org/r/20241219125221.1679-1-akash.m5@samsung.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 53658162b148..9b5f9d503ff0 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -1875,7 +1875,7 @@ static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev) ENTER(); - if (WARN_ON(ffs->state != FFS_ACTIVE + if ((ffs->state != FFS_ACTIVE || test_and_set_bit(FFS_FL_BOUND, &ffs->flags))) return -EBADFD; From 9629ff1a86823269b12fb1ba9ca4efa945906287 Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Mon, 25 Nov 2024 22:16:11 +0100 Subject: [PATCH 046/138] iio: pressure: zpa2326: fix information leak in triggered buffer commit 6007d10c5262f6f71479627c1216899ea7f09073 upstream. The 'sample' local struct is used to push data to user space from a triggered buffer, but it has a hole between the temperature and the timestamp (u32 pressure, u16 temperature, GAP, u64 timestamp). This hole is never initialized. Initialize the struct to zero before using it to avoid pushing uninitialized information to userspace. Cc: stable@vger.kernel.org Fixes: 03b262f2bbf4 ("iio:pressure: initial zpa2326 barometer support") Signed-off-by: Javier Carrasco Link: https://patch.msgid.link/20241125-iio_memset_scan_holes-v1-3-0cb6e98d895c@gmail.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/pressure/zpa2326.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c index 7f2e5a8942a4..df60b3d91dad 100644 --- a/drivers/iio/pressure/zpa2326.c +++ b/drivers/iio/pressure/zpa2326.c @@ -585,6 +585,8 @@ static int zpa2326_fill_sample_buffer(struct iio_dev *indio_dev, } sample; int err; + memset(&sample, 0, sizeof(sample)); + if (test_bit(0, indio_dev->active_scan_mask)) { /* Get current pressure from hardware FIFO. */ err = zpa2326_dequeue_pressure(indio_dev, &sample.pressure); From 03fa47621bf8fcbf5994c5716021527853f9af3d Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Mon, 25 Nov 2024 22:16:17 +0100 Subject: [PATCH 047/138] iio: dummy: iio_simply_dummy_buffer: fix information leak in triggered buffer commit 333be433ee908a53f283beb95585dfc14c8ffb46 upstream. The 'data' array is allocated via kmalloc() and it is used to push data to user space from a triggered buffer, but it does not set values for inactive channels, as it only uses iio_for_each_active_channel() to assign new values. Use kzalloc for the memory allocation to avoid pushing uninitialized information to userspace. Cc: stable@vger.kernel.org Fixes: 415f79244757 ("iio: Move IIO Dummy Driver out of staging") Signed-off-by: Javier Carrasco Link: https://patch.msgid.link/20241125-iio_memset_scan_holes-v1-9-0cb6e98d895c@gmail.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/dummy/iio_simple_dummy_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/dummy/iio_simple_dummy_buffer.c b/drivers/iio/dummy/iio_simple_dummy_buffer.c index 17606eca42b4..0615d34d908b 100644 --- a/drivers/iio/dummy/iio_simple_dummy_buffer.c +++ b/drivers/iio/dummy/iio_simple_dummy_buffer.c @@ -48,7 +48,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) int len = 0; u16 *data; - data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); + data = kzalloc(indio_dev->scan_bytes, GFP_KERNEL); if (!data) goto done; From 13e56229fc81051a42731046e200493c4a7c28ff Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Mon, 25 Nov 2024 22:16:14 +0100 Subject: [PATCH 048/138] iio: light: vcnl4035: fix information leak in triggered buffer commit 47b43e53c0a0edf5578d5d12f5fc71c019649279 upstream. The 'buffer' local array is used to push data to userspace from a triggered buffer, but it does not set an initial value for the single data element, which is an u16 aligned to 8 bytes. That leaves at least 4 bytes uninitialized even after writing an integer value with regmap_read(). Initialize the array to zero before using it to avoid pushing uninitialized information to userspace. Cc: stable@vger.kernel.org Fixes: ec90b52c07c0 ("iio: light: vcnl4035: Fix buffer alignment in iio_push_to_buffers_with_timestamp()") Signed-off-by: Javier Carrasco Link: https://patch.msgid.link/20241125-iio_memset_scan_holes-v1-6-0cb6e98d895c@gmail.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/light/vcnl4035.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/light/vcnl4035.c b/drivers/iio/light/vcnl4035.c index 6c83f9e54e2e..940b80c81d52 100644 --- a/drivers/iio/light/vcnl4035.c +++ b/drivers/iio/light/vcnl4035.c @@ -105,7 +105,7 @@ static irqreturn_t vcnl4035_trigger_consumer_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct vcnl4035_data *data = iio_priv(indio_dev); /* Ensure naturally aligned timestamp */ - u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)] __aligned(8); + u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)] __aligned(8) = { }; int ret; ret = regmap_read(data->regmap, VCNL4035_ALS_DATA, (int *)buffer); From 0871eb8d700b33dd7fa86c80630d62ddaef58c2c Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Mon, 25 Nov 2024 22:16:13 +0100 Subject: [PATCH 049/138] iio: imu: kmx61: fix information leak in triggered buffer commit 6ae053113f6a226a2303caa4936a4c37f3bfff7b upstream. The 'buffer' local array is used to push data to user space from a triggered buffer, but it does not set values for inactive channels, as it only uses iio_for_each_active_channel() to assign new values. Initialize the array to zero before using it to avoid pushing uninitialized information to userspace. Cc: stable@vger.kernel.org Fixes: c3a23ecc0901 ("iio: imu: kmx61: Add support for data ready triggers") Signed-off-by: Javier Carrasco Link: https://patch.msgid.link/20241125-iio_memset_scan_holes-v1-5-0cb6e98d895c@gmail.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/imu/kmx61.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c index c7d19f9ca765..fb01b64d356a 100644 --- a/drivers/iio/imu/kmx61.c +++ b/drivers/iio/imu/kmx61.c @@ -1198,7 +1198,7 @@ static irqreturn_t kmx61_trigger_handler(int irq, void *p) struct kmx61_data *data = kmx61_get_data(indio_dev); int bit, ret, i = 0; u8 base; - s16 buffer[8]; + s16 buffer[8] = { }; if (indio_dev == data->acc_indio_dev) base = KMX61_ACC_XOUT_L; From 1c80a0985a9a14f33dbf63cd703ca010f094f878 Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Mon, 25 Nov 2024 22:16:16 +0100 Subject: [PATCH 050/138] iio: adc: ti-ads8688: fix information leak in triggered buffer commit 2a7377ccfd940cd6e9201756aff1e7852c266e69 upstream. The 'buffer' local array is used to push data to user space from a triggered buffer, but it does not set values for inactive channels, as it only uses iio_for_each_active_channel() to assign new values. Initialize the array to zero before using it to avoid pushing uninitialized information to userspace. Cc: stable@vger.kernel.org Fixes: 61fa5dfa5f52 ("iio: adc: ti-ads8688: Fix alignment of buffer in iio_push_to_buffers_with_timestamp()") Signed-off-by: Javier Carrasco Link: https://patch.msgid.link/20241125-iio_memset_scan_holes-v1-8-0cb6e98d895c@gmail.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/ti-ads8688.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c index 55a2d619d6dd..f0f16bc68865 100644 --- a/drivers/iio/adc/ti-ads8688.c +++ b/drivers/iio/adc/ti-ads8688.c @@ -384,7 +384,7 @@ static irqreturn_t ads8688_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; /* Ensure naturally aligned timestamp */ - u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)] __aligned(8); + u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)] __aligned(8) = { }; int i, j = 0; for (i = 0; i < indio_dev->masklength; i++) { From 4bb2b90fc971094fde2bfa193a692d5fddda620b Mon Sep 17 00:00:00 2001 From: Carlos Song Date: Sat, 16 Nov 2024 10:29:45 -0500 Subject: [PATCH 051/138] iio: gyro: fxas21002c: Fix missing data update in trigger handler commit fa13ac6cdf9b6c358e7d77c29fb60145c7a87965 upstream. The fxas21002c_trigger_handler() may fail to acquire sample data because the runtime PM enters the autosuspend state and sensor can not return sample data in standby mode.. Resume the sensor before reading the sample data into the buffer within the trigger handler. After the data is read, place the sensor back into the autosuspend state. Fixes: a0701b6263ae ("iio: gyro: add core driver for fxas21002c") Signed-off-by: Carlos Song Signed-off-by: Frank Li Link: https://patch.msgid.link/20241116152945.4006374-1-Frank.Li@nxp.com Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/gyro/fxas21002c_core.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/iio/gyro/fxas21002c_core.c b/drivers/iio/gyro/fxas21002c_core.c index 45e2b5b33072..891969a805b7 100644 --- a/drivers/iio/gyro/fxas21002c_core.c +++ b/drivers/iio/gyro/fxas21002c_core.c @@ -664,14 +664,21 @@ static irqreturn_t fxas21002c_trigger_handler(int irq, void *p) int ret; mutex_lock(&data->lock); - ret = regmap_bulk_read(data->regmap, FXAS21002C_REG_OUT_X_MSB, - data->buffer, CHANNEL_SCAN_MAX * sizeof(s16)); + ret = fxas21002c_pm_get(data); if (ret < 0) goto out_unlock; + ret = regmap_bulk_read(data->regmap, FXAS21002C_REG_OUT_X_MSB, + data->buffer, CHANNEL_SCAN_MAX * sizeof(s16)); + if (ret < 0) + goto out_pm_put; + iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, data->timestamp); +out_pm_put: + fxas21002c_pm_put(data); + out_unlock: mutex_unlock(&data->lock); From 5856a85425ae41ee979eb6aef25b8ea722c0a482 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 22 Nov 2024 13:43:08 -0300 Subject: [PATCH 052/138] iio: adc: ti-ads124s08: Use gpiod_set_value_cansleep() commit 2a8e34096ec70d73ebb6d9920688ea312700cbd9 upstream. Using gpiod_set_value() to control the reset GPIO causes some verbose warnings during boot when the reset GPIO is controlled by an I2C IO expander. As the caller can sleep, use the gpiod_set_value_cansleep() variant to fix the issue. Tested on a custom i.MX93 board with a ADS124S08 ADC. Cc: stable@kernel.org Fixes: e717f8c6dfec ("iio: adc: Add the TI ads124s08 ADC code") Signed-off-by: Fabio Estevam Link: https://patch.msgid.link/20241122164308.390340-1-festevam@gmail.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/ti-ads124s08.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/ti-ads124s08.c b/drivers/iio/adc/ti-ads124s08.c index 4b706949a67f..b8a506209c35 100644 --- a/drivers/iio/adc/ti-ads124s08.c +++ b/drivers/iio/adc/ti-ads124s08.c @@ -182,9 +182,9 @@ static int ads124s_reset(struct iio_dev *indio_dev) struct ads124s_private *priv = iio_priv(indio_dev); if (priv->reset_gpio) { - gpiod_set_value(priv->reset_gpio, 0); + gpiod_set_value_cansleep(priv->reset_gpio, 0); udelay(200); - gpiod_set_value(priv->reset_gpio, 1); + gpiod_set_value_cansleep(priv->reset_gpio, 1); } else { return ads124s_write_cmd(indio_dev, ADS124S08_CMD_RESET); } From b549c90bfe66f704878aa1e57b30ba15dab71935 Mon Sep 17 00:00:00 2001 From: Joe Hattori Date: Sat, 7 Dec 2024 13:30:45 +0900 Subject: [PATCH 053/138] iio: adc: at91: call input_free_device() on allocated iio_dev commit de6a73bad1743e9e81ea5a24c178c67429ff510b upstream. Current implementation of at91_ts_register() calls input_free_deivce() on st->ts_input, however, the err label can be reached before the allocated iio_dev is stored to st->ts_input. Thus call input_free_device() on input instead of st->ts_input. Fixes: 84882b060301 ("iio: adc: at91_adc: Add support for touchscreens without TSMR") Signed-off-by: Joe Hattori Link: https://patch.msgid.link/20241207043045.1255409-1-joe@pf.is.s.u-tokyo.ac.jp Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/at91_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index cc81b35ca47a..4226e307ab27 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -1139,7 +1139,7 @@ static int at91_ts_register(struct at91_adc_state *st, return ret; err: - input_free_device(st->ts_input); + input_free_device(input); return ret; } From 56c85e6bc9cd7d4d935f013f211ed9acecba3acb Mon Sep 17 00:00:00 2001 From: Joe Hattori Date: Wed, 4 Dec 2024 20:13:42 +0900 Subject: [PATCH 054/138] iio: inkern: call iio_device_put() only on mapped devices commit 64f43895b4457532a3cc524ab250b7a30739a1b1 upstream. In the error path of iio_channel_get_all(), iio_device_put() is called on all IIO devices, which can cause a refcount imbalance. Fix this error by calling iio_device_put() only on IIO devices whose refcounts were previously incremented by iio_device_get(). Fixes: 314be14bb893 ("iio: Rename _st_ functions to loose the bit that meant the staging version.") Signed-off-by: Joe Hattori Link: https://patch.msgid.link/20241204111342.1246706-1-joe@pf.is.s.u-tokyo.ac.jp Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/inkern.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 730c821b5221..6374d5091555 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -466,7 +466,7 @@ struct iio_channel *iio_channel_get_all(struct device *dev) return chans; error_free_chans: - for (i = 0; i < nummaps; i++) + for (i = 0; i < mapind; i++) iio_device_put(chans[i].indio_dev); kfree(chans); error_ret: From a0dfff81549fc7858045339995a8d0930150eadd Mon Sep 17 00:00:00 2001 From: Johan Jonker Date: Tue, 28 Apr 2020 22:30:02 +0200 Subject: [PATCH 055/138] arm64: dts: rockchip: fix defines in pd_vio node for rk3399 [ Upstream commit 84836ded76ec9a6f25d1d0acebaad44977e0ec6f ] A test with the command below gives for example this error: arch/arm64/boot/dts/rockchip/rk3399-evb.dt.yaml: pd_vio@15: 'pd_tcpc0@RK3399_PD_TCPC0', 'pd_tcpc1@RK3399_PD_TCPC1' do not match any of the regexes: '.*-names$', '.*-supply$', '^#.*-cells$', '^#[a-zA-Z0-9,+\\-._]{0,63}$', '^[a-zA-Z][a-zA-Z0-9,+\\-._]{0,63}$', '^[a-zA-Z][a-zA-Z0-9,+\\-._]{0,63}@[0-9a-fA-F]+(,[0-9a-fA-F]+)*$', '^__.*__$', 'pinctrl-[0-9]+' Fix error by replacing the wrong defines by the ones mentioned in 'rk3399-power.h'. make -k ARCH=arm64 dtbs_check Signed-off-by: Johan Jonker Link: https://lore.kernel.org/r/20200428203003.3318-1-jbx6244@gmail.com Signed-off-by: Heiko Stuebner Stable-dep-of: 3699f2c43ea9 ("arm64: dts: rockchip: add hevc power domain clock to rk3328") Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/rockchip/rk3399.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index e5a25bc7d799..dcd989563d27 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -1089,12 +1089,12 @@ pm_qos = <&qos_isp1_m0>, <&qos_isp1_m1>; }; - pd_tcpc0@RK3399_PD_TCPC0 { + pd_tcpc0@RK3399_PD_TCPD0 { reg = ; clocks = <&cru SCLK_UPHY0_TCPDCORE>, <&cru SCLK_UPHY0_TCPDPHY_REF>; }; - pd_tcpc1@RK3399_PD_TCPC1 { + pd_tcpc1@RK3399_PD_TCPD1 { reg = ; clocks = <&cru SCLK_UPHY1_TCPDCORE>, <&cru SCLK_UPHY1_TCPDPHY_REF>; From 2aa7a5086942924061d5804beade4455544fda4e Mon Sep 17 00:00:00 2001 From: Johan Jonker Date: Tue, 28 Apr 2020 22:30:03 +0200 Subject: [PATCH 056/138] arm64: dts: rockchip: fix pd_tcpc0 and pd_tcpc1 node position on rk3399 [ Upstream commit 2b99e6196663199409540fb95798dba464e34343 ] The pd_tcpc0 and pd_tcpc1 nodes are currently a sub node of pd_vio. In the rk3399 TRM figure of the 'Power Domain Partition' and in the table of 'Power Domain and Voltage Domain Summary' these power domains are positioned directly under VD_LOGIC, so fix that in 'rk3399.dtsi'. Signed-off-by: Johan Jonker Reviewed-by: Caesar Wang Link: https://lore.kernel.org/r/20200428203003.3318-2-jbx6244@gmail.com Signed-off-by: Heiko Stuebner Stable-dep-of: 3699f2c43ea9 ("arm64: dts: rockchip: add hevc power domain clock to rk3328") Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/rockchip/rk3399.dtsi | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index dcd989563d27..04ca346b2f28 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -1057,6 +1057,16 @@ clocks = <&cru HCLK_SDIO>; pm_qos = <&qos_sdioaudio>; }; + pd_tcpc0@RK3399_PD_TCPD0 { + reg = ; + clocks = <&cru SCLK_UPHY0_TCPDCORE>, + <&cru SCLK_UPHY0_TCPDPHY_REF>; + }; + pd_tcpc1@RK3399_PD_TCPD1 { + reg = ; + clocks = <&cru SCLK_UPHY1_TCPDCORE>, + <&cru SCLK_UPHY1_TCPDPHY_REF>; + }; pd_usb3@RK3399_PD_USB3 { reg = ; clocks = <&cru ACLK_USB3>; @@ -1089,16 +1099,6 @@ pm_qos = <&qos_isp1_m0>, <&qos_isp1_m1>; }; - pd_tcpc0@RK3399_PD_TCPD0 { - reg = ; - clocks = <&cru SCLK_UPHY0_TCPDCORE>, - <&cru SCLK_UPHY0_TCPDPHY_REF>; - }; - pd_tcpc1@RK3399_PD_TCPD1 { - reg = ; - clocks = <&cru SCLK_UPHY1_TCPDCORE>, - <&cru SCLK_UPHY1_TCPDPHY_REF>; - }; pd_vo@RK3399_PD_VO { reg = ; #address-cells = <1>; From 2c574e1a1c3e1590b7fa46857c6ca75c3b1f73a4 Mon Sep 17 00:00:00 2001 From: Johan Jonker Date: Sat, 17 Apr 2021 13:29:45 +0200 Subject: [PATCH 057/138] arm64: dts: rockchip: add #power-domain-cells to power domain nodes [ Upstream commit 837188d49823230f47afdbbec7556740e89a8557 ] Add #power-domain-cells to power domain nodes, because they are required by power-domain.yaml Signed-off-by: Johan Jonker Link: https://lore.kernel.org/r/20210417112952.8516-9-jbx6244@gmail.com Signed-off-by: Heiko Stuebner Stable-dep-of: 3699f2c43ea9 ("arm64: dts: rockchip: add hevc power domain clock to rk3328") Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/rockchip/px30.dtsi | 8 ++++++++ arch/arm64/boot/dts/rockchip/rk3328.dtsi | 3 +++ arch/arm64/boot/dts/rockchip/rk3399.dtsi | 20 ++++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi index f297601c9f71..652998c83640 100644 --- a/arch/arm64/boot/dts/rockchip/px30.dtsi +++ b/arch/arm64/boot/dts/rockchip/px30.dtsi @@ -219,12 +219,14 @@ <&cru HCLK_OTG>, <&cru SCLK_OTG_ADP>; pm_qos = <&qos_usb_host>, <&qos_usb_otg>; + #power-domain-cells = <0>; }; power-domain@PX30_PD_SDCARD { reg = ; clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; pm_qos = <&qos_sdmmc>; + #power-domain-cells = <0>; }; power-domain@PX30_PD_GMAC { reg = ; @@ -233,6 +235,7 @@ <&cru SCLK_MAC_REF>, <&cru SCLK_GMAC_RX_TX>; pm_qos = <&qos_gmac>; + #power-domain-cells = <0>; }; power-domain@PX30_PD_MMC_NAND { reg = ; @@ -246,6 +249,7 @@ <&cru SCLK_SFC>; pm_qos = <&qos_emmc>, <&qos_nand>, <&qos_sdio>, <&qos_sfc>; + #power-domain-cells = <0>; }; power-domain@PX30_PD_VPU { reg = ; @@ -253,6 +257,7 @@ <&cru HCLK_VPU>, <&cru SCLK_CORE_VPU>; pm_qos = <&qos_vpu>, <&qos_vpu_r128>; + #power-domain-cells = <0>; }; power-domain@PX30_PD_VO { reg = ; @@ -269,6 +274,7 @@ <&cru SCLK_VOPB_PWM>; pm_qos = <&qos_rga_rd>, <&qos_rga_wr>, <&qos_vop_m0>, <&qos_vop_m1>; + #power-domain-cells = <0>; }; power-domain@PX30_PD_VI { reg = ; @@ -280,11 +286,13 @@ pm_qos = <&qos_isp_128>, <&qos_isp_rd>, <&qos_isp_wr>, <&qos_isp_m1>, <&qos_vip>; + #power-domain-cells = <0>; }; power-domain@PX30_PD_GPU { reg = ; clocks = <&cru SCLK_GPU>; pm_qos = <&qos_gpu>; + #power-domain-cells = <0>; }; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index 5bb84ec31c6f..d8af608752e3 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -272,13 +272,16 @@ power-domain@RK3328_PD_HEVC { reg = ; + #power-domain-cells = <0>; }; power-domain@RK3328_PD_VIDEO { reg = ; + #power-domain-cells = <0>; }; power-domain@RK3328_PD_VPU { reg = ; clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; + #power-domain-cells = <0>; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 04ca346b2f28..e52c2dc1710a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -1001,6 +1001,7 @@ clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>; pm_qos = <&qos_iep>; + #power-domain-cells = <0>; }; pd_rga@RK3399_PD_RGA { reg = ; @@ -1008,12 +1009,14 @@ <&cru HCLK_RGA>; pm_qos = <&qos_rga_r>, <&qos_rga_w>; + #power-domain-cells = <0>; }; pd_vcodec@RK3399_PD_VCODEC { reg = ; clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>; pm_qos = <&qos_video_m0>; + #power-domain-cells = <0>; }; pd_vdu@RK3399_PD_VDU { reg = ; @@ -1021,6 +1024,7 @@ <&cru HCLK_VDU>; pm_qos = <&qos_video_m1_r>, <&qos_video_m1_w>; + #power-domain-cells = <0>; }; /* These power domains are grouped by VD_GPU */ @@ -1028,53 +1032,63 @@ reg = ; clocks = <&cru ACLK_GPU>; pm_qos = <&qos_gpu>; + #power-domain-cells = <0>; }; /* These power domains are grouped by VD_LOGIC */ pd_edp@RK3399_PD_EDP { reg = ; clocks = <&cru PCLK_EDP_CTRL>; + #power-domain-cells = <0>; }; pd_emmc@RK3399_PD_EMMC { reg = ; clocks = <&cru ACLK_EMMC>; pm_qos = <&qos_emmc>; + #power-domain-cells = <0>; }; pd_gmac@RK3399_PD_GMAC { reg = ; clocks = <&cru ACLK_GMAC>, <&cru PCLK_GMAC>; pm_qos = <&qos_gmac>; + #power-domain-cells = <0>; }; pd_sd@RK3399_PD_SD { reg = ; clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; pm_qos = <&qos_sd>; + #power-domain-cells = <0>; }; pd_sdioaudio@RK3399_PD_SDIOAUDIO { reg = ; clocks = <&cru HCLK_SDIO>; pm_qos = <&qos_sdioaudio>; + #power-domain-cells = <0>; }; pd_tcpc0@RK3399_PD_TCPD0 { reg = ; clocks = <&cru SCLK_UPHY0_TCPDCORE>, <&cru SCLK_UPHY0_TCPDPHY_REF>; + #power-domain-cells = <0>; }; pd_tcpc1@RK3399_PD_TCPD1 { reg = ; clocks = <&cru SCLK_UPHY1_TCPDCORE>, <&cru SCLK_UPHY1_TCPDPHY_REF>; + #power-domain-cells = <0>; }; pd_usb3@RK3399_PD_USB3 { reg = ; clocks = <&cru ACLK_USB3>; pm_qos = <&qos_usb_otg0>, <&qos_usb_otg1>; + #power-domain-cells = <0>; }; pd_vio@RK3399_PD_VIO { reg = ; + #power-domain-cells = <1>; #address-cells = <1>; #size-cells = <0>; @@ -1084,6 +1098,7 @@ <&cru HCLK_HDCP>, <&cru PCLK_HDCP>; pm_qos = <&qos_hdcp>; + #power-domain-cells = <0>; }; pd_isp0@RK3399_PD_ISP0 { reg = ; @@ -1091,6 +1106,7 @@ <&cru HCLK_ISP0>; pm_qos = <&qos_isp0_m0>, <&qos_isp0_m1>; + #power-domain-cells = <0>; }; pd_isp1@RK3399_PD_ISP1 { reg = ; @@ -1098,9 +1114,11 @@ <&cru HCLK_ISP1>; pm_qos = <&qos_isp1_m0>, <&qos_isp1_m1>; + #power-domain-cells = <0>; }; pd_vo@RK3399_PD_VO { reg = ; + #power-domain-cells = <1>; #address-cells = <1>; #size-cells = <0>; @@ -1110,12 +1128,14 @@ <&cru HCLK_VOP0>; pm_qos = <&qos_vop_big_r>, <&qos_vop_big_w>; + #power-domain-cells = <0>; }; pd_vopl@RK3399_PD_VOPL { reg = ; clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>; pm_qos = <&qos_vop_little>; + #power-domain-cells = <0>; }; }; }; From d6c8871e3f109046c9ed46ba4bd14a76e6bb4c48 Mon Sep 17 00:00:00 2001 From: Peter Geis Date: Sat, 14 Dec 2024 22:43:39 +0000 Subject: [PATCH 058/138] arm64: dts: rockchip: add hevc power domain clock to rk3328 [ Upstream commit 3699f2c43ea9984e00d70463f8c29baaf260ea97 ] There is a race condition at startup between disabling power domains not used and disabling clocks not used on the rk3328. When the clocks are disabled first, the hevc power domain fails to shut off leading to a splat of failures. Add the hevc core clock to the rk3328 power domain node to prevent this condition. rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 3-.... } 1087 jiffies s: 89 root: 0x8/. rcu: blocking rcu_node structures (internal RCU debug): Sending NMI from CPU 0 to CPUs 3: NMI backtrace for cpu 3 CPU: 3 UID: 0 PID: 86 Comm: kworker/3:3 Not tainted 6.12.0-rc5+ #53 Hardware name: Firefly ROC-RK3328-CC (DT) Workqueue: pm genpd_power_off_work_fn pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : regmap_unlock_spinlock+0x18/0x30 lr : regmap_read+0x60/0x88 sp : ffff800081123c00 x29: ffff800081123c00 x28: ffff2fa4c62cad80 x27: 0000000000000000 x26: ffffd74e6e660eb8 x25: ffff2fa4c62cae00 x24: 0000000000000040 x23: ffffd74e6d2f3ab8 x22: 0000000000000001 x21: ffff800081123c74 x20: 0000000000000000 x19: ffff2fa4c0412000 x18: 0000000000000000 x17: 77202c31203d2065 x16: 6c6469203a72656c x15: 6c6f72746e6f632d x14: 7265776f703a6e6f x13: 2063766568206e69 x12: 616d6f64202c3431 x11: 347830206f742030 x10: 3430303034783020 x9 : ffffd74e6c7369e0 x8 : 3030316666206e69 x7 : 205d383738353733 x6 : 332e31202020205b x5 : ffffd74e6c73fc88 x4 : ffffd74e6c73fcd4 x3 : ffffd74e6c740b40 x2 : ffff800080015484 x1 : 0000000000000000 x0 : ffff2fa4c0412000 Call trace: regmap_unlock_spinlock+0x18/0x30 rockchip_pmu_set_idle_request+0xac/0x2c0 rockchip_pd_power+0x144/0x5f8 rockchip_pd_power_off+0x1c/0x30 _genpd_power_off+0x9c/0x180 genpd_power_off.part.0.isra.0+0x130/0x2a8 genpd_power_off_work_fn+0x6c/0x98 process_one_work+0x170/0x3f0 worker_thread+0x290/0x4a8 kthread+0xec/0xf8 ret_from_fork+0x10/0x20 rockchip-pm-domain ff100000.syscon:power-controller: failed to get ack on domain 'hevc', val=0x88220 Fixes: 52e02d377a72 ("arm64: dts: rockchip: add core dtsi file for RK3328 SoCs") Signed-off-by: Peter Geis Reviewed-by: Dragan Simic Link: https://lore.kernel.org/r/20241214224339.24674-1-pgwipeout@gmail.com Signed-off-by: Heiko Stuebner Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/rockchip/rk3328.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index d8af608752e3..f6f5a64fef09 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -272,6 +272,7 @@ power-domain@RK3328_PD_HEVC { reg = ; + clocks = <&cru SCLK_VENC_CORE>; #power-domain-cells = <0>; }; power-domain@RK3328_PD_VIDEO { From 5c51a223fed1157fc6c933196677ab0f88b47325 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 29 Jun 2020 20:20:07 +0530 Subject: [PATCH 059/138] phy: core: fix code style in devm_of_phy_provider_unregister [ Upstream commit b555f35f2f87f8a99ba8e65d3f51ae4294748b58 ] Documentation/process/coding-style.rst says: "functions: they have the opening brace at the beginning of the next line" devm_of_phy_provider_unregister() function has opening brace at same line, so fix it up. Link: https://lore.kernel.org/r/20200629145010.122675-1-vkoul@kernel.org Signed-off-by: Vinod Koul Stable-dep-of: c0b82ab95b4f ("phy: core: Fix that API devm_of_phy_provider_unregister() fails to unregister the phy provider") Signed-off-by: Sasha Levin --- drivers/phy/phy-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index c801fe727f09..ffe89ed15a36 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -1094,7 +1094,8 @@ EXPORT_SYMBOL_GPL(of_phy_provider_unregister); * of_phy_provider_unregister to unregister the phy provider. */ void devm_of_phy_provider_unregister(struct device *dev, - struct phy_provider *phy_provider) { + struct phy_provider *phy_provider) +{ int r; r = devres_destroy(dev, devm_phy_provider_release, devm_phy_match, From 1abde0742921a88a1e38a22f392f75e0c10c610c Mon Sep 17 00:00:00 2001 From: Zijun Hu Date: Fri, 13 Dec 2024 20:36:42 +0800 Subject: [PATCH 060/138] phy: core: Fix that API devm_of_phy_provider_unregister() fails to unregister the phy provider [ Upstream commit c0b82ab95b4f1fbc3e3aeab9d829d012669524b6 ] For devm_of_phy_provider_unregister(), its comment says it needs to invoke of_phy_provider_unregister() to unregister the phy provider, but it will not actually invoke the function since devres_destroy() does not call devm_phy_provider_release(), and the missing of_phy_provider_unregister() call will cause: - The phy provider fails to be unregistered. - Leak both memory and the OF node refcount. Fortunately, the faulty API has not been used by current kernel tree. Fix by using devres_release() instead of devres_destroy() within the API. Fixes: ff764963479a ("drivers: phy: add generic PHY framework") Reviewed-by: Johan Hovold Signed-off-by: Zijun Hu Link: https://lore.kernel.org/stable/20241213-phy_core_fix-v6-2-40ae28f5015a%40quicinc.com Link: https://lore.kernel.org/r/20241213-phy_core_fix-v6-2-40ae28f5015a@quicinc.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/phy/phy-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index ffe89ed15a36..c94a0d2c4516 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -1094,12 +1094,12 @@ EXPORT_SYMBOL_GPL(of_phy_provider_unregister); * of_phy_provider_unregister to unregister the phy provider. */ void devm_of_phy_provider_unregister(struct device *dev, - struct phy_provider *phy_provider) + struct phy_provider *phy_provider) { int r; - r = devres_destroy(dev, devm_phy_provider_release, devm_phy_match, - phy_provider); + r = devres_release(dev, devm_phy_provider_release, devm_phy_match, + phy_provider); dev_WARN_ONCE(dev, r, "couldn't find PHY provider device resource\n"); } EXPORT_SYMBOL_GPL(devm_of_phy_provider_unregister); From a57944e99e1f1e8fe98d153fd26d6873e93879f3 Mon Sep 17 00:00:00 2001 From: Joseph Qi Date: Sun, 28 May 2023 21:20:32 +0800 Subject: [PATCH 061/138] ocfs2: correct return value of ocfs2_local_free_info() [ Upstream commit d32840ad4a111c6abd651fbf6b5996e6123913da ] Now in ocfs2_local_free_info(), it returns 0 even if it actually fails. Though it doesn't cause any real problem since the only caller dquot_disable() ignores the return value, we'd better return correct as it is. Link: https://lkml.kernel.org/r/20230528132033.217664-1-joseph.qi@linux.alibaba.com Signed-off-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Cc: Joseph Qi Cc: Changwei Ge Cc: Gang He Cc: Jun Piao Signed-off-by: Andrew Morton Stable-dep-of: 5f3fd772d152 ("ocfs2: fix slab-use-after-free due to dangling pointer dqi_priv") Signed-off-by: Sasha Levin --- fs/ocfs2/quota_local.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c index 7a1c8da9e44b..fbab536741e2 100644 --- a/fs/ocfs2/quota_local.c +++ b/fs/ocfs2/quota_local.c @@ -815,7 +815,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type) struct ocfs2_quota_chunk *chunk; struct ocfs2_local_disk_chunk *dchunk; int mark_clean = 1, len; - int status; + int status = 0; iput(oinfo->dqi_gqinode); ocfs2_simple_drop_lockres(OCFS2_SB(sb), &oinfo->dqi_gqlock); @@ -857,17 +857,14 @@ static int ocfs2_local_free_info(struct super_block *sb, int type) oinfo->dqi_libh, olq_update_info, info); - if (status < 0) { + if (status < 0) mlog_errno(status); - goto out; - } - out: ocfs2_inode_unlock(sb_dqopt(sb)->files[type], 1); brelse(oinfo->dqi_libh); brelse(oinfo->dqi_lqi_bh); kfree(oinfo); - return 0; + return status; } static void olq_set_dquot(struct buffer_head *bh, void *private) From 58f9e20e2a7602e1dd649a1ec4790077c251cb6c Mon Sep 17 00:00:00 2001 From: Dennis Lam Date: Tue, 17 Dec 2024 21:39:25 -0500 Subject: [PATCH 062/138] ocfs2: fix slab-use-after-free due to dangling pointer dqi_priv [ Upstream commit 5f3fd772d152229d94602bca243fbb658068a597 ] When mounting ocfs2 and then remounting it as read-only, a slab-use-after-free occurs after the user uses a syscall to quota_getnextquota. Specifically, sb_dqinfo(sb, type)->dqi_priv is the dangling pointer. During the remounting process, the pointer dqi_priv is freed but is never set as null leaving it to be accessed. Additionally, the read-only option for remounting sets the DQUOT_SUSPENDED flag instead of setting the DQUOT_USAGE_ENABLED flags. Moreover, later in the process of getting the next quota, the function ocfs2_get_next_id is called and only checks the quota usage flags and not the quota suspended flags. To fix this, I set dqi_priv to null when it is freed after remounting with read-only and put a check for DQUOT_SUSPENDED in ocfs2_get_next_id. [akpm@linux-foundation.org: coding-style cleanups] Link: https://lkml.kernel.org/r/20241218023924.22821-2-dennis.lamerice@gmail.com Fixes: 8f9e8f5fcc05 ("ocfs2: Fix Q_GETNEXTQUOTA for filesystem without quotas") Signed-off-by: Dennis Lam Reported-by: syzbot+d173bf8a5a7faeede34c@syzkaller.appspotmail.com Tested-by: syzbot+d173bf8a5a7faeede34c@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/6731d26f.050a0220.1fb99c.014b.GAE@google.com/T/ Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Cc: Changwei Ge Cc: Jun Piao Cc: Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin --- fs/ocfs2/quota_global.c | 2 +- fs/ocfs2/quota_local.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index eda83487c9ec..1ce3780e8b49 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c @@ -881,7 +881,7 @@ static int ocfs2_get_next_id(struct super_block *sb, struct kqid *qid) int status = 0; trace_ocfs2_get_next_id(from_kqid(&init_user_ns, *qid), type); - if (!sb_has_quota_loaded(sb, type)) { + if (!sb_has_quota_active(sb, type)) { status = -ESRCH; goto out; } diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c index fbab536741e2..77d5aa90338f 100644 --- a/fs/ocfs2/quota_local.c +++ b/fs/ocfs2/quota_local.c @@ -864,6 +864,7 @@ out: brelse(oinfo->dqi_libh); brelse(oinfo->dqi_lqi_bh); kfree(oinfo); + info->dqi_priv = NULL; return status; } From c8d179f3b1c1d60bf4484f50aa67b4c70f91bff9 Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Wed, 8 Jan 2025 16:34:33 +0100 Subject: [PATCH 063/138] sctp: sysctl: rto_min/max: avoid using current->nsproxy [ Upstream commit 9fc17b76fc70763780aa78b38fcf4742384044a5 ] As mentioned in a previous commit of this series, using the 'net' structure via 'current' is not recommended for different reasons: - Inconsistency: getting info from the reader's/writer's netns vs only from the opener's netns. - current->nsproxy can be NULL in some cases, resulting in an 'Oops' (null-ptr-deref), e.g. when the current task is exiting, as spotted by syzbot [1] using acct(2). The 'net' structure can be obtained from the table->data using container_of(). Note that table->data could also be used directly, as this is the only member needed from the 'net' structure, but that would increase the size of this fix, to use '*data' everywhere 'net->sctp.rto_min/max' is used. Fixes: 4f3fdf3bc59c ("sctp: add check rto_min and rto_max in sysctl") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/67769ecb.050a0220.3a8527.003f.GAE@google.com [1] Suggested-by: Al Viro Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20250108-net-sysctl-current-nsproxy-v1-5-5df34b2083e8@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sctp/sysctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 4513d8d45e55..7777c0096a38 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c @@ -372,7 +372,7 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - struct net *net = current->nsproxy->net_ns; + struct net *net = container_of(ctl->data, struct net, sctp.rto_min); unsigned int min = *(unsigned int *) ctl->extra1; unsigned int max = *(unsigned int *) ctl->extra2; struct ctl_table tbl; @@ -401,7 +401,7 @@ static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - struct net *net = current->nsproxy->net_ns; + struct net *net = container_of(ctl->data, struct net, sctp.rto_max); unsigned int min = *(unsigned int *) ctl->extra1; unsigned int max = *(unsigned int *) ctl->extra2; struct ctl_table tbl; From b42e21d09788e88029461626db8f3069d386221d Mon Sep 17 00:00:00 2001 From: Sudheer Kumar Doredla Date: Wed, 8 Jan 2025 22:54:33 +0530 Subject: [PATCH 064/138] net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field() [ Upstream commit 03d120f27d050336f7e7d21879891542c4741f81 ] CPSW ALE has 75-bit ALE entries stored across three 32-bit words. The cpsw_ale_get_field() and cpsw_ale_set_field() functions support ALE field entries spanning up to two words at the most. The cpsw_ale_get_field() and cpsw_ale_set_field() functions work as expected when ALE field spanned across word1 and word2, but fails when ALE field spanned across word2 and word3. For example, while reading the ALE field spanned across word2 and word3 (i.e. bits 62 to 64), the word3 data shifted to an incorrect position due to the index becoming zero while flipping. The same issue occurred when setting an ALE entry. This issue has not been seen in practice but will be an issue in the future if the driver supports accessing ALE fields spanning word2 and word3 Fix the methods to handle getting/setting fields spanning up to two words. Fixes: b685f1a58956 ("net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field()/cpsw_ale_set_field()") Signed-off-by: Sudheer Kumar Doredla Reviewed-by: Simon Horman Reviewed-by: Roger Quadros Reviewed-by: Siddharth Vadapalli Link: https://patch.msgid.link/20250108172433.311694-1-s-doredla@ti.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/ti/cpsw_ale.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index f17619c545ae..9280601961c7 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c @@ -60,15 +60,15 @@ static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) { - int idx, idx2; + int idx, idx2, index; u32 hi_val = 0; idx = start / 32; idx2 = (start + bits - 1) / 32; /* Check if bits to be fetched exceed a word */ if (idx != idx2) { - idx2 = 2 - idx2; /* flip */ - hi_val = ale_entry[idx2] << ((idx2 * 32) - start); + index = 2 - idx2; /* flip */ + hi_val = ale_entry[index] << ((idx2 * 32) - start); } start -= idx * 32; idx = 2 - idx; /* flip */ @@ -78,16 +78,16 @@ static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits, u32 value) { - int idx, idx2; + int idx, idx2, index; value &= BITMASK(bits); idx = start / 32; idx2 = (start + bits - 1) / 32; /* Check if bits to be set exceed a word */ if (idx != idx2) { - idx2 = 2 - idx2; /* flip */ - ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32))); - ale_entry[idx2] |= (value >> ((idx2 * 32) - start)); + index = 2 - idx2; /* flip */ + ale_entry[index] &= ~(BITMASK(bits + start - (idx2 * 32))); + ale_entry[index] |= (value >> ((idx2 * 32) - start)); } start -= idx * 32; idx = 2 - idx; /* flip */ From 378b81b092351ffa99284a807615d9d8f4b83df7 Mon Sep 17 00:00:00 2001 From: Yajun Deng Date: Tue, 17 Aug 2021 23:23:00 +0800 Subject: [PATCH 065/138] net: net_namespace: Optimize the code [ Upstream commit 41467d2ff4dfe1837cbb0f45e2088e6e787580c6 ] There is only one caller for ops_free(), so inline it. Separate net_drop_ns() and net_free(), so the net_free() can be called directly. Add free_exit_list() helper function for free net_exit_list. ==================== v2: - v1 does not apply, rebase it. ==================== Signed-off-by: Yajun Deng Signed-off-by: David S. Miller Stable-dep-of: 46841c7053e6 ("gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp().") Signed-off-by: Sasha Levin --- net/core/net_namespace.c | 52 +++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index c94179d30d42..c4bcedc06822 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -98,7 +98,7 @@ static int net_assign_generic(struct net *net, unsigned int id, void *data) } ng = net_alloc_generic(); - if (ng == NULL) + if (!ng) return -ENOMEM; /* @@ -155,13 +155,6 @@ out: return err; } -static void ops_free(const struct pernet_operations *ops, struct net *net) -{ - if (ops->id && ops->size) { - kfree(net_generic(net, *ops->id)); - } -} - static void ops_pre_exit_list(const struct pernet_operations *ops, struct list_head *net_exit_list) { @@ -193,7 +186,7 @@ static void ops_free_list(const struct pernet_operations *ops, struct net *net; if (ops->size && ops->id) { list_for_each_entry(net, net_exit_list, exit_list) - ops_free(ops, net); + kfree(net_generic(net, *ops->id)); } } @@ -448,15 +441,18 @@ out_free: static void net_free(struct net *net) { - kfree(rcu_access_pointer(net->gen)); - kmem_cache_free(net_cachep, net); + if (refcount_dec_and_test(&net->passive)) { + kfree(rcu_access_pointer(net->gen)); + kmem_cache_free(net_cachep, net); + } } void net_drop_ns(void *p) { - struct net *ns = p; - if (ns && refcount_dec_and_test(&ns->passive)) - net_free(ns); + struct net *net = (struct net *)p; + + if (net) + net_free(net); } struct net *copy_net_ns(unsigned long flags, @@ -496,7 +492,7 @@ put_userns: key_remove_domain(net->key_domain); #endif put_user_ns(user_ns); - net_drop_ns(net); + net_free(net); dec_ucounts: dec_net_namespaces(ucounts); return ERR_PTR(rv); @@ -630,7 +626,7 @@ static void cleanup_net(struct work_struct *work) key_remove_domain(net->key_domain); #endif put_user_ns(net->user_ns); - net_drop_ns(net); + net_free(net); } } @@ -1150,6 +1146,14 @@ static int __init net_ns_init(void) pure_initcall(net_ns_init); +static void free_exit_list(struct pernet_operations *ops, struct list_head *net_exit_list) +{ + ops_pre_exit_list(ops, net_exit_list); + synchronize_rcu(); + ops_exit_list(ops, net_exit_list); + ops_free_list(ops, net_exit_list); +} + #ifdef CONFIG_NET_NS static int __register_pernet_operations(struct list_head *list, struct pernet_operations *ops) @@ -1175,10 +1179,7 @@ static int __register_pernet_operations(struct list_head *list, out_undo: /* If I have an error cleanup all namespaces I initialized */ list_del(&ops->list); - ops_pre_exit_list(ops, &net_exit_list); - synchronize_rcu(); - ops_exit_list(ops, &net_exit_list); - ops_free_list(ops, &net_exit_list); + free_exit_list(ops, &net_exit_list); return error; } @@ -1191,10 +1192,8 @@ static void __unregister_pernet_operations(struct pernet_operations *ops) /* See comment in __register_pernet_operations() */ for_each_net(net) list_add_tail(&net->exit_list, &net_exit_list); - ops_pre_exit_list(ops, &net_exit_list); - synchronize_rcu(); - ops_exit_list(ops, &net_exit_list); - ops_free_list(ops, &net_exit_list); + + free_exit_list(ops, &net_exit_list); } #else @@ -1217,10 +1216,7 @@ static void __unregister_pernet_operations(struct pernet_operations *ops) } else { LIST_HEAD(net_exit_list); list_add(&init_net.exit_list, &net_exit_list); - ops_pre_exit_list(ops, &net_exit_list); - synchronize_rcu(); - ops_exit_list(ops, &net_exit_list); - ops_free_list(ops, &net_exit_list); + free_exit_list(ops, &net_exit_list); } } From 2131315571026a91ecda9a690f68bf1de0f51ccd Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 6 Feb 2024 14:42:57 +0000 Subject: [PATCH 066/138] net: add exit_batch_rtnl() method [ Upstream commit fd4f101edbd9f99567ab2adb1f2169579ede7c13 ] Many (struct pernet_operations)->exit_batch() methods have to acquire rtnl. In presence of rtnl mutex pressure, this makes cleanup_net() very slow. This patch adds a new exit_batch_rtnl() method to reduce number of rtnl acquisitions from cleanup_net(). exit_batch_rtnl() handlers are called while rtnl is locked, and devices to be killed can be queued in a list provided as their second argument. A single unregister_netdevice_many() is called right before rtnl is released. exit_batch_rtnl() handlers are called before ->exit() and ->exit_batch() handlers. Signed-off-by: Eric Dumazet Reviewed-by: Antoine Tenart Link: https://lore.kernel.org/r/20240206144313.2050392-2-edumazet@google.com Signed-off-by: Jakub Kicinski Stable-dep-of: 46841c7053e6 ("gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp().") Signed-off-by: Sasha Levin --- include/net/net_namespace.h | 3 +++ net/core/net_namespace.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 167e390ac9d4..0d61b452b908 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -382,6 +382,9 @@ struct pernet_operations { void (*pre_exit)(struct net *net); void (*exit)(struct net *net); void (*exit_batch)(struct list_head *net_exit_list); + /* Following method is called with RTNL held. */ + void (*exit_batch_rtnl)(struct list_head *net_exit_list, + struct list_head *dev_kill_list); unsigned int *id; size_t size; }; diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index c4bcedc06822..e6585a758edd 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -325,8 +325,9 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns) { /* Must be called with pernet_ops_rwsem held */ const struct pernet_operations *ops, *saved_ops; - int error = 0; LIST_HEAD(net_exit_list); + LIST_HEAD(dev_kill_list); + int error = 0; refcount_set(&net->count, 1); refcount_set(&net->passive, 1); @@ -359,6 +360,15 @@ out_undo: synchronize_rcu(); + ops = saved_ops; + rtnl_lock(); + list_for_each_entry_continue_reverse(ops, &pernet_list, list) { + if (ops->exit_batch_rtnl) + ops->exit_batch_rtnl(&net_exit_list, &dev_kill_list); + } + unregister_netdevice_many(&dev_kill_list); + rtnl_unlock(); + ops = saved_ops; list_for_each_entry_continue_reverse(ops, &pernet_list, list) ops_exit_list(ops, &net_exit_list); @@ -563,6 +573,7 @@ static void cleanup_net(struct work_struct *work) struct net *net, *tmp, *last; struct llist_node *net_kill_list; LIST_HEAD(net_exit_list); + LIST_HEAD(dev_kill_list); /* Atomically snapshot the list of namespaces to cleanup */ net_kill_list = llist_del_all(&cleanup_list); @@ -603,6 +614,14 @@ static void cleanup_net(struct work_struct *work) */ synchronize_rcu(); + rtnl_lock(); + list_for_each_entry_reverse(ops, &pernet_list, list) { + if (ops->exit_batch_rtnl) + ops->exit_batch_rtnl(&net_exit_list, &dev_kill_list); + } + unregister_netdevice_many(&dev_kill_list); + rtnl_unlock(); + /* Run all of the network namespace exit methods */ list_for_each_entry_reverse(ops, &pernet_list, list) ops_exit_list(ops, &net_exit_list); @@ -1150,7 +1169,17 @@ static void free_exit_list(struct pernet_operations *ops, struct list_head *net_ { ops_pre_exit_list(ops, net_exit_list); synchronize_rcu(); + + if (ops->exit_batch_rtnl) { + LIST_HEAD(dev_kill_list); + + rtnl_lock(); + ops->exit_batch_rtnl(net_exit_list, &dev_kill_list); + unregister_netdevice_many(&dev_kill_list); + rtnl_unlock(); + } ops_exit_list(ops, net_exit_list); + ops_free_list(ops, net_exit_list); } From 85d9663360988a434a46af25516c718308c471ba Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 6 Feb 2024 14:43:03 +0000 Subject: [PATCH 067/138] gtp: use exit_batch_rtnl() method [ Upstream commit 6eedda01b2bfdcf427b37759e053dc27232f3af1 ] exit_batch_rtnl() is called while RTNL is held, and devices to be unregistered can be queued in the dev_kill_list. This saves one rtnl_lock()/rtnl_unlock() pair per netns and one unregister_netdevice_many() call per netns. Signed-off-by: Eric Dumazet Reviewed-by: Antoine Tenart Link: https://lore.kernel.org/r/20240206144313.2050392-8-edumazet@google.com Signed-off-by: Jakub Kicinski Stable-dep-of: 46841c7053e6 ("gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp().") Signed-off-by: Sasha Levin --- drivers/net/gtp.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index f85f4e3d2821..fd5d3f58b5c1 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -1355,23 +1355,23 @@ static int __net_init gtp_net_init(struct net *net) return 0; } -static void __net_exit gtp_net_exit(struct net *net) +static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list, + struct list_head *dev_to_kill) { - struct gtp_net *gn = net_generic(net, gtp_net_id); - struct gtp_dev *gtp; - LIST_HEAD(list); + struct net *net; - rtnl_lock(); - list_for_each_entry(gtp, &gn->gtp_dev_list, list) - gtp_dellink(gtp->dev, &list); + list_for_each_entry(net, net_list, exit_list) { + struct gtp_net *gn = net_generic(net, gtp_net_id); + struct gtp_dev *gtp; - unregister_netdevice_many(&list); - rtnl_unlock(); + list_for_each_entry(gtp, &gn->gtp_dev_list, list) + gtp_dellink(gtp->dev, dev_to_kill); + } } static struct pernet_operations gtp_net_ops = { .init = gtp_net_init, - .exit = gtp_net_exit, + .exit_batch_rtnl = gtp_net_exit_batch_rtnl, .id = >p_net_id, .size = sizeof(struct gtp_net), }; From 574c3f3f8e5e4cad8ae92f46df4214c153866dd2 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Fri, 10 Jan 2025 10:47:52 +0900 Subject: [PATCH 068/138] gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp(). [ Upstream commit 46841c7053e6d25fb33e0534ef023833bf03e382 ] gtp_newlink() links the gtp device to a list in dev_net(dev). However, even after the gtp device is moved to another netns, it stays on the list but should be invisible. Let's use for_each_netdev_rcu() for netdev traversal in gtp_genl_dump_pdp(). Note that gtp_dev_list is no longer used under RCU, so list helpers are converted to the non-RCU variant. Fixes: 459aa660eb1d ("gtp: add initial driver for datapath of GPRS Tunneling Protocol (GTP-U)") Reported-by: Xiao Liang Closes: https://lore.kernel.org/netdev/CABAhCOQdBL6h9M2C+kd+bGivRJ9Q72JUxW+-gur0nub_=PmFPA@mail.gmail.com/ Signed-off-by: Kuniyuki Iwashima Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/gtp.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index fd5d3f58b5c1..e08cd4b1be6c 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -691,7 +691,7 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev, } gn = net_generic(dev_net(dev), gtp_net_id); - list_add_rcu(>p->list, &gn->gtp_dev_list); + list_add(>p->list, &gn->gtp_dev_list); dev->priv_destructor = gtp_destructor; netdev_dbg(dev, "registered new GTP interface\n"); @@ -717,7 +717,7 @@ static void gtp_dellink(struct net_device *dev, struct list_head *head) hlist_for_each_entry_safe(pctx, next, >p->tid_hash[i], hlist_tid) pdp_context_delete(pctx); - list_del_rcu(>p->list); + list_del(>p->list); unregister_netdevice_queue(dev, head); } @@ -1259,16 +1259,19 @@ static int gtp_genl_dump_pdp(struct sk_buff *skb, struct gtp_dev *last_gtp = (struct gtp_dev *)cb->args[2], *gtp; int i, j, bucket = cb->args[0], skip = cb->args[1]; struct net *net = sock_net(skb->sk); + struct net_device *dev; struct pdp_ctx *pctx; - struct gtp_net *gn; - - gn = net_generic(net, gtp_net_id); if (cb->args[4]) return 0; rcu_read_lock(); - list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) { + for_each_netdev_rcu(net, dev) { + if (dev->rtnl_link_ops != >p_link_ops) + continue; + + gtp = netdev_priv(dev); + if (last_gtp && last_gtp != gtp) continue; else @@ -1362,9 +1365,9 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list, list_for_each_entry(net, net_list, exit_list) { struct gtp_net *gn = net_generic(net, gtp_net_id); - struct gtp_dev *gtp; + struct gtp_dev *gtp, *gtp_next; - list_for_each_entry(gtp, &gn->gtp_dev_list, list) + list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list) gtp_dellink(gtp->dev, dev_to_kill); } } From c986380c1d5274c4d5e935addc807d6791cc23eb Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Fri, 10 Jan 2025 10:47:53 +0900 Subject: [PATCH 069/138] gtp: Destroy device along with udp socket's netns dismantle. [ Upstream commit eb28fd76c0a08a47b470677c6cef9dd1c60e92d1 ] gtp_newlink() links the device to a list in dev_net(dev) instead of src_net, where a udp tunnel socket is created. Even when src_net is removed, the device stays alive on dev_net(dev). Then, removing src_net triggers the splat below. [0] In this example, gtp0 is created in ns2, and the udp socket is created in ns1. ip netns add ns1 ip netns add ns2 ip -n ns1 link add netns ns2 name gtp0 type gtp role sgsn ip netns del ns1 Let's link the device to the socket's netns instead. Now, gtp_net_exit_batch_rtnl() needs another netdev iteration to remove all gtp devices in the netns. [0]: ref_tracker: net notrefcnt@000000003d6e7d05 has 1/2 users at sk_alloc (./include/net/net_namespace.h:345 net/core/sock.c:2236) inet_create (net/ipv4/af_inet.c:326 net/ipv4/af_inet.c:252) __sock_create (net/socket.c:1558) udp_sock_create4 (net/ipv4/udp_tunnel_core.c:18) gtp_create_sock (./include/net/udp_tunnel.h:59 drivers/net/gtp.c:1423) gtp_create_sockets (drivers/net/gtp.c:1447) gtp_newlink (drivers/net/gtp.c:1507) rtnl_newlink (net/core/rtnetlink.c:3786 net/core/rtnetlink.c:3897 net/core/rtnetlink.c:4012) rtnetlink_rcv_msg (net/core/rtnetlink.c:6922) netlink_rcv_skb (net/netlink/af_netlink.c:2542) netlink_unicast (net/netlink/af_netlink.c:1321 net/netlink/af_netlink.c:1347) netlink_sendmsg (net/netlink/af_netlink.c:1891) ____sys_sendmsg (net/socket.c:711 net/socket.c:726 net/socket.c:2583) ___sys_sendmsg (net/socket.c:2639) __sys_sendmsg (net/socket.c:2669) do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83) WARNING: CPU: 1 PID: 60 at lib/ref_tracker.c:179 ref_tracker_dir_exit (lib/ref_tracker.c:179) Modules linked in: CPU: 1 UID: 0 PID: 60 Comm: kworker/u16:2 Not tainted 6.13.0-rc5-00147-g4c1224501e9d #5 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 Workqueue: netns cleanup_net RIP: 0010:ref_tracker_dir_exit (lib/ref_tracker.c:179) Code: 00 00 00 fc ff df 4d 8b 26 49 bd 00 01 00 00 00 00 ad de 4c 39 f5 0f 85 df 00 00 00 48 8b 74 24 08 48 89 df e8 a5 cc 12 02 90 <0f> 0b 90 48 8d 6b 44 be 04 00 00 00 48 89 ef e8 80 de 67 ff 48 89 RSP: 0018:ff11000009a07b60 EFLAGS: 00010286 RAX: 0000000000002bd3 RBX: ff1100000f4e1aa0 RCX: 1ffffffff0e40ac6 RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff8423ee3c RBP: ff1100000f4e1af0 R08: 0000000000000001 R09: fffffbfff0e395ae R10: 0000000000000001 R11: 0000000000036001 R12: ff1100000f4e1af0 R13: dead000000000100 R14: ff1100000f4e1af0 R15: dffffc0000000000 FS: 0000000000000000(0000) GS:ff1100006ce80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f9b2464bd98 CR3: 0000000005286005 CR4: 0000000000771ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: ? __warn (kernel/panic.c:748) ? ref_tracker_dir_exit (lib/ref_tracker.c:179) ? report_bug (lib/bug.c:201 lib/bug.c:219) ? handle_bug (arch/x86/kernel/traps.c:285) ? exc_invalid_op (arch/x86/kernel/traps.c:309 (discriminator 1)) ? asm_exc_invalid_op (./arch/x86/include/asm/idtentry.h:621) ? _raw_spin_unlock_irqrestore (./arch/x86/include/asm/irqflags.h:42 ./arch/x86/include/asm/irqflags.h:97 ./arch/x86/include/asm/irqflags.h:155 ./include/linux/spinlock_api_smp.h:151 kernel/locking/spinlock.c:194) ? ref_tracker_dir_exit (lib/ref_tracker.c:179) ? __pfx_ref_tracker_dir_exit (lib/ref_tracker.c:158) ? kfree (mm/slub.c:4613 mm/slub.c:4761) net_free (net/core/net_namespace.c:476 net/core/net_namespace.c:467) cleanup_net (net/core/net_namespace.c:664 (discriminator 3)) process_one_work (kernel/workqueue.c:3229) worker_thread (kernel/workqueue.c:3304 kernel/workqueue.c:3391) kthread (kernel/kthread.c:389) ret_from_fork (arch/x86/kernel/process.c:147) ret_from_fork_asm (arch/x86/entry/entry_64.S:257) Fixes: 459aa660eb1d ("gtp: add initial driver for datapath of GPRS Tunneling Protocol (GTP-U)") Reported-by: Xiao Liang Closes: https://lore.kernel.org/netdev/20250104125732.17335-1-shaw.leon@gmail.com/ Signed-off-by: Kuniyuki Iwashima Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/gtp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index e08cd4b1be6c..68698457add0 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -690,7 +690,7 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev, goto out_encap; } - gn = net_generic(dev_net(dev), gtp_net_id); + gn = net_generic(src_net, gtp_net_id); list_add(>p->list, &gn->gtp_dev_list); dev->priv_destructor = gtp_destructor; @@ -1366,6 +1366,11 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list, list_for_each_entry(net, net_list, exit_list) { struct gtp_net *gn = net_generic(net, gtp_net_id); struct gtp_dev *gtp, *gtp_next; + struct net_device *dev; + + for_each_netdev(net, dev) + if (dev->rtnl_link_ops == >p_link_ops) + gtp_dellink(dev, dev_to_kill); list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list) gtp_dellink(gtp->dev, dev_to_kill); From 8e87be55db4e8ede3138577a4751fd0f337aada9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 13 Jan 2025 09:18:39 +0300 Subject: [PATCH 070/138] nfp: bpf: prevent integer overflow in nfp_bpf_event_output() [ Upstream commit 16ebb6f5b6295c9688749862a39a4889c56227f8 ] The "sizeof(struct cmsg_bpf_event) + pkt_size + data_size" math could potentially have an integer wrapping bug on 32bit systems. Check for this and return an error. Fixes: 9816dd35ecec ("nfp: bpf: perf event output helpers support") Signed-off-by: Dan Carpenter Link: https://patch.msgid.link/6074805b-e78d-4b8a-bf05-e929b5377c28@stanley.mountain Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/netronome/nfp/bpf/offload.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c b/drivers/net/ethernet/netronome/nfp/bpf/offload.c index 7ff388ecc7e3..409b636c7647 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c @@ -454,7 +454,8 @@ int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data, map_id_full = be64_to_cpu(cbe->map_ptr); map_id = map_id_full; - if (len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size) + if (size_add(pkt_size, data_size) > INT_MAX || + len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size) return -EINVAL; if (cbe->hdr.ver != NFP_CCM_ABI_VERSION) return -EINVAL; From 1bd6303d08c85072ce40ac01a767ab67195105bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= Date: Mon, 13 Jan 2025 12:47:40 -0300 Subject: [PATCH 071/138] drm/v3d: Ensure job pointer is set to NULL after job completion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit e4b5ccd392b92300a2b341705cc4805681094e49 ] After a job completes, the corresponding pointer in the device must be set to NULL. Failing to do so triggers a warning when unloading the driver, as it appears the job is still active. To prevent this, assign the job pointer to NULL after completing the job, indicating the job has finished. Fixes: 14d1d1908696 ("drm/v3d: Remove the bad signaled() implementation.") Signed-off-by: Maíra Canal Reviewed-by: Jose Maria Casanova Crespo Link: https://patchwork.freedesktop.org/patch/msgid/20250113154741.67520-1-mcanal@igalia.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/v3d/v3d_irq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c index 662e67279a7b..aa27b7654dee 100644 --- a/drivers/gpu/drm/v3d/v3d_irq.c +++ b/drivers/gpu/drm/v3d/v3d_irq.c @@ -103,6 +103,7 @@ v3d_irq(int irq, void *arg) trace_v3d_bcl_irq(&v3d->drm, fence->seqno); dma_fence_signal(&fence->base); + v3d->bin_job = NULL; status = IRQ_HANDLED; } @@ -112,6 +113,7 @@ v3d_irq(int irq, void *arg) trace_v3d_rcl_irq(&v3d->drm, fence->seqno); dma_fence_signal(&fence->base); + v3d->render_job = NULL; status = IRQ_HANDLED; } @@ -121,6 +123,7 @@ v3d_irq(int irq, void *arg) trace_v3d_csd_irq(&v3d->drm, fence->seqno); dma_fence_signal(&fence->base); + v3d->csd_job = NULL; status = IRQ_HANDLED; } @@ -157,6 +160,7 @@ v3d_hub_irq(int irq, void *arg) trace_v3d_tfu_irq(&v3d->drm, fence->seqno); dma_fence_signal(&fence->base); + v3d->tfu_job = NULL; status = IRQ_HANDLED; } From 5d2b25cbeee2cbff5fbe71bb8a02983ed30078fc Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 15 Jan 2025 08:29:45 +0100 Subject: [PATCH 072/138] i2c: mux: demux-pinctrl: check initial mux selection, too [ Upstream commit ca89f73394daf92779ddaa37b42956f4953f3941 ] When misconfigured, the initial setup of the current mux channel can fail, too. It must be checked as well. Fixes: 50a5ba876908 ("i2c: mux: demux-pinctrl: add driver") Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin --- drivers/i2c/muxes/i2c-demux-pinctrl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/muxes/i2c-demux-pinctrl.c b/drivers/i2c/muxes/i2c-demux-pinctrl.c index 45a3f7e7b3f6..cea057704c00 100644 --- a/drivers/i2c/muxes/i2c-demux-pinctrl.c +++ b/drivers/i2c/muxes/i2c-demux-pinctrl.c @@ -261,7 +261,9 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) pm_runtime_no_callbacks(&pdev->dev); /* switch to first parent as active master */ - i2c_demux_activate_master(priv, 0); + err = i2c_demux_activate_master(priv, 0); + if (err) + goto err_rollback; err = device_create_file(&pdev->dev, &dev_attr_available_masters); if (err) From 0d11dc30edfc4acef0acef130bb5ca596317190a Mon Sep 17 00:00:00 2001 From: Lizhi Xu Date: Wed, 13 Nov 2024 17:51:29 +0800 Subject: [PATCH 073/138] mac802154: check local interfaces before deleting sdata list [ Upstream commit eb09fbeb48709fe66c0d708aed81e910a577a30a ] syzkaller reported a corrupted list in ieee802154_if_remove. [1] Remove an IEEE 802.15.4 network interface after unregister an IEEE 802.15.4 hardware device from the system. CPU0 CPU1 ==== ==== genl_family_rcv_msg_doit ieee802154_unregister_hw ieee802154_del_iface ieee802154_remove_interfaces rdev_del_virtual_intf_deprecated list_del(&sdata->list) ieee802154_if_remove list_del_rcu The net device has been unregistered, since the rcu grace period, unregistration must be run before ieee802154_if_remove. To avoid this issue, add a check for local->interfaces before deleting sdata list. [1] kernel BUG at lib/list_debug.c:58! Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI CPU: 0 UID: 0 PID: 6277 Comm: syz-executor157 Not tainted 6.12.0-rc6-syzkaller-00005-g557329bcecc2 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 RIP: 0010:__list_del_entry_valid_or_report+0xf4/0x140 lib/list_debug.c:56 Code: e8 a1 7e 00 07 90 0f 0b 48 c7 c7 e0 37 60 8c 4c 89 fe e8 8f 7e 00 07 90 0f 0b 48 c7 c7 40 38 60 8c 4c 89 fe e8 7d 7e 00 07 90 <0f> 0b 48 c7 c7 a0 38 60 8c 4c 89 fe e8 6b 7e 00 07 90 0f 0b 48 c7 RSP: 0018:ffffc9000490f3d0 EFLAGS: 00010246 RAX: 000000000000004e RBX: dead000000000122 RCX: d211eee56bb28d00 RDX: 0000000000000000 RSI: 0000000080000000 RDI: 0000000000000000 RBP: ffff88805b278dd8 R08: ffffffff8174a12c R09: 1ffffffff2852f0d R10: dffffc0000000000 R11: fffffbfff2852f0e R12: dffffc0000000000 R13: dffffc0000000000 R14: dead000000000100 R15: ffff88805b278cc0 FS: 0000555572f94380(0000) GS:ffff8880b8600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000056262e4a3000 CR3: 0000000078496000 CR4: 00000000003526f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: __list_del_entry_valid include/linux/list.h:124 [inline] __list_del_entry include/linux/list.h:215 [inline] list_del_rcu include/linux/rculist.h:157 [inline] ieee802154_if_remove+0x86/0x1e0 net/mac802154/iface.c:687 rdev_del_virtual_intf_deprecated net/ieee802154/rdev-ops.h:24 [inline] ieee802154_del_iface+0x2c0/0x5c0 net/ieee802154/nl-phy.c:323 genl_family_rcv_msg_doit net/netlink/genetlink.c:1115 [inline] genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline] genl_rcv_msg+0xb14/0xec0 net/netlink/genetlink.c:1210 netlink_rcv_skb+0x1e3/0x430 net/netlink/af_netlink.c:2551 genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219 netlink_unicast_kernel net/netlink/af_netlink.c:1331 [inline] netlink_unicast+0x7f6/0x990 net/netlink/af_netlink.c:1357 netlink_sendmsg+0x8e4/0xcb0 net/netlink/af_netlink.c:1901 sock_sendmsg_nosec net/socket.c:729 [inline] __sock_sendmsg+0x221/0x270 net/socket.c:744 ____sys_sendmsg+0x52a/0x7e0 net/socket.c:2607 ___sys_sendmsg net/socket.c:2661 [inline] __sys_sendmsg+0x292/0x380 net/socket.c:2690 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f Reported-and-tested-by: syzbot+985f827280dc3a6e7e92@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=985f827280dc3a6e7e92 Signed-off-by: Lizhi Xu Reviewed-by: Miquel Raynal Link: https://lore.kernel.org/20241113095129.1457225-1-lizhi.xu@windriver.com Signed-off-by: Stefan Schmidt Signed-off-by: Sasha Levin --- net/mac802154/iface.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index a08240fe68a7..22514ab060f8 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -688,6 +688,10 @@ void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata) ASSERT_RTNL(); mutex_lock(&sdata->local->iflist_mtx); + if (list_empty(&sdata->local->interfaces)) { + mutex_unlock(&sdata->local->iflist_mtx); + return; + } list_del_rcu(&sdata->list); mutex_unlock(&sdata->local->iflist_mtx); From 296b89c569f5af48f96b1cfca36cb646c6d7b7df Mon Sep 17 00:00:00 2001 From: Leo Stone Date: Sat, 30 Nov 2024 21:14:19 -0800 Subject: [PATCH 074/138] hfs: Sanity check the root record [ Upstream commit b905bafdea21a75d75a96855edd9e0b6051eee30 ] In the syzbot reproducer, the hfs_cat_rec for the root dir has type HFS_CDR_FIL after being read with hfs_bnode_read() in hfs_super_fill(). This indicates it should be used as an hfs_cat_file, which is 102 bytes. Only the first 70 bytes of that struct are initialized, however, because the entrylength passed into hfs_bnode_read() is still the length of a directory record. This causes uninitialized values to be used later on, when the hfs_cat_rec union is treated as the larger hfs_cat_file struct. Add a check to make sure the retrieved record has the correct type for the root directory (HFS_CDR_DIR), and make sure we load the correct number of bytes for a directory record. Reported-by: syzbot+2db3c7526ba68f4ea776@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=2db3c7526ba68f4ea776 Tested-by: syzbot+2db3c7526ba68f4ea776@syzkaller.appspotmail.com Tested-by: Leo Stone Signed-off-by: Leo Stone Link: https://lore.kernel.org/r/20241201051420.77858-1-leocstone@gmail.com Reviewed-by: Jan Kara Signed-off-by: Christian Brauner Signed-off-by: Sasha Levin --- fs/hfs/super.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/hfs/super.c b/fs/hfs/super.c index bcf820ce0e02..f82444fbbedc 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -419,11 +419,13 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) goto bail_no_root; res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd); if (!res) { - if (fd.entrylength > sizeof(rec) || fd.entrylength < 0) { + if (fd.entrylength != sizeof(rec.dir)) { res = -EIO; goto bail_hfs_find; } hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength); + if (rec.type != HFS_CDR_DIR) + res = -EIO; } if (res) goto bail_hfs_find; From be1d9d4cb1dc54ed3e46593feb2c76c0bf4456f5 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 13 Dec 2024 13:50:01 +0000 Subject: [PATCH 075/138] kheaders: Ignore silly-rename files [ Upstream commit 973b710b8821c3401ad7a25360c89e94b26884ac ] Tell tar to ignore silly-rename files (".__afs*" and ".nfs*") when building the header archive. These occur when a file that is open is unlinked locally, but hasn't yet been closed. Such files are visible to the user via the getdents() syscall and so programs may want to do things with them. During the kernel build, such files may be made during the processing of header files and the cleanup may get deferred by fput() which may result in tar seeing these files when it reads the directory, but they may have disappeared by the time it tries to open them, causing tar to fail with an error. Further, we don't want to include them in the tarball if they still exist. With CONFIG_HEADERS_INSTALL=y, something like the following may be seen: find: './kernel/.tmp_cpio_dir/include/dt-bindings/reset/.__afs2080': No such file or directory tar: ./include/linux/greybus/.__afs3C95: File removed before we read it The find warning doesn't seem to cause a problem. Fix this by telling tar when called from in gen_kheaders.sh to exclude such files. This only affects afs and nfs; cifs uses the Windows Hidden attribute to prevent the file from being seen. Signed-off-by: David Howells Link: https://lore.kernel.org/r/20241213135013.2964079-2-dhowells@redhat.com cc: Masahiro Yamada cc: Marc Dionne cc: linux-afs@lists.infradead.org cc: linux-nfs@vger.kernel.org cc: linux-kernel@vger.kernel.org Signed-off-by: Christian Brauner Signed-off-by: Sasha Levin --- kernel/gen_kheaders.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh index 206ab3d41ee7..7fc44d8da205 100755 --- a/kernel/gen_kheaders.sh +++ b/kernel/gen_kheaders.sh @@ -84,6 +84,7 @@ find $cpio_dir -type f -print0 | # Create archive and try to normalize metadata for reproducibility. tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \ + --exclude=".__afs*" --exclude=".nfs*" \ --owner=0 --group=0 --sort=name --numeric-owner --mode=u=rw,go=r,a+X \ -I $XZ -cf $tarfile -C $cpio_dir/ . > /dev/null From df19e2d7bdf7e9e30f36a9906e4269a49148d603 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 7 Jan 2025 17:27:17 +0100 Subject: [PATCH 076/138] poll_wait: add mb() to fix theoretical race between waitqueue_active() and .poll() [ Upstream commit cacd9ae4bf801ff4125d8961bb9a3ba955e51680 ] As the comment above waitqueue_active() explains, it can only be used if both waker and waiter have mb()'s that pair with each other. However __pollwait() is broken in this respect. This is not pipe-specific, but let's look at pipe_poll() for example: poll_wait(...); // -> __pollwait() -> add_wait_queue() LOAD(pipe->head); LOAD(pipe->head); In theory these LOAD()'s can leak into the critical section inside add_wait_queue() and can happen before list_add(entry, wq_head), in this case pipe_poll() can race with wakeup_pipe_readers/writers which do smp_mb(); if (waitqueue_active(wq_head)) wake_up_interruptible(wq_head); There are more __pollwait()-like functions (grep init_poll_funcptr), and it seems that at least ep_ptable_queue_proc() has the same problem, so the patch adds smp_mb() into poll_wait(). Link: https://lore.kernel.org/all/20250102163320.GA17691@redhat.com/ Signed-off-by: Oleg Nesterov Link: https://lore.kernel.org/r/20250107162717.GA18922@redhat.com Signed-off-by: Christian Brauner Signed-off-by: Sasha Levin --- include/linux/poll.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/linux/poll.h b/include/linux/poll.h index 7e0fdcf905d2..a4af5e14dffe 100644 --- a/include/linux/poll.h +++ b/include/linux/poll.h @@ -43,8 +43,16 @@ typedef struct poll_table_struct { static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p) { - if (p && p->_qproc && wait_address) + if (p && p->_qproc && wait_address) { p->_qproc(filp, wait_address, p); + /* + * This memory barrier is paired in the wq_has_sleeper(). + * See the comment above prepare_to_wait(), we need to + * ensure that subsequent tests in this thread can't be + * reordered with __add_wait_queue() in _qproc() paths. + */ + smp_mb(); + } } /* From fb6114c857aa68bd8334273eb13db29ff1afe58d Mon Sep 17 00:00:00 2001 From: Luis Chamberlain Date: Tue, 17 Dec 2024 18:33:25 -0800 Subject: [PATCH 077/138] nvmet: propagate npwg topology [ Upstream commit b579d6fdc3a9149bb4d2b3133cc0767130ed13e6 ] Ensure we propagate npwg to the target as well instead of assuming its the same logical blocks per physical block. This ensures devices with large IUs information properly propagated on the target. Signed-off-by: Luis Chamberlain Reviewed-by: Sagi Grimberg Signed-off-by: Keith Busch Signed-off-by: Sasha Levin --- drivers/nvme/target/io-cmd-bdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c index 32008d85172b..40afe3d0599d 100644 --- a/drivers/nvme/target/io-cmd-bdev.c +++ b/drivers/nvme/target/io-cmd-bdev.c @@ -36,7 +36,7 @@ void nvmet_bdev_set_limits(struct block_device *bdev, struct nvme_id_ns *id) */ id->nsfeat |= 1 << 4; /* NPWG = Namespace Preferred Write Granularity. 0's based */ - id->npwg = lpp0b; + id->npwg = to0based(bdev_io_min(bdev) / bdev_logical_block_size(bdev)); /* NPWA = Namespace Preferred Write Alignment. 0's based */ id->npwa = id->npwg; /* NPDG = Namespace Preferred Deallocate Granularity. 0's based */ From fbd7d5d954eab240082239cea8b95f4b955179e5 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sun, 12 Jan 2025 22:59:59 +0100 Subject: [PATCH 078/138] net: ethernet: xgbe: re-add aneg to supported features in PHY quirks commit 6be7aca91009865d8c2b73589270224a6b6e67ab upstream. In 4.19, before the switch to linkmode bitmaps, PHY_GBIT_FEATURES included feature bits for aneg and TP/MII ports. SUPPORTED_TP | \ SUPPORTED_MII) SUPPORTED_10baseT_Full) SUPPORTED_100baseT_Full) SUPPORTED_1000baseT_Full) PHY_100BT_FEATURES | \ PHY_DEFAULT_FEATURES) PHY_1000BT_FEATURES) Referenced commit expanded PHY_GBIT_FEATURES, silently removing PHY_DEFAULT_FEATURES. The removed part can be re-added by using the new PHY_GBIT_FEATURES definition. Not clear to me is why nobody seems to have noticed this issue. I stumbled across this when checking what it takes to make phy_10_100_features_array et al private to phylib. Fixes: d0939c26c53a ("net: ethernet: xgbe: expand PHY_GBIT_FEAUTRES") Cc: stable@vger.kernel.org Signed-off-by: Heiner Kallweit Link: https://patch.msgid.link/46521973-7738-4157-9f5e-0bb6f694acba@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c index 0a15c617c702..fa56ef029315 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c @@ -855,7 +855,6 @@ static void xgbe_phy_free_phy_device(struct xgbe_prv_data *pdata) static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata) { - __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, }; struct xgbe_phy_data *phy_data = pdata->phy_data; unsigned int phy_id = phy_data->phydev->phy_id; @@ -877,14 +876,7 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata) phy_write(phy_data->phydev, 0x04, 0x0d01); phy_write(phy_data->phydev, 0x00, 0x9140); - linkmode_set_bit_array(phy_10_100_features_array, - ARRAY_SIZE(phy_10_100_features_array), - supported); - linkmode_set_bit_array(phy_gbit_features_array, - ARRAY_SIZE(phy_gbit_features_array), - supported); - - linkmode_copy(phy_data->phydev->supported, supported); + linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES); phy_support_asym_pause(phy_data->phydev); @@ -896,7 +888,6 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata) static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata) { - __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, }; struct xgbe_phy_data *phy_data = pdata->phy_data; struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom; unsigned int phy_id = phy_data->phydev->phy_id; @@ -960,13 +951,7 @@ static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata) reg = phy_read(phy_data->phydev, 0x00); phy_write(phy_data->phydev, 0x00, reg & ~0x00800); - linkmode_set_bit_array(phy_10_100_features_array, - ARRAY_SIZE(phy_10_100_features_array), - supported); - linkmode_set_bit_array(phy_gbit_features_array, - ARRAY_SIZE(phy_gbit_features_array), - supported); - linkmode_copy(phy_data->phydev->supported, supported); + linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES); phy_support_asym_pause(phy_data->phydev); netif_dbg(pdata, drv, pdata->netdev, From 84c4ed15626574c9ac6c1039ba9c137a77bcc7f2 Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Fri, 10 Jan 2025 10:28:21 -0500 Subject: [PATCH 079/138] fs/proc: fix softlockup in __read_vmcore (part 2) commit cbc5dde0a461240046e8a41c43d7c3b76d5db952 upstream. Since commit 5cbcb62dddf5 ("fs/proc: fix softlockup in __read_vmcore") the number of softlockups in __read_vmcore at kdump time have gone down, but they still happen sometimes. In a memory constrained environment like the kdump image, a softlockup is not just a harmless message, but it can interfere with things like RCU freeing memory, causing the crashdump to get stuck. The second loop in __read_vmcore has a lot more opportunities for natural sleep points, like scheduling out while waiting for a data write to happen, but apparently that is not always enough. Add a cond_resched() to the second loop in __read_vmcore to (hopefully) get rid of the softlockups. Link: https://lkml.kernel.org/r/20250110102821.2a37581b@fangorn Fixes: 5cbcb62dddf5 ("fs/proc: fix softlockup in __read_vmcore") Signed-off-by: Rik van Riel Reported-by: Breno Leitao Cc: Baoquan He Cc: Dave Young Cc: Vivek Goyal Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- fs/proc/vmcore.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 0ff2f1ddf9ef..fc70107740ab 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -397,6 +397,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos, if (buflen == 0) return acc; } + + cond_resched(); } return acc; From 1a544a2d424b82542e6761a1666a8bcafcb817ac Mon Sep 17 00:00:00 2001 From: Yogesh Lal Date: Fri, 20 Dec 2024 15:09:07 +0530 Subject: [PATCH 080/138] irqchip/gic-v3: Handle CPU_PM_ENTER_FAILED correctly commit 0d62a49ab55c99e8deb4593b8d9f923de1ab5c18 upstream. When a CPU attempts to enter low power mode, it disables the redistributor and Group 1 interrupts and reinitializes the system registers upon wakeup. If the transition into low power mode fails, then the CPU_PM framework invokes the PM notifier callback with CPU_PM_ENTER_FAILED to allow the drivers to undo the state changes. The GIC V3 driver ignores CPU_PM_ENTER_FAILED, which leaves the GIC in disabled state. Handle CPU_PM_ENTER_FAILED in the same way as CPU_PM_EXIT to restore normal operation. [ tglx: Massage change log, add Fixes tag ] Fixes: 3708d52fc6bb ("irqchip: gic-v3: Implement CPU PM notifier") Signed-off-by: Yogesh Lal Signed-off-by: Thomas Gleixner Acked-by: Marc Zyngier Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20241220093907.2747601-1-quic_ylal@quicinc.com Signed-off-by: Greg Kroah-Hartman --- drivers/irqchip/irq-gic-v3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 4cbfd8c18615..93fc046f9307 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1185,7 +1185,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, static int gic_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd, void *v) { - if (cmd == CPU_PM_EXIT) { + if (cmd == CPU_PM_EXIT || cmd == CPU_PM_ENTER_FAILED) { if (gic_dist_security_disabled()) gic_enable_redist(true); gic_cpu_sys_reg_init(); From 95e4f62df23f4df1ce6ef897d44b8e23c260921a Mon Sep 17 00:00:00 2001 From: Koichiro Den Date: Fri, 20 Dec 2024 22:44:21 +0900 Subject: [PATCH 081/138] hrtimers: Handle CPU state correctly on hotplug commit 2f8dea1692eef2b7ba6a256246ed82c365fdc686 upstream. Consider a scenario where a CPU transitions from CPUHP_ONLINE to halfway through a CPU hotunplug down to CPUHP_HRTIMERS_PREPARE, and then back to CPUHP_ONLINE: Since hrtimers_prepare_cpu() does not run, cpu_base.hres_active remains set to 1 throughout. However, during a CPU unplug operation, the tick and the clockevents are shut down at CPUHP_AP_TICK_DYING. On return to the online state, for instance CFS incorrectly assumes that the hrtick is already active, and the chance of the clockevent device to transition to oneshot mode is also lost forever for the CPU, unless it goes back to a lower state than CPUHP_HRTIMERS_PREPARE once. This round-trip reveals another issue; cpu_base.online is not set to 1 after the transition, which appears as a WARN_ON_ONCE in enqueue_hrtimer(). Aside of that, the bulk of the per CPU state is not reset either, which means there are dangling pointers in the worst case. Address this by adding a corresponding startup() callback, which resets the stale per CPU state and sets the online flag. [ tglx: Make the new callback unconditionally available, remove the online modification in the prepare() callback and clear the remaining state in the starting callback instead of the prepare callback ] Fixes: 5c0930ccaad5 ("hrtimers: Push pending hrtimers away from outgoing CPU earlier") Signed-off-by: Koichiro Den Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20241220134421.3809834-1-koichiro.den@canonical.com Signed-off-by: Greg Kroah-Hartman --- include/linux/hrtimer.h | 1 + kernel/cpu.c | 2 +- kernel/time/hrtimer.c | 11 ++++++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 7bbcb64eeecf..79b8cb62ce81 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -527,6 +527,7 @@ extern void __init hrtimers_init(void); extern void sysrq_timer_list_show(void); int hrtimers_prepare_cpu(unsigned int cpu); +int hrtimers_cpu_starting(unsigned int cpu); #ifdef CONFIG_HOTPLUG_CPU int hrtimers_cpu_dying(unsigned int cpu); #else diff --git a/kernel/cpu.c b/kernel/cpu.c index ba579bb6b897..5602936d9a9a 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -1542,7 +1542,7 @@ static struct cpuhp_step cpuhp_hp_states[] = { }, [CPUHP_AP_HRTIMERS_DYING] = { .name = "hrtimers:dying", - .startup.single = NULL, + .startup.single = hrtimers_cpu_starting, .teardown.single = hrtimers_cpu_dying, }, diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 2e4f136bdf6a..539bc80787ee 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -2065,6 +2065,15 @@ int hrtimers_prepare_cpu(unsigned int cpu) } cpu_base->cpu = cpu; + hrtimer_cpu_base_init_expiry_lock(cpu_base); + return 0; +} + +int hrtimers_cpu_starting(unsigned int cpu) +{ + struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases); + + /* Clear out any left over state from a CPU down operation */ cpu_base->active_bases = 0; cpu_base->hres_active = 0; cpu_base->hang_detected = 0; @@ -2073,7 +2082,6 @@ int hrtimers_prepare_cpu(unsigned int cpu) cpu_base->expires_next = KTIME_MAX; cpu_base->softirq_expires_next = KTIME_MAX; cpu_base->online = 1; - hrtimer_cpu_base_init_expiry_lock(cpu_base); return 0; } @@ -2151,6 +2159,7 @@ int hrtimers_cpu_dying(unsigned int dying_cpu) void __init hrtimers_init(void) { hrtimers_prepare_cpu(smp_processor_id()); + hrtimers_cpu_starting(smp_processor_id()); open_softirq(HRTIMER_SOFTIRQ, hrtimer_run_softirq); } From a61a174280dad99f25a7dee920310885daf2552b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 13 Sep 2024 08:31:47 +0000 Subject: [PATCH 082/138] ipv6: avoid possible NULL deref in rt6_uncached_list_flush_dev() commit 04ccecfa959d3b9ae7348780d8e379c6486176ac upstream. Blamed commit accidentally removed a check for rt->rt6i_idev being NULL, as spotted by syzbot: Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN PTI KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 1 UID: 0 PID: 10998 Comm: syz-executor Not tainted 6.11.0-rc6-syzkaller-00208-g625403177711 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/06/2024 RIP: 0010:rt6_uncached_list_flush_dev net/ipv6/route.c:177 [inline] RIP: 0010:rt6_disable_ip+0x33e/0x7e0 net/ipv6/route.c:4914 Code: 41 80 3c 04 00 74 0a e8 90 d0 9b f7 48 8b 7c 24 08 48 8b 07 48 89 44 24 10 4c 89 f0 48 c1 e8 03 48 b9 00 00 00 00 00 fc ff df <80> 3c 08 00 74 08 4c 89 f7 e8 64 d0 9b f7 48 8b 44 24 18 49 39 06 RSP: 0018:ffffc900047374e0 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 1ffff1100fdf8f33 RCX: dffffc0000000000 RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffff88807efc78c0 RBP: ffffc900047375d0 R08: 0000000000000003 R09: fffff520008e6e8c R10: dffffc0000000000 R11: fffff520008e6e8c R12: 1ffff1100fdf8f18 R13: ffff88807efc7998 R14: 0000000000000000 R15: ffff88807efc7930 FS: 0000000000000000(0000) GS:ffff8880b8900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020002a80 CR3: 0000000022f62000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: addrconf_ifdown+0x15d/0x1bd0 net/ipv6/addrconf.c:3856 addrconf_notify+0x3cb/0x1020 notifier_call_chain+0x19f/0x3e0 kernel/notifier.c:93 call_netdevice_notifiers_extack net/core/dev.c:2032 [inline] call_netdevice_notifiers net/core/dev.c:2046 [inline] unregister_netdevice_many_notify+0xd81/0x1c40 net/core/dev.c:11352 unregister_netdevice_many net/core/dev.c:11414 [inline] unregister_netdevice_queue+0x303/0x370 net/core/dev.c:11289 unregister_netdevice include/linux/netdevice.h:3129 [inline] __tun_detach+0x6b9/0x1600 drivers/net/tun.c:685 tun_detach drivers/net/tun.c:701 [inline] tun_chr_close+0x108/0x1b0 drivers/net/tun.c:3510 __fput+0x24a/0x8a0 fs/file_table.c:422 task_work_run+0x24f/0x310 kernel/task_work.c:228 exit_task_work include/linux/task_work.h:40 [inline] do_exit+0xa2f/0x27f0 kernel/exit.c:882 do_group_exit+0x207/0x2c0 kernel/exit.c:1031 __do_sys_exit_group kernel/exit.c:1042 [inline] __se_sys_exit_group kernel/exit.c:1040 [inline] __x64_sys_exit_group+0x3f/0x40 kernel/exit.c:1040 x64_sys_call+0x2634/0x2640 arch/x86/include/generated/asm/syscalls_64.h:232 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f1acc77def9 Code: Unable to access opcode bytes at 0x7f1acc77decf. RSP: 002b:00007ffeb26fa738 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f1acc77def9 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000043 RBP: 00007f1acc7dd508 R08: 00007ffeb26f84d7 R09: 0000000000000003 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001 R13: 0000000000000003 R14: 00000000ffffffff R15: 00007ffeb26fa8e0 Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:rt6_uncached_list_flush_dev net/ipv6/route.c:177 [inline] RIP: 0010:rt6_disable_ip+0x33e/0x7e0 net/ipv6/route.c:4914 Code: 41 80 3c 04 00 74 0a e8 90 d0 9b f7 48 8b 7c 24 08 48 8b 07 48 89 44 24 10 4c 89 f0 48 c1 e8 03 48 b9 00 00 00 00 00 fc ff df <80> 3c 08 00 74 08 4c 89 f7 e8 64 d0 9b f7 48 8b 44 24 18 49 39 06 RSP: 0018:ffffc900047374e0 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 1ffff1100fdf8f33 RCX: dffffc0000000000 RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffff88807efc78c0 RBP: ffffc900047375d0 R08: 0000000000000003 R09: fffff520008e6e8c R10: dffffc0000000000 R11: fffff520008e6e8c R12: 1ffff1100fdf8f18 R13: ffff88807efc7998 R14: 0000000000000000 R15: ffff88807efc7930 FS: 0000000000000000(0000) GS:ffff8880b8900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020002a80 CR3: 0000000022f62000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Fixes: e332bc67cf5e ("ipv6: Don't call with rt6_uncached_list_flush_dev") Signed-off-by: Eric Dumazet Reviewed-by: Simon Horman Reviewed-by: David Ahern Acked-by: Martin KaFai Lau Link: https://patch.msgid.link/20240913083147.3095442-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: BRUNO VERNAY Signed-off-by: Hugo SIMELIERE Signed-off-by: Greg Kroah-Hartman --- net/ipv6/route.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index f1c2ac967e36..364abcf4b6c1 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -173,7 +173,7 @@ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev) struct inet6_dev *rt_idev = rt->rt6i_idev; struct net_device *rt_dev = rt->dst.dev; - if (rt_idev->dev == dev) { + if (rt_idev && rt_idev->dev == dev) { rt->rt6i_idev = in6_dev_get(loopback_dev); in6_dev_put(rt_idev); } From e19acb1926c4a1f30ee1ec84d8afba2d975bd534 Mon Sep 17 00:00:00 2001 From: Suraj Sonawane Date: Wed, 20 Nov 2024 18:29:44 +0530 Subject: [PATCH 083/138] scsi: sg: Fix slab-use-after-free read in sg_release() commit f10593ad9bc36921f623361c9e3dd96bd52d85ee upstream. Fix a use-after-free bug in sg_release(), detected by syzbot with KASAN: BUG: KASAN: slab-use-after-free in lock_release+0x151/0xa30 kernel/locking/lockdep.c:5838 __mutex_unlock_slowpath+0xe2/0x750 kernel/locking/mutex.c:912 sg_release+0x1f4/0x2e0 drivers/scsi/sg.c:407 In sg_release(), the function kref_put(&sfp->f_ref, sg_remove_sfp) is called before releasing the open_rel_lock mutex. The kref_put() call may decrement the reference count of sfp to zero, triggering its cleanup through sg_remove_sfp(). This cleanup includes scheduling deferred work via sg_remove_sfp_usercontext(), which ultimately frees sfp. After kref_put(), sg_release() continues to unlock open_rel_lock and may reference sfp or sdp. If sfp has already been freed, this results in a slab-use-after-free error. Move the kref_put(&sfp->f_ref, sg_remove_sfp) call after unlocking the open_rel_lock mutex. This ensures: - No references to sfp or sdp occur after the reference count is decremented. - Cleanup functions such as sg_remove_sfp() and sg_remove_sfp_usercontext() can safely execute without impacting the mutex handling in sg_release(). The fix has been tested and validated by syzbot. This patch closes the bug reported at the following syzkaller link and ensures proper sequencing of resource cleanup and mutex operations, eliminating the risk of use-after-free errors in sg_release(). Reported-by: syzbot+7efb5850a17ba6ce098b@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=7efb5850a17ba6ce098b Tested-by: syzbot+7efb5850a17ba6ce098b@syzkaller.appspotmail.com Fixes: cc833acbee9d ("sg: O_EXCL and other lock handling") Signed-off-by: Suraj Sonawane Link: https://lore.kernel.org/r/20241120125944.88095-1-surajsonawane0215@gmail.com Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen Signed-off-by: BRUNO VERNAY Signed-off-by: Hugo SIMELIERE Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index cc836610e21e..001a3470b3aa 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -390,7 +390,6 @@ sg_release(struct inode *inode, struct file *filp) mutex_lock(&sdp->open_rel_lock); scsi_autopm_put_device(sdp->device); - kref_put(&sfp->f_ref, sg_remove_sfp); sdp->open_cnt--; /* possibly many open()s waiting on exlude clearing, start many; @@ -402,6 +401,7 @@ sg_release(struct inode *inode, struct file *filp) wake_up_interruptible(&sdp->open_wait); } mutex_unlock(&sdp->open_rel_lock); + kref_put(&sfp->f_ref, sg_remove_sfp); return 0; } From 695fb0b9aecfd5dd5b2946ba8897ac2c1eef654d Mon Sep 17 00:00:00 2001 From: Wang Liang Date: Thu, 7 Nov 2024 10:34:05 +0800 Subject: [PATCH 084/138] net: fix data-races around sk->sk_forward_alloc commit 073d89808c065ac4c672c0a613a71b27a80691cb upstream. Syzkaller reported this warning: ------------[ cut here ]------------ WARNING: CPU: 0 PID: 16 at net/ipv4/af_inet.c:156 inet_sock_destruct+0x1c5/0x1e0 Modules linked in: CPU: 0 UID: 0 PID: 16 Comm: ksoftirqd/0 Not tainted 6.12.0-rc5 #26 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 RIP: 0010:inet_sock_destruct+0x1c5/0x1e0 Code: 24 12 4c 89 e2 5b 48 c7 c7 98 ec bb 82 41 5c e9 d1 18 17 ff 4c 89 e6 5b 48 c7 c7 d0 ec bb 82 41 5c e9 bf 18 17 ff 0f 0b eb 83 <0f> 0b eb 97 0f 0b eb 87 0f 0b e9 68 ff ff ff 66 66 2e 0f 1f 84 00 RSP: 0018:ffffc9000008bd90 EFLAGS: 00010206 RAX: 0000000000000300 RBX: ffff88810b172a90 RCX: 0000000000000007 RDX: 0000000000000002 RSI: 0000000000000300 RDI: ffff88810b172a00 RBP: ffff88810b172a00 R08: ffff888104273c00 R09: 0000000000100007 R10: 0000000000020000 R11: 0000000000000006 R12: ffff88810b172a00 R13: 0000000000000004 R14: 0000000000000000 R15: ffff888237c31f78 FS: 0000000000000000(0000) GS:ffff888237c00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffc63fecac8 CR3: 000000000342e000 CR4: 00000000000006f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: ? __warn+0x88/0x130 ? inet_sock_destruct+0x1c5/0x1e0 ? report_bug+0x18e/0x1a0 ? handle_bug+0x53/0x90 ? exc_invalid_op+0x18/0x70 ? asm_exc_invalid_op+0x1a/0x20 ? inet_sock_destruct+0x1c5/0x1e0 __sk_destruct+0x2a/0x200 rcu_do_batch+0x1aa/0x530 ? rcu_do_batch+0x13b/0x530 rcu_core+0x159/0x2f0 handle_softirqs+0xd3/0x2b0 ? __pfx_smpboot_thread_fn+0x10/0x10 run_ksoftirqd+0x25/0x30 smpboot_thread_fn+0xdd/0x1d0 kthread+0xd3/0x100 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x34/0x50 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 ---[ end trace 0000000000000000 ]--- Its possible that two threads call tcp_v6_do_rcv()/sk_forward_alloc_add() concurrently when sk->sk_state == TCP_LISTEN with sk->sk_lock unlocked, which triggers a data-race around sk->sk_forward_alloc: tcp_v6_rcv tcp_v6_do_rcv skb_clone_and_charge_r sk_rmem_schedule __sk_mem_schedule sk_forward_alloc_add() skb_set_owner_r sk_mem_charge sk_forward_alloc_add() __kfree_skb skb_release_all skb_release_head_state sock_rfree sk_mem_uncharge sk_forward_alloc_add() sk_mem_reclaim // set local var reclaimable __sk_mem_reclaim sk_forward_alloc_add() In this syzkaller testcase, two threads call tcp_v6_do_rcv() with skb->truesize=768, the sk_forward_alloc changes like this: (cpu 1) | (cpu 2) | sk_forward_alloc ... | ... | 0 __sk_mem_schedule() | | +4096 = 4096 | __sk_mem_schedule() | +4096 = 8192 sk_mem_charge() | | -768 = 7424 | sk_mem_charge() | -768 = 6656 ... | ... | sk_mem_uncharge() | | +768 = 7424 reclaimable=7424 | | | sk_mem_uncharge() | +768 = 8192 | reclaimable=8192 | __sk_mem_reclaim() | | -4096 = 4096 | __sk_mem_reclaim() | -8192 = -4096 != 0 The skb_clone_and_charge_r() should not be called in tcp_v6_do_rcv() when sk->sk_state is TCP_LISTEN, it happens later in tcp_v6_syn_recv_sock(). Fix the same issue in dccp_v6_do_rcv(). Suggested-by: Eric Dumazet Reviewed-by: Eric Dumazet Fixes: e994b2f0fb92 ("tcp: do not lock listener to process SYN packets") Signed-off-by: Wang Liang Link: https://patch.msgid.link/20241107023405.889239-1-wangliang74@huawei.com Signed-off-by: Jakub Kicinski Signed-off-by: Alva Lan Signed-off-by: Greg Kroah-Hartman --- net/dccp/ipv6.c | 2 +- net/ipv6/tcp_ipv6.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index c3a378ef95aa..cbefbe6d07ae 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -602,7 +602,7 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) by tcp. Feel free to propose better solution. --ANK (980728) */ - if (np->rxopt.all) + if (np->rxopt.all && sk->sk_state != DCCP_LISTEN) opt_skb = skb_clone_and_charge_r(skb, sk); if (sk->sk_state == DCCP_OPEN) { /* Fast path */ diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 8be41d6c4278..8ed5b5dd6ba4 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1393,7 +1393,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) by tcp. Feel free to propose better solution. --ANK (980728) */ - if (np->rxopt.all) + if (np->rxopt.all && sk->sk_state != TCP_LISTEN) opt_skb = skb_clone_and_charge_r(skb, sk); if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ @@ -1430,8 +1430,6 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) if (nsk != sk) { if (tcp_child_process(sk, nsk, skb)) goto reset; - if (opt_skb) - __kfree_skb(opt_skb); return 0; } } else From 820bc91224daeffdd37bf96710306f9f61f8aea1 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 6 Jan 2025 15:46:39 +0000 Subject: [PATCH 085/138] ASoC: wm8994: Add depends on MFD core [ Upstream commit 5ed01155cea69801f1f0c908954a56a5a3474bed ] The ASoC driver should not be used without the MFD component. This was causing randconfig issues with regmap IRQ which is selected by the MFD part of the wm8994 driver. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202501061337.R0DlBUoD-lkp@intel.com/ Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250106154639.3999553-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index dfc536cd9d2f..7b03ff158d78 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -1400,6 +1400,7 @@ config SND_SOC_WM8993 config SND_SOC_WM8994 tristate + depends on MFD_WM8994 config SND_SOC_WM8995 tristate From c7cbdb506d408f0c6f17f4c0ec5bcd5f53d299c0 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Tue, 7 Jan 2025 10:24:31 +0800 Subject: [PATCH 086/138] scsi: iscsi: Fix redundant response for ISCSI_UEVENT_GET_HOST_STATS request [ Upstream commit 63ca02221cc5aa0731fe2b0cc28158aaa4b84982 ] The ISCSI_UEVENT_GET_HOST_STATS request is already handled in iscsi_get_host_stats(). This fix ensures that redundant responses are skipped in iscsi_if_rx(). - On success: send reply and stats from iscsi_get_host_stats() within if_recv_msg(). - On error: fall through. Signed-off-by: Xiang Zhang Link: https://lore.kernel.org/r/20250107022432.65390-1-hawkxiang.cpp@gmail.com Reviewed-by: Mike Christie Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/scsi_transport_iscsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 51f53638629c..9ef242d2a2c9 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -3746,7 +3746,7 @@ iscsi_if_rx(struct sk_buff *skb) } do { /* - * special case for GET_STATS: + * special case for GET_STATS, GET_CHAP and GET_HOST_STATS: * on success - sending reply and stats from * inside of if_recv_msg(), * on error - fall through. @@ -3755,6 +3755,8 @@ iscsi_if_rx(struct sk_buff *skb) break; if (ev->type == ISCSI_UEVENT_GET_CHAP && !err) break; + if (ev->type == ISCSI_UEVENT_GET_HOST_STATS && !err) + break; err = iscsi_if_send_reply(portid, nlh->nlmsg_type, ev, sizeof(*ev)); if (err == -EAGAIN && --retries < 0) { From d26c6ec19cdf5b41c4a604e9df851793904c3e17 Mon Sep 17 00:00:00 2001 From: Philippe Simons Date: Sun, 12 Jan 2025 13:34:02 +0100 Subject: [PATCH 087/138] irqchip/sunxi-nmi: Add missing SKIP_WAKE flag [ Upstream commit 3a748d483d80f066ca4b26abe45cdc0c367d13e9 ] Some boards with Allwinner SoCs connect the PMIC's IRQ pin to the SoC's NMI pin instead of a normal GPIO. Since the power key is connected to the PMIC, and people expect to wake up a suspended system via this key, the NMI IRQ controller must stay alive when the system goes into suspend. Add the SKIP_WAKE flag to prevent the sunxi NMI controller from going to sleep, so that the power key can wake up those systems. [ tglx: Fixed up coding style ] Signed-off-by: Philippe Simons Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250112123402.388520-1-simons.philippe@gmail.com Signed-off-by: Sasha Levin --- drivers/irqchip/irq-sunxi-nmi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-sunxi-nmi.c b/drivers/irqchip/irq-sunxi-nmi.c index a412b5d5d0fa..a2aadfdc4772 100644 --- a/drivers/irqchip/irq-sunxi-nmi.c +++ b/drivers/irqchip/irq-sunxi-nmi.c @@ -200,7 +200,8 @@ static int __init sunxi_sc_nmi_irq_init(struct device_node *node, gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; gc->chip_types[0].chip.irq_eoi = irq_gc_ack_set_bit; gc->chip_types[0].chip.irq_set_type = sunxi_sc_nmi_set_type; - gc->chip_types[0].chip.flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED; + gc->chip_types[0].chip.flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED | + IRQCHIP_SKIP_SET_WAKE; gc->chip_types[0].regs.ack = reg_offs->pend; gc->chip_types[0].regs.mask = reg_offs->enable; gc->chip_types[0].regs.type = reg_offs->ctrl; From 2b0bd5051ad1c1e9ef4879f18e15a7712c974f3e Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Mon, 13 Jan 2025 19:31:28 +0100 Subject: [PATCH 088/138] gfs2: Truncate address space when flipping GFS2_DIF_JDATA flag commit 7c9d9223802fbed4dee1ae301661bf346964c9d2 upstream. Truncate an inode's address space when flipping the GFS2_DIF_JDATA flag: depending on that flag, the pages in the address space will either use buffer heads or iomap_folio_state structs, and we cannot mix the two. Reported-by: Kun Hu , Jiaji Qin Signed-off-by: Andreas Gruenbacher Signed-off-by: Greg Kroah-Hartman --- fs/gfs2/file.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 69c52edf5713..22c1b29c0551 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -271,6 +271,7 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask, error = filemap_fdatawait(inode->i_mapping); if (error) goto out; + truncate_inode_pages(inode->i_mapping, 0); if (new_flags & GFS2_DIF_JDATA) gfs2_ordered_del_inode(ip); } From 2354a75095b96d4097684a7a318c5164b31f98ff Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 25 Jul 2021 17:19:45 +0000 Subject: [PATCH 089/138] m68k: Update ->thread.esp0 before calling syscall_trace() in ret_from_signal commit 50e43a57334400668952f8e551c9d87d3ed2dfef upstream. We get there when sigreturn has performed obscene acts on kernel stack; in particular, the location of pt_regs has shifted. We are about to call syscall_trace(), which might stop for tracer. If that happens, we'd better have task_pt_regs() returning correct result... Fucked-up-by: Al Viro Fixes: bd6f56a75bb2 ("m68k: Missing syscall_trace() on sigreturn") Signed-off-by: Al Viro Tested-by: Michael Schmitz Reviewed-by: Michael Schmitz Tested-by: Finn Thain Link: https://lore.kernel.org/r/YP2dMWeV1LkHiOpr@zeniv-ca.linux.org.uk Signed-off-by: Geert Uytterhoeven Signed-off-by: Finn Thain Signed-off-by: Greg Kroah-Hartman --- arch/m68k/kernel/entry.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 417d8f0e8962..0d03b4f2077b 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -182,6 +182,8 @@ ENTRY(ret_from_signal) movel %curptr@(TASK_STACK),%a1 tstb %a1@(TINFO_FLAGS+2) jge 1f + lea %sp@(SWITCH_STACK_SIZE),%a1 + movel %a1,%curptr@(TASK_THREAD+THREAD_ESP0) jbsr syscall_trace 1: RESTORE_SWITCH_STACK addql #4,%sp From 28810b2aa0b1be9e4b8364470ae342dd44de4704 Mon Sep 17 00:00:00 2001 From: Liam Howlett Date: Wed, 7 Apr 2021 20:00:45 +0000 Subject: [PATCH 090/138] m68k: Add missing mmap_read_lock() to sys_cacheflush() commit f829b4b212a315b912cb23fd10aaf30534bb5ce9 upstream. When the superuser flushes the entire cache, the mmap_read_lock() is not taken, but mmap_read_unlock() is called. Add the missing mmap_read_lock() call. Fixes: cd2567b6850b1648 ("m68k: call find_vma with the mmap_sem held in sys_cacheflush()") Signed-off-by: Liam R. Howlett Reviewed-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20210407200032.764445-1-Liam.Howlett@Oracle.com Signed-off-by: Geert Uytterhoeven [ mmap_read_lock() open-coded using down_read() as was done prior to v5.8 ] Signed-off-by: Finn Thain Signed-off-by: Greg Kroah-Hartman --- arch/m68k/kernel/sys_m68k.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 6363ec83a290..38dcc1a2097d 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c @@ -388,6 +388,8 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) ret = -EPERM; if (!capable(CAP_SYS_ADMIN)) goto out; + + down_read(¤t->mm->mmap_sem); } else { struct vm_area_struct *vma; From d304365293219810c677bc5a2255bbb1d6bee002 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Mon, 26 Jul 2021 14:23:11 -0500 Subject: [PATCH 091/138] signal/m68k: Use force_sigsegv(SIGSEGV) in fpsp040_die commit a3616a3c02722d1edb95acc7fceade242f6553ba upstream. In the fpsp040 code when copyin or copyout fails call force_sigsegv(SIGSEGV) instead of do_exit(SIGSEGV). This solves a couple of problems. Because do_exit embeds the ptrace stop PTRACE_EVENT_EXIT a complete stack frame needs to be present for that to work correctly. There is always the information needed for a ptrace stop where get_signal is called. So exiting with a signal solves the ptrace issue. Further exiting with a signal ensures that all of the threads in a process are killed not just the thread that malfunctioned. Which avoids confusing userspace. To make force_sigsegv(SIGSEGV) work in fpsp040_die modify the code to save all of the registers and jump to ret_from_exception (which ultimately calls get_signal) after fpsp040_die returns. v2: Updated the branches to use gas's pseudo ops that automatically calculate the best branch instruction to use for the purpose. v1: https://lkml.kernel.org/r/87a6m8kgtx.fsf_-_@disp2133 Link: https://lkml.kernel.org/r/87tukghjfs.fsf_-_@disp2133 Acked-by: Geert Uytterhoeven Signed-off-by: "Eric W. Biederman" Signed-off-by: Finn Thain Signed-off-by: Greg Kroah-Hartman --- arch/m68k/fpsp040/skeleton.S | 3 ++- arch/m68k/kernel/traps.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/m68k/fpsp040/skeleton.S b/arch/m68k/fpsp040/skeleton.S index 31a9c634c81e..081922c72daa 100644 --- a/arch/m68k/fpsp040/skeleton.S +++ b/arch/m68k/fpsp040/skeleton.S @@ -502,7 +502,8 @@ in_ea: .section .fixup,"ax" .even 1: - jbra fpsp040_die + jbsr fpsp040_die + jbra .Lnotkern .section __ex_table,"a" .align 4 diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c index 5bf314871e9f..38311a403b08 100644 --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c @@ -1155,7 +1155,7 @@ asmlinkage void set_esp0(unsigned long ssp) */ asmlinkage void fpsp040_die(void) { - do_exit(SIGSEGV); + force_sigsegv(SIGSEGV); } #ifdef CONFIG_M68KFPU_EMU From 4b978070c505c5ebca32095256407760c5397558 Mon Sep 17 00:00:00 2001 From: Madhuparna Bhowmik Date: Wed, 15 Jan 2020 21:25:53 +0530 Subject: [PATCH 092/138] net: xen-netback: hash.c: Use built-in RCU list checking commit f3265971ded98a069ad699b51b8a5ab95e9e5be1 upstream. list_for_each_entry_rcu has built-in RCU and lock checking. Pass cond argument to list_for_each_entry_rcu. Signed-off-by: Madhuparna Bhowmik Acked-by: Wei Liu Signed-off-by: David S. Miller Stable-dep-of: 0fa5e94a1811 ("net/xen-netback: prevent UAF in xenvif_flush_hash()") Signed-off-by: Hagar Hemdan Signed-off-by: Greg Kroah-Hartman --- drivers/net/xen-netback/hash.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/xen-netback/hash.c b/drivers/net/xen-netback/hash.c index 10d580c3dea3..6b7532f7c936 100644 --- a/drivers/net/xen-netback/hash.c +++ b/drivers/net/xen-netback/hash.c @@ -51,7 +51,8 @@ static void xenvif_add_hash(struct xenvif *vif, const u8 *tag, found = false; oldest = NULL; - list_for_each_entry_rcu(entry, &vif->hash.cache.list, link) { + list_for_each_entry_rcu(entry, &vif->hash.cache.list, link, + lockdep_is_held(&vif->hash.cache.lock)) { /* Make sure we don't add duplicate entries */ if (entry->len == len && memcmp(entry->tag, tag, len) == 0) @@ -102,7 +103,8 @@ static void xenvif_flush_hash(struct xenvif *vif) spin_lock_irqsave(&vif->hash.cache.lock, flags); - list_for_each_entry_rcu(entry, &vif->hash.cache.list, link) { + list_for_each_entry_rcu(entry, &vif->hash.cache.list, link, + lockdep_is_held(&vif->hash.cache.lock)) { list_del_rcu(&entry->link); vif->hash.cache.count--; kfree_rcu(entry, rcu); From 3c4423b0c4b98213b3438e15061e1d08220e6982 Mon Sep 17 00:00:00 2001 From: Jeongjun Park Date: Fri, 23 Aug 2024 03:11:09 +0900 Subject: [PATCH 093/138] net/xen-netback: prevent UAF in xenvif_flush_hash() commit 0fa5e94a1811d68fbffa0725efe6d4ca62c03d12 upstream. During the list_for_each_entry_rcu iteration call of xenvif_flush_hash, kfree_rcu does not exist inside the rcu read critical section, so if kfree_rcu is called when the rcu grace period ends during the iteration, UAF occurs when accessing head->next after the entry becomes free. Therefore, to solve this, you need to change it to list_for_each_entry_safe. Signed-off-by: Jeongjun Park Link: https://patch.msgid.link/20240822181109.2577354-1-aha310510@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Hagar Hemdan Signed-off-by: Greg Kroah-Hartman --- drivers/net/xen-netback/hash.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/xen-netback/hash.c b/drivers/net/xen-netback/hash.c index 6b7532f7c936..dff011bf324b 100644 --- a/drivers/net/xen-netback/hash.c +++ b/drivers/net/xen-netback/hash.c @@ -95,7 +95,7 @@ static u32 xenvif_new_hash(struct xenvif *vif, const u8 *data, static void xenvif_flush_hash(struct xenvif *vif) { - struct xenvif_hash_cache_entry *entry; + struct xenvif_hash_cache_entry *entry, *n; unsigned long flags; if (xenvif_hash_cache_size == 0) @@ -103,8 +103,7 @@ static void xenvif_flush_hash(struct xenvif *vif) spin_lock_irqsave(&vif->hash.cache.lock, flags); - list_for_each_entry_rcu(entry, &vif->hash.cache.list, link, - lockdep_is_held(&vif->hash.cache.lock)) { + list_for_each_entry_safe(entry, n, &vif->hash.cache.list, link) { list_del_rcu(&entry->link); vif->hash.cache.count--; kfree_rcu(entry, rcu); From f21636f24b6786c8b13f1af4319fa75ffcf17f38 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Wed, 22 Jan 2025 10:38:30 -0700 Subject: [PATCH 094/138] vfio/platform: check the bounds of read/write syscalls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit ce9ff21ea89d191e477a02ad7eabf4f996b80a69 upstream. count and offset are passed from user space and not checked, only offset is capped to 40 bits, which can be used to read/write out of bounds of the device. Fixes: 6e3f26456009 (“vfio/platform: read and write support for the device fd”) Cc: stable@vger.kernel.org Reported-by: Mostafa Saleh Reviewed-by: Eric Auger Reviewed-by: Mostafa Saleh Tested-by: Mostafa Saleh Signed-off-by: Alex Williamson Signed-off-by: Greg Kroah-Hartman --- drivers/vfio/platform/vfio_platform_common.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c index 46a72fe39719..9165bf6ad018 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c @@ -405,6 +405,11 @@ static ssize_t vfio_platform_read_mmio(struct vfio_platform_region *reg, { unsigned int done = 0; + if (off >= reg->size) + return -EINVAL; + + count = min_t(size_t, count, reg->size - off); + if (!reg->ioaddr) { reg->ioaddr = ioremap_nocache(reg->addr, reg->size); @@ -482,6 +487,11 @@ static ssize_t vfio_platform_write_mmio(struct vfio_platform_region *reg, { unsigned int done = 0; + if (off >= reg->size) + return -EINVAL; + + count = min_t(size_t, count, reg->size - off); + if (!reg->ioaddr) { reg->ioaddr = ioremap_nocache(reg->addr, reg->size); From 34b2d3843a53e13439ba9b06a63484dfb21725b5 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 7 May 2020 10:50:28 -0700 Subject: [PATCH 095/138] ext4: avoid ext4_error()'s caused by ENOMEM in the truncate path commit 73c384c0cdaa8ea9ca9ef2d0cff6a25930f1648e upstream. We can't fail in the truncate path without requiring an fsck. Add work around for this by using a combination of retry loops and the __GFP_NOFAIL flag. From: Theodore Ts'o Signed-off-by: Theodore Ts'o Signed-off-by: Anna Pendleton Reviewed-by: Harshad Shirwadkar Link: https://lore.kernel.org/r/20200507175028.15061-1-pendleton@google.com Signed-off-by: Theodore Ts'o Stable-dep-of: c26ab35702f8 ("ext4: fix slab-use-after-free in ext4_split_extent_at()") [v5.4: resolved contextual conflict in __read_extent_tree_block] Signed-off-by: Shaoying Xu Signed-off-by: Greg Kroah-Hartman --- fs/ext4/ext4.h | 1 + fs/ext4/extents.c | 43 +++++++++++++++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 4d02116193de..44bfa589ed36 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -628,6 +628,7 @@ enum { */ #define EXT4_EX_NOCACHE 0x40000000 #define EXT4_EX_FORCE_CACHE 0x20000000 +#define EXT4_EX_NOFAIL 0x10000000 /* * Flags used by ext4_free_blocks diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 0d692025f923..0e16e7c08a42 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -304,11 +304,14 @@ ext4_force_split_extent_at(handle_t *handle, struct inode *inode, { struct ext4_ext_path *path = *ppath; int unwritten = ext4_ext_is_unwritten(path[path->p_depth].p_ext); + int flags = EXT4_EX_NOCACHE | EXT4_GET_BLOCKS_PRE_IO; + + if (nofail) + flags |= EXT4_GET_BLOCKS_METADATA_NOFAIL | EXT4_EX_NOFAIL; return ext4_split_extent_at(handle, inode, ppath, lblk, unwritten ? EXT4_EXT_MARK_UNWRIT1|EXT4_EXT_MARK_UNWRIT2 : 0, - EXT4_EX_NOCACHE | EXT4_GET_BLOCKS_PRE_IO | - (nofail ? EXT4_GET_BLOCKS_METADATA_NOFAIL:0)); + flags); } /* @@ -572,9 +575,13 @@ __read_extent_tree_block(const char *function, unsigned int line, struct buffer_head *bh; int err; ext4_fsblk_t pblk; + gfp_t gfp_flags = __GFP_MOVABLE | GFP_NOFS; + + if (flags & EXT4_EX_NOFAIL) + gfp_flags |= __GFP_NOFAIL; pblk = ext4_idx_pblock(idx); - bh = sb_getblk_gfp(inode->i_sb, pblk, __GFP_MOVABLE | GFP_NOFS); + bh = sb_getblk_gfp(inode->i_sb, pblk, gfp_flags); if (unlikely(!bh)) return ERR_PTR(-ENOMEM); @@ -919,6 +926,10 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block, struct ext4_ext_path *path = orig_path ? *orig_path : NULL; short int depth, i, ppos = 0; int ret; + gfp_t gfp_flags = GFP_NOFS; + + if (flags & EXT4_EX_NOFAIL) + gfp_flags |= __GFP_NOFAIL; eh = ext_inode_hdr(inode); depth = ext_depth(inode); @@ -939,7 +950,7 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block, if (!path) { /* account possible depth increase */ path = kcalloc(depth + 2, sizeof(struct ext4_ext_path), - GFP_NOFS); + gfp_flags); if (unlikely(!path)) return ERR_PTR(-ENOMEM); path[0].p_maxdepth = depth + 1; @@ -1088,9 +1099,13 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, ext4_fsblk_t newblock, oldblock; __le32 border; ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */ + gfp_t gfp_flags = GFP_NOFS; int err = 0; size_t ext_size = 0; + if (flags & EXT4_EX_NOFAIL) + gfp_flags |= __GFP_NOFAIL; + /* make decision: where to split? */ /* FIXME: now decision is simplest: at current extent */ @@ -1124,7 +1139,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, * We need this to handle errors and free blocks * upon them. */ - ablocks = kcalloc(depth, sizeof(ext4_fsblk_t), GFP_NOFS); + ablocks = kcalloc(depth, sizeof(ext4_fsblk_t), gfp_flags); if (!ablocks) return -ENOMEM; @@ -2110,7 +2125,7 @@ prepend: if (next != EXT_MAX_BLOCKS) { ext_debug("next leaf block - %u\n", next); BUG_ON(npath != NULL); - npath = ext4_find_extent(inode, next, NULL, 0); + npath = ext4_find_extent(inode, next, NULL, gb_flags); if (IS_ERR(npath)) return PTR_ERR(npath); BUG_ON(npath->p_depth != path->p_depth); @@ -3018,7 +3033,8 @@ again: ext4_fsblk_t pblk; /* find extent for or closest extent to this block */ - path = ext4_find_extent(inode, end, NULL, EXT4_EX_NOCACHE); + path = ext4_find_extent(inode, end, NULL, + EXT4_EX_NOCACHE | EXT4_EX_NOFAIL); if (IS_ERR(path)) { ext4_journal_stop(handle); return PTR_ERR(path); @@ -3104,7 +3120,7 @@ again: le16_to_cpu(path[k].p_hdr->eh_entries)+1; } else { path = kcalloc(depth + 1, sizeof(struct ext4_ext_path), - GFP_NOFS); + GFP_NOFS | __GFP_NOFAIL); if (path == NULL) { ext4_journal_stop(handle); return -ENOMEM; @@ -3528,7 +3544,7 @@ static int ext4_split_extent(handle_t *handle, * Update path is required because previous ext4_split_extent_at() may * result in split of original leaf or extent zeroout. */ - path = ext4_find_extent(inode, map->m_lblk, ppath, 0); + path = ext4_find_extent(inode, map->m_lblk, ppath, flags); if (IS_ERR(path)) return PTR_ERR(path); depth = ext_depth(inode); @@ -4650,7 +4666,14 @@ retry: } if (err) return err; - return ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1); +retry_remove_space: + err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1); + if (err == -ENOMEM) { + cond_resched(); + congestion_wait(BLK_RW_ASYNC, HZ/50); + goto retry_remove_space; + } + return err; } static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, From 448100a29395b0c8b4c42967155849fe0fbe808f Mon Sep 17 00:00:00 2001 From: Baokun Li Date: Thu, 22 Aug 2024 10:35:23 +0800 Subject: [PATCH 096/138] ext4: fix slab-use-after-free in ext4_split_extent_at() commit c26ab35702f8cd0cdc78f96aa5856bfb77be798f upstream. We hit the following use-after-free: ================================================================== BUG: KASAN: slab-use-after-free in ext4_split_extent_at+0xba8/0xcc0 Read of size 2 at addr ffff88810548ed08 by task kworker/u20:0/40 CPU: 0 PID: 40 Comm: kworker/u20:0 Not tainted 6.9.0-dirty #724 Call Trace: kasan_report+0x93/0xc0 ext4_split_extent_at+0xba8/0xcc0 ext4_split_extent.isra.0+0x18f/0x500 ext4_split_convert_extents+0x275/0x750 ext4_ext_handle_unwritten_extents+0x73e/0x1580 ext4_ext_map_blocks+0xe20/0x2dc0 ext4_map_blocks+0x724/0x1700 ext4_do_writepages+0x12d6/0x2a70 [...] Allocated by task 40: __kmalloc_noprof+0x1ac/0x480 ext4_find_extent+0xf3b/0x1e70 ext4_ext_map_blocks+0x188/0x2dc0 ext4_map_blocks+0x724/0x1700 ext4_do_writepages+0x12d6/0x2a70 [...] Freed by task 40: kfree+0xf1/0x2b0 ext4_find_extent+0xa71/0x1e70 ext4_ext_insert_extent+0xa22/0x3260 ext4_split_extent_at+0x3ef/0xcc0 ext4_split_extent.isra.0+0x18f/0x500 ext4_split_convert_extents+0x275/0x750 ext4_ext_handle_unwritten_extents+0x73e/0x1580 ext4_ext_map_blocks+0xe20/0x2dc0 ext4_map_blocks+0x724/0x1700 ext4_do_writepages+0x12d6/0x2a70 [...] ================================================================== The flow of issue triggering is as follows: ext4_split_extent_at path = *ppath ext4_ext_insert_extent(ppath) ext4_ext_create_new_leaf(ppath) ext4_find_extent(orig_path) path = *orig_path read_extent_tree_block // return -ENOMEM or -EIO ext4_free_ext_path(path) kfree(path) *orig_path = NULL a. If err is -ENOMEM: ext4_ext_dirty(path + path->p_depth) // path use-after-free !!! b. If err is -EIO and we have EXT_DEBUG defined: ext4_ext_show_leaf(path) eh = path[depth].p_hdr // path also use-after-free !!! So when trying to zeroout or fix the extent length, call ext4_find_extent() to update the path. In addition we use *ppath directly as an ext4_ext_show_leaf() input to avoid possible use-after-free when EXT_DEBUG is defined, and to avoid unnecessary path updates. Fixes: dfe5080939ea ("ext4: drop EXT4_EX_NOFREE_ON_ERR from rest of extents handling code") Cc: stable@kernel.org Signed-off-by: Baokun Li Reviewed-by: Jan Kara Reviewed-by: Ojaswin Mujoo Tested-by: Ojaswin Mujoo Link: https://patch.msgid.link/20240822023545.1994557-4-libaokun@huaweicloud.com Signed-off-by: Theodore Ts'o Signed-off-by: Shaoying Xu Signed-off-by: Greg Kroah-Hartman --- fs/ext4/extents.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 0e16e7c08a42..5c0ef7a04169 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3440,6 +3440,25 @@ static int ext4_split_extent_at(handle_t *handle, if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM) goto out; + /* + * Update path is required because previous ext4_ext_insert_extent() + * may have freed or reallocated the path. Using EXT4_EX_NOFAIL + * guarantees that ext4_find_extent() will not return -ENOMEM, + * otherwise -ENOMEM will cause a retry in do_writepages(), and a + * WARN_ON may be triggered in ext4_da_update_reserve_space() due to + * an incorrect ee_len causing the i_reserved_data_blocks exception. + */ + path = ext4_find_extent(inode, ee_block, ppath, + flags | EXT4_EX_NOFAIL); + if (IS_ERR(path)) { + EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld", + split, PTR_ERR(path)); + return PTR_ERR(path); + } + depth = ext_depth(inode); + ex = path[depth].p_ext; + *ppath = path; + if (EXT4_EXT_MAY_ZEROOUT & split_flag) { if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) { if (split_flag & EXT4_EXT_DATA_VALID1) { @@ -3488,7 +3507,7 @@ fix_extent_len: ext4_ext_dirty(handle, inode, path + path->p_depth); return err; out: - ext4_ext_show_leaf(inode, path); + ext4_ext_show_leaf(inode, *ppath); return err; } From fa4c7472469d97c4707698b4c0e098f8cfc2bf22 Mon Sep 17 00:00:00 2001 From: Qasim Ijaz Date: Mon, 13 Jan 2025 18:00:34 +0000 Subject: [PATCH 097/138] USB: serial: quatech2: fix null-ptr-deref in qt2_process_read_urb() commit 575a5adf48b06a2980c9eeffedf699ed5534fade upstream. This patch addresses a null-ptr-deref in qt2_process_read_urb() due to an incorrect bounds check in the following: if (newport > serial->num_ports) { dev_err(&port->dev, "%s - port change to invalid port: %i\n", __func__, newport); break; } The condition doesn't account for the valid range of the serial->port buffer, which is from 0 to serial->num_ports - 1. When newport is equal to serial->num_ports, the assignment of "port" in the following code is out-of-bounds and NULL: serial_priv->current_port = newport; port = serial->port[serial_priv->current_port]; The fix checks if newport is greater than or equal to serial->num_ports indicating it is out-of-bounds. Reported-by: syzbot Closes: https://syzkaller.appspot.com/bug?extid=506479ebf12fe435d01a Fixes: f7a33e608d9a ("USB: serial: add quatech2 usb to serial driver") Cc: # 3.5 Signed-off-by: Qasim Ijaz Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/quatech2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index d172e8642d4a..5501898dfcfb 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -555,7 +555,7 @@ static void qt2_process_read_urb(struct urb *urb) newport = *(ch + 3); - if (newport > serial->num_ports) { + if (newport >= serial->num_ports) { dev_err(&port->dev, "%s - port change to invalid port: %i\n", __func__, newport); From 76e7577bb89b327abdf72d4c0d486074a17f712a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 17 Jan 2025 09:17:12 +0100 Subject: [PATCH 098/138] Revert "usb: gadget: u_serial: Disable ep before setting port to null to fix the crash caused by port being null" commit 086fd062bc3883ae1ce4166cff5355db315ad879 upstream. This reverts commit 13014969cbf07f18d62ceea40bd8ca8ec9d36cec. It is reported to cause crashes on Tegra systems, so revert it for now. Link: https://lore.kernel.org/r/1037c1ad-9230-4181-b9c3-167dbaa47644@nvidia.com Reported-by: Jon Hunter Cc: stable Cc: Lianqin Hu Link: https://lore.kernel.org/r/2025011711-yippee-fever-a737@gregkh Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/u_serial.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index ff13887114da..d432f96ec419 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -1369,10 +1369,6 @@ void gserial_disconnect(struct gserial *gser) /* REVISIT as above: how best to track this? */ port->port_line_coding = gser->port_line_coding; - /* disable endpoints, aborting down any active I/O */ - usb_ep_disable(gser->out); - usb_ep_disable(gser->in); - port->port_usb = NULL; gser->ioport = NULL; if (port->port.count > 0 || port->openclose) { @@ -1382,6 +1378,10 @@ void gserial_disconnect(struct gserial *gser) } spin_unlock_irqrestore(&port->port_lock, flags); + /* disable endpoints, aborting down any active I/O */ + usb_ep_disable(gser->out); + usb_ep_disable(gser->in); + /* finally, free any unused/unusable I/O buffers */ spin_lock_irqsave(&port->port_lock, flags); if (port->port.count == 0 && !port->openclose) From e9ba82343e87211982df74b2fa300584ba36fcb0 Mon Sep 17 00:00:00 2001 From: Mark Pearson Date: Mon, 20 Jan 2025 20:24:08 -0800 Subject: [PATCH 099/138] Input: atkbd - map F23 key to support default copilot shortcut commit 907bc9268a5a9f823ffa751957a5c1dd59f83f42 upstream. Microsoft defined Meta+Shift+F23 as the Copilot shortcut instead of a dedicated keycode, and multiple vendors have their keyboards emit this sequence in response to users pressing a dedicated "Copilot" key. Unfortunately the default keymap table in atkbd does not map scancode 0x6e (F23) and so the key combination does not work even if userspace is ready to handle it. Because this behavior is common between multiple vendors and the scancode is currently unused map 0x6e to keycode 193 (KEY_F23) so that key sequence is generated properly. MS documentation for the scan code: https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input#scan-codes Confirmed on Lenovo, HP and Dell machines by Canonical. Tested on Lenovo T14s G6 AMD. Signed-off-by: Mark Pearson Link: https://lore.kernel.org/r/20250107034554.25843-1-mpearson-lenovo@squebb.ca Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/keyboard/atkbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index cb7f9b46ce65..c22ef6483c40 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -84,7 +84,7 @@ static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = { 0, 46, 45, 32, 18, 5, 4, 95, 0, 57, 47, 33, 20, 19, 6,183, 0, 49, 48, 35, 34, 21, 7,184, 0, 0, 50, 36, 22, 8, 9,185, 0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0, - 0, 89, 40, 0, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 85, + 0, 89, 40, 0, 26, 13, 0,193, 58, 54, 28, 27, 0, 43, 0, 85, 0, 86, 91, 90, 92, 0, 14, 94, 0, 79,124, 75, 71,121, 0, 0, 82, 83, 80, 76, 77, 72, 1, 69, 87, 78, 81, 74, 55, 73, 70, 99, From 20c54dc14d3cbcc698ef1f17d38c35a0db748448 Mon Sep 17 00:00:00 2001 From: Nilton Perim Neto Date: Fri, 17 Jan 2025 09:34:18 -0800 Subject: [PATCH 100/138] Input: xpad - add unofficial Xbox 360 wireless receiver clone commit e4940fe6322c851659c17852b671c6e7b1aa9f56 upstream. Although it mimics the Microsoft's VendorID, it is in fact a clone. Taking into account that the original Microsoft Receiver is not being manufactured anymore, this drive can solve dpad issues encontered by those who still use the original 360 Wireless controller but are using a receiver clone. Signed-off-by: Nilton Perim Neto Signed-off-by: Pavel Rojtberg Link: https://lore.kernel.org/r/20250107192830.414709-12-rojtberg@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/joystick/xpad.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 239471cf7e4c..9ebef004b7e2 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -128,6 +128,7 @@ static const struct xpad_device { { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, { 0x045e, 0x028f, "Microsoft X-Box 360 pad v2", 0, XTYPE_XBOX360 }, { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, + { 0x045e, 0x02a9, "Xbox 360 Wireless Receiver (Unofficial)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE }, { 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE }, { 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", 0, XTYPE_XBOXONE }, From 9e87fc214ed912ac7c967a0cb74b29c3a7a02318 Mon Sep 17 00:00:00 2001 From: Jack Greiner Date: Fri, 17 Jan 2025 16:51:58 -0800 Subject: [PATCH 101/138] Input: xpad - add support for wooting two he (arm) commit 222f3390c15c4452a9f7e26f5b7d9138e75d00d5 upstream. Add Wooting Two HE (ARM) to the list of supported devices. Signed-off-by: Jack Greiner Signed-off-by: Pavel Rojtberg Link: https://lore.kernel.org/r/20250107192830.414709-3-rojtberg@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/joystick/xpad.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 9ebef004b7e2..00b973e0f79f 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -345,6 +345,7 @@ static const struct xpad_device { { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 }, { 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 }, { 0x31e3, 0x1220, "Wooting Two HE", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1230, "Wooting Two HE (ARM)", 0, XTYPE_XBOX360 }, { 0x31e3, 0x1300, "Wooting 60HE (AVR)", 0, XTYPE_XBOX360 }, { 0x31e3, 0x1310, "Wooting 60HE (ARM)", 0, XTYPE_XBOX360 }, { 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 }, From 9793206fbf5293534c3a79d78f196e2cbb48c22d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= Date: Wed, 22 Jan 2025 22:24:03 -0300 Subject: [PATCH 102/138] drm/v3d: Assign job pointer to NULL before signaling the fence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 6e64d6b3a3c39655de56682ec83e894978d23412 upstream. In commit e4b5ccd392b9 ("drm/v3d: Ensure job pointer is set to NULL after job completion"), we introduced a change to assign the job pointer to NULL after completing a job, indicating job completion. However, this approach created a race condition between the DRM scheduler workqueue and the IRQ execution thread. As soon as the fence is signaled in the IRQ execution thread, a new job starts to be executed. This results in a race condition where the IRQ execution thread sets the job pointer to NULL simultaneously as the `run_job()` function assigns a new job to the pointer. This race condition can lead to a NULL pointer dereference if the IRQ execution thread sets the job pointer to NULL after `run_job()` assigns it to the new job. When the new job completes and the GPU emits an interrupt, `v3d_irq()` is triggered, potentially causing a crash. [ 466.310099] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000c0 [ 466.318928] Mem abort info: [ 466.321723] ESR = 0x0000000096000005 [ 466.325479] EC = 0x25: DABT (current EL), IL = 32 bits [ 466.330807] SET = 0, FnV = 0 [ 466.333864] EA = 0, S1PTW = 0 [ 466.337010] FSC = 0x05: level 1 translation fault [ 466.341900] Data abort info: [ 466.344783] ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000 [ 466.350285] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [ 466.355350] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [ 466.360677] user pgtable: 4k pages, 39-bit VAs, pgdp=0000000089772000 [ 466.367140] [00000000000000c0] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000 [ 466.375875] Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP [ 466.382163] Modules linked in: rfcomm snd_seq_dummy snd_hrtimer snd_seq snd_seq_device algif_hash algif_skcipher af_alg bnep binfmt_misc vc4 snd_soc_hdmi_codec drm_display_helper cec brcmfmac_wcc spidev rpivid_hevc(C) drm_client_lib brcmfmac hci_uart drm_dma_helper pisp_be btbcm brcmutil snd_soc_core aes_ce_blk v4l2_mem2mem bluetooth aes_ce_cipher snd_compress videobuf2_dma_contig ghash_ce cfg80211 gf128mul snd_pcm_dmaengine videobuf2_memops ecdh_generic sha2_ce ecc videobuf2_v4l2 snd_pcm v3d sha256_arm64 rfkill videodev snd_timer sha1_ce libaes gpu_sched snd videobuf2_common sha1_generic drm_shmem_helper mc rp1_pio drm_kms_helper raspberrypi_hwmon spi_bcm2835 gpio_keys i2c_brcmstb rp1 raspberrypi_gpiomem rp1_mailbox rp1_adc nvmem_rmem uio_pdrv_genirq uio i2c_dev drm ledtrig_pattern drm_panel_orientation_quirks backlight fuse dm_mod ip_tables x_tables ipv6 [ 466.458429] CPU: 0 UID: 1000 PID: 2008 Comm: chromium Tainted: G C 6.13.0-v8+ #18 [ 466.467336] Tainted: [C]=CRAP [ 466.470306] Hardware name: Raspberry Pi 5 Model B Rev 1.0 (DT) [ 466.476157] pstate: 404000c9 (nZcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 466.483143] pc : v3d_irq+0x118/0x2e0 [v3d] [ 466.487258] lr : __handle_irq_event_percpu+0x60/0x228 [ 466.492327] sp : ffffffc080003ea0 [ 466.495646] x29: ffffffc080003ea0 x28: ffffff80c0c94200 x27: 0000000000000000 [ 466.502807] x26: ffffffd08dd81d7b x25: ffffff80c0c94200 x24: ffffff8003bdc200 [ 466.509969] x23: 0000000000000001 x22: 00000000000000a7 x21: 0000000000000000 [ 466.517130] x20: ffffff8041bb0000 x19: 0000000000000001 x18: 0000000000000000 [ 466.524291] x17: ffffffafadfb0000 x16: ffffffc080000000 x15: 0000000000000000 [ 466.531452] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000 [ 466.538613] x11: 0000000000000000 x10: 0000000000000000 x9 : ffffffd08c527eb0 [ 466.545777] x8 : 0000000000000000 x7 : 0000000000000000 x6 : 0000000000000000 [ 466.552941] x5 : ffffffd08c4100d0 x4 : ffffffafadfb0000 x3 : ffffffc080003f70 [ 466.560102] x2 : ffffffc0829e8058 x1 : 0000000000000001 x0 : 0000000000000000 [ 466.567263] Call trace: [ 466.569711] v3d_irq+0x118/0x2e0 [v3d] (P) [ 466.573826] __handle_irq_event_percpu+0x60/0x228 [ 466.578546] handle_irq_event+0x54/0xb8 [ 466.582391] handle_fasteoi_irq+0xac/0x240 [ 466.586498] generic_handle_domain_irq+0x34/0x58 [ 466.591128] gic_handle_irq+0x48/0xd8 [ 466.594798] call_on_irq_stack+0x24/0x58 [ 466.598730] do_interrupt_handler+0x88/0x98 [ 466.602923] el0_interrupt+0x44/0xc0 [ 466.606508] __el0_irq_handler_common+0x18/0x28 [ 466.611050] el0t_64_irq_handler+0x10/0x20 [ 466.615156] el0t_64_irq+0x198/0x1a0 [ 466.618740] Code: 52800035 3607faf3 f9442e80 52800021 (f9406018) [ 466.624853] ---[ end trace 0000000000000000 ]--- [ 466.629483] Kernel panic - not syncing: Oops: Fatal exception in interrupt [ 466.636384] SMP: stopping secondary CPUs [ 466.640320] Kernel Offset: 0x100c400000 from 0xffffffc080000000 [ 466.646259] PHYS_OFFSET: 0x0 [ 466.649141] CPU features: 0x100,00000170,00901250,0200720b [ 466.654644] Memory Limit: none [ 466.657706] ---[ end Kernel panic - not syncing: Oops: Fatal exception in interrupt ]--- Fix the crash by assigning the job pointer to NULL before signaling the fence. This ensures that the job pointer is cleared before any new job starts execution, preventing the race condition and the NULL pointer dereference crash. Cc: stable@vger.kernel.org Fixes: e4b5ccd392b9 ("drm/v3d: Ensure job pointer is set to NULL after job completion") Signed-off-by: Maíra Canal Reviewed-by: Jose Maria Casanova Crespo Reviewed-by: Iago Toral Quiroga Tested-by: Phil Elwell Link: https://patchwork.freedesktop.org/patch/msgid/20250123012403.20447-1-mcanal@igalia.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/v3d/v3d_irq.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c index aa27b7654dee..41705436a748 100644 --- a/drivers/gpu/drm/v3d/v3d_irq.c +++ b/drivers/gpu/drm/v3d/v3d_irq.c @@ -102,8 +102,10 @@ v3d_irq(int irq, void *arg) to_v3d_fence(v3d->bin_job->base.irq_fence); trace_v3d_bcl_irq(&v3d->drm, fence->seqno); - dma_fence_signal(&fence->base); + v3d->bin_job = NULL; + dma_fence_signal(&fence->base); + status = IRQ_HANDLED; } @@ -112,8 +114,10 @@ v3d_irq(int irq, void *arg) to_v3d_fence(v3d->render_job->base.irq_fence); trace_v3d_rcl_irq(&v3d->drm, fence->seqno); - dma_fence_signal(&fence->base); + v3d->render_job = NULL; + dma_fence_signal(&fence->base); + status = IRQ_HANDLED; } @@ -122,8 +126,10 @@ v3d_irq(int irq, void *arg) to_v3d_fence(v3d->csd_job->base.irq_fence); trace_v3d_csd_irq(&v3d->drm, fence->seqno); - dma_fence_signal(&fence->base); + v3d->csd_job = NULL; + dma_fence_signal(&fence->base); + status = IRQ_HANDLED; } @@ -159,8 +165,10 @@ v3d_hub_irq(int irq, void *arg) to_v3d_fence(v3d->tfu_job->base.irq_fence); trace_v3d_tfu_irq(&v3d->drm, fence->seqno); - dma_fence_signal(&fence->base); + v3d->tfu_job = NULL; + dma_fence_signal(&fence->base); + status = IRQ_HANDLED; } From 1f91ebde6e35db144b952b87cf36bab7fb5426c2 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 28 Mar 2023 15:10:43 +0200 Subject: [PATCH 103/138] xhci: use pm_ptr() instead of #ifdef for CONFIG_PM conditionals commit 130eac4170859fb368681e00d390f20f44bbf27b upstream. A recent patch caused an unused-function warning in builds with CONFIG_PM disabled, after the function became marked 'static': drivers/usb/host/xhci-pci.c:91:13: error: 'xhci_msix_sync_irqs' defined but not used [-Werror=unused-function] 91 | static void xhci_msix_sync_irqs(struct xhci_hcd *xhci) | ^~~~~~~~~~~~~~~~~~~ This could be solved by adding another #ifdef, but as there is a trend towards removing CONFIG_PM checks in favor of helper macros, do the same conversion here and use pm_ptr() to get either a function pointer or NULL but avoid the warning. As the hidden functions reference some other symbols, make sure those are visible at compile time, at the minimal cost of a few extra bytes for 'struct usb_device'. Fixes: 9abe15d55dcc ("xhci: Move xhci MSI sync function to to xhci-pci") Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20230328131114.1296430-1-arnd@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 4 ---- include/linux/usb.h | 3 +-- include/linux/usb/hcd.h | 2 -- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index f35476af78a3..8cda8d24faf6 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -518,7 +518,6 @@ static void xhci_pci_remove(struct pci_dev *dev) usb_hcd_pci_remove(dev); } -#ifdef CONFIG_PM /* * In some Intel xHCI controllers, in order to get D3 working, * through a vendor specific SSIC CONFIG register at offset 0x883c, @@ -659,7 +658,6 @@ static void xhci_pci_shutdown(struct usb_hcd *hcd) if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) pci_set_power_state(pdev, PCI_D3hot); } -#endif /* CONFIG_PM */ /*-------------------------------------------------------------------------*/ @@ -693,11 +691,9 @@ static struct pci_driver xhci_pci_driver = { static int __init xhci_pci_init(void) { xhci_init_driver(&xhci_pci_hc_driver, &xhci_pci_overrides); -#ifdef CONFIG_PM xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend; xhci_pci_hc_driver.pci_resume = xhci_pci_resume; xhci_pci_hc_driver.shutdown = xhci_pci_shutdown; -#endif return pci_register_driver(&xhci_pci_driver); } module_init(xhci_pci_init); diff --git a/include/linux/usb.h b/include/linux/usb.h index 7c0e7efbc8f2..ffc16257899f 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -699,13 +699,12 @@ struct usb_device { unsigned long active_duration; -#ifdef CONFIG_PM unsigned long connect_time; unsigned do_remote_wakeup:1; unsigned reset_resume:1; unsigned port_is_suspended:1; -#endif + struct wusb_dev *wusb_dev; int slot_id; enum usb_device_removable removable; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 0cfd540e7d06..a57e023755aa 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -488,9 +488,7 @@ extern void usb_hcd_pci_shutdown(struct pci_dev *dev); extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev); -#ifdef CONFIG_PM extern const struct dev_pm_ops usb_hcd_pci_pm_ops; -#endif #endif /* CONFIG_USB_PCI */ /* pci-ish (pdev null is ok) buffer alloc/mapping support */ From 4b7032d01ea1fd7bae1f5ce008aaf25f4857d07f Mon Sep 17 00:00:00 2001 From: Ron Economos Date: Sat, 18 Jan 2025 04:24:09 -0800 Subject: [PATCH 104/138] Partial revert of xhci: use pm_ptr() instead #ifdef for CONFIG_PM conditionals commit 448fe5a1a4b538b235a43e57863c3a078bd13b01 upstream. commit 9734fd7a2777 ("xhci: use pm_ptr() instead of #ifdef for CONFIG_PM conditionals") did not quite work properly in the 5.15.y branch where it was applied to fix a build error when CONFIG_PM was set as it left the following build errors still present: ERROR: modpost: "xhci_suspend" [drivers/usb/host/xhci-pci.ko] undefined! ERROR: modpost: "xhci_resume" [drivers/usb/host/xhci-pci.ko] undefined! Fix this up by properly placing the #ifdef CONFIG_PM in the xhci-pci.c and hcd.h files to handle this correctly. Link: https://lore.kernel.org/r/133dbfa0-4a37-4ae0-bb95-1a35f668ec11@w6rz.net Signed-off-by: Ron Economos Link: https://lore.kernel.org/r/d0919169-ee06-4bdd-b2e3-2f776db90971@roeck-us.net Reported-by: Guenter Roeck [ Trimmed the partial revert down to an even smaller bit to only be what is required to fix the build error - gregkh] Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 8cda8d24faf6..f35476af78a3 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -518,6 +518,7 @@ static void xhci_pci_remove(struct pci_dev *dev) usb_hcd_pci_remove(dev); } +#ifdef CONFIG_PM /* * In some Intel xHCI controllers, in order to get D3 working, * through a vendor specific SSIC CONFIG register at offset 0x883c, @@ -658,6 +659,7 @@ static void xhci_pci_shutdown(struct usb_hcd *hcd) if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) pci_set_power_state(pdev, PCI_D3hot); } +#endif /* CONFIG_PM */ /*-------------------------------------------------------------------------*/ @@ -691,9 +693,11 @@ static struct pci_driver xhci_pci_driver = { static int __init xhci_pci_init(void) { xhci_init_driver(&xhci_pci_hc_driver, &xhci_pci_overrides); +#ifdef CONFIG_PM xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend; xhci_pci_hc_driver.pci_resume = xhci_pci_resume; xhci_pci_hc_driver.shutdown = xhci_pci_shutdown; +#endif return pci_register_driver(&xhci_pci_driver); } module_init(xhci_pci_init); From 856a224845f949243d6719165c88a70e4b473ec4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 Feb 2025 18:18:54 +0100 Subject: [PATCH 105/138] Linux 5.4.290 Link: https://lore.kernel.org/r/20250130140133.662535583@linuxfoundation.org Tested-by: Florian Fainelli Tested-by: Jon Hunter Link: https://lore.kernel.org/r/20250131112114.030356568@linuxfoundation.org Tested-by: Jon Hunter Tested-by: kernelci.org bot Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e983a36fa88b..dc7f459fc670 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 4 -SUBLEVEL = 289 +SUBLEVEL = 290 EXTRAVERSION = NAME = Kleptomaniac Octopus From bd90eaaa4b2000feff23eb22685893c1876bc33b Mon Sep 17 00:00:00 2001 From: Jayasri Sampath Kumaran Date: Wed, 28 Aug 2024 15:46:09 -0400 Subject: [PATCH 106/138] disp: msm: sde: fix kms NULL pointer access in encoder IRQ control A possible kms NULL pointer access is found during CPU vote for IRQ when kms isn't NULL checked before accessing structure members. So, perform kms NULL check before accessing members. Change-Id: I137759ea0723be8580e9166c983d1ba38f4eb281 Signed-off-by: Jayasri Sampath Kumaran --- msm/sde/sde_encoder.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 9c103530d916..3bdee2440572 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -1434,6 +1434,7 @@ static int _sde_encoder_update_rsc_client( void sde_encoder_irq_control(struct drm_encoder *drm_enc, bool enable) { struct sde_encoder_virt *sde_enc; + struct sde_kms *sde_kms = NULL; int i; if (!drm_enc) { @@ -1441,6 +1442,12 @@ void sde_encoder_irq_control(struct drm_encoder *drm_enc, bool enable) return; } + sde_kms = sde_encoder_get_kms(drm_enc); + if (!sde_kms) { + SDE_ERROR("invalid kms\n"); + return; + } + sde_enc = to_sde_encoder_virt(drm_enc); SDE_DEBUG_ENC(sde_enc, "enable:%d\n", enable); @@ -1450,7 +1457,7 @@ void sde_encoder_irq_control(struct drm_encoder *drm_enc, bool enable) if (phys && phys->ops.irq_control) phys->ops.irq_control(phys, enable); } - sde_kms_cpu_vote_for_irq(sde_encoder_get_kms(drm_enc), enable); + sde_kms_cpu_vote_for_irq(sde_kms, enable); } From 67d6b1a6cd97e5ef07d4c5162379acf572aa2df8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 Feb 2025 18:22:44 +0000 Subject: [PATCH 107/138] Revert "gtp: Destroy device along with udp socket's netns dismantle." This reverts commit c986380c1d5274c4d5e935addc807d6791cc23eb which is commit eb28fd76c0a08a47b470677c6cef9dd1c60e92d1 upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: Icb16f395345b5eb6bd40cb8f50780af8c8ffcf09 Signed-off-by: Greg Kroah-Hartman --- drivers/net/gtp.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index 68698457add0..e08cd4b1be6c 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -690,7 +690,7 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev, goto out_encap; } - gn = net_generic(src_net, gtp_net_id); + gn = net_generic(dev_net(dev), gtp_net_id); list_add(>p->list, &gn->gtp_dev_list); dev->priv_destructor = gtp_destructor; @@ -1366,11 +1366,6 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list, list_for_each_entry(net, net_list, exit_list) { struct gtp_net *gn = net_generic(net, gtp_net_id); struct gtp_dev *gtp, *gtp_next; - struct net_device *dev; - - for_each_netdev(net, dev) - if (dev->rtnl_link_ops == >p_link_ops) - gtp_dellink(dev, dev_to_kill); list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list) gtp_dellink(gtp->dev, dev_to_kill); From c4395bd9f7c56848eb97d0675c2be4a9579259ef Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 Feb 2025 18:22:50 +0000 Subject: [PATCH 108/138] Revert "gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp()." This reverts commit 574c3f3f8e5e4cad8ae92f46df4214c153866dd2 which is commit 46841c7053e6d25fb33e0534ef023833bf03e382 upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: Ic4e353bd2ab45d5d9f45558e031d219d1cbba39e Signed-off-by: Greg Kroah-Hartman --- drivers/net/gtp.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index e08cd4b1be6c..fd5d3f58b5c1 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -691,7 +691,7 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev, } gn = net_generic(dev_net(dev), gtp_net_id); - list_add(>p->list, &gn->gtp_dev_list); + list_add_rcu(>p->list, &gn->gtp_dev_list); dev->priv_destructor = gtp_destructor; netdev_dbg(dev, "registered new GTP interface\n"); @@ -717,7 +717,7 @@ static void gtp_dellink(struct net_device *dev, struct list_head *head) hlist_for_each_entry_safe(pctx, next, >p->tid_hash[i], hlist_tid) pdp_context_delete(pctx); - list_del(>p->list); + list_del_rcu(>p->list); unregister_netdevice_queue(dev, head); } @@ -1259,19 +1259,16 @@ static int gtp_genl_dump_pdp(struct sk_buff *skb, struct gtp_dev *last_gtp = (struct gtp_dev *)cb->args[2], *gtp; int i, j, bucket = cb->args[0], skip = cb->args[1]; struct net *net = sock_net(skb->sk); - struct net_device *dev; struct pdp_ctx *pctx; + struct gtp_net *gn; + + gn = net_generic(net, gtp_net_id); if (cb->args[4]) return 0; rcu_read_lock(); - for_each_netdev_rcu(net, dev) { - if (dev->rtnl_link_ops != >p_link_ops) - continue; - - gtp = netdev_priv(dev); - + list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) { if (last_gtp && last_gtp != gtp) continue; else @@ -1365,9 +1362,9 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list, list_for_each_entry(net, net_list, exit_list) { struct gtp_net *gn = net_generic(net, gtp_net_id); - struct gtp_dev *gtp, *gtp_next; + struct gtp_dev *gtp; - list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list) + list_for_each_entry(gtp, &gn->gtp_dev_list, list) gtp_dellink(gtp->dev, dev_to_kill); } } From 9a42fba6f871c39bcf3c2043e27be4ee1dd9c5a9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 Feb 2025 18:23:05 +0000 Subject: [PATCH 109/138] Revert "gtp: use exit_batch_rtnl() method" This reverts commit 85d9663360988a434a46af25516c718308c471ba which is commit 6eedda01b2bfdcf427b37759e053dc27232f3af1 upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: Idcdef934cbbe6566d020c84086f33964fb30e1e9 Signed-off-by: Greg Kroah-Hartman --- drivers/net/gtp.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index fd5d3f58b5c1..f85f4e3d2821 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -1355,23 +1355,23 @@ static int __net_init gtp_net_init(struct net *net) return 0; } -static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list, - struct list_head *dev_to_kill) +static void __net_exit gtp_net_exit(struct net *net) { - struct net *net; + struct gtp_net *gn = net_generic(net, gtp_net_id); + struct gtp_dev *gtp; + LIST_HEAD(list); - list_for_each_entry(net, net_list, exit_list) { - struct gtp_net *gn = net_generic(net, gtp_net_id); - struct gtp_dev *gtp; + rtnl_lock(); + list_for_each_entry(gtp, &gn->gtp_dev_list, list) + gtp_dellink(gtp->dev, &list); - list_for_each_entry(gtp, &gn->gtp_dev_list, list) - gtp_dellink(gtp->dev, dev_to_kill); - } + unregister_netdevice_many(&list); + rtnl_unlock(); } static struct pernet_operations gtp_net_ops = { .init = gtp_net_init, - .exit_batch_rtnl = gtp_net_exit_batch_rtnl, + .exit = gtp_net_exit, .id = >p_net_id, .size = sizeof(struct gtp_net), }; From d85e176a2a81799c58a44faee5b34e103daea749 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 Feb 2025 18:23:20 +0000 Subject: [PATCH 110/138] Revert "net: add exit_batch_rtnl() method" This reverts commit 2131315571026a91ecda9a690f68bf1de0f51ccd which is commit fd4f101edbd9f99567ab2adb1f2169579ede7c13 upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: I164d68cc594a2e25999bdf1c1346b3792766a9c0 Signed-off-by: Greg Kroah-Hartman --- include/net/net_namespace.h | 3 --- net/core/net_namespace.c | 31 +------------------------------ 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 0d61b452b908..167e390ac9d4 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -382,9 +382,6 @@ struct pernet_operations { void (*pre_exit)(struct net *net); void (*exit)(struct net *net); void (*exit_batch)(struct list_head *net_exit_list); - /* Following method is called with RTNL held. */ - void (*exit_batch_rtnl)(struct list_head *net_exit_list, - struct list_head *dev_kill_list); unsigned int *id; size_t size; }; diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index e6585a758edd..c4bcedc06822 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -325,9 +325,8 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns) { /* Must be called with pernet_ops_rwsem held */ const struct pernet_operations *ops, *saved_ops; - LIST_HEAD(net_exit_list); - LIST_HEAD(dev_kill_list); int error = 0; + LIST_HEAD(net_exit_list); refcount_set(&net->count, 1); refcount_set(&net->passive, 1); @@ -360,15 +359,6 @@ out_undo: synchronize_rcu(); - ops = saved_ops; - rtnl_lock(); - list_for_each_entry_continue_reverse(ops, &pernet_list, list) { - if (ops->exit_batch_rtnl) - ops->exit_batch_rtnl(&net_exit_list, &dev_kill_list); - } - unregister_netdevice_many(&dev_kill_list); - rtnl_unlock(); - ops = saved_ops; list_for_each_entry_continue_reverse(ops, &pernet_list, list) ops_exit_list(ops, &net_exit_list); @@ -573,7 +563,6 @@ static void cleanup_net(struct work_struct *work) struct net *net, *tmp, *last; struct llist_node *net_kill_list; LIST_HEAD(net_exit_list); - LIST_HEAD(dev_kill_list); /* Atomically snapshot the list of namespaces to cleanup */ net_kill_list = llist_del_all(&cleanup_list); @@ -614,14 +603,6 @@ static void cleanup_net(struct work_struct *work) */ synchronize_rcu(); - rtnl_lock(); - list_for_each_entry_reverse(ops, &pernet_list, list) { - if (ops->exit_batch_rtnl) - ops->exit_batch_rtnl(&net_exit_list, &dev_kill_list); - } - unregister_netdevice_many(&dev_kill_list); - rtnl_unlock(); - /* Run all of the network namespace exit methods */ list_for_each_entry_reverse(ops, &pernet_list, list) ops_exit_list(ops, &net_exit_list); @@ -1169,17 +1150,7 @@ static void free_exit_list(struct pernet_operations *ops, struct list_head *net_ { ops_pre_exit_list(ops, net_exit_list); synchronize_rcu(); - - if (ops->exit_batch_rtnl) { - LIST_HEAD(dev_kill_list); - - rtnl_lock(); - ops->exit_batch_rtnl(net_exit_list, &dev_kill_list); - unregister_netdevice_many(&dev_kill_list); - rtnl_unlock(); - } ops_exit_list(ops, net_exit_list); - ops_free_list(ops, net_exit_list); } From aa7664d1acccf3bf09848cf18f1329e93658e4a6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 Feb 2025 18:23:32 +0000 Subject: [PATCH 111/138] Revert "net: net_namespace: Optimize the code" This reverts commit 378b81b092351ffa99284a807615d9d8f4b83df7 which is commit 41467d2ff4dfe1837cbb0f45e2088e6e787580c6 upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: Ie2e2cbdc5f27ee7f02a9f620106a26d6e7155eec Signed-off-by: Greg Kroah-Hartman --- net/core/net_namespace.c | 52 +++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index c4bcedc06822..c94179d30d42 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -98,7 +98,7 @@ static int net_assign_generic(struct net *net, unsigned int id, void *data) } ng = net_alloc_generic(); - if (!ng) + if (ng == NULL) return -ENOMEM; /* @@ -155,6 +155,13 @@ out: return err; } +static void ops_free(const struct pernet_operations *ops, struct net *net) +{ + if (ops->id && ops->size) { + kfree(net_generic(net, *ops->id)); + } +} + static void ops_pre_exit_list(const struct pernet_operations *ops, struct list_head *net_exit_list) { @@ -186,7 +193,7 @@ static void ops_free_list(const struct pernet_operations *ops, struct net *net; if (ops->size && ops->id) { list_for_each_entry(net, net_exit_list, exit_list) - kfree(net_generic(net, *ops->id)); + ops_free(ops, net); } } @@ -441,18 +448,15 @@ out_free: static void net_free(struct net *net) { - if (refcount_dec_and_test(&net->passive)) { - kfree(rcu_access_pointer(net->gen)); - kmem_cache_free(net_cachep, net); - } + kfree(rcu_access_pointer(net->gen)); + kmem_cache_free(net_cachep, net); } void net_drop_ns(void *p) { - struct net *net = (struct net *)p; - - if (net) - net_free(net); + struct net *ns = p; + if (ns && refcount_dec_and_test(&ns->passive)) + net_free(ns); } struct net *copy_net_ns(unsigned long flags, @@ -492,7 +496,7 @@ put_userns: key_remove_domain(net->key_domain); #endif put_user_ns(user_ns); - net_free(net); + net_drop_ns(net); dec_ucounts: dec_net_namespaces(ucounts); return ERR_PTR(rv); @@ -626,7 +630,7 @@ static void cleanup_net(struct work_struct *work) key_remove_domain(net->key_domain); #endif put_user_ns(net->user_ns); - net_free(net); + net_drop_ns(net); } } @@ -1146,14 +1150,6 @@ static int __init net_ns_init(void) pure_initcall(net_ns_init); -static void free_exit_list(struct pernet_operations *ops, struct list_head *net_exit_list) -{ - ops_pre_exit_list(ops, net_exit_list); - synchronize_rcu(); - ops_exit_list(ops, net_exit_list); - ops_free_list(ops, net_exit_list); -} - #ifdef CONFIG_NET_NS static int __register_pernet_operations(struct list_head *list, struct pernet_operations *ops) @@ -1179,7 +1175,10 @@ static int __register_pernet_operations(struct list_head *list, out_undo: /* If I have an error cleanup all namespaces I initialized */ list_del(&ops->list); - free_exit_list(ops, &net_exit_list); + ops_pre_exit_list(ops, &net_exit_list); + synchronize_rcu(); + ops_exit_list(ops, &net_exit_list); + ops_free_list(ops, &net_exit_list); return error; } @@ -1192,8 +1191,10 @@ static void __unregister_pernet_operations(struct pernet_operations *ops) /* See comment in __register_pernet_operations() */ for_each_net(net) list_add_tail(&net->exit_list, &net_exit_list); - - free_exit_list(ops, &net_exit_list); + ops_pre_exit_list(ops, &net_exit_list); + synchronize_rcu(); + ops_exit_list(ops, &net_exit_list); + ops_free_list(ops, &net_exit_list); } #else @@ -1216,7 +1217,10 @@ static void __unregister_pernet_operations(struct pernet_operations *ops) } else { LIST_HEAD(net_exit_list); list_add(&init_net.exit_list, &net_exit_list); - free_exit_list(ops, &net_exit_list); + ops_pre_exit_list(ops, &net_exit_list); + synchronize_rcu(); + ops_exit_list(ops, &net_exit_list); + ops_free_list(ops, &net_exit_list); } } From 4255f08ff54b31f60f8bb0b3e65f17ed3116adf2 Mon Sep 17 00:00:00 2001 From: spuligil Date: Wed, 5 Feb 2025 01:43:05 -0800 Subject: [PATCH 112/138] fw-api: CL 28524940 - update fw common interface files Change-Id: Ic3cc32f729c4e20f22126bf7fd6fedced6dd6ebe CRs-Fixed: 3830439 --- fw/htt.h | 4 ++ fw/htt_stats.h | 132 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 135 insertions(+), 1 deletion(-) diff --git a/fw/htt.h b/fw/htt.h index 3b0c0b8ef951..e9d34066ff72 100644 --- a/fw/htt.h +++ b/fw/htt.h @@ -840,6 +840,10 @@ typedef enum { HTT_STATS_PDEV_RTT_DELAY_TAG = 205, /* htt_stats_pdev_rtt_delay_tlv */ HTT_STATS_PDEV_AOA_TAG = 206, /* htt_stats_pdev_aoa_tlv */ HTT_STATS_PDEV_FTM_TPCCAL_TAG = 207, /* htt_stats_pdev_ftm_tpccal_tlv */ + HTT_STATS_PDEV_UL_MUMIMO_GRP_STATS_TAG = 208, /* htt_stats_pdev_ulmumimo_grp_stats_tlv */ + HTT_STATS_PDEV_UL_MUMIMO_DENYLIST_STATS_TAG = 209, /* htt_stats_pdev_ulmumimo_denylist_stats_tlv */ + HTT_STATS_PDEV_UL_MUMIMO_SEQ_TERM_STATS_TAG = 210, /* htt_stats_pdev_ulmumimo_seq_term_stats_tlv */ + HTT_STATS_PDEV_UL_MUMIMO_HIST_INELIGIBILITY_TAG = 211, /* htt_stats_pdev_ulmumimo_hist_ineligibility_tlv */ HTT_STATS_MAX_TAG, } htt_stats_tlv_tag_t; diff --git a/fw/htt_stats.h b/fw/htt_stats.h index c0eccd71a494..f3dc39b8dce8 100644 --- a/fw/htt_stats.h +++ b/fw/htt_stats.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -818,6 +818,17 @@ enum htt_dbg_ext_stats_type { */ HTT_DBG_EXT_STATS_PDEV_FTM_TPCCAL = 73, + /** HTT_DBG_EXT_STATS_PDEV_UL_MUMIMO_ELIGIBLE + * PARAMS: + * - No Params + * RESP MSG: + * - htt_stats_pdev_ul_mumimo_grp_stats_tlv + * - htt_stats_pdev_ul_mumimo_denylist_stats_tlv + * - htt_stats_pdev_ul_mumimo_seq_term_stats_tlv + * - htt_stats_pdev_ul_mumimo_hist_ineligibility_tlv + */ + HTT_DBG_EXT_STATS_PDEV_UL_MUMIMO_ELIGIBLE = 74, + /* keep this last */ HTT_DBG_NUM_EXT_STATS = 256, @@ -2858,6 +2869,11 @@ typedef enum { HTT_TX_MUMIMO_GRP_INVALID_GROUP_INELIGIBLE, HTT_TX_MUMIMO_GRP_INVALID, HTT_TX_MUMIMO_GRP_INVALID_GROUP_EFF_MU_TPUT_OMBPS, + HTT_TX_MUMIMO_GRP_INVALID_GRP, + HTT_TX_MUMIMO_GRP_INVALID_TOTAL_NSS_LESS_THAN_GROUP_SIZE, + HTT_TX_MUMIMO_GRP_INSUFFICIENT_CANDIDATES_UL_MU_1SS_RATE, + HTT_TX_MUMIMO_GRP_MU_GRP_NOT_NEEDED, + HTT_TX_MUMIMO_GRP_INVALID_MAX_REASON_CODE, } htt_tx_mumimo_grp_invalid_reason_code_stats; @@ -7561,6 +7577,15 @@ typedef struct { A_UINT32 cv_corr_upload_total_num_users[HTT_TX_CV_CORR_MAX_NUM_COLUMNS]; /** number of streams present in uploaded CV Correlation results buffer */ A_UINT32 cv_corr_upload_total_num_streams[HTT_TX_CV_CORR_MAX_NUM_COLUMNS]; + + /** Total number of times lookahead sounding done for DL MU */ + A_UINT32 lookahead_sounding_dl_cnt; + /** Total number of times lookahead sounding done for DL MU based on number of users */ + A_UINT32 lookahead_snd_dl_num_users[HTT_TX_PDEV_STATS_NUM_BE_MUMIMO_USER_STATS]; + /** Total number of times lookahead sounding done for UL MU */ + A_UINT32 lookahead_sounding_ul_cnt; + /** Total number of times lookahead sounding done for UL MU based on number of users */ + A_UINT32 lookahead_snd_ul_num_users[HTT_TX_PDEV_STATS_NUM_UL_MUMIMO_USER_STATS]; } htt_stats_tx_sounding_stats_tlv; /* preserve old name alias for new name consistent with the tag name */ typedef htt_stats_tx_sounding_stats_tlv htt_tx_sounding_stats_tlv; @@ -9063,6 +9088,111 @@ typedef struct { A_INT32 phase_in_degree[HTT_STATS_PDEV_AOA_MAX_HISTOGRAM][HTT_STATS_PDEV_AOA_MAX_CHAINS]; } htt_stats_pdev_aoa_tlv; +/* STATS_TYPE: HTT_DBG_EXT_STATS_PDEV_ULMUMIMO_ELIGIBLE + * TLV_TAGS: + * HTT_STATS_PDEV_UL_MUMIMO_GRP_STATS_TAG + * HTT_STATS_PDEV_UL_MUMIMO_DENYLIST_STATS_TAG + * HTT_STATS_PDEV_UL_MUMIMO_SEQ_TERM_STATS_TAG + * HTT_STATS_PDEV_UL_MUMIMO_HIST_INELIGIBILITY_TAG + */ + +typedef enum { + HTT_STATS_CANDIDATE_MU_NOT_COMPATIBLE = 1, + HTT_STATS_CANDIDATE_SKIP_NR_INDEX, + HTT_STATS_CANDIDATE_SKIP_BASIC_CHECKS_INELIGIBLE, + HTT_STATS_CANDIDATE_SKIP_ZERO_NSS, + HTT_STATS_CANDIDATE_SKIP_MCS_THRESHOLD_LIMIT, + HTT_STATS_CANDIDATE_SKIP_POWER_IMBALANCED, + HTT_STATS_CANDIDATE_SKIP_NULL_MU_RC, + HTT_STATS_CANDIDATE_SKIP_CV_CORR_SKIP_PEER, + HTT_STATS_CANDIDATE_SKIP_SEND_BAR_SET_FOR_AC_MUMIMO, + + HTT_STATS_CANDIDATE_SKIP_REASON_MAX +} htt_stats_candidate_sched_compatible_code; + +typedef struct { + htt_tlv_hdr_t tlv_hdr; + /* Current Pdev id */ + A_UINT32 pdev_id; + /* Group eligibility count */ + A_UINT32 mu_grp_eligible[HTT_STATS_MAX_MUMIMO_GRP_SZ]; + /* Group ineligibility */ + A_UINT32 mu_grp_ineligible[HTT_STATS_MAX_MUMIMO_GRP_SZ]; + /* Group Invalid reason */ + A_UINT32 mu_grp_invalid[HTT_TX_NUM_MUMIMO_GRP_INVALID_WORDS]; + /* mu_grp_candidate_skip: + * Sched_compatibility reason codes as listed by + * htt_stats_candidate_sched_compatible code + */ + A_UINT32 mu_grp_candidate_skip + [HTT_TX_PDEV_STATS_NUM_UL_MUMIMO_USER_STATS] + [HTT_STATS_CANDIDATE_SKIP_REASON_MAX]; + /* Group eligibility count for 1SS grouping */ + A_UINT32 mu_grp_eligible_1ss[HTT_STATS_MAX_MUMIMO_GRP_SZ]; + /* Group ineligibility fpr 1SS grouping */ + A_UINT32 mu_grp_ineligible_1ss[HTT_STATS_MAX_MUMIMO_GRP_SZ]; + /* Group Invalid reason for 1SS grouping */ + A_UINT32 mu_grp_invalid_1ss[HTT_TX_NUM_MUMIMO_GRP_INVALID_WORDS]; + /* Sched_compatibility reason code for 1SS grouping */ + A_UINT32 mu_grp_candidate_skip_1ss + [HTT_TX_PDEV_STATS_NUM_UL_MUMIMO_USER_STATS] + [HTT_STATS_CANDIDATE_SKIP_REASON_MAX]; +} htt_stats_pdev_ulmumimo_grp_stats_tlv; + +typedef struct { + htt_tlv_hdr_t tlv_hdr; + + /* Num of times peer denylisted for MU-MIMO transmission */ + A_UINT32 num_peer_denylist_cnt; + /* Num of times peer denylisted due to trigger bitmap failure */ + A_UINT32 trig_bitmap_fail_cnt; + /* Num of times peer denylisted due to trigger consecutive failure */ + A_UINT32 trig_consecutive_fail_cnt; +} htt_stats_pdev_ulmumimo_denylist_stats_tlv; + +#define HTT_STATS_SEQ_EFFICIENCY_HISTOGRAM 10 +typedef struct { + htt_tlv_hdr_t tlv_hdr; + + /* Num of times seq terminated for MU-MIMO transmission */ + A_UINT32 num_terminate_seq; + /* Num of sequences terminated due to low qdepth */ + A_UINT32 num_terminate_low_qdepth; + /* Number of sequences terminated due to sequence inefficient */ + A_UINT32 num_terminate_seq_inefficient; + /* Histogram of sequence inefficiency */ + A_UINT32 hist_seq_efficiency[HTT_STATS_SEQ_EFFICIENCY_HISTOGRAM]; +} htt_stats_pdev_ulmumimo_seq_term_stats_tlv; + +#define HTT_STATS_MAX_ULMUMIMO_TRIGGERS 6 +#define HTT_STATS_TXOP_HISTOGRAM_BINS 24 +#define HTT_STATS_ULMUMIMO_DUR_INTERVAL_US 500 +#define HTT_STATS_ULMUMIMO_MIN_PPDU_DUR_US 1000 +#define HTT_STATS_MAX_PPDU_DURATION_BINS 10 +typedef struct { + htt_tlv_hdr_t tlv_hdr; + + /* Number of ULMUMIMO triggers */ + A_UINT32 num_triggers[HTT_STATS_MAX_ULMUMIMO_TRIGGERS]; + /* Txop duration history from 0 to 12 ms with interval of 500us */ + A_UINT32 txop_history [HTT_STATS_TXOP_HISTOGRAM_BINS]; + /* ppdu_duration_hist: + * PPDU Duration History (histogram) + * Num PPDUs from 1 to 6 + * 0 to 6 ms with interval of 500us + */ + A_UINT32 ppdu_duration_hist + [HTT_STATS_MAX_ULMUMIMO_TRIGGERS][HTT_STATS_MAX_PPDU_DURATION_BINS]; + /* Ineligible Count for ULMUMIMO based on avg qdepth and txtime criteria */ + A_UINT32 ineligible_count; + /* history_ineligibility: + * History based ineligibility counter for ULMUMIMO. + * Checks for 8 eligible instances of ULMUMIMO in the past 32 instances. + */ + A_UINT32 history_ineligibility; +} htt_stats_pdev_ulmumimo_hist_ineligibility_tlv; + + /* RTT VREG MASK */ #define HTT_STATS_RTT_CHAN_CAPTURE_MASK 0x00000001 #define HTT_STATS_RTT_HW_FAC_MASK 0x00000002 From 067af3a8927b50da26d8be8556bb1e4714b34562 Mon Sep 17 00:00:00 2001 From: spuligil Date: Thu, 6 Feb 2025 06:01:24 -0800 Subject: [PATCH 113/138] fw-api: CL 28539558 - update fw common interface files Change-Id: I599abc46aeb9618fd7497c9b9f1adcec0c60d314 CRs-Fixed: 3830439 --- fw/htt_ppdu_stats.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fw/htt_ppdu_stats.h b/fw/htt_ppdu_stats.h index 1fd2698551cd..d1575d7c91ba 100644 --- a/fw/htt_ppdu_stats.h +++ b/fw/htt_ppdu_stats.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -922,6 +922,8 @@ typedef struct { * part of existing DL/UL data sequence */ A_UINT32 is_combined_ul_bsrp_trigger; + /* Flag to indicate if the channel chosen is 320_1 / 320_2 */ + A_UINT32 chan_type_320mhz; } htt_ppdu_stats_common_tlv; #define HTT_PPDU_STATS_USER_COMMON_TLV_TID_NUM_M 0x000000ff From af43eef0ea7ae83727cc0e92c424d80b26d5e7c2 Mon Sep 17 00:00:00 2001 From: spuligil Date: Wed, 5 Feb 2025 01:44:51 -0800 Subject: [PATCH 114/138] fw-api: CL 28532052 - update fw common interface files Change-Id: I735df6c87afdcc6989f317f2d7b0d53c08a19608 CRs-Fixed: 3830439 --- fw/wmi_unified.h | 9 +++++++++ fw/wmi_version.h | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/fw/wmi_unified.h b/fw/wmi_unified.h index ad2badd010cd..f6c9050c4c98 100644 --- a/fw/wmi_unified.h +++ b/fw/wmi_unified.h @@ -21404,6 +21404,15 @@ typedef struct { #define WMI_PEER_PARAM_UL_OFDMA_RTD 0x2B +/* + * Send unsolicited probe response to a connected STA. + * 0: Send immediately and stop. + * XX: Send every XX ms continuously. + * 0xFFFFFFFF: Stop sending immediately. + */ +#define WMI_PEER_PARAM_UNSOL_PROBE_RESP_INTVL 0x2C + + typedef struct { A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param */ /** unique id identifying the VDEV, generated by the caller */ diff --git a/fw/wmi_version.h b/fw/wmi_version.h index 796f76d3dd21..7dedd1b1a9cd 100644 --- a/fw/wmi_version.h +++ b/fw/wmi_version.h @@ -37,7 +37,7 @@ #define __WMI_VER_MINOR_ 0 /** WMI revision number has to be incremented when there is a * change that may or may not break compatibility. */ -#define __WMI_REVISION_ 1571 +#define __WMI_REVISION_ 1572 /** The Version Namespace should not be normally changed. Only * host and firmware of the same WMI namespace will work From b5649d57b9823cb43d5d02f6fa9899e196c41e0a Mon Sep 17 00:00:00 2001 From: spuligil Date: Wed, 5 Feb 2025 01:46:26 -0800 Subject: [PATCH 115/138] fw-api: CL 28534399 - update fw common interface files Change-Id: I8c103cafd1d1e4b2afac79190ce3058f8b51f0ca CRs-Fixed: 3830439 --- fw/wmi_tlv_defs.h | 6 ++++-- fw/wmi_unified.h | 24 ++++++++++++++++++++++++ fw/wmi_version.h | 2 +- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/fw/wmi_tlv_defs.h b/fw/wmi_tlv_defs.h index 96f7d8385f12..e8c306dbcb7f 100644 --- a/fw/wmi_tlv_defs.h +++ b/fw/wmi_tlv_defs.h @@ -5484,7 +5484,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_MULTIPLE_PEER_GROUP_CMDID); /* RTT 11az PASN authentication status cmd */ #define WMITLV_TABLE_WMI_RTT_PASN_AUTH_STATUS_CMD(id,op,buf,len) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_rtt_pasn_auth_status_cmd_fixed_param, wmi_rtt_pasn_auth_status_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_rtt_pasn_auth_status_param, pasn_auth_status_param, WMITLV_SIZE_VAR) + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_rtt_pasn_auth_status_param, pasn_auth_status_param, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, cookie, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_RTT_PASN_AUTH_STATUS_CMD); /* RTT 11az PASN deauthentication cmd */ @@ -7635,7 +7636,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_PKTLOG_DECODE_INFO_EVENTID); #define WMITLV_TABLE_WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID(id,op,buf,len) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_rtt_pasn_peer_create_req_event_fixed_param, \ wmi_rtt_pasn_peer_create_req_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_rtt_pasn_peer_create_req_param, rtt_pasn_peer_param, WMITLV_SIZE_VAR) + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_rtt_pasn_peer_create_req_param, rtt_pasn_peer_param, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, cookie, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_RTT_PASN_PEER_CREATE_REQ_EVENTID); /* RTT 11az PASN peer delete event */ diff --git a/fw/wmi_unified.h b/fw/wmi_unified.h index f6c9050c4c98..7fda522028f9 100644 --- a/fw/wmi_unified.h +++ b/fw/wmi_unified.h @@ -22705,6 +22705,7 @@ enum { WMI_AUTH_RSNA_8021X_SHA384, WMI_AUTH_WPA3_SAE_SHA384, WMI_AUTH_FT_RSNA_SAE_SHA384, + WMI_AUTH_FT_RSNA_PSK_SHA384, }; typedef enum { @@ -47990,6 +47991,7 @@ typedef struct { #define WMI_RTT_PASN_PEER_CREATE_SECURITY_MODE_SET(flag,val) WMI_SET_BITS(flag, 0, 2, val) #define WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_GET(flag) WMI_GET_BITS(flag, 2, 1) #define WMI_RTT_PASN_PEER_CREATE_FORCE_SELF_MAC_USE_SET(flag,val) WMI_SET_BITS(flag, 2, 1, val) +#define WMI_MAX_PASN_PASSPHRASE_LEN 64 typedef struct { A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_rtt_pasn_peer_create_req_event_fixed_param */ @@ -47999,6 +48001,7 @@ typedef struct { * The following TLV will follow this fixed_param TLV: * * wmi_rtt_pasn_peer_create_req_param rtt_pasn_peer_param[] + * A_UINT8 cookie[] */ } wmi_rtt_pasn_peer_create_req_event_fixed_param; @@ -48016,6 +48019,18 @@ typedef struct { * and flush old cache( if it exists) for dest_mac_addr with old self_mac_addr. * Bits 31:3: Reserved */ + /* Authentication modes */ + A_UINT32 akm; + /* pairwise cipher suite selector */ + A_UINT32 cipher_suite; + /* PMKID */ + A_UINT8 pmk_id[WMI_MAX_PMKID_LEN]; + /* passphrase length */ + A_UINT32 passphrase_len; + /* passphrase */ + A_UINT8 passphrase[WMI_MAX_PASN_PASSPHRASE_LEN]; + /* comeback cookie length */ + A_UINT32 cookie_len; } wmi_rtt_pasn_peer_create_req_param; @@ -48025,6 +48040,7 @@ typedef struct { * The following TLV will follow this fixed_param TLV: * * wmi_rtt_pasn_auth_status_param pasn_auth_status_param[] + * A_UINT8 cookie[] */ } wmi_rtt_pasn_auth_status_cmd_fixed_param; @@ -48036,6 +48052,14 @@ typedef struct { A_UINT32 status; /* Source address used for doing PASN authentication */ wmi_mac_addr source_mac_addr; + /* Authentication modes */ + A_UINT32 akm; + /* pairwise cipher suite selector */ + A_UINT32 cipher_suite; + /* PASN comeback timeout */ + A_INT32 timeout_value; + /* comeback cookie length */ + A_UINT32 cookie_len; } wmi_rtt_pasn_auth_status_param; diff --git a/fw/wmi_version.h b/fw/wmi_version.h index 7dedd1b1a9cd..f7b88daff837 100644 --- a/fw/wmi_version.h +++ b/fw/wmi_version.h @@ -37,7 +37,7 @@ #define __WMI_VER_MINOR_ 0 /** WMI revision number has to be incremented when there is a * change that may or may not break compatibility. */ -#define __WMI_REVISION_ 1572 +#define __WMI_REVISION_ 1573 /** The Version Namespace should not be normally changed. Only * host and firmware of the same WMI namespace will work From b824744c4ace9a3e4ceb47f6488e5454e2ac0a5b Mon Sep 17 00:00:00 2001 From: Pallavi Singh Date: Fri, 17 May 2024 11:58:06 +0530 Subject: [PATCH 116/138] msm: mhi_dev: Breaking memory for event request in smaller chunks Optimizing event buffer allocation to avoid memory allocation failure on 512MB targets for sdx72 M.2 devices. Change-Id: Ia2b381e71aff72fc4f5c379f7226cf0e91f069a3 Signed-off-by: Pallavi Singh --- drivers/platform/msm/mhi_dev/mhi.c | 41 ++++++++++++++++++------------ 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/drivers/platform/msm/mhi_dev/mhi.c b/drivers/platform/msm/mhi_dev/mhi.c index 68401a824bc2..68e52b8191c9 100644 --- a/drivers/platform/msm/mhi_dev/mhi.c +++ b/drivers/platform/msm/mhi_dev/mhi.c @@ -3189,6 +3189,7 @@ static int mhi_dev_alloc_evt_buf_evt_req(struct mhi_dev *mhi, { int rc; uint32_t size, i; + struct event_req *req, *tmp; size = mhi_dev_get_evt_ring_size(mhi, ch->ch_id); @@ -3207,7 +3208,14 @@ static int mhi_dev_alloc_evt_buf_evt_req(struct mhi_dev *mhi, * they were allocated with a different size */ if (ch->evt_buf_size) { - kfree(ch->ereqs); + list_for_each_entry_safe(req, tmp, &ch->event_req_buffers, list) { + list_del(&req->list); + kfree(req); + } + list_for_each_entry_safe(req, tmp, &ch->flush_event_req_buffers, list) { + list_del(&req->list); + kfree(req); + } kfree(ch->tr_events); } /* @@ -3221,14 +3229,8 @@ static int mhi_dev_alloc_evt_buf_evt_req(struct mhi_dev *mhi, mhi_log(MHI_MSG_INFO, "ch_id:%d evt buf size is %d\n", ch->ch_id, ch->evt_buf_size); - /* Allocate event requests */ - ch->ereqs = kcalloc(ch->evt_req_size, sizeof(*ch->ereqs), GFP_KERNEL); - if (!ch->ereqs) { - mhi_log(MHI_MSG_ERROR, - "Failed to alloc ereqs for ch_id:%d\n", ch->ch_id); - rc = -ENOMEM; - goto free_ereqs; - } + INIT_LIST_HEAD(&ch->event_req_buffers); + INIT_LIST_HEAD(&ch->flush_event_req_buffers); /* Allocate buffers to queue transfer completion events */ ch->tr_events = kcalloc(ch->evt_buf_size, sizeof(*ch->tr_events), @@ -3241,11 +3243,13 @@ static int mhi_dev_alloc_evt_buf_evt_req(struct mhi_dev *mhi, goto free_ereqs; } - /* Organize event flush requests into a linked list */ - INIT_LIST_HEAD(&ch->event_req_buffers); - INIT_LIST_HEAD(&ch->flush_event_req_buffers); - for (i = 0; i < ch->evt_req_size; ++i) - list_add_tail(&ch->ereqs[i].list, &ch->event_req_buffers); + /* Allocate event requests */ + for (i = 0; i < ch->evt_req_size; ++i) { + req = kzalloc(sizeof(struct event_req), GFP_KERNEL); + if (!req) + goto free_ereqs; + list_add_tail(&req->list, &ch->event_req_buffers); + } ch->curr_ereq = container_of(ch->event_req_buffers.next, @@ -3263,8 +3267,13 @@ static int mhi_dev_alloc_evt_buf_evt_req(struct mhi_dev *mhi, return 0; free_ereqs: - kfree(ch->ereqs); - ch->ereqs = NULL; + if (!list_empty(&ch->event_req_buffers)) { + list_for_each_entry_safe(req, tmp, &ch->event_req_buffers, list) { + list_del(&req->list); + kfree(req); + } + } + kfree(ch->tr_events); ch->evt_buf_size = 0; ch->evt_req_size = 0; From cfeb72f849d06253abf8538431b236cb65f98c11 Mon Sep 17 00:00:00 2001 From: spuligil Date: Thu, 6 Feb 2025 21:42:19 -0800 Subject: [PATCH 117/138] fw-api: CL 28541501 - update fw common interface files Change-Id: I639f50977f61beee705144c4f217cf7fe8eb2bf7 CRs-Fixed: 3830439 --- fw/wmi_unified.h | 1 + fw/wmi_version.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fw/wmi_unified.h b/fw/wmi_unified.h index 7fda522028f9..caa0250c71e8 100644 --- a/fw/wmi_unified.h +++ b/fw/wmi_unified.h @@ -5548,6 +5548,7 @@ typedef enum { WMI_VENDOR1_REQ1_VERSION_4_00 = 5, WMI_VENDOR1_REQ1_VERSION_4_10 = 6, WMI_VENDOR1_REQ1_VERSION_4_20 = 7, + WMI_VENDOR1_REQ1_VERSION_4_40 = 8, } WMI_VENDOR1_REQ1_VERSION; typedef enum { diff --git a/fw/wmi_version.h b/fw/wmi_version.h index f7b88daff837..76817640a7ee 100644 --- a/fw/wmi_version.h +++ b/fw/wmi_version.h @@ -37,7 +37,7 @@ #define __WMI_VER_MINOR_ 0 /** WMI revision number has to be incremented when there is a * change that may or may not break compatibility. */ -#define __WMI_REVISION_ 1573 +#define __WMI_REVISION_ 1574 /** The Version Namespace should not be normally changed. Only * host and firmware of the same WMI namespace will work From 420fc2034b3b4799ab1a2114276c7c9aaa2bfd3d Mon Sep 17 00:00:00 2001 From: spuligil Date: Thu, 6 Feb 2025 21:43:54 -0800 Subject: [PATCH 118/138] fw-api: CL 28550964 - update fw common interface files Change-Id: I93e1f01a433eb5c056fcec4c6b1211c3364a08f3 CRs-Fixed: 3830439 --- fw/wmi_unified.h | 3 +++ fw/wmi_version.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/fw/wmi_unified.h b/fw/wmi_unified.h index caa0250c71e8..70eaf1826cf7 100644 --- a/fw/wmi_unified.h +++ b/fw/wmi_unified.h @@ -37771,6 +37771,9 @@ typedef enum { WMI_THERMAL_CLIENT_APPS = 1, WMI_THERMAL_CLIENT_WPSS = 2, WMI_THERMAL_CLIENT_FW = 3, + /* WMI_THERMAL_CLIENT_DDR_BWM: client is for DDR bandwidth mitigation */ + WMI_THERMAL_CLIENT_DDR_BWM = 4, + WMI_THERMAL_CLIENT_MAX } WMI_THERMAL_MITIGATION_CLIENTS; diff --git a/fw/wmi_version.h b/fw/wmi_version.h index 76817640a7ee..145e8fcc2aa4 100644 --- a/fw/wmi_version.h +++ b/fw/wmi_version.h @@ -37,7 +37,7 @@ #define __WMI_VER_MINOR_ 0 /** WMI revision number has to be incremented when there is a * change that may or may not break compatibility. */ -#define __WMI_REVISION_ 1574 +#define __WMI_REVISION_ 1575 /** The Version Namespace should not be normally changed. Only * host and firmware of the same WMI namespace will work From 764e789b7bdb739aaf2b710d0aac108180cd5ccb Mon Sep 17 00:00:00 2001 From: spuligil Date: Mon, 10 Feb 2025 12:01:49 -0800 Subject: [PATCH 119/138] fw-api: CL 28563606 - update fw common interface files Change-Id: I394ad0da6b3a57d04b9b6630190d938150bee4d7 CRs-Fixed: 3830439 --- fw/htt_stats.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fw/htt_stats.h b/fw/htt_stats.h index f3dc39b8dce8..5a57e7f9f171 100644 --- a/fw/htt_stats.h +++ b/fw/htt_stats.h @@ -4781,6 +4781,19 @@ typedef struct { A_UINT32 g1_compl_fail; A_UINT32 g2_success; A_UINT32 g2_compl_fail; + /* enqueue */ + A_UINT32 m1_enq_success; + A_UINT32 m1_enq_fail; + A_UINT32 m2_enq_success; + A_UINT32 m2_enq_fail; + A_UINT32 m3_enq_success; + A_UINT32 m3_enq_fail; + A_UINT32 m4_enq_success; + A_UINT32 m4_enq_fail; + A_UINT32 g1_enq_success; + A_UINT32 g1_enq_fail; + A_UINT32 g2_enq_success; + A_UINT32 g2_enq_fail; } htt_stats_tx_de_eapol_packets_tlv; /* preserve old name alias for new name consistent with the tag name */ typedef htt_stats_tx_de_eapol_packets_tlv htt_tx_de_eapol_packets_stats_tlv; From 0d3e5b23e533879d5c4c30fdb114738235c202a2 Mon Sep 17 00:00:00 2001 From: Terence Tritton Date: Tue, 18 Feb 2025 08:55:50 +0000 Subject: [PATCH 120/138] ANDROID: ABI: Cuttlefish Symbol update android11-5.4 is broken on Cuttlefish aarch64 because of the use of blk_mq_quiesce_queue_nowait in virtio_blk.ko. The following steps were used to update the cuttlefish symbol list. $ BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh $ BUILD_CONFIG=common-modules/virtual-\ device/build.config.cuttlefish.aarch64 build/build.sh $ build/abi/extract_symbols out/android11-5.4/dist/ --whitelist \ common/android/abi_gki_aarch64_cuttlefish --additions-only $ BUILD_CONFIG=common/build.config.gki.aarch64 build/build_abi.sh \ --update --print-report Change-Id: I01fac6926d4362c00cbd212091ab7d4fa98b885c Bug: 391465004 Signed-off-by: Terry Tritton --- android/abi_gki_aarch64.xml | 13 +++++++++++++ android/abi_gki_aarch64_cuttlefish | 18 +++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index def41776bbaf..0e48c4e84df9 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -426,6 +426,7 @@ + @@ -37447,6 +37448,10 @@ + + + + @@ -149383,6 +149388,14 @@ + + + + + + + + diff --git a/android/abi_gki_aarch64_cuttlefish b/android/abi_gki_aarch64_cuttlefish index c2732aa7dba0..6d6db2054797 100644 --- a/android/abi_gki_aarch64_cuttlefish +++ b/android/abi_gki_aarch64_cuttlefish @@ -230,7 +230,6 @@ vring_del_virtqueue vring_interrupt vring_transport_features - wait_for_completion wait_woken __wake_up __warn_printk @@ -739,11 +738,13 @@ blk_mq_complete_request blk_mq_end_request blk_mq_free_tag_set + blk_mq_freeze_queue blk_mq_init_queue - blk_mq_quiesce_queue + blk_mq_quiesce_queue_nowait blk_mq_start_request blk_mq_start_stopped_hw_queues blk_mq_stop_hw_queue + blk_mq_unfreeze_queue blk_mq_unquiesce_queue blk_mq_virtio_map_queues blk_put_request @@ -800,6 +801,7 @@ __splice_from_pipe system_freezing_cnt __unregister_chrdev + wait_for_completion # required by virtio_input.ko input_alloc_absinfo @@ -813,14 +815,10 @@ # required by virtio_mmio.ko device_for_each_child - devm_ioremap - devm_kfree - __devm_request_region - iomem_resource + devm_platform_ioremap_resource memparse platform_device_register_full platform_get_irq - platform_get_resource sscanf # required by virtio_net.ko @@ -956,6 +954,12 @@ sock_i_ino # preserved by --additions-only + blk_mq_quiesce_queue + devm_ioremap + devm_kfree + __devm_request_region generic_shutdown_super + iomem_resource + platform_get_resource refcount_dec_and_test_checked refcount_inc_checked From cc9368436492dc083f98ba2ed620c6c4b9097afb Mon Sep 17 00:00:00 2001 From: Prashanth K Date: Tue, 25 Feb 2025 14:05:21 +0530 Subject: [PATCH 121/138] defconfig: Enable RTL8152 ETH-USB driver Enable RTL815x Ethernet dongle support for sdxlemur. Change-Id: Ida1265bd8642af0b9211dea5cf6330d8487274b0 Signed-off-by: Prashanth K --- arch/arm/configs/vendor/sdxlemur.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/vendor/sdxlemur.config b/arch/arm/configs/vendor/sdxlemur.config index f51895fb5d48..2646540a9f28 100644 --- a/arch/arm/configs/vendor/sdxlemur.config +++ b/arch/arm/configs/vendor/sdxlemur.config @@ -250,6 +250,7 @@ CONFIG_USB_CONFIGFS_F_UAC2=y CONFIG_USB_CONFIGFS_F_CCID=y CONFIG_USB_G_QTI=y CONFIG_USB_BAM=y +CONFIG_USB_RTL8152=y CONFIG_USB_NET_SMSC75XX=y CONFIG_USB_NET_SMSC95XX=y CONFIG_ARM_PSCI=y From 2a4f06f92c03d2c30f6bda9c30f46ba15a461a9c Mon Sep 17 00:00:00 2001 From: Prashanth K Date: Tue, 25 Feb 2025 14:37:32 +0530 Subject: [PATCH 122/138] UPSTREAM: usb: xhci: Set quirk for XHCI_SG_TRB_CACHE_SIZE_QUIRK This commit uses the private data passed by parent device to set the quirk for Synopsys xHC. This patch fixes the SNPS xHC hang issue when the data is scattered across small buffers which does not make atleast MPS size for given TRB cache size of SNPS xHC. Change-Id: I1eb96096cfb7500b5ef4eb866170642bff0b2133 Signed-off-by: Tejas Joglekar Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20201208092912.1773650-2-mathias.nyman@linux.intel.com Cc: stable Signed-off-by: Greg Kroah-Hartman Signed-off-by: Prashanth K --- drivers/usb/host/xhci-plat.c | 3 +++ drivers/usb/host/xhci.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 524bf63d5e9b..52635c85c175 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -336,6 +336,9 @@ static int xhci_plat_probe(struct platform_device *pdev) if ((xhci->quirks & XHCI_SKIP_PHY_INIT) || (priv && (priv->quirks & XHCI_SKIP_PHY_INIT))) hcd->skip_phy_initialization = 1; + if (priv && (priv->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK)) + xhci->quirks |= XHCI_SG_TRB_CACHE_SIZE_QUIRK; + ret = usb_add_hcd(hcd, irq, IRQF_SHARED); if (ret) goto disable_usb_phy; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index a520d40836ac..35eb51ac1590 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1891,6 +1891,7 @@ struct xhci_hcd { #define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35) #define XHCI_SKIP_PHY_INIT BIT_ULL(37) #define XHCI_DISABLE_SPARSE BIT_ULL(38) +#define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39) #define XHCI_NO_SOFT_RETRY BIT_ULL(40) unsigned int num_active_eps; From ea488268157f50d2c015d4ce871850b30586004e Mon Sep 17 00:00:00 2001 From: Prashanth K Date: Tue, 25 Feb 2025 14:33:17 +0530 Subject: [PATCH 123/138] UPSTREAM: usb: xhci: Use temporary buffer to consolidate SG The Synopsys xHC has an internal TRB cache of size TRB_CACHE_SIZE for each endpoint. The default value for TRB_CACHE_SIZE is 16 for SS and 8 for HS. The controller loads and updates the TRB cache from the transfer ring in system memory whenever the driver issues a start transfer or update transfer command. For chained TRBs, the Synopsys xHC requires that the total amount of bytes for all TRBs loaded in the TRB cache be greater than or equal to 1 MPS. Or the chain ends within the TRB cache (with a last TRB). If this requirement is not met, the controller will not be able to send or receive a packet and it will hang causing a driver timeout and error. This can be a problem if a class driver queues SG requests with many small-buffer entries. The XHCI driver will create a chained TRB for each entry which may trigger this issue. This patch adds logic to the XHCI driver to detect and prevent this from happening. For every (TRB_CACHE_SIZE - 2), we check the total buffer size of the SG list and if the last window of (TRB_CACHE_SIZE - 2) SG list length and we don't make up at least 1 MPS, we create a temporary buffer to consolidate full SG list into the buffer. We check at (TRB_CACHE_SIZE - 2) window because it is possible that there would be a link and/or event data TRB that take up to 2 of the cache entries. We discovered this issue with devices on other platforms but have not yet come across any device that triggers this on Linux. But it could be a real problem now or in the future. All it takes is N number of small chained TRBs. And other instances of the Synopsys IP may have smaller values for the TRB_CACHE_SIZE which would exacerbate the problem. Change-Id: I6d34805c32756c48b07be2ffa9aad72ab5af2bbe Signed-off-by: Tejas Joglekar Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20201208092912.1773650-3-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Prashanth K --- drivers/usb/host/xhci-ring.c | 2 +- drivers/usb/host/xhci.c | 130 +++++++++++++++++++++++++++++++++++ drivers/usb/host/xhci.h | 4 ++ 3 files changed, 135 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 6ca953ffa3dd..ee692d865c87 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3380,7 +3380,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, full_len = urb->transfer_buffer_length; /* If we have scatter/gather list, we use it. */ - if (urb->num_sgs) { + if (urb->num_sgs && !(urb->transfer_flags & URB_DMA_MAP_SINGLE)) { num_sgs = urb->num_mapped_sgs; sg = urb->sg; addr = (u64) sg_dma_address(sg); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 5bb772bd9d87..776d7bb2499c 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1349,6 +1349,110 @@ EXPORT_SYMBOL_GPL(xhci_resume); /*-------------------------------------------------------------------------*/ +static int xhci_map_temp_buffer(struct usb_hcd *hcd, struct urb *urb) +{ + void *temp; + int ret = 0; + unsigned int buf_len; + enum dma_data_direction dir; + + dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + buf_len = urb->transfer_buffer_length; + + temp = kzalloc_node(buf_len, GFP_ATOMIC, + dev_to_node(hcd->self.sysdev)); + + if (usb_urb_dir_out(urb)) + sg_pcopy_to_buffer(urb->sg, urb->num_sgs, + temp, buf_len, 0); + + urb->transfer_buffer = temp; + urb->transfer_dma = dma_map_single(hcd->self.sysdev, + urb->transfer_buffer, + urb->transfer_buffer_length, + dir); + + if (dma_mapping_error(hcd->self.sysdev, + urb->transfer_dma)) { + ret = -EAGAIN; + kfree(temp); + } else { + urb->transfer_flags |= URB_DMA_MAP_SINGLE; + } + + return ret; +} + +static bool xhci_urb_temp_buffer_required(struct usb_hcd *hcd, + struct urb *urb) +{ + bool ret = false; + unsigned int i; + unsigned int len = 0; + unsigned int trb_size; + unsigned int max_pkt; + struct scatterlist *sg; + struct scatterlist *tail_sg; + + tail_sg = urb->sg; + max_pkt = usb_endpoint_maxp(&urb->ep->desc); + + if (!urb->num_sgs) + return ret; + + if (urb->dev->speed >= USB_SPEED_SUPER) + trb_size = TRB_CACHE_SIZE_SS; + else + trb_size = TRB_CACHE_SIZE_HS; + + if (urb->transfer_buffer_length != 0 && + !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { + for_each_sg(urb->sg, sg, urb->num_sgs, i) { + len = len + sg->length; + if (i > trb_size - 2) { + len = len - tail_sg->length; + if (len < max_pkt) { + ret = true; + break; + } + + tail_sg = sg_next(tail_sg); + } + } + } + return ret; +} + +static void xhci_unmap_temp_buf(struct usb_hcd *hcd, struct urb *urb) +{ + unsigned int len; + unsigned int buf_len; + enum dma_data_direction dir; + + dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + + buf_len = urb->transfer_buffer_length; + + if (IS_ENABLED(CONFIG_HAS_DMA) && + (urb->transfer_flags & URB_DMA_MAP_SINGLE)) + dma_unmap_single(hcd->self.sysdev, + urb->transfer_dma, + urb->transfer_buffer_length, + dir); + + if (usb_urb_dir_in(urb)) + len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, + urb->transfer_buffer, + buf_len, + 0); + + urb->transfer_flags &= ~URB_DMA_MAP_SINGLE; + kfree(urb->transfer_buffer); + urb->transfer_buffer = NULL; +} + + + /* * Bypass the DMA mapping if URB is suitable for Immediate Transfer (IDT), * we'll copy the actual data into the TRB address register. This is limited to @@ -1358,12 +1462,37 @@ EXPORT_SYMBOL_GPL(xhci_resume); static int xhci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) { + struct xhci_hcd *xhci; + + xhci = hcd_to_xhci(hcd); + if (xhci_urb_suitable_for_idt(urb)) return 0; + if (xhci->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK) { + if (xhci_urb_temp_buffer_required(hcd, urb)) + return xhci_map_temp_buffer(hcd, urb); + } return usb_hcd_map_urb_for_dma(hcd, urb, mem_flags); } +static void xhci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) +{ + struct xhci_hcd *xhci; + bool unmap_temp_buf = false; + + xhci = hcd_to_xhci(hcd); + + if (urb->num_sgs && (urb->transfer_flags & URB_DMA_MAP_SINGLE)) + unmap_temp_buf = true; + + if ((xhci->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK) && unmap_temp_buf) + xhci_unmap_temp_buf(hcd, urb); + else + usb_hcd_unmap_urb_for_dma(hcd, urb); +} + + /** * xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and * HCDs. Find the index for an endpoint given its descriptor. Use the return @@ -5596,6 +5725,7 @@ static const struct hc_driver xhci_hc_driver = { * managing i/o requests and associated device resources */ .map_urb_for_dma = xhci_map_urb_for_dma, + .unmap_urb_for_dma = xhci_unmap_urb_for_dma, .urb_enqueue = xhci_urb_enqueue, .urb_dequeue = xhci_urb_dequeue, .alloc_dev = xhci_alloc_dev, diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 35eb51ac1590..81049e5d05f2 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1338,6 +1338,10 @@ enum xhci_setup_dev { #define TRB_SIA (1<<31) #define TRB_FRAME_ID(p) (((p) & 0x7ff) << 20) +/* TRB cache size for xHC with TRB cache */ +#define TRB_CACHE_SIZE_HS 8 +#define TRB_CACHE_SIZE_SS 16 + struct xhci_generic_trb { __le32 field[4]; }; From 43e62e158f32e7c5b21c7c0fcce957b747370182 Mon Sep 17 00:00:00 2001 From: Prashanth K Date: Thu, 29 Feb 2024 16:14:38 +0200 Subject: [PATCH 124/138] UPSTREAM: usb: xhci: Add error handling in xhci_map_urb_for_dma Currently xhci_map_urb_for_dma() creates a temporary buffer and copies the SG list to the new linear buffer. But if the kzalloc_node() fails, then the following sg_pcopy_to_buffer() can lead to crash since it tries to memcpy to NULL pointer. So return -ENOMEM if kzalloc returns null pointer. Change-Id: I5a2d953f8e9b2f2488f5daafdfbc7084db0ceb61 Cc: stable@vger.kernel.org # 5.11 Fixes: 2017a1e58472 ("usb: xhci: Use temporary buffer to consolidate SG") Signed-off-by: Prashanth K Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20240229141438.619372-10-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Prashanth K --- drivers/usb/host/xhci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 776d7bb2499c..3d61c9611872 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1361,6 +1361,8 @@ static int xhci_map_temp_buffer(struct usb_hcd *hcd, struct urb *urb) temp = kzalloc_node(buf_len, GFP_ATOMIC, dev_to_node(hcd->self.sysdev)); + if (!temp) + return -ENOMEM; if (usb_urb_dir_out(urb)) sg_pcopy_to_buffer(urb->sg, urb->num_sgs, From 4f6f18aa00af3d9647ef1cbd4e6879ceec28f728 Mon Sep 17 00:00:00 2001 From: Prashanth K Date: Tue, 16 Jan 2024 11:28:16 +0530 Subject: [PATCH 125/138] UPSTREAM: usb: host: xhci-plat: Add support for XHCI_SG_TRB_CACHE_SIZE_QUIRK Upstream commit bac1ec551434 ("usb: xhci: Set quirk for XHCI_SG_TRB_CACHE_SIZE_QUIRK") introduced a new quirk in XHCI which fixes XHC timeout, which was seen on synopsys XHCs while using SG buffers. Currently this quirk can only be set using xhci private data. But there are some drivers like dwc3/host.c which adds adds quirks using software node for xhci device. Hence set this xhci quirk by iterating over device properties. Change-Id: I29c31b05727851fd7c22809febc64589113bc1b9 Cc: stable@vger.kernel.org # 5.11 Fixes: bac1ec551434 ("usb: xhci: Set quirk for XHCI_SG_TRB_CACHE_SIZE_QUIRK") Signed-off-by: Prashanth K Link: https://lore.kernel.org/r/20240116055816.1169821-3-quic_prashk@quicinc.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Prashanth K --- drivers/usb/host/xhci-plat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 52635c85c175..ed18301187bd 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -309,6 +309,9 @@ static int xhci_plat_probe(struct platform_device *pdev) if (device_property_read_bool(tmpdev, "quirk-broken-port-ped")) xhci->quirks |= XHCI_BROKEN_PORT_PED; + if (device_property_read_bool(tmpdev, "xhci-sg-trb-cache-size-quirk")) + xhci->quirks |= XHCI_SG_TRB_CACHE_SIZE_QUIRK; + device_property_read_u32(tmpdev, "imod-interval-ns", &xhci->imod_interval); } From 95c448e702322a23175d9831158ca96f82a484ee Mon Sep 17 00:00:00 2001 From: Prashanth K Date: Tue, 25 Feb 2025 14:43:34 +0530 Subject: [PATCH 126/138] UPSTREAM: usb: dwc3: host: Set XHCI_SG_TRB_CACHE_SIZE_QUIRK Upstream commit bac1ec551434 ("usb: xhci: Set quirk for XHCI_SG_TRB_CACHE_SIZE_QUIRK") introduced a new quirk in XHCI which fixes XHC timeout, which was seen on synopsys XHCs while using SG buffers. But the support for this quirk isn't present in the DWC3 layer. We will encounter this XHCI timeout/hung issue if we run iperf loopback tests using RTL8156 ethernet adaptor on DWC3 targets with scatter-gather enabled. This gets resolved after enabling the XHCI_SG_TRB_CACHE_SIZE_QUIRK. This patch enables it using the xhci device property since its needed for DWC3 controller. In Synopsys DWC3 databook, Table 9-3: xHCI Debug Capability Limitations Chained TRBs greater than TRB cache size: The debug capability driver must not create a multi-TRB TD that describes smaller than a 1K packet that spreads across 8 or more TRBs on either the IN TR or the OUT TR. Change-Id: I51c065d76939b6fc34e80dc970568ba5c9d40567 Cc: stable@vger.kernel.org #5.11 Signed-off-by: Prashanth K Acked-by: Thinh Nguyen Link: https://lore.kernel.org/r/20240116055816.1169821-2-quic_prashk@quicinc.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Prashanth K --- drivers/usb/dwc3/host.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index 2a06550c97c6..0831cc7059f9 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c @@ -43,7 +43,7 @@ out: int dwc3_host_init(struct dwc3 *dwc) { - struct property_entry props[6]; + struct property_entry props[7]; struct platform_device *xhci; int ret, irq; struct resource *res; @@ -88,6 +88,8 @@ int dwc3_host_init(struct dwc3 *dwc) memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props)); + props[prop_idx++] = PROPERTY_ENTRY_BOOL("xhci-sg-trb-cache-size-quirk"); + if (dwc->usb3_lpm_capable) props[prop_idx++] = PROPERTY_ENTRY_BOOL("usb3-lpm-capable"); From f567655bdb8a8487eb0d6f647fb6e315a29e720a Mon Sep 17 00:00:00 2001 From: Luca Stefani Date: Thu, 6 May 2021 21:37:25 +0200 Subject: [PATCH 127/138] UPSTREAM: binder: Return EFAULT if we fail BINDER_ENABLE_ONEWAY_SPAM_DETECTION All the other ioctl paths return EFAULT in case the copy_from_user/copy_to_user call fails, make oneway spam detection follow the same paradigm. Bug: 254441685 Fixes: a7dc1e6f99df ("binder: tell userspace to dump current backtrace when detected oneway spamming") Acked-by: Todd Kjos Acked-by: Christian Brauner Signed-off-by: Luca Stefani Link: https://lore.kernel.org/r/20210506193726.45118-1-luca.stefani.ge1@gmail.com Signed-off-by: Greg Kroah-Hartman (cherry picked from commit ced081a436d21a7d34d4d42acb85058f9cf423f2) Signed-off-by: Lee Jones Change-Id: I5f54cc7505300f106c04ac81da33d8046704f377 --- drivers/android/binder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 1765a4f896e2..4f7fdc2ab881 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -5854,7 +5854,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) uint32_t enable; if (copy_from_user(&enable, ubuf, sizeof(enable))) { - ret = -EINVAL; + ret = -EFAULT; goto err; } binder_inner_proc_lock(proc); From 0b8367ba8c3bb0d61ed67a0ac41422ae91705192 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Tue, 26 Mar 2024 12:33:58 +0100 Subject: [PATCH 128/138] UPSTREAM: udp: do not accept non-tunnel GSO skbs landing in a tunnel When rx-udp-gro-forwarding is enabled UDP packets might be GROed when being forwarded. If such packets might land in a tunnel this can cause various issues and udp_gro_receive makes sure this isn't the case by looking for a matching socket. This is performed in udp4/6_gro_lookup_skb but only in the current netns. This is an issue with tunneled packets when the endpoint is in another netns. In such cases the packets will be GROed at the UDP level, which leads to various issues later on. The same thing can happen with rx-gro-list. We saw this with geneve packets being GROed at the UDP level. In such case gso_size is set; later the packet goes through the geneve rx path, the geneve header is pulled, the offset are adjusted and frag_list skbs are not adjusted with regard to geneve. When those skbs hit skb_fragment, it will misbehave. Different outcomes are possible depending on what the GROed skbs look like; from corrupted packets to kernel crashes. One example is a BUG_ON[1] triggered in skb_segment while processing the frag_list. Because gso_size is wrong (geneve header was pulled) skb_segment thinks there is "geneve header size" of data in frag_list, although it's in fact the next packet. The BUG_ON itself has nothing to do with the issue. This is only one of the potential issues. Looking up for a matching socket in udp_gro_receive is fragile: the lookup could be extended to all netns (not speaking about performances) but nothing prevents those packets from being modified in between and we could still not find a matching socket. It's OK to keep the current logic there as it should cover most cases but we also need to make sure we handle tunnel packets being GROed too early. This is done by extending the checks in udp_unexpected_gso: GSO packets lacking the SKB_GSO_UDP_TUNNEL/_CSUM bits and landing in a tunnel must be segmented. [1] kernel BUG at net/core/skbuff.c:4408! RIP: 0010:skb_segment+0xd2a/0xf70 __udp_gso_segment+0xaa/0x560 Bug: 254441685 Fixes: 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.") Fixes: 36707061d6ba ("udp: allow forwarding of plain (non-fraglisted) UDP GRO packets") Signed-off-by: Antoine Tenart Reviewed-by: Willem de Bruijn Signed-off-by: David S. Miller (cherry picked from commit 3d010c8031e39f5fa1e8b13ada77e0321091011f) Signed-off-by: Lee Jones Change-Id: I28f2d205ff3fd88ef83f16a6fb92057a6f7a6423 --- include/linux/udp.h | 28 ++++++++++++++++++++++++++++ net/ipv4/udp.c | 7 +++++++ net/ipv4/udp_offload.c | 6 ++++-- net/ipv6/udp.c | 2 +- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/include/linux/udp.h b/include/linux/udp.h index ae58ff3b6b5b..a220880019d6 100644 --- a/include/linux/udp.h +++ b/include/linux/udp.h @@ -131,6 +131,24 @@ static inline void udp_cmsg_recv(struct msghdr *msg, struct sock *sk, } } +DECLARE_STATIC_KEY_FALSE(udp_encap_needed_key); +#if IS_ENABLED(CONFIG_IPV6) +DECLARE_STATIC_KEY_FALSE(udpv6_encap_needed_key); +#endif + +static inline bool udp_encap_needed(void) +{ + if (static_branch_unlikely(&udp_encap_needed_key)) + return true; + +#if IS_ENABLED(CONFIG_IPV6) + if (static_branch_unlikely(&udpv6_encap_needed_key)) + return true; +#endif + + return false; +} + static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb) { if (!skb_is_gso(skb)) @@ -142,6 +160,16 @@ static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb) if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST && !udp_sk(sk)->accept_udp_fraglist) return true; + /* GSO packets lacking the SKB_GSO_UDP_TUNNEL/_CSUM bits might still + * land in a tunnel as the socket check in udp_gro_receive cannot be + * foolproof. + */ + if (udp_encap_needed() && + READ_ONCE(udp_sk(sk)->encap_rcv) && + !(skb_shinfo(skb)->gso_type & + (SKB_GSO_UDP_TUNNEL | SKB_GSO_UDP_TUNNEL_CSUM))) + return true; + return false; } diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 59f158f27273..fdc652bda520 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -540,6 +540,13 @@ static inline bool __udp_is_mcast_sock(struct net *net, struct sock *sk, } DEFINE_STATIC_KEY_FALSE(udp_encap_needed_key); +EXPORT_SYMBOL(udp_encap_needed_key); + +#if IS_ENABLED(CONFIG_IPV6) +DEFINE_STATIC_KEY_FALSE(udpv6_encap_needed_key); +EXPORT_SYMBOL(udpv6_encap_needed_key); +#endif + void udp_encap_enable(void) { static_branch_inc(&udp_encap_needed_key); diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index 0c1aacf6e312..cc9fde88ddb7 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c @@ -512,8 +512,10 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb, unsigned int off = skb_gro_offset(skb); int flush = 1; - /* we can do L4 aggregation only if the packet can't land in a tunnel - * otherwise we could corrupt the inner stream + /* We can do L4 aggregation only if the packet can't land in a tunnel + * otherwise we could corrupt the inner stream. Detecting such packets + * cannot be foolproof and the aggregation might still happen in some + * cases. Such packets should be caught in udp_unexpected_gso later. */ NAPI_GRO_CB(skb)->is_flist = 0; if (!sk || !udp_sk(sk)->gro_receive) { diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index e6fdb842e89d..2b4f2c626d37 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -413,7 +413,7 @@ csum_copy_err: goto try_again; } -DEFINE_STATIC_KEY_FALSE(udpv6_encap_needed_key); +DECLARE_STATIC_KEY_FALSE(udpv6_encap_needed_key); void udpv6_encap_enable(void) { static_branch_inc(&udpv6_encap_needed_key); From 2949c0bf09d8d7c1b1384e3207113aac2443a234 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Tue, 26 Mar 2024 12:34:00 +0100 Subject: [PATCH 129/138] UPSTREAM: udp: do not transition UDP GRO fraglist partial checksums to unnecessary UDP GRO validates checksums and in udp4/6_gro_complete fraglist packets are converted to CHECKSUM_UNNECESSARY to avoid later checks. However this is an issue for CHECKSUM_PARTIAL packets as they can be looped in an egress path and then their partial checksums are not fixed. Different issues can be observed, from invalid checksum on packets to traces like: gen01: hw csum failure skb len=3008 headroom=160 headlen=1376 tailroom=0 mac=(106,14) net=(120,40) trans=160 shinfo(txflags=0 nr_frags=0 gso(size=0 type=0 segs=0)) csum(0xffff232e ip_summed=2 complete_sw=0 valid=0 level=0) hash(0x77e3d716 sw=1 l4=1) proto=0x86dd pkttype=0 iif=12 ... Fix this by only converting CHECKSUM_NONE packets to CHECKSUM_UNNECESSARY by reusing __skb_incr_checksum_unnecessary. All other checksum types are kept as-is, including CHECKSUM_COMPLETE as fraglist packets being segmented back would have their skb->csum valid. Bug: 254441685 Fixes: 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.") Signed-off-by: Antoine Tenart Reviewed-by: Willem de Bruijn Signed-off-by: David S. Miller (cherry picked from commit f0b8c30345565344df2e33a8417a27503589247d) Signed-off-by: Lee Jones Change-Id: I29b8543842f63664e901a217f8636f21ffef504b --- net/ipv4/udp_offload.c | 8 +------- net/ipv6/udp_offload.c | 8 +------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index cc9fde88ddb7..e3d754169f97 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c @@ -662,13 +662,7 @@ INDIRECT_CALLABLE_SCOPE int udp4_gro_complete(struct sk_buff *skb, int nhoff) skb_shinfo(skb)->gso_type |= (SKB_GSO_FRAGLIST|SKB_GSO_UDP_L4); skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count; - if (skb->ip_summed == CHECKSUM_UNNECESSARY) { - if (skb->csum_level < SKB_MAX_CSUM_LEVEL) - skb->csum_level++; - } else { - skb->ip_summed = CHECKSUM_UNNECESSARY; - skb->csum_level = 0; - } + __skb_incr_checksum_unnecessary(skb); return 0; } diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c index 6e06c90fa318..ad20e304f634 100644 --- a/net/ipv6/udp_offload.c +++ b/net/ipv6/udp_offload.c @@ -156,13 +156,7 @@ INDIRECT_CALLABLE_SCOPE int udp6_gro_complete(struct sk_buff *skb, int nhoff) skb_shinfo(skb)->gso_type |= (SKB_GSO_FRAGLIST|SKB_GSO_UDP_L4); skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count; - if (skb->ip_summed == CHECKSUM_UNNECESSARY) { - if (skb->csum_level < SKB_MAX_CSUM_LEVEL) - skb->csum_level++; - } else { - skb->ip_summed = CHECKSUM_UNNECESSARY; - skb->csum_level = 0; - } + __skb_incr_checksum_unnecessary(skb); return 0; } From bf543165c8250e502a05c8a652c78ba5c5aac548 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Tue, 26 Mar 2024 12:34:01 +0100 Subject: [PATCH 130/138] UPSTREAM: udp: prevent local UDP tunnel packets from being GROed GRO has a fundamental issue with UDP tunnel packets as it can't detect those in a foolproof way and GRO could happen before they reach the tunnel endpoint. Previous commits have fixed issues when UDP tunnel packets come from a remote host, but if those packets are issued locally they could run into checksum issues. If the inner packet has a partial checksum the information will be lost in the GRO logic, either in udp4/6_gro_complete or in udp_gro_complete_segment and packets will have an invalid checksum when leaving the host. Prevent local UDP tunnel packets from ever being GROed at the outer UDP level. Due to skb->encapsulation being wrongly used in some drivers this is actually only preventing UDP tunnel packets with a partial checksum to be GROed (see iptunnel_handle_offloads) but those were also the packets triggering issues so in practice this should be sufficient. Bug: 254441685 Fixes: 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.") Fixes: 36707061d6ba ("udp: allow forwarding of plain (non-fraglisted) UDP GRO packets") Suggested-by: Paolo Abeni Signed-off-by: Antoine Tenart Reviewed-by: Willem de Bruijn Signed-off-by: David S. Miller (cherry picked from commit 64235eabc4b5b18c507c08a1f16cdac6c5661220) Signed-off-by: Lee Jones Change-Id: I1f6d19cfd34e04e395b270e5c286fec06d13fedd --- net/ipv4/udp_offload.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index e3d754169f97..0ff68f00a535 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c @@ -519,6 +519,12 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb, */ NAPI_GRO_CB(skb)->is_flist = 0; if (!sk || !udp_sk(sk)->gro_receive) { + /* If the packet was locally encapsulated in a UDP tunnel that + * wasn't detected above, do not GRO. + */ + if (skb->encapsulation) + goto out; + if (skb->dev->features & NETIF_F_GRO_FRAGLIST) NAPI_GRO_CB(skb)->is_flist = sk ? !udp_sk(sk)->gro_enabled : 1; From 45b722f73a86ddb2ac62fa199e19572ffe181e44 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 27 Apr 2024 20:24:19 +0200 Subject: [PATCH 131/138] UPSTREAM: net: core: reject skb_copy(_expand) for fraglist GSO skbs SKB_GSO_FRAGLIST skbs must not be linearized, otherwise they become invalid. Return NULL if such an skb is passed to skb_copy or skb_copy_expand, in order to prevent a crash on a potential later call to skb_gso_segment. Bug: 254441685 Fixes: 3a1296a38d0c ("net: Support GRO/GSO fraglist chaining.") Signed-off-by: Felix Fietkau Signed-off-by: David S. Miller (cherry picked from commit d091e579b864fa790dd6a0cd537a22c383126681) Signed-off-by: Lee Jones Change-Id: I0835421359096bd9566a09037d43db84f371dcb1 --- net/core/skbuff.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 3001b05c919c..fec1b4777efb 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -1527,11 +1527,17 @@ static inline int skb_alloc_rx_flag(const struct sk_buff *skb) struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask) { - int headerlen = skb_headroom(skb); - unsigned int size = skb_end_offset(skb) + skb->data_len; - struct sk_buff *n = __alloc_skb(size, gfp_mask, - skb_alloc_rx_flag(skb), NUMA_NO_NODE); + struct sk_buff *n; + unsigned int size; + int headerlen; + if (WARN_ON_ONCE(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)) + return NULL; + + headerlen = skb_headroom(skb); + size = skb_end_offset(skb) + skb->data_len; + n = __alloc_skb(size, gfp_mask, + skb_alloc_rx_flag(skb), NUMA_NO_NODE); if (!n) return NULL; @@ -1803,12 +1809,17 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb, /* * Allocate the copy buffer */ - struct sk_buff *n = __alloc_skb(newheadroom + skb->len + newtailroom, - gfp_mask, skb_alloc_rx_flag(skb), - NUMA_NO_NODE); - int oldheadroom = skb_headroom(skb); int head_copy_len, head_copy_off; + struct sk_buff *n; + int oldheadroom; + if (WARN_ON_ONCE(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)) + return NULL; + + oldheadroom = skb_headroom(skb); + n = __alloc_skb(newheadroom + skb->len + newtailroom, + gfp_mask, skb_alloc_rx_flag(skb), + NUMA_NO_NODE); if (!n) return NULL; From 196e23be873afbb2901b85db8be99549a8cbd0f4 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Fri, 10 May 2024 11:33:39 +0800 Subject: [PATCH 132/138] UPSTREAM: f2fs: compress: don't allow unaligned truncation on released compress inode f2fs image may be corrupted after below testcase: - mkfs.f2fs -O extra_attr,compression -f /dev/vdb - mount /dev/vdb /mnt/f2fs - touch /mnt/f2fs/file - f2fs_io setflags compression /mnt/f2fs/file - dd if=/dev/zero of=/mnt/f2fs/file bs=4k count=4 - f2fs_io release_cblocks /mnt/f2fs/file - truncate -s 8192 /mnt/f2fs/file - umount /mnt/f2fs - fsck.f2fs /dev/vdb [ASSERT] (fsck_chk_inode_blk:1256) --> ino: 0x5 has i_blocks: 0x00000002, but has 0x3 blocks [FSCK] valid_block_count matching with CP [Fail] [0x4, 0x5] [FSCK] other corrupted bugs [Fail] The reason is: partial truncation assume compressed inode has reserved blocks, after partial truncation, valid block count may change w/o .i_blocks and .total_valid_block_count update, result in corruption. This patch only allow cluster size aligned truncation on released compress inode for fixing. Bug: 254441685 Fixes: c61404153eb6 ("f2fs: introduce FI_COMPRESS_RELEASED instead of using IMMUTABLE bit") Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim (cherry picked from commit 29ed2b5dd521ce7c5d8466cd70bf0cc9d07afeee) Signed-off-by: Lee Jones Change-Id: I33ef69b992bdeb4f4f3b7741eaf6ce0e24f689f6 --- fs/f2fs/file.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 7027239e2765..0d95b82703c8 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -890,9 +890,14 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) ATTR_GID | ATTR_TIMES_SET)))) return -EPERM; - if ((attr->ia_valid & ATTR_SIZE) && - !f2fs_is_compress_backend_ready(inode)) - return -EOPNOTSUPP; + if ((attr->ia_valid & ATTR_SIZE)) { + if (!f2fs_is_compress_backend_ready(inode)) + return -EOPNOTSUPP; + if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED) && + !IS_ALIGNED(attr->ia_size, + F2FS_BLK_TO_BYTES(F2FS_I(inode)->i_cluster_size))) + return -EINVAL; + } err = setattr_prepare(dentry, attr); if (err) From 2cc0b129d22711c4936cb0964315fc87043fbf77 Mon Sep 17 00:00:00 2001 From: Quang Le Date: Mon, 3 Feb 2025 16:58:38 -0800 Subject: [PATCH 133/138] UPSTREAM: pfifo_tail_enqueue: Drop new packet when sch->limit == 0 commit 647cef20e649c576dff271e018d5d15d998b629d upstream. Expected behaviour: In case we reach scheduler's limit, pfifo_tail_enqueue() will drop a packet in scheduler's queue and decrease scheduler's qlen by one. Then, pfifo_tail_enqueue() enqueue new packet and increase scheduler's qlen by one. Finally, pfifo_tail_enqueue() return `NET_XMIT_CN` status code. Weird behaviour: In case we set `sch->limit == 0` and trigger pfifo_tail_enqueue() on a scheduler that has no packet, the 'drop a packet' step will do nothing. This means the scheduler's qlen still has value equal 0. Then, we continue to enqueue new packet and increase scheduler's qlen by one. In summary, we can leverage pfifo_tail_enqueue() to increase qlen by one and return `NET_XMIT_CN` status code. The problem is: Let's say we have two qdiscs: Qdisc_A and Qdisc_B. - Qdisc_A's type must have '->graft()' function to create parent/child relationship. Let's say Qdisc_A's type is `hfsc`. Enqueue packet to this qdisc will trigger `hfsc_enqueue`. - Qdisc_B's type is pfifo_head_drop. Enqueue packet to this qdisc will trigger `pfifo_tail_enqueue`. - Qdisc_B is configured to have `sch->limit == 0`. - Qdisc_A is configured to route the enqueued's packet to Qdisc_B. Enqueue packet through Qdisc_A will lead to: - hfsc_enqueue(Qdisc_A) -> pfifo_tail_enqueue(Qdisc_B) - Qdisc_B->q.qlen += 1 - pfifo_tail_enqueue() return `NET_XMIT_CN` - hfsc_enqueue() check for `NET_XMIT_SUCCESS` and see `NET_XMIT_CN` => hfsc_enqueue() don't increase qlen of Qdisc_A. The whole process lead to a situation where Qdisc_A->q.qlen == 0 and Qdisc_B->q.qlen == 1. Replace 'hfsc' with other type (for example: 'drr') still lead to the same problem. This violate the design where parent's qlen should equal to the sum of its childrens'qlen. Bug impact: This issue can be used for user->kernel privilege escalation when it is reachable. Bug: 395539871 Fixes: 57dbb2d83d10 ("sched: add head drop fifo queue") Reported-by: Quang Le Signed-off-by: Quang Le Signed-off-by: Cong Wang Link: https://patch.msgid.link/20250204005841.223511-2-xiyou.wangcong@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 79a955ea4a2e5ddf4a36328959de0de496419888) Signed-off-by: Lee Jones Change-Id: I94a3851190671bc98666cb659e8419ab2767fb03 --- net/sched/sch_fifo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c index 56f4c1621e44..9de91f69032d 100644 --- a/net/sched/sch_fifo.c +++ b/net/sched/sch_fifo.c @@ -38,6 +38,9 @@ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch, { unsigned int prev_backlog; + if (unlikely(sch->limit == 0)) + return qdisc_drop(skb, sch, to_free); + if (likely(sch->q.qlen < sch->limit)) return qdisc_enqueue_tail(skb, sch); From 923627e8b76f83783cb8dd51f03b6da370258844 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Thu, 13 Mar 2025 23:22:48 +0530 Subject: [PATCH 134/138] FROMGIT: media: venus: hfi_parser: add check to avoid out of bound access There is a possibility that init_codecs is invoked multiple times during manipulated payload from video firmware. In such case, if codecs_count can get incremented to value more than MAX_CODEC_NUM, there can be OOB access. Reset the count so that it always starts from beginning. Cc: stable@vger.kernel.org Fixes: 1a73374a04e5 ("media: venus: hfi_parser: add common capability parser") Reviewed-by: Bryan O'Donoghue CRs-Fixed: 3935643 Change-Id: I6216e773af65082e4775b415789ffd549e0bed2d Git-commit: 172bf5a9ef70a399bb227809db78442dc01d9e48 Git-repo: https://gitlab.freedesktop.org/linux-media/media-committers.git Signed-off-by: Vikash Garodia (cherry picked from commit 91f42e0f9cae5ee5f9d8f4286762c3bfb2e66dd3) --- drivers/media/platform/qcom/venus/hfi_parser.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c index ad22b51765d4..6a8259bcf0be 100644 --- a/drivers/media/platform/qcom/venus/hfi_parser.c +++ b/drivers/media/platform/qcom/venus/hfi_parser.c @@ -19,6 +19,8 @@ static void init_codecs(struct venus_core *core) struct venus_caps *caps = core->caps, *cap; unsigned long bit; + core->codecs_count = 0; + if (hweight_long(core->dec_codecs) + hweight_long(core->enc_codecs) > MAX_CODEC_NUM) return; From 63b1d96ea814749a73b3e63c83e3da21d6fb177f Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Thu, 13 Mar 2025 14:09:16 +0530 Subject: [PATCH 135/138] FROMGIT: media: venus: hfi_parser: refactor hfi packet parsing logic words_count denotes the number of words in total payload, while data points to payload of various property within it. When words_count reaches last word, data can access memory beyond the total payload. This can lead to OOB access. With this patch, the utility api for handling individual properties now returns the size of data consumed. Accordingly remaining bytes are calculated before parsing the payload, thereby eliminates the OOB access possibilities. Cc: stable@vger.kernel.org Fixes: 1a73374a04e5 ("media: venus: hfi_parser: add common capability parser") CRs-Fixed: 3935669 Change-Id: I692e4a8dea110f0650fe26e07207408087a4d19b Git-commit: 9edaaa8e3e15aab1ca413ab50556de1975bcb329 Git-repo: https://gitlab.freedesktop.org/linux-media/media-committers.git Signed-off-by: Vikash Garodia (cherry picked from commit fd9b658c8ab9faa6fbb96004ad4a853c9b30236f) --- .../media/platform/qcom/venus/hfi_parser.c | 99 ++++++++++++++----- 1 file changed, 73 insertions(+), 26 deletions(-) diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c index ad22b51765d4..6b60e9a9b256 100644 --- a/drivers/media/platform/qcom/venus/hfi_parser.c +++ b/drivers/media/platform/qcom/venus/hfi_parser.c @@ -62,7 +62,7 @@ fill_buf_mode(struct venus_caps *cap, const void *data, unsigned int num) cap->cap_bufs_mode_dynamic = true; } -static void +static int parse_alloc_mode(struct venus_core *core, u32 codecs, u32 domain, void *data) { struct hfi_buffer_alloc_mode_supported *mode = data; @@ -70,7 +70,7 @@ parse_alloc_mode(struct venus_core *core, u32 codecs, u32 domain, void *data) u32 *type; if (num_entries > MAX_ALLOC_MODE_ENTRIES) - return; + return -EINVAL; type = mode->data; @@ -82,6 +82,8 @@ parse_alloc_mode(struct venus_core *core, u32 codecs, u32 domain, void *data) type++; } + + return sizeof(*mode); } static void fill_profile_level(struct venus_caps *cap, const void *data, @@ -96,7 +98,7 @@ static void fill_profile_level(struct venus_caps *cap, const void *data, cap->num_pl += num; } -static void +static int parse_profile_level(struct venus_core *core, u32 codecs, u32 domain, void *data) { struct hfi_profile_level_supported *pl = data; @@ -104,12 +106,14 @@ parse_profile_level(struct venus_core *core, u32 codecs, u32 domain, void *data) struct hfi_profile_level pl_arr[HFI_MAX_PROFILE_COUNT] = {}; if (pl->profile_count > HFI_MAX_PROFILE_COUNT) - return; + return -EINVAL; memcpy(pl_arr, proflevel, pl->profile_count * sizeof(*proflevel)); for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain, fill_profile_level, pl_arr, pl->profile_count); + + return pl->profile_count * sizeof(*proflevel) + sizeof(u32); } static void @@ -124,7 +128,7 @@ fill_caps(struct venus_caps *cap, const void *data, unsigned int num) cap->num_caps += num; } -static void +static int parse_caps(struct venus_core *core, u32 codecs, u32 domain, void *data) { struct hfi_capabilities *caps = data; @@ -133,12 +137,14 @@ parse_caps(struct venus_core *core, u32 codecs, u32 domain, void *data) struct hfi_capability caps_arr[MAX_CAP_ENTRIES] = {}; if (num_caps > MAX_CAP_ENTRIES) - return; + return -EINVAL; memcpy(caps_arr, cap, num_caps * sizeof(*cap)); for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain, fill_caps, caps_arr, num_caps); + + return sizeof(*caps); } static void fill_raw_fmts(struct venus_caps *cap, const void *fmts, @@ -153,7 +159,7 @@ static void fill_raw_fmts(struct venus_caps *cap, const void *fmts, cap->num_fmts += num_fmts; } -static void +static int parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data) { struct hfi_uncompressed_format_supported *fmt = data; @@ -162,7 +168,8 @@ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data) struct raw_formats rawfmts[MAX_FMT_ENTRIES] = {}; u32 entries = fmt->format_entries; unsigned int i = 0; - u32 num_planes; + u32 num_planes = 0; + u32 size; while (entries) { num_planes = pinfo->num_planes; @@ -172,7 +179,7 @@ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data) i++; if (i >= MAX_FMT_ENTRIES) - return; + return -EINVAL; if (pinfo->num_planes > MAX_PLANES) break; @@ -184,9 +191,13 @@ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data) for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain, fill_raw_fmts, rawfmts, i); + size = fmt->format_entries * (sizeof(*constr) * num_planes + 2 * sizeof(u32)) + + 2 * sizeof(u32); + + return size; } -static void parse_codecs(struct venus_core *core, void *data) +static int parse_codecs(struct venus_core *core, void *data) { struct hfi_codec_supported *codecs = data; @@ -198,21 +209,27 @@ static void parse_codecs(struct venus_core *core, void *data) core->dec_codecs &= ~HFI_VIDEO_CODEC_SPARK; core->enc_codecs &= ~HFI_VIDEO_CODEC_HEVC; } + + return sizeof(*codecs); } -static void parse_max_sessions(struct venus_core *core, const void *data) +static int parse_max_sessions(struct venus_core *core, const void *data) { const struct hfi_max_sessions_supported *sessions = data; core->max_sessions_supported = sessions->max_sessions; + + return sizeof(*sessions); } -static void parse_codecs_mask(u32 *codecs, u32 *domain, void *data) +static int parse_codecs_mask(u32 *codecs, u32 *domain, void *data) { struct hfi_codec_mask_supported *mask = data; *codecs = mask->codecs; *domain = mask->video_domains; + + return sizeof(*mask); } static void parser_init(struct venus_inst *inst, u32 *codecs, u32 *domain) @@ -246,46 +263,76 @@ static void parser_fini(struct venus_inst *inst, u32 codecs, u32 domain) u32 hfi_parser(struct venus_core *core, struct venus_inst *inst, void *buf, u32 size) { - unsigned int words_count = size >> 2; - u32 *word = buf, *data, codecs = 0, domain = 0; + u32 *words = buf, *payload, codecs = 0, domain = 0; + u32 *frame_size = buf + size; + u32 rem_bytes = size; + int ret; if (size % 4) return HFI_ERR_SYS_INSUFFICIENT_RESOURCES; parser_init(inst, &codecs, &domain); - while (words_count) { - data = word + 1; + while (words < frame_size) { + payload = words + 1; - switch (*word) { + switch (*words) { case HFI_PROPERTY_PARAM_CODEC_SUPPORTED: - parse_codecs(core, data); + if (rem_bytes <= sizeof(struct hfi_codec_supported)) + return HFI_ERR_SYS_INSUFFICIENT_RESOURCES; + + ret = parse_codecs(core, payload); + if (ret < 0) + return HFI_ERR_SYS_INSUFFICIENT_RESOURCES; + init_codecs(core); break; case HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED: - parse_max_sessions(core, data); + if (rem_bytes <= sizeof(struct hfi_max_sessions_supported)) + return HFI_ERR_SYS_INSUFFICIENT_RESOURCES; + + ret = parse_max_sessions(core, payload); break; case HFI_PROPERTY_PARAM_CODEC_MASK_SUPPORTED: - parse_codecs_mask(&codecs, &domain, data); + if (rem_bytes <= sizeof(struct hfi_codec_mask_supported)) + return HFI_ERR_SYS_INSUFFICIENT_RESOURCES; + + ret = parse_codecs_mask(&codecs, &domain, payload); break; case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED: - parse_raw_formats(core, codecs, domain, data); + if (rem_bytes <= sizeof(struct hfi_uncompressed_format_supported)) + return HFI_ERR_SYS_INSUFFICIENT_RESOURCES; + + ret = parse_raw_formats(core, codecs, domain, payload); break; case HFI_PROPERTY_PARAM_CAPABILITY_SUPPORTED: - parse_caps(core, codecs, domain, data); + if (rem_bytes <= sizeof(struct hfi_capabilities)) + return HFI_ERR_SYS_INSUFFICIENT_RESOURCES; + + ret = parse_caps(core, codecs, domain, payload); break; case HFI_PROPERTY_PARAM_PROFILE_LEVEL_SUPPORTED: - parse_profile_level(core, codecs, domain, data); + if (rem_bytes <= sizeof(struct hfi_profile_level_supported)) + return HFI_ERR_SYS_INSUFFICIENT_RESOURCES; + + ret = parse_profile_level(core, codecs, domain, payload); break; case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE_SUPPORTED: - parse_alloc_mode(core, codecs, domain, data); + if (rem_bytes <= sizeof(struct hfi_buffer_alloc_mode_supported)) + return HFI_ERR_SYS_INSUFFICIENT_RESOURCES; + + ret = parse_alloc_mode(core, codecs, domain, payload); break; default: + ret = sizeof(u32); break; } - word++; - words_count--; + if (ret < 0) + return HFI_ERR_SYS_INSUFFICIENT_RESOURCES; + + words += ret / sizeof(u32); + rem_bytes -= ret; } parser_fini(inst, codecs, domain); From a08e1274304de4d1ef884d1195897ba868cbba68 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Tue, 5 Nov 2024 14:24:56 +0530 Subject: [PATCH 136/138] FROMGIT: media: venus: hfi: add check to handle incorrect queue size qsize represents size of shared queued between driver and video firmware. Firmware can modify this value to an invalid large value. In such situation, empty_space will be bigger than the space actually available. Since new_wr_idx is not checked, so the following code will result in an OOB write. ... qsize = qhdr->q_size if (wr_idx >= rd_idx) empty_space = qsize - (wr_idx - rd_idx) .... if (new_wr_idx < qsize) { memcpy(wr_ptr, packet, dwords << 2) --> OOB write Add check to ensure qsize is within the allocated size while reading and writing packets into the queue. Cc: stable@vger.kernel.org Fixes: d96d3f30c0f2 ("[media] media: venus: hfi: add Venus HFI files") Reviewed-by: Bryan O'Donoghue CRs-Fixed: 3935673 Change-Id: Ifb907d4a4c82f853081492e06e68180476367ed5 Git-commit: 69baf245b23e20efda0079238b27fc63ecf13de1 Git-repo: https://gitlab.freedesktop.org/linux-media/media-committers.git Signed-off-by: Vikash Garodia (cherry picked from commit 11f9d2350e2c6bce56f1aa27ffbab7085da38aae) --- drivers/media/platform/qcom/venus/hfi_venus.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c index 306082e25943..2921486c3238 100644 --- a/drivers/media/platform/qcom/venus/hfi_venus.c +++ b/drivers/media/platform/qcom/venus/hfi_venus.c @@ -188,6 +188,9 @@ static int venus_write_queue(struct venus_hfi_device *hdev, /* ensure rd/wr indices's are read from memory */ rmb(); + if (qsize > IFACEQ_QUEUE_SIZE / 4) + return -EINVAL; + if (wr_idx >= rd_idx) empty_space = qsize - (wr_idx - rd_idx); else @@ -256,6 +259,9 @@ static int venus_read_queue(struct venus_hfi_device *hdev, wr_idx = qhdr->write_idx; qsize = qhdr->q_size; + if (qsize > IFACEQ_QUEUE_SIZE / 4) + return -EINVAL; + /* make sure data is valid before using it */ rmb(); From 901a26c51e8bcf814a482dbdd5b1fd5f909af8d0 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Tue, 5 Nov 2024 14:24:57 +0530 Subject: [PATCH 137/138] FROMGIT: media: venus: hfi: add a check to handle OOB in sfr region sfr->buf_size is in shared memory and can be modified by malicious user. OOB write is possible when the size is made higher than actual sfr data buffer. Cap the size to allocated size for such cases. Cc: stable@vger.kernel.org Fixes: d96d3f30c0f2 ("[media] media: venus: hfi: add Venus HFI files") Reviewed-by: Bryan O'Donoghue CRs-Fixed: 3947576 Change-Id: I483a5feff3dfa35dae8f444e57601d2d1d85246f Git-commit: f4b211714bcc70effa60c34d9fa613d182e3ef1e Git-repo: https://gitlab.freedesktop.org/linux-media/media-committers.git Signed-off-by: Vikash Garodia (cherry picked from commit 56820042f93c80d21cd1442b6a6f4d8fa496598c) --- drivers/media/platform/qcom/venus/hfi_venus.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c index 306082e25943..0b6cf86004fd 100644 --- a/drivers/media/platform/qcom/venus/hfi_venus.c +++ b/drivers/media/platform/qcom/venus/hfi_venus.c @@ -970,18 +970,26 @@ static void venus_sfr_print(struct venus_hfi_device *hdev) { struct device *dev = hdev->core->dev; struct hfi_sfr *sfr = hdev->sfr.kva; + u32 size; void *p; if (!sfr) return; - p = memchr(sfr->data, '\0', sfr->buf_size); + size = sfr->buf_size; + if (!size) + return; + + if (size > ALIGNED_SFR_SIZE) + size = ALIGNED_SFR_SIZE; + + p = memchr(sfr->data, '\0', size); /* * SFR isn't guaranteed to be NULL terminated since SYS_ERROR indicates * that Venus is in the process of crashing. */ if (!p) - sfr->data[sfr->buf_size - 1] = '\0'; + sfr->data[size - 1] = '\0'; dev_err_ratelimited(dev, "SFR message from FW: %s\n", sfr->data); } From 7e39477098b50156535c8f910fee50d6dac2a793 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Wed, 15 Jan 2025 17:37:13 -0800 Subject: [PATCH 138/138] UPSTREAM: net: sched: Disallow replacing of child qdisc from one parent to another [ Upstream commit bc50835e83f60f56e9bec2b392fb5544f250fb6f ] Lion Ackermann was able to create a UAF which can be abused for privilege escalation with the following script Step 1. create root qdisc tc qdisc add dev lo root handle 1:0 drr step2. a class for packet aggregation do demonstrate uaf tc class add dev lo classid 1:1 drr step3. a class for nesting tc class add dev lo classid 1:2 drr step4. a class to graft qdisc to tc class add dev lo classid 1:3 drr step5. tc qdisc add dev lo parent 1:1 handle 2:0 plug limit 1024 step6. tc qdisc add dev lo parent 1:2 handle 3:0 drr step7. tc class add dev lo classid 3:1 drr step 8. tc qdisc add dev lo parent 3:1 handle 4:0 pfifo step 9. Display the class/qdisc layout tc class ls dev lo class drr 1:1 root leaf 2: quantum 64Kb class drr 1:2 root leaf 3: quantum 64Kb class drr 3:1 root leaf 4: quantum 64Kb tc qdisc ls qdisc drr 1: dev lo root refcnt 2 qdisc plug 2: dev lo parent 1:1 qdisc pfifo 4: dev lo parent 3:1 limit 1000p qdisc drr 3: dev lo parent 1:2 step10. trigger the bug <=== prevented by this patch tc qdisc replace dev lo parent 1:3 handle 4:0 step 11. Redisplay again the qdiscs/classes tc class ls dev lo class drr 1:1 root leaf 2: quantum 64Kb class drr 1:2 root leaf 3: quantum 64Kb class drr 1:3 root leaf 4: quantum 64Kb class drr 3:1 root leaf 4: quantum 64Kb tc qdisc ls qdisc drr 1: dev lo root refcnt 2 qdisc plug 2: dev lo parent 1:1 qdisc pfifo 4: dev lo parent 3:1 refcnt 2 limit 1000p qdisc drr 3: dev lo parent 1:2 Observe that a) parent for 4:0 does not change despite the replace request. There can only be one parent. b) refcount has gone up by two for 4:0 and c) both class 1:3 and 3:1 are pointing to it. Step 12. send one packet to plug echo "" | socat -u STDIN UDP4-DATAGRAM:127.0.0.1:8888,priority=$((0x10001)) step13. send one packet to the grafted fifo echo "" | socat -u STDIN UDP4-DATAGRAM:127.0.0.1:8888,priority=$((0x10003)) step14. lets trigger the uaf tc class delete dev lo classid 1:3 tc class delete dev lo classid 1:1 The semantics of "replace" is for a del/add _on the same node_ and not a delete from one node(3:1) and add to another node (1:3) as in step10. While we could "fix" with a more complex approach there could be consequences to expectations so the patch takes the preventive approach of "disallow such config". Bug: 393266309 Joint work with Lion Ackermann Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Jamal Hadi Salim Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250116013713.900000-1-kuba@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin (cherry picked from commit deda09c0543a66fa51554abc5ffd723d99b191bf) Signed-off-by: Lee Jones Change-Id: Id94e8dfb543643e489e33f79af990f23580b9121 --- net/sched/sch_api.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index b8dc03a7487e..178044a845df 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -1593,6 +1593,10 @@ replay: q = qdisc_lookup(dev, tcm->tcm_handle); if (!q) goto create_n_graft; + if (q->parent != tcm->tcm_parent) { + NL_SET_ERR_MSG(extack, "Cannot move an existing qdisc to a different parent"); + return -EINVAL; + } if (n->nlmsg_flags & NLM_F_EXCL) { NL_SET_ERR_MSG(extack, "Exclusivity flag on, cannot override"); return -EEXIST;