5.15.75-rc1 review
Subsystems (9)
Greg Kroah-Hartman
maintainerPATCH 315/530 ata: fix ata_id_has_dipm()
In reply to Greg Kroah-HartmanFrom: Niklas Cassel <[email protected]>
[ Upstream commit 630624cb1b5826d753ac8e01a0e42de43d66dedf ]
ACS-5 section
7.13.6.36 Word 78: Serial ATA features supported
states that:
If word 76 is not 0000h or FFFFh, word 78 reports the features supported by the device. If this word is not supported, the word shall be cleared to zero.
(This text also exists in really old ACS standards, e.g. ACS-3.)
The problem with ata_id_has_dipm() is that the while it performs a check against 0 and 0xffff, it performs the check against ATA_ID_FEATURE_SUPP (word 78), the same word where the feature bit is stored.
Fix this by performing the check against ATA_ID_SATA_CAPABILITY (word 76), like required by the spec. The feature bit check itself is of course still performed against ATA_ID_FEATURE_SUPP (word 78).
Additionally, move the macro to the other ATA_ID_FEATURE_SUPP macros (which already have this check), thus making it more likely that the next ATA_ID_FEATURE_SUPP macro that is added will include this check.
--- include/linux/ata.h | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
include/linux/ata.h +4 -11
@@ -573,6 +573,10 @@ struct ata_bmdma_prd { ((((id)[ATA_ID_SATA_CAPABILITY ] !=0x0000 ) && \ ((id)[ATA_ID_SATA_CAPABILITY ] !=0xffff )) && \ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7))) +#define ata_id_has_dipm (id) \ + ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ + ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ + ((id)[ATA_ID_FEATURE_SUPP] & (1 << 3)))#define ata_id_iordy_disable (id) ((id)[ATA_ID_CAPABILITY] & (1 << 10))#define ata_id_has_iordy (id) ((id)[ATA_ID_CAPABILITY] & (1 << 11))#define ata_id_u32 (id,n) \
@@ -596,17 +600,6 @@ static inline bool ata_id_has_hipm(const u16 *id)return val & (1 <<9 ); } -static inline bool ata_id_has_dipm (const u16 *id) -{ -u16 val = id[ATA_ID_FEATURE_SUPP ]; - -if (val ==0 || val ==0xffff ) -return false; - -return val & (1 <<3 ); -} - -static inline bool ata_id_has_fua (const u16 *id) {if ((id[ATA_ID_CFSSE ] &0xC000 ) !=0x4000 )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 316/530 mtd: rawnand: meson: fix bit map use in meson_nfc_ecc_correct()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 3e4ad3212cf22687410b1e8f4e68feec50646113 ]
The meson_nfc_ecc_correct() function accidentally does a right shift instead of a left shift so it only works for BIT(0). Also use BIT_ULL() because "correct_bitmap" is a u64 and we want to avoid shift wrapping bugs.
--- drivers/mtd/nand/raw/meson_nand.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mtd/nand/raw/meson_nand.c +2 -2
@@ -454,7 +454,7 @@ static int meson_nfc_ecc_correct(struct nand_chip *nand, u32 *bitflips,if (ECC_ERR_CNT (*info) !=ECC_UNCORRECTABLE ) { mtd->ecc_stats.corrected +=ECC_ERR_CNT (*info); *bitflips =max_t (u32, *bitflips,ECC_ERR_CNT (*info)); - *correct_bitmap |=1 >> i; + *correct_bitmap |=BIT_ULL (i);continue ; } if ((nand->options & NAND_NEED_SCRAMBLING) &&
@@ -800,7 +800,7 @@ static int meson_nfc_read_page_hwecc(struct nand_chip *nand, u8 *buf,u8 *data = buf + i * ecc->size;u8 *oob = nand->oob_poi + i * (ecc->bytes +2 ); -if (correct_bitmap & (1 << i)) +if (correct_bitmap &BIT_ULL (i))continue ; ret = nand_check_erased_ecc_chunk(data, ecc->size, oob, ecc->bytes + 2,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 317/530 md: Replace snprintf with scnprintf
In reply to Greg Kroah-HartmanFrom: Saurabh Sengar <[email protected]>
[ Upstream commit 1727fd5015d8f93474148f94e34cda5aa6ad4a43 ]
Current code produces a warning as shown below when total characters in the constituent block device names plus the slashes exceeds 200. snprintf() returns the number of characters generated from the given input, which could cause the expression “200 – len” to wrap around to a large positive number. Fix this by using scnprintf() instead, which returns the actual number of characters written into the buffer.
[ 1513.267938] ------------[ cut here ]------------ [ 1513.267943] WARNING: CPU: 15 PID: 37247 at <snip>/lib/vsprintf.c:2509 vsnprintf+0x2c8/0x510 [ 1513.267944] Modules linked in: <snip> [ 1513.267969] CPU: 15 PID: 37247 Comm: mdadm Not tainted 5.4.0-1085-azure #90~18.04.1-Ubuntu [ 1513.267969] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.1 05/09/2022 [ 1513.267971] RIP: 0010:vsnprintf+0x2c8/0x510 <-snip-> [ 1513.267982] Call Trace: [ 1513.267986] snprintf+0x45/0x70 [ 1513.267990] ? disk_name+0x71/0xa0 [ 1513.267993] dump_zones+0x114/0x240 [raid0] [ 1513.267996] ? _cond_resched+0x19/0x40 [ 1513.267998] raid0_run+0x19e/0x270 [raid0] [ 1513.268000] md_run+0x5e0/0xc50 [ 1513.268003] ? security_capable+0x3f/0x60 [ 1513.268005] do_md_run+0x19/0x110 [ 1513.268006] md_ioctl+0x195e/0x1f90 [ 1513.268007] blkdev_ioctl+0x91f/0x9f0 [ 1513.268010] block_ioctl+0x3d/0x50 [ 1513.268012] do_vfs_ioctl+0xa9/0x640 [ 1513.268014] ? __fput+0x162/0x260 [ 1513.268016] ksys_ioctl+0x75/0x80 [ 1513.268017] __x64_sys_ioctl+0x1a/0x20 [ 1513.268019] do_syscall_64+0x5e/0x200 [ 1513.268021] entry_SYSCALL_64_after_hwframe+0x44/0xa9
--- drivers/md/raid0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/raid0.c +1 -1
@@ -48,7 +48,7 @@ static void dump_zones(struct mddev *mddint len =0 ;for (k =0 ; k < conf->strip_zone[j].nb_dev; k++) - len +=snprintf (line+len,200 -len,"%s%s" , k?"/" :"" , + len +=scnprintf (line+len,200 -len,"%s%s" , k?"/" :"" ,bdevname (conf->devlist[j*raid_disks + k]->bdev, b));pr_debug ("md: zone%d=[%s]\n" , j, line);
Greg Kroah-Hartman
maintainerPATCH 318/530 md/raid5: Ensure stripe_fill happens on non-read IO with journal
In reply to Greg Kroah-HartmanFrom: Logan Gunthorpe <[email protected]>
[ Upstream commit e2eed85bc75138a9eeb63863d20f8904ac42a577 ]
When doing degrade/recover tests using the journal a kernel BUG is hit at drivers/md/raid5.c:4381 in handle_parity_checks5():
BUG_ON(!test_bit(R5_UPTODATE, &dev->flags));
This was found to occur because handle_stripe_fill() was skipped for stripes in the journal due to a condition in that function. Thus blocks were not fetched and R5_UPTODATE was not set when the code reached handle_parity_checks5().
To fix this, don't skip handle_stripe_fill() unless the stripe is for read.
--- drivers/md/raid5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/raid5.c +1 -1
@@ -3936,7 +3936,7 @@ static void handle_stripe_fill(struct st* back cache (prexor with orig_page, and then xor with * page) in the read path */ -if (s->injournal && s->failed) { +if (s->to_read && s->injournal && s->failed) {if (test_bit (STRIPE_R5C_CACHING , &sh->state))r5c_make_stripe_write_out (sh); goto out;
Greg Kroah-Hartman
maintainerPATCH 319/530 md/raid5: Remove unnecessary bio_put() in raid5_read_one_chunk()
In reply to Greg Kroah-HartmanFrom: David Sloan <[email protected]>
[ Upstream commit c66a6f41e09ad386fd2cce22b9cded837bbbc704 ]
When running chunk-sized reads on disks with badblocks duplicate bio free/puts are observed:
=============================================================================
BUG bio-200 (Not tainted): Object already free
-----------------------------------------------------------------------------
Allocated in mempool_alloc_slab+0x17/0x20 age=3 cpu=2 pid=7504
__slab_alloc.constprop.0+0x5a/0xb0
kmem_cache_alloc+0x31e/0x330
mempool_alloc_slab+0x17/0x20
mempool_alloc+0x100/0x2b0
bio_alloc_bioset+0x181/0x460
do_mpage_readpage+0x776/0xd00
mpage_readahead+0x166/0x320
blkdev_readahead+0x15/0x20
read_pages+0x13f/0x5f0
page_cache_ra_unbounded+0x18d/0x220
force_page_cache_ra+0x181/0x1c0
page_cache_sync_ra+0x65/0xb0
filemap_get_pages+0x1df/0xaf0
filemap_read+0x1e1/0x700
blkdev_read_iter+0x1e5/0x330
vfs_read+0x42a/0x570
Freed in mempool_free_slab+0x17/0x20 age=3 cpu=2 pid=7504
kmem_cache_free+0x46d/0x490
mempool_free_slab+0x17/0x20
mempool_free+0x66/0x190
bio_free+0x78/0x90
bio_put+0x100/0x1a0
raid5_make_request+0x2259/0x2450
md_handle_request+0x402/0x600
md_submit_bio+0xd9/0x120
__submit_bio+0x11f/0x1b0
submit_bio_noacct_nocheck+0x204/0x480
submit_bio_noacct+0x32e/0xc70
submit_bio+0x98/0x1a0
mpage_readahead+0x250/0x320
blkdev_readahead+0x15/0x20
read_pages+0x13f/0x5f0
page_cache_ra_unbounded+0x18d/0x220
Slab 0xffffea000481b600 objects=21 used=0 fp=0xffff8881206d8940 flags=0x17ffffc0010201(locked|slab|head|node=0|zone=2|lastcpupid=0x1fffff)
CPU: 0 PID: 34525 Comm: kworker/u24:2 Not tainted 6.0.0-rc2-localyes-265166-gf11c5343fa3f #143
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
Workqueue: raid5wq raid5_do_work
Call Trace:
<TASK>
dump_stack_lvl+0x5a/0x78
dump_stack+0x10/0x16
print_trailer+0x158/0x165
object_err+0x35/0x50
free_debug_processing.cold+0xb7/0xbe
__slab_free+0x1ae/0x330
kmem_cache_free+0x46d/0x490
mempool_free_slab+0x17/0x20
mempool_free+0x66/0x190
bio_free+0x78/0x90
bio_put+0x100/0x1a0
mpage_end_io+0x36/0x150
bio_endio+0x2fd/0x360
md_end_io_acct+0x7e/0x90
bio_endio+0x2fd/0x360
handle_failed_stripe+0x960/0xb80
handle_stripe+0x1348/0x3760
handle_active_stripes.constprop.0+0x72a/0xaf0
raid5_do_work+0x177/0x330
process_one_work+0x616/0xb20
worker_thread+0x2bd/0x6f0
kthread+0x179/0x1b0
ret_from_fork+0x22/0x30
</TASK>The double free is caused by an unnecessary bio_put() in the if(is_badblock(...)) error path in raid5_read_one_chunk().
The error path was moved ahead of bio_alloc_clone() in c82aa1b76787c ("md/raid5: move checking badblock before clone bio in raid5_read_one_chunk"). The previous code checked and freed align_bio which required a bio_put. After the move that is no longer needed as raid_bio is returned to the control of the common io path which performs its own endio resulting in a double free on bad device blocks.
--- drivers/md/raid5.c | 1 - 1 file changed, 1 deletion(-)
drivers/md/raid5.c +0 -1
@@ -5430,7 +5430,6 @@ static int raid5_read_one_chunk(struct mif (is_badblock (rdev, sector,bio_sectors (raid_bio), &first_bad, &bad_sectors)) { -bio_put (raid_bio);rdev_dec_pending (rdev, mddev);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 320/530 RDMA/cm: Use SLID in the work completion as the DLID in responder side
In reply to Greg Kroah-HartmanFrom: Mark Zhang <[email protected]>
[ Upstream commit b7d95040c13f61a4a6a859c5355faf583eff9658 ]
The responder should always use WC's SLID as the dlid, to follow the IB SPEC section "13.5.4.2 COMMON RESPONSE ACTIONS":
A responder always takes the following actions in constructing a response packet:
- The SLID of the received packet is used as the DLID in the response packet.
--- drivers/infiniband/core/cm.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/infiniband/core/cm.c +7 -7
@@ -1632,14 +1632,13 @@ static void cm_path_set_rec_type(struct ib_device *ib_device, u32 port_num,static void cm_format_path_lid_from_req (struct cm_req_msg *req_msg,struct sa_path_rec *primary_path, -struct sa_path_rec *alt_path) +struct sa_path_rec *alt_path, +struct ib_wc *wc) {u32 lid;if (primary_path->rec_type !=SA_PATH_REC_TYPE_OPA ) { -sa_path_set_dlid (primary_path, -IBA_GET (CM_REQ_PRIMARY_LOCAL_PORT_LID , - req_msg)); +sa_path_set_dlid (primary_path, wc->slid);sa_path_set_slid (primary_path,IBA_GET (CM_REQ_PRIMARY_REMOTE_PORT_LID , req_msg));
@@ -1676,7 +1675,8 @@ static void cm_format_path_lid_from_req(struct cm_req_msg *req_msg,static void cm_format_paths_from_req (struct cm_req_msg *req_msg,struct sa_path_rec *primary_path, -struct sa_path_rec *alt_path) +struct sa_path_rec *alt_path, +struct ib_wc *wc) { primary_path->dgid = *IBA_GET_MEM_PTR (CM_REQ_PRIMARY_LOCAL_PORT_GID , req_msg);
@@ -1734,7 +1734,7 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg,if (sa_path_is_roce (alt_path)) alt_path->roce.route_resolved = false; } -cm_format_path_lid_from_req (req_msg, primary_path, alt_path); +cm_format_path_lid_from_req (req_msg, primary_path, alt_path, wc); }static u16 cm_get_bth_pkey (struct cm_work *work)
@@ -2148,7 +2148,7 @@ static int cm_req_handler(struct cm_work *work)if (cm_req_has_alt_path (req_msg)) work->path[1 ].rec_type = work->path[0 ].rec_type;cm_format_paths_from_req (req_msg, &work->path[0 ], - &work->path[1 ]); + &work->path[1 ], work->mad_recv_wc->wc);if (cm_id_priv->av.ah_attr.type ==RDMA_AH_ATTR_TYPE_ROCE )sa_path_set_dmac (&work->path[0 ], cm_id_priv->av.ah_attr.roce.dmac);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 321/530 IB: Set IOVA/LENGTH on IB_MR in core/uverbs layers
In reply to Greg Kroah-HartmanFrom: Daisuke Matsuda <[email protected]>
[ Upstream commit 241f9a27e0fc0eaf23e3d52c8450f10648cd11f1 ]
Set 'iova' and 'length' on ib_mr in ib_uverbs and ib_core layers to let all drivers have the members filled. Also, this commit removes redundancy in the respective drivers.
Previously, commit 04c0a5fcfcf65 ("IB/uverbs: Set IOVA on IB MR in uverbs layer") changed to set 'iova', but seems to have missed 'length' and the ib_core layer at that time.
--- drivers/infiniband/core/uverbs_cmd.c | 5 ++++- drivers/infiniband/core/verbs.c | 2 ++ drivers/infiniband/hw/hns/hns_roce_mr.c | 1 - drivers/infiniband/hw/mlx4/mr.c | 1 - 4 files changed, 6 insertions(+), 3 deletions(-)
drivers/infiniband/core/uverbs_cmd.c +4 -1
@@ -739,6 +739,7 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs) mr->uobject = uobj;atomic_inc (&pd->usecnt); mr->iova = cmd.hca_va; + mr->length = cmd.length;rdma_restrack_new (&mr->res,RDMA_RESTRACK_MR );rdma_restrack_set_name (&mr->res,NULL );
@@ -861,8 +862,10 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs) mr->pd = new_pd;atomic_inc (&new_pd->usecnt); } -if (cmd.flags &IB_MR_REREG_TRANS ) +if (cmd.flags &IB_MR_REREG_TRANS ) { mr->iova = cmd.hca_va; + mr->length = cmd.length; + } }memset (&resp,0 ,sizeof (resp));
drivers/infiniband/core/verbs.c +2 -0
@@ -2157,6 +2157,8 @@ struct ib_mr *ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, mr->pd = pd; mr->dm =NULL ;atomic_inc (&pd->usecnt); + mr->iova = virt_addr; + mr->length = length;rdma_restrack_new (&mr->res,RDMA_RESTRACK_MR );rdma_restrack_parent_name (&mr->res, &pd->res);
drivers/infiniband/hw/hns/hns_roce_mr.c +0 -1
@@ -272,7 +272,6 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, goto err_alloc_pbl; mr->ibmr.rkey = mr->ibmr.lkey = mr->key; - mr->ibmr.length = length;return &mr->ibmr;
drivers/infiniband/hw/mlx4/mr.c +0 -1
@@ -439,7 +439,6 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, goto err_mr; mr->ibmr.rkey = mr->ibmr.lkey = mr->mmr.key; - mr->ibmr.length = length; mr->ibmr.page_size =1U << shift;return &mr->ibmr;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 322/530 xhci: Dont show warning for reinit on known broken suspend
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
[ Upstream commit 484d6f7aa3283d082c87654b7fe7a7f725423dfb ]
commit 8b328f8002bc ("xhci: re-initialize the HC during resume if HCE was set") introduced a new warning message when the host controller error was set and re-initializing.
This is expected behavior on some designs which already set xhci->broken_suspend so the new warning is alarming to some users.
Modify the code to only show the warning if this was a surprising behavior to the XHCI driver.
--- drivers/usb/host/xhci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/host/xhci.c +2 -1
@@ -1165,7 +1165,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)/* re-initialize the HC on Restore Error, or Host Controller Error */ if (temp & (STS_SRE |STS_HCE )) { reinit_xhc = true; -xhci_warn (xhci,"xHC error in resume, USBSTS 0x%x, Reinit\n" , temp); +if (!xhci->broken_suspend) +xhci_warn (xhci,"xHC error in resume, USBSTS 0x%x, Reinit\n" , temp); }if (reinit_xhc) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 323/530 usb: gadget: function: fix dangling pnp_string in f_printer.c
In reply to Greg Kroah-HartmanFrom: Albert Briscoe <[email protected]>
[ Upstream commit 24b7ba2f88e04800b54d462f376512e8c41b8a3c ]
When opts->pnp_string is changed with configfs, new memory is allocated for the string. It does not, however, update dev->pnp_string, even though the memory is freed. When rquesting the string, the host then gets old or corrupted data rather than the new string. The ieee 1284 id string should be allowed to change while the device is connected.
The bug was introduced in commit fdc01cc286be ("usb: gadget: printer:
Remove pnp_string static buffer"), which changed opts->pnp_string from a char[] to a char*.
This patch changes dev->pnp_string from a char* to a char** pointing to opts->pnp_string.
--- drivers/usb/gadget/function/f_printer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/usb/gadget/function/f_printer.c +6 -6
@@ -89,7 +89,7 @@ struct printer_dev {u8 printer_cdev_open;wait_queue_head_t wait;unsigned q_len; -char *pnp_string;/* We don't own memory! */ +char **pnp_string;/* We don't own memory! */ struct usb_function function; };
@@ -1000,16 +1000,16 @@ static int printer_func_setup(struct usb_function *f,if ((wIndex>>8 ) != dev->interface)break ; -if (!dev->pnp_string) { +if (!*dev->pnp_string) { value =0 ;break ; } - value =strlen (dev->pnp_string); + value =strlen (*dev->pnp_string); buf[0 ] = (value >>8 ) &0xFF ; buf[1 ] = value &0xFF ; -memcpy (buf +2 , dev->pnp_string, value); +memcpy (buf +2 , *dev->pnp_string, value);DBG (dev,"1284 PNP String: %x %s\n" , value, - dev->pnp_string); + *dev->pnp_string);break ;case GET_PORT_STATUS :/* Get Port Status */
@@ -1475,7 +1475,7 @@ static struct usb_function *gprinter_alloc(struct usb_function_instance *fi)kref_init (&dev->kref); ++opts->refcnt; dev->minor = opts->minor; - dev->pnp_string = opts->pnp_string; + dev->pnp_string = &opts->pnp_string; dev->q_len = opts->q_len;mutex_unlock (&opts->lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 324/530 drivers: serial: jsm: fix some leaks in probe
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 1d5859ef229e381f4db38dce8ed58e4bf862006b ]
This error path needs to unwind instead of just returning directly.
--- drivers/tty/serial/jsm/jsm_driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/tty/serial/jsm/jsm_driver.c +2 -1
@@ -211,7 +211,8 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)break ;default : -return -ENXIO ; + rc = -ENXIO ; + goto out_kfree_brd; } rc =request_irq (brd->irq, brd->bd_ops->intr,IRQF_SHARED ,"JSM" , brd);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 325/530 serial: 8250: Toggle IER bits on only after irq has been set up
In reply to Greg Kroah-HartmanFrom: Ilpo Järvinen <[email protected]>
[ Upstream commit 039d4926379b1d1c17b51cf21c500a5eed86899e ]
Invoking TIOCVHANGUP on 8250_mid port on Ice Lake-D and then reopening the port triggers these faults during serial8250_do_startup():
DMAR: DRHD: handling fault status reg 3
DMAR: [DMA Write NO_PASID] Request device [00:1a.0] fault addr 0x0 [fault reason 0x05] PTE Write access is not set
If the IRQ hasn't been set up yet, the UART will have zeroes in its MSI address/data registers. Disabling the IRQ at the interrupt controller won't stop the UART from performing a DMA write to the address programmed in its MSI address register (zero) when it wants to signal an interrupt.
The UARTs (in Ice Lake-D) implement PCI 2.1 style MSI without masking capability, so there is no way to mask the interrupt at the source PCI function level, except disabling the MSI capability entirely, but that would cause it to fall back to INTx# assertion, and the PCI specification prohibits disabling the MSI capability as a way to mask a function's interrupt service request.
The MSI address register is zeroed by the hangup as the irq is freed. The interrupt is signalled during serial8250_do_startup() performing a THRE test that temporarily toggles THRI in IER. The THRE test currently occurs before UART's irq (and MSI address) is properly set up.
Refactor serial8250_do_startup() such that irq is set up before the THRE test. The current irq setup code is intermixed with the timer setup code. As THRE test must be performed prior to the timer setup, extract it into own function and call it only after the THRE test.
The ->setup_timer() needs to be part of the struct uart_8250_ops in order to not create circular dependency between 8250 and 8250_base modules.
--- drivers/tty/serial/8250/8250_core.c | 16 +++++++++++----- drivers/tty/serial/8250/8250_port.c | 8 +++++--- include/linux/serial_8250.h | 1 + 3 files changed, 17 insertions(+), 8 deletions(-)
drivers/tty/serial/8250/8250_core.c +11 -5
@@ -300,10 +300,9 @@ static void serial8250_backup_timeout(struct timer_list *t) jiffies + uart_poll_timeout(&up->port) + HZ / 5); } -static int univ8250_setup_irq (struct uart_8250_port *up) +static void univ8250_setup_timer (struct uart_8250_port *up) {struct uart_port *port = &up->port; -int retval =0 ;/* * The above check will only give an accurate result the first time
@@ -324,10 +323,16 @@ static int univ8250_setup_irq(struct uart_8250_port *up)*/ if (!port->irq)mod_timer (&up->timer, jiffies +uart_poll_timeout (port)); -else - retval =serial_link_irq_chain (up); +} -return retval; +static int univ8250_setup_irq (struct uart_8250_port *up) +{ +struct uart_port *port = &up->port; + +if (port->irq) +return serial_link_irq_chain (up); + +return 0 ; }static void univ8250_release_irq (struct uart_8250_port *up)
@@ -383,6 +388,7 @@ static struct uart_ops univ8250_port_ops;static const struct uart_8250_ops univ8250_driver_ops = { .setup_irq = univ8250_setup_irq, .release_irq = univ8250_release_irq, + .setup_timer = univ8250_setup_timer, };static struct uart_8250_port serial8250_ports[UART_NR ];
drivers/tty/serial/8250/8250_port.c +5 -3
@@ -2280,6 +2280,10 @@ int serial8250_do_startup(struct uart_port *port)if (port->irq && (up->port.flags &UPF_SHARE_IRQ )) up->port.irqflags |=IRQF_SHARED ; + retval = up->ops->setup_irq (up); +if (retval) + goto out; +if (port->irq && !(up->port.flags &UPF_NO_THRE_TEST )) {unsigned char iir1;
@@ -2322,9 +2326,7 @@ int serial8250_do_startup(struct uart_port *port) } } - retval = up->ops->setup_irq (up); -if (retval) - goto out; + up->ops->setup_timer (up);/* * Now, initialize the UART
include/linux/serial_8250.h +1 -0
@@ -74,6 +74,7 @@ struct uart_8250_port;struct uart_8250_ops {int (*setup_irq)(struct uart_8250_port *);void (*release_irq)(struct uart_8250_port *); +void (*setup_timer)(struct uart_8250_port *); };struct uart_8250_em485 {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 326/530 tty: serial: fsl_lpuart: disable dma rx/tx use flags in lpuart_dma_shutdown
In reply to Greg Kroah-HartmanFrom: Sherry Sun <[email protected]>
[ Upstream commit 316ae95c175a7d770d1bfe4c011192712f57aa4a ]
lpuart_dma_shutdown tears down lpuart dma, but lpuart_flush_buffer can still occur which in turn tries to access dma apis if lpuart_dma_tx_use flag is true. At this point since dma is torn down, these dma apis can abort. Set lpuart_dma_tx_use and the corresponding rx flag lpuart_dma_rx_use to false in lpuart_dma_shutdown so that dmas are not accessed after they are relinquished.
Otherwise, when try to kill btattach, kernel may panic. This patch may fix this issue.
root@imx8ulpevk:~# btattach -B /dev/ttyLP2 -S 115200 ^C[ 90.182296] Internal error: synchronous external abort: 96000210 [#1] PREEMPT SMP [ 90.189806] Modules linked in: moal(O) mlan(O) [ 90.194258] CPU: 0 PID: 503 Comm: btattach Tainted: G O 5.15.32-06136-g34eecdf2f9e4 #37 [ 90.203554] Hardware name: NXP i.MX8ULP 9X9 EVK (DT) [ 90.208513] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 90.215470] pc : fsl_edma3_disable_request+0x8/0x60 [ 90.220358] lr : fsl_edma3_terminate_all+0x34/0x20c [ 90.225237] sp : ffff800013f0bac0 [ 90.228548] x29: ffff800013f0bac0 x28: 0000000000000001 x27: ffff000008404800 [ 90.235681] x26: ffff000008404960 x25: ffff000008404a08 x24: ffff000008404a00 [ 90.242813] x23: ffff000008404a60 x22: 0000000000000002 x21: 0000000000000000 [ 90.249946] x20: ffff800013f0baf8 x19: ffff00000559c800 x18: 0000000000000000 [ 90.257078] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 [ 90.264211] x14: 0000000000000003 x13: 0000000000000000 x12: 0000000000000040 [ 90.271344] x11: ffff00000600c248 x10: ffff800013f0bb10 x9 : ffff000057bcb090 [ 90.278477] x8 : fffffc0000241a08 x7 : ffff00000534ee00 x6 : ffff000008404804 [ 90.285609] x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff0000055b3480 [ 90.292742] x2 : ffff8000135c0000 x1 : ffff00000534ee00 x0 : ffff00000559c800 [ 90.299876] Call trace: [ 90.302321] fsl_edma3_disable_request+0x8/0x60 [ 90.306851] lpuart_flush_buffer+0x40/0x160 [ 90.311037] uart_flush_buffer+0x88/0x120 [ 90.315050] tty_driver_flush_buffer+0x20/0x30 [ 90.319496] hci_uart_flush+0x44/0x90 [ 90.323162] +0x34/0x12c [ 90.327253] tty_ldisc_close+0x38/0x70 [ 90.331005] tty_ldisc_release+0xa8/0x190 [ 90.335018] tty_release_struct+0x24/0x8c [ 90.339022] tty_release+0x3ec/0x4c0 [ 90.342593] __fput+0x70/0x234 [ 90.345652] ____fput+0x14/0x20 [ 90.348790] task_work_run+0x84/0x17c [ 90.352455] do_exit+0x310/0x96c [ 90.355688] do_group_exit+0x3c/0xa0 [ 90.359259] __arm64_sys_exit_group+0x1c/0x20 [ 90.363609] invoke_syscall+0x48/0x114 [ 90.367362] el0_svc_common.constprop.0+0xd4/0xfc [ 90.372068] do_el0_svc+0x2c/0x94 [ 90.375379] el0_svc+0x28/0x80 [ 90.378438] el0t_64_sync_handler+0xa8/0x130 [ 90.382711] el0t_64_sync+0x1a0/0x1a4 [ 90.386376] Code: 17ffffda d503201f d503233f f9409802 (b9400041) [ 90.392467] ---[ end trace 2f60524b4a43f1f6 ]--- [ 90.397073] note: btattach[503] exited with preempt_count 1 [ 90.402636] Fixing recursive fault but reboot is needed!
--- drivers/tty/serial/fsl_lpuart.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/tty/serial/fsl_lpuart.c +2 -0
@@ -1787,6 +1787,7 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport)if (sport->lpuart_dma_rx_use) {del_timer_sync (&sport->lpuart_timer);lpuart_dma_rx_free (&sport->port); + sport->lpuart_dma_rx_use = false; }if (sport->lpuart_dma_tx_use) {
@@ -1795,6 +1796,7 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport) sport->dma_tx_in_progress = false;dmaengine_terminate_all (sport->dma_tx_chan); } + sport->lpuart_dma_tx_use = false; }if (sport->dma_tx_chan)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 327/530 phy: qualcomm: call clk_disable_unprepare in the error handling
In reply to Greg Kroah-HartmanFrom: Dongliang Mu <[email protected]>
[ Upstream commit c3966ced8eb8dc53b6c8d7f97d32cc8a2107d83e ]
Smatch reports the following error:
drivers/phy/qualcomm/phy-qcom-usb-hsic.c:82 qcom_usb_hsic_phy_power_on()
warn: 'uphy->cal_clk' from clk_prepare_enable() not released on lines:
58.drivers/phy/qualcomm/phy-qcom-usb-hsic.c:82 qcom_usb_hsic_phy_power_on()
warn: 'uphy->cal_sleep_clk' from clk_prepare_enable() not released on
lines: 58.drivers/phy/qualcomm/phy-qcom-usb-hsic.c:82 qcom_usb_hsic_phy_power_on()
warn: 'uphy->phy_clk' from clk_prepare_enable() not released on lines:
58.
Fix this by calling proper clk_disable_unprepare calls.
--- drivers/phy/qualcomm/phy-qcom-usb-hsic.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/phy/qualcomm/phy-qcom-usb-hsic.c +4 -2
@@ -54,8 +54,10 @@ static int qcom_usb_hsic_phy_power_on(struct phy *phy)/* Configure pins for HSIC functionality */ pins_default =pinctrl_lookup_state (uphy->pctl,PINCTRL_STATE_DEFAULT ); -if (IS_ERR (pins_default)) -return PTR_ERR (pins_default); +if (IS_ERR (pins_default)) { + ret =PTR_ERR (pins_default); + goto err_ulpi; + } ret =pinctrl_select_state (uphy->pctl, pins_default);if (ret)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 328/530 staging: vt6655: fix some erroneous memory clean-up loops
In reply to Greg Kroah-HartmanFrom: Nam Cao <[email protected]>
[ Upstream commit 2a2db520e3ca5aafba7c211abfd397666c9b5f9d ]
In some initialization functions of this driver, memory is allocated with 'i' acting as an index variable and increasing from 0. The commit in "Fixes" introduces some clean-up codes in case of allocation failure, which free memory in reverse order with 'i' decreasing to 0. However, there are some problems:
- The case i=0 is left out. Thus memory is leaked.
- In case memory allocation fails right from the start, the memory freeing loops will start with i=-1 and invalid memory locations will be accessed.
One of these loops has been fixed in commit c8ff91535880 ("staging:
vt6655: fix potential memory leak"). Fix the remaining erroneous loops.
--- drivers/staging/vt6655/device_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/staging/vt6655/device_main.c +3 -3
@@ -565,7 +565,7 @@ static int device_init_rd0_ring(struct vnt_private *priv)kfree (desc->rd_info); err_free_desc: -while (--i) { +while (i--) { desc = &priv->aRD0Ring[i];device_free_rx_buf (priv, desc);kfree (desc->rd_info);
@@ -611,7 +611,7 @@ static int device_init_rd1_ring(struct vnt_private *priv)kfree (desc->rd_info); err_free_desc: -while (--i) { +while (i--) { desc = &priv->aRD1Ring[i];device_free_rx_buf (priv, desc);kfree (desc->rd_info);
@@ -716,7 +716,7 @@ static int device_init_td1_ring(struct vnt_private *priv)return 0 ; err_free_desc: -while (--i) { +while (i--) { desc = &priv->apTD1Rings[i];kfree (desc->td_info); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 329/530 slimbus: qcom-ngd-ctrl: allow compile testing without QCOM_RPROC_COMMON
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
[ Upstream commit e291691c69776ad278cd39dec2306dd39d681a9f ]
The Qualcomm common remote-proc code (CONFIG_QCOM_RPROC_COMMON) has necessary stubs, so it is not needed for compile testing.
Stable-dep-of: 42992cf187e4 ("slimbus: qcom-ngd: Add error handling in of_qcom_slim_ngd_register")
--- drivers/slimbus/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/slimbus/Kconfig +2 -1
@@ -22,7 +22,8 @@ config SLIM_QCOM_CTRL config SLIM_QCOM_NGD_CTRL tristate "Qualcomm SLIMbus Satellite Non-Generic Device Component" - depends on HAS_IOMEM && DMA_ENGINE && NET && QCOM_RPROC_COMMON + depends on HAS_IOMEM && DMA_ENGINE && NET + depends on QCOM_RPROC_COMMON || COMPILE_TEST depends on ARCH_QCOM || COMPILE_TEST select QCOM_QMI_HELPERS select QCOM_PDR_HELPERS
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 330/530 firmware: google: Test spinlock on panic path to avoid lockups
In reply to Greg Kroah-HartmanFrom: Guilherme G. Piccoli <[email protected]>
[ Upstream commit 3e081438b8e639cc76ef1a5ce0c1bd8a154082c7 ]
Currently the gsmi driver registers a panic notifier as well as reboot and die notifiers. The callbacks registered are called in atomic and very limited context - for instance, panic disables preemption and local IRQs, also all secondary CPUs (not executing the panic path) are shutdown.
With that said, taking a spinlock in this scenario is a dangerous invitation for lockup scenarios. So, fix that by checking if the spinlock is free to acquire in the panic notifier callback - if not, bail-out and avoid a potential hang.
--- drivers/firmware/google/gsmi.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/firmware/google/gsmi.c +9 -0
@@ -681,6 +681,15 @@ static struct notifier_block gsmi_die_notifier = {static int gsmi_panic_callback (struct notifier_block *nb,unsigned long reason,void *arg) { + +/* +* Panic callbacks are executed with all other CPUs stopped, +* so we must not attempt to spin waiting for gsmi_dev.lock +* to be released. +*/ +if (spin_is_locked (&gsmi_dev.lock)) +return NOTIFY_DONE ; +gsmi_shutdown_reason (GSMI_SHUTDOWN_PANIC );return NOTIFY_DONE ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 331/530 serial: 8250: Fix restoring termios speed after suspend
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit 379a33786d489ab81885ff0b3935cfeb36137fea ]
Since commit edc6afc54968 ("tty: switch to ktermios and new framework") termios speed is no longer stored only in c_cflag member but also in new additional c_ispeed and c_ospeed members. If BOTHER flag is set in c_cflag then termios speed is stored only in these new members.
Since commit 027b57170bf8 ("serial: core: Fix initializing and restoring termios speed") termios speed is available also in struct console.
So properly restore also c_ispeed and c_ospeed members after suspend to fix restoring termios speed which is not represented by Bnnn constant.
--- drivers/tty/serial/8250/8250_port.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/tty/serial/8250/8250_port.c +6 -1
@@ -3318,8 +3318,13 @@ static void serial8250_console_restore(struct uart_8250_port *up)unsigned int baud, quot, frac =0 ; termios.c_cflag = port->cons->cflag; -if (port->state->port.tty && termios.c_cflag ==0 ) + termios.c_ispeed = port->cons->ispeed; + termios.c_ospeed = port->cons->ospeed; +if (port->state->port.tty && termios.c_cflag ==0 ) { termios.c_cflag = port->state->port.tty->termios.c_cflag; + termios.c_ispeed = port->state->port.tty->termios.c_ispeed; + termios.c_ospeed = port->state->port.tty->termios.c_ospeed; + } baud =serial8250_get_baud_rate (port, &termios,NULL ); quot =serial8250_get_divisor (port, baud, &frac);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 332/530 scsi: libsas: Fix use-after-free bug in smp_execute_task_sg()
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit 46ba53c30666717cb06c2b3c5d896301cd00d0c0 ]
When executing SMP task failed, the smp_execute_task_sg() calls del_timer() to delete "slow_task->timer". However, if the timer handler sas_task_internal_timedout() is running, the del_timer() in smp_execute_task_sg() will not stop it and a UAF will happen. The process is shown below:
(thread 1) | (thread 2)
smp_execute_task_sg() | sas_task_internal_timedout()
... |
del_timer() |
... | ...
sas_free_task(task) |
kfree(task->slow_task) //FREE|
| task->slow_task->... //USEFix by calling del_timer_sync() in smp_execute_task_sg(), which makes sure the timer handler have finished before the "task->slow_task" is deallocated.
--- drivers/scsi/libsas/sas_expander.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/libsas/sas_expander.c +1 -1
@@ -85,7 +85,7 @@ static int smp_execute_task_sg(struct domain_device *dev, res = i->dft->lldd_execute_task (task,GFP_KERNEL );if (res) { -del_timer (&task->slow_task->timer); +del_timer_sync (&task->slow_task->timer);pr_notice ("executing SMP task failed:%d\n" , res);break ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 333/530 scsi: iscsi: Rename iscsi_conn_queue_work()
In reply to Greg Kroah-HartmanFrom: Mike Christie <[email protected]>
[ Upstream commit 4b9f8ce4d5e823e42944c5a0a4842b0f936365ad ]
Rename iscsi_conn_queue_work() to iscsi_conn_queue_xmit() to reflect that it handles queueing of xmits only.
Stable-dep-of: 57569c37f0ad ("scsi: iscsi: iscsi_tcp: Fix null-ptr-deref while calling getpeername()")
--- drivers/scsi/cxgbi/libcxgbi.c | 2 +- drivers/scsi/iscsi_tcp.c | 2 +- drivers/scsi/libiscsi.c | 12 ++++++------ include/scsi/libiscsi.h | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-)
drivers/scsi/cxgbi/libcxgbi.c +1 -1
@@ -1455,7 +1455,7 @@ void cxgbi_conn_tx_open(struct cxgbi_sock *csk)if (conn) {log_debug (1 <<CXGBI_DBG_SOCK ,"csk 0x%p, cid %d.\n" , csk, conn->id); -iscsi_conn_queue_work (conn); +iscsi_conn_queue_xmit (conn); } }EXPORT_SYMBOL_GPL (cxgbi_conn_tx_open);
drivers/scsi/iscsi_tcp.c +1 -1
@@ -205,7 +205,7 @@ static void iscsi_sw_tcp_write_space(struct sock *sk)old_write_space (sk);ISCSI_SW_TCP_DBG (conn,"iscsi_write_space\n" ); -iscsi_conn_queue_work (conn); +iscsi_conn_queue_xmit (conn); }static void iscsi_sw_tcp_conn_set_callbacks (struct iscsi_conn *conn)
drivers/scsi/libiscsi.c +6 -6
@@ -83,7 +83,7 @@ MODULE_PARM_DESC(debug_libiscsi_eh, "%s " dbg_fmt, __func__, ##arg); \ }while (0 ); -inline void iscsi_conn_queue_work (struct iscsi_conn *conn) +inline void iscsi_conn_queue_xmit (struct iscsi_conn *conn) {struct Scsi_Host *shost = conn->session->host;struct iscsi_host *ihost =shost_priv (shost);
@@ -91,7 +91,7 @@ inline void iscsi_conn_queue_work(struct iscsi_conn *conn)if (ihost->workq)queue_work (ihost->workq, &conn->xmitwork); } -EXPORT_SYMBOL_GPL (iscsi_conn_queue_work); +EXPORT_SYMBOL_GPL (iscsi_conn_queue_xmit);static void __iscsi_update_cmdsn (struct iscsi_session *session,uint32_t exp_cmdsn,uint32_t max_cmdsn)
@@ -765,7 +765,7 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, goto free_task; }else {list_add_tail (&task->running, &conn->mgmtqueue); -iscsi_conn_queue_work (conn); +iscsi_conn_queue_xmit (conn); }return task;
@@ -1513,7 +1513,7 @@ void iscsi_requeue_task(struct iscsi_task *task)*/ iscsi_put_task (task); } -iscsi_conn_queue_work (conn); +iscsi_conn_queue_xmit (conn);spin_unlock_bh (&conn->session->frwd_lock); }EXPORT_SYMBOL_GPL (iscsi_requeue_task);
@@ -1782,7 +1782,7 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc) } }else {list_add_tail (&task->running, &conn->cmdqueue); -iscsi_conn_queue_work (conn); +iscsi_conn_queue_xmit (conn); } session->queued_cmdsn++;
@@ -1963,7 +1963,7 @@ EXPORT_SYMBOL_GPL(iscsi_suspend_tx);static void iscsi_start_tx (struct iscsi_conn *conn) {clear_bit (ISCSI_CONN_FLAG_SUSPEND_TX , &conn->flags); -iscsi_conn_queue_work (conn); +iscsi_conn_queue_xmit (conn); }/*
include/scsi/libiscsi.h +1 -1
@@ -442,7 +442,7 @@ extern int iscsi_conn_get_addr_param(struct sockaddr_storage *addr, enum iscsi_param param, char *buf);extern void iscsi_suspend_tx (struct iscsi_conn *conn);extern void iscsi_suspend_queue (struct iscsi_conn *conn); -extern void iscsi_conn_queue_work (struct iscsi_conn *conn); +extern void iscsi_conn_queue_xmit (struct iscsi_conn *conn); #define iscsi_conn_printk(prefix, _c, fmt, a...) \ iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 334/530 scsi: iscsi: Add recv workqueue helpers
In reply to Greg Kroah-HartmanFrom: Mike Christie <[email protected]>
[ Upstream commit 8af809966c0b34cfacd8da9a412689b8e9910354 ]
Add helpers to allow the drivers to run their recv paths from libiscsi's workqueue.
Stable-dep-of: 57569c37f0ad ("scsi: iscsi: iscsi_tcp: Fix null-ptr-deref while calling getpeername()")
--- drivers/scsi/libiscsi.c | 29 +++++++++++++++++++++++++++-- include/scsi/libiscsi.h | 4 ++++ 2 files changed, 31 insertions(+), 2 deletions(-)
drivers/scsi/libiscsi.c +27 -2
@@ -93,6 +93,16 @@ inline void iscsi_conn_queue_xmit(struct iscsi_conn *conn) }EXPORT_SYMBOL_GPL (iscsi_conn_queue_xmit); +inline void iscsi_conn_queue_recv (struct iscsi_conn *conn) +{ +struct Scsi_Host *shost = conn->session->host; +struct iscsi_host *ihost =shost_priv (shost); + +if (ihost->workq && !test_bit (ISCSI_CONN_FLAG_SUSPEND_RX , &conn->flags)) +queue_work (ihost->workq, &conn->recvwork); +} +EXPORT_SYMBOL_GPL (iscsi_conn_queue_recv); +static void __iscsi_update_cmdsn (struct iscsi_session *session,uint32_t exp_cmdsn,uint32_t max_cmdsn) {
@@ -1943,7 +1953,7 @@ EXPORT_SYMBOL_GPL(iscsi_suspend_queue);/** * iscsi_suspend_tx - suspend iscsi_data_xmit -* @conn: iscsi conn tp stop processing IO on. +* @conn: iscsi conn to stop processing IO on. * * This function sets the suspend bit to prevent iscsi_data_xmit * from sending new IO, and if work is queued on the xmit thread
@@ -1956,7 +1966,7 @@ void iscsi_suspend_tx(struct iscsi_conn *conn)set_bit (ISCSI_CONN_FLAG_SUSPEND_TX , &conn->flags);if (ihost->workq) -flush_workqueue (ihost->workq); +flush_work (&conn->xmitwork); }EXPORT_SYMBOL_GPL (iscsi_suspend_tx);
@@ -1966,6 +1976,21 @@ static void iscsi_start_tx(struct iscsi_conn *conn)iscsi_conn_queue_xmit (conn); } +/** +* iscsi_suspend_rx - Prevent recvwork from running again. +* @conn: iscsi conn to stop. +*/ +void iscsi_suspend_rx (struct iscsi_conn *conn) +{ +struct Scsi_Host *shost = conn->session->host; +struct iscsi_host *ihost =shost_priv (shost); + +set_bit (ISCSI_CONN_FLAG_SUSPEND_RX , &conn->flags); +if (ihost->workq) +flush_work (&conn->recvwork); +} +EXPORT_SYMBOL_GPL (iscsi_suspend_rx); +/* * We want to make sure a ping is in flight. It has timed out. * And we are not busy processing a pdu that is making
include/scsi/libiscsi.h +4 -0
@@ -201,6 +201,8 @@ struct iscsi_conn {struct list_head cmdqueue;/* data-path cmd queue */ struct list_head requeue;/* tasks needing another run */ struct work_struct xmitwork;/* per-conn. xmit workqueue */ +/* recv */ +struct work_struct recvwork;unsigned long flags;/* ISCSI_CONN_FLAGs */ /* negotiated params */
@@ -441,8 +443,10 @@ extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,extern int iscsi_conn_get_addr_param (struct sockaddr_storage *addr,enum iscsi_param param,char *buf);extern void iscsi_suspend_tx (struct iscsi_conn *conn); +extern void iscsi_suspend_rx (struct iscsi_conn *conn);extern void iscsi_suspend_queue (struct iscsi_conn *conn);extern void iscsi_conn_queue_xmit (struct iscsi_conn *conn); +extern void iscsi_conn_queue_recv (struct iscsi_conn *conn); #define iscsi_conn_printk(prefix, _c, fmt, a...) \ iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 335/530 scsi: iscsi: Run recv path from workqueue
In reply to Greg Kroah-HartmanFrom: Mike Christie <[email protected]>
[ Upstream commit f1d269765ee29da56b32818b7a08054484ed89f2 ]
We don't always want to run the recv path from the network softirq because when we have to have multiple sessions sharing the same CPUs, some sessions can eat up the NAPI softirq budget and affect other sessions or users.
Allow us to queue the recv handling to the iscsi workqueue so we can have the scheduler/wq code try to balance the work and CPU use across all sessions' worker threads.
Note: It wasn't the original intent of the change but a nice side effect is that for some workloads/configs we get a nice performance boost. For a simple read heavy test:
fio --direct=1 --filename=/dev/dm-0 --rw=randread --bs=256K
--ioengine=libaio --iodepth=128 --numjobs=4where the iscsi threads, fio jobs, and rps_cpus share CPUs we see a 32% throughput boost. We also see increases for small I/O IOPs tests but it's not as high.
Stable-dep-of: 57569c37f0ad ("scsi: iscsi: iscsi_tcp: Fix null-ptr-deref while calling getpeername()")
--- drivers/scsi/iscsi_tcp.c | 65 ++++++++++++++++++++++++++++++++-------- drivers/scsi/iscsi_tcp.h | 2 ++ 2 files changed, 54 insertions(+), 13 deletions(-)
drivers/scsi/iscsi_tcp.c +52 -13
@@ -52,6 +52,10 @@ static struct iscsi_transport iscsi_sw_tcp_transport;static unsigned int iscsi_max_lun = ~0 ;module_param_named (max_lun, iscsi_max_lun, uint,S_IRUGO ); +static bool iscsi_recv_from_iscsi_q; +module_param_named (recv_from_iscsi_q, iscsi_recv_from_iscsi_q, bool,0644 ); +MODULE_PARM_DESC (recv_from_iscsi_q,"Set to true to read iSCSI data/headers from the iscsi_q workqueue. The default is false which will perform reads from the network softirq context." ); +static int iscsi_sw_tcp_dbg;module_param_named (debug_iscsi_tcp, iscsi_sw_tcp_dbg, int,S_IRUGO |S_IWUSR );
@@ -122,20 +126,13 @@ static inline int iscsi_sw_sk_state_check(struct sock *sk)return 0 ; } -static void iscsi_sw_tcp_data_ready (struct sock *sk) +static void iscsi_sw_tcp_recv_data (struct iscsi_conn *conn) { -struct iscsi_conn *conn; -struct iscsi_tcp_conn *tcp_conn; +struct iscsi_tcp_conn *tcp_conn = conn->dd_data; +struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; +struct sock *sk = tcp_sw_conn->sock->sk;read_descriptor_t rd_desc; -read_lock_bh (&sk->sk_callback_lock); - conn = sk->sk_user_data; -if (!conn) { -read_unlock_bh (&sk->sk_callback_lock); -return ; - } - tcp_conn = conn->dd_data; -/* * Use rd_desc to pass 'conn' to iscsi_tcp_recv. * We set count to 1 because we want the network layer to
@@ -144,13 +141,48 @@ static void iscsi_sw_tcp_data_ready(struct sock *sk)*/ rd_desc.arg.data = conn; rd_desc.count =1 ; -tcp_read_sock (sk, &rd_desc, iscsi_sw_tcp_recv); -iscsi_sw_sk_state_check (sk); +tcp_read_sock (sk, &rd_desc, iscsi_sw_tcp_recv);/* If we had to (atomically) map a highmem page, * unmap it now. */ iscsi_tcp_segment_unmap (&tcp_conn->in.segment); + +iscsi_sw_sk_state_check (sk); +} + +static void iscsi_sw_tcp_recv_data_work (struct work_struct *work) +{ + struct iscsi_conn *conn = container_of(work, struct iscsi_conn, + recvwork); +struct iscsi_tcp_conn *tcp_conn = conn->dd_data; +struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; +struct sock *sk = tcp_sw_conn->sock->sk; + +lock_sock (sk); +iscsi_sw_tcp_recv_data (conn); +release_sock (sk); +} + +static void iscsi_sw_tcp_data_ready (struct sock *sk) +{ +struct iscsi_sw_tcp_conn *tcp_sw_conn; +struct iscsi_tcp_conn *tcp_conn; +struct iscsi_conn *conn; + +read_lock_bh (&sk->sk_callback_lock); + conn = sk->sk_user_data; +if (!conn) { +read_unlock_bh (&sk->sk_callback_lock); +return ; + } + tcp_conn = conn->dd_data; + tcp_sw_conn = tcp_conn->dd_data; + +if (tcp_sw_conn->queue_recv) +iscsi_conn_queue_recv (conn); +else +iscsi_sw_tcp_recv_data (conn);read_unlock_bh (&sk->sk_callback_lock); }
@@ -276,6 +308,9 @@ static int iscsi_sw_tcp_xmit_segment(struct iscsi_tcp_conn *tcp_conn,if (segment->total_copied + segment->size < segment->total_size) flags |=MSG_MORE ; +if (tcp_sw_conn->queue_recv) + flags |=MSG_DONTWAIT ; +/* Use sendpage if we can; else fall back to sendmsg */ if (!segment->data) { sg = segment->sg;
@@ -557,6 +592,8 @@ iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session, conn = cls_conn->dd_data; tcp_conn = conn->dd_data; tcp_sw_conn = tcp_conn->dd_data; +INIT_WORK (&conn->recvwork, iscsi_sw_tcp_recv_data_work); + tcp_sw_conn->queue_recv = iscsi_recv_from_iscsi_q; tfm =crypto_alloc_ahash ("crc32c" ,0 ,CRYPTO_ALG_ASYNC );if (IS_ERR (tfm))
@@ -610,6 +647,8 @@ static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn)iscsi_sw_tcp_conn_restore_callbacks (conn);sock_put (sock->sk); +iscsi_suspend_rx (conn); +spin_lock_bh (&session->frwd_lock); tcp_sw_conn->sock =NULL ;spin_unlock_bh (&session->frwd_lock);
drivers/scsi/iscsi_tcp.h +2 -0
@@ -28,6 +28,8 @@ struct iscsi_sw_tcp_send {struct iscsi_sw_tcp_conn {struct socket *sock; +struct work_struct recvwork; +bool queue_recv;struct iscsi_sw_tcp_send out;/* old values for socket callbacks */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 336/530 scsi: iscsi: iscsi_tcp: Fix null-ptr-deref while calling getpeername()
In reply to Greg Kroah-HartmanFrom: Mike Christie <[email protected]>
[ Upstream commit 57569c37f0add1b6489e1a1563c71519daf732cf ]
Fix a NULL pointer crash that occurs when we are freeing the socket at the same time we access it via sysfs.
The problem is that:
1. iscsi_sw_tcp_conn_get_param() and iscsi_sw_tcp_host_get_param() take the frwd_lock and do sock_hold() then drop the frwd_lock. sock_hold() does a get on the "struct sock".
2. iscsi_sw_tcp_release_conn() does sockfd_put() which does the last put on the "struct socket" and that does __sock_release() which sets the sock->ops to NULL.
3. iscsi_sw_tcp_conn_get_param() and iscsi_sw_tcp_host_get_param() then
call kernel_getpeername() which accesses the NULL sock->ops.
Above we do a get on the "struct sock", but we needed a get on the "struct socket". Originally, we just held the frwd_lock the entire time but in commit bcf3a2953d36 ("scsi: iscsi: iscsi_tcp: Avoid holding spinlock while calling getpeername()") we switched to refcount based because the network layer changed and started taking a mutex in that path, so we could no longer hold the frwd_lock.
Instead of trying to maintain multiple refcounts, this just has us use a mutex for accessing the socket in the interface code paths.
--- drivers/scsi/iscsi_tcp.c | 73 ++++++++++++++++++++++++++++------------ drivers/scsi/iscsi_tcp.h | 3 ++ 2 files changed, 55 insertions(+), 21 deletions(-)
drivers/scsi/iscsi_tcp.c +52 -21
@@ -595,6 +595,8 @@ iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session,INIT_WORK (&conn->recvwork, iscsi_sw_tcp_recv_data_work); tcp_sw_conn->queue_recv = iscsi_recv_from_iscsi_q; +mutex_init (&tcp_sw_conn->sock_lock); + tfm =crypto_alloc_ahash ("crc32c" ,0 ,CRYPTO_ALG_ASYNC );if (IS_ERR (tfm)) goto free_conn;
@@ -629,11 +631,15 @@ iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session,static void iscsi_sw_tcp_release_conn (struct iscsi_conn *conn) { -struct iscsi_session *session = conn->session;struct iscsi_tcp_conn *tcp_conn = conn->dd_data;struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;struct socket *sock = tcp_sw_conn->sock; +/* +* The iscsi transport class will make sure we are not called in +* parallel with start, stop, bind and destroys. However, this can be +* called twice if userspace does a stop then a destroy. +*/ if (!sock)return ;
@@ -649,9 +655,9 @@ static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn)iscsi_suspend_rx (conn); -spin_lock_bh (&session->frwd_lock); +mutex_lock (&tcp_sw_conn->sock_lock); tcp_sw_conn->sock =NULL ; -spin_unlock_bh (&session->frwd_lock); +mutex_unlock (&tcp_sw_conn->sock_lock);sockfd_put (sock); }
@@ -703,7 +709,6 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session, struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, int is_leading) { - struct iscsi_session *session = cls_session->dd_data; struct iscsi_conn *conn = cls_conn->dd_data;struct iscsi_tcp_conn *tcp_conn = conn->dd_data;struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
@@ -723,10 +728,10 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session,if (err) goto free_socket; -spin_lock_bh (&session->frwd_lock); +mutex_lock (&tcp_sw_conn->sock_lock);/* bind iSCSI connection and socket */ tcp_sw_conn->sock = sock; -spin_unlock_bh (&session->frwd_lock); +mutex_unlock (&tcp_sw_conn->sock_lock);/* setup Socket parameters */ sk = sock->sk;
@@ -763,8 +768,15 @@ static int iscsi_sw_tcp_conn_set_param(struct iscsi_cls_conn *cls_conn,break ;case ISCSI_PARAM_DATADGST_EN :iscsi_set_param (cls_conn, param, buf, buflen); + +mutex_lock (&tcp_sw_conn->sock_lock); +if (!tcp_sw_conn->sock) { +mutex_unlock (&tcp_sw_conn->sock_lock); +return -ENOTCONN ; + } tcp_sw_conn->sendpage = conn->datadgst_en ? sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage; +mutex_unlock (&tcp_sw_conn->sock_lock);break ;case ISCSI_PARAM_MAX_R2T :return iscsi_tcp_set_max_r2t (conn, buf);
@@ -779,8 +791,8 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, char *buf) { struct iscsi_conn *conn = cls_conn->dd_data; -struct iscsi_tcp_conn *tcp_conn = conn->dd_data; -struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; +struct iscsi_sw_tcp_conn *tcp_sw_conn; +struct iscsi_tcp_conn *tcp_conn;struct sockaddr_in6 addr;struct socket *sock;int rc;
@@ -790,21 +802,36 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,case ISCSI_PARAM_CONN_ADDRESS :case ISCSI_PARAM_LOCAL_PORT :spin_lock_bh (&conn->session->frwd_lock); -if (!tcp_sw_conn || !tcp_sw_conn->sock) { +if (!conn->session->leadconn) {spin_unlock_bh (&conn->session->frwd_lock);return -ENOTCONN ; } - sock = tcp_sw_conn->sock; -sock_hold (sock->sk); +/* +* The conn has been setup and bound, so just grab a ref +* incase a destroy runs while we are in the net layer. +*/ +iscsi_get_conn (conn->cls_conn);spin_unlock_bh (&conn->session->frwd_lock); + tcp_conn = conn->dd_data; + tcp_sw_conn = tcp_conn->dd_data; + +mutex_lock (&tcp_sw_conn->sock_lock); + sock = tcp_sw_conn->sock; +if (!sock) { + rc = -ENOTCONN ; + goto sock_unlock; + } +if (param ==ISCSI_PARAM_LOCAL_PORT ) rc =kernel_getsockname (sock, (struct sockaddr *)&addr);else rc =kernel_getpeername (sock, (struct sockaddr *)&addr); -sock_put (sock->sk); +sock_unlock: +mutex_unlock (&tcp_sw_conn->sock_lock); +iscsi_put_conn (conn->cls_conn);if (rc <0 )return rc;
@@ -842,17 +869,21 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host *shost, } tcp_conn = conn->dd_data; tcp_sw_conn = tcp_conn->dd_data; - sock = tcp_sw_conn->sock; -if (!sock) { -spin_unlock_bh (&session->frwd_lock); -return -ENOTCONN ; - } -sock_hold (sock->sk); +/* +* The conn has been setup and bound, so just grab a ref +* incase a destroy runs while we are in the net layer. +*/ +iscsi_get_conn (conn->cls_conn);spin_unlock_bh (&session->frwd_lock); - rc =kernel_getsockname (sock, - (struct sockaddr *)&addr); -sock_put (sock->sk); +mutex_lock (&tcp_sw_conn->sock_lock); + sock = tcp_sw_conn->sock; +if (!sock) + rc = -ENOTCONN ; +else + rc =kernel_getsockname (sock, (struct sockaddr *)&addr); +mutex_unlock (&tcp_sw_conn->sock_lock); +iscsi_put_conn (conn->cls_conn);if (rc <0 )return rc;
drivers/scsi/iscsi_tcp.h +3 -0
@@ -28,6 +28,9 @@ struct iscsi_sw_tcp_send {struct iscsi_sw_tcp_conn {struct socket *sock; +/* Taken when accessing the sock from the netlink/sysfs interface */ +struct mutex sock_lock; +struct work_struct recvwork;bool queue_recv;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 337/530 clk: qcom: apss-ipq6018: mark apcs_alias0_core_clk as critical
In reply to Greg Kroah-HartmanFrom: Robert Marko <[email protected]>
[ Upstream commit 86e78995c93ee182433f965babfccd48417d4dcf ]
While fixing up the driver I noticed that my IPQ8074 board was hanging after CPUFreq switched the frequency during boot, WDT would eventually reset it.
So mark apcs_alias0_core_clk as critical since its the clock feeding the CPU cluster and must never be disabled.
--- drivers/clk/qcom/apss-ipq6018.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/qcom/apss-ipq6018.c +1 -1
@@ -57,7 +57,7 @@ static struct clk_branch apcs_alias0_cor .parent_hws = (const struct clk_hw *[]){ &apcs_alias0_clk_src.clkr.hw }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, },
Greg Kroah-Hartman
maintainerPATCH 338/530 clk: qcom: gcc-sm6115: Override default Alpha PLL regs
In reply to Greg Kroah-HartmanFrom: Adam Skladowski <[email protected]>
[ Upstream commit 068a0605ef5a6b430e7278c169bfcd25b680b28f ]
The DEFAULT and BRAMMO PLL offsets are non-standard in downstream, but currently only BRAMMO ones are overridden. Override DEFAULT ones too.
A very similar thing is happening in gcc-qcm2290 driver.
--- drivers/clk/qcom/gcc-sm6115.c | 46 +++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 16 deletions(-)
drivers/clk/qcom/gcc-sm6115.c +30 -16
@@ -53,11 +53,25 @@ static struct pll_vco gpll10_vco[] = { { 750000000, 1500000000, 1 }, }; +static const u8 clk_alpha_pll_regs_offset[][PLL_OFF_MAX_REGS] = { + [CLK_ALPHA_PLL_TYPE_DEFAULT] = { + [PLL_OFF_L_VAL] = 0x04, + [PLL_OFF_ALPHA_VAL] = 0x08, + [PLL_OFF_ALPHA_VAL_U] = 0x0c, + [PLL_OFF_TEST_CTL] = 0x10, + [PLL_OFF_TEST_CTL_U] = 0x14, + [PLL_OFF_USER_CTL] = 0x18, + [PLL_OFF_USER_CTL_U] = 0x1c, + [PLL_OFF_CONFIG_CTL] = 0x20, + [PLL_OFF_STATUS] = 0x24, + }, +}; + static struct clk_alpha_pll gpll0 = { .offset = 0x0, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(0),
@@ -83,7 +97,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_aux2 = { .post_div_table = post_div_table_gpll0_out_aux2, .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_aux2), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll0_out_aux2" , .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
@@ -115,7 +129,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_main = { .post_div_table = post_div_table_gpll0_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll0_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
@@ -137,7 +151,7 @@ static struct clk_alpha_pll gpll10 = { .offset = 0xa000, .vco_table = gpll10_vco, .num_vco = ARRAY_SIZE(gpll10_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(10),
@@ -163,7 +177,7 @@ static struct clk_alpha_pll_postdiv gpll10_out_main = { .post_div_table = post_div_table_gpll10_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll10_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll10_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll10.clkr.hw },
@@ -189,7 +203,7 @@ static struct clk_alpha_pll gpll11 = { .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), .flags = SUPPORTS_DYNAMIC_UPDATE, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(11),
@@ -215,7 +229,7 @@ static struct clk_alpha_pll_postdiv gpll11_out_main = { .post_div_table = post_div_table_gpll11_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll11_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll11_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll11.clkr.hw },
@@ -229,7 +243,7 @@ static struct clk_alpha_pll gpll3 = { .offset = 0x3000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(3),
@@ -248,7 +262,7 @@ static struct clk_alpha_pll gpll4 = { .offset = 0x4000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(4),
@@ -274,7 +288,7 @@ static struct clk_alpha_pll_postdiv gpll4_out_main = { .post_div_table = post_div_table_gpll4_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll4_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll4_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll4.clkr.hw },
@@ -287,7 +301,7 @@ static struct clk_alpha_pll gpll6 = { .offset = 0x6000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(6),
@@ -313,7 +327,7 @@ static struct clk_alpha_pll_postdiv gpll6_out_main = { .post_div_table = post_div_table_gpll6_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll6_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll6_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll6.clkr.hw },
@@ -326,7 +340,7 @@ static struct clk_alpha_pll gpll7 = { .offset = 0x7000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(7),
@@ -352,7 +366,7 @@ static struct clk_alpha_pll_postdiv gpll7_out_main = { .post_div_table = post_div_table_gpll7_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll7_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll7_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll7.clkr.hw },
@@ -380,7 +394,7 @@ static struct clk_alpha_pll gpll8 = { .offset = 0x8000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .flags = SUPPORTS_DYNAMIC_UPDATE, .clkr = { .enable_reg = 0x79000,
@@ -407,7 +421,7 @@ static struct clk_alpha_pll_postdiv gpll8_out_main = { .post_div_table = post_div_table_gpll8_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll8_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll8_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll8.clkr.hw },
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 339/530 RDMA/rxe: Fix resize_finish() in rxe_queue.c
In reply to Greg Kroah-HartmanFrom: Bob Pearson <[email protected]>
[ Upstream commit fda5d0cf8aef12f0a4f714a96a4b2fce039a3e55 ]
Currently in resize_finish() in rxe_queue.c there is a loop which copies the entries in the original queue into a newly allocated queue. The termination logic for this loop is incorrect. The call to queue_next_index() updates cons but has no effect on whether the queue is empty. So if the queue starts out empty nothing is copied but if it is not then the loop will run forever. This patch changes the loop to compare the value of cons to the original producer index.
--- drivers/infiniband/sw/rxe/rxe_queue.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/infiniband/sw/rxe/rxe_queue.c +7 -5
@@ -112,23 +112,25 @@ static int resize_finish(struct rxe_queue *q, struct rxe_queue *new_q, unsigned int num_elem) {enum queue_type type = q->type; +u32 new_prod;u32 prod;u32 cons;if (!queue_empty (q, q->type) && (num_elem <queue_count (q, type)))return -EINVAL ; - prod =queue_get_producer (new_q, type); + new_prod =queue_get_producer (new_q, type); + prod =queue_get_producer (q, type); cons =queue_get_consumer (q, type); -while (!queue_empty (q, type)) { -memcpy (queue_addr_from_index (new_q, prod), +while ((prod - cons) & q->index_mask) { +memcpy (queue_addr_from_index (new_q, new_prod),queue_addr_from_index (q, cons), new_q->elem_size); - prod =queue_next_index (new_q, prod); + new_prod =queue_next_index (new_q, new_prod); cons =queue_next_index (q, cons); } - new_q->buf->producer_index = prod; + new_q->buf->producer_index = new_prod; q->buf->consumer_index = cons;/* update private index copies */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 340/530 fsi: core: Check error number after calling ida_simple_get
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 35af9fb49bc5c6d61ef70b501c3a56fe161cce3e ]
If allocation fails, the ida_simple_get() will return error number. So master->idx could be error number and be used in dev_set_name(). Therefore, it should be better to check it and return error if fails, like the ida_simple_get() in __fsi_get_new_minor().
--- drivers/fsi/fsi-core.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/fsi/fsi-core.c +3 -0
@@ -1309,6 +1309,9 @@ int fsi_master_register(struct fsi_master *master)mutex_init (&master->scan_lock); master->idx =ida_simple_get (&master_ida,0 ,INT_MAX ,GFP_KERNEL ); +if (master->idx <0 ) +return master->idx; +dev_set_name (&master->dev,"fsi%d" , master->idx); master->dev.class = &fsi_master_class;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 341/530 mfd: intel_soc_pmic: Fix an error handling path in intel_soc_pmic_i2c_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 48749cabba109397b4e7dd556e85718ec0ec114d ]
The commit in Fixes: has added a pwm_add_table() call in the probe() and a pwm_remove_table() call in the remove(), but forget to update the error handling path of the probe.
Add the missing pwm_remove_table() call.
--- drivers/mfd/intel_soc_pmic_core.c | 1 + 1 file changed, 1 insertion(+)
drivers/mfd/intel_soc_pmic_core.c +1 -0
@@ -95,6 +95,7 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c,return 0 ; err_del_irq_chip: +pwm_remove_table (crc_pwm_lookup,ARRAY_SIZE (crc_pwm_lookup));regmap_del_irq_chip (pmic->irq, pmic->irq_chip_data);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 342/530 mfd: fsl-imx25: Fix an error handling path in mx25_tsadc_setup_irq()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 3fa9e4cfb55da512ebfd57336fde468830719298 ]
If devm_of_platform_populate() fails, some resources need to be released.
Introduce a mx25_tsadc_unset_irq() function that undoes mx25_tsadc_setup_irq() and call it both from the new error handling path of the probe and in the remove function.
--- drivers/mfd/fsl-imx25-tsadc.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-)
drivers/mfd/fsl-imx25-tsadc.c +24 -8
@@ -84,6 +84,19 @@ static int mx25_tsadc_setup_irq(struct platform_device *pdev,return 0 ; } +static int mx25_tsadc_unset_irq (struct platform_device *pdev) +{ +struct mx25_tsadc *tsadc =platform_get_drvdata (pdev); +int irq =platform_get_irq (pdev,0 ); + +if (irq) { +irq_set_chained_handler_and_data (irq,NULL ,NULL ); +irq_domain_remove (tsadc->domain); + } + +return 0 ; +} +static void mx25_tsadc_setup_clk (struct platform_device *pdev,struct mx25_tsadc *tsadc) {
@@ -171,18 +184,21 @@ static int mx25_tsadc_probe(struct platform_device *pdev)platform_set_drvdata (pdev, tsadc); -return devm_of_platform_populate (dev); + ret =devm_of_platform_populate (dev); +if (ret) + goto err_irq; + +return 0 ; + +err_irq: +mx25_tsadc_unset_irq (pdev); + +return ret; }static int mx25_tsadc_remove (struct platform_device *pdev) { -struct mx25_tsadc *tsadc =platform_get_drvdata (pdev); -int irq =platform_get_irq (pdev,0 ); - -if (irq) { -irq_set_chained_handler_and_data (irq,NULL ,NULL ); -irq_domain_remove (tsadc->domain); - } +mx25_tsadc_unset_irq (pdev);return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 343/530 mfd: lp8788: Fix an error handling path in lp8788_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit becfdcd75126b20b8ec10066c5e85b34f8994ad5 ]
Should an error occurs in mfd_add_devices(), some resources need to be released, as already done in the .remove() function.
Add an error handling path and a lp8788_irq_exit() call to undo a previous lp8788_irq_init().
--- drivers/mfd/lp8788.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/mfd/lp8788.c +10 -2
@@ -195,8 +195,16 @@ static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id)if (ret)return ret; -return mfd_add_devices (lp->dev,-1 , lp8788_devs, -ARRAY_SIZE (lp8788_devs),NULL ,0 ,NULL ); + ret =mfd_add_devices (lp->dev,-1 , lp8788_devs, +ARRAY_SIZE (lp8788_devs),NULL ,0 ,NULL ); +if (ret) + goto err_exit_irq; + +return 0 ; + +err_exit_irq: +lp8788_irq_exit (lp); +return ret; }static int lp8788_remove (struct i2c_client *cl)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 344/530 mfd: lp8788: Fix an error handling path in lp8788_irq_init() and lp8788_irq_init()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 557244f6284f30613f2d61f14b579303165876c3 ]
In lp8788_irq_init(), if an error occurs after a successful irq_domain_add_linear() call, it must be undone by a corresponding irq_domain_remove() call.
irq_domain_remove() should also be called in lp8788_irq_exit() for the same reason.
--- drivers/mfd/lp8788-irq.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/mfd/lp8788-irq.c +3 -0
@@ -175,6 +175,7 @@ int lp8788_irq_init(struct lp8788 *lp, int irq)IRQF_TRIGGER_FALLING |IRQF_ONESHOT , "lp8788-irq", irqd);if (ret) { +irq_domain_remove (lp->irqdm);dev_err (lp->dev,"failed to create a thread for IRQ_N\n" );return ret; }
@@ -188,4 +189,6 @@ void lp8788_irq_exit(struct lp8788 *lp) {if (lp->irq)free_irq (lp->irq, lp->irqdm); +if (lp->irqdm) +irq_domain_remove (lp->irqdm); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 345/530 mfd: fsl-imx25: Fix check for platform_get_irq() errors
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 75db7907355ca5e2ff606e9dd3e86b6c3a455fe2 ]
The mx25_tsadc_remove() function assumes all non-zero returns are success but the platform_get_irq() function returns negative on error and positive non-zero values on success. It never returns zero, but if it did then treat that as a success.
--- drivers/mfd/fsl-imx25-tsadc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mfd/fsl-imx25-tsadc.c +2 -2
@@ -69,7 +69,7 @@ static int mx25_tsadc_setup_irq(struct platform_device *pdev,int irq; irq =platform_get_irq (pdev,0 ); -if (irq <=0 ) +if (irq <0 )return irq; tsadc->domain = irq_domain_add_simple(np, 2, 0, &mx25_tsadc_domain_ops,
@@ -89,7 +89,7 @@ static int mx25_tsadc_unset_irq(struct platform_device *pdev)struct mx25_tsadc *tsadc =platform_get_drvdata (pdev);int irq =platform_get_irq (pdev,0 ); -if (irq) { +if (irq >=0 ) {irq_set_chained_handler_and_data (irq,NULL ,NULL );irq_domain_remove (tsadc->domain); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 346/530 mfd: sm501: Add check for platform_driver_register()
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 8325a6c24ad78b8c1acc3c42b098ee24105d68e5 ]
As platform_driver_register() can return error numbers, it should be better to check platform_driver_register() and deal with the exception.
--- drivers/mfd/sm501.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/mfd/sm501.c +6 -1
@@ -1720,7 +1720,12 @@ static struct platform_driver sm501_plat_driver = {static int __init sm501_base_init (void ) { -platform_driver_register (&sm501_plat_driver); +int ret; + + ret =platform_driver_register (&sm501_plat_driver); +if (ret <0 ) +return ret; +return pci_register_driver (&sm501_pci_driver); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 347/530 clk: mediatek: mt8183: mfgcfg: Propagate rate changes to parent
In reply to Greg Kroah-HartmanFrom: Chen-Yu Tsai <[email protected]>
[ Upstream commit 9f94f545f258b15bfa6357eb62e1e307b712851e ]
The only clock in the MT8183 MFGCFG block feeds the GPU. Propagate its rate change requests to its parent, so that DVFS for the GPU can work properly.
--- drivers/clk/mediatek/clk-mt8183-mfgcfg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/mediatek/clk-mt8183-mfgcfg.c +3 -3
@@ -18,9 +18,9 @@ static const struct mtk_gate_regs mfg_cg_regs = { .sta_ofs = 0x0, }; -#define GATE_MFG (_id, _name, _parent, _shift) \ - GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, \ - &mtk_clk_gate_ops_setclr) +#define GATE_MFG (_id, _name, _parent, _shift) \ + GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr, CLK_SET_RATE_PARENT)static const struct mtk_gate mfg_clks[] = {GATE_MFG (CLK_MFG_BG3D ,"mfg_bg3d" ,"mfg_sel" ,0 )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 348/530 dmaengine: ioat: stop mod_timer from resurrecting deleted timer in __cleanup()
In reply to Greg Kroah-HartmanFrom: Dave Jiang <[email protected]>
[ Upstream commit 898ec89dbb55b8294695ad71694a0684e62b2a73 ]
User reports observing timer event report channel halted but no error observed in CHANERR register. The driver finished self-test and released channel resources. Debug shows that __cleanup() can call mod_timer() after the timer has been deleted and thus resurrect the timer. While harmless, it causes suprious error message to be emitted. Use mod_timer_pending() call to prevent deleted timer from being resurrected.
--- drivers/dma/ioat/dma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/dma/ioat/dma.c +3 -3
@@ -656,7 +656,7 @@ static void __cleanup(struct ioatdma_chan *ioat_chan, dma_addr_t phys_complete)if (active - i ==0 ) {dev_dbg (to_dev (ioat_chan),"%s: cancel completion timeout\n" , __func__); -mod_timer (&ioat_chan->timer, jiffies +IDLE_TIMEOUT ); +mod_timer_pending (&ioat_chan->timer, jiffies +IDLE_TIMEOUT ); }/* microsecond delay by sysfs variable per pending descriptor */
@@ -682,7 +682,7 @@ static void ioat_cleanup(struct ioatdma_chan *ioat_chan)if (chanerr & (IOAT_CHANERR_HANDLE_MASK |IOAT_CHANERR_RECOVER_MASK )) { -mod_timer (&ioat_chan->timer, jiffies +IDLE_TIMEOUT ); +mod_timer_pending (&ioat_chan->timer, jiffies +IDLE_TIMEOUT );ioat_eh (ioat_chan); } }
@@ -879,7 +879,7 @@ static void check_active(struct ioatdma_chan *ioat_chan) }if (test_and_clear_bit (IOAT_CHAN_ACTIVE , &ioat_chan->state)) -mod_timer (&ioat_chan->timer, jiffies +IDLE_TIMEOUT ); +mod_timer_pending (&ioat_chan->timer, jiffies +IDLE_TIMEOUT ); }static void ioat_reboot_chan (struct ioatdma_chan *ioat_chan)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 349/530 usb: mtu3: fix failed runtime suspend in host only mode
In reply to Greg Kroah-HartmanFrom: Chunfeng Yun <[email protected]>
[ Upstream commit 1c703e29da5efac6180e4c189029fa34b7e48e97 ]
When the dr_mode is "host", after the host enter runtime suspend, the mtu3 can't do it, because the mtu3's device wakeup function is not enabled, instead it's enabled in gadget init function, to fix the issue, init wakeup early in mtu3's probe()
--- drivers/usb/mtu3/mtu3_core.c | 2 -- drivers/usb/mtu3/mtu3_plat.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/usb/mtu3/mtu3_core.c +0 -2
@@ -971,8 +971,6 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb) goto irq_err; } -device_init_wakeup (dev, true); -/* power down device IP for power saving by default */ mtu3_stop (mtu);
drivers/usb/mtu3/mtu3_plat.c +2 -0
@@ -332,6 +332,8 @@ static int mtu3_probe(struct platform_device *pdev)pm_runtime_enable (dev);pm_runtime_get_sync (dev); +device_init_wakeup (dev, true); + ret =ssusb_rscs_init (ssusb);if (ret) goto comm_init_err;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 350/530 spmi: pmic-arb: correct duplicate APID to PPID mapping logic
In reply to Greg Kroah-HartmanFrom: David Collins <[email protected]>
[ Upstream commit 1f1693118c2476cb1666ad357edcf3cf48bf9b16 ]
Correct the way that duplicate PPID mappings are handled for PMIC arbiter v5. The final APID mapped to a given PPID should be the one which has write owner = APPS EE, if it exists, or if not that, then the first APID mapped to the PPID, if it exists.
--- drivers/spmi/spmi-pmic-arb.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/spmi/spmi-pmic-arb.c +7 -6
@@ -887,7 +887,8 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)* version 5, there is more than one APID mapped to each PPID. * The owner field for each of these mappings specifies the EE which is * allowed to write to the APID. The owner of the last (highest) APID -* for a given PPID will receive interrupts from the PPID. +* which has the IRQ owner bit set for a given PPID will receive +* interrupts from the PPID. */ for (i =0 ; ; i++, apidd++) { offset = pmic_arb->ver_ops->apid_map_offset (i);
@@ -910,16 +911,16 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb) apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID ; prev_apidd = &pmic_arb->apid_data[apid]; -if (valid && is_irq_ee && - prev_apidd->write_ee == pmic_arb->ee) { +if (!valid || apidd->write_ee == pmic_arb->ee) { +/* First PPID mapping or one for this EE */ + pmic_arb->ppid_to_apid[ppid] = i |PMIC_ARB_APID_VALID ; + }else if (valid && is_irq_ee && + prev_apidd->write_ee == pmic_arb->ee) {/* * Duplicate PPID mapping after the one for this EE; * override the irq owner */ prev_apidd->irq_ee = apidd->irq_ee; - }else if (!valid || is_irq_ee) { -/* First PPID mapping or duplicate for another EE */ - pmic_arb->ppid_to_apid[ppid] = i |PMIC_ARB_APID_VALID ; } apidd->ppid = ppid;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 351/530 clk: vc5: Fix 5P49V6901 outputs disabling when enabling FOD
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit c388cc804016cf0f65afdc2362b120aa594ff3e6 ]
We have discovered random glitches during the system boot up procedure. The problem investigation led us to the weird outcomes: when none of the Renesas 5P49V6901 ports are explicitly enabled by the kernel driver, the glitches disappeared. It was a mystery since the SoC external clock domains were fed with different 5P49V6901 outputs. The driver code didn't seem like bogus either. We almost despaired to find out a root cause when the solution has been found for a more modern revision of the chip. It turned out the 5P49V6901 clock generator stopped its output for a short period of time during the VC5_OUT_DIV_CONTROL register writing. The same problem was found for the 5P49V6965 revision of the chip and was successfully fixed in commit fc336ae622df ("clk: vc5: fix output disabling when enabling a FOD") by enabling the "bypass_sync" flag hidden inside "Unused Factory Reserved Register". Even though the 5P49V6901 registers description and programming guide doesn't provide any intel regarding that flag, setting it up anyway in the officially unused register completely eliminated the denoted glitches. Thus let's activate the functionality submitted in commit fc336ae622df ("clk: vc5: fix output disabling when enabling a FOD") for the Renesas 5P49V6901 chip too in order to remove the ports implicit inter-dependency.
--- drivers/clk/clk-versaclock5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/clk-versaclock5.c +1 -1
@@ -1204,7 +1204,7 @@ static const struct vc5_chip_info idt_5p49v6901_info = { .model = IDT_VC6_5P49V6901, .clk_fod_cnt = 4, .clk_out_cnt = 5, - .flags = VC5_HAS_PFD_FREQ_DBL, + .flags = VC5_HAS_PFD_FREQ_DBL | VC5_HAS_BYPASS_SYNC_BIT, };static const struct vc5_chip_info idt_5p49v6965_info = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 352/530 clk: baikal-t1: Fix invalid xGMAC PTP clock divider
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit 3c742088686ce922704aec5b11d09bcc5a396589 ]
Most likely due to copy-paste mistake the divider has been set to 10 while according to the SoC reference manual it's supposed to be 8 thus having PTP clock frequency of 156.25 MHz.
--- drivers/clk/baikal-t1/clk-ccu-div.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/baikal-t1/clk-ccu-div.c +1 -1
@@ -207,7 +207,7 @@ static const struct ccu_div_info sys_info[] = {CCU_DIV_GATE_INFO (CCU_SYS_XGMAC_REF_CLK ,"sys_xgmac_ref_clk" ,"eth_clk" ,CCU_SYS_XGMAC_BASE ,8 ),CCU_DIV_FIXED_INFO (CCU_SYS_XGMAC_PTP_CLK ,"sys_xgmac_ptp_clk" , -"eth_clk" ,10 ), +"eth_clk" ,8 ),CCU_DIV_GATE_INFO (CCU_SYS_USB_CLK ,"sys_usb_clk" ,"eth_clk" ,CCU_SYS_USB_BASE ,10 ), CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 353/530 clk: baikal-t1: Add shared xGMAC ref/ptp clocks internal parent
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit e2eef312762e0b5a5a70d29fe59a245c0a3cffa0 ]
Baikal-T1 CCU reference manual says that both xGMAC reference and xGMAC PTP clocks are generated by two different wrappers with the same constant divider thus each producing a 156.25 MHz signal. But for some reason both of these clock sources are gated by a single switch-flag in the CCU registers space - CCU_SYS_XGMAC_BASE.BIT(0). In order to make the clocks handled independently we need to define a shared parental gate so the base clock signal would be switched off only if both of the child-clocks are disabled.
Note the ID is intentionally set to -2 since we are going to add a one more internal clock identifier in the next commit.
--- drivers/clk/baikal-t1/ccu-div.c | 1 + drivers/clk/baikal-t1/ccu-div.h | 6 ++++++ drivers/clk/baikal-t1/clk-ccu-div.c | 8 +++++--- 3 files changed, 12 insertions(+), 3 deletions(-)
drivers/clk/baikal-t1/ccu-div.c +1 -0
@@ -579,6 +579,7 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init) goto err_free_div; } parent_data.fw_name = div_init->parent_name; + parent_data.name = div_init->parent_name; hw_init.parent_data = &parent_data; hw_init.num_parents =1 ;
drivers/clk/baikal-t1/ccu-div.h +6 -0
@@ -13,6 +13,12 @@#include <linux/bits.h> #include <linux/of.h> +/* +* CCU Divider private clock IDs +* @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock +*/ +#define CCU_SYS_XGMAC_CLK -2 +/* * CCU Divider private flags * @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1.
drivers/clk/baikal-t1/clk-ccu-div.c +5 -3
@@ -204,10 +204,12 @@ static const struct ccu_div_info sys_info[] = { "eth_clk", CCU_SYS_GMAC1_BASE, 5),CCU_DIV_FIXED_INFO (CCU_SYS_GMAC1_PTP_CLK ,"sys_gmac1_ptp_clk" ,"eth_clk" ,10 ), -CCU_DIV_GATE_INFO (CCU_SYS_XGMAC_REF_CLK ,"sys_xgmac_ref_clk" , -"eth_clk" ,CCU_SYS_XGMAC_BASE ,8 ), +CCU_DIV_GATE_INFO (CCU_SYS_XGMAC_CLK ,"sys_xgmac_clk" , +"eth_clk" ,CCU_SYS_XGMAC_BASE ,1 ), +CCU_DIV_FIXED_INFO (CCU_SYS_XGMAC_REF_CLK ,"sys_xgmac_ref_clk" , +"sys_xgmac_clk" ,8 ),CCU_DIV_FIXED_INFO (CCU_SYS_XGMAC_PTP_CLK ,"sys_xgmac_ptp_clk" , -"eth_clk" ,8 ), +"sys_xgmac_clk" ,8 ),CCU_DIV_GATE_INFO (CCU_SYS_USB_CLK ,"sys_usb_clk" ,"eth_clk" ,CCU_SYS_USB_BASE ,10 ), CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 354/530 clk: baikal-t1: Add SATA internal ref clock buffer
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit 081a9b7c74eae4e12b2cb1b86720f836a8f29247 ]
It turns out the internal SATA reference clock signal will stay unavailable for the SATA interface consumer until the buffer on it's way is ungated. So aside with having the actual clock divider enabled we need to ungate a buffer placed on the signal way to the SATA controller (most likely some rudiment from the initial SoC release). Seeing the switch flag is placed in the same register as the SATA-ref clock divider at a non-standard ffset, let's implement it as a separate clock controller with the set-rate propagation to the parental clock divider wrapper. As such we'll be able to disable/enable and still change the original clock source rate.
--- drivers/clk/baikal-t1/ccu-div.c | 64 +++++++++++++++++++++++++++++ drivers/clk/baikal-t1/ccu-div.h | 4 ++ drivers/clk/baikal-t1/clk-ccu-div.c | 18 +++++++- 3 files changed, 85 insertions(+), 1 deletion(-)
drivers/clk/baikal-t1/ccu-div.c +64 -0
@@ -34,6 +34,7 @@#define CCU_DIV_CTL_CLKDIV_MASK (_width) \ GENMASK((_width) + CCU_DIV_CTL_CLKDIV_FLD - 1, CCU_DIV_CTL_CLKDIV_FLD)#define CCU_DIV_CTL_LOCK_SHIFTED BIT(27) +#define CCU_DIV_CTL_GATE_REF_BUF BIT(28)#define CCU_DIV_CTL_LOCK_NORMAL BIT(31)#define CCU_DIV_RST_DELAY_US 1
@@ -170,6 +171,40 @@ static int ccu_div_gate_is_enabled(struct clk_hw *hw)return !!(val &CCU_DIV_CTL_EN ); } +static int ccu_div_buf_enable (struct clk_hw *hw) +{ +struct ccu_div *div =to_ccu_div (hw); +unsigned long flags; + +spin_lock_irqsave (&div->lock, flags); +regmap_update_bits (div->sys_regs, div->reg_ctl, +CCU_DIV_CTL_GATE_REF_BUF ,0 ); +spin_unlock_irqrestore (&div->lock, flags); + +return 0 ; +} + +static void ccu_div_buf_disable (struct clk_hw *hw) +{ +struct ccu_div *div =to_ccu_div (hw); +unsigned long flags; + +spin_lock_irqsave (&div->lock, flags); +regmap_update_bits (div->sys_regs, div->reg_ctl, +CCU_DIV_CTL_GATE_REF_BUF ,CCU_DIV_CTL_GATE_REF_BUF ); +spin_unlock_irqrestore (&div->lock, flags); +} + +static int ccu_div_buf_is_enabled (struct clk_hw *hw) +{ +struct ccu_div *div =to_ccu_div (hw); +u32 val =0 ; + +regmap_read (div->sys_regs, div->reg_ctl, &val); + +return !(val &CCU_DIV_CTL_GATE_REF_BUF ); +} +static unsigned long ccu_div_var_recalc_rate (struct clk_hw *hw,unsigned long parent_rate) {
@@ -323,6 +358,7 @@ static const struct ccu_div_dbgfs_bit ccu_div_bits[] = {CCU_DIV_DBGFS_BIT_ATTR ("div_en" ,CCU_DIV_CTL_EN ),CCU_DIV_DBGFS_BIT_ATTR ("div_rst" ,CCU_DIV_CTL_RST ),CCU_DIV_DBGFS_BIT_ATTR ("div_bypass" ,CCU_DIV_CTL_SET_CLKDIV ), +CCU_DIV_DBGFS_BIT_ATTR ("div_buf" ,CCU_DIV_CTL_GATE_REF_BUF ), CCU_DIV_DBGFS_BIT_ATTR("div_lock", CCU_DIV_CTL_LOCK_NORMAL) };
@@ -441,6 +477,9 @@ static void ccu_div_var_debug_init(struct clk_hw *hw, struct dentry *dentry)continue ; } +if (!strcmp ("div_buf" , name)) +continue ; + bits[didx] = ccu_div_bits[bidx]; bits[didx].div = div;
@@ -477,6 +516,21 @@ static void ccu_div_gate_debug_init(struct clk_hw *hw, struct dentry *dentry) &ccu_div_dbgfs_fixed_clkdiv_fops); } +static void ccu_div_buf_debug_init (struct clk_hw *hw,struct dentry *dentry) +{ +struct ccu_div *div =to_ccu_div (hw); +struct ccu_div_dbgfs_bit *bit; + + bit =kmalloc (sizeof (*bit),GFP_KERNEL ); +if (!bit) +return ; + + *bit = ccu_div_bits[3 ]; + bit->div = div; +debugfs_create_file_unsafe (bit->name, ccu_div_dbgfs_mode, dentry, bit, + &ccu_div_dbgfs_bit_fops); +} +static void ccu_div_fixed_debug_init (struct clk_hw *hw,struct dentry *dentry) {struct ccu_div *div =to_ccu_div (hw);
@@ -489,6 +543,7 @@ static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry)#define ccu_div_var_debug_init NULL#define ccu_div_gate_debug_init NULL +#define ccu_div_buf_debug_init NULL#define ccu_div_fixed_debug_init NULL#endif /* !CONFIG_DEBUG_FS */
@@ -520,6 +575,13 @@ static const struct clk_ops ccu_div_gate_ops = { .debug_init = ccu_div_gate_debug_init }; +static const struct clk_ops ccu_div_buf_ops = { + .enable = ccu_div_buf_enable, + .disable = ccu_div_buf_disable, + .is_enabled = ccu_div_buf_is_enabled, + .debug_init = ccu_div_buf_debug_init +}; +static const struct clk_ops ccu_div_fixed_ops = { .recalc_rate = ccu_div_fixed_recalc_rate, .round_rate = ccu_div_fixed_round_rate,
@@ -566,6 +628,8 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init) }else if (div_init->type ==CCU_DIV_GATE ) { hw_init.ops = &ccu_div_gate_ops; div->divider = div_init->divider; + }else if (div_init->type ==CCU_DIV_BUF ) { + hw_init.ops = &ccu_div_buf_ops; }else if (div_init->type ==CCU_DIV_FIXED ) { hw_init.ops = &ccu_div_fixed_ops; div->divider = div_init->divider;
drivers/clk/baikal-t1/ccu-div.h +4 -0
@@ -15,8 +15,10 @@/* * CCU Divider private clock IDs +* @CCU_SYS_SATA_CLK: CCU SATA internal clock * @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock */ +#define CCU_SYS_SATA_CLK -1#define CCU_SYS_XGMAC_CLK -2/*
@@ -37,11 +39,13 @@* enum ccu_div_type - CCU Divider types * @CCU_DIV_VAR: Clocks gate with variable divider. * @CCU_DIV_GATE: Clocks gate with fixed divider. +* @CCU_DIV_BUF: Clock gate with no divider. * @CCU_DIV_FIXED: Ungateable clock with fixed divider. */ enum ccu_div_type {CCU_DIV_VAR ,CCU_DIV_GATE , +CCU_DIV_BUF ,CCU_DIV_FIXED };
drivers/clk/baikal-t1/clk-ccu-div.c +17 -1
@@ -76,6 +76,16 @@ .divider = _divider \ } +#define CCU_DIV_BUF_INFO (_id, _name, _pname, _base, _flags) \ + { \ + .id = _id, \ + .name = _name, \ + .parent_name = _pname, \ + .base = _base, \ + .type = CCU_DIV_BUF, \ + .flags = _flags \ + } +#define CCU_DIV_FIXED_INFO (_id, _name, _pname, _divider) \ { \ .id = _id, \
@@ -188,11 +198,14 @@ static const struct ccu_div_rst_map axi_rst_map[] = {* for the SoC devices registers IO-operations. */ static const struct ccu_div_info sys_info[] = { -CCU_DIV_VAR_INFO (CCU_SYS_SATA_REF_CLK ,"sys_sata_ref_clk" , +CCU_DIV_VAR_INFO (CCU_SYS_SATA_CLK ,"sys_sata_clk" ,"sata_clk" ,CCU_SYS_SATA_REF_BASE ,4 ,CLK_SET_RATE_GATE ,CCU_DIV_SKIP_ONE |CCU_DIV_LOCK_SHIFTED |CCU_DIV_RESET_DOMAIN ), +CCU_DIV_BUF_INFO (CCU_SYS_SATA_REF_CLK ,"sys_sata_ref_clk" , +"sys_sata_clk" ,CCU_SYS_SATA_REF_BASE , +CLK_SET_RATE_PARENT ),CCU_DIV_VAR_INFO (CCU_SYS_APB_CLK ,"sys_apb_clk" ,"pcie_clk" ,CCU_SYS_APB_BASE ,5 ,CLK_IS_CRITICAL ,CCU_DIV_RESET_DOMAIN ),
@@ -398,6 +411,9 @@ static int ccu_div_clk_register(struct ccu_div_data *data) init.base = info->base; init.sys_regs = data->sys_regs; init.divider = info->divider; + }else if (init.type ==CCU_DIV_BUF ) { + init.base = info->base; + init.sys_regs = data->sys_regs; }else { init.divider = info->divider; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 355/530 clk: bcm2835: fix bcm2835_clock_rate_from_divisor declaration
In reply to Greg Kroah-HartmanFrom: Stefan Wahren <[email protected]>
[ Upstream commit 0b919a3728691c172312dee99ba654055ccd8c84 ]
The return value of bcm2835_clock_rate_from_divisor is always unsigned and also all caller expect this. So fix the declaration accordingly.
--- drivers/clk/bcm/clk-bcm2835.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/bcm/clk-bcm2835.c +3 -3
@@ -967,9 +967,9 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,return div; } -static long bcm2835_clock_rate_from_divisor (struct bcm2835_clock *clock, -unsigned long parent_rate, -u32 div) +static unsigned long bcm2835_clock_rate_from_divisor (struct bcm2835_clock *clock, +unsigned long parent_rate, +u32 div) {const struct bcm2835_clock_data *data = clock->data;u64 temp;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 356/530 clk: imx: scu: fix memleak on platform_device_add() fails
In reply to Greg Kroah-HartmanFrom: Lin Yujun <[email protected]>
[ Upstream commit 855ae87a2073ebf1b395e020de54fdf9ce7d166f ]
No error handling is performed when platform_device_add() fails. Add error processing before return, and modified the return value.
--- drivers/clk/imx/clk-scu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/clk/imx/clk-scu.c +5 -1
@@ -690,7 +690,11 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,pr_warn ("%s: failed to attached the power domain %d\n" , name, ret); -platform_device_add (pdev); + ret =platform_device_add (pdev); +if (ret) { +platform_device_put (pdev); +return ERR_PTR (ret); + }/* For API backwards compatiblilty, simply return NULL for success */ return NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 357/530 clk: ti: dra7-atl: Fix reference leak in of_dra7_atl_clk_probe
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 9c59a01caba26ec06fefd6ca1f22d5fd1de57d63 ]
pm_runtime_get_sync() will increment pm usage counter. Forgetting to putting operation will result in reference leak. Add missing pm_runtime_put_sync in some error paths.
--- drivers/clk/ti/clk-dra7-atl.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/clk/ti/clk-dra7-atl.c +6 -3
@@ -251,14 +251,16 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)if (rc) {pr_err ("%s: failed to lookup atl clock %d\n" , __func__, i); -return -EINVAL ; + ret = -EINVAL ; + goto pm_put; } clk =of_clk_get_from_provider (&clkspec);if (IS_ERR (clk)) {pr_err ("%s: failed to get atl clock %d from provider\n" , __func__, i); -return PTR_ERR (clk); + ret =PTR_ERR (clk); + goto pm_put; } cdesc =to_atl_desc (__clk_get_hw (clk));
@@ -291,8 +293,9 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)if (cdesc->enabled)atl_clk_enable (__clk_get_hw (clk)); } -pm_runtime_put_sync (cinfo->dev); +pm_put: +pm_runtime_put_sync (cinfo->dev);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 358/530 clk: ast2600: BCLK comes from EPLL
In reply to Greg Kroah-HartmanFrom: Joel Stanley <[email protected]>
[ Upstream commit b8c1dc9c00b252b3be853720a71b05ed451ddd9f ]
This correction was made in the u-boot SDK recently. There are no in-tree users of this clock so the impact is minimal.
--- drivers/clk/clk-ast2600.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/clk-ast2600.c +1 -1
@@ -622,7 +622,7 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev)regmap_write (map,0x308 ,0x12000 );/* 3x3 = 9 */ /* P-Bus (BCLK) clock divider */ - hw =clk_hw_register_divider_table (dev,"bclk" ,"hpll" ,0 , + hw =clk_hw_register_divider_table (dev,"bclk" ,"epll" ,0 , scu_g6_base +ASPEED_G6_CLK_SELECTION1 ,20 ,3 ,0 , ast2600_div_table, &aspeed_g6_clk_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 359/530 mailbox: mpfs: fix handling of the reg property
In reply to Greg Kroah-HartmanFrom: Conor Dooley <[email protected]>
[ Upstream commit 2e10289d1f304f5082a4dda55a677b72b3bdb581 ]
The "data" region of the PolarFire SoC's system controller mailbox is not one continuous register space - the system controller's QSPI sits between the control and data registers. Split the "data" reg into two
parts: "data" & "control". Optionally get the "data" register address from the 3rd reg property in the devicetree & fall back to using the old base + MAILBOX_REG_OFFSET that the current code uses.
--- drivers/mailbox/mailbox-mpfs.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-)
drivers/mailbox/mailbox-mpfs.c +14 -10
@@ -62,6 +62,7 @@ struct mpfs_mbox {struct mbox_controller controller;struct device *dev;int irq; +void __iomem *ctrl_base;void __iomem *mbox_base;void __iomem *int_reg;struct mbox_chan chans[1 ];
@@ -73,7 +74,7 @@ static bool mpfs_mbox_busy(struct mpfs_mbox *mbox) {u32 status; - status =readl_relaxed (mbox->mbox_base +SERVICES_SR_OFFSET ); + status =readl_relaxed (mbox->ctrl_base +SERVICES_SR_OFFSET );return status &SCB_STATUS_BUSY_MASK ; }
@@ -99,14 +100,13 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data)for (index =0 ; index < (msg->cmd_data_size /4 ); index++)writel_relaxed (word_buf[index], - mbox->mbox_base +MAILBOX_REG_OFFSET + index *0x4 ); + mbox->mbox_base + index *0x4 );if (extra_bits) {u8 i;u8 byte_off =ALIGN_DOWN (msg->cmd_data_size,4 );u8 *byte_buf = msg->cmd_data + byte_off; - val =readl_relaxed (mbox->mbox_base + -MAILBOX_REG_OFFSET + index *0x4 ); + val =readl_relaxed (mbox->mbox_base + index *0x4 );for (i =0u ; i < extra_bits; i++) { val &= ~(0xffu << (i *8u ));
@@ -114,14 +114,14 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data) }writel_relaxed (val, - mbox->mbox_base +MAILBOX_REG_OFFSET + index *0x4 ); + mbox->mbox_base + index *0x4 ); } } opt_sel = ((msg->mbox_offset <<7u ) | (msg->cmd_opcode &0x7fu )); tx_trigger = (opt_sel <<SCB_CTRL_POS ) &SCB_CTRL_MASK ; tx_trigger |=SCB_CTRL_REQ_MASK |SCB_STATUS_NOTIFY_MASK ; -writel_relaxed (tx_trigger, mbox->mbox_base +SERVICES_CR_OFFSET ); +writel_relaxed (tx_trigger, mbox->ctrl_base +SERVICES_CR_OFFSET );return 0 ; }
@@ -141,7 +141,7 @@ static void mpfs_mbox_rx_data(struct mbox_chan *chan)if (!mpfs_mbox_busy (mbox)) {for (i =0 ; i < num_words; i++) { response->resp_msg[i] = -readl_relaxed (mbox->mbox_base +MAILBOX_REG_OFFSET +readl_relaxed (mbox->mbox_base + mbox->resp_offset + i *0x4 ); } }
@@ -200,14 +200,18 @@ static int mpfs_mbox_probe(struct platform_device *pdev)if (!mbox)return -ENOMEM ; - mbox->mbox_base =devm_platform_get_and_ioremap_resource (pdev,0 , ®s); -if (IS_ERR (mbox->mbox_base)) -return PTR_ERR (mbox->mbox_base); + mbox->ctrl_base =devm_platform_get_and_ioremap_resource (pdev,0 , ®s); +if (IS_ERR (mbox->ctrl_base)) +return PTR_ERR (mbox->ctrl_base); mbox->int_reg =devm_platform_get_and_ioremap_resource (pdev,1 , ®s);if (IS_ERR (mbox->int_reg))return PTR_ERR (mbox->int_reg); + mbox->mbox_base =devm_platform_get_and_ioremap_resource (pdev,2 , ®s); +if (IS_ERR (mbox->mbox_base))// account for the old dt-binding w/ 2 regs + mbox->mbox_base = mbox->ctrl_base +MAILBOX_REG_OFFSET ; + mbox->irq =platform_get_irq (pdev,0 );if (mbox->irq <0 )return mbox->irq;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 360/530 mailbox: mpfs: account for mbox offsets while sending
In reply to Greg Kroah-HartmanFrom: Conor Dooley <[email protected]>
[ Upstream commit 0d1aadfe10ba17ebdeb96abb9638eb0f623f9b55 ]
The mailbox offset is not only used for receiving messages, but it is also used by messages sent to the system controller by Linux that have a payload, such as the "digital signature service". It is also overloaded by certain other services (reprogramming of the FPGA fabric, see Link:) to have a meaning other than the offset the system controller should read from.
When the driver was written, no such services of the latter type were in use & those of the former used an offset of zero so this has gone un-noticed.
--- drivers/mailbox/mailbox-mpfs.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/mailbox/mailbox-mpfs.c +3 -4
@@ -100,21 +100,20 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data)for (index =0 ; index < (msg->cmd_data_size /4 ); index++)writel_relaxed (word_buf[index], - mbox->mbox_base + index *0x4 ); + mbox->mbox_base + msg->mbox_offset + index *0x4 );if (extra_bits) {u8 i;u8 byte_off =ALIGN_DOWN (msg->cmd_data_size,4 );u8 *byte_buf = msg->cmd_data + byte_off; - val =readl_relaxed (mbox->mbox_base + index *0x4 ); + val =readl_relaxed (mbox->mbox_base + msg->mbox_offset + index *0x4 );for (i =0u ; i < extra_bits; i++) { val &= ~(0xffu << (i *8u )); val |= (byte_buf[i] << (i *8u )); } -writel_relaxed (val, - mbox->mbox_base + index *0x4 ); +writel_relaxed (val, mbox->mbox_base + msg->mbox_offset + index *0x4 ); } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 361/530 mailbox: bcm-ferxrm-mailbox: Fix error check for dma_map_sg
In reply to Greg Kroah-HartmanFrom: Jack Wang <[email protected]>
[ Upstream commit 6b207ce8a96a71e966831e3a13c38143ba9a73c1 ]
dma_map_sg return 0 on error, fix the error check, and return -EIO to caller.
--- drivers/mailbox/bcm-flexrm-mailbox.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/mailbox/bcm-flexrm-mailbox.c +4 -4
@@ -632,15 +632,15 @@ static int flexrm_spu_dma_map(struct device *dev, struct brcm_message *msg) rc =dma_map_sg (dev, msg->spu.src,sg_nents (msg->spu.src),DMA_TO_DEVICE ); -if (rc <0 ) -return rc; +if (!rc) +return -EIO ; rc =dma_map_sg (dev, msg->spu.dst,sg_nents (msg->spu.dst),DMA_FROM_DEVICE ); -if (rc <0 ) { +if (!rc) {dma_unmap_sg (dev, msg->spu.src,sg_nents (msg->spu.src),DMA_TO_DEVICE ); -return rc; +return -EIO ; }return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 362/530 powerpc/configs: Properly enable PAPR_SCM in pseries_defconfig
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
[ Upstream commit aa398d88aea4ec863bd7aea35d5035a37096dc59 ]
My commit to add PAPR_SCM to pseries_defconfig failed to add the required dependencies, meaning the driver doesn't get built.
Add the required LIBNVDIMM=m.
--- arch/powerpc/configs/pseries_defconfig | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/configs/pseries_defconfig +1 -0
@@ -41,6 +41,7 @@ CONFIG_DTL=y CONFIG_SCANLOG=m CONFIG_PPC_SMLPAR=y CONFIG_IBMEBUS=y +CONFIG_LIBNVDIMM=m CONFIG_PAPR_SCM=m CONFIG_PPC_SVM=y # CONFIG_PPC_PMAC is not set
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 363/530 powerpc/math_emu/efp: Include module.h
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit cfe0d370e0788625ce0df3239aad07a2506c1796 ]
When building with a recent version of clang, there are a couple of errors around the call to module_init():
arch/powerpc/math-emu/math_efp.c:927:1: error: type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int] module_init(spe_mathemu_init);
^
int
arch/powerpc/math-emu/math_efp.c:927:13: error: a parameter list without types is only allowed in a function definition
module_init(spe_mathemu_init);
^2 errors generated.
module_init() is a macro, which is not getting expanded because module.h is not included in this file. Add the include so that the macro can expand properly, clearing up the build failure.
--- arch/powerpc/math-emu/math_efp.c | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/math-emu/math_efp.c +1 -0
@@ -17,6 +17,7 @@#include <linux/types.h> #include <linux/prctl.h> +#include <linux/module.h> #include <linux/uaccess.h> #include <asm/reg.h>
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 364/530 powerpc/sysdev/fsl_msi: Add missing of_node_put()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit def435c04ee984a5f9ed2711b2bfe946936c6a21 ]
In fsl_setup_msi_irqs(), use of_node_put() to drop the reference returned by of_parse_phandle().
--- arch/powerpc/sysdev/fsl_msi.c | 2 ++ 1 file changed, 2 insertions(+)
arch/powerpc/sysdev/fsl_msi.c +2 -0
@@ -211,8 +211,10 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)dev_err (&pdev->dev,"node %pOF has an invalid fsl,msi phandle %u\n" , hose->dn, np->phandle); +of_node_put (np);return -EINVAL ; } +of_node_put (np); }for_each_pci_msi_entry (entry, pdev) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 365/530 powerpc/pci_dn: Add missing of_node_put()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 110a1fcb6c4d55144d8179983a475f17a1d6f832 ]
In pci_add_device_node_info(), use of_node_put() to drop the reference to 'parent' returned by of_get_parent() to keep refcount balance.
--- arch/powerpc/kernel/pci_dn.c | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/kernel/pci_dn.c +1 -0
@@ -330,6 +330,7 @@ struct pci_dn *pci_add_device_node_info(struct pci_controller *hose,INIT_LIST_HEAD (&pdn->list); parent =of_get_parent (dn); pdn->parent = parent ?PCI_DN (parent) :NULL ; +of_node_put (parent);if (pdn->parent)list_add_tail (&pdn->list, &pdn->parent->child_list);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 366/530 powerpc/powernv: add missing of_node_put() in opal_export_attrs()
In reply to Greg Kroah-HartmanFrom: Zheng Yongjun <[email protected]>
[ Upstream commit 71a92e99c47900cc164620948b3863382cec4f1a ]
After using 'np' returned by of_find_node_by_path(), of_node_put() need be called to decrease the refcount.
--- arch/powerpc/platforms/powernv/opal.c | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/platforms/powernv/opal.c +1 -0
@@ -892,6 +892,7 @@ static void opal_export_attrs(void) kobj =kobject_create_and_add ("exports" , opal_kobj);if (!kobj) {pr_warn ("kobject_create_and_add() of exports failed\n" ); +of_node_put (np);return ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 367/530 powerpc: Fix fallocate and fadvise64_64 compat parameter combination
In reply to Greg Kroah-HartmanFrom: Rohan McLure <[email protected]>
[ Upstream commit 016ff72bd2090903715c0f9422a44afbb966f4ee ]
As reported[1] by Arnd, the arch-specific fadvise64_64 and fallocate compatibility handlers assume parameters are passed with 32-bit big-endian ABI. This affects the assignment of odd-even parameter pairs to the high or low words of a 64-bit syscall parameter.
Fix fadvise64_64 fallocate compat handlers to correctly swap upper/lower 32 bits conditioned on endianness.
A future patch will replace the arch-specific compat fallocate with an asm-generic implementation. This patch is intended for ease of back-port.
[1]: https://lore.kernel.org/all/[email protected]/
--- arch/powerpc/include/asm/syscalls.h | 12 ++++++++++++ arch/powerpc/kernel/sys_ppc32.c | 14 +------------- arch/powerpc/kernel/syscalls.c | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-)
arch/powerpc/include/asm/syscalls.h +12 -0
@@ -8,6 +8,18 @@#include <linux/types.h> #include <linux/compat.h> +/* +* long long munging: +* The 32 bit ABI passes long longs in an odd even register pair. +* High and low parts are swapped depending on endian mode, +* so define a macro (similar to mips linux32) to handle that. +*/ +#ifdef __LITTLE_ENDIAN__ +#define merge_64 (low, high) (((u64)high << 32) | low) +#else +#define merge_64 (high, low) (((u64)high << 32) | low) +#endif +struct rtas_args ; asmlinkage long sys_mmap(unsigned long addr, size_t len,
arch/powerpc/kernel/sys_ppc32.c +1 -13
@@ -56,18 +56,6 @@ unsigned long compat_sys_mmap2(unsigned long addr, size_t len,return sys_mmap (addr, len, prot, flags, fd, pgoff <<12 ); } -/* -* long long munging: -* The 32 bit ABI passes long longs in an odd even register pair. -* High and low parts are swapped depending on endian mode, -* so define a macro (similar to mips linux32) to handle that. -*/ -#ifdef __LITTLE_ENDIAN__ -#define merge_64 (low, high) ((u64)high << 32) | low -#else -#define merge_64 (high, low) ((u64)high << 32) | low -#endif -compat_ssize_t compat_sys_pread64 (unsigned int fd,char __user *ubuf,compat_size_t count,u32 reg6,u32 pos1,u32 pos2) {
@@ -94,7 +82,7 @@ asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4,asmlinkage long compat_sys_fallocate (int fd,int mode,u32 offset1,u32 offset2,u32 len1,u32 len2) { -return ksys_fallocate (fd, mode, ((loff_t )offset1 <<32 ) | offset2, +return ksys_fallocate (fd, mode,merge_64 (offset1, offset2),merge_64 (len1, len2)); }
arch/powerpc/kernel/syscalls.c +2 -2
@@ -99,8 +99,8 @@ long ppc64_personality(unsigned long personality)long ppc_fadvise64_64 (int fd,int advice,u32 offset_high,u32 offset_low,u32 len_high,u32 len_low) { -return ksys_fadvise64_64 (fd, (u64 )offset_high <<32 | offset_low, - (u64 )len_high <<32 | len_low, advice); +return ksys_fadvise64_64 (fd,merge_64 (offset_high, offset_low), +merge_64 (len_high, len_low), advice); }SYSCALL_DEFINE0 (switch_endian)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 368/530 x86/hyperv: Fix struct hv_enlightened_vmcs definition
In reply to Greg Kroah-HartmanFrom: Vitaly Kuznetsov <[email protected]>
[ Upstream commit ea9da788a61e47e7ab9cbad397453e51cd82ac0d ]
Section 1.9 of TLFS v6.0b says:
"All structures are padded in such a way that fields are aligned naturally (that is, an 8-byte field is aligned to an offset of 8 bytes and so on)".
'struct enlightened_vmcs' has a glitch:
...
struct {
u32 nested_flush_hypercall:1; /* 836: 0 4 */
u32 msr_bitmap:1; /* 836: 1 4 */
u32 reserved:30; /* 836: 2 4 */
} hv_enlightenments_control; /* 836 4 */
u32 hv_vp_id; /* 840 4 */
u64 hv_vm_id; /* 844 8 */
u64 partition_assist_page; /* 852 8 */...
And the observed values in 'partition_assist_page' make no sense at all. Fix the layout by padding the structure properly.
--- arch/x86/include/asm/hyperv-tlfs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/include/asm/hyperv-tlfs.h +2 -2
@@ -529,7 +529,7 @@ struct hv_enlightened_vmcs {u64 guest_rip;u32 hv_clean_fields; -u32 hv_padding_32; +u32 padding32_1;u32 hv_synthetic_controls;struct {u32 nested_flush_hypercall:1 ;
@@ -537,7 +537,7 @@ struct hv_enlightened_vmcs { u32 reserved:30; }__packed hv_enlightenments_control;u32 hv_vp_id; - +u32 padding32_2;u64 hv_vm_id;u64 partition_assist_page;u64 padding64_4[4 ];
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 369/530 powerpc/64s: Fix GENERIC_CPU build flags for PPC970 / G5
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit 58ec7f06b74e0d6e76c4110afce367c8b5f0837d ]
Big-endian GENERIC_CPU supports 970, but builds with -mcpu=power5. POWER5 is ISA v2.02 whereas 970 is v2.01 plus Altivec. 2.02 added the popcntb instruction which a compiler might use.
Use -mcpu=power4.
--- arch/powerpc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/Makefile +1 -1
@@ -154,7 +154,7 @@ CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power8 CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power9,-mtune=power8) else CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power7,$(call cc-option,-mtune=power5)) -CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mcpu=power5,-mcpu=power4) +CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power4 endif else ifdef CONFIG_PPC_BOOK3E_64 CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64
Signature · 1 line
2.35.1
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.75 release. There are 530 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 26 Oct 2022 11:29:24 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.75-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.15:
10 builds: 10 pass, 0 fail
28 boots: 28 pass, 0 fail
114 tests: 114 pass, 0 failLinux version: 5.15.75-rc1-g98108584d385
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000,
tegra20-ventana, tegra210-p2371-2180,
tegra210-p3450-0000, tegra30-cardhu-a04Jon
Greg Kroah-Hartman
maintainerPATCH 370/530 powerpc: Fix SPE Power ISA properties for e500v1 platforms
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit 37b9345ce7f4ab17538ea62def6f6d430f091355 ]
Commit 2eb28006431c ("powerpc/e500v2: Add Power ISA properties to comply with ePAPR 1.1") introduced new include file e500v2_power_isa.dtsi and should have used it for all e500v2 platforms. But apparently it was used also for e500v1 platforms mpc8540, mpc8541, mpc8555 and mpc8560.
e500v1 cores compared to e500v2 do not support double precision floating point SPE instructions. Hence power-isa-sp.fd should not be set on e500v1 platforms, which is in e500v2_power_isa.dtsi include file.
Fix this issue by introducing a new e500v1_power_isa.dtsi include file and use it in all e500v1 device tree files.
--- .../boot/dts/fsl/e500v1_power_isa.dtsi | 51 +++++++++++++++++++ arch/powerpc/boot/dts/fsl/mpc8540ads.dts | 2 +- arch/powerpc/boot/dts/fsl/mpc8541cds.dts | 2 +- arch/powerpc/boot/dts/fsl/mpc8555cds.dts | 2 +- arch/powerpc/boot/dts/fsl/mpc8560ads.dts | 2 +- 5 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi
arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi new file +51 -0
@@ -0,0 +1,51 @@ +/* + * e500v1 Power ISA Device Tree Source (include) + * + * Copyright 2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/ { + cpus { + power-isa-version = "2.03"; + power-isa-b; // Base + power-isa-e; // Embedded + power-isa-atb; // Alternate Time Base + power-isa-cs; // Cache Specification + power-isa-e.le; // Embedded.Little-Endian + power-isa-e.pm; // Embedded.Performance Monitor + power-isa-ecl; // Embedded Cache Locking + power-isa-mmc; // Memory Coherence + power-isa-sp; // Signal Processing Engine + power-isa-sp.fs; // SPE.Embedded Float Scalar Single + power-isa-sp.fv; // SPE.Embedded Float Vector + mmu-type = "power-embedded"; + }; +};
arch/powerpc/boot/dts/fsl/mpc8540ads.dts +1 -1
@@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8540ADS";
arch/powerpc/boot/dts/fsl/mpc8541cds.dts +1 -1
@@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8541CDS";
arch/powerpc/boot/dts/fsl/mpc8555cds.dts +1 -1
@@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8555CDS";
arch/powerpc/boot/dts/fsl/mpc8560ads.dts +1 -1
@@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8560ADS";
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 371/530 powerpc/kprobes: Fix null pointer reference in arch_prepare_kprobe()
In reply to Greg Kroah-HartmanFrom: Li Huafei <[email protected]>
[ Upstream commit 97f88a3d723162781d6cbfdc7b9617eefab55b19 ]
I found a null pointer reference in arch_prepare_kprobe():
# echo 'p cmdline_proc_show' > kprobe_events
# echo 'p cmdline_proc_show+16' >> kprobe_events
Kernel attempted to read user page (0) - exploit attempt? (uid: 0)
BUG: Kernel NULL pointer dereference on read at 0x00000000
Faulting instruction address: 0xc000000000050bfc
Oops: Kernel access of bad area, sig: 11 [#1]
LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV
Modules linked in:
CPU: 0 PID: 122 Comm: sh Not tainted 6.0.0-rc3-00007-gdcf8e5633e2e #10
NIP: c000000000050bfc LR: c000000000050bec CTR: 0000000000005bdc
REGS: c0000000348475b0 TRAP: 0300 Not tainted (6.0.0-rc3-00007-gdcf8e5633e2e)
MSR: 9000000000009033 <SF,HV,EE,ME,IR,DR,RI,LE> CR: 88002444 XER: 20040006
CFAR: c00000000022d100 DAR: 0000000000000000 DSISR: 40000000 IRQMASK: 0
...
NIP arch_prepare_kprobe+0x10c/0x2d0
LR arch_prepare_kprobe+0xfc/0x2d0
Call Trace:
0xc0000000012f77a0 (unreliable)
register_kprobe+0x3c0/0x7a0
__register_trace_kprobe+0x140/0x1a0
__trace_kprobe_create+0x794/0x1040
trace_probe_create+0xc4/0xe0
create_or_delete_trace_kprobe+0x2c/0x80
trace_parse_run_command+0xf0/0x210
probes_write+0x20/0x40
vfs_write+0xfc/0x450
ksys_write+0x84/0x140
system_call_exception+0x17c/0x3a0
system_call_vectored_common+0xe8/0x278
--- interrupt: 3000 at 0x7fffa5682de0
NIP: 00007fffa5682de0 LR: 0000000000000000 CTR: 0000000000000000
REGS: c000000034847e80 TRAP: 3000 Not tainted (6.0.0-rc3-00007-gdcf8e5633e2e)
MSR: 900000000280f033 <SF,HV,VEC,VSX,EE,PR,FP,ME,IR,DR,RI,LE> CR: 44002408 XER: 00000000The address being probed has some special:
cmdline_proc_show: Probe based on ftrace
cmdline_proc_show+16: Probe for the next instruction at the ftrace location
The ftrace-based kprobe does not generate kprobe::ainsn::insn, it gets set to NULL. In arch_prepare_kprobe() it will check for:
...
prev = get_kprobe(p->addr - 1);
preempt_enable_no_resched();
if (prev && ppc_inst_prefixed(ppc_inst_read(prev->ainsn.insn))) {
...If prev is based on ftrace, 'ppc_inst_read(prev->ainsn.insn)' will occur with a null pointer reference. At this point prev->addr will not be a prefixed instruction, so the check can be skipped.
Check if prev is ftrace-based kprobe before reading 'prev->ainsn.insn' to fix this problem.
--- arch/powerpc/kernel/kprobes.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/powerpc/kernel/kprobes.c +7 -1
@@ -140,7 +140,13 @@ int arch_prepare_kprobe(struct kprobe *p)preempt_disable (); prev =get_kprobe (p->addr -1 );preempt_enable_no_resched (); -if (prev &&ppc_inst_prefixed (ppc_inst_read (prev->ainsn.insn))) { + +/* +* When prev is a ftrace-based kprobe, we don't have an insn, and it +* doesn't probe for prefixed instruction. +*/ +if (prev && !kprobe_ftrace (prev) && +ppc_inst_prefixed (ppc_inst_read (prev->ainsn.insn))) {printk ("Cannot register a kprobe on the second word of prefixed instruction\n" ); ret = -EINVAL ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 372/530 powerpc/pseries/vas: Pass hw_cpu_id to node associativity HCALL
In reply to Greg Kroah-HartmanFrom: Haren Myneni <[email protected]>
[ Upstream commit f3e5d9e53e74d77e711a2c90a91a8b0836a9e0b3 ]
Generally the hypervisor decides to allocate a window on different VAS instances. But if user space wishes to allocate on the current VAS instance where the process is executing, the kernel has to pass associativity domain IDs to allocate VAS window HCALL.
To determine the associativity domain IDs for the current CPU, smp_processor_id() is passed to node associativity HCALL which may return H_P2 (-55) error during DLPAR CPU event. This is because Linux CPU numbers (smp_processor_id()) are not the same as the hypervisor's view of CPU numbers.
Fix the issue by passing hard_smp_processor_id() with VPHN_FLAG_VCPU flag (PAPR 14.11.6.1 H_HOME_NODE_ASSOCIATIVITY).
--- arch/powerpc/platforms/pseries/vas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/platforms/pseries/vas.c +1 -1
@@ -324,7 +324,7 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,* So no unpacking needs to be done. */ rc =plpar_hcall9 (H_HOME_NODE_ASSOCIATIVITY , domain, -VPHN_FLAG_VCPU ,smp_processor_id ()); +VPHN_FLAG_VCPU ,hard_smp_processor_id ());if (rc !=H_SUCCESS ) {pr_err ("H_HOME_NODE_ASSOCIATIVITY error: %d\n" , rc); goto out;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 373/530 crypto: sahara - dont sleep when in softirq
In reply to Greg Kroah-HartmanFrom: Zhengchao Shao <[email protected]>
[ Upstream commit 108586eba094b318e6a831f977f4ddcc403a15da ]
Function of sahara_aes_crypt maybe could be called by function of crypto_skcipher_encrypt during the rx softirq, so it is not allowed to use mutex lock.
--- drivers/crypto/sahara.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/crypto/sahara.c +9 -9
@@ -26,10 +26,10 @@#include <linux/kernel.h> #include <linux/kthread.h> #include <linux/module.h> -#include <linux/mutex.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/platform_device.h> +#include <linux/spinlock.h> #define SHA_BUFFER_LEN PAGE_SIZE#define SAHARA_MAX_SHA_BLOCK_SIZE SHA256_BLOCK_SIZE
@@ -196,7 +196,7 @@ struct sahara_dev {void __iomem *regs_base;struct clk *clk_ipg;struct clk *clk_ahb; -struct mutex queue_mutex; +spinlock_t queue_spinlock;struct task_struct *kthread;struct completion dma_completion;
@@ -642,9 +642,9 @@ static int sahara_aes_crypt(struct skcipher_request *req, unsigned long mode) rctx->mode = mode; -mutex_lock (&dev->queue_mutex); +spin_lock_bh (&dev->queue_spinlock); err =crypto_enqueue_request (&dev->queue, &req->base); -mutex_unlock (&dev->queue_mutex); +spin_unlock_bh (&dev->queue_spinlock);wake_up_process (dev->kthread);
@@ -1043,10 +1043,10 @@ static int sahara_queue_manage(void *data) do { __set_current_state(TASK_INTERRUPTIBLE); - mutex_lock(&dev->queue_mutex); + spin_lock_bh(&dev->queue_spinlock); backlog = crypto_get_backlog(&dev->queue); async_req = crypto_dequeue_request(&dev->queue); - mutex_unlock(&dev->queue_mutex); + spin_unlock_bh(&dev->queue_spinlock); if (backlog) backlog->complete(backlog, -EINPROGRESS);
@@ -1092,9 +1092,9 @@ static int sahara_sha_enqueue(struct ahash_request *req, int last) rctx->first =1 ; } -mutex_lock (&dev->queue_mutex); +spin_lock_bh (&dev->queue_spinlock); ret =crypto_enqueue_request (&dev->queue, &req->base); -mutex_unlock (&dev->queue_mutex); +spin_unlock_bh (&dev->queue_spinlock);wake_up_process (dev->kthread);
@@ -1449,7 +1449,7 @@ static int sahara_probe(struct platform_device *pdev)crypto_init_queue (&dev->queue,SAHARA_QUEUE_LENGTH ); -mutex_init (&dev->queue_mutex); +spin_lock_init (&dev->queue_spinlock); dev_ptr = dev;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 374/530 crypto: hisilicon/zip - fix mismatch in get/set sgl_sge_nr
In reply to Greg Kroah-HartmanFrom: Ye Weihua <[email protected]>
[ Upstream commit d74f9340097a881869c4c22ca376654cc2516ecc ]
KASAN reported this Bug:
[17619.659757] BUG: KASAN: global-out-of-bounds in param_get_int+0x34/0x60 [17619.673193] Read of size 4 at addr fffff01332d7ed00 by task read_all/1507958 ... [17619.698934] The buggy address belongs to the variable: [17619.708371] sgl_sge_nr+0x0/0xffffffffffffa300 [hisi_zip]
There is a mismatch in hisi_zip when get/set the variable sgl_sge_nr. The type of sgl_sge_nr is u16, and get/set sgl_sge_nr by param_get/set_int.
Replacing param_get/set_int to param_get/set_ushort can fix this bug.
--- drivers/crypto/hisilicon/zip/zip_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/crypto/hisilicon/zip/zip_crypto.c +2 -2
@@ -122,12 +122,12 @@ static int sgl_sge_nr_set(const char *val, const struct kernel_param *kp)if (ret || n ==0 || n >HISI_ACC_SGL_SGE_NR_MAX )return -EINVAL ; -return param_set_int (val, kp); +return param_set_ushort (val, kp); }static const struct kernel_param_ops sgl_sge_nr_ops = { .set = sgl_sge_nr_set, - .get = param_get_int, + .get = param_get_ushort, };static u16 sgl_sge_nr =HZIP_SGL_SGE_NR ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 375/530 hwrng: arm-smccc-trng - fix NO_ENTROPY handling
In reply to Greg Kroah-HartmanFrom: James Cowgill <[email protected]>
[ Upstream commit 042b4b169c6fb9d4df268d66282d7302dd73d37b ]
The SMCCC_RET_TRNG_NO_ENTROPY switch arm is never used because the NO_ENTROPY return value is negative and negative values are handled above the switch by immediately returning.
Fix by handling errors using a default arm in the switch.
--- drivers/char/hw_random/arm_smccc_trng.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/char/hw_random/arm_smccc_trng.c +2 -2
@@ -71,8 +71,6 @@ static int smccc_trng_read(struct hwrng *rng, void *data, size_t max, bool wait) MAX_BITS_PER_CALL);arm_smccc_1_1_invoke (ARM_SMCCC_TRNG_RND , bits, &res); -if ((int )res.a0 <0 ) -return (int )res.a0;switch ((int )res.a0) {case SMCCC_RET_SUCCESS :
@@ -88,6 +86,8 @@ static int smccc_trng_read(struct hwrng *rng, void *data, size_t max, bool wait)return copied;cond_resched ();break ; +default : +return -EIO ; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 376/530 cgroup: Honor callers cgroup NS when resolving path
In reply to Greg Kroah-HartmanFrom: Michal Koutný <[email protected]>
[ Upstream commit 74e4b956eb1cac0e4c10c240339b1bbfbc9a4c48 ]
cgroup_get_from_path() is not widely used function. Its callers presume the path is resolved under cgroup namespace. (There is one caller currently and resolving in init NS won't make harm (netfilter). However, future users may be subject to different effects when resolving globally.)
Since, there's currently no use for the global resolution, modify the existing function to take cgroup NS into account.
--- kernel/cgroup/cgroup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
kernel/cgroup/cgroup.c +5 -1
@@ -6598,8 +6598,12 @@ struct cgroup *cgroup_get_from_path(const char *path) {struct kernfs_node *kn;struct cgroup *cgrp =ERR_PTR (-ENOENT ); +struct cgroup *root_cgrp; - kn =kernfs_walk_and_get (cgrp_dfl_root.cgrp.kn, path); +spin_lock_irq (&css_set_lock); + root_cgrp =current_cgns_cgroup_from_root (&cgrp_dfl_root); + kn =kernfs_walk_and_get (root_cgrp->kn, path); +spin_unlock_irq (&css_set_lock);if (!kn) goto out;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 377/530 hwrng: imx-rngc - Moving IRQ handler registering after imx_rngc_irq_mask_clear()
In reply to Greg Kroah-HartmanFrom: Kshitiz Varshney <[email protected]>
[ Upstream commit 10a2199caf437e893d9027d97700b3c6010048b7 ]
Issue:
While servicing interrupt, if the IRQ happens to be because of a SEED_DONE due to a previous boot stage, you end up completing the completion prematurely, hence causing kernel to crash while booting.
Fix:
Moving IRQ handler registering after imx_rngc_irq_mask_clear()
--- drivers/char/hw_random/imx-rngc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/char/hw_random/imx-rngc.c +7 -7
@@ -270,13 +270,6 @@ static int imx_rngc_probe(struct platfor goto err; } - ret =devm_request_irq (&pdev->dev, - irq, imx_rngc_irq,0 , pdev->name, (void *)rngc); -if (ret) { -dev_err (rngc->dev,"Can't get interrupt working.\n" ); - goto err; - } -init_completion (&rngc->rng_op_done); rngc->rng.name = pdev->name;
@@ -290,6 +283,13 @@ static int imx_rngc_probe(struct platforimx_rngc_irq_mask_clear (rngc); + ret =devm_request_irq (&pdev->dev, + irq, imx_rngc_irq,0 , pdev->name, (void *)rngc); +if (ret) { +dev_err (rngc->dev,"Can't get interrupt working.\n" ); +return ret; + } +if (self_test) { ret =imx_rngc_self_test (rngc);if (ret) {
Greg Kroah-Hartman
maintainerPATCH 378/530 crypto: qat - fix default value of WDT timer
In reply to Greg Kroah-HartmanFrom: Lucas Segarra Fernandez <[email protected]>
[ Upstream commit cc40b04c08400d86d2d6ea0159e0617e717f729c ]
The QAT HW supports an hardware mechanism to detect an accelerator hang. The reporting of a hang occurs after a watchdog timer (WDT) expires.
The value of the WDT set previously was too small and was causing false positives.
Change the default value of the WDT to 0x7000000ULL to avoid this.
--- drivers/crypto/qat/qat_common/adf_gen4_hw_data.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/crypto/qat/qat_common/adf_gen4_hw_data.h +1 -1
@@ -99,7 +99,7 @@ do { \* Timeout is in cycles. Clock speed may vary across products but this * value should be a few milli-seconds. */ -#define ADF_SSM_WDT_DEFAULT_VALUE 0x200000 +#define ADF_SSM_WDT_DEFAULT_VALUE 0x7000000ULL#define ADF_SSM_WDT_PKE_DEFAULT_VALUE 0x8000000#define ADF_SSMWDTL_OFFSET 0x54#define ADF_SSMWDTH_OFFSET 0x5C
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 379/530 crypto: hisilicon/qm - fix missing put dfx access
In reply to Greg Kroah-HartmanFrom: Weili Qian <[email protected]>
[ Upstream commit 5afc904f443de2afd31c4e0686ba178beede86fe ]
In function qm_cmd_write(), if function returns from branch 'atomic_read(&qm->status.flags) == QM_STOP', the got dfx access is forgotten to put.
--- drivers/crypto/hisilicon/qm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/crypto/hisilicon/qm.c +4 -2
@@ -1888,8 +1888,10 @@ static ssize_t qm_cmd_write(struct file *filp, const char __user *buffer,return ret;/* Judge if the instance is being reset. */ -if (unlikely (atomic_read (&qm->status.flags) ==QM_STOP )) -return 0 ; +if (unlikely (atomic_read (&qm->status.flags) ==QM_STOP )) { + ret =0 ; + goto put_dfx_access; + }if (count >QM_DBG_WRITE_LEN ) { ret = -ENOSPC ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 380/530 cgroup/cpuset: Enable update_tasks_cpumask() on top_cpuset
In reply to Greg Kroah-HartmanFrom: Waiman Long <[email protected]>
[ Upstream commit ec5fbdfb99d18482619ac42605cb80fbb56068ee ]
Previously, update_tasks_cpumask() is not supposed to be called with top cpuset. With cpuset partition that takes CPUs away from the top cpuset, adjusting the cpus_mask of the tasks in the top cpuset is necessary. Percpu kthreads, however, are ignored.
--- kernel/cgroup/cpuset.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
kernel/cgroup/cpuset.c +11 -7
@@ -33,6 +33,7 @@#include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/kmod.h> +#include <linux/kthread.h> #include <linux/list.h> #include <linux/mempolicy.h> #include <linux/mm.h>
@@ -1087,10 +1088,18 @@ static void update_tasks_cpumask(struct cpuset *cs) {struct css_task_iter it;struct task_struct *task; +bool top_cs = cs == &top_cpuset;css_task_iter_start (&cs->css,0 , &it); -while ((task =css_task_iter_next (&it))) +while ((task =css_task_iter_next (&it))) { +/* +* Percpu kthreads in top_cpuset are ignored +*/ +if (top_cs && (task->flags &PF_KTHREAD ) && +kthread_is_per_cpu (task)) +continue ;set_cpus_allowed_ptr (task, cs->effective_cpus); + }css_task_iter_end (&it); }
@@ -2052,12 +2061,7 @@ static int update_prstate(struct cpuset *cs, int new_prs)update_flag (CS_CPU_EXCLUSIVE , cs,0 ); } -/* -* Update cpumask of parent's tasks except when it is the top -* cpuset as some system daemons cannot be mapped to other CPUs. -*/ -if (parent != &top_cpuset) -update_tasks_cpumask (parent); +update_tasks_cpumask (parent);if (parent->child_ecpus_count)update_sibling_cpumasks (parent, cs, &tmpmask);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 381/530 iommu/omap: Fix buffer overflow in debugfs
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 184233a5202786b20220acd2d04ddf909ef18f29 ]
There are two issues here:
1) The "len" variable needs to be checked before the very first write. Otherwise if omap2_iommu_dump_ctx() with "bytes" less than 32 it is a buffer overflow.
2) The snprintf() function returns the number of bytes that *would* have been copied if there were enough space. But we want to know the number of bytes which were *actually* copied so use scnprintf() instead.
--- drivers/iommu/omap-iommu-debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/iommu/omap-iommu-debug.c +3 -3
@@ -32,12 +32,12 @@ static inline bool is_omap_iommu_detached(struct omap_iommu *obj)ssize_t bytes; \const char *str ="%20s: %08x\n" ; \const int maxcol =32 ; \ - bytes =snprintf (p, maxcol, str,__stringify (name), \ +if (len < maxcol) \ + goto out; \ + bytes =scnprintf (p, maxcol, str,__stringify (name), \ iommu_read_reg(obj, MMU_##name)); \ p += bytes; \ len -= bytes; \ -if (len < maxcol) \ - goto out; \ }while (0 ) static ssize_t
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 382/530 crypto: akcipher - default implementation for setting a private key
In reply to Greg Kroah-HartmanFrom: Ignat Korchagin <[email protected]>
[ Upstream commit bc155c6c188c2f0c5749993b1405673d25a80389 ]
Changes from v1:
* removed the default implementation from set_pub_key: it is assumed that an implementation must always have this callback defined as there are no use case for an algorithm, which doesn't need a public key
Many akcipher implementations (like ECDSA) support only signature verifications, so they don't have all callbacks defined.
Commit 78a0324f4a53 ("crypto: akcipher - default implementations for request callbacks") introduced default callbacks for sign/verify operations, which just return an error code.
However, these are not enough, because before calling sign the caller would likely call set_priv_key first on the instantiated transform (as the in-kernel testmgr does). This function does not have a default stub, so the kernel crashes, when trying to set a private key on an akcipher, which doesn't support signature generation.
I've noticed this, when trying to add a KAT vector for ECDSA signature to the testmgr.
With this patch the testmgr returns an error in dmesg (as it should) instead of crashing the kernel NULL ptr dereference.
--- crypto/akcipher.c | 8 ++++++++ 1 file changed, 8 insertions(+)
crypto/akcipher.c +8 -0
@@ -120,6 +120,12 @@ static int akcipher_default_op(struct akcipher_request *req)return -ENOSYS ; } +static int akcipher_default_set_key (struct crypto_akcipher *tfm, +const void *key,unsigned int keylen) +{ +return -ENOSYS ; +} +int crypto_register_akcipher (struct akcipher_alg *alg) {struct crypto_alg *base = &alg->base;
@@ -132,6 +138,8 @@ int crypto_register_akcipher(struct akcipher_alg *alg) alg->encrypt = akcipher_default_op;if (!alg->decrypt) alg->decrypt = akcipher_default_op; +if (!alg->set_priv_key) + alg->set_priv_key = akcipher_default_set_key;akcipher_prepare_alg (alg);return crypto_register_alg (base);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 383/530 crypto: ccp - Release dma channels before dmaengine unrgister
In reply to Greg Kroah-HartmanFrom: Koba Ko <[email protected]>
[ Upstream commit 68dbe80f5b510c66c800b9e8055235c5b07e37d1 ]
A warning is shown during shutdown,
__dma_async_device_channel_unregister called while 2 clients hold a reference
WARNING: CPU: 15 PID: 1 at drivers/dma/dmaengine.c:1110 __dma_async_device_channel_unregister+0xb7/0xc0
Call dma_release_channel for occupied channles before dma_async_device_unregister.
--- drivers/crypto/ccp/ccp-dmaengine.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/crypto/ccp/ccp-dmaengine.c +5 -1
@@ -641,6 +641,10 @@ static void ccp_dma_release(struct ccp_device *ccp)for (i =0 ; i < ccp->cmd_q_count; i++) { chan = ccp->ccp_dma_chan + i; dma_chan = &chan->dma_chan; + +if (dma_chan->client_count) +dma_release_channel (dma_chan); +tasklet_kill (&chan->cleanup_tasklet);list_del_rcu (&dma_chan->device_node); }
@@ -766,8 +770,8 @@ void ccp_dmaengine_unregister(struct ccp_device *ccp)if (!dmaengine)return ; -dma_async_device_unregister (dma_dev);ccp_dma_release (ccp); +dma_async_device_unregister (dma_dev);kmem_cache_destroy (ccp->dma_desc_cache);kmem_cache_destroy (ccp->dma_cmd_cache);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 384/530 crypto: inside-secure - Change swab to swab32
In reply to Greg Kroah-HartmanFrom: Peter Harliman Liem <[email protected]>
[ Upstream commit 664593407e936b6438fbfaaf98876910fd31cf9a ]
The use of swab() is causing failures in 64-bit arch, as it translates to __swab64() instead of the intended __swab32(). It eventually causes wrong results in xcbcmac & cmac algo.
--- drivers/crypto/inside-secure/safexcel_hash.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/crypto/inside-secure/safexcel_hash.c +4 -4
@@ -383,7 +383,7 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,u32 x; x = ipad[i] ^ ipad[i +4 ]; - cache[i] ^=swab (x); + cache[i] ^=swab32 (x); } } cache_len =AES_BLOCK_SIZE ;
@@ -821,7 +821,7 @@ static int safexcel_ahash_final(struct ahash_request *areq)u32 *result = (void *)areq->result;/* K3 */ - result[i] =swab (ctx->base.ipad.word[i +4 ]); + result[i] =swab32 (ctx->base.ipad.word[i +4 ]); } areq->result[0 ] ^=0x80 ;// 10- padding crypto_cipher_encrypt_one (ctx->kaes, areq->result, areq->result);
@@ -2106,7 +2106,7 @@ static int safexcel_xcbcmac_setkey(struct crypto_ahash *tfm, const u8 *key,crypto_cipher_encrypt_one (ctx->kaes, (u8 *)key_tmp +AES_BLOCK_SIZE ,"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3" );for (i =0 ; i <3 *AES_BLOCK_SIZE /sizeof (u32); i++) - ctx->base.ipad.word[i] =swab (key_tmp[i]); + ctx->base.ipad.word[i] =swab32 (key_tmp[i]);crypto_cipher_clear_flags (ctx->kaes,CRYPTO_TFM_REQ_MASK ); crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) &
@@ -2189,7 +2189,7 @@ static int safexcel_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,return ret;for (i =0 ; i < len /sizeof (u32); i++) - ctx->base.ipad.word[i +8 ] =swab (aes.key_enc[i]); + ctx->base.ipad.word[i +8 ] =swab32 (aes.key_enc[i]);/* precompute the CMAC key material */ crypto_cipher_clear_flags (ctx->kaes,CRYPTO_TFM_REQ_MASK );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 385/530 crypto: qat - fix DMA transfer direction
In reply to Greg Kroah-HartmanFrom: Damian Muszynski <[email protected]>
[ Upstream commit cf5bb835b7c8a5fee7f26455099cca7feb57f5e9 ]
When CONFIG_DMA_API_DEBUG is selected, while running the crypto self test on the QAT crypto algorithms, the function add_dma_entry() reports a warning similar to the one below, saying that overlapping mappings are not supported. This occurs in tests where the input and the output scatter list point to the same buffers (i.e. two different scatter lists which point to the same chunks of memory).
The logic that implements the mapping uses the flag DMA_BIDIRECTIONAL for both the input and the output scatter lists which leads to overlapped write mappings. These are not supported by the DMA layer.
Fix by specifying the correct DMA transfer directions when mapping buffers. For in-place operations where the input scatter list matches the output scatter list, buffers are mapped once with DMA_BIDIRECTIONAL, otherwise input buffers are mapped using the flag DMA_TO_DEVICE and output buffers are mapped with DMA_FROM_DEVICE. Overlapping a read mapping with a write mapping is a valid case in dma-coherent devices like QAT.
The function that frees and unmaps the buffers, qat_alg_free_bufl() has been changed accordingly to the changes to the mapping function.
DMA-API: 4xxx 0000:06:00.0: cacheline tracking EEXIST, overlapping mappings aren't supported
WARNING: CPU: 53 PID: 4362 at kernel/dma/debug.c:570 add_dma_entry+0x1e9/0x270 ... Call Trace: dma_map_page_attrs+0x82/0x2d0 ? preempt_count_add+0x6a/0xa0 qat_alg_sgl_to_bufl+0x45b/0x990 [intel_qat] qat_alg_aead_dec+0x71/0x250 [intel_qat] crypto_aead_decrypt+0x3d/0x70 test_aead_vec_cfg+0x649/0x810 ? number+0x310/0x3a0 ? vsnprintf+0x2a3/0x550 ? scnprintf+0x42/0x70 ? valid_sg_divisions.constprop.0+0x86/0xa0 ? test_aead_vec+0xdf/0x120 test_aead_vec+0xdf/0x120 alg_test_aead+0x185/0x400 alg_test+0x3d8/0x500 ? crypto_acomp_scomp_free_ctx+0x30/0x30 ? __schedule+0x32a/0x12a0 ? ttwu_queue_wakelist+0xbf/0x110 ? _raw_spin_unlock_irqrestore+0x23/0x40 ? try_to_wake_up+0x83/0x570 ? _raw_spin_unlock_irqrestore+0x23/0x40 ? __set_cpus_allowed_ptr_locked+0xea/0x1b0 ? crypto_acomp_scomp_free_ctx+0x30/0x30 cryptomgr_test+0x27/0x50 kthread+0xe6/0x110 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork+0x1f/0x30
--- drivers/crypto/qat/qat_common/qat_algs.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/crypto/qat/qat_common/qat_algs.c +12 -6
@@ -673,11 +673,14 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst,dma_addr_t blpout = qat_req->buf.bloutp;size_t sz = qat_req->buf.sz;size_t sz_out = qat_req->buf.sz_out; +int bl_dma_dir;int i; + bl_dma_dir = blp != blpout ?DMA_TO_DEVICE :DMA_BIDIRECTIONAL ; +for (i =0 ; i < bl->num_bufs; i++)dma_unmap_single (dev, bl->bufers[i].addr, - bl->bufers[i].len,DMA_BIDIRECTIONAL ); + bl->bufers[i].len, bl_dma_dir);dma_unmap_single (dev, blp, sz,DMA_TO_DEVICE );
@@ -691,7 +694,7 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst,for (i = bufless; i < blout->num_bufs; i++) {dma_unmap_single (dev, blout->bufers[i].addr, blout->bufers[i].len, -DMA_BIDIRECTIONAL ); +DMA_FROM_DEVICE ); }dma_unmap_single (dev, blpout, sz_out,DMA_TO_DEVICE );
@@ -715,6 +718,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,struct scatterlist *sg;size_t sz_out, sz =struct_size (bufl, bufers, n);int node =dev_to_node (&GET_DEV (inst->accel_dev)); +int bufl_dma_dir;if (unlikely (!n))return -EINVAL ;
@@ -732,6 +736,8 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, qat_req->buf.sgl_src_valid = true; } + bufl_dma_dir = sgl != sglout ?DMA_TO_DEVICE :DMA_BIDIRECTIONAL ; +for_each_sg (sgl, sg, n, i) bufl->bufers[i].addr =DMA_MAPPING_ERROR ;
@@ -743,7 +749,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, bufl->bufers[y].addr =dma_map_single (dev,sg_virt (sg), sg->length, -DMA_BIDIRECTIONAL ); + bufl_dma_dir); bufl->bufers[y].len = sg->length;if (unlikely (dma_mapping_error (dev, bufl->bufers[y].addr))) goto err_in;
@@ -786,7 +792,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, bufers[y].addr =dma_map_single (dev,sg_virt (sg), sg->length, -DMA_BIDIRECTIONAL ); +DMA_FROM_DEVICE );if (unlikely (dma_mapping_error (dev, bufers[y].addr))) goto err_out; bufers[y].len = sg->length;
@@ -816,7 +822,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,if (!dma_mapping_error (dev, buflout->bufers[i].addr))dma_unmap_single (dev, buflout->bufers[i].addr, buflout->bufers[i].len, -DMA_BIDIRECTIONAL ); +DMA_FROM_DEVICE );if (!qat_req->buf.sgl_dst_valid)kfree (buflout);
@@ -830,7 +836,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,if (!dma_mapping_error (dev, bufl->bufers[i].addr))dma_unmap_single (dev, bufl->bufers[i].addr, bufl->bufers[i].len, -DMA_BIDIRECTIONAL ); + bufl_dma_dir);if (!qat_req->buf.sgl_src_valid)kfree (bufl);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 386/530 cifs: return correct error in ->calc_signature()
In reply to Greg Kroah-HartmanFrom: Enzo Matsumiya <[email protected]>
[ Upstream commit 09a1f9a168ae1f69f701689429871793174417d2 ]
If an error happens while getting the key or session in the ->calc_signature implementations, 0 (success) is returned. Fix it by returning a proper error code.
Since it seems to be highly unlikely to happen wrap the rc check in unlikely() too.
--- fs/cifs/smb2transport.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
fs/cifs/smb2transport.c +6 -4
@@ -221,9 +221,9 @@ smb2_calc_signature(struct smb_rqst *rqsstruct smb_rqst drqst; ses =smb2_find_smb_ses (server, shdr->SessionId); -if (!ses) { +if (unlikely (!ses)) {cifs_server_dbg (VFS ,"%s: Could not find session\n" , __func__); -return 0 ; +return -ENOENT ; }memset (smb2_signature,0x0 ,SMB2_HMACSHA256_SIZE );
@@ -542,8 +542,10 @@ smb3_calc_signature(struct smb_rqst *rqsu8 key[SMB3_SIGN_KEY_SIZE ]; rc =smb2_get_sign_key (shdr->SessionId, server, key); -if (rc) -return 0 ; +if (unlikely (rc)) { +cifs_server_dbg (VFS ,"%s: Could not get signing key\n" , __func__); +return rc; + }if (allocate_crypto) { rc =cifs_alloc_hash ("cmac(aes)" , &hash, &sdesc);
Greg Kroah-Hartman
maintainerPATCH 387/530 iommu/iova: Fix module config properly
In reply to Greg Kroah-HartmanFrom: Robin Murphy <[email protected]>
[ Upstream commit 4f58330fcc8482aa90674e1f40f601e82f18ed4a ]
IOMMU_IOVA is intended to be an optional library for users to select as and when they desire. Since it can be a module now, this means that built-in code which has chosen not to select it should not fail to link if it happens to have selected as a module by someone else. Replace IS_ENABLED() with IS_REACHABLE() to do the right thing.
--- include/linux/iova.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/iova.h +1 -1
@@ -133,7 +133,7 @@ static inline unsigned long iova_pfn(struct iova_domain *iovad, dma_addr_t iova)return iova >>iova_shift (iovad); } -#if IS_ENABLED (CONFIG_IOMMU_IOVA ) +#if IS_REACHABLE (CONFIG_IOMMU_IOVA )int iova_cache_get (void );void iova_cache_put (void );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 388/530 tracing: kprobe: Fix kprobe event gen test module on exit
In reply to Greg Kroah-HartmanFrom: Yipeng Zou <[email protected]>
[ Upstream commit ac48e189527fae87253ef2bf58892e782fb36874 ]
Correct gen_kretprobe_test clr event para on module exit. This will make it can't to delete.
--- kernel/trace/kprobe_event_gen_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/kprobe_event_gen_test.c +1 -1
@@ -206,7 +206,7 @@ static void __exit kprobe_event_gen_test_exit(void)WARN_ON (kprobe_event_delete ("gen_kprobe_test" ));/* Disable the event or you can't remove it */ -WARN_ON (trace_array_set_clr_event (gen_kprobe_test->tr, +WARN_ON (trace_array_set_clr_event (gen_kretprobe_test->tr,"kprobes" ,"gen_kretprobe_test" , false));
Signature · 9 lines
2.35.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Greg Kroah-Hartman
maintainerPATCH 389/530 tracing: kprobe: Make gen test module work in arm and riscv
In reply to Greg Kroah-HartmanFrom: Yipeng Zou <[email protected]>
[ Upstream commit d8ef45d66c01425ff748e13ef7dd1da7a91cc93c ]
For now, this selftest module can only work in x86 because of the kprobe cmd was fixed use of x86 registers.
This patch adapted to register names under arm and riscv, So that this module can be worked on those platform.
--- kernel/trace/kprobe_event_gen_test.c | 47 +++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-)
kernel/trace/kprobe_event_gen_test.c +43 -4
@@ -35,6 +35,45 @@static struct trace_event_file *gen_kprobe_test;static struct trace_event_file *gen_kretprobe_test; +#define KPROBE_GEN_TEST_FUNC "do_sys_open" + +/* X86 */ +#if defined(CONFIG_X86_64 ) || defined(CONFIG_X86_32 ) +#define KPROBE_GEN_TEST_ARG0 "dfd=%ax" +#define KPROBE_GEN_TEST_ARG1 "filename=%dx" +#define KPROBE_GEN_TEST_ARG2 "flags=%cx" +#define KPROBE_GEN_TEST_ARG3 "mode=+4($stack)" + +/* ARM64 */ +#elif defined(CONFIG_ARM64 ) +#define KPROBE_GEN_TEST_ARG0 "dfd=%x0" +#define KPROBE_GEN_TEST_ARG1 "filename=%x1" +#define KPROBE_GEN_TEST_ARG2 "flags=%x2" +#define KPROBE_GEN_TEST_ARG3 "mode=%x3" + +/* ARM */ +#elif defined(CONFIG_ARM ) +#define KPROBE_GEN_TEST_ARG0 "dfd=%r0" +#define KPROBE_GEN_TEST_ARG1 "filename=%r1" +#define KPROBE_GEN_TEST_ARG2 "flags=%r2" +#define KPROBE_GEN_TEST_ARG3 "mode=%r3" + +/* RISCV */ +#elif defined(CONFIG_RISCV ) +#define KPROBE_GEN_TEST_ARG0 "dfd=%a0" +#define KPROBE_GEN_TEST_ARG1 "filename=%a1" +#define KPROBE_GEN_TEST_ARG2 "flags=%a2" +#define KPROBE_GEN_TEST_ARG3 "mode=%a3" + +/* others */ +#else +#define KPROBE_GEN_TEST_ARG0 NULL +#define KPROBE_GEN_TEST_ARG1 NULL +#define KPROBE_GEN_TEST_ARG2 NULL +#define KPROBE_GEN_TEST_ARG3 NULL +#endif + +/* * Test to make sure we can create a kprobe event, then add more * fields.
@@ -58,14 +97,14 @@ static int __init test_gen_kprobe_cmd(void)* fields. */ ret =kprobe_event_gen_cmd_start (&cmd,"gen_kprobe_test" , -"do_sys_open" , -"dfd=%ax" ,"filename=%dx" ); +KPROBE_GEN_TEST_FUNC , +KPROBE_GEN_TEST_ARG0 ,KPROBE_GEN_TEST_ARG1 );if (ret) goto free;/* Use kprobe_event_add_fields to add the rest of the fields */ - ret =kprobe_event_add_fields (&cmd,"flags=%cx" ,"mode=+4($stack)" ); + ret =kprobe_event_add_fields (&cmd,KPROBE_GEN_TEST_ARG2 ,KPROBE_GEN_TEST_ARG3 );if (ret) goto free;
@@ -128,7 +167,7 @@ static int __init test_gen_kretprobe_cmd(void)* Define the kretprobe event. */ ret =kretprobe_event_gen_cmd_start (&cmd,"gen_kretprobe_test" , -"do_sys_open" , +KPROBE_GEN_TEST_FUNC ,"$retval" );if (ret) goto free;
Signature · 9 lines
2.35.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Greg Kroah-Hartman
maintainerPATCH 390/530 tracing/osnoise: Fix possible recursive locking in stop_per_cpu_kthreads
In reply to Greg Kroah-HartmanFrom: Nico Pache <[email protected]>
[ Upstream commit 99ee9317a1305cd5626736785c8cb38b0e47686c ]
There is a recursive lock on the cpu_hotplug_lock.
In kernel/trace/trace_osnoise.c:<start/stop>_per_cpu_kthreads:
- start_per_cpu_kthreads calls cpus_read_lock() and if start_kthreads returns a error it will call stop_per_cpu_kthreads.
- stop_per_cpu_kthreads then calls cpus_read_lock() again causing deadlock.
Fix this by calling cpus_read_unlock() before calling stop_per_cpu_kthreads. This behavior can also be seen in commit f46b16520a08 ("trace/hwlat: Implement the per-cpu mode").
This error was noticed during the LTP ftrace-stress-test:
WARNING: possible recursive locking detected
--------------------------------------------
sh/275006 is trying to acquire lock:ffffffffb02f5400 (cpu_hotplug_lock){++++}-{0:0}, at: stop_per_cpu_kthreads
but task is already holding lock:ffffffffb02f5400 (cpu_hotplug_lock){++++}-{0:0}, at: start_per_cpu_kthreads
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
---- lock(cpu_hotplug_lock);
lock(cpu_hotplug_lock);
*** DEADLOCK ***
May be due to missing lock nesting notation
3 locks held by sh/275006:
#0: ffff8881023f0470 (sb_writers#24){.+.+}-{0:0}, at: ksys_write #1: ffffffffb084f430 (trace_types_lock){+.+.}-{3:3}, at: rb_simple_write #2: ffffffffb02f5400 (cpu_hotplug_lock){++++}-{0:0}, at: start_per_cpu_kthreads
--- kernel/trace/trace_osnoise.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/trace/trace_osnoise.c +2 -1
@@ -1598,8 +1598,9 @@ static int start_per_cpu_kthreads(struct trace_array *tr)for_each_cpu (cpu, current_mask) { retval =start_kthread (cpu);if (retval) { +cpus_read_unlock ();stop_per_cpu_kthreads (); -break ; +return retval; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 391/530 kbuild: remove the target in signal traps when interrupted
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
[ Upstream commit a7f3257da8a86b96fb9bf1bba40ae0bbd7f1885a ]
When receiving some signal, GNU Make automatically deletes the target if it has already been changed by the interrupted recipe.
If the target is possibly incomplete due to interruption, it must be deleted so that it will be remade from scratch on the next run of make. Otherwise, the target would remain corrupted permanently because its timestamp had already been updated.
Thanks to this behavior of Make, you can stop the build any time by pressing Ctrl-C, and just run 'make' to resume it.
Kbuild also relies on this feature, but it is equivalently important for any build systems that make decisions based on timestamps (if you want to support Ctrl-C reliably).
However, this does not always work as claimed; Make immediately dies with Ctrl-C if its stderr goes into a pipe.
[Test Makefile]
foo:
echo hello > $@
sleep 3
echo world >> $@
[Test Result]
$ make # hit Ctrl-C
echo hello > foo
sleep 3
^Cmake: *** Deleting file 'foo'
make: *** [Makefile:3: foo] Interrupt $ make 2>&1 | cat # hit Ctrl-C
echo hello > foo
sleep 3
^C$ # 'foo' is often left-overThe reason is because SIGINT is sent to the entire process group. In this example, SIGINT kills 'cat', and 'make' writes the message to the closed pipe, then dies with SIGPIPE before cleaning the target.
A typical bad scenario (as reported by [1], [2]) is to save build log by using the 'tee' command:
$ make 2>&1 | tee log
This can be problematic for any build systems based on Make, so I hope it will be fixed in GNU Make. The maintainer of GNU Make stated this is a long-standing issue and difficult to fix [3]. It has not been fixed yet as of writing.
So, we cannot rely on Make cleaning the target. We can do it by ourselves, in signal traps.
As far as I understand, Make takes care of SIGHUP, SIGINT, SIGQUIT, and SITERM for the target removal. I added the traps for them, and also for SIGPIPE just in case cmd_* rule prints something to stdout or stderr (but I did not observe an actual case where SIGPIPE was triggered).
[Note 1]
The trap handler might be worth explaining.
rm -f $@; trap - $(sig); kill -s $(sig) $$
This lets the shell kill itself by the signal it caught, so the parent process can tell the child has exited on the signal. Generally, this is a proper manner for handling signals, in case the calling program (like Bash) may monitor WIFSIGNALED() and WTERMSIG() for WCE although this may not be a big deal here because GNU Make handles SIGHUP, SIGINT, SIGQUIT in WUE and SIGTERM in IUE.
IUE - Immediate Unconditional Exit
WUE - Wait and Unconditional Exit
WCE - Wait and Cooperative Exit
For details, see "Proper handling of SIGINT/SIGQUIT" [4].
[Note 2]
Reverting 392885ee82d3 ("kbuild: let fixdep directly write to .*.cmd files") would directly address [1], but it only saves if_changed_dep. As reported in [2], all commands that use redirection can potentially leave an empty (i.e. broken) target.
[Note 3]
Another (even safer) approach might be to always write to a temporary file, and rename it to $@ at the end of the recipe.
<command> > $(tmp-target) mv $(tmp-target) $@
It would require a lot of Makefile changes, and result in ugly code, so I did not take it.
[Note 4]
A little more thoughts about a pattern rule with multiple targets (or a grouped target).
%.x %.y: %.z
<recipe>When interrupted, GNU Make deletes both %.x and %.y, while this solution only deletes $@. Probably, this is not a big deal. The next run of make will execute the rule again to create $@ along with the other files.
[1]: https://lore.kernel.org/all/[email protected]/
[2]: https://lore.kernel.org/all/[email protected]/
[3]: https://lists.gnu.org/archive/html/help-make/2021-06/msg00001.html
[4]: https://www.cons.org/cracauer/sigint.html
--- scripts/Kbuild.include | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-)
scripts/Kbuild.include +22 -1
@@ -96,8 +96,29 @@ echo-cmd = $(if $($(quiet)cmd_$(1)),\ quiet_redirect := silent_redirect := exec >/dev/null; +# Delete the target on interruption +# +# GNU Make automatically deletes the target if it has already been changed by +# the interrupted recipe. So, you can safely stop the build by Ctrl-C (Make +# will delete incomplete targets), and resume it later. +# +# However, this does not work when the stderr is piped to another program, like +# $ make >&2 | tee log +# Make dies with SIGPIPE before cleaning the targets. +# +# To address it, we clean the target in signal traps. +# +# Make deletes the target when it catches SIGHUP, SIGINT, SIGQUIT, SIGTERM. +# So, we cover them, and also SIGPIPE just in case. +# +# Of course, this is unneeded for phony targets. +delete-on-interrupt = \ + $(if $(filter-out $(PHONY), $@), \ + $(foreach sig, HUP INT QUIT TERM PIPE, \ + trap 'rm -f $@; trap - $(sig); kill -s $(sig) $$$$' $(sig);)) + # printing commands -cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(cmd_$(1)) +cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(delete-on-interrupt) $(cmd_$(1)) ### # if_changed - execute command if any prerequisite is newer than
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 392/530 kbuild: rpm-pkg: fix breakage when V=1 is used
In reply to Greg Kroah-HartmanFrom: Janis Schoetterl-Glausch <[email protected]>
[ Upstream commit 2e07005f4813a9ff6e895787e0c2d1fea859b033 ]
Doing make V=1 binrpm-pkg results in:
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.EgV6qJ
+ umask 022
+ cd .
+ /bin/rm -rf /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x
+ /bin/mkdir -p /home/scgl/rpmbuild/BUILDROOT
+ /bin/mkdir /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x
+ mkdir -p /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x/boot
+ make -f ./Makefile image_name
+ cp test -e include/generated/autoconf.h -a -e include/config/auto.conf || ( \ echo >&2; \ echo >&2 " ERROR: Kernel configuration is invalid."; \ echo >&2 " include/generated/autoconf.h or include/config/auto.conf are missing.";\ echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \ echo >&2 ; \ /bin/false) arch/s390/boot/bzImage /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x/boot/vmlinuz-6.0.0-rc5+
cp: invalid option -- 'e'
Try 'cp --help' for more information.
error: Bad exit status from /var/tmp/rpm-tmp.EgV6qJ (%install)
Because the make call to get the image name is verbose and prints additional information.
--- scripts/package/mkspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
scripts/package/mkspec +2 -2
@@ -85,10 +85,10 @@ $S mkdir -p %{buildroot}/boot %ifarch ia64 mkdir -p %{buildroot}/boot/efi - cp \$($MAKE image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE + cp \$($MAKE -s image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE ln -s efi/vmlinuz-$KERNELRELEASE %{buildroot}/boot/ %else - cp \$($MAKE image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE + cp \$($MAKE -s image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE %endif $M $MAKE %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} modules_install $MAKE %{?_smp_mflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 393/530 crypto: marvell/octeontx - prevent integer overflows
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit caca37cf6c749ff0303f68418cfe7b757a4e0697 ]
The "code_length" value comes from the firmware file. If your firmware is untrusted realistically there is probably very little you can do to protect yourself. Still we try to limit the damage as much as possible. Also Smatch marks any data read from the filesystem as untrusted and prints warnings if it not capped correctly.
The "code_length * 2" can overflow. The round_up(ucode_size, 16) + sizeof() expression can overflow too. Prevent these overflows.
--- .../crypto/marvell/octeontx/otx_cptpf_ucode.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c +16 -2
@@ -286,6 +286,7 @@ static int process_tar_file(struct device *dev,struct tar_ucode_info_t *tar_info;struct otx_cpt_ucode_hdr *ucode_hdr;int ucode_type, ucode_size; +unsigned int code_length;/* * If size is less than microcode header size then don't report
@@ -303,7 +304,13 @@ static int process_tar_file(struct device *dev,if (get_ucode_type (ucode_hdr, &ucode_type))return 0 ; - ucode_size =ntohl (ucode_hdr->code_length) *2 ; + code_length =ntohl (ucode_hdr->code_length); +if (code_length >=INT_MAX /2 ) { +dev_err (dev,"Invalid code_length %u\n" , code_length); +return -EINVAL ; + } + + ucode_size = code_length *2 ;if (!ucode_size || (size <round_up (ucode_size,16 ) +sizeof (struct otx_cpt_ucode_hdr ) +OTX_CPT_UCODE_SIGN_LEN )) {dev_err (dev,"Ucode %s invalid size\n" , filename);
@@ -886,6 +893,7 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode, {struct otx_cpt_ucode_hdr *ucode_hdr;const struct firmware *fw; +unsigned int code_length;int ret;set_ucode_filename (ucode, ucode_filename);
@@ -896,7 +904,13 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode, ucode_hdr = (struct otx_cpt_ucode_hdr *) fw->data;memcpy (ucode->ver_str, ucode_hdr->ver_str,OTX_CPT_UCODE_VER_STR_SZ ); ucode->ver_num = ucode_hdr->ver_num; - ucode->size =ntohl (ucode_hdr->code_length) *2 ; + code_length =ntohl (ucode_hdr->code_length); +if (code_length >=INT_MAX /2 ) { +dev_err (dev,"Ucode invalid code_length %u\n" , code_length); + ret = -EINVAL ; + goto release_fw; + } + ucode->size = code_length *2 ;if (!ucode->size || (fw->size <round_up (ucode->size,16 ) +sizeof (struct otx_cpt_ucode_hdr ) +OTX_CPT_UCODE_SIGN_LEN )) {dev_err (dev,"Ucode %s invalid size\n" , ucode_filename);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 394/530 crypto: cavium - prevent integer overflow loading firmware
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 2526d6bf27d15054bb0778b2f7bc6625fd934905 ]
The "code_length" value comes from the firmware file. If your firmware is untrusted realistically there is probably very little you can do to protect yourself. Still we try to limit the damage as much as possible. Also Smatch marks any data read from the filesystem as untrusted and prints warnings if it not capped correctly.
The "ntohl(ucode->code_length) * 2" multiplication can have an integer overflow.
--- drivers/crypto/cavium/cpt/cptpf_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/crypto/cavium/cpt/cptpf_main.c +4 -2
@@ -253,6 +253,7 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae)const struct firmware *fw_entry;struct device *dev = &cpt->pdev->dev;struct ucode_header *ucode; +unsigned int code_length;struct microcode *mcode;int j, ret =0 ;
@@ -263,11 +264,12 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae) ucode = (struct ucode_header *)fw_entry->data; mcode = &cpt->mcode[cpt->next_mc_idx];memcpy (mcode->version, (u8 *)fw_entry->data,CPT_UCODE_VERSION_SZ ); - mcode->code_size =ntohl (ucode->code_length) *2 ; -if (!mcode->code_size) { + code_length =ntohl (ucode->code_length); +if (code_length ==0 || code_length >=INT_MAX /2 ) { ret = -EINVAL ; goto fw_release; } + mcode->code_size = code_length *2 ; mcode->is_ae = is_ae; mcode->core_mask =0ULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 395/530 thermal/drivers/qcom/tsens-v0_1: Fix MSM8939 fourth sensor hw_id
In reply to Greg Kroah-HartmanFrom: Vincent Knecht <[email protected]>
[ Upstream commit b0c883e900702f408d62cf92b0ef01303ed69be9 ]
Reading temperature from this sensor fails with 'Invalid argument'.
Looking at old vendor dts [1], its hw_id should be 3 instead of 4. Change this hw_id accordingly.
--- drivers/thermal/qcom/tsens-v0_1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/thermal/qcom/tsens-v0_1.c +1 -1
@@ -604,7 +604,7 @@ static const struct tsens_ops ops_8939 = {struct tsens_plat_data data_8939 = { .num_sensors =10 , .ops = &ops_8939, - .hw_ids = (unsigned int []){0 ,1 ,2 ,4 ,5 ,6 ,7 ,8 ,9 ,10 }, + .hw_ids = (unsigned int []){0 ,1 ,2 ,3 ,5 ,6 ,7 ,8 ,9 ,10 }, .feat = &tsens_v0_1_feat, .fields = tsens_v0_1_regfields,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 396/530 ACPI: APEI: do not add task_work to kernel thread to avoid memory leak
In reply to Greg Kroah-HartmanFrom: Shuai Xue <[email protected]>
[ Upstream commit 415fed694fe11395df56e05022d6e7cee1d39dd3 ]
If an error is detected as a result of user-space process accessing a corrupt memory location, the CPU may take an abort. Then the platform firmware reports kernel via NMI like notifications, e.g. NOTIFY_SEA, NOTIFY_SOFTWARE_DELEGATED, etc.
For NMI like notifications, commit 7f17b4a121d0 ("ACPI: APEI: Kick the memory_failure() queue for synchronous errors") keep track of whether memory_failure() work was queued, and make task_work pending to flush out the queue so that the work is processed before return to user-space.
The code use init_mm to check whether the error occurs in user space:
if (current->mm != &init_mm)
The condition is always true, becase _nobody_ ever has "init_mm" as a real VM any more.
In addition to abort, errors can also be signaled as asynchronous exceptions, such as interrupt and SError. In such case, the interrupted current process could be any kind of thread. When a kernel thread is interrupted, the work ghes_kick_task_work deferred to task_work will never be processed because entry_handler returns to call ret_to_kernel() instead of ret_to_user(). Consequently, the estatus_node alloced from ghes_estatus_pool in ghes_in_nmi_queue_one_entry() will not be freed. After around 200 allocations in our platform, the ghes_estatus_pool will run of memory and ghes_in_nmi_queue_one_entry() returns ENOMEM. As a result, the event failed to be processed.
sdei: event 805 on CPU 113 failed with error: -2
Finally, a lot of unhandled events may cause platform firmware to exceed some threshold and reboot.
The condition should generally just do
if (current->mm)
as described in active_mm.rst documentation.
Then if an asynchronous error is detected when a kernel thread is running, (e.g. when detected by a background scrubber), do not add task_work to it as the original patch intends to do.
--- drivers/acpi/apei/ghes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/apei/ghes.c +1 -1
@@ -985,7 +985,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)ghes_estatus_cache_add (generic, estatus); } -if (task_work_pending && current->mm != &init_mm) { +if (task_work_pending && current->mm) { estatus_node->task_work.func = ghes_kick_task_work; estatus_node->task_work_cpu =smp_processor_id (); ret = task_work_add(current, &estatus_node->task_work,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 397/530 f2fs: fix race condition on setting FI_NO_EXTENT flag
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 07725adc55c0a414c10acb5c8c86cea34b95ddef ]
The following scenarios exist.
process A: process B:
->f2fs_drop_extent_tree ->f2fs_update_extent_cache_range
->f2fs_update_extent_tree_range
->write_lock
->set_inode_flag
->is_inode_flag_set
->__free_extent_tree // Shouldn't
// have been
// cleaned up
// here->write_lock
In this case, the "FI_NO_EXTENT" flag is set between f2fs_update_extent_tree_range and is_inode_flag_set by other process. it leads to clearing the whole exten tree which should not have happened. And we fix it by move the setting it to the range of write_lock.
--- fs/f2fs/extent_cache.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/f2fs/extent_cache.c +1 -2
@@ -804,9 +804,8 @@ void f2fs_drop_extent_tree(struct inode *inode)if (!f2fs_may_extent_tree (inode))return ; -set_inode_flag (inode,FI_NO_EXTENT ); -write_lock (&et->lock); +set_inode_flag (inode,FI_NO_EXTENT );__free_extent_tree (sbi, et);if (et->largest.len) { et->largest.len =0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 398/530 f2fs: fix to account FS_CP_DATA_IO correctly
In reply to Greg Kroah-HartmanFrom: Chao Yu <[email protected]>
[ Upstream commit d80afefb17e01aa0c46a8eebc01882e0ebd8b0f6 ]
f2fs_inode_info.cp_task was introduced for FS_CP_DATA_IO accounting since commit b0af6d491a6b ("f2fs: add app/fs io stat").
However, cp_task usage coverage has been increased due to below commits:
commit 040d2bb318d1 ("f2fs: fix to avoid deadloop if data_flush is on") commit 186857c5a14a ("f2fs: fix potential recursive call when enabling data_flush")
So that, if data_flush mountoption is on, when data flush was triggered from background, the IO from data flush will be accounted as checkpoint IO type incorrectly.
In order to fix this issue, this patch splits cp_task into two:
a) cp_task: used for IO accounting
b) wb_task: used to avoid deadlock
--- fs/f2fs/checkpoint.c | 13 +++++++++---- fs/f2fs/data.c | 4 ++-- fs/f2fs/f2fs.h | 4 +++- fs/f2fs/segment.c | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-)
fs/f2fs/checkpoint.c +9 -4
@@ -1062,7 +1062,8 @@ void f2fs_remove_dirty_inode(struct inode *inode)spin_unlock (&sbi->inode_lock[type]); } -int f2fs_sync_dirty_inodes (struct f2fs_sb_info *sbi,enum inode_type type) +int f2fs_sync_dirty_inodes (struct f2fs_sb_info *sbi,enum inode_type type, +bool from_cp) {struct list_head *head;struct inode *inode;
@@ -1097,11 +1098,15 @@ int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)if (inode) {unsigned long cur_ino = inode->i_ino; -F2FS_I (inode)->cp_task = current; +if (from_cp) +F2FS_I (inode)->cp_task = current; +F2FS_I (inode)->wb_task = current;filemap_fdatawrite (inode->i_mapping); -F2FS_I (inode)->cp_task =NULL ; +F2FS_I (inode)->wb_task =NULL ; +if (from_cp) +F2FS_I (inode)->cp_task =NULL ;iput (inode);/* We need to give cpu to another writers. */
@@ -1230,7 +1235,7 @@ static int block_operations(struct f2fs_sb_info *sbi)/* write all the dirty dentry pages */ if (get_pages (sbi,F2FS_DIRTY_DENTS )) {f2fs_unlock_all (sbi); - err =f2fs_sync_dirty_inodes (sbi,DIR_INODE ); + err =f2fs_sync_dirty_inodes (sbi,DIR_INODE , true);if (err)return err;cond_resched ();
fs/f2fs/data.c +2 -2
@@ -2862,7 +2862,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted, }unlock_page (page);if (!S_ISDIR (inode->i_mode) && !IS_NOQUOTA (inode) && - !F2FS_I (inode)->cp_task && allow_balance) + !F2FS_I (inode)->wb_task && allow_balance)f2fs_balance_fs (sbi, need_balance_fs);if (unlikely (f2fs_cp_error (sbi))) {
@@ -3160,7 +3160,7 @@ static inline bool __should_serialize_io(struct inode *inode, struct writeback_control *wbc) {/* to avoid deadlock in path of data flush */ -if (F2FS_I (inode)->cp_task) +if (F2FS_I (inode)->wb_task)return false;if (!S_ISREG (inode->i_mode))
fs/f2fs/f2fs.h +3 -1
@@ -749,6 +749,7 @@ struct f2fs_inode_info {unsigned int clevel;/* maximum level of given file name */ struct task_struct *task;/* lookup and create consistency */ struct task_struct *cp_task;/* separate cp/wb IO stats*/ +struct task_struct *wb_task;/* indicate inode is in context of writeback */ nid_t i_xattr_nid;/* node id that contains xattrs */ loff_t last_disk_size;/* lastly written file size */ spinlock_t i_size_lock;/* protect last_disk_size */
@@ -3573,7 +3574,8 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi);int f2fs_get_valid_checkpoint (struct f2fs_sb_info *sbi);void f2fs_update_dirty_page (struct inode *inode,struct page *page);void f2fs_remove_dirty_inode (struct inode *inode); -int f2fs_sync_dirty_inodes (struct f2fs_sb_info *sbi,enum inode_type type); +int f2fs_sync_dirty_inodes (struct f2fs_sb_info *sbi,enum inode_type type, +bool from_cp);void f2fs_wait_on_all_pages (struct f2fs_sb_info *sbi,int type);u64 f2fs_get_sectors_written (struct f2fs_sb_info *sbi);int f2fs_write_checkpoint (struct f2fs_sb_info *sbi,struct cp_control *cpc);
fs/f2fs/segment.c +1 -1
@@ -575,7 +575,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi, bool from_bg)mutex_lock (&sbi->flush_lock);blk_start_plug (&plug); -f2fs_sync_dirty_inodes (sbi,FILE_INODE ); +f2fs_sync_dirty_inodes (sbi,FILE_INODE , false);blk_finish_plug (&plug);mutex_unlock (&sbi->flush_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 399/530 selftest: tpm2: Add Client.__del__() to close /dev/tpm* handle
In reply to Greg Kroah-HartmanFrom: Stefan Berger <[email protected]>
[ Upstream commit 2d869f0b458547386fbcd8cf3004b271b7347b7f ]
The following output can bee seen when the test is executed:
test_flush_context (tpm2_tests.SpaceTest) ... \
/usr/lib64/python3.6/unittest/case.py:605: ResourceWarning: \
unclosed file <_io.FileIO name='/dev/tpmrm0' mode='rb+' closefd=True>An instance of Client does not implicitly close /dev/tpm* handle, once it gets destroyed. Close the file handle in the class destructor Client.__del__().
--- tools/testing/selftests/tpm2/tpm2.py | 4 ++++ 1 file changed, 4 insertions(+)
tools/testing/selftests/tpm2/tpm2.py +4 -0
@@ -370,6 +370,10 @@ class Client: fcntl.fcntl(self.tpm, fcntl.F_SETFL, flags) self.tpm_poll = select.poll() + def __del__(self): + if self.tpm: + self.tpm.close() + def close(self): self.tpm.close()
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 400/530 fs: dlm: fix race in lowcomms
In reply to Greg Kroah-HartmanFrom: Alexander Aring <[email protected]>
[ Upstream commit 30ea3257e8766027c4d8d609dcbd256ff9a76073 ]
This patch fixes a race between queue_work() in _dlm_lowcomms_commit_msg() and srcu_read_unlock(). The queue_work() can take the final reference of a dlm_msg and so msg->idx can contain garbage which is signaled by the following warning:
[ 676.237050] ------------[ cut here ]------------ [ 676.237052] WARNING: CPU: 0 PID: 1060 at include/linux/srcu.h:189 dlm_lowcomms_commit_msg+0x41/0x50 [ 676.238945] Modules linked in: dlm_locktorture torture rpcsec_gss_krb5 intel_rapl_msr intel_rapl_common iTCO_wdt iTCO_vendor_support qxl kvm_intel drm_ttm_helper vmw_vsock_virtio_transport kvm vmw_vsock_virtio_transport_common ttm irqbypass crc32_pclmul joydev crc32c_intel serio_raw drm_kms_helper vsock virtio_scsi virtio_console virtio_balloon snd_pcm drm syscopyarea sysfillrect sysimgblt snd_timer fb_sys_fops i2c_i801 lpc_ich snd i2c_smbus soundcore pcspkr [ 676.244227] CPU: 0 PID: 1060 Comm: lock_torture_wr Not tainted 5.19.0-rc3+ #1546 [ 676.245216] Hardware name: Red Hat KVM/RHEL-AV, BIOS 1.16.0-2.module+el8.7.0+15506+033991b0 04/01/2014 [ 676.246460] RIP: 0010:dlm_lowcomms_commit_msg+0x41/0x50 [ 676.247132] Code: fe ff ff ff 75 24 48 c7 c6 bd 0f 49 bb 48 c7 c7 38 7c 01 bd e8 00 e7 ca ff 89 de 48 c7 c7 60 78 01 bd e8 42 3d cd ff 5b 5d c3 <0f> 0b eb d8 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 [ 676.249253] RSP: 0018:ffffa401c18ffc68 EFLAGS: 00010282 [ 676.249855] RAX: 0000000000000001 RBX: 00000000ffff8b76 RCX: 0000000000000006 [ 676.250713] RDX: 0000000000000000 RSI: ffffffffbccf3a10 RDI: ffffffffbcc7b62e [ 676.251610] RBP: ffffa401c18ffc70 R08: 0000000000000001 R09: 0000000000000001 [ 676.252481] R10: 0000000000000001 R11: 0000000000000001 R12: 0000000000000005 [ 676.253421] R13: ffff8b76786ec370 R14: ffff8b76786ec370 R15: ffff8b76786ec480 [ 676.254257] FS: 0000000000000000(0000) GS:ffff8b7777800000(0000) knlGS:0000000000000000 [ 676.255239] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 676.255897] CR2: 00005590205d88b8 CR3: 000000017656c003 CR4: 0000000000770ee0 [ 676.256734] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 676.257567] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 676.258397] PKRU: 55555554 [ 676.258729] Call Trace: [ 676.259063] <TASK> [ 676.259354] dlm_midcomms_commit_mhandle+0xcc/0x110 [ 676.259964] queue_bast+0x8b/0xb0 [ 676.260423] grant_pending_locks+0x166/0x1b0 [ 676.261007] _unlock_lock+0x75/0x90 [ 676.261469] unlock_lock.isra.57+0x62/0xa0 [ 676.262009] dlm_unlock+0x21e/0x330 [ 676.262457] ? lock_torture_stats+0x80/0x80 [dlm_locktorture] [ 676.263183] torture_unlock+0x5a/0x90 [dlm_locktorture] [ 676.263815] ? preempt_count_sub+0xba/0x100 [ 676.264361] ? complete+0x1d/0x60 [ 676.264777] lock_torture_writer+0xb8/0x150 [dlm_locktorture] [ 676.265555] kthread+0x10a/0x130 [ 676.266007] ? kthread_complete_and_exit+0x20/0x20 [ 676.266616] ret_from_fork+0x22/0x30 [ 676.267097] </TASK> [ 676.267381] irq event stamp: 9579855 [ 676.267824] hardirqs last enabled at (9579863): [<ffffffffbb14e6f8>] __up_console_sem+0x58/0x60 [ 676.268896] hardirqs last disabled at (9579872): [<ffffffffbb14e6dd>] __up_console_sem+0x3d/0x60 [ 676.270008] softirqs last enabled at (9579798): [<ffffffffbc200349>] __do_softirq+0x349/0x4c7 [ 676.271438] softirqs last disabled at (9579897): [<ffffffffbb0d54c0>] irq_exit_rcu+0xb0/0xf0 [ 676.272796] ---[ end trace 0000000000000000 ]---
I reproduced this warning with dlm_locktorture test which is currently not upstream. However this patch fix the issue by make a additional refcount between dlm_lowcomms_new_msg() and dlm_lowcomms_commit_msg(). In case of the race the kref_put() in dlm_lowcomms_commit_msg() will be the final put.
--- fs/dlm/lowcomms.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/dlm/lowcomms.c +4 -0
@@ -1319,6 +1319,8 @@ struct dlm_msg *dlm_lowcomms_new_msg(int nodeid, int len, gfp_t allocation,return NULL ; } +/* for dlm_lowcomms_commit_msg() */ +kref_get (&msg->ref);/* we assume if successful commit must called */ msg->idx = idx;return msg;
@@ -1353,6 +1355,8 @@ void dlm_lowcomms_commit_msg(struct dlm_msg *msg) {_dlm_lowcomms_commit_msg (msg);srcu_read_unlock (&connections_srcu, msg->idx); +/* because dlm_lowcomms_new_msg() */ +kref_put (&msg->ref, dlm_msg_release); }void dlm_lowcomms_put_msg (struct dlm_msg *msg)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 401/530 rcu: Avoid triggering strict-GP irq-work when RCU is idle
In reply to Greg Kroah-HartmanFrom: Zqiang <[email protected]>
[ Upstream commit 621189a1fe93cb2b34d62c5cdb9e258bca044813 ]
Kernels built with PREEMPT_RCU=y and RCU_STRICT_GRACE_PERIOD=y trigger irq-work from rcu_read_unlock(), and the resulting irq-work handler invokes rcu_preempt_deferred_qs_handle(). The point of this triggering is to force grace periods to end quickly in order to give tools like KASAN a better chance of detecting RCU usage bugs such as leaking RCU-protected pointers out of an RCU read-side critical section.
However, this irq-work triggering is unconditional. This works, but there is no point in doing this irq-work unless the current grace period is waiting on the running CPU or task, which is not the common case. After all, in the common case there are many rcu_read_unlock() calls per CPU per grace period.
This commit therefore triggers the irq-work only when the current grace period is waiting on the running CPU or task.
This change was tested as follows on a four-CPU system:
echo rcu_preempt_deferred_qs_handler > /sys/kernel/debug/tracing/set_ftrace_filter echo 1 > /sys/kernel/debug/tracing/function_profile_enabled
insmod rcutorture.ko
sleep 20
rmmod rcutorture.ko
echo 0 > /sys/kernel/debug/tracing/function_profile_enabled
echo > /sys/kernel/debug/tracing/set_ftrace_filter
This procedure produces results in this per-CPU set of files:
/sys/kernel/debug/tracing/trace_stat/function*
Sample output from one of these files is as follows:
Function Hit Time Avg s^2 -------- --- ---- --- --- rcu_preempt_deferred_qs_handle 838746 182650.3 us 0.217 us 0.004 us
The baseline sum of the "Hit" values (the number of calls to this function) was 3,319,015. With this commit, that sum was 1,140,359, for a 2.9x reduction. The worst-case variance across the CPUs was less than 25%, so this large effect size is statistically significant.
The raw data is available in the Link: URL.
--- kernel/rcu/tree_plugin.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/rcu/tree_plugin.h +2 -1
@@ -638,7 +638,8 @@ static void rcu_read_unlock_special(struct task_struct *t) expboost = (t->rcu_blocked_node &&READ_ONCE (t->rcu_blocked_node->exp_tasks)) || (rdp->grpmask &READ_ONCE (rnp->expmask)) || -IS_ENABLED (CONFIG_RCU_STRICT_GRACE_PERIOD ) || + (IS_ENABLED (CONFIG_RCU_STRICT_GRACE_PERIOD ) && + ((rdp->grpmask &READ_ONCE (rnp->qsmask)) || t->rcu_blocked_node)) || (IS_ENABLED (CONFIG_RCU_BOOST ) && irqs_were_disabled && t->rcu_blocked_node);// Need to defer quiescent state until everything is enabled.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 402/530 rcu: Back off upon fill_page_cache_func() allocation failure
In reply to Greg Kroah-HartmanFrom: Michal Hocko <[email protected]>
[ Upstream commit 093590c16b447f53e66771c8579ae66c96f6ef61 ]
The fill_page_cache_func() function allocates couple of pages to store kvfree_rcu_bulk_data structures. This is a lightweight (GFP_NORETRY) allocation which can fail under memory pressure. The function will, however keep retrying even when the previous attempt has failed.
This retrying is in theory correct, but in practice the allocation is invoked from workqueue context, which means that if the memory reclaim gets stuck, these retries can hog the worker for quite some time. Although the workqueues subsystem automatically adjusts concurrency, such adjustment is not guaranteed to happen until the worker context sleeps. And the fill_page_cache_func() function's retry loop is not guaranteed to sleep (see the should_reclaim_retry() function).
And we have seen this function cause workqueue lockups:
kernel: BUG: workqueue lockup - pool cpus=93 node=1 flags=0x1 nice=0 stuck for 32s! [...]
kernel: pool 74: cpus=37 node=0 flags=0x1 nice=0 hung=32s workers=2 manager: 2146 kernel: pwq 498: cpus=249 node=1 flags=0x1 nice=0 active=4/256 refcnt=5 kernel: in-flight: 1917:fill_page_cache_func kernel: pending: dbs_work_handler, free_work, kfree_rcu_monitor
Originally, we thought that the root cause of this lockup was several retries with direct reclaim, but this is not yet confirmed. Furthermore, we have seen similar lockups without any heavy memory pressure. This suggests that there are other factors contributing to these lockups. However, it is not really clear that endless retries are desireable.
So let's make the fill_page_cache_func() function back off after allocation failure.
--- kernel/rcu/tree.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
kernel/rcu/tree.c +9 -8
@@ -3419,15 +3419,16 @@ static void fill_page_cache_func(struct work_struct *work) bnode = (struct kvfree_rcu_bulk_data *)__get_free_page (GFP_KERNEL | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); -if (bnode) { -raw_spin_lock_irqsave (&krcp->lock, flags); - pushed =put_cached_bnode (krcp, bnode); -raw_spin_unlock_irqrestore (&krcp->lock, flags); +if (!bnode) +break ; -if (!pushed) { -free_page ((unsigned long ) bnode); -break ; - } +raw_spin_lock_irqsave (&krcp->lock, flags); + pushed =put_cached_bnode (krcp, bnode); +raw_spin_unlock_irqrestore (&krcp->lock, flags); + +if (!pushed) { +free_page ((unsigned long ) bnode); +break ; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 403/530 rcu-tasks: Convert RCU_LOCKDEP_WARN() to WARN_ONCE()
In reply to Greg Kroah-HartmanFrom: Zqiang <[email protected]>
[ Upstream commit fcd53c8a4dfa38bafb89efdd0b0f718f3a03f884 ]
Kernels built with CONFIG_PROVE_RCU=y and CONFIG_DEBUG_LOCK_ALLOC=y attempt to emit a warning when the synchronize_rcu_tasks_generic() function is called during early boot while the rcu_scheduler_active variable is RCU_SCHEDULER_INACTIVE. However the warnings is not actually be printed because the debug_lockdep_rcu_enabled() returns false, exactly because the rcu_scheduler_active variable is still equal to RCU_SCHEDULER_INACTIVE.
This commit therefore replaces RCU_LOCKDEP_WARN() with WARN_ONCE() to force these warnings to actually be printed.
--- kernel/rcu/tasks.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/rcu/tasks.h +1 -1
@@ -171,7 +171,7 @@ static void call_rcu_tasks_generic(struct rcu_head *rhp, rcu_callback_t func,static void synchronize_rcu_tasks_generic (struct rcu_tasks *rtp) {/* Complain if the scheduler has not started. */ -RCU_LOCKDEP_WARN (rcu_scheduler_active ==RCU_SCHEDULER_INACTIVE , +WARN_ONCE (rcu_scheduler_active ==RCU_SCHEDULER_INACTIVE ,"synchronize_rcu_tasks called too soon" );/* Wait for the grace period. */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 404/530 ACPI: video: Add Toshiba Satellite/Portege Z830 quirk
In reply to Greg Kroah-HartmanFrom: Arvid Norlander <[email protected]>
[ Upstream commit 574160b8548deff8b80b174f03201e94ab8431e2 ]
Toshiba Satellite Z830 needs the quirk video_disable_backlight_sysfs_if for proper backlight control after suspend/resume cycles.
Toshiba Portege Z830 is simply the same laptop rebranded for certain markets (I looked through the manual to other language sections to confirm this) and thus also needs this quirk.
Thanks to Hans de Goede for suggesting this fix.
--- drivers/acpi/acpi_video.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/acpi/acpi_video.c +16 -0
@@ -496,6 +496,22 @@ static const struct dmi_system_id video_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE R830"), }, }, + { + .callback = video_disable_backlight_sysfs_if, + .ident = "Toshiba Satellite Z830", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Z830"), + }, + }, + { + .callback = video_disable_backlight_sysfs_if, + .ident = "Toshiba Portege Z830", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE Z830"), + }, + }, /* * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set * but the IDs actually follow the Device ID Scheme.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 405/530 ACPI: tables: FPDT: Dont call acpi_os_map_memory() on invalid phys address
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit 211391bf04b3c74e250c566eeff9cf808156c693 ]
On a Packard Bell Dot SC (Intel Atom N2600 model) there is a FPDT table which contains invalid physical addresses, with high bits set which fall outside the range of the CPU-s supported physical address range.
Calling acpi_os_map_memory() on such an invalid phys address leads to the below WARN_ON in ioremap triggering resulting in an oops/stacktrace.
Add code to verify the physical address before calling acpi_os_map_memory() to fix / avoid the oops.
[ 1.226900] ioremap: invalid physical address 3001000000000000 [ 1.226949] ------------[ cut here ]------------ [ 1.226962] WARNING: CPU: 1 PID: 1 at arch/x86/mm/ioremap.c:200 __ioremap_caller.cold+0x43/0x5f [ 1.226996] Modules linked in: [ 1.227016] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 6.0.0-rc3+ #490 [ 1.227029] Hardware name: Packard Bell dot s/SJE01_CT, BIOS V1.10 07/23/2013 [ 1.227038] RIP: 0010:__ioremap_caller.cold+0x43/0x5f [ 1.227054] Code: 96 00 00 e9 f8 af 24 ff 89 c6 48 c7 c7 d8 0c 84 99 e8 6a 96 00 00 e9 76 af 24 ff 48 89 fe 48 c7 c7 a8 0c 84 99 e8 56 96 00 00 <0f> 0b e9 60 af 24 ff 48 8b 34 24 48 c7 c7 40 0d 84 99 e8 3f 96 00 [ 1.227067] RSP: 0000:ffffb18c40033d60 EFLAGS: 00010286 [ 1.227084] RAX: 0000000000000032 RBX: 3001000000000000 RCX: 0000000000000000 [ 1.227095] RDX: 0000000000000001 RSI: 00000000ffffdfff RDI: 00000000ffffffff [ 1.227105] RBP: 3001000000000000 R08: 0000000000000000 R09: ffffb18c40033c18 [ 1.227115] R10: 0000000000000003 R11: ffffffff99d62fe8 R12: 0000000000000008 [ 1.227124] R13: 0003001000000000 R14: 0000000000001000 R15: 3001000000000000 [ 1.227135] FS: 0000000000000000(0000) GS:ffff913a3c080000(0000) knlGS:0000000000000000 [ 1.227146] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1.227156] CR2: 0000000000000000 CR3: 0000000018c26000 CR4: 00000000000006e0 [ 1.227167] Call Trace: [ 1.227176] <TASK> [ 1.227185] ? acpi_os_map_iomem+0x1c9/0x1e0 [ 1.227215] ? kmem_cache_alloc_trace+0x187/0x370 [ 1.227254] acpi_os_map_iomem+0x1c9/0x1e0 [ 1.227288] acpi_init_fpdt+0xa8/0x253 [ 1.227308] ? acpi_debugfs_init+0x1f/0x1f [ 1.227339] do_one_initcall+0x5a/0x300 [ 1.227406] ? rcu_read_lock_sched_held+0x3f/0x80 [ 1.227442] kernel_init_freeable+0x28b/0x2cc [ 1.227512] ? rest_init+0x170/0x170 [ 1.227538] kernel_init+0x16/0x140 [ 1.227552] ret_from_fork+0x1f/0x30 [ 1.227639] </TASK> [ 1.227647] irq event stamp: 186819 [ 1.227656] hardirqs last enabled at (186825): [<ffffffff98184a6e>] __up_console_sem+0x5e/0x70 [ 1.227672] hardirqs last disabled at (186830): [<ffffffff98184a53>] __up_console_sem+0x43/0x70 [ 1.227686] softirqs last enabled at (186576): [<ffffffff980fbc9d>] __irq_exit_rcu+0xed/0x160 [ 1.227701] softirqs last disabled at (186569): [<ffffffff980fbc9d>] __irq_exit_rcu+0xed/0x160 [ 1.227715] ---[ end trace 0000000000000000 ]---
--- drivers/acpi/acpi_fpdt.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
drivers/acpi/acpi_fpdt.c +22 -0
@@ -143,6 +143,23 @@ static const struct attribute_group boot_attr_group = {static struct kobject *fpdt_kobj; +#if definedCONFIG_X86 && definedCONFIG_PHYS_ADDR_T_64BIT +#include <linux/processor.h> +static bool fpdt_address_valid (u64 address) +{ +/* +* On some systems the table contains invalid addresses +* with unsuppored high address bits set, check for this. +*/ +return !(address >> boot_cpu_data.x86_phys_bits); +} +#else +static bool fpdt_address_valid (u64 address) +{ +return true; +} +#endif +static int fpdt_process_subtable (u64 address,u32 subtable_type) {struct fpdt_subtable_header *subtable_header;
@@ -151,6 +168,11 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)u32 length, offset;int result; +if (!fpdt_address_valid (address)) { +pr_info (FW_BUG "invalid physical address: 0x%llx!\n" , address); +return -EINVAL ; + } + subtable_header =acpi_os_map_memory (address,sizeof (*subtable_header));if (!subtable_header)return -ENOMEM ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 406/530 cpufreq: intel_pstate: Add Tigerlake support in no-HWP mode
In reply to Greg Kroah-HartmanFrom: Doug Smythies <[email protected]>
[ Upstream commit 71bb5c82aaaea007167f3ba68d3a669c74d7d55d ]
Users may disable HWP in firmware, in which case intel_pstate wouldn't load unless the CPU model is explicitly supported.
Add TIGERLAKE to the list of CPUs that can register intel_pstate while not advertising the HWP capability. Without this change, an TIGERLAKE in no-HWP mode could only use the acpi_cpufreq frequency scaling driver.
See also commits:d8de7a44e11f: cpufreq: intel_pstate: Add Skylake servers supportfbdc21e9b038: cpufreq: intel_pstate: Add Icelake servers support in no-HWP mode 706c5328851d: cpufreq: intel_pstate: Add Cometlake support in no-HWP mode
Reported by: M. Cargi Ari <[email protected]>
--- drivers/cpufreq/intel_pstate.c | 1 + 1 file changed, 1 insertion(+)
drivers/cpufreq/intel_pstate.c +1 -0
@@ -2257,6 +2257,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = {X86_MATCH (SKYLAKE_X , core_funcs),X86_MATCH (COMETLAKE , core_funcs),X86_MATCH (ICELAKE_X , core_funcs), +X86_MATCH (TIGERLAKE , core_funcs), {} };MODULE_DEVICE_TABLE (x86cpu, intel_pstate_cpu_ids);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 407/530 MIPS: BCM47XX: Cast memcmp() of function to (void *)
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit 0dedcf6e3301836eb70cfa649052e7ce4fcd13ba ]
Clang is especially sensitive about argument type matching when using __overloaded functions (like memcmp(), etc). Help it see that function pointers are just "void *". Avoids this error:
arch/mips/bcm47xx/prom.c:89:8: error: no matching function for call to 'memcmp'
if (!memcmp(prom_init, prom_init + mem, 32))
^~~~~~include/linux/string.h:156:12: note: candidate function not viable: no known conversion from 'void (void)' to 'const void *' for 1st argument extern int memcmp(const void *,const void *,__kernel_size_t);
--- arch/mips/bcm47xx/prom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/mips/bcm47xx/prom.c +2 -2
@@ -86,7 +86,7 @@ static __init void prom_init_mem(void)pr_debug ("Assume 128MB RAM\n" );break ; } -if (!memcmp (prom_init, prom_init + mem,32 )) +if (!memcmp ((void *)prom_init, (void *)prom_init + mem,32 ))break ; } lowmem = mem;
@@ -159,7 +159,7 @@ void __init bcm47xx_prom_highmem_init(void) off =EXTVBASE +__pa (off);for (extmem =128 <<20 ; extmem <512 <<20 ; extmem <<=1 ) { -if (!memcmp (prom_init, (void *)(off + extmem),16 )) +if (!memcmp ((void *)prom_init, (void *)(off + extmem),16 ))break ; } extmem -= lowmem;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 408/530 powercap: intel_rapl: fix UBSAN shift-out-of-bounds issue
In reply to Greg Kroah-HartmanFrom: Chao Qin <[email protected]>
[ Upstream commit 2d93540014387d1c73b9ccc4d7895320df66d01b ]
When value < time_unit, the parameter of ilog2() will be zero and the return value is -1. u64(-1) is too large for shift exponent and then will trigger shift-out-of-bounds:
shift exponent 18446744073709551615 is too large for 32-bit type 'int'
Call Trace: rapl_compute_time_window_core rapl_write_data_raw set_time_window store_constraint_time_window_us
--- drivers/powercap/intel_rapl_common.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/powercap/intel_rapl_common.c +3 -0
@@ -938,6 +938,9 @@ static u64 rapl_compute_time_window_core(struct rapl_package *rp, u64 value, y = value &0x1f ; value = (1 << y) * (4 + f) * rp->time_unit /4 ; }else { +if (value < rp->time_unit) +return 0 ; +do_div (value, rp->time_unit); y =ilog2 (value); f =div64_u64 (4 * (value - (1 << y)),1 << y);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 409/530 thermal: intel_powerclamp: Use get_cpu() instead of smp_processor_id() to avoid crash
In reply to Greg Kroah-HartmanFrom: Srinivas Pandruvada <[email protected]>
[ Upstream commit 68b99e94a4a2db6ba9b31fe0485e057b9354a640 ]
When CPU 0 is offline and intel_powerclamp is used to inject idle, it generates kernel BUG:
BUG: using smp_processor_id() in preemptible [00000000] code: bash/15687 caller is debug_smp_processor_id+0x17/0x20 CPU: 4 PID: 15687 Comm: bash Not tainted 5.19.0-rc7+ #57 Call Trace: <TASK> dump_stack_lvl+0x49/0x63 dump_stack+0x10/0x16 check_preemption_disabled+0xdd/0xe0 debug_smp_processor_id+0x17/0x20 powerclamp_set_cur_state+0x7f/0xf9 [intel_powerclamp]
...
...
Here CPU 0 is the control CPU by default and changed to the current CPU, if CPU 0 offlined. This check has to be performed under cpus_read_lock(), hence the above warning.
Use get_cpu() instead of smp_processor_id() to avoid this BUG.
--- drivers/thermal/intel/intel_powerclamp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/thermal/intel/intel_powerclamp.c +4 -2
@@ -532,8 +532,10 @@ static int start_power_clamp(void)/* prefer BSP */ control_cpu =0 ; -if (!cpu_online (control_cpu)) - control_cpu =smp_processor_id (); +if (!cpu_online (control_cpu)) { + control_cpu =get_cpu (); +put_cpu (); + } clamping = true;schedule_delayed_work (&poll_pkg_cstate_work,0 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 410/530 ARM: decompressor: Include .data.rel.ro.local
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit 1b64daf413acd86c2c13f5443f6b4ef3690c8061 ]
The .data.rel.ro.local section has the same semantics as .data.rel.ro here, so include it in the .rodata section of the decompressor. Additionally since the .printk_index section isn't usable outside of the core kernel, discard it in the decompressor. Avoids these warnings:
arm-linux-gnueabi-ld: warning: orphan section .data.rel.ro.local' from arch/arm/boot/compressed/fdt_rw.o' being placed in section `.data.rel.ro.local'
arm-linux-gnueabi-ld: warning: orphan section .printk_index' from arch/arm/boot/compressed/fdt_rw.o' being placed in section `.printk_index'
--- arch/arm/boot/compressed/vmlinux.lds.S | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/boot/compressed/vmlinux.lds.S +2 -0
@@ -23,6 +23,7 @@ SECTIONS *(.ARM.extab*) *(.note.*) *(.rel.*) + *(.printk_index) /* * Discard any r/w data - this produces a link error if we have any, * which is required for PIC decompression. Local data generates
@@ -57,6 +58,7 @@ SECTIONS *(.rodata) *(.rodata.*) *(.data.rel.ro) + *(.data.rel.ro.*) } .piggydata : { *(.piggydata)
Signature · 9 lines
2.35.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Greg Kroah-Hartman
maintainerPATCH 411/530 ACPI: x86: Add a quirk for Dell Inspiron 14 2-in-1 for StorageD3Enable
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
[ Upstream commit 018d6711c26e4bd26e20a819fcc7f8ab902608f3 ]
Dell Inspiron 14 2-in-1 has two ACPI nodes under GPP1 both with _ADR of 0, both without _HID. It's ambiguous which the kernel should take, but it seems to take "DEV0". Unfortunately "DEV0" is missing the device property StorageD3Enable which is present on "NVME".
To avoid this causing problems for suspend, add a quirk for this system to behave like StorageD3Enable property was found.
--- drivers/acpi/x86/utils.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
drivers/acpi/x86/utils.c +18 -1
@@ -198,7 +198,24 @@ static const struct x86_cpu_id storage_d3_cpu_ids[] = { {} }; +static const struct dmi_system_id force_storage_d3_dmi[] = { + { +/* +* _ADR is ambiguous between GPP1.DEV0 and GPP1.NVME +* but .NVME is needed to get StorageD3Enable node +* https://bugzilla.kernel.org/show_bug.cgi?id=216440 +*/ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Dell Inc." ), +DMI_MATCH (DMI_PRODUCT_NAME ,"Inspiron 14 7425 2-in-1" ), + } + }, + {} +}; +bool force_storage_d3 (void ) { -return x86_match_cpu (storage_d3_cpu_ids); +const struct dmi_system_id *dmi_id =dmi_first_match (force_storage_d3_dmi); + +return dmi_id ||x86_match_cpu (storage_d3_cpu_ids); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 412/530 x86/entry: Work around Clang __bdos() bug
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit 3e1730842f142add55dc658929221521a9ea62b6 ]
Clang produces a false positive when building with CONFIG_FORTIFY_SOURCE=y and CONFIG_UBSAN_BOUNDS=y when operating on an array with a dynamic offset. Work around this by using a direct assignment of an empty instance. Avoids this warning:
../include/linux/fortify-string.h:309:4: warning: call to __write_overflow_field declared with 'warn ing' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Wat tribute-warning]
__write_overflow_field(p_size_field, size);
^which was isolated to the memset() call in xen_load_idt().
Note that this looks very much like another bug that was worked around:
https://github.com/ClangBuiltLinux/linux/issues/1592
--- arch/x86/xen/enlighten_pv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/xen/enlighten_pv.c +2 -1
@@ -759,6 +759,7 @@ static void xen_load_idt(const struct desc_ptr *desc) {static DEFINE_SPINLOCK (lock);static struct trap_info traps[257 ]; +static const struct trap_info zero = { };unsigned out;trace_xen_cpu_load_idt (desc);
@@ -768,7 +769,7 @@ static void xen_load_idt(const struct desc_ptr *desc)memcpy (this_cpu_ptr (&idt_desc), desc,sizeof (idt_desc)); out =xen_convert_trap_info (desc, traps, false); -memset (&traps[out],0 ,sizeof (traps[0 ])); + traps[out] = zero;xen_mc_flush ();if (HYPERVISOR_set_trap_table (traps))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 413/530 NFSD: Return nfserr_serverfault if splice_ok but buf->pages have data
In reply to Greg Kroah-HartmanFrom: Anna Schumaker <[email protected]>
[ Upstream commit 06981d560606ac48d61e5f4fff6738b925c93173 ]
This was discussed with Chuck as part of this patch set. Returning nfserr_resource was decided to not be the best error message here, and he suggested changing to nfserr_serverfault instead.
--- fs/nfsd/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/nfs4xdr.c +1 -1
@@ -3988,7 +3988,7 @@ nfsd4_encode_read(struct nfsd4_compoundrif (resp->xdr->buf->page_len &&test_bit (RQ_SPLICE_OK , &resp->rqstp->rq_flags)) {WARN_ON_ONCE (1 ); -return nfserr_resource; +return nfserr_serverfault; }xdr_commit_encode (xdr);
Greg Kroah-Hartman
maintainerPATCH 414/530 NFSD: fix use-after-free on source server when doing inter-server copy
In reply to Greg Kroah-HartmanFrom: Dai Ngo <[email protected]>
[ Upstream commit 019805fea91599b22dfa62ffb29c022f35abeb06 ]
Use-after-free occurred when the laundromat tried to free expired cpntf_state entry on the s2s_cp_stateids list after inter-server copy completed. The sc_cp_list that the expired copy state was inserted on was already freed.
When COPY completes, the Linux client normally sends LOCKU(lock_state x), FREE_STATEID(lock_state x) and CLOSE(open_state y) to the source server. The nfs4_put_stid call from nfsd4_free_stateid cleans up the copy state from the s2s_cp_stateids list before freeing the lock state's stid.
However, sometimes the CLOSE was sent before the FREE_STATEID request. When this happens, the nfsd4_close_open_stateid call from nfsd4_close frees all lock states on its st_locks list without cleaning up the copy state on the sc_cp_list list. When the time the FREE_STATEID arrives the server returns BAD_STATEID since the lock state was freed. This causes the use-after-free error to occur when the laundromat tries to free the expired cpntf_state.
This patch adds a call to nfs4_free_cpntf_statelist in nfsd4_close_open_stateid to clean up the copy state before calling free_ol_stateid_reaplist to free the lock state's stid on the reaplist.
--- fs/nfsd/nfs4state.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/nfsd/nfs4state.c +5 -0
@@ -961,6 +961,7 @@ static struct nfs4_ol_stateid * nfs4_alloc_open_stateid(struct nfs4_client *clp)static void nfs4_free_deleg (struct nfs4_stid *stid) { +WARN_ON (!list_empty (&stid->sc_cp_list));kmem_cache_free (deleg_slab, stid);atomic_long_dec (&num_delegations); }
@@ -1374,6 +1375,7 @@ static void nfs4_free_ol_stateid(struct nfs4_stid *stid)release_all_access (stp);if (stp->st_stateowner)nfs4_put_stateowner (stp->st_stateowner); +WARN_ON (!list_empty (&stid->sc_cp_list));kmem_cache_free (stateid_slab, stid); }
@@ -6389,6 +6391,7 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)struct nfs4_client *clp = s->st_stid.sc_client;bool unhashed;LIST_HEAD (reaplist); +struct nfs4_ol_stateid *stp;spin_lock (&clp->cl_lock); unhashed =unhash_open_stateid (s, &reaplist);
@@ -6397,6 +6400,8 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)if (unhashed)put_ol_stateid_locked (s, &reaplist);spin_unlock (&clp->cl_lock); +list_for_each_entry (stp, &reaplist, st_locks) +nfs4_free_cpntf_statelist (clp->net, &stp->st_stid);free_ol_stateid_reaplist (&reaplist); }else {spin_unlock (&clp->cl_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 415/530 wifi: brcmfmac: fix invalid address access when enabling SCAN log level
In reply to Greg Kroah-HartmanFrom: Wright Feng <[email protected]>
[ Upstream commit aa666b68e73fc06d83c070d96180b9010cf5a960 ]
The variable i is changed when setting random MAC address and causes invalid address access when printing the value of pi->reqs[i]->reqid.
We replace reqs index with ri to fix the issue.
[ 136.726473] Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000000000000000 [ 136.737365] Mem abort info: [ 136.740172] ESR = 0x96000004 [ 136.743359] Exception class = DABT (current EL), IL = 32 bits [ 136.749294] SET = 0, FnV = 0 [ 136.752481] EA = 0, S1PTW = 0 [ 136.755635] Data abort info: [ 136.758514] ISV = 0, ISS = 0x00000004 [ 136.762487] CM = 0, WnR = 0 [ 136.765522] user pgtable: 4k pages, 48-bit VAs, pgdp = 000000005c4e2577 [ 136.772265] [0000000000000000] pgd=0000000000000000 [ 136.777160] Internal error: Oops: 96000004 [#1] PREEMPT SMP [ 136.782732] Modules linked in: brcmfmac(O) brcmutil(O) cfg80211(O) compat(O) [ 136.789788] Process wificond (pid: 3175, stack limit = 0x00000000053048fb) [ 136.796664] CPU: 3 PID: 3175 Comm: wificond Tainted: G O 4.19.42-00001-g531a5f5 #1 [ 136.805532] Hardware name: Freescale i.MX8MQ EVK (DT) [ 136.810584] pstate: 60400005 (nZCv daif +PAN -UAO) [ 136.815429] pc : brcmf_pno_config_sched_scans+0x6cc/0xa80 [brcmfmac] [ 136.821811] lr : brcmf_pno_config_sched_scans+0x67c/0xa80 [brcmfmac] [ 136.828162] sp : ffff00000e9a3880 [ 136.831475] x29: ffff00000e9a3890 x28: ffff800020543400 [ 136.836786] x27: ffff8000b1008880 x26: ffff0000012bf6a0 [ 136.842098] x25: ffff80002054345c x24: ffff800088d22400 [ 136.847409] x23: ffff0000012bf638 x22: ffff0000012bf6d8 [ 136.852721] x21: ffff8000aced8fc0 x20: ffff8000ac164400 [ 136.858032] x19: ffff00000e9a3946 x18: 0000000000000000 [ 136.863343] x17: 0000000000000000 x16: 0000000000000000 [ 136.868655] x15: ffff0000093f3b37 x14: 0000000000000050 [ 136.873966] x13: 0000000000003135 x12: 0000000000000000 [ 136.879277] x11: 0000000000000000 x10: ffff000009a61888 [ 136.884589] x9 : 000000000000000f x8 : 0000000000000008 [ 136.889900] x7 : 303a32303d726464 x6 : ffff00000a1f957d [ 136.895211] x5 : 0000000000000000 x4 : ffff00000e9a3942 [ 136.900523] x3 : 0000000000000000 x2 : ffff0000012cead8 [ 136.905834] x1 : ffff0000012bf6d8 x0 : 0000000000000000 [ 136.911146] Call trace: [ 136.913623] brcmf_pno_config_sched_scans+0x6cc/0xa80 [brcmfmac] [ 136.919658] brcmf_pno_start_sched_scan+0xa4/0x118 [brcmfmac] [ 136.925430] brcmf_cfg80211_sched_scan_start+0x80/0xe0 [brcmfmac] [ 136.931636] nl80211_start_sched_scan+0x140/0x308 [cfg80211] [ 136.937298] genl_rcv_msg+0x358/0x3f4 [ 136.940960] netlink_rcv_skb+0xb4/0x118 [ 136.944795] genl_rcv+0x34/0x48 [ 136.947935] netlink_unicast+0x264/0x300 [ 136.951856] netlink_sendmsg+0x2e4/0x33c [ 136.955781] __sys_sendto+0x120/0x19c
--- .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c +6 -6
@@ -158,12 +158,12 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi)struct brcmf_pno_macaddr_le pfn_mac;u8 *mac_addr =NULL ;u8 *mac_mask =NULL ; -int err, i; +int err, i, ri; -for (i =0 ; i < pi->n_reqs; i++) -if (pi->reqs[i]->flags &NL80211_SCAN_FLAG_RANDOM_ADDR ) { - mac_addr = pi->reqs[i]->mac_addr; - mac_mask = pi->reqs[i]->mac_addr_mask; +for (ri =0 ; ri < pi->n_reqs; ri++) +if (pi->reqs[ri]->flags &NL80211_SCAN_FLAG_RANDOM_ADDR ) { + mac_addr = pi->reqs[ri]->mac_addr; + mac_mask = pi->reqs[ri]->mac_addr_mask;break ; }
@@ -185,7 +185,7 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi) pfn_mac.mac[0 ] |=0x02 ;brcmf_dbg (SCAN ,"enabling random mac: reqid=%llu mac=%pM\n" , - pi->reqs[i]->reqid, pfn_mac.mac); + pi->reqs[ri]->reqid, pfn_mac.mac); err =brcmf_fil_iovar_data_set (ifp,"pfn_macaddr" , &pfn_mac,sizeof (pfn_mac));if (err)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 416/530 bpftool: Clear errno after libcaps checks
In reply to Greg Kroah-HartmanFrom: Quentin Monnet <[email protected]>
[ Upstream commit cea558855c39b7f1f02ff50dcf701ca6596bc964 ]
When bpftool is linked against libcap, the library runs a "constructor" function to compute the number of capabilities of the running kernel [0], at the beginning of the execution of the program. As part of this, it performs multiple calls to prctl(). Some of these may fail, and set errno to a non-zero value:
# strace -e prctl ./bpftool version
prctl(PR_CAPBSET_READ, CAP_MAC_OVERRIDE) = 1
prctl(PR_CAPBSET_READ, 0x30 /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, CAP_CHECKPOINT_RESTORE) = 1
prctl(PR_CAPBSET_READ, 0x2c /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, 0x2a /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, 0x29 /* CAP_??? */) = -1 EINVAL (Invalid argument)
** fprintf added at the top of main(): we have errno == 1
./bpftool v7.0.0
using libbpf v1.0
features: libbfd, libbpf_strict, skeletons
+++ exited with 0 +++This has been addressed in libcap 2.63 [1], but until this version is available everywhere, we can fix it on bpftool side.
Let's clean errno at the beginning of the main() function, to make sure that these checks do not interfere with the batch mode, where we error out if errno is set after a bpftool command.
[0] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/tree/libcap/cap_alloc.c?h=libcap-2.65#n20
[1] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=f25a1b7e69f7b33e6afb58b3e38f3450b7d2d9a0
--- tools/bpf/bpftool/main.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
tools/bpf/bpftool/main.c +10 -0
@@ -404,6 +404,16 @@ int main(int argc, char **argv)setlinebuf (stdout); +#ifdef USE_LIBCAP +/* Libcap < 2.63 hooks before main() to compute the number of +* capabilities of the running kernel, and doing so it calls prctl() +* which may fail and set errno to non-zero. +* Let's reset errno to make sure this does not interfere with the +* batch mode. +*/ + errno =0 ; +#endif + last_do_help = do_help; pretty_output = false; json_output = false;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 417/530 ice: set tx_tstamps when creating new Tx rings via ethtool
In reply to Greg Kroah-HartmanFrom: Jacob Keller <[email protected]>
[ Upstream commit b3b173745c8cab1e24d6821488b60abed3acb24d ]
When the user changes the number of queues via ethtool, the driver allocates new rings. This allocation did not initialize tx_tstamps. This results in the tx_tstamps field being zero (due to kcalloc allocation), and would result in a NULL pointer dereference when attempting a transmit timestamp on the new ring.
--- drivers/net/ethernet/intel/ice/ice_ethtool.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/intel/ice/ice_ethtool.c +1 -0
@@ -2788,6 +2788,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) tx_rings[i].count = new_tx_cnt; tx_rings[i].desc =NULL ; tx_rings[i].tx_buf =NULL ; + tx_rings[i].tx_tstamps = &pf->ptp.port.tx; err =ice_setup_tx_ring (&tx_rings[i]);if (err) {while (i--)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 418/530 net: ethernet: ti: davinci_mdio: Add workaround for errata i2329
In reply to Greg Kroah-HartmanFrom: Ravi Gunasekaran <[email protected]>
[ Upstream commit d04807b80691c6041ca8e3dcf1870d1bf1082c22 ]
On the CPSW and ICSS peripherals, there is a possibility that the MDIO interface returns corrupt data on MDIO reads or writes incorrect data on MDIO writes. There is also a possibility for the MDIO interface to become unavailable until the next peripheral reset.
The workaround is to configure the MDIO in manual mode and disable the MDIO state machine and emulate the MDIO protocol by reading and writing appropriate fields in MDIO_MANUAL_IF_REG register of the MDIO controller to manipulate the MDIO clock and data pins.
More details about the errata i2329 and the workaround is available in:
https://www.ti.com/lit/er/sprz487a/sprz487a.pdf
Add implementation to disable MDIO state machine, configure MDIO in manual mode and achieve MDIO read and writes via MDIO Bitbanging
--- drivers/net/ethernet/ti/davinci_mdio.c | 242 +++++++++++++++++++++++-- 1 file changed, 231 insertions(+), 11 deletions(-)
drivers/net/ethernet/ti/davinci_mdio.c +231 -11
@@ -26,6 +26,8 @@#include <linux/of_device.h> #include <linux/of_mdio.h> #include <linux/pinctrl/consumer.h> +#include <linux/mdio-bitbang.h> +#include <linux/sys_soc.h> /* * This timeout definition is a worst-case ultra defensive measure against
@@ -41,6 +43,7 @@struct davinci_mdio_of_param {int autosuspend_delay_ms; +bool manual_mode; };struct davinci_mdio_regs {
@@ -49,6 +52,15 @@ struct davinci_mdio_regs {#define CONTROL_IDLE BIT(31)#define CONTROL_ENABLE BIT(30)#define CONTROL_MAX_DIV (0xffff) +#define CONTROL_CLKDIV GENMASK(15, 0) + +#define MDIO_MAN_MDCLK_O BIT(2) +#define MDIO_MAN_OE BIT(1) +#define MDIO_MAN_PIN BIT(0) +#define MDIO_MANUALMODE BIT(31) + +#define MDIO_PIN 0 +u32 alive;u32 link;
@@ -59,7 +71,9 @@ struct davinci_mdio_regs {u32 userintmasked;u32 userintmaskset;u32 userintmaskclr; -u32 __reserved_1[20 ]; +u32 manualif; +u32 poll; +u32 __reserved_1[18 ];struct {u32 access;
@@ -79,6 +93,7 @@ static const struct mdio_platform_data default_pdata = {struct davinci_mdio_data {struct mdio_platform_data pdata; +struct mdiobb_ctrl bb_ctrl;struct davinci_mdio_regs __iomem *regs;struct clk *clk;struct device *dev;
@@ -90,6 +105,7 @@ struct davinci_mdio_data {*/ bool skip_scan;u32 clk_div; +bool manual_mode; };static void davinci_mdio_init_clk (struct davinci_mdio_data *data)
@@ -128,9 +144,122 @@ static void davinci_mdio_enable(struct davinci_mdio_data *data)writel (data->clk_div |CONTROL_ENABLE , &data->regs->control); } -static int davinci_mdio_reset (struct mii_bus *bus) +static void davinci_mdio_disable (struct davinci_mdio_data *data) +{ +u32 reg; + +/* Disable MDIO state machine */ + reg =readl (&data->regs->control); + + reg &= ~CONTROL_CLKDIV ; + reg |= data->clk_div; + + reg &= ~CONTROL_ENABLE ; +writel (reg, &data->regs->control); +} + +static void davinci_mdio_enable_manual_mode (struct davinci_mdio_data *data) +{ +u32 reg; +/* set manual mode */ + reg =readl (&data->regs->poll); + reg |=MDIO_MANUALMODE ; +writel (reg, &data->regs->poll); +} + +static void davinci_set_mdc (struct mdiobb_ctrl *ctrl,int level) +{ +struct davinci_mdio_data *data; +u32 reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg =readl (&data->regs->manualif); + +if (level) + reg |=MDIO_MAN_MDCLK_O ; +else + reg &= ~MDIO_MAN_MDCLK_O ; + +writel (reg, &data->regs->manualif); +} + +static void davinci_set_mdio_dir (struct mdiobb_ctrl *ctrl,int output) +{ +struct davinci_mdio_data *data; +u32 reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg =readl (&data->regs->manualif); + +if (output) + reg |=MDIO_MAN_OE ; +else + reg &= ~MDIO_MAN_OE ; + +writel (reg, &data->regs->manualif); +} + +static void davinci_set_mdio_data (struct mdiobb_ctrl *ctrl,int value) +{ +struct davinci_mdio_data *data; +u32 reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg =readl (&data->regs->manualif); + +if (value) + reg |=MDIO_MAN_PIN ; +else + reg &= ~MDIO_MAN_PIN ; + +writel (reg, &data->regs->manualif); +} + +static int davinci_get_mdio_data (struct mdiobb_ctrl *ctrl) +{ +struct davinci_mdio_data *data; +unsigned long reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg =readl (&data->regs->manualif); +return test_bit (MDIO_PIN , ®); +} + +static int davinci_mdiobb_read (struct mii_bus *bus,int phy,int reg) +{ +int ret; + + ret =pm_runtime_resume_and_get (bus->parent); +if (ret <0 ) +return ret; + + ret =mdiobb_read (bus, phy, reg); + +pm_runtime_mark_last_busy (bus->parent); +pm_runtime_put_autosuspend (bus->parent); + +return ret; +} + +static int davinci_mdiobb_write (struct mii_bus *bus,int phy,int reg, +u16 val) +{ +int ret; + + ret =pm_runtime_resume_and_get (bus->parent); +if (ret <0 ) +return ret; + + ret =mdiobb_write (bus, phy, reg, val); + +pm_runtime_mark_last_busy (bus->parent); +pm_runtime_put_autosuspend (bus->parent); + +return ret; +} + +static int davinci_mdio_common_reset (struct davinci_mdio_data *data) { -struct davinci_mdio_data *data = bus->priv;u32 phy_mask, ver;int ret;
@@ -140,6 +269,11 @@ static int davinci_mdio_reset(struct mii_bus *bus)return ret; } +if (data->manual_mode) { +davinci_mdio_disable (data); +davinci_mdio_enable_manual_mode (data); + } +/* wait for scan logic to settle */ msleep (PHY_MAX_ADDR * data->access_time);
@@ -173,6 +307,23 @@ static int davinci_mdio_reset(struct mii_bus *bus)return 0 ; } +static int davinci_mdio_reset (struct mii_bus *bus) +{ +struct davinci_mdio_data *data = bus->priv; + +return davinci_mdio_common_reset (data); +} + +static int davinci_mdiobb_reset (struct mii_bus *bus) +{ +struct mdiobb_ctrl *ctrl = bus->priv; +struct davinci_mdio_data *data; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + +return davinci_mdio_common_reset (data); +} +/* wait until hardware is ready for another user access */ static inline int wait_for_user_access (struct davinci_mdio_data *data) {
@@ -324,6 +475,28 @@ static int davinci_mdio_probe_dt(struct mdio_platform_data *data,return 0 ; } +struct k3_mdio_soc_data { +bool manual_mode; +}; + +static const struct k3_mdio_soc_data am65_mdio_soc_data = { + .manual_mode = true, +}; + +static const struct soc_device_attribute k3_mdio_socinfo[] = { + { .family ="AM62X" , .revision ="SR1.0" , .data = &am65_mdio_soc_data }, + { .family ="AM64X" , .revision ="SR1.0" , .data = &am65_mdio_soc_data }, + { .family ="AM64X" , .revision ="SR2.0" , .data = &am65_mdio_soc_data }, + { .family ="AM65X" , .revision ="SR1.0" , .data = &am65_mdio_soc_data }, + { .family ="AM65X" , .revision ="SR2.0" , .data = &am65_mdio_soc_data }, + { .family ="J7200" , .revision ="SR1.0" , .data = &am65_mdio_soc_data }, + { .family ="J7200" , .revision ="SR2.0" , .data = &am65_mdio_soc_data }, + { .family ="J721E" , .revision ="SR1.0" , .data = &am65_mdio_soc_data }, + { .family ="J721E" , .revision ="SR2.0" , .data = &am65_mdio_soc_data }, + { .family ="J721S2" , .revision ="SR1.0" , .data = &am65_mdio_soc_data}, + {/* sentinel */ }, +}; +#if IS_ENABLED (CONFIG_OF )static const struct davinci_mdio_of_param of_cpsw_mdio_data = { .autosuspend_delay_ms = 100,
@@ -337,6 +510,14 @@ static const struct of_device_id davinci_mdio_of_mtable[] = {MODULE_DEVICE_TABLE (of, davinci_mdio_of_mtable);#endif +static const struct mdiobb_ops davinci_mdiobb_ops = { + .owner =THIS_MODULE , + .set_mdc = davinci_set_mdc, + .set_mdio_dir = davinci_set_mdio_dir, + .set_mdio_data = davinci_set_mdio_data, + .get_mdio_data = davinci_get_mdio_data, +}; +static int davinci_mdio_probe (struct platform_device *pdev) {struct mdio_platform_data *pdata =dev_get_platdata (&pdev->dev);
@@ -351,7 +532,26 @@ static int davinci_mdio_probe(struct platform_device *pdev)if (!data)return -ENOMEM ; - data->bus =devm_mdiobus_alloc (dev); + data->manual_mode = false; + data->bb_ctrl.ops = &davinci_mdiobb_ops; + +if (IS_ENABLED (CONFIG_OF ) && dev->of_node) { +const struct soc_device_attribute *soc_match_data; + + soc_match_data =soc_device_match (k3_mdio_socinfo); +if (soc_match_data && soc_match_data->data) { +const struct k3_mdio_soc_data *socdata = + soc_match_data->data; + + data->manual_mode = socdata->manual_mode; + } + } + +if (data->manual_mode) + data->bus =alloc_mdio_bitbang (&data->bb_ctrl); +else + data->bus =devm_mdiobus_alloc (dev); +if (!data->bus) {dev_err (dev,"failed to alloc mii bus\n" );return -ENOMEM ;
@@ -377,11 +577,20 @@ static int davinci_mdio_probe(struct platform_device *pdev) } data->bus->name =dev_name (dev); - data->bus->read = davinci_mdio_read; - data->bus->write = davinci_mdio_write; - data->bus->reset = davinci_mdio_reset; + +if (data->manual_mode) { + data->bus->read = davinci_mdiobb_read; + data->bus->write = davinci_mdiobb_write; + data->bus->reset = davinci_mdiobb_reset; + +dev_info (dev,"Configuring MDIO in manual mode\n" ); + }else { + data->bus->read = davinci_mdio_read; + data->bus->write = davinci_mdio_write; + data->bus->reset = davinci_mdio_reset; + data->bus->priv = data; + } data->bus->parent = dev; - data->bus->priv = data; data->clk =devm_clk_get (dev,"fck" );if (IS_ERR (data->clk)) {
@@ -439,9 +648,13 @@ static int davinci_mdio_remove(struct platform_device *pdev) {struct davinci_mdio_data *data =platform_get_drvdata (pdev); -if (data->bus) +if (data->bus) {mdiobus_unregister (data->bus); +if (data->manual_mode) +free_mdio_bitbang (data->bus); + } +pm_runtime_dont_use_autosuspend (&pdev->dev);pm_runtime_disable (&pdev->dev);
@@ -458,7 +671,9 @@ static int davinci_mdio_runtime_suspend(struct device *dev) ctrl =readl (&data->regs->control); ctrl &= ~CONTROL_ENABLE ;writel (ctrl, &data->regs->control); -wait_for_idle (data); + +if (!data->manual_mode) +wait_for_idle (data);return 0 ; }
@@ -467,7 +682,12 @@ static int davinci_mdio_runtime_resume(struct device *dev) {struct davinci_mdio_data *data =dev_get_drvdata (dev); -davinci_mdio_enable (data); +if (data->manual_mode) { +davinci_mdio_disable (data); +davinci_mdio_enable_manual_mode (data); + }else { +davinci_mdio_enable (data); + }return 0 ; }#endif
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 419/530 openvswitch: Fix double reporting of drops in dropwatch
In reply to Greg Kroah-HartmanFrom: Mike Pattrick <[email protected]>
[ Upstream commit 1100248a5c5ccd57059eb8d02ec077e839a23826 ]
Frames sent to userspace can be reported as dropped in ovs_dp_process_packet, however, if they are dropped in the netlink code then netlink_attachskb will report the same frame as dropped.
This patch checks for error codes which indicate that the frame has already been freed.
--- net/openvswitch/datapath.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
net/openvswitch/datapath.c +10 -3
@@ -251,10 +251,17 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key) upcall.mru =OVS_CB (skb)->mru; error =ovs_dp_upcall (dp, skb, key, &upcall,0 ); -if (unlikely (error)) -kfree_skb (skb); -else +switch (error) { +case 0 : +case -EAGAIN : +case -ERESTARTSYS : +case -EINTR :consume_skb (skb); +break ; +default : +kfree_skb (skb); +break ; + } stats_counter = &stats->n_missed; goto out; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 420/530 openvswitch: Fix overreporting of drops in dropwatch
In reply to Greg Kroah-HartmanFrom: Mike Pattrick <[email protected]>
[ Upstream commit c21ab2afa2c64896a7f0e3cbc6845ec63dcfad2e ]
Currently queue_userspace_packet will call kfree_skb for all frames, whether or not an error occurred. This can result in a single dropped frame being reported as multiple drops in dropwatch. This functions caller may also call kfree_skb in case of an error. This patch will consume the skbs instead and allow caller's to use kfree_skb.
--- net/openvswitch/datapath.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/openvswitch/datapath.c +3 -2
@@ -557,8 +557,9 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, out:if (err)skb_tx_error (skb); -kfree_skb (user_skb); -kfree_skb (nskb); +consume_skb (user_skb); +consume_skb (nskb); +return err; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 421/530 tcp: annotate data-race around tcp_md5sig_pool_populated
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit aacd467c0a576e5e44d2de4205855dc0fe43f6fb ]
tcp_md5sig_pool_populated can be read while another thread changes its value.
The race has no consequence because allocations are protected with tcp_md5sig_mutex.
This patch adds READ_ONCE() and WRITE_ONCE() to document the race and silence KCSAN.
--- net/ipv4/tcp.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
net/ipv4/tcp.c +10 -4
@@ -4331,12 +4331,16 @@ static void __tcp_alloc_md5sig_pool(void)* to memory. See smp_rmb() in tcp_get_md5sig_pool() */ smp_wmb (); - tcp_md5sig_pool_populated = true; +/* Paired with READ_ONCE() from tcp_alloc_md5sig_pool() +* and tcp_get_md5sig_pool(). +*/ +WRITE_ONCE (tcp_md5sig_pool_populated, true); }bool tcp_alloc_md5sig_pool (void ) { -if (unlikely (!tcp_md5sig_pool_populated)) { +/* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */ +if (unlikely (!READ_ONCE (tcp_md5sig_pool_populated))) {mutex_lock (&tcp_md5sig_mutex);if (!tcp_md5sig_pool_populated) {
@@ -4347,7 +4351,8 @@ bool tcp_alloc_md5sig_pool(void)mutex_unlock (&tcp_md5sig_mutex); } -return tcp_md5sig_pool_populated; +/* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */ +return READ_ONCE (tcp_md5sig_pool_populated); }EXPORT_SYMBOL (tcp_alloc_md5sig_pool);
@@ -4363,7 +4368,8 @@ struct tcp_md5sig_pool *tcp_get_md5sig_pool(void) {local_bh_disable (); -if (tcp_md5sig_pool_populated) { +/* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */ +if (READ_ONCE (tcp_md5sig_pool_populated)) {/* coupled with smp_wmb() in __tcp_alloc_md5sig_pool() */ smp_rmb ();return this_cpu_ptr (&tcp_md5sig_pool);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 422/530 x86/mce: Retrieve poison range from hardware
In reply to Greg Kroah-HartmanFrom: Jane Chu <[email protected]>
[ Upstream commit f9781bb18ed828e7b83b7bac4a4ad7cd497ee7d7 ]
When memory poison consumption machine checks fire, MCE notifier handlers like nfit_handle_mce() record the impacted physical address range which is reported by the hardware in the MCi_MISC MSR. The error information includes data about blast radius, i.e. how many cachelines did the hardware determine are impacted. A recent change
7917f9cdb503 ("acpi/nfit: rely on mce->misc to determine poison granularity")
updated nfit_handle_mce() to stop hard coding the blast radius value of 1 cacheline, and instead rely on the blast radius reported in 'struct mce' which can be up to 4K (64 cachelines).
It turns out that apei_mce_report_mem_error() had a similar problem in that it hard coded a blast radius of 4K rather than reading the blast radius from the error information. Fix apei_mce_report_mem_error() to convey the proper poison granularity.
--- arch/x86/kernel/cpu/mce/apei.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
arch/x86/kernel/cpu/mce/apei.c +12 -1
@@ -29,15 +29,26 @@void apei_mce_report_mem_error (int severity,struct cper_sec_mem_err *mem_err) {struct mce m; +int lsb;if (!(mem_err->validation_bits &CPER_MEM_VALID_PA ))return ; +/* +* Even if the ->validation_bits are set for address mask, +* to be extra safe, check and reject an error radius '0', +* and fall back to the default page size. +*/ +if (mem_err->validation_bits &CPER_MEM_VALID_PA_MASK ) + lsb =find_first_bit ((void *)&mem_err->physical_addr_mask,PAGE_SHIFT ); +else + lsb =PAGE_SHIFT ; +mce_setup (&m); m.bank =-1 ;/* Fake a memory read error with unknown channel */ m.status =MCI_STATUS_VAL |MCI_STATUS_EN |MCI_STATUS_ADDRV |MCI_STATUS_MISCV |0x9f ; - m.misc = (MCI_MISC_ADDR_PHYS <<6 ) |PAGE_SHIFT ; + m.misc = (MCI_MISC_ADDR_PHYS <<6 ) | lsb;if (severity >=GHES_SEV_RECOVERABLE ) m.status |=MCI_STATUS_UC ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 423/530 wifi: ath9k: avoid uninit memory read in ath9k_htc_rx_msg()
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
[ Upstream commit b383e8abed41cc6ff1a3b34de75df9397fa4878c ]
syzbot is reporting uninit value at ath9k_htc_rx_msg() [1], for ioctl(USB_RAW_IOCTL_EP_WRITE) can call ath9k_hif_usb_rx_stream() with pkt_len = 0 but ath9k_hif_usb_rx_stream() uses __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC) based on an assumption that pkt_len is valid. As a result, ath9k_hif_usb_rx_stream() allocates skb with uninitialized memory and ath9k_htc_rx_msg() is reading from uninitialized memory.
Since bytes accessed by ath9k_htc_rx_msg() is not known until ath9k_htc_rx_msg() is called, it would be difficult to check minimal valid pkt_len at "if (pkt_len > 2 * MAX_RX_BUF_SIZE) {" line in ath9k_hif_usb_rx_stream().
We have two choices. One is to workaround by adding __GFP_ZERO so that ath9k_htc_rx_msg() sees 0 if pkt_len is invalid. The other is to let ath9k_htc_rx_msg() validate pkt_len before accessing. This patch chose the latter.
Note that I'm not sure threshold condition is correct, for I can't find details on possible packet length used by this protocol.
--- drivers/net/wireless/ath/ath9k/htc_hst.c | 43 +++++++++++++++--------- 1 file changed, 28 insertions(+), 15 deletions(-)
drivers/net/wireless/ath/ath9k/htc_hst.c +28 -15
@@ -364,33 +364,27 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, }static void ath9k_htc_fw_panic_report (struct htc_target *htc_handle, -struct sk_buff *skb) +struct sk_buff *skb,u32 len) {uint32_t *pattern = (uint32_t *)skb->data; -switch (*pattern) { -case 0x33221199 : - { +if (*pattern ==0x33221199 && len >=sizeof (struct htc_panic_bad_vaddr )) {struct htc_panic_bad_vaddr *htc_panic; htc_panic = (struct htc_panic_bad_vaddr *) skb->data;dev_err (htc_handle->dev,"ath: firmware panic! " "exccause: 0x%08x; pc: 0x%08x; badvaddr: 0x%08x.\n" , htc_panic->exccause, htc_panic->pc, htc_panic->badvaddr); -break ; - } -case 0x33221299 : - { +return ; + } +if (*pattern ==0x33221299 ) {struct htc_panic_bad_epid *htc_panic; htc_panic = (struct htc_panic_bad_epid *) skb->data;dev_err (htc_handle->dev,"ath: firmware panic! " "bad epid: 0x%08x\n" , htc_panic->epid); -break ; - } -default : -dev_err (htc_handle->dev,"ath: unknown panic pattern!\n" ); -break ; +return ; } +dev_err (htc_handle->dev,"ath: unknown panic pattern!\n" ); }/*
@@ -411,16 +405,26 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,if (!htc_handle || !skb)return ; +/* A valid message requires len >= 8. +* +* sizeof(struct htc_frame_hdr) == 8 +* sizeof(struct htc_ready_msg) == 8 +* sizeof(struct htc_panic_bad_vaddr) == 16 +* sizeof(struct htc_panic_bad_epid) == 8 +*/ +if (unlikely (len <sizeof (struct htc_frame_hdr ))) + goto invalid; htc_hdr = (struct htc_frame_hdr *) skb->data; epid = htc_hdr->endpoint_id;if (epid ==0x99 ) { -ath9k_htc_fw_panic_report (htc_handle, skb); +ath9k_htc_fw_panic_report (htc_handle, skb, len);kfree_skb (skb);return ; }if (epid <0 || epid >=ENDPOINT_MAX ) { +invalid:if (pipe_id !=USB_REG_IN_PIPE )dev_kfree_skb_any (skb);else
@@ -432,21 +436,30 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,/* Handle trailer */ if (htc_hdr->flags &HTC_FLAGS_RECV_TRAILER ) { -if (be32_to_cpu (*(__be32 *) skb->data) ==0x00C60000 ) +if (be32_to_cpu (*(__be32 *) skb->data) ==0x00C60000 ) {/* Move past the Watchdog pattern */ htc_hdr = (struct htc_frame_hdr *)(skb->data +4 ); + len -=4 ; + } }/* Get the message ID */ +if (unlikely (len <sizeof (struct htc_frame_hdr ) +sizeof (__be16))) + goto invalid; msg_id = (__be16 *) ((void *) htc_hdr +sizeof (struct htc_frame_hdr ));/* Now process HTC messages */ switch (be16_to_cpu (*msg_id)) {case HTC_MSG_READY_ID : +if (unlikely (len <sizeof (struct htc_ready_msg ))) + goto invalid;htc_process_target_rdy (htc_handle, htc_hdr);break ;case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID : +if (unlikely (len <sizeof (struct htc_frame_hdr ) + +sizeof (struct htc_conn_svc_rspmsg ))) + goto invalid;htc_process_conn_rsp (htc_handle, htc_hdr);break ;default :
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 424/530 thunderbolt: Add back Intel Falcon Ridge end-to-end flow control workaround
In reply to Greg Kroah-HartmanFrom: Mika Westerberg <[email protected]>
[ Upstream commit 54669e2f17cb5a4c41ade89427f074dc22cecb17 ]
As we are now enabling full end-to-end flow control to the Thunderbolt networking driver, in order for it to work properly on second generation Thunderbolt hardware (Falcon Ridge), we need to add back the workaround that was removed with commit 53f13319d131 ("thunderbolt: Get rid of E2E workaround"). However, this time we only apply it for Falcon Ridge controllers as a form of an additional quirk. For non-Falcon Ridge this does nothing.
While there fix a typo 'reqister' -> 'register' in the comment.
--- drivers/thunderbolt/nhi.c | 49 +++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 7 deletions(-)
drivers/thunderbolt/nhi.c +42 -7
@@ -25,7 +25,11 @@#define RING_TYPE (ring) ((ring)->is_tx ? "TX ring" : "RX ring")#define RING_FIRST_USABLE_HOPID 1 - +/* +* Used with QUIRK_E2E to specify an unused HopID the Rx credits are +* transferred. +*/ +#define RING_E2E_RESERVED_HOPID RING_FIRST_USABLE_HOPID/* * Minimal number of vectors when we use MSI-X. Two for control channel * Rx/Tx and the rest four are for cross domain DMA paths.
@@ -35,7 +39,9 @@#define NHI_MAILBOX_TIMEOUT 500/* ms */ +/* Host interface quirks */ #define QUIRK_AUTO_CLEAR_INT BIT(0) +#define QUIRK_E2E BIT(1)static int ring_interrupt_index (struct tb_ring *ring) {
@@ -455,8 +461,18 @@ static void ring_release_msix(struct tb_ring *ring)static int nhi_alloc_hop (struct tb_nhi *nhi,struct tb_ring *ring) { +unsigned int start_hop =RING_FIRST_USABLE_HOPID ;int ret =0 ; +if (nhi->quirks &QUIRK_E2E ) { + start_hop =RING_FIRST_USABLE_HOPID +1 ; +if (ring->flags &RING_FLAG_E2E && !ring->is_tx) { +dev_dbg (&nhi->pdev->dev,"quirking E2E TX HopID %u -> %u\n" , + ring->e2e_tx_hop,RING_E2E_RESERVED_HOPID ); + ring->e2e_tx_hop =RING_E2E_RESERVED_HOPID ; + } + } +spin_lock_irq (&nhi->lock);if (ring->hop <0 ) {
@@ -466,7 +482,7 @@ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring)* Automatically allocate HopID from the non-reserved * range 1 .. hop_count - 1. */ -for (i =RING_FIRST_USABLE_HOPID ; i < nhi->hop_count; i++) { +for (i = start_hop; i < nhi->hop_count; i++) {if (ring->is_tx) {if (!nhi->tx_rings[i]) { ring->hop = i;
@@ -481,6 +497,11 @@ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring) } } +if (ring->hop >0 && ring->hop < start_hop) { +dev_warn (&nhi->pdev->dev,"invalid hop: %d\n" , ring->hop); + ret = -EINVAL ; + goto err_unlock; + }if (ring->hop <0 || ring->hop >= nhi->hop_count) {dev_warn (&nhi->pdev->dev,"invalid hop: %d\n" , ring->hop); ret = -EINVAL ;
@@ -1094,12 +1115,26 @@ static void nhi_shutdown(struct tb_nhi *nhi)static void nhi_check_quirks (struct tb_nhi *nhi) { -/* -* Intel hardware supports auto clear of the interrupt status -* reqister right after interrupt is being issued. -*/ -if (nhi->pdev->vendor ==PCI_VENDOR_ID_INTEL ) +if (nhi->pdev->vendor ==PCI_VENDOR_ID_INTEL ) { +/* +* Intel hardware supports auto clear of the interrupt +* status register right after interrupt is being +* issued. +*/ nhi->quirks |=QUIRK_AUTO_CLEAR_INT ; + +switch (nhi->pdev->device) { +case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI : +case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI : +/* +* Falcon Ridge controller needs the end-to-end +* flow control workaround to avoid losing Rx +* packets when RING_FLAG_E2E is set. +*/ + nhi->quirks |=QUIRK_E2E ; +break ; + } + } }static int nhi_init_msi (struct tb_nhi *nhi)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 425/530 xfrm: Update ipcomp_scratches with NULL when freed
In reply to Greg Kroah-HartmanFrom: Khalid Masum <[email protected]>
[ Upstream commit 8a04d2fc700f717104bfb95b0f6694e448a4537f ]
Currently if ipcomp_alloc_scratches() fails to allocate memory ipcomp_scratches holds obsolete address. So when we try to free the percpu scratches using ipcomp_free_scratches() it tries to vfree non existent vm area. Described below:
static void * __percpu *ipcomp_alloc_scratches(void)
{
...
scratches = alloc_percpu(void *);
if (!scratches)
return NULL;
ipcomp_scratches does not know about this allocation failure.
Therefore holding the old obsolete address.
...
}So when we free,
static void ipcomp_free_scratches(void)
{
...
scratches = ipcomp_scratches;Assigning obsolete address from ipcomp_scratches
if (!scratches)
return;
for_each_possible_cpu(i)
vfree(*per_cpu_ptr(scratches, i));
Trying to free non existent page, causing warning: trying to vfree
existent vm area.
...
}Fix this breakage by updating ipcomp_scrtches with NULL when scratches is freed
--- net/xfrm/xfrm_ipcomp.c | 1 + 1 file changed, 1 insertion(+)
net/xfrm/xfrm_ipcomp.c +1 -0
@@ -203,6 +203,7 @@ static void ipcomp_free_scratches(void)vfree (*per_cpu_ptr (scratches, i));free_percpu (scratches); + ipcomp_scratches =NULL ; }static void *__percpu *ipcomp_alloc_scratches (void )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 426/530 iavf: Fix race between iavf_close and iavf_reset_task
In reply to Greg Kroah-HartmanFrom: Michal Jaron <[email protected]>
[ Upstream commit 11c12adcbc1598d91e73ab6ddfa41d25a01478ed ]
During stress tests with adding VF to namespace and changing vf's trust there was a race between iavf_reset_task and iavf_close. Sometimes when IAVF_FLAG_AQ_DISABLE_QUEUES from iavf_close was sent to PF after reset and before IAVF_AQ_GET_CONFIG was sent then PF returns error IAVF_NOT_SUPPORTED to disable queues request and following requests. There is need to get_config before other aq_required will be send but iavf_close clears all flags, if get_config was not sent before iavf_close, then it will not be send at all.
In case when IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS was sent before IAVF_FLAG_AQ_DISABLE_QUEUES then there was rtnl_lock deadlock between iavf_close and iavf_adminq_task until iavf_close timeouts and disable queues was sent after iavf_close ends.
There was also a problem with sending delete/add filters. Sometimes when filters was not yet added to PF and in iavf_close all filters was set to remove there might be a try to remove nonexistent filters on PF.
Add aq_required_tmp to save aq_required flags and send them after disable_queues will be handled. Clear flags given to iavf_down different than IAVF_FLAG_AQ_GET_CONFIG as this flag is necessary to sent other aq_required. Remove some flags that we don't want to send as we are in iavf_close and we want to disable interface. Remove filters which was not yet sent and send del filters flags only when there are filters to remove.
--- drivers/net/ethernet/intel/iavf/iavf_main.c | 177 ++++++++++++++++---- 1 file changed, 141 insertions(+), 36 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_main.c +141 -36
@@ -1012,66 +1012,138 @@ static void iavf_up_complete(struct iavf_adapter *adapter) }/** -* iavf_down - Shutdown the connection processing +* iavf_clear_mac_vlan_filters - Remove mac and vlan filters not sent to PF +* yet and mark other to be removed. * @adapter: board private structure -* -* Expects to be called while holding the __IAVF_IN_CRITICAL_TASK bit lock. **/ -void iavf_down (struct iavf_adapter *adapter) +static void iavf_clear_mac_vlan_filters (struct iavf_adapter *adapter) { -struct net_device *netdev = adapter->netdev; -struct iavf_vlan_filter *vlf; -struct iavf_cloud_filter *cf; -struct iavf_fdir_fltr *fdir; -struct iavf_mac_filter *f; -struct iavf_adv_rss *rss; - -if (adapter->state <= __IAVF_DOWN_PENDING) -return ; - -netif_carrier_off (netdev); -netif_tx_disable (netdev); - adapter->link_up = false; -iavf_napi_disable_all (adapter); -iavf_irq_disable (adapter); +struct iavf_vlan_filter *vlf, *vlftmp; +struct iavf_mac_filter *f, *ftmp;spin_lock_bh (&adapter->mac_vlan_list_lock); -/* clear the sync flag on all filters */ __dev_uc_unsync (adapter->netdev,NULL );__dev_mc_unsync (adapter->netdev,NULL );/* remove all MAC filters */ -list_for_each_entry (f, &adapter->mac_filter_list, list) { - f->remove = true; +list_for_each_entry_safe (f, ftmp, &adapter->mac_filter_list, + list) { +if (f->add) { +list_del (&f->list); +kfree (f); + }else { + f->remove = true; + } }/* remove all VLAN filters */ -list_for_each_entry (vlf, &adapter->vlan_filter_list, list) { - vlf->remove = true; +list_for_each_entry_safe (vlf, vlftmp, &adapter->vlan_filter_list, + list) { +if (vlf->add) { +list_del (&vlf->list); +kfree (vlf); + }else { + vlf->remove = true; + } } -spin_unlock_bh (&adapter->mac_vlan_list_lock); +} + +/** +* iavf_clear_cloud_filters - Remove cloud filters not sent to PF yet and +* mark other to be removed. +* @adapter: board private structure +**/ +static void iavf_clear_cloud_filters (struct iavf_adapter *adapter) +{ +struct iavf_cloud_filter *cf, *cftmp;/* remove all cloud filters */ spin_lock_bh (&adapter->cloud_filter_list_lock); -list_for_each_entry (cf, &adapter->cloud_filter_list, list) { - cf->del = true; +list_for_each_entry_safe (cf, cftmp, &adapter->cloud_filter_list, + list) { +if (cf->add) { +list_del (&cf->list); +kfree (cf); + adapter->num_cloud_filters--; + }else { + cf->del = true; + } }spin_unlock_bh (&adapter->cloud_filter_list_lock); +} + +/** +* iavf_clear_fdir_filters - Remove fdir filters not sent to PF yet and mark +* other to be removed. +* @adapter: board private structure +**/ +static void iavf_clear_fdir_filters (struct iavf_adapter *adapter) +{ +struct iavf_fdir_fltr *fdir, *fdirtmp;/* remove all Flow Director filters */ spin_lock_bh (&adapter->fdir_fltr_lock); -list_for_each_entry (fdir, &adapter->fdir_list_head, list) { - fdir->state =IAVF_FDIR_FLTR_DEL_REQUEST ; +list_for_each_entry_safe (fdir, fdirtmp, &adapter->fdir_list_head, + list) { +if (fdir->state ==IAVF_FDIR_FLTR_ADD_REQUEST ) { +list_del (&fdir->list); +kfree (fdir); + adapter->fdir_active_fltr--; + }else { + fdir->state =IAVF_FDIR_FLTR_DEL_REQUEST ; + } }spin_unlock_bh (&adapter->fdir_fltr_lock); +} + +/** +* iavf_clear_adv_rss_conf - Remove adv rss conf not sent to PF yet and mark +* other to be removed. +* @adapter: board private structure +**/ +static void iavf_clear_adv_rss_conf (struct iavf_adapter *adapter) +{ +struct iavf_adv_rss *rss, *rsstmp;/* remove all advance RSS configuration */ spin_lock_bh (&adapter->adv_rss_lock); -list_for_each_entry (rss, &adapter->adv_rss_list_head, list) - rss->state =IAVF_ADV_RSS_DEL_REQUEST ; +list_for_each_entry_safe (rss, rsstmp, &adapter->adv_rss_list_head, + list) { +if (rss->state ==IAVF_ADV_RSS_ADD_REQUEST ) { +list_del (&rss->list); +kfree (rss); + }else { + rss->state =IAVF_ADV_RSS_DEL_REQUEST ; + } + }spin_unlock_bh (&adapter->adv_rss_lock); +} + +/** +* iavf_down - Shutdown the connection processing +* @adapter: board private structure +* +* Expects to be called while holding the __IAVF_IN_CRITICAL_TASK bit lock. +**/ +void iavf_down (struct iavf_adapter *adapter) +{ +struct net_device *netdev = adapter->netdev; + +if (adapter->state <= __IAVF_DOWN_PENDING) +return ; + +netif_carrier_off (netdev); +netif_tx_disable (netdev); + adapter->link_up = false; +iavf_napi_disable_all (adapter); +iavf_irq_disable (adapter); + +iavf_clear_mac_vlan_filters (adapter); +iavf_clear_cloud_filters (adapter); +iavf_clear_fdir_filters (adapter); +iavf_clear_adv_rss_conf (adapter);if (!(adapter->flags &IAVF_FLAG_PF_COMMS_FAILED )) {/* cancel any current operation */
@@ -1080,11 +1152,16 @@ void iavf_down(struct iavf_adapter *adapter)* here for this to complete. The watchdog is still running * and it will take care of this. */ - adapter->aq_required =IAVF_FLAG_AQ_DEL_MAC_FILTER ; - adapter->aq_required |=IAVF_FLAG_AQ_DEL_VLAN_FILTER ; - adapter->aq_required |=IAVF_FLAG_AQ_DEL_CLOUD_FILTER ; - adapter->aq_required |=IAVF_FLAG_AQ_DEL_FDIR_FILTER ; - adapter->aq_required |=IAVF_FLAG_AQ_DEL_ADV_RSS_CFG ; +if (!list_empty (&adapter->mac_filter_list)) + adapter->aq_required |=IAVF_FLAG_AQ_DEL_MAC_FILTER ; +if (!list_empty (&adapter->vlan_filter_list)) + adapter->aq_required |=IAVF_FLAG_AQ_DEL_VLAN_FILTER ; +if (!list_empty (&adapter->cloud_filter_list)) + adapter->aq_required |=IAVF_FLAG_AQ_DEL_CLOUD_FILTER ; +if (!list_empty (&adapter->fdir_list_head)) + adapter->aq_required |=IAVF_FLAG_AQ_DEL_FDIR_FILTER ; +if (!list_empty (&adapter->adv_rss_list_head)) + adapter->aq_required |=IAVF_FLAG_AQ_DEL_ADV_RSS_CFG ; adapter->aq_required |=IAVF_FLAG_AQ_DISABLE_QUEUES ; }
@@ -3483,6 +3560,7 @@ static int iavf_open(struct net_device *netdev)static int iavf_close (struct net_device *netdev) {struct iavf_adapter *adapter =netdev_priv (netdev); +u64 aq_to_restore;int status;mutex_lock (&adapter->crit_lock);
@@ -3495,6 +3573,29 @@ static int iavf_close(struct net_device *netdev)set_bit (__IAVF_VSI_DOWN, adapter->vsi.state);if (CLIENT_ENABLED (adapter)) adapter->flags |=IAVF_FLAG_CLIENT_NEEDS_CLOSE ; +/* We cannot send IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS before +* IAVF_FLAG_AQ_DISABLE_QUEUES because in such case there is rtnl +* deadlock with adminq_task() until iavf_close timeouts. We must send +* IAVF_FLAG_AQ_GET_CONFIG before IAVF_FLAG_AQ_DISABLE_QUEUES to make +* disable queues possible for vf. Give only necessary flags to +* iavf_down and save other to set them right before iavf_close() +* returns, when IAVF_FLAG_AQ_DISABLE_QUEUES will be already sent and +* iavf will be in DOWN state. +*/ + aq_to_restore = adapter->aq_required; + adapter->aq_required &=IAVF_FLAG_AQ_GET_CONFIG ; + +/* Remove flags which we do not want to send after close or we want to +* send before disable queues. +*/ + aq_to_restore &= ~(IAVF_FLAG_AQ_GET_CONFIG | +IAVF_FLAG_AQ_ENABLE_QUEUES | +IAVF_FLAG_AQ_CONFIGURE_QUEUES | +IAVF_FLAG_AQ_ADD_VLAN_FILTER | +IAVF_FLAG_AQ_ADD_MAC_FILTER | +IAVF_FLAG_AQ_ADD_CLOUD_FILTER | +IAVF_FLAG_AQ_ADD_FDIR_FILTER | +IAVF_FLAG_AQ_ADD_ADV_RSS_CFG );iavf_down (adapter);iavf_change_state (adapter, __IAVF_DOWN_PENDING);
@@ -3518,6 +3619,10 @@ static int iavf_close(struct net_device *netdev) msecs_to_jiffies(500));if (!status)netdev_warn (netdev,"Device resources not yet released\n" ); + +mutex_lock (&adapter->crit_lock); + adapter->aq_required |= aq_to_restore; +mutex_unlock (&adapter->crit_lock);return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 427/530 wifi: brcmfmac: fix use-after-free bug in brcmf_netdev_start_xmit()
In reply to Greg Kroah-HartmanFrom: Alexander Coffin <[email protected]>
[ Upstream commit 3f42faf6db431e04bf942d2ebe3ae88975723478 ]
Quoted 1 line
ret =
brcmf_proto_tx_queue_data(drvr, ifp->ifidx, skb);
may be schedule, and then complete before the line
Quoted 1 line
ndev->stats.tx_bytes+=skb->len;
[ 46.912801] ================================================================== [ 46.920552] BUG: KASAN: use-after-free in brcmf_netdev_start_xmit+0x718/0x8c8 [brcmfmac] [ 46.928673] Read of size 4 at addr ffffff803f5882e8 by task systemd-resolve/328 [ 46.935991] [ 46.937514] CPU: 1 PID: 328 Comm: systemd-resolve Tainted: G O 5.4.199-[REDACTED] #1 [ 46.947255] Hardware name: [REDACTED] [ 46.954568] Call trace: [ 46.957037] dump_backtrace+0x0/0x2b8 [ 46.960719] show_stack+0x24/0x30 [ 46.964052] dump_stack+0x128/0x194 [ 46.967557] print_address_description.isra.0+0x64/0x380 [ 46.972877] __kasan_report+0x1d4/0x240 [ 46.976723] kasan_report+0xc/0x18 [ 46.980138] __asan_report_load4_noabort+0x18/0x20 [ 46.985027] brcmf_netdev_start_xmit+0x718/0x8c8 [brcmfmac] [ 46.990613] dev_hard_start_xmit+0x1bc/0xda0 [ 46.994894] sch_direct_xmit+0x198/0xd08 [ 46.998827] __qdisc_run+0x37c/0x1dc0 [ 47.002500] __dev_queue_xmit+0x1528/0x21f8 [ 47.006692] dev_queue_xmit+0x24/0x30 [ 47.010366] neigh_resolve_output+0x37c/0x678 [ 47.014734] ip_finish_output2+0x598/0x2458 [ 47.018927] __ip_finish_output+0x300/0x730 [ 47.023118] ip_output+0x2e0/0x430 [ 47.026530] ip_local_out+0x90/0x140 [ 47.030117] igmpv3_sendpack+0x14c/0x228 [ 47.034049] igmpv3_send_cr+0x384/0x6b8 [ 47.037895] igmp_ifc_timer_expire+0x4c/0x118 [ 47.042262] call_timer_fn+0x1cc/0xbe8 [ 47.046021] __run_timers+0x4d8/0xb28 [ 47.049693] run_timer_softirq+0x24/0x40 [ 47.053626] __do_softirq+0x2c0/0x117c [ 47.057387] irq_exit+0x2dc/0x388 [ 47.060715] __handle_domain_irq+0xb4/0x158 [ 47.064908] gic_handle_irq+0x58/0xb0 [ 47.068581] el0_irq_naked+0x50/0x5c [ 47.072162] [ 47.073665] Allocated by task 328: [ 47.077083] save_stack+0x24/0xb0 [ 47.080410] __kasan_kmalloc.isra.0+0xc0/0xe0 [ 47.084776] kasan_slab_alloc+0x14/0x20 [ 47.088622] kmem_cache_alloc+0x15c/0x468 [ 47.092643] __alloc_skb+0xa4/0x498 [ 47.096142] igmpv3_newpack+0x158/0xd78 [ 47.099987] add_grhead+0x210/0x288 [ 47.103485] add_grec+0x6b0/0xb70 [ 47.106811] igmpv3_send_cr+0x2e0/0x6b8 [ 47.110657] igmp_ifc_timer_expire+0x4c/0x118 [ 47.115027] call_timer_fn+0x1cc/0xbe8 [ 47.118785] __run_timers+0x4d8/0xb28 [ 47.122457] run_timer_softirq+0x24/0x40 [ 47.126389] __do_softirq+0x2c0/0x117c [ 47.130142] [ 47.131643] Freed by task 180: [ 47.134712] save_stack+0x24/0xb0 [ 47.138041] __kasan_slab_free+0x108/0x180 [ 47.142146] kasan_slab_free+0x10/0x18 [ 47.145904] slab_free_freelist_hook+0xa4/0x1b0 [ 47.150444] kmem_cache_free+0x8c/0x528 [ 47.154292] kfree_skbmem+0x94/0x108 [ 47.157880] consume_skb+0x10c/0x5a8 [ 47.161466] __dev_kfree_skb_any+0x88/0xa0 [ 47.165598] brcmu_pkt_buf_free_skb+0x44/0x68 [brcmutil] [ 47.171023] brcmf_txfinalize+0xec/0x190 [brcmfmac] [ 47.176016] brcmf_proto_bcdc_txcomplete+0x1c0/0x210 [brcmfmac] [ 47.182056] brcmf_sdio_sendfromq+0x8dc/0x1e80 [brcmfmac] [ 47.187568] brcmf_sdio_dpc+0xb48/0x2108 [brcmfmac] [ 47.192529] brcmf_sdio_dataworker+0xc8/0x238 [brcmfmac] [ 47.197859] process_one_work+0x7fc/0x1a80 [ 47.201965] worker_thread+0x31c/0xc40 [ 47.205726] kthread+0x2d8/0x370 [ 47.208967] ret_from_fork+0x10/0x18 [ 47.212546] [ 47.214051] The buggy address belongs to the object at ffffff803f588280 [ 47.214051] which belongs to the cache skbuff_head_cache of size 208 [ 47.227086] The buggy address is located 104 bytes inside of [ 47.227086] 208-byte region [ffffff803f588280, ffffff803f588350) [ 47.238814] The buggy address belongs to the page: [ 47.243618] page:ffffffff00dd6200 refcount:1 mapcount:0 mapping:ffffff804b6bf800 index:0xffffff803f589900 compound_mapcount: 0 [ 47.255007] flags: 0x10200(slab|head) [ 47.258689] raw: 0000000000010200 ffffffff00dfa980 0000000200000002 ffffff804b6bf800 [ 47.266439] raw: ffffff803f589900 0000000080190018 00000001ffffffff 0000000000000000 [ 47.274180] page dumped because: kasan: bad access detected [ 47.279752] [ 47.281251] Memory state around the buggy address: [ 47.286051] ffffff803f588180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 47.293277] ffffff803f588200: fb fb fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 47.300502] >ffffff803f588280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 47.307723] ^ [ 47.314343] ffffff803f588300: fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc fc [ 47.321569] ffffff803f588380: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb [ 47.328789] ==================================================================
--- drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +2 -1
@@ -295,6 +295,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,struct brcmf_pub *drvr = ifp->drvr;struct ethhdr *eh;int head_delta; +unsigned int tx_bytes = skb->len;brcmf_dbg (DATA ,"Enter, bsscfgidx=%d\n" , ifp->bsscfgidx);
@@ -369,7 +370,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, ndev->stats.tx_dropped++; }else { ndev->stats.tx_packets++; - ndev->stats.tx_bytes += skb->len; + ndev->stats.tx_bytes += tx_bytes; }/* Return ok: we always eat the packet */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 428/530 Bluetooth: btintel: Mark Intel controller to support LE_STATES quirk
In reply to Greg Kroah-HartmanFrom: Kiran K <[email protected]>
[ Upstream commit dd0a1794f4334ddbf9b7c5e7d642aaffff38c69b ]
HarrrisonPeak, CyclonePeak, SnowFieldPeak and SandyPeak controllers are marked to support HCI_QUIRK_LE_STATES.
--- drivers/bluetooth/btintel.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
drivers/bluetooth/btintel.c +8 -9
@@ -2274,15 +2274,20 @@ static int btintel_setup_combined(struct hci_dev *hdev) INTEL_ROM_LEGACY_NO_WBS_SUPPORT)) set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); +if (ver.hw_variant ==0x08 && ver.fw_variant ==0x22 ) +set_bit (HCI_QUIRK_VALID_LE_STATES , + &hdev->quirks); err =btintel_legacy_rom_setup (hdev, &ver);break ;case 0x0b :/* SfP */ -case 0x0c :/* WsP */ case 0x11 :/* JfP */ case 0x12 :/* ThP */ case 0x13 :/* HrP */ case 0x14 :/* CcP */ +set_bit (HCI_QUIRK_VALID_LE_STATES , &hdev->quirks); + fallthrough; +case 0x0c :/* WsP */ /* Apply the device specific HCI quirks * * All Legacy bootloader devices support WBS
@@ -2290,11 +2295,6 @@ static int btintel_setup_combined(struct hci_dev *hdev)set_bit (HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED , &hdev->quirks); -/* Valid LE States quirk for JfP/ThP familiy */ -if (ver.hw_variant ==0x11 || ver.hw_variant ==0x12 ) -set_bit (HCI_QUIRK_VALID_LE_STATES , - &hdev->quirks); -/* Setup MSFT Extension support */ btintel_set_msft_opcode (hdev, ver.hw_variant);
@@ -2361,9 +2361,8 @@ static int btintel_setup_combined(struct hci_dev *hdev)*/ set_bit (HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED , &hdev->quirks); -/* Valid LE States quirk for JfP/ThP familiy */ -if (ver.hw_variant ==0x11 || ver.hw_variant ==0x12 ) -set_bit (HCI_QUIRK_VALID_LE_STATES , &hdev->quirks); +/* Set Valid LE States quirk */ +set_bit (HCI_QUIRK_VALID_LE_STATES , &hdev->quirks);/* Setup MSFT Extension support */ btintel_set_msft_opcode (hdev, ver.hw_variant);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 429/530 regulator: core: Prevent integer underflow
In reply to Greg Kroah-HartmanFrom: Patrick Rudolph <[email protected]>
[ Upstream commit 8d8e16592022c9650df8aedfe6552ed478d7135b ]
By using a ratio of delay to poll_enabled_time that is not integer time_remaining underflows and does not exit the loop as expected. As delay could be derived from DT and poll_enabled_time is defined in the driver this can easily happen.
Use a signed iterator to make sure that the loop exits once the remaining time is negative.
--- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/regulator/core.c +1 -1
@@ -2636,7 +2636,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev)* expired, return -ETIMEDOUT. */ if (rdev->desc->poll_enabled_time) { -unsigned int time_remaining = delay; +int time_remaining = delay;while (time_remaining >0 ) {_regulator_enable_delay (rdev->desc->poll_enabled_time);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 430/530 wifi: mt76: mt7921: reset msta->airtime_ac while clearing up hw value
In reply to Greg Kroah-HartmanFrom: Sean Wang <[email protected]>
[ Upstream commit 1bf66dc31032ff5292f4d5b76436653f269fcfbd ]
We should reset mstat->airtime_ac along with clear up the entries in the hardware WLAN table for the Rx and Rx accumulative airtime. Otherwsie, the value msta->airtime_ac - [tx, rx]_last may be a negative and that is not the actual airtime the device took in the last run.
--- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/mediatek/mt76/mt7921/main.c +1 -0
@@ -627,6 +627,7 @@ void mt7921_mac_sta_assoc(struct mt76_dev *mdev, struct ieee80211_vif *vif,mt7921_mac_wtbl_update (dev, msta->wcid.idx,MT_WTBL_UPDATE_ADM_COUNT_CLEAR ); +memset (msta->airtime_ac,0 ,sizeof (msta->airtime_ac));mt7921_mcu_sta_update (dev, sta, vif, true,MT76_STA_INFO_STATE_ASSOC );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 431/530 Bluetooth: L2CAP: initialize delayed works at l2cap_chan_create()
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
[ Upstream commit 2d2cb3066f2c90cd8ca540b36ba7a55e7f2406e0 ]
syzbot is reporting cancel_delayed_work() without INIT_DELAYED_WORK() at l2cap_chan_del() [1], for CONF_NOT_COMPLETE flag (which meant to prevent l2cap_chan_del() from calling cancel_delayed_work()) is cleared by timer which fires before l2cap_chan_del() is called by closing file descriptor created by socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_L2CAP).
l2cap_bredr_sig_cmd(L2CAP_CONF_REQ) and l2cap_bredr_sig_cmd(L2CAP_CONF_RSP) are calling l2cap_ertm_init(chan), and they call l2cap_chan_ready() (which clears CONF_NOT_COMPLETE flag) only when l2cap_ertm_init(chan) succeeded.
l2cap_sock_init() does not call l2cap_ertm_init(chan), and it instead sets CONF_NOT_COMPLETE flag by calling l2cap_chan_set_defaults(). However, when connect() is requested, "command 0x0409 tx timeout" happens after 2 seconds
from connect() request, and CONF_NOT_COMPLETE flag is cleared after 4
seconds from connect() request, for l2cap_conn_start() from l2cap_info_timeout() callback scheduled by
schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
in l2cap_connect() is calling l2cap_chan_ready().
Fix this problem by initializing delayed works used by L2CAP_MODE_ERTM mode as soon as l2cap_chan_create() allocates a channel, like I did in commit be8597239379f0f5 ("Bluetooth: initialize skb_queue_head at l2cap_chan_create()").
--- net/bluetooth/l2cap_core.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
net/bluetooth/l2cap_core.c +6 -4
@@ -61,6 +61,9 @@ static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);static void l2cap_tx (struct l2cap_chan *chan,struct l2cap_ctrl *control,struct sk_buff_head *skbs,u8 event); +static void l2cap_retrans_timeout (struct work_struct *work); +static void l2cap_monitor_timeout (struct work_struct *work); +static void l2cap_ack_timeout (struct work_struct *work);static inline u8 bdaddr_type (u8 link_type,u8 bdaddr_type) {
@@ -476,6 +479,9 @@ struct l2cap_chan *l2cap_chan_create(void)write_unlock (&chan_list_lock);INIT_DELAYED_WORK (&chan->chan_timer, l2cap_chan_timeout); +INIT_DELAYED_WORK (&chan->retrans_timer, l2cap_retrans_timeout); +INIT_DELAYED_WORK (&chan->monitor_timer, l2cap_monitor_timeout); +INIT_DELAYED_WORK (&chan->ack_timer, l2cap_ack_timeout); chan->state =BT_OPEN ;
@@ -3320,10 +3326,6 @@ int l2cap_ertm_init(struct l2cap_chan *chan) chan->rx_state =L2CAP_RX_STATE_RECV ; chan->tx_state =L2CAP_TX_STATE_XMIT ; -INIT_DELAYED_WORK (&chan->retrans_timer, l2cap_retrans_timeout); -INIT_DELAYED_WORK (&chan->monitor_timer, l2cap_monitor_timeout); -INIT_DELAYED_WORK (&chan->ack_timer, l2cap_ack_timeout); -skb_queue_head_init (&chan->srej_q); err =l2cap_seq_list_init (&chan->srej_list, chan->tx_win);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 432/530 Bluetooth: hci_sysfs: Fix attempting to call device_add multiple times
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 448a496f760664d3e2e79466aa1787e6abc922b5 ]
device_add shall not be called multiple times as stated in its documentation:
'Do not call this routine or device_register() more than once for any device structure'
Syzkaller reports a bug as follows [1]:
------------[ cut here ]------------ kernel BUG at lib/list_debug.c:33! invalid opcode: 0000 [#1] PREEMPT SMP KASAN [...] Call Trace: <TASK> __list_add include/linux/list.h:69 [inline] list_add_tail include/linux/list.h:102 [inline] kobj_kset_join lib/kobject.c:164 [inline] kobject_add_internal+0x18f/0x8f0 lib/kobject.c:214 kobject_add_varg lib/kobject.c:358 [inline] kobject_add+0x150/0x1c0 lib/kobject.c:410 device_add+0x368/0x1e90 drivers/base/core.c:3452 hci_conn_add_sysfs+0x9b/0x1b0 net/bluetooth/hci_sysfs.c:53 hci_le_cis_estabilished_evt+0x57c/0xae0 net/bluetooth/hci_event.c:6799 hci_le_meta_evt+0x2b8/0x510 net/bluetooth/hci_event.c:7110 hci_event_func net/bluetooth/hci_event.c:7440 [inline] hci_event_packet+0x63d/0xfd0 net/bluetooth/hci_event.c:7495 hci_rx_work+0xae7/0x1230 net/bluetooth/hci_core.c:4007 process_one_work+0x991/0x1610 kernel/workqueue.c:2289 worker_thread+0x665/0x1080 kernel/workqueue.c:2436 kthread+0x2e4/0x3a0 kernel/kthread.c:376 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:306 </TASK>
--- net/bluetooth/hci_sysfs.c | 3 +++ 1 file changed, 3 insertions(+)
net/bluetooth/hci_sysfs.c +3 -0
@@ -48,6 +48,9 @@ void hci_conn_add_sysfs(struct hci_conn *conn)BT_DBG ("conn %p" , conn); +if (device_is_registered (&conn->dev)) +return ; +dev_set_name (&conn->dev,"%s:%d" , hdev->name, conn->handle);if (device_add (&conn->dev) <0 ) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 433/530 can: bcm: check the result of can_send() in bcm_can_tx()
In reply to Greg Kroah-HartmanFrom: Ziyang Xuan <[email protected]>
[ Upstream commit 3fd7bfd28cfd68ae80a2fe92ea1615722cc2ee6e ]
If can_send() fail, it should not update frames_abs counter in bcm_can_tx(). Add the result check for can_send() in bcm_can_tx().
--- net/can/bcm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
net/can/bcm.c +4 -3
@@ -274,6 +274,7 @@ static void bcm_can_tx(struct bcm_op *op)struct sk_buff *skb;struct net_device *dev;struct canfd_frame *cf = op->frames + op->cfsiz * op->currframe; +int err;/* no target device? => exit */ if (!op->ifindex)
@@ -298,11 +299,11 @@ static void bcm_can_tx(struct bcm_op *op)/* send with loopback */ skb->dev = dev;can_skb_set_owner (skb, op->sk); -can_send (skb,1 ); + err =can_send (skb,1 ); +if (!err) + op->frames_abs++; -/* update statistics */ op->currframe++; - op->frames_abs++;/* reached last frame? */ if (op->currframe >= op->nframes)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 434/530 wifi: rt2x00: dont run Rt5592 IQ calibration on MT7620
In reply to Greg Kroah-HartmanFrom: Daniel Golle <[email protected]>
[ Upstream commit d3aad83d05aec0cfd7670cf0028f2ad4b81de92e ]
The function rt2800_iq_calibrate is intended for Rt5592 only. Don't call it for MT7620 which has it's own calibration functions.
--- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/ralink/rt2x00/rt2800lib.c +2 -1
@@ -4365,7 +4365,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, reg = (rf->channel <=14 ?0x1c :0x24 ) +2 *rt2x00dev->lna_gain;rt2800_bbp_write_with_rx_chain (rt2x00dev,66 , reg); -rt2800_iq_calibrate (rt2x00dev, rf->channel); +if (rt2x00_rt (rt2x00dev,RT5592 )) +rt2800_iq_calibrate (rt2x00dev, rf->channel); } bbp =rt2800_bbp_read (rt2x00dev,4 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 435/530 wifi: rt2x00: set correct TX_SW_CFG1 MAC register for MT7620
In reply to Greg Kroah-HartmanFrom: Daniel Golle <[email protected]>
[ Upstream commit eeb50acf15762b61921f9df18663f839f387c054 ]
Set correct TX_SW_CFG1 MAC register as it is done also in v3 of the vendor driver[1].
--- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ralink/rt2x00/rt2800lib.c +1 -1
@@ -5868,7 +5868,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)rt2800_register_write (rt2x00dev,TX_SW_CFG0 ,0x00000404 ); }else if (rt2x00_rt (rt2x00dev,RT6352 )) {rt2800_register_write (rt2x00dev,TX_SW_CFG0 ,0x00000401 ); -rt2800_register_write (rt2x00dev,TX_SW_CFG1 ,0x000C0000 ); +rt2800_register_write (rt2x00dev,TX_SW_CFG1 ,0x000C0001 );rt2800_register_write (rt2x00dev,TX_SW_CFG2 ,0x00000000 );rt2800_register_write (rt2x00dev,TX_ALC_VGA3 ,0x00000000 );rt2800_register_write (rt2x00dev,TX0_BB_GAIN_ATTEN ,0x0 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 436/530 wifi: rt2x00: set VGC gain for both chains of MT7620
In reply to Greg Kroah-HartmanFrom: Daniel Golle <[email protected]>
[ Upstream commit 0e09768c085709e10ece3b68f6ac921d3f6a9caa ]
Set bbp66 for all chains of the MT7620.
--- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/ralink/rt2x00/rt2800lib.c +2 -1
@@ -5645,7 +5645,8 @@ static inline void rt2800_set_vgc(struct rt2x00_dev *rt2x00dev,if (qual->vgc_level != vgc_level) {if (rt2x00_rt (rt2x00dev,RT3572 ) ||rt2x00_rt (rt2x00dev,RT3593 ) || -rt2x00_rt (rt2x00dev,RT3883 )) { +rt2x00_rt (rt2x00dev,RT3883 ) || +rt2x00_rt (rt2x00dev,RT6352 )) {rt2800_bbp_write_with_rx_chain (rt2x00dev,66 , vgc_level); }else if (rt2x00_rt (rt2x00dev,RT5592 )) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 437/530 wifi: rt2x00: set SoC wmac clock register
In reply to Greg Kroah-HartmanFrom: Daniel Golle <[email protected]>
[ Upstream commit cbde6ed406a51092d9e8a2df058f5f8490f27443 ]
Instead of using the default value 33 (pci), set US_CYC_CNT init based on Programming guide:
If available, set chipset bus clock with fallback to cpu clock/3.
--- .../net/wireless/ralink/rt2x00/rt2800lib.c | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+)
drivers/net/wireless/ralink/rt2x00/rt2800lib.c +21 -0
@@ -6131,6 +6131,27 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) reg =rt2800_register_read (rt2x00dev,US_CYC_CNT );rt2x00_set_field32 (®,US_CYC_CNT_CLOCK_CYCLE ,125 );rt2800_register_write (rt2x00dev,US_CYC_CNT , reg); + }else if (rt2x00_is_soc (rt2x00dev)) { +struct clk *clk =clk_get_sys ("bus" ,NULL ); +int rate; + +if (IS_ERR (clk)) { + clk =clk_get_sys ("cpu" ,NULL ); + +if (IS_ERR (clk)) { + rate =125 ; + }else { + rate =clk_get_rate (clk) /3000000 ; +clk_put (clk); + } + }else { + rate =clk_get_rate (clk) /1000000 ; +clk_put (clk); + } + + reg =rt2800_register_read (rt2x00dev,US_CYC_CNT ); +rt2x00_set_field32 (®,US_CYC_CNT_CLOCK_CYCLE , rate); +rt2800_register_write (rt2x00dev,US_CYC_CNT , reg); } reg =rt2800_register_read (rt2x00dev,HT_FBK_CFG0 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 438/530 wifi: rt2x00: correctly set BBP register 86 for MT7620
In reply to Greg Kroah-HartmanFrom: Daniel Golle <[email protected]>
[ Upstream commit c9aada64fe6493461127f1522d7e2f01792d2424 ]
Instead of 0 set the correct value for BBP register 86 for MT7620.
--- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/wireless/ralink/rt2x00/rt2800lib.c +4 -1
@@ -4164,7 +4164,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,rt2800_bbp_write (rt2x00dev,62 ,0x37 - rt2x00dev->lna_gain);rt2800_bbp_write (rt2x00dev,63 ,0x37 - rt2x00dev->lna_gain);rt2800_bbp_write (rt2x00dev,64 ,0x37 - rt2x00dev->lna_gain); -rt2800_bbp_write (rt2x00dev,86 ,0 ); +if (rt2x00_rt (rt2x00dev,RT6352 )) +rt2800_bbp_write (rt2x00dev,86 ,0x38 ); +else +rt2800_bbp_write (rt2x00dev,86 ,0 ); }if (rf->channel <=14 ) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 439/530 hwmon: (sht4x) do not overflow clamping operation on 32-bit platforms
In reply to Greg Kroah-HartmanFrom: Jason A. Donenfeld <[email protected]>
[ Upstream commit f9c0cf8f26de367c58e48b02b1cdb9c377626e6f ]
On 32-bit platforms, long is 32 bits, so (long)UINT_MAX is less than (long)SHT4X_MIN_POLL_INTERVAL, which means the clamping operation is bogus. Fix this by clamping at INT_MAX, so that the upperbound is the same on all platforms.
--- drivers/hwmon/sht4x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/sht4x.c +1 -1
@@ -129,7 +129,7 @@ static int sht4x_read_values(struct sht4x_data *data)static ssize_t sht4x_interval_write (struct sht4x_data *data,long val) { - data->update_interval =clamp_val (val,SHT4X_MIN_POLL_INTERVAL ,UINT_MAX ); + data->update_interval =clamp_val (val,SHT4X_MIN_POLL_INTERVAL ,INT_MAX );return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 440/530 net: If sock is dead dont access socks sk_wq in sk_stream_wait_memory
In reply to Greg Kroah-HartmanFrom: Liu Jian <[email protected]>
[ Upstream commit 3f8ef65af927db247418d4e1db49164d7a158fc5 ]
Fixes the below NULL pointer dereference:
[...]
[ 14.471200] Call Trace: [ 14.471562] <TASK> [ 14.471882] lock_acquire+0x245/0x2e0 [ 14.472416] ? remove_wait_queue+0x12/0x50 [ 14.473014] ? _raw_spin_lock_irqsave+0x17/0x50 [ 14.473681] _raw_spin_lock_irqsave+0x3d/0x50 [ 14.474318] ? remove_wait_queue+0x12/0x50 [ 14.474907] remove_wait_queue+0x12/0x50 [ 14.475480] sk_stream_wait_memory+0x20d/0x340 [ 14.476127] ? do_wait_intr_irq+0x80/0x80 [ 14.476704] do_tcp_sendpages+0x287/0x600 [ 14.477283] tcp_bpf_push+0xab/0x260 [ 14.477817] tcp_bpf_sendmsg_redir+0x297/0x500 [ 14.478461] ? __local_bh_enable_ip+0x77/0xe0 [ 14.479096] tcp_bpf_send_verdict+0x105/0x470 [ 14.479729] tcp_bpf_sendmsg+0x318/0x4f0 [ 14.480311] sock_sendmsg+0x2d/0x40 [ 14.480822] ____sys_sendmsg+0x1b4/0x1c0 [ 14.481390] ? copy_msghdr_from_user+0x62/0x80 [ 14.482048] ___sys_sendmsg+0x78/0xb0 [ 14.482580] ? vmf_insert_pfn_prot+0x91/0x150 [ 14.483215] ? __do_fault+0x2a/0x1a0 [ 14.483738] ? do_fault+0x15e/0x5d0 [ 14.484246] ? __handle_mm_fault+0x56b/0x1040 [ 14.484874] ? lock_is_held_type+0xdf/0x130 [ 14.485474] ? find_held_lock+0x2d/0x90 [ 14.486046] ? __sys_sendmsg+0x41/0x70 [ 14.486587] __sys_sendmsg+0x41/0x70 [ 14.487105] ? intel_pmu_drain_pebs_core+0x350/0x350 [ 14.487822] do_syscall_64+0x34/0x80 [ 14.488345] entry_SYSCALL_64_after_hwframe+0x63/0xcd [...]
The test scenario has the following flow:
thread1 thread2
----------- ---------------
tcp_bpf_sendmsg
tcp_bpf_send_verdict
tcp_bpf_sendmsg_redir sock_close
tcp_bpf_push_locked __sock_release
tcp_bpf_push //inet_release
do_tcp_sendpages sock->ops->release
sk_stream_wait_memory // tcp_close
sk_wait_event sk->sk_prot->close
release_sock(__sk);
***
lock_sock(sk);
__tcp_close
sock_orphan(sk)
sk->sk_wq = NULL
release_sock
****
lock_sock(__sk);
remove_wait_queue(sk_sleep(sk), &wait);
sk_sleep(sk)
//NULL pointer dereference
&rcu_dereference_raw(sk->sk_wq)->waitWhile waiting for memory in thread1, the socket is released with its wait queue because thread2 has closed it. This caused by tcp_bpf_send_verdict didn't increase the f_count of psock->sk_redir->sk_socket->file in thread1.
We should check if SOCK_DEAD flag is set on wakeup in sk_stream_wait_memory before accessing the wait queue.
--- net/core/stream.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/core/stream.c +2 -1
@@ -159,7 +159,8 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) *timeo_p = current_timeo; } out: -remove_wait_queue (sk_sleep (sk), &wait); +if (!sock_flag (sk,SOCK_DEAD )) +remove_wait_queue (sk_sleep (sk), &wait);return err; do_error:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 441/530 Bluetooth: L2CAP: Fix user-after-free
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 35fcbc4243aad7e7d020b7c1dfb14bb888b20a4f ]
This uses l2cap_chan_hold_unless_zero() after calling __l2cap_get_chan_blah() to prevent the following trace:
Bluetooth: l2cap_core.c:static void l2cap_chan_destroy(struct kref *kref)
Bluetooth: chan 0000000023c4974d
Bluetooth: parent 00000000ae861c08
==================================================================
BUG: KASAN: use-after-free in __mutex_waiter_is_first kernel/locking/mutex.c:191 [inline] BUG: KASAN: use-after-free in __mutex_lock_common kernel/locking/mutex.c:671 [inline] BUG: KASAN: use-after-free in __mutex_lock+0x278/0x400 kernel/locking/mutex.c:729 Read of size 8 at addr ffff888006a49b08 by task kworker/u3:2/389
--- net/bluetooth/l2cap_core.c | 7 +++++++ 1 file changed, 7 insertions(+)
net/bluetooth/l2cap_core.c +7 -0
@@ -4309,6 +4309,12 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, } } + chan =l2cap_chan_hold_unless_zero (chan); +if (!chan) { + err = -EBADSLT ; + goto unlock; + } + err =0 ;l2cap_chan_lock (chan);
@@ -4338,6 +4344,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, }l2cap_chan_unlock (chan); +l2cap_chan_put (chan); unlock:mutex_unlock (&conn->chan_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 442/530 r8152: Rate limit overflow messages
In reply to Greg Kroah-HartmanFrom: Andrew Gaul <[email protected]>
[ Upstream commit 93e2be344a7db169b7119de21ac1bf253b8c6907 ]
My system shows almost 10 million of these messages over a 24-hour period which pollutes my logs.
--- drivers/net/usb/r8152.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/usb/r8152.c +3 -1
@@ -1871,7 +1871,9 @@ static void intr_callback(struct urb *urb) "Stop submitting intr, status %d\n", status);return ;case -EOVERFLOW : -netif_info (tp, intr, tp->netdev,"intr status -EOVERFLOW\n" ); +if (net_ratelimit ()) +netif_info (tp, intr, tp->netdev, +"intr status -EOVERFLOW\n" ); goto resubmit;/* -EPIPE: should clear the halt */ default :
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 443/530 drm/nouveau/nouveau_bo: fix potential memory leak in nouveau_bo_alloc()
In reply to Greg Kroah-HartmanFrom: Jianglei Nie <[email protected]>
[ Upstream commit 6dc548745d5b5102e3c53dc5097296ac270b6c69 ]
nouveau_bo_alloc() allocates a memory chunk for "nvbo" with kzalloc(). When some error occurs, "nvbo" should be released. But when WARN_ON(pi < 0)) equals true, the function return ERR_PTR without releasing the "nvbo", which will lead to a memory leak.
We should release the "nvbo" with kfree() if WARN_ON(pi < 0)) equals true.
--- drivers/gpu/drm/nouveau/nouveau_bo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/nouveau/nouveau_bo.c +3 -1
@@ -281,8 +281,10 @@ nouveau_bo_alloc(struct nouveau_cli *cli, u64 *size, int *align, u32 domain,break ; } -if (WARN_ON (pi <0 )) +if (WARN_ON (pi <0 )) { +kfree (nvbo);return ERR_PTR (-EINVAL ); + }/* Disable compression if suitable settings couldn't be found. */ if (nvbo->comp && !vmm->page[pi].comp) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 444/530 drm: Use size_t type for len variable in drm_copy_field()
In reply to Greg Kroah-HartmanFrom: Javier Martinez Canillas <[email protected]>
[ Upstream commit 94dc3471d1b2b58b3728558d0e3f264e9ce6ff59 ]
The strlen() function returns a size_t which is an unsigned int on 32-bit arches and an unsigned long on 64-bit arches. But in the drm_copy_field() function, the strlen() return value is assigned to an 'int len' variable.
Later, the len variable is passed as copy_from_user() third argument that is an unsigned long parameter as well.
In theory, this can lead to an integer overflow via type conversion. Since the assignment happens to a signed int lvalue instead of a size_t lvalue.
In practice though, that's unlikely since the values copied are set by DRM drivers and not controlled by userspace. But using a size_t for len is the correct thing to do anyways.
--- drivers/gpu/drm/drm_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/drm_ioctl.c +1 -1
@@ -472,7 +472,7 @@ EXPORT_SYMBOL(drm_invalid_op);*/ static int drm_copy_field (char __user *buf,size_t *buf_len,const char *value) { -int len; +size_t len;/* don't overflow userbuf */ len =strlen (value);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 445/530 drm: Prevent drm_copy_field() to attempt copying a NULL pointer
In reply to Greg Kroah-HartmanFrom: Javier Martinez Canillas <[email protected]>
[ Upstream commit f6ee30407e883042482ad4ad30da5eaba47872ee ]
There are some struct drm_driver fields that are required by drivers since drm_copy_field() attempts to copy them to user-space via DRM_IOCTL_VERSION.
But it can be possible that a driver has a bug and did not set some of the fields, which leads to drm_copy_field() attempting to copy a NULL pointer:
[ +10.395966] Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000000000000000
[ +0.010955] Mem abort info: [ +0.002835] ESR = 0x0000000096000004 [ +0.003872] EC = 0x25: DABT (current EL), IL = 32 bits [ +0.005395] SET = 0, FnV = 0 [ +0.003113] EA = 0, S1PTW = 0 [ +0.003182] FSC = 0x04: level 0 translation fault [ +0.004964] Data abort info: [ +0.002919] ISV = 0, ISS = 0x00000004 [ +0.003886] CM = 0, WnR = 0 [ +0.003040] user pgtable: 4k pages, 48-bit VAs, pgdp=0000000115dad000 [ +0.006536] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000 [ +0.006925] Internal error: Oops: 96000004 [#1] SMP ... [ +0.011113] pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ +0.007061] pc : __pi_strlen+0x14/0x150 [ +0.003895] lr : drm_copy_field+0x30/0x1a4 [ +0.004156] sp : ffff8000094b3a50 [ +0.003355] x29: ffff8000094b3a50 x28: ffff8000094b3b70 x27: 0000000000000040 [ +0.007242] x26: ffff443743c2ba00 x25: 0000000000000000 x24: 0000000000000040 [ +0.007243] x23: ffff443743c2ba00 x22: ffff8000094b3b70 x21: 0000000000000000 [ +0.007241] x20: 0000000000000000 x19: ffff8000094b3b90 x18: 0000000000000000 [ +0.007241] x17: 0000000000000000 x16: 0000000000000000 x15: 0000aaab14b9af40 [ +0.007241] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000 [ +0.007239] x11: 0000000000000000 x10: 0000000000000000 x9 : ffffa524ad67d4d8 [ +0.007242] x8 : 0101010101010101 x7 : 7f7f7f7f7f7f7f7f x6 : 6c6e6263606e7141 [ +0.007239] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 [ +0.007241] x2 : 0000000000000000 x1 : ffff8000094b3b90 x0 : 0000000000000000 [ +0.007240] Call trace: [ +0.002475] __pi_strlen+0x14/0x150 [ +0.003537] drm_version+0x84/0xac [ +0.003448] drm_ioctl_kernel+0xa8/0x16c [ +0.003975] drm_ioctl+0x270/0x580 [ +0.003448] __arm64_sys_ioctl+0xb8/0xfc [ +0.003978] invoke_syscall+0x78/0x100 [ +0.003799] el0_svc_common.constprop.0+0x4c/0xf4 [ +0.004767] do_el0_svc+0x38/0x4c [ +0.003357] el0_svc+0x34/0x100 [ +0.003185] el0t_64_sync_handler+0x11c/0x150 [ +0.004418] el0t_64_sync+0x190/0x194 [ +0.003716] Code: 92402c04 b200c3e8 f13fc09f 5400088c (a9400c02) [ +0.006180] ---[ end trace 0000000000000000 ]---
--- drivers/gpu/drm/drm_ioctl.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/drm_ioctl.c +6 -0
@@ -474,6 +474,12 @@ static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value) {size_t len; +/* don't attempt to copy a NULL pointer */ +if (WARN_ONCE (!value,"BUG: the value to copy was not set!" )) { + *buf_len =0 ; +return 0 ; + } +/* don't overflow userbuf */ len =strlen (value);if (len > *buf_len)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 446/530 drm/komeda: Fix handling of atomic commits in the atomic_commit_tail hook
In reply to Greg Kroah-HartmanFrom: Liviu Dudau <[email protected]>
[ Upstream commit eaa225b6b52233d45457fd33730e1528c604d92d ]
Komeda driver relies on the generic DRM atomic helper functions to handle commits. It only implements an atomic_commit_tail hook for the mode_config_helper_funcs and even that one is pretty close to the generic implementation with the exception of additional dma_fence signalling.
What the generic helper framework doesn't do is waiting for the actual hardware to signal that the commit parameters have been written into the appropriate registers. As we signal CRTC events only on the irq handlers, we need to flush the configuration and wait for the hardware to respond.
Add the Komeda specific implementation for atomic_commit_hw_done() that flushes and waits for flip done before calling drm_atomic_helper_commit_hw_done().
The fix was prompted by a patch from Carsten Haitzler where he was trying to solve the same issue but in a different way that I think can lead to wrong event signaling to userspace.
--- .../gpu/drm/arm/display/komeda/komeda_crtc.c | 4 ++-- .../gpu/drm/arm/display/komeda/komeda_kms.c | 21 ++++++++++++++++++- .../gpu/drm/arm/display/komeda/komeda_kms.h | 2 ++ 3 files changed, 24 insertions(+), 3 deletions(-)
drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +2 -2
@@ -235,7 +235,7 @@ void komeda_crtc_handle_event(struct komeda_crtc *kcrtc, crtc->state->event =NULL ;drm_crtc_send_vblank_event (crtc, event); }else { -DRM_WARN ("CRTC[%d]: FLIP happen but no pending commit.\n" , +DRM_WARN ("CRTC[%d]: FLIP happened but no pending commit.\n" ,drm_crtc_index (&kcrtc->base)); }spin_unlock_irqrestore (&crtc->dev->event_lock, flags);
@@ -286,7 +286,7 @@ komeda_crtc_atomic_enable(struct drm_crtc *crtc,komeda_crtc_do_flush (crtc, old); } -static void +void komeda_crtc_flush_and_wait_for_flip_done (struct komeda_crtc *kcrtc,struct completion *input_flip_done) {
drivers/gpu/drm/arm/display/komeda/komeda_kms.c +20 -1
@@ -69,6 +69,25 @@ static const struct drm_driver komeda_kms_driver = { .minor = 1, }; +static void komeda_kms_atomic_commit_hw_done (struct drm_atomic_state *state) +{ +struct drm_device *dev = state->dev; +struct komeda_kms_dev *kms =to_kdev (dev); +int i; + +for (i =0 ; i < kms->n_crtcs; i++) { +struct komeda_crtc *kcrtc = &kms->crtcs[i]; + +if (kcrtc->base.state->active) { +struct completion *flip_done =NULL ; +if (kcrtc->base.state->event) + flip_done = kcrtc->base.state->event->base.completion; +komeda_crtc_flush_and_wait_for_flip_done (kcrtc, flip_done); + } + } +drm_atomic_helper_commit_hw_done (state); +} +static void komeda_kms_commit_tail (struct drm_atomic_state *old_state) {struct drm_device *dev = old_state->dev;
@@ -81,7 +100,7 @@ static void komeda_kms_commit_tail(struct drm_atomic_state *old_state)drm_atomic_helper_commit_modeset_enables (dev, old_state); -drm_atomic_helper_commit_hw_done (old_state); +komeda_kms_atomic_commit_hw_done (old_state);drm_atomic_helper_wait_for_flip_done (dev, old_state);
drivers/gpu/drm/arm/display/komeda/komeda_kms.h +2 -0
@@ -182,6 +182,8 @@ void komeda_kms_cleanup_private_objs(struct komeda_kms_dev *kms);void komeda_crtc_handle_event (struct komeda_crtc *kcrtc,struct komeda_events *evts); +void komeda_crtc_flush_and_wait_for_flip_done (struct komeda_crtc *kcrtc, +struct completion *input_flip_done);struct komeda_kms_dev *komeda_kms_attach (struct komeda_dev *mdev);void komeda_kms_detach (struct komeda_kms_dev *kms);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 447/530 gpu: lontium-lt9611: Fix NULL pointer dereference in lt9611_connector_init()
In reply to Greg Kroah-HartmanFrom: Zeng Jingxiang <[email protected]>
[ Upstream commit ef8886f321c5dab8124b9153d25afa2a71d05323 ]
A NULL check for bridge->encoder shows that it may be NULL, but it already been dereferenced on all paths leading to the check.
812 if (!bridge->encoder) {
Dereference the pointer bridge->encoder.
810 drm_connector_attach_encoder(<9611->connector, bridge->encoder);
--- drivers/gpu/drm/bridge/lontium-lt9611.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/bridge/lontium-lt9611.c +2 -1
@@ -816,13 +816,14 @@ static int lt9611_connector_init(struct drm_bridge *bridge, struct lt9611 *lt961drm_connector_helper_add (<9611->connector, <9611_bridge_connector_helper_funcs); -drm_connector_attach_encoder (<9611->connector, bridge->encoder);if (!bridge->encoder) {DRM_ERROR ("Parent encoder object not found" );return -ENODEV ; } +drm_connector_attach_encoder (<9611->connector, bridge->encoder); +return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 448/530 drm/amd/display: fix overflow on MIN_I64 definition
In reply to Greg Kroah-HartmanFrom: David Gow <[email protected]>
[ Upstream commit 6ae0632d17759852c07e2d1e0a31c728eb6ba246 ]
The definition of MIN_I64 in bw_fixed.c can cause gcc to whinge about integer overflow, because it is treated as a positive value, which is then negated. The temporary positive value is not necessarily representable.
This causes the following warning:../drivers/gpu/drm/amd/amdgpu/../display/dc/dml/calcs/bw_fixed.c:30:19:
warning: integer overflow in expression ‘-9223372036854775808’ of type ‘long long int’ results in ‘-9223372036854775808’ [-Woverflow]
30 | (int64_t)(-(1LL << 63))
| ^
Writing out (-MAX_I64 - 1) works instead.
--- drivers/gpu/drm/amd/display/dc/calcs/bw_fixed.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/display/dc/calcs/bw_fixed.c +3 -3
@@ -26,12 +26,12 @@#include "bw_fixed.h" -#define MIN_I64 \ - (int64_t)(-(1LL << 63)) -#define MAX_I64 \ (int64_t)((1ULL << 63) - 1) +#define MIN_I64 \ + (-MAX_I64 - 1) +#define FRACTIONAL_PART_MASK \ ((1ULL << BW_FIXED_BITS_PER_FRACTIONAL_PART) - 1)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 449/530 udmabuf: Set ubuf->sg = NULL if the creation of sg table fails
In reply to Greg Kroah-HartmanFrom: Vivek Kasireddy <[email protected]>
[ Upstream commit d9c04a1b7a15b5e74b2977461d9511e497f05d8f ]
When userspace tries to map the dmabuf and if for some reason (e.g. OOM) the creation of the sg table fails, ubuf->sg needs to be set to NULL. Otherwise, when the userspace subsequently closes the dmabuf fd, we'd try to erroneously free the invalid sg table from release_udmabuf resulting in the following crash reported by syzbot:
general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 0 PID: 3609 Comm: syz-executor487 Not tainted 5.19.0-syzkaller-13930-g7ebfc85e2cd7 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/22/2022 RIP: 0010:dma_unmap_sgtable include/linux/dma-mapping.h:378 [inline] RIP: 0010:put_sg_table drivers/dma-buf/udmabuf.c:89 [inline] RIP: 0010:release_udmabuf+0xcb/0x4f0 drivers/dma-buf/udmabuf.c:114 Code: 48 89 fa 48 c1 ea 03 80 3c 02 00 0f 85 2b 04 00 00 48 8d 7d 0c 4c 8b 63 30 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <0f> b6 14 02 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 e2 RSP: 0018:ffffc900037efd30 EFLAGS: 00010246 RAX: dffffc0000000000 RBX: ffffffff8cb67800 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffffffff84ad27e0 RDI: 0000000000000000 RBP: fffffffffffffff4 R08: 0000000000000005 R09: 0000000000000000 R10: 0000000000000000 R11: 000000000008c07c R12: ffff88801fa05000 R13: ffff888073db07e8 R14: ffff888025c25440 R15: 0000000000000000 FS: 0000555555fc4300(0000) GS:ffff8880b9a00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fc1c0ce06e4 CR3: 00000000715e6000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> dma_buf_release+0x157/0x2d0 drivers/dma-buf/dma-buf.c:78 __dentry_kill+0x42b/0x640 fs/dcache.c:612 dentry_kill fs/dcache.c:733 [inline] dput+0x806/0xdb0 fs/dcache.c:913 __fput+0x39c/0x9d0 fs/file_table.c:333 task_work_run+0xdd/0x1a0 kernel/task_work.c:177 ptrace_notify+0x114/0x140 kernel/signal.c:2353 ptrace_report_syscall include/linux/ptrace.h:420 [inline] ptrace_report_syscall_exit include/linux/ptrace.h:482 [inline] syscall_exit_work kernel/entry/common.c:249 [inline] syscall_exit_to_user_mode_prepare+0x129/0x280 kernel/entry/common.c:276 __syscall_exit_to_user_mode_work kernel/entry/common.c:281 [inline] syscall_exit_to_user_mode+0x9/0x50 kernel/entry/common.c:294 do_syscall_64+0x42/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7fc1c0c35b6b Code: 0f 05 48 3d 00 f0 ff ff 77 45 c3 0f 1f 40 00 48 83 ec 18 89 7c 24
0c e8 63 fc ff ff 8b 7c 24 0c 41 89 c0 b8 03 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 35 44 89 c7 89 44 24 0c e8 a1 fc ff ff 8b 44
RSP: 002b:00007ffd78a06090 EFLAGS: 00000293 ORIG_RAX: 0000000000000003
RAX: 0000000000000000 RBX: 0000000000000007 RCX: 00007fc1c0c35b6b
RDX: 0000000020000280 RSI: 0000000040086200 RDI: 0000000000000006
RBP: 0000000000000007 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000293 R12: 000000000000000c
R13: 0000000000000003 R14: 00007fc1c0cfe4a0 R15: 00007ffd78a06140
</TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:dma_unmap_sgtable include/linux/dma-mapping.h:378 [inline] RIP: 0010:put_sg_table drivers/dma-buf/udmabuf.c:89 [inline] RIP: 0010:release_udmabuf+0xcb/0x4f0 drivers/dma-buf/udmabuf.c:114
--- drivers/dma-buf/udmabuf.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/dma-buf/udmabuf.c +6 -3
@@ -124,17 +124,20 @@ static int begin_cpu_udmabuf(struct dma_buf *buf, {struct udmabuf *ubuf = buf->priv;struct device *dev = ubuf->device->this_device; +int ret =0 ;if (!ubuf->sg) { ubuf->sg =get_sg_table (dev, buf, direction); -if (IS_ERR (ubuf->sg)) -return PTR_ERR (ubuf->sg); +if (IS_ERR (ubuf->sg)) { + ret =PTR_ERR (ubuf->sg); + ubuf->sg =NULL ; + } }else {dma_sync_sg_for_cpu (dev, ubuf->sg->sgl, ubuf->sg->nents, direction); } -return 0 ; +return ret; } static int end_cpu_udmabuf(struct dma_buf *buf,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 450/530 drm: bridge: dw_hdmi: only trigger hotplug event on link change
In reply to Greg Kroah-HartmanFrom: Lucas Stach <[email protected]>
[ Upstream commit da09daf881082266e4075657fac53c7966de8e4d ]
There are two events that signal a real change of the link state: HPD going high means the sink is newly connected or wants the source to re-read the EDID, RX sense going low is a indication that the link has been disconnected.
Ignore the other two events that also trigger interrupts, but don't need immediate attention: HPD going low does not necessarily mean the link has been lost and should not trigger a immediate read of the status. RX sense going high also does not require a detect cycle, as HPD going high is the right point in time to read the EDID.
--- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +8 -5
@@ -2970,6 +2970,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) {struct dw_hdmi *hdmi = dev_id;u8 intr_stat, phy_int_pol, phy_pol_mask, phy_stat; +enum drm_connector_status status = connector_status_unknown; intr_stat =hdmi_readb (hdmi,HDMI_IH_PHY_STAT0 ); phy_int_pol =hdmi_readb (hdmi,HDMI_PHY_POL0 );
@@ -3008,13 +3009,15 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)cec_notifier_phys_addr_invalidate (hdmi->cec_notifier);mutex_unlock (&hdmi->cec_notifier_mutex); } - } -if (intr_stat &HDMI_IH_PHY_STAT0_HPD ) { -enum drm_connector_status status = phy_int_pol &HDMI_PHY_HPD - ? connector_status_connected - : connector_status_disconnected; +if (phy_stat &HDMI_PHY_HPD ) + status = connector_status_connected; + +if (!(phy_stat & (HDMI_PHY_HPD |HDMI_PHY_RX_SENSE ))) + status = connector_status_disconnected; + } +if (status != connector_status_unknown) {dev_dbg (hdmi->dev,"EVENT=%s\n" , status == connector_status_connected ?"plugin" :"plugout" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 451/530 ALSA: usb-audio: Register card at the last interface
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
[ Upstream commit 6392dcd1d0c7034ccf630ec55fc9e5810ecadf3b ]
The USB-audio driver matches per interface, and as default, it registers the card instance at the very first instance. This can be a problem for the devices that have multiple interfaces to be probed, as the udev rule isn't applied properly for the later appearing interfaces. Although we introduced the delayed_register option and the quirks for covering those shortcomings, it's nothing but a workaround for specific devices.
This patch is an another attempt to fix the problem in a more generic way. Now the driver checks the whole USB device descriptor at the very first time when an interface is attached to a sound card. It looks at each matching interface in the descriptor and remembers the last matching one. The snd_card_register() is invoked only when this last interface is probed.
After this change, the quirks for the delayed registration become superfluous, hence they are removed along with the patch. OTOH, the delayed_register option is still kept, as it might be useful for some corner cases (e.g. a special driver overtakes the interface probe from the standard driver, and the last interface probe may miss).
--- sound/usb/card.c | 32 +++++++++++++++++++++++++------- sound/usb/quirks.c | 42 ------------------------------------------ sound/usb/quirks.h | 2 -- sound/usb/usbaudio.h | 1 + 4 files changed, 26 insertions(+), 51 deletions(-)
sound/usb/card.c +25 -7
@@ -689,7 +689,7 @@ static bool get_alias_id(struct usb_devireturn false; } -static bool check_delayed_register_option (struct snd_usb_audio *chip,int iface) +static int check_delayed_register_option (struct snd_usb_audio *chip) {int i;unsigned int id, inum;
@@ -698,14 +698,31 @@ static bool check_delayed_register_optioif (delayed_register[i] &&sscanf (delayed_register[i],"%x:%x" , &id, &inum) ==2 && id == chip->usb_id) -return iface < inum; +return inum; } -return false; +return -1 ; }static const struct usb_device_id usb_audio_ids[];/* defined below */ +/* look for the last interface that matches with our ids and remember it */ +static void find_last_interface (struct snd_usb_audio *chip) +{ +struct usb_host_config *config = chip->dev->actconfig; +struct usb_interface *intf; +int i; + +if (!config) +return ; +for (i =0 ; i < config->desc.bNumInterfaces; i++) { + intf = config->interface[i]; +if (usb_match_id (intf, usb_audio_ids)) + chip->last_iface = intf->altsetting[0 ].desc.bInterfaceNumber; + } +usb_audio_dbg (chip,"Found last interface = %d\n" , chip->last_iface); +} +/* look for the corresponding quirk */ static const struct snd_usb_audio_quirk *get_alias_quirk (struct usb_device *dev,unsigned int id)
@@ -812,6 +829,7 @@ static int usb_audio_probe(struct usb_in err = -ENODEV ; goto __error; } +find_last_interface (chip); }if (chip->num_interfaces >=MAX_CARD_INTERFACES ) {
@@ -861,11 +879,11 @@ static int usb_audio_probe(struct usb_in chip->need_delayed_register = false;/* clear again */ } -/* we are allowed to call snd_card_register() many times, but first -* check to see if a device needs to skip it or do anything special +/* register card if we reach to the last interface or to the specified +* one given via option */ -if (!snd_usb_registration_quirk (chip, ifnum) && - !check_delayed_register_option (chip, ifnum)) { +if (check_delayed_register_option (chip) == ifnum || + chip->last_iface == ifnum) { err =snd_card_register (chip->card);if (err <0 ) goto __error;
sound/usb/quirks.c +0 -42
48 lines not on this page · raw message
sound/usb/quirks.h +0 -2
@@ -48,8 +48,6 @@ void snd_usb_audioformat_attributes_quirstruct audioformat *fp, int stream); -bool snd_usb_registration_quirk (struct snd_usb_audio *chip,int iface); -void snd_usb_init_quirk_flags (struct snd_usb_audio *chip);#endif /* __USBAUDIO_QUIRKS_H */
sound/usb/usbaudio.h +1 -0
@@ -37,6 +37,7 @@ struct snd_usb_audio {unsigned int quirk_flags; unsigned int need_delayed_register:1; /* warn for delayed registration */int num_interfaces; +int last_iface;int num_suspended_intf;int sample_rate_read_error;
Greg Kroah-Hartman
maintainerPATCH 452/530 drm/vc4: vec: Fix timings for VEC modes
In reply to Greg Kroah-HartmanFrom: Mateusz Kwiatkowski <[email protected]>
[ Upstream commit 30d7565be96b3946c18a1ce3fd538f7946839092 ]
This commit fixes vertical timings of the VEC (composite output) modes to accurately represent the 525-line ("NTSC") and 625-line ("PAL") ITU-R standards.
Previous timings were actually defined as 502 and 601 lines, resulting in non-standard 62.69 Hz and 52 Hz signals being generated, respectively.
--- drivers/gpu/drm/vc4/vc4_vec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/vc4/vc4_vec.c +2 -2
@@ -256,7 +256,7 @@ static void vc4_vec_ntsc_j_mode_set(struct vc4_vec *vec)static const struct drm_display_mode ntsc_mode = {DRM_MODE ("720x480" ,DRM_MODE_TYPE_DRIVER ,13500 ,720 ,720 +14 ,720 +14 +64 ,720 +14 +64 +60 ,0 , -480 ,480 +3 ,480 +3 +3 ,480 +3 +3 +16 ,0 , +480 ,480 +7 ,480 +7 +6 ,525 ,0 ,DRM_MODE_FLAG_INTERLACE ) };
@@ -278,7 +278,7 @@ static void vc4_vec_pal_m_mode_set(struct vc4_vec *vec)static const struct drm_display_mode pal_mode = {DRM_MODE ("720x576" ,DRM_MODE_TYPE_DRIVER ,13500 ,720 ,720 +20 ,720 +20 +64 ,720 +20 +64 +60 ,0 , -576 ,576 +2 ,576 +2 +3 ,576 +2 +3 +20 ,0 , +576 ,576 +4 ,576 +4 +6 ,625 ,0 ,DRM_MODE_FLAG_INTERLACE ) };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 453/530 drm: panel-orientation-quirks: Add quirk for Anbernic Win600
In reply to Greg Kroah-HartmanFrom: Maya Matuszczyk <[email protected]>
[ Upstream commit 770e19076065e079a32f33eb11be2057c87f1cde ]
This device is another x86 gaming handheld, and as (hopefully) there is only one set of DMI IDs it's using DMI_EXACT_MATCH
--- drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/drm_panel_orientation_quirks.c +6 -0
@@ -128,6 +128,12 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"), }, .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* Anbernic Win600 */ + .matches = { +DMI_EXACT_MATCH (DMI_BOARD_VENDOR ,"Anbernic" ), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Win600"), + }, + .driver_data = (void *)&lcd720x1280_rightside_up, }, { /* Asus T100HA */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 454/530 platform/chrome: cros_ec: Notify the PM of wake events during resume
In reply to Greg Kroah-HartmanFrom: Jameson Thies <[email protected]>
[ Upstream commit 8edd2752b0aa498b3a61f3caee8f79f7e0567fad ]
cros_ec_handle_event in the cros_ec driver can notify the PM of wake events. When a device is suspended, cros_ec_handle_event will not check MKBP events. Instead, received MKBP events are checked during resume by cros_ec_report_events_during_suspend. But cros_ec_report_events_during_suspend cannot notify the PM if received events are wake events, causing wake events to not be reported if received while the device is suspended.
Update cros_ec_report_events_during_suspend to notify the PM of wake events during resume by calling pm_wakeup_event.
--- drivers/platform/chrome/cros_ec.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/platform/chrome/cros_ec.c +7 -1
@@ -353,10 +353,16 @@ EXPORT_SYMBOL(cros_ec_suspend);static void cros_ec_report_events_during_suspend (struct cros_ec_device *ec_dev) { +bool wake_event; +while (ec_dev->mkbp_event_supported && -cros_ec_get_next_event (ec_dev,NULL ,NULL ) >0 ) +cros_ec_get_next_event (ec_dev, &wake_event,NULL ) >0 ) {blocking_notifier_call_chain (&ec_dev->event_notifier,1 , ec_dev); + +if (wake_event &&device_may_wakeup (ec_dev->dev)) +pm_wakeup_event (ec_dev->dev,0 ); + } }/**
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 455/530 platform/x86: msi-laptop: Change DMI match / alias strings to fix module autoloading
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit 2a2565272a3628e45d61625e36ef17af7af4e3de ]
On a MSI S270 with Fedora 37 x86_64 / systemd-251.4 the module does not properly autoload.
This is likely caused by issues with how systemd-udevd handles the single quote char (') which is part of the sys_vendor / chassis_vendor strings on this laptop. As a workaround remove the single quote char + everything behind it from the sys_vendor + chassis_vendor matches. This fixes the module not autoloading.
--- drivers/platform/x86/msi-laptop.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/platform/x86/msi-laptop.c +3 -5
@@ -596,11 +596,10 @@ static const struct dmi_system_id msi_dmi_table[] __initconst = { { .ident = "MSI S270", .matches = { -DMI_MATCH (DMI_SYS_VENDOR ,"MICRO-STAR INT'L CO.,LTD" ), +DMI_MATCH (DMI_SYS_VENDOR ,"MICRO-STAR INT" ),DMI_MATCH (DMI_PRODUCT_NAME ,"MS-1013" ),DMI_MATCH (DMI_PRODUCT_VERSION ,"0131" ), -DMI_MATCH (DMI_CHASSIS_VENDOR , -"MICRO-STAR INT'L CO.,LTD" ) +DMI_MATCH (DMI_CHASSIS_VENDOR ,"MICRO-STAR INT" ) }, .driver_data = &quirk_old_ec_model, .callback = dmi_check_cb
@@ -633,8 +632,7 @@ static const struct dmi_system_id msi_dmi_table[] __initconst = {DMI_MATCH (DMI_SYS_VENDOR ,"NOTEBOOK" ),DMI_MATCH (DMI_PRODUCT_NAME ,"SAM2000" ),DMI_MATCH (DMI_PRODUCT_VERSION ,"0131" ), -DMI_MATCH (DMI_CHASSIS_VENDOR , -"MICRO-STAR INT'L CO.,LTD" ) +DMI_MATCH (DMI_CHASSIS_VENDOR ,"MICRO-STAR INT" ) }, .driver_data = &quirk_old_ec_model, .callback = dmi_check_cb
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 456/530 ASoC: SOF: pci: Change DMI match info to support all Chrome platforms
In reply to Greg Kroah-HartmanFrom: Jairaj Arava <[email protected]>
[ Upstream commit c1c1fc8103f794a10c5c15e3c17879caf4f42c8f ]
In some Chrome platforms if OEM's use their own string as SYS_VENDOR than "Google", it leads to firmware load failure from intel/sof/community path.
Hence, changing SYS_VENDOR to PRODUCT_FAMILY in which "Google" is used as common prefix and is supported in all Chrome platforms.
--- sound/soc/sof/sof-pci-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/sof/sof-pci-dev.c +1 -1
@@ -80,7 +80,7 @@ static const struct dmi_system_id community_key_platforms[] = { { .ident = "Google Chromebooks", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Google"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "Google"), } }, {},
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 457/530 drm/amdgpu: fix initial connector audio value
In reply to Greg Kroah-HartmanFrom: hongao <[email protected]>
[ Upstream commit 4bb71fce58f30df3f251118291d6b0187ce531e6 ]
This got lost somewhere along the way, This fixes
audio not working until set_property was called.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +6 -1
@@ -1671,10 +1671,12 @@ amdgpu_connector_add(struct amdgpu_device *adev, adev->mode_info.dither_property, AMDGPU_FMT_DITHER_DISABLE); -if (amdgpu_audio !=0 ) +if (amdgpu_audio !=0 ) {drm_object_attach_property (&amdgpu_connector->base.base, adev->mode_info.audio_property,AMDGPU_AUDIO_AUTO ); + amdgpu_connector->audio =AMDGPU_AUDIO_AUTO ; + } subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = true;
@@ -1796,6 +1798,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,drm_object_attach_property (&amdgpu_connector->base.base, adev->mode_info.audio_property,AMDGPU_AUDIO_AUTO ); + amdgpu_connector->audio =AMDGPU_AUDIO_AUTO ; } drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.dither_property,
@@ -1849,6 +1852,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,drm_object_attach_property (&amdgpu_connector->base.base, adev->mode_info.audio_property,AMDGPU_AUDIO_AUTO ); + amdgpu_connector->audio =AMDGPU_AUDIO_AUTO ; } drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.dither_property,
@@ -1899,6 +1903,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,drm_object_attach_property (&amdgpu_connector->base.base, adev->mode_info.audio_property,AMDGPU_AUDIO_AUTO ); + amdgpu_connector->audio =AMDGPU_AUDIO_AUTO ; } drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.dither_property,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 458/530 drm/meson: reorder driver deinit sequence to fix use-after-free bug
In reply to Greg Kroah-HartmanFrom: Adrián Larumbe <[email protected]>
[ Upstream commit 31c519981eb141c7ec39bfd5be25d35f02edb868 ]
Unloading the driver triggers the following KASAN warning:
[ +0.006275] ============================================================= [ +0.000029] BUG: KASAN: use-after-free in __list_del_entry_valid+0xe0/0x1a0 [ +0.000026] Read of size 8 at addr ffff000020c395e0 by task rmmod/2695
[ +0.000019] CPU: 5 PID: 2695 Comm: rmmod Tainted: G C O 5.19.0-rc6-lrmbkasan+ #1 [ +0.000013] Hardware name: Hardkernel ODROID-N2Plus (DT) [ +0.000008] Call trace: [ +0.000007] dump_backtrace+0x1ec/0x280 [ +0.000013] show_stack+0x24/0x80 [ +0.000008] dump_stack_lvl+0x98/0xd4 [ +0.000011] print_address_description.constprop.0+0x80/0x520 [ +0.000011] print_report+0x128/0x260 [ +0.000007] kasan_report+0xb8/0xfc [ +0.000008] __asan_report_load8_noabort+0x3c/0x50 [ +0.000010] __list_del_entry_valid+0xe0/0x1a0 [ +0.000009] drm_atomic_private_obj_fini+0x30/0x200 [drm] [ +0.000172] drm_bridge_detach+0x94/0x260 [drm] [ +0.000145] drm_encoder_cleanup+0xa4/0x290 [drm] [ +0.000144] drm_mode_config_cleanup+0x118/0x740 [drm] [ +0.000143] drm_mode_config_init_release+0x1c/0x2c [drm] [ +0.000144] drm_managed_release+0x170/0x414 [drm] [ +0.000142] drm_dev_put.part.0+0xc0/0x124 [drm] [ +0.000143] drm_dev_put+0x20/0x30 [drm] [ +0.000142] meson_drv_unbind+0x1d8/0x2ac [meson_drm] [ +0.000028] take_down_aggregate_device+0xb0/0x160 [ +0.000016] component_del+0x18c/0x360 [ +0.000009] meson_dw_hdmi_remove+0x28/0x40 [meson_dw_hdmi] [ +0.000015] platform_remove+0x64/0xb0 [ +0.000009] device_remove+0xb8/0x154 [ +0.000009] device_release_driver_internal+0x398/0x5b0 [ +0.000009] driver_detach+0xac/0x1b0 [ +0.000009] bus_remove_driver+0x158/0x29c [ +0.000009] driver_unregister+0x70/0xb0 [ +0.000008] platform_driver_unregister+0x20/0x2c [ +0.000008] meson_dw_hdmi_platform_driver_exit+0x1c/0x30 [meson_dw_hdmi] [ +0.000012] __do_sys_delete_module+0x288/0x400 [ +0.000011] __arm64_sys_delete_module+0x5c/0x80 [ +0.000009] invoke_syscall+0x74/0x260 [ +0.000009] el0_svc_common.constprop.0+0xcc/0x260 [ +0.000009] do_el0_svc+0x50/0x70 [ +0.000007] el0_svc+0x68/0x1a0 [ +0.000012] el0t_64_sync_handler+0x11c/0x150 [ +0.000008] el0t_64_sync+0x18c/0x190
[ +0.000018] Allocated by task 0:
[ +0.000007] (stack is not available)
[ +0.000011] Freed by task 2695: [ +0.000008] kasan_save_stack+0x2c/0x5c [ +0.000011] kasan_set_track+0x2c/0x40 [ +0.000008] kasan_set_free_info+0x28/0x50 [ +0.000009] ____kasan_slab_free+0x128/0x1d4 [ +0.000008] __kasan_slab_free+0x18/0x24 [ +0.000007] slab_free_freelist_hook+0x108/0x230 [ +0.000011] kfree+0x110/0x35c [ +0.000008] release_nodes+0xf0/0x16c [ +0.000009] devres_release_group+0x180/0x270 [ +0.000008] component_unbind+0x128/0x1e0 [ +0.000010] component_unbind_all+0x1b8/0x264 [ +0.000009] meson_drv_unbind+0x1a0/0x2ac [meson_drm] [ +0.000025] take_down_aggregate_device+0xb0/0x160 [ +0.000009] component_del+0x18c/0x360 [ +0.000009] meson_dw_hdmi_remove+0x28/0x40 [meson_dw_hdmi] [ +0.000012] platform_remove+0x64/0xb0 [ +0.000008] device_remove+0xb8/0x154 [ +0.000009] device_release_driver_internal+0x398/0x5b0 [ +0.000009] driver_detach+0xac/0x1b0 [ +0.000009] bus_remove_driver+0x158/0x29c [ +0.000008] driver_unregister+0x70/0xb0 [ +0.000008] platform_driver_unregister+0x20/0x2c [ +0.000008] meson_dw_hdmi_platform_driver_exit+0x1c/0x30 [meson_dw_hdmi] [ +0.000011] __do_sys_delete_module+0x288/0x400 [ +0.000010] __arm64_sys_delete_module+0x5c/0x80 [ +0.000008] invoke_syscall+0x74/0x260 [ +0.000008] el0_svc_common.constprop.0+0xcc/0x260 [ +0.000008] do_el0_svc+0x50/0x70 [ +0.000007] el0_svc+0x68/0x1a0 [ +0.000009] el0t_64_sync_handler+0x11c/0x150 [ +0.000009] el0t_64_sync+0x18c/0x190
[ +0.000014] The buggy address belongs to the object at ffff000020c39000
which belongs to the cache kmalloc-4k of size 4096
[ +0.000008] The buggy address is located 1504 bytes inside of
4096-byte region [ffff000020c39000, ffff000020c3a000)
[ +0.000016] The buggy address belongs to the physical page: [ +0.000009] page:fffffc0000830e00 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x20c38 [ +0.000013] head:fffffc0000830e00 order:3 compound_mapcount:0 compound_pincount:0 [ +0.000008] flags: 0xffff00000010200(slab|head|node=0|zone=0|lastcpupid=0xffff) [ +0.000019] raw: 0ffff00000010200 fffffc0000fd4808 fffffc0000126208 ffff000000002e80 [ +0.000009] raw: 0000000000000000 0000000000020002 00000001ffffffff 0000000000000000 [ +0.000008] page dumped because: kasan: bad access detected
[ +0.000011] Memory state around the buggy address: [ +0.000008] ffff000020c39480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ +0.000007] ffff000020c39500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ +0.000007] >ffff000020c39580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ +0.000007] ^ [ +0.000007] ffff000020c39600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ +0.000007] ffff000020c39680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ +0.000006] ==================================================================
The reason this is happening is unloading meson-dw-hdmi will cause the component API to take down the aggregate device, which in turn will cause all devres-managed memory to be freed, including the struct dw_hdmi allocated in dw_hdmi_probe. This struct embeds a struct drm_bridge that is added at the end of the function, and which is later on picked up in meson_encoder_hdmi_init.
However, when attaching the bridge to the encoder created in meson_encoder_hdmi_init, it's linked to the encoder's bridge chain, from where it never leaves, even after devres_release_group is called when the driver's components are unbound and the embedding structure freed.
Then, when calling drm_dev_put in the aggregate driver's unbind function, drm_bridge_detach is called for every single bridge linked to the encoder, including the one whose memory had already been deallocated.
Fix by calling component_unbind_all after drm_dev_put.
--- drivers/gpu/drm/meson/meson_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/meson/meson_drv.c +1 -1
@@ -387,9 +387,9 @@ static void meson_drv_unbind(struct device *dev)drm_dev_unregister (drm);drm_kms_helper_poll_fini (drm);drm_atomic_helper_shutdown (drm); -component_unbind_all (dev, drm);free_irq (priv->vsync_irq, drm);drm_dev_put (drm); +component_unbind_all (dev, drm);if (priv->afbcd.ops) priv->afbcd.ops->exit (priv);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 459/530 drm/meson: explicitly remove aggregate driver at module unload time
In reply to Greg Kroah-HartmanFrom: Adrián Larumbe <[email protected]>
[ Upstream commit 8616f2a0589a80e08434212324250eb22f6a66ce ]
Because component_master_del wasn't being called when unloading the meson_drm module, the aggregate device would linger forever in the global aggregate_devices list. That means when unloading and reloading the meson_dw_hdmi module, component_add would call into try_to_bring_up_aggregate_device and find the unbound meson_drm aggregate device.
This would in turn dereference some of the aggregate_device's struct entries which point to memory automatically freed by the devres API when unbinding the aggregate device from meson_drv_unbind, and trigger an use-after-free bug:
[ +0.000014] ============================================================= [ +0.000007] BUG: KASAN: use-after-free in find_components+0x468/0x500 [ +0.000017] Read of size 8 at addr ffff000006731688 by task modprobe/2536 [ +0.000018] CPU: 4 PID: 2536 Comm: modprobe Tainted: G C O 5.19.0-rc6-lrmbkasan+ #1 [ +0.000010] Hardware name: Hardkernel ODROID-N2Plus (DT) [ +0.000008] Call trace: [ +0.000005] dump_backtrace+0x1ec/0x280 [ +0.000011] show_stack+0x24/0x80 [ +0.000007] dump_stack_lvl+0x98/0xd4 [ +0.000010] print_address_description.constprop.0+0x80/0x520 [ +0.000011] print_report+0x128/0x260 [ +0.000007] kasan_report+0xb8/0xfc [ +0.000007] __asan_report_load8_noabort+0x3c/0x50 [ +0.000009] find_components+0x468/0x500 [ +0.000008] try_to_bring_up_aggregate_device+0x64/0x390 [ +0.000009] __component_add+0x1dc/0x49c [ +0.000009] component_add+0x20/0x30 [ +0.000008] meson_dw_hdmi_probe+0x28/0x34 [meson_dw_hdmi] [ +0.000013] platform_probe+0xd0/0x220 [ +0.000008] really_probe+0x3ac/0xa80 [ +0.000008] __driver_probe_device+0x1f8/0x400 [ +0.000008] driver_probe_device+0x68/0x1b0 [ +0.000008] __driver_attach+0x20c/0x480 [ +0.000009] bus_for_each_dev+0x114/0x1b0 [ +0.000007] driver_attach+0x48/0x64 [ +0.000009] bus_add_driver+0x390/0x564 [ +0.000007] driver_register+0x1a8/0x3e4 [ +0.000009] __platform_driver_register+0x6c/0x94 [ +0.000007] meson_dw_hdmi_platform_driver_init+0x30/0x1000 [meson_dw_hdmi] [ +0.000014] do_one_initcall+0xc4/0x2b0 [ +0.000008] do_init_module+0x154/0x570 [ +0.000010] load_module+0x1a78/0x1ea4 [ +0.000008] __do_sys_init_module+0x184/0x1cc [ +0.000008] __arm64_sys_init_module+0x78/0xb0 [ +0.000008] invoke_syscall+0x74/0x260 [ +0.000008] el0_svc_common.constprop.0+0xcc/0x260 [ +0.000009] do_el0_svc+0x50/0x70 [ +0.000008] el0_svc+0x68/0x1a0 [ +0.000009] el0t_64_sync_handler+0x11c/0x150 [ +0.000009] el0t_64_sync+0x18c/0x190
[ +0.000014] Allocated by task 902: [ +0.000007] kasan_save_stack+0x2c/0x5c [ +0.000009] __kasan_kmalloc+0x90/0xd0 [ +0.000007] __kmalloc_node+0x240/0x580 [ +0.000010] memcg_alloc_slab_cgroups+0xa4/0x1ac [ +0.000010] memcg_slab_post_alloc_hook+0xbc/0x4c0 [ +0.000008] kmem_cache_alloc_node+0x1d0/0x490 [ +0.000009] __alloc_skb+0x1d4/0x310 [ +0.000010] alloc_skb_with_frags+0x8c/0x620 [ +0.000008] sock_alloc_send_pskb+0x5ac/0x6d0 [ +0.000010] unix_dgram_sendmsg+0x2e0/0x12f0 [ +0.000010] sock_sendmsg+0xcc/0x110 [ +0.000007] sock_write_iter+0x1d0/0x304 [ +0.000008] new_sync_write+0x364/0x460 [ +0.000007] vfs_write+0x420/0x5ac [ +0.000008] ksys_write+0x19c/0x1f0 [ +0.000008] __arm64_sys_write+0x78/0xb0 [ +0.000007] invoke_syscall+0x74/0x260 [ +0.000008] el0_svc_common.constprop.0+0x1a8/0x260 [ +0.000009] do_el0_svc+0x50/0x70 [ +0.000007] el0_svc+0x68/0x1a0 [ +0.000008] el0t_64_sync_handler+0x11c/0x150 [ +0.000008] el0t_64_sync+0x18c/0x190
[ +0.000013] Freed by task 2509: [ +0.000008] kasan_save_stack+0x2c/0x5c [ +0.000007] kasan_set_track+0x2c/0x40 [ +0.000008] kasan_set_free_info+0x28/0x50 [ +0.000008] ____kasan_slab_free+0x128/0x1d4 [ +0.000008] __kasan_slab_free+0x18/0x24 [ +0.000007] slab_free_freelist_hook+0x108/0x230 [ +0.000010] kfree+0x110/0x35c [ +0.000008] release_nodes+0xf0/0x16c [ +0.000008] devres_release_all+0xfc/0x180 [ +0.000008] device_unbind_cleanup+0x24/0x164 [ +0.000008] device_release_driver_internal+0x3e8/0x5b0 [ +0.000010] driver_detach+0xac/0x1b0 [ +0.000008] bus_remove_driver+0x158/0x29c [ +0.000008] driver_unregister+0x70/0xb0 [ +0.000009] platform_driver_unregister+0x20/0x2c [ +0.000007] 0xffff800003722d98 [ +0.000012] __do_sys_delete_module+0x288/0x400 [ +0.000009] __arm64_sys_delete_module+0x5c/0x80 [ +0.000008] invoke_syscall+0x74/0x260 [ +0.000008] el0_svc_common.constprop.0+0xcc/0x260 [ +0.000008] do_el0_svc+0x50/0x70 [ +0.000007] el0_svc+0x68/0x1a0 [ +0.000008] el0t_64_sync_handler+0x11c/0x150 [ +0.000009] el0t_64_sync+0x18c/0x190
[ +0.000013] Last potentially related work creation: [ +0.000007] kasan_save_stack+0x2c/0x5c [ +0.000007] __kasan_record_aux_stack+0xb8/0xf0 [ +0.000009] kasan_record_aux_stack_noalloc+0x14/0x20 [ +0.000008] insert_work+0x54/0x290 [ +0.000009] __queue_work+0x48c/0xd24 [ +0.000008] queue_work_on+0x90/0x11c [ +0.000008] call_usermodehelper_exec+0x188/0x404 [ +0.000010] kobject_uevent_env+0x5a8/0x794 [ +0.000010] kobject_uevent+0x14/0x20 [ +0.000008] driver_register+0x230/0x3e4 [ +0.000009] __platform_driver_register+0x6c/0x94 [ +0.000007] gxbb_driver_init+0x28/0x34 [ +0.000010] do_one_initcall+0xc4/0x2b0 [ +0.000008] do_initcalls+0x20c/0x24c [ +0.000010] kernel_init_freeable+0x22c/0x278 [ +0.000009] kernel_init+0x3c/0x170 [ +0.000008] ret_from_fork+0x10/0x20
[ +0.000013] The buggy address belongs to the object at ffff000006731600
which belongs to the cache kmalloc-256 of size 256
[ +0.000009] The buggy address is located 136 bytes inside of
256-byte region [ffff000006731600, ffff000006731700)
[ +0.000015] The buggy address belongs to the physical page: [ +0.000008] page:fffffc000019cc00 refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff000006730a00 pfn:0x6730 [ +0.000011] head:fffffc000019cc00 order:2 compound_mapcount:0 compound_pincount:0 [ +0.000008] flags: 0xffff00000010200(slab|head|node=0|zone=0|lastcpupid=0xffff) [ +0.000016] raw: 0ffff00000010200 fffffc00000c3d08 fffffc0000ef2b08 ffff000000002680 [ +0.000009] raw: ffff000006730a00 0000000000150014 00000001ffffffff 0000000000000000 [ +0.000006] page dumped because: kasan: bad access detected
[ +0.000011] Memory state around the buggy address: [ +0.000007] ffff000006731580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ +0.000007] ffff000006731600: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ +0.000007] >ffff000006731680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ +0.000007] ^ [ +0.000006] ffff000006731700: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ +0.000007] ffff000006731780: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ +0.000006] ==================================================================
Fix by adding 'remove' driver callback for meson-drm, and explicitly deleting the aggregate device.
--- drivers/gpu/drm/meson/meson_drv.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/gpu/drm/meson/meson_drv.c +8 -0
@@ -520,6 +520,13 @@ static int meson_drv_probe(struct platform_device *pdev)return 0 ; }; +static int meson_drv_remove (struct platform_device *pdev) +{ +component_master_del (&pdev->dev, &meson_drv_master_ops); + +return 0 ; +} +static struct meson_drm_match_data meson_drm_gxbb_data = { .compat =VPU_COMPATIBLE_GXBB , };
@@ -557,6 +564,7 @@ static const struct dev_pm_ops meson_drv_pm_ops = {static struct platform_driver meson_drm_platform_driver = { .probe = meson_drv_probe, + .remove = meson_drv_remove, .shutdown = meson_drv_shutdown, .driver = { .name ="meson-drm" ,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 460/530 mmc: sdhci-msm: add compatible string check for sdm670
In reply to Greg Kroah-HartmanFrom: Richard Acayan <[email protected]>
[ Upstream commit 4de95950d970c71a9e82a24573bb7a44fd95baa1 ]
The Snapdragon 670 has the same quirk as Snapdragon 845 (needing to restore the dll config). Add a compatible string check to detect the need for this.
--- drivers/mmc/host/sdhci-msm.c | 1 + 1 file changed, 1 insertion(+)
drivers/mmc/host/sdhci-msm.c +1 -0
@@ -2437,6 +2437,7 @@ static const struct sdhci_msm_variant_info sdm845_sdhci_var = {static const struct of_device_id sdhci_msm_dt_match[] = { {.compatible ="qcom,sdhci-msm-v4" , .data = &sdhci_msm_mci_var}, {.compatible ="qcom,sdhci-msm-v5" , .data = &sdhci_msm_v5_var}, + {.compatible ="qcom,sdm670-sdhci" , .data = &sdm845_sdhci_var}, {.compatible ="qcom,sdm845-sdhci" , .data = &sdm845_sdhci_var}, {.compatible ="qcom,sc7180-sdhci" , .data = &sdm845_sdhci_var}, {},
Signature · 1 line
2.35.1
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.75 release. There are 530 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 26 Oct 2022 11:29:24 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.75-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Greg Kroah-Hartman
maintainerPATCH 461/530 drm/dp: Dont rewrite link config when setting phy test pattern
In reply to Greg Kroah-HartmanFrom: Khaled Almahallawy <[email protected]>
[ Upstream commit 7b4d8db657192066bc6f1f6635d348413dac1e18 ]
The sequence for Source DP PHY CTS automation is [2][1]:
1- Emulate successful Link Training(LT)
2- Short HPD and change link rates and number of lanes by LT. (This is same flow for Link Layer CTS)
3- Short HPD and change PHY test pattern and swing/pre-emphasis levels (This step should not trigger LT)
The problem is with DP PHY compliance setup as follow:
[DPTX + on board LTTPR]------Main Link--->[Scope]
^ |
| |
| |
----------Aux Ch------>[Aux Emulator]At step 3, before writing TRAINING_LANEx_SET/LINK_QUAL_PATTERN_SET to declare the pattern/swing requested by scope, we write link config in LINK_BW_SET/LANE_COUNT_SET on a port that has LTTPR. As LTTPR snoops aux transaction, LINK_BW_SET/LANE_COUNT_SET writes indicate a LT will start [Check DP 2.0 E11 -Sec 3.6.8.2 & 3.6.8.6.3], and LTTPR will reset the link and stop sending DP signals to DPTX/Scope causing the measurements to fail. Note that step 3 will not trigger LT and DP link will never recovered by the
Aux Emulator/Scope.
The reset of link can be tested with a monitor connected to LTTPR port simply by writing to LINK_BW_SET or LANE_COUNT_SET as follow
igt/tools/dpcd_reg write --offset=0x100 --value 0x14 --device=2
OR
printf '\x14' | sudo dd of=/dev/drm_dp_aux2 bs=1 count=1 conv=notrunc seek=$((0x100))
This single aux write causes the screen to blank, sending short HPD to DPTX, setting LINK_STATUS_UPDATE = 1 in DPCD 0x204, and triggering LT.
As stated in [1]:
"Before any TX electrical testing can be performed, the link between a DPTX and DPRX (in this case, a piece of test equipment), including all LTTPRs within the path, shall be trained as defined in this Standard."
In addition, changing Phy pattern/Swing/Pre-emphasis (Step 3) uses the same link rate and lane count applied on step 2, so no need to redo LT.
The fix is to not rewrite link config in step 3, and just writes TRAINING_LANEx_SET and LINK_QUAL_PATTERN_SET
[1]: DP 2.0 E11 - 3.6.11.1 LTTPR DPTX_PHY Electrical Compliance
[2]: Configuring UnigrafDPTC Controller - Automation Test Sequence
https://www.keysight.com/us/en/assets/9922-01244/help-files/
D9040DPPC-DisplayPort-Test-Software-Online-Help-latest.chm
--- drivers/gpu/drm/drm_dp_helper.c | 9 --------- 1 file changed, 9 deletions(-)
drivers/gpu/drm/drm_dp_helper.c +0 -9
@@ -2376,17 +2376,8 @@ int drm_dp_set_phy_test_pattern(struct drm_dp_aux *aux, struct drm_dp_phy_test_params *data, u8 dp_rev) { int err, i; -u8 link_config[2 ];u8 test_pattern; - link_config[0 ] =drm_dp_link_rate_to_bw_code (data->link_rate); - link_config[1 ] = data->num_lanes; -if (data->enhanced_frame_cap) - link_config[1 ] |=DP_LANE_COUNT_ENHANCED_FRAME_EN ; - err =drm_dp_dpcd_write (aux,DP_LINK_BW_SET , link_config,2 ); -if (err <0 ) -return err; - test_pattern = data->phy_pattern;if (dp_rev <0x12 ) { test_pattern = (test_pattern << 2) &
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 462/530 drm/amd/display: Remove interface for periodic interrupt 1
In reply to Greg Kroah-HartmanFrom: Aric Cyr <[email protected]>
[ Upstream commit 97d8d6f075bd8f988589be02b91f6fa644d0b0b8 ]
[why]
Only a single VLINE interrupt is available so interface should not expose the second one which is used by DMU firmware.
[how]
Remove references to periodic_interrupt1 and VLINE1 from DC interfaces.
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 16 +++------ drivers/gpu/drm/amd/display/dc/dc_stream.h | 6 ++-- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 35 ++++++------------- .../amd/display/dc/dcn10/dcn10_hw_sequencer.h | 3 +- .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 8 +---- 5 files changed, 18 insertions(+), 50 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +4 -12
@@ -2462,11 +2462,8 @@ static void copy_stream_update_to_stream(struct dc *dc,if (update->abm_level) stream->abm_level = *update->abm_level; -if (update->periodic_interrupt0) - stream->periodic_interrupt0 = *update->periodic_interrupt0; - -if (update->periodic_interrupt1) - stream->periodic_interrupt1 = *update->periodic_interrupt1; +if (update->periodic_interrupt) + stream->periodic_interrupt = *update->periodic_interrupt;if (update->gamut_remap) stream->gamut_remap_matrix = *update->gamut_remap;
@@ -2550,13 +2547,8 @@ static void commit_planes_do_stream_update(struct dc *dc,if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe && pipe_ctx->stream == stream) { -if (stream_update->periodic_interrupt0 && - dc->hwss.setup_periodic_interrupt) - dc->hwss.setup_periodic_interrupt (dc, pipe_ctx,VLINE0 ); - -if (stream_update->periodic_interrupt1 && - dc->hwss.setup_periodic_interrupt) - dc->hwss.setup_periodic_interrupt (dc, pipe_ctx,VLINE1 ); +if (stream_update->periodic_interrupt && dc->hwss.setup_periodic_interrupt) + dc->hwss.setup_periodic_interrupt (dc, pipe_ctx); if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) || stream_update->vrr_infopacket ||
drivers/gpu/drm/amd/display/dc/dc_stream.h +2 -4
@@ -193,8 +193,7 @@ struct dc_stream_state {/* DMCU info */ unsigned int abm_level; -struct periodic_interrupt_config periodic_interrupt0; -struct periodic_interrupt_config periodic_interrupt1; +struct periodic_interrupt_config periodic_interrupt;/* from core_stream struct */ struct dc_context *ctx;
@@ -260,8 +259,7 @@ struct dc_stream_update {struct dc_info_packet *hdr_static_metadata;unsigned int *abm_level; -struct periodic_interrupt_config *periodic_interrupt0; -struct periodic_interrupt_config *periodic_interrupt1; +struct periodic_interrupt_config *periodic_interrupt;struct dc_info_packet *vrr_infopacket;struct dc_info_packet *vsc_infopacket;
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +10 -25
@@ -3517,7 +3517,7 @@ void dcn10_calc_vupdate_position( {const struct dc_crtc_timing *dc_crtc_timing = &pipe_ctx->stream->timing;int vline_int_offset_from_vupdate = - pipe_ctx->stream->periodic_interrupt0.lines_offset; + pipe_ctx->stream->periodic_interrupt.lines_offset;int vupdate_offset_from_vsync = dc->hwss.get_vupdate_offset_from_vsync (pipe_ctx);int start_position;
@@ -3542,18 +3542,10 @@ void dcn10_calc_vupdate_position(static void dcn10_cal_vline_position (struct dc *dc,struct pipe_ctx *pipe_ctx, -enum vline_select vline,uint32_t *start_line,uint32_t *end_line) { -enum vertical_interrupt_ref_point ref_point =INVALID_POINT ; - -if (vline ==VLINE0 ) - ref_point = pipe_ctx->stream->periodic_interrupt0.ref_point; -else if (vline ==VLINE1 ) - ref_point = pipe_ctx->stream->periodic_interrupt1.ref_point; - -switch (ref_point) { +switch (pipe_ctx->stream->periodic_interrupt.ref_point) {case START_V_UPDATE : dcn10_calc_vupdate_position( dc,
@@ -3562,7 +3554,9 @@ static void dcn10_cal_vline_position( end_line);break ;case START_V_SYNC : -// Suppose to do nothing because vsync is 0; +// vsync is line 0 so start_line is just the requested line offset + *start_line = pipe_ctx->stream->periodic_interrupt.lines_offset; + *end_line = *start_line +2 ;break ;default :ASSERT (0 );
@@ -3572,24 +3566,15 @@ static void dcn10_cal_vline_position(void dcn10_setup_periodic_interrupt (struct dc *dc, -struct pipe_ctx *pipe_ctx, -enum vline_select vline) +struct pipe_ctx *pipe_ctx) {struct timing_generator *tg = pipe_ctx->stream_res.tg; +uint32_t start_line =0 ; +uint32_t end_line =0 ; -if (vline ==VLINE0 ) { -uint32_t start_line =0 ; -uint32_t end_line =0 ; +dcn10_cal_vline_position (dc, pipe_ctx, &start_line, &end_line); -dcn10_cal_vline_position (dc, pipe_ctx, vline, &start_line, &end_line); - - tg->funcs->setup_vertical_interrupt0 (tg, start_line, end_line); - - }else if (vline ==VLINE1 ) { - pipe_ctx->stream_res.tg->funcs->setup_vertical_interrupt1 ( - tg, - pipe_ctx->stream->periodic_interrupt1.lines_offset); - } + tg->funcs->setup_vertical_interrupt0 (tg, start_line, end_line); }void dcn10_setup_vupdate_interrupt (struct dc *dc,struct pipe_ctx *pipe_ctx)
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +1 -2
@@ -175,8 +175,7 @@ void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx);void dcn10_set_cursor_sdr_white_level (struct pipe_ctx *pipe_ctx);void dcn10_setup_periodic_interrupt (struct dc *dc, -struct pipe_ctx *pipe_ctx, -enum vline_select vline); +struct pipe_ctx *pipe_ctx); enum dc_status dcn10_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz,
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +1 -7
@@ -32,11 +32,6 @@#include "inc/hw/link_encoder.h" #include "core_status.h" -enum vline_select { -VLINE0 , -VLINE1 -}; -struct pipe_ctx ;struct dc_state ;struct dc_stream_status ;
@@ -115,8 +110,7 @@ struct hw_sequencer_funcs { int group_index, int group_size, struct pipe_ctx *grouped_pipes[]);void (*setup_periodic_interrupt)(struct dc *dc, -struct pipe_ctx *pipe_ctx, -enum vline_select vline); +struct pipe_ctx *pipe_ctx);void (*set_drr)(struct pipe_ctx **pipe_ctx,int num_pipes,struct dc_crtc_timing_adjust adjust); void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 463/530 ARM: dts: imx7d-sdb: config the max pressure for tsc2046
In reply to Greg Kroah-HartmanFrom: Haibo Chen <[email protected]>
[ Upstream commit e7c4ebe2f9cd68588eb24ba4ed122e696e2d5272 ]
Use the general touchscreen method to config the max pressure for touch tsc2046(data sheet suggest 8 bit pressure), otherwise, for ABS_PRESSURE, when config the same max and min value, weston will meet the following issue,
[17:19:39.183] event1 - ADS7846 Touchscreen: is tagged by udev as: Touchscreen [17:19:39.183] event1 - ADS7846 Touchscreen: kernel bug: device has min == max on ABS_PRESSURE [17:19:39.183] event1 - ADS7846 Touchscreen: was rejected [17:19:39.183] event1 - not using input device '/dev/input/event1'
This will then cause the APP weston-touch-calibrator can't list touch devices.
root@imx6ul7d:~# weston-touch-calibrator could not load cursor 'dnd-move' could not load cursor 'dnd-copy' could not load cursor 'dnd-none' No devices listed.
And accroding to binding Doc, "ti,x-max", "ti,y-max", "ti,pressure-max" belong to the deprecated properties, so remove them. Also for "ti,x-min", "ti,y-min", "ti,x-plate-ohms", the value set in dts equal to the default value in driver, so are redundant, also remove here.
--- arch/arm/boot/dts/imx7d-sdb.dts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
arch/arm/boot/dts/imx7d-sdb.dts +1 -6
@@ -206,12 +206,7 @@ interrupt-parent = <&gpio2>; interrupts = <29 0>; pendown-gpio = <&gpio2 29 GPIO_ACTIVE_HIGH>; - ti,x-min = /bits/ 16 <0>; - ti,x-max = /bits/ 16 <0>; - ti,y-min = /bits/ 16 <0>; - ti,y-max = /bits/ 16 <0>; - ti,pressure-max = /bits/ 16 <0>; - ti,x-plate-ohms = /bits/ 16 <400>; + touchscreen-max-pressure = <255>; wakeup-source; }; };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 464/530 ARM: dts: imx6q: add missing properties for sram
In reply to Greg Kroah-HartmanFrom: Alexander Stein <[email protected]>
[ Upstream commit b11d083c5dcec7c42fe982c854706d404ddd3a5f ]
All 3 properties are required by sram.yaml. Fixes the dtbs_check warning:
sram@900000: '#address-cells' is a required property sram@900000: '#size-cells' is a required property sram@900000: 'ranges' is a required property
--- arch/arm/boot/dts/imx6q.dtsi | 3 +++ 1 file changed, 3 insertions(+)
arch/arm/boot/dts/imx6q.dtsi +3 -0
@@ -163,6 +163,9 @@ ocram: sram@900000 { compatible = "mmio-sram"; reg = <0x00900000 0x40000>; + ranges = <0 0x00900000 0x40000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6QDL_CLK_OCRAM>; };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 465/530 ARM: dts: imx6dl: add missing properties for sram
In reply to Greg Kroah-HartmanFrom: Alexander Stein <[email protected]>
[ Upstream commit f5848b95633d598bacf0500e0108dc5961af88c0 ]
All 3 properties are required by sram.yaml. Fixes the dtbs_check warning:
sram@900000: '#address-cells' is a required property sram@900000: '#size-cells' is a required property sram@900000: 'ranges' is a required property
--- arch/arm/boot/dts/imx6dl.dtsi | 3 +++ 1 file changed, 3 insertions(+)
arch/arm/boot/dts/imx6dl.dtsi +3 -0
@@ -84,6 +84,9 @@ ocram: sram@900000 { compatible = "mmio-sram"; reg = <0x00900000 0x20000>; + ranges = <0 0x00900000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6QDL_CLK_OCRAM>; };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 466/530 ARM: dts: imx6qp: add missing properties for sram
In reply to Greg Kroah-HartmanFrom: Alexander Stein <[email protected]>
[ Upstream commit 088fe5237435ee2f7ed4450519b2ef58b94c832f ]
All 3 properties are required by sram.yaml. Fixes the dtbs_check warning:
sram@940000: '#address-cells' is a required property sram@940000: '#size-cells' is a required property sram@940000: 'ranges' is a required property
--- arch/arm/boot/dts/imx6qp.dtsi | 6 ++++++ 1 file changed, 6 insertions(+)
arch/arm/boot/dts/imx6qp.dtsi +6 -0
@@ -9,12 +9,18 @@ ocram2: sram@940000 { compatible = "mmio-sram"; reg = <0x00940000 0x20000>; + ranges = <0 0x00940000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6QDL_CLK_OCRAM>; }; ocram3: sram@960000 { compatible = "mmio-sram"; reg = <0x00960000 0x20000>; + ranges = <0 0x00960000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6QDL_CLK_OCRAM>; };
Signature · 1 line
2.35.1