[NTOSKRNL]: Stubplement SystemSessionCreateInformation (it allocates a real Session ID and sets the right EPROCESS flags). Nobody uses this yet (future SMSS2 will).

[SMSS2]: More attempts at fixing KVM.

svn path=/trunk/; revision=55464
This commit is contained in:
Alex Ionescu 2012-02-06 17:41:49 +00:00
parent 1fbcc2809f
commit 5fb988c04d
5 changed files with 176 additions and 5 deletions

View file

@ -395,7 +395,7 @@ SmpGetVolumeFreeSpace(IN PSMP_VOLUME_DESCRIPTOR Volume)
SizeInfo.SectorsPerAllocationUnit;
FinalFreeSpace.QuadPart = FreeSpace.QuadPart * SizeInfo.BytesPerSector;
Volume->FreeSpace = FinalFreeSpace;
DPRINT1("AUs: %I64 Sectors: %lx Bytes Per Sector: %lx\n",
DPRINT1("AUs: %I64x Sectors: %lx Bytes Per Sector: %lx\n",
SizeInfo.AvailableAllocationUnits.QuadPart,
SizeInfo.SectorsPerAllocationUnit,
SizeInfo.BytesPerSector);
@ -592,7 +592,13 @@ SmpCreatePagingFileOnFixedDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor,
if (Descriptor->ActualMinSize.QuadPart < MinimumSize->QuadPart)
{
/* Delete the current page file and fail */
if (ShouldDelete) SmpDeletePagingFile(&Descriptor->Name);
if (ShouldDelete)
{
SmpDeletePagingFile(&Descriptor->Name);
/* FIXFIX: Windows Vista does this, and it seems like we should too, so try to see if this fixes KVM */
Volume->FreeSpace.QuadPart += PageFileSize.QuadPart;
}
DPRINT1("SMSS:PFILE: Failing for min %I64X, max %I64X, real min %I64X \n",
Descriptor->ActualMinSize.QuadPart,
Descriptor->ActualMaxSize.QuadPart,

View file

@ -1755,13 +1755,31 @@ SSI_DEF(SystemSetTimeSlipEvent)
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
MmSessionCreate(OUT PULONG SessionId);
/* Class 47 - Create a new session (TSE) */
SSI_DEF(SystemCreateSession)
{
/* FIXME */
DPRINT1("NtSetSystemInformation - SystemCreateSession not implemented\n");
return STATUS_NOT_IMPLEMENTED;
ULONG SessionId;
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
NTSTATUS Status;
if (Size != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH;
if (PreviousMode != KernelMode)
{
if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, PreviousMode))
{
return STATUS_PRIVILEGE_NOT_HELD;
}
}
Status = MmSessionCreate(&SessionId);
if (NT_SUCCESS(Status)) *(PULONG)Buffer = SessionId;
return Status;
}

View file

@ -983,6 +983,12 @@ MiInitializePfnDatabase(
IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
VOID
NTAPI
MiInitializeSessionIds(
VOID
);
BOOLEAN
NTAPI
MiInitializeMemoryEvents(

View file

@ -1340,6 +1340,144 @@ MmCleanProcessAddressSpace(IN PEPROCESS Process)
MmUnlockAddressSpace(&Process->Vm);
}
/* SESSION CODE TO MOVE TO SESSION.C ******************************************/
KGUARDED_MUTEX MiSessionIdMutex;
PRTL_BITMAP MiSessionIdBitmap;
volatile LONG MiSessionLeaderExists;
VOID
NTAPI
MiInitializeSessionIds(VOID)
{
/* FIXME: Other stuff should go here */
/* Initialize the lock */
KeInitializeGuardedMutex(&MiSessionIdMutex);
/* Allocate the bitmap */
MiSessionIdBitmap = ExAllocatePoolWithTag(PagedPool,
sizeof(RTL_BITMAP) + ((64 + 31) / 32) * 4,
' mM');
if (MiSessionIdBitmap)
{
/* Free all the bits */
RtlInitializeBitMap(MiSessionIdBitmap, (PVOID)(MiSessionIdBitmap + 1), 64);
RtlClearAllBits(MiSessionIdBitmap);
}
else
{
/* Die if we couldn't allocate the bitmap */
KeBugCheckEx(INSTALL_MORE_MEMORY,
MmNumberOfPhysicalPages,
MmLowestPhysicalPage,
MmHighestPhysicalPage,
0x200);
}
}
VOID
NTAPI
MiSessionLeader(IN PEPROCESS Process)
{
KIRQL OldIrql;
/* Set the flag while under the expansion lock */
OldIrql = KeAcquireQueuedSpinLock(LockQueueExpansionLock);
Process->Vm.Flags.SessionLeader = TRUE;
KeReleaseQueuedSpinLock(LockQueueExpansionLock, OldIrql);
}
NTSTATUS
NTAPI
MiSessionCreateInternal(OUT PULONG SessionId)
{
PEPROCESS Process = PsGetCurrentProcess();
ULONG NewFlags, Flags;
/* Loop so we can set the session-is-creating flag */
Flags = Process->Flags;
while (TRUE)
{
/* Check if it's already set */
if (Flags & PSF_SESSION_CREATION_UNDERWAY_BIT)
{
/* Bail out */
DPRINT1("Lost session race\n");
return STATUS_ALREADY_COMMITTED;
}
/* Now try to set it */
NewFlags = InterlockedCompareExchange((PLONG)&Process->Flags,
Flags | PSF_SESSION_CREATION_UNDERWAY_BIT,
Flags);
if (NewFlags == Flags) break;
/* It changed, try again */
Flags = NewFlags;
}
/* Now we should own the flag */
ASSERT(Process->Flags & PSF_SESSION_CREATION_UNDERWAY_BIT);
/* Allocate a new Session ID */
KeAcquireGuardedMutex(&MiSessionIdMutex);
*SessionId = RtlFindClearBitsAndSet(MiSessionIdBitmap, 1, 0);
if (*SessionId == 0xFFFFFFFF)
{
DPRINT1("Too many sessions created. Expansion not yet supported\n");
return STATUS_NO_MEMORY;
}
KeReleaseGuardedMutex(&MiSessionIdMutex);
/* We're done, clear the flag */
ASSERT(Process->Flags & PSF_SESSION_CREATION_UNDERWAY_BIT);
PspClearProcessFlag(Process, PSF_SESSION_CREATION_UNDERWAY_BIT);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
MmSessionCreate(OUT PULONG SessionId)
{
PEPROCESS Process = PsGetCurrentProcess();
ULONG SessionLeaderExists;
NTSTATUS Status;
/* Fail if the process is already in a session */
if (Process->Flags & PSF_PROCESS_IN_SESSION_BIT)
{
DPRINT1("Process already in session\n");
return STATUS_ALREADY_COMMITTED;
}
/* Check if the process is already the session leader */
if (!Process->Vm.Flags.SessionLeader)
{
/* Atomically set it as the leader */
SessionLeaderExists = InterlockedCompareExchange(&MiSessionLeaderExists, 1, 0);
if (SessionLeaderExists)
{
DPRINT1("Session leader race\n");
return STATUS_INVALID_SYSTEM_SERVICE;
}
/* Do the work required to upgrade him */
MiSessionLeader(Process);
}
/* FIXME: Actually create a session */
KeEnterCriticalRegion();
Status = MiSessionCreateInternal(SessionId);
KeLeaveCriticalRegion();
/* Set and assert the flags, and return */
PspSetProcessFlag(Process, PSF_PROCESS_IN_SESSION_BIT);
ASSERT(MiSessionLeaderExists == 1);
if (NT_SUCCESS(Status)) DPRINT1("New session created: %lx\n", *SessionId);
return Status;
}
/* SYSTEM CALLS ***************************************************************/
NTSTATUS

View file

@ -437,6 +437,9 @@ MmInitSystem(IN ULONG Phase,
PageFrameNumber);
*MmSharedUserDataPte = TempPte;
/* Setup session IDs */
MiInitializeSessionIds();
/* Setup the memory threshold events */
if (!MiInitializeMemoryEvents()) return FALSE;