[NTOSKRNL]

- Fix a bug in CmpSetSystemValues, where an uninitialized handle would be closed in the failure path.
- Add a hack on top of the MI_GET_ROS_DATA(x) hack so that we can squeeze a pointer into a 32 bit field.
Make MmInitializeProcessAddressSpace amd64 ready and use a portable way to determine the page table base pfn in MiInitializeWorkingSetList
- Make MmProbeAndLockPages ready for 3 and 4 level page tables
add MiIsPteOnP*eBoundary macros - use  these in MmProbeAndLockPages
- Raise IRQL to SYNCH_LEVEL not DISPATCH_LEVEL in KiAcquireDispatcherLock
- Add MiNonPagedSystemSize for all architectures
- Fix amd64 definition of KERNEL_HANDLE_FLAG
- Fix definition of PrototypePte
- Fix KiGetLinkedTrapFrame()
- Make MmProtectTpPteMask 64 bit wide 
- Fix definition of MI_PTE_LOOKUP_NEEDED for amd64
- Impllement KiSendEOI() to be able to send an EOI from C code.
- Fix some MSVC/amd64 warnings

svn path=/trunk/; revision=55423
This commit is contained in:
Timo Kreuzer 2012-02-04 23:08:20 +00:00
parent cb837e18a1
commit d7bdbf2152
15 changed files with 195 additions and 119 deletions

View file

