[08/11] usb: Add USB subsystem notifications [ver #7]
diff mbox series

Message ID 156717350329.2204.7056537095039252263.stgit@warthog.procyon.org.uk
State New
Headers show
Series
  • Keyrings, Block and USB notifications [ver #7]
Related show

Commit Message

David Howells Aug. 30, 2019, 1:58 p.m. UTC
Add a USB subsystem notification mechanism whereby notifications about
hardware events such as device connection, disconnection, reset and I/O
errors, can be reported to a monitoring process asynchronously.

Firstly, an event queue needs to be created:

	fd = open("/dev/event_queue", O_RDWR);
	ioctl(fd, IOC_WATCH_QUEUE_SET_SIZE, page_size << n);

then a notification can be set up to report USB notifications via that
queue:

	struct watch_notification_filter filter = {
		.nr_filters = 1,
		.filters = {
			[0] = {
				.type = WATCH_TYPE_USB_NOTIFY,
				.subtype_filter[0] = UINT_MAX;
			},
		},
	};
	ioctl(fd, IOC_WATCH_QUEUE_SET_FILTER, &filter);
	notify_devices(fd, 12);

After that, records will be placed into the queue when events occur on a
USB device or bus.  Records are of the following format:

	struct usb_notification {
		struct watch_notification watch;
		__u32	error;
		__u32	reserved;
		__u8	name_len;
		__u8	name[0];
	} *n;

Where:

	n->watch.type will be WATCH_TYPE_USB_NOTIFY

	n->watch.subtype will be the type of notification, such as
	NOTIFY_USB_DEVICE_ADD.

	n->watch.info & WATCH_INFO_LENGTH will indicate the length of the
	record.

	n->watch.info & WATCH_INFO_ID will be the second argument to
	device_notify(), shifted.

	n->error and n->reserved are intended to convey information such as
	error codes, but are currently not used

	n->name_len and n->name convey the USB device name as an
	unterminated string.  This may be truncated - it is currently
	limited to a maximum 63 chars.

Note that it is permissible for event records to be of variable length -
or, at least, the length may be dependent on the subtype.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
cc: linux-usb@vger.kernel.org
---

 Documentation/watch_queue.rst    |    9 ++++++
 drivers/usb/core/Kconfig         |    9 ++++++
 drivers/usb/core/devio.c         |   56 ++++++++++++++++++++++++++++++++++++++
 drivers/usb/core/hub.c           |    4 +++
 include/linux/usb.h              |   18 ++++++++++++
 include/uapi/linux/watch_queue.h |   30 ++++++++++++++++++++
 6 files changed, 125 insertions(+), 1 deletion(-)

Comments

Yoshihiro Shimoda Sept. 3, 2019, 8:53 a.m. UTC | #1
Hi,

> From: David Howells, Sent: Friday, August 30, 2019 10:58 PM
<snip>
> diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
> index 9063ede411ae..b8572e4d6a1b 100644
> --- a/drivers/usb/core/devio.c
> +++ b/drivers/usb/core/devio.c
> @@ -41,6 +41,7 @@
>  #include <linux/dma-mapping.h>
>  #include <asm/byteorder.h>
>  #include <linux/moduleparam.h>
> +#include <linux/watch_queue.h>
> 
>  #include "usb.h"
> 
> @@ -2660,13 +2661,68 @@ static void usbdev_remove(struct usb_device *udev)
>  	}
>  }
> 
> +#ifdef CONFIG_USB_NOTIFICATIONS
> +static noinline void post_usb_notification(const char *devname,
> +					   enum usb_notification_type subtype,
> +					   u32 error)
> +{
> +	unsigned int gran = WATCH_LENGTH_GRANULARITY;
> +	unsigned int name_len, n_len;
> +	u64 id = 0; /* Might want to put a dev# here. */
> +
> +	struct {
> +		struct usb_notification n;
> +		char more_name[USB_NOTIFICATION_MAX_NAME_LEN -
> +			       (sizeof(struct usb_notification) -
> +				offsetof(struct usb_notification, name))];
> +	} n;
> +
> +	name_len = strlen(devname);
> +	name_len = min_t(size_t, name_len, USB_NOTIFICATION_MAX_NAME_LEN);
> +	n_len = round_up(offsetof(struct usb_notification, name) + name_len,
> +			 gran) / gran;
> +
> +	memset(&n, 0, sizeof(n));
> +	memcpy(n.n.name, devname, n_len);
> +
> +	n.n.watch.type		= WATCH_TYPE_USB_NOTIFY;
> +	n.n.watch.subtype	= subtype;
> +	n.n.watch.info		= n_len;
> +	n.n.error		= error;
> +	n.n.name_len		= name_len;
> +
> +	post_device_notification(&n.n.watch, id);
> +}
> +
> +void post_usb_device_notification(const struct usb_device *udev,
> +				  enum usb_notification_type subtype, u32 error)
> +{
> +	post_usb_notification(dev_name(&udev->dev), subtype, error);
> +}
> +
> +void post_usb_bus_notification(const struct usb_bus *ubus,

This function's argument is struct usb_bus *, but ...

> +			       enum usb_notification_type subtype, u32 error)
> +{
> +	post_usb_notification(ubus->bus_name, subtype, error);
> +}
> +#endif
> +
>  static int usbdev_notify(struct notifier_block *self,
>  			       unsigned long action, void *dev)
>  {
>  	switch (action) {
>  	case USB_DEVICE_ADD:
> +		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_ADD, 0);
>  		break;
>  	case USB_DEVICE_REMOVE:
> +		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_REMOVE, 0);
> +		usbdev_remove(dev);
> +		break;
> +	case USB_BUS_ADD:
> +		post_usb_bus_notification(dev, NOTIFY_USB_BUS_ADD, 0);
> +		break;
> +	case USB_BUS_REMOVE:
> +		post_usb_bus_notification(dev, NOTIFY_USB_BUS_REMOVE, 0);
>  		usbdev_remove(dev);

this function calls usbdev_remove() with incorrect argument if the action
is USB_BUS_REMOVE. So, this seems to cause the following issue [1] on
my environment (R-Car H3 / r8a7795 on next-20190902) [2]. However, I have
no idea how to fix the issue, so I report this issue at the first step.

JFYI, even if I have reverted this patch on next-20190902, other issue
appears [3].

