- Move NtFlushInstructionCache from sysinfo.c to virtual.c where it fits better. Likewise, move it from kefuncs to mmfuncs in NDK, and fix function arguments (ULONG -> SIZE_T).
- Re-enable TRAP_DEBUG, adding back critical checks in the trap code. Checks can be improved but it is better than potentially silently messing up system state.
- Move remaining RtlPrefetchMemoryNonTemporal code into kernel. Stubbed for non-x86.
- By Hermes suggestion, override ASSERT to NT_ASSERT only for MSVC builds as that is where the main benefit is.
svn path=/trunk/; revision=68907
WINAPI
FlushInstructionCache(IN HANDLE hProcess,
IN LPCVOID lpBaseAddress,
- IN SIZE_T dwSize)
+ IN SIZE_T nSize)
{
NTSTATUS Status;
/* Call the native function */
- Status = NtFlushInstructionCache(hProcess, (PVOID)lpBaseAddress, dwSize);
+ Status = NtFlushInstructionCache(hProcess, (PVOID)lpBaseAddress, nSize);
if (!NT_SUCCESS(Status))
{
/* Handle failure case */
_In_ LARGE_INTEGER *Interval
);
-NTSYSCALLAPI
-NTSTATUS
-NTAPI
-NtFlushInstructionCache(
- _In_ HANDLE ProcessHandle,
- _In_ PVOID BaseAddress,
- _In_ ULONG NumberOfBytesToFlush
-);
-
ULONG
NTAPI
NtGetCurrentProcessorNumber(
_In_ PLARGE_INTEGER NewMaximumSize
);
+NTSYSCALLAPI
+NTSTATUS
+NTAPI
+NtFlushInstructionCache(
+ _In_ HANDLE ProcessHandle,
+ _In_ PVOID BaseAddress,
+ _In_ SIZE_T NumberOfBytesToFlush
+);
+
NTSYSCALLAPI
NTSTATUS
NTAPI
memmove(Destination, Source, Length);
}
-
-/*
-* @implemented
-*/
-VOID
-FASTCALL
-RtlPrefetchMemoryNonTemporal(IN PVOID Source,
- IN SIZE_T Length)
-{
- /* By nature of prefetch, this is non-portable. */
- (void)Source;
- (void)Length;
-}
-
-
#undef RtlZeroMemory
/*
* @implemented
mr 5,4
xor 4,4,4
b memset
-
-RtlPrefetchMemoryNonTemporal:
- blr
return Status;
}
-NTSTATUS
-NTAPI
-NtFlushInstructionCache(
- _In_ HANDLE ProcessHandle,
- _In_opt_ PVOID BaseAddress,
- _In_ ULONG FlushSize)
-{
- KAPC_STATE ApcState;
- PKPROCESS Process;
- NTSTATUS Status;
- PAGED_CODE();
-
- /* Is a base address given? */
- if (BaseAddress != NULL)
- {
- /* If the requested size is 0, there is nothing to do */
- if (FlushSize == 0)
- {
- return STATUS_SUCCESS;
- }
-
- /* Is this a user mode call? */
- if (KeGetPreviousMode() != KernelMode)
- {
- /* Make sure the base address is in user space */
- if (BaseAddress > MmHighestUserAddress)
- {
- DPRINT1("Invalid BaseAddress 0x%p\n", BaseAddress);
- return STATUS_ACCESS_VIOLATION;
- }
- }
- }
-
- /* Is another process requested? */
- if (ProcessHandle != NtCurrentProcess())
- {
- /* Reference the process */
- Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_VM_WRITE,
- PsProcessType,
- KeGetPreviousMode(),
- (PVOID*)&Process,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to reference the process %p\n", ProcessHandle);
- return Status;
- }
-
- /* Attach to the process */
- KeStackAttachProcess(Process, &ApcState);
- }
-
- /* FIXME: don't flush everything if a range is requested */
-#if defined(_M_IX86) || defined(_M_AMD64)
- __wbinvd();
-#elif defined(_M_PPC)
- __asm__ __volatile__("tlbsync");
-#elif defined(_M_MIPS)
- DPRINT1("NtFlushInstructionCache() is not implemented\n");
- DbgBreakPoint();
-#elif defined(_M_ARM)
- _MoveToCoprocessor(0, CP15_ICIALLU);
-#else
-#error Unknown architecture
-#endif
-
- /* Check if we attached */
- if (ProcessHandle != NtCurrentProcess())
- {
- /* Detach from the process */
- KeUnstackDetachProcess(&ApcState);
- ObDereferenceObject(Process);
- }
-
- return STATUS_SUCCESS;
-}
-
ULONG
NTAPI
NtGetCurrentProcessorNumber(VOID)
{
- /* Just return the CPU */
+ /* Just use Ke */
return KeGetCurrentProcessorNumber();
}
-/*
- * @implemented
- */
#undef ExGetPreviousMode
KPROCESSOR_MODE
NTAPI
-ExGetPreviousMode (VOID)
+ExGetPreviousMode(VOID)
{
+ /* Just use Ke */
return KeGetPreviousMode();
}
__writecr3(__readcr3());
}
+FORCEINLINE
+VOID
+KeSweepICache(IN PVOID BaseAddress,
+ IN SIZE_T FlushSize)
+{
+ //
+ // Always sweep the whole cache
+ //
+ UNREFERENCED_PARAMETER(BaseAddress);
+ UNREFERENCED_PARAMETER(FlushSize);
+ __wbinvd();
+}
+
FORCEINLINE
VOID
KiRundownThread(IN PKTHREAD Thread)
KeArmFlushTlb();
}
+FORCEINLINE
+VOID
+KeSweepICache(IN PVOID BaseAddress,
+ IN SIZE_T FlushSize)
+{
+ //
+ // Always sweep the whole cache
+ //
+ UNREFERENCED_PARAMETER(BaseAddress);
+ UNREFERENCED_PARAMETER(FlushSize);
+ _MoveToCoprocessor(0, CP15_ICIALLU);
+}
+
FORCEINLINE
VOID
KiRundownThread(IN PKTHREAD Thread)
__writecr3(__readcr3());
}
+FORCEINLINE
+VOID
+KeSweepICache(IN PVOID BaseAddress,
+ IN SIZE_T FlushSize)
+{
+ //
+ // Always sweep the whole cache
+ //
+ UNREFERENCED_PARAMETER(BaseAddress);
+ UNREFERENCED_PARAMETER(FlushSize);
+ __wbinvd();
+}
+
FORCEINLINE
PRKTHREAD
KeGetCurrentThread(VOID)
#pragma once
-#define TRAP_DEBUG 0
-
#define UNREACHABLE __assume(0)
#if _MSC_VER
DbgPrint("V86Gs: %x\n", TrapFrame->V86Gs);
}
-#if TRAP_DEBUG
-VOID
+#if DBG
FORCEINLINE
+VOID
KiFillTrapFrameDebug(IN PKTRAP_FRAME TrapFrame)
{
/* Set the debug information */
__asm__("sync\n\tisync\n\t");
}
+FORCEINLINE
+VOID
+KeSweepICache(IN PVOID BaseAddress,
+ IN SIZE_T FlushSize)
+{
+ //
+ // Always sweep the whole cache
+ //
+ UNREFERENCED_PARAMETER(BaseAddress);
+ UNREFERENCED_PARAMETER(FlushSize);
+ __asm__ __volatile__("tlbsync");
+}
+
FORCEINLINE
PRKTHREAD
KeGetCurrentThread(VOID)
//
// NT_ASSERT Best Assert
//
+#if defined(_MSC_VER)
#undef ASSERT
#define ASSERT NT_ASSERT
+#endif
/* Internal Headers */
#include "internal/ntoskrnl.h"
RemainingLength = RemainingLength - CopyChunk;
}
+ /*
+ * We may have modified executable code, flush the instruction cache
+ */
+ KeSweepICache((PVOID)Address, TotalSize);
+
/*
* Return the size we managed to copy
* and return success if we could copy the whole range
PKDBG_PRESERVICEHOOK KeWin32PreServiceHook = NULL;
PKDBG_POSTSERVICEHOOK KeWin32PostServiceHook = NULL;
#endif
-#if TRAP_DEBUG
+#if DBG
BOOLEAN StopChecking = FALSE;
#endif
return Status;
}
+NTSTATUS
+NTAPI
+NtFlushInstructionCache(_In_ HANDLE ProcessHandle,
+ _In_opt_ PVOID BaseAddress,
+ _In_ SIZE_T FlushSize)
+{
+ KAPC_STATE ApcState;
+ PKPROCESS Process;
+ NTSTATUS Status;
+ PAGED_CODE();
+
+ /* Is a base address given? */
+ if (BaseAddress != NULL)
+ {
+ /* If the requested size is 0, there is nothing to do */
+ if (FlushSize == 0)
+ {
+ return STATUS_SUCCESS;
+ }
+
+ /* Is this a user mode call? */
+ if (ExGetPreviousMode() != KernelMode)
+ {
+ /* Make sure the base address is in user space */
+ if (BaseAddress > MmHighestUserAddress)
+ {
+ DPRINT1("Invalid BaseAddress 0x%p\n", BaseAddress);
+ return STATUS_ACCESS_VIOLATION;
+ }
+ }
+ }
+
+ /* Is another process requested? */
+ if (ProcessHandle != NtCurrentProcess())
+ {
+ /* Reference the process */
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_VM_WRITE,
+ PsProcessType,
+ ExGetPreviousMode(),
+ (PVOID*)&Process,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to reference the process %p\n", ProcessHandle);
+ return Status;
+ }
+
+ /* Attach to the process */
+ KeStackAttachProcess(Process, &ApcState);
+ }
+
+ /* Forward to Ke */
+ KeSweepICache(BaseAddress, FlushSize);
+
+ /* Check if we attached */
+ if (ProcessHandle != NtCurrentProcess())
+ {
+ /* Detach from the process and dereference it */
+ KeUnstackDetachProcess(&ApcState);
+ ObDereferenceObject(Process);
+ }
+
+ /* All done, return to caller */
+ return STATUS_SUCCESS;
+}
+
NTSTATUS
NTAPI
NtProtectVirtualMemory(IN HANDLE ProcessHandle,
return STATUS_SUCCESS;
}
+#if !defined(_M_IX86)
+//
+// Stub for architectures which don't have this implemented
+//
+VOID
+FASTCALL
+RtlPrefetchMemoryNonTemporal(IN PVOID Source,
+ IN SIZE_T Length)
+{
+ //
+ // Do nothing
+ //
+ UNREFERENCED_PARAMETER(Source);
+ UNREFERENCED_PARAMETER(Length);
+}
+#endif
+
/* EOF */