On Mon, Nov 28, 2022 at 10:10:04AM +0800, Li Zetao wrote: > When doing the following test steps, an error was found: > step 1: modprobe virtio_input succeeded > # modprobe virtio_input <-- OK > > step 2: fault injection in input_allocate_device() > # modprobe -r virtio_input <-- OK > # ... > CPU: 0 PID: 4260 Comm: modprobe Tainted: G W > 6.1.0-rc6-00285-g6a1e40c4b995-dirty #109 > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), > Call Trace: > <TASK> > should_fail.cold+0x5/0x1f > ... > kmalloc_trace+0x27/0xa0 > input_allocate_device+0x43/0x280 > virtinput_probe+0x23b/0x1648 [virtio_input] > ... > </TASK> > virtio_input: probe of virtio5 failed with error -12 > > step 3: modprobe virtio_net failed > # modprobe virtio_input <-- failed > virtio_input: probe of virtio1 failed with error -2 > > The root cause of the problem is that the virtqueues are not > stopped on the error handling path when input_allocate_device() > fails in virtinput_probe(), resulting in an error "-ENOENT" > returned in the next modprobe call in setup_vq(). > > virtio_pci_modern_device uses virtqueues to send or > receive message, and "queue_enable" records whether the > queues are available. In vp_modern_find_vqs(), all queues > will be selected and activated, but once queues are enabled > there is no way to go back except reset. > > Fix it by reset virtio device on error handling path. After > virtinput_init_vqs() succeeded, all virtqueues should be > stopped on error handling path. > > Fixes: 1fcf0512c9c8 ("virtio_pci: modern driver") Probably 271c865161c57cfabca45b93eaa712b19da365bc > Signed-off-by: Li Zetao <lizetao1@xxxxxxxxxx> > --- > drivers/virtio/virtio_input.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/virtio/virtio_input.c b/drivers/virtio/virtio_input.c > index 3aa46703872d..f638f1cd3531 100644 > --- a/drivers/virtio/virtio_input.c > +++ b/drivers/virtio/virtio_input.c > @@ -330,6 +330,7 @@ static int virtinput_probe(struct virtio_device *vdev) > err_mt_init_slots: > input_free_device(vi->idev); > err_input_alloc: > + virtio_reset_device(vdev); > vdev->config->del_vqs(vdev); > err_init_vq: > kfree(vi); > -- > 2.25.1