// __asm__ blocks are only checked for inline functions that end up being // emitted, so call functions with __asm__ blocks to make sure their inline // assembly parses. void f() { __movsb(0, 0, 0); __movsd(0, 0, 0); __movsw(0, 0, 0); __stosd(0, 0, 0); __stosw(0, 0, 0); #ifdef _M_X64 __movsq(0, 0, 0); __stosq(0, 0, 0); #endif int info[4]; __cpuid(info, 0); __cpuidex(info, 0, 0); _xgetbv(0); __halt(); __nop(); __readmsr(0); // FIXME: Call these in 64-bit too once the intrinsics have been fixed to // work there, PR19301 #ifndef _M_X64 __readcr3(); __writecr3(0); #endif #ifdef _M_ARM __dmb(_ARM_BARRIER_ISHST); #endif }
PSHV_GLOBAL_DATA ShvVpAllocateGlobalData ( VOID ) { PHYSICAL_ADDRESS lowest, highest; PSHV_GLOBAL_DATA data; ULONG cpuCount, size; // // The entire address range is OK for this allocation // lowest.QuadPart = 0; highest.QuadPart = lowest.QuadPart - 1; // // Query the number of logical processors, including those potentially in // groups other than 0. This allows us to support >64 processors. // cpuCount = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); // // Each processor will receive its own slice of per-virtual processor data. // size = FIELD_OFFSET(SHV_GLOBAL_DATA, VpData) + cpuCount * sizeof(SHV_VP_DATA); // // Allocate a contiguous chunk of RAM to back this allocation and make sure // that it is RW only, instead of RWX, by using the new Windows 8 API. // #if TARGETVERSION > 7 data = (PSHV_GLOBAL_DATA)MmAllocateContiguousNodeMemory(size, lowest, highest, lowest, PAGE_READWRITE, MM_ANY_NODE_OK); #else data = (PSHV_GLOBAL_DATA)MmAllocateContiguousMemory(size, highest); #endif // TARGETVERSION > 7 if (data != NULL) { // // Zero out the entire data region // __stosq((PULONGLONG)data, 0, size / sizeof(ULONGLONG)); } // // Return what is hopefully a valid pointer, otherwise NULL. // return data; }