win-pvdrivers

diff xenpci/xenpci.c @ 1022:cd72cd0e1c19

hooking debug doesn't survive hibernate under win8. Remove it.
Remove initial balloon down - doesn't work under xen 4.2 without xenbus being loaded
author James Harper <james.harper@bendigoit.com.au>
date Tue Feb 19 15:11:49 2013 +1100 (2013-02-19)
parents 9e076343bb8e
children 37c0c84a42e8
line diff
     1.1 --- a/xenpci/xenpci.c	Wed Feb 13 23:37:17 2013 +1100
     1.2 +++ b/xenpci/xenpci.c	Tue Feb 19 15:11:49 2013 +1100
     1.3 @@ -103,6 +103,7 @@ XenPci_EvtDeviceAdd_XenPci(WDFDRIVER dri
     1.4    WDFKEY param_key;
     1.5    DECLARE_CONST_UNICODE_STRING(veto_devices_name, L"veto_devices");
     1.6    WDF_DEVICE_POWER_CAPABILITIES power_capabilities;
     1.7 +  PPHYSICAL_MEMORY_RANGE pmr_head, pmr;
     1.8    int i;
     1.9    
    1.10    UNREFERENCED_PARAMETER(driver);
    1.11 @@ -138,8 +139,7 @@ XenPci_EvtDeviceAdd_XenPci(WDFDRIVER dri
    1.12    
    1.13    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&device_attributes, XENPCI_DEVICE_DATA);
    1.14    status = WdfDeviceCreate(&device_init, &device_attributes, &device);
    1.15 -  if (!NT_SUCCESS(status))
    1.16 -  {
    1.17 +  if (!NT_SUCCESS(status)) {
    1.18      KdPrint(("Error creating device %08x\n", status));
    1.19      return status;
    1.20    }
    1.21 @@ -148,26 +148,33 @@ XenPci_EvtDeviceAdd_XenPci(WDFDRIVER dri
    1.22    xpdd->wdf_device = device;
    1.23    xpdd->child_list = WdfFdoGetDefaultChildList(device);
    1.24  
    1.25 +  /* this is not a documented function */
    1.26 +  KeInitializeEvent(&xpdd->balloon_event, SynchronizationEvent, FALSE);
    1.27 +  pmr_head = MmGetPhysicalMemoryRanges();
    1.28 +  xpdd->current_memory_kb = 0;
    1.29 +  for (pmr = pmr_head; !(pmr->BaseAddress.QuadPart == 0 && pmr->NumberOfBytes.QuadPart == 0); pmr++) {
    1.30 +    xpdd->current_memory_kb += (ULONG)(pmr->NumberOfBytes.QuadPart / 1024);
    1.31 +  }
    1.32 +  FUNCTION_MSG("current_memory_kb = %d\n", xpdd->current_memory_kb);
    1.33 +  /* round to MB increments because that is what balloon deals in */
    1.34 +  xpdd->current_memory_kb = (xpdd->current_memory_kb + 0x1FF) & 0xFFFFFC00;
    1.35 +  FUNCTION_MSG("current_memory_kb rounded to %d\n", xpdd->current_memory_kb);
    1.36 +
    1.37    ExInitializeFastMutex(&xpdd->suspend_mutex);
    1.38    WdfCollectionCreate(WDF_NO_OBJECT_ATTRIBUTES, &veto_devices);
    1.39    status = WdfDriverOpenParametersRegistryKey(driver, KEY_QUERY_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &param_key);
    1.40 -  if (NT_SUCCESS(status))
    1.41 -  {
    1.42 +  if (NT_SUCCESS(status)) {
    1.43      status = WdfRegistryQueryMultiString(param_key, &veto_devices_name, WDF_NO_OBJECT_ATTRIBUTES, veto_devices);
    1.44 -    if (!NT_SUCCESS(status))
    1.45 -    {
    1.46 +    if (!NT_SUCCESS(status)) {
    1.47        KdPrint(("Error reading parameters/veto_devices value %08x\n", status));
    1.48      }
    1.49      WdfRegistryClose(param_key);
    1.50 -  }
    1.51 -  else
    1.52 -  {
    1.53 +  } else {
    1.54      KdPrint(("Error opening parameters key %08x\n", status));
    1.55    }
    1.56  
    1.57    InitializeListHead(&xpdd->veto_list);
    1.58 -  for (i = 0; i < (int)WdfCollectionGetCount(veto_devices); i++)
    1.59 -  {
    1.60 +  for (i = 0; i < (int)WdfCollectionGetCount(veto_devices); i++) {
    1.61      WDFOBJECT ws;
    1.62      UNICODE_STRING val;
    1.63      ANSI_STRING s;
    1.64 @@ -259,8 +266,7 @@ XenHide_EvtDevicePrepareHardware(WDFDEVI
    1.65  }
    1.66  
    1.67  static BOOLEAN
    1.68 -XenPci_IdSuffixMatches(PWDFDEVICE_INIT device_init, PWCHAR matching_id)
    1.69 -{
    1.70 +XenPci_IdSuffixMatches(PWDFDEVICE_INIT device_init, PWCHAR matching_id) {
    1.71    NTSTATUS status;
    1.72    WDFMEMORY memory;
    1.73    ULONG remaining;
    1.74 @@ -280,33 +286,25 @@ XenPci_IdSuffixMatches(PWDFDEVICE_INIT d
    1.75        continue;
    1.76      ids = WdfMemoryGetBuffer(memory, &ids_length);
    1.77  
    1.78 -    if (!NT_SUCCESS(status))
    1.79 -    {
    1.80 -//      KdPrint((__DRIVER_NAME "     i = %d, status = %x, ids_length = %d\n", i, status, ids_length));
    1.81 +    if (!NT_SUCCESS(status)) {
    1.82        continue;
    1.83      }
    1.84      
    1.85      remaining = (ULONG)ids_length / 2;
    1.86 -    for (ptr = ids; *ptr != 0; ptr += string_length + 1)
    1.87 -    {
    1.88 +    for (ptr = ids; *ptr != 0; ptr += string_length + 1) {
    1.89        RtlStringCchLengthW(ptr, remaining, &string_length);
    1.90        remaining -= (ULONG)string_length + 1;
    1.91 -      if (string_length >= wcslen(matching_id))
    1.92 -      {
    1.93 +      if (string_length >= wcslen(matching_id)) {
    1.94          ptr += string_length - wcslen(matching_id);
    1.95          string_length = wcslen(matching_id);
    1.96        }
    1.97 -//      KdPrint((__DRIVER_NAME "     Comparing '%S' and '%S'\n", ptr, matching_id));
    1.98 -      if (wcscmp(ptr, matching_id) == 0)
    1.99 -      {
   1.100 -        //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (Match)\n"));
   1.101 +      if (wcscmp(ptr, matching_id) == 0) {
   1.102          WdfObjectDelete(memory);
   1.103          return TRUE;
   1.104        }
   1.105      }
   1.106      WdfObjectDelete(memory);
   1.107    }
   1.108 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (No match)\n"));
   1.109    return FALSE;
   1.110  }
   1.111  
   1.112 @@ -395,8 +393,7 @@ ULONG tpr_patch_requested;
   1.113  extern PULONG InitSafeBootMode;
   1.114  
   1.115  VOID
   1.116 -XenPci_HideQemuDevices()
   1.117 -{
   1.118 +XenPci_HideQemuDevices() {
   1.119    #pragma warning(suppress:28138)
   1.120    WRITE_PORT_USHORT(XEN_IOPORT_DEVICE_MASK, (USHORT)qemu_hide_flags_value); //QEMU_UNPLUG_ALL_IDE_DISKS|QEMU_UNPLUG_ALL_NICS);
   1.121    KdPrint((__DRIVER_NAME "     Disabled qemu devices %02x\n", qemu_hide_flags_value));
   1.122 @@ -406,13 +403,11 @@ static BOOLEAN
   1.123  XenPci_CheckHideQemuDevices()
   1.124  {
   1.125    #pragma warning(suppress:28138)
   1.126 -  if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2)
   1.127 -  {
   1.128 +  if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2) {
   1.129      #pragma warning(suppress:28138)
   1.130      qemu_protocol_version = READ_PORT_UCHAR(XEN_IOPORT_VERSION);
   1.131      KdPrint((__DRIVER_NAME "     Version = %d\n", qemu_protocol_version));
   1.132 -    switch(qemu_protocol_version)
   1.133 -    {
   1.134 +    switch(qemu_protocol_version) {
   1.135      case 1:
   1.136        #pragma warning(suppress:28138)
   1.137        WRITE_PORT_USHORT(XEN_IOPORT_PRODUCT, XEN_PV_PRODUCT_NUMBER);
   1.138 @@ -562,126 +557,9 @@ XenPci_EvtDriverUnload(WDFDRIVER driver)
   1.139  {
   1.140    UNREFERENCED_PARAMETER(driver);
   1.141    
   1.142 -  #if DBG
   1.143 -  XenPci_UnHookDbgPrint();
   1.144 -  #endif  
   1.145 -}
   1.146 -
   1.147 -/* we need to balloon down very early on in the case of PoD, so things get a little messy */
   1.148 -static PMDL
   1.149 -XenPci_InitialBalloonDown()
   1.150 -{
   1.151 -  PVOID hypercall_stubs;
   1.152 -  domid_t domid = DOMID_SELF;
   1.153 -  ULONG maximum_reservation;
   1.154 -  ULONG current_reservation;
   1.155 -  ULONG extra_kb;
   1.156 -  ULONG ret;
   1.157 -  struct xen_memory_reservation reservation;
   1.158 -  xen_pfn_t *pfns;
   1.159 -  PMDL head = NULL;
   1.160 -  PMDL mdl;
   1.161 -  int i, j;
   1.162 -  ULONG curr_pfns_offset;
   1.163 -  PHYSICAL_ADDRESS alloc_low;
   1.164 -  PHYSICAL_ADDRESS alloc_high;
   1.165 -  PHYSICAL_ADDRESS alloc_skip;
   1.166 -
   1.167 -  FUNCTION_ENTER();
   1.168 -  
   1.169 -  hypercall_stubs = hvm_get_hypercall_stubs();
   1.170 -  if (!hypercall_stubs)
   1.171 -  {
   1.172 -    KdPrint((__DRIVER_NAME "     Failed to copy hypercall stubs. Maybe not running under Xen?\n"));
   1.173 -    FUNCTION_EXIT();
   1.174 -    return NULL;
   1.175 -  }
   1.176 -  if (xen_version_major < 4)
   1.177 -  {
   1.178 -    FUNCTION_MSG("No support for PoD. Cannot do initial balloon down.\n");
   1.179 -    FUNCTION_MSG("Expect a crash if maxmem is set much larger than memory.\n");
   1.180 -    FUNCTION_EXIT();
   1.181 -    return NULL;
   1.182 -  }
   1.183 -  ret = _HYPERVISOR_memory_op(hypercall_stubs, XENMEM_maximum_reservation, &domid);
   1.184 -  KdPrint((__DRIVER_NAME "     XENMEM_maximum_reservation = %d\n", ret));
   1.185 -  maximum_reservation = ret;
   1.186 -  ret = _HYPERVISOR_memory_op(hypercall_stubs, XENMEM_current_reservation, &domid);
   1.187 -  KdPrint((__DRIVER_NAME "     XENMEM_current_reservation = %d\n", ret));
   1.188 -  current_reservation = ret;
   1.189 -
   1.190 -  extra_kb = (maximum_reservation - current_reservation) << 2;
   1.191 -
   1.192 -  alloc_low.QuadPart = 0;
   1.193 -  alloc_high.QuadPart = 0xFFFFFFFFFFFFFFFFULL;
   1.194 -  alloc_skip.QuadPart = PAGE_SIZE;
   1.195 -
   1.196 -  KdPrint((__DRIVER_NAME "     Trying to give %d KB (%d MB) to Xen\n", extra_kb, extra_kb >> 10));
   1.197 -
   1.198 -  /* this code is mostly duplicated from the actual balloon thread... too hard to reuse */
   1.199 -  pfns = ExAllocatePoolWithTag(NonPagedPool, max(BALLOON_UNIT_PAGES, (64 << 8)) * sizeof(xen_pfn_t), XENPCI_POOL_TAG);
   1.200 -  if (!pfns) {
   1.201 -      /* If we can't balloon down then we are going to crash in strange ways later. Better to bug check now. */
   1.202 -      KdPrint((__DRIVER_NAME "     Initial Balloon Down failed - no memory for pfn list\n"));
   1.203 -      #pragma warning(suppress:28159)
   1.204 -      KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000003, 0x00000000, 0x00000000, 0x00000000);
   1.205 -  }
   1.206 -  curr_pfns_offset = 0;
   1.207 -  /* this makes sure we balloon up to the next multiple of BALLOON_UNITS_KB */
   1.208 -  for (j = 0; j < (int)extra_kb; j += BALLOON_UNITS_KB)
   1.209 -  {
   1.210 -    #if (NTDDI_VERSION >= NTDDI_WS03SP1)
   1.211 -    /* our contract says that we must zero pages before returning to xen, so we can't use MM_DONT_ZERO_ALLOCATION */
   1.212 -    mdl = MmAllocatePagesForMdlEx(alloc_low, alloc_high, alloc_skip, BALLOON_UNITS_KB * 1024, MmCached, 0);
   1.213 -    #else
   1.214 -    mdl = MmAllocatePagesForMdl(alloc_low, alloc_high, alloc_skip, BALLOON_UNITS_KB * 1024);
   1.215 -    #endif
   1.216 -    if (!mdl || MmGetMdlByteCount(mdl) != BALLOON_UNITS_KB * 1024)
   1.217 -    {
   1.218 -      /* this should actually never happen. If we can't allocate the memory it means windows is using it, and if it was using it we would have crashed already... */
   1.219 -      KdPrint((__DRIVER_NAME "     Initial Balloon Down failed\n"));
   1.220 -      #pragma warning(suppress:28159)
   1.221 -      KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000002, extra_kb, j, 0x00000000);
   1.222 -    }
   1.223 -    else
   1.224 -    {
   1.225 -      /* sizeof(xen_pfn_t) may not be the same as PPFN_NUMBER */
   1.226 -      for (i = 0; i < BALLOON_UNIT_PAGES; i++)
   1.227 -      {
   1.228 -        pfns[curr_pfns_offset] = (xen_pfn_t)(MmGetMdlPfnArray(mdl)[i]);
   1.229 -        curr_pfns_offset++;
   1.230 -      }
   1.231 -      if (curr_pfns_offset == (ULONG)max(BALLOON_UNIT_PAGES, (64 << 8)) || j + BALLOON_UNITS_KB > (int)extra_kb)
   1.232 -      {
   1.233 -        reservation.address_bits = 0;
   1.234 -        reservation.extent_order = 0;
   1.235 -        reservation.domid = DOMID_SELF;
   1.236 -        reservation.nr_extents = curr_pfns_offset;
   1.237 -        #pragma warning(disable: 4127) /* conditional expression is constant */
   1.238 -        set_xen_guest_handle(reservation.extent_start, pfns);
   1.239 -        ret = _HYPERVISOR_memory_op(hypercall_stubs, XENMEM_decrease_reservation, &reservation);
   1.240 -        if (ret != curr_pfns_offset)
   1.241 -          FUNCTION_MSG("only decreased %d of %d pages\n", ret, curr_pfns_offset);
   1.242 -        curr_pfns_offset = 0;
   1.243 -      }
   1.244 -      if (head)
   1.245 -      {
   1.246 -        mdl->Next = head;
   1.247 -        head = mdl;
   1.248 -      }
   1.249 -      else
   1.250 -      {
   1.251 -        head = mdl;
   1.252 -      }
   1.253 -    }
   1.254 -//KdPrint((__DRIVER_NAME "     C\n"));
   1.255 -  }
   1.256 -  ExFreePoolWithTag(pfns, XENPCI_POOL_TAG);
   1.257 -  hvm_free_hypercall_stubs(hypercall_stubs);
   1.258 -  
   1.259 -  FUNCTION_EXIT();
   1.260 -  
   1.261 -  return head;
   1.262 +//  #if DBG
   1.263 +//  XenPci_UnHookDbgPrint();
   1.264 +//  #endif  
   1.265  }
   1.266  
   1.267  #if (NTDDI_VERSION >= NTDDI_WS03SP1)  
   1.268 @@ -742,13 +620,6 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   1.269  
   1.270    FUNCTION_MSG(__DRIVER_NAME " " VER_FILEVERSION_STR "\n");
   1.271  
   1.272 -  #if DBG
   1.273 -  XenPci_HookDbgPrint();
   1.274 -  #endif
   1.275 -
   1.276 -  NT_ASSERT(!balloon_mdl_head);
   1.277 -  balloon_mdl_head = XenPci_InitialBalloonDown();
   1.278 -
   1.279  #if (NTDDI_VERSION >= NTDDI_WS03SP1)
   1.280    status = KeInitializeCrashDumpHeader(DUMP_TYPE_FULL, 0, NULL, 0, &dump_header_size);
   1.281    /* try and allocate contiguous memory as low as possible */
   1.282 @@ -756,7 +627,11 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   1.283    dump_header_mem_max.QuadPart = 0xFFFFF;
   1.284    while (!dump_header && dump_header_mem_max.QuadPart != 0xFFFFFFFFFFFFFFFF) {
   1.285      dump_header = MmAllocateContiguousMemory(DUMP_HEADER_PREFIX_SIZE + dump_header_size + DUMP_HEADER_SUFFIX_SIZE, dump_header_mem_max);
   1.286 -    dump_header_mem_max.QuadPart = (dump_header_mem_max.QuadPart << 8) | 0xF;
   1.287 +    if (dump_header) {
   1.288 +      FUNCTION_MSG("Allocated crash dump header < 0x%016I64x\n", dump_header_mem_max.QuadPart);
   1.289 +      break;
   1.290 +    }
   1.291 +    dump_header_mem_max.QuadPart = (dump_header_mem_max.QuadPart << 4) | 0xF;
   1.292    }
   1.293    if (dump_header) {
   1.294      status = KeInitializeCrashDumpHeader(DUMP_TYPE_FULL, 0, dump_header + DUMP_HEADER_PREFIX_SIZE, dump_header_size, &dump_header_size);
   1.295 @@ -779,28 +654,25 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   1.296    WDF_DRIVER_CONFIG_INIT(&config, XenPci_EvtDeviceAdd);
   1.297    config.EvtDriverUnload = XenPci_EvtDriverUnload;
   1.298    status = WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, &driver);
   1.299 -  if (!NT_SUCCESS(status))
   1.300 -  {
   1.301 +  if (!NT_SUCCESS(status)) {
   1.302      KdPrint((__DRIVER_NAME "     WdfDriverCreate failed with status 0x%x\n", status));
   1.303      FUNCTION_EXIT();
   1.304 -    #if DBG
   1.305 -    XenPci_UnHookDbgPrint();
   1.306 -    #endif
   1.307 +    //#if DBG
   1.308 +    //XenPci_UnHookDbgPrint();
   1.309 +    //#endif
   1.310      return status;
   1.311    }
   1.312    WDF_OBJECT_ATTRIBUTES_INIT(&parent_attributes);
   1.313    parent_attributes.ParentObject = driver;
   1.314    
   1.315    status = WdfDriverOpenParametersRegistryKey(driver, KEY_QUERY_VALUE, &parent_attributes, &param_key);
   1.316 -  if (!NT_SUCCESS(status))
   1.317 -  {
   1.318 +  if (!NT_SUCCESS(status)) {
   1.319      KdPrint(("Error opening parameters key %08x\n", status));
   1.320      goto error;
   1.321    }
   1.322  
   1.323    status = AuxKlibInitialize();
   1.324 -  if(!NT_SUCCESS(status))
   1.325 -  {
   1.326 +  if(!NT_SUCCESS(status)) {
   1.327      KdPrint((__DRIVER_NAME "     AuxKlibInitialize failed %08x\n", status));
   1.328      goto error;
   1.329    }
   1.330 @@ -809,8 +681,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   1.331  
   1.332    RtlInitUnicodeString(&system_start_options, L"failed to read");
   1.333    status = WdfRegistryOpenKey(NULL, &control_key_name, GENERIC_READ, &parent_attributes, &control_key);
   1.334 -  if (NT_SUCCESS(status))
   1.335 -  {
   1.336 +  if (NT_SUCCESS(status)) {
   1.337      status = WdfStringCreate(NULL, &parent_attributes, &wdf_system_start_options);
   1.338      status = WdfRegistryQueryString(control_key, &system_start_options_name, wdf_system_start_options);
   1.339      if (NT_SUCCESS(status))
   1.340 @@ -822,8 +693,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   1.341    
   1.342    always_patch = 0;
   1.343    WdfRegistryQueryULong(param_key, &txt_always_patch_name, &always_patch);
   1.344 -  if (always_patch || (system_start_options.Buffer && wcsstr(system_start_options.Buffer, L"PATCHTPR")))
   1.345 -  {
   1.346 +  if (always_patch || (system_start_options.Buffer && wcsstr(system_start_options.Buffer, L"PATCHTPR"))) {
   1.347      DECLARE_CONST_UNICODE_STRING(verifier_key_name, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\Memory Management");
   1.348      WDFKEY memory_key;
   1.349      ULONG verifier_value;
   1.350 @@ -879,9 +749,6 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   1.351    return STATUS_SUCCESS;
   1.352  
   1.353  error:
   1.354 -  #if DBG
   1.355 -  XenPci_UnHookDbgPrint();
   1.356 -  #endif
   1.357    KdPrint(("Failed, returning %08x\n", status));
   1.358    FUNCTION_EXIT();
   1.359    return status;