[1] The following panic happened.
[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x411fd073]
[    0.000000] Linux version 5.3.0-rc6-next-20190902 (shimoda@shimoda-RB02198) (gcc version 7.4.1 20181213 [linaro-7.4-2019.02 revision 56ec6f6b99cc167ff0c2f8e1a2eed33b1edc85d4] (Linaro GCC 7.4-2019.02)) #47 SMP PREEMPT Tue Sep 3 17:42:01 JST 2019
[    0.000000] Machine model: Renesas Salvator-X board based on r8a7795 ES2.0+
[    0.000000] printk: debug: ignoring loglevel setting.
[    0.000000] efi: Getting EFI parameters from FDT:
[    0.000000] efi: UEFI not found.
[    0.000000] cma: Reserved 32 MiB at 0x00000000be000000
[    0.000000] NUMA: No NUMA configuration found
[    0.000000] NUMA: Faking a node at [mem 0x0000000048000000-0x000000077fffffff]
[    0.000000] NUMA: NODE_DATA [mem 0x77efdb800-0x77efdcfff]
[    0.000000] Zone ranges:
[    0.000000]   DMA32    [mem 0x0000000048000000-0x00000000ffffffff]
[    0.000000]   Normal   [mem 0x0000000100000000-0x000000077fffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000048000000-0x00000000bfffffff]
[    0.000000]   node   0: [mem 0x0000000500000000-0x000000057fffffff]
[    0.000000]   node   0: [mem 0x0000000600000000-0x000000067fffffff]
[    0.000000]   node   0: [mem 0x0000000700000000-0x000000077fffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000048000000-0x000000077fffffff]
[    0.000000] On node 0 totalpages: 2064384
[    0.000000]   DMA32 zone: 7680 pages used for memmap
[    0.000000]   DMA32 zone: 0 pages reserved
[    0.000000]   DMA32 zone: 491520 pages, LIFO batch:63
[    0.000000]   Normal zone: 24576 pages used for memmap
[    0.000000]   Normal zone: 1572864 pages, LIFO batch:63
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.1 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: Trusted OS migration not required
[    0.000000] psci: SMC Calling Convention v1.1
[    0.000000] percpu: Embedded 22 pages/cpu s52952 r8192 d28968 u90112
[    0.000000] pcpu-alloc: s52952 r8192 d28968 u90112 alloc=22*4096
[    0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0] 4 [0] 5 [0] 6 [0] 7 
[    0.000000] Detected PIPT I-cache on CPU0
[    0.000000] CPU features: detected: EL2 vector hardening
[    0.000000] Speculative Store Bypass Disable mitigation not required
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 2032128
[    0.000000] Policy zone: Normal
[    0.000000] Kernel command line: console=ttySC0,115200 ignore_loglevel consoleblank=0 rw root=/dev/nfs ip=dhcp
[    0.000000] Dentry cache hash table entries: 1048576 (order: 11, 8388608 bytes, linear)
[    0.000000] Inode-cache hash table entries: 524288 (order: 10, 4194304 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] software IO TLB: mapped [mem 0xba000000-0xbe000000] (64MB)
[    0.000000] Memory: 7972368K/8257536K available (12092K kernel code, 1846K rwdata, 6320K rodata, 4992K init, 450K bss, 252400K reserved, 32768K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=8, Nodes=1
[    0.000000] rcu: Preemptible hierarchical RCU implementation.
[    0.000000] rcu: 	RCU restricting CPUs from NR_CPUS=256 to nr_cpu_ids=8.
[    0.000000] 	Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=8
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] GIC: Adjusting CPU interface base to 0x00000000f102f000
[    0.000000] GIC: Using split EOI/Deactivate mode
[    0.000000] random: get_random_bytes called from start_kernel+0x2f0/0x490 with crng_init=0
[    0.000000] arch_timer: cp15 timer(s) running at 8.33MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x1ec02923e, max_idle_ns: 440795202125 ns
[    0.000003] sched_clock: 56 bits at 8MHz, resolution 120ns, wraps every 2199023255496ns
[    0.000142] Console: colour dummy device 80x25
[    0.000211] Calibrating delay loop (skipped), value calculated using timer frequency.. 16.66 BogoMIPS (lpj=33333)
[    0.000218] pid_max: default: 32768 minimum: 301
[    0.000273] LSM: Security Framework initializing
[    0.000351] Mount-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
[    0.000397] Mountpoint-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
[    0.023974] ASID allocator initialised with 32768 entries
[    0.031963] rcu: Hierarchical SRCU implementation.
[    0.041031] Detected Renesas R-Car Gen3 r8a7795 ES3.0
[    0.042354] EFI services will not be available.
[    0.047989] smp: Bringing up secondary CPUs ...
[    0.080173] Detected PIPT I-cache on CPU1
[    0.080213] CPU1: Booted secondary processor 0x0000000001 [0x411fd073]
[    0.112190] Detected PIPT I-cache on CPU2
[    0.112210] CPU2: Booted secondary processor 0x0000000002 [0x411fd073]
[    0.144225] Detected PIPT I-cache on CPU3
[    0.144244] CPU3: Booted secondary processor 0x0000000003 [0x411fd073]
[    0.176267] CPU features: detected: ARM erratum 845719
[    0.176278] Detected VIPT I-cache on CPU4
[    0.176316] CPU4: Booted secondary processor 0x0000000100 [0x410fd034]
[    0.208292] Detected VIPT I-cache on CPU5
[    0.208316] CPU5: Booted secondary processor 0x0000000101 [0x410fd034]
[    0.240331] Detected VIPT I-cache on CPU6
[    0.240354] CPU6: Booted secondary processor 0x0000000102 [0x410fd034]
[    0.272365] Detected VIPT I-cache on CPU7
[    0.272389] CPU7: Booted secondary processor 0x0000000103 [0x410fd034]
[    0.272464] smp: Brought up 1 node, 8 CPUs
[    0.272484] SMP: Total of 8 processors activated.
[    0.272488] CPU features: detected: 32-bit EL0 Support
[    0.272493] CPU features: detected: CRC32 instructions
[    0.282612] CPU: All CPU(s) started at EL2
[    0.282644] alternatives: patching kernel code
[    0.283676] devtmpfs: initialized
[    0.289458] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    0.289471] futex hash table entries: 2048 (order: 5, 131072 bytes, linear)
[    0.290163] pinctrl core: initialized pinctrl subsystem
[    0.291360] DMI not present or invalid.
[    0.291607] NET: Registered protocol family 16
[    0.292388] DMA: preallocated 256 KiB pool for atomic allocations
[    0.292399] audit: initializing netlink subsys (disabled)
[    0.292539] audit: type=2000 audit(0.292:1): state=initialized audit_enabled=0 res=1
[    0.293573] cpuidle: using governor menu
[    0.293733] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
[    0.294678] Serial: AMBA PL011 UART driver
[    0.296912] sh-pfc e6060000.pin-controller: IRQ index 0 not found
[    0.297125] sh-pfc e6060000.pin-controller: r8a77951_pfc support registered
[    0.317432] HugeTLB registered 1.00 GiB page size, pre-allocated 0 pages
[    0.317439] HugeTLB registered 32.0 MiB page size, pre-allocated 0 pages
[    0.317443] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
[    0.317447] HugeTLB registered 64.0 KiB page size, pre-allocated 0 pages
[    0.319199] cryptd: max_cpu_qlen set to 1000
[    0.322091] ACPI: Interpreter disabled.
[    0.325627] iommu: Default domain type: Translated 
[    0.325823] vgaarb: loaded
[    0.326011] SCSI subsystem initialized
[    0.326113] libata version 3.00 loaded.
[    0.326243] usbcore: registered new interface driver usbfs
[    0.326264] usbcore: registered new interface driver hub
[    0.326307] usbcore: registered new device driver usb
[    0.327255] i2c-sh_mobile e60b0000.i2c: I2C adapter 7, bus speed 400000 Hz
[    0.327560] pps_core: LinuxPPS API ver. 1 registered
[    0.327564] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    0.327573] PTP clock support registered
[    0.327701] EDAC MC: Ver: 3.0.0
[    0.328991] FPGA manager framework
[    0.329031] Advanced Linux Sound Architecture Driver Initialized.
[    0.329497] clocksource: Switched to clocksource arch_sys_counter
[    0.329639] VFS: Disk quotas dquot_6.6.0
[    0.329682] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    0.329800] pnp: PnP ACPI: disabled
[    0.332764] thermal_sys: Registered thermal governor 'step_wise'
[    0.332767] thermal_sys: Registered thermal governor 'power_allocator'
[    0.333270] NET: Registered protocol family 2
[    0.333558] tcp_listen_portaddr_hash hash table entries: 4096 (order: 4, 65536 bytes, linear)
[    0.333624] TCP established hash table entries: 65536 (order: 7, 524288 bytes, linear)
[    0.333903] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes, linear)
[    0.334489] TCP: Hash tables configured (established 65536 bind 65536)
[    0.334606] UDP hash table entries: 4096 (order: 5, 131072 bytes, linear)
[    0.334714] UDP-Lite hash table entries: 4096 (order: 5, 131072 bytes, linear)
[    0.334929] NET: Registered protocol family 1
[    0.335290] RPC: Registered named UNIX socket transport module.
[    0.335295] RPC: Registered udp transport module.
[    0.335299] RPC: Registered tcp transport module.
[    0.335302] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.335311] PCI: CLS 0 bytes, default 64
[    0.336141] hw perfevents: enabled with armv8_cortex_a53 PMU driver, 7 counters available
[    0.336377] hw perfevents: enabled with armv8_cortex_a57 PMU driver, 7 counters available
[    0.336799] kvm [1]: IPA Size Limit: 40bits
[    0.337273] kvm [1]: vgic interrupt IRQ1
[    0.337415] kvm [1]: Hyp mode initialized successfully
[    0.341775] Initialise system trusted keyrings
[    0.341864] workingset: timestamp_bits=44 max_order=21 bucket_order=0
[    0.345076] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.345515] NFS: Registering the id_resolver key type
[    0.345532] Key type id_resolver registered
[    0.345535] Key type id_legacy registered
[    0.345544] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    0.345638] 9p: Installing v9fs 9p2000 file system support
[    0.354995] Key type asymmetric registered
[    0.355001] Asymmetric key parser 'x509' registered
[    0.355027] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 245)
[    0.355032] io scheduler mq-deadline registered
[    0.355036] io scheduler kyber registered
[    0.359639] phy_rcar_gen3_usb2 ee0a0200.usb-phy: IRQ index 0 not found
[    0.360346] phy_rcar_gen3_usb2 ee0c0200.usb-phy: IRQ index 0 not found
[    0.366010] gpio_rcar e6050000.gpio: driving 16 GPIOs
[    0.366187] gpio_rcar e6051000.gpio: driving 29 GPIOs
[    0.366348] gpio_rcar e6052000.gpio: driving 15 GPIOs
[    0.366504] gpio_rcar e6053000.gpio: driving 16 GPIOs
[    0.366663] gpio_rcar e6054000.gpio: driving 18 GPIOs
[    0.366816] gpio_rcar e6055000.gpio: driving 26 GPIOs
[    0.366973] gpio_rcar e6055400.gpio: driving 32 GPIOs
[    0.367126] gpio_rcar e6055800.gpio: driving 4 GPIOs
[    0.368571] rcar-pcie fe000000.pcie: host bridge /soc/pcie@fe000000 ranges:
[    0.368596] rcar-pcie fe000000.pcie:    IO 0xfe100000..0xfe1fffff -> 0x00000000
[    0.368613] rcar-pcie fe000000.pcie:   MEM 0xfe200000..0xfe3fffff -> 0xfe200000
[    0.368626] rcar-pcie fe000000.pcie:   MEM 0x30000000..0x37ffffff -> 0x30000000
[    0.368635] rcar-pcie fe000000.pcie:   MEM 0x38000000..0x3fffffff -> 0x38000000
[    0.433003] rcar-pcie fe000000.pcie: PCIe link down
[    0.433148] rcar-pcie ee800000.pcie: host bridge /soc/pcie@ee800000 ranges:
[    0.433165] rcar-pcie ee800000.pcie:    IO 0xee900000..0xee9fffff -> 0x00000000
[    0.433179] rcar-pcie ee800000.pcie:   MEM 0xeea00000..0xeebfffff -> 0xeea00000
[    0.433191] rcar-pcie ee800000.pcie:   MEM 0xc0000000..0xc7ffffff -> 0xc0000000
[    0.433200] rcar-pcie ee800000.pcie:   MEM 0xc8000000..0xcfffffff -> 0xc8000000
[    0.496985] rcar-pcie ee800000.pcie: PCIe link down
[    0.498893] EINJ: ACPI disabled.
[    0.510430] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[    0.512246] SuperH (H)SCI(F) driver initialized
[    0.512568] sh-sci e6550000.serial: IRQ index 1 not found
[    0.512577] sh-sci e6550000.serial: IRQ index 2 not found
[    0.512584] sh-sci e6550000.serial: IRQ index 3 not found
[    0.512591] sh-sci e6550000.serial: IRQ index 4 not found
[    0.512597] sh-sci e6550000.serial: IRQ index 5 not found
[    0.512647] e6550000.serial: ttySC1 at MMIO 0xe6550000 (irq = 34, base_baud = 0) is a hscif
[    0.513065] sh-sci e6e88000.serial: IRQ index 1 not found
[    0.513073] sh-sci e6e88000.serial: IRQ index 2 not found
[    0.513079] sh-sci e6e88000.serial: IRQ index 3 not found
[    0.513086] sh-sci e6e88000.serial: IRQ index 4 not found
[    0.513092] sh-sci e6e88000.serial: IRQ index 5 not found
[    0.513119] e6e88000.serial: ttySC0 at MMIO 0xe6e88000 (irq = 119, base_baud = 0) is a scif
[    1.655695] printk: console [ttySC0] enabled
[    1.660706] msm_serial: driver initialized
[    1.671544] loop: module loaded
[    1.679482] libphy: Fixed MDIO Bus: probed
[    1.683719] tun: Universal TUN/TAP device driver, 1.6
[    1.689559] thunder_xcv, ver 1.0
[    1.692805] thunder_bgx, ver 1.0
[    1.696052] nicpf, ver 1.0
[    1.699373] hclge is initializing
[    1.702688] hns3: Hisilicon Ethernet Network Driver for Hip08 Family - version
[    1.709907] hns3: Copyright (c) 2017 Huawei Corporation.
[    1.715242] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
[    1.721073] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
[    1.727012] igb: Intel(R) Gigabit Ethernet Network Driver - version 5.6.0-k
[    1.733971] igb: Copyright (c) 2007-2014 Intel Corporation.
[    1.739557] igbvf: Intel(R) Gigabit Virtual Function Network Driver - version 2.4.0-k
[    1.747383] igbvf: Copyright (c) 2009 - 2012 Intel Corporation.
[    1.753636] sky2: driver version 1.30
[    1.758264] VFIO - User Level meta-driver version: 0.3
[    1.764783] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    1.771320] ehci-pci: EHCI PCI platform driver
[    1.775780] ehci-platform: EHCI generic platform driver
[    1.781335] ehci-platform ee0a0100.usb: EHCI Host Controller
[    1.787016] ehci-platform ee0a0100.usb: new USB bus registered, assigned bus number 1
[    1.794935] ehci-platform ee0a0100.usb: irq 165, io mem 0xee0a0100
[    1.813507] ehci-platform ee0a0100.usb: USB 2.0 started, EHCI 1.10
[    1.820044] hub 1-0:1.0: USB hub found
[    1.823828] hub 1-0:1.0: 1 port detected
[    1.828017] ehci-platform ee0c0100.usb: EHCI Host Controller
[    1.833684] ehci-platform ee0c0100.usb: new USB bus registered, assigned bus number 2
[    1.841560] ehci-platform ee0c0100.usb: irq 166, io mem 0xee0c0100
[    1.861506] ehci-platform ee0c0100.usb: USB 2.0 started, EHCI 1.10
[    1.867940] hub 2-0:1.0: USB hub found
[    1.871704] hub 2-0:1.0: 1 port detected
[    1.875860] ehci-orion: EHCI orion driver
[    1.880049] ehci-exynos: EHCI EXYNOS driver
[    1.884320] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[    1.890509] ohci-pci: OHCI PCI platform driver
[    1.894978] ohci-platform: OHCI generic platform driver
[    1.900444] ohci-platform ee0a0000.usb: Generic Platform OHCI controller
[    1.907159] ohci-platform ee0a0000.usb: new USB bus registered, assigned bus number 3
[    1.915025] ohci-platform ee0a0000.usb: irq 165, io mem 0xee0a0000
[    2.008477] hub 3-0:1.0: USB hub found
[    2.012244] hub 3-0:1.0: 1 port detected
[    2.016388] ohci-platform ee0c0000.usb: Generic Platform OHCI controller
[    2.023097] ohci-platform ee0c0000.usb: new USB bus registered, assigned bus number 4
[    2.030977] ohci-platform ee0c0000.usb: irq 166, io mem 0xee0c0000
[    2.124457] hub 4-0:1.0: USB hub found
[    2.128220] hub 4-0:1.0: 1 port detected
[    2.132361] ohci-exynos: OHCI EXYNOS driver
[    2.137069] xhci-hcd ee000000.usb: xHCI Host Controller
[    2.142305] xhci-hcd ee000000.usb: new USB bus registered, assigned bus number 5
[    2.149748] xhci-hcd ee000000.usb: Direct firmware load for r8a779x_usb3_v3.dlmem failed with error -2
[    2.159063] xhci-hcd ee000000.usb: can't setup: -2
[    2.163861] xhci-hcd ee000000.usb: USB bus 5 deregistered
[    2.169266] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000020
[    2.178042] Mem abort info:
[    2.180828]   ESR = 0x96000004
[    2.183876]   EC = 0x25: DABT (current EL), IL = 32 bits
[    2.189179]   SET = 0, FnV = 0
[    2.192226]   EA = 0, S1PTW = 0
[    2.195358] Data abort info:
[    2.198231]   ISV = 0, ISS = 0x00000004
[    2.202058]   CM = 0, WnR = 0
[    2.205019] [0000000000000020] user address but active_mm is swapper
[    2.211366] Internal error: Oops: 96000004 [#1] PREEMPT SMP
[    2.216930] Modules linked in:
[    2.219981] CPU: 2 PID: 1 Comm: swapper/0 Not tainted 5.3.0-rc6-next-20190902 #47
[    2.227456] Hardware name: Renesas Salvator-X board based on r8a7795 ES2.0+ (DT)
[    2.234844] pstate: a0000085 (NzCv daIf -PAN -UAO)
[    2.239638] pc : _raw_write_lock+0x68/0x288
[    2.243819] lr : destroy_async+0x20/0xb0
[    2.247733] sp : ffff80001006b9b0
[    2.251040] x29: ffff80001006b9b0 x28: ffff800011186fd8 
[    2.256345] x27: ffff800011186fc0 x26: 00000000ffffffed 
[    2.261650] x25: ffff8000118ff570 x24: ffff8000118ff000 
[    2.266955] x23: 0000000000000004 x22: ffff800011900000 
[    2.272259] x21: 0000000000000020 x20: 0000000000000028 
[    2.277564] x19: 0000000000000000 x18: 0000000000000005 
[    2.282868] x17: 0000000000000020 x16: ffff800010d164b0 
[    2.288172] x15: ffff8000118ff6e8 x14: ffff000735867958 
[    2.293476] x13: 0000000000000000 x12: ffff8000118ff6e8 
[    2.298779] x11: ffff000735867908 x10: 0000000000000040 
[    2.304083] x9 : ffff8000118ff6f0 x8 : ffff8000118ff6e8 
[    2.309388] x7 : ffff000735867958 x6 : 0000000000000000 
[    2.314691] x5 : 0000000000000001 x4 : 0000000000000000 
[    2.319995] x3 : 0000000000000020 x2 : 0000000000000001 
[    2.325299] x1 : 0000000000000000 x0 : 0000000000000001 
[    2.330604] Call trace:
[    2.333045]  _raw_write_lock+0x68/0x288
[    2.336874]  destroy_async+0x20/0xb0
[    2.340443]  usbdev_remove+0x3c/0xc0
[    2.344011]  usbdev_notify+0x20/0x38
[    2.347583]  notifier_call_chain+0x54/0x98
[    2.351672]  blocking_notifier_call_chain+0x48/0x70
[    2.356543]  usb_notify_remove_bus+0x1c/0x28
[    2.360808]  usb_deregister_bus+0x58/0x68
[    2.364811]  usb_add_hcd+0x234/0x730
[    2.368381]  xhci_plat_probe+0x4ec/0x650
[    2.372302]  platform_drv_probe+0x50/0xa0
[    2.376305]  really_probe+0xdc/0x350
[    2.379874]  driver_probe_device+0x58/0x100
[    2.384050]  device_driver_attach+0x6c/0x90
[    2.388226]  __driver_attach+0x84/0xc8
[    2.391968]  bus_for_each_dev+0x74/0xc8
[    2.395796]  driver_attach+0x20/0x28
[    2.399365]  bus_add_driver+0x148/0x1f0
[    2.403193]  driver_register+0x60/0x110
[    2.407022]  __platform_driver_register+0x40/0x48
[    2.411723]  xhci_plat_init+0x2c/0x34
[    2.415380]  do_one_initcall+0x5c/0x1b0
[    2.419213]  kernel_init_freeable+0x1a4/0x24c
[    2.423564]  kernel_init+0x10/0x108
[    2.427045]  ret_from_fork+0x10/0x18
[    2.430617] Code: 97d3f2b6 a8c17bfd d65f03c0 f9800071 (885ffc60) 
[    2.436717] ---[ end trace 33e4fb349eb48047 ]---
[    2.441345] note: swapper/0[1] exited with preempt_count 1
[    2.446846] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[    2.454497] SMP: stopping secondary CPUs
[    2.458416] Kernel Offset: disabled
[    2.461898] CPU features: 0x0002,21006004
[    2.465899] Memory Limit: none
[    2.468950] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---

[2] I'm using defconfig on arch/arm64 and disable CONFIG_FW_LOADER_USER_HELPER.

[3] The following panic happened when I reverted the commit ef9cc255c9539288f119156412d23a4b785f3599
    on next-20190902.
[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x411fd073]
[    0.000000] Linux version 5.3.0-rc6-next-20190902-00001-g9709468 (shimoda@shimoda-RB02198) (gcc version 7.4.1 20181213 [linaro-7.4-2019.02 revision 56ec6f6b99cc167ff0c2f8e1a2eed33b1edc85d4] (Linaro GCC 7.4-2019.02)) #48 SMP PREEMPT Tue Sep 3 17:46:54 JST 2019
[    0.000000] Machine model: Renesas Salvator-X board based on r8a7795 ES2.0+
[    0.000000] printk: debug: ignoring loglevel setting.
[    0.000000] efi: Getting EFI parameters from FDT:
[    0.000000] efi: UEFI not found.
[    0.000000] cma: Reserved 32 MiB at 0x00000000be000000
[    0.000000] NUMA: No NUMA configuration found
[    0.000000] NUMA: Faking a node at [mem 0x0000000048000000-0x000000077fffffff]
[    0.000000] NUMA: NODE_DATA [mem 0x77efdb800-0x77efdcfff]
[    0.000000] Zone ranges:
[    0.000000]   DMA32    [mem 0x0000000048000000-0x00000000ffffffff]
[    0.000000]   Normal   [mem 0x0000000100000000-0x000000077fffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000048000000-0x00000000bfffffff]
[    0.000000]   node   0: [mem 0x0000000500000000-0x000000057fffffff]
[    0.000000]   node   0: [mem 0x0000000600000000-0x000000067fffffff]
[    0.000000]   node   0: [mem 0x0000000700000000-0x000000077fffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000048000000-0x000000077fffffff]
[    0.000000] On node 0 totalpages: 2064384
[    0.000000]   DMA32 zone: 7680 pages used for memmap
[    0.000000]   DMA32 zone: 0 pages reserved
[    0.000000]   DMA32 zone: 491520 pages, LIFO batch:63
[    0.000000]   Normal zone: 24576 pages used for memmap
[    0.000000]   Normal zone: 1572864 pages, LIFO batch:63
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.1 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: Trusted OS migration not required
[    0.000000] psci: SMC Calling Convention v1.1
[    0.000000] percpu: Embedded 22 pages/cpu s52952 r8192 d28968 u90112
[    0.000000] pcpu-alloc: s52952 r8192 d28968 u90112 alloc=22*4096
[    0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0] 4 [0] 5 [0] 6 [0] 7 
[    0.000000] Detected PIPT I-cache on CPU0
[    0.000000] CPU features: detected: EL2 vector hardening
[    0.000000] Speculative Store Bypass Disable mitigation not required
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 2032128
[    0.000000] Policy zone: Normal
[    0.000000] Kernel command line: console=ttySC0,115200 ignore_loglevel consoleblank=0 rw root=/dev/nfs ip=dhcp
[    0.000000] Dentry cache hash table entries: 1048576 (order: 11, 8388608 bytes, linear)
[    0.000000] Inode-cache hash table entries: 524288 (order: 10, 4194304 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] software IO TLB: mapped [mem 0xba000000-0xbe000000] (64MB)
[    0.000000] Memory: 7972368K/8257536K available (12092K kernel code, 1846K rwdata, 6320K rodata, 4992K init, 450K bss, 252400K reserved, 32768K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=8, Nodes=1
[    0.000000] rcu: Preemptible hierarchical RCU implementation.
[    0.000000] rcu: 	RCU restricting CPUs from NR_CPUS=256 to nr_cpu_ids=8.
[    0.000000] 	Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=8
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] GIC: Adjusting CPU interface base to 0x00000000f102f000
[    0.000000] GIC: Using split EOI/Deactivate mode
[    0.000000] random: get_random_bytes called from start_kernel+0x2f0/0x490 with crng_init=0
[    0.000000] arch_timer: cp15 timer(s) running at 8.33MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x1ec02923e, max_idle_ns: 440795202125 ns
[    0.000002] sched_clock: 56 bits at 8MHz, resolution 120ns, wraps every 2199023255496ns
[    0.000141] Console: colour dummy device 80x25
[    0.000207] Calibrating delay loop (skipped), value calculated using timer frequency.. 16.66 BogoMIPS (lpj=33333)
[    0.000215] pid_max: default: 32768 minimum: 301
[    0.000270] LSM: Security Framework initializing
[    0.000352] Mount-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
[    0.000398] Mountpoint-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
[    0.023978] ASID allocator initialised with 32768 entries
[    0.031968] rcu: Hierarchical SRCU implementation.
[    0.041040] Detected Renesas R-Car Gen3 r8a7795 ES3.0
[    0.042364] EFI services will not be available.
[    0.047996] smp: Bringing up secondary CPUs ...
[    0.080183] Detected PIPT I-cache on CPU1
[    0.080222] CPU1: Booted secondary processor 0x0000000001 [0x411fd073]
[    0.112195] Detected PIPT I-cache on CPU2
[    0.112216] CPU2: Booted secondary processor 0x0000000002 [0x411fd073]
[    0.144232] Detected PIPT I-cache on CPU3
[    0.144253] CPU3: Booted secondary processor 0x0000000003 [0x411fd073]
[    0.176276] CPU features: detected: ARM erratum 845719
[    0.176286] Detected VIPT I-cache on CPU4
[    0.176324] CPU4: Booted secondary processor 0x0000000100 [0x410fd034]
[    0.208297] Detected VIPT I-cache on CPU5
[    0.208321] CPU5: Booted secondary processor 0x0000000101 [0x410fd034]
[    0.240338] Detected VIPT I-cache on CPU6
[    0.240361] CPU6: Booted secondary processor 0x0000000102 [0x410fd034]
[    0.272375] Detected VIPT I-cache on CPU7
[    0.272398] CPU7: Booted secondary processor 0x0000000103 [0x410fd034]
[    0.272473] smp: Brought up 1 node, 8 CPUs
[    0.272492] SMP: Total of 8 processors activated.
[    0.272497] CPU features: detected: 32-bit EL0 Support
[    0.272502] CPU features: detected: CRC32 instructions
[    0.282749] CPU: All CPU(s) started at EL2
[    0.282777] alternatives: patching kernel code
[    0.283815] devtmpfs: initialized
[    0.289644] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    0.289659] futex hash table entries: 2048 (order: 5, 131072 bytes, linear)
[    0.290353] pinctrl core: initialized pinctrl subsystem
[    0.291538] DMI not present or invalid.
[    0.291777] NET: Registered protocol family 16
[    0.292561] DMA: preallocated 256 KiB pool for atomic allocations
[    0.292571] audit: initializing netlink subsys (disabled)
[    0.292709] audit: type=2000 audit(0.292:1): state=initialized audit_enabled=0 res=1
[    0.293743] cpuidle: using governor menu
[    0.293898] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
[    0.294862] Serial: AMBA PL011 UART driver
[    0.297061] sh-pfc e6060000.pin-controller: IRQ index 0 not found
[    0.297280] sh-pfc e6060000.pin-controller: r8a77951_pfc support registered
[    0.317490] HugeTLB registered 1.00 GiB page size, pre-allocated 0 pages
[    0.317498] HugeTLB registered 32.0 MiB page size, pre-allocated 0 pages
[    0.317503] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
[    0.317506] HugeTLB registered 64.0 KiB page size, pre-allocated 0 pages
[    0.319278] cryptd: max_cpu_qlen set to 1000
[    0.322162] ACPI: Interpreter disabled.
[    0.325707] iommu: Default domain type: Translated 
[    0.325909] vgaarb: loaded
[    0.326100] SCSI subsystem initialized
[    0.326199] libata version 3.00 loaded.
[    0.326333] usbcore: registered new interface driver usbfs
[    0.326353] usbcore: registered new interface driver hub
[    0.326395] usbcore: registered new device driver usb
[    0.327336] i2c-sh_mobile e60b0000.i2c: I2C adapter 7, bus speed 400000 Hz
[    0.327631] pps_core: LinuxPPS API ver. 1 registered
[    0.327636] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    0.327644] PTP clock support registered
[    0.327770] EDAC MC: Ver: 3.0.0
[    0.329047] FPGA manager framework
[    0.329089] Advanced Linux Sound Architecture Driver Initialized.
[    0.329548] clocksource: Switched to clocksource arch_sys_counter
[    0.329696] VFS: Disk quotas dquot_6.6.0
[    0.329738] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    0.329855] pnp: PnP ACPI: disabled
[    0.332843] thermal_sys: Registered thermal governor 'step_wise'
[    0.332845] thermal_sys: Registered thermal governor 'power_allocator'
[    0.333337] NET: Registered protocol family 2
[    0.333618] tcp_listen_portaddr_hash hash table entries: 4096 (order: 4, 65536 bytes, linear)
[    0.333682] TCP established hash table entries: 65536 (order: 7, 524288 bytes, linear)
[    0.333961] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes, linear)
[    0.334551] TCP: Hash tables configured (established 65536 bind 65536)
[    0.334661] UDP hash table entries: 4096 (order: 5, 131072 bytes, linear)
[    0.334769] UDP-Lite hash table entries: 4096 (order: 5, 131072 bytes, linear)
[    0.334979] NET: Registered protocol family 1
[    0.335329] RPC: Registered named UNIX socket transport module.
[    0.335333] RPC: Registered udp transport module.
[    0.335337] RPC: Registered tcp transport module.
[    0.335340] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.335349] PCI: CLS 0 bytes, default 64
[    0.336179] hw perfevents: enabled with armv8_cortex_a53 PMU driver, 7 counters available
[    0.336413] hw perfevents: enabled with armv8_cortex_a57 PMU driver, 7 counters available
[    0.336837] kvm [1]: IPA Size Limit: 40bits
[    0.337313] kvm [1]: vgic interrupt IRQ1
[    0.337458] kvm [1]: Hyp mode initialized successfully
[    0.341834] Initialise system trusted keyrings
[    0.341924] workingset: timestamp_bits=44 max_order=21 bucket_order=0
[    0.345148] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.345585] NFS: Registering the id_resolver key type
[    0.345602] Key type id_resolver registered
[    0.345606] Key type id_legacy registered
[    0.345615] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    0.345714] 9p: Installing v9fs 9p2000 file system support
[    0.354814] Key type asymmetric registered
[    0.354819] Asymmetric key parser 'x509' registered
[    0.354844] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 245)
[    0.354849] io scheduler mq-deadline registered
[    0.354853] io scheduler kyber registered
[    0.359476] phy_rcar_gen3_usb2 ee0a0200.usb-phy: IRQ index 0 not found
[    0.360174] phy_rcar_gen3_usb2 ee0c0200.usb-phy: IRQ index 0 not found
[    0.365881] gpio_rcar e6050000.gpio: driving 16 GPIOs
[    0.366057] gpio_rcar e6051000.gpio: driving 29 GPIOs
[    0.366222] gpio_rcar e6052000.gpio: driving 15 GPIOs
[    0.366376] gpio_rcar e6053000.gpio: driving 16 GPIOs
[    0.366536] gpio_rcar e6054000.gpio: driving 18 GPIOs
[    0.366688] gpio_rcar e6055000.gpio: driving 26 GPIOs
[    0.366860] gpio_rcar e6055400.gpio: driving 32 GPIOs
[    0.367015] gpio_rcar e6055800.gpio: driving 4 GPIOs
[    0.368473] rcar-pcie fe000000.pcie: host bridge /soc/pcie@fe000000 ranges:
[    0.368498] rcar-pcie fe000000.pcie:    IO 0xfe100000..0xfe1fffff -> 0x00000000
[    0.368514] rcar-pcie fe000000.pcie:   MEM 0xfe200000..0xfe3fffff -> 0xfe200000
[    0.368527] rcar-pcie fe000000.pcie:   MEM 0x30000000..0x37ffffff -> 0x30000000
[    0.368536] rcar-pcie fe000000.pcie:   MEM 0x38000000..0x3fffffff -> 0x38000000
[    0.437037] rcar-pcie fe000000.pcie: PCIe link down
[    0.437187] rcar-pcie ee800000.pcie: host bridge /soc/pcie@ee800000 ranges:
[    0.437205] rcar-pcie ee800000.pcie:    IO 0xee900000..0xee9fffff -> 0x00000000
[    0.437218] rcar-pcie ee800000.pcie:   MEM 0xeea00000..0xeebfffff -> 0xeea00000
[    0.437230] rcar-pcie ee800000.pcie:   MEM 0xc0000000..0xc7ffffff -> 0xc0000000
[    0.437239] rcar-pcie ee800000.pcie:   MEM 0xc8000000..0xcfffffff -> 0xc8000000
[    0.501036] rcar-pcie ee800000.pcie: PCIe link down
[    0.502959] EINJ: ACPI disabled.
[    0.514458] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[    0.516285] SuperH (H)SCI(F) driver initialized
[    0.516608] sh-sci e6550000.serial: IRQ index 1 not found
[    0.516616] sh-sci e6550000.serial: IRQ index 2 not found
[    0.516624] sh-sci e6550000.serial: IRQ index 3 not found
[    0.516630] sh-sci e6550000.serial: IRQ index 4 not found
[    0.516637] sh-sci e6550000.serial: IRQ index 5 not found
[    0.516685] e6550000.serial: ttySC1 at MMIO 0xe6550000 (irq = 34, base_baud = 0) is a hscif
[    0.517112] sh-sci e6e88000.serial: IRQ index 1 not found
[    0.517121] sh-sci e6e88000.serial: IRQ index 2 not found
[    0.517128] sh-sci e6e88000.serial: IRQ index 3 not found
[    0.517134] sh-sci e6e88000.serial: IRQ index 4 not found
[    0.517140] sh-sci e6e88000.serial: IRQ index 5 not found
[    0.517169] e6e88000.serial: ttySC0 at MMIO 0xe6e88000 (irq = 119, base_baud = 0) is a scif
[    1.661047] printk: console [ttySC0] enabled
[    1.666084] msm_serial: driver initialized
[    1.676874] loop: module loaded
[    1.684780] libphy: Fixed MDIO Bus: probed
[    1.689023] tun: Universal TUN/TAP device driver, 1.6
[    1.694842] thunder_xcv, ver 1.0
[    1.698099] thunder_bgx, ver 1.0
[    1.701336] nicpf, ver 1.0
[    1.704657] hclge is initializing
[    1.707971] hns3: Hisilicon Ethernet Network Driver for Hip08 Family - version
[    1.715189] hns3: Copyright (c) 2017 Huawei Corporation.
[    1.720525] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
[    1.726355] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
[    1.732292] igb: Intel(R) Gigabit Ethernet Network Driver - version 5.6.0-k
[    1.739250] igb: Copyright (c) 2007-2014 Intel Corporation.
[    1.744836] igbvf: Intel(R) Gigabit Virtual Function Network Driver - version 2.4.0-k
[    1.752662] igbvf: Copyright (c) 2009 - 2012 Intel Corporation.
[    1.758910] sky2: driver version 1.30
[    1.763530] VFIO - User Level meta-driver version: 0.3
[    1.770067] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    1.776596] ehci-pci: EHCI PCI platform driver
[    1.781050] ehci-platform: EHCI generic platform driver
[    1.786609] ehci-platform ee0a0100.usb: EHCI Host Controller
[    1.792287] ehci-platform ee0a0100.usb: new USB bus registered, assigned bus number 1
[    1.800200] ehci-platform ee0a0100.usb: irq 165, io mem 0xee0a0100
[    1.821568] ehci-platform ee0a0100.usb: USB 2.0 started, EHCI 1.10
[    1.828087] hub 1-0:1.0: USB hub found
[    1.831856] hub 1-0:1.0: 1 port detected
[    1.836044] ehci-platform ee0c0100.usb: EHCI Host Controller
[    1.841711] ehci-platform ee0c0100.usb: new USB bus registered, assigned bus number 2
[    1.849592] ehci-platform ee0c0100.usb: irq 166, io mem 0xee0c0100
[    1.869555] ehci-platform ee0c0100.usb: USB 2.0 started, EHCI 1.10
[    1.875993] hub 2-0:1.0: USB hub found
[    1.879757] hub 2-0:1.0: 1 port detected
[    1.883910] ehci-orion: EHCI orion driver
[    1.888098] ehci-exynos: EHCI EXYNOS driver
[    1.892371] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[    1.898562] ohci-pci: OHCI PCI platform driver
[    1.903033] ohci-platform: OHCI generic platform driver
[    1.908496] ohci-platform ee0a0000.usb: Generic Platform OHCI controller
[    1.915209] ohci-platform ee0a0000.usb: new USB bus registered, assigned bus number 3
[    1.923072] ohci-platform ee0a0000.usb: irq 165, io mem 0xee0a0000
[    2.016534] hub 3-0:1.0: USB hub found
[    2.020298] hub 3-0:1.0: 1 port detected
[    2.024438] ohci-platform ee0c0000.usb: Generic Platform OHCI controller
[    2.031147] ohci-platform ee0c0000.usb: new USB bus registered, assigned bus number 4
[    2.039026] ohci-platform ee0c0000.usb: irq 166, io mem 0xee0c0000
[    2.132519] hub 4-0:1.0: USB hub found
[    2.136281] hub 4-0:1.0: 1 port detected
[    2.140417] ohci-exynos: OHCI EXYNOS driver
[    2.145110] xhci-hcd ee000000.usb: xHCI Host Controller
[    2.150344] xhci-hcd ee000000.usb: new USB bus registered, assigned bus number 5
[    2.157782] xhci-hcd ee000000.usb: Direct firmware load for r8a779x_usb3_v3.dlmem failed with error -2
[    2.167098] xhci-hcd ee000000.usb: can't setup: -2
[    2.171895] xhci-hcd ee000000.usb: USB bus 5 deregistered
[    2.177324] xhci-hcd: probe of ee000000.usb failed with error -2
[    2.183655] usbcore: registered new interface driver usb-storage
[    2.192417] i2c /dev entries driver
[    2.203824] cs2000-cp 2-004f: revision - C1
[    2.208051] i2c-rcar e6510000.i2c: probed
[    2.212397] pca953x 4-0020: 4-0020 supply vcc not found, using dummy regulator
[    2.220399] i2c-rcar e66d8000.i2c: probed
[    2.231022] rcar_gen3_thermal e6198000.thermal: TSC0: Loaded 1 trip points
[    2.242049] rcar_gen3_thermal e6198000.thermal: TSC1: Loaded 1 trip points
[    2.253051] rcar_gen3_thermal e6198000.thermal: TSC2: Loaded 2 trip points
[    2.262525] cpufreq: cpufreq_online: CPU0: Running at unlisted freq: 1499999 KHz
[    2.269954] cpufreq: cpufreq_online: CPU0: Unlisted initial frequency changed to: 1500000 KHz
[    2.278842] cpufreq: cpufreq_online: CPU4: Running at unlisted freq: 1199999 KHz
[    2.286537] cpufreq: cpufreq_online: CPU4: Unlisted initial frequency changed to: 1200000 KHz
[    2.295864] sdhci: Secure Digital Host Controller Interface driver
[    2.302048] sdhci: Copyright(c) Pierre Ossman
[    2.307021] renesas_sdhi_internal_dmac ee100000.sd: Got CD GPIO
[    2.312959] renesas_sdhi_internal_dmac ee100000.sd: Got WP GPIO
[    2.389858] renesas_sdhi_internal_dmac ee140000.sd: IRQ index 1 not found
[    2.396653] renesas_sdhi_internal_dmac ee140000.sd: mmc0 base at 0xee140000 max clock rate 200 MHz
[    2.405964] renesas_sdhi_internal_dmac ee160000.sd: Got CD GPIO
[    2.411904] renesas_sdhi_internal_dmac ee160000.sd: Got WP GPIO
[    2.418211] Synopsys Designware Multimedia Card Interface Driver
[    2.425178] sdhci-pltfm: SDHCI platform and OF driver helper
[    2.432494] ledtrig-cpu: registered to indicate activity on CPUs
[    2.439571] usbcore: registered new interface driver usbhid
[    2.445144] usbhid: USB HID core driver
[    2.452453] NET: Registered protocol family 17
[    2.457011] 9pnet: Installing 9P2000 support
[    2.461319] Key type dns_resolver registered
[    2.465799] registered taskstats version 1
[    2.469898] Loading compiled-in X.509 certificates
[    2.482897] renesas_irqc e61c0000.interrupt-controller: driving 6 irqs
[    2.495600] bd9571mwv 7-0030: Device: BD9571MWV rev. 1
[    2.515031] mmc0: new HS400 MMC card at address 0001
[    2.520418] mmcblk0: mmc0:0001 BGSD3R 29.1 GiB 
[    2.525131] mmcblk0boot0: mmc0:0001 BGSD3R partition 1 16.0 MiB
[    2.529575] ehci-platform ee080100.usb: EHCI Host Controller
[    2.531207] mmcblk0boot1: mmc0:0001 BGSD3R partition 2 16.0 MiB
[    2.536718] ehci-platform ee080100.usb: new USB bus registered, assigned bus number 5
[    2.542734] mmcblk0rpmb: mmc0:0001 BGSD3R partition 3 4.00 MiB, chardev (237:0)
[    2.550499] ehci-platform ee080100.usb: irq 164, io mem 0xee080100
[    2.558357]  mmcblk0: p1
[    2.577560] ehci-platform ee080100.usb: USB 2.0 started, EHCI 1.10
[    2.584084] hub 5-0:1.0: USB hub found
[    2.587851] hub 5-0:1.0: 1 port detected
[    2.592849] ohci-platform ee080000.usb: Generic Platform OHCI controller
[    2.599569] ohci-platform ee080000.usb: new USB bus registered, assigned bus number 6
[    2.607446] ohci-platform ee080000.usb: irq 164, io mem 0xee080000
[    2.704528] hub 6-0:1.0: USB hub found
[    2.708295] hub 6-0:1.0: 1 port detected
[    2.713342] renesas_sdhi_internal_dmac ee100000.sd: Got CD GPIO
[    2.719283] renesas_sdhi_internal_dmac ee100000.sd: Got WP GPIO
[    2.795713] renesas_sdhi_internal_dmac ee100000.sd: IRQ index 1 not found
[    2.802509] renesas_sdhi_internal_dmac ee100000.sd: mmc1 base at 0xee100000 max clock rate 200 MHz
[    2.812389] renesas_sdhi_internal_dmac ee160000.sd: Got CD GPIO
[    2.818337] renesas_sdhi_internal_dmac ee160000.sd: Got WP GPIO
[    2.894683] renesas_sdhi_internal_dmac ee160000.sd: IRQ index 1 not found
[    2.901477] renesas_sdhi_internal_dmac ee160000.sd: mmc2 base at 0xee160000 max clock rate 200 MHz
[    2.914096] rcar-dmac e6700000.dma-controller: ignoring dependency for device, assuming no driver
[    2.925001] rcar-dmac e7300000.dma-controller: ignoring dependency for device, assuming no driver
[    2.935788] rcar-dmac e7310000.dma-controller: ignoring dependency for device, assuming no driver
[    2.946621] rcar-dmac ec700000.dma-controller: ignoring dependency for device, assuming no driver
[    2.957413] rcar-dmac ec720000.dma-controller: ignoring dependency for device, assuming no driver
[    2.968426] sata_rcar ee300000.sata: ignoring dependency for device, assuming no driver
[    2.976875] scsi host0: sata_rcar
[    2.980348] ata1: SATA max UDMA/133 irq 170
[    2.985299] ravb e6800000.ethernet: ignoring dependency for device, assuming no driver
[    2.993512] libphy: ravb_mii: probed
[    2.998278] ravb e6800000.ethernet eth0: Base address at 0xe6800000, 2e:09:0a:00:83:ea, IRQ 116.
[    3.008624] input: keys as /devices/platform/keys/input/input0
[    3.014713] hctosys: unable to open rtc device (rtc0)
[    3.096510] Micrel KSZ9031 Gigabit PHY e6800000.ethernet-ffffffff:00: attached PHY driver [Micrel KSZ9031 Gigabit PHY] (mii_bus:phy_addr=e6800000.ethernet-ffffffff:00, irq=175)
[    3.401564] ata1: link resume succeeded after 1 retries
[    3.513072] ata1: SATA link down (SStatus 0 SControl 300)
[    4.742059] ravb e6800000.ethernet eth0: Link is Up - 100Mbps/Full - flow control off
[    4.773553] Sending DHCP requests ..,
[    7.413975] random: fast init done
[    7.421550]  OK
[    7.423320] IP-Config: Got DHCP answer from 192.168.44.74, my address is 192.168.44.104
[    7.431336] IP-Config: Complete:
[    7.434568]      device=eth0, hwaddr=2e:09:0a:00:83:ea, ipaddr=192.168.44.104, mask=255.255.255.0, gw=192.168.44.74
[    7.445000]      host=192.168.44.104, domain=shimoda-i7.org, nis-domain=(none)
[    7.452218]      bootserver=192.168.44.74, rootserver=192.168.44.74, rootpath=/var/lib/tftpboot/aarch64/rootfs/buildroot
[    7.452220]      nameserver0=192.168.44.74
[    7.467553] SDHI0 Vcc: disabling
[    7.470782] SDHI3 Vcc: disabling
[    7.474008] SDHI0 VccQ: disabling
[    7.477316] SDHI3 VccQ: disabling
[    7.480632] ALSA device list:
[    7.483598]   No soundcards found.
[    7.492496] VFS: Mounted root (nfs filesystem) on device 0:19.
[    7.498742] devtmpfs: mounted
[    7.504263] Freeing unused kernel memory: 4992K
[    7.513642] Run /sbin/init as init process
[    7.843871] Unable to handle kernel paging request at virtual address 0000000056000000
[    7.851797] Mem abort info:
[    7.854589]   ESR = 0x96000004
[    7.857642]   EC = 0x25: DABT (current EL), IL = 32 bits
[    7.862950]   SET = 0, FnV = 0
[    7.866001]   EA = 0, S1PTW = 0
[    7.869134] Data abort info:
[    7.872011]   ISV = 0, ISS = 0x00000004
[    7.875842]   CM = 0, WnR = 0
[    7.878806] user pgtable: 4k pages, 48-bit VAs, pgdp=0000000774787000
[    7.885242] [0000000056000000] pgd=0000000000000000
[    7.890119] Internal error: Oops: 96000004 [#1] PREEMPT SMP
[    7.895684] Modules linked in:
[    7.898737] CPU: 2 PID: 1 Comm: systemd Not tainted 5.3.0-rc6-next-20190902-00001-g9709468 #48
[    7.907340] Hardware name: Renesas Salvator-X board based on r8a7795 ES2.0+ (DT)
[    7.914729] pstate: 20000005 (nzCv daif -PAN -UAO)
[    7.919523] pc : dput+0x38/0x2e8
[    7.922743] lr : dput+0x34/0x2e8
[    7.925964] sp : ffff80001006bba0
[    7.929270] x29: ffff80001006bba0 x28: ffff000735c98000 
[    7.934576] x27: 0000000000000000 x26: 0000000000000000 
[    7.939881] x25: 0000000056000000 x24: 0000000000004000 
[    7.945186] x23: 0000000000000001 x22: 0000000000080060 
[    7.950491] x21: 0000000000080040 x20: 0000000056000058 
[    7.955795] x19: 0000000056000000 x18: 0000000000000000 
[    7.961099] x17: 0000000000000000 x16: 0000000000000000 
[    7.966403] x15: 0000000000000000 x14: 0000000000000000 
[    7.971707] x13: 0000000000000000 x12: fefefefefefefeff 
[    7.977011] x11: 0000ffffa01018b8 x10: 0000ffffa01018b8 
[    7.982315] x9 : 6bff3a3a375c19ff x8 : 00ffffa01018b800 
[    7.987620] x7 : 0000000000000000 x6 : 0000000000000000 
[    7.992924] x5 : 0000000000000064 x4 : 0000000c00000000 
[    7.998228] x3 : 0000000000000001 x2 : 0000000000000082 
[    8.003532] x1 : ffff000735c98000 x0 : 0000000000000001 
[    8.008838] Call trace:
[    8.011278]  dput+0x38/0x2e8
[    8.014155]  terminate_walk+0xf4/0x120
[    8.017897]  path_lookupat+0xf8/0x1f8
[    8.021553]  filename_lookup+0x8c/0x160
[    8.025382]  user_path_at_empty+0x48/0x58
[    8.029387]  __arm64_sys_name_to_handle_at+0x64/0x2d0
[    8.034435]  el0_svc_common+0x68/0x178
[    8.038177]  el0_svc_handler+0x24/0x98
[    8.041920]  el0_svc+0x8/0xc
[    8.044798] Code: 72a00115 52800037 97fb26b4 91016274 (b9400260) 
[    8.050895] ---[ end trace dd06490ec981282b ]---
[    8.055966] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[    8.063619] SMP: stopping secondary CPUs
[    8.067539] Kernel Offset: disabled
[    8.071021] CPU features: 0x0002,21006004
[    8.075022] Memory Limit: none
[    8.078076] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---

Best regards,
Yoshihiro Shimoda
Greg Kroah-Hartman Sept. 3, 2019, 9:37 a.m. UTC | #2
On Tue, Sep 03, 2019 at 08:53:31AM +0000, Yoshihiro Shimoda wrote:
> Hi,
> 
> > From: David Howells, Sent: Friday, August 30, 2019 10:58 PM
> <snip>
> > diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
> > index 9063ede411ae..b8572e4d6a1b 100644
> > --- a/drivers/usb/core/devio.c
> > +++ b/drivers/usb/core/devio.c
> > @@ -41,6 +41,7 @@
> >  #include <linux/dma-mapping.h>
> >  #include <asm/byteorder.h>
> >  #include <linux/moduleparam.h>
> > +#include <linux/watch_queue.h>
> > 
> >  #include "usb.h"
> > 
> > @@ -2660,13 +2661,68 @@ static void usbdev_remove(struct usb_device *udev)
> >  	}
> >  }
> > 
> > +#ifdef CONFIG_USB_NOTIFICATIONS
> > +static noinline void post_usb_notification(const char *devname,
> > +					   enum usb_notification_type subtype,
> > +					   u32 error)
> > +{
> > +	unsigned int gran = WATCH_LENGTH_GRANULARITY;
> > +	unsigned int name_len, n_len;
> > +	u64 id = 0; /* Might want to put a dev# here. */
> > +
> > +	struct {
> > +		struct usb_notification n;
> > +		char more_name[USB_NOTIFICATION_MAX_NAME_LEN -
> > +			       (sizeof(struct usb_notification) -
> > +				offsetof(struct usb_notification, name))];
> > +	} n;
> > +
> > +	name_len = strlen(devname);
> > +	name_len = min_t(size_t, name_len, USB_NOTIFICATION_MAX_NAME_LEN);
> > +	n_len = round_up(offsetof(struct usb_notification, name) + name_len,
> > +			 gran) / gran;
> > +
> > +	memset(&n, 0, sizeof(n));
> > +	memcpy(n.n.name, devname, n_len);
> > +
> > +	n.n.watch.type		= WATCH_TYPE_USB_NOTIFY;
> > +	n.n.watch.subtype	= subtype;
> > +	n.n.watch.info		= n_len;
> > +	n.n.error		= error;
> > +	n.n.name_len		= name_len;
> > +
> > +	post_device_notification(&n.n.watch, id);
> > +}
> > +
> > +void post_usb_device_notification(const struct usb_device *udev,
> > +				  enum usb_notification_type subtype, u32 error)
> > +{
> > +	post_usb_notification(dev_name(&udev->dev), subtype, error);
> > +}
> > +
> > +void post_usb_bus_notification(const struct usb_bus *ubus,
> 
> This function's argument is struct usb_bus *, but ...
> 
> > +			       enum usb_notification_type subtype, u32 error)
> > +{
> > +	post_usb_notification(ubus->bus_name, subtype, error);
> > +}
> > +#endif
> > +
> >  static int usbdev_notify(struct notifier_block *self,
> >  			       unsigned long action, void *dev)
> >  {
> >  	switch (action) {
> >  	case USB_DEVICE_ADD:
> > +		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_ADD, 0);
> >  		break;
> >  	case USB_DEVICE_REMOVE:
> > +		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_REMOVE, 0);
> > +		usbdev_remove(dev);
> > +		break;
> > +	case USB_BUS_ADD:
> > +		post_usb_bus_notification(dev, NOTIFY_USB_BUS_ADD, 0);
> > +		break;
> > +	case USB_BUS_REMOVE:
> > +		post_usb_bus_notification(dev, NOTIFY_USB_BUS_REMOVE, 0);
> >  		usbdev_remove(dev);
> 
> this function calls usbdev_remove() with incorrect argument if the action
> is USB_BUS_REMOVE. So, this seems to cause the following issue [1] on
> my environment (R-Car H3 / r8a7795 on next-20190902) [2]. However, I have
> no idea how to fix the issue, so I report this issue at the first step.

