6.17.8-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainerPATCH 679/849 ima: dont clear IMA_DIGSIG flag when setting or removing non-IMA xattr
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Coiby Xu <[email protected]>
[ Upstream commit 88b4cbcf6b041ae0f2fc8a34554a5b6a83a2b7cd ]
Currently when both IMA and EVM are in fix mode, the IMA signature will be reset to IMA hash if a program first stores IMA signature in security.ima and then writes/removes some other security xattr for the file.
For example, on Fedora, after booting the kernel with "ima_appraise=fix evm=fix ima_policy=appraise_tcb" and installing rpm-plugin-ima, installing/reinstalling a package will not make good reference IMA signature generated. Instead IMA hash is generated,
# getfattr -m - -d -e hex /usr/bin/bash
# file: usr/bin/bash
security.ima=0x0404...This happens because when setting security.selinux, the IMA_DIGSIG flag that had been set early was cleared. As a result, IMA hash is generated when the file is closed.
Similarly, IMA signature can be cleared on file close after removing security xattr like security.evm or setting/removing ACL.
Prevent replacing the IMA file signature with a file hash, by preventing the IMA_DIGSIG flag from being reset.
Here's a minimal C reproducer which sets security.selinux as the last step which can also replaced by removing security.evm or setting ACL,
#include <stdio.h>
#include <sys/xattr.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main() {
const char* file_path = "/usr/sbin/test_binary";
const char* hex_string = "030204d33204490066306402304";
int length = strlen(hex_string);
char* ima_attr_value;
int fd;
fd = open(file_path, O_WRONLY|O_CREAT|O_EXCL, 0644);
if (fd == -1) {
perror("Error opening file");
return 1;
}
ima_attr_value = (char*)malloc(length / 2 );
for (int i = 0, j = 0; i < length; i += 2, j++) {
sscanf(hex_string + i, "%2hhx", &ima_attr_value[j]);
}
if (fsetxattr(fd, "security.ima", ima_attr_value, length/2, 0) == -1) {
perror("Error setting extended attribute");
close(fd);
return 1;
}
const char* selinux_value= "system_u:object_r:bin_t:s0";
if (fsetxattr(fd, "security.selinux", selinux_value, strlen(selinux_value), 0) == -1) {
perror("Error setting extended attribute");
close(fd);
return 1;
}
close(fd);
return 0;
}--- security/integrity/ima/ima_appraise.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
security/integrity/ima/ima_appraise.c +18 -5
@@ -694,6 +694,15 @@ static int ima_protect_xattr(struct dentry *dentry, const char *xattr_name,return 0 ; } +/* +* ima_reset_appraise_flags - reset ima_iint_cache flags +* +* @digsig: whether to clear/set IMA_DIGSIG flag, tristate values +* 0: clear IMA_DIGSIG +* 1: set IMA_DIGSIG +* -1: don't change IMA_DIGSIG +* +*/ static void ima_reset_appraise_flags (struct inode *inode,int digsig) {struct ima_iint_cache *iint;
@@ -706,9 +715,9 @@ static void ima_reset_appraise_flags(struct inode *inode, int digsig)return ; iint->measured_pcrs =0 ;set_bit (IMA_CHANGE_XATTR , &iint->atomic_flags); -if (digsig) +if (digsig ==1 )set_bit (IMA_DIGSIG , &iint->atomic_flags); -else +else if (digsig ==0 )clear_bit (IMA_DIGSIG , &iint->atomic_flags); }
@@ -794,6 +803,8 @@ static int ima_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, digsig = (xvalue->type ==EVM_IMA_XATTR_DIGSIG ); }else if (!strcmp (xattr_name,XATTR_NAME_EVM ) && xattr_value_len >0 ) { digsig = (xvalue->type ==EVM_XATTR_PORTABLE_DIGSIG ); + }else { + digsig =-1 ; }if (result ==1 ||evm_revalidate_status (xattr_name)) {ima_reset_appraise_flags (d_backing_inode (dentry), digsig);
@@ -807,7 +818,7 @@ static int ima_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name, struct posix_acl *kacl) { if (evm_revalidate_status(acl_name)) - ima_reset_appraise_flags(d_backing_inode(dentry), 0); + ima_reset_appraise_flags(d_backing_inode(dentry), -1);return 0 ; }
@@ -815,11 +826,13 @@ static int ima_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,static int ima_inode_removexattr (struct mnt_idmap *idmap,struct dentry *dentry,const char *xattr_name) { -int result; +int result, digsig =-1 ; result =ima_protect_xattr (dentry, xattr_name,NULL ,0 );if (result ==1 ||evm_revalidate_status (xattr_name)) { -ima_reset_appraise_flags (d_backing_inode (dentry),0 ); +if (!strcmp (xattr_name,XATTR_NAME_IMA )) + digsig =0 ; +ima_reset_appraise_flags (d_backing_inode (dentry), digsig);if (result ==1 ) result =0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 680/849 usb: xhci-pci: Fix USB2-only root hub registration
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Pecio <[email protected]>
[ Upstream commit 8607edcd1748503f4f58e66ca0216170f260c79b ]
A recent change to hide USB3 root hubs of USB2-only controllers broke registration of USB2 root hubs - allow_single_roothub is set too late, and by this time xhci_run() has already deferred root hub registration until after the shared HCD is added, which will never happen.
This makes such controllers unusable, but testers didn't notice since they were only bothered by warnings about empty USB3 root hubs. The bug causes problems to other people who actually use such HCs and I was able to confirm it on an ordinary HC by patching to ignore USB3 ports.
Setting allow_single_roothub during early setup fixes things.
--- drivers/usb/host/xhci-pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/host/xhci-pci.c +2 -1
@@ -582,6 +582,8 @@ static int xhci_pci_setup(struct usb_hcd *hcd)if (!usb_hcd_is_primary_hcd (hcd))return 0 ; + xhci->allow_single_roothub =1 ; +if (xhci->quirks &XHCI_PME_STUCK_QUIRK )xhci_pme_acpi_rtd3_enable (pdev);
@@ -637,7 +639,6 @@ int xhci_pci_common_probe(struct pci_dev *dev, const struct pci_device_id *id) xhci =hcd_to_xhci (hcd); xhci->reset = reset; - xhci->allow_single_roothub =1 ;if (!xhci_has_one_roothub (xhci)) { xhci->shared_hcd =usb_create_shared_hcd (&xhci_pci_hc_driver, &dev->dev,pci_name (dev), hcd);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 681/849 drm/amd/display: Add fallback path for YCBCR422
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
[ Upstream commit db291ed1732e02e79dca431838713bbf602bda1c ]
[Why]
DP validation may fail with multiple displays and higher color depths. The sink may support others though.
[How]
When DP bandwidth validation fails, progressively fallback through:
- YUV422 8bpc (bandwidth efficient)
- YUV422 6bpc (reduced color depth)
- YUV420 (last resort)
This resolves cases where displays would show no image due to insufficient DP link bandwidth for the requested RGB mode.
--- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 45 +++++++++++++++---- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 1 + 2 files changed, 37 insertions(+), 9 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +36 -9
@@ -6405,7 +6405,8 @@ static void fill_stream_properties_from_drm_display_mode( && aconnector->force_yuv420_output) timing_out->pixel_encoding =PIXEL_ENCODING_YCBCR420 ; else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR422) - && stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) + && aconnector + && aconnector->force_yuv422_output) timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR422; else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR444) && stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
@@ -7665,6 +7666,7 @@ create_validate_stream_for_sink(struct drm_connector *connector, bpc_limit =8 ; do { + drm_dbg_kms(connector->dev, "Trying with %d bpc\n", requested_bpc); stream = create_stream_for_sink(connector, drm_mode, dm_state, old_stream, requested_bpc);
@@ -7700,16 +7702,41 @@ create_validate_stream_for_sink(struct drm_connector *connector, }while (stream ==NULL && requested_bpc >= bpc_limit); -if ((dc_result ==DC_FAIL_ENC_VALIDATE || - dc_result ==DC_EXCEED_DONGLE_CAP ) && - !aconnector->force_yuv420_output) { -DRM_DEBUG_KMS ("%s:%d Retry forcing yuv420 encoding\n" , - __func__, __LINE__); - - aconnector->force_yuv420_output = true; +switch (dc_result) { +/* +* If we failed to validate DP bandwidth stream with the requested RGB color depth, +* we try to fallback and configure in order: +* YUV422 (8bpc, 6bpc) +* YUV420 (8bpc, 6bpc) +*/ +case DC_FAIL_ENC_VALIDATE : +case DC_EXCEED_DONGLE_CAP : +case DC_NO_DP_LINK_BANDWIDTH : +/* recursively entered twice and already tried both YUV422 and YUV420 */ +if (aconnector->force_yuv422_output && aconnector->force_yuv420_output) +break ; +/* first failure; try YUV422 */ +if (!aconnector->force_yuv422_output) { +drm_dbg_kms (connector->dev,"%s:%d Validation failed with %d, retrying w/ YUV422\n" , + __func__, __LINE__, dc_result); + aconnector->force_yuv422_output = true; +/* recursively entered and YUV422 failed, try YUV420 */ + }else if (!aconnector->force_yuv420_output) { +drm_dbg_kms (connector->dev,"%s:%d Validation failed with %d, retrying w/ YUV420\n" , + __func__, __LINE__, dc_result); + aconnector->force_yuv420_output = true; + } stream =create_validate_stream_for_sink (connector, drm_mode, - dm_state, old_stream); + dm_state, old_stream); + aconnector->force_yuv422_output = false; aconnector->force_yuv420_output = false; +break ; +case DC_OK : +break ; +default : +drm_dbg_kms (connector->dev,"%s:%d Unhandled validation failure %d\n" , + __func__, __LINE__, dc_result); +break ; }return stream;
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +1 -0
@@ -790,6 +790,7 @@ struct amdgpu_dm_connector {bool fake_enable;bool force_yuv420_output; +bool force_yuv422_output;struct dsc_preferred_settings dsc_settings;union dp_downstream_port_present mst_downstream_port_present;/* Cached display modes */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 682/849 ACPICA: Update dsmethod.c to get rid of unused variable warning
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Saket Dumbre <[email protected]>
[ Upstream commit 761dc71c6020d6aa68666e96373342d49a7e9d0a ]
All the 3 major C compilers (MSVC, GCC, LLVM/Clang) warn about the unused variable i after the removal of its usage by PR #1031 addressing Issue #1027
--- drivers/acpi/acpica/dsmethod.c | 1 - 1 file changed, 1 deletion(-)
drivers/acpi/acpica/dsmethod.c +0 -1
@@ -462,7 +462,6 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,struct acpi_walk_state *next_walk_state =NULL ;union acpi_operand_object *obj_desc;struct acpi_evaluate_info *info; -u32 i;ACPI_FUNCTION_TRACE_PTR (ds_call_control_method, this_walk_state);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 683/849 RDMA/bnxt_re: Fix a potential memory leak in destroy_gsi_sqp
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: YanLong Dai <[email protected]>
[ Upstream commit 88de89f184661ebb946804a5abdf2bdec7f0a7ab ]
The current error handling path in bnxt_re_destroy_gsi_sqp() could lead to a resource leak. When bnxt_qplib_destroy_qp() fails, the function jumps to the 'fail' label and returns immediately, skipping the call to bnxt_qplib_free_qp_res().
Continue the resource teardown even if bnxt_qplib_destroy_qp() fails, which aligns with the driver's general error handling strategy and prevents the potential leak.
--- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
drivers/infiniband/hw/bnxt_re/ib_verbs.c +3 -8
@@ -911,7 +911,7 @@ void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp,spin_unlock_irqrestore (&qp->scq->cq_lock, flags); } -static int bnxt_re_destroy_gsi_sqp (struct bnxt_re_qp *qp) +static void bnxt_re_destroy_gsi_sqp (struct bnxt_re_qp *qp) {struct bnxt_re_qp *gsi_sqp;struct bnxt_re_ah *gsi_sah;
@@ -931,10 +931,9 @@ static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)ibdev_dbg (&rdev->ibdev,"Destroy the shadow QP\n" ); rc =bnxt_qplib_destroy_qp (&rdev->qplib_res, &gsi_sqp->qplib_qp); -if (rc) { +if (rc)ibdev_err (&rdev->ibdev,"Destroy Shadow QP failed" ); - goto fail; - } +bnxt_qplib_free_qp_res (&rdev->qplib_res, &gsi_sqp->qplib_qp);/* remove from active qp list */
@@ -949,10 +948,6 @@ static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp) rdev->gsi_ctx.gsi_sqp =NULL ; rdev->gsi_ctx.gsi_sah =NULL ; rdev->gsi_ctx.sqp_tbl =NULL ; - -return 0 ; -fail: -return rc; }/* Queue Pairs */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 684/849 RDMA/irdma: Fix SD index calculation
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacob Moroni <[email protected]>
[ Upstream commit 8d158f47f1f33d8747e80c3afbea5aa337e59d41 ]
In some cases, it is possible for pble_rsrc->next_fpm_addr to be larger than u32, so remove the u32 cast to avoid unintentional truncation.
This fixes the following error that can be observed when registering massive memory regions:
[ 447.227494] (NULL ib_device): cqp opcode = 0x1f maj_err_code = 0xffff min_err_code = 0x800c [ 447.227505] (NULL ib_device): [Update PE SDs Cmd Error][op_code=21] status=-5 waiting=1 completion_err=1 maj=0xffff min=0x800c
--- drivers/infiniband/hw/irdma/pble.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/irdma/pble.c +1 -1
@@ -71,7 +71,7 @@ int irdma_hmc_init_pble(struct irdma_sc_dev *dev,static void get_sd_pd_idx (struct irdma_hmc_pble_rsrc *pble_rsrc,struct sd_pd_idx *idx) { - idx->sd_idx = (u32 )pble_rsrc->next_fpm_addr /IRDMA_HMC_DIRECT_BP_SIZE ; + idx->sd_idx = pble_rsrc->next_fpm_addr /IRDMA_HMC_DIRECT_BP_SIZE ; idx->pd_idx = (u32)(pble_rsrc->next_fpm_addr /IRDMA_HMC_PAGED_BP_SIZE ); idx->rel_pd_idx = (idx->pd_idx %IRDMA_HMC_PD_CNT_IN_SD ); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 685/849 RDMA/irdma: Remove unused struct irdma_cq fields
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacob Moroni <[email protected]>
[ Upstream commit 880245fd029a8f8ee8fd557c2681d077c1b1a959 ]
These fields were set but not used anywhere, so remove them.
Stable-dep-of: 5575b7646b94 ("RDMA/irdma: Set irdma_cq cq_num field during CQ create")
--- drivers/infiniband/hw/irdma/verbs.c | 3 --- drivers/infiniband/hw/irdma/verbs.h | 6 ------ 2 files changed, 9 deletions(-)
drivers/infiniband/hw/irdma/verbs.c +0 -3
@@ -2116,8 +2116,6 @@ static int irdma_create_cq(struct ib_cq *ibcq, goto cq_free_rsrc; } - iwcq->iwpbl = iwpbl; - iwcq->cq_mem_size =0 ; cqmr = &iwpbl->cq_mr; if (rf->sc_dev.hw_attrs.uk_attrs.feature_flags &
@@ -2132,7 +2130,6 @@ static int irdma_create_cq(struct ib_cq *ibcq, err_code = -EPROTO ; goto cq_free_rsrc; } - iwcq->iwpbl_shadow = iwpbl_shadow; cqmr_shadow = &iwpbl_shadow->cq_mr; info.shadow_area_pa = cqmr_shadow->cq_pbl.addr; cqmr->split = true;
drivers/infiniband/hw/irdma/verbs.h +0 -6
@@ -115,21 +115,15 @@ struct irdma_mr {struct irdma_cq {struct ib_cq ibcq;struct irdma_sc_cq sc_cq; -u16 cq_head; -u16 cq_size;u16 cq_num;bool user_mode;atomic_t armed;enum irdma_cmpl_notify last_notify; -u32 polled_cmpls; -u32 cq_mem_size;struct irdma_dma_mem kmem;struct irdma_dma_mem kmem_shadow;struct completion free_cq;refcount_t refcnt;spinlock_t lock;/* for poll cq */ -struct irdma_pbl *iwpbl; -struct irdma_pbl *iwpbl_shadow;struct list_head resize_list;struct irdma_cq_poll_info cur_cqe;struct list_head cmpl_generated;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 686/849 RDMA/irdma: Set irdma_cq cq_num field during CQ create
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacob Moroni <[email protected]>
[ Upstream commit 5575b7646b94c0afb0f4c0d86e00e13cf3397a62 ]
The driver maintains a CQ table that is used to ensure that a CQ is still valid when processing CQ related AEs. When a CQ is destroyed, the table entry is cleared, using irdma_cq.cq_num as the index. This field was never being set, so it was just always clearing out entry 0.
Additionally, the cq_num field size was increased to accommodate HW supporting more than 64K CQs.
--- drivers/infiniband/hw/irdma/verbs.c | 1 + drivers/infiniband/hw/irdma/verbs.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
drivers/infiniband/hw/irdma/verbs.c +1 -0
@@ -2078,6 +2078,7 @@ static int irdma_create_cq(struct ib_cq *ibcq,spin_lock_init (&iwcq->lock);INIT_LIST_HEAD (&iwcq->resize_list);INIT_LIST_HEAD (&iwcq->cmpl_generated); + iwcq->cq_num = cq_num; info.dev = dev; ukinfo->cq_size =max (entries,4 ); ukinfo->cq_id = cq_num;
drivers/infiniband/hw/irdma/verbs.h +1 -1
@@ -115,7 +115,7 @@ struct irdma_mr {struct irdma_cq {struct ib_cq ibcq;struct irdma_sc_cq sc_cq; -u16 cq_num; +u32 cq_num;bool user_mode;atomic_t armed;enum irdma_cmpl_notify last_notify;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 687/849 RDMA/uverbs: Fix umem release in UVERBS_METHOD_CQ_CREATE
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuhao Fu <[email protected]>
[ Upstream commit d8713158faad0fd4418cb2f4e432c3876ad53a1f ]
In UVERBS_METHOD_CQ_CREATE, umem should be released if anything goes wrong. Currently, if create_cq_umem fails, umem would not be released or referenced, causing a possible leak.
In this patch, we release umem at UVERBS_METHOD_CQ_CREATE, the driver should not release umem if it returns an error code.
--- drivers/infiniband/core/uverbs_std_types_cq.c | 1 + drivers/infiniband/hw/efa/efa_verbs.c | 16 +++++++--------- 2 files changed, 8 insertions(+), 9 deletions(-)
drivers/infiniband/core/uverbs_std_types_cq.c +1 -0
@@ -206,6 +206,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(return ret; err_free: +ib_umem_release (umem);rdma_restrack_put (&cq->res);kfree (cq); err_event_file:
drivers/infiniband/hw/efa/efa_verbs.c +7 -9
@@ -1216,13 +1216,13 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,if (umem->length < cq->size) {ibdev_dbg (&dev->ibdev,"External memory too small\n" ); err = -EINVAL ; - goto err_free_mem; + goto err_out; }if (!ib_umem_is_contiguous (umem)) {ibdev_dbg (&dev->ibdev,"Non contiguous CQ unsupported\n" ); err = -EINVAL ; - goto err_free_mem; + goto err_out; } cq->cpu_addr =NULL ;
@@ -1251,7 +1251,7 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, err =efa_com_create_cq (&dev->edev, ¶ms, &result);if (err) - goto err_free_mem; + goto err_free_mapped; resp.db_off = result.db_off; resp.cq_idx = result.cq_idx;
@@ -1299,12 +1299,10 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,efa_cq_user_mmap_entries_remove (cq); err_destroy_cq:efa_destroy_cq_idx (dev, cq->cq_idx); -err_free_mem: -if (umem) -ib_umem_release (umem); -else -efa_free_mapped (dev, cq->cpu_addr, cq->dma_addr, cq->size,DMA_FROM_DEVICE ); - +err_free_mapped: +if (!umem) +efa_free_mapped (dev, cq->cpu_addr, cq->dma_addr, cq->size, +DMA_FROM_DEVICE ); err_out:atomic64_inc (&dev->stats.create_cq_err);return err;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 688/849 RDMA/hns: Fix recv CQ and QP cache affinity
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengchang Tang <[email protected]>
[ Upstream commit c4b67b514af8c2d73c64b36e0cd99e9b26b9ac82 ]
Currently driver enforces affinity between QP cache and send CQ cache, which helps improve the performance of sending, but doesn't set affinity with recv CQ cache, resulting in suboptimal performance of receiving.
Use one CQ bank per context to ensure the affinity among QP, send CQ and recv CQ. For kernel ULP, CQ bank is fixed to 0.
--- drivers/infiniband/hw/hns/hns_roce_cq.c | 58 +++++++++++++++++++-- drivers/infiniband/hw/hns/hns_roce_device.h | 4 ++ drivers/infiniband/hw/hns/hns_roce_main.c | 4 ++ 3 files changed, 63 insertions(+), 3 deletions(-)
drivers/infiniband/hw/hns/hns_roce_cq.c +55 -3
@@ -30,6 +30,7 @@* SOFTWARE. */ +#include <linux/pci.h> #include <rdma/ib_umem.h> #include <rdma/uverbs_ioctl.h> #include "hns_roce_device.h"
@@ -37,6 +38,43 @@#include "hns_roce_hem.h" #include "hns_roce_common.h" +void hns_roce_put_cq_bankid_for_uctx (struct hns_roce_ucontext *uctx) +{ +struct hns_roce_dev *hr_dev =to_hr_dev (uctx->ibucontext.device); +struct hns_roce_cq_table *cq_table = &hr_dev->cq_table; + +if (hr_dev->pci_dev->revision <PCI_REVISION_ID_HIP09 ) +return ; + +mutex_lock (&cq_table->bank_mutex); + cq_table->ctx_num[uctx->cq_bank_id]--; +mutex_unlock (&cq_table->bank_mutex); +} + +void hns_roce_get_cq_bankid_for_uctx (struct hns_roce_ucontext *uctx) +{ +struct hns_roce_dev *hr_dev =to_hr_dev (uctx->ibucontext.device); +struct hns_roce_cq_table *cq_table = &hr_dev->cq_table; +u32 least_load = cq_table->ctx_num[0 ]; +u8 bankid =0 ; +u8 i; + +if (hr_dev->pci_dev->revision <PCI_REVISION_ID_HIP09 ) +return ; + +mutex_lock (&cq_table->bank_mutex); +for (i =1 ; i <HNS_ROCE_CQ_BANK_NUM ; i++) { +if (cq_table->ctx_num[i] < least_load) { + least_load = cq_table->ctx_num[i]; + bankid = i; + } + } + cq_table->ctx_num[bankid]++; +mutex_unlock (&cq_table->bank_mutex); + + uctx->cq_bank_id = bankid; +} +static u8 get_least_load_bankid_for_cq (struct hns_roce_bank *bank) {u32 least_load = bank[0 ].inuse;
@@ -55,7 +93,21 @@ static u8 get_least_load_bankid_for_cq(struct hns_roce_bank *bank)return bankid; } -static int alloc_cqn (struct hns_roce_dev *hr_dev,struct hns_roce_cq *hr_cq) +static u8 select_cq_bankid (struct hns_roce_dev *hr_dev, +struct hns_roce_bank *bank,struct ib_udata *udata) +{ +struct hns_roce_ucontext *uctx = udata ? + rdma_udata_to_drv_context(udata, struct hns_roce_ucontext, + ibucontext) :NULL ; + +if (hr_dev->pci_dev->revision >=PCI_REVISION_ID_HIP09 ) +return uctx ? uctx->cq_bank_id :0 ; + +return get_least_load_bankid_for_cq (bank); +} + +static int alloc_cqn (struct hns_roce_dev *hr_dev,struct hns_roce_cq *hr_cq, +struct ib_udata *udata) {struct hns_roce_cq_table *cq_table = &hr_dev->cq_table;struct hns_roce_bank *bank;
@@ -63,7 +115,7 @@ static int alloc_cqn(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)int id;mutex_lock (&cq_table->bank_mutex); - bankid =get_least_load_bankid_for_cq (cq_table->bank); + bankid =select_cq_bankid (hr_dev, cq_table->bank, udata); bank = &cq_table->bank[bankid]; id =ida_alloc_range (&bank->ida, bank->min, bank->max,GFP_KERNEL );
@@ -396,7 +448,7 @@ int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr, goto err_cq_buf; } - ret =alloc_cqn (hr_dev, hr_cq); + ret =alloc_cqn (hr_dev, hr_cq, udata);if (ret) {ibdev_err (ibdev,"failed to alloc CQN, ret = %d.\n" , ret); goto err_cq_db;
drivers/infiniband/hw/hns/hns_roce_device.h +4 -0
@@ -217,6 +217,7 @@ struct hns_roce_ucontext {struct mutex page_mutex;struct hns_user_mmap_entry *db_mmap_entry;u32 config; +u8 cq_bank_id; };struct hns_roce_pd {
@@ -495,6 +496,7 @@ struct hns_roce_cq_table {struct hns_roce_hem_table table;struct hns_roce_bank bank[HNS_ROCE_CQ_BANK_NUM ];struct mutex bank_mutex; +u32 ctx_num[HNS_ROCE_CQ_BANK_NUM ]; };struct hns_roce_srq_table {
@@ -1305,5 +1307,7 @@ hns_roce_user_mmap_entry_insert(struct ib_ucontext *ucontext, u64 address,size_t length, enum hns_roce_mmap_type mmap_type);bool check_sl_valid (struct hns_roce_dev *hr_dev,u8 sl); +void hns_roce_put_cq_bankid_for_uctx (struct hns_roce_ucontext *uctx); +void hns_roce_get_cq_bankid_for_uctx (struct hns_roce_ucontext *uctx);#endif /* _HNS_ROCE_DEVICE_H */
drivers/infiniband/hw/hns/hns_roce_main.c +4 -0
@@ -425,6 +425,8 @@ static int hns_roce_alloc_ucontext(struct ib_ucontext *uctx,if (ret) goto error_fail_copy_to_udata; +hns_roce_get_cq_bankid_for_uctx (context); +return 0 ; error_fail_copy_to_udata:
@@ -447,6 +449,8 @@ static void hns_roce_dealloc_ucontext(struct ib_ucontext *ibcontext)struct hns_roce_ucontext *context =to_hr_ucontext (ibcontext);struct hns_roce_dev *hr_dev =to_hr_dev (ibcontext->device); +hns_roce_put_cq_bankid_for_uctx (context); +if (hr_dev->caps.flags &HNS_ROCE_CAP_FLAG_CQ_RECORD_DB || hr_dev->caps.flags &HNS_ROCE_CAP_FLAG_QP_RECORD_DB )mutex_destroy (&context->page_mutex);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 689/849 RDMA/hns: Fix the modification of max_send_sge
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: wenglianfa <[email protected]>
[ Upstream commit f5a7cbea5411668d429eb4ffe96c4063fe8dac9e ]
The actual sge number may exceed the value specified in init_attr->cap when HW needs extra sge to enable inline feature. Since these extra sges are not expected by ULP, return the user-specified value to ULP instead of the expanded sge number.
--- drivers/infiniband/hw/hns/hns_roce_qp.c | 2 -- 1 file changed, 2 deletions(-)
drivers/infiniband/hw/hns/hns_roce_qp.c +0 -2
@@ -662,7 +662,6 @@ static int set_user_sq_size(struct hns_roce_dev *hr_dev, hr_qp->sq.wqe_shift = ucmd->log_sq_stride; hr_qp->sq.wqe_cnt = cnt; - cap->max_send_sge = hr_qp->sq.max_gs;return 0 ; }
@@ -744,7 +743,6 @@ static int set_kernel_sq_size(struct hns_roce_dev *hr_dev,/* sync the parameters of kernel QP to user's configuration */ cap->max_send_wr = cnt; - cap->max_send_sge = hr_qp->sq.max_gs;return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 690/849 RDMA/hns: Fix wrong WQE data when QP wraps around
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxian Huang <[email protected]>
[ Upstream commit fe9622011f955e35ba84d3af7b2f2fed31cf8ca1 ]
When QP wraps around, WQE data from the previous use at the same position still remains as driver does not clear it. The WQE field layout differs across different opcodes, causing that the fields that are not explicitly assigned for the current opcode retain stale values, and are issued to HW by mistake. Such fields are as follows:
* MSG_START_SGE_IDX field in ATOMIC WQE
* BLOCK_SIZE and ZBVA fields in FRMR WQE
* DirectWQE fields when DirectWQE not used
For ATOMIC WQE, always set the latest sge index in MSG_START_SGE_IDX as required by HW.
For FRMR WQE and DirectWQE, clear only those unassigned fields instead of the entire WQE to avoid performance penalty.
--- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +8 -3
@@ -165,6 +165,8 @@ static void set_frmr_seg(struct hns_roce_v2_rc_send_wqe *rc_sq_wqe,hr_reg_write (fseg,FRMR_PBL_BUF_PG_SZ ,to_hr_hw_page_shift (mr->pbl_mtr.hem_cfg.buf_pg_shift));hr_reg_clear (fseg,FRMR_BLK_MODE ); +hr_reg_clear (fseg,FRMR_BLOCK_SIZE ); +hr_reg_clear (fseg,FRMR_ZBVA ); } static void set_atomic_seg(const struct ib_send_wr *wr,
@@ -339,9 +341,6 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr,int j =0 ;int i; -hr_reg_write (rc_sq_wqe,RC_SEND_WQE_MSG_START_SGE_IDX , - (*sge_ind) & (qp->sge.sge_cnt -1 )); -hr_reg_write (rc_sq_wqe,RC_SEND_WQE_INLINE , !!(wr->send_flags &IB_SEND_INLINE ));if (wr->send_flags &IB_SEND_INLINE )
@@ -586,6 +585,9 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp,hr_reg_write (rc_sq_wqe,RC_SEND_WQE_CQE , (wr->send_flags &IB_SEND_SIGNALED ) ?1 :0 ); +hr_reg_write (rc_sq_wqe,RC_SEND_WQE_MSG_START_SGE_IDX , + curr_idx & (qp->sge.sge_cnt -1 )); +if (wr->opcode ==IB_WR_ATOMIC_CMP_AND_SWP || wr->opcode ==IB_WR_ATOMIC_FETCH_AND_ADD ) {if (msg_len !=ATOMIC_WR_LEN )
@@ -734,6 +736,9 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, owner_bit = ~(((qp->sq.head + nreq) >>ilog2 (qp->sq.wqe_cnt)) &0x1 ); +/* RC and UD share the same DirectWQE field layout */ + ((struct hns_roce_v2_rc_send_wqe *)wqe)->byte_4 =0 ; +/* Corresponding to the QP type, wqe process separately */ if (ibqp->qp_type ==IB_QPT_RC ) ret =set_rc_wqe (qp, wr, wqe, &sge_idx, owner_bit);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 691/849 btrfs: fix memory leak of qgroup_list in btrfs_add_qgroup_relation
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shardul Bankar <[email protected]>
[ Upstream commit f260c6aff0b8af236084012d14f9f1bf792ea883 ]
When btrfs_add_qgroup_relation() is called with invalid qgroup levels (src >= dst), the function returns -EINVAL directly without freeing the preallocated qgroup_list structure passed by the caller. This causes a memory leak because the caller unconditionally sets the pointer to NULL after the call, preventing any cleanup.
The issue occurs because the level validation check happens before the mutex is acquired and before any error handling path that would free the prealloc pointer. On this early return, the cleanup code at the 'out' label (which includes kfree(prealloc)) is never reached.
In btrfs_ioctl_qgroup_assign(), the code pattern is:
prealloc = kzalloc(sizeof(*prealloc), GFP_KERNEL);
ret = btrfs_add_qgroup_relation(trans, sa->src, sa->dst, prealloc);
prealloc = NULL; // Always set to NULL regardless of return value
...
kfree(prealloc); // This becomes kfree(NULL), does nothingWhen the level check fails, 'prealloc' is never freed by either the callee or the caller, resulting in a 64-byte memory leak per failed operation. This can be triggered repeatedly by an unprivileged user with access to a writable btrfs mount, potentially exhausting kernel memory.
Fix this by freeing prealloc before the early return, ensuring prealloc is always freed on all error paths.
--- fs/btrfs/qgroup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/btrfs/qgroup.c +3 -1
@@ -1539,8 +1539,10 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, u64 src, u64 dstASSERT (prealloc);/* Check the level of src and dst first */ -if (btrfs_qgroup_level (src) >=btrfs_qgroup_level (dst)) +if (btrfs_qgroup_level (src) >=btrfs_qgroup_level (dst)) { +kfree (prealloc);return -EINVAL ; + }mutex_lock (&fs_info->qgroup_ioctl_lock);if (!fs_info->quota_root) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 692/849 btrfs: mark dirty extent range for out of bound prealloc extents
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: austinchang <[email protected]>
[ Upstream commit 3b1a4a59a2086badab391687a6a0b86e03048393 ]
In btrfs_fallocate(), when the allocated range overlaps with a prealloc extent and the extent starts after i_size, the range doesn't get marked dirty in file_extent_tree. This results in persisting an incorrect disk_i_size for the inode when not using the no-holes feature.
This is reproducible since commit 41a2ee75aab0 ("btrfs: introduce per-inode file extent tree"), then became hidden since commit 3d7db6e8bd22 ("btrfs: don't allocate file extent tree for non regular files") and then visible again after commit 8679d2687c35 ("btrfs: initialize inode::file_extent_tree after i_mode has been set"), which fixes the previous commit.
The following reproducer triggers the problem:
$ cat test.sh
MNT=/mnt/test
DEV=/dev/vdb
mkdir -p $MNT
mkfs.btrfs -f -O ^no-holes $DEV
mount $DEV $MNT
touch $MNT/file1
fallocate -n -o 1M -l 2M $MNT/file1
umount $MNT
mount $DEV $MNT
len=$((1 * 1024 * 1024))
fallocate -o 1M -l $len $MNT/file1
du --bytes $MNT/file1
umount $MNT
mount $DEV $MNT
du --bytes $MNT/file1
umount $MNT
Running the reproducer gives the following result:
$ ./test.sh (...) 2097152 /mnt/test/file1 1048576 /mnt/test/file1
The difference is exactly 1048576 as we assigned.
Fix by adding a call to btrfs_inode_set_file_extent_range() in btrfs_fallocate_update_isize().
--- fs/btrfs/file.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
fs/btrfs/file.c +10 -0
@@ -2855,12 +2855,22 @@ static int btrfs_fallocate_update_isize(struct inode *inode, {struct btrfs_trans_handle *trans;struct btrfs_root *root =BTRFS_I (inode)->root; +u64 range_start; +u64 range_end;int ret;int ret2;if (mode &FALLOC_FL_KEEP_SIZE || end <=i_size_read (inode))return 0 ; + range_start =round_down (i_size_read (inode), root->fs_info->sectorsize); + range_end =round_up (end, root->fs_info->sectorsize); + + ret =btrfs_inode_set_file_extent_range (BTRFS_I (inode), range_start, + range_end - range_start); +if (ret) +return ret; + trans =btrfs_start_transaction (root,1 );if (IS_ERR (trans))return PTR_ERR (trans);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 693/849 clk: qcom: gcc-ipq6018: rework nss_port5 clock to multiple conf
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marko Mäkelä <[email protected]>
[ Upstream commit 2f7b168323c22faafb1fbf94ef93b7ce5efc15c6 ]
Rework nss_port5 to use the new multiple configuration implementation and correctly fix the clocks for this port under some corner case.
In OpenWrt, this patch avoids intermittent dmesg errors of the formnss_port5_rx_clk_src: rcg didn't update its configuration.
This is a mechanical, straightforward port of
commit e88f03230dc07aa3293b6aeb078bd27370bb2594
("clk: qcom: gcc-ipq8074: rework nss_port5/6 clock to multiple conf") to gcc-ipq6018, with two conflicts resolved: different frequency of the P_XO clock source, and only 5 Ethernet ports.
This was originally developed by JiaY-shi <[email protected]>.
--- drivers/clk/qcom/gcc-ipq6018.c | 60 +++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 22 deletions(-)
drivers/clk/qcom/gcc-ipq6018.c +38 -22
@@ -511,15 +511,23 @@ static struct clk_rcg2 apss_ahb_clk_src = { }, }; -static const struct freq_tbl ftbl_nss_port5_rx_clk_src[] = { -F (24000000 ,P_XO ,1 ,0 ,0 ), -F (25000000 ,P_UNIPHY1_RX ,12.5 ,0 ,0 ), -F (25000000 ,P_UNIPHY0_RX ,5 ,0 ,0 ), -F (78125000 ,P_UNIPHY1_RX ,4 ,0 ,0 ), -F (125000000 ,P_UNIPHY1_RX ,2.5 ,0 ,0 ), -F (125000000 ,P_UNIPHY0_RX ,1 ,0 ,0 ), -F (156250000 ,P_UNIPHY1_RX ,2 ,0 ,0 ), -F (312500000 ,P_UNIPHY1_RX ,1 ,0 ,0 ), +static const struct freq_conf ftbl_nss_port5_rx_clk_src_25[] = { +C (P_UNIPHY1_RX ,12.5 ,0 ,0 ), +C (P_UNIPHY0_RX ,5 ,0 ,0 ), +}; + +static const struct freq_conf ftbl_nss_port5_rx_clk_src_125[] = { +C (P_UNIPHY1_RX ,2.5 ,0 ,0 ), +C (P_UNIPHY0_RX ,1 ,0 ,0 ), +}; + +static const struct freq_multi_tbl ftbl_nss_port5_rx_clk_src[] = { +FMS (24000000 ,P_XO ,1 ,0 ,0 ), +FM (25000000 , ftbl_nss_port5_rx_clk_src_25), +FMS (78125000 ,P_UNIPHY1_RX ,4 ,0 ,0 ), +FM (125000000 , ftbl_nss_port5_rx_clk_src_125), +FMS (156250000 ,P_UNIPHY1_RX ,2 ,0 ,0 ), +FMS (312500000 ,P_UNIPHY1_RX ,1 ,0 ,0 ), { } };
@@ -547,26 +555,34 @@ gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map[] = {static struct clk_rcg2 nss_port5_rx_clk_src = { .cmd_rcgr =0x68060 , - .freq_tbl = ftbl_nss_port5_rx_clk_src, + .freq_multi_tbl = ftbl_nss_port5_rx_clk_src, .hid_width =5 , .parent_map = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data ){ .name ="nss_port5_rx_clk_src" , .parent_data = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias, .num_parents =7 , - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_fm_ops, }, }; -static const struct freq_tbl ftbl_nss_port5_tx_clk_src[] = { -F (24000000 ,P_XO ,1 ,0 ,0 ), -F (25000000 ,P_UNIPHY1_TX ,12.5 ,0 ,0 ), -F (25000000 ,P_UNIPHY0_TX ,5 ,0 ,0 ), -F (78125000 ,P_UNIPHY1_TX ,4 ,0 ,0 ), -F (125000000 ,P_UNIPHY1_TX ,2.5 ,0 ,0 ), -F (125000000 ,P_UNIPHY0_TX ,1 ,0 ,0 ), -F (156250000 ,P_UNIPHY1_TX ,2 ,0 ,0 ), -F (312500000 ,P_UNIPHY1_TX ,1 ,0 ,0 ), +static const struct freq_conf ftbl_nss_port5_tx_clk_src_25[] = { +C (P_UNIPHY1_TX ,12.5 ,0 ,0 ), +C (P_UNIPHY0_TX ,5 ,0 ,0 ), +}; + +static const struct freq_conf ftbl_nss_port5_tx_clk_src_125[] = { +C (P_UNIPHY1_TX ,2.5 ,0 ,0 ), +C (P_UNIPHY0_TX ,1 ,0 ,0 ), +}; + +static const struct freq_multi_tbl ftbl_nss_port5_tx_clk_src[] = { +FMS (24000000 ,P_XO ,1 ,0 ,0 ), +FM (25000000 , ftbl_nss_port5_tx_clk_src_25), +FMS (78125000 ,P_UNIPHY1_TX ,4 ,0 ,0 ), +FM (125000000 , ftbl_nss_port5_tx_clk_src_125), +FMS (156250000 ,P_UNIPHY1_TX ,2 ,0 ,0 ), +FMS (312500000 ,P_UNIPHY1_TX ,1 ,0 ,0 ), { } };
@@ -594,14 +610,14 @@ gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map[] = {static struct clk_rcg2 nss_port5_tx_clk_src = { .cmd_rcgr =0x68068 , - .freq_tbl = ftbl_nss_port5_tx_clk_src, + .freq_multi_tbl = ftbl_nss_port5_tx_clk_src, .hid_width =5 , .parent_map = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data ){ .name ="nss_port5_tx_clk_src" , .parent_data = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias, .num_parents =7 , - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_fm_ops, }, };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 694/849 clk: thead: th1520-ap: set all AXI clocks to CLK_IS_CRITICAL
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Icenowy Zheng <[email protected]>
[ Upstream commit c567bc5fc68c4388c00e11fc65fd14fe86b52070 ]
The AXI crossbar of TH1520 has no proper timeout handling, which means gating AXI clocks can easily lead to bus timeout and thus system hang.
Set all AXI clock gates to CLK_IS_CRITICAL. All these clock gates are ungated by default on system reset.
In addition, convert all current CLK_IGNORE_UNUSED usage to CLK_IS_CRITICAL to prevent unwanted clock gating.
--- drivers/clk/thead/clk-th1520-ap.c | 44 +++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-)
drivers/clk/thead/clk-th1520-ap.c +22 -22
@@ -480,7 +480,7 @@ static struct ccu_div axi4_cpusys2_aclk = { .hw.init = CLK_HW_INIT_PARENTS_HW("axi4-cpusys2-aclk", gmac_pll_clk_parent, &ccu_div_ops, - 0), + CLK_IS_CRITICAL), }, };
@@ -502,7 +502,7 @@ static struct ccu_div axi_aclk = { .hw.init = CLK_HW_INIT_PARENTS_DATA("axi-aclk", axi_parents, &ccu_div_ops, - 0), + CLK_IS_CRITICAL), }, };
@@ -651,7 +651,7 @@ static struct ccu_div apb_pclk = { .hw.init = CLK_HW_INIT_PARENTS_DATA("apb-pclk", apb_parents, &ccu_div_ops, - CLK_IGNORE_UNUSED), + CLK_IS_CRITICAL), }, };
@@ -682,7 +682,7 @@ static struct ccu_div vi_clk = { .hw.init = CLK_HW_INIT_PARENTS_HW("vi", video_pll_clk_parent, &ccu_div_ops, - 0), + CLK_IS_CRITICAL), }, };
@@ -707,7 +707,7 @@ static struct ccu_div vo_axi_clk = { .hw.init = CLK_HW_INIT_PARENTS_HW("vo-axi", video_pll_clk_parent, &ccu_div_ops, - 0), + CLK_IS_CRITICAL), }, };
@@ -732,7 +732,7 @@ static struct ccu_div vp_axi_clk = { .hw.init = CLK_HW_INIT_PARENTS_HW("vp-axi", video_pll_clk_parent, &ccu_div_ops, - CLK_IGNORE_UNUSED), + CLK_IS_CRITICAL), }, };
@@ -791,27 +791,27 @@ static const struct clk_parent_data emmc_sdio_ref_clk_pd[] = { static CCU_GATE(CLK_BROM, brom_clk, "brom", ahb2_cpusys_hclk_pd, 0x100, 4, 0); static CCU_GATE(CLK_BMU, bmu_clk, "bmu", axi4_cpusys2_aclk_pd, 0x100, 5, 0); static CCU_GATE(CLK_AON2CPU_A2X, aon2cpu_a2x_clk, "aon2cpu-a2x", axi4_cpusys2_aclk_pd, - 0x134, 8, 0); + 0x134, 8, CLK_IS_CRITICAL); static CCU_GATE(CLK_X2X_CPUSYS, x2x_cpusys_clk, "x2x-cpusys", axi4_cpusys2_aclk_pd, - 0x134, 7, 0); + 0x134, 7, CLK_IS_CRITICAL); static CCU_GATE(CLK_CPU2AON_X2H, cpu2aon_x2h_clk, "cpu2aon-x2h", axi_aclk_pd, - 0x138, 8, CLK_IGNORE_UNUSED); + 0x138, 8, CLK_IS_CRITICAL); static CCU_GATE(CLK_CPU2PERI_X2H, cpu2peri_x2h_clk, "cpu2peri-x2h", axi4_cpusys2_aclk_pd, - 0x140, 9, CLK_IGNORE_UNUSED); + 0x140, 9, CLK_IS_CRITICAL); static CCU_GATE(CLK_PERISYS_APB1_HCLK, perisys_apb1_hclk, "perisys-apb1-hclk", perisys_ahb_hclk_pd, - 0x150, 9, CLK_IGNORE_UNUSED); + 0x150, 9, CLK_IS_CRITICAL); static CCU_GATE(CLK_PERISYS_APB2_HCLK, perisys_apb2_hclk, "perisys-apb2-hclk", perisys_ahb_hclk_pd, - 0x150, 10, CLK_IGNORE_UNUSED); + 0x150, 10, CLK_IS_CRITICAL); static CCU_GATE(CLK_PERISYS_APB3_HCLK, perisys_apb3_hclk, "perisys-apb3-hclk", perisys_ahb_hclk_pd, - 0x150, 11, CLK_IGNORE_UNUSED); + 0x150, 11, CLK_IS_CRITICAL); static CCU_GATE(CLK_PERISYS_APB4_HCLK, perisys_apb4_hclk, "perisys-apb4-hclk", perisys_ahb_hclk_pd, 0x150, 12, 0);static const struct clk_parent_data perisys_apb4_hclk_pd[] = { { .hw = &perisys_apb4_hclk.gate.hw }, }; -static CCU_GATE(CLK_NPU_AXI, npu_axi_clk, "npu-axi", axi_aclk_pd, 0x1c8, 5, 0); -static CCU_GATE(CLK_CPU2VP, cpu2vp_clk, "cpu2vp", axi_aclk_pd, 0x1e0, 13, 0); +static CCU_GATE(CLK_NPU_AXI, npu_axi_clk, "npu-axi", axi_aclk_pd, 0x1c8, 5, CLK_IS_CRITICAL); +static CCU_GATE(CLK_CPU2VP, cpu2vp_clk, "cpu2vp", axi_aclk_pd, 0x1e0, 13, CLK_IS_CRITICAL); static CCU_GATE(CLK_EMMC_SDIO, emmc_sdio_clk, "emmc-sdio", emmc_sdio_ref_clk_pd, 0x204, 30, 0); static CCU_GATE(CLK_GMAC1, gmac1_clk, "gmac1", gmac_pll_clk_pd, 0x204, 26, 0); static CCU_GATE(CLK_PADCTRL1, padctrl1_clk, "padctrl1", perisys_apb_pclk_pd, 0x204, 24, 0);
@@ -855,11 +855,11 @@ static CCU_GATE(CLK_SRAM2, sram2_clk, "sram2", axi_aclk_pd, 0x20c, 2, 0); static CCU_GATE(CLK_SRAM3, sram3_clk, "sram3", axi_aclk_pd, 0x20c, 1, 0); static CCU_GATE(CLK_AXI4_VO_ACLK, axi4_vo_aclk, "axi4-vo-aclk", - video_pll_clk_pd, 0x0, 0, 0); + video_pll_clk_pd, 0x0, 0, CLK_IS_CRITICAL); static CCU_GATE(CLK_GPU_CORE, gpu_core_clk, "gpu-core-clk", video_pll_clk_pd, 0x0, 3, 0); static CCU_GATE(CLK_GPU_CFG_ACLK, gpu_cfg_aclk, "gpu-cfg-aclk", - video_pll_clk_pd, 0x0, 4, 0); + video_pll_clk_pd, 0x0, 4, CLK_IS_CRITICAL); static CCU_GATE(CLK_DPU_PIXELCLK0, dpu0_pixelclk, "dpu0-pixelclk", dpu0_clk_pd, 0x0, 5, 0); static CCU_GATE(CLK_DPU_PIXELCLK1, dpu1_pixelclk, "dpu1-pixelclk",
@@ -891,9 +891,9 @@ static CCU_GATE(CLK_MIPI_DSI1_REFCLK, mipi_dsi1_refclk, "mipi-dsi1-refclk", static CCU_GATE(CLK_HDMI_I2S, hdmi_i2s_clk, "hdmi-i2s-clk", video_pll_clk_pd, 0x0, 19, 0); static CCU_GATE(CLK_X2H_DPU1_ACLK, x2h_dpu1_aclk, "x2h-dpu1-aclk", - video_pll_clk_pd, 0x0, 20, 0); + video_pll_clk_pd, 0x0, 20, CLK_IS_CRITICAL); static CCU_GATE(CLK_X2H_DPU_ACLK, x2h_dpu_aclk, "x2h-dpu-aclk", - video_pll_clk_pd, 0x0, 21, 0); + video_pll_clk_pd, 0x0, 21, CLK_IS_CRITICAL); static CCU_GATE(CLK_AXI4_VO_PCLK, axi4_vo_pclk, "axi4-vo-pclk", video_pll_clk_pd, 0x0, 22, 0); static CCU_GATE(CLK_IOPMP_VOSYS_DPU_PCLK, iopmp_vosys_dpu_pclk,
@@ -903,11 +903,11 @@ static CCU_GATE(CLK_IOPMP_VOSYS_DPU1_PCLK, iopmp_vosys_dpu1_pclk, static CCU_GATE(CLK_IOPMP_VOSYS_GPU_PCLK, iopmp_vosys_gpu_pclk, "iopmp-vosys-gpu-pclk", video_pll_clk_pd, 0x0, 25, 0); static CCU_GATE(CLK_IOPMP_DPU1_ACLK, iopmp_dpu1_aclk, "iopmp-dpu1-aclk", - video_pll_clk_pd, 0x0, 27, 0); + video_pll_clk_pd, 0x0, 27, CLK_IS_CRITICAL); static CCU_GATE(CLK_IOPMP_DPU_ACLK, iopmp_dpu_aclk, "iopmp-dpu-aclk", - video_pll_clk_pd, 0x0, 28, 0); + video_pll_clk_pd, 0x0, 28, CLK_IS_CRITICAL); static CCU_GATE(CLK_IOPMP_GPU_ACLK, iopmp_gpu_aclk, "iopmp-gpu-aclk", - video_pll_clk_pd, 0x0, 29, 0); + video_pll_clk_pd, 0x0, 29, CLK_IS_CRITICAL); static CCU_GATE(CLK_MIPIDSI0_PIXCLK, mipi_dsi0_pixclk, "mipi-dsi0-pixclk", video_pll_clk_pd, 0x0, 30, 0); static CCU_GATE(CLK_MIPIDSI1_PIXCLK, mipi_dsi1_pixclk, "mipi-dsi1-pixclk",
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 695/849 clk: renesas: rzv2h: Re-assert reset on deassert timeout
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tommaso Merciai <[email protected]>
[ Upstream commit f8c002165ca27d95d3d15e865dd0a47c0a1b14dd ]
Prevent issues during reset deassertion by re-asserting the reset if a timeout occurs when trying to deassert. This ensures the reset line is in a known state and improves reliability for hardware that may not immediately clear the reset monitor bit.
--- drivers/clk/renesas/rzv2h-cpg.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/clk/renesas/rzv2h-cpg.c +10 -3
@@ -864,6 +864,7 @@ static int __rzv2h_cpg_assert(struct reset_controller_dev *rcdev,u32 mask =BIT (priv->resets[id].reset_bit);u8 monbit = priv->resets[id].mon_bit;u32 value = mask <<16 ; +int ret;dev_dbg (rcdev->dev,"%s id:%ld offset:0x%x\n" , assert ?"assert" :"deassert" , id, reg);
@@ -875,9 +876,15 @@ static int __rzv2h_cpg_assert(struct reset_controller_dev *rcdev, reg =GET_RST_MON_OFFSET (priv->resets[id].mon_index); mask =BIT (monbit); -return readl_poll_timeout_atomic (priv->base + reg, value, - assert ? (value & mask) : !(value & mask), -10 ,200 ); + ret =readl_poll_timeout_atomic (priv->base + reg, value, + assert ? (value & mask) : !(value & mask), +10 ,200 ); +if (ret && !assert) { + value = mask <<16 ; +writel (value, priv->base +GET_RST_OFFSET (priv->resets[id].reset_index)); + } + +return ret; } static int rzv2h_cpg_assert(struct reset_controller_dev *rcdev,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 696/849 clk: samsung: exynos990: Add missing USB clock registers to HSI0
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Denzeel Oliva <[email protected]>
[ Upstream commit f00a5dc81744250e7a3f843adfe12d7883282c56 ]
These registers are required for proper USB operation and were omitted in the initial clock controller setup.
--- drivers/clk/samsung/clk-exynos990.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/clk/samsung/clk-exynos990.c +2 -0
@@ -1198,6 +1198,8 @@ static const unsigned long hsi0_clk_regs[] __initconst = {CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSMMU_USB_IPCLKPORT_CLK_S2 ,CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSREG_HSI0_IPCLKPORT_PCLK ,CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_ACLK_PHYCTRL , +CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USB31DRD_REF_CLK_40 , +CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_REF_SOC_PLL ,CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_SCL_APB_PCLK ,CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBPCS_APB_CLK , CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_BUS_CLK_EARLY,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 697/849 fs/hpfs: Fix error code for new_inode() failure in mkdir/create/mknod/symlink
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yikang Yue <[email protected]>
[ Upstream commit 32058c38d3b79a28963a59ac0353644dc24775cd ]
The function call new_inode() is a primitive for allocating an inode in memory, rather than planning disk space for it. Therefore, -ENOMEM should be returned as the error code rather than -ENOSPC.
To be specific, new_inode()'s call path looks like this:new_inode
new_inode_pseudo
alloc_inode
ops->alloc_inode (hpfs_alloc_inode)
alloc_inode_sb
kmem_cache_alloc_lruTherefore, the failure of new_inode() indicates a memory presure issue (-ENOMEM), not a lack of disk space. However, the current implementation of hpfs_mkdir/create/mknod/symlink incorrectly returns -ENOSPC when new_inode() fails. This patch fix this by set err to -ENOMEM before the goto statement.
BTW, we also noticed that other nested calls within these four functions, like hpfs_alloc_f/dnode and hpfs_add_dirent, might also fail due to memory presure. But similarly, only -ENOSPC is returned. Addressing these will involve code modifications in other functions, and we plan to submit dedicated patches for these issues in the future. For this patch, we focus on new_inode().
--- fs/hpfs/namei.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
fs/hpfs/namei.c +12 -6
@@ -52,8 +52,10 @@ static struct dentry *hpfs_mkdir(struct mnt_idmap *idmap, struct inode *dir, dee.fnode =cpu_to_le32 (fno); dee.creation_date = dee.write_date = dee.read_date =cpu_to_le32 (local_get_seconds (dir->i_sb)); result =new_inode (dir->i_sb); -if (!result) +if (!result) { + err = -ENOMEM ; goto bail2; + }hpfs_init_inode (result); result->i_ino = fno;hpfs_i (result)->i_parent_dir = dir->i_ino;
@@ -153,9 +155,10 @@ static int hpfs_create(struct mnt_idmap *idmap, struct inode *dir, dee.creation_date = dee.write_date = dee.read_date =cpu_to_le32 (local_get_seconds (dir->i_sb)); result =new_inode (dir->i_sb); -if (!result) +if (!result) { + err = -ENOMEM ; goto bail1; - + }hpfs_init_inode (result); result->i_ino = fno; result->i_mode |=S_IFREG ;
@@ -239,9 +242,10 @@ static int hpfs_mknod(struct mnt_idmap *idmap, struct inode *dir, dee.creation_date = dee.write_date = dee.read_date =cpu_to_le32 (local_get_seconds (dir->i_sb)); result =new_inode (dir->i_sb); -if (!result) +if (!result) { + err = -ENOMEM ; goto bail1; - + }hpfs_init_inode (result); result->i_ino = fno;hpfs_i (result)->i_parent_dir = dir->i_ino;
@@ -314,8 +318,10 @@ static int hpfs_symlink(struct mnt_idmap *idmap, struct inode *dir, dee.creation_date = dee.write_date = dee.read_date =cpu_to_le32 (local_get_seconds (dir->i_sb)); result =new_inode (dir->i_sb); -if (!result) +if (!result) { + err = -ENOMEM ; goto bail1; + } result->i_ino = fno;hpfs_init_inode (result);hpfs_i (result)->i_parent_dir = dir->i_ino;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 698/849 clocksource: hyper-v: Skip unnecessary checks for the root partition
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Liu <[email protected]>
[ Upstream commit 47691ced158ab3a7ce2189b857b19c0c99a9aa80 ]
The HV_ACCESS_TSC_INVARIANT bit is always zero when Linux runs as the root partition. The root partition will see directly what the hardware provides.
The old logic in ms_hyperv_init_platform caused the native TSC clock source to be incorrectly marked as unstable on x86. Fix it.
Skip the unnecessary checks in code for the root partition. Add one extra comment in code to clarify the behavior.
--- arch/x86/kernel/cpu/mshyperv.c | 11 ++++++++++- drivers/clocksource/hyperv_timer.c | 10 +++++++++- 2 files changed, 19 insertions(+), 2 deletions(-)
arch/x86/kernel/cpu/mshyperv.c +10 -1
@@ -565,6 +565,11 @@ static void __init ms_hyperv_init_platform(void) machine_ops.crash_shutdown = hv_machine_crash_shutdown;#endif #endif +/* +* HV_ACCESS_TSC_INVARIANT is always zero for the root partition. Root +* partition doesn't need to write to synthetic MSR to enable invariant +* TSC feature. It sees what the hardware provides. +*/ if (ms_hyperv.features &HV_ACCESS_TSC_INVARIANT ) {/* * Writing to synthetic MSR 0x40000118 updates/changes the
@@ -636,8 +641,12 @@ static void __init ms_hyperv_init_platform(void)* TSC should be marked as unstable only after Hyper-V * clocksource has been initialized. This ensures that the * stability of the sched_clock is not altered. +* +* HV_ACCESS_TSC_INVARIANT is always zero for the root partition. No +* need to check for it. */ -if (!(ms_hyperv.features &HV_ACCESS_TSC_INVARIANT )) +if (!hv_root_partition () && + !(ms_hyperv.features &HV_ACCESS_TSC_INVARIANT ))mark_tsc_unstable ("running on Hyper-V" );hardlockup_detector_disable ();
drivers/clocksource/hyperv_timer.c +9 -1
@@ -549,14 +549,22 @@ static void __init hv_init_tsc_clocksource(void)union hv_reference_tsc_msr tsc_msr;/* +* When running as a guest partition: +* * If Hyper-V offers TSC_INVARIANT, then the virtualized TSC correctly * handles frequency and offset changes due to live migration, * pause/resume, and other VM management operations. So lower the * Hyper-V Reference TSC rating, causing the generic TSC to be used. * TSC_INVARIANT is not offered on ARM64, so the Hyper-V Reference * TSC will be preferred over the virtualized ARM64 arch counter. +* +* When running as the root partition: +* +* There is no HV_ACCESS_TSC_INVARIANT feature. Always lower the rating +* of the Hyper-V Reference TSC. */ -if (ms_hyperv.features &HV_ACCESS_TSC_INVARIANT ) { +if ((ms_hyperv.features &HV_ACCESS_TSC_INVARIANT ) || +hv_root_partition ()) { hyperv_cs_tsc.rating =250 ; hyperv_cs_msr.rating =245 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 699/849 hyperv: Add missing field to hv_output_map_device_interrupt
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Das Neves <[email protected]>
[ Upstream commit 4cd661c248b6671914ad59e16760bb6d908dfc61 ]
This field is unused, but the correct structure size is needed when computing the amount of space for the output argument to reside, so that it does not cross a page boundary.
--- include/hyperv/hvhdk_mini.h | 1 + 1 file changed, 1 insertion(+)
include/hyperv/hvhdk_mini.h +1 -0
@@ -301,6 +301,7 @@ struct hv_input_map_device_interrupt {/* HV_OUTPUT_MAP_DEVICE_INTERRUPT */ struct hv_output_map_device_interrupt {struct hv_interrupt_entry interrupt_entry; +u64 ext_status_deprecated[5 ]; } __packed;/* HV_INPUT_UNMAP_DEVICE_INTERRUPT */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 700/849 um: Fix help message for ssl-non-raw
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiwei Bie <[email protected]>
[ Upstream commit 725e9d81868fcedaeef775948e699955b01631ae ]
Add the missing option name in the help message. Additionally, switch to __uml_help(), because this is a global option rather than a per-channel option.
--- arch/um/drivers/ssl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
arch/um/drivers/ssl.c +4 -1
@@ -199,4 +199,7 @@ static int ssl_non_raw_setup(char *str)return 1 ; }__setup ("ssl-non-raw" , ssl_non_raw_setup); -__channel_help (ssl_non_raw_setup,"set serial lines to non-raw mode" ); +__uml_help (ssl_non_raw_setup, +"ssl-non-raw\n" +" Set serial lines to non-raw mode.\n\n" +);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 701/849 clk: sunxi-ng: sun6i-rtc: Add A523 specifics
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai <[email protected]>
[ Upstream commit 7aa8781f379c32c31bd78f1408a31765b2297c43 ]
The A523's RTC block is backward compatible with the R329's, but it also has a calibration function for its internal oscillator, which would allow it to provide a clock rate closer to the desired 32.768 KHz. This is useful on the Radxa Cubie A5E, which does not have an external 32.768 KHz crystal.
Add new compatible-specific data for it.
--- drivers/clk/sunxi-ng/ccu-sun6i-rtc.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/clk/sunxi-ng/ccu-sun6i-rtc.c +11 -0
@@ -325,6 +325,13 @@ static const struct sun6i_rtc_match_data sun50i_r329_rtc_ccu_data = { .osc32k_fanout_nparents = ARRAY_SIZE(sun50i_r329_osc32k_fanout_parents), }; +static const struct sun6i_rtc_match_data sun55i_a523_rtc_ccu_data = { + .have_ext_osc32k = true, + .have_iosc_calibration = true, + .osc32k_fanout_parents = sun50i_r329_osc32k_fanout_parents, + .osc32k_fanout_nparents =ARRAY_SIZE (sun50i_r329_osc32k_fanout_parents), +}; +static const struct of_device_id sun6i_rtc_ccu_match[] = { { .compatible ="allwinner,sun50i-h616-rtc" ,
@@ -334,6 +341,10 @@ static const struct of_device_id sun6i_rtc_ccu_match[] = { .compatible = "allwinner,sun50i-r329-rtc", .data = &sun50i_r329_rtc_ccu_data, }, + { + .compatible = "allwinner,sun55i-a523-rtc", + .data = &sun55i_a523_rtc_ccu_data, + }, {}, };MODULE_DEVICE_TABLE (of, sun6i_rtc_ccu_match);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 702/849 rtc: pcf2127: clear minute/second interrupt
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josua Mayer <[email protected]>
[ Upstream commit a6f1a4f05970664004a9370459c6799c1b2f2dcf ]
PCF2127 can generate interrupt every full second or minute configured from control and status register 1, bits MI (1) and SI (0).
On interrupt control register 2 bit MSF (7) is set and must be cleared to continue normal operation.
While the driver never enables this interrupt on its own, users or firmware may do so - e.g. as an easy way to test the interrupt.
Add preprocessor definition for MSF bit and include it in the irq bitmask to ensure minute and second interrupts are cleared when fired.
This fixes an issue where the rtc enters a test mode and becomes unresponsive after a second interrupt has fired and is not cleared in time. In this state register writes to control registers have no effect and the interrupt line is kept asserted [1]:
[1] userspace commands to put rtc into unresponsive state:
$ i2cget -f -y 2 0x51 0x00 0x04 $ i2cset -f -y 2 0x51 0x00 0x05 # set bit 0 SI $ i2cget -f -y 2 0x51 0x00 0x84 # bit 8 EXT_TEST set $ i2cset -f -y 2 0x51 0x00 0x05 # try overwrite control register $ i2cget -f -y 2 0x51 0x00 0x84 # no change
--- drivers/rtc/rtc-pcf2127.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/rtc/rtc-pcf2127.c +3 -1
@@ -42,6 +42,7 @@#define PCF2127_BIT_CTRL2_AF BIT(4)#define PCF2127_BIT_CTRL2_TSF2 BIT(5)#define PCF2127_BIT_CTRL2_WDTF BIT(6) +#define PCF2127_BIT_CTRL2_MSF BIT(7)/* Control register 3 */ #define PCF2127_REG_CTRL3 0x02#define PCF2127_BIT_CTRL3_BLIE BIT(0)
@@ -96,7 +97,8 @@#define PCF2127_CTRL2_IRQ_MASK ( \ PCF2127_BIT_CTRL2_AF | \ PCF2127_BIT_CTRL2_WDTF | \ - PCF2127_BIT_CTRL2_TSF2) + PCF2127_BIT_CTRL2_TSF2 | \ + PCF2127_BIT_CTRL2_MSF)#define PCF2127_MAX_TS_SUPPORTED 4
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 703/849 ARM: at91: pm: save and restore ACR during PLL disable/enable
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolas Ferre <[email protected]>
[ Upstream commit 0c01fe49651d387776abed6a28541e80c8a93319 ]
Add a new word in assembly to store ACR value during the calls to at91_plla_disable/at91_plla_enable macros and use it.
--- arch/arm/mach-at91/pm_suspend.S | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/arm/mach-at91/pm_suspend.S +7 -1
@@ -689,6 +689,10 @@ sr_dis_exit: bic tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID str tmp2, [pmc, #AT91_PMC_PLL_UPDT] + /* save acr */ + ldr tmp2, [pmc, #AT91_PMC_PLL_ACR] + str tmp2, .saved_acr + /* save div. */ mov tmp1, #0 ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL0]
@@ -758,7 +762,7 @@ sr_dis_exit: str tmp1, [pmc, #AT91_PMC_PLL_UPDT] /* step 2. */ - ldr tmp1, =AT91_PMC_PLL_ACR_DEFAULT_PLLA + ldr tmp1, .saved_acr str tmp1, [pmc, #AT91_PMC_PLL_ACR] /* step 3. */
@@ -1207,6 +1211,8 @@ ENDPROC(at91_pm_suspend_in_sram) #endif .saved_mckr: .word 0 +.saved_acr: + .word 0 .saved_pllar: .word 0 .saved_sam9_lpr:
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 704/849 clk: at91: add ACR in all PLL settings
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Birsan <[email protected]>
[ Upstream commit bfa2bddf6ffe0ac034d02cda20c74ef05571210e ]
Add the ACR register to all PLL settings and provide the correct ACR value for each PLL used in different SoCs.
--- drivers/clk/at91/pmc.h | 1 + drivers/clk/at91/sam9x60.c | 2 ++ drivers/clk/at91/sam9x7.c | 5 +++++ drivers/clk/at91/sama7d65.c | 4 ++++ drivers/clk/at91/sama7g5.c | 2 ++ 5 files changed, 14 insertions(+)
drivers/clk/at91/pmc.h +1 -0
@@ -80,6 +80,7 @@ struct clk_pll_characteristics {u16 *icpll;u8 *out; u8 upll : 1; +u32 acr; };struct clk_programmable_layout {
drivers/clk/at91/sam9x60.c +2 -0
@@ -36,6 +36,7 @@ static const struct clk_pll_characteristics plla_characteristics = { .num_output = ARRAY_SIZE(plla_outputs), .output = plla_outputs, .core_output = core_outputs, + .acr = UL(0x00020010), };static const struct clk_range upll_outputs[] = {
@@ -48,6 +49,7 @@ static const struct clk_pll_characteristics upll_characteristics = { .output = upll_outputs, .core_output = core_outputs, .upll = true, + .acr = UL(0x12023010), /* fIN = [18 MHz, 32 MHz]*/ };static const struct clk_pll_layout pll_frac_layout = {
drivers/clk/at91/sam9x7.c +5 -0
@@ -107,6 +107,7 @@ static const struct clk_pll_characteristics plla_characteristics = { .num_output = ARRAY_SIZE(plla_outputs), .output = plla_outputs, .core_output = plla_core_outputs, + .acr = UL(0x00020010), /* Old ACR_DEFAULT_PLLA value */ };static const struct clk_pll_characteristics upll_characteristics = {
@@ -115,6 +116,7 @@ static const struct clk_pll_characteristics upll_characteristics = { .output = upll_outputs, .core_output = upll_core_outputs, .upll = true, + .acr = UL(0x12023010), /* fIN=[20 MHz, 32 MHz] */ };static const struct clk_pll_characteristics lvdspll_characteristics = {
@@ -122,6 +124,7 @@ static const struct clk_pll_characteristics lvdspll_characteristics = { .num_output = ARRAY_SIZE(lvdspll_outputs), .output = lvdspll_outputs, .core_output = lvdspll_core_outputs, + .acr = UL(0x12023010), /* fIN=[20 MHz, 32 MHz] */ };static const struct clk_pll_characteristics audiopll_characteristics = {
@@ -129,6 +132,7 @@ static const struct clk_pll_characteristics audiopll_characteristics = { .num_output = ARRAY_SIZE(audiopll_outputs), .output = audiopll_outputs, .core_output = audiopll_core_outputs, + .acr = UL(0x12023010), /* fIN=[20 MHz, 32 MHz] */ };static const struct clk_pll_characteristics plladiv2_characteristics = {
@@ -136,6 +140,7 @@ static const struct clk_pll_characteristics plladiv2_characteristics = { .num_output = ARRAY_SIZE(plladiv2_outputs), .output = plladiv2_outputs, .core_output = plladiv2_core_outputs, + .acr = UL(0x00020010), /* Old ACR_DEFAULT_PLLA value */ };/* Layout for fractional PLL ID PLLA. */
drivers/clk/at91/sama7d65.c +4 -0
@@ -138,6 +138,7 @@ static const struct clk_pll_characteristics cpu_pll_characteristics = { .num_output = ARRAY_SIZE(cpu_pll_outputs), .output = cpu_pll_outputs, .core_output = core_outputs, + .acr = UL(0x00070010), };/* PLL characteristics. */
@@ -146,6 +147,7 @@ static const struct clk_pll_characteristics pll_characteristics = { .num_output = ARRAY_SIZE(pll_outputs), .output = pll_outputs, .core_output = core_outputs, + .acr = UL(0x00070010), };static const struct clk_pll_characteristics lvdspll_characteristics = {
@@ -153,6 +155,7 @@ static const struct clk_pll_characteristics lvdspll_characteristics = { .num_output = ARRAY_SIZE(lvdspll_outputs), .output = lvdspll_outputs, .core_output = lvdspll_core_outputs, + .acr = UL(0x00070010), };static const struct clk_pll_characteristics upll_characteristics = {
@@ -160,6 +163,7 @@ static const struct clk_pll_characteristics upll_characteristics = { .num_output = ARRAY_SIZE(upll_outputs), .output = upll_outputs, .core_output = upll_core_outputs, + .acr = UL(0x12020010), .upll = true, };
drivers/clk/at91/sama7g5.c +2 -0
@@ -113,6 +113,7 @@ static const struct clk_pll_characteristics cpu_pll_characteristics = { .num_output = ARRAY_SIZE(cpu_pll_outputs), .output = cpu_pll_outputs, .core_output = core_outputs, + .acr = UL(0x00070010), };/* PLL characteristics. */
@@ -121,6 +122,7 @@ static const struct clk_pll_characteristics pll_characteristics = { .num_output = ARRAY_SIZE(pll_outputs), .output = pll_outputs, .core_output = core_outputs, + .acr = UL(0x00070010), };/*
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 705/849 clk: at91: sam9x7: Add peripheral clock id for pmecc
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Balamanikandan Gunasundar <[email protected]>
[ Upstream commit 94a1274100e397a27361ae53ace37be6da42a079 ]
Add pmecc instance id in peripheral clock description.
--- drivers/clk/at91/sam9x7.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/at91/sam9x7.c +1 -0
@@ -408,6 +408,7 @@ static const struct { { .n = "pioD_clk", .id = 44, }, { .n = "tcb1_clk", .id = 45, }, { .n = "dbgu_clk", .id = 47, }, + { .n = "pmecc_clk", .id = 48, }, /* * mpddr_clk feeds DDR controller and is enabled by bootloader thus we * need to keep it enabled in case there is no Linux consumer for it.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 706/849 clk: at91: clk-master: Add check for divide by 3
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryan Wanner <[email protected]>
[ Upstream commit e0237f5635727d64635ec6665e1de9f4cacce35c ]
A potential divider for the master clock is div/3. The register configuration for div/3 is MASTER_PRES_MAX. The current bit shifting method does not work for this case. Checking for MASTER_PRES_MAX will ensure the correct decimal value is stored in the system.
--- drivers/clk/at91/clk-master.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/clk/at91/clk-master.c +3 -0
@@ -580,6 +580,9 @@ clk_sama7g5_master_recalc_rate(struct clk_hw *hw, {struct clk_master *master =to_clk_master (hw); +if (master->div ==MASTER_PRES_MAX ) +return DIV_ROUND_CLOSEST_ULL (parent_rate,3 ); +return DIV_ROUND_CLOSEST_ULL (parent_rate, (1 << master->div)); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 707/849 clk: at91: clk-sam9x60-pll: force write to PLL_UPDT register
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolas Ferre <[email protected]>
[ Upstream commit af98caeaa7b6ad11eb7b7c8bfaddc769df2889f3 ]
This register is important for sequencing the commands to PLLs, so actually write the update bits with regmap_write_bits() instead of relying on a read/modify/write regmap command that could skip the actual hardware write if the value is identical to the one read.
It's changed when modification is needed to the PLL, when read-only operation is done, we could keep the call to regmap_update_bits().
Add a comment to the sam9x60_div_pll_set_div() function that uses this PLL_UPDT register so that it's used consistently, according to the product's datasheet.
[claudiu.beznea: fix "Alignment should match open parenthesis"
checkpatch.pl check]
--- drivers/clk/at91/clk-sam9x60-pll.c | 75 ++++++++++++++++-------------- 1 file changed, 39 insertions(+), 36 deletions(-)
drivers/clk/at91/clk-sam9x60-pll.c +39 -36
@@ -93,8 +93,8 @@ static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core)spin_lock_irqsave (core->lock, flags); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_ID_MSK , core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_ID_MSK , core->id);regmap_read (regmap,AT91_PMC_PLL_CTRL1 , &val); cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift; cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift;
@@ -128,17 +128,17 @@ static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core)udelay (10 ); } -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , -AT91_PMC_PLL_UPDT_UPDATE | core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , +AT91_PMC_PLL_UPDT_UPDATE | core->id);regmap_update_bits (regmap,AT91_PMC_PLL_CTRL0 ,AT91_PMC_PLL_CTRL0_ENLOCK |AT91_PMC_PLL_CTRL0_ENPLL ,AT91_PMC_PLL_CTRL0_ENLOCK |AT91_PMC_PLL_CTRL0_ENPLL ); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , -AT91_PMC_PLL_UPDT_UPDATE | core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , +AT91_PMC_PLL_UPDT_UPDATE | core->id);while (!sam9x60_pll_ready (regmap, core->id))cpu_relax ();
@@ -164,8 +164,8 @@ static void sam9x60_frac_pll_unprepare(struct clk_hw *hw)spin_lock_irqsave (core->lock, flags); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_ID_MSK , core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_ID_MSK , core->id);regmap_update_bits (regmap,AT91_PMC_PLL_CTRL0 ,AT91_PMC_PLL_CTRL0_ENPLL ,0 );
@@ -173,9 +173,9 @@ static void sam9x60_frac_pll_unprepare(struct clk_hw *hw)regmap_update_bits (regmap,AT91_PMC_PLL_ACR ,AT91_PMC_PLL_ACR_UTMIBG |AT91_PMC_PLL_ACR_UTMIVR ,0 ); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , -AT91_PMC_PLL_UPDT_UPDATE | core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , +AT91_PMC_PLL_UPDT_UPDATE | core->id);spin_unlock_irqrestore (core->lock, flags); }
@@ -262,8 +262,8 @@ static int sam9x60_frac_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate,spin_lock_irqsave (core->lock, irqflags); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT ,AT91_PMC_PLL_UPDT_ID_MSK , - core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT ,AT91_PMC_PLL_UPDT_ID_MSK , + core->id);regmap_read (regmap,AT91_PMC_PLL_CTRL1 , &val); cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift; cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift;
@@ -275,18 +275,18 @@ static int sam9x60_frac_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, (frac->mul << core->layout->mul_shift) | (frac->frac << core->layout->frac_shift)); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , -AT91_PMC_PLL_UPDT_UPDATE | core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , +AT91_PMC_PLL_UPDT_UPDATE | core->id);regmap_update_bits (regmap,AT91_PMC_PLL_CTRL0 ,AT91_PMC_PLL_CTRL0_ENLOCK |AT91_PMC_PLL_CTRL0_ENPLL ,AT91_PMC_PLL_CTRL0_ENLOCK |AT91_PMC_PLL_CTRL0_ENPLL ); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , -AT91_PMC_PLL_UPDT_UPDATE | core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , +AT91_PMC_PLL_UPDT_UPDATE | core->id);while (!sam9x60_pll_ready (regmap, core->id))cpu_relax ();
@@ -338,7 +338,10 @@ static const struct clk_ops sam9x60_frac_pll_ops_chg = { .restore_context = sam9x60_frac_pll_restore_context, }; -/* This function should be called with spinlock acquired. */ +/* This function should be called with spinlock acquired. +* Warning: this function must be called only if the same PLL ID was set in +* PLL_UPDT register previously. +*/ static void sam9x60_div_pll_set_div (struct sam9x60_pll_core *core,u32 div,bool enable) {
@@ -350,9 +353,9 @@ static void sam9x60_div_pll_set_div(struct sam9x60_pll_core *core, u32 div, core->layout->div_mask | ena_msk, (div << core->layout->div_shift) | ena_val); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , -AT91_PMC_PLL_UPDT_UPDATE | core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , +AT91_PMC_PLL_UPDT_UPDATE | core->id);while (!sam9x60_pll_ready (regmap, core->id))cpu_relax ();
@@ -366,8 +369,8 @@ static int sam9x60_div_pll_set(struct sam9x60_pll_core *core)unsigned int val, cdiv;spin_lock_irqsave (core->lock, flags); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_ID_MSK , core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_ID_MSK , core->id);regmap_read (regmap,AT91_PMC_PLL_CTRL0 , &val); cdiv = (val & core->layout->div_mask) >> core->layout->div_shift;
@@ -398,15 +401,15 @@ static void sam9x60_div_pll_unprepare(struct clk_hw *hw)spin_lock_irqsave (core->lock, flags); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_ID_MSK , core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_ID_MSK , core->id);regmap_update_bits (regmap,AT91_PMC_PLL_CTRL0 , core->layout->endiv_mask,0 ); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT , -AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , -AT91_PMC_PLL_UPDT_UPDATE | core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT , +AT91_PMC_PLL_UPDT_UPDATE |AT91_PMC_PLL_UPDT_ID_MSK , +AT91_PMC_PLL_UPDT_UPDATE | core->id);spin_unlock_irqrestore (core->lock, flags); }
@@ -518,8 +521,8 @@ static int sam9x60_div_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, div->div =DIV_ROUND_CLOSEST (parent_rate, rate) -1 ;spin_lock_irqsave (core->lock, irqflags); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT ,AT91_PMC_PLL_UPDT_ID_MSK , - core->id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT ,AT91_PMC_PLL_UPDT_ID_MSK , + core->id);regmap_read (regmap,AT91_PMC_PLL_CTRL0 , &val); cdiv = (val & core->layout->div_mask) >> core->layout->div_shift;
@@ -574,8 +577,8 @@ static int sam9x60_div_pll_notifier_fn(struct notifier_block *notifier, div->div = div->safe_div;spin_lock_irqsave (core.lock, irqflags); -regmap_update_bits (regmap,AT91_PMC_PLL_UPDT ,AT91_PMC_PLL_UPDT_ID_MSK , - core.id); +regmap_write_bits (regmap,AT91_PMC_PLL_UPDT ,AT91_PMC_PLL_UPDT_ID_MSK , + core.id);regmap_read (regmap,AT91_PMC_PLL_CTRL0 , &val); cdiv = (val & core.layout->div_mask) >> core.layout->div_shift;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 708/849 9p/trans_fd: p9_fd_request: kick rx thread if EPOLLIN
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleg Nesterov <[email protected]>
[ Upstream commit e8fe3f07a357c39d429e02ca34f740692d88967a ]
p9_read_work() doesn't set Rworksched and doesn't do schedule_work(m->rq) if list_empty(&m->req_list).
However, if the pipe is full, we need to read more data and this used to work prior to commit aaec5a95d59615 ("pipe_read: don't wake up the writer if the pipe is still full").
p9_read_work() does p9_fd_read() -> ... -> anon_pipe_read() which (before the commit above) triggered the unnecessary wakeup. This wakeup calls p9_pollwake() which kicks p9_poll_workfn() -> p9_poll_mux(), p9_poll_mux() will notice EPOLLIN and schedule_work(&m->rq).
This no longer happens after the optimization above, change p9_fd_request() to use p9_poll_mux() instead of only checking for EPOLLOUT.
Message-ID: <[email protected]>
--- net/9p/trans_fd.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
net/9p/trans_fd.c +1 -8
@@ -666,7 +666,6 @@ static void p9_poll_mux(struct p9_conn *m)static int p9_fd_request (struct p9_client *client,struct p9_req_t *req) { -__poll_t n;int err;struct p9_trans_fd *ts = client->trans;struct p9_conn *m = &ts->conn;
@@ -686,13 +685,7 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)list_add_tail (&req->req_list, &m->unsent_req_list);spin_unlock (&m->req_lock); -if (test_and_clear_bit (Wpending, &m->wsched)) - n =EPOLLOUT ; -else - n =p9_fd_poll (m->client,NULL ,NULL ); - -if (n &EPOLLOUT && !test_and_set_bit (Wworksched, &m->wsched)) -schedule_work (&m->wq); +p9_poll_mux (m);return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 709/849 clk: ti: am33xx: keep WKUP_DEBUGSS_CLKCTRL enabled
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthias Schiffer <[email protected]>
[ Upstream commit 1e0d75258bd09323cb452655549e03975992b29e ]
As described in AM335x Errata Advisory 1.0.42, WKUP_DEBUGSS_CLKCTRL can't be disabled - the clock module will just be stuck in transitioning state forever, resulting in the following warning message after the wait loop times out:
l3-aon-clkctrl:0000:0: failed to disable
Just add the clock to enable_init_clks, so no attempt is made to disable it.
--- drivers/clk/ti/clk-33xx.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/clk/ti/clk-33xx.c +2 -0
@@ -258,6 +258,8 @@ static const char *enable_init_clks[] = {"dpll_ddr_m2_ck" ,"dpll_mpu_m2_ck" ,"l3_gclk" , +/* WKUP_DEBUGSS_CLKCTRL - disable fails, AM335x Errata Advisory 1.0.42 */ +"l3-aon-clkctrl:0000:0" ,/* AM3_L3_L3_MAIN_CLKCTRL, needed during suspend */ "l3-clkctrl:00bc:0" , "l4hs_gclk",
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 710/849 clk: scmi: Add duty cycle ops only when duty cycle is supported
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacky Bai <[email protected]>
[ Upstream commit 18db1ff2dea0f97dedaeadd18b0cb0a0d76154df ]
For some of the SCMI based platforms, the oem extended config may be supported, but not for duty cycle purpose. Skip the duty cycle ops if err return when trying to get duty cycle info.
--- drivers/clk/clk-scmi.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/clk/clk-scmi.c +9 -2
@@ -349,6 +349,8 @@ scmi_clk_ops_select(struct scmi_clk *sclk, bool atomic_capable,unsigned int atomic_threshold_us, const struct clk_ops **clk_ops_db, size_t db_size) { + int ret; +u32 val;const struct scmi_clock_info *ci = sclk->info;unsigned int feats_key =0 ;const struct clk_ops *ops;
@@ -370,8 +372,13 @@ scmi_clk_ops_select(struct scmi_clk *sclk, bool atomic_capable,if (!ci->parent_ctrl_forbidden) feats_key |=BIT (SCMI_CLK_PARENT_CTRL_SUPPORTED ); -if (ci->extended_config) - feats_key |=BIT (SCMI_CLK_DUTY_CYCLE_SUPPORTED ); +if (ci->extended_config) { + ret = scmi_proto_clk_ops->config_oem_get (sclk->ph, sclk->id, +SCMI_CLOCK_CFG_DUTY_CYCLE , + &val,NULL , false); +if (!ret) + feats_key |=BIT (SCMI_CLK_DUTY_CYCLE_SUPPORTED ); + }if (WARN_ON (feats_key >= db_size))return NULL ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 711/849 clk: clocking-wizard: Fix output clock register offset for Versal platforms
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shubhrajyoti Datta <[email protected]>
[ Upstream commit 7c2e86f7b5af93d0e78c16e4359318fe7797671d ]
The output clock register offset used in clk_wzrd_register_output_clocks was incorrectly referencing 0x3C instead of 0x38, which caused misconfiguration of output dividers on Versal platforms.
Correcting the off-by-one error ensures proper configuration of output clocks.
--- drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/xilinx/clk-xlnx-clock-wizard.c +1 -1
@@ -1108,7 +1108,7 @@ static int clk_wzrd_register_output_clocks(struct device *dev, int nr_outputs) (dev, clkout_name, clk_name,0 , clk_wzrd->base, - (WZRD_CLK_CFG_REG (is_versal,3 ) + i *8 ), + (WZRD_CLK_CFG_REG (is_versal,2 ) + i *8 ),WZRD_CLKOUT_DIVIDE_SHIFT ,WZRD_CLKOUT_DIVIDE_WIDTH , CLK_DIVIDER_ONE_BASED |
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 712/849 NTB: epf: Allow arbitrary BAR mapping
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Brunet <[email protected]>
[ Upstream commit 5ad865862a0fd349163243e1834ed98ba9b81905 ]
The NTB epf host driver assumes the BAR number associated with a memory window is just incremented from the BAR number associated with MW1. This seems to have been enough so far but this is not really how the endpoint side work and the two could easily become mis-aligned.
ntb_epf_mw_to_bar() even assumes that the BAR number is the memory window index + 2, which means the function only returns a proper result if BAR_2 is associated with MW1.
Instead, fully describe and allow arbitrary NTB BAR mapping.
--- drivers/ntb/hw/epf/ntb_hw_epf.c | 103 ++++++++++++++++---------------- 1 file changed, 53 insertions(+), 50 deletions(-)
drivers/ntb/hw/epf/ntb_hw_epf.c +53 -50
@@ -49,6 +49,7 @@#define NTB_EPF_COMMAND_TIMEOUT 1000/* 1 Sec */ enum pci_barno { +NO_BAR =-1 ,BAR_0 ,BAR_1 ,BAR_2 ,
@@ -57,16 +58,26 @@ enum pci_barno { BAR_5, }; +enum epf_ntb_bar { +BAR_CONFIG , +BAR_PEER_SPAD , +BAR_DB , +BAR_MW1 , +BAR_MW2 , +BAR_MW3 , +BAR_MW4 , +NTB_BAR_NUM , +}; + +#define NTB_EPF_MAX_MW_COUNT (NTB_BAR_NUM - BAR_MW1) +struct ntb_epf_dev {struct ntb_dev ntb;struct device *dev;/* Mutex to protect providing commands to NTB EPF */ struct mutex cmd_lock; -enum pci_barno ctrl_reg_bar; -enum pci_barno peer_spad_reg_bar; -enum pci_barno db_reg_bar; -enum pci_barno mw_bar; +const enum pci_barno *barno_map;unsigned int mw_count;unsigned int spad_count;
@@ -85,17 +96,6 @@ struct ntb_epf_dev {#define ntb_ndev (__ntb) container_of(__ntb, struct ntb_epf_dev, ntb) -struct ntb_epf_data { -/* BAR that contains both control region and self spad region */ -enum pci_barno ctrl_reg_bar; -/* BAR that contains peer spad region */ -enum pci_barno peer_spad_reg_bar; -/* BAR that contains Doorbell region and Memory window '1' */ -enum pci_barno db_reg_bar; -/* BAR that contains memory windows*/ -enum pci_barno mw_bar; -}; -static int ntb_epf_send_command (struct ntb_epf_dev *ndev,u32 command,u32 argument) {
@@ -144,7 +144,7 @@ static int ntb_epf_mw_to_bar(struct ntb_epf_dev *ndev, int idx)return -EINVAL ; } -return idx +2 ; +return ndev->barno_map[BAR_MW1 + idx]; }static int ntb_epf_mw_count (struct ntb_dev *ntb,int pidx)
@@ -413,7 +413,9 @@ static int ntb_epf_mw_set_trans(struct ntb_dev *ntb, int pidx, int idx,return -EINVAL ; } - bar = idx + ndev->mw_bar; + bar =ntb_epf_mw_to_bar (ndev, idx); +if (bar <0 ) +return bar; mw_size =pci_resource_len (ntb->pdev, bar);
@@ -455,7 +457,9 @@ static int ntb_epf_peer_mw_get_addr(struct ntb_dev *ntb, int idx,if (idx ==0 ) offset =readl (ndev->ctrl_reg +NTB_EPF_MW1_OFFSET ); - bar = idx + ndev->mw_bar; + bar =ntb_epf_mw_to_bar (ndev, idx); +if (bar <0 ) +return bar;if (base) *base =pci_resource_start (ndev->ntb.pdev, bar) + offset;
@@ -560,6 +564,11 @@ static int ntb_epf_init_dev(struct ntb_epf_dev *ndev) ndev->mw_count =readl (ndev->ctrl_reg +NTB_EPF_MW_COUNT ); ndev->spad_count =readl (ndev->ctrl_reg +NTB_EPF_SPAD_COUNT ); +if (ndev->mw_count >NTB_EPF_MAX_MW_COUNT ) { +dev_err (dev,"Unsupported MW count: %u\n" , ndev->mw_count); +return -EINVAL ; + } +return 0 ; }
@@ -596,14 +605,15 @@ static int ntb_epf_init_pci(struct ntb_epf_dev *ndev,dev_warn (&pdev->dev,"Cannot DMA highmem\n" ); } - ndev->ctrl_reg =pci_iomap (pdev, ndev->ctrl_reg_bar,0 ); + ndev->ctrl_reg =pci_iomap (pdev, ndev->barno_map[BAR_CONFIG ],0 );if (!ndev->ctrl_reg) { ret = -EIO ; goto err_pci_regions; } -if (ndev->peer_spad_reg_bar) { - ndev->peer_spad_reg =pci_iomap (pdev, ndev->peer_spad_reg_bar,0 ); +if (ndev->barno_map[BAR_PEER_SPAD ] != ndev->barno_map[BAR_CONFIG ]) { + ndev->peer_spad_reg =pci_iomap (pdev, + ndev->barno_map[BAR_PEER_SPAD ],0 );if (!ndev->peer_spad_reg) { ret = -EIO ; goto err_pci_regions;
@@ -614,7 +624,7 @@ static int ntb_epf_init_pci(struct ntb_epf_dev *ndev, ndev->peer_spad_reg = ndev->ctrl_reg + spad_off + spad_sz; } - ndev->db_reg =pci_iomap (pdev, ndev->db_reg_bar,0 ); + ndev->db_reg =pci_iomap (pdev, ndev->barno_map[BAR_DB ],0 );if (!ndev->db_reg) { ret = -EIO ; goto err_pci_regions;
@@ -659,12 +669,7 @@ static void ntb_epf_cleanup_isr(struct ntb_epf_dev *ndev)static int ntb_epf_pci_probe (struct pci_dev *pdev,const struct pci_device_id *id) { -enum pci_barno peer_spad_reg_bar =BAR_1 ; -enum pci_barno ctrl_reg_bar =BAR_0 ; -enum pci_barno db_reg_bar =BAR_2 ; -enum pci_barno mw_bar =BAR_2 ;struct device *dev = &pdev->dev; -struct ntb_epf_data *data;struct ntb_epf_dev *ndev;int ret;
@@ -675,18 +680,10 @@ static int ntb_epf_pci_probe(struct pci_dev *pdev,if (!ndev)return -ENOMEM ; - data = (struct ntb_epf_data *)id->driver_data; -if (data) { - peer_spad_reg_bar = data->peer_spad_reg_bar; - ctrl_reg_bar = data->ctrl_reg_bar; - db_reg_bar = data->db_reg_bar; - mw_bar = data->mw_bar; - } + ndev->barno_map = (const enum pci_barno *)id->driver_data; +if (!ndev->barno_map) +return -EINVAL ; - ndev->peer_spad_reg_bar = peer_spad_reg_bar; - ndev->ctrl_reg_bar = ctrl_reg_bar; - ndev->db_reg_bar = db_reg_bar; - ndev->mw_bar = mw_bar; ndev->dev = dev;ntb_epf_init_struct (ndev, pdev);
@@ -730,30 +727,36 @@ static void ntb_epf_pci_remove(struct pci_dev *pdev)ntb_epf_deinit_pci (ndev); } -static const struct ntb_epf_data j721e_data = { - .ctrl_reg_bar =BAR_0 , - .peer_spad_reg_bar =BAR_1 , - .db_reg_bar =BAR_2 , - .mw_bar =BAR_2 , +static const enum pci_barno j721e_map[NTB_BAR_NUM ] = { + [BAR_CONFIG ] =BAR_0 , + [BAR_PEER_SPAD ] =BAR_1 , + [BAR_DB ] =BAR_2 , + [BAR_MW1 ] =BAR_2 , + [BAR_MW2 ] =BAR_3 , + [BAR_MW3 ] =BAR_4 , + [BAR_MW4 ] =BAR_5 }; -static const struct ntb_epf_data mx8_data = { - .ctrl_reg_bar =BAR_0 , - .peer_spad_reg_bar =BAR_0 , - .db_reg_bar =BAR_2 , - .mw_bar =BAR_4 , +static const enum pci_barno mx8_map[NTB_BAR_NUM ] = { + [BAR_CONFIG ] =BAR_0 , + [BAR_PEER_SPAD ] =BAR_0 , + [BAR_DB ] =BAR_2 , + [BAR_MW1 ] =BAR_4 , + [BAR_MW2 ] =BAR_5 , + [BAR_MW3 ] =NO_BAR , + [BAR_MW4 ] =NO_BAR };static const struct pci_device_id ntb_epf_pci_tbl[] = { {PCI_DEVICE (PCI_VENDOR_ID_TI ,PCI_DEVICE_ID_TI_J721E ), .class =PCI_CLASS_MEMORY_RAM <<8 , .class_mask =0xffff00 , - .driver_data = (kernel_ulong_t)&j721e_data, + .driver_data = (kernel_ulong_t )j721e_map, }, {PCI_DEVICE (PCI_VENDOR_ID_FREESCALE ,0x0809 ), .class =PCI_CLASS_MEMORY_RAM <<8 , .class_mask =0xffff00 , - .driver_data = (kernel_ulong_t)&mx8_data, + .driver_data = (kernel_ulong_t )mx8_map, }, { }, };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 713/849 9p: fix /sys/fs/9p/caches overwriting itself
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randall P. Embry <[email protected]>
[ Upstream commit 86db0c32f16c5538ddb740f54669ace8f3a1f3d7 ]
caches_show() overwrote its buffer on each iteration, so only the last cache tag was visible in sysfs output.
Properly append with snprintf(buf + count, …).
Message-ID: <[email protected]>
--- fs/9p/v9fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/9p/v9fs.c +1 -1
@@ -561,7 +561,7 @@ static ssize_t caches_show(struct kobject *kobj,spin_lock (&v9fs_sessionlist_lock);list_for_each_entry (v9ses, &v9fs_sessionlist, slist) {if (v9ses->cachetag) { - n =snprintf (buf, limit,"%s\n" , v9ses->cachetag); + n =snprintf (buf + count, limit,"%s\n" , v9ses->cachetag);if (n <0 ) { count = n;break ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 714/849 cpufreq: tegra186: Initialize all cores to max frequencies
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaron Kling <[email protected]>
[ Upstream commit ba6018929165fc914c665f071f8e8cdbac844a49 ]
During initialization, the EDVD_COREx_VOLT_FREQ registers for some cores are still at reset values and not reflecting the actual frequency. This causes get calls to fail. Set all cores to their respective max frequency during probe to initialize the registers to working values.
--- drivers/cpufreq/tegra186-cpufreq.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-)
drivers/cpufreq/tegra186-cpufreq.c +21 -6
@@ -138,13 +138,14 @@ static struct cpufreq_driver tegra186_cpufreq_driver = {static struct cpufreq_frequency_table *init_vhint_table (struct platform_device *pdev,struct tegra_bpmp *bpmp, -struct tegra186_cpufreq_cluster *cluster,unsigned int cluster_id) +struct tegra186_cpufreq_cluster *cluster,unsigned int cluster_id, +int *num_rates) {struct cpufreq_frequency_table *table;struct mrq_cpu_vhint_request req;struct tegra_bpmp_message msg;struct cpu_vhint_data *data; -int err, i, j, num_rates =0 ; +int err, i, j;dma_addr_t phys;void *virt;
@@ -174,6 +175,7 @@ static struct cpufreq_frequency_table *init_vhint_table( goto free; } + *num_rates =0 ;for (i = data->vfloor; i <= data->vceil; i++) {u16 ndiv = data->ndiv[i];
@@ -184,10 +186,10 @@ static struct cpufreq_frequency_table *init_vhint_table(if (i >0 && ndiv == data->ndiv[i -1 ])continue ; - num_rates++; + (*num_rates)++; } - table =devm_kcalloc (&pdev->dev, num_rates +1 ,sizeof (*table), + table =devm_kcalloc (&pdev->dev, *num_rates +1 ,sizeof (*table),GFP_KERNEL );if (!table) { table =ERR_PTR (-ENOMEM );
@@ -229,7 +231,9 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev) {struct tegra186_cpufreq_data *data;struct tegra_bpmp *bpmp; -unsigned int i =0 , err; +unsigned int i =0 , err, edvd_offset; +int num_rates =0 ; +u32 edvd_val, cpu; data = devm_kzalloc(&pdev->dev, struct_size(data, clusters, TEGRA186_NUM_CLUSTERS),
@@ -252,10 +256,21 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev)for (i =0 ; i <TEGRA186_NUM_CLUSTERS ; i++) {struct tegra186_cpufreq_cluster *cluster = &data->clusters[i]; - cluster->table =init_vhint_table (pdev, bpmp, cluster, i); + cluster->table =init_vhint_table (pdev, bpmp, cluster, i, &num_rates);if (IS_ERR (cluster->table)) { err =PTR_ERR (cluster->table); goto put_bpmp; + }else if (!num_rates) { + err = -EINVAL ; + goto put_bpmp; + } + +for (cpu =0 ; cpu <ARRAY_SIZE (tegra186_cpus); cpu++) { +if (data->cpus[cpu].bpmp_cluster_id == i) { + edvd_val = cluster->table[num_rates -1 ].driver_data; + edvd_offset = data->cpus[cpu].edvd_offset; +writel (edvd_val, data->regs + edvd_offset); + } } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 715/849 9p: sysfs_init: dont hardcode error to ENOMEM
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randall P. Embry <[email protected]>
[ Upstream commit 528f218b31aac4bbfc58914d43766a22ab545d48 ]
v9fs_sysfs_init() always returned -ENOMEM on failure; return the actual sysfs_create_group() error instead.
Message-ID: <[email protected]>
--- fs/9p/v9fs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/9p/v9fs.c +5 -2
@@ -597,13 +597,16 @@ static const struct attribute_group v9fs_attr_group = {static int __init v9fs_sysfs_init (void ) { +int ret; + v9fs_kobj =kobject_create_and_add ("9p" , fs_kobj);if (!v9fs_kobj)return -ENOMEM ; -if (sysfs_create_group (v9fs_kobj, &v9fs_attr_group)) { + ret =sysfs_create_group (v9fs_kobj, &v9fs_attr_group); +if (ret) {kobject_put (v9fs_kobj); -return -ENOMEM ; +return ret; }return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 716/849 scsi: ufs: core: Include UTP error in INT_FATAL_ERRORS
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hoyoung Seo <[email protected]>
[ Upstream commit 558ae4579810fa0fef011944230c65a6f3087f85 ]
When a UTP error occurs in isolation, UFS is not currently recoverable. This is because the UTP error is not considered fatal in the error handling code, leading to either an I/O timeout or an OCS error.
Add the UTP error flag to INT_FATAL_ERRORS so the controller will be reset in this situation.
sd 0:0:0:0: [sda] tag#38 UNKNOWN(0x2003) Result: hostbyte=0x07 driverbyte=DRIVER_OK cmd_age=0s
sd 0:0:0:0: [sda] tag#38 CDB: opcode=0x28 28 00 00 51 24 e2 00 00 08 00 I/O error, dev sda, sector 42542864 op 0x0:(READ) flags 0x80700 phys_seg 8 prio class 2
OCS error from controller = 9 for tag 39
pa_err[1] = 0x80000010 at 2667224756 us
pa_err: total cnt=2
dl_err[0] = 0x80000002 at 2667148060 us
dl_err[1] = 0x80002000 at 2667282844 us
No record of nl_err
No record of tl_err
No record of dme_err
No record of auto_hibern8_err
fatal_err[0] = 0x804 at 2667282836 us
---------------------------------------------------
REGISTER
---------------------------------------------------
NAME OFFSET VALUE
STD HCI SFR 0xfffffff0 0x0
AHIT 0x18 0x814
INTERRUPT STATUS 0x20 0x1000
INTERRUPT ENABLE 0x24 0x70ef5[mkp: commit desc]
Message-Id: <[email protected]>
--- include/ufs/ufshci.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
include/ufs/ufshci.h +3 -1
@@ -180,6 +180,7 @@ static inline u32 ufshci_version(u32 major, u32 minor)#define UTP_TASK_REQ_COMPL 0x200#define UIC_COMMAND_COMPL 0x400#define DEVICE_FATAL_ERROR 0x800 +#define UTP_ERROR 0x1000#define CONTROLLER_FATAL_ERROR 0x10000#define SYSTEM_BUS_FATAL_ERROR 0x20000#define CRYPTO_ENGINE_FATAL_ERROR 0x40000
@@ -199,7 +200,8 @@ static inline u32 ufshci_version(u32 major, u32 minor) CONTROLLER_FATAL_ERROR |\ SYSTEM_BUS_FATAL_ERROR |\ CRYPTO_ENGINE_FATAL_ERROR |\ - UIC_LINK_LOST) + UIC_LINK_LOST |\ + UTP_ERROR)/* HCS - Host Controller Status 30h */ #define DEVICE_PRESENT 0x1
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 717/849 fbdev: core: Fix ubsan warning in pixel_to_pat
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zsolt Kajtar <[email protected]>
[ Upstream commit aad1d99beaaf132e2024a52727c24894cdf9474a ]
It could be triggered on 32 bit big endian machines at 32 bpp in the pattern realignment. In this case just return early as the result is an identity.
--- drivers/video/fbdev/core/fb_fillrect.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/video/fbdev/core/fb_fillrect.h +1 -2
@@ -92,8 +92,7 @@ static unsigned long pixel_to_pat(int bpp, u32 color) pattern = pattern | pattern << bpp;break ;default : - pattern = color; -break ; +return color; }#ifndef __LITTLE_ENDIAN pattern <<= (BITS_PER_LONG % bpp);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 718/849 ACPI: property: Return present device nodes only on fwnode interface
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sakari Ailus <[email protected]>
[ Upstream commit d9f866b2bb3eec38b3734f1fed325ec7c55ccdfa ]
fwnode_graph_get_next_subnode() may return fwnode backed by ACPI device nodes and there has been no check these devices are present in the system, unlike there has been on fwnode OF backend.
In order to provide consistent behaviour towards callers, add a check for device presence by introducing
a new function acpi_get_next_present_subnode(), used as the get_next_child_node() fwnode operation that also checks device node presence.
--- drivers/acpi/property.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)
drivers/acpi/property.c +23 -1
@@ -1357,6 +1357,28 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode,return NULL ; } +/* +* acpi_get_next_present_subnode - Return the next present child node handle +* @fwnode: Firmware node to find the next child node for. +* @child: Handle to one of the device's child nodes or a null handle. +* +* Like acpi_get_next_subnode(), but the device nodes returned by +* acpi_get_next_present_subnode() are guaranteed to be present. +* +* Returns: The fwnode handle of the next present sub-node. +*/ +static struct fwnode_handle * +acpi_get_next_present_subnode (const struct fwnode_handle *fwnode, +struct fwnode_handle *child) +{ +do { + child =acpi_get_next_subnode (fwnode, child); + }while (is_acpi_device_node (child) && + !acpi_device_is_present (to_acpi_device_node (child))); + +return child; +} +/** * acpi_node_get_parent - Return parent fwnode of this fwnode * @fwnode: Firmware node whose parent to get
@@ -1701,7 +1723,7 @@ static int acpi_fwnode_irq_get(const struct fwnode_handle *fwnode, .property_read_string_array = \ acpi_fwnode_property_read_string_array, \ .get_parent = acpi_node_get_parent, \ - .get_next_child_node = acpi_get_next_subnode, \ + .get_next_child_node = acpi_get_next_present_subnode, \ .get_named_child_node = acpi_fwnode_get_named_child_node, \ .get_name = acpi_fwnode_get_name, \ .get_name_prefix = acpi_fwnode_get_name_prefix, \
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 719/849 LoongArch: Handle new atomic instructions for probes
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiezhu Yang <[email protected]>
[ Upstream commit db740f5689e61f2e75b73e5c8e7c985a3b4bc045 ]
The atomic instructions sc.q, llacq.{w/d}, screl.{w/d} were newly added in the LoongArch Reference Manual v1.10, it is necessary to handle them in insns_not_supported() to avoid putting a breakpoint in the middle of a ll/sc atomic sequence, otherwise it will loop forever for kprobes and uprobes.
--- arch/loongarch/include/asm/inst.h | 5 +++++ arch/loongarch/kernel/inst.c | 12 ++++++++++++ 2 files changed, 17 insertions(+)
arch/loongarch/include/asm/inst.h +5 -0
@@ -77,6 +77,10 @@ enum reg2_op { iocsrwrh_op =0x19205 , iocsrwrw_op =0x19206 , iocsrwrd_op =0x19207 , + llacqw_op =0xe15e0 , + screlw_op =0xe15e1 , + llacqd_op =0xe15e2 , + screld_op = 0xe15e3, }; enum reg2i5_op {
@@ -189,6 +193,7 @@ enum reg3_op { fldxd_op =0x7068 , fstxs_op =0x7070 , fstxd_op =0x7078 , + scq_op =0x70ae , amswapw_op =0x70c0 , amswapd_op =0x70c1 , amaddw_op = 0x70c2,
arch/loongarch/kernel/inst.c +12 -0
@@ -141,6 +141,9 @@ bool insns_not_supported(union loongarch_instruction insn) case amswapw_op ... ammindbdu_op:pr_notice ("atomic memory access instructions are not supported\n" );return true; +case scq_op: +pr_notice ("sc.q instruction is not supported\n" ); +return true; }switch (insn.reg2i14_format.opcode) {
@@ -152,6 +155,15 @@ bool insns_not_supported(union loongarch_instruction insn)return true; } +switch (insn.reg2_format.opcode) { +case llacqw_op: +case llacqd_op: +case screlw_op: +case screld_op: +pr_notice ("llacq and screl instructions are not supported\n" ); +return true; + } +switch (insn.reg1i21_format.opcode) {case bceqz_op:pr_notice ("bceqz and bcnez instructions are not supported\n" );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 720/849 tools bitmap: Add missing asm-generic/bitsperlong.h include
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Rogers <[email protected]>
[ Upstream commit f38ce0209ab4553906b44bd1159e35c740a84161 ]
small_const_nbits is defined in asm-generic/bitsperlong.h which bitmap.h uses but doesn't include causing build failures in some build systems. Add the missing #include.
Note the bitmap.h in tools has diverged from that of the kernel, so no changes are made there.
--- tools/include/linux/bitmap.h | 1 + 1 file changed, 1 insertion(+)
tools/include/linux/bitmap.h +1 -0
@@ -3,6 +3,7 @@#define _TOOLS_LINUX_BITMAP_H#include <string.h> +#include <asm-generic/bitsperlong.h> #include <linux/align.h> #include <linux/bitops.h> #include <linux/find.h>
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 721/849 tools: lib: thermal: dont preserve owner in install
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emil Dahl Juhl <[email protected]>
[ Upstream commit 1375152bb02ab2a8435e87ea27034482dbc95f57 ]
Instead of preserving mode, timestamp, and owner, for the object files during installation, just preserve the mode and timestamp.
When installing as root, the installed files should be owned by root. When installing as user, --preserve=ownership doesn't work anyway. This makes --preserve=ownership rather pointless.
--- tools/lib/thermal/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/lib/thermal/Makefile +1 -1
@@ -134,7 +134,7 @@ endef install_lib: libs $(call QUIET_INSTALL, $(LIBTHERMAL_ALL)) \ $(call do_install_mkdir,$(libdir_SQ)); \ - cp -fpR $(LIBTHERMAL_ALL) $(DESTDIR)$(libdir_SQ) + cp -fR --preserve=mode,timestamp $(LIBTHERMAL_ALL) $(DESTDIR)$(libdir_SQ) install_headers: $(call QUIET_INSTALL, headers) \
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 722/849 tools: lib: thermal: use pkg-config to locate libnl3
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sascha Hauer <[email protected]>
[ Upstream commit b31f7f725cd932e2c2b41f3e4b66273653953687 ]
To make libthermal more cross compile friendly use pkg-config to locate libnl3. Only if that fails fall back to hardcoded /usr/include/libnl3.
--- tools/lib/thermal/Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
tools/lib/thermal/Makefile +6 -1
@@ -46,8 +46,12 @@ else CFLAGS := -g -Wall endif +NL3_CFLAGS = $(shell pkg-config --cflags libnl-3.0 2>/dev/null) +ifeq ($(NL3_CFLAGS),) +NL3_CFLAGS = -I/usr/include/libnl3 +endif + INCLUDES = \ --I/usr/include/libnl3 \ -I$(srctree)/tools/lib/thermal/include \ -I$(srctree)/tools/lib/ \ -I$(srctree)/tools/include \
@@ -59,6 +63,7 @@ INCLUDES = \ override CFLAGS += $(EXTRA_WARNINGS) override CFLAGS += -Werror -Wall override CFLAGS += -fPIC +override CFLAGS += $(NL3_CFLAGS) override CFLAGS += $(INCLUDES) override CFLAGS += -fvisibility=hidden override CFGLAS += -Wl,-L.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 723/849 fbdev: Add bounds checking in bit_putcs to fix vmalloc-out-of-bounds
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Albin Babu Varghese <[email protected]>
[ Upstream commit 3637d34b35b287ab830e66048841ace404382b67 ]
Add bounds checking to prevent writes past framebuffer boundaries when rendering text near screen edges. Return early if the Y position is off-screen and clip image height to screen boundary. Break from the rendering loop if the X position is off-screen. When clipping image width to fit the screen, update the character count to match the clipped width to prevent buffer size mismatches.
Without the character count update, bit_putcs_aligned and bit_putcs_unaligned receive mismatched parameters where the buffer is allocated for the clipped width but cnt reflects the original larger count, causing out-of-bounds writes.
--- drivers/video/fbdev/core/bitblit.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
drivers/video/fbdev/core/bitblit.c +17 -0
@@ -168,6 +168,11 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, image.height = vc->vc_font.height; image.depth =1 ; +if (image.dy >= info->var.yres) +return ; + + image.height =min (image.height, info->var.yres - image.dy); +if (attribute) { buf =kmalloc (cellsize,GFP_ATOMIC );if (!buf)
@@ -181,6 +186,18 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, cnt = count; image.width = vc->vc_font.width * cnt; + +if (image.dx >= info->var.xres) +break ; + +if (image.dx + image.width > info->var.xres) { + image.width = info->var.xres - image.dx; + cnt = image.width / vc->vc_font.width; +if (cnt ==0 ) +break ; + image.width = cnt * vc->vc_font.width; + } + pitch =DIV_ROUND_UP (image.width,8 ) + scan_align; pitch &= ~scan_align; size = pitch * image.height + buf_align;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 724/849 ALSA: hda/realtek: Add quirk for ASUS ROG Zephyrus Duo
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adam Holliday <[email protected]>
[ Upstream commit 328b80b29a6a165c47fcc04d2bef3e09ed1d28f9 ]
The ASUS ROG Zephyrus Duo 15 SE (GX551QS) with ALC 289 codec requires specific pin configuration for proper volume control. Without this quirk, volume adjustments produce a muffled sound effect as only certain channels attenuate, leaving bass frequency at full volume.
Testing with hdajackretask confirms these pin tweaks fix the issue:
- Pin 0x17: Internal Speaker (LFE)
- Pin 0x1e: Internal Speaker
--- sound/hda/codecs/realtek/alc269.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
sound/hda/codecs/realtek/alc269.c +10 -0
@@ -3737,6 +3737,7 @@ enum {ALC285_FIXUP_ASUS_GA605K_HEADSET_MIC ,ALC285_FIXUP_ASUS_GA605K_I2C_SPEAKER2_TO_DAC1 ,ALC269_FIXUP_POSITIVO_P15X_HEADSET_MIC , + ALC289_FIXUP_ASUS_ZEPHYRUS_DUAL_SPK, };/* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -6166,6 +6167,14 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE, }, + [ALC289_FIXUP_ASUS_ZEPHYRUS_DUAL_SPK] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl []) { + {0x17 ,0x90170151 },/* Internal Speaker LFE */ + {0x1e ,0x90170150 },/* Internal Speaker */ + { } + }, + } };static const struct hda_quirk alc269_fixup_tbl[] = {
@@ -6721,6 +6730,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {SND_PCI_QUIRK (0x1043 ,0x1517 ,"Asus Zenbook UX31A" ,ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A ),SND_PCI_QUIRK (0x1043 ,0x1533 ,"ASUS GV302XA/XJ/XQ/XU/XV/XI" ,ALC287_FIXUP_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x1043 ,0x1573 ,"ASUS GZ301VV/VQ/VU/VJ/VA/VC/VE/VVC/VQC/VUC/VJC/VEC/VCC" ,ALC285_FIXUP_ASUS_HEADSET_MIC ), +SND_PCI_QUIRK (0x1043 ,0x1652 ,"ASUS ROG Zephyrus Do 15 SE" ,ALC289_FIXUP_ASUS_ZEPHYRUS_DUAL_SPK ),SND_PCI_QUIRK (0x1043 ,0x1662 ,"ASUS GV301QH" ,ALC294_FIXUP_ASUS_DUAL_SPK ),SND_PCI_QUIRK (0x1043 ,0x1663 ,"ASUS GU603ZI/ZJ/ZQ/ZU/ZV" ,ALC285_FIXUP_ASUS_HEADSET_MIC ), SND_PCI_QUIRK(0x1043, 0x1683, "ASUS UM3402YAR", ALC287_FIXUP_CS35L41_I2C_2),
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 725/849 rtc: zynqmp: Restore alarm functionality after kexec transition
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harini T <[email protected]>
[ Upstream commit e22f4d1321e0055065f274e20bf6d1dbf4b500f5 ]
During kexec reboots, RTC alarms that are fired during the kernel transition experience delayed execution. The new kernel would eventually honor these alarms, but the interrupt handlers would only execute after the driver probe is completed rather than at the intended alarm time.
This is because pending alarm interrupt status from the previous kernel is not properly cleared during driver initialization, causing timing discrepancies in alarm delivery.
To ensure precise alarm timing across kexec transitions, enhance the probe function to:
1. Clear any pending alarm interrupt status from previous boot.
2. Detect existing valid alarms and preserve their state.
3. Re-enable alarm interrupts for future alarms.
--- drivers/rtc/rtc-zynqmp.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
drivers/rtc/rtc-zynqmp.c +19 -0
@@ -277,6 +277,10 @@ static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)static int xlnx_rtc_probe (struct platform_device *pdev) {struct xlnx_rtc_dev *xrtcdev; +bool is_alarm_set = false; +u32 pending_alrm_irq; +u32 current_time; +u32 alarm_time;int ret; xrtcdev =devm_kzalloc (&pdev->dev,sizeof (*xrtcdev),GFP_KERNEL );
@@ -296,6 +300,17 @@ static int xlnx_rtc_probe(struct platform_device *pdev)if (IS_ERR (xrtcdev->reg_base))return PTR_ERR (xrtcdev->reg_base); +/* Clear any pending alarm interrupts from previous kernel/boot */ + pending_alrm_irq =readl (xrtcdev->reg_base +RTC_INT_STS ) &RTC_INT_ALRM ; +if (pending_alrm_irq) +writel (pending_alrm_irq, xrtcdev->reg_base +RTC_INT_STS ); + +/* Check if a valid alarm is already set from previous kernel/boot */ + alarm_time =readl (xrtcdev->reg_base +RTC_ALRM ); + current_time =readl (xrtcdev->reg_base +RTC_CUR_TM ); +if (alarm_time > current_time && alarm_time !=0 ) + is_alarm_set = true; + xrtcdev->alarm_irq =platform_get_irq_byname (pdev,"alarm" );if (xrtcdev->alarm_irq <0 )return xrtcdev->alarm_irq;
@@ -337,6 +352,10 @@ static int xlnx_rtc_probe(struct platform_device *pdev)xlnx_init_rtc (xrtcdev); +/* Re-enable alarm interrupt if a valid alarm was found */ +if (is_alarm_set) +writel (RTC_INT_ALRM , xrtcdev->reg_base +RTC_INT_EN ); +device_init_wakeup (&pdev->dev, true);return devm_rtc_register_device (xrtcdev->rtc);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 726/849 rtc: pcf2127: fix watchdog interrupt mask on pcf2131
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bruno Thomsen <[email protected]>
[ Upstream commit 87064da2db7be537a7da20a25c18ba912c4db9e1 ]
When using interrupt pin (INT A) as watchdog output all other interrupt sources need to be disabled to avoid additional resets. Resulting INT_A_MASK1 value is 55 (0x37).
--- drivers/rtc/rtc-pcf2127.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
drivers/rtc/rtc-pcf2127.c +15 -0
@@ -608,6 +608,21 @@ static int pcf2127_watchdog_init(struct device *dev, struct pcf2127 *pcf2127)set_bit (WDOG_HW_RUNNING , &pcf2127->wdd.status); } +/* +* When using interrupt pin (INT A) as watchdog output, only allow +* watchdog interrupt (PCF2131_BIT_INT_WD_CD) and disable (mask) all +* other interrupts. +*/ +if (pcf2127->cfg->type ==PCF2131 ) { + ret =regmap_write (pcf2127->regmap, +PCF2131_REG_INT_A_MASK1 , +PCF2131_BIT_INT_BLIE | +PCF2131_BIT_INT_BIE | +PCF2131_BIT_INT_AIE | +PCF2131_BIT_INT_SI | +PCF2131_BIT_INT_MI ); + } +return devm_watchdog_register_device (dev, &pcf2127->wdd); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 727/849 net: wwan: t7xx: add support for HP DRMR-H01
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sammy Hsu <[email protected]>
[ Upstream commit 370e98728bda92b1bdffb448d1acdcbe19dadb4c ]
add support for HP DRMR-H01 (0x03f0, 0x09c8)
--- drivers/net/wwan/t7xx/t7xx_pci.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wwan/t7xx/t7xx_pci.c +1 -0
@@ -939,6 +939,7 @@ static void t7xx_pci_remove(struct pci_dev *pdev)static const struct pci_device_id t7xx_pci_table[] = { {PCI_DEVICE (PCI_VENDOR_ID_MEDIATEK ,0x4d75 ) }, + {PCI_DEVICE (0x03f0 ,0x09c8 ) },// HP DRMR-H01 {PCI_DEVICE (0x14c0 ,0x4d75 ) },// Dell DW5933e { } };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 728/849 kbuild: uapi: Strip comments before size type check
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven <[email protected]>
[ Upstream commit 66128f4287b04aef4d4db9bf5035985ab51487d5 ]
On m68k, check_sizetypes in headers_check reports:
./usr/include/asm/bootinfo-amiga.h:17: found __[us]{8,16,32,64} type without #include <linux/types.h>This header file does not use any of the Linux-specific integer types, but merely refers to them from comments, so this is a false positive. As of commit c3a9d74ee413bdb3 ("kbuild: uapi: upgrade check_sizetypes() warning to error"), this check was promoted to an error, breaking m68k all{mod,yes}config builds.
Fix this by stripping simple comments before looking for Linux-specific integer types.
[nathan: Adjust comment and remove unnecessary escaping from slashes in
regex]
--- usr/include/headers_check.pl | 2 ++ 1 file changed, 2 insertions(+)
usr/include/headers_check.pl +2 -0
@@ -155,6 +155,8 @@ sub check_sizetypes if (my $included = ($line =~ /^\s*#\s*include\s+[<"](\S+)[>"]/)[0]) { check_include_typesh($included); } + # strip single-line comments, as types may be referenced within them + $line =~ s@/\*.*?\*/@@; if ($line =~ m/__[us](8|16|32|64)\b/) { printf STDERR "$filename:$lineno: " . "found __[us]{8,16,32,64} type " .
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 729/849 ASoC: meson: aiu-encoder-i2s: fix bit clock polarity
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Valerio Setti <[email protected]>
[ Upstream commit 4c4ed5e073a923fb3323022e1131cb51ad8df7a0 ]
According to I2S specs audio data is sampled on the rising edge of the clock and it can change on the falling one. When operating in normal mode this SoC behaves the opposite so a clock polarity inversion is required in this case.
This was tested on an OdroidC2 (Amlogic S905 SoC) board.
--- sound/soc/meson/aiu-encoder-i2s.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
sound/soc/meson/aiu-encoder-i2s.c +6 -3
@@ -236,8 +236,12 @@ static int aiu_encoder_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) inv == SND_SOC_DAIFMT_IB_IF) val |=AIU_CLK_CTRL_LRCLK_INVERT ; -if (inv ==SND_SOC_DAIFMT_IB_NF || - inv ==SND_SOC_DAIFMT_IB_IF ) +/* +* The SoC changes data on the rising edge of the bitclock +* so an inversion of the bitclock is required in normal mode +*/ +if (inv ==SND_SOC_DAIFMT_NB_NF || + inv ==SND_SOC_DAIFMT_NB_IF ) val |=AIU_CLK_CTRL_AOCLK_INVERT ;/* Signal skew */
@@ -328,4 +332,3 @@ const struct snd_soc_dai_ops aiu_encoder_i2s_dai_ops = { .startup = aiu_encoder_i2s_startup, .shutdown = aiu_encoder_i2s_shutdown, }; -
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 730/849 ASoC: rt722: add settings for rt722VB
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuming Fan <[email protected]>
[ Upstream commit a27539810e1e61efcfdeb51777ed875dc61e9d49 ]
This patch adds settings for RT722VB.
--- sound/soc/codecs/rt722-sdca-sdw.c | 2 +- sound/soc/codecs/rt722-sdca.c | 14 ++++++++++++++ sound/soc/codecs/rt722-sdca.h | 6 ++++++ 3 files changed, 21 insertions(+), 1 deletion(-)
sound/soc/codecs/rt722-sdca-sdw.c +1 -1
@@ -21,7 +21,7 @@ static int rt722_sdca_mbq_size(struct device *dev, unsigned int reg)switch (reg) { case 0x2f01 ... 0x2f0a: case 0x2f35 ... 0x2f36: -case 0x2f50 : + case 0x2f50 ... 0x2f52:case 0x2f54 : case 0x2f58 ... 0x2f5d:case SDW_SDCA_CTL (FUNC_NUM_JACK_CODEC ,RT722_SDCA_ENT0 ,RT722_SDCA_CTL_FUNC_STATUS ,0 ):
sound/soc/codecs/rt722-sdca.c +14 -0
@@ -1378,6 +1378,9 @@ static void rt722_sdca_dmic_preset(struct rt722_sdca_priv *rt722)/* PHYtiming TDZ/TZD control */ regmap_write (rt722->regmap,0x2f03 ,0x06 ); +if (rt722->hw_vid ==RT722_VB ) +regmap_write (rt722->regmap,0x2f52 ,0x00 ); +/* clear flag */ regmap_write(rt722->regmap, SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT0, RT722_SDCA_CTL_FUNC_STATUS, 0),
@@ -1415,6 +1418,9 @@ static void rt722_sdca_amp_preset(struct rt722_sdca_priv *rt722)SDW_SDCA_CTL (FUNC_NUM_AMP ,RT722_SDCA_ENT_OT23 , RT722_SDCA_CTL_VENDOR_DEF, CH_08), 0x04); +if (rt722->hw_vid ==RT722_VB ) +regmap_write (rt722->regmap,0x2f54 ,0x00 ); +/* clear flag */ regmap_write(rt722->regmap, SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT0, RT722_SDCA_CTL_FUNC_STATUS, 0),
@@ -1506,6 +1512,9 @@ static void rt722_sdca_jack_preset(struct rt722_sdca_priv *rt722)rt722_sdca_index_write (rt722,RT722_VENDOR_REG ,RT722_DIGITAL_MISC_CTRL4 ,0x0010 ); +if (rt722->hw_vid ==RT722_VB ) +regmap_write (rt722->regmap,0x2f51 ,0x00 ); +/* clear flag */ regmap_write(rt722->regmap, SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT0, RT722_SDCA_CTL_FUNC_STATUS, 0),
@@ -1516,6 +1525,7 @@ static void rt722_sdca_jack_preset(struct rt722_sdca_priv *rt722)int rt722_sdca_io_init (struct device *dev,struct sdw_slave *slave) {struct rt722_sdca_priv *rt722 =dev_get_drvdata (dev); +unsigned int val; rt722->disable_irq = false;
@@ -1545,6 +1555,10 @@ int rt722_sdca_io_init(struct device *dev, struct sdw_slave *slave)pm_runtime_get_noresume (&slave->dev); +rt722_sdca_index_read (rt722,RT722_VENDOR_REG ,RT722_JD_PRODUCT_NUM , &val); + rt722->hw_vid = (val &0x0f00 ) >>8 ; +dev_dbg (&slave->dev,"%s hw_vid=0x%x\n" , __func__, rt722->hw_vid); +rt722_sdca_dmic_preset (rt722);rt722_sdca_amp_preset (rt722);rt722_sdca_jack_preset (rt722);
sound/soc/codecs/rt722-sdca.h +6 -0
@@ -39,6 +39,7 @@ struct rt722_sdca_priv {/* For DMIC */ bool fu1e_dapm_mute;bool fu1e_mixer_mute[4 ]; +int hw_vid; };struct rt722_sdca_dmic_kctrl_priv {
@@ -233,6 +234,11 @@ enum rt722_sdca_jd_src { RT722_JD1, }; +enum rt722_sdca_version { +RT722_VA , +RT722_VB , +}; +int rt722_sdca_io_init (struct device *dev,struct sdw_slave *slave);int rt722_sdca_init (struct device *dev,struct regmap *regmap,struct sdw_slave *slave); int rt722_sdca_index_write(struct rt722_sdca_priv *rt722,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 731/849 drm/amdkfd: Fix mmap write lock not release
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philip Yang <[email protected]>
[ Upstream commit 7574f30337e19045f03126b4c51f525b84e5049e ]
If mmap write lock is taken while draining retry fault, mmap write lock is not released because svm_range_restore_pages calls mmap_read_unlock then returns. This causes deadlock and system hangs later because mmap read or write lock cannot be taken.
Downgrade mmap write lock to read lock if draining retry fault fix this bug.
--- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdkfd/kfd_svm.c +2 -0
@@ -3046,6 +3046,8 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,if (svms->checkpoint_ts[gpuidx] !=0 ) {if (amdgpu_ih_ts_after_or_equal (ts, svms->checkpoint_ts[gpuidx])) {pr_debug ("draining retry fault, drop fault 0x%llx\n" , addr); +if (write_locked) +mmap_write_downgrade (mm); r = -EAGAIN ; goto out_unlock_svms; }else {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 732/849 drm/amdgpu: Report individual reset error
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lijo Lazar <[email protected]>
[ Upstream commit 2e97663760e5fb7ee14f399c68e57b894f01e505 ]
If reinitialization of one of the GPUs fails after reset, it logs failure on all subsequent GPUs eventhough they have resumed successfully.
A sample log where only device at 0000:95:00.0 had a failure -
amdgpu 0000:15:00.0: amdgpu: GPU reset(19) succeeded! amdgpu 0000:65:00.0: amdgpu: GPU reset(19) succeeded! amdgpu 0000:75:00.0: amdgpu: GPU reset(19) succeeded! amdgpu 0000:85:00.0: amdgpu: GPU reset(19) succeeded! amdgpu 0000:95:00.0: amdgpu: GPU reset(19) failed amdgpu 0000:e5:00.0: amdgpu: GPU reset(19) failed amdgpu 0000:f5:00.0: amdgpu: GPU reset(19) failed amdgpu 0000:05:00.0: amdgpu: GPU reset(19) failed amdgpu 0000:15:00.0: amdgpu: GPU reset end with ret = -5
To avoid confusion, report the error for each device separately and return the first error as the overall result.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 25 +++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +15 -10
@@ -6337,23 +6337,28 @@ static int amdgpu_device_sched_resume(struct list_head *device_list,if (!drm_drv_uses_atomic_modeset (adev_to_drm (tmp_adev)) && !job_signaled)drm_helper_resume_force_mode (adev_to_drm (tmp_adev)); -if (tmp_adev->asic_reset_res) - r = tmp_adev->asic_reset_res; - - tmp_adev->asic_reset_res =0 ; - -if (r) { +if (tmp_adev->asic_reset_res) {/* bad news, how to tell it to userspace ? * for ras error, we should report GPU bad status instead of * reset failure */ if (reset_context->src !=AMDGPU_RESET_SRC_RAS || !amdgpu_ras_eeprom_check_err_threshold (tmp_adev)) -dev_info (tmp_adev->dev,"GPU reset(%d) failed\n" , -atomic_read (&tmp_adev->gpu_reset_counter)); -amdgpu_vf_error_put (tmp_adev,AMDGIM_ERROR_VF_GPU_RESET_FAIL ,0 , r); +dev_info ( + tmp_adev->dev, +"GPU reset(%d) failed with error %d \n" , +atomic_read ( + &tmp_adev->gpu_reset_counter), + tmp_adev->asic_reset_res); +amdgpu_vf_error_put (tmp_adev, +AMDGIM_ERROR_VF_GPU_RESET_FAIL ,0 , + tmp_adev->asic_reset_res); +if (!r) + r = tmp_adev->asic_reset_res; + tmp_adev->asic_reset_res =0 ; }else { -dev_info (tmp_adev->dev,"GPU reset(%d) succeeded!\n" ,atomic_read (&tmp_adev->gpu_reset_counter)); +dev_info (tmp_adev->dev,"GPU reset(%d) succeeded!\n" , +atomic_read (&tmp_adev->gpu_reset_counter));if (amdgpu_acpi_smart_shift_update (tmp_adev,AMDGPU_SS_DEV_D0 )) dev_warn(tmp_adev->dev,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 733/849 ceph: add checking of wait_for_completion_killable() return value
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viacheslav Dubeyko <[email protected]>
[ Upstream commit b7ed1e29cfe773d648ca09895b92856bd3a2092d ]
The Coverity Scan service has detected the calling of wait_for_completion_killable() without checking the return value in ceph_lock_wait_for_completion() [1]. The CID 1636232 defect contains explanation: "If the function returns an error value, the error value may be mistaken for a normal value. In ceph_lock_wait_for_completion(): Value returned from a function is not checked for errors before being used. (CWE-252)".
The patch adds the checking of wait_for_completion_killable() return value and return the error code from ceph_lock_wait_for_completion().
[1] https://scan5.scan.coverity.com/#/project-view/64304/10063?selectedIssue=1636232
--- fs/ceph/locks.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/ceph/locks.c +4 -1
@@ -221,7 +221,10 @@ static int ceph_lock_wait_for_completion(struct ceph_mds_client *mdsc,if (err && err != -ERESTARTSYS )return err; -wait_for_completion_killable (&req->r_safe_completion); + err =wait_for_completion_killable (&req->r_safe_completion); +if (err) +return err; +return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 734/849 ceph: fix potential race condition in ceph_ioctl_lazyio()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viacheslav Dubeyko <[email protected]>
[ Upstream commit 5824ccba9a39a3ad914fc9b2972a2c1119abaac9 ]
The Coverity Scan service has detected potential
race condition in ceph_ioctl_lazyio() [1].
The CID 1591046 contains explanation: "Check of thread-shared field evades lock acquisition (LOCK_EVASION). Thread1 sets fmode to a new value. Now the two threads have an inconsistent view of fmode and updates to fields correlated with fmode may be lost. The data guarded by this critical section may be read while in an inconsistent state or modified by multiple racing threads. In ceph_ioctl_lazyio: Checking the value of a thread-shared field outside of a locked region to determine if a locked operation involving that thread shared field has completed. (CWE-543)".
The patch places fi->fmode field access under ci->i_ceph_lock protection. Also, it introduces the is_file_already_lazy variable that is set under the lock and it is checked later out of scope of critical section.
[1] https://scan5.scan.coverity.com/#/project-view/64304/10063?selectedIssue=1591046
--- fs/ceph/ioctl.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
fs/ceph/ioctl.c +12 -5
@@ -246,21 +246,28 @@ static long ceph_ioctl_lazyio(struct file *file)struct ceph_inode_info *ci =ceph_inode (inode);struct ceph_mds_client *mdsc =ceph_inode_to_fs_client (inode)->mdsc;struct ceph_client *cl = mdsc->fsc->client; +bool is_file_already_lazy = false; +spin_lock (&ci->i_ceph_lock);if ((fi->fmode &CEPH_FILE_MODE_LAZY ) ==0 ) { -spin_lock (&ci->i_ceph_lock); fi->fmode |=CEPH_FILE_MODE_LAZY ; ci->i_nr_by_mode[ffs (CEPH_FILE_MODE_LAZY )]++;__ceph_touch_fmode (ci, mdsc, fi->fmode); -spin_unlock (&ci->i_ceph_lock); + }else { + is_file_already_lazy = true; + } +spin_unlock (&ci->i_ceph_lock); + +if (is_file_already_lazy) { +doutc (cl,"file %p %p %llx.%llx already lazy\n" , file, inode, +ceph_vinop (inode)); + }else {doutc (cl,"file %p %p %llx.%llx marked lazy\n" , file, inode,ceph_vinop (inode));ceph_check_caps (ci,0 ); - }else { -doutc (cl,"file %p %p %llx.%llx already lazy\n" , file, inode, -ceph_vinop (inode)); } +return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 735/849 ceph: refactor wake_up_bit() pattern of calling
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viacheslav Dubeyko <[email protected]>
[ Upstream commit 53db6f25ee47cb1265141d31562604e56146919a ]
The wake_up_bit() is called in ceph_async_unlink_cb(), wake_async_create_waiters(), and ceph_finish_async_create(). It makes sense to switch on clear_bit() function, because it makes the code much cleaner and easier to understand. More important rework is the adding of smp_mb__after_atomic() memory barrier after the bit modification and before wake_up_bit() call. It can prevent potential race condition of accessing the modified bit in other threads. Luckily, clear_and_wake_up_bit() already implements the required functionality pattern:
static inline void clear_and_wake_up_bit(int bit, unsigned long *word)
{
clear_bit_unlock(bit, word);
/* See wake_up_bit() for which memory barrier you need to use. */
smp_mb__after_atomic();
wake_up_bit(word, bit);
}--- fs/ceph/dir.c | 3 +-- fs/ceph/file.c | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-)
fs/ceph/dir.c +1 -2
@@ -1260,8 +1260,7 @@ static void ceph_async_unlink_cb(struct ceph_mds_client *mdsc,spin_unlock (&fsc->async_unlink_conflict_lock);spin_lock (&dentry->d_lock); - di->flags &= ~CEPH_DENTRY_ASYNC_UNLINK ; -wake_up_bit (&di->flags,CEPH_DENTRY_ASYNC_UNLINK_BIT ); +clear_and_wake_up_bit (CEPH_DENTRY_ASYNC_UNLINK_BIT , &di->flags);spin_unlock (&dentry->d_lock);synchronize_rcu ();
fs/ceph/file.c +2 -4
@@ -579,8 +579,7 @@ static void wake_async_create_waiters(struct inode *inode,spin_lock (&ci->i_ceph_lock);if (ci->i_ceph_flags &CEPH_I_ASYNC_CREATE ) { - ci->i_ceph_flags &= ~CEPH_I_ASYNC_CREATE ; -wake_up_bit (&ci->i_ceph_flags,CEPH_ASYNC_CREATE_BIT ); +clear_and_wake_up_bit (CEPH_ASYNC_CREATE_BIT , &ci->i_ceph_flags);if (ci->i_ceph_flags &CEPH_I_ASYNC_CHECK_CAPS ) { ci->i_ceph_flags &= ~CEPH_I_ASYNC_CHECK_CAPS ;
@@ -762,8 +761,7 @@ static int ceph_finish_async_create(struct inode *dir, struct inode *inode, }spin_lock (&dentry->d_lock); - di->flags &= ~CEPH_DENTRY_ASYNC_CREATE ; -wake_up_bit (&di->flags,CEPH_DENTRY_ASYNC_CREATE_BIT ); +clear_and_wake_up_bit (CEPH_DENTRY_ASYNC_CREATE_BIT , &di->flags);spin_unlock (&dentry->d_lock);return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 736/849 ceph: fix multifs mds auth caps issue
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kotresh HR <[email protected]>
[ Upstream commit 22c73d52a6d05c5a2053385c0d6cd9984732799d ]
The mds auth caps check should also validate the fsname along with the associated caps. Not doing so would result in applying the mds auth caps of one fs on to the other fs in a multifs ceph cluster. The bug causes multiple issues w.r.t user authentication, following is one such example.
Steps to Reproduce (on vstart cluster):
1. Create two file systems in a cluster, say 'fsname1' and 'fsname2'
2. Authorize read only permission to the user 'client.usr' on fs 'fsname1' $ceph fs authorize fsname1 client.usr / r
3. Authorize read and write permission to the same user 'client.usr' on fs 'fsname2' $ceph fs authorize fsname2 client.usr / rw
4. Update the keyring
$ceph auth get client.usr >> ./keyring
With above permssions for the user 'client.usr', following is the expectation.
a. The 'client.usr' should be able to only read the contents
and not allowed to create or delete files on file system 'fsname1'.
b. The 'client.usr' should be able to read/write on file system 'fsname2'.
But, with this bug, the 'client.usr' is allowed to read/write on file system 'fsname1'. See below.
5. Mount the file system 'fsname1' with the user 'client.usr' $sudo bin/mount.ceph [email protected]=/ /kmnt_fsname1_usr/
6. Try creating a file on file system 'fsname1' with user 'client.usr'. This should fail but passes with this bug.
$touch /kmnt_fsname1_usr/file1
7. Mount the file system 'fsname1' with the user 'client.admin' and create a file.
$sudo bin/mount.ceph [email protected]=/ /kmnt_fsname1_admin $echo "data" > /kmnt_fsname1_admin/admin_file1
8. Try removing an existing file on file system 'fsname1' with the user 'client.usr'. This shoudn't succeed but succeeds with the bug. $rm -f /kmnt_fsname1_usr/admin_file1
For more information, please take a look at the corresponding mds/fuse patch and tests added by looking into the tracker mentioned below.
v2: Fix a possible null dereference in doutc
v3: Don't store fsname from mdsmap, validate against
ceph_mount_options's fsname and use it
v4: Code refactor, better warning message and
fix possible compiler warning
[ Slava.Dubeyko: "fsname check failed" -> "fsname mismatch" ]
--- fs/ceph/mds_client.c | 8 ++++++++ fs/ceph/mdsmap.c | 14 +++++++++++++- fs/ceph/super.c | 14 -------------- fs/ceph/super.h | 14 ++++++++++++++ 4 files changed, 35 insertions(+), 15 deletions(-)
fs/ceph/mds_client.c +8 -0
@@ -5649,11 +5649,19 @@ static int ceph_mds_auth_match(struct ceph_mds_client *mdsc,u32 caller_uid =from_kuid (&init_user_ns, cred->fsuid);u32 caller_gid =from_kgid (&init_user_ns, cred->fsgid);struct ceph_client *cl = mdsc->fsc->client; +const char *fs_name = mdsc->fsc->mount_options->mds_namespace;const char *spath = mdsc->fsc->mount_options->server_path;bool gid_matched = false;u32 gid, tlen, len;int i, j; +doutc (cl,"fsname check fs_name=%s match.fs_name=%s\n" , + fs_name, auth->match.fs_name ? auth->match.fs_name :"" ); +if (auth->match.fs_name &&strcmp (auth->match.fs_name, fs_name)) { +/* fsname mismatch, try next one */ +return 0 ; + } +doutc (cl,"match.uid %lld\n" , auth->match.uid);if (auth->match.uid !=MDS_AUTH_UID_ANY ) {if (auth->match.uid != caller_uid)
fs/ceph/mdsmap.c +13 -1
@@ -353,10 +353,22 @@ struct ceph_mdsmap *ceph_mdsmap_decode(struct ceph_mds_client *mdsc, void **p,__decode_and_drop_type (p, end, u8, bad_ext); }if (mdsmap_ev >=8 ) { +u32 fsname_len;/* enabled */ ceph_decode_8_safe (p, end, m->m_enabled, bad_ext);/* fs_name */ -ceph_decode_skip_string (p, end, bad_ext); +ceph_decode_32_safe (p, end, fsname_len, bad_ext); + +/* validate fsname against mds_namespace */ +if (!namespace_equals (mdsc->fsc->mount_options, *p, + fsname_len)) { +pr_warn_client (cl,"fsname %*pE doesn't match mds_namespace %s\n" , + (int )fsname_len, (char *)*p, + mdsc->fsc->mount_options->mds_namespace); + goto bad; + } +/* skip fsname after validation */ +ceph_decode_skip_n (p, end, fsname_len, bad); }/* damaged */ if (mdsmap_ev >=9 ) {
fs/ceph/super.c +0 -14
@@ -246,20 +246,6 @@ static void canonicalize_path(char *path) path[j] ='\0' ; } -/* -* Check if the mds namespace in ceph_mount_options matches -* the passed in namespace string. First time match (when -* ->mds_namespace is NULL) is treated specially, since -* ->mds_namespace needs to be initialized by the caller. -*/ -static int namespace_equals (struct ceph_mount_options *fsopt, -const char *namespace,size_t len) -{ -return !(fsopt->mds_namespace && - (strlen (fsopt->mds_namespace) != len || -strncmp (fsopt->mds_namespace, namespace, len))); -} -static int ceph_parse_old_source (const char *dev_name,const char *dev_name_end,struct fs_context *fc) {
fs/ceph/super.h +14 -0
@@ -104,6 +104,20 @@ struct ceph_mount_options {struct fscrypt_dummy_policy dummy_enc_policy; }; +/* +* Check if the mds namespace in ceph_mount_options matches +* the passed in namespace string. First time match (when +* ->mds_namespace is NULL) is treated specially, since +* ->mds_namespace needs to be initialized by the caller. +*/ +static inline int namespace_equals (struct ceph_mount_options *fsopt, +const char *namespace,size_t len) +{ +return !(fsopt->mds_namespace && + (strlen (fsopt->mds_namespace) != len || +strncmp (fsopt->mds_namespace, namespace, len))); +} +/* mount state */ enum {CEPH_MOUNT_MOUNTING ,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 737/849 x86: uaccess: dont use runtime-const rewriting in modules
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds <[email protected]>
[ Upstream commit 284922f4c563aa3a8558a00f2a05722133237fe8 ]
The runtime-const infrastructure was never designed to handle the modular case, because the constant fixup is only done at boot time for core kernel code.
But by the time I used it for the x86-64 user space limit handling in commit 86e6b1547b3d ("x86: fix user address masking non-canonical speculation issue"), I had completely repressed that fact.
And it all happens to work because the only code that currently actually gets inlined by modules is for the access_ok() limit check, where the default constant value works even when not fixed up. Because at least I had intentionally made it be something that is in the non-canonical address space region.
But it's technically very wrong, and it does mean that at least in theory, the use of 'access_ok()' + '__get_user()' can trigger the same speculation issue with non-canonical addresses that the original commit was all about.
The pattern is unusual enough that this probably doesn't matter in practice, but very wrong is still very wrong. Also, let's fix it before the nice optimized scoped user accessor helpers that Thomas Gleixner is working on cause this pseudo-constant to then be more widely used.
This all came up due to an unrelated discussion with Mateusz Guzik about using the runtime const infrastructure for names_cachep accesses too. There the modular case was much more obviously broken, and Mateusz noted it in his 'v2' of the patch series.
That then made me notice how broken 'access_ok()' had been in modules all along. Mea culpa, mea maxima culpa.
Fix it by simply not using the runtime-const code in modules, and just using the USER_PTR_MAX variable value instead. This is not performance-critical like the core user accessor functions (get_user() and friends) are.
Also make sure this doesn't get forgotten the next time somebody wants to do runtime constant optimizations by having the x86 runtime-const.h header file error out if included by modules.
--- arch/x86/include/asm/runtime-const.h | 4 ++++ arch/x86/include/asm/uaccess_64.h | 10 +++++----- arch/x86/kernel/cpu/common.c | 6 +++++- 3 files changed, 14 insertions(+), 6 deletions(-)
arch/x86/include/asm/runtime-const.h +4 -0
@@ -2,6 +2,10 @@#ifndef _ASM_RUNTIME_CONST_H#define _ASM_RUNTIME_CONST_H +#ifdef MODULE +#error "Cannot use runtime-const infrastructure from modules" +#endif +#ifdef __ASSEMBLY__ .macro RUNTIME_CONST_PTR sym reg
arch/x86/include/asm/uaccess_64.h +5 -5
@@ -12,12 +12,12 @@#include <asm/cpufeatures.h> #include <asm/page.h> #include <asm/percpu.h> -#include <asm/runtime-const.h> -/* -* Virtual variable: there's no actual backing store for this, -* it can purely be used as 'runtime_const_ptr(USER_PTR_MAX)' -*/ +#ifdef MODULE +#define runtime_const_ptr (sym) (sym) +#else +#include <asm/runtime-const.h> +#endif extern unsigned long USER_PTR_MAX ;#ifdef CONFIG_ADDRESS_MASKING
arch/x86/kernel/cpu/common.c +5 -1
@@ -78,6 +78,10 @@ DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);EXPORT_PER_CPU_SYMBOL (cpu_info); +/* Used for modules: built-in code uses runtime constants */ +unsigned long USER_PTR_MAX ; +EXPORT_SYMBOL (USER_PTR_MAX ); +u32 elf_hwcap2__read_mostly ;/* Number of siblings per CPU package */
@@ -2578,7 +2582,7 @@ void __init arch_cpu_finalize_init(void)alternative_instructions ();if (IS_ENABLED (CONFIG_X86_64 )) { -unsigned long USER_PTR_MAX =TASK_SIZE_MAX ; +USER_PTR_MAX =TASK_SIZE_MAX ;/* * Enable this when LAM is gated on LASS support
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 738/849 rust: condvar: fix broken intra-doc link
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit 09b1704f5b02c18dd02b21343530463fcfc92c54 upstream.
The future move of pin-init to syn uncovers the following broken intra-doc link:
error: unresolved link to crate::pin_init
--> rust/kernel/sync/condvar.rs:39:40
|
39 | /// instances is with the [pin_init](crate::pin_init!) and [new_condvar] macros.
| ^^^^^^^^^^^^^^^^ no item named pin_init in module kernel
|
= note: -D rustdoc::broken-intra-doc-links implied by -D warnings
= help: to override -D warnings add #[allow(rustdoc::broken_intra_doc_links)]
Currently, when rendered, the link points to a literal crate::pin_init! URL.
Thus fix it.
--- rust/kernel/sync/condvar.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
rust/kernel/sync/condvar.rs +1 -1
@@ -36,7 +36,7 @@ macro_rules! new_condvar {/// spuriously. /// /// Instances of [`CondVar`] need a lock class and to be pinned. The recommended way to create such -/// instances is with the [`pin_init`](crate::pin_init!) and [`new_condvar`] macros. +/// instances is with the [`pin_init`](pin_init::pin_init!) and [`new_condvar`] macros. /// /// # Examples ///
Signature · 1 line
2.51.2
Greg Kroah-Hartman
maintainerPATCH 739/849 rust: devres: fix private intra-doc link
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit ff4d2ef3874773c9c6173b0f099372bf62252aaf upstream.
The future move of pin-init to syn uncovers the following private intra-doc link:
error: public documentation for Devres links to private item Self::inner
--> rust/kernel/devres.rs:106:7
|
106 | /// [Self::inner] is guaranteed to be initialized and is always accessed read-only.
| ^^^^^^^^^^^ this item is private
|
= note: this link will resolve properly if you pass --document-private-items = note: -D rustdoc::private-intra-doc-links implied by -D warnings
= help: to override -D warnings add #[allow(rustdoc::private_intra_doc_links)]
Currently, when rendered, the link points to "nowhere" (an inexistent anchor for a "method").
Thus fix it.
--- rust/kernel/devres.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
rust/kernel/devres.rs +1 -1
@@ -103,7 +103,7 @@ struct Inner<T: Send> {/// /// # Invariants /// -/// [`Self::inner`] is guaranteed to be initialized and is always accessed read-only. +/// `Self::inner` is guaranteed to be initialized and is always accessed read-only. #[pin_data( PinnedDrop )] pub struct Devres <T :Send > { dev:ARef <Device >,
Signature · 1 line
2.51.2
Greg Kroah-Hartman
maintainerPATCH 740/849 rust: kbuild: workaround `rustdoc` doctests modifier bug
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit fad472efab0a805dd939f017c5b8669a786a4bcf upstream.
The rustdoc modifiers bug [1] was fixed in Rust 1.90.0 [2], for which we added a workaround in commit abbf9a449441 ("rust: workaround rustdoc target modifiers bug").
However, rustdoc's doctest generation still has a similar issue [3], being fixed at [4], which does not affect us because we apply the workaround to both, and now, starting with Rust 1.91.0 (released 2025-10-30), -Zsanitizer is a target modifier too [5], which means we fail with:
RUSTDOC TK rust/kernel/lib.rs
error: mixing -Zsanitizer will cause an ABI mismatch in crate kernel
--> rust/kernel/lib.rs:3:1
|
3 | //! The kernel crate.
| ^
|
= help: the -Zsanitizer flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely = note: unset -Zsanitizer in this crate is incompatible with -Zsanitizer=kernel-address in dependency core
= help: set -Zsanitizer=kernel-address in this crate or unset -Zsanitizer in core
= help: if you are sure this will not cause problems, you may use -Cunsafe-allow-abi-mismatch=sanitizer to silence this error
A simple way around is to add the sanitizer to the list in the existing workaround (especially if we had not started to pass the sanitizer flags in the previous commit, since in that case that would not be necessary). However, that still applies the workaround in more cases than necessary.
Instead, only modify the doctests flags to ignore the check for sanitizers, so that it is more local (and thus the compiler keeps checking it for us in the normal rustdoc calls). Since the previous commit already treated the rustdoc calls as kernel objects, this should allow us in the future to easily remove this workaround when the time comes.
By the way, the -Cunsafe-allow-abi-mismatch flag overwrites previous ones rather than appending, so it needs to be all done in the same flag. Moreover, unknown modifiers are rejected, and thus we have to gate based on the version too.
Finally, -Zsanitizer-cfi-normalize-integers is not affected (in Rust 1.91.0), so it is not needed in the workaround for the moment.
--- rust/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
rust/Makefile +4 -1
@@ -69,6 +69,9 @@ core-edition := $(if $(call rustc-min-ve # the time being (https://github.com/rust-lang/rust/issues/144521). rustdoc_modifiers_workaround := $(if $(call rustc-min-version,108800),-Cunsafe-allow-abi-mismatch=fixed-x18) +# Similarly, for doctests (https://github.com/rust-lang/rust/issues/146465). +doctests_modifiers_workaround := $(rustdoc_modifiers_workaround)$(if $(call rustc-min-version,109100),$(comma)sanitizer) + # `rustc` recognizes `--remap-path-prefix` since 1.26.0, but `rustdoc` only # since Rust 1.81.0. Moreover, `rustdoc` ICEs on out-of-tree builds since Rust # 1.82.0 (https://github.com/rust-lang/rust/issues/138520). Thus workaround both
@@ -224,7 +227,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC --extern bindings --extern uapi \ --no-run --crate-name kernel -Zunstable-options \ --sysroot=/dev/null \ - $(rustdoc_modifiers_workaround) \ + $(doctests_modifiers_workaround) \ --test-builder $(objtree)/scripts/rustdoc_test_builder \ $< $(rustdoc_test_kernel_quiet); \ $(objtree)/scripts/rustdoc_test_gen
Greg Kroah-Hartman
maintainerPATCH 741/849 rust: kbuild: treat `build_error` and `rustdoc` as kernel objects
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
commit 16c43a56b79e2c3220b043236369a129d508c65a upstream.
Even if normally build_error isn't a kernel object, it should still be treated as such so that we pass the same flags. Similarly, rustdoc targets are never kernel objects, but we need to treat them as such.
Otherwise, starting with Rust 1.91.0 (released 2025-10-30), rustc will complain about missing sanitizer flags since -Zsanitizer is a target modifier too [1]:
error: mixing -Zsanitizer will cause an ABI mismatch in crate build_error
--> rust/build_error.rs:3:1
|
3 | //! Build-time error.
| ^
|
= help: the -Zsanitizer flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely = note: unset -Zsanitizer in this crate is incompatible with -Zsanitizer=kernel-address in dependency core
= help: set -Zsanitizer=kernel-address in this crate or unset -Zsanitizer in core
= help: if you are sure this will not cause problems, you may use -Cunsafe-allow-abi-mismatch=sanitizer to silence this error
Thus explicitly mark them as kernel objects.
--- rust/Makefile | 10 ++++++++++ 1 file changed, 10 insertions(+)
rust/Makefile +10 -0
@@ -124,9 +124,14 @@ rustdoc-core: private rustc_target_flags rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs rustdoc-clean FORCE +$(call if_changed,rustdoc) +# Even if `rustdoc` targets are not kernel objects, they should still be +# treated as such so that we pass the same flags. Otherwise, for instance, +# `rustdoc` will complain about missing sanitizer flags causing an ABI mismatch. +rustdoc-compiler_builtins: private is-kernel-object := y rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE +$(call if_changed,rustdoc) +rustdoc-ffi: private is-kernel-object := y rustdoc-ffi: $(src)/ffi.rs rustdoc-core FORCE +$(call if_changed,rustdoc)
@@ -144,6 +149,7 @@ rustdoc-pin_init: $(src)/pin-init/src/li rustdoc-macros FORCE +$(call if_changed,rustdoc) +rustdoc-kernel: private is-kernel-object := y rustdoc-kernel: private rustc_target_flags = --extern ffi --extern pin_init \ --extern build_error --extern macros \ --extern bindings --extern uapi
@@ -526,6 +532,10 @@ $(obj)/pin_init.o: $(src)/pin-init/src/l $(obj)/$(libpin_init_internal_name) $(obj)/$(libmacros_name) FORCE +$(call if_changed_rule,rustc_library) +# Even if normally `build_error` is not a kernel object, it should still be +# treated as such so that we pass the same flags. Otherwise, for instance, +# `rustc` will complain about missing sanitizer flags causing an ABI mismatch. +$(obj)/build_error.o: private is-kernel-object := y $(obj)/build_error.o: private skip_gendwarfksyms = 1 $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE +$(call if_changed_rule,rustc_library)
Greg Kroah-Hartman
maintainerPATCH 742/849 btrfs: ensure no dirty metadata is written back for an fs with errors
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
commit 2618849f31e7cf51fadd4a5242458501a6d5b315 upstream.
[BUG]
During development of a minor feature (make sure all btrfs_bio::end_io() is called in task context), I noticed a crash in generic/388, where metadata writes triggered new works after btrfs_stop_all_workers().
It turns out that it can even happen without any code modification, just using RAID5 for metadata and the same workload from generic/388 is going to trigger the use-after-free.
[CAUSE]
If btrfs hits an error, the fs is marked as error, no new transaction is allowed thus metadata is in a frozen state.
But there are some metadata modifications before that error, and they are still in the btree inode page cache.
Since there will be no real transaction commit, all those dirty folios are just kept as is in the page cache, and they can not be invalidated by invalidate_inode_pages2() call inside close_ctree(), because they are dirty.
And finally after btrfs_stop_all_workers(), we call iput() on btree inode, which triggers writeback of those dirty metadata.
And if the fs is using RAID56 metadata, this will trigger RMW and queue new works into rmw_workers, which is already stopped, causing warning from queue_work() and use-after-free.
[FIX]
Add a special handling for write_one_eb(), that if the fs is already in an error state, immediately mark the bbio as failure, instead of really submitting them.
Then during close_ctree(), iput() will just discard all those dirty tree blocks without really writing them back, thus no more new jobs for already stopped-and-freed workqueues.
The extra discard in write_one_eb() also acts as an extra safenet. E.g. the transaction abort is triggered by some extent/free space tree corruptions, and since extent/free space tree is already corrupted some tree blocks may be allocated where they shouldn't be (overwriting existing tree blocks). In that case writing them back will further corrupting the fs.
--- fs/btrfs/extent_io.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/btrfs/extent_io.c +8 -0
@@ -2167,6 +2167,14 @@ static noinline_for_stack void write_onewbc_account_cgroup_owner (wbc, folio, range_len);folio_unlock (folio); } +/* +* If the fs is already in error status, do not submit any writeback +* but immediately finish it. +*/ +if (unlikely (BTRFS_FS_ERROR (fs_info))) { +btrfs_bio_end_io (bbio,errno_to_blk_status (BTRFS_FS_ERROR (fs_info))); +return ; + }btrfs_submit_bbio (bbio,0 ); }
Greg Kroah-Hartman
maintainerPATCH 743/849 media: uvcvideo: Use heuristic to find stream entity
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <[email protected]>
commit 758dbc756aad429da11c569c0d067f7fd032bcf7 upstream.
Some devices, like the Grandstream GUV3100 webcam, have an invalid UVC descriptor where multiple entities share the same ID, this is invalid and makes it impossible to make a proper entity tree without heuristics.
We have recently introduced a change in the way that we handle invalid entities that has caused a regression on broken devices.
Implement a new heuristic to handle these devices properly.
--- drivers/media/usb/uvc/uvc_driver.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
drivers/media/usb/uvc/uvc_driver.c +14 -1
@@ -167,13 +167,26 @@ static struct uvc_entity *uvc_entity_by_static struct uvc_streaming *uvc_stream_by_id (struct uvc_device *dev,int id) { -struct uvc_streaming *stream; +struct uvc_streaming *stream, *last_stream; +unsigned int count =0 ;list_for_each_entry (stream, &dev->streams, list) { + count +=1 ; + last_stream = stream;if (stream->header.bTerminalLink == id)return stream; } +/* +* If the streaming entity is referenced by an invalid ID, notify the +* user and use heuristics to guess the correct entity. +*/ +if (count ==1 && id ==UVC_INVALID_ENTITY_ID ) { +dev_warn (&dev->intf->dev, +"UVC non compliance: Invalid USB header. The streaming entity has an invalid ID, guessing the correct one." ); +return last_stream; + } +return NULL ; }
Greg Kroah-Hartman
maintainerPATCH 744/849 media: videobuf2: forbid remove_bufs when legacy fileio is active
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Szyprowski <[email protected]>
commit 27afd6e066cfd80ddbe22a4a11b99174ac89cced upstream.
vb2_ioctl_remove_bufs() call manipulates queue internal buffer list, potentially overwriting some pointers used by the legacy fileio access mode. Forbid that ioctl when fileio is active to protect internal queue state between subsequent read/write calls.
--- drivers/media/common/videobuf2/videobuf2-v4l2.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/media/common/videobuf2/videobuf2-v4l2.c +5 -0
@@ -1014,6 +1014,11 @@ int vb2_ioctl_remove_bufs(struct file *fif (vb2_queue_is_busy (vdev->queue, file))return -EBUSY ; +if (vb2_fileio_is_active (vdev->queue)) { +dprintk (vdev->queue,1 ,"file io in progress\n" ); +return -EBUSY ; + } +return vb2_core_remove_bufs (vdev->queue, d->index, d->count); }EXPORT_SYMBOL_GPL (vb2_ioctl_remove_bufs);
Greg Kroah-Hartman
maintainerPATCH 745/849 drm/mediatek: Disable AFBC support on Mediatek DRM driver
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ariel D'Alessandro <[email protected]>
commit 9882a40640036d5bbc590426a78981526d4f2345 upstream.
Commit c410fa9b07c3 ("drm/mediatek: Add AFBC support to Mediatek DRM driver") added AFBC support to Mediatek DRM and enabled the 32x8/split/sparse modifier.
However, this is currently broken on Mediatek MT8188 (Genio 700 EVK platform); tested using upstream Kernel and Mesa (v25.2.1), AFBC is used by default since Mesa v25.0.
Kernel trace reports vblank timeouts constantly, and the render is garbled:
``` [CRTC:62:crtc-0] vblank wait timed out WARNING: CPU: 7 PID: 70 at drivers/gpu/drm/drm_atomic_helper.c:1835 drm_atomic_helper_wait_for_vblanks.part.0+0x24c/0x27c [...] Hardware name: MediaTek Genio-700 EVK (DT) Workqueue: events_unbound commit_work pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : drm_atomic_helper_wait_for_vblanks.part.0+0x24c/0x27c lr : drm_atomic_helper_wait_for_vblanks.part.0+0x24c/0x27c sp : ffff80008337bca0 x29: ffff80008337bcd0 x28: 0000000000000061 x27: 0000000000000000 x26: 0000000000000001 x25: 0000000000000000 x24: ffff0000c9dcc000 x23: 0000000000000001 x22: 0000000000000000 x21: ffff0000c66f2f80 x20: ffff0000c0d7d880 x19: 0000000000000000 x18: 000000000000000a x17: 000000040044ffff x16: 005000f2b5503510 x15: 0000000000000000 x14: 0000000000000000 x13: 74756f2064656d69 x12: 742074696177206b x11: 0000000000000058 x10: 0000000000000018 x9 : ffff800082396a70 x8 : 0000000000057fa8 x7 : 0000000000000cce x6 : ffff8000823eea70 x5 : ffff0001fef5f408 x4 : ffff80017ccee000 x3 : ffff0000c12cb480 x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0000c12cb480 Call trace: drm_atomic_helper_wait_for_vblanks.part.0+0x24c/0x27c (P) drm_atomic_helper_commit_tail_rpm+0x64/0x80 commit_tail+0xa4/0x1a4 commit_work+0x14/0x20 process_one_work+0x150/0x290 worker_thread+0x2d0/0x3ec kthread+0x12c/0x210 ret_from_fork+0x10/0x20 ---[ end trace 0000000000000000 ]--- ```
Until this gets fixed upstream, disable AFBC support on this platform, as it's currently broken with upstream Mesa.
--- drivers/gpu/drm/mediatek/mtk_plane.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-)
drivers/gpu/drm/mediatek/mtk_plane.c +1 -23
@@ -21,9 +21,6 @@static const u64 modifiers[] = {DRM_FORMAT_MOD_LINEAR , -DRM_FORMAT_MOD_ARM_AFBC (AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | -AFBC_FORMAT_MOD_SPLIT | -AFBC_FORMAT_MOD_SPARSE ),DRM_FORMAT_MOD_INVALID , };
@@ -71,26 +68,7 @@ static bool mtk_plane_format_mod_support uint32_t format, uint64_t modifier) { -if (modifier ==DRM_FORMAT_MOD_LINEAR ) -return true; - -if (modifier !=DRM_FORMAT_MOD_ARM_AFBC ( - AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | -AFBC_FORMAT_MOD_SPLIT | -AFBC_FORMAT_MOD_SPARSE )) -return false; - -if (format !=DRM_FORMAT_XRGB8888 && - format !=DRM_FORMAT_ARGB8888 && - format !=DRM_FORMAT_BGRX8888 && - format !=DRM_FORMAT_BGRA8888 && - format !=DRM_FORMAT_ABGR8888 && - format !=DRM_FORMAT_XBGR8888 && - format !=DRM_FORMAT_RGB888 && - format !=DRM_FORMAT_BGR888 ) -return false; - -return true; +return modifier ==DRM_FORMAT_MOD_LINEAR ; } static void mtk_plane_destroy_state(struct drm_plane *plane,
Greg Kroah-Hartman
maintainerPATCH 746/849 Revert "wifi: ath10k: avoid unnecessary wait for service ready message"
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baochen Qiang <[email protected]>
commit 2469bb6a6af944755a7d7daf66be90f3b8decbf9 upstream.
This reverts commit 51a73f1b2e56b0324b4a3bb8cebc4221b5be4c7a.
Although this commit benefits QCA6174, it breaks QCA988x and QCA9984 [1][2]. Since it is not likely to root cause/fix this issue in a short time, revert it to get those chips back.
Compile tested only.
--- drivers/net/wireless/ath/ath10k/wmi.c | 39 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 19 deletions(-)
drivers/net/wireless/ath/ath10k/wmi.c +20 -19
@@ -1764,32 +1764,33 @@ void ath10k_wmi_put_wmi_channel(struct aint ath10k_wmi_wait_for_service_ready (struct ath10k *ar) { -unsigned long timeout = jiffies +WMI_SERVICE_READY_TIMEOUT_HZ ;unsigned long time_left, i; -/* Sometimes the PCI HIF doesn't receive interrupt -* for the service ready message even if the buffer -* was completed. PCIe sniffer shows that it's -* because the corresponding CE ring doesn't fires -* it. Workaround here by polling CE rings. Since -* the message could arrive at any time, continue -* polling until timeout. -*/ -do { + time_left =wait_for_completion_timeout (&ar->wmi.service_ready, +WMI_SERVICE_READY_TIMEOUT_HZ ); +if (!time_left) { +/* Sometimes the PCI HIF doesn't receive interrupt +* for the service ready message even if the buffer +* was completed. PCIe sniffer shows that it's +* because the corresponding CE ring doesn't fires +* it. Workaround here by polling CE rings once. +*/ +ath10k_warn (ar,"failed to receive service ready completion, polling..\n" ); +for (i =0 ; i <CE_COUNT ; i++)ath10k_hif_send_complete_check (ar, i,1 ); -/* The 100 ms granularity is a tradeoff considering scheduler -* overhead and response latency -*/ time_left =wait_for_completion_timeout (&ar->wmi.service_ready, -msecs_to_jiffies (100 )); -if (time_left) -return 0 ; - }while (time_before (jiffies, timeout)); +WMI_SERVICE_READY_TIMEOUT_HZ ); +if (!time_left) { +ath10k_warn (ar,"polling timed out\n" ); +return -ETIMEDOUT ; + } + +ath10k_warn (ar,"service ready completion received, continuing normally\n" ); + } -ath10k_warn (ar,"failed to receive service ready completion\n" ); -return -ETIMEDOUT ; +return 0 ; }int ath10k_wmi_wait_for_unified_ready (struct ath10k *ar)
Greg Kroah-Hartman
maintainerPATCH 747/849 tracing: tprobe-events: Fix to register tracepoint correctly
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masami Hiramatsu (Google) <[email protected]>
commit 10d9dda426d684e98b17161f02f77894c6de9b60 upstream.
Since __tracepoint_user_init() calls tracepoint_user_register() without initializing tuser->tpoint with given tracpoint, it does not register tracepoint stub function as callback correctly, and tprobe does not work.
Initializing tuser->tpoint correctly before tracepoint_user_register() so that it sets up tracepoint callback.
I confirmed below example works fine again.
echo "t sched_switch preempt prev_pid=prev->pid next_pid=next->pid" > /sys/kernel/tracing/dynamic_events echo 1 > /sys/kernel/tracing/events/tracepoints/sched_switch/enable
cat /sys/kernel/tracing/trace_pipe
--- kernel/trace/trace_fprobe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/trace/trace_fprobe.c +2 -1
@@ -106,13 +106,14 @@ static struct tracepoint_user *__tracepoint_user_init(const char *name, struct tif (!tuser->name)return NULL ; +/* Register tracepoint if it is loaded. */ if (tpoint) { + tuser->tpoint = tpoint; ret =tracepoint_user_register (tuser);if (ret)return ERR_PTR (ret); } - tuser->tpoint = tpoint; tuser->refcount =1 ;INIT_LIST_HEAD (&tuser->list);list_add (&tuser->list, &tracepoint_user_list);
Signature · 1 line
2.51.2
Greg Kroah-Hartman
maintainerPATCH 748/849 tracing: tprobe-events: Fix to put tracepoint_user when disable the tprobe
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masami Hiramatsu (Google) <[email protected]>
commit c91afa7610235f89a5e8f5686aac23892ab227ed upstream.
__unregister_trace_fprobe() checks tf->tuser to put it when removing tprobe. However, disable_trace_fprobe() does not use it and only calls unregister_fprobe(). Thus it forgets to disable tracepoint_user.
If the trace_fprobe has tuser, put it for unregistering the tracepoint callbacks when disabling tprobe correctly.
--- kernel/trace/trace_fprobe.c | 4 ++++ 1 file changed, 4 insertions(+)
kernel/trace/trace_fprobe.c +4 -0
@@ -1514,6 +1514,10 @@ static int disable_trace_fprobe(struct trace_event_call *call,if (!trace_probe_is_enabled (tp)) {list_for_each_entry (tf,trace_probe_probe_list (tp), tp.list) {unregister_fprobe (&tf->fp); +if (tf->tuser) { +tracepoint_user_put (tf->tuser); + tf->tuser =NULL ; + } } }
Signature · 1 line
2.51.2
Greg Kroah-Hartman
maintainerPATCH 749/849 ring-buffer: Do not warn in ring_buffer_map_get_reader() when reader catches up
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
commit aa997d2d2a0b2e76f4df0f1f12829f02acb4fb6b upstream.
The function ring_buffer_map_get_reader() is a bit more strict than the other get reader functions, and except for certain situations the rb_get_reader_page() should not return NULL. If it does, it triggers a warning.
This warning was triggering but after looking at why, it was because another acceptable situation was happening and it wasn't checked for.
If the reader catches up to the writer and there's still data to be read on the reader page, then the rb_get_reader_page() will return NULL as there's no new page to get.
In this situation, the reader page should not be updated and no warning should trigger.
--- kernel/trace/ring_buffer.c | 4 ++++ 1 file changed, 4 insertions(+)
kernel/trace/ring_buffer.c +4 -0
@@ -7344,6 +7344,10 @@ consume: goto out; } +/* Did the reader catch up with the writer? */ +if (cpu_buffer->reader_page == cpu_buffer->commit_page) + goto out; + reader =rb_get_reader_page (cpu_buffer);if (WARN_ON (!reader)) goto out;
Greg Kroah-Hartman
maintainerPATCH 750/849 net: libwx: fix device bus LAN ID
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiawen Wu <[email protected]>
commit a04ea57aae375bdda1cb57034d8bcbb351e1f973 upstream.
The device bus LAN ID was obtained from PCI_FUNC(), but when a PF port is passthrough to a virtual machine, the function number may not match the actual port index on the device. This could cause the driver to perform operations such as LAN reset on the wrong port.
Fix this by reading the LAN ID from port status register.
--- drivers/net/ethernet/wangxun/libwx/wx_hw.c | 3 ++- drivers/net/ethernet/wangxun/libwx/wx_type.h | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-)
drivers/net/ethernet/wangxun/libwx/wx_hw.c +2 -1
@@ -2368,7 +2368,8 @@ int wx_sw_init(struct wx *wx) wx->oem_svid = pdev->subsystem_vendor; wx->oem_ssid = pdev->subsystem_device; wx->bus.device =PCI_SLOT (pdev->devfn); - wx->bus.func =PCI_FUNC (pdev->devfn); + wx->bus.func =FIELD_GET (WX_CFG_PORT_ST_LANID , +rd32 (wx,WX_CFG_PORT_ST ));if (wx->oem_svid ==PCI_VENDOR_ID_WANGXUN || pdev->is_virtfn) {
drivers/net/ethernet/wangxun/libwx/wx_type.h +2 -2
@@ -96,6 +96,8 @@#define WX_CFG_PORT_CTL_DRV_LOAD BIT(3)#define WX_CFG_PORT_CTL_QINQ BIT(2)#define WX_CFG_PORT_CTL_D_VLAN BIT(0)/* double vlan*/ +#define WX_CFG_PORT_ST 0x14404 +#define WX_CFG_PORT_ST_LANID GENMASK(9, 8)#define WX_CFG_TAG_TPID (_i) (0x14430 + ((_i) * 4))#define WX_CFG_PORT_CTL_NUM_VT_MASK GENMASK(13, 12)/* number of TVs */
@@ -549,8 +551,6 @@ enum WX_MSCA_CMD_value {#define TXD_USE_COUNT (S ) DIV_ROUND_UP((S), WX_MAX_DATA_PER_TXD)#define DESC_NEEDED (MAX_SKB_FRAGS + 4) -#define WX_CFG_PORT_ST 0x14404 -/******************* Receive Descriptor bit definitions **********************/ #define WX_RXD_STAT_DD BIT(0)/* Done */ #define WX_RXD_STAT_EOP BIT(1)/* End of Packet */
Greg Kroah-Hartman
maintainerPATCH 751/849 scsi: ufs: core: Fix a race condition related to the "hid" attribute group
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit c74dc8ab47c1ec3927f63ca83b542c363249b3d8 ]
ufs_sysfs_add_nodes() is called concurrently with ufs_get_device_desc(). This may cause the following code to be called before ufs_sysfs_add_nodes():
sysfs_update_group(&hba->dev->kobj, &ufs_sysfs_hid_group);
If this happens, ufs_sysfs_add_nodes() triggers a kernel warning and fails. Fix this by calling ufs_sysfs_add_nodes() before SCSI LUNs are scanned since the sysfs_update_group() call happens from the context of thread that executes ufshcd_async_scan(). This patch fixes the following kernel warning:
sysfs: cannot create duplicate filename '/devices/platform/3c2d0000.ufs/hid'
Workqueue: async async_run_entry_fn Call trace: dump_backtrace+0xfc/0x17c show_stack+0x18/0x28 dump_stack_lvl+0x40/0x104 dump_stack+0x18/0x3c sysfs_warn_dup+0x6c/0xc8 internal_create_group+0x1c8/0x504 sysfs_create_groups+0x38/0x9c ufs_sysfs_add_nodes+0x20/0x58 ufshcd_init+0x1114/0x134c ufshcd_pltfrm_init+0x728/0x7d8 ufs_google_probe+0x30/0x84 platform_probe+0xa0/0xe0 really_probe+0x114/0x454 __driver_probe_device+0xa4/0x160 driver_probe_device+0x44/0x23c __device_attach_driver+0x15c/0x1f4 bus_for_each_drv+0x10c/0x168 __device_attach_async_helper+0x80/0xf8 async_run_entry_fn+0x4c/0x17c process_one_work+0x26c/0x65c worker_thread+0x33c/0x498 kthread+0x110/0x134 ret_from_fork+0x10/0x20
ufshcd 3c2d0000.ufs: ufs_sysfs_add_nodes: sysfs groups creation failed (err = -17)
--- drivers/ufs/core/ufshcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ufs/core/ufshcd.c +1 -1
@@ -10869,8 +10869,8 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)if (err) goto out_disable; -async_schedule (ufshcd_async_scan, hba);ufs_sysfs_add_nodes (hba->dev); +async_schedule (ufshcd_async_scan, hba);device_enable_async_suspend (dev);ufshcd_pm_qos_init (hba);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 752/849 riscv: stacktrace: Disable KASAN checks for non-current tasks
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chunyan Zhang <[email protected]>
[ Upstream commit 060ea84a484e852b52b938f234bf9b5503a6c910 ]
Unwinding the stack of a task other than current, KASAN would report "BUG: KASAN: out-of-bounds in walk_stackframe+0x41c/0x460"
There is a same issue on x86 and has been resolved by the commit 84936118bdf3 ("x86/unwind: Disable KASAN checks for non-current tasks") The solution could be applied to RISC-V too.
This patch also can solve the issue:
https://seclists.org/oss-sec/2025/q4/23
--- arch/riscv/kernel/stacktrace.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
arch/riscv/kernel/stacktrace.c +19 -2
@@ -16,6 +16,22 @@#ifdef CONFIG_FRAME_POINTER +/* +* This disables KASAN checking when reading a value from another task's stack, +* since the other task could be running on another CPU and could have poisoned +* the stack in the meantime. +*/ +#define READ_ONCE_TASK_STACK (task, x) \ +({ \ + unsigned long val; \ + unsigned long addr = x; \ + if ((task) == current) \ + val = READ_ONCE(addr); \ + else \ + val = READ_ONCE_NOCHECK(addr); \ + val; \ +}) + extern asmlinkage void handle_exception(void);extern unsigned long ret_from_exception_end;
@@ -69,8 +85,9 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, fp = frame->ra; pc = regs->ra; }else { - fp = frame->fp; - pc =ftrace_graph_ret_addr (current, &graph_idx, frame->ra, + fp =READ_ONCE_TASK_STACK (task, frame->fp); + pc =READ_ONCE_TASK_STACK (task, frame->ra); + pc =ftrace_graph_ret_addr (current, &graph_idx, pc, &frame->ra);if (pc >= (unsigned long )handle_exception && pc < (unsigned long )&ret_from_exception_end) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 753/849 riscv: ptdump: use seq_puts() in pt_dump_seq_puts() macro
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josephine Pfeiffer <[email protected]>
[ Upstream commit a74f038fa50e0d33b740f44f862fe856f16de6a8 ]
The pt_dump_seq_puts() macro incorrectly uses seq_printf() instead of seq_puts(). This is both a performance issue and conceptually wrong, as the macro name suggests plain string output (puts) but the implementation uses formatted output (printf).
The macro is used in ptdump.c:301 to output a newline character. Using seq_printf() adds unnecessary overhead for format string parsing when outputting this constant string.
This bug was introduced in commit 59c4da8640cc ("riscv: Add support to dump the kernel page tables") in 2020, which copied the implementation pattern from other architectures that had the same bug.
--- arch/riscv/mm/ptdump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/mm/ptdump.c +1 -1
@@ -21,7 +21,7 @@#define pt_dump_seq_puts (m, fmt) \ ({ \ if (m) \ - seq_printf(m, fmt); \ + seq_puts(m, fmt); \ })/*
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 754/849 Revert "wifi: ath12k: Fix missing station power save configuration"
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaoqing Pan <[email protected]>
[ Upstream commit 9222582ec524707fbb9d076febead5b6a07611ed ]
This reverts commit 4b66d18918f8e4d85e51974a9e3ce9abad5c7c3d.
In [1], Ross Brown reports poor performance of WCN7850 after enabling power save. Temporarily revert the fix; it will be re-enabled once the issue is resolved.
Tested-on: WCN7850 hw2.0 PCI WLAN.IOE_HMT.1.1-00011-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1
--- drivers/net/wireless/ath/ath12k/mac.c | 122 ++++++++++++-------------- 1 file changed, 55 insertions(+), 67 deletions(-)
drivers/net/wireless/ath/ath12k/mac.c +55 -67
@@ -4078,68 +4078,12 @@ static int ath12k_mac_fils_discovery(struct ath12k_link_vif *arvif,return ret; } -static void ath12k_mac_vif_setup_ps (struct ath12k_link_vif *arvif) -{ -struct ath12k *ar = arvif->ar; -struct ieee80211_vif *vif = arvif->ahvif->vif; -struct ieee80211_conf *conf = &ath12k_ar_to_hw (ar)->conf; -enum wmi_sta_powersave_param param; -struct ieee80211_bss_conf *info; -enum wmi_sta_ps_mode psmode; -int ret; -int timeout; -bool enable_ps; - -lockdep_assert_wiphy (ath12k_ar_to_hw (ar)->wiphy); - -if (vif->type !=NL80211_IFTYPE_STATION ) -return ; - - enable_ps = arvif->ahvif->ps; -if (enable_ps) { - psmode =WMI_STA_PS_MODE_ENABLED ; - param =WMI_STA_PS_PARAM_INACTIVITY_TIME ; - - timeout = conf->dynamic_ps_timeout; -if (timeout ==0 ) { - info =ath12k_mac_get_link_bss_conf (arvif); -if (!info) { -ath12k_warn (ar->ab,"unable to access bss link conf in setup ps for vif %pM link %u\n" , - vif->addr, arvif->link_id); -return ; - } - -/* firmware doesn't like 0 */ - timeout =ieee80211_tu_to_usec (info->beacon_int) /1000 ; - } - - ret =ath12k_wmi_set_sta_ps_param (ar, arvif->vdev_id, param, - timeout); -if (ret) { -ath12k_warn (ar->ab,"failed to set inactivity time for vdev %d: %i\n" , - arvif->vdev_id, ret); -return ; - } - }else { - psmode =WMI_STA_PS_MODE_DISABLED ; - } - -ath12k_dbg (ar->ab,ATH12K_DBG_MAC ,"mac vdev %d psmode %s\n" , - arvif->vdev_id, psmode ?"enable" :"disable" ); - - ret =ath12k_wmi_pdev_set_ps_mode (ar, arvif->vdev_id, psmode); -if (ret) -ath12k_warn (ar->ab,"failed to set sta power save mode %d for vdev %d: %d\n" , - psmode, arvif->vdev_id, ret); -} -static void ath12k_mac_op_vif_cfg_changed (struct ieee80211_hw *hw,struct ieee80211_vif *vif,u64 changed) {struct ath12k_vif *ahvif =ath12k_vif_to_ahvif (vif);unsigned long links = ahvif->links_map; -struct ieee80211_vif_cfg *vif_cfg;struct ieee80211_bss_conf *info;struct ath12k_link_vif *arvif;struct ieee80211_sta *sta;
@@ -4203,24 +4147,61 @@ static void ath12k_mac_op_vif_cfg_changed(struct ieee80211_hw *hw, } } } +} -if (changed &BSS_CHANGED_PS ) { - links = ahvif->links_map; - vif_cfg = &vif->cfg; +static void ath12k_mac_vif_setup_ps (struct ath12k_link_vif *arvif) +{ +struct ath12k *ar = arvif->ar; +struct ieee80211_vif *vif = arvif->ahvif->vif; +struct ieee80211_conf *conf = &ath12k_ar_to_hw (ar)->conf; +enum wmi_sta_powersave_param param; +struct ieee80211_bss_conf *info; +enum wmi_sta_ps_mode psmode; +int ret; +int timeout; +bool enable_ps; -for_each_set_bit (link_id, &links,IEEE80211_MLD_MAX_NUM_LINKS ) { - arvif =wiphy_dereference (hw->wiphy, ahvif->link[link_id]); -if (!arvif || !arvif->ar) -continue ; +lockdep_assert_wiphy (ath12k_ar_to_hw (ar)->wiphy); - ar = arvif->ar; +if (vif->type !=NL80211_IFTYPE_STATION ) +return ; + + enable_ps = arvif->ahvif->ps; +if (enable_ps) { + psmode =WMI_STA_PS_MODE_ENABLED ; + param =WMI_STA_PS_PARAM_INACTIVITY_TIME ; -if (ar->ab->hw_params->supports_sta_ps) { - ahvif->ps = vif_cfg->ps; -ath12k_mac_vif_setup_ps (arvif); + timeout = conf->dynamic_ps_timeout; +if (timeout ==0 ) { + info =ath12k_mac_get_link_bss_conf (arvif); +if (!info) { +ath12k_warn (ar->ab,"unable to access bss link conf in setup ps for vif %pM link %u\n" , + vif->addr, arvif->link_id); +return ; } + +/* firmware doesn't like 0 */ + timeout =ieee80211_tu_to_usec (info->beacon_int) /1000 ; } + + ret =ath12k_wmi_set_sta_ps_param (ar, arvif->vdev_id, param, + timeout); +if (ret) { +ath12k_warn (ar->ab,"failed to set inactivity time for vdev %d: %i\n" , + arvif->vdev_id, ret); +return ; + } + }else { + psmode =WMI_STA_PS_MODE_DISABLED ; } + +ath12k_dbg (ar->ab,ATH12K_DBG_MAC ,"mac vdev %d psmode %s\n" , + arvif->vdev_id, psmode ?"enable" :"disable" ); + + ret =ath12k_wmi_pdev_set_ps_mode (ar, arvif->vdev_id, psmode); +if (ret) +ath12k_warn (ar->ab,"failed to set sta power save mode %d for vdev %d: %d\n" , + psmode, arvif->vdev_id, ret); } static bool ath12k_mac_supports_tpc(struct ath12k *ar, struct ath12k_vif *ahvif,
@@ -4242,6 +4223,7 @@ static void ath12k_mac_bss_info_changed(struct ath12k *ar, {struct ath12k_vif *ahvif = arvif->ahvif;struct ieee80211_vif *vif =ath12k_ahvif_to_vif (ahvif); +struct ieee80211_vif_cfg *vif_cfg = &vif->cfg;struct cfg80211_chan_def def;u32 param_id, param_value;enum nl80211_band band;
@@ -4528,6 +4510,12 @@ static void ath12k_mac_bss_info_changed(struct ath12k *ar, }ath12k_mac_fils_discovery (arvif, info); + +if (changed &BSS_CHANGED_PS && + ar->ab->hw_params->supports_sta_ps) { + ahvif->ps = vif_cfg->ps; +ath12k_mac_vif_setup_ps (arvif); + } } static struct ath12k_vif_cache *ath12k_ahvif_get_link_cache(struct ath12k_vif *ahvif,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 755/849 scsi: ufs: core: Revert "Make HID attributes visible"
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit f838d624fd1183e07db86f3138bcd05fd7630a1e ]
Patch "Make HID attributes visible" is needed for older kernel versions (e.g. 6.12) where ufs_get_device_desc() is called from ufshcd_probe_hba(). In these older kernel versions ufshcd_get_device_desc() may be called after the sysfs attributes have been added. In the upstream kernel however ufshcd_get_device_desc() is called before ufs_sysfs_add_nodes(). See also the ufshcd_device_params_init() call from ufshcd_init(). Hence, calling sysfs_update_group() is not necessary.
See also commit 69f5eb78d4b0 ("scsi: ufs: core: Move the ufshcd_device_init(hba, true) call") in kernel v6.13.
This patch fixes the following kernel warning:
sysfs: cannot create duplicate filename '/devices/platform/3c2d0000.ufs/hid'
Workqueue: async async_run_entry_fn Call trace: dump_backtrace+0xfc/0x17c show_stack+0x18/0x28 dump_stack_lvl+0x40/0x104 dump_stack+0x18/0x3c sysfs_warn_dup+0x6c/0xc8 internal_create_group+0x1c8/0x504 sysfs_create_groups+0x38/0x9c ufs_sysfs_add_nodes+0x20/0x58 ufshcd_init+0x1114/0x134c ufshcd_pltfrm_init+0x728/0x7d8 ufs_google_probe+0x30/0x84 platform_probe+0xa0/0xe0 really_probe+0x114/0x454 __driver_probe_device+0xa4/0x160 driver_probe_device+0x44/0x23c __device_attach_driver+0x15c/0x1f4 bus_for_each_drv+0x10c/0x168 __device_attach_async_helper+0x80/0xf8 async_run_entry_fn+0x4c/0x17c process_one_work+0x26c/0x65c worker_thread+0x33c/0x498 kthread+0x110/0x134 ret_from_fork+0x10/0x20
ufshcd 3c2d0000.ufs: ufs_sysfs_add_nodes: sysfs groups creation failed (err = -17)
--- drivers/ufs/core/ufs-sysfs.c | 2 +- drivers/ufs/core/ufs-sysfs.h | 1 - drivers/ufs/core/ufshcd.c | 2 -- 3 files changed, 1 insertion(+), 4 deletions(-)
drivers/ufs/core/ufs-sysfs.c +1 -1
@@ -1949,7 +1949,7 @@ static umode_t ufs_sysfs_hid_is_visible(struct kobject *kobj,return hba->dev_info.hid_sup ? attr->mode :0 ; } -const struct attribute_group ufs_sysfs_hid_group = { +static const struct attribute_group ufs_sysfs_hid_group = { .name ="hid" , .attrs = ufs_sysfs_hid, .is_visible = ufs_sysfs_hid_is_visible,
drivers/ufs/core/ufs-sysfs.h +0 -1
@@ -14,6 +14,5 @@ void ufs_sysfs_remove_nodes(struct device *dev);extern const struct attribute_group ufs_sysfs_unit_descriptor_group;extern const struct attribute_group ufs_sysfs_lun_attributes_group; -extern const struct attribute_group ufs_sysfs_hid_group;#endif
drivers/ufs/core/ufshcd.c +0 -2
@@ -8481,8 +8481,6 @@ static int ufs_get_device_desc(struct ufs_hba *hba) DEVICE_DESC_PARAM_EXT_UFS_FEATURE_SUP) &UFS_DEV_HID_SUPPORT ; -sysfs_update_group (&hba->dev->kobj, &ufs_sysfs_hid_group); - model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME ]; err = ufshcd_read_string_desc(hba, model_index,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 756/849 Bluetooth: hci_event: validate skb length for unknown CC opcode
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raphael Pinsonneault-Thibeault <[email protected]>
[ Upstream commit 5c5f1f64681cc889d9b13e4a61285e9e029d6ab5 ]
In hci_cmd_complete_evt(), if the command complete event has an unknown opcode, we assume the first byte of the remaining skb->data contains the return status. However, parameter data has previously been pulled in hci_event_func(), which may leave the skb empty. If so, using skb->data[0] for the return status uses un-init memory.
The fix is to check skb->len before using skb->data.
--- net/bluetooth/hci_event.c | 7 +++++++ 1 file changed, 7 insertions(+)
net/bluetooth/hci_event.c +7 -0
@@ -4218,6 +4218,13 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data, }if (i ==ARRAY_SIZE (hci_cc_table)) { +if (!skb->len) { +bt_dev_err (hdev,"Unexpected cc 0x%4.4x with no status" , + *opcode); + *status =HCI_ERROR_UNSPECIFIED ; +return ; + } +/* Unknown opcode, assume byte 0 contains the status, so * that e.g. __hci_cmd_sync() properly returns errors * for vendor specific commands send by HCI drivers.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 757/849 Bluetooth: btrtl: Fix memory leak in rtlbt_parse_firmware_v2()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abdun Nihaal <[email protected]>
[ Upstream commit 1c21cf89a66413eb04b2d22c955b7a50edc14dfa ]
The memory allocated for ptr using kvmalloc() is not freed on the last error path. Fix that by freeing it on that error path.
--- drivers/bluetooth/btrtl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/bluetooth/btrtl.c +3 -1
@@ -625,8 +625,10 @@ static int rtlbt_parse_firmware_v2(struct hci_dev *hdev, len += entry->len; } -if (!len) +if (!len) { +kvfree (ptr);return -EPERM ; + } *_buf = ptr;return len;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 758/849 gve: Implement gettimex64 with -EOPNOTSUPP
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Hostetler <[email protected]>
[ Upstream commit 6ab753b5d8e521616cd9bd10b09891cbeb7e0235 ]
gve implemented a ptp_clock for sole use of do_aux_work at this time. ptp_clock_gettime() and ptp_sys_offset() assume every ptp_clock has implemented either gettimex64 or gettime64. Stub gettimex64 and return -EOPNOTSUPP to prevent NULL dereferencing.
--- drivers/net/ethernet/google/gve/gve_ptp.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/net/ethernet/google/gve/gve_ptp.c +8 -0
@@ -26,6 +26,13 @@ int gve_clock_nic_ts_read(struct gve_priv *priv)return 0 ; } +static int gve_ptp_gettimex64 (struct ptp_clock_info *info, +struct timespec64 *ts, +struct ptp_system_timestamp *sts) +{ +return -EOPNOTSUPP ; +} +static long gve_ptp_do_aux_work (struct ptp_clock_info *info) { const struct gve_ptp *ptp = container_of(info, struct gve_ptp, info);
@@ -47,6 +54,7 @@ static long gve_ptp_do_aux_work(struct ptp_clock_info *info)static const struct ptp_clock_info gve_ptp_caps = { .owner =THIS_MODULE , .name ="gve clock" , + .gettimex64 = gve_ptp_gettimex64, .do_aux_work = gve_ptp_do_aux_work, };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 759/849 gve: Implement settime64 with -EOPNOTSUPP
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Hostetler <[email protected]>
[ Upstream commit 329d050bbe63c2999f657cf2d3855be11a473745 ]
ptp_clock_settime() assumes every ptp_clock has implemented settime64(). Stub it with -EOPNOTSUPP to prevent a NULL dereference.
--- drivers/net/ethernet/google/gve/gve_ptp.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/ethernet/google/gve/gve_ptp.c +7 -0
@@ -33,6 +33,12 @@ static int gve_ptp_gettimex64(struct ptp_clock_info *info,return -EOPNOTSUPP ; } +static int gve_ptp_settime64 (struct ptp_clock_info *info, +const struct timespec64 *ts) +{ +return -EOPNOTSUPP ; +} +static long gve_ptp_do_aux_work (struct ptp_clock_info *info) { const struct gve_ptp *ptp = container_of(info, struct gve_ptp, info);
@@ -55,6 +61,7 @@ static const struct ptp_clock_info gve_ptp_caps = { .owner = THIS_MODULE, .name = "gve clock", .gettimex64 = gve_ptp_gettimex64, + .settime64 = gve_ptp_settime64, .do_aux_work = gve_ptp_do_aux_work, };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 760/849 net: dsa: tag_brcm: legacy: fix untagged rx on unbridged ports for bcm63xx
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 3d18a84eddde169d6dbf3c72cc5358b988c347d0 ]
The internal switch on BCM63XX SoCs will unconditionally add 802.1Q VLAN tags on egress to CPU when 802.1Q mode is enabled. We do this unconditionally since commit ed409f3bbaa5 ("net: dsa: b53: Configure VLANs while not filtering").
This is fine for VLAN aware bridges, but for standalone ports and vlan unaware bridges this means all packets are tagged with the default VID, which is 0.
While the kernel will treat that like untagged, this can break userspace applications processing raw packets, expecting untagged traffic, like STP daemons.
This also breaks several bridge tests, where the tcpdump output then does not match the expected output anymore.
Since 0 isn't a valid VID, just strip out the VLAN tag if we encounter it, unless the priority field is set, since that would be a valid tag again.
--- net/dsa/tag_brcm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
net/dsa/tag_brcm.c +8 -2
@@ -224,12 +224,14 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb, {int len =BRCM_LEG_TAG_LEN ;int source_port; +__be16 *proto;u8 *brcm_tag;if (unlikely (!pskb_may_pull (skb,BRCM_LEG_TAG_LEN +VLAN_HLEN )))return NULL ; brcm_tag =dsa_etype_header_pos_rx (skb); + proto = (__be16 *)(brcm_tag +BRCM_LEG_TAG_LEN ); source_port = brcm_tag[5 ] &BRCM_LEG_PORT_ID ;
@@ -237,8 +239,12 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,if (!skb->dev)return NULL ; -/* VLAN tag is added by BCM63xx internal switch */ -if (netdev_uses_dsa (skb->dev)) +/* The internal switch in BCM63XX SoCs always tags on egress on the CPU +* port. We use VID 0 internally for untagged traffic, so strip the tag +* if the TCI field is all 0, and keep it otherwise to also retain +* e.g. 802.1p tagged packets. +*/ +if (proto[0 ] ==htons (ETH_P_8021Q ) && proto[1 ] ==0 ) len +=VLAN_HLEN ;/* Remove Broadcom tag and update checksum */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 761/849 selftests/net: fix out-of-order delivery of FIN in gro:tcp test
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anubhav Singh <[email protected]>
[ Upstream commit 02d064de05b1fcca769391fa82d205bed8bb9bf0 ]
Due to the gro_sender sending data packets and FIN packets in very quick succession, these are received almost simultaneously by the gro_receiver. FIN packets are sometimes processed before the data packets leading to intermittent (~1/100) test failures.
This change adds a delay of 100ms before sending FIN packets in gro:tcp test to avoid the out-of-order delivery. The same mitigation already exists for the gro:ip test.
--- tools/testing/selftests/net/gro.c | 8 ++++++++ 1 file changed, 8 insertions(+)
tools/testing/selftests/net/gro.c +8 -0
@@ -969,6 +969,7 @@ static void check_recv_pkts(int fd, int *correct_payload,static void gro_sender (void ) { +const int fin_delay_us =100 *1000 ;static char fin_pkt[MAX_HDR_LEN ];struct sockaddr_ll daddr = {};int txfd =-1 ;
@@ -1012,15 +1013,22 @@ static void gro_sender(void)write_packet (txfd, fin_pkt, total_hdr_len, &daddr); }else if (strcmp (testname,"tcp" ) ==0 ) {send_changed_checksum (txfd, &daddr); +/* Adding sleep before sending FIN so that it is not +* received prior to other packets. +*/ +usleep (fin_delay_us);write_packet (txfd, fin_pkt, total_hdr_len, &daddr);send_changed_seq (txfd, &daddr); +usleep (fin_delay_us);write_packet (txfd, fin_pkt, total_hdr_len, &daddr);send_changed_ts (txfd, &daddr); +usleep (fin_delay_us);write_packet (txfd, fin_pkt, total_hdr_len, &daddr);send_diff_opt (txfd, &daddr); +usleep (fin_delay_us);write_packet (txfd, fin_pkt, total_hdr_len, &daddr); }else if (strcmp (testname,"ip" ) ==0 ) {send_changed_ECN (txfd, &daddr);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 762/849 selftests/net: use destination options instead of hop-by-hop
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anubhav Singh <[email protected]>
[ Upstream commit f8e8486702abb05b8c734093aab1606af0eac068 ]
The GRO self-test, gro.c, currently constructs IPv6 packets containing a Hop-by-Hop Options header (IPPROTO_HOPOPTS) to ensure the GRO path correctly handles IPv6 extension headers.
However, network elements may be configured to drop packets with the Hop-by-Hop Options header (HBH). This causes the self-test to fail in environments where such network elements are present.
To improve the robustness and reliability of this test in diverse network environments, switch from using IPPROTO_HOPOPTS to IPPROTO_DSTOPTS (Destination Options).
The Destination Options header is less likely to be dropped by intermediate routers and still serves the core purpose of the test:
validating GRO's handling of an IPv6 extension header. This change ensures the test can execute successfully without being incorrectly failed by network policies outside the kernel's control.
--- tools/testing/selftests/net/gro.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/testing/selftests/net/gro.c +2 -2
@@ -734,11 +734,11 @@ static void send_ipv6_exthdr(int fd, struct sockaddr_ll *daddr, char *ext_data1,static char exthdr_pck[sizeof (buf) +MIN_EXTHDR_SIZE ];create_packet (buf,0 ,0 ,PAYLOAD_LEN ,0 ); -add_ipv6_exthdr (buf, exthdr_pck,IPPROTO_HOPOPTS , ext_data1); +add_ipv6_exthdr (buf, exthdr_pck,IPPROTO_DSTOPTS , ext_data1);write_packet (fd, exthdr_pck, total_hdr_len +PAYLOAD_LEN +MIN_EXTHDR_SIZE , daddr);create_packet (buf,PAYLOAD_LEN *1 ,0 ,PAYLOAD_LEN ,0 ); -add_ipv6_exthdr (buf, exthdr_pck,IPPROTO_HOPOPTS , ext_data2); +add_ipv6_exthdr (buf, exthdr_pck,IPPROTO_DSTOPTS , ext_data2);write_packet (fd, exthdr_pck, total_hdr_len +PAYLOAD_LEN +MIN_EXTHDR_SIZE , daddr); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 763/849 selftests: netdevsim: Fix ethtool-coalesce.sh fail by installing ethtool-common.sh
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Liang <[email protected]>
[ Upstream commit d01f8136d46b925798abcf86b35a4021e4cfb8bb ]
The script "ethtool-common.sh" is not installed in INSTALL_PATH, and triggers some errors when I try to run the test 'drivers/net/netdevsim/ethtool-coalesce.sh':
TAP version 13
1..1
# timeout set to 600 # selftests: drivers/net/netdevsim: ethtool-coalesce.sh # ./ethtool-coalesce.sh: line 4: ethtool-common.sh: No such file or directory # ./ethtool-coalesce.sh: line 25: make_netdev: command not found # ethtool: bad command line argument(s) # ./ethtool-coalesce.sh: line 124: check: command not found # ./ethtool-coalesce.sh: line 126: [: -eq: unary operator expected # FAILED /0 checks not ok 1 selftests: drivers/net/netdevsim: ethtool-coalesce.sh # exit=1
Install this file to avoid this error. After this patch:
TAP version 13
1..1
# timeout set to 600 # selftests: drivers/net/netdevsim: ethtool-coalesce.sh # PASSED all 22 checks ok 1 selftests: drivers/net/netdevsim: ethtool-coalesce.sh
--- tools/testing/selftests/drivers/net/netdevsim/Makefile | 4 ++++ 1 file changed, 4 insertions(+)
tools/testing/selftests/drivers/net/netdevsim/Makefile +4 -0
@@ -18,4 +18,8 @@ TEST_PROGS = devlink.sh \ tc-mq-visibility.sh \ udp_tunnel_nic.sh \ +TEST_FILES := \ + ethtool-common.sh +# end of TEST_FILES + include ../../../lib.mk
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 764/849 net: vlan: sync VLAN features with lower device
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hangbin Liu <[email protected]>
[ Upstream commit c211f5d7cbd5cb34489d526648bb9c8ecc907dee ]
After registering a VLAN device and setting its feature flags, we need to synchronize the VLAN features with the lower device. For example, the VLAN device does not have the NETIF_F_LRO flag, it should be synchronized with the lower device based on the NETIF_F_UPPER_DISABLES definition.
As the dev->vlan_features has changed, we need to call netdev_update_features(). The caller must run after netdev_upper_dev_link() links the lower devices, so this patch adds the netdev_update_features() call in register_vlan_dev().
--- net/8021q/vlan.c | 2 ++ 1 file changed, 2 insertions(+)
net/8021q/vlan.c +2 -0
@@ -193,6 +193,8 @@ int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack)vlan_group_set_device (grp, vlan->vlan_proto, vlan_id, dev); grp->nr_vlan_devs++; +netdev_update_features (dev); +return 0 ; out_unregister_netdev:
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 765/849 netconsole: Acquire su_mutex before navigating configs hierarchy
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gustavo Luiz Duarte <[email protected]>
[ Upstream commit d7d2fcf7ae31471b4e08b7e448b8fd0ec2e06a1b ]
There is a race between operations that iterate over the userdata cg_children list and concurrent add/remove of userdata items through configfs. The update_userdata() function iterates over the nt->userdata_group.cg_children list, and count_extradata_entries() also iterates over this same list to count nodes.
Quoting from Documentation/filesystems/configfs.rst:
Quoted 6 lines
A subsystem can navigate the
cg_childrenlist and theci_parentpointer to see the tree created by the subsystem. This can race with configfs' management of the hierarchy, so configfs uses the subsystem mutex to protect modifications. Whenever a subsystem wants to navigate the hierarchy, it must do so under the protection of the subsystem mutex.
Without proper locking, if a userdata item is added or removed concurrently while these functions are iterating, the list can be accessed in an inconsistent state. For example, the list_for_each() loop can reach a node that is being removed from the list by list_del_init() which sets the nodes' .next pointer to point to itself, so the loop will never end (or reach the WARN_ON_ONCE in update_userdata() ).
Fix this by holding the configfs subsystem mutex (su_mutex) during all operations that iterate over cg_children.
This includes:
- userdatum_value_store() which calls update_userdata() to iterate over cg_children
- All sysdata_*_enabled_store() functions which call count_extradata_entries() to iterate over cg_children
The su_mutex must be acquired before dynamic_netconsole_mutex to avoid potential lock ordering issues, as configfs operations may already hold su_mutex when calling into our code.
--- drivers/net/netconsole.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/net/netconsole.c +10 -0
@@ -928,6 +928,7 @@ static ssize_t userdatum_value_store(struct config_item *item, const char *buf,if (count >MAX_EXTRADATA_VALUE_LEN )return -EMSGSIZE ; +mutex_lock (&netconsole_subsys.su_mutex);mutex_lock (&dynamic_netconsole_mutex); ret =strscpy (udm->value, buf,sizeof (udm->value));
@@ -941,6 +942,7 @@ static ssize_t userdatum_value_store(struct config_item *item, const char *buf, ret = count; out_unlock:mutex_unlock (&dynamic_netconsole_mutex); +mutex_unlock (&netconsole_subsys.su_mutex);return ret; }
@@ -966,6 +968,7 @@ static ssize_t sysdata_msgid_enabled_store(struct config_item *item,if (ret)return ret; +mutex_lock (&netconsole_subsys.su_mutex);mutex_lock (&dynamic_netconsole_mutex); curr = !!(nt->sysdata_fields &SYSDATA_MSGID );if (msgid_enabled == curr)
@@ -986,6 +989,7 @@ static ssize_t sysdata_msgid_enabled_store(struct config_item *item, ret =strnlen (buf, count); unlock:mutex_unlock (&dynamic_netconsole_mutex); +mutex_unlock (&netconsole_subsys.su_mutex);return ret; }
@@ -1000,6 +1004,7 @@ static ssize_t sysdata_release_enabled_store(struct config_item *item,if (ret)return ret; +mutex_lock (&netconsole_subsys.su_mutex);mutex_lock (&dynamic_netconsole_mutex); curr = !!(nt->sysdata_fields &SYSDATA_RELEASE );if (release_enabled == curr)
@@ -1020,6 +1025,7 @@ static ssize_t sysdata_release_enabled_store(struct config_item *item, ret =strnlen (buf, count); unlock:mutex_unlock (&dynamic_netconsole_mutex); +mutex_unlock (&netconsole_subsys.su_mutex);return ret; }
@@ -1034,6 +1040,7 @@ static ssize_t sysdata_taskname_enabled_store(struct config_item *item,if (ret)return ret; +mutex_lock (&netconsole_subsys.su_mutex);mutex_lock (&dynamic_netconsole_mutex); curr = !!(nt->sysdata_fields &SYSDATA_TASKNAME );if (taskname_enabled == curr)
@@ -1054,6 +1061,7 @@ static ssize_t sysdata_taskname_enabled_store(struct config_item *item, ret =strnlen (buf, count); unlock:mutex_unlock (&dynamic_netconsole_mutex); +mutex_unlock (&netconsole_subsys.su_mutex);return ret; }
@@ -1069,6 +1077,7 @@ static ssize_t sysdata_cpu_nr_enabled_store(struct config_item *item,if (ret)return ret; +mutex_lock (&netconsole_subsys.su_mutex);mutex_lock (&dynamic_netconsole_mutex); curr = !!(nt->sysdata_fields &SYSDATA_CPU_NR );if (cpu_nr_enabled == curr)
@@ -1097,6 +1106,7 @@ static ssize_t sysdata_cpu_nr_enabled_store(struct config_item *item, ret =strnlen (buf, count); unlock:mutex_unlock (&dynamic_netconsole_mutex); +mutex_unlock (&netconsole_subsys.su_mutex);return ret; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 766/849 gpio: swnode: dont use the swnodes name as the key for GPIO lookup
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
[ Upstream commit e5d527be7e6984882306b49c067f1fec18920735 ]
Looking up a GPIO controller by label that is the name of the software node is wonky at best - the GPIO controller driver is free to set a different label than the name of its firmware node. We're already being passed a firmware node handle attached to the GPIO device to swnode_get_gpio_device() so use it instead for a more precise lookup.
--- drivers/gpio/gpiolib-swnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpio/gpiolib-swnode.c +1 -1
@@ -41,7 +41,7 @@ static struct gpio_device *swnode_get_gpio_device(struct fwnode_handle *fwnode) !strcmp(gdev_node->name, GPIOLIB_SWNODE_UNDEFINED_NAME))return ERR_PTR (-ENOENT ); - gdev =gpio_device_find_by_label (gdev_node->name); + gdev =gpio_device_find_by_fwnode (fwnode);return gdev ?:ERR_PTR (-EPROBE_DEFER ); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 767/849 gpiolib: fix invalid pointer access in debugfs
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
[ Upstream commit 2f6115ad8864cf3f48598f26c74c7c8e5c391919 ]
If the memory allocation in gpiolib_seq_start() fails, the s->private field remains uninitialized and is later dereferenced without checking in gpiolib_seq_stop(). Initialize s->private to NULL before calling kzalloc() and check it before dereferencing it.
--- drivers/gpio/gpiolib.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/gpio/gpiolib.c +7 -1
@@ -5285,6 +5285,8 @@ static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos)struct gpio_device *gdev;loff_t index = *pos; + s->private =NULL ; + priv =kzalloc (sizeof (*priv),GFP_KERNEL );if (!priv)return NULL ;
@@ -5318,7 +5320,11 @@ static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos)static void gpiolib_seq_stop (struct seq_file *s,void *v) { -struct gpiolib_seq_priv *priv = s->private; +struct gpiolib_seq_priv *priv; + + priv = s->private; +if (!priv) +return ;srcu_read_unlock (&gpio_devices_srcu, priv->idx);kfree (priv);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 768/849 net: mdio: Check regmap pointer returned by device_node_to_regmap()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alok Tiwari <[email protected]>
[ Upstream commit b2b526c2cf57d14ee269e012ed179081871f45a1 ]
The call to device_node_to_regmap() in airoha_mdio_probe() can return an ERR_PTR() if regmap initialization fails. Currently, the driver stores the pointer without validation, which could lead to a crash if it is later dereferenced.
Add an IS_ERR() check and return the corresponding error code to make the probe path more robust.
--- drivers/net/mdio/mdio-airoha.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/mdio/mdio-airoha.c +2 -0
@@ -219,6 +219,8 @@ static int airoha_mdio_probe(struct platform_device *pdev) priv = bus->priv; priv->base_addr = addr; priv->regmap =device_node_to_regmap (dev->parent->of_node); +if (IS_ERR (priv->regmap)) +return PTR_ERR (priv->regmap); priv->clk =devm_clk_get_enabled (dev,NULL );if (IS_ERR (priv->clk))
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 769/849 net: dsa: b53: fix resetting speed and pause on forced link
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit b6a8a5477fe9bd6be2b594a88f82f8bba41e6d54 ]
There is no guarantee that the port state override registers have their default values, as not all switches support being reset via register or have a reset GPIO.
So when forcing port config, we need to make sure to clear all fields, which we currently do not do for the speed and flow control configuration. This can cause flow control stay enabled, or in the case of speed becoming an illegal value, e.g. configured for 1G (0x2), then setting 100M (0x1), results in 0x3 which is invalid.
For PORT_OVERRIDE_SPEED_2000M we need to make sure to only clear it on supported chips, as the bit can have different meanings on other chips, e.g. for BCM5389 this controls scanning PHYs for link/speed configuration.
--- drivers/net/dsa/b53/b53_common.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/net/dsa/b53/b53_common.c +9 -0
@@ -1372,6 +1372,10 @@ static void b53_force_port_config(struct b53_device *dev, int port,else reg &= ~PORT_OVERRIDE_FULL_DUPLEX ; + reg &= ~(0x3 <<GMII_PO_SPEED_S ); +if (is5301x (dev) ||is58xx (dev)) + reg &= ~PORT_OVERRIDE_SPEED_2000M ; +switch (speed) {case 2000 : reg |=PORT_OVERRIDE_SPEED_2000M ;
@@ -1390,6 +1394,11 @@ static void b53_force_port_config(struct b53_device *dev, int port,return ; } +if (is5325 (dev)) + reg &= ~PORT_OVERRIDE_LP_FLOW_25 ; +else + reg &= ~(PORT_OVERRIDE_RX_FLOW |PORT_OVERRIDE_TX_FLOW ); +if (rx_pause) {if (is5325 (dev)) reg |=PORT_OVERRIDE_LP_FLOW_25 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 770/849 net: dsa: b53: fix bcm63xx RGMII port link adjustment
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 3e4ebdc1606adf77744cf8ed7a433d279fdc57ba ]
BCM63XX's switch does not support MDIO scanning of external phys, so its MACs needs to be manually configured for autonegotiated link speeds.
So b53_force_port_config() and b53_force_link() accordingly also when mode is MLO_AN_PHY for those ports.
Fixes lower speeds than 1000/full on rgmii ports 4 - 7.
This aligns the behaviour with the old bcm63xx_enetsw driver for those ports.
--- drivers/net/dsa/b53/b53_common.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/net/dsa/b53/b53_common.c +11 -1
@@ -1602,8 +1602,11 @@ static void b53_phylink_mac_link_down(struct phylink_config *config,struct b53_device *dev = dp->ds->priv;int port = dp->index; -if (mode ==MLO_AN_PHY ) +if (mode ==MLO_AN_PHY ) { +if (is63xx (dev) &&in_range (port,B53_63XX_RGMII0 ,4 )) +b53_force_link (dev, port, false);return ; + }if (mode ==MLO_AN_FIXED ) {b53_force_link (dev, port, false);
@@ -1631,6 +1634,13 @@ static void b53_phylink_mac_link_up(struct phylink_config *config,if (mode ==MLO_AN_PHY ) {/* Re-negotiate EEE if it was enabled already */ p->eee_enabled =b53_eee_init (ds, port, phydev); + +if (is63xx (dev) &&in_range (port,B53_63XX_RGMII0 ,4 )) { +b53_force_port_config (dev, port, speed, duplex, + tx_pause, rx_pause); +b53_force_link (dev, port, true); + } +return ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 771/849 net: dsa: b53: fix enabling ip multicast
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit c264294624e956a967a9e2e5fa41e3273340b089 ]
In the New Control register bit 1 is either reserved, or has a different function:
Out of Range Error Discard
When enabled, the ingress port discards any frames if the Length field is between 1500 and 1536 (excluding 1500 and 1536) and with good CRC.
The actual bit for enabling IP multicast is bit 0, which was only explicitly enabled for BCM5325 so far.
For older switch chips, this bit defaults to 0, so we want to enable it as well, while newer switch chips default to 1, and their documentation says "It is illegal to set this bit to zero."
So drop the wrong B53_IPMC_FWD_EN define, enable the IP multicast bit also for other switch chips. While at it, rename it to (B53_)IP_MC as that is how it is called in Broadcom code.
--- drivers/net/dsa/b53/b53_common.c | 4 ++-- drivers/net/dsa/b53/b53_regs.h | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-)
drivers/net/dsa/b53/b53_common.c +2 -2
@@ -371,11 +371,11 @@ static void b53_set_forwarding(struct b53_device *dev, int enable)* frames should be flooded or not. */ b53_read8 (dev,B53_CTRL_PAGE ,B53_IP_MULTICAST_CTRL , &mgmt); - mgmt |=B53_UC_FWD_EN |B53_MC_FWD_EN |B53_IPMC_FWD_EN ; + mgmt |=B53_UC_FWD_EN |B53_MC_FWD_EN |B53_IP_MC ;b53_write8 (dev,B53_CTRL_PAGE ,B53_IP_MULTICAST_CTRL , mgmt); }else {b53_read8 (dev,B53_CTRL_PAGE ,B53_IP_MULTICAST_CTRL , &mgmt); - mgmt |=B53_IP_MCAST_25 ; + mgmt |=B53_IP_MC ;b53_write8 (dev,B53_CTRL_PAGE ,B53_IP_MULTICAST_CTRL , mgmt); } }
drivers/net/dsa/b53/b53_regs.h +1 -2
@@ -111,8 +111,7 @@/* IP Multicast control (8 bit) */ #define B53_IP_MULTICAST_CTRL 0x21 -#define B53_IP_MCAST_25 BIT(0) -#define B53_IPMC_FWD_EN BIT(1) +#define B53_IP_MC BIT(0)#define B53_UC_FWD_EN BIT(6)#define B53_MC_FWD_EN BIT(7)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 772/849 net: dsa: b53: stop reading ARL entries if search is done
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 0be04b5fa62a82a9929ca261f6c9f64a3d0a28da ]
The switch clears the ARL_SRCH_STDN bit when the search is done, i.e. it finished traversing the ARL table.
This means that there will be no valid result, so we should not attempt to read and process any further entries.
We only ever check the validity of the entries for 4 ARL bin chips, and only after having passed the first entry to the b53_fdb_copy().
This means that we always pass an invalid entry at the end to the b53_fdb_copy(). b53_fdb_copy() does check the validity though before passing on the entry, so it never gets passed on.
On < 4 ARL bin chips, we will even continue reading invalid entries until we reach the result limit.
--- drivers/net/dsa/b53/b53_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/dsa/b53/b53_common.c +1 -1
@@ -2037,7 +2037,7 @@ static int b53_arl_search_wait(struct b53_device *dev) do { b53_read8(dev, B53_ARLIO_PAGE, offset, ®); if (!(reg & ARL_SRCH_STDN)) - return 0; + return -ENOENT; if (reg & ARL_SRCH_VLID) return 0;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 773/849 net: dsa: b53: properly bound ARL searches for < 4 ARL bin chips
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit e57723fe536f040cc2635ec1545dd0a7919a321e ]
When iterating over the ARL table we stop at max ARL entries / 2, but this is only valid if the chip actually returns 2 results at once. For chips with only one result register we will stop before reaching the end of the table if it is more than half full.
Fix this by only dividing the maximum results by two if we have a chip with more than one result register (i.e. those with 4 ARL bins).
--- drivers/net/dsa/b53/b53_common.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/net/dsa/b53/b53_common.c +6 -3
@@ -2087,13 +2087,16 @@ static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,int b53_fdb_dump (struct dsa_switch *ds,int port,dsa_fdb_dump_cb_t *cb,void *data) { +unsigned int count =0 , results_per_hit =1 ;struct b53_device *priv = ds->priv;struct b53_arl_entry results[2 ]; -unsigned int count =0 ;u8 offset;int ret;u8 reg; +if (priv->num_arl_bins >2 ) + results_per_hit =2 ; +mutex_lock (&priv->arl_mutex);if (is5325 (priv) ||is5365 (priv))
@@ -2115,7 +2118,7 @@ int b53_fdb_dump(struct dsa_switch *ds, int port,if (ret)break ; -if (priv->num_arl_bins >2 ) { +if (results_per_hit ==2 ) {b53_arl_search_rd (priv,1 , &results[1 ]); ret =b53_fdb_copy (port, &results[1 ], cb, data);if (ret)
@@ -2125,7 +2128,7 @@ int b53_fdb_dump(struct dsa_switch *ds, int port,break ; } - }while (count++ <b53_max_arl_entries (priv) /2 ); + }while (count++ <b53_max_arl_entries (priv) / results_per_hit);mutex_unlock (&priv->arl_mutex);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 774/849 sctp: Hold RCU read lock while iterating over address list
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wiehler <[email protected]>
[ Upstream commit 38f50242bf0f237cdc262308d624d333286ec3c5 ]
With CONFIG_PROVE_RCU_LIST=y and by executing
$ netcat -l --sctp & $ netcat --sctp localhost & $ ss --sctp
one can trigger the following Lockdep-RCU splat(s):
WARNING: suspicious RCU usage 6.18.0-rc1-00093-g7f864458e9a6 #5 Not tainted
-----------------------------
net/sctp/diag.c:76 RCU-list traversed in non-reader section!!
other info that might help us debug this:
rcu_scheduler_active = 2, debug_locks = 1
2 locks held by ss/215:
#0: ffff9c740828bec0 (nlk_cb_mutex-SOCK_DIAG){+.+.}-{4:4}, at: __netlink_dump_start+0x84/0x2b0 #1: ffff9c7401d72cd0 (sk_lock-AF_INET6){+.+.}-{0:0}, at: sctp_sock_dump+0x38/0x200
stack backtrace: CPU: 0 UID: 0 PID: 215 Comm: ss Not tainted 6.18.0-rc1-00093-g7f864458e9a6 #5 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x5d/0x90 lockdep_rcu_suspicious.cold+0x4e/0xa3 inet_sctp_diag_fill.isra.0+0x4b1/0x5d0 sctp_sock_dump+0x131/0x200 sctp_transport_traverse_process+0x170/0x1b0 ? __pfx_sctp_sock_filter+0x10/0x10 ? __pfx_sctp_sock_dump+0x10/0x10 sctp_diag_dump+0x103/0x140 __inet_diag_dump+0x70/0xb0 netlink_dump+0x148/0x490 __netlink_dump_start+0x1f3/0x2b0 inet_diag_handler_cmd+0xcd/0x100 ? __pfx_inet_diag_dump_start+0x10/0x10 ? __pfx_inet_diag_dump+0x10/0x10 ? __pfx_inet_diag_dump_done+0x10/0x10 sock_diag_rcv_msg+0x18e/0x320 ? __pfx_sock_diag_rcv_msg+0x10/0x10 netlink_rcv_skb+0x4d/0x100 netlink_unicast+0x1d7/0x2b0 netlink_sendmsg+0x203/0x450 ____sys_sendmsg+0x30c/0x340 ___sys_sendmsg+0x94/0xf0 __sys_sendmsg+0x83/0xf0 do_syscall_64+0xbb/0x390 entry_SYSCALL_64_after_hwframe+0x77/0x7f ... </TASK>
--- net/sctp/diag.c | 4 ++++ 1 file changed, 4 insertions(+)
net/sctp/diag.c +4 -0
@@ -73,19 +73,23 @@ static int inet_diag_msg_sctpladdrs_fill(struct sk_buff *skb,struct nlattr *attr;void *info =NULL ; +rcu_read_lock ();list_for_each_entry_rcu (laddr, address_list, list) addrcnt++; +rcu_read_unlock (); attr =nla_reserve (skb,INET_DIAG_LOCALS , addrlen * addrcnt);if (!attr)return -EMSGSIZE ; info =nla_data (attr); +rcu_read_lock ();list_for_each_entry_rcu (laddr, address_list, list) {memcpy (info, &laddr->a,sizeof (laddr->a));memset (info +sizeof (laddr->a),0 , addrlen -sizeof (laddr->a)); info += addrlen; } +rcu_read_unlock ();return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 775/849 sctp: Prevent TOCTOU out-of-bounds write
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wiehler <[email protected]>
[ Upstream commit 95aef86ab231f047bb8085c70666059b58f53c09 ]
For the following path not holding the sock lock,
sctp_diag_dump() -> sctp_for_each_endpoint() -> sctp_ep_dump()
make sure not to exceed bounds in case the address list has grown between buffer allocation (time-of-check) and write (time-of-use).
--- net/sctp/diag.c | 3 +++ 1 file changed, 3 insertions(+)
net/sctp/diag.c +3 -0
@@ -88,6 +88,9 @@ static int inet_diag_msg_sctpladdrs_fill(struct sk_buff *skb,memcpy (info, &laddr->a,sizeof (laddr->a));memset (info +sizeof (laddr->a),0 , addrlen -sizeof (laddr->a)); info += addrlen; + +if (!--addrcnt) +break ; }rcu_read_unlock ();
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 776/849 sctp: Hold sock lock while iterating over address list
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wiehler <[email protected]>
[ Upstream commit f1fc201148c7e684c10a72b6a3375597f28d1ef6 ]
Move address list traversal in inet_assoc_attr_size() under the sock lock to avoid holding the RCU read lock.
--- net/sctp/diag.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
net/sctp/diag.c +9 -5
@@ -230,14 +230,15 @@ struct sctp_comm_param {bool net_admin; }; -static size_t inet_assoc_attr_size (struct sctp_association *asoc) +static size_t inet_assoc_attr_size (struct sock *sk, +struct sctp_association *asoc) {int addrlen =sizeof (struct sockaddr_storage );int addrcnt =0 ;struct sctp_sockaddr_entry *laddr;list_for_each_entry_rcu (laddr, &asoc->base.bind_addr.address_list, - list) + list,lockdep_sock_is_held (sk)) addrcnt++;return nla_total_size (sizeof (struct sctp_info ))
@@ -263,11 +264,14 @@ static int sctp_sock_dump_one(struct sctp_endpoint *ep, struct sctp_transport *tif (err)return err; - rep =nlmsg_new (inet_assoc_attr_size (assoc),GFP_KERNEL ); -if (!rep) +lock_sock (sk); + + rep =nlmsg_new (inet_assoc_attr_size (sk, assoc),GFP_KERNEL ); +if (!rep) { +release_sock (sk);return -ENOMEM ; + } -lock_sock (sk);if (ep != assoc->ep) { err = -EAGAIN ; goto out;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 777/849 net: ionic: add dma_wmb() before ringing TX doorbell
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mohammad Heib <[email protected]>
[ Upstream commit d261f5b09c28850dc63ca1d3018596f829f402d5 ]
The TX path currently writes descriptors and then immediately writes to the MMIO doorbell register to notify the NIC. On weakly ordered architectures, descriptor writes may still be pending in CPU or DMA write buffers when the doorbell is issued, leading to the device fetching stale or incomplete descriptors.
Add a dma_wmb() in ionic_txq_post() to ensure all descriptor writes are visible to the device before the doorbell MMIO write.
--- drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/ethernet/pensando/ionic/ionic_txrx.c +4 -0
@@ -29,6 +29,10 @@ static void ionic_tx_clean(struct ionic_queue *q,static inline void ionic_txq_post (struct ionic_queue *q,bool ring_dbell) { +/* Ensure TX descriptor writes reach memory before NIC reads them. +* Prevents device from fetching stale descriptors. +*/ +dma_wmb ();ionic_q_post (q, ring_dbell); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 778/849 net: ionic: map SKB after pseudo-header checksum prep
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mohammad Heib <[email protected]>
[ Upstream commit de0337d641bfa5b6d6b489e479792f1039274e84 ]
The TSO path called ionic_tx_map_skb() before preparing the TCP pseudo checksum (ionic_tx_tcp_[inner_]pseudo_csum()), which may perform skb_cow_head() and might modifies bytes in the linear header area.
Mapping first and then mutating the header risks:
- Using a stale DMA address if skb_cow_head() relocates the head, and/or
- Device reading stale header bytes on weakly-ordered systems (CPU writes after mapping are not guaranteed visible without an explicit dma_sync_single_for_device()).
Reorder the TX path to perform all header mutations (including skb_cow_head()) *before* DMA mapping. Mapping is now done only after the skb layout and header contents are final. This removes the need for any post-mapping dma_sync and prevents on-wire corruption observed under VLAN+TSO load after repeated runs.
This change is purely an ordering fix; no functional behavior change otherwise.
--- .../net/ethernet/pensando/ionic/ionic_txrx.c | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-)
drivers/net/ethernet/pensando/ionic/ionic_txrx.c +13 -17
@@ -1448,19 +1448,6 @@ static int ionic_tx_tso(struct net_device *netdev, struct ionic_queue *q,bool encap;int err; - desc_info = &q->tx_info[q->head_idx]; - -if (unlikely (ionic_tx_map_skb (q, skb, desc_info))) -return -EIO ; - - len = skb->len; - mss =skb_shinfo (skb)->gso_size; - outer_csum = (skb_shinfo (skb)->gso_type & (SKB_GSO_GRE | -SKB_GSO_GRE_CSUM | -SKB_GSO_IPXIP4 | -SKB_GSO_IPXIP6 | -SKB_GSO_UDP_TUNNEL | -SKB_GSO_UDP_TUNNEL_CSUM )); has_vlan = !!skb_vlan_tag_present (skb); vlan_tci =skb_vlan_tag_get (skb); encap = skb->encapsulation;
@@ -1474,12 +1461,21 @@ static int ionic_tx_tso(struct net_device *netdev, struct ionic_queue *q, err =ionic_tx_tcp_inner_pseudo_csum (skb); else err =ionic_tx_tcp_pseudo_csum (skb); -if (unlikely (err)) { -/* clean up mapping from ionic_tx_map_skb */ -ionic_tx_desc_unmap_bufs (q, desc_info); +if (unlikely (err))return err; - } + desc_info = &q->tx_info[q->head_idx]; +if (unlikely (ionic_tx_map_skb (q, skb, desc_info))) +return -EIO ; + + len = skb->len; + mss =skb_shinfo (skb)->gso_size; + outer_csum = (skb_shinfo (skb)->gso_type & (SKB_GSO_GRE | +SKB_GSO_GRE_CSUM | +SKB_GSO_IPXIP4 | +SKB_GSO_IPXIP6 | +SKB_GSO_UDP_TUNNEL | +SKB_GSO_UDP_TUNNEL_CSUM ));if (encap) hdrlen =skb_inner_tcp_all_headers (skb);else
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 779/849 octeontx2-pf: Fix devm_kcalloc() error checking
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 2e25935ed24daee37c4c2e8e29e478ce6e1f72c7 ]
The devm_kcalloc() function never return error pointers, it returns NULL on failure. Also delete the netdev_err() printk. These allocation functions already have debug output built-in some the extra error message is not required.
--- drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +2 -4
@@ -1516,10 +1516,8 @@ int otx2_pool_init(struct otx2_nic *pfvf, u16 pool_id, pool->xdp_cnt = numptrs; pool->xdp =devm_kcalloc (pfvf->dev, numptrs,sizeof (struct xdp_buff *),GFP_KERNEL ); -if (IS_ERR (pool->xdp)) { -netdev_err (pfvf->netdev,"Creation of xsk pool failed\n" ); -return PTR_ERR (pool->xdp); - } +if (!pool->xdp) +return -ENOMEM ; }return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 780/849 net: usb: qmi_wwan: initialize MAC header offset in qmimux_rx_fixup
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qendrim Maxhuni <[email protected]>
[ Upstream commit e120f46768d98151ece8756ebd688b0e43dc8b29 ]
Raw IP packets have no MAC header, leaving skb->mac_header uninitialized. This can trigger kernel panics on ARM64 when xfrm or other subsystems access the offset due to strict alignment checks.
Initialize the MAC header to prevent such crashes.
This can trigger kernel panics on ARM when running IPsec over the qmimux0 interface.
Example trace:
Internal error: Oops: 000000009600004f [#1] SMP
CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.12.34-gbe78e49cb433 #1
Hardware name: LS1028A RDB Board (DT)
pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : xfrm_input+0xde8/0x1318
lr : xfrm_input+0x61c/0x1318
sp : ffff800080003b20
Call trace:
xfrm_input+0xde8/0x1318
xfrm6_rcv+0x38/0x44
xfrm6_esp_rcv+0x48/0xa8
ip6_protocol_deliver_rcu+0x94/0x4b0
ip6_input_finish+0x44/0x70
ip6_input+0x44/0xc0
ipv6_rcv+0x6c/0x114
__netif_receive_skb_one_core+0x5c/0x8c
__netif_receive_skb+0x18/0x60
process_backlog+0x78/0x17c
__napi_poll+0x38/0x180
net_rx_action+0x168/0x2f0--- drivers/net/usb/qmi_wwan.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/usb/qmi_wwan.c +6 -0
@@ -192,6 +192,12 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)if (!skbn)return 0 ; +/* Raw IP packets don't have a MAC header, but other subsystems +* (like xfrm) may still access MAC header offsets, so they must +* be initialized. +*/ +skb_reset_mac_header (skbn); +switch (skb->data[offset + qmimux_hdr_sz] &0xf0 ) {case 0x40 : skbn->protocol =htons (ETH_P_IP );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 781/849 bnxt_en: Shutdown FW DMA in bnxt_shutdown()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Chan <[email protected]>
[ Upstream commit bc7208ca805ae6062f353a4753467d913d963bc6 ]
The netif_close() call in bnxt_shutdown() only stops packet DMA. There may be FW DMA for trace logging (recently added) that will continue. If we kexec to a new kernel, the DMA will corrupt memory in the new kernel.
Add bnxt_hwrm_func_drv_unrgtr() to unregister the driver from the FW. This will stop the FW DMA. In case the call fails, call pcie_flr() to reset the function and stop the DMA.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +4 -0
@@ -16869,6 +16869,10 @@ static void bnxt_shutdown(struct pci_dev *pdev)if (netif_running (dev))netif_close (dev); +if (bnxt_hwrm_func_drv_unrgtr (bp)) { +pcie_flr (pdev); + goto shutdown_exit; + }bnxt_ptp_clear (bp);bnxt_clear_int_mode (bp);pci_disable_device (pdev);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 782/849 bnxt_en: Fix a possible memory leak in bnxt_ptp_init
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kalesh AP <[email protected]>
[ Upstream commit deb8eb39164382f1f67ef8e8af9176baf5e10f2d ]
In bnxt_ptp_init(), when ptp_clock_register() fails, the driver is not freeing the memory allocated for ptp_info->pin_config. Fix it to unconditionally free ptp_info->pin_config in bnxt_ptp_free().
--- drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +2 -2
@@ -1054,9 +1054,9 @@ static void bnxt_ptp_free(struct bnxt *bp)if (ptp->ptp_clock) {ptp_clock_unregister (ptp->ptp_clock); ptp->ptp_clock =NULL ; -kfree (ptp->ptp_info.pin_config); - ptp->ptp_info.pin_config =NULL ; } +kfree (ptp->ptp_info.pin_config); + ptp->ptp_info.pin_config =NULL ; }int bnxt_ptp_init (struct bnxt *bp)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 783/849 bnxt_en: Fix null pointer dereference in bnxt_bs_trace_check_wrap()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gautam R A <[email protected]>
[ Upstream commit ff02be05f78399c766be68ab0b2285ff90b2aaa8 ]
With older FW, we may get the ASYNC_EVENT_CMPL_EVENT_ID_DBG_BUF_PRODUCER for FW trace data type that has not been initialized. This will result in a crash in bnxt_bs_trace_type_wrap(). Add a guard to check for a valid magic_byte pointer before proceeding.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.h +1 -1
@@ -2148,7 +2148,7 @@ struct bnxt_bs_trace_info {static inline void bnxt_bs_trace_check_wrap (struct bnxt_bs_trace_info *bs_trace,u32 offset) { -if (!bs_trace->wrapped && +if (!bs_trace->wrapped && bs_trace->magic_byte && *bs_trace->magic_byte !=BNXT_TRACE_BUF_MAGIC_BYTE ) bs_trace->wrapped =1 ; bs_trace->last_offset = offset;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 784/849 bnxt_en: Always provide max entry and entry size in coredump segments
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kashyap Desai <[email protected]>
[ Upstream commit 28d9a84ef0ce56cc623da2a1ebf7583c00d52b31 ]
While populating firmware host logging segments for the coredump, it is possible for the FW command that flushes the segment to fail. When that happens, the existing code will not update the max entry and entry size in the segment header and this causes software that decodes the coredump to skip the segment.
The segment most likely has already collected some DMA data, so always update these 2 segment fields in the header to allow the decoder to decode any data in the segment.
--- drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c +3 -2
@@ -332,13 +332,14 @@ static void bnxt_fill_drv_seg_record(struct bnxt *bp,u32 offset =0 ;int rc =0 ; + record->max_entries =cpu_to_le32 (ctxm->max_entries); + record->entry_size =cpu_to_le32 (ctxm->entry_size); + rc =bnxt_dbg_hwrm_log_buffer_flush (bp, type,0 , &offset);if (rc)return ;bnxt_bs_trace_check_wrap (bs_trace, offset); - record->max_entries =cpu_to_le32 (ctxm->max_entries); - record->entry_size =cpu_to_le32 (ctxm->entry_size); record->offset =cpu_to_le32 (bs_trace->last_offset); record->wrapped = bs_trace->wrapped; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 785/849 bnxt_en: Fix warning in bnxt_dl_reload_down()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shantiprasad Shettar <[email protected]>
[ Upstream commit 5204943a4c6efc832993c0fa17dec275071eeccc ]
The existing code calls bnxt_cancel_reservations() after bnxt_hwrm_func_drv_unrgtr() in bnxt_dl_reload_down(). bnxt_cancel_reservations() calls the FW and it will always fail since the driver has already unregistered, triggering this warning:
bnxt_en 0000:0a:00.0 ens2np0: resc_qcaps failed
Fix it by calling bnxt_clear_reservations() which will skip the unnecessary FW call since we have unregistered.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 + drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +1 -1
@@ -12428,7 +12428,7 @@ static int bnxt_try_recover_fw(struct bnxt *bp)return -ENODEV ; } -static void bnxt_clear_reservations (struct bnxt *bp,bool fw_reset) +void bnxt_clear_reservations (struct bnxt *bp,bool fw_reset) {struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
drivers/net/ethernet/broadcom/bnxt/bnxt.h +1 -0
@@ -2930,6 +2930,7 @@ void bnxt_report_link(struct bnxt *bp);int bnxt_update_link (struct bnxt *bp,bool chng_link_state);int bnxt_hwrm_set_pause (struct bnxt *);int bnxt_hwrm_set_link_setting (struct bnxt *,bool ,bool ); +void bnxt_clear_reservations (struct bnxt *bp,bool fw_reset);int bnxt_cancel_reservations (struct bnxt *bp,bool fw_reset);int bnxt_hwrm_alloc_wol_fltr (struct bnxt *bp);int bnxt_hwrm_free_wol_fltr (struct bnxt *bp);
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c +1 -1
@@ -467,7 +467,7 @@ static int bnxt_dl_reload_down(struct devlink *dl, bool netns_change,rtnl_unlock ();break ; } -bnxt_cancel_reservations (bp, false); +bnxt_clear_reservations (bp, false);bnxt_free_ctx_mem (bp, false);break ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 786/849 netpoll: Fix deadlock in memory allocation under spinlock
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit 327c20c21d80e0d87834b392d83ae73c955ad8ff ]
Fix a AA deadlock in refill_skbs() where memory allocation while holding skb_pool->lock can trigger a recursive lock acquisition attempt.
The deadlock scenario occurs when the system is under severe memory pressure:
1. refill_skbs() acquires skb_pool->lock (spinlock)
2. alloc_skb() is called while holding the lock
3. Memory allocator fails and calls slab_out_of_memory()
4. This triggers printk() for the OOM warning
5. The console output path calls netpoll_send_udp()
6. netpoll_send_udp() attempts to acquire the same skb_pool->lock
7. Deadlock: the lock is already held by the same CPU
Call stack:
refill_skbs()
spin_lock_irqsave(&skb_pool->lock) <- lock acquired
__alloc_skb()
kmem_cache_alloc_node_noprof()
slab_out_of_memory()
printk()
console_flush_all()
netpoll_send_udp()
skb_dequeue()
spin_lock_irqsave(&skb_pool->lock) <- deadlock attemptThis bug was exposed by commit 248f6571fd4c51 ("netpoll: Optimize skb refilling on critical path") which removed refill_skbs() from the critical path (where nested printk was being deferred), letting nested printk being called from inside refill_skbs()
Refactor refill_skbs() to never allocate memory while holding the spinlock.
Another possible solution to fix this problem is protecting the refill_skbs() from nested printks, basically calling printk_deferred_{enter,exit}() in refill_skbs(), then, any nested pr_warn() would be deferred.
I prefer this approach, given I _think_ it might be a good idea to move the alloc_skb() from GFP_ATOMIC to GFP_KERNEL in the future, so, having the alloc_skb() outside of the lock will be necessary step.
There is a possible TOCTOU issue when checking for the pool length, and queueing the new allocated skb, but, this is not an issue, given that an extra SKB in the pool is harmless and it will be eventually used.
--- net/core/netpoll.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
net/core/netpoll.c +2 -5
@@ -228,19 +228,16 @@ static void refill_skbs(struct netpoll *np) {struct sk_buff_head *skb_pool;struct sk_buff *skb; -unsigned long flags; skb_pool = &np->skb_pool; -spin_lock_irqsave (&skb_pool->lock, flags); -while (skb_pool->qlen <MAX_SKBS ) { +while (READ_ONCE (skb_pool->qlen) <MAX_SKBS ) { skb =alloc_skb (MAX_SKB_SIZE ,GFP_ATOMIC );if (!skb)break ; -__skb_queue_tail (skb_pool, skb); +skb_queue_tail (skb_pool, skb); } -spin_unlock_irqrestore (&skb_pool->lock, flags); }static void zap_completion_queue (void )
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 787/849 wifi: mac80211_hwsim: Limit destroy_on_close radio removal to netgroup
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Willi <[email protected]>
[ Upstream commit c74619e7602e88a0239cd4999571dd31081e9adf ]
hwsim radios marked destroy_on_close are removed when the Netlink socket that created them is closed. As the portid is not unique across network namespaces, closing a socket in one namespace may remove radios in another if it has the destroy_on_close flag set.
Instead of matching the network namespace, match the netgroup of the radio to limit radio removal to those that have been created by the closing Netlink socket. The netgroup of a radio identifies the network namespace it was created in, and matching on it removes a destroy_on_close radio even if it has been moved to another namespace.
--- drivers/net/wireless/virtual/mac80211_hwsim.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/net/wireless/virtual/mac80211_hwsim.c +4 -3
@@ -6453,14 +6453,15 @@ static struct genl_family hwsim_genl_family __ro_after_init = { .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps), }; -static void remove_user_radios (u32 portid) +static void remove_user_radios (u32 portid,int netgroup) {struct mac80211_hwsim_data *entry, *tmp;LIST_HEAD (list);spin_lock_bh (&hwsim_radio_lock);list_for_each_entry_safe (entry, tmp, &hwsim_radios, list) { -if (entry->destroy_on_close && entry->portid == portid) { +if (entry->destroy_on_close && entry->portid == portid && + entry->netgroup == netgroup) {list_move (&entry->list, &list);rhashtable_remove_fast (&hwsim_radios_rht, &entry->rht, hwsim_rht_params);
@@ -6485,7 +6486,7 @@ static int mac80211_hwsim_netlink_notify(struct notifier_block *nb,if (state !=NETLINK_URELEASE )return NOTIFY_DONE ; -remove_user_radios (notify->portid); +remove_user_radios (notify->portid,hwsim_net_get_netgroup (notify->net));if (notify->portid ==hwsim_net_get_wmediumd (notify->net)) { printk(KERN_INFO "mac80211_hwsim: wmediumd released netlink"
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 788/849 io_uring: fix types for region size calulation
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Begunkov <[email protected]>
[ Upstream commit 1fd5367391bf0eeb09e624c4ab45121b54eaab96 ]
->nr_pages is int, it needs type extension before calculating the region size.
--- io_uring/memmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
io_uring/memmap.c +1 -1
@@ -135,7 +135,7 @@ static int io_region_pin_pages(struct io_ring_ctx *ctx,struct io_mapped_region *mr, struct io_uring_region_desc *reg) { - unsigned long size = mr->nr_pages << PAGE_SHIFT; + unsigned long size = (size_t) mr->nr_pages << PAGE_SHIFT;struct page **pages;int nr_pages;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 789/849 net/mlx5e: Fix return value in case of module EEPROM read error
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gal Pressman <[email protected]>
[ Upstream commit d1c94bc5b90c21b65469d30d4a6bc8ed715c1bfe ]
mlx5e_get_module_eeprom_by_page() has weird error handling.
First, it is treating -EINVAL as a special case, but it is unclear why.
Second, it tries to fail "gracefully" by returning the number of bytes read even in case of an error. This results in wrongly returning success (0 return value) if the error occurs before any bytes were read.
Simplify the error handling by returning an error when such occurs. This also aligns with the error handling we have in mlx5e_get_module_eeprom() for the old API.
This fixes the following case where the query fails, but userspace ethtool wrongly treats it as success and dumps an output:
# ethtool -m eth2 netlink warning: mlx5_core: Query module eeprom by page failed, read 0 bytes, err -5 netlink warning: mlx5_core: Query module eeprom by page failed, read 0 bytes, err -5 Offset Values ------ ------ 0x0000: 00 00 00 00 05 00 04 00 00 00 00 00 05 00 05 00 0x0010: 00 00 00 00 05 00 06 00 50 00 00 00 67 65 20 66 0x0020: 61 69 6c 65 64 2c 20 72 65 61 64 20 30 20 62 79 0x0030: 74 65 73 2c 20 65 72 72 20 2d 35 00 14 00 03 00 0x0040: 08 00 01 00 03 00 00 00 08 00 02 00 1a 00 00 00 0x0050: 14 00 04 00 08 00 01 00 04 00 00 00 08 00 02 00 0x0060: 0e 00 00 00 14 00 05 00 08 00 01 00 05 00 00 00 0x0070: 08 00 02 00 1a 00 00 00 14 00 06 00 08 00 01 00
--- drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +1 -3
@@ -2121,14 +2121,12 @@ static int mlx5e_get_module_eeprom_by_page(struct net_device *netdev,if (!size_read)return i; -if (size_read == -EINVAL ) -return -EINVAL ;if (size_read <0 ) {NL_SET_ERR_MSG_FMT_MOD ( extack,"Query module eeprom by page failed, read %u bytes, err %d" , i, size_read); -return i; +return size_read; } i += size_read;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 790/849 net: ti: icssg-prueth: Fix fdb hash size configuration
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Meghana Malladi <[email protected]>
[ Upstream commit ae4789affd1e181ae46e72e2b5fbe2d6d7b6616a ]
The ICSSG driver does the initial FDB configuration which includes setting the control registers. Other run time management like learning is managed by the PRU's. The default FDB hash size used by the firmware is 512 slots, which is currently missing in the current driver. Update the driver FDB config to include FDB hash size as well.
Please refer trm [1] 6.4.14.12.17 section on how the FDB config register gets configured. From the table 6-1404, there is a reset field for FDB_HAS_SIZE which is 4, meaning 1024 slots. Currently the driver is not updating this reset value from 4(1024 slots) to 3(512 slots). This patch fixes this by updating the reset value to 512 slots.
[1]: https://www.ti.com/lit/pdf/spruim2
--- drivers/net/ethernet/ti/icssg/icssg_config.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/ethernet/ti/icssg/icssg_config.c +7 -0
@@ -66,6 +66,9 @@#define FDB_GEN_CFG1 0x60#define SMEM_VLAN_OFFSET 8#define SMEM_VLAN_OFFSET_MASK GENMASK(25, 8) +#define FDB_HASH_SIZE_MASK GENMASK(6, 3) +#define FDB_HASH_SIZE_SHIFT 3 +#define FDB_HASH_SIZE 3#define FDB_GEN_CFG2 0x64#define FDB_VLAN_EN BIT(6)
@@ -463,6 +466,8 @@ void icssg_init_emac_mode(struct prueth *prueth)/* Set VLAN TABLE address base */ regmap_update_bits (prueth->miig_rt,FDB_GEN_CFG1 ,SMEM_VLAN_OFFSET_MASK , addr <<SMEM_VLAN_OFFSET ); +regmap_update_bits (prueth->miig_rt,FDB_GEN_CFG1 ,FDB_HASH_SIZE_MASK , +FDB_HASH_SIZE <<FDB_HASH_SIZE_SHIFT );/* Set enable VLAN aware mode, and FDBs for all PRUs */ regmap_write (prueth->miig_rt,FDB_GEN_CFG2 , (FDB_PRU0_EN |FDB_PRU1_EN |FDB_HOST_EN )); prueth->vlan_tbl = (struct prueth_vlan_tbl __force *)(prueth->shram.va +
@@ -484,6 +489,8 @@ void icssg_init_fw_offload_mode(struct prueth *prueth)/* Set VLAN TABLE address base */ regmap_update_bits (prueth->miig_rt,FDB_GEN_CFG1 ,SMEM_VLAN_OFFSET_MASK , addr <<SMEM_VLAN_OFFSET ); +regmap_update_bits (prueth->miig_rt,FDB_GEN_CFG1 ,FDB_HASH_SIZE_MASK , +FDB_HASH_SIZE <<FDB_HASH_SIZE_SHIFT );/* Set enable VLAN aware mode, and FDBs for all PRUs */ regmap_write (prueth->miig_rt,FDB_GEN_CFG2 ,FDB_EN_ALL ); prueth->vlan_tbl = (struct prueth_vlan_tbl __force *)(prueth->shram.va +
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 791/849 net/mlx5e: SHAMPO, Fix header mapping for 64K pages
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dragos Tatulea <[email protected]>
[ Upstream commit 665a7e13c220bbde55531a24bd5524320648df10 ]
HW-GRO is broken on mlx5 for 64K page sizes. The patch in the fixes tag didn't take into account larger page sizes when doing an align down of max_ksm_entries. For 64K page size, max_ksm_entries is 0 which will skip mapping header pages via WQE UMR. This breaks header-data split and will result in the following syndrome:
mlx5_core 0000:00:08.0 eth2: Error cqe on cqn 0x4c9, ci 0x0, qn 0x1133, opcode 0xe, syndrome 0x4, vendor syndrome 0x32 00000000: 00 00 00 00 04 4a 00 00 00 00 00 00 20 00 93 32
00000010: 55 00 00 00 fb cc 00 00 00 00 00 00 07 18 00 00
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4a
00000030: 00 00 3b c7 93 01 32 04 00 00 00 00 00 00 bf e0mlx5_core 0000:00:08.0 eth2: ERR CQE on RQ: 0x1133
Furthermore, the function that fills in WQE UMRs for the headers (mlx5e_build_shampo_hd_umr()) only supports mapping page sizes that fit in a single UMR WQE.
This patch goes back to the old non-aligned max_ksm_entries value and it changes mlx5e_build_shampo_hd_umr() to support mapping a large page over multiple UMR WQEs.
This means that mlx5e_build_shampo_hd_umr() can now leave a page only partially mapped. The caller, mlx5e_alloc_rx_hd_mpwqe(), ensures that there are enough UMR WQEs to cover complete pages by working on ksm_entries that are multiples of MLX5E_SHAMPO_WQ_HEADER_PER_PAGE.
--- .../net/ethernet/mellanox/mlx5/core/en_rx.c | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +17 -19
@@ -670,7 +670,7 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq,u16 pi, header_offset, err, wqe_bbs;u32 lkey = rq->mdev->mlx5e_res.hw_objs.mkey;struct mlx5e_umr_wqe *umr_wqe; -int headroom, i =0 ; +int headroom, i; headroom = rq->buff.headroom; wqe_bbs =MLX5E_KSM_UMR_WQEBBS (ksm_entries);
@@ -678,25 +678,24 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq, umr_wqe =mlx5_wq_cyc_get_wqe (&sq->wq, pi);build_ksm_umr (sq, umr_wqe, shampo->mkey_be, index, ksm_entries); -WARN_ON_ONCE (ksm_entries & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE -1 )); -while (i < ksm_entries) { -struct mlx5e_frag_page *frag_page =mlx5e_shampo_hd_to_frag_page (rq, index); +for (i =0 ; i < ksm_entries; i++, index++) { +struct mlx5e_frag_page *frag_page;u64 addr; - err =mlx5e_page_alloc_fragmented (rq->hd_page_pool, frag_page); -if (unlikely (err)) - goto err_unmap; + frag_page =mlx5e_shampo_hd_to_frag_page (rq, index); + header_offset =mlx5e_shampo_hd_offset (index); +if (!header_offset) { + err =mlx5e_page_alloc_fragmented (rq->hd_page_pool, + frag_page); +if (err) + goto err_unmap; + } addr =page_pool_get_dma_addr_netmem (frag_page->netmem); - -for (int j =0 ; j <MLX5E_SHAMPO_WQ_HEADER_PER_PAGE ; j++) { - header_offset =mlx5e_shampo_hd_offset (index++); - - umr_wqe->inline_ksms[i++] = (struct mlx5_ksm ) { - .key =cpu_to_be32 (lkey), - .va =cpu_to_be64 (addr + header_offset + headroom), - }; - } + umr_wqe->inline_ksms[i] = (struct mlx5_ksm ) { + .key =cpu_to_be32 (lkey), + .va =cpu_to_be64 (addr + header_offset + headroom), + }; } sq->db.wqe_info[pi] = (struct mlx5e_icosq_wqe_info ) {
@@ -712,7 +711,7 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq,return 0 ; err_unmap: -while (--i) { +while (--i >=0 ) { --index; header_offset =mlx5e_shampo_hd_offset (index);if (!header_offset) {
@@ -734,8 +733,7 @@ static int mlx5e_alloc_rx_hd_mpwqe(struct mlx5e_rq *rq)struct mlx5e_icosq *sq = rq->icosq;int i, err, max_ksm_entries, len; - max_ksm_entries =ALIGN_DOWN (MLX5E_MAX_KSM_PER_WQE (rq->mdev), -MLX5E_SHAMPO_WQ_HEADER_PER_PAGE ); + max_ksm_entries =MLX5E_MAX_KSM_PER_WQE (rq->mdev); ksm_entries =bitmap_find_window (shampo->bitmap, shampo->hd_per_wqe, shampo->hd_per_wq, shampo->pi);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 792/849 net/mlx5e: SHAMPO, Fix skb size check for 64K pages
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dragos Tatulea <[email protected]>
[ Upstream commit bacd8d80181ebe34b599a39aa26bf73a44c91e55 ]
mlx5e_hw_gro_skb_has_enough_space() uses a formula to check if there is enough space in the skb frags to store more data. This formula is incorrect for 64K page sizes and it triggers early GRO session termination because the first fragment will blow up beyond GRO_LEGACY_MAX_SIZE.
This patch adds a special case for page sizes >= GRO_LEGACY_MAX_SIZE (64K) which uses the skb->len instead. Within this context, the check is safe from fragment overflow because the hardware will continuously fill the data up to the reservation size of 64K and the driver will coalesce all data from the same page to the same fragment. This means that the data will span one fragment or at most two for such a large page size.
It is expected that the if statement will be optimized out as the check is done with constants.
--- drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +4 -1
@@ -2327,7 +2327,10 @@ mlx5e_hw_gro_skb_has_enough_space(struct sk_buff *skb, u16 data_bcnt) {int nr_frags =skb_shinfo (skb)->nr_frags; -return PAGE_SIZE * nr_frags + data_bcnt <=GRO_LEGACY_MAX_SIZE ; +if (PAGE_SIZE >=GRO_LEGACY_MAX_SIZE ) +return skb->len + data_bcnt <=GRO_LEGACY_MAX_SIZE ; +else +return PAGE_SIZE * nr_frags + data_bcnt <=GRO_LEGACY_MAX_SIZE ; }static void mlx5e_handle_rx_cqe_mpwrq_shampo (struct mlx5e_rq *rq,struct mlx5_cqe64 *cqe)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 793/849 net/mlx5e: SHAMPO, Fix header formulas for higher MTUs and 64K pages
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dragos Tatulea <[email protected]>
[ Upstream commit d8a7ed9586c7579a99e9e2d90988c9eceeee61ff ]
The MLX5E_SHAMPO_WQ_HEADER_PER_PAGE and MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE macros are used directly in several places under the assumption that there will always be more headers per WQE than headers per page. However, this assumption doesn't hold for 64K page sizes and higher MTUs (> 4K). This can be first observed during header page allocation: ksm_entries will become 0 during alignment to MLX5E_SHAMPO_WQ_HEADER_PER_PAGE.
This patch introduces 2 additional members to the mlx5e_shampo_hd struct which are meant to be used instead of the macrose mentioned above. When the number of headers per WQE goes below MLX5E_SHAMPO_WQ_HEADER_PER_PAGE, clamp the number of headers per page and expand the header size accordingly so that the headers for one WQE cover a full page.
All the formulas are adapted to use these two new members.
--- drivers/net/ethernet/mellanox/mlx5/core/en.h | 3 ++ .../net/ethernet/mellanox/mlx5/core/en_main.c | 24 +++++++++++--- .../net/ethernet/mellanox/mlx5/core/en_rx.c | 33 +++++++++++-------- 3 files changed, 41 insertions(+), 19 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en.h +3 -0
@@ -632,7 +632,10 @@ struct mlx5e_dma_info {struct mlx5e_shampo_hd {struct mlx5e_frag_page *pages;u32 hd_per_wq; +u32 hd_per_page;u16 hd_per_wqe; +u8 log_hd_per_page; +u8 log_hd_entry_size;unsigned long *bitmap;u16 pi;u16 ci;
drivers/net/ethernet/mellanox/mlx5/core/en_main.c +19 -5
@@ -793,8 +793,9 @@ static int mlx5_rq_shampo_alloc(struct mlx5_core_dev *mdev, int node) {void *wqc =MLX5_ADDR_OF (rqc, rqp->rqc, wq); +u8 log_hd_per_page, log_hd_entry_size; +u16 hd_per_wq, hd_per_wqe;u32 hd_pool_size; -u16 hd_per_wq;int wq_size;int err;
@@ -817,11 +818,24 @@ static int mlx5_rq_shampo_alloc(struct mlx5_core_dev *mdev,if (err) goto err_umr_mkey; - rq->mpwqe.shampo->hd_per_wqe = -mlx5e_shampo_hd_per_wqe (mdev, params, rqp); + hd_per_wqe =mlx5e_shampo_hd_per_wqe (mdev, params, rqp); wq_size =BIT (MLX5_GET (wq, wqc, log_wq_sz)); - hd_pool_size = (rq->mpwqe.shampo->hd_per_wqe * wq_size) / -MLX5E_SHAMPO_WQ_HEADER_PER_PAGE ; + +BUILD_BUG_ON (MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE >PAGE_SHIFT ); +if (hd_per_wqe >=MLX5E_SHAMPO_WQ_HEADER_PER_PAGE ) { + log_hd_per_page =MLX5E_SHAMPO_LOG_WQ_HEADER_PER_PAGE ; + log_hd_entry_size =MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE ; + }else { + log_hd_per_page =order_base_2 (hd_per_wqe); + log_hd_entry_size =order_base_2 (PAGE_SIZE / hd_per_wqe); + } + + rq->mpwqe.shampo->hd_per_wqe = hd_per_wqe; + rq->mpwqe.shampo->hd_per_page =BIT (log_hd_per_page); + rq->mpwqe.shampo->log_hd_per_page = log_hd_per_page; + rq->mpwqe.shampo->log_hd_entry_size = log_hd_entry_size; + + hd_pool_size = (hd_per_wqe * wq_size) >> log_hd_per_page;if (mlx5_rq_needs_separate_hd_pool (rq)) {/* Separate page pool for shampo headers */
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +19 -14
@@ -647,17 +647,20 @@ static void build_ksm_umr(struct mlx5e_icosq *sq, struct mlx5e_umr_wqe *umr_wqe, umr_wqe->hdr.uctrl.mkey_mask =cpu_to_be64 (MLX5_MKEY_MASK_FREE ); } -static struct mlx5e_frag_page *mlx5e_shampo_hd_to_frag_page (struct mlx5e_rq *rq,int header_index) +static struct mlx5e_frag_page *mlx5e_shampo_hd_to_frag_page (struct mlx5e_rq *rq, +int header_index) { -BUILD_BUG_ON (MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE >PAGE_SHIFT ); +struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo; -return &rq->mpwqe.shampo->pages[header_index >>MLX5E_SHAMPO_LOG_WQ_HEADER_PER_PAGE ]; +return &shampo->pages[header_index >> shampo->log_hd_per_page]; } -static u64 mlx5e_shampo_hd_offset (int header_index) +static u64 mlx5e_shampo_hd_offset (struct mlx5e_rq *rq,int header_index) { -return (header_index & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE -1 )) << -MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE ; +struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo; +u32 hd_per_page = shampo->hd_per_page; + +return (header_index & (hd_per_page -1 )) << shampo->log_hd_entry_size; }static void mlx5e_free_rx_shampo_hd_entry (struct mlx5e_rq *rq,u16 header_index);
@@ -683,7 +686,7 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq,u64 addr; frag_page =mlx5e_shampo_hd_to_frag_page (rq, index); - header_offset =mlx5e_shampo_hd_offset (index); + header_offset =mlx5e_shampo_hd_offset (rq, index);if (!header_offset) { err =mlx5e_page_alloc_fragmented (rq->hd_page_pool, frag_page);
@@ -713,7 +716,7 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq, err_unmap:while (--i >=0 ) { --index; - header_offset =mlx5e_shampo_hd_offset (index); + header_offset =mlx5e_shampo_hd_offset (rq, index);if (!header_offset) {struct mlx5e_frag_page *frag_page =mlx5e_shampo_hd_to_frag_page (rq, index);
@@ -737,7 +740,7 @@ static int mlx5e_alloc_rx_hd_mpwqe(struct mlx5e_rq *rq) ksm_entries =bitmap_find_window (shampo->bitmap, shampo->hd_per_wqe, shampo->hd_per_wq, shampo->pi); - ksm_entries =ALIGN_DOWN (ksm_entries,MLX5E_SHAMPO_WQ_HEADER_PER_PAGE ); + ksm_entries =ALIGN_DOWN (ksm_entries, shampo->hd_per_page);if (!ksm_entries)return 0 ;
@@ -855,7 +858,7 @@ mlx5e_free_rx_shampo_hd_entry(struct mlx5e_rq *rq, u16 header_index) {struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo; -if (((header_index +1 ) & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE -1 )) ==0 ) { +if (((header_index +1 ) & (shampo->hd_per_page -1 )) ==0 ) {struct mlx5e_frag_page *frag_page =mlx5e_shampo_hd_to_frag_page (rq, header_index);mlx5e_page_release_fragmented (rq->hd_page_pool, frag_page);
@@ -1218,9 +1221,10 @@ static unsigned int mlx5e_lro_update_hdr(struct sk_buff *skb,static void *mlx5e_shampo_get_packet_hd (struct mlx5e_rq *rq,u16 header_index) {struct mlx5e_frag_page *frag_page =mlx5e_shampo_hd_to_frag_page (rq, header_index); -u16 head_offset =mlx5e_shampo_hd_offset (header_index) + rq->buff.headroom; +u16 head_offset =mlx5e_shampo_hd_offset (rq, header_index); +void *addr =netmem_address (frag_page->netmem); -return netmem_address (frag_page->netmem) + head_offset; +return addr + head_offset + rq->buff.headroom; }static void mlx5e_shampo_update_ipv4_udp_hdr (struct mlx5e_rq *rq,struct iphdr *ipv4)
@@ -2238,7 +2242,8 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi, struct mlx5_cqe64 *cqe, u16 header_index) {struct mlx5e_frag_page *frag_page =mlx5e_shampo_hd_to_frag_page (rq, header_index); -u16 head_offset =mlx5e_shampo_hd_offset (header_index); +u16 head_offset =mlx5e_shampo_hd_offset (rq, header_index); +struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo;u16 head_size = cqe->shampo.header_size;u16 rx_headroom = rq->buff.headroom;struct sk_buff *skb =NULL ;
@@ -2254,7 +2259,7 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi, data = hdr + rx_headroom; frag_size =MLX5_SKB_FRAG_SZ (rx_headroom + head_size); -if (likely (frag_size <=BIT (MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE ))) { +if (likely (frag_size <=BIT (shampo->log_hd_entry_size))) {/* build SKB around header */ dma_sync_single_range_for_cpu (rq->pdev, dma_addr,0 , frag_size, rq->buff.map_dir);net_prefetchw (hdr);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 794/849 net: wan: framer: pef2256: Switch to devm_mfd_add_devices()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 4d6ec3a7932ca5b168426f7b5b40abab2b41d2da ]
The driver calls mfd_add_devices() but fails to call mfd_remove_devices() in error paths after successful MFD device registration and in the remove function. This leads to resource leaks where MFD child devices are not properly unregistered.
Replace mfd_add_devices with devm_mfd_add_devices to automatically manage the device resources.
--- drivers/net/wan/framer/pef2256/pef2256.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/net/wan/framer/pef2256/pef2256.c +4 -3
@@ -637,7 +637,8 @@ static int pef2256_add_audio_devices(struct pef2256 *pef2256) audio_devs[i].id = i; } - ret =mfd_add_devices (pef2256->dev,0 , audio_devs, count,NULL ,0 ,NULL ); + ret =devm_mfd_add_devices (pef2256->dev,0 , audio_devs, count, +NULL ,0 ,NULL );kfree (audio_devs);return ret; }
@@ -812,8 +813,8 @@ static int pef2256_probe(struct platform_device *pdev)platform_set_drvdata (pdev, pef2256); - ret =mfd_add_devices (pef2256->dev,0 , pef2256_devs, -ARRAY_SIZE (pef2256_devs),NULL ,0 ,NULL ); + ret =devm_mfd_add_devices (pef2256->dev,0 , pef2256_devs, +ARRAY_SIZE (pef2256_devs),NULL ,0 ,NULL );if (ret) {dev_err (pef2256->dev,"add devices failed (%d)\n" , ret);return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 795/849 net: dsa: microchip: Fix reserved multicast address table programming
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristram Ha <[email protected]>
[ Upstream commit 96baf482ca1f69f0da9d10a5bd8422c87ea9039e ]
KSZ9477/KSZ9897 and LAN937X families of switches use a reserved multicast address table for some specific forwarding with some multicast addresses, like the one used in STP. The hardware assumes the host port is the last port in KSZ9897 family and port 5 in LAN937X family. Most of the time this assumption is correct but not in other cases like KSZ9477. Originally the function just setups the first entry, but the others still need update, especially for one common multicast address that is used by PTP operation.
LAN937x also uses different register bits when accessing the reserved table.
--- drivers/net/dsa/microchip/ksz9477.c | 98 +++++++++++++++++++++---- drivers/net/dsa/microchip/ksz9477_reg.h | 3 +- drivers/net/dsa/microchip/ksz_common.c | 4 + drivers/net/dsa/microchip/ksz_common.h | 2 + 4 files changed, 91 insertions(+), 16 deletions(-)
drivers/net/dsa/microchip/ksz9477.c +84 -14
@@ -1355,9 +1355,15 @@ void ksz9477_config_cpu_port(struct dsa_switch *ds) } } +#define RESV_MCAST_CNT 8 + +static u8 reserved_mcast_map[RESV_MCAST_CNT ] = {0 ,1 ,3 ,16 ,32 ,33 ,2 ,17 }; +int ksz9477_enable_stp_addr (struct ksz_device *dev) { +u8 i, ports, update;const u32 *masks; +bool override;u32 data;int ret;
@@ -1366,23 +1372,87 @@ int ksz9477_enable_stp_addr(struct ksz_device *dev)/* Enable Reserved multicast table */ ksz_cfg (dev,REG_SW_LUE_CTRL_0 ,SW_RESV_MCAST_ENABLE , true); -/* Set the Override bit for forwarding BPDU packet to CPU */ - ret =ksz_write32 (dev,REG_SW_ALU_VAL_B , -ALU_V_OVERRIDE |BIT (dev->cpu_port)); -if (ret <0 ) -return ret; +/* The reserved multicast address table has 8 entries. Each entry has +* a default value of which port to forward. It is assumed the host +* port is the last port in most of the switches, but that is not the +* case for KSZ9477 or maybe KSZ9897. For LAN937X family the default +* port is port 5, the first RGMII port. It is okay for LAN9370, a +* 5-port switch, but may not be correct for the other 8-port +* versions. It is necessary to update the whole table to forward to +* the right ports. +* Furthermore PTP messages can use a reserved multicast address and +* the host will not receive them if this table is not correct. +*/ +for (i =0 ; i <RESV_MCAST_CNT ; i++) { + data = reserved_mcast_map[i] << + dev->info->shifts[ALU_STAT_INDEX ]; + data |=ALU_STAT_START | + masks[ALU_STAT_DIRECT ] | + masks[ALU_RESV_MCAST_ADDR ] | + masks[ALU_STAT_READ ]; + ret =ksz_write32 (dev,REG_SW_ALU_STAT_CTRL__4 , data); +if (ret <0 ) +return ret; - data =ALU_STAT_START |ALU_RESV_MCAST_ADDR | masks[ALU_STAT_WRITE ]; +/* wait to be finished */ + ret =ksz9477_wait_alu_sta_ready (dev); +if (ret <0 ) +return ret; - ret =ksz_write32 (dev,REG_SW_ALU_STAT_CTRL__4 , data); -if (ret <0 ) -return ret; + ret =ksz_read32 (dev,REG_SW_ALU_VAL_B , &data); +if (ret <0 ) +return ret; -/* wait to be finished */ - ret =ksz9477_wait_alu_sta_ready (dev); -if (ret <0 ) { -dev_err (dev->dev,"Failed to update Reserved Multicast table\n" ); -return ret; + override = false; + ports = data & dev->port_mask; +switch (i) { +case 0 : +case 6 : +/* Change the host port. */ + update =BIT (dev->cpu_port); + override = true; +break ; +case 2 : +/* Change the host port. */ + update =BIT (dev->cpu_port); +break ; +case 4 : +case 5 : +case 7 : +/* Skip the host port. */ + update = dev->port_mask & ~BIT (dev->cpu_port); +break ; +default : + update = ports; +break ; + } +if (update != ports || override) { + data &= ~dev->port_mask; + data |= update; +/* Set Override bit to receive frame even when port is +* closed. +*/ +if (override) + data |=ALU_V_OVERRIDE ; + ret =ksz_write32 (dev,REG_SW_ALU_VAL_B , data); +if (ret <0 ) +return ret; + + data = reserved_mcast_map[i] << + dev->info->shifts[ALU_STAT_INDEX ]; + data |=ALU_STAT_START | + masks[ALU_STAT_DIRECT ] | + masks[ALU_RESV_MCAST_ADDR ] | + masks[ALU_STAT_WRITE ]; + ret =ksz_write32 (dev,REG_SW_ALU_STAT_CTRL__4 , data); +if (ret <0 ) +return ret; + +/* wait to be finished */ + ret =ksz9477_wait_alu_sta_ready (dev); +if (ret <0 ) +return ret; + } }return 0 ;
drivers/net/dsa/microchip/ksz9477_reg.h +1 -2
@@ -2,7 +2,7 @@/* * Microchip KSZ9477 register definitions * -* Copyright (C) 2017-2024 Microchip Technology Inc. +* Copyright (C) 2017-2025 Microchip Technology Inc. */ #ifndef __KSZ9477_REGS_H
@@ -397,7 +397,6 @@#define ALU_RESV_MCAST_INDEX_M (BIT(6) - 1)#define ALU_STAT_START BIT(7) -#define ALU_RESV_MCAST_ADDR BIT(1)#define REG_SW_ALU_VAL_A 0x0420
drivers/net/dsa/microchip/ksz_common.c +4 -0
@@ -808,6 +808,8 @@ static const u16 ksz9477_regs[] = {static const u32 ksz9477_masks[] = { [ALU_STAT_WRITE ] =0 , [ALU_STAT_READ ] =1 , + [ALU_STAT_DIRECT ] =0 , + [ALU_RESV_MCAST_ADDR ] =BIT (1 ), [P_MII_TX_FLOW_CTRL ] =BIT (5 ), [P_MII_RX_FLOW_CTRL ] =BIT (3 ), };
@@ -835,6 +837,8 @@ static const u8 ksz9477_xmii_ctrl1[] = {static const u32 lan937x_masks[] = { [ALU_STAT_WRITE ] =1 , [ALU_STAT_READ ] =2 , + [ALU_STAT_DIRECT ] =BIT (3 ), + [ALU_RESV_MCAST_ADDR ] =BIT (2 ), [P_MII_TX_FLOW_CTRL ] =BIT (5 ), [P_MII_RX_FLOW_CTRL ] =BIT (3 ), };
drivers/net/dsa/microchip/ksz_common.h +2 -0
@@ -294,6 +294,8 @@ enum ksz_masks {DYNAMIC_MAC_TABLE_TIMESTAMP ,ALU_STAT_WRITE ,ALU_STAT_READ , +ALU_STAT_DIRECT , +ALU_RESV_MCAST_ADDR ,P_MII_TX_FLOW_CTRL , P_MII_RX_FLOW_CTRL, };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 796/849 lan966x: Fix sleeping in atomic context
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Horatiu Vultur <[email protected]>
[ Upstream commit 0216721ce71252f60d89af49c8dff613358058d3 ]
The following warning was seen when we try to connect using ssh to the device.
BUG: sleeping function called from invalid context at kernel/locking/mutex.c:575 in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 104, name: dropbear preempt_count: 1, expected: 0 INFO: lockdep is turned off. CPU: 0 UID: 0 PID: 104 Comm: dropbear Tainted: G W 6.18.0-rc2-00399-g6f1ab1b109b9-dirty #530 NONE Tainted: [W]=WARN Hardware name: Generic DT based system Call trace: unwind_backtrace from show_stack+0x10/0x14 show_stack from dump_stack_lvl+0x7c/0xac dump_stack_lvl from __might_resched+0x16c/0x2b0 __might_resched from __mutex_lock+0x64/0xd34 __mutex_lock from mutex_lock_nested+0x1c/0x24 mutex_lock_nested from lan966x_stats_get+0x5c/0x558 lan966x_stats_get from dev_get_stats+0x40/0x43c dev_get_stats from dev_seq_printf_stats+0x3c/0x184 dev_seq_printf_stats from dev_seq_show+0x10/0x30 dev_seq_show from seq_read_iter+0x350/0x4ec seq_read_iter from seq_read+0xfc/0x194 seq_read from proc_reg_read+0xac/0x100 proc_reg_read from vfs_read+0xb0/0x2b0 vfs_read from ksys_read+0x6c/0xec ksys_read from ret_fast_syscall+0x0/0x1c Exception stack(0xf0b11fa8 to 0xf0b11ff0)
1fa0: 00000001 00001000 00000008 be9048d8 00001000 00000001
1fc0: 00000001 00001000 00000008 00000003 be905920 0000001e 00000000 00000001 1fe0: 0005404c be9048c0 00018684 b6ec2cd8
It seems that we are using a mutex in a atomic context which is wrong. Change the mutex with a spinlock.
--- .../microchip/lan966x/lan966x_ethtool.c | 18 +++++++++--------- .../ethernet/microchip/lan966x/lan966x_main.c | 2 -- .../ethernet/microchip/lan966x/lan966x_main.h | 4 ++-- .../microchip/lan966x/lan966x_vcap_impl.c | 8 ++++---- 4 files changed, 15 insertions(+), 17 deletions(-)
drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c +9 -9
@@ -294,7 +294,7 @@ static void lan966x_stats_update(struct lan966x *lan966x) {int i, j; -mutex_lock (&lan966x->stats_lock); +spin_lock (&lan966x->stats_lock);for (i =0 ; i < lan966x->num_phys_ports; i++) {uint idx = i * lan966x->num_stats;
@@ -310,7 +310,7 @@ static void lan966x_stats_update(struct lan966x *lan966x) } } -mutex_unlock (&lan966x->stats_lock); +spin_unlock (&lan966x->stats_lock); }static int lan966x_get_sset_count (struct net_device *dev,int sset)
@@ -365,7 +365,7 @@ static void lan966x_get_eth_mac_stats(struct net_device *dev, idx = port->chip_port * lan966x->num_stats; -mutex_lock (&lan966x->stats_lock); +spin_lock (&lan966x->stats_lock); mac_stats->FramesTransmittedOK = lan966x->stats[idx + SYS_COUNT_TX_UC] +
@@ -416,7 +416,7 @@ static void lan966x_get_eth_mac_stats(struct net_device *dev, lan966x->stats[idx +SYS_COUNT_RX_LONG ] + lan966x->stats[idx +SYS_COUNT_RX_PMAC_LONG ]; -mutex_unlock (&lan966x->stats_lock); +spin_unlock (&lan966x->stats_lock); }static const struct ethtool_rmon_hist_range lan966x_rmon_ranges[] = {
@@ -442,7 +442,7 @@ static void lan966x_get_eth_rmon_stats(struct net_device *dev, idx = port->chip_port * lan966x->num_stats; -mutex_lock (&lan966x->stats_lock); +spin_lock (&lan966x->stats_lock); rmon_stats->undersize_pkts = lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
@@ -500,7 +500,7 @@ static void lan966x_get_eth_rmon_stats(struct net_device *dev, lan966x->stats[idx +SYS_COUNT_TX_SZ_1024_1526 ] + lan966x->stats[idx +SYS_COUNT_TX_PMAC_SZ_1024_1526 ]; -mutex_unlock (&lan966x->stats_lock); +spin_unlock (&lan966x->stats_lock); *ranges = lan966x_rmon_ranges; }
@@ -603,7 +603,7 @@ void lan966x_stats_get(struct net_device *dev, idx = port->chip_port * lan966x->num_stats; -mutex_lock (&lan966x->stats_lock); +spin_lock (&lan966x->stats_lock); stats->rx_bytes = lan966x->stats[idx +SYS_COUNT_RX_OCT ] + lan966x->stats[idx +SYS_COUNT_RX_PMAC_OCT ];
@@ -685,7 +685,7 @@ void lan966x_stats_get(struct net_device *dev, stats->collisions = lan966x->stats[idx +SYS_COUNT_TX_COL ]; -mutex_unlock (&lan966x->stats_lock); +spin_unlock (&lan966x->stats_lock); }int lan966x_stats_init (struct lan966x *lan966x)
@@ -701,7 +701,7 @@ int lan966x_stats_init(struct lan966x *lan966x)return -ENOMEM ;/* Init stats worker */ -mutex_init (&lan966x->stats_lock); +spin_lock_init (&lan966x->stats_lock);snprintf (queue_name,sizeof (queue_name),"%s-stats" ,dev_name (lan966x->dev)); lan966x->stats_queue =create_singlethread_workqueue (queue_name);
drivers/net/ethernet/microchip/lan966x/lan966x_main.c +0 -2
@@ -1261,7 +1261,6 @@ static int lan966x_probe(struct platform_device *pdev)cancel_delayed_work_sync (&lan966x->stats_work);destroy_workqueue (lan966x->stats_queue); -mutex_destroy (&lan966x->stats_lock);debugfs_remove_recursive (lan966x->debugfs_root);
@@ -1279,7 +1278,6 @@ static void lan966x_remove(struct platform_device *pdev)cancel_delayed_work_sync (&lan966x->stats_work);destroy_workqueue (lan966x->stats_queue); -mutex_destroy (&lan966x->stats_lock);lan966x_mac_purge_entries (lan966x);lan966x_mdb_deinit (lan966x);
drivers/net/ethernet/microchip/lan966x/lan966x_main.h +2 -2
@@ -295,8 +295,8 @@ struct lan966x {const struct lan966x_stat_layout *stats_layout;u32 num_stats; -/* workqueue for reading stats */ -struct mutex stats_lock; +/* lock for reading stats */ +spinlock_t stats_lock;u64 *stats;struct delayed_work stats_work;struct workqueue_struct *stats_queue;
drivers/net/ethernet/microchip/lan966x/lan966x_vcap_impl.c +4 -4
@@ -403,11 +403,11 @@ static void lan966x_es0_read_esdx_counter(struct lan966x *lan966x,u32 counter; id = id &0xff ;/* counter limit */ -mutex_lock (&lan966x->stats_lock); +spin_lock (&lan966x->stats_lock);lan_wr (SYS_STAT_CFG_STAT_VIEW_SET (id), lan966x,SYS_STAT_CFG ); counter =lan_rd (lan966x,SYS_CNT (LAN966X_STAT_ESDX_GRN_PKTS )) +lan_rd (lan966x,SYS_CNT (LAN966X_STAT_ESDX_YEL_PKTS )); -mutex_unlock (&lan966x->stats_lock); +spin_unlock (&lan966x->stats_lock);if (counter) admin->cache.counter = counter; }
@@ -417,14 +417,14 @@ static void lan966x_es0_write_esdx_counter(struct lan966x *lan966x, { id = id &0xff ;/* counter limit */ -mutex_lock (&lan966x->stats_lock); +spin_lock (&lan966x->stats_lock);lan_wr (SYS_STAT_CFG_STAT_VIEW_SET (id), lan966x,SYS_STAT_CFG );lan_wr (0 , lan966x,SYS_CNT (LAN966X_STAT_ESDX_GRN_BYTES ));lan_wr (admin->cache.counter, lan966x,SYS_CNT (LAN966X_STAT_ESDX_GRN_PKTS ));lan_wr (0 , lan966x,SYS_CNT (LAN966X_STAT_ESDX_YEL_BYTES ));lan_wr (0 , lan966x,SYS_CNT (LAN966X_STAT_ESDX_YEL_PKTS )); -mutex_unlock (&lan966x->stats_lock); +spin_unlock (&lan966x->stats_lock); } static void lan966x_vcap_cache_write(struct net_device *dev,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 797/849 net: bridge: fix use-after-free due to MST port state bypass
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <[email protected]>
[ Upstream commit 8dca36978aa80bab9d4da130c211db75c9e00048 ]
syzbot reported[1] a use-after-free when deleting an expired fdb. It is due to a race condition between learning still happening and a port being deleted, after all its fdbs have been flushed. The port's state has been toggled to disabled so no learning should happen at that time, but if we have MST enabled, it will bypass the port's state, that together with VLAN filtering disabled can lead to fdb learning at a time when it shouldn't happen while the port is being deleted. VLAN filtering must be disabled because we flush the port VLANs when it's being deleted which will stop learning. This fix adds a check for the port's vlan group which is initialized to NULL when the port is getting deleted, that avoids the port state bypass. When MST is enabled there would be a minimal new overhead in the fast-path because the port's vlan group pointer is cache-hot.
[1] https://syzkaller.appspot.com/bug?extid=dd280197f0f7ab3917be
--- net/bridge/br_forward.c | 2 +- net/bridge/br_input.c | 4 ++-- net/bridge/br_private.h | 8 +++++--- 3 files changed, 8 insertions(+), 6 deletions(-)
net/bridge/br_forward.c +1 -1
@@ -25,7 +25,7 @@ static inline int should_deliver(const struct net_bridge_port *p, vg =nbp_vlan_group_rcu (p);return ((p->flags &BR_HAIRPIN_MODE ) || skb->dev != p->dev) && - (br_mst_is_enabled (p->br) || p->state ==BR_STATE_FORWARDING ) && + (br_mst_is_enabled (p) || p->state ==BR_STATE_FORWARDING ) &&br_allowed_egress (vg, skb) &&nbp_switchdev_allowed_egress (p, skb) && !br_skb_isolated (p, skb); }
net/bridge/br_input.c +2 -2
@@ -94,7 +94,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb br = p->br; -if (br_mst_is_enabled (br)) { +if (br_mst_is_enabled (p)) { state =BR_STATE_FORWARDING ; }else {if (p->state ==BR_STATE_DISABLED ) {
@@ -421,7 +421,7 @@ static rx_handler_result_t br_handle_frame(struct sk_buff **pskb)return RX_HANDLER_PASS ; forward: -if (br_mst_is_enabled (p->br)) +if (br_mst_is_enabled (p)) goto defer_stp_filtering;switch (p->state) {
net/bridge/br_private.h +5 -3
@@ -1932,10 +1932,12 @@ static inline bool br_vlan_state_allowed(u8 state, bool learn_allow)/* br_mst.c */ #ifdef CONFIG_BRIDGE_VLAN_FILTERING DECLARE_STATIC_KEY_FALSE (br_mst_used); -static inline bool br_mst_is_enabled (struct net_bridge *br) +static inline bool br_mst_is_enabled (const struct net_bridge_port *p) { +/* check the port's vlan group to avoid racing with port deletion */ return static_branch_unlikely (&br_mst_used) && -br_opt_get (br,BROPT_MST_ENABLED ); +br_opt_get (p->br,BROPT_MST_ENABLED ) && +rcu_access_pointer (p->vlgrp); } int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state,
@@ -1950,7 +1952,7 @@ int br_mst_fill_info(struct sk_buff *skb,int br_mst_process (struct net_bridge_port *p,const struct nlattr *mst_attr,struct netlink_ext_ack *extack);#else -static inline bool br_mst_is_enabled (struct net_bridge *br) +static inline bool br_mst_is_enabled (const struct net_bridge_port *p) {return false; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 798/849 net: bridge: fix MST static key usage
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <[email protected]>
[ Upstream commit ee87c63f9b2a418f698d79c2991347e31a7d2c27 ]
As Ido pointed out, the static key usage in MST is buggy and should use inc/dec instead of enable/disable because we can have multiple bridges with MST enabled which means a single bridge can disable MST for all. Use static_branch_inc/dec to avoid that. When destroying a bridge decrement the key if MST was enabled.
--- net/bridge/br_if.c | 1 + net/bridge/br_mst.c | 10 ++++++++-- net/bridge/br_private.h | 5 +++++ 3 files changed, 14 insertions(+), 2 deletions(-)
net/bridge/br_if.c +1 -0
@@ -386,6 +386,7 @@ void br_dev_delete(struct net_device *dev, struct list_head *head)del_nbp (p); } +br_mst_uninit (br);br_recalculate_neigh_suppress_enabled (br);br_fdb_delete_by_port (br,NULL ,0 ,1 );
net/bridge/br_mst.c +8 -2
@@ -22,6 +22,12 @@ bool br_mst_enabled(const struct net_device *dev) }EXPORT_SYMBOL_GPL (br_mst_enabled); +void br_mst_uninit (struct net_bridge *br) +{ +if (br_opt_get (br,BROPT_MST_ENABLED )) +static_branch_dec (&br_mst_used); +} +int br_mst_get_info (const struct net_device *dev,u16 msti,unsigned long *vids) {const struct net_bridge_vlan_group *vg;
@@ -225,9 +231,9 @@ int br_mst_set_enabled(struct net_bridge *br, bool on,return err;if (on) -static_branch_enable (&br_mst_used); +static_branch_inc (&br_mst_used);else -static_branch_disable (&br_mst_used); +static_branch_dec (&br_mst_used);br_opt_toggle (br,BROPT_MST_ENABLED , on);return 0 ;
net/bridge/br_private.h +5 -0
@@ -1951,6 +1951,7 @@ int br_mst_fill_info(struct sk_buff *skb, const struct net_bridge_vlan_group *vg);int br_mst_process (struct net_bridge_port *p,const struct nlattr *mst_attr,struct netlink_ext_ack *extack); +void br_mst_uninit (struct net_bridge *br);#else static inline bool br_mst_is_enabled (const struct net_bridge_port *p) {
@@ -1986,6 +1987,10 @@ static inline int br_mst_process(struct net_bridge_port *p, {return -EOPNOTSUPP ; } + +static inline void br_mst_uninit (struct net_bridge *br) +{ +}#endif struct nf_br_ops {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 799/849 selftests/vsock: avoid false-positives when checking dmesg
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bobby Eshleman <[email protected]>
[ Upstream commit 3534e03e0ec2e00908765549828a69df5ebefb91 ]
Sometimes VMs will have some intermittent dmesg warnings that are unrelated to vsock. Change the dmesg parsing to filter on strings containing 'vsock' to avoid false positive failures that are unrelated to vsock. The downside is that it is possible for some vsock related warnings to not contain the substring 'vsock', so those will be missed.
--- tools/testing/selftests/vsock/vmtest.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
tools/testing/selftests/vsock/vmtest.sh +4 -4
@@ -389,9 +389,9 @@ run_test() { local rc host_oops_cnt_before=$(dmesg | grep -c -i 'Oops') - host_warn_cnt_before=$(dmesg --level=warn | wc -l) + host_warn_cnt_before=$(dmesg --level=warn | grep -c -i 'vsock') vm_oops_cnt_before=$(vm_ssh -- dmesg | grep -c -i 'Oops') - vm_warn_cnt_before=$(vm_ssh -- dmesg --level=warn | wc -l) + vm_warn_cnt_before=$(vm_ssh -- dmesg --level=warn | grep -c -i 'vsock') name=$(echo "${1}" | awk '{ print $1 }') eval test_"${name}"
@@ -403,7 +403,7 @@ run_test() { rc=$KSFT_FAIL fi - host_warn_cnt_after=$(dmesg --level=warn | wc -l) + host_warn_cnt_after=$(dmesg --level=warn | grep -c -i 'vsock') if [[ ${host_warn_cnt_after} -gt ${host_warn_cnt_before} ]]; then echo "FAIL: kernel warning detected on host" | log_host "${name}" rc=$KSFT_FAIL
@@ -415,7 +415,7 @@ run_test() { rc=$KSFT_FAIL fi - vm_warn_cnt_after=$(vm_ssh -- dmesg --level=warn | wc -l) + vm_warn_cnt_after=$(vm_ssh -- dmesg --level=warn | grep -c -i 'vsock') if [[ ${vm_warn_cnt_after} -gt ${vm_warn_cnt_before} ]]; then echo "FAIL: kernel warning detected on vm" | log_host "${name}" rc=$KSFT_FAIL
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 800/849 tracing: Fix memory leaks in create_field_var()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zilin Guan <[email protected]>
[ Upstream commit 80f0d631dcc76ee1b7755bfca1d8417d91d71414 ]
The function create_field_var() allocates memory for 'val' through create_hist_field() inside parse_atom(), and for 'var' through create_var(), which in turn allocates var->type and var->var.name internally. Simply calling kfree() to release these structures will result in memory leaks.
Use destroy_hist_field() to properly free 'val', and explicitly release the memory of var->type and var->var.name before freeing 'var' itself.
--- kernel/trace/trace_events_hist.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
kernel/trace/trace_events_hist.c +4 -2
@@ -3272,14 +3272,16 @@ static struct field_var *create_field_var(struct hist_trigger_data *hist_data, var =create_var (hist_data, file, field_name, val->size, val->type);if (IS_ERR (var)) {hist_err (tr,HIST_ERR_VAR_CREATE_FIND_FAIL ,errpos (field_name)); -kfree (val); +destroy_hist_field (val,0 ); ret =PTR_ERR (var); goto err; } field_var =kzalloc (sizeof (struct field_var ),GFP_KERNEL );if (!field_var) { -kfree (val); +destroy_hist_field (val,0 ); +kfree_const (var->type); +kfree (var->var.name);kfree (var); ret = -ENOMEM ; goto err;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 801/849 drm/amd/display: Enable mst when its detected but yet to be initialized
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wayne Lin <[email protected]>
commit 3c6a743c6961cc2cab453b343bb157d6bbbf8120 upstream.
[Why]drm_dp_mst_topology_queue_probe() is used under the assumption that mst is already initialized. If we connect system with SST first then switch to the mst branch during suspend, we will fail probing topology by calling the wrong API since the mst manager is yet to be initialized.
[How]
At dm_resume(), once it's detected as mst branc connected, check if the mst is initialized already. If not, call dm_helpers_dp_mst_start_top_mgr() instead to initialize mst
V2: Adjust the commit msg a bit
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +9 -1
@@ -3574,6 +3574,7 @@ static int dm_resume(struct amdgpu_ip_bl/* Do mst topology probing after resuming cached state*/ drm_connector_list_iter_begin (ddev, &iter);drm_for_each_connector_iter (connector, &iter) { +bool init = false;if (connector->connector_type ==DRM_MODE_CONNECTOR_WRITEBACK )continue ;
@@ -3583,7 +3584,14 @@ static int dm_resume(struct amdgpu_ip_bl aconnector->mst_root) continue; -drm_dp_mst_topology_queue_probe (&aconnector->mst_mgr); + scoped_guard(mutex, &aconnector->mst_mgr.lock) { + init = !aconnector->mst_mgr.mst_primary; + } +if (init) +dm_helpers_dp_mst_start_top_mgr (aconnector->dc_link->ctx, + aconnector->dc_link, false); +else +drm_dp_mst_topology_queue_probe (&aconnector->mst_mgr); }drm_connector_list_iter_end (&iter);
Greg Kroah-Hartman
maintainerPATCH 802/849 wifi: cfg80211: add an hrtimer based delayed work item
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Berg <[email protected]>
commit 7ceba45a6658ce637da334cd0ebf27f4ede6c0fe upstream.
The normal timer mechanism assume that timeout further in the future need a lower accuracy. As an example, the granularity for a timer scheduled 4096 ms in the future on a 1000 Hz system is already 512 ms. This granularity is perfectly sufficient for e.g. timeouts, but there are other types of events that will happen at a future point in time and require a higher accuracy.
Add a new wiphy_hrtimer_work type that uses an hrtimer internally. The API is almost identical to the existing wiphy_delayed_work and it can be used as a drop-in replacement after minor adjustments. The work will be scheduled relative to the current time with a slack of 1 millisecond.
--- include/net/cfg80211.h | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ net/wireless/core.c | 56 +++++++++++++++++++++++++++++++++++ net/wireless/trace.h | 21 +++++++++++++ 3 files changed, 155 insertions(+)
include/net/cfg80211.h +78 -0
@@ -6289,6 +6289,11 @@ static inline void wiphy_delayed_work_in* after wiphy_lock() was called. Therefore, wiphy_cancel_work() can * use just cancel_work() instead of cancel_work_sync(), it requires * being in a section protected by wiphy_lock(). +* +* Note that these are scheduled with a timer where the accuracy +* becomes less the longer in the future the scheduled timer is. Use +* wiphy_hrtimer_work_queue() if the timer must be not be late by more +* than approximately 10 percent. */ void wiphy_delayed_work_queue(struct wiphy *wiphy, struct wiphy_delayed_work *dwork,
@@ -6360,6 +6365,79 @@ void wiphy_delayed_work_flush(struct wipbool wiphy_delayed_work_pending (struct wiphy *wiphy,struct wiphy_delayed_work *dwork); +struct wiphy_hrtimer_work { +struct wiphy_work work; +struct wiphy *wiphy; +struct hrtimer timer; +}; + +enum hrtimer_restart wiphy_hrtimer_work_timer (struct hrtimer *t); + +static inline void wiphy_hrtimer_work_init (struct wiphy_hrtimer_work *hrwork, +wiphy_work_func_t func) +{ +hrtimer_setup (&hrwork->timer, wiphy_hrtimer_work_timer, +CLOCK_BOOTTIME ,HRTIMER_MODE_REL ); +wiphy_work_init (&hrwork->work, func); +} + +/** +* wiphy_hrtimer_work_queue - queue hrtimer work for the wiphy +* @wiphy: the wiphy to queue for +* @hrwork: the high resolution timer worker +* @delay: the delay given as a ktime_t +* +* Please refer to wiphy_delayed_work_queue(). The difference is that +* the hrtimer work uses a high resolution timer for scheduling. This +* may be needed if timeouts might be scheduled further in the future +* and the accuracy of the normal timer is not sufficient. +* +* Expect a delay of a few milliseconds as the timer is scheduled +* with some slack and some more time may pass between queueing the +* work and its start. +*/ +void wiphy_hrtimer_work_queue (struct wiphy *wiphy, +struct wiphy_hrtimer_work *hrwork, +ktime_t delay); + +/** +* wiphy_hrtimer_work_cancel - cancel previously queued hrtimer work +* @wiphy: the wiphy, for debug purposes +* @hrtimer: the hrtimer work to cancel +* +* Cancel the work *without* waiting for it, this assumes being +* called under the wiphy mutex acquired by wiphy_lock(). +*/ +void wiphy_hrtimer_work_cancel (struct wiphy *wiphy, +struct wiphy_hrtimer_work *hrtimer); + +/** +* wiphy_hrtimer_work_flush - flush previously queued hrtimer work +* @wiphy: the wiphy, for debug purposes +* @hrwork: the hrtimer work to flush +* +* Flush the work (i.e. run it if pending). This must be called +* under the wiphy mutex acquired by wiphy_lock(). +*/ +void wiphy_hrtimer_work_flush (struct wiphy *wiphy, +struct wiphy_hrtimer_work *hrwork); + +/** +* wiphy_hrtimer_work_pending - Find out whether a wiphy hrtimer +* work item is currently pending. +* +* @wiphy: the wiphy, for debug purposes +* @hrwork: the hrtimer work in question +* +* Return: true if timer is pending, false otherwise +* +* Please refer to the wiphy_delayed_work_pending() documentation as +* this is the equivalent function for hrtimer based delayed work +* items. +*/ +bool wiphy_hrtimer_work_pending (struct wiphy *wiphy, +struct wiphy_hrtimer_work *hrwork); +/** * enum ieee80211_ap_reg_power - regulatory power for an Access Point *
net/wireless/core.c +56 -0
62 lines not on this page · raw message
net/wireless/trace.h +21 -0
@@ -304,6 +304,27 @@ TRACE_EVENT(wiphy_delayed_work_queue, __entry->delay) ); +TRACE_EVENT (wiphy_hrtimer_work_queue, + TP_PROTO(struct wiphy *wiphy, struct wiphy_work *work, + ktime_t delay), +TP_ARGS (wiphy, work, delay), +TP_STRUCT__entry ( + WIPHY_ENTRY + __field(void *, instance) + __field(void *, func) +__field (ktime_t, delay) + ), +TP_fast_assign ( + WIPHY_ASSIGN; + __entry->instance = work; + __entry->func = work->func; + __entry->delay = delay; + ), +TP_printk (WIPHY_PR_FMT " instance=%p func=%pS delay=%llu" , +WIPHY_PR_ARG , __entry->instance, __entry->func, + __entry->delay) +); + TRACE_EVENT(wiphy_work_worker_start, TP_PROTO(struct wiphy *wiphy), TP_ARGS(wiphy),
Greg Kroah-Hartman
maintainerPATCH 803/849 wifi: mac80211: use wiphy_hrtimer_work for ml_reconf_work
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Berg <[email protected]>
commit 3f654d53dff565095d83a84e3b6187526dadf4c8 upstream.
The work item may be scheduled relatively far in the future. As the event happens at a specific point in time, the normal timer accuracy is not sufficient in that case.
Switch to use wiphy_hrtimer_work so that the accuracy is sufficient.
--- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/mlme.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-)
net/mac80211/ieee80211_i.h +1 -1
@@ -604,7 +604,7 @@ struct ieee80211_if_managed {u8 *assoc_req_ies;size_t assoc_req_ies_len; -struct wiphy_delayed_work ml_reconf_work; +struct wiphy_hrtimer_work ml_reconf_work;u16 removed_links;/* TID-to-link mapping support */
net/mac80211/mlme.c +5 -5
@@ -4244,7 +4244,7 @@ static void ieee80211_set_disassoc(struc &ifmgd->neg_ttlm_timeout_work); sdata->u.mgd.removed_links =0 ; -wiphy_delayed_work_cancel (sdata->local->hw.wiphy, +wiphy_hrtimer_work_cancel (sdata->local->hw.wiphy, &sdata->u.mgd.ml_reconf_work); wiphy_work_cancel(sdata->local->hw.wiphy,
@@ -6868,7 +6868,7 @@ static void ieee80211_ml_reconfiguration/* In case the removal was cancelled, abort it */ if (sdata->u.mgd.removed_links) { sdata->u.mgd.removed_links =0 ; -wiphy_delayed_work_cancel (sdata->local->hw.wiphy, +wiphy_hrtimer_work_cancel (sdata->local->hw.wiphy, &sdata->u.mgd.ml_reconf_work); }return ;
@@ -6898,9 +6898,9 @@ static void ieee80211_ml_reconfiguration } sdata->u.mgd.removed_links = removed_links; -wiphy_delayed_work_queue (sdata->local->hw.wiphy, +wiphy_hrtimer_work_queue (sdata->local->hw.wiphy, &sdata->u.mgd.ml_reconf_work, -TU_TO_JIFFIES (delay)); +us_to_ktime (ieee80211_tu_to_usec (delay))); } static int ieee80211_ttlm_set_links(struct ieee80211_sub_if_data *sdata,
@@ -8752,7 +8752,7 @@ void ieee80211_sta_setup_sdata(struct ie ieee80211_csa_connection_drop_work);wiphy_delayed_work_init (&ifmgd->tdls_peer_del_work, ieee80211_tdls_peer_del_work); -wiphy_delayed_work_init (&ifmgd->ml_reconf_work, +wiphy_hrtimer_work_init (&ifmgd->ml_reconf_work, ieee80211_ml_reconf_work);wiphy_delayed_work_init (&ifmgd->reconf.wk, ieee80211_ml_sta_reconf_timeout);
Greg Kroah-Hartman
maintainerPATCH 804/849 platform/x86: int3472: Fix double free of GPIO device during unregister
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiu Wenbo <[email protected]>
commit f0f7a3f542c1698edb69075f25a3f846207facba upstream.
regulator_unregister() already frees the associated GPIO device. On ThinkPad X9 (Lunar Lake), this causes a double free issue that leads to random failures when other drivers (typically Intel THC) attempt to allocate interrupts. The root cause is that the reference count of the pinctrl_intel_platform module unexpectedly drops to zero when this driver defers its probe.
This behavior can also be reproduced by unloading the module directly.
Fix the issue by removing the redundant release of the GPIO device during regulator unregistration.
--- drivers/platform/x86/intel/int3472/clk_and_regulator.c | 5 +---- include/linux/platform_data/x86/int3472.h | 1 - 2 files changed, 1 insertion(+), 5 deletions(-)
drivers/platform/x86/intel/int3472/clk_and_regulator.c +1 -4
@@ -245,15 +245,12 @@ int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,if (IS_ERR (regulator->rdev))return PTR_ERR (regulator->rdev); - int3472->regulators[int3472->n_regulator_gpios].ena_gpio = gpio; int3472->n_regulator_gpios++;return 0 ; }void skl_int3472_unregister_regulator (struct int3472_discrete_device *int3472) { -for (int i =0 ; i < int3472->n_regulator_gpios; i++) { +for (int i =0 ; i < int3472->n_regulator_gpios; i++)regulator_unregister (int3472->regulators[i].rdev); -gpiod_put (int3472->regulators[i].ena_gpio); - } }
include/linux/platform_data/x86/int3472.h +0 -1
@@ -100,7 +100,6 @@ struct int3472_gpio_regulator {struct regulator_consumer_supply supply_map[GPIO_REGULATOR_SUPPLY_MAP_COUNT *2 ];char supply_name_upper[GPIO_SUPPLY_NAME_LENGTH ];char regulator_name[GPIO_REGULATOR_NAME_LENGTH ]; -struct gpio_desc *ena_gpio;struct regulator_dev *rdev;struct regulator_desc rdesc; };
Signature · 1 line
2.51.2
Greg Kroah-Hartman
maintainerPATCH 805/849 wifi: mac80211: use wiphy_hrtimer_work for ttlm_work
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Berg <[email protected]>
commit dfa865d490b1bd252045463588a91a4d3c82f3c8 upstream.
The work item may be scheduled relatively far in the future. As the event happens at a specific point in time, the normal timer accuracy is not sufficient in that case.
Switch to use wiphy_hrtimer_work so that the accuracy is sufficient.
--- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/mlme.c | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-)
net/mac80211/ieee80211_i.h +1 -1
@@ -608,7 +608,7 @@ struct ieee80211_if_managed {u16 removed_links;/* TID-to-link mapping support */ -struct wiphy_delayed_work ttlm_work; +struct wiphy_hrtimer_work ttlm_work;struct ieee80211_adv_ttlm_info ttlm_info;struct wiphy_work teardown_ttlm_work;
net/mac80211/mlme.c +12 -12
@@ -45,7 +45,7 @@#define IEEE80211_ASSOC_TIMEOUT_SHORT (HZ / 10)#define IEEE80211_ASSOC_MAX_TRIES 3 -#define IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS msecs_to_jiffies(100) +#define IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS (100 * USEC_PER_MSEC)#define IEEE80211_ADV_TTLM_ST_UNDERFLOW 0xff00#define IEEE80211_NEG_TTLM_REQ_TIMEOUT (HZ / 5)
@@ -4237,7 +4237,7 @@ static void ieee80211_set_disassoc(strucmemset (&sdata->u.mgd.ttlm_info,0 ,sizeof (sdata->u.mgd.ttlm_info)); -wiphy_delayed_work_cancel (sdata->local->hw.wiphy, &ifmgd->ttlm_work); +wiphy_hrtimer_work_cancel (sdata->local->hw.wiphy, &ifmgd->ttlm_work);memset (&sdata->vif.neg_ttlm,0 ,sizeof (sdata->vif.neg_ttlm)); wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
@@ -7087,7 +7087,7 @@ static void ieee80211_process_adv_ttlm(s/* if a planned TID-to-link mapping was cancelled - * abort it */ -wiphy_delayed_work_cancel (sdata->local->hw.wiphy, +wiphy_hrtimer_work_cancel (sdata->local->hw.wiphy, &sdata->u.mgd.ttlm_work); }else if (sdata->u.mgd.ttlm_info.active) {/* if no TID-to-link element, set to default mapping in
@@ -7122,7 +7122,7 @@ static void ieee80211_process_adv_ttlm(sif (ttlm_info.switch_time) {u16 beacon_ts_tu, st_tu, delay; -u32 delay_jiffies; +u64 delay_usec;u64 mask;/* The t2l map switch time is indicated with a partial
@@ -7144,23 +7144,23 @@ static void ieee80211_process_adv_ttlm(sif (delay >IEEE80211_ADV_TTLM_ST_UNDERFLOW )return ; - delay_jiffies =TU_TO_JIFFIES (delay); + delay_usec =ieee80211_tu_to_usec (delay);/* Link switching can take time, so schedule it * 100ms before to be ready on time */ -if (delay_jiffies >IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS ) - delay_jiffies -= +if (delay_usec >IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS ) + delay_usec -=IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS ;else - delay_jiffies =0 ; + delay_usec =0 ; sdata->u.mgd.ttlm_info = ttlm_info; -wiphy_delayed_work_cancel (sdata->local->hw.wiphy, +wiphy_hrtimer_work_cancel (sdata->local->hw.wiphy, &sdata->u.mgd.ttlm_work); -wiphy_delayed_work_queue (sdata->local->hw.wiphy, +wiphy_hrtimer_work_queue (sdata->local->hw.wiphy, &sdata->u.mgd.ttlm_work, - delay_jiffies); +us_to_ktime (delay_usec));return ; } }
@@ -8761,7 +8761,7 @@ void ieee80211_sta_setup_sdata(struct ietimer_setup (&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer,0 );wiphy_delayed_work_init (&ifmgd->tx_tspec_wk, ieee80211_sta_handle_tspec_ac_params_wk); -wiphy_delayed_work_init (&ifmgd->ttlm_work, +wiphy_hrtimer_work_init (&ifmgd->ttlm_work, ieee80211_tid_to_link_map_work);wiphy_delayed_work_init (&ifmgd->neg_ttlm_timeout_work, ieee80211_neg_ttlm_timeout_work);
Greg Kroah-Hartman
maintainerPATCH 806/849 wifi: mac80211: use wiphy_hrtimer_work for csa.switch_work
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Berg <[email protected]>
commit fbc1cc6973099f45e4c30b86f12b4435c7cb7d24 upstream.
The work item may be scheduled relatively far in the future. As the event happens at a specific point in time, the normal timer accuracy is not sufficient in that case.
Switch to use wiphy_hrtimer_work so that the accuracy is sufficient. To make this work, use the same clock to store the timestamp.
--- net/mac80211/chan.c | 2 +- net/mac80211/ieee80211_i.h | 4 ++-- net/mac80211/link.c | 4 ++-- net/mac80211/mlme.c | 18 +++++++++--------- 4 files changed, 14 insertions(+), 14 deletions(-)
net/mac80211/chan.c +1 -1
@@ -1301,7 +1301,7 @@ ieee80211_link_chanctx_reservation_compl &link->csa.finalize_work);break ;case NL80211_IFTYPE_STATION : -wiphy_delayed_work_queue (sdata->local->hw.wiphy, +wiphy_hrtimer_work_queue (sdata->local->hw.wiphy, &link->u.mgd.csa.switch_work,0 );break ;case NL80211_IFTYPE_UNSPECIFIED :
net/mac80211/ieee80211_i.h +2 -2
@@ -1009,10 +1009,10 @@ struct ieee80211_link_data_managed {bool operating_11g_mode;struct { -struct wiphy_delayed_work switch_work; +struct wiphy_hrtimer_work switch_work;struct cfg80211_chan_def ap_chandef;struct ieee80211_parsed_tpe tpe; -unsigned long time; +ktime_t time;bool waiting_bcn;bool ignored_same_chan;bool blocked_tx;
net/mac80211/link.c +2 -2
@@ -472,10 +472,10 @@ static int _ieee80211_set_active_links(s* from there. */ if (link->conf->csa_active) -wiphy_delayed_work_queue (local->hw.wiphy, +wiphy_hrtimer_work_queue (local->hw.wiphy, &link->u.mgd.csa.switch_work, link->u.mgd.csa.time - - jiffies); +ktime_get_boottime ()); }for_each_set_bit (link_id, &add,IEEE80211_MLD_MAX_NUM_LINKS ) {
net/mac80211/mlme.c +9 -9
@@ -2589,7 +2589,7 @@ void ieee80211_chswitch_done(struct ieeereturn ; } -wiphy_delayed_work_queue (sdata->local->hw.wiphy, +wiphy_hrtimer_work_queue (sdata->local->hw.wiphy, &link->u.mgd.csa.switch_work,0 ); }
@@ -2748,7 +2748,8 @@ ieee80211_sta_process_chanswitch(struct .timestamp = timestamp, .device_timestamp = device_timestamp, }; -unsigned long now; +u32 csa_time_tu; +ktime_t now;int res;lockdep_assert_wiphy (local->hw.wiphy);
@@ -2978,10 +2979,9 @@ ieee80211_sta_process_chanswitch(struct csa_ie.mode);/* we may have to handle timeout for deactivated link in software */ - now = jiffies; - link->u.mgd.csa.time = now + -TU_TO_JIFFIES ((max_t (int, csa_ie.count,1 ) -1 ) * - link->conf->beacon_int); + now =ktime_get_boottime (); + csa_time_tu = (max_t (int, csa_ie.count,1 ) -1 ) * link->conf->beacon_int; + link->u.mgd.csa.time = now +us_to_ktime (ieee80211_tu_to_usec (csa_time_tu));if (ieee80211_vif_link_active (&sdata->vif, link->link_id) && local->ops->channel_switch) {
@@ -2996,7 +2996,7 @@ ieee80211_sta_process_chanswitch(struct }/* channel switch handled in software */ -wiphy_delayed_work_queue (local->hw.wiphy, +wiphy_hrtimer_work_queue (local->hw.wiphy, &link->u.mgd.csa.switch_work, link->u.mgd.csa.time - now);return ;
@@ -8808,7 +8808,7 @@ void ieee80211_mgd_setup_link(struct ieeelse link->u.mgd.req_smps =IEEE80211_SMPS_OFF ; -wiphy_delayed_work_init (&link->u.mgd.csa.switch_work, +wiphy_hrtimer_work_init (&link->u.mgd.csa.switch_work, ieee80211_csa_switch_work);ieee80211_clear_tpe (&link->conf->tpe);
@@ -10023,7 +10023,7 @@ void ieee80211_mgd_stop_link(struct ieee &link->u.mgd.request_smps_work);wiphy_work_cancel (link->sdata->local->hw.wiphy, &link->u.mgd.recalc_smps); -wiphy_delayed_work_cancel (link->sdata->local->hw.wiphy, +wiphy_hrtimer_work_cancel (link->sdata->local->hw.wiphy, &link->u.mgd.csa.switch_work); }
Greg Kroah-Hartman
maintainerPATCH 807/849 fscrypt: fix left shift underflow when inode->i_blkbits > PAGE_SHIFT
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongpeng Yang <[email protected]>
commit 1e39da974ce621ed874c6d3aaf65ad14848c9f0d upstream.
When simulating an nvme device on qemu with both logical_block_size and physical_block_size set to 8 KiB, an error trace appears during partition table reading at boot time. The issue is caused by inode->i_blkbits being larger than PAGE_SHIFT, which leads to a left shift of -1 and triggering a UBSAN warning.
[ 2.697306] ------------[ cut here ]------------ [ 2.697309] UBSAN: shift-out-of-bounds in fs/crypto/inline_crypt.c:336:37 [ 2.697311] shift exponent -1 is negative [ 2.697315] CPU: 3 UID: 0 PID: 274 Comm: (udev-worker) Not tainted 6.18.0-rc2+ #34 PREEMPT(voluntary) [ 2.697317] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 [ 2.697320] Call Trace: [ 2.697324] <TASK> [ 2.697325] dump_stack_lvl+0x76/0xa0 [ 2.697340] dump_stack+0x10/0x20 [ 2.697342] __ubsan_handle_shift_out_of_bounds+0x1e3/0x390 [ 2.697351] bh_get_inode_and_lblk_num.cold+0x12/0x94 [ 2.697359] fscrypt_set_bio_crypt_ctx_bh+0x44/0x90 [ 2.697365] submit_bh_wbc+0xb6/0x190 [ 2.697370] block_read_full_folio+0x194/0x270 [ 2.697371] ? __pfx_blkdev_get_block+0x10/0x10 [ 2.697375] ? __pfx_blkdev_read_folio+0x10/0x10 [ 2.697377] blkdev_read_folio+0x18/0x30 [ 2.697379] filemap_read_folio+0x40/0xe0 [ 2.697382] filemap_get_pages+0x5ef/0x7a0 [ 2.697385] ? mmap_region+0x63/0xd0 [ 2.697389] filemap_read+0x11d/0x520 [ 2.697392] blkdev_read_iter+0x7c/0x180 [ 2.697393] vfs_read+0x261/0x390 [ 2.697397] ksys_read+0x71/0xf0 [ 2.697398] __x64_sys_read+0x19/0x30 [ 2.697399] x64_sys_call+0x1e88/0x26a0 [ 2.697405] do_syscall_64+0x80/0x670 [ 2.697410] ? __x64_sys_newfstat+0x15/0x20 [ 2.697414] ? x64_sys_call+0x204a/0x26a0 [ 2.697415] ? do_syscall_64+0xb8/0x670 [ 2.697417] ? irqentry_exit_to_user_mode+0x2e/0x2a0 [ 2.697420] ? irqentry_exit+0x43/0x50 [ 2.697421] ? exc_page_fault+0x90/0x1b0 [ 2.697422] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 2.697425] RIP: 0033:0x75054cba4a06 [ 2.697426] Code: 5d e8 41 8b 93 08 03 00 00 59 5e 48 83 f8 fc 75 19 83 e2 39 83 fa 08 75 11 e8 26 ff ff ff 66 0f 1f 44 00 00 48 8b 45 10 0f 05 <48> 8b 5d f8 c9 c3 0f 1f 40 00 f3 0f 1e fa 55 48 89 e5 48 83 ec 08 [ 2.697427] RSP: 002b:00007fff973723a0 EFLAGS: 00000202 ORIG_RAX: 0000000000000000 [ 2.697430] RAX: ffffffffffffffda RBX: 00005ea9a2c02760 RCX: 000075054cba4a06 [ 2.697432] RDX: 0000000000002000 RSI: 000075054c190000 RDI: 000000000000001b [ 2.697433] RBP: 00007fff973723c0 R08: 0000000000000000 R09: 0000000000000000 [ 2.697434] R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000000 [ 2.697434] R13: 00005ea9a2c027c0 R14: 00005ea9a2be5608 R15: 00005ea9a2be55f0 [ 2.697436] </TASK> [ 2.697436] ---[ end trace ]---
This situation can happen for block devices because when CONFIG_TRANSPARENT_HUGEPAGE is enabled, the maximum logical_block_size is 64 KiB. set_init_blocksize() then sets the block device inode->i_blkbits to 13, which is within this limit.
File I/O does not trigger this problem because for filesystems that do not support the FS_LBS feature, sb_set_blocksize() prevents sb->s_blocksize_bits from being larger than PAGE_SHIFT. During inode allocation, alloc_inode()->inode_init_always() assigns inode->i_blkbits from sb->s_blocksize_bits. Currently, only xfs_fs_type has the FS_LBS flag, and since xfs I/O paths do not reach submit_bh_wbc(), it does not hit the left-shift underflow issue.
--- fs/crypto/inline_crypt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/crypto/inline_crypt.c +1 -2
@@ -333,8 +333,7 @@ static bool bh_get_inode_and_lblk_num(const struct buffer_head *bh, inode = mapping->host; *inode_ret = inode; - *lblk_num_ret = ((u64 )folio->index << (PAGE_SHIFT - inode->i_blkbits)) + - (bh_offset (bh) >> inode->i_blkbits); + *lblk_num_ret = (folio_pos (folio) +bh_offset (bh)) >> inode->i_blkbits;return true; }
Signature · 1 line
2.51.2
Greg Kroah-Hartman
maintainerPATCH 808/849 drm/sched: Fix deadlock in drm_sched_entity_kill_jobs_cb
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pierre-Eric Pelloux-Prayer <[email protected]>
commit 487df8b698345dd5a91346335f05170ed5f29d4e upstream.
The Mesa issue referenced below pointed out a possible deadlock:
[ 1231.611031] Possible interrupt unsafe locking scenario:
[ 1231.611033] CPU0 CPU1
[ 1231.611034] ---- ----
[ 1231.611035] lock(&xa->xa_lock#17);
[ 1231.611038] local_irq_disable();
[ 1231.611039] lock(&fence->lock);
[ 1231.611041] lock(&xa->xa_lock#17);
[ 1231.611044] <Interrupt>
[ 1231.611045] lock(&fence->lock);
[ 1231.611047]
*** DEADLOCK ***In this example, CPU0 would be any function accessing job->dependencies through the xa_* functions that don't disable interrupts (eg:drm_sched_job_add_dependency(), drm_sched_entity_kill_jobs_cb()).
CPU1 is executing drm_sched_entity_kill_jobs_cb() as a fence signalling callback so in an interrupt context. It will deadlock when trying to grab the xa_lock which is already held by CPU0.
Replacing all xa_* usage by their xa_*_irq counterparts would fix this issue, but Christian pointed out another issue: dma_fence_signal takes fence.lock and so does dma_fence_add_callback.
dma_fence_signal() // locks f1.lock
-> drm_sched_entity_kill_jobs_cb()
-> foreach dependencies
-> dma_fence_add_callback() // locks f2.lock
This will deadlock if f1 and f2 share the same spinlock.
To fix both issues, the code iterating on dependencies and re-arming them is moved out to drm_sched_entity_kill_jobs_work().
--- drivers/gpu/drm/scheduler/sched_entity.c | 34 +++++++++++++++++-------------- 1 file changed, 19 insertions(+), 15 deletions(-)
drivers/gpu/drm/scheduler/sched_entity.c +19 -15
@@ -173,26 +173,15 @@ int drm_sched_entity_error(struct drm_sc }EXPORT_SYMBOL (drm_sched_entity_error); +static void drm_sched_entity_kill_jobs_cb (struct dma_fence *f, +struct dma_fence_cb *cb); +static void drm_sched_entity_kill_jobs_work (struct work_struct *wrk) {struct drm_sched_job *job =container_of (wrk,typeof (*job), work); - -drm_sched_fence_scheduled (job->s_fence,NULL ); -drm_sched_fence_finished (job->s_fence, -ESRCH ); -WARN_ON (job->s_fence->parent); - job->sched->ops->free_job (job); -} - -/* Signal the scheduler finished fence when the entity in question is killed. */ -static void drm_sched_entity_kill_jobs_cb (struct dma_fence *f, -struct dma_fence_cb *cb) -{ - struct drm_sched_job *job = container_of(cb, struct drm_sched_job, - finish_cb); +struct dma_fence *f;unsigned long index; -dma_fence_put (f); -/* Wait for all dependencies to avoid data corruptions */ xa_for_each (&job->dependencies, index, f) {struct drm_sched_fence *s_fence =to_drm_sched_fence (f);
@@ -220,6 +209,21 @@ static void drm_sched_entity_kill_jobs_cdma_fence_put (f); } +drm_sched_fence_scheduled (job->s_fence,NULL ); +drm_sched_fence_finished (job->s_fence, -ESRCH ); +WARN_ON (job->s_fence->parent); + job->sched->ops->free_job (job); +} + +/* Signal the scheduler finished fence when the entity in question is killed. */ +static void drm_sched_entity_kill_jobs_cb (struct dma_fence *f, +struct dma_fence_cb *cb) +{ + struct drm_sched_job *job = container_of(cb, struct drm_sched_job, + finish_cb); + +dma_fence_put (f); +INIT_WORK (&job->work, drm_sched_entity_kill_jobs_work);schedule_work (&job->work); }
Greg Kroah-Hartman
maintainerPATCH 809/849 Bluetooth: MGMT: Fix OOB access in parse_adv_monitor_pattern()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilia Gavrilov <[email protected]>
commit 8d59fba49362c65332395789fd82771f1028d87e upstream.
In the parse_adv_monitor_pattern() function, the value of
the 'length' variable is currently limited to HCI_MAX_EXT_AD_LENGTH(251). The size of the 'value' array in the mgmt_adv_pattern structure is 31. If the value of 'pattern[i].length' is set in the user space and exceeds 31, the 'patterns[i].value' array can be accessed out of bound when copied.
Increasing the size of the 'value' array in
the 'mgmt_adv_pattern' structure will break the userspace. Considering this, and to avoid OOB access revert the limits for 'offset' and 'length' back to the value of HCI_MAX_AD_LENGTH.
Found by InfoTeCS on behalf of Linux Verification Center (linuxtesting.org) with SVACE.
--- include/net/bluetooth/mgmt.h | 2 +- net/bluetooth/mgmt.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
include/net/bluetooth/mgmt.h +1 -1
@@ -775,7 +775,7 @@ struct mgmt_adv_pattern {__u8 ad_type;__u8 offset;__u8 length; -__u8 value[31 ]; +__u8 value[HCI_MAX_AD_LENGTH ]; } __packed;#define MGMT_OP_ADD_ADV_PATTERNS_MONITOR 0x0052
net/bluetooth/mgmt.c +3 -3
@@ -5395,9 +5395,9 @@ static u8 parse_adv_monitor_pattern(strufor (i =0 ; i < pattern_count; i++) { offset = patterns[i].offset; length = patterns[i].length; -if (offset >=HCI_MAX_EXT_AD_LENGTH || - length >HCI_MAX_EXT_AD_LENGTH || - (offset + length) >HCI_MAX_EXT_AD_LENGTH ) +if (offset >=HCI_MAX_AD_LENGTH || + length >HCI_MAX_AD_LENGTH || + (offset + length) >HCI_MAX_AD_LENGTH )return MGMT_STATUS_INVALID_PARAMS ; p =kmalloc (sizeof (*p),GFP_KERNEL );
Greg Kroah-Hartman
maintainerPATCH 810/849 iommufd: Dont overflow during division for dirty tracking
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
commit cb30dfa75d55eced379a42fd67bd5fb7ec38555e upstream.
If pgshift is 63 then BITS_PER_TYPE(*bitmap->bitmap) * pgsize will overflow to 0 and this triggers divide by 0.
In this case the index should just be 0, so reorganize things to divide by shift and avoid hitting any overflows.
--- drivers/iommu/iommufd/iova_bitmap.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/iommu/iommufd/iova_bitmap.c +2 -3
@@ -130,9 +130,8 @@ struct iova_bitmap {static unsigned long iova_bitmap_offset_to_index (struct iova_bitmap *bitmap,unsigned long iova) { -unsigned long pgsize =1UL << bitmap->mapped.pgshift; - -return iova / (BITS_PER_TYPE (*bitmap->bitmap) * pgsize); +return (iova >> bitmap->mapped.pgshift) / +BITS_PER_TYPE (*bitmap->bitmap); }/*
Greg Kroah-Hartman
maintainerPATCH 811/849 riscv: Fix memory leak in module_frob_arch_sections()
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaoqian Lin <[email protected]>
commit c42458fcf54b3d0bc2ac06667c98dceb43831889 upstream.
The current code directly overwrites the scratch pointer with the return value of kvrealloc(). If kvrealloc() fails and returns NULL, the original buffer becomes unreachable, causing a memory leak.
Fix this by using a temporary variable to store kvrealloc()'s return value and only update the scratch pointer on success.
Found via static anlaysis and this is similar to commit 42378a9ca553 ("bpf, verifier: Fix memory leak in array reallocation for stack state")
--- arch/riscv/kernel/module-sections.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/riscv/kernel/module-sections.c +6 -2
@@ -119,6 +119,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,unsigned int num_plts =0 ;unsigned int num_gots =0 ;Elf_Rela *scratch =NULL ; +Elf_Rela *new_scratch;size_t scratch_size =0 ;int i;
@@ -168,9 +169,12 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, scratch_size_needed = (num_scratch_relas + num_relas) *sizeof (*scratch);if (scratch_size_needed > scratch_size) { scratch_size = scratch_size_needed; - scratch =kvrealloc (scratch, scratch_size,GFP_KERNEL ); -if (!scratch) + new_scratch =kvrealloc (scratch, scratch_size,GFP_KERNEL ); +if (!new_scratch) { +kvfree (scratch);return -ENOMEM ; + } + scratch = new_scratch; }for (size_t j =0 ; j < num_relas; j++)
Signature · 1 line
2.51.2
Greg Kroah-Hartman
maintainerPATCH 812/849 parisc: Avoid crash due to unaligned access in unwinder
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit fd9f30d1038ee1624baa17a6ff11effe5f7617cb upstream.
Guenter Roeck reported this kernel crash on his emulated B160L machine:
Starting network: udhcpc: started, v1.36.1
Backtrace: [<104320d4>] unwind_once+0x1c/0x5c [<10434a00>] walk_stackframe.isra.0+0x74/0xb8 [<10434a6c>] arch_stack_walk+0x28/0x38 [<104e5efc>] stack_trace_save+0x48/0x5c [<105d1bdc>] set_track_prepare+0x44/0x6c [<105d9c80>] ___slab_alloc+0xfc4/0x1024 [<105d9d38>] __slab_alloc.isra.0+0x58/0x90 [<105dc80c>] kmem_cache_alloc_noprof+0x2ac/0x4a0 [<105b8e54>] __anon_vma_prepare+0x60/0x280 [<105a823c>] __vmf_anon_prepare+0x68/0x94 [<105a8b34>] do_wp_page+0x8cc/0xf10 [<105aad88>] handle_mm_fault+0x6c0/0xf08 [<10425568>] do_page_fault+0x110/0x440 [<10427938>] handle_interruption+0x184/0x748 [<11178398>] schedule+0x4c/0x190 BUG: spinlock recursion on CPU#0, ifconfig/2420 lock: terminate_lock.2+0x0/0x1c, .magic: dead4ead, .owner: ifconfig/2420, .owner_cpu: 0
While creating the stack trace, the unwinder uses the stack pointer to guess the previous frame to read the previous stack pointer from memory. The crash happens, because the unwinder tries to read from unaligned memory and as such triggers the unalignment trap handler which then leads to the spinlock recursion and finally to a deadlock.
Fix it by checking the alignment before accessing the memory.
--- arch/parisc/kernel/unwind.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
arch/parisc/kernel/unwind.c +10 -3
@@ -35,6 +35,8 @@#define KERNEL_START (KERNEL_BINARY_TEXT_START) +#define ALIGNMENT_OK (ptr, type) (((ptr) & (sizeof(type) - 1)) == 0) +extern struct unwind_table_entry __start___unwind[];extern struct unwind_table_entry __stop___unwind[];
@@ -257,12 +259,15 @@ static int unwind_special(struct unwind_if (pc_is_kernel_fn (pc, _switch_to) || pc == (unsigned long )&_switch_to_ret) { info->prev_sp = info->sp -CALLEE_SAVE_FRAME_SIZE ; - info->prev_ip = *(unsigned long *)(info->prev_sp -RP_OFFSET ); +if (ALIGNMENT_OK (info->prev_sp, long)) + info->prev_ip = *(unsigned long *)(info->prev_sp -RP_OFFSET ); +else + info->prev_ip = info->prev_sp =0 ;return 1 ; }#ifdef CONFIG_IRQSTACKS -if (pc == (unsigned long )&_call_on_stack) { +if (pc == (unsigned long )&_call_on_stack &&ALIGNMENT_OK (info->sp, long)) { info->prev_sp = *(unsigned long *)(info->sp -FRAME_SIZE -REG_SZ ); info->prev_ip = *(unsigned long *)(info->sp -FRAME_SIZE -RP_OFFSET );return 1 ;
@@ -370,8 +375,10 @@ static void unwind_frame_regs(struct unw info->prev_sp = info->sp - frame_size;if (e->Millicode) info->rp = info->r31; -else if (rpoffset) +else if (rpoffset &&ALIGNMENT_OK (info->prev_sp, long)) info->rp = *(unsigned long *)(info->prev_sp - rpoffset); +else + info->rp =0 ; info->prev_ip = info->rp; info->rp =0 ; }
Greg Kroah-Hartman
maintainerPATCH 813/849 rtc: rx8025: fix incorrect register reference
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuta Hayama <[email protected]>
commit 162f24cbb0f6ec596e7e9f3e91610d79dc805229 upstream.
This code is intended to operate on the CTRL1 register, but ctrl[1] is actually CTRL2. Correctly, ctrl[0] is CTRL1.
--- drivers/rtc/rtc-rx8025.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/rtc/rtc-rx8025.c +1 -1
@@ -316,7 +316,7 @@ static int rx8025_init_client(struct i2creturn hour_reg; rx8025->is_24 = (hour_reg &RX8035_BIT_HOUR_1224 ); }else { - rx8025->is_24 = (ctrl[1 ] &RX8025_BIT_CTRL1_1224 ); + rx8025->is_24 = (ctrl[0 ] &RX8025_BIT_CTRL1_1224 ); } out:return err;
Greg Kroah-Hartman
maintainerPATCH 814/849 x86/microcode/AMD: Add more known models to entry sign checking
In reply to Greg Kroah-Hartman6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello (AMD) <[email protected]>
commit d23550efc6800841b4d1639784afaebdea946ae0 upstream.
Two Zen5 systems are missing from need_sha_check(). Add them.
--- arch/x86/kernel/cpu/microcode/amd.c | 2 ++ 1 file changed, 2 insertions(+)
arch/x86/kernel/cpu/microcode/amd.c +2 -0
@@ -220,10 +220,12 @@ static bool need_sha_check(u32 cur_rev)case 0xaa001 :return cur_rev <=0xaa00116 ;break ;case 0xaa002 :return cur_rev <=0xaa00218 ;break ;case 0xb0021 :return cur_rev <=0xb002146 ;break ; +case 0xb0081 :return cur_rev <=0xb008111 ;break ;case 0xb1010 :return cur_rev <=0xb101046 ;break ;case 0xb2040 :return cur_rev <=0xb204031 ;break ;case 0xb4040 :return cur_rev <=0xb404031 ;break ;case 0xb6000 :return cur_rev <=0xb600031 ;break ; +case 0xb6080 :return cur_rev <=0xb608031 ;break ;case 0xb7000 :return cur_rev <=0xb700031 ;break ;default :break ; }