win-pvdrivers

view xenpci/xenpci.h @ 858:fc54b0c09c08

Added better tracking of grant tables for tracking leaks across suspend/resume
author James Harper <james.harper@bendigoit.com.au>
date Sun Feb 27 11:14:02 2011 +1100 (2011-02-27)
parents 2f4e64007b0f
children 95159ee58473
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 #if !defined(_XENPCI_H_)
21 #define _XENPCI_H_
23 #define __attribute__(arg) /* empty */
24 #define EISCONN 127
26 #include <ntifs.h>
27 //#include <ntddk.h>
29 #define DDKAPI
30 //#include <wdm.h>
31 #include <wdf.h>
32 #include <initguid.h>
33 #include <wdmguid.h>
34 #include <errno.h>
35 #define NTSTRSAFE_LIB
36 #include <ntstrsafe.h>
38 #include <liblfds.h>
40 #define __DRIVER_NAME "XenPCI"
42 #include <xen_windows.h>
43 #include <memory.h>
44 #include <grant_table.h>
45 #include <event_channel.h>
46 #include <hvm/params.h>
47 #include <hvm/hvm_op.h>
48 #include <sched.h>
49 #include <io/xenbus.h>
50 #include <io/xs_wire.h>
52 #include <xen_public.h>
54 //{C828ABE9-14CA-4445-BAA6-82C2376C6518}
55 DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC828ABE9, 0x14CA, 0x4445, 0xBA, 0xA6, 0x82, 0xC2, 0x37, 0x6C, 0x65, 0x18);
57 #define XENPCI_POOL_TAG (ULONG) 'XenP'
59 #define NR_RESERVED_ENTRIES 8
60 #define NR_GRANT_FRAMES 32
61 #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
63 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
65 #define EVT_ACTION_TYPE_EMPTY 0
66 #define EVT_ACTION_TYPE_NORMAL 1
67 #define EVT_ACTION_TYPE_DPC 2
68 #define EVT_ACTION_TYPE_IRQ 3
69 #define EVT_ACTION_TYPE_SUSPEND 4
70 #define EVT_ACTION_TYPE_NEW 5 /* setup of event is in progress */
72 #define EVT_ACTION_FLAGS_DEFAULT 0 /* no special flags */
73 #define EVT_ACTION_FLAGS_NO_SUSPEND 1 /* should not be fired on EVT_ACTION_TYPE_SUSPEND event */
76 #define XEN_PV_PRODUCT_NUMBER 0x0002
77 #define XEN_PV_PRODUCT_BUILD 0x00000001
79 extern ULONG qemu_protocol_version;
81 typedef struct _ev_action_t {
82 PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine;
83 PVOID ServiceContext;
84 CHAR description[128];
85 ULONG type; /* EVT_ACTION_TYPE_* */
86 ULONG flags; /* EVT_ACTION_FLAGS_* */
87 KDPC Dpc;
88 ULONG port;
89 ULONG vector;
90 ULONG count;
91 PVOID xpdd;
92 ULONG generation; /* increases each time the event is renewed */
93 } ev_action_t;
95 typedef struct _XENBUS_WATCH_RING
96 {
97 char Path[128];
98 char Token[10];
99 } XENBUS_WATCH_RING;
101 typedef struct xsd_sockmsg xsd_sockmsg_t;
103 typedef struct _XENBUS_WATCH_ENTRY {
104 char Path[128];
105 PXENBUS_WATCH_CALLBACK ServiceRoutine;
106 PVOID ServiceContext;
107 int Count;
108 int Active;
109 } XENBUS_WATCH_ENTRY, *PXENBUS_WATCH_ENTRY;
111 #define NR_EVENTS 1024
112 #define WATCH_RING_SIZE 128
113 #define NR_XB_REQS 32
114 #define MAX_WATCH_ENTRIES 128
116 #define CHILD_STATE_EMPTY 0
117 #define CHILD_STATE_DELETED 1
118 #define CHILD_STATE_ADDED 2
120 #define SUSPEND_STATE_NONE 0 /* no suspend in progress */
121 #define SUSPEND_STATE_SCHEDULED 1 /* suspend scheduled */
122 #define SUSPEND_STATE_HIGH_IRQL 2 /* all processors are at high IRQL and spinning */
123 #define SUSPEND_STATE_RESUMING 3 /* we are the other side of the suspend and things are starting to get back to normal */
125 /* we take some grant refs out and put them aside so that we dont get corrupted by hibernate */
126 #define HIBER_GREF_COUNT 128
128 typedef struct {
129 ULONG generation;
130 ULONG tag;
131 } grant_tag_t;
133 typedef struct {
134 WDFDEVICE wdf_device;
136 BOOLEAN tpr_patched;
138 WDFINTERRUPT interrupt;
139 ULONG irq_number;
140 ULONG irq_vector;
141 KIRQL irq_level;
142 KINTERRUPT_MODE irq_mode;
143 KAFFINITY irq_affinity;
145 PHYSICAL_ADDRESS shared_info_area_unmapped;
146 shared_info_t *shared_info_area;
147 xen_ulong_t evtchn_pending_pvt[MAX_VIRT_CPUS][sizeof(xen_ulong_t) * 8];
148 xen_ulong_t evtchn_pending_suspend[sizeof(xen_ulong_t) * 8];
149 evtchn_port_t pdo_event_channel;
150 KEVENT pdo_suspend_event;
151 BOOLEAN interrupts_masked;
153 PHYSICAL_ADDRESS platform_mmio_addr;
154 ULONG platform_mmio_orig_len;
155 ULONG platform_mmio_len;
156 ULONG platform_mmio_alloc;
157 USHORT platform_mmio_flags;
159 ULONG platform_ioport_addr;
160 ULONG platform_ioport_len;
162 char *hypercall_stubs;
164 evtchn_port_t xen_store_evtchn;
166 /* grant related */
167 struct stack_state *gnttbl_ss;
168 struct stack_state *gnttbl_ss_copy;
169 grant_ref_t hiber_grefs[HIBER_GREF_COUNT];
170 PMDL gnttbl_mdl;
171 grant_entry_t *gnttbl_table;
172 grant_entry_t *gnttbl_table_copy;
173 #if DBG
174 ULONG gnttbl_generation; /* incremented once per save or hibernate */
175 grant_tag_t *gnttbl_tag;
176 grant_tag_t *gnttbl_tag_copy;
177 #endif
178 ULONG grant_frames;
180 ev_action_t ev_actions[NR_EVENTS];
181 // unsigned long bound_ports[NR_EVENTS/(8*sizeof(unsigned long))];
183 BOOLEAN xb_state;
185 struct xenstore_domain_interface *xen_store_interface;
187 #define BALLOON_UNITS (1024 * 1024) /* 1MB */
188 PKTHREAD balloon_thread;
189 KEVENT balloon_event;
190 BOOLEAN balloon_shutdown;
191 ULONG initial_memory;
192 ULONG current_memory;
193 ULONG target_memory;
195 /* xenbus related */
196 XENBUS_WATCH_ENTRY XenBus_WatchEntries[MAX_WATCH_ENTRIES];
197 KSPIN_LOCK xb_ring_spinlock;
198 FAST_MUTEX xb_watch_mutex;
199 FAST_MUTEX xb_request_mutex;
200 KEVENT xb_request_complete_event;
201 struct xsd_sockmsg *xb_reply;
202 struct xsd_sockmsg *xb_msg;
203 ULONG xb_msg_offset;
205 WDFCHILDLIST child_list;
207 KSPIN_LOCK suspend_lock;
208 evtchn_port_t suspend_evtchn;
209 int suspend_state;
211 UNICODE_STRING legacy_interface_name;
212 UNICODE_STRING interface_name;
213 BOOLEAN interface_open;
215 BOOLEAN removable;
217 BOOLEAN hibernated;
219 WDFQUEUE io_queue;
221 //WDFCOLLECTION veto_devices;
222 LIST_ENTRY veto_list;
224 #if 0
225 KSPIN_LOCK mmio_freelist_lock;
226 PPFN_NUMBER mmio_freelist_base;
227 ULONG mmio_freelist_free;
228 #endif
230 } XENPCI_DEVICE_DATA, *PXENPCI_DEVICE_DATA;
232 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_DATA, GetXpdd)
234 typedef struct {
235 UCHAR front_target;
236 UCHAR back_expected;
237 UCHAR wait; /* units = 100ms */
238 } XENPCI_STATE_MAP_ELEMENT, *PXENPCI_STATE_MAP_ELEMENT;
240 typedef struct {
241 WDFDEVICE wdf_device;
242 WDFDEVICE wdf_device_bus_fdo;
243 BOOLEAN reported_missing;
244 char path[128];
245 char device[128];
246 ULONG index;
247 ULONG irq_number;
248 ULONG irq_vector;
249 KIRQL irq_level;
250 char backend_path[128];
251 //PVOID xenbus_request;
252 KEVENT backend_state_event;
253 ULONG backend_state;
254 FAST_MUTEX backend_state_mutex;
255 ULONG frontend_state;
256 PMDL config_page_mdl;
257 PHYSICAL_ADDRESS config_page_phys;
258 ULONG config_page_length;
259 PUCHAR requested_resources_start;
260 PUCHAR requested_resources_ptr;
261 PUCHAR assigned_resources_start;
262 PUCHAR assigned_resources_ptr;
263 XENPCI_DEVICE_STATE device_state;
264 BOOLEAN restart_on_resume;
265 BOOLEAN backend_initiated_remove;
266 BOOLEAN do_not_enumerate;
268 XENPCI_STATE_MAP_ELEMENT xb_pre_connect_map[5];
269 XENPCI_STATE_MAP_ELEMENT xb_post_connect_map[5];
270 XENPCI_STATE_MAP_ELEMENT xb_shutdown_map[5];
272 BOOLEAN hiber_usage_kludge;
273 } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
275 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_PDO_DEVICE_DATA, GetXppdd)
277 typedef struct {
278 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER header;
279 CHAR path[128];
280 CHAR device[128];
281 ULONG index;
282 } XENPCI_PDO_IDENTIFICATION_DESCRIPTION, *PXENPCI_PDO_IDENTIFICATION_DESCRIPTION;
284 #define XEN_INTERFACE_VERSION 1
286 //#define DEVICE_INTERFACE_TYPE_LEGACY 0
287 #define DEVICE_INTERFACE_TYPE_XENBUS 1
288 #define DEVICE_INTERFACE_TYPE_EVTCHN 2
289 #define DEVICE_INTERFACE_TYPE_GNTDEV 3
291 typedef struct {
292 ULONG len;
293 WDFQUEUE io_queue;
294 union {
295 struct xsd_sockmsg msg;
296 UCHAR buffer[PAGE_SIZE];
297 } u;
298 LIST_ENTRY read_list_head;
299 LIST_ENTRY watch_list_head;
300 } XENBUS_INTERFACE_DATA, *PXENBUS_INTERFACE_DATA;
302 typedef struct {
303 ULONG dummy; /* fill this in with whatever is required */
304 } EVTCHN_INTERFACE_DATA, *PEVTCHN_INTERFACE_DATA;
306 typedef struct {
307 ULONG dummy; /* fill this in with whatever is required */
308 } GNTDEV_INTERFACE_DATA, *PGNTDEV_INTERFACE_DATA;
310 typedef struct {
311 ULONG type;
312 KSPIN_LOCK lock;
313 WDFQUEUE io_queue;
314 EVT_WDF_FILE_CLEANUP *EvtFileCleanup;
315 EVT_WDF_FILE_CLOSE *EvtFileClose;
316 union {
317 XENBUS_INTERFACE_DATA xenbus;
318 EVTCHN_INTERFACE_DATA evtchn;
319 GNTDEV_INTERFACE_DATA gntdev;
320 };
321 } XENPCI_DEVICE_INTERFACE_DATA, *PXENPCI_DEVICE_INTERFACE_DATA;
323 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_INTERFACE_DATA, GetXpdid)
325 NTSTATUS
326 XenBus_DeviceFileInit(WDFDEVICE device, PWDF_IO_QUEUE_CONFIG queue_config, WDFFILEOBJECT file_object);
328 EVT_WDF_DEVICE_FILE_CREATE XenPci_EvtDeviceFileCreate;
329 EVT_WDF_FILE_CLOSE XenPci_EvtFileClose;
330 EVT_WDF_FILE_CLEANUP XenPci_EvtFileCleanup;
331 EVT_WDF_IO_QUEUE_IO_DEFAULT XenPci_EvtIoDefault;
333 #include "hypercall.h"
335 #define XBT_NIL ((xenbus_transaction_t)0)
337 NTSTATUS
338 hvm_get_stubs(PXENPCI_DEVICE_DATA xpdd);
339 NTSTATUS
340 hvm_free_stubs(PXENPCI_DEVICE_DATA xpdd);
342 EVT_WDF_DEVICE_PREPARE_HARDWARE XenPci_EvtDevicePrepareHardware;
343 EVT_WDF_DEVICE_RELEASE_HARDWARE XenPci_EvtDeviceReleaseHardware;
344 EVT_WDF_DEVICE_D0_ENTRY XenPci_EvtDeviceD0Entry;
345 EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED XenPci_EvtDeviceD0EntryPostInterruptsEnabled;
346 EVT_WDF_DEVICE_D0_EXIT XenPci_EvtDeviceD0Exit;
347 EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED XenPci_EvtDeviceD0ExitPreInterruptsDisabled;
348 EVT_WDF_DEVICE_QUERY_REMOVE XenPci_EvtDeviceQueryRemove;
349 EVT_WDF_CHILD_LIST_CREATE_DEVICE XenPci_EvtChildListCreateDevice;
350 EVT_WDF_CHILD_LIST_SCAN_FOR_CHILDREN XenPci_EvtChildListScanForChildren;
352 VOID
353 XenPci_HideQemuDevices();
354 extern WDFCOLLECTION qemu_hide_devices;
355 extern USHORT qemu_hide_flags_value;
357 #if 0
358 NTSTATUS
359 XenPci_Power_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
360 NTSTATUS
361 XenPci_Dummy_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
362 NTSTATUS
363 XenPci_Pnp_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
364 NTSTATUS
365 XenPci_Irp_Create_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
366 NTSTATUS
367 XenPci_Irp_Close_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
368 NTSTATUS
369 XenPci_Irp_Read_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
370 NTSTATUS
371 XenPci_Irp_Write_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
372 NTSTATUS
373 XenPci_Irp_Cleanup_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
374 NTSTATUS
375 XenPci_SystemControl_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
377 NTSTATUS
378 XenPci_Irp_Create_XenBus(PDEVICE_OBJECT device_object, PIRP irp);
379 NTSTATUS
380 XenPci_Irp_Close_XenBus(PDEVICE_OBJECT device_object, PIRP irp);
381 NTSTATUS
382 XenPci_Irp_Read_XenBus(PDEVICE_OBJECT device_object, PIRP irp);
383 NTSTATUS
384 XenPci_Irp_Write_XenBus(PDEVICE_OBJECT device_object, PIRP irp);
385 NTSTATUS
386 XenPci_Irp_Cleanup_XenBus(PDEVICE_OBJECT device_object, PIRP irp);
388 NTSTATUS
389 XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
390 //NTSTATUS
391 //XenPci_Dummy_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
392 NTSTATUS
393 XenPci_Pnp_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
394 NTSTATUS
395 XenPci_Irp_Create_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
396 NTSTATUS
397 XenPci_Irp_Close_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
398 NTSTATUS
399 XenPci_Irp_Read_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
400 NTSTATUS
401 XenPci_Irp_Write_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
402 NTSTATUS
403 XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
404 NTSTATUS
405 XenPci_SystemControl_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
406 #endif
408 NTSTATUS
409 XenPci_Pdo_Suspend(WDFDEVICE device);
410 NTSTATUS
411 XenPci_Pdo_Resume(WDFDEVICE device);
413 VOID
414 XenPci_DumpPdoConfig(PDEVICE_OBJECT device_object);
416 typedef VOID
417 (*PXENPCI_HIGHSYNC_FUNCTION)(PVOID context);
419 VOID
420 XenPci_HighSync(PXENPCI_HIGHSYNC_FUNCTION function0, PXENPCI_HIGHSYNC_FUNCTION functionN, PVOID context);
422 VOID
423 XenPci_PatchKernel(PXENPCI_DEVICE_DATA xpdd, PVOID base, ULONG length);
425 NTSTATUS
426 XenPci_HookDbgPrint();
427 NTSTATUS
428 XenPci_UnHookDbgPrint();
430 struct xsd_sockmsg *
431 XenBus_Raw(PXENPCI_DEVICE_DATA xpdd, struct xsd_sockmsg *msg);
432 char *
433 XenBus_Read(PVOID Context, xenbus_transaction_t xbt, char *path, char **value);
434 char *
435 XenBus_Write(PVOID Context, xenbus_transaction_t xbt, char *path, char *value);
436 char *
437 XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, char *path, char *fmt, ...);
438 char *
439 XenBus_StartTransaction(PVOID Context, xenbus_transaction_t *xbt);
440 char *
441 XenBus_EndTransaction(PVOID Context, xenbus_transaction_t t, int abort, int *retry);
442 char *
443 XenBus_List(PVOID Context, xenbus_transaction_t xbt, char *prefix, char ***contents);
444 char *
445 XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
446 char *
447 XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
448 //VOID
449 //XenBus_ThreadProc(PVOID StartContext);
450 NTSTATUS
451 XenBus_Init(PXENPCI_DEVICE_DATA xpdd);
452 NTSTATUS
453 XenBus_Halt(PXENPCI_DEVICE_DATA xpdd);
454 NTSTATUS
455 XenBus_Suspend(PXENPCI_DEVICE_DATA xpdd);
456 NTSTATUS
457 XenBus_Resume(PXENPCI_DEVICE_DATA xpdd);
459 PHYSICAL_ADDRESS
460 XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len);
462 EVT_WDF_INTERRUPT_ISR EvtChn_EvtInterruptIsr;
463 EVT_WDF_INTERRUPT_ENABLE EvtChn_EvtInterruptEnable;
464 EVT_WDF_INTERRUPT_DISABLE EvtChn_EvtInterruptDisable;
466 NTSTATUS
467 EvtChn_Init(PXENPCI_DEVICE_DATA xpdd);
468 NTSTATUS
469 EvtChn_Suspend(PXENPCI_DEVICE_DATA xpdd);
470 NTSTATUS
471 EvtChn_Resume(PXENPCI_DEVICE_DATA xpdd);
473 NTSTATUS
474 EvtChn_Mask(PVOID Context, evtchn_port_t Port);
475 NTSTATUS
476 EvtChn_Unmask(PVOID Context, evtchn_port_t Port);
477 NTSTATUS
478 EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, ULONG flags);
479 NTSTATUS
480 EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, ULONG flags);
481 NTSTATUS
482 EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector, PCHAR description, ULONG flags);
483 evtchn_port_t
484 EvtChn_AllocIpi(PVOID context, ULONG vcpu);
485 NTSTATUS
486 EvtChn_Unbind(PVOID Context, evtchn_port_t Port);
487 NTSTATUS
488 EvtChn_Notify(PVOID Context, evtchn_port_t Port);
489 VOID
490 EvtChn_Close(PVOID Context, evtchn_port_t Port);
491 evtchn_port_t
492 EvtChn_AllocUnbound(PVOID Context, domid_t Domain);
493 BOOLEAN
494 EvtChn_AckEvent(PVOID context, evtchn_port_t port, BOOLEAN *last_interrupt);
496 VOID
497 GntTbl_Init(PXENPCI_DEVICE_DATA xpdd);
498 VOID
499 GntTbl_Suspend(PXENPCI_DEVICE_DATA xpdd);
500 VOID
501 GntTbl_Resume(PXENPCI_DEVICE_DATA xpdd);
502 grant_ref_t
503 GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t, int readonly, grant_ref_t ref, ULONG tag);
504 BOOLEAN
505 GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref, ULONG tag);
506 VOID
507 GntTbl_PutRef(PVOID Context, grant_ref_t ref, ULONG tag);
508 grant_ref_t
509 GntTbl_GetRef(PVOID Context, ULONG tag);
511 #endif