usb: core: stop USB enumeration if too many retries
PATCH v5 1/1 usb: core: stop USB enumeration if too many retries
When a broken USB accessory connects to a USB host, usbcore might keep doing enumeration retries. If the host has a watchdog mechanism, the kernel panic will happen on the host.
This patch provides an attribute early_stop to limit the numbers of retries for each port of a hub. If a port was marked with early_stop attribute, unsuccessful connection attempts will fail quickly. In addition, if an early_stop port has failed to initialize, it will ignore all future connection events until early_stop attribute is clear.
---
Changes since v4:
- change the location of calling hub_port_stop_enumerate()
- modify if statement in hub_port_stop_enumerate()
- modify if statement in port_event()
Changes since v3:
- rename the attribute from quick_init to early_stop
- rename the variable of port_dev from ignore_connect to ignore_event
- modify changelog, documentation
- add more comments for hub_port_stop_enumerate()
Changes since v2:
- replace the quirk with the attribute
- Document the attribute
- modify hub_port_stop_enumerate() position in port_event()
- modify the changelog
Changes since v1:
- remove usb_hub_set_port_power()
- add a variable ignore_connect into struct port_dev
- modify hub_port_stop_enumerate() and set ignore_connect in this function
- avoid calling hub_port_connect_change() in port_event()
--- Documentation/ABI/testing/sysfs-bus-usb | 11 +++++ drivers/usb/core/hub.c | 60 +++++++++++++++++++++++++ drivers/usb/core/hub.h | 4 ++ drivers/usb/core/port.c | 27 +++++++++++ 4 files changed, 102 insertions(+)
Documentation/ABI/testing/sysfs-bus-usb +11 -0
@@ -264,6 +264,17 @@ Description: attached to the port will not be detected, initialized, or enumerated. +What: /sys/bus/usb/devices/.../<hub_interface>/port<X>/early_stop +Date: Sep 2022 +Contact: Ray Chi <[email protected]> +Description: + Some USB hosts have some watchdog mechanisms so that the device + may enter ramdump if it takes a long time during port initialization. + This attribute allows each port just has two attempts so that the + port initialization will be failed quickly. In addition, if a port + which is marked with early_stop has failed to initialize, it will ignore + all future connections until this attribute is clear. + What: /sys/bus/usb/devices/.../power/usb2_lpm_l1_timeout Date: May 2013 Contact: Mathias Nyman <[email protected]>
drivers/usb/core/hub.c +60 -0
90 lines not on this page · raw message
drivers/usb/core/hub.h +4 -0
@@ -90,6 +90,8 @@ struct usb_hub {* @is_superspeed cache super-speed status * @usb3_lpm_u1_permit: whether USB3 U1 LPM is permitted. * @usb3_lpm_u2_permit: whether USB3 U2 LPM is permitted. +* @early_stop: whether port initialization will be stopped earlier. +* @ignore_event: whether events of the port are ignored. */ struct usb_port {struct usb_device *child;
@@ -103,6 +105,8 @@ struct usb_port {u32 over_current_count;u8 portnum;u32 quirks; + unsigned int early_stop:1; + unsigned int ignore_event:1; unsigned int is_superspeed:1; unsigned int usb3_lpm_u1_permit:1; unsigned int usb3_lpm_u2_permit:1;
drivers/usb/core/port.c +27 -0
@@ -18,6 +18,32 @@ static int usb_port_block_power_off;static const struct attribute_group *port_dev_group[]; +static ssize_t early_stop_show (struct device *dev, +struct device_attribute *attr,char *buf) +{ +struct usb_port *port_dev =to_usb_port (dev); + +return sysfs_emit (buf,"%s\n" , port_dev->early_stop ?"yes" :"no" ); +} + +static ssize_t early_stop_store (struct device *dev,struct device_attribute *attr, +const char *buf,size_t count) +{ +struct usb_port *port_dev =to_usb_port (dev); +bool value; + +if (kstrtobool (buf, &value)) +return -EINVAL ; + +if (value) + port_dev->early_stop =1 ; +else + port_dev->early_stop =0 ; + +return count; +} +static DEVICE_ATTR_RW (early_stop); +static ssize_t disable_show (struct device *dev,struct device_attribute *attr,char *buf) {
@@ -237,6 +263,7 @@ static struct attribute *port_dev_attrs[] = { &dev_attr_quirks.attr, &dev_attr_over_current_count.attr, &dev_attr_disable.attr, + &dev_attr_early_stop.attr, NULL, };
Signature · 1 line
2.38.1.431.g37b22c650d-goog
Quoted 4 lines · Ray Chi
When a broken USB accessory connects to a USB host, usbcore might keep doing enumeration retries. If the host has a watchdog mechanism, the kernel panic will happen on the host.
Quoted 8 lines
This patch provides an attribute
early_stopto limit the numbers of retries for each port of a hub. If a port was marked withearly_stopattribute, unsuccessful connection attempts will fail quickly. In addition, if anearly_stopport has failed to initialize, it will ignore all future connection events untilearly_stopattribute is clear.Signed-off-by Ray Chi <[email protected]>---
This looks good.
Alan Stern
Greg KH
maintainerQuoted 4 lines · Ray Chi
When a broken USB accessory connects to a USB host, usbcore might keep doing enumeration retries. If the host has a watchdog mechanism, the kernel panic will happen on the host.
Quoted 8 lines
This patch provides an attribute
early_stopto limit the numbers of retries for each port of a hub. If a port was marked withearly_stopattribute, unsuccessful connection attempts will fail quickly. In addition, if anearly_stopport has failed to initialize, it will ignore all future connection events untilearly_stopattribute is clear.Signed-off-by Ray Chi <[email protected]>---
Much nicer, thanks for sticking with this! I'll go queue it up now
greg k-h