diff --git a/reactos/dll/win32/kernel32/client/proc.c b/reactos/dll/win32/kernel32/client/proc.c index 809457c78b9..0f57b7bbffb 100644 --- a/reactos/dll/win32/kernel32/client/proc.c +++ b/reactos/dll/win32/kernel32/client/proc.c @@ -1507,12 +1507,12 @@ BOOL 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 */ diff --git a/reactos/include/ndk/kefuncs.h b/reactos/include/ndk/kefuncs.h index a1e379fdc7f..bf8463ef13d 100644 --- a/reactos/include/ndk/kefuncs.h +++ b/reactos/include/ndk/kefuncs.h @@ -398,15 +398,6 @@ NtDelayExecution( _In_ LARGE_INTEGER *Interval ); -NTSYSCALLAPI -NTSTATUS -NTAPI -NtFlushInstructionCache( - _In_ HANDLE ProcessHandle, - _In_ PVOID BaseAddress, - _In_ ULONG NumberOfBytesToFlush -); - ULONG NTAPI NtGetCurrentProcessorNumber( diff --git a/reactos/include/ndk/mmfuncs.h b/reactos/include/ndk/mmfuncs.h index 0d3782fba9e..9872ecb9770 100644 --- a/reactos/include/ndk/mmfuncs.h +++ b/reactos/include/ndk/mmfuncs.h @@ -134,6 +134,15 @@ NtExtendSection( _In_ PLARGE_INTEGER NewMaximumSize ); +NTSYSCALLAPI +NTSTATUS +NTAPI +NtFlushInstructionCache( + _In_ HANDLE ProcessHandle, + _In_ PVOID BaseAddress, + _In_ SIZE_T NumberOfBytesToFlush +); + NTSYSCALLAPI NTSTATUS NTAPI diff --git a/reactos/lib/rtl/mem.c b/reactos/lib/rtl/mem.c index 0704f521ab2..6927f543f3e 100644 --- a/reactos/lib/rtl/mem.c +++ b/reactos/lib/rtl/mem.c @@ -146,21 +146,6 @@ RtlMoveMemory(PVOID Destination, 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 diff --git a/reactos/lib/rtl/powerpc/rtlmem.s b/reactos/lib/rtl/powerpc/rtlmem.s index 12c98c60aa3..8d08ed0424e 100644 --- a/reactos/lib/rtl/powerpc/rtlmem.s +++ b/reactos/lib/rtl/powerpc/rtlmem.s @@ -100,6 +100,3 @@ RtlZeroMemory: mr 5,4 xor 4,4,4 b memset - -RtlPrefetchMemoryNonTemporal: - blr diff --git a/reactos/ntoskrnl/ex/sysinfo.c b/reactos/ntoskrnl/ex/sysinfo.c index 3f5bf6f2663..570bf91f545 100644 --- a/reactos/ntoskrnl/ex/sysinfo.c +++ b/reactos/ntoskrnl/ex/sysinfo.c @@ -2533,99 +2533,19 @@ NtSetSystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass, 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(); } diff --git a/reactos/ntoskrnl/include/internal/amd64/ke.h b/reactos/ntoskrnl/include/internal/amd64/ke.h index 1701fe60fb2..c5af042be7b 100644 --- a/reactos/ntoskrnl/include/internal/amd64/ke.h +++ b/reactos/ntoskrnl/include/internal/amd64/ke.h @@ -188,6 +188,19 @@ KeFlushProcessTb(VOID) __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) diff --git a/reactos/ntoskrnl/include/internal/arm/ke.h b/reactos/ntoskrnl/include/internal/arm/ke.h index 32ac28d84df..2d39c580b15 100644 --- a/reactos/ntoskrnl/include/internal/arm/ke.h +++ b/reactos/ntoskrnl/include/internal/arm/ke.h @@ -116,6 +116,19 @@ KeFlushProcessTb(VOID) 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) diff --git a/reactos/ntoskrnl/include/internal/i386/ke.h b/reactos/ntoskrnl/include/internal/i386/ke.h index 4dbdb2d5891..7c9cce3ffcc 100644 --- a/reactos/ntoskrnl/include/internal/i386/ke.h +++ b/reactos/ntoskrnl/include/internal/i386/ke.h @@ -266,6 +266,19 @@ KeFlushProcessTb(VOID) __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) diff --git a/reactos/ntoskrnl/include/internal/i386/trap_x.h b/reactos/ntoskrnl/include/internal/i386/trap_x.h index 99e7cba3262..444696fee7a 100644 --- a/reactos/ntoskrnl/include/internal/i386/trap_x.h +++ b/reactos/ntoskrnl/include/internal/i386/trap_x.h @@ -8,8 +8,6 @@ #pragma once -#define TRAP_DEBUG 0 - #define UNREACHABLE __assume(0) #if _MSC_VER @@ -72,9 +70,9 @@ KiDumpTrapFrame(IN PKTRAP_FRAME TrapFrame) DbgPrint("V86Gs: %x\n", TrapFrame->V86Gs); } -#if TRAP_DEBUG -VOID +#if DBG FORCEINLINE +VOID KiFillTrapFrameDebug(IN PKTRAP_FRAME TrapFrame) { /* Set the debug information */ diff --git a/reactos/ntoskrnl/include/internal/powerpc/ke.h b/reactos/ntoskrnl/include/internal/powerpc/ke.h index 4edfbf4ce94..87c72a2d505 100644 --- a/reactos/ntoskrnl/include/internal/powerpc/ke.h +++ b/reactos/ntoskrnl/include/internal/powerpc/ke.h @@ -89,6 +89,19 @@ KeFlushProcessTb(VOID) __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) diff --git a/reactos/ntoskrnl/include/ntoskrnl.h b/reactos/ntoskrnl/include/ntoskrnl.h index 1b51ebc3697..5e5c9b49bcd 100644 --- a/reactos/ntoskrnl/include/ntoskrnl.h +++ b/reactos/ntoskrnl/include/ntoskrnl.h @@ -98,8 +98,10 @@ extern UCHAR _KeNumberProcessors; // // NT_ASSERT Best Assert // +#if defined(_MSC_VER) #undef ASSERT #define ASSERT NT_ASSERT +#endif /* Internal Headers */ #include "internal/ntoskrnl.h" diff --git a/reactos/ntoskrnl/kd64/kdapi.c b/reactos/ntoskrnl/kd64/kdapi.c index 1c427922f7a..5f14240694c 100644 --- a/reactos/ntoskrnl/kd64/kdapi.c +++ b/reactos/ntoskrnl/kd64/kdapi.c @@ -84,6 +84,11 @@ KdpCopyMemoryChunks(IN ULONG64 Address, 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 diff --git a/reactos/ntoskrnl/ke/i386/traphdlr.c b/reactos/ntoskrnl/ke/i386/traphdlr.c index 908a35ef2ab..d3b041e2f1c 100644 --- a/reactos/ntoskrnl/ke/i386/traphdlr.c +++ b/reactos/ntoskrnl/ke/i386/traphdlr.c @@ -56,7 +56,7 @@ PFAST_SYSTEM_CALL_EXIT KiFastCallExitHandler; PKDBG_PRESERVICEHOOK KeWin32PreServiceHook = NULL; PKDBG_POSTSERVICEHOOK KeWin32PostServiceHook = NULL; #endif -#if TRAP_DEBUG +#if DBG BOOLEAN StopChecking = FALSE; #endif diff --git a/reactos/ntoskrnl/mm/ARM3/virtual.c b/reactos/ntoskrnl/mm/ARM3/virtual.c index ee9446515f5..95c157184a8 100644 --- a/reactos/ntoskrnl/mm/ARM3/virtual.c +++ b/reactos/ntoskrnl/mm/ARM3/virtual.c @@ -2914,6 +2914,73 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle, 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, diff --git a/reactos/ntoskrnl/rtl/misc.c b/reactos/ntoskrnl/rtl/misc.c index 1b885498aa0..5d0861d9f11 100644 --- a/reactos/ntoskrnl/rtl/misc.c +++ b/reactos/ntoskrnl/rtl/misc.c @@ -62,4 +62,21 @@ RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation) 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 */