6.6.93-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainerPATCH 278/444 bridge: mdb: Allow replace of a host-joined group
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Machata <[email protected]>
[ Upstream commit d9e9f6d7b7d0c520bb87f19d2cbc57aeeb2091d5 ]
Attempts to replace an MDB group membership of the host itself are currently bounced:
# ip link add name br up type bridge vlan_filtering 1 # bridge mdb replace dev br port br grp 239.0.0.1 vid 2 # bridge mdb replace dev br port br grp 239.0.0.1 vid 2 Error: bridge: Group is already joined by host.
A similar operation done on a member port would succeed. Ignore the check for replacement of host group memberships as well.
The bit of code that this enables is br_multicast_host_join(), which, for already-joined groups only refreshes the MC group expiration timer, which is desirable; and a userspace notification, also desirable.
Change a selftest that exercises this code path from expecting a rejection to expecting a pass. The rest of MDB selftests pass without modification.
--- net/bridge/br_mdb.c | 2 +- tools/testing/selftests/net/forwarding/bridge_mdb.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
net/bridge/br_mdb.c +1 -1
@@ -1030,7 +1030,7 @@ static int br_mdb_add_group(const struct br_mdb_config *cfg,/* host join */ if (!port) { -if (mp->host_joined) { +if (mp->host_joined && !(cfg->nlflags &NLM_F_REPLACE )) {NL_SET_ERR_MSG_MOD (extack,"Group is already joined by host" );return -EEXIST ; }
tools/testing/selftests/net/forwarding/bridge_mdb.sh +1 -1
@@ -149,7 +149,7 @@ cfg_test_host_common() check_err $? "Failed to add $name host entry" bridge mdb replace dev br0 port br0 grp $grp $state vid 10 &> /dev/null - check_fail $? "Managed to replace $name host entry" + check_err $? "Failed to replace $name host entry" bridge mdb del dev br0 port br0 grp $grp $state vid 10 bridge mdb get dev br0 grp $grp vid 10 &> /dev/null
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 279/444 ice: treat dyn_allowed only as suggestion
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Swiatkowski <[email protected]>
[ Upstream commit a8c2d3932c1106af2764cc6869b29bcf3cb5bc47 ]
It can be needed to have some MSI-X allocated as static and rest as dynamic. For example on PF VSI. We want to always have minimum one MSI-X on it, because of that it is allocated as a static one, rest can be dynamic if it is supported.
Change the ice_get_irq_res() to allow using static entries if they are free even if caller wants dynamic one.
Adjust limit values to the new approach. Min and max in limit means the values that are valid, so decrease max and num_static by one.
Set vsi::irq_dyn_alloc if dynamic allocation is supported.
--- drivers/net/ethernet/intel/ice/ice_irq.c | 25 ++++++++++++------------ drivers/net/ethernet/intel/ice/ice_lib.c | 2 ++ 2 files changed, 15 insertions(+), 12 deletions(-)
drivers/net/ethernet/intel/ice/ice_irq.c +13 -12
@@ -45,7 +45,7 @@ static void ice_free_irq_res(struct ice_pf *pf, u16 index)/** * ice_get_irq_res - get an interrupt resource * @pf: board private structure -* @dyn_only: force entry to be dynamically allocated +* @dyn_allowed: allow entry to be dynamically allocated * * Allocate new irq entry in the free slot of the tracker. Since xarray * is used, always allocate new entry at the lowest possible index. Set
@@ -53,11 +53,12 @@ static void ice_free_irq_res(struct ice_pf *pf, u16 index)* * Returns allocated irq entry or NULL on failure. */ -static struct ice_irq_entry *ice_get_irq_res (struct ice_pf *pf,bool dyn_only) +static struct ice_irq_entry *ice_get_irq_res (struct ice_pf *pf, +bool dyn_allowed) { -struct xa_limit limit = { .max = pf->irq_tracker.num_entries, +struct xa_limit limit = { .max = pf->irq_tracker.num_entries -1 , .min =0 }; -unsigned int num_static = pf->irq_tracker.num_static; +unsigned int num_static = pf->irq_tracker.num_static -1 ;struct ice_irq_entry *entry;unsigned int index;int ret;
@@ -66,9 +67,9 @@ static struct ice_irq_entry *ice_get_irq_res(struct ice_pf *pf, bool dyn_only)if (!entry)return NULL ; -/* skip preallocated entries if the caller says so */ -if (dyn_only) - limit.min = num_static; +/* only already allocated if the caller says so */ +if (!dyn_allowed) + limit.max = num_static; ret =xa_alloc (&pf->irq_tracker.entries, &index, entry, limit,GFP_KERNEL );
@@ -78,7 +79,7 @@ static struct ice_irq_entry *ice_get_irq_res(struct ice_pf *pf, bool dyn_only) entry =NULL ; }else { entry->index = index; - entry->dynamic = index >= num_static; + entry->dynamic = index > num_static; }return entry;
@@ -272,7 +273,7 @@ int ice_init_interrupt_scheme(struct ice_pf *pf)/** * ice_alloc_irq - Allocate new interrupt vector * @pf: board private structure -* @dyn_only: force dynamic allocation of the interrupt +* @dyn_allowed: allow dynamic allocation of the interrupt * * Allocate new interrupt vector for a given owner id. * return struct msi_map with interrupt details and track
@@ -285,20 +286,20 @@ int ice_init_interrupt_scheme(struct ice_pf *pf)* interrupt will be allocated with pci_msix_alloc_irq_at. * * Some callers may only support dynamically allocated interrupts. -* This is indicated with dyn_only flag. +* This is indicated with dyn_allowed flag. * * On failure, return map with negative .index. The caller * is expected to check returned map index. * */ -struct msi_map ice_alloc_irq (struct ice_pf *pf,bool dyn_only) +struct msi_map ice_alloc_irq (struct ice_pf *pf,bool dyn_allowed) {int sriov_base_vector = pf->sriov_base_vector;struct msi_map map = { .index = -ENOENT };struct device *dev =ice_pf_to_dev (pf);struct ice_irq_entry *entry; - entry =ice_get_irq_res (pf, dyn_only); + entry =ice_get_irq_res (pf, dyn_allowed);if (!entry)return map;
drivers/net/ethernet/intel/ice/ice_lib.c +2 -0
@@ -587,6 +587,8 @@ ice_vsi_alloc_def(struct ice_vsi *vsi, struct ice_channel *ch)return -ENOMEM ; } + vsi->irq_dyn_alloc =pci_msix_can_alloc_dyn (vsi->back->pdev); +switch (vsi->type) {case ICE_VSI_SWITCHDEV_CTRL :/* Setup eswitch MSIX irq handler for VSI */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 280/444 rcu: handle quiescent states for PREEMPT_RCU=n, PREEMPT_COUNT=y
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ankur Arora <[email protected]>
[ Upstream commit 83b28cfe796464ebbde1cf7916c126da6d572685 ]
With PREEMPT_RCU=n, cond_resched() provides urgently needed quiescent states for read-side critical sections via rcu_all_qs(). One reason why this was needed: lacking preempt-count, the tick handler has no way of knowing whether it is executing in a read-side critical section or not.
With (PREEMPT_LAZY=y, PREEMPT_DYNAMIC=n), we get (PREEMPT_COUNT=y, PREEMPT_RCU=n). In this configuration cond_resched() is a stub and does not provide quiescent states via rcu_all_qs(). (PREEMPT_RCU=y provides this information via rcu_read_unlock() and its nesting counter.)
So, use the availability of preempt_count() to report quiescent states in rcu_flavor_sched_clock_irq().
--- kernel/rcu/tree_plugin.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
kernel/rcu/tree_plugin.h +7 -4
@@ -963,13 +963,16 @@ static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)*/ static void rcu_flavor_sched_clock_irq (int user) { -if (user ||rcu_is_cpu_rrupt_from_idle ()) { +if (user ||rcu_is_cpu_rrupt_from_idle () || + (IS_ENABLED (CONFIG_PREEMPT_COUNT ) && + (preempt_count () ==HARDIRQ_OFFSET ))) {/* * Get here if this CPU took its interrupt from user -* mode or from the idle loop, and if this is not a -* nested interrupt. In this case, the CPU is in -* a quiescent state, so note it. +* mode, from the idle loop without this being a nested +* interrupt, or while not holding the task preempt count +* (with PREEMPT_COUNT=y). In this case, the CPU is in a +* quiescent state, so note it. * * No memory barrier is required here because rcu_qs() * references only CPU-local variables that other CPUs
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 281/444 rcu: handle unstable rdp in rcu_read_unlock_strict()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ankur Arora <[email protected]>
[ Upstream commit fcf0e25ad4c8d14d2faab4d9a17040f31efce205 ]
rcu_read_unlock_strict() can be called with preemption enabled which can make for an unstable rdp and a racy norm value.
Fix this by dropping the preempt-count in __rcu_read_unlock() after the call to rcu_read_unlock_strict(), adjusting the preempt-count check appropriately.
--- include/linux/rcupdate.h | 2 +- kernel/rcu/tree_plugin.h | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-)
include/linux/rcupdate.h +1 -1
@@ -97,9 +97,9 @@ static inline void __rcu_read_lock(void)static inline void __rcu_read_unlock (void ) { -preempt_enable ();if (IS_ENABLED (CONFIG_RCU_STRICT_GRACE_PERIOD ))rcu_read_unlock_strict (); +preempt_enable (); }static inline int rcu_preempt_depth (void )
kernel/rcu/tree_plugin.h +10 -1
@@ -821,8 +821,17 @@ void rcu_read_unlock_strict(void) {struct rcu_data *rdp; -if (irqs_disabled () ||preempt_count () || !rcu_state.gp_kthread) +if (irqs_disabled () ||in_atomic_preempt_off () || !rcu_state.gp_kthread)return ; + +/* +* rcu_report_qs_rdp() can only be invoked with a stable rdp and +* from the local CPU. +* +* The in_atomic_preempt_off() check ensures that we come here holding +* the last preempt_count (which will get dropped once we return to +* __rcu_read_unlock(). +*/ rdp =this_cpu_ptr (&rcu_data); rdp->cpu_no_qs.b.norm = false;rcu_report_qs_rdp (rdp);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 282/444 rcu: fix header guard for rcu_all_qs()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ankur Arora <[email protected]>
[ Upstream commit ad6b5b73ff565e88aca7a7d1286788d80c97ba71 ]
rcu_all_qs() is defined for !CONFIG_PREEMPT_RCU but the declaration is conditioned on CONFIG_PREEMPTION.
With CONFIG_PREEMPT_LAZY, CONFIG_PREEMPTION=y does not imply CONFIG_PREEMPT_RCU=y.
Decouple the two.
--- include/linux/rcutree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/rcutree.h +1 -1
@@ -104,7 +104,7 @@ extern int rcu_scheduler_active;void rcu_end_inkernel_boot (void );bool rcu_inkernel_boot_has_ended (void );bool rcu_is_watching (void ); -#ifndef CONFIG_PREEMPTION +#ifndef CONFIG_PREEMPT_RCU void rcu_all_qs (void );#endif
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 283/444 perf: Avoid the read if the count is already updated
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra (Intel) <[email protected]>
[ Upstream commit 8ce939a0fa194939cc1f92dbd8bc1a7806e7d40a ]
The event may have been updated in the PMU-specific implementation, e.g., Intel PEBS counters snapshotting. The common code should not read and overwrite the value.
The PERF_SAMPLE_READ in the data->sample_type can be used to detect whether the PMU-specific value is available. If yes, avoid the pmu->read() in the common code. Add a new flag, skip_read, to track the case.
Factor out a perf_pmu_read() to clean up the code.
--- include/linux/perf_event.h | 8 +++++++- kernel/events/core.c | 33 ++++++++++++++++----------------- kernel/events/ring_buffer.c | 1 + 3 files changed, 24 insertions(+), 18 deletions(-)
include/linux/perf_event.h +7 -1
@@ -1016,7 +1016,13 @@ struct perf_output_handle {struct perf_buffer *rb;unsigned long wakeup;unsigned long size; -u64 aux_flags; +union { +u64 flags;/* perf_output*() */ +u64 aux_flags;/* perf_aux_output*() */ +struct { +u64 skip_read :1 ; + }; + };union {void *addr;unsigned long head;
kernel/events/core.c +16 -17
@@ -1163,6 +1163,12 @@ static void perf_assert_pmu_disabled(struct pmu *pmu)WARN_ON_ONCE (*this_cpu_ptr (pmu->pmu_disable_count) ==0 ); } +static inline void perf_pmu_read (struct perf_event *event) +{ +if (event->state ==PERF_EVENT_STATE_ACTIVE ) + event->pmu->read (event); +} +static void get_ctx (struct perf_event_context *ctx) {refcount_inc (&ctx->refcount);
@@ -3397,8 +3403,7 @@ static void __perf_event_sync_stat(struct perf_event *event,* we know the event must be on the current CPU, therefore we * don't need to use it. */ -if (event->state ==PERF_EVENT_STATE_ACTIVE ) - event->pmu->read (event); +perf_pmu_read (event);perf_event_update_time (event);
@@ -4524,15 +4529,8 @@ static void __perf_event_read(void *info) pmu->read (event); -for_each_sibling_event (sub, event) { -if (sub->state ==PERF_EVENT_STATE_ACTIVE ) { -/* -* Use sibling's PMU rather than @event's since -* sibling could be on different (eg: software) PMU. -*/ - sub->pmu->read (sub); - } - } +for_each_sibling_event (sub, event) +perf_pmu_read (sub); data->ret = pmu->commit_txn (pmu);
@@ -7297,9 +7295,8 @@ static void perf_output_read_group(struct perf_output_handle *handle,if (read_format &PERF_FORMAT_TOTAL_TIME_RUNNING ) values[n++] = running; -if ((leader != event) && - (leader->state ==PERF_EVENT_STATE_ACTIVE )) - leader->pmu->read (leader); +if ((leader != event) && !handle->skip_read) +perf_pmu_read (leader); values[n++] =perf_event_count (leader);if (read_format &PERF_FORMAT_ID )
@@ -7312,9 +7309,8 @@ static void perf_output_read_group(struct perf_output_handle *handle,for_each_sibling_event (sub, leader) { n =0 ; -if ((sub != event) && - (sub->state ==PERF_EVENT_STATE_ACTIVE )) - sub->pmu->read (sub); +if ((sub != event) && !handle->skip_read) +perf_pmu_read (sub); values[n++] =perf_event_count (sub);if (read_format &PERF_FORMAT_ID )
@@ -7369,6 +7365,9 @@ void perf_output_sample(struct perf_output_handle *handle, {u64 sample_type = data->type; +if (data->sample_flags &PERF_SAMPLE_READ ) + handle->skip_read =1 ; +perf_output_put (handle, *header);if (sample_type &PERF_SAMPLE_IDENTIFIER )
kernel/events/ring_buffer.c +1 -0
@@ -181,6 +181,7 @@ __perf_output_begin(struct perf_output_handle *handle, handle->rb = rb; handle->event = event; + handle->flags =0 ; have_lost =local_read (&rb->lost);if (unlikely (have_lost)) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 284/444 ice: count combined queues using Rx/Tx count
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Swiatkowski <[email protected]>
[ Upstream commit c3a392bdd31adc474f1009ee85c13fdd01fe800d ]
Previous implementation assumes that there is 1:1 matching between vectors and queues. It isn't always true.
Get minimum value from Rx/Tx queues to determine combined queues number.
--- drivers/net/ethernet/intel/ice/ice_ethtool.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/ethernet/intel/ice/ice_ethtool.c +1 -2
@@ -3329,8 +3329,7 @@ static u32 ice_get_combined_cnt(struct ice_vsi *vsi)ice_for_each_q_vector (vsi, q_idx) {struct ice_q_vector *q_vector = vsi->q_vectors[q_idx]; -if (q_vector->rx.rx_ring && q_vector->tx.tx_ring) - combined++; + combined +=min (q_vector->num_ring_tx, q_vector->num_ring_rx); }return combined;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 285/444 net/mana: fix warning in the writer of client oob
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Taranov <[email protected]>
[ Upstream commit 5ec7e1c86c441c46a374577bccd9488abea30037 ]
Do not warn on missing pad_data when oob is in sgl.
--- drivers/net/ethernet/microsoft/mana/gdma_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/microsoft/mana/gdma_main.c +1 -1
@@ -1036,7 +1036,7 @@ static u32 mana_gd_write_client_oob(const struct gdma_wqe_request *wqe_req, header->inline_oob_size_div4 = client_oob_size /sizeof (u32);if (oob_in_sgl) { -WARN_ON_ONCE (!pad_data || wqe_req->num_sge <2 ); +WARN_ON_ONCE (wqe_req->num_sge <2 ); header->client_oob_in_sgl =1 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 286/444 scsi: lpfc: Handle duplicate D_IDs in ndlp search-by D_ID routine
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Tee <[email protected]>
[ Upstream commit 56c3d809b7b450379162d0b8a70bbe71ab8db706 ]
After a port swap between separate fabrics, there may be multiple nodes in the vport's fc_nodes list with the same fabric well known address. Duplication is temporary and eventually resolves itself after dev_loss_tmo expires, but nameserver queries may still occur before dev_loss_tmo. This possibly results in returning stale fabric ndlp objects. Fix by adding an nlp_state check to ensure the ndlp search routine returns the correct newer allocated ndlp fabric object.
--- drivers/scsi/lpfc/lpfc_hbadisc.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
drivers/scsi/lpfc/lpfc_hbadisc.c +12 -5
@@ -5646,6 +5646,7 @@ static struct lpfc_nodelist * __lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did) {struct lpfc_nodelist *ndlp; +struct lpfc_nodelist *np =NULL ;uint32_t data1;list_for_each_entry (ndlp, &vport->fc_nodes, nlp_listp) {
@@ -5660,14 +5661,20 @@ __lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did) ndlp, ndlp->nlp_DID, ndlp->nlp_flag, data1, ndlp->nlp_rpi, ndlp->active_rrqs_xri_bitmap); -return ndlp; + +/* Check for new or potentially stale node */ +if (ndlp->nlp_state !=NLP_STE_UNUSED_NODE ) +return ndlp; + np = ndlp; } } -/* FIND node did <did> NOT FOUND */ -lpfc_printf_vlog (vport,KERN_INFO ,LOG_NODE , -"0932 FIND node did x%x NOT FOUND.\n" , did); -return NULL ; +if (!np) +/* FIND node did <did> NOT FOUND */ +lpfc_printf_vlog (vport,KERN_INFO ,LOG_NODE , +"0932 FIND node did x%x NOT FOUND.\n" , did); + +return np; } struct lpfc_nodelist *
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 287/444 scsi: lpfc: Free phba irq in lpfc_sli4_enable_msi() when pci_irq_vector() fails
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Tee <[email protected]>
[ Upstream commit f0842902b383982d1f72c490996aa8fc29a7aa0d ]
Fix smatch warning regarding missed calls to free_irq(). Free the phba IRQ in the failed pci_irq_vector cases.
lpfc_init.c: lpfc_sli4_enable_msi() warn: 'phba->pcidev->irq' from
request_irq() not released.
--- drivers/scsi/lpfc/lpfc_init.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/scsi/lpfc/lpfc_init.c +2 -0
@@ -13180,6 +13180,7 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba) eqhdl =lpfc_get_eq_hdl (0 ); rc =pci_irq_vector (phba->pcidev,0 );if (rc <0 ) { +free_irq (phba->pcidev->irq, phba);pci_free_irq_vectors (phba->pcidev);lpfc_printf_log (phba,KERN_WARNING ,LOG_INIT ,"0496 MSI pci_irq_vec failed (%d)\n" , rc);
@@ -13260,6 +13261,7 @@ lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode) eqhdl =lpfc_get_eq_hdl (0 ); retval =pci_irq_vector (phba->pcidev,0 );if (retval <0 ) { +free_irq (phba->pcidev->irq, phba);lpfc_printf_log (phba,KERN_WARNING ,LOG_INIT ,"0502 INTR pci_irq_vec failed (%d)\n" , retval);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 288/444 scsi: st: Restore some drive settings after reset
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kai Mäkisara <[email protected]>
[ Upstream commit 7081dc75df79696d8322d01821c28e53416c932c ]
Some of the allowed operations put the tape into a known position to continue operation assuming only the tape position has changed. But reset sets partition, density and block size to drive default values. These should be restored to the values before reset.
Normally the current block size and density are stored by the drive. If the settings have been changed, the changed values have to be saved by the driver across reset.
--- drivers/scsi/st.c | 24 +++++++++++++++++++++--- drivers/scsi/st.h | 2 ++ 2 files changed, 23 insertions(+), 3 deletions(-)
drivers/scsi/st.c +21 -3
@@ -953,7 +953,6 @@ static void reset_state(struct scsi_tape *STp) STp->partition =find_partition (STp);if (STp->partition <0 ) STp->partition =0 ; - STp->new_partition = STp->partition; } }
@@ -2927,14 +2926,17 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lonif (cmd_in ==MTSETDENSITY ) { (STp->buffer)->b_data[4 ] = arg; STp->density_changed =1 ;/* At least we tried ;-) */ + STp->changed_density = arg; }else if (cmd_in ==SET_DENS_AND_BLK ) (STp->buffer)->b_data[4 ] = arg >>24 ;else (STp->buffer)->b_data[4 ] = STp->density;if (cmd_in ==MTSETBLK || cmd_in ==SET_DENS_AND_BLK ) { ltmp = arg &MT_ST_BLKSIZE_MASK ; -if (cmd_in ==MTSETBLK ) +if (cmd_in ==MTSETBLK ) { STp->blksize_changed =1 ;/* At least we tried ;-) */ + STp->changed_blksize = arg; + } }else ltmp = STp->block_size; (STp->buffer)->b_data[9 ] = (ltmp >>16 );
@@ -3635,9 +3637,25 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) retval = (-EIO ); goto out; } -reset_state (STp); +reset_state (STp);/* Clears pos_unknown */ /* remove this when the midlevel properly clears was_reset */ STp->device->was_reset =0 ; + +/* Fix the device settings after reset, ignore errors */ +if (mtc.mt_op ==MTREW || mtc.mt_op ==MTSEEK || + mtc.mt_op ==MTEOM ) { +if (STp->can_partitions) { +/* STp->new_partition contains the +* latest partition set +*/ + STp->partition =0 ; +switch_partition (STp); + } +if (STp->density_changed) +st_int_ioctl (STp,MTSETDENSITY , STp->changed_density); +if (STp->blksize_changed) +st_int_ioctl (STp,MTSETBLK , STp->changed_blksize); + } } if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
drivers/scsi/st.h +2 -0
@@ -165,6 +165,7 @@ struct scsi_tape {unsigned char compression_changed;unsigned char drv_buffer;unsigned char density; +unsigned char changed_density;unsigned char door_locked;unsigned char autorew_dev;/* auto-rewind device */ unsigned char rew_at_close;/* rewind necessary at close */
@@ -172,6 +173,7 @@ struct scsi_tape {unsigned char cleaning_req;/* cleaning requested? */ unsigned char first_tur;/* first TEST UNIT READY */ int block_size; +int changed_blksize;int min_block;int max_block;int recover_count;/* From tape opening */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 289/444 wifi: ath12k: Avoid napi_sync() before napi_enable()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Avula Sri Charan <[email protected]>
[ Upstream commit 268c73d470a5790a492a2fc2ded084b909d144f3 ]
In case of MHI error a reset work will be queued which will try napi_disable() after napi_synchronize().
As the napi will be only enabled after qmi_firmware_ready event, trying napi_synchronize() before napi_enable() will result in indefinite sleep in case of a firmware crash in QMI init sequence.
To avoid this, introduce napi_enabled flag to check if napi is enabled or not before calling napi_synchronize().
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
--- drivers/net/wireless/ath/ath12k/core.h | 1 + drivers/net/wireless/ath/ath12k/pci.c | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-)
drivers/net/wireless/ath/ath12k/core.h +1 -0
@@ -125,6 +125,7 @@ struct ath12k_ext_irq_grp {u32 num_irq;u32 grp_id;u64 timestamp; +bool napi_enabled;struct napi_struct napi;struct net_device napi_ndev; };
drivers/net/wireless/ath/ath12k/pci.c +10 -3
@@ -442,8 +442,11 @@ static void __ath12k_pci_ext_irq_disable(struct ath12k_base *ab)ath12k_pci_ext_grp_disable (irq_grp); -napi_synchronize (&irq_grp->napi); -napi_disable (&irq_grp->napi); +if (irq_grp->napi_enabled) { +napi_synchronize (&irq_grp->napi); +napi_disable (&irq_grp->napi); + irq_grp->napi_enabled = false; + } } }
@@ -976,7 +979,11 @@ void ath12k_pci_ext_irq_enable(struct ath12k_base *ab)for (i =0 ; i <ATH12K_EXT_IRQ_GRP_NUM_MAX ; i++) {struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; -napi_enable (&irq_grp->napi); +if (!irq_grp->napi_enabled) { +napi_enable (&irq_grp->napi); + irq_grp->napi_enabled = true; + } +ath12k_pci_ext_grp_enable (irq_grp); } }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 290/444 HID: usbkbd: Fix the bit shift number for LED_KANA
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: junan <[email protected]>
[ Upstream commit d73a4bfa2881a6859b384b75a414c33d4898b055 ]
Since "LED_KANA" was defined as "0x04", the shift number should be "4".
--- drivers/hid/usbhid/usbkbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hid/usbhid/usbkbd.c +1 -1
@@ -160,7 +160,7 @@ static int usb_kbd_event(struct input_dev *dev, unsigned int type,return -1 ;spin_lock_irqsave (&kbd->leds_lock, flags); - kbd->newleds = (!!test_bit (LED_KANA , dev->led) <<3 ) | (!!test_bit (LED_COMPOSE , dev->led) <<3 ) | + kbd->newleds = (!!test_bit (LED_KANA , dev->led) <<4 ) | (!!test_bit (LED_COMPOSE , dev->led) <<3 ) | (!!test_bit (LED_SCROLLL , dev->led) <<2 ) | (!!test_bit (LED_CAPSL , dev->led) <<1 ) | (!!test_bit (LED_NUML , dev->led));
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 291/444 arm64: zynqmp: add clock-output-names property in clock nodes
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naman Trivedi <[email protected]>
[ Upstream commit 385a59e7f7fb3438466a0712cc14672c708bbd57 ]
Add clock-output-names property to clock nodes, so that the resulting clock name do not change when clock node name is changed. Also, replace underscores with hyphens in the clock node names as per dt-schema rule.
--- arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi +10 -5
@@ -10,39 +10,44 @@ #include <dt-bindings/clock/xlnx-zynqmp-clk.h> / { - pss_ref_clk: pss_ref_clk { + pss_ref_clk: pss-ref-clk { bootph-all; compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <33333333>; + clock-output-names = "pss_ref_clk"; }; - video_clk: video_clk { + video_clk: video-clk { bootph-all; compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <27000000>; + clock-output-names = "video_clk"; }; - pss_alt_ref_clk: pss_alt_ref_clk { + pss_alt_ref_clk: pss-alt-ref-clk { bootph-all; compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; + clock-output-names = "pss_alt_ref_clk"; }; - gt_crx_ref_clk: gt_crx_ref_clk { + gt_crx_ref_clk: gt-crx-ref-clk { bootph-all; compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <108000000>; + clock-output-names = "gt_crx_ref_clk"; }; - aux_ref_clk: aux_ref_clk { + aux_ref_clk: aux-ref-clk { bootph-all; compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <27000000>; + clock-output-names = "aux_ref_clk"; }; };
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 292/444 ASoC: codecs: pcm3168a: Allow for 24-bit in provider mode
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cezary Rojewski <[email protected]>
[ Upstream commit 7d92a38d67e5d937b64b20aa4fd14451ee1772f3 ]
As per codec device specification, 24-bit is allowed in provider mode. Update the code to reflect that.
--- sound/soc/codecs/pcm3168a.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/codecs/pcm3168a.c +3 -3
@@ -494,9 +494,9 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, }break ;case 24 : -if (provider_mode || (format ==SND_SOC_DAIFMT_DSP_A ) || - (format ==SND_SOC_DAIFMT_DSP_B )) { -dev_err (component->dev,"24-bit slots not supported in provider mode, or consumer mode using DSP\n" ); +if (!provider_mode && ((format ==SND_SOC_DAIFMT_DSP_A ) || + (format ==SND_SOC_DAIFMT_DSP_B ))) { +dev_err (component->dev,"24-bit slots not supported in consumer mode using DSP\n" );return -EINVAL ; }break ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 293/444 ASoC: rt722-sdca: Add some missing readable registers
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Keepax <[email protected]>
[ Upstream commit f9a5c4b6afc79073491acdab7f1e943ee3a19fbb ]
Add a few missing registers from the readable register callback.
--- sound/soc/codecs/rt722-sdca-sdw.c | 49 +++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-)
sound/soc/codecs/rt722-sdca-sdw.c +46 -3
@@ -28,9 +28,50 @@ static bool rt722_sdca_readable_register(struct device *dev, unsigned int reg) 0):case SDW_SDCA_CTL (FUNC_NUM_JACK_CODEC ,RT722_SDCA_ENT_GE49 ,RT722_SDCA_CTL_DETECTED_MODE ,0 ): -case SDW_SDCA_CTL (FUNC_NUM_HID ,RT722_SDCA_ENT_HID01 ,RT722_SDCA_CTL_HIDTX_CURRENT_OWNER , - 0) ... SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01, -RT722_SDCA_CTL_HIDTX_MESSAGE_LENGTH ,0 ): +case SDW_SDCA_CTL (FUNC_NUM_JACK_CODEC ,RT722_SDCA_ENT_XU03 ,RT722_SDCA_CTL_SELECTED_MODE , +0 ): +case SDW_SDCA_CTL (FUNC_NUM_JACK_CODEC ,RT722_SDCA_ENT_USER_FU05 , + RT722_SDCA_CTL_FU_MUTE, CH_L) ... +SDW_SDCA_CTL (FUNC_NUM_JACK_CODEC ,RT722_SDCA_ENT_USER_FU05 , +RT722_SDCA_CTL_FU_MUTE ,CH_R ): +case SDW_SDCA_CTL (FUNC_NUM_JACK_CODEC ,RT722_SDCA_ENT_XU0D , +RT722_SDCA_CTL_SELECTED_MODE ,0 ): +case SDW_SDCA_CTL (FUNC_NUM_JACK_CODEC ,RT722_SDCA_ENT_USER_FU0F , + RT722_SDCA_CTL_FU_MUTE, CH_L) ... +SDW_SDCA_CTL (FUNC_NUM_JACK_CODEC ,RT722_SDCA_ENT_USER_FU0F , +RT722_SDCA_CTL_FU_MUTE ,CH_R ): +case SDW_SDCA_CTL (FUNC_NUM_JACK_CODEC ,RT722_SDCA_ENT_PDE40 , +RT722_SDCA_CTL_REQ_POWER_STATE ,0 ): +case SDW_SDCA_CTL (FUNC_NUM_JACK_CODEC ,RT722_SDCA_ENT_PDE12 , +RT722_SDCA_CTL_REQ_POWER_STATE ,0 ): +case SDW_SDCA_CTL (FUNC_NUM_JACK_CODEC ,RT722_SDCA_ENT_CS01 , +RT722_SDCA_CTL_SAMPLE_FREQ_INDEX ,0 ): +case SDW_SDCA_CTL (FUNC_NUM_JACK_CODEC ,RT722_SDCA_ENT_CS11 , +RT722_SDCA_CTL_SAMPLE_FREQ_INDEX ,0 ): +case SDW_SDCA_CTL (FUNC_NUM_MIC_ARRAY ,RT722_SDCA_ENT_USER_FU1E , + RT722_SDCA_CTL_FU_MUTE, CH_01) ... +SDW_SDCA_CTL (FUNC_NUM_MIC_ARRAY ,RT722_SDCA_ENT_USER_FU1E , +RT722_SDCA_CTL_FU_MUTE ,CH_04 ): +case SDW_SDCA_CTL (FUNC_NUM_MIC_ARRAY ,RT722_SDCA_ENT_IT26 , +RT722_SDCA_CTL_VENDOR_DEF ,0 ): +case SDW_SDCA_CTL (FUNC_NUM_MIC_ARRAY ,RT722_SDCA_ENT_PDE2A , +RT722_SDCA_CTL_REQ_POWER_STATE ,0 ): +case SDW_SDCA_CTL (FUNC_NUM_MIC_ARRAY ,RT722_SDCA_ENT_CS1F , +RT722_SDCA_CTL_SAMPLE_FREQ_INDEX ,0 ): +case SDW_SDCA_CTL (FUNC_NUM_HID ,RT722_SDCA_ENT_HID01 , + RT722_SDCA_CTL_HIDTX_CURRENT_OWNER, 0) ... +SDW_SDCA_CTL (FUNC_NUM_HID ,RT722_SDCA_ENT_HID01 , +RT722_SDCA_CTL_HIDTX_MESSAGE_LENGTH ,0 ): +case SDW_SDCA_CTL (FUNC_NUM_AMP ,RT722_SDCA_ENT_USER_FU06 , + RT722_SDCA_CTL_FU_MUTE, CH_L) ... +SDW_SDCA_CTL (FUNC_NUM_AMP ,RT722_SDCA_ENT_USER_FU06 , +RT722_SDCA_CTL_FU_MUTE ,CH_R ): +case SDW_SDCA_CTL (FUNC_NUM_AMP ,RT722_SDCA_ENT_OT23 , +RT722_SDCA_CTL_VENDOR_DEF ,CH_08 ): +case SDW_SDCA_CTL (FUNC_NUM_AMP ,RT722_SDCA_ENT_PDE23 , +RT722_SDCA_CTL_REQ_POWER_STATE ,0 ): +case SDW_SDCA_CTL (FUNC_NUM_AMP ,RT722_SDCA_ENT_CS31 , +RT722_SDCA_CTL_SAMPLE_FREQ_INDEX ,0 ): case RT722_BUF_ADDR_HID1 ... RT722_BUF_ADDR_HID2:return true;default :
@@ -74,6 +115,7 @@ static bool rt722_sdca_mbq_readable_register(struct device *dev, unsigned int re case 0x5600000 ... 0x5600007: case 0x5700000 ... 0x5700004: case 0x5800000 ... 0x5800004: +case 0x5810000 :case 0x5b00003 :case 0x5c00011 :case 0x5d00006 :
@@ -81,6 +123,7 @@ static bool rt722_sdca_mbq_readable_register(struct device *dev, unsigned int recase 0x5f00030 : case 0x6100000 ... 0x6100051: case 0x6100055 ... 0x6100057: +case 0x6100060 :case 0x6100062 : case 0x6100064 ... 0x6100065:case 0x6100067 :
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 294/444 drm/ast: Find VBIOS mode from regular display size
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann <[email protected]>
[ Upstream commit c81202906b5cd56db403e95db3d29c9dfc8c74c1 ]
The ast driver looks up supplied display modes from an internal list of display modes supported by the VBIOS.
Do not use the crtc_-prefixed display values from struct drm_display_mode for looking up the VBIOS mode. The fields contain raw values that the driver programs to hardware. They are affected by display settings like double-scan or interlace.
Instead use the regular vdisplay and hdisplay fields for lookup. As the programmed values can now differ from the values used for lookup, set struct drm_display_mode.crtc_vdisplay and .crtc_hdisplay from the VBIOS mode.
--- drivers/gpu/drm/ast/ast_mode.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/gpu/drm/ast/ast_mode.c +6 -4
@@ -132,7 +132,7 @@ static bool ast_get_vbios_mode_info(const struct drm_format_info *format,return false; } -switch (mode->crtc_hdisplay) { +switch (mode->hdisplay) {case 640 : vbios_mode->enh_table = &res_640x480[refresh_rate_index];break ;
@@ -146,7 +146,7 @@ static bool ast_get_vbios_mode_info(const struct drm_format_info *format, vbios_mode->enh_table = &res_1152x864[refresh_rate_index];break ;case 1280 : -if (mode->crtc_vdisplay ==800 ) +if (mode->vdisplay ==800 ) vbios_mode->enh_table = &res_1280x800[refresh_rate_index];else vbios_mode->enh_table = &res_1280x1024[refresh_rate_index];
@@ -158,7 +158,7 @@ static bool ast_get_vbios_mode_info(const struct drm_format_info *format, vbios_mode->enh_table = &res_1440x900[refresh_rate_index];break ;case 1600 : -if (mode->crtc_vdisplay ==900 ) +if (mode->vdisplay ==900 ) vbios_mode->enh_table = &res_1600x900[refresh_rate_index];else vbios_mode->enh_table = &res_1600x1200[refresh_rate_index];
@@ -167,7 +167,7 @@ static bool ast_get_vbios_mode_info(const struct drm_format_info *format, vbios_mode->enh_table = &res_1680x1050[refresh_rate_index];break ;case 1920 : -if (mode->crtc_vdisplay ==1080 ) +if (mode->vdisplay ==1080 ) vbios_mode->enh_table = &res_1920x1080[refresh_rate_index];else vbios_mode->enh_table = &res_1920x1200[refresh_rate_index];
@@ -211,6 +211,7 @@ static bool ast_get_vbios_mode_info(const struct drm_format_info *format, hborder = (vbios_mode->enh_table->flags & HBorder) ?8 :0 ; vborder = (vbios_mode->enh_table->flags & VBorder) ?8 :0 ; + adjusted_mode->crtc_hdisplay = vbios_mode->enh_table->hde; adjusted_mode->crtc_htotal = vbios_mode->enh_table->ht; adjusted_mode->crtc_hblank_start = vbios_mode->enh_table->hde + hborder; adjusted_mode->crtc_hblank_end = vbios_mode->enh_table->ht - hborder;
@@ -220,6 +221,7 @@ static bool ast_get_vbios_mode_info(const struct drm_format_info *format, vbios_mode->enh_table->hfp + vbios_mode->enh_table->hsync); + adjusted_mode->crtc_vdisplay = vbios_mode->enh_table->vde; adjusted_mode->crtc_vtotal = vbios_mode->enh_table->vt; adjusted_mode->crtc_vblank_start = vbios_mode->enh_table->vde + vborder; adjusted_mode->crtc_vblank_end = vbios_mode->enh_table->vt - vborder;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 295/444 bpftool: Fix readlink usage in get_fd_type
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viktor Malik <[email protected]>
[ Upstream commit 0053f7d39d491b6138d7c526876d13885cbb65f1 ]
The readlink(path, buf, sizeof(buf)) call reads at most sizeof(buf) bytes and *does not* append null-terminator to buf. With respect to that, fix two pieces in get_fd_type:
1. Change the truncation check to contain sizeof(buf) rather than sizeof(path).
2. Append null-terminator to buf.
Reported by Coverity.
--- tools/bpf/bpftool/common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/bpf/bpftool/common.c +2 -1
@@ -461,10 +461,11 @@ int get_fd_type(int fd)p_err ("can't read link type: %s" ,strerror (errno));return -1 ; } -if (n ==sizeof (path)) { +if (n ==sizeof (buf)) {p_err ("can't read link type: path too long!" );return -1 ; } + buf[n] ='\0' ;if (strstr (buf,"bpf-map" ))return BPF_OBJ_MAP ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 296/444 firmware: arm_scmi: Relax duplicate name constraint across protocol ids
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sudeep Holla <[email protected]>
[ Upstream commit 21ee965267bcbdd733be0f35344fa0f0226d7861 ]
Currently in scmi_protocol_device_request(), no duplicate scmi device name is allowed across any protocol. However scmi_dev_match_id() first matches the protocol id and then the name. So, there is no strict requirement to keep this scmi device name unique across all the protocols.
Relax the constraint on the duplicate name across the protocols and inhibit only within the same protocol id.
Message-Id: <[email protected]>
--- drivers/firmware/arm_scmi/bus.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-)
drivers/firmware/arm_scmi/bus.c +6 -13
@@ -42,7 +42,7 @@ static atomic_t scmi_syspower_registered = ATOMIC_INIT(0);* This helper let an SCMI driver request specific devices identified by the * @id_table to be created for each active SCMI instance. * -* The requested device name MUST NOT be already existent for any protocol; +* The requested device name MUST NOT be already existent for this protocol; * at first the freshly requested @id_table is annotated in the IDR table * @scmi_requested_devices and then the requested device is advertised to any * registered party via the @scmi_requested_devices_nh notification chain.
@@ -52,7 +52,6 @@ static atomic_t scmi_syspower_registered = ATOMIC_INIT(0);static int scmi_protocol_device_request (const struct scmi_device_id *id_table) {int ret =0 ; -unsigned int id =0 ;struct list_head *head, *phead =NULL ;struct scmi_requested_dev *rdev;
@@ -67,19 +66,13 @@ static int scmi_protocol_device_request(const struct scmi_device_id *id_table) }/* -* Search for the matching protocol rdev list and then search -* of any existent equally named device...fails if any duplicate found. +* Find the matching protocol rdev list and then search of any +* existent equally named device...fails if any duplicate found. */ mutex_lock (&scmi_requested_devices_mtx); -idr_for_each_entry (&scmi_requested_devices, head, id) { -if (!phead) { -/* A list found registered in the IDR is never empty */ - rdev = list_first_entry(head, struct scmi_requested_dev, - node); -if (rdev->id_table->protocol_id == - id_table->protocol_id) - phead = head; - } + phead =idr_find (&scmi_requested_devices, id_table->protocol_id); +if (phead) { + head = phead;list_for_each_entry (rdev, head, node) {if (!strcmp (rdev->id_table->name, id_table->name)) { pr_err("Ignoring duplicate request [%d] %s\n",
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 297/444 perf/amd/ibs: Fix perf_ibs_op.cnt_mask for CurCnt
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ravi Bangoria <[email protected]>
[ Upstream commit 46dcf85566170d4528b842bf83ffc350d71771fa ]
IBS Op uses two counters: MaxCnt and CurCnt. MaxCnt is programmed with the desired sample period. IBS hw generates sample when CurCnt reaches to MaxCnt. The size of these counter used to be 20 bits but later they were extended to 27 bits. The 7 bit extension is indicated by CPUID Fn8000_001B_EAX[6 / OpCntExt].
perf_ibs->cnt_mask variable contains bit masks for MaxCnt and CurCnt. But IBS driver does not set upper 7 bits of CurCnt in cnt_mask even when OpCntExt CPUID bit is set. Fix this.
IBS driver uses cnt_mask[CurCnt] bits only while disabling an event. Fortunately, CurCnt bits are not read from MSR while re-enabling the event, instead MaxCnt is programmed with desired period and CurCnt is set to 0. Hence, we did not see any issues so far.
--- arch/x86/events/amd/ibs.c | 3 ++- arch/x86/include/asm/perf_event.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
arch/x86/events/amd/ibs.c +2 -1
@@ -1219,7 +1219,8 @@ static __init int perf_ibs_op_init(void)if (ibs_caps &IBS_CAPS_OPCNTEXT ) { perf_ibs_op.max_period |=IBS_OP_MAX_CNT_EXT_MASK ; perf_ibs_op.config_mask |=IBS_OP_MAX_CNT_EXT_MASK ; - perf_ibs_op.cnt_mask |=IBS_OP_MAX_CNT_EXT_MASK ; + perf_ibs_op.cnt_mask |= (IBS_OP_MAX_CNT_EXT_MASK | +IBS_OP_CUR_CNT_EXT_MASK ); }if (ibs_caps &IBS_CAPS_ZEN4 )
arch/x86/include/asm/perf_event.h +1 -0
@@ -501,6 +501,7 @@ struct pebs_xmm {*/ #define IBS_OP_CUR_CNT (0xFFF80ULL<<32)#define IBS_OP_CUR_CNT_RAND (0x0007FULL<<32) +#define IBS_OP_CUR_CNT_EXT_MASK (0x7FULL<<52)#define IBS_OP_CNT_CTL (1ULL<<19)#define IBS_OP_VAL (1ULL<<18)#define IBS_OP_ENABLE (1ULL<<17)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 298/444 perf/amd/ibs: Fix ->config to sample period calculation for OP PMU
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ravi Bangoria <[email protected]>
[ Upstream commit 598bdf4fefff5af4ce6d26d16f7b2a20808fc4cb ]
Instead of using standard perf_event_attr->freq=0 and ->sample_period fields, IBS event in 'sample period mode' can also be opened by setting period value directly in perf_event_attr->config in a MaxCnt bit-field format.
IBS OP MaxCnt bits are defined as:
(high bits) IbsOpCtl[26:20] = IbsOpMaxCnt[26:20] (low bits) IbsOpCtl[15:0] = IbsOpMaxCnt[19:4]
Perf event sample period can be derived from MaxCnt bits as:
sample_period = (high bits) | ((low_bits) << 4);
However, current code just masks MaxCnt bits and shifts all of them, including high bits, which is incorrect. Fix it.
--- arch/x86/events/amd/ibs.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
arch/x86/events/amd/ibs.c +13 -4
@@ -272,7 +272,7 @@ static int perf_ibs_init(struct perf_event *event) {struct hw_perf_event *hwc = &event->hw;struct perf_ibs *perf_ibs; -u64 max_cnt, config; +u64 config;int ret; perf_ibs =get_ibs_pmu (event->attr.type);
@@ -306,10 +306,19 @@ static int perf_ibs_init(struct perf_event *event)if (!hwc->sample_period) hwc->sample_period =0x10 ; }else { - max_cnt = config & perf_ibs->cnt_mask; +u64 period =0 ; + +if (perf_ibs == &perf_ibs_op) { + period = (config &IBS_OP_MAX_CNT ) <<4 ; +if (ibs_caps &IBS_CAPS_OPCNTEXT ) + period |= config &IBS_OP_MAX_CNT_EXT_MASK ; + }else { + period = (config &IBS_FETCH_MAX_CNT ) <<4 ; + } + config &= ~perf_ibs->cnt_mask; - event->attr.sample_period = max_cnt <<4 ; - hwc->sample_period = event->attr.sample_period; + event->attr.sample_period = period; + hwc->sample_period = period; }if (!hwc->sample_period)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 299/444 wifi: rtl8xxxu: retry firmware download on error
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Soeren Moch <[email protected]>
[ Upstream commit 3d3e28feca7ac8c6cf2a390dbbe1f97e3feb7f36 ]
Occasionally there is an EPROTO error during firmware download. This error is converted to EAGAIN in the download function. But nobody tries again and so device probe fails.
Implement download retry to fix this.
This error was observed (and fix tested) on a tbs2910 board [1] with an embedded RTL8188EU (0bda:8179) device behind a USB hub.
[1] arch/arm/boot/dts/nxp/imx/imx6q-tbs2910.dts
--- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +12 -5
@@ -900,9 +900,10 @@ rtl8xxxu_writeN(struct rtl8xxxu_priv *priv, u16 addr, u8 *buf, u16 len)return len; write_error: -dev_info (&udev->dev, -"%s: Failed to write block at addr: %04x size: %04x\n" , - __func__, addr, blocksize); +if (rtl8xxxu_debug &RTL8XXXU_DEBUG_REG_WRITE ) +dev_info (&udev->dev, +"%s: Failed to write block at addr: %04x size: %04x\n" , + __func__, addr, blocksize);return -EAGAIN ; }
@@ -4073,8 +4074,14 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)*/ rtl8xxxu_write16 (priv,REG_TRXFF_BNDY +2 , fops->trxff_boundary); - ret =rtl8xxxu_download_firmware (priv); -dev_dbg (dev,"%s: download_firmware %i\n" , __func__, ret); +for (int retry =5 ; retry >=0 ; retry--) { + ret =rtl8xxxu_download_firmware (priv); +dev_dbg (dev,"%s: download_firmware %i\n" , __func__, ret); +if (ret != -EAGAIN ) +break ; +if (retry) +dev_dbg (dev,"%s: retry firmware download\n" , __func__); + }if (ret) goto exit; ret =rtl8xxxu_start_firmware (priv);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 300/444 wifi: rtw88: Dont use static local variable in rtw8822b_set_tx_power_index_by_rate
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bitterblue Smith <[email protected]>
[ Upstream commit 00451eb3bec763f708e7e58326468c1e575e5a66 ]
Some users want to plug two identical USB devices at the same time. This static variable could theoretically cause them to use incorrect TX power values.
Move the variable to the caller and pass a pointer to it to rtw8822b_set_tx_power_index_by_rate().
--- drivers/net/wireless/realtek/rtw88/rtw8822b.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/net/wireless/realtek/rtw88/rtw8822b.c +8 -6
@@ -975,11 +975,11 @@ static void rtw8822b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, }static void -rtw8822b_set_tx_power_index_by_rate (struct rtw_dev *rtwdev,u8 path,u8 rs) +rtw8822b_set_tx_power_index_by_rate (struct rtw_dev *rtwdev,u8 path, +u8 rs,u32 *phy_pwr_idx) {struct rtw_hal *hal = &rtwdev->hal;static const u32 offset_txagc[2 ] = {0x1d00 ,0x1d80 }; -static u32 phy_pwr_idx;u8 rate, rate_idx, pwr_index, shift;int j;
@@ -987,12 +987,12 @@ rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) rate = rtw_rate_section[rs][j]; pwr_index = hal->tx_pwr_tbl[path][rate]; shift = rate &0x3 ; - phy_pwr_idx |= ((u32 )pwr_index << (shift *8 )); + *phy_pwr_idx |= ((u32 )pwr_index << (shift *8 ));if (shift ==0x3 ) { rate_idx = rate &0xfc ;rtw_write32 (rtwdev, offset_txagc[path] + rate_idx, - phy_pwr_idx); - phy_pwr_idx =0 ; + *phy_pwr_idx); + *phy_pwr_idx =0 ; } } }
@@ -1000,11 +1000,13 @@ rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)static void rtw8822b_set_tx_power_index (struct rtw_dev *rtwdev) {struct rtw_hal *hal = &rtwdev->hal; +u32 phy_pwr_idx =0 ;int rs, path;for (path =0 ; path < hal->rf_path_num; path++) {for (rs =0 ; rs <RTW_RATE_SECTION_MAX ; rs++) -rtw8822b_set_tx_power_index_by_rate (rtwdev, path, rs); +rtw8822b_set_tx_power_index_by_rate (rtwdev, path, rs, + &phy_pwr_idx); } }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 301/444 wifi: rtw89: add wiphy_lock() to work that isnt held wiphy_lock() yet
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ping-Ke Shih <[email protected]>
[ Upstream commit ebfc9199df05d37b67f4d1b7ee997193f3d2e7c8 ]
To ensure where are protected by driver mutex can also be protected by wiphy_lock(), so afterward we can remove driver mutex safely.
--- drivers/net/wireless/realtek/rtw89/regd.c | 2 ++ drivers/net/wireless/realtek/rtw89/ser.c | 4 ++++ 2 files changed, 6 insertions(+)
drivers/net/wireless/realtek/rtw89/regd.c +2 -0
@@ -451,6 +451,7 @@ void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *requeststruct ieee80211_hw *hw =wiphy_to_ieee80211_hw (wiphy);struct rtw89_dev *rtwdev = hw->priv; +wiphy_lock (wiphy);mutex_lock (&rtwdev->mutex);rtw89_leave_ps_mode (rtwdev);
@@ -468,6 +469,7 @@ void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request exit:mutex_unlock (&rtwdev->mutex); +wiphy_unlock (wiphy); }static void __rtw89_reg_6ghz_power_recalc (struct rtw89_dev *rtwdev)
drivers/net/wireless/realtek/rtw89/ser.c +4 -0
@@ -156,9 +156,11 @@ static void ser_state_run(struct rtw89_ser *ser, u8 evt)rtw89_debug (rtwdev,RTW89_DBG_SER ,"ser: %s receive %s\n" ,ser_st_name (ser),ser_ev_name (ser, evt)); +wiphy_lock (rtwdev->hw->wiphy);mutex_lock (&rtwdev->mutex);rtw89_leave_lps (rtwdev);mutex_unlock (&rtwdev->mutex); +wiphy_unlock (rtwdev->hw->wiphy); ser->st_tbl[ser->state].st_func (ser, evt); }
@@ -676,9 +678,11 @@ static void ser_l2_reset_st_hdl(struct rtw89_ser *ser, u8 evt)switch (evt) {case SER_EV_STATE_IN : +wiphy_lock (rtwdev->hw->wiphy);mutex_lock (&rtwdev->mutex);ser_l2_reset_st_pre_hdl (ser);mutex_unlock (&rtwdev->mutex); +wiphy_unlock (rtwdev->hw->wiphy);ieee80211_restart_hw (rtwdev->hw);ser_set_alarm (ser,SER_RECFG_TIMEOUT ,SER_EV_L2_RECFG_TIMEOUT );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 302/444 spi: zynqmp-gqspi: Always acknowledge interrupts
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Anderson <[email protected]>
[ Upstream commit 89785306453ce6d949e783f6936821a0b7649ee2 ]
RXEMPTY can cause an IRQ, even though we may not do anything about it (such as if we are waiting for more received data). We must still handle these IRQs because we can tell they were caused by the device.
--- drivers/spi/spi-zynqmp-gqspi.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-)
drivers/spi/spi-zynqmp-gqspi.c +8 -12
@@ -799,7 +799,6 @@ static void zynqmp_process_dma_irq(struct zynqmp_qspi *xqspi)static irqreturn_t zynqmp_qspi_irq (int irq,void *dev_id) {struct zynqmp_qspi *xqspi = (struct zynqmp_qspi *)dev_id; -irqreturn_t ret =IRQ_NONE ;u32 status, mask, dma_status =0 ; status =zynqmp_gqspi_read (xqspi,GQSPI_ISR_OFST );
@@ -814,27 +813,24 @@ static irqreturn_t zynqmp_qspi_irq(int irq, void *dev_id) dma_status); } -if (mask &GQSPI_ISR_TXNOT_FULL_MASK ) { +if (!mask && !dma_status) +return IRQ_NONE ; + +if (mask &GQSPI_ISR_TXNOT_FULL_MASK )zynqmp_qspi_filltxfifo (xqspi,GQSPI_TX_FIFO_FILL ); - ret =IRQ_HANDLED ; - } -if (dma_status &GQSPI_QSPIDMA_DST_I_STS_DONE_MASK ) { +if (dma_status &GQSPI_QSPIDMA_DST_I_STS_DONE_MASK )zynqmp_process_dma_irq (xqspi); - ret =IRQ_HANDLED ; - }else if (!(mask &GQSPI_IER_RXEMPTY_MASK ) && - (mask &GQSPI_IER_GENFIFOEMPTY_MASK )) { +else if (!(mask &GQSPI_IER_RXEMPTY_MASK ) && + (mask &GQSPI_IER_GENFIFOEMPTY_MASK ))zynqmp_qspi_readrxfifo (xqspi,GQSPI_RX_FIFO_FILL ); - ret =IRQ_HANDLED ; - }if (xqspi->bytes_to_receive ==0 && xqspi->bytes_to_transfer ==0 && ((status &GQSPI_IRQ_MASK ) ==GQSPI_IRQ_MASK )) {zynqmp_gqspi_write (xqspi,GQSPI_IDR_OFST ,GQSPI_ISR_IDR_MASK );complete (&xqspi->data_completion); - ret =IRQ_HANDLED ; } -return ret; +return IRQ_HANDLED ; }/**
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 303/444 regulator: ad5398: Add device tree support
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Isaac Scott <[email protected]>
[ Upstream commit 5a6a461079decea452fdcae955bccecf92e07e97 ]
Previously, the ad5398 driver used only platform_data, which is deprecated in favour of device tree. This caused the AD5398 to fail to probe as it could not load its init_data. If the AD5398 has a device tree node, pull the init_data from there using of_get_regulator_init_data.
--- drivers/regulator/ad5398.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
drivers/regulator/ad5398.c +9 -3
@@ -14,6 +14,7 @@#include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> +#include <linux/regulator/of_regulator.h> #define AD5398_CURRENT_EN_MASK 0x8000
@@ -221,15 +222,20 @@ static int ad5398_probe(struct i2c_client *client)const struct ad5398_current_data_format *df = (struct ad5398_current_data_format *)id->driver_data; -if (!init_data) -return -EINVAL ; - chip =devm_kzalloc (&client->dev,sizeof (*chip),GFP_KERNEL );if (!chip)return -ENOMEM ; config.dev = &client->dev; +if (client->dev.of_node) + init_data =of_get_regulator_init_data (&client->dev, + client->dev.of_node, + &ad5398_reg); +if (!init_data) +return -EINVAL ; + config.init_data = init_data; + config.of_node = client->dev.of_node; config.driver_data = chip; chip->client = client;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 304/444 wifi: ath12k: fix ath12k_hal_tx_cmd_ext_desc_setup() info1 override
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolas Escande <[email protected]>
[ Upstream commit df11edfba49e5fb69f4c9e7cb76082b89c417f78 ]
Since inception there is an obvious typo laying around in ath12k_hal_tx_cmd_ext_desc_setup(). Instead of initializing + adding flags to tcl_ext_cmd->info1, we initialize + override. This will be needed in the future to make broadcast frames work with ethernet encapsulation.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
--- drivers/net/wireless/ath/ath12k/dp_tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ath/ath12k/dp_tx.c +1 -1
@@ -118,7 +118,7 @@ static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, void *cmd,le32_encode_bits (ti->data_len,HAL_TX_MSDU_EXT_INFO1_BUF_LEN ); - tcl_ext_cmd->info1 =le32_encode_bits (1 ,HAL_TX_MSDU_EXT_INFO1_EXTN_OVERRIDE ) | + tcl_ext_cmd->info1 |=le32_encode_bits (1 ,HAL_TX_MSDU_EXT_INFO1_EXTN_OVERRIDE ) |le32_encode_bits (ti->encap_type,HAL_TX_MSDU_EXT_INFO1_ENCAP_TYPE ) | le32_encode_bits(ti->encrypt_type,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 305/444 accel/qaic: Mask out SR-IOV PCI resources
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Youssef Samir <[email protected]>
[ Upstream commit 8685520474bfc0fe4be83c3cbfe3fb3e1ca1514a ]
During the initialization of the qaic device, pci_select_bars() is used to fetch a bitmask of the BARs exposed by the device. On devices that have Virtual Functions capabilities, the bitmask includes SR-IOV BARs.
Use a mask to filter out SR-IOV BARs if they exist.
--- drivers/accel/qaic/qaic_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/accel/qaic/qaic_drv.c +1 -1
@@ -400,7 +400,7 @@ static int init_pci(struct qaic_device *qdev, struct pci_dev *pdev)int bars;int ret; - bars =pci_select_bars (pdev,IORESOURCE_MEM ); + bars =pci_select_bars (pdev,IORESOURCE_MEM ) &0x3f ;/* make sure the device has the expected BARs */ if (bars != (BIT (0 ) |BIT (2 ) |BIT (4 ))) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 306/444 wifi: ath9k: return by of_get_mac_address
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rosen Penev <[email protected]>
[ Upstream commit dfffb317519f88534bb82797f055f0a2fd867e7b ]
When using nvmem, ath9k could potentially be loaded before nvmem, which loads after mtd. This is an issue if DT contains an nvmem mac address.
If nvmem is not ready in time for ath9k, -EPROBE_DEFER is returned. Pass it to _probe so that ath9k can properly grab a potentially present MAC address.
--- drivers/net/wireless/ath/ath9k/init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/ath9k/init.c +3 -1
@@ -691,7 +691,9 @@ static int ath9k_of_init(struct ath_softc *sc) ah->ah_flags |=AH_NO_EEP_SWAP ; } -of_get_mac_address (np, common->macaddr); + ret =of_get_mac_address (np, common->macaddr); +if (ret == -EPROBE_DEFER ) +return ret;return 0 ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 307/444 wifi: ath12k: Fix end offset bit definition in monitor ring descriptor
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: P Praneesh <[email protected]>
[ Upstream commit 6788a666000d600bd8f2e9f991cad9cc805e7f01 ]
End offset for the monitor destination ring descriptor is defined as 16 bits, while the firmware definition specifies only 12 bits. The remaining bits (bit 12 to bit 15) are reserved and may contain junk values, leading to invalid information retrieval. Fix this issue by updating the correct genmask values.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
--- drivers/net/wireless/ath/ath12k/hal_desc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ath/ath12k/hal_desc.h +1 -1
@@ -2918,7 +2918,7 @@ struct hal_mon_buf_ring {#define HAL_MON_DEST_COOKIE_BUF_ID GENMASK(17, 0) -#define HAL_MON_DEST_INFO0_END_OFFSET GENMASK(15, 0) +#define HAL_MON_DEST_INFO0_END_OFFSET GENMASK(11, 0)#define HAL_MON_DEST_INFO0_FLUSH_DETECTED BIT(16)#define HAL_MON_DEST_INFO0_END_OF_PPDU BIT(17)#define HAL_MON_DEST_INFO0_INITIATOR BIT(18)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 308/444 drm: bridge: adv7511: fill stream capabilities
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Olivier Moysan <[email protected]>
[ Upstream commit c852646f12d4cd5b4f19eeec2976c5d98c0382f8 ]
Set no_i2s_capture and no_spdif_capture flags in hdmi_codec_pdata structure to report that the ADV7511 HDMI bridge does not support i2s or spdif audio capture.
--- drivers/gpu/drm/bridge/adv7511/adv7511_audio.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/bridge/adv7511/adv7511_audio.c +2 -0
@@ -244,7 +244,9 @@ static const struct hdmi_codec_pdata codec_data = { .ops = &adv7511_codec_ops, .max_i2s_channels = 2, .i2s = 1, + .no_i2s_capture = 1, .spdif = 1, + .no_spdif_capture = 1, };int adv7511_audio_init (struct device *dev,struct adv7511 *adv7511)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 309/444 drm/atomic: clarify the rules around drm_atomic_state->allow_modeset
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simona Vetter <[email protected]>
[ Upstream commit c5e3306a424b52e38ad2c28c7f3399fcd03e383d ]
msm is automagically upgrading normal commits to full modesets, and that's a big no-no:
- for one this results in full on->off->on transitions on all these crtc, at least if you're using the usual helpers. Which seems to be the case, and is breaking uapi
- further even if the ctm change itself would not result in flicker, this can hide modesets for other reasons. Which again breaks the uapi
v2: I forgot the case of adding unrelated crtc state. Add that case and link to the existing kerneldoc explainers. This has come up in an irc discussion with Manasi and Ville about intel's bigjoiner mode. Also cc everyone involved in the msm irc discussion, more people joined after I sent out v1.
v3: Wording polish from Pekka and Thomas
--- include/drm/drm_atomic.h | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
include/drm/drm_atomic.h +21 -2
@@ -372,8 +372,27 @@ struct drm_atomic_state {* * Allow full modeset. This is used by the ATOMIC IOCTL handler to * implement the DRM_MODE_ATOMIC_ALLOW_MODESET flag. Drivers should -* never consult this flag, instead looking at the output of -* drm_atomic_crtc_needs_modeset(). +* generally not consult this flag, but instead look at the output of +* drm_atomic_crtc_needs_modeset(). The detailed rules are: +* +* - Drivers must not consult @allow_modeset in the atomic commit path. +* Use drm_atomic_crtc_needs_modeset() instead. +* +* - Drivers must consult @allow_modeset before adding unrelated struct +* drm_crtc_state to this commit by calling +* drm_atomic_get_crtc_state(). See also the warning in the +* documentation for that function. +* +* - Drivers must never change this flag, it is under the exclusive +* control of userspace. +* +* - Drivers may consult @allow_modeset in the atomic check path, if +* they have the choice between an optimal hardware configuration +* which requires a modeset, and a less optimal configuration which +* can be committed without a modeset. An example would be suboptimal +* scanout FIFO allocation resulting in increased idle power +* consumption. This allows userspace to avoid flickering and delays +* for the normal composition loop at reasonable cost. */ bool allow_modeset : 1;/**
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 310/444 drm/panel-edp: Add Starry 116KHD024006
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Douglas Anderson <[email protected]>
[ Upstream commit 749b5b279e5636cdcef51e15d67b77162cca6caa ]
We have a few reports of sc7180-trogdor-pompom devices that have a panel in them that IDs as STA 0x0004 and has the following raw EDID:
00 ff ff ff ff ff ff 00 4e 81 04 00 00 00 00 00 10 20 01 04 a5 1a 0e 78 0a dc dd 96 5b 5b 91 28 1f 52 54 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 8e 1c 56 a0 50 00 1e 30 28 20 55 00 00 90 10 00 00 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe 00 31 31 36 4b 48 44 30 32 34 30 30 36 0a 00 e6
We've been unable to locate a datasheet for this panel and our partner has not been responsive, but all Starry eDP datasheets that we can find agree on the same timing (delay_100_500_e200) so it should be safe to use that here instead of the super conservative timings. We'll still go a little extra conservative and allow hpd_absent of 200 instead of 100 because that won't add any real-world delay in most cases.
We'll associate the string from the EDID ("116KHD024006") with this panel. Given that the ID is the suspicious value of 0x0004 it seems likely that Starry doesn't always update their IDs but the string will still work to differentiate if we ever need to in the future.
--- drivers/gpu/drm/panel/panel-edp.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/panel/panel-edp.c +1 -0
@@ -1923,6 +1923,7 @@ static const struct edp_panel_entry edp_panels[] = {EDP_PANEL_ENTRY ('S' ,'H' ,'P' ,0x1523 , &sharp_lq140m1jw46.delay,"LQ140M1JW46" ),EDP_PANEL_ENTRY ('S' ,'H' ,'P' ,0x154c , &delay_200_500_p2e100,"LQ116M1JW10" ), +EDP_PANEL_ENTRY ('S' ,'T' ,'A' ,0x0004 , &delay_200_500_e200,"116KHD024006" ), EDP_PANEL_ENTRY('S', 'T', 'A', 0x0100, &delay_100_500_e200, "2081116HHD028001-51D"), { /* sentinal */ }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 311/444 drm: Add valid clones check
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jessica Zhang <[email protected]>
[ Upstream commit 41b4b11da02157c7474caf41d56baae0e941d01a ]
Check that all encoders attached to a given CRTC are valid possible_clones of each other.
--- drivers/gpu/drm/drm_atomic_helper.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
drivers/gpu/drm/drm_atomic_helper.c +28 -0
@@ -573,6 +573,30 @@ mode_valid(struct drm_atomic_state *state)return 0 ; } +static int drm_atomic_check_valid_clones (struct drm_atomic_state *state, +struct drm_crtc *crtc) +{ +struct drm_encoder *drm_enc; +struct drm_crtc_state *crtc_state =drm_atomic_get_new_crtc_state (state, + crtc); + +drm_for_each_encoder_mask (drm_enc, crtc->dev, crtc_state->encoder_mask) { +if (!drm_enc->possible_clones) { +DRM_DEBUG ("enc%d possible_clones is 0\n" , drm_enc->base.id); +continue ; + } + +if ((crtc_state->encoder_mask & drm_enc->possible_clones) != + crtc_state->encoder_mask) { +DRM_DEBUG ("crtc%d failed valid clone check for mask 0x%x\n" , + crtc->base.id, crtc_state->encoder_mask); +return -EINVAL ; + } + } + +return 0 ; +} +/** * drm_atomic_helper_check_modeset - validate state object for modeset changes * @dev: DRM device
@@ -744,6 +768,10 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, ret =drm_atomic_add_affected_planes (state, crtc);if (ret !=0 )return ret; + + ret =drm_atomic_check_valid_clones (state, crtc); +if (ret !=0 ) +return ret; }/*
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 312/444 ASoC: imx-card: Adjust over allocation of memory in imx_card_parse_of()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenyuan Yang <[email protected]>
[ Upstream commit a9a69c3b38c89d7992fb53db4abb19104b531d32 ]
Incorrect types are used as sizeof() arguments in devm_kcalloc(). It should be sizeof(dai_link_data) for link_data instead of sizeof(snd_soc_dai_link).
This is found by our static analysis tool.
--- sound/soc/fsl/imx-card.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/fsl/imx-card.c +1 -1
@@ -517,7 +517,7 @@ static int imx_card_parse_of(struct imx_card_data *data)if (!card->dai_link)return -ENOMEM ; - data->link_data =devm_kcalloc (dev, num_links,sizeof (*link),GFP_KERNEL ); + data->link_data =devm_kcalloc (dev, num_links,sizeof (*link_data),GFP_KERNEL );if (!data->link_data)return -ENOMEM ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 313/444 book3s64/radix: Fix compile errors when CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP=n
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ritesh Harjani (IBM) <[email protected]>
[ Upstream commit 29bdc1f1c1df80868fb35bc69d1f073183adc6de ]
Fix compile errors when CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP=n
--- arch/powerpc/mm/book3s64/radix_pgtable.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/powerpc/mm/book3s64/radix_pgtable.c +2 -1
@@ -912,7 +912,7 @@ int __meminit radix__vmemmap_create_mapping(unsigned long start,return 0 ; } - +#ifdef CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP bool vmemmap_can_optimize (struct vmem_altmap *altmap,struct dev_pagemap *pgmap) {if (radix_enabled ())
@@ -920,6 +920,7 @@ bool vmemmap_can_optimize(struct vmem_altmap *altmap, struct dev_pagemap *pgmap) return false; } +#endif int __meminit vmemmap_check_pmd (pmd_t *pmdp,int node,unsigned long addr,unsigned long next)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 314/444 pinctrl: meson: define the pull up/down resistor value as 60 kOhm
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Blumenstingl <[email protected]>
[ Upstream commit e56088a13708757da68ad035269d69b93ac8c389 ]
The public datasheets of the following Amlogic SoCs describe a typical resistor value for the built-in pull up/down resistor:
- Meson8/8b/8m2: not documented
- GXBB (S905): 60 kOhm
- GXL (S905X): 60 kOhm
- GXM (S912): 60 kOhm
- G12B (S922X): 60 kOhm
- SM1 (S905D3): 60 kOhm
The public G12B and SM1 datasheets additionally state min and max values:
- min value: 50 kOhm for both, pull-up and pull-down
- max value for the pull-up: 70 kOhm
- max value for the pull-down: 130 kOhm
Use 60 kOhm in the pinctrl-meson driver as well so it's shown in the debugfs output. It may not be accurate for Meson8/8b/8m2 but in reality 60 kOhm is closer to the actual value than 1 Ohm.
--- drivers/pinctrl/meson/pinctrl-meson.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pinctrl/meson/pinctrl-meson.c +1 -1
@@ -486,7 +486,7 @@ static int meson_pinconf_get(struct pinctrl_dev *pcdev, unsigned int pin,case PIN_CONFIG_BIAS_PULL_DOWN :case PIN_CONFIG_BIAS_PULL_UP :if (meson_pinconf_get_pull (pc, pin) == param) - arg =1 ; + arg =60000 ;else return -EINVAL ;break ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 315/444 ASoC: cs42l43: Disable headphone clamps during type detection
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Keepax <[email protected]>
[ Upstream commit 70ad2e6bd180f94be030aef56e59693e36d945f3 ]
The headphone clamps cause fairly loud pops during type detect because they sink current from the detection process itself. Disable the clamps whilst the type detect runs, to improve the detection pop performance.
--- sound/soc/codecs/cs42l43-jack.c | 7 +++++++ 1 file changed, 7 insertions(+)
sound/soc/codecs/cs42l43-jack.c +7 -0
@@ -642,6 +642,10 @@ static int cs42l43_run_type_detect(struct cs42l43_codec *priv)reinit_completion (&priv->type_detect); +regmap_update_bits (cs42l43->regmap,CS42L43_STEREO_MIC_CLAMP_CTRL , +CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_VAL_MASK , +CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_VAL_MASK ); +cs42l43_start_hs_bias (priv, true);regmap_update_bits (cs42l43->regmap,CS42L43_HS2 ,CS42L43_HSDET_MODE_MASK ,0x3 <<CS42L43_HSDET_MODE_SHIFT );
@@ -653,6 +657,9 @@ static int cs42l43_run_type_detect(struct cs42l43_codec *priv) CS42L43_HSDET_MODE_MASK, 0x2 << CS42L43_HSDET_MODE_SHIFT);cs42l43_stop_hs_bias (priv); +regmap_update_bits (cs42l43->regmap,CS42L43_STEREO_MIC_CLAMP_CTRL , +CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_VAL_MASK ,0 ); +if (!time_left)return -ETIMEDOUT ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 316/444 ASoC: Intel: bytcr_rt5640: Add DMI quirk for Acer Aspire SW3-013
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit a549b927ea3f5e50b1394209b64e6e17e31d4db8 ]
Acer Aspire SW3-013 requires the very same quirk as other Acer Aspire model for making it working.
--- sound/soc/intel/boards/bytcr_rt5640.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
sound/soc/intel/boards/bytcr_rt5640.c +13 -0
@@ -576,6 +576,19 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {BYT_RT5640_SSP0_AIF2 | BYT_RT5640_MCLK_EN), }, + { /* Acer Aspire SW3-013 */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Acer" ), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW3-013"), + }, + .driver_data = (void *)(BYT_RT5640_DMIC1_MAP | +BYT_RT5640_JD_SRC_JD2_IN4N | +BYT_RT5640_OVCD_TH_2000UA | +BYT_RT5640_OVCD_SF_0P75 | +BYT_RT5640_DIFF_MIC | +BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 317/444 ALSA: hda/realtek: Add quirk for HP Spectre x360 15-df1xxx
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit be0c40da888840fe91b45474cb70779e6cbaf7ca ]
HP Spectre x360 15-df1xxx with SSID 13c:863e requires similar workarounds that were applied to another HP Spectre x360 models; it has a mute LED only, no micmute LEDs, and needs the speaker GPIO seup.
--- sound/pci/hda/patch_realtek.c | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
sound/pci/hda/patch_realtek.c +42 -0
@@ -6790,6 +6790,41 @@ static void alc285_fixup_hp_spectre_x360_eb1(struct hda_codec *codec, } } +/* GPIO1 = amplifier on/off */ +static void alc285_fixup_hp_spectre_x360_df1 (struct hda_codec *codec, +const struct hda_fixup *fix, +int action) +{ +struct alc_spec *spec = codec->spec; +static const hda_nid_t conn[] = {0x02 }; +static const struct hda_pintbl pincfgs[] = { + {0x14 ,0x90170110 },/* front/high speakers */ + {0x17 ,0x90170130 },/* back/bass speakers */ + { } + }; + +// enable mute led +alc285_fixup_hp_mute_led_coefbit (codec, fix, action); + +switch (action) { +case HDA_FIXUP_ACT_PRE_PROBE : +/* needed for amp of back speakers */ + spec->gpio_mask |=0x01 ; + spec->gpio_dir |=0x01 ; +snd_hda_apply_pincfgs (codec, pincfgs); +/* share DAC to have unified volume control */ +snd_hda_override_conn_list (codec,0x14 ,ARRAY_SIZE (conn), conn); +snd_hda_override_conn_list (codec,0x17 ,ARRAY_SIZE (conn), conn); +break ; +case HDA_FIXUP_ACT_INIT : +/* need to toggle GPIO to enable the amp of back speakers */ +alc_update_gpio_data (codec,0x01 , true); +msleep (100 ); +alc_update_gpio_data (codec,0x01 , false); +break ; + } +} +static void alc285_fixup_hp_spectre_x360 (struct hda_codec *codec,const struct hda_fixup *fix,int action) {
@@ -7401,6 +7436,7 @@ enum {ALC280_FIXUP_HP_9480M ,ALC245_FIXUP_HP_X360_AMP ,ALC285_FIXUP_HP_SPECTRE_X360_EB1 , +ALC285_FIXUP_HP_SPECTRE_X360_DF1 ,ALC285_FIXUP_HP_ENVY_X360 ,ALC288_FIXUP_DELL_HEADSET_MODE , ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
@@ -9439,6 +9475,10 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc285_fixup_hp_spectre_x360_eb1 }, + [ALC285_FIXUP_HP_SPECTRE_X360_DF1] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc285_fixup_hp_spectre_x360_df1 + }, [ALC285_FIXUP_HP_ENVY_X360] = { .type = HDA_FIXUP_FUNC, .v.func = alc285_fixup_hp_envy_x360,
@@ -10038,6 +10078,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {SND_PCI_QUIRK (0x103c ,0x86c1 ,"HP Laptop 15-da3001TU" ,ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 ),SND_PCI_QUIRK (0x103c ,0x86c7 ,"HP Envy AiO 32" ,ALC274_FIXUP_HP_ENVY_GPIO ),SND_PCI_QUIRK (0x103c ,0x86e7 ,"HP Spectre x360 15-eb0xxx" ,ALC285_FIXUP_HP_SPECTRE_X360_EB1 ), +SND_PCI_QUIRK (0x103c ,0x863e ,"HP Spectre x360 15-df1xxx" ,ALC285_FIXUP_HP_SPECTRE_X360_DF1 ),SND_PCI_QUIRK (0x103c ,0x86e8 ,"HP Spectre x360 15-eb0xxx" ,ALC285_FIXUP_HP_SPECTRE_X360_EB1 ),SND_PCI_QUIRK (0x103c ,0x86f9 ,"HP Spectre x360 13-aw0xxx" ,ALC285_FIXUP_HP_SPECTRE_X360_MUTE_LED ), SND_PCI_QUIRK(0x103c, 0x8716, "HP Elite Dragonfly G2 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
@@ -10786,6 +10827,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { {.id = ALC295_FIXUP_HP_OMEN, .name = "alc295-hp-omen"}, {.id = ALC285_FIXUP_HP_SPECTRE_X360, .name = "alc285-hp-spectre-x360"}, {.id = ALC285_FIXUP_HP_SPECTRE_X360_EB1, .name = "alc285-hp-spectre-x360-eb1"}, + {.id = ALC285_FIXUP_HP_SPECTRE_X360_DF1, .name = "alc285-hp-spectre-x360-df1"}, {.id = ALC285_FIXUP_HP_ENVY_X360, .name = "alc285-hp-envy-x360"}, {.id = ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP, .name = "alc287-ideapad-bass-spk-amp"}, {.id = ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN, .name = "alc287-yoga9-bass-spk-pin"},
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 318/444 nvme-pci: add quirks for device 126f:1001
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Guan <[email protected]>
[ Upstream commit 5b960f92ac3e5b4d7f60a506a6b6735eead1da01 ]
This commit adds NVME_QUIRK_NO_DEEPEST_PS and NVME_QUIRK_BOGUS_NID for device [126f:1001].
It is similar to commit e89086c43f05 ("drivers/nvme: Add quirks for device 126f:2262")
Diff is according the dmesg, use NVME_QUIRK_IGNORE_DEV_SUBNQN.
dmesg | grep -i nvme0:
nvme nvme0: pci function 0000:01:00.0
nvme nvme0: missing or invalid SUBNQN field.
nvme nvme0: 12/0/0 default/read/poll queues
--- drivers/nvme/host/pci.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/nvme/host/pci.c +3 -0
@@ -3429,6 +3429,9 @@ static const struct pci_device_id nvme_id_table[] = { .driver_data = NVME_QUIRK_BOGUS_NID, }, { PCI_DEVICE(0x1217, 0x8760), /* O2 Micro 64GB Steam Deck */ .driver_data = NVME_QUIRK_DMAPOOL_ALIGN_512, }, + { PCI_DEVICE(0x126f, 0x1001), /* Silicon Motion generic */ + .driver_data = NVME_QUIRK_NO_DEEPEST_PS | + NVME_QUIRK_IGNORE_DEV_SUBNQN, }, { PCI_DEVICE(0x126f, 0x2262), /* Silicon Motion generic */ .driver_data = NVME_QUIRK_NO_DEEPEST_PS | NVME_QUIRK_BOGUS_NID, },
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 319/444 nvme-pci: add quirks for WDC Blue SN550 15b7:5009
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Guan <[email protected]>
[ Upstream commit ab35ad950d439ec3409509835d229b3d93d3c7f9 ]
Add two quirks for the WDC Blue SN550 (PCI ID 15b7:5009) based on user reports and hardware analysis:
- NVME_QUIRK_NO_DEEPEST_PS:
liaozw talked to me the problem and solved with nvme_core.default_ps_max_latency_us=0, so add the quirk. I also found some reports in the following link.
- NVME_QUIRK_BROKEN_MSI:
after get the lspci from Jack Rio.
I think that the disk also have NVME_QUIRK_BROKEN_MSI. described in commit d5887dc6b6c0 ("nvme-pci: Add quirk for broken MSIs") as sean said in link which match the MSI 1/32 and MSI-X 17.
Log:
lspci -nn | grep -i memory
03:00.0 Non-Volatile memory controller [0108]: Sandisk Corp SanDisk Ultra 3D / WD PC SN530, IX SN530, Blue SN550 NVMe SSD (DRAM-less) [15b7:5009] (rev 01) lspci -v -d 15b7:5009
03:00.0 Non-Volatile memory controller: Sandisk Corp SanDisk Ultra 3D / WD PC SN530, IX SN530, Blue SN550 NVMe SSD (DRAM-less) (rev 01) (prog-if 02 [NVM Express])
Subsystem: Sandisk Corp WD Blue SN550 NVMe SSD
Flags: bus master, fast devsel, latency 0, IRQ 35, IOMMU group 10
Memory at fe800000 (64-bit, non-prefetchable) [size=16K]
Memory at fe804000 (64-bit, non-prefetchable) [size=256]
Capabilities: [80] Power Management version 3
Capabilities: [90] MSI: Enable- Count=1/32 Maskable- 64bit+
Capabilities: [b0] MSI-X: Enable+ Count=17 Masked-
Capabilities: [c0] Express Endpoint, MSI 00
Capabilities: [100] Advanced Error Reporting
Capabilities: [150] Device Serial Number 00-00-00-00-00-00-00-00
Capabilities: [1b8] Latency Tolerance Reporting
Capabilities: [300] Secondary PCI Express
Capabilities: [900] L1 PM Substates
Kernel driver in use: nvme
dmesg | grep nvme
[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-6.12.20-amd64-desktop-rolling root=UUID= ro splash quiet nvme_core.default_ps_max_latency_us=0 DEEPIN_GFXMODE= [ 0.059301] Kernel command line: BOOT_IMAGE=/vmlinuz-6.12.20-amd64-desktop-rolling root=UUID= ro splash quiet nvme_core.default_ps_max_latency_us=0 DEEPIN_GFXMODE= [ 0.542430] nvme nvme0: pci function 0000:03:00.0 [ 0.560426] nvme nvme0: allocated 32 MiB host memory buffer. [ 0.562491] nvme nvme0: 16/0/0 default/read/poll queues [ 0.567764] nvme0n1: p1 p2 p3 p4 p5 p6 p7 p8 p9 [ 6.388726] EXT4-fs (nvme0n1p7): mounted filesystem ro with ordered data mode. Quota mode: none. [ 6.893421] EXT4-fs (nvme0n1p7): re-mounted r/w. Quota mode: none. [ 7.125419] Adding 16777212k swap on /dev/nvme0n1p8. Priority:-2 extents:1 across:16777212k SS [ 7.157588] EXT4-fs (nvme0n1p6): mounted filesystem r/w with ordered data mode. Quota mode: none. [ 7.165021] EXT4-fs (nvme0n1p9): mounted filesystem r/w with ordered data mode. Quota mode: none. [ 8.036932] nvme nvme0: using unchecked data buffer [ 8.096023] block nvme0n1: No UUID available providing old NGUID
--- drivers/nvme/host/pci.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/nvme/host/pci.c +3 -0
@@ -3455,6 +3455,9 @@ static const struct pci_device_id nvme_id_table[] = { NVME_QUIRK_IGNORE_DEV_SUBNQN, }, { PCI_DEVICE(0x15b7, 0x5008), /* Sandisk SN530 */ .driver_data = NVME_QUIRK_BROKEN_MSI }, + { PCI_DEVICE(0x15b7, 0x5009), /* Sandisk SN550 */ + .driver_data =NVME_QUIRK_BROKEN_MSI | + NVME_QUIRK_NO_DEEPEST_PS }, { PCI_DEVICE(0x1987, 0x5012), /* Phison E12 */ .driver_data = NVME_QUIRK_BOGUS_NID, }, { PCI_DEVICE(0x1987, 0x5016), /* Phison E16 */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 320/444 nvmet-tcp: dont restore null sk_state_change
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alistair Francis <[email protected]>
[ Upstream commit 46d22b47df2741996af277a2838b95f130436c13 ]
queue->state_change is set as part of nvmet_tcp_set_queue_sock(), but if the TCP connection isn't established when nvmet_tcp_set_queue_sock() is called then queue->state_change isn't set and sock->sk->sk_state_change isn't replaced.
As such we don't need to restore sock->sk->sk_state_change if queue->state_change is NULL.
This avoids NULL pointer dereferences such as this:
[ 286.462026][ C0] BUG: kernel NULL pointer dereference, address: 0000000000000000 [ 286.462814][ C0] #PF: supervisor instruction fetch in kernel mode [ 286.463796][ C0] #PF: error_code(0x0010) - not-present page [ 286.464392][ C0] PGD 8000000140620067 P4D 8000000140620067 PUD 114201067 PMD 0 [ 286.465086][ C0] Oops: Oops: 0010 [#1] SMP KASAN PTI [ 286.465559][ C0] CPU: 0 UID: 0 PID: 1628 Comm: nvme Not tainted 6.15.0-rc2+ #11 PREEMPT(voluntary) [ 286.466393][ C0] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014 [ 286.467147][ C0] RIP: 0010:0x0 [ 286.467420][ C0] Code: Unable to access opcode bytes at 0xffffffffffffffd6. [ 286.467977][ C0] RSP: 0018:ffff8883ae008580 EFLAGS: 00010246 [ 286.468425][ C0] RAX: 0000000000000000 RBX: ffff88813fd34100 RCX: ffffffffa386cc43 [ 286.469019][ C0] RDX: 1ffff11027fa68b6 RSI: 0000000000000008 RDI: ffff88813fd34100 [ 286.469545][ C0] RBP: ffff88813fd34160 R08: 0000000000000000 R09: ffffed1027fa682c [ 286.470072][ C0] R10: ffff88813fd34167 R11: 0000000000000000 R12: ffff88813fd344c3 [ 286.470585][ C0] R13: ffff88813fd34112 R14: ffff88813fd34aec R15: ffff888132cdd268 [ 286.471070][ C0] FS: 00007fe3c04c7d80(0000) GS:ffff88840743f000(0000) knlGS:0000000000000000 [ 286.471644][ C0] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 286.472543][ C0] CR2: ffffffffffffffd6 CR3: 000000012daca000 CR4: 00000000000006f0 [ 286.473500][ C0] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 286.474467][ C0] DR3: 0000000000000000 DR6: 00000000ffff07f0 DR7: 0000000000000400 [ 286.475453][ C0] Call Trace: [ 286.476102][ C0] <IRQ> [ 286.476719][ C0] tcp_fin+0x2bb/0x440 [ 286.477429][ C0] tcp_data_queue+0x190f/0x4e60 [ 286.478174][ C0] ? __build_skb_around+0x234/0x330 [ 286.478940][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.479659][ C0] ? __pfx_tcp_data_queue+0x10/0x10 [ 286.480431][ C0] ? tcp_try_undo_loss+0x640/0x6c0 [ 286.481196][ C0] ? seqcount_lockdep_reader_access.constprop.0+0x82/0x90 [ 286.482046][ C0] ? kvm_clock_get_cycles+0x14/0x30 [ 286.482769][ C0] ? ktime_get+0x66/0x150 [ 286.483433][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.484146][ C0] tcp_rcv_established+0x6e4/0x2050 [ 286.484857][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.485523][ C0] ? ipv4_dst_check+0x160/0x2b0 [ 286.486203][ C0] ? __pfx_tcp_rcv_established+0x10/0x10 [ 286.486917][ C0] ? lock_release+0x217/0x2c0 [ 286.487595][ C0] tcp_v4_do_rcv+0x4d6/0x9b0 [ 286.488279][ C0] tcp_v4_rcv+0x2af8/0x3e30 [ 286.488904][ C0] ? raw_local_deliver+0x51b/0xad0 [ 286.489551][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.490198][ C0] ? __pfx_tcp_v4_rcv+0x10/0x10 [ 286.490813][ C0] ? __pfx_raw_local_deliver+0x10/0x10 [ 286.491487][ C0] ? __pfx_nf_confirm+0x10/0x10 [nf_conntrack] [ 286.492275][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.492900][ C0] ip_protocol_deliver_rcu+0x8f/0x370 [ 286.493579][ C0] ip_local_deliver_finish+0x297/0x420 [ 286.494268][ C0] ip_local_deliver+0x168/0x430 [ 286.494867][ C0] ? __pfx_ip_local_deliver+0x10/0x10 [ 286.495498][ C0] ? __pfx_ip_local_deliver_finish+0x10/0x10 [ 286.496204][ C0] ? ip_rcv_finish_core+0x19a/0x1f20 [ 286.496806][ C0] ? lock_release+0x217/0x2c0 [ 286.497414][ C0] ip_rcv+0x455/0x6e0 [ 286.497945][ C0] ? __pfx_ip_rcv+0x10/0x10 [ 286.498550][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.499137][ C0] ? __pfx_ip_rcv_finish+0x10/0x10 [ 286.499763][ C0] ? lock_release+0x217/0x2c0 [ 286.500327][ C0] ? dl_scaled_delta_exec+0xd1/0x2c0 [ 286.500922][ C0] ? __pfx_ip_rcv+0x10/0x10 [ 286.501480][ C0] __netif_receive_skb_one_core+0x166/0x1b0 [ 286.502173][ C0] ? __pfx___netif_receive_skb_one_core+0x10/0x10 [ 286.502903][ C0] ? lock_acquire+0x2b2/0x310 [ 286.503487][ C0] ? process_backlog+0x372/0x1350 [ 286.504087][ C0] ? lock_release+0x217/0x2c0 [ 286.504642][ C0] process_backlog+0x3b9/0x1350 [ 286.505214][ C0] ? process_backlog+0x372/0x1350 [ 286.505779][ C0] __napi_poll.constprop.0+0xa6/0x490 [ 286.506363][ C0] net_rx_action+0x92e/0xe10 [ 286.506889][ C0] ? __pfx_net_rx_action+0x10/0x10 [ 286.507437][ C0] ? timerqueue_add+0x1f0/0x320 [ 286.507977][ C0] ? sched_clock_cpu+0x68/0x540 [ 286.508492][ C0] ? lock_acquire+0x2b2/0x310 [ 286.509043][ C0] ? kvm_sched_clock_read+0xd/0x20 [ 286.509607][ C0] ? handle_softirqs+0x1aa/0x7d0 [ 286.510187][ C0] handle_softirqs+0x1f2/0x7d0 [ 286.510754][ C0] ? __pfx_handle_softirqs+0x10/0x10 [ 286.511348][ C0] ? irqtime_account_irq+0x181/0x290 [ 286.511937][ C0] ? __dev_queue_xmit+0x85d/0x3450 [ 286.512510][ C0] do_softirq.part.0+0x89/0xc0 [ 286.513100][ C0] </IRQ> [ 286.513548][ C0] <TASK> [ 286.513953][ C0] __local_bh_enable_ip+0x112/0x140 [ 286.514522][ C0] ? __dev_queue_xmit+0x85d/0x3450 [ 286.515072][ C0] __dev_queue_xmit+0x872/0x3450 [ 286.515619][ C0] ? nft_do_chain+0xe16/0x15b0 [nf_tables] [ 286.516252][ C0] ? __pfx___dev_queue_xmit+0x10/0x10 [ 286.516817][ C0] ? selinux_ip_postroute+0x43c/0xc50 [ 286.517433][ C0] ? __pfx_selinux_ip_postroute+0x10/0x10 [ 286.518061][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.518606][ C0] ? ip_output+0x164/0x4a0 [ 286.519149][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.519671][ C0] ? ip_finish_output2+0x17d5/0x1fb0 [ 286.520258][ C0] ip_finish_output2+0xb4b/0x1fb0 [ 286.520787][ C0] ? __pfx_ip_finish_output2+0x10/0x10 [ 286.521355][ C0] ? __ip_finish_output+0x15d/0x750 [ 286.521890][ C0] ip_output+0x164/0x4a0 [ 286.522372][ C0] ? __pfx_ip_output+0x10/0x10 [ 286.522872][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.523402][ C0] ? _raw_spin_unlock_irqrestore+0x4c/0x60 [ 286.524031][ C0] ? __pfx_ip_finish_output+0x10/0x10 [ 286.524605][ C0] ? __ip_queue_xmit+0x999/0x2260 [ 286.525200][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.525744][ C0] ? ipv4_dst_check+0x16a/0x2b0 [ 286.526279][ C0] ? lock_release+0x217/0x2c0 [ 286.526793][ C0] __ip_queue_xmit+0x1883/0x2260 [ 286.527324][ C0] ? __skb_clone+0x54c/0x730 [ 286.527827][ C0] __tcp_transmit_skb+0x209b/0x37a0 [ 286.528374][ C0] ? __pfx___tcp_transmit_skb+0x10/0x10 [ 286.528952][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.529472][ C0] ? seqcount_lockdep_reader_access.constprop.0+0x82/0x90 [ 286.530152][ C0] ? trace_hardirqs_on+0x12/0x120 [ 286.530691][ C0] tcp_write_xmit+0xb81/0x88b0 [ 286.531224][ C0] ? mod_memcg_state+0x4d/0x60 [ 286.531736][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.532253][ C0] __tcp_push_pending_frames+0x90/0x320 [ 286.532826][ C0] tcp_send_fin+0x141/0xb50 [ 286.533352][ C0] ? __pfx_tcp_send_fin+0x10/0x10 [ 286.533908][ C0] ? __local_bh_enable_ip+0xab/0x140 [ 286.534495][ C0] inet_shutdown+0x243/0x320 [ 286.535077][ C0] nvme_tcp_alloc_queue+0xb3b/0x2590 [nvme_tcp] [ 286.535709][ C0] ? do_raw_spin_lock+0x129/0x260 [ 286.536314][ C0] ? __pfx_nvme_tcp_alloc_queue+0x10/0x10 [nvme_tcp] [ 286.536996][ C0] ? do_raw_spin_unlock+0x54/0x1e0 [ 286.537550][ C0] ? _raw_spin_unlock+0x29/0x50 [ 286.538127][ C0] ? do_raw_spin_lock+0x129/0x260 [ 286.538664][ C0] ? __pfx_do_raw_spin_lock+0x10/0x10 [ 286.539249][ C0] ? nvme_tcp_alloc_admin_queue+0xd5/0x340 [nvme_tcp] [ 286.539892][ C0] ? __wake_up+0x40/0x60 [ 286.540392][ C0] nvme_tcp_alloc_admin_queue+0xd5/0x340 [nvme_tcp] [ 286.541047][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.541589][ C0] nvme_tcp_setup_ctrl+0x8b/0x7a0 [nvme_tcp] [ 286.542254][ C0] ? _raw_spin_unlock_irqrestore+0x4c/0x60 [ 286.542887][ C0] ? __pfx_nvme_tcp_setup_ctrl+0x10/0x10 [nvme_tcp] [ 286.543568][ C0] ? trace_hardirqs_on+0x12/0x120 [ 286.544166][ C0] ? _raw_spin_unlock_irqrestore+0x35/0x60 [ 286.544792][ C0] ? nvme_change_ctrl_state+0x196/0x2e0 [nvme_core] [ 286.545477][ C0] nvme_tcp_create_ctrl+0x839/0xb90 [nvme_tcp] [ 286.546126][ C0] nvmf_dev_write+0x3db/0x7e0 [nvme_fabrics] [ 286.546775][ C0] ? rw_verify_area+0x69/0x520 [ 286.547334][ C0] vfs_write+0x218/0xe90 [ 286.547854][ C0] ? do_syscall_64+0x9f/0x190 [ 286.548408][ C0] ? trace_hardirqs_on_prepare+0xdb/0x120 [ 286.549037][ C0] ? syscall_exit_to_user_mode+0x93/0x280 [ 286.549659][ C0] ? __pfx_vfs_write+0x10/0x10 [ 286.550259][ C0] ? do_syscall_64+0x9f/0x190 [ 286.550840][ C0] ? syscall_exit_to_user_mode+0x8e/0x280 [ 286.551516][ C0] ? trace_hardirqs_on_prepare+0xdb/0x120 [ 286.552180][ C0] ? syscall_exit_to_user_mode+0x93/0x280 [ 286.552834][ C0] ? ksys_read+0xf5/0x1c0 [ 286.553386][ C0] ? __pfx_ksys_read+0x10/0x10 [ 286.553964][ C0] ksys_write+0xf5/0x1c0 [ 286.554499][ C0] ? __pfx_ksys_write+0x10/0x10 [ 286.555072][ C0] ? trace_hardirqs_on_prepare+0xdb/0x120 [ 286.555698][ C0] ? syscall_exit_to_user_mode+0x93/0x280 [ 286.556319][ C0] ? do_syscall_64+0x54/0x190 [ 286.556866][ C0] do_syscall_64+0x93/0x190 [ 286.557420][ C0] ? rcu_read_unlock+0x17/0x60 [ 286.557986][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.558526][ C0] ? lock_release+0x217/0x2c0 [ 286.559087][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.559659][ C0] ? count_memcg_events.constprop.0+0x4a/0x60 [ 286.560476][ C0] ? exc_page_fault+0x7a/0x110 [ 286.561064][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.561647][ C0] ? lock_release+0x217/0x2c0 [ 286.562257][ C0] ? do_user_addr_fault+0x171/0xa00 [ 286.562839][ C0] ? do_user_addr_fault+0x4a2/0xa00 [ 286.563453][ C0] ? irqentry_exit_to_user_mode+0x84/0x270 [ 286.564112][ C0] ? rcu_is_watching+0x11/0xb0 [ 286.564677][ C0] ? irqentry_exit_to_user_mode+0x84/0x270 [ 286.565317][ C0] ? trace_hardirqs_on_prepare+0xdb/0x120 [ 286.565922][ C0] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 286.566542][ C0] RIP: 0033:0x7fe3c05e6504 [ 286.567102][ C0] Code: c7 00 16 00 00 00 b8 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 80 3d c5 8b 10 00 00 74 13 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 55 48 89 e5 48 83 ec 20 48 89 [ 286.568931][ C0] RSP: 002b:00007fff76444f58 EFLAGS: 00000202 ORIG_RAX: 0000000000000001 [ 286.569807][ C0] RAX: ffffffffffffffda RBX: 000000003b40d930 RCX: 00007fe3c05e6504 [ 286.570621][ C0] RDX: 00000000000000cf RSI: 000000003b40d930 RDI: 0000000000000003 [ 286.571443][ C0] RBP: 0000000000000003 R08: 00000000000000cf R09: 000000003b40d930 [ 286.572246][ C0] R10: 0000000000000000 R11: 0000000000000202 R12: 000000003b40cd60 [ 286.573069][ C0] R13: 00000000000000cf R14: 00007fe3c07417f8 R15: 00007fe3c073502e [ 286.573886][ C0] </TASK>
--- drivers/nvme/target/tcp.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/nvme/target/tcp.c +3 -0
@@ -1456,6 +1456,9 @@ static void nvmet_tcp_restore_socket_callbacks(struct nvmet_tcp_queue *queue) {struct socket *sock = queue->sock; +if (!queue->state_change) +return ; +write_lock_bh (&sock->sk->sk_callback_lock); sock->sk->sk_data_ready = queue->data_ready; sock->sk->sk_state_change = queue->state_change;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 321/444 io_uring/fdinfo: annotate racy sq/cq head/tail reads
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
[ Upstream commit f024d3a8ded0d8d2129ae123d7a5305c29ca44ce ]
syzbot complains about the cached sq head read, and it's totally right. But we don't need to care, it's just reading fdinfo, and reading the CQ or SQ tail/head entries are known racy in that they are just a view into that very instant and may of course be outdated by the time they are reported.
Annotate both the SQ head and CQ tail read with data_race() to avoid this syzbot complaint.
--- io_uring/fdinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
io_uring/fdinfo.c +2 -2
@@ -81,11 +81,11 @@ __cold void io_uring_show_fdinfo(struct seq_file *m, struct file *f)seq_printf (m,"SqMask:\t0x%x\n" , sq_mask);seq_printf (m,"SqHead:\t%u\n" , sq_head);seq_printf (m,"SqTail:\t%u\n" , sq_tail); -seq_printf (m,"CachedSqHead:\t%u\n" , ctx->cached_sq_head); +seq_printf (m,"CachedSqHead:\t%u\n" ,data_race (ctx->cached_sq_head));seq_printf (m,"CqMask:\t0x%x\n" , cq_mask);seq_printf (m,"CqHead:\t%u\n" , cq_head);seq_printf (m,"CqTail:\t%u\n" , cq_tail); -seq_printf (m,"CachedCqTail:\t%u\n" , ctx->cached_cq_tail); +seq_printf (m,"CachedCqTail:\t%u\n" ,data_race (ctx->cached_cq_tail));seq_printf (m,"SQEs:\t%u\n" , sq_tail - sq_head); sq_entries =min (sq_tail - sq_head, ctx->sq_entries);for (i =0 ; i < sq_entries; i++) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 322/444 cifs: Fix and improve cifs_query_path_info() and cifs_query_file_info()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pali Rohár <[email protected]>
[ Upstream commit 1041c117a2c33cdffc4f695ac4b469e9124d24d5 ]
When CAP_NT_SMBS was not negotiated then do not issue CIFSSMBQPathInfo() and CIFSSMBQFileInfo() commands. CIFSSMBQPathInfo() is not supported by non-NT Win9x SMB server and CIFSSMBQFileInfo() returns from Win9x SMB server bogus data in Attributes field (for example lot of files are marked as reparse points, even Win9x does not support them and read-only bit is not marked for read-only files). Correct information is returned by CIFSFindFirst() or SMBQueryInformation() command.
So as a fallback in cifs_query_path_info() function use CIFSFindFirst() with SMB_FIND_FILE_FULL_DIRECTORY_INFO level which is supported by both NT and non-NT servers and as a last option use SMBQueryInformation() as it was before.
And in function cifs_query_file_info() immediately returns -EOPNOTSUPP when not communicating with NT server. Client then revalidate inode entry by the cifs_query_path_info() call, which is working fine. So fstat() syscall on already opened file will receive correct information.
Note that both fallback functions in non-UNICODE mode expands wildcards. Therefore those fallback functions cannot be used on paths which contain SMB wildcard characters (* ? " > <).
CIFSFindFirst() returns all 4 time attributes as opposite of SMBQueryInformation() which returns only one.
With this change it is possible to query all 4 times attributes from Win9x server and at the same time, client minimize sending of unsupported commands to server.
--- fs/smb/client/smb1ops.c | 103 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 95 insertions(+), 8 deletions(-)
fs/smb/client/smb1ops.c +95 -8
@@ -541,24 +541,104 @@ static int cifs_query_path_info(const unsigned int xid,const char *full_path, struct cifs_open_info_data *data) { - int rc; + int rc = -EOPNOTSUPP;FILE_ALL_INFO fi = {}; +struct cifs_search_info search_info = {}; +bool non_unicode_wildcard = false; data->symlink = false; data->adjust_tz = false; -/* could do find first instead but this returns more info */ - rc =CIFSSMBQPathInfo (xid, tcon, full_path, &fi,0 /* not legacy */ , cifs_sb->local_nls, -cifs_remap (cifs_sb));/* -* BB optimize code so we do not make the above call when server claims -* no NT SMB support and the above call failed at least once - set flag -* in tcon or mount. +* First try CIFSSMBQPathInfo() function which returns more info +* (NumberOfLinks) than CIFSFindFirst() fallback function. +* Some servers like Win9x do not support SMB_QUERY_FILE_ALL_INFO over +* TRANS2_QUERY_PATH_INFORMATION, but supports it with filehandle over +* TRANS2_QUERY_FILE_INFORMATION (function CIFSSMBQFileInfo(). But SMB +* Open command on non-NT servers works only for files, does not work +* for directories. And moreover Win9x SMB server returns bogus data in +* SMB_QUERY_FILE_ALL_INFO Attributes field. So for non-NT servers, +* do not even use CIFSSMBQPathInfo() or CIFSSMBQFileInfo() function. +*/ +if (tcon->ses->capabilities &CAP_NT_SMBS ) + rc =CIFSSMBQPathInfo (xid, tcon, full_path, &fi,0 /* not legacy */ , + cifs_sb->local_nls,cifs_remap (cifs_sb)); + +/* +* Non-UNICODE variant of fallback functions below expands wildcards, +* so they cannot be used for querying paths with wildcard characters. */ -if ((rc == -EOPNOTSUPP ) || (rc == -EINVAL )) { +if (rc && !(tcon->ses->capabilities &CAP_UNICODE ) &&strpbrk (full_path,"*?\"><" )) + non_unicode_wildcard = true; + +/* +* Then fallback to CIFSFindFirst() which works also with non-NT servers +* but does not does not provide NumberOfLinks. +*/ +if ((rc == -EOPNOTSUPP || rc == -EINVAL ) && + !non_unicode_wildcard) { +if (!(tcon->ses->capabilities & tcon->ses->server->vals->cap_nt_find)) + search_info.info_level =SMB_FIND_FILE_INFO_STANDARD ; +else + search_info.info_level =SMB_FIND_FILE_FULL_DIRECTORY_INFO ; + rc =CIFSFindFirst (xid, tcon, full_path, cifs_sb,NULL , +CIFS_SEARCH_CLOSE_ALWAYS |CIFS_SEARCH_CLOSE_AT_END , + &search_info, false); +if (rc ==0 ) { +if (!(tcon->ses->capabilities & tcon->ses->server->vals->cap_nt_find)) { +FIND_FILE_STANDARD_INFO *di; +int offset = tcon->ses->server->timeAdj; + + di = (FIND_FILE_STANDARD_INFO *)search_info.srch_entries_start; + fi.CreationTime =cpu_to_le64 (cifs_UnixTimeToNT (cnvrtDosUnixTm ( + di->CreationDate, di->CreationTime, offset))); + fi.LastAccessTime =cpu_to_le64 (cifs_UnixTimeToNT (cnvrtDosUnixTm ( + di->LastAccessDate, di->LastAccessTime, offset))); + fi.LastWriteTime =cpu_to_le64 (cifs_UnixTimeToNT (cnvrtDosUnixTm ( + di->LastWriteDate, di->LastWriteTime, offset))); + fi.ChangeTime = fi.LastWriteTime; + fi.Attributes =cpu_to_le32 (le16_to_cpu (di->Attributes)); + fi.AllocationSize =cpu_to_le64 (le32_to_cpu (di->AllocationSize)); + fi.EndOfFile =cpu_to_le64 (le32_to_cpu (di->DataSize)); + }else { +FILE_FULL_DIRECTORY_INFO *di; + + di = (FILE_FULL_DIRECTORY_INFO *)search_info.srch_entries_start; + fi.CreationTime = di->CreationTime; + fi.LastAccessTime = di->LastAccessTime; + fi.LastWriteTime = di->LastWriteTime; + fi.ChangeTime = di->ChangeTime; + fi.Attributes = di->ExtFileAttributes; + fi.AllocationSize = di->AllocationSize; + fi.EndOfFile = di->EndOfFile; + fi.EASize = di->EaSize; + } + fi.NumberOfLinks =cpu_to_le32 (1 ); + fi.DeletePending =0 ; + fi.Directory = !!(le32_to_cpu (fi.Attributes) &ATTR_DIRECTORY ); +cifs_buf_release (search_info.ntwrk_buf_start); + }else if (!full_path[0 ]) { +/* +* CIFSFindFirst() does not work on root path if the +* root path was exported on the server from the top +* level path (drive letter). +*/ + rc = -EOPNOTSUPP ; + } + } + +/* +* If everything failed then fallback to the legacy SMB command +* SMB_COM_QUERY_INFORMATION which works with all servers, but +* provide just few information. +*/ +if ((rc == -EOPNOTSUPP || rc == -EINVAL ) && !non_unicode_wildcard) { rc =SMBQueryInformation (xid, tcon, full_path, &fi, cifs_sb->local_nls,cifs_remap (cifs_sb)); data->adjust_tz = true; + }else if ((rc == -EOPNOTSUPP || rc == -EINVAL ) && non_unicode_wildcard) { +/* Path with non-UNICODE wildcard character cannot exist. */ + rc = -ENOENT ; }if (!rc) {
@@ -655,6 +735,13 @@ static int cifs_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,int rc;FILE_ALL_INFO fi = {}; +/* +* CIFSSMBQFileInfo() for non-NT servers returns bogus data in +* Attributes fields. So do not use this command for non-NT servers. +*/ +if (!(tcon->ses->capabilities &CAP_NT_SMBS )) +return -EOPNOTSUPP ; +if (cfile->symlink_target) { data->symlink_target =kstrdup (cfile->symlink_target,GFP_KERNEL );if (!data->symlink_target)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 323/444 cifs: Fix changing times and read-only attr over SMB1 smb_set_file_info() function
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pali Rohár <[email protected]>
[ Upstream commit f122121796f91168d0894c2710b8dd71330a34f8 ]
Function CIFSSMBSetPathInfo() is not supported by non-NT servers and returns error. Fallback code via open filehandle and CIFSSMBSetFileInfo() does not work neither because CIFS_open() works also only on NT server.
Therefore currently the whole smb_set_file_info() function as a SMB1 callback for the ->set_file_info() does not work with older non-NT SMB servers, like Win9x and others.
This change implements fallback code in smb_set_file_info() which will works with any server and allows to change time values and also to set or clear read-only attributes.
To make existing fallback code via CIFSSMBSetFileInfo() working with also non-NT servers, it is needed to change open function from CIFS_open() (which is NT specific) to cifs_open_file() which works with any server (this is just a open wrapper function which choose the correct open function supported by the server).
CIFSSMBSetFileInfo() is working also on non-NT servers, but zero time values are not treated specially. So first it is needed to fill all time values if some of them are missing, via cifs_query_path_info() call.
There is another issue, opening file in write-mode (needed for changing attributes) is not possible when the file has read-only attribute set. The only option how to clear read-only attribute is via SMB_COM_SETATTR command. And opening directory is not possible neither and here the SMB_COM_SETATTR command is the only option how to change attributes. And CIFSSMBSetFileInfo() does not honor setting read-only attribute, so for setting is also needed to use SMB_COM_SETATTR command.
Existing code in cifs_query_path_info() is already using SMB_COM_GETATTR as a fallback code path (function SMBQueryInformation()), so introduce a new function SMBSetInformation which will implement SMB_COM_SETATTR command.
My testing showed that Windows XP SMB1 client is also using SMB_COM_SETATTR command for setting or clearing read-only attribute against non-NT server. So this can prove that this is the correct way how to do it.
With this change it is possible set all 4 time values and all attributes, including clearing and setting read-only bit on non-NT SMB servers. Tested against Win98 SMB1 server.
This change fixes "touch" command which was failing when called on existing file. And fixes also "chmod +w" and "chmod -w" commands which were also failing (as they are changing read-only attribute).
Note that this change depends on following change "cifs: Improve cifs_query_path_info() and cifs_query_file_info()" as it require to query all 4 time attribute values.
--- fs/smb/client/cifspdu.h | 5 +- fs/smb/client/cifsproto.h | 4 ++ fs/smb/client/cifssmb.c | 57 +++++++++++++++++++ fs/smb/client/smb1ops.c | 112 +++++++++++++++++++++++++++++++++++--- 4 files changed, 166 insertions(+), 12 deletions(-)
fs/smb/client/cifspdu.h +2 -3
@@ -1226,10 +1226,9 @@ typedef struct smb_com_query_information_rsp {typedef struct smb_com_setattr_req {struct smb_hdr hdr;/* wct = 8 */ __le16 attr; -__le16 time_low; -__le16 time_high; +__le32 last_write_time;__le16 reserved[5 ];/* must be zero */ -__u16 ByteCount; +__le16 ByteCount;__u8 BufferFormat;/* 4 = ASCII */ unsigned char fileName[]; } __attribute__((packed))SETATTR_REQ ;
fs/smb/client/cifsproto.h +4 -0
@@ -398,6 +398,10 @@ extern int CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon);extern int CIFSSMBQFSPosixInfo (const unsigned int xid,struct cifs_tcon *tcon,struct kstatfs *FSData); +extern int SMBSetInformation (const unsigned int xid,struct cifs_tcon *tcon, +const char *fileName,__le32 attributes,__le64 write_time, +const struct nls_table *nls_codepage, +struct cifs_sb_info *cifs_sb); extern int CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, const char *fileName, const FILE_BASIC_INFO *data, const struct nls_table *nls_codepage,
fs/smb/client/cifssmb.c +57 -0
63 lines not on this page · raw message
fs/smb/client/smb1ops.c +103 -9
149 lines not on this page · raw message
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 324/444 btrfs: correct the order of prelim_ref arguments in btrfs__prelim_ref
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Goldwyn Rodrigues <[email protected]>
[ Upstream commit bc7e0975093567f51be8e1bdf4aa5900a3cf0b1e ]
btrfs_prelim_ref() calls the old and new reference variables in the incorrect order. This causes a NULL pointer dereference because oldref is passed as NULL to trace_btrfs_prelim_ref_insert().
Note, trace_btrfs_prelim_ref_insert() is being called with newref as oldref (and oldref as NULL) on purpose in order to print out the values of newref.
To reproduce:
echo 1 > /sys/kernel/debug/tracing/events/btrfs/btrfs_prelim_ref_insert/enable
Perform some writeback operations.
Backtrace: BUG: kernel NULL pointer dereference, address: 0000000000000018 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 115949067 P4D 115949067 PUD 11594a067 PMD 0 Oops: Oops: 0000 [#1] SMP NOPTI CPU: 1 UID: 0 PID: 1188 Comm: fsstress Not tainted 6.15.0-rc2-tester+ #47 PREEMPT(voluntary) 7ca2cef72d5e9c600f0c7718adb6462de8149622 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.3-2-gc13ff2cd-prebuilt.qemu.org 04/01/2014 RIP: 0010:trace_event_raw_event_btrfs__prelim_ref+0x72/0x130 Code: e8 43 81 9f ff 48 85 c0 74 78 4d 85 e4 0f 84 8f 00 00 00 49 8b 94 24 c0 06 00 00 48 8b 0a 48 89 48 08 48 8b 52 08 48 89 50 10 <49> 8b 55 18 48 89 50 18 49 8b 55 20 48 89 50 20 41 0f b6 55 28 88 RSP: 0018:ffffce44820077a0 EFLAGS: 00010286 RAX: ffff8c6b403f9014 RBX: ffff8c6b55825730 RCX: 304994edf9cf506b RDX: d8b11eb7f0fdb699 RSI: ffff8c6b403f9010 RDI: ffff8c6b403f9010 RBP: 0000000000000001 R08: 0000000000000001 R09: 0000000000000010 R10: 00000000ffffffff R11: 0000000000000000 R12: ffff8c6b4e8fb000 R13: 0000000000000000 R14: ffffce44820077a8 R15: ffff8c6b4abd1540 FS: 00007f4dc6813740(0000) GS:ffff8c6c1d378000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000018 CR3: 000000010eb42000 CR4: 0000000000750ef0 PKRU: 55555554 Call Trace: <TASK> prelim_ref_insert+0x1c1/0x270 find_parent_nodes+0x12a6/0x1ee0 ? __entry_text_end+0x101f06/0x101f09 ? srso_alias_return_thunk+0x5/0xfbef5 ? srso_alias_return_thunk+0x5/0xfbef5 ? srso_alias_return_thunk+0x5/0xfbef5 ? srso_alias_return_thunk+0x5/0xfbef5 btrfs_is_data_extent_shared+0x167/0x640 ? fiemap_process_hole+0xd0/0x2c0 extent_fiemap+0xa5c/0xbc0 ? __entry_text_end+0x101f05/0x101f09 btrfs_fiemap+0x7e/0xd0 do_vfs_ioctl+0x425/0x9d0 __x64_sys_ioctl+0x75/0xc0
--- include/trace/events/btrfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/trace/events/btrfs.h +1 -1
@@ -1956,7 +1956,7 @@ DECLARE_EVENT_CLASS(btrfs__prelim_ref, TP_PROTO(const struct btrfs_fs_info *fs_info, const struct prelim_ref *oldref, const struct prelim_ref *newref, u64 tree_size), -TP_ARGS (fs_info, newref, oldref, tree_size), +TP_ARGS (fs_info, oldref, newref, tree_size),TP_STRUCT__entry_btrfs ( __field( u64, root_id )
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 325/444 btrfs: avoid NULL pointer dereference if no valid csum tree
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
[ Upstream commit f95d186255b319c48a365d47b69bd997fecb674e ]
[BUG]
When trying read-only scrub on a btrfs with rescue=idatacsums mount option, it will crash with the following call trace:
BUG: kernel NULL pointer dereference, address: 0000000000000208 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page CPU: 1 UID: 0 PID: 835 Comm: btrfs Tainted: G O 6.15.0-rc3-custom+ #236 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS unknown 02/02/2022 RIP: 0010:btrfs_lookup_csums_bitmap+0x49/0x480 [btrfs] Call Trace: <TASK> scrub_find_fill_first_stripe+0x35b/0x3d0 [btrfs] scrub_simple_mirror+0x175/0x290 [btrfs] scrub_stripe+0x5f7/0x6f0 [btrfs] scrub_chunk+0x9a/0x150 [btrfs] scrub_enumerate_chunks+0x333/0x660 [btrfs] btrfs_scrub_dev+0x23e/0x600 [btrfs] btrfs_ioctl+0x1dcf/0x2f80 [btrfs] __x64_sys_ioctl+0x97/0xc0 do_syscall_64+0x4f/0x120 entry_SYSCALL_64_after_hwframe+0x76/0x7e
[CAUSE]
Mount option "rescue=idatacsums" will completely skip loading the csum tree, so that any data read will not find any data csum thus we will ignore data checksum verification.
Normally call sites utilizing csum tree will check the fs state flag NO_DATA_CSUMS bit, but unfortunately scrub does not check that bit at all.
This results in scrub to call btrfs_search_slot() on a NULL pointer and triggered above crash.
[FIX]
Check both extent and csum tree root before doing any tree search.
--- fs/btrfs/scrub.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/btrfs/scrub.c +2 -2
@@ -1538,8 +1538,8 @@ static int scrub_find_fill_first_stripe(struct btrfs_block_group *bg,u64 extent_gen;int ret; -if (unlikely (!extent_root)) { -btrfs_err (fs_info,"no valid extent root for scrub" ); +if (unlikely (!extent_root || !csum_root)) { +btrfs_err (fs_info,"no valid extent or csum root for scrub" );return -EUCLEAN ; } memset(stripe->sectors, 0, sizeof(struct scrub_sector_verification) *
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 326/444 tools: ynl-gen: validate 0 len strings from kernel
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Wei <[email protected]>
[ Upstream commit 4720f9707c783f642332dee3d56dccaefa850e42 ]
Strings from the kernel are guaranteed to be null terminated and ynl_attr_validate() checks for this. But it doesn't check if the string has a len of 0, which would cause problems when trying to access data[len - 1]. Fix this by checking that len is positive.
--- tools/net/ynl/lib/ynl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/net/ynl/lib/ynl.c +1 -1
@@ -368,7 +368,7 @@ int ynl_attr_validate(struct ynl_parse_arg *yarg, const struct nlattr *attr) "Invalid attribute (binary %s)", policy->name);return -1 ;case YNL_PT_NUL_STR : -if ((!policy->len || len <= policy->len) && !data[len -1 ]) +if (len && (!policy->len || len <= policy->len) && !data[len -1 ])break ;yerr (yarg->ys,YNL_ERROR_ATTR_INVALID ,"Invalid attribute (string %s)" , policy->name);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 327/444 wifi: iwlwifi: add support for Killer on MTL
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit ebedf8b7f05b9c886d68d63025db8d1b12343157 ]
For now, we need another entry for these devices, this will be changed completely for 6.16.
--- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/wireless/intel/iwlwifi/pcie/drv.c +2 -0
@@ -580,6 +580,8 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {IWL_DEV_INFO (0x7A70 ,0x1692 , iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name),IWL_DEV_INFO (0x7AF0 ,0x1691 , iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name),IWL_DEV_INFO (0x7AF0 ,0x1692 , iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), +IWL_DEV_INFO (0x7F70 ,0x1691 , iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name), +IWL_DEV_INFO (0x7F70 ,0x1692 , iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name),IWL_DEV_INFO (0x271C ,0x0214 , iwl9260_2ac_cfg, iwl9260_1_name), IWL_DEV_INFO(0x7E40, 0x1691, iwl_cfg_ma, iwl_ax411_killer_1690s_name),
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 328/444 xenbus: Allow PVH dom0 a non-local xenstore
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Andryuk <[email protected]>
[ Upstream commit 90989869baae47ee2aa3bcb6f6eb9fbbe4287958 ]
Make xenbus_init() allow a non-local xenstore for a PVH dom0 - it is currently forced to XS_LOCAL. With Hyperlaunch booting dom0 and a xenstore stubdom, dom0 can be handled as a regular XS_HVM following the late init path.
Ideally we'd drop the use of xen_initial_domain() and just check for the event channel instead. However, ARM has a xen,enhanced no-xenstore mode, where the event channel and PFN would both be 0. Retain the xen_initial_domain() check, and use that for an additional check when the event channel is 0.
Check the full 64bit HVM_PARAM_STORE_EVTCHN value to catch the off chance that high bits are set for the 32bit event channel.
Message-ID: <[email protected]>
--- drivers/xen/xenbus/xenbus_probe.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/xen/xenbus/xenbus_probe.c +8 -6
@@ -966,9 +966,15 @@ static int __init xenbus_init(void)if (xen_pv_domain ()) xen_store_domain_type =XS_PV ;if (xen_hvm_domain ()) + { xen_store_domain_type =XS_HVM ; -if (xen_hvm_domain () &&xen_initial_domain ()) - xen_store_domain_type =XS_LOCAL ; + err =hvm_get_parameter (HVM_PARAM_STORE_EVTCHN , &v); +if (err) + goto out_error; + xen_store_evtchn = (int )v; +if (!v &&xen_initial_domain ()) + xen_store_domain_type =XS_LOCAL ; + }if (xen_pv_domain () && !xen_start_info->store_evtchn) xen_store_domain_type =XS_LOCAL ;if (xen_pv_domain () && xen_start_info->store_evtchn)
@@ -987,10 +993,6 @@ static int __init xenbus_init(void) xen_store_interface =gfn_to_virt (xen_store_gfn);break ;case XS_HVM : - err =hvm_get_parameter (HVM_PARAM_STORE_EVTCHN , &v); -if (err) - goto out_error; - xen_store_evtchn = (int )v; err =hvm_get_parameter (HVM_PARAM_STORE_PFN , &v);if (err) goto out_error;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 329/444 __legitimize_mnt(): check for MNT_SYNC_UMOUNT should be under mount_lock
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
[ Upstream commit 250cf3693060a5f803c5f1ddc082bb06b16112a9 ]
... or we risk stealing final mntput from sync umount - raising mnt_count after umount(2) has verified that victim is not busy, but before it has set MNT_SYNC_UMOUNT; in that case __legitimize_mnt() doesn't see that it's safe to quietly undo mnt_count increment and leaves dropping the reference to caller, where it'll be a full-blown mntput().
Check under mount_lock is needed; leaving the current one done before taking that makes no sense - it's nowhere near common enough to bother with.
--- fs/namespace.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
fs/namespace.c +1 -5
@@ -636,12 +636,8 @@ int __legitimize_mnt(struct vfsmount *bastard, unsigned seq)smp_mb ();// see mntput_no_expire() and do_umount() if (likely (!read_seqretry (&mount_lock, seq)))return 0 ; -if (bastard->mnt_flags &MNT_SYNC_UMOUNT ) { -mnt_add_count (mnt,-1 ); -return 1 ; - }lock_mount_hash (); -if (unlikely (bastard->mnt_flags &MNT_DOOMED )) { +if (unlikely (bastard->mnt_flags & (MNT_SYNC_UMOUNT |MNT_DOOMED ))) {mnt_add_count (mnt,-1 );unlock_mount_hash ();return 1 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 330/444 soundwire: bus: Fix race on the creation of the IRQ domain
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Keepax <[email protected]>
[ Upstream commit fd15594ba7d559d9da741504c322b9f57c4981e5 ]
The SoundWire IRQ domain needs to be created before any slaves are added to the bus, such that the domain is always available when needed. Move the call to sdw_irq_create() before the calls to sdw_acpi_find_slaves() and sdw_of_find_slaves().
--- drivers/soundwire/bus.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/soundwire/bus.c +5 -4
@@ -121,6 +121,10 @@ int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,set_bit (SDW_GROUP13_DEV_NUM , bus->assigned);set_bit (SDW_MASTER_DEV_NUM , bus->assigned); + ret =sdw_irq_create (bus, fwnode); +if (ret) +return ret; +/* * SDW is an enumerable bus, but devices can be powered off. So, * they won't be able to report as present.
@@ -137,6 +141,7 @@ int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,if (ret <0 ) {dev_err (bus->dev,"Finding slaves failed:%d\n" , ret); +sdw_irq_delete (bus);return ret; }
@@ -155,10 +160,6 @@ int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent, bus->params.curr_bank =SDW_BANK0 ; bus->params.next_bank =SDW_BANK1 ; - ret =sdw_irq_create (bus, fwnode); -if (ret) -return ret; -return 0 ; }EXPORT_SYMBOL (sdw_bus_master_add);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 331/444 espintcp: remove encap socket caching to avoid reference leak
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sabrina Dubroca <[email protected]>
[ Upstream commit 028363685bd0b7a19b4a820f82dd905b1dc83999 ]
The current scheme for caching the encap socket can lead to reference leaks when we try to delete the netns.
The reference chain is: xfrm_state -> enacp_sk -> netns
Since the encap socket is a userspace socket, it holds a reference on the netns. If we delete the espintcp state (through flush or individual delete) before removing the netns, the reference on the socket is dropped and the netns is correctly deleted. Otherwise, the netns may not be reachable anymore (if all processes within the ns have terminated), so we cannot delete the xfrm state to drop its reference on the socket.
This patch results in a small (~2% in my tests) performance regression.
A GC-type mechanism could be added for the socket cache, to clear references if the state hasn't been used "recently", but it's a lot more complex than just not caching the socket.
--- include/net/xfrm.h | 1 - net/ipv4/esp4.c | 49 ++++--------------------------------------- net/ipv6/esp6.c | 49 ++++--------------------------------------- net/xfrm/xfrm_state.c | 3 --- 4 files changed, 8 insertions(+), 94 deletions(-)
include/net/xfrm.h +0 -1
@@ -228,7 +228,6 @@ struct xfrm_state {/* Data for encapsulator */ struct xfrm_encap_tmpl *encap; -struct sock __rcu *encap_sk;/* Data for care-of address */ xfrm_address_t *coaddr;
net/ipv4/esp4.c +4 -45
83 lines not on this page · raw message
net/ipv6/esp6.c +4 -45
83 lines not on this page · raw message
net/xfrm/xfrm_state.c +0 -3
@@ -754,9 +754,6 @@ int __xfrm_state_delete(struct xfrm_state *x) net->xfrm.state_num--;spin_unlock (&net->xfrm.xfrm_state_lock); -if (x->encap_sk) -sock_put (rcu_dereference_raw (x->encap_sk)); -xfrm_dev_state_delete (x);/* All xfrm_state objects are created by xfrm_state_alloc.
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 332/444 dmaengine: idxd: add wq driver name support for accel-config user tool
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Jiang <[email protected]>
[ Upstream commit 7af1e0aceeb321cbc90fcf6fa0bec8870290377f ]
With the possibility of multiple wq drivers that can be bound to the wq, the user config tool accel-config needs a way to know which wq driver to bind to the wq. Introduce per wq driver_name sysfs attribute where the user can indicate the driver to be bound to the wq. This allows accel-config to just bind to the driver using wq->driver_name.
Stable-dep-of: 8dfa57aabff6 ("dmaengine: idxd: Fix allowing write() from different address spaces")
--- .../ABI/stable/sysfs-driver-dma-idxd | 6 ++++ drivers/dma/idxd/cdev.c | 7 ++++ drivers/dma/idxd/dma.c | 6 ++++ drivers/dma/idxd/idxd.h | 9 +++++ drivers/dma/idxd/sysfs.c | 34 +++++++++++++++++++ include/uapi/linux/idxd.h | 1 + 6 files changed, 63 insertions(+)
Documentation/ABI/stable/sysfs-driver-dma-idxd +6 -0
@@ -270,6 +270,12 @@ Description: Shows the operation capability bits displayed in bitmap format correlates to the operations allowed. It's visible only on platforms that support the capability. +What: /sys/bus/dsa/devices/wq<m>.<n>/driver_name +Date: Sept 8, 2023 +KernelVersion: 6.7.0 +Contact: [email protected] +Description: Name of driver to be bounded to the wq. + What: /sys/bus/dsa/devices/engine<m>.<n>/group_id Date: Oct 25, 2019 KernelVersion: 5.6.0
drivers/dma/idxd/cdev.c +7 -0
@@ -584,6 +584,7 @@ void idxd_wq_del_cdev(struct idxd_wq *wq)static int idxd_user_drv_probe (struct idxd_dev *idxd_dev) { +struct device *dev = &idxd_dev->conf_dev;struct idxd_wq *wq =idxd_dev_to_wq (idxd_dev);struct idxd_device *idxd = wq->idxd;int rc;
@@ -611,6 +612,12 @@ static int idxd_user_drv_probe(struct idxd_dev *idxd_dev)mutex_lock (&wq->wq_lock); +if (!idxd_wq_driver_name_match (wq, dev)) { + idxd->cmd_status =IDXD_SCMD_WQ_NO_DRV_NAME ; + rc = -ENODEV ; + goto wq_err; + } + wq->wq =create_workqueue (dev_name (wq_confdev (wq)));if (!wq->wq) { rc = -ENOMEM ;
drivers/dma/idxd/dma.c +6 -0
@@ -306,6 +306,12 @@ static int idxd_dmaengine_drv_probe(struct idxd_dev *idxd_dev)return -ENXIO ;mutex_lock (&wq->wq_lock); +if (!idxd_wq_driver_name_match (wq, dev)) { + idxd->cmd_status =IDXD_SCMD_WQ_NO_DRV_NAME ; + rc = -ENODEV ; + goto err; + } + wq->type =IDXD_WQT_KERNEL ; rc =drv_enable_wq (wq);
drivers/dma/idxd/idxd.h +9 -0
@@ -159,6 +159,8 @@ struct idxd_cdev {int minor; }; +#define DRIVER_NAME_SIZE 128 +#define IDXD_ALLOCATED_BATCH_SIZE 128U#define WQ_NAME_SIZE 1024#define WQ_TYPE_SIZE 10
@@ -227,6 +229,8 @@ struct idxd_wq {/* Lock to protect upasid_xa access. */ struct mutex uc_lock;struct xarray upasid_xa; + +char driver_name[DRIVER_NAME_SIZE +1 ]; };struct idxd_engine {
@@ -648,6 +652,11 @@ static inline void idxd_wqcfg_set_max_batch_shift(int idxd_type, union wqcfg *wq wqcfg->max_batch_shift = max_batch_shift; } +static inline int idxd_wq_driver_name_match (struct idxd_wq *wq,struct device *dev) +{ +return (strncmp (wq->driver_name, dev->driver->name,strlen (dev->driver->name)) ==0 ); +} +int __must_check __idxd_driver_register (struct idxd_device_driver *idxd_drv,struct module *module,const char *mod_name);#define idxd_driver_register (driver) \
drivers/dma/idxd/sysfs.c +34 -0
@@ -1282,6 +1282,39 @@ static ssize_t wq_op_config_store(struct device *dev, struct device_attribute *astatic struct device_attribute dev_attr_wq_op_config =__ATTR (op_config,0644 , wq_op_config_show, wq_op_config_store); +static ssize_t wq_driver_name_show (struct device *dev,struct device_attribute *attr,char *buf) +{ +struct idxd_wq *wq =confdev_to_wq (dev); + +return sysfs_emit (buf,"%s\n" , wq->driver_name); +} + +static ssize_t wq_driver_name_store (struct device *dev,struct device_attribute *attr, +const char *buf,size_t count) +{ +struct idxd_wq *wq =confdev_to_wq (dev); +char *input, *pos; + +if (wq->state !=IDXD_WQ_DISABLED ) +return -EPERM ; + +if (strlen (buf) >DRIVER_NAME_SIZE ||strlen (buf) ==0 ) +return -EINVAL ; + + input =kstrndup (buf, count,GFP_KERNEL ); +if (!input) +return -ENOMEM ; + + pos =strim (input); +memset (wq->driver_name,0 ,DRIVER_NAME_SIZE +1 ); +sprintf (wq->driver_name,"%s" , pos); +kfree (input); +return count; +} + +static struct device_attribute dev_attr_wq_driver_name = +__ATTR (driver_name,0644 , wq_driver_name_show, wq_driver_name_store); +static struct attribute *idxd_wq_attributes[] = { &dev_attr_wq_clients.attr, &dev_attr_wq_state.attr,
@@ -1301,6 +1334,7 @@ static struct attribute *idxd_wq_attributes[] = { &dev_attr_wq_occupancy.attr, &dev_attr_wq_enqcmds_retries.attr, &dev_attr_wq_op_config.attr, + &dev_attr_wq_driver_name.attr, NULL, };
include/uapi/linux/idxd.h +1 -0
@@ -31,6 +31,7 @@ enum idxd_scmd_stat {IDXD_SCMD_WQ_IRQ_ERR =0x80100000 ,IDXD_SCMD_WQ_USER_NO_IOMMU =0x80110000 ,IDXD_SCMD_DEV_EVL_ERR =0x80120000 , + IDXD_SCMD_WQ_NO_DRV_NAME = 0x80200000, };#define IDXD_SCMD_SOFTERR_MASK 0x80000000
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 333/444 dmaengine: idxd: Fix allowing write() from different address spaces
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vinicius Costa Gomes <[email protected]>
[ Upstream commit 8dfa57aabff625bf445548257f7711ef294cd30e ]
Check if the process submitting the descriptor belongs to the same address space as the one that opened the file, reject otherwise.
--- drivers/dma/idxd/cdev.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/dma/idxd/cdev.c +9 -0
@@ -412,6 +412,9 @@ static int idxd_cdev_mmap(struct file *filp, struct vm_area_struct *vma)if (!idxd->user_submission_safe && !capable (CAP_SYS_RAWIO ))return -EPERM ; +if (current->mm != ctx->mm) +return -EPERM ; + rc =check_vma (wq, vma, __func__);if (rc <0 )return rc;
@@ -478,6 +481,9 @@ static ssize_t idxd_cdev_write(struct file *filp, const char __user *buf, size_tssize_t written =0 ;int i; +if (current->mm != ctx->mm) +return -EPERM ; +for (i =0 ; i < len/sizeof (struct dsa_hw_desc ); i++) {int rc =idxd_submit_user_descriptor (ctx, udesc + i);
@@ -498,6 +504,9 @@ static __poll_t idxd_cdev_poll(struct file *filp,struct idxd_device *idxd = wq->idxd;__poll_t out =0 ; +if (current->mm != ctx->mm) +return -EPERM ; +poll_wait (filp, &wq->err_queue, wait);spin_lock (&idxd->dev_lock);if (idxd->sw_err.valid)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 334/444 kernel/fork: only call untrack_pfn_clear() on VMAs duplicated for fork()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand <[email protected]>
[ Upstream commit e9f180d7cfde23b9f8eebd60272465176373ab2c ]
Not intuitive, but vm_area_dup() located in kernel/fork.c is not only used for duplicating VMAs during fork(), but also for duplicating VMAs when splitting VMAs or when mremap()'ing them.
VM_PFNMAP mappings can at least get ordinarily mremap()'ed (no change in size) and apparently also shrunk during mremap(), which implies duplicating the VMA in __split_vma() first.
In case of ordinary mremap() (no change in size), we first duplicate the VMA in copy_vma_and_data()->copy_vma() to then call untrack_pfn_clear() on the old VMA: we effectively move the VM_PAT reservation. So the untrack_pfn_clear() call on the new VMA duplicating is wrong in that context.
Splitting of VMAs seems problematic, because we don't duplicate/adjust the reservation when splitting the VMA. Instead, in memtype_erase() -- called during zapping/munmap -- we shrink a reservation in case only the end address matches: Assume we split a VMA into A and B, both would share a reservation until B is unmapped.
So when unmapping B, the reservation would be updated to cover only A. When unmapping A, we would properly remove the now-shrunk reservation. That scenario describes the mremap() shrinking (old_size > new_size), where we split + unmap B, and the untrack_pfn_clear() on the new VMA when is wrong.
What if we manage to split a VM_PFNMAP VMA into A and B and unmap A first? It would be broken because we would never free the reservation. Likely, there are ways to trigger such a VMA split outside of mremap().
Affecting other VMA duplication was not intended, vm_area_dup() being used outside of kernel/fork.c was an oversight. So let's fix that for; how to handle VMA splits better should be investigated separately.
With a simple reproducer that uses mprotect() to split such a VMA I can trigger
x86/PAT: pat_mremap:26448 freeing invalid memtype [mem 0x00000000-0x00000fff]
--- kernel/fork.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
kernel/fork.c +5 -4
@@ -518,10 +518,6 @@ struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig)vma_numab_state_init (new);dup_anon_vma_name (orig, new); -/* track_pfn_copy() will later take care of copying internal state. */ -if (unlikely (new->vm_flags &VM_PFNMAP )) -untrack_pfn_clear (new); -return new; }
@@ -715,6 +711,11 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, tmp =vm_area_dup (mpnt);if (!tmp) goto fail_nomem; + +/* track_pfn_copy() will later take care of copying internal state. */ +if (unlikely (tmp->vm_flags &VM_PFNMAP )) +untrack_pfn_clear (tmp); + retval =vma_dup_policy (mpnt, tmp);if (retval) goto fail_nomem_policy;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 335/444 remoteproc: qcom_wcnss: Fix on platforms without fallback regulators
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matti Lehtimäki <[email protected]>
[ Upstream commit 4ca45af0a56d00b86285d6fdd720dca3215059a7 ]
Recent change to handle platforms with only single power domain broke pronto-v3 which requires power domains and doesn't have fallback voltage regulators in case power domains are missing. Add a check to verify the number of fallback voltage regulators before using the code which handles single power domain situation.
--- drivers/remoteproc/qcom_wcnss.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/remoteproc/qcom_wcnss.c +2 -1
@@ -456,7 +456,8 @@ static int wcnss_init_regulators(struct qcom_wcnss *wcnss,if (wcnss->num_pds) { info += wcnss->num_pds;/* Handle single power domain case */ - num_vregs += num_pd_vregs - wcnss->num_pds; +if (wcnss->num_pds < num_pd_vregs) + num_vregs += num_pd_vregs - wcnss->num_pds; }else { num_vregs += num_pd_vregs; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 336/444 clk: sunxi-ng: d1: Add missing divider for MMC mod clocks
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andre Przywara <[email protected]>
[ Upstream commit 98e6da673cc6dd46ca9a599802bd2c8f83606710 ]
The D1/R528/T113 SoCs have a hidden divider of 2 in the MMC mod clocks, just as other recent SoCs. So far we did not describe that, which led to the resulting MMC clock rate to be only half of its intended value.
Use a macro that allows to describe a fixed post-divider, to compensate for that divisor.
This brings the MMC performance on those SoCs to its expected level, so about 23 MB/s for SD cards, instead of the 11 MB/s measured so far.
--- drivers/clk/sunxi-ng/ccu-sun20i-d1.c | 44 ++++++++++++++++------------ drivers/clk/sunxi-ng/ccu_mp.h | 22 ++++++++++++++ 2 files changed, 47 insertions(+), 19 deletions(-)
drivers/clk/sunxi-ng/ccu-sun20i-d1.c +25 -19
@@ -412,19 +412,23 @@ static const struct clk_parent_data mmc0_mmc1_parents[] = { { .hw = &pll_periph0_2x_clk.common.hw }, { .hw = &pll_audio1_div2_clk.common.hw }, }; -static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc0_clk, "mmc0", mmc0_mmc1_parents, 0x830, -0 ,4 ,/* M */ -8 ,2 ,/* P */ -24 ,3 ,/* mux */ -BIT (31 ),/* gate */ - 0); - -static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc1_clk, "mmc1", mmc0_mmc1_parents, 0x834, -0 ,4 ,/* M */ -8 ,2 ,/* P */ -24 ,3 ,/* mux */ -BIT (31 ),/* gate */ - 0); +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", + mmc0_mmc1_parents,0x830 , +0 ,4 ,/* M */ +8 ,2 ,/* P */ +24 ,3 ,/* mux */ +BIT (31 ),/* gate */ +2 ,/* post-div */ + 0); + +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", + mmc0_mmc1_parents,0x834 , +0 ,4 ,/* M */ +8 ,2 ,/* P */ +24 ,3 ,/* mux */ +BIT (31 ),/* gate */ +2 ,/* post-div */ + 0);static const struct clk_parent_data mmc2_parents[] = { { .fw_name = "hosc" },
@@ -433,12 +437,14 @@ static const struct clk_parent_data mmc2_parents[] = { { .hw = &pll_periph0_800M_clk.common.hw }, { .hw = &pll_audio1_div2_clk.common.hw }, }; -static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc2_clk, "mmc2", mmc2_parents, 0x838, -0 ,4 ,/* M */ -8 ,2 ,/* P */ -24 ,3 ,/* mux */ -BIT (31 ),/* gate */ - 0); +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc2_parents, +0x838 , +0 ,4 ,/* M */ +8 ,2 ,/* P */ +24 ,3 ,/* mux */ +BIT (31 ),/* gate */ +2 ,/* post-div */ + 0); static SUNXI_CCU_GATE_HWS(bus_mmc0_clk, "bus-mmc0", psi_ahb_hws, 0x84c, BIT(0), 0);
drivers/clk/sunxi-ng/ccu_mp.h +22 -0
@@ -52,6 +52,28 @@ struct ccu_mp { } \ } +#define SUNXI_CCU_MP_DATA_WITH_MUX_GATE_POSTDIV (_struct, _name, _parents, \ + _reg, \ + _mshift, _mwidth, \ + _pshift, _pwidth, \ + _muxshift, _muxwidth, \ + _gate, _postdiv, _flags)\ + struct ccu_mp _struct = { \ + .enable = _gate, \ + .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ + .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \ + .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ + .fixed_post_div = _postdiv, \ + .common = { \ + .reg = _reg, \ + .features = CCU_FEATURE_FIXED_POSTDIV, \ + .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \ + _parents, \ + &ccu_mp_ops, \ + _flags), \ + } \ + } + #define SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ _mshift, _mwidth, \ _pshift, _pwidth, \
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 337/444 xfrm: Sanitize marks before insert
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Chaignon <[email protected]>
[ Upstream commit 0b91fda3a1f044141e1e615456ff62508c32b202 ]
Prior to this patch, the mark is sanitized (applying the state's mask to the state's value) only on inserts when checking if a conflicting XFRM state or policy exists.
We discovered in Cilium that this same sanitization does not occur in the hot-path __xfrm_state_lookup. In the hot-path, the sk_buff's mark is simply compared to the state's value:
if ((mark & x->mark.m) != x->mark.v)
continue;Therefore, users can define unsanitized marks (ex. 0xf42/0xf00) which will never match any packet.
This commit updates __xfrm_state_insert and xfrm_policy_insert to store the sanitized marks, thus removing this footgun.
This has the side effect of changing the ip output, as the returned mark will have the mask applied to it when printed.
--- net/xfrm/xfrm_policy.c | 3 +++ net/xfrm/xfrm_state.c | 3 +++ 2 files changed, 6 insertions(+)
net/xfrm/xfrm_policy.c +3 -0
@@ -1603,6 +1603,9 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)struct xfrm_policy *delpol;struct hlist_head *chain; +/* Sanitize mark before store */ + policy->mark.v &= policy->mark.m; +spin_lock_bh (&net->xfrm.xfrm_policy_lock); chain =policy_hash_bysel (net, &policy->selector, policy->family, dir);if (chain)
net/xfrm/xfrm_state.c +3 -0
@@ -1475,6 +1475,9 @@ static void __xfrm_state_insert(struct xfrm_state *x)list_add (&x->km.all, &net->xfrm.state_all); +/* Sanitize mark before store */ + x->mark.v &= x->mark.m; + h =xfrm_dst_hash (net, &x->id.daddr, &x->props.saddr, x->props.reqid, x->props.family); XFRM_STATE_INSERT(bydst, &x->bydst, net->xfrm.state_bydst + h,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 338/444 dmaengine: idxd: Fix ->poll() return value
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Jiang <[email protected]>
[ Upstream commit ae74cd15ade833adc289279b5c6f12e78f64d4d7 ]
The fix to block access from different address space did not return a correct value for ->poll() change. kernel test bot reported that a return value of type __poll_t is expected rather than int. Fix to return POLLNVAL to indicate invalid request.
--- drivers/dma/idxd/cdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/dma/idxd/cdev.c +1 -1
@@ -505,7 +505,7 @@ static __poll_t idxd_cdev_poll(struct file *filp,__poll_t out =0 ;if (current->mm != ctx->mm) -return -EPERM ; +return POLLNVAL ;poll_wait (filp, &wq->err_queue, wait);spin_lock (&idxd->dev_lock);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 339/444 dmaengine: fsl-edma: Fix return code for unhandled interrupts
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wahren <[email protected]>
[ Upstream commit 5e27af0514e2249a9ccc9a762abd3b74e03a1f90 ]
For fsl,imx93-edma4 two DMA channels share the same interrupt. So in case fsl_edma3_tx_handler is called for the "wrong" channel, the return code must be IRQ_NONE. This signalize that the interrupt wasn't handled.
--- drivers/dma/fsl-edma-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/dma/fsl-edma-main.c +1 -1
@@ -58,7 +58,7 @@ static irqreturn_t fsl_edma3_tx_handler(int irq, void *dev_id) intr =edma_readl_chreg (fsl_chan, ch_int);if (!intr) -return IRQ_HANDLED ; +return IRQ_NONE ;edma_writel_chreg (fsl_chan,1 , ch_int);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 340/444 Bluetooth: L2CAP: Fix not checking l2cap_chan security level
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 7af8479d9eb4319b4ba7b47a8c4d2c55af1c31e1 ]
l2cap_check_enc_key_size shall check the security level of the l2cap_chan rather than the hci_conn since for incoming connection request that may be different as hci_conn may already been encrypted using a different security level.
--- net/bluetooth/l2cap_core.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
net/bluetooth/l2cap_core.c +8 -7
@@ -1411,7 +1411,8 @@ static void l2cap_request_info(struct l2cap_conn *conn) sizeof(req), &req); } -static bool l2cap_check_enc_key_size (struct hci_conn *hcon) +static bool l2cap_check_enc_key_size (struct hci_conn *hcon, +struct l2cap_chan *chan) {/* The minimum encryption key size needs to be enforced by the * host stack before establishing any L2CAP connections. The
@@ -1425,7 +1426,7 @@ static bool l2cap_check_enc_key_size(struct hci_conn *hcon)int min_key_size = hcon->hdev->min_enc_key_size;/* On FIPS security level, key size must be 16 bytes */ -if (hcon->sec_level ==BT_SECURITY_FIPS ) +if (chan->sec_level ==BT_SECURITY_FIPS ) min_key_size =16 ; return (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags) ||
@@ -1453,7 +1454,7 @@ static void l2cap_do_start(struct l2cap_chan *chan) !__l2cap_no_conn_pending(chan))return ; -if (l2cap_check_enc_key_size (conn->hcon)) +if (l2cap_check_enc_key_size (conn->hcon, chan))l2cap_start_connection (chan);else __set_chan_timer (chan,L2CAP_DISC_TIMEOUT );
@@ -1528,7 +1529,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)continue ; } -if (l2cap_check_enc_key_size (conn->hcon)) +if (l2cap_check_enc_key_size (conn->hcon, chan))l2cap_start_connection (chan);else l2cap_chan_close (chan,ECONNREFUSED );
@@ -3955,7 +3956,7 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,/* Check if the ACL is secure enough (if not SDP) */ if (psm !=cpu_to_le16 (L2CAP_PSM_SDP ) && (!hci_conn_check_link_mode (conn->hcon) || - !l2cap_check_enc_key_size (conn->hcon))) { + !l2cap_check_enc_key_size (conn->hcon, pchan))) { conn->disc_reason =HCI_ERROR_AUTH_FAILURE ; result =L2CAP_CR_SEC_BLOCK ; goto response;
@@ -7323,7 +7324,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) }if (chan->state ==BT_CONNECT ) { -if (!status &&l2cap_check_enc_key_size (hcon)) +if (!status &&l2cap_check_enc_key_size (hcon, chan))l2cap_start_connection (chan);else __set_chan_timer (chan,L2CAP_DISC_TIMEOUT );
@@ -7333,7 +7334,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)struct l2cap_conn_rsp rsp;__u16 res, stat; -if (!status &&l2cap_check_enc_key_size (hcon)) { +if (!status &&l2cap_check_enc_key_size (hcon, chan)) {if (test_bit (FLAG_DEFER_SETUP , &chan->flags)) { res =L2CAP_CR_PEND ; stat =L2CAP_CS_AUTHOR_PEND ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 341/444 Bluetooth: btusb: use skb_pull to avoid unsafe access in QCA dump handling
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: En-Wei Wu <[email protected]>
[ Upstream commit 4bcb0c7dc25446b99fc7a8fa2a143d69f3314162 ]
Use skb_pull() and skb_pull_data() to safely parse QCA dump packets.
This avoids direct pointer math on skb->data, which could lead to invalid access if the packet is shorter than expected.
--- drivers/bluetooth/btusb.c | 98 ++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 58 deletions(-)
drivers/bluetooth/btusb.c +40 -58
@@ -3525,9 +3525,8 @@ static void btusb_coredump_qca(struct hci_dev *hdev)static int handle_dump_pkt_qca (struct hci_dev *hdev,struct sk_buff *skb) {int ret =0 ; +unsigned int skip =0 ;u8 pkt_type; -u8 *sk_ptr; -unsigned int sk_len;u16 seqno;u32 dump_size;
@@ -3536,18 +3535,13 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)struct usb_device *udev = btdata->udev; pkt_type =hci_skb_pkt_type (skb); - sk_ptr = skb->data; - sk_len = skb->len; + skip =sizeof (struct hci_event_hdr ); +if (pkt_type ==HCI_ACLDATA_PKT ) + skip +=sizeof (struct hci_acl_hdr ); -if (pkt_type ==HCI_ACLDATA_PKT ) { - sk_ptr +=HCI_ACL_HDR_SIZE ; - sk_len -=HCI_ACL_HDR_SIZE ; - } - - sk_ptr +=HCI_EVENT_HDR_SIZE ; - sk_len -=HCI_EVENT_HDR_SIZE ; +skb_pull (skb, skip); + dump_hdr = (struct qca_dump_hdr *)skb->data; - dump_hdr = (struct qca_dump_hdr *)sk_ptr; seqno =le16_to_cpu (dump_hdr->seqno);if (seqno ==0 ) {set_bit (BTUSB_HW_SSR_ACTIVE , &btdata->flags);
@@ -3567,16 +3561,15 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb) btdata->qca_dump.ram_dump_size = dump_size; btdata->qca_dump.ram_dump_seqno =0 ; - sk_ptr += offsetof(struct qca_dump_hdr , data0); - sk_len -= offsetof(struct qca_dump_hdr , data0); + +skb_pull (skb, offsetof(struct qca_dump_hdr , data0));usb_disable_autosuspend (udev);bt_dev_info (hdev,"%s memdump size(%u)\n" , (pkt_type ==HCI_ACLDATA_PKT ) ?"ACL" :"event" , dump_size); }else { - sk_ptr += offsetof(struct qca_dump_hdr , data); - sk_len -= offsetof(struct qca_dump_hdr , data); +skb_pull (skb, offsetof(struct qca_dump_hdr , data)); }if (!btdata->qca_dump.ram_dump_size) {
@@ -3596,7 +3589,6 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)return ret; } -skb_pull (skb, skb->len - sk_len);hci_devcd_append (hdev, skb); btdata->qca_dump.ram_dump_seqno++;if (seqno ==QCA_LAST_SEQUENCE_NUM ) {
@@ -3624,68 +3616,58 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)/* Return: true if the ACL packet is a dump packet, false otherwise. */ static bool acl_pkt_is_dump_qca (struct hci_dev *hdev,struct sk_buff *skb) { -u8 *sk_ptr; -unsigned int sk_len; -struct hci_event_hdr *event_hdr;struct hci_acl_hdr *acl_hdr;struct qca_dump_hdr *dump_hdr; +struct sk_buff *clone =skb_clone (skb,GFP_ATOMIC ); +bool is_dump = false; - sk_ptr = skb->data; - sk_len = skb->len; - - acl_hdr =hci_acl_hdr (skb); -if (le16_to_cpu (acl_hdr->handle) !=QCA_MEMDUMP_ACL_HANDLE ) +if (!clone)return false; - sk_ptr +=HCI_ACL_HDR_SIZE ; - sk_len -=HCI_ACL_HDR_SIZE ; - event_hdr = (struct hci_event_hdr *)sk_ptr; - -if ((event_hdr->evt !=HCI_VENDOR_PKT ) || - (event_hdr->plen != (sk_len -HCI_EVENT_HDR_SIZE ))) -return false; + acl_hdr =skb_pull_data (clone,sizeof (*acl_hdr)); +if (!acl_hdr || (le16_to_cpu (acl_hdr->handle) !=QCA_MEMDUMP_ACL_HANDLE )) + goto out; - sk_ptr +=HCI_EVENT_HDR_SIZE ; - sk_len -=HCI_EVENT_HDR_SIZE ; + event_hdr =skb_pull_data (clone,sizeof (*event_hdr)); +if (!event_hdr || (event_hdr->evt !=HCI_VENDOR_PKT )) + goto out; - dump_hdr = (struct qca_dump_hdr *)sk_ptr; -if ((sk_len < offsetof(struct qca_dump_hdr , data)) || - (dump_hdr->vse_class !=QCA_MEMDUMP_VSE_CLASS ) || - (dump_hdr->msg_type !=QCA_MEMDUMP_MSG_TYPE )) -return false; + dump_hdr =skb_pull_data (clone,sizeof (*dump_hdr)); +if (!dump_hdr || (dump_hdr->vse_class !=QCA_MEMDUMP_VSE_CLASS ) || + (dump_hdr->msg_type !=QCA_MEMDUMP_MSG_TYPE )) + goto out; -return true; + is_dump = true; +out: +consume_skb (clone); +return is_dump; }/* Return: true if the event packet is a dump packet, false otherwise. */ static bool evt_pkt_is_dump_qca (struct hci_dev *hdev,struct sk_buff *skb) { -u8 *sk_ptr; -unsigned int sk_len; -struct hci_event_hdr *event_hdr;struct qca_dump_hdr *dump_hdr; +struct sk_buff *clone =skb_clone (skb,GFP_ATOMIC ); +bool is_dump = false; - sk_ptr = skb->data; - sk_len = skb->len; - - event_hdr =hci_event_hdr (skb); - -if ((event_hdr->evt !=HCI_VENDOR_PKT ) - || (event_hdr->plen != (sk_len -HCI_EVENT_HDR_SIZE ))) +if (!clone)return false; - sk_ptr +=HCI_EVENT_HDR_SIZE ; - sk_len -=HCI_EVENT_HDR_SIZE ; + event_hdr =skb_pull_data (clone,sizeof (*event_hdr)); +if (!event_hdr || (event_hdr->evt !=HCI_VENDOR_PKT )) + goto out; - dump_hdr = (struct qca_dump_hdr *)sk_ptr; -if ((sk_len < offsetof(struct qca_dump_hdr , data)) || - (dump_hdr->vse_class !=QCA_MEMDUMP_VSE_CLASS ) || - (dump_hdr->msg_type !=QCA_MEMDUMP_MSG_TYPE )) -return false; + dump_hdr =skb_pull_data (clone,sizeof (*dump_hdr)); +if (!dump_hdr || (dump_hdr->vse_class !=QCA_MEMDUMP_VSE_CLASS ) || + (dump_hdr->msg_type !=QCA_MEMDUMP_MSG_TYPE )) + goto out; -return true; + is_dump = true; +out: +consume_skb (clone); +return is_dump; }static int btusb_recv_acl_qca (struct hci_dev *hdev,struct sk_buff *skb)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 342/444 bridge: netfilter: Fix forwarding of fragmented packets
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <[email protected]>
[ Upstream commit 91b6dbced0ef1d680afdd69b14fc83d50ebafaf3 ]
When netfilter defrag hooks are loaded (due to the presence of conntrack rules, for example), fragmented packets entering the bridge will be defragged by the bridge's pre-routing hook (br_nf_pre_routing() -> ipv4_conntrack_defrag()).
Later on, in the bridge's post-routing hook, the defragged packet will be fragmented again. If the size of the largest fragment is larger than what the kernel has determined as the destination MTU (using ip_skb_dst_mtu()), the defragged packet will be dropped.
Before commit ac6627a28dbf ("net: ipv4: Consolidate ipv4_mtu and ip_dst_mtu_maybe_forward"), ip_skb_dst_mtu() would return dst_mtu() as the destination MTU. Assuming the dst entry attached to the packet is the bridge's fake rtable one, this would simply be the bridge's MTU (see fake_mtu()).
However, after above mentioned commit, ip_skb_dst_mtu() ends up returning the route's MTU stored in the dst entry's metrics. Ideally, in case the dst entry is the bridge's fake rtable one, this should be the bridge's MTU as the bridge takes care of updating this metric when its MTU changes (see br_change_mtu()).
Unfortunately, the last operation is a no-op given the metrics attached to the fake rtable entry are marked as read-only. Therefore, ip_skb_dst_mtu() ends up returning 1500 (the initial MTU value) and defragged packets are dropped during fragmentation when dealing with large fragments and high MTU (e.g., 9k).
Fix by moving the fake rtable entry's metrics to be per-bridge (in a similar fashion to the fake rtable entry itself) and marking them as writable, thereby allowing MTU changes to be reflected.
--- net/bridge/br_nf_core.c | 7 ++----- net/bridge/br_private.h | 1 + 2 files changed, 3 insertions(+), 5 deletions(-)
net/bridge/br_nf_core.c +2 -5
@@ -65,17 +65,14 @@ static struct dst_ops fake_dst_ops = {* ipt_REJECT needs it. Future netfilter modules might * require us to fill additional fields. */ -static const u32 br_dst_default_metrics[RTAX_MAX ] = { - [RTAX_MTU -1 ] =1500 , -}; -void br_netfilter_rtable_init (struct net_bridge *br) {struct rtable *rt = &br->fake_rtable;rcuref_init (&rt->dst.__rcuref,1 ); rt->dst.dev = br->dev; -dst_init_metrics (&rt->dst, br_dst_default_metrics, true); +dst_init_metrics (&rt->dst, br->metrics, false); +dst_metric_set (&rt->dst,RTAX_MTU , br->dev->mtu); rt->dst.flags =DST_NOXFRM |DST_FAKE_RTABLE ; rt->dst.ops = &fake_dst_ops; }
net/bridge/br_private.h +1 -0
@@ -502,6 +502,7 @@ struct net_bridge {struct rtable fake_rtable; struct rt6_info fake_rt6_info; }; +u32 metrics[RTAX_MAX ];#endif u16 group_fwd_mask;u16 group_fwd_mask_required;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 343/444 ice: fix vf->num_mac count with port representors
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacob Keller <[email protected]>
[ Upstream commit bbd95160a03dbfcd01a541f25c27ddb730dfbbd5 ]
The ice_vc_repr_add_mac() function indicates that it does not store the MAC address filters in the firmware. However, it still increments vf->num_mac. This is incorrect, as vf->num_mac should represent the number of MAC filters currently programmed to firmware.
Indeed, we only perform this increment if the requested filter is a unicast address that doesn't match the existing vf->hw_lan_addr. In addition, ice_vc_repr_del_mac() does not decrement the vf->num_mac counter. This results in the counter becoming out of sync with the actual count.
As it turns out, vf->num_mac is currently only used in legacy made without port representors. The single place where the value is checked is for enforcing a filter limit on untrusted VFs.
Upcoming patches to support VF Live Migration will use this value when determining the size of the TLV for MAC address filters. Fix the representor mode function to stop incrementing the counter incorrectly.
--- drivers/net/ethernet/intel/ice/ice_virtchnl.c | 1 - 1 file changed, 1 deletion(-)
drivers/net/ethernet/intel/ice/ice_virtchnl.c +0 -1
@@ -3769,7 +3769,6 @@ static int ice_vc_repr_add_mac(struct ice_vf *vf, u8 *msg) }ice_vfhw_mac_add (vf, &al->list[i]); - vf->num_mac++;break ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 344/444 ice: Fix LACP bonds without SRIOV environment
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Ertman <[email protected]>
[ Upstream commit 6c778f1b839b63525b30046c9d1899424a62be0a ]
If an aggregate has the following conditions:
- The SRIOV LAG DDP package has been enabled
- The bond is in 802.3ad LACP mode
- The bond is disqualified from supporting SRIOV VF LAG
- Both interfaces were added simultaneously to the bond (same command)
Then there is a chance that the two interfaces will be assigned different LACP Aggregator ID's. This will cause a failure of the LACP control over the bond.
To fix this, we can detect if the primary interface for the bond (as defined by the driver) is not in switchdev mode, and exit the setup flow if so.
Reproduction steps:
%> ip link add bond0 type bond mode 802.3ad miimon 100 %> ip link set bond0 up
%> ifenslave bond0 eth0 eth1
%> cat /proc/net/bonding/bond0 | grep Agg
Check for Aggregator IDs that differ.
--- drivers/net/ethernet/intel/ice/ice_lag.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/ethernet/intel/ice/ice_lag.c +6 -0
@@ -1229,12 +1229,18 @@ static void ice_lag_changeupper_event(struct ice_lag *lag, void *ptr)*/ if (!primary_lag) { lag->primary = true; +if (!ice_is_switchdev_running (lag->pf)) +return ; +/* Configure primary's SWID to be shared */ ice_lag_primary_swid (lag, true); primary_lag = lag; }else {u16 swid; +if (!ice_is_switchdev_running (primary_lag->pf)) +return ; + swid = primary_lag->pf->hw.port_info->sw_id;ice_lag_set_swid (swid, lag, true);ice_lag_add_prune_list (primary_lag, lag->pf);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 345/444 pinctrl: qcom/msm: Convert to platform remove callback returning void
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
[ Upstream commit 22ee670a8ad3ec7cd9d872d4512fe8797130e191 ]
The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks.
To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove().
To convert all those qcom pinctrl drivers, make msm_pinctrl_remove() return void (instead of zero) and use .remove_new in all drivers.
Stable-dep-of: 41e452e6933d ("pinctrl: qcom: switch to devm_register_sys_off_handler()")
--- drivers/pinctrl/qcom/pinctrl-apq8064.c | 2 +- drivers/pinctrl/qcom/pinctrl-apq8084.c | 2 +- drivers/pinctrl/qcom/pinctrl-ipq4019.c | 2 +- drivers/pinctrl/qcom/pinctrl-ipq5018.c | 2 +- drivers/pinctrl/qcom/pinctrl-ipq5332.c | 2 +- drivers/pinctrl/qcom/pinctrl-ipq6018.c | 2 +- drivers/pinctrl/qcom/pinctrl-ipq8064.c | 2 +- drivers/pinctrl/qcom/pinctrl-ipq8074.c | 2 +- drivers/pinctrl/qcom/pinctrl-ipq9574.c | 2 +- drivers/pinctrl/qcom/pinctrl-mdm9607.c | 2 +- drivers/pinctrl/qcom/pinctrl-mdm9615.c | 2 +- drivers/pinctrl/qcom/pinctrl-msm.c | 4 +--- drivers/pinctrl/qcom/pinctrl-msm.h | 2 +- drivers/pinctrl/qcom/pinctrl-msm8226.c | 2 +- drivers/pinctrl/qcom/pinctrl-msm8660.c | 2 +- drivers/pinctrl/qcom/pinctrl-msm8909.c | 2 +- drivers/pinctrl/qcom/pinctrl-msm8916.c | 2 +- drivers/pinctrl/qcom/pinctrl-msm8953.c | 2 +- drivers/pinctrl/qcom/pinctrl-msm8960.c | 2 +- drivers/pinctrl/qcom/pinctrl-msm8976.c | 2 +- drivers/pinctrl/qcom/pinctrl-msm8994.c | 2 +- drivers/pinctrl/qcom/pinctrl-msm8996.c | 2 +- drivers/pinctrl/qcom/pinctrl-msm8998.c | 2 +- drivers/pinctrl/qcom/pinctrl-msm8x74.c | 2 +- drivers/pinctrl/qcom/pinctrl-qcm2290.c | 2 +- drivers/pinctrl/qcom/pinctrl-qcs404.c | 2 +- drivers/pinctrl/qcom/pinctrl-qdf2xxx.c | 2 +- drivers/pinctrl/qcom/pinctrl-qdu1000.c | 2 +- drivers/pinctrl/qcom/pinctrl-sa8775p.c | 2 +- drivers/pinctrl/qcom/pinctrl-sc7180.c | 2 +- drivers/pinctrl/qcom/pinctrl-sc7280.c | 2 +- drivers/pinctrl/qcom/pinctrl-sc8180x.c | 2 +- drivers/pinctrl/qcom/pinctrl-sc8280xp.c | 2 +- drivers/pinctrl/qcom/pinctrl-sdm660.c | 2 +- drivers/pinctrl/qcom/pinctrl-sdm670.c | 2 +- drivers/pinctrl/qcom/pinctrl-sdm845.c | 2 +- drivers/pinctrl/qcom/pinctrl-sdx55.c | 2 +- drivers/pinctrl/qcom/pinctrl-sdx65.c | 2 +- drivers/pinctrl/qcom/pinctrl-sdx75.c | 2 +- drivers/pinctrl/qcom/pinctrl-sm6115.c | 2 +- drivers/pinctrl/qcom/pinctrl-sm6125.c | 2 +- drivers/pinctrl/qcom/pinctrl-sm6350.c | 2 +- drivers/pinctrl/qcom/pinctrl-sm6375.c | 2 +- drivers/pinctrl/qcom/pinctrl-sm7150.c | 2 +- drivers/pinctrl/qcom/pinctrl-sm8150.c | 2 +- drivers/pinctrl/qcom/pinctrl-sm8250.c | 2 +- drivers/pinctrl/qcom/pinctrl-sm8350.c | 2 +- drivers/pinctrl/qcom/pinctrl-sm8450.c | 2 +- drivers/pinctrl/qcom/pinctrl-sm8550.c | 2 +- 49 files changed, 49 insertions(+), 51 deletions(-)
drivers/pinctrl/qcom/pinctrl-apq8064.c +1 -1
@@ -629,7 +629,7 @@ static struct platform_driver apq8064_pinctrl_driver = { .of_match_table = apq8064_pinctrl_of_match, }, .probe = apq8064_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init apq8064_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-apq8084.c +1 -1
@@ -1207,7 +1207,7 @@ static struct platform_driver apq8084_pinctrl_driver = { .of_match_table = apq8084_pinctrl_of_match, }, .probe = apq8084_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init apq8084_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-ipq4019.c +1 -1
@@ -710,7 +710,7 @@ static struct platform_driver ipq4019_pinctrl_driver = { .of_match_table = ipq4019_pinctrl_of_match, }, .probe = ipq4019_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init ipq4019_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-ipq5018.c +1 -1
@@ -754,7 +754,7 @@ static struct platform_driver ipq5018_pinctrl_driver = { .of_match_table = ipq5018_pinctrl_of_match, }, .probe = ipq5018_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init ipq5018_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-ipq5332.c +1 -1
@@ -834,7 +834,7 @@ static struct platform_driver ipq5332_pinctrl_driver = { .of_match_table = ipq5332_pinctrl_of_match, }, .probe = ipq5332_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init ipq5332_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-ipq6018.c +1 -1
@@ -1080,7 +1080,7 @@ static struct platform_driver ipq6018_pinctrl_driver = { .of_match_table = ipq6018_pinctrl_of_match, }, .probe = ipq6018_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init ipq6018_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-ipq8064.c +1 -1
@@ -631,7 +631,7 @@ static struct platform_driver ipq8064_pinctrl_driver = { .of_match_table = ipq8064_pinctrl_of_match, }, .probe = ipq8064_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init ipq8064_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-ipq8074.c +1 -1
@@ -1041,7 +1041,7 @@ static struct platform_driver ipq8074_pinctrl_driver = { .of_match_table = ipq8074_pinctrl_of_match, }, .probe = ipq8074_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init ipq8074_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-ipq9574.c +1 -1
@@ -799,7 +799,7 @@ static struct platform_driver ipq9574_pinctrl_driver = { .of_match_table = ipq9574_pinctrl_of_match, }, .probe = ipq9574_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init ipq9574_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-mdm9607.c +1 -1
@@ -1059,7 +1059,7 @@ static struct platform_driver mdm9607_pinctrl_driver = { .of_match_table = mdm9607_pinctrl_of_match, }, .probe = mdm9607_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init mdm9607_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-mdm9615.c +1 -1
@@ -446,7 +446,7 @@ static struct platform_driver mdm9615_pinctrl_driver = { .of_match_table = mdm9615_pinctrl_of_match, }, .probe = mdm9615_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init mdm9615_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-msm.c +1 -3
@@ -1547,15 +1547,13 @@ int msm_pinctrl_probe(struct platform_device *pdev, }EXPORT_SYMBOL (msm_pinctrl_probe); -int msm_pinctrl_remove (struct platform_device *pdev) +void msm_pinctrl_remove (struct platform_device *pdev) {struct msm_pinctrl *pctrl =platform_get_drvdata (pdev);gpiochip_remove (&pctrl->chip);unregister_restart_handler (&pctrl->restart_nb); - -return 0 ; }EXPORT_SYMBOL (msm_pinctrl_remove);
drivers/pinctrl/qcom/pinctrl-msm.h +1 -1
@@ -166,6 +166,6 @@ extern const struct dev_pm_ops msm_pinctrl_dev_pm_ops;int msm_pinctrl_probe (struct platform_device *pdev,const struct msm_pinctrl_soc_data *soc_data); -int msm_pinctrl_remove (struct platform_device *pdev); +void msm_pinctrl_remove (struct platform_device *pdev);#endif
drivers/pinctrl/qcom/pinctrl-msm8226.c +1 -1
@@ -638,7 +638,7 @@ static struct platform_driver msm8226_pinctrl_driver = { .of_match_table = msm8226_pinctrl_of_match, }, .probe = msm8226_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init msm8226_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-msm8660.c +1 -1
@@ -981,7 +981,7 @@ static struct platform_driver msm8660_pinctrl_driver = { .of_match_table = msm8660_pinctrl_of_match, }, .probe = msm8660_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init msm8660_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-msm8909.c +1 -1
@@ -929,7 +929,7 @@ static struct platform_driver msm8909_pinctrl_driver = { .of_match_table = msm8909_pinctrl_of_match, }, .probe = msm8909_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init msm8909_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-msm8916.c +1 -1
@@ -969,7 +969,7 @@ static struct platform_driver msm8916_pinctrl_driver = { .of_match_table = msm8916_pinctrl_of_match, }, .probe = msm8916_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init msm8916_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-msm8953.c +1 -1
@@ -1816,7 +1816,7 @@ static struct platform_driver msm8953_pinctrl_driver = { .of_match_table = msm8953_pinctrl_of_match, }, .probe = msm8953_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init msm8953_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-msm8960.c +1 -1
@@ -1246,7 +1246,7 @@ static struct platform_driver msm8960_pinctrl_driver = { .of_match_table = msm8960_pinctrl_of_match, }, .probe = msm8960_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init msm8960_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-msm8976.c +1 -1
@@ -1096,7 +1096,7 @@ static struct platform_driver msm8976_pinctrl_driver = { .of_match_table = msm8976_pinctrl_of_match, }, .probe = msm8976_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init msm8976_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-msm8994.c +1 -1
@@ -1343,7 +1343,7 @@ static struct platform_driver msm8994_pinctrl_driver = { .of_match_table = msm8994_pinctrl_of_match, }, .probe = msm8994_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init msm8994_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-msm8996.c +1 -1
@@ -1906,7 +1906,7 @@ static struct platform_driver msm8996_pinctrl_driver = { .of_match_table = msm8996_pinctrl_of_match, }, .probe = msm8996_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init msm8996_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-msm8998.c +1 -1
@@ -1535,7 +1535,7 @@ static struct platform_driver msm8998_pinctrl_driver = { .of_match_table = msm8998_pinctrl_of_match, }, .probe = msm8998_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init msm8998_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-msm8x74.c +1 -1
@@ -1071,7 +1071,7 @@ static struct platform_driver msm8x74_pinctrl_driver = { .of_match_table = msm8x74_pinctrl_of_match, }, .probe = msm8x74_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init msm8x74_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-qcm2290.c +1 -1
@@ -1113,7 +1113,7 @@ static struct platform_driver qcm2290_pinctrl_driver = { .of_match_table = qcm2290_pinctrl_of_match, }, .probe = qcm2290_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init qcm2290_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-qcs404.c +1 -1
@@ -1644,7 +1644,7 @@ static struct platform_driver qcs404_pinctrl_driver = { .of_match_table = qcs404_pinctrl_of_match, }, .probe = qcs404_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init qcs404_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-qdf2xxx.c +1 -1
@@ -145,7 +145,7 @@ static struct platform_driver qdf2xxx_pinctrl_driver = { .acpi_match_table = qdf2xxx_acpi_ids, }, .probe = qdf2xxx_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init qdf2xxx_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-qdu1000.c +1 -1
@@ -1248,7 +1248,7 @@ static struct platform_driver qdu1000_tlmm_driver = { .of_match_table = qdu1000_tlmm_of_match, }, .probe = qdu1000_tlmm_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init qdu1000_tlmm_init (void )
drivers/pinctrl/qcom/pinctrl-sa8775p.c +1 -1
@@ -1530,7 +1530,7 @@ static struct platform_driver sa8775p_pinctrl_driver = { .of_match_table = sa8775p_pinctrl_of_match, }, .probe = sa8775p_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sa8775p_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-sc7180.c +1 -1
@@ -1159,7 +1159,7 @@ static struct platform_driver sc7180_pinctrl_driver = { .of_match_table = sc7180_pinctrl_of_match, }, .probe = sc7180_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sc7180_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-sc7280.c +1 -1
@@ -1505,7 +1505,7 @@ static struct platform_driver sc7280_pinctrl_driver = { .of_match_table = sc7280_pinctrl_of_match, }, .probe = sc7280_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sc7280_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-sc8180x.c +1 -1
@@ -1720,7 +1720,7 @@ static struct platform_driver sc8180x_pinctrl_driver = { .acpi_match_table = sc8180x_pinctrl_acpi_match, }, .probe = sc8180x_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sc8180x_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-sc8280xp.c +1 -1
@@ -1926,7 +1926,7 @@ static struct platform_driver sc8280xp_pinctrl_driver = { .of_match_table = sc8280xp_pinctrl_of_match, }, .probe = sc8280xp_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sc8280xp_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-sdm660.c +1 -1
@@ -1428,7 +1428,7 @@ static struct platform_driver sdm660_pinctrl_driver = { .of_match_table = sdm660_pinctrl_of_match, }, .probe = sdm660_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sdm660_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-sdm670.c +1 -1
@@ -1318,7 +1318,7 @@ static struct platform_driver sdm670_pinctrl_driver = { .of_match_table = sdm670_pinctrl_of_match, }, .probe = sdm670_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sdm670_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-sdm845.c +1 -1
@@ -1351,7 +1351,7 @@ static struct platform_driver sdm845_pinctrl_driver = { .acpi_match_table = ACPI_PTR(sdm845_pinctrl_acpi_match), }, .probe = sdm845_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sdm845_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-sdx55.c +1 -1
@@ -990,7 +990,7 @@ static struct platform_driver sdx55_pinctrl_driver = { .of_match_table = sdx55_pinctrl_of_match, }, .probe = sdx55_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sdx55_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-sdx65.c +1 -1
@@ -939,7 +939,7 @@ static struct platform_driver sdx65_pinctrl_driver = { .of_match_table = sdx65_pinctrl_of_match, }, .probe = sdx65_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sdx65_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-sdx75.c +1 -1
@@ -1124,7 +1124,7 @@ static struct platform_driver sdx75_pinctrl_driver = { .of_match_table = sdx75_pinctrl_of_match, }, .probe = sdx75_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sdx75_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-sm6115.c +1 -1
@@ -895,7 +895,7 @@ static struct platform_driver sm6115_tlmm_driver = { .of_match_table = sm6115_tlmm_of_match, }, .probe = sm6115_tlmm_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sm6115_tlmm_init (void )
drivers/pinctrl/qcom/pinctrl-sm6125.c +1 -1
@@ -1249,7 +1249,7 @@ static struct platform_driver sm6125_tlmm_driver = { .of_match_table = sm6125_tlmm_of_match, }, .probe = sm6125_tlmm_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sm6125_tlmm_init (void )
drivers/pinctrl/qcom/pinctrl-sm6350.c +1 -1
@@ -1373,7 +1373,7 @@ static struct platform_driver sm6350_tlmm_driver = { .of_match_table = sm6350_tlmm_of_match, }, .probe = sm6350_tlmm_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sm6350_tlmm_init (void )
drivers/pinctrl/qcom/pinctrl-sm6375.c +1 -1
@@ -1516,7 +1516,7 @@ static struct platform_driver sm6375_tlmm_driver = { .of_match_table = sm6375_tlmm_of_match, }, .probe = sm6375_tlmm_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sm6375_tlmm_init (void )
drivers/pinctrl/qcom/pinctrl-sm7150.c +1 -1
@@ -1254,7 +1254,7 @@ static struct platform_driver sm7150_tlmm_driver = { .of_match_table = sm7150_tlmm_of_match, }, .probe = sm7150_tlmm_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sm7150_tlmm_init (void )
drivers/pinctrl/qcom/pinctrl-sm8150.c +1 -1
@@ -1542,7 +1542,7 @@ static struct platform_driver sm8150_pinctrl_driver = { .of_match_table = sm8150_pinctrl_of_match, }, .probe = sm8150_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sm8150_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-sm8250.c +1 -1
@@ -1351,7 +1351,7 @@ static struct platform_driver sm8250_pinctrl_driver = { .of_match_table = sm8250_pinctrl_of_match, }, .probe = sm8250_pinctrl_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sm8250_pinctrl_init (void )
drivers/pinctrl/qcom/pinctrl-sm8350.c +1 -1
@@ -1642,7 +1642,7 @@ static struct platform_driver sm8350_tlmm_driver = { .of_match_table = sm8350_tlmm_of_match, }, .probe = sm8350_tlmm_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sm8350_tlmm_init (void )
drivers/pinctrl/qcom/pinctrl-sm8450.c +1 -1
@@ -1677,7 +1677,7 @@ static struct platform_driver sm8450_tlmm_driver = { .of_match_table = sm8450_tlmm_of_match, }, .probe = sm8450_tlmm_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sm8450_tlmm_init (void )
drivers/pinctrl/qcom/pinctrl-sm8550.c +1 -1
@@ -1762,7 +1762,7 @@ static struct platform_driver sm8550_tlmm_driver = { .of_match_table = sm8550_tlmm_of_match, }, .probe = sm8550_tlmm_probe, - .remove = msm_pinctrl_remove, + .remove_new = msm_pinctrl_remove, };static int __init sm8550_tlmm_init (void )
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 346/444 pinctrl: qcom: switch to devm_register_sys_off_handler()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit 41e452e6933d14146381ea25cff5e4d1ac2abea1 ]
Error-handling paths in msm_pinctrl_probe() don't call
a function required to unroll restart handler registration, unregister_restart_handler(). Instead of adding calls to this function, switch the msm pinctrl code into using devm_register_sys_off_handler().
--- drivers/pinctrl/qcom/pinctrl-msm.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
drivers/pinctrl/qcom/pinctrl-msm.c +12 -11
@@ -43,7 +43,6 @@* @pctrl: pinctrl handle. * @chip: gpiochip handle. * @desc: pin controller descriptor -* @restart_nb: restart notifier block. * @irq: parent irq for the TLMM irq_chip. * @intr_target_use_scm: route irq to application cpu using scm calls * @lock: Spinlock to protect register resources as well
@@ -63,7 +62,6 @@ struct msm_pinctrl {struct pinctrl_dev *pctrl;struct gpio_chip chip;struct pinctrl_desc desc; -struct notifier_block restart_nb;int irq;
@@ -1424,10 +1422,9 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)return 0 ; } -static int msm_ps_hold_restart (struct notifier_block *nb,unsigned long action, -void *data) +static int msm_ps_hold_restart (struct sys_off_data *data) { - struct msm_pinctrl *pctrl = container_of(nb, struct msm_pinctrl, restart_nb); +struct msm_pinctrl *pctrl = data->cb_data;writel (0 , pctrl->regs[0 ] +PS_HOLD_OFFSET );mdelay (1000 );
@@ -1438,7 +1435,11 @@ static struct msm_pinctrl *poweroff_pctrl;static void msm_ps_hold_poweroff (void ) { -msm_ps_hold_restart (&poweroff_pctrl->restart_nb,0 ,NULL ); +struct sys_off_data data = { + .cb_data = poweroff_pctrl, + }; + +msm_ps_hold_restart (&data); }static void msm_pinctrl_setup_pm_reset (struct msm_pinctrl *pctrl)
@@ -1448,9 +1449,11 @@ static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl)for (i =0 ; i < pctrl->soc->nfunctions; i++)if (!strcmp (func[i].name,"ps_hold" )) { - pctrl->restart_nb.notifier_call = msm_ps_hold_restart; - pctrl->restart_nb.priority =128 ; -if (register_restart_handler (&pctrl->restart_nb)) +if (devm_register_sys_off_handler (pctrl->dev, +SYS_OFF_MODE_RESTART , +128 , + msm_ps_hold_restart, + pctrl))dev_err (pctrl->dev,"failed to setup restart handler.\n" ); poweroff_pctrl = pctrl;
@@ -1552,8 +1555,6 @@ void msm_pinctrl_remove(struct platform_device *pdev)struct msm_pinctrl *pctrl =platform_get_drvdata (pdev);gpiochip_remove (&pctrl->chip); - -unregister_restart_handler (&pctrl->restart_nb); }EXPORT_SYMBOL (msm_pinctrl_remove);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 347/444 net: dwmac-sun8i: Use parsed internal PHY address instead of 1
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Kocialkowski <[email protected]>
[ Upstream commit 47653e4243f2b0a26372e481ca098936b51ec3a8 ]
While the MDIO address of the internal PHY on Allwinner sun8i chips is generally 1, of_mdio_parse_addr is used to cleanly parse the address from the device-tree instead of hardcoding it.
A commit reworking the code ditched the parsed value and hardcoded the value 1 instead, which didn't really break anything but is more fragile and not future-proof.
Restore the initial behavior using the parsed address returned from the helper.
--- drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +1 -1
@@ -966,7 +966,7 @@ static int sun8i_dwmac_set_syscon(struct device *dev,/* of_mdio_parse_addr returns a valid (0 ~ 31) PHY * address. No need to mask it again. */ - reg |=1 <<H3_EPHY_ADDR_SHIFT ; + reg |= ret <<H3_EPHY_ADDR_SHIFT ; }else {/* For SoCs without internal PHY the PHY selection bit should be * set to 0 (external PHY).
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 348/444 net: lan743x: Restore SGMII CTRL register on resume
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thangaraj Samynathan <[email protected]>
[ Upstream commit 293e38ff4e4c2ba53f3fd47d8a4a9f0f0414a7a6 ]
SGMII_CTRL register, which specifies the active interface, was not properly restored when resuming from suspend. This led to incorrect interface selection after resume particularly in scenarios involving the FPGA.
To fix this:
- Move the SGMII_CTRL setup out of the probe function.
- Initialize the register in the hardware initialization helper function, which is called during both device initialization and resume.
This ensures the interface configuration is consistently restored after suspend/resume cycles.
--- drivers/net/ethernet/microchip/lan743x_main.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
drivers/net/ethernet/microchip/lan743x_main.c +10 -9
@@ -3259,6 +3259,7 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter, struct pci_dev *pdev) {struct lan743x_tx *tx; +u32 sgmii_ctl;int index;int ret;
@@ -3271,6 +3272,15 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter,spin_lock_init (&adapter->eth_syslock_spinlock);mutex_init (&adapter->sgmii_rw_lock);pci11x1x_set_rfe_rd_fifo_threshold (adapter); + sgmii_ctl =lan743x_csr_read (adapter,SGMII_CTL ); +if (adapter->is_sgmii_en) { + sgmii_ctl |=SGMII_CTL_SGMII_ENABLE_ ; + sgmii_ctl &= ~SGMII_CTL_SGMII_POWER_DN_ ; + }else { + sgmii_ctl &= ~SGMII_CTL_SGMII_ENABLE_ ; + sgmii_ctl |=SGMII_CTL_SGMII_POWER_DN_ ; + } +lan743x_csr_write (adapter,SGMII_CTL , sgmii_ctl); }else { adapter->max_tx_channels =LAN743X_MAX_TX_CHANNELS ; adapter->used_tx_channels =LAN743X_USED_TX_CHANNELS ;
@@ -3319,7 +3329,6 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter,static int lan743x_mdiobus_init (struct lan743x_adapter *adapter) { -u32 sgmii_ctl;int ret; adapter->mdiobus =devm_mdiobus_alloc (&adapter->pdev->dev);
@@ -3331,10 +3340,6 @@ static int lan743x_mdiobus_init(struct lan743x_adapter *adapter) adapter->mdiobus->priv = (void *)adapter;if (adapter->is_pci11x1x) {if (adapter->is_sgmii_en) { - sgmii_ctl =lan743x_csr_read (adapter,SGMII_CTL ); - sgmii_ctl |=SGMII_CTL_SGMII_ENABLE_ ; - sgmii_ctl &= ~SGMII_CTL_SGMII_POWER_DN_ ; -lan743x_csr_write (adapter,SGMII_CTL , sgmii_ctl);netif_dbg (adapter, drv, adapter->netdev,"SGMII operation\n" ); adapter->mdiobus->read = lan743x_mdiobus_read_c22;
@@ -3345,10 +3350,6 @@ static int lan743x_mdiobus_init(struct lan743x_adapter *adapter)netif_dbg (adapter, drv, adapter->netdev,"lan743x-mdiobus-c45\n" ); }else { - sgmii_ctl =lan743x_csr_read (adapter,SGMII_CTL ); - sgmii_ctl &= ~SGMII_CTL_SGMII_ENABLE_ ; - sgmii_ctl |=SGMII_CTL_SGMII_POWER_DN_ ; -lan743x_csr_write (adapter,SGMII_CTL , sgmii_ctl);netif_dbg (adapter, drv, adapter->netdev,"RGMII operation\n" );// Only C22 support when RGMII I/F
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 349/444 io_uring: fix overflow resched cqe reordering
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Begunkov <[email protected]>
[ Upstream commit a7d755ed9ce9738af3db602eb29d32774a180bc7 ]
Leaving the CQ critical section in the middle of a overflow flushing can cause cqe reordering since the cache cq pointers are reset and any new cqe emitters that might get called in between are not going to be forced into io_cqe_cache_refill().
--- io_uring/io_uring.c | 1 + 1 file changed, 1 insertion(+)
io_uring/io_uring.c +1 -0
@@ -701,6 +701,7 @@ static void __io_cqring_overflow_flush(struct io_ring_ctx *ctx)* to care for a non-real case. */ if (need_resched ()) { + ctx->cqe_sentinel = ctx->cqe_cached;io_cq_unlock_post (ctx);mutex_unlock (&ctx->uring_lock);cond_resched ();
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 350/444 sch_hfsc: Fix qlen accounting bug when using peek in hfsc_enqueue()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Wang <[email protected]>
[ Upstream commit 3f981138109f63232a5fb7165938d4c945cc1b9d ]
When enqueuing the first packet to an HFSC class, hfsc_enqueue() calls the child qdisc's peek() operation before incrementing sch->q.qlen and sch->qstats.backlog. If the child qdisc uses qdisc_peek_dequeued(), this may trigger an immediate dequeue and potential packet drop. In such cases, qdisc_tree_reduce_backlog() is called, but the HFSC qdisc's qlen and backlog have not yet been updated, leading to inconsistent queue accounting. This can leave an empty HFSC class in the active list, causing further consequences like use-after-free.
This patch fixes the bug by moving the increment of sch->q.qlen and sch->qstats.backlog before the call to the child qdisc's peek() operation. This ensures that queue length and backlog are always accurate when packet drops or dequeues are triggered during the peek.
--- net/sched/sch_hfsc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/sched/sch_hfsc.c +3 -3
@@ -1570,6 +1570,9 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free)return err; } + sch->qstats.backlog += len; + sch->q.qlen++; +if (first && !cl->cl_nactive) {if (cl->cl_flags &HFSC_RSC )init_ed (cl, len);
@@ -1585,9 +1588,6 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) } - sch->qstats.backlog += len; - sch->q.qlen++; -return NET_XMIT_SUCCESS ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 351/444 octeontx2-pf: Add AF_XDP non-zero copy support
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suman Ghosh <[email protected]>
[ Upstream commit b4164de5041b51cda3438e75bce668e2556057c3 ]
Set xdp rx ring memory type as MEM_TYPE_PAGE_POOL for af-xdp to work. This is needed since xdp_return_frame internally will use page pools.
--- drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +7 -1
@@ -988,6 +988,7 @@ static int otx2_cq_init(struct otx2_nic *pfvf, u16 qidx)int err, pool_id, non_xdp_queues;struct nix_aq_enq_req *aq;struct otx2_cq_queue *cq; +struct otx2_pool *pool; cq = &qset->cq[qidx]; cq->cq_idx = qidx;
@@ -996,8 +997,13 @@ static int otx2_cq_init(struct otx2_nic *pfvf, u16 qidx) cq->cq_type =CQ_RX ; cq->cint_idx = qidx; cq->cqe_cnt = qset->rqe_cnt; -if (pfvf->xdp_prog) +if (pfvf->xdp_prog) { + pool = &qset->pool[qidx];xdp_rxq_info_reg (&cq->xdp_rxq, pfvf->netdev, qidx,0 ); +xdp_rxq_info_reg_mem_model (&cq->xdp_rxq, +MEM_TYPE_PAGE_POOL , + pool->page_pool); + } }else if (qidx < non_xdp_queues) { cq->cq_type =CQ_TX ; cq->cint_idx = qidx - pfvf->hw.rx_queues;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 352/444 net/tipc: fix slab-use-after-free Read in tipc_aead_encrypt_done
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Liang <[email protected]>
[ Upstream commit e279024617134c94fd3e37470156534d5f2b3472 ]
Syzbot reported a slab-use-after-free with the following call trace:
==================================================================
BUG: KASAN: slab-use-after-free in tipc_aead_encrypt_done+0x4bd/0x510 net/tipc/crypto.c:840 Read of size 8 at addr ffff88807a733000 by task kworker/1:0/25 Call Trace: kasan_report+0xd9/0x110 mm/kasan/report.c:601 tipc_aead_encrypt_done+0x4bd/0x510 net/tipc/crypto.c:840 crypto_request_complete include/crypto/algapi.h:266 aead_request_complete include/crypto/internal/aead.h:85 cryptd_aead_crypt+0x3b8/0x750 crypto/cryptd.c:772 crypto_request_complete include/crypto/algapi.h:266 cryptd_queue_worker+0x131/0x200 crypto/cryptd.c:181 process_one_work+0x9fb/0x1b60 kernel/workqueue.c:3231 Allocated by task 8355: kzalloc_noprof include/linux/slab.h:778 tipc_crypto_start+0xcc/0x9e0 net/tipc/crypto.c:1466 tipc_init_net+0x2dd/0x430 net/tipc/core.c:72 ops_init+0xb9/0x650 net/core/net_namespace.c:139 setup_net+0x435/0xb40 net/core/net_namespace.c:343 copy_net_ns+0x2f0/0x670 net/core/net_namespace.c:508 create_new_namespaces+0x3ea/0xb10 kernel/nsproxy.c:110 unshare_nsproxy_namespaces+0xc0/0x1f0 kernel/nsproxy.c:228 ksys_unshare+0x419/0x970 kernel/fork.c:3323 __do_sys_unshare kernel/fork.c:3394 Freed by task 63: kfree+0x12a/0x3b0 mm/slub.c:4557 tipc_crypto_stop+0x23c/0x500 net/tipc/crypto.c:1539 tipc_exit_net+0x8c/0x110 net/tipc/core.c:119 ops_exit_list+0xb0/0x180 net/core/net_namespace.c:173 cleanup_net+0x5b7/0xbf0 net/core/net_namespace.c:640 process_one_work+0x9fb/0x1b60 kernel/workqueue.c:3231
After freed the tipc_crypto tx by delete namespace, tipc_aead_encrypt_done may still visit it in cryptd_queue_worker workqueue.
I reproduce this issue by:
ip netns add ns1
ip link add veth1 type veth peer name veth2
ip link set veth1 netns ns1
ip netns exec ns1 tipc bearer enable media eth dev veth1 ip netns exec ns1 tipc node set key this_is_a_master_key master ip netns exec ns1 tipc bearer disable media eth dev veth1 ip netns del ns1
The key of reproduction is that, simd_aead_encrypt is interrupted, leading to crypto_simd_usable() return false. Thus, the cryptd_queue_worker is triggered, and the tipc_crypto tx will be visited.
tipc_disc_timeout
tipc_bearer_xmit_skb
tipc_crypto_xmit
tipc_aead_encrypt
crypto_aead_encrypt
// encrypt()
simd_aead_encrypt
// crypto_simd_usable() is false
child = &ctx->cryptd_tfm->base; simd_aead_encrypt
crypto_aead_encrypt
// encrypt()
cryptd_aead_encrypt_enqueue
cryptd_aead_enqueue
cryptd_enqueue_request
// trigger cryptd_queue_worker
queue_work_on(smp_processor_id(), cryptd_wq, &cpu_queue->work)Fix this by holding net reference count before encrypt.
--- net/tipc/crypto.c | 5 +++++ 1 file changed, 5 insertions(+)
net/tipc/crypto.c +5 -0
@@ -817,12 +817,16 @@ static int tipc_aead_encrypt(struct tipc_aead *aead, struct sk_buff *skb, goto exit; } +/* Get net to avoid freed tipc_crypto when delete namespace */ +get_net (aead->crypto->net); +/* Now, do encrypt */ rc =crypto_aead_encrypt (req);if (rc == -EINPROGRESS || rc == -EBUSY )return rc;tipc_bearer_put (b); +put_net (aead->crypto->net); exit:kfree (ctx);
@@ -860,6 +864,7 @@ static void tipc_aead_encrypt_done(void *data, int err)kfree (tx_ctx);tipc_bearer_put (b);tipc_aead_put (aead); +put_net (net); }/**
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 353/444 octeontx2-af: Set LMT_ENA bit for APR table entries
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Subbaraya Sundeep <[email protected]>
[ Upstream commit 0eefa27b493306928d88af6368193b134c98fd64 ]
This patch enables the LMT line for a PF/VF by setting the LMT_ENA bit in the APR_LMT_MAP_ENTRY_S structure.
Additionally, it simplifies the logic for calculating the LMTST table index by consistently using the maximum number of hw supported VFs (i.e., 256).
--- .../net/ethernet/marvell/octeontx2/af/rvu_cn10k.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c +13 -2
@@ -15,13 +15,17 @@#define LMT_TBL_OP_WRITE 1#define LMT_MAP_TABLE_SIZE (128 * 1024)#define LMT_MAPTBL_ENTRY_SIZE 16 +#define LMT_MAX_VFS 256 + +#define LMT_MAP_ENTRY_ENA BIT_ULL(20) +#define LMT_MAP_ENTRY_LINES GENMASK_ULL(18, 16)/* Function to perform operations (read/write) on lmtst map table */ static int lmtst_map_table_ops (struct rvu *rvu,u32 index,u64 *val,int lmt_tbl_op) {void __iomem *lmt_map_base; -u64 tbl_base; +u64 tbl_base, cfg; tbl_base =rvu_read64 (rvu,BLKADDR_APR ,APR_AF_LMT_MAP_BASE );
@@ -35,6 +39,13 @@ static int lmtst_map_table_ops(struct rvu *rvu, u32 index, u64 *val, *val =readq (lmt_map_base + index); }else {writeq ((*val), (lmt_map_base + index)); + + cfg =FIELD_PREP (LMT_MAP_ENTRY_ENA ,0x1 ); +/* 2048 LMTLINES */ + cfg |=FIELD_PREP (LMT_MAP_ENTRY_LINES ,0x6 ); + +writeq (cfg, (lmt_map_base + (index +8 ))); +/* Flushing the AP interceptor cache to make APR_LMT_MAP_ENTRY_S * changes effective. Write 1 for flush and read is being used as a * barrier and sets up a data dependency. Write to 0 after a write
@@ -52,7 +63,7 @@ static int lmtst_map_table_ops(struct rvu *rvu, u32 index, u64 *val,#define LMT_MAP_TBL_W1_OFF 8static u32 rvu_get_lmtst_tbl_index (struct rvu *rvu,u16 pcifunc) { -return ((rvu_get_pf (pcifunc) * rvu->hw->total_vfs) + +return ((rvu_get_pf (pcifunc) *LMT_MAX_VFS ) + (pcifunc &RVU_PFVF_FUNC_MASK )) *LMT_MAPTBL_ENTRY_SIZE ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 354/444 octeontx2-af: Fix APR entry mapping based on APR_LMT_CFG
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geetha sowjanya <[email protected]>
[ Upstream commit a6ae7129819ad20788e610261246e71736543b8b ]
The current implementation maps the APR table using a fixed size, which can lead to incorrect mapping when the number of PFs and VFs varies.
This patch corrects the mapping by calculating the APR table size dynamically based on the values configured in the APR_LMT_CFG register, ensuring accurate representation of APR entries in debugfs.
--- drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c | 9 ++++++--- .../net/ethernet/marvell/octeontx2/af/rvu_debugfs.c | 11 ++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-)
drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c +6 -3
@@ -13,7 +13,6 @@/* RVU LMTST */ #define LMT_TBL_OP_READ 0#define LMT_TBL_OP_WRITE 1 -#define LMT_MAP_TABLE_SIZE (128 * 1024)#define LMT_MAPTBL_ENTRY_SIZE 16#define LMT_MAX_VFS 256
@@ -26,10 +25,14 @@ static int lmtst_map_table_ops(struct rvu *rvu, u32 index, u64 *val, {void __iomem *lmt_map_base;u64 tbl_base, cfg; +int pfs, vfs; tbl_base =rvu_read64 (rvu,BLKADDR_APR ,APR_AF_LMT_MAP_BASE ); + cfg =rvu_read64 (rvu,BLKADDR_APR ,APR_AF_LMT_CFG ); + vfs =1 << (cfg &0xF ); + pfs =1 << ((cfg >>4 ) &0x7 ); - lmt_map_base =ioremap_wc (tbl_base,LMT_MAP_TABLE_SIZE ); + lmt_map_base =ioremap_wc (tbl_base, pfs * vfs *LMT_MAPTBL_ENTRY_SIZE );if (!lmt_map_base) {dev_err (rvu->dev,"Failed to setup lmt map table mapping!!\n" );return -ENOMEM ;
@@ -80,7 +83,7 @@ static int rvu_get_lmtaddr(struct rvu *rvu, u16 pcifunc,mutex_lock (&rvu->rsrc_lock);rvu_write64 (rvu,BLKADDR_RVUM ,RVU_AF_SMMU_ADDR_REQ , iova); - pf =rvu_get_pf (pcifunc) &0x1F ; + pf =rvu_get_pf (pcifunc) &RVU_PFVF_PF_MASK ; val =BIT_ULL (63 ) |BIT_ULL (14 ) |BIT_ULL (13 ) | pf <<8 | ((pcifunc &RVU_PFVF_FUNC_MASK ) &0xFF );rvu_write64 (rvu,BLKADDR_RVUM ,RVU_AF_SMMU_TXN_REQ , val);
drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c +8 -3
@@ -580,6 +580,7 @@ static ssize_t rvu_dbg_lmtst_map_table_display(struct file *filp,u64 lmt_addr, val, tbl_base;int pf, vf, num_vfs, hw_vfs;void __iomem *lmt_map_base; +int apr_pfs, apr_vfs;int buf_size =10240 ;size_t off =0 ;int index =0 ;
@@ -595,8 +596,12 @@ static ssize_t rvu_dbg_lmtst_map_table_display(struct file *filp,return -ENOMEM ; tbl_base =rvu_read64 (rvu,BLKADDR_APR ,APR_AF_LMT_MAP_BASE ); + val =rvu_read64 (rvu,BLKADDR_APR ,APR_AF_LMT_CFG ); + apr_vfs =1 << (val &0xF ); + apr_pfs =1 << ((val >>4 ) &0x7 ); - lmt_map_base =ioremap_wc (tbl_base,128 *1024 ); + lmt_map_base =ioremap_wc (tbl_base, apr_pfs * apr_vfs * +LMT_MAPTBL_ENTRY_SIZE );if (!lmt_map_base) {dev_err (rvu->dev,"Failed to setup lmt map table mapping!!\n" );kfree (buf);
@@ -618,7 +623,7 @@ static ssize_t rvu_dbg_lmtst_map_table_display(struct file *filp, off +=scnprintf (&buf[off], buf_size -1 - off,"PF%d \t\t\t" , pf); - index = pf * rvu->hw->total_vfs *LMT_MAPTBL_ENTRY_SIZE ; + index = pf * apr_vfs *LMT_MAPTBL_ENTRY_SIZE ; off +=scnprintf (&buf[off], buf_size -1 - off," 0x%llx\t\t" , (tbl_base + index)); lmt_addr =readq (lmt_map_base + index);
@@ -631,7 +636,7 @@ static ssize_t rvu_dbg_lmtst_map_table_display(struct file *filp,/* Reading num of VFs per PF */ rvu_get_pf_numvfs (rvu, pf, &num_vfs, &hw_vfs);for (vf =0 ; vf < num_vfs; vf++) { - index = (pf * rvu->hw->total_vfs *16 ) + + index = (pf * apr_vfs *LMT_MAPTBL_ENTRY_SIZE ) + ((vf +1 ) *LMT_MAPTBL_ENTRY_SIZE ); off +=scnprintf (&buf[off], buf_size -1 - off,"PF%d:VF%d \t\t" , pf, vf);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 355/444 clk: s2mps11: initialise clk_hw_onecell_data::num before accessing ::hws[] in probe()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Draszik <[email protected]>
commit 3e14c7207a975eefcda1929b2134a9f4119dde45 upstream.
With UBSAN enabled, we're getting the following trace:
UBSAN: array-index-out-of-bounds in .../drivers/clk/clk-s2mps11.c:186:3
index 0 is out of range for type 'struct clk_hw *[] __counted_by(num)' (aka 'struct clk_hw *[]')This is because commit f316cdff8d67 ("clk: Annotate struct clk_hw_onecell_data with __counted_by") annotated the hws member of that struct with __counted_by, which informs the bounds sanitizer about the number of elements in hws, so that it can warn when hws is accessed out of bounds.
As noted in that change, the __counted_by member must be initialised with the number of elements before the first array access happens, otherwise there will be a warning from each access prior to the initialisation because the number of elements is zero. This occurs in s2mps11_clk_probe() due to ::num being assigned after ::hws access.
Move the assignment to satisfy the requirement of assign-before-access.
--- drivers/clk/clk-s2mps11.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/clk/clk-s2mps11.c +2 -1
@@ -137,6 +137,8 @@ static int s2mps11_clk_probe(struct platform_device *pdev)if (!clk_data)return -ENOMEM ; + clk_data->num =S2MPS11_CLKS_NUM ; +switch (hwid) {case S2MPS11X : s2mps11_reg =S2MPS11_REG_RTC_CTRL ;
@@ -186,7 +188,6 @@ static int s2mps11_clk_probe(struct platform_device *pdev) clk_data->hws[i] = &s2mps11_clks[i].hw; } - clk_data->num =S2MPS11_CLKS_NUM ;of_clk_add_hw_provider (s2mps11_clks->clk_np, of_clk_hw_onecell_get, clk_data);
Signature · 1 line
2.49.0
Greg Kroah-Hartman
maintainerPATCH 356/444 crypto: algif_hash - fix double free in hash_accept
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Pravdin <[email protected]>
commit b2df03ed4052e97126267e8c13ad4204ea6ba9b6 upstream.
If accept(2) is called on socket type algif_hash with MSG_MORE flag set and crypto_ahash_import fails, sk2 is freed. However, it is also freed in af_alg_release, leading to slab-use-after-free error.
--- crypto/algif_hash.c | 4 ---- 1 file changed, 4 deletions(-)
crypto/algif_hash.c +0 -4
@@ -265,10 +265,6 @@ static int hash_accept(struct socket *so goto out_free_state; err =crypto_ahash_import (&ctx2->req, state); -if (err) { -sock_orphan (sk2); -sock_put (sk2); - } out_free_state:kfree_sensitive (state);
Greg Kroah-Hartman
maintainerPATCH 357/444 padata: do not leak refcount in reorder_work
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dominik Grzegorzek <[email protected]>
commit d6ebcde6d4ecf34f8495fb30516645db3aea8993 upstream.
A recent patch that addressed a UAF introduced a reference count leak:
the parallel_data refcount is incremented unconditionally, regardless of the return value of queue_work(). If the work item is already queued, the incremented refcount is never decremented.
Fix this by checking the return value of queue_work() and decrementing the refcount when necessary.
Resolves:
Unreferenced object 0xffff9d9f421e3d80 (size 192):
comm "cryptomgr_probe", pid 157, jiffies 4294694003 hex dump (first 32 bytes):
80 8b cf 41 9f 9d ff ff b8 97 e0 89 ff ff ff ff ...A............
d0 97 e0 89 ff ff ff ff 19 00 00 00 1f 88 23 00 ..............#.
backtrace (crc 838fb36):
__kmalloc_cache_noprof+0x284/0x320
padata_alloc_pd+0x20/0x1e0
padata_alloc_shell+0x3b/0xa0
0xffffffffc040a54d
cryptomgr_probe+0x43/0xc0
kthread+0xf6/0x1f0
ret_from_fork+0x2f/0x50
ret_from_fork_asm+0x1a/0x30--- kernel/padata.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/padata.c +2 -1
@@ -358,7 +358,8 @@ static void padata_reorder(struct parall* To avoid UAF issue, add pd ref here, and put pd ref after reorder_work finish. */ padata_get_pd (pd); -queue_work (pinst->serial_wq, &pd->reorder_work); +if (!queue_work (pinst->serial_wq, &pd->reorder_work)) +padata_put_pd (pd); } }
Greg Kroah-Hartman
maintainerPATCH 358/444 can: slcan: allow reception of short error messages
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Carlos Sanchez <[email protected]>
commit ef0841e4cb08754be6cb42bf97739fce5d086e5f upstream.
Allows slcan to receive short messages (typically errors) from the serial interface.
When error support was added to slcan protocol in b32ff4668544e1333b694fcc7812b2d7397b4d6a ("can: slcan: extend the protocol with error info") the minimum valid message size changed from 5 (minimum standard can frame tIII0) to 3 ("e1a" is a valid protocol message, it is one of the examples given in the comments for slcan_bump_err() ), but the check for minimum message length prodicating all decoding was not adjusted. This makes short error messages discarded and error frames not being generated.
This patch changes the minimum length to the new minimum (3 characters, excluding terminator, is now a valid message).
--- drivers/net/can/slcan/slcan-core.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-)
drivers/net/can/slcan/slcan-core.c +20 -6
@@ -71,12 +71,21 @@ MODULE_AUTHOR("Dario Binacchi <dario.bin#define SLCAN_CMD_LEN 1#define SLCAN_SFF_ID_LEN 3#define SLCAN_EFF_ID_LEN 8 +#define SLCAN_DATA_LENGTH_LEN 1 +#define SLCAN_ERROR_LEN 1#define SLCAN_STATE_LEN 1#define SLCAN_STATE_BE_RXCNT_LEN 3#define SLCAN_STATE_BE_TXCNT_LEN 3 -#define SLCAN_STATE_FRAME_LEN (1 + SLCAN_CMD_LEN + \ - SLCAN_STATE_BE_RXCNT_LEN + \ - SLCAN_STATE_BE_TXCNT_LEN) +#define SLCAN_STATE_MSG_LEN (SLCAN_CMD_LEN + \ + SLCAN_STATE_LEN + \ + SLCAN_STATE_BE_RXCNT_LEN + \ + SLCAN_STATE_BE_TXCNT_LEN) +#define SLCAN_ERROR_MSG_LEN_MIN (SLCAN_CMD_LEN + \ + SLCAN_ERROR_LEN + \ + SLCAN_DATA_LENGTH_LEN) +#define SLCAN_FRAME_MSG_LEN_MIN (SLCAN_CMD_LEN + \ + SLCAN_SFF_ID_LEN + \ + SLCAN_DATA_LENGTH_LEN)struct slcan {struct can_priv can;
@@ -176,6 +185,9 @@ static void slcan_bump_frame(struct slcau32 tmpid;char *cmd = sl->rbuff; +if (sl->rcount <SLCAN_FRAME_MSG_LEN_MIN ) +return ; + skb =alloc_can_skb (sl->dev, &cf);if (unlikely (!skb)) { sl->dev->stats.rx_dropped++;
@@ -281,7 +293,7 @@ static void slcan_bump_state(struct slcareturn ; } -if (state == sl->can.state || sl->rcount <SLCAN_STATE_FRAME_LEN ) +if (state == sl->can.state || sl->rcount !=SLCAN_STATE_MSG_LEN )return ; cmd +=SLCAN_STATE_BE_RXCNT_LEN +SLCAN_CMD_LEN +1 ;
@@ -328,6 +340,9 @@ static void slcan_bump_err(struct slcanbool rx_errors = false, tx_errors = false, rx_over_errors = false;int i, len; +if (sl->rcount <SLCAN_ERROR_MSG_LEN_MIN ) +return ; +/* get len from sanitized ASCII value */ len = cmd[1 ];if (len >='0' && len <'9' )
@@ -456,8 +471,7 @@ static void slcan_bump(struct slcan *sl)static void slcan_unesc (struct slcan *sl,unsigned char s) {if ((s =='\r' ) || (s =='\a' )) {/* CR or BEL ends the pdu */ -if (!test_and_clear_bit (SLF_ERROR , &sl->flags) && - sl->rcount >4 ) +if (!test_and_clear_bit (SLF_ERROR , &sl->flags))slcan_bump (sl); sl->rcount =0 ;
Greg Kroah-Hartman
maintainerPATCH 359/444 can: bcm: add locking for bcm_op runtime updates
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <[email protected]>
commit c2aba69d0c36a496ab4f2e81e9c2b271f2693fd7 upstream.
The CAN broadcast manager (CAN BCM) can send a sequence of CAN frames via hrtimer. The content and also the length of the sequence can be changed resp reduced at runtime where the 'currframe' counter is then set to zero.
Although this appeared to be a safe operation the updates of 'currframe' can be triggered from user space and hrtimer context in bcm_can_tx(). Anderson Nascimento created a proof of concept that triggered a KASAN slab-out-of-bounds read access which can be prevented with a spin_lock_bh.
At the rework of bcm_can_tx() the 'count' variable has been moved into the protected section as this variable can be modified from both contexts too.
--- net/can/bcm.c | 66 +++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 21 deletions(-)
net/can/bcm.c +45 -21
@@ -58,6 +58,7 @@#include <linux/can/skb.h> #include <linux/can/bcm.h> #include <linux/slab.h> +#include <linux/spinlock.h> #include <net/sock.h> #include <net/net_namespace.h>
@@ -120,6 +121,7 @@ struct bcm_op {struct canfd_frame last_sframe;struct sock *sk;struct net_device *rx_reg_dev; +spinlock_t bcm_tx_lock;/* protect currframe/count in runtime updates */ };struct bcm_sock {
@@ -273,13 +275,18 @@ static void bcm_can_tx(struct bcm_op *op {struct sk_buff *skb;struct net_device *dev; -struct canfd_frame *cf = op->frames + op->cfsiz * op->currframe; +struct canfd_frame *cf;int err;/* no target device? => exit */ if (!op->ifindex)return ; +/* read currframe under lock protection */ +spin_lock_bh (&op->bcm_tx_lock); + cf = op->frames + op->cfsiz * op->currframe; +spin_unlock_bh (&op->bcm_tx_lock); + dev =dev_get_by_index (sock_net (op->sk), op->ifindex);if (!dev) {/* RFC: should this bcm_op remove itself here? */
@@ -300,6 +307,10 @@ static void bcm_can_tx(struct bcm_op *op skb->dev = dev;can_skb_set_owner (skb, op->sk); err =can_send (skb,1 ); + +/* update currframe and count under lock protection */ +spin_lock_bh (&op->bcm_tx_lock); +if (!err) op->frames_abs++;
@@ -308,6 +319,11 @@ static void bcm_can_tx(struct bcm_op *op/* reached last frame? */ if (op->currframe >= op->nframes) op->currframe =0 ; + +if (op->count >0 ) + op->count--; + +spin_unlock_bh (&op->bcm_tx_lock); out:dev_put (dev); }
@@ -404,7 +420,7 @@ static enum hrtimer_restart bcm_tx_timeostruct bcm_msg_head msg_head;if (op->kt_ival1 && (op->count >0 )) { - op->count--; +bcm_can_tx (op);if (!op->count && (op->flags &TX_COUNTEVT )) {/* create notification to user */
@@ -419,7 +435,6 @@ static enum hrtimer_restart bcm_tx_timeobcm_send_to_user (op, &msg_head,NULL ,0 ); } -bcm_can_tx (op); }else if (op->kt_ival2) {bcm_can_tx (op);
@@ -914,6 +929,27 @@ static int bcm_tx_setup(struct bcm_msg_h } op->flags = msg_head->flags; +/* only lock for unlikely count/nframes/currframe changes */ +if (op->nframes != msg_head->nframes || + op->flags &TX_RESET_MULTI_IDX || + op->flags &SETTIMER ) { + +spin_lock_bh (&op->bcm_tx_lock); + +if (op->nframes != msg_head->nframes || + op->flags &TX_RESET_MULTI_IDX ) { +/* potentially update changed nframes */ + op->nframes = msg_head->nframes; +/* restart multiple frame transmission */ + op->currframe =0 ; + } + +if (op->flags &SETTIMER ) + op->count = msg_head->count; + +spin_unlock_bh (&op->bcm_tx_lock); + } + }else {/* insert new BCM operation for the given can_id */
@@ -921,9 +957,14 @@ static int bcm_tx_setup(struct bcm_msg_hif (!op)return -ENOMEM ; +spin_lock_init (&op->bcm_tx_lock); op->can_id = msg_head->can_id; op->cfsiz =CFSIZ (msg_head->flags); op->flags = msg_head->flags; + op->nframes = msg_head->nframes; + +if (op->flags &SETTIMER ) + op->count = msg_head->count;/* create array for CAN frames and copy the data */ if (msg_head->nframes >1 ) {
@@ -982,22 +1023,8 @@ static int bcm_tx_setup(struct bcm_msg_h }/* if ((op = bcm_find_op(&bo->tx_ops, msg_head->can_id, ifindex))) */ -if (op->nframes != msg_head->nframes) { - op->nframes = msg_head->nframes; -/* start multiple frame transmission with index 0 */ - op->currframe =0 ; - } - -/* check flags */ - -if (op->flags &TX_RESET_MULTI_IDX ) { -/* start multiple frame transmission with index 0 */ - op->currframe =0 ; - } -if (op->flags &SETTIMER ) {/* set timer values */ - op->count = msg_head->count; op->ival1 = msg_head->ival1; op->ival2 = msg_head->ival2; op->kt_ival1 =bcm_timeval_to_ktime (msg_head->ival1);
@@ -1014,11 +1041,8 @@ static int bcm_tx_setup(struct bcm_msg_h op->flags |=TX_ANNOUNCE ; } -if (op->flags &TX_ANNOUNCE ) { +if (op->flags &TX_ANNOUNCE )bcm_can_tx (op); -if (op->count) - op->count--; - }if (op->flags &STARTTIMER )bcm_tx_start_timer (op);
Greg Kroah-Hartman
maintainerPATCH 360/444 can: bcm: add missing rcu read protection for procfs content
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <[email protected]>
commit dac5e6249159ac255dad9781793dbe5908ac9ddb upstream.
When the procfs content is generated for a bcm_op which is in the process to be removed the procfs output might show unreliable data (UAF).
As the removal of bcm_op's is already implemented with rcu handling this patch adds the missing rcu_read_lock() and makes sure the list entries are properly removed under rcu protection.
--- net/can/bcm.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
net/can/bcm.c +9 -4
@@ -207,7 +207,9 @@ static int bcm_proc_show(struct seq_fileseq_printf (m," / bound %s" ,bcm_proc_getifname (net, ifname, bo->ifindex));seq_printf (m," <<<\n" ); -list_for_each_entry (op, &bo->rx_ops, list) { +rcu_read_lock (); + +list_for_each_entry_rcu (op, &bo->rx_ops, list) {unsigned long reduction;
@@ -263,6 +265,9 @@ static int bcm_proc_show(struct seq_file seq_printf(m, "# sent %ld\n", op->frames_abs); }seq_putc (m,'\n' ); + +rcu_read_unlock (); +return 0 ; }#endif /* CONFIG_PROC_FS */
@@ -816,7 +821,7 @@ static int bcm_delete_rx_op(struct list_REGMASK (op->can_id), bcm_rx_handler, op); -list_del (&op->list); +list_del_rcu (&op->list);bcm_remove_op (op);return 1 ;/* done */ }
@@ -836,7 +841,7 @@ static int bcm_delete_tx_op(struct list_list_for_each_entry_safe (op, n, ops, list) {if ((op->can_id == mh->can_id) && (op->ifindex == ifindex) && (op->flags &CAN_FD_FRAME ) == (mh->flags &CAN_FD_FRAME )) { -list_del (&op->list); +list_del_rcu (&op->list);bcm_remove_op (op);return 1 ;/* done */ }
@@ -1258,7 +1263,7 @@ static int bcm_rx_setup(struct bcm_msg_h bcm_rx_handler, op, "bcm", sk);if (err) {/* this bcm rx op is broken -> remove it */ -list_del (&op->list); +list_del_rcu (&op->list);bcm_remove_op (op);return err; }
Greg Kroah-Hartman
maintainerPATCH 361/444 ASoC: SOF: ipc4-control: Use SOF_CTRL_CMD_BINARY as numid for bytes_ext
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Ujfalusi <[email protected]>
commit 4d14b1069e9e672dbe1adab52594076da6f4a62d upstream.
The header.numid is set to scontrol->comp_id in bytes_ext_get and it is ignored during bytes_ext_put.
The use of comp_id is not quite great as it is kernel internal identification number.
Set the header.numid to SOF_CTRL_CMD_BINARY during get and validate the numid during put to provide consistent and compatible identification number as IPC3.
For IPC4 existing tooling also ignored the numid but with the use of SOF_CTRL_CMD_BINARY the different handling of the blobs can be dropped, providing better user experience.
--- sound/soc/sof/ipc4-control.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
sound/soc/sof/ipc4-control.c +10 -1
@@ -483,6 +483,14 @@ static int sof_ipc4_bytes_ext_put(structreturn -EINVAL ; } +/* Check header id */ +if (header.numid !=SOF_CTRL_CMD_BINARY ) { +dev_err_ratelimited (scomp->dev, +"Incorrect numid for bytes put %d\n" , + header.numid); +return -EINVAL ; + } +/* Verify the ABI header first */ if (copy_from_user (&abi_hdr, tlvd->tlv,sizeof (abi_hdr)))return -EFAULT ;
@@ -565,7 +573,8 @@ static int _sof_ipc4_bytes_ext_get(strucif (data_size > size)return -ENOSPC ; - header.numid = scontrol->comp_id; +/* Set header id and length */ + header.numid =SOF_CTRL_CMD_BINARY ; header.length = data_size;if (copy_to_user (tlvd, &header,sizeof (struct snd_ctl_tlv )))
Greg Kroah-Hartman
maintainerPATCH 362/444 ASoc: SOF: topology: connect DAI to a single DAI link
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kai Vehmanen <[email protected]>
commit 6052f05254b4fe7b16bbd8224779af52fba98b71 upstream.
The partial matching of DAI widget to link names, can cause problems if one of the widget names is a substring of another. E.g. with names "Foo1" and Foo10", it's not possible to correctly link up "Foo1".
Modify the logic so that if multiple DAI links match the widget stream name, prioritize a full match if one is found.
--- sound/soc/sof/topology.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
sound/soc/sof/topology.c +14 -4
@@ -1057,7 +1057,7 @@ static int sof_connect_dai_widget(struct struct snd_sof_dai *dai) {struct snd_soc_card *card = scomp->card; -struct snd_soc_pcm_runtime *rtd; +struct snd_soc_pcm_runtime *rtd, *full, *partial;struct snd_soc_dai *cpu_dai;int stream;int i;
@@ -1074,12 +1074,22 @@ static int sof_connect_dai_widget(structelse goto end; + full =NULL ; + partial =NULL ;list_for_each_entry (rtd, &card->rtd_list, list) {/* does stream match DAI link ? */ -if (!rtd->dai_link->stream_name || - !strstr (rtd->dai_link->stream_name, w->sname)) -continue ; +if (rtd->dai_link->stream_name) { +if (!strcmp (rtd->dai_link->stream_name, w->sname)) { + full = rtd; +break ; + }else if (strstr (rtd->dai_link->stream_name, w->sname)) { + partial = rtd; + } + } + } + rtd = full ? full : partial; +if (rtd) {for_each_rtd_cpu_dais (rtd, i, cpu_dai) {/* * Please create DAI widget in the right order
Greg Kroah-Hartman
maintainerPATCH 363/444 ASoC: SOF: ipc4-pcm: Delay reporting is only supported for playback direction
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Ujfalusi <[email protected]>
commit 98db16f314b3a0d6e5acd94708ea69751436467f upstream.
The firmware does not provide any information for capture streams via the shared pipeline registers.
To avoid reporting invalid delay value for capture streams to user space we need to disable it.
--- sound/soc/sof/ipc4-pcm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
sound/soc/sof/ipc4-pcm.c +2 -1
@@ -621,7 +621,8 @@ static int sof_ipc4_pcm_setup(struct sndreturn -ENOMEM ; } -if (!support_info) +/* Delay reporting is only supported on playback */ +if (!support_info || stream ==SNDRV_PCM_STREAM_CAPTURE )continue ; stream_info =kzalloc (sizeof (*stream_info),GFP_KERNEL );
Greg Kroah-Hartman
maintainerPATCH 364/444 ALSA: pcm: Fix race of buffer access at PCM OSS layer
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 93a81ca0657758b607c3f4ba889ae806be9beb73 upstream.
The PCM OSS layer tries to clear the buffer with the silence data at initialization (or reconfiguration) of a stream with the explicit call of snd_pcm_format_set_silence() with runtime->dma_area. But this may lead to a UAF because the accessed runtime->dma_area might be freed concurrently, as it's performed outside the PCM ops.
For avoiding it, move the code into the PCM core and perform it inside the buffer access lock, so that it won't be changed during the operation.
--- include/sound/pcm.h | 2 ++ sound/core/oss/pcm_oss.c | 3 +-- sound/core/pcm_native.c | 11 +++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-)
include/sound/pcm.h +2 -0
@@ -1427,6 +1427,8 @@ int snd_pcm_lib_mmap_iomem(struct snd_pc#define snd_pcm_lib_mmap_iomem NULL#endif +void snd_pcm_runtime_buffer_set_silence (struct snd_pcm_runtime *runtime); +/** * snd_pcm_limit_isa_dma_size - Get the max size fitting with ISA DMA transfer * @dma: DMA number
sound/core/oss/pcm_oss.c +1 -2
@@ -1085,8 +1085,7 @@ static int snd_pcm_oss_change_params_loc runtime->oss.params =0 ; runtime->oss.prepare =1 ; runtime->oss.buffer_used =0 ; -if (runtime->dma_area) -snd_pcm_format_set_silence (runtime->format, runtime->dma_area,bytes_to_samples (runtime, runtime->dma_bytes)); +snd_pcm_runtime_buffer_set_silence (runtime); runtime->oss.period_frames =snd_pcm_alsa_frames (substream, oss_period_size);
sound/core/pcm_native.c +11 -0
@@ -703,6 +703,17 @@ static void snd_pcm_buffer_access_unlockatomic_inc (&runtime->buffer_accessing); } +/* fill the PCM buffer with the current silence format; called from pcm_oss.c */ +void snd_pcm_runtime_buffer_set_silence (struct snd_pcm_runtime *runtime) +{ +snd_pcm_buffer_access_lock (runtime); +if (runtime->dma_area) +snd_pcm_format_set_silence (runtime->format, runtime->dma_area, +bytes_to_samples (runtime, runtime->dma_bytes)); +snd_pcm_buffer_access_unlock (runtime); +} +EXPORT_SYMBOL_GPL (snd_pcm_runtime_buffer_set_silence); +#if IS_ENABLED (CONFIG_SND_PCM_OSS )#define is_oss_stream (substream) ((substream)->oss.oss)#else
Greg Kroah-Hartman
maintainerPATCH 365/444 ALSA: hda/realtek: Add quirk for Lenovo Yoga Pro 7 14ASP10
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ed Burcher <[email protected]>
commit 8d70503068510e6080c2c649cccb154f16de26c9 upstream.
Lenovo Yoga Pro 7 (gen 10) with Realtek ALC3306 and combined CS35L56 amplifiers need quirk ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN to enable bass
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -10574,6 +10574,7 @@ static const struct hda_quirk alc269_fixSND_PCI_QUIRK (0x17aa ,0x38f9 ,"Thinkbook 16P Gen5" ,ALC287_FIXUP_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x17aa ,0x38fa ,"Thinkbook 16P Gen5" ,ALC287_FIXUP_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x17aa ,0x3902 ,"Lenovo E50-80" ,ALC269_FIXUP_DMIC_THINKPAD_ACPI ), +SND_PCI_QUIRK (0x17aa ,0x390d ,"Lenovo Yoga Pro 7 14ASP10" ,ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN ),SND_PCI_QUIRK (0x17aa ,0x3913 ,"Lenovo 145" ,ALC236_FIXUP_LENOVO_INV_DMIC ),SND_PCI_QUIRK (0x17aa ,0x3977 ,"IdeaPad S210" ,ALC283_FIXUP_INT_MIC ), SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Greg Kroah-Hartman
maintainerPATCH 366/444 llc: fix data loss when reading from a socket in llc_ui_recvmsg()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilia Gavrilov <[email protected]>
commit 239af1970bcb039a1551d2c438d113df0010c149 upstream.
For SOCK_STREAM sockets, if user buffer size (len) is less than skb size (skb->len), the remaining data from skb will be lost after calling kfree_skb().
To fix this, move the statement for partial reading above skb deletion.
Found by InfoTeCS on behalf of Linux Verification Center (linuxtesting.org)
--- net/llc/af_llc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/llc/af_llc.c +4 -4
@@ -888,15 +888,15 @@ static int llc_ui_recvmsg(struct socketif (sk->sk_type !=SOCK_STREAM ) goto copy_uaddr; +/* Partial read */ +if (used + offset < skb_len) +continue ; +if (!(flags &MSG_PEEK )) {skb_unlink (skb, &sk->sk_receive_queue);kfree_skb (skb); *seq =0 ; } - -/* Partial read */ -if (used + offset < skb_len) -continue ; }while (len >0 ); out:
Greg Kroah-Hartman
maintainerPATCH 367/444 can: kvaser_pciefd: Continue parsing DMA buf after dropped RX
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Axel Forsman <[email protected]>
commit 6d820b81c4dc4a4023e45c3cd6707a07dd838649 upstream.
Going bus-off on a channel doing RX could result in dropped packets.
As netif_running() gets cleared before the channel abort procedure, the handling of any last RDATA packets would see netif_rx() return non-zero to signal a dropped packet. kvaser_pciefd_read_buffer() dealt with this "error" by breaking out of processing the remaining DMA RX buffer.
Only return an error from kvaser_pciefd_read_buffer() due to packet corruption, otherwise handle it internally.
--- drivers/net/can/kvaser_pciefd.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/net/can/kvaser_pciefd.c +5 -3
@@ -1137,7 +1137,7 @@ static int kvaser_pciefd_handle_data_pac skb =alloc_canfd_skb (priv->dev, &cf);if (!skb) { priv->dev->stats.rx_dropped++; -return -ENOMEM ; +return 0 ; } cf->len =can_fd_dlc2len (dlc);
@@ -1149,7 +1149,7 @@ static int kvaser_pciefd_handle_data_pac skb =alloc_can_skb (priv->dev, (struct can_frame **)&cf);if (!skb) { priv->dev->stats.rx_dropped++; -return -ENOMEM ; +return 0 ; }can_frame_set_cc_len ((struct can_frame *)cf, dlc, priv->ctrlmode); }
@@ -1167,7 +1167,9 @@ static int kvaser_pciefd_handle_data_pac priv->dev->stats.rx_packets++;kvaser_pciefd_set_skb_timestamp (pcie, skb, p->timestamp); -return netif_rx (skb); +netif_rx (skb); + +return 0 ; } static void kvaser_pciefd_change_state(struct kvaser_pciefd_can *can,
Greg Kroah-Hartman
maintainerPATCH 368/444 platform/x86: dell-wmi-sysman: Avoid buffer overflow in current_password_store()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Moskovkin <[email protected]>
commit 4e89a4077490f52cde652d17e32519b666abf3a6 upstream.
If the 'buf' array received from the user contains an empty string, the 'length' variable will be zero. Accessing the 'buf' array element with index 'length - 1' will result in a buffer overflow.
Add a check for an empty string.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c +1 -1
@@ -45,7 +45,7 @@ static ssize_t current_password_store(stint length; length =strlen (buf); -if (buf[length-1 ] =='\n' ) +if (length && buf[length -1 ] =='\n' ) length--;/* firmware does verifiation of min/max password length,
Greg Kroah-Hartman
maintainerPATCH 369/444 thermal: intel: x86_pkg_temp_thermal: Fix bogus trip temperature
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Rui <[email protected]>
commit cf948c8e274e8b406e846cdf6cc48fe47f98cf57 upstream.
The tj_max value obtained from the Intel TCC library are in Celsius, whereas the thermal subsystem operates in milli-Celsius.
This discrepancy leads to incorrect trip temperature calculations.
Fix bogus trip temperature by converting tj_max to milli-Celsius Unit.
--- drivers/thermal/intel/x86_pkg_temp_thermal.c | 1 + 1 file changed, 1 insertion(+)
drivers/thermal/intel/x86_pkg_temp_thermal.c +1 -0
@@ -331,6 +331,7 @@ static int pkg_temp_thermal_device_add(u tj_max =intel_tcc_get_tjmax (cpu);if (tj_max <0 )return tj_max; + tj_max *=1000 ; zonedev =kzalloc (sizeof (*zonedev),GFP_KERNEL );if (!zonedev)
Greg Kroah-Hartman
maintainerPATCH 370/444 drm/edid: fixed the bug that hdr metadata was not reset
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: feijuan.li <[email protected]>
commit 6692dbc15e5ed40a3aa037aced65d7b8826c58cd upstream.
When DP connected to a device with HDR capability, the hdr structure was filled.Then connected to another sink device without hdr capability, but the hdr info still exist.
--- drivers/gpu/drm/drm_edid.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/drm_edid.c +1 -0
@@ -6471,6 +6471,7 @@ static void drm_reset_display_info(struc info->has_hdmi_infoframe = false; info->rgb_quant_range_selectable = false;memset (&info->hdmi,0 ,sizeof (info->hdmi)); +memset (&connector->hdr_sink_metadata,0 ,sizeof (connector->hdr_sink_metadata)); info->edid_hdmi_rgb444_dc_modes =0 ; info->edid_hdmi_ycbcr444_dc_modes =0 ;
Greg Kroah-Hartman
maintainerPATCH 371/444 smb: client: Fix use-after-free in cifs_fill_dirent
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Zhaolong <[email protected]>
commit a7a8fe56e932a36f43e031b398aef92341bf5ea0 upstream.
There is a race condition in the readdir concurrency process, which may access the rsp buffer after it has been released, triggering the following KASAN warning.
==================================================================
BUG: KASAN: slab-use-after-free in cifs_fill_dirent+0xb03/0xb60 [cifs]
Read of size 4 at addr ffff8880099b819c by task a.out/342975
CPU: 2 UID: 0 PID: 342975 Comm: a.out Not tainted 6.15.0-rc6+ #240 PREEMPT(full)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x53/0x70
print_report+0xce/0x640
kasan_report+0xb8/0xf0
cifs_fill_dirent+0xb03/0xb60 [cifs]
cifs_readdir+0x12cb/0x3190 [cifs]
iterate_dir+0x1a1/0x520
__x64_sys_getdents+0x134/0x220
do_syscall_64+0x4b/0x110
entry_SYSCALL_64_after_hwframe+0x76/0x7e
RIP: 0033:0x7f996f64b9f9
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89
f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01
f0 ff ff 0d f7 c3 0c 00 f7 d8 64 89 8
RSP: 002b:00007f996f53de78 EFLAGS: 00000207 ORIG_RAX: 000000000000004e
RAX: ffffffffffffffda RBX: 00007f996f53ecdc RCX: 00007f996f64b9f9
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000003
RBP: 00007f996f53dea0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000207 R12: ffffffffffffff88
R13: 0000000000000000 R14: 00007ffc8cd9a500 R15: 00007f996f51e000
</TASK>
Allocated by task 408:
kasan_save_stack+0x20/0x40
kasan_save_track+0x14/0x30
__kasan_slab_alloc+0x6e/0x70
kmem_cache_alloc_noprof+0x117/0x3d0
mempool_alloc_noprof+0xf2/0x2c0
cifs_buf_get+0x36/0x80 [cifs]
allocate_buffers+0x1d2/0x330 [cifs]
cifs_demultiplex_thread+0x22b/0x2690 [cifs]
kthread+0x394/0x720
ret_from_fork+0x34/0x70
ret_from_fork_asm+0x1a/0x30
Freed by task 342979:
kasan_save_stack+0x20/0x40
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x37/0x50
kmem_cache_free+0x2b8/0x500
cifs_buf_release+0x3c/0x70 [cifs]
cifs_readdir+0x1c97/0x3190 [cifs]
iterate_dir+0x1a1/0x520
__x64_sys_getdents64+0x134/0x220
do_syscall_64+0x4b/0x110
entry_SYSCALL_64_after_hwframe+0x76/0x7e
The buggy address belongs to the object at ffff8880099b8000
which belongs to the cache cifs_request of size 16588
The buggy address is located 412 bytes inside of
freed 16588-byte region [ffff8880099b8000, ffff8880099bc0cc)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x99b8
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
anon flags: 0x80000000000040(head|node=0|zone=1)
page_type: f5(slab)
raw: 0080000000000040 ffff888001e03400 0000000000000000 dead000000000001
raw: 0000000000000000 0000000000010001 00000000f5000000 0000000000000000
head: 0080000000000040 ffff888001e03400 0000000000000000 dead000000000001
head: 0000000000000000 0000000000010001 00000000f5000000 0000000000000000
head: 0080000000000003 ffffea0000266e01 00000000ffffffff 00000000ffffffff
head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8880099b8080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8880099b8100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff8880099b8180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff8880099b8200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8880099b8280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================POC is available in the link [1].
The problem triggering process is as follows:
Process 1 Process 2
-----------------------------------------------------------------cifs_readdir
/* file->private_data == NULL */
initiate_cifs_search
cifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
smb2_query_dir_first ->query_dir_first()
SMB2_query_directory
SMB2_query_directory_init
cifs_send_recv
smb2_parse_query_directory
srch_inf->ntwrk_buf_start = (char *)rsp;
srch_inf->srch_entries_start = (char *)rsp + ...
srch_inf->last_entry = (char *)rsp + ...
srch_inf->smallBuf = true;
find_cifs_entry
/* if (cfile->srch_inf.ntwrk_buf_start) */
cifs_small_buf_release(cfile->srch_inf // free
cifs_readdir ->iterate_shared()
/* file->private_data != NULL */
find_cifs_entry
/* in while (...) loop */
smb2_query_dir_next ->query_dir_next()
SMB2_query_directory
SMB2_query_directory_init
cifs_send_recv
compound_send_recv
smb_send_rqst
__smb_send_rqst
rc = -ERESTARTSYS;
/* if (fatal_signal_pending()) */
goto out;
return rc
/* if (cfile->srch_inf.last_entry) */
cifs_save_resume_key()
cifs_fill_dirent // UAF
/* if (rc) */
return -ENOENT;Fix this by ensuring the return code is checked before using pointers from the srch_inf.
--- fs/smb/client/readdir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/smb/client/readdir.c +2 -2
@@ -756,11 +756,11 @@ find_cifs_entry(const unsigned int xid, rc = server->ops->query_dir_next (xid, tcon, &cfile->fid, search_flags, &cfile->srch_inf); +if (rc) +return -ENOENT ;/* FindFirst/Next set last_entry to NULL on malformed reply */ if (cfile->srch_inf.last_entry)cifs_save_resume_key (cfile->srch_inf.last_entry, cfile); -if (rc) -return -ENOENT ; }if (index_to_find < cfile->srch_inf.index_of_last_entry) {/* we found the buffer that contains the entry */
Greg Kroah-Hartman
maintainerPATCH 372/444 arm64: dts: marvell: uDPU: define pinctrl state for alarm LEDs
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabor Juhos <[email protected]>
commit b04f0d89e880bc2cca6a5c73cf287082c91878da upstream.
The two alarm LEDs of on the uDPU board are stopped working since commit 78efa53e715e ("leds: Init leds class earlier").
The LEDs are driven by the GPIO{15,16} pins of the North Bridge GPIO controller. These pins are part of the 'spi_quad' pin group for which the 'spi' function is selected via the default pinctrl state of the 'spi' node. This is wrong however, since in order to allow controlling the LEDs, the pins should use the 'gpio' function.
Before the commit mentined above, the 'spi' function is selected first by the pinctrl core before probing the spi driver, but then it gets overridden to 'gpio' implicitly via the devm_gpiod_get_index_optional() call from the 'leds-gpio' driver.
After the commit, the LED subsystem gets initialized before the SPI subsystem, so the function of the pin group remains 'spi' which in turn prevents controlling of the LEDs.
Despite the change of the initialization order, the root cause is that the pinctrl state definition is wrong since its initial commit 0d45062cfc89 ("arm64: dts: marvell: Add device tree for uDPU board"),
To fix the problem, override the function in the 'spi_quad_pins' node to 'gpio' and move the pinctrl state definition from the 'spi' node into the 'leds' node.
--- arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi +6 -2
@@ -26,6 +26,8 @@ leds { compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&spi_quad_pins>; led-power1 { label = "udpu:green:power";
@@ -82,8 +84,6 @@ &spi0 { status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&spi_quad_pins>; flash@0 { compatible = "jedec,spi-nor";
@@ -108,6 +108,10 @@ }; }; +&spi_quad_pins { + function = "gpio"; +}; + &pinctrl_nb { i2c2_recovery_pins: i2c2-recovery-pins { groups = "i2c2";
Greg Kroah-Hartman
maintainerPATCH 373/444 smb: client: Reset all search buffer pointers when releasing buffer
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Zhaolong <[email protected]>
commit e48f9d849bfdec276eebf782a84fd4dfbe1c14c0 upstream.
Multiple pointers in struct cifs_search_info (ntwrk_buf_start, srch_entries_start, and last_entry) point to the same allocated buffer. However, when freeing this buffer, only ntwrk_buf_start was set to NULL, while the other pointers remained pointing to freed memory.
This is defensive programming to prevent potential issues with stale pointers. While the active UAF vulnerability is fixed by the previous patch, this change ensures consistent pointer state and more robust error handling.
--- fs/smb/client/readdir.c | 3 +++ 1 file changed, 3 insertions(+)
fs/smb/client/readdir.c +3 -0
@@ -733,7 +733,10 @@ find_cifs_entry(const unsigned int xid,else cifs_buf_release (cfile->srch_inf. ntwrk_buf_start); +/* Reset all pointers to the network buffer to prevent stale references */ cfile->srch_inf.ntwrk_buf_start =NULL ; + cfile->srch_inf.srch_entries_start =NULL ; + cfile->srch_inf.last_entry =NULL ; } rc =initiate_cifs_search (xid, file, full_path);if (rc) {
Greg Kroah-Hartman
maintainerPATCH 374/444 Revert "drm/amd: Keep display off while going into S4"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 7e7cb7a13c81073d38a10fa7b450d23712281ec4 upstream.
commit 68bfdc8dc0a1a ("drm/amd: Keep display off while going into S4") attempted to keep displays off during the S4 sequence by not resuming display IP. This however leads to hangs because DRM clients such as the console can try to access registers and cause a hang.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 ----- 1 file changed, 5 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +0 -5
@@ -2896,11 +2896,6 @@ static int dm_resume(void *handle)return 0 ; } - -/* leave display off for S4 sequence */ -if (adev->in_s4) -return 0 ; -/* Recreate dc_state - DC invalidates it when setting power state to S3. */ dc_release_state (dm_state->context); dm_state->context =dc_create_state (dm->dc);
Greg Kroah-Hartman
maintainerPATCH 375/444 Input: xpad - add more controllers
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vicki Pfau <[email protected]>
commit f0d17942ea3edec191f1c0fc0d2cd7feca8de2f0 upstream.
Adds support for a revision of the Turtle Beach Recon Wired Controller, the Turtle Beach Stealth Ultra, and the PowerA Wired Controller.
--- drivers/input/joystick/xpad.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/input/joystick/xpad.c +3 -0
@@ -289,6 +289,8 @@ static const struct xpad_device { { 0x1038, 0x1430, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 }, { 0x1038, 0x1431, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 }, { 0x10f5, 0x7005, "Turtle Beach Recon Controller", 0, XTYPE_XBOXONE }, + { 0x10f5, 0x7008, "Turtle Beach Recon Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE }, + { 0x10f5, 0x7073, "Turtle Beach Stealth Ultra Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE }, { 0x11c9, 0x55f0, "Nacon GC-100XF", 0, XTYPE_XBOX360 }, { 0x11ff, 0x0511, "PXN V900", 0, XTYPE_XBOX360 }, { 0x1209, 0x2882, "Ardwiino Controller", 0, XTYPE_XBOX360 },
@@ -353,6 +355,7 @@ static const struct xpad_device { { 0x1ee9, 0x1590, "ZOTAC Gaming Zone", 0, XTYPE_XBOX360 }, { 0x20d6, 0x2001, "BDA Xbox Series X Wired Controller", 0, XTYPE_XBOXONE }, { 0x20d6, 0x2009, "PowerA Enhanced Wired Controller for Xbox Series X|S", 0, XTYPE_XBOXONE }, + { 0x20d6, 0x2064, "PowerA Wired Controller for Xbox", MAP_SHARE_BUTTON, XTYPE_XBOXONE }, { 0x20d6, 0x281f, "PowerA Wired Controller For Xbox 360", 0, XTYPE_XBOX360 }, { 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 },
Greg Kroah-Hartman
maintainerPATCH 376/444 memcg: always call cond_resched() after fn()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
commit 06717a7b6c86514dbd6ab322e8083ffaa4db5712 upstream.
I am seeing soft lockup on certain machine types when a cgroup OOMs. This is happening because killing the process in certain machine might be very slow, which causes the soft lockup and RCU stalls. This happens usually when the cgroup has MANY processes and memory.oom.group is set.
Example I am seeing in real production:
[462012.244552] Memory cgroup out of memory: Killed process 3370438 (crosvm) ....
....
[462037.318059] Memory cgroup out of memory: Killed process 4171372 (adb) ....
[462037.348314] watchdog: BUG: soft lockup - CPU#64 stuck for 26s! [stat_manager-ag:1618982]
....Quick look at why this is so slow, it seems to be related to serial flush for certain machine types. For all the crashes I saw, the target CPU was at console_flush_all().
In the case above, there are thousands of processes in the cgroup, and it is soft locking up before it reaches the 1024 limit in the code (which would call the cond_resched()). So, cond_resched() in 1024 blocks is not sufficient.
Remove the counter-based conditional rescheduling logic and call cond_resched() unconditionally after each task iteration, after fn() is called. This avoids the lockup independently of how slow fn() is.
--- mm/memcontrol.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
mm/memcontrol.c +2 -4
@@ -1266,7 +1266,6 @@ void mem_cgroup_scan_tasks(struct mem_cg {struct mem_cgroup *iter;int ret =0 ; -int i =0 ;BUG_ON (mem_cgroup_is_root (memcg));
@@ -1276,10 +1275,9 @@ void mem_cgroup_scan_tasks(struct mem_cgcss_task_iter_start (&iter->css,CSS_TASK_ITER_PROCS , &it);while (!ret && (task =css_task_iter_next (&it))) { -/* Avoid potential softlockup warning */ -if ((++i &1023 ) ==0 ) -cond_resched (); ret =fn (task, arg); +/* Avoid potential softlockup warning */ +cond_resched (); }css_task_iter_end (&it);if (ret) {
Greg Kroah-Hartman
maintainerPATCH 377/444 mm/page_alloc.c: avoid infinite retries caused by cpuset race
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianyang Zhang <[email protected]>
commit e05741fb10c38d70bbd7ec12b23c197b6355d519 upstream.
__alloc_pages_slowpath has no change detection for ac->nodemask in the part of retry path, while cpuset can modify it in parallel. For some processes that set mempolicy as MPOL_BIND, this results ac->nodemask changes, and then the should_reclaim_retry will judge based on the latest nodemask and jump to retry, while the get_page_from_freelist only traverses the zonelist from ac->preferred_zoneref, which selected by a expired nodemask and may cause infinite retries in some cases
cpu 64:
__alloc_pages_slowpath {
/* ..... */
retry:
/* ac->nodemask = 0x1, ac->preferred->zone->nid = 1 */
if (alloc_flags & ALLOC_KSWAPD)
wake_all_kswapds(order, gfp_mask, ac);
/* cpu 1:
cpuset_write_resmask
update_nodemask
update_nodemasks_hier
update_tasks_nodemask
mpol_rebind_task
mpol_rebind_policy
mpol_rebind_nodemask
// mempolicy->nodes has been modified,
// which ac->nodemask point to
*/
/* ac->nodemask = 0x3, ac->preferred->zone->nid = 1 */
if (should_reclaim_retry(gfp_mask, order, ac, alloc_flags,
did_some_progress > 0, &no_progress_loops))
goto retry;
}Simultaneously starting multiple cpuset01 from LTP can quickly reproduce this issue on a multi node server when the maximum memory pressure is reached and the swap is enabled
--- mm/page_alloc.c | 8 ++++++++ 1 file changed, 8 insertions(+)
mm/page_alloc.c +8 -0
@@ -4038,6 +4038,14 @@ restart: } retry: +/* +* Deal with possible cpuset update races or zonelist updates to avoid +* infinite retries. +*/ +if (check_retry_cpuset (cpuset_mems_cookie, ac) || +check_retry_zonelist (zonelist_iter_cookie)) + goto restart; +/* Ensure kswapd doesn't accidentally go to sleep as long as we loop */ if (alloc_flags &ALLOC_KSWAPD )wake_all_kswapds (order, gfp_mask, ac);
Greg Kroah-Hartman
maintainerPATCH 378/444 Revert "arm64: dts: allwinner: h6: Use RSB for AXP805 PMIC connection"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jernej Skrabec <[email protected]>
[ Upstream commit 573f99c7585f597630f14596550c79e73ffaeef4 ]
This reverts commit 531fdbeedeb89bd32018a35c6e137765c9cc9e97.
Hardware that uses I2C wasn't designed with high speeds in mind, so communication with PMIC via RSB can intermittently fail. Go back to I2C as higher speed and efficiency isn't worth the trouble.
--- .../dts/allwinner/sun50i-h6-beelink-gs1.dts | 38 +++++++++---------- .../dts/allwinner/sun50i-h6-orangepi-3.dts | 14 +++---- .../dts/allwinner/sun50i-h6-orangepi.dtsi | 22 +++++------ 3 files changed, 37 insertions(+), 37 deletions(-)
arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts +19 -19
@@ -151,28 +151,12 @@ vcc-pg-supply = <®_aldo1>; }; -&r_ir { - linux,rc-map-name = "rc-beelink-gs1"; - status = "okay"; -}; - -&r_pio { - /* - * FIXME: We can't add that supply for now since it would - * create a circular dependency between pinctrl, the regulator - * and the RSB Bus. - * - * vcc-pl-supply = <®_aldo1>; - */ - vcc-pm-supply = <®_aldo1>; -}; - -&r_rsb { +&r_i2c { status = "okay"; - axp805: pmic@745 { + axp805: pmic@36 { compatible = "x-powers,axp805", "x-powers,axp806"; - reg = <0x745>; + reg = <0x36>; interrupt-parent = <&r_intc>; interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>; interrupt-controller;
@@ -290,6 +274,22 @@ }; }; +&r_ir { + linux,rc-map-name = "rc-beelink-gs1"; + status = "okay"; +}; + +&r_pio { + /* + * PL0 and PL1 are used for PMIC I2C + * don't enable the pl-supply else + * it will fail at boot + * + * vcc-pl-supply = <®_aldo1>; + */ + vcc-pm-supply = <®_aldo1>; +}; + &spdif { pinctrl-names = "default"; pinctrl-0 = <&spdif_tx_pin>;
arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +7 -7
@@ -175,16 +175,12 @@ vcc-pg-supply = <®_vcc_wifi_io>; }; -&r_ir { - status = "okay"; -}; - -&r_rsb { +&r_i2c { status = "okay"; - axp805: pmic@745 { + axp805: pmic@36 { compatible = "x-powers,axp805", "x-powers,axp806"; - reg = <0x745>; + reg = <0x36>; interrupt-parent = <&r_intc>; interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>; interrupt-controller;
@@ -295,6 +291,10 @@ }; }; +&r_ir { + status = "okay"; +}; + &rtc { clocks = <&ext_osc32k>; };
arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi +11 -11
@@ -112,20 +112,12 @@ vcc-pg-supply = <®_aldo1>; }; -&r_ir { - status = "okay"; -}; - -&r_pio { - vcc-pm-supply = <®_bldo3>; -}; - -&r_rsb { +&r_i2c { status = "okay"; - axp805: pmic@745 { + axp805: pmic@36 { compatible = "x-powers,axp805", "x-powers,axp806"; - reg = <0x745>; + reg = <0x36>; interrupt-parent = <&r_intc>; interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>; interrupt-controller;
@@ -240,6 +232,14 @@ }; }; +&r_ir { + status = "okay"; +}; + +&r_pio { + vcc-pm-supply = <®_bldo3>; +}; + &rtc { clocks = <&ext_osc32k>; };
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 379/444 ksmbd: fix stream write failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit 1f4bbedd4e5a69b01cde2cc21d01151ab2d0884f ]
If there is no stream data in file, v_len is zero. So, If position(*pos) is zero, stream write will fail due to stream write position validation check. This patch reorganize stream write position validation.
--- fs/smb/server/vfs.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
fs/smb/server/vfs.c +6 -8
@@ -426,10 +426,15 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,ksmbd_debug (VFS ,"write stream data pos : %llu, count : %zd\n" , *pos, count); +if (*pos >=XATTR_SIZE_MAX ) { +pr_err ("stream write position %lld is out of bounds\n" , *pos); +return -EINVAL ; + } + size = *pos + count;if (size >XATTR_SIZE_MAX ) { size =XATTR_SIZE_MAX ; - count = (*pos + count) -XATTR_SIZE_MAX ; + count =XATTR_SIZE_MAX - *pos; } v_len = ksmbd_vfs_getcasexattr(idmap,
@@ -443,13 +448,6 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, goto out; } -if (v_len <= *pos) { -pr_err ("stream write position %lld is out of bounds (stream length: %zd)\n" , - *pos, v_len); - err = -EINVAL ; - goto out; - } -if (v_len < size) { wbuf =kvzalloc (size,GFP_KERNEL );if (!wbuf) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 380/444 spi: spi-fsl-dspi: restrict register range for regmap access
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Larisa Grigore <[email protected]>
[ Upstream commit 283ae0c65e9c592f4a1ba4f31917f5e766da7f31 ]
DSPI registers are NOT continuous, some registers are reserved and accessing them from userspace will trigger external abort, add regmap register access table to avoid below abort.
For example on S32G:
# cat /sys/kernel/debug/regmap/401d8000.spi/registers
Internal error: synchronous external abort: 96000210 1 PREEMPT SMP ... Call trace: regmap_mmio_read32le+0x24/0x48 regmap_mmio_read+0x48/0x70 _regmap_bus_reg_read+0x38/0x48 _regmap_read+0x68/0x1b0 regmap_read+0x50/0x78 regmap_read_debugfs+0x120/0x338
--- drivers/spi/spi-fsl-dspi.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
drivers/spi/spi-fsl-dspi.c +19 -1
@@ -1,7 +1,7 @@// SPDX-License-Identifier: GPL-2.0+ // // Copyright 2013 Freescale Semiconductor, Inc. -// Copyright 2020 NXP +// Copyright 2020-2025 NXP // // Freescale DSPI driver // This file contains a driver for the Freescale DSPI
@@ -1163,6 +1163,20 @@ static int dspi_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume); +static const struct regmap_range dspi_yes_ranges[] = { +regmap_reg_range (SPI_MCR ,SPI_MCR ), +regmap_reg_range (SPI_TCR ,SPI_CTAR (3 )), +regmap_reg_range (SPI_SR ,SPI_TXFR3 ), +regmap_reg_range (SPI_RXFR0 ,SPI_RXFR3 ), +regmap_reg_range (SPI_CTARE (0 ),SPI_CTARE (3 )), +regmap_reg_range (SPI_SREX ,SPI_SREX ), +}; + +static const struct regmap_access_table dspi_access_table = { + .yes_ranges = dspi_yes_ranges, + .n_yes_ranges =ARRAY_SIZE (dspi_yes_ranges), +}; +static const struct regmap_range dspi_volatile_ranges[] = {regmap_reg_range (SPI_MCR ,SPI_TCR ),regmap_reg_range (SPI_SR ,SPI_SR ),
@@ -1180,6 +1194,8 @@ static const struct regmap_config dspi_regmap_config = { .reg_stride = 4, .max_register = 0x88, .volatile_table = &dspi_volatile_table, + .rd_table = &dspi_access_table, + .wr_table = &dspi_access_table, };static const struct regmap_range dspi_xspi_volatile_ranges[] = {
@@ -1201,6 +1217,8 @@ static const struct regmap_config dspi_xspi_regmap_config[] = { .reg_stride = 4, .max_register = 0x13c, .volatile_table = &dspi_xspi_volatile_table, + .rd_table = &dspi_access_table, + .wr_table = &dspi_access_table, }, { .name = "pushr",
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 381/444 spi: spi-fsl-dspi: Halt the module after a new message transfer
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bogdan-Gabriel Roman <[email protected]>
[ Upstream commit 8a30a6d35a11ff5ccdede7d6740765685385a917 ]
The XSPI mode implementation in this driver still uses the EOQ flag to signal the last word in a transmission and deassert the PCS signal. However, at speeds lower than ~200kHZ, the PCS signal seems to remain asserted even when SR[EOQF] = 1 indicates the end of a transmission. This is a problem for target devices which require the deassertation of the PCS signal between transfers.
Hence, this commit 'forces' the deassertation of the PCS by stopping the module through MCR[HALT] after completing a new transfer. According to the reference manual, the module stops or transitions from the Running state to the Stopped state after the current frame, when any one of the following conditions exist:
- The value of SR[EOQF] = 1.
- The chip is in Debug mode and the value of MCR[FRZ] = 1.
- The value of MCR[HALT] = 1.
This shouldn't be done if the last transfer in the message has cs_change set.
--- drivers/spi/spi-fsl-dspi.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
drivers/spi/spi-fsl-dspi.c +24 -0
@@ -62,6 +62,7 @@#define SPI_SR_TFIWF BIT(18)#define SPI_SR_RFDF BIT(17)#define SPI_SR_CMDFFF BIT(16) +#define SPI_SR_TXRXS BIT(30)#define SPI_SR_CLEAR (SPI_SR_TCFQF | \ SPI_SR_TFUF | SPI_SR_TFFF | \ SPI_SR_CMDTCF | SPI_SR_SPEF | \
@@ -926,9 +927,20 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,struct spi_transfer *transfer;bool cs = false;int status =0 ; +u32 val =0 ; +bool cs_change = false; message->actual_length =0 ; +/* Put DSPI in running mode if halted. */ +regmap_read (dspi->regmap,SPI_MCR , &val); +if (val &SPI_MCR_HALT ) { +regmap_update_bits (dspi->regmap,SPI_MCR ,SPI_MCR_HALT ,0 ); +while (regmap_read (dspi->regmap,SPI_SR , &val) >=0 && + !(val &SPI_SR_TXRXS )) + ; + } +list_for_each_entry (transfer, &message->transfers, transfer_list) { dspi->cur_transfer = transfer; dspi->cur_msg = message;
@@ -958,6 +970,7 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr, dspi->tx_cmd |=SPI_PUSHR_CMD_CONT ; } + cs_change = transfer->cs_change; dspi->tx = transfer->tx_buf; dspi->rx = transfer->rx_buf; dspi->len = transfer->len;
@@ -993,6 +1006,15 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,dspi_deassert_cs (spi, &cs); } +if (status || !cs_change) { +/* Put DSPI in stop mode */ +regmap_update_bits (dspi->regmap,SPI_MCR , +SPI_MCR_HALT ,SPI_MCR_HALT ); +while (regmap_read (dspi->regmap,SPI_SR , &val) >=0 && + val &SPI_SR_TXRXS ) + ; + } + message->status = status;spi_finalize_current_message (ctlr);
@@ -1241,6 +1263,8 @@ static int dspi_init(struct fsl_dspi *dspi)if (!spi_controller_is_target (dspi->ctlr)) mcr |=SPI_MCR_HOST ; + mcr |=SPI_MCR_HALT ; +regmap_write (dspi->regmap,SPI_MCR , mcr);regmap_write (dspi->regmap,SPI_SR ,SPI_SR_CLEAR );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 382/444 spi: spi-fsl-dspi: Reset SR flags before sending a new message
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Larisa Grigore <[email protected]>
[ Upstream commit 7aba292eb15389073c7f3bd7847e3862dfdf604d ]
If, in a previous transfer, the controller sends more data than expected by the DSPI target, SR.RFDF (RX FIFO is not empty) will remain asserted. When flushing the FIFOs at the beginning of a new transfer (writing 1 into MCR.CLR_TXF and MCR.CLR_RXF), SR.RFDF should also be cleared. Otherwise, when running in target mode with DMA, if SR.RFDF remains asserted, the DMA callback will be fired before the controller sends any data.
Take this opportunity to reset all Status Register fields.
--- drivers/spi/spi-fsl-dspi.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/spi/spi-fsl-dspi.c +2 -0
@@ -980,6 +980,8 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,SPI_MCR_CLR_TXF |SPI_MCR_CLR_RXF , SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); +regmap_write (dspi->regmap,SPI_SR ,SPI_SR_CLEAR ); +spi_take_timestamp_pre (dspi->ctlr, dspi->cur_transfer, dspi->progress, !dspi->irq);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 383/444 x86/boot: Compile boot code with -std=gnu11 too
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Dobriyan <[email protected]>
commit b3bee1e7c3f2b1b77182302c7b2131c804175870 upstream.
Use -std=gnu11 for consistency with main kernel code.
It doesn't seem to change anything in vmlinux.
--- arch/x86/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/Makefile +1 -1
@@ -43,7 +43,7 @@ endif # How to compile the 16-bit code. Note we always compile for -march=i386; # that way we can complain to the user if the CPU is insufficient. -REALMODE_CFLAGS := -m16 -g -Os -DDISABLE_BRANCH_PROFILING -D__DISABLE_EXPORTS \ +REALMODE_CFLAGS := -std=gnu11 -m16 -g -Os -DDISABLE_BRANCH_PROFILING -D__DISABLE_EXPORTS \ -Wall -Wstrict-prototypes -march=i386 -mregparm=3 \ -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ -mno-mmx -mno-sse $(call cc-option,-fcf-protection=none)
Greg Kroah-Hartman
maintainerPATCH 384/444 highmem: add folio_test_partial_kmap()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Wilcox (Oracle) <[email protected]>
commit 97dfbbd135cb5e4426f37ca53a8fa87eaaa4e376 upstream.
In commit c749d9b7ebbc ("iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP"), Hugh correctly noted that if KMAP_LOCAL_FORCE_MAP is enabled, we must limit ourselves to PAGE_SIZE bytes per call to kmap_local(). The same problem exists in memcpy_from_folio(), memcpy_to_folio(), folio_zero_tail(), folio_fill_tail() and memcpy_from_file_folio(), so add folio_test_partial_kmap() to do this more succinctly.
--- include/linux/highmem.h | 6 +++--- include/linux/page-flags.h | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-)
include/linux/highmem.h +3 -3
@@ -448,7 +448,7 @@ static inline void memcpy_from_folio(chaconst char *from =kmap_local_folio (folio, offset);size_t chunk = len; -if (folio_test_highmem (folio) && +if (folio_test_partial_kmap (folio) && chunk >PAGE_SIZE -offset_in_page (offset)) chunk =PAGE_SIZE -offset_in_page (offset);memcpy (to, from, chunk);
@@ -469,7 +469,7 @@ static inline void memcpy_to_folio(strucchar *to =kmap_local_folio (folio, offset);size_t chunk = len; -if (folio_test_highmem (folio) && +if (folio_test_partial_kmap (folio) && chunk >PAGE_SIZE -offset_in_page (offset)) chunk =PAGE_SIZE -offset_in_page (offset);memcpy (to, from, chunk);
@@ -501,7 +501,7 @@ static inline size_t memcpy_from_file_fosize_t offset =offset_in_folio (folio, pos);char *from =kmap_local_folio (folio, offset); -if (folio_test_highmem (folio)) { +if (folio_test_partial_kmap (folio)) { offset =offset_in_page (offset); len =min_t (size_t, len,PAGE_SIZE - offset); }else
include/linux/page-flags.h +7 -0
@@ -551,6 +551,13 @@ PAGEFLAG(Readahead, readahead, PF_NO_COM PAGEFLAG_FALSE(HighMem, highmem)#endif +/* Does kmap_local_folio() only allow access to one page of the folio? */ +#ifdef CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP +#define folio_test_partial_kmap (f) true +#else +#define folio_test_partial_kmap (f) folio_test_highmem(f) +#endif +#ifdef CONFIG_SWAP static __always_inline bool folio_test_swapcache(struct folio *folio) {
Greg Kroah-Hartman
maintainerPATCH 385/444 pds_core: Prevent possible adminq overflow/stuck condition
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brett Creeley <[email protected]>
commit d9e2f070d8af60f2c8c02b2ddf0a9e90b4e9220c upstream.
The pds_core's adminq is protected by the adminq_lock, which prevents more than 1 command to be posted onto it at any one time. This makes it so the client drivers cannot simultaneously post adminq commands. However, the completions happen in a different context, which means multiple adminq commands can be posted sequentially and all waiting on completion.
On the FW side, the backing adminq request queue is only 16 entries long and the retry mechanism and/or overflow/stuck prevention is lacking. This can cause the adminq to get stuck, so commands are no longer processed and completions are no longer sent by the FW.
As an initial fix, prevent more than 16 outstanding adminq commands so there's no way to cause the adminq from getting stuck. This works because the backing adminq request queue will never have more than 16 pending adminq commands, so it will never overflow. This is done by reducing the adminq depth to 16.
--- drivers/net/ethernet/amd/pds_core/core.c | 5 +---- drivers/net/ethernet/amd/pds_core/core.h | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-)
drivers/net/ethernet/amd/pds_core/core.c +1 -4
@@ -413,10 +413,7 @@ int pdsc_setup(struct pdsc *pdsc, bool iif (err)return err; -/* Scale the descriptor ring length based on number of CPUs and VFs */ - numdescs =max_t (int,PDSC_ADMINQ_MIN_LENGTH ,num_online_cpus ()); - numdescs +=2 *pci_sriov_get_totalvfs (pdsc->pdev); - numdescs =roundup_pow_of_two (numdescs); + numdescs =PDSC_ADMINQ_MAX_LENGTH ; err = pdsc_qcq_alloc(pdsc, PDS_CORE_QTYPE_ADMINQ, 0, "adminq", PDS_CORE_QCQ_F_CORE | PDS_CORE_QCQ_F_INTR, numdescs,
drivers/net/ethernet/amd/pds_core/core.h +1 -1
@@ -16,7 +16,7 @@#define PDSC_WATCHDOG_SECS 5#define PDSC_QUEUE_NAME_MAX_SZ 16 -#define PDSC_ADMINQ_MIN_LENGTH 16/* must be a power of two */ +#define PDSC_ADMINQ_MAX_LENGTH 16/* must be a power of two */ #define PDSC_NOTIFYQ_LENGTH 64/* must be a power of two */ #define PDSC_TEARDOWN_RECOVERY false#define PDSC_TEARDOWN_REMOVING true
Greg Kroah-Hartman
maintainerPATCH 386/444 serial: sh-sci: Save and restore more registers
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven <[email protected]>
commit 81100b9a7b0515132996d62a7a676a77676cb6e3 upstream.
On (H)SCIF with a Baud Rate Generator for External Clock (BRG), there are multiple ways to configure the requested serial speed. If firmware uses a different method than Linux, and if any debug info is printed after the Bit Rate Register (SCBRR) is restored, but before termios is reconfigured (which configures the alternative method), the system may lock-up during resume.
Fix this by saving and restoring the contents of the BRG Frequency Division (SCDL) and Clock Select (SCCKS) registers as well.
Also save and restore the HSCIF's Sampling Rate Register (HSSRR), which configures the sampling point, and the SCIFA/SCIFB's Serial Port Control and Data Registers (SCPCR/SCPDR), which configure the optional control flow signals.
After this, all registers that are not saved/restored are either:
- read-only,
- write-only,
- status registers containing flags with clear-after-set semantics,
- FIFO Data Count Trigger registers, which do not matter much for the serial console.
--- drivers/tty/serial/sh-sci.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
drivers/tty/serial/sh-sci.c +25 -0
@@ -105,10 +105,15 @@ struct plat_sci_reg { };struct sci_suspend_regs { +u16 scdl; +u16 sccks;u16 scsmr;u16 scscr;u16 scfcr;u16 scsptr; +u16 hssrr; +u16 scpcr; +u16 scpdr;u8 scbrr;u8 semr; };
@@ -3491,6 +3496,10 @@ static void sci_console_save(struct sci_struct sci_suspend_regs *regs = &s->suspend_regs;struct uart_port *port = &s->port; +if (sci_getreg (port,SCDL )->size) + regs->scdl =sci_serial_in (port,SCDL ); +if (sci_getreg (port,SCCKS )->size) + regs->sccks =sci_serial_in (port,SCCKS );if (sci_getreg (port,SCSMR )->size) regs->scsmr =sci_serial_in (port,SCSMR );if (sci_getreg (port,SCSCR )->size)
@@ -3501,6 +3510,12 @@ static void sci_console_save(struct sci_ regs->scsptr =sci_serial_in (port,SCSPTR );if (sci_getreg (port,SCBRR )->size) regs->scbrr =sci_serial_in (port,SCBRR ); +if (sci_getreg (port,HSSRR )->size) + regs->hssrr =sci_serial_in (port,HSSRR ); +if (sci_getreg (port,SCPCR )->size) + regs->scpcr =sci_serial_in (port,SCPCR ); +if (sci_getreg (port,SCPDR )->size) + regs->scpdr =sci_serial_in (port,SCPDR );if (sci_getreg (port,SEMR )->size) regs->semr =sci_serial_in (port,SEMR ); }
@@ -3510,6 +3525,10 @@ static void sci_console_restore(struct sstruct sci_suspend_regs *regs = &s->suspend_regs;struct uart_port *port = &s->port; +if (sci_getreg (port,SCDL )->size) +sci_serial_out (port,SCDL , regs->scdl); +if (sci_getreg (port,SCCKS )->size) +sci_serial_out (port,SCCKS , regs->sccks);if (sci_getreg (port,SCSMR )->size)sci_serial_out (port,SCSMR , regs->scsmr);if (sci_getreg (port,SCSCR )->size)
@@ -3520,6 +3539,12 @@ static void sci_console_restore(struct ssci_serial_out (port,SCSPTR , regs->scsptr);if (sci_getreg (port,SCBRR )->size)sci_serial_out (port,SCBRR , regs->scbrr); +if (sci_getreg (port,HSSRR )->size) +sci_serial_out (port,HSSRR , regs->hssrr); +if (sci_getreg (port,SCPCR )->size) +sci_serial_out (port,SCPCR , regs->scpcr); +if (sci_getreg (port,SCPDR )->size) +sci_serial_out (port,SCPDR , regs->scpdr);if (sci_getreg (port,SEMR )->size)sci_serial_out (port,SEMR , regs->semr); }
Greg Kroah-Hartman
maintainerPATCH 387/444 watchdog: aspeed: fix 64-bit division
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit 48a136639ec233614a61653e19f559977d5da2b5 upstream.
On 32-bit architectures, the new calculation causes a build failure:
ld.lld-21: error: undefined symbol: __aeabi_uldivmod
Since neither value is ever larger than a register, cast both sides into a uintptr_t.
--- drivers/watchdog/aspeed_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/watchdog/aspeed_wdt.c +1 -1
@@ -252,7 +252,7 @@ static void aspeed_wdt_update_bootstatusif (!of_device_is_compatible (pdev->dev.of_node,"aspeed,ast2400-wdt" )) { res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); - idx = ((intptr_t )wdt->base &0x00000fff ) /resource_size (res); + idx = ((intptr_t )wdt->base &0x00000fff ) / (uintptr_t )resource_size (res); } scu_base =syscon_regmap_lookup_by_compatible (scu.compatible);
Greg Kroah-Hartman
maintainerPATCH 388/444 pinctrl: tegra: Fix off by one in tegra_pinctrl_get_group()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit 5a062c3c3b82004766bc3ece82b594d337076152 upstream.
This should be >= pmx->soc->ngroups instead of > to avoid an out of bounds access. The pmx->soc->groups[] array is allocated in tegra_pinctrl_probe().
--- drivers/pinctrl/tegra/pinctrl-tegra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pinctrl/tegra/pinctrl-tegra.c +1 -1
@@ -307,7 +307,7 @@ static const struct tegra_pingroup *tegr {struct tegra_pmx *pmx =pinctrl_dev_get_drvdata (pctldev); -if (group_index <0 || group_index > pmx->soc->ngroups) +if (group_index <0 || group_index >= pmx->soc->ngroups)return NULL ;return &pmx->soc->groups[group_index];
Greg Kroah-Hartman
maintainerPATCH 389/444 i3c: master: svc: Fix implicit fallthrough in svc_i3c_master_ibi_work()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
commit e8d2d287e26d9bd9114cf258a123a6b70812442e upstream.
Clang warns (or errors with CONFIG_WERROR=y):
drivers/i3c/master/svc-i3c-master.c:596:2: error: unannotated fall-through between switch labels [-Werror,-Wimplicit-fallthrough]
596 | default:
| ^
drivers/i3c/master/svc-i3c-master.c:596:2: note: insert 'break;' to avoid fall-through
596 | default:
| ^
| break;1 error generated.
Clang is a little more pedantic than GCC, which does not warn when falling through to a case that is just break or return. Clang's version is more in line with the kernel's own stance in deprecated.rst, which states that all switch/case blocks must end in either break, fallthrough, continue, goto, or return. Add the missing break to silence the warning.
--- drivers/i3c/master/svc-i3c-master.c | 1 + 1 file changed, 1 insertion(+)
drivers/i3c/master/svc-i3c-master.c +1 -0
@@ -504,6 +504,7 @@ static void svc_i3c_master_ibi_work(strubreak ;case SVC_I3C_MSTATUS_IBITYPE_MASTER_REQUEST :svc_i3c_master_emit_stop (master); +break ;default :break ; }
Greg Kroah-Hartman
maintainerPATCH 390/444 x86/mm/init: Handle the special case of device private pages in add_pages(), to not increase max_pfn and trigger dma_addressing_limited() bounce buffers bounce buffers
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Balbir Singh <[email protected]>
commit 7170130e4c72ce0caa0cb42a1627c635cc262821 upstream.
As Bert Karwatzki reported, the following recent commit causes a performance regression on AMD iGPU and dGPU systems:
7ffb791423c7 ("x86/kaslr: Reduce KASLR entropy on most x86 systems")
It exposed a bug with nokaslr and zone device interaction.
The root cause of the bug is that, the GPU driver registers a zone device private memory region. When KASLR is disabled or the above commit is applied, the direct_map_physmem_end is set to much higher than 10 TiB typically to the 64TiB address. When zone device private memory is added to the system via add_pages(), it bumps up the max_pfn to the same value. This causes dma_addressing_limited() to return true, since the device cannot address memory all the way up to max_pfn.
This caused a regression for games played on the iGPU, as it resulted in the DMA32 zone being used for GPU allocations.
Fix this by not bumping up max_pfn on x86 systems, when pgmap is passed into add_pages(). The presence of pgmap is used to determine if device private memory is being added via add_pages().
More details:
devm_request_mem_region() and request_free_mem_region() request for device private memory. iomem_resource is passed as the base resource with start and end parameters. iomem_resource's end depends on several factors, including the platform and virtualization. On x86 for example on bare metal, this value is set to boot_cpu_data.x86_phys_bits. boot_cpu_data.x86_phys_bits can change depending on support for MKTME. By default it is set to the same as log2(direct_map_physmem_end) which is 46 to 52 bits depending on the number of levels in the page table. The allocation routines used iomem_resource's end and direct_map_physmem_end to figure out where to allocate the region.
[ arch/powerpc is also impacted by this problem, but this patch does not fix
the issue for PowerPC. ]
Testing:
1. Tested on a virtual machine with test_hmm for zone device inseration
2. A previous version of this patch was tested by Bert, please see:
https://lore.kernel.org/lkml/[email protected]/
[ mingo: Clarified the comments and the changelog. ]
--- arch/x86/mm/init_64.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
arch/x86/mm/init_64.c +12 -3
@@ -959,9 +959,18 @@ int add_pages(int nid, unsigned long sta ret =__add_pages (nid, start_pfn, nr_pages, params);WARN_ON_ONCE (ret); -/* update max_pfn, max_low_pfn and high_memory */ -update_end_of_memory_vars (start_pfn <<PAGE_SHIFT , - nr_pages <<PAGE_SHIFT ); +/* +* Special case: add_pages() is called by memremap_pages() for adding device +* private pages. Do not bump up max_pfn in the device private path, +* because max_pfn changes affect dma_addressing_limited(). +* +* dma_addressing_limited() returning true when max_pfn is the device's +* addressable memory can force device drivers to use bounce buffers +* and impact their performance negatively: +*/ +if (!params->pgmap) +/* update max_pfn, max_low_pfn and high_memory */ +update_end_of_memory_vars (start_pfn <<PAGE_SHIFT , nr_pages <<PAGE_SHIFT );return ret; }
Greg Kroah-Hartman
maintainerPATCH 391/444 drm/gem: Internally test import_attach for imported objects
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann <[email protected]>
commit 8260731ccad0451207b45844bb66eb161a209218 upstream.
Test struct drm_gem_object.import_attach to detect imported objects.
During object clenanup, the dma_buf field might be NULL. Testing it in an object's free callback then incorrectly does a cleanup as for native objects. Happens for calls to drm_mode_destroy_dumb_ioctl() that clears the dma_buf field in drm_gem_object_exported_dma_buf_free().
v3:
- only test for import_attach (Boris)
v2:
- use import_attach.dmabuf instead of dma_buf (Christian)
--- include/drm/drm_gem.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
include/drm/drm_gem.h +1 -2
@@ -567,8 +567,7 @@ static inline bool drm_gem_object_is_sha*/ static inline bool drm_gem_is_imported (const struct drm_gem_object *obj) { -/* The dma-buf's priv field points to the original GEM object. */ -return obj->dma_buf && (obj->dma_buf->priv != obj); +return !!obj->import_attach; }#ifdef CONFIG_LOCKDEP
Greg Kroah-Hartman
maintainerPATCH 392/444 can: kvaser_pciefd: Force IRQ edge in case of nested IRQ
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Axel Forsman <[email protected]>
commit 9176bd205ee0b2cd35073a9973c2a0936bcb579e upstream.
Avoid the driver missing IRQs by temporarily masking IRQs in the ISR to enforce an edge even if a different IRQ is signalled before handled IRQs are cleared.
--- drivers/net/can/kvaser_pciefd.c | 80 ++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 43 deletions(-)
drivers/net/can/kvaser_pciefd.c +37 -43
@@ -1582,24 +1582,28 @@ static int kvaser_pciefd_read_buffer(strreturn res; } -static u32 kvaser_pciefd_receive_irq (struct kvaser_pciefd *pcie) +static void kvaser_pciefd_receive_irq (struct kvaser_pciefd *pcie) { +void __iomem *srb_cmd_reg =KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_CMD_REG ;u32 irq =ioread32 (KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_IRQ_REG ); -if (irq &KVASER_PCIEFD_SRB_IRQ_DPD0 ) +iowrite32 (irq,KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_IRQ_REG ); + +if (irq &KVASER_PCIEFD_SRB_IRQ_DPD0 ) {kvaser_pciefd_read_buffer (pcie,0 ); +iowrite32 (KVASER_PCIEFD_SRB_CMD_RDB0 , srb_cmd_reg);/* Rearm buffer */ + } -if (irq &KVASER_PCIEFD_SRB_IRQ_DPD1 ) +if (irq &KVASER_PCIEFD_SRB_IRQ_DPD1 ) {kvaser_pciefd_read_buffer (pcie,1 ); +iowrite32 (KVASER_PCIEFD_SRB_CMD_RDB1 , srb_cmd_reg);/* Rearm buffer */ + }if (irq &KVASER_PCIEFD_SRB_IRQ_DOF0 || irq &KVASER_PCIEFD_SRB_IRQ_DOF1 || irq &KVASER_PCIEFD_SRB_IRQ_DUF0 || irq &KVASER_PCIEFD_SRB_IRQ_DUF1 )dev_err (&pcie->pci->dev,"DMA IRQ error 0x%08X\n" , irq); - -iowrite32 (irq,KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_IRQ_REG ); -return irq; }static void kvaser_pciefd_transmit_irq (struct kvaser_pciefd_can *can)
@@ -1627,29 +1631,22 @@ static irqreturn_t kvaser_pciefd_irq_hanstruct kvaser_pciefd *pcie = (struct kvaser_pciefd *)dev;const struct kvaser_pciefd_irq_mask *irq_mask = pcie->driver_data->irq_mask;u32 pci_irq =ioread32 (KVASER_PCIEFD_PCI_IRQ_ADDR (pcie)); -u32 srb_irq =0 ; -u32 srb_release =0 ;int i;if (!(pci_irq & irq_mask->all))return IRQ_NONE ; +iowrite32 (0 ,KVASER_PCIEFD_PCI_IEN_ADDR (pcie)); +if (pci_irq & irq_mask->kcan_rx0) - srb_irq =kvaser_pciefd_receive_irq (pcie); +kvaser_pciefd_receive_irq (pcie);for (i =0 ; i < pcie->nr_channels; i++) {if (pci_irq & irq_mask->kcan_tx[i])kvaser_pciefd_transmit_irq (pcie->can[i]); } -if (srb_irq &KVASER_PCIEFD_SRB_IRQ_DPD0 ) - srb_release |=KVASER_PCIEFD_SRB_CMD_RDB0 ; - -if (srb_irq &KVASER_PCIEFD_SRB_IRQ_DPD1 ) - srb_release |=KVASER_PCIEFD_SRB_CMD_RDB1 ; - -if (srb_release) -iowrite32 (srb_release,KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_CMD_REG ); +iowrite32 (irq_mask->all,KVASER_PCIEFD_PCI_IEN_ADDR (pcie));return IRQ_HANDLED ; }
@@ -1669,13 +1666,22 @@ static void kvaser_pciefd_teardown_can_c } } +static void kvaser_pciefd_disable_irq_srcs (struct kvaser_pciefd *pcie) +{ +unsigned int i; + +/* Masking PCI_IRQ is insufficient as running ISR will unmask it */ +iowrite32 (0 ,KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_IEN_REG ); +for (i =0 ; i < pcie->nr_channels; ++i) +iowrite32 (0 , pcie->can[i]->reg_base +KVASER_PCIEFD_KCAN_IEN_REG ); +} +static int kvaser_pciefd_probe (struct pci_dev *pdev,const struct pci_device_id *id) {int err;struct kvaser_pciefd *pcie;const struct kvaser_pciefd_irq_mask *irq_mask; -void __iomem *irq_en_base; pcie =devm_kzalloc (&pdev->dev,sizeof (*pcie),GFP_KERNEL );if (!pcie)
@@ -1728,8 +1734,7 @@ static int kvaser_pciefd_probe(struct pc KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IEN_REG);/* Enable PCI interrupts */ - irq_en_base =KVASER_PCIEFD_PCI_IEN_ADDR (pcie); -iowrite32 (irq_mask->all, irq_en_base); +iowrite32 (irq_mask->all,KVASER_PCIEFD_PCI_IEN_ADDR (pcie));/* Ready the DMA buffers */ iowrite32 (KVASER_PCIEFD_SRB_CMD_RDB0 ,KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_CMD_REG );
@@ -1743,8 +1748,7 @@ static int kvaser_pciefd_probe(struct pcreturn 0 ; err_free_irq: -/* Disable PCI interrupts */ -iowrite32 (0 , irq_en_base); +kvaser_pciefd_disable_irq_srcs (pcie);free_irq (pcie->pci->irq, pcie); err_teardown_can_ctrls:
@@ -1764,35 +1768,25 @@ err_disable_pci:return err; } -static void kvaser_pciefd_remove_all_ctrls (struct kvaser_pciefd *pcie) -{ -int i; - -for (i =0 ; i < pcie->nr_channels; i++) { -struct kvaser_pciefd_can *can = pcie->can[i]; - -if (can) { -iowrite32 (0 , can->reg_base +KVASER_PCIEFD_KCAN_IEN_REG ); -unregister_candev (can->can.dev); -del_timer (&can->bec_poll_timer); -kvaser_pciefd_pwm_stop (can); -free_candev (can->can.dev); - } - } -} -static void kvaser_pciefd_remove (struct pci_dev *pdev) {struct kvaser_pciefd *pcie =pci_get_drvdata (pdev); +unsigned int i; -kvaser_pciefd_remove_all_ctrls (pcie); +for (i =0 ; i < pcie->nr_channels; ++i) { +struct kvaser_pciefd_can *can = pcie->can[i]; -/* Disable interrupts */ -iowrite32 (0 ,KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_CTRL_REG ); -iowrite32 (0 ,KVASER_PCIEFD_PCI_IEN_ADDR (pcie)); +unregister_candev (can->can.dev); +del_timer (&can->bec_poll_timer); +kvaser_pciefd_pwm_stop (can); + } +kvaser_pciefd_disable_irq_srcs (pcie);free_irq (pcie->pci->irq, pcie); +for (i =0 ; i < pcie->nr_channels; ++i) +free_candev (pcie->can[i]->can.dev); +pci_iounmap (pdev, pcie->reg_base);pci_release_regions (pdev);pci_disable_device (pdev);
Greg Kroah-Hartman
maintainerPATCH 393/444 hrtimers: Force migrate away hrtimers queued after CPUHP_AP_HRTIMERS_DYING
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frederic Weisbecker <[email protected]>
commit 53dac345395c0d2493cbc2f4c85fe38aef5b63f5 upstream.
hrtimers are migrated away from the dying CPU to any online target at the CPUHP_AP_HRTIMERS_DYING stage in order not to delay bandwidth timers handling tasks involved in the CPU hotplug forward progress.
However wakeups can still be performed by the outgoing CPU after CPUHP_AP_HRTIMERS_DYING. Those can result again in bandwidth timers being armed. Depending on several considerations (crystal ball power management based election, earliest timer already enqueued, timer migration enabled or not), the target may eventually be the current CPU even if offline. If that happens, the timer is eventually ignored.
The most notable example is RCU which had to deal with each and every of those wake-ups by deferring them to an online CPU, along with related workarounds:
_ e787644caf76 (rcu: Defer RCU kthreads wakeup when CPU is dying) _ 9139f93209d1 (rcu/nocb: Fix RT throttling hrtimer armed from offline CPU) _ f7345ccc62a4 (rcu/nocb: Fix rcuog wake-up from offline softirq)
The problem isn't confined to RCU though as the stop machine kthread (which runs CPUHP_AP_HRTIMERS_DYING) reports its completion at the end of its work through cpu_stop_signal_done() and performs a wake up that eventually arms the deadline server timer:
WARNING: CPU: 94 PID: 588 at kernel/time/hrtimer.c:1086 hrtimer_start_range_ns+0x289/0x2d0
CPU: 94 UID: 0 PID: 588 Comm: migration/94 Not tainted
Stopper: multi_cpu_stop+0x0/0x120 <- stop_machine_cpuslocked+0x66/0xc0
RIP: 0010:hrtimer_start_range_ns+0x289/0x2d0
Call Trace:
<TASK>
start_dl_timer
enqueue_dl_entity
dl_server_start
enqueue_task_fair
enqueue_task
ttwu_do_activate
try_to_wake_up
complete
cpu_stopper_threadInstead of providing yet another bandaid to work around the situation, fix it in the hrtimers infrastructure instead: always migrate away a timer to an online target whenever it is enqueued from an offline CPU.
This will also allow to revert all the above RCU disgraceful hacks.
--- include/linux/hrtimer.h | 1 kernel/time/hrtimer.c | 103 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 83 insertions(+), 21 deletions(-)
include/linux/hrtimer.h +1 -0
@@ -237,6 +237,7 @@ struct hrtimer_cpu_base {ktime_t softirq_expires_next;struct hrtimer *softirq_next_timer;struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES ]; +call_single_data_t csd; }____cacheline_aligned ;static inline void hrtimer_set_expires (struct hrtimer *timer,ktime_t time)
kernel/time/hrtimer.c +82 -21
176 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 394/444 btrfs: check folio mapping after unlock in relocate_one_folio()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov <[email protected]>
commit 3e74859ee35edc33a022c3f3971df066ea0ca6b9 upstream.
When we call btrfs_read_folio() to bring a folio uptodate, we unlock the folio. The result of that is that a different thread can modify the mapping (like remove it with invalidate) before we call folio_lock(). This results in an invalid page and we need to try again.
In particular, if we are relocating concurrently with aborting a transaction, this can result in a crash like the following:
BUG: kernel NULL pointer dereference, address: 0000000000000000 PGD 0 P4D 0 Oops: 0000 [#1] SMP CPU: 76 PID: 1411631 Comm: kworker/u322:5 Workqueue: events_unbound btrfs_reclaim_bgs_work RIP: 0010:set_page_extent_mapped+0x20/0xb0 RSP: 0018:ffffc900516a7be8 EFLAGS: 00010246 RAX: ffffea009e851d08 RBX: ffffea009e0b1880 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffffc900516a7b90 RDI: ffffea009e0b1880 RBP: 0000000003573000 R08: 0000000000000001 R09: ffff88c07fd2f3f0 R10: 0000000000000000 R11: 0000194754b575be R12: 0000000003572000 R13: 0000000003572fff R14: 0000000000100cca R15: 0000000005582fff FS: 0000000000000000(0000) GS:ffff88c07fd00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000407d00f002 CR4: 00000000007706f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: <TASK> ? __die+0x78/0xc0 ? page_fault_oops+0x2a8/0x3a0 ? __switch_to+0x133/0x530 ? wq_worker_running+0xa/0x40 ? exc_page_fault+0x63/0x130 ? asm_exc_page_fault+0x22/0x30 ? set_page_extent_mapped+0x20/0xb0 relocate_file_extent_cluster+0x1a7/0x940 relocate_data_extent+0xaf/0x120 relocate_block_group+0x20f/0x480 btrfs_relocate_block_group+0x152/0x320 btrfs_relocate_chunk+0x3d/0x120 btrfs_reclaim_bgs_work+0x2ae/0x4e0 process_scheduled_works+0x184/0x370 worker_thread+0xc6/0x3e0 ? blk_add_timer+0xb0/0xb0 kthread+0xae/0xe0 ? flush_tlb_kernel_range+0x90/0x90 ret_from_fork+0x2f/0x40 ? flush_tlb_kernel_range+0x90/0x90 ret_from_fork_asm+0x11/0x20 </TASK>
This occurs because cleanup_one_transaction() calls destroy_delalloc_inodes() which calls invalidate_inode_pages2() which takes the folio_lock before setting mapping to NULL. We fail to check this, and subsequently call set_extent_mapping(), which assumes that mapping != NULL (in fact it asserts that in debug mode)
Note that the "fixes" patch here is not the one that introduced the race (the very first iteration of this code from 2009) but a more recent change that made this particular crash happen in practice.
--- fs/btrfs/relocation.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/btrfs/relocation.c +6 -0
@@ -2931,6 +2931,7 @@ static int relocate_one_page(struct inodint ret;ASSERT (page_index <= last_index); +again: page =find_lock_page (inode->i_mapping, page_index);if (!page) { page_cache_sync_readahead(inode->i_mapping, ra, NULL,
@@ -2952,6 +2953,11 @@ static int relocate_one_page(struct inod ret = -EIO ; goto release_page; } +if (page->mapping != inode->i_mapping) { +unlock_page (page); +put_page (page); + goto again; + } }/*
Greg Kroah-Hartman
maintainerPATCH 395/444 af_unix: Return struct unix_sock from unix_get_socket().
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit 5b17307bd0789edea0675d524a2b277b93bbde62 upstream.
Currently, unix_get_socket() returns struct sock, but after calling it, we always cast it to unix_sk().
Let's return struct unix_sock from unix_get_socket().
--- include/net/af_unix.h | 2 +- net/unix/garbage.c | 19 +++++++------------ net/unix/scm.c | 19 +++++++------------ 3 files changed, 15 insertions(+), 25 deletions(-)
include/net/af_unix.h +1 -1
@@ -14,7 +14,7 @@ void unix_destruct_scm(struct sk_buff *svoid io_uring_destruct_scm (struct sk_buff *skb);void unix_gc (void );void wait_for_unix_gc (void ); -struct sock *unix_get_socket (struct file *filp); +struct unix_sock *unix_get_socket (struct file *filp);struct sock *unix_peer_get (struct sock *sk);#define UNIX_HASH_MOD (256 - 1)
net/unix/garbage.c +7 -12
@@ -105,20 +105,15 @@ static void scan_inflight(struct sock *xwhile (nfd--) {/* Get the socket the fd matches if it indeed does so */ -struct sock *sk =unix_get_socket (*fp++); +struct unix_sock *u =unix_get_socket (*fp++); -if (sk) { -struct unix_sock *u =unix_sk (sk); +/* Ignore non-candidates, they could have been added +* to the queues after starting the garbage collection +*/ +if (u &&test_bit (UNIX_GC_CANDIDATE , &u->gc_flags)) { + hit = true; -/* Ignore non-candidates, they could -* have been added to the queues after -* starting the garbage collection -*/ -if (test_bit (UNIX_GC_CANDIDATE , &u->gc_flags)) { - hit = true; - -func (u); - } +func (u); } }if (hit && hitlist !=NULL ) {
net/unix/scm.c +7 -12
@@ -21,9 +21,8 @@ EXPORT_SYMBOL(gc_inflight_list);DEFINE_SPINLOCK (unix_gc_lock);EXPORT_SYMBOL (unix_gc_lock); -struct sock *unix_get_socket (struct file *filp) +struct unix_sock *unix_get_socket (struct file *filp) { -struct sock *u_sock =NULL ;struct inode *inode =file_inode (filp);/* Socket ? */
@@ -34,10 +33,10 @@ struct sock *unix_get_socket(struct file/* PF_UNIX ? */ if (s && ops && ops->family ==PF_UNIX ) - u_sock = s; +return unix_sk (s); } -return u_sock; +return NULL ; }EXPORT_SYMBOL (unix_get_socket);
@@ -46,13 +45,11 @@ EXPORT_SYMBOL(unix_get_socket);*/ void unix_inflight (struct user_struct *user,struct file *fp) { -struct sock *s =unix_get_socket (fp); +struct unix_sock *u =unix_get_socket (fp);spin_lock (&unix_gc_lock); -if (s) { -struct unix_sock *u =unix_sk (s); - +if (u) {if (!u->inflight) {BUG_ON (!list_empty (&u->link));list_add_tail (&u->link, &gc_inflight_list);
@@ -69,13 +66,11 @@ void unix_inflight(struct user_struct *uvoid unix_notinflight (struct user_struct *user,struct file *fp) { -struct sock *s =unix_get_socket (fp); +struct unix_sock *u =unix_get_socket (fp);spin_lock (&unix_gc_lock); -if (s) { -struct unix_sock *u =unix_sk (s); - +if (u) {BUG_ON (!u->inflight);BUG_ON (list_empty (&u->link));
Greg Kroah-Hartman
maintainerPATCH 396/444 af_unix: Run GC on only one CPU.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit 8b90a9f819dc2a06baae4ec1a64d875e53b824ec upstream.
If more than 16000 inflight AF_UNIX sockets exist and the garbage collector is not running, unix_(dgram|stream)_sendmsg() call unix_gc(). Also, they wait for unix_gc() to complete.
In unix_gc(), all inflight AF_UNIX sockets are traversed at least once, and more if they are the GC candidate. Thus, sendmsg() significantly slows down with too many inflight AF_UNIX sockets.
There is a small window to invoke multiple unix_gc() instances, which will then be blocked by the same spinlock except for one.
Let's convert unix_gc() to use struct work so that it will not consume CPUs unnecessarily.
Note WRITE_ONCE(gc_in_progress, true) is moved before running GC. If we leave the WRITE_ONCE() as is and use the following test to call flush_work(), a process might not call it.
CPU 0 CPU 1
--- ---
start work and call __unix_gc()
if (work_pending(&unix_gc_work) || <-- false
READ_ONCE(gc_in_progress)) <-- false
flush_work(); <-- missed!
WRITE_ONCE(gc_in_progress, true)
--- net/unix/garbage.c | 54 ++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-)
net/unix/garbage.c +27 -27
@@ -86,7 +86,6 @@/* Internal data structures and random procedures: */ static LIST_HEAD (gc_candidates); -static DECLARE_WAIT_QUEUE_HEAD (unix_gc_wait);static void scan_inflight (struct sock *x,void (*func)(struct unix_sock *),struct sk_buff_head *hitlist)
@@ -182,23 +181,8 @@ static void inc_inflight_move_tail(struc }static bool gc_in_progress; -#define UNIX_INFLIGHT_TRIGGER_GC 16000 - -void wait_for_unix_gc (void ) -{ -/* If number of inflight sockets is insane, -* force a garbage collect right now. -* Paired with the WRITE_ONCE() in unix_inflight(), -* unix_notinflight() and gc_in_progress(). -*/ -if (READ_ONCE (unix_tot_inflight) >UNIX_INFLIGHT_TRIGGER_GC && - !READ_ONCE (gc_in_progress)) -unix_gc (); -wait_event (unix_gc_wait, !READ_ONCE (gc_in_progress)); -} -/* The external entry point: unix_gc() */ -void unix_gc (void ) +static void __unix_gc (struct work_struct *work) {struct sk_buff *next_skb, *skb;struct unix_sock *u;
@@ -209,13 +193,6 @@ void unix_gc(void)spin_lock (&unix_gc_lock); -/* Avoid a recursive GC. */ -if (gc_in_progress) - goto out; - -/* Paired with READ_ONCE() in wait_for_unix_gc(). */ -WRITE_ONCE (gc_in_progress, true); -/* First, select candidates for garbage collection. Only * in-flight sockets are considered, and from those only ones * which don't have any external reference.
@@ -346,8 +323,31 @@ void unix_gc(void)/* Paired with READ_ONCE() in wait_for_unix_gc(). */ WRITE_ONCE (gc_in_progress, false); -wake_up (&unix_gc_wait); - - out:spin_unlock (&unix_gc_lock); } + +static DECLARE_WORK(unix_gc_work, __unix_gc); + +void unix_gc (void ) +{ +WRITE_ONCE (gc_in_progress, true); +queue_work (system_unbound_wq, &unix_gc_work); +} + +#define UNIX_INFLIGHT_TRIGGER_GC 16000 + +void wait_for_unix_gc (void ) +{ +/* If number of inflight sockets is insane, +* force a garbage collect right now. +* +* Paired with the WRITE_ONCE() in unix_inflight(), +* unix_notinflight(), and __unix_gc(). +*/ +if (READ_ONCE (unix_tot_inflight) >UNIX_INFLIGHT_TRIGGER_GC && + !READ_ONCE (gc_in_progress)) +unix_gc (); + +if (READ_ONCE (gc_in_progress)) +flush_work (&unix_gc_work); +}
Greg Kroah-Hartman
maintainerPATCH 397/444 af_unix: Try to run GC async.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit d9f21b3613337b55cc9d4a6ead484dca68475143 upstream.
If more than 16000 inflight AF_UNIX sockets exist and the garbage collector is not running, unix_(dgram|stream)_sendmsg() call unix_gc(). Also, they wait for unix_gc() to complete.
In unix_gc(), all inflight AF_UNIX sockets are traversed at least once, and more if they are the GC candidate. Thus, sendmsg() significantly slows down with too many inflight AF_UNIX sockets.
However, if a process sends data with no AF_UNIX FD, the sendmsg() call does not need to wait for GC. After this change, only the process that meets the condition below will be blocked under such a situation.
1) cmsg contains AF_UNIX socket
2) more than 32 AF_UNIX sent by the same user are still inflight
Note that even a sendmsg() call that does not meet the condition but has AF_UNIX FD will be blocked later in unix_scm_to_skb() by the spinlock, but we allow that as a bonus for sane users.
The results below are the time spent in unix_dgram_sendmsg() sending 1 byte of data with no FD 4096 times on a host where 32K inflight AF_UNIX sockets exist.
Without series: the sane sendmsg() needs to wait gc unreasonably.
$ sudo /usr/share/bcc/tools/funclatency -p 11165 unix_dgram_sendmsg
Tracing 1 functions for "unix_dgram_sendmsg"... Hit Ctrl-C to end.
^C
nsecs : count distribution
[...]
524288 -> 1048575 : 0 | |
1048576 -> 2097151 : 3881 |****************************************|
2097152 -> 4194303 : 214 |** |
4194304 -> 8388607 : 1 | |avg = 1825567 nsecs, total: 7477526027 nsecs, count: 4096
With series: the sane sendmsg() can finish much faster.
$ sudo /usr/share/bcc/tools/funclatency -p 8702 unix_dgram_sendmsg
Tracing 1 functions for "unix_dgram_sendmsg"... Hit Ctrl-C to end.
^C
nsecs : count distribution
[...]
128 -> 255 : 0 | |
256 -> 511 : 4092 |****************************************|
512 -> 1023 : 2 | |
1024 -> 2047 : 0 | |
2048 -> 4095 : 0 | |
4096 -> 8191 : 1 | |
8192 -> 16383 : 1 | |avg = 410 nsecs, total: 1680510 nsecs, count: 4096
--- include/net/af_unix.h | 12 ++++++++++-- include/net/scm.h | 1 + net/core/scm.c | 5 +++++ net/unix/af_unix.c | 6 ++++-- net/unix/garbage.c | 10 +++++++++- 5 files changed, 29 insertions(+), 5 deletions(-)
include/net/af_unix.h +10 -2
@@ -8,13 +8,21 @@#include <linux/refcount.h> #include <net/sock.h> +#if IS_ENABLED (CONFIG_UNIX ) +struct unix_sock *unix_get_socket (struct file *filp); +#else +static inline struct unix_sock *unix_get_socket (struct file *filp) +{ +return NULL ; +} +#endif +void unix_inflight (struct user_struct *user,struct file *fp);void unix_notinflight (struct user_struct *user,struct file *fp);void unix_destruct_scm (struct sk_buff *skb);void io_uring_destruct_scm (struct sk_buff *skb);void unix_gc (void ); -void wait_for_unix_gc (void ); -struct unix_sock *unix_get_socket (struct file *filp); +void wait_for_unix_gc (struct scm_fp_list *fpl);struct sock *unix_peer_get (struct sock *sk);#define UNIX_HASH_MOD (256 - 1)
include/net/scm.h +1 -0
@@ -24,6 +24,7 @@ struct scm_creds {struct scm_fp_list {short count; +short count_unix;short max;struct user_struct *user;struct file *fp[SCM_MAX_FD ];
net/core/scm.c +5 -0
@@ -36,6 +36,7 @@#include <net/compat.h> #include <net/scm.h> #include <net/cls_cgroup.h> +#include <net/af_unix.h> /*
@@ -85,6 +86,7 @@ static int scm_fp_copy(struct cmsghdr *creturn -ENOMEM ; *fplp = fpl; fpl->count =0 ; + fpl->count_unix =0 ; fpl->max =SCM_MAX_FD ; fpl->user =NULL ; }
@@ -109,6 +111,9 @@ static int scm_fp_copy(struct cmsghdr *cfput (file);return -EINVAL ; } +if (unix_get_socket (file)) + fpl->count_unix++; + *fpp++ = file; fpl->count++; }
net/unix/af_unix.c +4 -2
@@ -1885,11 +1885,12 @@ static int unix_dgram_sendmsg(struct soclong timeo;int err; -wait_for_unix_gc (); err =scm_send (sock, msg, &scm, false);if (err <0 )return err; +wait_for_unix_gc (scm.fp); + err = -EOPNOTSUPP ;if (msg->msg_flags&MSG_OOB ) goto out;
@@ -2157,11 +2158,12 @@ static int unix_stream_sendmsg(struct sobool fds_sent = false;int data_len; -wait_for_unix_gc (); err =scm_send (sock, msg, &scm, false);if (err <0 )return err; +wait_for_unix_gc (scm.fp); + err = -EOPNOTSUPP ;if (msg->msg_flags &MSG_OOB ) {#if IS_ENABLED (CONFIG_AF_UNIX_OOB )
net/unix/garbage.c +9 -1
@@ -335,8 +335,9 @@ void unix_gc(void) }#define UNIX_INFLIGHT_TRIGGER_GC 16000 +#define UNIX_INFLIGHT_SANE_USER (SCM_MAX_FD * 8) -void wait_for_unix_gc (void ) +void wait_for_unix_gc (struct scm_fp_list *fpl) {/* If number of inflight sockets is insane, * force a garbage collect right now.
@@ -348,6 +349,13 @@ void wait_for_unix_gc(void) !READ_ONCE(gc_in_progress))unix_gc (); +/* Penalise users who want to send AF_UNIX sockets +* but whose sockets have not been received yet. +*/ +if (!fpl || !fpl->count_unix || +READ_ONCE (fpl->user->unix_inflight) <UNIX_INFLIGHT_SANE_USER ) +return ; +if (READ_ONCE (gc_in_progress))flush_work (&unix_gc_work); }
Greg Kroah-Hartman
maintainerPATCH 398/444 af_unix: Replace BUG_ON() with WARN_ON_ONCE().
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit d0f6dc26346863e1f4a23117f5468614e54df064 upstream.
This is a prep patch for the last patch in this series so that checkpatch will not warn about BUG_ON().
--- net/unix/garbage.c | 8 ++++---- net/unix/scm.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-)
net/unix/garbage.c +4 -4
@@ -145,7 +145,7 @@ static void scan_children(struct sock *x/* An embryo cannot be in-flight, so it's safe * to use the list link. */ -BUG_ON (!list_empty (&u->link)); +WARN_ON_ONCE (!list_empty (&u->link));list_add_tail (&u->link, &embryos); }spin_unlock (&x->sk_receive_queue.lock);
@@ -224,8 +224,8 @@ static void __unix_gc(struct work_struct total_refs =file_count (sk->sk_socket->file); -BUG_ON (!u->inflight); -BUG_ON (total_refs < u->inflight); +WARN_ON_ONCE (!u->inflight); +WARN_ON_ONCE (total_refs < u->inflight);if (total_refs == u->inflight) {list_move_tail (&u->link, &gc_candidates);__set_bit (UNIX_GC_CANDIDATE , &u->gc_flags);
@@ -318,7 +318,7 @@ static void __unix_gc(struct work_structlist_move_tail (&u->link, &gc_inflight_list);/* All candidates should have been detached by now. */ -BUG_ON (!list_empty (&gc_candidates)); +WARN_ON_ONCE (!list_empty (&gc_candidates));/* Paired with READ_ONCE() in wait_for_unix_gc(). */ WRITE_ONCE (gc_in_progress, false);
net/unix/scm.c +4 -4
@@ -51,10 +51,10 @@ void unix_inflight(struct user_struct *uif (u) {if (!u->inflight) { -BUG_ON (!list_empty (&u->link)); +WARN_ON_ONCE (!list_empty (&u->link));list_add_tail (&u->link, &gc_inflight_list); }else { -BUG_ON (list_empty (&u->link)); +WARN_ON_ONCE (list_empty (&u->link)); } u->inflight++;/* Paired with READ_ONCE() in wait_for_unix_gc() */
@@ -71,8 +71,8 @@ void unix_notinflight(struct user_structspin_lock (&unix_gc_lock);if (u) { -BUG_ON (!u->inflight); -BUG_ON (list_empty (&u->link)); +WARN_ON_ONCE (!u->inflight); +WARN_ON_ONCE (list_empty (&u->link)); u->inflight--;if (!u->inflight)
Greg Kroah-Hartman
maintainerPATCH 399/444 af_unix: Remove io_uring code for GC.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit 11498715f266a3fb4caabba9dd575636cbcaa8f1 upstream.
Since commit 705318a99a13 ("io_uring/af_unix: disable sending io_uring over sockets"), io_uring's unix socket cannot be passed via SCM_RIGHTS, so it does not contribute to cyclic reference and no longer be candidate for garbage collection.
Also, commit 6e5e6d274956 ("io_uring: drop any code related to SCM_RIGHTS") cleaned up SCM_RIGHTS code in io_uring.
Let's do it in AF_UNIX as well by reverting commit 0091bfc81741 ("io_uring/af_unix: defer registered files gc to io_uring release") and commit 10369080454d ("net: reclaim skb->scm_io_uring bit").
--- include/net/af_unix.h | 1 - net/unix/garbage.c | 25 ++----------------------- net/unix/scm.c | 6 ------ 3 files changed, 2 insertions(+), 30 deletions(-)
include/net/af_unix.h +0 -1
@@ -20,7 +20,6 @@ static inline struct unix_sock *unix_getvoid unix_inflight (struct user_struct *user,struct file *fp);void unix_notinflight (struct user_struct *user,struct file *fp);void unix_destruct_scm (struct sk_buff *skb); -void io_uring_destruct_scm (struct sk_buff *skb);void unix_gc (void );void wait_for_unix_gc (struct scm_fp_list *fpl);struct sock *unix_peer_get (struct sock *sk);
net/unix/garbage.c +2 -23
@@ -184,12 +184,10 @@ static bool gc_in_progress;static void __unix_gc (struct work_struct *work) { -struct sk_buff *next_skb, *skb; -struct unix_sock *u; -struct unix_sock *next;struct sk_buff_head hitlist; -struct list_head cursor; +struct unix_sock *u, *next;LIST_HEAD (not_cycle_list); +struct list_head cursor;spin_lock (&unix_gc_lock);
@@ -293,30 +291,11 @@ static void __unix_gc(struct work_structspin_unlock (&unix_gc_lock); -/* We need io_uring to clean its registered files, ignore all io_uring -* originated skbs. It's fine as io_uring doesn't keep references to -* other io_uring instances and so killing all other files in the cycle -* will put all io_uring references forcing it to go through normal -* release.path eventually putting registered files. -*/ - skb_queue_walk_safe(&hitlist, skb, next_skb) { -if (skb->destructor == io_uring_destruct_scm) { -__skb_unlink (skb, &hitlist); -skb_queue_tail (&skb->sk->sk_receive_queue, skb); - } - } -/* Here we are. Hitlist is filled. Die. */ __skb_queue_purge (&hitlist);spin_lock (&unix_gc_lock); -/* There could be io_uring registered files, just push them back to -* the inflight list -*/ -list_for_each_entry_safe (u, next, &gc_candidates, link) -list_move_tail (&u->link, &gc_inflight_list); -/* All candidates should have been detached by now. */ WARN_ON_ONCE (!list_empty (&gc_candidates));
net/unix/scm.c +0 -6
@@ -148,9 +148,3 @@ void unix_destruct_scm(struct sk_buff *ssock_wfree (skb); }EXPORT_SYMBOL (unix_destruct_scm); - -void io_uring_destruct_scm (struct sk_buff *skb) -{ -unix_destruct_scm (skb); -} -EXPORT_SYMBOL (io_uring_destruct_scm);
Greg Kroah-Hartman
maintainerPATCH 400/444 af_unix: Remove CONFIG_UNIX_SCM.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit 99a7a5b9943ea2d05fb0dee38e4ae2290477ed83 upstream.
Originally, the code related to garbage collection was all in garbage.c.
Commit f4e65870e5ce ("net: split out functions related to registering inflight socket files") moved some functions to scm.c for io_uring and added CONFIG_UNIX_SCM just in case AF_UNIX was built as module.
However, since commit 97154bcf4d1b ("af_unix: Kconfig: make CONFIG_UNIX bool"), AF_UNIX is no longer built separately. Also, io_uring does not support SCM_RIGHTS now.
Let's move the functions back to garbage.c
--- include/net/af_unix.h | 7 +- net/Makefile | 2 net/unix/Kconfig | 5 - net/unix/Makefile | 2 net/unix/af_unix.c | 63 ++++++++++++++++++++- net/unix/garbage.c | 73 +++++++++++++++++++++++- net/unix/scm.c | 150 -------------------------------------------------- net/unix/scm.h | 10 --- 8 files changed, 137 insertions(+), 175 deletions(-) delete mode 100644 net/unix/scm.c delete mode 100644 net/unix/scm.h
include/net/af_unix.h +4 -3
@@ -17,19 +17,20 @@ static inline struct unix_sock *unix_get }#endif +extern spinlock_t unix_gc_lock; +extern unsigned int unix_tot_inflight; +void unix_inflight (struct user_struct *user,struct file *fp);void unix_notinflight (struct user_struct *user,struct file *fp); -void unix_destruct_scm (struct sk_buff *skb);void unix_gc (void );void wait_for_unix_gc (struct scm_fp_list *fpl); +struct sock *unix_peer_get (struct sock *sk);#define UNIX_HASH_MOD (256 - 1)#define UNIX_HASH_SIZE (256 * 2)#define UNIX_HASH_BITS 8 -extern unsigned int unix_tot_inflight; -struct unix_address {refcount_t refcnt;int len;
net/Makefile +1 -1
@@ -17,7 +17,7 @@ obj-$(CONFIG_NETFILTER) += netfilter/ obj-$(CONFIG_INET) += ipv4/ obj-$(CONFIG_TLS) += tls/ obj-$(CONFIG_XFRM) += xfrm/ -obj-$(CONFIG_UNIX_SCM) += unix/ +obj-$(CONFIG_UNIX) += unix/ obj-y += ipv6/ obj-$(CONFIG_BPFILTER) += bpfilter/ obj-$(CONFIG_PACKET) += packet/
net/unix/Kconfig +0 -5
@@ -16,11 +16,6 @@ config UNIX Say Y unless you know what you are doing. -config UNIX_SCM - bool - depends on UNIX - default y - config AF_UNIX_OOB bool depends on UNIX
net/unix/Makefile +0 -2
@@ -11,5 +11,3 @@ unix-$(CONFIG_BPF_SYSCALL) += unix_bpf.o obj-$(CONFIG_UNIX_DIAG) += unix_diag.o unix_diag-y := diag.o - -obj-$(CONFIG_UNIX_SCM) += scm.o
net/unix/af_unix.c +61 -2
81 lines not on this page · raw message
net/unix/garbage.c +71 -2
82 lines not on this page · raw message
net/unix/scm.c deleted +0 -150
150 lines not on this page · raw message
net/unix/scm.h deleted +0 -10
@@ -1,10 +0,0 @@ -#ifndef NET_UNIX_SCM_H -#define NET_UNIX_SCM_H - -extern struct list_head gc_inflight_list; -extern spinlock_t unix_gc_lock; - -int unix_attach_fds (struct scm_cookie *scm,struct sk_buff *skb); -void unix_detach_fds (struct scm_cookie *scm,struct sk_buff *skb); - -#endif
Greg Kroah-Hartman
maintainerPATCH 401/444 af_unix: Allocate struct unix_vertex for each inflight AF_UNIX fd.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit 1fbfdfaa590248c1d86407f578e40e5c65136330 upstream.
We will replace the garbage collection algorithm for AF_UNIX, where we will consider each inflight AF_UNIX socket as a vertex and its file descriptor as an edge in a directed graph.
This patch introduces a new struct unix_vertex representing a vertex in the graph and adds its pointer to struct unix_sock.
When we send a fd using the SCM_RIGHTS message, we allocate struct scm_fp_list to struct scm_cookie in scm_fp_copy(). Then, we bump each refcount of the inflight fds' struct file and save them in scm_fp_list.fp.
After that, unix_attach_fds() inexplicably clones scm_fp_list of scm_cookie and sets it to skb. (We will remove this part after replacing GC.)
Here, we add a new function call in unix_attach_fds() to preallocate struct unix_vertex per inflight AF_UNIX fd and link each vertex to skb's scm_fp_list.vertices.
When sendmsg() succeeds later, if the socket of the inflight fd is still not inflight yet, we will set the preallocated vertex to struct unix_sock.vertex and link it to a global list unix_unvisited_vertices under spin_lock(&unix_gc_lock).
If the socket is already inflight, we free the preallocated vertex. This is to avoid taking the lock unnecessarily when sendmsg() could fail later.
In the following patch, we will similarly allocate another struct per edge, which will finally be linked to the inflight socket's unix_vertex.edges.
And then, we will count the number of edges as unix_vertex.out_degree.
--- include/net/af_unix.h | 9 +++++++++ include/net/scm.h | 3 +++ net/core/scm.c | 7 +++++++ net/unix/af_unix.c | 6 ++++++ net/unix/garbage.c | 38 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+)
include/net/af_unix.h +9 -0
@@ -22,9 +22,17 @@ extern unsigned int unix_tot_inflight;void unix_inflight (struct user_struct *user,struct file *fp);void unix_notinflight (struct user_struct *user,struct file *fp); +int unix_prepare_fpl (struct scm_fp_list *fpl); +void unix_destroy_fpl (struct scm_fp_list *fpl);void unix_gc (void );void wait_for_unix_gc (struct scm_fp_list *fpl); +struct unix_vertex { +struct list_head edges; +struct list_head entry; +unsigned long out_degree; +}; +struct sock *unix_peer_get (struct sock *sk);#define UNIX_HASH_MOD (256 - 1)
@@ -62,6 +70,7 @@ struct unix_sock {struct path path;struct mutex iolock, bindlock;struct sock *peer; +struct unix_vertex *vertex;struct list_head link;unsigned long inflight;spinlock_t lock;
include/net/scm.h +3 -0
@@ -26,6 +26,9 @@ struct scm_fp_list {short count;short count_unix;short max; +#ifdef CONFIG_UNIX +struct list_head vertices; +#endif struct user_struct *user;struct file *fp[SCM_MAX_FD ]; };
net/core/scm.c +7 -0
@@ -89,6 +89,9 @@ static int scm_fp_copy(struct cmsghdr *c fpl->count_unix =0 ; fpl->max =SCM_MAX_FD ; fpl->user =NULL ; +#if IS_ENABLED (CONFIG_UNIX ) +INIT_LIST_HEAD (&fpl->vertices); +#endif } fpp = &fpl->fp[fpl->count];
@@ -376,8 +379,12 @@ struct scm_fp_list *scm_fp_dup(struct scif (new_fpl) {for (i =0 ; i < fpl->count; i++)get_file (fpl->fp[i]); + new_fpl->max = new_fpl->count; new_fpl->user =get_uid (fpl->user); +#if IS_ENABLED (CONFIG_UNIX ) +INIT_LIST_HEAD (&new_fpl->vertices); +#endif }return new_fpl; }
net/unix/af_unix.c +6 -0
@@ -979,6 +979,7 @@ static struct sock *unix_create1(struct sk->sk_destruct = unix_sock_destructor; u =unix_sk (sk); u->inflight =0 ; + u->vertex =NULL ; u->path.dentry =NULL ; u->path.mnt =NULL ;spin_lock_init (&u->lock);
@@ -1782,6 +1783,9 @@ static int unix_attach_fds(struct scm_cofor (i = scm->fp->count -1 ; i >=0 ; i--)unix_inflight (scm->fp->user, scm->fp->fp[i]); +if (unix_prepare_fpl (UNIXCB (skb).fp)) +return -ENOMEM ; +return 0 ; }
@@ -1792,6 +1796,8 @@ static void unix_detach_fds(struct scm_c scm->fp =UNIXCB (skb).fp;UNIXCB (skb).fp =NULL ; +unix_destroy_fpl (scm->fp); +for (i = scm->fp->count -1 ; i >=0 ; i--)unix_notinflight (scm->fp->user, scm->fp->fp[i]); }
net/unix/garbage.c +38 -0
@@ -101,6 +101,44 @@ struct unix_sock *unix_get_socket(structreturn NULL ; } +static void unix_free_vertices (struct scm_fp_list *fpl) +{ +struct unix_vertex *vertex, *next_vertex; + +list_for_each_entry_safe (vertex, next_vertex, &fpl->vertices, entry) { +list_del (&vertex->entry); +kfree (vertex); + } +} + +int unix_prepare_fpl (struct scm_fp_list *fpl) +{ +struct unix_vertex *vertex; +int i; + +if (!fpl->count_unix) +return 0 ; + +for (i =0 ; i < fpl->count_unix; i++) { + vertex =kmalloc (sizeof (*vertex),GFP_KERNEL ); +if (!vertex) + goto err; + +list_add (&vertex->entry, &fpl->vertices); + } + +return 0 ; + +err: +unix_free_vertices (fpl); +return -ENOMEM ; +} + +void unix_destroy_fpl (struct scm_fp_list *fpl) +{ +unix_free_vertices (fpl); +} +DEFINE_SPINLOCK (unix_gc_lock);unsigned int unix_tot_inflight;static LIST_HEAD (gc_candidates);
Greg Kroah-Hartman
maintainerPATCH 402/444 af_unix: Allocate struct unix_edge for each inflight AF_UNIX fd.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit 29b64e354029cfcf1eea4d91b146c7b769305930 upstream.
As with the previous patch, we preallocate to skb's scm_fp_list an array of struct unix_edge in the number of inflight AF_UNIX fds.
There we just preallocate memory and do not use immediately because sendmsg() could fail after this point. The actual use will be in the next patch.
When we queue skb with inflight edges, we will set the inflight socket's unix_sock as unix_edge->predecessor and the receiver's unix_sock as successor, and then we will link the edge to the inflight socket's unix_vertex.edges.
Note that we set NULL to cloned scm_fp_list.edges in scm_fp_dup() so that MSG_PEEK does not change the shape of the directed graph.
--- include/net/af_unix.h | 6 ++++++ include/net/scm.h | 5 +++++ net/core/scm.c | 2 ++ net/unix/garbage.c | 6 ++++++ 4 files changed, 19 insertions(+)
include/net/af_unix.h +6 -0
@@ -33,6 +33,12 @@ struct unix_vertex {unsigned long out_degree; }; +struct unix_edge { +struct unix_sock *predecessor; +struct unix_sock *successor; +struct list_head vertex_entry; +}; +struct sock *unix_peer_get (struct sock *sk);#define UNIX_HASH_MOD (256 - 1)
include/net/scm.h +5 -0
@@ -22,12 +22,17 @@ struct scm_creds {kgid_t gid; }; +#ifdef CONFIG_UNIX +struct unix_edge ; +#endif +struct scm_fp_list {short count;short count_unix;short max;#ifdef CONFIG_UNIX struct list_head vertices; +struct unix_edge *edges;#endif struct user_struct *user;struct file *fp[SCM_MAX_FD ];
net/core/scm.c +2 -0
@@ -90,6 +90,7 @@ static int scm_fp_copy(struct cmsghdr *c fpl->max =SCM_MAX_FD ; fpl->user =NULL ;#if IS_ENABLED (CONFIG_UNIX ) + fpl->edges =NULL ;INIT_LIST_HEAD (&fpl->vertices);#endif }
@@ -383,6 +384,7 @@ struct scm_fp_list *scm_fp_dup(struct sc new_fpl->max = new_fpl->count; new_fpl->user =get_uid (fpl->user);#if IS_ENABLED (CONFIG_UNIX ) + new_fpl->edges =NULL ;INIT_LIST_HEAD (&new_fpl->vertices);#endif }
net/unix/garbage.c +6 -0
@@ -127,6 +127,11 @@ int unix_prepare_fpl(struct scm_fp_listlist_add (&vertex->entry, &fpl->vertices); } + fpl->edges =kvmalloc_array (fpl->count_unix,sizeof (*fpl->edges), +GFP_KERNEL_ACCOUNT ); +if (!fpl->edges) + goto err; +return 0 ; err:
@@ -136,6 +141,7 @@ err:void unix_destroy_fpl (struct scm_fp_list *fpl) { +kvfree (fpl->edges);unix_free_vertices (fpl); }
Greg Kroah-Hartman
maintainerPATCH 403/444 af_unix: Link struct unix_edge when queuing skb.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit 42f298c06b30bfe0a8cbee5d38644e618699e26e upstream.
Just before queuing skb with inflight fds, we call scm_stat_add(), which is a good place to set up the preallocated struct unix_vertex and struct unix_edge in UNIXCB(skb).fp.
Then, we call unix_add_edges() and construct the directed graph as follows:
1. Set the inflight socket's unix_sock to unix_edge.predecessor.
2. Set the receiver's unix_sock to unix_edge.successor.
3. Set the preallocated vertex to inflight socket's unix_sock.vertex.
4. Link inflight socket's unix_vertex.entry to unix_unvisited_vertices.
5. Link unix_edge.vertex_entry to the inflight socket's unix_vertex.edges.
Let's say we pass the fd of AF_UNIX socket A to B and the fd of B to C. The graph looks like this:
+-------------------------+
| unix_unvisited_vertices | <-------------------------.
+-------------------------+ |
+ |
| +--------------+ +--------------+ | +--------------+
| | unix_sock A | <---. .---> | unix_sock B | <-|-. .---> | unix_sock C |
| +--------------+ | | +--------------+ | | | +--------------+
| .-+ | vertex | | | .-+ | vertex | | | | | vertex |
| | +--------------+ | | | +--------------+ | | | +--------------+
| | | | | | | |
| | +--------------+ | | | +--------------+ | | |
| '-> | unix_vertex | | | '-> | unix_vertex | | | |
| +--------------+ | | +--------------+ | | |
`---> | entry | +---------> | entry | +-' | |
|--------------| | | |--------------| | |
| edges | <-. | | | edges | <-. | |
+--------------+ | | | +--------------+ | | |
| | | | | |
.----------------------' | | .----------------------' | |
| | | | | |
| +--------------+ | | | +--------------+ | |
| | unix_edge | | | | | unix_edge | | |
| +--------------+ | | | +--------------+ | |
`-> | vertex_entry | | | `-> | vertex_entry | | |
|--------------| | | |--------------| | |
| predecessor | +---' | | predecessor | +---' |
|--------------| | |--------------| |
| successor | +-----' | successor | +-----'
+--------------+ +--------------+Henceforth, we denote such a graph as A -> B (-> C).
Now, we can express all inflight fd graphs that do not contain embryo sockets. We will support the particular case later.
--- include/net/af_unix.h | 2 + include/net/scm.h | 1 net/core/scm.c | 2 + net/unix/af_unix.c | 8 +++- net/unix/garbage.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 100 insertions(+), 3 deletions(-)
include/net/af_unix.h +2 -0
@@ -22,6 +22,8 @@ extern unsigned int unix_tot_inflight;void unix_inflight (struct user_struct *user,struct file *fp);void unix_notinflight (struct user_struct *user,struct file *fp); +void unix_add_edges (struct scm_fp_list *fpl,struct unix_sock *receiver); +void unix_del_edges (struct scm_fp_list *fpl);int unix_prepare_fpl (struct scm_fp_list *fpl);void unix_destroy_fpl (struct scm_fp_list *fpl);void unix_gc (void );
include/net/scm.h +1 -0
@@ -31,6 +31,7 @@ struct scm_fp_list {short count_unix;short max;#ifdef CONFIG_UNIX +bool inflight;struct list_head vertices;struct unix_edge *edges;#endif
net/core/scm.c +2 -0
@@ -90,6 +90,7 @@ static int scm_fp_copy(struct cmsghdr *c fpl->max =SCM_MAX_FD ; fpl->user =NULL ;#if IS_ENABLED (CONFIG_UNIX ) + fpl->inflight = false; fpl->edges =NULL ;INIT_LIST_HEAD (&fpl->vertices);#endif
@@ -384,6 +385,7 @@ struct scm_fp_list *scm_fp_dup(struct sc new_fpl->max = new_fpl->count; new_fpl->user =get_uid (fpl->user);#if IS_ENABLED (CONFIG_UNIX ) + new_fpl->inflight = false; new_fpl->edges =NULL ;INIT_LIST_HEAD (&new_fpl->vertices);#endif
net/unix/af_unix.c +6 -2
@@ -1920,8 +1920,10 @@ static void scm_stat_add(struct sock *skstruct scm_fp_list *fp =UNIXCB (skb).fp;struct unix_sock *u =unix_sk (sk); -if (unlikely (fp && fp->count)) +if (unlikely (fp && fp->count)) {atomic_add (fp->count, &u->scm_stat.nr_fds); +unix_add_edges (fp, u); + } }static void scm_stat_del (struct sock *sk,struct sk_buff *skb)
@@ -1929,8 +1931,10 @@ static void scm_stat_del(struct sock *skstruct scm_fp_list *fp =UNIXCB (skb).fp;struct unix_sock *u =unix_sk (sk); -if (unlikely (fp && fp->count)) +if (unlikely (fp && fp->count)) {atomic_sub (fp->count, &u->scm_stat.nr_fds); +unix_del_edges (fp); + } }/*
net/unix/garbage.c +89 -1
112 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 404/444 af_unix: Bulk update unix_tot_inflight/unix_inflight when queuing skb.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit 22c3c0c52d32f41cc38cd936ea0c93f22ced3315 upstream.
Currently, we track the number of inflight sockets in two variables. unix_tot_inflight is the total number of inflight AF_UNIX sockets on the host, and user->unix_inflight is the number of inflight fds per user.
We update them one by one in unix_inflight(), which can be done once in batch. Also, sendmsg() could fail even after unix_inflight(), then we need to acquire unix_gc_lock only to decrement the counters.
Let's bulk update the counters in unix_add_edges() and unix_del_edges(), which is called only for successfully passed fds.
--- net/unix/garbage.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-)
net/unix/garbage.c +7 -11
@@ -144,6 +144,7 @@ static void unix_free_vertices(struct sc }DEFINE_SPINLOCK (unix_gc_lock); +unsigned int unix_tot_inflight;void unix_add_edges (struct scm_fp_list *fpl,struct unix_sock *receiver) {
@@ -168,7 +169,10 @@ void unix_add_edges(struct scm_fp_list *unix_add_edge (fpl, edge); }while (i < fpl->count_unix); +WRITE_ONCE (unix_tot_inflight, unix_tot_inflight + fpl->count_unix); out: +WRITE_ONCE (fpl->user->unix_inflight, fpl->user->unix_inflight + fpl->count); +spin_unlock (&unix_gc_lock); fpl->inflight = true;
@@ -191,7 +195,10 @@ void unix_del_edges(struct scm_fp_list *unix_del_edge (fpl, edge); }while (i < fpl->count_unix); +WRITE_ONCE (unix_tot_inflight, unix_tot_inflight - fpl->count_unix); out: +WRITE_ONCE (fpl->user->unix_inflight, fpl->user->unix_inflight - fpl->count); +spin_unlock (&unix_gc_lock); fpl->inflight = false;
@@ -234,7 +241,6 @@ void unix_destroy_fpl(struct scm_fp_listunix_free_vertices (fpl); } -unsigned int unix_tot_inflight;static LIST_HEAD (gc_candidates);static LIST_HEAD (gc_inflight_list);
@@ -255,13 +261,8 @@ void unix_inflight(struct user_struct *uWARN_ON_ONCE (list_empty (&u->link)); } u->inflight++; - -/* Paired with READ_ONCE() in wait_for_unix_gc() */ -WRITE_ONCE (unix_tot_inflight, unix_tot_inflight +1 ); } -WRITE_ONCE (user->unix_inflight, user->unix_inflight +1 ); -spin_unlock (&unix_gc_lock); }
@@ -278,13 +279,8 @@ void unix_notinflight(struct user_struct u->inflight--;if (!u->inflight)list_del_init (&u->link); - -/* Paired with READ_ONCE() in wait_for_unix_gc() */ -WRITE_ONCE (unix_tot_inflight, unix_tot_inflight -1 ); } -WRITE_ONCE (user->unix_inflight, user->unix_inflight -1 ); -spin_unlock (&unix_gc_lock); }
Greg Kroah-Hartman
maintainerPATCH 405/444 af_unix: Iterate all vertices by DFS.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit 6ba76fd2848e107594ea4f03b737230f74bc23ea upstream.
The new GC will use a depth first search graph algorithm to find cyclic references. The algorithm visits every vertex exactly once.
Here, we implement the DFS part without recursion so that no one can abuse it.
unix_walk_scc() marks every vertex unvisited by initialising index as UNIX_VERTEX_INDEX_UNVISITED and iterates inflight vertices in unix_unvisited_vertices and call __unix_walk_scc() to start DFS from an arbitrary vertex.
__unix_walk_scc() iterates all edges starting from the vertex and explores the neighbour vertices with DFS using edge_stack.
After visiting all neighbours, __unix_walk_scc() moves the visited vertex to unix_visited_vertices so that unix_walk_scc() will not restart DFS from the visited vertex.
--- include/net/af_unix.h | 2 + net/unix/garbage.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+)
include/net/af_unix.h +2 -0
@@ -33,12 +33,14 @@ struct unix_vertex {struct list_head edges;struct list_head entry;unsigned long out_degree; +unsigned long index; };struct unix_edge {struct unix_sock *predecessor;struct unix_sock *successor;struct list_head vertex_entry; +struct list_head stack_entry; };struct sock *unix_peer_get (struct sock *sk);
net/unix/garbage.c +74 -0
92 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 406/444 af_unix: Detect Strongly Connected Components.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit 3484f063172dd88776b062046d721d7c2ae1af7c upstream.
In the new GC, we use a simple graph algorithm, Tarjan's Strongly Connected Components (SCC) algorithm, to find cyclic references.
The algorithm visits every vertex exactly once using depth-first search (DFS).
DFS starts by pushing an input vertex to a stack and assigning it a unique number. Two fields, index and lowlink, are initialised with the number, but lowlink could be updated later during DFS.
If a vertex has an edge to an unvisited inflight vertex, we visit it and do the same processing. So, we will have vertices in the stack in the order they appear and number them consecutively in the same order.
If a vertex has a back-edge to a visited vertex in the stack, we update the predecessor's lowlink with the successor's index.
After iterating edges from the vertex, we check if its index equals its lowlink.
If the lowlink is different from the index, it shows there was a back-edge. Then, we go backtracking and propagate the lowlink to its predecessor and resume the previous edge iteration from the next edge.
If the lowlink is the same as the index, we pop vertices before and including the vertex from the stack. Then, the set of vertices is SCC, possibly forming a cycle. At the same time, we move the vertices to unix_visited_vertices.
When we finish the algorithm, all vertices in each SCC will be linked via unix_vertex.scc_entry.
Let's take an example. We have a graph including five inflight vertices (F is not inflight):
A -> B -> C -> D -> E (-> F)
^ |
`---------'Suppose that we start DFS from C. We will visit C, D, and B first and initialise their index and lowlink. Then, the stack looks like this:
Quoted 1 line
B = (3, 3) (index, lowlink)
D = (2, 2)
C = (1, 1)When checking B's edge to C, we update B's lowlink with C's index and propagate it to D.
B = (3, 1) (index, lowlink)
Quoted 1 line
D = (2, 1)
C = (1, 1)
Next, we visit E, which has no edge to an inflight vertex.
Quoted 1 line
E = (4, 4) (index, lowlink)
B = (3, 1)
D = (2, 1)
C = (1, 1)When we leave from E, its index and lowlink are the same, so we pop E from the stack as single-vertex SCC. Next, we leave from B and D but do nothing because their lowlink are different from their index.
B = (3, 1) (index, lowlink)
D = (2, 1)Quoted 1 line
C = (1, 1)
Then, we leave from C, whose index and lowlink are the same, so we pop B, D and C as SCC.
Last, we do DFS for the rest of vertices, A, which is also a single-vertex SCC.
Finally, each unix_vertex.scc_entry is linked as follows:
A -. B -> C -> D E -. ^ | ^ | ^ | `--' `---------' `--'
We use SCC later to decide whether we can garbage-collect the sockets.
Note that we still cannot detect SCC properly if an edge points to an embryo socket. The following two patches will sort it out.
--- include/net/af_unix.h | 3 +++ net/unix/garbage.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-)
include/net/af_unix.h +3 -0
@@ -32,8 +32,11 @@ void wait_for_unix_gc(struct scm_fp_liststruct unix_vertex {struct list_head edges;struct list_head entry; +struct list_head scc_entry;unsigned long out_degree;unsigned long index; +unsigned long lowlink; +bool on_stack; };struct unix_edge {
net/unix/garbage.c +44 -2
67 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 407/444 af_unix: Save listener for embryo socket.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit aed6ecef55d70de3762ce41c561b7f547dbaf107 upstream.
This is a prep patch for the following change, where we need to fetch the listening socket from the successor embryo socket during GC.
We add a new field to struct unix_sock to save a pointer to a listening socket.
We set it when connect() creates a new socket, and clear it when accept() is called.
--- include/net/af_unix.h | 1 + net/unix/af_unix.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-)
include/net/af_unix.h +1 -0
@@ -83,6 +83,7 @@ struct unix_sock {struct path path;struct mutex iolock, bindlock;struct sock *peer; +struct sock *listener;struct unix_vertex *vertex;struct list_head link;unsigned long inflight;
net/unix/af_unix.c +4 -1
@@ -978,6 +978,7 @@ static struct sock *unix_create1(struct sk->sk_max_ack_backlog =READ_ONCE (net->unx.sysctl_max_dgram_qlen); sk->sk_destruct = unix_sock_destructor; u =unix_sk (sk); + u->listener =NULL ; u->inflight =0 ; u->vertex =NULL ; u->path.dentry =NULL ;
@@ -1582,6 +1583,7 @@ restart: newsk->sk_type = sk->sk_type;init_peercred (newsk); newu =unix_sk (newsk); + newu->listener = other;RCU_INIT_POINTER (newsk->sk_wq, &newu->peer_wq); otheru =unix_sk (other);
@@ -1677,8 +1679,8 @@ static int unix_accept(struct socket *so bool kern) {struct sock *sk = sock->sk; -struct sock *tsk;struct sk_buff *skb; +struct sock *tsk;int err; err = -EOPNOTSUPP ;
@@ -1703,6 +1705,7 @@ static int unix_accept(struct socket *so } tsk = skb->sk; +unix_sk (tsk)->listener =NULL ;skb_free_datagram (sk, skb);wake_up_interruptible (&unix_sk (sk)->peer_wait);
Greg Kroah-Hartman
maintainerPATCH 408/444 af_unix: Fix up unix_edge.successor for embryo socket.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit dcf70df2048d27c5d186f013f101a4aefd63aa41 upstream.
To garbage collect inflight AF_UNIX sockets, we must define the cyclic reference appropriately. This is a bit tricky if the loop consists of embryo sockets.
Suppose that the fd of AF_UNIX socket A is passed to D and the fd B to C and that C and D are embryo sockets of A and B, respectively. It may appear that there are two separate graphs, A (-> D) and B (-> C), but this is not correct.
A --. .-- B
X
C <-' `-> DNow, D holds A's refcount, and C has B's refcount, so unix_release() will never be called for A and B when we close() them. However, no one can call close() for D and C to free skbs holding refcounts of A and B because C/D is in A/B's receive queue, which should have been purged by unix_release() for A and B.
So, here's another type of cyclic reference. When a fd of an AF_UNIX socket is passed to an embryo socket, the reference is indirectly held by its parent listening socket.
.-> A .-> B | `- sk_receive_queue | `- sk_receive_queue | `- skb | `- skb | `- sk == C | `- sk == D | `- sk_receive_queue | `- sk_receive_queue
| - skb +---------' - skb +-.
| |
`---------------------------------------------------------'
Technically, the graph must be denoted as A <-> B instead of A (-> D) and B (-> C) to find such a cyclic reference without touching each socket's receive queue.
.-> A --. .-- B <-.
| X | == A <-> B
-- C <-' -> D --'
We apply this fixup during GC by fetching the real successor by unix_edge_successor().
When we call accept(), we clear unix_sock.listener under unix_gc_lock not to confuse GC.
--- include/net/af_unix.h | 1 + net/unix/af_unix.c | 2 +- net/unix/garbage.c | 20 +++++++++++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-)
include/net/af_unix.h +1 -0
@@ -24,6 +24,7 @@ void unix_inflight(struct user_struct *uvoid unix_notinflight (struct user_struct *user,struct file *fp);void unix_add_edges (struct scm_fp_list *fpl,struct unix_sock *receiver);void unix_del_edges (struct scm_fp_list *fpl); +void unix_update_edges (struct unix_sock *receiver);int unix_prepare_fpl (struct scm_fp_list *fpl);void unix_destroy_fpl (struct scm_fp_list *fpl);void unix_gc (void );
net/unix/af_unix.c +1 -1
@@ -1705,7 +1705,7 @@ static int unix_accept(struct socket *so } tsk = skb->sk; -unix_sk (tsk)->listener =NULL ; +unix_update_edges (unix_sk (tsk));skb_free_datagram (sk, skb);wake_up_interruptible (&unix_sk (sk)->peer_wait);
net/unix/garbage.c +19 -1
@@ -101,6 +101,17 @@ struct unix_sock *unix_get_socket(structreturn NULL ; } +static struct unix_vertex *unix_edge_successor (struct unix_edge *edge) +{ +/* If an embryo socket has a fd, +* the listener indirectly holds the fd's refcnt. +*/ +if (edge->successor->listener) +return unix_sk (edge->successor->listener)->vertex; + +return edge->successor->vertex; +} +static LIST_HEAD (unix_unvisited_vertices);enum unix_vertex_index {
@@ -209,6 +220,13 @@ out: fpl->inflight = false; } +void unix_update_edges (struct unix_sock *receiver) +{ +spin_lock (&unix_gc_lock); + receiver->listener =NULL ; +spin_unlock (&unix_gc_lock); +} +int unix_prepare_fpl (struct scm_fp_list *fpl) {struct unix_vertex *vertex;
@@ -268,7 +286,7 @@ next_vertex:/* Explore neighbour vertices (receivers of the current vertex's fd). */ list_for_each_entry (edge, &vertex->edges, vertex_entry) { -struct unix_vertex *next_vertex = edge->successor->vertex; +struct unix_vertex *next_vertex =unix_edge_successor (edge);if (!next_vertex)continue ;
Greg Kroah-Hartman
maintainerPATCH 409/444 af_unix: Save O(n) setup of Tarjans algo.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit ba31b4a4e1018f5844c6eb31734976e2184f2f9a upstream.
Before starting Tarjan's algorithm, we need to mark all vertices as unvisited. We can save this O(n) setup by reserving two special indices (0, 1) and using two variables.
The first time we link a vertex to unix_unvisited_vertices, we set unix_vertex_unvisited_index to index.
During DFS, we can see that the index of unvisited vertices is the same as unix_vertex_unvisited_index.
When we finalise SCC later, we set unix_vertex_grouped_index to each vertex's index.
Then, we can know (i) that the vertex is on the stack if the index of a visited vertex is >= 2 and (ii) that it is not on the stack and belongs to a different SCC if the index is unix_vertex_grouped_index.
After the whole algorithm, all indices of vertices are set as unix_vertex_grouped_index.
Next time we start DFS, we know that all unvisited vertices have unix_vertex_grouped_index, and we can use unix_vertex_unvisited_index as the not-on-stack marker.
To use the same variable in __unix_walk_scc(), we can swap unix_vertex_(grouped|unvisited)_index at the end of Tarjan's algorithm.
--- include/net/af_unix.h | 1 - net/unix/garbage.c | 26 +++++++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-)
include/net/af_unix.h +0 -1
@@ -37,7 +37,6 @@ struct unix_vertex {unsigned long out_degree;unsigned long index;unsigned long lowlink; -bool on_stack; };struct unix_edge {
net/unix/garbage.c +15 -11
@@ -115,16 +115,20 @@ static struct unix_vertex *unix_edge_sucstatic LIST_HEAD (unix_unvisited_vertices);enum unix_vertex_index { -UNIX_VERTEX_INDEX_UNVISITED , +UNIX_VERTEX_INDEX_MARK1 , +UNIX_VERTEX_INDEX_MARK2 ,UNIX_VERTEX_INDEX_START , }; +static unsigned long unix_vertex_unvisited_index =UNIX_VERTEX_INDEX_MARK1 ; +static void unix_add_edge (struct scm_fp_list *fpl,struct unix_edge *edge) {struct unix_vertex *vertex = edge->predecessor->vertex;if (!vertex) { vertex =list_first_entry (&fpl->vertices,typeof (*vertex), entry); + vertex->index = unix_vertex_unvisited_index; vertex->out_degree =0 ;INIT_LIST_HEAD (&vertex->edges);
@@ -265,6 +269,7 @@ void unix_destroy_fpl(struct scm_fp_list }static LIST_HEAD (unix_visited_vertices); +static unsigned long unix_vertex_grouped_index =UNIX_VERTEX_INDEX_MARK2 ;static void __unix_walk_scc (struct unix_vertex *vertex) {
@@ -274,10 +279,10 @@ static void __unix_walk_scc(struct unix_LIST_HEAD (edge_stack); next_vertex: -/* Push vertex to vertex_stack. +/* Push vertex to vertex_stack and mark it as on-stack +* (index >= UNIX_VERTEX_INDEX_START). * The vertex will be popped when finalising SCC later. */ - vertex->on_stack = true;list_add (&vertex->scc_entry, &vertex_stack); vertex->index = index;
@@ -291,7 +296,7 @@ next_vertex:if (!next_vertex)continue ; -if (next_vertex->index ==UNIX_VERTEX_INDEX_UNVISITED ) { +if (next_vertex->index == unix_vertex_unvisited_index) {/* Iterative deepening depth first search * * 1. Push a forward edge to edge_stack and set
@@ -317,7 +322,7 @@ prev_vertex:* to skip SCC finalisation. */ vertex->lowlink =min (vertex->lowlink, next_vertex->lowlink); - }else if (next_vertex->on_stack) { + }else if (next_vertex->index != unix_vertex_grouped_index) {/* Loop detected by a back/cross edge. * * The successor is on vertex_stack, so two vertices are
@@ -344,7 +349,8 @@ prev_vertex:/* Don't restart DFS from this vertex in unix_walk_scc(). */ list_move_tail (&vertex->entry, &unix_visited_vertices); - vertex->on_stack = false; +/* Mark vertex as off-stack. */ + vertex->index = unix_vertex_grouped_index; }list_del (&scc);
@@ -357,20 +363,18 @@ prev_vertex:static void unix_walk_scc (void ) { -struct unix_vertex *vertex; - -list_for_each_entry (vertex, &unix_unvisited_vertices, entry) - vertex->index =UNIX_VERTEX_INDEX_UNVISITED ; -/* Visit every vertex exactly once. * __unix_walk_scc() moves visited vertices to unix_visited_vertices. */ while (!list_empty (&unix_unvisited_vertices)) { +struct unix_vertex *vertex; + vertex =list_first_entry (&unix_unvisited_vertices,typeof (*vertex), entry);__unix_walk_scc (vertex); }list_replace_init (&unix_visited_vertices, &unix_unvisited_vertices); +swap (unix_vertex_unvisited_index, unix_vertex_grouped_index); }static LIST_HEAD (gc_candidates);