Author: ion
Date: Mon Sep 23 02:30:58 2013
New Revision: 60329
URL: http://svn.reactos.org/svn/reactos?rev=60329&view=rev
Log:
- Implement and export MmCommitSessionMappedView. No gurantees this works until ThFabba writes a test for it, but it does what Windows does :P, minus charging commit since we don't do that yet. Nothing in ROS calls this so guranteed 0 regressions.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/section.c
trunk/reactos/ntoskrnl/ntoskrnl.spec
Modified: trunk/reactos/ntoskrnl/mm/ARM3/section.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/section.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] Mon Sep 23 02:30:58 2013
@@ -2742,6 +2742,171 @@
return MiUnmapViewInSystemSpace(&MmSession, MappedBase);
}
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+MmCommitSessionMappedView(IN PVOID MappedBase,
+ IN SIZE_T ViewSize)
+{
+ ULONG_PTR StartAddress, EndingAddress, Base;
+ ULONG Hash, Count, Size, QuotaCharge;
+ PMMSESSION Session;
+ PMMPTE LastProtoPte, PointerPte, ProtoPte;
+ PCONTROL_AREA ControlArea;
+ PSEGMENT Segment;
+ PSUBSECTION Subsection;
+ MMPTE TempPte;
+ PAGED_CODE();
+
+ /* Make sure the base isn't past the session view range */
+ if ((MappedBase < MiSessionViewStart) ||
+ (MappedBase >= (PVOID)((ULONG_PTR)MiSessionViewStart + MmSessionViewSize)))
+ {
+ DPRINT1("Base outside of valid range\n");
+ return STATUS_INVALID_PARAMETER_1;
+ }
+
+ /* Make sure the size isn't past the session view range */
+ if (((ULONG_PTR)MiSessionViewStart + MmSessionViewSize -
+ (ULONG_PTR)MappedBase) < ViewSize)
+ {
+ DPRINT1("Size outside of valid range\n");
+ return STATUS_INVALID_PARAMETER_2;
+ }
+
+ /* Sanity check */
+ ASSERT(ViewSize != 0);
+
+ /* Process must be in a session */
+ if (PsGetCurrentProcess()->ProcessInSession == FALSE)
+ {
+ DPRINT1("Process is not in session\n");
+ return STATUS_NOT_MAPPED_VIEW;
+ }
+
+ /* Compute the correctly aligned base and end addresses */
+ StartAddress = (ULONG_PTR)PAGE_ALIGN(MappedBase);
+ EndingAddress = ((ULONG_PTR)MappedBase + ViewSize - 1) | (PAGE_SIZE - 1);
+
+ /* Sanity check and grab the session */
+ ASSERT(MmIsAddressValid(MmSessionSpace) == TRUE);
+ Session = &MmSessionSpace->Session;
+
+ /* Get the hash entry for this allocation */
+ Hash = (StartAddress >> 16) % Session->SystemSpaceHashKey;
+
+ /* Lock system space */
+ KeAcquireGuardedMutex(Session->SystemSpaceViewLockPointer);
+
+ /* Loop twice so we can try rolling over if needed */
+ while (TRUE)
+ {
+ /* Extract the size and base addresses from the entry */
+ Base = Session->SystemSpaceViewTable[Hash].Entry & ~0xFFFF;
+ Size = Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF;
+
+ /* Convert the size to bucket chunks */
+ Size *= MI_SYSTEM_VIEW_BUCKET_SIZE;
+
+ /* Bail out if this entry fits in here */
+ if ((StartAddress >= Base) && (EndingAddress < (Base + Size))) break;
+
+ /* Check if we overflew past the end of the hash table */
+ if (++Hash >= Session->SystemSpaceHashSize)
+ {
+ /* Reset the hash to zero and keep searching from the bottom */
+ Hash = 0;
+ if (++Count == 2)
+ {
+ /* But if we overflew twice, then this is not a real mapping */
+ KeBugCheckEx(0xD7, //DRIVER_UNMAPPING_INVALID_VIEW,
+ Base,
+ 2,
+ 0,
+ 0);
+ }
+ }
+ }
+
+ /* Make sure the view being mapped is not file-based */
+ ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
+ if (ControlArea->FilePointer != NULL)
+ {
+ /* It is, so we have to bail out */
+ DPRINT1("Only page-filed backed sections can be commited\n");
+ KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
+ return STATUS_ALREADY_COMMITTED;
+ }
+
+ /* Get the subsection. We don't support LARGE_CONTROL_AREA in ARM3 */
+ ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
+ ASSERT(ControlArea->u.Flags.Rom == 0);
+ Subsection = (PSUBSECTION)(ControlArea + 1);
+
+ /* Get the start and end PTEs -- make sure the end PTE isn't past the end */
+ ProtoPte = Subsection->SubsectionBase + ((StartAddress - Base) >> PAGE_SHIFT);
+ QuotaCharge = MiAddressToPte(EndingAddress) - MiAddressToPte(StartAddress) + 1;
+ LastProtoPte = ProtoPte + QuotaCharge;
+ if (LastProtoPte >= Subsection->SubsectionBase + Subsection->PtesInSubsection)
+ {
+ DPRINT1("PTE is out of bounds\n");
+ KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
+ return STATUS_INVALID_PARAMETER_2;
+ }
+
+ /* Acquire the commit lock and count all the non-committed PTEs */
+ KeAcquireGuardedMutexUnsafe(&MmSectionCommitMutex);
+ PointerPte = ProtoPte;
+ while (PointerPte < LastProtoPte)
+ {
+ if (PointerPte->u.Long) QuotaCharge--;
+ PointerPte++;
+ }
+
+ /* Was everything committed already? */
+ if (!QuotaCharge)
+ {
+ /* Nothing to do! */
+ KeReleaseGuardedMutexUnsafe(&MmSectionCommitMutex);
+ KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
+ return STATUS_SUCCESS;
+ }
+
+ /* Pick the segment and template PTE */
+ Segment = ControlArea->Segment;
+ TempPte = Segment->SegmentPteTemplate;
+ ASSERT(TempPte.u.Long != 0);
+
+ /* Loop all prototype PTEs to be committed */
+ while (PointerPte < LastProtoPte)
+ {
+ /* Make sure the PTE is already invalid */
+ if (PointerPte->u.Long == 0)
+ {
+ /* And write the invalid PTE */
+ MI_WRITE_INVALID_PTE(PointerPte, TempPte);
+ }
+
+ /* Move to the next PTE */
+ PointerPte++;
+ }
+
+ /* Check if we had at least one page charged */
+ if (QuotaCharge)
+ {
+ /* Update the accounting data */
+ Segment->NumberOfCommittedPages += QuotaCharge;
+ InterlockedExchangeAddSizeT(&MmSharedCommit, QuotaCharge);
+ }
+
+ /* Release all */
+ KeReleaseGuardedMutexUnsafe(&MmSectionCommitMutex);
+ KeReleaseGuardedMutex(Session->SystemSpaceViewLockPointer);
+ return STATUS_SUCCESS;
+}
+
/* SYSTEM CALLS ***************************************************************/
NTSTATUS
Modified: trunk/reactos/ntoskrnl/ntoskrnl.spec
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl.spec?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl.spec [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl.spec [iso-8859-1] Mon Sep 23 02:30:58 2013
@@ -758,7 +758,7 @@
@ stdcall MmAllocatePagesForMdlEx(long long long long long long long long long)
@ stdcall MmBuildMdlForNonPagedPool(ptr)
@ stdcall MmCanFileBeTruncated(ptr ptr)
-;MmCommitSessionMappedView
+@ stdcall MmCommitSessionMappedView(ptr ptr)
@ stdcall MmCreateMdl(ptr ptr long)
;MmCreateMirror
@ stdcall MmCreateSection(ptr long ptr ptr long long ptr ptr)
Author: tkreuzer
Date: Sun Sep 22 21:19:40 2013
New Revision: 60327
URL: http://svn.reactos.org/svn/reactos?rev=60327&view=rev
Log:
[DEBUG.H] Add a _WARN macro to emit compiler warning messages (also adds __STRLINE__ macro, being resolved to the current line number as a string token)
[NTOSKRNL] Fix some x64 issues and warn about unimplemented session space stuff on x64
Modified:
trunk/reactos/include/reactos/debug.h
trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
Modified: trunk/reactos/include/reactos/debug.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/debug.h?re…
==============================================================================
--- trunk/reactos/include/reactos/debug.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/debug.h [iso-8859-1] Sun Sep 22 21:19:40 2013
@@ -230,4 +230,18 @@
#define ASSERT_IRQL_EQUAL(x) ASSERT(KeGetCurrentIrql()==(x))
#define ASSERT_IRQL_LESS(x) ASSERT(KeGetCurrentIrql()<(x))
+#define __STRING2__(x) #x
+#define __STRING__(x) __STRING2__(x)
+#define __STRLINE__ __STRING__(__LINE__)
+
+#define __TOKENPASTE2__(x, y) x ## y
+#define __TOKENPASTE__(x, y) __TOKENPASTE2__(x, y)
+
+#ifdef _MSC_VER
+#define _WARN(msg) __pragma(message("WARNING! Line " __STRLINE__ ": " msg))
+#else
+#define _WARN1(_func1, _func2, _msg) void __attribute__((warning (_msg))) _func1(void); void __attribute__((used)) _func2(void) { _func1(); }
+#define _WARN(_msg) _WARN1(__TOKENPASTE__(__warn_func1__, __LINE__), __TOKENPASTE__(__warn_func2__, __LINE__), _msg)
+#endif
+
#endif /* __INTERNAL_DEBUG */
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pagfault.…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] Sun Sep 22 21:19:40 2013
@@ -32,7 +32,7 @@
PETHREAD CurrentThread = PsGetCurrentThread();
PTEB Teb = CurrentThread->Tcb.Teb;
PVOID StackBase, DeallocationStack, NextStackAddress;
- ULONG GuranteedSize;
+ SIZE_T GuranteedSize;
NTSTATUS Status;
/* Do we own the address space lock? */
@@ -116,7 +116,7 @@
MiAccessCheck(IN PMMPTE PointerPte,
IN BOOLEAN StoreInstruction,
IN KPROCESSOR_MODE PreviousMode,
- IN ULONG ProtectionCode,
+ IN ULONG_PTR ProtectionCode,
IN PVOID TrapFrame,
IN BOOLEAN LockHeld)
{
@@ -1496,7 +1496,7 @@
return STATUS_SUCCESS;
}
}
-
+#if (_MI_PAGING_LEVELS == 2)
/* Check if this was a session PTE that needs to remap the session PDE */
if (MI_IS_SESSION_PTE(Address))
{
@@ -1512,6 +1512,11 @@
6);
}
}
+#else
+
+_WARN("Session space stuff is not implemented yet!")
+
+#endif
/* Check for a fault on the page table or hyperspace */
if (MI_IS_PAGE_TABLE_OR_HYPER_ADDRESS(Address))
@@ -1970,7 +1975,7 @@
else
{
/* Get the protection code and check if this is a proto PTE */
- ProtectionCode = TempPte.u.Soft.Protection;
+ ProtectionCode = (ULONG)TempPte.u.Soft.Protection;
if (TempPte.u.Soft.Prototype)
{
/* Do we need to go find the real PTE? */