5.18.4-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainerPATCH 148/339 perf parse-events: Move slots event for the hybrid platform too
In reply to Greg Kroah-HartmanFrom: Kan Liang <[email protected]>
[ Upstream commit e0e14cdff31d326f81e0edbd5140f788c870756c ]
The commit 94dbfd6781a0e87b ("perf parse-events: Architecture specific leader override") introduced a feature to reorder the slots event to fulfill the restriction of the perf metrics topdown group. But the feature doesn't work on the hybrid machine.
$ perf stat -e "{cpu_core/instructions/,cpu_core/slots/,cpu_core/topdown-retiring/}" -a sleep 1Performance counter stats for 'system wide':
<not counted> cpu_core/instructions/
<not counted> cpu_core/slots/
<not supported> cpu_core/topdown-retiring/1.002871801 seconds time elapsed
A hybrid platform has a different PMU name for the core PMUs, while current perf hard code the PMU name "cpu".
Introduce a new function to check whether the system supports the perf metrics feature. The result is cached for the future usage.
For X86, the core PMU name always has "cpu" prefix.
With the patch:
$ perf stat -e "{cpu_core/instructions/,cpu_core/slots/,cpu_core/topdown-retiring/}" -a sleep 1Performance counter stats for 'system wide':
76,337,010 cpu_core/slots/
10,416,809 cpu_core/instructions/
11,692,372 cpu_core/topdown-retiring/1.002805453 seconds time elapsed
--- tools/perf/arch/x86/util/evlist.c | 5 +++-- tools/perf/arch/x86/util/topdown.c | 25 +++++++++++++++++++++++++ tools/perf/arch/x86/util/topdown.h | 7 +++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 tools/perf/arch/x86/util/topdown.h
tools/perf/arch/x86/util/evlist.c +3 -2
@@ -3,6 +3,7 @@#include "util/pmu.h" #include "util/evlist.h" #include "util/parse-events.h" +#include "topdown.h" #define TOPDOWN_L1_EVENTS "{slots,topdown-retiring,topdown-bad-spec,topdown-fe-bound,topdown-be-bound}"#define TOPDOWN_L2_EVENTS "{slots,topdown-retiring,topdown-bad-spec,topdown-fe-bound,topdown-be-bound,topdown-heavy-ops,topdown-br-mispredict,topdown-fetch-lat,topdown-mem-bound}"
@@ -25,12 +26,12 @@ struct evsel *arch_evlist__leader(struct list_head *list) first = list_first_entry(list, struct evsel, core.node); -if (!pmu_have_event ("cpu" ,"slots" )) +if (!topdown_sys_has_perf_metrics ())return first;/* If there is a slots event and a topdown event then the slots event comes first. */ __evlist__for_each_entry (list, evsel) { -if (evsel->pmu_name && !strcmp (evsel->pmu_name,"cpu" ) && evsel->name) { +if (evsel->pmu_name && !strncmp (evsel->pmu_name,"cpu" ,3 ) && evsel->name) {if (strcasestr (evsel->name,"slots" )) { slots = evsel;if (slots == first)
tools/perf/arch/x86/util/topdown.c +25 -0
@@ -3,6 +3,31 @@#include "api/fs/fs.h" #include "util/pmu.h" #include "util/topdown.h" +#include "topdown.h" + +/* Check whether there is a PMU which supports the perf metrics. */ +bool topdown_sys_has_perf_metrics (void ) +{ +static bool has_perf_metrics; +static bool cached; +struct perf_pmu *pmu; + +if (cached) +return has_perf_metrics; + +/* +* The perf metrics feature is a core PMU feature. +* The PERF_TYPE_RAW type is the type of a core PMU. +* The slots event is only available when the core PMU +* supports the perf metrics feature. +*/ + pmu =perf_pmu__find_by_type (PERF_TYPE_RAW ); +if (pmu &&pmu_have_event (pmu->name,"slots" )) + has_perf_metrics = true; + + cached = true; +return has_perf_metrics; +}/* * Check whether we can use a group for top down.
tools/perf/arch/x86/util/topdown.h new file +7 -0
@@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _TOPDOWN_H +#define _TOPDOWN_H 1 + +bool topdown_sys_has_perf_metrics (void ); + +#endif
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 149/339 perf record: Support sample-read topdown metric group for hybrid platforms
In reply to Greg Kroah-HartmanFrom: Zhengjun Xing <[email protected]>
[ Upstream commit 151e7d75036b4e2ac0f33730bc1a5b3ff424d9a7 ]
With the hardware TopDown metrics feature, the sample-read feature should be supported for a TopDown group, e.g., sample a non-topdown event and read a Topdown metric group. But the current perf record code errors are out.
For a TopDown metric group,the slots event must be the leader of the group, but the leader slots event doesn't support sampling. To support sample-read the TopDown metric group, uses the 2nd event of the group as the "leader" for the purposes of sampling.
Only the platform with the TopDown metric feature supports sample-read the topdown group. In commit acb65150a47c ("perf record: Support sample-read topdown metric group"), it adds arch_topdown_sample_read() to indicate whether the TopDown group supports sample-read, it should only work on the non-hybrid systems, this patch extends the support for hybrid platforms.
Before:
# ./perf record -e "{cpu_core/slots/,cpu_core/cycles/,cpu_core/topdown-retiring/}:S" -a sleep 1
Error:
The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (cpu_core/topdown-retiring/).
/bin/dmesg | grep -i perf may provide additional information.After:
# ./perf record -e "{cpu_core/slots/,cpu_core/cycles/,cpu_core/topdown-retiring/}:S" -a sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.238 MB perf.data (369 samples) ]--- tools/perf/arch/x86/util/evsel.c | 3 ++- tools/perf/arch/x86/util/evsel.h | 7 +++++++ tools/perf/arch/x86/util/topdown.c | 21 ++++----------------- 3 files changed, 13 insertions(+), 18 deletions(-) create mode 100644 tools/perf/arch/x86/util/evsel.h
tools/perf/arch/x86/util/evsel.c +2 -1
@@ -5,6 +5,7 @@#include "util/env.h" #include "util/pmu.h" #include "linux/string.h" +#include "evsel.h" void arch_evsel__set_sample_weight (struct evsel *evsel) {
@@ -32,7 +33,7 @@ void arch_evsel__fixup_new_cycles(struct perf_event_attr *attr) }/* Check whether the evsel's PMU supports the perf metrics */ -static bool evsel__sys_has_perf_metrics (const struct evsel *evsel) +bool evsel__sys_has_perf_metrics (const struct evsel *evsel) {const char *pmu_name = evsel->pmu_name ? evsel->pmu_name :"cpu" ;
tools/perf/arch/x86/util/evsel.h new file +7 -0
@@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _EVSEL_H +#define _EVSEL_H 1 + +bool evsel__sys_has_perf_metrics (const struct evsel *evsel); + +#endif
tools/perf/arch/x86/util/topdown.c +4 -17
@@ -4,6 +4,7 @@#include "util/pmu.h" #include "util/topdown.h" #include "topdown.h" +#include "evsel.h" /* Check whether there is a PMU which supports the perf metrics. */ bool topdown_sys_has_perf_metrics (void )
@@ -55,33 +56,19 @@ void arch_topdown_group_warn(void)#define TOPDOWN_SLOTS 0x0400 -static bool is_topdown_slots_event (struct evsel *counter) -{ -if (!counter->pmu_name) -return false; - -if (strcmp (counter->pmu_name,"cpu" )) -return false; - -if (counter->core.attr.config ==TOPDOWN_SLOTS ) -return true; - -return false; -} -/* * Check whether a topdown group supports sample-read. * -* Only Topdown metic supports sample-read. The slots +* Only Topdown metric supports sample-read. The slots * event must be the leader of the topdown group. */ bool arch_topdown_sample_read (struct evsel *leader) { -if (!pmu_have_event ("cpu" ,"slots" )) +if (!evsel__sys_has_perf_metrics (leader))return false; -if (is_topdown_slots_event (leader)) +if (leader->core.attr.config ==TOPDOWN_SLOTS )return true;return false;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 150/339 perf c2c: Fix sorting in percent_rmt_hitm_cmp()
In reply to Greg Kroah-HartmanFrom: Leo Yan <[email protected]>
[ Upstream commit b24192a17337abbf3f44aaa75e15df14a2d0016e ]
The function percent_rmt_hitm_cmp() wrongly uses local HITMs for sorting remote HITMs.
Since this function is to sort cache lines for remote HITMs, this patch changes to use 'rmt_hitm' field for correct sorting.
--- tools/perf/builtin-c2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/builtin-c2c.c +2 -2
@@ -925,8 +925,8 @@ percent_rmt_hitm_cmp(struct perf_hpp_fmt *fmt __maybe_unused,double per_left;double per_right; - per_left =PERCENT (left, lcl_hitm); - per_right =PERCENT (right, lcl_hitm); + per_left =PERCENT (left, rmt_hitm); + per_right =PERCENT (right, rmt_hitm);return per_left - per_right; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 151/339 Bluetooth: MGMT: Add conditions for setting HCI_CONN_FLAG_REMOTE_WAKEUP
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit a9a347655d224fa2841877957b34fc9d491fc2d7 ]
HCI_CONN_FLAG_REMOTE_WAKEUP can only be set if device can be programmed in the allowlist which in case of device using RPA requires LL Privacy support to be enabled.
--- net/bluetooth/mgmt.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
net/bluetooth/mgmt.c +18 -0
@@ -4529,6 +4529,23 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, params =hci_conn_params_lookup (hdev, &cp->addr.bdaddr,le_addr_type (cp->addr.type));if (params) { +DECLARE_BITMAP (flags, __HCI_CONN_NUM_FLAGS); + +bitmap_from_u64 (flags, current_flags); + +/* Devices using RPAs can only be programmed in the +* acceptlist LL Privacy has been enable otherwise they +* cannot mark HCI_CONN_FLAG_REMOTE_WAKEUP. +*/ +if (test_bit (HCI_CONN_FLAG_REMOTE_WAKEUP , flags) && + !use_ll_privacy (hdev) && +hci_find_irk_by_addr (hdev, ¶ms->addr, + params->addr_type)) { +bt_dev_warn (hdev, +"Cannot set wakeable for RPA" ); + goto unlock; + } +bitmap_from_u64 (params->flags, current_flags); status =MGMT_STATUS_SUCCESS ;
@@ -4545,6 +4562,7 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, } } +unlock:hci_dev_unlock (hdev); done:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 152/339 Bluetooth: hci_sync: Fix attempting to suspend with unfiltered passive scan
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 3b42055388c30f2761a2d9cd9af2c99611dfe457 ]
When suspending the passive scanning _must_ have its filter_policy set to 0x01 to use the accept list otherwise _any_ advertise report would end up waking up the system.
In order to fix the filter_policy the code now checks for hdev->suspended && HCI_CONN_FLAG_REMOTE_WAKEUP
first, since the MGMT_OP_SET_DEVICE_FLAGS will reject any attempt to set HCI_CONN_FLAG_REMOTE_WAKEUP when it cannot be programmed in the acceptlist, so it can return success causing the proper filter_policy to be used.
--- net/bluetooth/hci_sync.c | 58 +++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 15 deletions(-)
net/bluetooth/hci_sync.c +43 -15
@@ -1664,20 +1664,19 @@ static int hci_le_add_accept_list_sync(struct hci_dev *hdev,struct hci_cp_le_add_to_accept_list cp;int err; +/* During suspend, only wakeable devices can be in acceptlist */ +if (hdev->suspended && + !test_bit (HCI_CONN_FLAG_REMOTE_WAKEUP , params->flags)) +return 0 ; +/* Select filter policy to accept all advertising */ if (*num_entries >= hdev->le_accept_list_size)return -ENOSPC ;/* Accept list can not be used with RPAs */ if (!use_ll_privacy (hdev) && -hci_find_irk_by_addr (hdev, ¶ms->addr, params->addr_type)) { +hci_find_irk_by_addr (hdev, ¶ms->addr, params->addr_type))return -EINVAL ; - } - -/* During suspend, only wakeable devices can be in acceptlist */ -if (hdev->suspended && - !test_bit (HCI_CONN_FLAG_REMOTE_WAKEUP , params->flags)) -return 0 ;/* Attempt to program the device in the resolving list first to avoid * having to rollback in case it fails since the resolving list is
@@ -4881,10 +4880,28 @@ static int hci_update_event_filter_sync(struct hci_dev *hdev)return 0 ; } +/* This function disables scan (BR and LE) and mark it as paused */ +static int hci_pause_scan_sync (struct hci_dev *hdev) +{ +if (hdev->scanning_paused) +return 0 ; + +/* Disable page scan if enabled */ +if (test_bit (HCI_PSCAN , &hdev->flags)) +hci_write_scan_enable_sync (hdev,SCAN_DISABLED ); + +hci_scan_disable_sync (hdev); + + hdev->scanning_paused = true; + +return 0 ; +} +/* This function performs the HCI suspend procedures in the follow order: * * Pause discovery (active scanning/inquiry) * Pause Directed Advertising/Advertising +* Pause Scanning (passive scanning in case discovery was not active) * Disconnect all connections * Set suspend_status to BT_SUSPEND_DISCONNECT if hdev cannot wakeup * otherwise:
@@ -4910,15 +4927,11 @@ int hci_suspend_sync(struct hci_dev *hdev)/* Pause other advertisements */ hci_pause_advertising_sync (hdev); -/* Disable page scan if enabled */ -if (test_bit (HCI_PSCAN , &hdev->flags)) -hci_write_scan_enable_sync (hdev,SCAN_DISABLED ); -/* Suspend monitor filters */ hci_suspend_monitor_sync (hdev);/* Prevent disconnects from causing scanning to be re-enabled */ - hdev->scanning_paused = true; +hci_pause_scan_sync (hdev);/* Soft disconnect everything (power off) */ err =hci_disconnect_all_sync (hdev,HCI_ERROR_REMOTE_POWER_OFF );
@@ -4989,6 +5002,22 @@ static void hci_resume_monitor_sync(struct hci_dev *hdev) } } +/* This function resume scan and reset paused flag */ +static int hci_resume_scan_sync (struct hci_dev *hdev) +{ +if (!hdev->scanning_paused) +return 0 ; + +hci_update_scan_sync (hdev); + +/* Reset passive scanning to normal */ +hci_update_passive_scan_sync (hdev); + + hdev->scanning_paused = false; + +return 0 ; +} +/* This function performs the HCI suspend procedures in the follow order: * * Restore event mask
@@ -5011,10 +5040,9 @@ int hci_resume_sync(struct hci_dev *hdev)/* Clear any event filters and restore scan state */ hci_clear_event_filter_sync (hdev); -hci_update_scan_sync (hdev); -/* Reset passive scanning to normal */ -hci_update_passive_scan_sync (hdev); +/* Resume scanning */ +hci_resume_scan_sync (hdev);/* Resume monitor filters */ hci_resume_monitor_sync (hdev);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 153/339 bluetooth: dont use bitmaps for random flag accesses
In reply to Greg Kroah-HartmanFrom: Linus Torvalds <[email protected]>
[ Upstream commit e1cff7002b716bd0b5f5f4afd4273c99aa8644be ]
The bluetooth code uses our bitmap infrastructure for the two bits (!) of connection setup flags, and in the process causes odd problems when it converts between a bitmap and just the regular values of said bits.
It's completely pointless to do things like bitmap_to_arr32() to convert a bitmap into a u32. It shoudln't have been a bitmap in the first place. The reason to use bitmaps is if you have arbitrary number of bits you want to manage (not two!), or if you rely on the atomicity guarantees of the bitmap setting and clearing.
The code could use an "atomic_t" and use "atomic_or/andnot()" to set and clear the bit values, but considering that it then copies the bitmaps around with "bitmap_to_arr32()" and friends, there clearly cannot be a lot of atomicity requirements.
So just use a regular integer.
In the process, this avoids the warnings about erroneous use of bitmap_from_u64() which were triggered on 32-bit architectures when conversion from a u64 would access two words (and, surprise, surprise, only one word is needed - and indeed overkill - for a 2-bit bitmap).
That was always problematic, but the compiler seems to notice it and warn about the invalid pattern only after commit 0a97953fd221 ("lib: add bitmap_{from,to}_arr64") changed the exact implementation details of 'bitmap_from_u64()', as reported by Sudip Mukherjee and Stephen Rothwell.
--- include/net/bluetooth/hci_core.h | 17 ++++++--------- net/bluetooth/hci_core.c | 4 ++-- net/bluetooth/hci_request.c | 2 +- net/bluetooth/hci_sync.c | 6 +++--- net/bluetooth/mgmt.c | 37 ++++++++++++-------------------- 5 files changed, 27 insertions(+), 39 deletions(-)
include/net/bluetooth/hci_core.h +7 -10
@@ -155,21 +155,18 @@ struct bdaddr_list_with_irk {u8 local_irk[16 ]; }; +/* Bitmask of connection flags */ enum hci_conn_flags { -HCI_CONN_FLAG_REMOTE_WAKEUP , -HCI_CONN_FLAG_DEVICE_PRIVACY , - - __HCI_CONN_NUM_FLAGS, +HCI_CONN_FLAG_REMOTE_WAKEUP =1 , +HCI_CONN_FLAG_DEVICE_PRIVACY =2 , }; - -/* Make sure number of flags doesn't exceed sizeof(current_flags) */ -static_assert (__HCI_CONN_NUM_FLAGS <32 ); +typedef u8 hci_conn_flags_t ;struct bdaddr_list_with_flags {struct list_head list;bdaddr_t bdaddr;u8 bdaddr_type; - DECLARE_BITMAP(flags, __HCI_CONN_NUM_FLAGS); +hci_conn_flags_t flags; };struct bt_uuid {
@@ -576,7 +573,7 @@ struct hci_dev {struct rfkill *rfkill;DECLARE_BITMAP (dev_flags, __HCI_NUM_FLAGS); -DECLARE_BITMAP (conn_flags, __HCI_CONN_NUM_FLAGS); +hci_conn_flags_t conn_flags;__s8 adv_tx_power;__u8 adv_data[HCI_MAX_EXT_AD_LENGTH ];
@@ -775,7 +772,7 @@ struct hci_conn_params {struct hci_conn *conn;bool explicit_connect; -DECLARE_BITMAP (flags, __HCI_CONN_NUM_FLAGS); +hci_conn_flags_t flags;u8 privacy_mode; };
net/bluetooth/hci_core.c +2 -2
@@ -2153,7 +2153,7 @@ int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,bacpy (&entry->bdaddr, bdaddr); entry->bdaddr_type = type; -bitmap_from_u64 (entry->flags, flags); + entry->flags = flags;list_add (&entry->list, list);
@@ -2634,7 +2634,7 @@ int hci_register_dev(struct hci_dev *hdev)* callback. */ if (hdev->wakeup) -set_bit (HCI_CONN_FLAG_REMOTE_WAKEUP , hdev->conn_flags); + hdev->conn_flags |=HCI_CONN_FLAG_REMOTE_WAKEUP ;hci_sock_dev_event (hdev,HCI_DEV_REG );hci_dev_hold (hdev);
net/bluetooth/hci_request.c +1 -1
@@ -482,7 +482,7 @@ static int add_to_accept_list(struct hci_request *req,/* During suspend, only wakeable devices can be in accept list */ if (hdev->suspended && - !test_bit (HCI_CONN_FLAG_REMOTE_WAKEUP , params->flags)) + !(params->flags &HCI_CONN_FLAG_REMOTE_WAKEUP ))return 0 ; *num_entries +=1 ;
net/bluetooth/hci_sync.c +3 -3
@@ -1637,7 +1637,7 @@ static int hci_le_set_privacy_mode_sync(struct hci_dev *hdev,* indicates that LL Privacy has been enabled and * HCI_OP_LE_SET_PRIVACY_MODE is supported. */ -if (!test_bit (HCI_CONN_FLAG_DEVICE_PRIVACY , params->flags)) +if (!(params->flags &HCI_CONN_FLAG_DEVICE_PRIVACY ))return 0 ; irk =hci_find_irk_by_addr (hdev, ¶ms->addr, params->addr_type);
@@ -1666,7 +1666,7 @@ static int hci_le_add_accept_list_sync(struct hci_dev *hdev,/* During suspend, only wakeable devices can be in acceptlist */ if (hdev->suspended && - !test_bit (HCI_CONN_FLAG_REMOTE_WAKEUP , params->flags)) + !(params->flags &HCI_CONN_FLAG_REMOTE_WAKEUP ))return 0 ;/* Select filter policy to accept all advertising */
@@ -4856,7 +4856,7 @@ static int hci_update_event_filter_sync(struct hci_dev *hdev)hci_clear_event_filter_sync (hdev);list_for_each_entry (b, &hdev->accept_list, list) { -if (!test_bit (HCI_CONN_FLAG_REMOTE_WAKEUP , b->flags)) +if (!(b->flags &HCI_CONN_FLAG_REMOTE_WAKEUP ))continue ;bt_dev_dbg (hdev,"Adding event filters for %pMR" , &b->bdaddr);
net/bluetooth/mgmt.c +14 -23
@@ -4013,10 +4013,11 @@ static int exp_ll_privacy_feature_changed(bool enabled, struct hci_dev *hdev,memcpy (ev.uuid, rpa_resolution_uuid,16 ); ev.flags =cpu_to_le32 ((enabled ?BIT (0 ) :0 ) |BIT (1 )); +// Do we need to be atomic with the conn_flags? if (enabled &&privacy_mode_capable (hdev)) -set_bit (HCI_CONN_FLAG_DEVICE_PRIVACY , hdev->conn_flags); + hdev->conn_flags |=HCI_CONN_FLAG_DEVICE_PRIVACY ;else -clear_bit (HCI_CONN_FLAG_DEVICE_PRIVACY , hdev->conn_flags); + hdev->conn_flags &= ~HCI_CONN_FLAG_DEVICE_PRIVACY ; return mgmt_limited_event(MGMT_EV_EXP_FEATURE_CHANGED, hdev, &ev, sizeof(ev),
@@ -4435,8 +4436,7 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,hci_dev_lock (hdev); -bitmap_to_arr32 (&supported_flags, hdev->conn_flags, - __HCI_CONN_NUM_FLAGS); + supported_flags = hdev->conn_flags;memset (&rp,0 ,sizeof (rp));
@@ -4447,8 +4447,7 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,if (!br_params) goto done; -bitmap_to_arr32 (¤t_flags, br_params->flags, - __HCI_CONN_NUM_FLAGS); + current_flags = br_params->flags; }else { params =hci_conn_params_lookup (hdev, &cp->addr.bdaddr,le_addr_type (cp->addr.type));
@@ -4456,8 +4455,7 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,if (!params) goto done; -bitmap_to_arr32 (¤t_flags, params->flags, - __HCI_CONN_NUM_FLAGS); + current_flags = params->flags; }bacpy (&rp.addr.bdaddr, &cp->addr.bdaddr);
@@ -4502,8 +4500,8 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, &cp->addr.bdaddr, cp->addr.type, __le32_to_cpu(current_flags)); -bitmap_to_arr32 (&supported_flags, hdev->conn_flags, - __HCI_CONN_NUM_FLAGS); +// We should take hci_dev_lock() early, I think.. conn_flags can change + supported_flags = hdev->conn_flags;if ((supported_flags | current_flags) != supported_flags) { bt_dev_warn(hdev, "Bad flag given (0x%x) vs supported (0x%0x)",
@@ -4519,7 +4517,7 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, cp->addr.type);if (br_params) { -bitmap_from_u64 (br_params->flags, current_flags); + br_params->flags = current_flags; status =MGMT_STATUS_SUCCESS ; }else { bt_dev_warn(hdev, "No such BR/EDR device %pMR (0x%x)",
@@ -4529,15 +4527,11 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, params =hci_conn_params_lookup (hdev, &cp->addr.bdaddr,le_addr_type (cp->addr.type));if (params) { -DECLARE_BITMAP (flags, __HCI_CONN_NUM_FLAGS); - -bitmap_from_u64 (flags, current_flags); -/* Devices using RPAs can only be programmed in the * acceptlist LL Privacy has been enable otherwise they * cannot mark HCI_CONN_FLAG_REMOTE_WAKEUP. */ -if (test_bit (HCI_CONN_FLAG_REMOTE_WAKEUP , flags) && +if ((current_flags &HCI_CONN_FLAG_REMOTE_WAKEUP ) && !use_ll_privacy (hdev) &&hci_find_irk_by_addr (hdev, ¶ms->addr, params->addr_type)) {
@@ -4546,14 +4540,13 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, goto unlock; } -bitmap_from_u64 (params->flags, current_flags); + params->flags = current_flags; status =MGMT_STATUS_SUCCESS ;/* Update passive scan if HCI_CONN_FLAG_DEVICE_PRIVACY * has been set. */ -if (test_bit (HCI_CONN_FLAG_DEVICE_PRIVACY , - params->flags)) +if (params->flags &HCI_CONN_FLAG_DEVICE_PRIVACY )hci_update_passive_scan (hdev); }else { bt_dev_warn(hdev, "No such LE device %pMR (0x%x)",
@@ -7154,8 +7147,7 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, params =hci_conn_params_lookup (hdev, &cp->addr.bdaddr, addr_type);if (params) -bitmap_to_arr32 (¤t_flags, params->flags, - __HCI_CONN_NUM_FLAGS); + current_flags = params->flags; } err =hci_cmd_sync_queue (hdev, add_device_sync,NULL ,NULL );
@@ -7164,8 +7156,7 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, added:device_added (sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action); -bitmap_to_arr32 (&supported_flags, hdev->conn_flags, - __HCI_CONN_NUM_FLAGS); + supported_flags = hdev->conn_flags;device_flags_changed (NULL , hdev, &cp->addr.bdaddr, cp->addr.type, supported_flags, current_flags);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 154/339 dmaengine: idxd: set DMA_INTERRUPT cap bit
In reply to Greg Kroah-HartmanFrom: Dave Jiang <[email protected]>
[ Upstream commit 4e5a4eb20393b851590b4465f1197a8041c2076b ]
Even though idxd driver has always supported interrupt, it never actually set the DMA_INTERRUPT cap bit. Rectify this mistake so the interrupt capability is advertised.
--- drivers/dma/idxd/dma.c | 1 + 1 file changed, 1 insertion(+)
drivers/dma/idxd/dma.c +1 -0
@@ -193,6 +193,7 @@ int idxd_register_dma_device(struct idxd_device *idxd)INIT_LIST_HEAD (&dma->channels); dma->dev = dev; +dma_cap_set (DMA_INTERRUPT , dma->cap_mask);dma_cap_set (DMA_PRIVATE , dma->cap_mask);dma_cap_set (DMA_COMPLETION_NO_ORDER , dma->cap_mask); dma->device_release = idxd_dma_release;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 155/339 mips: cpc: Fix refcount leak in mips_cpc_default_phys_base
In reply to Greg Kroah-HartmanFrom: Gong Yuanjun <[email protected]>
[ Upstream commit 4107fa700f314592850e2c64608f6ede4c077476 ]
Add the missing of_node_put() to release the refcount incremented by of_find_compatible_node().
--- arch/mips/kernel/mips-cpc.c | 1 + 1 file changed, 1 insertion(+)
arch/mips/kernel/mips-cpc.c +1 -0
@@ -28,6 +28,7 @@ phys_addr_t __weak mips_cpc_default_phys_base(void) cpc_node =of_find_compatible_node (of_root,NULL ,"mti,mips-cpc" );if (cpc_node) { err =of_address_to_resource (cpc_node,0 , &res); +of_node_put (cpc_node);if (!err)return res.start; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 156/339 bootconfig: Make the bootconfig.o as a normal object file
In reply to Greg Kroah-HartmanFrom: Masami Hiramatsu <[email protected]>
[ Upstream commit 6014a23638cdee63a71ef13c51d7c563eb5829ee ]
Since the APIs defined in the bootconfig.o are not individually used, it is meaningless to build it as library by lib-y. Use obj-y for that.
--- lib/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/Makefile +1 -1
@@ -279,7 +279,7 @@ $(foreach file, $(libfdt_files), \ $(eval CFLAGS_$(file) = -I $(srctree)/scripts/dtc/libfdt)) lib-$(CONFIG_LIBFDT) += $(libfdt_files) -lib-$(CONFIG_BOOT_CONFIG) += bootconfig.o +obj-$(CONFIG_BOOT_CONFIG) += bootconfig.o obj-$(CONFIG_RBTREE_TEST) += rbtree_test.o obj-$(CONFIG_INTERVAL_TREE_TEST) += interval_tree_test.o
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 157/339 tracing: Make tp_printk work on syscall tracepoints
In reply to Greg Kroah-HartmanFrom: Jeff Xie <[email protected]>
[ Upstream commit cb1c45fb68b8a4285ccf750842b1136f26cfe267 ]
Currently the tp_printk option has no effect on syscall tracepoint. When adding the kernel option parameter tp_printk, then:
echo 1 > /sys/kernel/debug/tracing/events/syscalls/enable
When running any application, no trace information is printed on the terminal.
Now added printk for syscall tracepoints.
--- kernel/trace/trace_syscalls.c | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-)
kernel/trace/trace_syscalls.c +11 -24
@@ -154,7 +154,7 @@ print_syscall_enter(struct trace_iterator *iter, int flags, goto end;/* parameter types */ -if (tr->trace_flags &TRACE_ITER_VERBOSE ) +if (tr && tr->trace_flags &TRACE_ITER_VERBOSE )trace_seq_printf (s,"%s " , entry->types[i]);/* parameter values */
@@ -296,9 +296,7 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)struct trace_event_file *trace_file;struct syscall_trace_enter *entry;struct syscall_metadata *sys_data; -struct ring_buffer_event *event; -struct trace_buffer *buffer; -unsigned int trace_ctx; +struct trace_event_buffer fbuffer;unsigned long args[6 ];int syscall_nr;int size;
@@ -321,20 +319,16 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id) size =sizeof (*entry) +sizeof (unsigned long ) * sys_data->nb_args; - trace_ctx =tracing_gen_ctx (); - - event =trace_event_buffer_lock_reserve (&buffer, trace_file, - sys_data->enter_event->event.type, size, trace_ctx); -if (!event) + entry =trace_event_buffer_reserve (&fbuffer, trace_file, size); +if (!entry)return ; - entry =ring_buffer_event_data (event); + entry =ring_buffer_event_data (fbuffer.event); entry->nr = syscall_nr;syscall_get_arguments (current, regs, args);memcpy (entry->args, args,sizeof (unsigned long ) * sys_data->nb_args); -event_trigger_unlock_commit (trace_file, buffer, event, entry, - trace_ctx); +trace_event_buffer_commit (&fbuffer); }static void ftrace_syscall_exit (void *data,struct pt_regs *regs,long ret)
@@ -343,9 +337,7 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)struct trace_event_file *trace_file;struct syscall_trace_exit *entry;struct syscall_metadata *sys_data; -struct ring_buffer_event *event; -struct trace_buffer *buffer; -unsigned int trace_ctx; +struct trace_event_buffer fbuffer;int syscall_nr; syscall_nr =trace_get_syscall_nr (current, regs);
@@ -364,20 +356,15 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)if (!sys_data)return ; - trace_ctx =tracing_gen_ctx (); - - event =trace_event_buffer_lock_reserve (&buffer, trace_file, - sys_data->exit_event->event.type,sizeof (*entry), - trace_ctx); -if (!event) + entry =trace_event_buffer_reserve (&fbuffer, trace_file,sizeof (*entry)); +if (!entry)return ; - entry =ring_buffer_event_data (event); + entry =ring_buffer_event_data (fbuffer.event); entry->nr = syscall_nr; entry->ret =syscall_get_return_value (current, regs); -event_trigger_unlock_commit (trace_file, buffer, event, entry, - trace_ctx); +trace_event_buffer_commit (&fbuffer); } static int reg_event_syscall_enter(struct trace_event_file *file,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 158/339 tracing: Fix sleeping function called from invalid context on RT kernel
In reply to Greg Kroah-HartmanFrom: Jun Miao <[email protected]>
[ Upstream commit 12025abdc8539ed9d5014e2d647a3fd1bd3de5cd ]
When setting bootparams="trace_event=initcall:initcall_start tp_printk=1" in the cmdline, the output_printk() was called, and the spin_lock_irqsave() was called in the atomic and irq disable interrupt context suitation. On the PREEMPT_RT kernel, these locks are replaced with sleepable rt-spinlock, so the stack calltrace will be triggered.
Fix it by raw_spin_lock_irqsave when PREEMPT_RT and "trace_event=initcall:initcall_start tp_printk=1" enabled.
BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:46 in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1, name: swapper/0 preempt_count: 2, expected: 0 RCU nest depth: 0, expected: 0 Preemption disabled at: [<ffffffff8992303e>] try_to_wake_up+0x7e/0xba0 CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.17.1-rt17+ #19 34c5812404187a875f32bee7977f7367f9679ea7 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x60/0x8c dump_stack+0x10/0x12 __might_resched.cold+0x11d/0x155 rt_spin_lock+0x40/0x70 trace_event_buffer_commit+0x2fa/0x4c0 ? map_vsyscall+0x93/0x93 trace_event_raw_event_initcall_start+0xbe/0x110 ? perf_trace_initcall_finish+0x210/0x210 ? probe_sched_wakeup+0x34/0x40 ? ttwu_do_wakeup+0xda/0x310 ? trace_hardirqs_on+0x35/0x170 ? map_vsyscall+0x93/0x93 do_one_initcall+0x217/0x3c0 ? trace_event_raw_event_initcall_level+0x170/0x170 ? push_cpu_stop+0x400/0x400 ? cblist_init_generic+0x241/0x290 kernel_init_freeable+0x1ac/0x347 ? _raw_spin_unlock_irq+0x65/0x80 ? rest_init+0xf0/0xf0 kernel_init+0x1e/0x150 ret_from_fork+0x22/0x30 </TASK>
--- kernel/trace/trace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/trace/trace.c +3 -3
@@ -2837,7 +2837,7 @@ trace_event_buffer_lock_reserve(struct trace_buffer **current_rb, }EXPORT_SYMBOL_GPL (trace_event_buffer_lock_reserve); -static DEFINE_SPINLOCK (tracepoint_iter_lock); +static DEFINE_RAW_SPINLOCK (tracepoint_iter_lock);static DEFINE_MUTEX (tracepoint_printk_mutex);static void output_printk (struct trace_event_buffer *fbuffer)
@@ -2865,14 +2865,14 @@ static void output_printk(struct trace_event_buffer *fbuffer) event = &fbuffer->trace_file->event_call->event; -spin_lock_irqsave (&tracepoint_iter_lock, flags); +raw_spin_lock_irqsave (&tracepoint_iter_lock, flags);trace_seq_init (&iter->seq); iter->ent = fbuffer->entry; event_call->event.funcs->trace (iter,0 , event);trace_seq_putc (&iter->seq,0 );printk ("%s" , iter->seq.buffer); -spin_unlock_irqrestore (&tracepoint_iter_lock, flags); +raw_spin_unlock_irqrestore (&tracepoint_iter_lock, flags); } int tracepoint_printk_sysctl(struct ctl_table *table, int write,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 159/339 tracing: Avoid adding tracer option before update_tracer_options
In reply to Greg Kroah-HartmanFrom: Mark-PK Tsai <[email protected]>
[ Upstream commit ef9188bcc6ca1d8a2ad83e826b548e6820721061 ]
To prepare for support asynchronous tracer_init_tracefs initcall, avoid calling create_trace_option_files before __update_tracer_options. Otherwise, create_trace_option_files will show warning because some tracers in trace_types list are already in tr->topts.
For example, hwlat_tracer call register_tracer in late_initcall, and global_trace.dir is already created in tracing_init_dentry, hwlat_tracer will be put into tr->topts.
Then if the __update_tracer_options is executed after hwlat_tracer registered, create_trace_option_files find that hwlat_tracer is already in tr->topts.
--- kernel/trace/trace.c | 7 +++++++ 1 file changed, 7 insertions(+)
kernel/trace/trace.c +7 -0
@@ -6334,12 +6334,18 @@ static void tracing_set_nop(struct trace_array *tr) tr->current_trace = &nop_trace; } +static bool tracer_options_updated; +static void add_tracer_options (struct trace_array *tr,struct tracer *t) {/* Only enable if the directory has been created already. */ if (!tr->dir)return ; +/* Only create trace option files after update_tracer_options finish */ +if (!tracer_options_updated) +return ; +create_trace_option_files (tr, t); }
@@ -9178,6 +9184,7 @@ static void __update_tracer_options(struct trace_array *tr)static void update_tracer_options (struct trace_array *tr) {mutex_lock (&trace_types_lock); + tracer_options_updated = true;__update_tracer_options (tr);mutex_unlock (&trace_types_lock); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 160/339 i2c: mediatek: Optimize master_xfer() and avoid circular locking
In reply to Greg Kroah-HartmanFrom: AngeloGioacchino Del Regno <[email protected]>
[ Upstream commit 8b4fc246c3fffde96835b2f6d5d0e2a56c70d8f9 ]
Especially (but not only) during probe, it may happen that multiple devices are communicating via i2c (or multiple i2c busses) and sometimes while others are probing asynchronously.
For example, a Cr50 TPM may be filling entropy (or userspace may be reading random data) while the rt5682 (i2c) codec driver reads/sets some registers, like while getting/setting a clock's rate, which happens both during probe and during system operation.
In this driver, the mtk_i2c_transfer() function (which is the i2c .master_xfer() callback) was granularly managing the clocks by performing a clk_bulk_prepare_enable() to start them and its inverse. This is not only creating possible circular locking dependencies in the some cases (like former explanation), but it's also suboptimal, as clk_core prepare/unprepare operations are using mutex locking, which creates a bit of unwanted overhead (for example, i2c trackpads will call master_xfer() every few milliseconds!).
With this commit, we avoid both the circular locking and additional overhead by changing how we handle the clocks in this driver:
- Prepare the clocks during probe (and PM resume)
- Enable/disable clocks in mtk_i2c_transfer()
- Unprepare the clocks only for driver removal (and PM suspend)
For the sake of providing a full explanation: during probe, the clocks are not only prepared but also enabled, as this is needed for some hardware initialization but, after that, we are disabling but not unpreparing them, leaving an expected state for the aforementioned clock handling strategy.
--- drivers/i2c/busses/i2c-mt65xx.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/i2c/busses/i2c-mt65xx.c +7 -4
@@ -1177,7 +1177,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,int left_num = num;struct mtk_i2c *i2c =i2c_get_adapdata (adap); - ret =clk_bulk_prepare_enable (I2C_MT65XX_CLK_MAX , i2c->clocks); + ret =clk_bulk_enable (I2C_MT65XX_CLK_MAX , i2c->clocks);if (ret)return ret;
@@ -1231,7 +1231,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, ret = num; err_exit: -clk_bulk_disable_unprepare (I2C_MT65XX_CLK_MAX , i2c->clocks); +clk_bulk_disable (I2C_MT65XX_CLK_MAX , i2c->clocks);return ret; }
@@ -1412,7 +1412,7 @@ static int mtk_i2c_probe(struct platform_device *pdev)return ret; }mtk_i2c_init_hw (i2c); -clk_bulk_disable_unprepare (I2C_MT65XX_CLK_MAX , i2c->clocks); +clk_bulk_disable (I2C_MT65XX_CLK_MAX , i2c->clocks); ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq, IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE,
@@ -1439,6 +1439,8 @@ static int mtk_i2c_remove(struct platform_device *pdev)i2c_del_adapter (&i2c->adap); +clk_bulk_unprepare (I2C_MT65XX_CLK_MAX , i2c->clocks); +return 0 ; }
@@ -1448,6 +1450,7 @@ static int mtk_i2c_suspend_noirq(struct device *dev)struct mtk_i2c *i2c =dev_get_drvdata (dev);i2c_mark_adapter_suspended (&i2c->adap); +clk_bulk_unprepare (I2C_MT65XX_CLK_MAX , i2c->clocks);return 0 ; }
@@ -1465,7 +1468,7 @@ static int mtk_i2c_resume_noirq(struct device *dev)mtk_i2c_init_hw (i2c); -clk_bulk_disable_unprepare (I2C_MT65XX_CLK_MAX , i2c->clocks); +clk_bulk_disable (I2C_MT65XX_CLK_MAX , i2c->clocks);i2c_mark_adapter_resumed (&i2c->adap);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 161/339 iommu/arm-smmu: fix possible null-ptr-deref in arm_smmu_device_probe()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit d9ed8af1dee37f181096631fb03729ece98ba816 ]
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/iommu/arm/arm-smmu/arm-smmu.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/iommu/arm/arm-smmu/arm-smmu.c +2 -3
@@ -2092,11 +2092,10 @@ static int arm_smmu_device_probe(struct platform_device *pdev)if (err)return err; - res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); - ioaddr = res->start; - smmu->base =devm_ioremap_resource (dev, res); + smmu->base =devm_platform_get_and_ioremap_resource (pdev,0 , &res);if (IS_ERR (smmu->base))return PTR_ERR (smmu->base); + ioaddr = res->start;/* * The resource size should effectively match the value of SMMU_TOP; * stash that temporarily until we know PAGESIZE to validate it with.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 162/339 iommu/arm-smmu-v3: check return value after calling platform_get_resource()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit b131fa8c1d2afd05d0b7598621114674289c2fbb ]
It will cause null-ptr-deref if platform_get_resource() returns NULL, we need check the return value.
--- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +2 -0
@@ -3770,6 +3770,8 @@ static int arm_smmu_device_probe(struct platform_device *pdev)/* Base address */ res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (!res) +return -EINVAL ;if (resource_size (res) <arm_smmu_resource_size (smmu)) {dev_err (dev,"MMIO region too small (%pr)\n" , res);return -EINVAL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 163/339 f2fs: remove WARN_ON in f2fs_is_valid_blkaddr
In reply to Greg Kroah-HartmanFrom: Dongliang Mu <[email protected]>
[ Upstream commit dc2f78e2d4cc844a1458653d57ce1b54d4a29f21 ]
Syzbot triggers two WARNs in f2fs_is_valid_blkaddr and __is_bitmap_valid. For example, in f2fs_is_valid_blkaddr, if type is DATA_GENERIC_ENHANCE or DATA_GENERIC_ENHANCE_READ, it invokes WARN_ON if blkaddr is not in the right range. The call trace is as follows:
f2fs_get_node_info+0x45f/0x1070 read_node_page+0x577/0x1190 __get_node_page.part.0+0x9e/0x10e0 __get_node_page f2fs_get_node_page+0x109/0x180 do_read_inode f2fs_iget+0x2a5/0x58b0 f2fs_fill_super+0x3b39/0x7ca0
Fix these two WARNs by replacing WARN_ON with dump_stack.
--- fs/f2fs/checkpoint.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/f2fs/checkpoint.c +2 -2
@@ -158,7 +158,7 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,f2fs_err (sbi,"Inconsistent error blkaddr:%u, sit bitmap:%d" , blkaddr, exist);set_sbi_flag (sbi,SBI_NEED_FSCK ); -WARN_ON (1 ); +dump_stack (); }return exist; }
@@ -196,7 +196,7 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,f2fs_warn (sbi,"access invalid blkaddr:%u" , blkaddr);set_sbi_flag (sbi,SBI_NEED_FSCK ); -WARN_ON (1 ); +dump_stack ();return false; }else {return __is_bitmap_valid (sbi, blkaddr, type);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 164/339 f2fs: avoid infinite loop to flush node pages
In reply to Greg Kroah-HartmanFrom: Jaegeuk Kim <[email protected]>
[ Upstream commit a7b8618aa2f0f926ce85f2486ac835a85c753ca7 ]
xfstests/generic/475 can give EIO all the time which give an infinite loop to flush node page like below. Let's avoid it.
[16418.518551] Call Trace: [16418.518553] ? dm_submit_bio+0x48/0x400 [16418.518574] ? submit_bio_checks+0x1ac/0x5a0 [16418.525207] __submit_bio+0x1a9/0x230 [16418.525210] ? kmem_cache_alloc+0x29e/0x3c0 [16418.525223] submit_bio_noacct+0xa8/0x2b0 [16418.525226] submit_bio+0x4d/0x130 [16418.525238] __submit_bio+0x49/0x310 [f2fs] [16418.525339] ? bio_add_page+0x6a/0x90 [16418.525344] f2fs_submit_page_bio+0x134/0x1f0 [f2fs] [16418.525365] read_node_page+0x125/0x1b0 [f2fs] [16418.525388] __get_node_page.part.0+0x58/0x3f0 [f2fs] [16418.525409] __get_node_page+0x2f/0x60 [f2fs] [16418.525431] f2fs_get_dnode_of_data+0x423/0x860 [f2fs] [16418.525452] ? asm_sysvec_apic_timer_interrupt+0x12/0x20 [16418.525458] ? __mod_memcg_state.part.0+0x2a/0x30 [16418.525465] ? __mod_memcg_lruvec_state+0x27/0x40 [16418.525467] ? __xa_set_mark+0x57/0x70 [16418.525472] f2fs_do_write_data_page+0x10e/0x7b0 [f2fs] [16418.525493] f2fs_write_single_data_page+0x555/0x830 [f2fs] [16418.525514] ? sysvec_apic_timer_interrupt+0x4e/0x90 [16418.525518] ? asm_sysvec_apic_timer_interrupt+0x12/0x20 [16418.525523] f2fs_write_cache_pages+0x303/0x880 [f2fs] [16418.525545] ? blk_flush_plug_list+0x47/0x100 [16418.525548] f2fs_write_data_pages+0xfd/0x320 [f2fs] [16418.525569] do_writepages+0xd5/0x210 [16418.525648] filemap_fdatawrite_wbc+0x7d/0xc0 [16418.525655] filemap_fdatawrite+0x50/0x70 [16418.525658] f2fs_sync_dirty_inodes+0xa4/0x230 [f2fs] [16418.525679] f2fs_write_checkpoint+0x16d/0x1720 [f2fs] [16418.525699] ? ttwu_do_wakeup+0x1c/0x160 [16418.525709] ? ttwu_do_activate+0x6d/0xd0 [16418.525711] ? __wait_for_common+0x11d/0x150 [16418.525715] kill_f2fs_super+0xca/0x100 [f2fs] [16418.525733] deactivate_locked_super+0x3b/0xb0 [16418.525739] deactivate_super+0x40/0x50 [16418.525741] cleanup_mnt+0x139/0x190 [16418.525747] __cleanup_mnt+0x12/0x20 [16418.525749] task_work_run+0x6d/0xa0 [16418.525765] exit_to_user_mode_prepare+0x1ad/0x1b0 [16418.525771] syscall_exit_to_user_mode+0x27/0x50 [16418.525774] do_syscall_64+0x48/0xc0 [16418.525776] entry_SYSCALL_64_after_hwframe+0x44/0xae
--- fs/f2fs/checkpoint.c | 8 +------- fs/f2fs/f2fs.h | 23 +++++++++++++++++++---- fs/f2fs/node.c | 23 ++++++++++++----------- 3 files changed, 32 insertions(+), 22 deletions(-)
fs/f2fs/checkpoint.c +1 -7
@@ -98,13 +98,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index, }if (unlikely (!PageUptodate (page))) { -if (page->index == sbi->metapage_eio_ofs) { -if (sbi->metapage_eio_cnt++ ==MAX_RETRY_META_PAGE_EIO ) -set_ckpt_flags (sbi,CP_ERROR_FLAG ); - }else { - sbi->metapage_eio_ofs = page->index; - sbi->metapage_eio_cnt =0 ; - } +f2fs_handle_page_eio (sbi, page->index,META );f2fs_put_page (page,1 );return ERR_PTR (-EIO ); }
fs/f2fs/f2fs.h +19 -4
@@ -578,8 +578,8 @@ enum {/* maximum retry quota flush count */ #define DEFAULT_RETRY_QUOTA_FLUSH_COUNT 8 -/* maximum retry of EIO'ed meta page */ -#define MAX_RETRY_META_PAGE_EIO 100 +/* maximum retry of EIO'ed page */ +#define MAX_RETRY_PAGE_EIO 100#define F2FS_LINK_MAX 0xffffffff/* maximum link count per file */
@@ -1614,8 +1614,8 @@ struct f2fs_sb_info {/* keep migration IO order for LFS mode */ struct f2fs_rwsem io_order_lock;mempool_t *write_io_dummy;/* Dummy pages */ -pgoff_t metapage_eio_ofs;/* EIO page offset */ -int metapage_eio_cnt;/* EIO count */ +pgoff_t page_eio_ofs[NR_PAGE_TYPE ];/* EIO page offset */ +int page_eio_cnt[NR_PAGE_TYPE ];/* EIO count */ /* for checkpoint */ struct f2fs_checkpoint *ckpt;/* raw checkpoint pointer */
@@ -4541,6 +4541,21 @@ static inline void f2fs_io_schedule_timeout(long timeout)io_schedule_timeout (timeout); } +static inline void f2fs_handle_page_eio (struct f2fs_sb_info *sbi,pgoff_t ofs, +enum page_type type) +{ +if (unlikely (f2fs_cp_error (sbi))) +return ; + +if (ofs == sbi->page_eio_ofs[type]) { +if (sbi->page_eio_cnt[type]++ ==MAX_RETRY_PAGE_EIO ) +set_ckpt_flags (sbi,CP_ERROR_FLAG ); + }else { + sbi->page_eio_ofs[type] = ofs; + sbi->page_eio_cnt[type] =0 ; + } +} +#define EFSBADCRC EBADMSG/* Bad CRC detected */ #define EFSCORRUPTED EUCLEAN/* Filesystem is corrupted */
fs/f2fs/node.c +12 -11
@@ -1416,8 +1416,7 @@ static struct page *__get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid, err =read_node_page (page,0 );if (err <0 ) { -f2fs_put_page (page,1 ); -return ERR_PTR (err); + goto out_put_err; }else if (err ==LOCKED_PAGE ) { err =0 ; goto page_hit;
@@ -1443,19 +1442,21 @@ static struct page *__get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid, goto out_err; } page_hit: -if (unlikely (nid !=nid_of_node (page))) { -f2fs_warn (sbi,"inconsistent node block, nid:%lu, node_footer[nid:%u,ino:%u,ofs:%u,cpver:%llu,blkaddr:%u]" , +if (likely (nid ==nid_of_node (page))) +return page; + +f2fs_warn (sbi,"inconsistent node block, nid:%lu, node_footer[nid:%u,ino:%u,ofs:%u,cpver:%llu,blkaddr:%u]" , nid,nid_of_node (page),ino_of_node (page),ofs_of_node (page),cpver_of_node (page),next_blkaddr_of_node (page)); -set_sbi_flag (sbi,SBI_NEED_FSCK ); - err = -EINVAL ; +set_sbi_flag (sbi,SBI_NEED_FSCK ); + err = -EINVAL ; out_err: -ClearPageUptodate (page); -f2fs_put_page (page,1 ); -return ERR_PTR (err); - } -return page; +ClearPageUptodate (page); +out_put_err: +f2fs_handle_page_eio (sbi, page->index,NODE ); +f2fs_put_page (page,1 ); +return ERR_PTR (err); }struct page *f2fs_get_node_page (struct f2fs_sb_info *sbi,pgoff_t nid)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 165/339 i2c: cadence: Increase timeout per message if necessary
In reply to Greg Kroah-HartmanFrom: Lucas Tanure <[email protected]>
[ Upstream commit 96789dce043f5bff8b7d62aa28d52a7c59403a84 ]
Timeout as 1 second sets an upper limit on the length of the transfer executed, but there is no maximum length of a write or read message set in i2c_adapter_quirks for this controller.
This upper limit affects devices that require sending large firmware blobs over I2C.
To remove that limitation, calculate the minimal time necessary, plus some wiggle room, for every message and use it instead of the default one second, if more than one second.
--- drivers/i2c/busses/i2c-cadence.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/i2c/busses/i2c-cadence.c +10 -2
@@ -760,7 +760,7 @@ static void cdns_i2c_master_reset(struct i2c_adapter *adap)static int cdns_i2c_process_msg (struct cdns_i2c *id,struct i2c_msg *msg,struct i2c_adapter *adap) { -unsigned long time_left; +unsigned long time_left, msg_timeout;u32 reg; id->p_msg = msg;
@@ -785,8 +785,16 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg,else cdns_i2c_msend (id); +/* Minimal time to execute this message */ + msg_timeout =msecs_to_jiffies ((1000 * msg->len *BITS_PER_BYTE ) / id->i2c_clk); +/* Plus some wiggle room */ + msg_timeout +=msecs_to_jiffies (500 ); + +if (msg_timeout < adap->timeout) + msg_timeout = adap->timeout; +/* Wait for the signal of completion */ - time_left =wait_for_completion_timeout (&id->xfer_done, adap->timeout); + time_left =wait_for_completion_timeout (&id->xfer_done, msg_timeout);if (time_left ==0 ) {cdns_i2c_master_reset (adap); dev_err(id->adap.dev.parent,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 166/339 m68knommu: set ZERO_PAGE() to the allocated zeroed page
In reply to Greg Kroah-HartmanFrom: Greg Ungerer <[email protected]>
[ Upstream commit dc068f46217970d9516f16cd37972a01d50dc055 ]
The non-MMU m68k pagetable ZERO_PAGE() macro is being set to the somewhat non-sensical value of "virt_to_page(0)". The zeroth page is not in any way guaranteed to be a page full of "0". So the result is that ZERO_PAGE() will almost certainly contain random values.
We already allocate a real "empty_zero_page" in the mm setup code shared between MMU m68k and non-MMU m68k. It is just not hooked up to the ZERO_PAGE() macro for the non-MMU m68k case.
Fix ZERO_PAGE() to use the allocated "empty_zero_page" pointer.
I am not aware of any specific issues caused by the old code.
--- arch/m68k/include/asm/pgtable_no.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/m68k/include/asm/pgtable_no.h +2 -1
@@ -42,7 +42,8 @@ extern void paging_init(void);* ZERO_PAGE is a global shared page that is always zero: used * for zero-mapped memory areas etc.. */ -#define ZERO_PAGE (vaddr) (virt_to_page(0)) +extern void *empty_zero_page; +#define ZERO_PAGE (vaddr) (virt_to_page(empty_zero_page))/* * All 32bit addresses are effectively valid for vmalloc...
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 167/339 m68knommu: fix undefined reference to `_init_sp
In reply to Greg Kroah-HartmanFrom: Greg Ungerer <[email protected]>
[ Upstream commit a71b9e66fee47c59b3ec34e652b5c23bc6550794 ]
When configuring a nommu classic m68k system enabling the uboot parameter passing support (CONFIG_UBOOT) will produce the following compile error:
m68k-linux-ld: arch/m68k/kernel/uboot.o: in function `process_uboot_commandline':
uboot.c:(.init.text+0x32): undefined reference to `_init_sp'
The logic to support this option is only used on ColdFire based platforms (in its head.S startup code). So make the selection of this option depend on building for a ColdFire based platform.
--- arch/m68k/Kconfig.machine | 1 + 1 file changed, 1 insertion(+)
arch/m68k/Kconfig.machine +1 -0
@@ -335,6 +335,7 @@ comment "Machine Options" config UBOOT bool "Support for U-Boot command line parameters" + depends on COLDFIRE help If you say Y here kernel will try to collect command line parameters from the initial u-boot stack.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 168/339 dmaengine: zynqmp_dma: In struct zynqmp_dma_chan fix desc_size data type
In reply to Greg Kroah-HartmanFrom: Radhey Shyam Pandey <[email protected]>
[ Upstream commit f9a9f43a62a04ec3183fb0da9226c7706eed0115 ]
In zynqmp_dma_alloc/free_chan_resources functions there is a potential overflow in the below expressions.
dma_alloc_coherent(chan->dev, (2 * chan->desc_size *
ZYNQMP_DMA_NUM_DESCS), &chan->desc_pool_p, GFP_KERNEL);
dma_free_coherent(chan->dev,(2 * ZYNQMP_DMA_DESC_SIZE(chan) *
ZYNQMP_DMA_NUM_DESCS),
chan->desc_pool_v, chan->desc_pool_p);The arguments desc_size and ZYNQMP_DMA_NUM_DESCS were 32 bit. Though this overflow condition is not observed but it is a potential problem in the case of 32-bit multiplication. Hence fix it by changing the desc_size data type to size_t.
In addition to coverity fix it also reuse ZYNQMP_DMA_DESC_SIZE macro in dma_alloc_coherent API argument.
Addresses-Coverity: Event overflow_before_widen.
--- drivers/dma/xilinx/zynqmp_dma.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/dma/xilinx/zynqmp_dma.c +3 -2
@@ -229,7 +229,7 @@ struct zynqmp_dma_chan {bool is_dmacoherent;struct tasklet_struct tasklet;bool idle; -u32 desc_size; +size_t desc_size;bool err;u32 bus_width;u32 src_burst_len;
@@ -486,7 +486,8 @@ static int zynqmp_dma_alloc_chan_resources(struct dma_chan *dchan) } chan->desc_pool_v =dma_alloc_coherent (chan->dev, - (2 * chan->desc_size *ZYNQMP_DMA_NUM_DESCS ), + (2 *ZYNQMP_DMA_DESC_SIZE (chan) * +ZYNQMP_DMA_NUM_DESCS ), &chan->desc_pool_p,GFP_KERNEL );if (!chan->desc_pool_v)return -ENOMEM ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 169/339 NFSv4: Dont hold the layoutget locks across multiple RPC calls
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
[ Upstream commit 6949493884fe88500de4af182588e071cf1544ee ]
When doing layoutget as part of the open() compound, we have to be careful to release the layout locks before we can call any further RPC calls, such as setattr(). The reason is that those calls could trigger a recall, which could deadlock.
--- fs/nfs/nfs4proc.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/nfs/nfs4proc.c +4 -0
@@ -3098,6 +3098,10 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, } out: +if (opendata->lgp) { +nfs4_lgopen_release (opendata->lgp); + opendata->lgp =NULL ; + }if (!opendata->cancelled)nfs4_sequence_free_slot (&opendata->o_res.seq_res);return ret;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 170/339 video: fbdev: hyperv_fb: Allow resolutions with size > 64 MB for Gen1
In reply to Greg Kroah-HartmanFrom: Saurabh Sengar <[email protected]>
[ Upstream commit c4b4d7047f16a8d138ce76da65faefb7165736f2 ]
This patch fixes a bug where GEN1 VMs doesn't allow resolutions greater than 64 MB size (eg 7680x4320). Unnecessary PCI check limits Gen1 VRAM to legacy PCI BAR size only (ie 64MB). Thus any, resolution requesting greater then 64MB (eg 7680x4320) would fail. MMIO region assigning this memory shouldn't be limited by PCI bar size.
--- drivers/video/fbdev/hyperv_fb.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-)
drivers/video/fbdev/hyperv_fb.c +1 -18
@@ -1009,7 +1009,6 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)struct pci_dev *pdev =NULL ;void __iomem *fb_virt;int gen2vm =efi_enabled (EFI_BOOT ); -resource_size_t pot_start, pot_end;phys_addr_t paddr;int ret;
@@ -1060,23 +1059,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) dio_fb_size = screen_width * screen_height * screen_depth /8 ; -if (gen2vm) { - pot_start =0 ; - pot_end =-1 ; - }else { -if (!(pci_resource_flags (pdev,0 ) &IORESOURCE_MEM ) || -pci_resource_len (pdev,0 ) < screen_fb_size) { -pr_err ("Resource not available or (0x%lx < 0x%lx)\n" , - (unsigned long )pci_resource_len (pdev,0 ), - (unsigned long ) screen_fb_size); - goto err1; - } - - pot_end =pci_resource_end (pdev,0 ); - pot_start = pot_end - screen_fb_size +1 ; - } - - ret =vmbus_allocate_mmio (&par->mem, hdev, pot_start, pot_end, + ret =vmbus_allocate_mmio (&par->mem, hdev,0 ,-1 , screen_fb_size,0x100000 , true);if (ret !=0 ) {pr_err ("Unable to allocate framebuffer memory\n" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 171/339 video: fbdev: pxa3xx-gcu: release the resources correctly in pxa3xx_gcu_probe/remove()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit d87ad457f7e1b8d2492ca5b1531eb35030a1cc8f ]
In pxa3xx_gcu_probe(), the sequence of error lable is wrong, it will leads some resource leaked, so adjust the sequence to handle the error correctly, and if pxa3xx_gcu_add_buffer() fails, pxa3xx_gcu_free_buffers() need be called.
In pxa3xx_gcu_remove(), add missing clk_disable_unpreprare().
--- drivers/video/fbdev/pxa3xx-gcu.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/video/fbdev/pxa3xx-gcu.c +7 -5
@@ -646,6 +646,7 @@ static int pxa3xx_gcu_probe(struct platform_device *pdev)for (i =0 ; i <8 ; i++) { ret =pxa3xx_gcu_add_buffer (dev, priv);if (ret) { +pxa3xx_gcu_free_buffers (dev, priv);dev_err (dev,"failed to allocate DMA memory\n" ); goto err_disable_clk; }
@@ -662,15 +663,15 @@ static int pxa3xx_gcu_probe(struct platform_device *pdev) SHARED_SIZE, irq);return 0 ; -err_free_dma: -dma_free_coherent (dev,SHARED_SIZE , - priv->shared, priv->shared_phys); +err_disable_clk: +clk_disable_unprepare (priv->clk); err_misc_deregister:misc_deregister (&priv->misc_dev); -err_disable_clk: -clk_disable_unprepare (priv->clk); +err_free_dma: +dma_free_coherent (dev,SHARED_SIZE , + priv->shared, priv->shared_phys);return ret; }
@@ -683,6 +684,7 @@ static int pxa3xx_gcu_remove(struct platform_device *pdev)pxa3xx_gcu_wait_idle (priv);misc_deregister (&priv->misc_dev);dma_free_coherent (dev,SHARED_SIZE , priv->shared, priv->shared_phys); +clk_disable_unprepare (priv->clk);pxa3xx_gcu_free_buffers (dev, priv);return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 172/339 RISC-V: use memcpy for kexec_file mode
In reply to Greg Kroah-HartmanFrom: Liao Chang <[email protected]>
[ Upstream commit b7fb4d78a6ade6026d9e5cf438c2a46ab962e032 ]
The pointer to buffer loading kernel binaries is in kernel space for kexec_fil mode, When copy_from_user copies data from pointer to a block of memory, it checkes that the pointer is in the user space range, on RISCV-V that is:
static inline bool __access_ok(unsigned long addr, unsigned long size)
{
return size <= TASK_SIZE && addr <= TASK_SIZE - size;
}and TASK_SIZE is 0x4000000000 for 64-bits, which now causes copy_from_user to reject the access of the field 'buf' of struct kexec_segment that is in range [CONFIG_PAGE_OFFSET - VMALLOC_SIZE, CONFIG_PAGE_OFFSET), is invalid user space pointer.
This patch fixes this issue by skipping access_ok(), use mempcy() instead.
--- arch/riscv/kernel/machine_kexec.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/riscv/kernel/machine_kexec.c +3 -1
@@ -65,7 +65,9 @@ machine_kexec_prepare(struct kimage *image)if (image->segment[i].memsz <=sizeof (fdt))continue ; -if (copy_from_user (&fdt, image->segment[i].buf,sizeof (fdt))) +if (image->file_mode) +memcpy (&fdt, image->segment[i].buf,sizeof (fdt)); +else if (copy_from_user (&fdt, image->segment[i].buf,sizeof (fdt)))continue ;if (fdt_check_header (&fdt))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 173/339 m68knommu: fix undefined reference to `mach_get_rtc_pll
In reply to Greg Kroah-HartmanFrom: Greg Ungerer <[email protected]>
[ Upstream commit 1300eec9e51f23c34c4487d2b06f58ca22e1ad3d ]
Configuring for a nommu classic m68k target and enabling the generic rtc driver (CONFIG_RTC_DRV_GENERIC) will result in the following compile error:
m68k-linux-ld: arch/m68k/kernel/time.o: in function `rtc_ioctl':
time.c:(.text+0x82): undefined reference to `mach_get_rtc_pll'
m68k-linux-ld: time.c:(.text+0xbc): undefined reference to `mach_set_rtc_pll'
m68k-linux-ld: time.c:(.text+0xf4): undefined reference to `mach_set_rtc_pll'
There are no definitions of "mach_set_rtc_pll" and "mach_get_rtc_pll" in the nommu code paths. Move these definitions and the associated "mach_hwclk", so that they are around their use case in time.c. This means they will always be defined on the builds that require them, and not on those that cannot use them - such as ColdFire (both with and without MMU enabled).
--- arch/m68k/kernel/setup_mm.c | 7 ------- arch/m68k/kernel/setup_no.c | 1 - arch/m68k/kernel/time.c | 9 +++++++++ 3 files changed, 9 insertions(+), 8 deletions(-)
arch/m68k/kernel/setup_mm.c +0 -7
@@ -87,15 +87,8 @@ void (*mach_sched_init) (void) __initdata = NULL;void (*mach_init_IRQ) (void )__initdata =NULL ;void (*mach_get_model) (char *model);void (*mach_get_hardware_list) (struct seq_file *m); -/* machine dependent timer functions */ -int (*mach_hwclk) (int ,struct rtc_time *); -EXPORT_SYMBOL (mach_hwclk);unsigned int (*mach_get_ss)(void ); -int (*mach_get_rtc_pll)(struct rtc_pll_info *); -int (*mach_set_rtc_pll)(struct rtc_pll_info *);EXPORT_SYMBOL (mach_get_ss); -EXPORT_SYMBOL (mach_get_rtc_pll); -EXPORT_SYMBOL (mach_set_rtc_pll);void (*mach_reset)(void );void (*mach_halt)(void );void (*mach_power_off)(void );
arch/m68k/kernel/setup_no.c +0 -1
@@ -50,7 +50,6 @@ char __initdata command_line[COMMAND_LINE_SIZE];/* machine dependent timer functions */ void (*mach_sched_init)(void )__initdata =NULL ; -int (*mach_hwclk) (int ,struct rtc_time *);/* machine dependent reboot functions */ void (*mach_reset)(void );
arch/m68k/kernel/time.c +9 -0
@@ -63,6 +63,15 @@ void timer_heartbeat(void)#endif /* CONFIG_HEARTBEAT */ #ifdef CONFIG_M68KCLASSIC +/* machine dependent timer functions */ +int (*mach_hwclk) (int, struct rtc_time*); +EXPORT_SYMBOL(mach_hwclk); + +int (*mach_get_rtc_pll)(struct rtc_pll_info *); +int (*mach_set_rtc_pll)(struct rtc_pll_info *); +EXPORT_SYMBOL(mach_get_rtc_pll); +EXPORT_SYMBOL(mach_set_rtc_pll); + #if !IS_BUILTIN(CONFIG_RTC_DRV_GENERIC) void read_persistent_clock64(struct timespec64 *ts) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 174/339 rtla/Makefile: Properly handle dependencies
In reply to Greg Kroah-HartmanFrom: Daniel Bristot de Oliveira <[email protected]>
[ Upstream commit fe4d0d5dde457bb5832b866418b5036f4f0c8d13 ]
Linus had a problem compiling RTLA, saying:
"[...] I wish the tracing tools would do a bit more package checking and helpful error messages too, rather than just fail with:
fatal error: tracefs.h: No such file or directory"
Which is indeed not a helpful message. Update the Makefile, adding proper checks for the dependencies, with useful information about how to resolve possible problems.
For example, the previous error is now reported as:
$ make
********************************************
** NOTICE: libtracefs version 1.3 or higher not found
**
** Consider installing the latest libtracefs from your
** distribution, e.g., 'dnf install libtracefs' on Fedora,
** or from source:
**
** https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/
**
********************************************These messages are inspired by the ones used on trace-cmd, as suggested by Stevel Rostedt.
Changes from V1:
- Moved the rst2man check to the install phase (when it is used).
- Removed the procps-ng lib check [1] as it is being removed.
[1] a0f9f8c1030c66305c9b921057c3d483064d5529.1651220820.git.bristot@kernel.org
--- Documentation/tools/rtla/Makefile | 14 ++++++++++++- tools/tracing/rtla/Makefile | 35 +++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-)
Documentation/tools/rtla/Makefile +13 -1
@@ -17,9 +17,21 @@ DOC_MAN1 = $(addprefix $(OUTPUT),$(_DOC_MAN1)) RST2MAN_DEP := $(shell command -v rst2man 2>/dev/null) RST2MAN_OPTS += --verbose +TEST_RST2MAN = $(shell sh -c "rst2man --version > /dev/null 2>&1 || echo n") + $(OUTPUT)%.1: %.rst ifndef RST2MAN_DEP - $(error "rst2man not found, but required to generate man pages") + $(info ********************************************) + $(info ** NOTICE: rst2man not found) + $(info **) + $(info ** Consider installing the latest rst2man from your) + $(info ** distribution, e.g., 'dnf install python3-docutils' on Fedora,) + $(info ** or from source:) + $(info **) + $(info ** https://docutils.sourceforge.io/docs/dev/repository.html ) + $(info **) + $(info ********************************************) + $(error NOTICE: rst2man required to generate man pages) endif rst2man $(RST2MAN_OPTS) $< > $@
tools/tracing/rtla/Makefile +35 -0
@@ -58,6 +58,41 @@ else DOCSRC = $(SRCTREE)/../../../Documentation/tools/rtla/ endif +LIBTRACEEVENT_MIN_VERSION = 1.5 +LIBTRACEFS_MIN_VERSION = 1.3 + +TEST_LIBTRACEEVENT = $(shell sh -c "$(PKG_CONFIG) --atleast-version $(LIBTRACEEVENT_MIN_VERSION) libtraceevent > /dev/null 2>&1 || echo n") +ifeq ("$(TEST_LIBTRACEEVENT)", "n") +.PHONY: warning_traceevent +warning_traceevent: + @echo "********************************************" + @echo "** NOTICE: libtraceevent version $(LIBTRACEEVENT_MIN_VERSION) or higher not found" + @echo "**" + @echo "** Consider installing the latest libtraceevent from your" + @echo "** distribution, e.g., 'dnf install libtraceevent' on Fedora," + @echo "** or from source:" + @echo "**" + @echo "** https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ " + @echo "**" + @echo "********************************************" +endif + +TEST_LIBTRACEFS = $(shell sh -c "$(PKG_CONFIG) --atleast-version $(LIBTRACEFS_MIN_VERSION) libtracefs > /dev/null 2>&1 || echo n") +ifeq ("$(TEST_LIBTRACEFS)", "n") +.PHONY: warning_tracefs +warning_tracefs: + @echo "********************************************" + @echo "** NOTICE: libtracefs version $(LIBTRACEFS_MIN_VERSION) or higher not found" + @echo "**" + @echo "** Consider installing the latest libtracefs from your" + @echo "** distribution, e.g., 'dnf install libtracefs' on Fedora," + @echo "** or from source:" + @echo "**" + @echo "** https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ " + @echo "**" + @echo "********************************************" +endif + .PHONY: all all: rtla
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 175/339 f2fs: fix to tag gcing flag on page during file defragment
In reply to Greg Kroah-HartmanFrom: Chao Yu <[email protected]>
[ Upstream commit 2d1fe8a86bf5e0663866fd0da83c2af1e1b0e362 ]
In order to garantee migrated data be persisted during checkpoint, otherwise out-of-order persistency between data and node may cause data corruption after SPOR.
--- fs/f2fs/file.c | 1 + 1 file changed, 1 insertion(+)
fs/f2fs/file.c +1 -0
@@ -2687,6 +2687,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, }set_page_dirty (page); +set_page_private_gcing (page);f2fs_put_page (page,1 ); idx++;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 176/339 xprtrdma: treat all calls not a bcall when bc_serv is NULL
In reply to Greg Kroah-HartmanFrom: Kinglong Mee <[email protected]>
[ Upstream commit 11270e7ca268e8d61b5d9e5c3a54bd1550642c9c ]
When a rdma server returns a fault format reply, nfs v3 client may treats it as a bcall when bc service is not exist.
The debug message at rpcrdma_bc_receive_call are,
[56579.837169] RPC: rpcrdma_bc_receive_call: callback XID 00000001, length=20 [56579.837174] RPC: rpcrdma_bc_receive_call: 00 00 00 01 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 04
After that, rpcrdma_bc_receive_call will meets NULL pointer as,
[ 226.057890] BUG: unable to handle kernel NULL pointer dereference at 00000000000000c8 ... [ 226.058704] RIP: 0010:_raw_spin_lock+0xc/0x20 ... [ 226.059732] Call Trace: [ 226.059878] rpcrdma_bc_receive_call+0x138/0x327 [rpcrdma] [ 226.060011] __ib_process_cq+0x89/0x170 [ib_core] [ 226.060092] ib_cq_poll_work+0x26/0x80 [ib_core] [ 226.060257] process_one_work+0x1a7/0x360 [ 226.060367] ? create_worker+0x1a0/0x1a0 [ 226.060440] worker_thread+0x30/0x390 [ 226.060500] ? create_worker+0x1a0/0x1a0 [ 226.060574] kthread+0x116/0x130 [ 226.060661] ? kthread_flush_work_fn+0x10/0x10 [ 226.060724] ret_from_fork+0x35/0x40
...
--- net/sunrpc/xprtrdma/rpc_rdma.c | 5 +++++ 1 file changed, 5 insertions(+)
net/sunrpc/xprtrdma/rpc_rdma.c +5 -0
@@ -1121,6 +1121,7 @@ static bool rpcrdma_is_bcall(struct rpcrdma_xprt *r_xprt, struct rpcrdma_rep *rep) #if defined(CONFIG_SUNRPC_BACKCHANNEL) { + struct rpc_xprt *xprt = &r_xprt->rx_xprt;struct xdr_stream *xdr = &rep->rr_stream;__be32 *p;
@@ -1144,6 +1145,10 @@ rpcrdma_is_bcall(struct rpcrdma_xprt *r_xprt, struct rpcrdma_rep *rep)if (*p !=cpu_to_be32 (RPC_CALL ))return false; +/* No bc service. */ +if (xprt->bc_serv ==NULL ) +return false; +/* Now that we are sure this is a backchannel call, * advance to the RPC header. */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 177/339 drm/bridge: ti-sn65dsi83: Handle dsi_lanes == 0 as invalid
In reply to Greg Kroah-HartmanFrom: Marek Vasut <[email protected]>
[ Upstream commit edbc7960bef7fd71ef1e44d0df15b864784b14c8 ]
Handle empty data-lanes = < >; property, which translates to dsi_lanes = 0 as invalid.
--- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/bridge/ti-sn65dsi83.c +1 -1
@@ -573,7 +573,7 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model) ctx->host_node =of_graph_get_remote_port_parent (endpoint);of_node_put (endpoint); -if (ctx->dsi_lanes <0 || ctx->dsi_lanes >4 ) { +if (ctx->dsi_lanes <=0 || ctx->dsi_lanes >4 ) { ret = -EINVAL ; goto err_put_node; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 178/339 drm/panfrost: Job should reference MMU not file_priv
In reply to Greg Kroah-HartmanFrom: Steven Price <[email protected]>
[ Upstream commit 6e516faf04317db2c46cbec4e3b78b4653a5b109 ]
For a while now it's been allowed for a MMU context to outlive it's corresponding panfrost_priv, however the job structure still references panfrost_priv to get hold of the MMU context. If panfrost_priv has been freed this is a use-after-free which I've been able to trigger resulting in a splat.
To fix this, drop the reference to panfrost_priv in the job structure and add a direct reference to the MMU structure which is what's actually needed.
--- drivers/gpu/drm/panfrost/panfrost_drv.c | 5 +++-- drivers/gpu/drm/panfrost/panfrost_job.c | 6 +++--- drivers/gpu/drm/panfrost/panfrost_job.h | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-)
drivers/gpu/drm/panfrost/panfrost_drv.c +3 -2
@@ -233,6 +233,7 @@ static int panfrost_ioctl_submit(struct drm_device *dev, void *data, struct drm_file *file) {struct panfrost_device *pfdev = dev->dev_private; +struct panfrost_file_priv *file_priv = file->driver_priv;struct drm_panfrost_submit *args = data;struct drm_syncobj *sync_out =NULL ;struct panfrost_job *job;
@@ -262,12 +263,12 @@ static int panfrost_ioctl_submit(struct drm_device *dev, void *data, job->jc = args->jc; job->requirements = args->requirements; job->flush_id =panfrost_gpu_get_latest_flush_id (pfdev); - job->file_priv = file->driver_priv; + job->mmu = file_priv->mmu; slot =panfrost_job_get_slot (job); ret =drm_sched_job_init (&job->base, - &job->file_priv->sched_entity[slot], + &file_priv->sched_entity[slot],NULL );if (ret) goto out_put_job;
drivers/gpu/drm/panfrost/panfrost_job.c +3 -3
@@ -201,7 +201,7 @@ static void panfrost_job_hw_submit(struct panfrost_job *job, int js)return ; } - cfg =panfrost_mmu_as_get (pfdev, job->file_priv->mmu); + cfg =panfrost_mmu_as_get (pfdev, job->mmu);job_write (pfdev,JS_HEAD_NEXT_LO (js),lower_32_bits (jc_head));job_write (pfdev,JS_HEAD_NEXT_HI (js),upper_32_bits (jc_head));
@@ -431,7 +431,7 @@ static void panfrost_job_handle_err(struct panfrost_device *pfdev, job->jc =0 ; } -panfrost_mmu_as_put (pfdev, job->file_priv->mmu); +panfrost_mmu_as_put (pfdev, job->mmu);panfrost_devfreq_record_idle (&pfdev->pfdevfreq);if (signal_fence)
@@ -452,7 +452,7 @@ static void panfrost_job_handle_done(struct panfrost_device *pfdev,* happen when we receive the DONE interrupt while doing a GPU reset). */ job->jc =0 ; -panfrost_mmu_as_put (pfdev, job->file_priv->mmu); +panfrost_mmu_as_put (pfdev, job->mmu);panfrost_devfreq_record_idle (&pfdev->pfdevfreq);dma_fence_signal_locked (job->done_fence);
drivers/gpu/drm/panfrost/panfrost_job.h +1 -1
@@ -17,7 +17,7 @@ struct panfrost_job {struct kref refcount;struct panfrost_device *pfdev; -struct panfrost_file_priv *file_priv; +struct panfrost_mmu *mmu;/* Fence to be signaled by IRQ handler when the job is complete. */ struct dma_fence *done_fence;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 179/339 powerpc/papr_scm: dont requests stats with 0 sized stats buffer
In reply to Greg Kroah-HartmanFrom: Vaibhav Jain <[email protected]>
[ Upstream commit 07bf9431b1590d1cd7a8d62075d0b50b073f0495 ]
Sachin reported [1] that on a POWER-10 lpar he is seeing a kernel panic being reported with vPMEM when papr_scm probe is being called. The panic is of the form below and is observed only with following option disabled(profile) for the said LPAR 'Enable Performance Information Collection' in the HMC:
Kernel attempted to write user page (1c) - exploit attempt? (uid: 0)
BUG: Kernel NULL pointer dereference on write at 0x0000001c
Faulting instruction address: 0xc008000001b90844
Oops: Kernel access of bad area, sig: 11 [#1]
<snip>
NIP [c008000001b90844] drc_pmem_query_stats+0x5c/0x270 [papr_scm]
LR [c008000001b92794] papr_scm_probe+0x2ac/0x6ec [papr_scm]
Call Trace:
0xc00000000941bca0 (unreliable)
papr_scm_probe+0x2ac/0x6ec [papr_scm]
platform_probe+0x98/0x150
really_probe+0xfc/0x510
__driver_probe_device+0x17c/0x230
<snip>
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Fatal exceptionOn investigation looks like this panic was caused due to a 'stat_buffer' of size==0 being provided to drc_pmem_query_stats() to fetch all performance stats-ids of an NVDIMM. However drc_pmem_query_stats() shouldn't have been called since the vPMEM NVDIMM doesn't support and performance stat-id's. This was caused due to missing check for 'p->stat_buffer_len' at the beginning of papr_scm_pmu_check_events() which indicates that the NVDIMM doesn't support performance-stats.
Fix this by introducing the check for 'p->stat_buffer_len' at the beginning of papr_scm_pmu_check_events().
[1] https://lore.kernel.org/all/[email protected]
--- arch/powerpc/platforms/pseries/papr_scm.c | 3 +++ 1 file changed, 3 insertions(+)
arch/powerpc/platforms/pseries/papr_scm.c +3 -0
@@ -465,6 +465,9 @@ static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmuu32 available_events;int index, rc =0 ; +if (!p->stat_buffer_len) +return -ENOENT ; + available_events = (p->stat_buffer_len -sizeof (struct papr_scm_perf_stats )) /sizeof (struct papr_scm_perf_stat );if (available_events ==0 )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 180/339 netfilter: nat: really support inet nat without l3 address
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
[ Upstream commit 282e5f8fe907dc3f2fbf9f2103b0e62ffc3a68a5 ]
When no l3 address is given, priv->family is set to NFPROTO_INET and the evaluation function isn't called.
Call it too so l4-only rewrite can work.
Also add a test case for this.
--- net/netfilter/nft_nat.c | 3 +- tools/testing/selftests/netfilter/nft_nat.sh | 43 ++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-)
net/netfilter/nft_nat.c +2 -1
@@ -335,7 +335,8 @@ static void nft_nat_inet_eval(const struct nft_expr *expr, {const struct nft_nat *priv =nft_expr_priv (expr); -if (priv->family ==nft_pf (pkt)) +if (priv->family ==nft_pf (pkt) || + priv->family ==NFPROTO_INET )nft_nat_eval (expr, regs, pkt); }
tools/testing/selftests/netfilter/nft_nat.sh +43 -0
55 lines not on this page · raw message
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 181/339 netfilter: nf_tables: use kfree_rcu(ptr, rcu) to release hooks in clean_net path
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ Upstream commit ab5e5c062f67c5ae8cd07f0632ffa62dc0e7d169 ]
Use kfree_rcu(ptr, rcu) variant instead as described by ae089831ff28 ("netfilter: nf_tables: prefer kfree_rcu(ptr, rcu) variant").
--- net/netfilter/nf_tables_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/nf_tables_api.c +1 -1
@@ -7326,7 +7326,7 @@ static void __nft_unregister_flowtable_net_hooks(struct net *net,nf_unregister_net_hook (net, &hook->ops);if (release_netdev) {list_del (&hook->list); -kfree_rcu (hook); +kfree_rcu (hook, rcu); } } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 182/339 netfilter: nf_tables: delete flowtable hooks via transaction list
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ Upstream commit b6d9014a3335194590abdd2a2471ef5147a67645 ]
Remove inactive bool field in nft_hook object that was introduced in abadb2f865d7 ("netfilter: nf_tables: delete devices from flowtable"). Move stale flowtable hooks to transaction list instead.
Deleting twice the same device does not result in ENOENT.
--- include/net/netfilter/nf_tables.h | 1 - net/netfilter/nf_tables_api.c | 31 ++++++------------------------- 2 files changed, 6 insertions(+), 26 deletions(-)
include/net/netfilter/nf_tables.h +0 -1
@@ -1090,7 +1090,6 @@ struct nft_stats {struct nft_hook {struct list_head list; -bool inactive;struct nf_hook_ops ops;struct rcu_head rcu; };
net/netfilter/nf_tables_api.c +6 -25
@@ -1914,7 +1914,6 @@ static struct nft_hook *nft_netdev_hook_alloc(struct net *net, goto err_hook_dev; } hook->ops.dev = dev; - hook->inactive = false;return hook;
@@ -7612,6 +7611,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx, {const struct nlattr *const *nla = ctx->nla;struct nft_flowtable_hook flowtable_hook; +LIST_HEAD (flowtable_del_list);struct nft_hook *this, *hook;struct nft_trans *trans;int err;
@@ -7627,7 +7627,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx, err = -ENOENT ; goto err_flowtable_del_hook; } - hook->inactive = true; +list_move (&hook->list, &flowtable_del_list); } trans = nft_trans_alloc(ctx, NFT_MSG_DELFLOWTABLE,
@@ -7640,6 +7640,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,nft_trans_flowtable (trans) = flowtable;nft_trans_flowtable_update (trans) = true;INIT_LIST_HEAD (&nft_trans_flowtable_hooks (trans)); +list_splice (&flowtable_del_list, &nft_trans_flowtable_hooks (trans));nft_flowtable_hook_release (&flowtable_hook);nft_trans_commit_list_add_tail (ctx->net, trans);
@@ -7647,13 +7648,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,return 0 ; err_flowtable_del_hook: -list_for_each_entry (this, &flowtable_hook.list, list) { - hook =nft_hook_list_find (&flowtable->hook_list, this); -if (!hook) -break ; - - hook->inactive = false; - } +list_splice (&flowtable_del_list, &flowtable->hook_list);nft_flowtable_hook_release (&flowtable_hook);return err;
@@ -8559,17 +8554,6 @@ void nft_chain_del(struct nft_chain *chain)list_del_rcu (&chain->list); } -static void nft_flowtable_hooks_del (struct nft_flowtable *flowtable, -struct list_head *hook_list) -{ -struct nft_hook *hook, *next; - -list_for_each_entry_safe (hook, next, &flowtable->hook_list, list) { -if (hook->inactive) -list_move (&hook->list, hook_list); - } -} -static void nf_tables_module_autoload_cleanup (struct net *net) {struct nftables_pernet *nft_net =nft_pernet (net);
@@ -8914,8 +8898,6 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)break ;case NFT_MSG_DELFLOWTABLE :if (nft_trans_flowtable_update (trans)) { -nft_flowtable_hooks_del (nft_trans_flowtable (trans), - &nft_trans_flowtable_hooks (trans)); nf_tables_flowtable_notify(&trans->ctx, nft_trans_flowtable(trans), &nft_trans_flowtable_hooks(trans),
@@ -8996,7 +8978,6 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)struct nftables_pernet *nft_net =nft_pernet (net);struct nft_trans *trans, *next;struct nft_trans_elem *te; -struct nft_hook *hook;if (action ==NFNL_ABORT_VALIDATE &&nf_tables_validate (net) <0 )
@@ -9127,8 +9108,8 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)break ;case NFT_MSG_DELFLOWTABLE :if (nft_trans_flowtable_update (trans)) { -list_for_each_entry (hook, &nft_trans_flowtable (trans)->hook_list, list) - hook->inactive = false; +list_splice (&nft_trans_flowtable_hooks (trans), + &nft_trans_flowtable (trans)->hook_list); }else { trans->ctx.table->use++;nft_clear (trans->ctx.net,nft_trans_flowtable (trans));
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 183/339 powerpc/kasan: Force thread size increase with KASAN
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
[ Upstream commit 3e8635fb2e072672cbc650989ffedf8300ad67fb ]
KASAN causes increased stack usage, which can lead to stack overflows.
The logic in Kconfig to suggest a larger default doesn't work if a user has CONFIG_EXPERT enabled and has an existing .config with a smaller value.
Follow the lead of x86 and arm64, and force the thread size to be increased when KASAN is enabled.
That also has the effect of enlarging the stack for 64-bit KASAN builds, which is also desirable.
--- arch/powerpc/Kconfig | 1 - arch/powerpc/include/asm/thread_info.h | 10 ++++++++-- 2 files changed, 8 insertions(+), 3 deletions(-)
arch/powerpc/Kconfig +0 -1
@@ -771,7 +771,6 @@ config THREAD_SHIFT range 13 15 default "15" if PPC_256K_PAGES default "14" if PPC64 - default "14" if KASAN default "13" help Used to define the stack size. The default is almost always what you
arch/powerpc/include/asm/thread_info.h +8 -2
@@ -14,10 +14,16 @@#ifdef __KERNEL__ -#if defined(CONFIG_VMAP_STACK ) &&CONFIG_THREAD_SHIFT <PAGE_SHIFT +#ifdef CONFIG_KASAN +#define MIN_THREAD_SHIFT (CONFIG_THREAD_SHIFT + 1) +#else +#define MIN_THREAD_SHIFT CONFIG_THREAD_SHIFT +#endif + +#if defined(CONFIG_VMAP_STACK ) &&MIN_THREAD_SHIFT <PAGE_SHIFT #define THREAD_SHIFT PAGE_SHIFT#else -#define THREAD_SHIFT CONFIG_THREAD_SHIFT +#define THREAD_SHIFT MIN_THREAD_SHIFT#endif #define THREAD_SIZE (1 << THREAD_SHIFT)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 184/339 NFSD: Fix potential use-after-free in nfsd_file_put()
In reply to Greg Kroah-HartmanFrom: Chuck Lever <[email protected]>
[ Upstream commit b6c71c66b0ad8f2b59d9bc08c7a5079b110bec01 ]
nfsd_file_put_noref() can free @nf, so don't dereference @nf immediately upon return from nfsd_file_put_noref().
--- fs/nfsd/filecache.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
fs/nfsd/filecache.c +5 -4
@@ -306,11 +306,12 @@ nfsd_file_put(struct nfsd_file *nf)if (test_bit (NFSD_FILE_HASHED , &nf->nf_flags) ==0 ) {nfsd_file_flush (nf);nfsd_file_put_noref (nf); - }else { + }else if (nf->nf_file) {nfsd_file_put_noref (nf); -if (nf->nf_file) -nfsd_file_schedule_laundrette (); - } +nfsd_file_schedule_laundrette (); + }else +nfsd_file_put_noref (nf); +if (atomic_long_read (&nfsd_filecache_count) >=NFSD_FILE_LRU_LIMIT )nfsd_file_gc (); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 185/339 SUNRPC: Trap RDMA segment overflows
In reply to Greg Kroah-HartmanFrom: Chuck Lever <[email protected]>
[ Upstream commit f012e95b377c73c0283f009823c633104dedb337 ]
Prevent svc_rdma_build_writes() from walking off the end of a Write chunk's segment array. Caught with KASAN.
The test that this fix replaces is invalid, and might have been left over from an earlier prototype of the PCL work.
--- net/sunrpc/xprtrdma/svc_rdma_rw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/sunrpc/xprtrdma/svc_rdma_rw.c +2 -2
@@ -478,10 +478,10 @@ svc_rdma_build_writes(struct svc_rdma_write_info *info,unsigned int write_len;u64 offset; - seg = &info->wi_chunk->ch_segments[info->wi_seg_no]; -if (!seg) +if (info->wi_seg_no >= info->wi_chunk->ch_segcount) goto out_overflow; + seg = &info->wi_chunk->ch_segments[info->wi_seg_no]; write_len =min (remaining, seg->rs_length - info->wi_seg_off);if (!write_len) goto out_overflow;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 186/339 netfilter: nf_tables: always initialize flowtable hook list in transaction
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ Upstream commit 2c9e4559773c261900c674a86b8e455911675d71 ]
The hook list is used if nft_trans_flowtable_update(trans) == true. However, initialize this list for other cases for safety reasons.
--- net/netfilter/nf_tables_api.c | 1 + 1 file changed, 1 insertion(+)
net/netfilter/nf_tables_api.c +1 -0
@@ -544,6 +544,7 @@ static int nft_trans_flowtable_add(struct nft_ctx *ctx, int msg_type,if (msg_type ==NFT_MSG_NEWFLOWTABLE )nft_activate_next (ctx->net, flowtable); +INIT_LIST_HEAD (&nft_trans_flowtable_hooks (trans));nft_trans_flowtable (trans) = flowtable;nft_trans_commit_list_add_tail (ctx->net, trans);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 187/339 ata: pata_octeon_cf: Fix refcount leak in octeon_cf_probe
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 10d6bdf532902be1d8aa5900b3c03c5671612aa2 ]
of_find_device_by_node() takes reference, we should use put_device() to release it when not need anymore.
Add missing put_device() to avoid refcount leak.
--- drivers/ata/pata_octeon_cf.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/ata/pata_octeon_cf.c +3 -0
@@ -856,12 +856,14 @@ static int octeon_cf_probe(struct platform_device *pdev)int i; res_dma =platform_get_resource (dma_dev,IORESOURCE_MEM ,0 );if (!res_dma) { +put_device (&dma_dev->dev);of_node_put (dma_node);return -EINVAL ; } cf_port->dma_base = (u64 )devm_ioremap (&pdev->dev, res_dma->start,resource_size (res_dma));if (!cf_port->dma_base) { +put_device (&dma_dev->dev);of_node_put (dma_node);return -EINVAL ; }
@@ -871,6 +873,7 @@ static int octeon_cf_probe(struct platform_device *pdev) irq = i; irq_handler = octeon_cf_interrupt; } +put_device (&dma_dev->dev); }of_node_put (dma_node); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 188/339 netfilter: nf_tables: release new hooks on unsupported flowtable flags
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ Upstream commit c271cc9febaaa1bcbc0842d1ee30466aa6148ea8 ]
Release the list of new hooks that are pending to be registered in case that unsupported flowtable flags are provided.
--- net/netfilter/nf_tables_api.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
net/netfilter/nf_tables_api.c +8 -4
@@ -7427,11 +7427,15 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh,if (nla[NFTA_FLOWTABLE_FLAGS ]) { flags =ntohl (nla_get_be32 (nla[NFTA_FLOWTABLE_FLAGS ])); -if (flags & ~NFT_FLOWTABLE_MASK ) -return -EOPNOTSUPP ; +if (flags & ~NFT_FLOWTABLE_MASK ) { + err = -EOPNOTSUPP ; + goto err_flowtable_update_hook; + }if ((flowtable->data.flags &NFT_FLOWTABLE_HW_OFFLOAD ) ^ - (flags &NFT_FLOWTABLE_HW_OFFLOAD )) -return -EOPNOTSUPP ; + (flags &NFT_FLOWTABLE_HW_OFFLOAD )) { + err = -EOPNOTSUPP ; + goto err_flowtable_update_hook; + } }else { flags = flowtable->data.flags; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 189/339 netfilter: nf_tables: memleak flow rule from commit path
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ Upstream commit 9dd732e0bdf538b1b76dc7c157e2b5e560ff30d3 ]
Abort path release flow rule object, however, commit path does not. Update code to destroy these objects before releasing the transaction.
--- net/netfilter/nf_tables_api.c | 6 ++++++ 1 file changed, 6 insertions(+)
net/netfilter/nf_tables_api.c +6 -0
@@ -8323,6 +8323,9 @@ static void nft_commit_release(struct nft_trans *trans)nf_tables_chain_destroy (&trans->ctx);break ;case NFT_MSG_DELRULE : +if (trans->ctx.chain->flags &NFT_CHAIN_HW_OFFLOAD ) +nft_flow_rule_destroy (nft_trans_flow_rule (trans)); +nf_tables_rule_destroy (&trans->ctx,nft_trans_rule (trans));break ;case NFT_MSG_DELSET :
@@ -8813,6 +8816,9 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)nf_tables_rule_notify (&trans->ctx,nft_trans_rule (trans),NFT_MSG_NEWRULE ); +if (trans->ctx.chain->flags &NFT_CHAIN_HW_OFFLOAD ) +nft_flow_rule_destroy (nft_trans_flow_rule (trans)); +nft_trans_destroy (trans);break ;case NFT_MSG_DELRULE :
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 190/339 netfilter: nf_tables: bail out early if hardware offload is not supported
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ Upstream commit 3a41c64d9c1185a2f3a184015e2a9b78bfc99c71 ]
If user requests for NFT_CHAIN_HW_OFFLOAD, then check if either device provides the .ndo_setup_tc interface or there is an indirect flow block that has been registered. Otherwise, bail out early from the preparation phase. Moreover, validate that family == NFPROTO_NETDEV and hook is NF_NETDEV_INGRESS.
--- include/net/flow_offload.h | 1 + include/net/netfilter/nf_tables_offload.h | 2 +- net/core/flow_offload.c | 6 ++++++ net/netfilter/nf_tables_api.c | 2 +- net/netfilter/nf_tables_offload.c | 23 ++++++++++++++++++++++- 5 files changed, 31 insertions(+), 3 deletions(-)
include/net/flow_offload.h +1 -0
@@ -612,5 +612,6 @@ int flow_indr_dev_setup_offload(struct net_device *dev, struct Qdisc *sch, enum tc_setup_type type, void *data, struct flow_block_offload *bo, void (*cleanup)(struct flow_block_cb *block_cb)); +bool flow_indr_dev_exists (void );#endif /* _NET_FLOW_OFFLOAD_H */
include/net/netfilter/nf_tables_offload.h +1 -1
@@ -92,7 +92,7 @@ int nft_flow_rule_offload_commit(struct net *net); NFT_OFFLOAD_MATCH(__key, __base, __field, __len, __reg) \memset (&(__reg)->mask,0xff , (__reg)->len); -int nft_chain_offload_priority (struct nft_base_chain *basechain); +bool nft_chain_offload_support (const struct nft_base_chain *basechain);int nft_offload_init (void );void nft_offload_exit (void );
net/core/flow_offload.c +6 -0
@@ -595,3 +595,9 @@ int flow_indr_dev_setup_offload(struct net_device *dev, struct Qdisc *sch,return (bo &&list_empty (&bo->cb_list)) ? -EOPNOTSUPP : count; }EXPORT_SYMBOL (flow_indr_dev_setup_offload); + +bool flow_indr_dev_exists (void ) +{ +return !list_empty (&flow_block_indr_dev_list); +} +EXPORT_SYMBOL (flow_indr_dev_exists);
net/netfilter/nf_tables_api.c +1 -1
@@ -2166,7 +2166,7 @@ static int nft_basechain_init(struct nft_base_chain *basechain, u8 family, chain->flags |=NFT_CHAIN_BASE | flags; basechain->policy =NF_ACCEPT ;if (chain->flags &NFT_CHAIN_HW_OFFLOAD && -nft_chain_offload_priority (basechain) <0 ) + !nft_chain_offload_support (basechain))return -EOPNOTSUPP ;flow_block_init (&basechain->flow_block);
net/netfilter/nf_tables_offload.c +22 -1
@@ -208,7 +208,7 @@ static int nft_setup_cb_call(enum tc_setup_type type, void *type_data,return 0 ; } -int nft_chain_offload_priority (struct nft_base_chain *basechain) +static int nft_chain_offload_priority (const struct nft_base_chain *basechain) {if (basechain->ops.priority <=0 || basechain->ops.priority >USHRT_MAX )
@@ -217,6 +217,27 @@ int nft_chain_offload_priority(struct nft_base_chain *basechain)return 0 ; } +bool nft_chain_offload_support (const struct nft_base_chain *basechain) +{ +struct net_device *dev; +struct nft_hook *hook; + +if (nft_chain_offload_priority (basechain) <0 ) +return false; + +list_for_each_entry (hook, &basechain->hook_list, list) { +if (hook->ops.pf !=NFPROTO_NETDEV || + hook->ops.hooknum !=NF_NETDEV_INGRESS ) +return false; + + dev = hook->ops.dev; +if (!dev->netdev_ops->ndo_setup_tc && !flow_indr_dev_exists ()) +return false; + } + +return true; +} + static void nft_flow_cls_offload_setup(struct flow_cls_offload *cls_flow, const struct nft_base_chain *basechain, const struct nft_rule *rule,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 191/339 amt: fix wrong usage of pskb_may_pull()
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
[ Upstream commit f55a07074fdd38cab8c097ac5bd397d68eff733c ]
It adds missing pskb_may_pull() in amt_update_handler() and amt_multicast_data_handler().
And it fixes wrong parameter of pskb_may_pull() in amt_advertisement_handler() and amt_membership_query_handler().
--- drivers/net/amt.c | 55 +++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 18 deletions(-)
drivers/net/amt.c +37 -18
@@ -2220,8 +2220,7 @@ static bool amt_advertisement_handler(struct amt_dev *amt, struct sk_buff *skb)struct amt_header_advertisement *amta;int hdr_size; - hdr_size =sizeof (*amta) -sizeof (struct amt_header ); - + hdr_size =sizeof (*amta) +sizeof (struct udphdr );if (!pskb_may_pull (skb, hdr_size))return true;
@@ -2251,19 +2250,27 @@ static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb)struct ethhdr *eth;struct iphdr *iph; + hdr_size =sizeof (*amtmd) +sizeof (struct udphdr ); +if (!pskb_may_pull (skb, hdr_size)) +return true; + amtmd = (struct amt_header_mcast_data *)(udp_hdr (skb) +1 );if (amtmd->reserved || amtmd->version)return true; - hdr_size =sizeof (*amtmd) +sizeof (struct udphdr );if (iptunnel_pull_header (skb, hdr_size,htons (ETH_P_IP ), false))return true; +skb_reset_network_header (skb);skb_push (skb,sizeof (*eth));skb_reset_mac_header (skb);skb_pull (skb,sizeof (*eth)); eth =eth_hdr (skb); + +if (!pskb_may_pull (skb,sizeof (*iph))) +return true; iph =ip_hdr (skb); +if (iph->version ==4 ) {if (!ipv4_is_multicast (iph->daddr))return true;
@@ -2274,6 +2281,9 @@ static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb) }else if (iph->version ==6 ) {struct ipv6hdr *ip6h; +if (!pskb_may_pull (skb,sizeof (*ip6h))) +return true; + ip6h =ipv6_hdr (skb);if (!ipv6_addr_is_multicast (&ip6h->daddr))return true;
@@ -2306,8 +2316,7 @@ static bool amt_membership_query_handler(struct amt_dev *amt,struct iphdr *iph;int hdr_size, len; - hdr_size =sizeof (*amtmq) -sizeof (struct amt_header ); - + hdr_size =sizeof (*amtmq) +sizeof (struct udphdr );if (!pskb_may_pull (skb, hdr_size))return true;
@@ -2315,22 +2324,27 @@ static bool amt_membership_query_handler(struct amt_dev *amt,if (amtmq->reserved || amtmq->version)return true; - hdr_size =sizeof (*amtmq) +sizeof (struct udphdr ) -sizeof (*eth); + hdr_size -=sizeof (*eth);if (iptunnel_pull_header (skb, hdr_size,htons (ETH_P_TEB ), false))return true; + oeth =eth_hdr (skb);skb_reset_mac_header (skb);skb_pull (skb,sizeof (*eth));skb_reset_network_header (skb); eth =eth_hdr (skb); +if (!pskb_may_pull (skb,sizeof (*iph))) +return true; + iph =ip_hdr (skb);if (iph->version ==4 ) { -if (!ipv4_is_multicast (iph->daddr)) -return true;if (!pskb_may_pull (skb,sizeof (*iph) +AMT_IPHDR_OPTS +sizeof (*ihv3)))return true; +if (!ipv4_is_multicast (iph->daddr)) +return true; + ihv3 =skb_pull (skb,sizeof (*iph) +AMT_IPHDR_OPTS );skb_reset_transport_header (skb);skb_push (skb,sizeof (*iph) +AMT_IPHDR_OPTS );
@@ -2345,15 +2359,17 @@ static bool amt_membership_query_handler(struct amt_dev *amt,ip_eth_mc_map (iph->daddr, eth->h_dest);#if IS_ENABLED (CONFIG_IPV6 ) } else if (iph->version == 6) { -struct ipv6hdr *ip6h =ipv6_hdr (skb);struct mld2_query *mld2q; +struct ipv6hdr *ip6h; -if (!ipv6_addr_is_multicast (&ip6h->daddr)) -return true;if (!pskb_may_pull (skb,sizeof (*ip6h) +AMT_IP6HDR_OPTS +sizeof (*mld2q)))return true; + ip6h =ipv6_hdr (skb); +if (!ipv6_addr_is_multicast (&ip6h->daddr)) +return true; + mld2q =skb_pull (skb,sizeof (*ip6h) +AMT_IP6HDR_OPTS );skb_reset_transport_header (skb);skb_push (skb,sizeof (*ip6h) +AMT_IP6HDR_OPTS );
@@ -2389,23 +2405,23 @@ static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb) {struct amt_header_membership_update *amtmu;struct amt_tunnel_list *tunnel; -struct udphdr *udph;struct ethhdr *eth;struct iphdr *iph; -int len; +int len, hdr_size; iph =ip_hdr (skb); - udph =udp_hdr (skb); -if (__iptunnel_pull_header (skb,sizeof (*udph), skb->protocol, - false, false)) + hdr_size =sizeof (*amtmu) +sizeof (struct udphdr ); +if (!pskb_may_pull (skb, hdr_size))return true; - amtmu = (struct amt_header_membership_update *)skb->data; + amtmu = (struct amt_header_membership_update *)(udp_hdr (skb) +1 );if (amtmu->reserved || amtmu->version)return true; -skb_pull (skb,sizeof (*amtmu)); +if (iptunnel_pull_header (skb, hdr_size, skb->protocol, false)) +return true; +skb_reset_network_header (skb);list_for_each_entry_rcu (tunnel, &amt->tunnel_list, list) {
@@ -2426,6 +2442,9 @@ static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb)return true; report: +if (!pskb_may_pull (skb,sizeof (*iph))) +return true; + iph =ip_hdr (skb);if (iph->version ==4 ) {if (ip_mc_check_igmp (skb)) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 192/339 amt: fix possible null-ptr-deref in amt_rcv()
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
[ Upstream commit d16207f92a4a823c48b4ea953ad51f4483456768 ]
When amt interface receives amt message, it tries to obtain amt private data from sock.
If there is no amt private data, it frees an skb immediately. After kfree_skb(), it increases the rx_dropped stats.
But in order to use rx_dropped, amt private data is needed. So, it makes amt_rcv() to do not increase rx_dropped stats when it can not obtain amt private data.
--- drivers/net/amt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/amt.c +2 -1
@@ -2698,7 +2698,8 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb) amt =rcu_dereference_sk_user_data (sk);if (!amt) { err = true; - goto drop; +kfree_skb (skb); + goto out; } skb->dev = amt->dev;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 193/339 amt: fix wrong type string definition
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
[ Upstream commit d7970039d87c926bb648982e920cb9851c19f3e1 ]
amt message type definition starts from 1, not 0.
But type_str[] starts from 0.
So, it prints wrong type information.
--- drivers/net/amt.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/amt.c +1 -0
@@ -51,6 +51,7 @@ static char *status_str[] = { };static char *type_str[] = { +"" ,/* Type 0 is not defined */ "AMT_MSG_DISCOVERY" ,"AMT_MSG_ADVERTISEMENT" ,"AMT_MSG_REQUEST" ,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 194/339 net: ethernet: bgmac: Fix refcount leak in bcma_mdio_mii_register
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit b8d91399775c55162073bb2aca061ec42e3d4bc1 ]
of_get_child_by_name() 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.
--- drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c +1 -0
@@ -234,6 +234,7 @@ struct mii_bus *bcma_mdio_mii_register(struct bgmac *bgmac) np =of_get_child_by_name (core->dev.of_node,"mdio" ); err =of_mdiobus_register (mii_bus, np); +of_node_put (np);if (err) {dev_err (&core->dev,"Registration of mii bus failed\n" ); goto err_free_bus;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 195/339 xen: unexport __init-annotated xen_xlate_map_ballooned_pages()
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
[ Upstream commit dbac14a5a05ff8e1ce7c0da0e1f520ce39ec62ea ]
EXPORT_SYMBOL and __init is a bad combination because the .init.text section is freed up after the initialization. Hence, modules cannot use symbols annotated __init. The access to a freed symbol may end up with kernel panic.
modpost used to detect it, but it has been broken for a decade.
Recently, I fixed modpost so it started to warn it again, then this showed up in linux-next builds.
There are two ways to fix it:
- Remove __init
- Remove EXPORT_SYMBOL
I chose the latter for this case because none of the in-tree call-sites (arch/arm/xen/enlighten.c, arch/x86/xen/grant-table.c) is compiled as modular.
--- drivers/xen/xlate_mmu.c | 1 - 1 file changed, 1 deletion(-)
drivers/xen/xlate_mmu.c +0 -1
@@ -261,7 +261,6 @@ int __init xen_xlate_map_ballooned_pages(xen_pfn_t **gfns, void **virt,return 0 ; } -EXPORT_SYMBOL_GPL (xen_xlate_map_ballooned_pages);struct remap_pfn {struct mm_struct *mm;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 196/339 stmmac: intel: Fix an error handling path in intel_eth_pci_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 5e74a4b3ec1816e3bbfd715d46ae29d2508079cb ]
When the managed API is used, there is no need to explicitly call pci_free_irq_vectors().
This looks to be a left-over from the commit in the Fixes tag. Only the .remove() function had been updated.
So remove this unused function call and update goto label accordingly.
--- drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +1 -3
@@ -1072,13 +1072,11 @@ static int intel_eth_pci_probe(struct pci_dev *pdev, ret =stmmac_dvr_probe (&pdev->dev, plat, &res);if (ret) { - goto err_dvr_probe; + goto err_alloc_irq; }return 0 ; -err_dvr_probe: -pci_free_irq_vectors (pdev); err_alloc_irq:clk_disable_unprepare (plat->stmmac_clk);clk_unregister_fixed_rate (plat->stmmac_clk);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 197/339 af_unix: Fix a data-race in unix_dgram_peer_wake_me().
In reply to Greg Kroah-HartmanFrom: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 662a80946ce13633ae90a55379f1346c10f0c432 ]
unix_dgram_poll() calls unix_dgram_peer_wake_me() without other's lock held and check if its receive queue is full. Here we need to use unix_recvq_full_lockless() instead of unix_recvq_full(), otherwise KCSAN will report a data-race.
--- net/unix/af_unix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/unix/af_unix.c +1 -1
@@ -490,7 +490,7 @@ static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)* -ECONNREFUSED. Otherwise, if we haven't queued any skbs * to other and its full, we will hang waiting for POLLOUT. */ -if (unix_recvq_full (other) && !sock_flag (other,SOCK_DEAD )) +if (unix_recvq_full_lockless (other) && !sock_flag (other,SOCK_DEAD ))return 1 ;if (connected)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 198/339 selftests net: fix bpf build error
In reply to Greg Kroah-HartmanFrom: Lina Wang <[email protected]>
[ Upstream commit cf67838c4422eab826679b076dad99f96152b4de ]
bpf_helpers.h has been moved to tools/lib/bpf since 5.10, so add more including path.
--- tools/testing/selftests/net/bpf/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/testing/selftests/net/bpf/Makefile +2 -2
@@ -2,6 +2,7 @@ CLANG ?= clang CCINCLUDE += -I../../bpf +CCINCLUDE += -I../../../lib CCINCLUDE += -I../../../../../usr/include/ TEST_CUSTOM_PROGS = $(OUTPUT)/bpf/nat6to4.o
@@ -10,5 +11,4 @@ all: $(TEST_CUSTOM_PROGS) $(OUTPUT)/%.o: %.c $(CLANG) -O2 -target bpf -c $< $(CCINCLUDE) -o $@ -clean: - rm -f $(TEST_CUSTOM_PROGS) +EXTRA_CLEAN := $(TEST_CUSTOM_PROGS)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 199/339 x86: drop bogus "cc" clobber from __try_cmpxchg_user_asm()
In reply to Greg Kroah-HartmanFrom: Jan Beulich <[email protected]>
[ Upstream commit 1df931d95f4dc1c11db1123e85d4e08156e46ef9 ]
As noted (and fixed) a couple of times in the past, "=@cc<cond>" outputs and clobbering of "cc" don't work well together. The compiler appears to mean to reject such, but doesn't - in its upstream form - quite manage to yet for "cc". Furthermore two similar macros don't clobber "cc", and clobbering "cc" is pointless in asm()-s for x86 anyway - the compiler always assumes status flags to be clobbered there.
Message-Id: <[email protected]>
--- arch/x86/include/asm/uaccess.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/uaccess.h +1 -1
@@ -439,7 +439,7 @@ do { \ [ptr] "+m" (*_ptr), \[old] " +a" (__old) \ : [new] ltype (__new) \ - : "memory", "cc"); \ + : "memory"); \ if (unlikely(__err)) \ goto label; \ if (unlikely(!success)) \
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 200/339 bpf, arm64: Clear prog->jited_len along prog->jited
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 10f3b29c65bb2fe0d47c2945cd0b4087be1c5218 ]
syzbot reported an illegal copy_to_user() attempt
from bpf_prog_get_info_by_fd() [1]
There was no repro yet on this bug, but I think
that commit 0aef499f3172 ("mm/usercopy: Detect vmalloc overruns") is exposing a prior bug in bpf arm64.
bpf_prog_get_info_by_fd() looks at prog->jited_len to determine if the JIT image can be copied out to user space.
My theory is that syzbot managed to get a prog where prog->jited_len has been set to 43, while prog->bpf_func has ben cleared.
It is not clear why copy_to_user(uinsns, NULL, ulen) is triggering this particular warning.
I thought find_vma_area(NULL) would not find a vm_struct. As we do not hold vmap_area_lock spinlock, it might be possible that the found vm_struct was garbage.
[1]
usercopy: Kernel memory exposure attempt detected from vmalloc (offset 792633534417210172, size 43)! kernel BUG at mm/usercopy.c:101!
Internal error: Oops - BUG: 0 [#1] PREEMPT SMP Modules linked in: CPU: 0 PID: 25002 Comm: syz-executor.1 Not tainted 5.18.0-syzkaller-10139-g8291eaafed36 #0 Hardware name: linux,dummy-virt (DT) pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : usercopy_abort+0x90/0x94 mm/usercopy.c:101 lr : usercopy_abort+0x90/0x94 mm/usercopy.c:89
sp : ffff80000b773a20
x29: ffff80000b773a30 x28: faff80000b745000 x27: ffff80000b773b48
x26: 0000000000000000 x25: 000000000000002b x24: 0000000000000000
x23: 00000000000000e0 x22: ffff80000b75db67 x21: 0000000000000001
x20: 000000000000002b x19: ffff80000b75db3c x18: 00000000fffffffd
x17: 2820636f6c6c616d x16: 76206d6f72662064 x15: 6574636574656420
x14: 74706d6574746120 x13: 2129333420657a69 x12: 73202c3237313031
x11: 3237313434333533 x10: 3336323937207465 x9 : 657275736f707865 x8 : ffff80000a30c550 x7 : ffff80000b773830 x6 : ffff80000b773830 x5 : 0000000000000000 x4 : ffff00007fbbaa10 x3 : 0000000000000000 x2 : 0000000000000000 x1 : f7ff000028fc0000 x0 : 0000000000000064
Call trace: usercopy_abort+0x90/0x94 mm/usercopy.c:89 check_heap_object mm/usercopy.c:186 [inline] __check_object_size mm/usercopy.c:252 [inline] __check_object_size+0x198/0x36c mm/usercopy.c:214 check_object_size include/linux/thread_info.h:199 [inline] check_copy_size include/linux/thread_info.h:235 [inline] copy_to_user include/linux/uaccess.h:159 [inline] bpf_prog_get_info_by_fd.isra.0+0xf14/0xfdc kernel/bpf/syscall.c:3993 bpf_obj_get_info_by_fd+0x12c/0x510 kernel/bpf/syscall.c:4253 __sys_bpf+0x900/0x2150 kernel/bpf/syscall.c:4956 __do_sys_bpf kernel/bpf/syscall.c:5021 [inline] __se_sys_bpf kernel/bpf/syscall.c:5019 [inline] __arm64_sys_bpf+0x28/0x40 kernel/bpf/syscall.c:5019 __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline] invoke_syscall+0x48/0x114 arch/arm64/kernel/syscall.c:52 el0_svc_common.constprop.0+0x44/0xec arch/arm64/kernel/syscall.c:142 do_el0_svc+0xa0/0xc0 arch/arm64/kernel/syscall.c:206 el0_svc+0x44/0xb0 arch/arm64/kernel/entry-common.c:624 el0t_64_sync_handler+0x1ac/0x1b0 arch/arm64/kernel/entry-common.c:642 el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:581 Code: aa0003e3 d00038c0 91248000 97fff65f (d4210000)
--- arch/arm64/net/bpf_jit_comp.c | 1 + 1 file changed, 1 insertion(+)
arch/arm64/net/bpf_jit_comp.c +1 -0
@@ -1261,6 +1261,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)bpf_jit_binary_free (header); prog->bpf_func =NULL ; prog->jited =0 ; + prog->jited_len =0 ; goto out_off; }bpf_jit_binary_lock_ro (header);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 201/339 net: dsa: lantiq_gswip: Fix refcount leak in gswip_gphy_fw_list
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 0737e018a05e2aa352828c52bdeed3b02cff2930 ]
Every iteration of for_each_available_child_of_node() decrements the reference count of the previous node.
when breaking early from a for_each_available_child_of_node() loop, we need to explicitly call of_node_put() on the gphy_fw_np. Add missing of_node_put() to avoid refcount leak.
--- drivers/net/dsa/lantiq_gswip.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/dsa/lantiq_gswip.c +3 -1
@@ -2069,8 +2069,10 @@ static int gswip_gphy_fw_list(struct gswip_priv *priv,for_each_available_child_of_node (gphy_fw_list_np, gphy_fw_np) { err =gswip_gphy_fw_probe (priv, &priv->gphy_fw[i], gphy_fw_np, i); -if (err) +if (err) { +of_node_put (gphy_fw_np); goto remove_gphy; + } i++; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 202/339 net/mlx4_en: Fix wrong return value on ioctl EEPROM query failure
In reply to Greg Kroah-HartmanFrom: Gal Pressman <[email protected]>
[ Upstream commit f5826c8c9d57210a17031af5527056eefdc2b7eb ]
The ioctl EEPROM query wrongly returns success on read failures, fix that by returning the appropriate error code.
--- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +1 -1
@@ -2110,7 +2110,7 @@ static int mlx4_en_get_module_eeprom(struct net_device *dev,en_err (priv,"mlx4_get_module_info i(%d) offset(%d) bytes_to_read(%d) - FAILED (0x%x)\n" , i, offset, ee->len - i, ret); -return 0 ; +return ret; } i += ret;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 203/339 xsk: Fix handling of invalid descriptors in XSK TX batching API
In reply to Greg Kroah-HartmanFrom: Maciej Fijalkowski <[email protected]>
[ Upstream commit d678cbd2f867a564a3c5b276c454e873f43f02f8 ]
xdpxceiver run on a AF_XDP ZC enabled driver revealed a problem with XSK Tx batching API. There is a test that checks how invalid Tx descriptors are handled by AF_XDP. Each valid descriptor is followed by invalid one on Tx side whereas the Rx side expects only to receive a set of valid descriptors.
In current xsk_tx_peek_release_desc_batch() function, the amount of available descriptors is hidden inside xskq_cons_peek_desc_batch(). This can be problematic in cases where invalid descriptors are present due to the fact that xskq_cons_peek_desc_batch() returns only a count of valid descriptors. This means that it is impossible to properly update XSK ring state when calling xskq_cons_release_n().
To address this issue, pull out the contents of xskq_cons_peek_desc_batch() so that callers (currently only xsk_tx_peek_release_desc_batch()) will always be able to update the state of ring properly, as total count of entries is now available and use this value as an argument in xskq_cons_release_n(). By doing so, xskq_cons_peek_desc_batch() can be dropped altogether.
--- net/xdp/xsk.c | 5 +++-- net/xdp/xsk_queue.h | 8 -------- 2 files changed, 3 insertions(+), 10 deletions(-)
net/xdp/xsk.c +3 -2
@@ -373,7 +373,8 @@ u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries) goto out; } - nb_pkts =xskq_cons_peek_desc_batch (xs->tx, pool, max_entries); + max_entries =xskq_cons_nb_entries (xs->tx, max_entries); + nb_pkts =xskq_cons_read_desc_batch (xs->tx, pool, max_entries);if (!nb_pkts) { xs->tx->queue_empty_descs++; goto out;
@@ -389,7 +390,7 @@ u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries)if (!nb_pkts) goto out; -xskq_cons_release_n (xs->tx, nb_pkts); +xskq_cons_release_n (xs->tx, max_entries);__xskq_cons_release (xs->tx); xs->sk.sk_write_space (&xs->sk);
net/xdp/xsk_queue.h +0 -8
@@ -282,14 +282,6 @@ static inline bool xskq_cons_peek_desc(struct xsk_queue *q,return xskq_cons_read_desc (q, desc, pool); } -static inline u32 xskq_cons_peek_desc_batch (struct xsk_queue *q,struct xsk_buff_pool *pool, -u32 max) -{ -u32 entries =xskq_cons_nb_entries (q, max); - -return xskq_cons_read_desc_batch (q, pool, entries); -} -/* To improve performance in the xskq_cons_release functions, only update local state here. * Reflect this to global state when we get new entries from the ring in * xskq_cons_get_entries() and whenever Rx or Tx processing are completed in the NAPI loop.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 204/339 drm/amdgpu: fix limiting AV1 to the first instance on VCN3
In reply to Greg Kroah-HartmanFrom: Christian König <[email protected]>
[ Upstream commit 1d2afeb7983081ecf656c2338c7db6fd405c653c ]
The job is not yet initialized here.
--- drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-)
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +7 -10
@@ -1821,23 +1821,21 @@ static const struct amdgpu_ring_funcs vcn_v3_0_dec_sw_ring_vm_funcs = { .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, }; -static int vcn_v3_0_limit_sched (struct amdgpu_cs_parser *p, -struct amdgpu_job *job) +static int vcn_v3_0_limit_sched (struct amdgpu_cs_parser *p) {struct drm_gpu_scheduler **scheds;/* The create msg must be in the first IB submitted */ -if (atomic_read (&job->base.entity->fence_seq)) +if (atomic_read (&p->entity->fence_seq))return -EINVAL ; scheds = p->adev->gpu_sched[AMDGPU_HW_IP_VCN_DEC ] [AMDGPU_RING_PRIO_DEFAULT ].sched; -drm_sched_entity_modify_sched (job->base.entity, scheds,1 ); +drm_sched_entity_modify_sched (p->entity, scheds,1 );return 0 ; } -static int vcn_v3_0_dec_msg (struct amdgpu_cs_parser *p,struct amdgpu_job *job, -uint64_t addr) +static int vcn_v3_0_dec_msg (struct amdgpu_cs_parser *p,uint64_t addr) {struct ttm_operation_ctx ctx = { false, false };struct amdgpu_bo_va_mapping *map;
@@ -1908,7 +1906,7 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,if (create[0 ] ==0x7 || create[0 ] ==0x10 || create[0 ] ==0x11 )continue ; - r =vcn_v3_0_limit_sched (p, job); + r =vcn_v3_0_limit_sched (p);if (r) goto out; }
@@ -1922,7 +1920,7 @@ static int vcn_v3_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,struct amdgpu_job *job, struct amdgpu_ib *ib) { - struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched); + struct amdgpu_ring *ring = to_amdgpu_ring(p->entity->rq->sched);uint32_t msg_lo =0 , msg_hi =0 ;unsigned i;int r;
@@ -1941,8 +1939,7 @@ static int vcn_v3_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p, msg_hi = val; }else if (reg ==PACKET0 (p->adev->vcn.internal.cmd,0 ) && val ==0 ) { - r =vcn_v3_0_dec_msg (p, job, - ((u64 )msg_hi) <<32 | msg_lo); + r =vcn_v3_0_dec_msg (p, ((u64 )msg_hi) <<32 | msg_lo);if (r)return r; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 205/339 SUNRPC: Fix the calculation of xdr->end in xdr_get_next_encode_buffer()
In reply to Greg Kroah-HartmanFrom: Chuck Lever <[email protected]>
[ Upstream commit 6c254bf3b637dd4ef4f78eb78c7447419c0161d7 ]
I found that NFSD's new NFSv3 READDIRPLUS XDR encoder was screwing up right at the end of the page array. xdr_get_next_encode_buffer() does not compute the value of xdr->end correctly:
* The check to see if we're on the final available page in xdr->buf needs to account for the space consumed by @nbytes.
* The new xdr->end value needs to account for the portion of @nbytes that is to be encoded into the previous buffer.
--- net/sunrpc/xdr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
net/sunrpc/xdr.c +5 -1
@@ -979,7 +979,11 @@ static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr,*/ xdr->p = (void *)p + frag2bytes; space_left = xdr->buf->buflen - xdr->buf->len; - xdr->end = (void *)p +min_t (int, space_left,PAGE_SIZE ); +if (space_left - nbytes >=PAGE_SIZE ) + xdr->end = (void *)p +PAGE_SIZE ; +else + xdr->end = (void *)p + space_left - frag1bytes; + xdr->buf->page_len += frag2bytes; xdr->buf->len += nbytes;return p;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 206/339 net: mdio: unexport __init-annotated mdio_bus_init()
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
[ Upstream commit 35b42dce619701f1300fb8498dae82c9bb1f0263 ]
EXPORT_SYMBOL and __init is a bad combination because the .init.text section is freed up after the initialization. Hence, modules cannot use symbols annotated __init. The access to a freed symbol may end up with kernel panic.
modpost used to detect it, but it has been broken for a decade.
Recently, I fixed modpost so it started to warn it again, then this showed up in linux-next builds.
There are two ways to fix it:
- Remove __init
- Remove EXPORT_SYMBOL
I chose the latter for this case because the only in-tree call-site, drivers/net/phy/phy_device.c is never compiled as modular. (CONFIG_PHYLIB is boolean)
--- drivers/net/phy/mdio_bus.c | 1 - 1 file changed, 1 deletion(-)
drivers/net/phy/mdio_bus.c +0 -1
@@ -1046,7 +1046,6 @@ int __init mdio_bus_init(void)return ret; } -EXPORT_SYMBOL_GPL (mdio_bus_init);#if IS_ENABLED (CONFIG_PHYLIB )void mdio_bus_exit (void )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 207/339 net: xfrm: unexport __init-annotated xfrm4_protocol_init()
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
[ Upstream commit 4a388f08d8784af48f352193d2b72aaf167a57a1 ]
EXPORT_SYMBOL and __init is a bad combination because the .init.text section is freed up after the initialization. Hence, modules cannot use symbols annotated __init. The access to a freed symbol may end up with kernel panic.
modpost used to detect it, but it has been broken for a decade.
Recently, I fixed modpost so it started to warn it again, then this showed up in linux-next builds.
There are two ways to fix it:
- Remove __init
- Remove EXPORT_SYMBOL
I chose the latter for this case because the only in-tree call-site, net/ipv4/xfrm4_policy.c is never compiled as modular. (CONFIG_XFRM is boolean)
--- net/ipv4/xfrm4_protocol.c | 1 - 1 file changed, 1 deletion(-)
net/ipv4/xfrm4_protocol.c +0 -1
@@ -304,4 +304,3 @@ void __init xfrm4_protocol_init(void) {xfrm_input_register_afinfo (&xfrm4_input_afinfo); } -EXPORT_SYMBOL (xfrm4_protocol_init);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 208/339 net: ipv6: unexport __init-annotated seg6_hmac_init()
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
[ Upstream commit 5801f064e35181c71857a80ff18af4dbec3c5f5c ]
EXPORT_SYMBOL and __init is a bad combination because the .init.text section is freed up after the initialization. Hence, modules cannot use symbols annotated __init. The access to a freed symbol may end up with kernel panic.
modpost used to detect it, but it has been broken for a decade.
Recently, I fixed modpost so it started to warn it again, then this showed up in linux-next builds.
There are two ways to fix it:
- Remove __init
- Remove EXPORT_SYMBOL
I chose the latter for this case because the caller (net/ipv6/seg6.c) and the callee (net/ipv6/seg6_hmac.c) belong to the same module. It seems an internal function call in ipv6.ko.
--- net/ipv6/seg6_hmac.c | 1 - 1 file changed, 1 deletion(-)
net/ipv6/seg6_hmac.c +0 -1
@@ -399,7 +399,6 @@ int __init seg6_hmac_init(void) {return seg6_hmac_init_algo (); } -EXPORT_SYMBOL (seg6_hmac_init);int __net_init seg6_hmac_net_init (struct net *net) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 209/339 net/mlx5e: CT: Fix cleanup of CT before cleanup of TC ct rules
In reply to Greg Kroah-HartmanFrom: Paul Blakey <[email protected]>
[ Upstream commit 15ef9efa855cf405fadd78272e1e5d04e09a1cf3 ]
CT cleanup assumes that all tc rules were deleted first, and so is free to delete the CT shared resources (e.g the dr_action fwd_action which is shared for all tuples). But currently for uplink, this is happens in reverse, causing the below trace.
CT cleanup is called from:
mlx5e_cleanup_rep_tx()->mlx5e_cleanup_uplink_rep_tx()-> mlx5e_rep_tc_cleanup()->mlx5e_tc_esw_cleanup()-> mlx5_tc_ct_clean()
Only afterwards, tc cleanup is called from:
mlx5e_cleanup_rep_tx()->mlx5e_tc_ht_cleanup() which would have deleted all the tc ct rules, and so delete all the offloaded tuples.
Fix this reversing the order of init and on cleanup, which will result in tc cleanup then ct cleanup.
[ 9443.593347] WARNING: CPU: 2 PID: 206774 at drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c:1882 mlx5dr_action_destroy+0x188/0x1a0 [mlx5_core] [ 9443.593349] Modules linked in: act_ct nf_flow_table rdma_ucm(O) rdma_cm(O) iw_cm(O) ib_ipoib(O) ib_cm(O) ib_umad(O) mlx5_core(O-) mlxfw(O) mlxdevm(O) auxiliary(O) ib_uverbs(O) psample ib_core(O) mlx_compat(O) ip_gre gre ip_tunnel act_vlan bonding geneve esp6_offload esp6 esp4_offload esp4 act_tunnel_key vxlan ip6_udp_tunnel udp_tunnel act_mirred act_skbedit act_gact cls_flower sch_ingress nfnetlink_cttimeout nfnetlink xfrm_user xfrm_algo 8021q garp stp ipmi_devintf mrp ipmi_msghandler llc openvswitch nsh nf_conncount nf_nat mst_pciconf(O) dm_multipath sbsa_gwdt uio_pdrv_genirq uio mlxbf_pmc mlxbf_pka mlx_trio mlx_bootctl(O) bluefield_edac sch_fq_codel ip_tables ipv6 crc_ccitt btrfs zstd_compress raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor xor_neon raid6_pq raid1 raid0 crct10dif_ce i2c_mlxbf gpio_mlxbf2 mlxbf_gige aes_neon_bs aes_neon_blk [last unloaded: mlx5_ib] [ 9443.593419] CPU: 2 PID: 206774 Comm: modprobe Tainted: G O 5.4.0-1023.24.gc14613d-bluefield #1 [ 9443.593422] Hardware name: https://www.mellanox.com BlueField SoC/BlueField SoC, BIOS BlueField:143ebaf Jan 11 2022 [ 9443.593424] pstate: 20000005 (nzCv daif -PAN -UAO) [ 9443.593489] pc : mlx5dr_action_destroy+0x188/0x1a0 [mlx5_core] [ 9443.593545] lr : mlx5_ct_fs_smfs_destroy+0x24/0x30 [mlx5_core] [ 9443.593546] sp : ffff8000135dbab0 [ 9443.593548] x29: ffff8000135dbab0 x28: ffff0003a6ab8e80 [ 9443.593550] x27: 0000000000000000 x26: ffff0003e07d7000 [ 9443.593552] x25: ffff800009609de0 x24: ffff000397fb2120 [ 9443.593554] x23: ffff0003975c0000 x22: 0000000000000000 [ 9443.593556] x21: ffff0003975f08c0 x20: ffff800009609de0 [ 9443.593558] x19: ffff0003c8a13380 x18: 0000000000000014 [ 9443.593560] x17: 0000000067f5f125 x16: 000000006529c620 [ 9443.593561] x15: 000000000000000b x14: 0000000000000000 [ 9443.593563] x13: 0000000000000002 x12: 0000000000000001 [ 9443.593565] x11: ffff800011108868 x10: 0000000000000000 [ 9443.593567] x9 : 0000000000000000 x8 : ffff8000117fb270 [ 9443.593569] x7 : ffff0003ebc01288 x6 : 0000000000000000 [ 9443.593571] x5 : ffff800009591ab8 x4 : fffffe000f6d9a20 [ 9443.593572] x3 : 0000000080040001 x2 : fffffe000f6d9a20 [ 9443.593574] x1 : ffff8000095901d8 x0 : 0000000000000025 [ 9443.593577] Call trace: [ 9443.593634] mlx5dr_action_destroy+0x188/0x1a0 [mlx5_core] [ 9443.593688] mlx5_ct_fs_smfs_destroy+0x24/0x30 [mlx5_core] [ 9443.593743] mlx5_tc_ct_clean+0x34/0xa8 [mlx5_core] [ 9443.593797] mlx5e_tc_esw_cleanup+0x58/0x88 [mlx5_core] [ 9443.593851] mlx5e_rep_tc_cleanup+0x24/0x30 [mlx5_core] [ 9443.593905] mlx5e_cleanup_rep_tx+0x6c/0x78 [mlx5_core] [ 9443.593959] mlx5e_detach_netdev+0x74/0x98 [mlx5_core] [ 9443.594013] mlx5e_netdev_change_profile+0x70/0x180 [mlx5_core] [ 9443.594067] mlx5e_netdev_attach_nic_profile+0x34/0x40 [mlx5_core] [ 9443.594122] mlx5e_vport_rep_unload+0x15c/0x1a8 [mlx5_core] [ 9443.594177] mlx5_eswitch_unregister_vport_reps+0x228/0x298 [mlx5_core] [ 9443.594231] mlx5e_rep_remove+0x2c/0x38 [mlx5_core] [ 9443.594236] auxiliary_bus_remove+0x30/0x50 [auxiliary] [ 9443.594246] device_release_driver_internal+0x108/0x1d0 [ 9443.594248] driver_detach+0x5c/0xe8 [ 9443.594250] bus_remove_driver+0x64/0xd8 [ 9443.594253] driver_unregister+0x38/0x60 [ 9443.594255] auxiliary_driver_unregister+0x24/0x38 [auxiliary] [ 9443.594311] mlx5e_rep_cleanup+0x20/0x38 [mlx5_core] [ 9443.594365] mlx5e_cleanup+0x18/0x30 [mlx5_core] [ 9443.594419] cleanup+0xc/0x20cc [mlx5_core] [ 9443.594424] __arm64_sys_delete_module+0x154/0x2b0 [ 9443.594429] el0_svc_common.constprop.0+0xf4/0x200 [ 9443.594432] el0_svc_handler+0x38/0xa8 [ 9443.594435] el0_svc+0x10/0x26c
--- .../net/ethernet/mellanox/mlx5/core/en_rep.c | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +16 -15
@@ -937,6 +937,13 @@ static int mlx5e_init_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)return err; } +static void mlx5e_cleanup_uplink_rep_tx (struct mlx5e_rep_priv *rpriv) +{ +mlx5e_rep_tc_netdevice_event_unregister (rpriv); +mlx5e_rep_bond_cleanup (rpriv); +mlx5e_rep_tc_cleanup (rpriv); +} +static int mlx5e_init_rep_tx (struct mlx5e_priv *priv) {struct mlx5e_rep_priv *rpriv = priv->ppriv;
@@ -948,42 +955,36 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)return err; } - err =mlx5e_tc_ht_init (&rpriv->tc_ht); -if (err) - goto err_ht_init; -if (rpriv->rep->vport ==MLX5_VPORT_UPLINK ) { err =mlx5e_init_uplink_rep_tx (rpriv);if (err) goto err_init_tx; } + err =mlx5e_tc_ht_init (&rpriv->tc_ht); +if (err) + goto err_ht_init; +return 0 ; -err_init_tx: -mlx5e_tc_ht_cleanup (&rpriv->tc_ht); err_ht_init: +if (rpriv->rep->vport ==MLX5_VPORT_UPLINK ) +mlx5e_cleanup_uplink_rep_tx (rpriv); +err_init_tx:mlx5e_destroy_tises (priv);return err; } -static void mlx5e_cleanup_uplink_rep_tx (struct mlx5e_rep_priv *rpriv) -{ -mlx5e_rep_tc_netdevice_event_unregister (rpriv); -mlx5e_rep_bond_cleanup (rpriv); -mlx5e_rep_tc_cleanup (rpriv); -} -static void mlx5e_cleanup_rep_tx (struct mlx5e_priv *priv) {struct mlx5e_rep_priv *rpriv = priv->ppriv; -mlx5e_destroy_tises (priv); +mlx5e_tc_ht_cleanup (&rpriv->tc_ht);if (rpriv->rep->vport ==MLX5_VPORT_UPLINK )mlx5e_cleanup_uplink_rep_tx (rpriv); -mlx5e_tc_ht_cleanup (&rpriv->tc_ht); +mlx5e_destroy_tises (priv); }static void mlx5e_rep_enable (struct mlx5e_priv *priv)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 210/339 net/mlx5: Lag, filter non compatible devices
In reply to Greg Kroah-HartmanFrom: Mark Bloch <[email protected]>
[ Upstream commit bc4c2f2e017949646b43fdcad005a03462d437c6 ]
When search for a peer lag device we can filter based on that device's capabilities.
Downstream patch will be less strict when filtering compatible devices and remove the limitation where we require exact MLX5_MAX_PORTS and change it to a range.
--- drivers/net/ethernet/mellanox/mlx5/core/dev.c | 48 +++++++++++++++---- .../net/ethernet/mellanox/mlx5/core/lag/lag.c | 12 ++--- .../ethernet/mellanox/mlx5/core/mlx5_core.h | 1 + 3 files changed, 47 insertions(+), 14 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/dev.c +40 -8
@@ -555,12 +555,9 @@ static u32 mlx5_gen_pci_id(const struct mlx5_core_dev *dev) PCI_SLOT(dev->pdev->devfn)); } -static int next_phys_dev (struct device *dev,const void *data) +static int _next_phys_dev (struct mlx5_core_dev *mdev, +const struct mlx5_core_dev *curr) { - struct mlx5_adev *madev = container_of(dev, struct mlx5_adev, adev.dev); -struct mlx5_core_dev *mdev = madev->mdev; -const struct mlx5_core_dev *curr = data; -if (!mlx5_core_is_pf (mdev))return 0 ;
@@ -574,8 +571,29 @@ static int next_phys_dev(struct device *dev, const void *data)return 1 ; } -/* Must be called with intf_mutex held */ -struct mlx5_core_dev *mlx5_get_next_phys_dev (struct mlx5_core_dev *dev) +static int next_phys_dev (struct device *dev,const void *data) +{ + struct mlx5_adev *madev = container_of(dev, struct mlx5_adev, adev.dev); +struct mlx5_core_dev *mdev = madev->mdev; + +return _next_phys_dev (mdev, data); +} + +static int next_phys_dev_lag (struct device *dev,const void *data) +{ + struct mlx5_adev *madev = container_of(dev, struct mlx5_adev, adev.dev); +struct mlx5_core_dev *mdev = madev->mdev; + +if (!MLX5_CAP_GEN (mdev, vport_group_manager) || + !MLX5_CAP_GEN (mdev, lag_master) || +MLX5_CAP_GEN (mdev, num_lag_ports) !=MLX5_MAX_PORTS ) +return 0 ; + +return _next_phys_dev (mdev, data); +} + +static struct mlx5_core_dev *mlx5_get_next_dev (struct mlx5_core_dev *dev, +int (*match)(struct device *dev,const void *data)) {struct auxiliary_device *adev;struct mlx5_adev *madev;
@@ -583,7 +601,7 @@ struct mlx5_core_dev *mlx5_get_next_phys_dev(struct mlx5_core_dev *dev)if (!mlx5_core_is_pf (dev))return NULL ; - adev =auxiliary_find_device (NULL , dev, &next_phys_dev); + adev =auxiliary_find_device (NULL , dev, match);if (!adev)return NULL ;
@@ -592,6 +610,20 @@ struct mlx5_core_dev *mlx5_get_next_phys_dev(struct mlx5_core_dev *dev)return madev->mdev; } +/* Must be called with intf_mutex held */ +struct mlx5_core_dev *mlx5_get_next_phys_dev (struct mlx5_core_dev *dev) +{ +lockdep_assert_held (&mlx5_intf_mutex); +return mlx5_get_next_dev (dev, &next_phys_dev); +} + +/* Must be called with intf_mutex held */ +struct mlx5_core_dev *mlx5_get_next_phys_dev_lag (struct mlx5_core_dev *dev) +{ +lockdep_assert_held (&mlx5_intf_mutex); +return mlx5_get_next_dev (dev, &next_phys_dev_lag); +} +void mlx5_dev_list_lock (void ) {mutex_lock (&mlx5_intf_mutex);
drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c +6 -6
@@ -924,12 +924,7 @@ static int __mlx5_lag_dev_add_mdev(struct mlx5_core_dev *dev)struct mlx5_lag *ldev =NULL ;struct mlx5_core_dev *tmp_dev; -if (!MLX5_CAP_GEN (dev, vport_group_manager) || - !MLX5_CAP_GEN (dev, lag_master) || -MLX5_CAP_GEN (dev, num_lag_ports) !=MLX5_MAX_PORTS ) -return 0 ; - - tmp_dev =mlx5_get_next_phys_dev (dev); + tmp_dev =mlx5_get_next_phys_dev_lag (dev);if (tmp_dev) ldev = tmp_dev->priv.lag;
@@ -974,6 +969,11 @@ void mlx5_lag_add_mdev(struct mlx5_core_dev *dev) {int err; +if (!MLX5_CAP_GEN (dev, vport_group_manager) || + !MLX5_CAP_GEN (dev, lag_master) || +MLX5_CAP_GEN (dev, num_lag_ports) !=MLX5_MAX_PORTS ) +return ; + recheck:mlx5_dev_list_lock (); err =__mlx5_lag_dev_add_mdev (dev);
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h +1 -0
@@ -210,6 +210,7 @@ void mlx5_detach_device(struct mlx5_core_dev *dev);int mlx5_register_device (struct mlx5_core_dev *dev);void mlx5_unregister_device (struct mlx5_core_dev *dev);struct mlx5_core_dev *mlx5_get_next_phys_dev (struct mlx5_core_dev *dev); +struct mlx5_core_dev *mlx5_get_next_phys_dev_lag (struct mlx5_core_dev *dev);void mlx5_dev_list_lock (void );void mlx5_dev_list_unlock (void );int mlx5_dev_list_trylock (void );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 211/339 net/mlx5: Fix mlx5_get_next_dev() peer device matching
In reply to Greg Kroah-HartmanFrom: Saeed Mahameed <[email protected]>
[ Upstream commit 1c5de097bea31760c3f0467ac0c84ba0dc3525d5 ]
In some use-cases, mlx5 instances will need to search for their peer device (the other port on the same HCA). For that, mlx5 device matching mechanism relied on auxiliary_find_device() to search, and used a bad matching callback function.
This approach has two issues:
1) next_phys_dev() the matching function, assumed all devices are of the type mlx5_adev (mlx5 auxiliary device) which is wrong and could lead to crashes, this worked for a while, since only lately other drivers started registering auxiliary devices.
2) using the auxiliary class bus (auxiliary_find_device) to search for mlx5_core_dev devices, who are actually PCIe device instances, is wrong. This works since mlx5_core always has at least one mlx5_adev instance hanging around in the aux bus.
As suggested by others we can fix 1. by comparing device names prefixes if they have the string "mlx5_core" in them, which is not a best practice ! but even with that fixed, still 2. needs fixing, we are trying to match pcie device peers so we should look in the right bus (pci bus), hence this fix.
The fix:
1) search the pci bus for mlx5 peer devices, instead of the aux bus
2) to validated devices are the same type "mlx5_core_dev" compare if they have the same driver, which is bulletproof.
This wouldn't have worked with the aux bus since the various mlx5 aux device types don't share the same driver, even if they share the same device wrapper struct (mlx5_adev) "which helped to find the parent device"
--- drivers/net/ethernet/mellanox/mlx5/core/dev.c | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/dev.c +23 -11
@@ -571,18 +571,32 @@ static int _next_phys_dev(struct mlx5_core_dev *mdev,return 1 ; } +static void *pci_get_other_drvdata (struct device *this,struct device *other) +{ +if (this->driver != other->driver) +return NULL ; + +return pci_get_drvdata (to_pci_dev (other)); +} +static int next_phys_dev (struct device *dev,const void *data) { - struct mlx5_adev *madev = container_of(dev, struct mlx5_adev, adev.dev); -struct mlx5_core_dev *mdev = madev->mdev; +struct mlx5_core_dev *mdev, *this = (struct mlx5_core_dev *)data; + + mdev =pci_get_other_drvdata (this->device, dev); +if (!mdev) +return 0 ;return _next_phys_dev (mdev, data); }static int next_phys_dev_lag (struct device *dev,const void *data) { - struct mlx5_adev *madev = container_of(dev, struct mlx5_adev, adev.dev); -struct mlx5_core_dev *mdev = madev->mdev; +struct mlx5_core_dev *mdev, *this = (struct mlx5_core_dev *)data; + + mdev =pci_get_other_drvdata (this->device, dev); +if (!mdev) +return 0 ; if (!MLX5_CAP_GEN(mdev, vport_group_manager) || !MLX5_CAP_GEN(mdev, lag_master) ||
@@ -595,19 +609,17 @@ static int next_phys_dev_lag(struct device *dev, const void *data)static struct mlx5_core_dev *mlx5_get_next_dev (struct mlx5_core_dev *dev,int (*match)(struct device *dev,const void *data)) { -struct auxiliary_device *adev; -struct mlx5_adev *madev; +struct device *next;if (!mlx5_core_is_pf (dev))return NULL ; - adev =auxiliary_find_device (NULL , dev, match); -if (!adev) + next =bus_find_device (&pci_bus_type,NULL , dev, match); +if (!next)return NULL ; - madev = container_of(adev, struct mlx5_adev, adev); -put_device (&adev->dev); -return madev->mdev; +put_device (next); +return pci_get_drvdata (to_pci_dev (next)); }/* Must be called with intf_mutex held */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 212/339 net/mlx5: Rearm the FW tracer after each tracer event
In reply to Greg Kroah-HartmanFrom: Feras Daoud <[email protected]>
[ Upstream commit 8bf94e6414c9481bfa28269022688ab445d0081d ]
The current design does not arm the tracer if traces are available before the tracer string database is fully loaded, leading to an unfunctional tracer. This fix will rearm the tracer every time the FW triggers tracer event regardless of the tracer strings database status.
--- drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +5 -2
@@ -675,6 +675,9 @@ static void mlx5_fw_tracer_handle_traces(struct work_struct *work)if (!tracer->owner)return ; +if (unlikely (!tracer->str_db.loaded)) + goto arm; + block_count = tracer->buff.size /TRACER_BLOCK_SIZE_BYTE ; start_offset = tracer->buff.consumer_index *TRACER_BLOCK_SIZE_BYTE ;
@@ -732,6 +735,7 @@ static void mlx5_fw_tracer_handle_traces(struct work_struct *work) &tmp_trace_block[TRACES_PER_BLOCK - 1]); } +arm:mlx5_fw_tracer_arm (dev); }
@@ -1136,8 +1140,7 @@ static int fw_tracer_event(struct notifier_block *nb, unsigned long action, voidqueue_work (tracer->work_queue, &tracer->ownership_change_work);break ;case MLX5_TRACER_SUBTYPE_TRACES_AVAILABLE : -if (likely (tracer->str_db.loaded)) -queue_work (tracer->work_queue, &tracer->handle_traces_work); +queue_work (tracer->work_queue, &tracer->handle_traces_work);break ;default : mlx5_core_dbg(dev, "FWTracer: Event with unrecognized subtype: sub_type %d\n",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 213/339 net/mlx5: fs, fail conflicting actions
In reply to Greg Kroah-HartmanFrom: Mark Bloch <[email protected]>
[ Upstream commit 8fa5e7b20e01042b14f8cd684d2da9b638460c74 ]
When combining two steering rules into one check not only do they share the same actions but those actions are also the same. This resolves an issue where when creating two different rules with the same match the actions are overwritten and one of the rules is deleted a FW syndrome can be seen in dmesg.
mlx5_core 0000:03:00.0: mlx5_cmd_check:819:(pid 2105): DEALLOC_MODIFY_HEADER_CONTEXT(0x941) op_mod(0x0) failed, status bad resource state(0x9), syndrome (0x1ab444)
--- .../net/ethernet/mellanox/mlx5/core/fs_core.c | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +32 -3
@@ -1560,9 +1560,22 @@ static struct mlx5_flow_rule *find_flow_rule(struct fs_fte *fte,return NULL ; } -static bool check_conflicting_actions (u32 action1,u32 action2) +static bool check_conflicting_actions_vlan (const struct mlx5_fs_vlan *vlan0, +const struct mlx5_fs_vlan *vlan1) { -u32 xored_actions = action1 ^ action2; +return vlan0->ethtype != vlan1->ethtype || + vlan0->vid != vlan1->vid || + vlan0->prio != vlan1->prio; +} + +static bool check_conflicting_actions (const struct mlx5_flow_act *act1, +const struct mlx5_flow_act *act2) +{ +u32 action1 = act1->action; +u32 action2 = act2->action; +u32 xored_actions; + + xored_actions = action1 ^ action2;/* if one rule only wants to count, it's ok */ if (action1 == MLX5_FLOW_CONTEXT_ACTION_COUNT ||
@@ -1579,6 +1592,22 @@ static bool check_conflicting_actions(u32 action1, u32 action2) MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2))return true; +if (action1 &MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT && + act1->pkt_reformat != act2->pkt_reformat) +return true; + +if (action1 &MLX5_FLOW_CONTEXT_ACTION_MOD_HDR && + act1->modify_hdr != act2->modify_hdr) +return true; + +if (action1 &MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH && +check_conflicting_actions_vlan (&act1->vlan[0 ], &act2->vlan[0 ])) +return true; + +if (action1 &MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2 && +check_conflicting_actions_vlan (&act1->vlan[1 ], &act2->vlan[1 ])) +return true; +return false; }
@@ -1586,7 +1615,7 @@ static int check_conflicting_ftes(struct fs_fte *fte, const struct mlx5_flow_context *flow_context, const struct mlx5_flow_act *flow_act) { - if (check_conflicting_actions(flow_act->action, fte->action.action)) { + if (check_conflicting_actions(flow_act, &fte->action)) { mlx5_core_warn(get_dev(&fte->node), "Found two FTEs with conflicting actions\n");return -EEXIST ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 214/339 ip_gre: test csum_start instead of transport header
In reply to Greg Kroah-HartmanFrom: Willem de Bruijn <[email protected]>
[ Upstream commit 8d21e9963bec1aad2280cdd034c8993033ef2948 ]
GRE with TUNNEL_CSUM will apply local checksum offload on CHECKSUM_PARTIAL packets.
ipgre_xmit must validate csum_start after an optional skb_pull, else lco_csum may trigger an overflow. The original check was
if (csum && skb_checksum_start(skb) < skb->data) return -EINVAL;
This had false positives when skb_checksum_start is undefined:
when ip_summed is not CHECKSUM_PARTIAL. A discussed refinement was straightforward
if (csum && skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_start(skb) < skb->data) return -EINVAL;
But was eventually revised more thoroughly:
- restrict the check to the only branch where needed, in an uncommon GRE path that uses header_ops and calls skb_pull.
- test skb_transport_header, which is set along with csum_start in skb_partial_csum_set in the normal header_ops datapath.
Turns out skbs can arrive in this branch without the transport header set, e.g., through BPF redirection.
Revise the check back to check csum_start directly, and only if CHECKSUM_PARTIAL. Do leave the check in the updated location. Check field regardless of whether TUNNEL_CSUM is configured.
--- net/ipv4/ip_gre.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
net/ipv4/ip_gre.c +5 -6
@@ -629,21 +629,20 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, }if (dev->header_ops) { -const int pull_len = tunnel->hlen +sizeof (struct iphdr ); -if (skb_cow_head (skb,0 )) goto free_skb; tnl_params = (const struct iphdr *)skb->data; -if (pull_len >skb_transport_offset (skb)) - goto free_skb; -/* Pull skb since ip_tunnel_xmit() needs skb->data pointing * to gre header. */ -skb_pull (skb, pull_len); +skb_pull (skb, tunnel->hlen +sizeof (struct iphdr ));skb_reset_mac_header (skb); + +if (skb->ip_summed ==CHECKSUM_PARTIAL && +skb_checksum_start (skb) < skb->data) + goto free_skb; }else {if (skb_cow_head (skb, dev->needed_headroom)) goto free_skb;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 215/339 net: altera: Fix refcount leak in altera_tse_mdio_create
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 11ec18b1d8d92b9df307d31950dcba0b3dd7283c ]
Every iteration of for_each_child_of_node() decrements the reference count of the previous node.
When break from a for_each_child_of_node() loop,
we need to explicitly call of_node_put() on the child node when not need anymore.
Add missing of_node_put() to avoid refcount leak.
--- drivers/net/ethernet/altera/altera_tse_main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/net/ethernet/altera/altera_tse_main.c +5 -1
@@ -163,7 +163,8 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id) mdio =mdiobus_alloc ();if (mdio ==NULL ) {netdev_err (dev,"Error allocating MDIO bus\n" ); -return -ENOMEM ; + ret = -ENOMEM ; + goto put_node; } mdio->name =ALTERA_TSE_RESOURCE_NAME ;
@@ -180,6 +181,7 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id) mdio->id); goto out_free_mdio; } +of_node_put (mdio_node);if (netif_msg_drv (priv))netdev_info (dev,"MDIO bus %s: created\n" , mdio->id);
@@ -189,6 +191,8 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id) out_free_mdio:mdiobus_free (mdio); mdio =NULL ; +put_node: +of_node_put (mdio_node);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 216/339 net: dsa: mv88e6xxx: use BMSR_ANEGCOMPLETE bit for filling an_complete
In reply to Greg Kroah-HartmanFrom: Marek Behún <[email protected]>
[ Upstream commit 47e96930d6e6106d5252e85b868d3c7e29296de0 ]
Commit ede359d8843a ("net: dsa: mv88e6xxx: Link in pcs_get_state() if AN is bypassed") added the ability to link if AN was bypassed, and added filling of state->an_complete field, but set it to true if AN was enabled in BMCR, not when AN was reported complete in BMSR.
This was done because for some reason, when I wanted to use BMSR value to infer an_complete, I was looking at BMSR_ANEGCAPABLE bit (which was always 1), instead of BMSR_ANEGCOMPLETE bit.
Use BMSR_ANEGCOMPLETE for filling state->an_complete.
--- drivers/net/dsa/mv88e6xxx/serdes.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-)
drivers/net/dsa/mv88e6xxx/serdes.c +11 -16
@@ -50,22 +50,17 @@ static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip, }static int mv88e6xxx_serdes_pcs_get_state (struct mv88e6xxx_chip *chip, -u16 ctrl,u16 status,u16 lpa, +u16 bmsr,u16 lpa,u16 status,struct phylink_link_state *state) { state->link = !!(status &MV88E6390_SGMII_PHY_STATUS_LINK ); + state->an_complete = !!(bmsr &BMSR_ANEGCOMPLETE );if (status &MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID ) {/* The Spped and Duplex Resolved register is 1 if AN is enabled * and complete, or if AN is disabled. So with disabled AN we -* still get here on link up. But we want to set an_complete -* only if AN was enabled, thus we look at BMCR_ANENABLE. -* (According to 802.3-2008 section 22.2.4.2.10, we should be -* able to get this same value from BMSR_ANEGCAPABLE, but tests -* show that these Marvell PHYs don't conform to this part of -* the specificaion - BMSR_ANEGCAPABLE is simply always 1.) +* still get here on link up. */ - state->an_complete = !!(ctrl &BMCR_ANENABLE ); state->duplex = status &MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ?DUPLEX_FULL :DUPLEX_HALF ;
@@ -191,12 +186,12 @@ int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,int mv88e6352_serdes_pcs_get_state (struct mv88e6xxx_chip *chip,int port,int lane,struct phylink_link_state *state) { -u16 lpa, status, ctrl; +u16 bmsr, lpa, status;int err; - err =mv88e6352_serdes_read (chip,MII_BMCR , &ctrl); + err =mv88e6352_serdes_read (chip,MII_BMSR , &bmsr);if (err) { -dev_err (chip->dev,"can't read Serdes PHY control: %d\n" , err); +dev_err (chip->dev,"can't read Serdes BMSR: %d\n" , err);return err; }
@@ -212,7 +207,7 @@ int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,return err; } -return mv88e6xxx_serdes_pcs_get_state (chip, ctrl, status, lpa, state); +return mv88e6xxx_serdes_pcs_get_state (chip, bmsr, lpa, status, state); } int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
@@ -918,13 +913,13 @@ int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,static int mv88e6390_serdes_pcs_get_state_sgmii (struct mv88e6xxx_chip *chip,int port,int lane,struct phylink_link_state *state) { -u16 lpa, status, ctrl; +u16 bmsr, lpa, status;int err; err =mv88e6390_serdes_read (chip, lane,MDIO_MMD_PHYXS , -MV88E6390_SGMII_BMCR , &ctrl); +MV88E6390_SGMII_BMSR , &bmsr);if (err) { -dev_err (chip->dev,"can't read Serdes PHY control: %d\n" , err); +dev_err (chip->dev,"can't read Serdes PHY BMSR: %d\n" , err);return err; }
@@ -942,7 +937,7 @@ static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,return err; } -return mv88e6xxx_serdes_pcs_get_state (chip, ctrl, status, lpa, state); +return mv88e6xxx_serdes_pcs_get_state (chip, bmsr, lpa, status, state); } static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 217/339 net: dsa: realtek: rtl8365mb: fix GMII caps for ports with internal PHY
In reply to Greg Kroah-HartmanFrom: Alvin Šipraga <[email protected]>
[ Upstream commit 487994ff75880569d32504d7e70da8b3328e0693 ]
Since commit a18e6521a7d9 ("net: phylink: handle NA interface mode in phylink_fwnode_phy_connect()"), phylib defaults to GMII when no phy-mode or phy-connection-type property is specified in a DSA port node of the device tree. The same commit caused a regression in rtl8365mb whereby phylink would fail to connect, because the driver did not advertise support for GMII for ports with internal PHY.
It should be noted that the aforementioned regression is not because the blamed commit was incorrect: on the contrary, the blamed commit is correcting the previous behaviour whereby unspecified phy-mode would cause the internal interface mode to be PHY_INTERFACE_MODE_NA. The rtl8365mb driver only worked by accident before because it _did_ advertise support for PHY_INTERFACE_MODE_NA, despite NA being reserved for internal use by phylink. With one mistake fixed, the other was exposed.
Commit a5dba0f207e5 ("net: dsa: rtl8365mb: add GMII as user port mode") then introduced implicit support for GMII mode on ports with internal PHY to allow a PHY connection for device trees where the phy-mode is not explicitly set to "internal". At this point everything was working OK again.
Subsequently, commit 6ff6064605e9 ("net: dsa: realtek: convert to phylink_generic_validate()") broke this behaviour again by discarding the usage of rtl8365mb_phy_mode_supported() - where this GMII support was indicated - while switching to the new .phylink_get_caps API.
With the new API, rtl8365mb_phy_mode_supported() is no longer needed. Remove it altogether and add back the GMII capability - this time to rtl8365mb_phylink_get_caps() - so that the above default behaviour works for ports with internal PHY again.
--- drivers/net/dsa/realtek/rtl8365mb.c | 38 +++++++---------------------- 1 file changed, 9 insertions(+), 29 deletions(-)
drivers/net/dsa/realtek/rtl8365mb.c +9 -29
@@ -955,35 +955,21 @@ static int rtl8365mb_ext_config_forcemode(struct realtek_priv *priv, int port,return 0 ; } -static bool rtl8365mb_phy_mode_supported (struct dsa_switch *ds,int port, -phy_interface_t interface) -{ -int ext_int; - - ext_int = rtl8365mb_extint_port_map[port]; - -if (ext_int <0 && - (interface ==PHY_INTERFACE_MODE_NA || - interface ==PHY_INTERFACE_MODE_INTERNAL || - interface ==PHY_INTERFACE_MODE_GMII )) -/* Internal PHY */ -return true; -else if ((ext_int >=1 ) && -phy_interface_mode_is_rgmii (interface)) -/* Extension MAC */ -return true; - -return false; -} -static void rtl8365mb_phylink_get_caps (struct dsa_switch *ds,int port,struct phylink_config *config) { -if (dsa_is_user_port (ds, port)) +if (dsa_is_user_port (ds, port)) {__set_bit (PHY_INTERFACE_MODE_INTERNAL , config->supported_interfaces); -else if (dsa_is_cpu_port (ds, port)) + +/* GMII is the default interface mode for phylib, so +* we have to support it for ports with integrated PHY. +*/ +__set_bit (PHY_INTERFACE_MODE_GMII , + config->supported_interfaces); + }else if (dsa_is_cpu_port (ds, port)) {phy_interface_set_rgmii (config->supported_interfaces); + } config->mac_capabilities =MAC_SYM_PAUSE |MAC_ASYM_PAUSE |MAC_10 |MAC_100 |MAC_1000FD ;
@@ -996,12 +982,6 @@ static void rtl8365mb_phylink_mac_config(struct dsa_switch *ds, int port,struct realtek_priv *priv = ds->priv;int ret; -if (!rtl8365mb_phy_mode_supported (ds, port, state->interface)) { -dev_err (priv->dev,"phy mode %s is unsupported on port %d\n" , -phy_modes (state->interface), port); -return ; - } -if (mode !=MLO_AN_PHY && mode !=MLO_AN_FIXED ) { dev_err(priv->dev, "port %d supports only conventional PHY or fixed-link\n",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 218/339 tcp: use alloc_large_system_hash() to allocate table_perturb
In reply to Greg Kroah-HartmanFrom: Muchun Song <[email protected]>
[ Upstream commit e67b72b90b7e19a4be4d9c29f3feea6f58ab43f8 ]
In our server, there may be no high order (>= 6) memory since we reserve lots of HugeTLB pages when booting. Then the system panic. So use alloc_large_system_hash() to allocate table_perturb.
--- net/ipv4/inet_hashtables.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
net/ipv4/inet_hashtables.c +6 -4
@@ -917,10 +917,12 @@ void __init inet_hashinfo2_init(struct inet_hashinfo *h, const char *name,init_hashinfo_lhash2 (h);/* this one is used for source ports of outgoing connections */ - table_perturb =kmalloc_array (INET_TABLE_PERTURB_SIZE , -sizeof (*table_perturb),GFP_KERNEL ); -if (!table_perturb) -panic ("TCP: failed to alloc table_perturb" ); + table_perturb =alloc_large_system_hash ("Table-perturb" , +sizeof (*table_perturb), +INET_TABLE_PERTURB_SIZE , +0 ,0 ,NULL ,NULL , +INET_TABLE_PERTURB_SIZE , +INET_TABLE_PERTURB_SIZE ); }int inet_hashinfo2_init_mod (struct inet_hashinfo *h)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 219/339 drm: imx: fix compiler warning with gcc-12
In reply to Greg Kroah-HartmanFrom: Linus Torvalds <[email protected]>
[ Upstream commit 7aefd8b53815274f3ef398d370a3c9b27dd9f00c ]
Gcc-12 correctly warned about this code using a non-NULL pointer as a truth value:
drivers/gpu/drm/imx/ipuv3-crtc.c: In function ‘ipu_crtc_disable_planes’:
drivers/gpu/drm/imx/ipuv3-crtc.c:72:21: error: the comparison will always evaluate as ‘true’ for the address of ‘plane’ will never be NULL [-Werror=address]
72 | if (&ipu_crtc->plane[1] && plane == &ipu_crtc->plane[1]->base)
| ^due to the extraneous '&' address-of operator.
Philipp Zabel points out that The mistake had no adverse effect since the following condition doesn't actually dereference the NULL pointer, but the intent of the code was obviously to check for it, not to take the address of the member.
--- drivers/gpu/drm/imx/ipuv3-crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/imx/ipuv3-crtc.c +1 -1
@@ -69,7 +69,7 @@ static void ipu_crtc_disable_planes(struct ipu_crtc *ipu_crtc,drm_atomic_crtc_state_for_each_plane (plane, old_crtc_state) {if (plane == &ipu_crtc->plane[0 ]->base) disable_full = true; -if (&ipu_crtc->plane[1 ] && plane == &ipu_crtc->plane[1 ]->base) +if (ipu_crtc->plane[1 ] && plane == &ipu_crtc->plane[1 ]->base) disable_partial = true; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 220/339 nfp: flower: restructure flow-key for gre+vlan combination
In reply to Greg Kroah-HartmanFrom: Etienne van der Linde <[email protected]>
[ Upstream commit a0b843340dae704e17c1ddfad0f85c583c36757f ]
Swap around the GRE and VLAN parts in the flow-key offloaded by the driver to fit in with other tunnel types and the firmware. Without this change used cases with GRE+VLAN on the outer header does not get offloaded as the flow-key mismatches what the firmware expect.
--- .../ethernet/netronome/nfp/flower/conntrack.c | 32 +++++++++---------- .../net/ethernet/netronome/nfp/flower/match.c | 16 +++++----- 2 files changed, 24 insertions(+), 24 deletions(-)
drivers/net/ethernet/netronome/nfp/flower/conntrack.c +16 -16
@@ -442,6 +442,11 @@ nfp_fl_calc_key_layers_sz(struct nfp_fl_key_ls in_key_ls, uint16_t *map) key_size +=sizeof (struct nfp_flower_ipv6 ); } +if (in_key_ls.key_layer_two &NFP_FLOWER_LAYER2_QINQ ) { + map[FLOW_PAY_QINQ ] = key_size; + key_size +=sizeof (struct nfp_flower_vlan ); + } +if (in_key_ls.key_layer_two &NFP_FLOWER_LAYER2_GRE ) { map[FLOW_PAY_GRE ] = key_size;if (in_key_ls.key_layer_two &NFP_FLOWER_LAYER2_TUN_IPV6 )
@@ -450,11 +455,6 @@ nfp_fl_calc_key_layers_sz(struct nfp_fl_key_ls in_key_ls, uint16_t *map) key_size +=sizeof (struct nfp_flower_ipv4_gre_tun ); } -if (in_key_ls.key_layer_two &NFP_FLOWER_LAYER2_QINQ ) { - map[FLOW_PAY_QINQ ] = key_size; - key_size +=sizeof (struct nfp_flower_vlan ); - } -if ((in_key_ls.key_layer &NFP_FLOWER_LAYER_VXLAN ) || (in_key_ls.key_layer_two &NFP_FLOWER_LAYER2_GENEVE )) { map[FLOW_PAY_UDP_TUN ] = key_size;
@@ -693,6 +693,17 @@ static int nfp_fl_ct_add_offload(struct nfp_fl_nft_tc_merge *m_entry) } } +if (NFP_FLOWER_LAYER2_QINQ & key_layer.key_layer_two) { + offset = key_map[FLOW_PAY_QINQ ]; + key = kdata + offset; + msk = mdata + offset; +for (i =0 ; i < _CT_TYPE_MAX; i++) { +nfp_flower_compile_vlan ((struct nfp_flower_vlan *)key, + (struct nfp_flower_vlan *)msk, + rules[i]); + } + } +if (key_layer.key_layer_two &NFP_FLOWER_LAYER2_GRE ) { offset = key_map[FLOW_PAY_GRE ]; key = kdata + offset;
@@ -733,17 +744,6 @@ static int nfp_fl_ct_add_offload(struct nfp_fl_nft_tc_merge *m_entry) } } -if (NFP_FLOWER_LAYER2_QINQ & key_layer.key_layer_two) { - offset = key_map[FLOW_PAY_QINQ ]; - key = kdata + offset; - msk = mdata + offset; -for (i =0 ; i < _CT_TYPE_MAX; i++) { -nfp_flower_compile_vlan ((struct nfp_flower_vlan *)key, - (struct nfp_flower_vlan *)msk, - rules[i]); - } - } -if (key_layer.key_layer &NFP_FLOWER_LAYER_VXLAN || key_layer.key_layer_two &NFP_FLOWER_LAYER2_GENEVE ) { offset = key_map[FLOW_PAY_UDP_TUN ];
drivers/net/ethernet/netronome/nfp/flower/match.c +8 -8
@@ -602,6 +602,14 @@ int nfp_flower_compile_flow_match(struct nfp_app *app, msk +=sizeof (struct nfp_flower_ipv6 ); } +if (NFP_FLOWER_LAYER2_QINQ & key_ls->key_layer_two) { +nfp_flower_compile_vlan ((struct nfp_flower_vlan *)ext, + (struct nfp_flower_vlan *)msk, + rule); + ext +=sizeof (struct nfp_flower_vlan ); + msk +=sizeof (struct nfp_flower_vlan ); + } +if (key_ls->key_layer_two &NFP_FLOWER_LAYER2_GRE ) {if (key_ls->key_layer_two &NFP_FLOWER_LAYER2_TUN_IPV6 ) {struct nfp_flower_ipv6_gre_tun *gre_match;
@@ -637,14 +645,6 @@ int nfp_flower_compile_flow_match(struct nfp_app *app, } } -if (NFP_FLOWER_LAYER2_QINQ & key_ls->key_layer_two) { -nfp_flower_compile_vlan ((struct nfp_flower_vlan *)ext, - (struct nfp_flower_vlan *)msk, - rule); - ext +=sizeof (struct nfp_flower_vlan ); - msk +=sizeof (struct nfp_flower_vlan ); - } -if (key_ls->key_layer &NFP_FLOWER_LAYER_VXLAN || key_ls->key_layer_two &NFP_FLOWER_LAYER2_GENEVE ) {if (key_ls->key_layer_two &NFP_FLOWER_LAYER2_TUN_IPV6 ) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 221/339 net: seg6: fix seg6_lookup_any_nexthop() to handle VRFs using flowi_l3mdev
In reply to Greg Kroah-HartmanFrom: Andrea Mayer <[email protected]>
[ Upstream commit a3bd2102e464202b58d57390a538d96f57ffc361 ]
Commit 40867d74c374 ("net: Add l3mdev index to flow struct and avoid oif reset for port devices") adds a new entry (flowi_l3mdev) in the common flow struct used for indicating the l3mdev index for later rule and table matching.
The l3mdev_update_flow() has been adapted to properly set the flowi_l3mdev based on the flowi_oif/flowi_iif. In fact, when a valid flowi_iif is supplied to the l3mdev_update_flow(), this function can update the flowi_l3mdev entry only if it has not yet been set (i.e., the flowi_l3mdev entry is equal to 0).
The SRv6 End.DT6 behavior in VRF mode leverages a VRF device in order to force the routing lookup into the associated routing table. This routing operation is performed by seg6_lookup_any_nextop() preparing a flowi6 data structure used by ip6_route_input_lookup() which, in turn, (indirectly) invokes l3mdev_update_flow().
However, seg6_lookup_any_nexthop() does not initialize the new flowi_l3mdev entry which is filled with random garbage data. This prevents l3mdev_update_flow() from properly updating the flowi_l3mdev with the VRF index, and thus SRv6 End.DT6 (VRF mode)/DT46 behaviors are broken.
This patch correctly initializes the flowi6 instance allocated and used by seg6_lookup_any_nexhtop(). Specifically, the entire flowi6 instance is wiped out: in case new entries are added to flowi/flowi6 (as happened with the flowi_l3mdev entry), we should no longer have incorrectly initialized values. As a result of this operation, the value of flowi_l3mdev is also set to 0.
The proposed fix can be tested easily. Starting from the commit referenced in the Fixes, selftests [1],[2] indicate that the SRv6 End.DT6 (VRF mode)/DT46 behaviors no longer work correctly. By applying this patch, those behaviors are back to work properly again.
[1] - tools/testing/selftests/net/srv6_end_dt46_l3vpn_test.sh
[2] - tools/testing/selftests/net/srv6_end_dt6_l3vpn_test.sh
--- net/ipv6/seg6_local.c | 1 + 1 file changed, 1 insertion(+)
net/ipv6/seg6_local.c +1 -0
@@ -218,6 +218,7 @@ seg6_lookup_any_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,struct flowi6 fl6;int dev_flags =0 ; +memset (&fl6,0 ,sizeof (fl6)); fl6.flowi6_iif = skb->dev->ifindex; fl6.daddr = nhaddr ? *nhaddr : hdr->daddr; fl6.saddr = hdr->saddr;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 222/339 iov_iter: Fix iter_xarray_get_pages{,_alloc}()
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit 6c77676645ad42993e0a8bdb8dafa517851a352a ]
The maths at the end of iter_xarray_get_pages() to calculate the actual size doesn't work under some circumstances, such as when it's been asked to extract a partial single page. Various terms of the equation cancel out and you end up with actual == offset. The same issue exists in iter_xarray_get_pages_alloc().
Fix these to just use min() to select the lesser amount from between the amount of page content transcribed into the buffer, minus the offset, and the size limit specified.
This doesn't appear to have caused a problem yet upstream because network filesystems aren't getting the pages from an xarray iterator, but rather passing it directly to the socket, which just iterates over it. Cachefiles *does* do DIO from one to/from ext4/xfs/btrfs/etc. but it always asks for whole pages to be written or read.
--- lib/iov_iter.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-)
lib/iov_iter.c +4 -16
@@ -1434,7 +1434,7 @@ static ssize_t iter_xarray_get_pages(struct iov_iter *i, {unsigned nr, offset;pgoff_t index, count; -size_t size = maxsize, actual; +size_t size = maxsize;loff_t pos;if (!size || !maxpages)
@@ -1461,13 +1461,7 @@ static ssize_t iter_xarray_get_pages(struct iov_iter *i,if (nr ==0 )return 0 ; - actual =PAGE_SIZE * nr; - actual -= offset; -if (nr == count && size >0 ) { -unsigned last_offset = (nr >1 ) ?0 : offset; - actual -=PAGE_SIZE - (last_offset + size); - } -return actual; +return min (nr *PAGE_SIZE - offset, maxsize); }/* must be done on non-empty ITER_IOVEC one */
@@ -1602,7 +1596,7 @@ static ssize_t iter_xarray_get_pages_alloc(struct iov_iter *i,struct page **p;unsigned nr, offset;pgoff_t index, count; -size_t size = maxsize, actual; +size_t size = maxsize;loff_t pos;if (!size)
@@ -1631,13 +1625,7 @@ static ssize_t iter_xarray_get_pages_alloc(struct iov_iter *i,if (nr ==0 )return 0 ; - actual =PAGE_SIZE * nr; - actual -= offset; -if (nr == count && size >0 ) { -unsigned last_offset = (nr >1 ) ?0 : offset; - actual -=PAGE_SIZE - (last_offset + size); - } -return actual; +return min (nr *PAGE_SIZE - offset, maxsize); } ssize_t iov_iter_get_pages_alloc(struct iov_iter *i,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 223/339 iio: dummy: iio_simple_dummy: check the return value of kstrdup()
In reply to Greg Kroah-HartmanFrom: Xiaoke Wang <[email protected]>
[ Upstream commit ba93642188a6fed754bf7447f638bc410e05a929 ]
kstrdup() is also a memory allocation-related function, it returns NULL when some memory errors happen. So it is better to check the return value of it so to catch the memory error in time. Besides, there should have a kfree() to clear up the allocation if we get a failure later in this function to prevent memory leak.
--- drivers/iio/dummy/iio_simple_dummy.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-)
drivers/iio/dummy/iio_simple_dummy.c +12 -8
@@ -575,10 +575,9 @@ static struct iio_sw_device *iio_dummy_probe(const char *name)*/ swd =kzalloc (sizeof (*swd),GFP_KERNEL ); -if (!swd) { - ret = -ENOMEM ; - goto error_kzalloc; - } +if (!swd) +return ERR_PTR (-ENOMEM ); +/* * Allocate an IIO device. *
@@ -590,7 +589,7 @@ static struct iio_sw_device *iio_dummy_probe(const char *name) indio_dev =iio_device_alloc (parent,sizeof (*st));if (!indio_dev) { ret = -ENOMEM ; - goto error_ret; + goto error_free_swd; } st =iio_priv (indio_dev);
@@ -616,6 +615,10 @@ static struct iio_sw_device *iio_dummy_probe(const char *name)* indio_dev->name = spi_get_device_id(spi)->name; */ indio_dev->name =kstrdup (name,GFP_KERNEL ); +if (!indio_dev->name) { + ret = -ENOMEM ; + goto error_free_device; + }/* Provide description of available channels */ indio_dev->channels = iio_dummy_channels;
@@ -632,7 +635,7 @@ static struct iio_sw_device *iio_dummy_probe(const char *name) ret =iio_simple_dummy_events_register (indio_dev);if (ret <0 ) - goto error_free_device; + goto error_free_name; ret =iio_simple_dummy_configure_buffer (indio_dev);if (ret <0 )
@@ -649,11 +652,12 @@ static struct iio_sw_device *iio_dummy_probe(const char *name)iio_simple_dummy_unconfigure_buffer (indio_dev); error_unregister_events:iio_simple_dummy_events_unregister (indio_dev); +error_free_name: +kfree (indio_dev->name); error_free_device:iio_device_free (indio_dev); -error_ret: +error_free_swd:kfree (swd); -error_kzalloc:return ERR_PTR (ret); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 224/339 staging: rtl8712: fix a potential memory leak in r871xu_drv_init()
In reply to Greg Kroah-HartmanFrom: Xiaoke Wang <[email protected]>
[ Upstream commit 7288ff561de650d4139fab80e9cb0da9b5b32434 ]
In r871xu_drv_init(), if r8712_init_drv_sw() fails, then the memory allocated by r8712_alloc_io_queue() in r8712_usb_dvobj_init() is not properly released as there is no action will be performed by r8712_usb_dvobj_deinit().
To properly release it, we should call r8712_free_io_queue() in r8712_usb_dvobj_deinit().
Besides, in r871xu_dev_remove(), r8712_usb_dvobj_deinit() will be called by r871x_dev_unload() under condition padapter->bup and r8712_free_io_queue() is called by r8712_free_drv_sw(). However, r8712_usb_dvobj_deinit() does not rely on padapter->bup and calling r8712_free_io_queue() in r8712_free_drv_sw() is negative for better understading the code.
So I move r8712_usb_dvobj_deinit() into r871xu_dev_remove(), and remove r8712_free_io_queue() from r8712_free_drv_sw().
--- drivers/staging/rtl8712/os_intfs.c | 1 - drivers/staging/rtl8712/usb_intf.c | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-)
drivers/staging/rtl8712/os_intfs.c +0 -1
@@ -332,7 +332,6 @@ void r8712_free_drv_sw(struct _adapter *padapter)r8712_free_evt_priv (&padapter->evtpriv);r8712_DeInitSwLeds (padapter);r8712_free_mlme_priv (&padapter->mlmepriv); -r8712_free_io_queue (padapter);_free_xmit_priv (&padapter->xmitpriv);_r8712_free_sta_priv (&padapter->stapriv);_r8712_free_recv_priv (&padapter->recvpriv);
drivers/staging/rtl8712/usb_intf.c +3 -3
@@ -265,6 +265,7 @@ static uint r8712_usb_dvobj_init(struct _adapter *padapter)static void r8712_usb_dvobj_deinit (struct _adapter *padapter) { +r8712_free_io_queue (padapter); }void rtl871x_intf_stop (struct _adapter *padapter)
@@ -302,9 +303,6 @@ void r871x_dev_unload(struct _adapter *padapter)rtl8712_hal_deinit (padapter); } -/*s6.*/ -if (padapter->dvobj_deinit) - padapter->dvobj_deinit (padapter); padapter->bup = false; } }
@@ -607,6 +605,8 @@ static void r871xu_dev_remove(struct usb_interface *pusb_intf)/* Stop driver mlme relation timer */ r8712_stop_drv_timers (padapter);r871x_dev_unload (padapter); +if (padapter->dvobj_deinit) + padapter->dvobj_deinit (padapter);r8712_free_drv_sw (padapter);free_netdev (pnetdev);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 225/339 iio: st_sensors: Add a local lock for protecting odr
In reply to Greg Kroah-HartmanFrom: Miquel Raynal <[email protected]>
[ Upstream commit 474010127e2505fc463236470908e1ff5ddb3578 ]
Right now the (framework) mlock lock is (ab)used for multiple purposes:
1- protecting concurrent accesses over the odr local cache 2- avoid changing samplig frequency whilst buffer is running
Let's start by handling situation #1 with a local lock.
--- .../iio/common/st_sensors/st_sensors_core.c | 24 ++++++++++++++----- include/linux/iio/common/st_sensors.h | 3 +++ 2 files changed, 21 insertions(+), 6 deletions(-)
drivers/iio/common/st_sensors/st_sensors_core.c +18 -6
@@ -71,16 +71,18 @@ static int st_sensors_match_odr(struct st_sensor_settings *sensor_settings,int st_sensors_set_odr (struct iio_dev *indio_dev,unsigned int odr) { -int err; +int err =0 ;struct st_sensor_odr_avl odr_out = {0 ,0 };struct st_sensor_data *sdata =iio_priv (indio_dev); +mutex_lock (&sdata->odr_lock); +if (!sdata->sensor_settings->odr.mask) -return 0 ; + goto unlock_mutex; err =st_sensors_match_odr (sdata->sensor_settings, odr, &odr_out);if (err <0 ) - goto st_sensors_match_odr_error; + goto unlock_mutex; if ((sdata->sensor_settings->odr.addr == sdata->sensor_settings->pw.addr) &&
@@ -103,7 +105,9 @@ int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr)if (err >=0 ) sdata->odr = odr_out.hz; -st_sensors_match_odr_error: +unlock_mutex: +mutex_unlock (&sdata->odr_lock); +return err; }EXPORT_SYMBOL_NS (st_sensors_set_odr,IIO_ST_SENSORS );
@@ -361,6 +365,8 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,struct st_sensors_platform_data *of_pdata;int err =0 ; +mutex_init (&sdata->odr_lock); +/* If OF/DT pdata exists, it will take precedence of anything else */ of_pdata =st_sensors_dev_probe (indio_dev->dev.parent, pdata);if (IS_ERR (of_pdata))
@@ -554,18 +560,24 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev, err = -EBUSY ; goto out; }else { +mutex_lock (&sdata->odr_lock); err =st_sensors_set_enable (indio_dev, true); -if (err <0 ) +if (err <0 ) { +mutex_unlock (&sdata->odr_lock); goto out; + }msleep ((sdata->sensor_settings->bootime *1000 ) / sdata->odr); err =st_sensors_read_axis_data (indio_dev, ch, val); -if (err <0 ) +if (err <0 ) { +mutex_unlock (&sdata->odr_lock); goto out; + } *val = *val >> ch->scan_type.shift; err =st_sensors_set_enable (indio_dev, false); +mutex_unlock (&sdata->odr_lock); } out:mutex_unlock (&indio_dev->mlock);
include/linux/iio/common/st_sensors.h +3 -0
@@ -237,6 +237,7 @@ struct st_sensor_settings {* @hw_irq_trigger: if we're using the hardware interrupt on the sensor. * @hw_timestamp: Latest timestamp from the interrupt handler, when in use. * @buffer_data: Data used by buffer part. +* @odr_lock: Local lock for preventing concurrent ODR accesses/changes */ struct st_sensor_data {struct iio_trigger *trig;
@@ -261,6 +262,8 @@ struct st_sensor_data {s64 hw_timestamp;char buffer_data[ST_SENSORS_MAX_BUFFER_SIZE ]____cacheline_aligned ; + +struct mutex odr_lock; };#ifdef CONFIG_IIO_BUFFER
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 226/339 lkdtm/usercopy: Expand size of "out of frame" object
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit f387e86d3a74407bdd9c5815820ac9d060962840 ]
To be sufficiently out of range for the usercopy test to see the lifetime mismatch, expand the size of the "bad" buffer, which will let it be beyond current_stack_pointer regardless of stack growth direction. Paired with the recent addition of stack depth checking under CONFIG_HARDENED_USERCOPY=y, this will correctly start tripping again.
--- drivers/misc/lkdtm/usercopy.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
drivers/misc/lkdtm/usercopy.c +14 -3
@@ -30,12 +30,12 @@ static const unsigned char test_text[] = "This is a test.\n";*/ static noinline unsigned char *trick_compiler(unsigned char *stack) { -return stack +0 ; +return stack + unconst; } static noinline unsigned char *do_usercopy_stack_callee(int value) { -unsigned char buf[32 ]; +unsigned char buf[128 ];int i;/* Exercise stack to avoid everything living in registers. */
@@ -43,7 +43,12 @@ static noinline unsigned char *do_usercopy_stack_callee(int value) buf[i] = value &0xff ; } -return trick_compiler (buf); +/* +* Put the target buffer in the middle of stack allocation +* so that we don't step on future stack users regardless +* of stack growth direction. +*/ +return trick_compiler (&buf[(128 /2 )-32 ]); } static noinline void do_usercopy_stack(bool to_user, bool bad_frame)
@@ -66,6 +71,12 @@ static noinline void do_usercopy_stack(bool to_user, bool bad_frame) bad_stack -=sizeof (unsigned long ); } +#ifdef ARCH_HAS_CURRENT_STACK_POINTER +pr_info ("stack : %px\n" , (void *)current_stack_pointer); +#endif +pr_info ("good_stack: %px-%px\n" , good_stack, good_stack +sizeof (good_stack)); +pr_info ("bad_stack : %px-%px\n" , bad_stack, bad_stack +sizeof (good_stack)); + user_addr =vm_mmap (NULL ,0 ,PAGE_SIZE ,PROT_READ |PROT_WRITE |PROT_EXEC ,MAP_ANONYMOUS |MAP_PRIVATE ,0 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 227/339 drivers: staging: rtl8723bs: Fix deadlock in rtw_surveydone_event_callback()
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit cc7ad0d77b51c872d629bcd98aea463a3c4109e7 ]
There is a deadlock in rtw_surveydone_event_callback(), which is shown below:
(Thread 1) | (Thread 2)
| _set_timer()
rtw_surveydone_event_callback()| mod_timer()
spin_lock_bh() //(1) | (wait a time)
... | rtw_scan_timeout_handler()
del_timer_sync() | spin_lock_bh() //(2)
(wait timer to stop) | ...We hold pmlmepriv->lock in position (1) of thread 1 and use del_timer_sync() to wait timer to stop, but timer handler also need pmlmepriv->lock in position (2) of thread 2. As a result, rtw_surveydone_event_callback() will block forever.
This patch extracts del_timer_sync() from the protection of spin_lock_bh(), which could let timer handler to obtain the needed lock. What`s more, we change spin_lock_bh() in rtw_scan_timeout_handler() to spin_lock_irq(). Otherwise, spin_lock_bh() will also cause deadlock() in timer handler.
--- drivers/staging/rtl8723bs/core/rtw_mlme.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/staging/rtl8723bs/core/rtw_mlme.c +4 -2
@@ -751,7 +751,9 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) }if (check_fwstate (pmlmepriv, _FW_UNDER_SURVEY)) { +spin_unlock_bh (&pmlmepriv->lock);del_timer_sync (&pmlmepriv->scan_to_timer); +spin_lock_bh (&pmlmepriv->lock);_clr_fwstate_ (pmlmepriv, _FW_UNDER_SURVEY); }
@@ -1586,11 +1588,11 @@ void rtw_scan_timeout_handler(struct timer_list *t) mlmepriv.scan_to_timer);struct mlme_priv *pmlmepriv = &adapter->mlmepriv; -spin_lock_bh (&pmlmepriv->lock); +spin_lock_irq (&pmlmepriv->lock);_clr_fwstate_ (pmlmepriv, _FW_UNDER_SURVEY); -spin_unlock_bh (&pmlmepriv->lock); +spin_unlock_irq (&pmlmepriv->lock);rtw_indicate_scan_done (adapter, true); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 228/339 drivers: staging: rtl8192bs: Fix deadlock in rtw_joinbss_event_prehandle()
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit 041879b12ddb0c6c83ed9c0bdd10dc82a056f2fc ]
There is a deadlock in rtw_joinbss_event_prehandle(), which is shown below:
(Thread 1) | (Thread 2)
| _set_timer()
rtw_joinbss_event_prehandle()| mod_timer()
spin_lock_bh() //(1) | (wait a time)
... | _rtw_join_timeout_handler()
del_timer_sync() | spin_lock_bh() //(2)
(wait timer to stop) | ...We hold pmlmepriv->lock in position (1) of thread 1 and use del_timer_sync() to wait timer to stop, but timer handler also need pmlmepriv->lock in position (2) of thread 2. As a result, rtw_joinbss_event_prehandle() will block forever.
This patch extracts del_timer_sync() from the protection of spin_lock_bh(), which could let timer handler to obtain the needed lock. What`s more, we change spin_lock_bh() to spin_lock_irq() in _rtw_join_timeout_handler() in order to prevent deadlock.
--- drivers/staging/rtl8723bs/core/rtw_mlme.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/staging/rtl8723bs/core/rtw_mlme.c +4 -2
@@ -1240,8 +1240,10 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf)spin_unlock_bh (&pmlmepriv->scanned_queue.lock); +spin_unlock_bh (&pmlmepriv->lock);/* s5. Cancel assoc_timer */ del_timer_sync (&pmlmepriv->assoc_timer); +spin_lock_bh (&pmlmepriv->lock); }else {spin_unlock_bh (&(pmlmepriv->scanned_queue.lock)); }
@@ -1547,7 +1549,7 @@ void _rtw_join_timeout_handler(struct timer_list *t)if (adapter->bDriverStopped || adapter->bSurpriseRemoved)return ; -spin_lock_bh (&pmlmepriv->lock); +spin_lock_irq (&pmlmepriv->lock);if (rtw_to_roam (adapter) >0 ) {/* join timeout caused by roaming */ while (1 ) {
@@ -1575,7 +1577,7 @@ void _rtw_join_timeout_handler(struct timer_list *t) } -spin_unlock_bh (&pmlmepriv->lock); +spin_unlock_irq (&pmlmepriv->lock); }/*
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 229/339 drivers: staging: rtl8192eu: Fix deadlock in rtw_joinbss_event_prehandle
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit 0fcddf9c7c10202946d5b19409efbdff744fba88 ]
There is a deadlock in rtw_joinbss_event_prehandle(), which is shown below:
(Thread 1) | (Thread 2)
| _set_timer()
rtw_joinbss_event_prehandle()| mod_timer()
spin_lock_bh() //(1) | (wait a time)
... | rtw_join_timeout_handler()
| _rtw_join_timeout_handler()
del_timer_sync() | spin_lock_bh() //(2)
(wait timer to stop) | ...We hold pmlmepriv->lock in position (1) of thread 1 and use del_timer_sync() to wait timer to stop, but timer handler also need pmlmepriv->lock in position (2) of thread 2. As a result, rtw_joinbss_event_prehandle() will block forever.
This patch extracts del_timer_sync() from the protection of spin_lock_bh(), which could let timer handler to obtain the needed lock. What`s more, we change spin_lock_bh() to spin_lock_irq() in _rtw_join_timeout_handler() in order to prevent deadlock.
--- drivers/staging/r8188eu/core/rtw_mlme.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/staging/r8188eu/core/rtw_mlme.c +4 -2
@@ -1071,8 +1071,10 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf)rtw_indicate_connect (adapter); } +spin_unlock_bh (&pmlmepriv->lock);/* s5. Cancel assoc_timer */ del_timer_sync (&pmlmepriv->assoc_timer); +spin_lock_bh (&pmlmepriv->lock); }else {spin_unlock_bh (&pmlmepriv->scanned_queue.lock); goto ignore_joinbss_callback;
@@ -1310,7 +1312,7 @@ void _rtw_join_timeout_handler (struct adapter *adapter)if (adapter->bDriverStopped || adapter->bSurpriseRemoved)return ; -spin_lock_bh (&pmlmepriv->lock); +spin_lock_irq (&pmlmepriv->lock);if (rtw_to_roaming (adapter) >0 ) {/* join timeout caused by roaming */ while (1 ) {
@@ -1329,7 +1331,7 @@ void _rtw_join_timeout_handler (struct adapter *adapter)rtw_indicate_disconnect (adapter);free_scanqueue (pmlmepriv);/* */ } -spin_unlock_bh (&pmlmepriv->lock); +spin_unlock_irq (&pmlmepriv->lock); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 230/339 tty: synclink_gt: Fix null-pointer-dereference in slgt_clean()
In reply to Greg Kroah-HartmanFrom: Zheyu Ma <[email protected]>
[ Upstream commit 689ca31c542687709ba21ec2195c1fbce34fd029 ]
When the driver fails at alloc_hdlcdev(), and then we remove the driver module, we will get the following splat:
[ 25.065966] general protection fault, probably for non-canonical address 0xdffffc0000000182: 0000 [#1] PREEMPT SMP KASAN PTI [ 25.066914] KASAN: null-ptr-deref in range [0x0000000000000c10-0x0000000000000c17] [ 25.069262] RIP: 0010:detach_hdlc_protocol+0x2a/0x3e0 [ 25.077709] Call Trace: [ 25.077924] <TASK> [ 25.078108] unregister_hdlc_device+0x16/0x30 [ 25.078481] slgt_cleanup+0x157/0x9f0 [synclink_gt]
Fix this by checking whether the 'info->netdev' is a null pointer first.
--- drivers/tty/synclink_gt.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/tty/synclink_gt.c +2 -0
@@ -1746,6 +1746,8 @@ static int hdlcdev_init(struct slgt_info *info)*/ static void hdlcdev_exit (struct slgt_info *info) { +if (!info->netdev) +return ;unregister_hdlc_device (info->netdev);free_netdev (info->netdev); info->netdev =NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 231/339 tty: Fix a possible resource leak in icom_probe
In reply to Greg Kroah-HartmanFrom: Huang Guobin <[email protected]>
[ Upstream commit ee157a79e7c82b01ae4c25de0ac75899801f322c ]
When pci_read_config_dword failed, call pci_release_regions() and pci_disable_device() to recycle the resource previously allocated.
--- drivers/tty/serial/icom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/icom.c +1 -1
@@ -1501,7 +1501,7 @@ static int icom_probe(struct pci_dev *dev, retval =pci_read_config_dword (dev,PCI_COMMAND , &command_reg);if (retval) {dev_err (&dev->dev,"PCI Config read FAILED\n" ); -return retval; + goto probe_exit0; } pci_write_config_dword(dev, PCI_COMMAND,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 232/339 thunderbolt: Use different lane for second DisplayPort tunnel
In reply to Greg Kroah-HartmanFrom: Mika Westerberg <[email protected]>
[ Upstream commit 9d2d0a5cf0ca063f417681cc33e767ce52615286 ]
Brad reported that on Apple hardware with Light Ridge or Falcon Ridge controller, plugging in a chain of Thunderbolt displays (Light Ridge based controllers) causes all kinds of tearing and flickering. The reason for this is that on Thunderbolt 1 hardware there is no lane bonding so we have two independent 10 Gb/s lanes, and currently Linux tunnels both displays through the lane 1. This makes the displays to share the 10 Gb/s bandwidth which may not be enough for higher resolutions.
For this reason make the second tunnel go through the lane 0 instead. This seems to match what the macOS connection manager is also doing.
--- drivers/thunderbolt/tb.c | 19 +++++++++++++++++-- drivers/thunderbolt/test.c | 16 ++++++++-------- drivers/thunderbolt/tunnel.c | 11 ++++++----- drivers/thunderbolt/tunnel.h | 4 ++-- 4 files changed, 33 insertions(+), 17 deletions(-)
drivers/thunderbolt/tb.c +17 -2
@@ -867,7 +867,7 @@ static struct tb_port *tb_find_dp_out(struct tb *tb, struct tb_port *in)static void tb_tunnel_dp (struct tb *tb) { -int available_up, available_down, ret; +int available_up, available_down, ret, link_nr;struct tb_cm *tcm =tb_priv (tb);struct tb_port *port, *in, *out;struct tb_tunnel *tunnel;
@@ -912,6 +912,20 @@ static void tb_tunnel_dp(struct tb *tb)return ; } +/* +* This is only applicable to links that are not bonded (so +* when Thunderbolt 1 hardware is involved somewhere in the +* topology). For these try to share the DP bandwidth between +* the two lanes. +*/ + link_nr =1 ; +list_for_each_entry (tunnel, &tcm->tunnel_list, list) { +if (tb_tunnel_is_dp (tunnel)) { + link_nr =0 ; +break ; + } + } +/* * DP stream needs the domain to be active so runtime resume * both ends of the tunnel.
@@ -943,7 +957,8 @@ static void tb_tunnel_dp(struct tb *tb)tb_dbg (tb,"available bandwidth for new DP tunnel %u/%u Mb/s\n" , available_up, available_down); - tunnel =tb_tunnel_alloc_dp (tb, in, out, available_up, available_down); + tunnel =tb_tunnel_alloc_dp (tb, in, out, link_nr, available_up, + available_down);if (!tunnel) {tb_port_dbg (out,"could not allocate DP tunnel\n" ); goto err_reclaim;
drivers/thunderbolt/test.c +8 -8
@@ -1348,7 +1348,7 @@ static void tb_test_tunnel_dp(struct kunit *test) in = &host->ports[5 ]; out = &dev->ports[13 ]; - tunnel =tb_tunnel_alloc_dp (NULL , in, out,0 ,0 ); + tunnel =tb_tunnel_alloc_dp (NULL , in, out,1 ,0 ,0 );KUNIT_ASSERT_TRUE (test, tunnel !=NULL );KUNIT_EXPECT_EQ (test, tunnel->type,TB_TUNNEL_DP );KUNIT_EXPECT_PTR_EQ (test, tunnel->src_port, in);
@@ -1394,7 +1394,7 @@ static void tb_test_tunnel_dp_chain(struct kunit *test) in = &host->ports[5 ]; out = &dev4->ports[14 ]; - tunnel =tb_tunnel_alloc_dp (NULL , in, out,0 ,0 ); + tunnel =tb_tunnel_alloc_dp (NULL , in, out,1 ,0 ,0 );KUNIT_ASSERT_TRUE (test, tunnel !=NULL );KUNIT_EXPECT_EQ (test, tunnel->type,TB_TUNNEL_DP );KUNIT_EXPECT_PTR_EQ (test, tunnel->src_port, in);
@@ -1444,7 +1444,7 @@ static void tb_test_tunnel_dp_tree(struct kunit *test) in = &dev2->ports[13 ]; out = &dev5->ports[13 ]; - tunnel =tb_tunnel_alloc_dp (NULL , in, out,0 ,0 ); + tunnel =tb_tunnel_alloc_dp (NULL , in, out,1 ,0 ,0 );KUNIT_ASSERT_TRUE (test, tunnel !=NULL );KUNIT_EXPECT_EQ (test, tunnel->type,TB_TUNNEL_DP );KUNIT_EXPECT_PTR_EQ (test, tunnel->src_port, in);
@@ -1509,7 +1509,7 @@ static void tb_test_tunnel_dp_max_length(struct kunit *test) in = &dev6->ports[13 ]; out = &dev12->ports[13 ]; - tunnel =tb_tunnel_alloc_dp (NULL , in, out,0 ,0 ); + tunnel =tb_tunnel_alloc_dp (NULL , in, out,1 ,0 ,0 );KUNIT_ASSERT_TRUE (test, tunnel !=NULL );KUNIT_EXPECT_EQ (test, tunnel->type,TB_TUNNEL_DP );KUNIT_EXPECT_PTR_EQ (test, tunnel->src_port, in);
@@ -1627,7 +1627,7 @@ static void tb_test_tunnel_port_on_path(struct kunit *test) in = &dev2->ports[13 ]; out = &dev5->ports[13 ]; - dp_tunnel =tb_tunnel_alloc_dp (NULL , in, out,0 ,0 ); + dp_tunnel =tb_tunnel_alloc_dp (NULL , in, out,1 ,0 ,0 );KUNIT_ASSERT_TRUE (test, dp_tunnel !=NULL );KUNIT_EXPECT_TRUE (test,tb_tunnel_port_on_path (dp_tunnel, in));
@@ -2009,7 +2009,7 @@ static void tb_test_credit_alloc_dp(struct kunit *test) in = &host->ports[5 ]; out = &dev->ports[14 ]; - tunnel =tb_tunnel_alloc_dp (NULL , in, out,0 ,0 ); + tunnel =tb_tunnel_alloc_dp (NULL , in, out,1 ,0 ,0 );KUNIT_ASSERT_TRUE (test, tunnel !=NULL );KUNIT_ASSERT_EQ (test, tunnel->npaths, (size_t )3 );
@@ -2245,7 +2245,7 @@ static struct tb_tunnel *TB_TEST_DP_TUNNEL1(struct kunit *test, in = &host->ports[5 ]; out = &dev->ports[13 ]; - dp_tunnel1 =tb_tunnel_alloc_dp (NULL , in, out,0 ,0 ); + dp_tunnel1 =tb_tunnel_alloc_dp (NULL , in, out,1 ,0 ,0 );KUNIT_ASSERT_TRUE (test, dp_tunnel1 !=NULL );KUNIT_ASSERT_EQ (test, dp_tunnel1->npaths, (size_t )3 );
@@ -2282,7 +2282,7 @@ static struct tb_tunnel *TB_TEST_DP_TUNNEL2(struct kunit *test, in = &host->ports[6 ]; out = &dev->ports[14 ]; - dp_tunnel2 =tb_tunnel_alloc_dp (NULL , in, out,0 ,0 ); + dp_tunnel2 =tb_tunnel_alloc_dp (NULL , in, out,1 ,0 ,0 );KUNIT_ASSERT_TRUE (test, dp_tunnel2 !=NULL );KUNIT_ASSERT_EQ (test, dp_tunnel2->npaths, (size_t )3 );
drivers/thunderbolt/tunnel.c +6 -5
@@ -858,6 +858,7 @@ struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in,* @tb: Pointer to the domain structure * @in: DP in adapter port * @out: DP out adapter port +* @link_nr: Preferred lane adapter when the link is not bonded * @max_up: Maximum available upstream bandwidth for the DP tunnel (%0 * if not limited) * @max_down: Maximum available downstream bandwidth for the DP tunnel
@@ -869,8 +870,8 @@ struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in,* Return: Returns a tb_tunnel on success or NULL on failure. */ struct tb_tunnel *tb_tunnel_alloc_dp (struct tb *tb,struct tb_port *in, -struct tb_port *out,int max_up, -int max_down) +struct tb_port *out,int link_nr, +int max_up,int max_down) {struct tb_tunnel *tunnel;struct tb_path **paths;
@@ -894,21 +895,21 @@ struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in, paths = tunnel->paths; path =tb_path_alloc (tb, in,TB_DP_VIDEO_HOPID , out,TB_DP_VIDEO_HOPID , -1 ,"Video" ); + link_nr,"Video" );if (!path) goto err_free;tb_dp_init_video_path (path); paths[TB_DP_VIDEO_PATH_OUT ] = path; path =tb_path_alloc (tb, in,TB_DP_AUX_TX_HOPID , out, -TB_DP_AUX_TX_HOPID ,1 ,"AUX TX" ); +TB_DP_AUX_TX_HOPID , link_nr,"AUX TX" );if (!path) goto err_free;tb_dp_init_aux_path (path); paths[TB_DP_AUX_PATH_OUT ] = path; path =tb_path_alloc (tb, out,TB_DP_AUX_RX_HOPID , in, -TB_DP_AUX_RX_HOPID ,1 ,"AUX RX" ); +TB_DP_AUX_RX_HOPID , link_nr,"AUX RX" );if (!path) goto err_free;tb_dp_init_aux_path (path);
drivers/thunderbolt/tunnel.h +2 -2
@@ -71,8 +71,8 @@ struct tb_tunnel *tb_tunnel_alloc_pci(struct tb *tb, struct tb_port *up,struct tb_tunnel *tb_tunnel_discover_dp (struct tb *tb,struct tb_port *in,bool alloc_hopid);struct tb_tunnel *tb_tunnel_alloc_dp (struct tb *tb,struct tb_port *in, -struct tb_port *out,int max_up, -int max_down); +struct tb_port *out,int link_nr, +int max_up,int max_down); struct tb_tunnel *tb_tunnel_alloc_dma(struct tb *tb, struct tb_port *nhi, struct tb_port *dst, int transmit_path, int transmit_ring, int receive_path,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 233/339 drivers: staging: rtl8192u: Fix deadlock in ieee80211_beacons_stop()
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit 806c7b53414934ba2a39449b31fd1a038e500273 ]
There is a deadlock in ieee80211_beacons_stop(), which is shown below:
(Thread 1) | (Thread 2)
| ieee80211_send_beacon()
ieee80211_beacons_stop() | mod_timer()
spin_lock_irqsave() //(1) | (wait a time)
... | ieee80211_send_beacon_cb()
del_timer_sync() | spin_lock_irqsave() //(2)
(wait timer to stop) | ...We hold ieee->beacon_lock in position (1) of thread 1 and use del_timer_sync() to wait timer to stop, but timer handler also need ieee->beacon_lock in position (2) of thread 2. As a result, ieee80211_beacons_stop() will block forever.
This patch extracts del_timer_sync() from the protection of spin_lock_irqsave(), which could let timer handler to obtain the needed lock.
--- drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +1 -1
@@ -528,9 +528,9 @@ static void ieee80211_beacons_stop(struct ieee80211_device *ieee)spin_lock_irqsave (&ieee->beacon_lock, flags); ieee->beacon_txing =0 ; -del_timer_sync (&ieee->beacon_timer);spin_unlock_irqrestore (&ieee->beacon_lock, flags); +del_timer_sync (&ieee->beacon_timer); }void ieee80211_stop_send_beacons (struct ieee80211_device *ieee)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 234/339 drivers: staging: rtl8192e: Fix deadlock in rtllib_beacons_stop()
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit 9b6bdbd9337de3917945847bde262a34a87a6303 ]
There is a deadlock in rtllib_beacons_stop(), which is shown below:
(Thread 1) | (Thread 2)
| rtllib_send_beacon()
rtllib_beacons_stop() | mod_timer()
spin_lock_irqsave() //(1) | (wait a time)
... | rtllib_send_beacon_cb()
del_timer_sync() | spin_lock_irqsave() //(2)
(wait timer to stop) | ...We hold ieee->beacon_lock in position (1) of thread 1 and use del_timer_sync() to wait timer to stop, but timer handler also need ieee->beacon_lock in position (2) of thread 2. As a result, rtllib_beacons_stop() will block forever.
This patch extracts del_timer_sync() from the protection of spin_lock_irqsave(), which could let timer handler to obtain the needed lock.
--- drivers/staging/rtl8192e/rtllib_softmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/rtl8192e/rtllib_softmac.c +1 -1
@@ -651,9 +651,9 @@ static void rtllib_beacons_stop(struct rtllib_device *ieee)spin_lock_irqsave (&ieee->beacon_lock, flags); ieee->beacon_txing =0 ; -del_timer_sync (&ieee->beacon_timer);spin_unlock_irqrestore (&ieee->beacon_lock, flags); +del_timer_sync (&ieee->beacon_timer); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 235/339 USB: host: isp116x: check return value after calling platform_get_resource()
In reply to Greg Kroah-HartmanFrom: Zhen Ni <[email protected]>
[ Upstream commit 134a3408c2d3f7e23eb0e4556e0a2d9f36c2614e ]
It will cause null-ptr-deref if platform_get_resource() returns NULL, we need check the return value.
--- drivers/usb/host/isp116x-hcd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/usb/host/isp116x-hcd.c +4 -2
@@ -1541,10 +1541,12 @@ static int isp116x_remove(struct platform_device *pdev)iounmap (isp116x->data_reg); res =platform_get_resource (pdev,IORESOURCE_MEM ,1 ); -release_mem_region (res->start,2 ); +if (res) +release_mem_region (res->start,2 );iounmap (isp116x->addr_reg); res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); -release_mem_region (res->start,2 ); +if (res) +release_mem_region (res->start,2 );usb_put_hcd (hcd);return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 236/339 drivers: tty: serial: Fix deadlock in sa1100_set_termios()
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit 62b2caef400c1738b6d22f636c628d9f85cd4c4c ]
There is a deadlock in sa1100_set_termios(), which is shown below:
(Thread 1) | (Thread 2)
| sa1100_enable_ms()
sa1100_set_termios() | mod_timer()
spin_lock_irqsave() //(1) | (wait a time)
... | sa1100_timeout()
del_timer_sync() | spin_lock_irqsave() //(2)
(wait timer to stop) | ...We hold sport->port.lock in position (1) of thread 1 and use del_timer_sync() to wait timer to stop, but timer handler also need sport->port.lock in position (2) of thread 2. As a result, sa1100_set_termios() will block forever.
This patch moves del_timer_sync() before spin_lock_irqsave() in order to prevent the deadlock.
--- drivers/tty/serial/sa1100.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/tty/serial/sa1100.c +2 -2
@@ -446,6 +446,8 @@ sa1100_set_termios(struct uart_port *port, struct ktermios *termios, baud =uart_get_baud_rate (port, termios, old,0 , port->uartclk/16 ); quot =uart_get_divisor (port, baud); +del_timer_sync (&sport->timer); +spin_lock_irqsave (&sport->port.lock, flags); sport->port.read_status_mask &=UTSR0_TO_SM (UTSR0_TFS );
@@ -476,8 +478,6 @@ sa1100_set_termios(struct uart_port *port, struct ktermios *termios,UTSR1_TO_SM (UTSR1_ROR ); } -del_timer_sync (&sport->timer); -/* * Update the per-port timeout. */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 237/339 drivers: usb: host: Fix deadlock in oxu_bus_suspend()
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit 4d378f2ae58138d4c55684e1d274e7dd94aa6524 ]
There is a deadlock in oxu_bus_suspend(), which is shown below:
(Thread 1) | (Thread 2)
| timer_action()
oxu_bus_suspend() | mod_timer()
spin_lock_irq() //(1) | (wait a time)
... | oxu_watchdog()
del_timer_sync() | spin_lock_irq() //(2)
(wait timer to stop) | ...We hold oxu->lock in position (1) of thread 1, and use del_timer_sync() to wait timer to stop, but timer handler also need oxu->lock in position (2) of thread 2. As a result, oxu_bus_suspend() will block forever.
This patch extracts del_timer_sync() from the protection of spin_lock_irq(), which could let timer handler to obtain the needed lock.
--- drivers/usb/host/oxu210hp-hcd.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/host/oxu210hp-hcd.c +2 -0
@@ -3909,8 +3909,10 @@ static int oxu_bus_suspend(struct usb_hcd *hcd) } } +spin_unlock_irq (&oxu->lock);/* turn off now-idle HC */ del_timer_sync (&oxu->watchdog); +spin_lock_irq (&oxu->lock);ehci_halt (oxu); hcd->state =HC_STATE_SUSPENDED ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 238/339 USB: hcd-pci: Fully suspend across freeze/thaw cycle
In reply to Greg Kroah-HartmanFrom: Evan Green <[email protected]>
[ Upstream commit 63acaa8e9c65dc34dc249440216f8e977f5d2748 ]
The documentation for the freeze() method says that it "should quiesce the device so that it doesn't generate IRQs or DMA". The unspoken consequence of not doing this is that MSIs aimed at non-boot CPUs may get fully lost if they're sent during the period where the target CPU is offline.
The current callbacks for USB HCD do not fully quiesce interrupts, specifically on XHCI. Change to use the full suspend/resume flow for freeze/thaw to ensure interrupts are fully quiesced. This fixes issues where USB devices fail to thaw during hibernation because XHCI misses its interrupt and cannot recover.
--- drivers/usb/core/hcd-pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/core/hcd-pci.c +2 -2
@@ -616,10 +616,10 @@ const struct dev_pm_ops usb_hcd_pci_pm_ops = { .suspend_noirq = hcd_pci_suspend_noirq, .resume_noirq = hcd_pci_resume_noirq, .resume = hcd_pci_resume, - .freeze = check_root_hub_suspended, + .freeze = hcd_pci_suspend, .freeze_noirq = check_root_hub_suspended, .thaw_noirq = NULL, - .thaw = NULL, + .thaw = hcd_pci_resume, .poweroff = hcd_pci_suspend, .poweroff_noirq = hcd_pci_suspend_noirq, .restore_noirq = hcd_pci_resume_noirq,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 239/339 char: xillybus: fix a refcount leak in cleanup_dev()
In reply to Greg Kroah-HartmanFrom: Hangyu Hua <[email protected]>
[ Upstream commit b67d19662fdee275c479d21853bc1239600a798f ]
usb_get_dev is called in xillyusb_probe. So it is better to call usb_put_dev before xdev is released.
--- drivers/char/xillybus/xillyusb.c | 1 + 1 file changed, 1 insertion(+)
drivers/char/xillybus/xillyusb.c +1 -0
@@ -549,6 +549,7 @@ static void cleanup_dev(struct kref *kref)if (xdev->workq)destroy_workqueue (xdev->workq); +usb_put_dev (xdev->udev);kfree (xdev->channels);/* Argument may be NULL, and that's fine */ kfree (xdev); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 240/339 sysrq: do not omit current cpu when showing backtrace of all active CPUs
In reply to Greg Kroah-HartmanFrom: Changbin Du <[email protected]>
[ Upstream commit 5390e7f46b9d5546d45a83e6463bc656678b1d0e ]
The backtrace of current CPU also should be printed as it is active. This change add stack trace for current CPU and print a hint for idle CPU for the generic workqueue based printing. (x86 already does this)
Now it looks like below:
[ 279.401567] sysrq: Show backtrace of all active CPUs [ 279.407234] sysrq: CPU5: [ 279.407505] Call Trace: [ 279.408789] [<ffffffff8000606c>] dump_backtrace+0x2c/0x3a [ 279.411698] [<ffffffff800060ac>] show_stack+0x32/0x3e [ 279.411809] [<ffffffff80542258>] sysrq_handle_showallcpus+0x4c/0xc6 [ 279.411929] [<ffffffff80542f16>] __handle_sysrq+0x106/0x26c [ 279.412034] [<ffffffff805436a8>] write_sysrq_trigger+0x64/0x74 [ 279.412139] [<ffffffff8029cd48>] proc_reg_write+0x8e/0xe2 [ 279.412252] [<ffffffff8021a8f8>] vfs_write+0x90/0x2be [ 279.412362] [<ffffffff8021acd2>] ksys_write+0xa6/0xce [ 279.412467] [<ffffffff8021ad24>] sys_write+0x2a/0x38 [ 279.412689] [<ffffffff80003ff8>] ret_from_syscall+0x0/0x2 [ 279.417173] sysrq: CPU6: backtrace skipped as idling [ 279.417185] sysrq: CPU4: backtrace skipped as idling [ 279.417187] sysrq: CPU0: backtrace skipped as idling [ 279.417181] sysrq: CPU7: backtrace skipped as idling [ 279.417190] sysrq: CPU1: backtrace skipped as idling [ 279.417193] sysrq: CPU3: backtrace skipped as idling [ 279.417219] sysrq: CPU2: [ 279.419179] Call Trace: [ 279.419440] [<ffffffff8000606c>] dump_backtrace+0x2c/0x3a [ 279.419782] [<ffffffff800060ac>] show_stack+0x32/0x3e [ 279.420015] [<ffffffff80542b30>] showacpu+0x5c/0x96 [ 279.420317] [<ffffffff800ba71c>] flush_smp_call_function_queue+0xd6/0x218 [ 279.420569] [<ffffffff800bb438>] generic_smp_call_function_single_interrupt+0x14/0x1c [ 279.420798] [<ffffffff800079ae>] handle_IPI+0xaa/0x13a [ 279.421024] [<ffffffff804dcb92>] riscv_intc_irq+0x56/0x70 [ 279.421274] [<ffffffff80a05b70>] generic_handle_arch_irq+0x6a/0xfa [ 279.421518] [<ffffffff80004006>] ret_from_exception+0x0/0x10 [ 279.421750] [<ffffffff80096492>] rcu_idle_enter+0x16/0x1e
--- drivers/tty/sysrq.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/tty/sysrq.c +9 -4
@@ -232,8 +232,10 @@ static void showacpu(void *dummy)unsigned long flags;/* Idle CPUs have no interesting backtrace. */ -if (idle_cpu (smp_processor_id ())) +if (idle_cpu (smp_processor_id ())) { +pr_info ("CPU%d: backtrace skipped as idling\n" ,smp_processor_id ());return ; + }raw_spin_lock_irqsave (&show_lock, flags);pr_info ("CPU%d:\n" ,smp_processor_id ());
@@ -260,10 +262,13 @@ static void sysrq_handle_showallcpus(int key)if (in_hardirq ()) regs =get_irq_regs (); -if (regs) { -pr_info ("CPU%d:\n" ,smp_processor_id ()); + +pr_info ("CPU%d:\n" ,smp_processor_id ()); +if (regs)show_regs (regs); - } +else +show_stack (NULL ,NULL ,KERN_INFO ); +schedule_work (&sysrq_showallcpus); } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 241/339 usb: dwc2: gadget: dont reset gadgets driver->bus
In reply to Greg Kroah-HartmanFrom: Marek Szyprowski <[email protected]>
[ Upstream commit 3120aac6d0ecd9accf56894aeac0e265f74d3d5a ]
UDC driver should not touch gadget's driver internals, especially it should not reset driver->bus. This wasn't harmful so far, but since commit fc274c1e9973 ("USB: gadget: Add a new bus for gadgets") gadget subsystem got it's own bus and messing with ->bus triggers the following NULL pointer dereference:
dwc2 12480000.hsotg: bound driver g_ether
8<--- cut here ---
Unable to handle kernel NULL pointer dereference at virtual address 00000000 [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] SMP ARM Modules linked in: ... CPU: 0 PID: 620 Comm: modprobe Not tainted 5.18.0-rc5-next-20220504 #11862 Hardware name: Samsung Exynos (Flattened Device Tree) PC is at module_add_driver+0x44/0xe8 LR is at sysfs_do_create_link_sd+0x84/0xe0
...
Process modprobe (pid: 620, stack limit = 0x(ptrval))
...
module_add_driver from bus_add_driver+0xf4/0x1e4 bus_add_driver from driver_register+0x78/0x10c driver_register from usb_gadget_register_driver_owner+0x40/0xb4 usb_gadget_register_driver_owner from do_one_initcall+0x44/0x1e0 do_one_initcall from do_init_module+0x44/0x1c8 do_init_module from load_module+0x19b8/0x1b9c load_module from sys_finit_module+0xdc/0xfc sys_finit_module from ret_fast_syscall+0x0/0x54
Exception stack(0xf1771fa8 to 0xf1771ff0) ... dwc2 12480000.hsotg: new device is high-speed ---[ end trace 0000000000000000 ]---
Fix this by removing driver->bus entry reset.
--- drivers/usb/dwc2/gadget.c | 1 - 1 file changed, 1 deletion(-)
drivers/usb/dwc2/gadget.c +0 -1
@@ -4544,7 +4544,6 @@ static int dwc2_hsotg_udc_start(struct usb_gadget *gadget,WARN_ON (hsotg->driver); - driver->driver.bus =NULL ; hsotg->driver = driver; hsotg->gadget.dev.of_node = hsotg->dev->of_node; hsotg->gadget.speed =USB_SPEED_UNKNOWN ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 242/339 usb: dwc3: host: Stop setting the ACPI companion
In reply to Greg Kroah-HartmanFrom: Heikki Krogerus <[email protected]>
[ Upstream commit 7fd069d65da2e20b1caec3b7bcf9dfbe28c04bb2 ]
It is no longer needed. The sysdev pointer is now used when assigning the ACPI companions to the xHCI ports and USB devices.
Assigning the ACPI companion here resulted in the fwnode->secondary pointer to be replaced also for the parent dwc3 device since the primary fwnode (the ACPI companion) was shared. That was unintentional and it created potential side effects like resource leaks.
--- drivers/usb/dwc3/host.c | 2 -- 1 file changed, 2 deletions(-)
drivers/usb/dwc3/host.c +0 -2
@@ -7,7 +7,6 @@* Authors: Felipe Balbi <[email protected]>, */ -#include <linux/acpi.h> #include <linux/irq.h> #include <linux/of.h> #include <linux/platform_device.h>
@@ -83,7 +82,6 @@ int dwc3_host_init(struct dwc3 *dwc) } xhci->dev.parent = dwc->dev; -ACPI_COMPANION_SET (&xhci->dev,ACPI_COMPANION (dwc->dev)); dwc->xhci = xhci;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 243/339 usb: dwc3: gadget: Only End Transfer for ep0 data phase
In reply to Greg Kroah-HartmanFrom: Thinh Nguyen <[email protected]>
[ Upstream commit ace17b6ee4f92ab0375d12a1b42494f8590a96b6 ]
The driver shouldn't be able to issue End Transfer to the control endpoint at anytime. Typically we should only do so in error cases such as invalid/unexpected direction of Data Phase as described in the control transfer flow of the programming guide. It _may_ end started data phase during controller deinitialization from soft disconnect or driver removal. However, that should not happen because the driver should be maintained in EP0_SETUP_PHASE during driver tear-down. On soft-connect, the controller should be reset from a soft-reset and there should be no issue starting the control endpoint.
--- drivers/usb/dwc3/gadget.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/usb/dwc3/gadget.c +11 -0
@@ -3685,6 +3685,17 @@ static void dwc3_reset_gadget(struct dwc3 *dwc)void dwc3_stop_active_transfer (struct dwc3_ep *dep,bool force,bool interrupt) { +struct dwc3 *dwc = dep->dwc; + +/* +* Only issue End Transfer command to the control endpoint of a started +* Data Phase. Typically we should only do so in error cases such as +* invalid/unexpected direction as described in the control transfer +* flow of the programming guide. +*/ +if (dep->number <=1 && dwc->ep0state !=EP0_DATA_PHASE ) +return ; +if (!(dep->flags &DWC3_EP_TRANSFER_STARTED ) || (dep->flags &DWC3_EP_DELAY_STOP ) || (dep->flags &DWC3_EP_END_TRANSFER_PENDING ))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 244/339 soundwire: qcom: adjust autoenumeration timeout
In reply to Greg Kroah-HartmanFrom: Srinivas Kandagatla <[email protected]>
[ Upstream commit 74da272400b46f2e898f115d1b1cd60828766919 ]
Currently timeout for autoenumeration during probe and bus reset is set to 2 secs which is really a big value. This can have an adverse effect on boot time if the slave device is not ready/reset.
This was the case with wcd938x which was not reset yet but we spent 2 secs waiting in the soundwire controller probe. Reduce this time to 1/10 of Hz which should be good enough time to finish autoenumeration if any slaves are available on the bus.
--- drivers/soundwire/qcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/soundwire/qcom.c +1 -1
@@ -105,7 +105,7 @@#define SWRM_SPECIAL_CMD_ID 0xF#define MAX_FREQ_NUM 1 -#define TIMEOUT_MS (2 * HZ) +#define TIMEOUT_MS 100#define QCOM_SWRM_MAX_RD_LEN 0x1#define QCOM_SDW_MAX_PORTS 14#define DEFAULT_CLK_FREQ 9600000
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 245/339 misc: rtsx: set NULL intfdata when probe fails
In reply to Greg Kroah-HartmanFrom: Shuah Khan <[email protected]>
[ Upstream commit f861d36e021e1ac4a0a2a1f6411d623809975d63 ]
rtsx_usb_probe() doesn't call usb_set_intfdata() to null out the interface pointer when probe fails. This leaves a stale pointer. Noticed the missing usb_set_intfdata() while debugging an unrelated invalid DMA mapping problem.
Fix it with a call to usb_set_intfdata(..., NULL).
--- drivers/misc/cardreader/rtsx_usb.c | 1 + 1 file changed, 1 insertion(+)
drivers/misc/cardreader/rtsx_usb.c +1 -0
@@ -667,6 +667,7 @@ static int rtsx_usb_probe(struct usb_interface *intf,return 0 ; out_init_fail: +usb_set_intfdata (ucr->pusb_intf,NULL );usb_free_coherent (ucr->pusb_dev,IOBUF_SIZE , ucr->iobuf, ucr->iobuf_dma);return ret;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 246/339 extcon: Fix extcon_get_extcon_dev() error handling
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 58e4a2d27d3255e4e8c507fdc13734dccc9fc4c7 ]
The extcon_get_extcon_dev() function returns error pointers on error, NULL when it's a -EPROBE_DEFER defer situation, and ERR_PTR(-ENODEV) when the CONFIG_EXTCON option is disabled. This is very complicated for the callers to handle and a number of them had bugs that would lead to an Oops.
In real life, there are two things which prevented crashes. First, error pointers would only be returned if there was bug in the caller where they passed a NULL "extcon_name" and none of them do that. Second, only two out of the eight drivers will build when CONFIG_EXTCON is disabled.
The normal way to write this would be to return -EPROBE_DEFER directly when appropriate and return NULL when CONFIG_EXTCON is disabled. Then the error handling is simple and just looks like:
dev->edev = extcon_get_extcon_dev(acpi_dev_name(adev)); if (IS_ERR(dev->edev)) return PTR_ERR(dev->edev);
For the two drivers which can build with CONFIG_EXTCON disabled, then extcon_get_extcon_dev() will now return NULL which is not treated as an error and the probe will continue successfully. Those two drivers are "typec_fusb302" and "max8997-battery". In the original code, the typec_fusb302 driver had an 800ms hang in tcpm_get_current_limit() but now that function is a no-op. For the max8997-battery driver everything should continue working as is.
--- drivers/extcon/extcon-axp288.c | 4 ++-- drivers/extcon/extcon.c | 4 +++- drivers/power/supply/axp288_charger.c | 17 ++++++++++------- drivers/power/supply/charger-manager.c | 7 ++----- drivers/power/supply/max8997_charger.c | 8 ++++---- drivers/usb/dwc3/drd.c | 9 ++------- drivers/usb/phy/phy-omap-otg.c | 4 ++-- drivers/usb/typec/tcpm/fusb302.c | 4 ++-- include/linux/extcon.h | 2 +- 9 files changed, 28 insertions(+), 31 deletions(-)
drivers/extcon/extcon-axp288.c +2 -2
@@ -394,8 +394,8 @@ static int axp288_extcon_probe(struct platform_device *pdev)if (adev) { info->id_extcon =extcon_get_extcon_dev (acpi_dev_name (adev));put_device (&adev->dev); -if (!info->id_extcon) -return -EPROBE_DEFER ; +if (IS_ERR (info->id_extcon)) +return PTR_ERR (info->id_extcon);dev_info (dev,"controlling USB role\n" ); }else {
drivers/extcon/extcon.c +3 -1
@@ -851,6 +851,8 @@ EXPORT_SYMBOL_GPL(extcon_set_property_capability);* @extcon_name: the extcon name provided with extcon_dev_register() * * Return the pointer of extcon device if success or ERR_PTR(err) if fail. +* NOTE: This function returns -EPROBE_DEFER so it may only be called from +* probe() functions. */ struct extcon_dev *extcon_get_extcon_dev (const char *extcon_name) {
@@ -864,7 +866,7 @@ struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name)if (!strcmp (sd->name, extcon_name)) goto out; } - sd =NULL ; + sd =ERR_PTR (-EPROBE_DEFER ); out:mutex_unlock (&extcon_dev_list_lock);return sd;
drivers/power/supply/axp288_charger.c +10 -7
@@ -865,17 +865,20 @@ static int axp288_charger_probe(struct platform_device *pdev) info->regmap_irqc = axp20x->regmap_irqc; info->cable.edev =extcon_get_extcon_dev (AXP288_EXTCON_DEV_NAME ); -if (info->cable.edev ==NULL ) { -dev_dbg (dev,"%s is not ready, probe deferred\n" , -AXP288_EXTCON_DEV_NAME ); -return -EPROBE_DEFER ; +if (IS_ERR (info->cable.edev)) { +dev_err_probe (dev,PTR_ERR (info->cable.edev), +"extcon_get_extcon_dev(%s) failed\n" , +AXP288_EXTCON_DEV_NAME ); +return PTR_ERR (info->cable.edev); }if (acpi_dev_present (USB_HOST_EXTCON_HID ,NULL ,-1 )) { info->otg.cable =extcon_get_extcon_dev (USB_HOST_EXTCON_NAME ); -if (info->otg.cable ==NULL ) { -dev_dbg (dev,"EXTCON_USB_HOST is not ready, probe deferred\n" ); -return -EPROBE_DEFER ; +if (IS_ERR (info->otg.cable)) { +dev_err_probe (dev,PTR_ERR (info->otg.cable), +"extcon_get_extcon_dev(%s) failed\n" , +USB_HOST_EXTCON_NAME ); +return PTR_ERR (info->otg.cable); }dev_info (dev,"Using " USB_HOST_EXTCON_HID " extcon for usb-id\n" ); }
drivers/power/supply/charger-manager.c +2 -5
@@ -985,13 +985,10 @@ static int charger_extcon_init(struct charger_manager *cm, cable->nb.notifier_call = charger_extcon_notifier; cable->extcon_dev =extcon_get_extcon_dev (cable->extcon_name); -if (IS_ERR_OR_NULL (cable->extcon_dev)) { +if (IS_ERR (cable->extcon_dev)) {pr_err ("Cannot find extcon_dev for %s (cable: %s)\n" , cable->extcon_name, cable->name); -if (cable->extcon_dev ==NULL ) -return -EPROBE_DEFER ; -else -return PTR_ERR (cable->extcon_dev); +return PTR_ERR (cable->extcon_dev); }for (i =0 ; i <ARRAY_SIZE (extcon_mapping); i++) {
drivers/power/supply/max8997_charger.c +4 -4
@@ -242,10 +242,10 @@ static int max8997_battery_probe(struct platform_device *pdev)dev_info (&pdev->dev,"couldn't get charger regulator\n" ); } charger->edev =extcon_get_extcon_dev ("max8997-muic" ); -if (IS_ERR_OR_NULL (charger->edev)) { -if (!charger->edev) -return -EPROBE_DEFER ; -dev_info (charger->dev,"couldn't get extcon device\n" ); +if (IS_ERR (charger->edev)) { +dev_err_probe (charger->dev,PTR_ERR (charger->edev), +"couldn't get extcon device: max8997-muic\n" ); +return PTR_ERR (charger->edev); }if (!IS_ERR (charger->reg) && !IS_ERR_OR_NULL (charger->edev)) {
drivers/usb/dwc3/drd.c +2 -7
@@ -455,13 +455,8 @@ static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)* This device property is for kernel internal use only and * is expected to be set by the glue code. */ -if (device_property_read_string (dev,"linux,extcon-name" , &name) ==0 ) { - edev =extcon_get_extcon_dev (name); -if (!edev) -return ERR_PTR (-EPROBE_DEFER ); - -return edev; - } +if (device_property_read_string (dev,"linux,extcon-name" , &name) ==0 ) +return extcon_get_extcon_dev (name);/* * Try to get an extcon device from the USB PHY controller's "port"
drivers/usb/phy/phy-omap-otg.c +2 -2
@@ -95,8 +95,8 @@ static int omap_otg_probe(struct platform_device *pdev)return -ENODEV ; extcon =extcon_get_extcon_dev (config->extcon); -if (!extcon) -return -EPROBE_DEFER ; +if (IS_ERR (extcon)) +return PTR_ERR (extcon); otg_dev =devm_kzalloc (&pdev->dev,sizeof (*otg_dev),GFP_KERNEL );if (!otg_dev)
drivers/usb/typec/tcpm/fusb302.c +2 -2
@@ -1708,8 +1708,8 @@ static int fusb302_probe(struct i2c_client *client,*/ if (device_property_read_string (dev,"linux,extcon-name" , &name) ==0 ) { chip->extcon =extcon_get_extcon_dev (name); -if (!chip->extcon) -return -EPROBE_DEFER ; +if (IS_ERR (chip->extcon)) +return PTR_ERR (chip->extcon); } chip->vbus =devm_regulator_get (chip->dev,"vbus" );
include/linux/extcon.h +1 -1
@@ -296,7 +296,7 @@ static inline void devm_extcon_unregister_notifier_all(struct device *dev,static inline struct extcon_dev *extcon_get_extcon_dev (const char *extcon_name) { -return ERR_PTR (-ENODEV ); +return NULL ; }static inline struct extcon_dev *extcon_find_edev_by_node (struct device_node *node)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 247/339 extcon: Modify extcon device to be created after driver data is set
In reply to Greg Kroah-HartmanFrom: bumwoo lee <[email protected]>
[ Upstream commit 5dcc2afe716d69f5112ce035cb14f007461ff189 ]
Currently, someone can invoke the sysfs such as state_show() intermittently before dev_set_drvdata() is done.
And it can be a cause of kernel Oops because of edev is Null at that time. So modified the driver registration to after setting drviver data.
- Oops's backtrace.
Backtrace:
[<c067865c>] (state_show) from [<c05222e8>] (dev_attr_show) [<c05222c0>] (dev_attr_show) from [<c02c66e0>] (sysfs_kf_seq_show) [<c02c6648>] (sysfs_kf_seq_show) from [<c02c496c>] (kernfs_seq_show) [<c02c4938>] (kernfs_seq_show) from [<c025e2a0>] (seq_read) [<c025e11c>] (seq_read) from [<c02c50a0>] (kernfs_fop_read) [<c02c5064>] (kernfs_fop_read) from [<c0231cac>] (__vfs_read) [<c0231c5c>] (__vfs_read) from [<c0231ee0>] (vfs_read) [<c0231e34>] (vfs_read) from [<c0232464>] (ksys_read) [<c02323f0>] (ksys_read) from [<c02324fc>] (sys_read) [<c02324e4>] (sys_read) from [<c00091d0>] (__sys_trace_return)
--- drivers/extcon/extcon.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-)
drivers/extcon/extcon.c +17 -12
@@ -1220,19 +1220,14 @@ int extcon_dev_register(struct extcon_dev *edev) edev->dev.type = &edev->extcon_dev_type; } - ret =device_register (&edev->dev); -if (ret) { -put_device (&edev->dev); - goto err_dev; - } -spin_lock_init (&edev->lock); - edev->nh =devm_kcalloc (&edev->dev, edev->max_supported, -sizeof (*edev->nh),GFP_KERNEL ); -if (!edev->nh) { - ret = -ENOMEM ; -device_unregister (&edev->dev); - goto err_dev; +if (edev->max_supported) { + edev->nh =kcalloc (edev->max_supported,sizeof (*edev->nh), +GFP_KERNEL ); +if (!edev->nh) { + ret = -ENOMEM ; + goto err_alloc_nh; + } }for (index =0 ; index < edev->max_supported; index++)
@@ -1243,6 +1238,12 @@ int extcon_dev_register(struct extcon_dev *edev)dev_set_drvdata (&edev->dev, edev); edev->state =0 ; + ret =device_register (&edev->dev); +if (ret) { +put_device (&edev->dev); + goto err_dev; + } +mutex_lock (&extcon_dev_list_lock);list_add (&edev->entry, &extcon_dev_list);mutex_unlock (&extcon_dev_list_lock);
@@ -1250,6 +1251,9 @@ int extcon_dev_register(struct extcon_dev *edev)return 0 ; err_dev: +if (edev->max_supported) +kfree (edev->nh); +err_alloc_nh:if (edev->max_supported)kfree (edev->extcon_dev_type.groups); err_alloc_groups:
@@ -1310,6 +1314,7 @@ void extcon_dev_unregister(struct extcon_dev *edev)if (edev->max_supported) {kfree (edev->extcon_dev_type.groups);kfree (edev->cables); +kfree (edev->nh); }put_device (&edev->dev);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 248/339 clocksource/drivers/sp804: Avoid error on multiple instances
In reply to Greg Kroah-HartmanFrom: Andre Przywara <[email protected]>
[ Upstream commit a98399cbc1e05f7b977419f03905501d566cf54e ]
When a machine sports more than one SP804 timer instance, we only bring up the first one, since multiple timers of the same kind are not useful to Linux. As this is intentional behaviour, we should not return an error message, as we do today:
===============
[ 0.000800] Failed to initialize '/bus@8000000/motherboard-bus@8000000/iofpga-bus@300000000/timer@120000': -22
===============
Replace the -EINVAL return with a debug message and return 0 instead.
Also we do not reach the init function anymore if the DT node is disabled (as this is now handled by OF_DECLARE), so remove the explicit check for that case.
This fixes a long standing bogus error when booting ARM's fastmodels.
--- drivers/clocksource/timer-sp804.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/clocksource/timer-sp804.c +5 -5
@@ -259,6 +259,11 @@ static int __init sp804_of_init(struct device_node *np, struct sp804_timer *timestruct clk *clk1, *clk2;const char *name =of_get_property (np,"compatible" ,NULL ); +if (initialized) { +pr_debug ("%pOF: skipping further SP804 timer device\n" , np); +return 0 ; + } + base =of_iomap (np,0 );if (!base)return -ENXIO ;
@@ -270,11 +275,6 @@ static int __init sp804_of_init(struct device_node *np, struct sp804_timer *timewritel (0 , timer1_base + timer->ctrl);writel (0 , timer2_base + timer->ctrl); -if (initialized || !of_device_is_available (np)) { - ret = -EINVAL ; - goto err; - } - clk1 =of_clk_get (np,0 );if (IS_ERR (clk1)) clk1 =NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 249/339 staging: rtl8712: fix uninit-value in usb_read8() and friends
In reply to Greg Kroah-HartmanFrom: Wang Cheng <[email protected]>
[ Upstream commit d1b57669732d09da7e13ef86d058dab0cd57f6e0 ]
When r8712_usbctrl_vendorreq() returns negative, 'data' in usb_read{8,16,32} will not be initialized.
BUG: KMSAN: uninit-value in string_nocheck lib/vsprintf.c:643 [inline] BUG: KMSAN: uninit-value in string+0x4ec/0x6f0 lib/vsprintf.c:725 string_nocheck lib/vsprintf.c:643 [inline] string+0x4ec/0x6f0 lib/vsprintf.c:725 vsnprintf+0x2222/0x3650 lib/vsprintf.c:2806 va_format lib/vsprintf.c:1704 [inline] pointer+0x18e6/0x1f70 lib/vsprintf.c:2443 vsnprintf+0x1a9b/0x3650 lib/vsprintf.c:2810 vprintk_store+0x537/0x2150 kernel/printk/printk.c:2158 vprintk_emit+0x28b/0xab0 kernel/printk/printk.c:2256 dev_vprintk_emit+0x5ef/0x6d0 drivers/base/core.c:4604 dev_printk_emit+0x1dd/0x21f drivers/base/core.c:4615 __dev_printk+0x3be/0x440 drivers/base/core.c:4627 _dev_info+0x1ea/0x22f drivers/base/core.c:4673 r871xu_drv_init+0x1929/0x3070 drivers/staging/rtl8712/usb_intf.c:401 usb_probe_interface+0xf19/0x1600 drivers/usb/core/driver.c:396 really_probe+0x6c7/0x1350 drivers/base/dd.c:621 __driver_probe_device+0x3e9/0x530 drivers/base/dd.c:752 driver_probe_device drivers/base/dd.c:782 [inline] __device_attach_driver+0x79f/0x1120 drivers/base/dd.c:899 bus_for_each_drv+0x2d6/0x3f0 drivers/base/bus.c:427 __device_attach+0x593/0x8e0 drivers/base/dd.c:970 device_initial_probe+0x4a/0x60 drivers/base/dd.c:1017 bus_probe_device+0x17b/0x3e0 drivers/base/bus.c:487 device_add+0x1fff/0x26e0 drivers/base/core.c:3405 usb_set_configuration+0x37e9/0x3ed0 drivers/usb/core/message.c:2170 usb_generic_driver_probe+0x13c/0x300 drivers/usb/core/generic.c:238 usb_probe_device+0x309/0x570 drivers/usb/core/driver.c:293 really_probe+0x6c7/0x1350 drivers/base/dd.c:621 __driver_probe_device+0x3e9/0x530 drivers/base/dd.c:752 driver_probe_device drivers/base/dd.c:782 [inline] __device_attach_driver+0x79f/0x1120 drivers/base/dd.c:899 bus_for_each_drv+0x2d6/0x3f0 drivers/base/bus.c:427 __device_attach+0x593/0x8e0 drivers/base/dd.c:970 device_initial_probe+0x4a/0x60 drivers/base/dd.c:1017 bus_probe_device+0x17b/0x3e0 drivers/base/bus.c:487 device_add+0x1fff/0x26e0 drivers/base/core.c:3405 usb_new_device+0x1b91/0x2950 drivers/usb/core/hub.c:2566 hub_port_connect drivers/usb/core/hub.c:5363 [inline] hub_port_connect_change drivers/usb/core/hub.c:5507 [inline] port_event drivers/usb/core/hub.c:5665 [inline] hub_event+0x58e3/0x89e0 drivers/usb/core/hub.c:5747 process_one_work+0xdb6/0x1820 kernel/workqueue.c:2289 worker_thread+0x10d0/0x2240 kernel/workqueue.c:2436 kthread+0x3c7/0x500 kernel/kthread.c:376 ret_from_fork+0x1f/0x30
Local variable data created at:
usb_read8+0x5d/0x130 drivers/staging/rtl8712/usb_ops.c:33 r8712_read8+0xa5/0xd0 drivers/staging/rtl8712/rtl8712_io.c:29
KMSAN: uninit-value in r871xu_drv_init
https://syzkaller.appspot.com/bug?id=3cd92b1d85428b128503bfa7a250294c9ae00bd8
--- drivers/staging/rtl8712/usb_ops.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-)
drivers/staging/rtl8712/usb_ops.c +18 -9
@@ -29,7 +29,8 @@ static u8 usb_read8(struct intf_hdl *intfhdl, u32 addr)u16 wvalue;u16 index;u16 len; -__le32 data; +int status; +__le32 data =0 ;struct intf_priv *intfpriv = intfhdl->pintfpriv; request =0x05 ;
@@ -37,8 +38,10 @@ static u8 usb_read8(struct intf_hdl *intfhdl, u32 addr) index =0 ; wvalue = (u16)(addr &0x0000ffff ); len =1 ; -r8712_usbctrl_vendorreq (intfpriv, request, wvalue, index, &data, len, - requesttype); + status =r8712_usbctrl_vendorreq (intfpriv, request, wvalue, index, + &data, len, requesttype); +if (status <0 ) +return 0 ;return (u8)(le32_to_cpu (data) &0x0ff ); }
@@ -49,7 +52,8 @@ static u16 usb_read16(struct intf_hdl *intfhdl, u32 addr)u16 wvalue;u16 index;u16 len; -__le32 data; +int status; +__le32 data =0 ;struct intf_priv *intfpriv = intfhdl->pintfpriv; request =0x05 ;
@@ -57,8 +61,10 @@ static u16 usb_read16(struct intf_hdl *intfhdl, u32 addr) index =0 ; wvalue = (u16)(addr &0x0000ffff ); len =2 ; -r8712_usbctrl_vendorreq (intfpriv, request, wvalue, index, &data, len, - requesttype); + status =r8712_usbctrl_vendorreq (intfpriv, request, wvalue, index, + &data, len, requesttype); +if (status <0 ) +return 0 ;return (u16)(le32_to_cpu (data) &0xffff ); }
@@ -69,7 +75,8 @@ static u32 usb_read32(struct intf_hdl *intfhdl, u32 addr)u16 wvalue;u16 index;u16 len; -__le32 data; +int status; +__le32 data =0 ;struct intf_priv *intfpriv = intfhdl->pintfpriv; request =0x05 ;
@@ -77,8 +84,10 @@ static u32 usb_read32(struct intf_hdl *intfhdl, u32 addr) index =0 ; wvalue = (u16)(addr &0x0000ffff ); len =4 ; -r8712_usbctrl_vendorreq (intfpriv, request, wvalue, index, &data, len, - requesttype); + status =r8712_usbctrl_vendorreq (intfpriv, request, wvalue, index, + &data, len, requesttype); +if (status <0 ) +return 0 ;return le32_to_cpu (data); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 250/339 staging: rtl8712: fix uninit-value in r871xu_drv_init()
In reply to Greg Kroah-HartmanFrom: Wang Cheng <[email protected]>
[ Upstream commit 0458e5428e5e959d201a40ffe71d762a79ecedc4 ]
When 'tmpU1b' returns from r8712_read8(padapter, EE_9346CR) is 0, 'mac[6]' will not be initialized.
BUG: KMSAN: uninit-value in r871xu_drv_init+0x2d54/0x3070 drivers/staging/rtl8712/usb_intf.c:541 r871xu_drv_init+0x2d54/0x3070 drivers/staging/rtl8712/usb_intf.c:541 usb_probe_interface+0xf19/0x1600 drivers/usb/core/driver.c:396 really_probe+0x653/0x14b0 drivers/base/dd.c:596 __driver_probe_device+0x3e9/0x530 drivers/base/dd.c:752 driver_probe_device drivers/base/dd.c:782 [inline] __device_attach_driver+0x79f/0x1120 drivers/base/dd.c:899 bus_for_each_drv+0x2d6/0x3f0 drivers/base/bus.c:427 __device_attach+0x593/0x8e0 drivers/base/dd.c:970 device_initial_probe+0x4a/0x60 drivers/base/dd.c:1017 bus_probe_device+0x17b/0x3e0 drivers/base/bus.c:487 device_add+0x1fff/0x26e0 drivers/base/core.c:3405 usb_set_configuration+0x37e9/0x3ed0 drivers/usb/core/message.c:2170 usb_generic_driver_probe+0x13c/0x300 drivers/usb/core/generic.c:238 usb_probe_device+0x309/0x570 drivers/usb/core/driver.c:293 really_probe+0x653/0x14b0 drivers/base/dd.c:596 __driver_probe_device+0x3e9/0x530 drivers/base/dd.c:752 driver_probe_device drivers/base/dd.c:782 [inline] __device_attach_driver+0x79f/0x1120 drivers/base/dd.c:899 bus_for_each_drv+0x2d6/0x3f0 drivers/base/bus.c:427 __device_attach+0x593/0x8e0 drivers/base/dd.c:970 device_initial_probe+0x4a/0x60 drivers/base/dd.c:1017 bus_probe_device+0x17b/0x3e0 drivers/base/bus.c:487 device_add+0x1fff/0x26e0 drivers/base/core.c:3405 usb_new_device+0x1b8e/0x2950 drivers/usb/core/hub.c:2566 hub_port_connect drivers/usb/core/hub.c:5358 [inline] hub_port_connect_change drivers/usb/core/hub.c:5502 [inline] port_event drivers/usb/core/hub.c:5660 [inline] hub_event+0x58e3/0x89e0 drivers/usb/core/hub.c:5742 process_one_work+0xdb6/0x1820 kernel/workqueue.c:2307 worker_thread+0x10b3/0x21e0 kernel/workqueue.c:2454 kthread+0x3c7/0x500 kernel/kthread.c:377 ret_from_fork+0x1f/0x30
Local variable mac created at:
r871xu_drv_init+0x1771/0x3070 drivers/staging/rtl8712/usb_intf.c:394 usb_probe_interface+0xf19/0x1600 drivers/usb/core/driver.c:396
KMSAN: uninit-value in r871xu_drv_init
https://syzkaller.appspot.com/bug?id=3cd92b1d85428b128503bfa7a250294c9ae00bd8
--- drivers/staging/rtl8712/usb_intf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/staging/rtl8712/usb_intf.c +3 -3
@@ -536,13 +536,13 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf, }else { AutoloadFail = false; } -if (((mac[0 ] ==0xff ) && (mac[1 ] ==0xff ) && +if ((!AutoloadFail) || + ((mac[0 ] ==0xff ) && (mac[1 ] ==0xff ) && (mac[2 ] ==0xff ) && (mac[3 ] ==0xff ) && (mac[4 ] ==0xff ) && (mac[5 ] ==0xff )) || ((mac[0 ] ==0x00 ) && (mac[1 ] ==0x00 ) && (mac[2 ] ==0x00 ) && (mac[3 ] ==0x00 ) && - (mac[4 ] ==0x00 ) && (mac[5 ] ==0x00 )) || - (!AutoloadFail)) { + (mac[4 ] ==0x00 ) && (mac[5 ] ==0x00 ))) { mac[0 ] =0x00 ; mac[1 ] =0xe0 ; mac[2 ] =0x4c ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 251/339 serial: msm_serial: disable interrupts in __msm_console_write()
In reply to Greg Kroah-HartmanFrom: John Ogness <[email protected]>
[ Upstream commit aabdbb1b7a5819e18c403334a31fb0cc2c06ad41 ]
__msm_console_write() assumes that interrupts are disabled, but with threaded console printers it is possible that the write() callback of the console is called with interrupts enabled.
Explicitly disable interrupts using local_irq_save() to preserve the assumed context.
--- drivers/tty/serial/msm_serial.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/tty/serial/msm_serial.c +5 -0
@@ -1599,6 +1599,7 @@ static inline struct uart_port *msm_get_port_from_line(unsigned int line)static void __msm_console_write (struct uart_port *port,const char *s,unsigned int count,bool is_uartdm) { +unsigned long flags;int i;int num_newlines =0 ;bool replaced = false;
@@ -1616,6 +1617,8 @@ static void __msm_console_write(struct uart_port *port, const char *s, num_newlines++; count += num_newlines; +local_irq_save (flags); +if (port->sysrq) locked =0 ;else if (oops_in_progress)
@@ -1661,6 +1664,8 @@ static void __msm_console_write(struct uart_port *port, const char *s,if (locked)spin_unlock (&port->lock); + +local_irq_restore (flags); } static void msm_console_write(struct console *co, const char *s,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 252/339 kernfs: Separate kernfs_pr_cont_buf and rename_lock.
In reply to Greg Kroah-HartmanFrom: Hao Luo <[email protected]>
[ Upstream commit 1a702dc88e150487c9c173a249b3d236498b9183 ]
Previously the protection of kernfs_pr_cont_buf was piggy backed by rename_lock, which means that pr_cont() needs to be protected under rename_lock. This can cause potential circular lock dependencies.
If there is an OOM, we have the following call hierarchy:
-> cpuset_print_current_mems_allowed()
-> pr_cont_cgroup_name()
-> pr_cont_kernfs_name()
pr_cont_kernfs_name() will grab rename_lock and call printk. So we have the following lock dependencies:
kernfs_rename_lock -> console_sem
Sometimes, printk does a wakeup before releasing console_sem, which has the dependence chain:
console_sem -> p->pi_lock -> rq->lock
Now, imagine one wants to read cgroup_name under rq->lock, for example, printing cgroup_name in a tracepoint in the scheduler code. They will be holding rq->lock and take rename_lock:
rq->lock -> kernfs_rename_lock
Now they will deadlock.
A prevention to this circular lock dependency is to separate the protection of pr_cont_buf from rename_lock. In principle, rename_lock is to protect the integrity of cgroup name when copying to buf. Once pr_cont_buf has got its content, rename_lock can be dropped. So it's safe to drop rename_lock after kernfs_name_locked (and kernfs_path_from_node_locked) and rely on a dedicated pr_cont_lock to protect pr_cont_buf.
--- fs/kernfs/dir.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-)
fs/kernfs/dir.c +19 -12
@@ -18,7 +18,15 @@#include "kernfs-internal.h" static DEFINE_SPINLOCK (kernfs_rename_lock);/* kn->parent and ->name */ -static char kernfs_pr_cont_buf[PATH_MAX ];/* protected by rename_lock */ +/* +* Don't use rename_lock to piggy back on pr_cont_buf. We don't want to +* call pr_cont() while holding rename_lock. Because sometimes pr_cont() +* will perform wakeups when releasing console_sem. Holding rename_lock +* will introduce deadlock if the scheduler reads the kernfs_name in the +* wakeup path. +*/ +static DEFINE_SPINLOCK (kernfs_pr_cont_lock); +static char kernfs_pr_cont_buf[PATH_MAX ];/* protected by pr_cont_lock */ static DEFINE_SPINLOCK (kernfs_idr_lock);/* root->ino_idr */ #define rb_to_kn (X ) rb_entry((X), struct kernfs_node, rb)
@@ -229,12 +237,12 @@ void pr_cont_kernfs_name(struct kernfs_node *kn) {unsigned long flags; -spin_lock_irqsave (&kernfs_rename_lock, flags); +spin_lock_irqsave (&kernfs_pr_cont_lock, flags); -kernfs_name_locked (kn, kernfs_pr_cont_buf,sizeof (kernfs_pr_cont_buf)); +kernfs_name (kn, kernfs_pr_cont_buf,sizeof (kernfs_pr_cont_buf));pr_cont ("%s" , kernfs_pr_cont_buf); -spin_unlock_irqrestore (&kernfs_rename_lock, flags); +spin_unlock_irqrestore (&kernfs_pr_cont_lock, flags); }/**
@@ -248,10 +256,10 @@ void pr_cont_kernfs_path(struct kernfs_node *kn)unsigned long flags;int sz; -spin_lock_irqsave (&kernfs_rename_lock, flags); +spin_lock_irqsave (&kernfs_pr_cont_lock, flags); - sz =kernfs_path_from_node_locked (kn,NULL , kernfs_pr_cont_buf, -sizeof (kernfs_pr_cont_buf)); + sz =kernfs_path_from_node (kn,NULL , kernfs_pr_cont_buf, +sizeof (kernfs_pr_cont_buf));if (sz <0 ) {pr_cont ("(error)" ); goto out;
@@ -265,7 +273,7 @@ void pr_cont_kernfs_path(struct kernfs_node *kn)pr_cont ("%s" , kernfs_pr_cont_buf); out: -spin_unlock_irqrestore (&kernfs_rename_lock, flags); +spin_unlock_irqrestore (&kernfs_pr_cont_lock, flags); }/**
@@ -823,13 +831,12 @@ static struct kernfs_node *kernfs_walk_ns(struct kernfs_node *parent,lockdep_assert_held_read (&kernfs_root (parent)->kernfs_rwsem); -/* grab kernfs_rename_lock to piggy back on kernfs_pr_cont_buf */ -spin_lock_irq (&kernfs_rename_lock); +spin_lock_irq (&kernfs_pr_cont_lock); len =strlcpy (kernfs_pr_cont_buf, path,sizeof (kernfs_pr_cont_buf));if (len >=sizeof (kernfs_pr_cont_buf)) { -spin_unlock_irq (&kernfs_rename_lock); +spin_unlock_irq (&kernfs_pr_cont_lock);return NULL ; }
@@ -841,7 +848,7 @@ static struct kernfs_node *kernfs_walk_ns(struct kernfs_node *parent, parent =kernfs_find_ns (parent, name, ns); } -spin_unlock_irq (&kernfs_rename_lock); +spin_unlock_irq (&kernfs_pr_cont_lock);return parent; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 253/339 watchdog: wdat_wdt: Stop watchdog when rebooting the system
In reply to Greg Kroah-HartmanFrom: Liu Xinpeng <[email protected]>
[ Upstream commit 27fdf84510a1374748904db43f6755f912736d92 ]
Executing reboot command several times on the machine "Dell PowerEdge R740", UEFI security detection stopped machine with the following prompt:
UEFI0082: The system was reset due to a timeout from the watchdog timer. Check the System Event Log (SEL) or crash dumps from Operating Sysstem to identify the source that triggered the watchdog timer reset. Update the firmware or driver for the identified device.
iDRAC has warning event: "The watchdog timer reset the system".
This patch fixes this issue by adding the reboot notifier.
--- drivers/watchdog/wdat_wdt.c | 1 + 1 file changed, 1 insertion(+)
drivers/watchdog/wdat_wdt.c +1 -0
@@ -462,6 +462,7 @@ static int wdat_wdt_probe(struct platform_device *pdev)return ret;watchdog_set_nowayout (&wdat->wdd, nowayout); +watchdog_stop_on_reboot (&wdat->wdd);return devm_watchdog_register_device (dev, &wdat->wdd); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 254/339 ksmbd: smbd: fix connection dropped issue
In reply to Greg Kroah-HartmanFrom: Hyunchul Lee <[email protected]>
[ Upstream commit 5366afc4065075a4456941fbd51c33604d631ee5 ]
When there are bursty connection requests, RDMA connection event handler is deferred and Negotiation requests are received even if connection status is NEW.
To handle it, set the status to CONNECTED
if Negotiation requests are received.
--- fs/ksmbd/transport_rdma.c | 1 + 1 file changed, 1 insertion(+)
fs/ksmbd/transport_rdma.c +1 -0
@@ -569,6 +569,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) } t->negotiation_requested = true; t->full_packet_received = true; + t->status =SMB_DIRECT_CS_CONNECTED ;enqueue_reassembly (t, recvmsg,0 );wake_up_interruptible (&t->wait_status);break ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 255/339 md: protect md_unregister_thread from reentrancy
In reply to Greg Kroah-HartmanFrom: Guoqing Jiang <[email protected]>
[ Upstream commit 1e267742283a4b5a8ca65755c44166be27e9aa0f ]
Generally, the md_unregister_thread is called with reconfig_mutex, but raid_message in dm-raid doesn't hold reconfig_mutex to unregister thread, so md_unregister_thread can be called simulitaneously from two call sites in theory.
Then after previous commit which remove the protection of reconfig_mutex for md_unregister_thread completely, the potential issue could be worse than before.
Let's take pers_lock at the beginning of function to ensure reentrancy.
--- drivers/md/md.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/md/md.c +10 -5
@@ -7960,17 +7960,22 @@ EXPORT_SYMBOL(md_register_thread);void md_unregister_thread (struct md_thread **threadp) { -struct md_thread *thread = *threadp; -if (!thread) -return ; -pr_debug ("interrupting MD-thread pid %d\n" ,task_pid_nr (thread->tsk)); -/* Locking ensures that mddev_unlock does not wake_up a +struct md_thread *thread; + +/* +* Locking ensures that mddev_unlock does not wake_up a * non-existent thread */ spin_lock (&pers_lock); + thread = *threadp; +if (!thread) { +spin_unlock (&pers_lock); +return ; + } *threadp =NULL ;spin_unlock (&pers_lock); +pr_debug ("interrupting MD-thread pid %d\n" ,task_pid_nr (thread->tsk));kthread_stop (thread->tsk);kfree (thread); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 256/339 ASoC: SOF: amd: Fixed Build error
In reply to Greg Kroah-HartmanFrom: Syed Saba kareem <[email protected]>
[ Upstream commit 803a1f7272797faa15a7879cdc70f9adaf3fdcba ]
Add linux/module.h in acp-pci.c to solve the below dependency
All error/warnings (new ones prefixed by >>):
Quoted 1 line
Quoted 1 line
sound/soc/amd/acp/acp-pci.c:148:1: warning: data definition has no type or storage class
148 | MODULE_DEVICE_TABLE(pci, acp_pci_ids);
| ^~~~~~~~~~~~~~~~~~~
Quoted 1 line
Quoted 1 line
sound/soc/amd/acp/acp-pci.c:148:1: error: type defaults to 'int' in declaration of 'MODULE_DEVICE_TABLE' [-Werror=implicit-int]
...
--- sound/soc/amd/acp/acp-pci.c | 1 + 1 file changed, 1 insertion(+)
sound/soc/amd/acp/acp-pci.c +1 -0
@@ -16,6 +16,7 @@#include <linux/pci.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/module.h> #include "amd.h" #include "../mach-config.h"
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 257/339 scsi: myrb: Fix up null pointer access on myrb_cleanup()
In reply to Greg Kroah-HartmanFrom: Hannes Reinecke <[email protected]>
[ Upstream commit f9f0a46141e2e39bedb4779c88380d1b5f018c14 ]
When myrb_probe() fails the callback might not be set, so we need to validate the 'disable_intr' callback in myrb_cleanup() to not cause a null pointer exception. And while at it do not call myrb_cleanup() if we cannot enable the PCI device at all.
--- drivers/scsi/myrb.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/scsi/myrb.c +8 -3
@@ -1239,7 +1239,8 @@ static void myrb_cleanup(struct myrb_hba *cb)myrb_unmap (cb);if (cb->mmio_base) { - cb->disable_intr (cb->io_base); +if (cb->disable_intr) + cb->disable_intr (cb->io_base);iounmap (cb->mmio_base); }if (cb->irq)
@@ -3413,9 +3414,13 @@ static struct myrb_hba *myrb_detect(struct pci_dev *pdev,mutex_init (&cb->dcmd_mutex);mutex_init (&cb->dma_mutex); cb->pdev = pdev; + cb->host = shost; -if (pci_enable_device (pdev)) - goto failure; +if (pci_enable_device (pdev)) { +dev_err (&pdev->dev,"Failed to enable PCI device\n" ); +scsi_host_put (shost); +return NULL ; + }if (privdata->hw_init == DAC960_PD_hw_init || privdata->hw_init == DAC960_P_hw_init) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 258/339 ASoC: rt5640: Do not manipulate pin "Platform Clock" if the "Platform Clock" is not in the DAPM
In reply to Greg Kroah-HartmanFrom: Oder Chiou <[email protected]>
[ Upstream commit 832296804bc7171730884e78c761c29f6d258e13 ]
The pin "Platform Clock" was only used by the Intel Byt CR platform. In the others, the error log will be informed. The patch will set the flag to avoid the pin "Platform Clock" manipulated by the other platforms.
--- sound/soc/codecs/rt5640.c | 11 +++++++++-- sound/soc/codecs/rt5640.h | 2 ++ sound/soc/intel/boards/bytcr_rt5640.c | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-)
sound/soc/codecs/rt5640.c +9 -2
@@ -2094,12 +2094,14 @@ EXPORT_SYMBOL_GPL(rt5640_sel_asrc_clk_src);void rt5640_enable_micbias1_for_ovcd (struct snd_soc_component *component) {struct snd_soc_dapm_context *dapm =snd_soc_component_get_dapm (component); +struct rt5640_priv *rt5640 =snd_soc_component_get_drvdata (component);snd_soc_dapm_mutex_lock (dapm);snd_soc_dapm_force_enable_pin_unlocked (dapm,"LDO2" );snd_soc_dapm_force_enable_pin_unlocked (dapm,"MICBIAS1" );/* OVCD is unreliable when used with RCCLK as sysclk-source */ -snd_soc_dapm_force_enable_pin_unlocked (dapm,"Platform Clock" ); +if (rt5640->use_platform_clock) +snd_soc_dapm_force_enable_pin_unlocked (dapm,"Platform Clock" );snd_soc_dapm_sync_unlocked (dapm);snd_soc_dapm_mutex_unlock (dapm); }
@@ -2108,9 +2110,11 @@ EXPORT_SYMBOL_GPL(rt5640_enable_micbias1_for_ovcd);void rt5640_disable_micbias1_for_ovcd (struct snd_soc_component *component) {struct snd_soc_dapm_context *dapm =snd_soc_component_get_dapm (component); +struct rt5640_priv *rt5640 =snd_soc_component_get_drvdata (component);snd_soc_dapm_mutex_lock (dapm); -snd_soc_dapm_disable_pin_unlocked (dapm,"Platform Clock" ); +if (rt5640->use_platform_clock) +snd_soc_dapm_disable_pin_unlocked (dapm,"Platform Clock" );snd_soc_dapm_disable_pin_unlocked (dapm,"MICBIAS1" );snd_soc_dapm_disable_pin_unlocked (dapm,"LDO2" );snd_soc_dapm_sync_unlocked (dapm);
@@ -2535,6 +2539,9 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component, rt5640->jd_gpio_irq_requested = true; } +if (jack_data && jack_data->use_platform_clock) + rt5640->use_platform_clock = jack_data->use_platform_clock; + ret =request_irq (rt5640->irq, rt5640_irq,IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING |IRQF_ONESHOT ,"rt5640" , rt5640);
sound/soc/codecs/rt5640.h +2 -0
@@ -2155,11 +2155,13 @@ struct rt5640_priv {bool jd_inverted;unsigned int ovcd_th;unsigned int ovcd_sf; +bool use_platform_clock; };struct rt5640_set_jack_data {int codec_irq_override;struct gpio_desc *jd_gpio; +bool use_platform_clock; }; int rt5640_dmic_enable(struct snd_soc_component *component,
sound/soc/intel/boards/bytcr_rt5640.c +2 -0
@@ -1191,12 +1191,14 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) {struct snd_soc_card *card = runtime->card;struct byt_rt5640_private *priv =snd_soc_card_get_drvdata (card); +struct rt5640_set_jack_data *jack_data = &priv->jack_data;struct snd_soc_component *component =asoc_rtd_to_codec (runtime,0 )->component;const struct snd_soc_dapm_route *custom_map =NULL ;int num_routes =0 ;int ret; card->dapm.idle_bias_off = true; + jack_data->use_platform_clock = true;/* Start with RC clk for jack-detect (we disable MCLK below) */ if (byt_rt5640_quirk &BYT_RT5640_MCLK_EN )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 259/339 Revert "net: af_key: add check for pfkey_broadcast in function pfkey_process"
In reply to Greg Kroah-HartmanFrom: Michal Kubecek <[email protected]>
[ Upstream commit 9c90c9b3e50e16d03c7f87d63e9db373974781e0 ]
This reverts commit 4dc2a5a8f6754492180741facf2a8787f2c415d7.
A non-zero return value from pfkey_broadcast() does not necessarily mean an error occurred as this function returns -ESRCH when no registered listener received the message. In particular, a call with BROADCAST_PROMISC_ONLY flag and null one_sk argument can never return zero so that this commit in fact prevents processing any PF_KEY message. One visible effect is that racoon daemon fails to find encryption algorithms like aes and refuses to start.
Excluding -ESRCH return value would fix this but it's not obvious that we really want to bail out here and most other callers of pfkey_broadcast() also ignore the return value. Also, as pointed out by Steffen Klassert, PF_KEY is kind of deprecated and newer userspace code should use netlink instead so that we should only disturb the code for really important fixes.
v2: add a comment explaining why is the return value ignored
--- net/key/af_key.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
net/key/af_key.c +6 -4
@@ -2826,10 +2826,12 @@ static int pfkey_process(struct sock *sk, struct sk_buff *skb, const struct sadbvoid *ext_hdrs[SADB_EXT_MAX ];int err; - err =pfkey_broadcast (skb_clone (skb,GFP_KERNEL ),GFP_KERNEL , -BROADCAST_PROMISC_ONLY ,NULL ,sock_net (sk)); -if (err) -return err; +/* Non-zero return value of pfkey_broadcast() does not always signal +* an error and even on an actual error we may still want to process +* the message so rather ignore the return value. +*/ +pfkey_broadcast (skb_clone (skb,GFP_KERNEL ),GFP_KERNEL , +BROADCAST_PROMISC_ONLY ,NULL ,sock_net (sk));memset (ext_hdrs,0 ,sizeof (ext_hdrs)); err =parse_exthdrs (skb, hdr, ext_hdrs);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 260/339 ceph: allow ceph.dir.rctime xattr to be updatable
In reply to Greg Kroah-HartmanFrom: Venky Shankar <[email protected]>
[ Upstream commit d7a2dc523085f8b8c60548ceedc696934aefeb0e ]
`rctime' has been a pain point in cephfs due to its buggy nature - inconsistent values reported and those sorts. Fixing rctime is non-trivial needing an overall redesign of the entire nested statistics infrastructure.
As a workaround, PR
http://github.com/ceph/ceph/pull/37938
allows this extended attribute to be manually set. This allows users to "fixup" inconsistent rctime values. While this sounds messy, its probably the wisest approach allowing users/scripts to workaround buggy rctime values.
The above PR enables Ceph MDS to allow manually setting rctime extended attribute with the corresponding user-land changes. We may as well allow the same to be done via kclient for parity.
--- fs/ceph/xattr.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
fs/ceph/xattr.c +9 -1
@@ -366,6 +366,14 @@ static ssize_t ceph_vxattrcb_auth_mds(struct ceph_inode_info *ci, }#define XATTR_RSTAT_FIELD (_type, _name) \ XATTR_NAME_CEPH(_type, _name, VXATTR_FLAG_RSTAT) +#define XATTR_RSTAT_FIELD_UPDATABLE (_type, _name) \ + { \ + .name = CEPH_XATTR_NAME(_type, _name), \ + .name_size = sizeof (CEPH_XATTR_NAME(_type, _name)), \ + .getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name, \ + .exists_cb = NULL, \ + .flags = VXATTR_FLAG_RSTAT, \ + }#define XATTR_LAYOUT_FIELD (_type, _name, _field) \ { \ .name = CEPH_XATTR_NAME2(_type, _name, _field), \
@@ -404,7 +412,7 @@ static struct ceph_vxattr ceph_dir_vxattrs[] = {XATTR_RSTAT_FIELD (dir, rsubdirs),XATTR_RSTAT_FIELD (dir, rsnaps),XATTR_RSTAT_FIELD (dir, rbytes), - XATTR_RSTAT_FIELD(dir, rctime), + XATTR_RSTAT_FIELD_UPDATABLE(dir, rctime), { .name ="ceph.dir.pin" , .name_size = sizeof("ceph.dir.pin"),
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 261/339 ceph: flush the mdlog for filesystem sync
In reply to Greg Kroah-HartmanFrom: Xiubo Li <[email protected]>
[ Upstream commit 1b2ba3c5616e17ff951359e25c658a1c3f146f1e ]
Before waiting for a request's safe reply, we will send the mdlog flush request to the relevant MDS. And this will also flush the mdlog for all the other unsafe requests in the same session, so we can record the last session and no need to flush mdlog again in the next loop. But there still have cases that it may send the mdlog flush requst twice or more, but that should be not often.
Rename wait_unsafe_requests() to flush_mdlog_and_wait_mdsc_unsafe_requests() to make it more descriptive.
[xiubli: fold in MDS request refcount leak fix from Jeff]
URL: https://tracker.ceph.com/issues/55284
URL: https://tracker.ceph.com/issues/55411
--- fs/ceph/mds_client.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-)
fs/ceph/mds_client.c +27 -6
@@ -4700,15 +4700,17 @@ void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc) }/* -* wait for all write mds requests to flush. +* flush the mdlog and wait for all write mds requests to flush. */ -static void wait_unsafe_requests (struct ceph_mds_client *mdsc,u64 want_tid) +static void flush_mdlog_and_wait_mdsc_unsafe_requests (struct ceph_mds_client *mdsc, +u64 want_tid) {struct ceph_mds_request *req =NULL , *nextreq; +struct ceph_mds_session *last_session =NULL ;struct rb_node *n;mutex_lock (&mdsc->mutex); -dout ("wait_unsafe_requests want %lld\n" , want_tid); +dout ("%s want %lld\n" , __func__, want_tid); restart: req =__get_oldest_req (mdsc);while (req && req->r_tid <= want_tid) {
@@ -4720,14 +4722,32 @@ static void wait_unsafe_requests(struct ceph_mds_client *mdsc, u64 want_tid) nextreq =NULL ;if (req->r_op !=CEPH_MDS_OP_SETFILELOCK && (req->r_op &CEPH_MDS_OP_WRITE )) { +struct ceph_mds_session *s = req->r_session; + +if (!s) { + req = nextreq; +continue ; + } +/* write op */ ceph_mdsc_get_request (req);if (nextreq)ceph_mdsc_get_request (nextreq); + s =ceph_get_mds_session (s);mutex_unlock (&mdsc->mutex); -dout ("wait_unsafe_requests wait on %llu (want %llu)\n" , + +/* send flush mdlog request to MDS */ +if (last_session != s) { +send_flush_mdlog (s); +ceph_put_mds_session (last_session); + last_session = s; + }else { +ceph_put_mds_session (s); + } +dout ("%s wait on %llu (want %llu)\n" , __func__, req->r_tid, want_tid);wait_for_completion (&req->r_safe_completion); +mutex_lock (&mdsc->mutex);ceph_mdsc_put_request (req);if (!nextreq)
@@ -4742,7 +4762,8 @@ static void wait_unsafe_requests(struct ceph_mds_client *mdsc, u64 want_tid) req = nextreq; }mutex_unlock (&mdsc->mutex); -dout ("wait_unsafe_requests done\n" ); +ceph_put_mds_session (last_session); +dout ("%s done\n" , __func__); }void ceph_mdsc_sync (struct ceph_mds_client *mdsc)
@@ -4771,7 +4792,7 @@ void ceph_mdsc_sync(struct ceph_mds_client *mdsc)dout ("sync want tid %lld flush_seq %lld\n" , want_tid, want_flush); -wait_unsafe_requests (mdsc, want_tid); +flush_mdlog_and_wait_mdsc_unsafe_requests (mdsc, want_tid);wait_caps_flush (mdsc, want_flush); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 262/339 ceph: fix possible deadlock when holding Fwb to get inline_data
In reply to Greg Kroah-HartmanFrom: Xiubo Li <[email protected]>
[ Upstream commit 825978fd6a0defc3c29d8a38b6cea76a0938d21e ]
1, mount with wsync.
2, create a file with O_RDWR, and the request was sent to mds.0:
ceph_atomic_open()-->
ceph_mdsc_do_request(openc)
finish_open(file, dentry, ceph_open)-->
ceph_open()-->
ceph_init_file()-->
ceph_init_file_info()-->
ceph_uninline_data()-->
{
...
if (inline_version == 1 || /* initial version, no data */
inline_version == CEPH_INLINE_NONE)
goto out_unlock;
...
}The inline_version will be 1, which is the initial version for the new create file. And here the ci->i_inline_version will keep with 1, it's buggy.
3, buffer write to the file immediately:
ceph_write_iter()-->
ceph_get_caps(file, need=Fw, want=Fb, ...);
generic_perform_write()-->
a_ops->write_begin()-->
ceph_write_begin()-->
netfs_write_begin()-->
netfs_begin_read()-->
netfs_rreq_submit_slice()-->
netfs_read_from_server()-->
rreq->netfs_ops->issue_read()-->
ceph_netfs_issue_read()-->
{
...
if (ci->i_inline_version != CEPH_INLINE_NONE &&
ceph_netfs_issue_op_inline(subreq))
return;
...
}
ceph_put_cap_refs(ci, Fwb);The ceph_netfs_issue_op_inline() will send a getattr(Fsr) request to mds.1.
4, then the mds.1 will request the rd lock for CInode::filelock from the auth mds.0, the mds.0 will do the CInode::filelock state transation from excl --> sync, but it need to revoke the Fxwb caps back from the clients.
While the kernel client has aleady held the Fwb caps and waiting for the getattr(Fsr).
It's deadlock!
URL: https://tracker.ceph.com/issues/55377
--- fs/ceph/addr.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-)
fs/ceph/addr.c +19 -14
@@ -1644,7 +1644,7 @@ int ceph_uninline_data(struct file *file)struct inode *inode =file_inode (file);struct ceph_inode_info *ci =ceph_inode (inode);struct ceph_fs_client *fsc =ceph_inode_to_client (inode); -struct ceph_osd_request *req; +struct ceph_osd_request *req =NULL ;struct ceph_cap_flush *prealloc_cf;struct folio *folio =NULL ;u64 inline_version =CEPH_INLINE_NONE ;
@@ -1652,10 +1652,23 @@ int ceph_uninline_data(struct file *file)int err =0 ;u64 len; +spin_lock (&ci->i_ceph_lock); + inline_version = ci->i_inline_version; +spin_unlock (&ci->i_ceph_lock); + +dout ("uninline_data %p %llx.%llx inline_version %llu\n" , + inode,ceph_vinop (inode), inline_version); + +if (inline_version ==CEPH_INLINE_NONE ) +return 0 ; + prealloc_cf =ceph_alloc_cap_flush ();if (!prealloc_cf)return -ENOMEM ; +if (inline_version ==1 )/* initial version, no data */ + goto out_uninline; + folio =read_mapping_folio (inode->i_mapping,0 , file);if (IS_ERR (folio)) { err =PTR_ERR (folio);
@@ -1664,17 +1677,6 @@ int ceph_uninline_data(struct file *file)folio_lock (folio); -spin_lock (&ci->i_ceph_lock); - inline_version = ci->i_inline_version; -spin_unlock (&ci->i_ceph_lock); - -dout ("uninline_data %p %llx.%llx inline_version %llu\n" , - inode,ceph_vinop (inode), inline_version); - -if (inline_version ==1 ||/* initial version, no data */ - inline_version ==CEPH_INLINE_NONE ) - goto out_unlock; - len =i_size_read (inode);if (len >folio_size (folio)) len =folio_size (folio);
@@ -1739,6 +1741,7 @@ int ceph_uninline_data(struct file *file)ceph_update_write_metrics (&fsc->mdsc->metric, req->r_start_latency, req->r_end_latency, len, err); +out_uninline:if (!err) {int dirty;
@@ -1757,8 +1760,10 @@ int ceph_uninline_data(struct file *file)if (err == -ECANCELED ) err =0 ; out_unlock: -folio_unlock (folio); -folio_put (folio); +if (folio) { +folio_unlock (folio); +folio_put (folio); + } out:ceph_free_cap_flush (prealloc_cf); dout("uninline_data %p %llx.%llx inline_version %llu = %d\n",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 263/339 net, neigh: Set lower cap for neigh_managed_work rearming
In reply to Greg Kroah-HartmanFrom: Daniel Borkmann <[email protected]>
[ Upstream commit ed6cd6a17896561b9f51ab4c0d9bbb29e762b597 ]
Yuwei reported that plain reuse of DELAY_PROBE_TIME to rearm work queue in neigh_managed_work is problematic if user explicitly configures the DELAY_PROBE_TIME to 0 for a neighbor table. Such misconfig can then hog CPU to 100% processing the system work queue. Instead, set lower interval bound to HZ which is totally sufficient. Yuwei is additionally looking into making the interval separately configurable from DELAY_PROBE_TIME.
--- net/core/neighbour.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/neighbour.c +1 -1
@@ -1579,7 +1579,7 @@ static void neigh_managed_work(struct work_struct *work)list_for_each_entry (neigh, &tbl->managed_list, managed_list)neigh_event_send_probe (neigh,NULL , false);queue_delayed_work (system_power_efficient_wq, &tbl->managed_work, -NEIGH_VAR (&tbl->parms,DELAY_PROBE_TIME )); +max (NEIGH_VAR (&tbl->parms,DELAY_PROBE_TIME ),HZ ));write_unlock_bh (&tbl->lock); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 264/339 drm/amd/display: Check if modulo is 0 before dividing.
In reply to Greg Kroah-HartmanFrom: David Galiffi <[email protected]>
[ Upstream commit 49947b906a6bd9668eaf4f9cf691973c25c26955 ]
[How & Why]
If a value of 0 is read, then this will cause a divide-by-0 panic.
--- drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c +6 -3
@@ -1105,9 +1105,12 @@ static bool get_pixel_clk_frequency_100hz(* not be programmed equal to DPREFCLK */ modulo_hz =REG_READ (MODULO [inst]); - *pixel_clk_khz =div_u64 ((uint64_t )clock_hz* - clock_source->ctx->dc->clk_mgr->dprefclk_khz*10 , - modulo_hz); +if (modulo_hz) + *pixel_clk_khz =div_u64 ((uint64_t )clock_hz* + clock_source->ctx->dc->clk_mgr->dprefclk_khz*10 , + modulo_hz); +else + *pixel_clk_khz =0 ; }else {/* NOTE: There is agreement with VBIOS here that MODULO is * programmed equal to DPREFCLK, in which case PHASE will be
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 265/339 drm/amd/display: Check zero planes for OTG disable W/A on clock change
In reply to Greg Kroah-HartmanFrom: Nicholas Kazlauskas <[email protected]>
[ Upstream commit 66a197203794339b028eedfa880bff9367fce783 ]
[Why]
A display clock change hang can occur when switching between DIO and HPO enabled modes during the optimize_bandwidth in dc_commit_state_no_check call.
This happens when going from 4k120 8bpc 420 to 4k144 10bpc 444.
Display clock in the DIO case is 1200MHz, but pixel rate is 600MHz because the pixel format is 420.
Display clock in the HPO case is less (800MHz?) because of ODM combine which results in a smaller divider.
The DIO is still active in prepare but not active in the optimize which results in the hang occuring.
During this change there are no planes on the stream so it's safe to apply the workaround, but dpms_off = false and signal type is not virtual.
[How]
Check for plane_count == 0, no planes on the stream.
It's easiest to check pipe->plane_state == NULL as an equivalent check rather than trying to search for the stream status in the context associated with the stream, so let's do that.
The primary, non MPO pipe should not have a NULL plane state.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c | 3 ++- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c +2 -1
@@ -91,7 +91,8 @@ static void dcn315_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable)if (pipe->top_pipe || pipe->prev_odm_pipe)continue ; -if (pipe->stream && (pipe->stream->dpms_off ||dc_is_virtual_signal (pipe->stream->signal))) { +if (pipe->stream && (pipe->stream->dpms_off || pipe->plane_state ==NULL || +dc_is_virtual_signal (pipe->stream->signal))) {if (disable) pipe->stream_res.tg->funcs->immediate_disable_crtc (pipe->stream_res.tg);else
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c +2 -1
@@ -122,7 +122,8 @@ static void dcn316_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable)if (pipe->top_pipe || pipe->prev_odm_pipe)continue ; -if (pipe->stream && (pipe->stream->dpms_off ||dc_is_virtual_signal (pipe->stream->signal))) { +if (pipe->stream && (pipe->stream->dpms_off || pipe->plane_state ==NULL || +dc_is_virtual_signal (pipe->stream->signal))) {if (disable) pipe->stream_res.tg->funcs->immediate_disable_crtc (pipe->stream_res.tg);else
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 266/339 drm/radeon: fix a possible null pointer dereference
In reply to Greg Kroah-HartmanFrom: Gong Yuanjun <[email protected]>
[ Upstream commit a2b28708b645c5632dc93669ab06e97874c8244f ]
In radeon_fp_native_mode(), the return value of drm_mode_duplicate() is assigned to mode, which will lead to a NULL pointer dereference on failure of drm_mode_duplicate(). Add a check to avoid npd.
The failure status of drm_cvt_mode() on the other path is checked too.
--- drivers/gpu/drm/radeon/radeon_connectors.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/gpu/drm/radeon/radeon_connectors.c +4 -0
@@ -473,6 +473,8 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode native_mode->vdisplay != 0 && native_mode->clock != 0) { mode =drm_mode_duplicate (dev, native_mode); +if (!mode) +return NULL ; mode->type =DRM_MODE_TYPE_PREFERRED |DRM_MODE_TYPE_DRIVER ;drm_mode_set_name (mode);
@@ -487,6 +489,8 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode* simpler. */ mode =drm_cvt_mode (dev, native_mode->hdisplay, native_mode->vdisplay,60 , true, false, false); +if (!mode) +return NULL ; mode->type =DRM_MODE_TYPE_PREFERRED |DRM_MODE_TYPE_DRIVER ;DRM_DEBUG_KMS ("Adding cvt approximation of native panel mode %s\n" , mode->name); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 267/339 drm/amd/pm: fix a potential gpu_metrics_table memory leak
In reply to Greg Kroah-HartmanFrom: Gong Yuanjun <[email protected]>
[ Upstream commit d2f4460a3d9502513419f06cc376c7ade49d5753 ]
gpu_metrics_table is allocated in yellow_carp_init_smc_tables() but not freed in yellow_carp_fini_smc_tables().
--- drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c +3 -0
@@ -190,6 +190,9 @@ static int yellow_carp_fini_smc_tables(struct smu_context *smu)kfree (smu_table->watermarks_table); smu_table->watermarks_table =NULL ; +kfree (smu_table->gpu_metrics_table); + smu_table->gpu_metrics_table =NULL ; +return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 268/339 drm/amd/pm: Fix missing thermal throttler status
In reply to Greg Kroah-HartmanFrom: Lijo Lazar <[email protected]>
[ Upstream commit b0f4d663fce6a4232d3c20ce820f919111b1c60b ]
On aldebaran, when thermal throttling happens due to excessive GPU temperature, the reason for throttling event is missed in warning message. This patch fixes it.
--- drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +1 -0
@@ -1664,6 +1664,7 @@ static const struct throttling_logging_label {uint32_t feature_mask;const char *label; } logging_label[] = { + {(1U << THROTTLER_TEMP_GPU_BIT), "GPU"}, {(1U << THROTTLER_TEMP_MEM_BIT), "HBM"}, {(1U << THROTTLER_TEMP_VR_GFX_BIT), "VR of GFX rail"}, {(1U << THROTTLER_TEMP_VR_MEM_BIT), "VR of HBM rail"},
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 269/339 drm/amd/pm: correct the metrics version for SMU 11.0.11/12/13
In reply to Greg Kroah-HartmanFrom: Evan Quan <[email protected]>
[ Upstream commit 396beb91a9eb86cbfa404e4220cca8f3ada70777 ]
Correct the metrics version used for SMU 11.0.11/12/13. Fixes misreported GPU metrics (e.g., fan speed, etc.) depending on which version of SMU firmware is loaded.
--- .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 57 ++++++++++++++----- 1 file changed, 44 insertions(+), 13 deletions(-)
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +44 -13
@@ -586,12 +586,28 @@ static int sienna_cichlid_get_smu_metrics_data(struct smu_context *smu,uint16_t average_gfx_activity;int ret =0 ; -if ((smu->adev->ip_versions[MP1_HWIP ][0 ] ==IP_VERSION (11 ,0 ,7 )) && - (smu->smc_fw_version >=0x3A4900 )) - use_metrics_v3 = true; -else if ((smu->adev->ip_versions[MP1_HWIP ][0 ] ==IP_VERSION (11 ,0 ,7 )) && - (smu->smc_fw_version >=0x3A4300 )) - use_metrics_v2 = true; +switch (smu->adev->ip_versions[MP1_HWIP ][0 ]) { +case IP_VERSION (11 ,0 ,7 ): +if (smu->smc_fw_version >=0x3A4900 ) + use_metrics_v3 = true; +else if (smu->smc_fw_version >=0x3A4300 ) + use_metrics_v2 = true; +break ; +case IP_VERSION (11 ,0 ,11 ): +if (smu->smc_fw_version >=0x412D00 ) + use_metrics_v2 = true; +break ; +case IP_VERSION (11 ,0 ,12 ): +if (smu->smc_fw_version >=0x3B2300 ) + use_metrics_v2 = true; +break ; +case IP_VERSION (11 ,0 ,13 ): +if (smu->smc_fw_version >=0x491100 ) + use_metrics_v2 = true; +break ; +default : +break ; + } ret = smu_cmn_get_metrics_table(smu, NULL,
@@ -3701,13 +3717,28 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu,uint16_t average_gfx_activity;int ret =0 ; -if ((adev->ip_versions[MP1_HWIP ][0 ] ==IP_VERSION (11 ,0 ,7 )) && - (smu->smc_fw_version >=0x3A4900 )) - use_metrics_v3 = true; -else if ((adev->ip_versions[MP1_HWIP ][0 ] ==IP_VERSION (11 ,0 ,7 )) && - (smu->smc_fw_version >=0x3A4300 )) - use_metrics_v2 = true; - +switch (smu->adev->ip_versions[MP1_HWIP ][0 ]) { +case IP_VERSION (11 ,0 ,7 ): +if (smu->smc_fw_version >=0x3A4900 ) + use_metrics_v3 = true; +else if (smu->smc_fw_version >=0x3A4300 ) + use_metrics_v2 = true; +break ; +case IP_VERSION (11 ,0 ,11 ): +if (smu->smc_fw_version >=0x412D00 ) + use_metrics_v2 = true; +break ; +case IP_VERSION (11 ,0 ,12 ): +if (smu->smc_fw_version >=0x3B2300 ) + use_metrics_v2 = true; +break ; +case IP_VERSION (11 ,0 ,13 ): +if (smu->smc_fw_version >=0x491100 ) + use_metrics_v2 = true; +break ; +default : +break ; + } ret = smu_cmn_get_metrics_table(smu, &metrics_external,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 270/339 um: line: Use separate IRQs per line
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
[ Upstream commit d5a9597d6916a76663085db984cb8fe97f0a5c56 ]
Today, all possible serial lines (ssl*=) as well as all possible consoles (con*=) each share a single interrupt (with a fixed number) with others of the same type.
Now, if you have two lines, say ssl0 and ssl1, and one of them is connected to an fd you cannot read (e.g. a file), but the other gets a read interrupt, then both of them get the interrupt since it's shared. Then, the read() call will return EOF, since it's a file being written and there's nothing to read (at least not at the current offset, at the end).
Unfortunately, this is treated as a read error, and we close this line, losing all the possible output.
It might be possible to work around this and make the IRQ sharing work, however, now that we have dynamically allocated IRQs that are easy to use, simply use that to achieve separating between the events; then there's no interrupt for that line and we never attempt the read in the first place, thus not closing the line.
This manifested itself in the wifi hostap/hwsim tests where the parallel script communicates via one serial console and the kernel messages go to another (a file) and sending data on the communication console caused the kernel messages to stop flowing into the file.
--- arch/um/drivers/chan_kern.c | 10 +++++----- arch/um/drivers/line.c | 22 +++++++++++++--------- arch/um/drivers/line.h | 4 ++-- arch/um/drivers/ssl.c | 2 -- arch/um/drivers/stdio_console.c | 2 -- arch/um/include/asm/irq.h | 22 +++++++++------------- 6 files changed, 29 insertions(+), 33 deletions(-)
arch/um/drivers/chan_kern.c +5 -5
@@ -133,7 +133,7 @@ static void line_timer_cb(struct work_struct *work) struct line *line = container_of(work, struct line, task.work);if (!line->throttled) -chan_interrupt (line, line->driver->read_irq); +chan_interrupt (line, line->read_irq); }int enable_chan (struct line *line)
@@ -195,9 +195,9 @@ void free_irqs(void) chan = list_entry(ele, struct chan, free_list);if (chan->input && chan->enabled) -um_free_irq (chan->line->driver->read_irq, chan); +um_free_irq (chan->line->read_irq, chan);if (chan->output && chan->enabled) -um_free_irq (chan->line->driver->write_irq, chan); +um_free_irq (chan->line->write_irq, chan); chan->enabled =0 ; } }
@@ -215,9 +215,9 @@ static void close_one_chan(struct chan *chan, int delay_free_irq)spin_unlock_irqrestore (&irqs_to_free_lock, flags); }else {if (chan->input && chan->enabled) -um_free_irq (chan->line->driver->read_irq, chan); +um_free_irq (chan->line->read_irq, chan);if (chan->output && chan->enabled) -um_free_irq (chan->line->driver->write_irq, chan); +um_free_irq (chan->line->write_irq, chan); chan->enabled =0 ; }if (chan->ops->close !=NULL )
arch/um/drivers/line.c +13 -9
@@ -139,7 +139,7 @@ static int flush_buffer(struct line *line) count = line->buffer +LINE_BUFSIZE - line->head; n =write_chan (line->chan_out, line->head, count, - line->driver->write_irq); + line->write_irq);if (n <0 )return n;if (n == count) {
@@ -156,7 +156,7 @@ static int flush_buffer(struct line *line) count = line->tail - line->head; n =write_chan (line->chan_out, line->head, count, - line->driver->write_irq); + line->write_irq);if (n <0 )return n;
@@ -195,7 +195,7 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len) ret =buffer_data (line, buf, len); else { n =write_chan (line->chan_out, buf, len, - line->driver->write_irq); + line->write_irq);if (n <0 ) { ret = n; goto out_up;
@@ -215,7 +215,7 @@ void line_throttle(struct tty_struct *tty) {struct line *line = tty->driver_data; -deactivate_chan (line->chan_in, line->driver->read_irq); +deactivate_chan (line->chan_in, line->read_irq); line->throttled =1 ; }
@@ -224,7 +224,7 @@ void line_unthrottle(struct tty_struct *tty)struct line *line = tty->driver_data; line->throttled =0 ; -chan_interrupt (line, line->driver->read_irq); +chan_interrupt (line, line->read_irq); }static irqreturn_t line_write_interrupt (int irq,void *data)
@@ -260,19 +260,23 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data)int err;if (input) { - err =um_request_irq (driver->read_irq, fd,IRQ_READ , - line_interrupt,IRQF_SHARED , + err =um_request_irq (UM_IRQ_ALLOC , fd,IRQ_READ , + line_interrupt,0 , driver->read_irq_name, data);if (err <0 )return err; + + line->read_irq = err; }if (output) { - err =um_request_irq (driver->write_irq, fd,IRQ_WRITE , - line_write_interrupt,IRQF_SHARED , + err =um_request_irq (UM_IRQ_ALLOC , fd,IRQ_WRITE , + line_write_interrupt,0 , driver->write_irq_name, data);if (err <0 )return err; + + line->write_irq = err; }return 0 ;
arch/um/drivers/line.h +2 -2
@@ -23,9 +23,7 @@ struct line_driver {const short minor_start;const short type;const short subtype; -const int read_irq;const char *read_irq_name; -const int write_irq;const char *write_irq_name;struct mc_device mc;struct tty_driver *driver;
@@ -35,6 +33,8 @@ struct line {struct tty_port port;int valid; +int read_irq, write_irq; +char *init_str;struct list_head chan_list;struct chan *chan_in, *chan_out;
arch/um/drivers/ssl.c +0 -2
@@ -47,9 +47,7 @@ static struct line_driver driver = { .minor_start = 64, .type = TTY_DRIVER_TYPE_SERIAL, .subtype = 0, - .read_irq = SSL_IRQ, .read_irq_name = "ssl", - .write_irq = SSL_WRITE_IRQ, .write_irq_name = "ssl-write", .mc = { .list = LIST_HEAD_INIT(driver.mc.list),
arch/um/drivers/stdio_console.c +0 -2
@@ -53,9 +53,7 @@ static struct line_driver driver = { .minor_start = 0, .type = TTY_DRIVER_TYPE_CONSOLE, .subtype = SYSTEM_TYPE_CONSOLE, - .read_irq = CONSOLE_IRQ, .read_irq_name = "console", - .write_irq = CONSOLE_WRITE_IRQ, .write_irq_name = "console-write", .mc = { .list = LIST_HEAD_INIT(driver.mc.list),
arch/um/include/asm/irq.h +9 -13
@@ -4,19 +4,15 @@#define TIMER_IRQ 0#define UMN_IRQ 1 -#define CONSOLE_IRQ 2 -#define CONSOLE_WRITE_IRQ 3 -#define UBD_IRQ 4 -#define UM_ETH_IRQ 5 -#define SSL_IRQ 6 -#define SSL_WRITE_IRQ 7 -#define ACCEPT_IRQ 8 -#define MCONSOLE_IRQ 9 -#define WINCH_IRQ 10 -#define SIGIO_WRITE_IRQ 11 -#define TELNETD_IRQ 12 -#define XTERM_IRQ 13 -#define RANDOM_IRQ 14 +#define UBD_IRQ 2 +#define UM_ETH_IRQ 3 +#define ACCEPT_IRQ 4 +#define MCONSOLE_IRQ 5 +#define WINCH_IRQ 6 +#define SIGIO_WRITE_IRQ 7 +#define TELNETD_IRQ 8 +#define XTERM_IRQ 9 +#define RANDOM_IRQ 10#ifdef CONFIG_UML_NET_VECTOR
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 271/339 modpost: fix undefined behavior of is_arm_mapping_symbol()
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
[ Upstream commit d6b732666a1bae0df3c3ae06925043bba34502b1 ]
The return value of is_arm_mapping_symbol() is unpredictable when "$" is passed in.
strchr(3) says:
The strchr() and strrchr() functions return a pointer to the matched character or NULL if the character is not found. The terminating null byte is considered part of the string, so that if c is specified as '\0', these functions return a pointer to the terminator.
When str[1] is '\0', strchr("axtd", str[1]) is not NULL, and str[2] is referenced (i.e. buffer overrun).
Test code
---------
char str1[] = "abc";
char str2[] = "ab";
strcpy(str1, "$");
strcpy(str2, "$");
printf("test1: %d\n", is_arm_mapping_symbol(str1));
printf("test2: %d\n", is_arm_mapping_symbol(str2));Result
------
test1: 0
test2: 1
--- scripts/mod/modpost.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
scripts/mod/modpost.c +2 -1
@@ -1267,7 +1267,8 @@ static int secref_whitelist(const struct sectioncheck *mismatch,static inline int is_arm_mapping_symbol (const char *str) { -return str[0 ] =='$' &&strchr ("axtd" , str[1 ]) +return str[0 ] =='$' && + (str[1 ] =='a' || str[1 ] =='d' || str[1 ] =='t' || str[1 ] =='x' ) && (str[2 ] =='\0' || str[2 ] =='.' ); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 272/339 objtool: Mark __ubsan_handle_builtin_unreachable() as noreturn
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit 385bd430c011a8cb8278e61c32d602d11e06f414 ]
fs/ntfs3/ntfs3.prelink.o: warning: objtool: ni_read_frame() falls through to next function ni_readpage_cmpr.cold()
That is in fact:
000000000000124a <ni_read_frame.cold>:
124a: 44 89 e0 mov %r12d,%eax
124d: 0f b6 55 98 movzbl -0x68(%rbp),%edx
1251: 48 c7 c7 00 00 00 00 mov $0x0,%rdi 1254: R_X86_64_32S .data+0x1380
1258: 48 89 c6 mov %rax,%rsi
125b: e8 00 00 00 00 call 1260 <ni_read_frame.cold+0x16> 125c: R_X86_64_PLT32 __ubsan_handle_shift_out_of_bounds-0x4
1260: 48 8d 7d cc lea -0x34(%rbp),%rdi
1264: e8 00 00 00 00 call 1269 <ni_read_frame.cold+0x1f> 1265: R_X86_64_PLT32 __tsan_read4-0x4
1269: 8b 45 cc mov -0x34(%rbp),%eax
126c: e9 00 00 00 00 jmp 1271 <ni_read_frame.cold+0x27> 126d: R_X86_64_PC32 .text+0x19109
1271: 48 8b 75 a0 mov -0x60(%rbp),%rsi
1275: 48 63 d0 movslq %eax,%rdx
1278: 48 c7 c7 00 00 00 00 mov $0x0,%rdi 127b: R_X86_64_32S .data+0x13a0
127f: 89 45 88 mov %eax,-0x78(%rbp)
1282: e8 00 00 00 00 call 1287 <ni_read_frame.cold+0x3d> 1283: R_X86_64_PLT32 __ubsan_handle_shift_out_of_bounds-0x4
1287: 8b 45 88 mov -0x78(%rbp),%eax
128a: e9 00 00 00 00 jmp 128f <ni_read_frame.cold+0x45> 128b: R_X86_64_PC32 .text+0x19098
128f: 48 c7 c7 00 00 00 00 mov $0x0,%rdi 1292: R_X86_64_32S .data+0x11f0
1296: e8 00 00 00 00 call 129b <ni_readpage_cmpr.cold> 1297: R_X86_64_PLT32 __ubsan_handle_builtin_unreachable-0x4000000000000129b <ni_readpage_cmpr.cold>:
Tell objtool that __ubsan_handle_builtin_unreachable() is a noreturn.
--- tools/objtool/check.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/objtool/check.c +2 -1
@@ -185,7 +185,8 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,"do_group_exit" ,"stop_this_cpu" ,"__invalid_creds" , - "cpu_startup_entry", +"cpu_startup_entry" , + "__ubsan_handle_builtin_unreachable", };if (!func)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 273/339 x86/cpu: Elide KCSAN for cpu_has() and friends
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit a6a5eb269f6f3a2fe392f725a8d9052190c731e2 ]
As x86 uses the <asm-generic/bitops/instrumented-*.h> headers, the regular forms of all bitops are instrumented with explicit calls to KASAN and KCSAN checks. As these are explicit calls, these are not suppressed by the noinstr function attribute.
This can result in calls to those check functions in noinstr code, which objtool warns about:
vmlinux.o: warning: objtool: enter_from_user_mode+0x24: call to __kcsan_check_access() leaves .noinstr.text section vmlinux.o: warning: objtool: syscall_enter_from_user_mode+0x28: call to __kcsan_check_access() leaves .noinstr.text section vmlinux.o: warning: objtool: syscall_enter_from_user_mode_prepare+0x24: call to __kcsan_check_access() leaves .noinstr.text section vmlinux.o: warning: objtool: irqentry_enter_from_user_mode+0x24: call to __kcsan_check_access() leaves .noinstr.text section
Prevent this by using the arch_*() bitops, which are the underlying bitops without explciit instrumentation.
--- arch/x86/include/asm/cpufeature.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/cpufeature.h +1 -1
@@ -51,7 +51,7 @@ extern const char * const x86_power_flags[32];extern const char *const x86_bug_flags[NBUGINTS *32 ];#define test_cpu_cap (c, bit) \ - test_bit(bit, (unsigned long *)((c)->x86_capability)) + arch_test_bit(bit, (unsigned long *)((c)->x86_capability))/* * There are 32 bits/features in each mask word. The high bits
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 274/339 jump_label,noinstr: Avoid instrumentation for JUMP_LABEL=n builds
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit 656d054e0a15ec327bd82801ccd58201e59f6896 ]
When building x86_64 with JUMP_LABEL=n it's possible for instrumentation to sneak into noinstr:
vmlinux.o: warning: objtool: exit_to_user_mode+0x14: call to static_key_count.constprop.0() leaves .noinstr.text section vmlinux.o: warning: objtool: syscall_exit_to_user_mode+0x2d: call to static_key_count.constprop.0() leaves .noinstr.text section vmlinux.o: warning: objtool: irqentry_exit_to_user_mode+0x1b: call to static_key_count.constprop.0() leaves .noinstr.text section
Switch to arch_ prefixed atomic to avoid the explicit instrumentation.
--- include/linux/jump_label.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/jump_label.h +2 -2
@@ -256,9 +256,9 @@ extern void static_key_disable_cpuslocked(struct static_key *key);#include <linux/atomic.h> #include <linux/bug.h> -static inline int static_key_count (struct static_key *key) +static __always_inline int static_key_count(struct static_key *key) { -return atomic_read (&key->enabled); +return arch_atomic_read (&key->enabled); } static __always_inline void jump_label_init(void)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 275/339 nbd: call genl_unregister_family() first in nbd_cleanup()
In reply to Greg Kroah-HartmanFrom: Yu Kuai <[email protected]>
[ Upstream commit 06c4da89c24e7023ea448cadf8e9daf06a0aae6e ]
Otherwise there may be race between module removal and the handling of netlink command, which can lead to the oops as shown below:
BUG: kernel NULL pointer dereference, address: 0000000000000098 Oops: 0002 [#1] SMP PTI CPU: 1 PID: 31299 Comm: nbd-client Tainted: G E 5.14.0-rc4 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) RIP: 0010:down_write+0x1a/0x50 Call Trace: start_creating+0x89/0x130 debugfs_create_dir+0x1b/0x130 nbd_start_device+0x13d/0x390 [nbd] nbd_genl_connect+0x42f/0x748 [nbd] genl_family_rcv_msg_doit.isra.0+0xec/0x150 genl_rcv_msg+0xe5/0x1e0 netlink_rcv_skb+0x55/0x100 genl_rcv+0x29/0x40 netlink_unicast+0x1a8/0x250 netlink_sendmsg+0x21b/0x430 ____sys_sendmsg+0x2a4/0x2d0 ___sys_sendmsg+0x81/0xc0 __sys_sendmsg+0x62/0xb0 __x64_sys_sendmsg+0x1f/0x30 do_syscall_64+0x3b/0xc0 entry_SYSCALL_64_after_hwframe+0x44/0xae Modules linked in: nbd(E-)
--- drivers/block/nbd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/block/nbd.c +6 -1
@@ -2545,6 +2545,12 @@ static void __exit nbd_cleanup(void)struct nbd_device *nbd;LIST_HEAD (del_list); +/* +* Unregister netlink interface prior to waiting +* for the completion of netlink commands. +*/ +genl_unregister_family (&nbd_genl_family); +nbd_dbg_close ();mutex_lock (&nbd_index_mutex);
@@ -2563,7 +2569,6 @@ static void __exit nbd_cleanup(void)destroy_workqueue (nbd_del_wq);idr_destroy (&nbd_index_idr); -genl_unregister_family (&nbd_genl_family);unregister_blkdev (NBD_MAJOR ,"nbd" ); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 276/339 nbd: fix race between nbd_alloc_config() and module removal
In reply to Greg Kroah-HartmanFrom: Yu Kuai <[email protected]>
[ Upstream commit c55b2b983b0fa012942c3eb16384b2b722caa810 ]
When nbd module is being removing, nbd_alloc_config() may be called concurrently by nbd_genl_connect(), although try_module_get() will return false, but nbd_alloc_config() doesn't handle it.
The race may lead to the leak of nbd_config and its related resources (e.g, recv_workq) and oops in nbd_read_stat() due to the unload of nbd module as shown below:
BUG: kernel NULL pointer dereference, address: 0000000000000040 Oops: 0000 [#1] SMP PTI CPU: 5 PID: 13840 Comm: kworker/u17:33 Not tainted 5.14.0+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) Workqueue: knbd16-recv recv_work [nbd] RIP: 0010:nbd_read_stat.cold+0x130/0x1a4 [nbd] Call Trace: recv_work+0x3b/0xb0 [nbd] process_one_work+0x1ed/0x390 worker_thread+0x4a/0x3d0 kthread+0x12a/0x150 ret_from_fork+0x22/0x30
Fixing it by checking the return value of try_module_get()
in nbd_alloc_config(). As nbd_alloc_config() may return ERR_PTR(-ENODEV), assign nbd->config only when nbd_alloc_config() succeeds to ensure the value of nbd->config is binary (valid or NULL).
Also adding a debug message to check the reference counter of nbd_config during module removal.
--- drivers/block/nbd.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-)
drivers/block/nbd.c +19 -9
@@ -1533,15 +1533,20 @@ static struct nbd_config *nbd_alloc_config(void) {struct nbd_config *config; +if (!try_module_get (THIS_MODULE )) +return ERR_PTR (-ENODEV ); + config =kzalloc (sizeof (struct nbd_config ),GFP_NOFS ); -if (!config) -return NULL ; +if (!config) { +module_put (THIS_MODULE ); +return ERR_PTR (-ENOMEM ); + } +atomic_set (&config->recv_threads,0 );init_waitqueue_head (&config->recv_wq);init_waitqueue_head (&config->conn_wait); config->blksize_bits =NBD_DEF_BLKSIZE_BITS ;atomic_set (&config->live_connections,0 ); -try_module_get (THIS_MODULE );return config; }
@@ -1568,12 +1573,13 @@ static int nbd_open(struct block_device *bdev, fmode_t mode)mutex_unlock (&nbd->config_lock); goto out; } - config = nbd->config =nbd_alloc_config (); -if (!config) { - ret = -ENOMEM ; + config =nbd_alloc_config (); +if (IS_ERR (config)) { + ret =PTR_ERR (config);mutex_unlock (&nbd->config_lock); goto out; } + nbd->config = config;refcount_set (&nbd->config_refs,1 );refcount_inc (&nbd->refs);mutex_unlock (&nbd->config_lock);
@@ -1981,13 +1987,14 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)nbd_put (nbd);return -EINVAL ; } - config = nbd->config =nbd_alloc_config (); -if (!nbd->config) { + config =nbd_alloc_config (); +if (IS_ERR (config)) {mutex_unlock (&nbd->config_lock);nbd_put (nbd);printk (KERN_ERR "nbd: couldn't allocate config\n" ); -return -ENOMEM ; +return PTR_ERR (config); } + nbd->config = config;refcount_set (&nbd->config_refs,1 );set_bit (NBD_RT_BOUND , &config->runtime_flags);
@@ -2560,6 +2567,9 @@ static void __exit nbd_cleanup(void)while (!list_empty (&del_list)) { nbd = list_first_entry(&del_list, struct nbd_device, list);list_del_init (&nbd->list); +if (refcount_read (&nbd->config_refs)) +printk (KERN_ERR "nbd: possibly leaking nbd_config (ref %d)\n" , +refcount_read (&nbd->config_refs));if (refcount_read (&nbd->refs) !=1 )printk (KERN_ERR "nbd: possibly leaking a device\n" );nbd_put (nbd);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 277/339 nbd: fix io hung while disconnecting device
In reply to Greg Kroah-HartmanFrom: Yu Kuai <[email protected]>
[ Upstream commit 09dadb5985023e27d4740ebd17e6fea4640110e5 ]
In our tests, "qemu-nbd" triggers a io hung:
INFO: task qemu-nbd:11445 blocked for more than 368 seconds.
Not tainted 5.18.0-rc3-next-20220422-00003-g2176915513ca #884
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:qemu-nbd state:D stack: 0 pid:11445 ppid: 1 flags:0x00000000
Call Trace:
<TASK>
__schedule+0x480/0x1050
? _raw_spin_lock_irqsave+0x3e/0xb0
schedule+0x9c/0x1b0
blk_mq_freeze_queue_wait+0x9d/0xf0
? ipi_rseq+0x70/0x70
blk_mq_freeze_queue+0x2b/0x40
nbd_add_socket+0x6b/0x270 [nbd]
nbd_ioctl+0x383/0x510 [nbd]
blkdev_ioctl+0x18e/0x3e0
__x64_sys_ioctl+0xac/0x120
do_syscall_64+0x35/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xae
RIP: 0033:0x7fd8ff706577
RSP: 002b:00007fd8fcdfebf8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 0000000040000000 RCX: 00007fd8ff706577
RDX: 000000000000000d RSI: 000000000000ab00 RDI: 000000000000000f
RBP: 000000000000000f R08: 000000000000fbe8 R09: 000055fe497c62b0
R10: 00000002aff20000 R11: 0000000000000246 R12: 000000000000006d
R13: 0000000000000000 R14: 00007ffe82dc5e70 R15: 00007fd8fcdff9c0"qemu-ndb -d" will call ioctl 'NBD_DISCONNECT' first, however, following message was found:
block nbd0: Send disconnect failed -32
Which indicate that something is wrong with the server. Then, "qemu-nbd -d" will call ioctl 'NBD_CLEAR_SOCK', however ioctl can't clear requests after commit 2516ab1543fd("nbd: only clear the queue on device teardown"). And in the meantime, request can't complete through timeout because nbd_xmit_timeout() will always return 'BLK_EH_RESET_TIMER', which means such request will never be completed in this situation.
Now that the flag 'NBD_CMD_INFLIGHT' can make sure requests won't complete multiple times, switch back to call nbd_clear_sock() in nbd_clear_sock_ioctl(), so that inflight requests can be cleared.
--- drivers/block/nbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/nbd.c +1 -1
@@ -1434,7 +1434,7 @@ static int nbd_start_device_ioctl(struct nbd_device *nbd, struct block_device *bstatic void nbd_clear_sock_ioctl (struct nbd_device *nbd,struct block_device *bdev) { -sock_shutdown (nbd); +nbd_clear_sock (nbd);__invalidate_device (bdev, true);nbd_bdev_reset (bdev); if (test_and_clear_bit(NBD_RT_HAS_CONFIG_REF,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 278/339 Revert "PCI: brcmstb: Do not turn off WOL regulators on suspend"
In reply to Greg Kroah-HartmanFrom: Bjorn Helgaas <[email protected]>
[ Upstream commit 7894025c783ca36394d3afe49c8cfb4c830b82fe ]
This reverts commit 11ed8b8624b8085f706864b4addcd304b1e4fc38.
This is part of a revert of the following commits:
11ed8b8624b8 ("PCI: brcmstb: Do not turn off WOL regulators on suspend") 93e41f3fca3d ("PCI: brcmstb: Add control of subdevice voltage regulators") 67211aadcb4b ("PCI: brcmstb: Add mechanism to turn on subdev regulators") 830aa6f29f07 ("PCI: brcmstb: Split brcm_pcie_setup() into two funcs")
Cyril reported that 830aa6f29f07 ("PCI: brcmstb: Split brcm_pcie_setup() into two funcs"), which appeared in v5.17-rc1, broke booting on the Raspberry Pi Compute Module 4. Apparently 830aa6f29f07 panics with an Asynchronous SError Interrupt, and after further commits here is a black screen on HDMI and no output on the serial console.
This does not seem to affect the Raspberry Pi 4 B.
--- drivers/pci/controller/pcie-brcmstb.c | 53 +++++---------------------- 1 file changed, 9 insertions(+), 44 deletions(-)
drivers/pci/controller/pcie-brcmstb.c +9 -44
@@ -333,7 +333,6 @@ struct brcm_pcie {void (*bridge_sw_init_set)(struct brcm_pcie *pcie,u32 val);bool refusal_mode;struct subdev_regulators *sr; -bool ep_wakeup_capable; };static inline bool is_bmips (const struct brcm_pcie *pcie)
@@ -1351,21 +1350,9 @@ static void brcm_pcie_turn_off(struct brcm_pcie *pcie) pcie->bridge_sw_init_set (pcie,1 ); } -static int pci_dev_may_wakeup (struct pci_dev *dev,void *data) -{ -bool *ret = data; - -if (device_may_wakeup (&dev->dev)) { - *ret = true; -dev_info (&dev->dev,"disable cancelled for wake-up device\n" ); - } -return (int ) *ret; -} -static int brcm_pcie_suspend (struct device *dev) {struct brcm_pcie *pcie =dev_get_drvdata (dev); -struct pci_host_bridge *bridge =pci_host_bridge_from_priv (pcie);int ret;brcm_pcie_turn_off (pcie);
@@ -1384,22 +1371,11 @@ static int brcm_pcie_suspend(struct device *dev) }if (pcie->sr) { -/* -* Now turn off the regulators, but if at least one -* downstream device is enabled as a wake-up source, do not -* turn off regulators. -*/ - pcie->ep_wakeup_capable = false; -pci_walk_bus (bridge->bus, pci_dev_may_wakeup, - &pcie->ep_wakeup_capable); -if (!pcie->ep_wakeup_capable) { - ret =regulator_bulk_disable (pcie->sr->num_supplies, - pcie->sr->supplies); -if (ret) { -dev_err (dev,"Could not turn off regulators\n" ); -reset_control_reset (pcie->rescal); -return ret; - } + ret =regulator_bulk_disable (pcie->sr->num_supplies, pcie->sr->supplies); +if (ret) { +dev_err (dev,"Could not turn off regulators\n" ); +reset_control_reset (pcie->rescal); +return ret; } }clk_disable_unprepare (pcie->clk);
@@ -1420,21 +1396,10 @@ static int brcm_pcie_resume(struct device *dev)return ret;if (pcie->sr) { -if (pcie->ep_wakeup_capable) { -/* -* We are resuming from a suspend. In the suspend we -* did not disable the power supplies, so there is -* no need to enable them (and falsely increase their -* usage count). -*/ - pcie->ep_wakeup_capable = false; - }else { - ret =regulator_bulk_enable (pcie->sr->num_supplies, - pcie->sr->supplies); -if (ret) { -dev_err (dev,"Could not turn on regulators\n" ); - goto err_disable_clk; - } + ret =regulator_bulk_enable (pcie->sr->num_supplies, pcie->sr->supplies); +if (ret) { +dev_err (dev,"Could not turn on regulators\n" ); + goto err_disable_clk; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 279/339 Revert "PCI: brcmstb: Add control of subdevice voltage regulators"
In reply to Greg Kroah-HartmanFrom: Bjorn Helgaas <[email protected]>
[ Upstream commit 212942609d83b591f5a2f2691df122d13aa3a87d ]
This reverts commit 93e41f3fca3d4a0f927b784012338c37f80a8a80.
This is part of a revert of the following commits:
11ed8b8624b8 ("PCI: brcmstb: Do not turn off WOL regulators on suspend") 93e41f3fca3d ("PCI: brcmstb: Add control of subdevice voltage regulators") 67211aadcb4b ("PCI: brcmstb: Add mechanism to turn on subdev regulators") 830aa6f29f07 ("PCI: brcmstb: Split brcm_pcie_setup() into two funcs")
Cyril reported that 830aa6f29f07 ("PCI: brcmstb: Split brcm_pcie_setup() into two funcs"), which appeared in v5.17-rc1, broke booting on the Raspberry Pi Compute Module 4. Apparently 830aa6f29f07 panics with an Asynchronous SError Interrupt, and after further commits here is a black screen on HDMI and no output on the serial console.
This does not seem to affect the Raspberry Pi 4 B.
--- drivers/pci/controller/pcie-brcmstb.c | 83 ++------------------------- 1 file changed, 5 insertions(+), 78 deletions(-)
drivers/pci/controller/pcie-brcmstb.c +5 -78
@@ -196,8 +196,6 @@ static inline void brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie,static inline void brcm_pcie_perst_set_4908 (struct brcm_pcie *pcie,u32 val);static inline void brcm_pcie_perst_set_7278 (struct brcm_pcie *pcie,u32 val);static inline void brcm_pcie_perst_set_generic (struct brcm_pcie *pcie,u32 val); -static int brcm_pcie_linkup (struct brcm_pcie *pcie); -static int brcm_pcie_add_bus (struct pci_bus *bus);enum {RGR1_SW_INIT_1 ,
@@ -331,8 +329,6 @@ struct brcm_pcie {u32 hw_rev;void (*perst_set)(struct brcm_pcie *pcie,u32 val);void (*bridge_sw_init_set)(struct brcm_pcie *pcie,u32 val); -bool refusal_mode; -struct subdev_regulators *sr; };static inline bool is_bmips (const struct brcm_pcie *pcie)
@@ -501,34 +497,6 @@ static int pci_subdev_regulators_add_bus(struct pci_bus *bus)return 0 ; } -static int brcm_pcie_add_bus (struct pci_bus *bus) -{ -struct device *dev = &bus->dev; -struct brcm_pcie *pcie = (struct brcm_pcie *) bus->sysdata; -int ret; - -if (!dev->of_node || !bus->parent || !pci_is_root_bus (bus->parent)) -return 0 ; - - ret =pci_subdev_regulators_add_bus (bus); -if (ret) -return ret; - -/* Grab the regulators for suspend/resume */ - pcie->sr = bus->dev.driver_data; - -/* -* If we have failed linkup there is no point to return an error as -* currently it will cause a WARNING() from pci_alloc_child_bus(). -* We return 0 and turn on the "refusal_mode" so that any further -* accesses to the pci_dev just get 0xffffffff -*/ -if (brcm_pcie_linkup (pcie) !=0 ) - pcie->refusal_mode = true; - -return 0 ; -} -static void pci_subdev_regulators_remove_bus (struct pci_bus *bus) {struct device *dev = &bus->dev;
@@ -857,18 +825,6 @@ static void __iomem *brcm_pcie_map_conf(struct pci_bus *bus, unsigned int devfn,/* Accesses to the RC go right to the RC registers if slot==0 */ if (pci_is_root_bus (bus))return PCI_SLOT (devfn) ?NULL : base + where; -if (pcie->refusal_mode) { -/* -* At this point we do not have link. There will be a CPU -* abort -- a quirk with this controller --if Linux tries -* to read any config-space registers besides those -* targeting the host bridge. To prevent this we hijack -* the address to point to a safe access that will return -* 0xffffffff. -*/ -writel (0xffffffff , base +PCIE_MISC_RC_BAR2_CONFIG_HI ); -return base +PCIE_MISC_RC_BAR2_CONFIG_HI + (where &0x3 ); - }/* For devices, write to the config space index register */ idx =PCIE_ECAM_OFFSET (bus->number, devfn,0 );
@@ -897,7 +853,7 @@ static struct pci_ops brcm_pcie_ops = { .map_bus = brcm_pcie_map_conf, .read = pci_generic_config_read, .write = pci_generic_config_write, - .add_bus = brcm_pcie_add_bus, + .add_bus = pci_subdev_regulators_add_bus, .remove_bus = pci_subdev_regulators_remove_bus, };
@@ -1370,14 +1326,6 @@ static int brcm_pcie_suspend(struct device *dev)return ret; } -if (pcie->sr) { - ret =regulator_bulk_disable (pcie->sr->num_supplies, pcie->sr->supplies); -if (ret) { -dev_err (dev,"Could not turn off regulators\n" ); -reset_control_reset (pcie->rescal); -return ret; - } - }clk_disable_unprepare (pcie->clk);return 0 ;
@@ -1395,17 +1343,9 @@ static int brcm_pcie_resume(struct device *dev)if (ret)return ret; -if (pcie->sr) { - ret =regulator_bulk_enable (pcie->sr->num_supplies, pcie->sr->supplies); -if (ret) { -dev_err (dev,"Could not turn on regulators\n" ); - goto err_disable_clk; - } - } - ret =reset_control_reset (pcie->rescal);if (ret) - goto err_regulator; + goto err_disable_clk; ret =brcm_phy_start (pcie);if (ret)
@@ -1437,9 +1377,6 @@ static int brcm_pcie_resume(struct device *dev) err_reset:reset_control_rearm (pcie->rescal); -err_regulator: -if (pcie->sr) -regulator_bulk_disable (pcie->sr->num_supplies, pcie->sr->supplies); err_disable_clk:clk_disable_unprepare (pcie->clk);return ret;
@@ -1571,17 +1508,7 @@ static int brcm_pcie_probe(struct platform_device *pdev)platform_set_drvdata (pdev, pcie); - ret =pci_host_probe (bridge); -if (!ret && !brcm_pcie_link_up (pcie)) - ret = -ENODEV ; - -if (ret) { -brcm_pcie_remove (pdev); -return ret; - } - -return 0 ; - +return pci_host_probe (bridge); fail:__brcm_pcie_remove (pcie);return ret;
@@ -1590,8 +1517,8 @@ static int brcm_pcie_probe(struct platform_device *pdev)MODULE_DEVICE_TABLE (of, brcm_pcie_match);static const struct dev_pm_ops brcm_pcie_pm_ops = { - .suspend_noirq = brcm_pcie_suspend, - .resume_noirq = brcm_pcie_resume, + .suspend = brcm_pcie_suspend, + .resume = brcm_pcie_resume, };static struct platform_driver brcm_pcie_driver = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 280/339 Revert "PCI: brcmstb: Add mechanism to turn on subdev regulators"
In reply to Greg Kroah-HartmanFrom: Bjorn Helgaas <[email protected]>
[ Upstream commit 420be2f7ebe60c9ba3e332f5290017cd168e2bf8 ]
This reverts commit 67211aadcb4b968d0fdc57bc27240fa71500c2d4.
This is part of a revert of the following commits:
11ed8b8624b8 ("PCI: brcmstb: Do not turn off WOL regulators on suspend") 93e41f3fca3d ("PCI: brcmstb: Add control of subdevice voltage regulators") 67211aadcb4b ("PCI: brcmstb: Add mechanism to turn on subdev regulators") 830aa6f29f07 ("PCI: brcmstb: Split brcm_pcie_setup() into two funcs")
Cyril reported that 830aa6f29f07 ("PCI: brcmstb: Split brcm_pcie_setup() into two funcs"), which appeared in v5.17-rc1, broke booting on the Raspberry Pi Compute Module 4. Apparently 830aa6f29f07 panics with an Asynchronous SError Interrupt, and after further commits here is a black screen on HDMI and no output on the serial console.
This does not seem to affect the Raspberry Pi 4 B.
--- drivers/pci/controller/pcie-brcmstb.c | 76 --------------------------- 1 file changed, 76 deletions(-)
drivers/pci/controller/pcie-brcmstb.c +0 -76
@@ -24,7 +24,6 @@#include <linux/pci.h> #include <linux/pci-ecam.h> #include <linux/printk.h> -#include <linux/regulator/consumer.h> #include <linux/reset.h> #include <linux/sizes.h> #include <linux/slab.h>
@@ -284,14 +283,6 @@ static const struct pcie_cfg_data bcm2711_cfg = { .bridge_sw_init_set = brcm_pcie_bridge_sw_init_set_generic, }; -struct subdev_regulators { -unsigned int num_supplies; -struct regulator_bulk_data supplies[]; -}; - -static int pci_subdev_regulators_add_bus (struct pci_bus *bus); -static void pci_subdev_regulators_remove_bus (struct pci_bus *bus); -struct brcm_msi {struct device *dev;void __iomem *base;
@@ -445,71 +436,6 @@ static int brcm_pcie_set_ssc(struct brcm_pcie *pcie)return ssc && pll ?0 : -EIO ; } -static void *alloc_subdev_regulators (struct device *dev) -{ -static const char *const supplies[] = { -"vpcie3v3" , -"vpcie3v3aux" , -"vpcie12v" , - }; -const size_t size =sizeof (struct subdev_regulators ) - +sizeof (struct regulator_bulk_data ) *ARRAY_SIZE (supplies); -struct subdev_regulators *sr; -int i; - - sr =devm_kzalloc (dev, size,GFP_KERNEL ); -if (sr) { - sr->num_supplies =ARRAY_SIZE (supplies); -for (i =0 ; i <ARRAY_SIZE (supplies); i++) - sr->supplies[i].supply = supplies[i]; - } - -return sr; -} - -static int pci_subdev_regulators_add_bus (struct pci_bus *bus) -{ -struct device *dev = &bus->dev; -struct subdev_regulators *sr; -int ret; - -if (!dev->of_node || !bus->parent || !pci_is_root_bus (bus->parent)) -return 0 ; - -if (dev->driver_data) -dev_err (dev,"dev.driver_data unexpectedly non-NULL\n" ); - - sr =alloc_subdev_regulators (dev); -if (!sr) -return -ENOMEM ; - - dev->driver_data = sr; - ret =regulator_bulk_get (dev, sr->num_supplies, sr->supplies); -if (ret) -return ret; - - ret =regulator_bulk_enable (sr->num_supplies, sr->supplies); -if (ret) { -dev_err (dev,"failed to enable regulators for downstream device\n" ); -return ret; - } - -return 0 ; -} - -static void pci_subdev_regulators_remove_bus (struct pci_bus *bus) -{ -struct device *dev = &bus->dev; -struct subdev_regulators *sr = dev->driver_data; - -if (!sr || !bus->parent || !pci_is_root_bus (bus->parent)) -return ; - -if (regulator_bulk_disable (sr->num_supplies, sr->supplies)) -dev_err (dev,"failed to disable regulators for downstream device\n" ); - dev->driver_data =NULL ; -} -/* Limits operation to a specific generation (1, 2, or 3) */ static void brcm_pcie_set_gen (struct brcm_pcie *pcie,int gen) {
@@ -853,8 +779,6 @@ static struct pci_ops brcm_pcie_ops = { .map_bus = brcm_pcie_map_conf, .read = pci_generic_config_read, .write = pci_generic_config_write, - .add_bus = pci_subdev_regulators_add_bus, - .remove_bus = pci_subdev_regulators_remove_bus, };static struct pci_ops brcm_pcie_ops32 = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 281/339 Revert "PCI: brcmstb: Split brcm_pcie_setup() into two funcs"
In reply to Greg Kroah-HartmanFrom: Bjorn Helgaas <[email protected]>
[ Upstream commit f4fd559de3434c44bed1d2912bd0c75cfa42898b ]
This reverts commit 830aa6f29f07a4e2f1a947dfa72b3ccddb46dd21.
This is part of a revert of the following commits:
11ed8b8624b8 ("PCI: brcmstb: Do not turn off WOL regulators on suspend") 93e41f3fca3d ("PCI: brcmstb: Add control of subdevice voltage regulators") 67211aadcb4b ("PCI: brcmstb: Add mechanism to turn on subdev regulators") 830aa6f29f07 ("PCI: brcmstb: Split brcm_pcie_setup() into two funcs")
Cyril reported that 830aa6f29f07 ("PCI: brcmstb: Split brcm_pcie_setup() into two funcs"), which appeared in v5.17-rc1, broke booting on the Raspberry Pi Compute Module 4. Apparently 830aa6f29f07 panics with an Asynchronous SError Interrupt, and after further commits here is a black screen on HDMI and no output on the serial console.
This does not seem to affect the Raspberry Pi 4 B.
--- drivers/pci/controller/pcie-brcmstb.c | 65 +++++++++++---------------- 1 file changed, 26 insertions(+), 39 deletions(-)
drivers/pci/controller/pcie-brcmstb.c +26 -39
@@ -926,9 +926,16 @@ static inline int brcm_pcie_get_rc_bar2_size_and_offset(struct brcm_pcie *pcie,static int brcm_pcie_setup (struct brcm_pcie *pcie) { +struct pci_host_bridge *bridge =pci_host_bridge_from_priv (pcie);u64 rc_bar2_offset, rc_bar2_size;void __iomem *base = pcie->base; -int ret, memc; +struct device *dev = pcie->dev; +struct resource_entry *entry; +bool ssc_good = false; +struct resource *res; +int num_out_wins =0 ; +u16 nlw, cls, lnksta; +int i, ret, memc;u32 tmp, burst, aspm_support;/* Reset the bridge */
@@ -1018,40 +1025,6 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)if (pcie->gen)brcm_pcie_set_gen (pcie, pcie->gen); -/* Don't advertise L0s capability if 'aspm-no-l0s' */ - aspm_support =PCIE_LINK_STATE_L1 ; -if (!of_property_read_bool (pcie->np,"aspm-no-l0s" )) - aspm_support |=PCIE_LINK_STATE_L0S ; - tmp =readl (base +PCIE_RC_CFG_PRIV1_LINK_CAPABILITY ); -u32p_replace_bits (&tmp, aspm_support, -PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK ); -writel (tmp, base +PCIE_RC_CFG_PRIV1_LINK_CAPABILITY ); - -/* -* For config space accesses on the RC, show the right class for -* a PCIe-PCIe bridge (the default setting is to be EP mode). -*/ - tmp =readl (base +PCIE_RC_CFG_PRIV1_ID_VAL3 ); -u32p_replace_bits (&tmp,0x060400 , -PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK ); -writel (tmp, base +PCIE_RC_CFG_PRIV1_ID_VAL3 ); - -return 0 ; -} - -static int brcm_pcie_linkup (struct brcm_pcie *pcie) -{ -struct pci_host_bridge *bridge =pci_host_bridge_from_priv (pcie); -struct device *dev = pcie->dev; -void __iomem *base = pcie->base; -struct resource_entry *entry; -struct resource *res; -int num_out_wins =0 ; -u16 nlw, cls, lnksta; -bool ssc_good = false; -u32 tmp; -int ret, i; -/* Unassert the fundamental reset */ pcie->perst_set (pcie,0 );
@@ -1102,6 +1075,24 @@ static int brcm_pcie_linkup(struct brcm_pcie *pcie) num_out_wins++; } +/* Don't advertise L0s capability if 'aspm-no-l0s' */ + aspm_support =PCIE_LINK_STATE_L1 ; +if (!of_property_read_bool (pcie->np,"aspm-no-l0s" )) + aspm_support |=PCIE_LINK_STATE_L0S ; + tmp =readl (base +PCIE_RC_CFG_PRIV1_LINK_CAPABILITY ); +u32p_replace_bits (&tmp, aspm_support, +PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK ); +writel (tmp, base +PCIE_RC_CFG_PRIV1_LINK_CAPABILITY ); + +/* +* For config space accesses on the RC, show the right class for +* a PCIe-PCIe bridge (the default setting is to be EP mode). +*/ + tmp =readl (base +PCIE_RC_CFG_PRIV1_ID_VAL3 ); +u32p_replace_bits (&tmp,0x060400 , +PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK ); +writel (tmp, base +PCIE_RC_CFG_PRIV1_ID_VAL3 ); +if (pcie->ssc) { ret =brcm_pcie_set_ssc (pcie);if (ret ==0 )
@@ -1290,10 +1281,6 @@ static int brcm_pcie_resume(struct device *dev)if (ret) goto err_reset; - ret =brcm_pcie_linkup (pcie); -if (ret) - goto err_reset; -if (pcie->msi)brcm_msi_set_regs (pcie->msi);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 282/339 cifs: fix potential deadlock in direct reclaim
In reply to Greg Kroah-HartmanFrom: Vincent Whitchurch <[email protected]>
[ Upstream commit cc391b694ff085f62f133e6b8f864d43a8e69dfd ]
The srv_mutex is used during writeback so cifs should ensure that allocations done when that mutex is held are done with GFP_NOFS, to avoid having direct reclaim ending up waiting for the same mutex and causing a deadlock. This is detected by lockdep with the splat below:
======================================================
WARNING: possible circular locking dependency detected
5.18.0 #70 Not tainted
------------------------------------------------------
kswapd0/49 is trying to acquire lock:
ffff8880195782e0 (&tcp_ses->srv_mutex){+.+.}-{3:3}, at: compound_send_recv
but task is already holding lock:
ffffffffa98e66c0 (fs_reclaim){+.+.}-{0:0}, at: balance_pgdat
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (fs_reclaim){+.+.}-{0:0}:
fs_reclaim_acquire
kmem_cache_alloc_trace
__request_module
crypto_alg_mod_lookup
crypto_alloc_tfm_node
crypto_alloc_shash
cifs_alloc_hash
smb311_crypto_shash_allocate
smb311_update_preauth_hash
compound_send_recv
cifs_send_recv
SMB2_negotiate
smb2_negotiate
cifs_negotiate_protocol
cifs_get_smb_ses
cifs_mount
cifs_smb3_do_mount
smb3_get_tree
vfs_get_tree
path_mount
__x64_sys_mount
do_syscall_64
entry_SYSCALL_64_after_hwframe -> #0 (&tcp_ses->srv_mutex){+.+.}-{3:3}:
__lock_acquire
lock_acquire
__mutex_lock
mutex_lock_nested
compound_send_recv
cifs_send_recv
SMB2_write
smb2_sync_write
cifs_write
cifs_writepage_locked
cifs_writepage
shrink_page_list
shrink_lruvec
shrink_node
balance_pgdat
kswapd
kthread
ret_from_fork
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(fs_reclaim);
lock(&tcp_ses->srv_mutex);
lock(fs_reclaim); lock(&tcp_ses->srv_mutex);
*** DEADLOCK ***
1 lock held by kswapd0/49:
#0: ffffffffa98e66c0 (fs_reclaim){+.+.}-{0:0}, at: balance_pgdat
stack backtrace: CPU: 2 PID: 49 Comm: kswapd0 Not tainted 5.18.0 #70 Call Trace: <TASK> dump_stack_lvl dump_stack print_circular_bug.cold check_noncircular __lock_acquire lock_acquire __mutex_lock mutex_lock_nested compound_send_recv cifs_send_recv SMB2_write smb2_sync_write cifs_write cifs_writepage_locked cifs_writepage shrink_page_list shrink_lruvec shrink_node balance_pgdat kswapd kthread ret_from_fork </TASK>
Fix this by using the memalloc_nofs_save/restore APIs around the places where the srv_mutex is held. Do this in a wrapper function for the lock/unlock of the srv_mutex, and rename the srv_mutex to avoid missing call sites in the conversion.
Note that there is another lockdep warning involving internal crypto locks, which was masked by this problem and is visible after this fix, see the discussion in this thread:
https://lore.kernel.org/all/[email protected]/
--- fs/cifs/cifs_swn.c | 4 ++-- fs/cifs/cifsencrypt.c | 8 ++++---- fs/cifs/cifsglob.h | 20 +++++++++++++++++++- fs/cifs/connect.c | 26 +++++++++++++------------- fs/cifs/dfs_cache.c | 4 ++-- fs/cifs/sess.c | 6 +++--- fs/cifs/smb1ops.c | 6 +++--- fs/cifs/smb2pdu.c | 6 +++--- fs/cifs/smbdirect.c | 4 ++-- fs/cifs/transport.c | 40 ++++++++++++++++++++-------------------- 10 files changed, 71 insertions(+), 53 deletions(-)
fs/cifs/cifs_swn.c +2 -2
@@ -465,7 +465,7 @@ static int cifs_swn_reconnect(struct cifs_tcon *tcon, struct sockaddr_storage *aint ret =0 ;/* Store the reconnect address */ -mutex_lock (&tcon->ses->server->srv_mutex); +cifs_server_lock (tcon->ses->server);if (cifs_sockaddr_equal (&tcon->ses->server->dstaddr, addr)) goto unlock;
@@ -501,7 +501,7 @@ static int cifs_swn_reconnect(struct cifs_tcon *tcon, struct sockaddr_storage *acifs_signal_cifsd_for_reconnect (tcon->ses->server, false); unlock: -mutex_unlock (&tcon->ses->server->srv_mutex); +cifs_server_unlock (tcon->ses->server);return ret; }
fs/cifs/cifsencrypt.c +4 -4
@@ -236,9 +236,9 @@ int cifs_verify_signature(struct smb_rqst *rqst,cpu_to_le32 (expected_sequence_number); cifs_pdu->Signature.Sequence.Reserved =0 ; -mutex_lock (&server->srv_mutex); +cifs_server_lock (server); rc =cifs_calc_signature (rqst, server, what_we_think_sig_should_be); -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);if (rc)return rc;
@@ -626,7 +626,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)memcpy (ses->auth_key.response + baselen, tiblob, tilen); -mutex_lock (&ses->server->srv_mutex); +cifs_server_lock (ses->server); rc = cifs_alloc_hash("hmac(md5)", &ses->server->secmech.hmacmd5,
@@ -678,7 +678,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)cifs_dbg (VFS ,"%s: Could not generate md5 hash\n" , __func__); unlock: -mutex_unlock (&ses->server->srv_mutex); +cifs_server_unlock (ses->server); setup_ntlmv2_rsp_ret:kfree (tiblob);
fs/cifs/cifsglob.h +19 -1
@@ -16,6 +16,7 @@#include <linux/mempool.h> #include <linux/workqueue.h> #include <linux/utsname.h> +#include <linux/sched/mm.h> #include <linux/netfs.h> #include "cifs_fs_sb.h" #include "cifsacl.h"
@@ -621,7 +622,8 @@ struct TCP_Server_Info {unsigned int in_flight;/* number of requests on the wire to server */ unsigned int max_in_flight;/* max number of requests that were on wire */ spinlock_t req_lock;/* protect the two values above */ -struct mutex srv_mutex; +struct mutex _srv_mutex; +unsigned int nofs_flag;struct task_struct *tsk;char server_GUID[16 ];__u16 sec_mode;
@@ -736,6 +738,22 @@ struct TCP_Server_Info {#endif }; +static inline void cifs_server_lock (struct TCP_Server_Info *server) +{ +unsigned int nofs_flag =memalloc_nofs_save (); + +mutex_lock (&server->_srv_mutex); + server->nofs_flag = nofs_flag; +} + +static inline void cifs_server_unlock (struct TCP_Server_Info *server) +{ +unsigned int nofs_flag = server->nofs_flag; + +mutex_unlock (&server->_srv_mutex); +memalloc_nofs_restore (nofs_flag); +} +struct cifs_credits {unsigned int value;unsigned int instance;
fs/cifs/connect.c +13 -13
@@ -148,7 +148,7 @@ static void cifs_resolve_server(struct work_struct *work)struct TCP_Server_Info *server =container_of (work, struct TCP_Server_Info, resolve.work); -mutex_lock (&server->srv_mutex); +cifs_server_lock (server);/* * Resolve the hostname again to make sure that IP address is up-to-date.
@@ -159,7 +159,7 @@ static void cifs_resolve_server(struct work_struct *work) __func__, rc); } -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server); }/*
@@ -267,7 +267,7 @@ cifs_abort_connection(struct TCP_Server_Info *server)/* do not want to be sending data on a socket we are freeing */ cifs_dbg (FYI ,"%s: tearing down socket\n" , __func__); -mutex_lock (&server->srv_mutex); +cifs_server_lock (server);if (server->ssocket) {cifs_dbg (FYI ,"State: 0x%x Flags: 0x%lx\n" , server->ssocket->state, server->ssocket->flags);
@@ -296,7 +296,7 @@ cifs_abort_connection(struct TCP_Server_Info *server) mid->mid_flags |=MID_DELETED ; }spin_unlock (&GlobalMid_Lock); -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);cifs_dbg (FYI ,"%s: issuing mid callbacks\n" , __func__);list_for_each_entry_safe (mid, nmid, &retry_list, qhead) {
@@ -306,9 +306,9 @@ cifs_abort_connection(struct TCP_Server_Info *server) }if (cifs_rdma_enabled (server)) { -mutex_lock (&server->srv_mutex); +cifs_server_lock (server);smbd_destroy (server); -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server); } }
@@ -359,7 +359,7 @@ static int __cifs_reconnect(struct TCP_Server_Info *server, do { try_to_freeze(); - mutex_lock(&server->srv_mutex); + cifs_server_lock(server); if (!cifs_swn_set_server_dstaddr(server)) { /* resolve the hostname again to make sure that IP address is up-to-date */
@@ -372,7 +372,7 @@ static int __cifs_reconnect(struct TCP_Server_Info *server,else rc =generic_ip_connect (server);if (rc) { -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);cifs_dbg (FYI ,"%s: reconnect error %d\n" , __func__, rc);msleep (3000 ); }else {
@@ -383,7 +383,7 @@ static int __cifs_reconnect(struct TCP_Server_Info *server, server->tcpStatus = CifsNeedNegotiate;spin_unlock (&cifs_tcp_ses_lock);cifs_swn_reset_server_dstaddr (server); -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);mod_delayed_work (cifsiod_wq, &server->reconnect,0 ); } }while (server->tcpStatus == CifsNeedReconnect);
@@ -488,12 +488,12 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server) do { try_to_freeze(); - mutex_lock(&server->srv_mutex); + cifs_server_lock(server); rc = reconnect_target_unlocked(server, &tl, &target_hint); if (rc) { /* Failed to reconnect socket */ - mutex_unlock(&server->srv_mutex); + cifs_server_unlock(server); cifs_dbg(FYI, "%s: reconnect error %d\n", __func__, rc); msleep(3000); continue;
@@ -510,7 +510,7 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server) server->tcpStatus = CifsNeedNegotiate;spin_unlock (&cifs_tcp_ses_lock);cifs_swn_reset_server_dstaddr (server); -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);mod_delayed_work (cifsiod_wq, &server->reconnect,0 ); }while (server->tcpStatus == CifsNeedReconnect);
@@ -1565,7 +1565,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,init_waitqueue_head (&tcp_ses->response_q);init_waitqueue_head (&tcp_ses->request_q);INIT_LIST_HEAD (&tcp_ses->pending_mid_q); -mutex_init (&tcp_ses->srv_mutex); +mutex_init (&tcp_ses->_srv_mutex);memcpy (tcp_ses->workstation_RFC1001_name, ctx->source_rfc1001_name,RFC1001_NAME_LEN_WITH_NULL ); memcpy(tcp_ses->server_RFC1001_name,
fs/cifs/dfs_cache.c +2 -2
@@ -1327,9 +1327,9 @@ static bool target_share_equal(struct TCP_Server_Info *server, const char *s1, ccifs_dbg (VFS ,"%s: failed to convert address \'%s\'. skip address matching.\n" , __func__, ip); }else { -mutex_lock (&server->srv_mutex); +cifs_server_lock (server); match =cifs_match_ipaddr ((struct sockaddr *)&server->dstaddr, &sa); -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server); }kfree (ip);
fs/cifs/sess.c +3 -3
@@ -1093,14 +1093,14 @@ sess_establish_session(struct sess_data *sess_data)struct cifs_ses *ses = sess_data->ses;struct TCP_Server_Info *server = sess_data->server; -mutex_lock (&server->srv_mutex); +cifs_server_lock (server);if (!server->session_estab) {if (server->sign) { server->session_key.response =kmemdup (ses->auth_key.response, ses->auth_key.len,GFP_KERNEL );if (!server->session_key.response) { -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);return -ENOMEM ; } server->session_key.len =
@@ -1109,7 +1109,7 @@ sess_establish_session(struct sess_data *sess_data) server->sequence_number =0x2 ; server->session_estab = true; } -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);cifs_dbg (FYI ,"CIFS session established successfully\n" );return 0 ;
fs/cifs/smb1ops.c +3 -3
@@ -38,10 +38,10 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst, in_buf->WordCount =0 ;put_bcc (0 , in_buf); -mutex_lock (&server->srv_mutex); +cifs_server_lock (server); rc =cifs_sign_smb (in_buf, server, &mid->sequence_number);if (rc) { -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);return rc; }
@@ -55,7 +55,7 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,if (rc <0 ) server->sequence_number--; -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);cifs_dbg (FYI ,"issued NT_CANCEL for mid %u, rc = %d\n" ,get_mid (in_buf), rc);
fs/cifs/smb2pdu.c +3 -3
@@ -1369,13 +1369,13 @@ SMB2_sess_establish_session(struct SMB2_sess_data *sess_data)struct cifs_ses *ses = sess_data->ses;struct TCP_Server_Info *server = sess_data->server; -mutex_lock (&server->srv_mutex); +cifs_server_lock (server);if (server->ops->generate_signingkey) { rc = server->ops->generate_signingkey (ses, server);if (rc) {cifs_dbg (FYI ,"SMB3 session key generation failed\n" ); -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);return rc; } }
@@ -1383,7 +1383,7 @@ SMB2_sess_establish_session(struct SMB2_sess_data *sess_data) server->sequence_number =0x2 ; server->session_estab = true; } -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);cifs_dbg (FYI ,"SMB2/3 session established successfully\n" );return rc;
fs/cifs/smbdirect.c +2 -2
@@ -1382,9 +1382,9 @@ void smbd_destroy(struct TCP_Server_Info *server)log_rdma_event (INFO ,"freeing mr list\n" );wake_up_interruptible_all (&info->wait_mr);while (atomic_read (&info->mr_used_count)) { -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);msleep (1000 ); -mutex_lock (&server->srv_mutex); +cifs_server_lock (server); }destroy_mr_list (info);
fs/cifs/transport.c +20 -20
@@ -822,7 +822,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, }else instance = exist_credits->instance; -mutex_lock (&server->srv_mutex); +cifs_server_lock (server);/* * We can't use credits obtained from the previous session to send this
@@ -830,14 +830,14 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,* return -EAGAIN in such cases to let callers handle it. */ if (instance != server->reconnect_instance) { -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);add_credits_and_wake_if (server, &credits, optype);return -EAGAIN ; } mid = server->ops->setup_async_request (server, rqst);if (IS_ERR (mid)) { -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);add_credits_and_wake_if (server, &credits, optype);return PTR_ERR (mid); }
@@ -868,7 +868,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,cifs_delete_mid (mid); } -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);if (rc ==0 )return 0 ;
@@ -1109,7 +1109,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,* of smb data. */ -mutex_lock (&server->srv_mutex); +cifs_server_lock (server);/* * All the parts of the compound chain belong obtained credits from the
@@ -1119,7 +1119,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,* handle it. */ if (instance != server->reconnect_instance) { -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);for (j =0 ; j < num_rqst; j++)add_credits (server, &credits[j], optype);return -EAGAIN ;
@@ -1131,7 +1131,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,revert_current_mid (server, i);for (j =0 ; j < i; j++)cifs_delete_mid (midQ[j]); -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);/* Update # of requests on wire to server */ for (j =0 ; j < num_rqst; j++)
@@ -1163,7 +1163,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, server->sequence_number -=2 ; } -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);/* * If sending failed for some reason or it is an oplock break that we
@@ -1190,9 +1190,9 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,if ((ses->status == CifsNew) || (optype &CIFS_NEG_OP ) || (optype &CIFS_SESS_OP )) {spin_unlock (&cifs_tcp_ses_lock); -mutex_lock (&server->srv_mutex); +cifs_server_lock (server);smb311_update_preauth_hash (ses, server, rqst[0 ].rq_iov, rqst[0 ].rq_nvec); -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);spin_lock (&cifs_tcp_ses_lock); }
@@ -1266,9 +1266,9 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, .iov_len = resp_iov[0].iov_len };spin_unlock (&cifs_tcp_ses_lock); -mutex_lock (&server->srv_mutex); +cifs_server_lock (server);smb311_update_preauth_hash (ses, server, &iov,1 ); -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);spin_lock (&cifs_tcp_ses_lock); }spin_unlock (&cifs_tcp_ses_lock);
@@ -1385,11 +1385,11 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,and avoid races inside tcp sendmsg code that could cause corruption of smb data */ -mutex_lock (&server->srv_mutex); +cifs_server_lock (server); rc =allocate_mid (ses, in_buf, &midQ);if (rc) { -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);/* Update # of requests on wire to server */ add_credits (server, &credits,0 );return rc;
@@ -1397,7 +1397,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, rc =cifs_sign_smb (in_buf, server, &midQ->sequence_number);if (rc) { -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server); goto out; }
@@ -1411,7 +1411,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,if (rc <0 ) server->sequence_number -=2 ; -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);if (rc <0 ) goto out;
@@ -1530,18 +1530,18 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,and avoid races inside tcp sendmsg code that could cause corruption of smb data */ -mutex_lock (&server->srv_mutex); +cifs_server_lock (server); rc =allocate_mid (ses, in_buf, &midQ);if (rc) { -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);return rc; } rc =cifs_sign_smb (in_buf, server, &midQ->sequence_number);if (rc) {cifs_delete_mid (midQ); -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);return rc; }
@@ -1554,7 +1554,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,if (rc <0 ) server->sequence_number -=2 ; -mutex_unlock (&server->srv_mutex); +cifs_server_unlock (server);if (rc <0 ) {cifs_delete_mid (midQ);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 283/339 s390/gmap: voluntarily schedule during key setting
In reply to Greg Kroah-HartmanFrom: Christian Borntraeger <[email protected]>
[ Upstream commit 6d5946274df1fff539a7eece458a43be733d1db8 ]
With large and many guest with storage keys it is possible to create large latencies or stalls during initial key setting:
rcu: INFO: rcu_sched self-detected stall on CPU
rcu: 18-....: (2099 ticks this GP) idle=54e/1/0x4000000000000002 softirq=35598716/35598716 fqs=998
(t=2100 jiffies g=155867385 q=20879)
Task dump for CPU 18:
CPU 1/KVM R running task 0 1030947 256019 0x06000004
Call Trace:sched_show_taskrcu_dump_cpu_stacksrcu_sched_clock_irqupdate_process_timestick_sched_handletick_sched_timer__hrtimer_run_queueshrtimer_interruptdo_IRQext_int_handlerptep_zap_key
The mmap lock is held during the page walking but since this is a semaphore scheduling is still possible. Same for the kvm srcu. To minimize overhead do this on every segment table entry or large page.
--- arch/s390/mm/gmap.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
arch/s390/mm/gmap.c +14 -0
@@ -2608,6 +2608,18 @@ static int __s390_enable_skey_pte(pte_t *pte, unsigned long addr,return 0 ; } +/* +* Give a chance to schedule after setting a key to 256 pages. +* We only hold the mm lock, which is a rwsem and the kvm srcu. +* Both can sleep. +*/ +static int __s390_enable_skey_pmd (pmd_t *pmd,unsigned long addr, +unsigned long next,struct mm_walk *walk) +{ +cond_resched (); +return 0 ; +} +static int __s390_enable_skey_hugetlb (pte_t *pte,unsigned long addr,unsigned long hmask,unsigned long next,struct mm_walk *walk)
@@ -2630,12 +2642,14 @@ static int __s390_enable_skey_hugetlb(pte_t *pte, unsigned long addr, end = start +HPAGE_SIZE -1 ;__storage_key_init_range (start, end);set_bit (PG_arch_1, &page->flags); +cond_resched ();return 0 ; }static const struct mm_walk_ops enable_skey_walk_ops = { .hugetlb_entry = __s390_enable_skey_hugetlb, .pte_entry = __s390_enable_skey_pte, + .pmd_entry = __s390_enable_skey_pmd, };int s390_enable_skey (void )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 284/339 cifs: version operations for smb20 unneeded when legacy support disabled
In reply to Greg Kroah-HartmanFrom: Steve French <[email protected]>
[ Upstream commit 7ef93ffccd55fb0ba000ed16ef6a81cd7dee07b5 ]
We should not be including unused smb20 specific code when legacy support is disabled (CONFIG_CIFS_ALLOW_INSECURE_LEGACY turned off). For example smb2_operations and smb2_values aren't used in that case. Over time we can move more and more SMB1/CIFS and SMB2.0 code into the insecure legacy ifdefs
--- fs/cifs/cifsglob.h | 4 +++- fs/cifs/smb2ops.c | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-)
fs/cifs/cifsglob.h +3 -1
@@ -1929,11 +1929,13 @@ extern mempool_t *cifs_mid_poolp;/* Operations for different SMB versions */ #define SMB1_VERSION_STRING "1.0" +#define SMB20_VERSION_STRING "2.0" +#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY extern struct smb_version_operations smb1_operations;extern struct smb_version_values smb1_values; -#define SMB20_VERSION_STRING "2.0"extern struct smb_version_operations smb20_operations;extern struct smb_version_values smb20_values; +#endif /* CIFS_ALLOW_INSECURE_LEGACY */ #define SMB21_VERSION_STRING "2.1"extern struct smb_version_operations smb21_operations;extern struct smb_version_values smb21_values;
fs/cifs/smb2ops.c +6 -1
@@ -4326,11 +4326,13 @@ smb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, } } +#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY static bool smb2_is_read_op (__u32 oplock) {return oplock ==SMB2_OPLOCK_LEVEL_II ; } +#endif /* CIFS_ALLOW_INSECURE_LEGACY */ static bool smb21_is_read_op (__u32 oplock)
@@ -5429,7 +5431,7 @@ smb2_make_node(unsigned int xid, struct inode *inode,return rc; } - +#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY struct smb_version_operations smb20_operations = { .compare_fids = smb2_compare_fids, .setup_request = smb2_setup_request,
@@ -5528,6 +5530,7 @@ struct smb_version_operations smb20_operations = { .is_status_io_timeout = smb2_is_status_io_timeout, .is_network_name_deleted = smb2_is_network_name_deleted, }; +#endif /* CIFS_ALLOW_INSECURE_LEGACY */ struct smb_version_operations smb21_operations = { .compare_fids = smb2_compare_fids,
@@ -5859,6 +5862,7 @@ struct smb_version_operations smb311_operations = { .is_network_name_deleted = smb2_is_network_name_deleted, }; +#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY struct smb_version_values smb20_values = { .version_string =SMB20_VERSION_STRING , .protocol_id = SMB20_PROT_ID,
@@ -5879,6 +5883,7 @@ struct smb_version_values smb20_values = { .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, .create_lease_size = sizeof(struct create_lease), }; +#endif /* ALLOW_INSECURE_LEGACY */ struct smb_version_values smb21_values = { .version_string =SMB21_VERSION_STRING ,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 285/339 drm/amd/pm: use bitmap_{from,to}_arr32 where appropriate
In reply to Greg Kroah-HartmanFrom: Yury Norov <[email protected]>
[ Upstream commit 525d6515604eb1373ce5e6372a6b6640953b2d6a ]
The smu_v1X_0_set_allowed_mask() uses bitmap_copy() to convert bitmap to 32-bit array. This may be wrong due to endiannes issues. Fix it by switching to bitmap_{from,to}_arr32.
--- drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 2 +- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +1 -1
@@ -781,7 +781,7 @@ int smu_v11_0_set_allowed_mask(struct smu_context *smu) goto failed; } -bitmap_copy ((unsigned long *)feature_mask, feature->allowed,64 ); +bitmap_to_arr32 (feature_mask, feature->allowed,64 ); ret =smu_cmn_send_smc_msg_with_param (smu, SMU_MSG_SetAllowedFeaturesMaskHigh, feature_mask[1 ],NULL );
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +1 -1
@@ -730,7 +730,7 @@ int smu_v13_0_set_allowed_mask(struct smu_context *smu) feature->feature_num < 64)return -EINVAL ; -bitmap_copy ((unsigned long *)feature_mask, feature->allowed,64 ); +bitmap_to_arr32 (feature_mask, feature->allowed,64 ); ret =smu_cmn_send_smc_msg_with_param (smu, SMU_MSG_SetAllowedFeaturesMaskHigh, feature_mask[1 ],NULL );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 286/339 nodemask: Fix return values to be unsigned
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit 0dfe54071d7c828a02917b595456bfde1afdddc9 ]
The nodemask routines had mixed return values that provided potentially signed return values that could never happen. This was leading to the compiler getting confusing about the range of possible return values (it was thinking things could be negative where they could not be). Fix all the nodemask routines that should be returning unsigned (or bool) values. Silences:
mm/swapfile.c: In function ‘setup_swap_info’:
mm/swapfile.c:2291:47: error: array subscript -1 is below array bounds of ‘struct plist_node[]’ [-Werror=array-bounds]
2291 | p->avail_lists[i].prio = 1;
| ~~~~~~~~~~~~~~^~~
In file included from mm/swapfile.c:16:
./include/linux/swap.h:292:27: note: while referencing ‘avail_lists’
292 | struct plist_node avail_lists[]; /*
| ^~~~~~~~~~~--- include/linux/nodemask.h | 38 +++++++++++++++++++------------------- lib/nodemask.c | 4 ++-- 2 files changed, 21 insertions(+), 21 deletions(-)
include/linux/nodemask.h +19 -19
@@ -42,11 +42,11 @@* void nodes_shift_right(dst, src, n) Shift right * void nodes_shift_left(dst, src, n) Shift left * -* int first_node(mask) Number lowest set bit, or MAX_NUMNODES -* int next_node(node, mask) Next node past 'node', or MAX_NUMNODES -* int next_node_in(node, mask) Next node past 'node', or wrap to first, +* unsigned int first_node(mask) Number lowest set bit, or MAX_NUMNODES +* unsigend int next_node(node, mask) Next node past 'node', or MAX_NUMNODES +* unsigned int next_node_in(node, mask) Next node past 'node', or wrap to first, * or MAX_NUMNODES -* int first_unset_node(mask) First node not set in mask, or +* unsigned int first_unset_node(mask) First node not set in mask, or * MAX_NUMNODES * * nodemask_t nodemask_of_node(node) Return nodemask with bit 'node' set
@@ -153,7 +153,7 @@ static inline void __nodes_clear(nodemask_t *dstp, unsigned int nbits)#define node_test_and_set (node, nodemask) \ __node_test_and_set((node), &(nodemask)) -static inline int __node_test_and_set (int node,nodemask_t *addr) +static inline bool __node_test_and_set (int node,nodemask_t *addr) {return test_and_set_bit (node, addr->bits); }
@@ -200,7 +200,7 @@ static inline void __nodes_complement(nodemask_t *dstp,#define nodes_equal (src1, src2) \ __nodes_equal(&(src1), &(src2), MAX_NUMNODES) -static inline int __nodes_equal (const nodemask_t *src1p, +static inline bool __nodes_equal (const nodemask_t *src1p,const nodemask_t *src2p,unsigned int nbits) {return bitmap_equal (src1p->bits, src2p->bits, nbits);
@@ -208,7 +208,7 @@ static inline int __nodes_equal(const nodemask_t *src1p,#define nodes_intersects (src1, src2) \ __nodes_intersects(&(src1), &(src2), MAX_NUMNODES) -static inline int __nodes_intersects (const nodemask_t *src1p, +static inline bool __nodes_intersects (const nodemask_t *src1p,const nodemask_t *src2p,unsigned int nbits) {return bitmap_intersects (src1p->bits, src2p->bits, nbits);
@@ -216,20 +216,20 @@ static inline int __nodes_intersects(const nodemask_t *src1p,#define nodes_subset (src1, src2) \ __nodes_subset(&(src1), &(src2), MAX_NUMNODES) -static inline int __nodes_subset (const nodemask_t *src1p, +static inline bool __nodes_subset (const nodemask_t *src1p,const nodemask_t *src2p,unsigned int nbits) {return bitmap_subset (src1p->bits, src2p->bits, nbits); }#define nodes_empty (src) __nodes_empty(&(src), MAX_NUMNODES) -static inline int __nodes_empty (const nodemask_t *srcp,unsigned int nbits) +static inline bool __nodes_empty (const nodemask_t *srcp,unsigned int nbits) {return bitmap_empty (srcp->bits, nbits); }#define nodes_full (nodemask) __nodes_full(&(nodemask), MAX_NUMNODES) -static inline int __nodes_full (const nodemask_t *srcp,unsigned int nbits) +static inline bool __nodes_full (const nodemask_t *srcp,unsigned int nbits) {return bitmap_full (srcp->bits, nbits); }
@@ -260,15 +260,15 @@ static inline void __nodes_shift_left(nodemask_t *dstp,> MAX_NUMNODES, then the silly min_ts could be dropped. */ #define first_node (src) __first_node(&(src)) -static inline int __first_node (const nodemask_t *srcp) +static inline unsigned int __first_node (const nodemask_t *srcp) { -return min_t (int,MAX_NUMNODES ,find_first_bit (srcp->bits,MAX_NUMNODES )); + return min_t(unsigned int, MAX_NUMNODES, find_first_bit(srcp->bits, MAX_NUMNODES)); }#define next_node (n, src) __next_node((n), &(src)) -static inline int __next_node (int n,const nodemask_t *srcp) +static inline unsigned int __next_node (int n,const nodemask_t *srcp) { -return min_t (int,MAX_NUMNODES ,find_next_bit (srcp->bits,MAX_NUMNODES , n+1 )); + return min_t(unsigned int, MAX_NUMNODES, find_next_bit(srcp->bits, MAX_NUMNODES, n+1)); }/*
@@ -276,7 +276,7 @@ static inline int __next_node(int n, const nodemask_t *srcp)* the first node in src if needed. Returns MAX_NUMNODES if src is empty. */ #define next_node_in (n, src) __next_node_in((n), &(src)) -int __next_node_in (int node,const nodemask_t *srcp); +unsigned int __next_node_in (int node,const nodemask_t *srcp);static inline void init_nodemask_of_node (nodemask_t *mask,int node) {
@@ -296,9 +296,9 @@ static inline void init_nodemask_of_node(nodemask_t *mask, int node) })#define first_unset_node (mask) __first_unset_node(&(mask)) -static inline int __first_unset_node (const nodemask_t *maskp) +static inline unsigned int __first_unset_node (const nodemask_t *maskp) { -return min_t (int,MAX_NUMNODES , + return min_t(unsigned int, MAX_NUMNODES,find_first_zero_bit (maskp->bits,MAX_NUMNODES )); }
@@ -435,11 +435,11 @@ static inline int num_node_state(enum node_states state)#define first_online_node first_node(node_states[N_ONLINE])#define first_memory_node first_node(node_states[N_MEMORY]) -static inline int next_online_node (int nid) +static inline unsigned int next_online_node (int nid) {return next_node (nid, node_states[N_ONLINE ]); } -static inline int next_memory_node (int nid) +static inline unsigned int next_memory_node (int nid) {return next_node (nid, node_states[N_MEMORY ]); }
lib/nodemask.c +2 -2
@@ -3,9 +3,9 @@#include <linux/module.h> #include <linux/random.h> -int __next_node_in (int node,const nodemask_t *srcp) +unsigned int __next_node_in (int node,const nodemask_t *srcp) { -int ret =__next_node (node, srcp); +unsigned int ret =__next_node (node, srcp);if (ret ==MAX_NUMNODES ) ret =__first_node (srcp);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 287/339 scsi: lpfc: Correct BDE type for XMIT_SEQ64_WQE in lpfc_ct_reject_event()
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit 44ba9786b67345dc4e5eabe537c9ef2bfd889888 ]
A previous commit assumed all XMIT_SEQ64_WQEs are prepped with the correct BDE type in word 0-2. However, lpfc_ct_reject_event() routine was missed and is still filling out the incorrect BDE type.
Fix lpfc_ct_reject_event() routine so that type BUFF_TYPE_BDE_64 is set instead of BUFF_TYPE_BLP_64.
--- drivers/scsi/lpfc/lpfc_ct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/lpfc/lpfc_ct.c +1 -1
@@ -197,7 +197,7 @@ lpfc_ct_reject_event(struct lpfc_nodelist *ndlp,memset (bpl,0 ,sizeof (struct ulp_bde64 )); bpl->addrHigh =le32_to_cpu (putPaddrHigh (mp->phys)); bpl->addrLow =le32_to_cpu (putPaddrLow (mp->phys)); - bpl->tus.f.bdeFlags =BUFF_TYPE_BLP_64 ; + bpl->tus.f.bdeFlags =BUFF_TYPE_BDE_64 ; bpl->tus.f.bdeSize = (LPFC_CT_PREAMBLE -4 ); bpl->tus.w =le32_to_cpu (bpl->tus.w);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 288/339 vringh: Fix loop descriptors check in the indirect cases
In reply to Greg Kroah-HartmanFrom: Xie Yongji <[email protected]>
[ Upstream commit dbd29e0752286af74243cf891accf472b2f3edd8 ]
We should use size of descriptor chain to test loop condition in the indirect case. And another statistical count is also introduced for indirect descriptors to avoid conflict with the statistical count of direct descriptors.
Message-Id: <[email protected]>
--- drivers/vhost/vringh.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/vhost/vringh.c +8 -2
@@ -292,7 +292,7 @@ __vringh_iov(struct vringh *vrh, u16 i,int (*copy)(const struct vringh *vrh, void *dst, const void *src, size_t len)) { -int err, count =0 , up_next, desc_max; +int err, count =0 , indirect_count =0 , up_next, desc_max;struct vring_desc desc, *descs;struct vringh_range range = {-1ULL ,0 }, slowrange;bool slow = false;
@@ -349,7 +349,12 @@ __vringh_iov(struct vringh *vrh, u16 i,continue ; } -if (count++ == vrh->vring.num) { +if (up_next ==-1 ) + count++; +else + indirect_count++; + +if (count > vrh->vring.num || indirect_count > desc_max) {vringh_bad ("Descriptor loop in %p" , descs); err = -ELOOP ; goto fail;
@@ -411,6 +416,7 @@ __vringh_iov(struct vringh *vrh, u16 i, i =return_from_indirect (vrh, &up_next, &descs, &desc_max); slow = false; + indirect_count =0 ; }else break ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 289/339 platform/x86: barco-p50-gpio: Add check for platform_driver_register
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 011881b80ebe773914b59905bce0f5e0ef93e7ba ]
As platform_driver_register() could fail, it should be better to deal with the return value in order to maintain the code consisitency.
--- drivers/platform/x86/barco-p50-gpio.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/platform/x86/barco-p50-gpio.c +4 -1
@@ -405,11 +405,14 @@ MODULE_DEVICE_TABLE(dmi, dmi_ids);static int __init p50_module_init (void ) {struct resource res =DEFINE_RES_IO (P50_GPIO_IO_PORT_BASE ,P50_PORT_CMD +1 ); +int ret;if (!dmi_first_match (dmi_ids))return -ENODEV ; -platform_driver_register (&p50_gpio_driver); + ret =platform_driver_register (&p50_gpio_driver); +if (ret) +return ret; gpio_pdev =platform_device_register_simple (DRIVER_NAME ,PLATFORM_DEVID_NONE , &res,1 );if (IS_ERR (gpio_pdev)) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 290/339 scripts/gdb: change kernel config dumping method
In reply to Greg Kroah-HartmanFrom: Kuan-Ying Lee <[email protected]>
[ Upstream commit 1f7a6cf6b07c74a17343c2559cd5f5018a245961 ]
MAGIC_START("IKCFG_ST") and MAGIC_END("IKCFG_ED") are moved out from the kernel_config_data variable.
Thus, we parse kernel_config_data directly instead of considering offset of MAGIC_START and MAGIC_END.
--- scripts/gdb/linux/config.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
scripts/gdb/linux/config.py +3 -3
@@ -24,9 +24,9 @@ class LxConfigDump(gdb.Command): filename = arg try: - py_config_ptr = gdb.parse_and_eval("kernel_config_data + 8") - py_config_size = gdb.parse_and_eval( - "sizeof(kernel_config_data) - 1 - 8 * 2") + py_config_ptr = gdb.parse_and_eval("&kernel_config_data") + py_config_ptr_end = gdb.parse_and_eval("&kernel_config_data_end") + py_config_size = py_config_ptr_end - py_config_ptr except gdb.error as e: raise gdb.GdbError("Can't find config, enable CONFIG_IKCONFIG?")
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 291/339 platform/x86: hp-wmi: Resolve WMI query failures on some devices
In reply to Greg Kroah-HartmanFrom: Jorge Lopez <[email protected]>
[ Upstream commit dc6a6ab58379f25bf991d8e4a13b001ed806e881 ]
WMI queries fail on some devices where the ACPI method HWMC unconditionally attempts to create Fields beyond the buffer if the buffer is too small, this breaks essential features such as power profiles:
CreateByteField (Arg1, 0x10, D008)
CreateByteField (Arg1, 0x11, D009)
CreateByteField (Arg1, 0x12, D010)
CreateDWordField (Arg1, 0x10, D032)
CreateField (Arg1, 0x80, 0x0400, D128)In cases where args->data had zero length, ACPI BIOS Error (bug): AE_AML_BUFFER_LIMIT, Field [D008] at bit offset/length 128/8 exceeds size of target Buffer (128 bits) (20211217/dsopcode-198) was obtained.
ACPI BIOS Error (bug): AE_AML_BUFFER_LIMIT, Field [D009] at bit offset/length 136/8 exceeds size of target Buffer (136bits) (20211217/dsopcode-198)
The original code created a buffer size of 128 bytes regardless if the WMI call required a smaller buffer or not. This particular behavior occurs in older BIOS and reproduced in OMEN laptops. Newer BIOS handles buffer sizes properly and meets the latest specification requirements. This is the reason why testing with a dynamically allocated buffer did not uncover any failures with the test systems at hand.
This patch was tested on several OMEN, Elite, and Zbooks. It was confirmed the patch resolves HPWMI_FAN GET/SET calls in an OMEN Laptop 15-ek0xxx. No problems were reported when testing on several Elite and Zbooks notebooks.
--- drivers/platform/x86/hp-wmi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/platform/x86/hp-wmi.c +4 -2
@@ -290,14 +290,16 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command,struct bios_return *bios_return;union acpi_object *obj =NULL ;struct bios_args *args =NULL ; -int mid, actual_outsize, ret; +int mid, actual_insize, actual_outsize;size_t bios_args_size; +int ret; mid =encode_outsize_for_pvsz (outsize);if (WARN_ON (mid <0 ))return mid; - bios_args_size =struct_size (args, data, insize); + actual_insize =max (insize,128 ); + bios_args_size =struct_size (args, data, actual_insize); args =kmalloc (bios_args_size,GFP_KERNEL );if (!args)return -ENOMEM ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 292/339 platform/x86: hp-wmi: Use zero insize parameter only when supported
In reply to Greg Kroah-HartmanFrom: Bedant Patnaik <[email protected]>
[ Upstream commit 65f936f3535950d2643eac5bf34a735a0e428cdd ]
commit be9d73e64957 ("platform/x86: hp-wmi: Fix 0x05 error code reported by several WMI calls") and commit 12b19f14a21a ("platform/x86: hp-wmi: Fix hp_wmi_read_int() reporting error (0x05)") cause ACPI BIOS Error (bug):
Attempt to CreateField of length zero (20211217/dsopcode-133) because of the ACPI method HWMC, which unconditionally creates a Field of size (insize*8) bits:
CreateField (Arg1, 0x80, (Local5 * 0x08), DAIN)
In cases where args->insize = 0, the Field size is 0, resulting in an error.
Fix this by using zero insize only if 0x5 error code is returned
Tested on Omen 15 AMD (2020) board ID: 8786.
--- drivers/platform/x86/hp-wmi.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
drivers/platform/x86/hp-wmi.c +15 -8
@@ -38,6 +38,7 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE9#define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C"#define HPWMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4"#define HP_OMEN_EC_THERMAL_PROFILE_OFFSET 0x95 +#define zero_if_sup (tmp) (zero_insize_support?0:sizeof(tmp)) // use when zero insize is required/* DMI board names of devices that should use the omen specific path for * thermal profiles.
@@ -220,6 +221,7 @@ static struct input_dev *hp_wmi_input_destatic struct platform_device *hp_wmi_platform_dev;static struct platform_profile_handler platform_profile_handler;static bool platform_profile_support; +static bool zero_insize_support;static struct rfkill *wifi_rfkill;static struct rfkill *bluetooth_rfkill;
@@ -376,7 +378,7 @@ static int hp_wmi_read_int(int query)int val =0 , ret; ret =hp_wmi_perform_query (query,HPWMI_READ , &val, -0 ,sizeof (val)); +zero_if_sup (val),sizeof (val));if (ret)return ret <0 ? ret : -EINVAL ;
@@ -412,7 +414,8 @@ static int hp_wmi_get_tablet_mode(void)return -ENODEV ; ret =hp_wmi_perform_query (HPWMI_SYSTEM_DEVICE_MODE ,HPWMI_READ , - system_device_mode,0 ,sizeof (system_device_mode)); + system_device_mode,zero_if_sup (system_device_mode), +sizeof (system_device_mode));if (ret <0 )return ret;
@@ -499,7 +502,7 @@ static int hp_wmi_fan_speed_max_get(voidint val =0 , ret; ret =hp_wmi_perform_query (HPWMI_FAN_SPEED_MAX_GET_QUERY ,HPWMI_GM , - &val,0 ,sizeof (val)); + &val,zero_if_sup (val),sizeof (val));if (ret)return ret <0 ? ret : -EINVAL ;
@@ -511,7 +514,7 @@ static int __init hp_wmi_bios_2008_later {int state =0 ;int ret =hp_wmi_perform_query (HPWMI_FEATURE_QUERY ,HPWMI_READ , &state, -0 ,sizeof (state)); +zero_if_sup (state),sizeof (state));if (!ret)return 1 ;
@@ -522,7 +525,7 @@ static int __init hp_wmi_bios_2009_later {u8 state[128 ];int ret =hp_wmi_perform_query (HPWMI_FEATURE2_QUERY ,HPWMI_READ , &state, -0 ,sizeof (state)); +zero_if_sup (state),sizeof (state));if (!ret)return 1 ;
@@ -600,7 +603,7 @@ static int hp_wmi_rfkill2_refresh(void)int err, i; err =hp_wmi_perform_query (HPWMI_WIRELESS2_QUERY ,HPWMI_READ , &state, -0 ,sizeof (state)); +zero_if_sup (state),sizeof (state));if (err)return err;
@@ -1002,7 +1005,7 @@ static int __init hp_wmi_rfkill2_setup(sint err, i; err =hp_wmi_perform_query (HPWMI_WIRELESS2_QUERY ,HPWMI_READ , &state, -0 ,sizeof (state)); +zero_if_sup (state),sizeof (state));if (err)return err <0 ? err : -EINVAL ;
@@ -1477,11 +1480,15 @@ static int __init hp_wmi_init(void) {int event_capable =wmi_has_guid (HPWMI_EVENT_GUID );int bios_capable =wmi_has_guid (HPWMI_BIOS_GUID ); -int err; +int err, tmp =0 ;if (!bios_capable && !event_capable)return -ENODEV ; +if (hp_wmi_perform_query (HPWMI_HARDWARE_QUERY ,HPWMI_READ , &tmp, +sizeof (tmp),sizeof (tmp)) ==HPWMI_RET_INVALID_PARAMETERS ) + zero_insize_support = true; +if (event_capable) { err =hp_wmi_input_setup ();if (err)