On Thu, Aug 08, 2024 at 10:51:41AM +0300, Kirill A. Shutemov wrote: > Hongyu reported a hang on kexec in a VM. QEMU reported invalid memory > accesses during the hang. > > Invalid read at addr 0x102877002, size 2, region '(null)', reason: rejected > Invalid write at addr 0x102877A44, size 2, region '(null)', reason: rejected > ... > > It was traced down to virtio-console. Kexec works fine if virtio-console > is not in use. virtio is not doing a lot of 16 bit reads. Are these the reads: virtio_cread(vdev, struct virtio_console_config, cols, &cols); virtio_cread(vdev, struct virtio_console_config, rows, &rows); ? write is a bit puzzling too. This one? bool vp_notify(struct virtqueue *vq) { /* we write the queue's selector into the notification register to * signal the other end */ iowrite16(vq->index, (void __iomem *)vq->priv); return true; } > > Looks like virtio-console continues to write to the MMIO even after > underlying virtio-pci device is removed. You mention both MMIO and pci, I am confused. Removed by what? In what sense? > > The problem can be mitigated by removing all virtio devices on virtio > bus shutdown. > > Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> > Reported-by: Hongyu Ning <hongyu.ning@xxxxxxxxxxxxxxx> A bit worried about doing so much activity on shutdown, and for all devices, too. I'd like to understand what is going on a bit better - could be a symptom of a bigger problem (e.g. missing handling for suprise removal?). > --- > drivers/virtio/virtio.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > > diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c > index a9b93e99c23a..6c2f908eb22c 100644 > --- a/drivers/virtio/virtio.c > +++ b/drivers/virtio/virtio.c > @@ -356,6 +356,15 @@ static void virtio_dev_remove(struct device *_d) > of_node_put(dev->dev.of_node); > } > > +static void virtio_dev_shutdown(struct device *_d) > +{ > + struct virtio_device *dev = dev_to_virtio(_d); > + struct virtio_driver *drv = drv_to_virtio(dev->dev.driver); > + > + if (drv && drv->remove) > + drv->remove(dev); > +} > + > static const struct bus_type virtio_bus = { > .name = "virtio", > .match = virtio_dev_match, > @@ -363,6 +372,7 @@ static const struct bus_type virtio_bus = { > .uevent = virtio_uevent, > .probe = virtio_dev_probe, > .remove = virtio_dev_remove, > + .shutdown = virtio_dev_shutdown, > }; > > int __register_virtio_driver(struct virtio_driver *driver, struct module *owner) > -- > 2.43.0