// Execute a non-image region as a test _Use_decl_annotations_ void MmonExecuteDoggyRegion() { PAGED_CODE(); #pragma prefast(suppress : 30030, "Allocating executable POOL_TYPE memory") auto code = reinterpret_cast<UCHAR *>(ExAllocatePoolWithTag( NonPagedPoolExecute, PAGE_SIZE, kHyperPlatformCommonPoolTag)); if (!code) { return; } RtlZeroMemory(code, PAGE_SIZE); HYPERPLATFORM_LOG_DEBUG("PoolCode = %p, Pa = %016llx", code, UtilPaFromVa(code)); code[0] = 0x90; // nop code[1] = 0x90; // nop if (IsX64()) { code[2] = 0xc3; // ret } else { code[2] = 0xc2; code[3] = 0x04; // retn 4 } KeInvalidateAllCaches(); // Runs code on all processors at once auto function = reinterpret_cast<PKIPI_BROADCAST_WORKER>(code); KeIpiGenericCall(function, 0); ExFreePoolWithTag(code, kHyperPlatformCommonPoolTag); }
BOOLEAN KeAdjustInterruptTime ( IN LONGLONG TimeDelta ) /*++ Routine Description: This function moves the physical interrupt time of the system forward by the specified time delta after a system wake has occurred. Arguments: TimeDelta - Supplies the time delta to be added to the interrupt time, tick count and the performance counter in 100ns units. Return Value: None. --*/ { ADJUST_INTERRUPT_TIME_CONTEXT Adjust; // // Time can only be moved forward. // if (TimeDelta < 0) { return FALSE; } else { Adjust.KiNumber = KeNumberProcessors; Adjust.HalNumber = KeNumberProcessors; Adjust.Adjustment = (ULONGLONG) TimeDelta; Adjust.Barrier = 1; KeIpiGenericCall((PKIPI_BROADCAST_WORKER)KiCalibrateTimeAdjustment, (ULONG_PTR)(&Adjust)); return TRUE; } }
VOID NTAPI INIT_FUNCTION KiInitMachineDependent(VOID) { ULONG CpuCount; BOOLEAN FbCaching = FALSE; NTSTATUS Status; ULONG ReturnLength; ULONG i, Affinity, Sample = 0; PFX_SAVE_AREA FxSaveArea; ULONG MXCsrMask = 0xFFBF; ULONG Dummy; KI_SAMPLE_MAP Samples[4]; PKI_SAMPLE_MAP CurrentSample = Samples; /* Check for large page support */ if (KeFeatureBits & KF_LARGE_PAGE) { /* FIXME: Support this */ DPRINT("Large Page support detected but not yet taken advantage of\n"); } /* Check for global page support */ if (KeFeatureBits & KF_GLOBAL_PAGE) { /* Do an IPI to enable it on all CPUs */ CpuCount = KeNumberProcessors; KeIpiGenericCall(Ki386EnableGlobalPage, (ULONG_PTR)&CpuCount); } /* Check for PAT and/or MTRR support */ if (KeFeatureBits & (KF_PAT | KF_MTRR)) { /* Query the HAL to make sure we can use it */ Status = HalQuerySystemInformation(HalFrameBufferCachingInformation, sizeof(BOOLEAN), &FbCaching, &ReturnLength); if ((NT_SUCCESS(Status)) && (FbCaching)) { /* We can't, disable it */ KeFeatureBits &= ~(KF_PAT | KF_MTRR); } } /* Check for PAT support and enable it */ if (KeFeatureBits & KF_PAT) KiInitializePAT(); /* Assume no errata for now */ SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = 0; /* Check if we have an NPX */ if (KeI386NpxPresent) { /* Loop every CPU */ i = KeActiveProcessors; for (Affinity = 1; i; Affinity <<= 1) { /* Check if this is part of the set */ if (i & Affinity) { /* Run on this CPU */ i &= ~Affinity; KeSetSystemAffinityThread(Affinity); /* Detect FPU errata */ if (KiIsNpxErrataPresent()) { /* Disable NPX support */ KeI386NpxPresent = FALSE; SharedUserData-> ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE; break; } } } } /* If there's no NPX, then we're emulating the FPU */ SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = !KeI386NpxPresent; /* Check if there's no NPX, so that we can disable associated features */ if (!KeI386NpxPresent) { /* Remove NPX-related bits */ KeFeatureBits &= ~(KF_XMMI64 | KF_XMMI | KF_FXSR | KF_MMX); /* Disable kernel flags */ KeI386FxsrPresent = KeI386XMMIPresent = FALSE; /* Disable processor features that might've been set until now */ SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] = SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = 0; } /* Check for CR4 support */ if (KeFeatureBits & KF_CR4) { /* Do an IPI call to enable the Debug Exceptions */ CpuCount = KeNumberProcessors; KeIpiGenericCall(Ki386EnableDE, (ULONG_PTR)&CpuCount); } /* Check if FXSR was found */ if (KeFeatureBits & KF_FXSR) { /* Do an IPI call to enable the FXSR */ CpuCount = KeNumberProcessors; KeIpiGenericCall(Ki386EnableFxsr, (ULONG_PTR)&CpuCount); /* Check if XMM was found too */ if (KeFeatureBits & KF_XMMI) { /* Do an IPI call to enable XMMI exceptions */ CpuCount = KeNumberProcessors; KeIpiGenericCall(Ki386EnableXMMIExceptions, (ULONG_PTR)&CpuCount); /* FIXME: Implement and enable XMM Page Zeroing for Mm */ /* Patch the RtlPrefetchMemoryNonTemporal routine to enable it */ *(PCHAR)RtlPrefetchMemoryNonTemporal = 0x90; } } /* Check for, and enable SYSENTER support */ KiRestoreFastSyscallReturnState(); /* Loop every CPU */ i = KeActiveProcessors; for (Affinity = 1; i; Affinity <<= 1) { /* Check if this is part of the set */ if (i & Affinity) { /* Run on this CPU */ i &= ~Affinity; KeSetSystemAffinityThread(Affinity); /* Reset MHz to 0 for this CPU */ KeGetCurrentPrcb()->MHz = 0; /* Check if we can use RDTSC */ if (KeFeatureBits & KF_RDTSC) { /* Start sampling loop */ for (;;) { /* Do a dummy CPUID to start the sample */ CPUID(0, &Dummy, &Dummy, &Dummy, &Dummy); /* Fill out the starting data */ CurrentSample->PerfStart = KeQueryPerformanceCounter(NULL); CurrentSample->TSCStart = __rdtsc(); CurrentSample->PerfFreq.QuadPart = -50000; /* Sleep for this sample */ KeDelayExecutionThread(KernelMode, FALSE, &CurrentSample->PerfFreq); /* Do another dummy CPUID */ CPUID(0, &Dummy, &Dummy, &Dummy, &Dummy); /* Fill out the ending data */ CurrentSample->PerfEnd = KeQueryPerformanceCounter(&CurrentSample->PerfFreq); CurrentSample->TSCEnd = __rdtsc(); /* Calculate the differences */ CurrentSample->PerfDelta = CurrentSample->PerfEnd.QuadPart - CurrentSample->PerfStart.QuadPart; CurrentSample->TSCDelta = CurrentSample->TSCEnd - CurrentSample->TSCStart; /* Compute CPU Speed */ CurrentSample->MHz = (ULONG)((CurrentSample->TSCDelta * CurrentSample-> PerfFreq.QuadPart + 500000) / (CurrentSample->PerfDelta * 1000000)); /* Check if this isn't the first sample */ if (Sample) { /* Check if we got a good precision within 1MHz */ if ((CurrentSample->MHz == CurrentSample[-1].MHz) || (CurrentSample->MHz == CurrentSample[-1].MHz + 1) || (CurrentSample->MHz == CurrentSample[-1].MHz - 1)) { /* We did, stop sampling */ break; } } /* Move on */ CurrentSample++; Sample++; if (Sample == sizeof(Samples) / sizeof(Samples[0])) { /* Restart */ CurrentSample = Samples; Sample = 0; } } /* Save the CPU Speed */ KeGetCurrentPrcb()->MHz = CurrentSample[-1].MHz; } /* Check if we have MTRR */ if (KeFeatureBits & KF_MTRR) { /* Then manually initialize MTRR for the CPU */ KiInitializeMTRR(i ? FALSE : TRUE); } /* Check if we have AMD MTRR and initialize it for the CPU */ if (KeFeatureBits & KF_AMDK6MTRR) KiAmdK6InitializeMTRR(); /* Check if this is a buggy Pentium and apply the fixup if so */ if (KiI386PentiumLockErrataPresent) KiI386PentiumLockErrataFixup(); /* Check if the CPU supports FXSR */ if (KeFeatureBits & KF_FXSR) { /* Get the current thread NPX state */ FxSaveArea = KiGetThreadNpxArea(KeGetCurrentThread()); /* Clear initial MXCsr mask */ FxSaveArea->U.FxArea.MXCsrMask = 0; /* Save the current NPX State */ Ke386SaveFpuState(FxSaveArea); /* Check if the current mask doesn't match the reserved bits */ if (FxSaveArea->U.FxArea.MXCsrMask != 0) { /* Then use whatever it's holding */ MXCsrMask = FxSaveArea->U.FxArea.MXCsrMask; } /* Check if nobody set the kernel-wide mask */ if (!KiMXCsrMask) { /* Then use the one we calculated above */ KiMXCsrMask = MXCsrMask; } else { /* Was it set to the same value we found now? */ if (KiMXCsrMask != MXCsrMask) { /* No, something is definitely wrong */ KeBugCheckEx(MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED, KF_FXSR, KiMXCsrMask, MXCsrMask, 0); } } /* Now set the kernel mask */ KiMXCsrMask &= MXCsrMask; } } } /* Return affinity back to where it was */ KeRevertToUserAffinityThread(); /* NT allows limiting the duration of an ISR with a registry key */ if (KiTimeLimitIsrMicroseconds) { /* FIXME: TODO */ DPRINT1("ISR Time Limit not yet supported\n"); } /* Set CR0 features based on detected CPU */ KiSetCR0Bits(); }