evtchn/fifo: Don't set PENDING bit if guest misbehaves

Currently, evtchn_fifo_set_pending() will mark the event as PENDING even
if it fails to lock the FIFO event queue(s), or if the guest has not
initialized the FIFO control block for the target vCPU. A well-behaved
guest should never trigger either of these cases.

There is no good reason to set the PENDING bit (the guest should not
depend on this behaviour anyway) or check for pollers in such corner
cases, so skip that. In fact, both the comment above the for loop and
the commit message for

 41a822c392 xen/events: rework fifo queue locking

suggest that the bit should be set after the FIFO queue(s) are locked.

Take the opportunity to rename the was_pending variable (flipping its
sense) and switch to the standard bool type.

Suggested-by: David Vrabel <dvrabel@amazon.co.uk>
Signed-off-by: Raphael Ning <raphning@amazon.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: David Vrabel <dvrabel@amazon.co.uk>
Tested-by: Luca Fancellu <luca.fancellu@arm.com>
This commit is contained in:
Raphael Ning authored and Julien Grall committed 2022-03-21 10:28:33 +00:00
1 parent fdfb07eb28
commit 8aa0e9d2d1
1 file changed
+4 -4
+4 -4
View File
@@ -165,7 +165,7 @@ static void cf_check evtchn_fifo_set_pending(
unsigned int port;
event_word_t *word;
unsigned long flags;
bool_t was_pending;
bool check_pollers = false;
struct evtchn_fifo_queue *q, *old_q;
unsigned int try;
bool linked = true;
@@ -226,8 +226,6 @@ static void cf_check evtchn_fifo_set_pending(
spin_unlock_irqrestore(&q->lock, flags);
}
was_pending = guest_test_and_set_bit(d, EVTCHN_FIFO_PENDING, word);
/* If we didn't get the lock bail out. */
if ( try == 3 )
{
@@ -249,6 +247,8 @@ static void cf_check evtchn_fifo_set_pending(
goto unlock;
}
check_pollers = !guest_test_and_set_bit(d, EVTCHN_FIFO_PENDING, word);
/*
* Link the event if it unmasked and not already linked.
*/
@@ -314,7 +314,7 @@ static void cf_check evtchn_fifo_set_pending(
&v->evtchn_fifo->control_block->ready) )
vcpu_mark_events_pending(v);
if ( !was_pending )
if ( check_pollers )
evtchn_check_pollers(d, port);
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.