As a few of us just discussed this on IRC, these bus notifiers should
probably be dropped as these are the incorrect structure type as you
found out.  Thanks for the report.

greg k-h
Guenter Roeck Sept. 3, 2019, 12:51 p.m. UTC | #3
On Fri, Aug 30, 2019 at 02:58:23PM +0100, David Howells wrote:
> Add a USB subsystem notification mechanism whereby notifications about
> hardware events such as device connection, disconnection, reset and I/O
> errors, can be reported to a monitoring process asynchronously.
> 
> Firstly, an event queue needs to be created:
> 
> 	fd = open("/dev/event_queue", O_RDWR);
> 	ioctl(fd, IOC_WATCH_QUEUE_SET_SIZE, page_size << n);
> 
> then a notification can be set up to report USB notifications via that
> queue:
> 
> 	struct watch_notification_filter filter = {
> 		.nr_filters = 1,
> 		.filters = {
> 			[0] = {
> 				.type = WATCH_TYPE_USB_NOTIFY,
> 				.subtype_filter[0] = UINT_MAX;
> 			},
> 		},
> 	};
> 	ioctl(fd, IOC_WATCH_QUEUE_SET_FILTER, &filter);
> 	notify_devices(fd, 12);
> 
> After that, records will be placed into the queue when events occur on a
> USB device or bus.  Records are of the following format:
> 
> 	struct usb_notification {
> 		struct watch_notification watch;
> 		__u32	error;
> 		__u32	reserved;
> 		__u8	name_len;
> 		__u8	name[0];
> 	} *n;
> 
> Where:
> 
> 	n->watch.type will be WATCH_TYPE_USB_NOTIFY
> 
> 	n->watch.subtype will be the type of notification, such as
> 	NOTIFY_USB_DEVICE_ADD.
> 
> 	n->watch.info & WATCH_INFO_LENGTH will indicate the length of the
> 	record.
> 
> 	n->watch.info & WATCH_INFO_ID will be the second argument to
> 	device_notify(), shifted.
> 
> 	n->error and n->reserved are intended to convey information such as
> 	error codes, but are currently not used
> 
> 	n->name_len and n->name convey the USB device name as an
> 	unterminated string.  This may be truncated - it is currently
> 	limited to a maximum 63 chars.
> 
> Note that it is permissible for event records to be of variable length -
> or, at least, the length may be dependent on the subtype.
> 
> Signed-off-by: David Howells <dhowells@redhat.com>
> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> cc: linux-usb@vger.kernel.org
> ---
> 
>  Documentation/watch_queue.rst    |    9 ++++++
>  drivers/usb/core/Kconfig         |    9 ++++++
>  drivers/usb/core/devio.c         |   56 ++++++++++++++++++++++++++++++++++++++
>  drivers/usb/core/hub.c           |    4 +++
>  include/linux/usb.h              |   18 ++++++++++++
>  include/uapi/linux/watch_queue.h |   30 ++++++++++++++++++++
>  6 files changed, 125 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/watch_queue.rst b/Documentation/watch_queue.rst
> index 5cc9c6924727..4087a8e670a8 100644
> --- a/Documentation/watch_queue.rst
> +++ b/Documentation/watch_queue.rst
> @@ -11,6 +11,8 @@ receive notifications from the kernel.  This can be used in conjunction with::
>  
>      * Block layer event notifications
>  
> +    * USB subsystem event notifications
> +
>  
>  The notifications buffers can be enabled by:
>  
> @@ -315,6 +317,13 @@ Any particular buffer can be fed from multiple sources.  Sources include:
>      or temporary link loss.  Watches of this type are set on the global device
>      watch list.
>  
> +  * WATCH_TYPE_USB_NOTIFY
> +
> +    Notifications of this type indicate USB subsystem events, such as
> +    attachment, removal, reset and I/O errors.  Separate events are generated
> +    for buses and devices.  Watchpoints of this type are set on the global
> +    device watch list.
> +
>  
>  Event Filtering
>  ===============
> diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
> index ecaacc8ed311..57e7b649e48b 100644
> --- a/drivers/usb/core/Kconfig
> +++ b/drivers/usb/core/Kconfig
> @@ -102,3 +102,12 @@ config USB_AUTOSUSPEND_DELAY
>  	  The default value Linux has always had is 2 seconds.  Change
>  	  this value if you want a different delay and cannot modify
>  	  the command line or module parameter.
> +
> +config USB_NOTIFICATIONS
> +	bool "Provide USB hardware event notifications"
> +	depends on USB && DEVICE_NOTIFICATIONS
> +	help
> +	  This option provides support for getting hardware event notifications
> +	  on USB devices and interfaces.  This makes use of the
> +	  /dev/watch_queue misc device to handle the notification buffer.
> +	  device_notify(2) is used to set/remove watches.
> diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
> index 9063ede411ae..b8572e4d6a1b 100644
> --- a/drivers/usb/core/devio.c
> +++ b/drivers/usb/core/devio.c
> @@ -41,6 +41,7 @@
>  #include <linux/dma-mapping.h>
>  #include <asm/byteorder.h>
>  #include <linux/moduleparam.h>
> +#include <linux/watch_queue.h>
>  
>  #include "usb.h"
>  
> @@ -2660,13 +2661,68 @@ static void usbdev_remove(struct usb_device *udev)
>  	}
>  }
>  
> +#ifdef CONFIG_USB_NOTIFICATIONS
> +static noinline void post_usb_notification(const char *devname,
> +					   enum usb_notification_type subtype,
> +					   u32 error)
> +{
> +	unsigned int gran = WATCH_LENGTH_GRANULARITY;
> +	unsigned int name_len, n_len;
> +	u64 id = 0; /* Might want to put a dev# here. */
> +
> +	struct {
> +		struct usb_notification n;
> +		char more_name[USB_NOTIFICATION_MAX_NAME_LEN -
> +			       (sizeof(struct usb_notification) -
> +				offsetof(struct usb_notification, name))];
> +	} n;
> +
> +	name_len = strlen(devname);
> +	name_len = min_t(size_t, name_len, USB_NOTIFICATION_MAX_NAME_LEN);
> +	n_len = round_up(offsetof(struct usb_notification, name) + name_len,
> +			 gran) / gran;
> +
> +	memset(&n, 0, sizeof(n));
> +	memcpy(n.n.name, devname, n_len);
> +
> +	n.n.watch.type		= WATCH_TYPE_USB_NOTIFY;
> +	n.n.watch.subtype	= subtype;
> +	n.n.watch.info		= n_len;
> +	n.n.error		= error;
> +	n.n.name_len		= name_len;
> +
> +	post_device_notification(&n.n.watch, id);
> +}
> +
> +void post_usb_device_notification(const struct usb_device *udev,
> +				  enum usb_notification_type subtype, u32 error)
> +{
> +	post_usb_notification(dev_name(&udev->dev), subtype, error);
> +}
> +
> +void post_usb_bus_notification(const struct usb_bus *ubus,
> +			       enum usb_notification_type subtype, u32 error)
> +{
> +	post_usb_notification(ubus->bus_name, subtype, error);
> +}
> +#endif
> +
>  static int usbdev_notify(struct notifier_block *self,
>  			       unsigned long action, void *dev)
>  {
>  	switch (action) {
>  	case USB_DEVICE_ADD:
> +		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_ADD, 0);
>  		break;
>  	case USB_DEVICE_REMOVE:
> +		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_REMOVE, 0);
> +		usbdev_remove(dev);
> +		break;
> +	case USB_BUS_ADD:
> +		post_usb_bus_notification(dev, NOTIFY_USB_BUS_ADD, 0);
> +		break;
> +	case USB_BUS_REMOVE:
> +		post_usb_bus_notification(dev, NOTIFY_USB_BUS_REMOVE, 0);
>  		usbdev_remove(dev);

