win-pvdrivers

view xenpci/xenpci_dbgprint.c @ 800:1d06ba3917d2

Unhook dbgprint on unload so we dont crash
author James Harper <james.harper@bendigoit.com.au>
date Thu Jun 24 12:51:23 2010 +1000 (2010-06-24)
parents e723cc352a15
children 4e6f162a054c
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
3 Copyright (C) 2007 James Harper
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
20 #include "xenpci.h"
21 #include <aux_klib.h>
23 #pragma intrinsic(_enable)
24 #pragma intrinsic(_disable)
26 #pragma pack(1)
27 #ifdef _AMD64_
28 typedef struct __KIDT_ENTRY
29 {
30 USHORT addr_0_15;
31 USHORT selector;
32 USHORT access;
33 USHORT addr_16_31;
34 ULONG addr_32_63;
35 ULONG reserved;
36 } IDT_ENTRY, *PIDT_ENTRY;
37 #else
38 typedef struct __KIDT_ENTRY
39 {
40 USHORT addr_0_15;
41 USHORT selector;
42 USHORT access;
43 USHORT addr_16_31;
44 } IDT_ENTRY, *PIDT_ENTRY;
45 #endif
46 #pragma pack()
48 #pragma pack(2)
49 typedef struct _IDT
50 {
51 USHORT limit;
52 PIDT_ENTRY entries;
53 } IDT, *PIDT;
54 #pragma pack()
56 /* Not really necessary but keeps PREfast happy */
57 static KBUGCHECK_CALLBACK_ROUTINE XenPci_BugcheckCallback;
59 KBUGCHECK_CALLBACK_RECORD callback_record;
61 extern VOID Int2dHandlerNew(VOID);
62 extern PVOID Int2dHandlerOld;
64 static VOID
65 XenPci_BugcheckCallback(PVOID buffer, ULONG length)
66 {
67 NTSTATUS status;
68 KBUGCHECK_DATA bugcheck_data;
70 UNREFERENCED_PARAMETER(buffer);
71 UNREFERENCED_PARAMETER(length);
73 bugcheck_data.BugCheckDataSize = sizeof(bugcheck_data);
74 status = AuxKlibGetBugCheckData(&bugcheck_data);
75 if(!NT_SUCCESS(status))
76 {
77 KdPrint((__DRIVER_NAME " AuxKlibGetBugCheckData returned %08x\n", status));
78 return;
79 }
80 KdPrint((__DRIVER_NAME " Bug check 0x%08X (0x%p, 0x%p, 0x%p, 0x%p)\n",
81 bugcheck_data.BugCheckCode, bugcheck_data.Parameter1, bugcheck_data.Parameter2, bugcheck_data.Parameter3, bugcheck_data.Parameter4));
82 }
84 static BOOLEAN debug_port_enabled = FALSE;
85 static volatile LONG debug_print_lock = 0;
87 /* This appears to be called with interrupts disabled already, so no need to go to HIGH_LEVEL or anything like that */
88 static void XenDbgPrint(PCHAR string, ULONG length)
89 {
90 ULONG i;
91 //KIRQL old_irql = 0;
93 while(InterlockedCompareExchange(&debug_print_lock, 1, 0) == 1)
94 KeStallExecutionProcessor(1);
95 for (i = 0; i < length; i++)
96 WRITE_PORT_UCHAR(XEN_IOPORT_LOG, string[i]);
97 /* release the lock */
98 InterlockedExchange(&debug_print_lock, 0);
99 }
101 VOID
102 Int2dHandlerProc(ULONG_PTR dbg_type, PVOID arg2, PVOID arg3, PVOID arg4, PVOID arg5)
103 {
104 CHAR buf[512];
106 switch (dbg_type)
107 {
108 case 1: /* DbgPrint */
109 XenDbgPrint((PCHAR)arg2, (ULONG)(ULONG_PTR)arg3);
110 break;
111 case 2: /* ASSERT */
112 case 3: /* ??? */
113 case 4: /* ??? */
114 break;
115 default:
116 RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "*** %d %08x %08x %08x %08x\n", dbg_type, arg2, arg3, arg4, arg5);
117 XenDbgPrint(buf, (ULONG)strlen(buf));
118 break;
119 }
120 return;
121 }
123 static VOID
124 XenPci_DbgPrintCallback(PSTRING output, ULONG component_id, ULONG level)
125 {
126 UNREFERENCED_PARAMETER(component_id);
127 UNREFERENCED_PARAMETER(level);
129 XenDbgPrint(output->Buffer, output->Length);
130 }
132 #if 0
133 typedef struct _hook_info {
134 PIDT_ENTRY idt_entry;
135 } hook_info_t;
136 #endif
138 #if (NTDDI_VERSION < NTDDI_VISTA)
139 #ifndef _AMD64_ // can't patch IDT on AMD64 unfortunately - results in bug check 0x109
140 static VOID
141 XenPci_HookDbgPrint_High(PVOID context)
142 {
143 IDT idt;
144 PIDT_ENTRY idt_entry;
146 UNREFERENCED_PARAMETER(context);
148 idt.limit = 0;
149 __sidt(&idt);
150 idt_entry = &idt.entries[0x2D];
151 #ifdef _AMD64_
152 Int2dHandlerOld = (PVOID)((ULONG_PTR)idt_entry->addr_0_15 | ((ULONG_PTR)idt_entry->addr_16_31 << 16) | ((ULONG_PTR)idt_entry->addr_32_63 << 32));
153 #else
154 Int2dHandlerOld = (PVOID)((ULONG_PTR)idt_entry->addr_0_15 | ((ULONG_PTR)idt_entry->addr_16_31 << 16));
155 #endif
156 idt_entry->addr_0_15 = (USHORT)(ULONG_PTR)Int2dHandlerNew;
157 idt_entry->addr_16_31 = (USHORT)((ULONG_PTR)Int2dHandlerNew >> 16);
158 #ifdef _AMD64_
159 idt_entry->addr_32_63 = (ULONG)((ULONG_PTR)Int2dHandlerNew >> 32);
160 #endif
161 }
163 static VOID
164 XenPci_UnHookDbgPrint_High(PVOID context)
165 {
166 IDT idt;
167 PIDT_ENTRY idt_entry;
169 UNREFERENCED_PARAMETER(context);
171 idt.limit = 0;
172 __sidt(&idt);
173 idt_entry = &idt.entries[0x2D];
174 idt_entry->addr_0_15 = (USHORT)(ULONG_PTR)Int2dHandlerOld;
175 idt_entry->addr_16_31 = (USHORT)((ULONG_PTR)Int2dHandlerOld >> 16);
176 #ifdef _AMD64_
177 idt_entry->addr_32_63 = (ULONG)((ULONG_PTR)Int2dHandlerOld >> 32);
178 #endif
179 }
180 #endif
181 #endif
183 NTSTATUS
184 XenPci_HookDbgPrint()
185 {
186 NTSTATUS status = STATUS_SUCCESS;
188 if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2
189 || READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0xd249)
190 {
191 //#pragma warning(suppress:4055)
192 //DbgSetDebugPrintCallback = (PDBG_SET_DEBUGPRINT_CALLBACK)MmGetSystemRoutineAddress((PUNICODE_STRING)&DbgSetDebugPrintCallbackName);
193 #if (NTDDI_VERSION >= NTDDI_VISTA)
194 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback found\n"));
195 status = DbgSetDebugPrintCallback(XenPci_DbgPrintCallback, TRUE);
196 if (!NT_SUCCESS(status))
197 {
198 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback failed - %08x\n", status));
199 }
200 //DbgSetDebugFilterState(componentid, level, state);
201 DbgSetDebugFilterState(DPFLTR_DEFAULT_ID, 0xFFFFFFFF, TRUE);
202 #else
203 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback not found\n"));
204 #ifndef _AMD64_ // can't patch IDT on AMD64 unfortunately - results in bug check 0x109
205 XenPci_HighSync(XenPci_HookDbgPrint_High, XenPci_HookDbgPrint_High, NULL);
206 #endif
207 #endif
208 }
209 else
210 {
211 status = STATUS_UNSUCCESSFUL;
212 }
214 KeInitializeCallbackRecord(&callback_record);
215 if (!KeRegisterBugCheckCallback(&callback_record, XenPci_BugcheckCallback, NULL, 0, (PUCHAR)"XenPci"))
216 {
217 KdPrint((__DRIVER_NAME " KeRegisterBugCheckCallback failed\n"));
218 status = STATUS_UNSUCCESSFUL;
219 }
221 return status;
222 }
224 NTSTATUS
225 XenPci_UnHookDbgPrint()
226 {
227 NTSTATUS status = STATUS_SUCCESS;
229 if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2
230 || READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0xd249)
231 {
232 //#pragma warning(suppress:4055)
233 //DbgSetDebugPrintCallback = (PDBG_SET_DEBUGPRINT_CALLBACK)MmGetSystemRoutineAddress((PUNICODE_STRING)&DbgSetDebugPrintCallbackName);
234 #if (NTDDI_VERSION >= NTDDI_VISTA)
235 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback found\n"));
236 status = DbgSetDebugPrintCallback(XenPci_DbgPrintCallback, FALSE);
237 if (!NT_SUCCESS(status))
238 {
239 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback failed - %08x\n", status));
240 }
241 //DbgSetDebugFilterState(componentid, level, state);
242 //DbgSetDebugFilterState(DPFLTR_DEFAULT_ID, 0xFFFFFFFF, TRUE);
243 #else
244 KdPrint((__DRIVER_NAME " DbgSetDebugPrintCallback not found\n"));
245 #ifndef _AMD64_ // can't patch IDT on AMD64 unfortunately - results in bug check 0x109
246 XenPci_HighSync(XenPci_UnHookDbgPrint_High, XenPci_UnHookDbgPrint_High, NULL);
247 #endif
248 #endif
249 }
250 else
251 {
252 status = STATUS_UNSUCCESSFUL;
253 }
255 if (!KeDeregisterBugCheckCallback(&callback_record))
256 {
257 KdPrint((__DRIVER_NAME " KeDeregisterBugCheckCallback failed\n"));
258 status = STATUS_UNSUCCESSFUL;
259 }
261 return status;
262 }