Make sure an event is ack-ed before Channel->Count is incremented
otherwise EvtchnGetCount() could sample the incremented value whilst new
events would be missed. Thus EvtchnWait() could end up waiting for a
Count value that my never be reached.
Signed-off-by: Paul Durrant <pdurrant@amazon.com>
KeMemoryBarrier();
if (!Channel->Closed) {
- Channel->Count++;
-
RemoveEntryList(&Channel->PendingListEntry);
InitializeListHead(&Channel->PendingListEntry);
&Context->EvtchnAbi,
Channel->LocalPort);
+ /*
+ * Make sure the event is ack-ed before Count is incremented
+ * otherwise there is a small window where EvtchnWait() could
+ * end up waiting on the incremented value whilst new events
+ * would be missed (hence Count would not be further
+ * incremented to wake the waiter).
+ */
+ KeMemoryBarrier();
+ Channel->Count++;
+
#pragma warning(suppress:6387) // NULL argument
DoneSomething |= Channel->Callback(NULL, Channel->Argument);
} else if (List != NULL) {
{
UNREFERENCED_PARAMETER(Interface);
+ KeMemoryBarrier();
+
return Channel->Count;
}