From: Greg Kroah-Hartman Date: Sun, 26 Sep 2021 13:03:05 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v5.4.150~50 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=62354e031a0a35be77c8ed113954d3db97a50105;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: binder-make-sure-fd-closes-complete.patch cifs-fix-incorrect-check-for-null-pointer-in-header_assemble.patch enable-uas-for-lacie-rugged-usb3-fw-with-fk-quirk.patch mcb-fix-error-handling-in-mcb_alloc_bus.patch ocfs2-drop-acl-cache-for-directories-too.patch staging-greybus-uart-fix-tty-use-after-free.patch usb-cdc-acm-fix-minor-number-release.patch usb-core-hcd-add-support-for-deferring-roothub-registration.patch usb-dwc2-gadget-fix-isoc-flow-for-bdma-and-slave.patch usb-dwc2-gadget-fix-isoc-transfer-complete-handling-for-ddma.patch usb-gadget-r8a66597-fix-a-loop-in-set_feature.patch usb-musb-tusb6010-uninitialized-data-in-tusb_fifo_write_unaligned.patch usb-serial-cp210x-add-id-for-gw-instek-gdm-834x-digital-multimeter.patch usb-serial-mos7840-remove-duplicated-0xac24-device-id.patch usb-serial-option-add-device-id-for-foxconn-t99w265.patch usb-serial-option-add-telit-ln920-compositions.patch usb-serial-option-remove-duplicate-usb-device-id.patch usb-storage-add-quirk-for-scanlogic-sl11r-ide-older-than-2.6c.patch xen-x86-fix-pv-trap-handling-on-secondary-processors.patch --- diff --git a/queue-5.4/binder-make-sure-fd-closes-complete.patch b/queue-5.4/binder-make-sure-fd-closes-complete.patch new file mode 100644 index 00000000000..07c61e16022 --- /dev/null +++ b/queue-5.4/binder-make-sure-fd-closes-complete.patch @@ -0,0 +1,104 @@ +From 5fdb55c1ac9585eb23bb2541d5819224429e103d Mon Sep 17 00:00:00 2001 +From: Todd Kjos +Date: Mon, 30 Aug 2021 12:51:46 -0700 +Subject: binder: make sure fd closes complete + +From: Todd Kjos + +commit 5fdb55c1ac9585eb23bb2541d5819224429e103d upstream. + +During BC_FREE_BUFFER processing, the BINDER_TYPE_FDA object +cleanup may close 1 or more fds. The close operations are +completed using the task work mechanism -- which means the thread +needs to return to userspace or the file object may never be +dereferenced -- which can lead to hung processes. + +Force the binder thread back to userspace if an fd is closed during +BC_FREE_BUFFER handling. + +Fixes: 80cd795630d6 ("binder: fix use-after-free due to ksys_close() during fdget()") +Cc: stable +Reviewed-by: Martijn Coenen +Acked-by: Christian Brauner +Signed-off-by: Todd Kjos +Link: https://lore.kernel.org/r/20210830195146.587206-1-tkjos@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/android/binder.c | 23 +++++++++++++++++------ + 1 file changed, 17 insertions(+), 6 deletions(-) + +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -2239,6 +2239,7 @@ static void binder_deferred_fd_close(int + } + + static void binder_transaction_buffer_release(struct binder_proc *proc, ++ struct binder_thread *thread, + struct binder_buffer *buffer, + binder_size_t failed_at, + bool is_failure) +@@ -2398,8 +2399,16 @@ static void binder_transaction_buffer_re + &proc->alloc, &fd, buffer, + offset, sizeof(fd)); + WARN_ON(err); +- if (!err) ++ if (!err) { + binder_deferred_fd_close(fd); ++ /* ++ * Need to make sure the thread goes ++ * back to userspace to complete the ++ * deferred close ++ */ ++ if (thread) ++ thread->looper_need_return = true; ++ } + } + } break; + default: +@@ -3469,7 +3478,7 @@ err_bad_parent: + err_copy_data_failed: + binder_free_txn_fixups(t); + trace_binder_transaction_failed_buffer_release(t->buffer); +- binder_transaction_buffer_release(target_proc, t->buffer, ++ binder_transaction_buffer_release(target_proc, NULL, t->buffer, + buffer_offset, true); + if (target_node) + binder_dec_node_tmpref(target_node); +@@ -3546,7 +3555,9 @@ err_invalid_target_handle: + * Cleanup buffer and free it. + */ + static void +-binder_free_buf(struct binder_proc *proc, struct binder_buffer *buffer) ++binder_free_buf(struct binder_proc *proc, ++ struct binder_thread *thread, ++ struct binder_buffer *buffer) + { + binder_inner_proc_lock(proc); + if (buffer->transaction) { +@@ -3574,7 +3585,7 @@ binder_free_buf(struct binder_proc *proc + binder_node_inner_unlock(buf_node); + } + trace_binder_transaction_buffer_release(buffer); +- binder_transaction_buffer_release(proc, buffer, 0, false); ++ binder_transaction_buffer_release(proc, thread, buffer, 0, false); + binder_alloc_free_buf(&proc->alloc, buffer); + } + +@@ -3775,7 +3786,7 @@ static int binder_thread_write(struct bi + proc->pid, thread->pid, (u64)data_ptr, + buffer->debug_id, + buffer->transaction ? "active" : "finished"); +- binder_free_buf(proc, buffer); ++ binder_free_buf(proc, thread, buffer); + break; + } + +@@ -4463,7 +4474,7 @@ retry: + buffer->transaction = NULL; + binder_cleanup_transaction(t, "fd fixups failed", + BR_FAILED_REPLY); +- binder_free_buf(proc, buffer); ++ binder_free_buf(proc, thread, buffer); + binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, + "%d:%d %stransaction %d fd fixups failed %d/%d, line %d\n", + proc->pid, thread->pid, diff --git a/queue-5.4/cifs-fix-incorrect-check-for-null-pointer-in-header_assemble.patch b/queue-5.4/cifs-fix-incorrect-check-for-null-pointer-in-header_assemble.patch new file mode 100644 index 00000000000..7d7a74a13e2 --- /dev/null +++ b/queue-5.4/cifs-fix-incorrect-check-for-null-pointer-in-header_assemble.patch @@ -0,0 +1,45 @@ +From 9ed38fd4a15417cac83967360cf20b853bfab9b6 Mon Sep 17 00:00:00 2001 +From: Steve French +Date: Thu, 23 Sep 2021 19:18:37 -0500 +Subject: cifs: fix incorrect check for null pointer in header_assemble + +From: Steve French + +commit 9ed38fd4a15417cac83967360cf20b853bfab9b6 upstream. + +Although very unlikely that the tlink pointer would be null in this case, +get_next_mid function can in theory return null (but not an error) +so need to check for null (not for IS_ERR, which can not be returned +here). + +Address warning: + + fs/smbfs_client/connect.c:2392 cifs_match_super() + warn: 'tlink' isn't an ERR_PTR + +Pointed out by Dan Carpenter via smatch code analysis tool + +CC: stable@vger.kernel.org +Reported-by: Dan Carpenter +Acked-by: Ronnie Sahlberg +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/cifs/connect.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -3691,9 +3691,10 @@ cifs_match_super(struct super_block *sb, + spin_lock(&cifs_tcp_ses_lock); + cifs_sb = CIFS_SB(sb); + tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb)); +- if (IS_ERR(tlink)) { ++ if (tlink == NULL) { ++ /* can not match superblock if tlink were ever null */ + spin_unlock(&cifs_tcp_ses_lock); +- return rc; ++ return 0; + } + tcon = tlink_tcon(tlink); + ses = tcon->ses; diff --git a/queue-5.4/enable-uas-for-lacie-rugged-usb3-fw-with-fk-quirk.patch b/queue-5.4/enable-uas-for-lacie-rugged-usb3-fw-with-fk-quirk.patch new file mode 100644 index 00000000000..05308a3588f --- /dev/null +++ b/queue-5.4/enable-uas-for-lacie-rugged-usb3-fw-with-fk-quirk.patch @@ -0,0 +1,35 @@ +From ce1c42b4dacfe7d71c852d8bf3371067ccba865c Mon Sep 17 00:00:00 2001 +From: Julian Sikorski +Date: Mon, 13 Sep 2021 20:14:55 +0200 +Subject: Re-enable UAS for LaCie Rugged USB3-FW with fk quirk + +From: Julian Sikorski + +commit ce1c42b4dacfe7d71c852d8bf3371067ccba865c upstream. + +Further testing has revealed that LaCie Rugged USB3-FW does work with +uas as long as US_FL_NO_REPORT_OPCODES and US_FL_NO_SAME are enabled. + +Link: https://lore.kernel.org/linux-usb/2167ea48-e273-a336-a4e0-10a4e883e75e@redhat.com/ +Cc: stable +Suggested-by: Hans de Goede +Reviewed-by: Hans de Goede +Acked-by: Oliver Neukum +Signed-off-by: Julian Sikorski +Link: https://lore.kernel.org/r/20210913181454.7365-1-belegdol+github@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/storage/unusual_uas.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/storage/unusual_uas.h ++++ b/drivers/usb/storage/unusual_uas.h +@@ -50,7 +50,7 @@ UNUSUAL_DEV(0x059f, 0x1061, 0x0000, 0x99 + "LaCie", + "Rugged USB3-FW", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, +- US_FL_IGNORE_UAS), ++ US_FL_NO_REPORT_OPCODES | US_FL_NO_SAME), + + /* + * Apricorn USB3 dongle sometimes returns "USBSUSBSUSBS" in response to SCSI diff --git a/queue-5.4/mcb-fix-error-handling-in-mcb_alloc_bus.patch b/queue-5.4/mcb-fix-error-handling-in-mcb_alloc_bus.patch new file mode 100644 index 00000000000..f3589ef53e9 --- /dev/null +++ b/queue-5.4/mcb-fix-error-handling-in-mcb_alloc_bus.patch @@ -0,0 +1,58 @@ +From 25a1433216489de4abc889910f744e952cb6dbae Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 6 Sep 2021 21:35:48 +0900 +Subject: mcb: fix error handling in mcb_alloc_bus() + +From: Dan Carpenter + +commit 25a1433216489de4abc889910f744e952cb6dbae upstream. + +There are two bugs: +1) If ida_simple_get() fails then this code calls put_device(carrier) + but we haven't yet called get_device(carrier) and probably that + leads to a use after free. +2) After device_initialize() then we need to use put_device() to + release the bus. This will free the internal resources tied to the + device and call mcb_free_bus() which will free the rest. + +Fixes: 5d9e2ab9fea4 ("mcb: Implement bus->dev.release callback") +Fixes: 18d288198099 ("mcb: Correctly initialize the bus's device") +Cc: stable@vger.kernel.org +Signed-off-by: Dan Carpenter +Signed-off-by: Johannes Thumshirn +Link: https://lore.kernel.org/r/32e160cf6864ce77f9d62948338e24db9fd8ead9.1630931319.git.johannes.thumshirn@wdc.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mcb/mcb-core.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/mcb/mcb-core.c ++++ b/drivers/mcb/mcb-core.c +@@ -277,8 +277,8 @@ struct mcb_bus *mcb_alloc_bus(struct dev + + bus_nr = ida_simple_get(&mcb_ida, 0, 0, GFP_KERNEL); + if (bus_nr < 0) { +- rc = bus_nr; +- goto err_free; ++ kfree(bus); ++ return ERR_PTR(bus_nr); + } + + bus->bus_nr = bus_nr; +@@ -293,12 +293,12 @@ struct mcb_bus *mcb_alloc_bus(struct dev + dev_set_name(&bus->dev, "mcb:%d", bus_nr); + rc = device_add(&bus->dev); + if (rc) +- goto err_free; ++ goto err_put; + + return bus; +-err_free: +- put_device(carrier); +- kfree(bus); ++ ++err_put: ++ put_device(&bus->dev); + return ERR_PTR(rc); + } + EXPORT_SYMBOL_GPL(mcb_alloc_bus); diff --git a/queue-5.4/ocfs2-drop-acl-cache-for-directories-too.patch b/queue-5.4/ocfs2-drop-acl-cache-for-directories-too.patch new file mode 100644 index 00000000000..ec48c0caa36 --- /dev/null +++ b/queue-5.4/ocfs2-drop-acl-cache-for-directories-too.patch @@ -0,0 +1,64 @@ +From 9c0f0a03e386f4e1df33db676401547e1b7800c6 Mon Sep 17 00:00:00 2001 +From: Wengang Wang +Date: Fri, 24 Sep 2021 15:43:35 -0700 +Subject: ocfs2: drop acl cache for directories too + +From: Wengang Wang + +commit 9c0f0a03e386f4e1df33db676401547e1b7800c6 upstream. + +ocfs2_data_convert_worker() is currently dropping any cached acl info +for FILE before down-converting meta lock. It should also drop for +DIRECTORY. Otherwise the second acl lookup returns the cached one (from +VFS layer) which could be already stale. + +The problem we are seeing is that the acl changes on one node doesn't +get refreshed on other nodes in the following case: + + Node 1 Node 2 + -------------- ---------------- + getfacl dir1 + + getfacl dir1 <-- this is OK + + setfacl -m u:user1:rwX dir1 + getfacl dir1 <-- see the change for user1 + + getfacl dir1 <-- can't see change for user1 + +Link: https://lkml.kernel.org/r/20210903012631.6099-1-wen.gang.wang@oracle.com +Signed-off-by: Wengang Wang +Reviewed-by: Joseph Qi +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Gang He +Cc: Jun Piao +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + fs/ocfs2/dlmglue.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/ocfs2/dlmglue.c ++++ b/fs/ocfs2/dlmglue.c +@@ -3933,7 +3933,7 @@ static int ocfs2_data_convert_worker(str + oi = OCFS2_I(inode); + oi->ip_dir_lock_gen++; + mlog(0, "generation: %u\n", oi->ip_dir_lock_gen); +- goto out; ++ goto out_forget; + } + + if (!S_ISREG(inode->i_mode)) +@@ -3964,6 +3964,7 @@ static int ocfs2_data_convert_worker(str + filemap_fdatawait(mapping); + } + ++out_forget: + forget_all_cached_acls(inode); + + out: diff --git a/queue-5.4/series b/queue-5.4/series new file mode 100644 index 00000000000..8d9b4a3e30e --- /dev/null +++ b/queue-5.4/series @@ -0,0 +1,19 @@ +ocfs2-drop-acl-cache-for-directories-too.patch +usb-gadget-r8a66597-fix-a-loop-in-set_feature.patch +usb-dwc2-gadget-fix-isoc-flow-for-bdma-and-slave.patch +usb-dwc2-gadget-fix-isoc-transfer-complete-handling-for-ddma.patch +usb-musb-tusb6010-uninitialized-data-in-tusb_fifo_write_unaligned.patch +cifs-fix-incorrect-check-for-null-pointer-in-header_assemble.patch +xen-x86-fix-pv-trap-handling-on-secondary-processors.patch +usb-storage-add-quirk-for-scanlogic-sl11r-ide-older-than-2.6c.patch +usb-serial-cp210x-add-id-for-gw-instek-gdm-834x-digital-multimeter.patch +usb-cdc-acm-fix-minor-number-release.patch +binder-make-sure-fd-closes-complete.patch +staging-greybus-uart-fix-tty-use-after-free.patch +enable-uas-for-lacie-rugged-usb3-fw-with-fk-quirk.patch +usb-core-hcd-add-support-for-deferring-roothub-registration.patch +usb-serial-mos7840-remove-duplicated-0xac24-device-id.patch +usb-serial-option-add-telit-ln920-compositions.patch +usb-serial-option-remove-duplicate-usb-device-id.patch +usb-serial-option-add-device-id-for-foxconn-t99w265.patch +mcb-fix-error-handling-in-mcb_alloc_bus.patch diff --git a/queue-5.4/staging-greybus-uart-fix-tty-use-after-free.patch b/queue-5.4/staging-greybus-uart-fix-tty-use-after-free.patch new file mode 100644 index 00000000000..2ef277cf9e9 --- /dev/null +++ b/queue-5.4/staging-greybus-uart-fix-tty-use-after-free.patch @@ -0,0 +1,172 @@ +From 92dc0b1f46e12cfabd28d709bb34f7a39431b44f Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 6 Sep 2021 14:45:38 +0200 +Subject: staging: greybus: uart: fix tty use after free + +From: Johan Hovold + +commit 92dc0b1f46e12cfabd28d709bb34f7a39431b44f upstream. + +User space can hold a tty open indefinitely and tty drivers must not +release the underlying structures until the last user is gone. + +Switch to using the tty-port reference counter to manage the life time +of the greybus tty state to avoid use after free after a disconnect. + +Fixes: a18e15175708 ("greybus: more uart work") +Cc: stable@vger.kernel.org # 4.9 +Reviewed-by: Alex Elder +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20210906124538.22358-1-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/greybus/uart.c | 62 +++++++++++++++++++++-------------------- + 1 file changed, 32 insertions(+), 30 deletions(-) + +--- a/drivers/staging/greybus/uart.c ++++ b/drivers/staging/greybus/uart.c +@@ -789,6 +789,17 @@ out: + gbphy_runtime_put_autosuspend(gb_tty->gbphy_dev); + } + ++static void gb_tty_port_destruct(struct tty_port *port) ++{ ++ struct gb_tty *gb_tty = container_of(port, struct gb_tty, port); ++ ++ if (gb_tty->minor != GB_NUM_MINORS) ++ release_minor(gb_tty); ++ kfifo_free(&gb_tty->write_fifo); ++ kfree(gb_tty->buffer); ++ kfree(gb_tty); ++} ++ + static const struct tty_operations gb_ops = { + .install = gb_tty_install, + .open = gb_tty_open, +@@ -814,6 +825,7 @@ static const struct tty_port_operations + .dtr_rts = gb_tty_dtr_rts, + .activate = gb_tty_port_activate, + .shutdown = gb_tty_port_shutdown, ++ .destruct = gb_tty_port_destruct, + }; + + static int gb_uart_probe(struct gbphy_device *gbphy_dev, +@@ -826,17 +838,11 @@ static int gb_uart_probe(struct gbphy_de + int retval; + int minor; + +- gb_tty = kzalloc(sizeof(*gb_tty), GFP_KERNEL); +- if (!gb_tty) +- return -ENOMEM; +- + connection = gb_connection_create(gbphy_dev->bundle, + le16_to_cpu(gbphy_dev->cport_desc->id), + gb_uart_request_handler); +- if (IS_ERR(connection)) { +- retval = PTR_ERR(connection); +- goto exit_tty_free; +- } ++ if (IS_ERR(connection)) ++ return PTR_ERR(connection); + + max_payload = gb_operation_get_payload_size_max(connection); + if (max_payload < sizeof(struct gb_uart_send_data_request)) { +@@ -844,13 +850,23 @@ static int gb_uart_probe(struct gbphy_de + goto exit_connection_destroy; + } + ++ gb_tty = kzalloc(sizeof(*gb_tty), GFP_KERNEL); ++ if (!gb_tty) { ++ retval = -ENOMEM; ++ goto exit_connection_destroy; ++ } ++ ++ tty_port_init(&gb_tty->port); ++ gb_tty->port.ops = &gb_port_ops; ++ gb_tty->minor = GB_NUM_MINORS; ++ + gb_tty->buffer_payload_max = max_payload - + sizeof(struct gb_uart_send_data_request); + + gb_tty->buffer = kzalloc(gb_tty->buffer_payload_max, GFP_KERNEL); + if (!gb_tty->buffer) { + retval = -ENOMEM; +- goto exit_connection_destroy; ++ goto exit_put_port; + } + + INIT_WORK(&gb_tty->tx_work, gb_uart_tx_write_work); +@@ -858,7 +874,7 @@ static int gb_uart_probe(struct gbphy_de + retval = kfifo_alloc(&gb_tty->write_fifo, GB_UART_WRITE_FIFO_SIZE, + GFP_KERNEL); + if (retval) +- goto exit_buf_free; ++ goto exit_put_port; + + gb_tty->credits = GB_UART_FIRMWARE_CREDITS; + init_completion(&gb_tty->credits_complete); +@@ -872,7 +888,7 @@ static int gb_uart_probe(struct gbphy_de + } else { + retval = minor; + } +- goto exit_kfifo_free; ++ goto exit_put_port; + } + + gb_tty->minor = minor; +@@ -881,9 +897,6 @@ static int gb_uart_probe(struct gbphy_de + init_waitqueue_head(&gb_tty->wioctl); + mutex_init(&gb_tty->mutex); + +- tty_port_init(&gb_tty->port); +- gb_tty->port.ops = &gb_port_ops; +- + gb_tty->connection = connection; + gb_tty->gbphy_dev = gbphy_dev; + gb_connection_set_data(connection, gb_tty); +@@ -891,7 +904,7 @@ static int gb_uart_probe(struct gbphy_de + + retval = gb_connection_enable_tx(connection); + if (retval) +- goto exit_release_minor; ++ goto exit_put_port; + + send_control(gb_tty, gb_tty->ctrlout); + +@@ -918,16 +931,10 @@ static int gb_uart_probe(struct gbphy_de + + exit_connection_disable: + gb_connection_disable(connection); +-exit_release_minor: +- release_minor(gb_tty); +-exit_kfifo_free: +- kfifo_free(&gb_tty->write_fifo); +-exit_buf_free: +- kfree(gb_tty->buffer); ++exit_put_port: ++ tty_port_put(&gb_tty->port); + exit_connection_destroy: + gb_connection_destroy(connection); +-exit_tty_free: +- kfree(gb_tty); + + return retval; + } +@@ -958,15 +965,10 @@ static void gb_uart_remove(struct gbphy_ + gb_connection_disable_rx(connection); + tty_unregister_device(gb_tty_driver, gb_tty->minor); + +- /* FIXME - free transmit / receive buffers */ +- + gb_connection_disable(connection); +- tty_port_destroy(&gb_tty->port); + gb_connection_destroy(connection); +- release_minor(gb_tty); +- kfifo_free(&gb_tty->write_fifo); +- kfree(gb_tty->buffer); +- kfree(gb_tty); ++ ++ tty_port_put(&gb_tty->port); + } + + static int gb_tty_init(void) diff --git a/queue-5.4/usb-cdc-acm-fix-minor-number-release.patch b/queue-5.4/usb-cdc-acm-fix-minor-number-release.patch new file mode 100644 index 00000000000..472c3ff508e --- /dev/null +++ b/queue-5.4/usb-cdc-acm-fix-minor-number-release.patch @@ -0,0 +1,63 @@ +From 91fac0741d4817945c6ee0a17591421e7f5ecb86 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 7 Sep 2021 10:23:18 +0200 +Subject: USB: cdc-acm: fix minor-number release + +From: Johan Hovold + +commit 91fac0741d4817945c6ee0a17591421e7f5ecb86 upstream. + +If the driver runs out of minor numbers it would release minor 0 and +allow another device to claim the minor while still in use. + +Fortunately, registering the tty class device of the second device would +fail (with a stack dump) due to the sysfs name collision so no memory is +leaked. + +Fixes: cae2bc768d17 ("usb: cdc-acm: Decrement tty port's refcount if probe() fail") +Cc: stable@vger.kernel.org # 4.19 +Cc: Jaejoong Kim +Acked-by: Oliver Neukum +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20210907082318.7757-1-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/class/cdc-acm.c | 7 +++++-- + drivers/usb/class/cdc-acm.h | 2 ++ + 2 files changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -725,7 +725,8 @@ static void acm_port_destruct(struct tty + { + struct acm *acm = container_of(port, struct acm, port); + +- acm_release_minor(acm); ++ if (acm->minor != ACM_MINOR_INVALID) ++ acm_release_minor(acm); + usb_put_intf(acm->control); + kfree(acm->country_codes); + kfree(acm); +@@ -1356,8 +1357,10 @@ made_compressed_probe: + usb_get_intf(acm->control); /* undone in destruct() */ + + minor = acm_alloc_minor(acm); +- if (minor < 0) ++ if (minor < 0) { ++ acm->minor = ACM_MINOR_INVALID; + goto alloc_fail1; ++ } + + acm->minor = minor; + acm->dev = usb_dev; +--- a/drivers/usb/class/cdc-acm.h ++++ b/drivers/usb/class/cdc-acm.h +@@ -22,6 +22,8 @@ + #define ACM_TTY_MAJOR 166 + #define ACM_TTY_MINORS 256 + ++#define ACM_MINOR_INVALID ACM_TTY_MINORS ++ + /* + * Requests. + */ diff --git a/queue-5.4/usb-core-hcd-add-support-for-deferring-roothub-registration.patch b/queue-5.4/usb-core-hcd-add-support-for-deferring-roothub-registration.patch new file mode 100644 index 00000000000..ddb300d84c7 --- /dev/null +++ b/queue-5.4/usb-core-hcd-add-support-for-deferring-roothub-registration.patch @@ -0,0 +1,115 @@ +From 58877b0824da15698bd85a0a9dbfa8c354e6ecb7 Mon Sep 17 00:00:00 2001 +From: Kishon Vijay Abraham I +Date: Thu, 9 Sep 2021 12:11:58 +0530 +Subject: usb: core: hcd: Add support for deferring roothub registration + +From: Kishon Vijay Abraham I + +commit 58877b0824da15698bd85a0a9dbfa8c354e6ecb7 upstream. + +It has been observed with certain PCIe USB cards (like Inateck connected +to AM64 EVM or J7200 EVM) that as soon as the primary roothub is +registered, port status change is handled even before xHC is running +leading to cold plug USB devices not detected. For such cases, registering +both the root hubs along with the second HCD is required. Add support for +deferring roothub registration in usb_add_hcd(), so that both primary and +secondary roothubs are registered along with the second HCD. + +CC: stable@vger.kernel.org # 5.4+ +Suggested-by: Mathias Nyman +Tested-by: Chris Chiu +Acked-by: Alan Stern +Signed-off-by: Kishon Vijay Abraham I +Link: https://lore.kernel.org/r/20210909064200.16216-2-kishon@ti.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/hcd.c | 29 +++++++++++++++++++++++------ + include/linux/usb/hcd.h | 2 ++ + 2 files changed, 25 insertions(+), 6 deletions(-) + +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -2636,6 +2636,7 @@ int usb_add_hcd(struct usb_hcd *hcd, + { + int retval; + struct usb_device *rhdev; ++ struct usb_hcd *shared_hcd; + + if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) { + hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev); +@@ -2792,13 +2793,26 @@ int usb_add_hcd(struct usb_hcd *hcd, + goto err_hcd_driver_start; + } + ++ /* starting here, usbcore will pay attention to the shared HCD roothub */ ++ shared_hcd = hcd->shared_hcd; ++ if (!usb_hcd_is_primary_hcd(hcd) && shared_hcd && HCD_DEFER_RH_REGISTER(shared_hcd)) { ++ retval = register_root_hub(shared_hcd); ++ if (retval != 0) ++ goto err_register_root_hub; ++ ++ if (shared_hcd->uses_new_polling && HCD_POLL_RH(shared_hcd)) ++ usb_hcd_poll_rh_status(shared_hcd); ++ } ++ + /* starting here, usbcore will pay attention to this root hub */ +- retval = register_root_hub(hcd); +- if (retval != 0) +- goto err_register_root_hub; ++ if (!HCD_DEFER_RH_REGISTER(hcd)) { ++ retval = register_root_hub(hcd); ++ if (retval != 0) ++ goto err_register_root_hub; + +- if (hcd->uses_new_polling && HCD_POLL_RH(hcd)) +- usb_hcd_poll_rh_status(hcd); ++ if (hcd->uses_new_polling && HCD_POLL_RH(hcd)) ++ usb_hcd_poll_rh_status(hcd); ++ } + + return retval; + +@@ -2841,6 +2855,7 @@ EXPORT_SYMBOL_GPL(usb_add_hcd); + void usb_remove_hcd(struct usb_hcd *hcd) + { + struct usb_device *rhdev = hcd->self.root_hub; ++ bool rh_registered; + + dev_info(hcd->self.controller, "remove, state %x\n", hcd->state); + +@@ -2851,6 +2866,7 @@ void usb_remove_hcd(struct usb_hcd *hcd) + + dev_dbg(hcd->self.controller, "roothub graceful disconnect\n"); + spin_lock_irq (&hcd_root_hub_lock); ++ rh_registered = hcd->rh_registered; + hcd->rh_registered = 0; + spin_unlock_irq (&hcd_root_hub_lock); + +@@ -2860,7 +2876,8 @@ void usb_remove_hcd(struct usb_hcd *hcd) + cancel_work_sync(&hcd->died_work); + + mutex_lock(&usb_bus_idr_lock); +- usb_disconnect(&rhdev); /* Sets rhdev to NULL */ ++ if (rh_registered) ++ usb_disconnect(&rhdev); /* Sets rhdev to NULL */ + mutex_unlock(&usb_bus_idr_lock); + + /* +--- a/include/linux/usb/hcd.h ++++ b/include/linux/usb/hcd.h +@@ -124,6 +124,7 @@ struct usb_hcd { + #define HCD_FLAG_RH_RUNNING 5 /* root hub is running? */ + #define HCD_FLAG_DEAD 6 /* controller has died? */ + #define HCD_FLAG_INTF_AUTHORIZED 7 /* authorize interfaces? */ ++#define HCD_FLAG_DEFER_RH_REGISTER 8 /* Defer roothub registration */ + + /* The flags can be tested using these macros; they are likely to + * be slightly faster than test_bit(). +@@ -134,6 +135,7 @@ struct usb_hcd { + #define HCD_WAKEUP_PENDING(hcd) ((hcd)->flags & (1U << HCD_FLAG_WAKEUP_PENDING)) + #define HCD_RH_RUNNING(hcd) ((hcd)->flags & (1U << HCD_FLAG_RH_RUNNING)) + #define HCD_DEAD(hcd) ((hcd)->flags & (1U << HCD_FLAG_DEAD)) ++#define HCD_DEFER_RH_REGISTER(hcd) ((hcd)->flags & (1U << HCD_FLAG_DEFER_RH_REGISTER)) + + /* + * Specifies if interfaces are authorized by default diff --git a/queue-5.4/usb-dwc2-gadget-fix-isoc-flow-for-bdma-and-slave.patch b/queue-5.4/usb-dwc2-gadget-fix-isoc-flow-for-bdma-and-slave.patch new file mode 100644 index 00000000000..7c677972ad6 --- /dev/null +++ b/queue-5.4/usb-dwc2-gadget-fix-isoc-flow-for-bdma-and-slave.patch @@ -0,0 +1,406 @@ +From 91bb163e1e4f88092f50dfaa5a816b658753e4b2 Mon Sep 17 00:00:00 2001 +From: Minas Harutyunyan +Date: Thu, 9 Sep 2021 14:45:15 +0400 +Subject: usb: dwc2: gadget: Fix ISOC flow for BDMA and Slave + +From: Minas Harutyunyan + +commit 91bb163e1e4f88092f50dfaa5a816b658753e4b2 upstream. + +According USB spec each ISOC transaction should be performed in a +designated for that transaction interval. On bus errors or delays +in operating system scheduling of client software can result in no +packet being transferred for a (micro)frame. An error indication +should be returned as status to the client software in such a case. + +Current implementation in case of missed/dropped interval send same +data in next possible interval instead of reporting missed isoc. + +This fix complete requests with -ENODATA if interval elapsed. + +HSOTG core in BDMA and Slave modes haven't HW support for +(micro)frames tracking, this is why SW should care about tracking +of (micro)frames. Because of that method and consider operating +system scheduling delays, added few additional checking's of elapsed +target (micro)frame: +1. Immediately before enabling EP to start transfer. +2. With any transfer completion interrupt. +3. With incomplete isoc in/out interrupt. +4. With EP disabled interrupt because of incomplete transfer. +5. With OUT token received while EP disabled interrupt (for OUT +transfers). +6. With NAK replied to IN token interrupt (for IN transfers). + +As part of ISOC flow, additionally fixed 'current' and 'target' frame +calculation functions. In HS mode SOF limits provided by DSTS register +is 0x3fff, but in non HS mode this limit is 0x7ff. + +Tested by internal tool which also using for dwc3 testing. + +Signed-off-by: Minas Harutyunyan +Cc: stable +Link: https://lore.kernel.org/r/95d1423adf4b0f68187c9894820c4b7e964a3f7f.1631175721.git.Minas.Harutyunyan@synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc2/gadget.c | 189 +++++++++++++++++++++++++--------------------- + 1 file changed, 106 insertions(+), 83 deletions(-) + +--- a/drivers/usb/dwc2/gadget.c ++++ b/drivers/usb/dwc2/gadget.c +@@ -115,10 +115,16 @@ static inline bool using_desc_dma(struct + */ + static inline void dwc2_gadget_incr_frame_num(struct dwc2_hsotg_ep *hs_ep) + { ++ struct dwc2_hsotg *hsotg = hs_ep->parent; ++ u16 limit = DSTS_SOFFN_LIMIT; ++ ++ if (hsotg->gadget.speed != USB_SPEED_HIGH) ++ limit >>= 3; ++ + hs_ep->target_frame += hs_ep->interval; +- if (hs_ep->target_frame > DSTS_SOFFN_LIMIT) { ++ if (hs_ep->target_frame > limit) { + hs_ep->frame_overrun = true; +- hs_ep->target_frame &= DSTS_SOFFN_LIMIT; ++ hs_ep->target_frame &= limit; + } else { + hs_ep->frame_overrun = false; + } +@@ -136,10 +142,16 @@ static inline void dwc2_gadget_incr_fram + */ + static inline void dwc2_gadget_dec_frame_num_by_one(struct dwc2_hsotg_ep *hs_ep) + { ++ struct dwc2_hsotg *hsotg = hs_ep->parent; ++ u16 limit = DSTS_SOFFN_LIMIT; ++ ++ if (hsotg->gadget.speed != USB_SPEED_HIGH) ++ limit >>= 3; ++ + if (hs_ep->target_frame) + hs_ep->target_frame -= 1; + else +- hs_ep->target_frame = DSTS_SOFFN_LIMIT; ++ hs_ep->target_frame = limit; + } + + /** +@@ -1018,6 +1030,12 @@ static void dwc2_gadget_start_isoc_ddma( + dwc2_writel(hsotg, ctrl, depctl); + } + ++static bool dwc2_gadget_target_frame_elapsed(struct dwc2_hsotg_ep *hs_ep); ++static void dwc2_hsotg_complete_request(struct dwc2_hsotg *hsotg, ++ struct dwc2_hsotg_ep *hs_ep, ++ struct dwc2_hsotg_req *hs_req, ++ int result); ++ + /** + * dwc2_hsotg_start_req - start a USB request from an endpoint's queue + * @hsotg: The controller state. +@@ -1170,14 +1188,19 @@ static void dwc2_hsotg_start_req(struct + } + } + +- if (hs_ep->isochronous && hs_ep->interval == 1) { +- hs_ep->target_frame = dwc2_hsotg_read_frameno(hsotg); +- dwc2_gadget_incr_frame_num(hs_ep); +- +- if (hs_ep->target_frame & 0x1) +- ctrl |= DXEPCTL_SETODDFR; +- else +- ctrl |= DXEPCTL_SETEVENFR; ++ if (hs_ep->isochronous) { ++ if (!dwc2_gadget_target_frame_elapsed(hs_ep)) { ++ if (hs_ep->interval == 1) { ++ if (hs_ep->target_frame & 0x1) ++ ctrl |= DXEPCTL_SETODDFR; ++ else ++ ctrl |= DXEPCTL_SETEVENFR; ++ } ++ ctrl |= DXEPCTL_CNAK; ++ } else { ++ dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, -ENODATA); ++ return; ++ } + } + + ctrl |= DXEPCTL_EPENA; /* ensure ep enabled */ +@@ -1325,12 +1348,16 @@ static bool dwc2_gadget_target_frame_ela + u32 target_frame = hs_ep->target_frame; + u32 current_frame = hsotg->frame_number; + bool frame_overrun = hs_ep->frame_overrun; ++ u16 limit = DSTS_SOFFN_LIMIT; ++ ++ if (hsotg->gadget.speed != USB_SPEED_HIGH) ++ limit >>= 3; + + if (!frame_overrun && current_frame >= target_frame) + return true; + + if (frame_overrun && current_frame >= target_frame && +- ((current_frame - target_frame) < DSTS_SOFFN_LIMIT / 2)) ++ ((current_frame - target_frame) < limit / 2)) + return true; + + return false; +@@ -1712,11 +1739,9 @@ static struct dwc2_hsotg_req *get_ep_hea + */ + static void dwc2_gadget_start_next_request(struct dwc2_hsotg_ep *hs_ep) + { +- u32 mask; + struct dwc2_hsotg *hsotg = hs_ep->parent; + int dir_in = hs_ep->dir_in; + struct dwc2_hsotg_req *hs_req; +- u32 epmsk_reg = dir_in ? DIEPMSK : DOEPMSK; + + if (!list_empty(&hs_ep->queue)) { + hs_req = get_ep_head(hs_ep); +@@ -1732,9 +1757,6 @@ static void dwc2_gadget_start_next_reque + } else { + dev_dbg(hsotg->dev, "%s: No more ISOC-OUT requests\n", + __func__); +- mask = dwc2_readl(hsotg, epmsk_reg); +- mask |= DOEPMSK_OUTTKNEPDISMSK; +- dwc2_writel(hsotg, mask, epmsk_reg); + } + } + +@@ -2304,19 +2326,6 @@ static void dwc2_hsotg_ep0_zlp(struct dw + dwc2_hsotg_program_zlp(hsotg, hsotg->eps_out[0]); + } + +-static void dwc2_hsotg_change_ep_iso_parity(struct dwc2_hsotg *hsotg, +- u32 epctl_reg) +-{ +- u32 ctrl; +- +- ctrl = dwc2_readl(hsotg, epctl_reg); +- if (ctrl & DXEPCTL_EOFRNUM) +- ctrl |= DXEPCTL_SETEVENFR; +- else +- ctrl |= DXEPCTL_SETODDFR; +- dwc2_writel(hsotg, ctrl, epctl_reg); +-} +- + /* + * dwc2_gadget_get_xfersize_ddma - get transferred bytes amount from desc + * @hs_ep - The endpoint on which transfer went +@@ -2437,20 +2446,11 @@ static void dwc2_hsotg_handle_outdone(st + dwc2_hsotg_ep0_zlp(hsotg, true); + } + +- /* +- * Slave mode OUT transfers do not go through XferComplete so +- * adjust the ISOC parity here. +- */ +- if (!using_dma(hsotg)) { +- if (hs_ep->isochronous && hs_ep->interval == 1) +- dwc2_hsotg_change_ep_iso_parity(hsotg, DOEPCTL(epnum)); +- else if (hs_ep->isochronous && hs_ep->interval > 1) +- dwc2_gadget_incr_frame_num(hs_ep); +- } +- + /* Set actual frame number for completed transfers */ +- if (!using_desc_dma(hsotg) && hs_ep->isochronous) +- req->frame_number = hsotg->frame_number; ++ if (!using_desc_dma(hsotg) && hs_ep->isochronous) { ++ req->frame_number = hs_ep->target_frame; ++ dwc2_gadget_incr_frame_num(hs_ep); ++ } + + dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, result); + } +@@ -2764,6 +2764,12 @@ static void dwc2_hsotg_complete_in(struc + return; + } + ++ /* Set actual frame number for completed transfers */ ++ if (!using_desc_dma(hsotg) && hs_ep->isochronous) { ++ hs_req->req.frame_number = hs_ep->target_frame; ++ dwc2_gadget_incr_frame_num(hs_ep); ++ } ++ + dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); + } + +@@ -2824,23 +2830,18 @@ static void dwc2_gadget_handle_ep_disabl + + dwc2_hsotg_txfifo_flush(hsotg, hs_ep->fifo_index); + +- if (hs_ep->isochronous) { +- dwc2_hsotg_complete_in(hsotg, hs_ep); +- return; +- } +- + if ((epctl & DXEPCTL_STALL) && (epctl & DXEPCTL_EPTYPE_BULK)) { + int dctl = dwc2_readl(hsotg, DCTL); + + dctl |= DCTL_CGNPINNAK; + dwc2_writel(hsotg, dctl, DCTL); + } +- return; +- } ++ } else { + +- if (dctl & DCTL_GOUTNAKSTS) { +- dctl |= DCTL_CGOUTNAK; +- dwc2_writel(hsotg, dctl, DCTL); ++ if (dctl & DCTL_GOUTNAKSTS) { ++ dctl |= DCTL_CGOUTNAK; ++ dwc2_writel(hsotg, dctl, DCTL); ++ } + } + + if (!hs_ep->isochronous) +@@ -2861,8 +2862,6 @@ static void dwc2_gadget_handle_ep_disabl + /* Update current frame number value. */ + hsotg->frame_number = dwc2_hsotg_read_frameno(hsotg); + } while (dwc2_gadget_target_frame_elapsed(hs_ep)); +- +- dwc2_gadget_start_next_request(hs_ep); + } + + /** +@@ -2879,8 +2878,8 @@ static void dwc2_gadget_handle_ep_disabl + static void dwc2_gadget_handle_out_token_ep_disabled(struct dwc2_hsotg_ep *ep) + { + struct dwc2_hsotg *hsotg = ep->parent; ++ struct dwc2_hsotg_req *hs_req; + int dir_in = ep->dir_in; +- u32 doepmsk; + + if (dir_in || !ep->isochronous) + return; +@@ -2894,28 +2893,39 @@ static void dwc2_gadget_handle_out_token + return; + } + +- if (ep->interval > 1 && +- ep->target_frame == TARGET_FRAME_INITIAL) { ++ if (ep->target_frame == TARGET_FRAME_INITIAL) { + u32 ctrl; + + ep->target_frame = hsotg->frame_number; +- dwc2_gadget_incr_frame_num(ep); ++ if (ep->interval > 1) { ++ ctrl = dwc2_readl(hsotg, DOEPCTL(ep->index)); ++ if (ep->target_frame & 0x1) ++ ctrl |= DXEPCTL_SETODDFR; ++ else ++ ctrl |= DXEPCTL_SETEVENFR; + +- ctrl = dwc2_readl(hsotg, DOEPCTL(ep->index)); +- if (ep->target_frame & 0x1) +- ctrl |= DXEPCTL_SETODDFR; +- else +- ctrl |= DXEPCTL_SETEVENFR; ++ dwc2_writel(hsotg, ctrl, DOEPCTL(ep->index)); ++ } ++ } ++ ++ while (dwc2_gadget_target_frame_elapsed(ep)) { ++ hs_req = get_ep_head(ep); ++ if (hs_req) ++ dwc2_hsotg_complete_request(hsotg, ep, hs_req, -ENODATA); + +- dwc2_writel(hsotg, ctrl, DOEPCTL(ep->index)); ++ dwc2_gadget_incr_frame_num(ep); ++ /* Update current frame number value. */ ++ hsotg->frame_number = dwc2_hsotg_read_frameno(hsotg); + } + +- dwc2_gadget_start_next_request(ep); +- doepmsk = dwc2_readl(hsotg, DOEPMSK); +- doepmsk &= ~DOEPMSK_OUTTKNEPDISMSK; +- dwc2_writel(hsotg, doepmsk, DOEPMSK); ++ if (!ep->req) ++ dwc2_gadget_start_next_request(ep); ++ + } + ++static void dwc2_hsotg_ep_stop_xfr(struct dwc2_hsotg *hsotg, ++ struct dwc2_hsotg_ep *hs_ep); ++ + /** + * dwc2_gadget_handle_nak - handle NAK interrupt + * @hs_ep: The endpoint on which interrupt is asserted. +@@ -2933,7 +2943,9 @@ static void dwc2_gadget_handle_out_token + static void dwc2_gadget_handle_nak(struct dwc2_hsotg_ep *hs_ep) + { + struct dwc2_hsotg *hsotg = hs_ep->parent; ++ struct dwc2_hsotg_req *hs_req; + int dir_in = hs_ep->dir_in; ++ u32 ctrl; + + if (!dir_in || !hs_ep->isochronous) + return; +@@ -2975,13 +2987,29 @@ static void dwc2_gadget_handle_nak(struc + + dwc2_writel(hsotg, ctrl, DIEPCTL(hs_ep->index)); + } +- +- dwc2_hsotg_complete_request(hsotg, hs_ep, +- get_ep_head(hs_ep), 0); + } + +- if (!using_desc_dma(hsotg)) ++ if (using_desc_dma(hsotg)) ++ return; ++ ++ ctrl = dwc2_readl(hsotg, DIEPCTL(hs_ep->index)); ++ if (ctrl & DXEPCTL_EPENA) ++ dwc2_hsotg_ep_stop_xfr(hsotg, hs_ep); ++ else ++ dwc2_hsotg_txfifo_flush(hsotg, hs_ep->fifo_index); ++ ++ while (dwc2_gadget_target_frame_elapsed(hs_ep)) { ++ hs_req = get_ep_head(hs_ep); ++ if (hs_req) ++ dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, -ENODATA); ++ + dwc2_gadget_incr_frame_num(hs_ep); ++ /* Update current frame number value. */ ++ hsotg->frame_number = dwc2_hsotg_read_frameno(hsotg); ++ } ++ ++ if (!hs_ep->req) ++ dwc2_gadget_start_next_request(hs_ep); + } + + /** +@@ -3048,12 +3076,8 @@ static void dwc2_hsotg_epint(struct dwc2 + * need to look at completing IN requests here + * if operating slave mode + */ +- if (hs_ep->isochronous && hs_ep->interval > 1) +- dwc2_gadget_incr_frame_num(hs_ep); +- +- dwc2_hsotg_complete_in(hsotg, hs_ep); +- if (ints & DXEPINT_NAKINTRPT) +- ints &= ~DXEPINT_NAKINTRPT; ++ if (!hs_ep->isochronous || !(ints & DXEPINT_NAKINTRPT)) ++ dwc2_hsotg_complete_in(hsotg, hs_ep); + + if (idx == 0 && !hs_ep->req) + dwc2_hsotg_enqueue_setup(hsotg); +@@ -3062,10 +3086,8 @@ static void dwc2_hsotg_epint(struct dwc2 + * We're using DMA, we need to fire an OutDone here + * as we ignore the RXFIFO. + */ +- if (hs_ep->isochronous && hs_ep->interval > 1) +- dwc2_gadget_incr_frame_num(hs_ep); +- +- dwc2_hsotg_handle_outdone(hsotg, idx); ++ if (!hs_ep->isochronous || !(ints & DXEPINT_OUTTKNEPDIS)) ++ dwc2_hsotg_handle_outdone(hsotg, idx); + } + } + +@@ -4055,6 +4077,7 @@ static int dwc2_hsotg_ep_enable(struct u + mask |= DIEPMSK_NAKMSK; + dwc2_writel(hsotg, mask, DIEPMSK); + } else { ++ epctrl |= DXEPCTL_SNAK; + mask = dwc2_readl(hsotg, DOEPMSK); + mask |= DOEPMSK_OUTTKNEPDISMSK; + dwc2_writel(hsotg, mask, DOEPMSK); diff --git a/queue-5.4/usb-dwc2-gadget-fix-isoc-transfer-complete-handling-for-ddma.patch b/queue-5.4/usb-dwc2-gadget-fix-isoc-transfer-complete-handling-for-ddma.patch new file mode 100644 index 00000000000..3bdafac6c39 --- /dev/null +++ b/queue-5.4/usb-dwc2-gadget-fix-isoc-transfer-complete-handling-for-ddma.patch @@ -0,0 +1,39 @@ +From dbe2518b2d8eabffa74dbf7d9fdd7dacddab7fc0 Mon Sep 17 00:00:00 2001 +From: Minas Harutyunyan +Date: Sat, 11 Sep 2021 22:58:30 +0400 +Subject: usb: dwc2: gadget: Fix ISOC transfer complete handling for DDMA + +From: Minas Harutyunyan + +commit dbe2518b2d8eabffa74dbf7d9fdd7dacddab7fc0 upstream. + +When last descriptor in a descriptor list completed with XferComplete +interrupt, core switching to handle next descriptor and assert BNA +interrupt. Both these interrupts are set while dwc2_hsotg_epint() +handler called. Each interrupt should be handled separately: first +XferComplete interrupt then BNA interrupt, otherwise last completed +transfer will not be giveback to function driver as completed +request. + +Fixes: 729cac693eec ("usb: dwc2: Change ISOC DDMA flow") +Cc: stable +Signed-off-by: Minas Harutyunyan +Link: https://lore.kernel.org/r/a36981accc26cd674c5d8f8da6164344b94ec1fe.1631386531.git.Minas.Harutyunyan@synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc2/gadget.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/usb/dwc2/gadget.c ++++ b/drivers/usb/dwc2/gadget.c +@@ -3067,9 +3067,7 @@ static void dwc2_hsotg_epint(struct dwc2 + + /* In DDMA handle isochronous requests separately */ + if (using_desc_dma(hsotg) && hs_ep->isochronous) { +- /* XferCompl set along with BNA */ +- if (!(ints & DXEPINT_BNAINTR)) +- dwc2_gadget_complete_isoc_request_ddma(hs_ep); ++ dwc2_gadget_complete_isoc_request_ddma(hs_ep); + } else if (dir_in) { + /* + * We get OutDone from the FIFO, so we only diff --git a/queue-5.4/usb-gadget-r8a66597-fix-a-loop-in-set_feature.patch b/queue-5.4/usb-gadget-r8a66597-fix-a-loop-in-set_feature.patch new file mode 100644 index 00000000000..6aa93f2897a --- /dev/null +++ b/queue-5.4/usb-gadget-r8a66597-fix-a-loop-in-set_feature.patch @@ -0,0 +1,39 @@ +From 17956b53ebff6a490baf580a836cbd3eae94892b Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 6 Sep 2021 12:42:21 +0300 +Subject: usb: gadget: r8a66597: fix a loop in set_feature() + +From: Dan Carpenter + +commit 17956b53ebff6a490baf580a836cbd3eae94892b upstream. + +This loop is supposed to loop until if reads something other than +CS_IDST or until it times out after 30,000 attempts. But because of +the || vs && bug, it will never time out and instead it will loop a +minimum of 30,000 times. + +This bug is quite old but the code is only used in USB_DEVICE_TEST_MODE +so it probably doesn't affect regular usage. + +Fixes: 96fe53ef5498 ("usb: gadget: r8a66597-udc: add support for TEST_MODE") +Cc: stable +Reviewed-by: Yoshihiro Shimoda +Acked-by: Felipe Balbi +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/20210906094221.GA10957@kili +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/r8a66597-udc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/r8a66597-udc.c ++++ b/drivers/usb/gadget/udc/r8a66597-udc.c +@@ -1250,7 +1250,7 @@ static void set_feature(struct r8a66597 + do { + tmp = r8a66597_read(r8a66597, INTSTS0) & CTSQ; + udelay(1); +- } while (tmp != CS_IDST || timeout-- > 0); ++ } while (tmp != CS_IDST && timeout-- > 0); + + if (tmp == CS_IDST) + r8a66597_bset(r8a66597, diff --git a/queue-5.4/usb-musb-tusb6010-uninitialized-data-in-tusb_fifo_write_unaligned.patch b/queue-5.4/usb-musb-tusb6010-uninitialized-data-in-tusb_fifo_write_unaligned.patch new file mode 100644 index 00000000000..51157aec68a --- /dev/null +++ b/queue-5.4/usb-musb-tusb6010-uninitialized-data-in-tusb_fifo_write_unaligned.patch @@ -0,0 +1,32 @@ +From 517c7bf99bad3d6b9360558414aae634b7472d80 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 16 Sep 2021 16:57:37 +0300 +Subject: usb: musb: tusb6010: uninitialized data in tusb_fifo_write_unaligned() + +From: Dan Carpenter + +commit 517c7bf99bad3d6b9360558414aae634b7472d80 upstream. + +This is writing to the first 1 - 3 bytes of "val" and then writing all +four bytes to musb_writel(). The last byte is always going to be +garbage. Zero out the last bytes instead. + +Fixes: 550a7375fe72 ("USB: Add MUSB and TUSB support") +Signed-off-by: Dan Carpenter +Cc: stable +Link: https://lore.kernel.org/r/20210916135737.GI25094@kili +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/musb/tusb6010.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/musb/tusb6010.c ++++ b/drivers/usb/musb/tusb6010.c +@@ -190,6 +190,7 @@ tusb_fifo_write_unaligned(void __iomem * + } + if (len > 0) { + /* Write the rest 1 - 3 bytes to FIFO */ ++ val = 0; + memcpy(&val, buf, len); + musb_writel(fifo, 0, val); + } diff --git a/queue-5.4/usb-serial-cp210x-add-id-for-gw-instek-gdm-834x-digital-multimeter.patch b/queue-5.4/usb-serial-cp210x-add-id-for-gw-instek-gdm-834x-digital-multimeter.patch new file mode 100644 index 00000000000..5fe3f40fe57 --- /dev/null +++ b/queue-5.4/usb-serial-cp210x-add-id-for-gw-instek-gdm-834x-digital-multimeter.patch @@ -0,0 +1,30 @@ +From 3bd18ba7d859eb1fbef3beb1e80c24f6f7d7596c Mon Sep 17 00:00:00 2001 +From: Uwe Brandt +Date: Tue, 21 Sep 2021 19:54:46 +0200 +Subject: USB: serial: cp210x: add ID for GW Instek GDM-834x Digital Multimeter + +From: Uwe Brandt + +commit 3bd18ba7d859eb1fbef3beb1e80c24f6f7d7596c upstream. + +Add the USB serial device ID for the GW Instek GDM-834x Digital Multimeter. + +Signed-off-by: Uwe Brandt +Link: https://lore.kernel.org/r/YUxFl3YUCPGJZd8Y@hovoldconsulting.com +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/cp210x.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -234,6 +234,7 @@ static const struct usb_device_id id_tab + { USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */ + { USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */ + { USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */ ++ { USB_DEVICE(0x2184, 0x0030) }, /* GW Instek GDM-834x Digital Multimeter */ + { USB_DEVICE(0x2626, 0xEA60) }, /* Aruba Networks 7xxx USB Serial Console */ + { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ + { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ diff --git a/queue-5.4/usb-serial-mos7840-remove-duplicated-0xac24-device-id.patch b/queue-5.4/usb-serial-mos7840-remove-duplicated-0xac24-device-id.patch new file mode 100644 index 00000000000..95215c6878f --- /dev/null +++ b/queue-5.4/usb-serial-mos7840-remove-duplicated-0xac24-device-id.patch @@ -0,0 +1,39 @@ +From 211f323768a25b30c106fd38f15a0f62c7c2b5f4 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Fri, 17 Sep 2021 11:18:47 +0200 +Subject: USB: serial: mos7840: remove duplicated 0xac24 device ID + +From: Krzysztof Kozlowski + +commit 211f323768a25b30c106fd38f15a0f62c7c2b5f4 upstream. + +0xac24 device ID is already defined and used via +BANDB_DEVICE_ID_USO9ML2_4. Remove the duplicate from the list. + +Fixes: 27f1281d5f72 ("USB: serial: Extra device/vendor ID for mos7840 driver") +Signed-off-by: Krzysztof Kozlowski +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/mos7840.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/usb/serial/mos7840.c ++++ b/drivers/usb/serial/mos7840.c +@@ -114,7 +114,6 @@ + #define BANDB_DEVICE_ID_USOPTL4_2P 0xBC02 + #define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 + #define BANDB_DEVICE_ID_USOPTL4_4P 0xBC03 +-#define BANDB_DEVICE_ID_USOPTL2_4 0xAC24 + + /* This driver also supports + * ATEN UC2324 device using Moschip MCS7840 +@@ -196,7 +195,6 @@ static const struct usb_device_id id_tab + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)}, +- {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, + {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, + {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, + {USB_DEVICE(USB_VENDOR_ID_MOXA, MOXA_DEVICE_ID_2210)}, diff --git a/queue-5.4/usb-serial-option-add-device-id-for-foxconn-t99w265.patch b/queue-5.4/usb-serial-option-add-device-id-for-foxconn-t99w265.patch new file mode 100644 index 00000000000..73e4e77a231 --- /dev/null +++ b/queue-5.4/usb-serial-option-add-device-id-for-foxconn-t99w265.patch @@ -0,0 +1,49 @@ +From 9e3eed534f8235a4a596a9dae5b8a6425d81ea1a Mon Sep 17 00:00:00 2001 +From: Slark Xiao +Date: Fri, 17 Sep 2021 19:01:06 +0800 +Subject: USB: serial: option: add device id for Foxconn T99W265 + +From: Slark Xiao + +commit 9e3eed534f8235a4a596a9dae5b8a6425d81ea1a upstream. + +Adding support for Foxconn device T99W265 for enumeration with +PID 0xe0db. + +usb-devices output for 0xe0db +T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 19 Spd=5000 MxCh= 0 +D: Ver= 3.20 Cls=ef(misc ) Sub=02 Prot=01 MxPS= 9 #Cfgs= 1 +P: Vendor=0489 ProdID=e0db Rev=05.04 +S: Manufacturer=Microsoft +S: Product=Generic Mobile Broadband Adapter +S: SerialNumber=6c50f452 +C: #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=896mA +I: If#=0x0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim +I: If#=0x1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim +I: If#=0x2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +I: If#=0x3 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) +I: If#=0x4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option + +if0/1: MBIM, if2:Diag, if3:GNSS, if4: Modem + +Signed-off-by: Slark Xiao +Link: https://lore.kernel.org/r/20210917110106.9852-1-slark_xiao@163.com +[ johan: use USB_DEVICE_INTERFACE_CLASS(), amend comment ] +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/option.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -2075,6 +2075,8 @@ static const struct usb_device_id option + .driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, + { USB_DEVICE(0x0489, 0xe0b5), /* Foxconn T77W968 ESIM */ + .driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, ++ { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe0db, 0xff), /* Foxconn T99W265 MBIM */ ++ .driver_info = RSVD(3) }, + { USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 (IOT version) */ + .driver_info = RSVD(4) | RSVD(5) | RSVD(6) }, + { USB_DEVICE(0x2cb7, 0x0104), /* Fibocom NL678 series */ diff --git a/queue-5.4/usb-serial-option-add-telit-ln920-compositions.patch b/queue-5.4/usb-serial-option-add-telit-ln920-compositions.patch new file mode 100644 index 00000000000..1cd221df28b --- /dev/null +++ b/queue-5.4/usb-serial-option-add-telit-ln920-compositions.patch @@ -0,0 +1,43 @@ +From 7bb057134d609b9c038a00b6876cf0d37d0118ce Mon Sep 17 00:00:00 2001 +From: Carlo Lobrano +Date: Fri, 3 Sep 2021 14:39:13 +0200 +Subject: USB: serial: option: add Telit LN920 compositions + +From: Carlo Lobrano + +commit 7bb057134d609b9c038a00b6876cf0d37d0118ce upstream. + +This patch adds the following Telit LN920 compositions: + +0x1060: tty, adb, rmnet, tty, tty, tty, tty +0x1061: tty, adb, mbim, tty, tty, tty, tty +0x1062: rndis, tty, adb, tty, tty, tty, tty +0x1063: tty, adb, ecm, tty, tty, tty, tty + +Signed-off-by: Carlo Lobrano +Link: https://lore.kernel.org/r/20210903123913.1086513-1-c.lobrano@gmail.com +Reviewed-by: Daniele Palmas +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/option.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1205,6 +1205,14 @@ static const struct usb_device_id option + .driver_info = NCTRL(0) | RSVD(1) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1056, 0xff), /* Telit FD980 */ + .driver_info = NCTRL(2) | RSVD(3) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1060, 0xff), /* Telit LN920 (rmnet) */ ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1061, 0xff), /* Telit LN920 (MBIM) */ ++ .driver_info = NCTRL(0) | RSVD(1) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1062, 0xff), /* Telit LN920 (RNDIS) */ ++ .driver_info = NCTRL(2) | RSVD(3) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1063, 0xff), /* Telit LN920 (ECM) */ ++ .driver_info = NCTRL(0) | RSVD(1) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), + .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), diff --git a/queue-5.4/usb-serial-option-remove-duplicate-usb-device-id.patch b/queue-5.4/usb-serial-option-remove-duplicate-usb-device-id.patch new file mode 100644 index 00000000000..827a0d359eb --- /dev/null +++ b/queue-5.4/usb-serial-option-remove-duplicate-usb-device-id.patch @@ -0,0 +1,30 @@ +From 1ca200a8c6f079950a04ea3c3380fe8cf78e95a2 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Fri, 17 Sep 2021 11:18:48 +0200 +Subject: USB: serial: option: remove duplicate USB device ID + +From: Krzysztof Kozlowski + +commit 1ca200a8c6f079950a04ea3c3380fe8cf78e95a2 upstream. + +The device ZTE 0x0094 is already on the list. + +Signed-off-by: Krzysztof Kozlowski +Fixes: b9e44fe5ecda ("USB: option: cleanup zte 3g-dongle's pid in option.c") +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/option.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1658,7 +1658,6 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff), + .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff), diff --git a/queue-5.4/usb-storage-add-quirk-for-scanlogic-sl11r-ide-older-than-2.6c.patch b/queue-5.4/usb-storage-add-quirk-for-scanlogic-sl11r-ide-older-than-2.6c.patch new file mode 100644 index 00000000000..787dc99de30 --- /dev/null +++ b/queue-5.4/usb-storage-add-quirk-for-scanlogic-sl11r-ide-older-than-2.6c.patch @@ -0,0 +1,59 @@ +From b55d37ef6b7db3eda9b4495a8d9b0a944ee8c67d Mon Sep 17 00:00:00 2001 +From: Ondrej Zary +Date: Mon, 13 Sep 2021 23:01:06 +0200 +Subject: usb-storage: Add quirk for ScanLogic SL11R-IDE older than 2.6c + +From: Ondrej Zary + +commit b55d37ef6b7db3eda9b4495a8d9b0a944ee8c67d upstream. + +ScanLogic SL11R-IDE with firmware older than 2.6c (the latest one) has +broken tag handling, preventing the device from working at all: +usb 1-1: new full-speed USB device number 2 using uhci_hcd +usb 1-1: New USB device found, idVendor=04ce, idProduct=0002, bcdDevice= 2.60 +usb 1-1: New USB device strings: Mfr=1, Product=1, SerialNumber=0 +usb 1-1: Product: USB Device +usb 1-1: Manufacturer: USB Device +usb-storage 1-1:1.0: USB Mass Storage device detected +scsi host2: usb-storage 1-1:1.0 +usbcore: registered new interface driver usb-storage +usb 1-1: reset full-speed USB device number 2 using uhci_hcd +usb 1-1: reset full-speed USB device number 2 using uhci_hcd +usb 1-1: reset full-speed USB device number 2 using uhci_hcd +usb 1-1: reset full-speed USB device number 2 using uhci_hcd + +Add US_FL_BULK_IGNORE_TAG to fix it. Also update my e-mail address. + +2.6c is the only firmware that claims Linux compatibility. +The firmware can be upgraded using ezotgdbg utility: +https://github.com/asciilifeform/ezotgdbg + +Acked-by: Alan Stern +Signed-off-by: Ondrej Zary +Cc: stable +Link: https://lore.kernel.org/r/20210913210106.12717-1-linux@zary.sk +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/storage/unusual_devs.h | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -416,9 +416,16 @@ UNUSUAL_DEV( 0x04cb, 0x0100, 0x0000, 0x + USB_SC_UFI, USB_PR_DEVICE, NULL, US_FL_FIX_INQUIRY | US_FL_SINGLE_LUN), + + /* +- * Reported by Ondrej Zary ++ * Reported by Ondrej Zary + * The device reports one sector more and breaks when that sector is accessed ++ * Firmwares older than 2.6c (the latest one and the only that claims Linux ++ * support) have also broken tag handling + */ ++UNUSUAL_DEV( 0x04ce, 0x0002, 0x0000, 0x026b, ++ "ScanLogic", ++ "SL11R-IDE", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_FIX_CAPACITY | US_FL_BULK_IGNORE_TAG), + UNUSUAL_DEV( 0x04ce, 0x0002, 0x026c, 0x026c, + "ScanLogic", + "SL11R-IDE", diff --git a/queue-5.4/xen-x86-fix-pv-trap-handling-on-secondary-processors.patch b/queue-5.4/xen-x86-fix-pv-trap-handling-on-secondary-processors.patch new file mode 100644 index 00000000000..705b8353e3d --- /dev/null +++ b/queue-5.4/xen-x86-fix-pv-trap-handling-on-secondary-processors.patch @@ -0,0 +1,98 @@ +From 0594c58161b6e0f3da8efa9c6e3d4ba52b652717 Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Mon, 20 Sep 2021 18:15:11 +0200 +Subject: xen/x86: fix PV trap handling on secondary processors + +From: Jan Beulich + +commit 0594c58161b6e0f3da8efa9c6e3d4ba52b652717 upstream. + +The initial observation was that in PV mode under Xen 32-bit user space +didn't work anymore. Attempts of system calls ended in #GP(0x402). All +of the sudden the vector 0x80 handler was not in place anymore. As it +turns out up to 5.13 redundant initialization did occur: Once from +cpu_initialize_context() (through its VCPUOP_initialise hypercall) and a +2nd time while each CPU was brought fully up. This 2nd initialization is +now gone, uncovering that the 1st one was flawed: Unlike for the +set_trap_table hypercall, a full virtual IDT needs to be specified here; +the "vector" fields of the individual entries are of no interest. With +many (kernel) IDT entries still(?) (i.e. at that point at least) empty, +the syscall vector 0x80 ended up in slot 0x20 of the virtual IDT, thus +becoming the domain's handler for vector 0x20. + +Make xen_convert_trap_info() fit for either purpose, leveraging the fact +that on the xen_copy_trap_info() path the table starts out zero-filled. +This includes moving out the writing of the sentinel, which would also +have lead to a buffer overrun in the xen_copy_trap_info() case if all +(kernel) IDT entries were populated. Convert the writing of the sentinel +to clearing of the entire table entry rather than just the address +field. + +(I didn't bother trying to identify the commit which uncovered the issue +in 5.14; the commit named below is the one which actually introduced the +bad code.) + +Fixes: f87e4cac4f4e ("xen: SMP guest support") +Cc: stable@vger.kernel.org +Signed-off-by: Jan Beulich +Reviewed-by: Boris Ostrovsky +Link: https://lore.kernel.org/r/7a266932-092e-b68f-f2bb-1473b61adc6e@suse.com +Signed-off-by: Juergen Gross +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/xen/enlighten_pv.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/arch/x86/xen/enlighten_pv.c ++++ b/arch/x86/xen/enlighten_pv.c +@@ -727,8 +727,8 @@ static void xen_write_idt_entry(gate_des + preempt_enable(); + } + +-static void xen_convert_trap_info(const struct desc_ptr *desc, +- struct trap_info *traps) ++static unsigned xen_convert_trap_info(const struct desc_ptr *desc, ++ struct trap_info *traps, bool full) + { + unsigned in, out, count; + +@@ -738,17 +738,18 @@ static void xen_convert_trap_info(const + for (in = out = 0; in < count; in++) { + gate_desc *entry = (gate_desc *)(desc->address) + in; + +- if (cvt_gate_to_trap(in, entry, &traps[out])) ++ if (cvt_gate_to_trap(in, entry, &traps[out]) || full) + out++; + } +- traps[out].address = 0; ++ ++ return out; + } + + void xen_copy_trap_info(struct trap_info *traps) + { + const struct desc_ptr *desc = this_cpu_ptr(&idt_desc); + +- xen_convert_trap_info(desc, traps); ++ xen_convert_trap_info(desc, traps, true); + } + + /* Load a new IDT into Xen. In principle this can be per-CPU, so we +@@ -758,6 +759,7 @@ static void xen_load_idt(const struct de + { + static DEFINE_SPINLOCK(lock); + static struct trap_info traps[257]; ++ unsigned out; + + trace_xen_cpu_load_idt(desc); + +@@ -765,7 +767,8 @@ static void xen_load_idt(const struct de + + memcpy(this_cpu_ptr(&idt_desc), desc, sizeof(idt_desc)); + +- xen_convert_trap_info(desc, traps); ++ out = xen_convert_trap_info(desc, traps, false); ++ memset(&traps[out], 0, sizeof(traps[0])); + + xen_mc_flush(); + if (HYPERVISOR_set_trap_table(traps))