win-pvdrivers

view xenpci/xenpci.h @ 790:467005e7f509

Big messy changes. Add grant ref tagging to better track when things go wrong (debug build only).
Fix a race in xennet that causes crashes under heavy traffic conditions on driver shutdown.
author James Harper <james.harper@bendigoit.com.au>
date Fri Mar 12 09:38:42 2010 +1100 (2010-03-12)
parents 3058ea7a6f59
children bbc6c94b9621
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 XEN_PV_PRODUCT_NUMBER 0x0002
73 #define XEN_PV_PRODUCT_BUILD 0x00000001
75 extern ULONG qemu_protocol_version;
77 typedef struct _ev_action_t {
78 PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine;
79 PVOID ServiceContext;
80 CHAR description[128];
81 ULONG type; /* EVT_ACTION_TYPE_* */
82 KDPC Dpc;
83 ULONG port;
84 ULONG vector;
85 ULONG count;
86 PVOID xpdd;
87 ULONG generation; /* increases each time the event is renewed */
88 } ev_action_t;
90 typedef struct _XENBUS_WATCH_RING
91 {
92 char Path[128];
93 char Token[10];
94 } XENBUS_WATCH_RING;
96 typedef struct xsd_sockmsg xsd_sockmsg_t;
98 typedef struct _XENBUS_WATCH_ENTRY {
99 char Path[128];
100 PXENBUS_WATCH_CALLBACK ServiceRoutine;
101 PVOID ServiceContext;
102 int Count;
103 int Active;
104 } XENBUS_WATCH_ENTRY, *PXENBUS_WATCH_ENTRY;
106 #define NR_EVENTS 1024
107 #define WATCH_RING_SIZE 128
108 #define NR_XB_REQS 32
109 #define MAX_WATCH_ENTRIES 128
111 #define CHILD_STATE_EMPTY 0
112 #define CHILD_STATE_DELETED 1
113 #define CHILD_STATE_ADDED 2
115 #define SUSPEND_STATE_NONE 0 /* no suspend in progress */
116 #define SUSPEND_STATE_SCHEDULED 1 /* suspend scheduled */
117 #define SUSPEND_STATE_HIGH_IRQL 2 /* all processors are at high IRQL and spinning */
118 #define SUSPEND_STATE_RESUMING 3 /* we are the other side of the suspend and things are starting to get back to normal */
120 typedef struct {
121 WDFDEVICE wdf_device;
123 BOOLEAN tpr_patched;
125 WDFINTERRUPT interrupt;
126 ULONG irq_number;
127 ULONG irq_vector;
128 KIRQL irq_level;
129 KINTERRUPT_MODE irq_mode;
130 KAFFINITY irq_affinity;
132 PHYSICAL_ADDRESS shared_info_area_unmapped;
133 shared_info_t *shared_info_area;
134 xen_ulong_t evtchn_pending_pvt[MAX_VIRT_CPUS][sizeof(xen_ulong_t) * 8];
135 xen_ulong_t evtchn_pending_suspend[sizeof(xen_ulong_t) * 8];
136 evtchn_port_t pdo_event_channel;
137 KEVENT pdo_suspend_event;
138 BOOLEAN interrupts_masked;
140 PHYSICAL_ADDRESS platform_mmio_addr;
141 ULONG platform_mmio_orig_len;
142 ULONG platform_mmio_len;
143 ULONG platform_mmio_alloc;
144 USHORT platform_mmio_flags;
146 ULONG platform_ioport_addr;
147 ULONG platform_ioport_len;
149 char *hypercall_stubs;
151 evtchn_port_t xen_store_evtchn;
153 /* grant related */
154 struct stack_state *gnttab_ss;
155 grant_entry_t *gnttab_table;
156 grant_entry_t *gnttab_table_copy;
157 #if DBG
158 PULONG gnttab_tag;
159 #endif
160 PHYSICAL_ADDRESS gnttab_table_physical;
161 //grant_ref_t *gnttab_list;
162 //int gnttab_list_free;
163 //KSPIN_LOCK grant_lock;
164 ULONG grant_frames;
166 ev_action_t ev_actions[NR_EVENTS];
167 // unsigned long bound_ports[NR_EVENTS/(8*sizeof(unsigned long))];
169 BOOLEAN xb_state;
171 struct xenstore_domain_interface *xen_store_interface;
173 #define BALLOON_UNITS (1024 * 1024) /* 1MB */
174 PKTHREAD balloon_thread;
175 KEVENT balloon_event;
176 BOOLEAN balloon_shutdown;
177 ULONG initial_memory;
178 ULONG current_memory;
179 ULONG target_memory;
181 /* xenbus related */
182 XENBUS_WATCH_ENTRY XenBus_WatchEntries[MAX_WATCH_ENTRIES];
183 KSPIN_LOCK xb_ring_spinlock;
184 FAST_MUTEX xb_watch_mutex;
185 FAST_MUTEX xb_request_mutex;
186 KEVENT xb_request_complete_event;
187 struct xsd_sockmsg *xb_reply;
188 struct xsd_sockmsg *xb_msg;
189 ULONG xb_msg_offset;
191 WDFCHILDLIST child_list;
193 KSPIN_LOCK suspend_lock;
194 evtchn_port_t suspend_evtchn;
195 int suspend_state;
197 UNICODE_STRING legacy_interface_name;
198 UNICODE_STRING interface_name;
199 BOOLEAN interface_open;
201 BOOLEAN removable;
203 BOOLEAN hibernated;
205 WDFQUEUE io_queue;
207 //WDFCOLLECTION veto_devices;
208 LIST_ENTRY veto_list;
210 #if 0
211 KSPIN_LOCK mmio_freelist_lock;
212 PPFN_NUMBER mmio_freelist_base;
213 ULONG mmio_freelist_free;
214 #endif
216 } XENPCI_DEVICE_DATA, *PXENPCI_DEVICE_DATA;
218 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_DATA, GetXpdd)
220 typedef struct {
221 WDFDEVICE wdf_device;
222 WDFDEVICE wdf_device_bus_fdo;
223 BOOLEAN reported_missing;
224 char path[128];
225 char device[128];
226 ULONG index;
227 ULONG irq_number;
228 ULONG irq_vector;
229 KIRQL irq_level;
230 char backend_path[128];
231 //PVOID xenbus_request;
232 KEVENT backend_state_event;
233 ULONG backend_state;
234 FAST_MUTEX backend_state_mutex;
235 ULONG frontend_state;
236 PMDL config_page_mdl;
237 PHYSICAL_ADDRESS config_page_phys;
238 ULONG config_page_length;
239 PUCHAR requested_resources_start;
240 PUCHAR requested_resources_ptr;
241 PUCHAR assigned_resources_start;
242 PUCHAR assigned_resources_ptr;
243 XENPCI_DEVICE_STATE device_state;
244 BOOLEAN restart_on_resume;
246 BOOLEAN hiber_usage_kludge;
247 } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
249 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_PDO_DEVICE_DATA, GetXppdd)
251 typedef struct {
252 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER header;
253 CHAR path[128];
254 CHAR device[128];
255 ULONG index;
256 } XENPCI_PDO_IDENTIFICATION_DESCRIPTION, *PXENPCI_PDO_IDENTIFICATION_DESCRIPTION;
258 #define XEN_INTERFACE_VERSION 1
260 //#define DEVICE_INTERFACE_TYPE_LEGACY 0
261 #define DEVICE_INTERFACE_TYPE_XENBUS 1
262 #define DEVICE_INTERFACE_TYPE_EVTCHN 2
263 #define DEVICE_INTERFACE_TYPE_GNTDEV 3
265 typedef struct {
266 ULONG len;
267 WDFQUEUE io_queue;
268 union {
269 struct xsd_sockmsg msg;
270 UCHAR buffer[PAGE_SIZE];
271 } u;
272 LIST_ENTRY read_list_head;
273 LIST_ENTRY watch_list_head;
274 } XENBUS_INTERFACE_DATA, *PXENBUS_INTERFACE_DATA;
276 typedef struct {
277 ULONG dummy; /* fill this in with whatever is required */
278 } EVTCHN_INTERFACE_DATA, *PEVTCHN_INTERFACE_DATA;
280 typedef struct {
281 ULONG dummy; /* fill this in with whatever is required */
282 } GNTDEV_INTERFACE_DATA, *PGNTDEV_INTERFACE_DATA;
284 typedef struct {
285 ULONG type;
286 KSPIN_LOCK lock;
287 WDFQUEUE io_queue;
288 EVT_WDF_FILE_CLEANUP *EvtFileCleanup;
289 EVT_WDF_FILE_CLOSE *EvtFileClose;
290 union {
291 XENBUS_INTERFACE_DATA xenbus;
292 EVTCHN_INTERFACE_DATA evtchn;
293 GNTDEV_INTERFACE_DATA gntdev;
294 };
295 } XENPCI_DEVICE_INTERFACE_DATA, *PXENPCI_DEVICE_INTERFACE_DATA;
297 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_INTERFACE_DATA, GetXpdid)
299 NTSTATUS
300 XenBus_DeviceFileInit(WDFDEVICE device, PWDF_IO_QUEUE_CONFIG queue_config, WDFFILEOBJECT file_object);
302 EVT_WDF_DEVICE_FILE_CREATE XenPci_EvtDeviceFileCreate;
303 EVT_WDF_FILE_CLOSE XenPci_EvtFileClose;
304 EVT_WDF_FILE_CLEANUP XenPci_EvtFileCleanup;
305 EVT_WDF_IO_QUEUE_IO_DEFAULT XenPci_EvtIoDefault;
307 #include "hypercall.h"
309 #define XBT_NIL ((xenbus_transaction_t)0)
311 NTSTATUS
312 hvm_get_stubs(PXENPCI_DEVICE_DATA xpdd);
313 NTSTATUS
314 hvm_free_stubs(PXENPCI_DEVICE_DATA xpdd);
316 EVT_WDF_DEVICE_PREPARE_HARDWARE XenPci_EvtDevicePrepareHardware;
317 EVT_WDF_DEVICE_RELEASE_HARDWARE XenPci_EvtDeviceReleaseHardware;
318 EVT_WDF_DEVICE_D0_ENTRY XenPci_EvtDeviceD0Entry;
319 EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED XenPci_EvtDeviceD0EntryPostInterruptsEnabled;
320 EVT_WDF_DEVICE_D0_EXIT XenPci_EvtDeviceD0Exit;
321 EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED XenPci_EvtDeviceD0ExitPreInterruptsDisabled;
322 EVT_WDF_DEVICE_QUERY_REMOVE XenPci_EvtDeviceQueryRemove;
323 EVT_WDF_CHILD_LIST_CREATE_DEVICE XenPci_EvtChildListCreateDevice;
324 EVT_WDF_CHILD_LIST_SCAN_FOR_CHILDREN XenPci_EvtChildListScanForChildren;
326 VOID
327 XenPci_HideQemuDevices();
328 extern WDFCOLLECTION qemu_hide_devices;
329 extern USHORT qemu_hide_flags_value;
331 #if 0
332 NTSTATUS
333 XenPci_Power_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
334 NTSTATUS
335 XenPci_Dummy_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
336 NTSTATUS
337 XenPci_Pnp_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
338 NTSTATUS
339 XenPci_Irp_Create_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
340 NTSTATUS
341 XenPci_Irp_Close_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
342 NTSTATUS
343 XenPci_Irp_Read_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
344 NTSTATUS
345 XenPci_Irp_Write_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
346 NTSTATUS
347 XenPci_Irp_Cleanup_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
348 NTSTATUS
349 XenPci_SystemControl_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
351 NTSTATUS
352 XenPci_Irp_Create_XenBus(PDEVICE_OBJECT device_object, PIRP irp);
353 NTSTATUS
354 XenPci_Irp_Close_XenBus(PDEVICE_OBJECT device_object, PIRP irp);
355 NTSTATUS
356 XenPci_Irp_Read_XenBus(PDEVICE_OBJECT device_object, PIRP irp);
357 NTSTATUS
358 XenPci_Irp_Write_XenBus(PDEVICE_OBJECT device_object, PIRP irp);
359 NTSTATUS
360 XenPci_Irp_Cleanup_XenBus(PDEVICE_OBJECT device_object, PIRP irp);
362 NTSTATUS
363 XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
364 //NTSTATUS
365 //XenPci_Dummy_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
366 NTSTATUS
367 XenPci_Pnp_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
368 NTSTATUS
369 XenPci_Irp_Create_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
370 NTSTATUS
371 XenPci_Irp_Close_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
372 NTSTATUS
373 XenPci_Irp_Read_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
374 NTSTATUS
375 XenPci_Irp_Write_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
376 NTSTATUS
377 XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
378 NTSTATUS
379 XenPci_SystemControl_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
380 #endif
382 NTSTATUS
383 XenPci_Pdo_Suspend(WDFDEVICE device);
384 NTSTATUS
385 XenPci_Pdo_Resume(WDFDEVICE device);
387 VOID
388 XenPci_DumpPdoConfig(PDEVICE_OBJECT device_object);
390 typedef VOID
391 (*PXENPCI_HIGHSYNC_FUNCTION)(PVOID context);
393 VOID
394 XenPci_HighSync(PXENPCI_HIGHSYNC_FUNCTION function0, PXENPCI_HIGHSYNC_FUNCTION functionN, PVOID context);
396 VOID
397 XenPci_PatchKernel(PXENPCI_DEVICE_DATA xpdd, PVOID base, ULONG length);
399 NTSTATUS
400 XenPci_HookDbgPrint();
402 struct xsd_sockmsg *
403 XenBus_Raw(PXENPCI_DEVICE_DATA xpdd, struct xsd_sockmsg *msg);
404 char *
405 XenBus_Read(PVOID Context, xenbus_transaction_t xbt, char *path, char **value);
406 char *
407 XenBus_Write(PVOID Context, xenbus_transaction_t xbt, char *path, char *value);
408 char *
409 XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, char *path, char *fmt, ...);
410 char *
411 XenBus_StartTransaction(PVOID Context, xenbus_transaction_t *xbt);
412 char *
413 XenBus_EndTransaction(PVOID Context, xenbus_transaction_t t, int abort, int *retry);
414 char *
415 XenBus_List(PVOID Context, xenbus_transaction_t xbt, char *prefix, char ***contents);
416 char *
417 XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
418 char *
419 XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
420 //VOID
421 //XenBus_ThreadProc(PVOID StartContext);
422 NTSTATUS
423 XenBus_Init(PXENPCI_DEVICE_DATA xpdd);
424 NTSTATUS
425 XenBus_Halt(PXENPCI_DEVICE_DATA xpdd);
426 NTSTATUS
427 XenBus_Suspend(PXENPCI_DEVICE_DATA xpdd);
428 NTSTATUS
429 XenBus_Resume(PXENPCI_DEVICE_DATA xpdd);
431 PHYSICAL_ADDRESS
432 XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len);
434 EVT_WDF_INTERRUPT_ISR EvtChn_EvtInterruptIsr;
435 EVT_WDF_INTERRUPT_ENABLE EvtChn_EvtInterruptEnable;
436 EVT_WDF_INTERRUPT_DISABLE EvtChn_EvtInterruptDisable;
438 NTSTATUS
439 EvtChn_Init(PXENPCI_DEVICE_DATA xpdd);
440 NTSTATUS
441 EvtChn_Suspend(PXENPCI_DEVICE_DATA xpdd);
442 NTSTATUS
443 EvtChn_Resume(PXENPCI_DEVICE_DATA xpdd);
445 NTSTATUS
446 EvtChn_Mask(PVOID Context, evtchn_port_t Port);
447 NTSTATUS
448 EvtChn_Unmask(PVOID Context, evtchn_port_t Port);
449 NTSTATUS
450 EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
451 NTSTATUS
452 EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
453 NTSTATUS
454 EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector, PCHAR description);
455 evtchn_port_t
456 EvtChn_AllocIpi(PVOID context, ULONG vcpu);
457 NTSTATUS
458 EvtChn_Unbind(PVOID Context, evtchn_port_t Port);
459 NTSTATUS
460 EvtChn_Notify(PVOID Context, evtchn_port_t Port);
461 VOID
462 EvtChn_Close(PVOID Context, evtchn_port_t Port);
463 evtchn_port_t
464 EvtChn_AllocUnbound(PVOID Context, domid_t Domain);
465 BOOLEAN
466 EvtChn_AckEvent(PVOID context, evtchn_port_t port, BOOLEAN *last_interrupt);
468 VOID
469 GntTbl_Init(PXENPCI_DEVICE_DATA xpdd);
470 VOID
471 GntTbl_Suspend(PXENPCI_DEVICE_DATA xpdd);
472 VOID
473 GntTbl_Resume(PXENPCI_DEVICE_DATA xpdd);
474 grant_ref_t
475 GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t, int readonly, grant_ref_t ref, ULONG tag);
476 BOOLEAN
477 GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref, ULONG tag);
478 VOID
479 GntTbl_PutRef(PVOID Context, grant_ref_t ref, ULONG tag);
480 grant_ref_t
481 GntTbl_GetRef(PVOID Context, ULONG tag);
483 #endif