evtchn: evtchn_reset() shouldn't succeed with still-open ports
authorJan Beulich <jbeulich@suse.com>
Tue, 22 Sep 2020 13:50:55 +0000 (15:50 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 22 Sep 2020 13:50:55 +0000 (15:50 +0200)
commit8d385b247bca40ece40c9279391054bc98934325
treeb14195d0e5cb6b18883d6a3c5961cedb289f1409
parent62bcdc4edbf6d8c6e8a25544d48de22ccf75310d
evtchn: evtchn_reset() shouldn't succeed with still-open ports

While the function closes all ports, it does so without holding any
lock, and hence racing requests may be issued causing new ports to get
opened. This would have been problematic in particular if such a newly
opened port had a port number above the new implementation limit (i.e.
when switching from FIFO to 2-level) after the reset, as prior to
"evtchn: relax port_is_valid()" this could have led to e.g.
evtchn_close()'s "BUG_ON(!port_is_valid(d2, port2))" to trigger.

Introduce a counter of active ports and check that it's (still) no
larger then the number of Xen internally used ones after obtaining the
necessary lock in evtchn_reset().

As to the access model of the new {active,xen}_evtchns fields - while
all writes get done using write_atomic(), reads ought to use
read_atomic() only when outside of a suitably locked region.

Note that as of now evtchn_bind_virq() and evtchn_bind_ipi() don't have
a need to call check_free_port().

This is part of XSA-343.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Reviewed-by: Julien Grall <jgrall@amazon.com>
xen/common/event_channel.c
xen/include/xen/sched.h