This added call to usbdev_remove() results in a crash when running
the qemu "tosa" emulation. Removing the call fixes the problem.

Guenter
David Howells Sept. 3, 2019, 4:07 p.m. UTC | #4
Guenter Roeck <linux@roeck-us.net> wrote:

> This added call to usbdev_remove() results in a crash when running
> the qemu "tosa" emulation. Removing the call fixes the problem.

Yeah - I'm going to drop the bus notification messages for now.

David
Guenter Roeck Sept. 3, 2019, 4:12 p.m. UTC | #5
On Tue, Sep 03, 2019 at 05:07:47PM +0100, David Howells wrote:
> Guenter Roeck <linux@roeck-us.net> wrote:
> 
> > This added call to usbdev_remove() results in a crash when running
> > the qemu "tosa" emulation. Removing the call fixes the problem.
> 
> Yeah - I'm going to drop the bus notification messages for now.
> 
It is not the bus notification itself causing problems. It is the
call to usbdev_remove().

Guenter
David Howells Sept. 3, 2019, 4:29 p.m. UTC | #6
Guenter Roeck <linux@roeck-us.net> wrote:

> > > This added call to usbdev_remove() results in a crash when running
> > > the qemu "tosa" emulation. Removing the call fixes the problem.
> > 
> > Yeah - I'm going to drop the bus notification messages for now.
> > 
> It is not the bus notification itself causing problems. It is the
> call to usbdev_remove().

Unfortunately, I don't know how to fix it and don't have much time to
investigate it right now - and it's something that can be added back later.

David
Alan Stern Sept. 3, 2019, 5:06 p.m. UTC | #7
On Tue, 3 Sep 2019, David Howells wrote:

> Guenter Roeck <linux@roeck-us.net> wrote:
> 
> > > > This added call to usbdev_remove() results in a crash when running
> > > > the qemu "tosa" emulation. Removing the call fixes the problem.
> > > 
> > > Yeah - I'm going to drop the bus notification messages for now.
> > > 
> > It is not the bus notification itself causing problems. It is the
> > call to usbdev_remove().
> 
> Unfortunately, I don't know how to fix it and don't have much time to
> investigate it right now - and it's something that can be added back later.

The cause of your problem is quite simple:

 static int usbdev_notify(struct notifier_block *self,
 			       unsigned long action, void *dev)
 {
 	switch (action) {
 	case USB_DEVICE_ADD:
+		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_ADD, 0);
 		break;
 	case USB_DEVICE_REMOVE:
+		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_REMOVE, 0);
+		usbdev_remove(dev);
+		break;
+	case USB_BUS_ADD:
+		post_usb_bus_notification(dev, NOTIFY_USB_BUS_ADD, 0);
+		break;
+	case USB_BUS_REMOVE:
+		post_usb_bus_notification(dev, NOTIFY_USB_BUS_REMOVE, 0);
 		usbdev_remove(dev);
 		break;
 	}

