dev/xenstore: fix return with locks held

Fix returning from xenstore device with locks held, which triggers the
following panic:

# cat /dev/xen/xenstore
^C
userret: returning with the following locks held:
exclusive sx evtchn_ringc_sx (evtchn_ringc_sx) r = 0 (0xfffff8000650be40) locked @ /usr/src/sys/dev/xen/evtchn/evtchn_dev.c:262

Note this is not a security issue since access to the device is
limited to root by default.

Sponsored by:	Citrix Systems R&D
MFC after:	1 week
This commit is contained in:
Roger Pau Monné 2020-05-20 11:01:10 +00:00
parent 22d1b05c8c
commit b5ba8a0f32

View File

@ -261,9 +261,10 @@ evtchn_read(struct cdev *dev, struct uio *uio, int ioflag)
sx_xlock(&u->ring_cons_mutex); sx_xlock(&u->ring_cons_mutex);
for (;;) { for (;;) {
error = EFBIG; if (u->ring_overflow) {
if (u->ring_overflow) error = EFBIG;
goto unlock_out; goto unlock_out;
}
c = u->ring_cons; c = u->ring_cons;
p = u->ring_prod; p = u->ring_prod;
@ -271,13 +272,13 @@ evtchn_read(struct cdev *dev, struct uio *uio, int ioflag)
break; break;
if (ioflag & IO_NDELAY) { if (ioflag & IO_NDELAY) {
sx_xunlock(&u->ring_cons_mutex); error = EWOULDBLOCK;
return (EWOULDBLOCK); goto unlock_out;
} }
error = sx_sleep(u, &u->ring_cons_mutex, PCATCH, "evtchw", 0); error = sx_sleep(u, &u->ring_cons_mutex, PCATCH, "evtchw", 0);
if ((error != 0) && (error != EWOULDBLOCK)) if ((error != 0) && (error != EWOULDBLOCK))
return (error); goto unlock_out;
} }
/* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */ /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */