win-pvdrivers

changeset 853:0fd4e07ab4ae 0.11.0.267

Fixed a race in xenbus_dpc
author James Harper <james.harper@bendigoit.com.au>
date Thu Feb 17 21:16:53 2011 +1100 (2011-02-17)
parents 5f986c984bf1
children f1de12c8d92d
files xenpci/xenbus.c
line diff
     1.1 --- a/xenpci/xenbus.c	Wed Feb 16 23:10:04 2011 +1100
     1.2 +++ b/xenpci/xenbus.c	Thu Feb 17 21:16:53 2011 +1100
     1.3 @@ -275,21 +275,23 @@ XenBus_Dpc(PVOID ServiceContext)
     1.4    WDF_WORKITEM_CONFIG workitem_config;
     1.5    WDF_OBJECT_ATTRIBUTES workitem_attributes;
     1.6    WDFWORKITEM workitem;
     1.7 +  ULONG rsp_prod;
     1.8  
     1.9    //FUNCTION_ENTER();
    1.10    
    1.11    KeAcquireSpinLockAtDpcLevel(&xpdd->xb_ring_spinlock);
    1.12  
    1.13 -  while (xpdd->xen_store_interface->rsp_prod != xpdd->xen_store_interface->rsp_cons)
    1.14 +  /* snapshot rsp_prod so it doesn't change while we are looking at it */
    1.15 +  while ((rsp_prod = xpdd->xen_store_interface->rsp_prod) != xpdd->xen_store_interface->rsp_cons)
    1.16    {
    1.17 +    KeMemoryBarrier(); /* make sure the data in the ring is valid */
    1.18      if (!xpdd->xb_msg)
    1.19      {
    1.20 -      if (xpdd->xen_store_interface->rsp_prod - xpdd->xen_store_interface->rsp_cons < sizeof(xsd_sockmsg_t))
    1.21 +      if (rsp_prod - xpdd->xen_store_interface->rsp_cons < sizeof(xsd_sockmsg_t))
    1.22        {
    1.23          //KdPrint((__DRIVER_NAME " +++ Message incomplete (not even a full header)\n"));
    1.24          break;
    1.25        }
    1.26 -      KeMemoryBarrier();
    1.27        memcpy_from_ring(xpdd->xen_store_interface->rsp, &msg,
    1.28          MASK_XENSTORE_IDX(xpdd->xen_store_interface->rsp_cons), sizeof(xsd_sockmsg_t));
    1.29        xpdd->xb_msg = ExAllocatePoolWithTag(NonPagedPool, sizeof(xsd_sockmsg_t) + msg.len, XENPCI_POOL_TAG);
    1.30 @@ -298,8 +300,7 @@ XenBus_Dpc(PVOID ServiceContext)
    1.31        xpdd->xen_store_interface->rsp_cons += sizeof(xsd_sockmsg_t);
    1.32      }
    1.33  
    1.34 -    msg_len = min(xpdd->xen_store_interface->rsp_prod - xpdd->xen_store_interface->rsp_cons, sizeof(xsd_sockmsg_t) + xpdd->xb_msg->len - xpdd->xb_msg_offset);
    1.35 -    KeMemoryBarrier(); /* make sure the data in the ring is valid */
    1.36 +    msg_len = min(rsp_prod - xpdd->xen_store_interface->rsp_cons, sizeof(xsd_sockmsg_t) + xpdd->xb_msg->len - xpdd->xb_msg_offset);
    1.37      ASSERT(xpdd->xb_msg_offset + msg_len <= sizeof(xsd_sockmsg_t) + xpdd->xb_msg->len);
    1.38      memcpy_from_ring(xpdd->xen_store_interface->rsp,
    1.39        (PUCHAR)xpdd->xb_msg + xpdd->xb_msg_offset,