win-pvdrivers

changeset 987:d4d381253394

Fix a few possible problems in generating windows dumps from xen core dumps.
author James Harper <james.harper@bendigoit.com.au>
date Fri Sep 21 16:30:57 2012 +1000 (2012-09-21)
parents f6e14bb62400
children 246cb954e046
files xenpci/xenpci.c
line diff
     1.1 --- a/xenpci/xenpci.c	Fri Sep 21 12:18:17 2012 +1000
     1.2 +++ b/xenpci/xenpci.c	Fri Sep 21 16:30:57 2012 +1000
     1.3 @@ -38,6 +38,7 @@ static EVT_WDF_DEVICE_USAGE_NOTIFICATION
     1.4  static EVT_WDF_DEVICE_PREPARE_HARDWARE XenHide_EvtDevicePrepareHardware;
     1.5  
     1.6  #if (NTDDI_VERSION >= NTDDI_WS03SP1)
     1.7 +static KBUGCHECK_REASON_CALLBACK_ROUTINE XenPci_DebugHeaderDumpIoCallback;
     1.8  
     1.9  /* this is supposed to be defined in wdm.h, but isn't */
    1.10  NTSTATUS 
    1.11 @@ -692,9 +693,35 @@ XenPci_InitialBalloonDown()
    1.12    return head;
    1.13  }
    1.14  
    1.15 +#if (NTDDI_VERSION >= NTDDI_WS03SP1)  
    1.16  /* this isn't freed on shutdown... perhaps it should be */
    1.17 -PVOID dump_page;
    1.18 +static PUCHAR dump_header;
    1.19 +static ULONG dump_header_size;
    1.20 +static ULONG dump_header_refreshed_flag = FALSE;
    1.21 +static KBUGCHECK_REASON_CALLBACK_RECORD callback_record;
    1.22 +#define DUMP_HEADER_PREFIX_SIZE 8
    1.23 +#define DUMP_HEADER_SUFFIX_SIZE 8
    1.24  
    1.25 +/* call KeInitializeCrashDumpHeader once on crash */
    1.26 +static VOID
    1.27 +XenPci_DebugHeaderDumpIoCallback(
    1.28 +  KBUGCHECK_CALLBACK_REASON reason,
    1.29 +  PKBUGCHECK_REASON_CALLBACK_RECORD record,
    1.30 +  PVOID reason_specific_data,
    1.31 +  ULONG reason_specific_data_length) {
    1.32 +  UNREFERENCED_PARAMETER(reason);
    1.33 +  UNREFERENCED_PARAMETER(record);
    1.34 +  UNREFERENCED_PARAMETER(reason_specific_data);
    1.35 +  UNREFERENCED_PARAMETER(reason_specific_data_length);
    1.36 +  if (!dump_header_refreshed_flag) {
    1.37 +    NTSTATUS status;
    1.38 +    status = KeInitializeCrashDumpHeader(DUMP_TYPE_FULL, 0, dump_header + DUMP_HEADER_PREFIX_SIZE, dump_header_size, &dump_header_size);
    1.39 +    /* copy bug check code in? */
    1.40 +    dump_header_refreshed_flag = TRUE;
    1.41 +  }
    1.42 +}
    1.43 +#endif
    1.44 +  
    1.45  NTSTATUS
    1.46  DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
    1.47  {
    1.48 @@ -714,15 +741,13 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
    1.49    DECLARE_CONST_UNICODE_STRING(txt_always_patch_name, L"txt_patch_tpr_always");
    1.50    WDFSTRING wdf_system_start_options;
    1.51    UNICODE_STRING system_start_options;
    1.52 -#if (NTDDI_VERSION >= NTDDI_WS03SP1)  
    1.53 -  ULONG dump_header_size;
    1.54 -#endif
    1.55 +  PHYSICAL_ADDRESS dump_header_mem_max;
    1.56    
    1.57    UNREFERENCED_PARAMETER(RegistryPath);
    1.58  
    1.59    FUNCTION_ENTER();
    1.60  
    1.61 -  KdPrint((__DRIVER_NAME " " VER_FILEVERSION_STR "\n"));
    1.62 +  FUNCTION_MSG(__DRIVER_NAME " " VER_FILEVERSION_STR "\n");
    1.63  
    1.64    #if DBG
    1.65    XenPci_HookDbgPrint();
    1.66 @@ -733,9 +758,25 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
    1.67  
    1.68  #if (NTDDI_VERSION >= NTDDI_WS03SP1)
    1.69    status = KeInitializeCrashDumpHeader(DUMP_TYPE_FULL, 0, NULL, 0, &dump_header_size);
    1.70 -  dump_page = ExAllocatePoolWithTag(NonPagedPool, dump_header_size, XENPCI_POOL_TAG);
    1.71 -  status = KeInitializeCrashDumpHeader(DUMP_TYPE_FULL, 0, dump_page, dump_header_size, &dump_header_size);
    1.72 -  KdPrint((__DRIVER_NAME "     KeInitializeCrashDumpHeader status = %08x, size = %d\n", status, dump_header_size));
    1.73 +  /* try and allocate contiguous memory as low as possible */
    1.74 +  dump_header = NULL;
    1.75 +  dump_header_mem_max.QuadPart = 0xFFFFF;
    1.76 +  while (!dump_header && dump_header_mem_max.QuadPart != 0xFFFFFFFFFFFFFFFF) {
    1.77 +    dump_header = MmAllocateContiguousMemory(DUMP_HEADER_PREFIX_SIZE + dump_header_size + DUMP_HEADER_SUFFIX_SIZE, dump_header_mem_max);
    1.78 +    dump_header_mem_max.QuadPart = (dump_header_mem_max.QuadPart << 8) | 0xF;
    1.79 +  }
    1.80 +  if (dump_header) {
    1.81 +    status = KeInitializeCrashDumpHeader(DUMP_TYPE_FULL, 0, dump_header + DUMP_HEADER_PREFIX_SIZE, dump_header_size, &dump_header_size);
    1.82 +    FUNCTION_MSG("KeInitializeCrashDumpHeader status = %08x, size = %d\n", status, dump_header_size);
    1.83 +    memcpy(dump_header + 0, "XENXEN", 6); /* magic number */
    1.84 +    *(PUSHORT)(dump_header + 6) = (USHORT)(INT_PTR)dump_header & (PAGE_SIZE - 1); /* store offset too as additional verification */
    1.85 +    memcpy(dump_header + DUMP_HEADER_PREFIX_SIZE + dump_header_size, "XENXEN", 6);
    1.86 +    *(PUSHORT)(dump_header + DUMP_HEADER_PREFIX_SIZE + dump_header_size + 6) = (USHORT)(INT_PTR)dump_header & (PAGE_SIZE - 1); /* store offset too as additional verification */
    1.87 +    KeInitializeCallbackRecord(&callback_record);
    1.88 +    KeRegisterBugCheckReasonCallback(&callback_record, XenPci_DebugHeaderDumpIoCallback, KbCallbackDumpIo, (PUCHAR)"XenPci_DebugHeaderDumpIoCallback");
    1.89 +  } else {
    1.90 +    FUNCTION_MSG("Failed to allocate memory for crash dump header\n");
    1.91 +  }
    1.92  #endif
    1.93  
    1.94    /* again after enabling DbgPrint hooking */