The original code had usbdev_remove(dev) under the USB_DEVICE_REMOVE
case.  The patch mistakenly moves it, putting it under the
USB_BUS_REMOVE case.

If the usbdev_remove() call were left where it was originally, the 
problem would be solved.

Alan Stern
Alan Stern Sept. 3, 2019, 5:17 p.m. UTC | #8
On Tue, 3 Sep 2019, Alan Stern wrote:

> On Tue, 3 Sep 2019, David Howells wrote:
> 
> > Guenter Roeck <linux@roeck-us.net> wrote:
> > 
> > > > > This added call to usbdev_remove() results in a crash when running
> > > > > the qemu "tosa" emulation. Removing the call fixes the problem.
> > > > 
> > > > Yeah - I'm going to drop the bus notification messages for now.
> > > > 
> > > It is not the bus notification itself causing problems. It is the
> > > call to usbdev_remove().
> > 
> > Unfortunately, I don't know how to fix it and don't have much time to
> > investigate it right now - and it's something that can be added back later.
> 
> The cause of your problem is quite simple:
> 
>  static int usbdev_notify(struct notifier_block *self,
>  			       unsigned long action, void *dev)
>  {
>  	switch (action) {
>  	case USB_DEVICE_ADD:
> +		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_ADD, 0);
>  		break;
>  	case USB_DEVICE_REMOVE:
> +		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_REMOVE, 0);
> +		usbdev_remove(dev);
> +		break;
> +	case USB_BUS_ADD:
> +		post_usb_bus_notification(dev, NOTIFY_USB_BUS_ADD, 0);
> +		break;
> +	case USB_BUS_REMOVE:
> +		post_usb_bus_notification(dev, NOTIFY_USB_BUS_REMOVE, 0);
>  		usbdev_remove(dev);
>  		break;
>  	}
> 
> The original code had usbdev_remove(dev) under the USB_DEVICE_REMOVE
> case.  The patch mistakenly moves it, putting it under the
------------------------------^^^^^

