Author: tkreuzer
Date: Sat Sep 1 17:01:05 2012
New Revision: 57214
URL: http://svn.reactos.org/svn/reactos?rev=57214&view=rev
Log:
[INTRIN]
Mark intrinsics on gcc with __attribute__((artificial)) so that they appear as one unit in the debug info. This way traces don't point inside the implementations, when they cause an eception, but rather to the line where they are used.
Modified:
trunk/reactos/include/crt/mingw32/intrin.h
Modified: trunk/reactos/include/crt/mingw32/intrin.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/crt/mingw32/intrin…
==============================================================================
--- trunk/reactos/include/crt/mingw32/intrin.h [iso-8859-1] (original)
+++ trunk/reactos/include/crt/mingw32/intrin.h [iso-8859-1] Sat Sep 1 17:01:05 2012
@@ -30,8 +30,14 @@
#ifndef RC_INVOKED
+#ifdef __clang__
+#define __ATTRIBUTE_ARTIFICIAL
+#else
+#define __ATTRIBUTE_ARTIFICIAL __attribute__((artificial))
+#endif
+
#define _PRAGMA_WARNING_SUPPRESS(x) /* Only for MSVC */
-#define __INTRIN_INLINE extern __inline__ __attribute__((__always_inline__,__gnu_inline__))
+#define __INTRIN_INLINE extern __inline__ __attribute__((__always_inline__,__gnu_inline__)) __ATTRIBUTE_ARTIFICIAL
#ifndef _SIZE_T_DEFINED
#define _SIZE_T_DEFINED
Author: ion
Date: Sat Sep 1 02:32:25 2012
New Revision: 57209
URL: http://svn.reactos.org/svn/reactos?rev=57209&view=rev
Log:
[NTOSKRNL]: Cleanup MmCreateArm3Section a little bit to handle file-backed sections in the future.
[NTOSKRNL]: Remove an ASSERT(FALSE) that was only there for testing.
[NTOSKRNL]: Support transition pages during prototype PTE faults, which is our first try at soft faults! Should fix ASSERTs that were seen in the previous attempts in ole32, corrupting the registry.
[NTOSKRNL]: It's fine for MiCreatePagingFileMap to fail in MmCreateSection -- don't assert and simply return failure. Should fix the ASSERTs taht were seen in KmTest.
[NTOSKRNL]: Enable richard's ARM3 section code unconditionally for all non-file backed sections. Works4me. Let's see what Testbot says.
Nobody has showed me how to use/where is PatchBot, and google founds 0 relevant results, so this is going into main again. However I'm actually home this week to revert if something goes wrong :)
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
trunk/reactos/ntoskrnl/mm/ARM3/section.c
trunk/reactos/ntoskrnl/mm/section.c
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] Sat Sep 1 02:32:25 2012
@@ -980,8 +980,51 @@
else if ((TempPte.u.Soft.Prototype == 0) &&
(TempPte.u.Soft.Transition == 1))
{
- /* No standby support yet */
- ASSERT(FALSE);
+ /* This is a standby page, bring it back from the cache */
+ PageFrameIndex = TempPte.u.Trans.PageFrameNumber;
+ DPRINT1("oooh, shiny, a soft fault! 0x%lx\n", PageFrameIndex);
+ Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
+ ASSERT(Pfn1->u3.e1.PageLocation != ActiveAndValid);
+
+ /* Should not yet happen in ReactOS */
+ ASSERT(Pfn1->u3.e1.ReadInProgress == 0);
+ ASSERT(Pfn1->u4.InPageError == 0);
+
+ /* Get the page */
+ MiUnlinkPageFromList(Pfn1);
+
+ /* Bump its reference count */
+ ASSERT(Pfn1->u2.ShareCount == 0);
+ InterlockedIncrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
+ Pfn1->u2.ShareCount++;
+
+ /* Make it valid again */
+ /* This looks like another macro.... */
+ Pfn1->u3.e1.PageLocation = ActiveAndValid;
+ ASSERT(PointerProtoPte->u.Hard.Valid == 0);
+ ASSERT(PointerProtoPte->u.Trans.Prototype == 0);
+ ASSERT(PointerProtoPte->u.Trans.Transition == 1);
+ TempPte.u.Long = (PointerProtoPte->u.Long & ~0xFFF) |
+ MmProtectToPteMask[PointerProtoPte->u.Trans.Protection];
+ TempPte.u.Hard.Valid = 1;
+ TempPte.u.Hard.Accessed = 1;
+
+ /* Is the PTE writeable? */
+ if (((Pfn1->u3.e1.Modified) && (TempPte.u.Hard.Write)) &&
+ (TempPte.u.Hard.CopyOnWrite == 0))
+ {
+ /* Make it dirty */
+ TempPte.u.Hard.Dirty = TRUE;
+ }
+ else
+ {
+ /* Make it clean */
+ TempPte.u.Hard.Dirty = FALSE;
+ }
+
+ /* Write the valid PTE */
+ MI_WRITE_VALID_PTE(PointerProtoPte, TempPte);
+ ASSERT(PointerPte->u.Hard.Valid == 0);
}
else
{
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] Sat Sep 1 02:32:25 2012
@@ -1335,7 +1335,6 @@
}
/* Check to see which list this page should go into */
- ASSERT(FALSE);
if (Pfn1->u3.e1.Modified == 1)
{
/* Push it into the modified page list */
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] Sat Sep 1 02:32:25 2012
@@ -894,10 +894,10 @@
ASSERT(ActualPages <= PageCount);
/* Release the working set lock */
-// MiUnlockWorkingSet(PsGetCurrentThread(),
+// MiUnlockWorkingSet(PsGetCurrentThread(),
// &MmSessionSpace->GlobalVirtualAddress->Vm);
-
+
/* If we did at least one page... */
if (ActualPages)
{
@@ -974,7 +974,7 @@
{
/* Create the PDEs needed for this mapping */
Status = MiSessionCommitPageTables(Base,
- (PVOID)((ULONG_PTR)Base +
+ (PVOID)((ULONG_PTR)Base +
Buckets * MI_SYSTEM_VIEW_BUCKET_SIZE));
NT_ASSERT(NT_SUCCESS(Status));
}
@@ -1243,6 +1243,37 @@
return STATUS_SUCCESS;
}
+VOID
+NTAPI
+MiSubsectionConsistent(IN PSUBSECTION Subsection)
+{
+ /* ReactOS only supports systems with 4K pages and 4K sectors */
+ ASSERT(Subsection->u.SubsectionFlags.SectorEndOffset == 0);
+
+ /* Therefore, then number of PTEs should be equal to the number of sectors */
+ if (Subsection->NumberOfFullSectors != Subsection->PtesInSubsection)
+ {
+ /* Break and warn if this is inconsistent */
+ DPRINT1("Mm: Subsection inconsistent (%x vs %x)\n",
+ Subsection->NumberOfFullSectors, Subsection->PtesInSubsection);
+ DbgBreakPoint();
+ }
+}
+
+NTSTATUS
+NTAPI
+MiCreateDataFileMap(IN PFILE_OBJECT File,
+ OUT PSEGMENT *Segment,
+ IN PSIZE_T MaximumSize,
+ IN ULONG SectionPageProtection,
+ IN ULONG AllocationAttributes,
+ IN ULONG IgnoreFileSizing)
+{
+ /* Not yet implemented */
+ ASSERT(FALSE);
+ return STATUS_NOT_IMPLEMENTED;
+}
+
NTSTATUS
NTAPI
MiCreatePagingFileMap(OUT PSEGMENT *Segment,
@@ -2048,15 +2079,15 @@
SECTION Section;
PSECTION NewSection;
PSUBSECTION Subsection;
- PSEGMENT NewSegment;
+ PSEGMENT NewSegment, Segment;
NTSTATUS Status;
PCONTROL_AREA ControlArea;
- ULONG ProtectionMask;
-
- /* ARM3 does not yet support this */
- ASSERT(FileHandle == NULL);
- ASSERT(FileObject == NULL);
- ASSERT((AllocationAttributes & SEC_LARGE_PAGES) == 0);
+ ULONG ProtectionMask, ControlAreaSize, Size, NonPagedCharge, PagedCharge;
+ KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ BOOLEAN FileLock = FALSE, KernelCall = FALSE;
+ KIRQL OldIrql;
+ PFILE_OBJECT File;
+ PVOID PreviousSectionPointer;
/* Make the same sanity checks that the Nt interface should've validated */
ASSERT((AllocationAttributes & ~(SEC_COMMIT | SEC_RESERVE | SEC_BASED |
@@ -2079,53 +2110,229 @@
ProtectionMask = MiMakeProtectionMask(SectionPageProtection);
if (ProtectionMask == MM_INVALID_PROTECTION) return STATUS_INVALID_PAGE_PROTECTION;
- /* A handle must be supplied with SEC_IMAGE, and this is the no-handle path */
- if (AllocationAttributes & SEC_IMAGE) return STATUS_INVALID_FILE_FOR_SECTION;
-
- /* So this must be a pagefile-backed section, create the mappings needed */
- Status = MiCreatePagingFileMap(&NewSegment,
- (PSIZE_T)InputMaximumSize,
- ProtectionMask,
- AllocationAttributes);
- ASSERT(NT_SUCCESS(Status));
- ASSERT(NewSegment != NULL);
+ /* Check if this is going to be a data or image backed file section */
+ if ((FileHandle) || (FileObject))
+ {
+ /* These cannot be mapped with large pages */
+ if (AllocationAttributes & SEC_LARGE_PAGES) return STATUS_INVALID_PARAMETER_6;
+
+ /* For now, only support the mechanism through a file handle */
+ ASSERT(FileObject == NULL);
+
+ /* Reference the file handle to get the object */
+ Status = ObReferenceObjectByHandle(FileHandle,
+ MmMakeFileAccess[ProtectionMask],
+ IoFileObjectType,
+ PreviousMode,
+ (PVOID*)&File,
+ NULL);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Make sure Cc has been doing its job */
+ if (!File->SectionObjectPointer)
+ {
+ /* This is not a valid file system-based file, fail */
+ ObDereferenceObject(File);
+ return STATUS_INVALID_FILE_FOR_SECTION;
+ }
+
+ /* Image-file backed sections are not yet supported */
+ ASSERT((AllocationAttributes & SEC_IMAGE) == 0);
+
+ /* Compute the size of the control area, and allocate it */
+ ControlAreaSize = sizeof(CONTROL_AREA) + sizeof(MSUBSECTION);
+ ControlArea = ExAllocatePoolWithTag(NonPagedPool, ControlAreaSize, 'aCmM');
+ if (!ControlArea)
+ {
+ ObDereferenceObject(File);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Zero it out */
+ RtlZeroMemory(ControlArea, ControlAreaSize);
+
+ /* Did we get a handle, or an object? */
+ if (FileHandle)
+ {
+ /* We got a file handle so we have to lock down the file */
+#if 0
+ Status = FsRtlAcquireToCreateMappedSection(File, SectionPageProtection);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(ControlArea);
+ ObDereferenceObject(File);
+ return Status;
+ }
+#else
+ /* ReactOS doesn't support this API yet, so do nothing */
+ Status = STATUS_SUCCESS;
+#endif
+ /* Update the top-level IRP so that drivers know what's happening */
+ IoSetTopLevelIrp((PIRP)FSRTL_FSP_TOP_LEVEL_IRP);
+ FileLock = TRUE;
+ }
+
+ /* Lock the PFN database while we play with the section pointers */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+ /* Image-file backed sections are not yet supported */
+ ASSERT((AllocationAttributes & SEC_IMAGE) == 0);
+
+ /* There should not already be a control area for this file */
+ ASSERT(File->SectionObjectPointer->DataSectionObject == NULL);
+ NewSegment = NULL;
+
+ /* Write down that this CA is being created, and set it */
+ ControlArea->u.Flags.BeingCreated = TRUE;
+ PreviousSectionPointer = File->SectionObjectPointer;
+ File->SectionObjectPointer->DataSectionObject = ControlArea;
+
+ /* We can release the PFN lock now */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+
+ /* We don't support previously-mapped file */
+ ASSERT(NewSegment == NULL);
+
+ /* Image-file backed sections are not yet supported */
+ ASSERT((AllocationAttributes & SEC_IMAGE) == 0);
+
+ /* So we always create a data file map */
+ Status = MiCreateDataFileMap(File,
+ &Segment,
+ (PSIZE_T)InputMaximumSize,
+ SectionPageProtection,
+ AllocationAttributes,
+ KernelCall);
+ ASSERT(PreviousSectionPointer == File->SectionObjectPointer);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* Check if a maximum size was specified */
+ if (!InputMaximumSize->QuadPart)
+ {
+ /* Nope, use the segment size */
+ Section.SizeOfSection.QuadPart = (LONGLONG)Segment->SizeOfSegment;
+ }
+ else
+ {
+ /* Yep, use the entered size */
+ Section.SizeOfSection.QuadPart = InputMaximumSize->QuadPart;
+ }
+
+ }
+ else
+ {
+ /* A handle must be supplied with SEC_IMAGE, as this is the no-handle path */
+ if (AllocationAttributes & SEC_IMAGE) return STATUS_INVALID_FILE_FOR_SECTION;
+
+ /* Not yet supported */
+ ASSERT((AllocationAttributes & SEC_LARGE_PAGES) == 0);
+
+ /* So this must be a pagefile-backed section, create the mappings needed */
+ Status = MiCreatePagingFileMap(&NewSegment,
+ (PSIZE_T)InputMaximumSize,
+ ProtectionMask,
+ AllocationAttributes);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Set the size here, and read the control area */
+ Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
+ ControlArea = NewSegment->ControlArea;
+ }
+
+ /* Did we already have a segment? */
+ if (!NewSegment)
+ {
+ /* This must be the file path and we created a segment */
+ NewSegment = Segment;
+ ASSERT(File != NULL);
+
+ /* Acquire the PFN lock while we set control area flags */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+ /* We don't support this race condition yet, so assume no waiters */
+ ASSERT(ControlArea->WaitingForDeletion == NULL);
+ ControlArea->WaitingForDeletion = NULL;
+
+ /* Image-file backed sections are not yet supported, nor ROM images */
+ ASSERT((AllocationAttributes & SEC_IMAGE) == 0);
+ ASSERT(Segment->ControlArea->u.Flags.Rom == 0);
+
+ /* Take off the being created flag, and then release the lock */
+ ControlArea->u.Flags.BeingCreated = FALSE;
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ }
+
+ /* Check if we locked the file earlier */
+ if (FileLock)
+ {
+ /* Reset the top-level IRP and release the lock */
+ IoSetTopLevelIrp(NULL);
+ //FsRtlReleaseFile(File);
+ FileLock = FALSE;
+ }
/* Set the initial section object data */
Section.InitialPageProtection = SectionPageProtection;
- Section.SizeOfSection.QuadPart = NewSegment->SizeOfSegment;
+
+ /* The mapping created a control area and segment, save the flags */
Section.Segment = NewSegment;
-
- /* THe mapping created a control area and segment, save the flags */
- ControlArea = NewSegment->ControlArea;
Section.u.LongFlags = ControlArea->u.LongFlags;
- /* ARM3 cannot support these right now, make sure they're not being set */
- ASSERT(ControlArea->u.Flags.Image == 0);
- ASSERT(ControlArea->FilePointer == NULL);
+ /* Check if this is a user-mode read-write non-image file mapping */
+ if (!(FileObject) &&
+ (SectionPageProtection & (PAGE_READWRITE | PAGE_EXECUTE_READWRITE)) &&
+ (ControlArea->u.Flags.Image == 0) &&
+ (ControlArea->FilePointer != NULL))
+ {
+ /* Add a reference and set the flag */
+ Section.u.Flags.UserWritable = 1;
+ InterlockedIncrement((PLONG)&ControlArea->WritableUserReferences);
+ }
+
+ /* Check for image mappings or page file mappings */
+ if ((ControlArea->u.Flags.Image == 1) || !(ControlArea->FilePointer))
+ {
+ /* Charge the segment size, and allocate a subsection */
+ PagedCharge = sizeof(SECTION) + NewSegment->TotalNumberOfPtes * sizeof(MMPTE);
+ Size = sizeof(SUBSECTION);
+ }
+ else
+ {
+ /* Charge nothing, and allocate a mapped subsection */
+ PagedCharge = 0;
+ Size = sizeof(MSUBSECTION);
+ }
+
+ /* Check if this is a normal CA */
ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
ASSERT(ControlArea->u.Flags.Rom == 0);
- ASSERT(ControlArea->u.Flags.WasPurged == 0);
-
- /* A pagefile-backed mapping only has one subsection, and this is all ARM3 supports */
+
+ /* Charge only a CA, and the subsection is right after */
+ NonPagedCharge = sizeof(CONTROL_AREA);
Subsection = (PSUBSECTION)(ControlArea + 1);
+
+ /* We only support single-subsection mappings */
+ NonPagedCharge += Size;
ASSERT(Subsection->NextSubsection == NULL);
/* Create the actual section object, with enough space for the prototype PTEs */
- Status = ObCreateObject(ExGetPreviousMode(),
+ Status = ObCreateObject(PreviousMode,
MmSectionObjectType,
ObjectAttributes,
- ExGetPreviousMode(),
+ PreviousMode,
NULL,
sizeof(SECTION),
- sizeof(SECTION) +
- NewSegment->TotalNumberOfPtes * sizeof(MMPTE),
- sizeof(CONTROL_AREA) + sizeof(SUBSECTION),
+ PagedCharge,
+ NonPagedCharge,
(PVOID*)&NewSection);
ASSERT(NT_SUCCESS(Status));
/* Now copy the local section object from the stack into this new object */
RtlCopyMemory(NewSection, &Section, sizeof(SECTION));
NewSection->Address.StartingVpn = 0;
+
+ /* For now, only user calls are supported */
+ ASSERT(KernelCall == FALSE);
NewSection->u.Flags.UserReference = TRUE;
/* Migrate the attribute into a flag */
@@ -2170,6 +2377,13 @@
/* Finally release the lock */
KeReleaseGuardedMutex(&MmSectionBasedMutex);
}
+
+ /* Write down if this was a kernel call */
+ ControlArea->u.Flags.WasPurged |= KernelCall;
+ ASSERT(ControlArea->u.Flags.WasPurged == FALSE);
+
+ /* Make sure the segment and the section are the same size, or the section is smaller */
+ ASSERT(NewSection->SizeOfSection.QuadPart <= NewSection->Segment->SizeOfSegment);
/* Return the object and the creation status */
*SectionObject = (PVOID)NewSection;
Modified: trunk/reactos/ntoskrnl/mm/section.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/section.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] Sat Sep 1 02:32:25 2012
@@ -4860,17 +4860,19 @@
PROS_SECTION_OBJECT *SectionObject = (PROS_SECTION_OBJECT *)Section;
/* Check if an ARM3 section is being created instead */
- if (AllocationAttributes & 1)
+ if (!(AllocationAttributes & SEC_IMAGE) && (AllocationAttributes))
{
- DPRINT1("Creating ARM3 section\n");
- return MmCreateArm3Section(Section,
- DesiredAccess,
- ObjectAttributes,
- MaximumSize,
- SectionPageProtection,
- AllocationAttributes &~ 1,
- FileHandle,
- FileObject);
+ if (!(FileObject) && !(FileHandle))
+ {
+ return MmCreateArm3Section(Section,
+ DesiredAccess,
+ ObjectAttributes,
+ MaximumSize,
+ SectionPageProtection,
+ AllocationAttributes &~ 1,
+ FileHandle,
+ FileObject);
+ }
}
/*