win-pvdrivers

changeset 1059:6f69b45af0fb

Mask CPU with 0xff as high bits can contain info. Fix vlapic detection. Tidy up.
author James Harper <james.harper@bendigoit.com.au>
date Tue Oct 01 11:42:11 2013 +1000 (2013-10-01)
parents 8b6500e0ebfc
children b448f01b31e8
files xenpci/xenpci_patch_kernel.c
line diff
     1.1 --- a/xenpci/xenpci_patch_kernel.c	Mon Sep 30 19:46:16 2013 +1000
     1.2 +++ b/xenpci/xenpci_patch_kernel.c	Tue Oct 01 11:42:11 2013 +1000
     1.3 @@ -50,10 +50,8 @@ static ULONG tpr_cache[MAX_VIRT_CPUS];
     1.4  static ULONG patch_method;
     1.5  
     1.6  static ULONG
     1.7 -SaveTprProcValue(ULONG cpu, ULONG value)
     1.8 -{
     1.9 -  switch (patch_method)
    1.10 -  {
    1.11 +SaveTprProcValue(ULONG cpu, ULONG value) {
    1.12 +  switch (patch_method) {
    1.13    case PATCH_METHOD_LOCK_MOVE_CR0:
    1.14    case PATCH_METHOD_CACHED_TPR:
    1.15      tpr_cache[cpu] = value;
    1.16 @@ -66,13 +64,13 @@ SaveTprProcValue(ULONG cpu, ULONG value)
    1.17  }
    1.18  
    1.19  static ULONG
    1.20 -SaveTpr()
    1.21 -{
    1.22 -  switch (patch_method)
    1.23 -  {
    1.24 +SaveTpr() {
    1.25 +  ULONG cpu = KeGetCurrentProcessorNumber() & 0xff;
    1.26 +
    1.27 +  switch (patch_method) {
    1.28    case PATCH_METHOD_LOCK_MOVE_CR0:
    1.29    case PATCH_METHOD_CACHED_TPR:
    1.30 -    return SaveTprProcValue(KeGetCurrentProcessorNumber(), *(PULONG)LAPIC_TASKPRI);
    1.31 +    return SaveTprProcValue(cpu, *(PULONG)LAPIC_TASKPRI);
    1.32    case PATCH_METHOD_MAPPED_VLAPIC:
    1.33      /* no need to save here */
    1.34      break;
    1.35 @@ -82,16 +80,13 @@ SaveTpr()
    1.36  
    1.37  /* called with interrupts disabled (via CLI) from an arbitrary location inside HAL.DLL */
    1.38  static __inline LONG
    1.39 -ApicHighestVector(PULONG bitmap)
    1.40 -{
    1.41 +ApicHighestVector(PULONG bitmap) {
    1.42    int i;
    1.43    ULONG bit;
    1.44    ULONG value;
    1.45 -  for (i = 0; i < 8; i++)
    1.46 -  {
    1.47 +  for (i = 0; i < 8; i++) {
    1.48      value = bitmap[(7 - i) * 4];
    1.49 -    if (value)
    1.50 -    {
    1.51 +    if (value) {
    1.52        _BitScanReverse(&bit, value);
    1.53        return ((7 - i) << 5) | bit;
    1.54      }
    1.55 @@ -101,14 +96,12 @@ ApicHighestVector(PULONG bitmap)
    1.56  
    1.57  /* called with interrupts disabled (via CLI) from an arbitrary location inside HAL.DLL */
    1.58  VOID
    1.59 -WriteTpr(ULONG new_tpr_value)
    1.60 -{
    1.61 +WriteTpr(ULONG new_tpr_value) {
    1.62    LONG ISR;
    1.63    LONG IRR;
    1.64 -  ULONG cpu = KeGetCurrentProcessorNumber();
    1.65 +  ULONG cpu = KeGetCurrentProcessorNumber() & 0xff;
    1.66    
    1.67 -  switch (patch_method)
    1.68 -  {
    1.69 +  switch (patch_method) {
    1.70    case PATCH_METHOD_LOCK_MOVE_CR0:
    1.71      tpr_cache[cpu] = new_tpr_value;
    1.72      __asm {
    1.73 @@ -118,8 +111,7 @@ WriteTpr(ULONG new_tpr_value)
    1.74      }
    1.75      break;
    1.76    case PATCH_METHOD_CACHED_TPR:
    1.77 -    if (new_tpr_value != tpr_cache[cpu])
    1.78 -    {
    1.79 +    if (new_tpr_value != tpr_cache[cpu]) {
    1.80        *(PULONG)LAPIC_TASKPRI = new_tpr_value;
    1.81        tpr_cache[cpu] = new_tpr_value;
    1.82      }
    1.83 @@ -142,23 +134,22 @@ WriteTpr(ULONG new_tpr_value)
    1.84  
    1.85  /* called with interrupts disabled (via CLI) from an arbitrary location inside HAL.DLL */
    1.86  ULONG
    1.87 -ReadTpr()
    1.88 -{
    1.89 -  switch (patch_method)
    1.90 -  {
    1.91 +ReadTpr() {
    1.92 +  ULONG cpu = KeGetCurrentProcessorNumber() & 0xff;
    1.93 +
    1.94 +  switch (patch_method) {
    1.95    case PATCH_METHOD_LOCK_MOVE_CR0:
    1.96    case PATCH_METHOD_CACHED_TPR:
    1.97 -    return tpr_cache[KeGetCurrentProcessorNumber()];
    1.98 +    return tpr_cache[cpu];
    1.99    case PATCH_METHOD_MAPPED_VLAPIC:
   1.100 -    return *(PULONG)((PUCHAR)lapic[KeGetCurrentProcessorNumber()] + 0x80);
   1.101 +    return *(PULONG)((PUCHAR)lapic[cpu] + 0x80);
   1.102    default:
   1.103      return 0;
   1.104    }
   1.105  }
   1.106  
   1.107  static __inline VOID
   1.108 -InsertCallRel32(PUCHAR address, ULONG target)
   1.109 -{
   1.110 +InsertCallRel32(PUCHAR address, ULONG target) {
   1.111    *address = 0xE8; /* call near */
   1.112    *(PULONG)(address + 1) = (ULONG)target - ((ULONG)address + 5);
   1.113  }
   1.114 @@ -178,8 +169,7 @@ typedef struct {
   1.115  #define PATCH_2B5   3 /* 2 byte opcode with 1 + 4 bytes of data - replace with nop + nop + call function */
   1.116  #define PATCH_2B8   4 /* 2 byte opcode with 4 + 4 bytes of data - replace with push const + call function*/
   1.117  
   1.118 -static patch_t patches[] =
   1.119 -{
   1.120 +static patch_t patches[] = {
   1.121    { PATCH_1B4,  5, (ULONG)MoveTprToEax,   { 0xa1, TPR_BYTES } },
   1.122    { PATCH_2B4,  6, (ULONG)MoveTprToEcx,   { 0x8b, 0x0d, TPR_BYTES } },
   1.123    { PATCH_2B4,  6, (ULONG)MoveTprToEdx,   { 0x8b, 0x15, TPR_BYTES } },
   1.124 @@ -196,20 +186,17 @@ static patch_t patches[] =
   1.125  };
   1.126  
   1.127  static BOOLEAN
   1.128 -XenPci_TestAndPatchInstruction(PVOID address)
   1.129 -{
   1.130 +XenPci_TestAndPatchInstruction(PVOID address) {
   1.131    PUCHAR instruction = address;
   1.132    ULONG i;
   1.133    /* don't declare patches[] on the stack - windows gets grumpy if we allocate too much space on the stack at HIGH_LEVEL */
   1.134    
   1.135 -  for (i = 0; patches[i].patch_type != PATCH_NONE; i++)
   1.136 -  {
   1.137 +  for (i = 0; patches[i].patch_type != PATCH_NONE; i++) {
   1.138      if (memcmp(address, patches[i].bytes, patches[i].match_size) == 0)
   1.139        break;
   1.140    }
   1.141  
   1.142 -  switch (patches[i].patch_type)
   1.143 -  {
   1.144 +  switch (patches[i].patch_type) {
   1.145    case PATCH_1B4:
   1.146      InsertCallRel32(instruction + 0, patches[i].function);
   1.147      break;
   1.148 @@ -242,8 +229,7 @@ static PVOID patch_positions[256];
   1.149  static PVOID potential_patch_positions[256];
   1.150  
   1.151  static VOID
   1.152 -XenPci_DoPatchKernel0(PVOID context)
   1.153 -{
   1.154 +XenPci_DoPatchKernel0(PVOID context) {
   1.155    patch_info_t *pi = context;
   1.156    ULONG i;
   1.157    ULONG high_level_tpr;
   1.158 @@ -258,30 +244,25 @@ XenPci_DoPatchKernel0(PVOID context)
   1.159      SaveTprProcValue(i, high_level_tpr);
   1.160  
   1.161    /* we can't use KdPrint while patching as it may involve the TPR while we are patching it */
   1.162 -  for (i = 0; i < pi->length; i++)
   1.163 -  {
   1.164 -    if (XenPci_TestAndPatchInstruction((PUCHAR)pi->base + i))
   1.165 -    {
   1.166 +  for (i = 0; i < pi->length; i++) {
   1.167 +    if (XenPci_TestAndPatchInstruction((PUCHAR)pi->base + i)) {
   1.168        patch_positions[patch_position_index++] = (PUCHAR)pi->base + i;
   1.169 -    }
   1.170 -    else if (*(PULONG)((PUCHAR)pi->base + i) == LAPIC_TASKPRI)
   1.171 -    {
   1.172 +    } else if (*(PULONG)((PUCHAR)pi->base + i) == LAPIC_TASKPRI) {
   1.173        potential_patch_positions[potential_patch_position_index++] = (PUCHAR)pi->base + i;
   1.174      }
   1.175    }
   1.176  
   1.177    for (i = 0; i < patch_position_index; i++)
   1.178 -    KdPrint((__DRIVER_NAME "     Patch added at %p\n", patch_positions[i]));
   1.179 +    FUNCTION_MSG("Patch added at %p\n", patch_positions[i]);
   1.180  
   1.181    for (i = 0; i < potential_patch_position_index; i++)
   1.182 -    KdPrint((__DRIVER_NAME "     Unpatch TPR address found at %p\n", potential_patch_positions[i]));
   1.183 +    FUNCTION_MSG("Unpatch TPR address found at %p\n", potential_patch_positions[i]);
   1.184  
   1.185    FUNCTION_EXIT();
   1.186  }
   1.187  
   1.188  static VOID
   1.189 -XenPci_DoPatchKernelN(PVOID context)
   1.190 -{
   1.191 +XenPci_DoPatchKernelN(PVOID context) {
   1.192    UNREFERENCED_PARAMETER(context);
   1.193    
   1.194    FUNCTION_ENTER();
   1.195 @@ -290,8 +271,7 @@ XenPci_DoPatchKernelN(PVOID context)
   1.196  }
   1.197  
   1.198  static BOOLEAN
   1.199 -IsMoveCr8Supported()
   1.200 -{
   1.201 +IsMoveCr8Supported() {
   1.202    DWORD32 cpuid_output[4];
   1.203    
   1.204    __cpuid(cpuid_output, 0x80000001UL);
   1.205 @@ -302,8 +282,7 @@ IsMoveCr8Supported()
   1.206  }
   1.207  
   1.208  static ULONG
   1.209 -MapVlapic(PXENPCI_DEVICE_DATA xpdd)
   1.210 -{
   1.211 +MapVlapic(PXENPCI_DEVICE_DATA xpdd) {
   1.212    struct xen_add_to_physmap xatp;
   1.213    ULONG rc = EINVAL;
   1.214    ULONG ActiveProcessorCount;
   1.215 @@ -317,9 +296,8 @@ MapVlapic(PXENPCI_DEVICE_DATA xpdd)
   1.216    ActiveProcessorCount = (ULONG)*KeNumberProcessors;
   1.217  #endif
   1.218  
   1.219 -  for (i = 0; i < (int)ActiveProcessorCount; i++)
   1.220 -  {
   1.221 -    KdPrint((__DRIVER_NAME "     mapping lapic for cpu = %d\n", i));
   1.222 +  for (i = 0; i < (int)ActiveProcessorCount; i++) {
   1.223 +    FUNCTION_MSG("mapping lapic for cpu = %d\n", i);
   1.224  
   1.225      lapic_page[i] = XenPci_AllocMMIO(xpdd, PAGE_SIZE);
   1.226      lapic[i] = MmMapIoSpace(lapic_page[i], PAGE_SIZE, MmCached);
   1.227 @@ -328,11 +306,10 @@ MapVlapic(PXENPCI_DEVICE_DATA xpdd)
   1.228      xatp.idx = i;
   1.229      xatp.space = XENMAPSPACE_vlapic;
   1.230      xatp.gpfn = (xen_pfn_t)(lapic_page[i].QuadPart >> PAGE_SHIFT);
   1.231 -    KdPrint((__DRIVER_NAME "     gpfn = %x\n", xatp.gpfn));
   1.232 +    FUNCTION_MSG("gpfn = %x\n", xatp.gpfn);
   1.233      rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
   1.234 -    KdPrint((__DRIVER_NAME "     hypervisor memory op (XENMAPSPACE_vlapic_regs) ret = %d\n", rc));
   1.235 -    if (rc != 0)
   1.236 -    {
   1.237 +    FUNCTION_MSG("hypervisor memory op (XENMAPSPACE_vlapic_regs) ret = %d\n", rc);
   1.238 +    if (rc != 0) {
   1.239        FUNCTION_EXIT();
   1.240        return rc;
   1.241      }
   1.242 @@ -343,8 +320,7 @@ MapVlapic(PXENPCI_DEVICE_DATA xpdd)
   1.243  }
   1.244  
   1.245  VOID
   1.246 -XenPci_PatchKernel(PXENPCI_DEVICE_DATA xpdd, PVOID base, ULONG length)
   1.247 -{
   1.248 +XenPci_PatchKernel(PXENPCI_DEVICE_DATA xpdd, PVOID base, ULONG length) {
   1.249    patch_info_t patch_info;
   1.250    ULONG rc;
   1.251  #if (NTDDI_VERSION >= NTDDI_WINXP)
   1.252 @@ -358,46 +334,36 @@ XenPci_PatchKernel(PXENPCI_DEVICE_DATA x
   1.253    version_info.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
   1.254  
   1.255    RtlGetVersion((PRTL_OSVERSIONINFOW)&version_info);
   1.256 -  if (version_info.dwMajorVersion >= 6)
   1.257 -  {
   1.258 -    KdPrint((__DRIVER_NAME "     Vista or newer - no need for patch\n"));
   1.259 +  if (version_info.dwMajorVersion >= 6) {
   1.260 +    FUNCTION_MSG("Vista or newer - no need for patch\n");
   1.261      return;
   1.262    }
   1.263    if (version_info.dwMajorVersion == 5
   1.264 -      && version_info.dwMinorVersion > 2)
   1.265 -  {
   1.266 -    KdPrint((__DRIVER_NAME "     Windows 2003 sp2 or newer - no need for patch\n"));
   1.267 +      && version_info.dwMinorVersion > 2) {
   1.268 +    FUNCTION_MSG("Windows 2003 sp2 or newer - no need for patch\n");
   1.269      return;
   1.270    }
   1.271    if (version_info.dwMajorVersion == 5
   1.272        && version_info.dwMinorVersion == 2
   1.273 -      && version_info.wServicePackMajor >= 2)
   1.274 -  {
   1.275 -    KdPrint((__DRIVER_NAME "     Windows 2003 sp2 or newer - no need for patch\n"));
   1.276 +      && version_info.wServicePackMajor >= 2) {
   1.277 +    FUNCTION_MSG("Windows 2003 sp2 or newer - no need for patch\n");
   1.278      return;
   1.279    }
   1.280  #endif
   1.281 -  if (IsMoveCr8Supported())
   1.282 -  {
   1.283 -    KdPrint((__DRIVER_NAME "     Using LOCK MOVE CR0 TPR patch\n"));
   1.284 +  if (IsMoveCr8Supported()) {
   1.285 +    FUNCTION_MSG("Using LOCK MOVE CR0 TPR patch\n");
   1.286      patch_method = PATCH_METHOD_LOCK_MOVE_CR0;
   1.287 -  }
   1.288 -  else
   1.289 -  {
   1.290 +  } else {
   1.291      rc = MapVlapic(xpdd);
   1.292 -    if (rc == EACCES)
   1.293 -    {
   1.294 -      KdPrint((__DRIVER_NAME "     Xen already using VMX LAPIC acceleration. No patch required\n"));
   1.295 +    if (rc == -EACCES) {
   1.296 +      FUNCTION_MSG("Xen already using VMX LAPIC acceleration. No patch required\n");
   1.297        return;
   1.298      }
   1.299 -    if (!rc)
   1.300 -    {
   1.301 -      KdPrint((__DRIVER_NAME "     Using mapped vLAPIC TPR patch\n"));
   1.302 +    if (!rc) {
   1.303 +      FUNCTION_MSG("Using mapped vLAPIC TPR patch\n");
   1.304        patch_method = PATCH_METHOD_MAPPED_VLAPIC;
   1.305 -    }
   1.306 -    else
   1.307 -    {
   1.308 -      KdPrint((__DRIVER_NAME "     Using cached TPR patch\n"));
   1.309 +    } else {
   1.310 +      FUNCTION_MSG("Using cached TPR patch\n");
   1.311        patch_method = PATCH_METHOD_CACHED_TPR;
   1.312      }
   1.313    }
   1.314 @@ -414,8 +380,7 @@ XenPci_PatchKernel(PXENPCI_DEVICE_DATA x
   1.315  #else
   1.316  
   1.317  VOID
   1.318 -XenPci_PatchKernel(PXENPCI_DEVICE_DATA xpdd, PVOID base, ULONG length)
   1.319 -{
   1.320 +XenPci_PatchKernel(PXENPCI_DEVICE_DATA xpdd, PVOID base, ULONG length) {
   1.321    UNREFERENCED_PARAMETER(xpdd);
   1.322    UNREFERENCED_PARAMETER(base);
   1.323    UNREFERENCED_PARAMETER(length);