Sorry, I should have said "duplicates" it.

Alan Stern

> USB_BUS_REMOVE case.
> 
> If the usbdev_remove() call were left where it was originally, the 
> problem would be solved.
> 
> Alan Stern
Yoshihiro Shimoda Sept. 4, 2019, 1:53 a.m. UTC | #9
Hi Greg,

> From: Greg Kroah-Hartman, Sent: Tuesday, September 3, 2019 6:37 PM
<snip>
> > > +void post_usb_bus_notification(const struct usb_bus *ubus,
> >
> > This function's argument is struct usb_bus *, but ...
> >
> > > +			       enum usb_notification_type subtype, u32 error)
> > > +{
> > > +	post_usb_notification(ubus->bus_name, subtype, error);
> > > +}
> > > +#endif
> > > +
> > >  static int usbdev_notify(struct notifier_block *self,
> > >  			       unsigned long action, void *dev)
> > >  {
> > >  	switch (action) {
> > >  	case USB_DEVICE_ADD:
> > > +		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_ADD, 0);
> > >  		break;
> > >  	case USB_DEVICE_REMOVE:
> > > +		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_REMOVE, 0);
> > > +		usbdev_remove(dev);
> > > +		break;
> > > +	case USB_BUS_ADD:
> > > +		post_usb_bus_notification(dev, NOTIFY_USB_BUS_ADD, 0);
> > > +		break;
> > > +	case USB_BUS_REMOVE:
> > > +		post_usb_bus_notification(dev, NOTIFY_USB_BUS_REMOVE, 0);
> > >  		usbdev_remove(dev);
> >
> > this function calls usbdev_remove() with incorrect argument if the action
> > is USB_BUS_REMOVE. So, this seems to cause the following issue [1] on
> > my environment (R-Car H3 / r8a7795 on next-20190902) [2]. However, I have
> > no idea how to fix the issue, so I report this issue at the first step.
> 
> As a few of us just discussed this on IRC, these bus notifiers should
> probably be dropped as these are the incorrect structure type as you
> found out.  Thanks for the report.

