Somehow missed this in previous commit

svn path=/trunk/; revision=69540
This commit is contained in:
Stefan Ginsberg 2015-10-15 12:58:28 +00:00
parent 8ea1ea856d
commit 415eda607f

View file

@ -21,6 +21,12 @@
#define KdpDprintf(...) #define KdpDprintf(...)
#endif #endif
BOOLEAN
NTAPI
MmIsSessionAddress(
IN PVOID Address
);
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
PVOID MiDebugMapping = MI_DEBUG_MAPPING; PVOID MiDebugMapping = MI_DEBUG_MAPPING;
@ -28,16 +34,6 @@ PMMPTE MmDebugPte = NULL;
/* FUNCTIONS ******************************************************************/ /* FUNCTIONS ******************************************************************/
BOOLEAN
NTAPI
MmIsSessionAddress(IN PVOID Address)
{
//
// No session space support yet
//
return FALSE;
}
PVOID PVOID
NTAPI NTAPI
MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress, MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress,
@ -47,78 +43,59 @@ MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress,
MMPTE TempPte; MMPTE TempPte;
PVOID MappingBaseAddress; PVOID MappingBaseAddress;
// /* Check if we are called too early */
// Check if we are called too early
//
if (MmDebugPte == NULL) if (MmDebugPte == NULL)
{ {
// /* The structures we require aren't initialized yet, fail */
// The structures we require aren't initialized yet, fail
//
KdpDprintf("MiDbgTranslatePhysicalAddress called too early! " KdpDprintf("MiDbgTranslatePhysicalAddress called too early! "
"Address: 0x%I64x\n", PhysicalAddress); "Address: 0x%I64x\n",
PhysicalAddress);
return NULL; return NULL;
} }
// /* FIXME: No support for cache flags yet */
// FIXME: No support for cache flags yet
//
if ((Flags & (MMDBG_COPY_CACHED | if ((Flags & (MMDBG_COPY_CACHED |
MMDBG_COPY_UNCACHED | MMDBG_COPY_UNCACHED |
MMDBG_COPY_WRITE_COMBINED)) != 0) MMDBG_COPY_WRITE_COMBINED)) != 0)
{ {
// /* Fail */
// Fail KdpDprintf("MiDbgTranslatePhysicalAddress: Cache flags not yet supported. "
// "Flags: 0x%lx\n",
KdpDprintf("MiDbgTranslatePhysicalAddress: Cache Flags not yet supported. " Flags & (MMDBG_COPY_CACHED |
"Flags: 0x%lx\n", Flags & (MMDBG_COPY_CACHED | MMDBG_COPY_UNCACHED |
MMDBG_COPY_UNCACHED | MMDBG_COPY_WRITE_COMBINED));
MMDBG_COPY_WRITE_COMBINED));
return NULL; return NULL;
} }
// /* Save the base address of our mapping page */
// Save the base address of our mapping page
//
MappingBaseAddress = MiPteToAddress(MmDebugPte); MappingBaseAddress = MiPteToAddress(MmDebugPte);
// /* Get the template */
// Get the template
//
TempPte = ValidKernelPte; TempPte = ValidKernelPte;
// /* Convert physical address to PFN */
// Convert physical address to PFN
//
Pfn = (PFN_NUMBER)(PhysicalAddress >> PAGE_SHIFT); Pfn = (PFN_NUMBER)(PhysicalAddress >> PAGE_SHIFT);
/* Check if this could be an I/O mapping */ /* Check if this could be an I/O mapping */
if (!MiGetPfnEntry(Pfn)) if (!MiGetPfnEntry(Pfn))
{ {
// /* FIXME: We don't support this yet */
// FIXME: We don't support this yet
//
KdpDprintf("MiDbgTranslatePhysicalAddress: I/O Space not yet supported. " KdpDprintf("MiDbgTranslatePhysicalAddress: I/O Space not yet supported. "
"PFN: 0x%I64x\n", (ULONG64)Pfn); "PFN: 0x%I64x\n",
(ULONG64)Pfn);
return NULL; return NULL;
} }
else else
{ {
// /* Set the PFN in the PTE */
// Set the PFN in the PTE
//
TempPte.u.Hard.PageFrameNumber = Pfn; TempPte.u.Hard.PageFrameNumber = Pfn;
} }
// /* Map the PTE and invalidate its TLB entry */
// Map the PTE and invalidate its TLB entry
//
*MmDebugPte = TempPte; *MmDebugPte = TempPte;
KeInvalidateTlbEntry(MappingBaseAddress); KeInvalidateTlbEntry(MappingBaseAddress);
// /* Calculate and return the virtual offset into our mapping page */
// Calculate and return the virtual offset into our mapping page
//
return (PVOID)((ULONG_PTR)MappingBaseAddress + return (PVOID)((ULONG_PTR)MappingBaseAddress +
BYTE_OFFSET(PhysicalAddress)); BYTE_OFFSET(PhysicalAddress));
} }
@ -127,20 +104,23 @@ VOID
NTAPI NTAPI
MiDbgUnTranslatePhysicalAddress(VOID) MiDbgUnTranslatePhysicalAddress(VOID)
{ {
PVOID MappingBaseAddress = MiPteToAddress(MmDebugPte); PVOID MappingBaseAddress;
// /* The address must still be valid at this point */
// The address must still be valid at this point MappingBaseAddress = MiPteToAddress(MmDebugPte);
//
ASSERT(MmIsAddressValid(MappingBaseAddress)); ASSERT(MmIsAddressValid(MappingBaseAddress));
// /* Clear the mapping PTE and invalidate its TLB entry */
// Clear the mapping PTE and invalidate its TLB entry
//
MmDebugPte->u.Long = 0; MmDebugPte->u.Long = 0;
KeInvalidateTlbEntry(MappingBaseAddress); KeInvalidateTlbEntry(MappingBaseAddress);
} }
//
// We handle 8-byte requests at most
//
C_ASSERT(MMDBG_COPY_MAX_SIZE == 8);
NTSTATUS NTSTATUS
NTAPI NTAPI
MmDbgCopyMemory(IN ULONG64 Address, MmDbgCopyMemory(IN ULONG64 Address,
@ -148,102 +128,80 @@ MmDbgCopyMemory(IN ULONG64 Address,
IN ULONG Size, IN ULONG Size,
IN ULONG Flags) IN ULONG Flags)
{ {
NTSTATUS Status;
PVOID TargetAddress; PVOID TargetAddress;
ULONG64 PhysicalAddress; ULONG64 PhysicalAddress;
PMMPTE PointerPte; PMMPTE PointerPte;
PVOID CopyDestination, CopySource;
// /* No local kernel debugging support yet, so don't worry about locking */
// No local kernel debugging support yet, so don't worry about locking
//
ASSERT(Flags & MMDBG_COPY_UNSAFE); ASSERT(Flags & MMDBG_COPY_UNSAFE);
// /* We only handle 1, 2, 4 and 8 byte requests */
// We only handle 1, 2, 4 and 8 byte requests
//
if ((Size != 1) && if ((Size != 1) &&
(Size != 2) && (Size != 2) &&
(Size != 4) && (Size != 4) &&
(Size != MMDBG_COPY_MAX_SIZE)) (Size != 8))
{ {
// /* Invalid size, fail */
// Invalid size, fail KdpDprintf("MmDbgCopyMemory: Received Illegal Size 0x%lx\n",
// Size);
KdpDprintf("MmDbgCopyMemory: Received Illegal Size 0x%lx\n", Size);
return STATUS_INVALID_PARAMETER_3; return STATUS_INVALID_PARAMETER_3;
} }
// /* The copy must be aligned */
// The copy must be aligned
//
if ((Address & (Size - 1)) != 0) if ((Address & (Size - 1)) != 0)
{ {
// /* Not allowing unaligned access */
// Fail
//
KdpDprintf("MmDbgCopyMemory: Received Unaligned Address 0x%I64x Size %lx\n", KdpDprintf("MmDbgCopyMemory: Received Unaligned Address 0x%I64x Size %lx\n",
Address, Size); Address,
Size);
return STATUS_INVALID_PARAMETER_3; return STATUS_INVALID_PARAMETER_3;
} }
// /* Check for physical or virtual copy */
// Check if this is physical or virtual copy
//
if (Flags & MMDBG_COPY_PHYSICAL) if (Flags & MMDBG_COPY_PHYSICAL)
{ {
// /* Physical: translate and map it to our mapping space */
// Physical: translate and map it to our mapping space TargetAddress = MiDbgTranslatePhysicalAddress(Address,
// Flags);
TargetAddress = MiDbgTranslatePhysicalAddress(Address, Flags);
// /* Check if translation failed */
// Check if translation failed
//
if (!TargetAddress) if (!TargetAddress)
{ {
// /* Fail */
// Fail KdpDprintf("MmDbgCopyMemory: Failed to Translate Physical Address %I64x\n",
// Address);
KdpDprintf("MmDbgCopyMemory: Failed to Translate Physical Address "
"%I64x\n", Address);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
// /* The address we received must be valid! */
// The address we received must be valid!
//
ASSERT(MmIsAddressValid(TargetAddress)); ASSERT(MmIsAddressValid(TargetAddress));
} }
else else
{ {
// /* Virtual; truncate it to avoid casts later down */
// Virtual; truncate it to avoid casts later down
//
TargetAddress = (PVOID)(ULONG_PTR)Address; TargetAddress = (PVOID)(ULONG_PTR)Address;
// /* Make sure address is valid */
// Check if the address is invalid
//
if (!MmIsAddressValid(TargetAddress)) if (!MmIsAddressValid(TargetAddress))
{ {
// /* Fail */
// Fail KdpDprintf("MmDbgCopyMemory: Failing %s for invalid Virtual Address 0x%p\n",
//
KdpDprintf("MmDbgCopyMemory: Failing %s for invalid "
"Virtual Address 0x%p\n",
Flags & MMDBG_COPY_WRITE ? "write" : "read", Flags & MMDBG_COPY_WRITE ? "write" : "read",
TargetAddress); TargetAddress);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
// /* Not handling session space correctly yet */
// No session space support yet if (MmIsSessionAddress(TargetAddress))
// {
ASSERT(MmIsSessionAddress(TargetAddress) == FALSE); /* FIXME */
}
/* If we are going to write to the address, then check if its writable */ /* If we are going to write to the address, then check if its writable */
PointerPte = MiAddressToPte(TargetAddress); PointerPte = MiAddressToPte(TargetAddress);
if ((Flags & MMDBG_COPY_WRITE) && !MI_IS_PAGE_WRITEABLE(PointerPte)) if ((Flags & MMDBG_COPY_WRITE) &&
(!MI_IS_PAGE_WRITEABLE(PointerPte)))
{ {
/* Not writable, we need to do a physical copy */ /* Not writable, we need to do a physical copy */
Flags |= MMDBG_COPY_PHYSICAL; Flags |= MMDBG_COPY_PHYSICAL;
@ -253,73 +211,73 @@ MmDbgCopyMemory(IN ULONG64 Address,
PhysicalAddress += BYTE_OFFSET(Address); PhysicalAddress += BYTE_OFFSET(Address);
/* Translate the physical address */ /* Translate the physical address */
TargetAddress = MiDbgTranslatePhysicalAddress(PhysicalAddress, Flags); TargetAddress = MiDbgTranslatePhysicalAddress(PhysicalAddress,
Flags);
/* Check if translation failed */ /* Check if translation failed */
if (!TargetAddress) if (!TargetAddress)
{ {
/* Fail */ /* Fail */
KdpDprintf("MmDbgCopyMemory: Failed to translate for write " KdpDprintf("MmDbgCopyMemory: Failed to translate for write %I64x (%I64x)\n",
"%I64x (%I64x)\n", PhysicalAddress, Address); PhysicalAddress,
Address);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
} }
} }
// /* Check what kind of operation this is */
// Use SEH to try to catch anything else somewhat cleanly if (Flags & MMDBG_COPY_WRITE)
//
_SEH2_TRY
{ {
// /* Write */
// Check if this is read or write CopyDestination = TargetAddress;
// CopySource = Buffer;
if (Flags & MMDBG_COPY_WRITE)
{
//
// Do the write
//
RtlCopyMemory(TargetAddress,
Buffer,
Size);
}
else
{
//
// Do the read
//
RtlCopyMemory(Buffer,
TargetAddress,
Size);
}
//
// Copy succeeded
//
Status = STATUS_SUCCESS;
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) else
{ {
// /* Read */
// Get the exception code CopyDestination = Buffer;
// CopySource = TargetAddress;
Status = _SEH2_GetExceptionCode();
} }
_SEH2_END;
// /* Do the copy */
// Get rid of the mapping if this was a physical copy switch (Size)
// {
case 1:
/* 1 byte */
*(PUCHAR)CopyDestination = *(PUCHAR)CopySource;
break;
case 2:
/* 2 bytes */
*(PUSHORT)CopyDestination = *(PUSHORT)CopySource;
break;
case 4:
/* 4 bytes */
*(PULONG)CopyDestination = *(PULONG)CopySource;
break;
case 8:
/* 8 bytes */
*(PULONGLONG)CopyDestination = *(PULONGLONG)CopySource;
break;
/* Size is sanitized above */
DEFAULT_UNREACHABLE;
}
/* Get rid of the mapping if this was a physical copy */
if (Flags & MMDBG_COPY_PHYSICAL) if (Flags & MMDBG_COPY_PHYSICAL)
{ {
// /* Unmap and flush it */
// Unmap and flush it
//
MiDbgUnTranslatePhysicalAddress(); MiDbgUnTranslatePhysicalAddress();
} }
// /* And we are done */
// Return status to caller return STATUS_SUCCESS;
//
return Status;
} }