This is a note to let you know that I've just added the patch titled
usb: xhci: do not perform Soft Retry for some xHCI hosts
to my usb git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
in the usb-linus branch.
The patch will show up in the next release of the linux-next tree
(usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the
next -rc kernel release.
If you have any questions about this process, please let me know.
>From a4a251f8c23518899d2078c320cf9ce2fa459c9f Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <stf_xl(a)wp.pl>
Date: Thu, 11 Mar 2021 13:53:50 +0200
Subject: usb: xhci: do not perform Soft Retry for some xHCI hosts
On some systems rt2800usb and mt7601u devices are unable to operate since
commit f8f80be501aa ("xhci: Use soft retry to recover faster from
transaction errors")
Seems that some xHCI controllers can not perform Soft Retry correctly,
affecting those devices.
To avoid the problem add xhci->quirks flag that restore pre soft retry
xhci behaviour for affected xHCI controllers. Currently those are
AMD_PROMONTORYA_4 and AMD_PROMONTORYA_2, since it was confirmed
by the users: on those xHCI hosts issue happen and is gone after
disabling Soft Retry.
[minor commit message rewording for checkpatch -Mathias]
Fixes: f8f80be501aa ("xhci: Use soft retry to recover faster from transaction errors")
Cc: <stable(a)vger.kernel.org> # 4.20+
Reported-by: Bernhard <bernhard.gebetsberger(a)gmx.at>
Tested-by: Bernhard <bernhard.gebetsberger(a)gmx.at>
Signed-off-by: Stanislaw Gruszka <stf_xl(a)wp.pl>
Signed-off-by: Mathias Nyman <mathias.nyman(a)linux.intel.com>
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202541
Link: https://lore.kernel.org/r/20210311115353.2137560-2-mathias.nyman@linux.inte…
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/usb/host/xhci-pci.c | 5 +++++
drivers/usb/host/xhci-ring.c | 3 ++-
drivers/usb/host/xhci.h | 1 +
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 84da8406d5b4..1f989a49c8c6 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -295,6 +295,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
pdev->device == 0x9026)
xhci->quirks |= XHCI_RESET_PLL_ON_DISCONNECT;
+ if (pdev->vendor == PCI_VENDOR_ID_AMD &&
+ (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2 ||
+ pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4))
+ xhci->quirks |= XHCI_NO_SOFT_RETRY;
+
if (xhci->quirks & XHCI_RESET_ON_RESUME)
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"QUIRK: Resetting on resume");
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 5e548a1c93ab..ce38076901e2 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2484,7 +2484,8 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
remaining = 0;
break;
case COMP_USB_TRANSACTION_ERROR:
- if ((ep_ring->err_count++ > MAX_SOFT_RETRY) ||
+ if (xhci->quirks & XHCI_NO_SOFT_RETRY ||
+ (ep_ring->err_count++ > MAX_SOFT_RETRY) ||
le32_to_cpu(slot_ctx->tt_info) & TT_SLOT)
break;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index d41de5dc0452..ca822ad3b65b 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1891,6 +1891,7 @@ struct xhci_hcd {
#define XHCI_SKIP_PHY_INIT BIT_ULL(37)
#define XHCI_DISABLE_SPARSE BIT_ULL(38)
#define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39)
+#define XHCI_NO_SOFT_RETRY BIT_ULL(40)
unsigned int num_active_eps;
unsigned int limit_active_eps;
--
2.30.2
If port terminations are detected in suspend, but link never reaches U0
then xHCI may have an internal uncleared wake state that will cause an
immediate wake after suspend.
This wake state is normally cleared when driver clears the PORT_CSC bit,
which is set after a device is enabled and in U0.
Write 1 to clear PORT_CSC for ports that don't have anything connected
when suspending. This makes sure any pending internal wake states in
xHCI are cleared.
Cc: stable(a)vger.kernel.org
Tested-by: Mika Westerberg <mika.westerberg(a)linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman(a)linux.intel.com>
---
drivers/usb/host/xhci.c | 62 ++++++++++++++++++++---------------------
1 file changed, 30 insertions(+), 32 deletions(-)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 48a68fcf2b36..1975016f46bf 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -883,44 +883,42 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
xhci_set_cmd_ring_deq(xhci);
}
-static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci)
+/*
+ * Disable port wake bits if do_wakeup is not set.
+ *
+ * Also clear a possible internal port wake state left hanging for ports that
+ * detected termination but never successfully enumerated (trained to 0U).
+ * Internal wake causes immediate xHCI wake after suspend. PORT_CSC write done
+ * at enumeration clears this wake, force one here as well for unconnected ports
+ */
+
+static void xhci_disable_hub_port_wake(struct xhci_hcd *xhci,
+ struct xhci_hub *rhub,
+ bool do_wakeup)
{
- struct xhci_port **ports;
- int port_index;
unsigned long flags;
u32 t1, t2, portsc;
+ int i;
spin_lock_irqsave(&xhci->lock, flags);
- /* disable usb3 ports Wake bits */
- port_index = xhci->usb3_rhub.num_ports;
- ports = xhci->usb3_rhub.ports;
- while (port_index--) {
- t1 = readl(ports[port_index]->addr);
- portsc = t1;
- t1 = xhci_port_state_to_neutral(t1);
- t2 = t1 & ~PORT_WAKE_BITS;
- if (t1 != t2) {
- writel(t2, ports[port_index]->addr);
- xhci_dbg(xhci, "disable wake bits port %d-%d, portsc: 0x%x, write: 0x%x\n",
- xhci->usb3_rhub.hcd->self.busnum,
- port_index + 1, portsc, t2);
- }
- }
+ for (i = 0; i < rhub->num_ports; i++) {
+ portsc = readl(rhub->ports[i]->addr);
+ t1 = xhci_port_state_to_neutral(portsc);
+ t2 = t1;
+
+ /* clear wake bits if do_wake is not set */
+ if (!do_wakeup)
+ t2 &= ~PORT_WAKE_BITS;
+
+ /* Don't touch csc bit if connected or connect change is set */
+ if (!(portsc & (PORT_CSC | PORT_CONNECT)))
+ t2 |= PORT_CSC;
- /* disable usb2 ports Wake bits */
- port_index = xhci->usb2_rhub.num_ports;
- ports = xhci->usb2_rhub.ports;
- while (port_index--) {
- t1 = readl(ports[port_index]->addr);
- portsc = t1;
- t1 = xhci_port_state_to_neutral(t1);
- t2 = t1 & ~PORT_WAKE_BITS;
if (t1 != t2) {
- writel(t2, ports[port_index]->addr);
- xhci_dbg(xhci, "disable wake bits port %d-%d, portsc: 0x%x, write: 0x%x\n",
- xhci->usb2_rhub.hcd->self.busnum,
- port_index + 1, portsc, t2);
+ writel(t2, rhub->ports[i]->addr);
+ xhci_dbg(xhci, "config port %d-%d wake bits, portsc: 0x%x, write: 0x%x\n",
+ rhub->hcd->self.busnum, i + 1, portsc, t2);
}
}
spin_unlock_irqrestore(&xhci->lock, flags);
@@ -983,8 +981,8 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
return -EINVAL;
/* Clear root port wake on bits if wakeup not allowed. */
- if (!do_wakeup)
- xhci_disable_port_wake_on_bits(xhci);
+ xhci_disable_hub_port_wake(xhci, &xhci->usb3_rhub, do_wakeup);
+ xhci_disable_hub_port_wake(xhci, &xhci->usb2_rhub, do_wakeup);
if (!HCD_HW_ACCESSIBLE(hcd))
return 0;
--
2.25.1
From: Daniel Rosenberg <drosen(a)google.com>
__configfs_open_file() used to use configfs_get_config_item, but changed
in commit b0841eefd969 ("configfs: provide exclusion between IO and
removals") to just call to_item. The error path still tries to clean up
the reference, incorrectly decrementing the ref count.
Signed-off-by: Daniel Rosenberg <drosen(a)google.com>
Cc: stable(a)vger.kernel.org
Fixes: b0841eefd969 ("configfs: provide exclusion between IO and removals")
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
v2: goto the correct out_ label as pointed out by Christoph
fs/configfs/file.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/fs/configfs/file.c b/fs/configfs/file.c
index 1f0270229d7b..da8351d1e455 100644
--- a/fs/configfs/file.c
+++ b/fs/configfs/file.c
@@ -378,7 +378,7 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type
attr = to_attr(dentry);
if (!attr)
- goto out_put_item;
+ goto out_free_buffer;
if (type & CONFIGFS_ITEM_BIN_ATTR) {
buffer->bin_attr = to_bin_attr(dentry);
@@ -391,7 +391,7 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type
/* Grab the module reference for this attribute if we have one */
error = -ENODEV;
if (!try_module_get(buffer->owner))
- goto out_put_item;
+ goto out_free_buffer;
error = -EACCES;
if (!buffer->item->ci_type)
@@ -435,8 +435,6 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type
out_put_module:
module_put(buffer->owner);
-out_put_item:
- config_item_put(buffer->item);
out_free_buffer:
up_read(&frag->frag_sem);
kfree(buffer);
--
2.30.2
From: Daniel Rosenberg <drosen(a)google.com>
__configfs_open_file() used to use configfs_get_config_item, but changed
in commit b0841eefd969 ("configfs: provide exclusion between IO and
removals") to just call to_item. The error path still tries to clean up
the reference, incorrectly decrementing the ref count.
Signed-off-by: Daniel Rosenberg <drosen(a)google.com>
Cc: stable(a)vger.kernel.org
Fixes: b0841eefd969 ("configfs: provide exclusion between IO and removals")
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
fs/configfs/file.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/fs/configfs/file.c b/fs/configfs/file.c
index 1f0270229d7b..8b7c8a8a09f3 100644
--- a/fs/configfs/file.c
+++ b/fs/configfs/file.c
@@ -378,7 +378,7 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type
attr = to_attr(dentry);
if (!attr)
- goto out_put_item;
+ goto out_put_module;
if (type & CONFIGFS_ITEM_BIN_ATTR) {
buffer->bin_attr = to_bin_attr(dentry);
@@ -391,7 +391,7 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type
/* Grab the module reference for this attribute if we have one */
error = -ENODEV;
if (!try_module_get(buffer->owner))
- goto out_put_item;
+ goto out_put_module;
error = -EACCES;
if (!buffer->item->ci_type)
@@ -435,8 +435,6 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type
out_put_module:
module_put(buffer->owner);
-out_put_item:
- config_item_put(buffer->item);
out_free_buffer:
up_read(&frag->frag_sem);
kfree(buffer);
--
2.30.2
Hello Dmitry,
On Wed, Mar 03, 2021 at 07:32:23PM +0100, Uwe Kleine-König wrote:
> Hello,
>
> On Wed, Mar 03, 2021 at 11:13:21AM +0800, jingle wrote:
> > HI uwe:
> >
> > Please updates this patchs.
> >
> > https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git/commit/?h=ne…
> >
> > https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git/commit/?h=ne…
>
> The first was one of the two patches I already tried, but the latter
> indeed fixes my problem \o/.
>
> @Dmitry: If you don't consider your tree stable, feel free to add a
>
> Tested-by: Uwe Kleine-König <u.kleine-koenig(a)pengutronix.de>
>
> to e4c9062717feda88900b566463228d1c4910af6d.
Do you consider this patch for stable? I'd like to see it in Debian's
5.10 kernel and I guess I'm not the only one who would benefit from such
a backport.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | https://www.pengutronix.de/ |
From: Jim Lin <jilin(a)nvidia.com>
When gadget is disconnected, running sequence is like this.
. composite_disconnect
. Call trace:
usb_string_copy+0xd0/0x128
gadget_config_name_configuration_store+0x4
gadget_config_name_attr_store+0x40/0x50
configfs_write_file+0x198/0x1f4
vfs_write+0x100/0x220
SyS_write+0x58/0xa8
. configfs_composite_unbind
. configfs_composite_bind
In configfs_composite_bind, it has
"cn->strings.s = cn->configuration;"
When usb_string_copy is invoked. it would
allocate memory, copy input string, release previous pointed memory space,
and use new allocated memory.
When gadget is connected, host sends down request to get information.
Call trace:
usb_gadget_get_string+0xec/0x168
lookup_string+0x64/0x98
composite_setup+0xa34/0x1ee8
If gadget is disconnected and connected quickly, in the failed case,
cn->configuration memory has been released by usb_string_copy kfree but
configfs_composite_bind hasn't been run in time to assign new allocated
"cn->configuration" pointer to "cn->strings.s".
When "strlen(s->s) of usb_gadget_get_string is being executed, the dangling
memory is accessed, "BUG: KASAN: use-after-free" error occurs.
Signed-off-by: Jim Lin <jilin(a)nvidia.com>
Signed-off-by: Macpaul Lin <macpaul.lin(a)mediatek.com>
Cc: stable(a)vger.kernel.org
---
Changes in v2:
Changes in v3:
- Change commit description
Changes in v4:
- Fix build error and adapt patch to kernel-5.12-rc1.
Replace definition "MAX_USB_STRING_WITH_NULL_LEN" with
"USB_MAX_STRING_WITH_NULL_LEN".
- Note: The patch v2 and v3 has been verified by
Thadeu Lima de Souza Cascardo <cascardo(a)canonical.com>
http://spinics.net/lists/kernel/msg3840792.html
and
Macpaul Lin <macpaul.lin(a)mediatek.com> on Android kernels.
http://lkml.org/lkml/2020/6/11/8
- The patch is suggested to be applied to LTS versions.
drivers/usb/gadget/configfs.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index 0d56f33..15a607c 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -97,6 +97,8 @@ struct gadget_config_name {
struct list_head list;
};
+#define USB_MAX_STRING_WITH_NULL_LEN (USB_MAX_STRING_LEN+1)
+
static int usb_string_copy(const char *s, char **s_copy)
{
int ret;
@@ -106,12 +108,16 @@ static int usb_string_copy(const char *s, char **s_copy)
if (ret > USB_MAX_STRING_LEN)
return -EOVERFLOW;
- str = kstrdup(s, GFP_KERNEL);
- if (!str)
- return -ENOMEM;
+ if (copy) {
+ str = copy;
+ } else {
+ str = kmalloc(USB_MAX_STRING_WITH_NULL_LEN, GFP_KERNEL);
+ if (!str)
+ return -ENOMEM;
+ }
+ strcpy(str, s);
if (str[ret - 1] == '\n')
str[ret - 1] = '\0';
- kfree(copy);
*s_copy = str;
return 0;
}
--
1.7.9.5
From: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
This is the start of the stable review cycle for the 4.4.261 release.
There are 7 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Fri, 12 Mar 2021 13:23:09 +0000.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.261-rc…
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Linux 4.4.261-rc1
Bjorn Helgaas <bhelgaas(a)google.com>
PCI: Add function 1 DMA alias quirk for Marvell 9215 SATA controller
Hans de Goede <hdegoede(a)redhat.com>
platform/x86: acer-wmi: Add new force_caps module parameter
Jeffle Xu <jefflexu(a)linux.alibaba.com>
dm table: fix iterate_devices based device capability checks
Dan Carpenter <dan.carpenter(a)oracle.com>
rsxx: Return -EFAULT if copy_to_user() fails
Colin Ian King <colin.king(a)canonical.com>
ALSA: ctxfi: cthw20k2: fix mask on conf to allow 4 bits
Thomas Schoebel-Theuer <tst(a)1und1.de>
futex: fix spin_lock() / spin_unlock_irq() imbalance
Thomas Schoebel-Theuer <tst(a)1und1.de>
futex: fix irq self-deadlock and satisfy assertion
-------------
Diffstat:
Makefile | 4 +-
drivers/block/rsxx/core.c | 8 ++--
drivers/md/dm-table.c | 83 ++++++++++++++++++++++++++---------------
drivers/pci/quirks.c | 3 ++
drivers/platform/x86/acer-wmi.c | 8 +++-
kernel/futex.c | 4 +-
sound/pci/ctxfi/cthw20k2.c | 2 +-
7 files changed, 74 insertions(+), 38 deletions(-)
From: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
This is the start of the stable review cycle for the 4.9.261 release.
There are 11 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Fri, 12 Mar 2021 13:23:09 +0000.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.9.261-rc…
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.9.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Linux 4.9.261-rc1
Aswath Govindraju <a-govindraju(a)ti.com>
misc: eeprom_93xx46: Add quirk to support Microchip 93LC46B eeprom
Bjorn Helgaas <bhelgaas(a)google.com>
PCI: Add function 1 DMA alias quirk for Marvell 9215 SATA controller
Hans de Goede <hdegoede(a)redhat.com>
platform/x86: acer-wmi: Add new force_caps module parameter
Andrey Ryabinin <arbn(a)yandex-team.com>
iommu/amd: Fix sleeping in atomic in increase_address_space()
Jeffle Xu <jefflexu(a)linux.alibaba.com>
dm table: fix DAX iterate_devices based device capability checks
Jeffle Xu <jefflexu(a)linux.alibaba.com>
dm table: fix iterate_devices based device capability checks
Dan Carpenter <dan.carpenter(a)oracle.com>
rsxx: Return -EFAULT if copy_to_user() fails
Colin Ian King <colin.king(a)canonical.com>
ALSA: ctxfi: cthw20k2: fix mask on conf to allow 4 bits
Antonio Borneo <borneo.antonio(a)gmail.com>
usbip: tools: fix build error for multiple definition
Ira Weiny <ira.weiny(a)intel.com>
btrfs: fix raid6 qstripe kmap
David Sterba <dsterba(a)suse.com>
btrfs: raid56: simplify tracking of Q stripe presence
-------------
Diffstat:
Makefile | 4 +-
drivers/block/rsxx/core.c | 8 ++-
drivers/iommu/amd_iommu.c | 10 ++--
drivers/md/dm-table.c | 91 +++++++++++++++++++-----------
drivers/misc/eeprom/eeprom_93xx46.c | 15 +++++
drivers/pci/quirks.c | 3 +
drivers/platform/x86/acer-wmi.c | 8 ++-
fs/btrfs/raid56.c | 58 ++++++++-----------
include/linux/eeprom_93xx46.h | 2 +
sound/pci/ctxfi/cthw20k2.c | 2 +-
tools/usb/usbip/libsrc/usbip_host_common.c | 2 +-
11 files changed, 124 insertions(+), 79 deletions(-)