5.10.37-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainerPATCH 272/530 ttyprintk: Add TTY hangup callback.
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
[ Upstream commit c0070e1e60270f6a1e09442a9ab2335f3eaeaad2 ]
syzbot is reporting hung task due to flood of
tty_warn(tty, "%s: tty->count = 1 port count = %d\n", __func__,
port->count);
message [1], for ioctl(TIOCVHANGUP) prevents tty_port_close() from decrementing port->count due to tty_hung_up_p() == true.
----------
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int i;
int fd[10];
for (i = 0; i < 10; i++)
fd[i] = open("/dev/ttyprintk", O_WRONLY);
ioctl(fd[0], TIOCVHANGUP);
for (i = 0; i < 10; i++)
close(fd[i]);
close(open("/dev/ttyprintk", O_WRONLY));
return 0;
}----------
When TTY hangup happens, port->count needs to be reset via "struct tty_operations"->hangup callback.
[1] https://syzkaller.appspot.com/bug?id=39ea6caa479af471183997376dc7e90bc7d64a6a
--- drivers/char/ttyprintk.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/char/ttyprintk.c +11 -0
@@ -158,12 +158,23 @@ static int tpk_ioctl(struct tty_struct *tty,return 0 ; } +/* +* TTY operations hangup function. +*/ +static void tpk_hangup (struct tty_struct *tty) +{ +struct ttyprintk_port *tpkp = tty->driver_data; + +tty_port_hangup (&tpkp->port); +} +static const struct tty_operations ttyprintk_ops = { .open = tpk_open, .close = tpk_close, .write = tpk_write, .write_room = tpk_write_room, .ioctl = tpk_ioctl, + .hangup = tpk_hangup, };static const struct tty_port_operations null_ops = { };
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 273/530 serial: omap: dont disable rs485 if rts gpio is missing
In reply to Greg Kroah-HartmanFrom: Dario Binacchi <[email protected]>
[ Upstream commit 45f6b6db53c80787b79044629b062dfcf2da71ec ]
There are rs485 transceivers (e.g. MAX13487E/MAX13488E) which automatically disable or enable the driver and receiver to keep the bus in the correct state.
In these cases we don't need a GPIO for flow control.
--- drivers/tty/serial/omap-serial.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
drivers/tty/serial/omap-serial.c +4 -8
@@ -302,7 +302,8 @@ static void serial_omap_stop_tx(struct uart_port *port)serial_out (up,UART_OMAP_SCR , up->scr); res = (port->rs485.flags &SER_RS485_RTS_AFTER_SEND ) ?1 :0 ; -if (gpiod_get_value (up->rts_gpiod) != res) { +if (up->rts_gpiod && +gpiod_get_value (up->rts_gpiod) != res) {if (port->rs485.delay_rts_after_send >0 )mdelay ( port->rs485.delay_rts_after_send);
@@ -411,7 +412,7 @@ static void serial_omap_start_tx(struct uart_port *port)/* if rts not already enabled */ res = (port->rs485.flags &SER_RS485_RTS_ON_SEND ) ?1 :0 ; -if (gpiod_get_value (up->rts_gpiod) != res) { +if (up->rts_gpiod &&gpiod_get_value (up->rts_gpiod) != res) {gpiod_set_value (up->rts_gpiod, res);if (port->rs485.delay_rts_before_send >0 )mdelay (port->rs485.delay_rts_before_send);
@@ -1407,18 +1408,13 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485)/* store new config */ port->rs485 = *rs485; -/* -* Just as a precaution, only allow rs485 -* to be enabled if the gpio pin is valid -*/ if (up->rts_gpiod) {/* enable / disable rts */ val = (port->rs485.flags &SER_RS485_ENABLED ) ?SER_RS485_RTS_AFTER_SEND :SER_RS485_RTS_ON_SEND ; val = (port->rs485.flags & val) ?1 :0 ;gpiod_set_value (up->rts_gpiod, val); - }else - port->rs485.flags &= ~SER_RS485_ENABLED ; + }/* Enable interrupts */ up->ier = mode;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 274/530 serial: omap: fix rs485 half-duplex filtering
In reply to Greg Kroah-HartmanFrom: Dario Binacchi <[email protected]>
[ Upstream commit e2a5e8448e7393e96ccde346c68764b40a52cc10 ]
Data received during half-duplex transmission must be filtered. If the target device responds quickly, emptying the FIFO at the end of the transmission can erase not only the echo characters but also part of the response message.
By keeping the receive interrupt enabled even during transmission, it allows you to filter each echo character and only in a number equal to those transmitted.
The issue was generated by a target device that started responding 240us later having received a request in communication at 115200bps. Sometimes, some messages received by the target were missing some of the first bytes.
--- drivers/tty/serial/omap-serial.c | 39 ++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 15 deletions(-)
drivers/tty/serial/omap-serial.c +24 -15
@@ -159,6 +159,8 @@ struct uart_omap_port {u32 calc_latency;struct work_struct qos_work;bool is_suspending; + +unsigned int rs485_tx_filter_count; };#define to_uart_omap_port (p) ((container_of((p), struct uart_omap_port, port)))
@@ -329,19 +331,6 @@ static void serial_omap_stop_tx(struct uart_port *port)serial_out (up,UART_IER , up->ier); } -if ((port->rs485.flags &SER_RS485_ENABLED ) && - !(port->rs485.flags &SER_RS485_RX_DURING_TX )) { -/* -* Empty the RX FIFO, we are not interested in anything -* received during the half-duplex transmission. -*/ -serial_out (up,UART_FCR , up->fcr |UART_FCR_CLEAR_RCVR ); -/* Re-enable RX interrupts */ - up->ier |=UART_IER_RLSI |UART_IER_RDI ; - up->port.read_status_mask |=UART_LSR_DR ; -serial_out (up,UART_IER , up->ier); - } -pm_runtime_mark_last_busy (up->dev);pm_runtime_put_autosuspend (up->dev); }
@@ -367,6 +356,10 @@ static void transmit_chars(struct uart_omap_port *up, unsigned int lsr)serial_out (up,UART_TX , up->port.x_char); up->port.icount.tx++; up->port.x_char =0 ; +if ((up->port.rs485.flags &SER_RS485_ENABLED ) && + !(up->port.rs485.flags &SER_RS485_RX_DURING_TX )) + up->rs485_tx_filter_count++; +return ; }if (uart_circ_empty (xmit) ||uart_tx_stopped (&up->port)) {
@@ -378,6 +371,10 @@ static void transmit_chars(struct uart_omap_port *up, unsigned int lsr)serial_out (up,UART_TX , xmit->buf[xmit->tail]); xmit->tail = (xmit->tail +1 ) & (UART_XMIT_SIZE -1 ); up->port.icount.tx++; +if ((up->port.rs485.flags &SER_RS485_ENABLED ) && + !(up->port.rs485.flags &SER_RS485_RX_DURING_TX )) + up->rs485_tx_filter_count++; +if (uart_circ_empty (xmit))break ; }while (--count >0 );
@@ -421,7 +418,7 @@ static void serial_omap_start_tx(struct uart_port *port)if ((port->rs485.flags &SER_RS485_ENABLED ) && !(port->rs485.flags &SER_RS485_RX_DURING_TX )) -serial_omap_stop_rx (port); + up->rs485_tx_filter_count =0 ;serial_omap_enable_ier_thri (up);pm_runtime_mark_last_busy (up->dev);
@@ -492,8 +489,13 @@ static void serial_omap_rlsi(struct uart_omap_port *up, unsigned int lsr)* Read one data character out to avoid stalling the receiver according * to the table 23-246 of the omap4 TRM. */ -if (likely (lsr &UART_LSR_DR )) +if (likely (lsr &UART_LSR_DR )) {serial_in (up,UART_RX ); +if ((up->port.rs485.flags &SER_RS485_ENABLED ) && + !(up->port.rs485.flags &SER_RS485_RX_DURING_TX ) && + up->rs485_tx_filter_count) + up->rs485_tx_filter_count--; + } up->port.icount.rx++; flag =TTY_NORMAL ;
@@ -544,6 +546,13 @@ static void serial_omap_rdi(struct uart_omap_port *up, unsigned int lsr)return ; ch =serial_in (up,UART_RX ); +if ((up->port.rs485.flags &SER_RS485_ENABLED ) && + !(up->port.rs485.flags &SER_RS485_RX_DURING_TX ) && + up->rs485_tx_filter_count) { + up->rs485_tx_filter_count--; +return ; + } + flag =TTY_NORMAL ; up->port.icount.rx++;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 275/530 xen-blkback: fix compatibility bug with single page rings
In reply to Greg Kroah-HartmanFrom: Paul Durrant <[email protected]>
[ Upstream commit d75e7f63b7c95c527cde42efb5d410d7f961498f ]
Prior to commit 4a8c31a1c6f5 ("xen/blkback: rework connect_ring() to avoid inconsistent xenstore 'ring-page-order' set by malicious blkfront"), the behaviour of xen-blkback when connecting to a frontend was:
- read 'ring-page-order'
- if not present then expect a single page ring specified by 'ring-ref'
- else expect a ring specified by 'ring-refX' where X is between 0 and 1 << ring-page-order
This was correct behaviour, but was broken by the afforementioned commit to become:
- read 'ring-page-order'
- if not present then expect a single page ring (i.e. ring-page-order = 0)
- expect a ring specified by 'ring-refX' where X is between 0 and 1 << ring-page-order
- if that didn't work then see if there's a single page ring specified by 'ring-ref'
This incorrect behaviour works most of the time but fails when a frontend that sets 'ring-page-order' is unloaded and replaced by one that does not because, instead of reading 'ring-ref', xen-blkback will read the stale 'ring-ref0' left around by the previous frontend will try to map the wrong grant reference.
This patch restores the original behaviour.
--- drivers/block/xen-blkback/common.h | 1 + drivers/block/xen-blkback/xenbus.c | 38 +++++++++++++----------------- 2 files changed, 17 insertions(+), 22 deletions(-)
drivers/block/xen-blkback/common.h +1 -0
@@ -313,6 +313,7 @@ struct xen_blkif {struct work_struct free_work;unsigned int nr_ring_pages; +bool multi_ref;/* All rings for this device. */ struct xen_blkif_ring *rings;unsigned int nr_rings;
drivers/block/xen-blkback/xenbus.c +16 -22
@@ -998,14 +998,17 @@ static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir)for (i =0 ; i < nr_grefs; i++) {char ring_ref_name[RINGREF_NAME_LEN ]; -snprintf (ring_ref_name,RINGREF_NAME_LEN ,"ring-ref%u" , i); +if (blkif->multi_ref) +snprintf (ring_ref_name,RINGREF_NAME_LEN ,"ring-ref%u" , i); +else { +WARN_ON (i !=0 ); +snprintf (ring_ref_name,RINGREF_NAME_LEN ,"ring-ref" ); + } + err =xenbus_scanf (XBT_NIL , dir, ring_ref_name,"%u" , &ring_ref[i]);if (err !=1 ) { -if (nr_grefs ==1 ) -break ; - err = -EINVAL ;xenbus_dev_fatal (dev, err,"reading %s/%s" , dir, ring_ref_name);
@@ -1013,18 +1016,6 @@ static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir) } } -if (err !=1 ) { -WARN_ON (nr_grefs !=1 ); - - err =xenbus_scanf (XBT_NIL , dir,"ring-ref" ,"%u" , - &ring_ref[0 ]); -if (err !=1 ) { - err = -EINVAL ; -xenbus_dev_fatal (dev, err,"reading %s/ring-ref" , dir); -return err; - } - } - err = -ENOMEM ;for (i =0 ; i < nr_grefs *XEN_BLKIF_REQS_PER_PAGE ; i++) { req =kzalloc (sizeof (*req),GFP_KERNEL );
@@ -1129,10 +1120,15 @@ static int connect_ring(struct backend_info *be) blkif->nr_rings, blkif->blk_protocol, protocol, blkif->vbd.feature_gnt_persistent ? "persistent grants" : ""); - ring_page_order =xenbus_read_unsigned (dev->otherend, -"ring-page-order" ,0 ); - -if (ring_page_order > xen_blkif_max_ring_order) { + err =xenbus_scanf (XBT_NIL , dev->otherend,"ring-page-order" ,"%u" , + &ring_page_order); +if (err !=1 ) { + blkif->nr_ring_pages =1 ; + blkif->multi_ref = false; + }else if (ring_page_order <= xen_blkif_max_ring_order) { + blkif->nr_ring_pages =1 << ring_page_order; + blkif->multi_ref = true; + }else { err = -EINVAL ; xenbus_dev_fatal(dev, err, "requested ring page order %d exceed max:%d",
@@ -1141,8 +1137,6 @@ static int connect_ring(struct backend_info *be)return err; } - blkif->nr_ring_pages =1 << ring_page_order; -if (blkif->nr_rings ==1 )return read_per_ring_refs (&blkif->rings[0 ], dev->otherend);else {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 276/530 soc: aspeed: fix a ternary sign expansion bug
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 5ffa828534036348fa90fb3079ccc0972d202c4a ]
The intent here was to return negative error codes but it actually returns positive values. The problem is that type promotion with ternary operations is quite complicated.
"ret" is an int. "copied" is a u32. And the snoop_file_read() function returns long. What happens is that "ret" is cast to u32 and becomes positive then it's cast to long and it's still positive.
Fix this by removing the ternary so that "ret" is type promoted directly to long.
--- drivers/soc/aspeed/aspeed-lpc-snoop.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/soc/aspeed/aspeed-lpc-snoop.c +3 -1
@@ -95,8 +95,10 @@ static ssize_t snoop_file_read(struct file *file, char __user *buffer,return -EINTR ; } ret =kfifo_to_user (&chan->fifo, buffer, count, &copied); +if (ret) +return ret; -return ret ? ret : copied; +return copied; } static __poll_t snoop_file_poll(struct file *file,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 277/530 drm/tilcdc: send vblank event when disabling crtc
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
[ Upstream commit f1a75f4dd8edf272b6b7cdccf6ba6254ec9d15fa ]
When run xrandr to change resolution on Beaglebone Black board, it will print the error information:
root@beaglebone:~# xrandr -display :0 --output HDMI-1 --mode 720x400 [drm:drm_crtc_commit_wait] *ERROR* flip_done timed out [drm:drm_atomic_helper_wait_for_dependencies] *ERROR* [CRTC:32:tilcdc crtc] commit wait timed out [drm:drm_crtc_commit_wait] *ERROR* flip_done timed out [drm:drm_atomic_helper_wait_for_dependencies] *ERROR* [CONNECTOR:34:HDMI-A-1] commit wait timed out [drm:drm_crtc_commit_wait] *ERROR* flip_done timed out [drm:drm_atomic_helper_wait_for_dependencies] *ERROR* [PLANE:31:plane-0] commit wait timed out tilcdc 4830e000.lcdc: already pending page flip!
This is because there is operation sequence as below:
drm_atomic_connector_commit_dpms(mode is DRM_MODE_DPMS_OFF):
...
drm_atomic_helper_setup_commit <- init_completion(commit_A->flip_done)
drm_atomic_helper_commit_tail
tilcdc_crtc_atomic_disable
tilcdc_plane_atomic_update <- drm_crtc_send_vblank_event in tilcdc_crtc_irq
is skipped since tilcdc_crtc->enabled is 0
tilcdc_crtc_atomic_flush <- drm_crtc_send_vblank_event is skipped since
crtc->state->event is set to be NULL in
tilcdc_plane_atomic_update
drm_mode_setcrtc:
...
drm_atomic_helper_setup_commit <- init_completion(commit_B->flip_done)
drm_atomic_helper_wait_for_dependencies
drm_crtc_commit_wait <- wait for commit_A->flip_done completingJust as shown above, the steps which could complete commit_A->flip_done are all skipped and commit_A->flip_done will never be completed. This will result a time-out ERROR when drm_crtc_commit_wait check the commit_A->flip_done. So add drm_crtc_send_vblank_event in tilcdc_crtc_atomic_disable to complete commit_A->flip_done.
--- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/gpu/drm/tilcdc/tilcdc_crtc.c +9 -0
@@ -518,6 +518,15 @@ static void tilcdc_crtc_off(struct drm_crtc *crtc, bool shutdown)drm_crtc_vblank_off (crtc); +spin_lock_irq (&crtc->dev->event_lock); + +if (crtc->state->event) { +drm_crtc_send_vblank_event (crtc, crtc->state->event); + crtc->state->event =NULL ; + } + +spin_unlock_irq (&crtc->dev->event_lock); +tilcdc_crtc_disable_irqs (dev);pm_runtime_put_sync (dev->dev);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 278/530 drm/stm: Fix bus_flags handling
In reply to Greg Kroah-HartmanFrom: Marek Vasut <[email protected]>
[ Upstream commit 99e360442f223dd40fc23ae07c7a263836fd27e6 ]
The drm_display_mode_to_videomode() does not populate DISPLAY_FLAGS_DE_LOW or DISPLAY_FLAGS_PIXDATA_NEGEDGE flags in struct videomode. Therefore, no matter what polarity the next bridge or display might require, these flags are never set, and thus the LTDC GCR_DEPOL and GCR_PCPOL bits are never set and the LTDC behaves as if both DISPLAY_FLAGS_PIXDATA_POSEDGE and DISPLAY_FLAGS_DE_HIGH were always set.
The fix for this problem is taken almost verbatim from MXSFB driver. In case there is a bridge attached to the LTDC, the bridge might have extra polarity requirements, so extract bus_flags from the bridge and use them for LTDC configuration. Otherwise, extract bus_flags from the connector, which is the display.
--- drivers/gpu/drm/stm/ltdc.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-)
drivers/gpu/drm/stm/ltdc.c +31 -2
@@ -525,13 +525,42 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc) {struct ltdc_device *ldev =crtc_to_ltdc (crtc);struct drm_device *ddev = crtc->dev; +struct drm_connector_list_iter iter; +struct drm_connector *connector =NULL ; +struct drm_encoder *encoder =NULL ; +struct drm_bridge *bridge =NULL ;struct drm_display_mode *mode = &crtc->state->adjusted_mode;struct videomode vm;u32 hsync, vsync, accum_hbp, accum_vbp, accum_act_w, accum_act_h;u32 total_width, total_height; +u32 bus_flags =0 ;u32 val;int ret; +/* get encoder from crtc */ +drm_for_each_encoder (encoder, ddev) +if (encoder->crtc == crtc) +break ; + +if (encoder) { +/* get bridge from encoder */ +list_for_each_entry (bridge, &encoder->bridge_chain, chain_node) +if (bridge->encoder == encoder) +break ; + +/* Get the connector from encoder */ +drm_connector_list_iter_begin (ddev, &iter); +drm_for_each_connector_iter (connector, &iter) +if (connector->encoder == encoder) +break ; +drm_connector_list_iter_end (&iter); + } + +if (bridge && bridge->timings) + bus_flags = bridge->timings->input_bus_flags; +else if (connector) + bus_flags = connector->display_info.bus_flags; +if (!pm_runtime_active (ddev->dev)) { ret =pm_runtime_get_sync (ddev->dev);if (ret) {
@@ -567,10 +596,10 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)if (vm.flags &DISPLAY_FLAGS_VSYNC_HIGH ) val |=GCR_VSPOL ; -if (vm.flags &DISPLAY_FLAGS_DE_LOW ) +if (bus_flags &DRM_BUS_FLAG_DE_LOW ) val |=GCR_DEPOL ; -if (vm.flags &DISPLAY_FLAGS_PIXDATA_NEGEDGE ) +if (bus_flags &DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE ) val |=GCR_PCPOL ; reg_update_bits(ldev->regs, LTDC_GCR,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 279/530 drm/amd/display: Fix off by one in hdmi_14_process_transaction()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 8e6fafd5a22e7a2eb216f5510db7aab54cc545c1 ]
The hdcp_i2c_offsets[] array did not have an entry for HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE so it led to an off by one read overflow. I added an entry and copied the 0x0 value for the offset from similar code in drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c.
I also declared several of these arrays as having HDCP_MESSAGE_ID_MAX entries. This doesn't change the code, but it's just a belt and suspenders approach to try future proof the code.
--- drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c +5 -4
@@ -39,7 +39,7 @@#define HDCP14_KSV_SIZE 5#define HDCP14_MAX_KSV_FIFO_SIZE 127*HDCP14_KSV_SIZE -static const bool hdcp_cmd_is_read[] = { +static const bool hdcp_cmd_is_read[HDCP_MESSAGE_ID_MAX ] = { [HDCP_MESSAGE_ID_READ_BKSV ] = true, [HDCP_MESSAGE_ID_READ_RI_R0 ] = true, [HDCP_MESSAGE_ID_READ_PJ ] = true,
@@ -75,7 +75,7 @@ static const bool hdcp_cmd_is_read[] = { [HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE ] = false }; -static const uint8_t hdcp_i2c_offsets[] = { +static const uint8_t hdcp_i2c_offsets[HDCP_MESSAGE_ID_MAX ] = { [HDCP_MESSAGE_ID_READ_BKSV ] =0x0 , [HDCP_MESSAGE_ID_READ_RI_R0 ] =0x8 , [HDCP_MESSAGE_ID_READ_PJ ] =0xA ,
@@ -106,7 +106,8 @@ static const uint8_t hdcp_i2c_offsets[] = { [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x60, [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x60, [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x80, - [HDCP_MESSAGE_ID_READ_RXSTATUS ] =0x70 + [HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x70, + [HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x0, };struct protection_properties {
@@ -184,7 +185,7 @@ static const struct protection_properties hdmi_14_protection = { .process_transaction = hdmi_14_process_transaction }; -static const uint32_t hdcp_dpcd_addrs[] = { +static const uint32_t hdcp_dpcd_addrs[HDCP_MESSAGE_ID_MAX ] = { [HDCP_MESSAGE_ID_READ_BKSV ] =0x68000 , [HDCP_MESSAGE_ID_READ_RI_R0 ] =0x68005 , [HDCP_MESSAGE_ID_READ_PJ ] =0xFFFFFFFF ,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 280/530 drm/mcde/panel: Inverse misunderstood flag
In reply to Greg Kroah-HartmanFrom: Linus Walleij <[email protected]>
[ Upstream commit d0c5ac04e7feedbc069f26f4dcbf35b521ae7fc5 ]
A recent patch renaming MIPI_DSI_MODE_EOT_PACKET to MIPI_DSI_MODE_NO_EOT_PACKET brought to light the misunderstanding in the current MCDE driver and all its associated panel drivers that MIPI_DSI_MODE_EOT_PACKET would mean "use EOT packet" when in fact it means the reverse.
Fix it up by implementing the flag right in the MCDE DSI driver and remove the flag from panels that actually want the EOT packet.
--- drivers/gpu/drm/mcde/mcde_dsi.c | 2 +- drivers/gpu/drm/panel/panel-novatek-nt35510.c | 3 +-- drivers/gpu/drm/panel/panel-samsung-s6d16d0.c | 4 +--- drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c | 1 - drivers/gpu/drm/panel/panel-sony-acx424akp.c | 3 +-- 5 files changed, 4 insertions(+), 9 deletions(-)
drivers/gpu/drm/mcde/mcde_dsi.c +1 -1
@@ -760,7 +760,7 @@ static void mcde_dsi_start(struct mcde_dsi *d)DSI_MCTL_MAIN_DATA_CTL_BTA_EN |DSI_MCTL_MAIN_DATA_CTL_READ_EN |DSI_MCTL_MAIN_DATA_CTL_REG_TE_EN ; -if (d->mdsi->mode_flags &MIPI_DSI_MODE_EOT_PACKET ) +if (!(d->mdsi->mode_flags &MIPI_DSI_MODE_EOT_PACKET )) val |=DSI_MCTL_MAIN_DATA_CTL_HOST_EOT_GEN ;writel (val, d->regs +DSI_MCTL_MAIN_DATA_CTL );
drivers/gpu/drm/panel/panel-novatek-nt35510.c +1 -2
@@ -898,8 +898,7 @@ static int nt35510_probe(struct mipi_dsi_device *dsi)*/ dsi->hs_rate =349440000 ; dsi->lp_rate =9600000 ; - dsi->mode_flags =MIPI_DSI_CLOCK_NON_CONTINUOUS | -MIPI_DSI_MODE_EOT_PACKET ; + dsi->mode_flags =MIPI_DSI_CLOCK_NON_CONTINUOUS ;/* * Every new incarnation of this display must have a unique
drivers/gpu/drm/panel/panel-samsung-s6d16d0.c +1 -3
@@ -184,9 +184,7 @@ static int s6d16d0_probe(struct mipi_dsi_device *dsi)* As we only send commands we do not need to be continuously * clocked. */ - dsi->mode_flags = -MIPI_DSI_CLOCK_NON_CONTINUOUS | -MIPI_DSI_MODE_EOT_PACKET ; + dsi->mode_flags =MIPI_DSI_CLOCK_NON_CONTINUOUS ; s6->supply =devm_regulator_get (dev,"vdd1" );if (IS_ERR (s6->supply))
drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c +0 -1
@@ -97,7 +97,6 @@ static int s6e63m0_dsi_probe(struct mipi_dsi_device *dsi) dsi->hs_rate =349440000 ; dsi->lp_rate =9600000 ; dsi->mode_flags =MIPI_DSI_MODE_VIDEO | -MIPI_DSI_MODE_EOT_PACKET |MIPI_DSI_MODE_VIDEO_BURST ; ret = s6e63m0_probe(dev, s6e63m0_dsi_dcs_read, s6e63m0_dsi_dcs_write,
drivers/gpu/drm/panel/panel-sony-acx424akp.c +1 -2
@@ -449,8 +449,7 @@ static int acx424akp_probe(struct mipi_dsi_device *dsi)MIPI_DSI_MODE_VIDEO_BURST ; else dsi->mode_flags = -MIPI_DSI_CLOCK_NON_CONTINUOUS | -MIPI_DSI_MODE_EOT_PACKET ; +MIPI_DSI_CLOCK_NON_CONTINUOUS ; acx->supply =devm_regulator_get (dev,"vddi" );if (IS_ERR (acx->supply))
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 281/530 sched/fair: Fix shift-out-of-bounds in load_balance()
In reply to Greg Kroah-HartmanFrom: Valentin Schneider <[email protected]>
[ Upstream commit 39a2a6eb5c9b66ea7c8055026303b3aa681b49a5 ]
Syzbot reported a handful of occurrences where an sd->nr_balance_failed can grow to much higher values than one would expect.
A successful load_balance() resets it to 0; a failed one increments it. Once it gets to sd->cache_nice_tries + 3, this *should* trigger an active balance, which will either set it to sd->cache_nice_tries+1 or reset it to 0. However, in case the to-be-active-balanced task is not allowed to run on env->dst_cpu, then the increment is done without any further modification.
This could then be repeated ad nauseam, and would explain the absurdly high values reported by syzbot (86, 149). VincentG noted there is value in letting sd->cache_nice_tries grow, so the shift itself should be fixed. That means preventing:
"""
If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined. """
Thus we need to cap the shift exponent to
BITS_PER_TYPE(typeof(lefthand)) - 1.
I had a look around for other similar cases via coccinelle:
@expr@
position pos;
expression E1;
expression E2;
@@
(
E1 >> E2@pos
|
E1 >> E2@pos
)
@cst depends on expr@
position pos;
expression expr.E1;
constant cst;
@@
(
E1 >> cst@pos
|
E1 << cst@pos
)
@script:python depends on !cst@
pos << expr.pos;
exp << expr.E2;
@@
# Dirty hack to ignore constexpr
if exp.upper() != exp:
coccilib.report.print_report(pos[0], "Possible UB shift here")
The only other match in kernel/sched is rq_clock_thermal() which employs sched_thermal_decay_shift, and that exponent is already capped to 10, so that one is fine.
--- kernel/sched/fair.c | 3 +-- kernel/sched/sched.h | 7 +++++++ 2 files changed, 8 insertions(+), 2 deletions(-)
kernel/sched/fair.c +1 -2
@@ -7735,8 +7735,7 @@ static int detach_tasks(struct lb_env *env)* scheduler fails to find a good waiting task to * migrate. */ - -if ((load >> env->sd->nr_balance_failed) > env->imbalance) +if (shr_bound (load, env->sd->nr_balance_failed) > env->imbalance) goto next; env->imbalance -= load;
kernel/sched/sched.h +7 -0
@@ -205,6 +205,13 @@ static inline void update_avg(u64 *avg, u64 sample) *avg += diff /8 ; } +/* +* Shifting a value by an exponent greater *or equal* to the size of said value +* is UB; cap at size-1. +*/ +#define shr_bound (val, shift) \ + (val >> min_t(typeof(shift), shift, BITS_PER_TYPE(typeof(val)) - 1)) +/* * !! For sched_setattr_nocheck() (kernel) only !! *
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 282/530 afs: Fix updating of i_mode due to 3rd party change
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit 6e1eb04a87f954eb06a89ee6034c166351dfff6e ]
Fix afs_apply_status() to mask off the irrelevant bits from status->mode when OR'ing them into i_mode. This can happen when a 3rd party chmod occurs.
Also fix afs_inode_init_from_status() to mask off the mode bits when initialising i_mode.
--- fs/afs/inode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/afs/inode.c +3 -3
@@ -102,13 +102,13 @@ static int afs_inode_init_from_status(struct afs_operation *op,switch (status->type) {case AFS_FTYPE_FILE : - inode->i_mode =S_IFREG | status->mode; + inode->i_mode =S_IFREG | (status->mode &S_IALLUGO ); inode->i_op = &afs_file_inode_operations; inode->i_fop = &afs_file_operations; inode->i_mapping->a_ops = &afs_fs_aops;break ;case AFS_FTYPE_DIR : - inode->i_mode =S_IFDIR | status->mode; + inode->i_mode =S_IFDIR | (status->mode &S_IALLUGO ); inode->i_op = &afs_dir_inode_operations; inode->i_fop = &afs_dir_file_operations; inode->i_mapping->a_ops = &afs_dir_aops;
@@ -198,7 +198,7 @@ static void afs_apply_status(struct afs_operation *op,if (status->mode != vnode->status.mode) { mode = inode->i_mode; mode &= ~S_IALLUGO ; - mode |= status->mode; + mode |= status->mode &S_IALLUGO ;WRITE_ONCE (inode->i_mode, mode); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 283/530 rcu: Remove spurious instrumentation_end() in rcu_nmi_enter()
In reply to Greg Kroah-HartmanFrom: Zhouyi Zhou <[email protected]>
[ Upstream commit 6494ccb93271bee596a12db32ff44867d5be2321 ]
In rcu_nmi_enter(), there is an erroneous instrumentation_end() in the second branch of the "if" statement. Oddly enough, "objtool check -f vmlinux.o" fails to complain because it is unable to correctly cover all cases. Instead, objtool visits the third branch first, which marks following trace_rcu_dyntick() as visited. This commit therefore removes the spurious instrumentation_end().
Reported-by Neeraj Upadhyay <[email protected]>
--- kernel/rcu/tree.c | 1 - 1 file changed, 1 deletion(-)
kernel/rcu/tree.c +0 -1
@@ -1019,7 +1019,6 @@ noinstr void rcu_nmi_enter(void) }else if (!in_nmi ()) {instrumentation_begin ();rcu_irq_enter_check_tick (); -instrumentation_end (); }else {instrumentation_begin (); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 284/530 media: vivid: fix assignment of dev->fbuf_out_flags
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 5cde22fcc7271812a7944c47b40100df15908358 ]
Currently the chroma_flags and alpha_flags are being zero'd with a bit-wise mask and the following statement should be bit-wise or'ing in the new flag bits but instead is making a direct assignment. Fix this by using the |= operator rather than an assignment.
Addresses-Coverity: ("Unused value")
--- drivers/media/test-drivers/vivid/vivid-vid-out.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/test-drivers/vivid/vivid-vid-out.c +1 -1
@@ -1025,7 +1025,7 @@ int vivid_vid_out_s_fbuf(struct file *file, void *fh,return -EINVAL ; } dev->fbuf_out_flags &= ~(chroma_flags | alpha_flags); - dev->fbuf_out_flags = a->flags & (chroma_flags | alpha_flags); + dev->fbuf_out_flags |= a->flags & (chroma_flags | alpha_flags);return 0 ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 285/530 media: saa7134: use sg_dma_len when building pgtable
In reply to Greg Kroah-HartmanFrom: Tasos Sahanidis <[email protected]>
[ Upstream commit 4e1cb753c04d74e06d7ca826ea0bcb02526af03e ]
The new AMD IOMMU DMA implementation concatenates sglist entries under certain conditions, and because saa7134 accessed the length member directly, it did not support this scenario.
This fixes IO_PAGE_FAULTs and choppy DMA audio by using the sg_dma_len macro.
--- drivers/media/pci/saa7134/saa7134-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/pci/saa7134/saa7134-core.c +1 -1
@@ -243,7 +243,7 @@ int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt, ptr = pt->cpu + startpage;for (i =0 ; i < length; i++, list =sg_next (list)) { -for (p =0 ; p *4096 < list->length; p++, ptr++) +for (p =0 ; p *4096 <sg_dma_len (list); p++, ptr++) *ptr =cpu_to_le32 (sg_dma_address (list) + list->offset + p *4096 ); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 286/530 media: saa7146: use sg_dma_len when building pgtable
In reply to Greg Kroah-HartmanFrom: Tasos Sahanidis <[email protected]>
[ Upstream commit e56429b09d5e0802b86f84ec7c24025886c9f88b ]
The new AMD IOMMU DMA implementation concatenates sglist entries under certain conditions, and because saa7146 accessed the length member directly, it did not support this scenario.
This fixes IO_PAGE_FAULTs by using the sg_dma_len macro.
--- drivers/media/common/saa7146/saa7146_core.c | 2 +- drivers/media/common/saa7146/saa7146_video.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-)
drivers/media/common/saa7146/saa7146_core.c +1 -1
@@ -253,7 +253,7 @@ int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pti, sg_dma_address(list), sg_dma_len(list), list->offset); */ -for (p =0 ; p *4096 < list->length; p++, ptr++) { +for (p =0 ; p *4096 <sg_dma_len (list); p++, ptr++) { *ptr =cpu_to_le32 (sg_dma_address (list) + p *4096 ); nr_pages++; }
drivers/media/common/saa7146/saa7146_video.c +1 -2
@@ -247,9 +247,8 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu/* walk all pages, copy all page addresses to ptr1 */ for (i =0 ; i < length; i++, list++) { -for (p =0 ; p *4096 < list->length; p++, ptr1++) { +for (p =0 ; p *4096 <sg_dma_len (list); p++, ptr1++) *ptr1 =cpu_to_le32 (sg_dma_address (list) - list->offset); - } }/* ptr1 = pt1->cpu;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 287/530 media: omap4iss: return error code when omap4iss_get() failed
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 8938c48fa25b491842ece9eb38f0bea0fcbaca44 ]
If omap4iss_get() failed, it need return error code in iss_probe().
--- drivers/staging/media/omap4iss/iss.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/staging/media/omap4iss/iss.c +3 -1
@@ -1236,8 +1236,10 @@ static int iss_probe(struct platform_device *pdev)if (ret <0 ) goto error; -if (!omap4iss_get (iss)) +if (!omap4iss_get (iss)) { + ret = -EINVAL ; goto error; + } ret =iss_reset (iss);if (ret <0 )
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 288/530 media: rkisp1: rsz: crash fix when setting src format
In reply to Greg Kroah-HartmanFrom: Dafna Hirschfeld <[email protected]>
[ Upstream commit cbe8373ca7e7cbb4b263b6bf222ccc19f5e119d2 ]
When setting the source media bus code in the resizer, we first check that the current media bus code in the source is yuv encoded format. This is done by retrieving the data from the formats list of the isp entity. This cause a crash when the media bus code on the source is YUYV8_1_5X8 which is not supported by the isp entity. Instead we should test the sink format of the resizer which is guaranteed to be supported by the isp entity.
--- drivers/staging/media/rkisp1/rkisp1-resizer.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/staging/media/rkisp1/rkisp1-resizer.c +5 -4
@@ -520,14 +520,15 @@ static void rkisp1_rsz_set_src_fmt(struct rkisp1_resizer *rsz, struct v4l2_mbus_framefmt *format, unsigned int which) { -const struct rkisp1_isp_mbus_info *mbus_info; -struct v4l2_mbus_framefmt *src_fmt; +const struct rkisp1_isp_mbus_info *sink_mbus_info; +struct v4l2_mbus_framefmt *src_fmt, *sink_fmt; + sink_fmt =rkisp1_rsz_get_pad_fmt (rsz, cfg,RKISP1_RSZ_PAD_SINK , which); src_fmt =rkisp1_rsz_get_pad_fmt (rsz, cfg,RKISP1_RSZ_PAD_SRC , which); - mbus_info =rkisp1_isp_mbus_info_get (src_fmt->code); + sink_mbus_info =rkisp1_isp_mbus_info_get (sink_fmt->code);/* for YUV formats, userspace can change the mbus code on the src pad if it is supported */ -if (mbus_info->pixel_enc ==V4L2_PIXEL_ENC_YUV && +if (sink_mbus_info->pixel_enc ==V4L2_PIXEL_ENC_YUV &&rkisp1_rsz_get_yuv_mbus_info (format->code)) src_fmt->code = format->code;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 289/530 media: aspeed: fix clock handling logic
In reply to Greg Kroah-HartmanFrom: Jae Hyun Yoo <[email protected]>
[ Upstream commit 3536169f8531c2c5b153921dc7d1ac9fd570cda7 ]
Video engine uses eclk and vclk for its clock sources and its reset control is coupled with eclk so the current clock enabling sequence works like below.
Enable eclk
De-assert Video Engine reset
10ms delay
Enable vclk
It introduces improper reset on the Video Engine hardware and eventually the hardware generates unexpected DMA memory transfers that can corrupt memory region in random and sporadic patterns. This issue is observed very rarely on some specific AST2500 SoCs but it causes a critical kernel panic with making a various shape of signature so it's extremely hard to debug. Moreover, the issue is observed even when the video engine is not actively used because udevd turns on the video engine hardware for a short time to make a query in every boot.
To fix this issue, this commit changes the clock handling logic to make the reset de-assertion triggered after enabling both eclk and vclk. Also, it adds clk_unprepare call for a case when probe fails.
clk: ast2600: fix reset settings for eclk and vclk
Video engine reset setting should be coupled with eclk to match it with the setting for previous Aspeed SoCs which is defined in clk-aspeed.c since all Aspeed SoCs are sharing a single video engine driver. Also, reset bit 6 is defined as 'Video Engine' reset in datasheet so it should be de-asserted when eclk is enabled. This commit fixes the setting.
--- drivers/clk/clk-ast2600.c | 4 ++-- drivers/media/platform/aspeed-video.c | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-)
drivers/clk/clk-ast2600.c +2 -2
@@ -61,10 +61,10 @@ static void __iomem *scu_g6_base;static const struct aspeed_gate_data aspeed_g6_gates[] = {/* clk rst name parent flags */ [ASPEED_CLK_GATE_MCLK ] = {0 ,-1 ,"mclk-gate" ,"mpll" ,CLK_IS_CRITICAL },/* SDRAM */ - [ASPEED_CLK_GATE_ECLK ] = {1 ,-1 ,"eclk-gate" ,"eclk" ,0 },/* Video Engine */ + [ASPEED_CLK_GATE_ECLK ] = {1 ,6 ,"eclk-gate" ,"eclk" ,0 },/* Video Engine */ [ASPEED_CLK_GATE_GCLK ] = {2 ,7 ,"gclk-gate" ,NULL ,0 },/* 2D engine */ /* vclk parent - dclk/d1clk/hclk/mclk */ - [ASPEED_CLK_GATE_VCLK ] = {3 ,6 ,"vclk-gate" ,NULL ,0 },/* Video Capture */ + [ASPEED_CLK_GATE_VCLK ] = {3 ,-1 ,"vclk-gate" ,NULL ,0 },/* Video Capture */ [ASPEED_CLK_GATE_BCLK ] = {4 ,8 ,"bclk-gate" ,"bclk" ,0 },/* PCIe/PCI */ /* From dpll */ [ASPEED_CLK_GATE_DCLK ] = {5 ,-1 ,"dclk-gate" ,NULL ,CLK_IS_CRITICAL },/* DAC */
drivers/media/platform/aspeed-video.c +6 -3
@@ -514,8 +514,8 @@ static void aspeed_video_off(struct aspeed_video *video)aspeed_video_write (video,VE_INTERRUPT_STATUS ,0xffffffff );/* Turn off the relevant clocks */ -clk_disable (video->vclk);clk_disable (video->eclk); +clk_disable (video->vclk);clear_bit (VIDEO_CLOCKS_ON , &video->flags); }
@@ -526,8 +526,8 @@ static void aspeed_video_on(struct aspeed_video *video)return ;/* Turn on the relevant clocks */ -clk_enable (video->eclk);clk_enable (video->vclk); +clk_enable (video->eclk);set_bit (VIDEO_CLOCKS_ON , &video->flags); }
@@ -1719,8 +1719,11 @@ static int aspeed_video_probe(struct platform_device *pdev)return rc; rc =aspeed_video_setup_video (video); -if (rc) +if (rc) { +clk_unprepare (video->vclk); +clk_unprepare (video->eclk);return rc; + }return 0 ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 290/530 drm/probe-helper: Check epoch counter in output_poll_execute()
In reply to Greg Kroah-HartmanFrom: Noralf Trønnes <[email protected]>
[ Upstream commit dc659a4e852b591771fc2e5abb60f4455b0cf316 ]
drm_helper_hpd_irq_event() checks the epoch counter to determine connector status change. This was introduced in
commit 5186421cbfe2 ("drm: Introduce epoch counter to drm_connector"). Do the same for output_poll_execute() so it can detect other changes beside connection status value changes.
v2:
- Add Fixes tag (Daniel)
--- drivers/gpu/drm/drm_probe_helper.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/drm_probe_helper.c +6 -1
@@ -623,6 +623,7 @@ static void output_poll_execute(struct work_struct *work)struct drm_connector_list_iter conn_iter;enum drm_connector_status old_status;bool repoll = false, changed; +u64 old_epoch_counter;if (!dev->mode_config.poll_enabled)return ;
@@ -659,8 +660,9 @@ static void output_poll_execute(struct work_struct *work) repoll = true; + old_epoch_counter = connector->epoch_counter; connector->status =drm_helper_probe_detect (connector,NULL , false); -if (old_status != connector->status) { +if (old_epoch_counter != connector->epoch_counter) {const char *old, *new;/*
@@ -689,6 +691,9 @@ static void output_poll_execute(struct work_struct *work) connector->base.id, connector->name, old, new); +DRM_DEBUG_KMS ("[CONNECTOR:%d:%s] epoch counter %llu -> %llu\n" , + connector->base.id, connector->name, + old_epoch_counter, connector->epoch_counter); changed = true; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 291/530 media: venus: core: Fix some resource leaks in the error path of venus_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 5a465c5391a856a0c1e9554964d660676c35d1b2 ]
If an error occurs after a successful 'of_icc_get()' call, it must be undone.
Use 'devm_of_icc_get()' instead of 'of_icc_get()' to avoid the leak. Update the remove function accordingly and axe the now unneeded 'icc_put()' calls.
--- drivers/media/platform/qcom/venus/core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/media/platform/qcom/venus/core.c +2 -5
@@ -195,11 +195,11 @@ static int venus_probe(struct platform_device *pdev)if (IS_ERR (core->base))return PTR_ERR (core->base); - core->video_path =of_icc_get (dev,"video-mem" ); + core->video_path =devm_of_icc_get (dev,"video-mem" );if (IS_ERR (core->video_path))return PTR_ERR (core->video_path); - core->cpucfg_path =of_icc_get (dev,"cpu-cfg" ); + core->cpucfg_path =devm_of_icc_get (dev,"cpu-cfg" );if (IS_ERR (core->cpucfg_path))return PTR_ERR (core->cpucfg_path);
@@ -334,9 +334,6 @@ static int venus_remove(struct platform_device *pdev)hfi_destroy (core); -icc_put (core->video_path); -icc_put (core->cpucfg_path); -v4l2_device_unregister (&core->v4l2_dev);mutex_destroy (&core->pm_lock);mutex_destroy (&core->lock);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 292/530 media: platform: sunxi: sun6i-csi: fix error return code of sun6i_video_start_streaming()
In reply to Greg Kroah-HartmanFrom: Jia-Ju Bai <[email protected]>
[ Upstream commit f3d384e36630e2a552d874e422835606d9cf230a ]
When sun6i_video_remote_subdev() returns NULL to subdev, no error return code of sun6i_video_start_streaming() is assigned.
To fix this bug, ret is assigned with -EINVAL in this case.
--- drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c +3 -1
@@ -151,8 +151,10 @@ static int sun6i_video_start_streaming(struct vb2_queue *vq, unsigned int count) } subdev =sun6i_video_remote_subdev (video,NULL ); -if (!subdev) +if (!subdev) { + ret = -EINVAL ; goto stop_media_pipeline; + } config.pixelformat = video->fmt.fmt.pix.pixelformat; config.code = video->mbus_code;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 293/530 media: m88ds3103: fix return value check in m88ds3103_probe()
In reply to Greg Kroah-HartmanFrom: Wei Yongjun <[email protected]>
[ Upstream commit e61f9ea271933d987ab895c689fa37744f6fc27f ]
In case of error, the function i2c_new_dummy_device() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR().
--- drivers/media/dvb-frontends/m88ds3103.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/media/dvb-frontends/m88ds3103.c +2 -2
@@ -1904,8 +1904,8 @@ static int m88ds3103_probe(struct i2c_client *client, dev->dt_client =i2c_new_dummy_device (client->adapter, dev->dt_addr); -if (!dev->dt_client) { - ret = -ENODEV ; +if (IS_ERR (dev->dt_client)) { + ret =PTR_ERR (dev->dt_client); goto err_kfree; } }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 294/530 media: docs: Fix data organization of MEDIA_BUS_FMT_RGB101010_1X30
In reply to Greg Kroah-HartmanFrom: Liu Ying <[email protected]>
[ Upstream commit c451ee146d449bbe39835fc3d9007b7f06332415 ]
The media bus bit width of MEDIA_BUS_FMT_RGB101010_1X30 is 30. So, 'Bit31' and 'Bit30' cells for the 'MEDIA_BUS_FMT_RGB101010_1X30' row should be spaces instead of '0's.
--- Documentation/userspace-api/media/v4l/subdev-formats.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Documentation/userspace-api/media/v4l/subdev-formats.rst +2 -2
@@ -1567,8 +1567,8 @@ The following tables list existing packed RGB formats. - MEDIA_BUS_FMT_RGB101010_1X30 - 0x1018 - - - 0 - - 0 + - + - - r\ :sub:`9` - r\ :sub:`8` - r\ :sub:`7`
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 295/530 media: [next] staging: media: atomisp: fix memory leak of object flash
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 6045b01dd0e3cd3759eafe7f290ed04c957500b1 ]
In the case where the call to lm3554_platform_data_func returns an error there is a memory leak on the error return path of object flash. Fix this by adding an error return path that will free flash and rename labels fail2 to fail3 and fail1 to fail2.
--- .../media/atomisp/i2c/atomisp-lm3554.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
drivers/staging/media/atomisp/i2c/atomisp-lm3554.c +11 -8
@@ -843,8 +843,10 @@ static int lm3554_probe(struct i2c_client *client)return -ENOMEM ; flash->pdata =lm3554_platform_data_func (client); -if (IS_ERR (flash->pdata)) -return PTR_ERR (flash->pdata); +if (IS_ERR (flash->pdata)) { + err =PTR_ERR (flash->pdata); + goto fail1; + }v4l2_i2c_subdev_init (&flash->sd, client, &lm3554_ops); flash->sd.internal_ops = &lm3554_internal_ops;
@@ -856,7 +858,7 @@ static int lm3554_probe(struct i2c_client *client) ARRAY_SIZE(lm3554_controls));if (ret) {dev_err (&client->dev,"error initialize a ctrl_handler.\n" ); - goto fail2; + goto fail3; }for (i =0 ; i <ARRAY_SIZE (lm3554_controls); i++)
@@ -865,14 +867,14 @@ static int lm3554_probe(struct i2c_client *client)if (flash->ctrl_handler.error) {dev_err (&client->dev,"ctrl_handler error.\n" ); - goto fail2; + goto fail3; } flash->sd.ctrl_handler = &flash->ctrl_handler; err =media_entity_pads_init (&flash->sd.entity,0 ,NULL );if (err) {dev_err (&client->dev,"error initialize a media entity.\n" ); - goto fail1; + goto fail2; } flash->sd.entity.function =MEDIA_ENT_F_FLASH ;
@@ -884,14 +886,15 @@ static int lm3554_probe(struct i2c_client *client) err =lm3554_gpio_init (client);if (err) {dev_err (&client->dev,"gpio request/direction_output fail" ); - goto fail2; + goto fail3; }return atomisp_register_i2c_module (&flash->sd,NULL ,LED_FLASH ); -fail2: +fail3:media_entity_cleanup (&flash->sd.entity);v4l2_ctrl_handler_free (&flash->ctrl_handler); -fail1: +fail2:v4l2_device_unregister_subdev (&flash->sd); +fail1:kfree (flash);return err;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 296/530 media: atomisp: Fixed error handling path
In reply to Greg Kroah-HartmanFrom: Souptick Joarder <[email protected]>
[ Upstream commit 16a5dcf7fbc2f5cd10c1e6264262bfa3832fb7d5 ]
Inside alloc_user_pages() based on flag value either pin_user_pages() or get_user_pages_fast() will be called. However, these API might fail.
But free_user_pages() called in error handling path doesn't bother about return value and will try to unpin bo->pgnr pages, which is incorrect.
Fix this by passing the page_nr to free_user_pages(). If page_nr > 0 pages will be unpinned based on bo->mem_type. This will also take care of non error handling path.
allocation")
--- drivers/staging/media/atomisp/pci/hmm/hmm_bo.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/staging/media/atomisp/pci/hmm/hmm_bo.c +8 -5
@@ -857,16 +857,17 @@ static void free_private_pages(struct hmm_buffer_object *bo,kfree (bo->page_obj); } -static void free_user_pages (struct hmm_buffer_object *bo) +static void free_user_pages (struct hmm_buffer_object *bo, +unsigned int page_nr) {int i; hmm_mem_stat.usr_size -= bo->pgnr;if (bo->mem_type ==HMM_BO_MEM_TYPE_PFN ) { -unpin_user_pages (bo->pages, bo->pgnr); +unpin_user_pages (bo->pages, page_nr); }else { -for (i =0 ; i < bo->pgnr; i++) +for (i =0 ; i < page_nr; i++)put_page (bo->pages[i]); }kfree (bo->pages);
@@ -942,6 +943,8 @@ static int alloc_user_pages(struct hmm_buffer_object *bo,dev_err (atomisp_dev,"get_user_pages err: bo->pgnr = %d, pgnr actually pinned = %d.\n" , bo->pgnr, page_nr); +if (page_nr <0 ) + page_nr =0 ; goto out_of_mem; }
@@ -954,7 +957,7 @@ static int alloc_user_pages(struct hmm_buffer_object *bo, out_of_mem: -free_user_pages (bo); +free_user_pages (bo, page_nr);return -ENOMEM ; }
@@ -1037,7 +1040,7 @@ void hmm_bo_free_pages(struct hmm_buffer_object *bo)if (bo->type ==HMM_BO_PRIVATE )free_private_pages (bo, &dynamic_pool, &reserved_pool);else if (bo->type ==HMM_BO_USER ) -free_user_pages (bo); +free_user_pages (bo, bo->pgnr);else dev_err (atomisp_dev,"invalid buffer type.\n" );mutex_unlock (&bo->mutex);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 297/530 media: m88rs6000t: avoid potential out-of-bounds reads on arrays
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 9baa3d64e8e2373ddd11c346439e5dfccb2cbb0d ]
There a 3 array for-loops that don't check the upper bounds of the index into arrays and this may lead to potential out-of-bounds reads. Fix this by adding array size upper bounds checks to be full safe.
Addresses-Coverity: ("Out-of-bounds read")
--- drivers/media/tuners/m88rs6000t.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/media/tuners/m88rs6000t.c +3 -3
@@ -525,7 +525,7 @@ static int m88rs6000t_get_rf_strength(struct dvb_frontend *fe, u16 *strength) PGA2_cri =PGA2_GC >>2 ; PGA2_crf =PGA2_GC &0x03 ; -for (i =0 ; i <=RF_GC ; i++) +for (i =0 ; i <=RF_GC && i <ARRAY_SIZE (RFGS ); i++)RFG +=RFGS [i];if (RF_GC ==0 )
@@ -537,12 +537,12 @@ static int m88rs6000t_get_rf_strength(struct dvb_frontend *fe, u16 *strength)if (RF_GC ==3 )RFG +=100 ; -for (i =0 ; i <=IF_GC ; i++) +for (i =0 ; i <=IF_GC && i <ARRAY_SIZE (IFGS ); i++)IFG +=IFGS [i];TIAG =TIA_GC *TIA_GS ; -for (i =0 ; i <=BB_GC ; i++) +for (i =0 ; i <=BB_GC && i <ARRAY_SIZE (BBGS ); i++)BBG +=BBGS [i];PGA2G = PGA2_cri * PGA2_cri_GS + PGA2_crf * PGA2_crf_GS;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 298/530 media: atomisp: Fix use after free in atomisp_alloc_css_stat_bufs()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit ba11bbf303fafb33989e95473e409f6ab412b18d ]
The "s3a_buf" is freed along with all the other items on the "asd->s3a_stats" list. It leads to a double free and a use after free.
--- drivers/staging/media/atomisp/pci/atomisp_ioctl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/staging/media/atomisp/pci/atomisp_ioctl.c +1 -3
@@ -948,10 +948,8 @@ int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd,dev_dbg (isp->dev,"allocating %d dis buffers\n" , count);while (count--) { dis_buf =kzalloc (sizeof (struct atomisp_dis_buf ),GFP_KERNEL ); -if (!dis_buf) { -kfree (s3a_buf); +if (!dis_buf) goto error; - }if (atomisp_css_allocate_stat_buffers ( asd, stream_id,NULL , dis_buf,NULL )) {kfree (dis_buf);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 299/530 drm/amdkfd: fix build error with AMD_IOMMU_V2=m
In reply to Greg Kroah-HartmanFrom: Felix Kuehling <[email protected]>
[ Upstream commit 1e87068570a2cc4db5f95a881686add71729e769 ]
Using 'imply AMD_IOMMU_V2' does not guarantee that the driver can link against the exported functions. If the GPU driver is built-in but the IOMMU driver is a loadable module, the kfd_iommu.c file is indeed built but does not work:
x86_64-linux-ld: drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: in function `kfd_iommu_bind_process_to_device':
kfd_iommu.c:(.text+0x516): undefined reference to `amd_iommu_bind_pasid'
x86_64-linux-ld: drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: in function `kfd_iommu_unbind_process':
kfd_iommu.c:(.text+0x691): undefined reference to `amd_iommu_unbind_pasid'
x86_64-linux-ld: drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: in function `kfd_iommu_suspend':
kfd_iommu.c:(.text+0x966): undefined reference to `amd_iommu_set_invalidate_ctx_cb'
x86_64-linux-ld: kfd_iommu.c:(.text+0x97f): undefined reference to `amd_iommu_set_invalid_ppr_cb'
x86_64-linux-ld: kfd_iommu.c:(.text+0x9a4): undefined reference to `amd_iommu_free_device'
x86_64-linux-ld: drivers/gpu/drm/amd/amdkfd/kfd_iommu.o: in function `kfd_iommu_resume':
kfd_iommu.c:(.text+0xa9a): undefined reference to `amd_iommu_init_device'
x86_64-linux-ld: kfd_iommu.c:(.text+0xadc): undefined reference to `amd_iommu_set_invalidate_ctx_cb'
x86_64-linux-ld: kfd_iommu.c:(.text+0xaff): undefined reference to `amd_iommu_set_invalid_ppr_cb'
x86_64-linux-ld: kfd_iommu.c:(.text+0xc72): undefined reference to `amd_iommu_bind_pasid'
x86_64-linux-ld: kfd_iommu.c:(.text+0xe08): undefined reference to `amd_iommu_set_invalidate_ctx_cb'
x86_64-linux-ld: kfd_iommu.c:(.text+0xe26): undefined reference to `amd_iommu_set_invalid_ppr_cb'
x86_64-linux-ld: kfd_iommu.c:(.text+0xe42): undefined reference to `amd_iommu_free_device'
Use IS_REACHABLE to only build IOMMU-V2 support if the amd_iommu symbols are reachable by the amdkfd driver. Output a warning if they are not, because that may not be what the user was expecting.
--- drivers/gpu/drm/amd/amdkfd/kfd_iommu.c | 6 ++++++ drivers/gpu/drm/amd/amdkfd/kfd_iommu.h | 9 +++++++-- 2 files changed, 13 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdkfd/kfd_iommu.c +6 -0
@@ -20,6 +20,10 @@* OTHER DEALINGS IN THE SOFTWARE. */ +#include <linux/kconfig.h> + +#if IS_REACHABLE (CONFIG_AMD_IOMMU_V2 ) +#include <linux/printk.h> #include <linux/device.h> #include <linux/slab.h>
@@ -355,3 +359,5 @@ int kfd_iommu_add_perf_counters(struct kfd_topology_device *kdev) return 0; } + +#endif
drivers/gpu/drm/amd/amdkfd/kfd_iommu.h +7 -2
@@ -23,7 +23,9 @@#ifndef __KFD_IOMMU_H__#define __KFD_IOMMU_H__ -#if defined(CONFIG_AMD_IOMMU_V2_MODULE ) || defined(CONFIG_AMD_IOMMU_V2 ) +#include <linux/kconfig.h> + +#if IS_REACHABLE (CONFIG_AMD_IOMMU_V2 )#define KFD_SUPPORT_IOMMU_V2
@@ -46,6 +48,9 @@ static inline int kfd_iommu_check_device(struct kfd_dev *kfd) }static inline int kfd_iommu_device_init (struct kfd_dev *kfd) { +#if IS_MODULE (CONFIG_AMD_IOMMU_V2 ) +WARN_ONCE (1 ,"iommu_v2 module is not usable by built-in KFD" ); +#endif return 0 ; }
@@ -73,6 +78,6 @@ static inline int kfd_iommu_add_perf_counters(struct kfd_topology_device *kdev)return 0 ; } -#endif /* defined(CONFIG_AMD_IOMMU_V2) */ +#endif /* IS_REACHABLE(CONFIG_AMD_IOMMU_V2) */ #endif /* __KFD_IOMMU_H__ */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 300/530 of: overlay: fix for_each_child.cocci warnings
In reply to Greg Kroah-HartmanFrom: kernel test robot <[email protected]>
[ Upstream commit c4d74f0f978ed5ceee62cd3f6708081042e582a1 ]
Function "for_each_child_of_node" should have of_node_put() before goto.
Generated by: scripts/coccinelle/iterators/for_each_child.cocci
--- drivers/of/overlay.c | 1 + 1 file changed, 1 insertion(+)
drivers/of/overlay.c +1 -0
@@ -796,6 +796,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs,if (!fragment->target) {of_node_put (fragment->overlay); ret = -EINVAL ; +of_node_put (node); goto err_free_fragments; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 301/530 x86/kprobes: Fix to check non boostable prefixes correctly
In reply to Greg Kroah-HartmanFrom: Masami Hiramatsu <[email protected]>
[ Upstream commit 6dd3b8c9f58816a1354be39559f630cd1bd12159 ]
There are 2 bugs in the can_boost() function because of using x86 insn decoder. Since the insn->opcode never has a prefix byte, it can not find CS override prefix in it. And the insn->attr is the attribute of the opcode, thus inat_is_address_size_prefix( insn->attr) always returns false.
Fix those by checking each prefix bytes with for_each_insn_prefix loop and getting the correct attribute for each prefix byte. Also, this removes unlikely, because this is a slow path.
--- arch/x86/kernel/kprobes/core.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
arch/x86/kernel/kprobes/core.c +12 -5
@@ -159,6 +159,8 @@ NOKPROBE_SYMBOL(skip_prefixes);int can_boost (struct insn *insn,void *addr) {kprobe_opcode_t opcode; +insn_byte_t prefix; +int i;if (search_exception_tables ((unsigned long )addr))return 0 ;/* Page fault may occur on this address. */
@@ -171,9 +173,14 @@ int can_boost(struct insn *insn, void *addr)if (insn->opcode.nbytes !=1 )return 0 ; -/* Can't boost Address-size override prefix */ -if (unlikely (inat_is_address_size_prefix (insn->attr))) -return 0 ; +for_each_insn_prefix (insn, i, prefix) { +insn_attr_t attr; + + attr =inat_get_opcode_attribute (prefix); +/* Can't boost Address-size override prefix and CS override prefix */ +if (prefix ==0x2e ||inat_is_address_size_prefix (attr)) +return 0 ; + } opcode = insn->opcode.bytes[0 ];
@@ -198,8 +205,8 @@ int can_boost(struct insn *insn, void *addr)/* clear and set flags are boostable */ return (opcode ==0xf5 || (0xf7 < opcode && opcode <0xfe ));default : -/* CS override prefix and call are not boostable */ -return (opcode !=0x2e && opcode !=0x9a ); +/* call is not boostable */ +return opcode !=0x9a ; } }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 302/530 selftests: fix prepending $(OUTPUT) to $(TEST_PROGS)
In reply to Greg Kroah-HartmanFrom: Ilya Leoshkevich <[email protected]>
[ Upstream commit cb4969e6f9f5ee12521aec764fa3d4bbd91bc797 ]
Currently the following command produces an error message:
linux# make kselftest TARGETS=bpf O=/mnt/linux-build
# selftests: bpf: test_libbpf.sh
# ./test_libbpf.sh: line 23: ./test_libbpf_open: No such file or directory # test_libbpf: failed at file test_l4lb.o
# selftests: test_libbpf [FAILED]
The error message might not affect the return code of make, therefore one needs to grep make output in order to detect it.
This is not the only instance of the same underlying problem; any test with more than one element in $(TEST_PROGS) fails the same way. Another example:
linux# make O=/mnt/linux-build TARGETS=splice kselftest [...]
# ./short_splice_read.sh: 15: ./splice_read: not found # FAIL: /sys/module/test_module/sections/.init.text 2 not ok 2 selftests: splice: short_splice_read.sh # exit=1
The current logic prepends $(OUTPUT) only to the first member of $(TEST_PROGS). After that, run_one() does
cd dirname $TEST
For all tests except the first one, dirname $TEST is ., which means they cannot access the files generated in $(OUTPUT).
Fix by using $(addprefix) to prepend $(OUTPUT)/ to each member of $(TEST_PROGS).
--- tools/testing/selftests/lib.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/testing/selftests/lib.mk +2 -1
@@ -74,7 +74,8 @@ ifdef building_out_of_srctree rsync -aq $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \ fi @if [ "X$(TEST_PROGS)" != "X" ]; then \ - $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(OUTPUT)/$(TEST_PROGS)) ; \ + $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) \ + $(addprefix $(OUTPUT)/,$(TEST_PROGS))) ; \ else \ $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS)); \ fi
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 303/530 pata_arasan_cf: fix IRQ check
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit c7e8f404d56b99c80990b19a402c3f640d74be05 ]
The driver's probe() method is written as if platform_get_irq() returns 0 on error, while actually it returns a negative error code (with all the other values considered valid IRQs). Rewrite the driver's IRQ checking code to pass the positive IRQ #s to ata_host_activate(), propagate upstream -EPROBE_DEFER, and set up the driver to polling mode on (negative) errors and IRQ0 (libata treats IRQ #0 as a polling mode anyway)...
--- drivers/ata/pata_arasan_cf.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/ata/pata_arasan_cf.c +11 -4
@@ -818,12 +818,19 @@ static int arasan_cf_probe(struct platform_device *pdev)else quirk =CF_BROKEN_UDMA ;/* as it is on spear1340 */ -/* if irq is 0, support only PIO */ - acdev->irq =platform_get_irq (pdev,0 ); -if (acdev->irq) +/* +* If there's an error getting IRQ (or we do get IRQ0), +* support only PIO +*/ + ret =platform_get_irq (pdev,0 ); +if (ret >0 ) { + acdev->irq = ret; irq_handler = arasan_cf_interrupt; -else + }else if (ret == -EPROBE_DEFER ) { +return ret; + }else { quirk |=CF_BROKEN_MWDMA |CF_BROKEN_UDMA ; + } acdev->pbase = res->start; acdev->vbase = devm_ioremap(&pdev->dev, res->start,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 304/530 pata_ipx4xx_cf: fix IRQ check
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit e379b40cc0f179403ce0b82b7e539f635a568da5 ]
The driver's probe() method is written as if platform_get_irq() returns 0 on error, while actually it returns a negative error code (with all the other values considered valid IRQs). Rewrite the driver's IRQ checking code to pass the positive IRQ #s to ata_host_activate(), propagate errors upstream, and treat IRQ0 as error, returning -EINVAL, as the libata code treats 0 as an indication that polling should be used anyway...
--- drivers/ata/pata_ixp4xx_cf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/ata/pata_ixp4xx_cf.c +5 -1
@@ -165,8 +165,12 @@ static int ixp4xx_pata_probe(struct platform_device *pdev)return -ENOMEM ; irq =platform_get_irq (pdev,0 ); -if (irq) +if (irq >0 )irq_set_irq_type (irq,IRQ_TYPE_EDGE_RISING ); +else if (irq <0 ) +return irq; +else +return -EINVAL ;/* Setup expansion bus chip selects */ *data->cs0_cfg = data->cs0_bits;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 305/530 sata_mv: add IRQ checks
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit e6471a65fdd5efbb8dd2732dd0f063f960685ceb ]
The function mv_platform_probe() neglects to check the results of the calls to platform_get_irq() and irq_of_parse_and_map() and blithely passes them to ata_host_activate() -- while the latter only checks for IRQ0 (treating it as a polling mode indicattion) and passes the negative values to devm_request_irq() causing it to fail as it takes unsigned values for the IRQ #...
Add to mv_platform_probe() the proper IRQ checks to pass the positive IRQ #s to ata_host_activate(), propagate upstream the negative error codes, and override the IRQ0 with -EINVAL (as we don't want the polling mode).
--- drivers/ata/sata_mv.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/ata/sata_mv.c +4 -0
@@ -4097,6 +4097,10 @@ static int mv_platform_probe(struct platform_device *pdev) n_ports = mv_platform_data->n_ports; irq =platform_get_irq (pdev,0 ); } +if (irq <0 ) +return irq; +if (!irq) +return -EINVAL ; host =ata_host_alloc_pinfo (&pdev->dev, ppi, n_ports); hpriv =devm_kzalloc (&pdev->dev,sizeof (*hpriv),GFP_KERNEL );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 306/530 ata: libahci_platform: fix IRQ check
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit b30d0040f06159de97ad9c0b1536f47250719d7d ]
Iff platform_get_irq() returns 0, ahci_platform_init_host() would return 0 early (as if the call was successful). Override IRQ0 with -EINVAL instead as the 'libata' regards 0 as "no IRQ" (thus polling) anyway...
--- drivers/ata/libahci_platform.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/ata/libahci_platform.c +3 -1
@@ -582,11 +582,13 @@ int ahci_platform_init_host(struct platform_device *pdev,int i, irq, n_ports, rc; irq =platform_get_irq (pdev,0 ); -if (irq <=0 ) { +if (irq <0 ) {if (irq != -EPROBE_DEFER )dev_err (dev,"no irq\n" );return irq; } +if (!irq) +return -EINVAL ; hpriv->irq = irq;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 307/530 seccomp: Fix CONFIG tests for Seccomp_filters
In reply to Greg Kroah-HartmanFrom: [email protected] <[email protected]>
[ Upstream commit 64bdc0244054f7d4bb621c8b4455e292f4e421bc ]
Strictly speaking, seccomp filters are only used when CONFIG_SECCOMP_FILTER.
This patch fixes the condition to enable "Seccomp_filters" in /proc/$pid/status.
--- fs/proc/array.c | 2 ++ init/init_task.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-)
fs/proc/array.c +2 -0
@@ -341,8 +341,10 @@ static inline void task_seccomp(struct seq_file *m, struct task_struct *p)seq_put_decimal_ull (m,"NoNewPrivs:\t" ,task_no_new_privs (p));#ifdef CONFIG_SECCOMP seq_put_decimal_ull (m,"\nSeccomp:\t" , p->seccomp.mode); +#ifdef CONFIG_SECCOMP_FILTER seq_put_decimal_ull (m,"\nSeccomp_filters:\t" ,atomic_read (&p->seccomp.filter_count)); +#endif #endif seq_puts (m,"\nSpeculation_Store_Bypass:\t" );switch (arch_prctl_spec_ctrl_get (p,PR_SPEC_STORE_BYPASS )) {
init/init_task.c +1 -1
@@ -210,7 +210,7 @@ struct task_struct init_task#ifdef CONFIG_SECURITY .security = NULL,#endif -#ifdef CONFIG_SECCOMP +#ifdef CONFIG_SECCOMP_FILTER .seccomp = { .filter_count = ATOMIC_INIT(0) },#endif };
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 308/530 nvme-tcp: block BH in sk state_change sk callback
In reply to Greg Kroah-HartmanFrom: Sagi Grimberg <[email protected]>
[ Upstream commit 8b73b45d54a14588f86792869bfb23098ea254cb ]
The TCP stack can run from process context for a long time so we should disable BH here.
--- drivers/nvme/host/tcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/nvme/host/tcp.c +2 -2
@@ -874,7 +874,7 @@ static void nvme_tcp_state_change(struct sock *sk) {struct nvme_tcp_queue *queue; -read_lock (&sk->sk_callback_lock); +read_lock_bh (&sk->sk_callback_lock); queue = sk->sk_user_data;if (!queue) goto done;
@@ -895,7 +895,7 @@ static void nvme_tcp_state_change(struct sock *sk) queue->state_change (sk); done: -read_unlock (&sk->sk_callback_lock); +read_unlock_bh (&sk->sk_callback_lock); }static inline bool nvme_tcp_queue_more (struct nvme_tcp_queue *queue)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 309/530 nvmet-tcp: fix incorrect locking in state_change sk callback
In reply to Greg Kroah-HartmanFrom: Sagi Grimberg <[email protected]>
[ Upstream commit b5332a9f3f3d884a1b646ce155e664cc558c1722 ]
We are not changing anything in the TCP connection state so we should not take a write_lock but rather a read lock.
This caused a deadlock when running nvmet-tcp and nvme-tcp on the same system, where state_change callbacks on the host and on the controller side have causal relationship and made lockdep report on this with blktests:
================================
WARNING: inconsistent lock state
5.12.0-rc3 #1 Tainted: G I
--------------------------------
inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-R} usage.
nvme/1324 [HC0[0]:SC0[0]:HE1:SE1] takes:ffff888363151000 (clock-AF_INET){++-?}-{2:2}, at: nvme_tcp_state_change+0x21/0x150 [nvme_tcp] {IN-SOFTIRQ-W} state was registered at:
__lock_acquire+0x79b/0x18d0 lock_acquire+0x1ca/0x480 _raw_write_lock_bh+0x39/0x80 nvmet_tcp_state_change+0x21/0x170 [nvmet_tcp] tcp_fin+0x2a8/0x780 tcp_data_queue+0xf94/0x1f20 tcp_rcv_established+0x6ba/0x1f00 tcp_v4_do_rcv+0x502/0x760 tcp_v4_rcv+0x257e/0x3430 ip_protocol_deliver_rcu+0x69/0x6a0 ip_local_deliver_finish+0x1e2/0x2f0 ip_local_deliver+0x1a2/0x420 ip_rcv+0x4fb/0x6b0 __netif_receive_skb_one_core+0x162/0x1b0 process_backlog+0x1ff/0x770 __napi_poll.constprop.0+0xa9/0x5c0 net_rx_action+0x7b3/0xb30 __do_softirq+0x1f0/0x940 do_softirq+0xa1/0xd0 __local_bh_enable_ip+0xd8/0x100 ip_finish_output2+0x6b7/0x18a0 __ip_queue_xmit+0x706/0x1aa0 __tcp_transmit_skb+0x2068/0x2e20 tcp_write_xmit+0xc9e/0x2bb0 __tcp_push_pending_frames+0x92/0x310 inet_shutdown+0x158/0x300 __nvme_tcp_stop_queue+0x36/0x270 [nvme_tcp] nvme_tcp_stop_queue+0x87/0xb0 [nvme_tcp] nvme_tcp_teardown_admin_queue+0x69/0xe0 [nvme_tcp] nvme_do_delete_ctrl+0x100/0x10c [nvme_core] nvme_sysfs_delete.cold+0x8/0xd [nvme_core] kernfs_fop_write_iter+0x2c7/0x460 new_sync_write+0x36c/0x610 vfs_write+0x5c0/0x870 ksys_write+0xf9/0x1d0 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xae irq event stamp: 10687 hardirqs last enabled at (10687): [<ffffffff9ec376bd>] _raw_spin_unlock_irqrestore+0x2d/0x40 hardirqs last disabled at (10686): [<ffffffff9ec374d8>] _raw_spin_lock_irqsave+0x68/0x90 softirqs last enabled at (10684): [<ffffffff9f000608>] __do_softirq+0x608/0x940 softirqs last disabled at (10649): [<ffffffff9cdedd31>] do_softirq+0xa1/0xd0
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
----
lock(clock-AF_INET);
<Interrupt>
lock(clock-AF_INET);*** DEADLOCK ***
5 locks held by nvme/1324:
#0: ffff8884a01fe470 (sb_writers#4){.+.+}-{0:0}, at: ksys_write+0xf9/0x1d0
#1: ffff8886e435c090 (&of->mutex){+.+.}-{3:3}, at: kernfs_fop_write_iter+0x216/0x460 #2: ffff888104d90c38 (kn->active#255){++++}-{0:0}, at: kernfs_remove_self+0x22d/0x330 #3: ffff8884634538d0 (&queue->queue_lock){+.+.}-{3:3}, at: nvme_tcp_stop_queue+0x52/0xb0 [nvme_tcp] #4: ffff888363150d30 (sk_lock-AF_INET){+.+.}-{0:0}, at: inet_shutdown+0x59/0x300
stack backtrace: CPU: 26 PID: 1324 Comm: nvme Tainted: G I 5.12.0-rc3 #1 Hardware name: Dell Inc. PowerEdge R640/06NR82, BIOS 2.10.0 11/12/2020 Call Trace: dump_stack+0x93/0xc2 mark_lock_irq.cold+0x2c/0xb3 ? verify_lock_unused+0x390/0x390 ? stack_trace_consume_entry+0x160/0x160 ? lock_downgrade+0x100/0x100 ? save_trace+0x88/0x5e0 ? _raw_spin_unlock_irqrestore+0x2d/0x40 mark_lock+0x530/0x1470 ? mark_lock_irq+0x1d10/0x1d10 ? enqueue_timer+0x660/0x660 mark_usage+0x215/0x2a0 __lock_acquire+0x79b/0x18d0 ? tcp_schedule_loss_probe.part.0+0x38c/0x520 lock_acquire+0x1ca/0x480 ? nvme_tcp_state_change+0x21/0x150 [nvme_tcp] ? rcu_read_unlock+0x40/0x40 ? tcp_mtu_probe+0x1ae0/0x1ae0 ? kmalloc_reserve+0xa0/0xa0 ? sysfs_file_ops+0x170/0x170 _raw_read_lock+0x3d/0xa0 ? nvme_tcp_state_change+0x21/0x150 [nvme_tcp] nvme_tcp_state_change+0x21/0x150 [nvme_tcp] ? sysfs_file_ops+0x170/0x170 inet_shutdown+0x189/0x300 __nvme_tcp_stop_queue+0x36/0x270 [nvme_tcp] nvme_tcp_stop_queue+0x87/0xb0 [nvme_tcp] nvme_tcp_teardown_admin_queue+0x69/0xe0 [nvme_tcp] nvme_do_delete_ctrl+0x100/0x10c [nvme_core] nvme_sysfs_delete.cold+0x8/0xd [nvme_core] kernfs_fop_write_iter+0x2c7/0x460 new_sync_write+0x36c/0x610 ? new_sync_read+0x600/0x600 ? lock_acquire+0x1ca/0x480 ? rcu_read_unlock+0x40/0x40 ? lock_is_held_type+0x9a/0x110 vfs_write+0x5c0/0x870 ksys_write+0xf9/0x1d0 ? __ia32_sys_read+0xa0/0xa0 ? lockdep_hardirqs_on_prepare.part.0+0x198/0x340 ? syscall_enter_from_user_mode+0x27/0x70 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xae
--- drivers/nvme/target/tcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/nvme/target/tcp.c +2 -2
@@ -1434,7 +1434,7 @@ static void nvmet_tcp_state_change(struct sock *sk) {struct nvmet_tcp_queue *queue; -write_lock_bh (&sk->sk_callback_lock); +read_lock_bh (&sk->sk_callback_lock); queue = sk->sk_user_data;if (!queue) goto done;
@@ -1452,7 +1452,7 @@ static void nvmet_tcp_state_change(struct sock *sk) queue->idx, sk->sk_state); } done: -write_unlock_bh (&sk->sk_callback_lock); +read_unlock_bh (&sk->sk_callback_lock); }static int nvmet_tcp_set_queue_sock (struct nvmet_tcp_queue *queue)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 310/530 clk: imx: Fix reparenting of UARTs not associated with stdout
In reply to Greg Kroah-HartmanFrom: Adam Ford <[email protected]>
[ Upstream commit 379c9a24cc239000b1dec53db02fe17a86947423 ]
Most if not all i.MX SoC's call a function which enables all UARTS. This is a problem for users who need to re-parent the clock source, because any attempt to change the parent results in an busy error due to the fact that the clocks have been enabled already.
clk: failed to reparent uart1 to sys_pll1_80m: -16
Instead of pre-initializing all UARTS, scan the device tree to see which UART clocks are associated to stdout, and only enable those UART clocks if it's needed early. This will move initialization of the remaining clocks until after the parenting of the clocks.
When the clocks are shutdown, this mechanism will also disable any clocks that were pre-initialized.
--- drivers/clk/imx/clk-imx25.c | 12 +--------- drivers/clk/imx/clk-imx27.c | 13 +---------- drivers/clk/imx/clk-imx35.c | 10 +-------- drivers/clk/imx/clk-imx5.c | 30 +++---------------------- drivers/clk/imx/clk-imx6q.c | 16 +------------- drivers/clk/imx/clk-imx6sl.c | 16 +------------- drivers/clk/imx/clk-imx6sll.c | 24 +------------------- drivers/clk/imx/clk-imx6sx.c | 16 +------------- drivers/clk/imx/clk-imx7d.c | 22 +------------------ drivers/clk/imx/clk-imx7ulp.c | 31 ++------------------------ drivers/clk/imx/clk-imx8mm.c | 18 ++------------- drivers/clk/imx/clk-imx8mn.c | 18 ++------------- drivers/clk/imx/clk-imx8mp.c | 17 +-------------- drivers/clk/imx/clk-imx8mq.c | 18 ++------------- drivers/clk/imx/clk.c | 41 +++++++++++++++++++++++++++-------- drivers/clk/imx/clk.h | 4 ++-- 16 files changed, 54 insertions(+), 252 deletions(-)
drivers/clk/imx/clk-imx25.c +1 -11
@@ -73,16 +73,6 @@ enum mx25_clks {static struct clk *clk[clk_max]; -static struct clk **const uart_clks[]__initconst = { - &clk[uart_ipg_per], - &clk[uart1_ipg], - &clk[uart2_ipg], - &clk[uart3_ipg], - &clk[uart4_ipg], - &clk[uart5_ipg], -NULL -}; -static int __init __mx25_clocks_init (void __iomem *ccm_base) {BUG_ON (!ccm_base);
@@ -228,7 +218,7 @@ static int __init __mx25_clocks_init(void __iomem *ccm_base)*/ clk_set_parent (clk[cko_sel], clk[ipg]); -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (6 );return 0 ; }
drivers/clk/imx/clk-imx27.c +1 -12
@@ -49,17 +49,6 @@ static const char *ssi_sel_clks[] = { "spll_gate", "mpll", };static struct clk *clk[IMX27_CLK_MAX ];static struct clk_onecell_data clk_data; -static struct clk **const uart_clks[]__initconst = { - &clk[IMX27_CLK_PER1_GATE ], - &clk[IMX27_CLK_UART1_IPG_GATE ], - &clk[IMX27_CLK_UART2_IPG_GATE ], - &clk[IMX27_CLK_UART3_IPG_GATE ], - &clk[IMX27_CLK_UART4_IPG_GATE ], - &clk[IMX27_CLK_UART5_IPG_GATE ], - &clk[IMX27_CLK_UART6_IPG_GATE ], -NULL -}; -static void __init _mx27_clocks_init (unsigned long fref) {BUG_ON (!ccm);
@@ -176,7 +165,7 @@ static void __init _mx27_clocks_init(unsigned long fref)clk_prepare_enable (clk[IMX27_CLK_EMI_AHB_GATE ]); -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (7 );imx_print_silicon_rev ("i.MX27" ,mx27_revision ()); }
drivers/clk/imx/clk-imx35.c +1 -9
@@ -82,14 +82,6 @@ enum mx35_clks {static struct clk *clk[clk_max]; -static struct clk **const uart_clks[]__initconst = { - &clk[ipg], - &clk[uart1_gate], - &clk[uart2_gate], - &clk[uart3_gate], -NULL -}; -static void __init _mx35_clocks_init (void ) {void __iomem *base;
@@ -243,7 +235,7 @@ static void __init _mx35_clocks_init(void)*/ clk_prepare_enable (clk[scc_gate]); -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (4 );imx_print_silicon_rev ("i.MX35" ,mx35_revision ()); }
drivers/clk/imx/clk-imx5.c +3 -27
@@ -128,30 +128,6 @@ static const char *ieee1588_sels[] = { "pll3_sw", "pll4_sw", "dummy" /* usbphy2_static struct clk *clk[IMX5_CLK_END ];static struct clk_onecell_data clk_data; -static struct clk **const uart_clks_mx51[]__initconst = { - &clk[IMX5_CLK_UART1_IPG_GATE ], - &clk[IMX5_CLK_UART1_PER_GATE ], - &clk[IMX5_CLK_UART2_IPG_GATE ], - &clk[IMX5_CLK_UART2_PER_GATE ], - &clk[IMX5_CLK_UART3_IPG_GATE ], - &clk[IMX5_CLK_UART3_PER_GATE ], -NULL -}; - -static struct clk **const uart_clks_mx50_mx53[]__initconst = { - &clk[IMX5_CLK_UART1_IPG_GATE ], - &clk[IMX5_CLK_UART1_PER_GATE ], - &clk[IMX5_CLK_UART2_IPG_GATE ], - &clk[IMX5_CLK_UART2_PER_GATE ], - &clk[IMX5_CLK_UART3_IPG_GATE ], - &clk[IMX5_CLK_UART3_PER_GATE ], - &clk[IMX5_CLK_UART4_IPG_GATE ], - &clk[IMX5_CLK_UART4_PER_GATE ], - &clk[IMX5_CLK_UART5_IPG_GATE ], - &clk[IMX5_CLK_UART5_PER_GATE ], -NULL -}; -static void __init mx5_clocks_common_init (void __iomem *ccm_base) { clk[IMX5_CLK_DUMMY ] =imx_clk_fixed ("dummy" ,0 );
@@ -382,7 +358,7 @@ static void __init mx50_clocks_init(struct device_node *np) r =clk_round_rate (clk[IMX5_CLK_USBOH3_PER_GATE ],54000000 );clk_set_rate (clk[IMX5_CLK_USBOH3_PER_GATE ], r); -imx_register_uart_clocks (uart_clks_mx50_mx53); +imx_register_uart_clocks (5 ); }CLK_OF_DECLARE (imx50_ccm,"fsl,imx50-ccm" , mx50_clocks_init);
@@ -488,7 +464,7 @@ static void __init mx51_clocks_init(struct device_node *np) val |=1 <<23 ;writel (val,MXC_CCM_CLPCR ); -imx_register_uart_clocks (uart_clks_mx51); +imx_register_uart_clocks (3 ); }CLK_OF_DECLARE (imx51_ccm,"fsl,imx51-ccm" , mx51_clocks_init);
@@ -633,6 +609,6 @@ static void __init mx53_clocks_init(struct device_node *np) r =clk_round_rate (clk[IMX5_CLK_USBOH3_PER_GATE ],54000000 );clk_set_rate (clk[IMX5_CLK_USBOH3_PER_GATE ], r); -imx_register_uart_clocks (uart_clks_mx50_mx53); +imx_register_uart_clocks (5 ); }CLK_OF_DECLARE (imx53_ccm,"fsl,imx53-ccm" , mx53_clocks_init);
drivers/clk/imx/clk-imx6q.c +1 -15
@@ -140,13 +140,6 @@ static inline int clk_on_imx6dl(void)return of_machine_is_compatible ("fsl,imx6dl" ); } -static const int uart_clk_ids[]__initconst = { -IMX6QDL_CLK_UART_IPG , -IMX6QDL_CLK_UART_SERIAL , -}; - -static struct clk **uart_clks[ARRAY_SIZE (uart_clk_ids) +1 ]__initdata ; -static int ldb_di_sel_by_clock_id (int clock_id) {switch (clock_id) {
@@ -440,7 +433,6 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)struct device_node *np;void __iomem *anatop_base, *base;int ret; -int i; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX6QDL_CLK_END ),GFP_KERNEL );
@@ -982,12 +974,6 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) hws[IMX6QDL_CLK_PLL3_USB_OTG]->clk); } -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_clks[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (1 ); }CLK_OF_DECLARE (imx6q,"fsl,imx6q-ccm" , imx6q_clocks_init);
drivers/clk/imx/clk-imx6sl.c +1 -15
@@ -178,19 +178,11 @@ void imx6sl_set_wait_clk(bool enter)imx6sl_enable_pll_arm (false); } -static const int uart_clk_ids[]__initconst = { -IMX6SL_CLK_UART , -IMX6SL_CLK_UART_SERIAL , -}; - -static struct clk **uart_clks[ARRAY_SIZE (uart_clk_ids) +1 ]__initdata ; -static void __init imx6sl_clocks_init (struct device_node *ccm_node) {struct device_node *np;void __iomem *base;int ret; -int i; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX6SL_CLK_END ),GFP_KERNEL );
@@ -447,12 +439,6 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)clk_set_parent (hws[IMX6SL_CLK_LCDIF_AXI_SEL ]->clk, hws[IMX6SL_CLK_PLL2_PFD2 ]->clk); -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_clks[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (2 ); }CLK_OF_DECLARE (imx6sl,"fsl,imx6sl-ccm" , imx6sl_clocks_init);
drivers/clk/imx/clk-imx6sll.c +1 -23
@@ -76,26 +76,10 @@ static u32 share_count_ssi1;static u32 share_count_ssi2;static u32 share_count_ssi3; -static const int uart_clk_ids[]__initconst = { -IMX6SLL_CLK_UART1_IPG , -IMX6SLL_CLK_UART1_SERIAL , -IMX6SLL_CLK_UART2_IPG , -IMX6SLL_CLK_UART2_SERIAL , -IMX6SLL_CLK_UART3_IPG , -IMX6SLL_CLK_UART3_SERIAL , -IMX6SLL_CLK_UART4_IPG , -IMX6SLL_CLK_UART4_SERIAL , -IMX6SLL_CLK_UART5_IPG , -IMX6SLL_CLK_UART5_SERIAL , -}; - -static struct clk **uart_clks[ARRAY_SIZE (uart_clk_ids) +1 ]__initdata ; -static void __init imx6sll_clocks_init (struct device_node *ccm_node) {struct device_node *np;void __iomem *base; -int i; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX6SLL_CLK_END ),GFP_KERNEL );
@@ -356,13 +340,7 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node)of_clk_add_hw_provider (np, of_clk_hw_onecell_get, clk_hw_data); -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_clks[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (5 );/* Lower the AHB clock rate before changing the clock source. */ clk_set_rate (hws[IMX6SLL_CLK_AHB ]->clk,99000000 );
drivers/clk/imx/clk-imx6sx.c +1 -15
@@ -117,18 +117,10 @@ static u32 share_count_ssi3;static u32 share_count_sai1;static u32 share_count_sai2; -static const int uart_clk_ids[]__initconst = { -IMX6SX_CLK_UART_IPG , -IMX6SX_CLK_UART_SERIAL , -}; - -static struct clk **uart_clks[ARRAY_SIZE (uart_clk_ids) +1 ]__initdata ; -static void __init imx6sx_clocks_init (struct device_node *ccm_node) {struct device_node *np;void __iomem *base; -int i; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX6SX_CLK_CLK_END ),GFP_KERNEL );
@@ -556,12 +548,6 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)clk_set_parent (hws[IMX6SX_CLK_QSPI1_SEL ]->clk, hws[IMX6SX_CLK_PLL2_BUS ]->clk);clk_set_parent (hws[IMX6SX_CLK_QSPI2_SEL ]->clk, hws[IMX6SX_CLK_PLL2_BUS ]->clk); -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_clks[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (2 ); }CLK_OF_DECLARE (imx6sx,"fsl,imx6sx-ccm" , imx6sx_clocks_init);
drivers/clk/imx/clk-imx7d.c +1 -21
@@ -377,23 +377,10 @@ static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_static struct clk_hw **hws;static struct clk_hw_onecell_data *clk_hw_data; -static const int uart_clk_ids[]__initconst = { -IMX7D_UART1_ROOT_CLK , -IMX7D_UART2_ROOT_CLK , -IMX7D_UART3_ROOT_CLK , -IMX7D_UART4_ROOT_CLK , -IMX7D_UART5_ROOT_CLK , -IMX7D_UART6_ROOT_CLK , -IMX7D_UART7_ROOT_CLK , -}; - -static struct clk **uart_clks[ARRAY_SIZE (uart_clk_ids) +1 ]__initdata ; -static void __init imx7d_clocks_init (struct device_node *ccm_node) {struct device_node *np;void __iomem *base; -int i; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX7D_CLK_END ),GFP_KERNEL );
@@ -897,14 +884,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) hws[IMX7D_USB1_MAIN_480M_CLK ] =imx_clk_hw_fixed_factor ("pll_usb1_main_clk" ,"osc" ,20 ,1 ); hws[IMX7D_USB_MAIN_480M_CLK ] =imx_clk_hw_fixed_factor ("pll_usb_main_clk" ,"osc" ,20 ,1 ); -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_clks[i] = &hws[index]->clk; - } - - -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (7 ); }CLK_OF_DECLARE (imx7d,"fsl,imx7d-ccm" , imx7d_clocks_init);
drivers/clk/imx/clk-imx7ulp.c +2 -29
@@ -43,19 +43,6 @@ static const struct clk_div_table ulp_div_table[] = { { /* sentinel */ }, }; -static const int pcc2_uart_clk_ids[]__initconst = { -IMX7ULP_CLK_LPUART4 , -IMX7ULP_CLK_LPUART5 , -}; - -static const int pcc3_uart_clk_ids[]__initconst = { -IMX7ULP_CLK_LPUART6 , -IMX7ULP_CLK_LPUART7 , -}; - -static struct clk **pcc2_uart_clks[ARRAY_SIZE (pcc2_uart_clk_ids) +1 ]__initdata ; -static struct clk **pcc3_uart_clks[ARRAY_SIZE (pcc3_uart_clk_ids) +1 ]__initdata ; -static void __init imx7ulp_clk_scg1_init (struct device_node *np) {struct clk_hw_onecell_data *clk_data;
@@ -150,7 +137,6 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np)struct clk_hw_onecell_data *clk_data;struct clk_hw **hws;void __iomem *base; -int i; clk_data =kzalloc (struct_size (clk_data, hws,IMX7ULP_CLK_PCC2_END ),GFP_KERNEL );
@@ -190,13 +176,7 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np)of_clk_add_hw_provider (np, of_clk_hw_onecell_get, clk_data); -for (i =0 ; i <ARRAY_SIZE (pcc2_uart_clk_ids); i++) { -int index = pcc2_uart_clk_ids[i]; - - pcc2_uart_clks[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (pcc2_uart_clks); +imx_register_uart_clocks (2 ); }CLK_OF_DECLARE (imx7ulp_clk_pcc2,"fsl,imx7ulp-pcc2" , imx7ulp_clk_pcc2_init);
@@ -205,7 +185,6 @@ static void __init imx7ulp_clk_pcc3_init(struct device_node *np)struct clk_hw_onecell_data *clk_data;struct clk_hw **hws;void __iomem *base; -int i; clk_data =kzalloc (struct_size (clk_data, hws,IMX7ULP_CLK_PCC3_END ),GFP_KERNEL );
@@ -244,13 +223,7 @@ static void __init imx7ulp_clk_pcc3_init(struct device_node *np)of_clk_add_hw_provider (np, of_clk_hw_onecell_get, clk_data); -for (i =0 ; i <ARRAY_SIZE (pcc3_uart_clk_ids); i++) { -int index = pcc3_uart_clk_ids[i]; - - pcc3_uart_clks[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (pcc3_uart_clks); +imx_register_uart_clocks (7 ); }CLK_OF_DECLARE (imx7ulp_clk_pcc3,"fsl,imx7ulp-pcc3" , imx7ulp_clk_pcc3_init);
drivers/clk/imx/clk-imx8mm.c +2 -16
@@ -291,20 +291,12 @@ static const char *imx8mm_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_static struct clk_hw_onecell_data *clk_hw_data;static struct clk_hw **hws; -static const int uart_clk_ids[] = { -IMX8MM_CLK_UART1_ROOT , -IMX8MM_CLK_UART2_ROOT , -IMX8MM_CLK_UART3_ROOT , -IMX8MM_CLK_UART4_ROOT , -}; -static struct clk **uart_hws[ARRAY_SIZE (uart_clk_ids) +1 ]; -static int imx8mm_clocks_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;struct device_node *np = dev->of_node;void __iomem *base; -int ret, i; +int ret; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX8MM_CLK_END ),GFP_KERNEL );
@@ -622,13 +614,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) goto unregister_hws; } -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_hws[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_hws); +imx_register_uart_clocks (4 );return 0 ;
drivers/clk/imx/clk-imx8mn.c +2 -16
@@ -284,20 +284,12 @@ static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "systatic struct clk_hw_onecell_data *clk_hw_data;static struct clk_hw **hws; -static const int uart_clk_ids[] = { -IMX8MN_CLK_UART1_ROOT , -IMX8MN_CLK_UART2_ROOT , -IMX8MN_CLK_UART3_ROOT , -IMX8MN_CLK_UART4_ROOT , -}; -static struct clk **uart_hws[ARRAY_SIZE (uart_clk_ids) +1 ]; -static int imx8mn_clocks_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;struct device_node *np = dev->of_node;void __iomem *base; -int ret, i; +int ret; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX8MN_CLK_END ),GFP_KERNEL );
@@ -573,13 +565,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) goto unregister_hws; } -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_hws[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_hws); +imx_register_uart_clocks (4 );return 0 ;
drivers/clk/imx/clk-imx8mp.c +1 -16
@@ -414,20 +414,11 @@ static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_rstatic struct clk_hw **hws;static struct clk_hw_onecell_data *clk_hw_data; -static const int uart_clk_ids[] = { -IMX8MP_CLK_UART1_ROOT , -IMX8MP_CLK_UART2_ROOT , -IMX8MP_CLK_UART3_ROOT , -IMX8MP_CLK_UART4_ROOT , -}; -static struct clk **uart_clks[ARRAY_SIZE (uart_clk_ids) +1 ]; -static int imx8mp_clocks_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;struct device_node *np = dev->of_node;void __iomem *anatop_base, *ccm_base; -int i; np =of_find_compatible_node (NULL ,NULL ,"fsl,imx8mp-anatop" ); anatop_base =of_iomap (np,0 );
@@ -737,13 +728,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)of_clk_add_hw_provider (np, of_clk_hw_onecell_get, clk_hw_data); -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_clks[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_clks); +imx_register_uart_clocks (4 );return 0 ; }
drivers/clk/imx/clk-imx8mq.c +2 -16
@@ -273,20 +273,12 @@ static const char * const imx8mq_clko2_sels[] = {"osc_25m", "sys2_pll_200m", "systatic struct clk_hw_onecell_data *clk_hw_data;static struct clk_hw **hws; -static const int uart_clk_ids[] = { -IMX8MQ_CLK_UART1_ROOT , -IMX8MQ_CLK_UART2_ROOT , -IMX8MQ_CLK_UART3_ROOT , -IMX8MQ_CLK_UART4_ROOT , -}; -static struct clk **uart_hws[ARRAY_SIZE (uart_clk_ids) +1 ]; -static int imx8mq_clocks_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;struct device_node *np = dev->of_node;void __iomem *base; -int err, i; +int err; clk_hw_data =kzalloc (struct_size (clk_hw_data, hws,IMX8MQ_CLK_END ),GFP_KERNEL );
@@ -607,13 +599,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) goto unregister_hws; } -for (i =0 ; i <ARRAY_SIZE (uart_clk_ids); i++) { -int index = uart_clk_ids[i]; - - uart_hws[i] = &hws[index]->clk; - } - -imx_register_uart_clocks (uart_hws); +imx_register_uart_clocks (4 );return 0 ;
drivers/clk/imx/clk.c +32 -9
64 lines not on this page · raw message
drivers/clk/imx/clk.h +2 -2
@@ -13,9 +13,9 @@ extern spinlock_t imx_ccm_lock;void imx_check_clocks (struct clk *clks[],unsigned int count);void imx_check_clk_hws (struct clk_hw *clks[],unsigned int count);#ifndef MODULE -void imx_register_uart_clocks (struct clk **const clks[]); +void imx_register_uart_clocks (unsigned int clk_count);#else -static inline void imx_register_uart_clocks (struct clk **const clks[]) +static inline void imx_register_uart_clocks (unsigned int clk_count) { }#endif
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 311/530 power: supply: bq25980: Move props from battery node
In reply to Greg Kroah-HartmanFrom: Ricardo Rivera-Matos <[email protected]>
[ Upstream commit 04722cec1436c732d39153ce6ae2ebf71ac3ade7 ]
Currently POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT and POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE are exposed on the battery node and this is incorrect.
This patch exposes both of them on the charger node rather than the battery node.
--- drivers/power/supply/bq25980_charger.c | 40 ++++++++------------------ 1 file changed, 12 insertions(+), 28 deletions(-)
drivers/power/supply/bq25980_charger.c +12 -28
@@ -606,33 +606,6 @@ static int bq25980_get_state(struct bq25980_device *bq,return 0 ; } -static int bq25980_set_battery_property (struct power_supply *psy, -enum power_supply_property psp, -const union power_supply_propval *val) -{ -struct bq25980_device *bq =power_supply_get_drvdata (psy); -int ret =0 ; - -switch (psp) { -case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT : - ret =bq25980_set_const_charge_curr (bq, val->intval); -if (ret) -return ret; -break ; - -case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE : - ret =bq25980_set_const_charge_volt (bq, val->intval); -if (ret) -return ret; -break ; - -default : -return -EINVAL ; - } - -return ret; -} -static int bq25980_get_battery_property (struct power_supply *psy,enum power_supply_property psp,union power_supply_propval *val)
@@ -701,6 +674,18 @@ static int bq25980_set_charger_property(struct power_supply *psy,return ret;break ; +case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT : + ret =bq25980_set_const_charge_curr (bq, val->intval); +if (ret) +return ret; +break ; + +case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE : + ret =bq25980_set_const_charge_volt (bq, val->intval); +if (ret) +return ret; +break ; +default :return -EINVAL ; }
@@ -922,7 +907,6 @@ static struct power_supply_desc bq25980_battery_desc = { .name = "bq25980-battery", .type = POWER_SUPPLY_TYPE_BATTERY, .get_property = bq25980_get_battery_property, - .set_property = bq25980_set_battery_property, .properties = bq25980_battery_props, .num_properties = ARRAY_SIZE(bq25980_battery_props), .property_is_writeable = bq25980_property_is_writeable,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 312/530 nvme: retrigger ANA log update if group descriptor isnt found
In reply to Greg Kroah-HartmanFrom: Hannes Reinecke <[email protected]>
[ Upstream commit dd8f7fa908f66dd44abcd83cbb50410524b9f8ef ]
If ANA is enabled but no ANA group descriptor is found when creating a new namespace the ANA log is most likely out of date, so trigger a re-read. The namespace will be tagged with the NS_ANA_PENDING flag to exclude it from path selection until the ANA log has been re-read.
--- drivers/nvme/host/multipath.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/nvme/host/multipath.c +4 -0
@@ -667,6 +667,10 @@ void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id)if (desc.state) {/* found the group desc: update */ nvme_update_ns_ana_state (&desc, ns); + }else { +/* group desc not found: trigger a re-read */ +set_bit (NVME_NS_ANA_PENDING , &ns->flags); +queue_work (nvme_wq, &ns->ctrl->ana_work); } }else { ns->ana_state =NVME_ANA_OPTIMIZED ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 313/530 media: i2c: imx219: Move out locking/unlocking of vflip and hflip controls from imx219_set_stream
In reply to Greg Kroah-HartmanFrom: Lad Prabhakar <[email protected]>
[ Upstream commit 745d4612d2c853c00abadbf69799c8aee7f99c39 ]
Move out locking/unlocking of vflip and hflip controls from imx219_set_stream() to the imx219_start_streaming()/ imx219_stop_streaming() respectively.
This fixes an issue in resume callback error path where streaming is stopped and the controls are left in locked state.
--- drivers/media/i2c/imx219.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
drivers/media/i2c/imx219.c +13 -6
@@ -1047,8 +1047,16 @@ static int imx219_start_streaming(struct imx219 *imx219)return ret;/* set stream on register */ -return imx219_write_reg (imx219,IMX219_REG_MODE_SELECT , -IMX219_REG_VALUE_08BIT ,IMX219_MODE_STREAMING ); + ret =imx219_write_reg (imx219,IMX219_REG_MODE_SELECT , +IMX219_REG_VALUE_08BIT ,IMX219_MODE_STREAMING ); +if (ret) +return ret; + +/* vflip and hflip cannot change during streaming */ +__v4l2_ctrl_grab (imx219->vflip, true); +__v4l2_ctrl_grab (imx219->hflip, true); + +return 0 ; }static void imx219_stop_streaming (struct imx219 *imx219)
@@ -1061,6 +1069,9 @@ static void imx219_stop_streaming(struct imx219 *imx219) IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY);if (ret)dev_err (&client->dev,"%s failed to set stream\n" , __func__); + +__v4l2_ctrl_grab (imx219->vflip, false); +__v4l2_ctrl_grab (imx219->hflip, false); }static int imx219_set_stream (struct v4l2_subdev *sd,int enable)
@@ -1096,10 +1107,6 @@ static int imx219_set_stream(struct v4l2_subdev *sd, int enable) imx219->streaming = enable; -/* vflip and hflip cannot change during streaming */ -__v4l2_ctrl_grab (imx219->vflip, enable); -__v4l2_ctrl_grab (imx219->hflip, enable); -mutex_unlock (&imx219->mutex);return ret;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 314/530 media: i2c: imx219: Balance runtime PM use-count
In reply to Greg Kroah-HartmanFrom: Lad Prabhakar <[email protected]>
[ Upstream commit dd90caa0111e178b52b21e56364bc2244a3973b3 ]
Move incrementing/decrementing runtime PM count to imx219_start_streaming()/imx219_stop_streaming() functions respectively.
This fixes an issue of unbalanced runtime PM count in resume callback error path where streaming is stopped and runtime PM count is left unbalanced.
--- drivers/media/i2c/imx219.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-)
drivers/media/i2c/imx219.c +17 -15
@@ -1026,37 +1026,47 @@ static int imx219_start_streaming(struct imx219 *imx219)const struct imx219_reg_list *reg_list;int ret; + ret =pm_runtime_get_sync (&client->dev); +if (ret <0 ) { +pm_runtime_put_noidle (&client->dev); +return ret; + } +/* Apply default values of current mode */ reg_list = &imx219->mode->reg_list; ret =imx219_write_regs (imx219, reg_list->regs, reg_list->num_of_regs);if (ret) {dev_err (&client->dev,"%s failed to set mode\n" , __func__); -return ret; + goto err_rpm_put; } ret =imx219_set_framefmt (imx219);if (ret) {dev_err (&client->dev,"%s failed to set frame format: %d\n" , __func__, ret); -return ret; + goto err_rpm_put; }/* Apply customized values from user */ ret =__v4l2_ctrl_handler_setup (imx219->sd.ctrl_handler);if (ret) -return ret; + goto err_rpm_put;/* set stream on register */ ret =imx219_write_reg (imx219,IMX219_REG_MODE_SELECT ,IMX219_REG_VALUE_08BIT ,IMX219_MODE_STREAMING );if (ret) -return ret; + goto err_rpm_put;/* vflip and hflip cannot change during streaming */ __v4l2_ctrl_grab (imx219->vflip, true);__v4l2_ctrl_grab (imx219->hflip, true);return 0 ; + +err_rpm_put: +pm_runtime_put (&client->dev); +return ret; }static void imx219_stop_streaming (struct imx219 *imx219)
@@ -1072,12 +1082,13 @@ static void imx219_stop_streaming(struct imx219 *imx219)__v4l2_ctrl_grab (imx219->vflip, false);__v4l2_ctrl_grab (imx219->hflip, false); + +pm_runtime_put (&client->dev); }static int imx219_set_stream (struct v4l2_subdev *sd,int enable) {struct imx219 *imx219 =to_imx219 (sd); -struct i2c_client *client =v4l2_get_subdevdata (sd);int ret =0 ;mutex_lock (&imx219->mutex);
@@ -1087,22 +1098,15 @@ static int imx219_set_stream(struct v4l2_subdev *sd, int enable) }if (enable) { - ret =pm_runtime_get_sync (&client->dev); -if (ret <0 ) { -pm_runtime_put_noidle (&client->dev); - goto err_unlock; - } -/* * Apply default & customized values * and then start streaming. */ ret =imx219_start_streaming (imx219);if (ret) - goto err_rpm_put; + goto err_unlock; }else {imx219_stop_streaming (imx219); -pm_runtime_put (&client->dev); } imx219->streaming = enable;
@@ -1111,8 +1115,6 @@ static int imx219_set_stream(struct v4l2_subdev *sd, int enable)return ret; -err_rpm_put: -pm_runtime_put (&client->dev); err_unlock:mutex_unlock (&imx219->mutex);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 315/530 media: v4l2-ctrls.c: fix race condition in hdl->requests list
In reply to Greg Kroah-HartmanFrom: Hans Verkuil <[email protected]>
[ Upstream commit be7e8af98f3af729aa9f08b1053f9533a5cceb91 ]
When a request is re-inited it will release all control handler objects that are still in the request. It does that by unbinding and putting all those objects. When the object is unbound the obj->req pointer is set to NULL, and the object's unbind op is called. When the object it put the object's release op is called to free the memory.
For a request object that contains a control handler that means that v4l2_ctrl_handler_free() is called in the release op.
A control handler used in a request has a pointer to the main control handler that is created by the driver and contains the current state of all controls. If the device is unbound (due to rmmod or a forced unbind), then that main handler is freed, again by calling v4l2_ctrl_handler_free(), and any outstanding request objects that refer to that main handler have to be unbound and put as well.
It does that by this test:
if (!hdl->req_obj.req && !list_empty(&hdl->requests)) {I.e. the handler has no pointer to a request, so is the main handler, and one or more request objects refer to this main handler.
However, this test is wrong since hdl->req_obj.req is actually NULL when re-initing a request (the object unbind will set req to NULL), and the only reason this seemingly worked is that the requests list is typically empty since the request's unbind op will remove the handler from the requests list.
But if another thread is at the same time adding a new control to a request, then there is a race condition where one thread is removing a control handler object from the requests list and another thread is adding one. The result is that hdl->requests is no longer empty and the code thinks that a main handler is being freed instead of a control handler that is part of a request.
There are two bugs here: first the test for hdl->req_obj.req: this should be hdl->req_obj.ops since only the main control handler will have a NULL pointer there.
The second is that adding or deleting request objects from the requests list of the main handler isn't protected by taking the main handler's lock.
--- drivers/media/v4l2-core/v4l2-ctrls.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
drivers/media/v4l2-core/v4l2-ctrls.c +14 -3
@@ -2356,7 +2356,15 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)if (hdl ==NULL || hdl->buckets ==NULL )return ; -if (!hdl->req_obj.req && !list_empty (&hdl->requests)) { +/* +* If the main handler is freed and it is used by handler objects in +* outstanding requests, then unbind and put those objects before +* freeing the main handler. +* +* The main handler can be identified by having a NULL ops pointer in +* the request object. +*/ +if (!hdl->req_obj.ops && !list_empty (&hdl->requests)) {struct v4l2_ctrl_handler *req, *next_req;list_for_each_entry_safe (req, next_req, &hdl->requests, requests) {
@@ -3402,8 +3410,8 @@ static void v4l2_ctrl_request_unbind(struct media_request_object *obj) container_of(obj, struct v4l2_ctrl_handler, req_obj);struct v4l2_ctrl_handler *main_hdl = obj->priv; -list_del_init (&hdl->requests);mutex_lock (main_hdl->lock); +list_del_init (&hdl->requests);if (hdl->request_is_queued) {list_del_init (&hdl->requests_queued); hdl->request_is_queued = false;
@@ -3462,8 +3470,11 @@ static int v4l2_ctrl_request_bind(struct media_request *req,if (!ret) { ret =media_request_object_bind (req, &req_ops, from, false, &hdl->req_obj); -if (!ret) +if (!ret) { +mutex_lock (from->lock);list_add_tail (&hdl->requests, &from->requests); +mutex_unlock (from->lock); + } }return ret; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 316/530 vfio/fsl-mc: Re-order vfio_fsl_mc_probe()
In reply to Greg Kroah-HartmanFrom: Jason Gunthorpe <[email protected]>
[ Upstream commit 2b1fe162e584a88ec7f12a651a2a50f94dd8cfac ]
vfio_add_group_dev() must be called only after all of the private data in vdev is fully setup and ready, otherwise there could be races with user space instantiating a device file descriptor and starting to call ops.
For instance vfio_fsl_mc_reflck_attach() sets vdev->reflck and vfio_fsl_mc_open(), called by fops open, unconditionally derefs it, which will crash if things get out of order.
This driver started life with the right sequence, but two commits added stuff after vfio_add_group_dev().
Message-Id: <[email protected]>
--- drivers/vfio/fsl-mc/vfio_fsl_mc.c | 74 ++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 27 deletions(-)
drivers/vfio/fsl-mc/vfio_fsl_mc.c +47 -27
@@ -568,23 +568,39 @@ static int vfio_fsl_mc_init_device(struct vfio_fsl_mc_device *vdev)dev_err (&mc_dev->dev,"VFIO_FSL_MC: Failed to setup DPRC (%d)\n" , ret); goto out_nc_unreg; } +return 0 ; + +out_nc_unreg: +bus_unregister_notifier (&fsl_mc_bus_type, &vdev->nb); +return ret; +} +static int vfio_fsl_mc_scan_container (struct fsl_mc_device *mc_dev) +{ +int ret; + +/* non dprc devices do not scan for other devices */ +if (!is_fsl_mc_bus_dprc (mc_dev)) +return 0 ; ret =dprc_scan_container (mc_dev, false);if (ret) { -dev_err (&mc_dev->dev,"VFIO_FSL_MC: Container scanning failed (%d)\n" , ret); - goto out_dprc_cleanup; +dev_err (&mc_dev->dev, +"VFIO_FSL_MC: Container scanning failed (%d)\n" , ret); +dprc_remove_devices (mc_dev,NULL ,0 ); +return ret; } -return 0 ; +} + +static void vfio_fsl_uninit_device (struct vfio_fsl_mc_device *vdev) +{ +struct fsl_mc_device *mc_dev = vdev->mc_dev; + +if (!is_fsl_mc_bus_dprc (mc_dev)) +return ; -out_dprc_cleanup: -dprc_remove_devices (mc_dev,NULL ,0 );dprc_cleanup (mc_dev); -out_nc_unreg:bus_unregister_notifier (&fsl_mc_bus_type, &vdev->nb); - vdev->nb.notifier_call =NULL ; - -return ret; }static int vfio_fsl_mc_probe (struct fsl_mc_device *mc_dev)
@@ -607,29 +623,39 @@ static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev) } vdev->mc_dev = mc_dev; - - ret =vfio_add_group_dev (dev, &vfio_fsl_mc_ops, vdev); -if (ret) { -dev_err (dev,"VFIO_FSL_MC: Failed to add to vfio group\n" ); - goto out_group_put; - } +mutex_init (&vdev->igate); ret =vfio_fsl_mc_reflck_attach (vdev);if (ret) - goto out_group_dev; + goto out_group_put; ret =vfio_fsl_mc_init_device (vdev);if (ret) goto out_reflck; -mutex_init (&vdev->igate); + ret =vfio_add_group_dev (dev, &vfio_fsl_mc_ops, vdev); +if (ret) { +dev_err (dev,"VFIO_FSL_MC: Failed to add to vfio group\n" ); + goto out_device; + } +/* +* This triggers recursion into vfio_fsl_mc_probe() on another device +* and the vfio_fsl_mc_reflck_attach() must succeed, which relies on the +* vfio_add_group_dev() above. It has no impact on this vdev, so it is +* safe to be after the vfio device is made live. +*/ + ret =vfio_fsl_mc_scan_container (mc_dev); +if (ret) + goto out_group_dev;return 0 ; -out_reflck: -vfio_fsl_mc_reflck_put (vdev->reflck); out_group_dev:vfio_del_group_dev (dev); +out_device: +vfio_fsl_uninit_device (vdev); +out_reflck: +vfio_fsl_mc_reflck_put (vdev->reflck); out_group_put:vfio_iommu_group_put (group, dev);return ret;
@@ -646,16 +672,10 @@ static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev)mutex_destroy (&vdev->igate); +dprc_remove_devices (mc_dev,NULL ,0 ); +vfio_fsl_uninit_device (vdev);vfio_fsl_mc_reflck_put (vdev->reflck); -if (is_fsl_mc_bus_dprc (mc_dev)) { -dprc_remove_devices (mc_dev,NULL ,0 ); -dprc_cleanup (mc_dev); - } - -if (vdev->nb.notifier_call) -bus_unregister_notifier (&fsl_mc_bus_type, &vdev->nb); -vfio_iommu_group_put (mc_dev->dev.iommu_group, dev);return 0 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 317/530 vfio/pci: Move VGA and VF initialization to functions
In reply to Greg Kroah-HartmanFrom: Jason Gunthorpe <[email protected]>
[ Upstream commit 61e90817482871b614133c0f20feb1aba2faec86 ]
vfio_pci_probe() is quite complicated, with optional VF and VGA sub components. Move these into clear init/uninit functions and have a linear flow in probe/remove.
This fixes a few little buglets:
- vfio_pci_remove() is in the wrong order, vga_client_register() removes a notifier and is after kfree(vdev), but the notifier refers to vdev, so it can use after free in a race.
- vga_client_register() can fail but was ignored
Organize things so destruction order is the reverse of creation order.
Message-Id: <[email protected]>
--- drivers/vfio/pci/vfio_pci.c | 116 +++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 42 deletions(-)
drivers/vfio/pci/vfio_pci.c +74 -42
@@ -1926,6 +1926,68 @@ static int vfio_pci_bus_notifier(struct notifier_block *nb,return 0 ; } +static int vfio_pci_vf_init (struct vfio_pci_device *vdev) +{ +struct pci_dev *pdev = vdev->pdev; +int ret; + +if (!pdev->is_physfn) +return 0 ; + + vdev->vf_token =kzalloc (sizeof (*vdev->vf_token),GFP_KERNEL ); +if (!vdev->vf_token) +return -ENOMEM ; + +mutex_init (&vdev->vf_token->lock); +uuid_gen (&vdev->vf_token->uuid); + + vdev->nb.notifier_call = vfio_pci_bus_notifier; + ret =bus_register_notifier (&pci_bus_type, &vdev->nb); +if (ret) { +kfree (vdev->vf_token); +return ret; + } +return 0 ; +} + +static void vfio_pci_vf_uninit (struct vfio_pci_device *vdev) +{ +if (!vdev->vf_token) +return ; + +bus_unregister_notifier (&pci_bus_type, &vdev->nb); +WARN_ON (vdev->vf_token->users); +mutex_destroy (&vdev->vf_token->lock); +kfree (vdev->vf_token); +} + +static int vfio_pci_vga_init (struct vfio_pci_device *vdev) +{ +struct pci_dev *pdev = vdev->pdev; +int ret; + +if (!vfio_pci_is_vga (pdev)) +return 0 ; + + ret =vga_client_register (pdev, vdev,NULL , vfio_pci_set_vga_decode); +if (ret) +return ret; +vga_set_legacy_decoding (pdev,vfio_pci_set_vga_decode (vdev, false)); +return 0 ; +} + +static void vfio_pci_vga_uninit (struct vfio_pci_device *vdev) +{ +struct pci_dev *pdev = vdev->pdev; + +if (!vfio_pci_is_vga (pdev)) +return ; +vga_client_register (pdev,NULL ,NULL ,NULL ); +vga_set_legacy_decoding (pdev,VGA_RSRC_NORMAL_IO |VGA_RSRC_NORMAL_MEM | +VGA_RSRC_LEGACY_IO | +VGA_RSRC_LEGACY_MEM ); +} +static int vfio_pci_probe (struct pci_dev *pdev,const struct pci_device_id *id) {struct vfio_pci_device *vdev;
@@ -1979,28 +2041,12 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ret =vfio_pci_reflck_attach (vdev);if (ret) goto out_del_group_dev; - -if (pdev->is_physfn) { - vdev->vf_token =kzalloc (sizeof (*vdev->vf_token),GFP_KERNEL ); -if (!vdev->vf_token) { - ret = -ENOMEM ; - goto out_reflck; - } - -mutex_init (&vdev->vf_token->lock); -uuid_gen (&vdev->vf_token->uuid); - - vdev->nb.notifier_call = vfio_pci_bus_notifier; - ret =bus_register_notifier (&pci_bus_type, &vdev->nb); -if (ret) - goto out_vf_token; - } - -if (vfio_pci_is_vga (pdev)) { -vga_client_register (pdev, vdev,NULL , vfio_pci_set_vga_decode); -vga_set_legacy_decoding (pdev, -vfio_pci_set_vga_decode (vdev, false)); - } + ret =vfio_pci_vf_init (vdev); +if (ret) + goto out_reflck; + ret =vfio_pci_vga_init (vdev); +if (ret) + goto out_vf;vfio_pci_probe_power_state (vdev);
@@ -2020,8 +2066,8 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)return ret; -out_vf_token: -kfree (vdev->vf_token); +out_vf: +vfio_pci_vf_uninit (vdev); out_reflck:vfio_pci_reflck_put (vdev->reflck); out_del_group_dev:
@@ -2043,33 +2089,19 @@ static void vfio_pci_remove(struct pci_dev *pdev)if (!vdev)return ; -if (vdev->vf_token) { -WARN_ON (vdev->vf_token->users); -mutex_destroy (&vdev->vf_token->lock); -kfree (vdev->vf_token); - } - -if (vdev->nb.notifier_call) -bus_unregister_notifier (&pci_bus_type, &vdev->nb); - +vfio_pci_vf_uninit (vdev);vfio_pci_reflck_put (vdev->reflck); +vfio_pci_vga_uninit (vdev);vfio_iommu_group_put (pdev->dev.iommu_group, &pdev->dev); -kfree (vdev->region); -mutex_destroy (&vdev->ioeventfds_lock);if (!disable_idle_d3)vfio_pci_set_power_state (vdev,PCI_D0 ); +mutex_destroy (&vdev->ioeventfds_lock); +kfree (vdev->region);kfree (vdev->pm_save);kfree (vdev); - -if (vfio_pci_is_vga (pdev)) { -vga_client_register (pdev,NULL ,NULL ,NULL ); -vga_set_legacy_decoding (pdev, -VGA_RSRC_NORMAL_IO |VGA_RSRC_NORMAL_MEM | -VGA_RSRC_LEGACY_IO |VGA_RSRC_LEGACY_MEM ); - } } static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 318/530 vfio/pci: Re-order vfio_pci_probe()
In reply to Greg Kroah-HartmanFrom: Jason Gunthorpe <[email protected]>
[ Upstream commit 4aeec3984ddc853f7c65903bde472ffdef738bae ]
vfio_add_group_dev() must be called only after all of the private data in vdev is fully setup and ready, otherwise there could be races with user space instantiating a device file descriptor and starting to call ops.
For instance vfio_pci_reflck_attach() sets vdev->reflck and vfio_pci_open(), called by fops open, unconditionally derefs it, which will crash if things get out of order.
Message-Id: <[email protected]>
--- drivers/vfio/pci/vfio_pci.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
drivers/vfio/pci/vfio_pci.c +9 -8
@@ -2034,13 +2034,9 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)INIT_LIST_HEAD (&vdev->vma_list);init_rwsem (&vdev->memory_lock); - ret =vfio_add_group_dev (&pdev->dev, &vfio_pci_ops, vdev); -if (ret) - goto out_free; - ret =vfio_pci_reflck_attach (vdev);if (ret) - goto out_del_group_dev; + goto out_free; ret =vfio_pci_vf_init (vdev);if (ret) goto out_reflck;
@@ -2064,15 +2060,20 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)vfio_pci_set_power_state (vdev, PCI_D3hot); } -return ret; + ret =vfio_add_group_dev (&pdev->dev, &vfio_pci_ops, vdev); +if (ret) + goto out_power; +return 0 ; +out_power: +if (!disable_idle_d3) +vfio_pci_set_power_state (vdev,PCI_D0 ); out_vf:vfio_pci_vf_uninit (vdev); out_reflck:vfio_pci_reflck_put (vdev->reflck); -out_del_group_dev: -vfio_del_group_dev (&pdev->dev); out_free: +kfree (vdev->pm_save);kfree (vdev); out_group_put:vfio_iommu_group_put (group, &pdev->dev);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 319/530 vfio/mdev: Do not allow a mdev_type to have a NULL parent pointer
In reply to Greg Kroah-HartmanFrom: Jason Gunthorpe <[email protected]>
[ Upstream commit b5a1f8921d5040bb788492bf33a66758021e4be5 ]
There is a small race where the parent is NULL even though the kobj has already been made visible in sysfs.
For instance the attribute_group is made visible in sysfs_create_files() and the mdev_type_attr_show() does:
ret = attr->show(kobj, type->parent->dev, buf);
Which will crash on NULL parent. Move the parent setup to before the type pointer leaves the stack frame.
Message-Id: <[email protected]>
--- drivers/vfio/mdev/mdev_sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/vfio/mdev/mdev_sysfs.c +1 -1
@@ -105,6 +105,7 @@ static struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent,return ERR_PTR (-ENOMEM ); type->kobj.kset = parent->mdev_types_kset; + type->parent = parent; ret = kobject_init_and_add(&type->kobj, &mdev_type_ktype, NULL, "%s-%s", dev_driver_string(parent->dev),
@@ -132,7 +133,6 @@ static struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent, } type->group = group; - type->parent = parent;return type; attrs_failed:
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 320/530 clk: zynqmp: move zynqmp_pll_set_mode out of round_rate callback
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
[ Upstream commit d7fd3f9f53df8bb2212dff70f66f12cae0e1a653 ]
The round_rate callback should only perform rate calculation and not involve calling zynqmp_pll_set_mode to change the pll mode. So let's move zynqmp_pll_set_mode out of round_rate and to set_rate callback.
--- drivers/clk/zynqmp/pll.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/clk/zynqmp/pll.c +6 -6
@@ -100,9 +100,7 @@ static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate,/* Enable the fractional mode if needed */ rate_div = (rate *FRAC_DIV ) / *prate; f = rate_div %FRAC_DIV ; -zynqmp_pll_set_mode (hw, !!f); - -if (zynqmp_pll_get_mode (hw) ==PLL_MODE_FRAC ) { +if (f) {if (rate >PS_PLL_VCO_MAX ) { fbdiv = rate /PS_PLL_VCO_MAX ; rate = rate / (fbdiv +1 );
@@ -173,10 +171,12 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,long rate_div, frac, m, f;int ret; -if (zynqmp_pll_get_mode (hw) ==PLL_MODE_FRAC ) { - rate_div = (rate *FRAC_DIV ) / parent_rate; + rate_div = (rate *FRAC_DIV ) / parent_rate; + f = rate_div %FRAC_DIV ; +zynqmp_pll_set_mode (hw, !!f); + +if (f) { m = rate_div /FRAC_DIV ; - f = rate_div %FRAC_DIV ; m =clamp_t (u32, m, (PLL_FBDIV_MIN ), (PLL_FBDIV_MAX )); rate = parent_rate * m; frac = (parent_rate * f) /FRAC_DIV ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 321/530 clk: zynqmp: pll: add set_pll_mode to check condition in zynqmp_pll_enable
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
[ Upstream commit 394cdb69a3c30b33524cf1204afe5cceaba69cdc ]
If there is a IOCTL_SET_PLL_FRAC_MODE request sent to ATF ever, we shouldn't skip invoking PM_CLOCK_ENABLE fn even though this pll has been enabled. In ATF implementation, it will only assign the mode to the variable (struct pm_pll *)pll->mode when handling IOCTL_SET_PLL_FRAC_MODE call. Invoking PM_CLOCK_ENABLE can force ATF send request to PWU to set the pll mode to PLL's register.
There is a scenario that happens in enabling VPLL_INT(clk_id:96):
1) VPLL_INT has been enabled during booting.
2) A driver calls clk_set_rate and according to the rate, the VPLL_INT should be set to FRAC mode. Then zynqmp_pll_set_mode is called to pass IOCTL_SET_PLL_FRAC_MODE to ATF. Note that at this point ATF just stores the mode to a variable.
3) This driver calls clk_prepare_enable and zynqmp_pll_enable is called to try to enable VPLL_INT pll. Because of 1), the function zynqmp_pll_enable just returns without doing anything after checking that this pll has been enabled.
In the scenario above, the pll mode of VPLL_INT will never be set successfully. So adding set_pll_mode to check condition to fix it.
--- drivers/clk/zynqmp/pll.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/clk/zynqmp/pll.c +11 -1
@@ -14,10 +14,12 @@* struct zynqmp_pll - PLL clock * @hw: Handle between common and hardware-specific interfaces * @clk_id: PLL clock ID +* @set_pll_mode: Whether an IOCTL_SET_PLL_FRAC_MODE request be sent to ATF */ struct zynqmp_pll {struct clk_hw hw;u32 clk_id; +bool set_pll_mode; };#define to_zynqmp_pll (_hw) container_of(_hw, struct zynqmp_pll, hw)
@@ -81,6 +83,8 @@ static inline void zynqmp_pll_set_mode(struct clk_hw *hw, bool on)if (ret)pr_warn_once ("%s() PLL set frac mode failed for %s, ret = %d\n" , __func__, clk_name, ret); +else + clk->set_pll_mode = true; }/**
@@ -240,9 +244,15 @@ static int zynqmp_pll_enable(struct clk_hw *hw)u32 clk_id = clk->clk_id;int ret; -if (zynqmp_pll_is_enabled (hw)) +/* +* Don't skip enabling clock if there is an IOCTL_SET_PLL_FRAC_MODE request +* that has been sent to ATF. +*/ +if (zynqmp_pll_is_enabled (hw) && (!clk->set_pll_mode))return 0 ; + clk->set_pll_mode = false; + ret =zynqmp_pm_clock_enable (clk_id);if (ret) pr_warn_once("%s() clock enable failed for %s, ret = %d\n",
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 322/530 drm: xlnx: zynqmp: fix a memset in zynqmp_dp_train()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 5842ab76bbfadb37eaea91e53c1efe34ae504e4a ]
The dp->train_set[] for this driver is only two characters, not four so this memsets too much. Fortunately, this ends up corrupting a struct hole and not anything important.
--- drivers/gpu/drm/xlnx/zynqmp_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/xlnx/zynqmp_dp.c +1 -1
@@ -866,7 +866,7 @@ static int zynqmp_dp_train(struct zynqmp_dp *dp)return ret;zynqmp_dp_write (dp,ZYNQMP_DP_SCRAMBLING_DISABLE ,1 ); -memset (dp->train_set,0 ,4 ); +memset (dp->train_set,0 ,sizeof (dp->train_set)); ret =zynqmp_dp_link_train_cr (dp);if (ret)return ret;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 323/530 clk: qcom: a53-pll: Add missing MODULE_DEVICE_TABLE
In reply to Greg Kroah-HartmanFrom: Chen Hui <[email protected]>
[ Upstream commit 790b516ada10a4dcc0f0a56dc0ced475d86d5820 ]
CONFIG_QCOM_A53PLL is tristate option and therefore this driver can be compiled as a module. This patch adds missing MODULE_DEVICE_TABLE definition which generates correct modalias for automatic loading of this driver when it is built as an external module.
--- drivers/clk/qcom/a53-pll.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/qcom/a53-pll.c +1 -0
@@ -93,6 +93,7 @@ static const struct of_device_id qcom_a53pll_match_table[] = { { .compatible = "qcom,msm8916-a53pll" }, { } }; +MODULE_DEVICE_TABLE (of, qcom_a53pll_match_table);static struct platform_driver qcom_a53pll_driver = { .probe = qcom_a53pll_probe,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 324/530 clk: qcom: apss-ipq-pll: Add missing MODULE_DEVICE_TABLE
In reply to Greg Kroah-HartmanFrom: Chen Hui <[email protected]>
[ Upstream commit d0a859edda46b45baeab9687d173102300d76e2b ]
CONFIG_IPQ_APSS_PLL is tristate option and therefore this driver can be compiled as a module. This patch adds missing MODULE_DEVICE_TABLE definition which generates correct modalias for automatic loading of this driver when it is built as an external module.
--- drivers/clk/qcom/apss-ipq-pll.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/qcom/apss-ipq-pll.c +1 -0
@@ -81,6 +81,7 @@ static const struct of_device_id apss_ipq_pll_match_table[] = { { .compatible = "qcom,ipq6018-a53pll" }, { } }; +MODULE_DEVICE_TABLE (of, apss_ipq_pll_match_table);static struct platform_driver apss_ipq_pll_driver = { .probe = apss_ipq_pll_probe,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 325/530 drm/amd/display: use GFP_ATOMIC in dcn20_resource_construct
In reply to Greg Kroah-HartmanFrom: Nirmoy Das <[email protected]>
[ Upstream commit 3bb1105071fb974e3e3ca2f92ddfd69c81285ab6 ]
Replace GFP_KERNEL with GFP_ATOMIC as dcn20_resource_construct() can't sleep.
Partially fixes: https://bugzilla.kernel.org/show_bug.cgi?id=212311
as dcn20_resource_construct() also calls into SMU functions which does mutex_lock().
--- drivers/gpu/drm/amd/display/dc/dce/dce_abm.c | 2 +- drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | 6 ++--- .../gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c | 2 +- .../drm/amd/display/dc/dcn20/dcn20_resource.c | 26 +++++++++---------- 4 files changed, 18 insertions(+), 18 deletions(-)
drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +1 -1
@@ -283,7 +283,7 @@ struct abm *dce_abm_create(const struct dce_abm_shift *abm_shift, const struct dce_abm_mask *abm_mask) { - struct dce_abm *abm_dce = kzalloc(sizeof(*abm_dce), GFP_KERNEL); + struct dce_abm *abm_dce = kzalloc(sizeof(*abm_dce), GFP_ATOMIC);if (abm_dce ==NULL ) {BREAK_TO_DEBUGGER ();
drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +3 -3
@@ -925,7 +925,7 @@ struct dmcu *dcn10_dmcu_create(const struct dce_dmcu_shift *dmcu_shift, const struct dce_dmcu_mask *dmcu_mask) { - struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL); + struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_ATOMIC);if (dmcu_dce ==NULL ) {BREAK_TO_DEBUGGER ();
@@ -946,7 +946,7 @@ struct dmcu *dcn20_dmcu_create(const struct dce_dmcu_shift *dmcu_shift, const struct dce_dmcu_mask *dmcu_mask) { - struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL); + struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_ATOMIC);if (dmcu_dce ==NULL ) {BREAK_TO_DEBUGGER ();
@@ -967,7 +967,7 @@ struct dmcu *dcn21_dmcu_create(const struct dce_dmcu_shift *dmcu_shift, const struct dce_dmcu_mask *dmcu_mask) { - struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL); + struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_ATOMIC);if (dmcu_dce ==NULL ) {BREAK_TO_DEBUGGER ();
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c +1 -1
@@ -112,7 +112,7 @@ struct dccg *dccg2_create(const struct dccg_shift *dccg_shift, const struct dccg_mask *dccg_mask) { - struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); + struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_ATOMIC);struct dccg *base;if (dccg_dcn ==NULL ) {
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +13 -13
@@ -1104,7 +1104,7 @@ struct dpp *dcn20_dpp_create( uint32_t inst) {struct dcn20_dpp *dpp = -kzalloc (sizeof (struct dcn20_dpp ),GFP_KERNEL ); +kzalloc (sizeof (struct dcn20_dpp ),GFP_ATOMIC );if (!dpp)return NULL ;
@@ -1122,7 +1122,7 @@ struct input_pixel_processor *dcn20_ipp_create( struct dc_context *ctx, uint32_t inst) {struct dcn10_ipp *ipp = -kzalloc (sizeof (struct dcn10_ipp ),GFP_KERNEL ); +kzalloc (sizeof (struct dcn10_ipp ),GFP_ATOMIC );if (!ipp) {BREAK_TO_DEBUGGER ();
@@ -1139,7 +1139,7 @@ struct output_pixel_processor *dcn20_opp_create( struct dc_context *ctx, uint32_t inst) {struct dcn20_opp *opp = -kzalloc (sizeof (struct dcn20_opp ),GFP_KERNEL ); +kzalloc (sizeof (struct dcn20_opp ),GFP_ATOMIC );if (!opp) {BREAK_TO_DEBUGGER ();
@@ -1156,7 +1156,7 @@ struct dce_aux *dcn20_aux_engine_create( uint32_t inst) {struct aux_engine_dce110 *aux_engine = -kzalloc (sizeof (struct aux_engine_dce110 ),GFP_KERNEL ); +kzalloc (sizeof (struct aux_engine_dce110 ),GFP_ATOMIC );if (!aux_engine)return NULL ;
@@ -1194,7 +1194,7 @@ struct dce_i2c_hw *dcn20_i2c_hw_create( uint32_t inst) {struct dce_i2c_hw *dce_i2c_hw = -kzalloc (sizeof (struct dce_i2c_hw ),GFP_KERNEL ); +kzalloc (sizeof (struct dce_i2c_hw ),GFP_ATOMIC );if (!dce_i2c_hw)return NULL ;
@@ -1207,7 +1207,7 @@ struct dce_i2c_hw *dcn20_i2c_hw_create(struct mpc *dcn20_mpc_create (struct dc_context *ctx) {struct dcn20_mpc *mpc20 =kzalloc (sizeof (struct dcn20_mpc ), -GFP_KERNEL ); +GFP_ATOMIC );if (!mpc20)return NULL ;
@@ -1225,7 +1225,7 @@ struct hubbub *dcn20_hubbub_create(struct dc_context *ctx) {int i;struct dcn20_hubbub *hubbub =kzalloc (sizeof (struct dcn20_hubbub ), -GFP_KERNEL ); +GFP_ATOMIC );if (!hubbub)return NULL ;
@@ -1253,7 +1253,7 @@ struct timing_generator *dcn20_timing_generator_create( uint32_t instance) {struct optc *tgn10 = -kzalloc (sizeof (struct optc ),GFP_KERNEL ); +kzalloc (sizeof (struct optc ),GFP_ATOMIC );if (!tgn10)return NULL ;
@@ -1332,7 +1332,7 @@ static struct clock_source *dcn20_clock_source_create( bool dp_clk_src) {struct dce110_clk_src *clk_src = -kzalloc (sizeof (struct dce110_clk_src ),GFP_KERNEL ); +kzalloc (sizeof (struct dce110_clk_src ),GFP_ATOMIC );if (!clk_src)return NULL ;
@@ -1438,7 +1438,7 @@ struct display_stream_compressor *dcn20_dsc_create( struct dc_context *ctx, uint32_t inst) {struct dcn20_dsc *dsc = -kzalloc (sizeof (struct dcn20_dsc ),GFP_KERNEL ); +kzalloc (sizeof (struct dcn20_dsc ),GFP_ATOMIC );if (!dsc) {BREAK_TO_DEBUGGER ();
@@ -1572,7 +1572,7 @@ struct hubp *dcn20_hubp_create( uint32_t inst) {struct dcn20_hubp *hubp2 = -kzalloc (sizeof (struct dcn20_hubp ),GFP_KERNEL ); +kzalloc (sizeof (struct dcn20_hubp ),GFP_ATOMIC );if (!hubp2)return NULL ;
@@ -3391,7 +3391,7 @@ bool dcn20_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool)static struct pp_smu_funcs *dcn20_pp_smu_create (struct dc_context *ctx) { -struct pp_smu_funcs *pp_smu =kzalloc (sizeof (*pp_smu),GFP_KERNEL ); +struct pp_smu_funcs *pp_smu =kzalloc (sizeof (*pp_smu),GFP_ATOMIC );if (!pp_smu)return pp_smu;
@@ -4142,7 +4142,7 @@ struct resource_pool *dcn20_create_resource_pool( struct dc *dc) {struct dcn20_resource_pool *pool = -kzalloc (sizeof (struct dcn20_resource_pool ),GFP_KERNEL ); +kzalloc (sizeof (struct dcn20_resource_pool ),GFP_ATOMIC );if (!pool)return NULL ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 326/530 drm/radeon: Fix a missing check bug in radeon_dp_mst_detect()
In reply to Greg Kroah-HartmanFrom: Yingjie Wang <[email protected]>
[ Upstream commit 25315ebfaefcffd126a266116b37bb8a3d1c4620 ]
In radeon_dp_mst_detect(), We should check whether or not @connector has been unregistered from userspace. If the connector is unregistered, we should return disconnected status.
--- drivers/gpu/drm/radeon/radeon_dp_mst.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/radeon/radeon_dp_mst.c +3 -0
@@ -242,6 +242,9 @@ radeon_dp_mst_detect(struct drm_connector *connector,to_radeon_connector (connector);struct radeon_connector *master = radeon_connector->mst_port; +if (drm_connector_is_unregistered (connector)) +return connector_status_disconnected; +return drm_dp_mst_detect_port (connector, ctx, &master->mst_mgr, radeon_connector->port); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 327/530 clk: uniphier: Fix potential infinite loop
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit f6b1340dc751a6caa2a0567b667d0f4f4172cd58 ]
The for-loop iterates with a u8 loop counter i and compares this with the loop upper limit of num_parents that is an int type. There is a potential infinite loop if num_parents is larger than the u8 loop counter. Fix this by making the loop counter the same type as num_parents. Also make num_parents an unsigned int to match the return type of the call to clk_hw_get_num_parents.
Addresses-Coverity: ("Infinite loop")
--- drivers/clk/uniphier/clk-uniphier-mux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/uniphier/clk-uniphier-mux.c +2 -2
@@ -31,10 +31,10 @@ static int uniphier_clk_mux_set_parent(struct clk_hw *hw, u8 index)static u8 uniphier_clk_mux_get_parent (struct clk_hw *hw) {struct uniphier_clk_mux *mux =to_uniphier_clk_mux (hw); -int num_parents =clk_hw_get_num_parents (hw); +unsigned int num_parents =clk_hw_get_num_parents (hw);int ret;unsigned int val; -u8 i; +unsigned int i; ret =regmap_read (mux->regmap, mux->reg, &val);if (ret)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 328/530 scsi: pm80xx: Increase timeout for pm80xx mpi_uninit_check()
In reply to Greg Kroah-HartmanFrom: Igor Pylypiv <[email protected]>
[ Upstream commit 3f744a14f331f56703a9d74e86520db045f11831 ]
The mpi_uninit_check() takes longer for inbound doorbell register to be cleared. Increase the timeout substantially so that the driver does not fail to load.
Previously, the inbound doorbell wait time was mistakenly increased in the mpi_init_check() instead of mpi_uninit_check(). It is okay to leave the mpi_init_check() wait time as-is as these are timeout values and if there is a failure, waiting longer is not an issue.
--- drivers/scsi/pm8001/pm80xx_hwi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/scsi/pm8001/pm80xx_hwi.c +2 -2
@@ -1488,9 +1488,9 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha)/* wait until Inbound DoorBell Clear Register toggled */ if (IS_SPCV_12G (pm8001_ha->pdev)) { - max_wait_count =4 *1000 *1000 ;/* 4 sec */ + max_wait_count =30 *1000 *1000 ;/* 30 sec */ }else { - max_wait_count =2 *1000 *1000 ;/* 2 sec */ + max_wait_count =15 *1000 *1000 ;/* 15 sec */ } do { udelay(1);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 329/530 scsi: pm80xx: Fix potential infinite loop
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 40fa7394a1ad5706e795823276f2e394cca145d0 ]
The for-loop iterates with a u8 loop counter i and compares this with the loop upper limit of pm8001_ha->max_q_num which is a u32 type. There is a potential infinite loop if pm8001_ha->max_q_num is larger than the u8 loop counter. Fix this by making the loop counter the same type as pm8001_ha->max_q_num.
[mkp: this is purely theoretical, max_q_num is currently limited to 64]
Addresses-Coverity: ("Infinite loop")
--- drivers/scsi/pm8001/pm8001_hwi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/pm8001/pm8001_hwi.c +1 -1
@@ -643,7 +643,7 @@ static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)*/ static int pm8001_chip_init (struct pm8001_hba_info *pm8001_ha) { -u8 i =0 ; +u32 i =0 ;u16 deviceid;pci_read_config_word (pm8001_ha->pdev,PCI_DEVICE_ID , &deviceid);/* 8081 controllers need BAR shift to access MPI space
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 330/530 scsi: ufs: ufshcd-pltfrm: Fix deferred probing
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit 339c9b63cc7ce779ce45c675bf709cb58b807fc3 ]
The driver overrides the error codes returned by platform_get_irq() to -ENODEV, so if it returns -EPROBE_DEFER, the driver would fail the probe permanently instead of the deferred probing. Propagate the error code upstream as it should have been done from the start...
--- drivers/scsi/ufs/ufshcd-pltfrm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/ufs/ufshcd-pltfrm.c +1 -1
@@ -377,7 +377,7 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, irq =platform_get_irq (pdev,0 );if (irq <0 ) { - err = -ENODEV ; + err = irq; goto out; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 331/530 scsi: hisi_sas: Fix IRQ checks
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit 6c11dc060427e07ca144eacaccd696106b361b06 ]
Commit df2d8213d9e3 ("hisi_sas: use platform_get_irq()") failed to take into account that irq_of_parse_and_map() and platform_get_irq() have a different way of indicating an error: the former returns 0 and the latter returns a negative error code. Fix up the IRQ checks!
--- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +3 -3
@@ -1644,7 +1644,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx = i *HISI_SAS_PHY_INT_NR ;for (j =0 ; j <HISI_SAS_PHY_INT_NR ; j++, idx++) { irq =platform_get_irq (pdev, idx); -if (!irq) { +if (irq <0 ) {dev_err (dev,"irq init: fail map phy interrupt %d\n" , idx);return -ENOENT ;
@@ -1663,7 +1663,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx = hisi_hba->n_phy *HISI_SAS_PHY_INT_NR ;for (i =0 ; i < hisi_hba->queue_count; i++, idx++) { irq =platform_get_irq (pdev, idx); -if (!irq) { +if (irq <0 ) {dev_err (dev,"irq init: could not map cq interrupt %d\n" , idx);return -ENOENT ;
@@ -1681,7 +1681,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx = (hisi_hba->n_phy *HISI_SAS_PHY_INT_NR ) + hisi_hba->queue_count;for (i =0 ; i <HISI_SAS_FATAL_INT_NR ; i++, idx++) { irq =platform_get_irq (pdev, idx); -if (!irq) { +if (irq <0 ) {dev_err (dev,"irq init: could not map fatal interrupt %d\n" , idx);return -ENOENT ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 332/530 scsi: jazz_esp: Add IRQ check
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit 38fca15c29db6ed06e894ac194502633e2a7d1fb ]
The driver neglects to check the result of platform_get_irq()'s call and blithely passes the negative error codes to request_irq() (which takes *unsigned* IRQ #), causing it to fail with -EINVAL, overriding the real error code. Stop calling request_irq() with the invalid IRQ #s.
--- drivers/scsi/jazz_esp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/scsi/jazz_esp.c +3 -1
@@ -143,7 +143,9 @@ static int esp_jazz_probe(struct platform_device *dev)if (!esp->command_block) goto fail_unmap_regs; - host->irq =platform_get_irq (dev,0 ); + host->irq = err =platform_get_irq (dev,0 ); +if (err <0 ) + goto fail_unmap_command_block; err =request_irq (host->irq, scsi_esp_intr,IRQF_SHARED ,"ESP" , esp);if (err <0 ) goto fail_unmap_command_block;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 333/530 scsi: sun3x_esp: Add IRQ check
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit 14b321380eb333c82853d7d612d0995f05f88fdc ]
The driver neglects to check the result of platform_get_irq()'s call and blithely passes the negative error codes to request_irq() (which takes *unsigned* IRQ #), causing it to fail with -EINVAL, overriding the real error code. Stop calling request_irq() with the invalid IRQ #s.
--- drivers/scsi/sun3x_esp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/scsi/sun3x_esp.c +3 -1
@@ -206,7 +206,9 @@ static int esp_sun3x_probe(struct platform_device *dev)if (!esp->command_block) goto fail_unmap_regs_dma; - host->irq =platform_get_irq (dev,0 ); + host->irq = err =platform_get_irq (dev,0 ); +if (err <0 ) + goto fail_unmap_command_block; err =request_irq (host->irq, scsi_esp_intr,IRQF_SHARED ,"SUN3X ESP" , esp);if (err <0 )
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 334/530 scsi: sni_53c710: Add IRQ check
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit 1160d61bc51e87e509cfaf9da50a0060f67b6de4 ]
The driver neglects to check the result of platform_get_irq()'s call and blithely passes the negative error codes to request_irq() (which takes *unsigned* IRQ #s), causing it to fail with -EINVAL (overridden by -ENODEV further below). Stop calling request_irq() with the invalid IRQ #s.
--- drivers/scsi/sni_53c710.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/scsi/sni_53c710.c +4 -1
@@ -58,6 +58,7 @@ static int snirm710_probe(struct platform_device *dev)struct NCR_700_Host_Parameters *hostdata;struct Scsi_Host *host;struct resource *res; +int rc; res =platform_get_resource (dev,IORESOURCE_MEM ,0 );if (!res)
@@ -83,7 +84,9 @@ static int snirm710_probe(struct platform_device *dev) goto out_kfree; host->this_id =7 ; host->base = base; - host->irq =platform_get_irq (dev,0 ); + host->irq = rc =platform_get_irq (dev,0 ); +if (rc <0 ) + goto out_put_host;if (request_irq (host->irq, NCR_700_intr,IRQF_SHARED ,"snirm710" , host)) {printk (KERN_ERR "snirm710: request_irq failed!\n" ); goto out_put_host;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 335/530 scsi: ibmvfc: Fix invalid state machine BUG_ON()
In reply to Greg Kroah-HartmanFrom: Brian King <[email protected]>
[ Upstream commit 15cfef8623a449d40d16541687afd58e78033be3 ]
This fixes an issue hitting the BUG_ON() in ibmvfc_do_work(). When going through a host action of IBMVFC_HOST_ACTION_RESET, we change the action to IBMVFC_HOST_ACTION_TGT_DEL, then drop the host lock, and reset the CRQ, which changes the host state to IBMVFC_NO_CRQ. If, prior to setting the host state to IBMVFC_NO_CRQ, ibmvfc_init_host() is called, it can then end up changing the host action to IBMVFC_HOST_ACTION_INIT. If we then change the host state to IBMVFC_NO_CRQ, we will then hit the BUG_ON().
Make a couple of changes to avoid this. Leave the host action to be IBMVFC_HOST_ACTION_RESET or IBMVFC_HOST_ACTION_REENABLE until after we drop the host lock and reset or reenable the CRQ. Also harden the host state machine to ensure we cannot leave the reset / reenable state until we've finished processing the reset or reenable.
--- drivers/scsi/ibmvscsi/ibmvfc.c | 57 ++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 19 deletions(-)
drivers/scsi/ibmvscsi/ibmvfc.c +38 -19
@@ -532,8 +532,17 @@ static void ibmvfc_set_host_action(struct ibmvfc_host *vhost,if (vhost->action ==IBMVFC_HOST_ACTION_ALLOC_TGTS ) vhost->action = action;break ; +case IBMVFC_HOST_ACTION_REENABLE : +case IBMVFC_HOST_ACTION_RESET : + vhost->action = action; +break ;case IBMVFC_HOST_ACTION_INIT :case IBMVFC_HOST_ACTION_TGT_DEL : +case IBMVFC_HOST_ACTION_LOGO : +case IBMVFC_HOST_ACTION_QUERY_TGTS : +case IBMVFC_HOST_ACTION_TGT_DEL_FAILED : +case IBMVFC_HOST_ACTION_NONE : +default :switch (vhost->action) {case IBMVFC_HOST_ACTION_RESET :case IBMVFC_HOST_ACTION_REENABLE :
@@ -543,15 +552,6 @@ static void ibmvfc_set_host_action(struct ibmvfc_host *vhost,break ; }break ; -case IBMVFC_HOST_ACTION_LOGO : -case IBMVFC_HOST_ACTION_QUERY_TGTS : -case IBMVFC_HOST_ACTION_TGT_DEL_FAILED : -case IBMVFC_HOST_ACTION_NONE : -case IBMVFC_HOST_ACTION_RESET : -case IBMVFC_HOST_ACTION_REENABLE : -default : - vhost->action = action; -break ; } }
@@ -4658,26 +4658,45 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)case IBMVFC_HOST_ACTION_INIT_WAIT :break ;case IBMVFC_HOST_ACTION_RESET : - vhost->action =IBMVFC_HOST_ACTION_TGT_DEL ;spin_unlock_irqrestore (vhost->host->host_lock, flags); rc =ibmvfc_reset_crq (vhost); +spin_lock_irqsave (vhost->host->host_lock, flags); -if (rc ==H_CLOSED ) +if (!rc || rc ==H_CLOSED )vio_enable_interrupts (to_vio_dev (vhost->dev)); -if (rc || (rc =ibmvfc_send_crq_init (vhost)) || - (rc =vio_enable_interrupts (to_vio_dev (vhost->dev)))) { -ibmvfc_link_down (vhost,IBMVFC_LINK_DEAD ); -dev_err (vhost->dev,"Error after reset (rc=%d)\n" , rc); +if (vhost->action ==IBMVFC_HOST_ACTION_RESET ) { +/* +* The only action we could have changed to would have +* been reenable, in which case, we skip the rest of +* this path and wait until we've done the re-enable +* before sending the crq init. +*/ + vhost->action =IBMVFC_HOST_ACTION_TGT_DEL ; + +if (rc || (rc =ibmvfc_send_crq_init (vhost)) || + (rc =vio_enable_interrupts (to_vio_dev (vhost->dev)))) { +ibmvfc_link_down (vhost,IBMVFC_LINK_DEAD ); +dev_err (vhost->dev,"Error after reset (rc=%d)\n" , rc); + } }break ;case IBMVFC_HOST_ACTION_REENABLE : - vhost->action =IBMVFC_HOST_ACTION_TGT_DEL ;spin_unlock_irqrestore (vhost->host->host_lock, flags); rc =ibmvfc_reenable_crq_queue (vhost); +spin_lock_irqsave (vhost->host->host_lock, flags); -if (rc || (rc =ibmvfc_send_crq_init (vhost))) { -ibmvfc_link_down (vhost,IBMVFC_LINK_DEAD ); -dev_err (vhost->dev,"Error after enable (rc=%d)\n" , rc); +if (vhost->action ==IBMVFC_HOST_ACTION_REENABLE ) { +/* +* The only action we could have changed to would have +* been reset, in which case, we skip the rest of this +* path and wait until we've done the reset before +* sending the crq init. +*/ + vhost->action =IBMVFC_HOST_ACTION_TGT_DEL ; +if (rc || (rc =ibmvfc_send_crq_init (vhost))) { +ibmvfc_link_down (vhost,IBMVFC_LINK_DEAD ); +dev_err (vhost->dev,"Error after enable (rc=%d)\n" , rc); + } }break ;case IBMVFC_HOST_ACTION_LOGO :
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 336/530 mailbox: sprd: Introduce refcnt when clients requests/free channels
In reply to Greg Kroah-HartmanFrom: Orson Zhai <[email protected]>
[ Upstream commit 9468ab84032f96496e998cfa173cd1d0ac316bcd ]
Unisoc mailbox has no way to be enabled/disabled for any single channel. They can only be set to startup or shutdown as a whole device at same time.
Add a variable to count references to avoid mailbox FIFO being reset unexpectedly when clients are requesting or freeing channels.
Also add a lock to dismiss possible conflicts from register r/w in different startup or shutdown threads. And fix the crash problem when early interrupts come from channel which has not been requested by client yet.
--- drivers/mailbox/sprd-mailbox.c | 43 +++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 14 deletions(-)
drivers/mailbox/sprd-mailbox.c +29 -14
@@ -60,6 +60,8 @@ struct sprd_mbox_priv {struct clk *clk;u32 outbox_fifo_depth; +struct mutex lock; +u32 refcnt;struct mbox_chan chan[SPRD_MBOX_CHAN_MAX ]; };
@@ -115,7 +117,11 @@ static irqreturn_t sprd_mbox_outbox_isr(int irq, void *data) id =readl (priv->outbox_base +SPRD_MBOX_ID ); chan = &priv->chan[id]; -mbox_chan_received_data (chan, (void *)msg); +if (chan->cl) +mbox_chan_received_data (chan, (void *)msg); +else +dev_warn_ratelimited (priv->dev, +"message's been dropped at ch[%d]\n" , id);/* Trigger to update outbox FIFO pointer */ writel (0x1 , priv->outbox_base +SPRD_MBOX_TRIGGER );
@@ -215,18 +221,22 @@ static int sprd_mbox_startup(struct mbox_chan *chan)struct sprd_mbox_priv *priv =to_sprd_mbox_priv (chan->mbox);u32 val; -/* Select outbox FIFO mode and reset the outbox FIFO status */ -writel (0x0 , priv->outbox_base +SPRD_MBOX_FIFO_RST ); +mutex_lock (&priv->lock); +if (priv->refcnt++ ==0 ) { +/* Select outbox FIFO mode and reset the outbox FIFO status */ +writel (0x0 , priv->outbox_base +SPRD_MBOX_FIFO_RST ); -/* Enable inbox FIFO overflow and delivery interrupt */ - val =readl (priv->inbox_base +SPRD_MBOX_IRQ_MSK ); - val &= ~(SPRD_INBOX_FIFO_OVERFLOW_IRQ |SPRD_INBOX_FIFO_DELIVER_IRQ ); -writel (val, priv->inbox_base +SPRD_MBOX_IRQ_MSK ); +/* Enable inbox FIFO overflow and delivery interrupt */ + val =readl (priv->inbox_base +SPRD_MBOX_IRQ_MSK ); + val &= ~(SPRD_INBOX_FIFO_OVERFLOW_IRQ |SPRD_INBOX_FIFO_DELIVER_IRQ ); +writel (val, priv->inbox_base +SPRD_MBOX_IRQ_MSK ); -/* Enable outbox FIFO not empty interrupt */ - val =readl (priv->outbox_base +SPRD_MBOX_IRQ_MSK ); - val &= ~SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ ; -writel (val, priv->outbox_base +SPRD_MBOX_IRQ_MSK ); +/* Enable outbox FIFO not empty interrupt */ + val =readl (priv->outbox_base +SPRD_MBOX_IRQ_MSK ); + val &= ~SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ ; +writel (val, priv->outbox_base +SPRD_MBOX_IRQ_MSK ); + } +mutex_unlock (&priv->lock);return 0 ; }
@@ -235,9 +245,13 @@ static void sprd_mbox_shutdown(struct mbox_chan *chan) {struct sprd_mbox_priv *priv =to_sprd_mbox_priv (chan->mbox); -/* Disable inbox & outbox interrupt */ -writel (SPRD_INBOX_FIFO_IRQ_MASK , priv->inbox_base +SPRD_MBOX_IRQ_MSK ); -writel (SPRD_OUTBOX_FIFO_IRQ_MASK , priv->outbox_base +SPRD_MBOX_IRQ_MSK ); +mutex_lock (&priv->lock); +if (--priv->refcnt ==0 ) { +/* Disable inbox & outbox interrupt */ +writel (SPRD_INBOX_FIFO_IRQ_MASK , priv->inbox_base +SPRD_MBOX_IRQ_MSK ); +writel (SPRD_OUTBOX_FIFO_IRQ_MASK , priv->outbox_base +SPRD_MBOX_IRQ_MSK ); + } +mutex_unlock (&priv->lock); }static const struct mbox_chan_ops sprd_mbox_ops = {
@@ -266,6 +280,7 @@ static int sprd_mbox_probe(struct platform_device *pdev)return -ENOMEM ; priv->dev = dev; +mutex_init (&priv->lock);/* * The Spreadtrum mailbox uses an inbox to send messages to the target
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 337/530 mfd: stm32-timers: Avoid clearing auto reload register
In reply to Greg Kroah-HartmanFrom: Fabrice Gasnier <[email protected]>
[ Upstream commit 4917e498c6894ba077867aff78f82cffd5ffbb5c ]
The ARR register is cleared unconditionally upon probing, after the maximum value has been read. This initial condition is rather not intuitive, when considering the counter child driver. It rather expects the maximum value by default:
- The counter interface shows a zero value by default for 'ceiling' attribute.
- Enabling the counter without any prior configuration makes it doesn't count.
The reset value of ARR register is the maximum. So Choice here is to backup it, and restore it then, instead of clearing its value. It also fixes the initial condition seen by the counter driver.
--- drivers/mfd/stm32-timers.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/mfd/stm32-timers.c +6 -1
@@ -158,13 +158,18 @@ static const struct regmap_config stm32_timers_regmap_cfg = {static void stm32_timers_get_arr_size (struct stm32_timers *ddata) { +u32 arr; + +/* Backup ARR to restore it after getting the maximum value */ +regmap_read (ddata->regmap,TIM_ARR , &arr); +/* * Only the available bits will be written so when readback * we get the maximum value of auto reload register */ regmap_write (ddata->regmap,TIM_ARR , ~0L );regmap_read (ddata->regmap,TIM_ARR , &ddata->max_arr); -regmap_write (ddata->regmap,TIM_ARR ,0x0 ); +regmap_write (ddata->regmap,TIM_ARR , arr); } static int stm32_timers_dma_probe(struct device *dev,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 338/530 nvmet-tcp: fix a segmentation fault during io parsing error
In reply to Greg Kroah-HartmanFrom: Elad Grupi <[email protected]>
[ Upstream commit bdaf13279192c60b2b1fc99badef53b494fec055 ]
In case there is an io that contains inline data and it goes to parsing error flow, command response will free command and iov before clearing the data on the socket buffer.
This will delay the command response until receive flow is completed.
--- drivers/nvme/target/tcp.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-)
drivers/nvme/target/tcp.c +31 -8
@@ -525,11 +525,36 @@ static void nvmet_tcp_queue_response(struct nvmet_req *req)struct nvmet_tcp_cmd *cmd = container_of(req, struct nvmet_tcp_cmd, req);struct nvmet_tcp_queue *queue = cmd->queue; +struct nvme_sgl_desc *sgl; +u32 len; + +if (unlikely (cmd == queue->cmd)) { + sgl = &cmd->req.cmd->common.dptr.sgl; + len =le32_to_cpu (sgl->length); + +/* +* Wait for inline data before processing the response. +* Avoid using helpers, this might happen before +* nvmet_req_init is completed. +*/ +if (queue->rcv_state ==NVMET_TCP_RECV_PDU && + len && len < cmd->req.port->inline_data_size && +nvme_is_write (cmd->req.cmd)) +return ; + }llist_add (&cmd->lentry, &queue->resp_list);queue_work_on (queue_cpu (queue), nvmet_tcp_wq, &cmd->queue->io_work); } +static void nvmet_tcp_execute_request (struct nvmet_tcp_cmd *cmd) +{ +if (unlikely (cmd->flags &NVMET_TCP_F_INIT_FAILED )) +nvmet_tcp_queue_response (&cmd->req); +else + cmd->req.execute (&cmd->req); +} +static int nvmet_try_send_data_pdu (struct nvmet_tcp_cmd *cmd) {u8 hdgst =nvmet_tcp_hdgst_len (cmd->queue);
@@ -961,7 +986,7 @@ static int nvmet_tcp_done_recv_pdu(struct nvmet_tcp_queue *queue) le32_to_cpu(req->cmd->common.dptr.sgl.length));nvmet_tcp_handle_req_failure (queue, queue->cmd, req); -return -EAGAIN ; +return 0 ; } ret =nvmet_tcp_map_data (queue->cmd);
@@ -1104,10 +1129,8 @@ static int nvmet_tcp_try_recv_data(struct nvmet_tcp_queue *queue)return 0 ; } -if (!(cmd->flags &NVMET_TCP_F_INIT_FAILED ) && - cmd->rbytes_done == cmd->req.transfer_len) { - cmd->req.execute (&cmd->req); - } +if (cmd->rbytes_done == cmd->req.transfer_len) +nvmet_tcp_execute_request (cmd);nvmet_prepare_receive_pdu (queue);return 0 ;
@@ -1144,9 +1167,9 @@ static int nvmet_tcp_try_recv_ddgst(struct nvmet_tcp_queue *queue) goto out; } -if (!(cmd->flags &NVMET_TCP_F_INIT_FAILED ) && - cmd->rbytes_done == cmd->req.transfer_len) - cmd->req.execute (&cmd->req); +if (cmd->rbytes_done == cmd->req.transfer_len) +nvmet_tcp_execute_request (cmd); + ret =0 ; out:nvmet_prepare_receive_pdu (queue);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 339/530 nvme-pci: dont simple map sgl when sgls are disabled
In reply to Greg Kroah-HartmanFrom: Niklas Cassel <[email protected]>
[ Upstream commit e51183be1fa96dc6d3cd11b3c25a0f595807315e ]
According to the module parameter description for sgl_threshold, a value of 0 means that SGLs are disabled.
If SGLs are disabled, we should respect that, even for the case where the request is made up of a single physical segment.
--- drivers/nvme/host/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nvme/host/pci.c +1 -1
@@ -852,7 +852,7 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req,return nvme_setup_prp_simple (dev, req, &cmnd->rw, &bv); -if (iod->nvmeq->qid && +if (iod->nvmeq->qid && sgl_threshold && dev->ctrl.sgls & ((1 <<0 ) | (1 <<1 )))return nvme_setup_sgl_simple (dev, req, &cmnd->rw, &bv);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 340/530 media: cedrus: Fix H265 status definitions
In reply to Greg Kroah-HartmanFrom: Jernej Skrabec <[email protected]>
[ Upstream commit 147d211cc9b4d753148d1640a1758b25edfbf437 ]
Some of the H265 status flags are wrong. Redefine them to corespond to Allwinner CedarC open source userspace library. Only one of these flags is actually used and new value also matches value used in libvdpau-sunxi library, which is proven to be working.
Note that wrong (old) value in right circumstances (in combination with another H265 decoding bug) causes driver lock up. With this fix decoding is still broken (green output) but at least driver doesn't lock up.
--- .../staging/media/sunxi/cedrus/cedrus_regs.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
drivers/staging/media/sunxi/cedrus/cedrus_regs.h +9 -8
@@ -443,16 +443,17 @@#define VE_DEC_H265_STATUS_STCD_BUSY BIT(21)#define VE_DEC_H265_STATUS_WB_BUSY BIT(20)#define VE_DEC_H265_STATUS_BS_DMA_BUSY BIT(19) -#define VE_DEC_H265_STATUS_IQIT_BUSY BIT(18) +#define VE_DEC_H265_STATUS_IT_BUSY BIT(18)#define VE_DEC_H265_STATUS_INTER_BUSY BIT(17)#define VE_DEC_H265_STATUS_MORE_DATA BIT(16) -#define VE_DEC_H265_STATUS_VLD_BUSY BIT(14) -#define VE_DEC_H265_STATUS_DEBLOCKING_BUSY BIT(13) -#define VE_DEC_H265_STATUS_DEBLOCKING_DRAM_BUSY BIT(12) -#define VE_DEC_H265_STATUS_INTRA_BUSY BIT(11) -#define VE_DEC_H265_STATUS_SAO_BUSY BIT(10) -#define VE_DEC_H265_STATUS_MVP_BUSY BIT(9) -#define VE_DEC_H265_STATUS_SWDEC_BUSY BIT(8) +#define VE_DEC_H265_STATUS_DBLK_BUSY BIT(15) +#define VE_DEC_H265_STATUS_IREC_BUSY BIT(14) +#define VE_DEC_H265_STATUS_INTRA_BUSY BIT(13) +#define VE_DEC_H265_STATUS_MCRI_BUSY BIT(12) +#define VE_DEC_H265_STATUS_IQIT_BUSY BIT(11) +#define VE_DEC_H265_STATUS_MVP_BUSY BIT(10) +#define VE_DEC_H265_STATUS_IS_BUSY BIT(9) +#define VE_DEC_H265_STATUS_VLD_BUSY BIT(8)#define VE_DEC_H265_STATUS_OVER_TIME BIT(3)#define VE_DEC_H265_STATUS_VLD_DATA_REQ BIT(2)#define VE_DEC_H265_STATUS_ERROR BIT(1)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 341/530 HSI: core: fix resource leaks in hsi_add_client_from_dt()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 5c08b0f75575648032f309a6f58294453423ed93 ]
If some of the allocations fail between the dev_set_name() and the device_register() then the name will not be freed. Fix this by moving dev_set_name() directly in front of the call to device_register().
--- drivers/hsi/hsi_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/hsi/hsi_core.c +1 -2
@@ -210,8 +210,6 @@ static void hsi_add_client_from_dt(struct hsi_port *port,if (err) goto err; -dev_set_name (&cl->device,"%s" , name); - err =hsi_of_property_parse_mode (client,"hsi-mode" , &mode);if (err) { err = hsi_of_property_parse_mode(client, "hsi-rx-mode",
@@ -293,6 +291,7 @@ static void hsi_add_client_from_dt(struct hsi_port *port, cl->device.release = hsi_client_release; cl->device.of_node = client; +dev_set_name (&cl->device,"%s" , name);if (device_register (&cl->device) <0 ) {pr_err ("hsi: failed to register client: %s\n" , name);put_device (&cl->device);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 342/530 x86/events/amd/iommu: Fix sysfs type mismatch
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit de5bc7b425d4c27ae5faa00ea7eb6b9780b9a355 ]
dev_attr_show() calls _iommu_event_show() via an indirect call but _iommu_event_show()'s type does not currently match the type of the show() member in 'struct device_attribute', resulting in a Control Flow Integrity violation.
$ cat /sys/devices/amd_iommu_1/events/mem_dte_hit csource=0x0a
$ dmesg | grep "CFI failure" [ 3526.735140] CFI failure (target: _iommu_event_show...):
Change _iommu_event_show() and 'struct amd_iommu_event_desc' to 'struct device_attribute' so that there is no more CFI violation.
--- arch/x86/events/amd/iommu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/events/amd/iommu.c +3 -3
@@ -81,12 +81,12 @@ static struct attribute_group amd_iommu_events_group = { };struct amd_iommu_event_desc { -struct kobj_attribute attr; +struct device_attribute attr;const char *event; }; -static ssize_t _iommu_event_show (struct kobject *kobj, -struct kobj_attribute *attr,char *buf) +static ssize_t _iommu_event_show (struct device *dev, +struct device_attribute *attr,char *buf) {struct amd_iommu_event_desc *event = container_of(attr, struct amd_iommu_event_desc, attr);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 343/530 perf/amd/uncore: Fix sysfs type mismatch
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit 5deac80d4571dffb51f452f0027979d72259a1b9 ]
dev_attr_show() calls the __uncore_*_show() functions via an indirect call but their type does not currently match the type of the show() member in 'struct device_attribute', resulting in a Control Flow Integrity violation.
$ cat /sys/devices/amd_l3/format/umask config:8-15
$ dmesg | grep "CFI failure" [ 1258.174653] CFI failure (target: __uncore_umask_show...):
Update the type in the DEFINE_UNCORE_FORMAT_ATTR macro to match 'struct device_attribute' so that there is no more CFI violation.
--- arch/x86/events/amd/uncore.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/events/amd/uncore.c +3 -3
@@ -275,14 +275,14 @@ static struct attribute_group amd_uncore_attr_group = { };#define DEFINE_UNCORE_FORMAT_ATTR (_var, _name, _format) \ -static ssize_t __uncore_##_var##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, \ +static ssize_t __uncore_##_var##_show(struct device *dev, \ + struct device_attribute *attr, \ char *page) \ { \ BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ return sprintf(page, _format "\n"); \ } \ -static struct kobj_attribute format_attr_##_var = \ +static struct device_attribute format_attr_##_var = \ __ATTR(_name, 0444, __uncore_##_var##_show, NULL)DEFINE_UNCORE_FORMAT_ATTR (event12, event,"config:0-7,32-35" );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 344/530 io_uring: fix overflows checks in provide buffers
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
[ Upstream commit 38134ada0ceea3e848fe993263c0ff6207fd46e7 ]
Colin reported before possible overflow and sign extension problems in io_provide_buffers_prep(). As Linus pointed out previous attempt did nothing useful, see d81269fecb8ce ("io_uring: fix provide_buffers sign extension").
Do that with help of check_<op>_overflow helpers. And fix struct io_provide_buf::len type, as it doesn't make much sense to keep it signed.
--- fs/io_uring.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
fs/io_uring.c +8 -2
@@ -527,7 +527,7 @@ struct io_splice {struct io_provide_buf {struct file *file;__u64 addr; -__s32 len; +__u32 len;__u32 bgid;__u16 nbufs;__u16 bid;
@@ -3996,7 +3996,7 @@ static int io_remove_buffers(struct io_kiocb *req, bool force_nonblock,static int io_provide_buffers_prep (struct io_kiocb *req,const struct io_uring_sqe *sqe) { -unsigned long size; +unsigned long size, tmp_check;struct io_provide_buf *p = &req->pbuf;u64 tmp;
@@ -4010,6 +4010,12 @@ static int io_provide_buffers_prep(struct io_kiocb *req, p->addr =READ_ONCE (sqe->addr); p->len =READ_ONCE (sqe->len); +if (check_mul_overflow ((unsigned long )p->len, (unsigned long )p->nbufs, + &size)) +return -EOVERFLOW ; +if (check_add_overflow ((unsigned long )p->addr, size, &tmp_check)) +return -EOVERFLOW ; + size = (unsigned long )p->len * p->nbufs;if (!access_ok (u64_to_user_ptr (p->addr), size))return -EFAULT ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 345/530 sched/debug: Fix cgroup_path[] serialization
In reply to Greg Kroah-HartmanFrom: Waiman Long <[email protected]>
[ Upstream commit ad789f84c9a145f8a18744c0387cec22ec51651e ]
The handling of sysrq key can be activated by echoing the key to /proc/sysrq-trigger or via the magic key sequence typed into a terminal that is connected to the system in some way (serial, USB or other mean). In the former case, the handling is done in a user context. In the latter case, it is likely to be in an interrupt context.
Currently in print_cpu() of kernel/sched/debug.c, sched_debug_lock is taken with interrupt disabled for the whole duration of the calls to print_*_stats() and print_rq() which could last for the quite some time if the information dump happens on the serial console.
If the system has many cpus and the sched_debug_lock is somehow busy (e.g. parallel sysrq-t), the system may hit a hard lockup panic depending on the actually serial console implementation of the system.
The purpose of sched_debug_lock is to serialize the use of the global cgroup_path[] buffer in print_cpu(). The rests of the printk calls don't need serialization from sched_debug_lock.
Calling printk() with interrupt disabled can still be problematic if multiple instances are running. Allocating a stack buffer of PATH_MAX bytes is not feasible because of the limited size of the kernel stack.
The solution implemented in this patch is to allow only one caller at a time to use the full size group_path[], while other simultaneous callers will have to use shorter stack buffers with the possibility of path name truncation. A "..." suffix will be printed if truncation may have happened. The cgroup path name is provided for informational purpose only, so occasional path name truncation should not be a big problem.
--- kernel/sched/debug.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-)
kernel/sched/debug.c +29 -13
@@ -8,8 +8,6 @@*/ #include "sched.h" -static DEFINE_SPINLOCK (sched_debug_lock); -/* * This allows printing both to /proc/sched_debug and * to the console
@@ -470,16 +468,37 @@ static void print_cfs_group_stats(struct seq_file *m, int cpu, struct task_group#endif #ifdef CONFIG_CGROUP_SCHED +static DEFINE_SPINLOCK (sched_debug_lock);static char group_path[PATH_MAX ]; -static char *task_group_path (struct task_group *tg) +static void task_group_path (struct task_group *tg,char *path,int plen) { -if (autogroup_path (tg, group_path,PATH_MAX )) -return group_path; +if (autogroup_path (tg, path, plen)) +return ; -cgroup_path (tg->css.cgroup, group_path,PATH_MAX ); +cgroup_path (tg->css.cgroup, path, plen); +} -return group_path; +/* +* Only 1 SEQ_printf_task_group_path() caller can use the full length +* group_path[] for cgroup path. Other simultaneous callers will have +* to use a shorter stack buffer. A "..." suffix is appended at the end +* of the stack buffer so that it will show up in case the output length +* matches the given buffer size to indicate possible path name truncation. +*/ +#define SEQ_printf_task_group_path(m, tg, fmt...) \ +{ \ + if (spin_trylock(&sched_debug_lock)) { \ + task_group_path(tg, group_path, sizeof(group_path)); \ + SEQ_printf(m, fmt, group_path); \ + spin_unlock(&sched_debug_lock); \ + } else { \ + char buf[128]; \ + char *bufend = buf + sizeof(buf) - 3; \ + task_group_path(tg, buf, bufend - buf); \ + strcpy(bufend - 1, "..."); \ + SEQ_printf(m, fmt, buf); \ + } \ }#endif
@@ -506,7 +525,7 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)SEQ_printf (m," %d %d" ,task_node (p),task_numa_group_id (p));#endif #ifdef CONFIG_CGROUP_SCHED -SEQ_printf (m," %s" ,task_group_path (task_group (p))); + SEQ_printf_task_group_path(m, task_group(p), " %s")#endif SEQ_printf (m,"\n" );
@@ -543,7 +562,7 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)#ifdef CONFIG_FAIR_GROUP_SCHED SEQ_printf (m,"\n" ); -SEQ_printf (m,"cfs_rq[%d]:%s\n" , cpu,task_group_path (cfs_rq->tg)); +SEQ_printf_task_group_path (m, cfs_rq->tg,"cfs_rq[%d]:%s\n" , cpu);#else SEQ_printf (m,"\n" );SEQ_printf (m,"cfs_rq[%d]:\n" , cpu);
@@ -614,7 +633,7 @@ void print_rt_rq(struct seq_file *m, int cpu, struct rt_rq *rt_rq) {#ifdef CONFIG_RT_GROUP_SCHED SEQ_printf (m,"\n" ); -SEQ_printf (m,"rt_rq[%d]:%s\n" , cpu,task_group_path (rt_rq->tg)); +SEQ_printf_task_group_path (m, rt_rq->tg,"rt_rq[%d]:%s\n" , cpu);#else SEQ_printf (m,"\n" );SEQ_printf (m,"rt_rq[%d]:\n" , cpu);
@@ -666,7 +685,6 @@ void print_dl_rq(struct seq_file *m, int cpu, struct dl_rq *dl_rq)static void print_cpu (struct seq_file *m,int cpu) {struct rq *rq =cpu_rq (cpu); -unsigned long flags;#ifdef CONFIG_X86 {
@@ -717,13 +735,11 @@ do { \ }#undef P -spin_lock_irqsave (&sched_debug_lock, flags);print_cfs_stats (m, cpu);print_rt_stats (m, cpu);print_dl_stats (m, cpu);print_rq (m, rq, cpu); -spin_unlock_irqrestore (&sched_debug_lock, flags);SEQ_printf (m,"\n" ); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 346/530 drivers/block/null_blk/main: Fix a double free in null_init.
In reply to Greg Kroah-HartmanFrom: Lv Yunlong <[email protected]>
[ Upstream commit 72ce11ddfa4e9e1879103581a60b7e34547eaa0a ]
In null_init, null_add_dev(dev) is called.
In null_add_dev, it calls null_free_zoned_dev(dev) to free dev->zones via kvfree(dev->zones) in out_cleanup_zone branch and returns err. Then null_init accept the err code and then calls null_free_dev(dev).
But in null_free_dev(dev), dev->zones is freed again by null_free_zoned_dev().
My patch set dev->zones to NULL in null_free_zoned_dev() after kvfree(dev->zones) is called, to avoid the double free.
--- drivers/block/null_blk_zoned.c | 1 + 1 file changed, 1 insertion(+)
drivers/block/null_blk_zoned.c +1 -0
@@ -149,6 +149,7 @@ void null_free_zoned_dev(struct nullb_device *dev) {bitmap_free (dev->zone_locks);kvfree (dev->zones); + dev->zones =NULL ; }static inline void null_lock_zone (struct nullb_device *dev,unsigned int zno)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 347/530 xsk: Respect devices headroom and tailroom on generic xmit path
In reply to Greg Kroah-HartmanFrom: Alexander Lobakin <[email protected]>
[ Upstream commit 3914d88f7608e6c2e80e344474fa289370c32451 ]
xsk_generic_xmit() allocates a new skb and then queues it for xmitting. The size of new skb's headroom is desc->len, so it comes to the driver/device with no reserved headroom and/or tailroom. Lots of drivers need some headroom (and sometimes tailroom) to prepend (and/or append) some headers or data, e.g. CPU tags, device-specific headers/descriptors (LSO, TLS etc.), and if case of no available space skb_cow_head() will reallocate the skb. Reallocations are unwanted on fast-path, especially when it comes to XDP, so generic XSK xmit should reserve the spaces declared in dev->needed_headroom and dev->needed tailroom to avoid them.
Note on max(NET_SKB_PAD, L1_CACHE_ALIGN(dev->needed_headroom)):
Usually, output functions reserve LL_RESERVED_SPACE(dev), which consists of dev->hard_header_len + dev->needed_headroom, aligned by 16.
However, on XSK xmit hard header is already here in the chunk, so hard_header_len is not needed. But it'd still be better to align data up to cacheline, while reserving no less than driver requests for headroom. NET_SKB_PAD here is to double-insure there will be no reallocations even when the driver advertises no needed_headroom, but in fact need it (not so rare case).
--- net/xdp/xsk.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
net/xdp/xsk.c +7 -1
@@ -380,12 +380,16 @@ static int xsk_generic_xmit(struct sock *sk)struct sk_buff *skb;unsigned long flags;int err =0 ; +u32 hr, tr;mutex_lock (&xs->mutex);if (xs->queue_id >= xs->dev->real_num_tx_queues) goto out; + hr =max (NET_SKB_PAD ,L1_CACHE_ALIGN (xs->dev->needed_headroom)); + tr = xs->dev->needed_tailroom; +while (xskq_cons_peek_desc (xs->tx, &desc, xs->pool)) {char *buffer;u64 addr;
@@ -397,11 +401,13 @@ static int xsk_generic_xmit(struct sock *sk) } len = desc.len; - skb =sock_alloc_send_skb (sk, len,1 , &err); + skb =sock_alloc_send_skb (sk, hr + len + tr,1 , &err);if (unlikely (!skb)) goto out; +skb_reserve (skb, hr);skb_put (skb, len); + addr = desc.addr; buffer =xsk_buff_raw_get_data (xs->pool, addr); err =skb_store_bits (skb,0 , buffer, len);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 348/530 HID: plantronics: Workaround for double volume key presses
In reply to Greg Kroah-HartmanFrom: Maxim Mikityanskiy <[email protected]>
[ Upstream commit f567d6ef8606fb427636e824c867229ecb5aefab ]
Plantronics Blackwire 3220 Series (047f:c056) sends HID reports twice for each volume key press. This patch adds a quirk to hid-plantronics for this product ID, which will ignore the second volume key press if it happens within 5 ms from the last one that was handled.
The patch was tested on the mentioned model only, it shouldn't affect other models, however, this quirk might be needed for them too. Auto-repeat (when a key is held pressed) is not affected, because the rate is about 3 times per second, which is far less frequent than once in 5 ms.
--- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-plantronics.c | 60 +++++++++++++++++++++++++++++++++-- include/linux/hid.h | 2 ++ 3 files changed, 61 insertions(+), 2 deletions(-)
drivers/hid/hid-ids.h +1 -0
@@ -938,6 +938,7 @@#define USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S 0x8003#define USB_VENDOR_ID_PLANTRONICS 0x047f +#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056#define USB_VENDOR_ID_PANASONIC 0x04da#define USB_DEVICE_ID_PANABOARD_UBT780 0x1044
drivers/hid/hid-plantronics.c +58 -2
113 lines not on this page · raw message
include/linux/hid.h +2 -0
@@ -262,6 +262,8 @@ struct hid_item {#define HID_CP_SELECTION 0x000c0080#define HID_CP_MEDIASELECTION 0x000c0087#define HID_CP_SELECTDISC 0x000c00ba +#define HID_CP_VOLUMEUP 0x000c00e9 +#define HID_CP_VOLUMEDOWN 0x000c00ea#define HID_CP_PLAYBACKSPEED 0x000c00f1#define HID_CP_PROXIMITY 0x000c0109#define HID_CP_SPEAKERSYSTEM 0x000c0160
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 349/530 perf symbols: Fix dso__fprintf_symbols_by_name() to return the number of printed chars
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
[ Upstream commit 210e4c89ef61432040c6cd828fefa441f4887186 ]
The 'ret' variable was initialized to zero but then it was not updated from the fprintf() return, fix it.
--- tools/perf/util/symbol_fprintf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/symbol_fprintf.c +1 -1
@@ -68,7 +68,7 @@ size_t dso__fprintf_symbols_by_name(struct dso *dso,for (nd =rb_first_cached (&dso->symbol_names); nd; nd =rb_next (nd)) { pos = rb_entry(nd, struct symbol_name_rb_node, rb_node); -fprintf (fp,"%s\n" , pos->sym.name); + ret +=fprintf (fp,"%s\n" , pos->sym.name); }return ret;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 350/530 ASoC: Intel: boards: sof-wm8804: add check for PLL setting
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 1730ef62874dbdc53dc2abfa430f09f0b304bafc ]
Currently the return from snd_soc_dai_set_pll is not checking for failure, this is the only driver in the kernel that ignores this, so it probably should be added for sake of completeness. Fix this by adding an error return check.
Addresses-Coverity: ("Unchecked return value")
--- sound/soc/intel/boards/sof_wm8804.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
sound/soc/intel/boards/sof_wm8804.c +5 -1
@@ -124,7 +124,11 @@ static int sof_wm8804_hw_params(struct snd_pcm_substream *substream, }snd_soc_dai_set_clkdiv (codec_dai,WM8804_MCLK_DIV , mclk_div); -snd_soc_dai_set_pll (codec_dai,0 ,0 , sysclk, mclk_freq); + ret =snd_soc_dai_set_pll (codec_dai,0 ,0 , sysclk, mclk_freq); +if (ret <0 ) { +dev_err (rtd->card->dev,"Failed to set WM8804 PLL\n" ); +return ret; + } ret =snd_soc_dai_set_sysclk (codec_dai,WM8804_TX_CLKSRC_PLL , sysclk,SND_SOC_CLOCK_OUT );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 351/530 ASoC: Intel: Skylake: Compile when any configuration is selected
In reply to Greg Kroah-HartmanFrom: Cezary Rojewski <[email protected]>
[ Upstream commit 1b99d50b9709a2cddaba4a7faf1862b4f7bec865 ]
Skylake is dependent on SND_SOC_INTEL_SKYLAKE (aka "all SST platforms") whereas selecting specific configuration such as KBL-only will not cause driver code to compile. Switch to SND_SOC_INTEL_SKYLAKE_COMMON dependency so selecting any configuration causes the driver to be built.
--- sound/soc/intel/Makefile | 2 +- sound/soc/intel/skylake/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
sound/soc/intel/Makefile +1 -1
@@ -5,7 +5,7 @@ obj-$(CONFIG_SND_SOC) += common/ # Platform Support obj-$(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM) += atom/ obj-$(CONFIG_SND_SOC_INTEL_CATPT) += catpt/ -obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += skylake/ +obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE_COMMON) += skylake/ obj-$(CONFIG_SND_SOC_INTEL_KEEMBAY) += keembay/ # Machine support
sound/soc/intel/skylake/Makefile +1 -1
@@ -7,7 +7,7 @@ ifdef CONFIG_DEBUG_FS snd-soc-skl-objs += skl-debug.o endif -obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o +obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE_COMMON) += snd-soc-skl.o #Skylake Clock device support snd-soc-skl-ssp-clk-objs := skl-ssp-clk.o
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 352/530 RDMA/mlx5: Fix mlx5 rates to IB rates map
In reply to Greg Kroah-HartmanFrom: Mark Zhang <[email protected]>
[ Upstream commit 6fe6e568639859db960c8fcef19a2ece1c2d7eae ]
Correct the map between mlx5 rates and corresponding ib rates, as they don't always have a fixed offset between them.
--- drivers/infiniband/hw/mlx5/qp.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
drivers/infiniband/hw/mlx5/qp.c +14 -1
@@ -3079,6 +3079,19 @@ enum { MLX5_PATH_FLAG_COUNTER = 1 << 2, }; +static int mlx5_to_ib_rate_map (u8 rate) +{ +static const int rates[] = {IB_RATE_PORT_CURRENT ,IB_RATE_56_GBPS , +IB_RATE_25_GBPS ,IB_RATE_100_GBPS , +IB_RATE_200_GBPS ,IB_RATE_50_GBPS , +IB_RATE_400_GBPS }; + +if (rate <ARRAY_SIZE (rates)) +return rates[rate]; + +return rate -MLX5_STAT_RATE_OFFSET ; +} +static int ib_to_mlx5_rate_map (u8 rate) {switch (rate) {
@@ -4420,7 +4433,7 @@ static void to_rdma_ah_attr(struct mlx5_ib_dev *ibdev,rdma_ah_set_path_bits (ah_attr,MLX5_GET (ads, path, mlid)); static_rate =MLX5_GET (ads, path, stat_rate); -rdma_ah_set_static_rate (ah_attr, static_rate ? static_rate -5 :0 ); +rdma_ah_set_static_rate (ah_attr,mlx5_to_ib_rate_map (static_rate));if (MLX5_GET (ads, path, grh) || ah_attr->type ==RDMA_AH_ATTR_TYPE_ROCE ) { rdma_ah_set_grh(ah_attr, NULL, MLX5_GET(ads, path, flow_label),
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 353/530 wilc1000: write value to WILC_INTR2_ENABLE register
In reply to Greg Kroah-HartmanFrom: Marcus Folkesson <[email protected]>
[ Upstream commit e21b6e5a54628cd3935f200049d4430c25c54e03 ]
Write the value instead of reading it twice.
--- drivers/net/wireless/microchip/wilc1000/sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/microchip/wilc1000/sdio.c +1 -1
@@ -947,7 +947,7 @@ static int wilc_sdio_sync_ext(struct wilc *wilc, int nint)for (i =0 ; (i <3 ) && (nint >0 ); i++, nint--) reg |=BIT (i); - ret =wilc_sdio_read_reg (wilc,WILC_INTR2_ENABLE , ®); + ret =wilc_sdio_write_reg (wilc,WILC_INTR2_ENABLE , reg);if (ret) { dev_err(&func->dev, "Failed write reg (%08x)...\n",
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 354/530 KVM: x86/mmu: Retry page faults that hit an invalid memslot
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
[ Upstream commit e0c378684b6545ad2d4403bb701d0ac4932b4e95 ]
Retry page faults (re-enter the guest) that hit an invalid memslot instead of treating the memslot as not existing, i.e. handling the page fault as an MMIO access. When deleting a memslot, SPTEs aren't zapped and the TLBs aren't flushed until after the memslot has been marked invalid.
Handling the invalid slot as MMIO means there's a small window where a page fault could replace a valid SPTE with an MMIO SPTE. The legacy MMU handles such a scenario cleanly, but the TDP MMU assumes such behavior is impossible (see the BUG() in __handle_changed_spte()). There's really no good reason why the legacy MMU should allow such a scenario, and closing this hole allows for additional cleanups.
Message-Id: <[email protected]>
--- arch/x86/kvm/mmu/mmu.c | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/x86/kvm/mmu/mmu.c +8 -0
@@ -3663,6 +3663,14 @@ static bool try_async_pf(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn,struct kvm_memory_slot *slot =kvm_vcpu_gfn_to_memslot (vcpu, gfn);bool async; +/* +* Retry the page fault if the gfn hit a memslot that is being deleted +* or moved. This ensures any existing SPTEs for the old memslot will +* be zapped before KVM inserts a new MMIO SPTE for the gfn. +*/ +if (slot && (slot->flags &KVM_MEMSLOT_INVALID )) +return true; +/* Don't expose private memslots to L2. */ if (is_guest_mode (vcpu) && !kvm_is_visible_memslot (slot)) { *pfn =KVM_PFN_NOSLOT ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 355/530 Bluetooth: avoid deadlock between hci_dev->lock and socket lock
In reply to Greg Kroah-HartmanFrom: Jiri Kosina <[email protected]>
[ Upstream commit 17486960d79b900c45e0bb8fbcac0262848582ba ]
Commit eab2404ba798 ("Bluetooth: Add BT_PHY socket option") added a dependency between socket lock and hci_dev->lock that could lead to deadlock.
It turns out that hci_conn_get_phy() is not in any way relying on hdev being immutable during the runtime of this function, neither does it even look at any of the members of hdev, and as such there is no need to hold that lock.
This fixes the lockdep splat below:
======================================================
WARNING: possible circular locking dependency detected 5.12.0-rc1-00026-g73d464503354 #10 Not tainted
------------------------------------------------------
bluetoothd/1118 is trying to acquire lock:
ffff8f078383c078 (&hdev->lock){+.+.}-{3:3}, at: hci_conn_get_phy+0x1c/0x150 [bluetooth]
but task is already holding lock:
ffff8f07e831d920 (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+.}-{0:0}, at: l2cap_sock_getsockopt+0x8b/0x610
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #3 (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+.}-{0:0}:
lock_sock_nested+0x72/0xa0
l2cap_sock_ready_cb+0x18/0x70 [bluetooth]
l2cap_config_rsp+0x27a/0x520 [bluetooth]
l2cap_sig_channel+0x658/0x1330 [bluetooth]
l2cap_recv_frame+0x1ba/0x310 [bluetooth]
hci_rx_work+0x1cc/0x640 [bluetooth]
process_one_work+0x244/0x5f0
worker_thread+0x3c/0x380
kthread+0x13e/0x160
ret_from_fork+0x22/0x30-> #2 (&chan->lock#2/1){+.+.}-{3:3}:
__mutex_lock+0xa3/0xa10
l2cap_chan_connect+0x33a/0x940 [bluetooth]
l2cap_sock_connect+0x141/0x2a0 [bluetooth]
__sys_connect+0x9b/0xc0
__x64_sys_connect+0x16/0x20
do_syscall_64+0x33/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xae-> #1 (&conn->chan_lock){+.+.}-{3:3}:
__mutex_lock+0xa3/0xa10
l2cap_chan_connect+0x322/0x940 [bluetooth]
l2cap_sock_connect+0x141/0x2a0 [bluetooth]
__sys_connect+0x9b/0xc0
__x64_sys_connect+0x16/0x20
do_syscall_64+0x33/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xae-> #0 (&hdev->lock){+.+.}-{3:3}:
__lock_acquire+0x147a/0x1a50
lock_acquire+0x277/0x3d0
__mutex_lock+0xa3/0xa10
hci_conn_get_phy+0x1c/0x150 [bluetooth]
l2cap_sock_getsockopt+0x5a9/0x610 [bluetooth]
__sys_getsockopt+0xcc/0x200
__x64_sys_getsockopt+0x20/0x30
do_syscall_64+0x33/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xaeother info that might help us debug this:
Chain exists of: &hdev->lock --> &chan->lock#2/1 --> sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP);
lock(&chan->lock#2/1);
lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP); lock(&hdev->lock);
*** DEADLOCK ***
1 lock held by bluetoothd/1118:
#0: ffff8f07e831d920 (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+.}-{0:0}, at: l2cap_sock_getsockopt+0x8b/0x610 [bluetooth]
stack backtrace: CPU: 3 PID: 1118 Comm: bluetoothd Not tainted 5.12.0-rc1-00026-g73d464503354 #10 Hardware name: LENOVO 20K5S22R00/20K5S22R00, BIOS R0IET38W (1.16 ) 05/31/2017 Call Trace: dump_stack+0x7f/0xa1 check_noncircular+0x105/0x120 ? __lock_acquire+0x147a/0x1a50 __lock_acquire+0x147a/0x1a50 lock_acquire+0x277/0x3d0 ? hci_conn_get_phy+0x1c/0x150 [bluetooth] ? __lock_acquire+0x2e1/0x1a50 ? lock_is_held_type+0xb4/0x120 ? hci_conn_get_phy+0x1c/0x150 [bluetooth] __mutex_lock+0xa3/0xa10 ? hci_conn_get_phy+0x1c/0x150 [bluetooth] ? lock_acquire+0x277/0x3d0 ? mark_held_locks+0x49/0x70 ? mark_held_locks+0x49/0x70 ? hci_conn_get_phy+0x1c/0x150 [bluetooth] hci_conn_get_phy+0x1c/0x150 [bluetooth] l2cap_sock_getsockopt+0x5a9/0x610 [bluetooth] __sys_getsockopt+0xcc/0x200 __x64_sys_getsockopt+0x20/0x30 do_syscall_64+0x33/0x80 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7fb73df33eee Code: 48 8b 0d 85 0f 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 37 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 52 0f 0c 00 f7 d8 64 89 01 48 RSP: 002b:00007fffcfbbbf08 EFLAGS: 00000203 ORIG_RAX: 0000000000000037 RAX: ffffffffffffffda RBX: 0000000000000019 RCX: 00007fb73df33eee RDX: 000000000000000e RSI: 0000000000000112 RDI: 0000000000000018 RBP: 0000000000000000 R08: 00007fffcfbbbf44 R09: 0000000000000000 R10: 00007fffcfbbbf3c R11: 0000000000000203 R12: 0000000000000000 R13: 0000000000000018 R14: 0000000000000000 R15: 0000556fcefc70d0
--- net/bluetooth/hci_conn.c | 4 ---- 1 file changed, 4 deletions(-)
net/bluetooth/hci_conn.c +0 -4
@@ -1789,8 +1789,6 @@ u32 hci_conn_get_phy(struct hci_conn *conn) {u32 phys =0 ; -hci_dev_lock (conn->hdev); -/* BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 2, Part B page 471: * Table 6.2: Packets defined for synchronous, asynchronous, and * CSB logical transport types.
@@ -1887,7 +1885,5 @@ u32 hci_conn_get_phy(struct hci_conn *conn)break ; } -hci_dev_unlock (conn->hdev); -return phys; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 356/530 net: lapbether: Prevent racing when checking whether the netif is running
In reply to Greg Kroah-HartmanFrom: Xie He <[email protected]>
[ Upstream commit 5acd0cfbfbb5a688da1bfb1a2152b0c855115a35 ]
There are two "netif_running" checks in this driver. One is in "lapbeth_xmit" and the other is in "lapbeth_rcv". They serve to make sure that the LAPB APIs called in these functions are called before "lapb_unregister" is called by the "ndo_stop" function.
However, these "netif_running" checks are unreliable, because it's possible that immediately after "netif_running" returns true, "ndo_stop" is called (which causes "lapb_unregister" to be called).
This patch adds locking to make sure "lapbeth_xmit" and "lapbeth_rcv" can reliably check and ensure the netif is running while doing their work.
--- drivers/net/wan/lapbether.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-)
drivers/net/wan/lapbether.c +25 -7
@@ -51,6 +51,8 @@ struct lapbethdev {struct list_head node;struct net_device *ethdev;/* link to ethernet device */ struct net_device *axdev;/* lapbeth device (lapb#) */ +bool up; +spinlock_t up_lock;/* Protects "up" */ };static LIST_HEAD (lapbeth_devices);
@@ -98,8 +100,9 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packercu_read_lock (); lapbeth =lapbeth_get_x25_dev (dev);if (!lapbeth) - goto drop_unlock; -if (!netif_running (lapbeth->axdev)) + goto drop_unlock_rcu; +spin_lock_bh (&lapbeth->up_lock); +if (!lapbeth->up) goto drop_unlock; len = skb->data[0 ] + skb->data[1 ] *256 ;
@@ -114,11 +117,14 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe goto drop_unlock; } out: +spin_unlock_bh (&lapbeth->up_lock);rcu_read_unlock ();return 0 ; drop_unlock:kfree_skb (skb); goto out; +drop_unlock_rcu: +rcu_read_unlock (); drop:kfree_skb (skb);return 0 ;
@@ -148,13 +154,11 @@ static int lapbeth_data_indication(struct net_device *dev, struct sk_buff *skb)static netdev_tx_t lapbeth_xmit (struct sk_buff *skb,struct net_device *dev) { +struct lapbethdev *lapbeth =netdev_priv (dev);int err; -/* -* Just to be *really* sure not to send anything if the interface -* is down, the ethernet device may have gone. -*/ -if (!netif_running (dev)) +spin_lock_bh (&lapbeth->up_lock); +if (!lapbeth->up) goto drop;/* There should be a pseudo header of 1 byte added by upper layers.
@@ -185,6 +189,7 @@ static netdev_tx_t lapbeth_xmit(struct sk_buff *skb, goto drop; } out: +spin_unlock_bh (&lapbeth->up_lock);return NETDEV_TX_OK ; drop:kfree_skb (skb);
@@ -276,6 +281,7 @@ static const struct lapb_register_struct lapbeth_callbacks = {*/ static int lapbeth_open (struct net_device *dev) { +struct lapbethdev *lapbeth =netdev_priv (dev);int err;if ((err =lapb_register (dev, &lapbeth_callbacks)) !=LAPB_OK ) {
@@ -283,13 +289,22 @@ static int lapbeth_open(struct net_device *dev)return -ENODEV ; } +spin_lock_bh (&lapbeth->up_lock); + lapbeth->up = true; +spin_unlock_bh (&lapbeth->up_lock); +return 0 ; }static int lapbeth_close (struct net_device *dev) { +struct lapbethdev *lapbeth =netdev_priv (dev);int err; +spin_lock_bh (&lapbeth->up_lock); + lapbeth->up = false; +spin_unlock_bh (&lapbeth->up_lock); +if ((err =lapb_unregister (dev)) !=LAPB_OK )pr_err ("lapb_unregister error: %d\n" , err);
@@ -347,6 +362,9 @@ static int lapbeth_new_device(struct net_device *dev)dev_hold (dev); lapbeth->ethdev = dev; + lapbeth->up = false; +spin_lock_init (&lapbeth->up_lock); + rc = -EIO ;if (register_netdevice (ndev)) goto fail;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 357/530 libbpf: Add explicit padding to bpf_xdp_set_link_opts
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit dde7b3f5f2f458297aeccfd4783e53ab8ca046db ]
Adding such anonymous padding fixes the issue with uninitialized portions of bpf_xdp_set_link_opts when using LIBBPF_DECLARE_OPTS macro with inline field initialization:
DECLARE_LIBBPF_OPTS(bpf_xdp_set_link_opts, opts, .old_fd = -1);
When such code is compiled in debug mode, compiler is generating code that leaves padding bytes uninitialized, which triggers error inside libbpf APIs that do strict zero initialization checks for OPTS structs.
Adding anonymous padding field fixes the issue.
--- tools/lib/bpf/libbpf.h | 1 + 1 file changed, 1 insertion(+)
tools/lib/bpf/libbpf.h +1 -0
@@ -507,6 +507,7 @@ struct xdp_link_info {struct bpf_xdp_set_link_opts {size_t sz;int old_fd; + size_t :0; };#define bpf_xdp_set_link_opts__last_field old_fd
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 358/530 bpftool: Fix maybe-uninitialized warnings
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit 4bbb3583687051ef99966ddaeb1730441b777d40 ]
Somehow when bpftool is compiled in -Og mode, compiler produces new warnings about possibly uninitialized variables. Fix all the reported problems.
--- tools/bpf/bpftool/btf.c | 3 +++ tools/bpf/bpftool/main.c | 3 +-- tools/bpf/bpftool/map.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-)
tools/bpf/bpftool/btf.c +3 -0
@@ -519,6 +519,7 @@ static int do_dump(int argc, char **argv)NEXT_ARG ();if (argc <1 ) {p_err ("expecting value for 'format' option\n" ); + err = -EINVAL ; goto done; }if (strcmp (*argv,"c" ) ==0 ) {
@@ -528,11 +529,13 @@ static int do_dump(int argc, char **argv) }else {p_err ("unrecognized format specifier: '%s', possible values: raw, c" , *argv); + err = -EINVAL ; goto done; }NEXT_ARG (); }else {p_err ("unrecognized option: '%s'" , *argv); + err = -EINVAL ; goto done; } }
tools/bpf/bpftool/main.c +1 -2
@@ -274,7 +274,7 @@ static int do_batch(int argc, char **argv)int n_argc;FILE *fp;char *cp; -int err; +int err =0 ;int i;if (argc <2 ) {
@@ -368,7 +368,6 @@ static int do_batch(int argc, char **argv) }else {if (!json_output)printf ("processed %d commands\n" , lines); - err =0 ; } err_close:if (fp != stdin)
tools/bpf/bpftool/map.c +1 -1
@@ -99,7 +99,7 @@ static int do_dump_btf(const struct btf_dumper *d, void *value) {__u32 value_id; -int ret; +int ret =0 ;/* start of key-value pair */ jsonw_start_object (d->jw);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 359/530 iommu: Check dev->iommu in iommu_dev_xxx functions
In reply to Greg Kroah-HartmanFrom: Shameer Kolothum <[email protected]>
[ Upstream commit b9abb19fa5fd2d8a4be61c6cd4b2a48aa1a17f9c ]
The device iommu probe/attach might have failed leaving dev->iommu to NULL and device drivers may still invoke these functions resulting in a crash in iommu vendor driver code.
Hence make sure we check that.
--- drivers/iommu/iommu.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-)
drivers/iommu/iommu.c +15 -9
@@ -2872,10 +2872,12 @@ EXPORT_SYMBOL_GPL(iommu_dev_has_feature);int iommu_dev_enable_feature (struct device *dev,enum iommu_dev_features feat) { -const struct iommu_ops *ops = dev->bus->iommu_ops; +if (dev->iommu && dev->iommu->iommu_dev) { +const struct iommu_ops *ops = dev->iommu->iommu_dev->ops; -if (ops && ops->dev_enable_feat) -return ops->dev_enable_feat (dev, feat); +if (ops->dev_enable_feat) +return ops->dev_enable_feat (dev, feat); + }return -ENODEV ; }
@@ -2888,10 +2890,12 @@ EXPORT_SYMBOL_GPL(iommu_dev_enable_feature);*/ int iommu_dev_disable_feature (struct device *dev,enum iommu_dev_features feat) { -const struct iommu_ops *ops = dev->bus->iommu_ops; +if (dev->iommu && dev->iommu->iommu_dev) { +const struct iommu_ops *ops = dev->iommu->iommu_dev->ops; -if (ops && ops->dev_disable_feat) -return ops->dev_disable_feat (dev, feat); +if (ops->dev_disable_feat) +return ops->dev_disable_feat (dev, feat); + }return -EBUSY ; }
@@ -2899,10 +2903,12 @@ EXPORT_SYMBOL_GPL(iommu_dev_disable_feature);bool iommu_dev_feature_enabled (struct device *dev,enum iommu_dev_features feat) { -const struct iommu_ops *ops = dev->bus->iommu_ops; +if (dev->iommu && dev->iommu->iommu_dev) { +const struct iommu_ops *ops = dev->iommu->iommu_dev->ops; -if (ops && ops->dev_feat_enabled) -return ops->dev_feat_enabled (dev, feat); +if (ops->dev_feat_enabled) +return ops->dev_feat_enabled (dev, feat); + }return false; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 360/530 iommu/vt-d: Reject unsupported page request modes
In reply to Greg Kroah-HartmanFrom: Jacob Pan <[email protected]>
[ Upstream commit 78a523fe73b81b4447beb2d6c78c9fafae24eebb ]
When supervisor/privilige mode SVM is used, we bind init_mm.pgd with a supervisor PASID. There should not be any page fault for init_mm. Execution request with DMA read is also not supported.
This patch checks PRQ descriptor for both unsupported configurations, reject them both with invalid responses.
--- drivers/iommu/intel/svm.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/iommu/intel/svm.c +11 -1
@@ -959,7 +959,17 @@ static irqreturn_t prq_event_thread(int irq, void *d) ((unsigned long long *)req)[1]); goto no_pasid; } - +/* We shall not receive page request for supervisor SVM */ +if (req->pm_req && (req->rd_req | req->wr_req)) { +pr_err ("Unexpected page request in Privilege Mode" ); +/* No need to find the matching sdev as for bad_req */ + goto no_pasid; + } +/* DMA read with exec requeset is not supported. */ +if (req->exe_req && req->rd_req) { +pr_err ("Execution request not supported\n" ); + goto no_pasid; + }if (!svm || svm->pasid != req->pasid) {rcu_read_lock (); svm =ioasid_find (NULL , req->pasid,NULL );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 361/530 selftests/bpf: Re-generate vmlinux.h and BPF skeletons if bpftool changed
In reply to Greg Kroah-HartmanFrom: Andrii Nakryiko <[email protected]>
[ Upstream commit cab62c37be057379a2a17b1b2eacd9dcba1e14dc ]
Trigger vmlinux.h and BPF skeletons re-generation if detected that bpftool was re-compiled. Otherwise full make clean is required to get updated skeletons, if bpftool is modified.
--- tools/testing/selftests/bpf/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
tools/testing/selftests/bpf/Makefile +3 -2
@@ -196,7 +196,7 @@ $(BUILD_DIR)/libbpf $(BUILD_DIR)/bpftool $(BUILD_DIR)/resolve_btfids $(INCLUDE_D $(call msg,MKDIR,,$@) $(Q)mkdir -p $@ -$(INCLUDE_DIR)/vmlinux.h: $(VMLINUX_BTF) | $(BPFTOOL) $(INCLUDE_DIR) +$(INCLUDE_DIR)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) | $(INCLUDE_DIR) ifeq ($(VMLINUX_H),) $(call msg,GEN,,$@) $(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@
@@ -333,7 +333,8 @@ $(TRUNNER_BPF_OBJS): $(TRUNNER_OUTPUT)/%.o: \ $(TRUNNER_BPF_SKELS): $(TRUNNER_OUTPUT)/%.skel.h: \ $(TRUNNER_OUTPUT)/%.o \ - | $(BPFTOOL) $(TRUNNER_OUTPUT) + $(BPFTOOL) \ + | $(TRUNNER_OUTPUT) $$(call msg,GEN-SKEL,$(TRUNNER_BINARY),$$@) $(Q)$$(BPFTOOL) gen skeleton $$< > $$@ endif
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 362/530 libbpf: Add explicit padding to btf_dump_emit_type_decl_opts
In reply to Greg Kroah-HartmanFrom: KP Singh <[email protected]>
[ Upstream commit ea24b19562fe5f72c78319dbb347b701818956d9 ]
Similar to
https://lore.kernel.org/bpf/[email protected]/
When DECLARE_LIBBPF_OPTS is used with inline field initialization, e.g:
DECLARE_LIBBPF_OPTS(btf_dump_emit_type_decl_opts, opts,
.field_name = var_ident,
.indent_level = 2,
.strip_mods = strip_mods,
);
and compiled in debug mode, the compiler generates code which leaves the padding uninitialized and triggers errors within libbpf APIs which require strict zero initialization of OPTS structs.
Adding anonymous padding field fixes the issue.
--- tools/lib/bpf/btf.h | 1 + 1 file changed, 1 insertion(+)
tools/lib/bpf/btf.h +1 -0
@@ -164,6 +164,7 @@ struct btf_dump_emit_type_decl_opts {int indent_level;/* strip all the const/volatile/restrict mods */ bool strip_mods; + size_t :0; };#define btf_dump_emit_type_decl_opts__last_field strip_mods
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 363/530 powerpc/fadump: Mark fadump_calculate_reserve_size as __init
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit fbced1546eaaab57a32e56c974ea8acf10c6abd8 ]
If fadump_calculate_reserve_size() is not inlined, there is a modpost warning:
WARNING: modpost: vmlinux.o(.text+0x5196c): Section mismatch in reference from the function fadump_calculate_reserve_size() to the function .init.text:parse_crashkernel()
The function fadump_calculate_reserve_size() references the function __init parse_crashkernel().
This is often because fadump_calculate_reserve_size lacks a __init annotation or the annotation of parse_crashkernel is wrong.
fadump_calculate_reserve_size() calls parse_crashkernel(), which is marked as __init and fadump_calculate_reserve_size() is called from within fadump_reserve_mem(), which is also marked as __init.
Mark fadump_calculate_reserve_size() as __init to fix the section mismatch. Additionally, remove the inline keyword as it is not necessary to inline this function; the compiler is still free to do so if it feels it is worthwhile since commit 889b3c1245de ("compiler: remove CONFIG_OPTIMIZE_INLINING entirely").
--- arch/powerpc/kernel/fadump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kernel/fadump.c +1 -1
@@ -292,7 +292,7 @@ static void fadump_show_config(void)* that is required for a kernel to boot successfully. * */ -static inline u64 fadump_calculate_reserve_size (void ) +static __init u64 fadump_calculate_reserve_size (void ) {u64 base, size, bootmem_min;int ret;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 364/530 powerpc/prom: Mark identical_pvr_fixup as __init
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit 1ef1dd9c7ed27b080445e1576e8a05957e0e4dfc ]
If identical_pvr_fixup() is not inlined, there are two modpost warnings:
WARNING: modpost: vmlinux.o(.text+0x54e8): Section mismatch in reference from the function identical_pvr_fixup() to the function .init.text:of_get_flat_dt_prop()
The function identical_pvr_fixup() references
the function __init of_get_flat_dt_prop().
This is often because identical_pvr_fixup lacks a __init annotation or the annotation of of_get_flat_dt_prop is wrong.
WARNING: modpost: vmlinux.o(.text+0x551c): Section mismatch in reference from the function identical_pvr_fixup() to the function .init.text:identify_cpu()
The function identical_pvr_fixup() references
the function __init identify_cpu().
This is often because identical_pvr_fixup lacks a __init annotation or the annotation of identify_cpu is wrong.
identical_pvr_fixup() calls two functions marked as __init and is only called by a function marked as __init so it should be marked as __init as well. At the same time, remove the inline keywork as it is not necessary to inline this function. The compiler is still free to do so if it feels it is worthwhile since commit 889b3c1245de ("compiler:
remove CONFIG_OPTIMIZE_INLINING entirely").
--- arch/powerpc/kernel/prom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kernel/prom.c +1 -1
@@ -268,7 +268,7 @@ static struct feature_property { };#if defined(CONFIG_44x) && defined(CONFIG_PPC_FPU ) -static inline void identical_pvr_fixup (unsigned long node) +static __init void identical_pvr_fixup (unsigned long node) {unsigned int pvr;const char *model =of_get_flat_dt_prop (node,"model" ,NULL );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 365/530 MIPS: fix local_irq_{disable,enable} in asmmacro.h
In reply to Greg Kroah-HartmanFrom: Huang Pei <[email protected]>
[ Upstream commit 05c4e2721d7af0df7bc1378a23712a0fd16947b5 ]
commit ba9196d2e005 ("MIPS: Make DIEI support as a config option") use CPU_HAS_DIEI to indicate whether di/ei is implemented correctly, without this patch, "local_irq_disable" from entry.S in 3A1000 (with buggy di/ei) lose protection of commit e97c5b609880 ("MIPS:
Make irqflags.h functions preempt-safe for non-mipsr2 cpus")
--- arch/mips/include/asm/asmmacro.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
arch/mips/include/asm/asmmacro.h +1 -2
@@ -44,8 +44,7 @@ .endm#endif -#if defined(CONFIG_CPU_MIPSR2 ) || defined(CONFIG_CPU_MIPSR5 ) || \ - defined(CONFIG_CPU_MIPSR6 ) +#ifdef CONFIG_CPU_HAS_DIEI .macro local_irq_enable reg=t0ei irq_enable_hazard
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 366/530 ima: Fix the error code for restoring the PCR value
In reply to Greg Kroah-HartmanFrom: Li Huafei <[email protected]>
[ Upstream commit 7990ccafaa37dc6d8bb095d4d7cd997e8903fd10 ]
In ima_restore_measurement_list(), hdr[HDR_PCR].data is pointing to a buffer of type u8, which contains the dumped 32-bit pcr value. Currently, only the least significant byte is used to restore the pcr value. We should convert hdr[HDR_PCR].data to a pointer of type u32 before fetching the value to restore the correct pcr value.
--- security/integrity/ima/ima_template.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
security/integrity/ima/ima_template.c +2 -2
@@ -468,8 +468,8 @@ int ima_restore_measurement_list(loff_t size, void *buf) } } - entry->pcr = !ima_canonical_fmt ? *(hdr[HDR_PCR ].data) : -le32_to_cpu (*(hdr[HDR_PCR ].data)); + entry->pcr = !ima_canonical_fmt ? *(u32 *)(hdr[HDR_PCR ].data) : +le32_to_cpu (*(u32 *)(hdr[HDR_PCR ].data)); ret =ima_restore_measurement_entry (entry);if (ret <0 )break ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 367/530 inet: use bigger hash table for IP ID generation
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit aa6dd211e4b1dde9d5dc25d699d35f789ae7eeba ]
In commit 73f156a6e8c1 ("inetpeer: get rid of ip_id_count") I used a very small hash table that could be abused by patient attackers to reveal sensitive information.
Switch to a dynamic sizing, depending on RAM size.
Typical big hosts will now use 128x more storage (2 MB) to get a similar increase in security and reduction of hash collisions.
As a bonus, use of alloc_large_system_hash() spreads allocated memory among all NUMA nodes.
--- net/ipv4/route.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-)
net/ipv4/route.c +28 -14
@@ -66,6 +66,7 @@#include <linux/types.h> #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/memblock.h> #include <linux/string.h> #include <linux/socket.h> #include <linux/sockios.h>
@@ -476,8 +477,10 @@ static void ipv4_confirm_neigh(const struct dst_entry *dst, const void *daddr)__ipv4_confirm_neigh (dev, *(__force u32 *)pkey); } -#define IP_IDENTS_SZ 2048u - +/* Hash tables of size 2048..262144 depending on RAM size. +* Each bucket uses 8 bytes. +*/ +static u32 ip_idents_mask__read_mostly ;static atomic_t *ip_idents__read_mostly ;static u32 *ip_tstamps__read_mostly ;
@@ -487,12 +490,16 @@ static u32 *ip_tstamps __read_mostly;*/ u32 ip_idents_reserve (u32 hash,int segs) { -u32 *p_tstamp = ip_tstamps + hash %IP_IDENTS_SZ ; -atomic_t *p_id = ip_idents + hash %IP_IDENTS_SZ ; -u32 old =READ_ONCE (*p_tstamp); -u32 now = (u32 )jiffies; +u32 bucket, old, now = (u32 )jiffies; +atomic_t *p_id; +u32 *p_tstamp;u32 delta =0 ; + bucket = hash & ip_idents_mask; + p_tstamp = ip_tstamps + bucket; + p_id = ip_idents + bucket; + old =READ_ONCE (*p_tstamp); +if (old != now &&cmpxchg (p_tstamp, old, now) == old) delta =prandom_u32_max (now - old);
@@ -3544,18 +3551,25 @@ struct ip_rt_acct __percpu *ip_rt_acct __read_mostly;int __init ip_rt_init (void ) { +void *idents_hash;int cpu; - ip_idents =kmalloc_array (IP_IDENTS_SZ ,sizeof (*ip_idents), -GFP_KERNEL ); -if (!ip_idents) -panic ("IP: failed to allocate ip_idents\n" ); +/* For modern hosts, this will use 2 MB of memory */ + idents_hash =alloc_large_system_hash ("IP idents" , +sizeof (*ip_idents) +sizeof (*ip_tstamps), +0 , +16 ,/* one bucket per 64 KB */ +HASH_ZERO , +NULL , + &ip_idents_mask, +2048 , +256 *1024 ); + + ip_idents = idents_hash; -prandom_bytes (ip_idents,IP_IDENTS_SZ *sizeof (*ip_idents)); +prandom_bytes (ip_idents, (ip_idents_mask +1 ) *sizeof (*ip_idents)); - ip_tstamps =kcalloc (IP_IDENTS_SZ ,sizeof (*ip_tstamps),GFP_KERNEL ); -if (!ip_tstamps) -panic ("IP: failed to allocate ip_tstamps\n" ); + ip_tstamps = idents_hash + (ip_idents_mask +1 ) *sizeof (*ip_idents);for_each_possible_cpu (cpu) {struct uncached_list *ul = &per_cpu (rt_uncached_list, cpu);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 368/530 pinctrl: pinctrl-single: remove unused parameter
In reply to Greg Kroah-HartmanFrom: Hanna Hawa <[email protected]>
[ Upstream commit 8fa2ea202b13b6da81e26c399ff1d87488398453 ]
Remove unused parameter 'pin_pos' from pcs_add_pin().
--- drivers/pinctrl/pinctrl-single.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/pinctrl/pinctrl-single.c +2 -6
@@ -656,10 +656,8 @@ static const struct pinconf_ops pcs_pinconf_ops = {* pcs_add_pin() - add a pin to the static per controller pin array * @pcs: pcs driver instance * @offset: register offset from base -* @pin_pos: unused */ -static int pcs_add_pin (struct pcs_device *pcs,unsigned offset, -unsigned pin_pos) +static int pcs_add_pin (struct pcs_device *pcs,unsigned int offset) {struct pcs_soc_data *pcs_soc = &pcs->socdata;struct pinctrl_pin_desc *pin;
@@ -729,16 +727,14 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs)unsigned offset;int res;int byte_num; -int pin_pos =0 ;if (pcs->bits_per_mux) { byte_num = (pcs->bits_per_pin * i) /BITS_PER_BYTE ; offset = (byte_num / mux_bytes) * mux_bytes; - pin_pos = i % num_pins_in_register; }else { offset = i * mux_bytes; } - res =pcs_add_pin (pcs, offset, pin_pos); + res =pcs_add_pin (pcs, offset);if (res <0 ) {dev_err (pcs->dev,"error adding pins: %i\n" , res);return res;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 369/530 pinctrl: pinctrl-single: fix pcs_pin_dbg_show() when bits_per_mux is not zero
In reply to Greg Kroah-HartmanFrom: Hanna Hawa <[email protected]>
[ Upstream commit bd85125ea88513f637a62a72e8949c579c5c0a87 ]
A System Error (SError, followed by kernel panic) was detected when trying to print the supported pins in a pinctrl device which supports multiple pins per register. This change fixes the pcs_pin_dbg_show() in pinctrl-single driver when bits_per_mux is not zero. In addition move offset calculation and pin offset in register to common function.
--- drivers/pinctrl/pinctrl-single.c | 55 ++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 20 deletions(-)
drivers/pinctrl/pinctrl-single.c +35 -20
@@ -270,20 +270,44 @@ static void __maybe_unused pcs_writel(unsigned val, void __iomem *reg)writel (val, reg); } +static unsigned int pcs_pin_reg_offset_get (struct pcs_device *pcs, +unsigned int pin) +{ +unsigned int mux_bytes = pcs->width /BITS_PER_BYTE ; + +if (pcs->bits_per_mux) { +unsigned int pin_offset_bytes; + + pin_offset_bytes = (pcs->bits_per_pin * pin) /BITS_PER_BYTE ; +return (pin_offset_bytes / mux_bytes) * mux_bytes; + } + +return pin * mux_bytes; +} + +static unsigned int pcs_pin_shift_reg_get (struct pcs_device *pcs, +unsigned int pin) +{ +return (pin % (pcs->width / pcs->bits_per_pin)) * pcs->bits_per_pin; +} +static void pcs_pin_dbg_show (struct pinctrl_dev *pctldev,struct seq_file *s,unsigned pin) {struct pcs_device *pcs; -unsigned val, mux_bytes; +unsigned int val;unsigned long offset;size_t pa; pcs =pinctrl_dev_get_drvdata (pctldev); - mux_bytes = pcs->width /BITS_PER_BYTE ; - offset = pin * mux_bytes; + offset =pcs_pin_reg_offset_get (pcs, pin); val = pcs->read (pcs->base + offset); + +if (pcs->bits_per_mux) + val &= pcs->fmask <<pcs_pin_shift_reg_get (pcs, pin); + pa = pcs->res->start + offset;seq_printf (s,"%zx %08x %s " , pa, val,DRIVER_NAME );
@@ -384,7 +408,6 @@ static int pcs_request_gpio(struct pinctrl_dev *pctldev,struct pcs_device *pcs =pinctrl_dev_get_drvdata (pctldev);struct pcs_gpiofunc_range *frange =NULL ;struct list_head *pos, *tmp; -int mux_bytes =0 ;unsigned data;/* If function mask is null, return directly. */
@@ -392,29 +415,27 @@ static int pcs_request_gpio(struct pinctrl_dev *pctldev,return -ENOTSUPP ;list_for_each_safe (pos, tmp, &pcs->gpiofuncs) { +u32 offset; + frange = list_entry(pos, struct pcs_gpiofunc_range, node);if (pin >= frange->offset + frange->npins || pin < frange->offset)continue ; - mux_bytes = pcs->width /BITS_PER_BYTE ; -if (pcs->bits_per_mux) { -int byte_num, offset, pin_shift; + offset =pcs_pin_reg_offset_get (pcs, pin); - byte_num = (pcs->bits_per_pin * pin) /BITS_PER_BYTE ; - offset = (byte_num / mux_bytes) * mux_bytes; - pin_shift = pin % (pcs->width / pcs->bits_per_pin) * - pcs->bits_per_pin; +if (pcs->bits_per_mux) { +int pin_shift =pcs_pin_shift_reg_get (pcs, pin); data = pcs->read (pcs->base + offset); data &= ~(pcs->fmask << pin_shift); data |= frange->gpiofunc << pin_shift; pcs->write (data, pcs->base + offset); }else { - data = pcs->read (pcs->base + pin * mux_bytes); + data = pcs->read (pcs->base + offset); data &= ~pcs->fmask; data |= frange->gpiofunc; - pcs->write (data, pcs->base + pin * mux_bytes); + pcs->write (data, pcs->base + offset); }break ; }
@@ -726,14 +747,8 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs)for (i =0 ; i < pcs->desc.npins; i++) {unsigned offset;int res; -int byte_num; -if (pcs->bits_per_mux) { - byte_num = (pcs->bits_per_pin * i) /BITS_PER_BYTE ; - offset = (byte_num / mux_bytes) * mux_bytes; - }else { - offset = i * mux_bytes; - } + offset =pcs_pin_reg_offset_get (pcs, i); res =pcs_add_pin (pcs, offset);if (res <0 ) {dev_err (pcs->dev,"error adding pins: %i\n" , res);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 370/530 MIPS: loongson64: fix bug when PAGE_SIZE > 16KB
In reply to Greg Kroah-HartmanFrom: Huang Pei <[email protected]>
[ Upstream commit 509d36a941a3466b78d4377913623d210b162458 ]
When page size larger than 16KB, arguments "vaddr + size(16KB)" in "ioremap_page_range(vaddr, vaddr + size,...)" called by "add_legacy_isa_io" is not page-aligned.
As loongson64 needs at least page size 16KB to get rid of cache alias, and "vaddr" is 64KB-aligned, and 64KB is largest page size supported, rounding "size" up to PAGE_SIZE is enough for all page size supported.
--- arch/mips/loongson64/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/loongson64/init.c +1 -1
@@ -82,7 +82,7 @@ static int __init add_legacy_isa_io(struct fwnode_handle *fwnode, resource_size_return -ENOMEM ; range->fwnode = fwnode; - range->size = size; + range->size = size =round_up (size,PAGE_SIZE ); range->hw_start = hw_start; range->flags =LOGIC_PIO_CPU_MMIO ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 371/530 ASoC: wm8960: Remove bitclk relax condition in wm8960_configure_sysclk
In reply to Greg Kroah-HartmanFrom: Shengjiu Wang <[email protected]>
[ Upstream commit 99067c07e8d877035f6249d194a317c78b7d052d ]
The call sequence in wm8960_configure_clocking is
ret = wm8960_configure_sysclk();
if (ret >= 0)
goto configure_clock;....
ret = wm8960_configure_pll();
configure_clock:
...
wm8960_configure_sysclk is called before wm8960_configure_pll, as there is bitclk relax on both functions, so wm8960_configure_sysclk always return success, then wm8960_configure_pll() never be called.
With this case:
aplay -Dhw:0,0 -d 5 -r 48000 -f S24_LE -c 2 audio48k24b2c.wav the required bitclk is 48000 * 24 * 2 = 2304000, bitclk got from wm8960_configure_sysclk is 3072000, but if go to wm8960_configure_pll. it can get correct bitclk 2304000.
So bitclk relax condition should be removed in wm8960_configure_sysclk, then wm8960_configure_pll can be called, and there is also bitclk relax function in wm8960_configure_pll.
--- sound/soc/codecs/wm8960.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
sound/soc/codecs/wm8960.c +1 -11
@@ -608,10 +608,6 @@ static const int bclk_divs[] = {* - lrclk = sysclk / dac_divs * - 10 * bclk = sysclk / bclk_divs * -* If we cannot find an exact match for (sysclk, lrclk, bclk) -* triplet, we relax the bclk such that bclk is chosen as the -* closest available frequency greater than expected bclk. -* * @wm8960: codec private data * @mclk: MCLK used to derive sysclk * @sysclk_idx: sysclk_divs index for found sysclk
@@ -629,7 +625,7 @@ int wm8960_configure_sysclk(struct wm8960_priv *wm8960, int mclk, {int sysclk, bclk, lrclk;int i, j, k; -int diff, closest = mclk; +int diff;/* marker for no match */ *bclk_idx =-1 ;
@@ -653,12 +649,6 @@ int wm8960_configure_sysclk(struct wm8960_priv *wm8960, int mclk, *bclk_idx = k;break ; } -if (diff >0 && closest > diff) { - *sysclk_idx = i; - *dac_idx = j; - *bclk_idx = k; - closest = diff; - } }if (k !=ARRAY_SIZE (bclk_divs))break ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 372/530 iommu/arm-smmu-v3: add bit field SFM into GERROR_ERR_MASK
In reply to Greg Kroah-HartmanFrom: Zhen Lei <[email protected]>
[ Upstream commit 655c447c97d7fe462e6cd9e15809037be028bc70 ]
In arm_smmu_gerror_handler(), the value of the SMMU_GERROR register is filtered by GERROR_ERR_MASK. However, the GERROR_ERR_MASK does not contain the SFM bit. As a result, the subsequent error processing is not performed when only the SFM error occurs.
--- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +1 -1
@@ -115,7 +115,7 @@#define GERROR_PRIQ_ABT_ERR (1 << 3)#define GERROR_EVTQ_ABT_ERR (1 << 2)#define GERROR_CMDQ_ERR (1 << 0) -#define GERROR_ERR_MASK 0xfd +#define GERROR_ERR_MASK 0x1fd#define ARM_SMMU_GERRORN 0x64
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 373/530 RDMA/mlx5: Fix drop packet rule in egress table
In reply to Greg Kroah-HartmanFrom: Maor Gottlieb <[email protected]>
[ Upstream commit c73700806d4e430d182c2be069d230076818a99a ]
Initial drop action support missed that drop action can be added to egress flow tables as well. Add the missing support.
This requires making sure that dest_type isn't set to PORT which in turn exposes a possibility of passing dst while indicating number of dsts as zero. Explicitly check for number of dsts and pass the appropriate pointer.
--- drivers/infiniband/hw/mlx5/fs.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/infiniband/hw/mlx5/fs.c +5 -4
@@ -1528,8 +1528,8 @@ static struct mlx5_ib_flow_handler *raw_fs_rule_add( dst_num++; } - handler =_create_raw_flow_rule (dev, ft_prio, dst, fs_matcher, - flow_context, flow_act, + handler =_create_raw_flow_rule (dev, ft_prio, dst_num ? dst :NULL , + fs_matcher, flow_context, flow_act, cmd_in, inlen, dst_num);if (IS_ERR (handler)) {
@@ -1885,8 +1885,9 @@ static int get_dests(struct uverbs_attr_bundle *attrs,else *dest_id = mqp->raw_packet_qp.rq.tirn; *dest_type =MLX5_FLOW_DESTINATION_TYPE_TIR ; - }else if (fs_matcher->ns_type ==MLX5_FLOW_NAMESPACE_EGRESS || - fs_matcher->ns_type ==MLX5_FLOW_NAMESPACE_RDMA_TX ) { + }else if ((fs_matcher->ns_type ==MLX5_FLOW_NAMESPACE_EGRESS || + fs_matcher->ns_type ==MLX5_FLOW_NAMESPACE_RDMA_TX ) && + !(*flags &MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DROP )) { *dest_type =MLX5_FLOW_DESTINATION_TYPE_PORT ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 374/530 IB/isert: Fix a use after free in isert_connect_request
In reply to Greg Kroah-HartmanFrom: Lv Yunlong <[email protected]>
[ Upstream commit adb76a520d068a54ee5ca82e756cf8e5a47363a4 ]
The device is got by isert_device_get() with refcount is 1, and is assigned to isert_conn by
isert_conn->device = device.
When isert_create_qp() failed, device will be freed with isert_device_put().
Later, the device is used in isert_free_login_buf(isert_conn) by the isert_conn->device->ib_device statement.
Free the device in the correct order.
--- drivers/infiniband/ulp/isert/ib_isert.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/infiniband/ulp/isert/ib_isert.c +8 -8
@@ -438,23 +438,23 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)isert_init_conn (isert_conn); isert_conn->cm_id = cma_id; - ret =isert_alloc_login_buf (isert_conn, cma_id->device); -if (ret) - goto out; - device =isert_device_get (cma_id);if (IS_ERR (device)) { ret =PTR_ERR (device); - goto out_rsp_dma_map; + goto out; } isert_conn->device = device; + ret =isert_alloc_login_buf (isert_conn, cma_id->device); +if (ret) + goto out_conn_dev; +isert_set_nego_params (isert_conn, &event->param.conn); isert_conn->qp =isert_create_qp (isert_conn, cma_id);if (IS_ERR (isert_conn->qp)) { ret =PTR_ERR (isert_conn->qp); - goto out_conn_dev; + goto out_rsp_dma_map; } ret =isert_login_post_recv (isert_conn);
@@ -473,10 +473,10 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) out_destroy_qp:isert_destroy_qp (isert_conn); -out_conn_dev: -isert_device_put (device); out_rsp_dma_map:isert_free_login_buf (isert_conn); +out_conn_dev: +isert_device_put (device); out:kfree (isert_conn);rdma_reject (cma_id,NULL ,0 ,IB_CM_REJ_CONSUMER_DEFINED );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 375/530 powerpc: Fix HAVE_HARDLOCKUP_DETECTOR_ARCH build configuration
In reply to Greg Kroah-HartmanFrom: Chen Huang <[email protected]>
[ Upstream commit 4fe529449d85e78972fa327999961ecc83a0b6db ]
When compiling the powerpc with the SMP disabled, it shows the issue:
arch/powerpc/kernel/watchdog.c: In function ‘watchdog_smp_panic’:arch/powerpc/kernel/watchdog.c:177:4: error: implicit declaration of function ‘smp_send_nmi_ipi’; did you mean ‘smp_send_stop’? [-Werror=implicit-function-declaration]
177 | smp_send_nmi_ipi(c, wd_lockup_ipi, 1000000);
| ^~~~~~~~~~~~~~~~
| smp_send_stopcc1: all warnings being treated as errors
make[2]: *** [scripts/Makefile.build:273: arch/powerpc/kernel/watchdog.o] Error 1 make[1]: *** [scripts/Makefile.build:534: arch/powerpc/kernel] Error 2
make: *** [Makefile:1980: arch/powerpc] Error 2
make: *** Waiting for unfinished jobs....
We found that powerpc used ipi to implement hardlockup watchdog, so the HAVE_HARDLOCKUP_DETECTOR_ARCH should depend on the SMP.
--- arch/powerpc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/Kconfig +1 -1
@@ -222,7 +222,7 @@ config PPC select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_MOD_ARCH_SPECIFIC select HAVE_NMI if PERF_EVENTS || (PPC64 && PPC_BOOK3S) - select HAVE_HARDLOCKUP_DETECTOR_ARCH if (PPC64 && PPC_BOOK3S) + select HAVE_HARDLOCKUP_DETECTOR_ARCH if PPC64 && PPC_BOOK3S && SMP select HAVE_OPROFILE select HAVE_OPTPROBES if PPC64 select HAVE_PERF_EVENTS
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 376/530 MIPS/bpf: Enable bpf_probe_read{, str}() on MIPS again
In reply to Greg Kroah-HartmanFrom: Tiezhu Yang <[email protected]>
[ Upstream commit 66633abd0642f1e89d26e15f36fb13d3a1c535ff ]
After commit 0ebeea8ca8a4 ("bpf: Restrict bpf_probe_read{, str}() only to archs where they work"), bpf_probe_read{, str}() functions were no longer available on MIPS, so there exist some errors when running bpf program:
root@linux:/home/loongson/bcc# python examples/tracing/task_switch.py bpf: Failed to load program: Invalid argument [...] 11: (85) call bpf_probe_read#4 unknown func bpf_probe_read#4 [...] Exception: Failed to load BPF program count_sched: Invalid argument
ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE should be restricted to archs with non-overlapping address ranges, but they can overlap in EVA mode on MIPS, so select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE if !EVA in arch/mips/Kconfig, otherwise the bpf old helper bpf_probe_read() will not be available.
This is similar with the commit d195b1d1d119 ("powerpc/bpf: Enable bpf_probe_read{, str}() on powerpc again").
--- arch/mips/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/mips/Kconfig +1 -0
@@ -6,6 +6,7 @@ config MIPS select ARCH_BINFMT_ELF_STATE if MIPS_FP_SUPPORT select ARCH_HAS_FORTIFY_SOURCE select ARCH_HAS_KCOV + select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE if !EVA select ARCH_HAS_PTE_SPECIAL if !(32BIT && CPU_HAS_RIXI) select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_UBSAN_SANITIZE_ALL
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 377/530 gpio: guard gpiochip_irqchip_add_domain() with GPIOLIB_IRQCHIP
In reply to Greg Kroah-HartmanFrom: Álvaro Fernández Rojas <[email protected]>
[ Upstream commit 9c7d24693d864f90b27aad5d15fbfe226c02898b ]
The current code doesn't check if GPIOLIB_IRQCHIP is enabled, which results in a compilation error when trying to build gpio-regmap if CONFIG_GPIOLIB_IRQCHIP isn't enabled.
--- include/linux/gpio/driver.h | 9 +++++++++ 1 file changed, 9 insertions(+)
include/linux/gpio/driver.h +9 -0
@@ -637,8 +637,17 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gc,bool gpiochip_irqchip_irq_valid (const struct gpio_chip *gc,unsigned int offset); +#ifdef CONFIG_GPIOLIB_IRQCHIP int gpiochip_irqchip_add_domain (struct gpio_chip *gc,struct irq_domain *domain); +#else +static inline int gpiochip_irqchip_add_domain (struct gpio_chip *gc, +struct irq_domain *domain) +{ +WARN_ON (1 ); +return -EINVAL ; +} +#endif #ifdef CONFIG_LOCKDEP
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 378/530 ALSA: core: remove redundant spin_lock pair in snd_card_disconnect
In reply to Greg Kroah-HartmanFrom: Jia Zhou <[email protected]>
[ Upstream commit abc21649b3e5c34b143bf86f0c78e33d5815e250 ]
modification in commit 2a3f7221acdd ("ALSA: core: Fix card races between register and disconnect") resulting in this problem.
--- sound/core/init.c | 2 -- 1 file changed, 2 deletions(-)
sound/core/init.c +0 -2
@@ -390,10 +390,8 @@ int snd_card_disconnect(struct snd_card *card)return 0 ; } card->shutdown =1 ; -spin_unlock (&card->files_lock);/* replace file->f_op with special dummy operations */ -spin_lock (&card->files_lock);list_for_each_entry (mfile, &card->files_list, list) {/* it's critical part, use endless loop */ /* we have no room to fail */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 379/530 net: phy: lan87xx: fix access to wrong register of LAN87xx
In reply to Greg Kroah-HartmanFrom: Andre Edich <[email protected]>
[ Upstream commit fdb5cc6ab3b6a1c0122d3644a63ef9dc7a610d35 ]
The function lan87xx_config_aneg_ext was introduced to configure LAN95xxA but as well writes to undocumented register of LAN87xx. This fix prevents that access.
The function lan87xx_config_aneg_ext gets more suitable for the new behavior name.
--- drivers/net/phy/smsc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/phy/smsc.c +5 -2
@@ -152,10 +152,13 @@ static int lan87xx_config_aneg(struct phy_device *phydev)return genphy_config_aneg (phydev); } -static int lan87xx_config_aneg_ext (struct phy_device *phydev) +static int lan95xx_config_aneg_ext (struct phy_device *phydev) {int rc; +if (phydev->phy_id !=0x0007c0f0 )/* not (LAN9500A or LAN9505A) */ +return lan87xx_config_aneg (phydev); +/* Extend Manual AutoMDIX timer */ rc =phy_read (phydev,PHY_EDPD_CONFIG );if (rc <0 )
@@ -408,7 +411,7 @@ static struct phy_driver smsc_phy_driver[] = { .read_status = lan87xx_read_status, .config_init = smsc_phy_config_init, .soft_reset = smsc_phy_reset, - .config_aneg = lan87xx_config_aneg_ext, + .config_aneg = lan95xx_config_aneg_ext,/* IRQ related */ .ack_interrupt = smsc_phy_ack_interrupt,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 380/530 udp: never accept GSO_FRAGLIST packets
In reply to Greg Kroah-HartmanFrom: Paolo Abeni <[email protected]>
[ Upstream commit 78352f73dc5047f3f744764cc45912498c52f3c9 ]
Currently the UDP protocol delivers GSO_FRAGLIST packets to the sockets without the expected segmentation.
This change addresses the issue introducing and maintaining a couple of new fields to explicitly accept SKB_GSO_UDP_L4 or GSO_FRAGLIST packets. Additionally updates udp_unexpected_gso() accordingly.
UDP sockets enabling UDP_GRO stil keep accept_udp_fraglist zeroed.
v1 -> v2:
- use 2 bits instead of a whole GSO bitmask (Willem)
--- include/linux/udp.h | 16 +++++++++++++--- net/ipv4/udp.c | 3 +++ 2 files changed, 16 insertions(+), 3 deletions(-)
include/linux/udp.h +13 -3
@@ -51,7 +51,9 @@ struct udp_sock {* different encapsulation layer set * this */ - gro_enabled:1 ;/* Can accept GRO packets */ + gro_enabled:1, /* Request GRO aggregation */ + accept_udp_l4:1, + accept_udp_fraglist:1;/* * Following member retains the information to create a UDP header * when the socket is uncorked.
@@ -131,8 +133,16 @@ static inline void udp_cmsg_recv(struct msghdr *msg, struct sock *sk,static inline bool udp_unexpected_gso (struct sock *sk,struct sk_buff *skb) { -return !udp_sk (sk)->gro_enabled &&skb_is_gso (skb) && -skb_shinfo (skb)->gso_type &SKB_GSO_UDP_L4 ; +if (!skb_is_gso (skb)) +return false; + +if (skb_shinfo (skb)->gso_type &SKB_GSO_UDP_L4 && !udp_sk (sk)->accept_udp_l4) +return true; + +if (skb_shinfo (skb)->gso_type &SKB_GSO_FRAGLIST && !udp_sk (sk)->accept_udp_fraglist) +return true; + +return false; }#define udp_portaddr_for_each_entry (__sk, list) \
net/ipv4/udp.c +3 -0
@@ -2657,9 +2657,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,case UDP_GRO :lock_sock (sk); + +/* when enabling GRO, accept the related GSO packet type */ if (valbool)udp_tunnel_encap_enable (sk->sk_socket); up->gro_enabled = valbool; + up->accept_udp_l4 = valbool;release_sock (sk);break ;
Signature · 1 line
2.30.2
Re: [PATCH 5.10 380/530] udp: never accept GSO_FRAGLIST packets
Hi!
Quoted 7 lines
From: Paolo Abeni <[email protected]>
[ Upstream commit
78352f73dc5047f3f744764cc45912498c52f3c9]Currently the UDP protocol delivers
GSO_FRAGLISTpackets to the sockets without the expected segmentation.
Quoted 7 lines
This change addresses the issue introducing and maintaining a couple of new fields to explicitly accept
SKB_GSO_UDP_L4orGSO_FRAGLISTpackets. Additionally updatesudp_unexpected_gso()accordingly.UDP sockets enabling
UDP_GROstil keepaccept_udp_fraglistzeroed.
What is going on here? accept_udp_fraglist variable is read-only.
Should this be dropped? Should
commit d18931a92a0b5feddd8a39d097b90ae2867db02f
vxlan: allow L4 GRO passthrough
be cherry-picked?
Best regards,
Pavel
Signature · 2 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Re: [PATCH 5.10 380/530] udp: never accept GSO_FRAGLIST packets
Quoted 14 lines · Pavel Machek
Hi!
Quoted 12 lines
From: Paolo Abeni <[email protected]>
[ Upstream commit
78352f73dc5047f3f744764cc45912498c52f3c9]Currently the UDP protocol delivers
GSO_FRAGLISTpackets to the sockets without the expected segmentation.This change addresses the issue introducing and maintaining a couple of new fields to explicitly accept
SKB_GSO_UDP_L4orGSO_FRAGLISTpackets. Additionally updatesudp_unexpected_gso()accordingly.
Quoted 4 lines
Quoted 2 lines
UDP sockets enabling
UDP_GROstil keepaccept_udp_fraglistzeroed.What is going on here?
accept_udp_fraglistvariable is read-only.
Thank you for checking this!
The 'accept_udp_fraglist' field is implicitly initilized to zero at UDP socket allocation time (done by sk_alloc).
So this patch effectively force segmentation of SKB_GSO_FRAGLIST packets via the udp_unexpected_gso() helper.
We introduce the above field instead of unconditionally segmenting SKB_GSO_FRAGLIST, because the next patch will use it (to avoid unneeded segmentation for performance's sake for UDP tunnel), as you noted.
Please let me know if the above clarifies the situation.
Thanks!
Paolo
Re: [PATCH 5.10 380/530] udp: never accept GSO_FRAGLIST packets
Hi!
Quoted 22 lines
Quoted 12 lines
Quoted 12 lines
From: Paolo Abeni <[email protected]>
[ Upstream commit
78352f73dc5047f3f744764cc45912498c52f3c9]Currently the UDP protocol delivers
GSO_FRAGLISTpackets to the sockets without the expected segmentation.This change addresses the issue introducing and maintaining a couple of new fields to explicitly accept
SKB_GSO_UDP_L4orGSO_FRAGLISTpackets. Additionally updatesudp_unexpected_gso()accordingly.Quoted 4 lines
Quoted 2 lines
UDP sockets enabling
UDP_GROstil keepaccept_udp_fraglistzeroed.What is going on here?
accept_udp_fraglistvariable is read-only.Thank you for checking this!
The '
accept_udp_fraglist' field is implicitly initilized to zero at UDP socket allocation time (done bysk_alloc).
Quoted 7 lines
So this patch effectively force segmentation of
SKB_GSO_FRAGLISTpackets via theudp_unexpected_gso()helper.We introduce the above field instead of unconditionally segmenting
SKB_GSO_FRAGLIST, because the next patch will use it (to avoid unneeded segmentation for performance's sake for UDP tunnel), as you noted.
Ok, but there's no follow up patch queued for 5.10...? Do we still need it there?
Best regards,
Pavel
Signature · 2 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Re: [PATCH 5.10 380/530] udp: never accept GSO_FRAGLIST packets
Quoted 25 lines · Pavel Machek
From: Paolo Abeni <[email protected]>
Quoted 24 lines
Quoted 11 lines
Quoted 11 lines
[ Upstream commit
78352f73dc5047f3f744764cc45912498c52f3c9]Currently the UDP protocol delivers
GSO_FRAGLISTpackets to the sockets without the expected segmentation.This change addresses the issue introducing and maintaining a couple of new fields to explicitly accept
SKB_GSO_UDP_L4orGSO_FRAGLISTpackets. Additionally updatesudp_unexpected_gso()accordingly.Quoted 4 lines
Quoted 2 lines
UDP sockets enabling
UDP_GROstil keepaccept_udp_fraglistzeroed.What is going on here?
accept_udp_fraglistvariable is read-only.Thank you for checking this!
The '
accept_udp_fraglist' field is implicitly initilized to zero at UDP socket allocation time (done bysk_alloc).So this patch effectively force segmentation of
SKB_GSO_FRAGLISTpackets via theudp_unexpected_gso()helper.
Quoted 7 lines
Quoted 4 lines
We introduce the above field instead of unconditionally segmenting
SKB_GSO_FRAGLIST, because the next patch will use it (to avoid unneeded segmentation for performance's sake for UDP tunnel), as you noted.Ok, but there's no follow up patch queued for 5.10...? Do we still need it there?
Patch d18931a92a0b5feddd8a39d097b90ae2867db02f is a performance improvement, I think not worthy/suitable for stable.
For 5.10 78352f73dc5047f3f744764cc45912498c52f3c9 should be enough.
Thanks!
Paolo
Greg Kroah-Hartman
maintainerPATCH 381/530 powerpc/pseries: Only register vio drivers if vio bus exists
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
[ Upstream commit 11d92156f7a862091009d7655d19c1e7de37fc7a ]
The vio bus is a fake bus, which we use on pseries LPARs (guests) to discover devices provided by the hypervisor. There's no need or sense in creating the vio bus on bare metal systems.
Which is why commit 4336b9337824 ("powerpc/pseries: Make vio and ibmebus initcalls pseries specific") made the initialisation of the vio bus only happen in LPARs.
However as a result of that commit we now see errors at boot on bare metal systems:
Driver 'hvc_console' was unable to register with bus_type 'vio' because the bus was not initialized. Driver 'tpm_ibmvtpm' was unable to register with bus_type 'vio' because the bus was not initialized.
This happens because those drivers are built-in, and are calling vio_register_driver(). It in turn calls driver_register() with a reference to vio_bus_type, but we haven't registered vio_bus_type with the driver core.
Fix it by also guarding vio_register_driver() with a check to see if we are on pseries.
--- arch/powerpc/platforms/pseries/vio.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/powerpc/platforms/pseries/vio.c +4 -0
@@ -1286,6 +1286,10 @@ static int vio_bus_remove(struct device *dev)int __vio_register_driver (struct vio_driver *viodrv,struct module *owner,const char *mod_name) { +// vio_bus_type is only initialised for pseries +if (!machine_is (pseries)) +return -ENODEV ; +pr_debug ("%s: driver %s registering\n" , __func__, viodrv->name);/* fill in 'struct driver' fields */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 382/530 net/tipc: fix missing destroy_workqueue() on error in tipc_crypto_start()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit ac1db7acea67777be1ba86e36e058c479eab6508 ]
Add the missing destroy_workqueue() before return from tipc_crypto_start() in the error handling case.
--- net/tipc/crypto.c | 2 ++ 1 file changed, 2 insertions(+)
net/tipc/crypto.c +2 -0
@@ -1485,6 +1485,8 @@ int tipc_crypto_start(struct tipc_crypto **crypto, struct net *net,/* Allocate statistic structure */ c->stats = alloc_percpu_gfp(struct tipc_crypto_stats, GFP_ATOMIC);if (!c->stats) { +if (c->wq) +destroy_workqueue (c->wq);kfree_sensitive (c);return -ENOMEM ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 383/530 bug: Remove redundant condition check in report_bug
In reply to Greg Kroah-HartmanFrom: Andrew Scull <[email protected]>
[ Upstream commit 3ad1a6cb0abc63d036fc866bd7c2c5983516dec5 ]
report_bug() will return early if it cannot find a bug corresponding to the provided address. The subsequent test for the bug will always be true so remove it.
--- lib/bug.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-)
lib/bug.c +15 -18
@@ -158,30 +158,27 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) file =NULL ; line =0 ; - warning =0 ; -if (bug) {#ifdef CONFIG_DEBUG_BUGVERBOSE #ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS - file = bug->file; + file = bug->file;#else - file = (const char *)bug + bug->file_disp; + file = (const char *)bug + bug->file_disp;#endif - line = bug->line; + line = bug->line;#endif - warning = (bug->flags &BUGFLAG_WARNING ) !=0 ; - once = (bug->flags &BUGFLAG_ONCE ) !=0 ; - done = (bug->flags &BUGFLAG_DONE ) !=0 ; - -if (warning && once) { -if (done) -return BUG_TRAP_TYPE_WARN ; - -/* -* Since this is the only store, concurrency is not an issue. -*/ - bug->flags |=BUGFLAG_DONE ; - } + warning = (bug->flags &BUGFLAG_WARNING ) !=0 ; + once = (bug->flags &BUGFLAG_ONCE ) !=0 ; + done = (bug->flags &BUGFLAG_DONE ) !=0 ; + +if (warning && once) { +if (done) +return BUG_TRAP_TYPE_WARN ; + +/* +* Since this is the only store, concurrency is not an issue. +*/ + bug->flags |=BUGFLAG_DONE ; }/*
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 384/530 RDMA/core: Fix corrupted SL on passive side
In reply to Greg Kroah-HartmanFrom: Håkon Bugge <[email protected]>
[ Upstream commit 194f64a3cad3ab9e381e996a13089de3215d1887 ]
On RoCE systems, a CM REQ contains a Primary Hop Limit > 1 and Primary Subnet Local is zero.
In cm_req_handler(), the cm_process_routed_req() function is called. Since the Primary Subnet Local value is zero in the request, and since this is RoCE (Primary Local LID is permissive), the following statement will be executed:
IBA_SET(CM_REQ_PRIMARY_SL, req_msg, wc->sl);
This corrupts SL in req_msg if it was different from zero. In other words, a request to setup a connection using an SL != zero, will not be honored, and a connection using SL zero will be created instead.
Fixed by not calling cm_process_routed_req() on RoCE systems, the cm_process_route_req() is only for IB anyhow.
--- drivers/infiniband/core/cm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/infiniband/core/cm.c +2 -1
@@ -2137,7 +2137,8 @@ static int cm_req_handler(struct cm_work *work) goto destroy; } -cm_process_routed_req (req_msg, work->mad_recv_wc->wc); +if (cm_id_priv->av.ah_attr.type !=RDMA_AH_ATTR_TYPE_ROCE ) +cm_process_routed_req (req_msg, work->mad_recv_wc->wc);memset (&work->path[0 ],0 ,sizeof (work->path[0 ]));if (cm_req_has_alt_path (req_msg))
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 385/530 nfc: pn533: prevent potential memory corruption
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit ca4d4c34ae9aa5c3c0da76662c5e549d2fc0cc86 ]
If the "type_a->nfcid_len" is too large then it would lead to memory corruption in pn533_target_found_type_a() when we do:
memcpy(nfc_tgt->nfcid1, tgt_type_a->nfcid_data, nfc_tgt->nfcid1_len);
--- drivers/nfc/pn533/pn533.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/nfc/pn533/pn533.c +3 -0
@@ -706,6 +706,9 @@ static bool pn533_target_type_a_is_valid(struct pn533_target_type_a *type_a,if (PN533_TYPE_A_SEL_CASCADE (type_a->sel_res) !=0 )return false; +if (type_a->nfcid_len >NFC_NFCID1_MAXSIZE ) +return false; +return true; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 386/530 net: hns3: Limiting the scope of vector_ring_chain variable
In reply to Greg Kroah-HartmanFrom: Salil Mehta <[email protected]>
[ Upstream commit d392ecd1bc29ae15b0e284d5f732c2d36f244271 ]
Limiting the scope of the variable vector_ring_chain to the block where it is used.
--- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +2 -1
@@ -3526,7 +3526,6 @@ static void hns3_nic_set_cpumask(struct hns3_nic_priv *priv)static int hns3_nic_init_vector_data (struct hns3_nic_priv *priv) { -struct hnae3_ring_chain_node vector_ring_chain;struct hnae3_handle *h = priv->ae_handle;struct hns3_enet_tqp_vector *tqp_vector;int ret;
@@ -3558,6 +3557,8 @@ static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv) }for (i =0 ; i < priv->vector_num; i++) { +struct hnae3_ring_chain_node vector_ring_chain; + tqp_vector = &priv->tqp_vector[i]; tqp_vector->rx_group.total_bytes =0 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 387/530 mips: bmips: fix syscon-reboot nodes
In reply to Greg Kroah-HartmanFrom: Álvaro Fernández Rojas <[email protected]>
[ Upstream commit cde58b861a1d365568588adda59d42351c0c4ad3 ]
Commit a23c4134955e added the clock controller nodes, incorrectly changing the syscon-reboot nodes addresses.
--- arch/mips/boot/dts/brcm/bcm3368.dtsi | 2 +- arch/mips/boot/dts/brcm/bcm63268.dtsi | 2 +- arch/mips/boot/dts/brcm/bcm6358.dtsi | 2 +- arch/mips/boot/dts/brcm/bcm6362.dtsi | 2 +- arch/mips/boot/dts/brcm/bcm6368.dtsi | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-)
arch/mips/boot/dts/brcm/bcm3368.dtsi +1 -1
@@ -59,7 +59,7 @@ periph_cntl: syscon@fff8c008 { compatible = "syscon"; - reg = <0xfff8c000 0x4>; + reg = <0xfff8c008 0x4>; native-endian; };
arch/mips/boot/dts/brcm/bcm63268.dtsi +1 -1
@@ -59,7 +59,7 @@ periph_cntl: syscon@10000008 { compatible = "syscon"; - reg = <0x10000000 0xc>; + reg = <0x10000008 0x4>; native-endian; };
arch/mips/boot/dts/brcm/bcm6358.dtsi +1 -1
@@ -59,7 +59,7 @@ periph_cntl: syscon@fffe0008 { compatible = "syscon"; - reg = <0xfffe0000 0x4>; + reg = <0xfffe0008 0x4>; native-endian; };
arch/mips/boot/dts/brcm/bcm6362.dtsi +1 -1
@@ -59,7 +59,7 @@ periph_cntl: syscon@10000008 { compatible = "syscon"; - reg = <0x10000000 0xc>; + reg = <0x10000008 0x4>; native-endian; };
arch/mips/boot/dts/brcm/bcm6368.dtsi +1 -1
@@ -59,7 +59,7 @@ periph_cntl: syscon@100000008 { compatible = "syscon"; - reg = <0x10000000 0xc>; + reg = <0x10000008 0x4>; native-endian; };
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 388/530 iommu/vt-d: Dont set then clear private data in prq_event_thread()
In reply to Greg Kroah-HartmanFrom: Lu Baolu <[email protected]>
[ Upstream commit 1d421058c815d54113d9afdf6db3f995c788cf0d ]
The VT-d specification (section 7.6) requires that the value in the Private Data field of a Page Group Response Descriptor must match the value in the Private Data field of the respective Page Request Descriptor.
The private data field of a page group response descriptor is set then immediately cleared in prq_event_thread(). This breaks the rule defined by the VT-d specification. Fix it by moving clearing code up.
--- drivers/iommu/intel/svm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iommu/intel/svm.c +2 -2
@@ -1071,12 +1071,12 @@ no_pasid:QI_PGRP_RESP_TYPE ; resp.qw1 =QI_PGRP_IDX (req->prg_index) |QI_PGRP_LPIG (req->lpig); + resp.qw2 =0 ; + resp.qw3 =0 ;if (req->priv_data_present)memcpy (&resp.qw2, req->priv_data,sizeof (req->priv_data)); - resp.qw2 =0 ; - resp.qw3 =0 ;qi_submit_sync (iommu, &resp,1 ,0 ); } prq_advance:
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 389/530 iommu: Fix a boundary issue to avoid performance drop
In reply to Greg Kroah-HartmanFrom: Xiang Chen <[email protected]>
[ Upstream commit 3431c3f660a39f6ced954548a59dba6541ce3eb1 ]
After the change of patch ("iommu: Switch gather->end to the inclusive end"), the performace drops from 1600+K IOPS to 1200K in our kunpeng ARM64 platform.
We find that the range [start1, end1) actually is joint from the range [end1, end2), but it is considered as disjoint after the change, so it needs more times of TLB sync, and spends more time on it. So fix the boundary issue to avoid performance drop.
--- include/linux/iommu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/iommu.h +1 -1
@@ -544,7 +544,7 @@ static inline void iommu_iotlb_gather_add_page(struct iommu_domain *domain,* structure can be rewritten. */ if (gather->pgsize != size || - end < gather->start || start > gather->end) { + end +1 < gather->start || start > gather->end +1 ) {if (gather->pgsize)iommu_iotlb_sync (domain, gather); gather->pgsize = size;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 390/530 iommu/vt-d: Report right snoop capability when using FL for IOVA
In reply to Greg Kroah-HartmanFrom: Lu Baolu <[email protected]>
[ Upstream commit 6c00612d0cba10f7d0917cf1f73c945003ed4cd7 ]
The Intel VT-d driver checks wrong register to report snoop capablility when using first level page table for GPA to HPA translation. This might lead the IOMMU driver to say that it supports snooping control, but in reality, it does not. Fix this by always setting PASID-table-entry.PGSNP whenever a pasid entry is setting up for GPA to HPA translation so that the IOMMU driver could report snoop capability as long as it runs in the scalable mode.
--- drivers/iommu/intel/iommu.c | 12 +++++++++++- drivers/iommu/intel/pasid.c | 16 ++++++++++++++++ drivers/iommu/intel/pasid.h | 1 + 3 files changed, 28 insertions(+), 1 deletion(-)
drivers/iommu/intel/iommu.c +11 -1
@@ -656,7 +656,14 @@ static int domain_update_iommu_snooping(struct intel_iommu *skip)rcu_read_lock ();for_each_active_iommu (iommu, drhd) {if (iommu != skip) { -if (!ecap_sc_support (iommu->ecap)) { +/* +* If the hardware is operating in the scalable mode, +* the snooping control is always supported since we +* always set PASID-table-entry.PGSNP bit if the domain +* is managed outside (UNMANAGED). +*/ +if (!sm_supported (iommu) && + !ecap_sc_support (iommu->ecap)) { ret =0 ;break ; }
@@ -2599,6 +2606,9 @@ static int domain_setup_first_level(struct intel_iommu *iommu, flags |= (level ==5 ) ?PASID_FLAG_FL5LP :0 ; +if (domain->domain.type ==IOMMU_DOMAIN_UNMANAGED ) + flags |=PASID_FLAG_PAGE_SNOOP ; +return intel_pasid_setup_first_level (iommu, dev, (pgd_t *)pgd, pasid, domain->iommu_did[iommu->seq_id], flags);
drivers/iommu/intel/pasid.c +16 -0
@@ -411,6 +411,16 @@ static inline void pasid_set_page_snoop(struct pasid_entry *pe, bool value)pasid_set_bits (&pe->val[1 ],1 <<23 , value <<23 ); } +/* +* Setup the Page Snoop (PGSNP) field (Bit 88) of a scalable mode +* PASID entry. +*/ +static inline void +pasid_set_pgsnp (struct pasid_entry *pe) +{ +pasid_set_bits (&pe->val[1 ],1ULL <<24 ,1ULL <<24 ); +} +/* * Setup the First Level Page table Pointer field (Bit 140~191) * of a scalable mode PASID entry.
@@ -579,6 +589,9 @@ int intel_pasid_setup_first_level(struct intel_iommu *iommu, } } +if (flags &PASID_FLAG_PAGE_SNOOP ) +pasid_set_pgsnp (pte); +pasid_set_domain_id (pte, did);pasid_set_address_width (pte, iommu->agaw);pasid_set_page_snoop (pte, !!ecap_smpwc (iommu->ecap));
@@ -657,6 +670,9 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,pasid_set_fault_enable (pte);pasid_set_page_snoop (pte, !!ecap_smpwc (iommu->ecap)); +if (domain->domain.type ==IOMMU_DOMAIN_UNMANAGED ) +pasid_set_pgsnp (pte); +/* * Since it is a second level only translation setup, we should * set SRE bit as well (addresses are expected to be GPAs).
drivers/iommu/intel/pasid.h +1 -0
@@ -48,6 +48,7 @@*/ #define PASID_FLAG_SUPERVISOR_MODE BIT(0)#define PASID_FLAG_NESTED BIT(1) +#define PASID_FLAG_PAGE_SNOOP BIT(2)/* * The PASID_FLAG_FL5LP flag Indicates using 5-level paging for first-
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 391/530 iommu/vt-d: Report the right page fault address
In reply to Greg Kroah-HartmanFrom: Lu Baolu <[email protected]>
[ Upstream commit 03d205094af45bca4f8e0498c461a893aa3ec6d9 ]
The Address field of the Page Request Descriptor only keeps bit [63:12] of the offending address. Convert it to a full address before reporting it to device drivers.
--- drivers/iommu/intel/svm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/intel/svm.c +1 -1
@@ -899,7 +899,7 @@ intel_svm_prq_report(struct device *dev, struct page_req_dsc *desc)/* Fill in event data for device specific processing */ memset (&event,0 ,sizeof (struct iommu_fault_event )); event.fault.type =IOMMU_FAULT_PAGE_REQ ; - event.fault.prm.addr = desc->addr; + event.fault.prm.addr = (u64 )desc->addr <<VTD_PAGE_SHIFT ; event.fault.prm.pasid = desc->pasid; event.fault.prm.grpid = desc->prg_index; event.fault.prm.perm =prq_to_iommu_prot (desc);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 392/530 iommu/vt-d: Preset Access/Dirty bits for IOVA over FL
In reply to Greg Kroah-HartmanFrom: Lu Baolu <[email protected]>
[ Upstream commit a8ce9ebbecdfda3322bbcece6b3b25888217f8e3 ]
The Access/Dirty bits in the first level page table entry will be set whenever a page table entry was used for address translation or write permission was successfully translated. This is always true when using the first-level page table for kernel IOVA. Instead of wasting hardware cycles to update the certain bits, it's better to set them up at the beginning.
--- drivers/iommu/intel/iommu.c | 17 ++++++++++++----- include/linux/intel-iommu.h | 2 ++ 2 files changed, 14 insertions(+), 5 deletions(-)
drivers/iommu/intel/iommu.c +12 -5
@@ -1028,8 +1028,11 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,domain_flush_cache (domain, tmp_page,VTD_PAGE_SIZE ); pteval = ((uint64_t )virt_to_dma_pfn (tmp_page) <<VTD_PAGE_SHIFT ) |DMA_PTE_READ |DMA_PTE_WRITE ; -if (domain_use_first_level (domain)) +if (domain_use_first_level (domain)) { pteval |=DMA_FL_PTE_XD |DMA_FL_PTE_US ; +if (domain->domain.type ==IOMMU_DOMAIN_DMA ) + pteval |=DMA_FL_PTE_ACCESS ; + }if (cmpxchg64 (&pte->val,0ULL , pteval))/* Someone else set it while we were thinking; use theirs. */ free_pgtable_page (tmp_page);
@@ -2354,14 +2357,18 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,return -EINVAL ; attr = prot & (DMA_PTE_READ |DMA_PTE_WRITE |DMA_PTE_SNP ); -if (domain_use_first_level (domain)) +if (domain_use_first_level (domain)) { attr |=DMA_FL_PTE_PRESENT |DMA_FL_PTE_XD |DMA_FL_PTE_US ; -if (!sg) { - sg_res = nr_pages; - pteval = ((phys_addr_t )phys_pfn <<VTD_PAGE_SHIFT ) | attr; +if (domain->domain.type ==IOMMU_DOMAIN_DMA ) { + attr |=DMA_FL_PTE_ACCESS ; +if (prot &DMA_PTE_WRITE ) + attr |=DMA_FL_PTE_DIRTY ; + } } + pteval = ((phys_addr_t )phys_pfn <<VTD_PAGE_SHIFT ) | attr; +while (nr_pages >0 ) {uint64_t tmp;
include/linux/intel-iommu.h +2 -0
@@ -42,6 +42,8 @@#define DMA_FL_PTE_PRESENT BIT_ULL(0)#define DMA_FL_PTE_US BIT_ULL(2) +#define DMA_FL_PTE_ACCESS BIT_ULL(5) +#define DMA_FL_PTE_DIRTY BIT_ULL(6)#define DMA_FL_PTE_XD BIT_ULL(63)#define ADDR_WIDTH_5LEVEL (57)
Signature · 1 line
2.30.2
Re: [PATCH 5.10 392/530] iommu/vt-d: Preset Access/Dirty bits for IOVA over FL
Hi!
First of all, apologies if this is the wrong place to post a problem report. I figured since I was going to reference a particular commit anyway I might as well reply to the patch series that (seemed to have) introduced the problem.
Quoted 10 lines
From: Lu Baolu <[email protected]>
[ Upstream commit
a8ce9ebbecdfda3322bbcece6b3b25888217f8e3]The Access/Dirty bits in the first level page table entry will be set whenever a page table entry was used for address translation or write permission was successfully translated. This is always true when using the first-level page table for kernel IOVA. Instead of wasting hardware cycles to update the certain bits, it's better to set them up at the beginning.
This commit seems to trigger a kernel panic very early in boot for me in 5.10.37 (36 is fine):
Call Trace: domain_mapping+0x16/0x90 __iommu_map+0xcd/0x120 iommu_create_device_direct_mappins.isra.0+0x175/0x210 bus_iommu_probe+0x15a/0x290 bus_set_iommu+0x7e/0xd0 intel_iommu_init+0xf84/0x112b ? e820__memblock_setup+0x76/0x76 pci_iommu_init+0x11/0x3a do_one_initcall+0x5a/0x190 kernel_init_freeable+0x140/0x185 ? rest_init+0xa4/0xa4 kernel_init+0x5/0xfc ret_from_fork+0x22/0x30 Modules linked in: CR2: 0000000000000000 ---[ end trace 0904a2a0169baf8a ]-- RIP: 0010:__domain_mapping+0xa1/0x3a0 Code: 02 4d 63 ff 0f 85 1b 02 00 00 4c 89 d3 48 c1 e3 0c 4c 09 fb 4d 85 c0 0f 84 2e 01 00 00 45 31 e4 31 ed 45 31 c9 4d 85 e4 75 58 <49> 8b 5d 00 41 8b 45 08 41 8b 4d 0c 48 83 e3 fc 48 2b 1d 28 8f b8 RSP: 0000:ffffafc54002bc00 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 00000000dd7e4003 RCX: 000000000000002d RDX: 0000000000000000 RSI: 00000000000dd7e4 RDI: ffff8b260108ac00 RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000000 R10: 00000000000dd7e4 R11: ffff8b260108ac00 R12: 0000000000000000 R13: 0000000000000000 R14: 00000000000dd7e4 R15: 0000000000000003 FS: 0000000000000000(0000) GS:ffff8b290ec80000(0000) knlGS: 000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 00000000080050033 CR2: 000000000000000 CR3: 0000000009700c001 CR4: 00000000001706e0 Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
I managed to build the kernel with debug info, and could trace the problem to drivers/iommu/intel/iommu.c:
(gdb) l *__domain_mapping+0xa10xffffffff8146b171 is in __domain_mapping (drivers/iommu/intel/iommu.c:2381).
I then had a look at the commits for v5.10.36..v5.10.37 that touched that file, and on a complete hunch reverted this one (there were only 4, and this one looked the most suspect to my eyes). I could successfully boot into the system again after that.
I'm unsure what other information about my system to include, please advise. Something to note is that I am compiling the 5.10 series with GCC 11 for which I'm manually pulling in the following commits:
1e860048c53ee77ee9870dcce94847a28544b75367a5a68013056cbcf0a647e36cb6f4622fb6a470
I have not yet tried building 5.10.37 with GCC 10 because I already cleaned the old compiler from my system. I don't think the compiler is to blame here, however.
Thanks a lot,
Signature · 1 line
Wolfgang
Re: [PATCH 5.10 392/530] iommu/vt-d: Preset Access/Dirty bits for IOVA over FL
Hi Wolfgang,
Quoted 18 lines · Wolfgang Müller
Hi!
First of all, apologies if this is the wrong place to post a problem report. I figured since I was going to reference a particular commit anyway I might as well reply to the patch series that (seemed to have) introduced the problem.
Quoted 10 lines
From: Lu Baolu <[email protected]>
[ Upstream commit
a8ce9ebbecdfda3322bbcece6b3b25888217f8e3]The Access/Dirty bits in the first level page table entry will be set whenever a page table entry was used for address translation or write permission was successfully translated. This is always true when using the first-level page table for kernel IOVA. Instead of wasting hardware cycles to update the certain bits, it's better to set them up at the beginning.
Quoted 2 lines
This commit seems to trigger a kernel panic very early in boot for me in 5.10.37 (36 is fine):
It seems due to the back-ported patch:
- if (!sg) {
- sg_res = nr_pages;
- pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | attr;
+ if (domain->domain.type == IOMMU_DOMAIN_DMA) {
+ attr |= DMA_FL_PTE_ACCESS;
+ if (prot & DMA_PTE_WRITE)
+ attr |= DMA_FL_PTE_DIRTY;
+ }
}
+ pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | attr;
Greg, do you want me to rework this patch, or submit an incremental fix?
Best regards,
baolu
Sasha Levin
maintainerRe: [PATCH 5.10 392/530] iommu/vt-d: Preset Access/Dirty bits for IOVA over FL
Quoted 38 lines · Lu Baolu
Hi Wolfgang,
Quoted 18 lines · Wolfgang Müller
Hi!
First of all, apologies if this is the wrong place to post a problem report. I figured since I was going to reference a particular commit anyway I might as well reply to the patch series that (seemed to have) introduced the problem.
Quoted 10 lines
From: Lu Baolu <[email protected]>
[ Upstream commit
a8ce9ebbecdfda3322bbcece6b3b25888217f8e3]The Access/Dirty bits in the first level page table entry will be set whenever a page table entry was used for address translation or write permission was successfully translated. This is always true when using the first-level page table for kernel IOVA. Instead of wasting hardware cycles to update the certain bits, it's better to set them up at the beginning.
Quoted 2 lines
This commit seems to trigger a kernel panic very early in boot for me in 5.10.37 (36 is fine):
It seems due to the back-ported patch:
drivers/iommu/intel/iommu.c +5
-3-if (!sg) { - sg_res = nr_pages; - pteval = ((phys_addr_t )phys_pfn <<VTD_PAGE_SHIFT ) | attr; +if (domain->domain.type ==IOMMU_DOMAIN_DMA ) { + attr |=DMA_FL_PTE_ACCESS ; +if (prot &DMA_PTE_WRITE ) + attr |=DMA_FL_PTE_DIRTY ; + }}drivers/iommu/intel/iommu.c +1
-0+ pteval = ((phys_addr_t )phys_pfn <<VTD_PAGE_SHIFT ) | attr;
Quoted 1 line
Greg, do you want me to rework this patch, or submit an incremental fix?
Could you send a reworked patch please?
Signature · 2 lines
Thanks, Sasha
Greg Kroah-Hartman
maintainerPATCH 393/530 iommu/vt-d: Remove WO permissions on second-level paging entries
In reply to Greg Kroah-HartmanFrom: Lu Baolu <[email protected]>
[ Upstream commit eea53c5816889ee8b64544fa2e9311a81184ff9c ]
When the first level page table is used for IOVA translation, it only supports Read-Only and Read-Write permissions. The Write-Only permission is not supported as the PRESENT bit (implying Read permission) should always set. When using second level, we still give separate permissions that allows WriteOnly which seems inconsistent and awkward. We want to have consistent behavior. After moving to 1st level, we don't want things to work sometimes, and break if we use 2nd level for the same mappings. Hence remove this configuration.
--- drivers/iommu/intel/iommu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/iommu/intel/iommu.c +2 -1
@@ -2357,8 +2357,9 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,return -EINVAL ; attr = prot & (DMA_PTE_READ |DMA_PTE_WRITE |DMA_PTE_SNP ); + attr |=DMA_FL_PTE_PRESENT ;if (domain_use_first_level (domain)) { - attr |=DMA_FL_PTE_PRESENT |DMA_FL_PTE_XD |DMA_FL_PTE_US ; + attr |=DMA_FL_PTE_XD |DMA_FL_PTE_US ;if (domain->domain.type ==IOMMU_DOMAIN_DMA ) { attr |=DMA_FL_PTE_ACCESS ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 394/530 iommu/vt-d: Invalidate PASID cache when root/context entry changed
In reply to Greg Kroah-HartmanFrom: Lu Baolu <[email protected]>
[ Upstream commit c0474a606ecb9326227b4d68059942f9db88a897 ]
When the Intel IOMMU is operating in the scalable mode, some information from the root and context table may be used to tag entries in the PASID cache. Software should invalidate the PASID-cache when changing root or context table entries.
--- drivers/iommu/intel/iommu.c | 18 +++++++++--------- include/linux/intel-iommu.h | 1 + 2 files changed, 10 insertions(+), 9 deletions(-)
drivers/iommu/intel/iommu.c +9 -9
@@ -1348,6 +1348,11 @@ static void iommu_set_root_entry(struct intel_iommu *iommu) readl, (sts & DMA_GSTS_RTPS), sts);raw_spin_unlock_irqrestore (&iommu->register_lock, flag); + + iommu->flush.flush_context (iommu,0 ,0 ,0 ,DMA_CCMD_GLOBAL_INVL ); +if (sm_supported (iommu)) +qi_flush_pasid_cache (iommu,0 ,QI_PC_GLOBAL ,0 ); + iommu->flush.flush_iotlb (iommu,0 ,0 ,0 ,DMA_TLB_GLOBAL_FLUSH ); }void iommu_flush_write_buffer (struct intel_iommu *iommu)
@@ -2521,6 +2526,10 @@ static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn (((u16 )bus) <<8 ) | devfn,DMA_CCMD_MASK_NOBIT , DMA_CCMD_DEVICE_INVL); + +if (sm_supported (iommu)) +qi_flush_pasid_cache (iommu, did_old,QI_PC_ALL_PASIDS ,0 ); + iommu->flush.flush_iotlb(iommu, did_old, 0,
@@ -3387,8 +3396,6 @@ static int __init init_dmars(void)register_pasid_allocator (iommu);#endif iommu_set_root_entry (iommu); - iommu->flush.flush_context (iommu,0 ,0 ,0 ,DMA_CCMD_GLOBAL_INVL ); - iommu->flush.flush_iotlb (iommu,0 ,0 ,0 ,DMA_TLB_GLOBAL_FLUSH ); }#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
@@ -4166,12 +4173,7 @@ static int init_iommu_hw(void) }iommu_flush_write_buffer (iommu); -iommu_set_root_entry (iommu); - - iommu->flush.flush_context (iommu,0 ,0 ,0 , -DMA_CCMD_GLOBAL_INVL ); - iommu->flush.flush_iotlb (iommu,0 ,0 ,0 ,DMA_TLB_GLOBAL_FLUSH );iommu_enable_translation (iommu);iommu_disable_protect_mem_regions (iommu); }
@@ -4499,8 +4501,6 @@ static int intel_iommu_add(struct dmar_drhd_unit *dmaru) goto disable_iommu;iommu_set_root_entry (iommu); - iommu->flush.flush_context (iommu,0 ,0 ,0 ,DMA_CCMD_GLOBAL_INVL ); - iommu->flush.flush_iotlb (iommu,0 ,0 ,0 ,DMA_TLB_GLOBAL_FLUSH );iommu_enable_translation (iommu);iommu_disable_protect_mem_regions (iommu);
include/linux/intel-iommu.h +1 -0
@@ -369,6 +369,7 @@ enum {/* PASID cache invalidation granu */ #define QI_PC_ALL_PASIDS 0#define QI_PC_PASID_SEL 1 +#define QI_PC_GLOBAL 3#define QI_EIOTLB_ADDR (addr) ((u64)(addr) & VTD_PAGE_MASK)#define QI_EIOTLB_IH (ih) (((u64)ih) << 6)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 395/530 ALSA: usb-audio: Add error checks for usb_driver_claim_interface() calls
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
[ Upstream commit 5fb45414ae03421255593fd5556aa2d1d82303aa ]
There are a few calls of usb_driver_claim_interface() but all of those miss the proper error checks, as reported by Coverity. This patch adds those missing checks.
Along with it, replace the magic pointer with -1 with a constant USB_AUDIO_IFACE_UNUSED for better readability.
Addresses-Coverity-ID: 1475943 ("Error handling issues")
Addresses-Coverity-ID: 1475944 ("Error handling issues")
Addresses-Coverity-ID: 1475945 ("Error handling issues")
--- sound/usb/card.c | 14 +++++++------- sound/usb/quirks.c | 16 ++++++++++++---- sound/usb/usbaudio.h | 2 ++ 3 files changed, 21 insertions(+), 11 deletions(-)
sound/usb/card.c +7 -7
@@ -182,9 +182,8 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int ctrlif, interface);return -EINVAL ; } -usb_driver_claim_interface (&usb_audio_driver, iface, (void *)-1L ); - -return 0 ; +return usb_driver_claim_interface (&usb_audio_driver, iface, +USB_AUDIO_IFACE_UNUSED ); } if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
@@ -204,7 +203,8 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int intif (!snd_usb_parse_audio_interface (chip, interface)) {usb_set_interface (dev, interface,0 );/* reset the current interface */ -usb_driver_claim_interface (&usb_audio_driver, iface, (void *)-1L ); +return usb_driver_claim_interface (&usb_audio_driver, iface, +USB_AUDIO_IFACE_UNUSED ); }return 0 ;
@@ -864,7 +864,7 @@ static void usb_audio_disconnect(struct usb_interface *intf)struct snd_card *card;struct list_head *p; -if (chip == (void *)-1L ) +if (chip ==USB_AUDIO_IFACE_UNUSED )return ; card = chip->card;
@@ -993,7 +993,7 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)struct usb_mixer_interface *mixer;struct list_head *p; -if (chip == (void *)-1L ) +if (chip ==USB_AUDIO_IFACE_UNUSED )return 0 ;if (!chip->num_suspended_intf++) {
@@ -1024,7 +1024,7 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)struct list_head *p;int err =0 ; -if (chip == (void *)-1L ) +if (chip ==USB_AUDIO_IFACE_UNUSED )return 0 ;atomic_inc (&chip->active);/* avoid autopm */
sound/usb/quirks.c +12 -4
@@ -55,8 +55,12 @@ static int create_composite_quirk(struct snd_usb_audio *chip,if (!iface)continue ;if (quirk->ifnum != probed_ifnum && - !usb_interface_claimed (iface)) -usb_driver_claim_interface (driver, iface, (void *)-1L ); + !usb_interface_claimed (iface)) { + err =usb_driver_claim_interface (driver, iface, +USB_AUDIO_IFACE_UNUSED ); +if (err <0 ) +return err; + } }return 0 ;
@@ -390,8 +394,12 @@ static int create_autodetect_quirks(struct snd_usb_audio *chip,continue ; err =create_autodetect_quirk (chip, iface, driver); -if (err >=0 ) -usb_driver_claim_interface (driver, iface, (void *)-1L ); +if (err >=0 ) { + err =usb_driver_claim_interface (driver, iface, +USB_AUDIO_IFACE_UNUSED ); +if (err <0 ) +return err; + } }return 0 ;
sound/usb/usbaudio.h +2 -0
@@ -63,6 +63,8 @@ struct snd_usb_audio {struct media_intf_devnode *ctl_intf_media_devnode; }; +#define USB_AUDIO_IFACE_UNUSED ((void *)-1L) + #define usb_audio_err(chip, fmt, args...) \ dev_err(&(chip)->dev->dev, fmt, ##args) #define usb_audio_warn(chip, fmt, args...) \
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 396/530 HID: lenovo: Use brightness_set_blocking callback for setting LEDs brightness
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit bbf62645255f120bc2e7488c237e3f04da42ec70 ]
The lenovo_led_brightness_set function may sleep, so we should have the the led_class_dev's brightness_set_blocking callback point to it, rather then the regular brightness_set callback.
When toggled through sysfs this is not a problem, but the brightness_set callback may be called from atomic context when using LED-triggers.
--- drivers/hid/hid-lenovo.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/hid/hid-lenovo.c +5 -3
@@ -777,7 +777,7 @@ static enum led_brightness lenovo_led_brightness_get( : LED_OFF; } -static void lenovo_led_brightness_set (struct led_classdev *led_cdev, +static int lenovo_led_brightness_set (struct led_classdev *led_cdev,enum led_brightness value) {struct device *dev = led_cdev->dev->parent;
@@ -802,6 +802,8 @@ static void lenovo_led_brightness_set(struct led_classdev *led_cdev,lenovo_led_set_tp10ubkbd (hdev, tp10ubkbd_led[led_nr], value);break ; } + +return 0 ; }static int lenovo_register_leds (struct hid_device *hdev)
@@ -822,7 +824,7 @@ static int lenovo_register_leds(struct hid_device *hdev) data->led_mute.name = name_mute; data->led_mute.brightness_get = lenovo_led_brightness_get; - data->led_mute.brightness_set = lenovo_led_brightness_set; + data->led_mute.brightness_set_blocking = lenovo_led_brightness_set; data->led_mute.dev = &hdev->dev; ret =led_classdev_register (&hdev->dev, &data->led_mute);if (ret <0 )
@@ -830,7 +832,7 @@ static int lenovo_register_leds(struct hid_device *hdev) data->led_micmute.name = name_micm; data->led_micmute.brightness_get = lenovo_led_brightness_get; - data->led_micmute.brightness_set = lenovo_led_brightness_set; + data->led_micmute.brightness_set_blocking = lenovo_led_brightness_set; data->led_micmute.dev = &hdev->dev; ret =led_classdev_register (&hdev->dev, &data->led_micmute);if (ret <0 ) {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 397/530 HID: lenovo: Fix lenovo_led_set_tp10ubkbd() error handling
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit 658d04e6eb6be1601ae95d7bee92bbf4096cdc1e ]
Fix the following issues with lenovo_led_set_tp10ubkbd() error handling:
1. On success hid_hw_raw_request() returns the number of bytes sent. So we should check for (ret != 3) rather then for (ret != 0).
2. Actually propagate errors to the caller.
3. Since the LEDs are part of an USB keyboard-dock the mute LEDs can go away at any time. Don't log an error when ret == -ENODEV and set the LED_HW_PLUGGABLE flag to avoid errors getting logged when the USB gets disconnected.
--- drivers/hid/hid-lenovo.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-)
drivers/hid/hid-lenovo.c +21 -8
@@ -62,8 +62,8 @@ struct lenovo_drvdata {#define TP10UBKBD_LED_OFF 1#define TP10UBKBD_LED_ON 2 -static void lenovo_led_set_tp10ubkbd (struct hid_device *hdev,u8 led_code, -enum led_brightness value) +static int lenovo_led_set_tp10ubkbd (struct hid_device *hdev,u8 led_code, +enum led_brightness value) {struct lenovo_drvdata *data =hid_get_drvdata (hdev);int ret;
@@ -75,10 +75,18 @@ static void lenovo_led_set_tp10ubkbd(struct hid_device *hdev, u8 led_code, data->led_report[2 ] = value ?TP10UBKBD_LED_ON :TP10UBKBD_LED_OFF ; ret =hid_hw_raw_request (hdev, data->led_report[0 ], data->led_report,3 ,HID_OUTPUT_REPORT ,HID_REQ_SET_REPORT ); -if (ret) -hid_err (hdev,"Set LED output report error: %d\n" , ret); +if (ret !=3 ) { +if (ret != -ENODEV ) +hid_err (hdev,"Set LED output report error: %d\n" , ret); + + ret = ret <0 ? ret : -EIO ; + }else { + ret =0 ; + }mutex_unlock (&data->led_report_mutex); + +return ret; }static void lenovo_tp10ubkbd_sync_fn_lock (struct work_struct *work)
@@ -349,7 +357,7 @@ static ssize_t attr_fn_lock_store(struct device *dev, {struct hid_device *hdev =to_hid_device (dev);struct lenovo_drvdata *data =hid_get_drvdata (hdev); -int value; +int value, ret;if (kstrtoint (buf,10 , &value))return -EINVAL ;
@@ -364,7 +372,9 @@ static ssize_t attr_fn_lock_store(struct device *dev,lenovo_features_set_cptkbd (hdev);break ;case USB_DEVICE_ID_LENOVO_TP10UBKBD : -lenovo_led_set_tp10ubkbd (hdev,TP10UBKBD_FN_LOCK_LED , value); + ret =lenovo_led_set_tp10ubkbd (hdev,TP10UBKBD_FN_LOCK_LED , value); +if (ret) +return ret;break ; }
@@ -785,6 +795,7 @@ static int lenovo_led_brightness_set(struct led_classdev *led_cdev,struct lenovo_drvdata *data_pointer =hid_get_drvdata (hdev);u8 tp10ubkbd_led[] = {TP10UBKBD_MUTE_LED ,TP10UBKBD_MICMUTE_LED };int led_nr =0 ; +int ret =0 ;if (led_cdev == &data_pointer->led_micmute) led_nr =1 ;
@@ -799,11 +810,11 @@ static int lenovo_led_brightness_set(struct led_classdev *led_cdev,lenovo_led_set_tpkbd (hdev);break ;case USB_DEVICE_ID_LENOVO_TP10UBKBD : -lenovo_led_set_tp10ubkbd (hdev, tp10ubkbd_led[led_nr], value); + ret =lenovo_led_set_tp10ubkbd (hdev, tp10ubkbd_led[led_nr], value);break ; } -return 0 ; +return ret; }static int lenovo_register_leds (struct hid_device *hdev)
@@ -825,6 +836,7 @@ static int lenovo_register_leds(struct hid_device *hdev) data->led_mute.name = name_mute; data->led_mute.brightness_get = lenovo_led_brightness_get; data->led_mute.brightness_set_blocking = lenovo_led_brightness_set; + data->led_mute.flags =LED_HW_PLUGGABLE ; data->led_mute.dev = &hdev->dev; ret =led_classdev_register (&hdev->dev, &data->led_mute);if (ret <0 )
@@ -833,6 +845,7 @@ static int lenovo_register_leds(struct hid_device *hdev) data->led_micmute.name = name_micm; data->led_micmute.brightness_get = lenovo_led_brightness_get; data->led_micmute.brightness_set_blocking = lenovo_led_brightness_set; + data->led_micmute.flags =LED_HW_PLUGGABLE ; data->led_micmute.dev = &hdev->dev; ret =led_classdev_register (&hdev->dev, &data->led_micmute);if (ret <0 ) {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 398/530 HID: lenovo: Check hid_get_drvdata() returns non NULL in lenovo_event()
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit 34348a8661e3cd67dcf6938f08c8bb77522301f7 ]
The HID lenovo probe function only attaches drvdata to one of the USB interfaces, but lenovo_event() will get called for all USB interfaces to which hid-lenovo is bound.
This allows a malicious device to fake being a device handled by hid-lenovo, which generates events for which lenovo_event() has special handling (and thus dereferences hid_get_drvdata()) on another interface triggering a NULL pointer exception.
Add a check for hid_get_drvdata() returning NULL, avoiding this possible NULL pointer exception.
--- drivers/hid/hid-lenovo.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/hid/hid-lenovo.c +3 -0
@@ -508,6 +508,9 @@ static int lenovo_event_cptkbd(struct hid_device *hdev,static int lenovo_event (struct hid_device *hdev,struct hid_field *field,struct hid_usage *usage,__s32 value) { +if (!hid_get_drvdata (hdev)) +return 0 ; +switch (hdev->product) {case USB_DEVICE_ID_LENOVO_CUSBKBD :case USB_DEVICE_ID_LENOVO_CBTKBD :
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 399/530 HID: lenovo: Map mic-mute button to KEY_F20 instead of KEY_MICMUTE
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit 617103246cfd19af837e4cb614ba9f877c4f7779 ]
Mapping the mic-mute button to KEY_MICMUTE is technically correct but KEY_MICMUTE translates to a scancode of 256 (248 + 8) under X, which does not fit in 8 bits, so it does not work.
Because of this userspace is expecting KEY_F20 instead, theoretically KEY_MICMUTE should work under Wayland but even there it does not work, because the desktop-environment is listening only for KEY_F20 and not for KEY_MICMUTE.
--- drivers/hid/hid-lenovo.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/hid/hid-lenovo.c +6 -3
@@ -33,6 +33,9 @@#include "hid-ids.h" +/* Userspace expects F20 for mic-mute KEY_MICMUTE does not work */ +#define LENOVO_KEY_MICMUTE KEY_F20 +struct lenovo_drvdata {u8 led_report[3 ];/* Must be first for proper alignment */ int led_state;
@@ -134,7 +137,7 @@ static int lenovo_input_mapping_tpkbd(struct hid_device *hdev,if (usage->hid == (HID_UP_BUTTON |0x0010 )) {/* This sub-device contains trackpoint, mark it */ hid_set_drvdata (hdev, (void *)1 ); -map_key_clear (KEY_MICMUTE ); +map_key_clear (LENOVO_KEY_MICMUTE );return 1 ; }return 0 ;
@@ -149,7 +152,7 @@ static int lenovo_input_mapping_cptkbd(struct hid_device *hdev, (usage->hid & HID_USAGE_PAGE) == HID_UP_LNVENDOR) {switch (usage->hid &HID_USAGE ) {case 0x00f1 :/* Fn-F4: Mic mute */ -map_key_clear (KEY_MICMUTE ); +map_key_clear (LENOVO_KEY_MICMUTE );return 1 ;case 0x00f2 :/* Fn-F5: Brightness down */ map_key_clear (KEY_BRIGHTNESSDOWN );
@@ -239,7 +242,7 @@ static int lenovo_input_mapping_tp10_ultrabook_kbd(struct hid_device *hdev,map_key_clear (KEY_FN_ESC );return 1 ;case 9 :/* Fn-F4: Mic mute */ -map_key_clear (KEY_MICMUTE ); +map_key_clear (LENOVO_KEY_MICMUTE );return 1 ;case 10 :/* Fn-F7: Control panel */ map_key_clear (KEY_CONFIG );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 400/530 KVM: arm64: Initialize VCPU mdcr_el2 before loading it
In reply to Greg Kroah-HartmanFrom: Alexandru Elisei <[email protected]>
[ Upstream commit 263d6287da1433aba11c5b4046388f2cdf49675c ]
When a VCPU is created, the kvm_vcpu struct is initialized to zero in kvm_vm_ioctl_create_vcpu(). On VHE systems, the first time vcpu.arch.mdcr_el2 is loaded on hardware is in vcpu_load(), before it is set to a sensible value in kvm_arm_setup_debug() later in the run loop. The result is that KVM executes for a short time with MDCR_EL2 set to zero.
This has several unintended consequences:
* Setting MDCR_EL2.HPMN to 0 is constrained unpredictable according to ARM DDI 0487G.a, page D13-3820. The behavior specified by the architecture in this case is for the PE to behave as if MDCR_EL2.HPMN is set to a value less than or equal to PMCR_EL0.N, which means that an unknown number of counters are now disabled by MDCR_EL2.HPME, which is zero.
* The host configuration for the other debug features controlled by MDCR_EL2 is temporarily lost. This has been harmless so far, as Linux doesn't use the other fields, but that might change in the future.
Let's avoid both issues by initializing the VCPU's mdcr_el2 field in kvm_vcpu_vcpu_first_run_init(), thus making sure that the MDCR_EL2 register has a consistent value after each vcpu_load().
--- arch/arm64/include/asm/kvm_host.h | 1 + arch/arm64/kvm/arm.c | 2 + arch/arm64/kvm/debug.c | 88 +++++++++++++++++++++---------- 3 files changed, 63 insertions(+), 28 deletions(-)
arch/arm64/include/asm/kvm_host.h +1 -0
@@ -601,6 +601,7 @@ static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}static inline void kvm_arch_vcpu_block_finish (struct kvm_vcpu *vcpu) {}void kvm_arm_init_debug (void ); +void kvm_arm_vcpu_init_debug (struct kvm_vcpu *vcpu);void kvm_arm_setup_debug (struct kvm_vcpu *vcpu);void kvm_arm_clear_debug (struct kvm_vcpu *vcpu);void kvm_arm_reset_debug_ptr (struct kvm_vcpu *vcpu);
arch/arm64/kvm/arm.c +2 -0
@@ -547,6 +547,8 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) vcpu->arch.has_run_once = true; +kvm_arm_vcpu_init_debug (vcpu); +if (likely (irqchip_in_kernel (kvm))) {/* * Map the VGIC hardware resources before running a vcpu the
arch/arm64/kvm/debug.c +60 -28
131 lines not on this page · raw message
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 401/530 ASoC: simple-card: fix possible uninitialized single_cpu local variable
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
[ Upstream commit fa74c223b6fd78a5314b4c61b9abdbed3c2185b4 ]
The 'single_cpu' local variable is assigned by asoc_simple_parse_dai() and later used in a asoc_simple_canonicalize_cpu() call, assuming the entire function did not exit on errors.
However the first function returns 0 if passed device_node is NULL, thus leaving the variable uninitialized and reporting success.
Addresses-Coverity: Uninitialized scalar variable
--- sound/soc/generic/audio-graph-card.c | 2 +- sound/soc/generic/simple-card.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
sound/soc/generic/audio-graph-card.c +1 -1
@@ -340,7 +340,7 @@ static int graph_dai_link_of(struct asoc_simple_priv *priv,struct device_node *top = dev->of_node;struct asoc_simple_dai *cpu_dai;struct asoc_simple_dai *codec_dai; -int ret, single_cpu; +int ret, single_cpu =0 ;/* Do it only CPU turn */ if (!li->cpu)
sound/soc/generic/simple-card.c +1 -1
@@ -258,7 +258,7 @@ static int simple_dai_link_of(struct asoc_simple_priv *priv,struct device_node *plat =NULL ;char prop[128 ];char *prefix ="" ; -int ret, single_cpu; +int ret, single_cpu =0 ;/* * |CPU |Codec : turn
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 402/530 liquidio: Fix unintented sign extension of a left shift of a u16
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 298b58f00c0f86868ea717426beb5c1198772f81 ]
The macro CN23XX_PEM_BAR1_INDEX_REG is being used to shift oct->pcie_port (a u16) left 24 places. There are two subtle issues here, first the shift gets promoted to an signed int and then sign extended to a u64. If oct->pcie_port is 0x80 or more then the upper bits get sign extended to 1. Secondly shfiting a u16 24 bits will lead to an overflow so it needs to be cast to a u64 for all the bits to not overflow.
It is entirely possible that the u16 port value is never large enough for this to fail, but it is useful to fix unintended overflows such as this.
Fix this by casting the port parameter to the macro to a u64 before the shift.
Addresses-Coverity: ("Unintended sign extension")
--- drivers/net/ethernet/cavium/liquidio/cn23xx_pf_regs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/cavium/liquidio/cn23xx_pf_regs.h +1 -1
@@ -521,7 +521,7 @@#define CN23XX_BAR1_INDEX_OFFSET 3#define CN23XX_PEM_BAR1_INDEX_REG (port, idx) \ - (CN23XX_PEM_BAR1_INDEX_START + ((port) << CN23XX_PEM_OFFSET) + \ + (CN23XX_PEM_BAR1_INDEX_START + (((u64)port) << CN23XX_PEM_OFFSET) + \ ((idx) << CN23XX_BAR1_INDEX_OFFSET))/*############################ DPI #########################*/
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 403/530 IB/hfi1: Use kzalloc() for mmu_rb_handler allocation
In reply to Greg Kroah-HartmanFrom: Mike Marciniszyn <[email protected]>
[ Upstream commit ca5f72568e034e1295a7ae350b1f786fcbfb2848 ]
The code currently assumes that the mmu_notifier struct embedded in mmu_rb_handler only contains two fields.
There are now extra fields:
struct mmu_notifier {
struct hlist_node hlist;
const struct mmu_notifier_ops *ops;
struct mm_struct *mm;
struct rcu_head rcu;
unsigned int users;
};Given that there in no init for the mmu_notifier, a kzalloc() should be used to insure that any newly added fields are given a predictable initial value of zero.
--- drivers/infiniband/hw/hfi1/mmu_rb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/hfi1/mmu_rb.c +1 -1
@@ -89,7 +89,7 @@ int hfi1_mmu_rb_register(void *ops_arg,struct mmu_rb_handler *h;int ret; - h =kmalloc (sizeof (*h),GFP_KERNEL ); + h =kzalloc (sizeof (*h),GFP_KERNEL );if (!h)return -ENOMEM ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 404/530 powerpc/64s: Fix pte update for kernel memory on radix
In reply to Greg Kroah-HartmanFrom: Jordan Niethe <[email protected]>
[ Upstream commit b8b2f37cf632434456182e9002d63cbc4cccc50c ]
When adding a PTE a ptesync is needed to order the update of the PTE with subsequent accesses otherwise a spurious fault may be raised.
radix__set_pte_at() does not do this for performance gains. For non-kernel memory this is not an issue as any faults of this kind are corrected by the page fault handler. For kernel memory these faults are not handled. The current solution is that there is a ptesync in flush_cache_vmap() which should be called when mapping from the vmalloc region.
However, map_kernel_page() does not call flush_cache_vmap(). This is troublesome in particular for code patching with Strict RWX on radix. In do_patch_instruction() the page frame that contains the instruction to be patched is mapped and then immediately patched. With no ordering or synchronization between setting up the PTE and writing to the page it is possible for faults.
As the code patching is done using __put_user_asm_goto() the resulting fault is obscured - but using a normal store instead it can be seen:
BUG: Unable to handle kernel data access on write at 0xc008000008f24a3c Faulting instruction address: 0xc00000000008bd74 Oops: Kernel access of bad area, sig: 11 [#1] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV Modules linked in: nop_module(PO+) [last unloaded: nop_module] CPU: 4 PID: 757 Comm: sh Tainted: P O 5.10.0-rc5-01361-ge3c1b78c8440-dirty #43 NIP: c00000000008bd74 LR: c00000000008bd50 CTR: c000000000025810 REGS: c000000016f634a0 TRAP: 0300 Tainted: P O (5.10.0-rc5-01361-ge3c1b78c8440-dirty) MSR: 9000000000009033 <SF,HV,EE,ME,IR,DR,RI,LE> CR: 44002884 XER: 00000000 CFAR: c00000000007c68c DAR: c008000008f24a3c DSISR: 42000000 IRQMASK: 1
This results in the kind of issue reported here:
https://lore.kernel.org/linuxppc-dev/[email protected]/
Chris Riedl suggested a reliable way to reproduce the issue:
$ mount -t debugfs none /sys/kernel/debug $ (while true; do echo function > /sys/kernel/debug/tracing/current_tracer ; echo nop > /sys/kernel/debug/tracing/current_tracer ; done) &
Turning ftrace on and off does a large amount of code patching which in usually less then 5min will crash giving a trace like:
ftrace-powerpc: (____ptrval____): replaced (4b473b11) != old (60000000) ------------[ ftrace bug ]------------
ftrace failed to modify
[<c000000000bf8e5c>] napi_busy_loop+0xc/0x390
actual: 11:3b:47:4b
Setting ftrace call site to call ftrace function
ftrace record flags: 80000001
(1)
expected tramp: c00000000006c96c
------------[ cut here ]------------
WARNING: CPU: 4 PID: 809 at kernel/trace/ftrace.c:2065 ftrace_bug+0x28c/0x2e8
Modules linked in: nop_module(PO-) [last unloaded: nop_module]
CPU: 4 PID: 809 Comm: sh Tainted: P O 5.10.0-rc5-01360-gf878ccaf250a #1
NIP: c00000000024f334 LR: c00000000024f330 CTR: c0000000001a5af0
REGS: c000000004c8b760 TRAP: 0700 Tainted: P O (5.10.0-rc5-01360-gf878ccaf250a)
MSR: 900000000282b033 <SF,HV,VEC,VSX,EE,FP,ME,IR,DR,RI,LE> CR: 28008848 XER: 20040000
CFAR: c0000000001a9c98 IRQMASK: 0
GPR00: c00000000024f330 c000000004c8b9f0 c000000002770600 0000000000000022
GPR04: 00000000ffff7fff c000000004c8b6d0 0000000000000027 c0000007fe9bcdd8
GPR08: 0000000000000023 ffffffffffffffd8 0000000000000027 c000000002613118
GPR12: 0000000000008000 c0000007fffdca00 0000000000000000 0000000000000000
GPR16: 0000000023ec37c5 0000000000000000 0000000000000000 0000000000000008
GPR20: c000000004c8bc90 c0000000027a2d20 c000000004c8bcd0 c000000002612fe8
GPR24: 0000000000000038 0000000000000030 0000000000000028 0000000000000020
GPR28: c000000000ff1b68 c000000000bf8e5c c00000000312f700 c000000000fbb9b0
NIP ftrace_bug+0x28c/0x2e8
LR ftrace_bug+0x288/0x2e8
Call Trace:
ftrace_bug+0x288/0x2e8 (unreliable)
ftrace_modify_all_code+0x168/0x210
arch_ftrace_update_code+0x18/0x30
ftrace_run_update_code+0x44/0xc0
ftrace_startup+0xf8/0x1c0
register_ftrace_function+0x4c/0xc0
function_trace_init+0x80/0xb0
tracing_set_tracer+0x2a4/0x4f0
tracing_set_trace_write+0xd4/0x130
vfs_write+0xf0/0x330
ksys_write+0x84/0x140
system_call_exception+0x14c/0x230
system_call_common+0xf0/0x27cTo fix this when updating kernel memory PTEs using ptesync.
--- arch/powerpc/include/asm/book3s/64/radix.h | 6 ++++-- arch/powerpc/mm/book3s64/radix_pgtable.c | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-)
arch/powerpc/include/asm/book3s/64/radix.h +4 -2
@@ -222,8 +222,10 @@ static inline void radix__set_pte_at(struct mm_struct *mm, unsigned long addr,* from ptesync, it should probably go into update_mmu_cache, rather * than set_pte_at (which is used to set ptes unrelated to faults). * -* Spurious faults to vmalloc region are not tolerated, so there is -* a ptesync in flush_cache_vmap. +* Spurious faults from the kernel memory are not tolerated, so there +* is a ptesync in flush_cache_vmap, and __map_kernel_page() follows +* the pte update sequence from ISA Book III 6.10 Translation Table +* Update Synchronization Requirements. */ }
arch/powerpc/mm/book3s64/radix_pgtable.c +2 -2
@@ -108,7 +108,7 @@ static int early_map_kernel_page(unsigned long ea, unsigned long pa, set_the_pte:set_pte_at (&init_mm, ea, ptep,pfn_pte (pfn, flags)); -smp_wmb (); + asmvolatile ("ptesync" : : :"memory" );return 0 ; }
@@ -168,7 +168,7 @@ static int __map_kernel_page(unsigned long ea, unsigned long pa, set_the_pte:set_pte_at (&init_mm, ea, ptep,pfn_pte (pfn, flags)); -smp_wmb (); + asmvolatile ("ptesync" : : :"memory" );return 0 ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 405/530 powerpc/perf: Fix PMU constraint check for EBB events
In reply to Greg Kroah-HartmanFrom: Athira Rajeev <[email protected]>
[ Upstream commit 10f8f96179ecc7f69c927f6d231f6d02736cea83 ]
The power PMU group constraints includes check for EBB events to make sure all events in a group must agree on EBB. This will prevent scheduling EBB and non-EBB events together. But in the existing check, settings for constraint mask and value is interchanged. Patch fixes the same.
Before the patch, PMU selftest "cpu_event_pinned_vs_ebb_test" fails with below in dmesg logs. This happens because EBB event gets enabled along with a non-EBB cpu event.
[35600.453346] cpu_event_pinne[41326]: illegal instruction (4) at 10004a18 nip 10004a18 lr 100049f8 code 1 in cpu_event_pinned_vs_ebb_test[10000000+10000]
Test results after the patch:
$ ./pmu/ebb/cpu_event_pinned_vs_ebb_test test: cpu_event_pinned_vs_ebb tags: git_version:v5.12-rc5-93-gf28c3125acd3-dirty Binding to cpu 8 EBB Handler is at 0x100050c8 read error on event 0x7fffe6bd4040! PM_RUN_INST_CMPL: result 9872 running/enabled 37930432 success: cpu_event_pinned_vs_ebb
This bug was hidden by other logic until commit 1908dc911792 (perf:
Tweak perf_event_attr::exclusive semantics).
--- arch/powerpc/perf/isa207-common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/powerpc/perf/isa207-common.c +2 -2
@@ -400,8 +400,8 @@ ebb_bhrb:* EBB events are pinned & exclusive, so this should never actually * hit, but we leave it as a fallback in case. */ - mask |=CNST_EBB_VAL (ebb); - value |=CNST_EBB_MASK ; + mask |=CNST_EBB_MASK ; + value |=CNST_EBB_VAL (ebb); *maskp = mask; *valp = value;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 406/530 powerpc: iommu: fix build when neither PCI or IBMVIO is set
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
[ Upstream commit b27dadecdf9102838331b9a0b41ffc1cfe288154 ]
When neither CONFIG_PCI nor CONFIG_IBMVIO is set/enabled, iommu.c has a build error. The fault injection code is not useful in that kernel config, so make the FAIL_IOMMU option depend on PCI || IBMVIO.
Prevents this build error (warning escalated to error):../arch/powerpc/kernel/iommu.c:178:30: error: 'fail_iommu_bus_notifier' defined but not used [-Werror=unused-variable]
178 | static struct notifier_block fail_iommu_bus_notifier = {
--- arch/powerpc/Kconfig.debug | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/Kconfig.debug +1 -0
@@ -352,6 +352,7 @@ config PPC_EARLY_DEBUG_CPM_ADDR config FAIL_IOMMU bool "Fault-injection capability for IOMMU" depends on FAULT_INJECTION + depends on PCI || IBMVIO help Provide fault-injection capability for IOMMU. Each device can be selectively enabled via the fail_iommu property.
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 407/530 mac80211: bail out if cipher schemes are invalid
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
[ Upstream commit db878e27a98106a70315d264cc92230d84009e72 ]
If any of the cipher schemes specified by the driver are invalid, bail out and fail the registration rather than just warning. Otherwise, we might later crash when we try to use the invalid cipher scheme, e.g. if the hdr_len is (significantly) less than the pn_offs + pn_len, we'd have an out-of-bounds access in RX validation.
--- net/mac80211/main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/mac80211/main.c +5 -2
@@ -1150,8 +1150,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)if (local->hw.wiphy->max_scan_ie_len) local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; -WARN_ON (!ieee80211_cs_list_valid (local->hw.cipher_schemes, - local->hw.n_cipher_schemes)); +if (WARN_ON (!ieee80211_cs_list_valid (local->hw.cipher_schemes, + local->hw.n_cipher_schemes))) { + result = -EINVAL ; + goto fail_workqueue; + } result =ieee80211_init_cipher_suites (local);if (result <0 )
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 408/530 perf vendor events amd: Fix broken L2 Cache Hits from L2 HWPF metric
In reply to Greg Kroah-HartmanFrom: Smita Koralahalli <[email protected]>
[ Upstream commit 86c2bc3da769124e3e856b6e9457be3667c30919 ]
Commit 08ed77e414ab2342 ("perf vendor events amd: Add recommended events") added the hits event "L2 Cache Hits from L2 HWPF" with the same metric expression as the accesses event "L2 Cache Accesses from L2 HWPF":
$ perf list --details
...
l2_cache_accesses_from_l2_hwpf
[L2 Cache Accesses from L2 HWPF]
[l2_pf_hit_l2 + l2_pf_miss_l2_hit_l3 + l2_pf_miss_l2_l3]
l2_cache_hits_from_l2_hwpf
[L2 Cache Hits from L2 HWPF]
[l2_pf_hit_l2 + l2_pf_miss_l2_hit_l3 + l2_pf_miss_l2_l3]
...This was wrong and led to counting hits the same as accesses. Section 2.1.15.2 "Performance Measurement" of "PPR for AMD Family 17h Model 31h B0 - 55803 Rev 0.54 - Sep 12, 2019", documents the hits event with EventCode 0x70 which is the same as l2_pf_hit_l2.
Fix this, and massage the description for l2_pf_hit_l2 as the hits event is now the duplicate of l2_pf_hit_l2. AMD recommends using the recommended event over other events if the duplicate exists and maintain both for consistency. Hence, l2_cache_hits_from_l2_hwpf should override l2_pf_hit_l2.
Before:
# perf stat -M l2_cache_accesses_from_l2_hwpf,l2_cache_hits_from_l2_hwpf sleep 1
Performance counter stats for 'sleep 1':
1,436 l2_pf_miss_l2_l3 # 11114.00 l2_cache_accesses_from_l2_hwpf
# 11114.00 l2_cache_hits_from_l2_hwpf
4,482 l2_pf_hit_l2
5,196 l2_pf_miss_l2_hit_l3
1.001765339 seconds time elapsedAfter:
# perf stat -M l2_cache_accesses_from_l2_hwpf sleep 1
Performance counter stats for 'sleep 1':
1,477 l2_pf_miss_l2_l3 # 10442.00 l2_cache_accesses_from_l2_hwpf
3,978 l2_pf_hit_l2
4,987 l2_pf_miss_l2_hit_l31.001491186 seconds time elapsed
# perf stat -e l2_cache_hits_from_l2_hwpf sleep 1
Performance counter stats for 'sleep 1':
3,983 l2_cache_hits_from_l2_hwpf
1.001329970 seconds time elapsedNote the difference in performance counter values for the accesses versus the hits after the fix, and the hits event now counting the same as l2_pf_hit_l2.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=206537
--- tools/perf/pmu-events/arch/x86/amdzen1/cache.json | 2 +- tools/perf/pmu-events/arch/x86/amdzen1/recommended.json | 6 +++--- tools/perf/pmu-events/arch/x86/amdzen2/cache.json | 2 +- tools/perf/pmu-events/arch/x86/amdzen2/recommended.json | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-)
tools/perf/pmu-events/arch/x86/amdzen1/cache.json +1 -1
@@ -275,7 +275,7 @@ { "EventName": "l2_pf_hit_l2", "EventCode": "0x70", - "BriefDescription": "L2 prefetch hit in L2.", + "BriefDescription": "L2 prefetch hit in L2. Use l2_cache_hits_from_l2_hwpf instead.", "UMask": "0xff" }, {
tools/perf/pmu-events/arch/x86/amdzen1/recommended.json +3 -3
@@ -79,10 +79,10 @@ "UMask": "0x70" }, { - "MetricName": "l2_cache_hits_from_l2_hwpf", + "EventName": "l2_cache_hits_from_l2_hwpf", + "EventCode": "0x70", "BriefDescription": "L2 Cache Hits from L2 HWPF", - "MetricExpr": "l2_pf_hit_l2 + l2_pf_miss_l2_hit_l3 + l2_pf_miss_l2_l3", - "MetricGroup": "l2_cache" + "UMask": "0xff" }, { "EventName": "l3_accesses",
tools/perf/pmu-events/arch/x86/amdzen2/cache.json +1 -1
@@ -205,7 +205,7 @@ { "EventName": "l2_pf_hit_l2", "EventCode": "0x70", - "BriefDescription": "L2 prefetch hit in L2.", + "BriefDescription": "L2 prefetch hit in L2. Use l2_cache_hits_from_l2_hwpf instead.", "UMask": "0xff" }, {
tools/perf/pmu-events/arch/x86/amdzen2/recommended.json +3 -3
@@ -79,10 +79,10 @@ "UMask": "0x70" }, { - "MetricName": "l2_cache_hits_from_l2_hwpf", + "EventName": "l2_cache_hits_from_l2_hwpf", + "EventCode": "0x70", "BriefDescription": "L2 Cache Hits from L2 HWPF", - "MetricExpr": "l2_pf_hit_l2 + l2_pf_miss_l2_hit_l3 + l2_pf_miss_l2_l3", - "MetricGroup": "l2_cache" + "UMask": "0xff" }, { "EventName": "l3_accesses",
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 409/530 xfs: fix return of uninitialized value in variable error
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 3b6dd9a9aeeada19d0c820ff68e979243a888bb6 ]
A previous commit removed a call to xfs_attr3_leaf_read that assigned an error return code to variable error. We now have a few early error return paths to label 'out' that return error if error is set; however error now is uninitialized so potentially garbage is being returned. Fix this by setting error to zero to restore the original behaviour where error was zero at the label 'restart'.
Addresses-Coverity: ("Uninitialized scalar variable")
--- fs/xfs/libxfs/xfs_attr.c | 1 + 1 file changed, 1 insertion(+)
fs/xfs/libxfs/xfs_attr.c +1 -0
@@ -928,6 +928,7 @@ restart:* Search to see if name already exists, and get back a pointer * to where it should go. */ + error =0 ; retval =xfs_attr_node_hasname (args, &state);if (retval != -ENOATTR && retval != -EEXIST ) goto out;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 410/530 rtw88: Fix an error code in rtw_debugfs_set_rsvd_page()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit c9eaee0c2ec6b1002044fb698cdfb5d9ef4ed28c ]
The sscanf() function returns the number of matches (0 or 1 in this case). It doesn't return error codes. We should return -EINVAL if the string is invalid
--- drivers/net/wireless/realtek/rtw88/debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw88/debug.c +1 -1
@@ -270,7 +270,7 @@ static ssize_t rtw_debugfs_set_rsvd_page(struct file *filp,if (num !=2 ) {rtw_warn (rtwdev,"invalid arguments\n" ); -return num; +return -EINVAL ; } debugfs_priv->rsvd_page.page_offset = offset;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 411/530 mt7601u: fix always true expression
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit 87fce88658ba047ae62e83497d3f3c5dc22fa6f9 ]
Currently the expression ~nic_conf1 is always true because nic_conf1 is a u16 and according to 6.5.3.3 of the C standard the ~ operator promotes the u16 to an integer before flipping all the bits. Thus the top 16 bits of the integer result are all set so the expression is always true. If the intention was to flip all the bits of nic_conf1 then casting the integer result back to a u16 is a suitabel fix.
Interestingly static analyzers seem to thing a bitwise ! should be used instead of ~ for this scenario, so I think the original intent of the expression may need some extra consideration.
Addresses-Coverity: ("Logical vs. bitwise operator")
--- drivers/net/wireless/mediatek/mt7601u/eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt7601u/eeprom.c +1 -1
@@ -99,7 +99,7 @@ mt7601u_has_tssi(struct mt7601u_dev *dev, u8 *eeprom) {u16 nic_conf1 =get_unaligned_le16 (eeprom +MT_EE_NIC_CONF_1 ); -return ~nic_conf1 && (nic_conf1 &MT_EE_NIC_CONF_1_TX_ALC_EN ); +return (u16 )~nic_conf1 && (nic_conf1 &MT_EE_NIC_CONF_1_TX_ALC_EN ); } static void
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 412/530 mt76: mt7615: fix tx skb dma unmap
In reply to Greg Kroah-HartmanFrom: Felix Fietkau <[email protected]>
[ Upstream commit ebee7885bb12a8fe2c2f9bac87dbd87a05b645f9 ]
The first pointer in the txp needs to be unmapped as well, otherwise it will leak DMA mapping entries
--- drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7615/mac.c +1 -1
@@ -688,7 +688,7 @@ mt7615_txp_skb_unmap_fw(struct mt76_dev *dev, struct mt7615_fw_txp *txp) {int i; -for (i =1 ; i < txp->nbuf; i++) +for (i =0 ; i < txp->nbuf; i++)dma_unmap_single (dev->dev,le32_to_cpu (txp->buf[i]),le16_to_cpu (txp->len[i]),DMA_TO_DEVICE ); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 413/530 mt76: mt7915: fix tx skb dma unmap
In reply to Greg Kroah-HartmanFrom: Felix Fietkau <[email protected]>
[ Upstream commit 7dcf3c04f0aca746517a77433b33d40868ca4749 ]
The first pointer in the txp needs to be unmapped as well, otherwise it will leak DMA mapping entries
--- drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +1 -1
@@ -856,7 +856,7 @@ void mt7915_txp_skb_unmap(struct mt76_dev *dev,int i; txp =mt7915_txwi_to_txp (dev, t); -for (i =1 ; i < txp->nbuf; i++) +for (i =0 ; i < txp->nbuf; i++)dma_unmap_single (dev->dev,le32_to_cpu (txp->buf[i]),le16_to_cpu (txp->len[i]),DMA_TO_DEVICE ); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 414/530 mt76: mt7915: fix aggr len debugfs node
In reply to Greg Kroah-HartmanFrom: Lorenzo Bianconi <[email protected]>
[ Upstream commit 9fb9d755fae20b5ad62ef8b4e9289e5baea2c6fc ]
Similar to mt7921, fix 802.11 aggr len debugfs reporting for mt7915 driver.
--- drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +1 -1
@@ -124,7 +124,7 @@ mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy, range[i] =mt76_rr (dev,MT_MIB_ARNG (ext_phy, i));for (i =0 ; i <ARRAY_SIZE (bound); i++) - bound[i] =MT_MIB_ARNCR_RANGE (range[i /4 ], i) +1 ; + bound[i] =MT_MIB_ARNCR_RANGE (range[i /4 ], i %4 ) +1 ;seq_printf (file,"\nPhy %d\n" , ext_phy);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 415/530 mt76: mt7615: fix mib stats counter reporting to mac80211
In reply to Greg Kroah-HartmanFrom: Lorenzo Bianconi <[email protected]>
[ Upstream commit 2eb6f6c437745bce46bd7a8f3a22a732d5b9becb ]
In order to properly report MIB counters to mac80211, resets stats in mt7615_get_stats routine and hold mt76 mutex accessing MIB counters. Sum up MIB counters in mt7615_mac_update_mib_stats routine.
--- .../net/wireless/mediatek/mt76/mt7615/mac.c | 26 ++++++------------- .../net/wireless/mediatek/mt76/mt7615/main.c | 6 +++++ .../wireless/mediatek/mt76/mt7615/mt7615.h | 10 +++---- 3 files changed, 19 insertions(+), 23 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7615/mac.c +8 -18
@@ -1817,10 +1817,8 @@ mt7615_mac_update_mib_stats(struct mt7615_phy *phy)int i, aggr;u32 val, val2; -memset (mib,0 ,sizeof (*mib)); - - mib->fcs_err_cnt =mt76_get_field (dev,MT_MIB_SDR3 (ext_phy), -MT_MIB_SDR3_FCS_ERR_MASK ); + mib->fcs_err_cnt +=mt76_get_field (dev,MT_MIB_SDR3 (ext_phy), +MT_MIB_SDR3_FCS_ERR_MASK ); val =mt76_get_field (dev,MT_MIB_SDR14 (ext_phy),MT_MIB_AMPDU_MPDU_COUNT );
@@ -1833,24 +1831,16 @@ mt7615_mac_update_mib_stats(struct mt7615_phy *phy) aggr = ext_phy ?ARRAY_SIZE (dev->mt76.aggr_stats) /2 :0 ;for (i =0 ; i <4 ; i++) { val =mt76_rr (dev,MT_MIB_MB_SDR1 (ext_phy, i)); - - val2 =FIELD_GET (MT_MIB_ACK_FAIL_COUNT_MASK , val); -if (val2 > mib->ack_fail_cnt) - mib->ack_fail_cnt = val2; - - val2 =FIELD_GET (MT_MIB_BA_MISS_COUNT_MASK , val); -if (val2 > mib->ba_miss_cnt) - mib->ba_miss_cnt = val2; + mib->ba_miss_cnt +=FIELD_GET (MT_MIB_BA_MISS_COUNT_MASK , val); + mib->ack_fail_cnt +=FIELD_GET (MT_MIB_ACK_FAIL_COUNT_MASK , + val); val =mt76_rr (dev,MT_MIB_MB_SDR0 (ext_phy, i)); - val2 =FIELD_GET (MT_MIB_RTS_RETRIES_COUNT_MASK , val); -if (val2 > mib->rts_retries_cnt) { - mib->rts_cnt =FIELD_GET (MT_MIB_RTS_COUNT_MASK , val); - mib->rts_retries_cnt = val2; - } + mib->rts_cnt +=FIELD_GET (MT_MIB_RTS_COUNT_MASK , val); + mib->rts_retries_cnt +=FIELD_GET (MT_MIB_RTS_RETRIES_COUNT_MASK , + val); val =mt76_rr (dev,MT_TX_AGG_CNT (ext_phy, i)); - dev->mt76.aggr_stats[aggr++] += val &0xffff ; dev->mt76.aggr_stats[aggr++] += val >>16 ; }
drivers/net/wireless/mediatek/mt76/mt7615/main.c +6 -0
@@ -851,11 +851,17 @@ mt7615_get_stats(struct ieee80211_hw *hw,struct mt7615_phy *phy =mt7615_hw_phy (hw);struct mib_stats *mib = &phy->mib; +mt7615_mutex_acquire (phy->dev); + stats->dot11RTSSuccessCount = mib->rts_cnt; stats->dot11RTSFailureCount = mib->rts_retries_cnt; stats->dot11FCSErrorCount = mib->fcs_err_cnt; stats->dot11ACKFailureCount = mib->ack_fail_cnt; +memset (mib,0 ,sizeof (*mib)); + +mt7615_mutex_release (phy->dev); +return 0 ; }
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +5 -5
@@ -161,11 +161,11 @@ struct mt7615_vif { };struct mib_stats { -u16 ack_fail_cnt; -u16 fcs_err_cnt; -u16 rts_cnt; -u16 rts_retries_cnt; -u16 ba_miss_cnt; +u32 ack_fail_cnt; +u32 fcs_err_cnt; +u32 rts_cnt; +u32 rts_retries_cnt; +u32 ba_miss_cnt;unsigned long aggr_per; };
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 416/530 mt76: mt7915: fix mib stats counter reporting to mac80211
In reply to Greg Kroah-HartmanFrom: Ryder Lee <[email protected]>
[ Upstream commit 2b35050a321865859fd2f12a3c18ed7be27858c9 ]
In order to properly report MIB counters to mac80211, resets stats in mt7915_get_stats routine() and hold mt76 mutex accessing MIB counters. Sum up MIB counters in mt7915_mac_update_mib_stats routine.
--- .../net/wireless/mediatek/mt76/mt7915/mac.c | 35 +++++++------------ .../net/wireless/mediatek/mt76/mt7915/main.c | 6 ++++ .../wireless/mediatek/mt76/mt7915/mt7915.h | 10 +++--- 3 files changed, 24 insertions(+), 27 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +13 -22
@@ -1277,39 +1277,30 @@ mt7915_mac_update_mib_stats(struct mt7915_phy *phy)bool ext_phy = phy != &dev->phy;int i, aggr0, aggr1; -memset (mib,0 ,sizeof (*mib)); - - mib->fcs_err_cnt =mt76_get_field (dev,MT_MIB_SDR3 (ext_phy), -MT_MIB_SDR3_FCS_ERR_MASK ); + mib->fcs_err_cnt +=mt76_get_field (dev,MT_MIB_SDR3 (ext_phy), +MT_MIB_SDR3_FCS_ERR_MASK ); aggr0 = ext_phy ?ARRAY_SIZE (dev->mt76.aggr_stats) /2 :0 ;for (i =0 , aggr1 = aggr0 +4 ; i <4 ; i++) { -u32 val, val2; +u32 val; val =mt76_rr (dev,MT_MIB_MB_SDR1 (ext_phy, i)); - - val2 =FIELD_GET (MT_MIB_ACK_FAIL_COUNT_MASK , val); -if (val2 > mib->ack_fail_cnt) - mib->ack_fail_cnt = val2; - - val2 =FIELD_GET (MT_MIB_BA_MISS_COUNT_MASK , val); -if (val2 > mib->ba_miss_cnt) - mib->ba_miss_cnt = val2; + mib->ba_miss_cnt +=FIELD_GET (MT_MIB_BA_MISS_COUNT_MASK , val); + mib->ack_fail_cnt += +FIELD_GET (MT_MIB_ACK_FAIL_COUNT_MASK , val); val =mt76_rr (dev,MT_MIB_MB_SDR0 (ext_phy, i)); - val2 =FIELD_GET (MT_MIB_RTS_RETRIES_COUNT_MASK , val); -if (val2 > mib->rts_retries_cnt) { - mib->rts_cnt =FIELD_GET (MT_MIB_RTS_COUNT_MASK , val); - mib->rts_retries_cnt = val2; - } + mib->rts_cnt +=FIELD_GET (MT_MIB_RTS_COUNT_MASK , val); + mib->rts_retries_cnt += +FIELD_GET (MT_MIB_RTS_RETRIES_COUNT_MASK , val); val =mt76_rr (dev,MT_TX_AGG_CNT (ext_phy, i)); - val2 =mt76_rr (dev,MT_TX_AGG_CNT2 (ext_phy, i)); - dev->mt76.aggr_stats[aggr0++] += val &0xffff ; dev->mt76.aggr_stats[aggr0++] += val >>16 ; - dev->mt76.aggr_stats[aggr1++] += val2 &0xffff ; - dev->mt76.aggr_stats[aggr1++] += val2 >>16 ; + + val =mt76_rr (dev,MT_TX_AGG_CNT2 (ext_phy, i)); + dev->mt76.aggr_stats[aggr1++] += val &0xffff ; + dev->mt76.aggr_stats[aggr1++] += val >>16 ; } }
drivers/net/wireless/mediatek/mt76/mt7915/main.c +6 -0
@@ -651,13 +651,19 @@ mt7915_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats) {struct mt7915_phy *phy =mt7915_hw_phy (hw); +struct mt7915_dev *dev =mt7915_hw_dev (hw);struct mib_stats *mib = &phy->mib; +mutex_lock (&dev->mt76.mutex); stats->dot11RTSSuccessCount = mib->rts_cnt; stats->dot11RTSFailureCount = mib->rts_retries_cnt; stats->dot11FCSErrorCount = mib->fcs_err_cnt; stats->dot11ACKFailureCount = mib->ack_fail_cnt; +memset (mib,0 ,sizeof (*mib)); + +mutex_unlock (&dev->mt76.mutex); +return 0 ; }
drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +5 -5
@@ -99,11 +99,11 @@ struct mt7915_vif { };struct mib_stats { -u16 ack_fail_cnt; -u16 fcs_err_cnt; -u16 rts_cnt; -u16 rts_retries_cnt; -u16 ba_miss_cnt; +u32 ack_fail_cnt; +u32 fcs_err_cnt; +u32 rts_cnt; +u32 rts_retries_cnt; +u32 ba_miss_cnt; };struct mt7915_phy {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 417/530 mt76: mt7663s: make all of packets 4-bytes aligned in sdio tx aggregation
In reply to Greg Kroah-HartmanFrom: Sean Wang <[email protected]>
[ Upstream commit 455ae5aabcc72fed7e5c803d59d122415500dc08 ]
Each packet should be padded with the additional zero to become 4-bytes alignment in sdio tx aggregation.
--- drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c +8 -1
@@ -195,6 +195,7 @@ static int mt7663s_tx_run_queue(struct mt76_dev *dev, enum mt76_txq_id qid)int err, nframes =0 , len =0 , pse_sz =0 , ple_sz =0 ;struct mt76_queue *q = dev->q_tx[qid];struct mt76_sdio *sdio = &dev->sdio; +u8 pad;while (q->first != q->head) {struct mt76_queue_entry *e = &q->entry[q->first];
@@ -210,7 +211,8 @@ static int mt7663s_tx_run_queue(struct mt76_dev *dev, enum mt76_txq_id qid) goto next; } -if (len + e->skb->len +4 >MT76S_XMIT_BUF_SZ ) + pad =roundup (e->skb->len,4 ) - e->skb->len; +if (len + e->skb->len + pad +4 >MT76S_XMIT_BUF_SZ )break ; if (mt7663s_tx_pick_quota(sdio, qid, e->buf_sz, &pse_sz,
@@ -228,6 +230,11 @@ static int mt7663s_tx_run_queue(struct mt76_dev *dev, enum mt76_txq_id qid) len += iter->len; nframes++; } + +if (unlikely (pad)) { +memset (sdio->xmit_buf[qid] + len,0 , pad); + len += pad; + } next: q->first = (q->first +1 ) % q->ndesc; e->done = true;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 418/530 mt76: mt7663s: fix the possible device hang in high traffic
In reply to Greg Kroah-HartmanFrom: Sean Wang <[email protected]>
[ Upstream commit 45247a85614b49b07b9dc59a4e6783b17e766ff2 ]
Use the additional memory barrier to ensure the skb list up-to-date between the skb producer and consumer to avoid the invalid skb content written into sdio controller and then cause device hang due to mcu assert caught by WR_TIMEOUT_INT.
--- drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c | 2 ++ drivers/net/wireless/mediatek/mt76/sdio.c | 3 +++ 2 files changed, 5 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c +2 -0
@@ -201,6 +201,8 @@ static int mt7663s_tx_run_queue(struct mt76_dev *dev, enum mt76_txq_id qid)struct mt76_queue_entry *e = &q->entry[q->first];struct sk_buff *iter; +smp_rmb (); +if (!test_bit (MT76_STATE_MCU_RUNNING , &dev->phy.state)) {__skb_put_zero (e->skb,4 ); err = __mt7663s_xmit_queue(dev, e->skb->data,
drivers/net/wireless/mediatek/mt76/sdio.c +3 -0
@@ -215,6 +215,9 @@ mt76s_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid, q->entry[q->head].skb = tx_info.skb; q->entry[q->head].buf_sz = len; + +smp_wmb (); + q->head = (q->head +1 ) % q->ndesc; q->queued++;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 419/530 KVM: PPC: Book3S HV P9: Restore host CTRL SPR after guest exit
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit 5088eb4092df12d701af8e0e92860b7186365279 ]
The host CTRL (runlatch) value is not restored after guest exit. The host CTRL should always be 1 except in CPU idle code, so this can result in the host running with runlatch clear, and potentially switching to a different vCPU which then runs with runlatch clear as well.
This has little effect on P9 machines, CTRL is only responsible for some PMU counter logic in the host and so other than corner cases of software relying on that, or explicitly reading the runlatch value (Linux does not appear to be affected but it's possible non-Linux guests could be), there should be no execution correctness problem, though it could be used as a covert channel between guests.
There may be microcontrollers, firmware or monitoring tools that sample the runlatch value out-of-band, however since the register is writable by guests, these values would (should) not be relied upon for correct operation of the host, so suboptimal performance or incorrect reporting should be the worst problem.
--- arch/powerpc/kvm/book3s_hv.c | 3 +++ 1 file changed, 3 insertions(+)
arch/powerpc/kvm/book3s_hv.c +3 -0
@@ -3697,7 +3697,10 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, vcpu->arch.dec_expires = dec + tb; vcpu->cpu =-1 ; vcpu->arch.thread_cpu =-1 ; +/* Save guest CTRL register, set runlatch to 1 */ vcpu->arch.ctrl =mfspr (SPRN_CTRLF ); +if (!(vcpu->arch.ctrl &1 )) +mtspr (SPRN_CTRLT , vcpu->arch.ctrl |1 ); vcpu->arch.iamr =mfspr (SPRN_IAMR ); vcpu->arch.pspb =mfspr (SPRN_PSPB );
Signature · 1 line
2.30.2