- Add the MMDBG_COPY_* flags and MmDbgCopyMemory's prototype.

- Add KdpCopyMemoryChunks and use it to handle virtual memory read/write (physical memory support still stubbed). The actual copy is still a hack and its only safeguard against invalid memory is still a simple check for NULL.
- Properly implement KdpReadVirtualMemory, KdpWriteVirtualMemory, KdpReadPhysicalmemory and KdpWritePhysicalmemory using KdpCopyMemoryChunks.
- Merge Timo's ReportFlags fix from the AMD64 branch.
- Implement KdpSysWriteMsr and KdpSysReadMsr for x86. SEH is commented as our GPF handler seems to swallow exceptions caused by accessing invalid MSRs.
- Change DataValue parameter of KdpSysReadIoSpace and KdpSysWriteIoSpace to PVOID to better match how it is used.

svn path=/trunk/; revision=43440
This commit is contained in:
Stefan Ginsberg 2009-10-13 19:45:40 +00:00
parent bfb5499f5c
commit 26a8c4b69a
7 changed files with 278 additions and 92 deletions

View file

@ -374,7 +374,7 @@ KdpSysReadIoSpace(
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PULONG DataValue,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize
);
@ -386,7 +386,7 @@ KdpSysWriteIoSpace(
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PULONG DataValue,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize
);

View file

