ReactOS  r76032
kdmemsup.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Kernel
4  * FILE: ntoskrnl/kd/amd64/kdmemsup.c
5  * PURPOSE: Kernel Debugger Safe Memory Support
6  *
7  * PROGRAMMERS: arty
8  */
9 
10 #include <ntoskrnl.h>
11 #define NDEBUG
12 #include <debug.h>
13 
14 #define HIGH_PHYS_MASK 0x80000000
15 #define PAGE_TABLE_MASK 0x3ff
16 #define BIG_PAGE_SIZE (1<<22)
17 #define CR4_PAGE_SIZE_BIT 0x10
18 #define PDE_PRESENT_BIT 0x01
19 #define PDE_W_BIT 0x02
20 #define PDE_PWT_BIT 0x08
21 #define PDE_PCD_BIT 0x10
22 #define PDE_ACCESSED_BIT 0x20
23 #define PDE_DIRTY_BIT 0x40
24 #define PDE_PS_BIT 0x80
25 
26 #define MI_KDBG_TMP_PAGE_1 (HYPER_SPACE + 0x400000 - PAGE_SIZE)
27 #define MI_KDBG_TMP_PAGE_0 (MI_KDBG_TMP_PAGE_1 - PAGE_SIZE)
28 
29 /* VARIABLES ***************************************************************/
30 
32 
33 static
36 {
37  MMPTE TempPte;
38  PMMPTE PointerPte;
39  ULONG_PTR VirtAddr;
40 
43 
44  if ((PhysAddr & (PAGE_SIZE - 1)) + Len > PAGE_SIZE)
45  {
46  TempPte.u.Hard.PageFrameNumber = (PhysAddr >> PAGE_SHIFT) + 1;
48  *PointerPte = TempPte;
49  VirtAddr = (ULONG_PTR)PointerPte << 10;
50  KeInvalidateTlbEntry((PVOID)VirtAddr);
51  }
52 
53  TempPte.u.Hard.PageFrameNumber = PhysAddr >> PAGE_SHIFT;
55  *PointerPte = TempPte;
56  VirtAddr = (ULONG_PTR)PointerPte << 10;
57  KeInvalidateTlbEntry((PVOID)VirtAddr);
58 
59  return VirtAddr + (PhysAddr & (PAGE_SIZE - 1));
60 }
61 
62 static
65 {
66  ULONG_PTR Addr;
67  ULONGLONG Result = 0;
68 
69  Addr = KdpPhysMap(PhysAddr, Len);
70 
71  switch (Len)
72  {
73  case 8:
74  Result = *((PULONGLONG)Addr);
75  break;
76  case 4:
77  Result = *((PULONG)Addr);
78  break;
79  case 2:
80  Result = *((PUSHORT)Addr);
81  break;
82  case 1:
83  Result = *((PUCHAR)Addr);
84  break;
85  }
86 
87  return Result;
88 }
89 
90 static
91 VOID
93 {
94  ULONG_PTR Addr;
95 
96  Addr = KdpPhysMap(PhysAddr, Len);
97 
98  switch (Len)
99  {
100  case 8:
101  *((PULONGLONG)Addr) = Value;
102  break;
103  case 4:
104  *((PULONG)Addr) = Value;
105  break;
106  case 2:
107  *((PUSHORT)Addr) = Value;
108  break;
109  case 1:
110  *((PUCHAR)Addr) = Value;
111  break;
112  }
113 }
114 
115 BOOLEAN
116 NTAPI
118 {
119  ULONG_PTR CR3Value = __readcr3();
120  ULONG_PTR CR4Value = __readcr4();
121  ULONG_PTR PageDirectory = (CR3Value & ~(PAGE_SIZE-1)) +
122  ((Addr >> 22) * sizeof(ULONG));
123  ULONG_PTR PageDirectoryEntry = KdpPhysRead(PageDirectory, sizeof(ULONG));
124 
125  /* Not present -> fail */
126  if (!(PageDirectoryEntry & PDE_PRESENT_BIT))
127  {
128  return FALSE;
129  }
130 
131  /* Big Page? */
132  if ((PageDirectoryEntry & PDE_PS_BIT) && (CR4Value & CR4_PAGE_SIZE_BIT))
133  {
134  *ResultAddr = (PageDirectoryEntry & ~(BIG_PAGE_SIZE-1)) +
135  (Addr & (BIG_PAGE_SIZE-1));
136  return TRUE;
137  }
138  else
139  {
140  ULONG_PTR PageTableAddr =
141  (PageDirectoryEntry & ~(PAGE_SIZE-1)) +
142  ((Addr >> PAGE_SHIFT) & PAGE_TABLE_MASK) * sizeof(ULONG);
143  ULONG_PTR PageTableEntry = KdpPhysRead(PageTableAddr, sizeof(ULONG));
144  if (PageTableEntry & PDE_PRESENT_BIT)
145  {
146  *ResultAddr = (PageTableEntry & ~(PAGE_SIZE-1)) +
147  (Addr & (PAGE_SIZE-1));
148  return TRUE;
149  }
150  }
151 
152  return FALSE;
153 }
154 
155 BOOLEAN
156 NTAPI
158 {
159  ULONG_PTR ResultPhysAddr;
160 
161  if (!KdpPhysAccess)
162  {
163  memcpy(Value, (PVOID)Addr, Len);
164  return TRUE;
165  }
166 
167  memset(Value, 0, Len);
168 
169  if (!KdpTranslateAddress(Addr, &ResultPhysAddr))
170  return FALSE;
171 
172  switch (Len)
173  {
174  case 8:
175  *((PULONGLONG)Value) = KdpPhysRead(ResultPhysAddr, Len);
176  break;
177  case 4:
178  *((PULONG)Value) = KdpPhysRead(ResultPhysAddr, Len);
179  break;
180  case 2:
181  *((PUSHORT)Value) = KdpPhysRead(ResultPhysAddr, Len);
182  break;
183  case 1:
184  *((PUCHAR)Value) = KdpPhysRead(ResultPhysAddr, Len);
185  break;
186  }
187 
188  return TRUE;
189 }
190 
191 BOOLEAN
192 NTAPI
194 {
195  ULONG_PTR ResultPhysAddr;
196 
197  if (!KdpPhysAccess)
198  {
199  memcpy((PVOID)Addr, &Value, Len);
200  return TRUE;
201  }
202 
203  if (!KdpTranslateAddress(Addr, &ResultPhysAddr))
204  return FALSE;
205 
206  KdpPhysWrite(ResultPhysAddr, Len, Value);
207  return TRUE;
208 }
209 
210 VOID
211 NTAPI
213 {
215 }
216 
217 /* EOF */
DWORD *typedef PVOID
Definition: winlogon.h:52
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define TRUE
Definition: types.h:120
VOID NTAPI KdpEnableSafeMem(VOID)
Definition: kdmemsup.c:212
unsigned char * PUCHAR
Definition: retypes.h:3
BOOLEAN NTAPI KdpSafeWriteMemory(ULONG_PTR Addr, LONG Len, ULONGLONG Value)
Definition: kdmemsup.c:193
#define PDE_ACCESSED_BIT
Definition: kdmemsup.c:22
__INTRIN_INLINE unsigned long __readcr3(void)
Definition: intrin_x86.h:1601
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
uint32_t ULONG_PTR
Definition: typedefs.h:63
BOOLEAN NTAPI KdpSafeReadMemory(ULONG_PTR Addr, LONG Len, PVOID Value)
Definition: kdmemsup.c:157
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define PDE_DIRTY_BIT
Definition: kdmemsup.c:23
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
#define MI_KDBG_TMP_PAGE_0
Definition: kdmemsup.c:27
static BOOLEAN KdpPhysAccess
Definition: kdmemsup.c:31
static ULONG_PTR KdpPhysMap(ULONG_PTR PhysAddr, LONG Len)
Definition: kdmemsup.c:35
BOOLEAN NTAPI KdpTranslateAddress(ULONG_PTR Addr, PULONG_PTR ResultAddr)
Definition: kdmemsup.c:117
unsigned char BOOLEAN
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:177
#define PDE_PS_BIT
Definition: kdmemsup.c:24
#define PAGE_TABLE_MASK
Definition: kdmemsup.c:15
uint64_t ULONGLONG
Definition: typedefs.h:65
unsigned short * PUSHORT
Definition: retypes.h:2
#define Len
Definition: deflate.h:82
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
#define CR4_PAGE_SIZE_BIT
Definition: kdmemsup.c:17
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PDE_W_BIT
Definition: kdmemsup.c:19
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1608
UINTN UINT8 Value
Definition: acefiex.h:751
#define BIG_PAGE_SIZE
Definition: kdmemsup.c:16
ULONG_PTR Long
Definition: mmtypes.h:215
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define PDE_PWT_BIT
Definition: kdmemsup.c:20
unsigned int * PULONG
Definition: retypes.h:1
static VOID KdpPhysWrite(ULONG_PTR PhysAddr, LONG Len, ULONGLONG Value)
Definition: kdmemsup.c:92
#define PDE_PRESENT_BIT
Definition: kdmemsup.c:18
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:382
#define PDE_PCD_BIT
Definition: kdmemsup.c:21
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:63
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
static ULONGLONG KdpPhysRead(ULONG_PTR PhysAddr, LONG Len)
Definition: kdmemsup.c:64
#define MI_KDBG_TMP_PAGE_1
Definition: kdmemsup.c:26
union _MMPTE::@2072 u
#define memset(x, y, z)
Definition: compat.h:39