5.17.14-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainerPATCH 420/772 thermal/core: Fix memory leak in __thermal_cooling_device_register()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 98a160e898c0f4a979af9de3ab48b4b1d42d1dbb ]
I got memory leak as follows when doing fault injection test:
unreferenced object 0xffff888010080000 (size 264312):
comm "182", pid 102533, jiffies 4296434960 (age 10.100s) hex dump (first 32 bytes):
00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00 .....N..........
ff ff ff ff ff ff ff ff 40 7f 1f b9 ff ff ff ff ........@.......
backtrace:
[<0000000038b2f4fc>] kmalloc_order_trace+0x1d/0x110 mm/slab_common.c:969
[<00000000ebcb8da5>] __kmalloc+0x373/0x420 include/linux/slab.h:510
[<0000000084137f13>] thermal_cooling_device_setup_sysfs+0x15d/0x2d0 include/linux/slab.h:586
[<00000000352b8755>] __thermal_cooling_device_register+0x332/0xa60 drivers/thermal/thermal_core.c:927
[<00000000fb9f331b>] devm_thermal_of_cooling_device_register+0x6b/0xf0 drivers/thermal/thermal_core.c:1041
[<000000009b8012d2>] max6650_probe.cold+0x557/0x6aa drivers/hwmon/max6650.c:211
[<00000000da0b7e04>] i2c_device_probe+0x472/0xac0 drivers/i2c/i2c-core-base.c:561If device_register() fails, thermal_cooling_device_destroy_sysfs() need be called to free the memory allocated in thermal_cooling_device_setup_sysfs().
--- drivers/thermal/thermal_core.c | 1 + 1 file changed, 1 insertion(+)
drivers/thermal/thermal_core.c +1 -0
@@ -947,6 +947,7 @@ __thermal_cooling_device_register(struct device_node *np,return cdev; out_kfree_type: +thermal_cooling_device_destroy_sysfs (cdev);kfree (cdev->type);put_device (&cdev->device); cdev =NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 421/772 thermal/drivers/imx_sc_thermal: Fix refcount leak in imx_sc_thermal_probe
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 09700c504d8e63faffd2a2235074e8c5d130cb8f ]
of_find_node_by_name() returns a node pointer with refcount incremented, we should use of_node_put() on it when done. Add missing of_node_put() to avoid refcount leak.
--- drivers/thermal/imx_sc_thermal.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/thermal/imx_sc_thermal.c +4 -2
@@ -94,8 +94,8 @@ static int imx_sc_thermal_probe(struct platform_device *pdev) sensor =devm_kzalloc (&pdev->dev,sizeof (*sensor),GFP_KERNEL );if (!sensor) {of_node_put (child); -of_node_put (sensor_np); -return -ENOMEM ; + ret = -ENOMEM ; + goto put_node; } ret = thermal_zone_of_get_sensor_id(child,
@@ -124,7 +124,9 @@ static int imx_sc_thermal_probe(struct platform_device *pdev)dev_warn (&pdev->dev,"failed to add hwmon sysfs attributes\n" ); } +put_node:of_node_put (sensor_np); +of_node_put (np);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 422/772 bfq: Relax waker detection for shared queues
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
[ Upstream commit f950667356ce90a41b446b726d4595a10cb65415 ]
Currently we look for waker only if current queue has no requests. This makes sense for bfq queues with a single process however for shared queues when there is a larger number of processes the condition that queue has no requests is difficult to meet because often at least one process has some request in flight although all the others are waiting for the waker to do the work and this harms throughput. Relax the "no queued request for bfq queue" condition to "the current task has no queued requests yet". For this, we also need to start tracking number of requests in flight for each task.
This patch (together with the following one) restores the performance for dbench with 128 clients that regressed with commit c65e6fd460b4 ("bfq: Do not let waker requests skip proper accounting") because this commit makes requests of wakers properly enter BFQ queues and thus these queues become ineligible for the old waker detection logic. Dbench results:
Vanilla 5.18-rc3 5.18-rc3 + revert 5.18-rc3 patched Mean 1237.36 ( 0.00%) 950.16 * 23.21%* 988.35 * 20.12%*
Numbers are time to complete workload so lower is better.
--- block/bfq-iosched.c | 5 +++-- block/bfq-iosched.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-)
block/bfq-iosched.c +3 -2
@@ -2133,7 +2133,6 @@ static void bfq_check_waker(struct bfq_data *bfqd, struct bfq_queue *bfqq,if (!bfqd->last_completed_rq_bfqq || bfqd->last_completed_rq_bfqq == bfqq ||bfq_bfqq_has_short_ttime (bfqq) || - bfqq->dispatched >0 || now_ns - bfqd->last_completion >=4 *NSEC_PER_MSEC || bfqd->last_completed_rq_bfqq == bfqq->waker_bfqq)return ;
@@ -2210,7 +2209,7 @@ static void bfq_add_request(struct request *rq) bfqq->queued[rq_is_sync (rq)]++; bfqd->queued++; -if (RB_EMPTY_ROOT (&bfqq->sort_list) &&bfq_bfqq_sync (bfqq)) { +if (bfq_bfqq_sync (bfqq) &&RQ_BIC (rq)->requests <=1 ) {bfq_check_waker (bfqd, bfqq, now_ns);/*
@@ -6563,6 +6562,7 @@ static void bfq_finish_requeue_request(struct request *rq)bfq_completed_request (bfqq, bfqd); }bfq_finish_requeue_request_body (bfqq); +RQ_BIC (rq)->requests--;spin_unlock_irqrestore (&bfqd->lock, flags);/*
@@ -6796,6 +6796,7 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)bfqq_request_allocated (bfqq); bfqq->ref++; + bic->requests++;bfq_log_bfqq (bfqd, bfqq,"get_request %p: bfqq %p, %d" , rq, bfqq, bfqq->ref);
block/bfq-iosched.h +1 -0
@@ -469,6 +469,7 @@ struct bfq_io_cq {struct bfq_queue *stable_merge_bfqq;bool stably_merged;/* non splittable if true */ +unsigned int requests;/* Number of requests this process has in flight */ };/**
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 423/772 bfq: Allow current waker to defend against a tentative one
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
[ Upstream commit c5ac56bb6110e42e79d3106866658376b2e48ab9 ]
The code in bfq_check_waker() ignores wake up events from the current waker. This makes it more likely we select a new tentative waker although the current one is generating more wake up events. Treat current waker the same way as any other process and allow it to reset the waker detection logic.
--- block/bfq-iosched.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
block/bfq-iosched.c +1 -2
@@ -2133,8 +2133,7 @@ static void bfq_check_waker(struct bfq_data *bfqd, struct bfq_queue *bfqq,if (!bfqd->last_completed_rq_bfqq || bfqd->last_completed_rq_bfqq == bfqq ||bfq_bfqq_has_short_ttime (bfqq) || - now_ns - bfqd->last_completion >=4 *NSEC_PER_MSEC || - bfqd->last_completed_rq_bfqq == bfqq->waker_bfqq) + now_ns - bfqd->last_completion >=4 *NSEC_PER_MSEC )return ;/*
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 424/772 ASoC: wm2000: fix missing clk_disable_unprepare() on error in wm2000_anc_transition()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit be2af740e2a9c7134f2d8ab4f104006e110b13de ]
Fix the missing clk_disable_unprepare() before return from wm2000_anc_transition() in the error handling case.
--- sound/soc/codecs/wm2000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/codecs/wm2000.c +3 -3
@@ -536,7 +536,7 @@ static int wm2000_anc_transition(struct wm2000_priv *wm2000, {struct i2c_client *i2c = wm2000->i2c;int i, j; -int ret; +int ret =0 ;if (wm2000->anc_mode == mode)return 0 ;
@@ -566,13 +566,13 @@ static int wm2000_anc_transition(struct wm2000_priv *wm2000, ret = anc_transitions[i].step[j](i2c, anc_transitions[i].analogue);if (ret !=0 ) -return ret; +break ; }if (anc_transitions[i].dest ==ANC_OFF )clk_disable_unprepare (wm2000->mclk); -return 0 ; +return ret; }static int wm2000_anc_set_mode (struct wm2000_priv *wm2000)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 425/772 PM: domains: Fix initialization of genpds next_wakeup
In reply to Greg Kroah-HartmanFrom: Ulf Hansson <[email protected]>
[ Upstream commit 622d9b5577f19a6472db21df042fea8f5fefe244 ]
In the genpd governor we walk the list of child-domains to take into account their next_wakeup. If the child-domain itself, doesn't have a governor assigned to it, we can end up using the next_wakeup value before it has been properly initialized. To prevent a possible incorrect behaviour in the governor, let's initialize next_wakeup to KTIME_MAX.
--- drivers/base/power/domain.c | 1 + 1 file changed, 1 insertion(+)
drivers/base/power/domain.c +1 -0
@@ -1978,6 +1978,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd, genpd->device_count =0 ; genpd->max_off_time_ns =-1 ; genpd->max_off_time_changed = true; + genpd->next_wakeup =KTIME_MAX ; genpd->provider =NULL ; genpd->has_provider = false; genpd->accounting_time =ktime_get ();
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 426/772 net: macb: Fix PTP one step sync support
In reply to Greg Kroah-HartmanFrom: Harini Katakam <[email protected]>
[ Upstream commit 5cebb40bc9554aafcc492431181f43c6231b0459 ]
PTP one step sync packets cannot have CSUM padding and insertion in SW since time stamp is inserted on the fly by HW.
In addition, ptp4l version 3.0 and above report an error when skb timestamps are reported for packets that not processed for TX TS after transmission.
Add a helper to identify PTP one step sync and fix the above two errors. Add a common mask for PTP header flag field "twoStepflag". Also reset ptp OSS bit when one step is not selected.
--- drivers/net/ethernet/cadence/macb_main.c | 40 +++++++++++++++++++++--- drivers/net/ethernet/cadence/macb_ptp.c | 4 ++- include/linux/ptp_classify.h | 3 ++ 3 files changed, 42 insertions(+), 5 deletions(-)
drivers/net/ethernet/cadence/macb_main.c +36 -4
@@ -35,6 +35,7 @@#include <linux/tcp.h> #include <linux/iopoll.h> #include <linux/pm_runtime.h> +#include <linux/ptp_classify.h> #include "macb.h" /* This structure is only used for MACB on SiFive FU540 devices */
@@ -1122,6 +1123,36 @@ static void macb_tx_error_task(struct work_struct *work)spin_unlock_irqrestore (&bp->lock, flags); } +static bool ptp_one_step_sync (struct sk_buff *skb) +{ +struct ptp_header *hdr; +unsigned int ptp_class; +u8 msgtype; + +/* No need to parse packet if PTP TS is not involved */ +if (likely (!(skb_shinfo (skb)->tx_flags &SKBTX_HW_TSTAMP ))) + goto not_oss; + +/* Identify and return whether PTP one step sync is being processed */ + ptp_class =ptp_classify_raw (skb); +if (ptp_class ==PTP_CLASS_NONE ) + goto not_oss; + + hdr =ptp_parse_header (skb, ptp_class); +if (!hdr) + goto not_oss; + +if (hdr->flag_field[0 ] &PTP_FLAG_TWOSTEP ) + goto not_oss; + + msgtype =ptp_get_msgtype (hdr, ptp_class); +if (msgtype ==PTP_MSGTYPE_SYNC ) +return true; + +not_oss: +return false; +} +static void macb_tx_interrupt (struct macb_queue *queue) {unsigned int tail;
@@ -1166,8 +1197,8 @@ static void macb_tx_interrupt(struct macb_queue *queue)/* First, update TX stats if needed */ if (skb) { -if (unlikely (skb_shinfo (skb)->tx_flags & -SKBTX_HW_TSTAMP ) && +if (unlikely (skb_shinfo (skb)->tx_flags &SKBTX_HW_TSTAMP ) && + !ptp_one_step_sync (skb) &&gem_ptp_do_txstamp (queue, skb, desc) ==0 ) {/* skb now belongs to timestamp buffer * and will be removed later
@@ -1997,7 +2028,8 @@ static unsigned int macb_tx_map(struct macb *bp, ctrl |=MACB_BF (TX_LSO , lso_ctrl); ctrl |=MACB_BF (TX_TCP_SEQ_SRC , seq_ctrl);if ((bp->dev->features &NETIF_F_HW_CSUM ) && - skb->ip_summed !=CHECKSUM_PARTIAL && !lso_ctrl) + skb->ip_summed !=CHECKSUM_PARTIAL && !lso_ctrl && + !ptp_one_step_sync (skb)) ctrl |=MACB_BIT (TX_NOCRC ); }else /* Only set MSS/MFS on payload descriptors
@@ -2095,7 +2127,7 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)if (!(ndev->features &NETIF_F_HW_CSUM ) || !((*skb)->ip_summed !=CHECKSUM_PARTIAL ) || -skb_shinfo (*skb)->gso_size)/* Not available for GSO */ +skb_shinfo (*skb)->gso_size ||ptp_one_step_sync (*skb))return 0 ;if (padlen <=0 ) {
drivers/net/ethernet/cadence/macb_ptp.c +3 -1
@@ -470,8 +470,10 @@ int gem_set_hwtst(struct net_device *dev, struct ifreq *ifr, int cmd)case HWTSTAMP_TX_ONESTEP_SYNC :if (gem_ptp_set_one_step_sync (bp,1 ) !=0 )return -ERANGE ; - fallthrough; + tx_bd_control =TSTAMP_ALL_FRAMES ; +break ;case HWTSTAMP_TX_ON : +gem_ptp_set_one_step_sync (bp,0 ); tx_bd_control =TSTAMP_ALL_FRAMES ;break ;default :
include/linux/ptp_classify.h +3 -0
@@ -43,6 +43,9 @@#define OFF_PTP_SOURCE_UUID 22/* PTPv1 only */ #define OFF_PTP_SEQUENCE_ID 30 +/* PTP header flag fields */ +#define PTP_FLAG_TWOSTEP BIT(1) +/* Below defines should actually be removed at some point in time. */ #define IP6_HLEN 40#define UDP_HLEN 8
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 427/772 scsi: hisi_sas: Fix rescan after deleting a disk
In reply to Greg Kroah-HartmanFrom: John Garry <[email protected]>
[ Upstream commit e9dedc13bb11bc553754abecb322e5e41d1b4fef ]
Removing an ATA device via sysfs means that the device may not be found through re-scanning:
root@ubuntu:/home/john# lsscsi [0:0:0:0] disk SanDisk LT0200MO P404 /dev/sda [0:0:1:0] disk ATA HGST HUS724040AL A8B0 /dev/sdb [0:0:8:0] enclosu 12G SAS Expander RevB - root@ubuntu:/home/john# echo 1 > /sys/block/sdb/device/delete root@ubuntu:/home/john# echo "- - -" > /sys/class/scsi_host/host0/scan root@ubuntu:/home/john# lsscsi [0:0:0:0] disk SanDisk LT0200MO P404 /dev/sda [0:0:8:0] enclosu 12G SAS Expander RevB - root@ubuntu:/home/john#
The problem is that the rescan of the device may conflict with the device in being re-initialized, as follows:
- In the rescan we call hisi_sas_slave_alloc() in store_scan() -> sas_user_scan() -> [__]scsi_scan_target() -> scsi_probe_and_add_lunc() -> scsi_alloc_sdev() -> hisi_sas_slave_alloc() -> hisi_sas_init_device() In hisi_sas_init_device() we issue an IT nexus reset for ATA devices
- That IT nexus causes the remote PHY to go down and this triggers a bcast event
- In parallel libsas processes the bcast event, finds that the phy is down and marks the device as gone
The hard reset issued in hisi_sas_init_device() is unncessary - as described in the code comment - so remove it. Also set dev status as HISI_SAS_DEV_NORMAL as the hisi_sas_init_device() call.
--- drivers/scsi/hisi_sas/hisi_sas_main.c | 47 ++++++++++----------------- 1 file changed, 18 insertions(+), 29 deletions(-)
drivers/scsi/hisi_sas/hisi_sas_main.c +18 -29
@@ -680,8 +680,6 @@ static int hisi_sas_init_device(struct domain_device *device)struct hisi_sas_tmf_task tmf_task;int retry =HISI_SAS_DISK_RECOVER_CNT ;struct hisi_hba *hisi_hba =dev_to_hisi_hba (device); -struct device *dev = hisi_hba->dev; -struct sas_phy *local_phy;switch (device->dev_type) {case SAS_END_DEVICE :
@@ -702,30 +700,18 @@ static int hisi_sas_init_device(struct domain_device *device)case SAS_SATA_PM_PORT :case SAS_SATA_PENDING :/* -* send HARD RESET to clear previous affiliation of -* STP target port +* If an expander is swapped when a SATA disk is attached then +* we should issue a hard reset to clear previous affiliation +* of STP target port, see SPL (chapter 6.19.4). +* +* However we don't need to issue a hard reset here for these +* reasons: +* a. When probing the device, libsas/libata already issues a +* hard reset in sas_probe_sata() -> ata_sas_async_probe(). +* Note that in hisi_sas_debug_I_T_nexus_reset() we take care +* to issue a hard reset by checking the dev status (== INIT). +* b. When resetting the controller, this is simply unnecessary. */ - local_phy =sas_get_local_phy (device); -if (!scsi_is_sas_phy_local (local_phy) && - !test_bit (HISI_SAS_RESETTING_BIT , &hisi_hba->flags)) { -unsigned long deadline =ata_deadline (jiffies,20000 ); -struct sata_device *sata_dev = &device->sata_dev; -struct ata_host *ata_host = sata_dev->ata_host; -struct ata_port_operations *ops = ata_host->ops; -struct ata_port *ap = sata_dev->ap; -struct ata_link *link; -unsigned int classes; - -ata_for_each_link (link, ap,EDGE ) - rc = ops->hardreset (link, &classes, - deadline); - } -sas_put_local_phy (local_phy); -if (rc) { -dev_warn (dev,"SATA disk hardreset fail: %d\n" , rc); -return rc; - } -while (retry-- >0 ) { rc =hisi_sas_softreset_ata_disk (device);if (!rc)
@@ -741,15 +727,19 @@ static int hisi_sas_init_device(struct domain_device *device)int hisi_sas_slave_alloc (struct scsi_device *sdev) { -struct domain_device *ddev; +struct domain_device *ddev =sdev_to_domain_dev (sdev); +struct hisi_sas_device *sas_dev = ddev->lldd_dev;int rc; rc =sas_slave_alloc (sdev);if (rc)return rc; - ddev =sdev_to_domain_dev (sdev); -return hisi_sas_init_device (ddev); + rc =hisi_sas_init_device (ddev); +if (rc) +return rc; + sas_dev->dev_status =HISI_SAS_DEV_NORMAL ; +return 0 ; }EXPORT_SYMBOL_GPL (hisi_sas_slave_alloc);
@@ -799,7 +789,6 @@ static int hisi_sas_dev_found(struct domain_device *device)dev_info (dev,"dev[%d:%x] found\n" , sas_dev->device_id, sas_dev->dev_type); - sas_dev->dev_status =HISI_SAS_DEV_NORMAL ;return 0 ; err_out:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 428/772 NFC: hci: fix sleep in atomic context bugs in nfc_hci_hcp_message_tx
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit b413b0cb008646e9f24ce5253cb3cf7ee217aff6 ]
There are sleep in atomic context bugs when the request to secure element of st21nfca is timeout. The root cause is that kzalloc and alloc_skb with GFP_KERNEL parameter and mutex_lock are called in st21nfca_se_wt_timeout which is a timer handler. The call tree shows the execution paths that could lead to bugs:
(Interrupt context)st21nfca_se_wt_timeout
nfc_hci_send_event
nfc_hci_hcp_message_tx
kzalloc(..., GFP_KERNEL) //may sleep
alloc_skb(..., GFP_KERNEL) //may sleep
mutex_lock() //may sleep
This patch moves the operations that may sleep into a work item. The work item will run in another kernel thread which is in process context to execute the bottom half of the interrupt. So it could prevent atomic context from sleeping.
--- drivers/nfc/st21nfca/se.c | 17 ++++++++++++++--- drivers/nfc/st21nfca/st21nfca.h | 1 + 2 files changed, 15 insertions(+), 3 deletions(-)
drivers/nfc/st21nfca/se.c +14 -3
@@ -241,7 +241,7 @@ int st21nfca_hci_se_io(struct nfc_hci_dev *hdev, u32 se_idx, }EXPORT_SYMBOL (st21nfca_hci_se_io); -static void st21nfca_se_wt_timeout (struct timer_list *t) +static void st21nfca_se_wt_work (struct work_struct *work) {/* * No answer from the secure element
@@ -254,8 +254,9 @@ static void st21nfca_se_wt_timeout(struct timer_list *t)*/ /* hardware reset managed through VCC_UICC_OUT power supply */ u8 param =0x01 ; -struct st21nfca_hci_info *info =from_timer (info, t, - se_info.bwi_timer); +struct st21nfca_hci_info *info =container_of (work, + struct st21nfca_hci_info, + se_info.timeout_work); info->se_info.bwi_active = false;
@@ -271,6 +272,13 @@ static void st21nfca_se_wt_timeout(struct timer_list *t) info->se_info.cb (info->se_info.cb_context,NULL ,0 , -ETIME ); } +static void st21nfca_se_wt_timeout (struct timer_list *t) +{ +struct st21nfca_hci_info *info =from_timer (info, t, se_info.bwi_timer); + +schedule_work (&info->se_info.timeout_work); +} +static void st21nfca_se_activation_timeout (struct timer_list *t) { struct st21nfca_hci_info *info = from_timer(info, t,
@@ -360,6 +368,7 @@ int st21nfca_apdu_reader_event_received(struct nfc_hci_dev *hdev,switch (event) {case ST21NFCA_EVT_TRANSMIT_DATA :del_timer_sync (&info->se_info.bwi_timer); +cancel_work_sync (&info->se_info.timeout_work); info->se_info.bwi_active = false; r =nfc_hci_send_event (hdev,ST21NFCA_DEVICE_MGNT_GATE ,ST21NFCA_EVT_SE_END_OF_APDU_TRANSFER ,NULL ,0 );
@@ -389,6 +398,7 @@ void st21nfca_se_init(struct nfc_hci_dev *hdev)struct st21nfca_hci_info *info =nfc_hci_get_clientdata (hdev);init_completion (&info->se_info.req_completion); +INIT_WORK (&info->se_info.timeout_work, st21nfca_se_wt_work);/* initialize timers */ timer_setup (&info->se_info.bwi_timer, st21nfca_se_wt_timeout,0 ); info->se_info.bwi_active = false;
@@ -416,6 +426,7 @@ void st21nfca_se_deinit(struct nfc_hci_dev *hdev)if (info->se_info.se_active)del_timer_sync (&info->se_info.se_active_timer); +cancel_work_sync (&info->se_info.timeout_work); info->se_info.bwi_active = false; info->se_info.se_active = false; }
drivers/nfc/st21nfca/st21nfca.h +1 -0
@@ -141,6 +141,7 @@ struct st21nfca_se_info {se_io_cb_t cb;void *cb_context; +struct work_struct timeout_work; };struct st21nfca_hci_info {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 429/772 bonding: fix missed rcu protection
In reply to Greg Kroah-HartmanFrom: Hangbin Liu <[email protected]>
[ Upstream commit 9b80ccda233fa6c59de411bf889cc4d0e028f2c7 ]
When removing the rcu_read_lock in bond_ethtool_get_ts_info() as discussed [1], I didn't notice it could be called via setsockopt, which doesn't hold rcu lock, as syzbot pointed:
stack backtrace: CPU: 0 PID: 3599 Comm: syz-executor317 Not tainted 5.18.0-rc5-syzkaller-01392-g01f4685797a5 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106 bond_option_active_slave_get_rcu include/net/bonding.h:353 [inline] bond_ethtool_get_ts_info+0x32c/0x3a0 drivers/net/bonding/bond_main.c:5595 __ethtool_get_ts_info+0x173/0x240 net/ethtool/common.c:554 ethtool_get_phc_vclocks+0x99/0x110 net/ethtool/common.c:568 sock_timestamping_bind_phc net/core/sock.c:869 [inline] sock_set_timestamping+0x3a3/0x7e0 net/core/sock.c:916 sock_setsockopt+0x543/0x2ec0 net/core/sock.c:1221 __sys_setsockopt+0x55e/0x6a0 net/socket.c:2223 __do_sys_setsockopt net/socket.c:2238 [inline] __se_sys_setsockopt net/socket.c:2235 [inline] __x64_sys_setsockopt+0xba/0x150 net/socket.c:2235 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f8902c8eb39
Fix it by adding rcu_read_lock and take a ref on the real_dev. Since dev_hold() and dev_put() can take NULL these days, we can skip checking if real_dev exist.
[1] https://lore.kernel.org/netdev/27565.1642742439@famine/
--- drivers/net/bonding/bond_main.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
drivers/net/bonding/bond_main.c +12 -3
@@ -5383,16 +5383,23 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,const struct ethtool_ops *ops;struct net_device *real_dev;struct phy_device *phydev; +int ret =0 ; +rcu_read_lock (); real_dev =bond_option_active_slave_get_rcu (bond); +dev_hold (real_dev); +rcu_read_unlock (); +if (real_dev) { ops = real_dev->ethtool_ops; phydev = real_dev->phydev;if (phy_has_tsinfo (phydev)) { -return phy_ts_info (phydev, info); + ret =phy_ts_info (phydev, info); + goto out; }else if (ops->get_ts_info) { -return ops->get_ts_info (real_dev, info); + ret = ops->get_ts_info (real_dev, info); + goto out; } }
@@ -5400,7 +5407,9 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,SOF_TIMESTAMPING_SOFTWARE ; info->phc_index =-1 ; -return 0 ; +out: +dev_put (real_dev); +return ret; }static const struct ethtool_ops bond_ethtool_ops = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 430/772 ASoC: max98090: Move check for invalid values before casting in max98090_put_enab_tlv()
In reply to Greg Kroah-HartmanFrom: Alexey Khoroshilov <[email protected]>
[ Upstream commit f7a344468105ef8c54086dfdc800e6f5a8417d3e ]
Validation of signed input should be done before casting to unsigned int.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- sound/soc/codecs/max98090.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
sound/soc/codecs/max98090.c +4 -2
@@ -393,7 +393,8 @@ static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol,struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;unsigned int mask = (1 <<fls (mc->max)) -1 ; -unsigned int sel = ucontrol->value.integer.value[0 ]; +int sel_unchecked = ucontrol->value.integer.value[0 ]; +unsigned int sel;unsigned int val =snd_soc_component_read (component, mc->reg);unsigned int *select;
@@ -413,8 +414,9 @@ static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol, val = (val >> mc->shift) & mask; -if (sel <0 || sel > mc->max) +if (sel_unchecked <0 || sel_unchecked > mc->max)return -EINVAL ; + sel = sel_unchecked; *select = sel;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 431/772 perf parse-events: Support different format of the topdown event name
In reply to Greg Kroah-HartmanFrom: Kan Liang <[email protected]>
[ Upstream commit e7d1374ed5cb346efd9b3df03814dbc0767adb4e ]
The evsel->name may have a different format for a topdown event, a pure topdown name (e.g., topdown-fe-bound), or a PMU name + a topdown name (e.g., cpu/topdown-fe-bound/). The cpu/topdown-fe-bound/ kind format isn't supported by the arch_evlist__leader(). This format is a very common format for a hybrid platform, which requires specifying the PMU name for each event.
Without the patch,
$ perf stat -e '{instructions,slots,cpu/topdown-fe-bound/}' -a sleep 1Performance counter stats for 'system wide':
<not counted> instructions
<not counted> slots
<not supported> cpu/topdown-fe-bound/1.003482041 seconds time elapsed
Some events weren't counted. Try disabling the NMI watchdog:
echo 0 > /proc/sys/kernel/nmi_watchdog
perf stat ...
echo 1 > /proc/sys/kernel/nmi_watchdog
The events in group usually have to be from the same PMU. Try reorganizing the group.
With the patch,
$ perf stat -e '{instructions,slots,cpu/topdown-fe-bound/}' -a sleep 1Performance counter stats for 'system wide':
157,383,996 slots
25,011,711 instructions
27,441,686 cpu/topdown-fe-bound/1.003530890 seconds time elapsed
--- tools/perf/arch/x86/util/evlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/arch/x86/util/evlist.c +1 -1
@@ -36,7 +36,7 @@ struct evsel *arch_evlist__leader(struct list_head *list)if (slots == first)return first; } -if (!strncasecmp (evsel->name,"topdown" ,7 )) +if (strcasestr (evsel->name,"topdown" )) has_topdown = true;if (slots && has_topdown)return slots;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 432/772 net: stmmac: fix out-of-bounds access in a selftest
In reply to Greg Kroah-HartmanFrom: Jakub Kicinski <[email protected]>
[ Upstream commit fe5c5fc145edcf98a759b895f52b646730eeb7be ]
GCC 12 points out that struct tc_action is smaller than struct tcf_action:
drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c: In function ‘stmmac_test_rxp’:drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c:1132:21: warning: array subscript ‘struct tcf_gact[0]’ is partly outside array bounds of ‘unsigned char[272]’ [-Warray-bounds]
1132 | gact->tcf_action = TC_ACT_SHOT;
| ^~
--- .../net/ethernet/stmicro/stmmac/stmmac_selftests.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c +6 -7
@@ -1084,8 +1084,9 @@ static int stmmac_test_rxp(struct stmmac_priv *priv)unsigned char addr[ETH_ALEN ] = {0xde ,0xad ,0xbe ,0xef ,0x00 ,0x00 };struct tc_cls_u32_offload cls_u32 = { };struct stmmac_packet_attrs attr = { }; -struct tc_action **actions, *act; +struct tc_action **actions;struct tc_u32_sel *sel; +struct tcf_gact *gact;struct tcf_exts *exts;int ret, i, nk =1 ;
@@ -1110,8 +1111,8 @@ static int stmmac_test_rxp(struct stmmac_priv *priv) goto cleanup_exts; } - act =kcalloc (nk,sizeof (*act),GFP_KERNEL ); -if (!act) { + gact =kcalloc (nk,sizeof (*gact),GFP_KERNEL ); +if (!gact) { ret = -ENOMEM ; goto cleanup_actions; }
@@ -1126,9 +1127,7 @@ static int stmmac_test_rxp(struct stmmac_priv *priv) exts->nr_actions = nk; exts->actions = actions;for (i =0 ; i < nk; i++) { -struct tcf_gact *gact =to_gact (&act[i]); - - actions[i] = &act[i]; + actions[i] = (struct tc_action *)&gact[i]; gact->tcf_action =TC_ACT_SHOT ; }
@@ -1152,7 +1151,7 @@ static int stmmac_test_rxp(struct stmmac_priv *priv)stmmac_tc_setup_cls_u32 (priv, priv, &cls_u32); cleanup_act: -kfree (act); +kfree (gact); cleanup_actions:kfree (actions); cleanup_exts:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 433/772 amt: fix gateway mode stuck
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
[ Upstream commit 937956ba404e70a765ca5aa39d3d7564d86a8872 ]
If a gateway can not receive any response to requests from a relay, gateway resets status from SENT_REQUEST to INIT and variable about a relay as well. And then it should start the full establish step from sending a discovery message and receiving advertisement message. But, after failure in amt_req_work() it continues sending a request message step with flushed(invalid) relay information and sets SENT_REQUEST. So, a gateway can't be established with a relay.
In order to avoid this situation, it stops sending the request message step if it fails.
--- drivers/net/amt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/amt.c +4 -2
@@ -943,7 +943,7 @@ static void amt_req_work(struct work_struct *work)if (amt->status <AMT_STATUS_RECEIVED_ADVERTISEMENT ) goto out; -if (amt->req_cnt++ >AMT_MAX_REQ_COUNT ) { +if (amt->req_cnt >AMT_MAX_REQ_COUNT ) {netdev_dbg (amt->dev,"Gateway is not ready" ); amt->qi =AMT_INIT_REQ_TIMEOUT ; amt->ready4 = false;
@@ -951,13 +951,15 @@ static void amt_req_work(struct work_struct *work) amt->remote_ip =0 ;__amt_update_gw_status (amt,AMT_STATUS_INIT , false); amt->req_cnt =0 ; + goto out; }spin_unlock_bh (&amt->lock);amt_send_request (amt, false);amt_send_request (amt, true); -amt_update_gw_status (amt,AMT_STATUS_SENT_REQUEST , true);spin_lock_bh (&amt->lock); +__amt_update_gw_status (amt,AMT_STATUS_SENT_REQUEST , true); + amt->req_cnt++; out: exp =min_t (u32, (1 * (1 << amt->req_cnt)),AMT_MAX_REQ_TIMEOUT );mod_delayed_work (amt_wq, &amt->req_wq,msecs_to_jiffies (exp *1000 ));
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 434/772 amt: fix memory leak for advertisement message
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
[ Upstream commit fe29794c3585d039fefebaa2b5a4932a627ad4fd ]
When a gateway receives an advertisement message, it extracts relay information and then it should be freed.
But the advertisement handler doesn't free it.
So, memory leak would occur.
--- drivers/net/amt.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/net/amt.c +2 -3
@@ -2698,9 +2698,8 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb) err = true; goto drop; } -if (amt_advertisement_handler (amt, skb)) - amt->dev->stats.rx_dropped++; - goto out; + err =amt_advertisement_handler (amt, skb); +break ;case AMT_MSG_MULTICAST_DATA :if (iph->saddr != amt->remote_ip) {netdev_dbg (amt->dev,"Invalid Relay IP\n" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 435/772 hv_netvsc: Fix potential dereference of NULL pointer
In reply to Greg Kroah-HartmanFrom: Yongzhi Liu <[email protected]>
[ Upstream commit eb4c0788964730d12e8dd520bd8f5217ca48321c ]
The return value of netvsc_devinfo_get()
needs to be checked to avoid use of NULL
pointer in case of an allocation failure.
--- drivers/net/hyperv/netvsc_drv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/hyperv/netvsc_drv.c +4 -1
@@ -2671,7 +2671,10 @@ static int netvsc_suspend(struct hv_device *dev)/* Save the current config info */ ndev_ctx->saved_netvsc_dev_info =netvsc_devinfo_get (nvdev); - +if (!ndev_ctx->saved_netvsc_dev_info) { + ret = -ENOMEM ; + goto out; + } ret =netvsc_detach (net, nvdev); out:rtnl_unlock ();
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 436/772 hwmon: (pmbus) Check PEC support before reading other registers
In reply to Greg Kroah-HartmanFrom: Adam Wujek <[email protected]>
[ Upstream commit d1baf7a3a3177d46a7149858beddb88a9eca7a54 ]
Make sure that the support of PEC is determined before the read of other registers. Otherwise the validation of PEC can trigger an error on the read of STATUS_BYTE or STATUS_WORD registers.
The problematic scenario is the following. A device with enabled PEC support is up and running and a kernel driver is loaded. Then the driver is unloaded (or device unbound), the HW device is reconfigured externally (e.g. by i2cset) to advertise itself as not supporting PEC. Without the move of the code, at the second load of the driver (or bind) the STATUS_BYTE or STATUS_WORD register is always read with PEC enabled, which is likely to cause a read error resulting with fail of a driver load (or bind).
--- drivers/hwmon/pmbus/pmbus_core.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-)
drivers/hwmon/pmbus/pmbus_core.c +15 -13
@@ -2308,6 +2308,21 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data,struct device *dev = &client->dev;int page, ret; +/* +* Figure out if PEC is enabled before accessing any other register. +* Make sure PEC is disabled, will be enabled later if needed. +*/ + client->flags &= ~I2C_CLIENT_PEC ; + +/* Enable PEC if the controller and bus supports it */ +if (!(data->flags &PMBUS_NO_CAPABILITY )) { + ret =i2c_smbus_read_byte_data (client,PMBUS_CAPABILITY ); +if (ret >=0 && (ret &PB_CAPABILITY_ERROR_CHECK )) { +if (i2c_check_functionality (client->adapter,I2C_FUNC_SMBUS_PEC )) + client->flags |=I2C_CLIENT_PEC ; + } + } +/* * Some PMBus chips don't support PMBUS_STATUS_WORD, so try * to use PMBUS_STATUS_BYTE instead if that is the case.
@@ -2326,19 +2341,6 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, data->has_status_word = true; } -/* Make sure PEC is disabled, will be enabled later if needed */ - client->flags &= ~I2C_CLIENT_PEC ; - -/* Enable PEC if the controller and bus supports it */ -if (!(data->flags &PMBUS_NO_CAPABILITY )) { - ret =i2c_smbus_read_byte_data (client,PMBUS_CAPABILITY ); -if (ret >=0 && (ret &PB_CAPABILITY_ERROR_CHECK )) { -if (i2c_check_functionality (client->adapter,I2C_FUNC_SMBUS_PEC )) { - client->flags |=I2C_CLIENT_PEC ; - } - } - } -/* * Check if the chip is write protected. If it is, we can not clear * faults, and we should not try it. Also, in that case, writes into
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 437/772 rxrpc: Fix locking issue
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit ad25f5cb39872ca14bcbe00816ae65c22fe04b89 ]
There's a locking issue with the per-netns list of calls in rxrpc. The pieces of code that add and remove a call from the list use write_lock() and the calls procfile uses read_lock() to access it. However, the timer callback function may trigger a removal by trying to queue a call for processing and finding that it's already queued - at which point it has a spare refcount that it has to do something with. Unfortunately, if it puts the call and this reduces the refcount to 0, the call will be removed from the list. Unfortunately, since the _bh variants of the locking functions aren't used, this can deadlock.
================================
WARNING: inconsistent lock state
5.18.0-rc3-build4+ #10 Not tainted
--------------------------------
inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
ksoftirqd/2/25 [HC0[0]:SC1[1]:HE1:SE0] takes:ffff888107ac4038 (&rxnet->call_lock){+.?.}-{2:2}, at: rxrpc_put_call+0x103/0x14b {SOFTIRQ-ON-W} state was registered at:
...
Possible unsafe locking scenario:
CPU0
----
lock(&rxnet->call_lock);
<Interrupt>
lock(&rxnet->call_lock);*** DEADLOCK ***
1 lock held by ksoftirqd/2/25:
#0: ffff8881008ffdb0 ((&call->timer)){+.-.}-{0:0}, at: call_timer_fn+0x5/0x23d
Changes
=======
ver #2)
- Changed to using list_next_rcu() rather than rcu_dereference() directly.
--- fs/seq_file.c | 32 ++++++++++++++++++++++++++++++++ include/linux/list.h | 10 ++++++++++ include/linux/seq_file.h | 4 ++++ net/rxrpc/ar-internal.h | 2 +- net/rxrpc/call_accept.c | 6 +++--- net/rxrpc/call_object.c | 18 +++++++++--------- net/rxrpc/net_ns.c | 2 +- net/rxrpc/proc.c | 10 ++-------- 8 files changed, 62 insertions(+), 22 deletions(-)
fs/seq_file.c +32 -0
@@ -931,6 +931,38 @@ struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos) }EXPORT_SYMBOL (seq_list_next); +struct list_head *seq_list_start_rcu (struct list_head *head,loff_t pos) +{ +struct list_head *lh; + +list_for_each_rcu (lh, head) +if (pos-- ==0 ) +return lh; + +return NULL ; +} +EXPORT_SYMBOL (seq_list_start_rcu); + +struct list_head *seq_list_start_head_rcu (struct list_head *head,loff_t pos) +{ +if (!pos) +return head; + +return seq_list_start_rcu (head, pos -1 ); +} +EXPORT_SYMBOL (seq_list_start_head_rcu); + +struct list_head *seq_list_next_rcu (void *v,struct list_head *head, +loff_t *ppos) +{ +struct list_head *lh; + + lh =list_next_rcu ((struct list_head *)v); + ++*ppos; +return lh == head ?NULL : lh; +} +EXPORT_SYMBOL (seq_list_next_rcu); +/** * seq_hlist_start - start an iteration of a hlist * @head: the head of the hlist
include/linux/list.h +10 -0
@@ -579,6 +579,16 @@ static inline void list_splice_tail_init(struct list_head *list,#define list_for_each (pos, head) \ for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next) +/** +* list_for_each_rcu - Iterate over a list in an RCU-safe fashion +* @pos: the &struct list_head to use as a loop cursor. +* @head: the head for your list. +*/ +#define list_for_each_rcu (pos, head) \ + for (pos = rcu_dereference((head)->next); \ + !list_is_head(pos, (head)); \ + pos = rcu_dereference(pos->next)) +/** * list_for_each_continue - continue iteration over a list * @pos: the &struct list_head to use as a loop cursor.
include/linux/seq_file.h +4 -0
@@ -276,6 +276,10 @@ extern struct list_head *seq_list_start_head(struct list_head *head,extern struct list_head *seq_list_next (void *v,struct list_head *head,loff_t *ppos); +extern struct list_head *seq_list_start_rcu (struct list_head *head,loff_t pos); +extern struct list_head *seq_list_start_head_rcu (struct list_head *head,loff_t pos); +extern struct list_head *seq_list_next_rcu (void *v,struct list_head *head,loff_t *ppos); +/* * Helpers for iteration over hlist_head-s in seq_files */
net/rxrpc/ar-internal.h +1 -1
@@ -68,7 +68,7 @@ struct rxrpc_net {struct proc_dir_entry *proc_net;/* Subdir in /proc/net */ u32 epoch;/* Local epoch for detecting local-end reset */ struct list_head calls;/* List of calls active in this namespace */ -rwlock_t call_lock;/* Lock for ->calls */ +spinlock_t call_lock;/* Lock for ->calls */ atomic_t nr_calls;/* Count of allocated calls */ atomic_t nr_conns;
net/rxrpc/call_accept.c +3 -3
@@ -140,9 +140,9 @@ static int rxrpc_service_prealloc_one(struct rxrpc_sock *rx,write_unlock (&rx->call_lock); rxnet = call->rxnet; -write_lock (&rxnet->call_lock); -list_add_tail (&call->link, &rxnet->calls); -write_unlock (&rxnet->call_lock); +spin_lock_bh (&rxnet->call_lock); +list_add_tail_rcu (&call->link, &rxnet->calls); +spin_unlock_bh (&rxnet->call_lock); b->call_backlog[call_head] = call;smp_store_release (&b->call_backlog_head, (call_head +1 ) & (size -1 ));
net/rxrpc/call_object.c +9 -9
@@ -337,9 +337,9 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,write_unlock (&rx->call_lock); rxnet = call->rxnet; -write_lock (&rxnet->call_lock); -list_add_tail (&call->link, &rxnet->calls); -write_unlock (&rxnet->call_lock); +spin_lock_bh (&rxnet->call_lock); +list_add_tail_rcu (&call->link, &rxnet->calls); +spin_unlock_bh (&rxnet->call_lock);/* From this point on, the call is protected by its own lock. */ release_sock (&rx->sk);
@@ -631,9 +631,9 @@ void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace op) ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);if (!list_empty (&call->link)) { -write_lock (&rxnet->call_lock); +spin_lock_bh (&rxnet->call_lock);list_del_init (&call->link); -write_unlock (&rxnet->call_lock); +spin_unlock_bh (&rxnet->call_lock); }rxrpc_cleanup_call (call);
@@ -705,7 +705,7 @@ void rxrpc_destroy_all_calls(struct rxrpc_net *rxnet)_enter ("" );if (!list_empty (&rxnet->calls)) { -write_lock (&rxnet->call_lock); +spin_lock_bh (&rxnet->call_lock);while (!list_empty (&rxnet->calls)) { call = list_entry(rxnet->calls.next,
@@ -720,12 +720,12 @@ void rxrpc_destroy_all_calls(struct rxrpc_net *rxnet) rxrpc_call_states[call->state], call->flags, call->events); -write_unlock (&rxnet->call_lock); +spin_unlock_bh (&rxnet->call_lock);cond_resched (); -write_lock (&rxnet->call_lock); +spin_lock_bh (&rxnet->call_lock); } -write_unlock (&rxnet->call_lock); +spin_unlock_bh (&rxnet->call_lock); }atomic_dec (&rxnet->nr_calls);
net/rxrpc/net_ns.c +1 -1
@@ -50,7 +50,7 @@ static __net_init int rxrpc_init_net(struct net *net) rxnet->epoch |=RXRPC_RANDOM_EPOCH ;INIT_LIST_HEAD (&rxnet->calls); -rwlock_init (&rxnet->call_lock); +spin_lock_init (&rxnet->call_lock);atomic_set (&rxnet->nr_calls,1 );atomic_set (&rxnet->nr_conns,1 );
net/rxrpc/proc.c +2 -8
@@ -26,29 +26,23 @@ static const char *const rxrpc_conn_states[RXRPC_CONN__NR_STATES] = {*/ static void *rxrpc_call_seq_start (struct seq_file *seq,loff_t *_pos)__acquires (rcu) - __acquires(rxnet->call_lock) {struct rxrpc_net *rxnet =rxrpc_net (seq_file_net (seq));rcu_read_lock (); -read_lock (&rxnet->call_lock); -return seq_list_start_head (&rxnet->calls, *_pos); +return seq_list_start_head_rcu (&rxnet->calls, *_pos); }static void *rxrpc_call_seq_next (struct seq_file *seq,void *v,loff_t *pos) {struct rxrpc_net *rxnet =rxrpc_net (seq_file_net (seq)); -return seq_list_next (v, &rxnet->calls, pos); +return seq_list_next_rcu (v, &rxnet->calls, pos); }static void rxrpc_call_seq_stop (struct seq_file *seq,void *v) - __releases(rxnet->call_lock)__releases (rcu) { -struct rxrpc_net *rxnet =rxrpc_net (seq_file_net (seq)); - -read_unlock (&rxnet->call_lock);rcu_read_unlock (); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 438/772 rxrpc: Fix listen() setting the bar too high for the prealloc rings
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit 88e22159750b0d55793302eeed8ee603f5c1a95c ]
AF_RXRPC's listen() handler lets you set the backlog up to 32 (if you bump up the sysctl), but whilst the preallocation circular buffers have 32 slots in them, one of them has to be a dead slot because we're using CIRC_CNT().
This means that listen(rxrpc_sock, 32) will cause an oops when the socket is closed because rxrpc_service_prealloc_one() allocated one too many calls and rxrpc_discard_prealloc() won't then be able to get rid of them because it'll think the ring is empty. rxrpc_release_calls_on_socket() then tries to abort them, but oopses because call->peer isn't yet set.
Fix this by setting the maximum backlog to RXRPC_BACKLOG_MAX - 1 to match the ring capacity.
BUG: kernel NULL pointer dereference, address: 0000000000000086 ... RIP: 0010:rxrpc_send_abort_packet+0x73/0x240 [rxrpc] Call Trace: <TASK> ? __wake_up_common_lock+0x7a/0x90 ? rxrpc_notify_socket+0x8e/0x140 [rxrpc] ? rxrpc_abort_call+0x4c/0x60 [rxrpc] rxrpc_release_calls_on_socket+0x107/0x1a0 [rxrpc] rxrpc_release+0xc9/0x1c0 [rxrpc] __sock_release+0x37/0xa0 sock_close+0x11/0x20 __fput+0x89/0x240 task_work_run+0x59/0x90 do_exit+0x319/0xaa0
--- net/rxrpc/sysctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/rxrpc/sysctl.c +2 -2
@@ -12,7 +12,7 @@static struct ctl_table_header *rxrpc_sysctl_reg_table;static const unsigned int four =4 ; -static const unsigned int thirtytwo =32 ; +static const unsigned int max_backlog =RXRPC_BACKLOG_MAX -1 ;static const unsigned int n_65535 =65535 ;static const unsigned int n_max_acks =RXRPC_RXTX_BUFF_SIZE -1 ;static const unsigned long one_jiffy =1 ;
@@ -89,7 +89,7 @@ static struct ctl_table rxrpc_sysctl_table[] = { .mode = 0644, .proc_handler = proc_dointvec_minmax, .extra1 = (void *)&four, - .extra2 = (void *)&thirtytwo, + .extra2 = (void *)&max_backlog, }, { .procname = "rx_window_size",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 439/772 rxrpc: Dont try to resend the request if were receiving the reply
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit 114af61f88fbe34d641b13922d098ffec4c1be1b ]
rxrpc has a timer to trigger resending of unacked data packets in a call. This is not cancelled when a client call switches to the receive phase on the basis that most calls don't last long enough for it to ever expire. However, if it *does* expire after we've started to receive the reply, we shouldn't then go into trying to retransmit or pinging the server to find out if an ack got lost.
Fix this by skipping the resend code if we're into receiving the reply to a client call.
--- net/rxrpc/call_event.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/rxrpc/call_event.c +2 -1
@@ -406,7 +406,8 @@ void rxrpc_process_call(struct work_struct *work) goto recheck_state; } -if (test_and_clear_bit (RXRPC_CALL_EV_RESEND , &call->events)) { +if (test_and_clear_bit (RXRPC_CALL_EV_RESEND , &call->events) && + call->state !=RXRPC_CALL_CLIENT_RECV_REPLY ) {rxrpc_resend (call, now); goto recheck_state; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 440/772 rxrpc: Fix overlapping ACK accounting
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit 8940ba3cfe4841928777fd45eaa92051522c7f0c ]
Fix accidental overlapping of Rx-phase ACK accounting with Tx-phase ACK accounting through variables shared between the two. call->acks_* members refer to ACKs received in the Tx phase and call->ackr_* members to ACKs sent/to be sent during the Rx phase.
--- net/rxrpc/ar-internal.h | 7 ++++--- net/rxrpc/input.c | 16 ++++++++-------- 2 files changed, 12 insertions(+), 11 deletions(-)
net/rxrpc/ar-internal.h +4 -3
@@ -676,10 +676,9 @@ struct rxrpc_call {spinlock_t input_lock;/* Lock for packet input to this call */ -/* receive-phase ACK management */ +/* Receive-phase ACK management (ACKs we send). */ u8 ackr_reason;/* reason to ACK */ rxrpc_serial_t ackr_serial;/* serial of packet being ACK'd */ -rxrpc_serial_t ackr_first_seq;/* first sequence number received */ rxrpc_seq_t ackr_prev_seq;/* previous sequence number received */ rxrpc_seq_t ackr_consumed;/* Highest packet shown consumed */ rxrpc_seq_t ackr_seen;/* Highest packet shown seen */
@@ -692,8 +691,10 @@ struct rxrpc_call {#define RXRPC_CALL_RTT_AVAIL_MASK 0xf#define RXRPC_CALL_RTT_PEND_SHIFT 8 -/* transmission-phase ACK management */ +/* Transmission-phase ACK management (ACKs we've received). */ ktime_t acks_latest_ts;/* Timestamp of latest ACK received */ +rxrpc_seq_t acks_first_seq;/* first sequence number received */ +rxrpc_seq_t acks_prev_seq;/* previous sequence number received */ rxrpc_seq_t acks_lowest_nak;/* Lowest NACK in the buffer (or ==tx_hard_ack) */ rxrpc_seq_t acks_lost_top;/* tx_top at the time lost-ack ping sent */ rxrpc_serial_t acks_lost_ping;/* Serial number of probe ACK */
net/rxrpc/input.c +8 -8
@@ -812,7 +812,7 @@ static void rxrpc_input_soft_acks(struct rxrpc_call *call, u8 *acks,static bool rxrpc_is_ack_valid (struct rxrpc_call *call,rxrpc_seq_t first_pkt,rxrpc_seq_t prev_pkt) { -rxrpc_seq_t base =READ_ONCE (call->ackr_first_seq); +rxrpc_seq_t base =READ_ONCE (call->acks_first_seq);if (after (first_pkt, base))return true;/* The window advanced */
@@ -820,7 +820,7 @@ static bool rxrpc_is_ack_valid(struct rxrpc_call *call,if (before (first_pkt, base))return false;/* firstPacket regressed */ -if (after_eq (prev_pkt, call->ackr_prev_seq)) +if (after_eq (prev_pkt, call->acks_prev_seq))return true;/* previousPacket hasn't regressed. */ /* Some rx implementations put a serial number in previousPacket. */
@@ -933,8 +933,8 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)/* Discard any out-of-order or duplicate ACKs (outside lock). */ if (!rxrpc_is_ack_valid (call, first_soft_ack, prev_pkt)) {trace_rxrpc_rx_discard_ack (call->debug_id, ack_serial, - first_soft_ack, call->ackr_first_seq, - prev_pkt, call->ackr_prev_seq); + first_soft_ack, call->acks_first_seq, + prev_pkt, call->acks_prev_seq);return ; }
@@ -949,14 +949,14 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)/* Discard any out-of-order or duplicate ACKs (inside lock). */ if (!rxrpc_is_ack_valid (call, first_soft_ack, prev_pkt)) {trace_rxrpc_rx_discard_ack (call->debug_id, ack_serial, - first_soft_ack, call->ackr_first_seq, - prev_pkt, call->ackr_prev_seq); + first_soft_ack, call->acks_first_seq, + prev_pkt, call->acks_prev_seq); goto out; } call->acks_latest_ts = skb->tstamp; - call->ackr_first_seq = first_soft_ack; - call->ackr_prev_seq = prev_pkt; + call->acks_first_seq = first_soft_ack; + call->acks_prev_seq = prev_pkt;/* Parse rwind and mtu sizes if provided. */ if (buf.info.rxMTU)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 441/772 rxrpc: Dont let ack.previousPacket regress
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit 81524b6312535897707f2942695da1d359a5e56b ]
The previousPacket field in the rx ACK packet should never go backwards - it's now the highest DATA sequence number received, not the last on received (it used to be used for out of sequence detection).
--- net/rxrpc/ar-internal.h | 4 ++-- net/rxrpc/input.c | 4 +++- net/rxrpc/output.c | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-)
net/rxrpc/ar-internal.h +2 -2
@@ -679,7 +679,7 @@ struct rxrpc_call {/* Receive-phase ACK management (ACKs we send). */ u8 ackr_reason;/* reason to ACK */ rxrpc_serial_t ackr_serial;/* serial of packet being ACK'd */ -rxrpc_seq_t ackr_prev_seq;/* previous sequence number received */ +rxrpc_seq_t ackr_highest_seq;/* Higest sequence number received */ rxrpc_seq_t ackr_consumed;/* Highest packet shown consumed */ rxrpc_seq_t ackr_seen;/* Highest packet shown seen */
@@ -694,7 +694,7 @@ struct rxrpc_call {/* Transmission-phase ACK management (ACKs we've received). */ ktime_t acks_latest_ts;/* Timestamp of latest ACK received */ rxrpc_seq_t acks_first_seq;/* first sequence number received */ -rxrpc_seq_t acks_prev_seq;/* previous sequence number received */ +rxrpc_seq_t acks_prev_seq;/* Highest previousPacket received */ rxrpc_seq_t acks_lowest_nak;/* Lowest NACK in the buffer (or ==tx_hard_ack) */ rxrpc_seq_t acks_lost_top;/* tx_top at the time lost-ack ping sent */ rxrpc_serial_t acks_lost_ping;/* Serial number of probe ACK */
net/rxrpc/input.c +3 -1
@@ -453,7 +453,6 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb) !rxrpc_receiving_reply(call)) goto unlock; - call->ackr_prev_seq = seq0; hard_ack =READ_ONCE (call->rx_hard_ack); nr_subpackets = sp->nr_subpackets;
@@ -534,6 +533,9 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb) ack_serial = serial; } +if (after (seq0, call->ackr_highest_seq)) + call->ackr_highest_seq = seq0; +/* Queue the packet. We use a couple of memory barriers here as need * to make sure that rx_top is perceived to be set after the buffer * pointer and that the buffer pointer is set after the annotation and
net/rxrpc/output.c +1 -1
@@ -89,7 +89,7 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_connection *conn, pkt->ack.bufferSpace =htons (8 ); pkt->ack.maxSkew =htons (0 ); pkt->ack.firstPacket =htonl (hard_ack +1 ); - pkt->ack.previousPacket =htonl (call->ackr_prev_seq); + pkt->ack.previousPacket =htonl (call->ackr_highest_seq); pkt->ack.serial =htonl (serial); pkt->ack.reason = reason; pkt->ack.nAcks = top - hard_ack;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 442/772 rxrpc: Fix decision on when to generate an IDLE ACK
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit 9a3dedcf18096e8f7f22b8777d78c4acfdea1651 ]
Fix the decision on when to generate an IDLE ACK by keeping a count of the number of packets we've received, but not yet soft-ACK'd, and the number of packets we've processed, but not yet hard-ACK'd, rather than trying to keep track of which DATA sequence numbers correspond to those points.
We then generate an ACK when either counter exceeds 2. The counters are both cleared when we transcribe the information into any sort of ACK packet for transmission. IDLE and DELAY ACKs are skipped if both counters are 0 (ie. no change).
--- include/trace/events/rxrpc.h | 2 +- net/rxrpc/ar-internal.h | 4 ++-- net/rxrpc/input.c | 11 +++++++++-- net/rxrpc/output.c | 18 +++++++++++------- net/rxrpc/recvmsg.c | 8 +++----- 5 files changed, 26 insertions(+), 17 deletions(-)
include/trace/events/rxrpc.h +1 -1
@@ -1509,7 +1509,7 @@ TRACE_EVENT(rxrpc_call_reset, __entry->call_serial = call->rx_serial; __entry->conn_serial = call->conn->hi_serial; __entry->tx_seq = call->tx_hard_ack; - __entry->rx_seq = call->ackr_seen; + __entry->rx_seq = call->rx_hard_ack; ), TP_printk("c=%08x %08x:%08x r=%08x/%08x tx=%08x rx=%08x",
net/rxrpc/ar-internal.h +2 -2
@@ -680,8 +680,8 @@ struct rxrpc_call {u8 ackr_reason;/* reason to ACK */ rxrpc_serial_t ackr_serial;/* serial of packet being ACK'd */ rxrpc_seq_t ackr_highest_seq;/* Higest sequence number received */ -rxrpc_seq_t ackr_consumed;/* Highest packet shown consumed */ -rxrpc_seq_t ackr_seen;/* Highest packet shown seen */ +atomic_t ackr_nr_unacked;/* Number of unacked packets */ +atomic_t ackr_nr_consumed;/* Number of packets needing hard ACK */ /* RTT management */ rxrpc_serial_t rtt_serial[4 ];/* Serial number of DATA or PING sent */
net/rxrpc/input.c +9 -2
@@ -412,8 +412,8 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb) {struct rxrpc_skb_priv *sp =rxrpc_skb (skb);enum rxrpc_call_state state; -unsigned int j, nr_subpackets; -rxrpc_serial_t serial = sp->hdr.serial, ack_serial =0 ; +unsigned int j, nr_subpackets, nr_unacked =0 ; +rxrpc_serial_t serial = sp->hdr.serial, ack_serial = serial;rxrpc_seq_t seq0 = sp->hdr.seq, hard_ack;bool immediate_ack = false, jumbo_bad = false;u8 ack =0 ;
@@ -569,6 +569,8 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb) sp =NULL ; } + nr_unacked++; +if (last) {set_bit (RXRPC_CALL_RX_LAST , &call->flags);if (!ack) {
@@ -588,9 +590,14 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb) } call->rx_expect_next = seq +1 ; } +if (!ack) + ack_serial = serial; } ack: +if (atomic_add_return (nr_unacked, &call->ackr_nr_unacked) >2 && !ack) + ack =RXRPC_ACK_IDLE ; +if (ack) rxrpc_propose_ACK(call, ack, ack_serial, immediate_ack, true,
net/rxrpc/output.c +11 -7
@@ -74,11 +74,18 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_connection *conn, u8 reason) {rxrpc_serial_t serial; +unsigned int tmp;rxrpc_seq_t hard_ack, top, seq;int ix;u32 mtu, jmax;u8 *ackp = pkt->acks; + tmp =atomic_xchg (&call->ackr_nr_unacked,0 ); + tmp |=atomic_xchg (&call->ackr_nr_consumed,0 ); +if (!tmp && (reason ==RXRPC_ACK_DELAY || + reason ==RXRPC_ACK_IDLE )) +return 0 ; +/* Barrier against rxrpc_input_data(). */ serial = call->ackr_serial; hard_ack =READ_ONCE (call->rx_hard_ack);
@@ -223,6 +230,10 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping, n =rxrpc_fill_out_ack (conn, call, pkt, &hard_ack, &top, reason);spin_unlock_bh (&call->lock); +if (n ==0 ) { +kfree (pkt); +return 0 ; + } iov[0 ].iov_base = pkt; iov[0 ].iov_len =sizeof (pkt->whdr) +sizeof (pkt->ack) + n;
@@ -259,13 +270,6 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,ntohl (pkt->ack.serial), false, true, rxrpc_propose_ack_retry_tx); - }else { -spin_lock_bh (&call->lock); -if (after (hard_ack, call->ackr_consumed)) - call->ackr_consumed = hard_ack; -if (after (top, call->ackr_seen)) - call->ackr_seen = top; -spin_unlock_bh (&call->lock); }rxrpc_set_keepalive (call);
net/rxrpc/recvmsg.c +3 -5
@@ -260,11 +260,9 @@ static void rxrpc_rotate_rx_window(struct rxrpc_call *call)rxrpc_end_rx_phase (call, serial); }else {/* Check to see if there's an ACK that needs sending. */ -if (after_eq (hard_ack, call->ackr_consumed +2 ) || -after_eq (top, call->ackr_seen +2 ) || - (hard_ack == top &&after (hard_ack, call->ackr_consumed))) -rxrpc_propose_ACK (call,RXRPC_ACK_DELAY , serial, - true, true, +if (atomic_inc_return (&call->ackr_nr_consumed) >2 ) +rxrpc_propose_ACK (call,RXRPC_ACK_IDLE , serial, + true, false, rxrpc_propose_ack_rotate_rx);if (call->ackr_reason && call->ackr_reason !=RXRPC_ACK_DELAY )rxrpc_send_ack_packet (call, false,NULL );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 443/772 hinic: Avoid some over memory allocation
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 15d221d0c345b76947911a3ac91897ffe2f1cc4e ]
'prod_idx' (atomic_t) is larger than 'shadow_idx' (u16), so some memory is over-allocated.
--- drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c +1 -1
@@ -386,7 +386,7 @@ static int alloc_wqes_shadow(struct hinic_wq *wq)return -ENOMEM ; wq->shadow_idx =devm_kcalloc (&pdev->dev, wq->num_q_pages, -sizeof (wq->prod_idx),GFP_KERNEL ); +sizeof (*wq->shadow_idx),GFP_KERNEL );if (!wq->shadow_idx) goto err_shadow_idx;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 444/772 net: dsa: restrict SMSC_LAN9303_I2C kconfig
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
[ Upstream commit 0a3ad7d323686fbaae8688326cc5ea0d185c6fca ]
Since kconfig 'select' does not follow dependency chains, if symbol KSA selects KSB, then KSA should also depend on the same symbols that KSB depends on, in order to prevent Kconfig warnings and possible build errors.
Change NET_DSA_SMSC_LAN9303_I2C and NET_DSA_SMSC_LAN9303_MDIO so that they are limited to VLAN_8021Q if the latter is enabled. This prevents the Kconfig warning:
WARNING: unmet direct dependencies detected for NET_DSA_SMSC_LAN9303
Depends on [m]: NETDEVICES [=y] && NET_DSA [=y] && (VLAN_8021Q [=m] || VLAN_8021Q [=m]=n) Selected by [y]:
- NET_DSA_SMSC_LAN9303_I2C [=y] && NETDEVICES [=y] && NET_DSA [=y] && I2C [=y]
--- drivers/net/dsa/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/dsa/Kconfig +2 -1
@@ -72,7 +72,6 @@ source "drivers/net/dsa/realtek/Kconfig" config NET_DSA_SMSC_LAN9303 tristate - depends on VLAN_8021Q || VLAN_8021Q=n select NET_DSA_TAG_LAN9303 select REGMAP help
@@ -82,6 +81,7 @@ config NET_DSA_SMSC_LAN9303 config NET_DSA_SMSC_LAN9303_I2C tristate "SMSC/Microchip LAN9303 3-ports 10/100 ethernet switch in I2C managed mode" depends on I2C + depends on VLAN_8021Q || VLAN_8021Q=n select NET_DSA_SMSC_LAN9303 select REGMAP_I2C help
@@ -91,6 +91,7 @@ config NET_DSA_SMSC_LAN9303_I2C config NET_DSA_SMSC_LAN9303_MDIO tristate "SMSC/Microchip LAN9303 3-ports 10/100 ethernet switch in MDIO managed mode" select NET_DSA_SMSC_LAN9303 + depends on VLAN_8021Q || VLAN_8021Q=n help Enable access functions if the SMSC/Microchip LAN9303 is configured for MDIO managed mode.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 445/772 net/smc: postpone sk_refcnt increment in connect()
In reply to Greg Kroah-HartmanFrom: liuyacan <[email protected]>
[ Upstream commit 75c1edf23b95a9c66923d9269d8e86e4dbde151f ]
Same trigger condition as commit 86434744. When setsockopt runs in parallel to a connect(), and switch the socket into fallback mode. Then the sk_refcnt is incremented in smc_connect(), but its state stay in SMC_INIT (NOT SMC_ACTIVE). This cause the corresponding sk_refcnt decrement in __smc_release() will not be performed.
--- net/smc/af_smc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/smc/af_smc.c +1 -1
@@ -1417,9 +1417,9 @@ static int smc_connect(struct socket *sock, struct sockaddr *addr,if (rc && rc != -EINPROGRESS ) goto out; -sock_hold (&smc->sk);/* sock put in passive closing */ if (smc->use_fallback) goto out; +sock_hold (&smc->sk);/* sock put in passive closing */ if (flags &O_NONBLOCK ) {if (queue_work (smc_hs_wq, &smc->connect_work)) smc->connect_nonblock =1 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 446/772 net/smc: fix listen processing for SMC-Rv2
In reply to Greg Kroah-HartmanFrom: liuyacan <[email protected]>
[ Upstream commit 8c3b8dc5cc9bf6d273ebe18b16e2d6882bcfb36d ]
In the process of checking whether RDMAv2 is available, the current implementation first sets ini->smcrv2.ib_dev_v2, and then allocates smc buf desc, but the latter may fail. Unfortunately, the caller will only check the former. In this case, a NULL pointer reference will occur in smc_clc_send_confirm_accept() when accessing conn->rmb_desc.
This patch does two things:
1. Use the return code to determine whether V2 is available.
2. If the return code is NODEV, continue to check whether V1 is available.
--- net/smc/af_smc.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-)
net/smc/af_smc.c +27 -17
@@ -1930,13 +1930,13 @@ static int smc_listen_rdma_reg(struct smc_sock *new_smc, bool local_first)return 0 ; } -static void smc_find_rdma_v2_device_serv (struct smc_sock *new_smc, -struct smc_clc_msg_proposal *pclc, -struct smc_init_info *ini) +static int smc_find_rdma_v2_device_serv (struct smc_sock *new_smc, +struct smc_clc_msg_proposal *pclc, +struct smc_init_info *ini) {struct smc_clc_v2_extension *smc_v2_ext;u8 smcr_version; -int rc; +int rc =0 ;if (!(ini->smcr_version &SMC_V2 ) || !smcr_indicated (ini->smc_type_v2)) goto not_found;
@@ -1954,26 +1954,31 @@ static void smc_find_rdma_v2_device_serv(struct smc_sock *new_smc, ini->smcrv2.saddr = new_smc->clcsock->sk->sk_rcv_saddr; ini->smcrv2.daddr =smc_ib_gid_to_ipv4 (smc_v2_ext->roce); rc =smc_find_rdma_device (new_smc, ini); -if (rc) { -smc_find_ism_store_rc (rc, ini); +if (rc) goto not_found; - } +if (!ini->smcrv2.uses_gateway)memcpy (ini->smcrv2.nexthop_mac, pclc->lcl.mac,ETH_ALEN ); smcr_version = ini->smcr_version; ini->smcr_version =SMC_V2 ; rc =smc_listen_rdma_init (new_smc, ini); -if (!rc) - rc =smc_listen_rdma_reg (new_smc, ini->first_contact_local); -if (!rc) -return ; - ini->smcr_version = smcr_version; -smc_find_ism_store_rc (rc, ini); +if (rc) { + ini->smcr_version = smcr_version; + goto not_found; + } + rc =smc_listen_rdma_reg (new_smc, ini->first_contact_local); +if (rc) { + ini->smcr_version = smcr_version; + goto not_found; + } +return 0 ; not_found: + rc = rc ?:SMC_CLC_DECL_NOSMCDEV ; ini->smcr_version &= ~SMC_V2 ; ini->check_smcrv2 = false; +return rc; } static int smc_find_rdma_v1_device_serv(struct smc_sock *new_smc,
@@ -2006,6 +2011,7 @@ static int smc_listen_find_device(struct smc_sock *new_smc, struct smc_init_info *ini) {int prfx_rc; +int rc;/* check for ISM device matching V2 proposed device */ smc_find_ism_v2_device_serv (new_smc, pclc, ini);
@@ -2033,14 +2039,18 @@ static int smc_listen_find_device(struct smc_sock *new_smc,return ini->rc ?:SMC_CLC_DECL_NOSMCDDEV ;/* check if RDMA V2 is available */ -smc_find_rdma_v2_device_serv (new_smc, pclc, ini); -if (ini->smcrv2.ib_dev_v2) + rc =smc_find_rdma_v2_device_serv (new_smc, pclc, ini); +if (!rc)return 0 ; +/* skip V1 check if V2 is unavailable for non-Device reason */ +if (rc !=SMC_CLC_DECL_NOSMCDEV && + rc !=SMC_CLC_DECL_NOSMCRDEV && + rc !=SMC_CLC_DECL_NOSMCDDEV ) +return rc; +/* check if RDMA V1 is available */ if (!prfx_rc) { -int rc; - rc =smc_find_rdma_v1_device_serv (new_smc, pclc, ini);smc_find_ism_store_rc (rc, ini);return (!rc) ?0 : ini->rc;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 447/772 dma-direct: dont over-decrypt memory
In reply to Greg Kroah-HartmanFrom: Robin Murphy <[email protected]>
[ Upstream commit 4a37f3dd9a83186cb88d44808ab35b78375082c9 ]
The original x86 sev_alloc() only called set_memory_decrypted() on memory returned by alloc_pages_node(), so the page order calculation fell out of that logic. However, the common dma-direct code has several potential allocators, not all of which are guaranteed to round up the underlying allocation to a power-of-two size, so carrying over that calculation for the encryption/decryption size was a mistake. Fix it by rounding to a *number* of pages, rather than an order.
Until recently there was an even worse interaction with DMA_DIRECT_REMAP where we could have ended up decrypting part of the next adjacent vmalloc area, only averted by no architecture actually supporting both configs at once. Don't ask how I found that one out...
--- kernel/dma/direct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/dma/direct.c +2 -2
@@ -79,7 +79,7 @@ static int dma_set_decrypted(struct device *dev, void *vaddr, size_t size) {if (!force_dma_unencrypted (dev))return 0 ; -return set_memory_decrypted ((unsigned long )vaddr,1 <<get_order (size)); +return set_memory_decrypted ((unsigned long )vaddr,PFN_UP (size)); }static int dma_set_encrypted (struct device *dev,void *vaddr,size_t size)
@@ -88,7 +88,7 @@ static int dma_set_encrypted(struct device *dev, void *vaddr, size_t size)if (!force_dma_unencrypted (dev))return 0 ; - ret =set_memory_encrypted ((unsigned long )vaddr,1 <<get_order (size)); + ret =set_memory_encrypted ((unsigned long )vaddr,PFN_UP (size));if (ret)pr_warn_ratelimited ("leaking DMA memory that can't be re-encrypted\n" );return ret;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 448/772 Bluetooth: hci_sync: Cleanup hci_conn if it cannot be aborted
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 9b3628d79b46f06157affc56fdb218fdd4988321 ]
This attempts to cleanup the hci_conn if it cannot be aborted as otherwise it would likely result in having the controller and host stack out of sync with respect to connection handle.
--- include/net/bluetooth/hci_core.h | 2 +- net/bluetooth/hci_conn.c | 32 ++++++++++++++++++++++++-------- net/bluetooth/hci_event.c | 13 ++++--------- net/bluetooth/hci_sync.c | 11 ++++++++++- 4 files changed, 39 insertions(+), 19 deletions(-)
include/net/bluetooth/hci_core.h +1 -1
@@ -1147,7 +1147,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role);void hci_conn_enter_active_mode (struct hci_conn *conn,__u8 force_active); -void hci_le_conn_failed (struct hci_conn *conn,u8 status); +void hci_conn_failed (struct hci_conn *conn,u8 status);/* * hci_conn_get() and hci_conn_put() are used to control the life-time of an
net/bluetooth/hci_conn.c +24 -8
@@ -670,7 +670,7 @@ static void le_conn_timeout(struct work_struct *work)/* Disable LE Advertising */ le_disable_advertising (hdev);hci_dev_lock (hdev); -hci_le_conn_failed (conn,HCI_ERROR_ADVERTISING_TIMEOUT ); +hci_conn_failed (conn,HCI_ERROR_ADVERTISING_TIMEOUT );hci_dev_unlock (hdev);return ; }
@@ -873,7 +873,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src, uint8_t src_type)EXPORT_SYMBOL (hci_get_route);/* This function requires the caller holds hdev->lock */ -void hci_le_conn_failed (struct hci_conn *conn,u8 status) +static void hci_le_conn_failed (struct hci_conn *conn,u8 status) {struct hci_dev *hdev = conn->hdev;struct hci_conn_params *params;
@@ -886,8 +886,6 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status) params->conn =NULL ; } - conn->state =BT_CLOSED ; -/* If the status indicates successful cancellation of * the attempt (i.e. Unknown Connection Id) there's no point of * notifying failure since we'll go back to keep trying to
@@ -899,10 +897,6 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)mgmt_connect_failed (hdev, &conn->dst, conn->type, conn->dst_type, status); -hci_connect_cfm (conn, status); - -hci_conn_del (conn); -/* Since we may have temporarily stopped the background scanning in * favor of connection establishment, we should restart it. */
@@ -914,6 +908,28 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)hci_enable_advertising (hdev); } +/* This function requires the caller holds hdev->lock */ +void hci_conn_failed (struct hci_conn *conn,u8 status) +{ +struct hci_dev *hdev = conn->hdev; + +bt_dev_dbg (hdev,"status 0x%2.2x" , status); + +switch (conn->type) { +case LE_LINK : +hci_le_conn_failed (conn, status); +break ; +case ACL_LINK : +mgmt_connect_failed (hdev, &conn->dst, conn->type, + conn->dst_type, status); +break ; + } + + conn->state =BT_CLOSED ; +hci_connect_cfm (conn, status); +hci_conn_del (conn); +} +static void create_le_conn_complete (struct hci_dev *hdev,void *data,int err) {struct hci_conn *conn = data;
net/bluetooth/hci_event.c +4 -9
@@ -2846,7 +2846,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)bt_dev_dbg (hdev,"status 0x%2.2x" , status);/* All connection failure handling is taken care of by the -* hci_le_conn_failed function which is triggered by the HCI +* hci_conn_failed function which is triggered by the HCI * request completion callbacks used for connecting. */ if (status)
@@ -2871,7 +2871,7 @@ static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status)bt_dev_dbg (hdev,"status 0x%2.2x" , status);/* All connection failure handling is taken care of by the -* hci_le_conn_failed function which is triggered by the HCI +* hci_conn_failed function which is triggered by the HCI * request completion callbacks used for connecting. */ if (status)
@@ -3185,12 +3185,7 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, done:if (status) { - conn->state =BT_CLOSED ; -if (conn->type ==ACL_LINK ) -mgmt_connect_failed (hdev, &conn->dst, conn->type, - conn->dst_type, status); -hci_connect_cfm (conn, status); -hci_conn_del (conn); +hci_conn_failed (conn, status); }else if (ev->link_type ==SCO_LINK ) {switch (conn->setting &SCO_AIRMODE_MASK ) {case SCO_AIRMODE_CVSD :
@@ -5626,7 +5621,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, }if (status) { -hci_le_conn_failed (conn, status); +hci_conn_failed (conn, status); goto unlock; }
net/bluetooth/hci_sync.c +10 -1
@@ -4408,12 +4408,21 @@ static int hci_reject_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,static int hci_abort_conn_sync (struct hci_dev *hdev,struct hci_conn *conn,u8 reason) { +int err; +switch (conn->state) {case BT_CONNECTED :case BT_CONFIG :return hci_disconnect_sync (hdev, conn, reason);case BT_CONNECT : -return hci_connect_cancel_sync (hdev, conn); + err =hci_connect_cancel_sync (hdev, conn); +/* Cleanup hci_conn object if it cannot be cancelled as it +* likelly means the controller and host stack are out of sync. +*/ +if (err) +hci_conn_failed (conn, err); + +return err;case BT_CONNECT2 :return hci_reject_conn_sync (hdev, conn, reason);default :
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 449/772 Bluetooth: hci_conn: Fix hci_connect_le_sync
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit c9f73a2178c12fb24d2807634209559d6a836e08 ]
The handling of connection failures shall be handled by the request completion callback as already done by hci_cs_le_create_conn, also make sure to use hci_conn_failed instead of hci_le_conn_failed as the later don't actually call hci_conn_del to cleanup.
--- net/bluetooth/hci_conn.c | 5 +++-- net/bluetooth/hci_event.c | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-)
net/bluetooth/hci_conn.c +3 -2
@@ -943,10 +943,11 @@ static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)bt_dev_err (hdev,"request failed to create LE connection: err %d" , err); -if (!conn) +/* Check if connection is still pending */ +if (conn !=hci_lookup_le_connect (hdev)) goto done; -hci_le_conn_failed (conn, err); +hci_conn_failed (conn, err); done:hci_dev_unlock (hdev);
net/bluetooth/hci_event.c +5 -3
@@ -5620,10 +5620,12 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, status =HCI_ERROR_INVALID_PARAMETERS ; } -if (status) { -hci_conn_failed (conn, status); +/* All connection failure handling is taken care of by the +* hci_conn_failed function which is triggered by the HCI +* request completion callbacks used for connecting. +*/ +if (status) goto unlock; - }if (conn->dst_type ==ADDR_LE_DEV_PUBLIC ) addr_type =BDADDR_LE_PUBLIC ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 450/772 Revert "net/smc: fix listen processing for SMC-Rv2"
In reply to Greg Kroah-HartmanFrom: liuyacan <[email protected]>
[ Upstream commit 9029ac03f20a5999bc5627277c6cf008ab8e23ed ]
This reverts commit 8c3b8dc5cc9bf6d273ebe18b16e2d6882bcfb36d.
Some rollback issue will be fixed in other patches in the future.
--- net/smc/af_smc.c | 44 +++++++++++++++++--------------------------- 1 file changed, 17 insertions(+), 27 deletions(-)
net/smc/af_smc.c +17 -27
@@ -1930,13 +1930,13 @@ static int smc_listen_rdma_reg(struct smc_sock *new_smc, bool local_first)return 0 ; } -static int smc_find_rdma_v2_device_serv (struct smc_sock *new_smc, -struct smc_clc_msg_proposal *pclc, -struct smc_init_info *ini) +static void smc_find_rdma_v2_device_serv (struct smc_sock *new_smc, +struct smc_clc_msg_proposal *pclc, +struct smc_init_info *ini) {struct smc_clc_v2_extension *smc_v2_ext;u8 smcr_version; -int rc =0 ; +int rc;if (!(ini->smcr_version &SMC_V2 ) || !smcr_indicated (ini->smc_type_v2)) goto not_found;
@@ -1954,31 +1954,26 @@ static int smc_find_rdma_v2_device_serv(struct smc_sock *new_smc, ini->smcrv2.saddr = new_smc->clcsock->sk->sk_rcv_saddr; ini->smcrv2.daddr =smc_ib_gid_to_ipv4 (smc_v2_ext->roce); rc =smc_find_rdma_device (new_smc, ini); -if (rc) +if (rc) { +smc_find_ism_store_rc (rc, ini); goto not_found; - + }if (!ini->smcrv2.uses_gateway)memcpy (ini->smcrv2.nexthop_mac, pclc->lcl.mac,ETH_ALEN ); smcr_version = ini->smcr_version; ini->smcr_version =SMC_V2 ; rc =smc_listen_rdma_init (new_smc, ini); -if (rc) { - ini->smcr_version = smcr_version; - goto not_found; - } - rc =smc_listen_rdma_reg (new_smc, ini->first_contact_local); -if (rc) { - ini->smcr_version = smcr_version; - goto not_found; - } -return 0 ; +if (!rc) + rc =smc_listen_rdma_reg (new_smc, ini->first_contact_local); +if (!rc) +return ; + ini->smcr_version = smcr_version; +smc_find_ism_store_rc (rc, ini); not_found: - rc = rc ?:SMC_CLC_DECL_NOSMCDEV ; ini->smcr_version &= ~SMC_V2 ; ini->check_smcrv2 = false; -return rc; } static int smc_find_rdma_v1_device_serv(struct smc_sock *new_smc,
@@ -2011,7 +2006,6 @@ static int smc_listen_find_device(struct smc_sock *new_smc, struct smc_init_info *ini) {int prfx_rc; -int rc;/* check for ISM device matching V2 proposed device */ smc_find_ism_v2_device_serv (new_smc, pclc, ini);
@@ -2039,18 +2033,14 @@ static int smc_listen_find_device(struct smc_sock *new_smc,return ini->rc ?:SMC_CLC_DECL_NOSMCDDEV ;/* check if RDMA V2 is available */ - rc =smc_find_rdma_v2_device_serv (new_smc, pclc, ini); -if (!rc) +smc_find_rdma_v2_device_serv (new_smc, pclc, ini); +if (ini->smcrv2.ib_dev_v2)return 0 ; -/* skip V1 check if V2 is unavailable for non-Device reason */ -if (rc !=SMC_CLC_DECL_NOSMCDEV && - rc !=SMC_CLC_DECL_NOSMCRDEV && - rc !=SMC_CLC_DECL_NOSMCDDEV ) -return rc; -/* check if RDMA V1 is available */ if (!prfx_rc) { +int rc; + rc =smc_find_rdma_v1_device_serv (new_smc, pclc, ini);smc_find_ism_store_rc (rc, ini);return (!rc) ?0 : ini->rc;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 451/772 arm64: dts: rockchip: Move drive-impedance-ohm to emmc phy on rk3399
In reply to Greg Kroah-HartmanFrom: Shawn Lin <[email protected]>
[ Upstream commit 4246d0bab2a8685e3d4aec2cb0ef8c526689ce96 ]
drive-impedance-ohm is introduced for emmc phy instead of pcie phy.
--- arch/arm64/boot/dts/rockchip/rk3399.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3399.dtsi +1 -1
@@ -1534,6 +1534,7 @@ reg = <0xf780 0x24>; clocks = <&sdhci>; clock-names = "emmcclk"; + drive-impedance-ohm = <50>; #phy-cells = <0>; status = "disabled"; };
@@ -1544,7 +1545,6 @@ clock-names = "refclk"; #phy-cells = <1>; resets = <&cru SRST_PCIEPHY>; - drive-impedance-ohm = <50>; reset-names = "phy"; status = "disabled"; };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 452/772 arm64: dts: mt8192: Fix nor_flash status disable typo
In reply to Greg Kroah-HartmanFrom: Allen-KH Cheng <[email protected]>
[ Upstream commit 27f0eb16b0d417c155e96b5d3b89074699944e09 ]
Correct nor_flash status disable typo of mt8192 SoC.
--- arch/arm64/boot/dts/mediatek/mt8192.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/mediatek/mt8192.dtsi +1 -1
@@ -470,7 +470,7 @@ clock-names = "spi", "sf", "axi"; #address-cells = <1>; #size-cells = <0>; - status = "disable"; + status = "disabled"; }; audsys: clock-controller@11210000 {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 453/772 PCI/ACPI: Allow D3 only if Root Port can signal and wake from D3
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
[ Upstream commit dff6139015dc68e93be3822a7bd406a1d138628b ]
acpi_pci_bridge_d3(dev) returns "true" if "dev" is a hotplug bridge that can handle hotplug events while in D3. Previously this meant either:
- "dev" has a _PS0 or _PR0 method (acpi_pci_power_manageable()), or
- The Root Port above "dev" has a _DSD with a "HotPlugSupportInD3" property with value 1.
This did not consider _PRW, which tells us about wakeup GPEs (ACPI v6.4, sec 7.3.13). Without a wakeup GPE, from an ACPI perspective the Root Port has no way of generating wakeup signals, so hotplug events will be lost if we use D3.
Similarly, it did not consider _S0W, which tells us the deepest D-state from which a device can wake itself (sec 7.3.20). If _S0W tells us the device cannot wake from D3, hotplug events will again be lost if we use D3.
Some platforms, e.g., AMD Yellow Carp, supply "HotPlugSupportInD3" without _PRW or with an _S0W that says the Root Port cannot wake from D3. On those platforms, we previously put bridges in D3hot, hotplug events were lost, and hotplugged devices would not be recognized without manually rescanning.
Allow bridges to be put in D3 only if the Root Port can generate wakeup GPEs (wakeup.flags.valid), it can wake from D3 (_S0W), AND it has the "HotPlugSupportInD3" property.
Neither Windows 10 nor Windows 11 puts the bridge in D3 when the firmware is configured this way, and this change aligns the handling of the situation to be the same.
--- drivers/pci/pci-acpi.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-)
drivers/pci/pci-acpi.c +30 -11
@@ -974,9 +974,11 @@ bool acpi_pci_power_manageable(struct pci_dev *dev)bool acpi_pci_bridge_d3 (struct pci_dev *dev) { -const union acpi_object *obj; -struct acpi_device *adev;struct pci_dev *rpdev; +struct acpi_device *adev; +acpi_status status; +unsigned long long state; +const union acpi_object *obj;if (acpi_pci_disabled || !dev->is_hotplug_bridge)return false;
@@ -985,12 +987,6 @@ bool acpi_pci_bridge_d3(struct pci_dev *dev)if (acpi_pci_power_manageable (dev))return true; -/* -* The ACPI firmware will provide the device-specific properties through -* _DSD configuration object. Look for the 'HotPlugSupportInD3' property -* for the root port and if it is set we know the hierarchy behind it -* supports D3 just fine. -*/ rpdev =pcie_find_root_port (dev);if (!rpdev)return false;
@@ -999,11 +995,34 @@ bool acpi_pci_bridge_d3(struct pci_dev *dev)if (!adev)return false; -if (acpi_dev_get_property (adev,"HotPlugSupportInD3" , -ACPI_TYPE_INTEGER , &obj) <0 ) +/* +* If the Root Port cannot signal wakeup signals at all, i.e., it +* doesn't supply a wakeup GPE via _PRW, it cannot signal hotplug +* events from low-power states including D3hot and D3cold. +*/ +if (!adev->wakeup.flags.valid)return false; -return obj->integer.value ==1 ; +/* +* If the Root Port cannot wake itself from D3hot or D3cold, we +* can't use D3. +*/ + status =acpi_evaluate_integer (adev->handle,"_S0W" ,NULL , &state); +if (ACPI_SUCCESS (status) && state <ACPI_STATE_D3_HOT ) +return false; + +/* +* The "HotPlugSupportInD3" property in a Root Port _DSD indicates +* the Port can signal hotplug events while in D3. We assume any +* bridges *below* that Root Port can also signal hotplug events +* while in D3. +*/ +if (!acpi_dev_get_property (adev,"HotPlugSupportInD3" , +ACPI_TYPE_INTEGER , &obj) && + obj->integer.value ==1 ) +return true; + +return false; }int acpi_pci_set_power_state (struct pci_dev *dev,pci_power_t state)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 454/772 memory: samsung: exynos5422-dmc: Avoid some over memory allocation
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 56653827f0d7bc7c2d8bac0e119fd1521fa9990a ]
'dmc->counter' is a 'struct devfreq_event_dev **', so there is some over memory allocation. 'counters_size' should be computed with 'sizeof(struct devfreq_event_dev *)'.
Use 'sizeof(*dmc->counter)' instead to fix it.
While at it, use devm_kcalloc() instead of devm_kzalloc()+open coded multiplication.
--- drivers/memory/samsung/exynos5422-dmc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/memory/samsung/exynos5422-dmc.c +2 -3
@@ -1322,7 +1322,6 @@ static int exynos5_dmc_init_clks(struct exynos5_dmc *dmc)*/ static int exynos5_performance_counters_init (struct exynos5_dmc *dmc) { -int counters_size;int ret, i; dmc->num_counters = devfreq_event_get_edev_count(dmc->dev,
@@ -1332,8 +1331,8 @@ static int exynos5_performance_counters_init(struct exynos5_dmc *dmc)return dmc->num_counters; } - counters_size =sizeof (struct devfreq_event_dev ) * dmc->num_counters; - dmc->counter =devm_kzalloc (dmc->dev, counters_size,GFP_KERNEL ); + dmc->counter =devm_kcalloc (dmc->dev, dmc->num_counters, +sizeof (*dmc->counter),GFP_KERNEL );if (!dmc->counter)return -ENOMEM ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 455/772 ARM: dts: BCM5301X: Update pin controller node name
In reply to Greg Kroah-HartmanFrom: Rafał Miłecki <[email protected]>
[ Upstream commit 130b5e32ba9d2d2313e39cf3f6d0729bff02b76a ]
This fixes:arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: cru-bus@100: 'pin-controller@1c0' does not match any of the regexes: '^clock-controller@[a-f0-9]+$', '^phy@[a-f0-9]+$', '^pinctrl@[a-f0-9]+$', '^syscon@[a-f0-9]+$', '^thermal@[a-f0-9]+$'
From schema: Documentation/devicetree/bindings/mfd/brcm,cru.yamlarch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pin-controller@1c0: $nodename:0: 'pin-controller@1c0' does not match '^(pinctrl|pinmux)(@[0-9a-f]+)?$'
From schema: Documentation/devicetree/bindings/pinctrl/brcm,ns-pinmux.yaml
Ref: e7391b021e3f ("dt-bindings: mfd: brcm,cru: Rename pinctrl node")
--- arch/arm/boot/dts/bcm5301x.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/bcm5301x.dtsi +1 -1
@@ -455,7 +455,7 @@ reg = <0x180 0x4>; }; - pinctrl: pin-controller@1c0 { + pinctrl: pinctrl@1c0 { compatible = "brcm,bcm4708-pinmux"; reg = <0x1c0 0x24>; reg-names = "cru_gpio_control";
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 456/772 ARM: dts: suniv: F1C100: fix watchdog compatible
In reply to Greg Kroah-HartmanFrom: Andre Przywara <[email protected]>
[ Upstream commit 01a850ee61cbf0ab77dcbf26bb133fec2dd640d6 ]
The F1C100 series of SoCs actually have their watchdog IP being compatible with the newer Allwinner generation, not the older one.
The currently described sun4i-a10-wdt actually does not work, neither the watchdog functionality (just never fires), nor the reset part (reboot hangs).
Replace the compatible string with the one used by the newer generation. Verified to work with both the watchdog and reboot functionality on a LicheePi Nano.
Also add the missing interrupt line and clock source, to make it binding compliant.
--- arch/arm/boot/dts/suniv-f1c100s.dtsi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/arm/boot/dts/suniv-f1c100s.dtsi +3 -1
@@ -104,8 +104,10 @@ wdt: watchdog@1c20ca0 { compatible = "allwinner,suniv-f1c100s-wdt", - "allwinner,sun4i-a10-wdt"; + "allwinner,sun6i-a31-wdt"; reg = <0x01c20ca0 0x20>; + interrupts = <16>; + clocks = <&osc32k>; }; uart0: serial@1c25000 {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 457/772 soc: qcom: smp2p: Fix missing of_node_put() in smp2p_parse_ipc
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 8fd3f18ea31a398ecce4a6d3804433658678b0a3 ]
The device_node pointer is returned by of_parse_phandle() with refcount incremented. We should use of_node_put() on it when done.
--- drivers/soc/qcom/smp2p.c | 1 + 1 file changed, 1 insertion(+)
drivers/soc/qcom/smp2p.c +1 -0
@@ -493,6 +493,7 @@ static int smp2p_parse_ipc(struct qcom_smp2p *smp2p) } smp2p->ipc_regmap =syscon_node_to_regmap (syscon); +of_node_put (syscon);if (IS_ERR (smp2p->ipc_regmap))return PTR_ERR (smp2p->ipc_regmap);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 458/772 soc: qcom: smsm: Fix missing of_node_put() in smsm_parse_ipc
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit aad66a3c78da668f4506356c2fdb70b7a19ecc76 ]
The device_node pointer is returned by of_parse_phandle() with refcount incremented. We should use of_node_put() on it when done.
--- drivers/soc/qcom/smsm.c | 1 + 1 file changed, 1 insertion(+)
drivers/soc/qcom/smsm.c +1 -0
@@ -374,6 +374,7 @@ static int smsm_parse_ipc(struct qcom_smsm *smsm, unsigned host_id)return 0 ; host->ipc_regmap =syscon_node_to_regmap (syscon); +of_node_put (syscon);if (IS_ERR (host->ipc_regmap))return PTR_ERR (host->ipc_regmap);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 459/772 PCI: cadence: Fix find_first_zero_bit() limit
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 0aa3a0937feeb91a0e4e438c3c063b749b194192 ]
The ep->ob_region_map bitmap is a long and it has BITS_PER_LONG bits.
--- drivers/pci/controller/cadence/pcie-cadence-ep.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/pci/controller/cadence/pcie-cadence-ep.c +1 -2
@@ -187,8 +187,7 @@ static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,struct cdns_pcie *pcie = &ep->pcie;u32 r; - r =find_first_zero_bit (&ep->ob_region_map, -sizeof (ep->ob_region_map) *BITS_PER_LONG ); + r =find_first_zero_bit (&ep->ob_region_map,BITS_PER_LONG );if (r >= ep->max_regions -1 ) {dev_err (&epc->dev,"no free outbound region\n" );return -EINVAL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 460/772 PCI: rockchip: Fix find_first_zero_bit() limit
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 096950e230b8d83645c7cf408b9f399f58c08b96 ]
The ep->ob_region_map bitmap is a long and it has BITS_PER_LONG bits.
--- drivers/pci/controller/pcie-rockchip-ep.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/pci/controller/pcie-rockchip-ep.c +1 -2
@@ -264,8 +264,7 @@ static int rockchip_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,struct rockchip_pcie *pcie = &ep->rockchip;u32 r; - r =find_first_zero_bit (&ep->ob_region_map, -sizeof (ep->ob_region_map) *BITS_PER_LONG ); + r =find_first_zero_bit (&ep->ob_region_map,BITS_PER_LONG );/* * Region 0 is reserved for configuration space and shouldn't * be used elsewhere per TRM, so leave it out.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 461/772 PCI: mediatek: Fix refcount leak in mtk_pcie_subsys_powerup()
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 214e0d8fe4a813ae6ffd62bc2dfe7544c20914f4 ]
The of_find_compatible_node() function returns a node pointer with refcount incremented, We should use of_node_put() on it when done Add the missing of_node_put() to release the refcount.
--- drivers/pci/controller/pcie-mediatek.c | 1 + 1 file changed, 1 insertion(+)
drivers/pci/controller/pcie-mediatek.c +1 -0
@@ -1008,6 +1008,7 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie) "mediatek,generic-pciecfg");if (cfg_node) { pcie->cfg =syscon_node_to_regmap (cfg_node); +of_node_put (cfg_node);if (IS_ERR (pcie->cfg))return PTR_ERR (pcie->cfg); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 462/772 PCI: dwc: Fix setting error return on MSI DMA mapping failure
In reply to Greg Kroah-HartmanFrom: Jiantao Zhang <[email protected]>
[ Upstream commit 88557685cd72cf0db686a4ebff3fad4365cb6071 ]
When dma_mapping_error() returns error because of no enough memory, but dw_pcie_host_init() returns success, which will mislead the callers.
--- drivers/pci/controller/dwc/pcie-designware-host.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/pci/controller/dwc/pcie-designware-host.c +2 -1
@@ -390,7 +390,8 @@ int dw_pcie_host_init(struct pcie_port *pp)sizeof (pp->msi_msg),DMA_FROM_DEVICE , DMA_ATTR_SKIP_CPU_SYNC); -if (dma_mapping_error (pci->dev, pp->msi_data)) { + ret =dma_mapping_error (pci->dev, pp->msi_data); +if (ret) {dev_err (pci->dev,"Failed to map MSI data\n" ); pp->msi_data =0 ; goto err_free_msi;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 463/772 ARM: dts: ci4x10: Adapt to changes in imx6qdl.dtsi regarding fec clocks
In reply to Greg Kroah-HartmanFrom: Thorsten Scherer <[email protected]>
[ Upstream commit 3d397a1277853498e8b7b305f2610881357c033f ]
Commit f3e7dae323ab ("ARM: dts: imx6qdl: add enet_out clk support") added another item to the list of clocks for the fec device. As imx6dl-eckelmann-ci4x10.dts only overwrites clocks, but not clock-names this resulted in an inconsistency with clocks having one item more than clock-names.
Also overwrite clock-names with the same value as in imx6qdl.dtsi. This is a no-op today, but prevents similar inconsistencies if the soc file will be changed in a similar way in the future.
--- arch/arm/boot/dts/imx6dl-eckelmann-ci4x10.dts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm/boot/dts/imx6dl-eckelmann-ci4x10.dts +5 -1
@@ -297,7 +297,11 @@ phy-mode = "rmii"; phy-reset-gpios = <&gpio1 18 GPIO_ACTIVE_LOW>; phy-handle = <&phy>; - clocks = <&clks IMX6QDL_CLK_ENET>, <&clks IMX6QDL_CLK_ENET>, <&rmii_clk>; + clocks = <&clks IMX6QDL_CLK_ENET>, + <&clks IMX6QDL_CLK_ENET>, + <&rmii_clk>, + <&clks IMX6QDL_CLK_ENET_REF>; + clock-names = "ipg", "ahb", "ptp", "enet_out"; status = "okay"; mdio {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 464/772 soc: qcom: llcc: Add MODULE_DEVICE_TABLE()
In reply to Greg Kroah-HartmanFrom: Bjorn Andersson <[email protected]>
[ Upstream commit 5334a3b12a7233b31788de60d61bfd890059d783 ]
The llcc-qcom driver can be compiled as a module, but lacks MODULE_DEVICE_TABLE() and will therefore not be loaded automatically. Fix this.
--- drivers/soc/qcom/llcc-qcom.c | 1 + 1 file changed, 1 insertion(+)
drivers/soc/qcom/llcc-qcom.c +1 -0
@@ -674,6 +674,7 @@ static const struct of_device_id qcom_llcc_of_match[] = { { .compatible = "qcom,sm8350-llcc", .data = &sm8350_cfg }, { } }; +MODULE_DEVICE_TABLE (of, qcom_llcc_of_match);static struct platform_driver qcom_llcc_driver = { .driver = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 465/772 KVM: nVMX: Leave most VM-Exit info fields unmodified on failed VM-Entry
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
[ Upstream commit c3634d25fbee88e2368a8e0903ae0d0670eb9e71 ]
Don't modify vmcs12 exit fields except EXIT_REASON and EXIT_QUALIFICATION when performing a nested VM-Exit due to failed VM-Entry. Per the SDM, only the two aformentioned fields are filled and "All other VM-exit information fields are unmodified".
Message-Id: <[email protected]>
--- arch/x86/kvm/vmx/nested.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
arch/x86/kvm/vmx/nested.c +10 -5
@@ -4202,12 +4202,12 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,if (to_vmx (vcpu)->exit_reason.enclave_mode) vmcs12->vm_exit_reason |=VMX_EXIT_REASONS_SGX_ENCLAVE_MODE ; vmcs12->exit_qualification = exit_qualification; - vmcs12->vm_exit_intr_info = exit_intr_info; - - vmcs12->idt_vectoring_info_field =0 ; - vmcs12->vm_exit_instruction_len =vmcs_read32 (VM_EXIT_INSTRUCTION_LEN ); - vmcs12->vmx_instruction_info =vmcs_read32 (VMX_INSTRUCTION_INFO ); +/* +* On VM-Exit due to a failed VM-Entry, the VMCS isn't marked launched +* and only EXIT_REASON and EXIT_QUALIFICATION are updated, all other +* exit info fields are unmodified. +*/ if (!(vmcs12->vm_exit_reason &VMX_EXIT_REASONS_FAILED_VMENTRY )) { vmcs12->launch_state =1 ;
@@ -4219,8 +4219,13 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,* Transfer the event that L0 or L1 may wanted to inject into * L2 to IDT_VECTORING_INFO_FIELD. */ + vmcs12->idt_vectoring_info_field =0 ;vmcs12_save_pending_event (vcpu, vmcs12); + vmcs12->vm_exit_intr_info = exit_intr_info; + vmcs12->vm_exit_instruction_len =vmcs_read32 (VM_EXIT_INSTRUCTION_LEN ); + vmcs12->vmx_instruction_info =vmcs_read32 (VMX_INSTRUCTION_INFO ); +/* * According to spec, there's no need to store the guest's * MSRs if the exit is due to a VM-entry failure that occurs
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 466/772 KVM: nVMX: Clear IDT vectoring on nested VM-Exit for double/triple fault
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
[ Upstream commit 9bd1f0efa859b61950d109b32ff8d529cc33a3ad ]
Clear the IDT vectoring field in vmcs12 on next VM-Exit due to a double or triple fault. Per the SDM, a VM-Exit isn't considered to occur during event delivery if the exit is due to an intercepted double fault or a triple fault. Opportunistically move the default clearing (no event "pending") into the helper so that it's more obvious that KVM does indeed handle this case.
Note, the double fault case is worded rather wierdly in the SDM:
The original event results in a double-fault exception that causes the VM exit directly.
Temporarily ignoring injected events, double faults can _only_ occur if an exception occurs while attempting to deliver a different exception, i.e. there's _always_ an original event. And for injected double fault, while there's no original event, injected events are never subject to interception.
Presumably the SDM is calling out that a the vectoring info will be valid if a different exit occurs after a double fault, e.g. if a #PF occurs and is intercepted while vectoring #DF, then the vectoring info will show the double fault. In other words, the clause can simply be read as:
The VM exit is caused by a double-fault exception.
Message-Id: <[email protected]>
--- arch/x86/kvm/vmx/nested.c | 32 ++++++++++++++++++++++++++++---- arch/x86/kvm/vmx/vmcs.h | 5 +++++ 2 files changed, 33 insertions(+), 4 deletions(-)
arch/x86/kvm/vmx/nested.c +28 -4
@@ -3695,12 +3695,34 @@ vmcs12_guest_cr4(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) }static void vmcs12_save_pending_event (struct kvm_vcpu *vcpu, -struct vmcs12 *vmcs12) +struct vmcs12 *vmcs12, +u32 vm_exit_reason,u32 exit_intr_info) {u32 idt_vectoring;unsigned int nr; -if (vcpu->arch.exception.injected) { +/* +* Per the SDM, VM-Exits due to double and triple faults are never +* considered to occur during event delivery, even if the double/triple +* fault is the result of an escalating vectoring issue. +* +* Note, the SDM qualifies the double fault behavior with "The original +* event results in a double-fault exception". It's unclear why the +* qualification exists since exits due to double fault can occur only +* while vectoring a different exception (injected events are never +* subject to interception), i.e. there's _always_ an original event. +* +* The SDM also uses NMI as a confusing example for the "original event +* causes the VM exit directly" clause. NMI isn't special in any way, +* the same rule applies to all events that cause an exit directly. +* NMI is an odd choice for the example because NMIs can only occur on +* instruction boundaries, i.e. they _can't_ occur during vectoring. +*/ +if ((u16 )vm_exit_reason ==EXIT_REASON_TRIPLE_FAULT || + ((u16 )vm_exit_reason ==EXIT_REASON_EXCEPTION_NMI && +is_double_fault (exit_intr_info))) { + vmcs12->idt_vectoring_info_field =0 ; + }else if (vcpu->arch.exception.injected) { nr = vcpu->arch.exception.nr; idt_vectoring = nr |VECTORING_INFO_VALID_MASK ;
@@ -3733,6 +3755,8 @@ static void vmcs12_save_pending_event(struct kvm_vcpu *vcpu, idt_vectoring |=INTR_TYPE_EXT_INTR ; vmcs12->idt_vectoring_info_field = idt_vectoring; + }else { + vmcs12->idt_vectoring_info_field =0 ; } }
@@ -4219,8 +4243,8 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,* Transfer the event that L0 or L1 may wanted to inject into * L2 to IDT_VECTORING_INFO_FIELD. */ - vmcs12->idt_vectoring_info_field =0 ; -vmcs12_save_pending_event (vcpu, vmcs12); +vmcs12_save_pending_event (vcpu, vmcs12, + vm_exit_reason, exit_intr_info); vmcs12->vm_exit_intr_info = exit_intr_info; vmcs12->vm_exit_instruction_len =vmcs_read32 (VM_EXIT_INSTRUCTION_LEN );
arch/x86/kvm/vmx/vmcs.h +5 -0
@@ -104,6 +104,11 @@ static inline bool is_breakpoint(u32 intr_info)return is_exception_n (intr_info,BP_VECTOR ); } +static inline bool is_double_fault (u32 intr_info) +{ +return is_exception_n (intr_info,DF_VECTOR ); +} +static inline bool is_page_fault (u32 intr_info) {return is_exception_n (intr_info,PF_VECTOR );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 467/772 crypto: qat - set CIPHER capability for DH895XCC
In reply to Greg Kroah-HartmanFrom: Giovanni Cabiddu <[email protected]>
[ Upstream commit 6a23804cb8bcb85c6998bf193d94d4036db26f51 ]
Set the CIPHER capability for QAT DH895XCC devices if the hardware supports it. This is done if both the CIPHER and the AUTHENTICATION engines are available on the device.
--- .../crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c +9 -3
@@ -58,17 +58,23 @@ static u32 get_accel_cap(struct adf_accel_dev *accel_dev) capabilities =ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC |ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC | -ICP_ACCEL_CAPABILITIES_AUTHENTICATION ; +ICP_ACCEL_CAPABILITIES_AUTHENTICATION | +ICP_ACCEL_CAPABILITIES_CIPHER ;/* Read accelerator capabilities mask */ pci_read_config_dword (pdev,ADF_DEVICE_LEGFUSE_OFFSET , &legfuses); -if (legfuses &ICP_ACCEL_MASK_CIPHER_SLICE ) +/* A set bit in legfuses means the feature is OFF in this SKU */ +if (legfuses &ICP_ACCEL_MASK_CIPHER_SLICE ) { capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC ; + capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER ; + }if (legfuses &ICP_ACCEL_MASK_PKE_SLICE ) capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC ; -if (legfuses &ICP_ACCEL_MASK_AUTH_SLICE ) +if (legfuses &ICP_ACCEL_MASK_AUTH_SLICE ) { capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION ; + capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER ; + }if (legfuses &ICP_ACCEL_MASK_COMPRESS_SLICE ) capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 468/772 crypto: qat - set COMPRESSION capability for DH895XCC
In reply to Greg Kroah-HartmanFrom: Giovanni Cabiddu <[email protected]>
[ Upstream commit 0eaa51543273fd0f4ba9bea83638f7033436e5eb ]
The capability detection logic clears bits for the features that are disabled in a certain SKU. For example, if the bit associate to compression is not present in the LEGFUSE register, the correspondent bit is cleared in the capability mask.
This change adds the compression capability to the mask as this was missing in the commit that enhanced the capability detection logic.
--- drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c +2 -1
@@ -59,7 +59,8 @@ static u32 get_accel_cap(struct adf_accel_dev *accel_dev) capabilities =ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC |ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC |ICP_ACCEL_CAPABILITIES_AUTHENTICATION | -ICP_ACCEL_CAPABILITIES_CIPHER ; +ICP_ACCEL_CAPABILITIES_CIPHER | +ICP_ACCEL_CAPABILITIES_COMPRESSION ;/* Read accelerator capabilities mask */ pci_read_config_dword (pdev,ADF_DEVICE_LEGFUSE_OFFSET , &legfuses);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 469/772 platform/chrome: cros_ec: fix error handling in cros_ec_register()
In reply to Greg Kroah-HartmanFrom: Tzung-Bi Shih <[email protected]>
[ Upstream commit 2cd01bd6b117df07b1bc2852f08694fdd29e40ed ]
Fix cros_ec_register() to unregister platform devices if blocking_notifier_chain_register() fails.
Also use the single exit path to handle the platform device unregistration.
--- drivers/platform/chrome/cros_ec.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/platform/chrome/cros_ec.c +10 -6
@@ -189,6 +189,8 @@ int cros_ec_register(struct cros_ec_device *ec_dev) ec_dev->max_request =sizeof (struct ec_params_hello ); ec_dev->max_response =sizeof (struct ec_response_get_protocol_info ); ec_dev->max_passthru =0 ; + ec_dev->ec =NULL ; + ec_dev->pd =NULL ; ec_dev->din =devm_kzalloc (dev, ec_dev->din_size,GFP_KERNEL );if (!ec_dev->din)
@@ -245,18 +247,16 @@ int cros_ec_register(struct cros_ec_device *ec_dev)if (IS_ERR (ec_dev->pd)) {dev_err (ec_dev->dev,"Failed to create CrOS PD platform device\n" ); -platform_device_unregister (ec_dev->ec); -return PTR_ERR (ec_dev->pd); + err =PTR_ERR (ec_dev->pd); + goto exit; } }if (IS_ENABLED (CONFIG_OF ) && dev->of_node) { err =devm_of_platform_populate (dev);if (err) { -platform_device_unregister (ec_dev->pd); -platform_device_unregister (ec_dev->ec);dev_err (dev,"Failed to register sub-devices\n" ); -return err; + goto exit; } }
@@ -278,7 +278,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev) err =blocking_notifier_chain_register (&ec_dev->event_notifier, &ec_dev->notifier_ready);if (err) -return err; + goto exit; }dev_info (dev,"Chrome EC device registered\n" );
@@ -291,6 +291,10 @@ int cros_ec_register(struct cros_ec_device *ec_dev)cros_ec_irq_thread (0 , ec_dev);return 0 ; +exit: +platform_device_unregister (ec_dev->ec); +platform_device_unregister (ec_dev->pd); +return err; }EXPORT_SYMBOL (cros_ec_register);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 470/772 ARM: dts: imx6dl-colibri: Fix I2C pinmuxing
In reply to Greg Kroah-HartmanFrom: Max Krummenacher <[email protected]>
[ Upstream commit 5f5c579a34a87117c20b411df583ae816c1ec84f ]
Fix names of extra pingroup node and property for gpio bus recovery. Without the change i2c2 is not functional.
--- arch/arm/boot/dts/imx6qdl-colibri.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm/boot/dts/imx6qdl-colibri.dtsi +3 -3
@@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2014-2020 Toradex + * Copyright 2014-2022 Toradex * Copyright 2012 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. */
@@ -132,7 +132,7 @@ clock-frequency = <100000>; pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c2>; - pinctrl-0 = <&pinctrl_i2c2_gpio>; + pinctrl-1 = <&pinctrl_i2c2_gpio>; scl-gpios = <&gpio2 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; sda-gpios = <&gpio3 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; status = "okay";
@@ -488,7 +488,7 @@ >; }; - pinctrl_i2c2_gpio: i2c2grp { + pinctrl_i2c2_gpio: i2c2gpiogrp { fsl,pins = < MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x4001b8b1 MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x4001b8b1
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 471/772 platform/chrome: Re-introduce cros_ec_cmd_xfer and use it for ioctls
In reply to Greg Kroah-HartmanFrom: Guenter Roeck <[email protected]>
[ Upstream commit 57b888ca2541785de2fcb90575b378921919b6c0 ]
Commit 413dda8f2c6f ("platform/chrome: cros_ec_chardev: Use cros_ec_cmd_xfer_status helper") inadvertendly changed the userspace ABI. Previously, cros_ec ioctls would only report errors if the EC communication failed, and otherwise return success and the result of the EC communication. An EC command execution failure was reported in the EC response field. The above mentioned commit changed this behavior, and the ioctl itself would fail. This breaks userspace commands trying to analyze the EC command execution error since the actual EC command response is no longer reported to userspace.
Fix the problem by re-introducing the cros_ec_cmd_xfer() helper, and use it to handle ioctl messages.
--- drivers/platform/chrome/cros_ec_chardev.c | 2 +- drivers/platform/chrome/cros_ec_proto.c | 50 +++++++++++++++++---- include/linux/platform_data/cros_ec_proto.h | 3 ++ 3 files changed, 45 insertions(+), 10 deletions(-)
drivers/platform/chrome/cros_ec_chardev.c +1 -1
@@ -301,7 +301,7 @@ static long cros_ec_chardev_ioctl_xcmd(struct cros_ec_dev *ec, void __user *arg) } s_cmd->command += ec->cmd_offset; - ret =cros_ec_cmd_xfer_status (ec->ec_dev, s_cmd); + ret =cros_ec_cmd_xfer (ec->ec_dev, s_cmd);/* Only copy data to userland if data was received. */ if (ret <0 ) goto exit;
drivers/platform/chrome/cros_ec_proto.c +41 -9
69 lines not on this page · raw message
include/linux/platform_data/cros_ec_proto.h +3 -0
@@ -216,6 +216,9 @@ int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,int cros_ec_check_result (struct cros_ec_device *ec_dev,struct cros_ec_command *msg); +int cros_ec_cmd_xfer (struct cros_ec_device *ec_dev, +struct cros_ec_command *msg); +int cros_ec_cmd_xfer_status (struct cros_ec_device *ec_dev,struct cros_ec_command *msg);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 472/772 can: xilinx_can: mark bit timing constants as const
In reply to Greg Kroah-HartmanFrom: Marc Kleine-Budde <[email protected]>
[ Upstream commit ae38fda02996d43d9fb09f16e81e0008704dd524 ]
This patch marks the bit timing constants as const.
--- drivers/net/can/xilinx_can.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/can/xilinx_can.c +2 -2
@@ -239,7 +239,7 @@ static const struct can_bittiming_const xcan_bittiming_const_canfd = { };/* AXI CANFD Data Bittiming constants as per AXI CANFD 1.0 specs */ -static struct can_bittiming_const xcan_data_bittiming_const_canfd = { +static const struct can_bittiming_const xcan_data_bittiming_const_canfd = { .name =DRIVER_NAME , .tseg1_min =1 , .tseg1_max =16 ,
@@ -265,7 +265,7 @@ static const struct can_bittiming_const xcan_bittiming_const_canfd2 = { };/* AXI CANFD 2.0 Data Bittiming constants as per AXI CANFD 2.0 spec */ -static struct can_bittiming_const xcan_data_bittiming_const_canfd2 = { +static const struct can_bittiming_const xcan_data_bittiming_const_canfd2 = { .name =DRIVER_NAME , .tseg1_min =1 , .tseg1_max =32 ,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 473/772 ARM: dts: stm32: Fix PHY post-reset delay on Avenger96
In reply to Greg Kroah-HartmanFrom: Marek Vasut <[email protected]>
[ Upstream commit ef2d90708883f4025a801feb0ba8411a7a4387e1 ]
Per KSZ9031RNX PHY datasheet FIGURE 7-5: POWER-UP/POWER-DOWN/RESET TIMING Note 2: After the de-assertion of reset, wait a minimum of 100 μs before starting programming on the MIIM (MDC/MDIO) interface.
Add 1ms post-reset delay to guarantee this figure.
--- arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 1 + 1 file changed, 1 insertion(+)
arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi +1 -0
@@ -141,6 +141,7 @@ compatible = "snps,dwmac-mdio"; reset-gpios = <&gpioz 2 GPIO_ACTIVE_LOW>; reset-delay-us = <1000>; + reset-post-delay-us = <1000>; phy0: ethernet-phy@7 { reg = <7>;
Signature · 9 lines
2.35.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Greg Kroah-Hartman
maintainerPATCH 474/772 dt-bindings: soc: qcom: smd-rpm: Fix missing MSM8936 compatible
In reply to Greg Kroah-HartmanFrom: Bryan O'Donoghue <[email protected]>
[ Upstream commit e930244918092d44b60a7b538cf60d737010ceef ]
Add compatible msm8936. msm8936 covers both msm8936 and msm8939. The relevant driver already has the compat string but, we haven't documented it.
--- Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml | 1 + 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml +1 -0
@@ -34,6 +34,7 @@ properties: - qcom,rpm-ipq6018 - qcom,rpm-msm8226 - qcom,rpm-msm8916 + - qcom,rpm-msm8936 - qcom,rpm-msm8953 - qcom,rpm-msm8974 - qcom,rpm-msm8976
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 475/772 ARM: dts: qcom: sdx55: remove wrong unit address from RPMH RSC clocks
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 97c246c825f73a018169834e56ffa9a89dea37a9 ]
The clock controller of RPMH RSC does not have 'reg' property, so should not have unit address.
--- arch/arm/boot/dts/qcom-sdx65.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/qcom-sdx65.dtsi +1 -1
@@ -202,7 +202,7 @@ <WAKE_TCS 2>, <CONTROL_TCS 1>; - rpmhcc: clock-controller@1 { + rpmhcc: clock-controller { compatible = "qcom,sdx65-rpmh-clk"; #clock-cells = <1>; clock-names = "xo";
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 476/772 ARM: dts: bcm2835-rpi-zero-w: Fix GPIO line name for Wifi/BT
In reply to Greg Kroah-HartmanFrom: Phil Elwell <[email protected]>
[ Upstream commit 2c663e5e5bbf2a5b85e0f76ccb69663f583c3e33 ]
The GPIOs 30 to 39 are connected to the Cypress CYW43438 (Wifi/BT). So fix the GPIO line names accordingly.
--- arch/arm/boot/dts/bcm2835-rpi-zero-w.dts | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
arch/arm/boot/dts/bcm2835-rpi-zero-w.dts +12 -10
@@ -74,16 +74,18 @@ "GPIO27", "SDA0", "SCL0", - "NC", /* GPIO30 */ - "NC", /* GPIO31 */ - "NC", /* GPIO32 */ - "NC", /* GPIO33 */ - "NC", /* GPIO34 */ - "NC", /* GPIO35 */ - "NC", /* GPIO36 */ - "NC", /* GPIO37 */ - "NC", /* GPIO38 */ - "NC", /* GPIO39 */ + /* Used by BT module */ + "CTS0", + "RTS0", + "TXD0", + "RXD0", + /* Used by Wifi */ + "SD1_CLK", + "SD1_CMD", + "SD1_DATA0", + "SD1_DATA1", + "SD1_DATA2", + "SD1_DATA3", "CAM_GPIO1", /* GPIO40 */ "WL_ON", /* GPIO41 */ "NC", /* GPIO42 */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 477/772 ARM: dts: bcm2837-rpi-cm3-io3: Fix GPIO line names for SMPS I2C
In reply to Greg Kroah-HartmanFrom: Phil Elwell <[email protected]>
[ Upstream commit 9fd26fd02749ec964eb0d588a3bab9e09bf77927 ]
The GPIOs 46 & 47 are already used for a I2C interface to a SMPS. So fix the GPIO line names accordingly.
--- arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts +2 -2
@@ -63,8 +63,8 @@ "GPIO43", "GPIO44", "GPIO45", - "GPIO46", - "GPIO47", + "SMPS_SCL", + "SMPS_SDA", /* Used by eMMC */ "SD_CLK_R", "SD_CMD_R",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 478/772 ARM: dts: bcm2837-rpi-3-b-plus: Fix GPIO line name of power LED
In reply to Greg Kroah-HartmanFrom: Phil Elwell <[email protected]>
[ Upstream commit 57f718aa4b93392fb1a8c0a874ab882b9e18136a ]
The red LED on the Raspberry Pi 3 B Plus is the power LED. So fix the GPIO line name accordingly.
--- arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts +1 -1
@@ -45,7 +45,7 @@ #gpio-cells = <2>; gpio-line-names = "BT_ON", "WL_ON", - "STATUS_LED_R", + "PWR_LED_R", "LAN_RUN", "", "CAM_GPIO0",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 479/772 ARM: dts: bcm2835-rpi-b: Fix GPIO line names
In reply to Greg Kroah-HartmanFrom: Stefan Wahren <[email protected]>
[ Upstream commit 97bd8659c1c46c23e4daea7e040befca30939950 ]
Recently this has been fixed in the vendor tree, so upstream this.
--- arch/arm/boot/dts/bcm2835-rpi-b.dts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
arch/arm/boot/dts/bcm2835-rpi-b.dts +6 -7
@@ -53,18 +53,17 @@ "GPIO18", "NC", /* GPIO19 */ "NC", /* GPIO20 */ - "GPIO21", + "CAM_GPIO0", "GPIO22", "GPIO23", "GPIO24", "GPIO25", "NC", /* GPIO26 */ - "CAM_GPIO0", - /* Binary number representing build/revision */ - "CONFIG0", - "CONFIG1", - "CONFIG2", - "CONFIG3", + "GPIO27", + "GPIO28", + "GPIO29", + "GPIO30", + "GPIO31", "NC", /* GPIO32 */ "NC", /* GPIO33 */ "NC", /* GPIO34 */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 480/772 misc: ocxl: fix possible double free in ocxl_file_register_afu
In reply to Greg Kroah-HartmanFrom: Hangyu Hua <[email protected]>
[ Upstream commit 950cf957fe34d40d63dfa3bf3968210430b6491e ]
info_release() will be called in device_unregister() when info->dev's reference count is 0. So there is no need to call ocxl_afu_put() and kfree() again.
Fix this by adding free_minor() and return to err_unregister error path.
--- drivers/misc/ocxl/file.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/misc/ocxl/file.c +2 -0
@@ -556,7 +556,9 @@ int ocxl_file_register_afu(struct ocxl_afu *afu) err_unregister:ocxl_sysfs_unregister_afu (info);// safe to call even if register failed +free_minor (info);device_unregister (&info->dev); +return rc; err_put:ocxl_afu_put (afu);free_minor (info);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 481/772 hwrng: cn10k - Optimize cn10k_rng_read()
In reply to Greg Kroah-HartmanFrom: Vladis Dronov <[email protected]>
[ Upstream commit 753d6770879894de10d74b437ab99ea380f1cad7 ]
This function assumes that sizeof(void) is 1 and arithmetic works for void pointers. This is a GNU C extention and may not work with other compilers. Change this by using an u8 pointer.
Also move cn10k_read_trng() out of a loop thus saving some cycles.
--- drivers/char/hw_random/cn10k-rng.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/char/hw_random/cn10k-rng.c +10 -6
@@ -90,6 +90,7 @@ static int cn10k_rng_read(struct hwrng *hwrng, void *data, {struct cn10k_rng *rng = (struct cn10k_rng *)hwrng->priv;unsigned int size; +u8 *pos = data;int err =0 ;u64 value;
@@ -102,17 +103,20 @@ static int cn10k_rng_read(struct hwrng *hwrng, void *data,while (size >=8 ) {cn10k_read_trng (rng, &value); - *((u64 *)data) = (u64 )value; + *((u64 *)pos) = value; size -=8 ; - data +=8 ; + pos +=8 ; } -while (size >0 ) { +if (size >0 ) {cn10k_read_trng (rng, &value); - *((u8 *)data) = (u8 )value; - size--; - data++; +while (size >0 ) { + *pos = (u8 )value; + value >>=8 ; + size--; + pos++; + } }return max - size;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 482/772 hwrng: cn10k - Make check_rng_health() return an error code
In reply to Greg Kroah-HartmanFrom: Vladis Dronov <[email protected]>
[ Upstream commit 32547a6aedda132907fcd15cdc8271429609f216 ]
Currently check_rng_health() returns zero unconditionally. Make it to output an error code and return it.
--- drivers/char/hw_random/cn10k-rng.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
drivers/char/hw_random/cn10k-rng.c +7 -8
@@ -31,26 +31,23 @@ struct cn10k_rng {#define PLAT_OCTEONTX_RESET_RNG_EBG_HEALTH_STATE 0xc2000b0f -static int reset_rng_health_state (struct cn10k_rng *rng) +static unsigned long reset_rng_health_state (struct cn10k_rng *rng) {struct arm_smccc_res res;/* Send SMC service call to reset EBG health state */ arm_smccc_smc (PLAT_OCTEONTX_RESET_RNG_EBG_HEALTH_STATE ,0 ,0 ,0 ,0 ,0 ,0 ,0 , &res); -if (res.a0 !=0UL ) -return -EIO ; - -return 0 ; +return res.a0; }static int check_rng_health (struct cn10k_rng *rng) {u64 status; -int err; +unsigned long err;/* Skip checking health */ if (!rng->reg_base) -return 0 ; +return -ENODEV ; status =readq (rng->reg_base +RNM_PF_EBG_HEALTH );if (status &BIT_ULL (20 )) {
@@ -58,7 +55,9 @@ static int check_rng_health(struct cn10k_rng *rng)if (err) {dev_err (&rng->pdev->dev,"HWRNG: Health test failed (status=%llx)\n" , status); -dev_err (&rng->pdev->dev,"HWRNG: error during reset\n" ); +dev_err (&rng->pdev->dev,"HWRNG: error during reset (error=%lx)\n" , + err); +return -EIO ; } }return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 483/772 crypto: marvell/cesa - ECB does not IV
In reply to Greg Kroah-HartmanFrom: Corentin Labbe <[email protected]>
[ Upstream commit 4ffa1763622ae5752961499588f3f8874315f974 ]
The DES3 ECB has an IV size set but ECB does not need one.
--- drivers/crypto/marvell/cesa/cipher.c | 1 - 1 file changed, 1 deletion(-)
drivers/crypto/marvell/cesa/cipher.c +0 -1
@@ -624,7 +624,6 @@ struct skcipher_alg mv_cesa_ecb_des3_ede_alg = { .decrypt = mv_cesa_ecb_des3_ede_decrypt, .min_keysize = DES3_EDE_KEY_SIZE, .max_keysize = DES3_EDE_KEY_SIZE, - .ivsize = DES3_EDE_BLOCK_SIZE, .base = { .cra_name = "ecb(des3_ede)", .cra_driver_name = "mv-ecb-des3-ede",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 484/772 gpiolib: of: Introduce hook for missing gpio-ranges
In reply to Greg Kroah-HartmanFrom: Stefan Wahren <[email protected]>
[ Upstream commit 3550bba25d5587a701e6edf20e20984d2ee72c78 ]
Since commit 2ab73c6d8323 ("gpio: Support GPIO controllers without pin-ranges") the device tree nodes of GPIO controller need the gpio-ranges property to handle gpio-hogs. Unfortunately it's impossible to guarantee that every new kernel is shipped with an updated device tree binary.
In order to provide backward compatibility with those older DTB, we need a callback within of_gpiochip_add_pin_range() so the relevant platform driver can handle this case.
--- drivers/gpio/gpiolib-of.c | 5 +++++ include/linux/gpio/driver.h | 12 ++++++++++++ 2 files changed, 17 insertions(+)
drivers/gpio/gpiolib-of.c +5 -0
@@ -933,6 +933,11 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)if (!np)return 0 ; +if (!of_property_read_bool (np,"gpio-ranges" ) && + chip->of_gpio_ranges_fallback) { +return chip->of_gpio_ranges_fallback (chip, np); + } + group_names =of_find_property (np, group_names_propname,NULL );for (;; index++) {
include/linux/gpio/driver.h +12 -0
@@ -498,6 +498,18 @@ struct gpio_chip {*/ int (*of_xlate)(struct gpio_chip *gc,const struct of_phandle_args *gpiospec,u32 *flags); + +/** +* @of_gpio_ranges_fallback: +* +* Optional hook for the case that no gpio-ranges property is defined +* within the device tree node "np" (usually DT before introduction +* of gpio-ranges). So this callback is helpful to provide the +* necessary backward compatibility for the pin ranges. +*/ +int (*of_gpio_ranges_fallback)(struct gpio_chip *gc, +struct device_node *np); +#endif /* CONFIG_OF_GPIO */ };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 485/772 pinctrl: bcm2835: implement hook for missing gpio-ranges
In reply to Greg Kroah-HartmanFrom: Stefan Wahren <[email protected]>
[ Upstream commit d2b67744fd99b06555b7e4d67302ede6c7c6a638 ]
The commit c8013355ead6 ("ARM: dts: gpio-ranges property is now required") fixed the GPIO probing issues caused by "pinctrl: bcm2835: Change init order for gpio hogs". This changed only the kernel DTS files. Unfortunately it isn't guaranteed that these files are shipped to all users.
So implement the necessary backward compatibility for BCM2835 and BCM2711 platform.
--- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
drivers/pinctrl/bcm/pinctrl-bcm2835.c +18 -0
@@ -358,6 +358,22 @@ static int bcm2835_gpio_direction_output(struct gpio_chip *chip,return 0 ; } +static int bcm2835_of_gpio_ranges_fallback (struct gpio_chip *gc, +struct device_node *np) +{ +struct pinctrl_dev *pctldev =of_pinctrl_get (np); + +of_node_put (np); + +if (!pctldev) +return 0 ; + +gpiochip_add_pin_range (gc,pinctrl_dev_get_devname (pctldev),0 ,0 , + gc->ngpio); + +return 0 ; +} +static const struct gpio_chip bcm2835_gpio_chip = { .label =MODULE_NAME , .owner =THIS_MODULE ,
@@ -372,6 +388,7 @@ static const struct gpio_chip bcm2835_gpio_chip = { .base = -1, .ngpio = BCM2835_NUM_GPIOS, .can_sleep = false, + .of_gpio_ranges_fallback = bcm2835_of_gpio_ranges_fallback, };static const struct gpio_chip bcm2711_gpio_chip = {
@@ -388,6 +405,7 @@ static const struct gpio_chip bcm2711_gpio_chip = { .base = -1, .ngpio = BCM2711_NUM_GPIOS, .can_sleep = false, + .of_gpio_ranges_fallback = bcm2835_of_gpio_ranges_fallback, }; static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 486/772 drm/msm: simplify gpu_busy callback
In reply to Greg Kroah-HartmanFrom: Chia-I Wu <[email protected]>
[ Upstream commit 15c411980bacddf294452fd1cf7308b14f3f8c63 ]
Move tracking and busy time calculation to msm_devfreq_get_dev_status.
--- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 19 ++++++---------- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 15 +++++-------- drivers/gpu/drm/msm/msm_gpu.h | 9 +++----- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 32 ++++++++++++++++++++++----- 4 files changed, 41 insertions(+), 34 deletions(-)
drivers/gpu/drm/msm/adreno/a5xx_gpu.c +7 -12
@@ -1662,28 +1662,23 @@ static struct msm_ringbuffer *a5xx_active_ring(struct msm_gpu *gpu)return a5xx_gpu->cur_ring; } -static unsigned long a5xx_gpu_busy (struct msm_gpu *gpu) +static u64 a5xx_gpu_busy (struct msm_gpu *gpu,unsigned long *out_sample_rate) { -u64 busy_cycles, busy_time; +u64 busy_cycles;/* Only read the gpu busy if the hardware is already active */ -if (pm_runtime_get_if_in_use (&gpu->pdev->dev) ==0 ) +if (pm_runtime_get_if_in_use (&gpu->pdev->dev) ==0 ) { + *out_sample_rate =1 ;return 0 ; + } busy_cycles =gpu_read64 (gpu,REG_A5XX_RBBM_PERFCTR_RBBM_0_LO ,REG_A5XX_RBBM_PERFCTR_RBBM_0_HI ); - - busy_time = busy_cycles - gpu->devfreq.busy_cycles; -do_div (busy_time,clk_get_rate (gpu->core_clk) /1000000 ); - - gpu->devfreq.busy_cycles = busy_cycles; + *out_sample_rate =clk_get_rate (gpu->core_clk);pm_runtime_put (&gpu->pdev->dev); -if (WARN_ON (busy_time > ~0LU )) -return ~0LU ; - -return (unsigned long )busy_time; +return busy_cycles; }static uint32_t a5xx_get_rptr (struct msm_gpu *gpu,struct msm_ringbuffer *ring)
drivers/gpu/drm/msm/adreno/a6xx_gpu.c +5 -10
@@ -1621,12 +1621,14 @@ static void a6xx_destroy(struct msm_gpu *gpu)kfree (a6xx_gpu); } -static unsigned long a6xx_gpu_busy (struct msm_gpu *gpu) +static u64 a6xx_gpu_busy (struct msm_gpu *gpu,unsigned long *out_sample_rate) {struct adreno_gpu *adreno_gpu =to_adreno_gpu (gpu);struct a6xx_gpu *a6xx_gpu =to_a6xx_gpu (adreno_gpu); -u64 busy_cycles, busy_time; +u64 busy_cycles; +/* 19.2MHz */ + *out_sample_rate =19200000 ;/* Only read the gpu busy if the hardware is already active */ if (pm_runtime_get_if_in_use (a6xx_gpu->gmu.dev) ==0 )
@@ -1636,17 +1638,10 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu)REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L , REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H); - busy_time = (busy_cycles - gpu->devfreq.busy_cycles) *10 ; -do_div (busy_time,192 ); - - gpu->devfreq.busy_cycles = busy_cycles;pm_runtime_put (a6xx_gpu->gmu.dev); -if (WARN_ON (busy_time > ~0LU )) -return ~0LU ; - -return (unsigned long )busy_time; +return busy_cycles; }static void a6xx_gpu_set_freq (struct msm_gpu *gpu,struct dev_pm_opp *opp)
drivers/gpu/drm/msm/msm_gpu.h +3 -6
@@ -59,7 +59,7 @@ struct msm_gpu_funcs {/* for generation specific debugfs: */ void (*debugfs_init)(struct msm_gpu *gpu,struct drm_minor *minor);#endif -unsigned long (*gpu_busy)(struct msm_gpu *gpu); +u64 (*gpu_busy)(struct msm_gpu *gpu,unsigned long *out_sample_rate);struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu);int (*gpu_state_put)(struct msm_gpu_state *state);unsigned long (*gpu_get_freq)(struct msm_gpu *gpu);
@@ -103,11 +103,8 @@ struct msm_gpu_devfreq {struct dev_pm_qos_request boost_freq;/** -* busy_cycles: -* -* Used by implementation of gpu->gpu_busy() to track the last -* busy counter value, for calculating elapsed busy cycles since -* last sampling period. +* busy_cycles: Last busy counter value, for calculating elapsed busy +* cycles since last sampling period. */ u64 busy_cycles;
drivers/gpu/drm/msm/msm_gpu_devfreq.c +26 -6
@@ -49,18 +49,38 @@ static unsigned long get_freq(struct msm_gpu *gpu)return clk_get_rate (gpu->core_clk); } -static int msm_devfreq_get_dev_status (struct device *dev, +static void get_raw_dev_status (struct msm_gpu *gpu,struct devfreq_dev_status *status) { -struct msm_gpu *gpu =dev_to_gpu (dev); +struct msm_gpu_devfreq *df = &gpu->devfreq; +u64 busy_cycles, busy_time; +unsigned long sample_rate;ktime_t time; status->current_frequency =get_freq (gpu); - status->busy_time = gpu->funcs->gpu_busy (gpu); - + busy_cycles = gpu->funcs->gpu_busy (gpu, &sample_rate); time =ktime_get (); - status->total_time =ktime_us_delta (time, gpu->devfreq.time); - gpu->devfreq.time = time; + + busy_time = busy_cycles - df->busy_cycles; + status->total_time =ktime_us_delta (time, df->time); + + df->busy_cycles = busy_cycles; + df->time = time; + + busy_time *=USEC_PER_SEC ; +do_div (busy_time, sample_rate); +if (WARN_ON (busy_time > ~0LU )) + busy_time = ~0LU ; + + status->busy_time = busy_time; +} + +static int msm_devfreq_get_dev_status (struct device *dev, +struct devfreq_dev_status *status) +{ +struct msm_gpu *gpu =dev_to_gpu (dev); + +get_raw_dev_status (gpu, status);return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 487/772 drm/msm: return the average load over the polling period
In reply to Greg Kroah-HartmanFrom: Chia-I Wu <[email protected]>
[ Upstream commit 78f815c1cf8fc5f05dc5cec29eb1895cb53470e9 ]
simple_ondemand interacts poorly with clamp_to_idle. It only looks at the load since the last get_dev_status call, while it should really look at the load over polling_ms. When clamp_to_idle true, it almost always picks the lowest frequency on active because the gpu is idle between msm_devfreq_idle/msm_devfreq_active.
This logic could potentially be moved into devfreq core.
--- drivers/gpu/drm/msm/msm_gpu.h | 3 ++ drivers/gpu/drm/msm/msm_gpu_devfreq.c | 60 ++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-)
drivers/gpu/drm/msm/msm_gpu.h +3 -0
@@ -9,6 +9,7 @@#include <linux/adreno-smmu-priv.h> #include <linux/clk.h> +#include <linux/devfreq.h> #include <linux/interconnect.h> #include <linux/pm_opp.h> #include <linux/regulator/consumer.h>
@@ -114,6 +115,8 @@ struct msm_gpu_devfreq {/** idle_time: Time of last transition to idle: */ ktime_t idle_time; +struct devfreq_dev_status average_status; +/** * idle_work: *
drivers/gpu/drm/msm/msm_gpu_devfreq.c +59 -1
77 lines not on this page · raw message
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 488/772 arm: mediatek: select arch timer for mt7629
In reply to Greg Kroah-HartmanFrom: Chuanhong Guo <[email protected]>
[ Upstream commit d66aea197d534e23d4989eb72fca9c0c114b97c9 ]
This chip has an armv7 arch timer according to the dts. Select it in Kconfig to enforce the support for it.
Otherwise the system time is just completely wrong if user forget to enable ARM_ARCH_TIMER in kernel config.
--- arch/arm/mach-mediatek/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/arm/mach-mediatek/Kconfig +1 -0
@@ -30,6 +30,7 @@ config MACH_MT7623 config MACH_MT7629 bool "MediaTek MT7629 SoCs support" default ARCH_MEDIATEK + select HAVE_ARM_ARCH_TIMER config MACH_MT8127 bool "MediaTek MT8127 SoCs support"
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 489/772 pinctrl/rockchip: support deferring other gpio params
In reply to Greg Kroah-HartmanFrom: Caleb Connolly <[email protected]>
[ Upstream commit 8ce5ef64546850294b021497046588a7abcebe96 ]
Add support for deferring other params like PIN_CONFIG_INPUT_ENABLE. This will be used to add support for PIN_CONFIG_INPUT_ENABLE to the driver.
--- drivers/gpio/gpio-rockchip.c | 24 ++++++++----- drivers/pinctrl/pinctrl-rockchip.c | 54 ++++++++++++++++-------------- drivers/pinctrl/pinctrl-rockchip.h | 7 ++-- 3 files changed, 50 insertions(+), 35 deletions(-)
drivers/gpio/gpio-rockchip.c +16 -8
@@ -19,6 +19,7 @@#include <linux/of_address.h> #include <linux/of_device.h> #include <linux/of_irq.h> +#include <linux/pinctrl/pinconf-generic.h> #include <linux/regmap.h> #include "../pinctrl/core.h"
@@ -706,7 +707,7 @@ static int rockchip_gpio_probe(struct platform_device *pdev)struct device_node *pctlnp =of_get_parent (np);struct pinctrl_dev *pctldev =NULL ;struct rockchip_pin_bank *bank =NULL ; -struct rockchip_pin_output_deferred *cfg; +struct rockchip_pin_deferred *cfg;static int gpio;int id, ret;
@@ -747,15 +748,22 @@ static int rockchip_gpio_probe(struct platform_device *pdev)return ret; } -while (!list_empty (&bank->deferred_output)) { - cfg =list_first_entry (&bank->deferred_output, - struct rockchip_pin_output_deferred, head); +while (!list_empty (&bank->deferred_pins)) { + cfg =list_first_entry (&bank->deferred_pins, + struct rockchip_pin_deferred, head);list_del (&cfg->head); - ret =rockchip_gpio_direction_output (&bank->gpio_chip, cfg->pin, cfg->arg); -if (ret) -dev_warn (dev,"setting output pin %u to %u failed\n" , cfg->pin, cfg->arg); - +switch (cfg->param) { +case PIN_CONFIG_OUTPUT : + ret =rockchip_gpio_direction_output (&bank->gpio_chip, cfg->pin, cfg->arg); +if (ret) +dev_warn (dev,"setting output pin %u to %u failed\n" , cfg->pin, + cfg->arg); +break ; +default : +dev_warn (dev,"unknown deferred config param %d\n" , cfg->param); +break ; + }kfree (cfg); }
drivers/pinctrl/pinctrl-rockchip.c +29 -25
99 lines not on this page · raw message
drivers/pinctrl/pinctrl-rockchip.h +5 -2
@@ -171,7 +171,7 @@ struct rockchip_pin_bank {u32 toggle_edge_mode;u32 recalced_mask;u32 route_mask; -struct list_head deferred_output; +struct list_head deferred_pins;struct mutex deferred_lock; };
@@ -247,9 +247,12 @@ struct rockchip_pin_config {unsigned int nconfigs; }; -struct rockchip_pin_output_deferred { +enum pin_config_param ; + +struct rockchip_pin_deferred {struct list_head head;unsigned int pin; +enum pin_config_param param;u32 arg; };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 490/772 pinctrl: mediatek: mt8195: enable driver on mtk platforms
In reply to Greg Kroah-HartmanFrom: Fabien Parent <[email protected]>
[ Upstream commit 931d7fa89e640dea146e00b77c1d73459e66ab6e ]
Set the pinctrl driver as built-in by default if
ARM64 and ARCH_MEDIATEK are enabled.
--- drivers/pinctrl/mediatek/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/pinctrl/mediatek/Kconfig +1 -0
@@ -159,6 +159,7 @@ config PINCTRL_MT8195 bool "Mediatek MT8195 pin control" depends on OF depends on ARM64 || COMPILE_TEST + default ARM64 && ARCH_MEDIATEK select PINCTRL_MTK_PARIS config PINCTRL_MT8365
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 491/772 arm64: dts: qcom: qrb5165-rb5: Fix can-clock node name
In reply to Greg Kroah-HartmanFrom: Vinod Koul <[email protected]>
[ Upstream commit 1eae95fb1d696968ca72be3ac8e0d62bb4d8da42 ]
Per DT spec node names should not have underscores (_) in them, so change can_clock to can-clock.
--- arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/qrb5165-rb5.dts +1 -1
@@ -29,7 +29,7 @@ }; /* Fixed crystal oscillator dedicated to MCP2518FD */ - clk40M: can_clock { + clk40M: can-clock { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <40000000>;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 492/772 Drivers: hv: vmbus: Fix handling of messages with transaction ID of zero
In reply to Greg Kroah-HartmanFrom: Andrea Parri (Microsoft) <[email protected]>
[ Upstream commit 82cd4bacff88a11e36f143e2cb950174b09c86c3 ]
vmbus_request_addr() returns 0 (zero) if the transaction ID passed to as argument is 0. This is unfortunate for two reasons: first, netvsc_send_completion() does not check for a NULL cmd_rqst (before dereferencing the corresponding NVSP message); second, 0 is a *valid* value of cmd_rqst in netvsc_send_tx_complete(), cf. the call of vmbus_sendpacket() in netvsc_send_pkt().
vmbus_request_addr() has included the code in question since its introduction with commit e8b7db38449ac ("Drivers: hv: vmbus: Add vmbus_requestor data structure for VMBus hardening"); such code was motivated by the early use of vmbus_requestor by hv_storvsc. Since hv_storvsc moved to a tag-based mechanism to generate and retrieve transaction IDs with commit bf5fd8cae3c8f ("scsi: storvsc: Use blk_mq_unique_tag() to generate requestIDs"), vmbus_request_addr() can be modified to return VMBUS_RQST_ERROR if the ID is 0. This change solves the issues in hv_netvsc (and makes the handling of messages with transaction ID of 0 consistent with the semantics "the ID is not contained in the requestor/invalid ID").
vmbus_next_request_id(), vmbus_request_addr() should still reserve the ID of 0 for Hyper-V, because Hyper-V will "ignore" (not respond to) VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED packets/requests with transaction ID of 0 from the guest.
--- drivers/hv/channel.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/hv/channel.c +4 -2
@@ -1245,7 +1245,9 @@ u64 vmbus_next_request_id(struct vmbus_channel *channel, u64 rqst_addr)/* * Cannot return an ID of 0, which is reserved for an unsolicited -* message from Hyper-V. +* message from Hyper-V; Hyper-V does not acknowledge (respond to) +* VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED requests with ID of +* 0 sent by the guest. */ return current_id +1 ; }
@@ -1270,7 +1272,7 @@ u64 vmbus_request_addr(struct vmbus_channel *channel, u64 trans_id)/* Hyper-V can send an unsolicited message with ID of 0 */ if (!trans_id) -return trans_id; +return VMBUS_RQST_ERROR ;spin_lock_irqsave (&rqstor->req_lock, flags);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 493/772 powerpc/fadump: fix PT_LOAD segment for boot memory area
In reply to Greg Kroah-HartmanFrom: Hari Bathini <[email protected]>
[ Upstream commit 15eb77f873255cf9f4d703b63cfbd23c46579654 ]
Boot memory area is setup as separate PT_LOAD segment in the vmcore as it is moved by f/w, on crash, to a destination address provided by the kernel. Having separate PT_LOAD segment helps in handling the different physical address and offset for boot memory area in the vmcore.
Commit ced1bf52f477 ("powerpc/fadump: merge adjacent memory ranges to reduce PT_LOAD segements") inadvertly broke this pre-condition for cases where some of the first kernel memory is available adjacent to boot memory area. This scenario is rare but possible when memory for fadump could not be reserved adjacent to boot memory area owing to memory hole or such. Reading memory from a vmcore exported in such scenario provides incorrect data. Fix it by ensuring no other region is folded into boot memory area.
--- arch/powerpc/kernel/fadump.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/powerpc/kernel/fadump.c +6 -2
@@ -861,7 +861,6 @@ static int fadump_alloc_mem_ranges(struct fadump_mrange_info *mrange_info) sizeof(struct fadump_memory_range));return 0 ; } -static inline int fadump_add_mem_range (struct fadump_mrange_info *mrange_info,u64 base,u64 end) {
@@ -880,7 +879,12 @@ static inline int fadump_add_mem_range(struct fadump_mrange_info *mrange_info, start = mem_ranges[mrange_info->mem_range_cnt -1 ].base; size = mem_ranges[mrange_info->mem_range_cnt -1 ].size; -if ((start + size) == base) +/* +* Boot memory area needs separate PT_LOAD segment(s) as it +* is moved to a different location at the time of crash. +* So, fold only if the region is not boot memory area. +*/ +if ((start + size) == base && start >= fw_dump.boot_mem_top) is_adjacent = true; }if (!is_adjacent) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 494/772 mfd: ipaq-micro: Fix error check return value of platform_get_irq()
In reply to Greg Kroah-HartmanFrom: Lv Ruyi <[email protected]>
[ Upstream commit 3b49ae380ce1a3054e0c505dd9a356b82a5b48e8 ]
platform_get_irq() return negative value on failure, so null check of irq is incorrect. Fix it by comparing whether it is less than zero.
--- drivers/mfd/ipaq-micro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mfd/ipaq-micro.c +1 -1
@@ -403,7 +403,7 @@ static int __init micro_probe(struct platform_device *pdev)micro_reset_comm (micro); irq =platform_get_irq (pdev,0 ); -if (!irq) +if (irq <0 )return -EINVAL ; ret = devm_request_irq(&pdev->dev, irq, micro_serial_isr, IRQF_SHARED, "ipaq-micro",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 495/772 scsi: fcoe: Fix Wstringop-overflow warnings in fcoe_wwn_from_mac()
In reply to Greg Kroah-HartmanFrom: Gustavo A. R. Silva <[email protected]>
[ Upstream commit 54db804d5d7d36709d1ce70bde3b9a6c61b290b6 ]
Fix the following Wstringop-overflow warnings when building with GCC-11:
drivers/scsi/fcoe/fcoe.c: In function ‘fcoe_netdev_config’:drivers/scsi/fcoe/fcoe.c:744:32: warning: ‘fcoe_wwn_from_mac’ accessing 32 bytes in a region of size 6 [-Wstringop-overflow=]
744 | wwnn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, 1, 0);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/scsi/fcoe/fcoe.c:744:32: note: referencing argument 1 of type ‘unsigned char *’
In file included from drivers/scsi/fcoe/fcoe.c:36:
./include/scsi/libfcoe.h:252:5: note: in a call to function ‘fcoe_wwn_from_mac’
252 | u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int);
| ^~~~~~~~~~~~~~~~~
drivers/scsi/fcoe/fcoe.c:747:32: warning: ‘fcoe_wwn_from_mac’ accessing 32 bytes in a region of size 6 [-Wstringop-overflow=]
747 | wwpn = fcoe_wwn_from_mac(ctlr->ctl_src_addr,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
748 | 2, 0);
| ~~~~~
drivers/scsi/fcoe/fcoe.c:747:32: note: referencing argument 1 of type ‘unsigned char *’
In file included from drivers/scsi/fcoe/fcoe.c:36:
./include/scsi/libfcoe.h:252:5: note: in a call to function ‘fcoe_wwn_from_mac’
252 | u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int);
| ^~~~~~~~~~~~~~~~~ CC drivers/scsi/bnx2fc/bnx2fc_io.o
In function ‘bnx2fc_net_config’,
inlined from ‘bnx2fc_if_create’ at drivers/scsi/bnx2fc/bnx2fc_fcoe.c:1543:7:drivers/scsi/bnx2fc/bnx2fc_fcoe.c:833:32: warning: ‘fcoe_wwn_from_mac’ accessing 32 bytes in a region of size 6 [-Wstringop-overflow=]
833 | wwnn = fcoe_wwn_from_mac(ctlr->ctl_src_addr,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
834 | 1, 0);
| ~~~~~
drivers/scsi/bnx2fc/bnx2fc_fcoe.c: In function ‘bnx2fc_if_create’:
drivers/scsi/bnx2fc/bnx2fc_fcoe.c:833:32: note: referencing argument 1 of type ‘unsigned char *’
In file included from drivers/scsi/bnx2fc/bnx2fc.h:53,
from drivers/scsi/bnx2fc/bnx2fc_fcoe.c:17:
./include/scsi/libfcoe.h:252:5: note: in a call to function ‘fcoe_wwn_from_mac’
252 | u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int);
| ^~~~~~~~~~~~~~~~~
In function ‘bnx2fc_net_config’,
inlined from ‘bnx2fc_if_create’ at drivers/scsi/bnx2fc/bnx2fc_fcoe.c:1543:7:
drivers/scsi/bnx2fc/bnx2fc_fcoe.c:839:32: warning: ‘fcoe_wwn_from_mac’ accessing 32 bytes in a region of size 6 [-Wstringop-overflow=]
839 | wwpn = fcoe_wwn_from_mac(ctlr->ctl_src_addr,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
840 | 2, 0);
| ~~~~~
drivers/scsi/bnx2fc/bnx2fc_fcoe.c: In function ‘bnx2fc_if_create’:
drivers/scsi/bnx2fc/bnx2fc_fcoe.c:839:32: note: referencing argument 1 of type ‘unsigned char *’
In file included from drivers/scsi/bnx2fc/bnx2fc.h:53,
from drivers/scsi/bnx2fc/bnx2fc_fcoe.c:17:
./include/scsi/libfcoe.h:252:5: note: in a call to function ‘fcoe_wwn_from_mac’
252 | u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int);
| ^~~~~~~~~~~~~~~~~
drivers/scsi/qedf/qedf_main.c: In function ‘__qedf_probe’:
drivers/scsi/qedf/qedf_main.c:3520:30: warning: ‘fcoe_wwn_from_mac’ accessing 32 bytes in a region of size 6 [-Wstringop-overflow=]
3520 | qedf->wwnn = fcoe_wwn_from_mac(qedf->mac, 1, 0);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~drivers/scsi/qedf/qedf_main.c:3520:30: note: referencing argument 1 of type ‘unsigned char *’ In file included from drivers/scsi/qedf/qedf.h:9,
from drivers/scsi/qedf/qedf_main.c:23:./include/scsi/libfcoe.h:252:5: note: in a call to function ‘fcoe_wwn_from_mac’
252 | u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int);
| ^~~~~~~~~~~~~~~~~
drivers/scsi/qedf/qedf_main.c:3521:30: warning: ‘fcoe_wwn_from_mac’ accessing 32 bytes in a region of size 6 [-Wstringop-overflow=]
3521 | qedf->wwpn = fcoe_wwn_from_mac(qedf->mac, 2, 0);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~drivers/scsi/qedf/qedf_main.c:3521:30: note: referencing argument 1 of type ‘unsigned char *’ In file included from drivers/scsi/qedf/qedf.h:9,
from drivers/scsi/qedf/qedf_main.c:23:./include/scsi/libfcoe.h:252:5: note: in a call to function ‘fcoe_wwn_from_mac’
252 | u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int);
| ^~~~~~~~~~~~~~~~~by changing the array size to the correct value of ETH_ALEN in the argument declaration.
Also, fix a couple of checkpatch warnings:
WARNING: function definition argument 'unsigned int' should also have an identifier name
This helps with the ongoing efforts to globally enable -Wstringop-overflow.
--- drivers/scsi/fcoe/fcoe_ctlr.c | 2 +- include/scsi/libfcoe.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-)
drivers/scsi/fcoe/fcoe_ctlr.c +1 -1
@@ -1969,7 +1969,7 @@ EXPORT_SYMBOL(fcoe_ctlr_recv_flogi);* * Returns: u64 fc world wide name */ -u64 fcoe_wwn_from_mac (unsigned char mac[MAX_ADDR_LEN ], +u64 fcoe_wwn_from_mac (unsigned char mac[ETH_ALEN ],unsigned int scheme,unsigned int port) {u64 wwn;
include/scsi/libfcoe.h +2 -1
@@ -249,7 +249,8 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *, struct fc_frame *);/* libfcoe funcs */ -u64 fcoe_wwn_from_mac (unsigned char mac[MAX_ADDR_LEN ],unsigned int ,unsigned int ); +u64 fcoe_wwn_from_mac (unsigned char mac[ETH_ALEN ],unsigned int scheme, +unsigned int port);int fcoe_libfc_config (struct fc_lport *,struct fcoe_ctlr *,const struct libfc_function_template *,int init_fcp);u32 fcoe_fc_crc (struct fc_frame *fp);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 496/772 soc: bcm: Check for NULL return of devm_kzalloc()
In reply to Greg Kroah-HartmanFrom: QintaoShen <[email protected]>
[ Upstream commit b4bd2aafacce48db26b0a213d849818d940556dd ]
As the potential failure of allocation, devm_kzalloc() may return NULL. Then the 'pd->pmb' and the follow lines of code may bring null pointer dereference.
Therefore, it is better to check the return value of devm_kzalloc() to avoid this confusion.
--- drivers/soc/bcm/bcm63xx/bcm-pmb.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/soc/bcm/bcm63xx/bcm-pmb.c +3 -0
@@ -312,6 +312,9 @@ static int bcm_pmb_probe(struct platform_device *pdev)for (e = table; e->name; e++) {struct bcm_pmb_pm_domain *pd =devm_kzalloc (dev,sizeof (*pd),GFP_KERNEL ); +if (!pd) +return -ENOMEM ; + pd->pmb = pmb; pd->data = e; pd->genpd.name = e->name;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 497/772 arm64: dts: ti: k3-am64-mcu: remove incorrect UART base clock rates
In reply to Greg Kroah-HartmanFrom: Matthias Schiffer <[email protected]>
[ Upstream commit 439677d416b17dd39964d5f7d64b742a2e51da5b ]
We found that (at least some versions of) the sci-fw set the base clock rate for UARTs in the MCU domain to 96 MHz instead of the expected 48 MHz, leading to incorrect baud rates when used from Linux.
As the 8250_omap driver will query the actual clock rate from the clk driver when clock-frequency is unset, removing the incorrect property is sufficient to fix the baud rate.
--- arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi | 2 -- 1 file changed, 2 deletions(-)
arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi +0 -2
@@ -10,7 +10,6 @@ compatible = "ti,am64-uart", "ti,am654-uart"; reg = <0x00 0x04a00000 0x00 0x100>; interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>; - clock-frequency = <48000000>; current-speed = <115200>; power-domains = <&k3_pds 149 TI_SCI_PD_EXCLUSIVE>; clocks = <&k3_clks 149 0>;
@@ -21,7 +20,6 @@ compatible = "ti,am64-uart", "ti,am654-uart"; reg = <0x00 0x04a10000 0x00 0x100>; interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>; - clock-frequency = <48000000>; current-speed = <115200>; power-domains = <&k3_pds 160 TI_SCI_PD_EXCLUSIVE>; clocks = <&k3_clks 160 0>;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 498/772 ASoC: sh: rz-ssi: Propagate error codes returned from platform_get_irq_byname()
In reply to Greg Kroah-HartmanFrom: Lad Prabhakar <[email protected]>
[ Upstream commit 91686a3984f34df0ab844cdbaa7e4d9621129f5d ]
Propagate error codes returned from platform_get_irq_byname() instead of returning -ENODEV. platform_get_irq_byname() may return -EPROBE_DEFER, to handle such cases propagate the error codes.
While at it drop the dev_err_probe() messages as platform_get_irq_byname() already does this for us in case of error.
--- sound/soc/sh/rz-ssi.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
sound/soc/sh/rz-ssi.c +3 -6
@@ -983,8 +983,7 @@ static int rz_ssi_probe(struct platform_device *pdev)/* Error Interrupt */ ssi->irq_int =platform_get_irq_byname (pdev,"int_req" );if (ssi->irq_int <0 ) -return dev_err_probe (&pdev->dev, -ENODEV , -"Unable to get SSI int_req IRQ\n" ); +return ssi->irq_int; ret =devm_request_irq (&pdev->dev, ssi->irq_int, &rz_ssi_interrupt,0 ,dev_name (&pdev->dev), ssi);
@@ -996,8 +995,7 @@ static int rz_ssi_probe(struct platform_device *pdev)/* Tx and Rx interrupts (pio only) */ ssi->irq_tx =platform_get_irq_byname (pdev,"dma_tx" );if (ssi->irq_tx <0 ) -return dev_err_probe (&pdev->dev, -ENODEV , -"Unable to get SSI dma_tx IRQ\n" ); +return ssi->irq_tx; ret = devm_request_irq(&pdev->dev, ssi->irq_tx, &rz_ssi_interrupt, 0,
@@ -1008,8 +1006,7 @@ static int rz_ssi_probe(struct platform_device *pdev) ssi->irq_rx =platform_get_irq_byname (pdev,"dma_rx" );if (ssi->irq_rx <0 ) -return dev_err_probe (&pdev->dev, -ENODEV , -"Unable to get SSI dma_rx IRQ\n" ); +return ssi->irq_rx; ret = devm_request_irq(&pdev->dev, ssi->irq_rx, &rz_ssi_interrupt, 0,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 499/772 ASoC: sh: rz-ssi: Release the DMA channels in rz_ssi_probe() error path
In reply to Greg Kroah-HartmanFrom: Lad Prabhakar <[email protected]>
[ Upstream commit 767e6f26204d3f5406630e86b720d01818b8616d ]
DMA channels requested by rz_ssi_dma_request() in rz_ssi_probe() were never released in the error path apart from one place. This patch fixes this issue by calling rz_ssi_release_dma_channels() in the error path.
--- sound/soc/sh/rz-ssi.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
sound/soc/sh/rz-ssi.c +10 -3
@@ -982,14 +982,18 @@ static int rz_ssi_probe(struct platform_device *pdev)/* Error Interrupt */ ssi->irq_int =platform_get_irq_byname (pdev,"int_req" ); -if (ssi->irq_int <0 ) +if (ssi->irq_int <0 ) { +rz_ssi_release_dma_channels (ssi);return ssi->irq_int; + } ret =devm_request_irq (&pdev->dev, ssi->irq_int, &rz_ssi_interrupt,0 ,dev_name (&pdev->dev), ssi); -if (ret <0 ) +if (ret <0 ) { +rz_ssi_release_dma_channels (ssi);return dev_err_probe (&pdev->dev, ret,"irq request error (int_req)\n" ); + }if (!rz_ssi_is_dma_enabled (ssi)) {/* Tx and Rx interrupts (pio only) */
@@ -1017,13 +1021,16 @@ static int rz_ssi_probe(struct platform_device *pdev) } ssi->rstc =devm_reset_control_get_exclusive (&pdev->dev,NULL ); -if (IS_ERR (ssi->rstc)) +if (IS_ERR (ssi->rstc)) { +rz_ssi_release_dma_channels (ssi);return PTR_ERR (ssi->rstc); + }reset_control_deassert (ssi->rstc);pm_runtime_enable (&pdev->dev); ret =pm_runtime_resume_and_get (&pdev->dev);if (ret <0 ) { +rz_ssi_release_dma_channels (ssi);pm_runtime_disable (ssi->dev);reset_control_assert (ssi->rstc);return dev_err_probe (ssi->dev, ret,"pm_runtime_resume_and_get failed\n" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 500/772 firmware: arm_scmi: Fix list protocols enumeration in the base protocol
In reply to Greg Kroah-HartmanFrom: Cristian Marussi <[email protected]>
[ Upstream commit 8009120e0354a67068e920eb10dce532391361d0 ]
While enumerating protocols implemented by the SCMI platform using BASE_DISCOVER_LIST_PROTOCOLS, the number of returned protocols is currently validated in an improper way since the check employs a sum between unsigned integers that could overflow and cause the check itself to be silently bypassed if the returned value 'loop_num_ret' is big enough.
Fix the validation avoiding the addition.
--- drivers/firmware/arm_scmi/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/arm_scmi/base.c +1 -1
@@ -197,7 +197,7 @@ scmi_base_implementation_list_get(const struct scmi_protocol_handle *ph,break ; loop_num_ret =le32_to_cpu (*num_ret); -if (tot_num_ret + loop_num_ret >MAX_PROTOCOLS_IMP ) { +if (loop_num_ret >MAX_PROTOCOLS_IMP - tot_num_ret) {dev_err (dev,"No. of Protocol > MAX_PROTOCOLS_IMP" );break ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 501/772 nvdimm: Fix firmware activation deadlock scenarios
In reply to Greg Kroah-HartmanFrom: Dan Williams <[email protected]>
[ Upstream commit e6829d1bd3c4b58296ee9e412f7ed4d6cb390192 ]
Lockdep reports the following deadlock scenarios for CXL root device power-management, device_prepare(), operations, and device_shutdown() operations for 'nd_region' devices:
Chain exists of: &nvdimm_region_key --> &nvdimm_bus->reconfig_mutex --> system_transition_mutex Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(system_transition_mutex);
lock(&nvdimm_bus->reconfig_mutex);
lock(system_transition_mutex); lock(&nvdimm_region_key);
Chain exists of: &cxl_nvdimm_bridge_key --> acpi_scan_lock --> &cxl_root_key Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&cxl_root_key);
lock(acpi_scan_lock);
lock(&cxl_root_key); lock(&cxl_nvdimm_bridge_key);
These stem from holding nvdimm_bus_lock() over hibernate_quiet_exec() which walks the entire system device topology taking device_lock() along the way. The nvdimm_bus_lock() is protecting against unregistration, multiple simultaneous ops callers, and preventing activate_show() from racing activate_store(). For the first 2, the lock is redundant. Unregistration already flushes all ops users, and sysfs already prevents multiple threads to be active in an ops handler at the same time. For the last userspace should already be waiting for its last activate_store() to complete, and does not need activate_show() to flush the write side, so this lock usage can be deleted in these attributes.
--- drivers/nvdimm/core.c | 9 --------- 1 file changed, 9 deletions(-)
drivers/nvdimm/core.c +0 -9
@@ -368,9 +368,7 @@ static ssize_t capability_show(struct device *dev,if (!nd_desc->fw_ops)return -EOPNOTSUPP ; -nvdimm_bus_lock (dev); cap = nd_desc->fw_ops->capability (nd_desc); -nvdimm_bus_unlock (dev);switch (cap) {case NVDIMM_FWA_CAP_QUIESCE :
@@ -395,10 +393,8 @@ static ssize_t activate_show(struct device *dev,if (!nd_desc->fw_ops)return -EOPNOTSUPP ; -nvdimm_bus_lock (dev); cap = nd_desc->fw_ops->capability (nd_desc); state = nd_desc->fw_ops->activate_state (nd_desc); -nvdimm_bus_unlock (dev);if (cap <NVDIMM_FWA_CAP_QUIESCE )return -EOPNOTSUPP ;
@@ -443,7 +439,6 @@ static ssize_t activate_store(struct device *dev,else return -EINVAL ; -nvdimm_bus_lock (dev); state = nd_desc->fw_ops->activate_state (nd_desc);switch (state) {
@@ -461,7 +456,6 @@ static ssize_t activate_store(struct device *dev,default : rc = -ENXIO ; } -nvdimm_bus_unlock (dev);if (rc ==0 ) rc = len;
@@ -484,10 +478,7 @@ static umode_t nvdimm_bus_firmware_visible(struct kobject *kobj, struct attributif (!nd_desc->fw_ops)return 0 ; -nvdimm_bus_lock (dev); cap = nd_desc->fw_ops->capability (nd_desc); -nvdimm_bus_unlock (dev); -if (cap <NVDIMM_FWA_CAP_QUIESCE )return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 502/772 nvdimm: Allow overwrite in the presence of disabled dimms
In reply to Greg Kroah-HartmanFrom: Dan Williams <[email protected]>
[ Upstream commit bb7bf697fed58eae9d3445944e457ab0de4da54f ]
It is not clear why the original implementation of overwrite support required the dimm driver to be active before overwrite could proceed. In fact that can lead to cases where the kernel retains an invalid cached copy of the labels from before the overwrite. Unfortunately the kernel has not only allowed that case, but enforced it.
Going forward, allow for overwrite to happen while the label area is offline, and follow-on with updates to 'ndctl sanitize-dimm --overwrite' to trigger the label area invalidation by default.
--- drivers/nvdimm/security.c | 5 ----- 1 file changed, 5 deletions(-)
drivers/nvdimm/security.c +0 -5
@@ -379,11 +379,6 @@ static int security_overwrite(struct nvdimm *nvdimm, unsigned int keyid) || !nvdimm->sec.flags)return -EOPNOTSUPP ; -if (dev->driver ==NULL ) { -dev_dbg (dev,"Unable to overwrite while DIMM active.\n" ); -return -EINVAL ; - } - rc =check_security_state (nvdimm);if (rc)return rc;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 503/772 pinctrl: mvebu: Fix irq_of_parse_and_map() return value
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 71bc7cf3be65bab441e03667cf215c557712976c ]
The irq_of_parse_and_map() returns 0 on failure, not a negative ERRNO.
--- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +1 -1
@@ -773,7 +773,7 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,for (i =0 ; i < nr_irq_parent; i++) {int irq =irq_of_parse_and_map (np, i); -if (irq <0 ) +if (!irq)continue ; girq->parents[i] = irq; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 504/772 crypto: ccp - Fix the INIT_EX data file open failure
In reply to Greg Kroah-HartmanFrom: Jacky Li <[email protected]>
[ Upstream commit 05def5cacfa0bd5ba380116046747da07ff5bd78 ]
There are 2 common cases when INIT_EX data file might not be opened successfully and fail the sev initialization:
1. In user namespaces, normal user tasks (e.g. VMM) can change their current->fs->root to point to arbitrary directories. While init_ex_path is provided as a module param related to root file system. Solution: use the root directory of init_task to avoid accessing the wrong file.
2. Normal user tasks (e.g. VMM) don't have the privilege to access the INIT_EX data file. Solution: open the file as root and restore permissions immediately.
--- drivers/crypto/ccp/sev-dev.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-)
drivers/crypto/ccp/sev-dev.c +28 -2
@@ -23,6 +23,7 @@#include <linux/gfp.h> #include <linux/cpufeature.h> #include <linux/fs.h> +#include <linux/fs_struct.h> #include <asm/smp.h>
@@ -170,6 +171,31 @@ static void *sev_fw_alloc(unsigned long len)return page_address (page); } +static struct file *open_file_as_root (const char *filename,int flags,umode_t mode) +{ +struct file *fp; +struct path root; +struct cred *cred; +const struct cred *old_cred; + +task_lock (&init_task); +get_fs_root (init_task.fs, &root); +task_unlock (&init_task); + + cred =prepare_creds (); +if (!cred) +return ERR_PTR (-ENOMEM ); + cred->fsuid =GLOBAL_ROOT_UID ; + old_cred =override_creds (cred); + + fp =file_open_root (&root, filename, flags, mode); +path_put (&root); + +revert_creds (old_cred); + +return fp; +} +static int sev_read_init_ex_file (void ) {struct sev_device *sev = psp_master->sev_data;
@@ -181,7 +207,7 @@ static int sev_read_init_ex_file(void)if (!sev_init_ex_buffer)return -EOPNOTSUPP ; - fp =filp_open (init_ex_path,O_RDONLY ,0 ); + fp =open_file_as_root (init_ex_path,O_RDONLY ,0 );if (IS_ERR (fp)) {int ret =PTR_ERR (fp);
@@ -217,7 +243,7 @@ static void sev_write_init_ex_file(void)if (!sev_init_ex_buffer)return ; - fp =filp_open (init_ex_path,O_CREAT |O_WRONLY ,0600 ); + fp =open_file_as_root (init_ex_path,O_CREAT |O_WRONLY ,0600 );if (IS_ERR (fp)) { dev_err(sev->dev, "SEV: could not open file for write, error %ld\n",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 505/772 drivers/base/node.c: fix compaction sysfs file leak
In reply to Greg Kroah-HartmanFrom: Miaohe Lin <[email protected]>
[ Upstream commit da63dc84befaa9e6079a0bc363ff0eaa975f9073 ]
Compaction sysfs file is created via compaction_register_node in register_node. But we forgot to remove it in unregister_node. Thus compaction sysfs file is leaked. Using compaction_unregister_node to fix this issue.
--- drivers/base/node.c | 1 + 1 file changed, 1 insertion(+)
drivers/base/node.c +1 -0
@@ -682,6 +682,7 @@ static int register_node(struct node *node, int num)*/ void unregister_node (struct node *node) { +compaction_unregister_node (node);hugetlb_unregister_node (node);/* no-op, if memoryless node */ node_remove_accesses (node);node_remove_caches (node);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 506/772 dax: fix cache flush on PMD-mapped pages
In reply to Greg Kroah-HartmanFrom: Muchun Song <[email protected]>
[ Upstream commit e583b5c472bd23d450e06f148dc1f37be74f7666 ]
The flush_cache_page() only remove a PAGE_SIZE sized range from the cache. However, it does not cover the full pages in a THP except a head page. Replace it with flush_cache_range() to fix this issue. This is just a documentation issue with the respect to properly documenting the expected usage of cache flushing before modifying the pmd. However, in practice this is not a problem due to the fact that DAX is not available on architectures with virtually indexed caches per:
commit d92576f1167c ("dax: does not work correctly with virtual aliasing caches")
--- fs/dax.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/dax.c +2 -1
@@ -846,7 +846,8 @@ static void dax_entry_mkclean(struct address_space *mapping, pgoff_t index,if (!pmd_dirty (*pmdp) && !pmd_write (*pmdp)) goto unlock_pmd; -flush_cache_page (vma, address, pfn); +flush_cache_range (vma, address, + address +HPAGE_PMD_SIZE ); pmd =pmdp_invalidate (vma, address, pmdp); pmd =pmd_wrprotect (pmd); pmd =pmd_mkclean (pmd);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 507/772 drivers/base/memory: fix an unlikely reference counting issue in __add_memory_block()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit f47f758cff59c68015d6b9b9c077110df7c2c828 ]
__add_memory_block() calls both put_device() and device_unregister() when storing the memory block into the xarray. This is incorrect because xarray doesn't take an additional reference and device_unregister() already calls put_device().
Triggering the issue looks really unlikely and its only effect should be to log a spurious warning about a ref counted issue.
--- drivers/base/memory.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/base/memory.c +2 -3
@@ -634,10 +634,9 @@ int register_memory(struct memory_block *memory) } ret =xa_err (xa_store (&memory_blocks, memory->dev.id, memory,GFP_KERNEL )); -if (ret) { -put_device (&memory->dev); +if (ret)device_unregister (&memory->dev); - } +return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 508/772 firmware: arm_ffa: Fix uuid parameter to ffa_partition_probe
In reply to Greg Kroah-HartmanFrom: Sudeep Holla <[email protected]>
[ Upstream commit f3c45c045e25ed52461829d2ce07954f72b6ad15 ]
While we pass uuid_null intentionally to ffa_partition_probe in ffa_setup_partitions to get the count of the partitions, it must not be uuid_null in ffa_partition_info_get which is used by the ffa_drivers to fetch the specific partition info passing the UUID of the partition.
Fix ffa_partition_info_get by passing the received uuid down to ffa_partition_probe so that the correct partition information is fetched.
--- drivers/firmware/arm_ffa/driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/arm_ffa/driver.c +1 -1
@@ -582,7 +582,7 @@ static int ffa_partition_info_get(const char *uuid_str,return -ENODEV ; } - count =ffa_partition_probe (&uuid_null, &pbuf); + count =ffa_partition_probe (&uuid, &pbuf);if (count <=0 )return -ENOENT ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 509/772 firmware: arm_ffa: Remove incorrect assignment of driver_data
In reply to Greg Kroah-HartmanFrom: Sudeep Holla <[email protected]>
[ Upstream commit 00512d2930b338fdd42bd90bbd1793fe212c2d31 ]
The ffa core driver currently assigns its own driver information to individual ffa device driver_data which is wrong. Firstly, it leaks this core driver information to individual ffa_device and hence to ffa_driver. Secondly the ffa_device driver_data is for use by individual ffa_driver and not for this core driver managing all those devices.
--- drivers/firmware/arm_ffa/driver.c | 2 -- 1 file changed, 2 deletions(-)
drivers/firmware/arm_ffa/driver.c +0 -2
@@ -688,8 +688,6 @@ static void ffa_setup_partitions(void) __func__, tpbuf->id);continue ; } - -ffa_dev_set_drvdata (ffa_dev, drv_info); }kfree (pbuf); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 510/772 ocfs2: fix mounting crash if journal is not alloced
In reply to Greg Kroah-HartmanFrom: Heming Zhao via Ocfs2-devel <[email protected]>
[ Upstream commit bb20b31dee1a6c329c2f721fbe21c51945cdfc29 ]
Patch series "rewrite error handling during mounting stage".
This patch (of 5):
After commit da5e7c87827e8 ("ocfs2: cleanup journal init and shutdown"), journal init later than before, it makes NULL pointer access in free routine.
Crash flow:
ocfs2_fill_super
+ ocfs2_mount_volume
| + ocfs2_dlm_init //fail & return, osb->journal is NULL.
| + ...
| + ocfs2_check_volume //no chance to init osb->journal
|
+ ...
+ ocfs2_dismount_volume
ocfs2_release_system_inodes
...
evict
...
ocfs2_clear_inode
ocfs2_checkpoint_inode
ocfs2_ci_fully_checkpointed
time_after(journal->j_trans_id, ci->ci_last_trans)
+ journal is empty, crash!For fixing, there are three solutions:
1> Partly revert commit da5e7c87827e8
For avoiding kernel crash, this make sense for us. We only concerned whether there has any non-system inode access before dlm init. The answer is NO. And all journal replay/recovery handling happen after dlm & journal init done. So this method is not graceful but workable.
2> Add osb->journal check in free inode routine (eg ocfs2_clear_inode)
The fix code is special for mounting phase, but it will continue working after mounting stage. In another word, this method adds useless code in normal inode free flow.
3> Do directly free inode in mounting phase
This method is brutal/complex and may introduce unsafe code, currently maintainer didn't like.
At last, we chose method <1> and did partly reverted job. We reverted journal init codes, and kept cleanup codes flow.
--- fs/ocfs2/inode.c | 4 ++-- fs/ocfs2/journal.c | 33 +++++++++++++++++++++++---------- fs/ocfs2/journal.h | 2 ++ fs/ocfs2/super.c | 15 +++++++++++++++ 4 files changed, 42 insertions(+), 12 deletions(-)
fs/ocfs2/inode.c +2 -2
@@ -125,6 +125,7 @@ struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags,struct inode *inode =NULL ;struct super_block *sb = osb->sb;struct ocfs2_find_inode_args args; +journal_t *journal = osb->journal->j_journal;trace_ocfs2_iget_begin ((unsigned long long )blkno, flags, sysfile_type);
@@ -171,11 +172,10 @@ struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags,* part of the transaction - the inode could have been reclaimed and * now it is reread from disk. */ -if (osb->journal) { +if (journal) {transaction_t *transaction;tid_t tid;struct ocfs2_inode_info *oi =OCFS2_I (inode); -journal_t *journal = osb->journal->j_journal;read_lock (&journal->j_state_lock);if (journal->j_running_transaction)
fs/ocfs2/journal.c +23 -10
@@ -810,22 +810,20 @@ void ocfs2_set_journal_params(struct ocfs2_super *osb)write_unlock (&journal->j_state_lock); } -int ocfs2_journal_init (struct ocfs2_super *osb,int *dirty) +/* +* alloc & initialize skeleton for journal structure. +* ocfs2_journal_init() will make fs have journal ability. +*/ +int ocfs2_journal_alloc (struct ocfs2_super *osb) { -int status =-1 ; -struct inode *inode =NULL ;/* the journal inode */ -journal_t *j_journal =NULL ; -struct ocfs2_journal *journal =NULL ; -struct ocfs2_dinode *di =NULL ; -struct buffer_head *bh =NULL ; -int inode_lock =0 ; +int status =0 ; +struct ocfs2_journal *journal; -/* initialize our journal structure */ journal =kzalloc (sizeof (struct ocfs2_journal ),GFP_KERNEL );if (!journal) {mlog (ML_ERROR ,"unable to alloc journal\n" ); status = -ENOMEM ; - goto done; + goto bail; } osb->journal = journal; journal->j_osb = osb;
@@ -839,6 +837,21 @@ int ocfs2_journal_init(struct ocfs2_super *osb, int *dirty)INIT_WORK (&journal->j_recovery_work, ocfs2_complete_recovery); journal->j_state =OCFS2_JOURNAL_FREE ; +bail: +return status; +} + +int ocfs2_journal_init (struct ocfs2_super *osb,int *dirty) +{ +int status =-1 ; +struct inode *inode =NULL ;/* the journal inode */ +journal_t *j_journal =NULL ; +struct ocfs2_journal *journal = osb->journal; +struct ocfs2_dinode *di =NULL ; +struct buffer_head *bh =NULL ; +int inode_lock =0 ; + +BUG_ON (!journal);/* already have the inode for our journal */ inode =ocfs2_get_system_file_inode (osb,JOURNAL_SYSTEM_INODE , osb->slot_num);
fs/ocfs2/journal.h +2 -0
@@ -154,6 +154,7 @@ int ocfs2_compute_replay_slots(struct ocfs2_super *osb);* Journal Control: * Initialize, Load, Shutdown, Wipe a journal. * +* ocfs2_journal_alloc - Initialize skeleton for journal structure. * ocfs2_journal_init - Initialize journal structures in the OSB. * ocfs2_journal_load - Load the given journal off disk. Replay it if * there's transactions still in there.
@@ -167,6 +168,7 @@ int ocfs2_compute_replay_slots(struct ocfs2_super *osb);* ocfs2_start_checkpoint - Kick the commit thread to do a checkpoint. */ void ocfs2_set_journal_params (struct ocfs2_super *osb); +int ocfs2_journal_alloc (struct ocfs2_super *osb);int ocfs2_journal_init (struct ocfs2_super *osb,int *dirty);void ocfs2_journal_shutdown (struct ocfs2_super *osb); int ocfs2_journal_wipe(struct ocfs2_journal *journal,
fs/ocfs2/super.c +15 -0
@@ -2195,6 +2195,15 @@ static int ocfs2_initialize_super(struct super_block *sb,get_random_bytes (&osb->s_next_generation,sizeof (u32)); +/* +* FIXME +* This should be done in ocfs2_journal_init(), but any inode +* writes back operation will cause the filesystem to crash. +*/ + status =ocfs2_journal_alloc (osb); +if (status <0 ) + goto bail; +INIT_WORK (&osb->dquot_drop_work, ocfs2_drop_dquot_refs);init_llist_head (&osb->dquot_drop_list);
@@ -2483,6 +2492,12 @@ static void ocfs2_delete_osb(struct ocfs2_super *osb)kfree (osb->osb_orphan_wipes);kfree (osb->slot_recovery_generations); +/* FIXME +* This belongs in journal shutdown, but because we have to +* allocate osb->journal at the middle of ocfs2_initialize_super(), +* we free it here. +*/ +kfree (osb->journal);kfree (osb->local_alloc_copy);kfree (osb->uuid_str);kfree (osb->vol_label);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 511/772 list: fix a data-race around ep->rdllist
In reply to Greg Kroah-HartmanFrom: Kuniyuki Iwashima <[email protected]>
[ Upstream commit d679ae94fdd5d3ab00c35078f5af5f37e068b03d ]
ep_poll() first calls ep_events_available() with no lock held and checks if ep->rdllist is empty by list_empty_careful(), which reads rdllist->prev. Thus all accesses to it need some protection to avoid store/load-tearing.
Note INIT_LIST_HEAD_RCU() already has the annotation for both prev and next.
Commit bf3b9f6372c4 ("epoll: Add busy poll support to epoll with socket fds.") added the first lockless ep_events_available(), and commit c5a282e9635e ("fs/epoll: reduce the scope of wq lock in epoll_wait()") made some ep_events_available() calls lockless and added single call under a lock, finally commit e59d3c64cba6 ("epoll: eliminate unnecessary lock for zero timeout") made the last ep_events_available() lockless.
BUG: KCSAN: data-race in do_epoll_wait / do_epoll_wait
write to 0xffff88810480c7d8 of 8 bytes by task 1802 on cpu 0:
INIT_LIST_HEAD include/linux/list.h:38 [inline] list_splice_init include/linux/list.h:492 [inline] ep_start_scan fs/eventpoll.c:622 [inline] ep_send_events fs/eventpoll.c:1656 [inline] ep_poll fs/eventpoll.c:1806 [inline] do_epoll_wait+0x4eb/0xf40 fs/eventpoll.c:2234 do_epoll_pwait fs/eventpoll.c:2268 [inline] __do_sys_epoll_pwait fs/eventpoll.c:2281 [inline] __se_sys_epoll_pwait+0x12b/0x240 fs/eventpoll.c:2275 __x64_sys_epoll_pwait+0x74/0x80 fs/eventpoll.c:2275 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x44/0xd0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae
read to 0xffff88810480c7d8 of 8 bytes by task 1799 on cpu 1:
list_empty_careful include/linux/list.h:329 [inline] ep_events_available fs/eventpoll.c:381 [inline] ep_poll fs/eventpoll.c:1797 [inline] do_epoll_wait+0x279/0xf40 fs/eventpoll.c:2234 do_epoll_pwait fs/eventpoll.c:2268 [inline] __do_sys_epoll_pwait fs/eventpoll.c:2281 [inline] __se_sys_epoll_pwait+0x12b/0x240 fs/eventpoll.c:2275 __x64_sys_epoll_pwait+0x74/0x80 fs/eventpoll.c:2275 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x44/0xd0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae
value changed: 0xffff88810480c7d0 -> 0xffff888103c15098
Reported by Kernel Concurrency Sanitizer on:
CPU: 1 PID: 1799 Comm: syz-fuzzer Tainted: G W 5.17.0-rc7-syzkaller-dirty #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
--- include/linux/list.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
include/linux/list.h +3 -3
@@ -35,7 +35,7 @@static inline void INIT_LIST_HEAD (struct list_head *list) {WRITE_ONCE (list->next, list); - list->prev = list; +WRITE_ONCE (list->prev, list); }#ifdef CONFIG_DEBUG_LIST
@@ -306,7 +306,7 @@ static inline int list_empty(const struct list_head *head)static inline void list_del_init_careful (struct list_head *entry) {__list_del_entry (entry); - entry->prev = entry; +WRITE_ONCE (entry->prev, entry);smp_store_release (&entry->next, entry); }
@@ -326,7 +326,7 @@ static inline void list_del_init_careful(struct list_head *entry)static inline int list_empty_careful (const struct list_head *head) {struct list_head *next =smp_load_acquire (&head->next); -return list_is_head (next, head) && (next == head->prev); +return list_is_head (next, head) && (next ==READ_ONCE (head->prev)); }/**
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 512/772 drm/msm/dpu: fix error check return value of irq_of_parse_and_map()
In reply to Greg Kroah-HartmanFrom: Lv Ruyi <[email protected]>
[ Upstream commit 95093595914c17f32e1d6228b4db06fab8cebd35 ]
The irq_of_parse_and_map() function returns 0 on failure, and does not return a negative value anyhow, so never enter this conditional branch.
Patchwork: https://patchwork.freedesktop.org/patch/483291/
--- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +1 -1
@@ -1262,7 +1262,7 @@ static int dpu_bind(struct device *dev, struct device *master, void *data) priv->kms = &dpu_kms->base; -return ret; +return 0 ; }static void dpu_unbind (struct device *dev,struct device *master,void *data)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 513/772 powerpc/8xx: export cpm_setbrg for modules
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
[ Upstream commit 22f8e625ebabd7ed3185b82b44b4f12fc0402113 ]
Fix missing export for a loadable module build:
ERROR: modpost: "cpm_setbrg" [drivers/tty/serial/cpm_uart/cpm_uart.ko] undefined!
--- arch/powerpc/platforms/8xx/cpm1.c | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/platforms/8xx/cpm1.c +1 -0
@@ -280,6 +280,7 @@ cpm_setbrg(uint brg, uint rate)out_be32 (bp, (((BRG_UART_CLK_DIV16 / rate) -1 ) <<1 ) |CPM_BRG_EN |CPM_BRG_DIV16 ); } +EXPORT_SYMBOL (cpm_setbrg);struct cpm_ioport16 {__be16 dir, par, odr_sor, dat, intr;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 514/772 pinctrl: renesas: r8a779a0: Fix GPIO function on I2C-capable pins
In reply to Greg Kroah-HartmanFrom: Geert Uytterhoeven <[email protected]>
[ Upstream commit 4288caed9a6319b766dc0adf605c7b401180db34 ]
Unlike on R-Car Gen3 SoCs, setting a bit to zero in a GPIO / Peripheral Function Select Register (GPSRn) on R-Car V3U is not always sufficient to configure a pin for GPIO. For I2C-capable pins, the I2C function must also be explicitly disabled in the corresponding Module Select Register (MODSELn).
Add the missing FN_SEL_I2Ci_0 function enums to the pinmux_data[] array by temporarily overriding the GP_2_j_FN function enum to expand to two
enums: the original GP_2_j_FN enum to configure the GSPR register bits, and the missing FN_SEL_I2Ci_0 enum to configure the MODSEL register bits.
--- drivers/pinctrl/renesas/pfc-r8a779a0.c | 29 ++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
drivers/pinctrl/renesas/pfc-r8a779a0.c +29 -0
@@ -629,7 +629,36 @@ enum { };static const u16 pinmux_data[] = { +/* Using GP_2_[2-15] requires disabling I2C in MOD_SEL2 */ +#define GP_2_2_FN GP_2_2_FN, FN_SEL_I2C0_0 +#define GP_2_3_FN GP_2_3_FN, FN_SEL_I2C0_0 +#define GP_2_4_FN GP_2_4_FN, FN_SEL_I2C1_0 +#define GP_2_5_FN GP_2_5_FN, FN_SEL_I2C1_0 +#define GP_2_6_FN GP_2_6_FN, FN_SEL_I2C2_0 +#define GP_2_7_FN GP_2_7_FN, FN_SEL_I2C2_0 +#define GP_2_8_FN GP_2_8_FN, FN_SEL_I2C3_0 +#define GP_2_9_FN GP_2_9_FN, FN_SEL_I2C3_0 +#define GP_2_10_FN GP_2_10_FN, FN_SEL_I2C4_0 +#define GP_2_11_FN GP_2_11_FN, FN_SEL_I2C4_0 +#define GP_2_12_FN GP_2_12_FN, FN_SEL_I2C5_0 +#define GP_2_13_FN GP_2_13_FN, FN_SEL_I2C5_0 +#define GP_2_14_FN GP_2_14_FN, FN_SEL_I2C6_0 +#define GP_2_15_FN GP_2_15_FN, FN_SEL_I2C6_0PINMUX_DATA_GP_ALL (), +#undef GP_2_2_FN +#undef GP_2_3_FN +#undef GP_2_4_FN +#undef GP_2_5_FN +#undef GP_2_6_FN +#undef GP_2_7_FN +#undef GP_2_8_FN +#undef GP_2_9_FN +#undef GP_2_10_FN +#undef GP_2_11_FN +#undef GP_2_12_FN +#undef GP_2_13_FN +#undef GP_2_14_FN +#undef GP_2_15_FNPINMUX_SINGLE (MMC_D7 ),PINMUX_SINGLE (MMC_D6 ),
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 515/772 pinctrl: renesas: core: Fix possible null-ptr-deref in sh_pfc_map_resources()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 5376e3d904532e657fd7ca1a9b1ff3d351527b90 ]
It will cause null-ptr-deref when using 'res', if platform_get_resource() returns NULL, so move using 'res' after devm_ioremap_resource() that will check it to avoid null-ptr-deref.
And use devm_platform_get_and_ioremap_resource() to simplify code.
--- drivers/pinctrl/renesas/core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/pinctrl/renesas/core.c +3 -4
@@ -71,12 +71,11 @@ static int sh_pfc_map_resources(struct sh_pfc *pfc,/* Fill them. */ for (i =0 ; i < num_windows; i++) { - res =platform_get_resource (pdev,IORESOURCE_MEM , i); - windows->phys = res->start; - windows->size =resource_size (res); - windows->virt =devm_ioremap_resource (pfc->dev, res); + windows->virt =devm_platform_get_and_ioremap_resource (pdev, i, &res);if (IS_ERR (windows->virt))return -ENOMEM ; + windows->phys = res->start; + windows->size =resource_size (res); windows++; }for (i =0 ; i < num_irqs; i++)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 516/772 powerpc/idle: Fix return value of __setup() handler
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
[ Upstream commit b793a01000122d2bd133ba451a76cc135b5e162c ]
__setup() handlers should return 1 to obsolete_checksetup() in init/main.c to indicate that the boot option has been handled.
A return of 0 causes the boot option/value to be listed as an Unknown kernel parameter and added to init's (limited) argument or environment strings.
Also, error return codes don't mean anything to obsolete_checksetup() -- only non-zero (usually 1) or zero. So return 1 from powersave_off().
--- arch/powerpc/kernel/idle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kernel/idle.c +1 -1
@@ -37,7 +37,7 @@ static int __init powersave_off(char *arg) { ppc_md.power_save =NULL ; cpuidle_disable =IDLE_POWERSAVE_OFF ; -return 0 ; +return 1 ; }__setup ("powersave=off" , powersave_off);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 517/772 powerpc/4xx/cpm: Fix return value of __setup() handler
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
[ Upstream commit 5bb99fd4090fe1acfdb90a97993fcda7f8f5a3d6 ]
__setup() handlers should return 1 to obsolete_checksetup() in init/main.c to indicate that the boot option has been handled.
A return of 0 causes the boot option/value to be listed as an Unknown kernel parameter and added to init's (limited) argument or environment strings.
Also, error return codes don't mean anything to obsolete_checksetup() -- only non-zero (usually 1) or zero. So return 1 from cpm_powersave_off().
--- arch/powerpc/platforms/4xx/cpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/platforms/4xx/cpm.c +1 -1
@@ -327,6 +327,6 @@ late_initcall(cpm_init);static int __init cpm_powersave_off (char *arg) { cpm.powersave_off =1 ; -return 0 ; +return 1 ; }__setup ("powersave=off" , cpm_powersave_off);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 518/772 RDMA/hns: Add the detection for CMDQ status in the device initialization process
In reply to Greg Kroah-HartmanFrom: Yangyang Li <[email protected]>
[ Upstream commit e8ea058edc2b225a68b307057a65599625daaebf ]
CMDQ may fail during HNS ROCEE initialization. The following is the log when the execution fails:
hns3 0000:bd:00.2: In reset process RoCE client reinit. hns3 0000:bd:00.2: CMDQ move tail from 840 to 839 hns3 0000:bd:00.2 hns_2: failed to set gid, ret = -11! hns3 0000:bd:00.2: CMDQ move tail from 840 to 839 <...>
hns3 0000:bd:00.2: CMDQ move tail from 840 to 839 hns3 0000:bd:00.2: CMDQ move tail from 840 to 0 hns3 0000:bd:00.2: [cmd]token 14e mailbox 20 timeout. hns3 0000:bd:00.2 hns_2: set HEM step 0 failed! hns3 0000:bd:00.2 hns_2: set HEM address to HW failed! hns3 0000:bd:00.2 hns_2: failed to alloc mtpt, ret = -16. infiniband hns_2: Couldn't create ib_mad PD infiniband hns_2: Couldn't open port 1
hns3 0000:bd:00.2: Reset done, RoCE client reinit finished.
However, even if ib_mad client registration failed, ib_register_device() still returns success to the driver.
In the device initialization process, CMDQ execution fails because HW/FW is abnormal. Therefore, if CMDQ fails, the initialization function should set CMDQ to a fatal error state and return a failure to the caller.
--- drivers/infiniband/hw/hns/hns_roce_device.h | 6 ++++++ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+)
drivers/infiniband/hw/hns/hns_roce_device.h +6 -0
@@ -535,6 +535,11 @@ struct hns_roce_cmd_context {u16 busy; }; +enum hns_roce_cmdq_state { +HNS_ROCE_CMDQ_STATE_NORMAL , +HNS_ROCE_CMDQ_STATE_FATAL_ERR , +}; +struct hns_roce_cmdq {struct dma_pool *pool;struct semaphore poll_sem;
@@ -554,6 +559,7 @@ struct hns_roce_cmdq {* close device, switch into poll mode(non event mode) */ u8 use_events; +enum hns_roce_cmdq_state state; };struct hns_roce_cmd_mailbox {
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +21 -0
@@ -1265,6 +1265,16 @@ static int hns_roce_cmq_csq_done(struct hns_roce_dev *hr_dev)return tail == priv->cmq.csq.head; } +static void update_cmdq_status (struct hns_roce_dev *hr_dev) +{ +struct hns_roce_v2_priv *priv = hr_dev->priv; +struct hnae3_handle *handle = priv->handle; + +if (handle->rinfo.reset_state ==HNS_ROCE_STATE_RST_INIT || + handle->rinfo.instance_state ==HNS_ROCE_STATE_INIT ) + hr_dev->cmd.state =HNS_ROCE_CMDQ_STATE_FATAL_ERR ; +} +static int __hns_roce_cmq_send (struct hns_roce_dev *hr_dev,struct hns_roce_cmq_desc *desc,int num) {
@@ -1318,6 +1328,8 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev, csq->head, tail); csq->head = tail; +update_cmdq_status (hr_dev); + ret = -EAGAIN ; }
@@ -1332,6 +1344,9 @@ static int hns_roce_cmq_send(struct hns_roce_dev *hr_dev,bool busy;int ret; +if (hr_dev->cmd.state ==HNS_ROCE_CMDQ_STATE_FATAL_ERR ) +return -EIO ; +if (!v2_chk_mbox_is_avail (hr_dev, &busy))return busy ? -EBUSY :0 ;
@@ -1528,6 +1543,9 @@ static void hns_roce_function_clear(struct hns_roce_dev *hr_dev) {int i; +if (hr_dev->cmd.state ==HNS_ROCE_CMDQ_STATE_FATAL_ERR ) +return ; +for (i = hr_dev->func_num -1 ; i >=0 ; i--) {__hns_roce_function_clear (hr_dev, i);if (i !=0 )
@@ -2812,6 +2830,9 @@ static int v2_wait_mbox_complete(struct hns_roce_dev *hr_dev, u32 timeout, mb_st = (struct hns_roce_mbox_status *)desc.data; end =msecs_to_jiffies (timeout) + jiffies;while (v2_chk_mbox_is_avail (hr_dev, &busy)) { +if (hr_dev->cmd.state ==HNS_ROCE_CMDQ_STATE_FATAL_ERR ) +return -EIO ; + status =0 ;hns_roce_cmq_setup_basic_desc (&desc,HNS_ROCE_OPC_QUERY_MB_ST , true);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 519/772 arm64: dts: marvell: espressobin-ultra: fix SPI-NOR config
In reply to Greg Kroah-HartmanFrom: Robert Marko <[email protected]>
[ Upstream commit 5202f4c3816b42e989f9cad49a73c7e88fba89f4 ]
SPI config for the SPI-NOR is incorrect and completely breaking reading/writing to the onboard SPI-NOR.
SPI-NOR is connected in the single(x1) IO mode and not in the quad (x4) mode.
Also, there is no need to override the max frequency from the DTSI as the mx25u3235f that is used supports 104Mhz.
--- arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts | 4 ---- 1 file changed, 4 deletions(-)
arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts +0 -4
@@ -71,10 +71,6 @@ &spi0 { flash@0 { - spi-max-frequency = <108000000>; - spi-rx-bus-width = <4>; - spi-tx-bus-width = <4>; - partitions { compatible = "fixed-partitions"; #address-cells = <1>;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 520/772 arm64: dts: marvell: espressobin-ultra: enable front USB3 port
In reply to Greg Kroah-HartmanFrom: Robert Marko <[email protected]>
[ Upstream commit eacec7ebc16cf5d2f6a6c7cf5d57156da2c3e98f ]
Espressobin Ultra has a front panel USB3.0 Type-A port which works just fine so enable it.
I dont see a reason why it was disabled in the first place anyway.
--- arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts | 1 - 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts +0 -1
@@ -108,7 +108,6 @@ &usb3 { usb-phy = <&usb3_phy>; - status = "disabled"; }; &mdio {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 521/772 ASoC: atmel-pdmic: Remove endianness flag on pdmic component
In reply to Greg Kroah-HartmanFrom: Charles Keepax <[email protected]>
[ Upstream commit 52857c3baa0e5ddeba7b2c84e56bb71c9674e048 ]
The endianness flag should have been removed when the driver was ported across from having both a CODEC and CPU side component, to just having a CPU component and using the dummy for the CODEC. The endianness flag is used to indicate that the device is completely ambivalent to the endianness of the data, typically due to the endianness being lost over the hardware link (ie. the link defines bit ordering). It's usage didn't have any effect when the driver had both a CPU and CODEC component, since the union of those equals the CPU side settings, but now causes the driver to falsely report it supports big endian. Correct this by removing the flag.
--- sound/soc/atmel/atmel-pdmic.c | 1 - 1 file changed, 1 deletion(-)
sound/soc/atmel/atmel-pdmic.c +0 -1
@@ -481,7 +481,6 @@ static const struct snd_soc_component_driver atmel_pdmic_cpu_dai_component = { .num_controls = ARRAY_SIZE(atmel_pdmic_snd_controls), .idle_bias_on = 1, .use_pmdown_time = 1, - .endianness = 1, };/* ASoC sound card */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 522/772 ASoC: atmel-classd: Remove endianness flag on class d component
In reply to Greg Kroah-HartmanFrom: Charles Keepax <[email protected]>
[ Upstream commit 0104d52a6a69b06b0e8167f7c1247e8c76aca070 ]
The endianness flag should have been removed when the driver was ported across from having both a CODEC and CPU side component, to just having a CPU component and using the dummy for the CODEC. The endianness flag is used to indicate that the device is completely ambivalent to the endianness of the data, typically due to the endianness being lost over the hardware link (ie. the link defines bit ordering). It's usage didn't have any effect when the driver had both a CPU and CODEC component, since the union of those equals the CPU side settings, but now causes the driver to falsely report it supports big endian. Correct this by removing the flag.
--- sound/soc/atmel/atmel-classd.c | 1 - 1 file changed, 1 deletion(-)
sound/soc/atmel/atmel-classd.c +0 -1
@@ -458,7 +458,6 @@ static const struct snd_soc_component_driver atmel_classd_cpu_dai_component = { .num_controls = ARRAY_SIZE(atmel_classd_snd_controls), .idle_bias_on = 1, .use_pmdown_time = 1, - .endianness = 1, };/* ASoC sound card */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 523/772 proc: fix dentry/inode overinstantiating under /proc/${pid}/net
In reply to Greg Kroah-HartmanFrom: Alexey Dobriyan <[email protected]>
[ Upstream commit 7055197705709c59b8ab77e6a5c7d46d61edd96e ]
When a process exits, /proc/${pid}, and /proc/${pid}/net dentries are flushed. However some leaf dentries like /proc/${pid}/net/arp_cache aren't. That's because respective PDEs have proc_misc_d_revalidate() hook which returns 1 and leaves dentries/inodes in the LRU.
Force revalidation/lookup on everything under /proc/${pid}/net by inheriting proc_net_dentry_ops.
--- fs/proc/generic.c | 3 +++ fs/proc/proc_net.c | 3 +++ 2 files changed, 6 insertions(+)
fs/proc/generic.c +3 -0
@@ -448,6 +448,9 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,proc_set_user (ent, (*parent)->uid, (*parent)->gid); ent->proc_dops = &proc_misc_dentry_ops; +/* Revalidate everything under /proc/${pid}/net */ +if ((*parent)->proc_dops == &proc_net_dentry_ops) +pde_force_lookup (ent); out:return ent;
fs/proc/proc_net.c +3 -0
@@ -376,6 +376,9 @@ static __net_init int proc_net_ns_init(struct net *net)proc_set_user (netd, uid, gid); +/* Seed dentry revalidation for /proc/${pid}/net */ +pde_force_lookup (netd); + err = -EEXIST ; net_statd =proc_net_mkdir (net,"stat" , netd);if (!net_statd)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 524/772 ipc/mqueue: use get_tree_nodev() in mqueue_get_tree()
In reply to Greg Kroah-HartmanFrom: Waiman Long <[email protected]>
[ Upstream commit d60c4d01a98bc1942dba6e3adc02031f5519f94b ]
When running the stress-ng clone benchmark with multiple testing threads, it was found that there were significant spinlock contention in sget_fc(). The contended spinlock was the sb_lock. It is under heavy contention because the following code in the critcal section of sget_fc():
hlist_for_each_entry(old, &fc->fs_type->fs_supers, s_instances) {
if (test(old, fc))
goto share_extant_sb;
}After testing with added instrumentation code, it was found that the benchmark could generate thousands of ipc namespaces with the corresponding number of entries in the mqueue's fs_supers list where the namespaces are the key for the search. This leads to excessive time in scanning the list for a match.
Looking back at the mqueue calling sequence leading to sget_fc():
mq_init_ns()
=> mq_create_mount()
=> fc_mount()
=> vfs_get_tree()
=> mqueue_get_tree()
=> get_tree_keyed()
=> vfs_get_super()
=> sget_fc()
Currently, mq_init_ns() is the only mqueue function that will indirectly call mqueue_get_tree() with a newly allocated ipc namespace as the key for searching. As a result, there will never be a match with the exising ipc namespaces stored in the mqueue's fs_supers list.
So using get_tree_keyed() to do an existing ipc namespace search is just a waste of time. Instead, we could use get_tree_nodev() to eliminate the useless search. By doing so, we can greatly reduce the sb_lock hold time and avoid the spinlock contention problem in case a large number of ipc namespaces are present.
Of course, if the code is modified in the future to allow mqueue_get_tree() to be called with an existing ipc namespace instead of a new one, we will have to use get_tree_keyed() in this case.
The following stress-ng clone benchmark command was run on a 2-socket 48-core Intel system:
./stress-ng --clone 32 --verbose --oomable --metrics-brief -t 20
The "bogo ops/s" increased from 5948.45 before patch to 9137.06 after patch. This is an increase of 54% in performance.
--- ipc/mqueue.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
ipc/mqueue.c +14 -0
@@ -45,6 +45,7 @@struct mqueue_fs_context {struct ipc_namespace *ipc_ns; +bool newns;/* Set if newly created ipc namespace */ };#define MQUEUE_MAGIC 0x19800202
@@ -427,6 +428,14 @@ static int mqueue_get_tree(struct fs_context *fc) {struct mqueue_fs_context *ctx = fc->fs_private; +/* +* With a newly created ipc namespace, we don't need to do a search +* for an ipc namespace match, but we still need to set s_fs_info. +*/ +if (ctx->newns) { + fc->s_fs_info = ctx->ipc_ns; +return get_tree_nodev (fc, mqueue_fill_super); + }return get_tree_keyed (fc, mqueue_fill_super, ctx->ipc_ns); }
@@ -454,6 +463,10 @@ static int mqueue_init_fs_context(struct fs_context *fc)return 0 ; } +/* +* mq_init_ns() is currently the only caller of mq_create_mount(). +* So the ns parameter is always a newly created ipc namespace. +*/ static struct vfsmount *mq_create_mount (struct ipc_namespace *ns) {struct mqueue_fs_context *ctx;
@@ -465,6 +478,7 @@ static struct vfsmount *mq_create_mount(struct ipc_namespace *ns)return ERR_CAST (fc); ctx = fc->fs_private; + ctx->newns = true;put_ipc_ns (ctx->ipc_ns); ctx->ipc_ns =get_ipc_ns (ns);put_user_ns (fc->user_ns);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 525/772 PCI: imx6: Fix PERST# start-up sequence
In reply to Greg Kroah-HartmanFrom: Francesco Dolcini <[email protected]>
[ Upstream commit a6809941c1f17f455db2cf4ca19c6d8c8746ec25 ]
According to the PCIe standard the PERST# signal (reset-gpio in fsl,imx* compatible dts) should be kept asserted for at least 100 usec before the PCIe refclock is stable, should be kept asserted for at least 100 msec after the power rails are stable and the host should wait at least 100 msec after it is de-asserted before accessing the configuration space of any attached device.
Quoted 1 line
From PCIe CEM r2.0, sec 2.6.2
T-PVPERL: Power stable to PERST# inactive - 100 msec
T-PERST-CLK: REFCLK stable before PERST# inactive - 100 usec.
Quoted 1 line
From PCIe r5.0, sec 6.6.1
With a Downstream Port that does not support Link speeds greater than 5.0 GT/s, software must wait a minimum of 100 ms before sending a Configuration Request to the device immediately below that Port.
Failure to do so could prevent PCIe devices to be working correctly, and this was experienced with real devices.
Move reset assert to imx6_pcie_assert_core_reset(), this way we ensure that PERST# is asserted before enabling any clock, move de-assert to the end of imx6_pcie_deassert_core_reset() after the clock is enabled and deemed stable and add a new delay of 100 msec just afterward.
--- drivers/pci/controller/dwc/pci-imx6.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
drivers/pci/controller/dwc/pci-imx6.c +14 -9
@@ -408,6 +408,11 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)dev_err (dev,"failed to disable vpcie regulator: %d\n" , ret); } + +/* Some boards don't have PCIe reset GPIO. */ +if (gpio_is_valid (imx6_pcie->reset_gpio)) +gpio_set_value_cansleep (imx6_pcie->reset_gpio, + imx6_pcie->gpio_active_high); }static unsigned int imx6_pcie_grp_offset (const struct imx6_pcie *imx6_pcie)
@@ -540,15 +545,6 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)/* allow the clocks to stabilize */ usleep_range (200 ,500 ); -/* Some boards don't have PCIe reset GPIO. */ -if (gpio_is_valid (imx6_pcie->reset_gpio)) { -gpio_set_value_cansleep (imx6_pcie->reset_gpio, - imx6_pcie->gpio_active_high); -msleep (100 ); -gpio_set_value_cansleep (imx6_pcie->reset_gpio, - !imx6_pcie->gpio_active_high); - } -switch (imx6_pcie->drvdata->variant) {case IMX8MQ :reset_control_deassert (imx6_pcie->pciephy_reset);
@@ -595,6 +591,15 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)break ; } +/* Some boards don't have PCIe reset GPIO. */ +if (gpio_is_valid (imx6_pcie->reset_gpio)) { +msleep (100 ); +gpio_set_value_cansleep (imx6_pcie->reset_gpio, + !imx6_pcie->gpio_active_high); +/* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */ +msleep (100 ); + } +return ; err_ref_clk:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 526/772 PCI: mediatek-gen3: Assert resets to ensure expected init state
In reply to Greg Kroah-HartmanFrom: AngeloGioacchino Del Regno <[email protected]>
[ Upstream commit 1d565935e3b9ccc682631e0bc6e415a7f48295d9 ]
The controller may have been left out of reset by the bootloader, in which case, before the powerup sequence, the controller will be found preconfigured with values that were set before booting the
kernel: this produces a controller failure, with the result of a failure during the mtk_pcie_startup_port() sequence as the PCIe link never gets up.
To ensure that we get a clean start in an expected state, assert both the PHY and MAC resets before executing the controller power-up sequence.
--- drivers/pci/controller/pcie-mediatek-gen3.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/pci/controller/pcie-mediatek-gen3.c +8 -0
@@ -838,6 +838,14 @@ static int mtk_pcie_setup(struct mtk_gen3_pcie *pcie)if (err)return err; +/* +* The controller may have been left out of reset by the bootloader +* so make sure that we get a clean start by asserting resets here. +*/ +reset_control_assert (pcie->phy_reset); +reset_control_assert (pcie->mac_reset); +usleep_range (10 ,20 ); +/* Don't touch the hardware registers before power up */ err =mtk_pcie_power_up (pcie);if (err)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 527/772 module.h: simplify MODULE_IMPORT_NS
In reply to Greg Kroah-HartmanFrom: Greg Kroah-Hartman <[email protected]>
[ Upstream commit 80140a81f7f833998d732102eea0fea230b88067 ]
In commit ca321ec74322 ("module.h: allow #define strings to work with MODULE_IMPORT_NS") I fixed up the MODULE_IMPORT_NS() macro to allow defined strings to work with it. Unfortunatly I did it in a two-stage process, when it could just be done with the __stringify() macro as pointed out by Masahiro Yamada.
Clean this up to only be one macro instead of two steps to achieve the same end result.
--- include/linux/module.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
include/linux/module.h +1 -2
@@ -290,8 +290,7 @@ extern typeof(name) __mod_##type##__##name##_device_table \* files require multiple MODULE_FIRMWARE() specifiers */ #define MODULE_FIRMWARE (_firmware) MODULE_INFO(firmware, _firmware) -#define _MODULE_IMPORT_NS (ns) MODULE_INFO(import_ns, #ns) -#define MODULE_IMPORT_NS (ns) _MODULE_IMPORT_NS(ns) +#define MODULE_IMPORT_NS (ns) MODULE_INFO(import_ns, __stringify(ns))struct notifier_block ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 528/772 module: fix [e_shstrndx].sh_size=0 OOB access
In reply to Greg Kroah-HartmanFrom: Alexey Dobriyan <[email protected]>
[ Upstream commit 391e982bfa632b8315235d8be9c0a81374c6a19c ]
It is trivial to craft a module to trigger OOB access in this line:
if (info->secstrings[strhdr->sh_size - 1] != '\0') {BUG: unable to handle page fault for address: ffffc90000aa0fff PGD 100000067 P4D 100000067 PUD 100066067 PMD 10436f067 PTE 0 Oops: 0000 [#1] PREEMPT SMP PTI CPU: 7 PID: 1215 Comm: insmod Not tainted 5.18.0-rc5-00007-g9bf578647087-dirty #10 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-4.fc34 04/01/2014 RIP: 0010:load_module+0x19b/0x2391
--- kernel/module.c | 4 ++++ 1 file changed, 4 insertions(+)
kernel/module.c +4 -0
@@ -3033,6 +3033,10 @@ static int elf_validity_check(struct load_info *info)* strings in the section safe. */ info->secstrings = (void *)info->hdr + strhdr->sh_offset; +if (strhdr->sh_size ==0 ) { +pr_err ("empty section name table\n" ); + goto no_exec; + }if (info->secstrings[strhdr->sh_size -1 ] !='\0' ) {pr_err ("ELF Spec violation: section name table isn't null terminated\n" ); goto no_exec;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 529/772 tty: fix deadlock caused by calling printk() under tty_port->lock
In reply to Greg Kroah-HartmanFrom: Qi Zheng <[email protected]>
[ Upstream commit 6b9dbedbe3499fef862c4dff5217cf91f34e43b3 ]
pty_write() invokes kmalloc() which may invoke a normal printk() to print failure message. This can cause a deadlock in the scenario reported by syz-bot below:
CPU0 CPU1 CPU2
---- ---- ----
lock(console_owner);
lock(&port_lock_key);
lock(&port->lock);
lock(&port_lock_key);
lock(&port->lock); lock(console_owner);
As commit dbdda842fe96 ("printk: Add console owner and waiter logic to load balance console writes") said, such deadlock can be prevented by using printk_deferred() in kmalloc() (which is invoked in the section guarded by the port->lock). But there are too many printk() on the kmalloc() path, and kmalloc() can be called from anywhere, so changing printk() to printk_deferred() is too complicated and inelegant.
Therefore, this patch chooses to specify __GFP_NOWARN to kmalloc(), so that printk() will not be called, and this deadlock problem can be avoided.
Syzbot reported the following lockdep error:
======================================================
WARNING: possible circular locking dependency detected
5.4.143-00237-g08ccc19a-dirty #10 Not tainted
------------------------------------------------------
syz-executor.4/29420 is trying to acquire lock:ffffffff8aedb2a0 (console_owner){....}-{0:0}, at: console_trylock_spinning kernel/printk/printk.c:1752 [inline] ffffffff8aedb2a0 (console_owner){....}-{0:0}, at: vprintk_emit+0x2ca/0x470 kernel/printk/printk.c:2023
but task is already holding lock:ffff8880119c9158 (&port->lock){-.-.}-{2:2}, at: pty_write+0xf4/0x1f0 drivers/tty/pty.c:120
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (&port->lock){-.-.}-{2:2}:
__raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
_raw_spin_lock_irqsave+0x35/0x50 kernel/locking/spinlock.c:159
tty_port_tty_get drivers/tty/tty_port.c:288 [inline] <-- lock(&port->lock);
tty_port_default_wakeup+0x1d/0xb0 drivers/tty/tty_port.c:47
serial8250_tx_chars+0x530/0xa80 drivers/tty/serial/8250/8250_port.c:1767
serial8250_handle_irq.part.0+0x31f/0x3d0 drivers/tty/serial/8250/8250_port.c:1854
serial8250_handle_irq drivers/tty/serial/8250/8250_port.c:1827 [inline] <-- lock(&port_lock_key);
serial8250_default_handle_irq+0xb2/0x220 drivers/tty/serial/8250/8250_port.c:1870
serial8250_interrupt+0xfd/0x200 drivers/tty/serial/8250/8250_core.c:126
__handle_irq_event_percpu+0x109/0xa50 kernel/irq/handle.c:156
[...]-> #1 (&port_lock_key){-.-.}-{2:2}:
__raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
_raw_spin_lock_irqsave+0x35/0x50 kernel/locking/spinlock.c:159
serial8250_console_write+0x184/0xa40 drivers/tty/serial/8250/8250_port.c:3198
<-- lock(&port_lock_key);
call_console_drivers kernel/printk/printk.c:1819 [inline]
console_unlock+0x8cb/0xd00 kernel/printk/printk.c:2504
vprintk_emit+0x1b5/0x470 kernel/printk/printk.c:2024 <-- lock(console_owner);
vprintk_func+0x8d/0x250 kernel/printk/printk_safe.c:394
printk+0xba/0xed kernel/printk/printk.c:2084
register_console+0x8b3/0xc10 kernel/printk/printk.c:2829
univ8250_console_init+0x3a/0x46 drivers/tty/serial/8250/8250_core.c:681
console_init+0x49d/0x6d3 kernel/printk/printk.c:2915
start_kernel+0x5e9/0x879 init/main.c:713
secondary_startup_64+0xa4/0xb0 arch/x86/kernel/head_64.S:241-> #0 (console_owner){....}-{0:0}:
[...]
lock_acquire+0x127/0x340 kernel/locking/lockdep.c:4734
console_trylock_spinning kernel/printk/printk.c:1773 [inline] <-- lock(console_owner);
vprintk_emit+0x307/0x470 kernel/printk/printk.c:2023
vprintk_func+0x8d/0x250 kernel/printk/printk_safe.c:394
printk+0xba/0xed kernel/printk/printk.c:2084
fail_dump lib/fault-inject.c:45 [inline]
should_fail+0x67b/0x7c0 lib/fault-inject.c:144
__should_failslab+0x152/0x1c0 mm/failslab.c:33
should_failslab+0x5/0x10 mm/slab_common.c:1224
slab_pre_alloc_hook mm/slab.h:468 [inline]
slab_alloc_node mm/slub.c:2723 [inline]
slab_alloc mm/slub.c:2807 [inline]
__kmalloc+0x72/0x300 mm/slub.c:3871
kmalloc include/linux/slab.h:582 [inline]
tty_buffer_alloc+0x23f/0x2a0 drivers/tty/tty_buffer.c:175
__tty_buffer_request_room+0x156/0x2a0 drivers/tty/tty_buffer.c:273
tty_insert_flip_string_fixed_flag+0x93/0x250 drivers/tty/tty_buffer.c:318
tty_insert_flip_string include/linux/tty_flip.h:37 [inline]
pty_write+0x126/0x1f0 drivers/tty/pty.c:122 <-- lock(&port->lock);
n_tty_write+0xa7a/0xfc0 drivers/tty/n_tty.c:2356
do_tty_write drivers/tty/tty_io.c:961 [inline]
tty_write+0x512/0x930 drivers/tty/tty_io.c:1045
__vfs_write+0x76/0x100 fs/read_write.c:494
[...]other info that might help us debug this:
Chain exists of: console_owner --> &port_lock_key --> &port->lock
--- drivers/tty/tty_buffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/tty/tty_buffer.c +2 -1
@@ -175,7 +175,8 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_port *port, size_t size)*/ if (atomic_read (&port->buf.mem_used) > port->buf.mem_limit)return NULL ; - p =kmalloc (sizeof (struct tty_buffer ) +2 * size,GFP_ATOMIC ); + p =kmalloc (sizeof (struct tty_buffer ) +2 * size, +GFP_ATOMIC | __GFP_NOWARN);if (p ==NULL )return NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 530/772 crypto: sun8i-ss - rework handling of IV
In reply to Greg Kroah-HartmanFrom: Corentin Labbe <[email protected]>
[ Upstream commit 359e893e8af456be2fefabe851716237df289cbf ]
sun8i-ss fail handling IVs when doing decryption of multiple SGs in-place. It should backup the last block of each SG source for using it later as IVs.
In the same time remove allocation on requests path for storing all IVs.
--- .../allwinner/sun8i-ss/sun8i-ss-cipher.c | 115 ++++++++++++------ .../crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 30 +++-- drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h | 14 ++- 3 files changed, 107 insertions(+), 52 deletions(-)
drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c +77 -38
@@ -93,6 +93,68 @@ static int sun8i_ss_cipher_fallback(struct skcipher_request *areq)return err; } +static int sun8i_ss_setup_ivs (struct skcipher_request *areq) +{ +struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq); +struct sun8i_cipher_tfm_ctx *op =crypto_skcipher_ctx (tfm); +struct sun8i_ss_dev *ss = op->ss; +struct sun8i_cipher_req_ctx *rctx =skcipher_request_ctx (areq); +struct scatterlist *sg = areq->src; +unsigned int todo, offset; +unsigned int len = areq->cryptlen; +unsigned int ivsize =crypto_skcipher_ivsize (tfm); +struct sun8i_ss_flow *sf = &ss->flows[rctx->flow]; +int i =0 ; +u32 a; +int err; + + rctx->ivlen = ivsize; +if (rctx->op_dir &SS_DECRYPTION ) { + offset = areq->cryptlen - ivsize; +scatterwalk_map_and_copy (sf->biv, areq->src, offset, + ivsize,0 ); + } + +/* we need to copy all IVs from source in case DMA is bi-directionnal */ +while (sg && len) { +if (sg_dma_len (sg) ==0 ) { + sg =sg_next (sg); +continue ; + } +if (i ==0 ) +memcpy (sf->iv[0 ], areq->iv, ivsize); + a =dma_map_single (ss->dev, sf->iv[i], ivsize,DMA_TO_DEVICE ); +if (dma_mapping_error (ss->dev, a)) { +memzero_explicit (sf->iv[i], ivsize); +dev_err (ss->dev,"Cannot DMA MAP IV\n" ); + err = -EFAULT ; + goto dma_iv_error; + } + rctx->p_iv[i] = a; +/* we need to setup all others IVs only in the decrypt way */ +if (rctx->op_dir &SS_ENCRYPTION ) +return 0 ; + todo =min (len,sg_dma_len (sg)); + len -= todo; + i++; +if (i <MAX_SG ) { + offset = sg->length - ivsize; +scatterwalk_map_and_copy (sf->iv[i], sg, offset, ivsize,0 ); + } + rctx->niv = i; + sg =sg_next (sg); + } + +return 0 ; +dma_iv_error: + i--; +while (i >=0 ) { +dma_unmap_single (ss->dev, rctx->p_iv[i], ivsize,DMA_TO_DEVICE ); +memzero_explicit (sf->iv[i], ivsize); + } +return err; +} +static int sun8i_ss_cipher (struct skcipher_request *areq) {struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq);
@@ -101,9 +163,9 @@ static int sun8i_ss_cipher(struct skcipher_request *areq)struct sun8i_cipher_req_ctx *rctx =skcipher_request_ctx (areq);struct skcipher_alg *alg =crypto_skcipher_alg (tfm);struct sun8i_ss_alg_template *algt; +struct sun8i_ss_flow *sf = &ss->flows[rctx->flow];struct scatterlist *sg;unsigned int todo, len, offset, ivsize; -void *backup_iv =NULL ;int nr_sgs =0 ;int nr_sgd =0 ;int err =0 ;
@@ -134,30 +196,9 @@ static int sun8i_ss_cipher(struct skcipher_request *areq) ivsize =crypto_skcipher_ivsize (tfm);if (areq->iv &&crypto_skcipher_ivsize (tfm) >0 ) { - rctx->ivlen = ivsize; - rctx->biv =kzalloc (ivsize,GFP_KERNEL |GFP_DMA ); -if (!rctx->biv) { - err = -ENOMEM ; + err =sun8i_ss_setup_ivs (areq); +if (err) goto theend_key; - } -if (rctx->op_dir &SS_DECRYPTION ) { - backup_iv =kzalloc (ivsize,GFP_KERNEL ); -if (!backup_iv) { - err = -ENOMEM ; - goto theend_key; - } - offset = areq->cryptlen - ivsize; -scatterwalk_map_and_copy (backup_iv, areq->src, offset, - ivsize,0 ); - } -memcpy (rctx->biv, areq->iv, ivsize); - rctx->p_iv =dma_map_single (ss->dev, rctx->biv, rctx->ivlen, -DMA_TO_DEVICE ); -if (dma_mapping_error (ss->dev, rctx->p_iv)) { -dev_err (ss->dev,"Cannot DMA MAP IV\n" ); - err = -ENOMEM ; - goto theend_iv; - } }if (areq->src == areq->dst) { nr_sgs = dma_map_sg(ss->dev, areq->src, sg_nents(areq->src),
@@ -243,21 +284,19 @@ static int sun8i_ss_cipher(struct skcipher_request *areq) } theend_iv: -if (rctx->p_iv) -dma_unmap_single (ss->dev, rctx->p_iv, rctx->ivlen, -DMA_TO_DEVICE ); -if (areq->iv && ivsize >0 ) { -if (rctx->biv) { - offset = areq->cryptlen - ivsize; -if (rctx->op_dir &SS_DECRYPTION ) { -memcpy (areq->iv, backup_iv, ivsize); -kfree_sensitive (backup_iv); - }else { -scatterwalk_map_and_copy (areq->iv, areq->dst, offset, - ivsize,0 ); - } -kfree (rctx->biv); +for (i =0 ; i < rctx->niv; i++) { +dma_unmap_single (ss->dev, rctx->p_iv[i], ivsize,DMA_TO_DEVICE ); +memzero_explicit (sf->iv[i], ivsize); + } + + offset = areq->cryptlen - ivsize; +if (rctx->op_dir &SS_DECRYPTION ) { +memcpy (areq->iv, sf->biv, ivsize); +memzero_explicit (sf->biv, ivsize); + }else { +scatterwalk_map_and_copy (areq->iv, areq->dst, offset, + ivsize,0 ); } }
drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c +21 -9
@@ -66,6 +66,7 @@ int sun8i_ss_run_task(struct sun8i_ss_dev *ss, struct sun8i_cipher_req_ctx *rctx const char *name) {int flow = rctx->flow; +unsigned int ivlen = rctx->ivlen;u32 v =SS_START ;int i;
@@ -104,15 +105,14 @@ int sun8i_ss_run_task(struct sun8i_ss_dev *ss, struct sun8i_cipher_req_ctx *rctxmutex_lock (&ss->mlock);writel (rctx->p_key, ss->base +SS_KEY_ADR_REG ); -if (i ==0 ) { -if (rctx->p_iv) -writel (rctx->p_iv, ss->base +SS_IV_ADR_REG ); - }else { -if (rctx->biv) { -if (rctx->op_dir ==SS_ENCRYPTION ) -writel (rctx->t_dst[i -1 ].addr + rctx->t_dst[i -1 ].len *4 - rctx->ivlen, ss->base +SS_IV_ADR_REG ); +if (ivlen) { +if (rctx->op_dir ==SS_ENCRYPTION ) { +if (i ==0 ) +writel (rctx->p_iv[0 ], ss->base +SS_IV_ADR_REG );else -writel (rctx->t_src[i -1 ].addr + rctx->t_src[i -1 ].len *4 - rctx->ivlen, ss->base +SS_IV_ADR_REG ); +writel (rctx->t_dst[i -1 ].addr + rctx->t_dst[i -1 ].len *4 - ivlen, ss->base +SS_IV_ADR_REG ); + }else { +writel (rctx->p_iv[i], ss->base +SS_IV_ADR_REG ); } }
@@ -464,7 +464,7 @@ static void sun8i_ss_free_flows(struct sun8i_ss_dev *ss, int i)*/ static int allocate_flows (struct sun8i_ss_dev *ss) { -int i, err; +int i, j, err; ss->flows =devm_kcalloc (ss->dev,MAXFLOW ,sizeof (struct sun8i_ss_flow ),GFP_KERNEL );
@@ -474,6 +474,18 @@ static int allocate_flows(struct sun8i_ss_dev *ss)for (i =0 ; i <MAXFLOW ; i++) {init_completion (&ss->flows[i].complete); + ss->flows[i].biv =devm_kmalloc (ss->dev,AES_BLOCK_SIZE , +GFP_KERNEL |GFP_DMA ); +if (!ss->flows[i].biv) + goto error_engine; + +for (j =0 ; j <MAX_SG ; j++) { + ss->flows[i].iv[j] =devm_kmalloc (ss->dev,AES_BLOCK_SIZE , +GFP_KERNEL |GFP_DMA ); +if (!ss->flows[i].iv[j]) + goto error_engine; + } + ss->flows[i].engine =crypto_engine_alloc_init (ss->dev, true);if (!ss->flows[i].engine) {dev_err (ss->dev,"Cannot allocate engine\n" );
drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h +9 -5
@@ -121,11 +121,15 @@ struct sginfo {* @complete: completion for the current task on this flow * @status: set to 1 by interrupt if task is done * @stat_req: number of request done by this flow +* @iv: list of IV to use for each step +* @biv: buffer which contain the backuped IV */ struct sun8i_ss_flow {struct crypto_engine *engine;struct completion complete;int status; +u8 *iv[MAX_SG ]; +u8 *biv;#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG unsigned long stat_req;#endif
@@ -164,28 +168,28 @@ struct sun8i_ss_dev {* @t_src: list of mapped SGs with their size * @t_dst: list of mapped SGs with their size * @p_key: DMA address of the key -* @p_iv: DMA address of the IV +* @p_iv: DMA address of the IVs +* @niv: Number of IVs DMA mapped * @method: current algorithm for this request * @op_mode: op_mode for this request * @op_dir: direction (encrypt vs decrypt) for this request * @flow: the flow to use for this request -* @ivlen: size of biv +* @ivlen: size of IVs * @keylen: keylen for this request -* @biv: buffer which contain the IV * @fallback_req: request struct for invoking the fallback skcipher TFM */ struct sun8i_cipher_req_ctx {struct sginfo t_src[MAX_SG ];struct sginfo t_dst[MAX_SG ];u32 p_key; -u32 p_iv; +u32 p_iv[MAX_SG ]; +int niv;u32 method;u32 op_mode;u32 op_dir;int flow;unsigned int ivlen;unsigned int keylen; -void *biv;struct skcipher_request fallback_req;// keep at the end };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 531/772 crypto: sun8i-ss - handle zero sized sg
In reply to Greg Kroah-HartmanFrom: Corentin Labbe <[email protected]>
[ Upstream commit c149e4763d28bb4c0e5daae8a59f2c74e889f407 ]
sun8i-ss does not handle well the possible zero sized sg.
--- drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c +9 -1
@@ -380,13 +380,21 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq) } len = areq->nbytes; -for_each_sg (areq->src, sg, nr_sgs, i) { + sg = areq->src; + i =0 ; +while (len >0 && sg) { +if (sg_dma_len (sg) ==0 ) { + sg =sg_next (sg); +continue ; + } rctx->t_src[i].addr =sg_dma_address (sg); todo =min (len,sg_dma_len (sg)); rctx->t_src[i].len = todo /4 ; len -= todo; rctx->t_dst[i].addr = addr_res; rctx->t_dst[i].len = digestsize /4 ; + sg =sg_next (sg); + i++; }if (len >0 ) {dev_err (ss->dev,"remaining len %d\n" , len);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 532/772 crypto: cryptd - Protect per-CPU resource by disabling BH.
In reply to Greg Kroah-HartmanFrom: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 91e8bcd7b4da182e09ea19a2c73167345fe14c98 ]
The access to cryptd_queue::cpu_queue is synchronized by disabling preemption in cryptd_enqueue_request() and disabling BH in cryptd_queue_worker(). This implies that access is allowed from BH.
If cryptd_enqueue_request() is invoked from preemptible context _and_ soft interrupt then this can lead to list corruption since cryptd_enqueue_request() is not protected against access from soft interrupt.
Replace get_cpu() in cryptd_enqueue_request() with local_bh_disable() to ensure BH is always disabled.
Remove preempt_disable() from cryptd_queue_worker() since it is not needed because local_bh_disable() ensures synchronisation.
--- crypto/cryptd.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)
crypto/cryptd.c +11 -12
@@ -39,6 +39,10 @@ struct cryptd_cpu_queue { };struct cryptd_queue { +/* +* Protected by disabling BH to allow enqueueing from softinterrupt and +* dequeuing from kworker (cryptd_queue_worker()). +*/ struct cryptd_cpu_queue __percpu *cpu_queue; };
@@ -125,28 +129,28 @@ static void cryptd_fini_queue(struct cryptd_queue *queue)static int cryptd_enqueue_request (struct cryptd_queue *queue,struct crypto_async_request *request) { -int cpu, err; +int err;struct cryptd_cpu_queue *cpu_queue;refcount_t *refcnt; - cpu =get_cpu (); +local_bh_disable (); cpu_queue =this_cpu_ptr (queue->cpu_queue); err =crypto_enqueue_request (&cpu_queue->queue, request); refcnt =crypto_tfm_ctx (request->tfm);if (err == -ENOSPC ) - goto out_put_cpu; + goto out; -queue_work_on (cpu, cryptd_wq, &cpu_queue->work); +queue_work_on (smp_processor_id (), cryptd_wq, &cpu_queue->work);if (!refcount_read (refcnt)) - goto out_put_cpu; + goto out;refcount_inc (refcnt); -out_put_cpu: -put_cpu (); +out: +local_bh_enable ();return err; }
@@ -162,15 +166,10 @@ static void cryptd_queue_worker(struct work_struct *work) cpu_queue = container_of(work, struct cryptd_cpu_queue, work);/* * Only handle one request at a time to avoid hogging crypto workqueue. -* preempt_disable/enable is used to prevent being preempted by -* cryptd_enqueue_request(). local_bh_disable/enable is used to prevent -* cryptd_enqueue_request() being accessed from software interrupts. */ local_bh_disable (); -preempt_disable (); backlog =crypto_get_backlog (&cpu_queue->queue); req =crypto_dequeue_request (&cpu_queue->queue); -preempt_enable ();local_bh_enable ();if (!req)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 533/772 ARM: dts: at91: sama7g5: remove interrupt-parent from gic node
In reply to Greg Kroah-HartmanFrom: Eugen Hristev <[email protected]>
[ Upstream commit b7e86ef7afd128577ff7bb0db0ae82d27d7ed7ad ]
interrupt-parent is not to be used as a boolean property.
It is already present in the DT in the proper way it's supposed to be used:
interrupt-parent = <&gic>;
This is also reported by dtbs_check:arch/arm/boot/dts/at91-sama7g5ek.dtb: interrupt-controller@e8c11000: interrupt-parent: True is not of type 'array'
From schema: /.local/lib/python3.8/site-packages/dtschema/schemas/interrupts.yaml
--- arch/arm/boot/dts/sama7g5.dtsi | 1 - 1 file changed, 1 deletion(-)
arch/arm/boot/dts/sama7g5.dtsi +0 -1
@@ -626,7 +626,6 @@ #interrupt-cells = <3>; #address-cells = <0>; interrupt-controller; - interrupt-parent; reg = <0xe8c11000 0x1000>, <0xe8c12000 0x2000>; };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 534/772 hugetlbfs: fix hugetlbfs_statfs() locking
In reply to Greg Kroah-HartmanFrom: Mina Almasry <[email protected]>
[ Upstream commit 4b25f030ae69ba710eff587cabb4c57cb7e7a8a1 ]
After commit db71ef79b59b ("hugetlb: make free_huge_page irq safe"), the subpool lock should be locked with spin_lock_irq() and all call sites was modified as such, except for the ones in hugetlbfs_statfs().
--- fs/hugetlbfs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/hugetlbfs/inode.c +2 -2
@@ -1048,12 +1048,12 @@ static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf)if (sbinfo->spool) {long free_pages; -spin_lock (&sbinfo->spool->lock); +spin_lock_irq (&sbinfo->spool->lock); buf->f_blocks = sbinfo->spool->max_hpages; free_pages = sbinfo->spool->max_hpages - sbinfo->spool->used_hpages; buf->f_bavail = buf->f_bfree = free_pages; -spin_unlock (&sbinfo->spool->lock); +spin_unlock_irq (&sbinfo->spool->lock); buf->f_files = sbinfo->max_inodes; buf->f_ffree = sbinfo->free_inodes; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 535/772 x86/mce: relocate set{clear}_mce_nospec() functions
In reply to Greg Kroah-HartmanFrom: Jane Chu <[email protected]>
[ Upstream commit b3fdf9398a16f01dc013967a4ab25e99c3f4fc12 ]
Relocate the twin mce functions to arch/x86/mm/pat/set_memory.c file where they belong.
While at it, fixup a function name in a comment.
--- arch/x86/include/asm/set_memory.h | 52 ------------------------------- arch/x86/mm/pat/set_memory.c | 50 +++++++++++++++++++++++++++-- include/linux/set_memory.h | 8 ++--- 3 files changed, 52 insertions(+), 58 deletions(-)
arch/x86/include/asm/set_memory.h +0 -52
@@ -88,56 +88,4 @@ void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc);extern int kernel_set_to_readonly; -#ifdef CONFIG_X86_64 -/* -* Prevent speculative access to the page by either unmapping -* it (if we do not require access to any part of the page) or -* marking it uncacheable (if we want to try to retrieve data -* from non-poisoned lines in the page). -*/ -static inline int set_mce_nospec (unsigned long pfn,bool unmap) -{ -unsigned long decoy_addr; -int rc; - -/* SGX pages are not in the 1:1 map */ -if (arch_is_platform_page (pfn <<PAGE_SHIFT )) -return 0 ; -/* -* We would like to just call: -* set_memory_XX((unsigned long)pfn_to_kaddr(pfn), 1); -* but doing that would radically increase the odds of a -* speculative access to the poison page because we'd have -* the virtual address of the kernel 1:1 mapping sitting -* around in registers. -* Instead we get tricky. We create a non-canonical address -* that looks just like the one we want, but has bit 63 flipped. -* This relies on set_memory_XX() properly sanitizing any __pa() -* results with __PHYSICAL_MASK or PTE_PFN_MASK. -*/ - decoy_addr = (pfn <<PAGE_SHIFT ) + (PAGE_OFFSET ^BIT (63 )); - -if (unmap) - rc =set_memory_np (decoy_addr,1 ); -else - rc =set_memory_uc (decoy_addr,1 ); -if (rc) -pr_warn ("Could not invalidate pfn=0x%lx from 1:1 map\n" , pfn); -return rc; -} -#define set_mce_nospec set_mce_nospec - -/* Restore full speculative operation to the pfn. */ -static inline int clear_mce_nospec (unsigned long pfn) -{ -return set_memory_wb ((unsigned long )pfn_to_kaddr (pfn),1 ); -} -#define clear_mce_nospec clear_mce_nospec -#else -/* -* Few people would run a 32-bit kernel on a machine that supports -* recoverable errors because they have too much memory to boot 32-bit. -*/ -#endif -#endif /* _ASM_X86_SET_MEMORY_H */
arch/x86/mm/pat/set_memory.c +48 -2
74 lines not on this page · raw message
include/linux/set_memory.h +4 -4
@@ -42,14 +42,14 @@ static inline bool can_set_direct_map(void)#endif #endif /* CONFIG_ARCH_HAS_SET_DIRECT_MAP */ -#ifndef set_mce_nospec +#ifdef CONFIG_X86_64 +int set_mce_nospec (unsigned long pfn,bool unmap); +int clear_mce_nospec (unsigned long pfn); +#else static inline int set_mce_nospec (unsigned long pfn,bool unmap) {return 0 ; } -#endif - -#ifndef clear_mce_nospecstatic inline int clear_mce_nospec (unsigned long pfn) {return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 536/772 mce: fix set_mce_nospec to always unmap the whole page
In reply to Greg Kroah-HartmanFrom: Jane Chu <[email protected]>
[ Upstream commit 5898b43af954b83c4a4ee4ab85c4dbafa395822a ]
The set_memory_uc() approach doesn't work well in all cases. As Dan pointed out when "The VMM unmapped the bad page from guest physical space and passed the machine check to the guest." "The guest gets virtual #MC on an access to that page. When the guest tries to do set_memory_uc() and instructs cpa_flush() to do clean caches that results in taking another fault / exception perhaps because the VMM unmapped the page from the guest."
Since the driver has special knowledge to handle NP or UC, mark the poisoned page with NP and let driver handle it when it comes down to repair.
Please refer to discussions here for more details.
https://lore.kernel.org/all/CAPcyv4hrXPb1tASBZUg-GgdVs0OOFKXMXLiHmktg_kFi7YBMyQ@mail.gmail.com/
Now since poisoned page is marked as not-present, in order to avoid writing to a not-present page and trigger kernel Oops, also fix pmem_do_write().
--- arch/x86/kernel/cpu/mce/core.c | 6 +++--- arch/x86/mm/pat/set_memory.c | 23 +++++++++++------------ drivers/nvdimm/pmem.c | 30 +++++++----------------------- include/linux/set_memory.h | 4 ++-- 4 files changed, 23 insertions(+), 40 deletions(-)
arch/x86/kernel/cpu/mce/core.c +3 -3
@@ -613,7 +613,7 @@ static int uc_decode_notifier(struct notifier_block *nb, unsigned long val, pfn = mce->addr >>PAGE_SHIFT ;if (!memory_failure (pfn,0 )) { -set_mce_nospec (pfn,whole_page (mce)); +set_mce_nospec (pfn); mce->kflags |=MCE_HANDLED_UC ; }
@@ -1350,7 +1350,7 @@ static void kill_me_maybe(struct callback_head *cb) ret =memory_failure (p->mce_addr >>PAGE_SHIFT , flags);if (!ret) { -set_mce_nospec (p->mce_addr >>PAGE_SHIFT , p->mce_whole_page); +set_mce_nospec (p->mce_addr >>PAGE_SHIFT );sync_core ();return ; }
@@ -1374,7 +1374,7 @@ static void kill_me_never(struct callback_head *cb) p->mce_count =0 ;pr_err ("Kernel accessed poison in user space at %llx\n" , p->mce_addr);if (!memory_failure (p->mce_addr >>PAGE_SHIFT ,0 )) -set_mce_nospec (p->mce_addr >>PAGE_SHIFT , p->mce_whole_page); +set_mce_nospec (p->mce_addr >>PAGE_SHIFT ); }static void queue_task_work (struct mce *m,char *msg,void (*func)(struct callback_head *))
arch/x86/mm/pat/set_memory.c +11 -12
@@ -1925,14 +1925,9 @@ int set_memory_wb(unsigned long addr, int numpages) }EXPORT_SYMBOL (set_memory_wb); -/* -* Prevent speculative access to the page by either unmapping -* it (if we do not require access to any part of the page) or -* marking it uncacheable (if we want to try to retrieve data -* from non-poisoned lines in the page). -*/ +/* Prevent speculative access to a page by marking it not-present */ #ifdef CONFIG_X86_64 -int set_mce_nospec (unsigned long pfn,bool unmap) +int set_mce_nospec (unsigned long pfn) {unsigned long decoy_addr;int rc;
@@ -1954,19 +1949,23 @@ int set_mce_nospec(unsigned long pfn, bool unmap)*/ decoy_addr = (pfn <<PAGE_SHIFT ) + (PAGE_OFFSET ^BIT (63 )); -if (unmap) - rc =set_memory_np (decoy_addr,1 ); -else - rc =set_memory_uc (decoy_addr,1 ); + rc =set_memory_np (decoy_addr,1 );if (rc)pr_warn ("Could not invalidate pfn=0x%lx from 1:1 map\n" , pfn); return rc; } +static int set_memory_present (unsigned long *addr,int numpages) +{ +return change_page_attr_set (addr, numpages,__pgprot (_PAGE_PRESENT),0 ); +} +/* Restore full speculative operation to the pfn. */ int clear_mce_nospec (unsigned long pfn) { -return set_memory_wb ((unsigned long )pfn_to_kaddr (pfn),1 ); +unsigned long addr = (unsigned long )pfn_to_kaddr (pfn); + +return set_memory_present (&addr,1 ); }EXPORT_SYMBOL_GPL (clear_mce_nospec);#endif /* CONFIG_X86_64 */
drivers/nvdimm/pmem.c +7 -23
@@ -158,36 +158,20 @@ static blk_status_t pmem_do_write(struct pmem_device *pmem, struct page *page, unsigned int page_off, sector_t sector, unsigned int len) { - blk_status_t rc = BLK_STS_OK; -bool bad_pmem = false; phys_addr_t pmem_off = sector * 512 + pmem->data_offset;void *pmem_addr = pmem->virt_addr + pmem_off; -if (unlikely (is_bad_pmem (&pmem->bb, sector, len))) - bad_pmem = true; +if (unlikely (is_bad_pmem (&pmem->bb, sector, len))) { +blk_status_t rc =pmem_clear_poison (pmem, pmem_off, len); + +if (rc !=BLK_STS_OK ) +return rc; + } -/* -* Note that we write the data both before and after -* clearing poison. The write before clear poison -* handles situations where the latest written data is -* preserved and the clear poison operation simply marks -* the address range as valid without changing the data. -* In this case application software can assume that an -* interrupted write will either return the new good -* data or an error. -* -* However, if pmem_clear_poison() leaves the data in an -* indeterminate state we need to perform the write -* after clear poison. -*/ flush_dcache_page (page);write_pmem (pmem_addr, page, page_off, len); -if (unlikely (bad_pmem)) { - rc =pmem_clear_poison (pmem, pmem_off, len); -write_pmem (pmem_addr, page, page_off, len); - } -return rc; +return BLK_STS_OK ; }static void pmem_submit_bio (struct bio *bio)
include/linux/set_memory.h +2 -2
@@ -43,10 +43,10 @@ static inline bool can_set_direct_map(void)#endif /* CONFIG_ARCH_HAS_SET_DIRECT_MAP */ #ifdef CONFIG_X86_64 -int set_mce_nospec (unsigned long pfn,bool unmap); +int set_mce_nospec (unsigned long pfn);int clear_mce_nospec (unsigned long pfn);#else -static inline int set_mce_nospec (unsigned long pfn,bool unmap) +static inline int set_mce_nospec (unsigned long pfn) {return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 537/772 Input: sparcspkr - fix refcount leak in bbc_beep_probe
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit c8994b30d71d64d5dcc9bc0edbfdf367171aa96f ]
of_find_node_by_path() calls of_find_node_opts_by_path(), which returns a node pointer with refcount incremented, we should use of_node_put() on it when done. Add missing of_node_put() to avoid refcount leak.
--- drivers/input/misc/sparcspkr.c | 1 + 1 file changed, 1 insertion(+)
drivers/input/misc/sparcspkr.c +1 -0
@@ -205,6 +205,7 @@ static int bbc_beep_probe(struct platform_device *op) info = &state->u.bbc; info->clock_freq =of_getintprop_default (dp,"clock-frequency" ,0 ); +of_node_put (dp);if (!info->clock_freq) goto out_free;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 538/772 PCI/AER: Clear MULTI_ERR_COR/UNCOR_RCV bits
In reply to Greg Kroah-HartmanFrom: Kuppuswamy Sathyanarayanan <[email protected]>
[ Upstream commit 203926da2bff8e172200a2f11c758987af112d4a ]
When a Root Port or Root Complex Event Collector receives an error Message e.g., ERR_COR, it sets PCI_ERR_ROOT_COR_RCV in the Root Error Status register and logs the Requester ID in the Error Source Identification register. If it receives a second ERR_COR Message before software clears PCI_ERR_ROOT_COR_RCV, hardware sets PCI_ERR_ROOT_MULTI_COR_RCV and the Requester ID is lost.
In the following scenario, PCI_ERR_ROOT_MULTI_COR_RCV was never cleared:
- hardware receives ERR_COR message
- hardware sets PCI_ERR_ROOT_COR_RCV
- aer_irq() entered
- aer_irq(): status = pci_read_config_dword(PCI_ERR_ROOT_STATUS)
- aer_irq(): now status == PCI_ERR_ROOT_COR_RCV
- hardware receives second ERR_COR message
- hardware sets PCI_ERR_ROOT_MULTI_COR_RCV
- aer_irq(): pci_write_config_dword(PCI_ERR_ROOT_STATUS, status)
- PCI_ERR_ROOT_COR_RCV is cleared; PCI_ERR_ROOT_MULTI_COR_RCV is set
- aer_irq() entered again
- aer_irq(): status = pci_read_config_dword(PCI_ERR_ROOT_STATUS)
- aer_irq(): now status == PCI_ERR_ROOT_MULTI_COR_RCV
- aer_irq() exits because PCI_ERR_ROOT_COR_RCV not set
- PCI_ERR_ROOT_MULTI_COR_RCV is still set
The same problem occurred with ERR_NONFATAL/ERR_FATAL Messages and PCI_ERR_ROOT_UNCOR_RCV and PCI_ERR_ROOT_MULTI_UNCOR_RCV.
Fix the problem by queueing an AER event and clearing the Root Error Status bits when any of these bits are set:
PCI_ERR_ROOT_COR_RCV
PCI_ERR_ROOT_UNCOR_RCV
PCI_ERR_ROOT_MULTI_COR_RCV
PCI_ERR_ROOT_MULTI_UNCOR_RCV
See the bugzilla link for details from Eric about how to reproduce this problem.
--- drivers/pci/pcie/aer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/pci/pcie/aer.c +6 -1
@@ -101,6 +101,11 @@ struct aer_stats {#define ERR_COR_ID (d) (d & 0xffff)#define ERR_UNCOR_ID (d) (d >> 16) +#define AER_ERR_STATUS_MASK (PCI_ERR_ROOT_UNCOR_RCV | \ + PCI_ERR_ROOT_COR_RCV | \ + PCI_ERR_ROOT_MULTI_COR_RCV | \ + PCI_ERR_ROOT_MULTI_UNCOR_RCV) +static int pcie_aer_disable;static pci_ers_result_t aer_root_reset (struct pci_dev *dev);
@@ -1196,7 +1201,7 @@ static irqreturn_t aer_irq(int irq, void *context)struct aer_err_source e_src = {};pci_read_config_dword (rp, aer +PCI_ERR_ROOT_STATUS , &e_src.status); -if (!(e_src.status & (PCI_ERR_ROOT_UNCOR_RCV |PCI_ERR_ROOT_COR_RCV ))) +if (!(e_src.status &AER_ERR_STATUS_MASK ))return IRQ_NONE ;pci_read_config_dword (rp, aer +PCI_ERR_ROOT_ERR_SRC , &e_src.id);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 539/772 KVM: PPC: Book3S HV: Fix vcore_blocked tracepoint
In reply to Greg Kroah-HartmanFrom: Fabiano Rosas <[email protected]>
[ Upstream commit ad55bae7dc364417434b69dd6c30104f20d0f84d ]
We removed most of the vcore logic from the P9 path but there's still a tracepoint that tried to dereference vc->runner.
--- arch/powerpc/kvm/book3s_hv.c | 8 ++++---- arch/powerpc/kvm/trace_hv.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-)
arch/powerpc/kvm/book3s_hv.c +4 -4
@@ -4238,13 +4238,13 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc) start_wait =ktime_get (); vc->vcore_state =VCORE_SLEEPING ; -trace_kvmppc_vcore_blocked (vc,0 ); +trace_kvmppc_vcore_blocked (vc->runner,0 );spin_unlock (&vc->lock);schedule ();finish_rcuwait (&vc->wait);spin_lock (&vc->lock); vc->vcore_state =VCORE_INACTIVE ; -trace_kvmppc_vcore_blocked (vc,1 ); +trace_kvmppc_vcore_blocked (vc->runner,1 ); ++vc->runner->stat.halt_successful_wait; cur =ktime_get ();
@@ -4624,9 +4624,9 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,if (kvmppc_vcpu_check_block (vcpu))break ; -trace_kvmppc_vcore_blocked (vc,0 ); +trace_kvmppc_vcore_blocked (vcpu,0 );schedule (); -trace_kvmppc_vcore_blocked (vc,1 ); +trace_kvmppc_vcore_blocked (vcpu,1 ); }finish_rcuwait (wait); }
arch/powerpc/kvm/trace_hv.h +4 -4
@@ -408,9 +408,9 @@ TRACE_EVENT(kvmppc_run_core, ); TRACE_EVENT(kvmppc_vcore_blocked, - TP_PROTO(struct kvmppc_vcore *vc, int where), + TP_PROTO(struct kvm_vcpu *vcpu, int where), - TP_ARGS(vc, where), + TP_ARGS(vcpu, where), TP_STRUCT__entry( __field(int, n_runnable)
@@ -420,8 +420,8 @@ TRACE_EVENT(kvmppc_vcore_blocked, ), TP_fast_assign( - __entry->runner_vcpu = vc->runner->vcpu_id; - __entry->n_runnable = vc->n_runnable; + __entry->runner_vcpu = vcpu->vcpu_id; + __entry->n_runnable = vcpu->arch.vcore->n_runnable; __entry->where = where; __entry->tgid = current->tgid; ),
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 540/772 PCI: microchip: Fix potential race in interrupt handling
In reply to Greg Kroah-HartmanFrom: Daire McNamara <[email protected]>
[ Upstream commit 7013654af694f6e1a2e699a6450ea50d309dd0e5 ]
Clear the MSI bit in ISTATUS_LOCAL register after reading it, but before reading and handling individual MSI bits from the ISTATUS_MSI register. This avoids a potential race where new MSI bits may be set on the ISTATUS_MSI register after it was read and be missed when the MSI bit in the ISTATUS_LOCAL register is cleared.
ISTATUS_LOCAL is a read/write/clear register; the register's bits are set when the corresponding interrupt source is activated. Each source is independent and thus multiple sources may be active simultaneously. The processor can monitor and clear status bits. If one or more ISTATUS_LOCAL interrupt sources are active, the RootPort issues an interrupt towards the processor (on the AXI domain). Bit 28 of this register reports an MSI has been received by the RootPort.
ISTATUS_MSI is a read/write/clear register. Bits 31-0 are asserted when an MSI with message number 31-0 is received by the RootPort. The processor must monitor and clear these bits.
Effectively, Bit 28 of ISTATUS_LOCAL informs the processor that an MSI has arrived at the RootPort and ISTATUS_MSI informs the processor which MSI (in the range 0 - 31) needs handling.
Reported by: Bjorn Helgaas <[email protected]>
--- drivers/pci/controller/pcie-microchip-host.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/pci/controller/pcie-microchip-host.c +1 -5
@@ -419,6 +419,7 @@ static void mc_handle_msi(struct irq_desc *desc) status =readl_relaxed (bridge_base_addr +ISTATUS_LOCAL );if (status &PM_MSI_INT_MSI_MASK ) { +writel_relaxed (status &PM_MSI_INT_MSI_MASK , bridge_base_addr +ISTATUS_LOCAL ); status =readl_relaxed (bridge_base_addr +ISTATUS_MSI );for_each_set_bit (bit, &status, msi->num_vectors) { ret =generic_handle_domain_irq (msi->dev_domain, bit);
@@ -437,13 +438,8 @@ static void mc_msi_bottom_irq_ack(struct irq_data *data)void __iomem *bridge_base_addr = port->axi_base_addr +MC_PCIE_BRIDGE_ADDR ;u32 bitpos = data->hwirq; -unsigned long status;writel_relaxed (BIT (bitpos), bridge_base_addr +ISTATUS_MSI ); - status =readl_relaxed (bridge_base_addr +ISTATUS_MSI ); -if (!status) -writel_relaxed (BIT (PM_MSI_INT_MSI_SHIFT ), - bridge_base_addr +ISTATUS_LOCAL ); }static void mc_compose_msi_msg (struct irq_data *data,struct msi_msg *msg)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 541/772 hwrng: omap3-rom - fix using wrong clk_disable() in omap_rom_rng_runtime_resume()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit e4e62bbc6aba49a5edb3156ec65f6698ff37d228 ]
'ddata->clk' is enabled by clk_prepare_enable(), it should be disabled by clk_disable_unprepare().
--- drivers/char/hw_random/omap3-rom-rng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/char/hw_random/omap3-rom-rng.c +1 -1
@@ -92,7 +92,7 @@ static int __maybe_unused omap_rom_rng_runtime_resume(struct device *dev) r = ddata->rom_rng_call (0 ,0 ,RNG_GEN_PRNG_HW_INIT );if (r !=0 ) { -clk_disable (ddata->clk); +clk_disable_unprepare (ddata->clk);dev_err (dev,"HW init failed: %d\n" , r);return -EIO ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 542/772 perf evlist: Keep topdown counters in weak group
In reply to Greg Kroah-HartmanFrom: Ian Rogers <[email protected]>
[ Upstream commit d98079c05b5a5411c6030c47b6256cbeeeff77d0 ]
On Intel Icelake, topdown events must always be grouped with a slots event as leader. When a metric is parsed a weak group is formed and retried if perf_event_open fails. The retried events aren't grouped breaking the slots leader requirement. This change modifies the weak group "reset" behavior so that topdown events aren't broken from the group for the retry.
$ perf stat -e '{slots,topdown-bad-spec,topdown-be-bound,topdown-fe-bound,topdown-retiring,branch-instructions,branch-misses,bus-cycles,cache-misses,cache-references,cpu-cycles,instructions,mem-loads,mem-stores,ref-cycles,baclears.any,ARITH.DIVIDER_ACTIVE}:W' -a sleep 1Performance counter stats for 'system wide':
47,867,188,483 slots (92.27%)
<not supported> topdown-bad-spec
<not supported> topdown-be-bound
<not supported> topdown-fe-bound
<not supported> topdown-retiring
2,173,346,937 branch-instructions (92.27%)
10,540,253 branch-misses # 0.48% of all branches (92.29%)
96,291,140 bus-cycles (92.29%)
6,214,202 cache-misses # 20.120 % of all cache refs (92.29%)
30,886,082 cache-references (76.91%)
11,773,726,641 cpu-cycles (84.62%)
11,807,585,307 instructions # 1.00 insn per cycle (92.31%)
0 mem-loads (92.32%)
2,212,928,573 mem-stores (84.69%)
10,024,403,118 ref-cycles (92.35%)
16,232,978 baclears.any (92.35%)
23,832,633 ARITH.DIVIDER_ACTIVE (84.59%)0.981070734 seconds time elapsed
After:
$ perf stat -e '{slots,topdown-bad-spec,topdown-be-bound,topdown-fe-bound,topdown-retiring,branch-instructions,branch-misses,bus-cycles,cache-misses,cache-references,cpu-cycles,instructions,mem-loads,mem-stores,ref-cycles,baclears.any,ARITH.DIVIDER_ACTIVE}:W' -a sleep 1Performance counter stats for 'system wide':
31040189283 slots (92.27%)
8997514811 topdown-bad-spec # 28.2% bad speculation (92.27%)
10997536028 topdown-be-bound # 34.5% backend bound (92.27%)
4778060526 topdown-fe-bound # 15.0% frontend bound (92.27%)
7086628768 topdown-retiring # 22.2% retiring (92.27%)
1417611942 branch-instructions (92.26%)
5285529 branch-misses # 0.37% of all branches (92.28%)
62922469 bus-cycles (92.29%)
1440708 cache-misses # 8.292 % of all cache refs (92.30%)
17374098 cache-references (76.94%)
8040889520 cpu-cycles (84.63%)
7709992319 instructions # 0.96 insn per cycle (92.32%)
0 mem-loads (92.32%)
1515669558 mem-stores (84.68%)
6542411177 ref-cycles (92.35%)
4154149 baclears.any (92.35%)
20556152 ARITH.DIVIDER_ACTIVE (84.59%)1.010799593 seconds time elapsed
--- tools/perf/arch/x86/util/evsel.c | 12 ++++++++++++ tools/perf/util/evlist.c | 16 ++++++++++++++-- tools/perf/util/evsel.c | 10 ++++++++++ tools/perf/util/evsel.h | 3 +++ 4 files changed, 39 insertions(+), 2 deletions(-)
tools/perf/arch/x86/util/evsel.c +12 -0
@@ -3,6 +3,7 @@#include <stdlib.h> #include "util/evsel.h" #include "util/env.h" +#include "util/pmu.h" #include "linux/string.h" void arch_evsel__set_sample_weight (struct evsel *evsel)
@@ -29,3 +30,14 @@ void arch_evsel__fixup_new_cycles(struct perf_event_attr *attr)free (env.cpuid); } + +bool arch_evsel__must_be_in_group (const struct evsel *evsel) +{ +if ((evsel->pmu_name &&strcmp (evsel->pmu_name,"cpu" )) || + !pmu_have_event ("cpu" ,"slots" )) +return false; + +return evsel->name && + (!strcasecmp (evsel->name,"slots" ) || +strcasestr (evsel->name,"topdown" )); +}
tools/perf/util/evlist.c +14 -2
@@ -1790,8 +1790,17 @@ struct evsel *evlist__reset_weak_group(struct evlist *evsel_list, struct evsel *if (evsel__has_leader (c2, leader)) {if (is_open && close)perf_evsel__close (&c2->core); -evsel__set_leader (c2, c2); - c2->core.nr_members =0 ; +/* +* We want to close all members of the group and reopen +* them. Some events, like Intel topdown, require being +* in a group and so keep these in the group. +*/ +if (!evsel__must_be_in_group (c2) && c2 != leader) { +evsel__set_leader (c2, c2); + c2->core.nr_members =0 ; + leader->core.nr_members--; + } +/* * Set this for all former members of the group * to indicate they get reopened.
@@ -1799,6 +1808,9 @@ struct evsel *evlist__reset_weak_group(struct evlist *evsel_list, struct evsel * c2->reset_group = true; } } +/* Reset the leader count if all entries were removed. */ +if (leader->core.nr_members ==1 ) + leader->core.nr_members =0 ;return leader; }
tools/perf/util/evsel.c +10 -0
@@ -3048,3 +3048,13 @@ int evsel__source_count(const struct evsel *evsel) }return count; } + +bool __weak arch_evsel__must_be_in_group (const struct evsel *evsel__maybe_unused ) +{ +return false; +} + +bool evsel__must_be_in_group (const struct evsel *evsel) +{ +return arch_evsel__must_be_in_group (evsel); +}
tools/perf/util/evsel.h +3 -0
@@ -483,6 +483,9 @@ bool evsel__has_leader(struct evsel *evsel, struct evsel *leader);bool evsel__is_leader (struct evsel *evsel);void evsel__set_leader (struct evsel *evsel,struct evsel *leader);int evsel__source_count (const struct evsel *evsel); +bool evsel__must_be_in_group (const struct evsel *evsel); + +bool arch_evsel__must_be_in_group (const struct evsel *evsel);/* * Macro to swap the bit-field postition and size.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 543/772 perf stat: Always keep perf metrics topdown events in a group
In reply to Greg Kroah-HartmanFrom: Kan Liang <[email protected]>
[ Upstream commit e8f4f794d7047dd36f090f44f12cd645fba204d2 ]
If any member in a group has a different cpu mask than the other members, the current perf stat disables group. when the perf metrics topdown events are part of the group, the below <not supported> error will be triggered.
$ perf stat -e "{slots,topdown-retiring,uncore_imc_free_running_0/dclk/}" -a sleep 1
WARNING: grouped events cpus do not match, disabling group:
anon group { slots, topdown-retiring, uncore_imc_free_running_0/dclk/ }Performance counter stats for 'system wide':
141,465,174 slots
<not supported> topdown-retiring
1,605,330,334 uncore_imc_free_running_0/dclk/The perf metrics topdown events must always be grouped with a slots event as leader.
Factor out evsel__remove_from_group() to only remove the regular events from the group.
Remove evsel__must_be_in_group(), since no one use it anymore.
With the patch, the topdown events aren't broken from the group for the splitting.
$ perf stat -e "{slots,topdown-retiring,uncore_imc_free_running_0/dclk/}" -a sleep 1
WARNING: grouped events cpus do not match, disabling group:
anon group { slots, topdown-retiring, uncore_imc_free_running_0/dclk/ }Performance counter stats for 'system wide':
346,110,588 slots
124,608,256 topdown-retiring
1,606,869,976 uncore_imc_free_running_0/dclk/1.003877592 seconds time elapsed
--- tools/perf/builtin-stat.c | 7 ++----- tools/perf/util/evlist.c | 6 +----- tools/perf/util/evsel.c | 13 +++++++++++-- tools/perf/util/evsel.h | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-)
tools/perf/builtin-stat.c +2 -5
@@ -271,11 +271,8 @@ static void evlist__check_cpu_maps(struct evlist *evlist)pr_warning (" %s: %s\n" , evsel->name, buf); } -for_each_group_evsel (pos, leader) { -evsel__set_leader (pos, pos); - pos->core.nr_members =0 ; - } - evsel->core.leader->nr_members =0 ; +for_each_group_evsel (pos, leader) +evsel__remove_from_group (pos, leader); } }
tools/perf/util/evlist.c +1 -5
@@ -1795,11 +1795,7 @@ struct evsel *evlist__reset_weak_group(struct evlist *evsel_list, struct evsel ** them. Some events, like Intel topdown, require being * in a group and so keep these in the group. */ -if (!evsel__must_be_in_group (c2) && c2 != leader) { -evsel__set_leader (c2, c2); - c2->core.nr_members =0 ; - leader->core.nr_members--; - } +evsel__remove_from_group (c2, leader);/* * Set this for all former members of the group
tools/perf/util/evsel.c +11 -2
@@ -3054,7 +3054,16 @@ bool __weak arch_evsel__must_be_in_group(const struct evsel *evsel __maybe_unusereturn false; } -bool evsel__must_be_in_group (const struct evsel *evsel) +/* +* Remove an event from a given group (leader). +* Some events, e.g., perf metrics Topdown events, +* must always be grouped. Ignore the events. +*/ +void evsel__remove_from_group (struct evsel *evsel,struct evsel *leader) { -return arch_evsel__must_be_in_group (evsel); +if (!arch_evsel__must_be_in_group (evsel) && evsel != leader) { +evsel__set_leader (evsel, evsel); + evsel->core.nr_members =0 ; + leader->core.nr_members--; + } }
tools/perf/util/evsel.h +1 -1
@@ -483,7 +483,7 @@ bool evsel__has_leader(struct evsel *evsel, struct evsel *leader);bool evsel__is_leader (struct evsel *evsel);void evsel__set_leader (struct evsel *evsel,struct evsel *leader);int evsel__source_count (const struct evsel *evsel); -bool evsel__must_be_in_group (const struct evsel *evsel); +void evsel__remove_from_group (struct evsel *evsel,struct evsel *leader);bool arch_evsel__must_be_in_group (const struct evsel *evsel);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 544/772 mailbox: pcc: Fix an invalid-load caught by the address sanitizer
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
[ Upstream commit 369e4ef87a8f5da7c348ec2c61ec5cd726e8337a ]
pcc_mailbox_probe doesn't initialize all memory that has been allocated before the first time that one of it's members txdone_irq may be accessed.
This leads to a an invalid load any time that this member is accessed:
[ 2.429769] UBSAN: invalid-load in drivers/mailbox/pcc.c:684:22 [ 2.430324] UBSAN: invalid-load in drivers/mailbox/mailbox.c:486:12 [ 4.276782] UBSAN: invalid-load in drivers/acpi/cppc_acpi.c:314:45
--- drivers/mailbox/pcc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mailbox/pcc.c +1 -1
@@ -654,7 +654,7 @@ static int pcc_mbox_probe(struct platform_device *pdev) goto err; } - pcc_mbox_ctrl =devm_kmalloc (dev,sizeof (*pcc_mbox_ctrl),GFP_KERNEL ); + pcc_mbox_ctrl =devm_kzalloc (dev,sizeof (*pcc_mbox_ctrl),GFP_KERNEL );if (!pcc_mbox_ctrl) { rc = -ENOMEM ; goto err;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 545/772 powerpc/64: Only WARN if __pa()/__va() called with bad addresses
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
[ Upstream commit c4bce84d0bd3f396f702d69be2e92bbd8af97583 ]
We added checks to __pa() / __va() to ensure they're only called with appropriate addresses. But using BUG_ON() is too strong, it means virt_addr_valid() will BUG when DEBUG_VIRTUAL is enabled.
Instead switch them to warnings, arm64 does the same.
--- arch/powerpc/include/asm/page.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
arch/powerpc/include/asm/page.h +5 -2
@@ -216,6 +216,9 @@ static inline bool pfn_valid(unsigned long pfn)#define __pa (x) ((phys_addr_t)(unsigned long)(x) - VIRT_PHYS_OFFSET)#else #ifdef CONFIG_PPC64 + +#define VIRTUAL_WARN_ON (x) WARN_ON(IS_ENABLED(CONFIG_DEBUG_VIRTUAL) && (x)) +/* * gcc miscompiles (unsigned long)(&static_var) - PAGE_OFFSET * with -mcmodel=medium, so we use & and | instead of - and + on 64-bit.
@@ -223,13 +226,13 @@ static inline bool pfn_valid(unsigned long pfn)*/ #define __va (x) \ ({ \ - VIRTUAL_BUG_ON((unsigned long)(x) >= PAGE_OFFSET); \ + VIRTUAL_WARN_ON((unsigned long)(x) >= PAGE_OFFSET); \ (void *)(unsigned long)((phys_addr_t)(x) | PAGE_OFFSET); \ })#define __pa (x) \ ({ \ - VIRTUAL_BUG_ON((unsigned long)(x) < PAGE_OFFSET); \ + VIRTUAL_WARN_ON((unsigned long)(x) < PAGE_OFFSET); \ (unsigned long)(x) & 0x0fffffffffffffffUL; \ })
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 546/772 powerpc/powernv: Get L1D flush requirements from device-tree
In reply to Greg Kroah-HartmanFrom: Russell Currey <[email protected]>
[ Upstream commit 2efee6adb56159288bce9d1ab51fc9056d7007d4 ]
The device-tree properties no-need-l1d-flush-msr-pr-1-to-0 and no-need-l1d-flush-kernel-on-user-access are the equivalents of H_CPU_BEHAV_NO_L1D_FLUSH_ENTRY and H_CPU_BEHAV_NO_L1D_FLUSH_UACCESS from the H_GET_CPU_CHARACTERISTICS hcall on pseries respectively.
In commit d02fa40d759f ("powerpc/powernv: Remove POWER9 PVR version check for entry and uaccess flushes") the condition for disabling the L1D flush on kernel entry and user access was changed from any non-P9 CPU to only checking P7 and P8. Without the appropriate device-tree checks for newer processors on powernv, these flushes are unnecessarily enabled on those systems. This patch corrects this.
--- arch/powerpc/platforms/powernv/setup.c | 6 ++++++ 1 file changed, 6 insertions(+)
arch/powerpc/platforms/powernv/setup.c +6 -0
@@ -96,6 +96,12 @@ static void __init init_fw_feat_flags(struct device_node *np)if (fw_feature_is ("disabled" ,"needs-spec-barrier-for-bound-checks" , np))security_ftr_clear (SEC_FTR_BNDS_CHK_SPEC_BAR ); + +if (fw_feature_is ("enabled" ,"no-need-l1d-flush-msr-pr-1-to-0" , np)) +security_ftr_clear (SEC_FTR_L1D_FLUSH_ENTRY ); + +if (fw_feature_is ("enabled" ,"no-need-l1d-flush-kernel-on-user-access" , np)) +security_ftr_clear (SEC_FTR_L1D_FLUSH_UACCESS ); }static void __init pnv_setup_security_mitigations (void )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 547/772 powerpc/powernv: Get STF barrier requirements from device-tree
In reply to Greg Kroah-HartmanFrom: Russell Currey <[email protected]>
[ Upstream commit d2a3c131981d4498571908df95c3c9393a00adf5 ]
The device-tree property no-need-store-drain-on-priv-state-switch is equivalent to H_CPU_BEHAV_NO_STF_BARRIER from the H_CPU_GET_CHARACTERISTICS hcall on pseries.
Since commit 84ed26fd00c5 ("powerpc/security: Add a security feature for STF barrier") powernv systems with this device-tree property have been enabling the STF barrier when they have no need for it. This patch fixes this by clearing the STF barrier feature on those systems.
--- arch/powerpc/platforms/powernv/setup.c | 3 +++ 1 file changed, 3 insertions(+)
arch/powerpc/platforms/powernv/setup.c +3 -0
@@ -102,6 +102,9 @@ static void __init init_fw_feat_flags(struct device_node *np)if (fw_feature_is ("enabled" ,"no-need-l1d-flush-kernel-on-user-access" , np))security_ftr_clear (SEC_FTR_L1D_FLUSH_UACCESS ); + +if (fw_feature_is ("enabled" ,"no-need-store-drain-on-priv-state-switch" , np)) +security_ftr_clear (SEC_FTR_STF_BARRIER ); }static void __init pnv_setup_security_mitigations (void )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 548/772 powerpc/perf: Fix the threshold compare group constraint for power10
In reply to Greg Kroah-HartmanFrom: Kajol Jain <[email protected]>
[ Upstream commit 505d31650ba96d6032313480fdb566d289a4698c ]
Thresh compare bits for a event is used to program thresh compare field in Monitor Mode Control Register A (MMCRA: 8-18 bits for power10). When scheduling events as a group, all events in that group should match value in threshold bits. Otherwise event open for the sibling events should fail. But in the current code, incase thresh compare bits are not valid, we are not failing in group_constraint function which can result in invalid group schduling.
Fix the issue by returning -1 incase event is threshold and threshold compare value is not valid in group_constraint function.
Patch also fixes the p10_thresh_cmp_val function to return -1, incase threshold bits are not valid and changes corresponding check in is_thresh_cmp_valid function to return false only when the thresh_cmp value is less then 0.
Thresh control bits in the event code is used to program thresh_ctl field in Monitor Mode Control Register A (MMCRA: 48-55). In below example, the scheduling of group events PM_MRK_INST_CMPL (3534401e0) and PM_THRESH_MET (34340101ec) is expected to fail as both event request different thresh control bits.
Result before the patch changes:
[command]# perf stat -e "{r35340401e0,r34340101ec}" sleep 1
Performance counter stats for 'sleep 1':
8,482 r35340401e0
0 r34340101ec
1.001474838 seconds time elapsed
0.001145000 seconds user
0.000000000 seconds sysResult after the patch changes:
[command]# perf stat -e "{r35340401e0,r34340101ec}" sleep 1
Performance counter stats for 'sleep 1':
<not counted> r35340401e0
<not supported> r34340101ec
1.001499607 seconds time elapsed
0.000204000 seconds user
0.000760000 seconds sys--- arch/powerpc/perf/isa207-common.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
arch/powerpc/perf/isa207-common.c +5 -4
@@ -108,7 +108,7 @@ static void mmcra_sdar_mode(u64 event, unsigned long *mmcra) *mmcra |=MMCRA_SDAR_MODE_TLB ; } -static u64 p10_thresh_cmp_val (u64 value) +static int p10_thresh_cmp_val (u64 value) {int exp =0 ;u64 result = value;
@@ -139,7 +139,7 @@ static u64 p10_thresh_cmp_val(u64 value)* exponent is also zero. */ if (!(value &0xC0 ) && exp) - result =0 ; + result =-1 ;else result = (exp <<8 ) | value; }
@@ -187,7 +187,7 @@ static bool is_thresh_cmp_valid(u64 event)unsigned int cmp, exp;if (cpu_has_feature (CPU_FTR_ARCH_31 )) -return p10_thresh_cmp_val (event) !=0 ; +return p10_thresh_cmp_val (event) >=0 ;/* * Check the mantissa upper two bits are not zero, unless the
@@ -502,7 +502,8 @@ int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp, value |=CNST_THRESH_CTL_SEL_VAL (event >>EVENT_THRESH_SHIFT ); mask |= p10_CNST_THRESH_CMP_MASK; value |=p10_CNST_THRESH_CMP_VAL (p10_thresh_cmp_val (event_config1)); - } + }else if (event_is_threshold (event)) +return -1 ; }else if (cpu_has_feature (CPU_FTR_ARCH_300 )) {if (event_is_threshold (event) &&is_thresh_cmp_valid (event)) { mask |=CNST_THRESH_MASK ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 549/772 powerpc/perf: Fix the threshold compare group constraint for power9
In reply to Greg Kroah-HartmanFrom: Kajol Jain <[email protected]>
[ Upstream commit ab0cc6bbf0c812731c703ec757fcc3fc3a457a34 ]
Thresh compare bits for a event is used to program thresh compare field in Monitor Mode Control Register A (MMCRA: 9-18 bits for power9). When scheduling events as a group, all events in that group should match value in threshold bits (like thresh compare, thresh control, thresh select). Otherwise event open for the sibling events should fail. But in the current code, incase thresh compare bits are not valid, we are not failing in group_constraint function which can result in invalid group schduling.
Fix the issue by returning -1 incase event is threshold and threshold compare value is not valid.
Thresh control bits in the event code is used to program thresh_ctl field in Monitor Mode Control Register A (MMCRA: 48-55). In below example, the scheduling of group events PM_MRK_INST_CMPL (873534401e0) and PM_THRESH_MET (8734340101ec) is expected to fail as both event request different thresh control bits and invalid thresh compare value.
Result before the patch changes:
[command]# perf stat -e "{r8735340401e0,r8734340101ec}" sleep 1
Performance counter stats for 'sleep 1':
11,048 r8735340401e0
1,967 r8734340101ec
1.001354036 seconds time elapsed
0.001421000 seconds user
0.000000000 seconds sysResult after the patch changes:
[command]# perf stat -e "{r8735340401e0,r8734340101ec}" sleep 1 Error:
The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (r8735340401e0)./bin/dmesg | grep -i perf may provide additional information.
--- arch/powerpc/perf/isa207-common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/powerpc/perf/isa207-common.c +2 -1
@@ -508,7 +508,8 @@ int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp,if (event_is_threshold (event) &&is_thresh_cmp_valid (event)) { mask |=CNST_THRESH_MASK ; value |=CNST_THRESH_VAL (event >>EVENT_THRESH_SHIFT ); - } + }else if (event_is_threshold (event)) +return -1 ; }else {/* * Special case for PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 550/772 macintosh: via-pmu and via-cuda need RTC_LIB
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
[ Upstream commit 9a9c5ff5fff87eb1a43db0d899473554e408fd7b ]
Fix build when RTC_LIB is not set/enabled.
Eliminates these build errors:
m68k-linux-ld: drivers/macintosh/via-pmu.o: in function `pmu_set_rtc_time':drivers/macintosh/via-pmu.c:1769: undefined reference to `rtc_tm_to_time64'
m68k-linux-ld: drivers/macintosh/via-cuda.o: in function `cuda_set_rtc_time':drivers/macintosh/via-cuda.c:797: undefined reference to `rtc_tm_to_time64'
--- drivers/macintosh/Kconfig | 2 ++ 1 file changed, 2 insertions(+)
drivers/macintosh/Kconfig +2 -0
@@ -44,6 +44,7 @@ config ADB_IOP config ADB_CUDA bool "Support for Cuda/Egret based Macs and PowerMacs" depends on (ADB || PPC_PMAC) && !PPC_PMAC64 + select RTC_LIB help This provides support for Cuda/Egret based Macintosh and Power Macintosh systems. This includes most m68k based Macs,
@@ -57,6 +58,7 @@ config ADB_CUDA config ADB_PMU bool "Support for PMU based PowerMacs and PowerBooks" depends on PPC_PMAC || MAC + select RTC_LIB help On PowerBooks, iBooks, and recent iMacs and Power Macintoshes, the PMU is an embedded microprocessor whose primary function is to
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 551/772 powerpc/xive: Add some error handling code to xive_spapr_init()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit e414e2938ee26e734f19e92a60cd090ebaff37e6 ]
'xive_irq_bitmap_add()' can return -ENOMEM.
In this case, we should free the memory already allocated and return 'false' to the caller.
Also add an error path which undoes the 'tima = ioremap(...)'
--- arch/powerpc/sysdev/xive/spapr.c | 36 +++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-)
arch/powerpc/sysdev/xive/spapr.c +28 -8
@@ -67,6 +67,17 @@ static int __init xive_irq_bitmap_add(int base, int count)return 0 ; } +static void xive_irq_bitmap_remove_all (void ) +{ +struct xive_irq_bitmap *xibm, *tmp; + +list_for_each_entry_safe (xibm, tmp, &xive_irq_bitmaps, list) { +list_del (&xibm->list); +kfree (xibm->bitmap); +kfree (xibm); + } +} +static int __xive_irq_bitmap_alloc (struct xive_irq_bitmap *xibm) {int irq;
@@ -803,7 +814,7 @@ bool __init xive_spapr_init(void)u32 val;u32 len;const __be32 *reg; -int i; +int i, err;if (xive_spapr_disabled ())return false;
@@ -828,23 +839,26 @@ bool __init xive_spapr_init(void) }if (!xive_get_max_prio (&max_prio)) -return false; + goto err_unmap;/* Feed the IRQ number allocator with the ranges given in the DT */ reg =of_get_property (np,"ibm,xive-lisn-ranges" , &len);if (!reg) {pr_err ("Failed to read 'ibm,xive-lisn-ranges' property\n" ); -return false; + goto err_unmap; }if (len % (2 *sizeof (u32)) !=0 ) {pr_err ("invalid 'ibm,xive-lisn-ranges' property\n" ); -return false; + goto err_unmap; } -for (i =0 ; i < len / (2 *sizeof (u32)); i++, reg +=2 ) -xive_irq_bitmap_add (be32_to_cpu (reg[0 ]), -be32_to_cpu (reg[1 ])); +for (i =0 ; i < len / (2 *sizeof (u32)); i++, reg +=2 ) { + err =xive_irq_bitmap_add (be32_to_cpu (reg[0 ]), +be32_to_cpu (reg[1 ])); +if (err <0 ) + goto err_mem_free; + }/* Iterate the EQ sizes and pick one */ of_property_for_each_u32 (np,"ibm,xive-eq-sizes" , prop, reg, val) {
@@ -855,10 +869,16 @@ bool __init xive_spapr_init(void)/* Initialize XIVE core with our backend */ if (!xive_core_init (np, &xive_spapr_ops, tima,TM_QW1_OS , max_prio)) -return false; + goto err_mem_free;pr_info ("Using %dkB queues\n" ,1 << (xive_queue_shift -10 ));return true; + +err_mem_free: +xive_irq_bitmap_remove_all (); +err_unmap: +iounmap (tima); +return false; }machine_arch_initcall (pseries, xive_core_debug_init);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 552/772 powerpc/xive: Fix refcount leak in xive_spapr_init
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 1d1fb9618bdd5a5fbf9a9eb75133da301d33721c ]
of_find_compatible_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when done. Add missing of_node_put() to avoid refcount leak.
--- arch/powerpc/sysdev/xive/spapr.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
arch/powerpc/sysdev/xive/spapr.c +5 -2
@@ -830,12 +830,12 @@ bool __init xive_spapr_init(void)/* Resource 1 is the OS ring TIMA */ if (of_address_to_resource (np,1 , &r)) {pr_err ("Failed to get thread mgmnt area resource\n" ); -return false; + goto err_put; } tima =ioremap (r.start,resource_size (&r));if (!tima) {pr_err ("Failed to map thread mgmnt area\n" ); -return false; + goto err_put; }if (!xive_get_max_prio (&max_prio))
@@ -871,6 +871,7 @@ bool __init xive_spapr_init(void)if (!xive_core_init (np, &xive_spapr_ops, tima,TM_QW1_OS , max_prio)) goto err_mem_free; +of_node_put (np);pr_info ("Using %dkB queues\n" ,1 << (xive_queue_shift -10 ));return true;
@@ -878,6 +879,8 @@ bool __init xive_spapr_init(void)xive_irq_bitmap_remove_all (); err_unmap:iounmap (tima); +err_put: +of_node_put (np);return false; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 553/772 powerpc/fsl_rio: Fix refcount leak in fsl_rio_setup
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit fcee96924ba1596ca80a6770b2567ca546f9a482 ]
of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
--- arch/powerpc/sysdev/fsl_rio.c | 2 ++ 1 file changed, 2 insertions(+)
arch/powerpc/sysdev/fsl_rio.c +2 -0
@@ -505,8 +505,10 @@ int fsl_rio_setup(struct platform_device *dev)if (rc) {dev_err (&dev->dev,"Can't get %pOF property 'reg'\n" , rmu_node); +of_node_put (rmu_node); goto err_rmu; } +of_node_put (rmu_node); rmu_regs_win =ioremap (rmu_regs.start,resource_size (&rmu_regs));if (!rmu_regs_win) {dev_err (&dev->dev,"Unable to map rmu register window\n" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 554/772 powerpc/fsl_book3e: Dont set rodata RO too early
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
[ Upstream commit ad91f66f5fa7c6f9346e721c3159ce818568028b ]
On fsl_book3e, rodata is set read-only at the same time as init text is set NX at the end of init. That's too early.
As both action are performed at the same time, delay both actions to the time rodata is expected to be made read-only.
It means we will have a small window with init mem freed but still executable. It shouldn't be an issue though, especially because the said memory gets poisoned and should therefore result to a bad instruction fault in case it gets executed.
mmu_mark_initmem_nx() is bailing out before doing anything when CONFIG_STRICT_KERNEL_RWX is not selected or rodata_enabled is false.
mmu_mark_rodata_ro() is called only when CONFIG_STRICT_KERNEL_RWX is selected and rodata_enabled is true so this is equivalent.
Move code from mmu_mark_initmem_nx() into mmu_mark_rodata_ro() and remove the call to strict_kernel_rwx_enabled() which is not needed anymore.
--- arch/powerpc/mm/nohash/fsl_book3e.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
arch/powerpc/mm/nohash/fsl_book3e.c +6 -9
@@ -287,22 +287,19 @@ void __init adjust_total_lowmem(void)#ifdef CONFIG_STRICT_KERNEL_RWX void mmu_mark_rodata_ro (void ) -{ -/* Everything is done in mmu_mark_initmem_nx() */ -} -#endif - -void mmu_mark_initmem_nx (void ) {unsigned long remapped; -if (!strict_kernel_rwx_enabled ()) -return ; - remapped =map_mem_in_cams (__max_low_memory,CONFIG_LOWMEM_CAM_NUM , false, false);WARN_ON (__max_low_memory != remapped); } +#endif + +void mmu_mark_initmem_nx (void ) +{ +/* Everything is done in mmu_mark_rodata_ro() */ +}void setup_initial_memory_limit (phys_addr_t first_memblock_base,phys_addr_t first_memblock_size)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 555/772 gpio: sim: Use correct order for the parameters of devm_kcalloc()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit c680c6a814a2269427fad9ac417ab16756bceae9 ]
We should have 'n', then 'size', not the opposite.
This is harmless because the 2 values are just multiplied, but having the correct order silence a (unpublished yet) smatch warning.
--- drivers/gpio/gpio-sim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpio/gpio-sim.c +2 -2
@@ -314,8 +314,8 @@ static int gpio_sim_setup_sysfs(struct gpio_sim_chip *chip)for (i =0 ; i < num_lines; i++) { attr_group =devm_kzalloc (dev,sizeof (*attr_group),GFP_KERNEL ); - attrs =devm_kcalloc (dev,sizeof (*attrs), -GPIO_SIM_NUM_ATTRS ,GFP_KERNEL ); + attrs =devm_kcalloc (dev,GPIO_SIM_NUM_ATTRS ,sizeof (*attrs), +GFP_KERNEL ); val_attr =devm_kzalloc (dev,sizeof (*val_attr),GFP_KERNEL ); pull_attr =devm_kzalloc (dev,sizeof (*pull_attr),GFP_KERNEL );if (!attr_group || !attrs || !val_attr || !pull_attr)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 556/772 mfd: davinci_voicecodec: Fix possible null-ptr-deref davinci_vc_probe()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 311242c7703df0da14c206260b7e855f69cb0264 ]
It will cause null-ptr-deref when using 'res', if platform_get_resource() returns NULL, so move using 'res' after devm_ioremap_resource() that will check it to avoid null-ptr-deref.
And use devm_platform_get_and_ioremap_resource() to simplify code.
--- drivers/mfd/davinci_voicecodec.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/mfd/davinci_voicecodec.c +2 -4
@@ -46,14 +46,12 @@ static int __init davinci_vc_probe(struct platform_device *pdev) }clk_enable (davinci_vc->clk); - res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); - - fifo_base = (dma_addr_t )res->start; - davinci_vc->base =devm_ioremap_resource (&pdev->dev, res); + davinci_vc->base =devm_platform_get_and_ioremap_resource (pdev,0 , &res);if (IS_ERR (davinci_vc->base)) { ret =PTR_ERR (davinci_vc->base); goto fail; } + fifo_base = (dma_addr_t )res->start; davinci_vc->regmap = devm_regmap_init_mmio(&pdev->dev, davinci_vc->base,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 557/772 nfsd: destroy percpu stats counters after reply cache shutdown
In reply to Greg Kroah-HartmanFrom: Julian Schroeder <[email protected]>
[ Upstream commit fd5e363eac77ef81542db77ddad0559fa0f9204e ]
Upon nfsd shutdown any pending DRC cache is freed. DRC cache use is tracked via a percpu counter. In the current code the percpu counter is destroyed before. If any pending cache is still present, percpu_counter_add is called with a percpu counter==NULL. This causes a kernel crash.
The solution is to destroy the percpu counter after the cache is freed.
--- fs/nfsd/nfscache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/nfscache.c +1 -1
@@ -212,7 +212,6 @@ void nfsd_reply_cache_shutdown(struct nfsd_net *nn)struct svc_cacherep *rp;unsigned int i; -nfsd_reply_cache_stats_destroy (nn);unregister_shrinker (&nn->nfsd_reply_cache_shrinker);for (i =0 ; i < nn->drc_hashsize; i++) {
@@ -223,6 +222,7 @@ void nfsd_reply_cache_shutdown(struct nfsd_net *nn) rp, nn); } } +nfsd_reply_cache_stats_destroy (nn);kvfree (nn->drc_hashtbl); nn->drc_hashtbl =NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 558/772 mailbox: forward the hrtimer if not queued and under a lock
In reply to Greg Kroah-HartmanFrom: Björn Ardö <[email protected]>
[ Upstream commit bca1a1004615efe141fd78f360ecc48c60bc4ad5 ]
This reverts commit c7dacf5b0f32957b24ef29df1207dc2cd8307743, "mailbox: avoid timer start from callback"
The previous commit was reverted since it lead to a race that caused the hrtimer to not be started at all. The check for hrtimer_active() in msg_submit() will return true if the callback function txdone_hrtimer() is currently running. This function could return HRTIMER_NORESTART and then the timer will not be restarted, and also msg_submit() will not start the timer. This will lead to a message actually being submitted but no timer will start to check for its compleation.
The original fix that added checking hrtimer_active() was added to avoid a warning with hrtimer_forward. Looking in the kernel another solution to avoid this warning is to check hrtimer_is_queued() before calling hrtimer_forward_now() instead. This however requires a lock so the timer is not started by msg_submit() inbetween this check and the hrtimer_forward() call.
--- drivers/mailbox/mailbox.c | 19 +++++++++++++------ include/linux/mailbox_controller.h | 1 + 2 files changed, 14 insertions(+), 6 deletions(-)
drivers/mailbox/mailbox.c +13 -6
@@ -82,11 +82,11 @@ static void msg_submit(struct mbox_chan *chan) exit:spin_unlock_irqrestore (&chan->lock, flags); -/* kick start the timer immediately to avoid delays */ if (!err && (chan->txdone_method &TXDONE_BY_POLL )) { -/* but only if not already active */ -if (!hrtimer_active (&chan->mbox->poll_hrt)) -hrtimer_start (&chan->mbox->poll_hrt,0 ,HRTIMER_MODE_REL ); +/* kick start the timer immediately to avoid delays */ +spin_lock_irqsave (&chan->mbox->poll_hrt_lock, flags); +hrtimer_start (&chan->mbox->poll_hrt,0 ,HRTIMER_MODE_REL ); +spin_unlock_irqrestore (&chan->mbox->poll_hrt_lock, flags); } }
@@ -120,20 +120,26 @@ static enum hrtimer_restart txdone_hrtimer(struct hrtimer *hrtimer) container_of(hrtimer, struct mbox_controller, poll_hrt);bool txdone, resched = false;int i; +unsigned long flags;for (i =0 ; i < mbox->num_chans; i++) {struct mbox_chan *chan = &mbox->chans[i];if (chan->active_req && chan->cl) { - resched = true; txdone = chan->mbox->ops->last_tx_done (chan);if (txdone)tx_tick (chan,0 ); +else + resched = true; } }if (resched) { -hrtimer_forward_now (hrtimer,ms_to_ktime (mbox->txpoll_period)); +spin_lock_irqsave (&mbox->poll_hrt_lock, flags); +if (!hrtimer_is_queued (hrtimer)) +hrtimer_forward_now (hrtimer,ms_to_ktime (mbox->txpoll_period)); +spin_unlock_irqrestore (&mbox->poll_hrt_lock, flags); +return HRTIMER_RESTART ; }return HRTIMER_NORESTART ;
@@ -500,6 +506,7 @@ int mbox_controller_register(struct mbox_controller *mbox)hrtimer_init (&mbox->poll_hrt,CLOCK_MONOTONIC ,HRTIMER_MODE_REL ); mbox->poll_hrt.function = txdone_hrtimer; +spin_lock_init (&mbox->poll_hrt_lock); }for (i =0 ; i < mbox->num_chans; i++) {
include/linux/mailbox_controller.h +1 -0
@@ -83,6 +83,7 @@ struct mbox_controller { const struct of_phandle_args *sp);/* Internal to API */ struct hrtimer poll_hrt; +spinlock_t poll_hrt_lock;struct list_head node; };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 559/772 RDMA/hfi1: Prevent use of lock before it is initialized
In reply to Greg Kroah-HartmanFrom: Douglas Miller <[email protected]>
[ Upstream commit 05c03dfd09c069c4ffd783b47b2da5dcc9421f2c ]
If there is a failure during probe of hfi1 before the sdma_map_lock is initialized, the call to hfi1_free_devdata() will attempt to use a lock that has not been initialized. If the locking correctness validator is on then an INFO message and stack trace resembling the following may be seen:
INFO: trying to register non-static key.
The code is fine but needs lockdep annotation, or maybe you didn't initialize this object before use? turning off the locking correctness validator.
Call Trace: register_lock_class+0x11b/0x880 __lock_acquire+0xf3/0x7930 lock_acquire+0xff/0x2d0 _raw_spin_lock_irq+0x46/0x60 sdma_clean+0x42a/0x660 [hfi1] hfi1_free_devdata+0x3a7/0x420 [hfi1] init_one+0x867/0x11a0 [hfi1] pci_device_probe+0x40e/0x8d0
The use of sdma_map_lock in sdma_clean() is for freeing the sdma_map memory, and sdma_map is not allocated/initialized until after sdma_map_lock has been initialized. This code only needs to be run if sdma_map is not NULL, and so checking for that condition will avoid trying to use the lock before it is initialized.
--- drivers/infiniband/hw/hfi1/sdma.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/infiniband/hw/hfi1/sdma.c +7 -5
@@ -1288,11 +1288,13 @@ void sdma_clean(struct hfi1_devdata *dd, size_t num_engines)kvfree (sde->tx_ring); sde->tx_ring =NULL ; } -spin_lock_irq (&dd->sde_map_lock); -sdma_map_free (rcu_access_pointer (dd->sdma_map)); -RCU_INIT_POINTER (dd->sdma_map,NULL ); -spin_unlock_irq (&dd->sde_map_lock); -synchronize_rcu (); +if (rcu_access_pointer (dd->sdma_map)) { +spin_lock_irq (&dd->sde_map_lock); +sdma_map_free (rcu_access_pointer (dd->sdma_map)); +RCU_INIT_POINTER (dd->sdma_map,NULL ); +spin_unlock_irq (&dd->sde_map_lock); +synchronize_rcu (); + }kfree (dd->per_sdma); dd->per_sdma =NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 560/772 pinctrl: apple: Use a raw spinlock for the regmap
In reply to Greg Kroah-HartmanFrom: Hector Martin <[email protected]>
[ Upstream commit 83969805cc716a7dc6b296c3fb1bc7e5cd7ca321 ]
The irqchip ops are called with a raw spinlock held, so the subsequent regmap usage cannot use a plain spinlock.
spi-hid-apple-of spi0.0: spihid_apple_of_probe:74
=============================
[ BUG: Invalid wait context ]
5.18.0-asahi-00176-g0fa3ab03bdea #1337 Not tainted
-----------------------------
kworker/u20:3/86 is trying to lock:ffff8000166b5018 (pinctrl_apple_gpio:462:(®map_config)->lock){....}-{3:3}, at: regmap_lock_spinlock+0x18/0x30 other info that might help us debug this:
context-{5:5}
7 locks held by kworker/u20:3/86:
#0: ffff800017725d48 ((wq_completion)events_unbound){+.+.}-{0:0}, at: process_one_work+0x1c8/0x670 #1: ffff80001e33bdd0 (deferred_probe_work){+.+.}-{0:0}, at: process_one_work+0x1c8/0x670
#2: ffff800017d629a0 (&dev->mutex){....}-{4:4}, at: __device_attach+0x30/0x17c
#3: ffff80002414e618 (&ctlr->add_lock){+.+.}-{4:4}, at: spi_add_device+0x40/0x80
#4: ffff800024116990 (&dev->mutex){....}-{4:4}, at: __device_attach+0x30/0x17c
#5: ffff800022d4be58 (request_class){+.+.}-{4:4}, at: __setup_irq+0xa8/0x720
#6: ffff800022d4bcc8 (lock_class){....}-{2:2}, at: __setup_irq+0xcc/0x720
--- drivers/pinctrl/pinctrl-apple-gpio.c | 1 + 1 file changed, 1 insertion(+)
drivers/pinctrl/pinctrl-apple-gpio.c +1 -0
@@ -72,6 +72,7 @@ struct regmap_config regmap_config = { .max_register = 512 * sizeof(u32), .num_reg_defaults_raw = 512, .use_relaxed_mmio = true, + .use_raw_spinlock = true, };/* No locking needed to mask/unmask IRQs as the interrupt mode is per pin-register. */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 561/772 KVM: LAPIC: Drop pending LAPIC timer injection when canceling the timer
In reply to Greg Kroah-HartmanFrom: Wanpeng Li <[email protected]>
[ Upstream commit 619f51da097952194a5d4d6a6c5f9ef3b9d1b25a ]
The timer is disarmed when switching between TSC deadline and other modes; however, the pending timer is still in-flight, so let's accurately remove any traces of the previous mode.
--- arch/x86/kvm/lapic.c | 1 + 1 file changed, 1 insertion(+)
arch/x86/kvm/lapic.c +1 -0
@@ -1508,6 +1508,7 @@ static void cancel_apic_timer(struct kvm_lapic *apic)if (apic->lapic_timer.hv_timer_in_use)cancel_hv_timer (apic);preempt_enable (); +atomic_set (&apic->lapic_timer.pending,0 ); }static void apic_update_lvtt (struct kvm_lapic *apic)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 562/772 Input: stmfts - do not leave device disabled in stmfts_input_open
In reply to Greg Kroah-HartmanFrom: Dmitry Torokhov <[email protected]>
[ Upstream commit 5f76955ab1e43e5795a9631b22ca4f918a0ae986 ]
The commit 26623eea0da3 attempted to deal with potential leak of runtime PM counter when opening the touchscreen device, however it ended up erroneously dropping the counter in the case of successfully enabling the device.
Let's address this by using pm_runtime_resume_and_get() and then executing pm_runtime_put_sync() only when we fail to send "sense on" command to the device.
--- drivers/input/touchscreen/stmfts.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/input/touchscreen/stmfts.c +8 -8
@@ -337,13 +337,15 @@ static int stmfts_input_open(struct input_dev *dev)struct stmfts_data *sdata =input_get_drvdata (dev);int err; - err =pm_runtime_get_sync (&sdata->client->dev); -if (err <0 ) - goto out; + err =pm_runtime_resume_and_get (&sdata->client->dev); +if (err) +return err; err =i2c_smbus_write_byte (sdata->client,STMFTS_MS_MT_SENSE_ON ); -if (err) - goto out; +if (err) { +pm_runtime_put_sync (&sdata->client->dev); +return err; + }mutex_lock (&sdata->mutex); sdata->running = true;
@@ -366,9 +368,7 @@ static int stmfts_input_open(struct input_dev *dev) "failed to enable touchkey\n"); } -out: -pm_runtime_put_noidle (&sdata->client->dev); -return err; +return 0 ; }static void stmfts_input_close (struct input_dev *dev)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 563/772 OPP: call of_node_put() on error path in _bandwidth_supported()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 907ed123b9d096c73e9361f6cd4097f0691497f2 ]
This code does not call of_node_put(opp_np) if of_get_next_available_child() returns NULL. But it should.
--- drivers/opp/of.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/opp/of.c +1 -1
@@ -437,11 +437,11 @@ static int _bandwidth_supported(struct device *dev, struct opp_table *opp_table)/* Checking only first OPP is sufficient */ np =of_get_next_available_child (opp_np,NULL ); +of_node_put (opp_np);if (!np) {dev_err (dev,"OPP table empty\n" );return -EINVAL ; } -of_node_put (opp_np); prop =of_find_property (np,"opp-peak-kBps" ,NULL );of_node_put (np);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 564/772 f2fs: fix to do sanity check on inline_dots inode
In reply to Greg Kroah-HartmanFrom: Chao Yu <[email protected]>
[ Upstream commit 12662d19467b391b5b509ac5e9ab4f583c6dde16 ]
As Wenqing reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=215765
It will cause a kernel panic with steps:
- mkdir mnt
- mount tmp40.img mnt
- ls mnt
folio_mark_dirty+0x33/0x50 f2fs_add_regular_entry+0x541/0xad0 [f2fs] f2fs_add_dentry+0x6c/0xb0 [f2fs] f2fs_do_add_link+0x182/0x230 [f2fs] __recover_dot_dentries+0x2d6/0x470 [f2fs] f2fs_lookup+0x5af/0x6a0 [f2fs] __lookup_slow+0xac/0x200 lookup_slow+0x45/0x70 walk_component+0x16c/0x250 path_lookupat+0x8b/0x1f0 filename_lookup+0xef/0x250 user_path_at_empty+0x46/0x70 vfs_statx+0x98/0x190 __do_sys_newlstat+0x41/0x90 __x64_sys_newlstat+0x1a/0x30 do_syscall_64+0x37/0xb0 entry_SYSCALL_64_after_hwframe+0x44/0xae
The root cause is for special file: e.g. character, block, fifo or socket file, f2fs doesn't assign address space operations pointer array for mapping->a_ops field, so, in a fuzzed image, if inline_dots flag was tagged in special file, during lookup(), when f2fs runs into __recover_dot_dentries(), it will cause NULL pointer access once f2fs_add_regular_entry() calls a_ops->set_dirty_page().
--- fs/f2fs/namei.c | 7 +++++++ 1 file changed, 7 insertions(+)
fs/f2fs/namei.c +7 -0
@@ -460,6 +460,13 @@ static int __recover_dot_dentries(struct inode *dir, nid_t pino)return 0 ; } +if (!S_ISDIR (dir->i_mode)) { +f2fs_err (sbi,"inconsistent inode status, skip recovering inline_dots inode (ino:%lu, i_mode:%u, pino:%u)" , + dir->i_ino, dir->i_mode, pino); +set_sbi_flag (sbi,SBI_NEED_FSCK ); +return -ENOTDIR ; + } + err =f2fs_dquot_initialize (dir);if (err)return err;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 565/772 f2fs: fix dereference of stale list iterator after loop body
In reply to Greg Kroah-HartmanFrom: Jakob Koschel <[email protected]>
[ Upstream commit 2aaf51dd39afb6d01d13f1e6fe20b684733b37d5 ]
The list iterator variable will be a bogus pointer if no break was hit. Dereferencing it (cur->page in this case) could load an out-of-bounds/undefined value making it unsafe to use that in the comparision to determine if the specific element was found.
Since 'cur->page' *can* be out-ouf-bounds it cannot be guaranteed that by chance (or intention of an attacker) it matches the value of 'page' even though the correct element was not found.
This is fixed by using a separate list iterator variable for the loop and only setting the original variable if a suitable element was found. Then determing if the element was found is simply checking if the variable is set.
--- fs/f2fs/segment.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
fs/f2fs/segment.c +6 -3
@@ -356,16 +356,19 @@ void f2fs_drop_inmem_page(struct inode *inode, struct page *page)struct f2fs_sb_info *sbi =F2FS_I_SB (inode);struct list_head *head = &fi->inmem_pages;struct inmem_pages *cur =NULL ; +struct inmem_pages *tmp;f2fs_bug_on (sbi, !page_private_atomic (page));mutex_lock (&fi->inmem_lock); -list_for_each_entry (cur, head, list) { -if (cur->page == page) +list_for_each_entry (tmp, head, list) { +if (tmp->page == page) { + cur = tmp;break ; + } } -f2fs_bug_on (sbi,list_empty (head) || cur->page != page); +f2fs_bug_on (sbi, !cur);list_del (&cur->list);mutex_unlock (&fi->inmem_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 566/772 riscv: Fixup difference with defconfig
In reply to Greg Kroah-HartmanFrom: Guo Ren <[email protected]>
[ Upstream commit 72f045d19f25f19be6d7682d5b1d948e20580817 ]
Let's follow the origin patch's spirit:
The only difference between rv32_defconfig and defconfig is that rv32_defconfig has CONFIG_ARCH_RV32I=y.
This is helpful to compare rv64-compat-rv32 v.s. rv32-linux.
--- arch/riscv/Makefile | 4 ++++ 1 file changed, 4 insertions(+)
arch/riscv/Makefile +4 -0
@@ -154,3 +154,7 @@ PHONY += rv64_randconfig rv64_randconfig: $(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/riscv/configs/64-bit.config \ -f $(srctree)/Makefile randconfig + +PHONY += rv32_defconfig +rv32_defconfig: + $(Q)$(MAKE) -f $(srctree)/Makefile defconfig 32-bit.config
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 567/772 iommu/amd: Enable swiotlb in all cases
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
[ Upstream commit 121660bba631104154b7c15e88f208c48c8c3297 ]
Previously the AMD IOMMU would only enable SWIOTLB in certain circumstances:
* IOMMU in passthrough mode
* SME enabled
This logic however doesn't work when an untrusted device is plugged in that doesn't do page aligned DMA transactions. The expectation is that a bounce buffer is used for those transactions.
This fails like this:
swiotlb buffer is full (sz: 4096 bytes), total 0 (slots), used 0 (slots)
That happens because the bounce buffers have been allocated, followed by freed during startup but the bounce buffering code expects that all IOMMUs have left it enabled.
Remove the criteria to set up bounce buffers on AMD systems to ensure they're always available for supporting untrusted devices.
--- drivers/iommu/amd/iommu.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/iommu/amd/iommu.c +0 -7
@@ -1838,17 +1838,10 @@ void amd_iommu_domain_update(struct protection_domain *domain)amd_iommu_domain_flush_complete (domain); } -static void __init amd_iommu_init_dma_ops (void ) -{ - swiotlb = (iommu_default_passthrough () || sme_me_mask) ?1 :0 ; -} -int __init amd_iommu_init_api (void ) {int err; -amd_iommu_init_dma_ops (); - err =bus_set_iommu (&pci_bus_type, &amd_iommu_ops);if (err)return err;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 568/772 iommu/mediatek: Fix 2 HW sharing pgtable issue
In reply to Greg Kroah-HartmanFrom: Yong Wu <[email protected]>
[ Upstream commit 645b87c190c959e9bb4f216b8c4add4ee880451a ]
In the commit 4f956c97d26b ("iommu/mediatek: Move domain_finalise into attach_device"), I overlooked the sharing pgtable case. After that commit, the "data" in the mtk_iommu_domain_finalise always is the data of the current IOMMU HW. Fix this for the sharing pgtable case.
Only affect mt2712 which is the only SoC that share pgtable currently.
--- drivers/iommu/mtk_iommu.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/iommu/mtk_iommu.c +5 -2
@@ -451,7 +451,7 @@ static void mtk_iommu_domain_free(struct iommu_domain *domain)static int mtk_iommu_attach_device (struct iommu_domain *domain,struct device *dev) { -struct mtk_iommu_data *data =dev_iommu_priv_get (dev); +struct mtk_iommu_data *data =dev_iommu_priv_get (dev), *frstdata;struct mtk_iommu_domain *dom =to_mtk_domain (domain);struct device *m4udev = data->dev;int ret, domid;
@@ -461,7 +461,10 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,return domid;if (!dom->data) { -if (mtk_iommu_domain_finalise (dom, data, domid)) +/* Data is in the frstdata in sharing pgtable case. */ + frstdata =mtk_iommu_get_m4u_data (); + +if (mtk_iommu_domain_finalise (dom, frstdata, domid))return -ENODEV ; dom->data = data; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 569/772 iommu/mediatek: Add list_del in mtk_iommu_remove
In reply to Greg Kroah-HartmanFrom: Yong Wu <[email protected]>
[ Upstream commit ee55f75e4bcade81d253163641b63bef3e76cac4 ]
Lack the list_del in the mtk_iommu_remove, and remove bus_set_iommu(*, NULL) since there may be several iommu HWs. we can not bus_set_iommu null when one iommu driver unbind.
This could be a fix for mt2712 which support 2 M4U HW and list them.
--- drivers/iommu/mtk_iommu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/iommu/mtk_iommu.c +1 -2
@@ -954,8 +954,7 @@ static int mtk_iommu_remove(struct platform_device *pdev)iommu_device_sysfs_remove (&data->iommu);iommu_device_unregister (&data->iommu); -if (iommu_present (&platform_bus_type)) -bus_set_iommu (&platform_bus_type,NULL ); +list_del (&data->list);clk_disable_unprepare (data->bclk);device_link_remove (data->smicomm_dev, &pdev->dev);
Signature · 1 line
2.35.1