Author: sginsberg Date: Wed Oct 14 19:33:35 2015 New Revision: 69528
URL: http://svn.reactos.org/svn/reactos?rev=69528&view=rev Log: [NTOS] Add super-complicated handling of global pages to KeFlushCurrentTb (pretty much the same code which has been in HalpFlushTLB for the past ~6 years). This should be all that is required to make this feature work (everything else being in place already), and *seems* to work fine but is disabled under a switch until tested thoroughly.
Global pages, an important optimization that allows for not flushing the whole x86 TLB every time CR3 is changed (typically on context switch to a new process, or during process attach/detach), relies on us doing extra work whenever we do alter a global page. This is likely where any bugs will have to be flushed out!
Fixup Ki386EnableGlobalPage while we are at it -- disable/restore interrupts properly, and verify PGE-bit isn't set (nothing should have touched it before this routine, which is responsible for initializing it, so we shouldn't have to disable it). Fix, but disable, the CPU-sync spin as well as there should be no particular reason to do this for PGE-enabling during initialization (no other processor will be messing with PTEs at this stage, as compared to a call to KeFlushEntireTb).
Everyone, repeat after me: Global pages are awesome!
Modified: trunk/reactos/ntoskrnl/include/ntoskrnl.h trunk/reactos/ntoskrnl/ke/i386/cpu.c trunk/reactos/ntoskrnl/ke/i386/patpge.c trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c
Modified: trunk/reactos/ntoskrnl/include/ntoskrnl.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/ntoskrnl.h... ============================================================================== --- trunk/reactos/ntoskrnl/include/ntoskrnl.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/ntoskrnl.h [iso-8859-1] Wed Oct 14 19:33:35 2015 @@ -98,6 +98,14 @@ #define ASSERT NT_ASSERT #endif
+ +// +// Switch for enabling global page support +// + +//#define _GLOBAL_PAGES_ARE_AWESOME_ + + /* Internal Headers */ #include "internal/ntoskrnl.h" #include "config.h"
Modified: trunk/reactos/ntoskrnl/ke/i386/cpu.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/cpu.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/cpu.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/i386/cpu.c [iso-8859-1] Wed Oct 14 19:33:35 2015 @@ -878,8 +878,37 @@ NTAPI KeFlushCurrentTb(VOID) { + +#if !defined(_GLOBAL_PAGES_ARE_AWESOME_) + /* Flush the TLB by resetting CR3 */ __writecr3(__readcr3()); + +#else + + /* Check if global pages are enabled */ + if (KeFeatureBits & KF_GLOBAL_PAGE) + { + ULONG Cr4; + + /* Disable PGE */ + Cr4 = __readcr4() & ~CR4_PGE; + __writecr4(Cr4); + + /* Flush everything */ + __writecr3(__readcr3()); + + /* Re-enable PGE */ + __writecr4(Cr4 | CR4_PGE); + } + else + { + /* No global pages, resetting CR3 is enough */ + __writecr3(__readcr3()); + } + +#endif + }
VOID
Modified: trunk/reactos/ntoskrnl/ke/i386/patpge.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/patpge.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/patpge.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/i386/patpge.c [iso-8859-1] Wed Oct 14 19:33:35 2015 @@ -17,40 +17,41 @@
/* FUNCTIONS *****************************************************************/
+INIT_SECTION ULONG_PTR NTAPI -INIT_FUNCTION Ki386EnableGlobalPage(IN ULONG_PTR Context) { - PLONG Count = (PLONG)Context; - ULONG Cr4, Cr3; + //PLONG Count; +#if defined(_GLOBAL_PAGES_ARE_AWESOME_) + ULONG Cr4; +#endif + BOOLEAN Enable;
/* Disable interrupts */ - _disable(); - - /* Decrease CPU Count and loop until it's reached 0 */ - do {InterlockedDecrement(Count);} while (!*Count); - - /* Now check if this is the Boot CPU */ - if (!KeGetPcr()->Number) - { - /* It is.FIXME: Patch KeFlushCurrentTb */ - } - - /* Now get CR4 and make sure PGE is masked out */ + Enable = KeDisableInterrupts(); + + /* Spin until other processors are ready */ + //Count = (PLONG)Context; + //InterlockedDecrement(Count); + //while (*Count) YieldProcessor(); + +#if defined(_GLOBAL_PAGES_ARE_AWESOME_) + + /* Get CR4 and ensure global pages are disabled */ Cr4 = __readcr4(); - __writecr4(Cr4 & ~CR4_PGE); - - /* Flush the TLB */ - Cr3 = __readcr3(); - __writecr3(Cr3); + ASSERT(!(Cr4 & CR4_PGE)); + + /* Reset CR3 to flush the TLB */ + __writecr3(__readcr3());
/* Now enable PGE */ - DPRINT("Global page support detected but not yet taken advantage of\n"); - //__writecr4(Cr4 | CR4_PGE); - - /* Restore interrupts */ - _enable(); + __writecr4(Cr4 | CR4_PGE); + +#endif + + /* Restore interrupts and return */ + KeRestoreInterrupts(Enable); return 0; }
Modified: trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/i386/init.... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] Wed Oct 14 19:33:35 2015 @@ -249,15 +249,18 @@ PMMPFN Pfn1; ULONG Flags;
+#if defined(_GLOBAL_PAGES_ARE_AWESOME_) + /* Check for global bit */ -#if 0 if (KeFeatureBits & KF_GLOBAL_PAGE) { /* Set it on the template PTE and PDE */ ValidKernelPte.u.Hard.Global = TRUE; ValidKernelPde.u.Hard.Global = TRUE; } + #endif + /* Now templates are ready */ TempPte = ValidKernelPte; TempPde = ValidKernelPde;