CVSROOT:        /cvs
Module name:    src
Changes by:     s...@cvs.openbsd.org    2024/05/17 10:37:11

Modified files:
        sys/dev/fdt    : virtio_mmio.c 
        sys/dev/pci    : virtio_pci.c 
        sys/dev/pv     : if_vio.c virtiovar.h 

Log message:
vio: Fix signal handling and locking in sysctl path

Commits f0b002d01d5 "Release the netlock when sleeping for control
messages in in vioioctl()" and 126b881f71 "Insert a workaround for
per-ifp ioctl being called w/o NET_LOCK()." in vio(4) fixed a deadlock
but may cause a crash with a protection fault trap if addresses are
added/removed concurrently.

The actual issue is that signals are not handled correctly while
sleeping. After a signal, there is a race condition where sc_ctrl_inuse
is first set to FREE and then the interrupt handler sets it to DONE,
causing a hang in the next vio_wait_ctrl() call.

To fix it:

* Revert the NET_LOCK unlocking work-around.

* Remove PCATCH from the sleep call when we wait for control queue,
avoiding the race with vio_ctrleof(). To ensure that we don't hang
forever, use a 5 second timeout.

* If the timeout is hit, or if the hypervisor has set the
DEVICE_NEEDS_RESET status bit, do not try to use the control queue
until the next ifconfig down/up which resets the device.

* In order to allow reading the device status from device drivers, add a
new interface to the virtio transport drivers.

* Avoid a crash if there is outgoing traffic while doing ifconfig down.

OK bluhm@

Reply via email to