6.0.3-rc1 review
Subsystems (10)
Greg Kroah-Hartman
maintainerPATCH 263/862 wifi: wfx: prevent underflow in wfx_send_pds()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit f97c81f5b7f8047810b0d79a8f759a83951210a0 ]
This does a "chunk_len - 4" subtraction later when it calls:
ret = wfx_hif_configuration(wdev, buf + 4, chunk_len - 4);
so check for "chunk_len" is less than 4.
--- drivers/net/wireless/silabs/wfx/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/silabs/wfx/main.c +1 -1
@@ -181,7 +181,7 @@ int wfx_send_pds(struct wfx_dev *wdev, u8 *buf, size_t len)while (len >0 ) { chunk_type =get_unaligned_le16 (buf +0 ); chunk_len =get_unaligned_le16 (buf +2 ); -if (chunk_len > len) { +if (chunk_len <4 || chunk_len > len) {dev_err (wdev->dev,"PDS:%d: corrupted file\n" , chunk_num);return -EINVAL ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 264/862 wifi: rtw88: add missing destroy_workqueue() on error path in rtw_core_init()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit b0ea758b30bbdf7c4323c78b7c50c05d2e1224d5 ]
Add the missing destroy_workqueue() before return from rtw_core_init() in error path.
--- drivers/net/wireless/realtek/rtw88/main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/wireless/realtek/rtw88/main.c +6 -2
@@ -2045,7 +2045,7 @@ int rtw_core_init(struct rtw_dev *rtwdev ret =rtw_load_firmware (rtwdev,RTW_NORMAL_FW );if (ret) {rtw_warn (rtwdev,"no firmware loaded\n" ); -return ret; + goto out; }if (chip->wow_fw_name) {
@@ -2055,11 +2055,15 @@ int rtw_core_init(struct rtw_dev *rtwdevwait_for_completion (&rtwdev->fw.completion);if (rtwdev->fw.firmware)release_firmware (rtwdev->fw.firmware); -return ret; + goto out; } }return 0 ; + +out: +destroy_workqueue (rtwdev->tx_wq); +return ret; }EXPORT_SYMBOL (rtw_core_init);
Greg Kroah-Hartman
maintainerPATCH 265/862 selftests/xsk: Avoid use-after-free on ctx
In reply to Greg Kroah-HartmanFrom: Ian Rogers <[email protected]>
[ Upstream commit af515a5587b8f45f19e11657746e0c89411b0380 ]
The put lowers the reference count to 0 and frees ctx, reading it afterwards is invalid. Move the put after the uses and determine the last use by the reference count being 1.
--- tools/testing/selftests/bpf/xsk.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/testing/selftests/bpf/xsk.c +3 -3
@@ -1237,15 +1237,15 @@ void xsk_socket__delete(struct xsk_socket *xsk) ctx = xsk->ctx; umem = ctx->umem; -xsk_put_ctx (ctx, true); - -if (!ctx->refcount) { +if (ctx->refcount ==1 ) {xsk_delete_bpf_maps (xsk);close (ctx->prog_fd);if (ctx->has_bpf_link)close (ctx->link_fd); } +xsk_put_ctx (ctx, true); + err =xsk_get_mmap_offsets (xsk->fd, &off);if (!err) {if (xsk->rx) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 266/862 wifi: mac80211: mlme: assign link address correctly
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
[ Upstream commit acdc3e47881d86dc1cb89d4603e3fed90ab150db ]
Right now, we assign the link address only after we add the link to the driver, which is quite obviously wrong. It happens to work in many cases because it gets updated immediately, and then link_conf updates may update it, but it's clearly not really right.
Set the link address during ieee80211_mgd_setup_link() so it's set before telling the driver about the link.
--- net/mac80211/mlme.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
net/mac80211/mlme.c +2 -3
@@ -6291,6 +6291,8 @@ void ieee80211_mgd_setup_link(struct ieee80211_link_data *link)if (sdata->u.mgd.assoc_data)ether_addr_copy (link->conf->addr, sdata->u.mgd.assoc_data->link[link_id].addr); +else if (!is_valid_ether_addr (link->conf->addr)) +eth_random_addr (link->conf->addr); }/* scan finished notification */
@@ -6378,9 +6380,6 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, goto out_err; } -if (mlo && !is_valid_ether_addr (link->conf->addr)) -eth_random_addr (link->conf->addr); -if (WARN_ON (!ifmgd->auth_data && !ifmgd->assoc_data)) { err = -EINVAL ; goto out_err;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 267/862 spi: qup: add missing clk_disable_unprepare on error in spi_qup_resume()
In reply to Greg Kroah-HartmanFrom: Xu Qiang <[email protected]>
[ Upstream commit 70034320fdc597b8f58b4a43bb547f17c4c5557a ]
Add the missing clk_disable_unprepare() before return from spi_qup_resume() in the error handling case.
--- drivers/spi/spi-qup.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
drivers/spi/spi-qup.c +14 -3
@@ -1245,14 +1245,25 @@ static int spi_qup_resume(struct device *device)return ret; ret =clk_prepare_enable (controller->cclk); -if (ret) +if (ret) { +clk_disable_unprepare (controller->iclk);return ret; + } ret =spi_qup_set_state (controller,QUP_STATE_RESET );if (ret) -return ret; + goto disable_clk; + + ret =spi_master_resume (master); +if (ret) + goto disable_clk; - return spi_master_resume(master); +return 0 ; + +disable_clk: +clk_disable_unprepare (controller->cclk); +clk_disable_unprepare (controller->iclk); + return ret; }#endif /* CONFIG_PM_SLEEP */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 268/862 spi: qup: add missing clk_disable_unprepare on error in spi_qup_pm_resume_runtime()
In reply to Greg Kroah-HartmanFrom: Xu Qiang <[email protected]>
[ Upstream commit 494a22765ce479c9f8ad181c5d24cffda9f534bb ]
Add the missing clk_disable_unprepare() before return from spi_qup_pm_resume_runtime() in the error handling case.
--- drivers/spi/spi-qup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/spi/spi-qup.c +3 -1
@@ -1198,8 +1198,10 @@ static int spi_qup_pm_resume_runtime(struct device *device)return ret; ret =clk_prepare_enable (controller->cclk); -if (ret) +if (ret) { +clk_disable_unprepare (controller->iclk);return ret; + }/* Disable clocks auto gaiting */ config =readl_relaxed (controller->base +QUP_CONFIG );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 269/862 wifi: rtl8xxxu: Fix skb misuse in TX queue selection
In reply to Greg Kroah-HartmanFrom: Bitterblue Smith <[email protected]>
[ Upstream commit edd5747aa12ed61a5ecbfa58d3908623fddbf1e8 ]
rtl8xxxu_queue_select() selects the wrong TX queues because it's reading memory from the wrong address. It expects to find ieee80211_hdr at skb->data, but that's not the case after skb_push(). Move the call to rtl8xxxu_queue_select() before the call to skb_push().
--- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +2 -1
@@ -5062,6 +5062,8 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,if (control && control->sta) sta = control->sta; + queue =rtl8xxxu_queue_select (hw, skb); + tx_desc =skb_push (skb, tx_desc_size);memset (tx_desc,0 , tx_desc_size);
@@ -5074,7 +5076,6 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, is_broadcast_ether_addr(ieee80211_get_DA(hdr))) tx_desc->txdw0 |= TXDESC_BROADMULTICAST; - queue =rtl8xxxu_queue_select (hw, skb); tx_desc->txdw1 =cpu_to_le32 (queue <<TXDESC_QUEUE_SHIFT );if (tx_info->control.hw_key) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 270/862 spi: meson-spicc: do not rely on busy flag in pow2 clk ops
In reply to Greg Kroah-HartmanFrom: Neil Armstrong <[email protected]>
[ Upstream commit 36acf80fc0c4b5ebe6fa010b524d442ee7f08fd3 ]
Since [1], controller's busy flag isn't set anymore when the __spi_transfer_message_noqueue() is used instead of the __spi_pump_transfer_message() logic for spi_sync transfers.
Since the pow2 clock ops were limited to only be available when a transfer is ongoing (between prepare_transfer_hardware and unprepare_transfer_hardware callbacks), the only way to track this down is to check for the controller cur_msg.
[1] ae7d2346dc89 ("spi: Don't use the message queue if possible in spi_sync")
--- drivers/spi/spi-meson-spicc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/spi/spi-meson-spicc.c +3 -3
@@ -537,7 +537,7 @@ static unsigned long meson_spicc_pow2_recalc_rate(struct clk_hw *hw,struct clk_divider *divider =to_clk_divider (hw);struct meson_spicc_device *spicc =pow2_clk_to_spicc (divider); -if (!spicc->master->cur_msg || !spicc->master->busy) +if (!spicc->master->cur_msg)return 0 ;return clk_divider_ops.recalc_rate (hw, parent_rate);
@@ -549,7 +549,7 @@ static int meson_spicc_pow2_determine_rate(struct clk_hw *hw,struct clk_divider *divider =to_clk_divider (hw);struct meson_spicc_device *spicc =pow2_clk_to_spicc (divider); -if (!spicc->master->cur_msg || !spicc->master->busy) +if (!spicc->master->cur_msg)return -EINVAL ;return clk_divider_ops.determine_rate (hw, req);
@@ -561,7 +561,7 @@ static int meson_spicc_pow2_set_rate(struct clk_hw *hw, unsigned long rate,struct clk_divider *divider =to_clk_divider (hw);struct meson_spicc_device *spicc =pow2_clk_to_spicc (divider); -if (!spicc->master->cur_msg || !spicc->master->busy) +if (!spicc->master->cur_msg)return -EINVAL ;return clk_divider_ops.set_rate (hw, rate, parent_rate);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 271/862 bpf: btf: fix truncated last_member_type_id in btf_struct_resolve
In reply to Greg Kroah-HartmanFrom: Lorenz Bauer <[email protected]>
[ Upstream commit a37a32583e282d8d815e22add29bc1e91e19951a ]
When trying to finish resolving a struct member, btf_struct_resolve saves the member type id in a u16 temporary variable. This truncates the 32 bit type id value if it exceeds UINT16_MAX.
As a result, structs that have members with type ids > UINT16_MAX and which need resolution will fail with a message like this:
[67414] STRUCT ff_device size=120 vlen=12
effect_owners type_id=67434 bits_offset=960 Member exceeds struct_size
Fix this by changing the type of last_member_type_id to u32.
--- kernel/bpf/btf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/bpf/btf.c +1 -1
@@ -3128,7 +3128,7 @@ static int btf_struct_resolve(struct btf_verifier_env *env,if (v->next_member) {const struct btf_type *last_member_type;const struct btf_member *last_member; -u16 last_member_type_id; +u32 last_member_type_id; last_member =btf_type_member (v->t) + v->next_member -1 ; last_member_type_id = last_member->type;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 272/862 wifi: rtl8xxxu: gen2: Fix mistake in path B IQ calibration
In reply to Greg Kroah-HartmanFrom: Bitterblue Smith <[email protected]>
[ Upstream commit e963a19c64ac0d2f8785d36a27391abd91ac77aa ]
Found by comparing with the vendor driver. Currently this affects only the RTL8192EU, which is the only gen2 chip with 2 TX paths supported by this driver. It's unclear what kind of effect the mistake had in practice, since I don't have any RTL8192EU devices to test it.
--- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +2 -2
@@ -2929,12 +2929,12 @@ bool rtl8xxxu_gen2_simularity_compare(struct rtl8xxxu_priv *priv, }if (!(simubitmap &0x30 ) && priv->tx_paths >1 ) { -/* path B RX OK */ +/* path B TX OK */ for (i =4 ; i <6 ; i++) result[3 ][i] = result[c1][i]; } -if (!(simubitmap &0x30 ) && priv->tx_paths >1 ) { +if (!(simubitmap &0xc0 ) && priv->tx_paths >1 ) {/* path B RX OK */ for (i =6 ; i <8 ; i++) result[3 ][i] = result[c1][i];
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 273/862 wifi: rtl8xxxu: Remove copy-paste leftover in gen2_update_rate_mask
In reply to Greg Kroah-HartmanFrom: Bitterblue Smith <[email protected]>
[ Upstream commit d5350756c03cdf18696295c6b11d7acc4dbf825c ]
It looks like a leftover from copying rtl8xxxu_update_rate_mask, which is used with the gen1 chips.
It wasn't causing any problems for my RTL8188FU test device, but it's clearly a mistake, so remove it.
--- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +2 -3
@@ -4353,15 +4353,14 @@ void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv, h2c.b_macid_cfg.ramask2 = (ramask >>16 ) &0xff ; h2c.b_macid_cfg.ramask3 = (ramask >>24 ) &0xff ; - h2c.ramask.arg =0x80 ; h2c.b_macid_cfg.data1 = rateid;if (sgi) h2c.b_macid_cfg.data1 |=BIT (7 ); h2c.b_macid_cfg.data2 = bw; -dev_dbg (&priv->udev->dev,"%s: rate mask %08x, arg %02x, size %zi\n" , - __func__, ramask, h2c.ramask.arg,sizeof (h2c.b_macid_cfg)); +dev_dbg (&priv->udev->dev,"%s: rate mask %08x, rateid %02x, sgi %d, size %zi\n" , + __func__, ramask, rateid, sgi,sizeof (h2c.b_macid_cfg));rtl8xxxu_gen2_h2c_cmd (priv, &h2c,sizeof (h2c.b_macid_cfg)); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 274/862 Bluetooth: avoid hci_dev_test_and_set_flag() in mgmt_init_hdev()
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
[ Upstream commit f74ca25d6d6629ffd4fd80a1a73037253b57d06b ]
syzbot is again reporting attempt to cancel uninitialized work at mgmt_index_removed() [1], for setting of HCI_MGMT flag from mgmt_init_hdev() from hci_mgmt_cmd() from hci_sock_sendmsg() can race with testing of HCI_MGMT flag from mgmt_index_removed() from hci_sock_bind() due to lack of serialization via hci_dev_lock().
Since mgmt_init_hdev() is called with mgmt_chan_list_lock held, we can safely split hci_dev_test_and_set_flag() into hci_dev_test_flag() and hci_dev_set_flag(). Thus, in order to close this race, set HCI_MGMT flag after INIT_DELAYED_WORK() completed.
This is a local fix based on mgmt_chan_list_lock. Lack of serialization via hci_dev_lock() might be causing different race conditions somewhere else. But a global fix based on hci_dev_lock() should deserve a future patch.
--- net/bluetooth/mgmt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/bluetooth/mgmt.c +3 -1
@@ -1050,7 +1050,7 @@ static void discov_off(struct work_struct *work)static void mgmt_init_hdev (struct sock *sk,struct hci_dev *hdev) { -if (hci_dev_test_and_set_flag (hdev,HCI_MGMT )) +if (hci_dev_test_flag (hdev,HCI_MGMT ))return ;BT_INFO ("MGMT ver %d.%d" ,MGMT_VERSION ,MGMT_REVISION );
@@ -1065,6 +1065,8 @@ static void mgmt_init_hdev(struct sock *sk, struct hci_dev *hdev)* it */ hci_dev_clear_flag (hdev,HCI_BONDABLE ); + +hci_dev_set_flag (hdev,HCI_MGMT ); } static int read_controller_info(struct sock *sk, struct hci_dev *hdev,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 275/862 wifi: mt76: mt7921e: fix race issue between reset and suspend/resume
In reply to Greg Kroah-HartmanFrom: Sean Wang <[email protected]>
[ Upstream commit ff6c4a6449793e9718ef2e9ad46864b63022648e ]
It is unexpected that the reset work is running simultaneously with the suspend or resume context and it is possible that reset work is still running even after mt7921 is suspended if we don't fix the race issue.
Thus, the suspend procedure should be waiting until the reset is completed at the beginning and ignore the subsequent the reset requests.
In case there is an error that happens during either suspend or resume handler, we will schedule a reset task to recover the error before returning the error code to ensure we can immediately fix the error there.
--- drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 5 +++++ drivers/net/wireless/mediatek/mt76/mt7921/pci.c | 13 +++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7921/mac.c +5 -0
@@ -780,6 +780,7 @@ void mt7921_mac_reset_work(struct work_struct *work)void mt7921_reset (struct mt76_dev *mdev) { struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); +struct mt76_connac_pm *pm = &dev->pm;if (!dev->hw_init_done)return ;
@@ -787,8 +788,12 @@ void mt7921_reset(struct mt76_dev *mdev)if (dev->hw_full_reset)return ; +if (pm->suspended) +return ; +queue_work (dev->mt76.wq, &dev->reset_work); } +EXPORT_SYMBOL_GPL (mt7921_reset);void mt7921_mac_update_mib_stats (struct mt7921_phy *phy) {
drivers/net/wireless/mediatek/mt76/mt7921/pci.c +9 -4
@@ -367,6 +367,7 @@ static int mt7921_pci_suspend(struct device *device)int i, err; pm->suspended = true; +flush_work (&dev->reset_work);cancel_delayed_work_sync (&pm->ps_work);cancel_work_sync (&pm->wake_work);
@@ -428,6 +429,9 @@ static int mt7921_pci_suspend(struct device *device) restore_suspend: pm->suspended = false; +if (err <0 ) +mt7921_reset (&dev->mt76); +return err; }
@@ -441,7 +445,7 @@ static int mt7921_pci_resume(struct device *device) err =mt7921_mcu_drv_pmctrl (dev);if (err <0 ) -return err; + goto failed;mt7921_wpdma_reinit_cond (dev);
@@ -471,11 +475,12 @@ static int mt7921_pci_resume(struct device *device)mt76_connac_mcu_set_deep_sleep (&dev->mt76, false); err =mt76_connac_mcu_set_hif_suspend (mdev, false); -if (err) -return err; - +failed: pm->suspended = false; +if (err <0 ) +mt7921_reset (&dev->mt76); +return err; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 276/862 wifi: mt76: mt7921s: fix race issue between reset and suspend/resume
In reply to Greg Kroah-HartmanFrom: Sean Wang <[email protected]>
[ Upstream commit e86f10e6809add9132ecc2c6b3184ed59db7ca71 ]
It is unexpected that the reset work is running simultaneously with the suspend or resume context and it is possible that reset work is still running even after mt7921 is suspended if we don't fix the race issue.
Thus, the suspend procedure should be waiting until the reset is completed at the beginning and ignore the subsequent the reset requests.
In case there is an error that happens during either suspend or resume handler, we will schedule a reset task to recover the error before returning the error code to ensure we can immediately fix the error there.
--- drivers/net/wireless/mediatek/mt76/mt7921/sdio.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7921/sdio.c +9 -4
@@ -206,6 +206,7 @@ static int mt7921s_suspend(struct device *__dev) pm->suspended = true;set_bit (MT76_STATE_SUSPEND , &mdev->phy.state); +flush_work (&dev->reset_work);cancel_delayed_work_sync (&pm->ps_work);cancel_work_sync (&pm->wake_work);
@@ -261,6 +262,9 @@ static int mt7921s_suspend(struct device *__dev)clear_bit (MT76_STATE_SUSPEND , &mdev->phy.state); pm->suspended = false; +if (err <0 ) +mt7921_reset (&dev->mt76); +return err; }
@@ -276,7 +280,7 @@ static int mt7921s_resume(struct device *__dev) err =mt7921_mcu_drv_pmctrl (dev);if (err <0 ) -return err; + goto failed;mt76_worker_enable (&mdev->tx_worker);mt76_worker_enable (&mdev->sdio.txrx_worker);
@@ -288,11 +292,12 @@ static int mt7921s_resume(struct device *__dev)mt76_connac_mcu_set_deep_sleep (mdev, false); err =mt76_connac_mcu_set_hif_suspend (mdev, false); -if (err) -return err; - +failed: pm->suspended = false; +if (err <0 ) +mt7921_reset (&dev->mt76); +return err; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 277/862 wifi: mt76: mt7921u: fix race issue between reset and suspend/resume
In reply to Greg Kroah-HartmanFrom: Sean Wang <[email protected]>
[ Upstream commit 86f15d043ba7f13211d5c3e41961c3381fb12880 ]
It is unexpected that the reset work is running simultaneously with the suspend or resume context and it is possible that reset work is still running even after mt7921 is suspended if we don't fix the race issue.
Thus, the suspend procedure should be waiting until the reset is completed at the beginning and ignore the subsequent the reset requests.
In case there is an error that happens during either suspend or resume handler, we will schedule a reset task to recover the error before returning the error code to ensure we can immediately fix the error there.
--- .../net/wireless/mediatek/mt76/mt7921/usb.c | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7921/usb.c +24 -4
@@ -300,11 +300,15 @@ static void mt7921u_disconnect(struct usb_interface *usb_intf)static int mt7921u_suspend (struct usb_interface *intf,pm_message_t state) {struct mt7921_dev *dev =usb_get_intfdata (intf); +struct mt76_connac_pm *pm = &dev->pm;int err; + pm->suspended = true; +flush_work (&dev->reset_work); + err =mt76_connac_mcu_set_hif_suspend (&dev->mt76, true);if (err) -return err; + goto failed;mt76u_stop_rx (&dev->mt76);mt76u_stop_tx (&dev->mt76);
@@ -312,11 +316,20 @@ static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state)set_bit (MT76_STATE_SUSPEND , &dev->mphy.state);return 0 ; + +failed: + pm->suspended = false; + +if (err <0 ) +mt7921_reset (&dev->mt76); + +return err; }static int mt7921u_resume (struct usb_interface *intf) {struct mt7921_dev *dev =usb_get_intfdata (intf); +struct mt76_connac_pm *pm = &dev->pm;bool reinit = true;int err, i;
@@ -338,16 +351,23 @@ static int mt7921u_resume(struct usb_interface *intf)if (reinit ||mt7921_dma_need_reinit (dev)) { err =mt7921u_dma_init (dev, true);if (err) -return err; + goto failed; }clear_bit (MT76_STATE_SUSPEND , &dev->mphy.state); err =mt76u_resume_rx (&dev->mt76);if (err <0 ) -return err; + goto failed; + + err =mt76_connac_mcu_set_hif_suspend (&dev->mt76, false); +failed: + pm->suspended = false; + +if (err <0 ) +mt7921_reset (&dev->mt76); - return mt76_connac_mcu_set_hif_suspend(&dev->mt76, false); + return err; }#endif /* CONFIG_PM */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 278/862 wifi: mt76: sdio: fix the deadlock caused by sdio->stat_work
In reply to Greg Kroah-HartmanFrom: Sean Wang <[email protected]>
[ Upstream commit e5d78fd998be94fb459a3d625df7367849b997b8 ]
Because wake_work and sdio->stat_work share the same workqueue mt76->wq, if sdio->stat_work cannot acquire the mutex lock such as that was possibly held up by [mt7615, mt7921]_mutex_acquire. Additionally, if [mt7615, mt7921]_mutex_acquire was called by sdio->stat_work self, the wake would be blocked by itself. Thus, we move the stat_work into ieee80211_workqueue instead to break the deadlock.
--- drivers/net/wireless/mediatek/mt76/sdio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/mediatek/mt76/sdio.c +2 -2
@@ -481,7 +481,7 @@ static void mt76s_status_worker(struct mt76_worker *w)if (dev->drv->tx_status_data && !test_and_set_bit (MT76_READING_STATS , &dev->phy.state) && !test_bit (MT76_STATE_SUSPEND , &dev->phy.state)) -queue_work (dev->wq, &dev->sdio.stat_work); +ieee80211_queue_work (dev->hw, &dev->sdio.stat_work); }while (nframes >0 );if (resched)
@@ -508,7 +508,7 @@ static void mt76s_tx_status_data(struct work_struct *work) }if (count &&test_bit (MT76_STATE_RUNNING , &dev->phy.state)) -queue_work (dev->wq, &sdio->stat_work); +ieee80211_queue_work (dev->hw, &sdio->stat_work);else clear_bit (MT76_READING_STATS , &dev->phy.state); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 279/862 wifi: mt76: sdio: poll sta stat when device transmits data
In reply to Greg Kroah-HartmanFrom: Sean Wang <[email protected]>
[ Upstream commit a323e5f041dd11af5e3de19ed7ea95a97d588c11 ]
It is not meaningful to poll sta stat when there is no data traffic. So polling sta stat when the device has transmitted data instead to save CPU power.
That implies that it is unallowed the stat_work to work while MCU is being initialized in the really early stage to fix the possible time to time MCU initialization failure.
--- drivers/net/wireless/mediatek/mt76/sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/sdio.c +1 -1
@@ -478,7 +478,7 @@ static void mt76s_status_worker(struct mt76_worker *w)if (ndata_frames >0 ) resched = true; -if (dev->drv->tx_status_data && +if (dev->drv->tx_status_data && ndata_frames >0 && !test_and_set_bit (MT76_READING_STATS , &dev->phy.state) && !test_bit (MT76_STATE_SUSPEND , &dev->phy.state))ieee80211_queue_work (dev->hw, &dev->sdio.stat_work);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 280/862 wifi: mt76: mt7915: fix an uninitialized variable bug
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit b5ee771c84082b4e54cc39d9d9a2dd239e4f6b86 ]
Smatch complains that:
drivers/net/wireless/mediatek/mt76/mt7915/mac.c:428 mt7915_mac_fill_rx()
error: uninitialized symbol 'msta'.
It looks like this was supposed to be initialized to NULL.
--- drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +1 -1
@@ -232,7 +232,7 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)bool unicast, insert_ccmp_hdr = false;u8 remove_pad, amsdu_info;u8 mode =0 , qos_ctl =0 ; -struct mt7915_sta *msta; +struct mt7915_sta *msta =NULL ;bool hdr_trans;u16 hdr_gap;u16 seq_ctrl =0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 281/862 wifi: mt76: mt7921: fix use after free in mt7921_acpi_read()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit e7de4b4979bd8d313ec837931dde936653ca82ea ]
Don't dereference "sar_root" after it has been freed.
--- drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c +4 -1
@@ -13,6 +13,7 @@ mt7921_acpi_read(struct mt7921_dev *dev, u8 *method, u8 **tbl, u32 *len)acpi_handle root, handle;acpi_status status;u32 i =0 ; +int ret; root =ACPI_HANDLE (mdev->dev);if (!root)
@@ -52,9 +53,11 @@ mt7921_acpi_read(struct mt7921_dev *dev, u8 *method, u8 **tbl, u32 *len) *(*tbl + i) = (u8 )sar_unit->integer.value; } free: + ret = (i == sar_root->package.count) ?0 : -EINVAL ; +kfree (sar_root); -return (i == sar_root->package.count) ?0 : -EINVAL ; +return ret; }/* MTCL : Country List Table for 6G band */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 282/862 wifi: mt76: sdio: fix transmitting packet hangs
In reply to Greg Kroah-HartmanFrom: YN Chen <[email protected]>
[ Upstream commit 250b1827205846ff346a76044955cb79d4963f70 ]
Fix transmitting packets hangs with continuing to pull the pending packet from mac80211 queues when receiving Tx status notification from the device.
--- drivers/net/wireless/mediatek/mt76/sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/sdio.c +1 -1
@@ -485,7 +485,7 @@ static void mt76s_status_worker(struct mt76_worker *w) }while (nframes >0 );if (resched) -mt76_worker_schedule (&dev->sdio.txrx_worker); +mt76_worker_schedule (&dev->tx_worker); }static void mt76s_tx_status_data (struct work_struct *work)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 283/862 wifi: mt76: mt7615: add mt7615_mutex_acquire/release in mt7615_sta_set_decap_offload
In reply to Greg Kroah-HartmanFrom: Lorenzo Bianconi <[email protected]>
[ Upstream commit 765c69d477a44c088e5d19e7758dfa4db418e3ba ]
Similar to mt7921 driver, introduce mt7615_mutex_acquire/release in mt7615_sta_set_decap_offload in order to avoid sending mcu commands while the device is in low-power state.
--- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7615/main.c +4 -0
@@ -1195,12 +1195,16 @@ static void mt7615_sta_set_decap_offload(struct ieee80211_hw *hw,struct mt7615_dev *dev =mt7615_hw_dev (hw);struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv; +mt7615_mutex_acquire (dev); +if (enabled)set_bit (MT_WCID_FLAG_HDR_TRANS , &msta->wcid.flags);else clear_bit (MT_WCID_FLAG_HDR_TRANS , &msta->wcid.flags);mt7615_mcu_set_sta_decap_offload (dev, vif, sta); + +mt7615_mutex_release (dev); }#ifdef CONFIG_PM
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 284/862 wifi: mt76: mt7915: fix possible unaligned access in mt7915_mac_add_twt_setup
In reply to Greg Kroah-HartmanFrom: Lorenzo Bianconi <[email protected]>
[ Upstream commit 3d9aa54355d863e5412a7e08180f50a8f1827b7f ]
Fix possible unaligned pointer in mt7915_mac_add_twt_setup routine.
--- drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +6 -4
@@ -2071,8 +2071,9 @@ void mt7915_mac_add_twt_setup(struct ieee80211_hw *hw, } flowid =ffs (~msta->twt.flowid_mask) -1 ; -le16p_replace_bits (&twt_agrt->req_type, flowid, -IEEE80211_TWT_REQTYPE_FLOWID ); + twt_agrt->req_type &= ~cpu_to_le16 (IEEE80211_TWT_REQTYPE_FLOWID ); + twt_agrt->req_type |=le16_encode_bits (flowid, +IEEE80211_TWT_REQTYPE_FLOWID ); table_id =ffs (~dev->twt.table_mask) -1 ; exp =FIELD_GET (IEEE80211_TWT_REQTYPE_WAKE_INT_EXP , req_type);
@@ -2122,8 +2123,9 @@ void mt7915_mac_add_twt_setup(struct ieee80211_hw *hw, unlock:mutex_unlock (&dev->mt76.mutex); out: -le16p_replace_bits (&twt_agrt->req_type, setup_cmd, -IEEE80211_TWT_REQTYPE_SETUP_CMD ); + twt_agrt->req_type &= ~cpu_to_le16 (IEEE80211_TWT_REQTYPE_SETUP_CMD ); + twt_agrt->req_type |= +le16_encode_bits (setup_cmd,IEEE80211_TWT_REQTYPE_SETUP_CMD ); twt->control = (twt->control &IEEE80211_TWT_CONTROL_WAKE_DUR_UNIT ) | (twt->control &IEEE80211_TWT_CONTROL_RX_DISABLED ); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 285/862 wifi: mt76: connac: fix possible unaligned access in mt76_connac_mcu_add_nested_tlv
In reply to Greg Kroah-HartmanFrom: Lorenzo Bianconi <[email protected]>
[ Upstream commit 0a4860f627f1f2b2b777f54f993de1638a79da9f ]
Fix possible unaligned pointer in mt76_connac_mcu_add_nested_tlv routine.
--- drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +4 -2
@@ -260,8 +260,10 @@ mt76_connac_mcu_add_nested_tlv(struct sk_buff *skb, int tag, int len, ntlv =le16_to_cpu (ntlv_hdr->tlv_num); ntlv_hdr->tlv_num =cpu_to_le16 (ntlv +1 ); -if (sta_hdr) -le16_add_cpu (&sta_hdr->len, len); +if (sta_hdr) { + len +=le16_to_cpu (sta_hdr->len); + sta_hdr->len =cpu_to_le16 (len); + }return ptlv; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 286/862 wifi: mt76: mt7921: add mt7921_mutex_acquire at mt7921_[start, stop]_ap
In reply to Greg Kroah-HartmanFrom: Sean Wang <[email protected]>
[ Upstream commit 52b44015f031f629f1ce1d73415a2017593c7ade ]
Add mt7921_mutex_acquire at mt7921_[start, stop]_ap to fix the race with the context holding dev->muxtex and the driver might access the device in low power state.
--- .../net/wireless/mediatek/mt76/mt7921/main.c | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7921/main.c +16 -5
@@ -1526,17 +1526,23 @@ mt7921_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,struct mt7921_dev *dev =mt7921_hw_dev (hw);int err; +mt7921_mutex_acquire (dev); + err =mt76_connac_mcu_uni_add_bss (phy->mt76, vif, &mvif->sta.wcid, true);if (err) -return err; + goto out; err =mt7921_mcu_set_bss_pm (dev, vif, true);if (err) -return err; + goto out; + + err =mt7921_mcu_sta_update (dev,NULL , vif, true, +MT76_STA_INFO_STATE_NONE ); +out: +mt7921_mutex_release (dev); -return mt7921_mcu_sta_update (dev,NULL , vif, true, -MT76_STA_INFO_STATE_NONE ); +return err; } static void
@@ -1548,11 +1554,16 @@ mt7921_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,struct mt7921_dev *dev =mt7921_hw_dev (hw);int err; +mt7921_mutex_acquire (dev); + err =mt7921_mcu_set_bss_pm (dev, vif, false);if (err) -return ; + goto out;mt76_connac_mcu_uni_add_bss (phy->mt76, vif, &mvif->sta.wcid, false); + +out: +mt7921_mutex_release (dev); }const struct ieee80211_ops mt7921_ops = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 287/862 wifi: mt76: mt7921: add mt7921_mutex_acquire at mt7921_sta_set_decap_offload
In reply to Greg Kroah-HartmanFrom: Sean Wang <[email protected]>
[ Upstream commit 59c20b91786d5f140ee7be2f24c242b5f8986046 ]
Add mt7921_mutex_acquire at mt7921_[start, stop]_ap to fix the race with the context holding dev->muxtex and the driver might access the device in low power state.
--- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7921/main.c +4 -0
@@ -1404,6 +1404,8 @@ static void mt7921_sta_set_decap_offload(struct ieee80211_hw *hw,struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv;struct mt7921_dev *dev =mt7921_hw_dev (hw); +mt7921_mutex_acquire (dev); +if (enabled)set_bit (MT_WCID_FLAG_HDR_TRANS , &msta->wcid.flags);else
@@ -1411,6 +1413,8 @@ static void mt7921_sta_set_decap_offload(struct ieee80211_hw *hw,mt76_connac_mcu_sta_update_hdr_trans (&dev->mt76, vif, &msta->wcid,MCU_UNI_CMD (STA_REC_UPDATE )); + +mt7921_mutex_release (dev); }#if IS_ENABLED (CONFIG_IPV6 )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 288/862 wifi: mt76: mt7921: fix the firmware version report
In reply to Greg Kroah-HartmanFrom: Sean Wang <[email protected]>
[ Upstream commit 00be84d6dfc8319ed1864d3ca8658569d36a1882 ]
Fix the regression of the firmware version report since 'b9ec27102ac0 ('mt76: connac: move mt76_connac2_load_ram in connac module')'.
--- drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +4 -0
@@ -2888,6 +2888,10 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm, goto out; } +snprintf (dev->hw->wiphy->fw_version, +sizeof (dev->hw->wiphy->fw_version), +"%.10s-%.15s" , hdr->fw_ver, hdr->build_date); +release_firmware (fw);if (!fw_wa)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 289/862 wifi: mt76: mt7915: fix mcs value in ht mode
In reply to Greg Kroah-HartmanFrom: Howard Hsu <[email protected]>
[ Upstream commit c6d3e16ad4362502e804a6ca01e955612f3b8222 ]
Fix the error that mcs will be reduced to a range of 0 to 7 in ht mode.
--- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +6 -4
@@ -1360,7 +1360,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,struct sta_phy phy = {};int ret, nrates =0 ; -#define __sta_phy_bitrate_mask_check (_mcs, _gi, _he) \ +#define __sta_phy_bitrate_mask_check (_mcs, _gi, _ht, _he) \ do { \ u8 i, gi = mask->control[band]._gi; \ gi = (_he) ? gi : gi == NL80211_TXRATE_FORCE_SGI; \
@@ -1373,15 +1373,17 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,continue ; \ nrates +=hweight16 (mask->control[band]._mcs[i]); \ phy.mcs =ffs (mask->control[band]._mcs[i]) -1 ; \ +if (_ht) \ + phy.mcs +=8 * i; \ } \ }while (0 )if (sta->deflink.he_cap.has_he) { -__sta_phy_bitrate_mask_check (he_mcs, he_gi,1 ); +__sta_phy_bitrate_mask_check (he_mcs, he_gi,0 ,1 ); }else if (sta->deflink.vht_cap.vht_supported) { -__sta_phy_bitrate_mask_check (vht_mcs, gi,0 ); +__sta_phy_bitrate_mask_check (vht_mcs, gi,0 ,0 ); }else if (sta->deflink.ht_cap.ht_supported) { -__sta_phy_bitrate_mask_check (ht_mcs, gi,0 ); +__sta_phy_bitrate_mask_check (ht_mcs, gi,1 ,0 ); }else { nrates =hweight32 (mask->control[band].legacy); phy.mcs =ffs (mask->control[band].legacy) -1 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 290/862 wifi: mt76: fix uninitialized pointer in mt7921_mac_fill_rx
In reply to Greg Kroah-HartmanFrom: Lorenzo Bianconi <[email protected]>
[ Upstream commit 9be57ad73984545d594ed359dac19457bcb9fc27 ]
Initialize msta pointer to NULL in mt7921_mac_fill_rx() in order to not dereference a uninitialized pointer.
--- drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7921/mac.c +1 -1
@@ -235,7 +235,7 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)u32 rxd2 =le32_to_cpu (rxd[2 ]);u32 rxd3 =le32_to_cpu (rxd[3 ]);u32 rxd4 =le32_to_cpu (rxd[4 ]); -struct mt7921_sta *msta; +struct mt7921_sta *msta =NULL ;u16 seq_ctrl =0 ;__le16 fc =0 ;u8 mode =0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 291/862 wifi: mt76: mt7915: do not check state before configuring implicit beamform
In reply to Greg Kroah-HartmanFrom: Howard Hsu <[email protected]>
[ Upstream commit d2b5bb6dfab29fe32bedefaade88dcd182c03a00 ]
Do not need to check running state before configuring implicit Tx beamform. It is okay to configure implicit Tx beamform in run time. Noted that the existing connected stations will be applied for new configuration only if they reconnected to the interface.
--- drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +3 -3
@@ -23,9 +23,9 @@ mt7915_implicit_txbf_set(void *data, u64 val) {struct mt7915_dev *dev = data; -if (test_bit (MT76_STATE_RUNNING , &dev->mphy.state)) -return -EBUSY ; - +/* The existing connected stations shall reconnect to apply +* new implicit txbf configuration. +*/ dev->ibf = !!val;return mt7915_mcu_set_txbf (dev,MT_BF_TYPE_UPDATE );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 292/862 wifi: mt76: mt7921e: fix rmmod crash in driver reload test
In reply to Greg Kroah-HartmanFrom: Deren Wu <[email protected]>
[ Upstream commit b5a62d612b7baf6e09884e4de94decb6391d6a9d ]
In insmod/rmmod stress test, the following crash dump shows up immediately. The problem is caused by missing mt76_dev in mt7921_pci_remove(). We should make sure the drvdata is ready before probe() finished.
[168.862789] ================================================================== [168.862797] BUG: KASAN: user-memory-access in try_to_grab_pending+0x59/0x480 [168.862805] Write of size 8 at addr 0000000000006df0 by task rmmod/5361 [168.862812] CPU: 7 PID: 5361 Comm: rmmod Tainted: G OE 5.19.0-rc6 #1 [168.862816] Hardware name: Intel(R) Client Systems NUC8i7BEH/NUC8BEB, 05/04/2020 [168.862820] Call Trace: [168.862822] <TASK> [168.862825] dump_stack_lvl+0x49/0x63 [168.862832] print_report.cold+0x493/0x6b7 [168.862845] kasan_report+0xa7/0x120 [168.862857] kasan_check_range+0x163/0x200 [168.862861] __kasan_check_write+0x14/0x20 [168.862866] try_to_grab_pending+0x59/0x480 [168.862870] __cancel_work_timer+0xbb/0x340 [168.862898] cancel_work_sync+0x10/0x20 [168.862902] mt7921_pci_remove+0x61/0x1c0 [mt7921e] [168.862909] pci_device_remove+0xa3/0x1d0 [168.862914] device_remove+0xc4/0x170 [168.862920] device_release_driver_internal+0x163/0x300 [168.862925] driver_detach+0xc7/0x1a0 [168.862930] bus_remove_driver+0xeb/0x2d0 [168.862935] driver_unregister+0x71/0xb0 [168.862939] pci_unregister_driver+0x30/0x230 [168.862944] mt7921_pci_driver_exit+0x10/0x1b [mt7921e] [168.862949] __x64_sys_delete_module+0x2f9/0x4b0 [168.862968] do_syscall_64+0x38/0x90 [168.862973] entry_SYSCALL_64_after_hwframe+0x63/0xcd
Test steps:
1. insmode
2. do not ifup
3. rmmod quickly (within 1 second)
--- drivers/net/wireless/mediatek/mt76/mt7921/pci.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7921/pci.c +2 -0
@@ -288,6 +288,8 @@ static int mt7921_pci_probe(struct pci_dev *pdev, goto err_free_pci_vec; } +pci_set_drvdata (pdev, mdev); + dev = container_of(mdev, struct mt7921_dev, mt76); dev->hif_ops = &mt7921_pcie_ops;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 293/862 Bluetooth: RFCOMM: Fix possible deadlock on socket shutdown/release
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 812e92b824c1db16c9519f8624d48a9901a0d38f ]
Due to change to switch to use lock_sock inside rfcomm_sk_state_change the socket shutdown/release procedure can cause a deadlock:
rfcomm_sock_shutdown():
lock_sock();
__rfcomm_sock_close():
rfcomm_dlc_close():
__rfcomm_dlc_close():
rfcomm_dlc_lock();
rfcomm_sk_state_change():
lock_sock();To fix this when the call __rfcomm_sock_close is now done without holding the lock_sock since rfcomm_dlc_lock exists to protect the dlc data there is no need to use lock_sock in that code path.
--- net/bluetooth/rfcomm/sock.c | 3 +++ 1 file changed, 3 insertions(+)
net/bluetooth/rfcomm/sock.c +3 -0
@@ -902,7 +902,10 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how)lock_sock (sk);if (!sk->sk_shutdown) { sk->sk_shutdown =SHUTDOWN_MASK ; + +release_sock (sk);__rfcomm_sock_close (sk); +lock_sock (sk);if (sock_flag (sk,SOCK_LINGER ) && sk->sk_lingertime && !(current->flags &PF_EXITING ))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 294/862 net: fs_enet: Fix wrong check in do_pd_setup
In reply to Greg Kroah-HartmanFrom: Zheng Yongjun <[email protected]>
[ Upstream commit ec3f06b542a960806a81345042e4eee3f8c5dec4 ]
Should check of_iomap return value 'fep->fec.fecp' instead of 'fep->fcc.fccp'
--- drivers/net/ethernet/freescale/fs_enet/mac-fec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/freescale/fs_enet/mac-fec.c +1 -1
@@ -98,7 +98,7 @@ static int do_pd_setup(struct fs_enet_private *fep)return -EINVAL ; fep->fec.fecp =of_iomap (ofdev->dev.of_node,0 ); -if (!fep->fcc.fccp) +if (!fep->fec.fecp)return -EINVAL ;return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 295/862 bpf: Ensure correct locking around vulnerable function find_vpid()
In reply to Greg Kroah-HartmanFrom: Lee Jones <[email protected]>
[ Upstream commit 83c10cc362d91c0d8d25e60779ee52fdbbf3894d ]
The documentation for find_vpid() clearly states:
"Must be called with the tasklist_lock or rcu_read_lock() held."
Presently we do neither for find_vpid() instance in bpf_task_fd_query(). Add proper rcu_read_lock/unlock() to fix the issue.
--- kernel/bpf/syscall.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/bpf/syscall.c +2 -0
@@ -4395,7 +4395,9 @@ static int bpf_task_fd_query(const union bpf_attr *attr,if (attr->task_fd_query.flags !=0 )return -EINVAL ; +rcu_read_lock (); task =get_pid_task (find_vpid (pid),PIDTYPE_PID ); +rcu_read_unlock ();if (!task)return -ENOENT ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 296/862 libbpf: Fix crash if SEC("freplace") programs dont have attach_prog_fd set
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit 749c202cb6ea40f4d7ac95c4a1217a7b506f43a8 ]
Fix SIGSEGV caused by libbpf trying to find attach type in vmlinux BTF for freplace programs. It's wrong to search in vmlinux BTF and libbpf doesn't even mark vmlinux BTF as required for freplace programs. So trying to search anything in obj->vmlinux_btf might cause NULL dereference if nothing else in BPF object requires vmlinux BTF.
Instead, error out if freplace (EXT) program doesn't specify attach_prog_fd during at the load time.
--- tools/lib/bpf/libbpf.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
tools/lib/bpf/libbpf.c +9 -4
@@ -9056,11 +9056,15 @@ static int libbpf_find_attach_btf_id(strint err =0 ;/* BPF program's BTF ID */ -if (attach_prog_fd) { +if (prog->type ==BPF_PROG_TYPE_EXT || attach_prog_fd) { +if (!attach_prog_fd) { +pr_warn ("prog '%s': attach program FD is not set\n" , prog->name); +return -EINVAL ; + } err =libbpf_find_prog_btf_id (attach_name, attach_prog_fd);if (err <0 ) { -pr_warn ("failed to find BPF program (FD %d) BTF ID for '%s': %d\n" , - attach_prog_fd, attach_name, err); +pr_warn ("prog '%s': failed to find BPF program (FD %d) BTF ID for '%s': %d\n" , + prog->name, attach_prog_fd, attach_name, err);return err; } *btf_obj_fd =0 ;
@@ -9077,7 +9081,8 @@ static int libbpf_find_attach_btf_id(str err =find_kernel_btf_id (prog->obj, attach_name, attach_type, btf_obj_fd, btf_type_id); }if (err) { -pr_warn ("failed to find kernel BTF type ID of '%s': %d\n" , attach_name, err); +pr_warn ("prog '%s': failed to find kernel BTF type ID of '%s': %d\n" , + prog->name, attach_name, err);return err; }return 0 ;
Greg Kroah-Hartman
maintainerPATCH 297/862 wifi: ath11k: Include STA_KEEPALIVE_ARP_RESPONSE TLV header by default
In reply to Greg Kroah-HartmanFrom: Baochen Qiang <[email protected]>
[ Upstream commit b7b6f86149a7e06269d61a7a5206360f5b642f80 ]
In current code STA_KEEPALIVE_ARP_RESPONSE TLV header is included only when ARP method is used, this causes firmware always to crash when wowlan is enabled because firmware needs it to be present no matter ARP method is used or not.
Fix this issue by including STA_KEEPALIVE_ARP_RESPONSE TLV header by default.
Also fix below typo:
s/WMI_TAG_STA_KEEPALVE_ARP_RESPONSE/WMI_TAG_STA_KEEPALIVE_ARP_RESPONSE/
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
--- drivers/net/wireless/ath/ath11k/wmi.c | 9 +++++---- drivers/net/wireless/ath/ath11k/wmi.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-)
drivers/net/wireless/ath/ath11k/wmi.c +5 -4
@@ -8962,12 +8962,13 @@ int ath11k_wmi_sta_keepalive(struct ath11k *ar, cmd->interval = arg->interval; cmd->method = arg->method; + arp = (struct wmi_sta_keepalive_arp_resp *)(cmd +1 ); + arp->tlv_header =FIELD_PREP (WMI_TLV_TAG , +WMI_TAG_STA_KEEPALIVE_ARP_RESPONSE ) | +FIELD_PREP (WMI_TLV_LEN ,sizeof (*arp) -TLV_HDR_SIZE ); +if (arg->method ==WMI_STA_KEEPALIVE_METHOD_UNSOLICITED_ARP_RESPONSE || arg->method ==WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST ) { - arp = (struct wmi_sta_keepalive_arp_resp *)(cmd +1 ); - arp->tlv_header =FIELD_PREP (WMI_TLV_TAG , -WMI_TAG_STA_KEEPALVE_ARP_RESPONSE ) | -FIELD_PREP (WMI_TLV_LEN ,sizeof (*arp) -TLV_HDR_SIZE ); arp->src_ip4_addr = arg->src_ip4_addr; arp->dest_ip4_addr = arg->dest_ip4_addr;ether_addr_copy (arp->dest_mac_addr.addr, arg->dest_mac_addr);
drivers/net/wireless/ath/ath11k/wmi.h +1 -1
@@ -1214,7 +1214,7 @@ enum wmi_tlv_tag {WMI_TAG_NS_OFFLOAD_TUPLE ,WMI_TAG_FTM_INTG_CMD ,WMI_TAG_STA_KEEPALIVE_CMD , -WMI_TAG_STA_KEEPALVE_ARP_RESPONSE , +WMI_TAG_STA_KEEPALIVE_ARP_RESPONSE ,WMI_TAG_P2P_SET_VENDOR_IE_DATA_CMD ,WMI_TAG_AP_PS_PEER_CMD , WMI_TAG_PEER_RATE_RETRY_SCHED_CMD,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 298/862 Bluetooth: hci_{ldisc,serdev}: check percpu_init_rwsem() failure
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
[ Upstream commit 3124d320c22f3f4388d9ac5c8f37eaad0cefd6b1 ]
syzbot is reporting NULL pointer dereference at hci_uart_tty_close() [1], for rcu_sync_enter() is called without rcu_sync_init() due to hci_uart_tty_open() ignoring percpu_init_rwsem() failure.
While we are at it, fix that hci_uart_register_device() ignores percpu_init_rwsem() failure and hci_uart_unregister_device() does not call percpu_free_rwsem().
--- drivers/bluetooth/hci_ldisc.c | 7 +++++-- drivers/bluetooth/hci_serdev.c | 10 +++++++--- 2 files changed, 12 insertions(+), 5 deletions(-)
drivers/bluetooth/hci_ldisc.c +5 -2
@@ -493,6 +493,11 @@ static int hci_uart_tty_open(struct tty_struct *tty)BT_ERR ("Can't allocate control structure" );return -ENFILE ; } +if (percpu_init_rwsem (&hu->proto_lock)) { +BT_ERR ("Can't allocate semaphore structure" ); +kfree (hu); +return -ENOMEM ; + } tty->disc_data = hu; hu->tty = tty;
@@ -505,8 +510,6 @@ static int hci_uart_tty_open(struct tty_struct *tty)INIT_WORK (&hu->init_ready, hci_uart_init_work);INIT_WORK (&hu->write_work, hci_uart_write_work); -percpu_init_rwsem (&hu->proto_lock); -/* Flush any pending characters in the driver */ tty_driver_flush_buffer (tty);
drivers/bluetooth/hci_serdev.c +7 -3
@@ -310,11 +310,12 @@ int hci_uart_register_device(struct hci_uart *hu,serdev_device_set_client_ops (hu->serdev, &hci_serdev_client_ops); +if (percpu_init_rwsem (&hu->proto_lock)) +return -ENOMEM ; + err =serdev_device_open (hu->serdev);if (err) -return err; - -percpu_init_rwsem (&hu->proto_lock); + goto err_rwsem; err = p->open (hu);if (err)
@@ -389,6 +390,8 @@ int hci_uart_register_device(struct hci_uart *hu, p->close (hu); err_open:serdev_device_close (hu->serdev); +err_rwsem: +percpu_free_rwsem (&hu->proto_lock);return err; }EXPORT_SYMBOL_GPL (hci_uart_register_device);
@@ -410,5 +413,6 @@ void hci_uart_unregister_device(struct hci_uart *hu)clear_bit (HCI_UART_PROTO_READY , &hu->flags);serdev_device_close (hu->serdev); } +percpu_free_rwsem (&hu->proto_lock); }EXPORT_SYMBOL_GPL (hci_uart_unregister_device);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 299/862 libbpf: Fix NULL pointer exception in API btf_dump__dump_type_data
In reply to Greg Kroah-HartmanFrom: Xin Liu <[email protected]>
[ Upstream commit 7620bffbf72cd66a5d18e444a143b5b5989efa87 ]
We found that function btf_dump__dump_type_data can be called by the user as an API, but in this function, the opts parameter may be used as a null pointer.This causes opts->indent_str to trigger a NULL pointer exception.
--- tools/lib/bpf/btf_dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/lib/bpf/btf_dump.c +1 -1
@@ -2385,7 +2385,7 @@ int btf_dump__dump_type_data(struct btf_dump *d, __u32 id, d->typed_dump->indent_lvl =OPTS_GET (opts, indent_level,0 );/* default indent string is a tab */ -if (!opts->indent_str) +if (!OPTS_GET (opts, indent_str,NULL )) d->typed_dump->indent_str[0 ] ='\t' ;else libbpf_strlcpy(d->typed_dump->indent_str, opts->indent_str,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 300/862 netfilter: conntrack: fix the gc rescheduling delay
In reply to Greg Kroah-HartmanFrom: Antoine Tenart <[email protected]>
[ Upstream commit 95eabdd207024312876d0ebed90b4c977e050e85 ]
Commit 2cfadb761d3d ("netfilter: conntrack: revisit gc autotuning") changed the eviction rescheduling to the use average expiry of scanned entries (within 1-60s) by doing:
for (...) {
expires = clamp(nf_ct_expires(tmp), ...);
next_run += expires;
next_run /= 2;
}The issue is the above will make the average ('next_run' here) more dependent on the last expiration values than the firsts (for sets > 2). Depending on the expiration values used to compute the average, the result can be quite different than what's expected. To fix this we can do the following:
for (...) {
expires = clamp(nf_ct_expires(tmp), ...);
next_run += (expires - next_run) / ++count;
}--- net/netfilter/nf_conntrack_core.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
net/netfilter/nf_conntrack_core.c +8 -2
@@ -67,6 +67,7 @@ struct conntrack_gc_work {struct delayed_work dwork;u32 next_bucket;u32 avg_timeout; +u32 count;u32 start_time;bool exiting;bool early_drop;
@@ -1466,6 +1467,7 @@ static void gc_worker(struct work_struct *work)unsigned int expired_count =0 ;unsigned long next_run;s32 delta_time; +long count; gc_work = container_of(work, struct conntrack_gc_work, dwork.work);
@@ -1475,10 +1477,12 @@ static void gc_worker(struct work_struct *work)if (i ==0 ) { gc_work->avg_timeout =GC_SCAN_INTERVAL_INIT ; + gc_work->count =1 ; gc_work->start_time = start_time; } next_run = gc_work->avg_timeout; + count = gc_work->count; end_time = start_time +GC_SCAN_MAX_DURATION ;
@@ -1498,8 +1502,8 @@ static void gc_worker(struct work_struct *work)hlist_nulls_for_each_entry_rcu (h, n, &ct_hash[i], hnnode) {struct nf_conntrack_net *cnet; -unsigned long expires;struct net *net; +long expires; tmp =nf_ct_tuplehash_to_ctrack (h);
@@ -1513,6 +1517,7 @@ static void gc_worker(struct work_struct *work) gc_work->next_bucket = i; gc_work->avg_timeout = next_run; + gc_work->count = count; delta_time = nfct_time_stamp - gc_work->start_time;
@@ -1528,8 +1533,8 @@ static void gc_worker(struct work_struct *work) } expires =clamp (nf_ct_expires (tmp),GC_SCAN_INTERVAL_MIN ,GC_SCAN_INTERVAL_CLAMP ); + expires = (expires - (long )next_run) / ++count; next_run += expires; - next_run /=2u ;if (nf_conntrack_max95 ==0 ||gc_worker_skip_ct (tmp))continue ;
@@ -1570,6 +1575,7 @@ static void gc_worker(struct work_struct *work) delta_time = nfct_time_stamp - end_time;if (delta_time >0 && i < hashsz) { gc_work->avg_timeout = next_run; + gc_work->count = count; gc_work->next_bucket = i; next_run =0 ; goto early_exit;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 301/862 netfilter: conntrack: revisit the gc initial rescheduling bias
In reply to Greg Kroah-HartmanFrom: Antoine Tenart <[email protected]>
[ Upstream commit 2aa192757005f130b2dd3547dda6e462e761199f ]
The previous commit changed the way the rescheduling delay is computed which has a side effect: the bias is now represented as much as the other entries in the rescheduling delay which makes the logic to kick in only with very large sets, as the initial interval is very large (INT_MAX).
Revisit the GC initial bias to allow more frequent GC for smaller sets while still avoiding wakeups when a machine is mostly idle. We're moving from a large initial value to pretending we have 100 entries expiring at the upper bound. This way only a few entries having a small timeout won't impact much the rescheduling delay and non-idle machines will have enough entries to lower the delay when needed. This also improves readability as the initial bias is now linked to what is computed instead of being an arbitrary large value.
--- net/netfilter/nf_conntrack_core.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
net/netfilter/nf_conntrack_core.c +6 -4
@@ -86,10 +86,12 @@ static DEFINE_MUTEX(nf_conntrack_mutex);/* clamp timeouts to this value (TCP unacked) */ #define GC_SCAN_INTERVAL_CLAMP (300ul * HZ) -/* large initial bias so that we don't scan often just because we have -* three entries with a 1s timeout. +/* Initial bias pretending we have 100 entries at the upper bound so we don't +* wakeup often just because we have three entries with a 1s timeout while still +* allowing non-idle machines to wakeup more often when needed. */ -#define GC_SCAN_INTERVAL_INIT INT_MAX +#define GC_SCAN_INITIAL_COUNT 100 +#define GC_SCAN_INTERVAL_INIT GC_SCAN_INTERVAL_MAX#define GC_SCAN_MAX_DURATION msecs_to_jiffies(10)#define GC_SCAN_EXPIRED_MAX (64000u / HZ)
@@ -1477,7 +1479,7 @@ static void gc_worker(struct work_struct *work)if (i ==0 ) { gc_work->avg_timeout =GC_SCAN_INTERVAL_INIT ; - gc_work->count =1 ; + gc_work->count =GC_SCAN_INITIAL_COUNT ; gc_work->start_time = start_time; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 302/862 bpf, cgroup: Reject prog_attach_flags array when effective query
In reply to Greg Kroah-HartmanFrom: Pu Lehui <[email protected]>
[ Upstream commit 0e426a3ae030a9e891899370229e117158b35de6 ]
Attach flags is only valid for attached progs of this layer cgroup, but not for effective progs. For querying with EFFECTIVE flags, exporting attach flags does not make sense. So when effective query, we reject prog_attach_flags array and don't need to populate it. Also we limit attach_flags to output 0 during effective query.
--- include/uapi/linux/bpf.h | 7 +++++-- kernel/bpf/cgroup.c | 28 ++++++++++++++++++---------- tools/include/uapi/linux/bpf.h | 7 +++++-- 3 files changed, 28 insertions(+), 14 deletions(-)
include/uapi/linux/bpf.h +5 -2
@@ -1233,7 +1233,7 @@ enum {/* Query effective (directly attached + inherited from ancestor cgroups) * programs that will be executed for events within a cgroup. -* attach_flags with this flag are returned only for directly attached programs. +* attach_flags with this flag are always returned 0. */ #define BPF_F_QUERY_EFFECTIVE (1U << 0)
@@ -1432,7 +1432,10 @@ union bpf_attr {__u32 attach_flags;__aligned_u64 prog_ids;__u32 prog_cnt; -__aligned_u64 prog_attach_flags;/* output: per-program attach_flags */ +/* output: per-program attach_flags. +* not allowed to be set during effective query. +*/ +__aligned_u64 prog_attach_flags; } query;struct {/* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */
kernel/bpf/cgroup.c +18 -10
@@ -1020,6 +1020,7 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, union bpf_attr __user *uattr) {__u32 __user *prog_attach_flags =u64_to_user_ptr (attr->query.prog_attach_flags); +bool effective_query = attr->query.query_flags &BPF_F_QUERY_EFFECTIVE ;__u32 __user *prog_ids =u64_to_user_ptr (attr->query.prog_ids);enum bpf_attach_type type = attr->query.attach_type;enum cgroup_bpf_attach_type from_atype, to_atype;
@@ -1029,8 +1030,12 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,int total_cnt =0 ;u32 flags; +if (effective_query && prog_attach_flags) +return -EINVAL ; +if (type ==BPF_LSM_CGROUP ) { -if (attr->query.prog_cnt && prog_ids && !prog_attach_flags) +if (!effective_query && attr->query.prog_cnt && + prog_ids && !prog_attach_flags)return -EINVAL ; from_atype =CGROUP_LSM_START ;
@@ -1045,7 +1050,7 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, }for (atype = from_atype; atype <= to_atype; atype++) { -if (attr->query.query_flags &BPF_F_QUERY_EFFECTIVE ) { +if (effective_query) { effective =rcu_dereference_protected (cgrp->bpf.effective[atype],lockdep_is_held (&cgroup_mutex)); total_cnt +=bpf_prog_array_length (effective);
@@ -1054,6 +1059,8 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, } } +/* always output uattr->query.attach_flags as 0 during effective query */ + flags = effective_query ?0 : flags;if (copy_to_user (&uattr->query.attach_flags, &flags,sizeof (flags)))return -EFAULT ;if (copy_to_user (&uattr->query.prog_cnt, &total_cnt,sizeof (total_cnt)))
@@ -1068,7 +1075,7 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, }for (atype = from_atype; atype <= to_atype && total_cnt; atype++) { -if (attr->query.query_flags &BPF_F_QUERY_EFFECTIVE ) { +if (effective_query) { effective =rcu_dereference_protected (cgrp->bpf.effective[atype],lockdep_is_held (&cgroup_mutex)); cnt =min_t (int,bpf_prog_array_length (effective), total_cnt);
@@ -1090,15 +1097,16 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,if (++i == cnt)break ; } - } -if (prog_attach_flags) { - flags = cgrp->bpf.flags[atype]; +if (prog_attach_flags) { + flags = cgrp->bpf.flags[atype]; -for (i =0 ; i < cnt; i++) -if (copy_to_user (prog_attach_flags + i, &flags,sizeof (flags))) -return -EFAULT ; - prog_attach_flags += cnt; +for (i =0 ; i < cnt; i++) +if (copy_to_user (prog_attach_flags + i, + &flags,sizeof (flags))) +return -EFAULT ; + prog_attach_flags += cnt; + } } prog_ids += cnt;
tools/include/uapi/linux/bpf.h +5 -2
@@ -1233,7 +1233,7 @@ enum {/* Query effective (directly attached + inherited from ancestor cgroups) * programs that will be executed for events within a cgroup. -* attach_flags with this flag are returned only for directly attached programs. +* attach_flags with this flag are always returned 0. */ #define BPF_F_QUERY_EFFECTIVE (1U << 0)
@@ -1432,7 +1432,10 @@ union bpf_attr {__u32 attach_flags;__aligned_u64 prog_ids;__u32 prog_cnt; -__aligned_u64 prog_attach_flags;/* output: per-program attach_flags */ +/* output: per-program attach_flags. +* not allowed to be set during effective query. +*/ +__aligned_u64 prog_attach_flags; } query;struct {/* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 303/862 bpftool: Fix wrong cgroup attach flags being assigned to effective progs
In reply to Greg Kroah-HartmanFrom: Pu Lehui <[email protected]>
[ Upstream commit bdcee1b0b0834d031c76a12209840afe949b048a ]
When root-cgroup attach multi progs and sub-cgroup attach a override prog, bpftool will display incorrectly for the attach flags of the sub-cgroup’s effective progs:
$ bpftool cgroup tree /sys/fs/cgroup effective CgroupPath ID AttachType AttachFlags Name /sys/fs/cgroup 6 cgroup_sysctl multi sysctl_tcp_mem 13 cgroup_sysctl multi sysctl_tcp_mem /sys/fs/cgroup/cg1 20 cgroup_sysctl override sysctl_tcp_mem 6 cgroup_sysctl override sysctl_tcp_mem <- wrong 13 cgroup_sysctl override sysctl_tcp_mem <- wrong /sys/fs/cgroup/cg1/cg2 20 cgroup_sysctl sysctl_tcp_mem 6 cgroup_sysctl sysctl_tcp_mem 13 cgroup_sysctl sysctl_tcp_mem
Attach flags is only valid for attached progs of this layer cgroup, but not for effective progs. For querying with EFFECTIVE flags, exporting attach flags does not make sense. So let's remove the AttachFlags field and the associated logic. After this patch, the above effective cgroup tree will show as bellow:
$ bpftool cgroup tree /sys/fs/cgroup effective CgroupPath ID AttachType Name /sys/fs/cgroup 6 cgroup_sysctl sysctl_tcp_mem 13 cgroup_sysctl sysctl_tcp_mem /sys/fs/cgroup/cg1 20 cgroup_sysctl sysctl_tcp_mem 6 cgroup_sysctl sysctl_tcp_mem 13 cgroup_sysctl sysctl_tcp_mem /sys/fs/cgroup/cg1/cg2 20 cgroup_sysctl sysctl_tcp_mem 6 cgroup_sysctl sysctl_tcp_mem 13 cgroup_sysctl sysctl_tcp_mem
--- tools/bpf/bpftool/cgroup.c | 54 ++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 5 deletions(-)
tools/bpf/bpftool/cgroup.c +49 -5
@@ -136,8 +136,8 @@ static int show_bpf_prog(int id, enum bpf_attach_type attach_type,jsonw_string_field (json_wtr,"attach_type" , attach_type_str); else jsonw_uint_field(json_wtr, "attach_type", attach_type); -jsonw_string_field (json_wtr,"attach_flags" , - attach_flags_str); +if (!(query_flags &BPF_F_QUERY_EFFECTIVE )) +jsonw_string_field (json_wtr,"attach_flags" , attach_flags_str);jsonw_string_field (json_wtr,"name" , prog_name);if (attach_btf_name)jsonw_string_field (json_wtr,"attach_btf_name" , attach_btf_name);
@@ -150,7 +150,10 @@ static int show_bpf_prog(int id, enum bpf_attach_type attach_type,printf ("%-15s" , attach_type_str); else printf("type %-10u", attach_type); -printf (" %-15s %-15s" , attach_flags_str, prog_name); +if (query_flags &BPF_F_QUERY_EFFECTIVE ) +printf (" %-15s" , prog_name); +else +printf (" %-15s %-15s" , attach_flags_str, prog_name);if (attach_btf_name)printf (" %-15s" , attach_btf_name);else if (info.attach_btf_id)
@@ -195,6 +198,32 @@ static int cgroup_has_attached_progs(int cgroup_fd)return no_prog ?0 :1 ; } + +static int show_effective_bpf_progs (int cgroup_fd,enum bpf_attach_type type, +int level) +{ +LIBBPF_OPTS (bpf_prog_query_opts, p); +__u32 prog_ids[1024 ] = {0 }; +__u32 iter; +int ret; + + p.query_flags = query_flags; + p.prog_cnt =ARRAY_SIZE (prog_ids); + p.prog_ids = prog_ids; + + ret =bpf_prog_query_opts (cgroup_fd, type, &p); +if (ret) +return ret; + +if (p.prog_cnt ==0 ) +return 0 ; + +for (iter =0 ; iter < p.prog_cnt; iter++) +show_bpf_prog (prog_ids[iter], type,NULL , level); + +return 0 ; +} +static int show_attached_bpf_progs (int cgroup_fd,enum bpf_attach_type type,int level) {
@@ -245,6 +274,14 @@ static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type,return 0 ; } +static int show_bpf_progs (int cgroup_fd,enum bpf_attach_type type, +int level) +{ +return query_flags &BPF_F_QUERY_EFFECTIVE ? +show_effective_bpf_progs (cgroup_fd, type, level) : +show_attached_bpf_progs (cgroup_fd, type, level); +} +static int do_show (int argc,char **argv) {enum bpf_attach_type type;
@@ -292,6 +329,8 @@ static int do_show(int argc, char **argv)if (json_output)jsonw_start_array (json_wtr); +else if (query_flags &BPF_F_QUERY_EFFECTIVE ) +printf ("%-8s %-15s %-15s\n" ,"ID" ,"AttachType" ,"Name" );else printf ("%-8s %-15s %-15s %-15s\n" ,"ID" ,"AttachType" ,"AttachFlags" ,"Name" );
@@ -304,7 +343,7 @@ static int do_show(int argc, char **argv)* If we were able to get the show for at least one * attach type, let's return 0. */ -if (show_attached_bpf_progs (cgroup_fd, type,0 ) ==0 ) +if (show_bpf_progs (cgroup_fd, type,0 ) ==0 ) ret =0 ; }
@@ -362,7 +401,7 @@ static int do_show_tree_fn(const char *fpath, const struct stat *sb, btf_vmlinux =libbpf_find_kernel_btf ();for (type =0 ; type < __MAX_BPF_ATTACH_TYPE; type++) -show_attached_bpf_progs (cgroup_fd, type, ftw->level); +show_bpf_progs (cgroup_fd, type, ftw->level);if (errno ==EINVAL )/* Last attach type does not support query.
@@ -436,6 +475,11 @@ static int do_show_tree(int argc, char **argv)if (json_output)jsonw_start_array (json_wtr); +else if (query_flags &BPF_F_QUERY_EFFECTIVE ) +printf ("%s\n" +"%-8s %-15s %-15s\n" , +"CgroupPath" , +"ID" ,"AttachType" ,"Name" );else printf("%s\n" "%-8s %-15s %-15s %-15s\n",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 304/862 selftests/bpf: Adapt cgroup effective query uapi change
In reply to Greg Kroah-HartmanFrom: Pu Lehui <[email protected]>
[ Upstream commit d2aa993b7d9de6deeb1df6c9a6b9b6193c337cc6 ]
The attach flags is meaningless for effective query and its value will always be set as 0 during effective query. Root cg's effective progs is always its attached progs, so we use non-effective query to get its progs count and attach flags. And we don't need the remain attach flags check.
--- tools/testing/selftests/bpf/prog_tests/cgroup_link.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
tools/testing/selftests/bpf/prog_tests/cgroup_link.c +4 -7
@@ -71,10 +71,9 @@ void serial_test_cgroup_link(void)ping_and_check (cg_nr,0 ); -/* query the number of effective progs and attach flags in root cg */ +/* query the number of attached progs and attach flags in root cg */ err =bpf_prog_query (cgs[0 ].fd,BPF_CGROUP_INET_EGRESS , -BPF_F_QUERY_EFFECTIVE , &attach_flags,NULL , - &prog_cnt); +0 , &attach_flags,NULL , &prog_cnt);CHECK_FAIL (err);CHECK_FAIL (attach_flags !=BPF_F_ALLOW_MULTI );if (CHECK (prog_cnt !=1 ,"effect_cnt" ,"exp %d, got %d\n" ,1 , prog_cnt))
@@ -85,17 +84,15 @@ void serial_test_cgroup_link(void)BPF_F_QUERY_EFFECTIVE ,NULL ,NULL , &prog_cnt);CHECK_FAIL (err); -CHECK_FAIL (attach_flags !=BPF_F_ALLOW_MULTI );if (CHECK (prog_cnt != cg_nr,"effect_cnt" ,"exp %d, got %d\n" , cg_nr, prog_cnt)) goto cleanup;/* query the effective prog IDs in last cg */ err =bpf_prog_query (cgs[last_cg].fd,BPF_CGROUP_INET_EGRESS , -BPF_F_QUERY_EFFECTIVE , &attach_flags, - prog_ids, &prog_cnt); +BPF_F_QUERY_EFFECTIVE ,NULL , prog_ids, + &prog_cnt);CHECK_FAIL (err); -CHECK_FAIL (attach_flags !=BPF_F_ALLOW_MULTI );if (CHECK (prog_cnt != cg_nr,"effect_cnt" ,"exp %d, got %d\n" , cg_nr, prog_cnt)) goto cleanup;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 305/862 flow_dissector: Do not count vlan tags inside tunnel payload
In reply to Greg Kroah-HartmanFrom: Qingqing Yang <[email protected]>
[ Upstream commit 9f87eb4246994e32a4e4ea88476b20ab3b412840 ]
We've met the problem that when there is a vlan tag inside GRE encapsulation, the match of num_of_vlans fails. It is caused by the vlan tag inside GRE payload has been counted into num_of_vlans, which is not expected.
One example packet is like this:
Ethernet II, Src: Broadcom_68:56:07 (00:10:18:68:56:07)
Dst: Broadcom_68:56:08 (00:10:18:68:56:08)
802.1Q Virtual LAN, PRI: 0, DEI: 0, ID: 100
Internet Protocol Version 4, Src: 192.168.1.4, Dst: 192.168.1.200 Generic Routing Encapsulation (Transparent Ethernet bridging) Ethernet II, Src: Broadcom_68:58:07 (00:10:18:68:58:07)
Dst: Broadcom_68:58:08 (00:10:18:68:58:08)
802.1Q Virtual LAN, PRI: 0, DEI: 0, ID: 200
...
It should match the (num_of_vlans 1) rule, but it matches the (num_of_vlans 2) rule.
The vlan tags inside the GRE or other tunnel encapsulated payload should not be taken into num_of_vlans.
The fix is to stop counting the vlan number when the encapsulation bit is set.
--- net/core/flow_dissector.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/core/flow_dissector.c +2 -2
@@ -1173,8 +1173,8 @@ bool __skb_flow_dissect(const struct net *net, nhoff +=sizeof (*vlan); } -if (dissector_uses_key (flow_dissector, -FLOW_DISSECTOR_KEY_NUM_OF_VLANS )) { +if (dissector_uses_key (flow_dissector,FLOW_DISSECTOR_KEY_NUM_OF_VLANS ) && + !(key_control->flags &FLOW_DIS_ENCAPSULATION )) {struct flow_dissector_key_num_of_vlans *key_nvs; key_nvs = skb_flow_dissector_target(flow_dissector,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 306/862 mwifiex: fix sleep in atomic context bugs caused by dev_coredumpv
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit 551e4745c7f218da7070b36a06318592913676ff ]
There are sleep in atomic context bugs when uploading device dump data in mwifiex. The root cause is that dev_coredumpv could not be used in atomic contexts, because it calls dev_set_name which include operations that may sleep. The call tree shows execution paths that could lead to bugs:
(Interrupt context)fw_dump_timer_fn
mwifiex_upload_device_dump
dev_coredumpv(..., GFP_KERNEL)
dev_coredumpm()
kzalloc(sizeof(*devcd), gfp); //may sleep dev_set_name
kobject_set_name_vargs
kvasprintf_const(GFP_KERNEL, ...); //may sleep kstrdup(s, GFP_KERNEL); //may sleep
The corresponding fail log is shown below:
[ 135.275938] usb 1-1: == mwifiex dump information to /sys/class/devcoredump start [ 135.281029] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:265 ... [ 135.293613] Call Trace: [ 135.293613] <IRQ> [ 135.293613] dump_stack_lvl+0x57/0x7d [ 135.293613] __might_resched.cold+0x138/0x173 [ 135.293613] ? dev_coredumpm+0xca/0x2e0 [ 135.293613] kmem_cache_alloc_trace+0x189/0x1f0 [ 135.293613] ? devcd_match_failing+0x30/0x30 [ 135.293613] dev_coredumpm+0xca/0x2e0 [ 135.293613] ? devcd_freev+0x10/0x10 [ 135.293613] dev_coredumpv+0x1c/0x20 [ 135.293613] ? devcd_match_failing+0x30/0x30 [ 135.293613] mwifiex_upload_device_dump+0x65/0xb0 [ 135.293613] ? mwifiex_dnld_fw+0x1b0/0x1b0 [ 135.293613] call_timer_fn+0x122/0x3d0 [ 135.293613] ? msleep_interruptible+0xb0/0xb0 [ 135.293613] ? lock_downgrade+0x3c0/0x3c0 [ 135.293613] ? __next_timer_interrupt+0x13c/0x160 [ 135.293613] ? lockdep_hardirqs_on_prepare+0xe/0x220 [ 135.293613] ? mwifiex_dnld_fw+0x1b0/0x1b0 [ 135.293613] __run_timers.part.0+0x3f8/0x540 [ 135.293613] ? call_timer_fn+0x3d0/0x3d0 [ 135.293613] ? arch_restore_msi_irqs+0x10/0x10 [ 135.293613] ? lapic_next_event+0x31/0x40 [ 135.293613] run_timer_softirq+0x4f/0xb0 [ 135.293613] __do_softirq+0x1c2/0x651 ... [ 135.293613] RIP: 0010:default_idle+0xb/0x10 [ 135.293613] RSP: 0018:ffff888006317e68 EFLAGS: 00000246 [ 135.293613] RAX: ffffffff82ad8d10 RBX: ffff888006301cc0 RCX: ffffffff82ac90e1 [ 135.293613] RDX: ffffed100d9ff1b4 RSI: ffffffff831ad140 RDI: ffffffff82ad8f20 [ 135.293613] RBP: 0000000000000003 R08: 0000000000000000 R09: ffff88806cff8d9b [ 135.293613] R10: ffffed100d9ff1b3 R11: 0000000000000001 R12: ffffffff84593410 [ 135.293613] R13: 0000000000000000 R14: 0000000000000000 R15: 1ffff11000c62fd2 ... [ 135.389205] usb 1-1: == mwifiex dump information to /sys/class/devcoredump end
This patch uses delayed work to replace timer and moves the operations that may sleep into a delayed work in order to mitigate bugs, it was tested on Marvell 88W8801 chip whose port is usb and the firmware is usb8801_uapsta.bin. The following is the result after using delayed work to replace timer.
[ 134.936453] usb 1-1: == mwifiex dump information to /sys/class/devcoredump start [ 135.043344] usb 1-1: == mwifiex dump information to /sys/class/devcoredump end
As we can see, there is no bug now.
--- drivers/net/wireless/marvell/mwifiex/init.c | 9 +++++---- drivers/net/wireless/marvell/mwifiex/main.h | 3 ++- drivers/net/wireless/marvell/mwifiex/sta_event.c | 6 +++--- 3 files changed, 10 insertions(+), 8 deletions(-)
drivers/net/wireless/marvell/mwifiex/init.c +5 -4
@@ -51,9 +51,10 @@ static void wakeup_timer_fn(struct timer_list *t) adapter->if_ops.card_reset (adapter); } -static void fw_dump_timer_fn (struct timer_list *t) +static void fw_dump_work (struct work_struct *work) { -struct mwifiex_adapter *adapter =from_timer (adapter, t, devdump_timer); +struct mwifiex_adapter *adapter = + container_of(work, struct mwifiex_adapter, devdump_work.work);mwifiex_upload_device_dump (adapter); }
@@ -309,7 +310,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) adapter->active_scan_triggered = false;timer_setup (&adapter->wakeup_timer, wakeup_timer_fn,0 ); adapter->devdump_len =0 ; -timer_setup (&adapter->devdump_timer, fw_dump_timer_fn,0 ); +INIT_DELAYED_WORK (&adapter->devdump_work, fw_dump_work); }/*
@@ -388,7 +389,7 @@ static void mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter) {del_timer (&adapter->wakeup_timer); -del_timer_sync (&adapter->devdump_timer); +cancel_delayed_work_sync (&adapter->devdump_work);mwifiex_cancel_all_pending_cmd (adapter);wake_up_interruptible (&adapter->cmd_wait_q.wait);wake_up_interruptible (&adapter->hs_activate_wait_q);
drivers/net/wireless/marvell/mwifiex/main.h +2 -1
@@ -37,6 +37,7 @@#include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/of_irq.h> +#include <linux/workqueue.h> #include "decl.h" #include "ioctl.h"
@@ -1043,7 +1044,7 @@ struct mwifiex_adapter {/* Device dump data/length */ void *devdump_data;int devdump_len; -struct timer_list devdump_timer; +struct delayed_work devdump_work;bool ignore_btcoex_events; };
drivers/net/wireless/marvell/mwifiex/sta_event.c +3 -3
@@ -611,8 +611,8 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv,* transmission event get lost, in this cornel case, * user would still get partial of the dump. */ -mod_timer (&adapter->devdump_timer, - jiffies +msecs_to_jiffies (MWIFIEX_TIMER_10S )); +schedule_delayed_work (&adapter->devdump_work, +msecs_to_jiffies (MWIFIEX_TIMER_10S )); }/* Overflow check */
@@ -631,7 +631,7 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv,return ; upload_dump: -del_timer_sync (&adapter->devdump_timer); +cancel_delayed_work_sync (&adapter->devdump_work);mwifiex_upload_device_dump (adapter); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 307/862 wifi: ath11k: fix failed to find the peer with peer_id 0 when disconnected
In reply to Greg Kroah-HartmanFrom: Wen Gong <[email protected]>
[ Upstream commit a20ed60bb357776301c2dad7b4a4f0db97e143e9 ]
It has a fail log which is ath11k_dbg in ath11k_dp_rx_process_mon_status(), as below, it will not print when debug_mask is not set ATH11K_DBG_DATA.
ath11k_dbg(ab, ATH11K_DBG_DATA, "failed to find the peer with peer_id %d\n", ppdu_info.peer_id);
When run scan with station disconnected, the peer_id is 0 for case HAL_RX_MPDU_START in ath11k_hal_rx_parse_mon_status_tlv() which called from ath11k_dp_rx_process_mon_status(), and the peer_id of ppdu_info is reset to 0 in the while loop, so it does not match condition of the check "if (ppdu_info->peer_id == HAL_INVALID_PEERID" in the loop, and then the log "failed to find the peer with peer_id 0" print after the check in the loop, it is below call stack when debug_mask is set ATH11K_DBG_DATA.
The reason is this commit 01d2f285e3e5 ("ath11k: decode HE status tlv") add "memset(ppdu_info, 0, sizeof(struct hal_rx_mon_ppdu_info))" in ath11k_dp_rx_process_mon_status(), but the commit does not initialize the peer_id to HAL_INVALID_PEERID, then lead the check mis-match.
Callstack of the failed log:
[12335.689072] RIP: 0010:ath11k_dp_rx_process_mon_status+0x9ea/0x1020 [ath11k] [12335.689157] Code: 89 ff e8 f9 10 00 00 be 01 00 00 00 4c 89 f7 e8 dc 4b 4e de 48 8b 85 38 ff ff ff c7 80 e4 07 00 00 01 00 00 00 e9 20 f8 ff ff <0f> 0b 41 0f b7 96 be 06 00 00 48 c7 c6 b8 50 44 c1 4c 89 ff e8 fd [12335.689180] RSP: 0018:ffffb874001a4ca0 EFLAGS: 00010246 [12335.689210] RAX: 0000000000000000 RBX: ffff995642cbd100 RCX: 0000000000000000 [12335.689229] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff99564212cd18 [12335.689248] RBP: ffffb874001a4dc0 R08: 0000000000000001 R09: 0000000000000000 [12335.689268] R10: 0000000000000220 R11: ffffb874001a48e8 R12: ffff995642473d40 [12335.689286] R13: ffff99564212c5b8 R14: ffff9956424736a0 R15: ffff995642120000 [12335.689303] FS: 0000000000000000(0000) GS:ffff995739000000(0000) knlGS:0000000000000000 [12335.689323] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [12335.689341] CR2: 00007f43c5d5e039 CR3: 000000011c012005 CR4: 00000000000606e0 [12335.689360] Call Trace: [12335.689377] <IRQ> [12335.689418] ? rcu_read_lock_held_common+0x12/0x50 [12335.689447] ? rcu_read_lock_sched_held+0x25/0x80 [12335.689471] ? rcu_read_lock_held_common+0x12/0x50 [12335.689504] ath11k_dp_rx_process_mon_rings+0x8d/0x4f0 [ath11k] [12335.689578] ? ath11k_dp_rx_process_mon_rings+0x8d/0x4f0 [ath11k] [12335.689653] ? lock_acquire+0xef/0x360 [12335.689681] ? rcu_read_lock_sched_held+0x25/0x80 [12335.689713] ath11k_dp_service_mon_ring+0x38/0x60 [ath11k] [12335.689784] ? ath11k_dp_rx_process_mon_rings+0x4f0/0x4f0 [ath11k] [12335.689860] call_timer_fn+0xb2/0x2f0 [12335.689897] ? ath11k_dp_rx_process_mon_rings+0x4f0/0x4f0 [ath11k] [12335.689970] run_timer_softirq+0x21f/0x540 [12335.689999] ? ktime_get+0xad/0x160 [12335.690025] ? lapic_next_deadline+0x2c/0x40 [12335.690053] ? clockevents_program_event+0x82/0x100 [12335.690093] __do_softirq+0x151/0x4a8 [12335.690135] irq_exit_rcu+0xc9/0x100 [12335.690165] sysvec_apic_timer_interrupt+0xa8/0xd0 [12335.690189] </IRQ> [12335.690204] <TASK> [12335.690225] asm_sysvec_apic_timer_interrupt+0x12/0x20
Reset the default value to HAL_INVALID_PEERID each time after memset of ppdu_info as well as others memset which existed in function ath11k_dp_rx_process_mon_status(), then the failed log disappeared.
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
--- drivers/net/wireless/ath/ath11k/dp_rx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/ath11k/dp_rx.c +2 -1
@@ -5197,7 +5197,8 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,if (log_type !=ATH11K_PKTLOG_TYPE_INVALID )trace_ath11k_htt_rxdesc (ar, skb->data, log_type, rx_buf_sz); -memset (ppdu_info,0 ,sizeof (struct hal_rx_mon_ppdu_info )); +memset (ppdu_info,0 ,sizeof (*ppdu_info)); + ppdu_info->peer_id =HAL_INVALID_PEERID ; hal_status =ath11k_hal_rx_parse_mon_status (ab, ppdu_info, skb); if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags) &&
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 308/862 wifi: ath11k: fix number of VHT beamformee spatial streams
In reply to Greg Kroah-HartmanFrom: Jesus Fernandez Manzano <[email protected]>
[ Upstream commit 55b5ee3357d7bb98ee578cf9b84a652e7a1bc199 ]
The number of spatial streams used when acting as a beamformee in VHT mode are reported by the firmware as 7 (8 sts - 1) both in IPQ6018 and IPQ8074 which respectively have 2 and 4 sts each. So the firmware should report 1 (2 - 1) and 3 (4 - 1).
Fix this by checking that the number of VHT beamformee sts reported by the firmware is not greater than the number of receiving antennas - 1. The fix is based on the same approach used in this same function for sanitizing the number of sounding dimensions reported by the firmware.
Without this change, acting as a beamformee in VHT mode is not working properly.
Tested-on: IPQ6018 hw1.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
--- drivers/net/wireless/ath/ath11k/mac.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)
drivers/net/wireless/ath/ath11k/mac.c +20 -5
@@ -4954,6 +4954,8 @@ static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif)if (vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE )) { nsts = vht_cap &IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK ; nsts >>=IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT ; +if (nsts > (ar->num_rx_chains -1 )) + nsts = ar->num_rx_chains -1 ; value |=SM (nsts,WMI_TXBF_STS_CAP_OFFSET ); }
@@ -4994,7 +4996,7 @@ static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif)static void ath11k_set_vht_txbf_cap (struct ath11k *ar,u32 *vht_cap) {bool subfer, subfee; -int sound_dim =0 ; +int sound_dim =0 , nsts =0 ; subfer = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE )); subfee = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE ));
@@ -5004,6 +5006,11 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) subfer = false; } +if (ar->num_rx_chains <2 ) { + *vht_cap &= ~(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE ); + subfee = false; + } +/* If SU Beaformer is not set, then disable MU Beamformer Capability */ if (!subfer) *vht_cap &= ~(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE );
@@ -5016,7 +5023,9 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) sound_dim >>=IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT ; *vht_cap &= ~IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK ; -/* TODO: Need to check invalid STS and Sound_dim values set by FW? */ + nsts = (*vht_cap &IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK ); + nsts >>=IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT ; + *vht_cap &= ~IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK ;/* Enable Sounding Dimension Field only if SU BF is enabled */ if (subfer) {
@@ -5028,9 +5037,15 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) *vht_cap |= sound_dim; } -/* Use the STS advertised by FW unless SU Beamformee is not supported*/ -if (!subfee) - *vht_cap &= ~(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK ); +/* Enable Beamformee STS Field only if SU BF is enabled */ +if (subfee) { +if (nsts > (ar->num_rx_chains -1 )) + nsts = ar->num_rx_chains -1 ; + + nsts <<=IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT ; + nsts &=IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK ; + *vht_cap |= nsts; + } } static struct ieee80211_sta_vht_cap
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 309/862 mips: dts: ralink: mt7621: fix external phy on GB-PC2
In reply to Greg Kroah-HartmanFrom: Arınç ÜNAL <[email protected]>
[ Upstream commit 247825f991b34440f9b9d4fe607502435a42ac7b ]
The address of the external phy on the mdio bus is 5. Update the devicetree for GB-PC2 accordingly.
--- arch/mips/boot/dts/ralink/mt7621-gnubee-gb-pc2.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/mips/boot/dts/ralink/mt7621-gnubee-gb-pc2.dts +3 -3
@@ -83,12 +83,12 @@ &gmac1 { status = "okay"; - phy-handle = <ðphy7>; + phy-handle = <ðphy5>; }; &mdio { - ethphy7: ethernet-phy@7 { - reg = <7>; + ethphy5: ethernet-phy@5 { + reg = <5>; phy-mode = "rgmii-rxid"; }; };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 310/862 x86/microcode/AMD: Track patch allocation size explicitly
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit 712f210a457d9c32414df246a72781550bc23ef6 ]
In preparation for reducing the use of ksize(), record the actual allocation size for later memcpy(). This avoids copying extra (uninitialized!) bytes into the patch buffer when the requested allocation size isn't exactly the size of a kmalloc bucket. Additionally, fix potential future issues where runtime bounds checking will notice that the buffer was allocated to a smaller value than returned by ksize().
--- arch/x86/include/asm/microcode.h | 1 + arch/x86/kernel/cpu/microcode/amd.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-)
arch/x86/include/asm/microcode.h +1 -0
@@ -9,6 +9,7 @@struct ucode_patch {struct list_head plist;void *data;/* Intel uses only this one */ +unsigned int size;u32 patch_id;u16 equiv_cpu; };
arch/x86/kernel/cpu/microcode/amd.c +2 -1
@@ -788,6 +788,7 @@ static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover,kfree (patch);return -EINVAL ; } + patch->size = *patch_size; mc_hdr = (struct microcode_header_amd *)(fw +SECTION_HDR_SIZE ); proc_id = mc_hdr->processor_rev_id;
@@ -869,7 +870,7 @@ load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)return ret;memset (amd_ucode_patch,0 ,PATCH_MAX_SIZE ); -memcpy (amd_ucode_patch, p->data,min_t (u32,ksize (p->data),PATCH_MAX_SIZE )); +memcpy (amd_ucode_patch, p->data,min_t (u32, p->size,PATCH_MAX_SIZE ));return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 311/862 libbpf: restore memory layout of bpf_object_open_opts
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit dbdea9b36fb61da3b9a1be0dd63542e2bfd3e5d7 ]
When attach_prog_fd field was removed in libbpf 1.0 and replaced with long: 0 placeholder, it actually shifted all the subsequent fields by 8 byte. This is due to long: 0 promising to adjust next field's offset to long-aligned offset. But in this case we were already long-aligned as pin_root_path is a pointer. So long: 0 had no effect, and thus didn't feel the gap created by removed attach_prog_fd.
Non-zero bitfield should have been used instead. I validated using pahole. Originally kconfig field was at offset 40. With long: 0 it's at offset 32, which is wrong. With this change it's back at offset 40.
While technically libbpf 1.0 is allowed to break backwards compatibility and applications should have been recompiled against libbpf 1.0 headers, but given how trivial it is to preserve memory layout, let's fix this.
--- tools/lib/bpf/libbpf.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
tools/lib/bpf/libbpf.h +3 -1
@@ -118,7 +118,9 @@ struct bpf_object_open_opts {* auto-pinned to that path on load; defaults to "/sys/fs/bpf". */ const char *pin_root_path; - long :0; + + __u32 :32 ;/* stub out now removed attach_prog_fd */ +/* Additional kernel config content that augments and overrides * system Kconfig for CONFIG_xxx externs. */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 312/862 wifi: ath11k: fix peer addition/deletion error on sta band migration
In reply to Greg Kroah-HartmanFrom: Christian 'Ansuel' Marangi <[email protected]>
[ Upstream commit d673cb6fe6c03b2be157cc6c5db40481828d282d ]
This patch try to fix the following error.
Wed Jun 1 22:19:30 2022 kern.warn kernel: [ 119.561227] ath11k c000000.wifi: peer already added vdev id 0 req, vdev id 1 present Wed Jun 1 22:19:30 2022 kern.warn kernel: [ 119.561282] ath11k c000000.wifi: Failed to add peer: 28:c2:1f:xx:xx:xx for VDEV: 0 Wed Jun 1 22:19:30 2022 kern.warn kernel: [ 119.568053] ath11k c000000.wifi: Failed to add station: 28:c2:1f:xx:xx:xx for VDEV: 0 Wed Jun 1 22:19:31 2022 daemon.notice hostapd: wlan2: STA 28:c2:1f:xx:xx:xx IEEE 802.11: Could not add STA to kernel driver Wed Jun 1 22:19:31 2022 daemon.notice hostapd: wlan2: STA 28:c2:1f:xx:xx:xx IEEE 802.11: did not acknowledge authentication response Wed Jun 1 22:19:31 2022 daemon.notice hostapd: wlan1: AP-STA-DISCONNECTED 28:c2:1f:xx:xx:xx Wed Jun 1 22:19:31 2022 daemon.info hostapd: wlan1: STA 28:c2:1f:xx:xx:xx IEEE 802.11: disassociated due to inactivity Wed Jun 1 22:19:32 2022 daemon.info hostapd: wlan1: STA 28:c2:1f:xx:xx:xx IEEE 802.11: deauthenticated due to inactivity (timer DEAUTH/REMOVE)
To repro this:
- Have 2 Wifi with the same bssid and pass on different band (2.4 and 5GHz)
- Enable 802.11r Fast Transaction with same mobility domain
- FT Protocol: FT over the Air
Quoted 1 line
From a openwrt system issue the command (with the correct mac)
ubus call hostapd.wlan1 wnm_disassoc_imminent '{"addr":"28:C2:1F:xx:xx:xx"}' Notice the log printing the errors.
The cause of this error has been investigated and we found that this is related to the WiFi Fast Transaction feature. We observed that this is triggered when the router tells the device to change band. In this case the device first auth to the other band and then the disconnect path from the prev band is triggered.
This is problematic with the current rhash implementation since the addrs is used as key and the logic of "adding first, delete later" conflicts with the rhash logic.
In fact peer addition will fail since the peer is already added and with that fixed a peer deletion will cause unitended effect by removing the peer just added.
Current solution to this is to add additional logic to the peer delete, make sure we are deleting the correct peer taken from the rhash table (and fallback to the peer list) and for the peer add logic delete the peer entry for the rhash list before adding the new one (counting as an error only when a peer with the same vlan_id is asked to be added).
With this change, a sta can correctly transition from 2.4GHz and 5GHZ with no drop and no error are printed.
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
--- drivers/net/wireless/ath/ath11k/peer.c | 30 ++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-)
drivers/net/wireless/ath/ath11k/peer.c +26 -4
@@ -302,6 +302,21 @@ static int __ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, const u8 *addr)spin_lock_bh (&ab->base_lock); peer =ath11k_peer_find_by_addr (ab, addr); +/* Check if the found peer is what we want to remove. +* While the sta is transitioning to another band we may +* have 2 peer with the same addr assigned to different +* vdev_id. Make sure we are deleting the correct peer. +*/ +if (peer && peer->vdev_id == vdev_id) +ath11k_peer_rhash_delete (ab, peer); + +/* Fallback to peer list search if the correct peer can't be found. +* Skip the deletion of the peer from the rhash since it has already +* been deleted in peer add. +*/ +if (!peer) + peer =ath11k_peer_find (ab, vdev_id, addr); +if (!peer) {spin_unlock_bh (&ab->base_lock);mutex_unlock (&ab->tbl_mtx_lock);
@@ -312,8 +327,6 @@ static int __ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, const u8 *addr)return -EINVAL ; } -ath11k_peer_rhash_delete (ab, peer); -spin_unlock_bh (&ab->base_lock);mutex_unlock (&ab->tbl_mtx_lock);
@@ -372,8 +385,17 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,spin_lock_bh (&ar->ab->base_lock); peer =ath11k_peer_find_by_addr (ar->ab, param->peer_addr);if (peer) { -spin_unlock_bh (&ar->ab->base_lock); -return -EINVAL ; +if (peer->vdev_id == param->vdev_id) { +spin_unlock_bh (&ar->ab->base_lock); +return -EINVAL ; + } + +/* Assume sta is transitioning to another band. +* Remove here the peer from rhash. +*/ +mutex_lock (&ar->ab->tbl_mtx_lock); +ath11k_peer_rhash_delete (ar->ab, peer); +mutex_unlock (&ar->ab->tbl_mtx_lock); }spin_unlock_bh (&ar->ab->base_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 313/862 x86/cpu: Include the header of init_ia32_feat_ctl()s prototype
In reply to Greg Kroah-HartmanFrom: Luciano Leão <[email protected]>
[ Upstream commit 30ea703a38ef76ca119673cd8bdd05c6e068e2ac ]
Include the header containing the prototype of init_ia32_feat_ctl(), solving the following warning:
$ make W=1 arch/x86/kernel/cpu/feat_ctl.o
arch/x86/kernel/cpu/feat_ctl.c:112:6: warning: no previous prototype for ‘init_ia32_feat_ctl’ [-Wmissing-prototypes]
112 | void init_ia32_feat_ctl(struct cpuinfo_x86 *c)This warning appeared after commit
5d5103595e9e5 ("x86/cpu: Reinitialize IA32_FEAT_CTL MSR on BSP during wakeup")
had moved the function init_ia32_feat_ctl()'s prototype from arch/x86/kernel/cpu/cpu.h to arch/x86/include/asm/cpu.h.
Note that, before the commit mentioned above, the header include "cpu.h" (arch/x86/kernel/cpu/cpu.h) was added by commit
0e79ad863df43 ("x86/cpu: Fix a -Wmissing-prototypes warning for init_ia32_feat_ctl()")
solely to fix init_ia32_feat_ctl()'s missing prototype. So, the header include "cpu.h" is no longer necessary.
[ bp: Massage commit message. ]
--- arch/x86/kernel/cpu/feat_ctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/feat_ctl.c +1 -1
@@ -1,11 +1,11 @@// SPDX-License-Identifier: GPL-2.0 #include <linux/tboot.h> +#include <asm/cpu.h> #include <asm/cpufeature.h> #include <asm/msr-index.h> #include <asm/processor.h> #include <asm/vmx.h> -#include "cpu.h" #undef pr_fmt#define pr_fmt (fmt) "x86/cpu: " fmt
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 314/862 spi: cadence-quadspi: Fix PM disable depth imbalance in cqspi_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 4d0ef0a1c35189a6e8377d8ee8310ea5ef22c5f3 ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context.
--- drivers/spi/spi-cadence-quadspi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/spi/spi-cadence-quadspi.c +2 -1
@@ -1645,7 +1645,7 @@ static int cqspi_probe(struct platform_device *pdev)pm_runtime_enable (dev); ret =pm_runtime_resume_and_get (dev);if (ret <0 ) -return ret; + goto probe_pm_failed; ret =clk_prepare_enable (cqspi->clk);if (ret) {
@@ -1740,6 +1740,7 @@ static int cqspi_probe(struct platform_device *pdev)clk_disable_unprepare (cqspi->clk); probe_clk_failed:pm_runtime_put_sync (dev); +probe_pm_failed:pm_runtime_disable (dev);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 315/862 spi: dw: Fix PM disable depth imbalance in dw_spi_bt1_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 618d815fc93477b1675878f3c04ff32657cc18b4 ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context.
--- drivers/spi/spi-dw-bt1.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/spi/spi-dw-bt1.c +3 -1
@@ -293,8 +293,10 @@ static int dw_spi_bt1_probe(struct platform_device *pdev)pm_runtime_enable (&pdev->dev); ret =dw_spi_add_host (&pdev->dev, dws); -if (ret) +if (ret) { +pm_runtime_disable (&pdev->dev); goto err_disable_clk; + }platform_set_drvdata (pdev, dwsbt1);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 316/862 spi/omap100k:Fix PM disable depth imbalance in omap1_spi100k_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 29f65f2171c85a9633daa380df14009a365f42f2 ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context.
--- drivers/spi/spi-omap-100k.c | 1 + 1 file changed, 1 insertion(+)
drivers/spi/spi-omap-100k.c +1 -0
@@ -412,6 +412,7 @@ static int omap1_spi100k_probe(struct platform_device *pdev)return status; err_fck: +pm_runtime_disable (&pdev->dev);clk_disable_unprepare (spi100k->fck); err_ick:clk_disable_unprepare (spi100k->ick);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 317/862 skmsg: Schedule psock work if the cached skb exists on the psock
In reply to Greg Kroah-HartmanFrom: Liu Jian <[email protected]>
[ Upstream commit bec217197b412d74168c6a42fc0f76d0cc9cad00 ]
In sk_psock_backlog function, for ingress direction skb, if no new data packet arrives after the skb is cached, the cached skb does not have a chance to be added to the receive queue of psock. As a result, the cached skb cannot be received by the upper-layer application. Fix this by reschedule the psock work to dispose the cached skb in sk_msg_recvmsg function.
--- net/core/skmsg.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
net/core/skmsg.c +8 -4
@@ -434,8 +434,10 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,if (copied + copy > len) copy = len - copied; copy =copy_page_to_iter (page, sge->offset, copy, iter); -if (!copy) -return copied ? copied : -EFAULT ; +if (!copy) { + copied = copied ? copied : -EFAULT ; + goto out; + } copied += copy;if (likely (!peek)) {
@@ -455,7 +457,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,* didn't copy the entire length lets just break. */ if (copy != sge->length) -return copied; + goto out;sk_msg_iter_var_next (i); }
@@ -477,7 +479,9 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg, } msg_rx =sk_psock_peek_msg (psock); } - +out: +if (psock->work_state.skb && copied >0 ) +schedule_work (&psock->work);return copied; }EXPORT_SYMBOL_GPL (sk_msg_recvmsg);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 318/862 cw1200: fix incorrect check to determine if no element is found in list
In reply to Greg Kroah-HartmanFrom: Xiaomeng Tong <[email protected]>
[ Upstream commit 86df5de5c632d3bd940f59bbb14ae912aa9cc363 ]
The bug is here: "} else if (item) {".
The list iterator value will *always* be set and non-NULL by list_for_each_entry(), so it is incorrect to assume that the iterator value will be NULL if the list is empty or no element is found in list.
Use a new value 'iter' as the list iterator, while use the old value 'item' as a dedicated pointer to point to the found element, which
1. can fix this bug, due to now 'item' is NULL only if it's not found.
2. do not need to change all the uses of 'item' after the loop.
3. can also limit the scope of the list iterator 'iter' *only inside* the traversal loop by simply declaring 'iter' inside the loop in the future, as usage of the iterator outside of the list_for_each_entry is considered harmful. https://lkml.org/lkml/2022/2/17/1032
--- drivers/net/wireless/st/cw1200/queue.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
drivers/net/wireless/st/cw1200/queue.c +10 -8
@@ -91,23 +91,25 @@ static void __cw1200_queue_gc(struct cw1200_queue *queue, bool unlock) {struct cw1200_queue_stats *stats = queue->stats; -struct cw1200_queue_item *item =NULL , *tmp; +struct cw1200_queue_item *item =NULL , *iter, *tmp;bool wakeup_stats = false; -list_for_each_entry_safe (item, tmp, &queue->queue, head) { -if (time_is_after_jiffies (item->queue_timestamp + queue->ttl)) +list_for_each_entry_safe (iter, tmp, &queue->queue, head) { +if (time_is_after_jiffies (iter->queue_timestamp + queue->ttl)) { + item = iter;break ; + } --queue->num_queued; - --queue->link_map_cache[item->txpriv.link_id]; + --queue->link_map_cache[iter->txpriv.link_id];spin_lock_bh (&stats->lock); --stats->num_queued; -if (!--stats->link_map_cache[item->txpriv.link_id]) +if (!--stats->link_map_cache[iter->txpriv.link_id]) wakeup_stats = true;spin_unlock_bh (&stats->lock);cw1200_debug_tx_ttl (stats->priv); -cw1200_queue_register_post_gc (head, item); - item->skb =NULL ; -list_move_tail (&item->head, &queue->free_pool); +cw1200_queue_register_post_gc (head, iter); + iter->skb =NULL ; +list_move_tail (&iter->head, &queue->free_pool); }if (wakeup_stats)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 319/862 libbpf: Dont require full struct enum64 in UAPI headers
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit 87dbdc230d162bf9ee1ac77c8ade178b6b1e199e ]
Drop the requirement for system-wide kernel UAPI headers to provide full struct btf_enum64 definition. This is an unexpected requirement that slipped in libbpf 1.0 and put unnecessary pressure ([0]) on users to have a bleeding-edge kernel UAPI header from unreleased Linux 6.0.
To achieve this, we forward declare struct btf_enum64. But that's not enough as there is btf_enum64_value() helper that expects to know the layout of struct btf_enum64. So we get a bit creative with reinterpreting memory layout as array of __u32 and accesing lo32/hi32 fields as array elements. Alternative way would be to have a local pointer variable for anonymous struct with exactly the same layout as struct btf_enum64, but that gets us into C++ compiler errors complaining about invalid type casts. So play it safe, if ugly.
[0] Closes: https://github.com/libbpf/libbpf/issues/562
--- tools/lib/bpf/btf.h | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
tools/lib/bpf/btf.h +24 -1
@@ -487,6 +487,8 @@ static inline struct btf_enum *btf_enum(const struct btf_type *t)return (struct btf_enum *)(t +1 ); } +struct btf_enum64 ; +static inline struct btf_enum64 *btf_enum64 (const struct btf_type *t) {return (struct btf_enum64 *)(t +1 );
@@ -494,7 +496,28 @@ static inline struct btf_enum64 *btf_enum64(const struct btf_type *t)static inline __u64 btf_enum64_value (const struct btf_enum64 *e) { -return ((__u64 )e->val_hi32 <<32 ) | e->val_lo32; +/* struct btf_enum64 is introduced in Linux 6.0, which is very +* bleeding-edge. Here we are avoiding relying on struct btf_enum64 +* definition coming from kernel UAPI headers to support wider range +* of system-wide kernel headers. +* +* Given this header can be also included from C++ applications, that +* further restricts C tricks we can use (like using compatible +* anonymous struct). So just treat struct btf_enum64 as +* a three-element array of u32 and access second (lo32) and third +* (hi32) elements directly. +* +* For reference, here is a struct btf_enum64 definition: +* +* const struct btf_enum64 { +* __u32 name_off; +* __u32 val_lo32; +* __u32 val_hi32; +* }; +*/ +const __u32 *e64 = (const __u32 *)e; + +return ((__u64 )e64[2 ] <<32 ) | e64[1 ]; }static inline struct btf_member *btf_members (const struct btf_type *t)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 320/862 i2c: mlxbf: support lock mechanism
In reply to Greg Kroah-HartmanFrom: Asmaa Mnebhi <[email protected]>
[ Upstream commit 86067ccfa1424a26491542d6f6d7546d40b61a10 ]
Linux is not the only entity using the BlueField I2C busses so support a lock mechanism provided by hardware to avoid issues when multiple entities are trying to access the same bus.
The lock is acquired whenever written explicitely or the lock register is read. So make sure it is always released at the end of a successful or failed transaction.
--- drivers/i2c/busses/i2c-mlxbf.c | 44 ++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 5 deletions(-)
drivers/i2c/busses/i2c-mlxbf.c +39 -5
@@ -306,6 +306,7 @@ static u64 mlxbf_i2c_corepll_frequency;* exact. */ #define MLXBF_I2C_SMBUS_TIMEOUT (300 * 1000)/* 300ms */ +#define MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT (300 * 1000)/* 300ms */ /* Encapsulates timing parameters. */ struct mlxbf_i2c_timings {
@@ -514,6 +515,25 @@ static bool mlxbf_smbus_master_wait_for_idle(struct mlxbf_i2c_priv *priv)return false; } +/* +* wait for the lock to be released before acquiring it. +*/ +static bool mlxbf_i2c_smbus_master_lock (struct mlxbf_i2c_priv *priv) +{ +if (mlxbf_smbus_poll (priv->smbus->io,MLXBF_I2C_SMBUS_MASTER_GW , +MLXBF_I2C_MASTER_LOCK_BIT , true, +MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT )) +return true; + +return false; +} + +static void mlxbf_i2c_smbus_master_unlock (struct mlxbf_i2c_priv *priv) +{ +/* Clear the gw to clear the lock */ +writel (0 , priv->smbus->io +MLXBF_I2C_SMBUS_MASTER_GW ); +} +static bool mlxbf_i2c_smbus_transaction_success (u32 master_status,u32 cause_status) {
@@ -705,10 +725,19 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, slave = request->slave &GENMASK (6 ,0 ); addr = slave <<1 ; -/* First of all, check whether the HW is idle. */ -if (WARN_ON (!mlxbf_smbus_master_wait_for_idle (priv))) +/* +* Try to acquire the smbus gw lock before any reads of the GW register since +* a read sets the lock. +*/ +if (WARN_ON (!mlxbf_i2c_smbus_master_lock (priv)))return -EBUSY ; +/* Check whether the HW is idle */ +if (WARN_ON (!mlxbf_smbus_master_wait_for_idle (priv))) { + ret = -EBUSY ; + goto out_unlock; + } +/* Set first byte. */ data_desc[data_idx++] = addr;
@@ -732,8 +761,10 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, write_en =1 ; write_len += operation->length;if (data_idx + operation->length > -MLXBF_I2C_MASTER_DATA_DESC_SIZE ) -return -ENOBUFS ; +MLXBF_I2C_MASTER_DATA_DESC_SIZE ) { + ret = -ENOBUFS ; + goto out_unlock; + }memcpy (data_desc + data_idx, operation->buffer, operation->length); data_idx += operation->length;
@@ -765,7 +796,7 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, ret =mlxbf_i2c_smbus_enable (priv, slave, write_len, block_en, pec_en,0 );if (ret) -return ret; + goto out_unlock; }if (read_en) {
@@ -792,6 +823,9 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_FSM); } +out_unlock: +mlxbf_i2c_smbus_master_unlock (priv); +return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 321/862 Bluetooth: hci_core: Fix not handling link timeouts propertly
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 116523c8fac05d1d26f748fee7919a4ec5df67ea ]
Change that introduced the use of __check_timeout did not account for link types properly, it always assumes ACL_LINK is used thus causing hdev->acl_last_tx to be used even in case of LE_LINK and then again uses ACL_LINK with hci_link_tx_to.
To fix this __check_timeout now takes the link type as parameter and then procedure to use the right last_tx based on the link type and pass it to hci_link_tx_to.
--- net/bluetooth/hci_core.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-)
net/bluetooth/hci_core.c +23 -11
@@ -3478,15 +3478,27 @@ static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)return DIV_ROUND_UP (skb->len -HCI_ACL_HDR_SIZE , hdev->block_len); } -static void __check_timeout (struct hci_dev *hdev,unsigned int cnt) +static void __check_timeout (struct hci_dev *hdev,unsigned int cnt,u8 type) { -if (!hci_dev_test_flag (hdev,HCI_UNCONFIGURED )) { -/* ACL tx timeout must be longer than maximum -* link supervision timeout (40.9 seconds) */ -if (!cnt &&time_after (jiffies, hdev->acl_last_tx + -HCI_ACL_TX_TIMEOUT )) -hci_link_tx_to (hdev,ACL_LINK ); +unsigned long last_tx; + +if (hci_dev_test_flag (hdev,HCI_UNCONFIGURED )) +return ; + +switch (type) { +case LE_LINK : + last_tx = hdev->le_last_tx; +break ; +default : + last_tx = hdev->acl_last_tx; +break ; } + +/* tx timeout must be longer than maximum link supervision timeout +* (40.9 seconds) +*/ +if (!cnt &&time_after (jiffies, last_tx +HCI_ACL_TX_TIMEOUT )) +hci_link_tx_to (hdev, type); }/* Schedule SCO */
@@ -3544,7 +3556,7 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev)struct sk_buff *skb;int quote; -__check_timeout (hdev, cnt); +__check_timeout (hdev, cnt,ACL_LINK );while (hdev->acl_cnt && (chan =hci_chan_sent (hdev,ACL_LINK , "e))) {
@@ -3587,8 +3599,6 @@ static void hci_sched_acl_blk(struct hci_dev *hdev)int quote;u8 type; -__check_timeout (hdev, cnt); -BT_DBG ("%s" , hdev->name);if (hdev->dev_type ==HCI_AMP )
@@ -3596,6 +3606,8 @@ static void hci_sched_acl_blk(struct hci_dev *hdev)else type =ACL_LINK ; +__check_timeout (hdev, cnt, type); +while (hdev->block_cnt >0 && (chan =hci_chan_sent (hdev, type, "e))) {u32 priority = (skb_peek (&chan->data_q))->priority;
@@ -3669,7 +3681,7 @@ static void hci_sched_le(struct hci_dev *hdev) cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; -__check_timeout (hdev, cnt); +__check_timeout (hdev, cnt,LE_LINK ); tmp = cnt;while (cnt && (chan =hci_chan_sent (hdev,LE_LINK , "e))) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 322/862 xfrm: Reinject transport-mode packets through workqueue
In reply to Greg Kroah-HartmanFrom: Liu Jian <[email protected]>
[ Upstream commit 4f4920669d21e1060b7243e5118dc3b71ced1276 ]
The following warning is displayed when the tcp6-multi-diffip11 stress test case of the LTP test suite is tested:
watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [ns-tcpserver:48198] CPU: 0 PID: 48198 Comm: ns-tcpserver Kdump: loaded Not tainted 6.0.0-rc6+ #39 Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : des3_ede_encrypt+0x27c/0x460 [libdes] lr : 0x3f
sp : ffff80000ceaa1b0
x29: ffff80000ceaa1b0 x28: ffff0000df056100 x27: ffff0000e51e5280
x26: ffff80004df75030 x25: ffff0000e51e4600 x24: 000000000000003b
x23: 0000000000802080 x22: 000000000000003d x21: 0000000000000038
x20: 0000000080000020 x19: 000000000000000a x18: 0000000000000033
x17: ffff0000e51e4780 x16: ffff80004e2d1448 x15: ffff80004e2d1248
x14: ffff0000e51e4680 x13: ffff80004e2d1348 x12: ffff80004e2d1548
x11: ffff80004e2d1848 x10: ffff80004e2d1648 x9 : ffff80004e2d1748 x8 : ffff80004e2d1948 x7 : 000000000bcaf83d x6 : 000000000000001b x5 : ffff80004e2d1048 x4 : 00000000761bf3bf x3 : 000000007f1dd0a3 x2 : ffff0000e51e4780 x1 : ffff0000e3b9a2f8 x0 : 00000000db44e872
Call trace: des3_ede_encrypt+0x27c/0x460 [libdes] crypto_des3_ede_encrypt+0x1c/0x30 [des_generic] crypto_cbc_encrypt+0x148/0x190 crypto_skcipher_encrypt+0x2c/0x40 crypto_authenc_encrypt+0xc8/0xfc [authenc] crypto_aead_encrypt+0x2c/0x40 echainiv_encrypt+0x144/0x1a0 [echainiv] crypto_aead_encrypt+0x2c/0x40 esp6_output_tail+0x1c8/0x5d0 [esp6] esp6_output+0x120/0x278 [esp6] xfrm_output_one+0x458/0x4ec xfrm_output_resume+0x6c/0x1f0 xfrm_output+0xac/0x4ac __xfrm6_output+0x130/0x270 xfrm6_output+0x60/0xec ip6_xmit+0x2ec/0x5bc inet6_csk_xmit+0xbc/0x10c __tcp_transmit_skb+0x460/0x8c0 tcp_write_xmit+0x348/0x890 __tcp_push_pending_frames+0x44/0x110 tcp_rcv_established+0x3c8/0x720 tcp_v6_do_rcv+0xdc/0x4a0 tcp_v6_rcv+0xc24/0xcb0 ip6_protocol_deliver_rcu+0xf0/0x574 ip6_input_finish+0x48/0x7c ip6_input+0x48/0xc0 ip6_rcv_finish+0x80/0x9c xfrm_trans_reinject+0xb0/0xf4 tasklet_action_common.constprop.0+0xf8/0x134 tasklet_action+0x30/0x3c __do_softirq+0x128/0x368 do_softirq+0xb4/0xc0 __local_bh_enable_ip+0xb0/0xb4 put_cpu_fpsimd_context+0x40/0x70 kernel_neon_end+0x20/0x40 sha1_base_do_update.constprop.0.isra.0+0x11c/0x140 [sha1_ce] sha1_ce_finup+0x94/0x110 [sha1_ce] crypto_shash_finup+0x34/0xc0 hmac_finup+0x48/0xe0 crypto_shash_finup+0x34/0xc0 shash_digest_unaligned+0x74/0x90 crypto_shash_digest+0x4c/0x9c shash_ahash_digest+0xc8/0xf0 shash_async_digest+0x28/0x34 crypto_ahash_digest+0x48/0xcc crypto_authenc_genicv+0x88/0xcc [authenc] crypto_authenc_encrypt+0xd8/0xfc [authenc] crypto_aead_encrypt+0x2c/0x40 echainiv_encrypt+0x144/0x1a0 [echainiv] crypto_aead_encrypt+0x2c/0x40 esp6_output_tail+0x1c8/0x5d0 [esp6] esp6_output+0x120/0x278 [esp6] xfrm_output_one+0x458/0x4ec xfrm_output_resume+0x6c/0x1f0 xfrm_output+0xac/0x4ac __xfrm6_output+0x130/0x270 xfrm6_output+0x60/0xec ip6_xmit+0x2ec/0x5bc inet6_csk_xmit+0xbc/0x10c __tcp_transmit_skb+0x460/0x8c0 tcp_write_xmit+0x348/0x890 __tcp_push_pending_frames+0x44/0x110 tcp_push+0xb4/0x14c tcp_sendmsg_locked+0x71c/0xb64 tcp_sendmsg+0x40/0x6c inet6_sendmsg+0x4c/0x80 sock_sendmsg+0x5c/0x6c __sys_sendto+0x128/0x15c __arm64_sys_sendto+0x30/0x40 invoke_syscall+0x50/0x120 el0_svc_common.constprop.0+0x170/0x194 do_el0_svc+0x38/0x4c el0_svc+0x28/0xe0 el0t_64_sync_handler+0xbc/0x13c el0t_64_sync+0x180/0x184
Get softirq info by bcc tool:
./softirqs -NT 10
Tracing soft irq event time... Hit Ctrl-C to end.
15:34:34
SOFTIRQ TOTAL_nsecs
block 158990
timer 20030920
sched 46577080net_rx 676746820
tasklet 9906067650
15:34:45
SOFTIRQ TOTAL_nsecs
block 86100
sched 38849790net_rx 676532470
timer 1163848790
tasklet 9409019620
15:34:55
SOFTIRQ TOTAL_nsecs
sched 58078450net_rx 475156720
timer 533832410
tasklet 9431333300
The tasklet software interrupt takes too much time. Therefore, the xfrm_trans_reinject executor is changed from tasklet to workqueue. Add add spin lock to protect the queue. This reduces the processing flow of the tcp_sendmsg function in this scenario.
--- net/xfrm/xfrm_input.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
net/xfrm/xfrm_input.c +13 -5
@@ -24,7 +24,8 @@#include "xfrm_inout.h" struct xfrm_trans_tasklet { -struct tasklet_struct tasklet; +struct work_struct work; +spinlock_t queue_lock;struct sk_buff_head queue; };
@@ -760,18 +761,22 @@ int xfrm_input_resume(struct sk_buff *skb, int nexthdr) }EXPORT_SYMBOL (xfrm_input_resume); -static void xfrm_trans_reinject (struct tasklet_struct *t) +static void xfrm_trans_reinject (struct work_struct *work) { -struct xfrm_trans_tasklet *trans =from_tasklet (trans, t, tasklet); + struct xfrm_trans_tasklet *trans = container_of(work, struct xfrm_trans_tasklet, work);struct sk_buff_head queue;struct sk_buff *skb;__skb_queue_head_init (&queue); +spin_lock_bh (&trans->queue_lock);skb_queue_splice_init (&trans->queue, &queue); +spin_unlock_bh (&trans->queue_lock); +local_bh_disable ();while ((skb =__skb_dequeue (&queue)))XFRM_TRANS_SKB_CB (skb)->finish (XFRM_TRANS_SKB_CB (skb)->net,NULL , skb); +local_bh_enable (); } int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
@@ -789,8 +794,10 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,XFRM_TRANS_SKB_CB (skb)->finish = finish;XFRM_TRANS_SKB_CB (skb)->net = net; +spin_lock_bh (&trans->queue_lock);__skb_queue_tail (&trans->queue, skb); -tasklet_schedule (&trans->tasklet); +spin_unlock_bh (&trans->queue_lock); +schedule_work (&trans->work);return 0 ; }EXPORT_SYMBOL (xfrm_trans_queue_net);
@@ -817,7 +824,8 @@ void __init xfrm_input_init(void)struct xfrm_trans_tasklet *trans; trans = &per_cpu (xfrm_trans_tasklet, i); +spin_lock_init (&trans->queue_lock);__skb_queue_head_init (&trans->queue); -tasklet_setup (&trans->tasklet, xfrm_trans_reinject); +INIT_WORK (&trans->work, xfrm_trans_reinject); } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 323/862 netfilter: nft_fib: Fix for rpath check with VRF devices
In reply to Greg Kroah-HartmanFrom: Phil Sutter <[email protected]>
[ Upstream commit 2a8a7c0eaa8747c16aa4a48d573aa920d5c00a5c ]
Analogous to commit b575b24b8eee3 ("netfilter: Fix rpfilter dropping vrf packets by mistake") but for nftables fib expression:
Add special treatment of VRF devices so that typical reverse path filtering via 'fib saddr . iif oif' expression works as expected.
--- net/ipv4/netfilter/nft_fib_ipv4.c | 3 +++ net/ipv6/netfilter/nft_fib_ipv6.c | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-)
net/ipv4/netfilter/nft_fib_ipv4.c +3 -0
@@ -83,6 +83,9 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,else oif =NULL ; +if (priv->flags &NFTA_FIB_F_IIF ) + fl4.flowi4_oif =l3mdev_master_ifindex_rcu (oif); +if (nft_hook (pkt) ==NF_INET_PRE_ROUTING &&nft_fib_is_loopback (pkt->skb,nft_in (pkt))) {nft_fib_store_result (dest, priv,nft_in (pkt));
net/ipv6/netfilter/nft_fib_ipv6.c +5 -1
@@ -41,6 +41,9 @@ static int nft_fib6_flowi_init(struct flowi6 *fl6, const struct nft_fib *priv,if (ipv6_addr_type (&fl6->daddr) &IPV6_ADDR_LINKLOCAL ) { lookup_flags |=RT6_LOOKUP_F_IFACE ; fl6->flowi6_oif =get_ifindex (dev ? dev : pkt->skb->dev); + }else if ((priv->flags &NFTA_FIB_F_IIF ) && + (netif_is_l3_master (dev) ||netif_is_l3_slave (dev))) { + fl6->flowi6_oif = dev->ifindex; }if (ipv6_addr_type (&fl6->saddr) &IPV6_ADDR_UNICAST )
@@ -197,7 +200,8 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,if (rt->rt6i_flags & (RTF_REJECT |RTF_ANYCAST |RTF_LOCAL )) goto put_rt_err; -if (oif && oif != rt->rt6i_idev->dev) +if (oif && oif != rt->rt6i_idev->dev && +l3mdev_master_ifindex_rcu (rt->rt6i_idev->dev) != oif->ifindex) goto put_rt_err;nft_fib_store_result (dest, priv, rt->rt6i_idev->dev);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 324/862 spi: s3c64xx: Fix large transfers with DMA
In reply to Greg Kroah-HartmanFrom: Vincent Whitchurch <[email protected]>
[ Upstream commit 1224e29572f655facfcd850cf0f0a4784f36a903 ]
The COUNT_VALUE in the PACKET_CNT register is 16-bit so the maximum value is 65535. Asking the driver to transfer a larger size currently leads to the DMA transfer timing out. Implement ->max_transfer_size() and have the core split the transfer as needed.
--- drivers/spi/spi-s3c64xx.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/spi/spi-s3c64xx.c +9 -0
@@ -84,6 +84,7 @@#define S3C64XX_SPI_ST_TX_FIFORDY (1<<0)#define S3C64XX_SPI_PACKET_CNT_EN (1<<16) +#define S3C64XX_SPI_PACKET_CNT_MASK GENMASK(15, 0)#define S3C64XX_SPI_PND_TX_UNDERRUN_CLR (1<<4)#define S3C64XX_SPI_PND_TX_OVERRUN_CLR (1<<3)
@@ -711,6 +712,13 @@ static int s3c64xx_spi_prepare_message(struct spi_master *master,return 0 ; } +static size_t s3c64xx_spi_max_transfer_size (struct spi_device *spi) +{ +struct spi_controller *ctlr = spi->controller; + +return ctlr->can_dma ?S3C64XX_SPI_PACKET_CNT_MASK :SIZE_MAX ; +} +static int s3c64xx_spi_transfer_one (struct spi_master *master,struct spi_device *spi,struct spi_transfer *xfer)
@@ -1152,6 +1160,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer; master->prepare_message = s3c64xx_spi_prepare_message; master->transfer_one = s3c64xx_spi_transfer_one; + master->max_transfer_size = s3c64xx_spi_max_transfer_size; master->num_chipselect = sci->num_cs; master->use_gpio_descriptors = true; master->dma_alignment =8 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 325/862 Bluetooth: Prevent double register of suspend
In reply to Greg Kroah-HartmanFrom: Abhishek Pandit-Subedi <[email protected]>
[ Upstream commit 4b8af331bb4d4cc8bb91c284b11b98dd1e265185 ]
Suspend notifier should only be registered and unregistered once per hdev. Simplify this by only registering during driver registration and simply exiting early when HCI_USER_CHANNEL is set.
--- net/bluetooth/hci_core.c | 4 ++++ net/bluetooth/hci_sock.c | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-)
net/bluetooth/hci_core.c +4 -0
@@ -2400,6 +2400,10 @@ static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action, container_of(nb, struct hci_dev, suspend_notifier);int ret =0 ; +/* Userspace has full control of this device. Do nothing. */ +if (hci_dev_test_flag (hdev,HCI_USER_CHANNEL )) +return NOTIFY_DONE ; +if (action ==PM_SUSPEND_PREPARE ) ret =hci_suspend_dev (hdev);else if (action ==PM_POST_SUSPEND )
net/bluetooth/hci_sock.c +0 -3
@@ -887,7 +887,6 @@ static int hci_sock_release(struct socket *sock)*/ hci_dev_do_close (hdev);hci_dev_clear_flag (hdev,HCI_USER_CHANNEL ); -hci_register_suspend_notifier (hdev);mgmt_index_added (hdev); }
@@ -1216,7 +1215,6 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, }mgmt_index_removed (hdev); -hci_unregister_suspend_notifier (hdev); err =hci_dev_open (hdev->id);if (err) {
@@ -1231,7 +1229,6 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, err =0 ; }else {hci_dev_clear_flag (hdev,HCI_USER_CHANNEL ); -hci_register_suspend_notifier (hdev);mgmt_index_added (hdev);hci_dev_put (hdev); goto done;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 326/862 wifi: rtl8xxxu: gen2: Enable 40 MHz channel width
In reply to Greg Kroah-HartmanFrom: Bitterblue Smith <[email protected]>
[ Upstream commit a8b5aef2cca15b7fa533421d462e4e0a3429bd6f ]
The module parameter ht40_2g was supposed to enable 40 MHz operation, but it didn't.
Tell the firmware about the channel width when updating the rate mask. This makes it work with my gen 2 chip RTL8188FU.
I'm not sure if anything needs to be done for the gen 1 chips, if 40 MHz channel width already works or not. They update the rate mask with a different structure which doesn't have a field for the channel width.
Also set the channel width correctly for sta_statistics.
--- .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 6 +++--- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 21 +++++++++++++------ 2 files changed, 18 insertions(+), 9 deletions(-)
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +3 -3
@@ -1425,7 +1425,7 @@ struct rtl8xxxu_fileops {void (*set_tx_power) (struct rtl8xxxu_priv *priv,int channel,bool ht40);void (*update_rate_mask) (struct rtl8xxxu_priv *priv, -u32 ramask,u8 rateid,int sgi); +u32 ramask,u8 rateid,int sgi,int txbw_40mhz);void (*report_connect) (struct rtl8xxxu_priv *priv,u8 macid,bool connect); void (*fill_txdesc) (struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
@@ -1511,9 +1511,9 @@ void rtl8xxxu_gen2_config_channel(struct ieee80211_hw *hw);void rtl8xxxu_gen1_usb_quirks (struct rtl8xxxu_priv *priv);void rtl8xxxu_gen2_usb_quirks (struct rtl8xxxu_priv *priv);void rtl8xxxu_update_rate_mask (struct rtl8xxxu_priv *priv, -u32 ramask,u8 rateid,int sgi); +u32 ramask,u8 rateid,int sgi,int txbw_40mhz);void rtl8xxxu_gen2_update_rate_mask (struct rtl8xxxu_priv *priv, -u32 ramask,u8 rateid,int sgi); +u32 ramask,u8 rateid,int sgi,int txbw_40mhz);void rtl8xxxu_gen1_report_connect (struct rtl8xxxu_priv *priv,u8 macid,bool connect); void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +15 -6
@@ -4320,7 +4320,7 @@ static void rtl8xxxu_sw_scan_complete(struct ieee80211_hw *hw, }void rtl8xxxu_update_rate_mask (struct rtl8xxxu_priv *priv, -u32 ramask,u8 rateid,int sgi) +u32 ramask,u8 rateid,int sgi,int txbw_40mhz) {struct h2c_cmd h2c;
@@ -4340,10 +4340,15 @@ void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv, }void rtl8xxxu_gen2_update_rate_mask (struct rtl8xxxu_priv *priv, -u32 ramask,u8 rateid,int sgi) +u32 ramask,u8 rateid,int sgi,int txbw_40mhz) {struct h2c_cmd h2c; -u8 bw =RTL8XXXU_CHANNEL_WIDTH_20 ; +u8 bw; + +if (txbw_40mhz) + bw =RTL8XXXU_CHANNEL_WIDTH_40 ; +else + bw =RTL8XXXU_CHANNEL_WIDTH_20 ;memset (&h2c,0 ,sizeof (struct h2c_cmd ));
@@ -4621,7 +4626,11 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,RATE_INFO_FLAGS_SHORT_GI ; } - rarpt->txrate.bw |=RATE_INFO_BW_20 ; +if (rtl8xxxu_ht40_2g && + (sta->deflink.ht_cap.cap &IEEE80211_HT_CAP_SUP_WIDTH_20_40 )) + rarpt->txrate.bw =RATE_INFO_BW_40 ; +else + rarpt->txrate.bw =RATE_INFO_BW_20 ; } bit_rate =cfg80211_calculate_bitrate (&rarpt->txrate); rarpt->bit_rate = bit_rate;
@@ -4630,7 +4639,7 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, priv->vif = vif; priv->rssi_level =RTL8XXXU_RATR_STA_INIT ; - priv->fops->update_rate_mask (priv, ramask,0 , sgi); + priv->fops->update_rate_mask (priv, ramask,0 , sgi, rarpt->txrate.bw ==RATE_INFO_BW_40 );rtl8xxxu_write8 (priv,REG_BCN_MAX_ERR ,0xff );
@@ -6344,7 +6353,7 @@ static void rtl8xxxu_refresh_rate_mask(struct rtl8xxxu_priv *priv, } priv->rssi_level = rssi_level; - priv->fops->update_rate_mask (priv, rate_bitmap, ratr_idx, sgi); + priv->fops->update_rate_mask (priv, rate_bitmap, ratr_idx, sgi, txbw_40mhz); } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 327/862 wifi: rtl8xxxu: Fix AIFS written to REG_EDCA_*_PARAM
In reply to Greg Kroah-HartmanFrom: Bitterblue Smith <[email protected]>
[ Upstream commit 5574d3290449916397f3092dcd2bac92415498e1 ]
ieee80211_tx_queue_params.aifs is not supposed to be written directly to the REG_EDCA_*_PARAM registers. Instead process it like the vendor drivers do. It's kinda hacky but it works.
This change boosts the download speed and makes it more stable.
Tested with RTL8188FU but all the other supported chips should also benefit.
--- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+)
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +49 -0
@@ -4560,6 +4560,53 @@ rtl8xxxu_wireless_mode(struct ieee80211_hw *hw, struct ieee80211_sta *sta)return network_type; } +static void rtl8xxxu_set_aifs (struct rtl8xxxu_priv *priv,u8 slot_time) +{ +u32 reg_edca_param[IEEE80211_NUM_ACS ] = { + [IEEE80211_AC_VO ] =REG_EDCA_VO_PARAM , + [IEEE80211_AC_VI ] =REG_EDCA_VI_PARAM , + [IEEE80211_AC_BE ] =REG_EDCA_BE_PARAM , + [IEEE80211_AC_BK ] =REG_EDCA_BK_PARAM , + }; +u32 val32; +u16 wireless_mode =0 ; +u8 aifs, aifsn, sifs; +int i; + +if (priv->vif) { +struct ieee80211_sta *sta; + +rcu_read_lock (); + sta =ieee80211_find_sta (priv->vif, priv->vif->bss_conf.bssid); +if (sta) + wireless_mode =rtl8xxxu_wireless_mode (priv->hw, sta); +rcu_read_unlock (); + } + +if (priv->hw->conf.chandef.chan->band ==NL80211_BAND_5GHZ || + (wireless_mode &WIRELESS_MODE_N_24G )) + sifs =16 ; +else + sifs =10 ; + +for (i =0 ; i <IEEE80211_NUM_ACS ; i++) { + val32 =rtl8xxxu_read32 (priv, reg_edca_param[i]); + +/* It was set in conf_tx. */ + aifsn = val32 &0xff ; + +/* aifsn not set yet or already fixed */ +if (aifsn <2 || aifsn >15 ) +continue ; + + aifs = aifsn * slot_time + sifs; + + val32 &= ~0xff ; + val32 |= aifs; +rtl8xxxu_write32 (priv, reg_edca_param[i], val32); + } +} +static void rtl8xxxu_bss_info_changed (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_bss_conf *bss_conf,u64 changed)
@@ -4679,6 +4726,8 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,else val8 =20 ;rtl8xxxu_write8 (priv,REG_SLOT , val8); + +rtl8xxxu_set_aifs (priv, val8); }if (changed &BSS_CHANGED_BSSID ) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 328/862 vhost/vsock: Use kvmalloc/kvfree for larger packets.
In reply to Greg Kroah-HartmanFrom: Junichi Uekawa <[email protected]>
[ Upstream commit 0e3f72931fc47bb81686020cc643cde5d9cd0bb8 ]
When copying a large file over sftp over vsock, data size is usually 32kB, and kmalloc seems to fail to try to allocate 32 32kB regions.
vhost-5837: page allocation failure: order:4, mode:0x24040c0
Call Trace: [<ffffffffb6a0df64>] dump_stack+0x97/0xdb [<ffffffffb68d6aed>] warn_alloc_failed+0x10f/0x138 [<ffffffffb68d868a>] ? __alloc_pages_direct_compact+0x38/0xc8 [<ffffffffb664619f>] __alloc_pages_nodemask+0x84c/0x90d [<ffffffffb6646e56>] alloc_kmem_pages+0x17/0x19 [<ffffffffb6653a26>] kmalloc_order_trace+0x2b/0xdb [<ffffffffb66682f3>] __kmalloc+0x177/0x1f7 [<ffffffffb66e0d94>] ? copy_from_iter+0x8d/0x31d [<ffffffffc0689ab7>] vhost_vsock_handle_tx_kick+0x1fa/0x301 [vhost_vsock] [<ffffffffc06828d9>] vhost_worker+0xf7/0x157 [vhost] [<ffffffffb683ddce>] kthread+0xfd/0x105 [<ffffffffc06827e2>] ? vhost_dev_set_owner+0x22e/0x22e [vhost] [<ffffffffb683dcd1>] ? flush_kthread_worker+0xf3/0xf3 [<ffffffffb6eb332e>] ret_from_fork+0x4e/0x80 [<ffffffffb683dcd1>] ? flush_kthread_worker+0xf3/0xf3
Work around by doing kvmalloc instead.
--- drivers/vhost/vsock.c | 2 +- net/vmw_vsock/virtio_transport_common.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/vhost/vsock.c +1 -1
@@ -393,7 +393,7 @@ vhost_vsock_alloc_pkt(struct vhost_virtqueue *vq,return NULL ; } - pkt->buf =kmalloc (pkt->len,GFP_KERNEL ); + pkt->buf =kvmalloc (pkt->len,GFP_KERNEL );if (!pkt->buf) {kfree (pkt);return NULL ;
net/vmw_vsock/virtio_transport_common.c +1 -1
@@ -1342,7 +1342,7 @@ EXPORT_SYMBOL_GPL(virtio_transport_recv_pkt);void virtio_transport_free_pkt (struct virtio_vsock_pkt *pkt) { -kfree (pkt->buf); +kvfree (pkt->buf);kfree (pkt); }EXPORT_SYMBOL_GPL (virtio_transport_free_pkt);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 329/862 eth: alx: take rtnl_lock on resume
In reply to Greg Kroah-HartmanFrom: Jakub Kicinski <[email protected]>
[ Upstream commit 6ad1c94e1e7e374d88f0cfd77936dddb8339aaba ]
Zbynek reports that alx trips an rtnl assertion on resume:
RTNL: assertion failed at net/core/dev.c (2891)
RIP: 0010:netif_set_real_num_tx_queues+0x1ac/0x1c0 Call Trace: <TASK> __alx_open+0x230/0x570 [alx] alx_resume+0x54/0x80 [alx] ? pci_legacy_resume+0x80/0x80 dpm_run_callback+0x4a/0x150 device_resume+0x8b/0x190 async_resume+0x19/0x30 async_run_entry_fn+0x30/0x130 process_one_work+0x1e5/0x3b0
indeed the driver does not hold rtnl_lock during its internal close and re-open functions during suspend/resume. Note that this is not a huge bug as the driver implements its own locking, and does not implement changing the number of queues, but we need to silence the splat.
--- drivers/net/ethernet/atheros/alx/main.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/ethernet/atheros/alx/main.c +5 -0
@@ -1912,11 +1912,14 @@ static int alx_suspend(struct device *dev)if (!netif_running (alx->dev))return 0 ; + +rtnl_lock ();netif_device_detach (alx->dev);mutex_lock (&alx->mtx);__alx_stop (alx);mutex_unlock (&alx->mtx); +rtnl_unlock ();return 0 ; }
@@ -1927,6 +1930,7 @@ static int alx_resume(struct device *dev)struct alx_hw *hw = &alx->hw;int err; +rtnl_lock ();mutex_lock (&alx->mtx);alx_reset_phy (hw);
@@ -1943,6 +1947,7 @@ static int alx_resume(struct device *dev) unlock:mutex_unlock (&alx->mtx); +rtnl_unlock ();return err; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 330/862 mISDN: fix use-after-free bugs in l1oip timer handlers
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit 2568a7e0832ee30b0a351016d03062ab4e0e0a3f ]
The l1oip_cleanup() traverses the l1oip_ilist and calls release_card() to cleanup module and stack. However, release_card() calls del_timer() to delete the timers such as keep_tl and timeout_tl. If the timer handler is running, the del_timer() will not stop it and result in UAF bugs. One of the processes is shown below:
(cleanup routine) | (timer handler)
release_card() | l1oip_timeout()
... |
del_timer() | ...
... |
kfree(hc) //FREE |
| hc->timeout_on = 0 //USEFix by calling del_timer_sync() in release_card(), which makes sure the timer handlers have finished before the resources, such as l1oip and so on, have been deallocated.
What's more, the hc->workq and hc->socket_thread can kick those timers right back in. We add a bool flag to show if card is released. Then, check this flag in hc->workq and hc->socket_thread.
--- drivers/isdn/mISDN/l1oip.h | 1 + drivers/isdn/mISDN/l1oip_core.c | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-)
drivers/isdn/mISDN/l1oip.h +1 -0
@@ -59,6 +59,7 @@ struct l1oip {int bundle;/* bundle channels in one frm */ int codec;/* codec to use for transmis. */ int limit;/* limit number of bchannels */ +bool shutdown;/* if card is released */ /* timer */ struct timer_list keep_tl;
drivers/isdn/mISDN/l1oip_core.c +7 -6
@@ -275,7 +275,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, p = frame;/* restart timer */ -if (time_before (hc->keep_tl.expires, jiffies +5 *HZ )) +if (time_before (hc->keep_tl.expires, jiffies +5 *HZ ) && !hc->shutdown)mod_timer (&hc->keep_tl, jiffies +L1OIP_KEEPALIVE *HZ );else hc->keep_tl.expires = jiffies +L1OIP_KEEPALIVE *HZ ;
@@ -601,7 +601,9 @@ l1oip_socket_parse(struct l1oip *hc, struct sockaddr_in *sin, u8 *buf, int len) goto multiframe;/* restart timer */ -if (time_before (hc->timeout_tl.expires, jiffies +5 *HZ ) || !hc->timeout_on) { +if ((time_before (hc->timeout_tl.expires, jiffies +5 *HZ ) || + !hc->timeout_on) && + !hc->shutdown) { hc->timeout_on =1 ;mod_timer (&hc->timeout_tl, jiffies +L1OIP_TIMEOUT *HZ ); }else /* only adjust timer */
@@ -1232,11 +1234,10 @@ release_card(struct l1oip *hc) {int ch; -if (timer_pending (&hc->keep_tl)) -del_timer (&hc->keep_tl); + hc->shutdown = true; -if (timer_pending (&hc->timeout_tl)) -del_timer (&hc->timeout_tl); +del_timer_sync (&hc->keep_tl); +del_timer_sync (&hc->timeout_tl);cancel_work_sync (&hc->workq);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 331/862 sctp: handle the error returned from sctp_auth_asoc_init_active_key
In reply to Greg Kroah-HartmanFrom: Xin Long <[email protected]>
[ Upstream commit 022152aaebe116a25c39818a07e175a8cd3c1e11 ]
When it returns an error from sctp_auth_asoc_init_active_key(), the active_key is actually not updated. The old sh_key will be freeed while it's still used as active key in asoc. Then an use-after-free will be triggered when sending patckets, as found by syzbot:
sctp_auth_shkey_hold+0x22/0xa0 net/sctp/auth.c:112 sctp_set_owner_w net/sctp/socket.c:132 [inline] sctp_sendmsg_to_asoc+0xbd5/0x1a20 net/sctp/socket.c:1863 sctp_sendmsg+0x1053/0x1d50 net/sctp/socket.c:2025 inet_sendmsg+0x99/0xe0 net/ipv4/af_inet.c:819 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg+0xcf/0x120 net/socket.c:734
This patch is to fix it by not replacing the sh_key when it returns errors from sctp_auth_asoc_init_active_key() in sctp_auth_set_key(). For sctp_auth_set_active_key(), old active_key_id will be set back to asoc->active_key_id when the same thing happens.
--- net/sctp/auth.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
net/sctp/auth.c +14 -4
@@ -863,12 +863,17 @@ int sctp_auth_set_key(struct sctp_endpoint *ep, }list_del_init (&shkey->key_list); -sctp_auth_shkey_release (shkey);list_add (&cur_key->key_list, sh_keys); -if (asoc && asoc->active_key_id == auth_key->sca_keynumber) -sctp_auth_asoc_init_active_key (asoc,GFP_KERNEL ); +if (asoc && asoc->active_key_id == auth_key->sca_keynumber && +sctp_auth_asoc_init_active_key (asoc,GFP_KERNEL )) { +list_del_init (&cur_key->key_list); +sctp_auth_shkey_release (cur_key); +list_add (&shkey->key_list, sh_keys); +return -ENOMEM ; + } +sctp_auth_shkey_release (shkey);return 0 ; }
@@ -902,8 +907,13 @@ int sctp_auth_set_active_key(struct sctp_endpoint *ep,return -EINVAL ;if (asoc) { +__u16 active_key_id = asoc->active_key_id; + asoc->active_key_id = key_id; -sctp_auth_asoc_init_active_key (asoc,GFP_KERNEL ); +if (sctp_auth_asoc_init_active_key (asoc,GFP_KERNEL )) { + asoc->active_key_id = active_key_id; +return -ENOMEM ; + } }else ep->active_key_id = key_id;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 332/862 tcp: fix tcp_cwnd_validate() to not forget is_cwnd_limited
In reply to Greg Kroah-HartmanFrom: Neal Cardwell <[email protected]>
[ Upstream commit f4ce91ce12a7c6ead19b128ffa8cff6e3ded2a14 ]
This commit fixes a bug in the tracking of max_packets_out and is_cwnd_limited. This bug can cause the connection to fail to remember that is_cwnd_limited is true, causing the connection to fail to grow cwnd when it should, causing throughput to be lower than it should be.
The following event sequence is an example that triggers the bug:
(a) The connection is cwnd_limited, but packets_out is not at its peak due to TSO deferral deciding not to send another skb yet. In such cases the connection can advance max_packets_seq and set tp->is_cwnd_limited to true and max_packets_out to a small number.
(b) Then later in the round trip the connection is pacing-limited (not cwnd-limited), and packets_out is larger. In such cases the connection would raise max_packets_out to a bigger number but (unexpectedly) flip tp->is_cwnd_limited from true to false.
This commit fixes that bug.
One straightforward fix would be to separately track (a) the next window after max_packets_out reaches a maximum, and (b) the next window after tp->is_cwnd_limited is set to true. But this would require consuming an extra u32 sequence number.
Instead, to save space we track only the most important information. Specifically, we track the strongest available signal of the degree to which the cwnd is fully utilized:
(1) If the connection is cwnd-limited then we remember that fact for the current window.
(2) If the connection not cwnd-limited then we track the maximum number of outstanding packets in the current window.
In particular, note that the new logic cannot trigger the buggy (a)/(b) sequence above because with the new logic a condition where tp->packets_out > tp->max_packets_out can only trigger an update of tp->is_cwnd_limited if tp->is_cwnd_limited is false.
This first showed up in a testing of a BBRv2 dev branch, but this buggy behavior highlighted a general issue with the tcp_cwnd_validate() logic that can cause cwnd to fail to increase at the proper rate for any TCP congestion control, including Reno or CUBIC.
--- include/linux/tcp.h | 2 +- include/net/tcp.h | 5 ++++- net/ipv4/tcp.c | 2 ++ net/ipv4/tcp_output.c | 19 ++++++++++++------- 4 files changed, 19 insertions(+), 9 deletions(-)
include/linux/tcp.h +1 -1
@@ -295,7 +295,7 @@ struct tcp_sock {u32 packets_out;/* Packets which are "in flight" */ u32 retrans_out;/* Retransmitted packets out */ u32 max_packets_out;/* max packets_out in last window */ -u32 max_packets_seq;/* right edge of max_packets_out flight */ +u32 cwnd_usage_seq;/* right edge of cwnd usage tracking flight */ u16 urg_data;/* Saved octet of OOB data and control flags */ u8 ecn_flags;/* ECN status bits. */
include/net/tcp.h +4 -1
@@ -1295,11 +1295,14 @@ static inline bool tcp_is_cwnd_limited(const struct sock *sk) {const struct tcp_sock *tp =tcp_sk (sk); +if (tp->is_cwnd_limited) +return true; +/* If in slow start, ensure cwnd grows to twice what was ACKed. */ if (tcp_in_slow_start (tp))return tcp_snd_cwnd (tp) <2 * tp->max_packets_out; -return tp->is_cwnd_limited; +return false; }/* BBR congestion control needs pacing.
net/ipv4/tcp.c +2 -0
@@ -3137,6 +3137,8 @@ int tcp_disconnect(struct sock *sk, int flags) tp->snd_ssthresh =TCP_INFINITE_SSTHRESH ;tcp_snd_cwnd_set (tp,TCP_INIT_CWND ); tp->snd_cwnd_cnt =0 ; + tp->is_cwnd_limited =0 ; + tp->max_packets_out =0 ; tp->window_clamp =0 ; tp->delivered =0 ; tp->delivered_ce =0 ;
net/ipv4/tcp_output.c +12 -7
@@ -1875,15 +1875,20 @@ static void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited)const struct tcp_congestion_ops *ca_ops =inet_csk (sk)->icsk_ca_ops;struct tcp_sock *tp =tcp_sk (sk); -/* Track the maximum number of outstanding packets in each -* window, and remember whether we were cwnd-limited then. +/* Track the strongest available signal of the degree to which the cwnd +* is fully utilized. If cwnd-limited then remember that fact for the +* current window. If not cwnd-limited then track the maximum number of +* outstanding packets in the current window. (If cwnd-limited then we +* chose to not update tp->max_packets_out to avoid an extra else +* clause with no functional impact.) */ -if (!before (tp->snd_una, tp->max_packets_seq) || - tp->packets_out > tp->max_packets_out || - is_cwnd_limited) { - tp->max_packets_out = tp->packets_out; - tp->max_packets_seq = tp->snd_nxt; +if (!before (tp->snd_una, tp->cwnd_usage_seq) || + is_cwnd_limited || + (!tp->is_cwnd_limited && + tp->packets_out > tp->max_packets_out)) { tp->is_cwnd_limited = is_cwnd_limited; + tp->max_packets_out = tp->packets_out; + tp->cwnd_usage_seq = tp->snd_nxt; }if (tcp_is_cwnd_limited (sk)) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 333/862 spi: Ensure that sg_table wont be used after being freed
In reply to Greg Kroah-HartmanFrom: Marek Szyprowski <[email protected]>
[ Upstream commit 8e9204cddcc3fea9affcfa411715ba4f66e97587 ]
SPI code checks for non-zero sgt->orig_nents to determine if the buffer has been DMA-mapped. Ensure that sg_table is really zeroed after free to avoid potential NULL pointer dereference if the given SPI xfer object is reused again without being DMA-mapped.
--- drivers/spi/spi.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/spi/spi.c +2 -0
@@ -1097,6 +1097,8 @@ void spi_unmap_buf(struct spi_controller *ctlr, struct device *dev,if (sgt->orig_nents) {dma_unmap_sg (dev, sgt->sgl, sgt->orig_nents, dir);sg_free_table (sgt); + sgt->orig_nents =0 ; + sgt->nents =0 ; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 334/862 Bluetooth: hci_sync: Fix not indicating power state
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 6abf0dae8c3c927f54e62c46faf8aba580ba0d04 ]
When setting power state using legacy/non-mgmt API
(e.g hcitool hci0 up) the likes of mgmt_set_powered_complete won't be called causing clients of the MGMT API to not be notified of the change of the state.
--- net/bluetooth/hci_sync.c | 1 + 1 file changed, 1 insertion(+)
net/bluetooth/hci_sync.c +1 -0
@@ -4355,6 +4355,7 @@ int hci_dev_open_sync(struct hci_dev *hdev) hci_dev_test_flag(hdev, HCI_MGMT) && hdev->dev_type == HCI_PRIMARY) { ret =hci_powered_update_sync (hdev); +mgmt_power_on (hdev, ret); } }else {/* Init failed, cleanup */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 335/862 hwmon: (pmbus/mp2888) Fix sensors readouts for MPS Multi-phase mp2888 controller
In reply to Greg Kroah-HartmanFrom: Oleksandr Shamray <[email protected]>
[ Upstream commit 525dd5aed67a2f4f7278116fb92a24e6a53e2622 ]
Fix scale factors for reading MPS Multi-phase mp2888 controller. Fixed sensors:
- PIN/POUT: based on vendor documentation, set bscale factor 0.5W/LSB
- IOUT: based on vendor documentation, set scale factor 0.25 A/LSB
--- drivers/hwmon/pmbus/mp2888.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
drivers/hwmon/pmbus/mp2888.c +6 -7
@@ -34,7 +34,7 @@ struct mp2888_data {int curr_sense_gain; }; -#define to_mp2888_data (x) container_of(x, struct mp2888_data, info) +#define to_mp2888_data (x) container_of(x, struct mp2888_data, info)static int mp2888_read_byte_data (struct i2c_client *client,int page,int reg) {
@@ -109,7 +109,7 @@ mp2888_read_phase(struct i2c_client *client, struct mp2888_data *data, int page,* - Kcs is the DrMOS current sense gain of power stage, which is obtained from the * register MP2888_MFR_VR_CONFIG1, bits 13-12 with the following selection of DrMOS * (data->curr_sense_gain): -* 00b - 5µA/A, 01b - 8.5µA/A, 10b - 9.7µA/A, 11b - 10µA/A. +* 00b - 8.5µA/A, 01b - 9.7µA/A, 1b - 10µA/A, 11b - 5µA/A. * - Rcs is the internal phase current sense resistor. This parameter depends on hardware * assembly. By default it is set to 1kΩ. In case of different assembly, user should * scale this parameter by dividing it by Rcs.
@@ -118,10 +118,9 @@ mp2888_read_phase(struct i2c_client *client, struct mp2888_data *data, int page,* because sampling of current occurrence of bit weight has a big deviation, especially for * light load. */ - ret =DIV_ROUND_CLOSEST (ret *100 -9800 , data->curr_sense_gain); - ret = (data->phase_curr_resolution) ? ret *2 : ret; + ret =DIV_ROUND_CLOSEST (ret *200 -19600 , data->curr_sense_gain);/* Scale according to total current resolution. */ - ret = (data->total_curr_resolution) ? ret *8 : ret *4 ; + ret = (data->total_curr_resolution) ? ret *2 : ret;return ret; }
@@ -212,7 +211,7 @@ static int mp2888_read_word_data(struct i2c_client *client, int page, int phase, ret =pmbus_read_word_data (client, page, phase, reg);if (ret <0 )return ret; - ret = data->total_curr_resolution ? ret *2 : ret; + ret = data->total_curr_resolution ? ret :DIV_ROUND_CLOSEST (ret,2 );break ;case PMBUS_POUT_OP_WARN_LIMIT : ret =pmbus_read_word_data (client, page, phase, reg);
@@ -223,7 +222,7 @@ static int mp2888_read_word_data(struct i2c_client *client, int page, int phase,* set 1. Actual power is reported with 0.5W or 1W respectively resolution. Scaling * is needed to match both. */ - ret = data->total_curr_resolution ? ret *4 : ret *2 ; + ret = data->total_curr_resolution ? ret *2 : ret;break ;/* * The below registers are not implemented by device or implemented not according to the
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 336/862 net: rds: dont hold sock lock when cancelling work from rds_tcp_reset_callbacks()
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
[ Upstream commit a91b750fd6629354460282bbf5146c01b05c4859 ]
syzbot is reporting lockdep warning at rds_tcp_reset_callbacks() [1], for commit ac3615e7f3cffe2a ("RDS: TCP: Reduce code duplication in rds_tcp_reset_callbacks()") added cancel_delayed_work_sync() into a section protected by lock_sock() without realizing that rds_send_xmit() might call lock_sock().
We don't need to protect cancel_delayed_work_sync() using lock_sock(), for even if rds_{send,recv}_worker() re-queued this work while __flush_work()
from cancel_delayed_work_sync() was waiting for this work to complete,
retried rds_{send,recv}_worker() is no-op due to the absence of RDS_CONN_UP bit.
--- net/rds/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/rds/tcp.c +1 -1
@@ -166,10 +166,10 @@ void rds_tcp_reset_callbacks(struct socket *sock,*/ atomic_set (&cp->cp_state,RDS_CONN_RESETTING );wait_event (cp->cp_waitq, !test_bit (RDS_IN_XMIT , &cp->cp_flags)); -lock_sock (osock->sk);/* reset receive side state for rds_tcp_data_recv() for osock */ cancel_delayed_work_sync (&cp->cp_send_w);cancel_delayed_work_sync (&cp->cp_recv_w); +lock_sock (osock->sk);if (tc->t_tinc) {rds_inc_put (&tc->t_tinc->ti_inc); tc->t_tinc =NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 337/862 af_unix: Fix memory leaks of the whole sk due to OOB skb.
In reply to Greg Kroah-HartmanFrom: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 7a62ed61367b8fd01bae1e18e30602c25060d824 ]
syzbot reported a sequence of memory leaks, and one of them indicated we failed to free a whole sk:
unreferenced object 0xffff8880126e0000 (size 1088):
comm "syz-executor419", pid 326, jiffies 4294773607 (age 12.609s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 7d 00 00 00 00 00 00 00 ........}.......
01 00 07 40 00 00 00 00 00 00 00 00 00 00 00 00 ...@............
backtrace:
[<000000006fefe750>] sk_prot_alloc+0x64/0x2a0 net/core/sock.c:1970
[<0000000074006db5>] sk_alloc+0x3b/0x800 net/core/sock.c:2029
[<00000000728cd434>] unix_create1+0xaf/0x920 net/unix/af_unix.c:928
[<00000000a279a139>] unix_create+0x113/0x1d0 net/unix/af_unix.c:997
[<0000000068259812>] __sock_create+0x2ab/0x550 net/socket.c:1516
[<00000000da1521e1>] sock_create net/socket.c:1566 [inline]
[<00000000da1521e1>] __sys_socketpair+0x1a8/0x550 net/socket.c:1698
[<000000007ab259e1>] __do_sys_socketpair net/socket.c:1751 [inline]
[<000000007ab259e1>] __se_sys_socketpair net/socket.c:1748 [inline]
[<000000007ab259e1>] __x64_sys_socketpair+0x97/0x100 net/socket.c:1748
[<000000007dedddc1>] do_syscall_x64 arch/x86/entry/common.c:50 [inline]
[<000000007dedddc1>] do_syscall_64+0x38/0x90 arch/x86/entry/common.c:80
[<000000009456679f>] entry_SYSCALL_64_after_hwframe+0x63/0xcdWe can reproduce this issue by creating two AF_UNIX SOCK_STREAM sockets, send()ing an OOB skb to each other, and close()ing them without consuming the OOB skbs.
int skpair[2]; socketpair(AF_UNIX, SOCK_STREAM, 0, skpair); send(skpair[0], "x", 1, MSG_OOB); send(skpair[1], "x", 1, MSG_OOB); close(skpair[0]); close(skpair[1]);
Currently, we free an OOB skb in unix_sock_destructor() which is called via __sk_free(), but it's too late because the receiver's unix_sk(sk)->oob_skb is accounted against the sender's sk->sk_wmem_alloc and __sk_free() is called only when sk->sk_wmem_alloc is 0.
In the repro sequences, we do not consume the OOB skb, so both two sk's sock_put() never reach __sk_free() due to the positive sk->sk_wmem_alloc. Then, no one can consume the OOB skb nor call __sk_free(), and we finally leak the two whole sk.
Thus, we must free the unconsumed OOB skb earlier when close()ing the socket.
--- net/unix/af_unix.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
net/unix/af_unix.c +7 -6
@@ -569,12 +569,6 @@ static void unix_sock_destructor(struct sock *sk)skb_queue_purge (&sk->sk_receive_queue); -#if IS_ENABLED (CONFIG_AF_UNIX_OOB ) -if (u->oob_skb) { -kfree_skb (u->oob_skb); - u->oob_skb =NULL ; - } -#endif DEBUG_NET_WARN_ON_ONCE (refcount_read (&sk->sk_wmem_alloc));DEBUG_NET_WARN_ON_ONCE (!sk_unhashed (sk));DEBUG_NET_WARN_ON_ONCE (sk->sk_socket);
@@ -620,6 +614,13 @@ static void unix_release_sock(struct sock *sk, int embrion)unix_state_unlock (sk); +#if IS_ENABLED (CONFIG_AF_UNIX_OOB ) +if (u->oob_skb) { +kfree_skb (u->oob_skb); + u->oob_skb =NULL ; + } +#endif +wake_up_interruptible_all (&u->peer_wait);if (skpair !=NULL ) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 338/862 net: prestera: acl: Add check for kmemdup
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 9e6fd874c7bb47b6a4295abc4c81b2f41b97e970 ]
As the kemdup could return NULL, it should be better to check the return value and return error if fails.
Moreover, the return value of prestera_acl_ruleset_keymask_set() should be checked by cascade.
--- drivers/net/ethernet/marvell/prestera/prestera_acl.c | 8 ++++++-- drivers/net/ethernet/marvell/prestera/prestera_acl.h | 4 ++-- drivers/net/ethernet/marvell/prestera/prestera_flower.c | 6 +++++- 3 files changed, 13 insertions(+), 5 deletions(-)
drivers/net/ethernet/marvell/prestera/prestera_acl.c +6 -2
@@ -178,10 +178,14 @@ prestera_acl_ruleset_create(struct prestera_acl *acl,return ERR_PTR (err); } -void prestera_acl_ruleset_keymask_set (struct prestera_acl_ruleset *ruleset, -void *keymask) +int prestera_acl_ruleset_keymask_set (struct prestera_acl_ruleset *ruleset, +void *keymask) { ruleset->keymask =kmemdup (keymask,ACL_KEYMASK_SIZE ,GFP_KERNEL ); +if (!ruleset->keymask) +return -ENOMEM ; + +return 0 ; }int prestera_acl_ruleset_offload (struct prestera_acl_ruleset *ruleset)
drivers/net/ethernet/marvell/prestera/prestera_acl.h +2 -2
@@ -185,8 +185,8 @@ struct prestera_acl_ruleset * prestera_acl_ruleset_lookup(struct prestera_acl *acl, struct prestera_flow_block *block, u32 chain_index); -void prestera_acl_ruleset_keymask_set (struct prestera_acl_ruleset *ruleset, -void *keymask); +int prestera_acl_ruleset_keymask_set (struct prestera_acl_ruleset *ruleset, +void *keymask);bool prestera_acl_ruleset_is_offload (struct prestera_acl_ruleset *ruleset);int prestera_acl_ruleset_offload (struct prestera_acl_ruleset *ruleset);void prestera_acl_ruleset_put (struct prestera_acl_ruleset *ruleset);
drivers/net/ethernet/marvell/prestera/prestera_flower.c +5 -1
@@ -452,7 +452,9 @@ int prestera_flower_tmplt_create(struct prestera_flow_block *block, }/* preserve keymask/template to this ruleset */ -prestera_acl_ruleset_keymask_set (ruleset, rule.re_key.match.mask); + err =prestera_acl_ruleset_keymask_set (ruleset, rule.re_key.match.mask); +if (err) + goto err_ruleset_keymask_set;/* skip error, as it is not possible to reject template operation, * so, keep the reference to the ruleset for rules to be added
@@ -468,6 +470,8 @@ int prestera_flower_tmplt_create(struct prestera_flow_block *block,list_add_rcu (&template->list, &block->template_list);return 0 ; +err_ruleset_keymask_set: +prestera_acl_ruleset_put (ruleset); err_ruleset_get:kfree (template); err_malloc:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 339/862 eth: lan743x: reject extts for non-pci11x1x devices
In reply to Greg Kroah-HartmanFrom: Raju Lakkaraju <[email protected]>
[ Upstream commit cb4b12071a4b68df323c339f60805834246b3e9e ]
Remove PTP_PF_EXTTS support for non-PCI11x1x devices since they do not support the PTP-IO Input event triggered timestamping mechanisms added
--- drivers/net/ethernet/microchip/lan743x_ptp.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/ethernet/microchip/lan743x_ptp.c +7 -0
@@ -1049,6 +1049,10 @@ static int lan743x_ptpci_verify_pin_config(struct ptp_clock_info *ptp, enum ptp_pin_function func, unsigned int chan) { +struct lan743x_ptp *lan_ptp = + container_of(ptp, struct lan743x_ptp, ptp_clock_info); +struct lan743x_adapter *adapter = + container_of(lan_ptp, struct lan743x_adapter, ptp);int result =0 ;/* Confirm the requested function is supported. Parameter
@@ -1057,7 +1061,10 @@ static int lan743x_ptpci_verify_pin_config(struct ptp_clock_info *ptp,switch (func) {case PTP_PF_NONE :case PTP_PF_PEROUT : +break ;case PTP_PF_EXTTS : +if (!adapter->is_pci11x1x) + result =-1 ;break ;case PTP_PF_PHYSYNC :default :
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 340/862 bnx2x: fix potential memory leak in bnx2x_tpa_stop()
In reply to Greg Kroah-HartmanFrom: Jianglei Nie <[email protected]>
[ Upstream commit b43f9acbb8942b05252be83ac25a81cec70cc192 ]
bnx2x_tpa_stop() allocates a memory chunk from new_data with bnx2x_frag_alloc(). The new_data should be freed when gets some error. But when "pad + len > fp->rx_buf_size" is true, bnx2x_tpa_stop() returns without releasing the new_data, which will lead to a memory leak.
We should free the new_data with bnx2x_frag_free() when "pad + len > fp->rx_buf_size" is true.
--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +1 -0
@@ -789,6 +789,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,BNX2X_ERR ("skb_put is about to fail... pad %d len %d rx_buf_size %d\n" , pad, len, fp->rx_buf_size);bnx2x_panic (); +bnx2x_frag_free (fp, new_data); return; }#endif
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 341/862 eth: sp7021: fix use after free bug in spl2sw_nvmem_get_mac_address
In reply to Greg Kroah-HartmanFrom: Zheng Wang <[email protected]>
[ Upstream commit 12aece8b01507a2d357a1861f470e83621fbb6f2 ]
This frees "mac" and tries to display its address as part of the error message on the next line. Swap the order.
--- drivers/net/ethernet/sunplus/spl2sw_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/sunplus/spl2sw_driver.c +1 -1
@@ -248,8 +248,8 @@ static int spl2sw_nvmem_get_mac_address(struct device *dev, struct device_node */* Check if mac address is valid */ if (!is_valid_ether_addr (mac)) { -kfree (mac);dev_info (dev,"Invalid mac address in nvmem (%pM)!\n" , mac); +kfree (mac);return -EINVAL ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 342/862 net: wwan: iosm: Call mutex_init before locking it
In reply to Greg Kroah-HartmanFrom: Maxim Mikityanskiy <[email protected]>
[ Upstream commit ba0fbdb95da5ddd8db457ce6ba09d16dd979a294 ]
wwan_register_ops calls wwan_create_default_link, which ends up in the ipc_wwan_newlink callback that locks ipc_wwan->if_mutex. However, this mutex is not yet initialized by that point. Fix it by moving mutex_init above the wwan_register_ops call. This also makes the order of operations in ipc_wwan_init symmetric to ipc_wwan_deinit.
--- drivers/net/wwan/iosm/iosm_ipc_wwan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/wwan/iosm/iosm_ipc_wwan.c +3 -2
@@ -323,15 +323,16 @@ struct iosm_wwan *ipc_wwan_init(struct iosm_imem *ipc_imem, struct device *dev) ipc_wwan->dev = dev; ipc_wwan->ipc_imem = ipc_imem; +mutex_init (&ipc_wwan->if_mutex); +/* WWAN core will create a netdev for the default IP MUX channel */ if (wwan_register_ops (ipc_wwan->dev, &iosm_wwan_ops, ipc_wwan,IP_MUX_SESSION_DEFAULT )) { +mutex_destroy (&ipc_wwan->if_mutex);kfree (ipc_wwan);return NULL ; } -mutex_init (&ipc_wwan->if_mutex); -return ipc_wwan; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 343/862 net/ieee802154: reject zero-sized raw_sendmsg()
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
[ Upstream commit 3a4d061c699bd3eedc80dc97a4b2a2e1af83c6f5 ]
syzbot is hitting skb_assert_len() warning at raw_sendmsg() for ieee802154 socket. What commit dc633700f00f726e ("net/af_packet: check len when min_header_len equals to 0") does also applies to ieee802154 socket.
--- net/ieee802154/socket.c | 3 +++ 1 file changed, 3 insertions(+)
net/ieee802154/socket.c +3 -0
@@ -251,6 +251,9 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)return -EOPNOTSUPP ; } +if (!size) +return -EINVAL ; +lock_sock (sk);if (!sk->sk_bound_dev_if) dev =dev_getfirstbyhwtype (sock_net (sk),ARPHRD_IEEE802154 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 344/862 once: add DO_ONCE_SLOW() for sleepable contexts
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 62c07983bef9d3e78e71189441e1a470f0d1e653 ]
Christophe Leroy reported a ~80ms latency spike
happening at first TCP connect() time.
This is because __inet_hash_connect() uses get_random_once()
to populate a perturbation table which became quite big
after commit 4c2c8f03a5ab ("tcp: increase source port perturb table to 2^16")
get_random_once() uses DO_ONCE(), which block hard irqs for the duration of the operation.
This patch adds DO_ONCE_SLOW() which uses a mutex instead of a spinlock for operations where we prefer to stay in process context.
Then __inet_hash_connect() can use get_random_slow_once() to populate its perturbation table.
--- include/linux/once.h | 28 ++++++++++++++++++++++++++++ lib/once.c | 30 ++++++++++++++++++++++++++++++ net/ipv4/inet_hashtables.c | 4 ++-- 3 files changed, 60 insertions(+), 2 deletions(-)
include/linux/once.h +28 -0
@@ -5,10 +5,18 @@#include <linux/types.h> #include <linux/jump_label.h> +/* Helpers used from arbitrary contexts. +* Hard irqs are blocked, be cautious. +*/ bool __do_once_start (bool *done,unsigned long *flags);void __do_once_done (bool *done,struct static_key_true *once_key,unsigned long *flags,struct module *mod); +/* Variant for process contexts only. */ +bool __do_once_slow_start (bool *done); +void __do_once_slow_done (bool *done,struct static_key_true *once_key, +struct module *mod); +/* Call a function exactly once. The idea of DO_ONCE() is to perform * a function call such as initialization of random seeds, etc, only * once, where DO_ONCE() can live in the fast-path. After @func has
@@ -52,7 +60,27 @@ void __do_once_done(bool *done, struct static_key_true *once_key, ___ret; \ }) +/* Variant of DO_ONCE() for process/sleepable contexts. */ +#define DO_ONCE_SLOW (func, ...) \ + ({ \ + bool ___ret = false; \ + static bool __section(".data.once") ___done = false; \ + static DEFINE_STATIC_KEY_TRUE(___once_key); \ + if (static_branch_unlikely(&___once_key)) { \ + ___ret = __do_once_slow_start(&___done); \ + if (unlikely(___ret)) { \ + func(__VA_ARGS__); \ + __do_once_slow_done(&___done, &___once_key, \ + THIS_MODULE); \ + } \ + } \ + ___ret; \ + }) +#define get_random_once (buf, nbytes) \ DO_ONCE(get_random_bytes, (buf), (nbytes)) +#define get_random_slow_once (buf, nbytes) \ + DO_ONCE_SLOW(get_random_bytes, (buf), (nbytes)) +#endif /* _LINUX_ONCE_H */
lib/once.c +30 -0
@@ -66,3 +66,33 @@ void __do_once_done(bool *done, struct static_key_true *once_key,once_disable_jump (once_key, mod); }EXPORT_SYMBOL (__do_once_done); + +static DEFINE_MUTEX (once_mutex); + +bool __do_once_slow_start (bool *done) +__acquires (once_mutex) +{ +mutex_lock (&once_mutex); +if (*done) { +mutex_unlock (&once_mutex); +/* Keep sparse happy by restoring an even lock count on +* this mutex. In case we return here, we don't call into +* __do_once_done but return early in the DO_ONCE_SLOW() macro. +*/ +__acquire (once_mutex); +return false; + } + +return true; +} +EXPORT_SYMBOL (__do_once_slow_start); + +void __do_once_slow_done (bool *done,struct static_key_true *once_key, +struct module *mod) +__releases (once_mutex) +{ + *done = true; +mutex_unlock (&once_mutex); +once_disable_jump (once_key, mod); +} +EXPORT_SYMBOL (__do_once_slow_done);
net/ipv4/inet_hashtables.c +2 -2
@@ -729,8 +729,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,if (likely (remaining >1 )) remaining &= ~1U ; -net_get_random_once (table_perturb, -INET_TABLE_PERTURB_SIZE *sizeof (*table_perturb)); +get_random_slow_once (table_perturb, +INET_TABLE_PERTURB_SIZE *sizeof (*table_perturb)); index = port_offset & (INET_TABLE_PERTURB_SIZE -1 ); offset =READ_ONCE (table_perturb[index]) + (port_offset >>32 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 345/862 net: mvpp2: fix mvpp2 debugfs leak
In reply to Greg Kroah-HartmanFrom: Russell King (Oracle) <[email protected]>
[ Upstream commit 0152dfee235e87660f52a117fc9f70dc55956bb4 ]
When mvpp2 is unloaded, the driver specific debugfs directory is not removed, which technically leads to a memory leak. However, this directory is only created when the first device is probed, so the hardware is present. Removing the module is only something a developer would to when e.g. testing out changes, so the module would be reloaded. So this memory leak is minor.
The original attempt in commit fe2c9c61f668 ("net: mvpp2: debugfs: fix memory leak when using debugfs_lookup()") that was labelled as a memory leak fix was not, it fixed a refcount leak, but in doing so created a problem when the module is reloaded - the directory already exists, but mvpp2_root is NULL, so we lose all debugfs entries. This fix has been reverted.
This is the alternative fix, where we remove the offending directory whenever the driver is unloaded.
--- drivers/net/ethernet/marvell/mvpp2/mvpp2.h | 1 + drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c | 10 ++++++++-- drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 13 ++++++++++++- 3 files changed, 21 insertions(+), 3 deletions(-)
drivers/net/ethernet/marvell/mvpp2/mvpp2.h +1 -0
@@ -1530,6 +1530,7 @@ u32 mvpp2_read(struct mvpp2 *priv, u32 offset);void mvpp2_dbgfs_init (struct mvpp2 *priv,const char *name);void mvpp2_dbgfs_cleanup (struct mvpp2 *priv); +void mvpp2_dbgfs_exit (void );void mvpp23_rx_fifo_fc_en (struct mvpp2 *priv,int port,bool en);
drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c +8 -2
@@ -691,6 +691,13 @@ static int mvpp2_dbgfs_port_init(struct dentry *parent,return 0 ; } +static struct dentry *mvpp2_root; + +void mvpp2_dbgfs_exit (void ) +{ +debugfs_remove (mvpp2_root); +} +void mvpp2_dbgfs_cleanup (struct mvpp2 *priv) {debugfs_remove_recursive (priv->dbgfs_dir);
@@ -700,10 +707,9 @@ void mvpp2_dbgfs_cleanup(struct mvpp2 *priv)void mvpp2_dbgfs_init (struct mvpp2 *priv,const char *name) { -struct dentry *mvpp2_dir, *mvpp2_root; +struct dentry *mvpp2_dir;int ret, i; - mvpp2_root =debugfs_lookup (MVPP2_DRIVER_NAME ,NULL );if (!mvpp2_root) mvpp2_root =debugfs_create_dir (MVPP2_DRIVER_NAME ,NULL );
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +12 -1
@@ -7706,7 +7706,18 @@ static struct platform_driver mvpp2_driver = { }, }; -module_platform_driver (mvpp2_driver); +static int __init mvpp2_driver_init (void ) +{ +return platform_driver_register (&mvpp2_driver); +} +module_init (mvpp2_driver_init); + +static void __exit mvpp2_driver_exit(void) +{ +platform_driver_unregister (&mvpp2_driver); +mvpp2_dbgfs_exit (); +} +module_exit (mvpp2_driver_exit);MODULE_DESCRIPTION ("Marvell PPv2 Ethernet Driver - www.marvell.com" );MODULE_AUTHOR ("Marcin Wojtas <[email protected]>" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 346/862 drm: bridge: adv7511: fix CEC power down control register offset
In reply to Greg Kroah-HartmanFrom: Alvin Šipraga <[email protected]>
[ Upstream commit 1d22b6033ea113a4c3850dfa2c0770885c81aec8 ]
The ADV7511_REG_CEC_CTRL = 0xE2 register is part of the main register map - not the CEC register map. As such, we shouldn't apply an offset to the register address. Doing so will cause us to address a bogus register for chips with a CEC register map offset (e.g. ADV7533).
--- drivers/gpu/drm/bridge/adv7511/adv7511.h | 5 +---- drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-)
drivers/gpu/drm/bridge/adv7511/adv7511.h +1 -4
@@ -394,10 +394,7 @@ void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1);#else static inline int adv7511_cec_init (struct device *dev,struct adv7511 *adv7511) { -unsigned int offset = adv7511->type ==ADV7533 ? -ADV7533_REG_CEC_OFFSET :0 ; - -regmap_write (adv7511->regmap,ADV7511_REG_CEC_CTRL + offset, +regmap_write (adv7511->regmap,ADV7511_REG_CEC_CTRL ,ADV7511_CEC_CTRL_POWER_DOWN );return 0 ; }
drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +2 -2
@@ -359,7 +359,7 @@ int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) goto err_cec_alloc; } -regmap_write (adv7511->regmap,ADV7511_REG_CEC_CTRL + offset,0 ); +regmap_write (adv7511->regmap,ADV7511_REG_CEC_CTRL ,0 );/* cec soft reset */ regmap_write (adv7511->regmap_cec,ADV7511_REG_CEC_SOFT_RESET + offset,0x01 );
@@ -386,7 +386,7 @@ int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)dev_info (dev,"Initializing CEC failed with error %d, disabling CEC\n" , ret); err_cec_parse_dt: -regmap_write (adv7511->regmap,ADV7511_REG_CEC_CTRL + offset, +regmap_write (adv7511->regmap,ADV7511_REG_CEC_CTRL ,ADV7511_CEC_CTRL_POWER_DOWN );return ret == -EPROBE_DEFER ? ret :0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 347/862 drm: bridge: adv7511: unregister cec i2c device after cec adapter
In reply to Greg Kroah-HartmanFrom: Alvin Šipraga <[email protected]>
[ Upstream commit 40cdb02cb9f965732eb543d47f15bef8d10f0f5f ]
cec_unregister_adapter() assumes that the underlying adapter ops are callable. For example, if the CEC adapter currently has a valid physical address, then the unregistration procedure will invalidate the physical address by setting it to f.f.f.f. Whence the following kernel oops observed after removing the adv7511 module:
Unable to handle kernel execution of user memory at virtual address 0000000000000000
Internal error: Oops: 86000004 [#1] PREEMPT_RT SMP
Call trace:
0x0
adv7511_cec_adap_log_addr+0x1ac/0x1c8 [adv7511]
cec_adap_unconfigure+0x44/0x90 [cec]
__cec_s_phys_addr.part.0+0x68/0x230 [cec]
__cec_s_phys_addr+0x40/0x50 [cec]
cec_unregister_adapter+0xb4/0x118 [cec]
adv7511_remove+0x60/0x90 [adv7511]
i2c_device_remove+0x34/0xe0
device_release_driver_internal+0x114/0x1f0
driver_detach+0x54/0xe0
bus_remove_driver+0x60/0xd8
driver_unregister+0x34/0x60
i2c_del_driver+0x2c/0x68
adv7511_exit+0x1c/0x67c [adv7511]
__arm64_sys_delete_module+0x154/0x288
invoke_syscall+0x48/0x100
el0_svc_common.constprop.0+0x48/0xe8
do_el0_svc+0x28/0x88
el0_svc+0x1c/0x50
el0t_64_sync_handler+0xa8/0xb0
el0t_64_sync+0x15c/0x160
Code: bad PC value
---[ end trace 0000000000000000 ]---Protect against this scenario by unregistering i2c_cec after unregistering the CEC adapter. Duly disable the CEC clock afterwards too.
--- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +2 -3
@@ -1340,9 +1340,6 @@ static int adv7511_remove(struct i2c_client *i2c) {struct adv7511 *adv7511 =i2c_get_clientdata (i2c); -i2c_unregister_device (adv7511->i2c_cec); -clk_disable_unprepare (adv7511->cec_clk); -adv7511_uninit_regulators (adv7511);drm_bridge_remove (&adv7511->bridge);
@@ -1350,6 +1347,8 @@ static int adv7511_remove(struct i2c_client *i2c)adv7511_audio_exit (adv7511);cec_unregister_adapter (adv7511->cec_adap); +i2c_unregister_device (adv7511->i2c_cec); +clk_disable_unprepare (adv7511->cec_clk);i2c_unregister_device (adv7511->i2c_packet);i2c_unregister_device (adv7511->i2c_edid);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 348/862 drm/bridge: Avoid uninitialized variable warning
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 7d1202738efda60155d98b370b3c70d336be0eea ]
This code works, but technically it uses "num_in_bus_fmts" before it has been initialized so it leads to static checker warnings and probably KMEMsan warnings at run time. Initialize the variable to zero to silence the warning.
--- drivers/gpu/drm/drm_bridge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/drm_bridge.c +2 -2
@@ -847,8 +847,8 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, struct drm_connector_state *conn_state, u32 out_bus_fmt) { +unsigned int i, num_in_bus_fmts =0 ;struct drm_bridge_state *cur_state; -unsigned int num_in_bus_fmts, i;struct drm_bridge *prev_bridge;u32 *in_bus_fmts;int ret;
@@ -969,7 +969,7 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,struct drm_connector *conn = conn_state->connector;struct drm_encoder *encoder = bridge->encoder;struct drm_bridge_state *last_bridge_state; -unsigned int i, num_out_bus_fmts; +unsigned int i, num_out_bus_fmts =0 ;struct drm_bridge *last_bridge;u32 *out_bus_fmts;int ret =0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 349/862 drm/mipi-dsi: Detach devices when removing the host
In reply to Greg Kroah-HartmanFrom: Maxime Ripard <[email protected]>
[ Upstream commit 668a8f17b5290d04ef7343636a5588a0692731a1 ]
Whenever the MIPI-DSI host is unregistered, the code of mipi_dsi_host_unregister() loops over every device currently found on that bus and will unregister it.
However, it doesn't detach it from the bus first, which leads to all kind of resource leaks if the host wants to perform some clean up whenever a device is detached.
--- drivers/gpu/drm/drm_mipi_dsi.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/drm_mipi_dsi.c +1 -0
@@ -346,6 +346,7 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv) {struct mipi_dsi_device *dsi =to_mipi_dsi_device (dev); +mipi_dsi_detach (dsi);mipi_dsi_device_unregister (dsi);return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 350/862 drm/vc4: drv: Call component_unbind_all()
In reply to Greg Kroah-HartmanFrom: Maxime Ripard <[email protected]>
[ Upstream commit 6cf61bf49c9bdb9ba2d33be812d90dd406326c6c ]
While we were using the component framework to deal with all the DRM subdevices, we were not calling component_unbind_all().
This leads to none of the subdevices freeing up their resources as part of their unbind() or device managed hooks.
--- drivers/gpu/drm/vc4/vc4_drv.c | 14 ++++++++++++-- drivers/gpu/drm/vc4/vc4_drv.h | 1 + 2 files changed, 13 insertions(+), 2 deletions(-)
drivers/gpu/drm/vc4/vc4_drv.c +12 -2
@@ -267,6 +267,13 @@ static void vc4_match_add_drivers(struct device *dev, } } +static void vc4_component_unbind_all (void *ptr) +{ +struct vc4_dev *vc4 = ptr; + +component_unbind_all (vc4->dev, &vc4->base); +} +static const struct of_device_id vc4_dma_range_matches[] = { { .compatible ="brcm,bcm2711-hvs" }, { .compatible ="brcm,bcm2835-hvs" },
@@ -310,6 +317,7 @@ static int vc4_drm_bind(struct device *dev)if (IS_ERR (vc4))return PTR_ERR (vc4); vc4->is_vc5 = is_vc5; + vc4->dev = dev; drm = &vc4->base;platform_set_drvdata (pdev, drm);
@@ -360,6 +368,10 @@ static int vc4_drm_bind(struct device *dev)if (ret)return ret; + ret =devm_add_action_or_reset (dev, vc4_component_unbind_all, vc4); +if (ret) +return ret; + ret =vc4_plane_create_additional_planes (drm);if (ret) goto unbind_all;
@@ -380,8 +392,6 @@ static int vc4_drm_bind(struct device *dev)return 0 ; unbind_all: -component_unbind_all (dev, drm); -return ret; }
drivers/gpu/drm/vc4/vc4_drv.h +1 -0
@@ -76,6 +76,7 @@ struct vc4_perfmon {struct vc4_dev {struct drm_device base; +struct device *dev;bool is_vc5;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 351/862 drm/bridge: it6505: Power on downstream device in .atomic_enable
In reply to Greg Kroah-HartmanFrom: Pin-Yen Lin <[email protected]>
[ Upstream commit fbc1fdaa8338ec4ebd862d918a0ce3e12033e8a3 ]
Send DPCD DP_SET_POWER_D0 command to the monitor in .atomic_enable callback. Without this command, some monitors won't show up again after changing the resolution.
--- drivers/gpu/drm/bridge/ite-it6505.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/bridge/ite-it6505.c +3 -0
@@ -2945,6 +2945,9 @@ static void it6505_bridge_atomic_enable(struct drm_bridge *bridge,if (ret)dev_err (dev,"Failed to setup AVI infoframe: %d" , ret); +it6505_drm_dp_link_set_power (&it6505->aux, &it6505->link, +DP_SET_POWER_D0 ); +it6505_update_video_parameter (it6505, mode); ret =it6505_send_video_infoframe (it6505, &frame);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 352/862 video/aperture: Disable and unregister sysfb devices via aperture helpers
In reply to Greg Kroah-HartmanFrom: Thomas Zimmermann <[email protected]>
[ Upstream commit 5e01376124309b4dbd30d413f43c0d9c2f60edea ]
Call sysfb_disable() before removing conflicting devices in aperture helpers. Fixes sysfb state if fbdev has been disabled.
--- drivers/video/aperture.c | 14 ++++++++++++++ drivers/video/fbdev/core/fbmem.c | 12 ------------ 2 files changed, 14 insertions(+), 12 deletions(-)
drivers/video/aperture.c +14 -0
@@ -8,6 +8,7 @@#include <linux/pci.h> #include <linux/platform_device.h> #include <linux/slab.h> +#include <linux/sysfb.h> #include <linux/types.h> #include <linux/vgaarb.h>
@@ -286,7 +287,20 @@ int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t si#if IS_REACHABLE (CONFIG_FB )struct apertures_struct *a;int ret; +#endif + +/* +* If a driver asked to unregister a platform device registered by +* sysfb, then can be assumed that this is a driver for a display +* that is set up by the system firmware and has a generic driver. +* +* Drivers for devices that don't have a generic driver will never +* ask for this, so let's assume that a real driver for the display +* was already probed and prevent sysfb to register devices later. +*/ +sysfb_disable (); +#if IS_REACHABLE (CONFIG_FB ) a =alloc_apertures (1 );if (!a)return -ENOMEM ;
drivers/video/fbdev/core/fbmem.c +0 -12
@@ -19,7 +19,6 @@#include <linux/kernel.h> #include <linux/major.h> #include <linux/slab.h> -#include <linux/sysfb.h> #include <linux/mm.h> #include <linux/mman.h> #include <linux/vt.h>
@@ -1777,17 +1776,6 @@ int remove_conflicting_framebuffers(struct apertures_struct *a, do_free = true; } -/* -* If a driver asked to unregister a platform device registered by -* sysfb, then can be assumed that this is a driver for a display -* that is set up by the system firmware and has a generic driver. -* -* Drivers for devices that don't have a generic driver will never -* ask for this, so let's assume that a real driver for the display -* was already probed and prevent sysfb to register devices later. -*/ -sysfb_disable (); -mutex_lock (®istration_lock);do_remove_conflicting_framebuffers (a, name, primary);mutex_unlock (®istration_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 353/862 drm/virtio: Correct drm_gem_shmem_get_sg_table() error handling
In reply to Greg Kroah-HartmanFrom: Dmitry Osipenko <[email protected]>
[ Upstream commit 64b88afbd92fbf434759d1896a7cf705e1c00e79 ]
Previous commit fixed checking of the ERR_PTR value returned by drm_gem_shmem_get_sg_table(), but it missed to zero out the shmem->pages, which will crash virtio_gpu_cleanup_object(). Add the missing zeroing of the shmem->pages.
--- drivers/gpu/drm/virtio/virtgpu_object.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/virtio/virtgpu_object.c +1 -0
@@ -170,6 +170,7 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev, shmem->pages =drm_gem_shmem_get_sg_table (&bo->base);if (IS_ERR (shmem->pages)) {drm_gem_shmem_unpin (&bo->base); + shmem->pages =NULL ;return PTR_ERR (shmem->pages); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 354/862 drm/bridge: anx7625: Fix refcount bug in anx7625_parse_dt()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 1d43a5120ab49f22ba6c5901ad3994e254510303 ]
In anx7625_parse_dt(), 'pdata->mipi_host_node' will be assigned a new reference with of_graph_get_remote_node() which will increase the refcount of the object, correspondingly, we should call of_node_put() for the old reference stored in the 'pdata->mipi_host_node'.
--- drivers/gpu/drm/bridge/analogix/anx7625.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/bridge/analogix/anx7625.c +1 -0
@@ -1642,6 +1642,7 @@ static int anx7625_parse_dt(struct device *dev,anx7625_get_swing_setting (dev, pdata); pdata->is_dpi =0 ;/* default dsi mode */ +of_node_put (pdata->mipi_host_node); pdata->mipi_host_node =of_graph_get_remote_node (np,0 ,0 );if (!pdata->mipi_host_node) {DRM_DEV_ERROR (dev,"fail to get internal panel.\n" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 355/862 drm/bridge: tc358767: Add of_node_put() when breaking out of loop
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 14e7157afb055248ed34901fcd6fbf54201cfea1 ]
In tc_probe_bridge_endpoint(), we should call of_node_put() when breaking out of the for_each_endpoint_of_node() which will automatically increase and decrease the refcount.
--- drivers/gpu/drm/bridge/tc358767.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/bridge/tc358767.c +3 -2
@@ -2010,9 +2010,10 @@ static int tc_probe_bridge_endpoint(struct tc_data *tc)for_each_endpoint_of_node (dev->of_node, node) {of_graph_parse_endpoint (node, &endpoint); -if (endpoint.port >2 ) +if (endpoint.port >2 ) { +of_node_put (node);return -EINVAL ; - + } mode |=BIT (endpoint.port); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 356/862 drm/bridge: parade-ps8640: Fix regulator supply order
In reply to Greg Kroah-HartmanFrom: Chen-Yu Tsai <[email protected]>
[ Upstream commit fc94224c2e0ae8d83ac511a3ef4962178505469d ]
The datasheet says that VDD12 must be enabled and at full voltage before VDD33 is enabled.
Reorder the bulk regulator supply names so that VDD12 is enabled before VDD33. Any enable ramp delays should be handled by setting proper constraints on the regulators.
--- drivers/gpu/drm/bridge/parade-ps8640.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/bridge/parade-ps8640.c +2 -2
@@ -631,8 +631,8 @@ static int ps8640_probe(struct i2c_client *client)if (!ps_bridge)return -ENOMEM ; - ps_bridge->supplies[0 ].supply ="vdd33" ; - ps_bridge->supplies[1 ].supply ="vdd12" ; + ps_bridge->supplies[0 ].supply ="vdd12" ; + ps_bridge->supplies[1 ].supply ="vdd33" ; ret =devm_regulator_bulk_get (dev,ARRAY_SIZE (ps_bridge->supplies), ps_bridge->supplies);if (ret)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 357/862 drm/format-helper: Fix test on big endian architectures
In reply to Greg Kroah-HartmanFrom: José Expósito <[email protected]>
[ Upstream commit 18c8485236a5e3f491b670c018ae391c9cb84dfa ]
The tests fail on big endian architectures, like PowerPC:
$ ./tools/testing/kunit/kunit.py run \ --kunitconfig=drivers/gpu/drm/tests \ --arch=powerpc --cross_compile=powerpc64-linux-gnu-
Transform the XRGB8888 buffer from little endian to the CPU endian before calling the conversion function to avoid this error.
--- .../gpu/drm/tests/drm_format_helper_test.c | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
drivers/gpu/drm/tests/drm_format_helper_test.c +21 -2
@@ -111,6 +111,21 @@ static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch,return dst_pitch *drm_rect_height (clip); } +static u32 *le32buf_to_cpu (struct kunit *test,const u32 *buf,size_t buf_size) +{ +u32 *dst =NULL ; +int n; + + dst =kunit_kzalloc (test,sizeof (*dst) * buf_size,GFP_KERNEL ); +if (!dst) +return NULL ; + +for (n =0 ; n < buf_size; n++) + dst[n] =le32_to_cpu ((__force __le32 )buf[n]); + +return dst; +} +static void xrgb8888_to_rgb332_case_desc (struct xrgb8888_to_rgb332_case *t,char *desc) {
@@ -125,6 +140,7 @@ static void xrgb8888_to_rgb332_test(struct kunit *test)const struct xrgb8888_to_rgb332_case *params = test->param_value;size_t dst_size;__u8 *dst =NULL ; +__u32 *src =NULL ;struct drm_framebuffer fb = { .format =drm_format_info (DRM_FORMAT_XRGB8888 ),
@@ -138,8 +154,11 @@ static void xrgb8888_to_rgb332_test(struct kunit *test) dst =kunit_kzalloc (test, dst_size,GFP_KERNEL );KUNIT_ASSERT_NOT_ERR_OR_NULL (test, dst); -drm_fb_xrgb8888_to_rgb332 (dst, params->dst_pitch, params->xrgb8888, - &fb, ¶ms->clip); + src =le32buf_to_cpu (test, params->xrgb8888,TEST_BUF_SIZE ); +KUNIT_ASSERT_NOT_ERR_OR_NULL (test, src); + +drm_fb_xrgb8888_to_rgb332 (dst, params->dst_pitch, src, &fb, + ¶ms->clip);KUNIT_EXPECT_EQ (test,memcmp (dst, params->expected, dst_size),0 ); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 358/862 drm/dp_mst: fix drm_dp_dpcd_read return value checks
In reply to Greg Kroah-HartmanFrom: Simon Ser <[email protected]>
[ Upstream commit 2ac6cdd581f48c8f68747156fde5868486a44985 ]
drm_dp_dpcd_read returns the number of bytes read. The previous code would print garbage on DPCD error, and would exit with on error on success.
--- drivers/gpu/drm/display/drm_dp_mst_topology.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/display/drm_dp_mst_topology.c +3 -3
@@ -4907,14 +4907,14 @@ void drm_dp_mst_dump_topology(struct seq_file *m,seq_printf (m,"dpcd: %*ph\n" ,DP_RECEIVER_CAP_SIZE , buf); ret =drm_dp_dpcd_read (mgr->aux,DP_FAUX_CAP , buf,2 ); -if (ret) { +if (ret !=2 ) {seq_printf (m,"faux/mst read failed\n" ); goto out; }seq_printf (m,"faux/mst: %*ph\n" ,2 , buf); ret =drm_dp_dpcd_read (mgr->aux,DP_MSTM_CTRL , buf,1 ); -if (ret) { +if (ret !=1 ) {seq_printf (m,"mst ctrl read failed\n" ); goto out; }
@@ -4922,7 +4922,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,/* dump the standard OUI branch header */ ret =drm_dp_dpcd_read (mgr->aux,DP_BRANCH_OUI , buf,DP_BRANCH_OUI_HEADER_SIZE ); -if (ret) { +if (ret !=DP_BRANCH_OUI_HEADER_SIZE ) {seq_printf (m,"branch oui read failed\n" ); goto out; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 359/862 drm:pl111: Add of_node_put() when breaking out of for_each_available_child_of_node()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit e0686dc6f2252e009c455fe99e2ce9d62a60eb47 ]
The reference 'child' in the iteration of for_each_available_child_of_node() is only escaped out into a local variable which is only used to check its value. So we still need to the of_node_put() when breaking of the for_each_available_child_of_node() which will automatically increase and decrease the refcount.
--- drivers/gpu/drm/pl111/pl111_versatile.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/pl111/pl111_versatile.c +1 -0
@@ -404,6 +404,7 @@ static int pl111_vexpress_clcd_init(struct device *dev, struct device_node *np,if (of_device_is_compatible (child,"arm,pl111" )) { has_coretile_clcd = true; ct_clcd = child; +of_node_put (child);break ; }if (of_device_is_compatible (child,"arm,hdlcd" )) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 360/862 ASoC: mt6359: fix tests for platform_get_irq() failure
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 51eea3a6fb4d39c2cc71824e6eee5949d7ae4d1c ]
The platform_get_irq() returns negative error codes. It can't actually return zero, but if it did that should be treated as success.
--- sound/soc/codecs/mt6359-accdet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/codecs/mt6359-accdet.c +3 -3
@@ -965,7 +965,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev)mutex_init (&priv->res_lock); priv->accdet_irq =platform_get_irq (pdev,0 ); -if (priv->accdet_irq) { +if (priv->accdet_irq >=0 ) { ret = devm_request_threaded_irq(&pdev->dev, priv->accdet_irq, NULL, mt6359_accdet_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
@@ -979,7 +979,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev)if (priv->caps &ACCDET_PMIC_EINT0 ) { priv->accdet_eint0 =platform_get_irq (pdev,1 ); -if (priv->accdet_eint0) { +if (priv->accdet_eint0 >=0 ) { ret = devm_request_threaded_irq(&pdev->dev, priv->accdet_eint0, NULL, mt6359_accdet_irq,
@@ -994,7 +994,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev) } }else if (priv->caps &ACCDET_PMIC_EINT1 ) { priv->accdet_eint1 =platform_get_irq (pdev,2 ); -if (priv->accdet_eint1) { +if (priv->accdet_eint1 >=0 ) { ret = devm_request_threaded_irq(&pdev->dev, priv->accdet_eint1, NULL, mt6359_accdet_irq,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 361/862 ASoC: amd: acp: add missing platform_device_unregister() in acp_pci_probe()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 6a4ce20fd776d2fd19ffaf85cf34a53761e2c888 ]
Add missing platform_device_unregister() in error path in acp_pci_probe().
--- sound/soc/amd/acp/acp-pci.c | 1 + 1 file changed, 1 insertion(+)
sound/soc/amd/acp/acp-pci.c +1 -0
@@ -104,6 +104,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id addr =pci_resource_start (pci,0 ); chip->base =devm_ioremap (&pci->dev, addr,pci_resource_len (pci,0 ));if (!chip->base) { +platform_device_unregister (dmic_dev); ret = -ENOMEM ; goto release_regions; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 362/862 drm/msm: Make .remove and .shutdown HW shutdown consistent
In reply to Greg Kroah-HartmanFrom: Javier Martinez Canillas <[email protected]>
[ Upstream commit 0a58d2ae572adaec8d046f8d35b40c2c32ac7468 ]
Drivers' .remove and .shutdown callbacks are executed on different code paths. The former is called when a device is removed from the bus, while the latter is called at system shutdown time to quiesce the device.
This means that some overlap exists between the two, because both have to take care of properly shutting down the hardware. But currently the logic used in these two callbacks isn't consistent in msm drivers, which could lead to kernel panic.
For example, on .remove the component is deleted and its .unbind callback leads to the hardware being shutdown but only if the DRM device has been marked as registered.
That check doesn't exist in the .shutdown logic and this can lead to the driver calling drm_atomic_helper_shutdown() for a DRM device that hasn't been properly initialized.
A situation like this can happen if drivers for expected sub-devices fail to probe, since the .bind callback will never be executed. If that is the case, drm_atomic_helper_shutdown() will attempt to take mutexes that are only initialized if drm_mode_config_init() is called during a device bind.
This bug was attempted to be fixed in commit 623f279c7781 ("drm/msm: fix shutdown hook in case GPU components failed to bind"), but unfortunately it still happens in some cases as the one mentioned above, i.e:
systemd-shutdown[1]: Powering off.
kvm: exiting hardware virtualization
platform wifi-firmware.0: Removing from iommu group 12 platform video-firmware.0: Removing from iommu group 10
------------[ cut here ]------------
WARNING: CPU: 6 PID: 1 at drivers/gpu/drm/drm_modeset_lock.c:317 drm_modeset_lock_all_ctx+0x3c4/0x3d0
...
Hardware name: Google CoachZ (rev3+) (DT)
pstate: a0400009 (NzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : drm_modeset_lock_all_ctx+0x3c4/0x3d0
lr : drm_modeset_lock_all_ctx+0x48/0x3d0
sp : ffff80000805bb80
x29: ffff80000805bb80 x28: ffff327c00128000 x27: 0000000000000000
x26: 0000000000000000 x25: 0000000000000001 x24: ffffc95d820ec030
x23: ffff327c00bbd090 x22: ffffc95d8215eca0 x21: ffff327c039c5800
x20: ffff327c039c5988 x19: ffff80000805bbe8 x18: 0000000000000034
x17: 000000040044ffff x16: ffffc95d80cac920 x15: 0000000000000000
x14: 0000000000000315 x13: 0000000000000315 x12: 0000000000000000
x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
x8 : ffff80000805bc28 x7 : 0000000000000000 x6 : 0000000000000000
x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
x2 : ffff327c00128000 x1 : 0000000000000000 x0 : ffff327c039c59b0
Call trace:
drm_modeset_lock_all_ctx+0x3c4/0x3d0
drm_atomic_helper_shutdown+0x70/0x134
msm_drv_shutdown+0x30/0x40
platform_shutdown+0x28/0x40
device_shutdown+0x148/0x350
kernel_power_off+0x38/0x80
__do_sys_reboot+0x288/0x2c0
__arm64_sys_reboot+0x28/0x34
invoke_syscall+0x48/0x114
el0_svc_common.constprop.0+0x44/0xec
do_el0_svc+0x2c/0xc0
el0_svc+0x2c/0x84
el0t_64_sync_handler+0x11c/0x150
el0t_64_sync+0x18c/0x190
---[ end trace 0000000000000000 ]---
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000018
Mem abort info:
ESR = 0x0000000096000004
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x04: level 0 translation fault
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgdp=000000010eab1000
[0000000000000018] pgd=0000000000000000, p4d=0000000000000000
Internal error: Oops: 96000004 [#1] PREEMPT SMP
...
Hardware name: Google CoachZ (rev3+) (DT)
pstate: a0400009 (NzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : ww_mutex_lock+0x28/0x32c
lr : drm_modeset_lock_all_ctx+0x1b0/0x3d0
sp : ffff80000805bb50
x29: ffff80000805bb50 x28: ffff327c00128000 x27: 0000000000000000
x26: 0000000000000000 x25: 0000000000000001 x24: 0000000000000018
x23: ffff80000805bc10 x22: ffff327c039c5ad8 x21: ffff327c039c5800
x20: ffff80000805bbe8 x19: 0000000000000018 x18: 0000000000000034
x17: 000000040044ffff x16: ffffc95d80cac920 x15: 0000000000000000
x14: 0000000000000315 x13: 0000000000000315 x12: 0000000000000000
x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
x8 : ffff80000805bc28 x7 : 0000000000000000 x6 : 0000000000000000
x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
x2 : ffff327c00128000 x1 : 0000000000000000 x0 : 0000000000000018
Call trace:
ww_mutex_lock+0x28/0x32c
drm_modeset_lock_all_ctx+0x1b0/0x3d0
drm_atomic_helper_shutdown+0x70/0x134
msm_drv_shutdown+0x30/0x40
platform_shutdown+0x28/0x40
device_shutdown+0x148/0x350
kernel_power_off+0x38/0x80
__do_sys_reboot+0x288/0x2c0
__arm64_sys_reboot+0x28/0x34
invoke_syscall+0x48/0x114
el0_svc_common.constprop.0+0x44/0xec
do_el0_svc+0x2c/0xc0
el0_svc+0x2c/0x84
el0t_64_sync_handler+0x11c/0x150
el0t_64_sync+0x18c/0x190
Code: aa0103f4 d503201f d2800001 aa0103e3 (c8e37c02)
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
Kernel Offset: 0x495d77c00000 from 0xffff800008000000
PHYS_OFFSET: 0xffffcd8500000000
CPU features: 0x800,00c2a015,19801c82
Memory Limit: none
---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]------ drivers/gpu/drm/msm/msm_drv.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/gpu/drm/msm/msm_drv.c +9 -4
@@ -1244,10 +1244,15 @@ void msm_drv_shutdown(struct platform_device *pdev)struct msm_drm_private *priv =platform_get_drvdata (pdev);struct drm_device *drm = priv ? priv->dev :NULL ; -if (!priv || !priv->kms) -return ; - -drm_atomic_helper_shutdown (drm); +/* +* Shutdown the hw if we're far enough along where things might be on. +* If we run this too early, we'll end up panicking in any variety of +* places. Since we don't register the drm device until late in +* msm_drm_init, drm_dev->registered is used as an indicator that the +* shutdown will be successful. +*/ +if (drm && drm->registered) +drm_atomic_helper_shutdown (drm); }static struct platform_driver msm_platform_driver = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 363/862 platform/chrome: fix double-free in chromeos_laptop_prepare()
In reply to Greg Kroah-HartmanFrom: Rustam Subkhankulov <[email protected]>
[ Upstream commit 6ad4194d6a1e1d11b285989cd648ef695b4a93c0 ]
If chromeos_laptop_prepare_i2c_peripherals() fails after allocating memory for 'cros_laptop->i2c_peripherals', this memory is freed at 'err_out' label and nonzero value is returned. Then chromeos_laptop_destroy() is called, resulting in double-free error.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/platform/chrome/chromeos_laptop.c | 24 ++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
drivers/platform/chrome/chromeos_laptop.c +13 -11
@@ -740,6 +740,7 @@ static int __init chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop, const struct chromeos_laptop *src) { + struct i2c_peripheral *i2c_peripherals;struct i2c_peripheral *i2c_dev;struct i2c_board_info *info;int i;
@@ -748,17 +749,15 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop,if (!src->num_i2c_peripherals)return 0 ; - cros_laptop->i2c_peripherals =kmemdup (src->i2c_peripherals, - src->num_i2c_peripherals * -sizeof (*src->i2c_peripherals), -GFP_KERNEL ); -if (!cros_laptop->i2c_peripherals) + i2c_peripherals =kmemdup (src->i2c_peripherals, + src->num_i2c_peripherals * +sizeof (*src->i2c_peripherals), +GFP_KERNEL ); +if (!i2c_peripherals)return -ENOMEM ; - cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals; - -for (i =0 ; i < cros_laptop->num_i2c_peripherals; i++) { - i2c_dev = &cros_laptop->i2c_peripherals[i]; +for (i =0 ; i < src->num_i2c_peripherals; i++) { + i2c_dev = &i2c_peripherals[i]; info = &i2c_dev->board_info; error =chromeos_laptop_setup_irq (i2c_dev);
@@ -775,16 +774,19 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop, } } + cros_laptop->i2c_peripherals = i2c_peripherals; + cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals; +return 0 ; err_out:while (--i >=0 ) { - i2c_dev = &cros_laptop->i2c_peripherals[i]; + i2c_dev = &i2c_peripherals[i]; info = &i2c_dev->board_info;if (!IS_ERR_OR_NULL (info->fwnode))fwnode_remove_software_node (info->fwnode); } -kfree (cros_laptop->i2c_peripherals); +kfree (i2c_peripherals);return error; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 364/862 platform/chrome: fix memory corruption in ioctl
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 8a07b45fd3c2dda24fad43639be5335a4595196a ]
If "s_mem.bytes" is larger than the buffer size it leads to memory corruption.
--- drivers/platform/chrome/cros_ec_chardev.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/platform/chrome/cros_ec_chardev.c +3 -0
@@ -327,6 +327,9 @@ static long cros_ec_chardev_ioctl_readmem(struct cros_ec_dev *ec,if (copy_from_user (&s_mem, arg,sizeof (s_mem)))return -EFAULT ; +if (s_mem.bytes >sizeof (s_mem.buffer)) +return -EINVAL ; + num = ec_dev->cmd_readmem (ec_dev, s_mem.offset, s_mem.bytes, s_mem.buffer);if (num <=0 )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 365/862 drm/i915/dg2: Bump up CDCLK for DG2
In reply to Greg Kroah-HartmanFrom: Stanislav Lisovskiy <[email protected]>
[ Upstream commit 859161b952a453b86362f168fadef72a8ba31a05 ]
We seem to need this W/A same way as for TGL, in order to fix some of the underruns, which we currently have and those not related to PSR.
Stable-dep-of: 4234ea300512 ("drm/i915/display: avoid warnings when registering dual panel backlight")
--- drivers/gpu/drm/i915/display/intel_cdclk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/display/intel_cdclk.c +2 -2
@@ -2300,7 +2300,7 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) min_cdclk =max (min_cdclk, (int )crtc_state->pixel_rate);/* -* HACK. Currently for TGL platforms we calculate +* HACK. Currently for TGL/DG2 platforms we calculate * min_cdclk initially based on pixel_rate divided * by 2, accounting for also plane requirements, * however in some cases the lowest possible CDCLK
@@ -2308,7 +2308,7 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)* Explicitly stating here that this seems to be currently * rather a Hack, than final solution. */ -if (IS_TIGERLAKE (dev_priv)) { +if (IS_TIGERLAKE (dev_priv) ||IS_DG2 (dev_priv)) {/* * Clamp to max_cdclk_freq in case pixel rate is higher, * in order not to break an 8K, but still leave W/A at place.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 366/862 drm/virtio: Fix same-context optimization
In reply to Greg Kroah-HartmanFrom: Rob Clark <[email protected]>
[ Upstream commit 3007dc2af6e86ac00b4daf7414142637fdf50bfa ]
When VIRTGPU_EXECBUF_RING_IDX is used, we should be considering the timeline that the EB if running on rather than the global driver fence context.
--- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/virtio/virtgpu_ioctl.c +1 -1
@@ -168,7 +168,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,* array contains any fence from a foreign context. */ ret =0 ; -if (!dma_fence_match_context (in_fence, vgdev->fence_drv.context)) +if (!dma_fence_match_context (in_fence, fence_ctx + ring_idx)) ret =dma_fence_wait (in_fence, true);dma_fence_put (in_fence);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 367/862 ASoC: soc-pcm.c: call __soc_pcm_close() in soc_pcm_close()
In reply to Greg Kroah-HartmanFrom: Kuninori Morimoto <[email protected]>
[ Upstream commit 6bbabd28805f36baf6d0f3eb082db032a638f612 ]
commit b7898396f4bbe16 ("ASoC: soc-pcm: Fix and cleanup DPCM locking") added __soc_pcm_close() for non-lock version of soc_pcm_close(). But soc_pcm_close() is not using it. It is no problem, but confusable.
static int __soc_pcm_close(...)
{
=> return soc_pcm_clean(rtd, substream, 0);
}
static int soc_pcm_close(...)
{
...
snd_soc_dpcm_mutex_lock(rtd);
=> soc_pcm_clean(rtd, substream, 0);
snd_soc_dpcm_mutex_unlock(rtd);
return 0;
}This patch use it.
--- sound/soc/soc-pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/soc-pcm.c +1 -1
@@ -723,7 +723,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)struct snd_soc_pcm_runtime *rtd =asoc_substream_to_rtd (substream);snd_soc_dpcm_mutex_lock (rtd); -soc_pcm_clean (rtd, substream,0 ); +__soc_pcm_close (rtd, substream);snd_soc_dpcm_mutex_unlock (rtd);return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 368/862 ASoC: tas2764: Allow mono streams
In reply to Greg Kroah-HartmanFrom: Martin Povišer <[email protected]>
[ Upstream commit 23204d928a27146d13e11c9383632775345ecca8 ]
The part is a mono speaker amp, but it can do downmix and switch between left and right channel, so the right channel range is 1 to 2.
(This mirrors commit bf54d97a835d ("ASoC: tas2770: Allow mono streams") which was a fix to the tas2770 driver.)
--- sound/soc/codecs/tas2764.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/codecs/tas2764.c +1 -1
@@ -485,7 +485,7 @@ static struct snd_soc_dai_driver tas2764_dai_driver[] = { .id = 0, .playback = { .stream_name = "ASI1 Playback", - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = TAS2764_RATES, .formats = TAS2764_FORMATS,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 369/862 ASoC: tas2764: Drop conflicting set_bias_level power setting
In reply to Greg Kroah-HartmanFrom: Martin Povišer <[email protected]>
[ Upstream commit 09273f38832406db19a8907a934687cc10660a6b ]
The driver is setting the PWR_CTRL field in both the set_bias_level callback and on DAPM events of the DAC widget (and also in the mute_stream method). Drop the set_bias_level callback altogether as the power setting it does is in conflict with the other code paths.
(This mirrors commit c8a6ae3fe1c8 ("ASoC: tas2770: Drop conflicting set_bias_level power setting") which was a fix to the tas2770 driver.)
--- sound/soc/codecs/tas2764.c | 33 --------------------------------- 1 file changed, 33 deletions(-)
sound/soc/codecs/tas2764.c +0 -33
@@ -50,38 +50,6 @@ static void tas2764_reset(struct tas2764_priv *tas2764)usleep_range (1000 ,2000 ); } -static int tas2764_set_bias_level (struct snd_soc_component *component, -enum snd_soc_bias_level level) -{ -struct tas2764_priv *tas2764 =snd_soc_component_get_drvdata (component); - -switch (level) { -case SND_SOC_BIAS_ON : -snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , -TAS2764_PWR_CTRL_ACTIVE ); -break ; -case SND_SOC_BIAS_STANDBY : -case SND_SOC_BIAS_PREPARE : -snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , -TAS2764_PWR_CTRL_MUTE ); -break ; -case SND_SOC_BIAS_OFF : -snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , -TAS2764_PWR_CTRL_SHUTDOWN ); -break ; - -default : -dev_err (tas2764->dev, -"wrong power level setting %d\n" , level); -return -EINVAL ; - } - -return 0 ; -} -#ifdef CONFIG_PM static int tas2764_codec_suspend (struct snd_soc_component *component) {
@@ -549,7 +517,6 @@ static const struct snd_soc_component_driver soc_component_driver_tas2764 = { .probe = tas2764_codec_probe, .suspend = tas2764_codec_suspend, .resume = tas2764_codec_resume, - .set_bias_level = tas2764_set_bias_level, .controls = tas2764_snd_controls, .num_controls = ARRAY_SIZE(tas2764_snd_controls), .dapm_widgets = tas2764_dapm_widgets,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 370/862 ASoC: tas2764: Fix mute/unmute
In reply to Greg Kroah-HartmanFrom: Martin Povišer <[email protected]>
[ Upstream commit f5ad67f13623548e5aff847f89700c178aaf2a98 ]
Because the PWR_CTRL field is modeled as the power state of the DAC widget, and at the same time it is used to implement mute/unmute, we need some additional book-keeping to have the right end result no matter the sequence of calls. Without this fix, one permanently mutes an ongoing stream by toggling the associated speaker pin control.
(This mirrors commit 1e5907bcb3a3 ("ASoC: tas2770: Fix handling of mute/unmute") which was a fix to the tas2770 driver.)
--- sound/soc/codecs/tas2764.c | 57 +++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 25 deletions(-)
sound/soc/codecs/tas2764.c +32 -25
@@ -34,6 +34,9 @@ struct tas2764_priv {int v_sense_slot;int i_sense_slot; + +bool dac_powered; +bool unmuted; };static void tas2764_reset (struct tas2764_priv *tas2764)
@@ -50,6 +53,26 @@ static void tas2764_reset(struct tas2764_priv *tas2764)usleep_range (1000 ,2000 ); } +static int tas2764_update_pwr_ctrl (struct tas2764_priv *tas2764) +{ +struct snd_soc_component *component = tas2764->component; +unsigned int val; +int ret; + +if (tas2764->dac_powered) + val = tas2764->unmuted ? +TAS2764_PWR_CTRL_ACTIVE :TAS2764_PWR_CTRL_MUTE ; +else + val =TAS2764_PWR_CTRL_SHUTDOWN ; + + ret =snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , +TAS2764_PWR_CTRL_MASK , val); +if (ret <0 ) +return ret; + +return 0 ; +} +#ifdef CONFIG_PM static int tas2764_codec_suspend (struct snd_soc_component *component) {
@@ -82,9 +105,7 @@ static int tas2764_codec_resume(struct snd_soc_component *component)usleep_range (1000 ,2000 ); } - ret =snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , -TAS2764_PWR_CTRL_ACTIVE ); + ret =tas2764_update_pwr_ctrl (tas2764);if (ret <0 )return ret;
@@ -118,14 +139,12 @@ static int tas2764_dac_event(struct snd_soc_dapm_widget *w,switch (event) {case SND_SOC_DAPM_POST_PMU : - ret =snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , -TAS2764_PWR_CTRL_MUTE ); + tas2764->dac_powered = true; + ret =tas2764_update_pwr_ctrl (tas2764);break ;case SND_SOC_DAPM_PRE_PMD : - ret =snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , -TAS2764_PWR_CTRL_SHUTDOWN ); + tas2764->dac_powered = false; + ret =tas2764_update_pwr_ctrl (tas2764);break ;default :dev_err (tas2764->dev,"Unsupported event\n" );
@@ -170,17 +189,11 @@ static const struct snd_soc_dapm_route tas2764_audio_map[] = {static int tas2764_mute (struct snd_soc_dai *dai,int mute,int direction) { -struct snd_soc_component *component = dai->component; -int ret; - - ret =snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , - mute ?TAS2764_PWR_CTRL_MUTE :0 ); +struct tas2764_priv *tas2764 = +snd_soc_component_get_drvdata (dai->component); -if (ret <0 ) -return ret; - -return 0 ; + tas2764->unmuted = !mute; +return tas2764_update_pwr_ctrl (tas2764); }static int tas2764_set_bitwidth (struct tas2764_priv *tas2764,int bitwidth)
@@ -494,12 +507,6 @@ static int tas2764_codec_probe(struct snd_soc_component *component)if (ret <0 )return ret; - ret =snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , -TAS2764_PWR_CTRL_MUTE ); -if (ret <0 ) -return ret; -return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 371/862 platform/x86: msi-laptop: Fix old-ec check for backlight registering
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit 83ac7a1c2ed5f17caa07cbbc84bad3c05dc3bf22 ]
Commit 2cc6c717799f ("msi-laptop: Port to new backlight interface selection API") replaced this check:
if (!quirks->old_ec_model || acpi_video_backlight_support())
pr_info("Brightness ignored, ...");
else
do_register();With:
if (quirks->old_ec_model || acpi_video_get_backlight_type() == acpi_backlight_vendor) do_register();
But since the do_register() part was part of the else branch, the entire condition should be inverted. So not only the 2 statements on either side of the || should be inverted, but the || itself should be replaced with a &&.
In practice this has likely not been an issue because the new-ec models (old_ec_model==false) likely all support ACPI video backlight control, making acpi_video_get_backlight_type() return acpi_backlight_video turning the second part of the || also false when old_ec_model == false.
--- drivers/platform/x86/msi-laptop.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/platform/x86/msi-laptop.c +1 -2
@@ -1048,8 +1048,7 @@ static int __init msi_init(void)return -EINVAL ;/* Register backlight stuff */ - -if (quirks->old_ec_model || +if (quirks->old_ec_model &&acpi_video_get_backlight_type () == acpi_backlight_vendor) {struct backlight_properties props;memset (&props,0 ,sizeof (struct backlight_properties ));
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 372/862 platform/x86: msi-laptop: Fix resource cleanup
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit 5523632aa10f906dfe2eb714ee748590dc7fc6b1 ]
Fix the input-device not getting free-ed on probe-errors and fix the msi_touchpad_dwork not getting cancelled on neither probe-errors nor on remove.
--- drivers/platform/x86/msi-laptop.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/platform/x86/msi-laptop.c +3 -0
@@ -1116,6 +1116,8 @@ static int __init msi_init(void) fail_create_group:if (quirks->load_scm_model) {i8042_remove_filter (msi_laptop_i8042_filter); +cancel_delayed_work_sync (&msi_touchpad_dwork); +input_unregister_device (msi_laptop_input_dev);cancel_delayed_work_sync (&msi_rfkill_dwork);cancel_work_sync (&msi_rfkill_work);rfkill_cleanup ();
@@ -1136,6 +1138,7 @@ static void __exit msi_cleanup(void) {if (quirks->load_scm_model) {i8042_remove_filter (msi_laptop_i8042_filter); +cancel_delayed_work_sync (&msi_touchpad_dwork);input_unregister_device (msi_laptop_input_dev);cancel_delayed_work_sync (&msi_rfkill_dwork);cancel_work_sync (&msi_rfkill_work);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 373/862 drm/panel: use select for Ili9341 panel driver helpers
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
[ Upstream commit 84dfc46594b0167e5d3736273b0e0e05365da641 ]
Use 'select' instead of 'depends on' for DRM helpers for the Ilitek ILI9341 panel driver.
This is what is done in the vast majority of other cases and this makes it possible to fix a build error with drm_mipi_dbi.
--- drivers/gpu/drm/panel/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/panel/Kconfig +2 -2
@@ -165,8 +165,8 @@ config DRM_PANEL_ILITEK_IL9322 config DRM_PANEL_ILITEK_ILI9341 tristate "Ilitek ILI9341 240x320 QVGA panels" depends on OF && SPI - depends on DRM_KMS_HELPER - depends on DRM_GEM_CMA_HELPER + select DRM_KMS_HELPER + select DRM_GEM_DMA_HELPER depends on BACKLIGHT_CLASS_DEVICE select DRM_MIPI_DBI help
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 374/862 drm: fix drm_mipi_dbi build errors
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
[ Upstream commit eb7de496451bd969e203f02f66585131228ba4ae ]
drm_mipi_dbi needs lots of DRM_KMS_HELPER support, so select that Kconfig symbol like it is done is most other uses, and the way that it was before MIPS_DBI was moved from tinydrm to its core location.
Fixes these build errors:
ld: drivers/gpu/drm/drm_mipi_dbi.o: in function `mipi_dbi_buf_copy':drivers/gpu/drm/drm_mipi_dbi.c:205: undefined reference to `drm_gem_fb_get_obj'
ld: drivers/gpu/drm/drm_mipi_dbi.c:211: undefined reference to `drm_gem_fb_begin_cpu_access'
ld: drivers/gpu/drm/drm_mipi_dbi.c:215: undefined reference to `drm_gem_fb_vmap'
ld: drivers/gpu/drm/drm_mipi_dbi.c:222: undefined reference to `drm_fb_swab'
ld: drivers/gpu/drm/drm_mipi_dbi.c:224: undefined reference to `drm_fb_memcpy'
ld: drivers/gpu/drm/drm_mipi_dbi.c:227: undefined reference to `drm_fb_xrgb8888_to_rgb565'
ld: drivers/gpu/drm/drm_mipi_dbi.c:235: undefined reference to `drm_gem_fb_vunmap'
ld: drivers/gpu/drm/drm_mipi_dbi.c:237: undefined reference to `drm_gem_fb_end_cpu_access'
ld: drivers/gpu/drm/drm_mipi_dbi.o: in function `mipi_dbi_dev_init_with_formats':
ld: drivers/gpu/drm/drm_mipi_dbi.o:/X64/../drivers/gpu/drm/drm_mipi_dbi.c:469: undefined reference to `drm_gem_fb_create_with_dirty'
--- drivers/gpu/drm/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/Kconfig +1 -0
@@ -31,6 +31,7 @@ menuconfig DRM config DRM_MIPI_DBI tristate depends on DRM + select DRM_KMS_HELPER config DRM_MIPI_DSI bool
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 375/862 platform/chrome: cros_ec_typec: Add bit offset for DP VDO
In reply to Greg Kroah-HartmanFrom: Prashant Malani <[email protected]>
[ Upstream commit 1903adae0464c1e1c36b132db474cb3aff7bc727 ]
Use the right macro while constructing the DP_PORT_VDO to ensure the Pin Assignment offsets are correct.
--- drivers/platform/chrome/cros_ec_typec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/platform/chrome/cros_ec_typec.c +2 -1
@@ -25,7 +25,8 @@#define DRV_NAME "cros-ec-typec" -#define DP_PORT_VDO (BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D) | DP_CAP_DFP_D) +#define DP_PORT_VDO (DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D)) | \ + DP_CAP_DFP_D)/* Supported alt modes. */ enum {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 376/862 platform/chrome: cros_ec_typec: Correct alt mode index
In reply to Greg Kroah-HartmanFrom: Prashant Malani <[email protected]>
[ Upstream commit 4e477663e396f48c5cfc5f2d75d4b514f409516a ]
Alt mode indices used by USB PD (Power Delivery) start with 1, not 0.
Update the alt mdoe registration code to factor this in to the alt mode descriptor.
--- drivers/platform/chrome/cros_ec_typec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/platform/chrome/cros_ec_typec.c +1 -1
@@ -698,7 +698,7 @@ static int cros_typec_register_altmodes(struct cros_typec_data *typec, int port_for (j =0 ; j < sop_disc->svids[i].mode_count; j++) {memset (&desc,0 ,sizeof (desc)); desc.svid = sop_disc->svids[i].svid; - desc.mode = j; + desc.mode = j +1 ; desc.vdo = sop_disc->svids[i].mode_vdo[j];if (is_partner)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 377/862 drm/amdgpu: add missing pci_disable_device() in amdgpu_pmops_runtime_resume()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 6b11af6d1c8f5d4135332bb932baaa06e511173d ]
Add missing pci_disable_device() if amdgpu_device_resume() fails.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +4 -1
@@ -2563,8 +2563,11 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)amdgpu_device_baco_exit (drm_dev); } ret =amdgpu_device_resume (drm_dev, false); -if (ret) +if (ret) { +if (amdgpu_device_supports_px (drm_dev)) +pci_disable_device (pdev);return ret; + }if (amdgpu_device_supports_px (drm_dev)) drm_dev->switch_power_state =DRM_SWITCH_POWER_ON ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 378/862 drm/bridge: megachips: Fix a null pointer dereference bug
In reply to Greg Kroah-HartmanFrom: Zheyu Ma <[email protected]>
[ Upstream commit 1ff673333d46d2c1b053ebd0c1c7c7c79e36943e ]
When removing the module we will get the following warning:
[ 31.911505] i2c-core: driver [stdp2690-ge-b850v3-fw] unregistered [ 31.912484] general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN PTI [ 31.913338] KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] [ 31.915280] RIP: 0010:drm_bridge_remove+0x97/0x130 [ 31.921825] Call Trace: [ 31.922533] stdp4028_ge_b850v3_fw_remove+0x34/0x60 [megachips_stdpxxxx_ge_b850v3_fw] [ 31.923139] i2c_device_remove+0x181/0x1f0
The two bridges (stdp2690, stdp4028) do not probe at the same time, so the driver does not call ge_b850v3_resgiter() when probing, causing the driver to try to remove the object that has not been initialized.
Fix this by checking whether both the bridges are probed.
--- drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c +3 -1
@@ -296,7 +296,9 @@ static void ge_b850v3_lvds_remove(void)* This check is to avoid both the drivers * removing the bridge in their remove() function */ -if (!ge_b850v3_lvds_ptr) +if (!ge_b850v3_lvds_ptr || + !ge_b850v3_lvds_ptr->stdp2690_i2c || + !ge_b850v3_lvds_ptr->stdp4028_i2c) goto out;drm_bridge_remove (&ge_b850v3_lvds_ptr->bridge);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 379/862 drm/bridge: it6505: Fix the order of DP_SET_POWER commands
In reply to Greg Kroah-HartmanFrom: Pin-yen Lin <[email protected]>
[ Upstream commit 7c1dceaffd99247bf443606730515b54d6285969 ]
Send DP_SET_POWER_D3 command to the downstream before stopping DP, so the suspend process will not be interrupted by the HPD interrupt. Also modify the order in .atomic_enable callback to make the callbacks symmetric.
--- drivers/gpu/drm/bridge/ite-it6505.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/bridge/ite-it6505.c +4 -4
@@ -2945,9 +2945,6 @@ static void it6505_bridge_atomic_enable(struct drm_bridge *bridge,if (ret)dev_err (dev,"Failed to setup AVI infoframe: %d" , ret); -it6505_drm_dp_link_set_power (&it6505->aux, &it6505->link, -DP_SET_POWER_D0 ); -it6505_update_video_parameter (it6505, mode); ret =it6505_send_video_infoframe (it6505, &frame);
@@ -2957,6 +2954,9 @@ static void it6505_bridge_atomic_enable(struct drm_bridge *bridge,it6505_int_mask_enable (it6505);it6505_video_reset (it6505); + +it6505_drm_dp_link_set_power (&it6505->aux, &it6505->link, +DP_SET_POWER_D0 ); } static void it6505_bridge_atomic_disable(struct drm_bridge *bridge,
@@ -2968,9 +2968,9 @@ static void it6505_bridge_atomic_disable(struct drm_bridge *bridge,DRM_DEV_DEBUG_DRIVER (dev,"start" );if (it6505->powered) { -it6505_video_disable (it6505);it6505_drm_dp_link_set_power (&it6505->aux, &it6505->link,DP_SET_POWER_D3 ); +it6505_video_disable (it6505); } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 380/862 ASoC: rsnd: Add check for rsnd_mod_power_on
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 376be51caf8871419bbcbb755e1e615d30dc3153 ]
As rsnd_mod_power_on() can return negative numbers, it should be better to check the return value and deal with the exception.
--- sound/soc/sh/rcar/ctu.c | 6 +++++- sound/soc/sh/rcar/dvc.c | 6 +++++- sound/soc/sh/rcar/mix.c | 6 +++++- sound/soc/sh/rcar/src.c | 5 ++++- sound/soc/sh/rcar/ssi.c | 4 +++- 5 files changed, 22 insertions(+), 5 deletions(-)
sound/soc/sh/rcar/ctu.c +5 -1
@@ -171,7 +171,11 @@ static int rsnd_ctu_init(struct rsnd_mod *mod,struct rsnd_dai_stream *io, struct rsnd_priv *priv) { -rsnd_mod_power_on (mod ); + int ret; + + ret =rsnd_mod_power_on (mod); +if (ret <0 ) +return ret;rsnd_ctu_activation (mod);
sound/soc/sh/rcar/dvc.c +5 -1
@@ -186,7 +186,11 @@ static int rsnd_dvc_init(struct rsnd_mod *mod,struct rsnd_dai_stream *io, struct rsnd_priv *priv) { -rsnd_mod_power_on (mod ); + int ret; + + ret =rsnd_mod_power_on (mod); +if (ret <0 ) +return ret;rsnd_dvc_activation (mod);
sound/soc/sh/rcar/mix.c +5 -1
@@ -146,7 +146,11 @@ static int rsnd_mix_init(struct rsnd_mod *mod,struct rsnd_dai_stream *io, struct rsnd_priv *priv) { -rsnd_mod_power_on (mod ); + int ret; + + ret =rsnd_mod_power_on (mod); +if (ret <0 ) +return ret;rsnd_mix_activation (mod);
sound/soc/sh/rcar/src.c +4 -1
@@ -463,11 +463,14 @@ static int rsnd_src_init(struct rsnd_mod *mod, struct rsnd_priv *priv) {struct rsnd_src *src =rsnd_mod_to_src (mod); +int ret;/* reset sync convert_rate */ src->sync.val =0 ; -rsnd_mod_power_on (mod); + ret =rsnd_mod_power_on (mod); +if (ret <0 ) +return ret;rsnd_src_activation (mod);
sound/soc/sh/rcar/ssi.c +3 -1
@@ -480,7 +480,9 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, ssi->usrcnt++; -rsnd_mod_power_on (mod); + ret =rsnd_mod_power_on (mod); +if (ret <0 ) +return ret;rsnd_ssi_config_init (mod, io);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 381/862 ASoC: wm_adsp: Handle optional legacy support
In reply to Greg Kroah-HartmanFrom: Cristian Ciocaltea <[email protected]>
[ Upstream commit 35c8ae25c4fdeabf490e005692795a3be17ca5f6 ]
The tracing capabilities for the speaker protection fw enabled via commit c55b3e46cb99 ("ASoC: wm_adsp: Add trace caps to speaker protection FW") are not be available on all platforms, such as the Valve's Steam Deck which is based on the Halo Core DSP.
As a consequence, whenever the firmware is loaded, a rather misleading 'Failed to parse legacy: -19' error message is written to the kernel ring buffer:
[ 288.977412] steamdeck kernel: cs35l41 spi-VLV1776:01: DSP1: Firmware version: 3 [ 288.978002] steamdeck kernel: cs35l41 spi-VLV1776:01: DSP1: cs35l41-dsp1-spk-prot.wmfw: Fri 02 Apr 2021 21:03:50 W. Europe Daylight Time [ 289.094065] steamdeck kernel: cs35l41 spi-VLV1776:01: DSP1: Firmware: 400a4 vendor: 0x2 v0.33.0, 2 algorithms [ 289.095073] steamdeck kernel: cs35l41 spi-VLV1776:01: DSP1: 0: ID cd v29.53.0 XM@94 YM@e [ 289.095665] steamdeck kernel: cs35l41 spi-VLV1776:01: DSP1: 1: ID f20b v0.0.1 XM@170 YM@0 [ 289.096275] steamdeck kernel: cs35l41 spi-VLV1776:01: DSP1: Protection: C:\Users\ocanavan\Desktop\cirrusTune_july2021.bin [ 291.172383] steamdeck kernel: cs35l41 spi-VLV1776:01: DSP1: Failed to parse legacy: -19
Update wm_adsp_buffer_init() to print a more descriptive info message when wm_adsp_buffer_parse_legacy() returns -ENODEV.
--- sound/soc/codecs/wm_adsp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
sound/soc/codecs/wm_adsp.c +3 -1
@@ -1602,7 +1602,9 @@ static int wm_adsp_buffer_init(struct wm_adsp *dsp)if (list_empty (&dsp->buffer_list)) {/* Fall back to legacy support */ ret =wm_adsp_buffer_parse_legacy (dsp); -if (ret) +if (ret == -ENODEV ) +adsp_info (dsp,"Legacy support not available\n" ); +else if (ret)adsp_warn (dsp,"Failed to parse legacy: %d\n" , ret); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 382/862 ALSA: hda: beep: Simplify keep-power-at-enable behavior
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
[ Upstream commit 4c8d695cb9bc5f6fd298a586602947b2fc099a64 ]
The recent fix for IDT codecs to keep the power up while the beep is enabled can be better integrated into the beep helper code. This patch cleans up the code with refactoring.
--- sound/pci/hda/hda_beep.c | 15 +++++++++++++-- sound/pci/hda/hda_beep.h | 1 + sound/pci/hda/patch_sigmatel.c | 25 ++----------------------- 3 files changed, 16 insertions(+), 25 deletions(-)
sound/pci/hda/hda_beep.c +13 -2
@@ -118,6 +118,12 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,return 0 ; } +static void turn_on_beep (struct hda_beep *beep) +{ +if (beep->keep_power_at_enable) +snd_hda_power_up_pm (beep->codec); +} +static void turn_off_beep (struct hda_beep *beep) {cancel_work_sync (&beep->beep_work);
@@ -125,6 +131,8 @@ static void turn_off_beep(struct hda_beep *beep)/* turn off beep */ generate_tone (beep,0 ); } +if (beep->keep_power_at_enable) +snd_hda_power_down_pm (beep->codec); }/**
@@ -140,7 +148,9 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) enable = !!enable;if (beep->enabled != enable) { beep->enabled = enable; -if (!enable) +if (enable) +turn_on_beep (beep); +else turn_off_beep (beep);return 1 ; }
@@ -167,7 +177,8 @@ static int beep_dev_disconnect(struct snd_device *device)input_unregister_device (beep->dev); else input_free_device(beep->dev); -turn_off_beep (beep); +if (beep->enabled) +turn_off_beep (beep);return 0 ; }
sound/pci/hda/hda_beep.h +1 -0
@@ -25,6 +25,7 @@ struct hda_beep { unsigned int enabled:1; unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ unsigned int playing:1; + unsigned int keep_power_at_enable:1; /* set by driver */struct work_struct beep_work;/* scheduled task for beep event */ struct mutex mutex;void (*power_hook)(struct hda_beep *beep,bool on);
sound/pci/hda/patch_sigmatel.c +2 -23
@@ -4311,6 +4311,8 @@ static int stac_parse_auto_config(struct hda_codec *codec)if (codec->beep) {/* IDT/STAC codecs have linear beep tone parameter */ codec->beep->linear_tone = spec->linear_tone_beep; +/* keep power up while beep is enabled */ + codec->beep->keep_power_at_enable =1 ;/* if no beep switch is available, make its own one */ caps =query_amp_caps (codec, nid,HDA_OUTPUT );if (!(caps &AC_AMPCAP_MUTE )) {
@@ -4444,28 +4446,6 @@ static int stac_suspend(struct hda_codec *codec) return 0; } - -static int stac_check_power_status (struct hda_codec *codec,hda_nid_t nid) -{ -#ifdef CONFIG_SND_HDA_INPUT_BEEP -struct sigmatel_spec *spec = codec->spec; -#endif -int ret =snd_hda_gen_check_power_status (codec, nid); - -#ifdef CONFIG_SND_HDA_INPUT_BEEP -if (nid == spec->gen.beep_nid && codec->beep) { -if (codec->beep->enabled != spec->beep_power_on) { - spec->beep_power_on = codec->beep->enabled; -if (spec->beep_power_on) -snd_hda_power_up_pm (codec); -else -snd_hda_power_down_pm (codec); - } - ret |= spec->beep_power_on; - } -#endif -return ret; -}#else #define stac_suspend NULL#endif /* CONFIG_PM */
@@ -4478,7 +4458,6 @@ static const struct hda_codec_ops stac_patch_ops = { .unsol_event = snd_hda_jack_unsol_event, #ifdef CONFIG_PM .suspend = stac_suspend, - .check_power_status = stac_check_power_status,#endif };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 383/862 drm/virtio: set fb_modifiers_not_supported
In reply to Greg Kroah-HartmanFrom: Chia-I Wu <[email protected]>
[ Upstream commit 85faca8ca0f659263b5fb2385e4c231cc075bd84 ]
Without this, the drm core advertises LINEAR modifier which is incorrect.
Also userspace virgl does not support modifiers. For example, it causes chrome on ozone/drm to fail with "Failed to create scanout buffer".
--- drivers/gpu/drm/virtio/virtgpu_display.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/virtio/virtgpu_display.c +2 -0
@@ -349,6 +349,8 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) vgdev->ddev->mode_config.max_width =XRES_MAX ; vgdev->ddev->mode_config.max_height =YRES_MAX ; + vgdev->ddev->mode_config.fb_modifiers_not_supported = true; +for (i =0 ; i < vgdev->num_scanouts; ++i)vgdev_output_init (vgdev, i);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 384/862 drm/bochs: fix blanking
In reply to Greg Kroah-HartmanFrom: Gerd Hoffmann <[email protected]>
[ Upstream commit e740ceb53e4579a7a4063712cebecac3c343b189 ]
VGA_IS1_RC is the color mode register (VGA_IS1_RM the one for monochrome mode, note C vs. M at the end). So when using VGA_IS1_RC make sure the vga device is actually in color mode and set the corresponding bit in the misc register.
Reproducible when booting VMs in UEFI mode with some edk2 versions (edk2 fix is on the way too). Doesn't happen in BIOS mode because in that case the vgabios already flips the bit.
--- drivers/gpu/drm/tiny/bochs.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/tiny/bochs.c +2 -0
@@ -309,6 +309,8 @@ static void bochs_hw_fini(struct drm_device *dev)static void bochs_hw_blank (struct bochs_device *bochs,bool blank) {DRM_DEBUG_DRIVER ("hw_blank %d\n" , blank); +/* enable color bit (so VGA_IS1_RC access works) */ +bochs_vga_writeb (bochs,VGA_MIS_W ,VGA_MIS_COLOR );/* discard ar_flip_flop */ (void )bochs_vga_readb (bochs,VGA_IS1_RC );/* blank or unblank; we need only update index and set 0x20 */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 385/862 ASoC: mediatek: mt8195-mt6359: Properly register sound card for SOF
In reply to Greg Kroah-HartmanFrom: AngeloGioacchino Del Regno <[email protected]>
[ Upstream commit 64ec924c781ee846bd469be8d1d6bbed78c0f439 ]
Adding a probe callback on this snd_soc_card is required when Sound Open Firmware support is desired, as we need to appropriately populate the stream_name for SOF to be able to bind widgets. Failing to do so will produce errors when applying the SOF topology leading to card registration failure (so, no sound).
While at it, also make sure to fill the topology_shortname as required.
--- sound/soc/mediatek/mt8195/mt8195-mt6359.c | 6 ++++++ 1 file changed, 6 insertions(+)
sound/soc/mediatek/mt8195/mt8195-mt6359.c +6 -0
@@ -1383,7 +1383,13 @@ static int mt8195_mt6359_dev_probe(struct platform_device *pdev) sof_priv->num_streams =ARRAY_SIZE (g_sof_conn_streams); sof_priv->sof_dai_link_fixup = mt8195_dai_link_fixup; soc_card_data->sof_priv = sof_priv; + card->probe = mtk_sof_card_probe; card->late_probe = mtk_sof_card_late_probe; +if (!card->topology_shortname_created) { +snprintf (card->topology_shortname,32 ,"sof-%s" , card->name); + card->topology_shortname_created = true; + } + card->name = card->topology_shortname; sof_on =1 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 386/862 ASoC: SOF: mediatek: mt8195: Import namespace SND_SOC_SOF_MTK_COMMON
In reply to Greg Kroah-HartmanFrom: AngeloGioacchino Del Regno <[email protected]>
[ Upstream commit 404bec4c8f6c38ae5fa208344f1086d38026e93d ]
Here we're using function mtk_adsp_dump() from mtk-adsp-common:
explicitly import its namespace.
--- sound/soc/sof/mediatek/mt8195/mt8195.c | 1 + 1 file changed, 1 insertion(+)
sound/soc/sof/mediatek/mt8195/mt8195.c +1 -0
@@ -652,4 +652,5 @@ static struct platform_driver snd_sof_of_mt8195_driver = {module_platform_driver (snd_sof_of_mt8195_driver);MODULE_IMPORT_NS (SND_SOC_SOF_XTENSA ); +MODULE_IMPORT_NS (SND_SOC_SOF_MTK_COMMON );MODULE_LICENSE ("Dual BSD/GPL" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 387/862 drm/omap: dss: Fix refcount leak bugs
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 8b42057e62120813ebe9274f508fa785b7cab33a ]
In dss_init_ports() and __dss_uninit_ports(), we should call of_node_put() for the reference returned by of_graph_get_port_by_id() in fail path or when it is not used anymore.
--- drivers/gpu/drm/omapdrm/dss/dss.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/omapdrm/dss/dss.c +3 -0
@@ -1176,6 +1176,7 @@ static void __dss_uninit_ports(struct dss_device *dss, unsigned int num_ports)default :break ; } +of_node_put (port); } }
@@ -1208,11 +1209,13 @@ static int dss_init_ports(struct dss_device *dss)default :break ; } +of_node_put (port); }return 0 ; error: +of_node_put (port);__dss_uninit_ports (dss, i);return r; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 388/862 drm/amdgpu: Fix memory leak in hpd_rx_irq_create_workqueue()
In reply to Greg Kroah-HartmanFrom: Rafael Mendonca <[email protected]>
[ Upstream commit 7136f956c73c4ba50bfeb61653dfd6a9669ea915 ]
If construction of the array of work queues to handle hpd_rx_irq offload work fails, we need to unwind. Destroy all the created workqueues and the allocated memory for the hpd_rx_irq_offload_work_queue struct array.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +9 -1
@@ -1296,13 +1296,21 @@ static struct hpd_rx_irq_offload_work_queue *hpd_rx_irq_create_workqueue(structif (hpd_rx_offload_wq[i].wq ==NULL ) {DRM_ERROR ("create amdgpu_dm_hpd_rx_offload_wq fail!" ); -return NULL ; + goto out_err; }spin_lock_init (&hpd_rx_offload_wq[i].offload_lock); }return hpd_rx_offload_wq; + +out_err: +for (i =0 ; i < max_caps; i++) { +if (hpd_rx_offload_wq[i].wq) +destroy_workqueue (hpd_rx_offload_wq[i].wq); + } +kfree (hpd_rx_offload_wq); +return NULL ; }struct amdgpu_stutter_quirk {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 389/862 ASoC: rockchip: i2s: use regmap_read_poll_timeout to poll I2S_CLR
In reply to Greg Kroah-HartmanFrom: Judy Hsiao <[email protected]>
[ Upstream commit fbb0ec656ee5ee43b4b3022fd8290707265c52df ]
Use regmap_read_poll_timeout to poll I2S_CLR.
It also fixes the 'rockchip-i2s ff070000.i2s; fail to clear' when the read of I2S_CLR exceeds the retry limit.
--- sound/soc/rockchip/rockchip_i2s.c | 41 ++++++++++++------------------- 1 file changed, 16 insertions(+), 25 deletions(-)
sound/soc/rockchip/rockchip_i2s.c +16 -25
@@ -126,7 +126,6 @@ static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai)static int rockchip_snd_txctrl (struct rk_i2s_dev *i2s,int on) {unsigned int val =0 ; -int retry =10 ;int ret =0 ;spin_lock (&i2s->lock);
@@ -163,18 +162,14 @@ static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) I2S_CLR_TXC | I2S_CLR_RXC);if (ret <0 ) goto end; -regmap_read (i2s->regmap,I2S_CLR , &val); - -/* Should wait for clear operation to finish */ -while (val) { -regmap_read (i2s->regmap,I2S_CLR , &val); - retry--; -if (!retry) { -dev_warn (i2s->dev,"fail to clear\n" ); - ret = -EBUSY ; -break ; - } - } + ret =regmap_read_poll_timeout (i2s->regmap, +I2S_CLR , + val, + val !=0 , +20 , +200 ); +if (ret <0 ) +dev_warn (i2s->dev,"fail to clear: %d\n" , ret); } } end:
@@ -188,7 +183,6 @@ static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)static int rockchip_snd_rxctrl (struct rk_i2s_dev *i2s,int on) {unsigned int val =0 ; -int retry =10 ;int ret =0 ;spin_lock (&i2s->lock);
@@ -226,17 +220,14 @@ static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) I2S_CLR_TXC | I2S_CLR_RXC);if (ret <0 ) goto end; -regmap_read (i2s->regmap,I2S_CLR , &val); -/* Should wait for clear operation to finish */ -while (val) { -regmap_read (i2s->regmap,I2S_CLR , &val); - retry--; -if (!retry) { -dev_warn (i2s->dev,"fail to clear\n" ); - ret = -EBUSY ; -break ; - } - } + ret =regmap_read_poll_timeout (i2s->regmap, +I2S_CLR , + val, + val !=0 , +20 , +200 ); +if (ret <0 ) +dev_warn (i2s->dev,"fail to clear: %d\n" , ret); } } end:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 390/862 mmc: au1xmmc: Fix an error handling path in au1xmmc_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 5cbedf52608cc3cbc1c2a9a861fb671620427a20 ]
If clk_prepare_enable() fails, there is no point in calling clk_disable_unprepare() in the error handling path.
Move the out_clk label at the right place.
--- drivers/mmc/host/au1xmmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/mmc/host/au1xmmc.c +2 -1
@@ -1097,8 +1097,9 @@ static int au1xmmc_probe(struct platform_device *pdev)if (host->platdata && host->platdata->cd_setup && !(mmc->caps &MMC_CAP_NEEDS_POLL )) host->platdata->cd_setup (mmc,0 ); -out_clk: +clk_disable_unprepare (host->clk); +out_clk:clk_put (host->clk); out_irq:free_irq (host->irq, host);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 391/862 ASoC: eureka-tlv320: Hold reference returned from of_find_xxx API
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit bfb735a3ceff0bab6473bac275da96f9b2a06dec ]
In eukrea_tlv320_probe(), we need to hold the reference returned from of_find_compatible_node() which has increased the refcount and then call of_node_put() with it when done.
--- sound/soc/fsl/eukrea-tlv320.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
sound/soc/fsl/eukrea-tlv320.c +5 -3
@@ -86,7 +86,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)int ret;int int_port =0 , ext_port;struct device_node *np = pdev->dev.of_node; -struct device_node *ssi_np =NULL , *codec_np =NULL ; +struct device_node *ssi_np =NULL , *codec_np =NULL , *tmp_np =NULL ; eukrea_tlv320.dev = &pdev->dev;if (np) {
@@ -143,7 +143,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) }if (machine_is_eukrea_cpuimx27 () || -of_find_compatible_node (NULL ,NULL ,"fsl,imx21-audmux" )) { + (tmp_np =of_find_compatible_node (NULL ,NULL ,"fsl,imx21-audmux" ))) { imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, IMX_AUDMUX_V1_PCR_SYN | IMX_AUDMUX_V1_PCR_TFSDIR |
@@ -158,10 +158,11 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)IMX_AUDMUX_V1_PCR_SYN |IMX_AUDMUX_V1_PCR_RXDSEL (MX27_AUDMUX_HPCR1_SSI0 ) ); +of_node_put (tmp_np); }else if (machine_is_eukrea_cpuimx25sd () ||machine_is_eukrea_cpuimx35sd () ||machine_is_eukrea_cpuimx51sd () || -of_find_compatible_node (NULL ,NULL ,"fsl,imx31-audmux" )) { + (tmp_np =of_find_compatible_node (NULL ,NULL ,"fsl,imx31-audmux" ))) {if (!np) ext_port =machine_is_eukrea_cpuimx25sd () ?4 :3 ;
@@ -178,6 +179,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)IMX_AUDMUX_V2_PTCR_SYN ,IMX_AUDMUX_V2_PDCR_RXDSEL (int_port) ); +of_node_put (tmp_np); }else {if (np) {/* The eukrea,asoc-tlv320 driver was explicitly
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 392/862 drm/msm: lookup the ICC paths in both mdp5/dpu and mdss devices
In reply to Greg Kroah-HartmanFrom: Dmitry Baryshkov <[email protected]>
[ Upstream commit 5ccdcecaf8f732f593e359ebfb65de96b11bae66 ]
The commit 6874f48bb8b0 ("drm/msm: make mdp5/dpu devices master components") changed the MDP5 driver to look for the interconnect paths in the MDSS device rather than in the MDP5 device itself. This was left unnoticed since on my testing devices the interconnects probably didn't reach the sync state.
Rather than just using the MDP5 device for ICC path lookups for the MDP5 devices, introduce an additional helper to check both MDP5/DPU and MDSS nodes. This will be helpful for the MDP5->DPU conversion, since the driver will have to check both nodes.
Patchwork: https://patchwork.freedesktop.org/patch/496488/
--- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 7 ++----- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 9 +++------ drivers/gpu/drm/msm/msm_drv.h | 2 ++ drivers/gpu/drm/msm/msm_io_utils.c | 22 ++++++++++++++++++++++ 4 files changed, 29 insertions(+), 11 deletions(-)
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +2 -5
@@ -384,12 +384,9 @@ static int dpu_kms_parse_data_bus_icc_path(struct dpu_kms *dpu_kms)struct icc_path *path1;struct drm_device *dev = dpu_kms->dev;struct device *dpu_dev = dev->dev; -struct device *mdss_dev = dpu_dev->parent; -/* Interconnects are a part of MDSS device tree binding, not the -* MDP/DPU device. */ - path0 =of_icc_get (mdss_dev,"mdp0-mem" ); - path1 =of_icc_get (mdss_dev,"mdp1-mem" ); + path0 =msm_icc_get (dpu_dev,"mdp0-mem" ); + path1 =msm_icc_get (dpu_dev,"mdp1-mem" );if (IS_ERR_OR_NULL (path0))return PTR_ERR_OR_ZERO (path0);
drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +3 -6
@@ -902,12 +902,9 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)static int mdp5_setup_interconnect (struct platform_device *pdev) { -/* Interconnects are a part of MDSS device tree binding, not the -* MDP5 device. */ -struct device *mdss_dev = pdev->dev.parent; -struct icc_path *path0 =of_icc_get (mdss_dev,"mdp0-mem" ); -struct icc_path *path1 =of_icc_get (mdss_dev,"mdp1-mem" ); -struct icc_path *path_rot =of_icc_get (mdss_dev,"rotator-mem" ); +struct icc_path *path0 =msm_icc_get (&pdev->dev,"mdp0-mem" ); +struct icc_path *path1 =msm_icc_get (&pdev->dev,"mdp1-mem" ); +struct icc_path *path_rot =msm_icc_get (&pdev->dev,"rotator-mem" );if (IS_ERR (path0))return PTR_ERR (path0);
drivers/gpu/drm/msm/msm_drv.h +2 -0
@@ -433,6 +433,8 @@ void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name, phys_addr_t *size);void __iomem *msm_ioremap_quiet (struct platform_device *pdev,const char *name); +struct icc_path *msm_icc_get (struct device *dev,const char *name); +#define msm_writel (data, addr) writel((data), (addr))#define msm_readl (addr) readl((addr))
drivers/gpu/drm/msm/msm_io_utils.c +22 -0
@@ -5,6 +5,8 @@* Author: Rob Clark <[email protected]> */ +#include <linux/interconnect.h> +#include "msm_drv.h" /*
@@ -124,3 +126,23 @@ void msm_hrtimer_work_init(struct msm_hrtimer_work *work, work->worker = worker;kthread_init_work (&work->work, fn); } + +struct icc_path *msm_icc_get (struct device *dev,const char *name) +{ +struct device *mdss_dev = dev->parent; +struct icc_path *path; + + path =of_icc_get (dev, name); +if (path) +return path; + +/* +* If there are no interconnects attached to the corresponding device +* node, of_icc_get() will return NULL. +* +* If the MDP5/DPU device node doesn't have interconnects, lookup the +* path in the parent (MDSS) device. +*/ +return of_icc_get (mdss_dev, name); + +}
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 393/862 drm/msm/dpu: index dpu_kms->hw_vbif using vbif_idx
In reply to Greg Kroah-HartmanFrom: Dmitry Baryshkov <[email protected]>
[ Upstream commit 7538f80ae0d98bf51eb89eee5344aec219902d42 ]
Remove loops over hw_vbif. Instead always VBIF's idx as an index in the array. This fixes an error in dpu_kms_hw_init(), where we fill dpu_kms->hw_vbif[i], but check for an error pointer at dpu_kms->hw_vbif[vbif_idx].
Patchwork: https://patchwork.freedesktop.org/patch/489569/
--- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 12 ++++------ drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c | 29 +++++++++++------------- 2 files changed, 18 insertions(+), 23 deletions(-)
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +5 -7
@@ -823,12 +823,10 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)_dpu_kms_mmu_destroy (dpu_kms);if (dpu_kms->catalog) { -for (i =0 ; i < dpu_kms->catalog->vbif_count; i++) { -u32 vbif_idx = dpu_kms->catalog->vbif[i].id; - -if ((vbif_idx <VBIF_MAX ) && dpu_kms->hw_vbif[vbif_idx]) { -dpu_hw_vbif_destroy (dpu_kms->hw_vbif[vbif_idx]); - dpu_kms->hw_vbif[vbif_idx] =NULL ; +for (i =0 ; i <ARRAY_SIZE (dpu_kms->hw_vbif); i++) { +if (dpu_kms->hw_vbif[i]) { +dpu_hw_vbif_destroy (dpu_kms->hw_vbif[i]); + dpu_kms->hw_vbif[i] =NULL ; } } }
@@ -1110,7 +1108,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms)for (i =0 ; i < dpu_kms->catalog->vbif_count; i++) {u32 vbif_idx = dpu_kms->catalog->vbif[i].id; - dpu_kms->hw_vbif[i] =dpu_hw_vbif_init (vbif_idx, + dpu_kms->hw_vbif[vbif_idx] =dpu_hw_vbif_init (vbif_idx, dpu_kms->vbif[vbif_idx], dpu_kms->catalog);if (IS_ERR_OR_NULL (dpu_kms->hw_vbif[vbif_idx])) { rc =PTR_ERR (dpu_kms->hw_vbif[vbif_idx]);
drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c +13 -16
@@ -11,6 +11,14 @@#include "dpu_hw_vbif.h" #include "dpu_trace.h" +static struct dpu_hw_vbif *dpu_get_vbif (struct dpu_kms *dpu_kms,enum dpu_vbif vbif_idx) +{ +if (vbif_idx <ARRAY_SIZE (dpu_kms->hw_vbif)) +return dpu_kms->hw_vbif[vbif_idx]; + +return NULL ; +} +/** * _dpu_vbif_wait_for_xin_halt - wait for the xin to halt * @vbif: Pointer to hardware vbif driver
@@ -148,20 +156,15 @@ static u32 _dpu_vbif_get_ot_limit(struct dpu_hw_vbif *vbif,void dpu_vbif_set_ot_limit (struct dpu_kms *dpu_kms,struct dpu_vbif_set_ot_params *params) { -struct dpu_hw_vbif *vbif =NULL ; +struct dpu_hw_vbif *vbif;struct dpu_hw_mdp *mdp;bool forced_on = false;u32 ot_lim; -int ret, i; +int ret; mdp = dpu_kms->hw_mdp; -for (i =0 ; i <ARRAY_SIZE (dpu_kms->hw_vbif); i++) { -if (dpu_kms->hw_vbif[i] && - dpu_kms->hw_vbif[i]->idx == params->vbif_idx) - vbif = dpu_kms->hw_vbif[i]; - } - + vbif =dpu_get_vbif (dpu_kms, params->vbif_idx);if (!vbif || !mdp) {DRM_DEBUG_ATOMIC ("invalid arguments vbif %d mdp %d\n" , vbif !=NULL , mdp !=NULL );
@@ -204,7 +207,7 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,void dpu_vbif_set_qos_remap (struct dpu_kms *dpu_kms,struct dpu_vbif_set_qos_params *params) { -struct dpu_hw_vbif *vbif =NULL ; +struct dpu_hw_vbif *vbif;struct dpu_hw_mdp *mdp;bool forced_on = false;const struct dpu_vbif_qos_tbl *qos_tbl;
@@ -216,13 +219,7 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms, } mdp = dpu_kms->hw_mdp; -for (i =0 ; i <ARRAY_SIZE (dpu_kms->hw_vbif); i++) { -if (dpu_kms->hw_vbif[i] && - dpu_kms->hw_vbif[i]->idx == params->vbif_idx) { - vbif = dpu_kms->hw_vbif[i]; -break ; - } - } + vbif =dpu_get_vbif (dpu_kms, params->vbif_idx);if (!vbif || !vbif->cap) {DPU_ERROR ("invalid vbif %d\n" , params->vbif_idx);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 394/862 drm/msm/dp: correct 1.62G link rate at dp_catalog_ctrl_config_msa()
In reply to Greg Kroah-HartmanFrom: Kuogee Hsieh <[email protected]>
[ Upstream commit aa0bff10af1c4b92e6b56e3e1b7f81c660d3ba78 ]
At current implementation there is an extra 0 at 1.62G link rate which cause no correct pixel_div selected for 1.62G link rate to calculate mvid and nvid. This patch delete the extra 0 to have mvid and nvid be calculated correctly.
Changes in v2:
-- fix Fixes tag's text
Changes in v3:
-- fix misspelling of "Reviewed-by"
Patchwork: https://patchwork.freedesktop.org/patch/499328/
--- drivers/gpu/drm/msm/dp/dp_catalog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/dp/dp_catalog.c +1 -1
@@ -431,7 +431,7 @@ void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog,if (rate == link_rate_hbr3) pixel_div =6 ; -else if (rate ==1620000 || rate ==270000 ) +else if (rate ==162000 || rate ==270000 ) pixel_div =2 ;else if (rate == link_rate_hbr2) pixel_div =4 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 395/862 ALSA: hda/hdmi: change type for the assigned variable
In reply to Greg Kroah-HartmanFrom: Jaroslav Kysela <[email protected]>
[ Upstream commit 4053a41282f8aae290d3fe7b8daef4c8c53a4ab8 ]
This change converts the assigned value from int type to the bool type to retain consistency with other structure members like 'setup', 'non_pcm' etc.
Stable-dep-of: fc6f923ecfa2 ("ALSA: hda/hdmi: Fix the converter allocation for the silent stream")
--- sound/pci/hda/patch_hdmi.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
sound/pci/hda/patch_hdmi.c +7 -7
@@ -53,7 +53,7 @@ MODULE_PARM_DESC(enable_all_pins, "Forcibly enable all pins");struct hdmi_spec_per_cvt {hda_nid_t cvt_nid; -int assigned; +bool assigned;/* the stream has been assigned */ unsigned int channels_min;unsigned int channels_max;u32 rates;
@@ -1204,7 +1204,7 @@ static int hdmi_pcm_open_no_pin(struct hda_pcm_stream *hinfo,return err; per_cvt =get_cvt (spec, cvt_idx); - per_cvt->assigned =1 ; + per_cvt->assigned = true; hinfo->nid = per_cvt->cvt_nid;pin_cvt_fixup (codec,NULL , per_cvt->cvt_nid);
@@ -1273,7 +1273,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, per_cvt =get_cvt (spec, cvt_idx);/* Claim converter */ - per_cvt->assigned =1 ; + per_cvt->assigned = true;set_bit (pcm_idx, &spec->pcm_in_use); per_pin =get_pin (spec, pin_idx);
@@ -1308,7 +1308,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,snd_hdmi_eld_update_pcm_info (&eld->info, hinfo);if (hinfo->channels_min > hinfo->channels_max || !hinfo->rates || !hinfo->formats) { - per_cvt->assigned =0 ; + per_cvt->assigned = false; hinfo->nid =0 ;snd_hda_spdif_ctls_unassign (codec, pcm_idx); err = -ENODEV ;
@@ -1767,7 +1767,7 @@ static void silent_stream_enable(struct hda_codec *codec, } per_cvt =get_cvt (spec, cvt_idx); - per_cvt->assigned =1 ; + per_cvt->assigned = true; per_pin->cvt_nid = per_cvt->cvt_nid; per_pin->silent_stream = true;
@@ -1827,7 +1827,7 @@ static void silent_stream_disable(struct hda_codec *codec, cvt_idx =cvt_nid_to_cvt_index (codec, per_pin->cvt_nid);if (cvt_idx >=0 && cvt_idx < spec->num_cvts) { per_cvt =get_cvt (spec, cvt_idx); - per_cvt->assigned =0 ; + per_cvt->assigned = false; }if (spec->silent_stream_type ==SILENT_STREAM_I915 ) {
@@ -2223,7 +2223,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, goto unlock; } per_cvt =get_cvt (spec, cvt_idx); - per_cvt->assigned =0 ; + per_cvt->assigned = false; hinfo->nid =0 ;azx_stream (get_azx_dev (substream))->stripe =0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 396/862 ALSA: hda/hdmi: Fix the converter allocation for the silent stream
In reply to Greg Kroah-HartmanFrom: Jaroslav Kysela <[email protected]>
[ Upstream commit fc6f923ecfa2fafd0600f1b7e2de09baf29865e2 ]
Track the converters handling the silent stream using a new variable to avoid mixing of the open/close and silent stream use. This change ensures the proper allocation of the converters.
--- sound/pci/hda/patch_hdmi.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-)
sound/pci/hda/patch_hdmi.c +12 -8
@@ -54,6 +54,7 @@ MODULE_PARM_DESC(enable_all_pins, "Forcibly enable all pins");struct hdmi_spec_per_cvt {hda_nid_t cvt_nid;bool assigned;/* the stream has been assigned */ +bool silent_stream;/* silent stream activated */ unsigned int channels_min;unsigned int channels_max;u32 rates;
@@ -988,7 +989,8 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,* of the pin. */ static int hdmi_choose_cvt (struct hda_codec *codec, -int pin_idx,int *cvt_id) +int pin_idx,int *cvt_id, +bool silent) {struct hdmi_spec *spec = codec->spec;struct hdmi_spec_per_pin *per_pin;
@@ -1003,6 +1005,9 @@ static int hdmi_choose_cvt(struct hda_codec *codec,if (per_pin && per_pin->silent_stream) { cvt_idx =cvt_nid_to_cvt_index (codec, per_pin->cvt_nid); + per_cvt =get_cvt (spec, cvt_idx); +if (per_cvt->assigned && !silent) +return -EBUSY ;if (cvt_id) *cvt_id = cvt_idx;return 0 ;
@@ -1013,7 +1018,7 @@ static int hdmi_choose_cvt(struct hda_codec *codec, per_cvt =get_cvt (spec, cvt_idx);/* Must not already be assigned */ -if (per_cvt->assigned) +if (per_cvt->assigned || per_cvt->silent_stream)continue ;if (per_pin ==NULL )break ;
@@ -1199,7 +1204,7 @@ static int hdmi_pcm_open_no_pin(struct hda_pcm_stream *hinfo,if (pcm_idx <0 )return -EINVAL ; - err =hdmi_choose_cvt (codec,-1 , &cvt_idx); + err =hdmi_choose_cvt (codec,-1 , &cvt_idx, false);if (err)return err;
@@ -1267,7 +1272,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, } } - err =hdmi_choose_cvt (codec, pin_idx, &cvt_idx); + err =hdmi_choose_cvt (codec, pin_idx, &cvt_idx, false);if (err <0 ) goto unlock;
@@ -1278,7 +1283,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,set_bit (pcm_idx, &spec->pcm_in_use); per_pin =get_pin (spec, pin_idx); per_pin->cvt_nid = per_cvt->cvt_nid; - per_pin->silent_stream = false; hinfo->nid = per_cvt->cvt_nid;/* flip stripe flag for the assigned stream if supported */
@@ -1760,14 +1764,14 @@ static void silent_stream_enable(struct hda_codec *codec, } pin_idx =pin_id_to_pin_index (codec, per_pin->pin_nid, per_pin->dev_id); - err =hdmi_choose_cvt (codec, pin_idx, &cvt_idx); + err =hdmi_choose_cvt (codec, pin_idx, &cvt_idx, true);if (err) {codec_err (codec,"hdmi: no free converter to enable silent mode\n" ); goto unlock_out; } per_cvt =get_cvt (spec, cvt_idx); - per_cvt->assigned = true; + per_cvt->silent_stream = true; per_pin->cvt_nid = per_cvt->cvt_nid; per_pin->silent_stream = true;
@@ -1827,7 +1831,7 @@ static void silent_stream_disable(struct hda_codec *codec, cvt_idx =cvt_nid_to_cvt_index (codec, per_pin->cvt_nid);if (cvt_idx >=0 && cvt_idx < spec->num_cvts) { per_cvt =get_cvt (spec, cvt_idx); - per_cvt->assigned = false; + per_cvt->silent_stream = false; }if (spec->silent_stream_type ==SILENT_STREAM_I915 ) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 397/862 ALSA: usb-audio: Properly refcounting clock rate
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
[ Upstream commit 9a737e7f8b371e97eb649904276407cee2c9cf30 ]
We fixed the bug introduced by the patch for managing the shared clocks at the commit 809f44a0cc5a ("ALSA: usb-audio: Clear fixed clock rate at closing EP"), but it was merely a workaround. By this change, the clock reference rate is cleared at each EP close, hence the still remaining EP may need a re-setup of rate unnecessarily.
This patch introduces the proper refcounting for the clock reference object so that the clock setup is done only when needed.
--- sound/usb/endpoint.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
sound/usb/endpoint.c +7 -4
@@ -39,6 +39,7 @@ struct snd_usb_iface_ref {struct snd_usb_clock_ref {unsigned char clock;atomic_t locked; +int opened;int rate;struct list_head list; };
@@ -802,6 +803,7 @@ snd_usb_endpoint_open(struct snd_usb_aud ep =NULL ; goto unlock; } + ep->clock_ref->opened++; } ep->cur_audiofmt = fp;
@@ -925,8 +927,10 @@ void snd_usb_endpoint_close(struct snd_uendpoint_set_interface (chip, ep, false);if (!--ep->opened) { -if (ep->clock_ref && !atomic_read (&ep->clock_ref->locked)) - ep->clock_ref->rate =0 ; +if (ep->clock_ref) { +if (!--ep->clock_ref->opened) + ep->clock_ref->rate =0 ; + } ep->iface =0 ; ep->altsetting =0 ; ep->cur_audiofmt =NULL ;
@@ -1633,8 +1637,7 @@ void snd_usb_endpoint_stop(struct snd_usWRITE_ONCE (ep->sync_source->sync_sink,NULL );stop_urbs (ep, false, keep_pending);if (ep->clock_ref) -if (!atomic_dec_return (&ep->clock_ref->locked)) - ep->clock_ref->rate =0 ; +atomic_dec (&ep->clock_ref->locked); } }
Greg Kroah-Hartman
maintainerPATCH 398/862 ASoC: SOF: ipc4-topology: Free the ida when IPC fails in sof_ipc4_widget_setup()
In reply to Greg Kroah-HartmanFrom: Peter Ujfalusi <[email protected]>
[ Upstream commit 61eb0add28023119773d6aab8f402e149473920c ]
The allocated ida needs to be freed up if the IPC message fails since next time when we try again to set up the widget we are going to try to allocate another ID and given enough tries, we are going to run out of unique IDs.
--- sound/soc/sof/ipc4-topology.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
sound/soc/sof/ipc4-topology.c +8 -1
@@ -1544,9 +1544,16 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget msg->data_ptr = ipc_data; ret =sof_ipc_tx_message (sdev->ipc, msg, ipc_size,NULL ,0 ); -if (ret <0 ) +if (ret <0 ) {dev_err (sdev->dev,"failed to create module %s\n" , swidget->widget->name); +if (swidget->id != snd_soc_dapm_scheduler) { +struct sof_ipc4_fw_module *fw_module = swidget->module_info; + +ida_free (&fw_module->m_ida, swidget->instance_id); + } + } +return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 399/862 drm/vmwgfx: Fix memory leak in vmw_mksstat_add_ioctl()
In reply to Greg Kroah-HartmanFrom: Rafael Mendonca <[email protected]>
[ Upstream commit a40c7f61d12fbd1e785e59140b9efd57127c0c33 ]
If the copy of the description string from userspace fails, then the page for the instance descriptor doesn't get freed before returning -EFAULT, which leads to a memleak.
--- drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/vmwgfx/vmwgfx_msg.c +1 -0
@@ -1076,6 +1076,7 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data,if (desc_len <0 ) {atomic_set (&dev_priv->mksstat_user_pids[slot],0 ); +__free_page (page);return -EFAULT ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 400/862 virtio-gpu: fix shift wrapping bug in virtio_gpu_fence_event_create()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 37a78445763a5921bb54e9bad01937d0dfa521c1 ]
The ->ring_idx_mask variable is a u64 so static checkers, Smatch in this case, complain if the BIT() is not also a u64.
drivers/gpu/drm/virtio/virtgpu_ioctl.c:50 virtio_gpu_fence_event_create()
warn: should '(1 << ring_idx)' be a 64 bit type?
--- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/virtio/virtgpu_ioctl.c +1 -1
@@ -47,7 +47,7 @@ static int virtio_gpu_fence_event_create(struct drm_device *dev,struct virtio_gpu_fence_event *e =NULL ;int ret; -if (!(vfpriv->ring_idx_mask & (1 << ring_idx))) +if (!(vfpriv->ring_idx_mask &BIT_ULL (ring_idx)))return 0 ; e =kzalloc (sizeof (*e),GFP_KERNEL );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 401/862 ASoC: codecs: tx-macro: fix kcontrol put
In reply to Greg Kroah-HartmanFrom: Srinivas Kandagatla <[email protected]>
[ Upstream commit c1057a08af438e0cf5450c1d977a3011198ed2f8 ]
tx_macro_tx_mixer_put() and tx_macro_dec_mode_put() currently returns zero eventhough it changes the value.
Fix this, so that change notifications are sent correctly.
--- sound/soc/codecs/lpass-tx-macro.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
sound/soc/codecs/lpass-tx-macro.c +11 -2
@@ -823,17 +823,23 @@ static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol,struct tx_macro *tx =snd_soc_component_get_drvdata (component);if (enable) { +if (tx->active_decimator[dai_id] == dec_id) +return 0 ; +set_bit (dec_id, &tx->active_ch_mask[dai_id]); tx->active_ch_cnt[dai_id]++; tx->active_decimator[dai_id] = dec_id; }else { +if (tx->active_decimator[dai_id] ==-1 ) +return 0 ; + tx->active_ch_cnt[dai_id]--;clear_bit (dec_id, &tx->active_ch_mask[dai_id]); tx->active_decimator[dai_id] =-1 ; }snd_soc_dapm_mixer_update_power (widget->dapm, kcontrol, enable, update); -return 0 ; +return 1 ; } static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
@@ -1019,9 +1025,12 @@ static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol,int path = e->shift_l;struct tx_macro *tx =snd_soc_component_get_drvdata (component); +if (tx->dec_mode[path] == value) +return 0 ; + tx->dec_mode[path] = value; -return 0 ; +return 1 ; } static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 402/862 ASoC: da7219: Fix an error handling path in da7219_register_dai_clks()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit abb4e4349afe7eecdb0499582f1c777031e3a7c8 ]
If clk_hw_register() fails, the corresponding clk should not be unregistered.
To handle errors from loops, clean up partial iterations before doing the goto. So add a clk_hw_unregister().
Then use a while (--i >= 0) loop in the unwind section.
--- sound/soc/codecs/da7219.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
sound/soc/codecs/da7219.c +3 -2
@@ -2196,6 +2196,7 @@ static int da7219_register_dai_clks(struct snd_soc_component *component) dai_clk_lookup =clkdev_hw_create (dai_clk_hw, init.name,"%s" ,dev_name (dev));if (!dai_clk_lookup) { +clk_hw_unregister (dai_clk_hw); ret = -ENOMEM ; goto err; }else {
@@ -2217,12 +2218,12 @@ static int da7219_register_dai_clks(struct snd_soc_component *component)return 0 ; err: -do { +while (--i >=0 ) {if (da7219->dai_clks_lookup[i])clkdev_drop (da7219->dai_clks_lookup[i]);clk_hw_unregister (&da7219->dai_clks_hw[i]); - }while (i-- >0 ); + }if (np)kfree (da7219->clk_hw_data);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 403/862 ALSA: dmaengine: increment buffer pointer atomically
In reply to Greg Kroah-HartmanFrom: Andreas Pape <[email protected]>
[ Upstream commit d1c442019594692c64a70a86ad88eb5b6db92216 ]
Setting pointer and afterwards checking for wraparound leads to the possibility of returning the inconsistent pointer position.
This patch increments buffer pointer atomically to avoid this issue.
--- sound/core/pcm_dmaengine.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
sound/core/pcm_dmaengine.c +5 -3
@@ -133,12 +133,14 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data);static void dmaengine_pcm_dma_complete (void *arg) { +unsigned int new_pos;struct snd_pcm_substream *substream = arg;struct dmaengine_pcm_runtime_data *prtd =substream_to_prtd (substream); - prtd->pos +=snd_pcm_lib_period_bytes (substream); -if (prtd->pos >=snd_pcm_lib_buffer_bytes (substream)) - prtd->pos =0 ; + new_pos = prtd->pos +snd_pcm_lib_period_bytes (substream); +if (new_pos >=snd_pcm_lib_buffer_bytes (substream)) + new_pos =0 ; + prtd->pos = new_pos;snd_pcm_period_elapsed (substream); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 404/862 mmc: wmt-sdmmc: Fix an error handling path in wmt_mci_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit cb58188ad90a61784a56a64f5107faaf2ad323e7 ]
A dma_free_coherent() call is missing in the error handling path of the probe, as already done in the remove function.
--- drivers/mmc/host/wmt-sdmmc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/mmc/host/wmt-sdmmc.c +4 -1
@@ -846,7 +846,7 @@ static int wmt_mci_probe(struct platform_device *pdev)if (IS_ERR (priv->clk_sdmmc)) {dev_err (&pdev->dev,"Error getting clock\n" ); ret =PTR_ERR (priv->clk_sdmmc); - goto fail5; + goto fail5_and_a_half; } ret =clk_prepare_enable (priv->clk_sdmmc);
@@ -863,6 +863,9 @@ static int wmt_mci_probe(struct platform_device *pdev)return 0 ; fail6:clk_put (priv->clk_sdmmc); +fail5_and_a_half: +dma_free_coherent (&pdev->dev, mmc->max_blk_count *16 , + priv->dma_desc_buffer, priv->dma_desc_device_addr); fail5:free_irq (dma_irq, priv); fail4:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 405/862 ASoC: stm32: dfsdm: Fix PM disable depth imbalance in stm32_adfsdm_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit b9a0da5b2edcae2a901b85c8cc42efc5bec4bd7b ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. We fix it by moving pm_runtime_enable to the endding of stm32_adfsdm_probe.
--- sound/soc/stm/stm32_adfsdm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
sound/soc/stm/stm32_adfsdm.c +5 -3
@@ -335,8 +335,6 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)dev_set_drvdata (&pdev->dev, priv); -pm_runtime_enable (&pdev->dev); - ret =devm_snd_soc_register_component (&pdev->dev, &stm32_adfsdm_dai_component, &priv->dai_drv,1 );
@@ -366,9 +364,13 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)#endif ret =snd_soc_add_component (component,NULL ,0 ); -if (ret <0 ) +if (ret <0 ) {dev_err (&pdev->dev,"%s: Failed to register PCM platform\n" , __func__); +return ret; + } + +pm_runtime_enable (&pdev->dev);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 406/862 ASoC: stm32: spdifrx: Fix PM disable depth imbalance in stm32_spdifrx_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 0325cc0ac7980e1c7b744aab8df59afab6daeb43 ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. We fix it by moving pm_runtime_enable to the endding of stm32_spdifrx_probe.
--- sound/soc/stm/stm32_spdifrx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/stm/stm32_spdifrx.c +2 -2
@@ -1002,8 +1002,6 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)udelay (2 );reset_control_deassert (rst); -pm_runtime_enable (&pdev->dev); - pcm_config = &stm32_spdifrx_pcm_config; ret =snd_dmaengine_pcm_register (&pdev->dev, pcm_config,0 );if (ret)
@@ -1036,6 +1034,8 @@ static int stm32_spdifrx_probe(struct platform_device *pdev) FIELD_GET(SPDIFRX_VERR_MIN_MASK, ver)); } +pm_runtime_enable (&pdev->dev); +return ret; error:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 407/862 ASoC: stm: Fix PM disable depth imbalance in stm32_i2s_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 93618e5e05a3ce4aa6750268c5025bdb4cb7dc6e ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. We fix it by moving pm_runtime_enable to the endding of stm32_i2s_probe.
--- sound/soc/stm/stm32_i2s.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/stm/stm32_i2s.c +2 -2
@@ -1136,8 +1136,6 @@ static int stm32_i2s_probe(struct platform_device *pdev)return dev_err_probe (&pdev->dev,PTR_ERR (i2s->regmap),"Regmap init error\n" ); -pm_runtime_enable (&pdev->dev); - ret =snd_dmaengine_pcm_register (&pdev->dev, &stm32_i2s_pcm_config,0 );if (ret)return dev_err_probe (&pdev->dev, ret,"PCM DMA register error\n" );
@@ -1180,6 +1178,8 @@ static int stm32_i2s_probe(struct platform_device *pdev) FIELD_GET(I2S_VERR_MIN_MASK, val)); } +pm_runtime_enable (&pdev->dev); +return ret; error:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 408/862 ASoC: wcd-mbhc-v2: Revert "ASoC: wcd-mbhc-v2: use pm_runtime_resume_and_get()"
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
[ Upstream commit e18f6bcf8e864ea0e9690691d0d749c662b6a2c7 ]
This reverts commit ddea4bbf287b6028eaa15a185d0693856956ecf2 ("ASoC:
wcd-mbhc-v2: use pm_runtime_resume_and_get()"), because it introduced double runtime PM put if pm_runtime_get_sync() returns -EACCES:
wcd934x-codec wcd934x-codec.3.auto: WCD934X Minor:0x1 Version:0x401 wcd934x-codec wcd934x-codec.3.auto: Runtime PM usage count underflow!
The commit claimed no changes in functionality except dropping the reference on -EACCESS. This is exactly the change introducing bug because function calls unconditionally pm_runtime_put_autosuspend() at the end.
--- sound/soc/codecs/wcd-mbhc-v2.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
sound/soc/codecs/wcd-mbhc-v2.c +6 -4
@@ -714,11 +714,12 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc)struct snd_soc_component *component = mbhc->component;int ret; - ret =pm_runtime_resume_and_get (component->dev); + ret =pm_runtime_get_sync (component->dev);if (ret <0 && ret != -EACCES ) {dev_err_ratelimited (component->dev, -"pm_runtime_resume_and_get failed in %s, ret %d\n" , +"pm_runtime_get_sync failed in %s, ret %d\n" , __func__, ret); +pm_runtime_put_noidle (component->dev);return ret; }
@@ -1096,11 +1097,12 @@ static void wcd_correct_swch_plug(struct work_struct *work) mbhc = container_of(work, struct wcd_mbhc, correct_plug_swch); component = mbhc->component; - ret =pm_runtime_resume_and_get (component->dev); + ret =pm_runtime_get_sync (component->dev);if (ret <0 && ret != -EACCES ) {dev_err_ratelimited (component->dev, -"pm_runtime_resume_and_get failed in %s, ret %d\n" , +"pm_runtime_get_sync failed in %s, ret %d\n" , __func__, ret); +pm_runtime_put_noidle (component->dev);return ; } micbias_mv =wcd_mbhc_get_micbias (mbhc);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 409/862 ASoC: wm8997: Fix PM disable depth imbalance in wm8997_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 41a736ac20602f64773e80f0f5b32cde1830a44a ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. We fix it by moving pm_runtime_enable to the endding of wm8997_probe
--- sound/soc/codecs/wm8997.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/codecs/wm8997.c +3 -3
@@ -1161,9 +1161,6 @@ static int wm8997_probe(struct platform_device *pdev)regmap_update_bits (arizona->regmap, wm8997_digital_vu[i],WM8997_DIG_VU ,WM8997_DIG_VU ); -pm_runtime_enable (&pdev->dev); -pm_runtime_idle (&pdev->dev); -arizona_init_common (arizona); ret =arizona_init_vol_limit (arizona);
@@ -1182,6 +1179,9 @@ static int wm8997_probe(struct platform_device *pdev) goto err_spk_irqs; } +pm_runtime_enable (&pdev->dev); +pm_runtime_idle (&pdev->dev); +return ret; err_spk_irqs:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 410/862 ASoC: wm5110: Fix PM disable depth imbalance in wm5110_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 86b46bf1feb83898d89a2b4a8d08d21e9ea277a7 ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. We fix it by moving pm_runtime_enable to the endding of wm5110_probe.
--- sound/soc/codecs/wm5110.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/codecs/wm5110.c +3 -3
@@ -2457,9 +2457,6 @@ static int wm5110_probe(struct platform_device *pdev)regmap_update_bits (arizona->regmap, wm5110_digital_vu[i],WM5110_DIG_VU ,WM5110_DIG_VU ); -pm_runtime_enable (&pdev->dev); -pm_runtime_idle (&pdev->dev); - ret =arizona_request_irq (arizona,ARIZONA_IRQ_DSP_IRQ1 ,"ADSP2 Compressed IRQ" , wm5110_adsp2_irq, wm5110);
@@ -2492,6 +2489,9 @@ static int wm5110_probe(struct platform_device *pdev) goto err_spk_irqs; } +pm_runtime_enable (&pdev->dev); +pm_runtime_idle (&pdev->dev); +return ret; err_spk_irqs:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 411/862 ASoC: wm5102: Fix PM disable depth imbalance in wm5102_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit fcbb60820cd3008bb44334a0395e5e57ccb77329 ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. We fix it by moving pm_runtime_enable to the endding of wm5102_probe.
--- sound/soc/codecs/wm5102.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/codecs/wm5102.c +3 -3
@@ -2099,9 +2099,6 @@ static int wm5102_probe(struct platform_device *pdev)regmap_update_bits (arizona->regmap, wm5102_digital_vu[i],WM5102_DIG_VU ,WM5102_DIG_VU ); -pm_runtime_enable (&pdev->dev); -pm_runtime_idle (&pdev->dev); - ret =arizona_request_irq (arizona,ARIZONA_IRQ_DSP_IRQ1 ,"ADSP2 Compressed IRQ" , wm5102_adsp2_irq, wm5102);
@@ -2134,6 +2131,9 @@ static int wm5102_probe(struct platform_device *pdev) goto err_spk_irqs; } +pm_runtime_enable (&pdev->dev); +pm_runtime_idle (&pdev->dev); +return ret; err_spk_irqs:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 412/862 ASoC: mt6660: Fix PM disable depth imbalance in mt6660_i2c_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit b73f11e895e140537e7f8c7251211ccd3ce0782b ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. We fix it by moving pm_runtime_enable to the endding of mt6660_i2c_probe.
--- sound/soc/codecs/mt6660.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
sound/soc/codecs/mt6660.c +6 -2
@@ -503,13 +503,17 @@ static int mt6660_i2c_probe(struct i2c_client *client)dev_err (chip->dev,"read chip revision fail\n" ); goto probe_fail; } -pm_runtime_set_active (chip->dev); -pm_runtime_enable (chip->dev); ret =devm_snd_soc_register_component (chip->dev, &mt6660_component_driver, &mt6660_codec_dai,1 ); +if (!ret) { +pm_runtime_set_active (chip->dev); +pm_runtime_enable (chip->dev); + } +return ret; + probe_fail:_mt6660_chip_power_on (chip,0 );mutex_destroy (&chip->io_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 413/862 ASoC: rockchip: i2s: use regmap_read_poll_timeout_atomic to poll I2S_CLR
In reply to Greg Kroah-HartmanFrom: Judy Hsiao <[email protected]>
[ Upstream commit f0c8d7468af0001b80b0c86802ee28063f800987 ]
1. Uses regmap_read_poll_timeout_atomic to poll I2S_CLR as it is called within a spin lock.
2. Fixes the typo of break condition in regmap_read_poll_timeout_atomic.
--- sound/soc/rockchip/rockchip_i2s.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
sound/soc/rockchip/rockchip_i2s.c +12 -12
@@ -162,12 +162,12 @@ static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) I2S_CLR_TXC | I2S_CLR_RXC);if (ret <0 ) goto end; - ret =regmap_read_poll_timeout (i2s->regmap, -I2S_CLR , - val, - val !=0 , -20 , -200 ); + ret =regmap_read_poll_timeout_atomic (i2s->regmap, +I2S_CLR , + val, + val ==0 , +20 , +200 );if (ret <0 )dev_warn (i2s->dev,"fail to clear: %d\n" , ret); }
@@ -220,12 +220,12 @@ static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) I2S_CLR_TXC | I2S_CLR_RXC);if (ret <0 ) goto end; - ret =regmap_read_poll_timeout (i2s->regmap, -I2S_CLR , - val, - val !=0 , -20 , -200 ); + ret =regmap_read_poll_timeout_atomic (i2s->regmap, +I2S_CLR , + val, + val ==0 , +20 , +200 );if (ret <0 )dev_warn (i2s->dev,"fail to clear: %d\n" , ret); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 414/862 ALSA: hda/hdmi: Dont skip notification handling during PM operation
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
[ Upstream commit 5226c7b9784eee215e3914f440b3c2e1764f67a8 ]
The HDMI driver skips the notification handling from the graphics driver when the codec driver is being in the PM operation. This behavior was introduced by the commit eb399d3c99d8 ("ALSA: hda - Skip ELD notification during PM process"). This skip may cause a problem, as we may miss the ELD update when the connection/disconnection happens right at the runtime-PM operation of the audio codec.
Although this workaround was valid at that time, it's no longer true; the fix was required just because the ELD update procedure needed to wake up the audio codec, which had lead to a runtime-resume during a runtime-suspend. Meanwhile, the ELD update procedure doesn't need a codec wake up any longer since the commit 788d441a164c ("ALSA: hda - Use component ops for i915 HDMI/DP audio jack handling"); i.e. there is no much reason for skipping the notification.
Let's drop those checks for addressing the missing notification.
--- sound/pci/hda/patch_hdmi.c | 6 ------ 1 file changed, 6 deletions(-)
sound/pci/hda/patch_hdmi.c +0 -6
@@ -2751,9 +2751,6 @@ static void generic_acomp_pin_eld_notify(void *audio_ptr, int port, int dev_id)*/ if (codec->core.dev.power.power_state.event ==PM_EVENT_SUSPEND )return ; -/* ditto during suspend/resume process itself */ -if (snd_hdac_is_in_pm (&codec->core)) -return ;check_presence_and_report (codec, pin_nid, dev_id); }
@@ -2937,9 +2934,6 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe)*/ if (codec->core.dev.power.power_state.event ==PM_EVENT_SUSPEND )return ; -/* ditto during suspend/resume process itself */ -if (snd_hdac_is_in_pm (&codec->core)) -return ;snd_hdac_i915_set_bclk (&codec->bus->core);check_presence_and_report (codec, pin_nid, dev_id);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 415/862 memory: pl353-smc: Fix refcount leak bug in pl353_smc_probe()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 61b3c876c1cbdb1efd1f52a1f348580e6e14efb6 ]
The break of for_each_available_child_of_node() needs a corresponding of_node_put() when the reference 'child' is not used anymore. Here we do not need to call of_node_put() in fail path as '!match' means no break.
While the of_platform_device_create() will created a new reference by 'child' but it has considered the refcounting.
--- drivers/memory/pl353-smc.c | 1 + 1 file changed, 1 insertion(+)
drivers/memory/pl353-smc.c +1 -0
@@ -122,6 +122,7 @@ static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id) }of_platform_device_create (child,NULL , &adev->dev); +of_node_put (child);return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 416/862 memory: of: Fix refcount leak bug in of_get_ddr_timings()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 05215fb32010d4afb68fbdbb4d237df6e2d4567b ]
We should add the of_node_put() when breaking out of for_each_child_of_node() as it will automatically increase and decrease the refcount.
--- drivers/memory/of_memory.c | 1 + 1 file changed, 1 insertion(+)
drivers/memory/of_memory.c +1 -0
@@ -134,6 +134,7 @@ const struct lpddr2_timings *of_get_ddr_timings(struct device_node *np_ddr,for_each_child_of_node (np_ddr, np_tim) {if (of_device_is_compatible (np_tim, tim_compat)) {if (of_do_get_timings (np_tim, &timings[i])) { +of_node_put (np_tim);devm_kfree (dev, timings); goto default_timings; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 417/862 memory: of: Fix refcount leak bug in of_lpddr3_get_ddr_timings()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 48af14fb0eaa63d9aa68f59fb0b205ec55a95636 ]
We should add the of_node_put() when breaking out of for_each_child_of_node() as it will automatically increase and decrease the refcount.
--- drivers/memory/of_memory.c | 1 + 1 file changed, 1 insertion(+)
drivers/memory/of_memory.c +1 -0
@@ -285,6 +285,7 @@ const struct lpddr3_timingsif (of_device_is_compatible (np_tim, tim_compat)) {if (of_lpddr3_do_get_timings (np_tim, &timings[i])) {devm_kfree (dev, timings); +of_node_put (np_tim); goto default_timings; } i++;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 418/862 locks: fix TOCTOU race when granting write lease
In reply to Greg Kroah-HartmanFrom: Amir Goldstein <[email protected]>
[ Upstream commit d6da19c9cace63290ccfccb1fc35151ffefc0bec ]
Thread A trying to acquire a write lease checks the value of i_readcount and i_writecount in check_conflicting_open() to verify that its own fd is the only fd referencing the file.
Thread B trying to open the file for read will call break_lease() in do_dentry_open() before incrementing i_readcount, which leaves a small window where thread A can acquire the write lease and then thread B completes the open of the file for read without breaking the write lease that was acquired by thread A.
Fix this race by incrementing i_readcount before checking for existing leases, same as the case with i_writecount.
Use a helper put_file_access() to decrement i_readcount or i_writecount in do_dentry_open() and __fput().
--- fs/file_table.c | 7 +------ fs/internal.h | 10 ++++++++++ fs/open.c | 11 ++++------- 3 files changed, 15 insertions(+), 13 deletions(-)
fs/file_table.c +1 -6
@@ -324,12 +324,7 @@ static void __fput(struct file *file) }fops_put (file->f_op);put_pid (file->f_owner.pid); -if ((mode & (FMODE_READ |FMODE_WRITE )) ==FMODE_READ ) -i_readcount_dec (inode); -if (mode &FMODE_WRITER ) { -put_write_access (inode); -__mnt_drop_write (mnt); - } +put_file_access (file);dput (dentry);if (unlikely (mode &FMODE_NEED_UNMOUNT ))dissolve_on_fput (mnt);
fs/internal.h +10 -0
@@ -102,6 +102,16 @@ extern void chroot_fs_refs(const struct path *, const struct path *);extern struct file *alloc_empty_file (int ,const struct cred *);extern struct file *alloc_empty_file_noaccount (int ,const struct cred *); +static inline void put_file_access (struct file *file) +{ +if ((file->f_mode & (FMODE_READ |FMODE_WRITE )) ==FMODE_READ ) { +i_readcount_dec (file->f_inode); + }else if (file->f_mode &FMODE_WRITER ) { +put_write_access (file->f_inode); +__mnt_drop_write (file->f_path.mnt); + } +} +/* * super.c */
fs/open.c +4 -7
@@ -842,7 +842,9 @@ static int do_dentry_open(struct file *f,return 0 ; } -if (f->f_mode &FMODE_WRITE && !special_file (inode->i_mode)) { +if ((f->f_mode & (FMODE_READ |FMODE_WRITE )) ==FMODE_READ ) { +i_readcount_inc (inode); + }else if (f->f_mode &FMODE_WRITE && !special_file (inode->i_mode)) { error =get_write_access (inode);if (unlikely (error)) goto cleanup_file;
@@ -882,8 +884,6 @@ static int do_dentry_open(struct file *f, goto cleanup_all; } f->f_mode |=FMODE_OPENED ; -if ((f->f_mode & (FMODE_READ |FMODE_WRITE )) ==FMODE_READ ) -i_readcount_inc (inode);if ((f->f_mode &FMODE_READ ) &&likely (f->f_op->read || f->f_op->read_iter)) f->f_mode |=FMODE_CAN_READ ;
@@ -937,10 +937,7 @@ static int do_dentry_open(struct file *f,if (WARN_ON_ONCE (error >0 )) error = -EINVAL ;fops_put (f->f_op); -if (f->f_mode &FMODE_WRITER ) { -put_write_access (inode); -__mnt_drop_write (f->f_path.mnt); - } +put_file_access (f); cleanup_file:path_put (&f->f_path); f->f_path.mnt =NULL ;
Signature · 1 line
2.35.1