6.17.13-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainerPATCH 277/507 perf arm_spe: Fix memset subclass in operation
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leo Yan <[email protected]>
[ Upstream commit 33e1fffea492b7158a168914dc0da6aedf78d08e ]
The operation subclass is extracted from bits [7..1] of the payload. Since bit [0] is not parsed, there is no chance to match the memset type (0x25). As a result, the memset payload is never parsed successfully.
Instead of extracting a unified bit field, change to extract the specific bits for each operation subclass.
--- .../arm-spe-decoder/arm-spe-pkt-decoder.c | 25 ++++++------------- .../arm-spe-decoder/arm-spe-pkt-decoder.h | 15 ++++++----- 2 files changed, 14 insertions(+), 26 deletions(-)
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c +7 -18
@@ -357,31 +357,20 @@ static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet,arm_spe_pkt_out_string (&err, &buf, &buf_len," AR" ); } -switch (SPE_OP_PKT_LDST_SUBCLASS_GET (payload)) { -case SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP : +if (SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP (payload))arm_spe_pkt_out_string (&err, &buf, &buf_len," SIMD-FP" ); -break ; -case SPE_OP_PKT_LDST_SUBCLASS_GP_REG : +else if (SPE_OP_PKT_LDST_SUBCLASS_GP_REG (payload))arm_spe_pkt_out_string (&err, &buf, &buf_len," GP-REG" ); -break ; -case SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG : +else if (SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG (payload))arm_spe_pkt_out_string (&err, &buf, &buf_len," UNSPEC-REG" ); -break ; -case SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG : +else if (SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG (payload))arm_spe_pkt_out_string (&err, &buf, &buf_len," NV-SYSREG" ); -break ; -case SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG : +else if (SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG (payload))arm_spe_pkt_out_string (&err, &buf, &buf_len," MTE-TAG" ); -break ; -case SPE_OP_PKT_LDST_SUBCLASS_MEMCPY : +else if (SPE_OP_PKT_LDST_SUBCLASS_MEMCPY (payload))arm_spe_pkt_out_string (&err, &buf, &buf_len," MEMCPY" ); -break ; -case SPE_OP_PKT_LDST_SUBCLASS_MEMSET : +else if (SPE_OP_PKT_LDST_SUBCLASS_MEMSET (payload))arm_spe_pkt_out_string (&err, &buf, &buf_len," MEMSET" ); -break ; -default : -break ; - }if (SPE_OP_PKT_IS_LDST_SVE (payload)) {/* SVE effective vector length */
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h +7 -8
@@ -118,14 +118,13 @@ enum arm_spe_events {#define SPE_OP_PKT_IS_OTHER_SVE_OP (v) (((v) & (BIT(7) | BIT(3) | BIT(0))) == 0x8) -#define SPE_OP_PKT_LDST_SUBCLASS_GET (v) ((v) & GENMASK_ULL(7, 1)) -#define SPE_OP_PKT_LDST_SUBCLASS_GP_REG 0x0 -#define SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP 0x4 -#define SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG 0x10 -#define SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG 0x30 -#define SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG 0x14 -#define SPE_OP_PKT_LDST_SUBCLASS_MEMCPY 0x20 -#define SPE_OP_PKT_LDST_SUBCLASS_MEMSET 0x25 +#define SPE_OP_PKT_LDST_SUBCLASS_GP_REG (v) (((v) & GENMASK_ULL(7, 1)) == 0x0) +#define SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP (v) (((v) & GENMASK_ULL(7, 1)) == 0x4) +#define SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG (v) (((v) & GENMASK_ULL(7, 1)) == 0x10) +#define SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG (v) (((v) & GENMASK_ULL(7, 1)) == 0x30) +#define SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG (v) (((v) & GENMASK_ULL(7, 1)) == 0x14) +#define SPE_OP_PKT_LDST_SUBCLASS_MEMCPY (v) (((v) & GENMASK_ULL(7, 1)) == 0x20) +#define SPE_OP_PKT_LDST_SUBCLASS_MEMSET (v) (((v) & GENMASK_ULL(7, 0)) == 0x25)#define SPE_OP_PKT_IS_LDST_ATOMIC (v) (((v) & (GENMASK_ULL(7, 5) | BIT(1))) == 0x2)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 278/507 pwm: bcm2835: Make sure the channel is enabled after pwm_request()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
[ Upstream commit cda323dbda76600bf9761970d58517648f0de67d ]
The .free callback cleared among others the enable bit PWENx in the control register. When the PWM is requested later again this bit isn't restored but the core assumes the PWM is enabled and thus skips a request to configure the same state as before.
To fix that don't touch the hardware configuration in .free(). For symmetry also drop .request() and configure the mode completely in .apply().
--- drivers/pwm/pwm-bcm2835.c | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-)
drivers/pwm/pwm-bcm2835.c +3 -25
@@ -34,29 +34,6 @@ static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip)return pwmchip_get_drvdata (chip); } -static int bcm2835_pwm_request (struct pwm_chip *chip,struct pwm_device *pwm) -{ -struct bcm2835_pwm *pc =to_bcm2835_pwm (chip); -u32 value; - - value =readl (pc->base +PWM_CONTROL ); - value &= ~(PWM_CONTROL_MASK <<PWM_CONTROL_SHIFT (pwm->hwpwm)); - value |= (PWM_MODE <<PWM_CONTROL_SHIFT (pwm->hwpwm)); -writel (value, pc->base +PWM_CONTROL ); - -return 0 ; -} - -static void bcm2835_pwm_free (struct pwm_chip *chip,struct pwm_device *pwm) -{ -struct bcm2835_pwm *pc =to_bcm2835_pwm (chip); -u32 value; - - value =readl (pc->base +PWM_CONTROL ); - value &= ~(PWM_CONTROL_MASK <<PWM_CONTROL_SHIFT (pwm->hwpwm)); -writel (value, pc->base +PWM_CONTROL ); -} -static int bcm2835_pwm_apply (struct pwm_chip *chip,struct pwm_device *pwm,const struct pwm_state *state) {
@@ -102,6 +79,9 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,/* set polarity */ val =readl (pc->base +PWM_CONTROL ); + val &= ~(PWM_CONTROL_MASK <<PWM_CONTROL_SHIFT (pwm->hwpwm)); + val |=PWM_MODE <<PWM_CONTROL_SHIFT (pwm->hwpwm); +if (state->polarity ==PWM_POLARITY_NORMAL ) val &= ~(PWM_POLARITY <<PWM_CONTROL_SHIFT (pwm->hwpwm));else
@@ -119,8 +99,6 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, }static const struct pwm_ops bcm2835_pwm_ops = { - .request = bcm2835_pwm_request, - .free = bcm2835_pwm_free, .apply = bcm2835_pwm_apply, };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 279/507 scsi: ufs: rockchip: Reset controller on PRE_CHANGE of hce enable notify
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shawn Lin <[email protected]>
[ Upstream commit b0ee72db9132bd19b1b80152b35e0cf6a6cbd9f2 ]
This fixes the dme-reset failed when doing recovery. Because device reset is not enough, we could occasionally see the error below:
ufshcd-rockchip 2a2d0000.ufs: uic cmd 0x14 with arg3 0x0 completion timeout ufshcd-rockchip 2a2d0000.ufs: dme-reset: error code -110 ufshcd-rockchip 2a2d0000.ufs: DME_RESET failed
ufshcd-rockchip 2a2d0000.ufs: ufshcd_host_reset_and_restore: Host init failed -110
Fix this by resetting the controller on PRE_CHANGE stage of hce enable notify.
--- drivers/ufs/host/ufs-rockchip.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
drivers/ufs/host/ufs-rockchip.c +13 -6
@@ -20,9 +20,17 @@#include "ufshcd-pltfrm.h" #include "ufs-rockchip.h" +static void ufs_rockchip_controller_reset (struct ufs_rockchip_host *host) +{ +reset_control_assert (host->rst); +udelay (1 ); +reset_control_deassert (host->rst); +} +static int ufs_rockchip_hce_enable_notify (struct ufs_hba *hba,enum ufs_notify_change_status status) { +struct ufs_rockchip_host *host =ufshcd_get_variant (hba);int err =0 ;if (status ==POST_CHANGE ) {
@@ -37,6 +45,9 @@ static int ufs_rockchip_hce_enable_notify(struct ufs_hba *hba,return ufshcd_vops_phy_initialization (hba); } +/* PRE_CHANGE */ +ufs_rockchip_controller_reset (host); +return 0 ; }
@@ -156,9 +167,7 @@ static int ufs_rockchip_common_init(struct ufs_hba *hba)return dev_err_probe (dev,PTR_ERR (host->rst),"failed to get reset control\n" ); -reset_control_assert (host->rst); -udelay (1 ); -reset_control_deassert (host->rst); +ufs_rockchip_controller_reset (host); host->ref_out_clk =devm_clk_get_enabled (dev,"ref_out" );if (IS_ERR (host->ref_out_clk))
@@ -282,9 +291,7 @@ static int ufs_rockchip_runtime_resume(struct device *dev)return err; } -reset_control_assert (host->rst); -udelay (1 ); -reset_control_deassert (host->rst); +ufs_rockchip_controller_reset (host);return ufshcd_runtime_resume (dev); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 280/507 scsi: qla2xxx: Fix improper freeing of purex item
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zilin Guan <[email protected]>
[ Upstream commit 78b1a242fe612a755f2158fd206ee6bb577d18ca ]
In qla2xxx_process_purls_iocb(), an item is allocated via qla27xx_copy_multiple_pkt(), which internally calls qla24xx_alloc_purex_item().
The qla24xx_alloc_purex_item() function may return a pre-allocated item from a per-adapter pool for small allocations, instead of dynamically allocating memory with kzalloc().
An error handling path in qla2xxx_process_purls_iocb() incorrectly uses kfree() to release the item. If the item was from the pre-allocated pool, calling kfree() on it is a bug that can lead to memory corruption.
Fix this by using the correct deallocation function, qla24xx_free_purex_item(), which properly handles both dynamically allocated and pre-allocated items.
--- drivers/scsi/qla2xxx/qla_nvme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/qla2xxx/qla_nvme.c +1 -1
@@ -1292,7 +1292,7 @@ void qla2xxx_process_purls_iocb(void **pkt, struct rsp_que **rsp) a.reason =FCNVME_RJT_RC_LOGIC ; a.explanation =FCNVME_RJT_EXP_NONE ; xmt_reject = true; -kfree (item); +qla24xx_free_purex_item (item); goto out; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 281/507 net: phy: realtek: create rtl8211f_config_rgmii_delay()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean <[email protected]>
[ Upstream commit 8e982441ba601d982dd0739972115d85ae01d99b ]
The control flow in rtl8211f_config_init() has some pitfalls which were probably unintended. Specifically it has an early return:
switch (phydev->interface) {
...
default: /* the rest of the modes imply leaving delay as is. */
return 0;
}which exits the entire config_init() function. This means it also skips doing things such as disabling CLKOUT or disabling PHY-mode EEE.
For the RTL8211FS, which uses PHY_INTERFACE_MODE_SGMII, this might be a problem. However, I don't know that it is, so there is no Fixes: tag. The issue was observed through code inspection.
--- drivers/net/phy/realtek/realtek_main.c | 65 +++++++++++++++----------- 1 file changed, 39 insertions(+), 26 deletions(-)
drivers/net/phy/realtek/realtek_main.c +39 -26
@@ -516,22 +516,11 @@ static int rtl8211c_config_init(struct phy_device *phydev) CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER); } -static int rtl8211f_config_init (struct phy_device *phydev) +static int rtl8211f_config_rgmii_delay (struct phy_device *phydev) { -struct rtl821x_priv *priv = phydev->priv; -struct device *dev = &phydev->mdio.dev;u16 val_txdly, val_rxdly;int ret; - ret =phy_modify_paged_changed (phydev,RTL8211F_PHYCR_PAGE ,RTL8211F_PHYCR1 , -RTL8211F_ALDPS_PLL_OFF |RTL8211F_ALDPS_ENABLE |RTL8211F_ALDPS_XTAL_OFF , - priv->phycr1); -if (ret <0 ) { -dev_err (dev,"aldps mode configuration failed: %pe\n" , -ERR_PTR (ret)); -return ret; - } -switch (phydev->interface) {case PHY_INTERFACE_MODE_RGMII : val_txdly =0 ;
@@ -561,34 +550,58 @@ static int rtl8211f_config_init(struct phy_device *phydev)RTL8211F_TXCR ,RTL8211F_TX_DELAY , val_txdly);if (ret <0 ) { -dev_err (dev,"Failed to update the TX delay register\n" ); +phydev_err (phydev,"Failed to update the TX delay register: %pe\n" , +ERR_PTR (ret));return ret; }else if (ret) { -dev_dbg (dev, -"%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n" , -str_enable_disable (val_txdly)); +phydev_dbg (phydev, +"%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n" , +str_enable_disable (val_txdly)); }else { -dev_dbg (dev, -"2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n" , -str_enabled_disabled (val_txdly)); +phydev_dbg (phydev, +"2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n" , +str_enabled_disabled (val_txdly)); } ret =phy_modify_paged_changed (phydev,RTL8211F_RGMII_PAGE ,RTL8211F_RXCR ,RTL8211F_RX_DELAY , val_rxdly);if (ret <0 ) { -dev_err (dev,"Failed to update the RX delay register\n" ); +phydev_err (phydev,"Failed to update the RX delay register: %pe\n" , +ERR_PTR (ret));return ret; }else if (ret) { -dev_dbg (dev, -"%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n" , -str_enable_disable (val_rxdly)); +phydev_dbg (phydev, +"%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n" , +str_enable_disable (val_rxdly)); }else { -dev_dbg (dev, -"2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n" , -str_enabled_disabled (val_rxdly)); +phydev_dbg (phydev, +"2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n" , +str_enabled_disabled (val_rxdly)); } +return 0 ; +} + +static int rtl8211f_config_init (struct phy_device *phydev) +{ +struct rtl821x_priv *priv = phydev->priv; +struct device *dev = &phydev->mdio.dev; +int ret; + + ret =phy_modify_paged_changed (phydev,RTL8211F_PHYCR_PAGE ,RTL8211F_PHYCR1 , +RTL8211F_ALDPS_PLL_OFF |RTL8211F_ALDPS_ENABLE |RTL8211F_ALDPS_XTAL_OFF , + priv->phycr1); +if (ret <0 ) { +dev_err (dev,"aldps mode configuration failed: %pe\n" , +ERR_PTR (ret)); +return ret; + } + + ret =rtl8211f_config_rgmii_delay (phydev); +if (ret) +return ret; +if (!priv->has_phycr2)return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 282/507 iommu/vt-d: Fix unused invalidation hint in qi_desc_iotlb
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aashish Sharma <[email protected]>
[ Upstream commit 6b38a108eeb3936b21643191db535a35dd7c890b ]
Invalidation hint (ih) in the function 'qi_desc_iotlb' is initialized to zero and never used. It is embedded in the 0th bit of the 'addr' parameter. Get the correct 'ih' value from there.
--- drivers/iommu/intel/iommu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/intel/iommu.h +1 -1
@@ -1100,7 +1100,7 @@ static inline void qi_desc_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, struct qi_desc *desc) {u8 dw =0 , dr =0 ; -int ih =0 ; +int ih = addr &1 ;if (cap_write_drain (iommu->cap)) dw =1 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 283/507 wifi: mac80211: fix CMAC functions not handling errors
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chien Wong <[email protected]>
[ Upstream commit 353cda30d30e5dc7cacf8de5d2546724708ae3bb ]
The called hash functions could fail thus we should check return values.
--- net/mac80211/aes_cmac.c | 63 +++++++++++++++++++++++++++++------------ net/mac80211/aes_cmac.h | 8 +++--- net/mac80211/wpa.c | 20 +++++++------ 3 files changed, 61 insertions(+), 30 deletions(-)
net/mac80211/aes_cmac.c +45 -18
@@ -22,50 +22,77 @@static const u8 zero[CMAC_TLEN_256 ]; -void ieee80211_aes_cmac (struct crypto_shash *tfm,const u8 *aad, -const u8 *data,size_t data_len,u8 *mic) +int ieee80211_aes_cmac (struct crypto_shash *tfm,const u8 *aad, +const u8 *data,size_t data_len,u8 *mic) { +int err;SHASH_DESC_ON_STACK (desc, tfm);u8 out[AES_BLOCK_SIZE ];const __le16 *fc; desc->tfm = tfm; -crypto_shash_init (desc); -crypto_shash_update (desc, aad,AAD_LEN ); + err =crypto_shash_init (desc); +if (err) +return err; + err =crypto_shash_update (desc, aad,AAD_LEN ); +if (err) +return err; fc = (const __le16 *)aad;if (ieee80211_is_beacon (*fc)) {/* mask Timestamp field to zero */ -crypto_shash_update (desc, zero,8 ); -crypto_shash_update (desc, data +8 , data_len -8 -CMAC_TLEN ); + err =crypto_shash_update (desc, zero,8 ); +if (err) +return err; + err =crypto_shash_update (desc, data +8 , + data_len -8 -CMAC_TLEN ); +if (err) +return err; }else { -crypto_shash_update (desc, data, data_len -CMAC_TLEN ); + err =crypto_shash_update (desc, data, + data_len -CMAC_TLEN ); +if (err) +return err; } -crypto_shash_finup (desc, zero,CMAC_TLEN , out); - + err =crypto_shash_finup (desc, zero,CMAC_TLEN , out); +if (err) +return err;memcpy (mic, out,CMAC_TLEN ); + +return 0 ; } -void ieee80211_aes_cmac_256 (struct crypto_shash *tfm,const u8 *aad, -const u8 *data,size_t data_len,u8 *mic) +int ieee80211_aes_cmac_256 (struct crypto_shash *tfm,const u8 *aad, +const u8 *data,size_t data_len,u8 *mic) { +int err;SHASH_DESC_ON_STACK (desc, tfm);const __le16 *fc; desc->tfm = tfm; -crypto_shash_init (desc); -crypto_shash_update (desc, aad,AAD_LEN ); + err =crypto_shash_init (desc); +if (err) +return err; + err =crypto_shash_update (desc, aad,AAD_LEN ); +if (err) +return err; fc = (const __le16 *)aad;if (ieee80211_is_beacon (*fc)) {/* mask Timestamp field to zero */ -crypto_shash_update (desc, zero,8 ); -crypto_shash_update (desc, data +8 , - data_len -8 -CMAC_TLEN_256 ); + err =crypto_shash_update (desc, zero,8 ); +if (err) +return err; + err =crypto_shash_update (desc, data +8 , + data_len -8 -CMAC_TLEN_256 ); +if (err) +return err; }else { -crypto_shash_update (desc, data, data_len -CMAC_TLEN_256 ); + err =crypto_shash_update (desc, data, data_len -CMAC_TLEN_256 ); +if (err) +return err; } -crypto_shash_finup (desc, zero,CMAC_TLEN_256 , mic); +return crypto_shash_finup (desc, zero,CMAC_TLEN_256 , mic); } struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[],
net/mac80211/aes_cmac.h +4 -4
@@ -11,10 +11,10 @@struct crypto_shash *ieee80211_aes_cmac_key_setup (const u8 key[],size_t key_len); -void ieee80211_aes_cmac (struct crypto_shash *tfm,const u8 *aad, -const u8 *data,size_t data_len,u8 *mic); -void ieee80211_aes_cmac_256 (struct crypto_shash *tfm,const u8 *aad, -const u8 *data,size_t data_len,u8 *mic); +int ieee80211_aes_cmac (struct crypto_shash *tfm,const u8 *aad, +const u8 *data,size_t data_len,u8 *mic); +int ieee80211_aes_cmac_256 (struct crypto_shash *tfm,const u8 *aad, +const u8 *data,size_t data_len,u8 *mic);void ieee80211_aes_cmac_key_free (struct crypto_shash *tfm);#endif /* AES_CMAC_H */
net/mac80211/wpa.c +12 -8
@@ -869,8 +869,9 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx)/* * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) */ -ieee80211_aes_cmac (key->u.aes_cmac.tfm, aad, - skb->data +24 , skb->len -24 , mmie->mic); +if (ieee80211_aes_cmac (key->u.aes_cmac.tfm, aad, + skb->data +24 , skb->len -24 , mmie->mic)) +return TX_DROP ;return TX_CONTINUE ; }
@@ -916,8 +917,9 @@ ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx)/* MIC = AES-256-CMAC(IGTK, AAD || Management Frame Body || MMIE, 128) */ -ieee80211_aes_cmac_256 (key->u.aes_cmac.tfm, aad, - skb->data +24 , skb->len -24 , mmie->mic); +if (ieee80211_aes_cmac_256 (key->u.aes_cmac.tfm, aad, + skb->data +24 , skb->len -24 , mmie->mic)) +return TX_DROP ;return TX_CONTINUE ; }
@@ -956,8 +958,9 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)if (!(status->flag &RX_FLAG_DECRYPTED )) {/* hardware didn't decrypt/verify MIC */ bip_aad (skb, aad); -ieee80211_aes_cmac (key->u.aes_cmac.tfm, aad, - skb->data +24 , skb->len -24 , mic); +if (ieee80211_aes_cmac (key->u.aes_cmac.tfm, aad, + skb->data +24 , skb->len -24 , mic)) +return RX_DROP_U_DECRYPT_FAIL ;if (crypto_memneq (mic, mmie->mic,sizeof (mmie->mic))) { key->u.aes_cmac.icverrors++;return RX_DROP_U_MIC_FAIL ;
@@ -1006,8 +1009,9 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)if (!(status->flag &RX_FLAG_DECRYPTED )) {/* hardware didn't decrypt/verify MIC */ bip_aad (skb, aad); -ieee80211_aes_cmac_256 (key->u.aes_cmac.tfm, aad, - skb->data +24 , skb->len -24 , mic); +if (ieee80211_aes_cmac_256 (key->u.aes_cmac.tfm, aad, + skb->data +24 , skb->len -24 , mic)) +return RX_DROP_U_DECRYPT_FAIL ;if (crypto_memneq (mic, mmie->mic,sizeof (mmie->mic))) { key->u.aes_cmac.icverrors++;return RX_DROP_U_MIC_FAIL ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 284/507 mfd: mt6397-irq: Fix missing irq_domain_remove() in error path
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit b4b1bd1f330fdd13706382be6c90ce9f58cee3f5 ]
If devm_request_threaded_irq() fails after irq_domain_create_linear() succeeds in mt6397_irq_init(), the function returns without removing the created IRQ domain, leading to a resource leak.
Call irq_domain_remove() in the error path after a successful irq_domain_create_linear() to properly release the IRQ domain.
--- drivers/mfd/mt6397-irq.c | 1 + 1 file changed, 1 insertion(+)
drivers/mfd/mt6397-irq.c +1 -0
@@ -229,6 +229,7 @@ int mt6397_irq_init(struct mt6397_chip *chip)if (ret) {dev_err (chip->dev,"failed to register irq=%d; err: %d\n" , chip->irq, ret); +irq_domain_remove (chip->irq_domain);return ret; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 285/507 mfd: mt6358-irq: Fix missing irq_domain_remove() in error path
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 384bd58bf7095e4c4c8fcdbcede316ef342c630c ]
If devm_request_threaded_irq() fails after irq_domain_add_linear() succeeds in mt6358_irq_init(), the function returns without removing the created IRQ domain, leading to a resource leak.
Call irq_domain_remove() in the error path after a successful irq_domain_add_linear() to properly release the IRQ domain.
--- drivers/mfd/mt6358-irq.c | 1 + 1 file changed, 1 insertion(+)
drivers/mfd/mt6358-irq.c +1 -0
@@ -285,6 +285,7 @@ int mt6358_irq_init(struct mt6397_chip *chip)if (ret) {dev_err (chip->dev,"Failed to register IRQ=%d, ret=%d\n" , chip->irq, ret); +irq_domain_remove (chip->irq_domain);return ret; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 286/507 of/fdt: Consolidate duplicate code into helper functions
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuntao Wang <[email protected]>
[ Upstream commit 8278cb72c60399f6dc6300c409879fb4c7291513 ]
Currently, there are many pieces of nearly identical code scattered across different places. Consolidate the duplicate code into helper functions to improve maintainability and reduce the likelihood of errors.
Stable-dep-of: c85da64ce2c3 ("of/fdt: Fix incorrect use of dt_root_addr_cells in early_init_dt_check_kho()")
--- drivers/of/fdt.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/linux/of_fdt.h | 9 +++++++++ 2 files changed, 50 insertions(+)
drivers/of/fdt.c +41 -0
@@ -625,6 +625,47 @@ const void *__init of_get_flat_dt_prop(unsigned long node, const char *name,return fdt_getprop (initial_boot_params, node, name, size); } +const __be32 *__init of_flat_dt_get_addr_size_prop (unsigned long node, +const char *name, +int *entries) +{ +const __be32 *prop; +int len, elen = (dt_root_addr_cells + dt_root_size_cells) *sizeof (__be32); + + prop =of_get_flat_dt_prop (node, name, &len); +if (!prop || len % elen) { + *entries =0 ; +return NULL ; + } + + *entries = len / elen; +return prop; +} + +bool __init of_flat_dt_get_addr_size (unsigned long node,const char *name, +u64 *addr,u64 *size) +{ +const __be32 *prop; +int entries; + + prop =of_flat_dt_get_addr_size_prop (node, name, &entries); +if (!prop || entries !=1 ) +return false; + +of_flat_dt_read_addr_size (prop,0 , addr, size); +return true; +} + +void __init of_flat_dt_read_addr_size (const __be32 *prop,int entry_index, +u64 *addr,u64 *size) +{ +int entry_cells = dt_root_addr_cells + dt_root_size_cells; + prop += entry_cells * entry_index; + + *addr =dt_mem_next_cell (dt_root_addr_cells, &prop); + *size =dt_mem_next_cell (dt_root_size_cells, &prop); +} +/** * of_fdt_is_compatible - Return true if given node from the given blob has * compat in its compatible list
include/linux/of_fdt.h +9 -0
@@ -55,6 +55,15 @@ extern int of_get_flat_dt_subnode_by_name(unsigned long node, const char *uname);extern const void *of_get_flat_dt_prop (unsigned long node,const char *name,int *size); + +extern const __be32 *of_flat_dt_get_addr_size_prop (unsigned long node, +const char *name, +int *entries); +extern bool of_flat_dt_get_addr_size (unsigned long node,const char *name, +u64 *addr,u64 *size); +extern void of_flat_dt_read_addr_size (const __be32 *prop,int entry_index, +u64 *addr,u64 *size); +extern int of_flat_dt_is_compatible (unsigned long node,const char *name);extern unsigned long of_get_flat_dt_root (void );extern uint32_t of_get_flat_dt_phandle (unsigned long node);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 287/507 of/fdt: Fix incorrect use of dt_root_addr_cells in early_init_dt_check_kho()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuntao Wang <[email protected]>
[ Upstream commit c85da64ce2c36bba469f6feede9ca768f0361741 ]
When reading the fdt_size value, the argument passed to dt_mem_next_cell() is dt_root_addr_cells, but it should be dt_root_size_cells.
The same issue occurs when reading the scratch_size value.
Use a helper function to simplify the code and fix these issues.
--- drivers/of/fdt.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-)
drivers/of/fdt.c +4 -12
@@ -924,26 +924,18 @@ static void __init early_init_dt_check_kho(void) {unsigned long node = chosen_node_offset;u64 fdt_start, fdt_size, scratch_start, scratch_size; -const __be32 *p; -int l;if (!IS_ENABLED (CONFIG_KEXEC_HANDOVER ) || (long )node <0 )return ; - p =of_get_flat_dt_prop (node,"linux,kho-fdt" , &l); -if (l != (dt_root_addr_cells + dt_root_size_cells) *sizeof (__be32)) +if (!of_flat_dt_get_addr_size (node,"linux,kho-fdt" , + &fdt_start, &fdt_size))return ; - fdt_start =dt_mem_next_cell (dt_root_addr_cells, &p); - fdt_size =dt_mem_next_cell (dt_root_addr_cells, &p); - - p =of_get_flat_dt_prop (node,"linux,kho-scratch" , &l); -if (l != (dt_root_addr_cells + dt_root_size_cells) *sizeof (__be32)) +if (!of_flat_dt_get_addr_size (node,"linux,kho-scratch" , + &scratch_start, &scratch_size))return ; - scratch_start =dt_mem_next_cell (dt_root_addr_cells, &p); - scratch_size =dt_mem_next_cell (dt_root_addr_cells, &p); -kho_populate (fdt_start, fdt_size, scratch_start, scratch_size); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 288/507 leds: rgb: leds-qcom-lpg: Dont enable TRILED when configuring PWM
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fenglin Wu <[email protected]>
[ Upstream commit 072cd5f458d76b9e15d89ebdaea8b5cb1312eeef ]
The PWM signal from the LPG channel can be routed to PMIC GPIOs with proper GPIO configuration, and it is not necessary to enable the TRILED channel in that case. This also applies to the LPG channels that mapped to TRILED channels. Additionally, enabling the TRILED channel unnecessarily would cause a voltage increase in its power supply. Hence remove it.
--- drivers/leds/rgb/leds-qcom-lpg.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/leds/rgb/leds-qcom-lpg.c +1 -3
@@ -2,7 +2,7 @@/* * Copyright (c) 2017-2022 Linaro Ltd * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. -* Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. +* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include <linux/bits.h> #include <linux/bitfield.h>
@@ -1247,8 +1247,6 @@ static int lpg_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,lpg_apply (chan); -triled_set (lpg, chan->triled_mask, chan->enabled ? chan->triled_mask :0 ); - out_unlock:mutex_unlock (&lpg->lock);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 289/507 phy: renesas: rcar-gen3-usb2: Fix an error handling path in rcar_gen3_phy_usb2_probe()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
[ Upstream commit 662bb179d3381c7c069e44bb177396bcaee31cc8 ]
If an error occurs after the reset_control_deassert(), reset_control_assert() must be called, as already done in the remove function.
Use devm_add_action_or_reset() to add the missing call and simplify the .remove() function accordingly.
While at it, drop struct rcar_gen3_chan::rstc as it is not used aymore.
[claudiu.beznea: removed "struct reset_control *rstc = data;" from
rcar_gen3_reset_assert(), dropped struct rcar_gen3_chan::rstc]
--- drivers/phy/renesas/phy-rcar-gen3-usb2.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
drivers/phy/renesas/phy-rcar-gen3-usb2.c +14 -6
@@ -125,7 +125,6 @@ struct rcar_gen3_chan {struct extcon_dev *extcon;struct rcar_gen3_phy rphys[NUM_OF_PHYS ];struct regulator *vbus; -struct reset_control *rstc;struct work_struct work;spinlock_t lock;/* protects access to hardware and driver data structure. */ enum usb_dr_mode dr_mode;
@@ -699,21 +698,31 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np)return candidate; } +static void rcar_gen3_reset_assert (void *data) +{ +reset_control_assert (data); +} +static int rcar_gen3_phy_usb2_init_bus (struct rcar_gen3_chan *channel) {struct device *dev = channel->dev; +struct reset_control *rstc;int ret;u32 val; - channel->rstc =devm_reset_control_array_get_shared (dev); -if (IS_ERR (channel->rstc)) -return PTR_ERR (channel->rstc); + rstc =devm_reset_control_array_get_shared (dev); +if (IS_ERR (rstc)) +return PTR_ERR (rstc); ret =pm_runtime_resume_and_get (dev);if (ret)return ret; - ret =reset_control_deassert (channel->rstc); + ret =reset_control_deassert (rstc); +if (ret) + goto rpm_put; + + ret =devm_add_action_or_reset (dev, rcar_gen3_reset_assert, rstc);if (ret) goto rpm_put;
@@ -860,7 +869,6 @@ static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev)if (channel->is_otg_channel)device_remove_file (&pdev->dev, &dev_attr_role); -reset_control_assert (channel->rstc);pm_runtime_disable (&pdev->dev); };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 290/507 phy: rockchip: naneng-combphy: Add SoC prefix to register definitions
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yao Zi <[email protected]>
[ Upstream commit b3bbc6afcff50e2fd4d51dd64929e62d66fdc814 ]
All supported variants of naneng-combphy follow a register layout similar to the RK3568 variant with some exceptions of SoC-specific registers.
Add RK3568 prefix for the common set of registers and the corresponding SoC prefix for SoC-specific registers, making usage of definitions clear and preparing for future COMBPHY variants with a different register layout.
Stable-dep-of: be866e68966d ("phy: rockchip: naneng-combphy: Fix PCIe L1ss support RK3562")
--- .../rockchip/phy-rockchip-naneng-combphy.c | 560 +++++++++--------- 1 file changed, 288 insertions(+), 272 deletions(-)
drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +288 -272
@@ -21,78 +21,80 @@#define REF_CLOCK_100MHz (100 * HZ_PER_MHZ)/* COMBO PHY REG */ -#define PHYREG6 0x14 -#define PHYREG6_PLL_DIV_MASK GENMASK(7, 6) -#define PHYREG6_PLL_DIV_SHIFT 6 -#define PHYREG6_PLL_DIV_2 1 - -#define PHYREG7 0x18 -#define PHYREG7_TX_RTERM_MASK GENMASK(7, 4) -#define PHYREG7_TX_RTERM_SHIFT 4 -#define PHYREG7_TX_RTERM_50OHM 8 -#define PHYREG7_RX_RTERM_MASK GENMASK(3, 0) -#define PHYREG7_RX_RTERM_SHIFT 0 -#define PHYREG7_RX_RTERM_44OHM 15 - -#define PHYREG8 0x1C -#define PHYREG8_SSC_EN BIT(4) - -#define PHYREG10 0x24 -#define PHYREG10_SSC_PCM_MASK GENMASK(3, 0) -#define PHYREG10_SSC_PCM_3500PPM 7 - -#define PHYREG11 0x28 -#define PHYREG11_SU_TRIM_0_7 0xF0 - -#define PHYREG12 0x2C -#define PHYREG12_PLL_LPF_ADJ_VALUE 4 - -#define PHYREG13 0x30 -#define PHYREG13_RESISTER_MASK GENMASK(5, 4) -#define PHYREG13_RESISTER_SHIFT 0x4 -#define PHYREG13_RESISTER_HIGH_Z 3 -#define PHYREG13_CKRCV_AMP0 BIT(7) - -#define PHYREG14 0x34 -#define PHYREG14_CKRCV_AMP1 BIT(0) - -#define PHYREG15 0x38 -#define PHYREG15_CTLE_EN BIT(0) -#define PHYREG15_SSC_CNT_MASK GENMASK(7, 6) -#define PHYREG15_SSC_CNT_SHIFT 6 -#define PHYREG15_SSC_CNT_VALUE 1 - -#define PHYREG16 0x3C -#define PHYREG16_SSC_CNT_VALUE 0x5f - -#define PHYREG17 0x40 - -#define PHYREG18 0x44 -#define PHYREG18_PLL_LOOP 0x32 - -#define PHYREG21 0x50 -#define PHYREG21_RX_SQUELCH_VAL 0x0D - -#define PHYREG27 0x6C -#define PHYREG27_RX_TRIM_RK3588 0x4C - -#define PHYREG30 0x74 - -#define PHYREG32 0x7C -#define PHYREG32_SSC_MASK GENMASK(7, 4) -#define PHYREG32_SSC_DIR_MASK GENMASK(5, 4) -#define PHYREG32_SSC_DIR_SHIFT 4 -#define PHYREG32_SSC_UPWARD 0 -#define PHYREG32_SSC_DOWNWARD 1 -#define PHYREG32_SSC_OFFSET_MASK GENMASK(7, 6) -#define PHYREG32_SSC_OFFSET_SHIFT 6 -#define PHYREG32_SSC_OFFSET_500PPM 1 - -#define PHYREG33 0x80 -#define PHYREG33_PLL_KVCO_MASK GENMASK(4, 2) -#define PHYREG33_PLL_KVCO_SHIFT 2 -#define PHYREG33_PLL_KVCO_VALUE 2 -#define PHYREG33_PLL_KVCO_VALUE_RK3576 4 +#define RK3568_PHYREG6 0x14 +#define RK3568_PHYREG6_PLL_DIV_MASK GENMASK(7, 6) +#define RK3568_PHYREG6_PLL_DIV_SHIFT 6 +#define RK3568_PHYREG6_PLL_DIV_2 1 + +#define RK3568_PHYREG7 0x18 +#define RK3568_PHYREG7_TX_RTERM_MASK GENMASK(7, 4) +#define RK3568_PHYREG7_TX_RTERM_SHIFT 4 +#define RK3568_PHYREG7_TX_RTERM_50OHM 8 +#define RK3568_PHYREG7_RX_RTERM_MASK GENMASK(3, 0) +#define RK3568_PHYREG7_RX_RTERM_SHIFT 0 +#define RK3568_PHYREG7_RX_RTERM_44OHM 15 + +#define RK3568_PHYREG8 0x1C +#define RK3568_PHYREG8_SSC_EN BIT(4) + +#define RK3568_PHYREG11 0x28 +#define RK3568_PHYREG11_SU_TRIM_0_7 0xF0 + +#define RK3568_PHYREG12 0x2C +#define RK3568_PHYREG12_PLL_LPF_ADJ_VALUE 4 + +#define RK3568_PHYREG13 0x30 +#define RK3568_PHYREG13_RESISTER_MASK GENMASK(5, 4) +#define RK3568_PHYREG13_RESISTER_SHIFT 0x4 +#define RK3568_PHYREG13_RESISTER_HIGH_Z 3 +#define RK3568_PHYREG13_CKRCV_AMP0 BIT(7) + +#define RK3568_PHYREG14 0x34 +#define RK3568_PHYREG14_CKRCV_AMP1 BIT(0) + +#define RK3568_PHYREG15 0x38 +#define RK3568_PHYREG15_CTLE_EN BIT(0) +#define RK3568_PHYREG15_SSC_CNT_MASK GENMASK(7, 6) +#define RK3568_PHYREG15_SSC_CNT_SHIFT 6 +#define RK3568_PHYREG15_SSC_CNT_VALUE 1 + +#define RK3568_PHYREG16 0x3C +#define RK3568_PHYREG16_SSC_CNT_VALUE 0x5f + +#define RK3568_PHYREG18 0x44 +#define RK3568_PHYREG18_PLL_LOOP 0x32 + +#define RK3568_PHYREG32 0x7C +#define RK3568_PHYREG32_SSC_MASK GENMASK(7, 4) +#define RK3568_PHYREG32_SSC_DIR_MASK GENMASK(5, 4) +#define RK3568_PHYREG32_SSC_DIR_SHIFT 4 +#define RK3568_PHYREG32_SSC_UPWARD 0 +#define RK3568_PHYREG32_SSC_DOWNWARD 1 +#define RK3568_PHYREG32_SSC_OFFSET_MASK GENMASK(7, 6) +#define RK3568_PHYREG32_SSC_OFFSET_SHIFT 6 +#define RK3568_PHYREG32_SSC_OFFSET_500PPM 1 + +#define RK3568_PHYREG33 0x80 +#define RK3568_PHYREG33_PLL_KVCO_MASK GENMASK(4, 2) +#define RK3568_PHYREG33_PLL_KVCO_SHIFT 2 +#define RK3568_PHYREG33_PLL_KVCO_VALUE 2 +#define RK3576_PHYREG33_PLL_KVCO_VALUE 4 + +/* RK3588 COMBO PHY registers */ +#define RK3588_PHYREG27 0x6C +#define RK3588_PHYREG27_RX_TRIM 0x4C + +/* RK3576 COMBO PHY registers */ +#define RK3576_PHYREG10 0x24 +#define RK3576_PHYREG10_SSC_PCM_MASK GENMASK(3, 0) +#define RK3576_PHYREG10_SSC_PCM_3500PPM 7 + +#define RK3576_PHYREG17 0x40 + +#define RK3576_PHYREG21 0x50 +#define RK3576_PHYREG21_RX_SQUELCH_VAL 0x0D + +#define RK3576_PHYREG30 0x74struct rockchip_combphy_priv ;
@@ -407,9 +409,8 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv)switch (priv->type) {case PHY_TYPE_PCIE :/* Set SSC downward spread spectrum */ -rockchip_combphy_updatel (priv,PHYREG32_SSC_MASK , -PHYREG32_SSC_DOWNWARD <<PHYREG32_SSC_DIR_SHIFT , -PHYREG32 ); + val =RK3568_PHYREG32_SSC_DOWNWARD <<RK3568_PHYREG32_SSC_DIR_SHIFT ; +rockchip_combphy_updatel (priv,RK3568_PHYREG32_SSC_MASK , val,RK3568_PHYREG32 );rockchip_combphy_param_write (priv->phy_grf, &cfg->con0_for_pcie, true);rockchip_combphy_param_write (priv->phy_grf, &cfg->con1_for_pcie, true);
@@ -418,29 +419,30 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv)break ;case PHY_TYPE_USB3 :/* Set SSC downward spread spectrum */ -rockchip_combphy_updatel (priv,PHYREG32_SSC_MASK , -PHYREG32_SSC_DOWNWARD <<PHYREG32_SSC_DIR_SHIFT , -PHYREG32 ); + val =RK3568_PHYREG32_SSC_DOWNWARD <<RK3568_PHYREG32_SSC_DIR_SHIFT ; +rockchip_combphy_updatel (priv,RK3568_PHYREG32_SSC_MASK , val, +RK3568_PHYREG32 );/* Enable adaptive CTLE for USB3.0 Rx */ -rockchip_combphy_updatel (priv,PHYREG15_CTLE_EN , -PHYREG15_CTLE_EN ,PHYREG15 ); +rockchip_combphy_updatel (priv,RK3568_PHYREG15_CTLE_EN , +RK3568_PHYREG15_CTLE_EN ,RK3568_PHYREG15 );/* Set PLL KVCO fine tuning signals */ -rockchip_combphy_updatel (priv,PHYREG33_PLL_KVCO_MASK ,BIT (3 ),PHYREG33 ); +rockchip_combphy_updatel (priv,RK3568_PHYREG33_PLL_KVCO_MASK , +BIT (3 ),RK3568_PHYREG33 );/* Set PLL LPF R1 to su_trim[10:7]=1001 */ -writel (PHYREG12_PLL_LPF_ADJ_VALUE , priv->mmio +PHYREG12 ); +writel (RK3568_PHYREG12_PLL_LPF_ADJ_VALUE , priv->mmio +RK3568_PHYREG12 );/* Set PLL input clock divider 1/2 */ - val =FIELD_PREP (PHYREG6_PLL_DIV_MASK ,PHYREG6_PLL_DIV_2 ); -rockchip_combphy_updatel (priv,PHYREG6_PLL_DIV_MASK , val,PHYREG6 ); + val =FIELD_PREP (RK3568_PHYREG6_PLL_DIV_MASK ,RK3568_PHYREG6_PLL_DIV_2 ); +rockchip_combphy_updatel (priv,RK3568_PHYREG6_PLL_DIV_MASK , val,RK3568_PHYREG6 );/* Set PLL loop divider */ -writel (PHYREG18_PLL_LOOP , priv->mmio +PHYREG18 ); +writel (RK3568_PHYREG18_PLL_LOOP , priv->mmio +RK3568_PHYREG18 );/* Set PLL KVCO to min and set PLL charge pump current to max */ -writel (PHYREG11_SU_TRIM_0_7 , priv->mmio +PHYREG11 ); +writel (RK3568_PHYREG11_SU_TRIM_0_7 , priv->mmio +RK3568_PHYREG11 );rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_sel_usb, true);rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_txcomp_sel, false);
@@ -458,11 +460,12 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv)case REF_CLOCK_24MHz:if (priv->type ==PHY_TYPE_USB3 ) {/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */ - val =FIELD_PREP (PHYREG15_SSC_CNT_MASK ,PHYREG15_SSC_CNT_VALUE ); -rockchip_combphy_updatel (priv,PHYREG15_SSC_CNT_MASK , - val,PHYREG15 ); + val =FIELD_PREP (RK3568_PHYREG15_SSC_CNT_MASK , +RK3568_PHYREG15_SSC_CNT_VALUE ); +rockchip_combphy_updatel (priv,RK3568_PHYREG15_SSC_CNT_MASK , + val,RK3568_PHYREG15 ); -writel (PHYREG16_SSC_CNT_VALUE , priv->mmio +PHYREG16 ); +writel (RK3568_PHYREG16_SSC_CNT_VALUE , priv->mmio +RK3568_PHYREG16 ); }break ;case REF_CLOCK_25MHz:
@@ -472,19 +475,20 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv)rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_clk_100m, true);if (priv->type ==PHY_TYPE_PCIE ) {/* PLL KVCO tuning fine */ - val =FIELD_PREP (PHYREG33_PLL_KVCO_MASK ,PHYREG33_PLL_KVCO_VALUE ); -rockchip_combphy_updatel (priv,PHYREG33_PLL_KVCO_MASK , - val,PHYREG33 ); + val =FIELD_PREP (RK3568_PHYREG33_PLL_KVCO_MASK , +RK3568_PHYREG33_PLL_KVCO_VALUE ); +rockchip_combphy_updatel (priv,RK3568_PHYREG33_PLL_KVCO_MASK , + val,RK3568_PHYREG33 );/* Enable controlling random jitter, aka RMJ */ -writel (0x4 , priv->mmio +PHYREG12 ); +writel (0x4 , priv->mmio +RK3568_PHYREG12 ); - val =PHYREG6_PLL_DIV_2 <<PHYREG6_PLL_DIV_SHIFT ; -rockchip_combphy_updatel (priv,PHYREG6_PLL_DIV_MASK , - val,PHYREG6 ); + val =RK3568_PHYREG6_PLL_DIV_2 <<RK3568_PHYREG6_PLL_DIV_SHIFT ; +rockchip_combphy_updatel (priv,RK3568_PHYREG6_PLL_DIV_MASK , + val,RK3568_PHYREG6 ); -writel (0x32 , priv->mmio +PHYREG18 ); -writel (0xf0 , priv->mmio +PHYREG11 ); +writel (0x32 , priv->mmio +RK3568_PHYREG18 ); +writel (0xf0 , priv->mmio +RK3568_PHYREG11 ); }break ;default :
@@ -495,20 +499,21 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv)if (priv->ext_refclk) {rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_clk_ext, true);if (priv->type ==PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { - val =PHYREG13_RESISTER_HIGH_Z <<PHYREG13_RESISTER_SHIFT ; - val |=PHYREG13_CKRCV_AMP0 ; -rockchip_combphy_updatel (priv,PHYREG13_RESISTER_MASK , val,PHYREG13 ); - - val =readl (priv->mmio +PHYREG14 ); - val |=PHYREG14_CKRCV_AMP1 ; -writel (val, priv->mmio +PHYREG14 ); + val =RK3568_PHYREG13_RESISTER_HIGH_Z <<RK3568_PHYREG13_RESISTER_SHIFT ; + val |=RK3568_PHYREG13_CKRCV_AMP0 ; +rockchip_combphy_updatel (priv,RK3568_PHYREG13_RESISTER_MASK , val, +RK3568_PHYREG13 ); + + val =readl (priv->mmio +RK3568_PHYREG14 ); + val |=RK3568_PHYREG14_CKRCV_AMP1 ; +writel (val, priv->mmio +RK3568_PHYREG14 ); } }if (priv->enable_ssc) { - val =readl (priv->mmio +PHYREG8 ); - val |=PHYREG8_SSC_EN ; -writel (val, priv->mmio +PHYREG8 ); + val =readl (priv->mmio +RK3568_PHYREG8 ); + val |=RK3568_PHYREG8_SSC_EN ; +writel (val, priv->mmio +RK3568_PHYREG8 ); }return 0 ;
@@ -555,9 +560,9 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)switch (priv->type) {case PHY_TYPE_PCIE :/* Set SSC downward spread spectrum. */ -rockchip_combphy_updatel (priv,PHYREG32_SSC_MASK , -PHYREG32_SSC_DOWNWARD <<PHYREG32_SSC_DIR_SHIFT , -PHYREG32 ); + val =RK3568_PHYREG32_SSC_DOWNWARD <<RK3568_PHYREG32_SSC_DIR_SHIFT ; + +rockchip_combphy_updatel (priv,RK3568_PHYREG32_SSC_MASK , val,RK3568_PHYREG32 );rockchip_combphy_param_write (priv->phy_grf, &cfg->con0_for_pcie, true);rockchip_combphy_param_write (priv->phy_grf, &cfg->con1_for_pcie, true);
@@ -567,30 +572,28 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)case PHY_TYPE_USB3 :/* Set SSC downward spread spectrum. */ -rockchip_combphy_updatel (priv,PHYREG32_SSC_MASK , -PHYREG32_SSC_DOWNWARD <<PHYREG32_SSC_DIR_SHIFT , -PHYREG32 ); + val =RK3568_PHYREG32_SSC_DOWNWARD <<RK3568_PHYREG32_SSC_DIR_SHIFT , +rockchip_combphy_updatel (priv,RK3568_PHYREG32_SSC_MASK , val,RK3568_PHYREG32 );/* Enable adaptive CTLE for USB3.0 Rx. */ - val =readl (priv->mmio +PHYREG15 ); - val |=PHYREG15_CTLE_EN ; -writel (val, priv->mmio +PHYREG15 ); + val =readl (priv->mmio +RK3568_PHYREG15 ); + val |=RK3568_PHYREG15_CTLE_EN ; +writel (val, priv->mmio +RK3568_PHYREG15 );/* Set PLL KVCO fine tuning signals. */ -rockchip_combphy_updatel (priv,PHYREG33_PLL_KVCO_MASK , -PHYREG33_PLL_KVCO_VALUE <<PHYREG33_PLL_KVCO_SHIFT , -PHYREG33 ); + val =RK3568_PHYREG33_PLL_KVCO_VALUE <<RK3568_PHYREG33_PLL_KVCO_SHIFT ; +rockchip_combphy_updatel (priv,RK3568_PHYREG33_PLL_KVCO_MASK , val,RK3568_PHYREG33 );/* Enable controlling random jitter. */ -writel (PHYREG12_PLL_LPF_ADJ_VALUE , priv->mmio +PHYREG12 ); +writel (RK3568_PHYREG12_PLL_LPF_ADJ_VALUE , priv->mmio +RK3568_PHYREG12 );/* Set PLL input clock divider 1/2. */ -rockchip_combphy_updatel (priv,PHYREG6_PLL_DIV_MASK , -PHYREG6_PLL_DIV_2 <<PHYREG6_PLL_DIV_SHIFT , -PHYREG6 ); +rockchip_combphy_updatel (priv,RK3568_PHYREG6_PLL_DIV_MASK , +RK3568_PHYREG6_PLL_DIV_2 <<RK3568_PHYREG6_PLL_DIV_SHIFT , +RK3568_PHYREG6 ); -writel (PHYREG18_PLL_LOOP , priv->mmio +PHYREG18 ); -writel (PHYREG11_SU_TRIM_0_7 , priv->mmio +PHYREG11 ); +writel (RK3568_PHYREG18_PLL_LOOP , priv->mmio +RK3568_PHYREG18 ); +writel (RK3568_PHYREG11_SU_TRIM_0_7 , priv->mmio +RK3568_PHYREG11 );rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_sel_usb, true);rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_txcomp_sel, false);
@@ -608,16 +611,16 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)case PHY_TYPE_SATA :/* Enable adaptive CTLE for SATA Rx. */ - val =readl (priv->mmio +PHYREG15 ); - val |=PHYREG15_CTLE_EN ; -writel (val, priv->mmio +PHYREG15 ); + val =readl (priv->mmio +RK3568_PHYREG15 ); + val |=RK3568_PHYREG15_CTLE_EN ; +writel (val, priv->mmio +RK3568_PHYREG15 );/* * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA. * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm) */ - val =PHYREG7_TX_RTERM_50OHM <<PHYREG7_TX_RTERM_SHIFT ; - val |=PHYREG7_RX_RTERM_44OHM <<PHYREG7_RX_RTERM_SHIFT ; -writel (val, priv->mmio +PHYREG7 ); + val =RK3568_PHYREG7_TX_RTERM_50OHM <<RK3568_PHYREG7_TX_RTERM_SHIFT ; + val |=RK3568_PHYREG7_RX_RTERM_44OHM <<RK3568_PHYREG7_RX_RTERM_SHIFT ; +writel (val, priv->mmio +RK3568_PHYREG7 );rockchip_combphy_param_write (priv->phy_grf, &cfg->con0_for_sata, true);rockchip_combphy_param_write (priv->phy_grf, &cfg->con1_for_sata, true);
@@ -652,11 +655,11 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)case REF_CLOCK_24MHz:if (priv->type ==PHY_TYPE_USB3 || priv->type ==PHY_TYPE_SATA ) {/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */ - val =PHYREG15_SSC_CNT_VALUE <<PHYREG15_SSC_CNT_SHIFT ; -rockchip_combphy_updatel (priv,PHYREG15_SSC_CNT_MASK , - val,PHYREG15 ); + val =RK3568_PHYREG15_SSC_CNT_VALUE <<RK3568_PHYREG15_SSC_CNT_SHIFT ; +rockchip_combphy_updatel (priv,RK3568_PHYREG15_SSC_CNT_MASK , + val,RK3568_PHYREG15 ); -writel (PHYREG16_SSC_CNT_VALUE , priv->mmio +PHYREG16 ); +writel (RK3568_PHYREG16_SSC_CNT_VALUE , priv->mmio +RK3568_PHYREG16 ); }break ;
@@ -668,24 +671,26 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_clk_100m, true);if (priv->type ==PHY_TYPE_PCIE ) {/* PLL KVCO fine tuning. */ - val =PHYREG33_PLL_KVCO_VALUE <<PHYREG33_PLL_KVCO_SHIFT ; -rockchip_combphy_updatel (priv,PHYREG33_PLL_KVCO_MASK , - val,PHYREG33 ); + val =RK3568_PHYREG33_PLL_KVCO_VALUE <<RK3568_PHYREG33_PLL_KVCO_SHIFT ; +rockchip_combphy_updatel (priv,RK3568_PHYREG33_PLL_KVCO_MASK , + val,RK3568_PHYREG33 );/* Enable controlling random jitter. */ -writel (PHYREG12_PLL_LPF_ADJ_VALUE , priv->mmio +PHYREG12 ); +writel (RK3568_PHYREG12_PLL_LPF_ADJ_VALUE , priv->mmio +RK3568_PHYREG12 ); - val =PHYREG6_PLL_DIV_2 <<PHYREG6_PLL_DIV_SHIFT ; -rockchip_combphy_updatel (priv,PHYREG6_PLL_DIV_MASK , - val,PHYREG6 ); + val =RK3568_PHYREG6_PLL_DIV_2 <<RK3568_PHYREG6_PLL_DIV_SHIFT ; +rockchip_combphy_updatel (priv,RK3568_PHYREG6_PLL_DIV_MASK , + val,RK3568_PHYREG6 ); -writel (PHYREG18_PLL_LOOP , priv->mmio +PHYREG18 ); -writel (PHYREG11_SU_TRIM_0_7 , priv->mmio +PHYREG11 ); +writel (RK3568_PHYREG18_PLL_LOOP , priv->mmio +RK3568_PHYREG18 ); +writel (RK3568_PHYREG11_SU_TRIM_0_7 , priv->mmio +RK3568_PHYREG11 ); }else if (priv->type ==PHY_TYPE_SATA ) {/* downward spread spectrum +500ppm */ - val =PHYREG32_SSC_DOWNWARD <<PHYREG32_SSC_DIR_SHIFT ; - val |=PHYREG32_SSC_OFFSET_500PPM <<PHYREG32_SSC_OFFSET_SHIFT ; -rockchip_combphy_updatel (priv,PHYREG32_SSC_MASK , val,PHYREG32 ); + val =RK3568_PHYREG32_SSC_DOWNWARD <<RK3568_PHYREG32_SSC_DIR_SHIFT ; + val |=RK3568_PHYREG32_SSC_OFFSET_500PPM << +RK3568_PHYREG32_SSC_OFFSET_SHIFT ; +rockchip_combphy_updatel (priv,RK3568_PHYREG32_SSC_MASK , val, +RK3568_PHYREG32 ); }break ;
@@ -697,20 +702,21 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)if (priv->ext_refclk) {rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_clk_ext, true);if (priv->type ==PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { - val =PHYREG13_RESISTER_HIGH_Z <<PHYREG13_RESISTER_SHIFT ; - val |=PHYREG13_CKRCV_AMP0 ; -rockchip_combphy_updatel (priv,PHYREG13_RESISTER_MASK , val,PHYREG13 ); - - val =readl (priv->mmio +PHYREG14 ); - val |=PHYREG14_CKRCV_AMP1 ; -writel (val, priv->mmio +PHYREG14 ); + val =RK3568_PHYREG13_RESISTER_HIGH_Z <<RK3568_PHYREG13_RESISTER_SHIFT ; + val |=RK3568_PHYREG13_CKRCV_AMP0 ; +rockchip_combphy_updatel (priv,RK3568_PHYREG13_RESISTER_MASK , val, +RK3568_PHYREG13 ); + + val =readl (priv->mmio +RK3568_PHYREG14 ); + val |=RK3568_PHYREG14_CKRCV_AMP1 ; +writel (val, priv->mmio +RK3568_PHYREG14 ); } }if (priv->enable_ssc) { - val =readl (priv->mmio +PHYREG8 ); - val |=PHYREG8_SSC_EN ; -writel (val, priv->mmio +PHYREG8 ); + val =readl (priv->mmio +RK3568_PHYREG8 ); + val |=RK3568_PHYREG8_SSC_EN ; +writel (val, priv->mmio +RK3568_PHYREG8 ); }return 0 ;
@@ -771,8 +777,8 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)switch (priv->type) {case PHY_TYPE_PCIE :/* Set SSC downward spread spectrum */ - val =FIELD_PREP (PHYREG32_SSC_MASK ,PHYREG32_SSC_DOWNWARD ); -rockchip_combphy_updatel (priv,PHYREG32_SSC_MASK , val,PHYREG32 ); + val =FIELD_PREP (RK3568_PHYREG32_SSC_MASK ,RK3568_PHYREG32_SSC_DOWNWARD ); +rockchip_combphy_updatel (priv,RK3568_PHYREG32_SSC_MASK , val,RK3568_PHYREG32 );rockchip_combphy_param_write (priv->phy_grf, &cfg->con0_for_pcie, true);rockchip_combphy_param_write (priv->phy_grf, &cfg->con1_for_pcie, true);
@@ -782,32 +788,33 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)case PHY_TYPE_USB3 :/* Set SSC downward spread spectrum */ - val =FIELD_PREP (PHYREG32_SSC_MASK ,PHYREG32_SSC_DOWNWARD ); -rockchip_combphy_updatel (priv,PHYREG32_SSC_MASK , val,PHYREG32 ); + val =FIELD_PREP (RK3568_PHYREG32_SSC_MASK ,RK3568_PHYREG32_SSC_DOWNWARD ); +rockchip_combphy_updatel (priv,RK3568_PHYREG32_SSC_MASK , val,RK3568_PHYREG32 );/* Enable adaptive CTLE for USB3.0 Rx */ - val =readl (priv->mmio +PHYREG15 ); - val |=PHYREG15_CTLE_EN ; -writel (val, priv->mmio +PHYREG15 ); + val =readl (priv->mmio +RK3568_PHYREG15 ); + val |=RK3568_PHYREG15_CTLE_EN ; +writel (val, priv->mmio +RK3568_PHYREG15 );/* Set PLL KVCO fine tuning signals */ -rockchip_combphy_updatel (priv,PHYREG33_PLL_KVCO_MASK ,BIT (3 ),PHYREG33 ); +rockchip_combphy_updatel (priv,RK3568_PHYREG33_PLL_KVCO_MASK ,BIT (3 ), +RK3568_PHYREG33 );/* Set PLL LPF R1 to su_trim[10:7]=1001 */ -writel (PHYREG12_PLL_LPF_ADJ_VALUE , priv->mmio +PHYREG12 ); +writel (RK3568_PHYREG12_PLL_LPF_ADJ_VALUE , priv->mmio +RK3568_PHYREG12 );/* Set PLL input clock divider 1/2 */ - val =FIELD_PREP (PHYREG6_PLL_DIV_MASK ,PHYREG6_PLL_DIV_2 ); -rockchip_combphy_updatel (priv,PHYREG6_PLL_DIV_MASK , val,PHYREG6 ); + val =FIELD_PREP (RK3568_PHYREG6_PLL_DIV_MASK ,RK3568_PHYREG6_PLL_DIV_2 ); +rockchip_combphy_updatel (priv,RK3568_PHYREG6_PLL_DIV_MASK , val,RK3568_PHYREG6 );/* Set PLL loop divider */ -writel (PHYREG18_PLL_LOOP , priv->mmio +PHYREG18 ); +writel (RK3568_PHYREG18_PLL_LOOP , priv->mmio +RK3568_PHYREG18 );/* Set PLL KVCO to min and set PLL charge pump current to max */ -writel (PHYREG11_SU_TRIM_0_7 , priv->mmio +PHYREG11 ); +writel (RK3568_PHYREG11_SU_TRIM_0_7 , priv->mmio +RK3568_PHYREG11 );/* Set Rx squelch input filler bandwidth */ -writel (PHYREG21_RX_SQUELCH_VAL , priv->mmio +PHYREG21 ); +writel (RK3576_PHYREG21_RX_SQUELCH_VAL , priv->mmio +RK3576_PHYREG21 );rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_txcomp_sel, false);rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_txelec_sel, false);
@@ -816,14 +823,14 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)case PHY_TYPE_SATA :/* Enable adaptive CTLE for SATA Rx */ - val =readl (priv->mmio +PHYREG15 ); - val |=PHYREG15_CTLE_EN ; -writel (val, priv->mmio +PHYREG15 ); + val =readl (priv->mmio +RK3568_PHYREG15 ); + val |=RK3568_PHYREG15_CTLE_EN ; +writel (val, priv->mmio +RK3568_PHYREG15 );/* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */ - val =PHYREG7_TX_RTERM_50OHM <<PHYREG7_TX_RTERM_SHIFT ; - val |=PHYREG7_RX_RTERM_44OHM <<PHYREG7_RX_RTERM_SHIFT ; -writel (val, priv->mmio +PHYREG7 ); + val =RK3568_PHYREG7_TX_RTERM_50OHM <<RK3568_PHYREG7_TX_RTERM_SHIFT ; + val |=RK3568_PHYREG7_RX_RTERM_44OHM <<RK3568_PHYREG7_RX_RTERM_SHIFT ; +writel (val, priv->mmio +RK3568_PHYREG7 );rockchip_combphy_param_write (priv->phy_grf, &cfg->con0_for_sata, true);rockchip_combphy_param_write (priv->phy_grf, &cfg->con1_for_sata, true);
@@ -845,19 +852,21 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_clk_24m, true);if (priv->type ==PHY_TYPE_USB3 || priv->type ==PHY_TYPE_SATA ) {/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */ - val =FIELD_PREP (PHYREG15_SSC_CNT_MASK ,PHYREG15_SSC_CNT_VALUE ); -rockchip_combphy_updatel (priv,PHYREG15_SSC_CNT_MASK , - val,PHYREG15 ); + val =FIELD_PREP (RK3568_PHYREG15_SSC_CNT_MASK , +RK3568_PHYREG15_SSC_CNT_VALUE ); +rockchip_combphy_updatel (priv,RK3568_PHYREG15_SSC_CNT_MASK , + val,RK3568_PHYREG15 ); -writel (PHYREG16_SSC_CNT_VALUE , priv->mmio +PHYREG16 ); +writel (RK3568_PHYREG16_SSC_CNT_VALUE , priv->mmio +RK3568_PHYREG16 ); }else if (priv->type ==PHY_TYPE_PCIE ) {/* PLL KVCO tuning fine */ - val =FIELD_PREP (PHYREG33_PLL_KVCO_MASK ,PHYREG33_PLL_KVCO_VALUE_RK3576 ); -rockchip_combphy_updatel (priv,PHYREG33_PLL_KVCO_MASK , - val,PHYREG33 ); + val =FIELD_PREP (RK3568_PHYREG33_PLL_KVCO_MASK , +RK3576_PHYREG33_PLL_KVCO_VALUE ); +rockchip_combphy_updatel (priv,RK3568_PHYREG33_PLL_KVCO_MASK , + val,RK3568_PHYREG33 );/* Set up rx_pck invert and rx msb to disable */ -writel (0x00 , priv->mmio +PHYREG27 ); +writel (0x00 , priv->mmio +RK3588_PHYREG27 );/* * Set up SU adjust signal:
@@ -865,11 +874,11 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)* su_trim[15:8], PLL LPF R1 adujst bits[9:7]=3'b011 * su_trim[31:24], CKDRV adjust */ -writel (0x90 , priv->mmio +PHYREG11 ); -writel (0x02 , priv->mmio +PHYREG12 ); -writel (0x57 , priv->mmio +PHYREG14 ); +writel (0x90 , priv->mmio +RK3568_PHYREG11 ); +writel (0x02 , priv->mmio +RK3568_PHYREG12 ); +writel (0x57 , priv->mmio +RK3568_PHYREG14 ); -writel (PHYREG16_SSC_CNT_VALUE , priv->mmio +PHYREG16 ); +writel (RK3568_PHYREG16_SSC_CNT_VALUE , priv->mmio +RK3568_PHYREG16 ); }break ;
@@ -881,15 +890,16 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_clk_100m, true);if (priv->type ==PHY_TYPE_PCIE ) {/* gate_tx_pck_sel length select work for L1SS */ -writel (0xc0 , priv->mmio +PHYREG30 ); +writel (0xc0 , priv->mmio +RK3576_PHYREG30 );/* PLL KVCO tuning fine */ - val =FIELD_PREP (PHYREG33_PLL_KVCO_MASK ,PHYREG33_PLL_KVCO_VALUE_RK3576 ); -rockchip_combphy_updatel (priv,PHYREG33_PLL_KVCO_MASK , - val,PHYREG33 ); + val =FIELD_PREP (RK3568_PHYREG33_PLL_KVCO_MASK , +RK3576_PHYREG33_PLL_KVCO_VALUE ); +rockchip_combphy_updatel (priv,RK3568_PHYREG33_PLL_KVCO_MASK , + val,RK3568_PHYREG33 );/* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ -writel (0x4c , priv->mmio +PHYREG27 ); +writel (0x4c , priv->mmio +RK3588_PHYREG27 );/* * Set up SU adjust signal:
@@ -899,20 +909,23 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)* su_trim[23:16], CKRCV adjust * su_trim[31:24], CKDRV adjust */ -writel (0x90 , priv->mmio +PHYREG11 ); -writel (0x43 , priv->mmio +PHYREG12 ); -writel (0x88 , priv->mmio +PHYREG13 ); -writel (0x56 , priv->mmio +PHYREG14 ); +writel (0x90 , priv->mmio +RK3568_PHYREG11 ); +writel (0x43 , priv->mmio +RK3568_PHYREG12 ); +writel (0x88 , priv->mmio +RK3568_PHYREG13 ); +writel (0x56 , priv->mmio +RK3568_PHYREG14 ); }else if (priv->type ==PHY_TYPE_SATA ) {/* downward spread spectrum +500ppm */ - val =FIELD_PREP (PHYREG32_SSC_DIR_MASK ,PHYREG32_SSC_DOWNWARD ); - val |=FIELD_PREP (PHYREG32_SSC_OFFSET_MASK ,PHYREG32_SSC_OFFSET_500PPM ); -rockchip_combphy_updatel (priv,PHYREG32_SSC_MASK , val,PHYREG32 ); + val =FIELD_PREP (RK3568_PHYREG32_SSC_DIR_MASK , +RK3568_PHYREG32_SSC_DOWNWARD ); + val |=FIELD_PREP (RK3568_PHYREG32_SSC_OFFSET_MASK , +RK3568_PHYREG32_SSC_OFFSET_500PPM ); +rockchip_combphy_updatel (priv,RK3568_PHYREG32_SSC_MASK , val, +RK3568_PHYREG32 );/* ssc ppm adjust to 3500ppm */ -rockchip_combphy_updatel (priv,PHYREG10_SSC_PCM_MASK , -PHYREG10_SSC_PCM_3500PPM , -PHYREG10 ); +rockchip_combphy_updatel (priv,RK3576_PHYREG10_SSC_PCM_MASK , +RK3576_PHYREG10_SSC_PCM_3500PPM , +RK3576_PHYREG10 ); }break ;
@@ -924,12 +937,13 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)if (priv->ext_refclk) {rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_clk_ext, true);if (priv->type ==PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { - val =FIELD_PREP (PHYREG33_PLL_KVCO_MASK ,PHYREG33_PLL_KVCO_VALUE_RK3576 ); -rockchip_combphy_updatel (priv,PHYREG33_PLL_KVCO_MASK , - val,PHYREG33 ); + val =FIELD_PREP (RK3568_PHYREG33_PLL_KVCO_MASK , +RK3576_PHYREG33_PLL_KVCO_VALUE ); +rockchip_combphy_updatel (priv,RK3568_PHYREG33_PLL_KVCO_MASK , + val,RK3568_PHYREG33 );/* Set up rx_trim: PLL LPF C1 85pf R1 2.5kohm */ -writel (0x0c , priv->mmio +PHYREG27 ); +writel (0x0c , priv->mmio +RK3588_PHYREG27 );/* * Set up SU adjust signal:
@@ -939,25 +953,25 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)* su_trim[23:16], CKRCV adjust * su_trim[31:24], CKDRV adjust */ -writel (0x90 , priv->mmio +PHYREG11 ); -writel (0x43 , priv->mmio +PHYREG12 ); -writel (0x88 , priv->mmio +PHYREG13 ); -writel (0x56 , priv->mmio +PHYREG14 ); +writel (0x90 , priv->mmio +RK3568_PHYREG11 ); +writel (0x43 , priv->mmio +RK3568_PHYREG12 ); +writel (0x88 , priv->mmio +RK3568_PHYREG13 ); +writel (0x56 , priv->mmio +RK3568_PHYREG14 ); } }if (priv->enable_ssc) { - val =readl (priv->mmio +PHYREG8 ); - val |=PHYREG8_SSC_EN ; -writel (val, priv->mmio +PHYREG8 ); + val =readl (priv->mmio +RK3568_PHYREG8 ); + val |=RK3568_PHYREG8_SSC_EN ; +writel (val, priv->mmio +RK3568_PHYREG8 );if (priv->type ==PHY_TYPE_PCIE && rate == REF_CLOCK_24MHz) {/* Set PLL loop divider */ -writel (0x00 , priv->mmio +PHYREG17 ); -writel (PHYREG18_PLL_LOOP , priv->mmio +PHYREG18 ); +writel (0x00 , priv->mmio +RK3576_PHYREG17 ); +writel (RK3568_PHYREG18_PLL_LOOP , priv->mmio +RK3568_PHYREG18 );/* Set up rx_pck invert and rx msb to disable */ -writel (0x00 , priv->mmio +PHYREG27 ); +writel (0x00 , priv->mmio +RK3588_PHYREG27 );/* * Set up SU adjust signal:
@@ -966,16 +980,17 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)* su_trim[23:16], CKRCV adjust * su_trim[31:24], CKDRV adjust */ -writel (0x90 , priv->mmio +PHYREG11 ); -writel (0x02 , priv->mmio +PHYREG12 ); -writel (0x08 , priv->mmio +PHYREG13 ); -writel (0x57 , priv->mmio +PHYREG14 ); -writel (0x40 , priv->mmio +PHYREG15 ); +writel (0x90 , priv->mmio +RK3568_PHYREG11 ); +writel (0x02 , priv->mmio +RK3568_PHYREG12 ); +writel (0x08 , priv->mmio +RK3568_PHYREG13 ); +writel (0x57 , priv->mmio +RK3568_PHYREG14 ); +writel (0x40 , priv->mmio +RK3568_PHYREG15 ); -writel (PHYREG16_SSC_CNT_VALUE , priv->mmio +PHYREG16 ); +writel (RK3568_PHYREG16_SSC_CNT_VALUE , priv->mmio +RK3568_PHYREG16 ); - val =FIELD_PREP (PHYREG33_PLL_KVCO_MASK ,PHYREG33_PLL_KVCO_VALUE_RK3576 ); -writel (val, priv->mmio +PHYREG33 ); + val =FIELD_PREP (RK3568_PHYREG33_PLL_KVCO_MASK , +RK3576_PHYREG33_PLL_KVCO_VALUE ); +writel (val, priv->mmio +RK3568_PHYREG33 ); } }
@@ -1045,30 +1060,28 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)break ;case PHY_TYPE_USB3 :/* Set SSC downward spread spectrum */ -rockchip_combphy_updatel (priv,PHYREG32_SSC_MASK , -PHYREG32_SSC_DOWNWARD <<PHYREG32_SSC_DIR_SHIFT , -PHYREG32 ); + val =RK3568_PHYREG32_SSC_DOWNWARD <<RK3568_PHYREG32_SSC_DIR_SHIFT ; +rockchip_combphy_updatel (priv,RK3568_PHYREG32_SSC_MASK , val,RK3568_PHYREG32 );/* Enable adaptive CTLE for USB3.0 Rx. */ - val =readl (priv->mmio +PHYREG15 ); - val |=PHYREG15_CTLE_EN ; -writel (val, priv->mmio +PHYREG15 ); + val =readl (priv->mmio +RK3568_PHYREG15 ); + val |=RK3568_PHYREG15_CTLE_EN ; +writel (val, priv->mmio +RK3568_PHYREG15 );/* Set PLL KVCO fine tuning signals. */ -rockchip_combphy_updatel (priv,PHYREG33_PLL_KVCO_MASK , -PHYREG33_PLL_KVCO_VALUE <<PHYREG33_PLL_KVCO_SHIFT , -PHYREG33 ); + val =RK3568_PHYREG33_PLL_KVCO_VALUE <<RK3568_PHYREG33_PLL_KVCO_SHIFT , +rockchip_combphy_updatel (priv,RK3568_PHYREG33_PLL_KVCO_MASK , val,RK3568_PHYREG33 );/* Enable controlling random jitter. */ -writel (PHYREG12_PLL_LPF_ADJ_VALUE , priv->mmio +PHYREG12 ); +writel (RK3568_PHYREG12_PLL_LPF_ADJ_VALUE , priv->mmio +RK3568_PHYREG12 );/* Set PLL input clock divider 1/2. */ -rockchip_combphy_updatel (priv,PHYREG6_PLL_DIV_MASK , -PHYREG6_PLL_DIV_2 <<PHYREG6_PLL_DIV_SHIFT , -PHYREG6 ); +rockchip_combphy_updatel (priv,RK3568_PHYREG6_PLL_DIV_MASK , +RK3568_PHYREG6_PLL_DIV_2 <<RK3568_PHYREG6_PLL_DIV_SHIFT , +RK3568_PHYREG6 ); -writel (PHYREG18_PLL_LOOP , priv->mmio +PHYREG18 ); -writel (PHYREG11_SU_TRIM_0_7 , priv->mmio +PHYREG11 ); +writel (RK3568_PHYREG18_PLL_LOOP , priv->mmio +RK3568_PHYREG18 ); +writel (RK3568_PHYREG11_SU_TRIM_0_7 , priv->mmio +RK3568_PHYREG11 );rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_txcomp_sel, false);rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_txelec_sel, false);
@@ -1076,16 +1089,16 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)break ;case PHY_TYPE_SATA :/* Enable adaptive CTLE for SATA Rx. */ - val =readl (priv->mmio +PHYREG15 ); - val |=PHYREG15_CTLE_EN ; -writel (val, priv->mmio +PHYREG15 ); + val =readl (priv->mmio +RK3568_PHYREG15 ); + val |=RK3568_PHYREG15_CTLE_EN ; +writel (val, priv->mmio +RK3568_PHYREG15 );/* * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA. * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm) */ - val =PHYREG7_TX_RTERM_50OHM <<PHYREG7_TX_RTERM_SHIFT ; - val |=PHYREG7_RX_RTERM_44OHM <<PHYREG7_RX_RTERM_SHIFT ; -writel (val, priv->mmio +PHYREG7 ); + val =RK3568_PHYREG7_TX_RTERM_50OHM <<RK3568_PHYREG7_TX_RTERM_SHIFT ; + val |=RK3568_PHYREG7_RX_RTERM_44OHM <<RK3568_PHYREG7_RX_RTERM_SHIFT ; +writel (val, priv->mmio +RK3568_PHYREG7 );rockchip_combphy_param_write (priv->phy_grf, &cfg->con0_for_sata, true);rockchip_combphy_param_write (priv->phy_grf, &cfg->con1_for_sata, true);
@@ -1107,11 +1120,11 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)case REF_CLOCK_24MHz:if (priv->type ==PHY_TYPE_USB3 || priv->type ==PHY_TYPE_SATA ) {/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */ - val =PHYREG15_SSC_CNT_VALUE <<PHYREG15_SSC_CNT_SHIFT ; -rockchip_combphy_updatel (priv,PHYREG15_SSC_CNT_MASK , - val,PHYREG15 ); + val =RK3568_PHYREG15_SSC_CNT_VALUE <<RK3568_PHYREG15_SSC_CNT_SHIFT ; +rockchip_combphy_updatel (priv,RK3568_PHYREG15_SSC_CNT_MASK , + val,RK3568_PHYREG15 ); -writel (PHYREG16_SSC_CNT_VALUE , priv->mmio +PHYREG16 ); +writel (RK3568_PHYREG16_SSC_CNT_VALUE , priv->mmio +RK3568_PHYREG16 ); }break ;
@@ -1122,23 +1135,25 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_clk_100m, true);if (priv->type ==PHY_TYPE_PCIE ) {/* PLL KVCO fine tuning. */ - val =4 <<PHYREG33_PLL_KVCO_SHIFT ; -rockchip_combphy_updatel (priv,PHYREG33_PLL_KVCO_MASK , - val,PHYREG33 ); + val =4 <<RK3568_PHYREG33_PLL_KVCO_SHIFT ; +rockchip_combphy_updatel (priv,RK3568_PHYREG33_PLL_KVCO_MASK , + val,RK3568_PHYREG33 );/* Enable controlling random jitter. */ -writel (PHYREG12_PLL_LPF_ADJ_VALUE , priv->mmio +PHYREG12 ); +writel (RK3568_PHYREG12_PLL_LPF_ADJ_VALUE , priv->mmio +RK3568_PHYREG12 );/* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ -writel (PHYREG27_RX_TRIM_RK3588 , priv->mmio +PHYREG27 ); +writel (RK3588_PHYREG27_RX_TRIM , priv->mmio +RK3588_PHYREG27 );/* Set up su_trim: */ -writel (PHYREG11_SU_TRIM_0_7 , priv->mmio +PHYREG11 ); +writel (RK3568_PHYREG11_SU_TRIM_0_7 , priv->mmio +RK3568_PHYREG11 ); }else if (priv->type ==PHY_TYPE_SATA ) {/* downward spread spectrum +500ppm */ - val =PHYREG32_SSC_DOWNWARD <<PHYREG32_SSC_DIR_SHIFT ; - val |=PHYREG32_SSC_OFFSET_500PPM <<PHYREG32_SSC_OFFSET_SHIFT ; -rockchip_combphy_updatel (priv,PHYREG32_SSC_MASK , val,PHYREG32 ); + val =RK3568_PHYREG32_SSC_DOWNWARD <<RK3568_PHYREG32_SSC_DIR_SHIFT ; + val |=RK3568_PHYREG32_SSC_OFFSET_500PPM << +RK3568_PHYREG32_SSC_OFFSET_SHIFT ; +rockchip_combphy_updatel (priv,RK3568_PHYREG32_SSC_MASK , val, +RK3568_PHYREG32 ); }break ;default :
@@ -1149,20 +1164,21 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)if (priv->ext_refclk) {rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_clk_ext, true);if (priv->type ==PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { - val =PHYREG13_RESISTER_HIGH_Z <<PHYREG13_RESISTER_SHIFT ; - val |=PHYREG13_CKRCV_AMP0 ; -rockchip_combphy_updatel (priv,PHYREG13_RESISTER_MASK , val,PHYREG13 ); - - val =readl (priv->mmio +PHYREG14 ); - val |=PHYREG14_CKRCV_AMP1 ; -writel (val, priv->mmio +PHYREG14 ); + val =RK3568_PHYREG13_RESISTER_HIGH_Z <<RK3568_PHYREG13_RESISTER_SHIFT ; + val |=RK3568_PHYREG13_CKRCV_AMP0 ; +rockchip_combphy_updatel (priv,RK3568_PHYREG13_RESISTER_MASK , val, +RK3568_PHYREG13 ); + + val =readl (priv->mmio +RK3568_PHYREG14 ); + val |=RK3568_PHYREG14_CKRCV_AMP1 ; +writel (val, priv->mmio +RK3568_PHYREG14 ); } }if (priv->enable_ssc) { - val =readl (priv->mmio +PHYREG8 ); - val |=PHYREG8_SSC_EN ; -writel (val, priv->mmio +PHYREG8 ); + val =readl (priv->mmio +RK3568_PHYREG8 ); + val |=RK3568_PHYREG8_SSC_EN ; +writel (val, priv->mmio +RK3568_PHYREG8 ); }return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 291/507 phy: rockchip: naneng-combphy: Fix PCIe L1ss support RK3562
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shawn Lin <[email protected]>
[ Upstream commit be866e68966d20bcc4a73708093d577176f99c0c ]
When PCIe link enters L1 PM substates, the PHY will turn off its PLL for power-saving. However, it turns off the PLL too fast which leads the PHY to be broken. According to the PHY document, we need to delay PLL turnoff time.
--- drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +8 -0
@@ -64,6 +64,10 @@#define RK3568_PHYREG18 0x44#define RK3568_PHYREG18_PLL_LOOP 0x32 +#define RK3568_PHYREG30 0x74 +#define RK3568_PHYREG30_GATE_TX_PCK_SEL BIT(7) +#define RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF BIT(7) +#define RK3568_PHYREG32 0x7C#define RK3568_PHYREG32_SSC_MASK GENMASK(7, 4)#define RK3568_PHYREG32_SSC_DIR_MASK GENMASK(5, 4)
@@ -474,6 +478,10 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv)case REF_CLOCK_100MHz:rockchip_combphy_param_write (priv->phy_grf, &cfg->pipe_clk_100m, true);if (priv->type ==PHY_TYPE_PCIE ) { +/* Gate_tx_pck_sel length select for L1ss support */ +rockchip_combphy_updatel (priv,RK3568_PHYREG30_GATE_TX_PCK_SEL , +RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF , +RK3568_PHYREG30 );/* PLL KVCO tuning fine */ val =FIELD_PREP (RK3568_PHYREG33_PLL_KVCO_MASK ,RK3568_PHYREG33_PLL_KVCO_VALUE );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 292/507 phy: freescale: Initialize priv->lock
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiaolei Wang <[email protected]>
[ Upstream commit 95e5905698983df94069e185f9eb3c67c7cf75d5 ]
Initialize priv->lock to fix the following warning.
WARNING: CPU: 0 PID: 12 at kernel/locking/mutex.c:577 __mutex_lock+0x70c/0x8b8 Modules linked in: Hardware name: Freescale i.MX8QM MEK (DT) Call trace: __mutex_lock+0x70c/0x8b8 (P) mutex_lock_nested+0x24/0x30 imx_hsio_power_on+0x4c/0x764 phy_power_on+0x7c/0x12c imx_pcie_host_init+0x1d0/0x4d4 dw_pcie_host_init+0x188/0x4b0 imx_pcie_probe+0x324/0x6f4 platform_probe+0x5c/0x98 really_probe+0xbc/0x29c __driver_probe_device+0x78/0x12c driver_probe_device+0xd8/0x160 __device_attach_driver+0xb8/0x138 bus_for_each_drv+0x84/0xe4 __device_attach_async_helper+0xb8/0xdc async_run_entry_fn+0x34/0xe0 process_one_work+0x220/0x694 worker_thread+0x1c0/0x36c kthread+0x14c/0x224
--- drivers/phy/freescale/phy-fsl-imx8qm-hsio.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/phy/freescale/phy-fsl-imx8qm-hsio.c +4 -1
@@ -533,7 +533,7 @@ static struct phy *imx_hsio_xlate(struct device *dev,static int imx_hsio_probe (struct platform_device *pdev) { -int i; +int i, ret;void __iomem *off;struct device *dev = &pdev->dev;struct device_node *np = dev->of_node;
@@ -545,6 +545,9 @@ static int imx_hsio_probe(struct platform_device *pdev)return -ENOMEM ; priv->dev = &pdev->dev; priv->drvdata =of_device_get_match_data (dev); + ret =devm_mutex_init (dev, &priv->lock); +if (ret) +return ret;/* Get HSIO configuration mode */ if (of_property_read_string (np,"fsl,hsio-cfg" , &priv->hsio_cfg))
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 293/507 phy: rockchip: samsung-hdptx: Fix reported clock rate in high bpc mode
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Ciocaltea <[email protected]>
[ Upstream commit 72126e9623e1696ea83c77ef6d0306a6263bdd6b ]
When making use of the clock provider functionality, the output clock does normally match the TMDS character rate, which is what the PHY PLL gets configured to.
However, this is only applicable for default color depth of 8 bpc. For higher depths, the output clock is further divided by the hardware according to the formula:
output_clock_rate = tmds_char_rate * 8 / bpc
Since the existence of the clock divider wasn't taken into account when support for high bpc has been introduced, make the necessary adjustments to report the correct clock rate.
--- drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +8 -6
@@ -1038,7 +1038,8 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx) ret =rk_hdptx_post_enable_pll (hdptx);if (!ret) - hdptx->hw_rate = hdptx->hdmi_cfg.tmds_char_rate; + hdptx->hw_rate =DIV_ROUND_CLOSEST_ULL (hdptx->hdmi_cfg.tmds_char_rate *8 , + hdptx->hdmi_cfg.bpc);return ret; }
@@ -1896,19 +1897,20 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,* hence ensure rk_hdptx_phy_clk_set_rate() won't be invoked with * a different rate argument. */ -return hdptx->hdmi_cfg.tmds_char_rate; +return DIV_ROUND_CLOSEST_ULL (hdptx->hdmi_cfg.tmds_char_rate *8 , hdptx->hdmi_cfg.bpc); }static int rk_hdptx_phy_clk_set_rate (struct clk_hw *hw,unsigned long rate,unsigned long parent_rate) {struct rk_hdptx_phy *hdptx =to_rk_hdptx_phy (hw); +unsigned long long tmds_rate =DIV_ROUND_CLOSEST_ULL (rate * hdptx->hdmi_cfg.bpc,8 );/* Revert any unlikely TMDS char rate change since round_rate() */ -if (hdptx->hdmi_cfg.tmds_char_rate != rate) { -dev_warn (hdptx->dev,"Reverting unexpected rate change from %lu to %llu\n" , - rate, hdptx->hdmi_cfg.tmds_char_rate); - hdptx->hdmi_cfg.tmds_char_rate = rate; +if (hdptx->hdmi_cfg.tmds_char_rate != tmds_rate) { +dev_warn (hdptx->dev,"Reverting unexpected rate change from %llu to %llu\n" , + tmds_rate, hdptx->hdmi_cfg.tmds_char_rate); + hdptx->hdmi_cfg.tmds_char_rate = tmds_rate; }/*
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 294/507 phy: rockchip: samsung-hdptx: Reduce ROPLL loop bandwidth
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Ciocaltea <[email protected]>
[ Upstream commit 8daaced9f5eeb4a2c8ca08b0a8286b6a498a8387 ]
Due to its relatively low frequency, a noise stemming from the 24MHz PLL reference clock may traverse the low-pass loop filter of ROPLL, which could potentially generate some HDMI flash artifacts.
Reduce ROPLL loop bandwidth in an attempt to mitigate the problem.
--- drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +2 -2
@@ -500,9 +500,7 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = {REG_SEQ0 (CMN_REG (0043 ),0x00 ),REG_SEQ0 (CMN_REG (0044 ),0x46 ),REG_SEQ0 (CMN_REG (0045 ),0x24 ), -REG_SEQ0 (CMN_REG (0046 ),0xff ),REG_SEQ0 (CMN_REG (0047 ),0x00 ), -REG_SEQ0 (CMN_REG (0048 ),0x44 ),REG_SEQ0 (CMN_REG (0049 ),0xfa ), REG_SEQ0(CMN_REG(004a), 0x08), REG_SEQ0(CMN_REG(004b), 0x00),
@@ -575,6 +573,8 @@ static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = {REG_SEQ0 (CMN_REG (0034 ),0x00 ),REG_SEQ0 (CMN_REG (003d ),0x40 ),REG_SEQ0 (CMN_REG (0042 ),0x78 ), +REG_SEQ0 (CMN_REG (0046 ),0xdd ), +REG_SEQ0 (CMN_REG (0048 ),0x11 ),REG_SEQ0 (CMN_REG (004e ),0x34 ), REG_SEQ0(CMN_REG(005c), 0x25), REG_SEQ0(CMN_REG(005e), 0x4f),
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 295/507 phy: rockchip: samsung-hdptx: Prevent Inter-Pair Skew from exceeding the limits
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Ciocaltea <[email protected]>
[ Upstream commit 51023cf6cc5db3423dea6620746d9087e336e024 ]
Fixup PHY deskew FIFO to prevent the phase of D2 lane going ahead of other lanes. It's worth noting this might only happen when dealing with HDMI 2.0 rates.
--- drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +5 -4
@@ -668,13 +668,9 @@ static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = {static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {REG_SEQ0 (LANE_REG (0312 ),0x00 ), -REG_SEQ0 (LANE_REG (031e ),0x00 ),REG_SEQ0 (LANE_REG (0412 ),0x00 ), -REG_SEQ0 (LANE_REG (041e ),0x00 ),REG_SEQ0 (LANE_REG (0512 ),0x00 ), -REG_SEQ0 (LANE_REG (051e ),0x00 ),REG_SEQ0 (LANE_REG (0612 ),0x00 ), -REG_SEQ0 (LANE_REG (061e ),0x08 ),REG_SEQ0 (LANE_REG (0303 ),0x2f ),REG_SEQ0 (LANE_REG (0403 ),0x2f ),REG_SEQ0 (LANE_REG (0503 ),0x2f ),
@@ -687,6 +683,11 @@ static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {REG_SEQ0 (LANE_REG (0406 ),0x1c ),REG_SEQ0 (LANE_REG (0506 ),0x1c ),REG_SEQ0 (LANE_REG (0606 ),0x1c ), +/* Keep Inter-Pair Skew in the limits */ +REG_SEQ0 (LANE_REG (031e ),0x02 ), +REG_SEQ0 (LANE_REG (041e ),0x02 ), +REG_SEQ0 (LANE_REG (051e ),0x02 ), + REG_SEQ0(LANE_REG(061e), 0x0a), }; static struct tx_drv_ctrl tx_drv_ctrl_rbr[4][4] = {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 296/507 ASoC: SDCA: Fix missing dash in HIDE DisCo property
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Keepax <[email protected]>
[ Upstream commit 3508311f2e1c872b645f13c6fd52840418089d41 ]
The property name is "mipi-sdca-RxUMP-ownership-transition-max-delay", with a dash between max and delay. Add the missing dash.
--- sound/soc/sdca/sdca_functions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/sdca/sdca_functions.c +1 -1
@@ -1263,7 +1263,7 @@ find_sdca_entity_hide(struct device *dev, struct fwnode_handle *function_node,unsigned char *report_desc =NULL ; ret =fwnode_property_read_u32 (entity_node, -"mipi-sdca-RxUMP-ownership-transition-maxdelay" , &delay); +"mipi-sdca-RxUMP-ownership-transition-max-delay" , &delay);if (!ret) hide->max_delay = delay;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 297/507 selftests/bpf: Use ASSERT_STRNEQ to factor in long slab cache names
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Bobrowski <[email protected]>
[ Upstream commit d088da904223e8f5e19c6d156cf372d5baec1a7c ]
subtest_kmem_cache_iter_check_slabinfo() fundamentally compares slab cache names parsed out from /proc/slabinfo against those stored within struct kmem_cache_result. The current problem is that the slab cache name within struct kmem_cache_result is stored within a bounded fixed-length array (sized to SLAB_NAME_MAX(32)), whereas the name parsed out from /proc/slabinfo is not. Meaning, using ASSERT_STREQ() can certainly lead to test failures, particularly when dealing with slab cache names that are longer than SLAB_NAME_MAX(32) bytes. Notably, kmem_cache_create() allows callers to create slab caches with somewhat arbitrarily sized names via its __name identifier argument, so exceeding the SLAB_NAME_MAX(32) limit that is in place now can certainly happen.
Make subtest_kmem_cache_iter_check_slabinfo() more reliable by only checking up to sizeof(struct kmem_cache_result.name) - 1 using ASSERT_STRNEQ().
--- tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c +2 -1
@@ -57,7 +57,8 @@ static void subtest_kmem_cache_iter_check_slabinfo(struct kmem_cache_iter *skel)if (!ASSERT_OK (ret,"kmem_cache_lookup" ))break ; -ASSERT_STREQ (r.name, name,"kmem_cache_name" ); +ASSERT_STRNEQ (r.name, name,sizeof (r.name) -1 , +"kmem_cache_name" );ASSERT_EQ (r.obj_size, objsize,"kmem_cache_objsize" ); seen++;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 298/507 net: phy: adin1100: Fix software power-down ready condition
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Dahl <[email protected]>
[ Upstream commit bccaf1fe08f2c9f96f6bc38391d41e67f6bf38e3 ]
Value CRSM_SFT_PD written to Software Power-Down Control Register (CRSM_SFT_PD_CNTRL) is 0x01 and therefor different to value CRSM_SFT_PD_RDY (0x02) read from System Status Register (CRSM_STAT) for confirmation powerdown has been reached.
The condition could have only worked when disabling powerdown (both 0x00), but never when enabling it (0x01 != 0x02).
Result is a timeout, like so:
$ ifdown eth0
macb f802c000.ethernet eth0: Link is Down
ADIN1100 f802c000.ethernet-ffffffff:01: adin_set_powerdown_mode failed: -110
ADIN1100 f802c000.ethernet-ffffffff:01: adin_set_powerdown_mode failed: -110--- drivers/net/phy/adin1100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/phy/adin1100.c +1 -1
@@ -201,7 +201,7 @@ static int adin_set_powerdown_mode(struct phy_device *phydev, bool en)return ret;return phy_read_mmd_poll_timeout (phydev,MDIO_MMD_VEND1 ,ADIN_CRSM_STAT , ret, - (ret &ADIN_CRSM_SFT_PD_RDY ) == val, + !!(ret &ADIN_CRSM_SFT_PD_RDY ) == en,1000 ,30000 , true); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 299/507 cpuset: Treat cpusets in attaching as populated
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Ridong <[email protected]>
[ Upstream commit b1bcaed1e39a9e0dfbe324a15d2ca4253deda316 ]
Currently, the check for whether a partition is populated does not account for tasks in the cpuset of attaching. This is a corner case that can leave a task stuck in a partition with no effective CPUs.
The race condition occurs as follows:
cpu0 cpu1
//cpuset A with cpu N
migrate task p to Acpuset_can_attach
// with effective cpus
// check ok
// cpuset_mutex is not held // clear cpuset.cpus.exclusive
// making effective cpus empty update_exclusive_cpumask // tasks_nocpu_error check ok // empty effective cpus, partition valid
cpuset_attach
...
// task p stays in A, with non-effective cpus.
To fix this issue, this patch introduces cs_is_populated, which considers tasks in the attaching cpuset. This new helper is used in validate_change and partition_is_populated.
--- kernel/cgroup/cpuset.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-)
kernel/cgroup/cpuset.c +27 -8
@@ -327,6 +327,15 @@ static inline bool is_in_v2_mode(void) (cpuset_cgrp_subsys.root->flags &CGRP_ROOT_CPUSET_V2_MODE ); } +static inline bool cpuset_is_populated (struct cpuset *cs) +{ +lockdep_assert_held (&cpuset_mutex); + +/* Cpusets in the process of attaching should be considered as populated */ +return cgroup_is_populated (cs->css.cgroup) || + cs->attach_in_progress; +} +/** * partition_is_populated - check if partition has tasks * @cs: partition root to be checked
@@ -339,21 +348,31 @@ static inline bool is_in_v2_mode(void)static inline bool partition_is_populated (struct cpuset *cs,struct cpuset *excluded_child) { -struct cgroup_subsys_state *css; -struct cpuset *child; +struct cpuset *cp; +struct cgroup_subsys_state *pos_css; -if (cs->css.cgroup->nr_populated_csets) +/* +* We cannot call cs_is_populated(cs) directly, as +* nr_populated_domain_children may include populated +* csets from descendants that are partitions. +*/ +if (cs->css.cgroup->nr_populated_csets || + cs->attach_in_progress)return true;if (!excluded_child && !cs->nr_subparts)return cgroup_is_populated (cs->css.cgroup);rcu_read_lock (); -cpuset_for_each_child (child, css, cs) { -if (child == excluded_child) +cpuset_for_each_descendant_pre (cp, pos_css, cs) { +if (cp == cs || cp == excluded_child)continue ; -if (is_partition_valid (child)) + +if (is_partition_valid (cp)) { + pos_css =css_rightmost_descendant (pos_css);continue ; -if (cgroup_is_populated (child->css.cgroup)) { + } + +if (cpuset_is_populated (cp)) {rcu_read_unlock ();return true; }
@@ -584,7 +603,7 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial)* be changed to have empty cpus_allowed or mems_allowed. */ ret = -ENOSPC ; -if ((cgroup_is_populated (cur->css.cgroup) || cur->attach_in_progress)) { +if (cpuset_is_populated (cur)) {if (!cpumask_empty (cur->cpus_allowed) &&cpumask_empty (trial->cpus_allowed)) goto out;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 300/507 clk: spacemit: Set clk_hw_onecell_data::num before using flex array
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Mirabile <[email protected]>
[ Upstream commit 23b2d2fb136959fd0a8e309c70be83d9b8841c7e ]
When booting with KASAN enabled the following splat is encountered during probe of the k1 clock driver:
UBSAN: array-index-out-of-bounds in drivers/clk/spacemit/ccu-k1.c:1044:16 index 0 is out of range for type 'clk_hw *[*]' CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.18.0-rc5+ #1 PREEMPT(lazy) Hardware name: Unknown Unknown Product/Unknown Product, BIOS 2022.10spacemit 10/01/2022 Call Trace: [<ffffffff8002b628>] dump_backtrace+0x28/0x38 [<ffffffff800027d2>] show_stack+0x3a/0x50 [<ffffffff800220c2>] dump_stack_lvl+0x5a/0x80 [<ffffffff80022100>] dump_stack+0x18/0x20 [<ffffffff800164b8>] ubsan_epilogue+0x10/0x48 [<ffffffff8099034e>] __ubsan_handle_out_of_bounds+0xa6/0xa8 [<ffffffff80acbfa6>] k1_ccu_probe+0x37e/0x420 [<ffffffff80b79e6e>] platform_probe+0x56/0x98 [<ffffffff80b76a7e>] really_probe+0x9e/0x350 [<ffffffff80b76db0>] __driver_probe_device+0x80/0x138 [<ffffffff80b76f52>] driver_probe_device+0x3a/0xd0 [<ffffffff80b771c4>] __driver_attach+0xac/0x1b8 [<ffffffff80b742fc>] bus_for_each_dev+0x6c/0xc8 [<ffffffff80b76296>] driver_attach+0x26/0x38 [<ffffffff80b759ae>] bus_add_driver+0x13e/0x268 [<ffffffff80b7836a>] driver_register+0x52/0x100 [<ffffffff80b79a78>] __platform_driver_register+0x28/0x38 [<ffffffff814585da>] k1_ccu_driver_init+0x22/0x38 [<ffffffff80023a8a>] do_one_initcall+0x62/0x2a0 [<ffffffff81401c60>] do_initcalls+0x170/0x1a8 [<ffffffff81401e7a>] kernel_init_freeable+0x16a/0x1e0 [<ffffffff811f7534>] kernel_init+0x2c/0x180 [<ffffffff80025f56>] ret_from_fork_kernel+0x16/0x1d8 [<ffffffff81205336>] ret_from_fork_kernel_asm+0x16/0x18 ---[ end trace ]---
This is bogus and is simply a result of KASAN consulting the .num member of the struct for bounds information (as it should due to __counted_by) and finding 0 set by kzalloc() because it has not been initialized before the loop that fills in the array. The easy fix is to just move the line that sets num to before the loop that fills the array so that KASAN has the information it needs to accurately conclude that the access is valid.
--- drivers/clk/spacemit/ccu-k1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/spacemit/ccu-k1.c +2 -2
@@ -973,6 +973,8 @@ static int spacemit_ccu_register(struct device *dev,if (!clk_data)return -ENOMEM ; + clk_data->num = data->num; +for (i =0 ; i < data->num; i++) {struct clk_hw *hw = data->hws[i];struct ccu_common *common;
@@ -999,8 +1001,6 @@ static int spacemit_ccu_register(struct device *dev, clk_data->hws[i] = hw; } - clk_data->num = data->num; - ret =devm_of_clk_add_hw_provider (dev, of_clk_hw_onecell_get, clk_data);if (ret)dev_err (dev,"failed to add clock hardware provider (%d)\n" , ret);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 301/507 wifi: rtl818x: rtl8187: Fix potential buffer underflow in rtl8187_rx_cb()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Seungjin Bae <[email protected]>
[ Upstream commit b647d2574e4583c2e3b0ab35568f60c88e910840 ]
The rtl8187_rx_cb() calculates the rx descriptor header address by subtracting its size from the skb tail pointer. However, it does not validate if the received packet (skb->len from urb->actual_length) is large enough to contain this header.
If a truncated packet is received, this will lead to a buffer underflow, reading memory before the start of the skb data area, and causing a kernel panic.
Add length checks for both rtl8187 and rtl8187b descriptor headers before attempting to access them, dropping the packet cleanly if the check fails.
--- .../wireless/realtek/rtl818x/rtl8187/dev.c | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-)
drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +19 -8
@@ -338,14 +338,16 @@ static void rtl8187_rx_cb(struct urb *urb)spin_unlock_irqrestore (&priv->rx_queue.lock, f);skb_put (skb, urb->actual_length); -if (unlikely (urb->status)) { -dev_kfree_skb_irq (skb); -return ; - } +if (unlikely (urb->status)) + goto free_skb;if (!priv->is_rtl8187b) { -struct rtl8187_rx_hdr *hdr = - (typeof (hdr))(skb_tail_pointer (skb) -sizeof (*hdr)); +struct rtl8187_rx_hdr *hdr; + +if (skb->len <sizeof (struct rtl8187_rx_hdr )) + goto free_skb; + + hdr = (typeof (hdr))(skb_tail_pointer (skb) -sizeof (*hdr)); flags =le32_to_cpu (hdr->flags);/* As with the RTL8187B below, the AGC is used to calculate * signal strength. In this case, the scaling
@@ -355,8 +357,12 @@ static void rtl8187_rx_cb(struct urb *urb) rx_status.antenna = (hdr->signal >>7 ) &1 ; rx_status.mactime =le64_to_cpu (hdr->mac_time); }else { -struct rtl8187b_rx_hdr *hdr = - (typeof (hdr))(skb_tail_pointer (skb) -sizeof (*hdr)); +struct rtl8187b_rx_hdr *hdr; + +if (skb->len <sizeof (struct rtl8187b_rx_hdr )) + goto free_skb; + + hdr = (typeof (hdr))(skb_tail_pointer (skb) -sizeof (*hdr));/* The Realtek datasheet for the RTL8187B shows that the RX * header contains the following quantities: signal quality, * RSSI, AGC, the received power in dB, and the measured SNR.
@@ -409,6 +415,11 @@ static void rtl8187_rx_cb(struct urb *urb)skb_unlink (skb, &priv->rx_queue);dev_kfree_skb_irq (skb); } +return ; + +free_skb: +dev_kfree_skb_irq (skb); +return ; }static int rtl8187_init_urbs (struct ieee80211_hw *dev)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 302/507 RAS: Report all ARM processor CPER information to userspace
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Tian <[email protected]>
[ Upstream commit 05954511b73e748d0370549ad9dd9cd95297d97a ]
The ARM processor CPER record was added in UEFI v2.6 and remained unchanged up to v2.10.
Yet, the original arm_event trace code added by
e9279e83ad1f ("trace, ras: add ARM processor error trace event")
is incomplete, as it only traces some fields of UAPI 2.6 table N.16, not exporting any information from tables N.17 to N.29 of the record.
This is not enough for the user to be able to figure out what has exactly happened or to take appropriate action.
According to the UEFI v2.9 specification chapter N2.4.4, the ARM processor error section includes:
- several (ERR_INFO_NUM) ARM processor error information structures (Tables N.17 to N.20);
- several (CONTEXT_INFO_NUM) ARM processor context information structures (Tables N.21 to N.29);
- several vendor specific error information structures. The size is given by Section Length minus the size of the other fields.
In addition, it also exports two fields that are parsed by the GHES driver when firmware reports it, e.g.:
- error severity
- CPU logical index
Report all of these information to userspace via a the ARM tracepoint so that userspace can properly record the error and take decisions related to CPU core isolation according to error severity and other info.
The updated ARM trace event now contains the following fields:
====================================== =============================
UEFI field on table N.16 ARM Processor trace fields
====================================== =============================
Validation handled when filling data for
affinity MPIDR and running
state.
ERR_INFO_NUM pei_len
CONTEXT_INFO_NUM ctx_len
Section Length indirectly reported by
pei_len, ctx_len and oem_len
Error affinity level affinity
MPIDR_EL1 mpidr
MIDR_EL1 midr
Running State running_state
PSCI State psci_state
Processor Error Information Structure pei_err - count at pei_len
Processor Context ctx_err- count at ctx_len
Vendor Specific Error Info oem - count at oem_len
====================================== =============================It should be noted that decoding of tables N.17 to N.29, if needed, will be handled in userspace. That gives more flexibility, as there won't be any need to flood the kernel with micro-architecture specific error decoding.
Also, decoding the other fields require a complex logic, and should be done for each of the several values inside the record field. So, let userspace daemons like rasdaemon decode them, parsing such tables and having vendor-specific micro-architecture-specific decoders.
[mchehab: modified description, solved merge conflicts and fixed coding style]
--- drivers/acpi/apei/ghes.c | 11 ++++----- drivers/ras/ras.c | 40 ++++++++++++++++++++++++++++++-- include/linux/ras.h | 16 ++++++++++--- include/ras/ras_event.h | 49 ++++++++++++++++++++++++++++++++++++---- 4 files changed, 99 insertions(+), 17 deletions(-)
drivers/acpi/apei/ghes.c +4 -7
@@ -552,7 +552,7 @@ static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, }static bool ghes_handle_arm_hw_error (struct acpi_hest_generic_data *gdata, -int sev,bool sync) +int sev,bool sync) {struct cper_sec_proc_arm *err =acpi_hest_get_payload (gdata);int flags = sync ?MF_ACTION_REQUIRED :0 ;
@@ -560,9 +560,8 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata,int sec_sev, i;char *p; -log_arm_hw_error (err); - sec_sev =ghes_severity (gdata->error_severity); +log_arm_hw_error (err, sec_sev);if (sev !=GHES_SEV_RECOVERABLE || sec_sev !=GHES_SEV_RECOVERABLE )return false;
@@ -895,11 +894,9 @@ static void ghes_do_proc(struct ghes *ghes,arch_apei_report_mem_error (sev, mem_err); queued =ghes_handle_memory_failure (gdata, sev, sync); - } -else if (guid_equal (sec_type, &CPER_SEC_PCIE )) { + }else if (guid_equal (sec_type, &CPER_SEC_PCIE )) {ghes_handle_aer (gdata); - } -else if (guid_equal (sec_type, &CPER_SEC_PROC_ARM )) { + }else if (guid_equal (sec_type, &CPER_SEC_PROC_ARM )) { queued =ghes_handle_arm_hw_error (gdata, sev, sync); }else if (guid_equal (sec_type, &CPER_SEC_CXL_PROT_ERR )) {struct cxl_cper_sec_prot_err *prot_err =acpi_hest_get_payload (gdata);
drivers/ras/ras.c +38 -2
@@ -52,9 +52,45 @@ void log_non_standard_event(const guid_t *sec_type, const guid_t *fru_id,trace_non_standard_event (sec_type, fru_id, fru_text, sev, err, len); } -void log_arm_hw_error (struct cper_sec_proc_arm *err) +void log_arm_hw_error (struct cper_sec_proc_arm *err,const u8 sev) { -trace_arm_event (err); +struct cper_arm_err_info *err_info; +struct cper_arm_ctx_info *ctx_info; +u8 *ven_err_data; +u32 ctx_len =0 ; +int n, sz, cpu; +s32 vsei_len; +u32 pei_len; +u8 *pei_err, *ctx_err; + + pei_len =sizeof (struct cper_arm_err_info ) * err->err_info_num; + pei_err = (u8 *)(err +1 ); + + err_info = (struct cper_arm_err_info *)(err +1 ); + ctx_info = (struct cper_arm_ctx_info *)(err_info + err->err_info_num); + ctx_err = (u8 *)ctx_info; + +for (n =0 ; n < err->context_info_num; n++) { + sz =sizeof (struct cper_arm_ctx_info ) + ctx_info->size; + ctx_info = (struct cper_arm_ctx_info *)((long )ctx_info + sz); + ctx_len += sz; + } + + vsei_len = err->section_length - (sizeof (struct cper_sec_proc_arm ) + pei_len + ctx_len); +if (vsei_len <0 ) { +pr_warn (FW_BUG "section length: %d\n" , err->section_length); +pr_warn (FW_BUG "section length is too small\n" ); +pr_warn (FW_BUG "firmware-generated error record is incorrect\n" ); + vsei_len =0 ; + } + ven_err_data = (u8 *)ctx_info; + + cpu =GET_LOGICAL_INDEX (err->mpidr); +if (cpu <0 ) + cpu =-1 ; + +trace_arm_event (err, pei_err, pei_len, ctx_err, ctx_len, + ven_err_data, (u32 )vsei_len, sev, cpu); }static int __init ras_init (void )
include/linux/ras.h +13 -3
@@ -24,8 +24,7 @@ int __init parse_cec_param(char *str);void log_non_standard_event (const guid_t *sec_type,const guid_t *fru_id,const char *fru_text,const u8 sev,const u8 *err,const u32 len); -void log_arm_hw_error (struct cper_sec_proc_arm *err); - +void log_arm_hw_error (struct cper_sec_proc_arm *err,const u8 sev);#else static inline void log_non_standard_event(const guid_t *sec_type,
@@ -33,7 +32,7 @@ log_non_standard_event(const guid_t *sec_type, const u8 sev, const u8 *err, const u32 len) { return; }static inline void -log_arm_hw_error (struct cper_sec_proc_arm *err) {return ; } +log_arm_hw_error (struct cper_sec_proc_arm *err,const u8 sev) {return ; }#endif struct atl_err {
@@ -53,4 +52,15 @@ static inline unsigned long amd_convert_umc_mca_addr_to_sys_addr(struct atl_err *err) { return -EINVAL; }#endif /* CONFIG_AMD_ATL */ +#if defined(CONFIG_ARM ) || defined(CONFIG_ARM64 ) +#include <asm/smp_plat.h> +/* +* Include ARM-specific SMP header which provides a function mapping mpidr to +* CPU logical index. +*/ +#define GET_LOGICAL_INDEX (mpidr) get_logical_index(mpidr & MPIDR_HWID_BITMASK) +#else +#define GET_LOGICAL_INDEX (mpidr) -EINVAL +#endif /* CONFIG_ARM || CONFIG_ARM64 */ +#endif /* __RAS_H__ */
include/ras/ras_event.h +44 -5
73 lines not on this page · raw message
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 303/507 ima: Handle error code returned by ima_filter_rule_match()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Yipeng <[email protected]>
[ Upstream commit 738c9738e690f5cea24a3ad6fd2d9a323cf614f6 ]
In ima_match_rules(), if ima_filter_rule_match() returns -ENOENT due to the rule being NULL, the function incorrectly skips the 'if (!rc)' check and sets 'result = true'. The LSM rule is considered a match, causing extra files to be measured by IMA.
This issue can be reproduced in the following scenario:
After unloading the SELinux policy module via 'semodule -d', if an IMA measurement is triggered before ima_lsm_rules is updated,
in ima_match_rules(), the first call to ima_filter_rule_match() returns -ESTALE. This causes the code to enter the 'if (rc == -ESTALE && !rule_reinitialized)' block, perform ima_lsm_copy_rule() and retry. In ima_lsm_copy_rule(), since the SELinux module has been removed, the rule becomes NULL, and the second call to ima_filter_rule_match() returns -ENOENT. This bypasses the 'if (!rc)' check and results in a false match.
Call trace: selinux_audit_rule_match+0x310/0x3b8 security_audit_rule_match+0x60/0xa0 ima_match_rules+0x2e4/0x4a0 ima_match_policy+0x9c/0x1e8 ima_get_action+0x48/0x60 process_measurement+0xf8/0xa98 ima_bprm_check+0x98/0xd8 security_bprm_check+0x5c/0x78 search_binary_handler+0x6c/0x318 exec_binprm+0x58/0x1b8 bprm_execve+0xb8/0x130 do_execveat_common.isra.0+0x1a8/0x258 __arm64_sys_execve+0x48/0x68 invoke_syscall+0x50/0x128 el0_svc_common.constprop.0+0xc8/0xf0 do_el0_svc+0x24/0x38 el0_svc+0x44/0x200 el0t_64_sync_handler+0x100/0x130 el0t_64_sync+0x3c8/0x3d0
Fix this by changing 'if (!rc)' to 'if (rc <= 0)' to ensure that error codes like -ENOENT do not bypass the check and accidentally result in a successful match.
--- security/integrity/ima/ima_policy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
security/integrity/ima/ima_policy.c +1 -1
@@ -674,7 +674,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, goto retry; } } -if (!rc) { +if (rc <=0 ) { result = false; goto out; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 304/507 usb: chaoskey: fix locking for O_NONBLOCK
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
[ Upstream commit a2fa8a12e6bc9d89c0505b8dd7ae38ec173d25de ]
A failure to take a lock with O_NONBLOCK needs to result in -EAGAIN. Change it.
--- drivers/usb/misc/chaoskey.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
drivers/usb/misc/chaoskey.c +13 -3
@@ -444,9 +444,19 @@ static ssize_t chaoskey_read(struct file *file, goto bail;mutex_unlock (&dev->rng_lock); - result =mutex_lock_interruptible (&dev->lock); -if (result) - goto bail; +if (file->f_flags &O_NONBLOCK ) { + result =mutex_trylock (&dev->lock); +if (result ==0 ) { + result = -EAGAIN ; + goto bail; + }else { + result =0 ; + } + }else { + result =mutex_lock_interruptible (&dev->lock); +if (result) + goto bail; + }if (dev->valid == dev->used) { result =_chaoskey_fill (dev);if (result <0 ) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 305/507 usb: dwc2: fix hang during shutdown if set as peripheral
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jisheng Zhang <[email protected]>
[ Upstream commit b6ebcfdcac40a27953f052e4269ce75a18825ffc ]
dwc2 on most platforms needs phy controller, clock and power supply. All of them must be enabled/activated to properly operate. If dwc2 is configured as peripheral mode, then all the above three hardware resources are disabled at the end of the probe:
/* Gadget code manages lowlevel hw on its own */ if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) dwc2_lowlevel_hw_disable(hsotg);
But dwc2_driver_shutdown() tries to disable the interrupts on HW IP level. This would result in hang during shutdown if dwc2 is configured as peripheral mode.
Fix this hang by only disable and sync irq when lowlevel hw is enabled.
--- drivers/usb/dwc2/platform.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/dwc2/platform.c +4 -4
@@ -369,11 +369,11 @@ static void dwc2_driver_shutdown(struct platform_device *dev) {struct dwc2_hsotg *hsotg =platform_get_drvdata (dev); -dwc2_disable_global_interrupts (hsotg); -synchronize_irq (hsotg->irq); - -if (hsotg->ll_hw_enabled) +if (hsotg->ll_hw_enabled) { +dwc2_disable_global_interrupts (hsotg); +synchronize_irq (hsotg->irq);dwc2_lowlevel_hw_disable (hsotg); + } }/**
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 306/507 usb: dwc2: fix hang during suspend if set as peripheral
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jisheng Zhang <[email protected]>
[ Upstream commit 2b94b054ac4974ad2f89f7f7461840c851933adb ]
dwc2 on most platforms needs phy controller, clock and power supply. All of them must be enabled/activated to properly operate. If dwc2 is configured as peripheral mode, then all the above three hardware resources are disabled at the end of the probe:
/* Gadget code manages lowlevel hw on its own */ if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) dwc2_lowlevel_hw_disable(hsotg);
But the dwc2_suspend() tries to read the dwc2's reg to check whether is_device_mode or not, this would result in hang during suspend if dwc2 is configured as peripheral mode.
Fix this hang by bypassing suspend/resume if lowlevel hw isn't enabled.
--- drivers/usb/dwc2/platform.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/usb/dwc2/platform.c +8 -1
@@ -649,9 +649,13 @@ static int dwc2_driver_probe(struct platform_device *dev)static int __maybe_unused dwc2_suspend (struct device *dev) {struct dwc2_hsotg *dwc2 =dev_get_drvdata (dev); -bool is_device_mode =dwc2_is_device_mode (dwc2); +bool is_device_mode;int ret =0 ; +if (!dwc2->ll_hw_enabled) +return 0 ; + + is_device_mode =dwc2_is_device_mode (dwc2);if (is_device_mode)dwc2_hsotg_suspend (dwc2);
@@ -728,6 +732,9 @@ static int __maybe_unused dwc2_resume(struct device *dev)struct dwc2_hsotg *dwc2 =dev_get_drvdata (dev);int ret =0 ; +if (!dwc2->ll_hw_enabled) +return 0 ; +if (dwc2->phy_off_for_suspend && dwc2->ll_hw_enabled) { ret =__dwc2_lowlevel_hw_enable (dwc2);if (ret)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 307/507 usb: raw-gadget: cap raw_io transfer length to KMALLOC_MAX_SIZE
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gopi Krishna Menon <[email protected]>
[ Upstream commit a5160af78be7fcf3ade6caab0a14e349560c96d7 ]
The previous commit removed the PAGE_SIZE limit on transfer length of raw_io buffer in order to avoid any problems with emulating USB devices whose full configuration descriptor exceeds PAGE_SIZE in length. However this also removes the upperbound on user supplied length, allowing very large values to be passed to the allocator.
syzbot on fuzzing the transfer length with very large value (1.81GB) results in kmalloc() to fall back to the page allocator, which triggers a kernel warning as the page allocator cannot handle allocations more than MAX_PAGE_ORDER/KMALLOC_MAX_SIZE.
Since there is no limit imposed on the size of buffer for both control and non control transfers, cap the raw_io transfer length to KMALLOC_MAX_SIZE and return -EINVAL for larger transfer length to prevent any warnings from the page allocator.
--- drivers/usb/gadget/legacy/raw_gadget.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/gadget/legacy/raw_gadget.c +3 -0
@@ -40,6 +40,7 @@ MODULE_LICENSE("GPL");static DEFINE_IDA (driver_id_numbers);#define DRIVER_DRIVER_NAME_LENGTH_MAX 32 +#define USB_RAW_IO_LENGTH_MAX KMALLOC_MAX_SIZE#define RAW_EVENT_QUEUE_SIZE 16
@@ -667,6 +668,8 @@ static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr,return ERR_PTR (-EINVAL );if (!usb_raw_io_flags_valid (io->flags))return ERR_PTR (-EINVAL ); +if (io->length >USB_RAW_IO_LENGTH_MAX ) +return ERR_PTR (-EINVAL );if (get_from_user) data =memdup_user (ptr +sizeof (*io), io->length);else {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 308/507 regulator: pca9450: Fix error code in probe()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 670500b41e543c5cb09eb9f7f0e4e26c5b5fdf7e ]
Return "PTR_ERR(pca9450->sd_vsel_gpio)" instead of "ret". The "ret" variable is success at this point.
--- drivers/regulator/pca9450-regulator.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/regulator/pca9450-regulator.c +3 -4
@@ -1251,10 +1251,9 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)* to this signal (if SION bit is set in IOMUX). */ pca9450->sd_vsel_gpio =gpiod_get_optional (&ldo5->dev,"sd-vsel" ,GPIOD_IN ); -if (IS_ERR (pca9450->sd_vsel_gpio)) { -dev_err (&i2c->dev,"Failed to get SD_VSEL GPIO\n" ); -return ret; - } +if (IS_ERR (pca9450->sd_vsel_gpio)) +return dev_err_probe (&i2c->dev,PTR_ERR (pca9450->sd_vsel_gpio), +"Failed to get SD_VSEL GPIO\n" ); pca9450->sd_vsel_fixed_low =of_property_read_bool (ldo5->dev.of_node,"nxp,sd-vsel-fixed-low" );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 309/507 selftests/bpf: skip test_perf_branches_hw() on unsupported platforms
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Bobrowski <[email protected]>
[ Upstream commit 27746aaf1b20172f0859546c4a3e82eca459f680 ]
Gracefully skip the test_perf_branches_hw subtest on platforms that do not support LBR or require specialized perf event attributes to enable branch sampling.
For example, AMD's Milan (Zen 3) supports BRS rather than traditional LBR. This requires specific configurations (attr.type = PERF_TYPE_RAW, attr.config = RETIRED_TAKEN_BRANCH_INSTRUCTIONS) that differ from the generic setup used within this test. Notably, it also probably doesn't hold much value to special case perf event configurations for selected micro architectures.
--- tools/testing/selftests/bpf/prog_tests/perf_branches.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/testing/selftests/bpf/prog_tests/perf_branches.c +3 -3
@@ -116,11 +116,11 @@ static void test_perf_branches_hw(void) pfd =syscall (__NR_perf_event_open, &attr,-1 ,0 ,-1 ,PERF_FLAG_FD_CLOEXEC );/* -* Some setups don't support branch records (virtual machines, !x86), -* so skip test in this case. +* Some setups don't support LBR (virtual machines, !x86, AMD Milan Zen +* 3 which only supports BRS), so skip test in this case. */ if (pfd <0 ) { -if (errno ==ENOENT || errno ==EOPNOTSUPP ) { +if (errno ==ENOENT || errno ==EOPNOTSUPP || errno ==EINVAL ) {printf ("%s:SKIP:no PERF_SAMPLE_BRANCH_STACK\n" , __func__);test__skip ();
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 310/507 selftests/bpf: Improve reliability of test_perf_branches_no_hw()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Bobrowski <[email protected]>
[ Upstream commit ae24fc8a16b0481ea8c5acbc66453c49ec0431c4 ]
Currently, test_perf_branches_no_hw() relies on the busy loop within test_perf_branches_common() being slow enough to allow at least one perf event sample tick to occur before starting to tear down the backing perf event BPF program. With a relatively small fixed iteration count of 1,000,000, this is not guaranteed on modern fast CPUs, resulting in the test run to subsequently fail with the following:
bpf_testmod.ko is already unloaded.
Loading bpf_testmod.ko...
Successfully loaded bpf_testmod.ko. test_perf_branches_common:PASS:test_perf_branches_load 0 nsec test_perf_branches_common:PASS:attach_perf_event 0 nsec test_perf_branches_common:PASS:set_affinity 0 nsec check_good_sample:PASS:output not valid 0 nsec check_good_sample:PASS:read_branches_size 0 nsec check_good_sample:PASS:read_branches_stack 0 nsec check_good_sample:PASS:read_branches_stack 0 nsec check_good_sample:PASS:read_branches_global 0 nsec check_good_sample:PASS:read_branches_global 0 nsec check_good_sample:PASS:read_branches_size 0 nsec test_perf_branches_no_hw:PASS:perf_event_open 0 nsec test_perf_branches_common:PASS:test_perf_branches_load 0 nsec test_perf_branches_common:PASS:attach_perf_event 0 nsec test_perf_branches_common:PASS:set_affinity 0 nsec check_bad_sample:FAIL:output not valid no valid sample from prog
Summary: 0/1 PASSED, 0 SKIPPED, 1 FAILED
Successfully unloaded bpf_testmod.ko.
On a modern CPU (i.e. one with a 3.5 GHz clock rate), executing 1 million increments of a volatile integer can take significantly less than 1 millisecond. If the spin loop and detachment of the perf event BPF program elapses before the first 1 ms sampling interval elapses, the perf event will never end up firing. Fix this by bumping the loop iteration counter a little within test_perf_branches_common(), along with ensuring adding another loop termination condition which is directly influenced by the backing perf event BPF program executing. Notably, a concious decision was made to not adjust the sample_freq value as that is just not a reliable way to go about fixing the problem. It effectively still leaves the race window open.
--- .../selftests/bpf/prog_tests/perf_branches.c | 16 ++++++++++++++-- .../selftests/bpf/progs/test_perf_branches.c | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-)
tools/testing/selftests/bpf/prog_tests/perf_branches.c +14 -2
@@ -15,6 +15,10 @@ static void check_good_sample(struct test_perf_branches *skel)int pbe_size =sizeof (struct perf_branch_entry );int duration =0 ; +if (CHECK (!skel->bss->run_cnt,"invalid run_cnt" , +"checked sample validity before prog run" )) +return ; +if (CHECK (!skel->bss->valid,"output not valid" ,"no valid sample from prog" ))return ;
@@ -45,6 +49,10 @@ static void check_bad_sample(struct test_perf_branches *skel)int written_stack = skel->bss->written_stack_out;int duration =0 ; +if (CHECK (!skel->bss->run_cnt,"invalid run_cnt" , +"checked sample validity before prog run" )) +return ; +if (CHECK (!skel->bss->valid,"output not valid" ,"no valid sample from prog" ))return ;
@@ -83,8 +91,12 @@ static void test_perf_branches_common(int perf_fd, err =pthread_setaffinity_np (pthread_self (),sizeof (cpu_set), &cpu_set);if (CHECK (err,"set_affinity" ,"cpu #0, err %d\n" , err)) goto out_destroy; -/* spin the loop for a while (random high number) */ -for (i =0 ; i <1000000 ; ++i) + +/* Spin the loop for a while by using a high iteration count, and by +* checking whether the specific run count marker has been explicitly +* incremented at least once by the backing perf_event BPF program. +*/ +for (i =0 ; i <100000000 && !*(volatile int *)&skel->bss->run_cnt; ++i) ++j;test_perf_branches__detach (skel);
tools/testing/selftests/bpf/progs/test_perf_branches.c +3 -0
@@ -8,6 +8,7 @@#include <bpf/bpf_tracing.h> int valid =0 ; +int run_cnt =0 ;int required_size_out =0 ;int written_stack_out =0 ;int written_global_out =0 ;
@@ -24,6 +25,8 @@ int perf_branches(void *ctx)__u64 entries[4 *3 ] = {0 };int required_size, written_stack, written_global; + ++run_cnt; +/* write to stack */ written_stack =bpf_read_branch_records (ctx, entries,sizeof (entries),0 );/* ignore spurious events */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 311/507 crypto: starfive - Correctly handle return of sg_nents_for_len
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit e9eb52037a529fbb307c290e9951a62dd728b03d ]
The return value of sg_nents_for_len was assigned to an unsigned long in starfive_hash_digest, causing negative error codes to be converted to large positive integers.
Add error checking for sg_nents_for_len and return immediately on failure to prevent potential buffer overflows.
--- drivers/crypto/starfive/jh7110-hash.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/crypto/starfive/jh7110-hash.c +5 -1
@@ -326,6 +326,7 @@ static int starfive_hash_digest(struct ahash_request *req)struct starfive_cryp_ctx *ctx =crypto_ahash_ctx (tfm);struct starfive_cryp_request_ctx *rctx =ahash_request_ctx (req);struct starfive_cryp_dev *cryp = ctx->cryp; +int sg_len;memset (rctx,0 ,sizeof (struct starfive_cryp_request_ctx ));
@@ -334,7 +335,10 @@ static int starfive_hash_digest(struct ahash_request *req) rctx->in_sg = req->src; rctx->blksize =crypto_tfm_alg_blocksize (crypto_ahash_tfm (tfm)); rctx->digsize =crypto_ahash_digestsize (tfm); - rctx->in_sg_len =sg_nents_for_len (rctx->in_sg, rctx->total); + sg_len =sg_nents_for_len (rctx->in_sg, rctx->total); +if (sg_len <0 ) +return sg_len; + rctx->in_sg_len = sg_len; ctx->rctx = rctx;return crypto_transfer_hash_request_to_engine (cryp->engine, req);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 312/507 crypto: ccree - Correctly handle return of sg_nents_for_len
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 8700ce07c5c6bf27afa7b59a8d9cf58d783a7d5c ]
Fix error handling in cc_map_hash_request_update where sg_nents_for_len return value was assigned to u32, converting negative errors to large positive values before passing to sg_copy_to_buffer.
Check sg_nents_for_len return value and propagate errors before assigning to areq_ctx->in_nents.
--- drivers/crypto/ccree/cc_buffer_mgr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/crypto/ccree/cc_buffer_mgr.c +5 -1
@@ -1235,6 +1235,7 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx,int rc =0 ;u32 dummy =0 ;u32 mapped_nents =0 ; +int sg_nents;dev_dbg (dev," update params : curr_buff=%p curr_buff_cnt=0x%X nbytes=0x%X src=%p curr_index=%u\n" , curr_buff, *curr_buff_cnt, nbytes, src, areq_ctx->buff_index);
@@ -1248,7 +1249,10 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx,if (total_in_len < block_size) {dev_dbg (dev," less than one block: curr_buff=%p *curr_buff_cnt=0x%X copy_to=%p\n" , curr_buff, *curr_buff_cnt, &curr_buff[*curr_buff_cnt]); - areq_ctx->in_nents =sg_nents_for_len (src, nbytes); + sg_nents =sg_nents_for_len (src, nbytes); +if (sg_nents <0 ) +return sg_nents; + areq_ctx->in_nents = sg_nents;sg_copy_to_buffer (src, areq_ctx->in_nents, &curr_buff[*curr_buff_cnt], nbytes); *curr_buff_cnt += nbytes;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 313/507 PM / devfreq: hisi: Fix potential UAF in OPP handling
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengjie Zhang <[email protected]>
[ Upstream commit 26dd44a40096468396b6438985d8e44e0743f64c ]
Ensure all required data is acquired before calling dev_pm_opp_put(opp) to maintain correct resource acquisition and release order.
--- drivers/devfreq/hisi_uncore_freq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/devfreq/hisi_uncore_freq.c +2 -1
@@ -265,10 +265,11 @@ static int hisi_uncore_target(struct device *dev, unsigned long *freq,dev_err (dev,"Failed to get opp for freq %lu hz\n" , *freq);return PTR_ERR (opp); } -dev_pm_opp_put (opp); data = (u32)(dev_pm_opp_get_freq (opp) /HZ_PER_MHZ ); +dev_pm_opp_put (opp); +return hisi_uncore_cmd_send (uncore,HUCF_PCC_CMD_SET_FREQ , &data); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 314/507 RISC-V: KVM: Fix guest page fault within HLV* instructions
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangyu Yu <[email protected]>
[ Upstream commit 974555d6e417974e63444266e495a06d06c23af5 ]
When executing HLV* instructions at the HS mode, a guest page fault may occur when a g-stage page table migration between triggering the virtual instruction exception and executing the HLV* instruction.
This may be a corner case, and one simpler way to handle this is to re-execute the instruction where the virtual instruction exception occurred, and the guest page fault will be automatically handled.
--- arch/riscv/kvm/vcpu_insn.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
arch/riscv/kvm/vcpu_insn.c +22 -0
@@ -424,6 +424,22 @@ static int system_opcode_insn(struct kvm_vcpu *vcpu, struct kvm_run *run,return (rc <=0 ) ? rc :1 ; } +static bool is_load_guest_page_fault (unsigned long scause) +{ +/** +* If a g-stage page fault occurs, the direct approach +* is to let the g-stage page fault handler handle it +* naturally, however, calling the g-stage page fault +* handler here seems rather strange. +* Considering this is a corner case, we can directly +* return to the guest and re-execute the same PC, this +* will trigger a g-stage page fault again and then the +* regular g-stage page fault handler will populate +* g-stage page table. +*/ +return (scause ==EXC_LOAD_GUEST_PAGE_FAULT ); +} +/** * kvm_riscv_vcpu_virtual_insn -- Handle virtual instruction trap *
@@ -449,6 +465,8 @@ int kvm_riscv_vcpu_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ct->sepc, &utrap);if (utrap.scause) { +if (is_load_guest_page_fault (utrap.scause)) +return 1 ; utrap.sepc = ct->sepc;kvm_riscv_vcpu_trap_redirect (vcpu, &utrap);return 1 ;
@@ -504,6 +522,8 @@ int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run, insn =kvm_riscv_vcpu_unpriv_read (vcpu, true, ct->sepc, &utrap);if (utrap.scause) { +if (is_load_guest_page_fault (utrap.scause)) +return 1 ;/* Redirect trap if we failed to read instruction */ utrap.sepc = ct->sepc;kvm_riscv_vcpu_trap_redirect (vcpu, &utrap);
@@ -630,6 +650,8 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, insn =kvm_riscv_vcpu_unpriv_read (vcpu, true, ct->sepc, &utrap);if (utrap.scause) { +if (is_load_guest_page_fault (utrap.scause)) +return 1 ;/* Redirect trap if we failed to read instruction */ utrap.sepc = ct->sepc;kvm_riscv_vcpu_trap_redirect (vcpu, &utrap);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 315/507 erofs: correct FSDAX detection
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gao Xiang <[email protected]>
[ Upstream commit ebe4f3f6eb0c10f87c58e52a8912694c14fdeda6 ]
The detection of the primary device is skipped incorrectly if the multiple or flattened feature is enabled.
It also fixes the FSDAX misdetection for non-block extra blobs.
--- fs/erofs/super.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
fs/erofs/super.c +11 -11
@@ -174,15 +174,15 @@ static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb,if (!erofs_is_fileio_mode (sbi)) { dif->dax_dev =fs_dax_get_by_bdev (file_bdev (file), &dif->dax_part_off,NULL ,NULL ); -if (!dif->dax_dev &&test_opt (&sbi->opt,DAX_ALWAYS )) { -erofs_info (sb,"DAX unsupported by %s. Turning off DAX." , - dif->path); -clear_opt (&sbi->opt,DAX_ALWAYS ); - } }else if (!S_ISREG (file_inode (file)->i_mode)) {fput (file);return -EINVAL ; } +if (!dif->dax_dev &&test_opt (&sbi->opt,DAX_ALWAYS )) { +erofs_info (sb,"DAX unsupported by %s. Turning off DAX." , + dif->path); +clear_opt (&sbi->opt,DAX_ALWAYS ); + } dif->file = file; }
@@ -215,13 +215,13 @@ static int erofs_scan_devices(struct super_block *sb, ondisk_extradevs, sbi->devs->extra_devices);return -EINVAL ; } -if (!ondisk_extradevs) { -if (test_opt (&sbi->opt,DAX_ALWAYS ) && !sbi->dif0.dax_dev) { -erofs_info (sb,"DAX unsupported by block device. Turning off DAX." ); -clear_opt (&sbi->opt,DAX_ALWAYS ); - } -return 0 ; + +if (test_opt (&sbi->opt,DAX_ALWAYS ) && !sbi->dif0.dax_dev) { +erofs_info (sb,"DAX unsupported by block device. Turning off DAX." ); +clear_opt (&sbi->opt,DAX_ALWAYS ); } +if (!ondisk_extradevs) +return 0 ;if (!sbi->devs->extra_devices && !erofs_is_fscache_mode (sb)) sbi->devs->flatdev = true;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 316/507 erofs: limit the level of fs stacking for file-backed mounts
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gao Xiang <[email protected]>
[ Upstream commit d53cd891f0e4311889349fff3a784dc552f814b9 ]
Otherwise, it could cause potential kernel stack overflow (e.g., EROFS mounting itself).
--- fs/erofs/super.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
fs/erofs/super.c +16 -0
@@ -632,6 +632,22 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) sbi->blkszbits =PAGE_SHIFT ;if (!sb->s_bdev) { +/* +* (File-backed mounts) EROFS claims it's safe to nest other +* fs contexts (including its own) due to self-controlled RO +* accesses/contexts and no side-effect changes that need to +* context save & restore so it can reuse the current thread +* context. However, it still needs to bump `s_stack_depth` to +* avoid kernel stack overflow from nested filesystems. +*/ +if (erofs_is_fileio_mode (sbi)) { + sb->s_stack_depth = +file_inode (sbi->dif0.file)->i_sb->s_stack_depth +1 ; +if (sb->s_stack_depth >FILESYSTEM_MAX_STACK_DEPTH ) { +erofs_err (sb,"maximum fs stacking depth exceeded" ); +return -ENOTBLK ; + } + } sb->s_blocksize =PAGE_SIZE ; sb->s_blocksize_bits =PAGE_SHIFT ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 317/507 RDMA/bnxt_re: Fix the inline size for GenP7 devices
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Selvin Xavier <[email protected]>
[ Upstream commit 6afe40ff484a1155b71158b911c65299496e35c3 ]
Inline size supported by the device is based on the number of SGEs supported by the adapter. Change the inline size calculation based on that.
--- drivers/infiniband/hw/bnxt_re/qplib_sp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/bnxt_re/qplib_sp.c +1 -1
@@ -161,7 +161,7 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw) attr->max_srq_wqes =le32_to_cpu (sb->max_srq_wr) -1 ; attr->max_srq_sges = sb->max_srq_sge; attr->max_pkey =1 ; - attr->max_inline_data =le32_to_cpu (sb->max_inline_data); + attr->max_inline_data = attr->max_qp_sges *sizeof (struct sq_sge );if (!bnxt_qplib_is_chip_gen_p7 (rcfw->res->cctx)) attr->l2_db_size = (sb->l2_db_space_size +1 ) * (0x01 <<RCFW_DBR_BASE_PAGE_SHIFT );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 318/507 RDMA/bnxt_re: Pass correct flag for dma mr creation
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Selvin Xavier <[email protected]>
[ Upstream commit a26c4c7cdb50247b8486f1caa1ea8ab5e5c37edf ]
DMA MR doesn't use the unified MR model. So the lkey passed on to the reg_mr command to FW should contain the correct lkey. Driver is incorrectly over writing the lkey with pdid and firmware commands fails due to this.
Avoid passing the wrong key for cases where the unified MR registration is not used.
--- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 8 +++++--- drivers/infiniband/hw/bnxt_re/qplib_sp.c | 6 +++--- drivers/infiniband/hw/bnxt_re/qplib_sp.h | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-)
drivers/infiniband/hw/bnxt_re/ib_verbs.c +5 -3
@@ -599,7 +599,8 @@ static int bnxt_re_create_fence_mr(struct bnxt_re_pd *pd) mr->qplib_mr.va = (u64 )(unsigned long )fence->va; mr->qplib_mr.total_size =BNXT_RE_FENCE_BYTES ; rc =bnxt_qplib_reg_mr (&rdev->qplib_res, &mr->qplib_mr,NULL , -BNXT_RE_FENCE_PBL_SIZE ,PAGE_SIZE ); +BNXT_RE_FENCE_PBL_SIZE ,PAGE_SIZE , +_is_alloc_mr_unified (rdev->dev_attr->dev_cap_flags));if (rc) {ibdev_err (&rdev->ibdev,"Failed to register fence-MR\n" ); goto fail;
@@ -3972,7 +3973,7 @@ struct ib_mr *bnxt_re_get_dma_mr(struct ib_pd *ib_pd, int mr_access_flags) mr->qplib_mr.hwq.level =PBL_LVL_MAX ; mr->qplib_mr.total_size =-1 ;/* Infinte length */ rc =bnxt_qplib_reg_mr (&rdev->qplib_res, &mr->qplib_mr,NULL ,0 , -PAGE_SIZE ); +PAGE_SIZE , false);if (rc) goto fail_mr;
@@ -4202,7 +4203,8 @@ static struct ib_mr *__bnxt_re_user_reg_mr(struct ib_pd *ib_pd, u64 length, u64 umem_pgs =ib_umem_num_dma_blocks (umem, page_size); rc =bnxt_qplib_reg_mr (&rdev->qplib_res, &mr->qplib_mr, umem, - umem_pgs, page_size); + umem_pgs, page_size, +_is_alloc_mr_unified (rdev->dev_attr->dev_cap_flags));if (rc) {ibdev_err (&rdev->ibdev,"Failed to register user MR - rc = %d\n" , rc); rc = -EIO ;
drivers/infiniband/hw/bnxt_re/qplib_sp.c +3 -3
@@ -615,7 +615,7 @@ int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw, }int bnxt_qplib_reg_mr (struct bnxt_qplib_res *res,struct bnxt_qplib_mrw *mr, -struct ib_umem *umem,int num_pbls,u32 buf_pg_size) +struct ib_umem *umem,int num_pbls,u32 buf_pg_size,bool unified_mr) {struct bnxt_qplib_rcfw *rcfw = res->rcfw;struct bnxt_qplib_hwq_attr hwq_attr = {};
@@ -677,7 +677,7 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr, req.access = (mr->access_flags &BNXT_QPLIB_MR_ACCESS_MASK ); req.va =cpu_to_le64 (mr->va); req.key =cpu_to_le32 (mr->lkey); -if (_is_alloc_mr_unified (res->dattr->dev_cap_flags)) +if (unified_mr) req.key =cpu_to_le32 (mr->pd->id); req.flags =cpu_to_le16 (mr->flags); req.mr_size =cpu_to_le64 (mr->total_size);
@@ -688,7 +688,7 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,if (rc) goto fail; -if (_is_alloc_mr_unified (res->dattr->dev_cap_flags)) { +if (unified_mr) { mr->lkey =le32_to_cpu (resp.xid); mr->rkey = mr->lkey; }
drivers/infiniband/hw/bnxt_re/qplib_sp.h +1 -1
@@ -340,7 +340,7 @@ int bnxt_qplib_alloc_mrw(struct bnxt_qplib_res *res,int bnxt_qplib_dereg_mrw (struct bnxt_qplib_res *res,struct bnxt_qplib_mrw *mrw,bool block);int bnxt_qplib_reg_mr (struct bnxt_qplib_res *res,struct bnxt_qplib_mrw *mr, -struct ib_umem *umem,int num_pbls,u32 buf_pg_size); +struct ib_umem *umem,int num_pbls,u32 buf_pg_size,bool unified_mr);int bnxt_qplib_free_mrw (struct bnxt_qplib_res *res,struct bnxt_qplib_mrw *mr);int bnxt_qplib_alloc_fast_reg_mr (struct bnxt_qplib_res *res,struct bnxt_qplib_mrw *mr,int max);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 319/507 crypto: ahash - Fix crypto_ahash_import with partial block data
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
[ Upstream commit b0356b75f42fde15d4be268c5891f2cee6eb65bf ]
Restore the partial block buffer in crypto_ahash_import by copying it. Check whether the partial block buffer exceeds the maximum size and return -EOVERFLOW if it does.
Zero the partial block buffer in crypto_ahash_import_core.
--- crypto/ahash.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
crypto/ahash.c +11 -1
@@ -661,6 +661,12 @@ int crypto_ahash_import_core(struct ahash_request *req, const void *in) in);if (crypto_ahash_get_flags (tfm) &CRYPTO_TFM_NEED_KEY )return -ENOKEY ; +if (crypto_ahash_block_only (tfm)) { +unsigned int reqsize =crypto_ahash_reqsize (tfm); +u8 *buf =ahash_request_ctx (req); + + buf[reqsize -1 ] =0 ; + }return crypto_ahash_alg (tfm)->import_core (req, in); }EXPORT_SYMBOL_GPL (crypto_ahash_import_core);
@@ -674,10 +680,14 @@ int crypto_ahash_import(struct ahash_request *req, const void *in)if (crypto_ahash_get_flags (tfm) &CRYPTO_TFM_NEED_KEY )return -ENOKEY ;if (crypto_ahash_block_only (tfm)) { +unsigned int plen =crypto_ahash_blocksize (tfm) +1 ;unsigned int reqsize =crypto_ahash_reqsize (tfm); +unsigned int ss =crypto_ahash_statesize (tfm);u8 *buf =ahash_request_ctx (req); - buf[reqsize -1 ] =0 ; +memcpy (buf + reqsize - plen, in + ss - plen, plen); +if (buf[reqsize -1 ] >= plen) +return -EOVERFLOW ; }return crypto_ahash_alg (tfm)->import (req, in); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 320/507 crypto: ahash - Zero positive err value in ahash_update_finish
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
[ Upstream commit ebbdf6466b30e3b37f3b360826efd21f0633fb9e ]
The partial block length returned by a block-only driver should not be passed up to the caller since ahash itself deals with the partial block data.
Set err to zero in ahash_update_finish if it was positive.
--- crypto/ahash.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
crypto/ahash.c +5 -1
@@ -423,7 +423,11 @@ static int ahash_update_finish(struct ahash_request *req, int err) req->nbytes += nonzero - blen; - blen = err <0 ?0 : err + nonzero; + blen =0 ; +if (err >=0 ) { + blen = err + nonzero; + err =0 ; + }if (ahash_request_isvirt (req))memcpy (buf, req->svirt + req->nbytes - blen, blen);else
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 321/507 ASoC: tas2781: correct the wrong period
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shenghao Ding <[email protected]>
[ Upstream commit 950167a99dfd27eeaf177092908c598a31c79a7e ]
A wrong preiod at the end of the sentence was reported by one of my customers. Their thorough code review is greatly appreciated.
--- sound/soc/codecs/tas2781-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/codecs/tas2781-i2c.c +1 -1
@@ -1340,7 +1340,7 @@ static int tasdevice_create_cali_ctrls(struct tasdevice_priv *priv)/* * Alloc kcontrol via devm_kzalloc(), which don't manually -* free the kcontrol。 +* free the kcontrol. */ cali_ctrls =devm_kcalloc (priv->dev, nctrls,sizeof (cali_ctrls[0 ]),GFP_KERNEL );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 322/507 wifi: mt76: mt7996: fix null pointer deref in mt7996_conf_tx()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <[email protected]>
[ Upstream commit 79277f8ad15ec5f255ed0e1427c7a8a3e94e7f52 ]
If a link does not have an assigned channel yet, mt7996_vif_link returns NULL. We still need to store the updated queue settings in that case, and apply them later.
Move the location of the queue params to within struct mt7996_vif_link.
--- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 6 +++--- drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 5 ++++- drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 7 ++++++- 3 files changed, 13 insertions(+), 5 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7996/main.c +3 -3
@@ -650,8 +650,8 @@ mt7996_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, unsigned int link_id, u16 queue, const struct ieee80211_tx_queue_params *params) { - struct mt7996_dev *dev = mt7996_hw_dev(hw); -struct mt7996_vif_link *mlink =mt7996_vif_link (dev, vif, link_id); + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; +struct mt7996_vif_link_info *link_info = &mvif->link_info[link_id]; static const u8 mq_to_aci[] = { [IEEE80211_AC_VO] = 3, [IEEE80211_AC_VI] = 2,
@@ -660,7 +660,7 @@ mt7996_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, };/* firmware uses access class index */ - mlink->queue_params[mq_to_aci[queue]] = *params; + link_info->queue_params[mq_to_aci[queue]] = *params;/* no need to update right away, we'll get BSS_CHANGED_QOS */ return 0 ;
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +4 -1
@@ -3438,6 +3438,9 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif,#define WMM_PARAM_SET (WMM_AIFS_SET | WMM_CW_MIN_SET | \ WMM_CW_MAX_SET | WMM_TXOP_SET)struct mt7996_vif_link *link =mt7996_vif_conf_link (dev, vif, link_conf); +struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; +unsigned int link_id = link_conf->link_id; +struct mt7996_vif_link_info *link_info = &mvif->link_info[link_id];struct {u8 bss_idx;u8 __rsv[3 ];
@@ -3455,7 +3458,7 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif,skb_put_data (skb, &hdr,sizeof (hdr));for (ac =0 ; ac <IEEE80211_NUM_ACS ; ac++) { -struct ieee80211_tx_queue_params *q = &link->queue_params[ac]; +struct ieee80211_tx_queue_params *q = &link_info->queue_params[ac];struct edca *e;struct tlv *tlv;
drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +6 -1
@@ -246,16 +246,21 @@ struct mt7996_vif_link {struct mt7996_sta_link msta_link;struct mt7996_phy *phy; -struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS ];struct cfg80211_bitrate_mask bitrate_mask;u8 mld_idx; }; +struct mt7996_vif_link_info { +struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS ]; +}; +struct mt7996_vif {struct mt7996_vif_link deflink;/* must be first */ struct mt76_vif_data mt76; +struct mt7996_vif_link_info link_info[IEEE80211_MLD_MAX_NUM_LINKS ]; +u8 mld_group_idx;u8 mld_remap_idx; };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 323/507 wifi: mt76: wed: use proper wed reference in mt76 wed driver callabacks
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <[email protected]>
[ Upstream commit 385aab8fccd7a8746b9f1a17f3c1e38498a14bc7 ]
MT7996 driver can use both wed and wed_hif2 devices to offload traffic from/to the wireless NIC. In the current codebase we assume to always use the primary wed device in wed callbacks resulting in the following crash if the hw runs wed_hif2 (e.g. 6GHz link).
[ 297.455876] Unable to handle kernel read from unreadable memory at virtual address 000000000000080a [ 297.464928] Mem abort info: [ 297.467722] ESR = 0x0000000096000005 [ 297.471461] EC = 0x25: DABT (current EL), IL = 32 bits [ 297.476766] SET = 0, FnV = 0 [ 297.479809] EA = 0, S1PTW = 0 [ 297.482940] FSC = 0x05: level 1 translation fault [ 297.487809] Data abort info: [ 297.490679] ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000 [ 297.496156] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [ 297.501196] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [ 297.506500] user pgtable: 4k pages, 39-bit VAs, pgdp=0000000107480000 [ 297.512927] [000000000000080a] pgd=08000001097fb003, p4d=08000001097fb003, pud=08000001097fb003, pmd=0000000000000000 [ 297.523532] Internal error: Oops: 0000000096000005 [#1] SMP [ 297.715393] CPU: 2 UID: 0 PID: 45 Comm: kworker/u16:2 Tainted: G O 6.12.50 #0 [ 297.723908] Tainted: [O]=OOT_MODULE [ 297.727384] Hardware name: Banana Pi BPI-R4 (2x SFP+) (DT) [ 297.732857] Workqueue: nf_ft_offload_del nf_flow_rule_route_ipv6 [nf_flow_table] [ 297.740254] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 297.747205] pc : mt76_wed_offload_disable+0x64/0xa0 [mt76] [ 297.752688] lr : mtk_wed_flow_remove+0x58/0x80 [ 297.757126] sp : ffffffc080fe3ae0 [ 297.760430] x29: ffffffc080fe3ae0 x28: ffffffc080fe3be0 x27: 00000000deadbef7 [ 297.767557] x26: ffffff80c5ebca00 x25: 0000000000000001 x24: ffffff80c85f4c00 [ 297.774683] x23: ffffff80c1875b78 x22: ffffffc080d42cd0 x21: ffffffc080660018 [ 297.781809] x20: ffffff80c6a076d0 x19: ffffff80c6a043c8 x18: 0000000000000000 [ 297.788935] x17: 0000000000000000 x16: 0000000000000001 x15: 0000000000000000 [ 297.796060] x14: 0000000000000019 x13: ffffff80c0ad8ec0 x12: 00000000fa83b2da [ 297.803185] x11: ffffff80c02700c0 x10: ffffff80c0ad8ec0 x9 : ffffff81fef96200 [ 297.810311] x8 : ffffff80c02700c0 x7 : ffffff80c02700d0 x6 : 0000000000000002 [ 297.817435] x5 : 0000000000000400 x4 : 0000000000000000 x3 : 0000000000000000 [ 297.824561] x2 : 0000000000000001 x1 : 0000000000000800 x0 : ffffff80c6a063c8 [ 297.831686] Call trace: [ 297.834123] mt76_wed_offload_disable+0x64/0xa0 [mt76] [ 297.839254] mtk_wed_flow_remove+0x58/0x80 [ 297.843342] mtk_flow_offload_cmd+0x434/0x574 [ 297.847689] mtk_wed_setup_tc_block_cb+0x30/0x40 [ 297.852295] nf_flow_offload_ipv6_hook+0x7f4/0x964 [nf_flow_table] [ 297.858466] nf_flow_rule_route_ipv6+0x438/0x4a4 [nf_flow_table] [ 297.864463] process_one_work+0x174/0x300 [ 297.868465] worker_thread+0x278/0x430 [ 297.872204] kthread+0xd8/0xdc [ 297.875251] ret_from_fork+0x10/0x20 [ 297.878820] Code: 928b5ae0 8b000273 91400a60 f943fa61 (79401421) [ 297.884901] ---[ end trace 0000000000000000 ]---
Fix the issue detecting the proper wed reference to use running wed callabacks.
--- drivers/net/wireless/mediatek/mt76/mt76.h | 9 +++++++++ drivers/net/wireless/mediatek/mt76/mt7996/mmio.c | 1 + drivers/net/wireless/mediatek/mt76/wed.c | 10 +++++----- include/linux/soc/mediatek/mtk_wed.h | 1 + 4 files changed, 16 insertions(+), 5 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76.h +9 -0
@@ -1226,6 +1226,15 @@ static inline int mt76_wed_dma_setup(struct mt76_dev *dev, struct mt76_queue *q,#define mt76_dereference (p, dev) \ rcu_dereference_protected(p, lockdep_is_held(&(dev)->mutex)) +static inline struct mt76_dev *mt76_wed_to_dev (struct mtk_wed_device *wed) +{ +#ifdef CONFIG_NET_MEDIATEK_SOC_WED +if (wed->wlan.hif2) + return container_of(wed, struct mt76_dev, mmio.wed_hif2); +#endif /* CONFIG_NET_MEDIATEK_SOC_WED */ + return container_of(wed, struct mt76_dev, mmio.wed); +} +static inline struct mt76_wcid *__mt76_wcid_ptr (struct mt76_dev *dev,u16 idx) {
drivers/net/wireless/mediatek/mt76/mt7996/mmio.c +1 -0
@@ -562,6 +562,7 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr, wed->wlan.nbuf =MT7996_HW_TOKEN_SIZE ; wed->wlan.token_start =MT7996_TOKEN_SIZE - wed->wlan.nbuf; + wed->wlan.hif2 = hif2; wed->wlan.amsdu_max_subframes =8 ; wed->wlan.amsdu_max_len =1536 ;
drivers/net/wireless/mediatek/mt76/wed.c +5 -5
@@ -8,7 +8,7 @@void mt76_wed_release_rx_buf (struct mtk_wed_device *wed) { - struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); +struct mt76_dev *dev =mt76_wed_to_dev (wed);int i;for (i =0 ; i < dev->rx_token_size; i++) {
@@ -31,8 +31,8 @@ EXPORT_SYMBOL_GPL(mt76_wed_release_rx_buf);#ifdef CONFIG_NET_MEDIATEK_SOC_WED u32 mt76_wed_init_rx_buf (struct mtk_wed_device *wed,int size) { - struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc; +struct mt76_dev *dev =mt76_wed_to_dev (wed);struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN ];struct mt76_txwi_cache *t =NULL ;int i;
@@ -80,7 +80,7 @@ EXPORT_SYMBOL_GPL(mt76_wed_init_rx_buf);int mt76_wed_offload_enable (struct mtk_wed_device *wed) { - struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); +struct mt76_dev *dev =mt76_wed_to_dev (wed);spin_lock_bh (&dev->token_lock); dev->token_size = wed->wlan.token_start;
@@ -164,7 +164,7 @@ EXPORT_SYMBOL_GPL(mt76_wed_dma_setup);void mt76_wed_offload_disable (struct mtk_wed_device *wed) { - struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); +struct mt76_dev *dev =mt76_wed_to_dev (wed);spin_lock_bh (&dev->token_lock); dev->token_size = dev->drv->token_size;
@@ -174,7 +174,7 @@ EXPORT_SYMBOL_GPL(mt76_wed_offload_disable);void mt76_wed_reset_complete (struct mtk_wed_device *wed) { - struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); +struct mt76_dev *dev =mt76_wed_to_dev (wed);complete (&dev->mmio.wed_reset_complete); }
include/linux/soc/mediatek/mtk_wed.h +1 -0
@@ -154,6 +154,7 @@ struct mtk_wed_device {bool wcid_512;bool hw_rro;bool msi; +bool hif2;u16 token_start;unsigned int nbuf;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 324/507 wifi: mt76: mt7925: add MBSSID support
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Yen Hsieh <[email protected]>
[ Upstream commit 74e756b9e28af3ee94a7ea480bb39694be5fbd96 ]
Enable MBSSID support for MT7925 by setting the
appropriate capability to the firmware.
Stable-dep-of: cdb2941a516c ("Revert "wifi: mt76: mt792x: improve monitor interface handling"")
--- .../net/wireless/mediatek/mt76/mt7925/main.c | 1 + .../net/wireless/mediatek/mt76/mt7925/mcu.c | 23 ++++++++++++++++++- .../net/wireless/mediatek/mt76/mt792x_core.c | 7 +++++- 3 files changed, 29 insertions(+), 2 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7925/main.c +1 -0
@@ -240,6 +240,7 @@ int mt7925_init_mlo_caps(struct mt792x_phy *phy) {struct wiphy *wiphy = phy->mt76->hw->wiphy;static const u8 ext_capa_sta[] = { + [2 ] =WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT , [7 ] =WLAN_EXT_CAPA8_OPMODE_NOTIF , };static struct wiphy_iftype_ext_capab ext_capab[] = {
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +22 -1
@@ -2621,6 +2621,25 @@ mt7925_mcu_bss_qos_tlv(struct sk_buff *skb, struct ieee80211_bss_conf *link_conf qos->qos = link_conf->qos; } +static void +mt7925_mcu_bss_mbssid_tlv (struct sk_buff *skb,struct ieee80211_bss_conf *link_conf, +bool enable) +{ +struct bss_info_uni_mbssid *mbssid; +struct tlv *tlv; + +if (!enable && !link_conf->bssid_indicator) +return ; + + tlv =mt76_connac_mcu_add_tlv (skb,UNI_BSS_INFO_11V_MBSSID , +sizeof (*mbssid)); + + mbssid = (struct bss_info_uni_mbssid *)tlv; + mbssid->max_indicator = link_conf->bssid_indicator; + mbssid->mbss_idx = link_conf->bssid_index; + mbssid->tx_bss_omac_idx =0 ; +} +static void mt7925_mcu_bss_he_tlv (struct sk_buff *skb,struct ieee80211_bss_conf *link_conf,struct mt792x_phy *phy)
@@ -2787,8 +2806,10 @@ int mt7925_mcu_add_bss_info(struct mt792x_phy *phy,mt7925_mcu_bss_color_tlv (skb, link_conf, enable); } -if (enable) +if (enable) {mt7925_mcu_bss_rlm_tlv (skb, phy->mt76, link_conf, ctx); +mt7925_mcu_bss_mbssid_tlv (skb, link_conf, enable); + }return mt76_mcu_skb_send_msg (&dev->mt76, skb,MCU_UNI_CMD (BSS_INFO_UPDATE ), true);
drivers/net/wireless/mediatek/mt76/mt792x_core.c +6 -1
@@ -689,8 +689,13 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw)ieee80211_hw_set (hw,SUPPORTS_VHT_EXT_NSS_BW );ieee80211_hw_set (hw,CONNECTION_MONITOR );ieee80211_hw_set (hw,NO_VIRTUAL_MONITOR ); -if (is_mt7921 (&dev->mt76)) + +if (is_mt7921 (&dev->mt76)) {ieee80211_hw_set (hw,CHANCTX_STA_CSA ); + }else { +ieee80211_hw_set (hw,SUPPORTS_MULTI_BSSID ); +ieee80211_hw_set (hw,SUPPORTS_ONLY_HE_MULTI_BSSID ); + }if (dev->pm.enable)ieee80211_hw_set (hw,CONNECTION_MONITOR );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 325/507 wifi: mt76: mt7921: add MBSSID support
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Yen Hsieh <[email protected]>
[ Upstream commit 7ae99dd459ba1ea83a9b3d8de254f374182e602c ]
Enable MBSSID support for MT7921 by setting the
appropriate capability to the firmware.
Stable-dep-of: cdb2941a516c ("Revert "wifi: mt76: mt792x: improve monitor interface handling"")
--- .../wireless/mediatek/mt76/mt76_connac_mcu.c | 25 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt792x_core.c | 5 ++-- 2 files changed, 27 insertions(+), 3 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +25 -0
@@ -1662,6 +1662,31 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,return err; } +if (enable && vif->bss_conf.bssid_indicator) { +struct { +struct { +u8 bss_idx; +u8 pad[3 ]; + } __packed hdr; +struct bss_info_uni_mbssid mbssid; + } mbssid_req = { + .hdr = { + .bss_idx = mvif->idx, + }, + .mbssid = { + .tag =cpu_to_le16 (UNI_BSS_INFO_11V_MBSSID ), + .len =cpu_to_le16 (sizeof (struct bss_info_uni_mbssid )), + .max_indicator = vif->bss_conf.bssid_indicator, + .mbss_idx = vif->bss_conf.bssid_index, + }, + }; + + err =mt76_mcu_send_msg (mdev,MCU_UNI_CMD (BSS_INFO_UPDATE ), + &mbssid_req,sizeof (mbssid_req), true); +if (err <0 ) +return err; + } +return mt76_connac_mcu_uni_set_chctx (phy, mvif, ctx); }EXPORT_SYMBOL_GPL (mt76_connac_mcu_uni_add_bss);
drivers/net/wireless/mediatek/mt76/mt792x_core.c +2 -3
@@ -689,12 +689,11 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw)ieee80211_hw_set (hw,SUPPORTS_VHT_EXT_NSS_BW );ieee80211_hw_set (hw,CONNECTION_MONITOR );ieee80211_hw_set (hw,NO_VIRTUAL_MONITOR ); +ieee80211_hw_set (hw,SUPPORTS_MULTI_BSSID ); +ieee80211_hw_set (hw,SUPPORTS_ONLY_HE_MULTI_BSSID );if (is_mt7921 (&dev->mt76)) {ieee80211_hw_set (hw,CHANCTX_STA_CSA ); - }else { -ieee80211_hw_set (hw,SUPPORTS_MULTI_BSSID ); -ieee80211_hw_set (hw,SUPPORTS_ONLY_HE_MULTI_BSSID ); }if (dev->pm.enable)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 326/507 Revert "wifi: mt76: mt792x: improve monitor interface handling"
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fedor Pchelkin <[email protected]>
[ Upstream commit cdb2941a516cf06929293604e2e0f4c1d6f3541e ]
This reverts commit 55e95ce469d0c61041bae48b2ebb7fcbf6d1ba7f.
mt792x drivers don't seem to support multi-radio devices yet. At least they don't mess with struct wiphy_radio at the moment.
Packet capturing on monitor interface doesn't work after the blamed patch:
tcpdump -i wls6mon -n -vvv
Revert the NO_VIRTUAL_MONITOR feature for now to resolve the issue.
Found by Linux Verification Center (linuxtesting.org).
--- drivers/net/wireless/mediatek/mt76/mt792x_core.c | 1 - 1 file changed, 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt792x_core.c +0 -1
@@ -688,7 +688,6 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw)ieee80211_hw_set (hw,SUPPORTS_DYNAMIC_PS );ieee80211_hw_set (hw,SUPPORTS_VHT_EXT_NSS_BW );ieee80211_hw_set (hw,CONNECTION_MONITOR ); -ieee80211_hw_set (hw,NO_VIRTUAL_MONITOR );ieee80211_hw_set (hw,SUPPORTS_MULTI_BSSID );ieee80211_hw_set (hw,SUPPORTS_ONLY_HE_MULTI_BSSID );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 327/507 wifi: mt76: mt7996: fix max nss value when getting rx chainmask
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: StanleyYP Wang <[email protected]>
[ Upstream commit 361b59b6be7c33c43b619d5cada394efc0f3b398 ]
Since wiphy->available_antennas_tx now accumulates the chainmask of all the radios of a wiphy, use phy->orig_antenna_mask to get the original max nss for comparison.
--- drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +1 -1
@@ -720,7 +720,7 @@ void mt7996_memcpy_fromio(struct mt7996_dev *dev, void *buf, u32 offset,static inline u16 mt7996_rx_chainmask (struct mt7996_phy *phy) { -int max_nss =hweight8 (phy->mt76->hw->wiphy->available_antennas_tx); +int max_nss =hweight16 (phy->orig_antenna_mask);int cur_nss =hweight8 (phy->mt76->antenna_mask);u16 tx_chainmask = phy->mt76->chainmask;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 328/507 wifi: mt76: mt7996: fix implicit beamforming support for mt7992
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Howard Hsu <[email protected]>
[ Upstream commit 5d86765828b47444908a8689f2625872e8dac48f ]
Fix the ibf_timeout field for mt7996, mt7992 and mt7990 chipsets. For the mt7992, this value shall be set as 0xff, while the others shall be set as 0x18.
--- drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +2 -2
@@ -1754,8 +1754,8 @@ mt7996_mcu_sta_bfer_tlv(struct mt7996_dev *dev, struct sk_buff *skb, bf->ibf_nrow = tx_ant;if (link_sta->eht_cap.has_eht || link_sta->he_cap.has_he) - bf->ibf_timeout =is_mt7996 (&dev->mt76) ?MT7996_IBF_TIMEOUT : -MT7992_IBF_TIMEOUT ; + bf->ibf_timeout =is_mt7992 (&dev->mt76) ?MT7992_IBF_TIMEOUT : +MT7996_IBF_TIMEOUT ;else if (!ebf && link_sta->bandwidth <=IEEE80211_STA_RX_BW_40 && !bf->ncol) bf->ibf_timeout =MT7996_IBF_TIMEOUT_LEGACY ;else
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 329/507 wifi: mt76: mt7996: fix several fields in mt7996_mcu_bss_basic_tlv()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shayne Chen <[email protected]>
[ Upstream commit bb705a606734e1ce0ff17a4f368a896757ba686d ]
Fix several fields in mt7996_mcu_bss_basic_tlv() that were not obtained from the correct link. Without this patch, the MLD station interface does not function properly.
--- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +11 -10
@@ -1010,7 +1010,6 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,struct mt76_connac_bss_basic_tlv *bss;u32 type =CONNECTION_INFRA_AP ;u16 sta_wlan_idx = wlan_idx; -struct ieee80211_sta *sta;struct tlv *tlv;int idx;
@@ -1021,14 +1020,18 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,break ;case NL80211_IFTYPE_STATION :if (enable) { +struct ieee80211_sta *sta; +rcu_read_lock (); - sta =ieee80211_find_sta (vif, vif->bss_conf.bssid); -/* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */ + sta =ieee80211_find_sta (vif, link_conf->bssid);if (sta) { -struct mt76_wcid *wcid; +struct mt7996_sta *msta = (void *)sta->drv_priv; +struct mt7996_sta_link *msta_link; +int link_id = link_conf->link_id; - wcid = (struct mt76_wcid *)sta->drv_priv; - sta_wlan_idx = wcid->idx; + msta_link =rcu_dereference (msta->link[link_id]); +if (msta_link) + sta_wlan_idx = msta_link->wcid.idx; }rcu_read_unlock (); }
@@ -1045,8 +1048,6 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, tlv =mt7996_mcu_add_uni_tlv (skb,UNI_BSS_INFO_BASIC ,sizeof (*bss)); bss = (struct mt76_connac_bss_basic_tlv *)tlv; - bss->bcn_interval =cpu_to_le16 (link_conf->beacon_int); - bss->dtim_period = link_conf->dtim_period; bss->bmc_tx_wlan_idx =cpu_to_le16 (wlan_idx); bss->sta_idx =cpu_to_le16 (sta_wlan_idx); bss->conn_type =cpu_to_le32 (type);
@@ -1066,10 +1067,10 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,memcpy (bss->bssid, link_conf->bssid,ETH_ALEN ); bss->bcn_interval =cpu_to_le16 (link_conf->beacon_int); - bss->dtim_period = vif->bss_conf.dtim_period; + bss->dtim_period = link_conf->dtim_period; bss->phymode =mt76_connac_get_phy_mode (phy, vif, chandef->chan->band,NULL ); - bss->phymode_ext =mt76_connac_get_phy_mode_ext (phy, &vif->bss_conf, + bss->phymode_ext =mt76_connac_get_phy_mode_ext (phy, link_conf, chandef->chan->band);return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 330/507 wifi: mt76: mt7996: fix teardown command for an MLD peer
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shayne Chen <[email protected]>
[ Upstream commit e077071e7ac48d5453072f615d51629891c5b90d ]
For an MLD peer, we only need to call the teardown command when removing the last link, and there's no need to call mt7996_mcu_add_sta() for the earlier links.
--- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7996/main.c +4 -4
@@ -1197,13 +1197,13 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif,mt7996_mac_twt_teardown_flow (dev, link, msta_link, i); -if (sta->mlo && links ==BIT (link_id))/* last link */ -mt7996_mcu_teardown_mld_sta (dev, link, - msta_link); -else +if (!sta->mlo)mt7996_mcu_add_sta (dev, link_conf, link_sta, link, msta_link,CONN_STATE_DISCONNECT , false); +else if (sta->mlo && links ==BIT (link_id))/* last link */ +mt7996_mcu_teardown_mld_sta (dev, link, + msta_link); msta_link->wcid.sta_disabled =1 ; msta_link->wcid.sta =0 ; links = links & ~BIT (link_id);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 331/507 wifi: mt76: mt7996: set link_valid field when initializing wcid
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shayne Chen <[email protected]>
[ Upstream commit 7eaea3a8ba1e9bb58f87e3030f6ce18537e57e1f ]
This ensures the upper layer uses the correct link ID during packet processing.
--- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7996/main.c +2 -0
@@ -346,6 +346,7 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif,INIT_LIST_HEAD (&msta_link->rc_list); msta_link->wcid.idx = idx; msta_link->wcid.link_id = link_conf->link_id; + msta_link->wcid.link_valid =ieee80211_vif_is_mld (vif); msta_link->wcid.tx_info |=MT_WCID_TX_INFO_SET ;mt76_wcid_init (&msta_link->wcid, band_idx);
@@ -969,6 +970,7 @@ mt7996_mac_sta_init_link(struct mt7996_dev *dev, msta_link->wcid.sta =1 ; msta_link->wcid.idx = idx; msta_link->wcid.link_id = link_id; + msta_link->wcid.link_valid = !!sta->valid_links; msta_link->wcid.def_wcid = &msta->deflink.wcid;ewma_avg_signal_init (&msta_link->avg_ack_signal);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 332/507 wifi: mt76: mt7996: fix MLD group index assignment
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shayne Chen <[email protected]>
[ Upstream commit 4fb3b4e7d1ca5453c6167816230370afc15f26bf ]
Fix extender mode and MBSS issues caused by incorrect assignment of the MLD group and remap indices.
--- .../net/wireless/mediatek/mt76/mt7996/main.c | 58 +++++++++++++------ 1 file changed, 40 insertions(+), 18 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7996/main.c +40 -18
@@ -90,9 +90,11 @@ static void mt7996_stop(struct ieee80211_hw *hw, bool suspend) { } -static inline int get_free_idx (u32 mask,u8 start,u8 end) +static inline int get_free_idx (u64 mask,u8 start,u8 end) { -return ffs (~mask &GENMASK (end, start)); +if (~mask &GENMASK_ULL (end, start)) +return __ffs64 (~mask &GENMASK_ULL (end, start)) +1 ; +return 0 ; }static int get_omac_idx (enum nl80211_iftype type,u64 mask)
@@ -311,12 +313,6 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif,if (idx <0 )return -ENOSPC ; -if (!dev->mld_idx_mask) {/* first link in the group */ - mvif->mld_group_idx =get_own_mld_idx (dev->mld_idx_mask, true); - mvif->mld_remap_idx =get_free_idx (dev->mld_remap_idx_mask, -0 ,15 ); - } - mld_idx =get_own_mld_idx (dev->mld_idx_mask, false);if (mld_idx <0 )return -ENOSPC ;
@@ -334,10 +330,6 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif,return ret; dev->mt76.vif_mask |=BIT_ULL (mlink->idx); -if (!dev->mld_idx_mask) { - dev->mld_idx_mask |=BIT_ULL (mvif->mld_group_idx); - dev->mld_remap_idx_mask |=BIT_ULL (mvif->mld_remap_idx); - } dev->mld_idx_mask |=BIT_ULL (link->mld_idx); phy->omac_mask |=BIT_ULL (mlink->omac_idx);
@@ -421,11 +413,6 @@ void mt7996_vif_link_remove(struct mt76_phy *mphy, struct ieee80211_vif *vif, dev->mt76.vif_mask &= ~BIT_ULL (mlink->idx); dev->mld_idx_mask &= ~BIT_ULL (link->mld_idx); phy->omac_mask &= ~BIT_ULL (mlink->omac_idx); -if (!(dev->mld_idx_mask & ~BIT_ULL (mvif->mld_group_idx))) { -/* last link */ - dev->mld_idx_mask &= ~BIT_ULL (mvif->mld_group_idx); - dev->mld_remap_idx_mask &= ~BIT_ULL (mvif->mld_remap_idx); - }spin_lock_bh (&dev->mt76.sta_poll_lock);if (!list_empty (&msta_link->wcid.poll_list))
@@ -2181,7 +2168,42 @@ mt7996_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 old_links, u16 new_links, struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]) { - return 0; + struct mt7996_dev *dev = mt7996_hw_dev(hw); +struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; +int ret =0 ; + +mutex_lock (&dev->mt76.mutex); + +if (!old_links) { +int idx; + + idx =get_own_mld_idx (dev->mld_idx_mask, true); +if (idx <0 ) { + ret = -ENOSPC ; + goto out; + } + mvif->mld_group_idx = idx; + dev->mld_idx_mask |=BIT_ULL (mvif->mld_group_idx); + + idx =get_free_idx (dev->mld_remap_idx_mask,0 ,15 ) -1 ; +if (idx <0 ) { + ret = -ENOSPC ; + goto out; + } + mvif->mld_remap_idx = idx; + dev->mld_remap_idx_mask |=BIT_ULL (mvif->mld_remap_idx); + } + +if (new_links) + goto out; + + dev->mld_idx_mask &= ~BIT_ULL (mvif->mld_group_idx); + dev->mld_remap_idx_mask &= ~BIT_ULL (mvif->mld_remap_idx); + +out: +mutex_unlock (&dev->mt76.mutex); + +return ret; } const struct ieee80211_ops mt7996_ops = {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 333/507 wifi: mt76: mt7996: fix using wrong phy to start in mt7996_mac_restart()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shayne Chen <[email protected]>
[ Upstream commit f1e9f369ae42ee433836b24467e645192d046a51 ]
Pass the correct mt7996_phy to mt7996_run().
--- drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7996/mac.c +1 -1
@@ -1894,7 +1894,7 @@ mt7996_mac_restart(struct mt7996_dev *dev)if (!test_bit (MT76_STATE_RUNNING , &phy->mt76->state))continue ; - ret =mt7996_run (&dev->phy); + ret =mt7996_run (phy);if (ret) goto out; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 334/507 wifi: mt76: mt7996: grab mt76 mutex in mt7996_mac_sta_event()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <[email protected]>
[ Upstream commit 5a4bcba26e9fbea87507a81ad891e70bb525014f ]
Grab mt76 mutex in mt7996_mac_sta_event routine in order to rely on mt76_dereference() utility macro.
--- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7996/main.c +10 -5
@@ -1140,12 +1140,15 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif,unsigned long links = sta->valid_links;struct ieee80211_link_sta *link_sta;unsigned int link_id; +int err =0 ; + +mutex_lock (&dev->mt76.mutex);for_each_sta_active_link (vif, sta, link_sta, link_id) {struct ieee80211_bss_conf *link_conf;struct mt7996_sta_link *msta_link;struct mt7996_vif_link *link; -int i, err; +int i; link_conf =link_conf_dereference_protected (vif, link_id);if (!link_conf)
@@ -1165,12 +1168,12 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, link, msta_link, CONN_STATE_CONNECT, true);if (err) -return err; + goto unlock; err =mt7996_mcu_add_rate_ctrl (dev, msta_link->sta, vif, link_id, false);if (err) -return err; + goto unlock; msta_link->wcid.tx_info |=MT_WCID_TX_INFO_SET ;break ;
@@ -1179,7 +1182,7 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, link, msta_link, CONN_STATE_PORT_SECURE, false);if (err) -return err; + goto unlock;break ;case MT76_STA_EVENT_DISASSOC :for (i =0 ; i <ARRAY_SIZE (msta_link->twt.flow); i++)
@@ -1199,8 +1202,10 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif,break ; } } +unlock: +mutex_unlock (&dev->mt76.mutex); -return 0 ; +return err; } static void
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 335/507 wifi: mt76: mt7996: skip deflink accounting for offchannel links
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <[email protected]>
[ Upstream commit 4fe823b9ee0317b04ddc6d9e00fea892498aa0f2 ]
Do not take into account offchannel links for deflink accounting.
--- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7996/main.c +4 -2
@@ -372,7 +372,8 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif,ieee80211_iter_keys (mphy->hw, vif, mt7996_key_iter,NULL ); -if (mvif->mt76.deflink_id ==IEEE80211_LINK_UNSPECIFIED ) +if (!mlink->wcid->offchannel && + mvif->mt76.deflink_id ==IEEE80211_LINK_UNSPECIFIED ) mvif->mt76.deflink_id = link_conf->link_id;return 0 ;
@@ -397,7 +398,8 @@ void mt7996_vif_link_remove(struct mt76_phy *mphy, struct ieee80211_vif *vif,rcu_assign_pointer (dev->mt76.wcid[idx],NULL ); -if (mvif->mt76.deflink_id == link_conf->link_id) { +if (!mlink->wcid->offchannel && + mvif->mt76.deflink_id == link_conf->link_id) {struct ieee80211_bss_conf *iter;unsigned int link_id;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 336/507 wifi: mt76: mt7996: Add missing locking in mt7996_mac_sta_rc_work()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <[email protected]>
[ Upstream commit 7545551631fa63101f97974f49ac0b564814f703 ]
Grab the mt76 mutex running mt7996_mac_sta_rc_work() since it is required by mt7996_mcu_add_rate_ctrl routine.
--- drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7996/mac.c +4 -0
@@ -2338,6 +2338,8 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)LIST_HEAD (list);u32 changed; +mutex_lock (&dev->mt76.mutex); +spin_lock_bh (&dev->mt76.sta_poll_lock);list_splice_init (&dev->sta_rc_list, &list);
@@ -2370,6 +2372,8 @@ void mt7996_mac_sta_rc_work(struct work_struct *work) }spin_unlock_bh (&dev->mt76.sta_poll_lock); + +mutex_unlock (&dev->mt76.mutex); }void mt7996_mac_work (struct work_struct *work)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 337/507 mt76: mt7615: Fix memory leak in mt7615_mcu_wtbl_sta_add()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zilin Guan <[email protected]>
[ Upstream commit 53d1548612670aa8b5d89745116cc33d9d172863 ]
In mt7615_mcu_wtbl_sta_add(), an skb sskb is allocated. If the subsequent call to mt76_connac_mcu_alloc_wtbl_req() fails, the function returns an error without freeing sskb, leading to a memory leak.
Fix this by calling dev_kfree_skb() on sskb in the error handling path to ensure it is properly released.
--- drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +3 -1
@@ -874,8 +874,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif, wtbl_hdr =mt76_connac_mcu_alloc_wtbl_req (&dev->mt76, &msta->wcid,WTBL_RESET_AND_SET ,NULL , &wskb); -if (IS_ERR (wtbl_hdr)) +if (IS_ERR (wtbl_hdr)) { +dev_kfree_skb (sskb);return PTR_ERR (wtbl_hdr); + }if (enable) { mt76_connac_mcu_wtbl_generic_tlv(&dev->mt76, wskb, vif, sta,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 338/507 firmware: stratix10-svc: fix make htmldocs warning for stratix10_svc
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dinh Nguyen <[email protected]>
[ Upstream commit 377441d53a2df61b105e823b335010cd4f1a6e56 ]
Fix this warning that was generated from "make htmldocs":
WARNING: drivers/firmware/stratix10-svc.c:58 struct member 'intel_svc_fcs'
not described in 'stratix10_svc'
--- drivers/firmware/stratix10-svc.c | 1 + 1 file changed, 1 insertion(+)
drivers/firmware/stratix10-svc.c +1 -0
@@ -52,6 +52,7 @@ struct stratix10_svc_chan;/** * struct stratix10_svc - svc private data * @stratix10_svc_rsu: pointer to stratix10 RSU device +* @intel_svc_fcs: pointer to the FCS device */ struct stratix10_svc {struct platform_device *stratix10_svc_rsu;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 339/507 staging: fbtft: core: fix potential memory leak in fbtft_probe_common()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianglei Nie <[email protected]>
[ Upstream commit 47d3949a9b04cbcb0e10abae30c2b53e98706e11 ]
fbtft_probe_common() allocates a memory chunk for "info" with fbtft_framebuffer_alloc(). When "display->buswidth == 0" is true, the function returns without releasing the "info", which will lead to a memory leak.
Fix it by calling fbtft_framebuffer_release() when "display->buswidth == 0" is true.
--- drivers/staging/fbtft/fbtft-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/staging/fbtft/fbtft-core.c +2 -2
@@ -1171,8 +1171,8 @@ int fbtft_probe_common(struct fbtft_display *display, par->pdev = pdev;if (display->buswidth ==0 ) { -dev_err (dev,"buswidth is not set\n" ); -return -EINVAL ; + ret =dev_err_probe (dev, -EINVAL ,"buswidth is not set\n" ); + goto out_release; }/* write register functions */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 340/507 iommu/arm-smmu-v3: Fix error check in arm_smmu_alloc_cd_tables
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryan Huang <[email protected]>
[ Upstream commit 5941f0e0c1e0be03ebc15b461f64208f5250d3d9 ]
In arm_smmu_alloc_cd_tables(), the error check following the dma_alloc_coherent() for cd_table->l2.l1tab incorrectly tests cd_table->l2.l2ptrs.
This means an allocation failure for l1tab goes undetected, causing the function to return 0 (success) erroneously.
Correct the check to test cd_table->l2.l1tab.
--- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +1 -1
@@ -1464,7 +1464,7 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master) cd_table->l2.l1tab =dma_alloc_coherent (smmu->dev, l1size, &cd_table->cdtab_dma,GFP_KERNEL ); -if (!cd_table->l2.l2ptrs) { +if (!cd_table->l2.l1tab) { ret = -ENOMEM ; goto err_free_l2ptrs; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 341/507 btrfs: fix double free of qgroup record after failure to add delayed ref head
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miquel Sabaté Solà <[email protected]>
[ Upstream commit 725e46298876a2cc1f1c3fb22ba69d29102c3ddf ]
In the previous code it was possible to incur into a double kfree() scenario when calling add_delayed_ref_head(). This could happen if the record was reported to already exist in the btrfs_qgroup_trace_extent_nolock() call, but then there was an error later on add_delayed_ref_head(). In this case, since add_delayed_ref_head() returned an error, the caller went to free the record. Since add_delayed_ref_head() couldn't set this kfree'd pointer to NULL, then kfree() would have acted on a non-NULL 'record' object which was pointing to memory already freed by the callee.
The problem comes from the fact that the responsibility to kfree the object is on both the caller and the callee at the same time. Hence, the fix for this is to shift the ownership of the 'qrecord' object out of the add_delayed_ref_head(). That is, we will never attempt to kfree() the given object inside of this function, and will expect the caller to act on the 'qrecord' object on its own. The only exception where the 'qrecord' object cannot be kfree'd is if it was inserted into the tracing logic, for which we already have the 'qrecord_inserted_ret' boolean to account for this. Hence, the caller has to kfree the object only if add_delayed_ref_head() reports not to have inserted it on the tracing logic.
As a side-effect of the above, we must guarantee that 'qrecord_inserted_ret' is properly initialized at the start of the function, not at the end, and then set when an actual insert happens. This way we avoid 'qrecord_inserted_ret' having an invalid value on an early exit.
The documentation from the add_delayed_ref_head() has also been updated to reflect on the exact ownership of the 'qrecord' object.
--- fs/btrfs/delayed-ref.c | 43 ++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-)
fs/btrfs/delayed-ref.c +33 -10
@@ -798,9 +798,13 @@ static void init_delayed_ref_head(struct btrfs_delayed_ref_head *head_ref, }/* -* helper function to actually insert a head node into the rbtree. -* this does all the dirty work in terms of maintaining the correct -* overall modification count. +* Helper function to actually insert a head node into the xarray. This does all +* the dirty work in terms of maintaining the correct overall modification +* count. +* +* The caller is responsible for calling kfree() on @qrecord. More specifically, +* if this function reports that it did not insert it as noted in +* @qrecord_inserted_ret, then it's safe to call kfree() on it. * * Returns an error pointer in case of an error. */
@@ -814,7 +818,14 @@ add_delayed_ref_head(struct btrfs_trans_handle *trans,struct btrfs_delayed_ref_head *existing;struct btrfs_delayed_ref_root *delayed_refs;const unsigned long index = (head_ref->bytenr >> fs_info->sectorsize_bits); -bool qrecord_inserted = false; + +/* +* If 'qrecord_inserted_ret' is provided, then the first thing we need +* to do is to initialize it to false just in case we have an exit +* before trying to insert the record. +*/ +if (qrecord_inserted_ret) + *qrecord_inserted_ret = false; delayed_refs = &trans->transaction->delayed_refs;lockdep_assert_held (&delayed_refs->lock);
@@ -833,6 +844,12 @@ add_delayed_ref_head(struct btrfs_trans_handle *trans,/* Record qgroup extent info if provided */ if (qrecord) { +/* +* Setting 'qrecord' but not 'qrecord_inserted_ret' will likely +* result in a memory leakage. +*/ +ASSERT (qrecord_inserted_ret !=NULL ); +int ret; ret = btrfs_qgroup_trace_extent_nolock(fs_info, delayed_refs, qrecord,
@@ -840,12 +857,10 @@ add_delayed_ref_head(struct btrfs_trans_handle *trans,if (ret) {/* Clean up if insertion fails or item exists. */ xa_release (&delayed_refs->dirty_extents, index); -/* Caller responsible for freeing qrecord on error. */ if (ret <0 )return ERR_PTR (ret); -kfree (qrecord); - }else { - qrecord_inserted = true; + }else if (qrecord_inserted_ret) { + *qrecord_inserted_ret = true; } }
@@ -888,8 +903,6 @@ add_delayed_ref_head(struct btrfs_trans_handle *trans, delayed_refs->num_heads++; delayed_refs->num_heads_ready++; } -if (qrecord_inserted_ret) - *qrecord_inserted_ret = qrecord_inserted;return head_ref; }
@@ -1049,6 +1062,14 @@ static int add_delayed_ref(struct btrfs_trans_handle *trans,xa_release (&delayed_refs->head_refs, index);spin_unlock (&delayed_refs->lock); ret =PTR_ERR (new_head_ref); + +/* +* It's only safe to call kfree() on 'qrecord' if +* add_delayed_ref_head() has _not_ inserted it for +* tracing. Otherwise we need to handle this here. +*/ +if (!qrecord_reserved || qrecord_inserted) + goto free_head_ref; goto free_record; } head_ref = new_head_ref;
@@ -1071,6 +1092,8 @@ static int add_delayed_ref(struct btrfs_trans_handle *trans,if (qrecord_inserted)return btrfs_qgroup_trace_extent_post (trans, record, generic_ref->bytenr); + +kfree (record);return 0 ; free_record:
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 342/507 btrfs: fix racy bitfield write in btrfs_clear_space_info_full()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov <[email protected]>
[ Upstream commit 38e818718c5e04961eea0fa8feff3f100ce40408 ]
Quoted 1 line
From the memory-barriers.txt document regarding memory barrier ordering
guarantees:
(*) These guarantees do not apply to bitfields, because compilers often
generate code to modify these using non-atomic read-modify-write sequences. Do not attempt to use bitfields to synchronize parallel algorithms.
(*) Even in cases where bitfields are protected by locks, all fields
in a given bitfield must be protected by one lock. If two fields in a given bitfield are protected by different locks, the compiler's non-atomic read-modify-write sequences can cause an update to one field to corrupt the value of an adjacent field.
btrfs_space_info has a bitfield sharing an underlying word consisting of the fields full, chunk_alloc, and flush:
struct btrfs_space_info {
struct btrfs_fs_info * fs_info; /* 0 8 */
struct btrfs_space_info * parent; /* 8 8 */ ...
int clamp; /* 172 4 */
unsigned int full:1; /* 176: 0 4 */
unsigned int chunk_alloc:1; /* 176: 1 4 */
unsigned int flush:1; /* 176: 2 4 */
...
Therefore, to be safe from parallel read-modify-writes losing a write to one of the bitfield members protected by a lock, all writes to all the bitfields must use the lock. They almost universally do, except for btrfs_clear_space_info_full() which iterates over the space_infos and writes out found->full = 0 without a lock.
Imagine that we have one thread completing a transaction in which we finished deleting a block_group and are thus calling btrfs_clear_space_info_full() while simultaneously the data reclaim ticket infrastructure is running do_async_reclaim_data_space():
T1 T2btrfs_commit_transaction
btrfs_clear_space_info_full
data_sinfo->full = 0
READ: full:0, chunk_alloc:0, flush:1
do_async_reclaim_data_space(data_sinfo)
spin_lock(&space_info->lock);
if(list_empty(tickets))
space_info->flush = 0;
READ: full: 0, chunk_alloc:0, flush:1
MOD/WRITE: full: 0, chunk_alloc:0, flush:0
spin_unlock(&space_info->lock);
return;MOD/WRITE: full:0, chunk_alloc:0, flush:1
and now data_sinfo->flush is 1 but the reclaim worker has exited. This breaks the invariant that flush is 0 iff there is no work queued or running. Once this invariant is violated, future allocations that go into __reserve_bytes() will add tickets to space_info->tickets but will see space_info->flush is set to 1 and not queue the work. After this, they will block forever on the resulting ticket, as it is now impossible to kick the worker again.
I also confirmed by looking at the assembly of the affected kernel that it is doing RMW operations. For example, to set the flush (3rd) bit to 0, the assembly is:
andb $0xfb,0x60(%rbx)
and similarly for setting the full (1st) bit to 0:
andb $0xfe,-0x20(%rax)
So I think this is really a bug on practical systems. I have observed a number of systems in this exact state, but am currently unable to reproduce it.
Rather than leaving this footgun lying around for the future, take advantage of the fact that there is room in the struct anyway, and that it is already quite large and simply change the three bitfield members to bools. This avoids writes to space_info->full having any effect on writes to space_info->flush, regardless of locking.
--- fs/btrfs/block-group.c | 6 +++--- fs/btrfs/space-info.c | 22 +++++++++++----------- fs/btrfs/space-info.h | 6 +++--- 3 files changed, 17 insertions(+), 17 deletions(-)
fs/btrfs/block-group.c +3 -3
@@ -4215,7 +4215,7 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans,mutex_unlock (&fs_info->chunk_mutex); }else {/* Proceed with allocation */ - space_info->chunk_alloc =1 ; + space_info->chunk_alloc = true; wait_for_alloc = false;spin_unlock (&space_info->lock); }
@@ -4264,7 +4264,7 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans,spin_lock (&space_info->lock);if (ret <0 ) {if (ret == -ENOSPC ) - space_info->full =1 ; + space_info->full = true;else goto out; }else {
@@ -4274,7 +4274,7 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, space_info->force_alloc =CHUNK_ALLOC_NO_FORCE ; out: - space_info->chunk_alloc =0 ; + space_info->chunk_alloc = false;spin_unlock (&space_info->lock);mutex_unlock (&fs_info->chunk_mutex);
fs/btrfs/space-info.c +11 -11
@@ -192,7 +192,7 @@ void btrfs_clear_space_info_full(struct btrfs_fs_info *info)struct btrfs_space_info *found;list_for_each_entry (found, head, list) - found->full =0 ; + found->full = false; }/*
@@ -372,7 +372,7 @@ void btrfs_add_bg_to_space_info(struct btrfs_fs_info *info, space_info->bytes_readonly += block_group->bytes_super;btrfs_space_info_update_bytes_zone_unusable (space_info, block_group->zone_unusable);if (block_group->length >0 ) - space_info->full =0 ; + space_info->full = false;btrfs_try_granting_tickets (info, space_info);spin_unlock (&space_info->lock);
@@ -1146,7 +1146,7 @@ static void do_async_reclaim_metadata_space(struct btrfs_space_info *space_info)spin_lock (&space_info->lock); to_reclaim =btrfs_calc_reclaim_metadata_size (fs_info, space_info);if (!to_reclaim) { - space_info->flush =0 ; + space_info->flush = false;spin_unlock (&space_info->lock);return ; }
@@ -1158,7 +1158,7 @@ static void do_async_reclaim_metadata_space(struct btrfs_space_info *space_info)flush_space (fs_info, space_info, to_reclaim, flush_state, false);spin_lock (&space_info->lock);if (list_empty (&space_info->tickets)) { - space_info->flush =0 ; + space_info->flush = false;spin_unlock (&space_info->lock);return ; }
@@ -1201,7 +1201,7 @@ static void do_async_reclaim_metadata_space(struct btrfs_space_info *space_info) flush_state =FLUSH_DELAYED_ITEMS_NR ; commit_cycles--; }else { - space_info->flush =0 ; + space_info->flush = false; } }else { flush_state =FLUSH_DELAYED_ITEMS_NR ;
@@ -1383,7 +1383,7 @@ static void do_async_reclaim_data_space(struct btrfs_space_info *space_info)spin_lock (&space_info->lock);if (list_empty (&space_info->tickets)) { - space_info->flush =0 ; + space_info->flush = false;spin_unlock (&space_info->lock);return ; }
@@ -1394,7 +1394,7 @@ static void do_async_reclaim_data_space(struct btrfs_space_info *space_info)flush_space (fs_info, space_info,U64_MAX ,ALLOC_CHUNK_FORCE , false);spin_lock (&space_info->lock);if (list_empty (&space_info->tickets)) { - space_info->flush =0 ; + space_info->flush = false;spin_unlock (&space_info->lock);return ; }
@@ -1411,7 +1411,7 @@ static void do_async_reclaim_data_space(struct btrfs_space_info *space_info) data_flush_states[flush_state], false);spin_lock (&space_info->lock);if (list_empty (&space_info->tickets)) { - space_info->flush =0 ; + space_info->flush = false;spin_unlock (&space_info->lock);return ; }
@@ -1428,7 +1428,7 @@ static void do_async_reclaim_data_space(struct btrfs_space_info *space_info)if (maybe_fail_all_tickets (fs_info, space_info)) flush_state =0 ;else - space_info->flush =0 ; + space_info->flush = false; }else { flush_state =0 ; }
@@ -1444,7 +1444,7 @@ static void do_async_reclaim_data_space(struct btrfs_space_info *space_info) aborted_fs:maybe_fail_all_tickets (fs_info, space_info); - space_info->flush =0 ; + space_info->flush = false;spin_unlock (&space_info->lock); }
@@ -1825,7 +1825,7 @@ static int __reserve_bytes(struct btrfs_fs_info *fs_info,*/ maybe_clamp_preempt (fs_info, space_info); - space_info->flush =1 ; + space_info->flush = true; trace_btrfs_trigger_flush(fs_info, space_info->flags, orig_bytes, flush,
fs/btrfs/space-info.h +3 -3
@@ -142,11 +142,11 @@ struct btrfs_space_info {flushing. The value is >> clamp, so turns out to be a 2^clamp divisor. */ - unsigned int full:1; /* indicates that we cannot allocate any more +bool full;/* indicates that we cannot allocate any more chunks for this space */ - unsigned int chunk_alloc:1; /* set if we are allocating a chunk */ +bool chunk_alloc;/* set if we are allocating a chunk */ - unsigned int flush:1; /* set if we are trying to make space */ +bool flush;/* set if we are trying to make space */ unsigned int force_alloc;/* set if we need to force a chunk alloc for this space */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 343/507 btrfs: fix leaf leak in an error path in btrfs_del_items()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit e7dd1182fcedee7c6097c9f49eba8de94a4364e3 ]
If the call to btrfs_del_leaf() fails we return without decrementing the extra ref we took on the leaf, therefore leaking it. Fix this by ensuring we drop the ref count before returning the error.
--- fs/btrfs/ctree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/ctree.c +1 -1
@@ -4557,9 +4557,9 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,if (btrfs_header_nritems (leaf) ==0 ) { path->slots[1 ] = slot; ret =btrfs_del_leaf (trans, root, path, leaf); +free_extent_buffer (leaf);if (ret <0 )return ret; -free_extent_buffer (leaf); ret =0 ; }else {/* if we're still in the path, make sure
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 344/507 PCI: dwc: Fix wrong PORT_LOGIC_LTSSM_STATE_MASK definition
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shawn Lin <[email protected]>
[ Upstream commit bcc9a4a0bca3aee4303fa4a20302e57b24ac8f68 ]
As per DesignWare Cores PCI Express Controller Databook, section 5.50,
SII: Debug Signals, cxpl_debug_info[63:0]:
[5:0] smlh_ltssm_state: LTSSM current state. Encoding is same as the dedicated smlh_ltssm_state output.
The mask should be 6 bits, from 0 to 5. Hence, fix the mask definition.
--- drivers/pci/controller/dwc/pcie-designware.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/controller/dwc/pcie-designware.h +1 -1
@@ -95,7 +95,7 @@#define PORT_LANE_SKEW_INSERT_MASK GENMASK(23, 0)#define PCIE_PORT_DEBUG0 0x728 -#define PORT_LOGIC_LTSSM_STATE_MASK 0x1f +#define PORT_LOGIC_LTSSM_STATE_MASK 0x3f#define PORT_LOGIC_LTSSM_STATE_L0 0x11#define PCIE_PORT_DEBUG1 0x72C#define PCIE_PORT_DEBUG1_LINK_UP BIT(4)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 345/507 drm/nouveau: restrict the flush page to a 32-bit address
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Tabi <[email protected]>
[ Upstream commit 04d98b3452331fa53ec3b698b66273af6ef73288 ]
The flush page DMA address is stored in a special register that is not associated with the GPU's standard DMA range. For example, on Turing, the GPU's MMU can handle 47-bit addresses, but the flush page address register is limited to 40 bits.
At the point during device initialization when the flush page is allocated, the DMA mask is still at its default of 32 bits. So even though it's unlikely that the flush page could exist above a 40-bit address, the dma_map_page() call could fail, e.g. if IOMMU is disabled and the address is above 32 bits. The simplest way to achieve all constraints is to allocate the page in the DMA32 zone. Since the flush page is literally just a page, this is an acceptable limitation. The alternative is to temporarily set the DMA mask to 40 (or 52 for Hopper and later) bits, but that could have unforseen side effects.
In situations where the flush page is allocated above 32 bits and IOMMU is disabled, you will get an error like this:
nouveau 0000:65:00.0: DMA addr 0x0000000107c56000+4096 overflow (mask ffffffff, bus limit 0).
--- drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +1 -1
@@ -279,7 +279,7 @@ nvkm_fb_ctor(const struct nvkm_fb_func *func, struct nvkm_device *device,mutex_init (&fb->tags.mutex);if (func->sysmem.flush_page_init) { - fb->sysmem.flush_page =alloc_page (GFP_KERNEL | __GFP_ZERO); + fb->sysmem.flush_page =alloc_page (GFP_KERNEL |GFP_DMA32 | __GFP_ZERO);if (!fb->sysmem.flush_page)return -ENOMEM ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 346/507 um: Dont rename vmap to kernel_vmap
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Gow <[email protected]>
[ Upstream commit a74b6c0e53a6df8e8a096b50c06c4f872906368a ]
In order to work around the existence of a vmap symbol in libpcap, the UML makefile unconditionally redefines vmap to kernel_vmap. However, this not only affects the actual vmap symbol, but also anything else named vmap, including a number of struct members in DRM.
This would not be too much of a problem, since all uses are also updated, except we now have Rust DRM bindings, which expect the corresponding Rust structs to have 'vmap' names. Since the redefinition applies in bindgen, but not to Rust code, we end up with errors such as:
error[E0560]: struct drm_gem_object_funcs has no fields named vmap
--> rust/kernel/drm/gem/mod.rs:210:9
Since libpcap support was removed in commit 12b8e7e69aa7 ("um: Remove obsolete pcap driver"), remove the, now unnecessary, define as well.
We also take this opportunity to update the comment.
--- arch/um/Makefile | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
arch/um/Makefile +5 -7
@@ -46,19 +46,17 @@ ARCH_INCLUDE := -I$(srctree)/$(SHARED_HEADERS) ARCH_INCLUDE += -I$(srctree)/$(HOST_DIR)/um/shared KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/um -# -Dvmap=kernel_vmap prevents anything from referencing the libpcap.o symbol so -# named - it's a common symbol in libpcap, so we get a binary which crashes. -# -# Same things for in6addr_loopback and mktime - found in libc. For these two we -# only get link-time error, luckily. +# -Dstrrchr=kernel_strrchr (as well as the various in6addr symbols) prevents +# anything from referencing +# libc symbols with the same name, which can cause a linker error. # # -Dlongjmp=kernel_longjmp prevents anything from referencing the libpthread.a # embedded copy of longjmp, same thing for setjmp. # -# These apply to USER_CFLAGS to. +# These apply to USER_CFLAGS too. KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ \ - $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ + $(ARCH_INCLUDE) $(MODE_INCLUDE) \ -Dlongjmp=kernel_longjmp -Dsetjmp=kernel_setjmp \ -Din6addr_loopback=kernel_in6addr_loopback \ -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr \
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 347/507 iomap: always run error completions in user context
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit ddb4873286e03e193c5a3bebb5fc6fa820e9ee3a ]
At least zonefs expects error completions to be able to sleep. Because error completions aren't performance critical, just defer them to workqueue context unconditionally.
--- fs/iomap/direct-io.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
fs/iomap/direct-io.c +12 -1
@@ -179,7 +179,18 @@ static void iomap_dio_done(struct iomap_dio *dio)WRITE_ONCE (dio->submit.waiter,NULL );blk_wake_io_task (waiter); - }else if (dio->flags &IOMAP_DIO_INLINE_COMP ) { +return ; + } + +/* +* Always run error completions in user context. These are not +* performance critical and some code relies on taking sleeping locks +* for error handling. +*/ +if (dio->error) + dio->flags &= ~IOMAP_DIO_INLINE_COMP ; + +if (dio->flags &IOMAP_DIO_INLINE_COMP ) {WRITE_ONCE (iocb->private,NULL );iomap_dio_complete_work (&dio->aio.work); }else if (dio->flags &IOMAP_DIO_CALLER_COMP ) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 348/507 wifi: ieee80211: correct FILS status codes
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ria Thomas <[email protected]>
[ Upstream commit 24d4da5c2565313c2ad3c43449937a9351a64407 ]
The FILS status codes are set to 108/109, but the IEEE 802.11-2020 spec defines them as 112/113. Update the enum so it matches the specification and keeps the kernel consistent with standard values.
--- include/linux/ieee80211.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/ieee80211.h +2 -2
@@ -3572,8 +3572,8 @@ enum ieee80211_statuscode {WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL =99 ,WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT =103 ,/* 802.11ai */ -WLAN_STATUS_FILS_AUTHENTICATION_FAILURE =108 , -WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER =109 , +WLAN_STATUS_FILS_AUTHENTICATION_FAILURE =112 , +WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER =113 ,WLAN_STATUS_SAE_HASH_TO_ELEMENT =126 ,WLAN_STATUS_SAE_PK =127 , WLAN_STATUS_DENIED_TID_TO_LINK_MAPPING = 133,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 349/507 backlight: led-bl: Add devlink to supplier LEDs
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luca Ceresoli <[email protected]>
[ Upstream commit 9341d6698f4cfdfc374fb6944158d111ebe16a9d ]
LED Backlight is a consumer of one or multiple LED class devices, but devlink is currently unable to create correct supplier-producer links when the supplier is a class device. It creates instead a link where the supplier is the parent of the expected device.
One consequence is that removal order is not correctly enforced.
Issues happen for example with the following sections in a device tree overlay:
// An LED driver chip
pca9632@62 {
compatible = "nxp,pca9632";
reg = <0x62>;
// ...
addon_led_pwm: led-pwm@3 {
reg = <3>;
label = "addon:led:pwm";
};
};
backlight-addon {
compatible = "led-backlight";
leds = <&addon_led_pwm>;
brightness-levels = <255>;
default-brightness-level = <255>;
};In this example, the devlink should be created between the backlight-addon (consumer) and the pca9632@62 (supplier). Instead it is created between the backlight-addon (consumer) and the parent of the pca9632@62, which is typically the I2C bus adapter.
On removal of the above overlay, the LED driver can be removed before the backlight device, resulting in:
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
...
Call trace:
led_put+0xe0/0x140
devm_led_release+0x6c/0x98Another way to reproduce the bug without any device tree overlays is unbinding the LED class device (pca9632@62) before unbinding the consumer (backlight-addon):
echo 11-0062 >/sys/bus/i2c/drivers/leds-pca963x/unbind echo ...backlight-dock >/sys/bus/platform/drivers/led-backlight/unbind
Fix by adding a devlink between the consuming led-backlight device and the supplying LED device, as other drivers and subsystems do as well.
--- drivers/video/backlight/led_bl.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/video/backlight/led_bl.c +13 -0
@@ -209,6 +209,19 @@ static int led_bl_probe(struct platform_device *pdev)return PTR_ERR (priv->bl_dev); } +for (i =0 ; i < priv->nb_leds; i++) { +struct device_link *link; + + link =device_link_add (&pdev->dev, priv->leds[i]->dev->parent, +DL_FLAG_AUTOREMOVE_CONSUMER ); +if (!link) { +dev_err (&pdev->dev,"Failed to add devlink (consumer %s, supplier %s)\n" , +dev_name (&pdev->dev),dev_name (priv->leds[i]->dev->parent)); +backlight_device_unregister (priv->bl_dev); +return -EINVAL ; + } + } +for (i =0 ; i < priv->nb_leds; i++) {mutex_lock (&priv->leds[i]->led_access);led_sysfs_disable (priv->leds[i]);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 350/507 backlight: lp855x: Fix lp855x.h kernel-doc warnings
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randy Dunlap <[email protected]>
[ Upstream commit 2d45db63260c6ae3cf007361e04a1c41bd265084 ]
Add a missing struct short description and a missing leading " *" to lp855x.h to avoid kernel-doc warnings:
Warning: include/linux/platform_data/lp855x.h:126 missing initial short
description on line:
* struct lp855x_platform_data
Warning: include/linux/platform_data/lp855x.h:131 bad line:
Only valid when mode is PWM_BASED.
--- include/linux/platform_data/lp855x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/platform_data/lp855x.h +2 -2
@@ -124,12 +124,12 @@ struct lp855x_rom_data { };/** -* struct lp855x_platform_data +* struct lp855x_platform_data - lp855 platform-specific data * @name : Backlight driver name. If it is not defined, default name is set. * @device_control : value of DEVICE CONTROL register * @initial_brightness : initial value of backlight brightness * @period_ns : platform specific pwm period value. unit is nano. -Only valid when mode is PWM_BASED. +* Only valid when mode is PWM_BASED. * @size_program : total size of lp855x_rom_data * @rom_data : list of new eeprom/eprom registers */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 351/507 iommu/arm-smmu-qcom: Enable use of all SMR groups when running bare-metal
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephan Gerhold <[email protected]>
[ Upstream commit 5583a55e074b33ccd88ac0542fd7cd656a7e2c8c ]
Some platforms (e.g. SC8280XP and X1E) support more than 128 stream matching groups. This is more than what is defined as maximum by the ARM SMMU architecture specification. Commit 122611347326 ("iommu/arm-smmu-qcom:
Limit the SMR groups to 128") disabled use of the additional groups because they don't exhibit the same behavior as the architecture supported ones.
It seems like this is just another quirk of the hypervisor: When running bare-metal without the hypervisor, the additional groups appear to behave just like all others. The boot firmware uses some of the additional groups, so ignoring them in this situation leads to stream match conflicts whenever we allocate a new SMR group for the same SID.
The workaround exists primarily because the bypass quirk detection fails when using a S2CR register from the additional matching groups, so let's perform the test with the last reliable S2CR (127) and then limit the number of SMR groups only if we detect that we are running below the hypervisor (because of the bypass quirk).
--- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 27 ++++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-)
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +17 -10
@@ -431,17 +431,19 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)/* * Some platforms support more than the Arm SMMU architected maximum of -* 128 stream matching groups. For unknown reasons, the additional -* groups don't exhibit the same behavior as the architected registers, -* so limit the groups to 128 until the behavior is fixed for the other -* groups. +* 128 stream matching groups. The additional registers appear to have +* the same behavior as the architected registers in the hardware. +* However, on some firmware versions, the hypervisor does not +* correctly trap and emulate accesses to the additional registers, +* resulting in unexpected behavior. +* +* If there are more than 128 groups, use the last reliable group to +* detect if we need to apply the bypass quirk. */ -if (smmu->num_mapping_groups >128 ) { -dev_notice (smmu->dev,"\tLimiting the stream matching groups to 128\n" ); - smmu->num_mapping_groups =128 ; - } - - last_s2cr =ARM_SMMU_GR0_S2CR (smmu->num_mapping_groups -1 ); +if (smmu->num_mapping_groups >128 ) + last_s2cr =ARM_SMMU_GR0_S2CR (127 ); +else + last_s2cr =ARM_SMMU_GR0_S2CR (smmu->num_mapping_groups -1 );/* * With some firmware versions writes to S2CR of type FAULT are
@@ -464,6 +466,11 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) reg =FIELD_PREP (ARM_SMMU_CBAR_TYPE ,CBAR_TYPE_S1_TRANS_S2_BYPASS );arm_smmu_gr1_write (smmu,ARM_SMMU_GR1_CBAR (qsmmu->bypass_cbndx), reg); + +if (smmu->num_mapping_groups >128 ) { +dev_notice (smmu->dev,"\tLimiting the stream matching groups to 128\n" ); + smmu->num_mapping_groups =128 ; + } }for (i =0 ; i < smmu->num_mapping_groups; i++) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 352/507 RDMA/irdma: Fix data race in irdma_sc_ccq_arm
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Czurylo <[email protected]>
[ Upstream commit a521928164433de44fed5aaf5f49aeb3f1fb96f5 ]
Adds a lock around irdma_sc_ccq_arm body to prevent inter-thread data race. Fixes data race in irdma_sc_ccq_arm() reported by KCSAN:
BUG: KCSAN: data-race in irdma_sc_ccq_arm [irdma] / irdma_sc_ccq_arm [irdma]
read to 0xffff9d51b4034220 of 8 bytes by task 255 on cpu 11:
irdma_sc_ccq_arm+0x36/0xd0 [irdma] irdma_cqp_ce_handler+0x300/0x310 [irdma] cqp_compl_worker+0x2a/0x40 [irdma] process_one_work+0x402/0x7e0 worker_thread+0xb3/0x6d0 kthread+0x178/0x1a0 ret_from_fork+0x2c/0x50
write to 0xffff9d51b4034220 of 8 bytes by task 89 on cpu 3:
irdma_sc_ccq_arm+0x7e/0xd0 [irdma] irdma_cqp_ce_handler+0x300/0x310 [irdma] irdma_wait_event+0xd4/0x3e0 [irdma] irdma_handle_cqp_op+0xa5/0x220 [irdma] irdma_hw_flush_wqes+0xb1/0x300 [irdma] irdma_flush_wqes+0x22e/0x3a0 [irdma] irdma_cm_disconn_true+0x4c7/0x5d0 [irdma] irdma_disconnect_worker+0x35/0x50 [irdma] process_one_work+0x402/0x7e0 worker_thread+0xb3/0x6d0 kthread+0x178/0x1a0 ret_from_fork+0x2c/0x50
value changed: 0x0000000000024000 -> 0x0000000000034000
--- drivers/infiniband/hw/irdma/ctrl.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/infiniband/hw/irdma/ctrl.c +3 -0
@@ -3316,11 +3316,13 @@ int irdma_sc_cqp_destroy(struct irdma_sc_cqp *cqp)*/ void irdma_sc_ccq_arm (struct irdma_sc_cq *ccq) { +unsigned long flags;u64 temp_val;u16 sw_cq_sel;u8 arm_next_se;u8 arm_seq_num; +spin_lock_irqsave (&ccq->dev->cqp_lock, flags);get_64bit_val (ccq->cq_uk.shadow_area,32 , &temp_val); sw_cq_sel = (u16 )FIELD_GET (IRDMA_CQ_DBSA_SW_CQ_SELECT , temp_val); arm_next_se = (u8 )FIELD_GET (IRDMA_CQ_DBSA_ARM_NEXT_SE , temp_val);
@@ -3331,6 +3333,7 @@ void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq)FIELD_PREP (IRDMA_CQ_DBSA_ARM_NEXT_SE , arm_next_se) |FIELD_PREP (IRDMA_CQ_DBSA_ARM_NEXT ,1 );set_64bit_val (ccq->cq_uk.shadow_area,32 , temp_val); +spin_unlock_irqrestore (&ccq->dev->cqp_lock, flags);dma_wmb ();/* make sure shadow area is updated before arming */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 353/507 RDMA/irdma: Fix data race in irdma_free_pble
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Czurylo <[email protected]>
[ Upstream commit 81f44409fb4f027d1e6d54edbeba5156ad94b214 ]
Protects pble_rsrc counters with mutex to prevent data race. Fixes the following data race in irdma_free_pble reported by KCSAN:
BUG: KCSAN: data-race in irdma_free_pble [irdma] / irdma_free_pble [irdma]
write to 0xffff91430baa0078 of 8 bytes by task 16956 on cpu 5:
irdma_free_pble+0x3b/0xb0 [irdma] irdma_dereg_mr+0x108/0x110 [irdma] ib_dereg_mr_user+0x74/0x160 [ib_core] uverbs_free_mr+0x26/0x30 [ib_uverbs] destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] uobj_destroy+0x61/0xb0 [ib_uverbs] ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] __x64_sys_ioctl+0xc9/0x100 do_syscall_64+0x44/0xa0 entry_SYSCALL_64_after_hwframe+0x6e/0xd8
read to 0xffff91430baa0078 of 8 bytes by task 16953 on cpu 2:
irdma_free_pble+0x23/0xb0 [irdma] irdma_dereg_mr+0x108/0x110 [irdma] ib_dereg_mr_user+0x74/0x160 [ib_core] uverbs_free_mr+0x26/0x30 [ib_uverbs] destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] uobj_destroy+0x61/0xb0 [ib_uverbs] ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] __x64_sys_ioctl+0xc9/0x100 do_syscall_64+0x44/0xa0 entry_SYSCALL_64_after_hwframe+0x6e/0xd8
value changed: 0x0000000000005a62 -> 0x0000000000005a68
--- drivers/infiniband/hw/irdma/pble.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/infiniband/hw/irdma/pble.c +4 -2
@@ -498,12 +498,14 @@ int irdma_get_pble(struct irdma_hmc_pble_rsrc *pble_rsrc,void irdma_free_pble (struct irdma_hmc_pble_rsrc *pble_rsrc,struct irdma_pble_alloc *palloc) { - pble_rsrc->freedpbles += palloc->total_cnt; -if (palloc->level ==PBLE_LEVEL_2 )free_lvl2 (pble_rsrc, palloc);else irdma_prm_return_pbles (&pble_rsrc->pinfo, &palloc->level1.chunkinfo); + +mutex_lock (&pble_rsrc->pble_mutex_lock); + pble_rsrc->freedpbles += palloc->total_cnt; pble_rsrc->stats_alloc_freed++; +mutex_unlock (&pble_rsrc->pble_mutex_lock); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 354/507 RDMA/irdma: Do not directly rely on IB_PD_UNSAFE_GLOBAL_RKEY
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacob Moroni <[email protected]>
[ Upstream commit 71d3bdae5eab21cf8991a6f3cd914caa31d5a51f ]
The HW disables bounds checking for MRs with a length of zero, so the driver will only allow a zero length MR if the "all_memory" flag is set, and this flag is only set if IB_PD_UNSAFE_GLOBAL_RKEY is set for the PD.
This means that the "get_dma_mr" method will currently fail unless the IB_PD_UNSAFE_GLOBAL_RKEY flag is set. This has not been an issue because the "get_dma_mr" method is only ever invoked if the device does not support the local DMA key or if IB_PD_UNSAFE_GLOBAL_RKEY is set, and so far, all IRDMA HW supports the local DMA lkey.
However, some new HW does not support the local DMA lkey, so the "get_dma_mr" method needs to work without IB_PD_UNSAFE_GLOBAL_RKEY being set.
To support HW that does not allow the local DMA lkey, the logic has been changed to pass an explicit flag to indicate when a dma_mr is being created so that the zero length will be allowed.
Also, the "all_memory" flag has been forced to false for normal MR allocation since these MRs are never supposed to provide global unsafe rkey semantics anyway; only the MR created with "get_dma_mr" should support this.
--- drivers/infiniband/hw/irdma/cm.c | 2 +- drivers/infiniband/hw/irdma/main.h | 2 +- drivers/infiniband/hw/irdma/verbs.c | 15 ++++++++------- drivers/infiniband/hw/irdma/verbs.h | 3 ++- 4 files changed, 12 insertions(+), 10 deletions(-)
drivers/infiniband/hw/irdma/cm.c +1 -1
@@ -3710,7 +3710,7 @@ int irdma_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) iwpd = iwqp->iwpd; tagged_offset = (uintptr_t )iwqp->ietf_mem.va; ibmr =irdma_reg_phys_mr (&iwpd->ibpd, iwqp->ietf_mem.pa, buf_len, -IB_ACCESS_LOCAL_WRITE , &tagged_offset); +IB_ACCESS_LOCAL_WRITE , &tagged_offset, false);if (IS_ERR (ibmr)) { ret = -ENOMEM ; goto error;
drivers/infiniband/hw/irdma/main.h +1 -1
@@ -538,7 +538,7 @@ void irdma_copy_ip_htonl(__be32 *dst, u32 *src);u16 irdma_get_vlan_ipv4 (u32 *addr);void irdma_get_vlan_mac_ipv6 (u32 *addr,u16 *vlan_id,u8 *mac);struct ib_mr *irdma_reg_phys_mr (struct ib_pd *ib_pd,u64 addr,u64 size, -int acc,u64 *iova_start); +int acc,u64 *iova_start,bool dma_mr);int irdma_upload_qp_context (struct irdma_qp *iwqp,bool freeze,bool raw);void irdma_cqp_ce_handler (struct irdma_pci_f *rf,struct irdma_sc_cq *cq); int irdma_ah_cqp_op(struct irdma_pci_f *rf, struct irdma_sc_ah *sc_ah, u8 cmd,
drivers/infiniband/hw/irdma/verbs.c +8 -7
@@ -2654,7 +2654,6 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev, info->stag_idx = iwmr->stag >>IRDMA_CQPSQ_STAG_IDX_S ; info->pd_id = iwpd->sc_pd.pd_id; info->total_len = iwmr->len; - info->all_memory = pd->flags &IB_PD_UNSAFE_GLOBAL_RKEY ; info->remote_access = true; cqp_info->cqp_cmd =IRDMA_OP_ALLOC_STAG ; cqp_info->post_sq =1 ;
@@ -2665,7 +2664,7 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev,if (status)return status; - iwmr->is_hwreg =1 ; + iwmr->is_hwreg = true;return 0 ; }
@@ -2806,7 +2805,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr, stag_info->total_len = iwmr->len; stag_info->access_rights =irdma_get_mr_access (access); stag_info->pd_id = iwpd->sc_pd.pd_id; - stag_info->all_memory = pd->flags &IB_PD_UNSAFE_GLOBAL_RKEY ; + stag_info->all_memory = iwmr->dma_mr;if (stag_info->access_rights &IRDMA_ACCESS_FLAGS_ZERO_BASED ) stag_info->addr_type =IRDMA_ADDR_TYPE_ZERO_BASED ;else
@@ -2833,7 +2832,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr,irdma_put_cqp_request (&iwdev->rf->cqp, cqp_request);if (!ret) - iwmr->is_hwreg =1 ; + iwmr->is_hwreg = true;return ret; }
@@ -3169,7 +3168,7 @@ static int irdma_hwdereg_mr(struct ib_mr *ib_mr)if (status)return status; - iwmr->is_hwreg =0 ; + iwmr->is_hwreg = false;return 0 ; }
@@ -3292,9 +3291,10 @@ static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags,* @size: size of memory to register * @access: Access rights * @iova_start: start of virtual address for physical buffers +* @dma_mr: Flag indicating whether this region is a PD DMA MR */ struct ib_mr *irdma_reg_phys_mr (struct ib_pd *pd,u64 addr,u64 size,int access, -u64 *iova_start) +u64 *iova_start,bool dma_mr) {struct irdma_device *iwdev =to_iwdev (pd->device);struct irdma_pbl *iwpbl;
@@ -3311,6 +3311,7 @@ struct ib_mr *irdma_reg_phys_mr(struct ib_pd *pd, u64 addr, u64 size, int access iwpbl = &iwmr->iwpbl; iwpbl->iwmr = iwmr; iwmr->type =IRDMA_MEMREG_TYPE_MEM ; + iwmr->dma_mr = dma_mr; iwpbl->user_base = *iova_start; stag =irdma_create_stag (iwdev);if (!stag) {
@@ -3349,7 +3350,7 @@ static struct ib_mr *irdma_get_dma_mr(struct ib_pd *pd, int acc) {u64 kva =0 ; -return irdma_reg_phys_mr (pd,0 ,0 , acc, &kva); +return irdma_reg_phys_mr (pd,0 ,0 , acc, &kva, true); }/**
drivers/infiniband/hw/irdma/verbs.h +2 -1
@@ -101,7 +101,8 @@ struct irdma_mr { };struct ib_umem *region;int access; -u8 is_hwreg; + bool is_hwreg:1; + bool dma_mr:1;u16 type;u32 page_cnt;u64 page_size;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 355/507 drm/panthor: Avoid adding of kernel BOs to extobj list
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Akash Goel <[email protected]>
[ Upstream commit ce04ec03a9c2c4f3e60e26f21311b25d5a478208 ]
The kernel BOs unnecessarily got added to the external objects list of drm_gpuvm, when mapping to GPU, which would have resulted in few extra CPU cycles being spent at the time of job submission as drm_exec_until_all_locked() loop iterates over all external objects.
Kernel BOs are private to a VM and so they share the dma_resv object of the dummy GEM object created for a VM. Use of DRM_EXEC_IGNORE_DUPLICATES flag ensured the recursive locking of the dummy GEM object was ignored. Also no extra space got allocated to add fences to the dma_resv object of dummy GEM object. So no other impact apart from few extra CPU cycles.
This commit sets the pointer to dma_resv object of GEM object of kernel BOs before they are mapped to GPU, to prevent them from being added to external objects list.
v2: Add R-bs and fixes tags
--- drivers/gpu/drm/panthor/panthor_gem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/panthor/panthor_gem.c +3 -3
@@ -145,6 +145,9 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, bo =to_panthor_bo (&obj->base); kbo->obj = &obj->base; bo->flags = bo_flags; + bo->exclusive_vm_root_gem =panthor_vm_root_gem (vm); +drm_gem_object_get (bo->exclusive_vm_root_gem); + bo->base.base.resv = bo->exclusive_vm_root_gem->resv;if (vm ==panthor_fw_vm (ptdev)) debug_flags |=PANTHOR_DEBUGFS_GEM_USAGE_FLAG_FW_MAPPED ;
@@ -168,9 +171,6 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, goto err_free_va; kbo->vm =panthor_vm_get (vm); - bo->exclusive_vm_root_gem =panthor_vm_root_gem (vm); -drm_gem_object_get (bo->exclusive_vm_root_gem); - bo->base.base.resv = bo->exclusive_vm_root_gem->resv;return kbo; err_free_va:
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 356/507 clocksource/drivers/ralink: Fix resource leaks in init error path
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 2ba8e2aae1324704565a7d4d66f199d056c9e3c6 ]
The ralink_systick_init() function does not release all acquired resources on its error paths. If irq_of_parse_and_map() or a subsequent call fails, the previously created I/O memory mapping and IRQ mapping are leaked.
Add goto-based error handling labels to ensure that all allocated resources are correctly freed.
--- drivers/clocksource/timer-ralink.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/clocksource/timer-ralink.c +9 -2
@@ -130,14 +130,15 @@ static int __init ralink_systick_init(struct device_node *np) systick.dev.irq =irq_of_parse_and_map (np,0 );if (!systick.dev.irq) {pr_err ("%pOFn: request_irq failed" , np); -return -EINVAL ; + ret = -EINVAL ; + goto err_iounmap; } ret =clocksource_mmio_init (systick.membase +SYSTICK_COUNT , np->name,SYSTICK_FREQ ,301 ,16 , clocksource_mmio_readl_up);if (ret) -return ret; + goto err_free_irq;clockevents_register_device (&systick.dev);
@@ -145,6 +146,12 @@ static int __init ralink_systick_init(struct device_node *np) np, systick.dev.mult, systick.dev.shift);return 0 ; + +err_free_irq: +irq_dispose_mapping (systick.dev.irq); +err_iounmap: +iounmap (systick.membase); +return ret; }TIMER_OF_DECLARE (systick,"ralink,cevt-systick" , ralink_systick_init);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 357/507 clocksource/drivers/stm: Fix double deregistration on probe failure
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit 6b38a8b31e2c5c2c3fd5f9848850788c190f216d ]
The purpose of the devm_add_action_or_reset() helper is to call the action function in case adding an action ever fails so drop the clock source deregistration from the error path to avoid deregistering twice.
--- drivers/clocksource/timer-nxp-stm.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/clocksource/timer-nxp-stm.c +1 -3
@@ -207,10 +207,8 @@ static int __init nxp_stm_clocksource_init(struct device *dev, struct stm_timerreturn ret; ret =devm_add_action_or_reset (dev, devm_clocksource_unregister, stm_timer); -if (ret) { -clocksource_unregister (&stm_timer->cs); +if (ret)return ret; - } stm_sched_clock = stm_timer;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 358/507 clocksource/drivers/nxp-stm: Fix section mismatches
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit b452d2c97eeccbf9c7ac5b3d2d9e80bf6d8a23db ]
Platform drivers can be probed after their init sections have been discarded (e.g. on probe deferral or manual rebind through sysfs) so the probe function must not live in init. Device managed resource actions similarly cannot be discarded.
The "_probe" suffix of the driver structure name prevents modpost from warning about this so replace it to catch any similar future issues.
Stable-dep-of: 6a2416892e89 ("clocksource/drivers/nxp-stm: Prevent driver unbind")
--- drivers/clocksource/timer-nxp-stm.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/clocksource/timer-nxp-stm.c +9 -9
@@ -177,15 +177,15 @@ static void nxp_stm_clocksource_resume(struct clocksource *cs)nxp_stm_clocksource_enable (cs); } -static void __init devm_clocksource_unregister (void *data) +static void devm_clocksource_unregister (void *data) {struct stm_timer *stm_timer = data;clocksource_unregister (&stm_timer->cs); } -static int __init nxp_stm_clocksource_init (struct device *dev,struct stm_timer *stm_timer, -const char *name,void __iomem *base,struct clk *clk) +static int nxp_stm_clocksource_init (struct device *dev,struct stm_timer *stm_timer, +const char *name,void __iomem *base,struct clk *clk) {int ret;
@@ -295,9 +295,9 @@ static void nxp_stm_clockevent_resume(struct clock_event_device *ced)nxp_stm_module_get (stm_timer); } -static int __init nxp_stm_clockevent_per_cpu_init (struct device *dev,struct stm_timer *stm_timer, -const char *name,void __iomem *base,int irq, -struct clk *clk,int cpu) +static int nxp_stm_clockevent_per_cpu_init (struct device *dev,struct stm_timer *stm_timer, +const char *name,void __iomem *base,int irq, +struct clk *clk,int cpu) { stm_timer->base = base; stm_timer->rate =clk_get_rate (clk);
@@ -384,7 +384,7 @@ static irqreturn_t nxp_stm_module_interrupt(int irq, void *dev_id)return IRQ_HANDLED ; } -static int __init nxp_stm_timer_probe (struct platform_device *pdev) +static int nxp_stm_timer_probe (struct platform_device *pdev) {struct stm_timer *stm_timer;struct device *dev = &pdev->dev;
@@ -480,14 +480,14 @@ static const struct of_device_id nxp_stm_of_match[] = { };MODULE_DEVICE_TABLE (of, nxp_stm_of_match); -static struct platform_driver nxp_stm_probe = { +static struct platform_driver nxp_stm_driver = { .probe = nxp_stm_timer_probe, .driver = { .name ="nxp-stm" , .of_match_table = nxp_stm_of_match, }, }; -module_platform_driver (nxp_stm_probe); +module_platform_driver (nxp_stm_driver);MODULE_DESCRIPTION ("NXP System Timer Module driver" );MODULE_LICENSE ("GPL" );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 359/507 clocksource/drivers/nxp-stm: Prevent driver unbind
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit 6a2416892e8942f5e2bfe9b85c0164f410a53a2d ]
Clockevents cannot be deregistered so suppress the bind attributes to prevent the driver from being unbound and releasing the underlying resources after registration.
Even if the driver can currently only be built-in, also switch to builtin_platform_driver() to prevent it from being unloaded should modular builds ever be enabled.
--- drivers/clocksource/timer-nxp-stm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/clocksource/timer-nxp-stm.c +2 -1
@@ -485,9 +485,10 @@ static struct platform_driver nxp_stm_driver = { .driver = { .name = "nxp-stm", .of_match_table = nxp_stm_of_match, + .suppress_bind_attrs = true, }, }; -module_platform_driver (nxp_stm_driver); +builtin_platform_driver (nxp_stm_driver);MODULE_DESCRIPTION ("NXP System Timer Module driver" );MODULE_LICENSE ("GPL" );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 360/507 ASoC: nau8325: use simple i2c probe function
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaroslav Kysela <[email protected]>
[ Upstream commit b4d072c98e47c562834f2a050ca98a1c709ef4f9 ]
The i2c probe functions here don't use the id information provided in their second argument, so the single-parameter i2c probe function ("probe_new") can be used instead.
This avoids scanning the identifier tables during probes.
Stable-dep-of: cd41d3420ef6 ("ASoC: nau8325: add missing build config")
--- sound/soc/codecs/nau8325.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
sound/soc/codecs/nau8325.c +1 -2
@@ -829,8 +829,7 @@ static int nau8325_read_device_properties(struct device *dev,return 0 ; } -static int nau8325_i2c_probe (struct i2c_client *i2c, -const struct i2c_device_id *id) +static int nau8325_i2c_probe (struct i2c_client *i2c) {struct device *dev = &i2c->dev;struct nau8325 *nau8325 =dev_get_platdata (dev);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 361/507 ASoC: nau8325: add missing build config
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaroslav Kysela <[email protected]>
[ Upstream commit cd41d3420ef658b2ca902d7677536ec8e25b610a ]
This configuration was missing from the initial commit.
Found by Jiri Benc <[email protected]>
--- sound/soc/codecs/Kconfig | 5 +++++ sound/soc/codecs/Makefile | 2 ++ 2 files changed, 7 insertions(+)
sound/soc/codecs/Kconfig +5 -0
@@ -169,6 +169,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_MT6359 imply SND_SOC_MT6660 imply SND_SOC_NAU8315 + imply SND_SOC_NAU8325 imply SND_SOC_NAU8540 imply SND_SOC_NAU8810 imply SND_SOC_NAU8821
@@ -2655,6 +2656,10 @@ config SND_SOC_MT6660 config SND_SOC_NAU8315 tristate "Nuvoton Technology Corporation NAU8315 CODEC" +config SND_SOC_NAU8325 + tristate "Nuvoton Technology Corporation NAU8325 CODEC" + depends on I2C + config SND_SOC_NAU8540 tristate "Nuvoton Technology Corporation NAU85L40 CODEC" depends on I2C
sound/soc/codecs/Makefile +2 -0
@@ -190,6 +190,7 @@ snd-soc-mt6359-y := mt6359.o snd-soc-mt6359-accdet-y := mt6359-accdet.o snd-soc-mt6660-y := mt6660.o snd-soc-nau8315-y := nau8315.o +snd-soc-nau8325-y := nau8325.o snd-soc-nau8540-y := nau8540.o snd-soc-nau8810-y := nau8810.o snd-soc-nau8821-y := nau8821.o
@@ -610,6 +611,7 @@ obj-$(CONFIG_SND_SOC_MT6359) += snd-soc-mt6359.o obj-$(CONFIG_SND_SOC_MT6359_ACCDET) += mt6359-accdet.o obj-$(CONFIG_SND_SOC_MT6660) += snd-soc-mt6660.o obj-$(CONFIG_SND_SOC_NAU8315) += snd-soc-nau8315.o +obj-$(CONFIG_SND_SOC_NAU8325) += snd-soc-nau8325.o obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o obj-$(CONFIG_SND_SOC_NAU8821) += snd-soc-nau8821.o
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 362/507 gfs2: Prevent recursive memory reclaim
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Gruenbacher <[email protected]>
[ Upstream commit 2c5f4a53476e3cab70adc77b38942c066bd2c17c ]
Function new_inode() returns a new inode with inode->i_mapping->gfp_mask set to GFP_HIGHUSER_MOVABLE. This value includes the __GFP_FS flag, so allocations in that address space can recurse into filesystem memory reclaim. We don't want that to happen because it can consume a significant amount of stack memory.
Worse than that is that it can also deadlock: for example, in several places, gfs2_unstuff_dinode() is called inside filesystem transactions. This calls filemap_grab_folio(), which can allocate a new folio, which can trigger memory reclaim. If memory reclaim recurses into the filesystem and starts another transaction, a deadlock will ensue.
To fix these kinds of problems, prevent memory reclaim from recursing into filesystem code by making sure that the gfp_mask of inode address spaces doesn't include __GFP_FS.
The "meta" and resource group address spaces were already using GFP_NOFS as their gfp_mask (which doesn't include __GFP_FS). The default value of GFP_HIGHUSER_MOVABLE is less restrictive than GFP_NOFS, though. To avoid being overly limiting, use the default value and only knock off the __GFP_FS flag. I'm not sure if this will actually make a difference, but it also shouldn't hurt.
This patch is loosely based on commit ad22c7a043c2 ("xfs: prevent stack overflows from page cache allocation").
Fixes xfstest generic/273.
--- fs/gfs2/glock.c | 5 ++++- fs/gfs2/inode.c | 15 +++++++++++++++ fs/gfs2/inode.h | 1 + fs/gfs2/ops_fstype.c | 2 +- 4 files changed, 21 insertions(+), 2 deletions(-)
fs/gfs2/glock.c +4 -1
@@ -1205,10 +1205,13 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, mapping =gfs2_glock2aspace (gl);if (mapping) { +gfp_t gfp_mask; + mapping->a_ops = &gfs2_meta_aops; mapping->host = sdp->sd_inode; mapping->flags =0 ; -mapping_set_gfp_mask (mapping,GFP_NOFS ); + gfp_mask =mapping_gfp_mask (sdp->sd_inode->i_mapping); +mapping_set_gfp_mask (mapping, gfp_mask); mapping->i_private_data =NULL ; mapping->writeback_index =0 ; }
fs/gfs2/inode.c +15 -0
@@ -89,6 +89,19 @@ static int iget_set(struct inode *inode, void *opaque)return 0 ; } +void gfs2_setup_inode (struct inode *inode) +{ +gfp_t gfp_mask; + +/* +* Ensure all page cache allocations are done from GFP_NOFS context to +* prevent direct reclaim recursion back into the filesystem and blowing +* stacks or deadlocking. +*/ + gfp_mask =mapping_gfp_mask (inode->i_mapping); +mapping_set_gfp_mask (inode->i_mapping, gfp_mask & ~__GFP_FS); +} +/** * gfs2_inode_lookup - Lookup an inode * @sb: The super block
@@ -132,6 +145,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,struct gfs2_glock *io_gl;int extra_flags =0 ; +gfs2_setup_inode (inode); error =gfs2_glock_get (sdp, no_addr, &gfs2_inode_glops,CREATE , &ip->i_gl);if (unlikely (error))
@@ -752,6 +766,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, error = -ENOMEM ;if (!inode) goto fail_gunlock; +gfs2_setup_inode (inode); ip =GFS2_I (inode); error =posix_acl_create (dir, &mode, &default_acl, &acl);
fs/gfs2/inode.h +1 -0
@@ -86,6 +86,7 @@ static inline int gfs2_check_internal_file_size(struct inode *inode,return -EIO ; } +void gfs2_setup_inode (struct inode *inode);struct inode *gfs2_inode_lookup (struct super_block *sb,unsigned type,u64 no_addr,u64 no_formal_ino,unsigned int blktype);
fs/gfs2/ops_fstype.c +1 -1
@@ -1183,7 +1183,7 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc) mapping =gfs2_aspace (sdp); mapping->a_ops = &gfs2_rgrp_aops; -mapping_set_gfp_mask (mapping,GFP_NOFS ); +gfs2_setup_inode (sdp->sd_inode); error =init_names (sdp, silent);if (error)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 363/507 ASoC: fsl_xcvr: clear the channel status control memory
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit 73b97d46dde64fa184d47865d4a532d818c3a007 ]
memset_io() writes memory byte by byte with __raw_writeb() on the arm platform if the size is word. but XCVR data RAM memory can't be accessed with byte address, so with memset_io() the channel status control memory is not really cleared, use writel_relaxed() instead.
--- sound/soc/fsl/fsl_xcvr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/fsl/fsl_xcvr.c +1 -1
@@ -1421,7 +1421,7 @@ static irqreturn_t irq0_isr(int irq, void *devid)bitrev32 (val); }/* clear CS control register */ -memset_io (reg_ctrl,0 ,sizeof (val)); +writel_relaxed (0 , reg_ctrl); } }else { regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_0,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 364/507 firmware_loader: make RUST_FW_LOADER_ABSTRACTIONS select FW_LOADER
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexandre Courbot <[email protected]>
[ Upstream commit 9906efa545d1d2cf25a614eeb219d3f8d5a302cd ]
The use of firmware_loader is an implementation detail of drivers rather than a dependency. FW_LOADER is typically selected rather than depended on; the Rust abstractions should do the same thing.
--- drivers/base/firmware_loader/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/base/firmware_loader/Kconfig +1 -1
@@ -38,7 +38,7 @@ config FW_LOADER_DEBUG config RUST_FW_LOADER_ABSTRACTIONS bool "Rust Firmware Loader abstractions" depends on RUST - depends on FW_LOADER=y + select FW_LOADER help This enables the Rust abstractions for the firmware loader API.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 365/507 greybus: gb-beagleplay: Fix timeout handling in bootloader functions
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit e6df0f649cff08da7a2feb6d963b39076ca129f9 ]
wait_for_completion_timeout() returns the remaining jiffies (at least 1) on success or 0 on timeout, but never negative error codes. The current code incorrectly checks for negative values, causing timeouts to be ignored and treated as success.
Check for a zero return value to correctly identify and handle timeout events.
--- drivers/greybus/gb-beagleplay.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/greybus/gb-beagleplay.c +6 -6
@@ -644,8 +644,8 @@ static int cc1352_bootloader_wait_for_ack(struct gb_beagleplay *bg) ret =wait_for_completion_timeout ( &bg->fwl_ack_com,msecs_to_jiffies (CC1352_BOOTLOADER_TIMEOUT )); -if (ret <0 ) -return dev_err_probe (&bg->sd->dev, ret, +if (!ret) +return dev_err_probe (&bg->sd->dev, -ETIMEDOUT ,"Failed to acquire ack semaphore" );switch (READ_ONCE (bg->fwl_ack)) {
@@ -683,8 +683,8 @@ static int cc1352_bootloader_get_status(struct gb_beagleplay *bg) ret =wait_for_completion_timeout ( &bg->fwl_cmd_response_com,msecs_to_jiffies (CC1352_BOOTLOADER_TIMEOUT )); -if (ret <0 ) -return dev_err_probe (&bg->sd->dev, ret, +if (!ret) +return dev_err_probe (&bg->sd->dev, -ETIMEDOUT ,"Failed to acquire last status semaphore" );switch (READ_ONCE (bg->fwl_cmd_response)) {
@@ -768,8 +768,8 @@ static int cc1352_bootloader_crc32(struct gb_beagleplay *bg, u32 *crc32) ret =wait_for_completion_timeout ( &bg->fwl_cmd_response_com,msecs_to_jiffies (CC1352_BOOTLOADER_TIMEOUT )); -if (ret <0 ) -return dev_err_probe (&bg->sd->dev, ret, +if (!ret) +return dev_err_probe (&bg->sd->dev, -ETIMEDOUT ,"Failed to acquire last status semaphore" ); *crc32 =READ_ONCE (bg->fwl_cmd_response);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 366/507 misc: rp1: Fix an error handling path in rp1_probe()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
[ Upstream commit 43cd4b634ef90c4e2ff75eaeb361786fa04c8874 ]
When DT is used to get the reference of 'rp1_node', it should be released when not needed anymore, otherwise it is leaking.
In such a case, add the missing of_node_put() call at the end of the probe, as already done in the error handling path.
--- drivers/misc/rp1/rp1_pci.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/misc/rp1/rp1_pci.c +3 -0
@@ -289,6 +289,9 @@ static int rp1_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_unload_overlay; } +if (skip_ovl) +of_node_put (rp1_node); +return 0 ; err_unload_overlay:
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 367/507 kernfs: fix memory leak of kernfs_iattrs in __kernfs_new_node
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Will Rosenberg <[email protected]>
[ Upstream commit 382b1e8f30f779af8d6d33268e53df7de579ef3c ]
There exists a memory leak of kernfs_iattrs contained as an element of kernfs_node allocated in __kernfs_new_node(). __kernfs_setattr() allocates kernfs_iattrs as a sub-object, and the LSM security check incorrectly errors out and does not free the kernfs_iattrs sub-object.
Make an additional error out case that properly frees kernfs_iattrs if security_kernfs_init_security() fails.
--- fs/kernfs/dir.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/kernfs/dir.c +4 -1
@@ -675,11 +675,14 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,if (parent) { ret =security_kernfs_init_security (parent, kn);if (ret) - goto err_out3; + goto err_out4; }return kn; + err_out4: +simple_xattrs_free (&kn->iattr->xattrs,NULL ); +kmem_cache_free (kernfs_iattrs_cache, kn->iattr); err_out3:spin_lock (&root->kernfs_idr_lock);idr_remove (&root->ino_idr, (u32 )kernfs_ino (kn));
Signature · 1 line
2.51.0
Re: [PATCH 6.17 367/507] kernfs: fix memory leak of kernfs_iattrs in __kernfs_new_node
Quoted 1 line · Greg Kroah-Hartman
6.17-stable review patch. If anyone has any objections, please let me know.
Please see https://lkml.org/lkml/2025/12/16/1248.
Greg Kroah-Hartman
maintainerPATCH 368/507 drm/amd/display: Fix logical vs bitwise bug in get_embedded_panel_info_v2_1()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 1a79482699b4d1e43948d14f0c7193dc1dcad858 ]
The .H_SYNC_POLARITY and .V_SYNC_POLARITY variables are 1 bit bitfields of a u32. The ATOM_HSYNC_POLARITY define is 0x2 and the ATOM_VSYNC_POLARITY is 0x4. When we do a bitwise negate of 0, 2, or 4 then the last bit is always 1 so this code always sets .H_SYNC_POLARITY and .V_SYNC_POLARITY to true.
This code is instead intended to check if the ATOM_HSYNC_POLARITY or ATOM_VSYNC_POLARITY flags are set and reverse the result. In other words, it's supposed to be a logical negate instead of a bitwise negate.
--- drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +4 -4
@@ -1480,10 +1480,10 @@ static enum bp_result get_embedded_panel_info_v2_1(/* not provided by VBIOS */ info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF =0 ; - info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t ) (lvds->lcd_timing.miscinfo - &ATOM_HSYNC_POLARITY ); - info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t ) (lvds->lcd_timing.miscinfo - &ATOM_VSYNC_POLARITY ); + info->lcd_timing.misc_info.H_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & +ATOM_HSYNC_POLARITY ); + info->lcd_timing.misc_info.V_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & +ATOM_VSYNC_POLARITY );/* not provided by VBIOS */ info->lcd_timing.misc_info.VERTICAL_CUT_OFF =0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 369/507 hwmon: sy7636a: Fix regulator_enable resource leak on error path
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 2f88425ef590b7fcc2324334b342e048edc144a9 ]
In sy7636a_sensor_probe(), regulator_enable() is called but if devm_hwmon_device_register_with_info() fails, the function returns without calling regulator_disable(), leaving the regulator enabled and leaking the reference count.
Switch to devm_regulator_get_enable() to automatically manage the regulator resource.
--- drivers/hwmon/sy7636a-hwmon.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
drivers/hwmon/sy7636a-hwmon.c +1 -6
@@ -66,18 +66,13 @@ static const struct hwmon_chip_info sy7636a_chip_info = {static int sy7636a_sensor_probe (struct platform_device *pdev) {struct regmap *regmap =dev_get_regmap (pdev->dev.parent,NULL ); -struct regulator *regulator;struct device *hwmon_dev;int err;if (!regmap)return -EPROBE_DEFER ; - regulator =devm_regulator_get (&pdev->dev,"vcom" ); -if (IS_ERR (regulator)) -return PTR_ERR (regulator); - - err =regulator_enable (regulator); + err =devm_regulator_get_enable (&pdev->dev,"vcom" );if (err)return err;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 370/507 ACPI: processor_core: fix map_x2apic_id for amd-pstate on am4
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: René Rebe <[email protected]>
[ Upstream commit 17e7972979e147cc51d4a165e6b6b0f93273ca68 ]
On all AMD AM4 systems I have seen, e.g ASUS X470-i, Pro WS X570 Ace and equivalent Gigabyte, amd-pstate does not initialize when the x2apic is enabled in the BIOS. Kernel debug messages include:
[ 0.315438] acpi LNXCPU:00: Failed to get CPU physical ID. [ 0.354756] ACPI CPPC: No CPC descriptor for CPU:0 [ 0.714951] amd_pstate: the _CPC object is not present in SBIOS or ACPI disabled
I tracked this down to map_x2apic_id() checking device_declaration passed in via the type argument of acpi_get_phys_id() via map_madt_entry() while map_lapic_id() does not.
It appears these BIOSes use Processor statements for declaring the CPUs in the ACPI namespace instead of processor device objects (which should have been used). CPU declarations via Processor statements were deprecated in ACPI 6.0 that was released 10 years ago. They should not be used any more in any contemporary platform firmware.
I tried to contact Asus support multiple times, but never received a reply nor did any BIOS update ever change this.
Fix amd-pstate w/ x2apic on am4 by allowing map_x2apic_id() to work with CPUs declared via Processor statements for IDs less than 255, which is consistent with ACPI 5.0 that still allowed Processor statements to be used for declaring CPUs.
--- drivers/acpi/processor_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/processor_core.c +1 -1
@@ -54,7 +54,7 @@ static int map_x2apic_id(struct acpi_subtable_header *entry,if (!(apic->lapic_flags &ACPI_MADT_ENABLED ))return -ENODEV ; -if (device_declaration && (apic->uid == acpi_id)) { +if (apic->uid == acpi_id && (device_declaration || acpi_id <255 )) { *apic_id = apic->local_apic_id;return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 371/507 ublk: prevent invalid access with DEBUG
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kevin Brodsky <[email protected]>
[ Upstream commit c6a45ee7607de3a350008630f4369b1b5ac80884 ]
ublk_ch_uring_cmd_local() may jump to the out label before initialising the io pointer. This will cause trouble if DEBUG is defined, because the pr_devel() call dereferences io. Clang reports:
drivers/block/ublk_drv.c:2403:6: error: variable 'io' is used uninitialized whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized]
2403 | if (tag >= ub->dev_info.queue_depth)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/block/ublk_drv.c:2492:32: note: uninitialized use occurs here
2492 | __func__, cmd_op, tag, ret, io->flags);
|Fix this by initialising io to NULL and checking it before dereferencing it.
--- drivers/block/ublk_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/block/ublk_drv.c +2 -2
@@ -2340,7 +2340,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd,u16 buf_idx =UBLK_INVALID_BUF_IDX ;struct ublk_device *ub = cmd->file->private_data;struct ublk_queue *ubq; -struct ublk_io *io; +struct ublk_io *io =NULL ;u32 cmd_op = cmd->cmd_op;unsigned tag = ub_cmd->tag;struct request *req;
@@ -2458,7 +2458,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, out:pr_devel ("%s: complete: cmd op %d, tag %d ret %x io_flags %x\n" , - __func__, cmd_op, tag, ret, io->flags); + __func__, cmd_op, tag, ret, io ? io->flags :0 );return ret; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 372/507 ext4: improve integrity checking in __mb_check_buddy by enhancing order-0 validation
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongjian Sun <[email protected]>
[ Upstream commit d9ee3ff810f1cc0e253c9f2b17b668b973cb0e06 ]
When the MB_CHECK_ASSERT macro is enabled, we found that the current validation logic in __mb_check_buddy has a gap in detecting certain invalid buddy states, particularly related to order-0 (bitmap) bits.
The original logic consists of three steps:
1. Validates higher-order buddies: if a higher-order bit is set, at most one of the two corresponding lower-order bits may be free; if a higher-order bit is clear, both lower-order bits must be allocated (and their bitmap bits must be 0).
2. For any set bit in order-0, ensures all corresponding higher-order bits are not free.
3. Verifies that all preallocated blocks (pa) in the group have pa_pstart within bounds and their bitmap bits marked as allocated.
However, this approach fails to properly validate cases where order-0 bits are incorrectly cleared (0), allowing some invalid configurations to pass:
corrupt integral
order 3 1 1
order 2 1 1 1 1
order 1 1 1 1 1 1 1 1 1
order 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Here we get two adjacent free blocks at order-0 with inconsistent higher-order state, and the right one shows the correct scenario.
The root cause is insufficient validation of order-0 zero bits. To fix this and improve completeness without significant performance cost, we refine the logic:
1. Maintain the top-down higher-order validation, but we no longer check the cases where the higher-order bit is 0, as this case will be covered in step 2.
2. Enhance order-0 checking by examining pairs of bits:
- If either bit in a pair is set (1), all corresponding higher-order bits must not be free.
- If both bits are clear (0), then exactly one of the corresponding higher-order bits must be free
3. Keep the preallocation (pa) validation unchanged.
This change closes the validation gap, ensuring illegal buddy states involving order-0 are correctly detected, while removing redundant checks and maintaining efficiency.
Message-ID: <[email protected]>
--- fs/ext4/mballoc.c | 49 +++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 17 deletions(-)
fs/ext4/mballoc.c +32 -17
@@ -682,6 +682,24 @@ do { \ } \ }while (0 ) +/* +* Perform buddy integrity check with the following steps: +* +* 1. Top-down validation (from highest order down to order 1, excluding order-0 bitmap): +* For each pair of adjacent orders, if a higher-order bit is set (indicating a free block), +* at most one of the two corresponding lower-order bits may be clear (free). +* +* 2. Order-0 (bitmap) validation, performed on bit pairs: +* - If either bit in a pair is set (1, allocated), then all corresponding higher-order bits +* must not be free (0). +* - If both bits in a pair are clear (0, free), then exactly one of the corresponding +* higher-order bits must be free (0). +* +* 3. Preallocation (pa) list validation: +* For each preallocated block (pa) in the group: +* - Verify that pa_pstart falls within the bounds of this block group. +* - Ensure the corresponding bit(s) in the order-0 bitmap are marked as allocated (1). +*/ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file,const char *function,int line) {
@@ -723,15 +741,6 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file,continue ; } -/* both bits in buddy2 must be 1 */ -MB_CHECK_ASSERT (mb_test_bit (i <<1 , buddy2)); -MB_CHECK_ASSERT (mb_test_bit ((i <<1 ) +1 , buddy2)); - -for (j =0 ; j < (1 << order); j++) { - k = (i * (1 << order)) + j; -MB_CHECK_ASSERT ( - !mb_test_bit (k, e4b->bd_bitmap)); - } count++; }MB_CHECK_ASSERT (e4b->bd_info->bb_counters[order] == count);
@@ -747,15 +756,21 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, fragments++; fstart = i; } -continue ; + }else { + fstart =-1 ; } - fstart =-1 ; -/* check used bits only */ -for (j =0 ; j < e4b->bd_blkbits +1 ; j++) { - buddy2 =mb_find_buddy (e4b, j, &max2); - k = i >> j; -MB_CHECK_ASSERT (k < max2); -MB_CHECK_ASSERT (mb_test_bit (k, buddy2)); +if (!(i &1 )) { +int in_use, zero_bit_count =0 ; + + in_use =mb_test_bit (i, buddy) ||mb_test_bit (i +1 , buddy); +for (j =1 ; j < e4b->bd_blkbits +2 ; j++) { + buddy2 =mb_find_buddy (e4b, j, &max2); + k = i >> j; +MB_CHECK_ASSERT (k < max2); +if (!mb_test_bit (k, buddy2)) + zero_bit_count++; + } +MB_CHECK_ASSERT (zero_bit_count == !in_use); } }MB_CHECK_ASSERT (!EXT4_MB_GRP_NEED_INIT (e4b->bd_info));
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 373/507 selftests/net: packetdrill: pass send_omit_free to MSG_ZEROCOPY tests
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Willem de Bruijn <[email protected]>
[ Upstream commit c01a6e5b2e4f21d31cf725b9f3803cb0280b1b8d ]
The --send_omit_free flag is needed for TCP zero copy tests, to ensure that packetdrill doesn't free the send() buffer after the send() call.
--- .../net/packetdrill/tcp_syscall_bad_arg_sendmsg-empty-iov.pkt | 4 ++++ .../testing/selftests/net/packetdrill/tcp_zerocopy_basic.pkt | 2 ++ .../testing/selftests/net/packetdrill/tcp_zerocopy_batch.pkt | 2 ++ .../testing/selftests/net/packetdrill/tcp_zerocopy_client.pkt | 2 ++ .../testing/selftests/net/packetdrill/tcp_zerocopy_closed.pkt | 2 ++ .../selftests/net/packetdrill/tcp_zerocopy_epoll_edge.pkt | 3 +++ .../net/packetdrill/tcp_zerocopy_epoll_exclusive.pkt | 3 +++ .../selftests/net/packetdrill/tcp_zerocopy_epoll_oneshot.pkt | 3 +++ .../net/packetdrill/tcp_zerocopy_fastopen-client.pkt | 2 ++ .../net/packetdrill/tcp_zerocopy_fastopen-server.pkt | 2 ++ .../selftests/net/packetdrill/tcp_zerocopy_maxfrags.pkt | 2 ++ .../testing/selftests/net/packetdrill/tcp_zerocopy_small.pkt | 2 ++ 12 files changed, 29 insertions(+)
tools/testing/selftests/net/packetdrill/tcp_syscall_bad_arg_sendmsg-empty-iov.pkt +4 -0
@@ -1,6 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 // Test that we correctly skip zero-length IOVs. + +--send_omit_free // do not reuse send buffers with zerocopy + `./defaults.sh` + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0 setsockopt(3, SOL_SOCKET, SO_ZEROCOPY, [1], 4) = 0 +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
tools/testing/selftests/net/packetdrill/tcp_zerocopy_basic.pkt +2 -0
@@ -4,6 +4,8 @@ // send a packet with MSG_ZEROCOPY and receive the notification ID // repeat and verify IDs are consecutive +--send_omit_free // do not reuse send buffers with zerocopy + `./defaults.sh` 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
tools/testing/selftests/net/packetdrill/tcp_zerocopy_batch.pkt +2 -0
@@ -3,6 +3,8 @@ // // send multiple packets, then read one range of all notifications. +--send_omit_free // do not reuse send buffers with zerocopy + `./defaults.sh` 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
tools/testing/selftests/net/packetdrill/tcp_zerocopy_client.pkt +2 -0
@@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 // Minimal client-side zerocopy test +--send_omit_free // do not reuse send buffers with zerocopy + `./defaults.sh` 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4
tools/testing/selftests/net/packetdrill/tcp_zerocopy_closed.pkt +2 -0
@@ -7,6 +7,8 @@ // First send on a closed socket and wait for (absent) notification. // Then connect and send and verify that notification nr. is zero. +--send_omit_free // do not reuse send buffers with zerocopy + `./defaults.sh` 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4
tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_edge.pkt +3 -0
@@ -7,6 +7,9 @@ // fire two sends with MSG_ZEROCOPY and receive the acks. confirm that EPOLLERR // is correctly fired only once, when EPOLLET is set. send another packet with // MSG_ZEROCOPY. confirm that EPOLLERR is correctly fired again only once. + +--send_omit_free // do not reuse send buffers with zerocopy + `./defaults.sh` 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_exclusive.pkt +3 -0
@@ -8,6 +8,9 @@ // fire two sends with MSG_ZEROCOPY and receive the acks. confirm that EPOLLERR // is correctly fired only once, when EPOLLET is set. send another packet with // MSG_ZEROCOPY. confirm that EPOLLERR is correctly fired again only once. + +--send_omit_free // do not reuse send buffers with zerocopy + `./defaults.sh` 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_oneshot.pkt +3 -0
@@ -8,6 +8,9 @@ // is correctly fired only once, when EPOLLONESHOT is set. send another packet // with MSG_ZEROCOPY. confirm that EPOLLERR is not fired. Rearm the FD and // confirm that EPOLLERR is correctly set. + +--send_omit_free // do not reuse send buffers with zerocopy + `./defaults.sh` 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-client.pkt +2 -0
@@ -8,6 +8,8 @@ // one will have no data in the initial send. On return 0 the // zerocopy notification counter is not incremented. Verify this too. +--send_omit_free // do not reuse send buffers with zerocopy + `./defaults.sh` // Send a FastOpen request, no cookie yet so no data in SYN
tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-server.pkt +2 -0
@@ -4,6 +4,8 @@ // send data with MSG_FASTOPEN | MSG_ZEROCOPY and verify that the // kernel returns the notification ID. +--send_omit_free // do not reuse send buffers with zerocopy + `./defaults.sh ./set_sysctls.py /proc/sys/net/ipv4/tcp_fastopen=0x207`
tools/testing/selftests/net/packetdrill/tcp_zerocopy_maxfrags.pkt +2 -0
@@ -7,6 +7,8 @@ // because each iovec element becomes a frag // 3) the PSH bit is set on an skb when it runs out of fragments +--send_omit_free // do not reuse send buffers with zerocopy + `./defaults.sh` 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
tools/testing/selftests/net/packetdrill/tcp_zerocopy_small.pkt +2 -0
@@ -4,6 +4,8 @@ // verify that SO_EE_CODE_ZEROCOPY_COPIED is set on zerocopy // packets of all sizes, including the smallest payload, 1B. +--send_omit_free // do not reuse send buffers with zerocopy + `./defaults.sh` 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 374/507 of: Skip devicetree kunit tests when RISCV+ACPI doesnt populate root node
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit 546dbb0223102813ffb5bbcb9443a47c3183f195 ]
Starting with commit 69a8b62a7aa1 ("riscv: acpi: avoid errors caused by probing DT devices when ACPI is used"), riscv images no longer populate devicetree if ACPI is enabled. This causes unit tests to fail which require the root node to be set.
# Subtest: of_dtb
# module: of_test
1..2
# of_dtb_root_node_found_by_path: EXPECTATION FAILED at drivers/of/of_test.c:21 Expected np is not null, but is
# of_dtb_root_node_found_by_path: pass:0 fail:1 skip:0 total:1
not ok 1 of_dtb_root_node_found_by_path
# of_dtb_root_node_populates_of_root: EXPECTATION FAILED at drivers/of/of_test.c:31 Expected of_root is not null, but is
# of_dtb_root_node_populates_of_root: pass:0 fail:1 skip:0 total:1 not ok 2 of_dtb_root_node_populates_of_root
Skip those tests for RISCV if the root node is not populated.
--- drivers/of/of_kunit_helpers.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/of/of_kunit_helpers.c +3 -2
@@ -18,8 +18,9 @@*/ void of_root_kunit_skip (struct kunit *test) { -if (IS_ENABLED (CONFIG_ARM64 ) &&IS_ENABLED (CONFIG_ACPI ) && !of_root) -kunit_skip (test,"arm64+acpi doesn't populate a root node" ); +if ((IS_ENABLED (CONFIG_ARM64 ) ||IS_ENABLED (CONFIG_RISCV )) && +IS_ENABLED (CONFIG_ACPI ) && !of_root) +kunit_skip (test,"arm64/riscv+acpi doesn't populate a root node" ); }EXPORT_SYMBOL_GPL (of_root_kunit_skip);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 375/507 virtio_vdpa: fix misleading return in void function
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alok Tiwari <[email protected]>
[ Upstream commit e40b6abe0b1247d43bc61942aa7534fca7209e44 ]
virtio_vdpa_set_status() is declared as returning void, but it used "return vdpa_set_status()" Since vdpa_set_status() also returns void, the return statement is unnecessary and misleading. Remove it.
Message-Id: <[email protected]>
--- drivers/virtio/virtio_vdpa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/virtio/virtio_vdpa.c +1 -1
@@ -80,7 +80,7 @@ static void virtio_vdpa_set_status(struct virtio_device *vdev, u8 status) {struct vdpa_device *vdpa =vd_get_vdpa (vdev); -return vdpa_set_status (vdpa, status); +vdpa_set_status (vdpa, status); }static void virtio_vdpa_reset (struct virtio_device *vdev)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 376/507 virtio: fix typo in virtio_device_ready() comment
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael S. Tsirkin <[email protected]>
[ Upstream commit 361173f95ae4b726ebbbf0bd594274f5576c4abc ]
"coherenct" -> "coherent"
Message-Id: <db286e9a65449347f6584e68c9960fd5ded2b4b0.1763026134.git.mst@redhat.com>
--- include/linux/virtio_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/virtio_config.h +1 -1
@@ -290,7 +290,7 @@ void virtio_device_ready(struct virtio_device *dev)* specific set_status() method. * * A well behaved device will only notify a virtqueue after -* DRIVER_OK, this means the device should "see" the coherenct +* DRIVER_OK, this means the device should "see" the coherent * memory write that set vq->broken as false which is done by * the driver when it sees DRIVER_OK, then the following * driver's vring_interrupt() will see vq->broken as false so
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 377/507 virtio: fix whitespace in virtio_config_ops
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael S. Tsirkin <[email protected]>
[ Upstream commit 7831791e77a1cd29528d4dc336ce14466aef5ba6 ]
The finalize_features documentation uses a tab between words. Use space instead.
Message-Id: <39d7685c82848dc6a876d175e33a1407f6ab3fc1.1763026134.git.mst@redhat.com>
--- include/linux/virtio_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/virtio_config.h +1 -1
@@ -86,7 +86,7 @@ struct virtqueue_info {* vdev: the virtio_device * This sends the driver feature bits to the device: it can change * the dev->feature bits if it wants. -* Note that despite the name this can be called any number of +* Note that despite the name this can be called any number of * times. * Returns 0 on success or error status * @bus_name: return the bus name associated with the device (optional)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 378/507 virtio: fix grammar in virtio_queue_info docs
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael S. Tsirkin <[email protected]>
[ Upstream commit 63598fba55ab9d384818fed48dc04006cecf7be4 ]
Fix grammar in the description of @ctx
Message-Id: <a5cf2b92573200bdb1c1927e559d3930d61a4af2.1763026134.git.mst@redhat.com>
--- include/linux/virtio_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/virtio_config.h +1 -1
@@ -24,7 +24,7 @@ typedef void vq_callback_t(struct virtqueue *);* a virtqueue unused by the driver. * @callback: A callback to invoke on a used buffer notification. * NULL for a virtqueue that does not need a callback. -* @ctx: A flag to indicate to maintain an extra context per virtqueue. +* @ctx: whether to maintain an extra context per virtqueue. */ struct virtqueue_info {const char *name;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 379/507 virtio: fix virtqueue_set_affinity() docs
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael S. Tsirkin <[email protected]>
[ Upstream commit 43236d8bbafff94b423afecc4a692dd90602d426 ]
Rewrite the comment for better grammar and clarity.
Message-Id: <e317e91bd43b070e5eaec0ebbe60c5749d02e2dd.1763026134.git.mst@redhat.com>
--- include/linux/virtio_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/virtio_config.h +1 -1
@@ -312,7 +312,7 @@ const char *virtio_bus_name(struct virtio_device *vdev)* @vq: the virtqueue * @cpu_mask: the cpu mask * -* Pay attention the function are best-effort: the affinity hint may not be set +* Note that this function is best-effort: the affinity hint may not be set * due to config support, irq type and sharing. * */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 380/507 vdpa/mlx5: Fix incorrect error code reporting in query_virtqueues
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alok Tiwari <[email protected]>
[ Upstream commit f0ea2e91093ac979d07ebd033e0f45869b1d2608 ]
When query_virtqueues() fails, the error log prints the variable err instead of cmd->err. Since err may still be zero at this point, the log message can misleadingly report a success value 0 even though the command actually failed.
Even worse, once err is set to the first failure, subsequent logs print that same stale value. This makes the error reporting appear one step behind the actual failing queue index, which is confusing and misleading.
Fix the log to report cmd->err, which reflects the real failure code returned by the firmware.
Message-Id: <[email protected]>
--- drivers/vdpa/mlx5/net/mlx5_vnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/vdpa/mlx5/net/mlx5_vnet.c +1 -1
@@ -1256,7 +1256,7 @@ static int query_virtqueues(struct mlx5_vdpa_net *ndev,int vq_idx = start_vq + i;if (cmd->err) { -mlx5_vdpa_err (mvdev,"query vq %d failed, err: %d\n" , vq_idx, err); +mlx5_vdpa_err (mvdev,"query vq %d failed, err: %d\n" , vq_idx, cmd->err);if (!err) err = cmd->err;continue ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 381/507 vhost: Fix kthread worker cgroup failure handling
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Christie <[email protected]>
[ Upstream commit f3f64c2eaffbc3169bbe1e5d1e897e6dacc839d1 ]
If we fail to attach to a cgroup we are leaking the id. This adds a new goto to free the id.
Message-Id: <[email protected]>
--- drivers/vhost/vhost.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/vhost/vhost.c +3 -1
@@ -804,11 +804,13 @@ static int vhost_kthread_worker_create(struct vhost_worker *worker, ret =vhost_attach_task_to_cgroups (worker);if (ret) - goto stop_worker; + goto free_id; worker->id = id;return 0 ; +free_id: +xa_erase (&dev->worker_xa, id); stop_worker:vhost_kthread_do_stop (worker);return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 382/507 vdpa/pds: use %pe for ERR_PTR() in event handler registration
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alok Tiwari <[email protected]>
[ Upstream commit 731ca4a4cc52fd5c5ae309edcfd2d7e54ece3321 ]
Use %pe instead of %ps when printing ERR_PTR() values. %ps is intended for string pointers, while %pe correctly prints symbolic error names for error pointers returned via ERR_PTR().
This shows the returned error value more clearly.
Message-Id: <[email protected]>
--- drivers/vdpa/pds/vdpa_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/vdpa/pds/vdpa_dev.c +1 -1
@@ -51,7 +51,7 @@ static int pds_vdpa_register_event_handler(struct pds_vdpa_device *pdsv) err =pdsc_register_notify (nb);if (err) { nb->notifier_call =NULL ; -dev_err (dev,"failed to register pds event handler: %ps\n" , +dev_err (dev,"failed to register pds event handler: %pe\n" ,ERR_PTR (err));return -EINVAL ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 383/507 virtio: clean up features qword/dword terms
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael S. Tsirkin <[email protected]>
[ Upstream commit 9513f25056b22100ddffe24898c587873b0d022c ]
virtio pci uses word to mean "16 bits". mmio uses it to mean "32 bits".
To avoid confusion, let's avoid the term in core virtio altogether. Just say U64 to mean "64 bit".
Message-ID: <ad53b7b6be87fc524f45abaeca0bb05fb3633397.1764225384.git.mst@redhat.com>
--- drivers/vhost/net.c | 12 +++++------ drivers/virtio/virtio.c | 12 +++++------ drivers/virtio/virtio_debug.c | 10 ++++----- drivers/virtio/virtio_pci_modern_dev.c | 6 +++--- include/linux/virtio.h | 2 +- include/linux/virtio_config.h | 2 +- include/linux/virtio_features.h | 29 +++++++++++++------------- include/linux/virtio_pci_modern.h | 8 +++---- 8 files changed, 41 insertions(+), 40 deletions(-)
drivers/vhost/net.c +6 -6
@@ -69,7 +69,7 @@ MODULE_PARM_DESC(experimental_zcopytx, "Enable Zero Copy TX;"#define VHOST_DMA_IS_DONE (len) ((__force u32)(len) >= (__force u32)VHOST_DMA_DONE_LEN) -static const u64 vhost_net_features[VIRTIO_FEATURES_DWORDS ] = { +static const u64 vhost_net_features[VIRTIO_FEATURES_U64S ] = {VHOST_FEATURES | (1ULL <<VHOST_NET_F_VIRTIO_NET_HDR ) | (1ULL << VIRTIO_NET_F_MRG_RXBUF) |
@@ -1731,7 +1731,7 @@ static long vhost_net_set_owner(struct vhost_net *n)static long vhost_net_ioctl (struct file *f,unsigned int ioctl,unsigned long arg) { -u64 all_features[VIRTIO_FEATURES_DWORDS ]; +u64 all_features[VIRTIO_FEATURES_U64S ];struct vhost_net *n = f->private_data;void __user *argp = (void __user *)arg;u64 __user *featurep = argp;
@@ -1763,7 +1763,7 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl,/* Copy the net features, up to the user-provided buffer size */ argp +=sizeof (u64); - copied =min (count,VIRTIO_FEATURES_DWORDS ); + copied =min (count, (u64 )VIRTIO_FEATURES_U64S );if (copy_to_user (argp, vhost_net_features, copied *sizeof (u64)))return -EFAULT ;
@@ -1778,13 +1778,13 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl,virtio_features_zero (all_features); argp +=sizeof (u64); - copied =min (count,VIRTIO_FEATURES_DWORDS ); + copied =min (count, (u64 )VIRTIO_FEATURES_U64S );if (copy_from_user (all_features, argp, copied *sizeof (u64)))return -EFAULT ;/* * Any feature specified by user-space above -* VIRTIO_FEATURES_MAX is not supported by definition. +* VIRTIO_FEATURES_BITS is not supported by definition. */ for (i = copied; i < count; ++i) { if (copy_from_user(&features, featurep + 1 + i,
@@ -1794,7 +1794,7 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl,return -EOPNOTSUPP ; } -for (i =0 ; i <VIRTIO_FEATURES_DWORDS ; i++) +for (i =0 ; i <VIRTIO_FEATURES_U64S ; i++)if (all_features[i] & ~vhost_net_features[i])return -EOPNOTSUPP ;
drivers/virtio/virtio.c +6 -6
@@ -53,7 +53,7 @@ static ssize_t features_show(struct device *_d,/* We actually represent this as a bitstring, as it could be * arbitrary length in future. */ -for (i =0 ; i <VIRTIO_FEATURES_MAX ; i++) +for (i =0 ; i <VIRTIO_FEATURES_BITS ; i++) len +=sysfs_emit_at (buf, len,"%c" ,__virtio_test_bit (dev, i) ?'1' :'0' ); len +=sysfs_emit_at (buf, len,"\n" );
@@ -272,8 +272,8 @@ static int virtio_dev_probe(struct device *_d)int err, i;struct virtio_device *dev =dev_to_virtio (_d);struct virtio_driver *drv =drv_to_virtio (dev->dev.driver); -u64 device_features[VIRTIO_FEATURES_DWORDS ]; -u64 driver_features[VIRTIO_FEATURES_DWORDS ]; +u64 device_features[VIRTIO_FEATURES_U64S ]; +u64 driver_features[VIRTIO_FEATURES_U64S ];u64 driver_features_legacy;/* We have a driver! */
@@ -286,7 +286,7 @@ static int virtio_dev_probe(struct device *_d)virtio_features_zero (driver_features);for (i =0 ; i < drv->feature_table_size; i++) {unsigned int f = drv->feature_table[i]; -if (!WARN_ON_ONCE (f >=VIRTIO_FEATURES_MAX )) +if (!WARN_ON_ONCE (f >=VIRTIO_FEATURES_BITS ))virtio_features_set_bit (driver_features, f); }
@@ -303,7 +303,7 @@ static int virtio_dev_probe(struct device *_d) }if (virtio_features_test_bit (device_features,VIRTIO_F_VERSION_1 )) { -for (i =0 ; i <VIRTIO_FEATURES_DWORDS ; ++i) +for (i =0 ; i <VIRTIO_FEATURES_U64S ; ++i) dev->features_array[i] = driver_features[i] & device_features[i]; }else {
@@ -325,7 +325,7 @@ static int virtio_dev_probe(struct device *_d) goto err;if (drv->validate) { -u64 features[VIRTIO_FEATURES_DWORDS ]; +u64 features[VIRTIO_FEATURES_U64S ];virtio_features_copy (features, dev->features_array); err = drv->validate (dev);
drivers/virtio/virtio_debug.c +5 -5
@@ -8,12 +8,12 @@ static struct dentry *virtio_debugfs_dir;static int virtio_debug_device_features_show (struct seq_file *s,void *data) { -u64 device_features[VIRTIO_FEATURES_DWORDS ]; +u64 device_features[VIRTIO_FEATURES_U64S ];struct virtio_device *dev = s->private;unsigned int i;virtio_get_features (dev, device_features); -for (i =0 ; i <VIRTIO_FEATURES_MAX ; i++) { +for (i =0 ; i <VIRTIO_FEATURES_BITS ; i++) {if (virtio_features_test_bit (device_features, i))seq_printf (s,"%u\n" , i); }
@@ -26,7 +26,7 @@ static int virtio_debug_filter_features_show(struct seq_file *s, void *data)struct virtio_device *dev = s->private;unsigned int i; -for (i =0 ; i <VIRTIO_FEATURES_MAX ; i++) { +for (i =0 ; i <VIRTIO_FEATURES_BITS ; i++) {if (virtio_features_test_bit (dev->debugfs_filter_features, i))seq_printf (s,"%u\n" , i); }
@@ -50,7 +50,7 @@ static int virtio_debug_filter_feature_add(void *data, u64 val) {struct virtio_device *dev = data; -if (val >=VIRTIO_FEATURES_MAX ) +if (val >=VIRTIO_FEATURES_BITS )return -EINVAL ;virtio_features_set_bit (dev->debugfs_filter_features, val);
@@ -64,7 +64,7 @@ static int virtio_debug_filter_feature_del(void *data, u64 val) {struct virtio_device *dev = data; -if (val >=VIRTIO_FEATURES_MAX ) +if (val >=VIRTIO_FEATURES_BITS )return -EINVAL ;virtio_features_clear_bit (dev->debugfs_filter_features, val);
drivers/virtio/virtio_pci_modern_dev.c +3 -3
@@ -401,7 +401,7 @@ void vp_modern_get_extended_features(struct virtio_pci_modern_device *mdev,int i;virtio_features_zero (features); -for (i =0 ; i <VIRTIO_FEATURES_WORDS ; i++) { +for (i =0 ; i <VIRTIO_FEATURES_BITS /32 ; i++) {u64 cur;vp_iowrite32 (i, &cfg->device_feature_select);
@@ -427,7 +427,7 @@ vp_modern_get_driver_extended_features(struct virtio_pci_modern_device *mdev,int i;virtio_features_zero (features); -for (i =0 ; i <VIRTIO_FEATURES_WORDS ; i++) { +for (i =0 ; i <VIRTIO_FEATURES_BITS /32 ; i++) {u64 cur;vp_iowrite32 (i, &cfg->guest_feature_select);
@@ -448,7 +448,7 @@ void vp_modern_set_extended_features(struct virtio_pci_modern_device *mdev,struct virtio_pci_common_cfg __iomem *cfg = mdev->common;int i; -for (i =0 ; i <VIRTIO_FEATURES_WORDS ; i++) { +for (i =0 ; i <VIRTIO_FEATURES_BITS /32 ; i++) {u32 cur = features[i >>1 ] >> (32 * (i &1 ));vp_iowrite32 (i, &cfg->guest_feature_select);
include/linux/virtio.h +1 -1
@@ -166,7 +166,7 @@ struct virtio_device {void *priv;#ifdef CONFIG_VIRTIO_DEBUG struct dentry *debugfs_dir; -u64 debugfs_filter_features[VIRTIO_FEATURES_DWORDS ]; +u64 debugfs_filter_features[VIRTIO_FEATURES_U64S ];#endif };
include/linux/virtio_config.h +1 -1
@@ -80,7 +80,7 @@ struct virtqueue_info {* Returns the first 64 feature bits. * @get_extended_features: * vdev: the virtio_device -* Returns the first VIRTIO_FEATURES_MAX feature bits (all we currently +* Returns the first VIRTIO_FEATURES_BITS feature bits (all we currently * need). * @finalize_features: confirm what device features we'll be using. * vdev: the virtio_device
include/linux/virtio_features.h +15 -14
@@ -4,15 +4,16 @@#include <linux/bits.h> -#define VIRTIO_FEATURES_DWORDS 2 -#define VIRTIO_FEATURES_MAX (VIRTIO_FEATURES_DWORDS * 64) -#define VIRTIO_FEATURES_WORDS (VIRTIO_FEATURES_DWORDS * 2) +#define VIRTIO_FEATURES_U64S 2 +#define VIRTIO_FEATURES_BITS (VIRTIO_FEATURES_U64S * 64) +#define VIRTIO_BIT (b) BIT_ULL((b) & 0x3f) -#define VIRTIO_DWORD (b) ((b) >> 6) +#define VIRTIO_U64 (b) ((b) >> 6) +#define VIRTIO_DECLARE_FEATURES (name) \ union { \ u64 name; \ - u64 name##_array[VIRTIO_FEATURES_DWORDS];\ + u64 name##_array[VIRTIO_FEATURES_U64S];\ }static inline bool virtio_features_chk_bit (unsigned int bit)
@@ -22,9 +23,9 @@ static inline bool virtio_features_chk_bit(unsigned int bit)* Don't care returning the correct value: the build * will fail before any bad features access */ -BUILD_BUG_ON (bit >=VIRTIO_FEATURES_MAX ); +BUILD_BUG_ON (bit >=VIRTIO_FEATURES_BITS ); }else { -if (WARN_ON_ONCE (bit >=VIRTIO_FEATURES_MAX )) +if (WARN_ON_ONCE (bit >=VIRTIO_FEATURES_BITS ))return false; }return true;
@@ -34,26 +35,26 @@ static inline bool virtio_features_test_bit(const u64 *features, unsigned int bit) {return virtio_features_chk_bit (bit) && - !!(features[VIRTIO_DWORD (bit)] &VIRTIO_BIT (bit)); + !!(features[VIRTIO_U64 (bit)] &VIRTIO_BIT (bit)); }static inline void virtio_features_set_bit (u64 *features,unsigned int bit) {if (virtio_features_chk_bit (bit)) - features[VIRTIO_DWORD (bit)] |=VIRTIO_BIT (bit); + features[VIRTIO_U64 (bit)] |=VIRTIO_BIT (bit); }static inline void virtio_features_clear_bit (u64 *features,unsigned int bit) {if (virtio_features_chk_bit (bit)) - features[VIRTIO_DWORD (bit)] &= ~VIRTIO_BIT (bit); + features[VIRTIO_U64 (bit)] &= ~VIRTIO_BIT (bit); }static inline void virtio_features_zero (u64 *features) { -memset (features,0 ,sizeof (features[0 ]) *VIRTIO_FEATURES_DWORDS ); +memset (features,0 ,sizeof (features[0 ]) *VIRTIO_FEATURES_U64S ); }static inline void virtio_features_from_u64 (u64 *features,u64 from)
@@ -66,7 +67,7 @@ static inline bool virtio_features_equal(const u64 *f1, const u64 *f2) {int i; -for (i =0 ; i <VIRTIO_FEATURES_DWORDS ; ++i) +for (i =0 ; i <VIRTIO_FEATURES_U64S ; ++i)if (f1[i] != f2[i])return false;return true;
@@ -74,14 +75,14 @@ static inline bool virtio_features_equal(const u64 *f1, const u64 *f2)static inline void virtio_features_copy (u64 *to,const u64 *from) { -memcpy (to, from,sizeof (to[0 ]) *VIRTIO_FEATURES_DWORDS ); +memcpy (to, from,sizeof (to[0 ]) *VIRTIO_FEATURES_U64S ); }static inline void virtio_features_andnot (u64 *to,const u64 *f1,const u64 *f2) {int i; -for (i =0 ; i <VIRTIO_FEATURES_DWORDS ; i++) +for (i =0 ; i <VIRTIO_FEATURES_U64S ; i++) to[i] = f1[i] & ~f2[i]; }
include/linux/virtio_pci_modern.h +4 -4
@@ -107,7 +107,7 @@ void vp_modern_set_extended_features(struct virtio_pci_modern_device *mdev,static inline u64 vp_modern_get_features (struct virtio_pci_modern_device *mdev) { -u64 features_array[VIRTIO_FEATURES_DWORDS ]; +u64 features_array[VIRTIO_FEATURES_U64S ];vp_modern_get_extended_features (mdev, features_array);return features_array[0 ];
@@ -116,11 +116,11 @@ vp_modern_get_features(struct virtio_pci_modern_device *mdev)static inline u64 vp_modern_get_driver_features (struct virtio_pci_modern_device *mdev) { -u64 features_array[VIRTIO_FEATURES_DWORDS ]; +u64 features_array[VIRTIO_FEATURES_U64S ];int i;vp_modern_get_driver_extended_features (mdev, features_array); -for (i =1 ; i <VIRTIO_FEATURES_DWORDS ; ++i) +for (i =1 ; i <VIRTIO_FEATURES_U64S ; ++i)WARN_ON_ONCE (features_array[i]);return features_array[0 ]; }
@@ -128,7 +128,7 @@ vp_modern_get_driver_features(struct virtio_pci_modern_device *mdev)static inline void vp_modern_set_features (struct virtio_pci_modern_device *mdev,u64 features) { -u64 features_array[VIRTIO_FEATURES_DWORDS ]; +u64 features_array[VIRTIO_FEATURES_U64S ];virtio_features_from_u64 (features_array, features);vp_modern_set_extended_features (mdev, features_array);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 384/507 ASoC: Intel: catpt: Fix error path in hw_params()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cezary Rojewski <[email protected]>
[ Upstream commit 86a5b621be658fc8fe594ca6db317d64de30cce1 ]
Do not leave any resources hanging on the DSP side if applying user settings fails.
--- sound/soc/intel/catpt/pcm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
sound/soc/intel/catpt/pcm.c +3 -1
@@ -417,8 +417,10 @@ static int catpt_dai_hw_params(struct snd_pcm_substream *substream,return CATPT_IPC_ERROR (ret); ret =catpt_dai_apply_usettings (dai, stream); -if (ret) +if (ret) { +catpt_ipc_free_stream (cdev, stream->info.stream_hw_id);return ret; + } stream->allocated = true;return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 385/507 spi: airoha-snfi: en7523: workaround flash damaging if UART_TXD was short to GND
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Kshevetskiy <[email protected]>
[ Upstream commit 061795b345aff371df8f71d54ae7c7dc8ae630d0 ]
Airoha EN7523 specific bug
--------------------------
We found that some serial console may pull TX line to GROUND during board boot time. Airoha uses TX line as one of its bootstrap pins. On the EN7523 SoC this may lead to booting in RESERVED boot mode.
It was found that some flashes operates incorrectly in RESERVED mode. Micron and Skyhigh flashes are definitely affected by the issue, Winbond flashes are not affected.
Details:
--------
DMA reading of odd pages on affected flashes operates incorrectly. Page reading offset (start of the page) on hardware level is replaced by 0x10. Thus results in incorrect data reading. As result OS loading becomes impossible.
Usage of UBI make things even worse. On attaching, UBI will detects corruptions (because of wrong reading of odd pages) and will try to recover. For recovering UBI will erase and write 'damaged' blocks with a valid information. This will destroy all UBI data.
Non-DMA reading is OK.
This patch detects booting in reserved mode, turn off DMA and print big fat warning.
It's worth noting that the boot configuration is preserved across reboots. Therefore, to boot normally, you should do the following:
- disconnect the serial console from the board,
- power cycle the board.
--- drivers/spi/spi-airoha-snfi.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
drivers/spi/spi-airoha-snfi.c +24 -1
@@ -1030,6 +1030,11 @@ static const struct spi_controller_mem_ops airoha_snand_mem_ops = { .dirmap_write = airoha_snand_dirmap_write, }; +static const struct spi_controller_mem_ops airoha_snand_nodma_mem_ops = { + .supports_op = airoha_snand_supports_op, + .exec_op = airoha_snand_exec_op, +}; +static int airoha_snand_setup (struct spi_device *spi) {struct airoha_snand_ctrl *as_ctrl;
@@ -1104,7 +1109,9 @@ static int airoha_snand_probe(struct platform_device *pdev)struct airoha_snand_ctrl *as_ctrl;struct device *dev = &pdev->dev;struct spi_controller *ctrl; +bool dma_enable = true;void __iomem *base; +u32 sfc_strap;int err; ctrl =devm_spi_alloc_host (dev,sizeof (*as_ctrl));
@@ -1139,12 +1146,28 @@ static int airoha_snand_probe(struct platform_device *pdev)return dev_err_probe (dev,PTR_ERR (as_ctrl->spi_clk),"unable to get spi clk\n" ); +if (device_is_compatible (dev,"airoha,en7523-snand" )) { + err =regmap_read (as_ctrl->regmap_ctrl, +REG_SPI_CTRL_SFC_STRAP , &sfc_strap); +if (err) +return err; + +if (!(sfc_strap &0x04 )) { + dma_enable = false; +dev_warn (dev,"Detected booting in RESERVED mode (UART_TXD was short to GND).\n" ); +dev_warn (dev,"This mode is known for incorrect DMA reading of some flashes.\n" ); +dev_warn (dev,"Much slower PIO mode will be used to prevent flash data damage.\n" ); +dev_warn (dev,"Unplug UART cable and power cycle board to get full performance.\n" ); + } + } + err =dma_set_mask (as_ctrl->dev,DMA_BIT_MASK (32 ));if (err)return err; ctrl->num_chipselect =2 ; - ctrl->mem_ops = &airoha_snand_mem_ops; + ctrl->mem_ops = dma_enable ? &airoha_snand_mem_ops + : &airoha_snand_nodma_mem_ops; ctrl->bits_per_word_mask =SPI_BPW_MASK (8 ); ctrl->mode_bits =SPI_RX_DUAL ; ctrl->setup = airoha_snand_setup;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 386/507 ARM: dts: samsung: universal_c210: turn off SDIO WLAN chip during system suspend
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Szyprowski <[email protected]>
[ Upstream commit 97aee67e2406ea381408915e606c5f86448f3949 ]
Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board requires it") changed default behavior of the BRCMFMAC driver, which now keeps SDIO card powered during system suspend to enable optional support for WOWL. This feature is not supported by the legacy Exynos4 based boards and leads to WLAN disfunction after system suspend/resume cycle. Fix this by annotating SDIO host used by WLAN chip with 'cap-power-off-card' property, which should have been there from the beginning.
--- arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts | 1 + 1 file changed, 1 insertion(+)
arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts +1 -0
@@ -610,6 +610,7 @@ &sdhci_3 { #size-cells = <0>; non-removable; + cap-power-off-card; bus-width = <4>; mmc-pwrseq = <&wlan_pwrseq>; vmmc-supply = <&ldo5_reg>;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 387/507 ARM: dts: samsung: exynos4210-i9100: turn off SDIO WLAN chip during system suspend
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Szyprowski <[email protected]>
[ Upstream commit 863d69923bdb6f414d0a3f504f1dfaeacbc00b09 ]
Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board requires it") changed default behavior of the BRCMFMAC driver, which now keeps SDIO card powered during system suspend to enable optional support for WOWL. This feature is not supported by the legacy Exynos4 based boards and leads to WLAN disfunction after system suspend/resume cycle. Fix this by annotating SDIO host used by WLAN chip with 'cap-power-off-card' property, which should have been there from the beginning.
--- arch/arm/boot/dts/samsung/exynos4210-i9100.dts | 1 + 1 file changed, 1 insertion(+)
arch/arm/boot/dts/samsung/exynos4210-i9100.dts +1 -0
@@ -853,6 +853,7 @@ &sdhci_3 { #size-cells = <0>; non-removable; + cap-power-off-card; bus-width = <4>; mmc-pwrseq = <&wlan_pwrseq>; vmmc-supply = <&vtf_reg>;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 388/507 ARM: dts: samsung: exynos4210-trats: turn off SDIO WLAN chip during system suspend
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Szyprowski <[email protected]>
[ Upstream commit 97cc9c346b2c9cde075b9420fc172137d2427711 ]
Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board requires it") changed default behavior of the BRCMFMAC driver, which now keeps SDIO card powered during system suspend to enable optional support for WOWL. This feature is not supported by the legacy Exynos4 based boards and leads to WLAN disfunction after system suspend/resume cycle. Fix this by annotating SDIO host used by WLAN chip with 'cap-power-off-card' property, which should have been there from the beginning.
--- arch/arm/boot/dts/samsung/exynos4210-trats.dts | 1 + 1 file changed, 1 insertion(+)
arch/arm/boot/dts/samsung/exynos4210-trats.dts +1 -0
@@ -518,6 +518,7 @@ &sdhci_3 { #size-cells = <0>; non-removable; + cap-power-off-card; bus-width = <4>; mmc-pwrseq = <&wlan_pwrseq>; vmmc-supply = <&tflash_reg>;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 389/507 ARM: dts: samsung: exynos4412-midas: turn off SDIO WLAN chip during system suspend
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Szyprowski <[email protected]>
[ Upstream commit 2ff147fdfa99b8cbb8c2833e685fde7c42580ae6 ]
Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board requires it") changed default behavior of the BRCMFMAC driver, which now keeps SDIO card powered during system suspend to enable optional support for WOWL. This feature is not supported by the legacy Exynos4 based boards and leads to WLAN disfunction after system suspend/resume cycle. Fix this by annotating SDIO host used by WLAN chip with 'cap-power-off-card' property, which should have been there from the beginning.
--- arch/arm/boot/dts/samsung/exynos4412-midas.dtsi | 1 + 1 file changed, 1 insertion(+)
arch/arm/boot/dts/samsung/exynos4412-midas.dtsi +1 -0
@@ -1440,6 +1440,7 @@ &sdhci_3 { #address-cells = <1>; #size-cells = <0>; non-removable; + cap-power-off-card; bus-width = <4>; mmc-pwrseq = <&wlan_pwrseq>;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 390/507 regulator: core: Protect regulator_supply_alias_list with regulator_list_mutex
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: sparkhuang <[email protected]>
[ Upstream commit 0cc15a10c3b4ab14cd71b779fd5c9ca0cb2bc30d ]
regulator_supply_alias_list was accessed without any locking in regulator_supply_alias(), regulator_register_supply_alias(), and regulator_unregister_supply_alias(). Concurrent registration, unregistration and lookups can race, leading to:
1 use-after-free if an alias entry is removed while being read, 2 duplicate entries when two threads register the same alias, 3 inconsistent alias mappings observed by consumers.
Protect all traversals, insertions and deletions on regulator_supply_alias_list with the existing regulator_list_mutex.
--- drivers/regulator/core.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-)
drivers/regulator/core.c +20 -12
@@ -1947,6 +1947,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) {struct regulator_supply_alias *map; +mutex_lock (®ulator_list_mutex); map =regulator_find_supply_alias (*dev, *supply);if (map) { dev_dbg(*dev, "Mapping supply %s to %s,%s\n",
@@ -1955,6 +1956,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) *dev = map->alias_dev; *supply = map->alias_supply; } +mutex_unlock (®ulator_list_mutex); }static int regulator_match (struct device *dev,const void *data)
@@ -2497,22 +2499,26 @@ int regulator_register_supply_alias(struct device *dev, const char *id, const char *alias_id) {struct regulator_supply_alias *map; +struct regulator_supply_alias *new_map; - map =regulator_find_supply_alias (dev, id); -if (map) -return -EEXIST ; - - map =kzalloc (sizeof (struct regulator_supply_alias ),GFP_KERNEL ); -if (!map) + new_map =kzalloc (sizeof (struct regulator_supply_alias ),GFP_KERNEL ); +if (!new_map)return -ENOMEM ; - map->src_dev = dev; - map->src_supply = id; - map->alias_dev = alias_dev; - map->alias_supply = alias_id; - -list_add (&map->list, ®ulator_supply_alias_list); +mutex_lock (®ulator_list_mutex); + map =regulator_find_supply_alias (dev, id); +if (map) { +mutex_unlock (®ulator_list_mutex); +kfree (new_map); +return -EEXIST ; + } + new_map->src_dev = dev; + new_map->src_supply = id; + new_map->alias_dev = alias_dev; + new_map->alias_supply = alias_id; +list_add (&new_map->list, ®ulator_supply_alias_list); +mutex_unlock (®ulator_list_mutex);pr_info ("Adding alias for supply %s,%s -> %s,%s\n" , id,dev_name (dev), alias_id,dev_name (alias_dev));
@@ -2532,11 +2538,13 @@ void regulator_unregister_supply_alias(struct device *dev, const char *id) {struct regulator_supply_alias *map; +mutex_lock (®ulator_list_mutex); map =regulator_find_supply_alias (dev, id);if (map) {list_del (&map->list);kfree (map); } +mutex_unlock (®ulator_list_mutex); }EXPORT_SYMBOL_GPL (regulator_unregister_supply_alias);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 391/507 Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilias Stamatis <[email protected]>
[ Upstream commit 6fb3acdebf65a72df0a95f9fd2c901ff2bc9a3a2 ]
Commit 97523a4edb7b ("kernel/resource: remove first_lvl / siblings_only logic") removed an optimization introduced by commit 756398750e11 ("resource: avoid unnecessary lookups in find_next_iomem_res()"). That was not called out in the message of the first commit explicitly so it's not entirely clear whether removing the optimization happened inadvertently or not.
As the original commit message of the optimization explains there is no point considering the children of a subtree in find_next_iomem_res() if the top level range does not match.
Reinstating the optimization results in performance improvements in systems where /proc/iomem is ~5k lines long. Calling mmap() on /dev/mem in such platforms takes 700-1500μs without the optimisation and 10-50μs with the optimisation.
Note that even though commit 97523a4edb7b removed the 'sibling_only' parameter from next_resource(), newer kernels have basically reinstated it under the name 'skip_children'.
--- kernel/resource.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
kernel/resource.c +9 -1
@@ -341,6 +341,8 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, unsigned long flags, unsigned long desc, struct resource *res) { + /* Skip children until we find a top level range that matches */ + bool skip_children = true;struct resource *p;if (!res)
@@ -351,7 +353,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end,read_lock (&resource_lock); -for_each_resource (&iomem_resource, p, false) { +for_each_resource (&iomem_resource, p, skip_children) {/* If we passed the resource we are looking for, stop */ if (p->start > end) { p =NULL ;
@@ -362,6 +364,12 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end,if (p->end < start)continue ; +/* +* We found a top level range that matches what we are looking +* for. Time to start checking children too. +*/ + skip_children = false; +/* Found a match, break */ if (is_type_match (p, flags, desc))break ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 392/507 netfilter: flowtable: check for maximum number of encapsulations in bridge vlan
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
[ Upstream commit 634f3853cc98d73bdec8918010ee29b06981583e ]
Add a sanity check to skip path discovery if the maximum number of encapsulation is reached. While at it, check for underflow too.
--- net/netfilter/nft_flow_offload.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
net/netfilter/nft_flow_offload.c +8 -1
@@ -141,12 +141,19 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack, info->ingress_vlans |=BIT (info->num_encaps -1 );break ;case DEV_PATH_BR_VLAN_TAG : +if (info->num_encaps >=NF_FLOW_TABLE_ENCAP_MAX ) { + info->indev =NULL ; +break ; + } info->encap[info->num_encaps].id = path->bridge.vlan_id; info->encap[info->num_encaps].proto = path->bridge.vlan_proto; info->num_encaps++;break ;case DEV_PATH_BR_VLAN_UNTAG : - info->num_encaps--; +if (WARN_ON_ONCE (info->num_encaps-- ==0 )) { + info->indev =NULL ; +break ; + }break ;case DEV_PATH_BR_VLAN_KEEP :break ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 393/507 netfilter: nf_conncount: rework API to use sk_buff directly
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fernando Fernandez Mancera <[email protected]>
[ Upstream commit be102eb6a0e7c03db00e50540622f4e43b2d2844 ]
When using nf_conncount infrastructure for non-confirmed connections a duplicated track is possible due to an optimization introduced since commit d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC").
In order to fix this introduce a new conncount API that receives directly an sk_buff struct. It fetches the tuple and zone and the corresponding ct from it. It comes with both existing conncount variants nf_conncount_count_skb() and nf_conncount_add_skb(). In addition remove the old API and adjust all the users to use the new one.
This way, for each sk_buff struct it is possible to check if there is a ct present and already confirmed. If so, skip the add operation.
--- include/net/netfilter/nf_conntrack_count.h | 17 +- net/netfilter/nf_conncount.c | 177 ++++++++++++++------- net/netfilter/nft_connlimit.c | 21 +-- net/netfilter/xt_connlimit.c | 14 +- net/openvswitch/conntrack.c | 16 +- 5 files changed, 142 insertions(+), 103 deletions(-)
include/net/netfilter/nf_conntrack_count.h +8 -9
@@ -18,15 +18,14 @@ struct nf_conncount_list {struct nf_conncount_data *nf_conncount_init (struct net *net,unsigned int keylen);void nf_conncount_destroy (struct net *net,struct nf_conncount_data *data); -unsigned int nf_conncount_count (struct net *net, -struct nf_conncount_data *data, -const u32 *key, -const struct nf_conntrack_tuple *tuple, -const struct nf_conntrack_zone *zone); - -int nf_conncount_add (struct net *net,struct nf_conncount_list *list, -const struct nf_conntrack_tuple *tuple, -const struct nf_conntrack_zone *zone); +unsigned int nf_conncount_count_skb (struct net *net, +const struct sk_buff *skb, +u16 l3num, +struct nf_conncount_data *data, +const u32 *key); + +int nf_conncount_add_skb (struct net *net,const struct sk_buff *skb, +u16 l3num,struct nf_conncount_list *list);void nf_conncount_list_init (struct nf_conncount_list *list);
net/netfilter/nf_conncount.c +120 -57
298 lines not on this page · raw message
net/netfilter/nft_connlimit.c +3 -18
@@ -24,26 +24,11 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv,const struct nft_pktinfo *pkt, const struct nft_set_ext *ext) { - const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; -const struct nf_conntrack_tuple *tuple_ptr; -struct nf_conntrack_tuple tuple; -enum ip_conntrack_info ctinfo; -const struct nf_conn *ct; unsigned int count; +int err; - tuple_ptr = &tuple; - - ct =nf_ct_get (pkt->skb, &ctinfo); -if (ct !=NULL ) { - tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL ].tuple; - zone =nf_ct_zone (ct); - }else if (!nf_ct_get_tuplepr (pkt->skb,skb_network_offset (pkt->skb), -nft_pf (pkt),nft_net (pkt), &tuple)) { - regs->verdict.code =NF_DROP ; -return ; - } - -if (nf_conncount_add (nft_net (pkt), priv->list, tuple_ptr, zone)) { + err =nf_conncount_add_skb (nft_net (pkt), pkt->skb,nft_pf (pkt), priv->list); +if (err) { regs->verdict.code =NF_DROP ;return ; }
net/netfilter/xt_connlimit.c +3 -11
@@ -31,8 +31,6 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) {struct net *net =xt_net (par);const struct xt_connlimit_info *info = par->matchinfo; -struct nf_conntrack_tuple tuple; -const struct nf_conntrack_tuple *tuple_ptr = &tuple;const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt;enum ip_conntrack_info ctinfo;const struct nf_conn *ct;
@@ -40,13 +38,8 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)u32 key[5 ]; ct =nf_ct_get (skb, &ctinfo); -if (ct !=NULL ) { - tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL ].tuple; +if (ct) zone =nf_ct_zone (ct); - }else if (!nf_ct_get_tuplepr (skb,skb_network_offset (skb), -xt_family (par), net, &tuple)) { - goto hotdrop; - }if (xt_family (par) ==NFPROTO_IPV6 ) {const struct ipv6hdr *iph =ipv6_hdr (skb);
@@ -69,10 +62,9 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) key[1 ] = zone->id; } - connections =nf_conncount_count (net, info->data, key, tuple_ptr, - zone); + connections =nf_conncount_count_skb (net, skb,xt_family (par), info->data, key);if (connections ==0 ) -/* kmalloc failed, drop it entirely */ +/* kmalloc failed or tuple couldn't be found, drop it entirely */ goto hotdrop;return (connections > info->limit) ^ !!(info->flags &XT_CONNLIMIT_INVERT );
net/openvswitch/conntrack.c +8 -8
@@ -928,8 +928,8 @@ static u32 ct_limit_get(const struct ovs_ct_limit_info *info, u16 zone) }static int ovs_ct_check_limit (struct net *net, -const struct ovs_conntrack_info *info, -const struct nf_conntrack_tuple *tuple) +const struct sk_buff *skb, +const struct ovs_conntrack_info *info) {struct ovs_net *ovs_net =net_generic (net, ovs_net_id);const struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info;
@@ -942,8 +942,9 @@ static int ovs_ct_check_limit(struct net *net,if (per_zone_limit ==OVS_CT_LIMIT_UNLIMITED )return 0 ; - connections =nf_conncount_count (net, ct_limit_info->data, - &conncount_key, tuple, &info->zone); + connections =nf_conncount_count_skb (net, skb, info->family, + ct_limit_info->data, + &conncount_key);if (connections > per_zone_limit)return -ENOMEM ;
@@ -972,8 +973,7 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,#if IS_ENABLED (CONFIG_NETFILTER_CONNCOUNT )if (static_branch_unlikely (&ovs_ct_limit_enabled)) {if (!nf_ct_is_confirmed (ct)) { - err =ovs_ct_check_limit (net, info, - &ct->tuplehash[IP_CT_DIR_ORIGINAL ].tuple); + err =ovs_ct_check_limit (net, skb, info);if (err) { net_warn_ratelimited("openvswitch: zone: %u " "exceeds conntrack limit\n",
@@ -1770,8 +1770,8 @@ static int __ovs_ct_limit_get_zone_limit(struct net *net, zone_limit.limit = limit;nf_ct_zone_init (&ct_zone, zone_id,NF_CT_DEFAULT_ZONE_DIR ,0 ); - zone_limit.count =nf_conncount_count (net, data, &conncount_key,NULL , - &ct_zone); + zone_limit.count =nf_conncount_count_skb (net,NULL ,0 , data, + &conncount_key);return nla_put_nohdr (reply,sizeof (zone_limit), &zone_limit); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 394/507 netfilter: nft_connlimit: update the count if add was skipped
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fernando Fernandez Mancera <[email protected]>
[ Upstream commit 69894e5b4c5e28cda5f32af33d4a92b7a4b93b0e ]
Connlimit expression can be used for all kind of packets and not only for packets with connection state new. See this ruleset as example:
table ip filter {
chain input {
type filter hook input priority filter; policy accept;
tcp dport 22 ct count over 4 counter
}
}Currently, if the connection count goes over the limit the counter will count the packets. When a connection is closed, the connection count won't decrement as it should because it is only updated for new connections due to an optimization on __nf_conncount_add() that prevents updating the list if the connection is duplicated.
To solve this problem, check whether the connection was skipped and if so, update the list. Adjust count_tree() too so the same fix is applied for xt_connlimit.
--- net/netfilter/nf_conncount.c | 12 ++++++++---- net/netfilter/nft_connlimit.c | 13 +++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-)
net/netfilter/nf_conncount.c +8 -4
@@ -179,7 +179,7 @@ static int __nf_conncount_add(struct net *net,if (ct &&nf_ct_is_confirmed (ct)) {if (refcounted)nf_ct_put (ct); -return 0 ; +return -EEXIST ; }if ((u32 )jiffies == list->last_gc)
@@ -398,7 +398,7 @@ insert_tree(struct net *net,int ret; ret =nf_conncount_add_skb (net, skb, l3num, &rbconn->list); -if (ret) +if (ret && ret != -EEXIST ) count =0 ;/* hotdrop */ else count = rbconn->list.count;
@@ -501,10 +501,14 @@ count_tree(struct net *net,/* same source network -> be counted! */ ret =__nf_conncount_add (net, skb, l3num, &rbconn->list);spin_unlock_bh (&rbconn->list.list_lock); -if (ret) +if (ret && ret != -EEXIST ) {return 0 ;/* hotdrop */ -else + }else { +/* -EEXIST means add was skipped, update the list */ +if (ret == -EEXIST ) +nf_conncount_gc_list (net, &rbconn->list);return rbconn->list.count; + } } }
net/netfilter/nft_connlimit.c +11 -2
@@ -29,8 +29,17 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, err =nf_conncount_add_skb (nft_net (pkt), pkt->skb,nft_pf (pkt), priv->list);if (err) { - regs->verdict.code =NF_DROP ; -return ; +if (err == -EEXIST ) { +/* Call gc to update the list count if any connection has +* been closed already. This is useful for softlimit +* connections like limiting bandwidth based on a number +* of open connections. +*/ +nf_conncount_gc_list (nft_net (pkt), priv->list); + }else { + regs->verdict.code =NF_DROP ; +return ; + } } count = priv->list->count;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 395/507 iavf: Implement settime64 with -EOPNOTSUPP
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Schmidt <[email protected]>
[ Upstream commit 1e43ebcd5152b3e681a334cc6542fb21770c3a2e ]
ptp_clock_settime() assumes every ptp_clock has implemented settime64(). Stub it with -EOPNOTSUPP to prevent a NULL dereference.
The fix is similar to commit 329d050bbe63 ("gve: Implement settime64 with -EOPNOTSUPP").
--- drivers/net/ethernet/intel/iavf/iavf_ptp.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/ethernet/intel/iavf/iavf_ptp.c +7 -0
@@ -252,6 +252,12 @@ static int iavf_ptp_gettimex64(struct ptp_clock_info *info,return iavf_read_phc_indirect (adapter, ts, sts); } +static int iavf_ptp_settime64 (struct ptp_clock_info *info, +const struct timespec64 *ts) +{ +return -EOPNOTSUPP ; +} +/** * iavf_ptp_cache_phc_time - Cache PHC time for performing timestamp extension * @adapter: private adapter structure
@@ -320,6 +326,7 @@ static int iavf_ptp_register_clock(struct iavf_adapter *adapter) KBUILD_MODNAME, dev_name(dev)); ptp_info->owner =THIS_MODULE ; ptp_info->gettimex64 = iavf_ptp_gettimex64; + ptp_info->settime64 = iavf_ptp_settime64; ptp_info->do_aux_work = iavf_ptp_do_aux_work; clock =ptp_clock_register (ptp_info, dev);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 396/507 net: stmmac: fix rx limit check in stmmac_rx_zc()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Kodanev <[email protected]>
[ Upstream commit 8048168df56e225c94e50b04cb7b0514135d7a1c ]
The extra "count >= limit" check in stmmac_rx_zc() is redundant and has no effect because the value of "count" doesn't change after the while condition at this point.
However, it can change after "read_again:" label:
while (count < limit) {
...
if (count >= limit)
break;
read_again:
...
/* XSK pool expects RX frame 1:1 mapped to XSK buffer */
if (likely(status & rx_not_ls)) {
xsk_buff_free(buf->xdp);
buf->xdp = NULL;
dirty++;
count++;
goto read_again;
}
...This patch addresses the same issue previously resolved in stmmac_rx() by commit fa02de9e7588 ("net: stmmac: fix rx budget limit check"). The fix is the same: move the check after the label to ensure that it bounds the goto loop.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +1 -1
@@ -5349,10 +5349,10 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) len =0 ; } +read_again:if (count >= limit)break ; -read_again: buf1_len =0 ; entry = next_entry; buf = &rx_q->buf_pool[entry];
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 397/507 mtd: rawnand: renesas: Handle devm_pm_runtime_enable() errors
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit a3623e1ae1ed6be4d49b2ccb9996a9d2b65c1828 ]
devm_pm_runtime_enable() can fail due to memory allocation failures. The current code ignores its return value and proceeds with pm_runtime_resume_and_get(), which may operate on incorrectly initialized runtime PM state.
Check the return value of devm_pm_runtime_enable() and return the error code if it fails.
--- drivers/mtd/nand/raw/renesas-nand-controller.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/mtd/nand/raw/renesas-nand-controller.c +4 -1
@@ -1336,7 +1336,10 @@ static int rnandc_probe(struct platform_device *pdev)if (IS_ERR (rnandc->regs))return PTR_ERR (rnandc->regs); -devm_pm_runtime_enable (&pdev->dev); + ret =devm_pm_runtime_enable (&pdev->dev); +if (ret) +return ret; + ret =pm_runtime_resume_and_get (&pdev->dev);if (ret <0 )return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 398/507 spi: ch341: fix out-of-bounds memory access in ch341_transfer_one
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianchu Chen <[email protected]>
[ Upstream commit 545d1287e40a55242f6ab68bcc1ba3b74088b1bc ]
Discovered by Atuin - Automated Vulnerability Discovery Engine.
The 'len' variable is calculated as 'min(32, trans->len + 1)', which includes the 1-byte command header.
When copying data from 'trans->tx_buf' to 'ch341->tx_buf + 1', using 'len' as the length is incorrect because:
1. It causes an out-of-bounds read from 'trans->tx_buf' (which has size 'trans->len', i.e., 'len - 1' in this context).
2. It can cause an out-of-bounds write to 'ch341->tx_buf' if 'len' is CH341_PACKET_LENGTH (32). Writing 32 bytes to ch341->tx_buf + 1 overflows the buffer.
Fix this by copying 'len - 1' bytes.
--- drivers/spi/spi-ch341.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/spi-ch341.c +1 -1
@@ -78,7 +78,7 @@ static int ch341_transfer_one(struct spi_controller *host, ch341->tx_buf[0 ] =CH341A_CMD_SPI_STREAM ; -memcpy (ch341->tx_buf +1 , trans->tx_buf, len); +memcpy (ch341->tx_buf +1 , trans->tx_buf, len -1 ); ret =usb_bulk_msg (ch341->udev, ch341->write_pipe, ch341->tx_buf, len,NULL ,CH341_DEFAULT_TIMEOUT );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 399/507 vfio/pci: Use RCU for error/request triggers to avoid circular locking
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Williamson <[email protected]>
[ Upstream commit 98693e0897f754e3f51ce6626ed5f785f625ba2b ]
Thanks to a device generating an ACS violation during bus reset, lockdep reported the following circular locking issue:
CPU0: SET_IRQS (MSI/X): holds igate, acquires memory_lock
CPU1: HOT_RESET: holds memory_lock, acquires pci_bus_sem
CPU2: AER: holds pci_bus_sem, acquires igate
This results in a potential 3-way deadlock.
Remove the pci_bus_sem->igate leg of the triangle by using RCU to peek at the eventfd rather than locking it with igate.
--- drivers/vfio/pci/vfio_pci_core.c | 68 ++++++++++++++++++++++--------- drivers/vfio/pci/vfio_pci_intrs.c | 52 ++++++++++++++--------- drivers/vfio/pci/vfio_pci_priv.h | 4 ++ include/linux/vfio_pci_core.h | 10 ++++- 4 files changed, 93 insertions(+), 41 deletions(-)
drivers/vfio/pci/vfio_pci_core.c +48 -20
@@ -41,6 +41,40 @@ static bool nointxmask;static bool disable_vga;static bool disable_idle_d3; +static void vfio_pci_eventfd_rcu_free (struct rcu_head *rcu) +{ +struct vfio_pci_eventfd *eventfd = + container_of(rcu, struct vfio_pci_eventfd, rcu); + +eventfd_ctx_put (eventfd->ctx); +kfree (eventfd); +} + +int vfio_pci_eventfd_replace_locked (struct vfio_pci_core_device *vdev, +struct vfio_pci_eventfd __rcu **peventfd, +struct eventfd_ctx *ctx) +{ +struct vfio_pci_eventfd *new =NULL ; +struct vfio_pci_eventfd *old; + +lockdep_assert_held (&vdev->igate); + +if (ctx) { + new =kzalloc (sizeof (*new),GFP_KERNEL_ACCOUNT ); +if (!new) +return -ENOMEM ; + + new->ctx = ctx; + } + + old =rcu_replace_pointer (*peventfd, new, +lockdep_is_held (&vdev->igate)); +if (old) +call_rcu (&old->rcu, vfio_pci_eventfd_rcu_free); + +return 0 ; +} +/* List of PF's that vfio_pci_core_sriov_configure() has been called on */ static DEFINE_MUTEX (vfio_pci_sriov_pfs_mutex);static LIST_HEAD (vfio_pci_sriov_pfs);
@@ -696,14 +730,8 @@ void vfio_pci_core_close_device(struct vfio_device *core_vdev)vfio_pci_core_disable (vdev);mutex_lock (&vdev->igate); -if (vdev->err_trigger) { -eventfd_ctx_put (vdev->err_trigger); - vdev->err_trigger =NULL ; - } -if (vdev->req_trigger) { -eventfd_ctx_put (vdev->req_trigger); - vdev->req_trigger =NULL ; - } +vfio_pci_eventfd_replace_locked (vdev, &vdev->err_trigger,NULL ); +vfio_pci_eventfd_replace_locked (vdev, &vdev->req_trigger,NULL );mutex_unlock (&vdev->igate); }EXPORT_SYMBOL_GPL (vfio_pci_core_close_device);
@@ -1800,21 +1828,21 @@ void vfio_pci_core_request(struct vfio_device *core_vdev, unsigned int count)struct vfio_pci_core_device *vdev = container_of(core_vdev, struct vfio_pci_core_device, vdev);struct pci_dev *pdev = vdev->pdev; +struct vfio_pci_eventfd *eventfd; -mutex_lock (&vdev->igate); - -if (vdev->req_trigger) { +rcu_read_lock (); + eventfd =rcu_dereference (vdev->req_trigger); +if (eventfd) {if (!(count %10 ))pci_notice_ratelimited (pdev,"Relaying device request to user (#%u)\n" , count); -eventfd_signal (vdev->req_trigger); +eventfd_signal (eventfd->ctx); }else if (count ==0 ) {pci_warn (pdev,"No device request channel registered, blocked until released by user\n" ); } - -mutex_unlock (&vdev->igate); +rcu_read_unlock (); }EXPORT_SYMBOL_GPL (vfio_pci_core_request);
@@ -2227,13 +2255,13 @@ pci_ers_result_t vfio_pci_core_aer_err_detected(struct pci_dev *pdev, pci_channel_state_t state) {struct vfio_pci_core_device *vdev =dev_get_drvdata (&pdev->dev); +struct vfio_pci_eventfd *eventfd; -mutex_lock (&vdev->igate); - -if (vdev->err_trigger) -eventfd_signal (vdev->err_trigger); - -mutex_unlock (&vdev->igate); +rcu_read_lock (); + eventfd =rcu_dereference (vdev->err_trigger); +if (eventfd) +eventfd_signal (eventfd->ctx); +rcu_read_unlock ();return PCI_ERS_RESULT_CAN_RECOVER ; }
drivers/vfio/pci/vfio_pci_intrs.c +33 -19
98 lines not on this page · raw message
drivers/vfio/pci/vfio_pci_priv.h +4 -0
@@ -26,6 +26,10 @@ struct vfio_pci_ioeventfd {bool vfio_pci_intx_mask (struct vfio_pci_core_device *vdev);void vfio_pci_intx_unmask (struct vfio_pci_core_device *vdev); +int vfio_pci_eventfd_replace_locked (struct vfio_pci_core_device *vdev, +struct vfio_pci_eventfd __rcu **peventfd, +struct eventfd_ctx *ctx); +int vfio_pci_set_irqs_ioctl (struct vfio_pci_core_device *vdev,uint32_t flags,unsigned index,unsigned start,unsigned count,void *data);
include/linux/vfio_pci_core.h +8 -2
@@ -12,6 +12,7 @@#include <linux/pci.h> #include <linux/vfio.h> #include <linux/irqbypass.h> +#include <linux/rcupdate.h> #include <linux/types.h> #include <linux/uuid.h> #include <linux/notifier.h>
@@ -27,6 +28,11 @@struct vfio_pci_core_device ;struct vfio_pci_region ; +struct vfio_pci_eventfd { +struct eventfd_ctx *ctx; +struct rcu_head rcu; +}; +struct vfio_pci_regops {ssize_t (*rw)(struct vfio_pci_core_device *vdev,char __user *buf,size_t count,loff_t *ppos,bool iswrite);
@@ -83,8 +89,8 @@ struct vfio_pci_core_device {struct pci_saved_state *pci_saved_state;struct pci_saved_state *pm_save;int ioeventfds_nr; -struct eventfd_ctx *err_trigger; -struct eventfd_ctx *req_trigger; +struct vfio_pci_eventfd __rcu *err_trigger; +struct vfio_pci_eventfd __rcu *req_trigger;struct eventfd_ctx *pm_wake_eventfd_ctx;struct list_head dummy_resources_list;struct mutex ioeventfds_lock;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 400/507 net: phy: aquantia: check for NVMEM deferral
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Marko <[email protected]>
[ Upstream commit a6c121a2432eee2c4ebceb1483ccd4a50a52983d ]
Currently, if NVMEM provider is probed later than Aquantia, loading the firmware will fail with -EINVAL.
To fix this, simply check for -EPROBE_DEFER when NVMEM is attempted and return it.
--- drivers/net/phy/aquantia/aquantia_firmware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/phy/aquantia/aquantia_firmware.c +1 -1
@@ -369,7 +369,7 @@ int aqr_firmware_load(struct phy_device *phydev)* assume that, and load a new image. */ ret =aqr_firmware_load_nvmem (phydev); -if (!ret) +if (ret == -EPROBE_DEFER || !ret)return ret; ret =aqr_firmware_load_fs (phydev);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 401/507 selftests: bonding: add delay before each xvlan_over_bond connectivity check
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hangbin Liu <[email protected]>
[ Upstream commit 2c28ee720ad14f58eb88a97ec3efe7c5c315ea5d ]
Jakub reported increased flakiness in bond_macvlan_ipvlan.sh on regular kernel, while the tests consistently pass on a debug kernel. This suggests a timing-sensitive issue.
To mitigate this, introduce a short sleep before each xvlan_over_bond connectivity check. The delay helps ensure neighbor and route cache have fully converged before verifying connectivity.
The sleep interval is kept minimal since check_connection() is invoked nearly 100 times during the test.
--- .../testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh | 1 + 1 file changed, 1 insertion(+)
tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh +1 -0
@@ -30,6 +30,7 @@ check_connection() local message=${3} RET=0 + sleep 0.25 ip netns exec ${ns} ping ${target} -c 4 -i 0.1 &>/dev/null check_err $? "ping failed" log_test "${bond_mode}/${xvlan_type}_${xvlan_mode}: ${message}"
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 402/507 net: netpoll: initialize work queue before error checks
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit e5235eb6cfe02a51256013a78f7b28779a7740d5 ]
Prevent a kernel warning when netconsole setup fails on devices with IFF_DISABLE_NETPOLL flag. The warning (at kernel/workqueue.c:4242 in __flush_work) occurs because the cleanup path tries to cancel an uninitialized work queue.
When __netpoll_setup() encounters a device with IFF_DISABLE_NETPOLL, it fails early and calls skb_pool_flush() for cleanup. This function calls cancel_work_sync(&np->refill_wq), but refill_wq hasn't been initialized yet, triggering the warning.
Move INIT_WORK() to the beginning of __netpoll_setup(), ensuring the work queue is properly initialized before any potential failure points. This allows the cleanup path to safely cancel the work queue regardless of where the setup fails.
--- net/core/netpoll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/netpoll.c +1 -1
@@ -554,6 +554,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)int err;skb_queue_head_init (&np->skb_pool); +INIT_WORK (&np->refill_wq, refill_skbs_work_handler);if (ndev->priv_flags &IFF_DISABLE_NETPOLL ) { np_err(np, "%s doesn't support polling, aborting\n",
@@ -592,7 +593,6 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)/* fill up the skb queue */ refill_skbs (np); -INIT_WORK (&np->refill_wq, refill_skbs_work_handler);/* last thing to do is link it to the net device structure */ rcu_assign_pointer (ndev->npinfo, npinfo);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 403/507 mtd: lpddr_cmds: fix signed shifts in lpddr_cmds
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Stepchenko <[email protected]>
[ Upstream commit c909fec69f84b39e63876c69b9df2c178c6b76ba ]
There are several places where a value of type 'int' is shifted by lpddr->chipshift. lpddr->chipshift is derived from QINFO geometry and might reach 31 when QINFO reports a 2 GiB size - the maximum supported by LPDDR(1) compliant chips. This may cause unexpected sign-extensions when casting the integer value to the type of 'unsigned long'.
Use '1UL << lpddr->chipshift' and cast 'j' to unsigned long before shifting so the computation is performed at the destination width.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/mtd/lpddr/lpddr_cmds.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/mtd/lpddr/lpddr_cmds.c +4 -4
@@ -79,7 +79,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map)mutex_init (&shared[i].lock);for (j =0 ; j < lpddr->qinfo->HWPartsNum; j++) { *chip = lpddr->chips[i]; - chip->start += j << lpddr->chipshift; + chip->start += (unsigned long )j << lpddr->chipshift; chip->oldstate = chip->state =FL_READY ; chip->priv = &shared[i];/* those should be reset too since
@@ -559,7 +559,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len,break ;if ((len + ofs -1 ) >> lpddr->chipshift) - thislen = (1 <<lpddr->chipshift) - ofs; + thislen = (1UL << lpddr->chipshift) - ofs;else thislen = len;/* get the chip */
@@ -575,7 +575,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, len -= thislen; ofs =0 ; - last_end +=1 << lpddr->chipshift; + last_end +=1UL << lpddr->chipshift; chipnum++; chip = &lpddr->chips[chipnum]; }
@@ -601,7 +601,7 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len)break ;if ((len + ofs -1 ) >> lpddr->chipshift) - thislen = (1 <<lpddr->chipshift) - ofs; + thislen = (1UL << lpddr->chipshift) - ofs;else thislen = len;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 404/507 rqspinlock: Enclose lock/unlock within lock entry acquisitions
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <[email protected]>
[ Upstream commit beb7021a6003d9c6a463fffca0d6311efb8e0e66 ]
Ritesh reported that timeouts occurred frequently for rqspinlock despite reentrancy on the same lock on the same CPU in [0]. This patch closes one of the races leading to this behavior, and reduces the frequency of timeouts.
We currently have a tiny window between the fast-path cmpxchg and the grabbing of the lock entry where an NMI could land, attempt the same lock that was just acquired, and end up timing out. This is not ideal. Instead, move the lock entry acquisition from the fast path to before the cmpxchg, and remove the grabbing of the lock entry in the slow path, assuming it was already taken by the fast path. The TAS fallback is invoked directly without being preceded by the typical fast path, therefore we must continue to grab the deadlock detection entry in that case.
Case on lock leading to missed AA:
cmpxchg lock A
<NMI> ... rqspinlock acquisition of A ... timeout </NMI>
grab_held_lock_entry(A)
There is a similar case when unlocking the lock. If the NMI lands between the WRITE_ONCE and smp_store_release, it is possible that we end up in a situation where the NMI fails to diagnose the AA condition, leading to a timeout.
Case on unlock leading to missed AA:
WRITE_ONCE(rqh->locks[rqh->cnt - 1], NULL)
<NMI> ... rqspinlock acquisition of A ... timeout </NMI>
smp_store_release(A->locked, 0)
The patch changes the order on unlock to smp_store_release() succeeded by WRITE_ONCE() of NULL. This avoids the missed AA detection described above, but may lead to a false positive if the NMI lands between these two statements, which is acceptable (and preferred over a timeout).
The original intention of the reverse order on unlock was to prevent the following possible misdiagnosis of an ABBA scenario:
grab entry A
lock A
grab entry B
lock B
unlock B
smp_store_release(B->locked, 0)
grab entry B lock B grab entry A lock A ! <detect ABBA>
WRITE_ONCE(rqh->locks[rqh->cnt - 1], NULL)
If the store release were is after the WRITE_ONCE, the other CPU would not observe B in the table of the CPU unlocking the lock B. However, since the threads are obviously participating in an ABBA deadlock, it is no longer appealing to use the order above since it may lead to a 250 ms timeout due to missed AA detection.
[0]: https://lore.kernel.org/bpf/CAH6OuBTjG+N=+GGwcpOUbeDN563oz4iVcU3rbse68egp9wj9_A@mail.gmail.com
--- include/asm-generic/rqspinlock.h | 60 +++++++++++++++++--------------- kernel/bpf/rqspinlock.c | 15 ++++---- 2 files changed, 38 insertions(+), 37 deletions(-)
include/asm-generic/rqspinlock.h +32 -28
@@ -129,8 +129,8 @@ static __always_inline void release_held_lock_entry(void)* <error> for lock B * release_held_lock_entry * -* try_cmpxchg_acquire for lock A * grab_held_lock_entry +* try_cmpxchg_acquire for lock A * * Lack of any ordering means reordering may occur such that dec, inc * are done before entry is overwritten. This permits a remote lock
@@ -139,13 +139,8 @@ static __always_inline void release_held_lock_entry(void)* CPU holds a lock it is attempting to acquire, leading to false ABBA * diagnosis). * -* In case of unlock, we will always do a release on the lock word after -* releasing the entry, ensuring that other CPUs cannot hold the lock -* (and make conclusions about deadlocks) until the entry has been -* cleared on the local CPU, preventing any anomalies. Reordering is -* still possible there, but a remote CPU cannot observe a lock in our -* table which it is already holding, since visibility entails our -* release store for the said lock has not retired. +* The case of unlock is treated differently due to NMI reentrancy, see +* comments in res_spin_unlock. * * In theory we don't have a problem if the dec and WRITE_ONCE above get * reordered with each other, we either notice an empty NULL entry on
@@ -175,10 +170,22 @@ static __always_inline int res_spin_lock(rqspinlock_t *lock) {int val =0 ; -if (likely (atomic_try_cmpxchg_acquire (&lock->val, &val, _Q_LOCKED_VAL))) { -grab_held_lock_entry (lock); +/* +* Grab the deadlock detection entry before doing the cmpxchg, so that +* reentrancy due to NMIs between the succeeding cmpxchg and creation of +* held lock entry can correctly detect an acquisition attempt in the +* interrupted context. +* +* cmpxchg lock A +* <NMI> +* res_spin_lock(A) --> missed AA, leads to timeout +* </NMI> +* grab_held_lock_entry(A) +*/ +grab_held_lock_entry (lock); + +if (likely (atomic_try_cmpxchg_acquire (&lock->val, &val, _Q_LOCKED_VAL)))return 0 ; - }return resilient_queued_spin_lock_slowpath (lock, val); }
@@ -192,28 +199,25 @@ static __always_inline void res_spin_unlock(rqspinlock_t *lock) {struct rqspinlock_held *rqh =this_cpu_ptr (&rqspinlock_held_locks); -if (unlikely (rqh->cnt >RES_NR_HELD )) - goto unlock; -WRITE_ONCE (rqh->locks[rqh->cnt -1 ],NULL ); -unlock:/* -* Release barrier, ensures correct ordering. See release_held_lock_entry -* for details. Perform release store instead of queued_spin_unlock, -* since we use this function for test-and-set fallback as well. When we -* have CONFIG_QUEUED_SPINLOCKS=n, we clear the full 4-byte lockword. +* Release barrier, ensures correct ordering. Perform release store +* instead of queued_spin_unlock, since we use this function for the TAS +* fallback as well. When we have CONFIG_QUEUED_SPINLOCKS=n, we clear +* the full 4-byte lockword. * -* Like release_held_lock_entry, we can do the release before the dec. -* We simply care about not seeing the 'lock' in our table from a remote -* CPU once the lock has been released, which doesn't rely on the dec. +* Perform the smp_store_release before clearing the lock entry so that +* NMIs landing in the unlock path can correctly detect AA issues. The +* opposite order shown below may lead to missed AA checks: * -* Unlike smp_wmb(), release is not a two way fence, hence it is -* possible for a inc to move up and reorder with our clearing of the -* entry. This isn't a problem however, as for a misdiagnosis of ABBA, -* the remote CPU needs to hold this lock, which won't be released until -* the store below is done, which would ensure the entry is overwritten -* to NULL, etc. +* WRITE_ONCE(rqh->locks[rqh->cnt - 1], NULL) +* <NMI> +* res_spin_lock(A) --> missed AA, leads to timeout +* </NMI> +* smp_store_release(A->locked, 0) */ smp_store_release (&lock->locked,0 ); +if (likely (rqh->cnt <=RES_NR_HELD )) +WRITE_ONCE (rqh->locks[rqh->cnt -1 ],NULL );this_cpu_dec (rqspinlock_held_locks.cnt); }
kernel/bpf/rqspinlock.c +6 -9
@@ -275,6 +275,10 @@ int __lockfunc resilient_tas_spin_lock(rqspinlock_t *lock)int val, ret =0 ;RES_INIT_TIMEOUT (ts); +/* +* The fast path is not invoked for the TAS fallback, so we must grab +* the deadlock detection entry here. +*/ grab_held_lock_entry (lock);/*
@@ -397,10 +401,7 @@ int __lockfunc resilient_queued_spin_lock_slowpath(rqspinlock_t *lock, u32 val) goto queue; } -/* -* Grab an entry in the held locks array, to enable deadlock detection. -*/ -grab_held_lock_entry (lock); +/* Deadlock detection entry already held after failing fast path. */ /* * We're pending, wait for the owner to go away.
@@ -448,11 +449,7 @@ int __lockfunc resilient_queued_spin_lock_slowpath(rqspinlock_t *lock, u32 val)*/ queue:lockevent_inc (lock_slowpath); -/* -* Grab deadlock detection entry for the queue path. -*/ -grab_held_lock_entry (lock); - +/* Deadlock detection entry already held after failing fast path. */ node =this_cpu_ptr (&rqnodes[0 ].mcs); idx = node->count++; tail =encode_tail (smp_processor_id (), idx);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 405/507 rqspinlock: Use trylock fallback when per-CPU rqnode is busy
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <[email protected]>
[ Upstream commit 81d5a6a438595e46be191d602e5c2d6d73992fdc ]
In addition to deferring to the trylock fallback in NMIs, only do so when an rqspinlock waiter is queued on the current CPU. This is detected by noticing a non-zero node index. This allows NMI waiters to join the waiter queue if it isn't interrupting an existing rqspinlock waiter, and increase the chances of fairly obtaining the lock, performing deadlock detection as the head, and not being starved while attempting the trylock.
The trylock path in particular is unlikely to succeed under contention, as it relies on the lock word becoming 0, which indicates no contention. This means that the most likely result for NMIs attempting a trylock is a timeout under contention if they don't hit an AA or ABBA case.
The core problem being addressed through the fixed commit was removing the dependency edge between an NMI queue waiter and the queue waiter it is interrupting. Whenever a circular dependency forms, and with no way to break it (as non-head waiters don't poll for deadlocks or timeouts), we would enter into a deadlock. A trylock either breaks such an edge by probing for deadlocks, and finally terminating the waiting loop using a timeout.
By excluding queueing on CPUs where the node index is non-zero for NMIs, this sort of dependency is broken. The CPU enters the trylock path for those cases, and falls back to deadlock checks and timeouts. However, in other case where it doesn't interrupt the CPU in the slow path while its queued on the lock, it can join the queue as a normal waiter, and avoid trylock associated starvation and subsequent timeouts.
There are a few remaining cases here that matter: the NMI can still preempt the owner in its critical section, and if it queues as a non-head waiter, it can end up impeding the progress of the owner. While this won't deadlock, since the head waiter will eventually signal the NMI waiter to either stop (due to a timeout), it can still lead to long timeouts. These gaps will be addressed in subsequent commits.
Note that while the node count detection approach is less conservative than simply deferring NMIs to trylock, it is going to return errors where attempts to lock B in NMI happen while waiters for lock A are in a lower context on the same CPU. However, this only occurs when the lower context is queued in the slow path, and the NMI attempt can proceed without failure in all other cases. To continue to prevent AA deadlocks (or ABBA in a similar NMI interrupting lower context pattern), we'd need a more fleshed out algorithm to unlink NMI waiters after they queue and detect such cases. However, all that complexity isn't appealing yet to reduce the failure rate in the small window inside the slow path.
It is important to note that reentrancy in the slow path can also happen through trace_contention_{begin,end}, but in those cases, unlike an NMI, the forward progress of the head waiter (or the predecessor in general) is not being blocked.
--- kernel/bpf/rqspinlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/bpf/rqspinlock.c +1 -1
@@ -465,7 +465,7 @@ int __lockfunc resilient_queued_spin_lock_slowpath(rqspinlock_t *lock, u32 val)* any MCS node. This is not the most elegant solution, but is * simple enough. */ -if (unlikely (idx >= _Q_MAX_NODES ||in_nmi ())) { +if (unlikely (idx >= _Q_MAX_NODES || (in_nmi () && idx >0 ))) {lockevent_inc (lock_no_node);RES_RESET_TIMEOUT (ts,RES_DEF_TIMEOUT );while (!queued_spin_trylock (lock)) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 406/507 remoteproc: qcom_q6v5_wcss: fix parsing of qcom,halt-regs
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexandru Gagniuc <[email protected]>
[ Upstream commit 7e81fa8d809ed1e67ae9ecd52d20a20c2c65d877 ]
The "qcom,halt-regs" consists of a phandle reference followed by the three offsets within syscon for halt registers. Thus, we need to request 4 integers from of_property_read_variable_u32_array(), with the halt_reg ofsets at indexes 1, 2, and 3. Offset 0 is the phandle.
With MAX_HALT_REG at 3, of_property_read_variable_u32_array() returns -EOVERFLOW, causing .probe() to fail.
Increase MAX_HALT_REG to 4, and update the indexes accordingly.
--- drivers/remoteproc/qcom_q6v5_wcss.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/remoteproc/qcom_q6v5_wcss.c +4 -4
@@ -85,7 +85,7 @@#define TCSR_WCSS_CLK_MASK 0x1F#define TCSR_WCSS_CLK_ENABLE 0x14 -#define MAX_HALT_REG 3 +#define MAX_HALT_REG 4enum {WCSS_IPQ8074 ,WCSS_QCS404 ,
@@ -864,9 +864,9 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss,return -EINVAL ; } - wcss->halt_q6 = halt_reg[0 ]; - wcss->halt_wcss = halt_reg[1 ]; - wcss->halt_nc = halt_reg[2 ]; + wcss->halt_q6 = halt_reg[1 ]; + wcss->halt_wcss = halt_reg[2 ]; + wcss->halt_nc = halt_reg[3 ];return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 407/507 md/raid5: fix IO hang when array is broken with IO inflight
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit a913d1f6a7f607c110aeef8b58c8988f47a4b24e ]
Following test can cause IO hang:
mdadm -CvR /dev/md0 -l10 -n4 /dev/sd[abcd] --assume-clean --chunk=64K --bitmap=none sleep 5
echo 1 > /sys/block/sda/device/delete
echo 1 > /sys/block/sdb/device/delete
echo 1 > /sys/block/sdc/device/delete
echo 1 > /sys/block/sdd/device/delete
dd if=/dev/md0 of=/dev/null bs=8k count=1 iflag=direct
Root cause:
1) all disks removed, however all rdevs in the array is still in sync, IO will be issued normally.
2) IO failure from sda, and set badblocks failed, sda will be faulty and MD_SB_CHANGING_PENDING will be set.
3) error recovery try to recover this IO from other disks, IO will be issued to sdb, sdc, and sdd.
4) IO failure from sdb, and set badblocks failed again, now array is broken and will become read-only.
5) IO failure from sdc and sdd, however, stripe can't be handled anymore because MD_SB_CHANGING_PENDING is set:
handle_stripe
handle_stripe
if (test_bit MD_SB_CHANGING_PENDING)
set_bit STRIPE_HANDLE
goto finish
// skip handling failed stripe
release_stripe
if (test_bit STRIPE_HANDLE)
list_add_tail conf->hand_list
6) later raid5d can't handle failed stripe as well:
raid5d
md_check_recovery
md_update_sb
if (!md_is_rdwr())
// can't clear pending bit
return if (test_bit MD_SB_CHANGING_PENDING)
break;
// can't handle failed stripe
Since MD_SB_CHANGING_PENDING can never be cleared for read-only array, fix this problem by skip this checking for read-only array.
--- drivers/md/raid5.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/md/raid5.c +4 -2
@@ -4938,7 +4938,8 @@ static void handle_stripe(struct stripe_head *sh) goto finish;if (s.handle_bad_blocks || -test_bit (MD_SB_CHANGE_PENDING , &conf->mddev->sb_flags)) { + (md_is_rdwr (conf->mddev) && +test_bit (MD_SB_CHANGE_PENDING , &conf->mddev->sb_flags))) {set_bit (STRIPE_HANDLE , &sh->state); goto finish; }
@@ -6753,7 +6754,8 @@ static void raid5d(struct md_thread *thread)int batch_size, released;unsigned int offset; -if (test_bit (MD_SB_CHANGE_PENDING , &mddev->sb_flags)) +if (md_is_rdwr (mddev) && +test_bit (MD_SB_CHANGE_PENDING , &mddev->sb_flags))break ; released =release_stripe_list (conf, conf->temp_inactive_list);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 408/507 clk: keystone: fix compile testing
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit b276445e98fe28609688fb85b89a81b803910e63 ]
Some keystone clock drivers can be selected when COMPILE_TEST is enabled but since commit b745c0794e2f ("clk: keystone: Add sci-clk driver support") they are never actually built.
Enable compile testing by allowing the build system to process the keystone drivers.
--- drivers/clk/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/clk/Makefile +1 -2
@@ -124,8 +124,7 @@ obj-$(CONFIG_ARCH_HISI) += hisilicon/ obj-y += imgtec/ obj-y += imx/ obj-y += ingenic/ -obj-$(CONFIG_ARCH_K3) += keystone/ -obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ +obj-y += keystone/ obj-y += mediatek/ obj-$(CONFIG_ARCH_MESON) += meson/ obj-y += microchip/
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 409/507 net: dsa: b53: fix VLAN_ID_IDX write size for BCM5325/65
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 6f268e275c74dae0536e0b61982a8db25bcf4f16 ]
Since BCM5325 and BCM5365 only support up to 256 VLANs, the VLAN_ID_IDX register is only 8 bit wide, not 16 bit, so use an appropriate accessor.
--- drivers/net/dsa/b53/b53_common.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/dsa/b53/b53_common.c +6 -2
@@ -1924,8 +1924,12 @@ static int b53_arl_op(struct b53_device *dev, int op, int port,/* Perform a read for the given MAC and VID */ b53_write48 (dev,B53_ARLIO_PAGE ,B53_MAC_ADDR_IDX , mac); -if (!is5325m (dev)) -b53_write16 (dev,B53_ARLIO_PAGE ,B53_VLAN_ID_IDX , vid); +if (!is5325m (dev)) { +if (is5325 (dev) ||is5365 (dev)) +b53_write8 (dev,B53_ARLIO_PAGE ,B53_VLAN_ID_IDX , vid); +else +b53_write16 (dev,B53_ARLIO_PAGE ,B53_VLAN_ID_IDX , vid); + }/* Issue a read operation for this MAC */ ret =b53_arl_rw_op (dev,1 );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 410/507 net: dsa: b53: fix extracting VID from entry for BCM5325/65
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 9316012dd01952f75e37035360138ccc786ef727 ]
BCM5325/65's Entry register uses the highest three bits for VALID/STATIC/AGE, so shifting by 53 only will add these to b53_arl_entry::vid.
So make sure to mask the vid value as well, to not get invalid VIDs.
--- drivers/net/dsa/b53/b53_priv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/dsa/b53/b53_priv.h +1 -1
@@ -338,7 +338,7 @@ static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent, ent->is_age = !!(mac_vid &ARLTBL_AGE_25 ); ent->is_static = !!(mac_vid &ARLTBL_STATIC_25 );u64_to_ether_addr (mac_vid, ent->mac); - ent->vid = mac_vid >>ARLTBL_VID_S_65 ; + ent->vid = (mac_vid >>ARLTBL_VID_S_65 ) &ARLTBL_VID_MASK_25 ; } static inline void b53_arl_from_entry(u64 *mac_vid, u32 *fwd_entry,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 411/507 net: dsa: b53: b53_arl_read{,25}(): use the entry for comparision
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit a6e4fd38bf2f2e2363b61c27f4e6c49b14e4bb07 ]
Align the b53_arl_read{,25}() functions by consistently using the parsed arl entry instead of parsing the raw registers again.
Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65")
--- drivers/net/dsa/b53/b53_common.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-)
drivers/net/dsa/b53/b53_common.c +10 -12
@@ -1830,7 +1830,7 @@ static int b53_arl_rw_op(struct b53_device *dev, unsigned int op)return b53_arl_op_wait (dev); } -static int b53_arl_read (struct b53_device *dev,u64 mac, +static int b53_arl_read (struct b53_device *dev,const u8 *mac,u16 vid,struct b53_arl_entry *ent,u8 *idx) {DECLARE_BITMAP (free_bins,B53_ARLTBL_MAX_BIN_ENTRIES );
@@ -1854,14 +1854,13 @@ static int b53_arl_read(struct b53_device *dev, u64 mac, B53_ARLTBL_DATA_ENTRY(i), &fwd_entry);b53_arl_to_entry (ent, mac_vid, fwd_entry); -if (!(fwd_entry &ARLTBL_VALID )) { +if (!ent->is_valid) {set_bit (i, free_bins);continue ; } -if ((mac_vid &ARLTBL_MAC_MASK ) != mac) +if (!ether_addr_equal (ent->mac, mac))continue ; -if (dev->vlan_enabled && - ((mac_vid >>ARLTBL_VID_S ) &ARLTBL_VID_MASK ) != vid) +if (dev->vlan_enabled && ent->vid != vid)continue ; *idx = i;return 0 ;
@@ -1871,7 +1870,7 @@ static int b53_arl_read(struct b53_device *dev, u64 mac,return *idx >= dev->num_arl_bins ? -ENOSPC : -ENOENT ; } -static int b53_arl_read_25 (struct b53_device *dev,u64 mac, +static int b53_arl_read_25 (struct b53_device *dev,const u8 *mac,u16 vid,struct b53_arl_entry *ent,u8 *idx) {DECLARE_BITMAP (free_bins,B53_ARLTBL_MAX_BIN_ENTRIES );
@@ -1893,14 +1892,13 @@ static int b53_arl_read_25(struct b53_device *dev, u64 mac,b53_arl_to_entry_25 (ent, mac_vid); -if (!(mac_vid &ARLTBL_VALID_25 )) { +if (!ent->is_valid) {set_bit (i, free_bins);continue ; } -if ((mac_vid &ARLTBL_MAC_MASK ) != mac) +if (!ether_addr_equal (ent->mac, mac))continue ; -if (dev->vlan_enabled && - ((mac_vid >>ARLTBL_VID_S_65 ) &ARLTBL_VID_MASK_25 ) != vid) +if (dev->vlan_enabled && ent->vid != vid)continue ; *idx = i;return 0 ;
@@ -1937,9 +1935,9 @@ static int b53_arl_op(struct b53_device *dev, int op, int port,return ret;if (is5325 (dev) ||is5365 (dev)) - ret =b53_arl_read_25 (dev, mac, vid, &ent, &idx); + ret =b53_arl_read_25 (dev, addr, vid, &ent, &idx);else - ret =b53_arl_read (dev, mac, vid, &ent, &idx); + ret =b53_arl_read (dev, addr, vid, &ent, &idx);/* If this is a read, just finish now */ if (op)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 412/507 net: dsa: b53: move reading ARL entries into their own function
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 4a291fe7226736a465ddb3fa93c21fcef7162ec7 ]
Instead of duplicating the whole code iterating over all bins for BCM5325, factor out reading and parsing the entry into its own functions, and name it the modern one after the first chip with that ARL format, (BCM53)95.
Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65")
--- drivers/net/dsa/b53/b53_common.c | 69 +++++++++++--------------------- 1 file changed, 23 insertions(+), 46 deletions(-)
drivers/net/dsa/b53/b53_common.c +23 -46
@@ -1830,48 +1830,30 @@ static int b53_arl_rw_op(struct b53_device *dev, unsigned int op)return b53_arl_op_wait (dev); } -static int b53_arl_read (struct b53_device *dev,const u8 *mac, -u16 vid,struct b53_arl_entry *ent,u8 *idx) +static void b53_arl_read_entry_25 (struct b53_device *dev, +struct b53_arl_entry *ent,u8 idx) { -DECLARE_BITMAP (free_bins,B53_ARLTBL_MAX_BIN_ENTRIES ); -unsigned int i; -int ret; - - ret =b53_arl_op_wait (dev); -if (ret) -return ret; - -bitmap_zero (free_bins, dev->num_arl_bins); - -/* Read the bins */ -for (i =0 ; i < dev->num_arl_bins; i++) { -u64 mac_vid; -u32 fwd_entry; +u64 mac_vid; -b53_read64 (dev,B53_ARLIO_PAGE , -B53_ARLTBL_MAC_VID_ENTRY (i), &mac_vid); -b53_read32 (dev,B53_ARLIO_PAGE , -B53_ARLTBL_DATA_ENTRY (i), &fwd_entry); -b53_arl_to_entry (ent, mac_vid, fwd_entry); +b53_read64 (dev,B53_ARLIO_PAGE ,B53_ARLTBL_MAC_VID_ENTRY (idx), + &mac_vid); +b53_arl_to_entry_25 (ent, mac_vid); +} -if (!ent->is_valid) { -set_bit (i, free_bins); -continue ; - } -if (!ether_addr_equal (ent->mac, mac)) -continue ; -if (dev->vlan_enabled && ent->vid != vid) -continue ; - *idx = i; -return 0 ; - } +static void b53_arl_read_entry_95 (struct b53_device *dev, +struct b53_arl_entry *ent,u8 idx) +{ +u32 fwd_entry; +u64 mac_vid; - *idx =find_first_bit (free_bins, dev->num_arl_bins); -return *idx >= dev->num_arl_bins ? -ENOSPC : -ENOENT ; +b53_read64 (dev,B53_ARLIO_PAGE ,B53_ARLTBL_MAC_VID_ENTRY (idx), + &mac_vid); +b53_read32 (dev,B53_ARLIO_PAGE ,B53_ARLTBL_DATA_ENTRY (idx), &fwd_entry); +b53_arl_to_entry (ent, mac_vid, fwd_entry); } -static int b53_arl_read_25 (struct b53_device *dev,const u8 *mac, -u16 vid,struct b53_arl_entry *ent,u8 *idx) +static int b53_arl_read (struct b53_device *dev,const u8 *mac, +u16 vid,struct b53_arl_entry *ent,u8 *idx) {DECLARE_BITMAP (free_bins,B53_ARLTBL_MAX_BIN_ENTRIES );unsigned int i;
@@ -1885,12 +1867,10 @@ static int b53_arl_read_25(struct b53_device *dev, const u8 *mac,/* Read the bins */ for (i =0 ; i < dev->num_arl_bins; i++) { -u64 mac_vid; - -b53_read64 (dev,B53_ARLIO_PAGE , -B53_ARLTBL_MAC_VID_ENTRY (i), &mac_vid); - -b53_arl_to_entry_25 (ent, mac_vid); +if (is5325 (dev) ||is5365 (dev)) +b53_arl_read_entry_25 (dev, ent, i); +else +b53_arl_read_entry_95 (dev, ent, i);if (!ent->is_valid) {set_bit (i, free_bins);
@@ -1934,10 +1914,7 @@ static int b53_arl_op(struct b53_device *dev, int op, int port,if (ret)return ret; -if (is5325 (dev) ||is5365 (dev)) - ret =b53_arl_read_25 (dev, addr, vid, &ent, &idx); -else - ret =b53_arl_read (dev, addr, vid, &ent, &idx); + ret =b53_arl_read (dev, addr, vid, &ent, &idx);/* If this is a read, just finish now */ if (op)
Signature · 1 line
2.51.0