5.4.282-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainerPATCH 160/259 PCI: rockchip: Use GPIOD_OUT_LOW flag while requesting ep_gpio
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manivannan Sadhasivam <[email protected]>
[ Upstream commit 840b7a5edf88fe678c60dee88a135647c0ea4375 ]
Rockchip platforms use 'GPIO_ACTIVE_HIGH' flag in the devicetree definition for ep_gpio. This means, whatever the logical value set by the driver for the ep_gpio, physical line will output the same logic level.
For instance,
gpiod_set_value_cansleep(rockchip->ep_gpio, 0); --> Level low gpiod_set_value_cansleep(rockchip->ep_gpio, 1); --> Level high
But while requesting the ep_gpio, GPIOD_OUT_HIGH flag is currently used. Now, this also causes the physical line to output 'high' creating trouble for endpoint devices during host reboot.
When host reboot happens, the ep_gpio will initially output 'low' due to the GPIO getting reset to its POR value. Then during host controller probe, it will output 'high' due to GPIOD_OUT_HIGH flag. Then during rockchip_pcie_host_init_port(), it will first output 'low' and then 'high' indicating the completion of controller initialization.
On the endpoint side, each output 'low' of ep_gpio is accounted for PERST# assert and 'high' for PERST# deassert. With the above mentioned flow during host reboot, endpoint will witness below state changes for PERST#:
(1) PERST# assert - GPIO POR state
(2) PERST# deassert - GPIOD_OUT_HIGH while requesting GPIO
(3) PERST# assert - rockchip_pcie_host_init_port()
(4) PERST# deassert - rockchip_pcie_host_init_port()
Now the time interval between (2) and (3) is very short as both happen during the driver probe(), and this results in a race in the endpoint. Because, before completing the PERST# deassertion in (2), endpoint got another PERST# assert in (3).
A proper way to fix this issue is to change the GPIOD_OUT_HIGH flag in (2) to GPIOD_OUT_LOW. Because the usual convention is to request the GPIO with a state corresponding to its 'initial/default' value and let the driver change the state of the GPIO when required.
As per that, the ep_gpio should be requested with GPIOD_OUT_LOW as it corresponds to the POR value of '0' (PERST# assert in the endpoint). Then the driver can change the state of the ep_gpio later in rockchip_pcie_host_init_port() as per the initialization sequence.
This fixes the firmware crash issue in Qcom based modems connected to Rockpro64 based board.
--- drivers/pci/controller/pcie-rockchip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/controller/pcie-rockchip.c +1 -1
@@ -121,7 +121,7 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)if (rockchip->is_rc) { rockchip->ep_gpio =devm_gpiod_get_optional (dev,"ep" , -GPIOD_OUT_HIGH ); +GPIOD_OUT_LOW );if (IS_ERR (rockchip->ep_gpio))return dev_err_probe (dev,PTR_ERR (rockchip->ep_gpio),"failed to get ep GPIO\n" );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 161/259 parport: Convert printk(KERN_<LEVEL> to pr_<level>(
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Perches <[email protected]>
[ Upstream commit decf26f6ec25dac868782dc1751623a87d147831 ]
Use the more common kernel style.
Miscellanea:
o Coalesce formats
o Realign arguments
Stable-dep-of: ab11dac93d2d ("dev/parport: fix the array out-of-bounds risk")
--- drivers/parport/daisy.c | 6 +- drivers/parport/ieee1284.c | 4 +- drivers/parport/ieee1284_ops.c | 3 +- drivers/parport/parport_amiga.c | 2 +- drivers/parport/parport_atari.c | 2 +- drivers/parport/parport_cs.c | 6 +- drivers/parport/parport_gsc.c | 7 +- drivers/parport/parport_ip32.c | 25 ++--- drivers/parport/parport_mfc3.c | 2 +- drivers/parport/parport_pc.c | 166 +++++++++++++------------------ drivers/parport/parport_sunbpp.c | 2 +- drivers/parport/probe.c | 7 +- drivers/parport/share.c | 24 ++--- 13 files changed, 110 insertions(+), 146 deletions(-)
drivers/parport/daisy.c +2 -4
@@ -109,8 +109,7 @@ int parport_daisy_init(struct parport *port) ((num_ports = num_mux_ports(port)) == 2 || num_ports == 4)) {/* Leave original as port zero. */ port->muxport =0 ; -printk (KERN_INFO -"%s: 1st (default) port of %d-way multiplexor\n" , +pr_info ("%s: 1st (default) port of %d-way multiplexor\n" , port->name, num_ports);for (i =1 ; i < num_ports; i++) {/* Clone the port. */
@@ -123,8 +122,7 @@ int parport_daisy_init(struct parport *port)continue ; } -printk (KERN_INFO -"%s: %d%s port of %d-way multiplexor on %s\n" , +pr_info ("%s: %d%s port of %d-way multiplexor on %s\n" , extra->name, i +1 , th[i +1 ], num_ports, port->name);
drivers/parport/ieee1284.c +2 -2
@@ -329,7 +329,7 @@ int parport_negotiate (struct parport *port, int mode)#ifndef CONFIG_PARPORT_1284 if (mode ==IEEE1284_MODE_COMPAT )return 0 ; -printk (KERN_ERR "parport: IEEE1284 not supported in this kernel\n" ); +pr_err ("parport: IEEE1284 not supported in this kernel\n" );return -1 ;#else int m = mode & ~IEEE1284_ADDR ;
@@ -694,7 +694,7 @@ ssize_t parport_write (struct parport *port, const void *buffer, size_t len)ssize_t parport_read (struct parport *port,void *buffer,size_t len) {#ifndef CONFIG_PARPORT_1284 -printk (KERN_ERR "parport: IEEE1284 not supported in this kernel\n" ); +pr_err ("parport: IEEE1284 not supported in this kernel\n" );return -ENODEV ;#else int mode = port->physport->ieee1284.mode;
drivers/parport/ieee1284_ops.c +1 -2
@@ -599,8 +599,7 @@ size_t parport_ieee1284_ecp_read_data (struct parport *port,DPRINTK (KERN_DEBUG "ECP read timed out at 45\n" );if (command) -printk (KERN_WARNING -"%s: command ignored (%02x)\n" , +pr_warn ("%s: command ignored (%02x)\n" , port->name, byte);break ;
drivers/parport/parport_amiga.c +1 -1
@@ -212,7 +212,7 @@ static int __init amiga_parallel_probe(struct platform_device *pdev)if (err) goto out_irq; -printk (KERN_INFO "%s: Amiga built-in port using irq\n" , p->name); +pr_info ("%s: Amiga built-in port using irq\n" , p->name);/* XXX: set operating mode */ parport_announce_port (p);
drivers/parport/parport_atari.c +1 -1
@@ -200,7 +200,7 @@ static int __init parport_atari_init(void) } this_port = p; -printk (KERN_INFO "%s: Atari built-in port using irq\n" , p->name); +pr_info ("%s: Atari built-in port using irq\n" , p->name);parport_announce_port (p);return 0 ;
drivers/parport/parport_cs.c +2 -4
@@ -142,10 +142,8 @@ static int parport_config(struct pcmcia_device *link) link->irq,PARPORT_DMA_NONE , &link->dev, IRQF_SHARED);if (p ==NULL ) { -printk (KERN_NOTICE "parport_cs: parport_pc_probe_port() at " -"0x%3x, irq %u failed\n" , - (unsigned int ) link->resource[0 ]->start, - link->irq); +pr_notice ("parport_cs: parport_pc_probe_port() at 0x%3x, irq %u failed\n" , + (unsigned int )link->resource[0 ]->start, link->irq); goto failed; }
drivers/parport/parport_gsc.c +3 -4
@@ -282,7 +282,7 @@ struct parport *parport_gsc_probe_port(unsigned long base, p->size = (p->modes &PARPORT_MODE_EPP )?8 :3 ; p->private_data = priv; -printk (KERN_INFO "%s: PC-style at 0x%lx" , p->name, p->base); +pr_info ("%s: PC-style at 0x%lx" , p->name, p->base); p->irq = irq;if (p->irq ==PARPORT_IRQ_AUTO ) { p->irq =PARPORT_IRQ_NONE ;
@@ -315,8 +315,7 @@ struct parport *parport_gsc_probe_port(unsigned long base,if (p->irq !=PARPORT_IRQ_NONE ) {if (request_irq (p->irq, parport_irq_handler,0 , p->name, p)) { -printk (KERN_WARNING "%s: irq %d in use, " -"resorting to polled operation\n" , +pr_warn ("%s: irq %d in use, resorting to polled operation\n" , p->name, p->irq); p->irq =PARPORT_IRQ_NONE ; p->dma =PARPORT_DMA_NONE ;
@@ -347,7 +346,7 @@ static int __init parport_init_chip(struct parisc_device *dev)unsigned long port;if (!dev->irq) { -printk (KERN_WARNING "IRQ not found for parallel device at 0x%llx\n" , +pr_warn ("IRQ not found for parallel device at 0x%llx\n" , (unsigned long long )dev->hpa.start);return -ENODEV ; }
drivers/parport/parport_ip32.c +10 -15
@@ -1337,9 +1337,8 @@ static unsigned int parport_ip32_fwp_wait_interrupt(struct parport *p) ecr =parport_ip32_read_econtrol (p);if ((ecr &ECR_F_EMPTY ) && !(ecr &ECR_SERVINTR ) && !lost_interrupt) { - printk(KERN_WARNING PPIP32 -"%s: lost interrupt in %s\n" , - p->name, __func__); +pr_warn (PPIP32 "%s: lost interrupt in %s\n" , + p->name, __func__); lost_interrupt =1 ; } }
@@ -1643,8 +1642,8 @@ static size_t parport_ip32_compat_write_data(struct parport *p, DSR_nBUSY | DSR_nFAULT)) {/* Avoid to flood the logs */ if (ready_before) - printk(KERN_INFO PPIP32 "%s: not ready in %s\n", - p->name, __func__); +pr_info (PPIP32 "%s: not ready in %s\n" , + p->name, __func__); ready_before =0 ; goto stop; }
@@ -1724,8 +1723,8 @@ static size_t parport_ip32_ecp_write_data(struct parport *p, DSR_nBUSY | DSR_nFAULT)) {/* Avoid to flood the logs */ if (ready_before) - printk(KERN_INFO PPIP32 "%s: not ready in %s\n", - p->name, __func__); +pr_info (PPIP32 "%s: not ready in %s\n" , + p->name, __func__); ready_before =0 ; goto stop; }
@@ -2064,8 +2063,7 @@ static __init struct parport *parport_ip32_probe_port(void) p->modes |=PARPORT_MODE_TRISTATE ;if (!parport_ip32_fifo_supported (p)) { - printk(KERN_WARNING PPIP32 - "%s: error: FIFO disabled\n", p->name); +pr_warn (PPIP32 "%s: error: FIFO disabled\n" , p->name);/* Disable hardware modes depending on a working FIFO. */ features &= ~PARPORT_IP32_ENABLE_SPP ; features &= ~PARPORT_IP32_ENABLE_ECP ;
@@ -2077,8 +2075,7 @@ static __init struct parport *parport_ip32_probe_port(void)if (features &PARPORT_IP32_ENABLE_IRQ ) {int irq =MACEISA_PARALLEL_IRQ ;if (request_irq (irq, parport_ip32_interrupt,0 , p->name, p)) { - printk(KERN_WARNING PPIP32 - "%s: error: IRQ disabled\n", p->name); +pr_warn (PPIP32 "%s: error: IRQ disabled\n" , p->name);/* DMA cannot work without interrupts. */ features &= ~PARPORT_IP32_ENABLE_DMA ; }else {
@@ -2091,8 +2088,7 @@ static __init struct parport *parport_ip32_probe_port(void)/* Allocate DMA resources */ if (features &PARPORT_IP32_ENABLE_DMA ) {if (parport_ip32_dma_register ()) - printk(KERN_WARNING PPIP32 -"%s: error: DMA disabled\n" , p->name); +pr_warn (PPIP32 "%s: error: DMA disabled\n" , p->name);else {pr_probe (p,"DMA support enabled\n" ); p->dma =0 ;/* arbitrary value != PARPORT_DMA_NONE */
@@ -2134,8 +2130,7 @@ static __init struct parport *parport_ip32_probe_port(void)parport_ip32_dump_state (p,"end init" ,0 );/* Print out what we found */ -printk (KERN_INFO "%s: SGI IP32 at 0x%lx (0x%lx)" , - p->name, p->base, p->base_hi); +pr_info ("%s: SGI IP32 at 0x%lx (0x%lx)" , p->name, p->base, p->base_hi);if (p->irq !=PARPORT_IRQ_NONE )printk (", irq %d" , p->irq);printk (" [" );
drivers/parport/parport_mfc3.c +1 -1
@@ -325,7 +325,7 @@ static int __init parport_mfc3_init(void) p->dev = &z->dev; this_port[pias++] = p; -printk (KERN_INFO "%s: Multiface III port using irq\n" , p->name); +pr_info ("%s: Multiface III port using irq\n" , p->name);/* XXX: set operating mode */ p->private_data = (void *)piabase;
drivers/parport/parport_pc.c +70 -96
386 lines not on this page · raw message
drivers/parport/parport_sunbpp.c +1 -1
@@ -314,7 +314,7 @@ static int bpp_probe(struct platform_device *op) value_tcr &= ~P_TCR_DIR ;sbus_writeb (value_tcr, ®s->p_tcr); -printk (KERN_INFO "%s: sunbpp at 0x%lx\n" , p->name, p->base); +pr_info ("%s: sunbpp at 0x%lx\n" , p->name, p->base);dev_set_drvdata (&op->dev, p);
drivers/parport/probe.c +4 -3
@@ -38,7 +38,7 @@ static void pretty_print(struct parport *port, int device) {struct parport_device_info *info = &port->probe_info[device +1 ]; -printk (KERN_INFO "%s" , port->name); +pr_info ("%s" , port->name);if (device >=0 )printk (" (addr %d)" , device);
@@ -58,7 +58,7 @@ static void parse_data(struct parport *port, int device, char *str)struct parport_device_info *info = &port->probe_info[device +1 ];if (!txt) { -printk (KERN_WARNING "%s probe: memory squeeze\n" , port->name); +pr_warn ("%s probe: memory squeeze\n" , port->name);return ; }strcpy (txt, str);
@@ -98,7 +98,8 @@ static void parse_data(struct parport *port, int device, char *str) goto rock_on; } } -printk (KERN_WARNING "%s probe: warning, class '%s' not understood.\n" , port->name, sep); +pr_warn ("%s probe: warning, class '%s' not understood\n" , + port->name, sep); info->class =PARPORT_CLASS_OTHER ; }else if (!strcmp (p,"CMD" ) || !strcmp (p,"COMMAND SET" )) {
drivers/parport/share.c +12 -12
@@ -555,8 +555,8 @@ void parport_announce_port(struct parport *port)#endif if (!port->dev) -printk (KERN_WARNING "%s: fix this legacy no-device port driver!\n" , - port->name); +pr_warn ("%s: fix this legacy no-device port driver!\n" , + port->name);parport_proc_register (port);mutex_lock (®istration_lock);
@@ -728,7 +728,8 @@ parport_register_device(struct parport *port, const char *name,if (flags &PARPORT_DEV_LURK ) {if (!pf || !kf) { -printk (KERN_INFO "%s: refused to register lurking device (%s) without callbacks\n" , port->name, name); +pr_info ("%s: refused to register lurking device (%s) without callbacks\n" , + port->name, name);return NULL ; } }
@@ -997,7 +998,7 @@ void parport_unregister_device(struct pardevice *dev)#ifdef PARPORT_PARANOID if (!dev) { -printk (KERN_ERR "parport_unregister_device: passed NULL\n" ); +pr_err ("%s: passed NULL\n" , __func__);return ; }#endif
@@ -1138,8 +1139,7 @@ int parport_claim(struct pardevice *dev)unsigned long flags;if (port->cad == dev) { -printk (KERN_INFO "%s: %s already owner\n" , - dev->port->name,dev->name); +pr_info ("%s: %s already owner\n" , dev->port->name, dev->name);return 0 ; }
@@ -1159,9 +1159,8 @@ int parport_claim(struct pardevice *dev)* I think we'll actually deadlock rather than * get here, but just in case.. */ -printk (KERN_WARNING -"%s: %s released port when preempted!\n" , - port->name, oldcad->name); +pr_warn ("%s: %s released port when preempted!\n" , + port->name, oldcad->name);if (port->cad) goto blocked; }
@@ -1321,8 +1320,8 @@ void parport_release(struct pardevice *dev)write_lock_irqsave (&port->cad_lock, flags);if (port->cad != dev) {write_unlock_irqrestore (&port->cad_lock, flags); -printk (KERN_WARNING "%s: %s tried to release parport when not owner\n" , - port->name, dev->name); +pr_warn ("%s: %s tried to release parport when not owner\n" , + port->name, dev->name);return ; }
@@ -1362,7 +1361,8 @@ void parport_release(struct pardevice *dev)if (dev->port->cad)/* racy but no matter */ return ; }else { -printk (KERN_ERR "%s: don't know how to wake %s\n" , port->name, pd->name); +pr_err ("%s: don't know how to wake %s\n" , + port->name, pd->name); } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 162/259 parport: Standardize use of printmode
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Perches <[email protected]>
[ Upstream commit a6abfdff4fe5dd19d1f1b37d72ba34cd4492fd4d ]
Standardize the define and the uses of printmode.
Miscellanea:
o Add missing statement termination ; where necessary
Stable-dep-of: ab11dac93d2d ("dev/parport: fix the array out-of-bounds risk")
--- drivers/parport/parport_gsc.c | 8 ++++++-- drivers/parport/parport_pc.c | 14 ++++++-------- drivers/parport/procfs.c | 6 +++++- 3 files changed, 17 insertions(+), 11 deletions(-)
drivers/parport/parport_gsc.c +6 -2
@@ -299,12 +299,16 @@ struct parport *parport_gsc_probe_port(unsigned long base, p->dma =PARPORT_DMA_NONE ;pr_cont (" [" ); -#define printmode (x) {if(p->modes&PARPORT_MODE_##x){pr_cont("%s%s",f?",":"",#x);f++;}} +#define printmode (x) \ +do { \ + if (p->modes & PARPORT_MODE_##x) \ + pr_cont("%s%s", f++ ? "," : "", #x); \ +} while (0) {int f =0 ;printmode (PCSPP );printmode (TRISTATE ); -printmode (COMPAT) +printmode (COMPAT );printmode (EPP );// printmode(ECP); // printmode(DMA);
drivers/parport/parport_pc.c +6 -8
@@ -2143,19 +2143,17 @@ struct parport *parport_pc_probe_port(unsigned long int base,pr_cont (" [" ); -#define printmode (x) \ - {\ - if (p->modes & PARPORT_MODE_##x) {\ - pr_cont("%s%s", f ? "," : "", #x); \ - f++;\ - } \ - } +#define printmode (x) \ +do { \ + if (p->modes & PARPORT_MODE_##x) \ + pr_cont("%s%s", f++ ? "," : "", #x); \ +} while (0) {int f =0 ;printmode (PCSPP );printmode (TRISTATE ); -printmode (COMPAT) +printmode (COMPAT );printmode (EPP );printmode (ECP );printmode (DMA );
drivers/parport/procfs.c +5 -1
@@ -213,7 +213,11 @@ static int do_hardware_modes(struct ctl_table *table, int write,return -EACCES ; { -#define printmode (x) {if(port->modes&PARPORT_MODE_##x){len+=sprintf(buffer+len,"%s%s",f?",":"",#x);f++;}} +#define printmode (x) \ +do { \ + if (port->modes & PARPORT_MODE_##x) \ + len += sprintf(buffer + len, "%s%s", f++ ? "," : "", #x); \ +} while (0)int f =0 ;printmode (PCSPP );printmode (TRISTATE );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 163/259 dev/parport: fix the array out-of-bounds risk
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: tuhaowen <[email protected]>
[ Upstream commit ab11dac93d2d568d151b1918d7b84c2d02bacbd5 ]
Fixed array out-of-bounds issues caused by sprintf by replacing it with snprintf for safer data copying, ensuring the destination buffer is not overflowed.
Below is the stack trace I encountered during the actual issue:
[ 66.575408s] [pid:5118,cpu4,QThread,4]Kernel panic - not syncing: stack-protector:
Kernel stack is corrupted in: do_hardware_base_addr+0xcc/0xd0 [parport] [ 66.575408s] [pid:5118,cpu4,QThread,5]CPU: 4 PID: 5118 Comm:
QThread Tainted: G S W O 5.10.97-arm64-desktop #7100.57021.2
[ 66.575439s] [pid:5118,cpu4,QThread,6]TGID: 5087 Comm: EFileApp
[ 66.575439s] [pid:5118,cpu4,QThread,7]Hardware name: HUAWEI HUAWEI QingYun PGUX-W515x-B081/SP1PANGUXM, BIOS 1.00.07 04/29/2024
[ 66.575439s] [pid:5118,cpu4,QThread,8]Call trace:
[ 66.575469s] [pid:5118,cpu4,QThread,9] dump_backtrace+0x0/0x1c0
[ 66.575469s] [pid:5118,cpu4,QThread,0] show_stack+0x14/0x20
[ 66.575469s] [pid:5118,cpu4,QThread,1] dump_stack+0xd4/0x10c
[ 66.575500s] [pid:5118,cpu4,QThread,2] panic+0x1d8/0x3bc
[ 66.575500s] [pid:5118,cpu4,QThread,3] __stack_chk_fail+0x2c/0x38
[ 66.575500s] [pid:5118,cpu4,QThread,4] do_hardware_base_addr+0xcc/0xd0 [parport]
--- drivers/parport/procfs.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
drivers/parport/procfs.c +12 -12
@@ -51,12 +51,12 @@ static int do_active_device(struct ctl_table *table, int write,for (dev = port->devices; dev ; dev = dev->next) {if (dev == port->cad) { - len +=sprintf (buffer,"%s\n" , dev->name); + len +=snprintf (buffer,sizeof (buffer),"%s\n" , dev->name); } }if (!len) { - len +=sprintf (buffer,"%s\n" ,"none" ); + len +=snprintf (buffer,sizeof (buffer),"%s\n" ,"none" ); }if (len > *lenp)
@@ -87,19 +87,19 @@ static int do_autoprobe(struct ctl_table *table, int write, }if ((str = info->class_name) !=NULL ) - len +=sprintf (buffer + len,"CLASS:%s;\n" , str); + len +=snprintf (buffer + len,sizeof (buffer) - len,"CLASS:%s;\n" , str);if ((str = info->model) !=NULL ) - len +=sprintf (buffer + len,"MODEL:%s;\n" , str); + len +=snprintf (buffer + len,sizeof (buffer) - len,"MODEL:%s;\n" , str);if ((str = info->mfr) !=NULL ) - len +=sprintf (buffer + len,"MANUFACTURER:%s;\n" , str); + len +=snprintf (buffer + len,sizeof (buffer) - len,"MANUFACTURER:%s;\n" , str);if ((str = info->description) !=NULL ) - len +=sprintf (buffer + len,"DESCRIPTION:%s;\n" , str); + len +=snprintf (buffer + len,sizeof (buffer) - len,"DESCRIPTION:%s;\n" , str);if ((str = info->cmdset) !=NULL ) - len +=sprintf (buffer + len,"COMMAND SET:%s;\n" , str); + len +=snprintf (buffer + len,sizeof (buffer) - len,"COMMAND SET:%s;\n" , str);if (len > *lenp) len = *lenp;
@@ -117,7 +117,7 @@ static int do_hardware_base_addr(struct ctl_table *table, int write, size_t *lenp, loff_t *ppos) { struct parport *port = (struct parport *)table->extra1; -char buffer[20 ]; +char buffer[64 ];int len =0 ;if (*ppos) {
@@ -128,7 +128,7 @@ static int do_hardware_base_addr(struct ctl_table *table, int write,if (write)/* permissions prevent this anyway */ return -EACCES ; - len +=sprintf (buffer,"%lu\t%lu\n" , port->base, port->base_hi); + len +=snprintf (buffer,sizeof (buffer),"%lu\t%lu\n" , port->base, port->base_hi);if (len > *lenp) len = *lenp;
@@ -156,7 +156,7 @@ static int do_hardware_irq(struct ctl_table *table, int write,if (write)/* permissions prevent this anyway */ return -EACCES ; - len +=sprintf (buffer,"%d\n" , port->irq); + len +=snprintf (buffer,sizeof (buffer),"%d\n" , port->irq);if (len > *lenp) len = *lenp;
@@ -184,7 +184,7 @@ static int do_hardware_dma(struct ctl_table *table, int write,if (write)/* permissions prevent this anyway */ return -EACCES ; - len +=sprintf (buffer,"%d\n" , port->dma); + len +=snprintf (buffer,sizeof (buffer),"%d\n" , port->dma);if (len > *lenp) len = *lenp;
@@ -216,7 +216,7 @@ static int do_hardware_modes(struct ctl_table *table, int write,#define printmode (x) \ do { \ if (port->modes & PARPORT_MODE_##x) \ - len += sprintf(buffer + len, "%s%s", f++ ? "," : "", #x); \ + len += snprintf(buffer + len, sizeof(buffer) - len, "%s%s", f++ ? "," : "", #x); \ } while (0)int f =0 ;printmode (PCSPP );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 164/259 driver core: Cast to (void *) with __force for __percpu pointer
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit d7aa44f5a1f86cb40659eef06035d8d92604b9d5 ]
Sparse is not happy:
drivers/base/devres.c:1230:9: warning: cast removes address space '__percpu' of expression
Use __force attribute to make it happy.
Stable-dep-of: bd50a974097b ("devres: Fix memory leakage caused by driver API devm_free_percpu()")
--- drivers/base/devres.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/base/devres.c +1 -1
@@ -1112,6 +1112,6 @@ EXPORT_SYMBOL_GPL(__devm_alloc_percpu);void devm_free_percpu (struct device *dev,void __percpu *pdata) {WARN_ON (devres_destroy (dev, devm_percpu_release, devm_percpu_match, - (void *)pdata)); + (__force void *)pdata)); }EXPORT_SYMBOL_GPL (devm_free_percpu);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 165/259 devres: Fix memory leakage caused by driver API devm_free_percpu()
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijun Hu <[email protected]>
[ Upstream commit bd50a974097bb82d52a458bd3ee39fb723129a0c ]
It will cause memory leakage when use driver API devm_free_percpu() to free memory allocated by devm_alloc_percpu(), fixed by using devres_release() instead of devres_destroy() within devm_free_percpu().
--- drivers/base/devres.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/base/devres.c +5 -1
@@ -1111,7 +1111,11 @@ EXPORT_SYMBOL_GPL(__devm_alloc_percpu);*/ void devm_free_percpu (struct device *dev,void __percpu *pdata) { -WARN_ON (devres_destroy (dev, devm_percpu_release, devm_percpu_match, +/* +* Use devres_release() to prevent memory leakage as +* devm_free_pages() does. +*/ +WARN_ON (devres_release (dev, devm_percpu_release, devm_percpu_match, (__force void *)pdata)); }EXPORT_SYMBOL_GPL (devm_free_percpu);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 166/259 genirq: Allow the PM device to originate from irq domain
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier <[email protected]>
[ Upstream commit 1f8863bfb5ca500ea1c7669b16b1931ba27fce20 ]
As a preparation to moving the reference to the device used for runtime power management, add a new 'dev' field to the irqdomain structure for that exact purpose.
The irq_chip_pm_{get,put}() helpers are made aware of the dual location via a new private helper.
No functional change intended.
Stable-dep-of: 33b1c47d1fc0 ("irqchip/imx-irqsteer: Handle runtime power management correctly")
--- include/linux/irqdomain.h | 10 ++++++++++ kernel/irq/chip.c | 23 ++++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-)
include/linux/irqdomain.h +10 -0
@@ -147,6 +147,8 @@ struct irq_domain_chip_generic;* @gc: Pointer to a list of generic chips. There is a helper function for * setting up one or more generic chips for interrupt controllers * drivers using the generic chip library which uses this pointer. +* @dev: Pointer to a device that the domain represent, and that will be +* used for power management purposes. * @parent: Pointer to parent irq_domain to support hierarchy irq_domains * @debugfs_file: dentry for the domain debugfs file *
@@ -169,6 +171,7 @@ struct irq_domain {struct fwnode_handle *fwnode;enum irq_domain_bus_token bus_token;struct irq_domain_chip_generic *gc; +struct device *dev;#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY struct irq_domain *parent;#endif
@@ -225,6 +228,13 @@ static inline struct device_node *irq_domain_get_of_node(struct irq_domain *d)return to_of_node (d->fwnode); } +static inline void irq_domain_set_pm_device (struct irq_domain *d, +struct device *dev) +{ +if (d) + d->dev = dev; +} +#ifdef CONFIG_IRQ_DOMAIN struct fwnode_handle *__irq_domain_alloc_fwnode (unsigned int type,int id,const char *name,phys_addr_t *pa);
kernel/irq/chip.c +18 -5
@@ -1528,6 +1528,17 @@ int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)return 0 ; } +static struct device *irq_get_parent_device (struct irq_data *data) +{ +if (data->chip->parent_device) +return data->chip->parent_device; + +if (data->domain) +return data->domain->dev; + +return NULL ; +} +/** * irq_chip_pm_get - Enable power for an IRQ chip * @data: Pointer to interrupt specific data
@@ -1537,12 +1548,13 @@ int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)*/ int irq_chip_pm_get (struct irq_data *data) { +struct device *dev =irq_get_parent_device (data);int retval; -if (IS_ENABLED (CONFIG_PM ) && data->chip->parent_device) { - retval =pm_runtime_get_sync (data->chip->parent_device); +if (IS_ENABLED (CONFIG_PM ) && dev) { + retval =pm_runtime_get_sync (dev);if (retval <0 ) { -pm_runtime_put_noidle (data->chip->parent_device); +pm_runtime_put_noidle (dev);return retval; } }
@@ -1560,10 +1572,11 @@ int irq_chip_pm_get(struct irq_data *data)*/ int irq_chip_pm_put (struct irq_data *data) { +struct device *dev =irq_get_parent_device (data);int retval =0 ; -if (IS_ENABLED (CONFIG_PM ) && data->chip->parent_device) - retval =pm_runtime_put (data->chip->parent_device); +if (IS_ENABLED (CONFIG_PM ) && dev) + retval =pm_runtime_put (dev);return (retval <0 ) ? retval :0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 167/259 irqchip/imx-irqsteer: Constify irq_chip struct
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lucas Stach <[email protected]>
[ Upstream commit e9a50f12e579a48e124ac5adb93dafc35f0a46b8 ]
The imx_irqsteer_irq_chip struct is constant data.
Stable-dep-of: 33b1c47d1fc0 ("irqchip/imx-irqsteer: Handle runtime power management correctly")
--- drivers/irqchip/irq-imx-irqsteer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/irqchip/irq-imx-irqsteer.c +1 -1
@@ -70,7 +70,7 @@ static void imx_irqsteer_irq_mask(struct irq_data *d)raw_spin_unlock_irqrestore (&data->lock, flags); } -static struct irq_chip imx_irqsteer_irq_chip = { +static const struct irq_chip imx_irqsteer_irq_chip = { .name ="irqsteer" , .irq_mask = imx_irqsteer_irq_mask, .irq_unmask = imx_irqsteer_irq_unmask,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 168/259 irqchip/imx-irqsteer: Add runtime PM support
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lucas Stach <[email protected]>
[ Upstream commit 4730d2233311d86cad9dc510318d1b40e4b53cf2 ]
There are now SoCs that integrate the irqsteer controller within a separate power domain. In order to allow this domain to be powered down when not needed, add runtime PM support to the driver.
Stable-dep-of: 33b1c47d1fc0 ("irqchip/imx-irqsteer: Handle runtime power management correctly")
--- drivers/irqchip/irq-imx-irqsteer.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
drivers/irqchip/irq-imx-irqsteer.c +11 -3
@@ -12,6 +12,7 @@#include <linux/kernel.h> #include <linux/of_irq.h> #include <linux/of_platform.h> +#include <linux/pm_runtime.h> #include <linux/spinlock.h> #define CTRL_STRIDE_OFF (_t, _r) (_t * 4 * _r)
@@ -181,7 +182,7 @@ static int imx_irqsteer_probe(struct platform_device *pdev) data->irq_count =DIV_ROUND_UP (irqs_num,64 ); data->reg_num = irqs_num /32 ; -if (IS_ENABLED (CONFIG_PM_SLEEP )) { +if (IS_ENABLED (CONFIG_PM )) { data->saved_reg =devm_kzalloc (&pdev->dev,sizeof (u32) * data->reg_num,GFP_KERNEL );
@@ -205,6 +206,7 @@ static int imx_irqsteer_probe(struct platform_device *pdev) ret = -ENOMEM ; goto out; } +irq_domain_set_pm_device (data->domain, &pdev->dev);if (!data->irq_count || data->irq_count >CHAN_MAX_OUTPUT_INT ) { ret = -EINVAL ;
@@ -225,6 +227,9 @@ static int imx_irqsteer_probe(struct platform_device *pdev)platform_set_drvdata (pdev, data); +pm_runtime_set_active (&pdev->dev); +pm_runtime_enable (&pdev->dev); +return 0 ; out:clk_disable_unprepare (data->ipg_clk);
@@ -247,7 +252,7 @@ static int imx_irqsteer_remove(struct platform_device *pdev)return 0 ; } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static void imx_irqsteer_save_regs (struct irqsteer_data *data) {int i;
@@ -294,7 +299,10 @@ static int imx_irqsteer_resume(struct device *dev)#endif static const struct dev_pm_ops imx_irqsteer_pm_ops = { -SET_NOIRQ_SYSTEM_SLEEP_PM_OPS (imx_irqsteer_suspend, imx_irqsteer_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) +SET_RUNTIME_PM_OPS (imx_irqsteer_suspend, + imx_irqsteer_resume,NULL ) };static const struct of_device_id imx_irqsteer_dt_ids[] = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 169/259 irqchip/imx-irqsteer: Handle runtime power management correctly
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shenwei Wang <[email protected]>
[ Upstream commit 33b1c47d1fc0b5f06a393bb915db85baacba18ea ]
The power domain is automatically activated from clk_prepare(). However, on certain platforms like i.MX8QM and i.MX8QXP, the power-on handling invokes sleeping functions, which triggers the 'scheduling while atomic' bug in the context switch path during device probing:
BUG: scheduling while atomic: kworker/u13:1/48/0x00000002 Call trace: __schedule_bug+0x54/0x6c __schedule+0x7f0/0xa94 schedule+0x5c/0xc4 schedule_preempt_disabled+0x24/0x40 __mutex_lock.constprop.0+0x2c0/0x540 __mutex_lock_slowpath+0x14/0x20 mutex_lock+0x48/0x54 clk_prepare_lock+0x44/0xa0 clk_prepare+0x20/0x44 imx_irqsteer_resume+0x28/0xe0 pm_generic_runtime_resume+0x2c/0x44 __genpd_runtime_resume+0x30/0x80 genpd_runtime_resume+0xc8/0x2c0 __rpm_callback+0x48/0x1d8 rpm_callback+0x6c/0x78 rpm_resume+0x490/0x6b4 __pm_runtime_resume+0x50/0x94 irq_chip_pm_get+0x2c/0xa0 __irq_do_set_handler+0x178/0x24c irq_set_chained_handler_and_data+0x60/0xa4 mxc_gpio_probe+0x160/0x4b0
Cure this by implementing the irq_bus_lock/sync_unlock() interrupt chip callbacks and handle power management in them as they are invoked from non-atomic context.
[ tglx: Rewrote change log, added Fixes tag ]
--- drivers/irqchip/irq-imx-irqsteer.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-)
drivers/irqchip/irq-imx-irqsteer.c +21 -3
@@ -35,6 +35,7 @@ struct irqsteer_data {int channel;struct irq_domain *domain;u32 *saved_reg; +struct device *dev; }; static int imx_irqsteer_get_reg_index(struct irqsteer_data *data,
@@ -71,10 +72,26 @@ static void imx_irqsteer_irq_mask(struct irq_data *d)raw_spin_unlock_irqrestore (&data->lock, flags); } +static void imx_irqsteer_irq_bus_lock (struct irq_data *d) +{ +struct irqsteer_data *data = d->chip_data; + +pm_runtime_get_sync (data->dev); +} + +static void imx_irqsteer_irq_bus_sync_unlock (struct irq_data *d) +{ +struct irqsteer_data *data = d->chip_data; + +pm_runtime_put_autosuspend (data->dev); +} +static const struct irq_chip imx_irqsteer_irq_chip = { - .name ="irqsteer" , - .irq_mask = imx_irqsteer_irq_mask, - .irq_unmask = imx_irqsteer_irq_unmask, + .name ="irqsteer" , + .irq_mask = imx_irqsteer_irq_mask, + .irq_unmask = imx_irqsteer_irq_unmask, + .irq_bus_lock = imx_irqsteer_irq_bus_lock, + .irq_bus_sync_unlock = imx_irqsteer_irq_bus_sync_unlock, }; static int imx_irqsteer_irq_map(struct irq_domain *h, unsigned int irq,
@@ -152,6 +169,7 @@ static int imx_irqsteer_probe(struct platform_device *pdev)if (!data)return -ENOMEM ; + data->dev = &pdev->dev; data->regs =devm_platform_ioremap_resource (pdev,0 );if (IS_ERR (data->regs)) {dev_err (&pdev->dev,"failed to initialize reg\n" );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 170/259 remoteproc: imx_rproc: ignore mapping vdev regions
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit 8f2d8961640f0346cbe892273c3260a0d30c1931 ]
vdev regions are vdev0vring0, vdev0vring1, vdevbuffer and similar. They are handled by remoteproc common code, no need to map in imx rproc driver.
Stable-dep-of: 2fa26ca8b786 ("remoteproc: imx_rproc: Skip over memory region when node value is NULL")
--- drivers/remoteproc/imx_rproc.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/remoteproc/imx_rproc.c +3 -0
@@ -286,6 +286,9 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,struct resource res; node =of_parse_phandle (np,"memory-region" , a); +/* Not map vdev region */ +if (!strcmp (node->name,"vdev" )) +continue ; err =of_address_to_resource (node,0 , &res);if (err) {dev_err (dev,"unable to resolve memory region\n" );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 171/259 remoteproc: imx_rproc: Fix ignoring mapping vdev regions
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dong Aisheng <[email protected]>
[ Upstream commit afe670e23af91d8a74a8d7049f6e0984bbf6ea11 ]
vdev regions are typically named vdev0buffer, vdev0ring0, vdev0ring1 and etc. Change to strncmp to cover them all.
Stable-dep-of: 2fa26ca8b786 ("remoteproc: imx_rproc: Skip over memory region when node value is NULL")
--- drivers/remoteproc/imx_rproc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/remoteproc/imx_rproc.c +2 -2
@@ -286,8 +286,8 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,struct resource res; node =of_parse_phandle (np,"memory-region" , a); -/* Not map vdev region */ -if (!strcmp (node->name,"vdev" )) +/* Not map vdevbuffer, vdevring region */ +if (!strncmp (node->name,"vdev" ,strlen ("vdev" )))continue ; err =of_address_to_resource (node,0 , &res);if (err) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 172/259 remoteproc: imx_rproc: Skip over memory region when node value is NULL
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandr Mishin <[email protected]>
[ Upstream commit 2fa26ca8b786888673689ccc9da6094150939982 ]
In imx_rproc_addr_init() "nph = of_count_phandle_with_args()" just counts number of phandles. But phandles may be empty. So of_parse_phandle() in the parsing loop (0 < a < nph) may return NULL which is later dereferenced. Adjust this issue by adding NULL-return check.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/remoteproc/imx_rproc.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/remoteproc/imx_rproc.c +2 -0
@@ -286,6 +286,8 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,struct resource res; node =of_parse_phandle (np,"memory-region" , a); +if (!node) +continue ;/* Not map vdevbuffer, vdevring region */ if (!strncmp (node->name,"vdev" ,strlen ("vdev" )))continue ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 173/259 drm/nouveau: prime: fix refcount underflow
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danilo Krummrich <[email protected]>
[ Upstream commit a9bf3efc33f1fbf88787a277f7349459283c9b95 ]
Calling nouveau_bo_ref() on a nouveau_bo without initializing it (and hence the backing ttm_bo) leads to a refcount underflow.
Instead of calling nouveau_bo_ref() in the unwind path of drm_gem_object_init(), clean things up manually.
--- drivers/gpu/drm/nouveau/nouveau_prime.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/nouveau/nouveau_prime.c +2 -1
@@ -83,7 +83,8 @@ struct drm_gem_object *nouveau_gem_prime_import_sg_table(struct drm_device *dev,* to the caller, instead of a normal nouveau_bo ttm reference. */ ret =drm_gem_object_init (dev, &nvbo->bo.base, size);if (ret) { -nouveau_bo_ref (NULL , &nvbo); +drm_gem_object_release (&nvbo->bo.base); +kfree (nvbo); obj =ERR_PTR (-ENOMEM ); goto unlock; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 174/259 drm/vmwgfx: Fix overlay when using Screen Targets
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Forbes <[email protected]>
[ Upstream commit cb372a505a994cb39aa75acfb8b3bcf94787cf94 ]
This code was never updated to support Screen Targets.
Fixes a bug where Xv playback displays a green screen instead of actual video contents when 3D acceleration is disabled in the guest.
--- drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c +1 -1
@@ -98,7 +98,7 @@ static int vmw_overlay_send_put(struct vmw_private *dev_priv, {struct vmw_escape_video_flush *flush;size_t fifo_size; -bool have_so = (dev_priv->active_display_unit == vmw_du_screen_object); +bool have_so = (dev_priv->active_display_unit != vmw_du_legacy);int i, num_items;SVGAGuestPtr ptr;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 175/259 net/iucv: fix use after free in iucv_sock_close()
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexandra Winter <[email protected]>
[ Upstream commit f558120cd709682b739207b48cf7479fd9568431 ]
iucv_sever_path() is called from process context and from bh context. iucv->path is used as indicator whether somebody else is taking care of severing the path (or it is already removed / never existed). This needs to be done with atomic compare and swap, otherwise there is a small window where iucv_sock_close() will try to work with a path that has already been severed and freed by iucv_callback_connrej() called by iucv_tasklet_fn().
Example:
[452744.123844] Call Trace: [452744.123845] ([<0000001e87f03880>] 0x1e87f03880) [452744.123966] [<00000000d593001e>] iucv_path_sever+0x96/0x138 [452744.124330] [<000003ff801ddbca>] iucv_sever_path+0xc2/0xd0 [af_iucv] [452744.124336] [<000003ff801e01b6>] iucv_sock_close+0xa6/0x310 [af_iucv] [452744.124341] [<000003ff801e08cc>] iucv_sock_release+0x3c/0xd0 [af_iucv] [452744.124345] [<00000000d574794e>] __sock_release+0x5e/0xe8 [452744.124815] [<00000000d5747a0c>] sock_close+0x34/0x48 [452744.124820] [<00000000d5421642>] __fput+0xba/0x268 [452744.124826] [<00000000d51b382c>] task_work_run+0xbc/0xf0 [452744.124832] [<00000000d5145710>] do_notify_resume+0x88/0x90 [452744.124841] [<00000000d5978096>] system_call+0xe2/0x2c8 [452744.125319] Last Breaking-Event-Address: [452744.125321] [<00000000d5930018>] iucv_path_sever+0x90/0x138 [452744.125324] [452744.125325] Kernel panic - not syncing: Fatal exception in interrupt
Note that bh_lock_sock() is not serializing the tasklet context against process context, because the check for sock_owned_by_user() and corresponding handling is missing.
Ideas for a future clean-up patch:
A) Correct usage of bh_lock_sock() in tasklet context, as described in
Re-enqueue, if needed. This may require adding return values to the tasklet functions and thus changes to all users of iucv.
B) Change iucv tasklet into worker and use only lock_sock() in af_iucv.
--- net/iucv/af_iucv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/iucv/af_iucv.c +2 -2
@@ -453,8 +453,8 @@ static void iucv_sever_path(struct sock *sk, int with_user_data)struct iucv_sock *iucv =iucv_sk (sk);struct iucv_path *path = iucv->path; -if (iucv->path) { - iucv->path =NULL ; +/* Whoever resets the path pointer, must sever and free it. */ +if (xchg (&iucv->path,NULL )) {if (with_user_data) {low_nmcpy (user_data, iucv->src_name);high_nmcpy (user_data, iucv->dst_name);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 176/259 net/mlx5e: Add a check for the return value from mlx5_port_set_eth_ptys
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shahar Shitrit <[email protected]>
[ Upstream commit 3f8e82a020a5c22f9b791f4ac499b8e18007fbda ]
Since the documentation for mlx5_toggle_port_link states that it should only be used after setting the port register, we add a check for the return value from mlx5_port_set_eth_ptys to ensure the register was successfully set before calling it.
--- drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +6 -1
@@ -1104,7 +1104,12 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,if (!an_changes && link_modes == eproto.admin) goto out; -mlx5_port_set_eth_ptys (mdev, an_disable, link_modes, ext); + err =mlx5_port_set_eth_ptys (mdev, an_disable, link_modes, ext); +if (err) { +netdev_err (priv->netdev,"%s: failed to set ptys reg: %d\n" , __func__, err); + goto out; + } +mlx5_toggle_port_link (mdev); out:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 177/259 ipv6: fix ndisc_is_useropt() handling for PIO
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maciej Żenczykowski <[email protected]>
[ Upstream commit a46c68debf3be3a477a69ccbf0a1d050df841676 ]
The current logic only works if the PIO is between two other ND user options. This fixes it so that the PIO can also be either before or after other ND user options (for example the first or last option in the RA).
side note: there's actually Android tests verifying a portion of the old broken behaviour, so:
https://android-review.googlesource.com/c/kernel/tests/+/3196704
fixes those up.
--- net/ipv6/ndisc.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-)
net/ipv6/ndisc.c +18 -16
@@ -225,6 +225,7 @@ struct ndisc_options *ndisc_parse_options(const struct net_device *dev,return NULL ;memset (ndopts,0 ,sizeof (*ndopts));while (opt_len) { +bool unknown = false;int l;if (opt_len <sizeof (struct nd_opt_hdr ))return NULL ;
@@ -260,22 +261,23 @@ struct ndisc_options *ndisc_parse_options(const struct net_device *dev,break ;#endif default : -if (ndisc_is_useropt (dev, nd_opt)) { - ndopts->nd_useropts_end = nd_opt; -if (!ndopts->nd_useropts) - ndopts->nd_useropts = nd_opt; - }else { -/* -* Unknown options must be silently ignored, -* to accommodate future extension to the -* protocol. -*/ -ND_PRINTK (2 , notice, -"%s: ignored unsupported option; type=%d, len=%d\n" , - __func__, - nd_opt->nd_opt_type, - nd_opt->nd_opt_len); - } + unknown = true; + } +if (ndisc_is_useropt (dev, nd_opt)) { + ndopts->nd_useropts_end = nd_opt; +if (!ndopts->nd_useropts) + ndopts->nd_useropts = nd_opt; + }else if (unknown) { +/* +* Unknown options must be silently ignored, +* to accommodate future extension to the +* protocol. +*/ +ND_PRINTK (2 , notice, +"%s: ignored unsupported option; type=%d, len=%d\n" , + __func__, + nd_opt->nd_opt_type, + nd_opt->nd_opt_len); } next_opt: opt_len -= l;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 178/259 HID: wacom: Modify pen IDs
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tatsunosuke Tobita <[email protected]>
commit f0d17d696dfce77c9abc830e4ac2d677890a2dad upstream.
The pen ID, 0x80842, was not the correct ID for wacom driver to treat. The ID was corrected to 0x8842.
Also, 0x4200 was not the expected ID used on any Wacom device. Therefore, 0x4200 was removed.
--- drivers/hid/wacom_wac.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/hid/wacom_wac.c +1 -2
@@ -714,13 +714,12 @@ static int wacom_intuos_get_tool_type(incase 0x8e2 :/* IntuosHT2 pen */ case 0x022 :case 0x200 :/* Pro Pen 3 */ -case 0x04200 :/* Pro Pen 3 */ case 0x10842 :/* MobileStudio Pro Pro Pen slim */ case 0x14802 :/* Intuos4/5 13HD/24HD Classic Pen */ case 0x16802 :/* Cintiq 13HD Pro Pen */ case 0x18802 :/* DTH2242 Pen */ case 0x10802 :/* Intuos4/5 13HD/24HD General Pen */ -case 0x80842 :/* Intuos Pro and Cintiq Pro 3D Pen */ +case 0x8842 :/* Intuos Pro and Cintiq Pro 3D Pen */ tool_type =BTN_TOOL_PEN ;break ;
Greg Kroah-Hartman
maintainerPATCH 179/259 protect the fetch of ->fd[fd] in do_dup2() from mispredictions
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 8aa37bde1a7b645816cda8b80df4753ecf172bf1 upstream.
both callers have verified that fd is not greater than ->max_fds; however, misprediction might end up with
tofree = fdt->fd[fd];
being speculatively executed. That's wrong for the same reasons why it's wrong in close_fd()/file_close_fd_locked(); the same solution applies - array_index_nospec(fd, fdt->max_fds) could differ from fd only in case of speculative execution on mispredicted path.
--- fs/file.c | 1 + 1 file changed, 1 insertion(+)
fs/file.c +1 -0
@@ -908,6 +908,7 @@ __releases(&files->file_lock)* tables and this condition does not arise without those. */ fdt =files_fdtable (files); + fd =array_index_nospec (fd, fdt->max_fds); tofree = fdt->fd[fd];if (!tofree &&fd_is_open (fd, fdt)) goto Ebusy;
Greg Kroah-Hartman
maintainerPATCH 180/259 ALSA: usb-audio: Correct surround channels in UAC1 channel map
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit b7b7e1ab7619deb3b299b5e5c619c3e6f183a12d upstream.
USB-audio driver puts SNDRV_CHMAP_SL and _SR as left and right surround channels for UAC1 channel map, respectively. But they should have been SNDRV_CHMAP_RL and _RR; the current value *_SL and _SR are rather "side" channels, not "surround". I guess I took those mistakenly when I read the spec mentioning "surround left".
This patch corrects those entries to be the right channels.
--- sound/usb/stream.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/usb/stream.c +2 -2
@@ -245,8 +245,8 @@ static struct snd_pcm_chmap_elem *converSNDRV_CHMAP_FR ,/* right front */ SNDRV_CHMAP_FC ,/* center front */ SNDRV_CHMAP_LFE ,/* LFE */ -SNDRV_CHMAP_SL ,/* left surround */ -SNDRV_CHMAP_SR ,/* right surround */ +SNDRV_CHMAP_RL ,/* left surround */ +SNDRV_CHMAP_RR ,/* right surround */ SNDRV_CHMAP_FLC ,/* left of center */ SNDRV_CHMAP_FRC ,/* right of center */ SNDRV_CHMAP_RC, /* surround */
Greg Kroah-Hartman
maintainerPATCH 181/259 net: usb: sr9700: fix uninitialized variable use in sr_mdio_read
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit 08f3a5c38087d1569e982a121aad1e6acbf145ce upstream.
It could lead to error happen because the variable res is not updated if the call to sr_share_read_word returns an error. In this particular case error code was returned and res stayed uninitialized. Same issue also applies to sr_read_reg.
This can be avoided by checking the return value of sr_share_read_word and sr_read_reg, and propagating the error if the read operation failed.
Found by code review.
--- drivers/net/usb/sr9700.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/net/usb/sr9700.c +9 -2
@@ -178,6 +178,7 @@ static int sr_mdio_read(struct net_devicstruct usbnet *dev =netdev_priv (netdev);__le16 res;int rc =0 ; +int err;if (phy_id) {netdev_dbg (netdev,"Only internal phy supported\n" );
@@ -188,11 +189,17 @@ static int sr_mdio_read(struct net_devicif (loc ==MII_BMSR ) {u8 value; -sr_read_reg (dev,SR_NSR , &value); + err =sr_read_reg (dev,SR_NSR , &value); +if (err <0 ) +return err; +if (value &NSR_LINKST ) rc =1 ; } -sr_share_read_word (dev,1 , loc, &res); + err =sr_share_read_word (dev,1 , loc, &res); +if (err <0 ) +return err; +if (rc ==1 ) res =le16_to_cpu (res) |BMSR_LSTATUS ;else
Greg Kroah-Hartman
maintainerPATCH 182/259 netfilter: ipset: Add list flush to cancel_gc
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Maltsev <[email protected]>
[ Upstream commit c1193d9bbbd379defe9be3c6de566de684de8a6f ]
Flushing list in cancel_gc drops references to other lists right away, without waiting for RCU to destroy list. Fixes race when referenced ipsets can't be destroyed while referring list is scheduled for destroy.
--- net/netfilter/ipset/ip_set_list_set.c | 3 +++ 1 file changed, 3 insertions(+)
net/netfilter/ipset/ip_set_list_set.c +3 -0
@@ -547,6 +547,9 @@ list_set_cancel_gc(struct ip_set *set)if (SET_WITH_TIMEOUT (set))del_timer_sync (&map->gc); + +/* Flush list to drop references to other ipsets */ +list_set_flush (set); }static const struct ip_set_type_variant set_variant = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 183/259 genirq: Allow irq_chip registration functions to take a const irq_chip
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier <[email protected]>
[ Upstream commit 393e1280f765661cf39785e967676a4e57324126 ]
In order to let a const irqchip be fed to the irqchip layer, adjust the various prototypes. An extra cast in irq_set_chip()() is required to avoid a warning.
--- include/linux/irq.h | 7 ++++--- kernel/irq/chip.c | 9 +++------ 2 files changed, 7 insertions(+), 9 deletions(-)
include/linux/irq.h +4 -3
@@ -677,10 +677,11 @@ extern struct irq_chip no_irq_chip;extern struct irq_chip dummy_irq_chip;extern void -irq_set_chip_and_handler_name (unsigned int irq,struct irq_chip *chip, +irq_set_chip_and_handler_name (unsigned int irq,const struct irq_chip *chip,irq_flow_handler_t handle,const char *name); -static inline void irq_set_chip_and_handler (unsigned int irq,struct irq_chip *chip, +static inline void irq_set_chip_and_handler (unsigned int irq, +const struct irq_chip *chip,irq_flow_handler_t handle) {irq_set_chip_and_handler_name (irq, chip, handle,NULL );
@@ -770,7 +771,7 @@ static inline void irq_set_percpu_devid_flags(unsigned int irq) }/* Set/get chip/data for an IRQ: */ -extern int irq_set_chip (unsigned int irq,struct irq_chip *chip); +extern int irq_set_chip (unsigned int irq,const struct irq_chip *chip);extern int irq_set_handler_data (unsigned int irq,void *data);extern int irq_set_chip_data (unsigned int irq,void *data);extern int irq_set_irq_type (unsigned int irq,unsigned int type);
kernel/irq/chip.c +3 -6
@@ -38,7 +38,7 @@ struct irqaction chained_action = {* @irq: irq number * @chip: pointer to irq chip description structure */ -int irq_set_chip (unsigned int irq,struct irq_chip *chip) +int irq_set_chip (unsigned int irq,const struct irq_chip *chip) {unsigned long flags;struct irq_desc *desc =irq_get_desc_lock (irq, &flags,0 );
@@ -46,10 +46,7 @@ int irq_set_chip(unsigned int irq, struct irq_chip *chip)if (!desc)return -EINVAL ; -if (!chip) - chip = &no_irq_chip; - - desc->irq_data.chip = chip; + desc->irq_data.chip = (struct irq_chip *)(chip ?: &no_irq_chip);irq_put_desc_unlock (desc, flags);/* * For !CONFIG_SPARSE_IRQ make the irq show up in
@@ -1086,7 +1083,7 @@ irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,EXPORT_SYMBOL_GPL (irq_set_chained_handler_and_data);void -irq_set_chip_and_handler_name (unsigned int irq,struct irq_chip *chip, +irq_set_chip_and_handler_name (unsigned int irq,const struct irq_chip *chip,irq_flow_handler_t handle,const char *name) {irq_set_chip (irq, chip);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 184/259 irqchip/mbigen: Fix mbigen node address layout
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yipeng Zou <[email protected]>
[ Upstream commit 6be6cba9c4371d27f78d900ccfe34bb880d9ee20 ]
The mbigen interrupt chip has its per node registers located in a contiguous region of page sized chunks. The code maps them into virtual address space as a contiguous region and determines the address of a node by using the node ID as index.
mbigen chip
|-----------------|------------|--------------|
mgn_node_0 mgn_node_1 ... mgn_node_i
|--------------| |--------------| |----------------------|
[0x0000, 0x0x0FFF] [0x1000, 0x1FFF] [i*0x1000, (i+1)*0x1000 - 1]This works correctly up to 10 nodes, but then fails because the 11th's array slot is used for the MGN_CLEAR registers.
mbigen chip
|-----------|--------|--------|---------------|--------|
mgn_node_0 mgn_node_1 ... mgn_clear_register ... mgn_node_i
|-----------------|
[0xA000, 0xAFFF]Skip the MGN_CLEAR register space when calculating the offset for node IDs greater than or equal to ten.
--- drivers/irqchip/irq-mbigen.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
drivers/irqchip/irq-mbigen.c +16 -4
@@ -64,6 +64,20 @@ struct mbigen_device {void __iomem *base; }; +static inline unsigned int get_mbigen_node_offset (unsigned int nid) +{ +unsigned int offset = nid *MBIGEN_NODE_OFFSET ; + +/* +* To avoid touched clear register in unexpected way, we need to directly +* skip clear register when access to more than 10 mbigen nodes. +*/ +if (nid >= (REG_MBIGEN_CLEAR_OFFSET /MBIGEN_NODE_OFFSET )) + offset +=MBIGEN_NODE_OFFSET ; + +return offset; +} +static inline unsigned int get_mbigen_vec_reg (irq_hw_number_t hwirq) {unsigned int nid, pin;
@@ -72,8 +86,7 @@ static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq) nid = hwirq /IRQS_PER_MBIGEN_NODE +1 ; pin = hwirq %IRQS_PER_MBIGEN_NODE ; -return pin *4 + nid *MBIGEN_NODE_OFFSET - +REG_MBIGEN_VEC_OFFSET ; +return pin *4 +get_mbigen_node_offset (nid) +REG_MBIGEN_VEC_OFFSET ; } static inline void get_mbigen_type_reg(irq_hw_number_t hwirq,
@@ -88,8 +101,7 @@ static inline void get_mbigen_type_reg(irq_hw_number_t hwirq, *mask =1 << (irq_ofst %32 ); ofst = irq_ofst /32 *4 ; - *addr = ofst + nid *MBIGEN_NODE_OFFSET - +REG_MBIGEN_TYPE_OFFSET ; + *addr = ofst +get_mbigen_node_offset (nid) +REG_MBIGEN_TYPE_OFFSET ; } static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 185/259 x86/mm: Fix pti_clone_pgtable() alignment assumption
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit 41e71dbb0e0a0fe214545fe64af031303a08524c ]
Guenter reported dodgy crashes on an i386-nosmp build using GCC-11 that had the form of endless traps until entry stack exhaust and then #DF from the stack guard.
It turned out that pti_clone_pgtable() had alignment assumptions on the start address, notably it hard assumes start is PMD aligned. This is true on x86_64, but very much not true on i386.
These assumptions can cause the end condition to malfunction, leading to a 'short' clone. Guess what happens when the user mapping has a short copy of the entry text?
Use the correct increment form for addr to avoid alignment assumptions.
--- arch/x86/mm/pti.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/mm/pti.c +3 -3
@@ -375,14 +375,14 @@ pti_clone_pgtable(unsigned long start, unsigned long end,*/ *target_pmd = *pmd; - addr +=PMD_SIZE ; + addr =round_up (addr +1 ,PMD_SIZE ); }else if (level ==PTI_CLONE_PTE ) {/* Walk the page-table down to the pte level */ pte =pte_offset_kernel (pmd, addr);if (pte_none (*pte)) { - addr +=PAGE_SIZE ; + addr =round_up (addr +1 ,PAGE_SIZE );continue ; }
@@ -402,7 +402,7 @@ pti_clone_pgtable(unsigned long start, unsigned long end,/* Clone the PTE */ *target_pte = *pte; - addr +=PAGE_SIZE ; + addr =round_up (addr +1 ,PAGE_SIZE ); }else {BUG ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 186/259 sctp: move hlist_node and hashent out of sctp_ep_common
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Long <[email protected]>
[ Upstream commit 3d3b2f57d4447e6e9f4096ad01d0e4129f7bc7e9 ]
Struct sctp_ep_common is included in both asoc and ep, but hlist_node and hashent are only needed by ep after asoc_hashtable was dropped by Commit b5eff7128366 ("sctp: drop the old assoc hashtable of sctp").
So it is better to move hlist_node and hashent from sctp_ep_common to sctp_endpoint, and it saves some space for each asoc.
Stable-dep-of: 9ab0faa7f9ff ("sctp: Fix null-ptr-deref in reuseport_add_sock().")
--- include/net/sctp/sctp.h | 4 ++-- include/net/sctp/structs.h | 8 ++++---- net/sctp/input.c | 27 ++++++++++----------------- net/sctp/proc.c | 10 ++++------ net/sctp/socket.c | 6 +++--- 5 files changed, 23 insertions(+), 32 deletions(-)
include/net/sctp/sctp.h +2 -2
@@ -506,8 +506,8 @@ static inline int sctp_ep_hashfn(struct net *net, __u16 lport)return (net_hash_mix (net) + lport) & (sctp_ep_hashsize -1 ); } -#define sctp_for_each_hentry (epb, head) \ - hlist_for_each_entry(epb, head, node) +#define sctp_for_each_hentry (ep, head) \ + hlist_for_each_entry(ep, head, node)/* Is a socket of this style? */ #define sctp_style (sk, style) __sctp_style((sk), (SCTP_SOCKET_##style))
include/net/sctp/structs.h +4 -4
@@ -1224,10 +1224,6 @@ enum sctp_endpoint_type {*/ struct sctp_ep_common { -/* Fields to help us manage our entries in the hash tables. */ -struct hlist_node node; -int hashent; -/* Runtime type information. What kind of endpoint is this? */ enum sctp_endpoint_type type;
@@ -1279,6 +1275,10 @@ struct sctp_endpoint {/* Common substructure for endpoint and association. */ struct sctp_ep_common base; +/* Fields to help us manage our entries in the hash tables. */ +struct hlist_node node; +int hashent; +/* Associations: A list of current associations and mappings * to the data consumers for each association. This * may be in the form of a hash table or other
net/sctp/input.c +10 -17
@@ -722,23 +722,21 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep)struct sock *sk = ep->base.sk;struct net *net =sock_net (sk);struct sctp_hashbucket *head; -struct sctp_ep_common *epb; - epb = &ep->base; - epb->hashent =sctp_ep_hashfn (net, epb->bind_addr.port); - head = &sctp_ep_hashtable[epb->hashent]; + ep->hashent =sctp_ep_hashfn (net, ep->base.bind_addr.port); + head = &sctp_ep_hashtable[ep->hashent];if (sk->sk_reuseport) {bool any =sctp_is_ep_boundall (sk); -struct sctp_ep_common *epb2; +struct sctp_endpoint *ep2;struct list_head *list;int cnt =0 , err =1 ;list_for_each (list, &ep->base.bind_addr.address_list) cnt++; -sctp_for_each_hentry (epb2, &head->chain) { -struct sock *sk2 = epb2->sk; +sctp_for_each_hentry (ep2, &head->chain) { +struct sock *sk2 = ep2->base.sk; if (!net_eq(sock_net(sk2), net) || sk2 == sk || !uid_eq(sock_i_uid(sk2), sock_i_uid(sk)) ||
@@ -765,7 +763,7 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep) }write_lock (&head->lock); -hlist_add_head (&epb->node, &head->chain); +hlist_add_head (&ep->node, &head->chain);write_unlock (&head->lock);return 0 ; }
@@ -787,19 +785,16 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep) {struct sock *sk = ep->base.sk;struct sctp_hashbucket *head; -struct sctp_ep_common *epb; - epb = &ep->base; + ep->hashent =sctp_ep_hashfn (sock_net (sk), ep->base.bind_addr.port); - epb->hashent =sctp_ep_hashfn (sock_net (sk), epb->bind_addr.port); - - head = &sctp_ep_hashtable[epb->hashent]; + head = &sctp_ep_hashtable[ep->hashent];if (rcu_access_pointer (sk->sk_reuseport_cb))reuseport_detach_sock (sk);write_lock (&head->lock); -hlist_del_init (&epb->node); +hlist_del_init (&ep->node);write_unlock (&head->lock); }
@@ -832,7 +827,6 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint( const union sctp_addr *paddr) {struct sctp_hashbucket *head; -struct sctp_ep_common *epb;struct sctp_endpoint *ep;struct sock *sk;__be16 lport;
@@ -842,8 +836,7 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint( hash =sctp_ep_hashfn (net,ntohs (lport)); head = &sctp_ep_hashtable[hash];read_lock (&head->lock); -sctp_for_each_hentry (epb, &head->chain) { - ep =sctp_ep (epb); +sctp_for_each_hentry (ep, &head->chain) {if (sctp_endpoint_is_match (ep, net, laddr)) goto hit; }
net/sctp/proc.c +4 -6
@@ -161,7 +161,6 @@ static void *sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos)static int sctp_eps_seq_show (struct seq_file *seq,void *v) {struct sctp_hashbucket *head; -struct sctp_ep_common *epb;struct sctp_endpoint *ep;struct sock *sk;int hash = *(loff_t *)v;
@@ -171,18 +170,17 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v) head = &sctp_ep_hashtable[hash];read_lock_bh (&head->lock); -sctp_for_each_hentry (epb, &head->chain) { - ep =sctp_ep (epb); - sk = epb->sk; +sctp_for_each_hentry (ep, &head->chain) { + sk = ep->base.sk;if (!net_eq (sock_net (sk),seq_file_net (seq)))continue ;seq_printf (seq,"%8pK %8pK %-3d %-3d %-4d %-5d %5u %5lu " , ep, sk,sctp_sk (sk)->type, sk->sk_state, hash, - epb->bind_addr.port, + ep->base.bind_addr.port,from_kuid_munged (seq_user_ns (seq),sock_i_uid (sk)),sock_i_ino (sk)); -sctp_seq_dump_local_addrs (seq, epb); +sctp_seq_dump_local_addrs (seq, &ep->base);seq_printf (seq,"\n" ); }read_unlock_bh (&head->lock);
net/sctp/socket.c +3 -3
@@ -5365,14 +5365,14 @@ int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *), void *p) {int err =0 ;int hash =0 ; -struct sctp_ep_common *epb; +struct sctp_endpoint *ep;struct sctp_hashbucket *head;for (head = sctp_ep_hashtable; hash < sctp_ep_hashsize; hash++, head++) {read_lock_bh (&head->lock); -sctp_for_each_hentry (epb, &head->chain) { - err =cb (sctp_ep (epb), p); +sctp_for_each_hentry (ep, &head->chain) { + err =cb (ep, p);if (err)break ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 187/259 sctp: Fix null-ptr-deref in reuseport_add_sock().
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 9ab0faa7f9ffe31296dbb9bbe6f76c72c14eea18 ]
syzbot reported a null-ptr-deref while accessing sk2->sk_reuseport_cb in reuseport_add_sock(). [0]
The repro first creates a listener with SO_REUSEPORT. Then, it creates another listener on the same port and concurrently closes the first listener.
The second listen() calls reuseport_add_sock() with the first listener as sk2, where sk2->sk_reuseport_cb is not expected to be cleared concurrently, but the close() does clear it by reuseport_detach_sock().
The problem is SCTP does not properly synchronise reuseport_alloc(), reuseport_add_sock(), and reuseport_detach_sock().
The caller of reuseport_alloc() and reuseport_{add,detach}_sock() must provide synchronisation for sockets that are classified into the same reuseport group.
Otherwise, such sockets form multiple identical reuseport groups, and all groups except one would be silently dead.
1. Two sockets call listen() concurrently
2. No socket in the same group found in sctp_ep_hashtable[]
3. Two sockets call reuseport_alloc() and form two reuseport groups
4. Only one group hit first in __sctp_rcv_lookup_endpoint() receives incoming packets
Also, the reported null-ptr-deref could occur.
TCP/UDP guarantees that would not happen by holding the hash bucket lock.
Let's apply the locking strategy to __sctp_hash_endpoint() and __sctp_unhash_endpoint().
[0]:
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000002: 0000 [#1] PREEMPT SMP KASAN PTI KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017] CPU: 1 UID: 0 PID: 10230 Comm: syz-executor119 Not tainted 6.10.0-syzkaller-12585-g301927d2d2eb #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 06/27/2024 RIP: 0010:reuseport_add_sock+0x27e/0x5e0 net/core/sock_reuseport.c:350 Code: 00 0f b7 5d 00 bf 01 00 00 00 89 de e8 1b a4 ff f7 83 fb 01 0f 85 a3 01 00 00 e8 6d a0 ff f7 49 8d 7e 12 48 89 f8 48 c1 e8 03 <42> 0f b6 04 28 84 c0 0f 85 4b 02 00 00 41 0f b7 5e 12 49 8d 7e 14 RSP: 0018:ffffc9000b947c98 EFLAGS: 00010202 RAX: 0000000000000002 RBX: ffff8880252ddf98 RCX: ffff888079478000 RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000012 RBP: 0000000000000001 R08: ffffffff8993e18d R09: 1ffffffff1fef385 R10: dffffc0000000000 R11: fffffbfff1fef386 R12: ffff8880252ddac0 R13: dffffc0000000000 R14: 0000000000000000 R15: 0000000000000000 FS: 00007f24e45b96c0(0000) GS:ffff8880b9300000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffcced5f7b8 CR3: 00000000241be000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> __sctp_hash_endpoint net/sctp/input.c:762 [inline] sctp_hash_endpoint+0x52a/0x600 net/sctp/input.c:790 sctp_listen_start net/sctp/socket.c:8570 [inline] sctp_inet_listen+0x767/0xa20 net/sctp/socket.c:8625 __sys_listen_socket net/socket.c:1883 [inline] __sys_listen+0x1b7/0x230 net/socket.c:1894 __do_sys_listen net/socket.c:1902 [inline] __se_sys_listen net/socket.c:1900 [inline] __x64_sys_listen+0x5a/0x70 net/socket.c:1900 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f24e46039b9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 91 1a 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f24e45b9228 EFLAGS: 00000246 ORIG_RAX: 0000000000000032 RAX: ffffffffffffffda RBX: 00007f24e468e428 RCX: 00007f24e46039b9 RDX: 00007f24e46039b9 RSI: 0000000000000003 RDI: 0000000000000004 RBP: 00007f24e468e420 R08: 00007f24e45b96c0 R09: 00007f24e45b96c0 R10: 00007f24e45b96c0 R11: 0000000000000246 R12: 00007f24e468e42c R13: 00007f24e465a5dc R14: 0020000000000001 R15: 00007ffcced5f7d8 </TASK> Modules linked in:
--- net/sctp/input.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
net/sctp/input.c +11 -8
@@ -722,15 +722,19 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep)struct sock *sk = ep->base.sk;struct net *net =sock_net (sk);struct sctp_hashbucket *head; +int err =0 ; ep->hashent =sctp_ep_hashfn (net, ep->base.bind_addr.port); head = &sctp_ep_hashtable[ep->hashent]; +write_lock (&head->lock);if (sk->sk_reuseport) {bool any =sctp_is_ep_boundall (sk);struct sctp_endpoint *ep2;struct list_head *list; -int cnt =0 , err =1 ; +int cnt =0 ; + + err =1 ;list_for_each (list, &ep->base.bind_addr.address_list) cnt++;
@@ -748,24 +752,24 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep)if (!err) { err =reuseport_add_sock (sk, sk2, any);if (err) -return err; + goto out;break ; }else if (err <0 ) { -return err; + goto out; } }if (err) { err =reuseport_alloc (sk, any);if (err) -return err; + goto out; } } -write_lock (&head->lock);hlist_add_head (&ep->node, &head->chain); +out:write_unlock (&head->lock); -return 0 ; +return err; }/* Add an endpoint to the hash. Local BH-safe. */
@@ -790,10 +794,9 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep) head = &sctp_ep_hashtable[ep->hashent]; +write_lock (&head->lock);if (rcu_access_pointer (sk->sk_reuseport_cb))reuseport_detach_sock (sk); - -write_lock (&head->lock);hlist_del_init (&ep->node);write_unlock (&head->lock); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 188/259 net: usb: qmi_wwan: fix memory leak for not ip packets
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniele Palmas <[email protected]>
[ Upstream commit 7ab107544b777c3bd7feb9fe447367d8edd5b202 ]
Free the unused skb when not ip packets arrive.
--- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/usb/qmi_wwan.c +1 -0
@@ -238,6 +238,7 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)break ;default :/* not ip - do not know what to do */ +kfree_skb (skbn); goto skip; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 189/259 net: linkwatch: use system_unbound_wq
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 3e7917c0cdad835a5121520fc5686d954b7a61ab ]
linkwatch_event() grabs possibly very contended RTNL mutex.
system_wq is not suitable for such work.
Inspired by many noisy syzbot reports.
3 locks held by kworker/0:7/5266:
#0: ffff888015480948 ((wq_completion)events){+.+.}-{0:0}, at: process_one_work kernel/workqueue.c:3206 [inline] #0: ffff888015480948 ((wq_completion)events){+.+.}-{0:0}, at: process_scheduled_works+0x90a/0x1830 kernel/workqueue.c:3312 #1: ffffc90003f6fd00 ((linkwatch_work).work){+.+.}-{0:0}, at: process_one_work kernel/workqueue.c:3207 [inline] , at: process_scheduled_works+0x945/0x1830 kernel/workqueue.c:3312
#2: ffffffff8fa6f208 (rtnl_mutex){+.+.}-{3:3}, at: linkwatch_event+0xe/0x60 net/core/link_watch.c:276
--- net/core/link_watch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/core/link_watch.c +2 -2
@@ -130,9 +130,9 @@ static void linkwatch_schedule_work(int urgent)* override the existing timer. */ if (test_bit (LW_URGENT , &linkwatch_flags)) -mod_delayed_work (system_wq, &linkwatch_work,0 ); +mod_delayed_work (system_unbound_wq, &linkwatch_work,0 );else -schedule_delayed_work (&linkwatch_work, delay); +queue_delayed_work (system_unbound_wq, &linkwatch_work, delay); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 190/259 Bluetooth: l2cap: always unlock channel in l2cap_conless_channel()
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Antipov <[email protected]>
[ Upstream commit c531e63871c0b50c8c4e62c048535a08886fba3e ]
Add missing call to 'l2cap_chan_unlock()' on receive error handling path in 'l2cap_conless_channel()'.
--- net/bluetooth/l2cap_core.c | 1 + 1 file changed, 1 insertion(+)
net/bluetooth/l2cap_core.c +1 -0
@@ -7089,6 +7089,7 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,bt_cb (skb)->l2cap.psm = psm;if (!chan->ops->recv (chan, skb)) { +l2cap_chan_unlock (chan);l2cap_chan_put (chan);return ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 191/259 net: fec: Stop PPS on driver remove
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Csókás, Bence <[email protected]>
[ Upstream commit 8fee6d5ad5fa18c270eedb2a2cdf58dbadefb94b ]
PPS was not stopped in fec_ptp_stop(), called when the adapter was removed. Consequentially, you couldn't safely reload the driver with the PPS signal on.
--- drivers/net/ethernet/freescale/fec_ptp.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/freescale/fec_ptp.c +3 -0
@@ -635,6 +635,9 @@ void fec_ptp_stop(struct platform_device *pdev)struct net_device *ndev =platform_get_drvdata (pdev);struct fec_enet_private *fep =netdev_priv (ndev); +if (fep->pps_enable) +fec_ptp_enable_pps (fep,0 ); +cancel_delayed_work_sync (&fep->time_keep);if (fep->ptp_clock)ptp_clock_unregister (fep->ptp_clock);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 192/259 md/raid5: avoid BUG_ON() while continue reshape after reassembling
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
[ Upstream commit 305a5170dc5cf3d395bb4c4e9239bca6d0b54b49 ]
Currently, mdadm support --revert-reshape to abort the reshape while reassembling, as the test 07revert-grow. However, following BUG_ON() can be triggerred by the test:
kernel BUG at drivers/md/raid5.c:6278!
invalid opcode: 0000 [#1] PREEMPT SMP PTI
irq event stamp: 158985 CPU: 6 PID: 891 Comm: md0_reshape Not tainted 6.9.0-03335-g7592a0b0049a #94 RIP: 0010:reshape_request+0x3f1/0xe60 Call Trace: <TASK> raid5_sync_request+0x43d/0x550 md_do_sync+0xb7a/0x2110 md_thread+0x294/0x2b0 kthread+0x147/0x1c0 ret_from_fork+0x59/0x70 ret_from_fork_asm+0x1a/0x30 </TASK>
Root cause is that --revert-reshape update the raid_disks from 5 to 4, while reshape position is still set, and after reassembling the array, reshape position will be read from super block, then during reshape the checking of 'writepos' that is caculated by old reshape position will fail.
Fix this panic the easy way first, by converting the BUG_ON() to WARN_ON(), and stop the reshape if checkings fail.
Noted that mdadm must fix --revert-shape as well, and probably md/raid should enhance metadata validation as well, however this means reassemble will fail and there must be user tools to fix the wrong metadata.
--- drivers/md/raid5.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
drivers/md/raid5.c +13 -7
@@ -5821,7 +5821,9 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk safepos = conf->reshape_safe;sector_div (safepos, data_disks);if (mddev->reshape_backwards) { -BUG_ON (writepos < reshape_sectors); +if (WARN_ON (writepos < reshape_sectors)) +return MaxSector; + writepos -= reshape_sectors; readpos += reshape_sectors; safepos += reshape_sectors;
@@ -5839,14 +5841,18 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk* to set 'stripe_addr' which is where we will write to. */ if (mddev->reshape_backwards) { -BUG_ON (conf->reshape_progress ==0 ); +if (WARN_ON (conf->reshape_progress ==0 )) +return MaxSector; + stripe_addr = writepos; -BUG_ON ((mddev->dev_sectors & - ~((sector_t )reshape_sectors -1 )) - - reshape_sectors - stripe_addr - != sector_nr); +if (WARN_ON ((mddev->dev_sectors & + ~((sector_t )reshape_sectors -1 )) - + reshape_sectors - stripe_addr != sector_nr)) +return MaxSector; }else { -BUG_ON (writepos != sector_nr + reshape_sectors); +if (WARN_ON (writepos != sector_nr + reshape_sectors)) +return MaxSector; + stripe_addr = sector_nr; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 193/259 clocksource/drivers/sh_cmt: Address race condition for clock events
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Söderlund <[email protected]>
[ Upstream commit db19d3aa77612983a02bd223b3f273f896b243cf ]
There is a race condition in the CMT interrupt handler. In the interrupt handler the driver sets a driver private flag, FLAG_IRQCONTEXT. This flag is used to indicate any call to set_next_event() should not be directly propagated to the device, but instead cached. This is done as the interrupt handler itself reprograms the device when needed before it completes and this avoids this operation to take place twice.
It is unclear why this design was chosen, my suspicion is to allow the struct clock_event_device.event_handler callback, which is called while the FLAG_IRQCONTEXT is set, can update the next event without having to write to the device twice.
Unfortunately there is a race between when the FLAG_IRQCONTEXT flag is set and later cleared where the interrupt handler have already started to write the next event to the device. If set_next_event() is called in this window the value is only cached in the driver but not written. This leads to the board to misbehave, or worse lockup and produce a splat.
rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
rcu: 0-...!: (0 ticks this GP) idle=f5e0/0/0x0 softirq=519/519 fqs=0 (false positive?)
rcu: (detected by 1, t=6502 jiffies, g=-595, q=77 ncpus=2)
Sending NMI from CPU 1 to CPUs 0:
NMI backtrace for cpu 0
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.10.0-rc5-arm64-renesas-00019-g74a6f86eaf1c-dirty #20
Hardware name: Renesas Salvator-X 2nd version board based on r8a77965 (DT)
pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : tick_check_broadcast_expired+0xc/0x40
lr : cpu_idle_poll.isra.0+0x8c/0x168
sp : ffff800081c63d70
x29: ffff800081c63d70 x28: 00000000580000c8 x27: 00000000bfee5610
x26: 0000000000000027 x25: 0000000000000000 x24: 0000000000000000
x23: ffff00007fbb9100 x22: ffff8000818f1008 x21: ffff8000800ef07c
x20: ffff800081c79ec0 x19: ffff800081c70c28 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000000 x15: 0000ffffc2c717d8
x14: 0000000000000000 x13: ffff000009c18080 x12: ffff8000825f7fc0
x11: 0000000000000000 x10: ffff8000818f3cd4 x9 : 0000000000000028
x8 : ffff800081c79ec0 x7 : ffff800081c73000 x6 : 0000000000000000
x5 : 0000000000000000 x4 : ffff7ffffe286000 x3 : 0000000000000000
x2 : ffff7ffffe286000 x1 : ffff800082972900 x0 : ffff8000818f1008
Call trace:
tick_check_broadcast_expired+0xc/0x40
do_idle+0x9c/0x280
cpu_startup_entry+0x34/0x40
kernel_init+0x0/0x11c
do_one_initcall+0x0/0x260
__primary_switched+0x80/0x88
rcu: rcu_preempt kthread timer wakeup didn't happen for 6501 jiffies! g-595 f0x0 RCU_GP_WAIT_FQS(5) ->state=0x402
rcu: Possible timer handling issue on cpu=0 timer-softirq=262
rcu: rcu_preempt kthread starved for 6502 jiffies! g-595 f0x0 RCU_GP_WAIT_FQS(5) ->state=0x402 ->cpu=0
rcu: Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior.
rcu: RCU grace-period kthread stack dump:
task:rcu_preempt state:I stack:0 pid:15 tgid:15 ppid:2 flags:0x00000008
Call trace:
__switch_to+0xbc/0x100
__schedule+0x358/0xbe0
schedule+0x48/0x148
schedule_timeout+0xc4/0x138
rcu_gp_fqs_loop+0x12c/0x764
rcu_gp_kthread+0x208/0x298
kthread+0x10c/0x110
ret_from_fork+0x10/0x20The design have been part of the driver since it was first merged in early 2009. It becomes increasingly harder to trigger the issue the older kernel version one tries. It only takes a few boots on v6.10-rc5, while hundreds of boots are needed to trigger it on v5.10.
Close the race condition by using the CMT channel lock for the two competing sections. The channel lock was added to the driver after its initial design.
--- drivers/clocksource/sh_cmt.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/clocksource/sh_cmt.c +12 -1
@@ -510,6 +510,7 @@ static void sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)static irqreturn_t sh_cmt_interrupt (int irq,void *dev_id) {struct sh_cmt_channel *ch = dev_id; +unsigned long flags;/* clear flags */ sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) &
@@ -540,6 +541,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) ch->flags &= ~FLAG_SKIPEVENT ; +raw_spin_lock_irqsave (&ch->lock, flags); +if (ch->flags &FLAG_REPROGRAM ) { ch->flags &= ~FLAG_REPROGRAM ;sh_cmt_clock_event_program_verify (ch,1 );
@@ -552,6 +555,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) ch->flags &= ~FLAG_IRQCONTEXT ; +raw_spin_unlock_irqrestore (&ch->lock, flags); +return IRQ_HANDLED ; }
@@ -750,12 +755,18 @@ static int sh_cmt_clock_event_next(unsigned long delta, struct clock_event_device *ced) {struct sh_cmt_channel *ch =ced_to_sh_cmt (ced); +unsigned long flags;BUG_ON (!clockevent_state_oneshot (ced)); + +raw_spin_lock_irqsave (&ch->lock, flags); +if (likely (ch->flags &FLAG_IRQCONTEXT )) ch->next_match_value = delta -1 ;else -sh_cmt_set_next (ch, delta -1 ); +__sh_cmt_set_next (ch, delta -1 ); + +raw_spin_unlock_irqrestore (&ch->lock, flags);return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 194/259 ACPI: battery: create alarm sysfs attribute atomically
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
[ Upstream commit a231eed10ed5a290129fda36ad7bcc263c53ff7d ]
Let the power supply core register the attribute. This ensures that the attribute is created before the device is announced to userspace, avoid a race condition.
--- drivers/acpi/battery.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/acpi/battery.c +12 -4
@@ -681,12 +681,18 @@ static ssize_t acpi_battery_alarm_store(struct device *dev,return count; } -static const struct device_attribute alarm_attr = { +static struct device_attribute alarm_attr = { .attr = {.name ="alarm" , .mode =0644 }, .show = acpi_battery_alarm_show, .store = acpi_battery_alarm_store, }; +static struct attribute *acpi_battery_attrs[] = { + &alarm_attr.attr, +NULL +}; +ATTRIBUTE_GROUPS (acpi_battery); +/* * The Battery Hooking API *
@@ -823,7 +829,10 @@ static void __exit battery_hook_exit(void)static int sysfs_add_battery (struct acpi_battery *battery) { -struct power_supply_config psy_cfg = { .drv_data = battery, }; +struct power_supply_config psy_cfg = { + .drv_data = battery, + .attr_grp = acpi_battery_groups, + };bool full_cap_broken = false; if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) &&
@@ -868,7 +877,7 @@ static int sysfs_add_battery(struct acpi_battery *battery)return result; }battery_hook_add_battery (battery); -return device_create_file (&battery->bat->dev, &alarm_attr); +return 0 ; }static void sysfs_remove_battery (struct acpi_battery *battery)
@@ -879,7 +888,6 @@ static void sysfs_remove_battery(struct acpi_battery *battery)return ; }battery_hook_remove_battery (battery); -device_remove_file (&battery->bat->dev, &alarm_attr);power_supply_unregister (battery->bat); battery->bat =NULL ;mutex_unlock (&battery->sysfs_lock);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 195/259 ACPI: SBS: manage alarm sysfs attribute through psy core
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
[ Upstream commit 6bad28cfc30988a845fb3f59a99f4b8a4ce8fe95 ]
Let the power supply core register the attribute.
This ensures that the attribute is created before the device is announced to userspace, avoiding a race condition.
--- drivers/acpi/sbs.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
drivers/acpi/sbs.c +12 -11
@@ -80,7 +80,6 @@ struct acpi_battery {u16 spec;u8 id; u8 present:1; - u8 have_sysfs_alarm:1; };#define to_acpi_battery (x) power_supply_get_drvdata(x)
@@ -465,12 +464,18 @@ static ssize_t acpi_battery_alarm_store(struct device *dev,return count; } -static const struct device_attribute alarm_attr = { +static struct device_attribute alarm_attr = { .attr = {.name ="alarm" , .mode =0644 }, .show = acpi_battery_alarm_show, .store = acpi_battery_alarm_store, }; +static struct attribute *acpi_battery_attrs[] = { + &alarm_attr.attr, +NULL +}; +ATTRIBUTE_GROUPS (acpi_battery); +/* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */
@@ -512,7 +517,10 @@ static int acpi_battery_read(struct acpi_battery *battery)static int acpi_battery_add (struct acpi_sbs *sbs,int id) {struct acpi_battery *battery = &sbs->battery[id]; -struct power_supply_config psy_cfg = { .drv_data = battery, }; +struct power_supply_config psy_cfg = { + .drv_data = battery, + .attr_grp = acpi_battery_groups, + };int result; battery->id = id;
@@ -542,10 +550,6 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) goto end; } - result =device_create_file (&battery->bat->dev, &alarm_attr); -if (result) - goto end; - battery->have_sysfs_alarm =1 ; end: printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
@@ -557,11 +561,8 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id) {struct acpi_battery *battery = &sbs->battery[id]; -if (battery->bat) { -if (battery->have_sysfs_alarm) -device_remove_file (&battery->bat->dev, &alarm_attr); +if (battery->bat)power_supply_unregister (battery->bat); - } }static int acpi_charger_add (struct acpi_sbs *sbs)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 196/259 selftests/bpf: Fix send_signal test with nested CONFIG_PARAVIRT
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yonghong Song <[email protected]>
[ Upstream commit 7015843afcaf68c132784c89528dfddc0005e483 ]
Alexei reported that send_signal test may fail with nested CONFIG_PARAVIRT configs. In this particular case, the base VM is AMD with 166 cpus, and I run selftests with regular qemu on top of that and indeed send_signal test failed. I also tried with an Intel box with 80 cpus and there is no issue.
The main qemu command line includes:
-enable-kvm -smp 16 -cpu host
The failure log looks like:
$ ./test_progs -t send_signal [ 48.501588] watchdog: BUG: soft lockup - CPU#9 stuck for 26s! [test_progs:2225] [ 48.503622] Modules linked in: bpf_testmod(O) [ 48.503622] CPU: 9 PID: 2225 Comm: test_progs Tainted: G O 6.9.0-08561-g2c1713a8f1c9-dirty #69 [ 48.507629] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014 [ 48.511635] RIP: 0010:handle_softirqs+0x71/0x290 [ 48.511635] Code: [...] 10 0a 00 00 00 31 c0 65 66 89 05 d5 f4 fa 7e fb bb ff ff ff ff <49> c7 c2 cb [ 48.518527] RSP: 0018:ffffc90000310fa0 EFLAGS: 00000246 [ 48.519579] RAX: 0000000000000000 RBX: 00000000ffffffff RCX: 00000000000006e0 [ 48.522526] RDX: 0000000000000006 RSI: ffff88810791ae80 RDI: 0000000000000000 [ 48.523587] RBP: ffffc90000fabc88 R08: 00000005a0af4f7f R09: 0000000000000000 [ 48.525525] R10: 0000000561d2f29c R11: 0000000000006534 R12: 0000000000000280 [ 48.528525] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 [ 48.528525] FS: 00007f2f2885cd00(0000) GS:ffff888237c40000(0000) knlGS:0000000000000000 [ 48.531600] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 48.535520] CR2: 00007f2f287059f0 CR3: 0000000106a28002 CR4: 00000000003706f0 [ 48.537538] Call Trace: [ 48.537538] <IRQ> [ 48.537538] ? watchdog_timer_fn+0x1cd/0x250 [ 48.539590] ? lockup_detector_update_enable+0x50/0x50 [ 48.539590] ? __hrtimer_run_queues+0xff/0x280 [ 48.542520] ? hrtimer_interrupt+0x103/0x230 [ 48.544524] ? __sysvec_apic_timer_interrupt+0x4f/0x140 [ 48.545522] ? sysvec_apic_timer_interrupt+0x3a/0x90 [ 48.547612] ? asm_sysvec_apic_timer_interrupt+0x1a/0x20 [ 48.547612] ? handle_softirqs+0x71/0x290 [ 48.547612] irq_exit_rcu+0x63/0x80 [ 48.551585] sysvec_apic_timer_interrupt+0x75/0x90 [ 48.552521] </IRQ> [ 48.553529] <TASK> [ 48.553529] asm_sysvec_apic_timer_interrupt+0x1a/0x20 [ 48.555609] RIP: 0010:finish_task_switch.isra.0+0x90/0x260 [ 48.556526] Code: [...] 9f 58 0a 00 00 48 85 db 0f 85 89 01 00 00 4c 89 ff e8 53 d9 bd 00 fb 66 90 <4d> 85 ed 74 [ 48.562524] RSP: 0018:ffffc90000fabd38 EFLAGS: 00000282 [ 48.563589] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff83385620 [ 48.563589] RDX: ffff888237c73ae4 RSI: 0000000000000000 RDI: ffff888237c6fd00 [ 48.568521] RBP: ffffc90000fabd68 R08: 0000000000000000 R09: 0000000000000000 [ 48.569528] R10: 0000000000000001 R11: 0000000000000000 R12: ffff8881009d0000 [ 48.573525] R13: ffff8881024e5400 R14: ffff88810791ae80 R15: ffff888237c6fd00 [ 48.575614] ? finish_task_switch.isra.0+0x8d/0x260 [ 48.576523] __schedule+0x364/0xac0 [ 48.577535] schedule+0x2e/0x110 [ 48.578555] pipe_read+0x301/0x400 [ 48.579589] ? destroy_sched_domains_rcu+0x30/0x30 [ 48.579589] vfs_read+0x2b3/0x2f0 [ 48.579589] ksys_read+0x8b/0xc0 [ 48.583590] do_syscall_64+0x3d/0xc0 [ 48.583590] entry_SYSCALL_64_after_hwframe+0x4b/0x53 [ 48.586525] RIP: 0033:0x7f2f28703fa1 [ 48.587592] Code: [...] 00 00 00 0f 1f 44 00 00 f3 0f 1e fa 80 3d c5 23 14 00 00 74 13 31 c0 0f 05 <48> 3d 00 f0 [ 48.593534] RSP: 002b:00007ffd90f8cf88 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 [ 48.595589] RAX: ffffffffffffffda RBX: 00007ffd90f8d5e8 RCX: 00007f2f28703fa1 [ 48.595589] RDX: 0000000000000001 RSI: 00007ffd90f8cfb0 RDI: 0000000000000006 [ 48.599592] RBP: 00007ffd90f8d2f0 R08: 0000000000000064 R09: 0000000000000000 [ 48.602527] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 [ 48.603589] R13: 00007ffd90f8d608 R14: 00007f2f288d8000 R15: 0000000000f6bdb0 [ 48.605527] </TASK>
In the test, two processes are communicating through pipe. Further debugging with strace found that the above splat is triggered as read() syscall could not receive the data even if the corresponding write() syscall in another process successfully wrote data into the pipe.
The failed subtest is "send_signal_perf". The corresponding perf event has sample_period 1 and config PERF_COUNT_SW_CPU_CLOCK. sample_period 1 means every overflow event will trigger a call to the BPF program. So I suspect this may overwhelm the system. So I increased the sample_period to 100,000 and the test passed. The sample_period 10,000 still has the test failed.
In other parts of selftest, e.g., [1], sample_freq is used instead. So I decided to use sample_freq = 1,000 since the test can pass as well.
[1] https://lore.kernel.org/bpf/[email protected]/
--- tools/testing/selftests/bpf/prog_tests/send_signal.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/testing/selftests/bpf/prog_tests/send_signal.c +2 -1
@@ -174,7 +174,8 @@ static void test_send_signal_tracepoint(void)static void test_send_signal_perf (void ) {struct perf_event_attr attr = { - .sample_period =1 , + .freq =1 , + .sample_freq =1000 , .type =PERF_TYPE_SOFTWARE , .config =PERF_COUNT_SW_CPU_CLOCK , };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 197/259 PCI: Add Edimax Vendor ID to pci_ids.h
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: FUJITA Tomonori <[email protected]>
[ Upstream commit eee5528890d54b22b46f833002355a5ee94c3bb4 ]
Add the Edimax Vendor ID (0x1432) for an ethernet driver for Tehuti Networks TN40xx chips. This ID can be used for Realtek 8180 and Ralink rt28xx wireless drivers.
--- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+)
include/linux/pci_ids.h +2 -0
@@ -2136,6 +2136,8 @@#define PCI_VENDOR_ID_CHELSIO 0x1425 +#define PCI_VENDOR_ID_EDIMAX 0x1432 +#define PCI_VENDOR_ID_ADLINK 0x144a#define PCI_VENDOR_ID_SAMSUNG 0x144d
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 198/259 udf: prevent integer overflow in udf_bitmap_free_blocks()
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roman Smirnov <[email protected]>
[ Upstream commit 56e69e59751d20993f243fb7dd6991c4e522424c ]
An overflow may occur if the function is called with the last block and an offset greater than zero. It is necessary to add a check to avoid this.
Found by Linux Verification Center (linuxtesting.org) with Svace.
[JK: Make test cover also unalloc table freeing]
--- fs/udf/balloc.c | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-)
fs/udf/balloc.c +13 -23
@@ -22,6 +22,7 @@#include "udfdecl.h" #include <linux/bitops.h> +#include <linux/overflow.h> #include "udf_i.h" #include "udf_sb.h"
@@ -144,7 +145,6 @@ static void udf_bitmap_free_blocks(struct super_block *sb, {struct udf_sb_info *sbi =UDF_SB (sb);struct buffer_head *bh =NULL ; -struct udf_part_map *partmap;unsigned long block;unsigned long block_group;unsigned long bit;
@@ -153,19 +153,9 @@ static void udf_bitmap_free_blocks(struct super_block *sb,unsigned long overflow;mutex_lock (&sbi->s_alloc_mutex); - partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; -if (bloc->logicalBlockNum + count < count || - (bloc->logicalBlockNum + count) > partmap->s_partition_len) { -udf_debug ("%u < %d || %u + %u > %u\n" , - bloc->logicalBlockNum,0 , - bloc->logicalBlockNum, count, - partmap->s_partition_len); - goto error_return; - } - +/* We make sure this cannot overflow when mounting the filesystem */ block = bloc->logicalBlockNum + offset + (sizeof (struct spaceBitmapDesc ) <<3 ); - do { overflow = 0; block_group = block >> (sb->s_blocksize_bits + 3);
@@ -395,7 +385,6 @@ static void udf_table_free_blocks(struct super_block *sb, uint32_t count) {struct udf_sb_info *sbi =UDF_SB (sb); -struct udf_part_map *partmap;uint32_t start, end;uint32_t elen;struct kernel_lb_addr eloc;
@@ -404,16 +393,6 @@ static void udf_table_free_blocks(struct super_block *sb,struct udf_inode_info *iinfo;mutex_lock (&sbi->s_alloc_mutex); - partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; -if (bloc->logicalBlockNum + count < count || - (bloc->logicalBlockNum + count) > partmap->s_partition_len) { -udf_debug ("%u < %d || %u + %u > %u\n" , - bloc->logicalBlockNum,0 , - bloc->logicalBlockNum, count, - partmap->s_partition_len); - goto error_return; - } - iinfo =UDF_I (table);udf_add_free_space (sb, sbi->s_partition, count);
@@ -688,6 +667,17 @@ void udf_free_blocks(struct super_block *sb, struct inode *inode, {uint16_t partition = bloc->partitionReferenceNum;struct udf_part_map *map = &UDF_SB (sb)->s_partmaps[partition]; +uint32_t blk; + +if (check_add_overflow (bloc->logicalBlockNum, offset, &blk) || +check_add_overflow (blk, count, &blk) || + bloc->logicalBlockNum + count > map->s_partition_len) { +udf_debug ("Invalid request to free blocks: (%d, %u), off %u, " +"len %u, partition len %u\n" , + partition, bloc->logicalBlockNum, offset, count, + map->s_partition_len); +return ; + }if (map->s_partition_flags &UDF_PART_FLAG_UNALLOC_BITMAP ) { udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 199/259 wifi: nl80211: dont give key data to userspace
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit a7e5793035792cc46a1a4b0a783655ffa897dfe9 ]
When a key is requested by userspace, there's really no need to include the key data, the sequence counter is really what userspace needs in this case. The fact that it's included is just a historic quirk.
Remove the key data.
--- net/wireless/nl80211.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
net/wireless/nl80211.c +2 -8
@@ -3723,10 +3723,7 @@ static void get_key_callback(void *c, struct key_params *params)struct nlattr *key;struct get_key_cookie *cookie = c; - if ((params->key && - nla_put(cookie->msg, NL80211_ATTR_KEY_DATA, - params->key_len, params->key)) || - (params->seq && + if ((params->seq && nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ, params->seq_len, params->seq)) || (params->cipher &&
@@ -3738,10 +3735,7 @@ static void get_key_callback(void *c, struct key_params *params)if (!key) goto nla_put_failure; - if ((params->key && - nla_put(cookie->msg, NL80211_KEY_DATA, - params->key_len, params->key)) || - (params->seq && + if ((params->seq && nla_put(cookie->msg, NL80211_KEY_SEQ, params->seq_len, params->seq)) || (params->cipher &&
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 200/259 btrfs: fix bitmap leak when loading free space cache on duplicate entry
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 320d8dc612660da84c3b70a28658bb38069e5a9a ]
If we failed to link a free space entry because there's already a conflicting entry for the same offset, we free the free space entry but we don't free the associated bitmap that we had just allocated before. Fix that by freeing the bitmap before freeing the entry.
--- fs/btrfs/free-space-cache.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/free-space-cache.c +1 -0
@@ -788,6 +788,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,spin_unlock (&ctl->tree_lock);btrfs_err (fs_info,"Duplicate entries in free space cache, dumping" ); +kmem_cache_free (btrfs_free_space_bitmap_cachep, e->bitmap);kmem_cache_free (btrfs_free_space_cachep, e); goto free_cache; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 201/259 drm/amdgpu: Fix the null pointer dereference to ras_manager
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Jun <[email protected]>
[ Upstream commit 4c11d30c95576937c6c35e6f29884761f2dddb43 ]
Check ras_manager before using it
--- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +5 -2
@@ -1053,12 +1053,15 @@ static void amdgpu_ras_interrupt_process_handler(struct work_struct *work)int amdgpu_ras_interrupt_dispatch (struct amdgpu_device *adev,struct ras_dispatch_if *info) { -struct ras_manager *obj =amdgpu_ras_find_obj (adev, &info->head); -struct ras_ih_data *data = &obj->ih_data; +struct ras_manager *obj; +struct ras_ih_data *data; + obj =amdgpu_ras_find_obj (adev, &info->head);if (!obj)return -EINVAL ; + data = &obj->ih_data; +if (data->inuse ==0 )return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 202/259 media: uvcvideo: Ignore empty TS packets
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <[email protected]>
[ Upstream commit 5cd7c25f6f0576073b3d03bc4cfb1e8ca63a1195 ]
Some SunplusIT cameras took a borderline interpretation of the UVC 1.5 standard, and fill the PTS and SCR fields with invalid data if the package does not contain data.
"STC must be captured when the first video data of a video frame is put on the USB bus."
Some SunplusIT devices send, e.g.,
buffer: 0xa7755c00 len 000012 header:0x8c stc 00000000 sof 0000 pts 00000000
buffer: 0xa7755c00 len 000012 header:0x8c stc 00000000 sof 0000 pts 00000000
buffer: 0xa7755c00 len 000668 header:0x8c stc 73779dba sof 070c pts 7376d37a
While the UVC specification meant that the first two packets shouldn't have had the SCR bit set in the header.
This borderline/buggy interpretation has been implemented in a variety of devices, from directly SunplusIT and from other OEMs that rebrand SunplusIT products. So quirking based on VID:PID will be problematic.
All the affected modules have the following extension unit:
VideoControl Interface Descriptor:
guidExtensionCode {82066163-7050-ab49-b8cc-b3855e8d221d}
But the vendor plans to use that GUID in the future and fix the bug, this means that we should use heuristic to figure out the broken packets.
This patch takes care of this.
lsusb of one of the affected cameras:
Bus 001 Device 003: ID 1bcf:2a01 Sunplus Innovation Technology Inc. Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.01
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 ?
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x1bcf Sunplus Innovation Technology Inc.
idProduct 0x2a01
bcdDevice 0.02
iManufacturer 1 SunplusIT Inc iProduct 2 HanChen Wise Camera iSerial 3 01.00.00 bNumConfigurations 1
--- drivers/media/usb/uvc/uvc_video.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-)
drivers/media/usb/uvc/uvc_video.c +30 -1
@@ -468,6 +468,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,ktime_t time;u16 host_sof;u16 dev_sof; +u32 dev_stc;switch (data[1 ] & (UVC_STREAM_PTS |UVC_STREAM_SCR )) {case UVC_STREAM_PTS |UVC_STREAM_SCR :
@@ -512,6 +513,34 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,if (dev_sof == stream->clock.last_sof)return ; + dev_stc =get_unaligned_le32 (&data[header_size -6 ]); + +/* +* STC (Source Time Clock) is the clock used by the camera. The UVC 1.5 +* standard states that it "must be captured when the first video data +* of a video frame is put on the USB bus". This is generally understood +* as requiring devices to clear the payload header's SCR bit before +* the first packet containing video data. +* +* Most vendors follow that interpretation, but some (namely SunplusIT +* on some devices) always set the `UVC_STREAM_SCR` bit, fill the SCR +* field with 0's,and expect that the driver only processes the SCR if +* there is data in the packet. +* +* Ignore all the hardware timestamp information if we haven't received +* any data for this frame yet, the packet contains no data, and both +* STC and SOF are zero. This heuristics should be safe on compliant +* devices. This should be safe with compliant devices, as in the very +* unlikely case where a UVC 1.1 device would send timing information +* only before the first packet containing data, and both STC and SOF +* happen to be zero for a particular frame, we would only miss one +* clock sample from many and the clock recovery algorithm wouldn't +* suffer from this condition. +*/ +if (buf && buf->bytesused ==0 && len == header_size && + dev_stc ==0 && dev_sof ==0 ) +return ; + stream->clock.last_sof = dev_sof; host_sof =usb_get_current_frame_number (stream->dev->udev);
@@ -549,7 +578,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,spin_lock_irqsave (&stream->clock.lock, flags); sample = &stream->clock.samples[stream->clock.head]; - sample->dev_stc =get_unaligned_le32 (&data[header_size -6 ]); + sample->dev_stc = dev_stc; sample->dev_sof = dev_sof; sample->host_sof = host_sof; sample->host_time = time;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 203/259 media: uvcvideo: Fix the bandwdith quirk on USB 3.x
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Pecio <[email protected]>
[ Upstream commit 9e3d55fbd160b3ca376599a68b4cddfdc67d4153 ]
The bandwidth fixup quirk doesn't know that SuperSpeed exists and has the same 8 service intervals per millisecond as High Speed, hence its calculations are wrong.
Assume that all speeds from HS up use 8 intervals per millisecond.
No further changes are needed, updated code has been confirmed to work with all speeds from FS to SS.
--- drivers/media/usb/uvc/uvc_video.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/media/usb/uvc/uvc_video.c +3 -3
@@ -207,13 +207,13 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,/* Compute a bandwidth estimation by multiplying the frame * size by the number of video frames per second, divide the * result by the number of USB frames (or micro-frames for -* high-speed devices) per second and add the UVC header size -* (assumed to be 12 bytes long). +* high- and super-speed devices) per second and add the UVC +* header size (assumed to be 12 bytes long). */ bandwidth = frame->wWidth * frame->wHeight /8 * format->bpp; bandwidth *=10000000 / interval +1 ; bandwidth /=1000 ; -if (stream->dev->udev->speed ==USB_SPEED_HIGH ) +if (stream->dev->udev->speed >=USB_SPEED_HIGH ) bandwidth /=8 ; bandwidth +=12 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 204/259 jbd2: avoid memleak in jbd2_journal_write_metadata_buffer
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kemeng Shi <[email protected]>
[ Upstream commit cc102aa24638b90e04364d64e4f58a1fa91a1976 ]
The new_bh is from alloc_buffer_head, we should call free_buffer_head to free it in error case.
--- fs/jbd2/journal.c | 1 + 1 file changed, 1 insertion(+)
fs/jbd2/journal.c +1 -0
@@ -408,6 +408,7 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, tmp =jbd2_alloc (bh_in->b_size,GFP_NOFS );if (!tmp) {brelse (new_bh); +free_buffer_head (new_bh);return -ENOMEM ; }jbd_lock_bh_state (bh_in);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 205/259 s390/sclp: Prevent release of buffer in I/O
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Oberparleiter <[email protected]>
[ Upstream commit bf365071ea92b9579d5a272679b74052a5643e35 ]
When a task waiting for completion of a Store Data operation is interrupted, an attempt is made to halt this operation. If this attempt fails due to a hardware or firmware problem, there is a chance that the SCLP facility might store data into buffers referenced by the original operation at a later time.
Handle this situation by not releasing the referenced data buffers if the halt attempt fails. For current use cases, this might result in a leak of few pages of memory in case of a rare hardware/firmware malfunction.
--- drivers/s390/char/sclp_sd.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/s390/char/sclp_sd.c +8 -2
@@ -319,8 +319,14 @@ static int sclp_sd_store_data(struct sclp_sd_data *result, u8 di) &esize);if (rc) {/* Cancel running request if interrupted */ -if (rc == -ERESTARTSYS ) -sclp_sd_sync (page,SD_EQ_HALT , di,0 ,0 ,NULL ,NULL ); +if (rc == -ERESTARTSYS ) { +if (sclp_sd_sync (page,SD_EQ_HALT , di,0 ,0 ,NULL ,NULL )) { +pr_warn ("Could not stop Store Data request - leaking at least %zu bytes\n" , + (size_t )dsize *PAGE_SIZE ); + data =NULL ; + asce =0 ; + } + }vfree (data); goto out; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 206/259 SUNRPC: Fix a race to wake a sync task
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Coddington <[email protected]>
[ Upstream commit ed0172af5d6fc07d1b40ca82f5ca3979300369f7 ]
We've observed NFS clients with sync tasks sleeping in __rpc_execute waiting on RPC_TASK_QUEUED that have not responded to a wake-up from rpc_make_runnable(). I suspect this problem usually goes unnoticed, because on a busy client the task will eventually be re-awoken by another task completion or xprt event. However, if the state manager is draining the slot table, a sync task missing a wake-up can result in a hung client.
We've been able to prove that the waker in rpc_make_runnable() successfully calls wake_up_bit() (ie- there's no race to tk_runstate), but the wake_up_bit() call fails to wake the waiter. I suspect the waker is missing the load of the bit's wait_queue_head, so waitqueue_active() is false. There are some very helpful comments about this problem above wake_up_bit(), prepare_to_wait(), and waitqueue_active().
Fix this by inserting smp_mb__after_atomic() before the wake_up_bit(), which pairs with prepare_to_wait() calling set_current_state().
--- net/sunrpc/sched.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/sunrpc/sched.c +3 -1
@@ -368,8 +368,10 @@ static void rpc_make_runnable(struct workqueue_struct *wq,if (RPC_IS_ASYNC (task)) {INIT_WORK (&task->u.tk_work, rpc_async_schedule);queue_work (wq, &task->u.tk_work); - }else + }else { +smp_mb__after_atomic ();wake_up_bit (&task->tk_runstate,RPC_TASK_QUEUED ); + } }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 207/259 ext4: fix wrong unit use in ext4_mb_find_by_goal
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kemeng Shi <[email protected]>
[ Upstream commit 99c515e3a860576ba90c11acbc1d6488dfca6463 ]
We need start in block unit while fe_start is in cluster unit. Use ext4_grp_offs_to_block helper to convert fe_start to get start in block unit.
--- fs/ext4/mballoc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/ext4/mballoc.c +1 -2
@@ -1850,8 +1850,7 @@ int ext4_mb_find_by_goal(struct ext4_allocation_context *ac,if (max >= ac->ac_g_ex.fe_len && ac->ac_g_ex.fe_len == sbi->s_stripe) {ext4_fsblk_t start; - start =ext4_group_first_block_no (ac->ac_sb, e4b->bd_group) + - ex.fe_start; + start =ext4_grp_offs_to_block (ac->ac_sb, &ex);/* use do_div to get remainder (would be 64-bit modulo) */ if (do_div (start, sbi->s_stripe) ==0 ) { ac->ac_found++;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 208/259 arm64: cpufeature: Force HWCAP to be based on the sysreg visible to user-space
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Morse <[email protected]>
[ Upstream commit 237405ebef580a7352a52129b2465c117145eafa ]
arm64 advertises hardware features to user-space via HWCAPs, and by emulating access to the CPUs id registers. The cpufeature code has a sanitised system-wide view of an id register, and a sanitised user-space view of an id register, where some features use their 'safe' value instead of the hardware value.
It is currently possible for a HWCAP to be advertised where the user-space view of the id register does not show the feature as supported. Erratum workaround need to remove both the HWCAP, and the feature from the user-space view of the id register. This involves duplicating the code, and spreading it over cpufeature.c and cpu_errata.c.
Make the HWCAP code use the user-space view of id registers. This ensures the values never diverge, and allows erratum workaround to remove HWCAP by modifying the user-space view of the id register.
--- arch/arm64/kernel/cpufeature.c | 36 +++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-)
arch/arm64/kernel/cpufeature.c +29 -7
@@ -875,17 +875,39 @@ feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry)return val >= entry->min_field_value; } -static bool -has_cpuid_feature (const struct arm64_cpu_capabilities *entry,int scope) +static u64 +read_scoped_sysreg (const struct arm64_cpu_capabilities *entry,int scope) { -u64 val; -WARN_ON (scope ==SCOPE_LOCAL_CPU &&preemptible ());if (scope ==SCOPE_SYSTEM ) - val =read_sanitised_ftr_reg (entry->sys_reg); +return read_sanitised_ftr_reg (entry->sys_reg);else - val =__read_sysreg_by_encoding (entry->sys_reg); +return __read_sysreg_by_encoding (entry->sys_reg); +} +static bool +has_user_cpuid_feature (const struct arm64_cpu_capabilities *entry,int scope) +{ +int mask; +struct arm64_ftr_reg *regp; +u64 val =read_scoped_sysreg (entry, scope); + + regp =get_arm64_ftr_reg (entry->sys_reg); +if (!regp) +return false; + + mask =cpuid_feature_extract_unsigned_field (regp->user_mask, + entry->field_pos); +if (!mask) +return false; + +return feature_matches (val, entry); +} + +static bool +has_cpuid_feature (const struct arm64_cpu_capabilities *entry,int scope) +{ +u64 val =read_scoped_sysreg (entry, scope);return feature_matches (val, entry); }
@@ -1593,7 +1615,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = { };#define HWCAP_CPUID_MATCH (reg, field, s, min_value) \ - .matches = has_cpuid_feature, \ + .matches = has_user_cpuid_feature, \ .sys_reg = reg, \ .field_pos = field, \ .sign = s, \
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 209/259 arm64: Add Neoverse-V2 part
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Besar Wicaksono <[email protected]>
[ Upstream commit f4d9d9dcc70b96b5e5d7801bd5fbf8491b07b13d ]
Add the part number and MIDR for Neoverse-V2
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -80,6 +80,7 @@#define ARM_CPU_PART_CORTEX_X2 0xD48#define ARM_CPU_PART_NEOVERSE_N2 0xD49#define ARM_CPU_PART_CORTEX_A78C 0xD4B +#define ARM_CPU_PART_NEOVERSE_V2 0xD4F#define APM_CPU_PART_POTENZA 0x000
@@ -121,6 +122,7 @@#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) +#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2)#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 210/259 arm64: cputype: Add Cortex-X4 definitions
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
[ Upstream commit 02a0a04676fa7796d9cbc9eb5ca120aaa194d2dd ]
Add cputype definitions for Cortex-X4. These will be used for errata detection in subsequent patches.
These values can be found in Table B-249 ("MIDR_EL1 bit descriptions") in issue 0002-05 of the Cortex-X4 TRM, which can be found at:
https://developer.arm.com/documentation/102484/0002/?lang=en
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -81,6 +81,7 @@#define ARM_CPU_PART_NEOVERSE_N2 0xD49#define ARM_CPU_PART_CORTEX_A78C 0xD4B#define ARM_CPU_PART_NEOVERSE_V2 0xD4F +#define ARM_CPU_PART_CORTEX_X4 0xD82#define APM_CPU_PART_POTENZA 0x000
@@ -123,6 +124,7 @@#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2) +#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4)#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 211/259 arm64: cputype: Add Neoverse-V3 definitions
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
[ Upstream commit 0ce85db6c2141b7ffb95709d76fc55a27ff3cdc1 ]
Add cputype definitions for Neoverse-V3. These will be used for errata detection in subsequent patches.
These values can be found in Table B-249 ("MIDR_EL1 bit descriptions") in issue 0001-04 of the Neoverse-V3 TRM, which can be found at:
https://developer.arm.com/documentation/107734/0001/?lang=en
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -82,6 +82,7 @@#define ARM_CPU_PART_CORTEX_A78C 0xD4B#define ARM_CPU_PART_NEOVERSE_V2 0xD4F#define ARM_CPU_PART_CORTEX_X4 0xD82 +#define ARM_CPU_PART_NEOVERSE_V3 0xD84#define APM_CPU_PART_POTENZA 0x000
@@ -125,6 +126,7 @@#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2)#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4) +#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 212/259 arm64: errata: Add workaround for Arm errata 3194386 and 3312417
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
[ Upstream commit 7187bb7d0b5c7dfa18ca82e9e5c75e13861b1d88 ]
Cortex-X4 and Neoverse-V3 suffer from errata whereby an MSR to the SSBS special-purpose register does not affect subsequent speculative instructions, permitting speculative store bypassing for a window of time. This is described in their Software Developer Errata Notice (SDEN) documents:
* Cortex-X4 SDEN v8.0, erratum 3194386:
https://developer.arm.com/documentation/SDEN-2432808/0800/
* Neoverse-V3 SDEN v6.0, erratum 3312417:
https://developer.arm.com/documentation/SDEN-2891958/0600/
To workaround these errata, it is necessary to place a speculation barrier (SB) after MSR to the SSBS special-purpose register. This patch adds the requisite SB after writes to SSBS within the kernel, and hides the presence of SSBS from EL0 such that userspace software which cares about SSBS will manipulate this via prctl(PR_GET_SPECULATION_CTRL, ...).
--- Documentation/arm64/silicon-errata.rst | 4 +++ arch/arm64/Kconfig | 41 ++++++++++++++++++++++++++ arch/arm64/include/asm/cpucaps.h | 3 +- arch/arm64/kernel/cpu_errata.c | 32 ++++++++++++++++++++ arch/arm64/kernel/cpufeature.c | 12 ++++++++ 5 files changed, 91 insertions(+), 1 deletion(-)
Documentation/arm64/silicon-errata.rst +4 -0
@@ -88,12 +88,16 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X4 | #3194386 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1349291 | N/A | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3312417 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-500 | #841119,826419 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
arch/arm64/Kconfig +41 -0
47 lines not on this page · raw message
arch/arm64/include/asm/cpucaps.h +2 -1
@@ -57,7 +57,8 @@#define ARM64_WORKAROUND_1542419 47#define ARM64_SPECTRE_BHB 48#define ARM64_WORKAROUND_1742098 49 +#define ARM64_WORKAROUND_SPECULATIVE_SSBS 50 -#define ARM64_NCAPS 50 +#define ARM64_NCAPS 51#endif /* __ASM_CPUCAPS_H */
arch/arm64/kernel/cpu_errata.c +32 -0
@@ -372,6 +372,19 @@ void arm64_set_ssbd_mitigation(bool state) asm volatile(SET_PSTATE_SSBS(0)); else asm volatile(SET_PSTATE_SSBS(1)); + +/* +* SSBS is self-synchronizing and is intended to affect +* subsequent speculative instructions, but some CPUs can +* speculate with a stale value of SSBS. +* +* Mitigate this with an unconditional speculation barrier, as +* CPUs could mis-speculate branches and bypass a conditional +* barrier. +*/ +if (IS_ENABLED (CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS )) +spec_bar (); +return ; }
@@ -828,6 +841,18 @@ static struct midr_range broken_aarch32_aes[] = { };#endif +#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS +static const struct midr_range erratum_spec_ssbs_list[] = { +#ifdef CONFIG_ARM64_ERRATUM_3194386 +MIDR_ALL_VERSIONS (MIDR_CORTEX_X4 ), +#endif +#ifdef CONFIG_ARM64_ERRATUM_3312417 +MIDR_ALL_VERSIONS (MIDR_NEOVERSE_V3 ), +#endif + {} +}; +#endif + const struct arm64_cpu_capabilities arm64_errata[] = {#ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE {
@@ -1016,6 +1041,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = { CAP_MIDR_RANGE_LIST(broken_aarch32_aes), .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, }, +#endif +#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS + { + .desc = "ARM errata 3194386, 3312417", + .capability = ARM64_WORKAROUND_SPECULATIVE_SSBS, + ERRATA_MIDR_RANGE_LIST(erratum_spec_ssbs_list), + }, #endif { }
arch/arm64/kernel/cpufeature.c +12 -0
@@ -1303,6 +1303,17 @@ static bool can_use_gic_priorities(const struct arm64_cpu_capabilities *entry, }#endif +static void user_feature_fixup (void ) +{ +if (cpus_have_cap (ARM64_WORKAROUND_SPECULATIVE_SSBS )) { +struct arm64_ftr_reg *regp; + + regp =get_arm64_ftr_reg (SYS_ID_AA64PFR1_EL1 ); +if (regp) + regp->user_mask &= ~GENMASK (7 ,4 );/* SSBS */ + } +} +static void elf_hwcap_fixup (void ) {#ifdef CONFIG_ARM64_ERRATUM_1742098
@@ -2132,6 +2143,7 @@ void __init setup_cpu_features(void)setup_system_capabilities ();mark_const_caps_ready (); +user_feature_fixup ();setup_elf_hwcaps (arm64_elf_hwcaps);if (system_supports_32bit_el0 ()) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 213/259 arm64: cputype: Add Cortex-X3 definitions
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
[ Upstream commit be5a6f238700f38b534456608588723fba96c5ab ]
Add cputype definitions for Cortex-X3. These will be used for errata detection in subsequent patches.
These values can be found in Table A-263 ("MIDR_EL1 bit descriptions") in issue 07 of the Cortex-X3 TRM, which can be found at:
https://developer.arm.com/documentation/101593/0102/?lang=en
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -80,6 +80,7 @@#define ARM_CPU_PART_CORTEX_X2 0xD48#define ARM_CPU_PART_NEOVERSE_N2 0xD49#define ARM_CPU_PART_CORTEX_A78C 0xD4B +#define ARM_CPU_PART_CORTEX_X3 0xD4E#define ARM_CPU_PART_NEOVERSE_V2 0xD4F#define ARM_CPU_PART_CORTEX_X4 0xD82#define ARM_CPU_PART_NEOVERSE_V3 0xD84
@@ -124,6 +125,7 @@#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) +#define MIDR_CORTEX_X3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X3)#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2)#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4)#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 214/259 arm64: cputype: Add Cortex-A720 definitions
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
[ Upstream commit add332c40328cf06fe35e4b3cde8ec315c4629e5 ]
Add cputype definitions for Cortex-A720. These will be used for errata detection in subsequent patches.
These values can be found in Table A-186 ("MIDR_EL1 bit descriptions") in issue 0002-05 of the Cortex-A720 TRM, which can be found at:
https://developer.arm.com/documentation/102530/0002/?lang=en
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -82,6 +82,7 @@#define ARM_CPU_PART_CORTEX_A78C 0xD4B#define ARM_CPU_PART_CORTEX_X3 0xD4E#define ARM_CPU_PART_NEOVERSE_V2 0xD4F +#define ARM_CPU_PART_CORTEX_A720 0xD81#define ARM_CPU_PART_CORTEX_X4 0xD82#define ARM_CPU_PART_NEOVERSE_V3 0xD84
@@ -127,6 +128,7 @@#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)#define MIDR_CORTEX_X3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X3)#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2) +#define MIDR_CORTEX_A720 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720)#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4)#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 215/259 arm64: cputype: Add Cortex-X925 definitions
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
[ Upstream commit fd2ff5f0b320f418288e7a1f919f648fbc8a0dfc ]
Add cputype definitions for Cortex-X925. These will be used for errata detection in subsequent patches.
These values can be found in Table A-285 ("MIDR_EL1 bit descriptions") in issue 0001-05 of the Cortex-X925 TRM, which can be found at:
https://developer.arm.com/documentation/102807/0001/?lang=en
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -85,6 +85,7 @@#define ARM_CPU_PART_CORTEX_A720 0xD81#define ARM_CPU_PART_CORTEX_X4 0xD82#define ARM_CPU_PART_NEOVERSE_V3 0xD84 +#define ARM_CPU_PART_CORTEX_X925 0xD85#define APM_CPU_PART_POTENZA 0x000
@@ -131,6 +132,7 @@#define MIDR_CORTEX_A720 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720)#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4)#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3) +#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 216/259 arm64: errata: Unify speculative SSBS errata logic
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
[ Upstream commit ec768766608092087dfb5c1fc45a16a6f524dee2 ]
Cortex-X4 erratum 3194386 and Neoverse-V3 erratum 3312417 are identical, with duplicate Kconfig text and some unsightly ifdeffery. While we try to share code behind CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS, having separate options results in a fair amount of boilerplate code, and this will only get worse as we expand the set of affected CPUs.
To reduce this boilerplate, unify the two behind a common Kconfig option. This removes the duplicate text and Kconfig logic, and removes the need for the intermediate ARM64_WORKAROUND_SPECULATIVE_SSBS option. The set of affected CPUs is described as a list so that this can easily be extended.
I've used ARM64_ERRATUM_3194386 (matching the Neoverse-V3 erratum ID) as the common option, matching the way we use ARM64_ERRATUM_1319367 to cover Cortex-A57 erratum 1319537 and Cortex-A72 erratum 1319367.
--- Documentation/arm64/silicon-errata.rst | 2 +- arch/arm64/Kconfig | 28 ++++---------------------- arch/arm64/kernel/cpu_errata.c | 10 +++------ 3 files changed, 8 insertions(+), 32 deletions(-)
Documentation/arm64/silicon-errata.rst +1 -1
@@ -96,7 +96,7 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 | +----------------+-----------------+-----------------+-----------------------------+ -| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3312417 | +| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-500 | #841119,826419 | N/A | +----------------+-----------------+-----------------+-----------------------------+
arch/arm64/Kconfig +4 -24
@@ -590,34 +590,14 @@ config ARM64_ERRATUM_1742098 If unsure, say Y. -config ARM64_WORKAROUND_SPECULATIVE_SSBS - bool - config ARM64_ERRATUM_3194386 - bool "Cortex-X4: 3194386: workaround for MSR SSBS not self-synchronizing" - select ARM64_WORKAROUND_SPECULATIVE_SSBS + bool "Cortex-X4/Neoverse-V3: workaround for MSR SSBS not self-synchronizing" default y help - This option adds the workaround for ARM Cortex-X4 erratum 3194386. - - On affected cores "MSR SSBS, #0" instructions may not affect - subsequent speculative instructions, which may permit unexepected - speculative store bypassing. - - Work around this problem by placing a speculation barrier after - kernel changes to SSBS. The presence of the SSBS special-purpose - register is hidden from hwcaps and EL0 reads of ID_AA64PFR1_EL1, such - that userspace will use the PR_SPEC_STORE_BYPASS prctl to change - SSBS. + This option adds the workaround for the following errata: - If unsure, say Y. - -config ARM64_ERRATUM_3312417 - bool "Neoverse-V3: 3312417: workaround for MSR SSBS not self-synchronizing" - select ARM64_WORKAROUND_SPECULATIVE_SSBS - default y - help - This option adds the workaround for ARM Neoverse-V3 erratum 3312417. + * ARM Cortex-X4 erratum 3194386 + * ARM Neoverse-V3 erratum 3312417 On affected cores "MSR SSBS, #0" instructions may not affect subsequent speculative instructions, which may permit unexepected
arch/arm64/kernel/cpu_errata.c +3 -7
@@ -382,7 +382,7 @@ void arm64_set_ssbd_mitigation(bool state)* CPUs could mis-speculate branches and bypass a conditional * barrier. */ -if (IS_ENABLED (CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS )) +if (IS_ENABLED (CONFIG_ARM64_ERRATUM_3194386 ))spec_bar ();return ;
@@ -841,14 +841,10 @@ static struct midr_range broken_aarch32_aes[] = { };#endif -#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS -static const struct midr_range erratum_spec_ssbs_list[] = {#ifdef CONFIG_ARM64_ERRATUM_3194386 +static const struct midr_range erratum_spec_ssbs_list[] = {MIDR_ALL_VERSIONS (MIDR_CORTEX_X4 ), -#endif -#ifdef CONFIG_ARM64_ERRATUM_3312417MIDR_ALL_VERSIONS (MIDR_NEOVERSE_V3 ), -#endif {} };#endif
@@ -1042,7 +1038,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = { .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, },#endif -#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS +#ifdef CONFIG_ARM64_ERRATUM_3194386 { .desc = "ARM errata 3194386, 3312417", .capability = ARM64_WORKAROUND_SPECULATIVE_SSBS,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 217/259 arm64: errata: Expand speculative SSBS workaround
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
[ Upstream commit 75b3c43eab594bfbd8184ec8ee1a6b820950819a ]
A number of Arm Ltd CPUs suffer from errata whereby an MSR to the SSBS special-purpose register does not affect subsequent speculative instructions, permitting speculative store bypassing for a window of time.
We worked around this for Cortex-X4 and Neoverse-V3, in commit:
7187bb7d0b5c7dfa ("arm64: errata: Add workaround for Arm errata 3194386 and 3312417")
... as per their Software Developer Errata Notice (SDEN) documents:
* Cortex-X4 SDEN v8.0, erratum 3194386:
https://developer.arm.com/documentation/SDEN-2432808/0800/
* Neoverse-V3 SDEN v6.0, erratum 3312417:
https://developer.arm.com/documentation/SDEN-2891958/0600/
Since then, similar errata have been published for a number of other Arm Ltd CPUs, for which the mitigation is the same. This is described in their respective SDEN documents:
* Cortex-A710 SDEN v19.0, errataum 3324338
https://developer.arm.com/documentation/SDEN-1775101/1900/?lang=en
* Cortex-A720 SDEN v11.0, erratum 3456091
https://developer.arm.com/documentation/SDEN-2439421/1100/?lang=en
* Cortex-X2 SDEN v19.0, erratum 3324338
https://developer.arm.com/documentation/SDEN-1775100/1900/?lang=en
* Cortex-X3 SDEN v14.0, erratum 3324335
https://developer.arm.com/documentation/SDEN-2055130/1400/?lang=en
* Cortex-X925 SDEN v8.0, erratum 3324334
https://developer.arm.com/documentation/109108/800/?lang=en
* Neoverse-N2 SDEN v17.0, erratum 3324339
https://developer.arm.com/documentation/SDEN-1982442/1700/?lang=en
* Neoverse-V2 SDEN v9.0, erratum 3324336
https://developer.arm.com/documentation/SDEN-2332927/900/?lang=en
Note that due to shared design lineage, some CPUs share the same erratum number.
Add these to the existing mitigation under CONFIG_ARM64_ERRATUM_3194386. As listing all of the erratum IDs in the runtime description would be unwieldy, this is reduced to:
"SSBS not fully self-synchronizing"
... matching the description of the errata in all of the SDENs.
--- Documentation/arm64/silicon-errata.rst | 14 ++++++++++++++ arch/arm64/Kconfig | 9 ++++++++- arch/arm64/kernel/cpu_errata.c | 9 ++++++++- 3 files changed, 30 insertions(+), 2 deletions(-)
Documentation/arm64/silicon-errata.rst +14 -0
@@ -88,14 +88,28 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X2 | #3324338 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X3 | #3324335 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-X4 | #3194386 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X925 | #3324334 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1349291 | N/A | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-500 | #841119,826419 | N/A |
arch/arm64/Kconfig +8 -1
@@ -591,12 +591,19 @@ config ARM64_ERRATUM_1742098 If unsure, say Y. config ARM64_ERRATUM_3194386 - bool "Cortex-X4/Neoverse-V3: workaround for MSR SSBS not self-synchronizing" + bool "Cortex-{A720,X4,X925}/Neoverse-V3: workaround for MSR SSBS not self-synchronizing" default y help This option adds the workaround for the following errata: + * ARM Cortex-A710 erratam 3324338 + * ARM Cortex-A720 erratum 3456091 + * ARM Cortex-X2 erratum 3324338 + * ARM Cortex-X3 erratum 3324335 * ARM Cortex-X4 erratum 3194386 + * ARM Cortex-X925 erratum 3324334 + * ARM Neoverse N2 erratum 3324339 + * ARM Neoverse V2 erratum 3324336 * ARM Neoverse-V3 erratum 3312417 On affected cores "MSR SSBS, #0" instructions may not affect
arch/arm64/kernel/cpu_errata.c +8 -1
@@ -843,8 +843,15 @@ static struct midr_range broken_aarch32_aes[] = {#ifdef CONFIG_ARM64_ERRATUM_3194386 static const struct midr_range erratum_spec_ssbs_list[] = { +MIDR_ALL_VERSIONS (MIDR_CORTEX_A710 ), +MIDR_ALL_VERSIONS (MIDR_CORTEX_A720 ), +MIDR_ALL_VERSIONS (MIDR_CORTEX_X2 ), +MIDR_ALL_VERSIONS (MIDR_CORTEX_X3 ),MIDR_ALL_VERSIONS (MIDR_CORTEX_X4 ), +MIDR_ALL_VERSIONS (MIDR_CORTEX_X925 ), +MIDR_ALL_VERSIONS (MIDR_NEOVERSE_N2 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_V3 ), +MIDR_ALL_VERSIONS (MIDR_NEOVERSE_V2 ), {} };#endif
@@ -1040,7 +1047,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = {#endif #ifdef CONFIG_ARM64_ERRATUM_3194386 { - .desc = "ARM errata 3194386, 3312417", + .desc = "SSBS not fully self-synchronizing", .capability = ARM64_WORKAROUND_SPECULATIVE_SSBS, ERRATA_MIDR_RANGE_LIST(erratum_spec_ssbs_list), },
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 218/259 arm64: cputype: Add Cortex-X1C definitions
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
[ Upstream commit 58d245e03c324d083a0ec3b9ab8ebd46ec9848d7 ]
Add cputype definitions for Cortex-X1C. These will be used for errata detection in subsequent patches.
These values can be found in the Cortex-X1C TRM:
https://developer.arm.com/documentation/101968/0002/
... in section B2.107 ("MIDR_EL1, Main ID Register, EL1").
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -80,6 +80,7 @@#define ARM_CPU_PART_CORTEX_X2 0xD48#define ARM_CPU_PART_NEOVERSE_N2 0xD49#define ARM_CPU_PART_CORTEX_A78C 0xD4B +#define ARM_CPU_PART_CORTEX_X1C 0xD4C#define ARM_CPU_PART_CORTEX_X3 0xD4E#define ARM_CPU_PART_NEOVERSE_V2 0xD4F#define ARM_CPU_PART_CORTEX_A720 0xD81
@@ -127,6 +128,7 @@#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) +#define MIDR_CORTEX_X1C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1C)#define MIDR_CORTEX_X3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X3)#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2)#define MIDR_CORTEX_A720 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 219/259 arm64: cputype: Add Cortex-A725 definitions
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
[ Upstream commit 9ef54a384526911095db465e77acc1cb5266b32c ]
Add cputype definitions for Cortex-A725. These will be used for errata detection in subsequent patches.
These values can be found in the Cortex-A725 TRM:
https://developer.arm.com/documentation/107652/0001/
... in table A-247 ("MIDR_EL1 bit descriptions").
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -87,6 +87,7 @@#define ARM_CPU_PART_CORTEX_X4 0xD82#define ARM_CPU_PART_NEOVERSE_V3 0xD84#define ARM_CPU_PART_CORTEX_X925 0xD85 +#define ARM_CPU_PART_CORTEX_A725 0xD87#define APM_CPU_PART_POTENZA 0x000
@@ -135,6 +136,7 @@#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4)#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925) +#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 220/259 arm64: errata: Expand speculative SSBS workaround (again)
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
[ Upstream commit adeec61a4723fd3e39da68db4cc4d924e6d7f641 ]
A number of Arm Ltd CPUs suffer from errata whereby an MSR to the SSBS special-purpose register does not affect subsequent speculative instructions, permitting speculative store bypassing for a window of time.
We worked around this for a number of CPUs in commits:
* 7187bb7d0b5c7dfa ("arm64: errata: Add workaround for Arm errata 3194386 and 3312417")
* 75b3c43eab594bfb ("arm64: errata: Expand speculative SSBS workaround")
Since then, similar errata have been published for a number of other Arm Ltd CPUs, for which the same mitigation is sufficient. This is described in their respective Software Developer Errata Notice (SDEN) documents:
* Cortex-A76 (MP052) SDEN v31.0, erratum 3324349
https://developer.arm.com/documentation/SDEN-885749/3100/
* Cortex-A77 (MP074) SDEN v19.0, erratum 3324348
https://developer.arm.com/documentation/SDEN-1152370/1900/
* Cortex-A78 (MP102) SDEN v21.0, erratum 3324344
https://developer.arm.com/documentation/SDEN-1401784/2100/
* Cortex-A78C (MP138) SDEN v16.0, erratum 3324346
https://developer.arm.com/documentation/SDEN-1707916/1600/
* Cortex-A78C (MP154) SDEN v10.0, erratum 3324347
https://developer.arm.com/documentation/SDEN-2004089/1000/
* Cortex-A725 (MP190) SDEN v5.0, erratum 3456106
https://developer.arm.com/documentation/SDEN-2832921/0500/
* Cortex-X1 (MP077) SDEN v21.0, erratum 3324344
https://developer.arm.com/documentation/SDEN-1401782/2100/
* Cortex-X1C (MP136) SDEN v16.0, erratum 3324346
https://developer.arm.com/documentation/SDEN-1707914/1600/
* Neoverse-N1 (MP050) SDEN v32.0, erratum 3324349
https://developer.arm.com/documentation/SDEN-885747/3200/
* Neoverse-V1 (MP076) SDEN v19.0, erratum 3324341
https://developer.arm.com/documentation/SDEN-1401781/1900/
Note that due to the manner in which Arm develops IP and tracks errata, some CPUs share a common erratum number and some CPUs have multiple erratum numbers for the same HW issue.
On parts without SB, it is necessary to use ISB for the workaround. The spec_bar() macro used in the mitigation will expand to a "DSB SY; ISB" sequence in this case, which is sufficient on all affected parts.
Enable the existing mitigation by adding the relevant MIDRs to erratum_spec_ssbs_list. The list is sorted alphanumerically (involving moving Neoverse-V3 after Neoverse-V2) so that this is easy to audit and potentially extend again in future. The Kconfig text is also updated to clarify the set of affected parts and the mitigation.
--- Documentation/arm64/silicon-errata.rst | 18 ++++++++++++++++++ arch/arm64/Kconfig | 22 ++++++++++++++++------ arch/arm64/kernel/cpu_errata.c | 11 ++++++++++- 3 files changed, 44 insertions(+), 7 deletions(-)
Documentation/arm64/silicon-errata.rst +18 -0
@@ -88,10 +88,24 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A76 | #3324349 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A77 | #3324348 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A78 | #3324344 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A78C | #3324346,3324347| ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X1C | #3324346 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-X2 | #3324338 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-X3 | #3324335 | ARM64_ERRATUM_3194386 |
@@ -106,8 +120,12 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-N1 | #3324349 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 |
arch/arm64/Kconfig +16 -6
@@ -591,18 +591,28 @@ config ARM64_ERRATUM_1742098 If unsure, say Y. config ARM64_ERRATUM_3194386 - bool "Cortex-{A720,X4,X925}/Neoverse-V3: workaround for MSR SSBS not self-synchronizing" + bool "Cortex-*/Neoverse-*: workaround for MSR SSBS not self-synchronizing" default y help This option adds the workaround for the following errata: + * ARM Cortex-A76 erratum 3324349 + * ARM Cortex-A77 erratum 3324348 + * ARM Cortex-A78 erratum 3324344 + * ARM Cortex-A78C erratum 3324346 + * ARM Cortex-A78C erratum 3324347 * ARM Cortex-A710 erratam 3324338 * ARM Cortex-A720 erratum 3456091 + * ARM Cortex-A725 erratum 3456106 + * ARM Cortex-X1 erratum 3324344 + * ARM Cortex-X1C erratum 3324346 * ARM Cortex-X2 erratum 3324338 * ARM Cortex-X3 erratum 3324335 * ARM Cortex-X4 erratum 3194386 * ARM Cortex-X925 erratum 3324334 + * ARM Neoverse-N1 erratum 3324349 * ARM Neoverse N2 erratum 3324339 + * ARM Neoverse-V1 erratum 3324341 * ARM Neoverse V2 erratum 3324336 * ARM Neoverse-V3 erratum 3312417
@@ -610,11 +620,11 @@ config ARM64_ERRATUM_3194386 subsequent speculative instructions, which may permit unexepected speculative store bypassing. - Work around this problem by placing a speculation barrier after - kernel changes to SSBS. The presence of the SSBS special-purpose - register is hidden from hwcaps and EL0 reads of ID_AA64PFR1_EL1, such - that userspace will use the PR_SPEC_STORE_BYPASS prctl to change - SSBS. + Work around this problem by placing a Speculation Barrier (SB) or + Instruction Synchronization Barrier (ISB) after kernel changes to + SSBS. The presence of the SSBS special-purpose register is hidden + from hwcaps and EL0 reads of ID_AA64PFR1_EL1, such that userspace + will use the PR_SPEC_STORE_BYPASS prctl to change SSBS. If unsure, say Y.
arch/arm64/kernel/cpu_errata.c +10 -1
@@ -843,15 +843,24 @@ static struct midr_range broken_aarch32_aes[] = {#ifdef CONFIG_ARM64_ERRATUM_3194386 static const struct midr_range erratum_spec_ssbs_list[] = { +MIDR_ALL_VERSIONS (MIDR_CORTEX_A76 ), +MIDR_ALL_VERSIONS (MIDR_CORTEX_A77 ), +MIDR_ALL_VERSIONS (MIDR_CORTEX_A78 ), +MIDR_ALL_VERSIONS (MIDR_CORTEX_A78C ),MIDR_ALL_VERSIONS (MIDR_CORTEX_A710 ),MIDR_ALL_VERSIONS (MIDR_CORTEX_A720 ), +MIDR_ALL_VERSIONS (MIDR_CORTEX_A725 ), +MIDR_ALL_VERSIONS (MIDR_CORTEX_X1 ), +MIDR_ALL_VERSIONS (MIDR_CORTEX_X1C ),MIDR_ALL_VERSIONS (MIDR_CORTEX_X2 ),MIDR_ALL_VERSIONS (MIDR_CORTEX_X3 ),MIDR_ALL_VERSIONS (MIDR_CORTEX_X4 ),MIDR_ALL_VERSIONS (MIDR_CORTEX_X925 ), +MIDR_ALL_VERSIONS (MIDR_NEOVERSE_N1 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_N2 ), -MIDR_ALL_VERSIONS (MIDR_NEOVERSE_V3 ), +MIDR_ALL_VERSIONS (MIDR_NEOVERSE_V1 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_V2 ), +MIDR_ALL_VERSIONS (MIDR_NEOVERSE_V3 ), {} };#endif
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 221/259 i2c: smbus: Dont filter out duplicate alerts
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Corey Minyard <[email protected]>
[ Upstream commit dca0dd28fa5e0a1ec41a623dbaf667601fc62331 ]
Getting the same alert twice in a row is legal and normal, especially on a fast device (like running in qemu). Kind of like interrupts. So don't report duplicate alerts, and deliver them normally.
[JD: Fixed subject]
Stable-dep-of: 37c526f00bc1 ("i2c: smbus: Improve handling of stuck alerts")
--- drivers/i2c/i2c-smbus.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/i2c/i2c-smbus.c +0 -7
@@ -66,7 +66,6 @@ static irqreturn_t smbus_alert(int irq, void *d) {struct i2c_smbus_alert *alert = d;struct i2c_client *ara; -unsigned short prev_addr =0 ;/* Not a valid address */ ara = alert->ara;
@@ -90,18 +89,12 @@ static irqreturn_t smbus_alert(int irq, void *d) data.addr = status >>1 ; data.type =I2C_PROTOCOL_SMBUS_ALERT ; -if (data.addr == prev_addr) { -dev_warn (&ara->dev,"Duplicate SMBALERT# from dev " -"0x%02x, skipping\n" , data.addr); -break ; - }dev_dbg (&ara->dev,"SMBALERT# from dev 0x%02x, flag %d\n" , data.addr, data.data);/* Notify driver for the device which issued the alert */ device_for_each_child (&ara->adapter->dev, &data, smbus_do_alert); - prev_addr = data.addr; }return IRQ_HANDLED ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 222/259 i2c: smbus: Improve handling of stuck alerts
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit 37c526f00bc1c4f847fc800085f8f009d2e11be6 ]
The following messages were observed while testing alert functionality on systems with multiple I2C devices on a single bus if alert was active on more than one chip.
smbus_alert 3-000c: SMBALERT# from dev 0x0c, flag 0 smbus_alert 3-000c: no driver alert()!
and:
smbus_alert 3-000c: SMBALERT# from dev 0x28, flag 0
Once it starts, this message repeats forever at high rate. There is no device at any of the reported addresses.
Analysis shows that this is seen if multiple devices have the alert pin active. Apparently some devices do not support SMBus arbitration correctly. They keep sending address bits after detecting an address collision and handle the collision not at all or too late.
Specifically, address 0x0c is seen with ADT7461A at address 0x4c and ADM1021 at address 0x18 if alert is active on both chips. Address 0x28 is seen with ADT7483 at address 0x2a and ADT7461 at address 0x4c if alert is active on both chips.
Once the system is in bad state (alert is set by more than one chip), it often only recovers by power cycling.
To reduce the impact of this problem, abort the endless loop in smbus_alert() if the same address is read more than once and not handled by a driver.
--- drivers/i2c/i2c-smbus.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-)
drivers/i2c/i2c-smbus.c +25 -7
@@ -33,6 +33,7 @@ static int smbus_do_alert(struct device *dev, void *addrp)struct i2c_client *client =i2c_verify_client (dev);struct alert_data *data = addrp;struct i2c_driver *driver; +int ret;if (!client || client->addr != data->addr)return 0 ;
@@ -46,16 +47,21 @@ static int smbus_do_alert(struct device *dev, void *addrp)device_lock (dev);if (client->dev.driver) { driver =to_i2c_driver (client->dev.driver); -if (driver->alert) +if (driver->alert) { +/* Stop iterating after we find the device */ driver->alert (client, data->type, data->data); -else + ret = -EBUSY ; + }else {dev_warn (&client->dev,"no driver alert()!\n" ); - }else + ret = -EOPNOTSUPP ; + } + }else {dev_dbg (&client->dev,"alert with no driver\n" ); + ret = -ENODEV ; + }device_unlock (dev); -/* Stop iterating after we find the device */ -return -EBUSY ; +return ret; }/*
@@ -66,6 +72,7 @@ static irqreturn_t smbus_alert(int irq, void *d) {struct i2c_smbus_alert *alert = d;struct i2c_client *ara; +unsigned short prev_addr =I2C_CLIENT_END ;/* Not a valid address */ ara = alert->ara;
@@ -93,8 +100,19 @@ static irqreturn_t smbus_alert(int irq, void *d) data.addr, data.data);/* Notify driver for the device which issued the alert */ -device_for_each_child (&ara->adapter->dev, &data, - smbus_do_alert); + status =device_for_each_child (&ara->adapter->dev, &data, + smbus_do_alert); +/* +* If we read the same address more than once, and the alert +* was not handled by a driver, it won't do any good to repeat +* the loop because it will never terminate. +* Bail out in this case. +* Note: This assumes that a driver with alert handler handles +* the alert properly and clears it if necessary. +*/ +if (data.addr == prev_addr && status != -EBUSY ) +break ; + prev_addr = data.addr; }return IRQ_HANDLED ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 223/259 i2c: smbus: Send alert notifications to all devices if source not found
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit f6c29f710c1ff2590109f83be3e212b86c01e0f3 ]
If a SMBus alert is received and the originating device is not found, the reason may be that the address reported on the SMBus alert address is corrupted, for example because multiple devices asserted alert and do not correctly implement SMBus arbitration.
If this happens, call alert handlers on all devices connected to the given I2C bus, in the hope that this cleans up the situation.
This change reliably fixed the problem on a system with multiple devices on a single bus. Example log where the device on address 0x18 (ADM1021) and on address 0x4c (ADT7461A) both had the alert line asserted:
smbus_alert 3-000c: SMBALERT# from dev 0x0c, flag 0 smbus_alert 3-000c: no driver alert()! smbus_alert 3-000c: SMBALERT# from dev 0x0c, flag 0 smbus_alert 3-000c: no driver alert()!
lm90 3-0018: temp1 out of range, please check! lm90 3-0018: Disabling ALERT#
lm90 3-0029: Everything OK
lm90 3-002a: Everything OK
lm90 3-004c: temp1 out of range, please check! lm90 3-004c: temp2 out of range, please check! lm90 3-004c: Disabling ALERT#
--- drivers/i2c/i2c-smbus.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-)
drivers/i2c/i2c-smbus.c +35 -3
@@ -64,6 +64,32 @@ static int smbus_do_alert(struct device *dev, void *addrp)return ret; } +/* Same as above, but call back all drivers with alert handler */ + +static int smbus_do_alert_force (struct device *dev,void *addrp) +{ +struct i2c_client *client =i2c_verify_client (dev); +struct alert_data *data = addrp; +struct i2c_driver *driver; + +if (!client || (client->flags &I2C_CLIENT_TEN )) +return 0 ; + +/* +* Drivers should either disable alerts, or provide at least +* a minimal handler. Lock so the driver won't change. +*/ +device_lock (dev); +if (client->dev.driver) { + driver =to_i2c_driver (client->dev.driver); +if (driver->alert) + driver->alert (client, data->type, data->data); + } +device_unlock (dev); + +return 0 ; +} +/* * The alert IRQ handler needs to hand work off to a task which can issue * SMBus calls, because those sleeping calls can't be made in IRQ context.
@@ -105,13 +131,19 @@ static irqreturn_t smbus_alert(int irq, void *d)/* * If we read the same address more than once, and the alert * was not handled by a driver, it won't do any good to repeat -* the loop because it will never terminate. -* Bail out in this case. +* the loop because it will never terminate. Try again, this +* time calling the alert handlers of all devices connected to +* the bus, and abort the loop afterwards. If this helps, we +* are all set. If it doesn't, there is nothing else we can do, +* so we might as well abort the loop. * Note: This assumes that a driver with alert handler handles * the alert properly and clears it if necessary. */ -if (data.addr == prev_addr && status != -EBUSY ) +if (data.addr == prev_addr && status != -EBUSY ) { +device_for_each_child (&ara->adapter->dev, &data, + smbus_do_alert_force);break ; + } prev_addr = data.addr; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 224/259 bpf: kprobe: remove unused declaring of bpf_kprobe_override
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Menglong Dong <[email protected]>
[ Upstream commit 0e8b53979ac86eddb3fd76264025a70071a25574 ]
After the commit 66665ad2f102 ("tracing/kprobe: bpf: Compare instruction pointer with original one"), "bpf_kprobe_override" is not used anywhere anymore, and we can remove it now.
--- include/linux/trace_events.h | 1 - 1 file changed, 1 deletion(-)
include/linux/trace_events.h +0 -1
@@ -578,7 +578,6 @@ do { \struct perf_event ; DECLARE_PER_CPU(struct pt_regs, perf_trace_regs); -DECLARE_PER_CPU (int, bpf_kprobe_override);extern int perf_trace_init (struct perf_event *event);extern void perf_trace_destroy (struct perf_event *event);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 225/259 spi: fsl-lpspi: remove unneeded array
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksandr Suvorov <[email protected]>
[ Upstream commit 2fa98705a9289c758b6154a22174aa8d4041a285 ]
- replace the array with the shift operation
- remove the extra comparing operation.
Stable-dep-of: 730bbfaf7d48 ("spi: spi-fsl-lpspi: Fix scldiv calculation")
--- drivers/spi/spi-fsl-lpspi.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/spi/spi-fsl-lpspi.c +2 -5
@@ -86,8 +86,6 @@#define TCR_RXMSK BIT(19)#define TCR_TXMSK BIT(18) -static int clkdivs[] = {1 ,2 ,4 ,8 ,16 ,32 ,64 ,128 }; -struct lpspi_config {u8 bpw;u8 chip_select;
@@ -331,15 +329,14 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi) }for (prescale =0 ; prescale <8 ; prescale++) { - scldiv = perclk_rate / - (clkdivs[prescale] * config.speed_hz) -2 ; + scldiv = perclk_rate / config.speed_hz / (1 << prescale) -2 ;if (scldiv <256 ) { fsl_lpspi->config.prescale = prescale;break ; } } -if (prescale ==8 && scldiv >=256 ) +if (scldiv >=256 )return -EINVAL ; writel(scldiv | (scldiv << 8) | ((scldiv >> 1) << 16),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 226/259 spi: spi-fsl-lpspi: Fix scldiv calculation
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wahren <[email protected]>
[ Upstream commit 730bbfaf7d4890bd99e637db7767dc68cfeb24e7 ]
The effective SPI clock frequency should never exceed speed_hz otherwise this might result in undefined behavior of the SPI device.
Currently the scldiv calculation could violate this constraint. For the example parameters perclk_rate = 24 MHz and speed_hz = 7 MHz, the function fsl_lpspi_set_bitrate will determine perscale = 0 and scldiv = 1, which is a effective SPI clock of 8 MHz.
So fix this by rounding up the quotient of perclk_rate and speed_hz. While this never change within the loop, we can pull this out.
--- drivers/spi/spi-fsl-lpspi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/spi/spi-fsl-lpspi.c +4 -2
@@ -317,7 +317,7 @@ static void fsl_lpspi_set_watermark(struct fsl_lpspi_data *fsl_lpspi)static int fsl_lpspi_set_bitrate (struct fsl_lpspi_data *fsl_lpspi) {struct lpspi_config config = fsl_lpspi->config; -unsigned int perclk_rate, scldiv; +unsigned int perclk_rate, scldiv, div;u8 prescale; perclk_rate =clk_get_rate (fsl_lpspi->clk_per);
@@ -328,8 +328,10 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)return -EINVAL ; } + div =DIV_ROUND_UP (perclk_rate, config.speed_hz); +for (prescale =0 ; prescale <8 ; prescale++) { - scldiv = perclk_rate / config.speed_hz / (1 << prescale) -2 ; + scldiv = div / (1 << prescale) -2 ;if (scldiv <256 ) { fsl_lpspi->config.prescale = prescale;break ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 227/259 drm/client: fix null pointer dereference in drm_client_modeset_probe
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit 113fd6372a5bb3689aba8ef5b8a265ed1529a78f upstream.
In drm_client_modeset_probe(), the return value of drm_mode_duplicate() is assigned to modeset->mode, which will lead to a possible NULL pointer dereference on failure of drm_mode_duplicate(). Add a check to avoid npd.
--- drivers/gpu/drm/drm_client_modeset.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/drm_client_modeset.c +5 -0
@@ -792,6 +792,11 @@ int drm_client_modeset_probe(struct drm_kfree (modeset->mode); modeset->mode =drm_mode_duplicate (dev, mode); +if (!modeset->mode) { + ret = -ENOMEM ; +break ; + } +drm_connector_get (connector); modeset->connectors[modeset->num_connectors++] = connector; modeset->x = offset->x;
Greg Kroah-Hartman
maintainerPATCH 228/259 ALSA: line6: Fix racy access to midibuf
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 15b7a03205b31bc5623378c190d22b7ff60026f1 upstream.
There can be concurrent accesses to line6 midibuf from both the URB completion callback and the rawmidi API access. This could be a cause of KMSAN warning triggered by syzkaller below (so put as reported-by here).
This patch protects the midibuf call of the former code path with a spinlock for avoiding the possible races.
--- sound/usb/line6/driver.c | 5 +++++ 1 file changed, 5 insertions(+)
sound/usb/line6/driver.c +5 -0
@@ -285,12 +285,14 @@ static void line6_data_received(struct u {struct usb_line6 *line6 = (struct usb_line6 *)urb->context;struct midi_buffer *mb = &line6->line6midi->midibuf_in; +unsigned long flags;int done;if (urb->status == -ESHUTDOWN )return ;if (line6->properties->capabilities &LINE6_CAP_CONTROL_MIDI ) { +spin_lock_irqsave (&line6->line6midi->lock, flags); done =line6_midibuf_write (mb, urb->transfer_buffer, urb->actual_length);
@@ -299,12 +301,15 @@ static void line6_data_received(struct udev_dbg (line6->ifcdev,"%d %d buffer overflow - message skipped\n" , done, urb->actual_length); } +spin_unlock_irqrestore (&line6->line6midi->lock, flags);for (;;) { +spin_lock_irqsave (&line6->line6midi->lock, flags); done =line6_midibuf_read (mb, line6->buffer_message,LINE6_MIDI_MESSAGE_MAXLEN ,LINE6_MIDIBUF_READ_RX ); +spin_unlock_irqrestore (&line6->line6midi->lock, flags);if (done <=0 )break ;
Greg Kroah-Hartman
maintainerPATCH 229/259 ALSA: hda: Add HP MP9 G4 Retail System AMS to force connect list
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven 'Steve' Kendall <[email protected]>
commit 7e1e206b99f4b3345aeb49d94584a420b7887f1d upstream.
In recent HP UEFI firmware (likely v2.15 and above, tested on 2.27), these pins are incorrectly set for HDMI/DP audio. Tested on HP MP9 G4 Retail System AMS. Tested audio with two monitors connected via DisplayPort.
--- sound/pci/hda/patch_hdmi.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_hdmi.c +1 -0
@@ -1818,6 +1818,7 @@ static int hdmi_add_cvt(struct hda_codec }static const struct snd_pci_quirk force_connect_list[] = { +SND_PCI_QUIRK (0x103c ,0x83ef ,"HP MP9 G4 Retail System AMS" ,1 ),SND_PCI_QUIRK (0x103c ,0x870f ,"HP" ,1 ),SND_PCI_QUIRK (0x103c ,0x871a ,"HP" ,1 ),SND_PCI_QUIRK (0x103c ,0x8711 ,"HP" ,1 ),
Greg Kroah-Hartman
maintainerPATCH 230/259 ALSA: hda/hdmi: Yet more pin fix for HP EliteDesk 800 G4
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 176fd1511dd9086ab4fa9323cb232177c6235288 upstream.
HP EliteDesk 800 G4 (PCI SSID 103c:83e2) is another Kabylake machine where BIOS misses the HDMI pin initializations. Add the quirk entry.
--- sound/pci/hda/patch_hdmi.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_hdmi.c +1 -0
@@ -1818,6 +1818,7 @@ static int hdmi_add_cvt(struct hda_codec }static const struct snd_pci_quirk force_connect_list[] = { +SND_PCI_QUIRK (0x103c ,0x83e2 ,"HP EliteDesk 800 G4" ,1 ),SND_PCI_QUIRK (0x103c ,0x83ef ,"HP MP9 G4 Retail System AMS" ,1 ),SND_PCI_QUIRK (0x103c ,0x870f ,"HP" ,1 ),SND_PCI_QUIRK (0x103c ,0x871a ,"HP" ,1 ),
Greg Kroah-Hartman
maintainerPATCH 231/259 usb: vhci-hcd: Do not drop references before new references are gained
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit afdcfd3d6fcdeca2735ca8d994c5f2d24a368f0a upstream.
At a few places the driver carries stale pointers
to references that can still be used. Make sure that does not happen. This strictly speaking closes ZDI-CAN-22273, though there may be similar races in the driver.
--- drivers/usb/usbip/vhci_hcd.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/usb/usbip/vhci_hcd.c +6 -3
@@ -746,6 +746,7 @@ static int vhci_urb_enqueue(struct usb_h* */ if (usb_pipedevice (urb->pipe) ==0 ) { +struct usb_device *old;__u8 type =usb_pipetype (urb->pipe);struct usb_ctrlrequest *ctrlreq = (struct usb_ctrlrequest *) urb->setup_packet;
@@ -756,14 +757,15 @@ static int vhci_urb_enqueue(struct usb_h goto no_need_xmit; } + old = vdev->udev;switch (ctrlreq->bRequest) {case USB_REQ_SET_ADDRESS :/* set_address may come when a device is reset */ dev_info (dev,"SetAddress Request (%d) to port %d\n" , ctrlreq->wValue, vdev->rhport); -usb_put_dev (vdev->udev); vdev->udev =usb_get_dev (urb->dev); +usb_put_dev (old);spin_lock (&vdev->ud.lock); vdev->ud.status =VDEV_ST_USED ;
@@ -782,8 +784,8 @@ static int vhci_urb_enqueue(struct usb_husbip_dbg_vhci_hc ("Not yet?:Get_Descriptor to device 0 (get max pipe size)\n" ); -usb_put_dev (vdev->udev); vdev->udev =usb_get_dev (urb->dev); +usb_put_dev (old); goto out;default :
@@ -1090,6 +1092,7 @@ static void vhci_shutdown_connection(strstatic void vhci_device_reset (struct usbip_device *ud) { struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); +struct usb_device *old = vdev->udev;unsigned long flags;spin_lock_irqsave (&ud->lock, flags);
@@ -1097,8 +1100,8 @@ static void vhci_device_reset(struct usb vdev->speed =0 ; vdev->devid =0 ; -usb_put_dev (vdev->udev); vdev->udev =NULL ; +usb_put_dev (old);if (ud->tcp_socket) {sockfd_put (ud->tcp_socket);
Greg Kroah-Hartman
maintainerPATCH 232/259 USB: serial: debug: do not echo input by default
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Marczykowski-Górecki <[email protected]>
commit 00af4f3dda1461ec90d892edc10bec6d3c50c554 upstream.
This driver is intended as a "client" end of the console connection. When connected to a host it's supposed to receive debug logs, and possibly allow to interact with whatever debug console is available there. Feeding messages back, depending on a configuration may cause log messages be executed as shell commands (which can be really bad if one is unlucky, imagine a log message like "prevented running rm -rf /home"). In case of Xen, it exposes sysrq-like debug interface, and feeding it its own logs will pretty quickly hit 'R' for "instant reboot".
Contrary to a classic serial console, the USB one cannot be configured ahead of time, as the device shows up only when target OS is up. And at the time device is opened to execute relevant ioctl, it's already too late, especially when logs start flowing shortly after device is initialized.
Avoid the issue by changing default to no echo for this type of devices.
--- drivers/usb/serial/usb_debug.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/usb/serial/usb_debug.c +7 -0
@@ -69,6 +69,11 @@ static void usb_debug_process_read_urb(susb_serial_generic_process_read_urb (urb); } +static void usb_debug_init_termios (struct tty_struct *tty) +{ + tty->termios.c_lflag &= ~(ECHO |ECHONL ); +} +static struct usb_serial_driver debug_device = { .driver = { .owner =THIS_MODULE ,
@@ -78,6 +83,7 @@ static struct usb_serial_driver debug_de .num_ports = 1, .bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE, .break_ctl = usb_debug_break_ctl, + .init_termios = usb_debug_init_termios, .process_read_urb = usb_debug_process_read_urb, };
@@ -89,6 +95,7 @@ static struct usb_serial_driver dbc_devi .id_table = dbc_id_table, .num_ports = 1, .break_ctl = usb_debug_break_ctl, + .init_termios = usb_debug_init_termios, .process_read_urb = usb_debug_process_read_urb, };
Greg Kroah-Hartman
maintainerPATCH 233/259 usb: gadget: core: Check for unset descriptor
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Wulff <[email protected]>
commit 973a57891608a98e894db2887f278777f564de18 upstream.
Make sure the descriptor has been set before looking at maxpacket. This fixes a null pointer panic in this case.
This may happen if the gadget doesn't properly set up the endpoint for the current speed, or the gadget descriptors are malformed and the descriptor for the speed/endpoint are not found.
No current gadget driver is known to have this problem, but this may cause a hard-to-find bug during development of new gadgets.
--- drivers/usb/gadget/udc/core.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/usb/gadget/udc/core.c +4 -6
@@ -99,12 +99,10 @@ int usb_ep_enable(struct usb_ep *ep) goto out;/* UDC drivers can't handle endpoints with maxpacket size 0 */ -if (usb_endpoint_maxp (ep->desc) ==0 ) { -/* -* We should log an error message here, but we can't call -* dev_err() because there's no way to find the gadget -* given only ep. -*/ +if (!ep->desc ||usb_endpoint_maxp (ep->desc) ==0 ) { +WARN_ONCE (1 ,"%s: ep%d (%s) has %s\n" , __func__, ep->address, ep->name, + (!ep->desc) ?"NULL descriptor" :"maxpacket 0" ); + ret = -EINVAL ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 234/259 scsi: ufs: core: Fix hba->last_dme_cmd_tstamp timestamp updating logic
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vamshi Gajjela <[email protected]>
commit ab9fd06cb8f0db0854291833fc40c789e43a361f upstream.
The ufshcd_add_delay_before_dme_cmd() always introduces a delay of MIN_DELAY_BEFORE_DME_CMDS_US between DME commands even when it's not required. The delay is added when the UFS host controller supplies the quirk UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS.
Fix the logic to update hba->last_dme_cmd_tstamp to ensure subsequent DME commands have the correct delay in the range of 0 to MIN_DELAY_BEFORE_DME_CMDS_US.
Update the timestamp at the end of the function to ensure it captures the latest time after any necessary delay has been applied.
--- drivers/scsi/ufs/ufshcd.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/scsi/ufs/ufshcd.c +8 -3
@@ -3569,11 +3569,16 @@ static inline void ufshcd_add_delay_befo min_sleep_time_us =MIN_DELAY_BEFORE_DME_CMDS_US - delta; else - return;/* no more delay required */ + min_sleep_time_us =0 ;/* no more delay required */ } -/* allow sleep for extra 50us if needed */ -usleep_range (min_sleep_time_us, min_sleep_time_us +50 ); +if (min_sleep_time_us >0 ) { +/* allow sleep for extra 50us if needed */ +usleep_range (min_sleep_time_us, min_sleep_time_us +50 ); + } + +/* update the last_dme_cmd_tstamp */ + hba->last_dme_cmd_tstamp =ktime_get (); }/**
Greg Kroah-Hartman
maintainerPATCH 235/259 tick/broadcast: Move per CPU pointer access into the atomic section
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
commit 6881e75237a84093d0986f56223db3724619f26e upstream.
The recent fix for making the take over of the broadcast timer more reliable retrieves a per CPU pointer in preemptible context.
This went unnoticed as compilers hoist the access into the non-preemptible region where the pointer is actually used. But of course it's valid that the compiler keeps it at the place where the code puts it which rightfully triggers:
BUG: using smp_processor_id() in preemptible [00000000] code:
caller is hotplug_cpu__broadcast_tick_pull+0x1c/0xc0Move it to the actual usage site which is in a non-preemptible region.
--- kernel/time/tick-broadcast.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/time/tick-broadcast.c +2 -1
@@ -944,7 +944,6 @@ void tick_broadcast_switch_to_oneshot(vo#ifdef CONFIG_HOTPLUG_CPU void hotplug_cpu__broadcast_tick_pull (int deadcpu) { -struct tick_device *td =this_cpu_ptr (&tick_cpu_device);struct clock_event_device *bc;unsigned long flags;
@@ -970,6 +969,8 @@ void hotplug_cpu__broadcast_tick_pull(in* device to avoid the starvation. */ if (tick_check_broadcast_expired ()) { +struct tick_device *td =this_cpu_ptr (&tick_cpu_device); +cpumask_clear_cpu (smp_processor_id (), tick_broadcast_force_mask);tick_program_event (td->evtdev->next_event,1 ); }
Greg Kroah-Hartman
maintainerPATCH 236/259 ntp: Clamp maxerror and esterror to operating range
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Stitt <[email protected]>
[ Upstream commit 87d571d6fb77ec342a985afa8744bb9bb75b3622 ]
Using syzkaller alongside the newly reintroduced signed integer overflow sanitizer spits out this report:
UBSAN: signed-integer-overflow in ../kernel/time/ntp.c:461:16 9223372036854775807 + 500 cannot be represented in type 'long' Call Trace: handle_overflow+0x171/0x1b0 second_overflow+0x2d6/0x500 accumulate_nsecs_to_secs+0x60/0x160 timekeeping_advance+0x1fe/0x890 update_wall_time+0x10/0x30
time_maxerror is unconditionally incremented and the result is checked against NTP_PHASE_LIMIT, but the increment itself can overflow, resulting in wrap-around to negative space.
Before commit eea83d896e31 ("ntp: NTP4 user space bits update") the user supplied value was sanity checked to be in the operating range. That change removed the sanity check and relied on clamping in handle_overflow() which does not work correctly when the user supplied value is in the overflow zone of the '+ 500' operation.
The operation requires CAP_SYS_TIME and the side effect of the overflow is NTP getting out of sync.
Miroslav confirmed that the input value should be clamped to the operating range and the same applies to time_esterror. The latter is not used by the kernel, but the value still should be in the operating range as it was before the sanity check got removed.
Clamp them to the operating range.
[ tglx: Changed it to clamping and included time_esterror ]
--- kernel/time/ntp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/time/ntp.c +2 -2
@@ -679,10 +679,10 @@ static inline void process_adjtimex_mode }if (txc->modes &ADJ_MAXERROR ) - time_maxerror = txc->maxerror; + time_maxerror =clamp (txc->maxerror, (long long )0 , (long long )NTP_PHASE_LIMIT );if (txc->modes &ADJ_ESTERROR ) - time_esterror = txc->esterror; + time_esterror =clamp (txc->esterror, (long long )0 , (long long )NTP_PHASE_LIMIT );if (txc->modes &ADJ_TIMECONST ) { time_constant = txc->constant;
Greg Kroah-Hartman
maintainerPATCH 237/259 driver core: Fix uevent_show() vs driver detach race
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams <[email protected]>
commit 15fffc6a5624b13b428bb1c6e9088e32a55eb82c upstream.
uevent_show() wants to de-reference dev->driver->name. There is no clean way for a device attribute to de-reference dev->driver unless that attribute is defined via (struct device_driver).dev_groups. Instead, the anti-pattern of taking the device_lock() in the attribute handler risks deadlocks with code paths that remove device attributes while holding the lock.
This deadlock is typically invisible to lockdep given the device_lock() is marked lockdep_set_novalidate_class(), but some subsystems allocate a local lockdep key for @dev->mutex to reveal reports of the form:
======================================================
WARNING: possible circular locking dependency detected
6.10.0-rc7+ #275 Tainted: G OE N
------------------------------------------------------
modprobe/2374 is trying to acquire lock:
ffff8c2270070de0 (kn->active#6){++++}-{0:0}, at: __kernfs_remove+0xde/0x220
but task is already holding lock:
ffff8c22016e88f8 (&cxl_root_key){+.+.}-{3:3}, at: device_release_driver_internal+0x39/0x210
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&cxl_root_key){+.+.}-{3:3}:
__mutex_lock+0x99/0xc30
uevent_show+0xac/0x130
dev_attr_show+0x18/0x40
sysfs_kf_seq_show+0xac/0xf0
seq_read_iter+0x110/0x450
vfs_read+0x25b/0x340
ksys_read+0x67/0xf0
do_syscall_64+0x75/0x190
entry_SYSCALL_64_after_hwframe+0x76/0x7e-> #0 (kn->active#6){++++}-{0:0}:
__lock_acquire+0x121a/0x1fa0
lock_acquire+0xd6/0x2e0
kernfs_drain+0x1e9/0x200
__kernfs_remove+0xde/0x220
kernfs_remove_by_name_ns+0x5e/0xa0
device_del+0x168/0x410
device_unregister+0x13/0x60
devres_release_all+0xb8/0x110
device_unbind_cleanup+0xe/0x70
device_release_driver_internal+0x1c7/0x210
driver_detach+0x47/0x90
bus_remove_driver+0x6c/0xf0
cxl_acpi_exit+0xc/0x11 [cxl_acpi]
__do_sys_delete_module.isra.0+0x181/0x260
do_syscall_64+0x75/0x190
entry_SYSCALL_64_after_hwframe+0x76/0x7eThe observation though is that driver objects are typically much longer lived than device objects. It is reasonable to perform lockless de-reference of a @driver pointer even if it is racing detach from a device. Given the infrequency of driver unregistration, use synchronize_rcu() in module_remove_driver() to close any potential races. It is potentially overkill to suffer synchronize_rcu() just to handle the rare module removal racing uevent_show() event.
Thanks to Tetsuo Handa for the debug analysis of the syzbot report [1].
--- drivers/base/core.c | 13 ++++++++----- drivers/base/module.c | 4 ++++ 2 files changed, 12 insertions(+), 5 deletions(-)
drivers/base/core.c +8 -5
@@ -25,6 +25,7 @@#include <linux/mutex.h> #include <linux/pm_runtime.h> #include <linux/netdevice.h> +#include <linux/rcupdate.h> #include <linux/sched/signal.h> #include <linux/sysfs.h>
@@ -1174,6 +1175,7 @@ static int dev_uevent(struct kset *kset, struct kobj_uevent_env *env) {struct device *dev =kobj_to_dev (kobj); +struct device_driver *driver;int retval =0 ;/* add device node properties if present */
@@ -1202,8 +1204,12 @@ static int dev_uevent(struct kset *kset,if (dev->type && dev->type->name)add_uevent_var (env,"DEVTYPE=%s" , dev->type->name); -if (dev->driver) -add_uevent_var (env,"DRIVER=%s" , dev->driver->name); +/* Synchronize with module_remove_driver() */ +rcu_read_lock (); + driver =READ_ONCE (dev->driver); +if (driver) +add_uevent_var (env,"DRIVER=%s" , driver->name); +rcu_read_unlock ();/* Add common DT information about the device */ of_device_uevent (dev, env);
@@ -1273,11 +1279,8 @@ static ssize_t uevent_show(struct deviceif (!env)return -ENOMEM ; -/* Synchronize with really_probe() */ -device_lock (dev);/* let the kset specific function add its keys */ retval = kset->uevent_ops->uevent (kset, &dev->kobj, env); -device_unlock (dev);if (retval) goto out;
drivers/base/module.c +4 -0
@@ -7,6 +7,7 @@#include <linux/errno.h> #include <linux/slab.h> #include <linux/string.h> +#include <linux/rcupdate.h> #include "base.h" static char *make_driver_name (struct device_driver *drv)
@@ -77,6 +78,9 @@ void module_remove_driver(struct device_if (!drv)return ; +/* Synchronize with dev_uevent() */ +synchronize_rcu (); +sysfs_remove_link (&drv->p->kobj,"module" );if (drv->owner)
Greg Kroah-Hartman
maintainerPATCH 238/259 ntp: Safeguard against time_constant overflow
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Stitt <[email protected]>
commit 06c03c8edce333b9ad9c6b207d93d3a5ae7c10c0 upstream.
Using syzkaller with the recently reintroduced signed integer overflow sanitizer produces this UBSAN report:
UBSAN: signed-integer-overflow in ../kernel/time/ntp.c:738:18 9223372036854775806 + 4 cannot be represented in type 'long' Call Trace: handle_overflow+0x171/0x1b0 __do_adjtimex+0x1236/0x1440 do_adjtimex+0x2be/0x740
The user supplied time_constant value is incremented by four and then clamped to the operating range.
Before commit eea83d896e31 ("ntp: NTP4 user space bits update") the user supplied value was sanity checked to be in the operating range. That change removed the sanity check and relied on clamping after incrementing which does not work correctly when the user supplied value is in the overflow zone of the '+ 4' operation.
The operation requires CAP_SYS_TIME and the side effect of the overflow is NTP getting out of sync.
Similar to the fixups for time_maxerror and time_esterror, clamp the user space supplied value to the operating range.
[ tglx: Switch to clamping ]
--- kernel/time/ntp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
kernel/time/ntp.c +2 -3
@@ -685,11 +685,10 @@ static inline void process_adjtimex_mode time_esterror =clamp (txc->esterror, (long long )0 , (long long )NTP_PHASE_LIMIT );if (txc->modes &ADJ_TIMECONST ) { - time_constant = txc->constant; + time_constant =clamp (txc->constant, (long long )0 , (long long )MAXTC );if (!(time_status &STA_NANO )) time_constant +=4 ; - time_constant =min (time_constant, (long )MAXTC ); - time_constant =max (time_constant,0l ); + time_constant =clamp (time_constant, (long )0 , (long )MAXTC ); } if (txc->modes & ADJ_TAI &&
Greg Kroah-Hartman
maintainerPATCH 239/259 scsi: mpt3sas: Remove scsi_dma_map() error messages
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sreekanth Reddy <[email protected]>
[ Upstream commit 0c25422d34b4726b2707d5f38560943155a91b80 ]
When scsi_dma_map() fails by returning a sges_left value less than zero, the amount of logging produced can be extremely high. In a recent end-user environment, 1200 messages per second were being sent to the log buffer. This eventually overwhelmed the system and it stalled.
These error messages are not needed. Remove them.
Stable-dep-of: 82dbb57ac8d0 ("scsi: mpt3sas: Avoid IOMMU page faults on REPORT ZONES")
--- drivers/scsi/mpt3sas/mpt3sas_base.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-)
drivers/scsi/mpt3sas/mpt3sas_base.c +3 -15
@@ -2310,12 +2310,8 @@ _base_check_pcie_native_sgl(struct MPT3SAS_ADAPTER *ioc,/* Get the SG list pointer and info. */ sges_left =scsi_dma_map (scmd); -if (sges_left <0 ) { -sdev_printk (KERN_ERR , scmd->device, -"scsi_dma_map failed: request for %d bytes!\n" , -scsi_bufflen (scmd)); +if (sges_left <0 )return 1 ; - }/* Check if we need to build a native SG list. */ if (base_is_prp_possible(ioc, pcie_device,
@@ -2422,12 +2418,8 @@ _base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc, sg_scmd =scsi_sglist (scmd); sges_left =scsi_dma_map (scmd); -if (sges_left <0 ) { -sdev_printk (KERN_ERR , scmd->device, -"scsi_dma_map failed: request for %d bytes!\n" , -scsi_bufflen (scmd)); +if (sges_left <0 )return -ENOMEM ; - } sg_local = &mpi_request->SGL; sges_in_segment = ioc->max_sges_in_main_message;
@@ -2570,12 +2562,8 @@ _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc, sg_scmd =scsi_sglist (scmd); sges_left =scsi_dma_map (scmd); -if (sges_left <0 ) { -sdev_printk (KERN_ERR , scmd->device, -"scsi_dma_map failed: request for %d bytes!\n" , -scsi_bufflen (scmd)); +if (sges_left <0 )return -ENOMEM ; - } sg_local = &mpi_request->SGL; sges_in_segment = (ioc->request_sz -
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 240/259 scsi: mpt3sas: Avoid IOMMU page faults on REPORT ZONES
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
[ Upstream commit 82dbb57ac8d06dfe8227ba9ab11a49de2b475ae5 ]
Some firmware versions of the 9600 series SAS HBA byte-swap the REPORT ZONES command reply buffer from ATA-ZAC devices by directly accessing the buffer in the host memory. This does not respect the default command DMA direction and causes IOMMU page faults on architectures with an IOMMU enforcing write-only mappings for DMA_FROM_DEVICE DMA driection (e.g. AMD hosts).
scsi 18:0:0:0: Direct-Access-ZBC ATA WDC WSH722020AL W870 PQ: 0 ANSI: 6
scsi 18:0:0:0: SATA: handle(0x0027), sas_addr(0x300062b2083e7c40), phy(0), device_name(0x5000cca29dc35e11) scsi 18:0:0:0: enclosure logical id (0x300062b208097c40), slot(0)
scsi 18:0:0:0: enclosure level(0x0000), connector name( C0.0)
scsi 18:0:0:0: atapi(n), ncq(y), asyn_notify(n), smart(y), fua(y), sw_preserve(y)
scsi 18:0:0:0: qdepth(32), tagged(1), scsi_level(7), cmd_que(1)
sd 18:0:0:0: Attached scsi generic sg2 type 20
sd 18:0:0:0: [sdc] Host-managed zoned block device
mpt3sas 0000:41:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0021 address=0xfff9b200 flags=0x0050] mpt3sas 0000:41:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0021 address=0xfff9b300 flags=0x0050]mpt3sas_cm0: mpt3sas_ctl_pre_reset_handler: Releasing the trace buffer due to adapter reset. mpt3sas_cm0 fault info from func: mpt3sas_base_make_ioc_readympt3sas_cm0: fault_state(0x2666)!mpt3sas_cm0: sending diag reset !!mpt3sas_cm0: diag reset: SUCCESS
sd 18:0:0:0: [sdc] REPORT ZONES start lba 0 failed
sd 18:0:0:0: [sdc] REPORT ZONES: Result: hostbyte=DID_RESET driverbyte=DRIVER_OK
sd 18:0:0:0: [sdc] 0 4096-byte logical blocks: (0 B/0 B)
Avoid such issue by always mapping the buffer of REPORT ZONES commands using DMA_BIDIRECTIONAL (read+write IOMMU mapping). This is done by introducing the helper function _base_scsi_dma_map() and using this helper in _base_build_sg_scmd() and _base_build_sg_scmd_ieee() instead of calling directly scsi_dma_map().
--- drivers/scsi/mpt3sas/mpt3sas_base.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
drivers/scsi/mpt3sas/mpt3sas_base.c +18 -2
@@ -2371,6 +2371,22 @@ _base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr)_base_add_sg_single_ieee (paddr, sgl_flags,0 ,0 ,-1 ); } +static inline int _base_scsi_dma_map (struct scsi_cmnd *cmd) +{ +/* +* Some firmware versions byte-swap the REPORT ZONES command reply from +* ATA-ZAC devices by directly accessing in the host buffer. This does +* not respect the default command DMA direction and causes IOMMU page +* faults on some architectures with an IOMMU enforcing write mappings +* (e.g. AMD hosts). Avoid such issue by making the report zones buffer +* mapping bi-directional. +*/ +if (cmd->cmnd[0 ] ==ZBC_IN && cmd->cmnd[1 ] ==ZI_REPORT_ZONES ) + cmd->sc_data_direction =DMA_BIDIRECTIONAL ; + +return scsi_dma_map (cmd); +} +/** * _base_build_sg_scmd - main sg creation routine * pcie_device is unused here!
@@ -2417,7 +2433,7 @@ _base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc, sgl_flags = sgl_flags <<MPI2_SGE_FLAGS_SHIFT ; sg_scmd =scsi_sglist (scmd); - sges_left =scsi_dma_map (scmd); + sges_left =_base_scsi_dma_map (scmd);if (sges_left <0 )return -ENOMEM ;
@@ -2561,7 +2577,7 @@ _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc, } sg_scmd =scsi_sglist (scmd); - sges_left =scsi_dma_map (scmd); + sges_left =_base_scsi_dma_map (scmd);if (sges_left <0 )return -ENOMEM ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 241/259 serial: core: check uartclk for zero to avoid divide by zero
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: George Kennedy <[email protected]>
commit 6eabce6608d6f3440f4c03aa3d3ef50a47a3d193 upstream.
Calling ioctl TIOCSSERIAL with an invalid baud_base can result in uartclk being zero, which will result in a divide by zero error in uart_get_divisor(). The check for uartclk being zero in uart_set_info() needs to be done before other settings are made as subsequent calls to ioctl TIOCSSERIAL for the same port would be impacted if the uartclk check was done where uartclk gets set.
Oops: divide error: 0000 PREEMPT SMP KASAN PTI
RIP: 0010:uart_get_divisor (drivers/tty/serial/serial_core.c:580)
Call Trace:
<TASK>
serial8250_get_divisor (drivers/tty/serial/8250/8250_port.c:2576
drivers/tty/serial/8250/8250_port.c:2589)
serial8250_do_set_termios (drivers/tty/serial/8250/8250_port.c:502
drivers/tty/serial/8250/8250_port.c:2741)
serial8250_set_termios (drivers/tty/serial/8250/8250_port.c:2862)
uart_change_line_settings (./include/linux/spinlock.h:376
./include/linux/serial_core.h:608 drivers/tty/serial/serial_core.c:222)uart_port_startup (drivers/tty/serial/serial_core.c:342) uart_startup (drivers/tty/serial/serial_core.c:368) uart_set_info (drivers/tty/serial/serial_core.c:1034) uart_set_info_user (drivers/tty/serial/serial_core.c:1059) tty_set_serial (drivers/tty/tty_io.c:2637)
tty_ioctl (drivers/tty/tty_io.c:2647 drivers/tty/tty_io.c:2791)
__x64_sys_ioctl (fs/ioctl.c:52 fs/ioctl.c:907
fs/ioctl.c:893 fs/ioctl.c:893)
do_syscall_64 (arch/x86/entry/common.c:52
(discriminator 1) arch/x86/entry/common.c:83 (discriminator 1))entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
Rule: add
--- drivers/tty/serial/serial_core.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/tty/serial/serial_core.c +8 -0
@@ -854,6 +854,14 @@ static int uart_set_info(struct tty_stru new_flags = (__force upf_t )new_info->flags; old_custom_divisor = uport->custom_divisor; +if (!(uport->flags &UPF_FIXED_PORT )) { +unsigned int uartclk = new_info->baud_base *16 ; +/* check needs to be done here before other settings made */ +if (uartclk ==0 ) { + retval = -EINVAL ; + goto exit; + } + }if (!capable (CAP_SYS_ADMIN )) { retval = -EPERM ; if (change_irq || change_port ||
Greg Kroah-Hartman
maintainerPATCH 242/259 genirq/irqdesc: Honor caller provided affinity in alloc_desc()
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shay Drory <[email protected]>
commit edbbaae42a56f9a2b39c52ef2504dfb3fb0a7858 upstream.
Currently, whenever a caller is providing an affinity hint for an interrupt, the allocation code uses it to calculate the node and copies the cpumask into irq_desc::affinity.
If the affinity for the interrupt is not marked 'managed' then the startup of the interrupt ignores irq_desc::affinity and uses the system default affinity mask.
Prevent this by setting the IRQD_AFFINITY_SET flag for the interrupt in the allocator, which causes irq_setup_affinity() to use irq_desc::affinity on interrupt startup if the mask contains an online CPU.
[ tglx: Massaged changelog ]
--- kernel/irq/irqdesc.c | 1 + 1 file changed, 1 insertion(+)
kernel/irq/irqdesc.c +1 -0
@@ -491,6 +491,7 @@ static int alloc_descs(unsigned int star flags =IRQD_AFFINITY_MANAGED |IRQD_MANAGED_SHUTDOWN ; } + flags |=IRQD_AFFINITY_SET ; mask = &affinity->mask; node =cpu_to_node (cpumask_first (mask)); affinity++;
Greg Kroah-Hartman
maintainerPATCH 243/259 power: supply: axp288_charger: Fix constant_charge_voltage writes
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit b34ce4a59cfe9cd0d6f870e6408e8ec88a964585 upstream.
info->max_cv is in millivolts, divide the microvolt value being written to constant_charge_voltage by 1000 *before* clamping it to info->max_cv.
Before this fix the code always tried to set constant_charge_voltage to max_cv / 1000 = 4 millivolt, which ends up in setting it to 4.1V which is the lowest supported value.
--- drivers/power/supply/axp288_charger.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/power/supply/axp288_charger.c +2 -2
@@ -371,8 +371,8 @@ static int axp288_charger_usb_set_properdev_warn (&info->pdev->dev,"set charge current failed\n" );break ;case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE : - scaled_val =min (val->intval, info->max_cv); - scaled_val =DIV_ROUND_CLOSEST (scaled_val,1000 ); + scaled_val =DIV_ROUND_CLOSEST (val->intval,1000 ); + scaled_val =min (scaled_val, info->max_cv); ret =axp288_charger_set_cv (info, scaled_val);if (ret <0 )dev_warn (&info->pdev->dev,"set charge voltage failed\n" );
Greg Kroah-Hartman
maintainerPATCH 244/259 power: supply: axp288_charger: Round constant_charge_voltage writes down
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit 81af7f2342d162e24ac820c10e68684d9f927663 upstream.
Round constant_charge_voltage writes down to the first supported lower value, rather then rounding them up to the first supported higher value.
This fixes e.g. writing 4250000 resulting in a value of 4350000 which might be dangerous, instead writing 4250000 will now result in a safe 4200000 value.
--- drivers/power/supply/axp288_charger.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/power/supply/axp288_charger.c +9 -9
@@ -168,18 +168,18 @@ static inline int axp288_charger_set_cv(u8 reg_val;int ret; -if (cv <=CV_4100MV ) { - reg_val =CHRG_CCCV_CV_4100MV ; - cv =CV_4100MV ; - }else if (cv <=CV_4150MV ) { - reg_val =CHRG_CCCV_CV_4150MV ; - cv =CV_4150MV ; - }else if (cv <=CV_4200MV ) { +if (cv >=CV_4350MV ) { + reg_val =CHRG_CCCV_CV_4350MV ; + cv =CV_4350MV ; + }else if (cv >=CV_4200MV ) { reg_val =CHRG_CCCV_CV_4200MV ; cv =CV_4200MV ; + }else if (cv >=CV_4150MV ) { + reg_val =CHRG_CCCV_CV_4150MV ; + cv =CV_4150MV ; }else { - reg_val =CHRG_CCCV_CV_4350MV ; - cv =CV_4350MV ; + reg_val =CHRG_CCCV_CV_4100MV ; + cv =CV_4100MV ; } reg_val = reg_val <<CHRG_CCCV_CV_BIT_POS ;
Greg Kroah-Hartman
maintainerPATCH 245/259 tracing: Fix overflow in get_free_elt()
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tze-nan Wu <[email protected]>
commit bcf86c01ca4676316557dd482c8416ece8c2e143 upstream.
"tracing_map->next_elt" in get_free_elt() is at risk of overflowing.
Once it overflows, new elements can still be inserted into the tracing_map even though the maximum number of elements (max_elts) has been reached. Continuing to insert elements after the overflow could result in the tracing_map containing "tracing_map->max_size" elements, leaving no empty entries.
If any attempt is made to insert an element into a full tracing_map using __tracing_map_insert(), it will cause an infinite loop with preemption disabled, leading to a CPU hang problem.
Fix this by preventing any further increments to "tracing_map->next_elt" once it reaches "tracing_map->max_elt".
--- kernel/trace/tracing_map.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/trace/tracing_map.c +3 -3
@@ -454,7 +454,7 @@ static struct tracing_map_elt *get_free_struct tracing_map_elt *elt =NULL ;int idx; - idx =atomic_inc_return (&map->next_elt); + idx =atomic_fetch_add_unless (&map->next_elt,1 , map->max_elts);if (idx < map->max_elts) { elt = *(TRACING_MAP_ELT (map->elts, idx));if (map->ops && map->ops->elt_init)
@@ -699,7 +699,7 @@ void tracing_map_clear(struct tracing_ma {unsigned int i; -atomic_set (&map->next_elt,-1 ); +atomic_set (&map->next_elt,0 );atomic64_set (&map->hits,0 );atomic64_set (&map->drops,0 );
@@ -783,7 +783,7 @@ struct tracing_map *tracing_map_create(u map->map_bits = map_bits; map->max_elts = (1 << map_bits); -atomic_set (&map->next_elt,-1 ); +atomic_set (&map->next_elt,0 ); map->map_size = (1 << (map_bits +1 )); map->ops = ops;
Greg Kroah-Hartman
maintainerPATCH 246/259 x86/mtrr: Check if fixed MTRRs exist before saving them
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andi Kleen <[email protected]>
commit 919f18f961c03d6694aa726c514184f2311a4614 upstream.
MTRRs have an obsolete fixed variant for fine grained caching control of the 640K-1MB region that uses separate MSRs. This fixed variant has a separate capability bit in the MTRR capability MSR.
So far all x86 CPUs which support MTRR have this separate bit set, so it went unnoticed that mtrr_save_state() does not check the capability bit before accessing the fixed MTRR MSRs.
Though on a CPU that does not support the fixed MTRR capability this results in a #GP. The #GP itself is harmless because the RDMSR fault is handled gracefully, but results in a WARN_ON().
Add the missing capability check to prevent this.
--- arch/x86/kernel/cpu/mtrr/mtrr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/mtrr/mtrr.c +1 -1
@@ -817,7 +817,7 @@ void mtrr_save_state(void) {int first_cpu; -if (!mtrr_enabled ()) +if (!mtrr_enabled () || !mtrr_state.have_fixed)return ; first_cpu =cpumask_first (cpu_online_mask);
Greg Kroah-Hartman
maintainerPATCH 247/259 drm/bridge: analogix_dp: properly handle zero sized AUX transactions
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lucas Stach <[email protected]>
commit e82290a2e0e8ec5e836ecad1ca025021b3855c2d upstream.
Address only transactions without any data are valid and should not be flagged as short transactions. Simply return the message size when no transaction errors occured.
--- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +1 -4
@@ -1115,7 +1115,6 @@ ssize_t analogix_dp_transfer(struct analu32 status_reg;u8 *buffer = msg->buffer;unsigned int i; -int num_transferred =0 ;int ret;/* Buffer size of AUX CH is 16 bytes */
@@ -1167,7 +1166,6 @@ ssize_t analogix_dp_transfer(struct anal reg = buffer[i];writel (reg, dp->reg_base +ANALOGIX_DP_BUF_DATA_0 +4 * i); - num_transferred++; } }
@@ -1215,7 +1213,6 @@ ssize_t analogix_dp_transfer(struct anal reg =readl (dp->reg_base +ANALOGIX_DP_BUF_DATA_0 +4 * i); buffer[i] = (unsigned char )reg; - num_transferred++; } }
@@ -1232,7 +1229,7 @@ ssize_t analogix_dp_transfer(struct anal (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ) msg->reply = DP_AUX_NATIVE_REPLY_ACK; -return num_transferred >0 ? num_transferred : -EBUSY ; +return msg->size; aux_error:/* if aux err happen, reset aux */
Greg Kroah-Hartman
maintainerPATCH 248/259 drm/mgag200: Set DDC timeout in milliseconds
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann <[email protected]>
commit ecde5db1598aecab54cc392282c15114f526f05f upstream.
Compute the i2c timeout in jiffies from a value in milliseconds. The original values of 2 jiffies equals 2 milliseconds if HZ has been configured to a value of 1000. This corresponds to 2.2 milliseconds used by most other DRM drivers. Update mgag200 accordingly.
--- drivers/gpu/drm/mgag200/mgag200_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/mgag200/mgag200_i2c.c +1 -1
@@ -135,7 +135,7 @@ struct mga_i2c_chan *mgag200_i2c_create( i2c->adapter.algo_data = &i2c->bit; i2c->bit.udelay =10 ; - i2c->bit.timeout =2 ; + i2c->bit.timeout =usecs_to_jiffies (2200 ); i2c->bit.data = i2c; i2c->bit.setsda = mga_gpio_setsda; i2c->bit.setscl = mga_gpio_setscl;
Greg Kroah-Hartman
maintainerPATCH 249/259 Fix gcc 4.9 build issue in 5.4.y
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jari Ruusu <[email protected]>
Some older systems still compile kernels with old gcc version. These warnings and errors show up when compiling with gcc 4.9.2
error: "__GCC4_has_attribute___uninitialized__" is not defined [-Werror=undef]
Upstream won't need this because newer kernels are not compilable with gcc 4.9.
Subject: [PATCH 5.4 249/259] gcc-4.9 warning/error fix for 5.10.223-rc1
--- include/linux/compiler_attributes.h | 1 + 1 file changed, 1 insertion(+)
include/linux/compiler_attributes.h +1 -0
@@ -40,6 +40,7 @@# define __GCC4_has_attribute___noclone__ 1# define __GCC4_has_attribute___nonstring__ 0# define __GCC4_has_attribute___no_sanitize_address__ (__GNUC_MINOR__ >= 8) +# define __GCC4_has_attribute___uninitialized__ 0# define __GCC4_has_attribute___fallthrough__ 0#endif
Greg Kroah-Hartman
maintainerPATCH 250/259 kbuild: Fix -S -c in x86 stack protector scripts
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
commit 3415b10a03945b0da4a635e146750dfe5ce0f448 upstream.
After a recent change in clang to stop consuming all instances of '-S' and '-c' [1], the stack protector scripts break due to the kernel's use of -Werror=unused-command-line-argument to catch cases where flags are not being properly consumed by the compiler driver:
$ echo | clang -o - -x c - -S -c -Werror=unused-command-line-argument clang: error: argument unused during compilation: '-c' [-Werror,-Wunused-command-line-argument]
This results in CONFIG_STACKPROTECTOR getting disabled because CONFIG_CC_HAS_SANE_STACKPROTECTOR is no longer set.
'-c' and '-S' both instruct the compiler to stop at different stages of the pipeline ('-S' after compiling, '-c' after assembling), so having them present together in the same command makes little sense. In this case, the test wants to stop before assembling because it is looking at the textual assembly output of the compiler for either '%fs' or '%gs', so remove '-c' from the list of arguments to resolve the error.
All versions of GCC continue to work after this change, along with versions of clang that do or do not contain the change mentioned above.
--- scripts/gcc-x86_32-has-stack-protector.sh | 2 +- scripts/gcc-x86_64-has-stack-protector.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
scripts/gcc-x86_32-has-stack-protector.sh +1 -1
@@ -1,4 +1,4 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 -echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m32 -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs" +echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -m32 -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
scripts/gcc-x86_64-has-stack-protector.sh +1 -1
@@ -1,4 +1,4 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 -echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m64 -O0 -mcmodel=kernel -fno-PIE -fstack-protector - -o - 2> /dev/null | grep -q "%gs" +echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -m64 -O0 -mcmodel=kernel -fno-PIE -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
Greg Kroah-Hartman
maintainerPATCH 251/259 netfilter: nf_tables: set element extended ACK reporting support
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
commit b53c116642502b0c85ecef78bff4f826a7dd4145 upstream.
Report the element that causes problems via netlink extended ACK for set element commands.
--- net/netfilter/nf_tables_api.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
net/netfilter/nf_tables_api.c +9 -4
@@ -4670,8 +4670,10 @@ static int nf_tables_getsetelem(struct nnla_for_each_nested (attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS ], rem) { err =nft_get_set_elem (&ctx, set, attr); -if (err <0 ) +if (err <0 ) { +NL_SET_BAD_ATTR (extack, attr);break ; + } }return err;
@@ -5063,8 +5065,10 @@ static int nf_tables_newsetelem(struct nnla_for_each_nested (attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS ], rem) { err =nft_add_set_elem (&ctx, set, attr, nlh->nlmsg_flags); -if (err <0 ) +if (err <0 ) { +NL_SET_BAD_ATTR (extack, attr);return err; + } }if (nft_net->validate_state ==NFT_VALIDATE_DO )
@@ -5264,9 +5268,10 @@ static int nf_tables_delsetelem(struct nnla_for_each_nested (attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS ], rem) { err =nft_del_setelem (&ctx, set, attr); -if (err <0 ) +if (err <0 ) { +NL_SET_BAD_ATTR (extack, attr);break ; - + } set->ndeact++; }return err;
Greg Kroah-Hartman
maintainerPATCH 252/259 netfilter: nf_tables: use timestamp to check for set element timeout
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
commit 7395dfacfff65e9938ac0889dafa1ab01e987d15 upstream
Add a timestamp field at the beginning of the transaction, store it in the nftables per-netns area.
Update set backend .insert, .deactivate and sync gc path to use the timestamp, this avoids that an element expires while control plane transaction is still unfinished.
.lookup and .update, which are used from packet path, still use the current time to check if the element has expired. And .get path and dump also since this runs lockless under rcu read size lock. Then, there is async gc which also needs to check the current time since it runs asynchronously from a workqueue.
[ NB: rbtree GC updates has been excluded because GC is asynchronous. ]
--- include/net/netfilter/nf_tables.h | 21 +++++++++++++++++++-- net/netfilter/nf_tables_api.c | 1 + net/netfilter/nft_set_hash.c | 8 +++++++- net/netfilter/nft_set_rbtree.c | 6 ++++-- 4 files changed, 31 insertions(+), 5 deletions(-)
include/net/netfilter/nf_tables.h +19 -2
@@ -13,6 +13,7 @@#include <net/netfilter/nf_flow_table.h> #include <net/netlink.h> #include <net/flow_offload.h> +#include <net/netns/generic.h> struct module ;
@@ -656,10 +657,16 @@ static inline struct nft_expr *nft_set_ereturn nft_set_ext (ext,NFT_SET_EXT_EXPR ); } -static inline bool nft_set_elem_expired (const struct nft_set_ext *ext) +static inline bool __nft_set_elem_expired (const struct nft_set_ext *ext, +u64 tstamp) {return nft_set_ext_exists (ext,NFT_SET_EXT_EXPIRATION ) && -time_is_before_eq_jiffies64 (*nft_set_ext_expiration (ext)); +time_after_eq64 (tstamp, *nft_set_ext_expiration (ext)); +} + +static inline bool nft_set_elem_expired (const struct nft_set_ext *ext) +{ +return __nft_set_elem_expired (ext,get_jiffies_64 ()); } static inline struct nft_set_ext *nft_set_elem_ext(const struct nft_set *set,
@@ -1482,9 +1489,19 @@ struct nftables_pernet {struct list_head module_list;struct list_head notify_list;struct mutex commit_mutex; +u64 tstamp;unsigned int base_seq;u8 validate_state; unsigned int gc_seq; }; +extern unsigned int nf_tables_net_id; + +static inline u64 nft_net_tstamp (const struct net *net) +{ +struct nftables_pernet *nft_net =net_generic (net, nf_tables_net_id); + +return nft_net->tstamp; +} +#endif /* _NET_NF_TABLES_H */
net/netfilter/nf_tables_api.c +1 -0
@@ -7758,6 +7758,7 @@ static bool nf_tables_valid_genid(structbool genid_ok;mutex_lock (&nft_net->commit_mutex); + nft_net->tstamp =get_jiffies_64 (); genid_ok = genid ==0 || nft_net->base_seq == genid;if (!genid_ok)
net/netfilter/nft_set_hash.c +7 -1
@@ -38,6 +38,7 @@ struct nft_rhash_cmp_arg {const struct nft_set *set;const u32 *key;u8 genmask; +u64 tstamp; };static inline u32 nft_rhash_key (const void *data,u32 len,u32 seed)
@@ -64,7 +65,7 @@ static inline int nft_rhash_cmp(struct rreturn 1 ;if (nft_set_elem_is_dead (&he->ext))return 1 ; -if (nft_set_elem_expired (&he->ext)) +if (__nft_set_elem_expired (&he->ext, x->tstamp))return 1 ;if (!nft_set_elem_active (&he->ext, x->genmask))return 1 ;
@@ -88,6 +89,7 @@ static bool nft_rhash_lookup(const struc .genmask = nft_genmask_cur(net), .set = set, .key = key, + .tstamp = get_jiffies_64(), }; he =rhashtable_lookup (&priv->ht, &arg, nft_rhash_params);
@@ -106,6 +108,7 @@ static void *nft_rhash_get(const struct .genmask = nft_genmask_cur(net), .set = set, .key = elem->key.val.data, + .tstamp = get_jiffies_64(), }; he =rhashtable_lookup (&priv->ht, &arg, nft_rhash_params);
@@ -129,6 +132,7 @@ static bool nft_rhash_update(struct nft_ .genmask = NFT_GENMASK_ANY, .set = set, .key = key, + .tstamp = get_jiffies_64(), }; he =rhashtable_lookup (&priv->ht, &arg, nft_rhash_params);
@@ -172,6 +176,7 @@ static int nft_rhash_insert(const struct .genmask = nft_genmask_next(net), .set = set, .key = elem->key.val.data, + .tstamp = nft_net_tstamp(net), };struct nft_rhash_elem *prev;
@@ -214,6 +219,7 @@ static void *nft_rhash_deactivate(const .genmask = nft_genmask_next(net), .set = set, .key = elem->key.val.data, + .tstamp = nft_net_tstamp(net), };rcu_read_lock ();
net/netfilter/nft_set_rbtree.c +4 -2
@@ -315,6 +315,7 @@ static int __nft_rbtree_insert(const strstruct nft_rbtree *priv =nft_set_priv (set);u8 cur_genmask =nft_genmask_cur (net);u8 genmask =nft_genmask_next (net); +u64 tstamp =nft_net_tstamp (net);int d, err;/* Descend the tree to search for an existing element greater than the
@@ -362,7 +363,7 @@ static int __nft_rbtree_insert(const str/* perform garbage collection to avoid bogus overlap reports * but skip new elements in this transaction. */ -if (nft_set_elem_expired (&rbe->ext) && +if (__nft_set_elem_expired (&rbe->ext, tstamp) &&nft_set_elem_active (&rbe->ext, cur_genmask)) { err =nft_rbtree_gc_elem (set, priv, rbe);if (err <0 )
@@ -537,6 +538,7 @@ static void *nft_rbtree_deactivate(constconst struct rb_node *parent = priv->root.rb_node;struct nft_rbtree_elem *rbe, *this = elem->priv;u8 genmask =nft_genmask_next (net); +u64 tstamp =nft_net_tstamp (net);int d;while (parent !=NULL ) {
@@ -557,7 +559,7 @@ static void *nft_rbtree_deactivate(const nft_rbtree_interval_end(this)) { parent = parent->rb_right;continue ; - } else if (nft_set_elem_expired(&rbe->ext)) { + } else if (__nft_set_elem_expired(&rbe->ext, tstamp)) {break ; } else if (!nft_set_elem_active(&rbe->ext, genmask)) { parent = parent->rb_left;
Greg Kroah-Hartman
maintainerPATCH 253/259 netfilter: nf_tables: prefer nft_chain_validate
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit cff3bd012a9512ac5ed858d38e6ed65f6391008c upstream.
nft_chain_validate already performs loop detection because a cycle will result in a call stack overflow (ctx->level >= NFT_JUMP_STACK_SIZE).
It also follows maps via ->validate callback in nft_lookup, so there appears no reason to iterate the maps again.
nf_tables_check_loops() and all its helper functions can be removed. This improves ruleset load time significantly, from 23s down to 12s.
This also fixes a crash bug. Old loop detection code can result in unbounded recursion:
BUG: TASK stack guard page was hit at .... Oops: stack guard page: 0000 [#1] PREEMPT SMP KASAN CPU: 4 PID: 1539 Comm: nft Not tainted 6.10.0-rc5+ #1
[..]
with a suitable ruleset during validation of register stores.
I can't see any actual reason to attempt to check for this from nft_validate_register_store(), at this point the transaction is still in progress, so we don't have a full picture of the rule graph.
For nf-next it might make sense to either remove it or make this depend on table->validate_state in case we could catch an error earlier (for improved error reporting to userspace).
--- net/netfilter/nf_tables_api.c | 114 ++++-------------------------------------- 1 file changed, 13 insertions(+), 101 deletions(-)
net/netfilter/nf_tables_api.c +13 -101
@@ -2829,6 +2829,15 @@ static void nf_tables_rule_release(constnf_tables_rule_destroy (ctx, rule); } +/** nft_chain_validate - loop detection and hook validation +* +* @ctx: context containing call depth and base chain +* @chain: chain to validate +* +* Walk through the rules of the given chain and chase all jumps/gotos +* and set lookups until either the jump limit is hit or all reachable +* chains have been validated. +*/ int nft_chain_validate (const struct nft_ctx *ctx,const struct nft_chain *chain) {struct nft_expr *expr, *last;
@@ -2847,6 +2856,9 @@ int nft_chain_validate(const struct nft_if (!expr->ops->validate)continue ; +/* This may call nft_chain_validate() recursively, +* callers that do so must increment ctx->level. +*/ err = expr->ops->validate (ctx, expr, &data);if (err <0 )return err;
@@ -7811,106 +7823,6 @@ int nft_chain_validate_hooks(const struc }EXPORT_SYMBOL_GPL (nft_chain_validate_hooks); -/* -* Loop detection - walk through the ruleset beginning at the destination chain -* of a new jump until either the source chain is reached (loop) or all -* reachable chains have been traversed. -* -* The loop check is performed whenever a new jump verdict is added to an -* expression or verdict map or a verdict map is bound to a new chain. -*/ - -static int nf_tables_check_loops (const struct nft_ctx *ctx, -const struct nft_chain *chain); - -static int nf_tables_loop_check_setelem (const struct nft_ctx *ctx, -struct nft_set *set, -const struct nft_set_iter *iter, -struct nft_set_elem *elem) -{ -const struct nft_set_ext *ext =nft_set_elem_ext (set, elem->priv); -const struct nft_data *data; - -if (nft_set_ext_exists (ext,NFT_SET_EXT_FLAGS ) && - *nft_set_ext_flags (ext) &NFT_SET_ELEM_INTERVAL_END ) -return 0 ; - - data =nft_set_ext_data (ext); -switch (data->verdict.code) { -case NFT_JUMP : -case NFT_GOTO : -return nf_tables_check_loops (ctx, data->verdict.chain); -default : -return 0 ; - } -} - -static int nf_tables_check_loops (const struct nft_ctx *ctx, -const struct nft_chain *chain) -{ -const struct nft_rule *rule; -const struct nft_expr *expr, *last; -struct nft_set *set; -struct nft_set_binding *binding; -struct nft_set_iter iter; - -if (ctx->chain == chain) -return -ELOOP ; - -list_for_each_entry (rule, &chain->rules, list) { -nft_rule_for_each_expr (expr, last, rule) { -struct nft_immediate_expr *priv; -const struct nft_data *data; -int err; - -if (strcmp (expr->ops->type->name,"immediate" )) -continue ; - - priv =nft_expr_priv (expr); -if (priv->dreg !=NFT_REG_VERDICT ) -continue ; - - data = &priv->data; -switch (data->verdict.code) { -case NFT_JUMP : -case NFT_GOTO : - err =nf_tables_check_loops (ctx, - data->verdict.chain); -if (err <0 ) -return err; -default : -break ; - } - } - } - -list_for_each_entry (set, &ctx->table->sets, list) { -if (!nft_is_active_next (ctx->net, set)) -continue ; -if (!(set->flags &NFT_SET_MAP ) || - set->dtype !=NFT_DATA_VERDICT ) -continue ; - -list_for_each_entry (binding, &set->bindings, list) { -if (!(binding->flags &NFT_SET_MAP ) || - binding->chain != chain) -continue ; - - iter.genmask =nft_genmask_next (ctx->net); - iter.skip =0 ; - iter.count =0 ; - iter.err =0 ; - iter.fn = nf_tables_loop_check_setelem; - - set->ops->walk (ctx, set, &iter); -if (iter.err <0 ) -return iter.err; - } - } - -return 0 ; -} -/** * nft_parse_u32_check - fetch u32 attribute and check for maximum value *
@@ -8046,7 +7958,7 @@ static int nft_validate_register_store(cif (data !=NULL && (data->verdict.code ==NFT_GOTO || data->verdict.code ==NFT_JUMP )) { - err =nf_tables_check_loops (ctx, data->verdict.chain); + err =nft_chain_validate (ctx, data->verdict.chain);if (err <0 )return err; }
Greg Kroah-Hartman
maintainerPATCH 254/259 drm/i915/gem: Fix Virtual Memory mapping boundaries calculation
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andi Shyti <[email protected]>
commit 8bdd9ef7e9b1b2a73e394712b72b22055e0e26c3 upstream.
Calculating the size of the mapped area as the lesser value between the requested size and the actual size does not consider the partial mapping offset. This can cause page fault access.
Fix the calculation of the starting and ending addresses, the total size is now deduced from the difference between the end and start addresses.
Additionally, the calculations have been rewritten in a clearer and more understandable form.
Requires: 60a2066c5005 ("drm/i915/gem: Adjust vma offset for framebuffer mmap offset")
--- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 47 +++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 5 deletions(-)
drivers/gpu/drm/i915/gem/i915_gem_mman.c +42 -5
@@ -196,6 +196,39 @@ compute_partial_view(const struct drm_i9return view; } +static void set_address_limits (struct vm_area_struct *area, +struct i915_vma *vma, +unsigned long *start_vaddr, +unsigned long *end_vaddr) +{ +unsigned long vm_start, vm_end, vma_size;/* user's memory parameters */ +long start, end;/* memory boundaries */ + +/* +* Let's move into the ">> PAGE_SHIFT" +* domain to be sure not to lose bits +*/ + vm_start = area->vm_start >>PAGE_SHIFT ; + vm_end = area->vm_end >>PAGE_SHIFT ; + vma_size = vma->size >>PAGE_SHIFT ; + +/* +* Calculate the memory boundaries by considering the offset +* provided by the user during memory mapping and the offset +* provided for the partial mapping. +*/ + start = vm_start; + start += vma->ggtt_view.partial.offset; + end = start + vma_size; + + start =max_t (long, start, vm_start); + end =min_t (long, end, vm_end); + +/* Let's move back into the "<< PAGE_SHIFT" domain */ + *start_vaddr = (unsigned long )start <<PAGE_SHIFT ; + *end_vaddr = (unsigned long )end <<PAGE_SHIFT ; +} +/** * i915_gem_fault - fault a page into the GTT * @vmf: fault info
@@ -224,9 +257,11 @@ vm_fault_t i915_gem_fault(struct vm_faulstruct intel_runtime_pm *rpm = &i915->runtime_pm;struct i915_ggtt *ggtt = &i915->ggtt;bool write = area->vm_flags &VM_WRITE ; +unsigned long start, end;/* memory boundaries */ intel_wakeref_t wakeref;struct i915_vma *vma;pgoff_t page_offset; +unsigned long pfn;int srcu;int ret;
@@ -295,12 +330,14 @@ vm_fault_t i915_gem_fault(struct vm_faulif (ret) goto err_unpin; +set_address_limits (area, vma, &start, &end); + + pfn = (ggtt->gmadr.start +i915_ggtt_offset (vma)) >>PAGE_SHIFT ; + pfn += (start - area->vm_start) >>PAGE_SHIFT ; + pfn -= vma->ggtt_view.partial.offset; +/* Finally, remap it using the new GTT offset */ - ret =remap_io_mapping (area, - area->vm_start + (vma->ggtt_view.partial.offset <<PAGE_SHIFT ), - (ggtt->gmadr.start + vma->node.start) >>PAGE_SHIFT , -min_t (u64, vma->size, area->vm_end - area->vm_start), - &ggtt->iomap); + ret =remap_io_mapping (area, start, pfn, end - start, &ggtt->iomap);if (ret) goto err_fence;
Greg Kroah-Hartman
maintainerPATCH 255/259 arm64: cpufeature: Fix the visibility of compat hwcaps
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amit Daniel Kachhap <[email protected]>
commit 85f1506337f0c79a4955edfeee86a18628e3735f upstream.
Commit 237405ebef58 ("arm64: cpufeature: Force HWCAP to be based on the sysreg visible to user-space") forced the hwcaps to use sanitised user-space view of the id registers. However, the ID register structures used to select few compat cpufeatures (vfp, crc32, ...) are masked and hence such hwcaps do not appear in /proc/cpuinfo anymore for PER_LINUX32 personality.
Add the ID register structures explicitly and set the relevant entry as visible. As these ID registers are now of type visible so make them available in 64-bit userspace by making necessary changes in register emulation logic and documentation.
While at it, update the comment for structure ftr_generic_32bits[] which lists the ID register that use it.
--- Documentation/arm64/cpu-feature-registers.rst | 38 ++++++++++++++++++++++- arch/arm64/kernel/cpufeature.c | 42 ++++++++++++++++++++------ 2 files changed, 70 insertions(+), 10 deletions(-)
Documentation/arm64/cpu-feature-registers.rst +37 -1
@@ -92,7 +92,7 @@ operation if the source belongs to the s The infrastructure emulates only the following system register space:: - Op0=3, Op1=0, CRn=0, CRm=0,4,5,6,7 + Op0=3, Op1=0, CRn=0, CRm=0,2,3,4,5,6,7 (See Table C5-6 'System instruction encodings for non-Debug System register accesses' in ARMv8 ARM DDI 0487A.h, for the list of
@@ -167,6 +167,42 @@ infrastructure: | EL0 | [3-0] | n | +------------------------------+---------+---------+ + 10) MVFR0_EL1 - AArch32 Media and VFP Feature Register 0 + + +------------------------------+---------+---------+ + | Name | bits | visible | + +------------------------------+---------+---------+ + | FPDP | [11-8] | y | + +------------------------------+---------+---------+ + + 11) MVFR1_EL1 - AArch32 Media and VFP Feature Register 1 + + +------------------------------+---------+---------+ + | Name | bits | visible | + +------------------------------+---------+---------+ + | SIMDFMAC | [31-28] | y | + +------------------------------+---------+---------+ + | SIMDSP | [19-16] | y | + +------------------------------+---------+---------+ + | SIMDInt | [15-12] | y | + +------------------------------+---------+---------+ + | SIMDLS | [11-8] | y | + +------------------------------+---------+---------+ + + 12) ID_ISAR5_EL1 - AArch32 Instruction Set Attribute Register 5 + + +------------------------------+---------+---------+ + | Name | bits | visible | + +------------------------------+---------+---------+ + | CRC32 | [19-16] | y | + +------------------------------+---------+---------+ + | SHA2 | [15-12] | y | + +------------------------------+---------+---------+ + | SHA1 | [11-8] | y | + +------------------------------+---------+---------+ + | AES | [7-4] | y | + +------------------------------+---------+---------+ + 3) MIDR_EL1 - Main ID Register
arch/arm64/kernel/cpufeature.c +33 -9
78 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 256/259 media: uvcvideo: Use entity get_cur in uvc_ctrl_set
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yunke Cao <[email protected]>
commit 5f36851c36b30f713f588ed2b60aa7b4512e2c76 upstream.
Entity controls should get_cur using an entity-defined function instead of via a query. Fix this in uvc_ctrl_set.
--- drivers/media/usb/uvc/uvc_ctrl.c | 83 +++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 37 deletions(-)
drivers/media/usb/uvc/uvc_ctrl.c +46 -37
@@ -992,36 +992,56 @@ static s32 __uvc_ctrl_get_value(struct ureturn value; } -static int __uvc_ctrl_get (struct uvc_video_chain *chain, -struct uvc_control *ctrl,struct uvc_control_mapping *mapping, -s32 *value) +static int __uvc_ctrl_load_cur (struct uvc_video_chain *chain, +struct uvc_control *ctrl) { +u8 *data;int ret; -if ((ctrl->info.flags &UVC_CTRL_FLAG_GET_CUR ) ==0 ) -return -EACCES ; +if (ctrl->loaded) +return 0 ; -if (!ctrl->loaded) { -if (ctrl->entity->get_cur) { - ret = ctrl->entity->get_cur (chain->dev, - ctrl->entity, - ctrl->info.selector, -uvc_ctrl_data (ctrl,UVC_CTRL_DATA_CURRENT ), - ctrl->info.size); - }else { - ret =uvc_query_ctrl (chain->dev,UVC_GET_CUR , - ctrl->entity->id, - chain->dev->intfnum, - ctrl->info.selector, -uvc_ctrl_data (ctrl,UVC_CTRL_DATA_CURRENT ), - ctrl->info.size); - } -if (ret <0 ) -return ret; + data =uvc_ctrl_data (ctrl,UVC_CTRL_DATA_CURRENT ); +if ((ctrl->info.flags &UVC_CTRL_FLAG_GET_CUR ) ==0 ) { +memset (data,0 , ctrl->info.size); ctrl->loaded =1 ; + +return 0 ; } +if (ctrl->entity->get_cur) + ret = ctrl->entity->get_cur (chain->dev, ctrl->entity, + ctrl->info.selector, data, + ctrl->info.size); +else + ret =uvc_query_ctrl (chain->dev,UVC_GET_CUR , + ctrl->entity->id, chain->dev->intfnum, + ctrl->info.selector, data, + ctrl->info.size); + +if (ret <0 ) +return ret; + + ctrl->loaded =1 ; + +return ret; +} + +static int __uvc_ctrl_get (struct uvc_video_chain *chain, +struct uvc_control *ctrl, +struct uvc_control_mapping *mapping, +s32 *value) +{ +int ret; + +if ((ctrl->info.flags &UVC_CTRL_FLAG_GET_CUR ) ==0 ) +return -EACCES ; + + ret =__uvc_ctrl_load_cur (chain, ctrl); +if (ret <0 ) +return ret; + *value =__uvc_ctrl_get_value (mapping,uvc_ctrl_data (ctrl,UVC_CTRL_DATA_CURRENT ));
@@ -1675,21 +1695,10 @@ int uvc_ctrl_set(struct uvc_fh *handle,* needs to be loaded from the device to perform the read-modify-write * operation. */ -if (!ctrl->loaded && (ctrl->info.size *8 ) != mapping->size) { -if ((ctrl->info.flags &UVC_CTRL_FLAG_GET_CUR ) ==0 ) { -memset (uvc_ctrl_data (ctrl,UVC_CTRL_DATA_CURRENT ), -0 , ctrl->info.size); - }else { - ret =uvc_query_ctrl (chain->dev,UVC_GET_CUR , - ctrl->entity->id, chain->dev->intfnum, - ctrl->info.selector, -uvc_ctrl_data (ctrl,UVC_CTRL_DATA_CURRENT ), - ctrl->info.size); -if (ret <0 ) -return ret; - } - - ctrl->loaded =1 ; +if ((ctrl->info.size *8 ) != mapping->size) { + ret =__uvc_ctrl_load_cur (chain, ctrl); +if (ret <0 ) +return ret; }/* Backup the current value in case we need to rollback later. */
Greg Kroah-Hartman
maintainerPATCH 257/259 exec: Fix ToCToU between perm check and set-uid/gid usage
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
commit f50733b45d865f91db90919f8311e2127ce5a0cb upstream.
When opening a file for exec via do_filp_open(), permission checking is done against the file's metadata at that moment, and on success, a file pointer is passed back. Much later in the execve() code path, the file metadata (specifically mode, uid, and gid) is used to determine if/how to set the uid and gid. However, those values may have changed since the permissions check, meaning the execution may gain unintended privileges.
For example, if a file could change permissions from executable and not set-id:
---------x 1 root root 16048 Aug 7 13:16 target
to set-id and non-executable:
---S------ 1 root root 16048 Aug 7 13:16 target
it is possible to gain root privileges when execution should have been disallowed.
While this race condition is rare in real-world scenarios, it has been observed (and proven exploitable) when package managers are updating the setuid bits of installed programs. Such files start with being world-executable but then are adjusted to be group-exec with a set-uid bit. For example, "chmod o-x,u+s target" makes "target" executable only by uid "root" and gid "cdrom", while also becoming setuid-root:
-rwxr-xr-x 1 root cdrom 16048 Aug 7 13:16 target
becomes:
-rwsr-xr-- 1 root cdrom 16048 Aug 7 13:16 target
But racing the chmod means users without group "cdrom" membership can get the permission to execute "target" just before the chmod, and when the chmod finishes, the exec reaches brpm_fill_uid(), and performs the setuid to root, violating the expressed authorization of "only cdrom group members can setuid to root".
Re-check that we still have execute permissions in case the metadata has changed. It would be better to keep a copy from the perm-check time, but until we can do that refactoring, the least-bad option is to do a full inode_permission() call (under inode lock). It is understood that this is safe against dead-locks, but hardly optimal.
--- fs/exec.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
fs/exec.c +7 -1
@@ -1558,6 +1558,7 @@ static void bprm_fill_uid(struct linux_bunsigned int mode;kuid_t uid;kgid_t gid; +int err;/* * Since this can be called multiple times (via prepare_binprm),
@@ -1582,12 +1583,17 @@ static void bprm_fill_uid(struct linux_b/* Be careful if suid/sgid is set */ inode_lock (inode); -/* reload atomically mode/uid/gid now that lock held */ +/* Atomically reload and check mode/uid/gid now that lock held. */ mode = inode->i_mode; uid = inode->i_uid; gid = inode->i_gid; + err =inode_permission (inode,MAY_EXEC );inode_unlock (inode); +/* Did the exec bit vanish out from under us? Give up. */ +if (err) +return ; +/* We ignore suid/sgid if there are no mappings for them in the ns */ if (!kuid_has_mapping (bprm->cred->user_ns, uid) || !kgid_has_mapping (bprm->cred->user_ns, gid))
Greg Kroah-Hartman
maintainerPATCH 258/259 nvme/pci: Add APST quirk for Lenovo N60z laptop
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: WangYuli <[email protected]>
commit ab091ec536cb7b271983c0c063b17f62f3591583 upstream.
There is a hardware power-saving problem with the Lenovo N60z board. When turn it on and leave it for 10 hours, there is a 20% chance that a nvme disk will not wake up until reboot.
--- drivers/nvme/host/pci.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/nvme/host/pci.c +7 -0
@@ -2822,6 +2822,13 @@ static unsigned long check_vendor_combinreturn NVME_QUIRK_SIMPLE_SUSPEND ; } +/* +* NVMe SSD drops off the PCIe bus after system idle +* for 10 hours on a Lenovo N60z board. +*/ +if (dmi_match (DMI_BOARD_NAME ,"LXKT-ZXEG-N6" )) +return NVME_QUIRK_NO_APST ; +return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 259/259 ARM: dts: imx6qdl-kontron-samx6i: fix phy-mode
In reply to Greg Kroah-Hartman5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Walle <[email protected]>
commit 0df3c7d7a73d75153090637392c0b73a63cdc24a upstream.
The i.MX6 cannot add any RGMII delays. The PHY has to add both the RX and TX delays on the RGMII interface. Fix the interface mode. While at it, use the new phy-connection-type property name.
--- arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi +1 -1
@@ -259,7 +259,7 @@ &fec { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; - phy-mode = "rgmii"; + phy-connection-type = "rgmii-id"; phy-handle = <ðphy>; mdio {
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.282 release. There are 259 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 Sat, 17 Aug 2024 13:18:17 +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.4.282-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.4.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
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.282 release. There are 259 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 Sat, 17 Aug 2024 13:18:17 +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.4.282-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.4.y
and the diffstat can be found below.thanks,
greg k-h
The following S390 build failed on stable-rc 5.4.y with gcc-12 due to following warnings and errors [1].
s390:
build:
* gcc-8-defconfig-fe40093d
* gcc-12-defconfig
Bisect point to deb23146ba03 ("s390/pci: fix CPU address in MSI for directed IRQ")
as the problematic commit [ Upstream commit a2bd4097b3ec242f4de4924db463a9c94530e03a ].
Build log:
------
/builds/linux/arch/s390/pci/pci_irq.c: In function 'zpci_set_irq_affinity':
/builds/linux/arch/s390/pci/pci_irq.c:106:17: error: implicit declaration of function 'smp_cpu_get_cpu_address'; did you mean 'device_get_mac_address'? [-Werror=implicit-function-declaration]
int cpu_addr = smp_cpu_get_cpu_address(cpumask_first(dest));
^~~~~~~~~~~~~~~~~~~~~~~
device_get_mac_address/builds/linux/arch/s390/pci/pci_irq.c: In function 'arch_setup_msi_irqs':
/builds/linux/arch/s390/pci/pci_irq.c:298:2: error: implicit declaration of function 'msi_for_each_desc'; did you mean 'bus_for_each_dev'? [-Werror=implicit-function-declaration]
msi_for_each_desc(msi, &pdev->dev, MSI_DESC_NOTASSOCIATED) { ^~~~~~~~~~~~~~~~~
bus_for_each_dev
/builds/linux/arch/s390/pci/pci_irq.c:298:37: error:
'MSI_DESC_NOTASSOCIATED' undeclared (first use in this function)
msi_for_each_desc(msi, &pdev->dev, MSI_DESC_NOTASSOCIATED) {
^~~~~~~~~~~~~~~~~~~~~~/builds/linux/arch/s390/pci/pci_irq.c:298:37: note: each undeclared identifier is reported only once for each function it appears in /builds/linux/arch/s390/pci/pci_irq.c:298:60: error: expected ';' before '{' token
msi_for_each_desc(msi, &pdev->dev, MSI_DESC_NOTASSOCIATED) {
^~
;Build log link:
-------
[1] https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.4.y/build/v5.4.281-260-g95ce4659a81b/testrun/24873581/suite/build/test/gcc-12-defconfig/log
metadata:
--------
* kernel: 5.4.282-rc1
* git: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
* git commit: 95ce4659a81b365646fc35fdd6678a62f8c02256
* git describe: v5.4.281-260-g95ce4659a81b
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.4.y/build/v5.4.281-260-g95ce4659a81b
* arch: s390
* toolchain: gcc-12
* config: https://storage.tuxsuite.com/public/linaro/lkft/builds/2khPUOCfrk64PMmp7nyDUvvt9j6/config
* download_url:
https://storage.tuxsuite.com/public/linaro/lkft/builds/2khPUOCfrk64PMmp7nyDUvvt9j6/
--
Linaro LKFT
https://lkft.linaro.org
Greg Kroah-Hartman
maintainerQuoted 54 lines · Anders Roxell
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.282 release. There are 259 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 Sat, 17 Aug 2024 13:18:17 +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.4.282-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.4.y
and the diffstat can be found below.thanks,
greg k-h
The following S390 build failed on stable-rc 5.4.y with gcc-12 due to following warnings and errors [1].
s390:
build:
* gcc-8-defconfig-fe40093d
* gcc-12-defconfigBisect point to
deb23146ba03("s390/pci: fix CPU address in MSI for directed IRQ")
as the problematic commit [ Upstream commita2bd4097b3ec242f4de4924db463a9c94530e03a].Build log:
------
/builds/linux/arch/s390/pci/pci_irq.c: In function 'zpci_set_irq_affinity':
/builds/linux/arch/s390/pci/pci_irq.c:106:17: error: implicit declaration of function 'smp_cpu_get_cpu_address'; did you mean 'device_get_mac_address'? [-Werror=implicit-function-declaration]int cpu_addr = smp_cpu_get_cpu_address(cpumask_first(dest)); ^~~~~~~~~~~~~~~~~~~~~~~ device_get_mac_address/builds/linux/arch/s390/pci/pci_irq.c: In function '
arch_setup_msi_irqs':
/builds/linux/arch/s390/pci/pci_irq.c:298:2: error: implicit declaration of function 'msi_for_each_desc'; did you mean 'bus_for_each_dev'? [-Werror=implicit-function-declaration]
msi_for_each_desc(msi, &pdev->dev, MSI_DESC_NOTASSOCIATED){ ^~~~~~~~~~~~~~~~~
bus_for_each_dev
/builds/linux/arch/s390/pci/pci_irq.c:298:37: error:
'MSI_DESC_NOTASSOCIATED' undeclared (first use in this function)
Quoted 8 lines
msi_for_each_desc(msi, &pdev->dev, MSI_DESC_NOTASSOCIATED) { ^~~~~~~~~~~~~~~~~~~~~~/builds/linux/arch/s390/pci/pci_irq.c:298:37: note: each undeclared identifier is reported only once for each function it appears in /builds/linux/arch/s390/pci/pci_irq.c:298:60: error: expected ';' before '{' token
msi_for_each_desc(msi, &pdev->dev, MSI_DESC_NOTASSOCIATED) { ^~
Thanks, will go drop the offending commits and push out a -rc2
greg k-h