win-pvdrivers

view xenpci/gnttbl.c @ 340:2be08f708250

move KeGetCurrentProcessorNumber fix to xenpci.h
Add kdprints to new functions with inline asm to make sure they get verified to work properly
Add missing intrinsic to gnttbl.c
Add next file to makefile
author Andy Grover <andy.grover@oracle.com>
date Sun Jun 22 18:14:30 2008 -0700 (2008-06-22)
parents 3673f1f07746
children 097ab7d19ea2
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"
22 VOID
23 GntTbl_PutRef(PVOID Context, grant_ref_t ref)
24 {
25 PXENPCI_DEVICE_DATA xpdd = Context;
26 KIRQL OldIrql;
28 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
29 KeAcquireSpinLock(&xpdd->grant_lock, &OldIrql);
30 xpdd->gnttab_list[ref] = xpdd->gnttab_list[0];
31 xpdd->gnttab_list[0] = ref;
32 KeReleaseSpinLock(&xpdd->grant_lock, OldIrql);
33 }
35 grant_ref_t
36 GntTbl_GetRef(PVOID Context)
37 {
38 PXENPCI_DEVICE_DATA xpdd = Context;
39 unsigned int ref;
40 KIRQL OldIrql;
42 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
43 KeAcquireSpinLock(&xpdd->grant_lock, &OldIrql);
44 ref = xpdd->gnttab_list[0];
45 xpdd->gnttab_list[0] = xpdd->gnttab_list[ref];
46 KeReleaseSpinLock(&xpdd->grant_lock, OldIrql);
48 return ref;
49 }
51 int
52 GntTbl_Map(PVOID Context, unsigned int start_idx, unsigned int end_idx)
53 {
54 PXENPCI_DEVICE_DATA xpdd = Context;
55 struct xen_add_to_physmap xatp;
56 unsigned int i = end_idx;
58 /* Loop backwards, so that the first hypercall has the largest index, ensuring that the table will grow only once. */
59 do {
60 xatp.domid = DOMID_SELF;
61 xatp.idx = i;
62 xatp.space = XENMAPSPACE_grant_table;
63 xatp.gpfn = (xen_pfn_t)(xpdd->gnttab_table_physical.QuadPart >> PAGE_SHIFT) + i;
64 if (HYPERVISOR_memory_op(xpdd, XENMEM_add_to_physmap, &xatp))
65 {
66 KdPrint((__DRIVER_NAME " ***ERROR MAPPING FRAME***\n"));
67 }
68 } while (i-- > start_idx);
70 return 0;
71 }
73 grant_ref_t
74 GntTbl_GrantAccess(
75 PVOID Context,
76 domid_t domid,
77 uint32_t frame, // xen api limits pfn to 32bit, so no guests over 8TB
78 int readonly,
79 grant_ref_t ref)
80 {
81 PXENPCI_DEVICE_DATA xpdd = Context;
83 //KdPrint((__DRIVER_NAME " --> GntTbl_GrantAccess\n"));
85 //KdPrint((__DRIVER_NAME " Granting access to frame %08x\n", frame));
87 if (ref == 0)
88 ref = GntTbl_GetRef(Context);
89 xpdd->gnttab_table[ref].frame = frame;
90 xpdd->gnttab_table[ref].domid = domid;
92 if (xpdd->gnttab_table[ref].flags)
93 KdPrint((__DRIVER_NAME " WARNING: Attempting to re-use grant entry that is already in use!\n"));
95 KeMemoryBarrier();
96 readonly *= GTF_readonly;
97 xpdd->gnttab_table[ref].flags = GTF_permit_access | (uint16_t)readonly;
99 //KdPrint((__DRIVER_NAME " <-- GntTbl_GrantAccess (ref = %d)\n", ref));
101 return ref;
102 }
104 #ifdef __MINGW32__
105 /* from linux/include/asm-i386/cmpxchg.h */
106 static inline short InterlockedCompareExchange16(
107 short volatile *dest,
108 short exch,
109 short comp)
110 {
111 unsigned long prev;
113 __asm__ __volatile__("lock;"
114 "cmpxchgw %w1,%2"
115 : "=a"(prev)
116 : "r"(exch), "m"(*(dest)), "0"(comp)
117 : "memory");
119 KdPrint((__FUNC__ " Check that I work as expected!\n"));
121 return prev;
122 }
123 #endif
125 BOOLEAN
126 GntTbl_EndAccess(
127 PVOID Context,
128 grant_ref_t ref,
129 BOOLEAN keepref)
130 {
131 PXENPCI_DEVICE_DATA xpdd = Context;
132 unsigned short flags, nflags;
134 //KdPrint((__DRIVER_NAME " --> GntTbl_EndAccess\n"));
136 nflags = xpdd->gnttab_table[ref].flags;
137 do {
138 if ((flags = nflags) & (GTF_reading|GTF_writing))
139 {
140 KdPrint((__DRIVER_NAME "WARNING: g.e. still in use!\n"));
141 return FALSE;
142 }
143 } while ((nflags = InterlockedCompareExchange16(
144 (volatile SHORT *)&xpdd->gnttab_table[ref].flags, 0, flags)) != flags);
146 if (!keepref)
147 GntTbl_PutRef(Context, ref);
148 //KdPrint((__DRIVER_NAME " <-- GntTbl_EndAccess\n"));
149 return TRUE;
150 }
152 VOID
153 GntTbl_Init(PXENPCI_DEVICE_DATA xpdd)
154 {
155 int i;
157 //KdPrint((__DRIVER_NAME " --> GntTbl_Init\n"));
159 KeInitializeSpinLock(&xpdd->grant_lock);
161 for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
162 GntTbl_PutRef(xpdd, i);
164 xpdd->gnttab_table_physical = XenPci_AllocMMIO(xpdd,
165 PAGE_SIZE * NR_GRANT_FRAMES);
166 xpdd->gnttab_table = MmMapIoSpace(xpdd->gnttab_table_physical,
167 PAGE_SIZE * NR_GRANT_FRAMES, MmNonCached);
168 if (!xpdd->gnttab_table)
169 {
170 KdPrint((__DRIVER_NAME " Error Mapping Grant Table Shared Memory\n"));
171 return;
172 }
173 GntTbl_Map(xpdd, 0, NR_GRANT_FRAMES - 1);
175 //KdPrint((__DRIVER_NAME " <-- GntTbl_Init table mapped at %p\n", gnttab_table));
176 }