@ -333,7 +333,7 @@ CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName, ValueName = { 0, 0, NULL };
HANDLE KeyHandle;
HANDLE KeyHandle = NULL;
NTSTATUS Status;
ASSERT(LoaderBlock != NULL);
@ -374,7 +374,7 @@ Quickie:
RtlFreeUnicodeString(&ValueName);
/* Close the key and return */
NtClose(KeyHandle);
if (KeyHandle) NtClose(KeyHandle);
/* Return the status */
return (ExpInTextModeSetup ? STATUS_SUCCESS : Status);
@ -1098,7 +1098,8 @@ CmpLoadHiveThread(IN PVOID StartContext)
{
WCHAR FileBuffer[MAX_PATH], RegBuffer[MAX_PATH], ConfigPath[MAX_PATH];
UNICODE_STRING TempName, FileName, RegName;
ULONG FileStart, i, ErrorResponse, WorkerCount, Length;
ULONG i, ErrorResponse, WorkerCount, Length;
USHORT FileStart;
//ULONG RegStart;
ULONG PrimaryDisposition, SecondaryDisposition, ClusterSize;
PCMHIVE CmHive;
@ -1259,7 +1260,8 @@ CmpInitializeHiveList(IN USHORT Flag)
UNICODE_STRING TempName, FileName, RegName;
HANDLE Thread;
NTSTATUS Status;
ULONG RegStart, i;
ULONG i;
USHORT RegStart;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PAGED_CODE();

View file

@ -5,7 +5,9 @@
#ifdef _M_IX86
EXTERN _KiSystemService:PROC
#elif defined(_M_AMD64)
#include <ksamd64.inc>
EXTERN KiSystemService:PROC
EXTERN KiZwSystemService:PROC
#endif
.code

View file

@ -56,6 +56,8 @@
#define AMD64_TSS 9
#define APIC_EOI_REGISTER 0xFFFFFFFFFFFE00B0ULL
#ifndef __ASM__
#include "intrin_i.h"
@ -68,6 +70,17 @@ typedef struct _KIDT_INIT
PVOID ServiceRoutine;
} KIDT_INIT, *PKIDT_INIT;
#include <pshpack1.h>
typedef struct _KI_INTERRUPT_DISPATCH_ENTRY
{
UCHAR _Op_nop;
UCHAR _Op_push;
UCHAR _Vector;
UCHAR _Op_jmp;
ULONG RelativeAddress;
} KI_INTERRUPT_DISPATCH_ENTRY, *PKI_INTERRUPT_DISPATCH_ENTRY;
#include <poppack.h>
extern ULONG Ke386CacheAlignment;
extern ULONG KeI386NpxPresent;
extern ULONG KeI386XMMIPresent;
@ -95,7 +108,7 @@ extern ULONG KeI386CpuStep;
((TrapFrame)->Rip)
#define KiGetLinkedTrapFrame(x) \
(PKTRAP_FRAME)((x)->Rdx)
(PKTRAP_FRAME)((x)->TrapFrame)
#define KeGetContextReturnRegister(Context) \
((Context)->Rax)
@ -233,6 +246,14 @@ KeQueryInterruptHandler(IN ULONG Vector)
(ULONG64)Idt->OffsetLow);
}
VOID
FORCEINLINE
KiSendEOI()
{
/* Write 0 to the apic EOI register */
*((volatile ULONG*)APIC_EOI_REGISTER) = 0;
}
VOID
FORCEINLINE
KiEndInterrupt(IN KIRQL Irql,
@ -240,6 +261,7 @@ KiEndInterrupt(IN KIRQL Irql,
{
/* Make sure this is from the clock handler */
ASSERT(TrapFrame->ErrorCode == 0xc10c4);
//KeLowerIrql(Irql);
}
BOOLEAN

View file

@ -127,8 +127,8 @@ FORCEINLINE
KIRQL
KiAcquireDispatcherLock(VOID)
{
/* Raise to DPC level */
return KeRaiseIrqlToDpcLevel();
/* Raise to synch level */
return KfRaiseIrql(SYNCH_LEVEL);
}
FORCEINLINE

View file

@ -56,8 +56,11 @@
//
// Identifies a Kernel Handle
//
#define KERNEL_HANDLE_FLAG \
((ULONG_PTR)1 << ((sizeof(HANDLE) * 8) - 1))
#ifdef _WIN64
#define KERNEL_HANDLE_FLAG 0xFFFFFFFF80000000ULL
#else
#define KERNEL_HANDLE_FLAG 0x80000000
#endif
#define ObIsKernelHandle(Handle, ProcessorMode) \
(((ULONG_PTR)(Handle) & KERNEL_HANDLE_FLAG) && \
((ProcessorMode) == KernelMode))

View file

@ -1650,7 +1650,8 @@ IoGetRequestorSessionId(IN PIRP Irp,
/* Return the session */
if ((Process = IoGetRequestorProcess(Irp)))
{
*pSessionId = Process->Session;
// FIXME: broken
*pSessionId = PtrToUlong(Process->Session);
return STATUS_SUCCESS;
}

View file

@ -281,8 +281,9 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
// nonpaged pool expansion (above) and the system PTEs. Note that it is
// then aligned to a PDE boundary (4MB).
//
MiNonPagedSystemSize = (MmNumberOfSystemPtes + 1) * PAGE_SIZE;
MmNonPagedSystemStart = (PVOID)((ULONG_PTR)MmNonPagedPoolStart -
(MmNumberOfSystemPtes + 1) * PAGE_SIZE);
MiNonPagedSystemSize);
MmNonPagedSystemStart = (PVOID)((ULONG_PTR)MmNonPagedSystemStart &
~(PDE_MAPPED_VA - 1));

View file

@ -593,6 +593,12 @@ MmProbeAndLockPages(IN PMDL Mdl,
NTSTATUS ProbeStatus;
PMMPTE PointerPte, LastPte;
PMMPDE PointerPde;
#if (_MI_PAGING_LEVELS >= 3)
PMMPDE PointerPpe;
#endif
#if (_MI_PAGING_LEVELS == 4)
PMMPDE PointerPxe;
#endif
PFN_NUMBER PageFrameIndex;
BOOLEAN UsePfnLock;
KIRQL OldIrql;
@ -741,8 +747,10 @@ MmProbeAndLockPages(IN PMDL Mdl,
PointerPte = MiAddressToPte(StartAddress);
PointerPde = MiAddressToPde(StartAddress);
#if (_MI_PAGING_LEVELS >= 3)
DPRINT1("PAE/x64 Not Implemented\n");
ASSERT(FALSE);
PointerPpe = MiAddressToPpe(StartAddress);
#endif
#if (_MI_PAGING_LEVELS == 4)
PointerPxe = MiAddressToPxe(StartAddress);
#endif
//
@ -776,7 +784,7 @@ MmProbeAndLockPages(IN PMDL Mdl,
//
// Check if this came from kernel mode
//
if (Base >= MM_HIGHEST_USER_ADDRESS)
if (Base > MM_HIGHEST_USER_ADDRESS)
{
//
// We should not have a process
@ -834,11 +842,14 @@ MmProbeAndLockPages(IN PMDL Mdl,
// Assume failure and check for non-mapped pages
//
*MdlPages = LIST_HEAD;
#if (_MI_PAGING_LEVELS >= 3)
/* Should be checking the PPE and PXE */
ASSERT(FALSE);
while (
#if (_MI_PAGING_LEVELS == 4)
(PointerPxe->u.Hard.Valid == 0) ||
#endif
while ((PointerPde->u.Hard.Valid == 0) ||
#if (_MI_PAGING_LEVELS >= 3)
(PointerPpe->u.Hard.Valid == 0) ||
#endif
(PointerPde->u.Hard.Valid == 0) ||
(PointerPte->u.Hard.Valid == 0))
{
//
@ -1042,7 +1053,14 @@ MmProbeAndLockPages(IN PMDL Mdl,
PointerPte++;
/* Check if we're on a PDE boundary */
if (!((ULONG_PTR)PointerPte & (PD_SIZE - 1))) PointerPde++;
if (MiIsPteOnPdeBoundary(PointerPte)) PointerPde++;
#if (_MI_PAGING_LEVELS >= 3)
if (MiIsPteOnPpeBoundary(PointerPte)) PointerPpe++;
#endif
#if (_MI_PAGING_LEVELS == 4)
if (MiIsPteOnPxeBoundary(PointerPte)) PointerPxe++;
#endif
} while (PointerPte <= LastPte);
//

View file

@ -78,6 +78,8 @@
#define PDE_COUNT 1024
#define PTE_COUNT 1024
C_ASSERT(SYSTEM_PD_SIZE == PAGE_SIZE);
#define MiIsPteOnPdeBoundary(PointerPte) \
((((ULONG_PTR)PointerPte) & (PAGE_SIZE - 1)) == 0)
#elif _M_ARM
#define PD_COUNT 1
#define PDE_COUNT 4096
@ -164,7 +166,7 @@ C_ASSERT(SYSTEM_PD_SIZE == PAGE_SIZE);
#error Define these please!
#endif
extern const ULONG MmProtectToPteMask[32];
extern const ULONG_PTR MmProtectToPteMask[32];
extern const ULONG MmProtectToValue[32];
//
@ -262,7 +264,11 @@ extern const ULONG MmProtectToValue[32];
//
// Prototype PTEs that don't yet have a pagefile association
//
#ifdef _M_AMD64
#define MI_PTE_LOOKUP_NEEDED 0xffffffffULL
#else
#define MI_PTE_LOOKUP_NEEDED 0xFFFFF
#endif
//
// System views are binned into 64K chunks
@ -444,6 +450,7 @@ extern SIZE_T MmMaximumNonPagedPoolInBytes;
extern PFN_NUMBER MmMaximumNonPagedPoolInPages;
extern PFN_NUMBER MmSizeOfPagedPoolInPages;
extern PVOID MmNonPagedSystemStart;
extern SIZE_T MiNonPagedSystemSize;
extern PVOID MmNonPagedPoolStart;
extern PVOID MmNonPagedPoolExpansionStart;
extern PVOID MmNonPagedPoolEnd;
@ -1379,7 +1386,14 @@ MiRemoveZeroPageSafe(IN ULONG Color)
//
// New ARM3<->RosMM PAGE Architecture
//
#ifdef _WIN64
// HACK ON TOP OF HACK ALERT!!!
#define MI_GET_ROS_DATA(x) \
(((x)->RosMmData == 0) ? NULL : ((PMMROSPFN)((ULONG64)(ULONG)((x)->RosMmData) | \
((ULONG64)MmNonPagedPoolStart & 0xffffffff00000000ULL))))
#else
#define MI_GET_ROS_DATA(x) ((PMMROSPFN)(x->RosMmData))
#endif
#define MI_IS_ROS_PFN(x) (((x)->u4.AweAllocation == TRUE) && (MI_GET_ROS_DATA(x) != NULL))
#define ASSERT_IS_ROS_PFN(x) ASSERT(MI_IS_ROS_PFN(x) == TRUE);
typedef struct _MMROSPFN

View file

@ -93,6 +93,7 @@ ULONG MmMaxAdditionNonPagedPoolPerMb = 400 * 1024;
// http://www.ditii.com/2007/09/28/windows-memory-management-x86-virtual-address-space/
//
PVOID MmNonPagedSystemStart;
SIZE_T MiNonPagedSystemSize;
PVOID MmNonPagedPoolStart;
PVOID MmNonPagedPoolExpansionStart;
PVOID MmNonPagedPoolEnd = MI_NONPAGED_POOL_END;

View file

@ -913,7 +913,7 @@ MiInitializeWorkingSetList(IN PEPROCESS CurrentProcess)
MmWorkingSetList->LastInitializedWsle = 4;
/* The rule is that the owner process is always in the FLINK of the PDE's PFN entry */
Pfn1 = MiGetPfnEntry(MiAddressToPte(PDE_BASE)->u.Hard.PageFrameNumber);
Pfn1 = MiGetPfnEntry(CurrentProcess->Pcb.DirectoryTableBase[0] >> PAGE_SHIFT);
ASSERT(Pfn1->u4.PteFrame == MiGetPfnEntryIndex(Pfn1));
Pfn1->u1.Event = (PKEVENT)CurrentProcess;
}
@ -963,13 +963,23 @@ MmInitializeProcessAddressSpace(IN PEPROCESS Process,
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* Setup the PFN for the PDE base of this process */
#ifdef _M_AMD64
PointerPte = MiAddressToPte(PXE_BASE);
#else
PointerPte = MiAddressToPte(PDE_BASE);
#endif
PageFrameNumber = PFN_FROM_PTE(PointerPte);
ASSERT(Process->Pcb.DirectoryTableBase[0] == PageFrameNumber * PAGE_SIZE);
MiInitializePfn(PageFrameNumber, PointerPte, TRUE);
/* Do the same for hyperspace */
#ifdef _M_AMD64
PointerPde = MiAddressToPxe((PVOID)HYPER_SPACE);
#else
PointerPde = MiAddressToPde(HYPER_SPACE);
#endif
PageFrameNumber = PFN_FROM_PTE(PointerPde);
//ASSERT(Process->Pcb.DirectoryTableBase[0] == PageFrameNumber * PAGE_SIZE); // we're not lucky
MiInitializePfn(PageFrameNumber, (PMMPTE)PointerPde, TRUE);
/* Setup the PFN for the PTE for the working set */

View file

@ -261,7 +261,7 @@ MmAllocateSpecialPool(SIZE_T NumberOfBytes, ULONG Tag, POOL_TYPE PoolType, ULONG
RtlZeroMemory(Header, sizeof(POOL_HEADER));
/* Save allocation size there */
Header->Ulong1 = NumberOfBytes;
Header->Ulong1 = (ULONG)NumberOfBytes;
/* Make sure it's all good */
ASSERT((NumberOfBytes <= PAGE_SIZE - sizeof(POOL_HEADER)) &&
@ -286,7 +286,7 @@ MmAllocateSpecialPool(SIZE_T NumberOfBytes, ULONG Tag, POOL_TYPE PoolType, ULONG
That time will be used to check memory consistency within the allocated
page. */
Header->PoolTag = Tag;
Header->BlockSize = TickCount.LowPart;
Header->BlockSize = (USHORT)TickCount.LowPart;
DPRINT1("%p\n", Entry);
return Entry;
}
@ -305,7 +305,7 @@ MiSpecialPoolCheckPattern(PUCHAR P, PPOOL_HEADER Header)
Ptr = P + BytesRequested;
/* Calculate how many bytes to check */
BytesToCheck = (PUCHAR)PAGE_ALIGN(P) + PAGE_SIZE - Ptr;
BytesToCheck = (ULONG)((PUCHAR)PAGE_ALIGN(P) + PAGE_SIZE - Ptr);
/* Remove pool header size if we're catching underruns */
if (((ULONG_PTR)P & (PAGE_SIZE - 1)) == 0)
@ -335,7 +335,7 @@ MmFreeSpecialPool(PVOID P)
KIRQL Irql = KeGetCurrentIrql();
POOL_TYPE PoolType;
ULONG BytesRequested, BytesReal = 0;
ULONG_PTR PtrOffset;
ULONG PtrOffset;
PUCHAR b;
PMI_FREED_SPECIAL_POOL FreedHeader;
LARGE_INTEGER TickCount;
@ -358,7 +358,7 @@ MmFreeSpecialPool(PVOID P)
}
/* Determine if it's a underruns or overruns pool pointer */
PtrOffset = (ULONG_PTR)P & (PAGE_SIZE - 1);
PtrOffset = (ULONG)((ULONG_PTR)P & (PAGE_SIZE - 1));
if (PtrOffset)
{
/* Pool catches overruns */

View file

@ -165,7 +165,8 @@ NtAssignProcessToJobObject (
ExAcquireRundownProtection(&Process->RundownProtect);
if(NT_SUCCESS(Status))
{
if(Process->Job == NULL && Process->Session == Job->SessionId)
// FIXME: This is broken
if(Process->Job == NULL && PtrToUlong(Process->Session) == Job->SessionId)
{
/* Just store the pointer to the job object in the process, we'll
assign it later. The reason we can't do this here is that locking
@ -269,7 +270,7 @@ NtCreateJobObject (
/* setup the job object */
InitializeListHead(&Job->ProcessListHead);
Job->SessionId = CurrentProcess->Session; /* inherit the session id from the caller */
Job->SessionId = PtrToUlong(CurrentProcess->Session); /* inherit the session id from the caller, FIXME: broken */
Status = ExInitializeResource(&Job->JobLock);
if(!NT_SUCCESS(Status))

View file

@ -1113,7 +1113,8 @@ ULONG
NTAPI
PsGetCurrentProcessSessionId(VOID)
{
return PsGetCurrentProcess()->Session;
// FIXME: this is broken!
return PtrToUlong(PsGetCurrentProcess()->Session);
}
/*

View file

@ -419,7 +419,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
_SEH2_TRY
{
/* Write back the Session ID */
SessionInfo->SessionId = Process->Session; //MmGetSessionId(Process);
SessionInfo->SessionId = PtrToUlong(PsGetProcessSessionId(Process));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{