win-pvdrivers

changeset 176:09f1c620ba55

Added locking on the grant table code to prevent major badness on SMP systems.
author James Harper <james.harper@bendigoit.com.au>
date Wed Feb 06 12:28:10 2008 +1100 (2008-02-06)
parents c8d4df1e1d12
children 8d778a60aa2c
files common.inc xenhide/xenhide.c xenpci/gnttbl.c xenpci/xenpci.h xenvbd/xenvbd.c
line diff
     1.1 --- a/common.inc	Tue Feb 05 22:53:41 2008 +1100
     1.2 +++ b/common.inc	Wed Feb 06 12:28:10 2008 +1100
     1.3 @@ -1,4 +1,4 @@
     1.4 -VERSION=0.7.0.0
     1.5 +VERSION=0.7.0.5
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7  KMDF_VERSION=1
     1.8  !IF $(_NT_TOOLS_VERSION) > 0x700
     2.1 --- a/xenhide/xenhide.c	Tue Feb 05 22:53:41 2008 +1100
     2.2 +++ b/xenhide/xenhide.c	Wed Feb 06 12:28:10 2008 +1100
     2.3 @@ -221,7 +221,7 @@ XenHide_StringMatches(PWCHAR String1, PW
     2.4  static NTSTATUS
     2.5  XenHide_IoCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
     2.6  {
     2.7 -  ULONG i;
     2.8 +  ULONG i, j;
     2.9    PDEVICE_RELATIONS Relations;
    2.10    WCHAR Buffer[1000];
    2.11    PWCHAR Ptr;
    2.12 @@ -243,38 +243,32 @@ XenHide_IoCompletion(PDEVICE_OBJECT Devi
    2.13      if (Offset != 0)
    2.14        Relations->Objects[i - Offset] = Relations->Objects[i];
    2.15  
    2.16 -//    Length = sizeof(Buffer);
    2.17 -//    IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyDeviceDescription, Length, Buffer, &Length);
    2.18 -//    KdPrint((__DRIVER_NAME "     %3d - %ws\n", i, Buffer));
    2.19 -
    2.20 -//    Length = sizeof(Buffer);
    2.21 -//    IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyPhysicalDeviceObjectName, Length, Buffer, &Length);
    2.22 -//    KdPrint((__DRIVER_NAME "     %3d - %ws\n", i, Buffer));
    2.23 -
    2.24 -    Length = sizeof(Buffer);
    2.25 -    IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyCompatibleIDs, Length, Buffer, &Length);
    2.26      Match = 0;
    2.27 -    StrLen = 0;
    2.28 -    for (Ptr = Buffer; *Ptr != 0; Ptr += StrLen + 1)
    2.29 +    for (j = 0; j < 2 && !Match; j++)
    2.30      {
    2.31 -//      KdPrint((__DRIVER_NAME "         - %ws\n", Ptr));
    2.32 -      // Qemu PCI
    2.33 -//      if (XenHide_StringMatches(Ptr, L"PCI\\VEN_8086&DEV_7010&SUBSYS_00015853")) {
    2.34 -      if (XenHide_StringMatches(Ptr, L"PCI\\VEN_8086&DEV_7010")) {
    2.35 -        Match = 1;
    2.36 -        break;
    2.37 +      Length = sizeof(Buffer);
    2.38 +      if (j == 0)
    2.39 +        IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyCompatibleIDs, Length, Buffer, &Length);
    2.40 +      else
    2.41 +        IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyCompatibleIDs, Length, Buffer, &Length);
    2.42 +      StrLen = 0;
    2.43 +      for (Ptr = Buffer; *Ptr != 0; Ptr += StrLen + 1)
    2.44 +      {
    2.45 +        // Qemu PCI
    2.46 +        if (XenHide_StringMatches(Ptr, L"PCI\\VEN_8086&DEV_7010")) {
    2.47 +          Match = 1;
    2.48 +          break;
    2.49 +        }
    2.50 +        // Qemu Network
    2.51 +        if (XenHide_StringMatches(Ptr, L"PCI\\VEN_10EC&DEV_8139")) {
    2.52 +          Match = 1;
    2.53 +          break;
    2.54 +        }
    2.55 +        RtlStringCchLengthW(Ptr, Length, &StrLen);
    2.56        }
    2.57 -      // Qemu Network
    2.58 -//      if (XenHide_StringMatches(Ptr, L"PCI\\VEN_10EC&DEV_8139&SUBSYS_00015853")) {
    2.59 -      if (XenHide_StringMatches(Ptr, L"PCI\\VEN_10EC&DEV_8139")) {
    2.60 -        Match = 1;
    2.61 -        break;
    2.62 -      }
    2.63 -      RtlStringCchLengthW(Ptr, Length, &StrLen);
    2.64      }
    2.65      if (Match)
    2.66      {
    2.67 -//      KdPrint((__DRIVER_NAME "           (Match)\n"));
    2.68        Offset++;
    2.69      }
    2.70    }
     3.1 --- a/xenpci/gnttbl.c	Tue Feb 05 22:53:41 2008 +1100
     3.2 +++ b/xenpci/gnttbl.c	Wed Feb 06 12:28:10 2008 +1100
     3.3 @@ -23,18 +23,26 @@ static void
     3.4  put_free_entry(WDFDEVICE Device, grant_ref_t ref)
     3.5  {
     3.6    PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
     3.7 +  KIRQL OldIrql;
     3.8  
     3.9 +  KeAcquireSpinLock(&xpdd->grant_lock, &OldIrql);
    3.10    xpdd->gnttab_list[ref] = xpdd->gnttab_list[0];
    3.11    xpdd->gnttab_list[0]  = ref;
    3.12 +  KeReleaseSpinLock(&xpdd->grant_lock, OldIrql);
    3.13  }
    3.14  
    3.15  static grant_ref_t
    3.16  get_free_entry(WDFDEVICE Device)
    3.17  {
    3.18    PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
    3.19 -  unsigned int ref = xpdd->gnttab_list[0];
    3.20 +  unsigned int ref;
    3.21 +  KIRQL OldIrql;
    3.22  
    3.23 +  KeAcquireSpinLock(&xpdd->grant_lock, &OldIrql);
    3.24 +  ref = xpdd->gnttab_list[0];
    3.25    xpdd->gnttab_list[0] = xpdd->gnttab_list[ref];
    3.26 +  KeReleaseSpinLock(&xpdd->grant_lock, OldIrql);
    3.27 +
    3.28    return ref;
    3.29  }
    3.30  
    3.31 @@ -71,6 +79,9 @@ GntTbl_Init(WDFDEVICE Device)
    3.32  
    3.33    //KdPrint((__DRIVER_NAME " --> GntTbl_Init\n"));
    3.34  
    3.35 +  
    3.36 +  KeInitializeSpinLock(&xpdd->grant_lock);
    3.37 +
    3.38    for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
    3.39      put_free_entry(Device, i);
    3.40  
    3.41 @@ -102,7 +113,6 @@ GntTbl_GrantAccess(
    3.42  
    3.43    //KdPrint((__DRIVER_NAME "     Granting access to frame %08x\n", frame));
    3.44  
    3.45 -  /* TODO: locking? */
    3.46    ref = get_free_entry(Device);
    3.47    xpdd->gnttab_table[ref].frame = frame;
    3.48    xpdd->gnttab_table[ref].domid = domid;
    3.49 @@ -134,8 +144,6 @@ GntTbl_EndAccess(
    3.50      }
    3.51    } while ((nflags = InterlockedCompareExchange16(
    3.52      (volatile SHORT *)&xpdd->gnttab_table[ref].flags, 0, flags)) != flags);
    3.53 -//  } while ((nflags = InterlockedCompareExchange16(
    3.54 -//    (volatile SHORT *)&xpdd->gnttab_table[ref].flags, flags, 0)) != flags);
    3.55  
    3.56    put_free_entry(Device, ref);
    3.57    //KdPrint((__DRIVER_NAME " <-- GntTbl_EndAccess\n"));
     4.1 --- a/xenpci/xenpci.h	Tue Feb 05 22:53:41 2008 +1100
     4.2 +++ b/xenpci/xenpci.h	Wed Feb 06 12:28:10 2008 +1100
     4.3 @@ -141,6 +141,7 @@ typedef struct {
     4.4    XENBUS_WATCH_ENTRY XenBus_WatchEntries[MAX_WATCH_ENTRIES];
     4.5  
     4.6    KSPIN_LOCK WatchLock;
     4.7 +  KSPIN_LOCK grant_lock;
     4.8  } XENPCI_DEVICE_DATA, *PXENPCI_DEVICE_DATA;
     4.9  
    4.10  WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_DATA, GetDeviceData);
     5.1 --- a/xenvbd/xenvbd.c	Tue Feb 05 22:53:41 2008 +1100
     5.2 +++ b/xenvbd/xenvbd.c	Wed Feb 06 12:28:10 2008 +1100
     5.3 @@ -13,7 +13,7 @@
     5.4  #define wmb() KeMemoryBarrier()
     5.5  #define mb() KeMemoryBarrier()
     5.6  
     5.7 -#define BUF_PAGES_PER_SRB 11
     5.8 +//#define BUF_PAGES_PER_SRB 11
     5.9  
    5.10  DRIVER_INITIALIZE DriverEntry;
    5.11  
    5.12 @@ -190,10 +190,12 @@ XenVbd_HwScsiInterruptTarget(PVOID Devic
    5.13            KdPrint((__DRIVER_NAME "     Sector = %08X, Count = %d\n", TargetData->shadow[rep->id].req.sector_number, BlockCount));
    5.14            Srb->SrbStatus = SRB_STATUS_ERROR;
    5.15          }
    5.16 +/*
    5.17          for (j = 0; j < TargetData->shadow[rep->id].req.nr_segments; j++)
    5.18            DeviceData->XenDeviceData->XenInterface.GntTbl_EndAccess(
    5.19              DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
    5.20              TargetData->shadow[rep->id].req.seg[j].gref);
    5.21 +*/
    5.22          if (Srb->Cdb[0] == SCSIOP_READ)
    5.23            memcpy(Srb->DataBuffer, TargetData->shadow[rep->id].Buf, BlockCount * TargetData->BytesPerSector);
    5.24    
    5.25 @@ -258,7 +260,7 @@ XenVbd_BackEndStateHandler(char *Path, P
    5.26    grant_ref_t ref;
    5.27    blkif_sring_t *SharedRing;
    5.28    ULONG PFN;
    5.29 -  ULONG i;
    5.30 +  ULONG i, j;
    5.31    blkif_request_t *req;
    5.32    int notify;
    5.33  
    5.34 @@ -308,8 +310,15 @@ XenVbd_BackEndStateHandler(char *Path, P
    5.35      for (i = 0; i < max(BLK_RING_SIZE, BLK_OTHER_RING_SIZE); i++)
    5.36      {
    5.37        TargetData->shadow[i].req.id = i + 1;
    5.38 -      TargetData->shadow[i].Mdl = AllocatePages(BUF_PAGES_PER_SRB); // stupid that we have to do this!
    5.39 +      TargetData->shadow[i].Mdl = AllocatePages(BLKIF_MAX_SEGMENTS_PER_REQUEST); // stupid that we have to do this!
    5.40        TargetData->shadow[i].Buf = MmGetMdlVirtualAddress(TargetData->shadow[i].Mdl);
    5.41 +      for (j = 0; j < BLKIF_MAX_SEGMENTS_PER_REQUEST; j++)
    5.42 +      {
    5.43 +        TargetData->shadow[i].req.seg[j].gref = DeviceData->XenDeviceData->XenInterface.GntTbl_GrantAccess(
    5.44 +          DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
    5.45 +          0, (ULONG)MmGetMdlPfnArray(TargetData->shadow[i].Mdl)[j], FALSE);
    5.46 +        ASSERT((signed short)TargetData->shadow[i].req.seg[j].gref >= 0);
    5.47 +      }
    5.48      }
    5.49      TargetData->shadow_free = 0;
    5.50  
    5.51 @@ -643,8 +652,8 @@ XenVbd_HwScsiFindAdapter(PVOID DeviceExt
    5.52  #if defined(__x86_64__)
    5.53    ConfigInfo->Master = TRUE; // Won't work under x64 without this...
    5.54  #endif
    5.55 -  ConfigInfo->MaximumTransferLength = BUF_PAGES_PER_SRB * PAGE_SIZE;
    5.56 -  ConfigInfo->NumberOfPhysicalBreaks = BUF_PAGES_PER_SRB - 1;
    5.57 +  ConfigInfo->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
    5.58 +  ConfigInfo->NumberOfPhysicalBreaks = BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
    5.59    ConfigInfo->ScatterGather = TRUE;
    5.60    ConfigInfo->AlignmentMask = 0;
    5.61    ConfigInfo->NumberOfBuses = SCSI_BUSES;
    5.62 @@ -857,10 +866,12 @@ XenVbd_PutSrbOnRing(PXENVBD_TARGET_DATA 
    5.63  
    5.64    for (i = 0; i < shadow->req.nr_segments; i++)
    5.65    {
    5.66 +/*
    5.67      shadow->req.seg[i].gref = DeviceData->XenDeviceData->XenInterface.GntTbl_GrantAccess(
    5.68        DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
    5.69        0, (ULONG)MmGetMdlPfnArray(TargetData->shadow[shadow->req.id].Mdl)[i], FALSE);
    5.70      ASSERT((signed short)shadow->req.seg[i].gref >= 0);
    5.71 +*/
    5.72      shadow->req.seg[i].first_sect = 0;
    5.73      if (i == shadow->req.nr_segments - 1)
    5.74        shadow->req.seg[i].last_sect = (UINT8)((BlockCount - 1) % (PAGE_SIZE / TargetData->BytesPerSector));