Thank you for the discussion. I got it.

Best regards,
Yoshihiro Shimoda

> greg k-h
David Howells Sept. 4, 2019, 3:17 p.m. UTC | #10
Alan Stern <stern@rowland.harvard.edu> wrote:

> > > Unfortunately, I don't know how to fix it and don't have much time to
> > > investigate it right now - and it's something that can be added back later.
> > 
> > The cause of your problem is quite simple:
> > 
> >  static int usbdev_notify(struct notifier_block *self,
> >  			       unsigned long action, void *dev)
> >  {
> >  	switch (action) {
> >  	case USB_DEVICE_ADD:
> > +		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_ADD, 0);
> >  		break;
> >  	case USB_DEVICE_REMOVE:
> > +		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_REMOVE, 0);
> > +		usbdev_remove(dev);
> > +		break;
> > +	case USB_BUS_ADD:
> > +		post_usb_bus_notification(dev, NOTIFY_USB_BUS_ADD, 0);
> > +		break;
> > +	case USB_BUS_REMOVE:
> > +		post_usb_bus_notification(dev, NOTIFY_USB_BUS_REMOVE, 0);
> >  		usbdev_remove(dev);
> >  		break;
> >  	}
> > 
> > The original code had usbdev_remove(dev) under the USB_DEVICE_REMOVE
> > case.  The patch mistakenly moves it, putting it under the
> ------------------------------^^^^^
> 
> Sorry, I should have said "duplicates" it.

Ah, thanks.  I'd already removed the USB bus notifications, so I'll leave them
out for now.

David

Patch
diff mbox series

diff --git a/Documentation/watch_queue.rst b/Documentation/watch_queue.rst
index 5cc9c6924727..4087a8e670a8 100644
--- a/Documentation/watch_queue.rst
+++ b/Documentation/watch_queue.rst
@@ -11,6 +11,8 @@  receive notifications from the kernel.  This can be used in conjunction with::
 
     * Block layer event notifications
 
+    * USB subsystem event notifications
+
 
 The notifications buffers can be enabled by:
 
@@ -315,6 +317,13 @@  Any particular buffer can be fed from multiple sources.  Sources include:
     or temporary link loss.  Watches of this type are set on the global device
     watch list.
 
+  * WATCH_TYPE_USB_NOTIFY
+
+    Notifications of this type indicate USB subsystem events, such as
+    attachment, removal, reset and I/O errors.  Separate events are generated
+    for buses and devices.  Watchpoints of this type are set on the global
+    device watch list.
+
 
 Event Filtering
 ===============
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index ecaacc8ed311..57e7b649e48b 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -102,3 +102,12 @@  config USB_AUTOSUSPEND_DELAY
 	  The default value Linux has always had is 2 seconds.  Change
 	  this value if you want a different delay and cannot modify
 	  the command line or module parameter.
+
+config USB_NOTIFICATIONS
+	bool "Provide USB hardware event notifications"
+	depends on USB && DEVICE_NOTIFICATIONS
+	help
+	  This option provides support for getting hardware event notifications
+	  on USB devices and interfaces.  This makes use of the
+	  /dev/watch_queue misc device to handle the notification buffer.
+	  device_notify(2) is used to set/remove watches.
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 9063ede411ae..b8572e4d6a1b 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -41,6 +41,7 @@ 
 #include <linux/dma-mapping.h>
 #include <asm/byteorder.h>
 #include <linux/moduleparam.h>
+#include <linux/watch_queue.h>
 
 #include "usb.h"
 
@@ -2660,13 +2661,68 @@  static void usbdev_remove(struct usb_device *udev)
 	}
 }
 
+#ifdef CONFIG_USB_NOTIFICATIONS
+static noinline void post_usb_notification(const char *devname,
+					   enum usb_notification_type subtype,
+					   u32 error)
+{
+	unsigned int gran = WATCH_LENGTH_GRANULARITY;
+	unsigned int name_len, n_len;
+	u64 id = 0; /* Might want to put a dev# here. */
+
+	struct {
+		struct usb_notification n;
+		char more_name[USB_NOTIFICATION_MAX_NAME_LEN -
+			       (sizeof(struct usb_notification) -
+				offsetof(struct usb_notification, name))];
+	} n;
+
+	name_len = strlen(devname);
+	name_len = min_t(size_t, name_len, USB_NOTIFICATION_MAX_NAME_LEN);
+	n_len = round_up(offsetof(struct usb_notification, name) + name_len,
+			 gran) / gran;
+
+	memset(&n, 0, sizeof(n));
+	memcpy(n.n.name, devname, n_len);
+
+	n.n.watch.type		= WATCH_TYPE_USB_NOTIFY;
+	n.n.watch.subtype	= subtype;
+	n.n.watch.info		= n_len;
+	n.n.error		= error;
+	n.n.name_len		= name_len;
+
+	post_device_notification(&n.n.watch, id);
+}
+
+void post_usb_device_notification(const struct usb_device *udev,
+				  enum usb_notification_type subtype, u32 error)
+{
+	post_usb_notification(dev_name(&udev->dev), subtype, error);
+}
+
+void post_usb_bus_notification(const struct usb_bus *ubus,
+			       enum usb_notification_type subtype, u32 error)
+{
+	post_usb_notification(ubus->bus_name, subtype, error);
+}
+#endif
+
 static int usbdev_notify(struct notifier_block *self,
 			       unsigned long action, void *dev)
 {
 	switch (action) {
 	case USB_DEVICE_ADD:
+		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_ADD, 0);
 		break;
 	case USB_DEVICE_REMOVE:
+		post_usb_device_notification(dev, NOTIFY_USB_DEVICE_REMOVE, 0);
+		usbdev_remove(dev);
+		break;
+	case USB_BUS_ADD:
+		post_usb_bus_notification(dev, NOTIFY_USB_BUS_ADD, 0);
+		break;
+	case USB_BUS_REMOVE:
+		post_usb_bus_notification(dev, NOTIFY_USB_BUS_REMOVE, 0);
 		usbdev_remove(dev);
 		break;
 	}
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 236313f41f4a..e8ebacc15a32 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -29,6 +29,7 @@ 
 #include <linux/random.h>
 #include <linux/pm_qos.h>
 #include <linux/kobject.h>
+#include <linux/watch_queue.h>
 
 #include <linux/uaccess.h>
 #include <asm/byteorder.h>
@@ -4605,6 +4606,9 @@  hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
 				(udev->config) ? "reset" : "new", speed,
 				devnum, driver_name);
 
+	if (udev->config)
+		post_usb_device_notification(udev, NOTIFY_USB_DEVICE_RESET, 0);
+
 	/* Set up TT records, if needed  */
 	if (hdev->tt) {
 		udev->tt = hdev->tt;
diff --git a/include/linux/usb.h b/include/linux/usb.h
index e87826e23d59..ddfb9dc2473e 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -26,6 +26,7 @@ 
 struct usb_device;
 struct usb_driver;
 struct wusb_dev;
+enum usb_notification_type;
 
 /*-------------------------------------------------------------------------*/
 
@@ -2010,6 +2011,23 @@  extern void usb_led_activity(enum usb_led_event ev);
 static inline void usb_led_activity(enum usb_led_event ev) {}
 #endif
 
+/*
+ * Notification functions.
+ */
+#ifdef CONFIG_USB_NOTIFICATIONS
+extern void post_usb_device_notification(const struct usb_device *udev,
+					 enum usb_notification_type subtype,
+					 u32 error);
+extern void post_usb_bus_notification(const struct usb_bus *ubus,
+				      enum usb_notification_type subtype,
+				      u32 error);
+#else
+static inline void post_usb_device_notification(const struct usb_device *udev,
+						unsigned int subtype, u32 error) {}
+static inline void post_usb_bus_notification(const struct usb_bus *ubus,
+					     unsigned int subtype, u32 error) {}
+#endif
+
 #endif  /* __KERNEL__ */
 
 #endif
diff --git a/include/uapi/linux/watch_queue.h b/include/uapi/linux/watch_queue.h
index 9a6c059af09d..bc5183e10d8c 100644
--- a/include/uapi/linux/watch_queue.h
+++ b/include/uapi/linux/watch_queue.h
@@ -12,7 +12,8 @@  enum watch_notification_type {
 	WATCH_TYPE_META		= 0,	/* Special record */
 	WATCH_TYPE_KEY_NOTIFY	= 1,	/* Key change event notification */
 	WATCH_TYPE_BLOCK_NOTIFY	= 2,	/* Block layer event notification */
-	WATCH_TYPE___NR		= 3
+	WATCH_TYPE_USB_NOTIFY	= 3,	/* USB subsystem event notification */
+	WATCH_TYPE___NR		= 4
 };
 
 enum watch_meta_notification_subtype {
@@ -152,4 +153,31 @@  struct block_notification {
 	__u64	sector;			/* Affected sector */
 };
 
+/*
+ * Type of USB layer notification.
+ */
+enum usb_notification_type {
+	NOTIFY_USB_DEVICE_ADD		= 0, /* USB device added */
+	NOTIFY_USB_DEVICE_REMOVE	= 1, /* USB device removed */
+	NOTIFY_USB_BUS_ADD		= 2, /* USB bus added */
+	NOTIFY_USB_BUS_REMOVE		= 3, /* USB bus removed */
+	NOTIFY_USB_DEVICE_RESET		= 4, /* USB device reset */
+	NOTIFY_USB_DEVICE_ERROR		= 5, /* USB device error */
+};
+
+/*
+ * USB subsystem notification record.
+ * - watch.type = WATCH_TYPE_USB_NOTIFY
+ * - watch.subtype = enum usb_notification_type
+ */
+struct usb_notification {
+	struct watch_notification watch; /* WATCH_TYPE_USB_NOTIFY */
+	__u32	error;
+	__u32	reserved;
+	__u8	name_len;		/* Length of device name */
+	__u8	name[0];		/* Device name (padded to __u64, truncated at 63 chars) */
+};
+
+#define USB_NOTIFICATION_MAX_NAME_LEN 63
+
 #endif /* _UAPI_LINUX_WATCH_QUEUE_H */