@ -192,6 +192,29 @@ extern ULONG KiDPCTimeout;
/* INTERNAL KERNEL FUNCTIONS ************************************************/
VOID
NTAPI
CPUID(
IN ULONG InfoType,
OUT PULONG CpuInfoEax,
OUT PULONG CpuInfoEbx,
OUT PULONG CpuInfoEcx,
OUT PULONG CpuInfoEdx
);
LONGLONG
FASTCALL
RDMSR(
IN ULONG Register
);
VOID
NTAPI
WRMSR(
IN ULONG Register,
IN LONGLONG Value
);
/* Finds a new thread to run */
NTSTATUS
FASTCALL
@ -273,16 +296,6 @@ KiSelectNextThread(
IN PKPRCB Prcb
);
VOID
NTAPI
CPUID(
IN ULONG InfoType,
OUT PULONG CpuInfoEax,
OUT PULONG CpuInfoEbx,
OUT PULONG CpuInfoEcx,
OUT PULONG CpuInfoEdx
);
BOOLEAN
FASTCALL
KiInsertTimerTable(
@ -1006,13 +1019,6 @@ VOID
NTAPI
KiI386PentiumLockErrataFixup(VOID);
VOID
NTAPI
WRMSR(
IN ULONG Register,
IN LONGLONG Value
);
BOOLEAN
NTAPI
KeFreezeExecution(IN PKTRAP_FRAME TrapFrame,

View file

@ -30,6 +30,22 @@ struct _MM_PAGEOP;
typedef ULONG SWAPENTRY;
typedef ULONG PFN_TYPE, *PPFN_TYPE;
//
//MmDbgCopyMemory Flags
//
#define MMDBG_COPY_WRITE 0x00000001
#define MMDBG_COPY_PHYSICAL 0x00000002
#define MMDBG_COPY_UNSAFE 0x00000004
#define MMDBG_COPY_CACHED 0x00000008
#define MMDBG_COPY_UNCACHED 0x00000010
#define MMDBG_COPY_WRITE_COMBINED 0x00000020
//
// Maximum chunk size per copy
//
#define MMDBG_COPY_MAX_SIZE 0x8
#define MI_STATIC_MEMORY_AREAS (8)
#define MEMORY_AREA_INVALID (0)
@ -455,6 +471,18 @@ typedef VOID
BOOLEAN Dirty
);
//
// Mm copy support for Kd
//
NTSTATUS
NTAPI
MmDbgCopyMemory(
IN ULONG64 Address,
IN PVOID Buffer,
IN ULONG Size,
IN ULONG Flags
);
/* marea.c *******************************************************************/
NTSTATUS

View file

@ -125,7 +125,7 @@ KdpSysReadIoSpace(IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PULONG DataValue,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize)
{
@ -140,7 +140,7 @@ KdpSysWriteIoSpace(IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PULONG DataValue,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize)
{

View file

@ -125,7 +125,7 @@ KdpSysReadIoSpace(IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PULONG DataValue,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize)
{
@ -140,7 +140,7 @@ KdpSysWriteIoSpace(IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PULONG DataValue,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize)
{

View file

@ -95,7 +95,7 @@ KdpSetContextState(IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange,
WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_SEGS;
if (WaitStateChange->ControlReport.SegCs == KGDT_R0_CODE)
{
WaitStateChange->ControlReport.ReportFlags = REPORT_STANDARD_CS;
WaitStateChange->ControlReport.ReportFlags |= REPORT_STANDARD_CS;
}
}
@ -104,9 +104,21 @@ NTAPI
KdpSysReadMsr(IN ULONG Msr,
OUT PLARGE_INTEGER MsrValue)
{
UNIMPLEMENTED;
while (TRUE);
return STATUS_UNSUCCESSFUL;
/* Wrap this in SEH in case the MSR doesn't exist */
//_SEH2_TRY
{
/* Read from the MSR */
MsrValue->QuadPart = RDMSR(Msr);
}
//_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Invalid MSR */
//_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
}
//_SEH2_END;
/* Success */
return STATUS_SUCCESS;
}
NTSTATUS
@ -114,9 +126,21 @@ NTAPI
KdpSysWriteMsr(IN ULONG Msr,
IN PLARGE_INTEGER MsrValue)
{
UNIMPLEMENTED;
while (TRUE);
return STATUS_UNSUCCESSFUL;
/* Wrap this in SEH in case the MSR doesn't exist */
//_SEH2_TRY
{
/* Write to the MSR */
WRMSR(Msr, MsrValue->QuadPart);
}
//_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Invalid MSR */
//_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
}
//_SEH2_END;
/* Success */
return STATUS_SUCCESS;
}
NTSTATUS
@ -228,7 +252,7 @@ KdpSysReadIoSpace(IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PULONG DataValue,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize)
{
@ -243,7 +267,7 @@ KdpSysWriteIoSpace(IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PULONG DataValue,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize)
{

View file

@ -14,6 +14,76 @@
/* PRIVATE FUNCTIONS *********************************************************/
NTSTATUS
NTAPI
KdpCopyMemoryChunks(IN ULONG64 Address,
IN PVOID Buffer,
IN ULONG TotalSize,
IN ULONG ChunkSize,
IN ULONG Flags,
OUT PULONG ActualSize OPTIONAL)
{
ULONG Length;
NTSTATUS Status;
/* Check if this is physical or virtual copy */
if (Flags & MMDBG_COPY_PHYSICAL)
{
/* Fail physical memory read/write for now */
if (Flags & MMDBG_COPY_WRITE)
{
KdpDprintf("KdpCopyMemoryChunks: Failing write for Physical Address 0x%I64x Length: %x\n",
Address,
TotalSize);
}
else
{
KdpDprintf("KdpCopyMemoryChunks: Failing read for Physical Address 0x%I64x Length: %x\n",
Address,
TotalSize);
}
/* Return an error */
Length = 0;
Status = STATUS_UNSUCCESSFUL;
}
else
{
/* Protect against NULL */
if (!Address)
{
if (ActualSize) *ActualSize = 0;
return STATUS_UNSUCCESSFUL;
}
/* Check if this is read or write */
if (Flags & MMDBG_COPY_WRITE)
{
/* Do the write */
RtlCopyMemory((PVOID)(ULONG_PTR)Address,
Buffer,
TotalSize);
}
else
{
/* Do the read */
RtlCopyMemory(Buffer,
(PVOID)(ULONG_PTR)Address,
TotalSize);
}
/* Set size and status */
Length = TotalSize;
Status = STATUS_SUCCESS;
}
/* Return the actual length if requested */
if (ActualSize) *ActualSize = Length;
/* Return status */
return Status;
}
VOID
NTAPI
KdpQueryMemory(IN PDBGKD_MANIPULATE_STATE64 State,
@ -264,9 +334,14 @@ KdpReadVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State,
IN PSTRING Data,
IN PCONTEXT Context)
{
PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory;
STRING Header;
ULONG Length = State->u.ReadMemory.TransferCount;
NTSTATUS Status = STATUS_SUCCESS;
ULONG Length = ReadMemory->TransferCount;
/* Setup the header */
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
Header.Buffer = (PCHAR)State;
ASSERT(Data->Length == 0);
/* Validate length */
if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64)))
@ -275,35 +350,16 @@ KdpReadVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State,
Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64);
}
#if 0
if (!MmIsAddressValid((PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress))
{
KdpDprintf("Tried to read invalid address %p\n",
(PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress);
while (TRUE);
}
#endif
/* Do the read */
State->ReturnStatus = KdpCopyMemoryChunks(ReadMemory->TargetBaseAddress,
Data->Buffer,
Length,
0,
MMDBG_COPY_UNSAFE,
&Length);
if (!State->u.ReadMemory.TargetBaseAddress)
{
Length = 0;
Status = STATUS_UNSUCCESSFUL;
}
else
{
RtlCopyMemory(Data->Buffer,
(PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress,
Length);
}
/* Fill out the header */
Data->Length = Length;
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
Header.Buffer = (PCHAR)State;
/* Fill out the state */
State->ReturnStatus = Status;
State->u.ReadMemory.ActualBytesRead = Length;
/* Return the actual length read */
Data->Length = ReadMemory->ActualBytesRead = Length;
/* Send the packet */
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
@ -318,11 +374,27 @@ KdpWriteVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State,
IN PSTRING Data,
IN PCONTEXT Context)
{
/* FIXME: STUB */
KdpDprintf("KdpWriteVirtualMemory called for Address: %p Length %x\n",
(PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress,
State->u.ReadMemory.TransferCount);
while (TRUE);
PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory;
STRING Header;
/* Setup the header */
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
Header.Buffer = (PCHAR)State;
/* Do the write */
State->ReturnStatus = KdpCopyMemoryChunks(WriteMemory->TargetBaseAddress,
Data->Buffer,
Data->Length,
0,
MMDBG_COPY_UNSAFE |
MMDBG_COPY_WRITE,
&WriteMemory->ActualBytesWritten);
/* Send the packet */
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
&Header,
NULL,
&KdpContext);
}
VOID
@ -331,20 +403,56 @@ KdpReadPhysicalmemory(IN PDBGKD_MANIPULATE_STATE64 State,
IN PSTRING Data,
IN PCONTEXT Context)
{
PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory;
STRING Header;
ULONG Length = ReadMemory->TransferCount;
ULONG Flags, CacheFlags;
/* FIXME: STUB */
KdpDprintf("KdpWritePhysicalMemory called for Address %I64x Length: %x\n",
State->u.ReadMemory.TargetBaseAddress,
State->u.ReadMemory.TransferCount);
/* Setup an empty message, with failure */
/* Setup the header */
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
Header.Buffer = (PCHAR)State;
Data->Length = 0;
State->ReturnStatus = STATUS_UNSUCCESSFUL;
ASSERT(Data->Length == 0);
/* Send it */
/* Validate length */
if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64)))
{
/* Overflow, set it to maximum possible */
Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64);
}
/* Start with the default flags */
Flags = MMDBG_COPY_UNSAFE | MMDBG_COPY_PHYSICAL;
/* Get the caching flags and check if a type is specified */
CacheFlags = ReadMemory->ActualBytesRead;
if (CacheFlags == DBGKD_CACHING_CACHED)
{
/* Cached */
Flags |= MMDBG_COPY_CACHED;
}
else if (CacheFlags == DBGKD_CACHING_UNCACHED)
{
/* Uncached */
Flags |= MMDBG_COPY_UNCACHED;
}
else if (CacheFlags == DBGKD_CACHING_UNCACHED)
{
/* Write Combined */
Flags |= DBGKD_CACHING_WRITE_COMBINED;
}
/* Do the read */
State->ReturnStatus = KdpCopyMemoryChunks(ReadMemory->TargetBaseAddress,
Data->Buffer,
Length,
0,
Flags,
&Length);
/* Return the actual length read */
Data->Length = ReadMemory->ActualBytesRead = Length;
/* Send the packet */
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
&Header,
Data,
@ -357,23 +465,47 @@ KdpWritePhysicalmemory(IN PDBGKD_MANIPULATE_STATE64 State,
IN PSTRING Data,
IN PCONTEXT Context)
{
PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory;
STRING Header;
ULONG Flags, CacheFlags;
/* FIXME: STUB */
KdpDprintf("KdpWritePhysicalMemory called for Address %I64x Length: %x\n",
State->u.ReadMemory.TargetBaseAddress,
State->u.ReadMemory.TransferCount);
/* Setup an empty message, with failure */
/* Setup the header */
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
Header.Buffer = (PCHAR)State;
Data->Length = 0;
State->ReturnStatus = STATUS_UNSUCCESSFUL;
/* Send it */
/* Start with the default flags */
Flags = MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE | MMDBG_COPY_PHYSICAL;
/* Get the caching flags and check if a type is specified */
CacheFlags = WriteMemory->ActualBytesWritten;
if (CacheFlags == DBGKD_CACHING_CACHED)
{
/* Cached */
Flags |= MMDBG_COPY_CACHED;
}
else if (CacheFlags == DBGKD_CACHING_UNCACHED)
{
/* Uncached */
Flags |= MMDBG_COPY_UNCACHED;
}
else if (CacheFlags == DBGKD_CACHING_UNCACHED)
{
/* Write Combined */
Flags |= DBGKD_CACHING_WRITE_COMBINED;
}
/* Do the write */
State->ReturnStatus = KdpCopyMemoryChunks(WriteMemory->TargetBaseAddress,
Data->Buffer,
Data->Length,
0,
Flags,
&WriteMemory->ActualBytesWritten);
/* Send the packet */
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
&Header,
Data,
NULL,
&KdpContext);
}
@ -425,7 +557,6 @@ KdpWriteControlSpace(IN PDBGKD_MANIPULATE_STATE64 State,
{
PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory;
STRING Header;
ULONG Length;
/* Setup the header */
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
@ -436,10 +567,7 @@ KdpWriteControlSpace(IN PDBGKD_MANIPULATE_STATE64 State,
WriteMemory->TargetBaseAddress,
Data->Buffer,
Data->Length,
&Length);
/* Return the length written */
WriteMemory->ActualBytesWritten = Length;
&WriteMemory->ActualBytesWritten);
/* Send the reply */
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
@ -835,7 +963,7 @@ KdpCheckLowMemory(IN PDBGKD_MANIPULATE_STATE64 State)
Header.Buffer = (PCHAR)State;
/* Call the internal routine */
State->ReturnStatus = KdpSysCheckLowMemory(0x4);
State->ReturnStatus = KdpSysCheckLowMemory(MMDBG_COPY_UNSAFE);
/* Send the reply */
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,