ia64/xen-unstable

view linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c @ 7683:1470a9d40072

Remove unused and unnecessary gnttab ioctl.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Nov 08 12:25:09 2005 +0100 (2005-11-08)
parents b6cce4237ded
children 83ec10103067
line source
1 /******************************************************************************
2 * gnttab.c
3 *
4 * Granting foreign access to our memory reservation.
5 *
6 * Copyright (c) 2005, Christopher Clark
7 * Copyright (c) 2004-2005, K A Fraser
8 */
10 #include <linux/config.h>
11 #include <linux/module.h>
12 #include <linux/sched.h>
13 #include <asm/pgtable.h>
14 #include <asm-xen/xen-public/xen.h>
15 #include <asm/fixmap.h>
16 #include <asm/uaccess.h>
17 #include <asm-xen/xen_proc.h>
18 #include <asm-xen/linux-public/privcmd.h>
19 #include <asm-xen/gnttab.h>
20 #include <asm/synch_bitops.h>
22 #if 1
23 #define ASSERT(_p) \
24 if ( !(_p) ) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \
25 #_p , __LINE__, __FILE__); *(int*)0=0; }
26 #else
27 #define ASSERT(_p) ((void)0)
28 #endif
30 #define WPRINTK(fmt, args...) \
31 printk(KERN_WARNING "xen_grant: " fmt, ##args)
34 EXPORT_SYMBOL(gnttab_grant_foreign_access);
35 EXPORT_SYMBOL(gnttab_end_foreign_access_ref);
36 EXPORT_SYMBOL(gnttab_end_foreign_access);
37 EXPORT_SYMBOL(gnttab_query_foreign_access);
38 EXPORT_SYMBOL(gnttab_grant_foreign_transfer);
39 EXPORT_SYMBOL(gnttab_end_foreign_transfer_ref);
40 EXPORT_SYMBOL(gnttab_end_foreign_transfer);
41 EXPORT_SYMBOL(gnttab_alloc_grant_references);
42 EXPORT_SYMBOL(gnttab_free_grant_references);
43 EXPORT_SYMBOL(gnttab_free_grant_reference);
44 EXPORT_SYMBOL(gnttab_claim_grant_reference);
45 EXPORT_SYMBOL(gnttab_release_grant_reference);
46 EXPORT_SYMBOL(gnttab_grant_foreign_access_ref);
47 EXPORT_SYMBOL(gnttab_grant_foreign_transfer_ref);
49 /* External tools reserve first few grant table entries. */
50 #define NR_RESERVED_ENTRIES 8
52 #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
53 #define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1)
55 static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
56 static int gnttab_free_count;
57 static grant_ref_t gnttab_free_head;
58 static spinlock_t gnttab_list_lock = SPIN_LOCK_UNLOCKED;
60 static grant_entry_t *shared;
62 static struct gnttab_free_callback *gnttab_free_callback_list = NULL;
64 static int
65 get_free_entries(int count)
66 {
67 unsigned long flags;
68 int ref;
69 grant_ref_t head;
70 spin_lock_irqsave(&gnttab_list_lock, flags);
71 if (gnttab_free_count < count) {
72 spin_unlock_irqrestore(&gnttab_list_lock, flags);
73 return -1;
74 }
75 ref = head = gnttab_free_head;
76 gnttab_free_count -= count;
77 while (count-- > 1)
78 head = gnttab_list[head];
79 gnttab_free_head = gnttab_list[head];
80 gnttab_list[head] = GNTTAB_LIST_END;
81 spin_unlock_irqrestore(&gnttab_list_lock, flags);
82 return ref;
83 }
85 #define get_free_entry() get_free_entries(1)
87 static void
88 do_free_callbacks(void)
89 {
90 struct gnttab_free_callback *callback, *next;
92 callback = gnttab_free_callback_list;
93 gnttab_free_callback_list = NULL;
95 while (callback != NULL) {
96 next = callback->next;
97 if (gnttab_free_count >= callback->count) {
98 callback->next = NULL;
99 callback->fn(callback->arg);
100 } else {
101 callback->next = gnttab_free_callback_list;
102 gnttab_free_callback_list = callback;
103 }
104 callback = next;
105 }
106 }
108 static inline void
109 check_free_callbacks(void)
110 {
111 if (unlikely(gnttab_free_callback_list))
112 do_free_callbacks();
113 }
115 static void
116 put_free_entry(grant_ref_t ref)
117 {
118 unsigned long flags;
119 spin_lock_irqsave(&gnttab_list_lock, flags);
120 gnttab_list[ref] = gnttab_free_head;
121 gnttab_free_head = ref;
122 gnttab_free_count++;
123 check_free_callbacks();
124 spin_unlock_irqrestore(&gnttab_list_lock, flags);
125 }
127 /*
128 * Public grant-issuing interface functions
129 */
131 int
132 gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly)
133 {
134 int ref;
136 if (unlikely((ref = get_free_entry()) == -1))
137 return -ENOSPC;
139 shared[ref].frame = frame;
140 shared[ref].domid = domid;
141 wmb();
142 shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
144 return ref;
145 }
147 void
148 gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
149 unsigned long frame, int readonly)
150 {
151 shared[ref].frame = frame;
152 shared[ref].domid = domid;
153 wmb();
154 shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
155 }
158 int
159 gnttab_query_foreign_access(grant_ref_t ref)
160 {
161 u16 nflags;
163 nflags = shared[ref].flags;
165 return (nflags & (GTF_reading|GTF_writing));
166 }
168 int
169 gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
170 {
171 u16 flags, nflags;
173 nflags = shared[ref].flags;
174 do {
175 if ( (flags = nflags) & (GTF_reading|GTF_writing) ) {
176 printk(KERN_ALERT "WARNING: g.e. still in use!\n");
177 return 0;
178 }
179 }
180 while ((nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) !=
181 flags);
183 return 1;
184 }
186 void
187 gnttab_end_foreign_access(grant_ref_t ref, int readonly, unsigned long page)
188 {
189 if (gnttab_end_foreign_access_ref(ref, readonly)) {
190 put_free_entry(ref);
191 if (page != 0) {
192 free_page(page);
193 }
194 }
195 else {
196 /* XXX This needs to be fixed so that the ref and page are
197 placed on a list to be freed up later. */
198 printk(KERN_WARNING
199 "WARNING: leaking g.e. and page still in use!\n");
200 }
201 }
203 int
204 gnttab_grant_foreign_transfer(domid_t domid)
205 {
206 int ref;
208 if (unlikely((ref = get_free_entry()) == -1))
209 return -ENOSPC;
211 shared[ref].frame = 0;
212 shared[ref].domid = domid;
213 wmb();
214 shared[ref].flags = GTF_accept_transfer;
216 return ref;
217 }
219 void
220 gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid)
221 {
222 shared[ref].frame = 0;
223 shared[ref].domid = domid;
224 wmb();
225 shared[ref].flags = GTF_accept_transfer;
226 }
228 unsigned long
229 gnttab_end_foreign_transfer_ref(grant_ref_t ref)
230 {
231 unsigned long frame = 0;
232 u16 flags;
234 flags = shared[ref].flags;
236 /*
237 * If a transfer is committed then wait for the frame address to
238 * appear. Otherwise invalidate the grant entry against future use.
239 */
240 if (likely(flags != GTF_accept_transfer) ||
241 (synch_cmpxchg(&shared[ref].flags, flags, 0) !=
242 GTF_accept_transfer))
243 while (unlikely((frame = shared[ref].frame) == 0))
244 cpu_relax();
246 return frame;
247 }
249 unsigned long
250 gnttab_end_foreign_transfer(grant_ref_t ref)
251 {
252 unsigned long frame = gnttab_end_foreign_transfer_ref(ref);
253 put_free_entry(ref);
254 return frame;
255 }
257 void
258 gnttab_free_grant_reference(grant_ref_t ref)
259 {
261 put_free_entry(ref);
262 }
264 void
265 gnttab_free_grant_references(grant_ref_t head)
266 {
267 grant_ref_t ref;
268 unsigned long flags;
269 int count = 1;
270 if (head == GNTTAB_LIST_END)
271 return;
272 spin_lock_irqsave(&gnttab_list_lock, flags);
273 ref = head;
274 while (gnttab_list[ref] != GNTTAB_LIST_END) {
275 ref = gnttab_list[ref];
276 count++;
277 }
278 gnttab_list[ref] = gnttab_free_head;
279 gnttab_free_head = head;
280 gnttab_free_count += count;
281 check_free_callbacks();
282 spin_unlock_irqrestore(&gnttab_list_lock, flags);
283 }
285 int
286 gnttab_alloc_grant_references(u16 count, grant_ref_t *head)
287 {
288 int h = get_free_entries(count);
290 if (h == -1)
291 return -ENOSPC;
293 *head = h;
295 return 0;
296 }
298 int
299 gnttab_claim_grant_reference(grant_ref_t *private_head)
300 {
301 grant_ref_t g = *private_head;
302 if (unlikely(g == GNTTAB_LIST_END))
303 return -ENOSPC;
304 *private_head = gnttab_list[g];
305 return g;
306 }
308 void
309 gnttab_release_grant_reference(grant_ref_t *private_head, grant_ref_t release)
310 {
311 gnttab_list[release] = *private_head;
312 *private_head = release;
313 }
315 void
316 gnttab_request_free_callback(struct gnttab_free_callback *callback,
317 void (*fn)(void *), void *arg, u16 count)
318 {
319 unsigned long flags;
320 spin_lock_irqsave(&gnttab_list_lock, flags);
321 if (callback->next)
322 goto out;
323 callback->fn = fn;
324 callback->arg = arg;
325 callback->count = count;
326 callback->next = gnttab_free_callback_list;
327 gnttab_free_callback_list = callback;
328 check_free_callbacks();
329 out:
330 spin_unlock_irqrestore(&gnttab_list_lock, flags);
331 }
333 /*
334 * ProcFS operations
335 */
337 #ifdef CONFIG_PROC_FS
339 static struct proc_dir_entry *grant_pde;
340 static struct file_operations grant_file_ops;
342 static int
343 grant_read(char *page, char **start, off_t off, int count, int *eof,
344 void *data)
345 {
346 int len;
347 unsigned int i;
348 grant_entry_t *gt;
350 gt = (grant_entry_t *)shared;
351 len = 0;
353 for (i = 0; i < NR_GRANT_ENTRIES; i++) {
354 if (len > (PAGE_SIZE - 200)) {
355 len += sprintf( page + len, "Truncated.\n");
356 break;
357 }
358 }
360 if (gt[i].flags) {
361 len += sprintf(page + len,
362 "Grant: ref (0x%x) flags (0x%hx) "
363 "dom (0x%hx) frame (0x%x)\n",
364 i,
365 gt[i].flags,
366 gt[i].domid,
367 gt[i].frame );
368 }
370 *eof = 1;
371 return len;
372 }
374 static int
375 grant_write(struct file *file, const char __user *buffer, unsigned long count,
376 void *data)
377 {
378 /* TODO: implement this */
379 return -ENOSYS;
380 }
382 #endif /* CONFIG_PROC_FS */
384 int
385 gnttab_resume(void)
386 {
387 gnttab_setup_table_t setup;
388 unsigned long frames[NR_GRANT_FRAMES];
389 int i;
391 setup.dom = DOMID_SELF;
392 setup.nr_frames = NR_GRANT_FRAMES;
393 setup.frame_list = frames;
395 BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1));
396 BUG_ON(setup.status != 0);
398 #ifdef __ia64__
399 shared = __va(frames[0] << PAGE_SHIFT);
400 printk("grant table at %p\n", shared);
401 #else
402 for (i = 0; i < NR_GRANT_FRAMES; i++)
403 set_fixmap(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT);
404 #endif
406 return 0;
407 }
409 int
410 gnttab_suspend(void)
411 {
412 int i;
414 for (i = 0; i < NR_GRANT_FRAMES; i++)
415 clear_fixmap(FIX_GNTTAB_END - i);
417 return 0;
418 }
420 static int __init
421 gnttab_init(void)
422 {
423 int i;
425 if (xen_init() < 0)
426 return -ENODEV;
428 BUG_ON(gnttab_resume());
430 #ifndef __ia64__
431 shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB_END);
432 #endif
434 for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
435 gnttab_list[i] = i + 1;
436 gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES;
437 gnttab_free_head = NR_RESERVED_ENTRIES;
439 #ifdef CONFIG_PROC_FS
440 /*
441 * /proc/xen/grant : used by libxc to access grant tables
442 */
443 if ((grant_pde = create_xen_proc_entry("grant", 0600)) == NULL) {
444 WPRINTK("Unable to create grant xen proc entry\n");
445 return -1;
446 }
448 grant_file_ops.read = grant_pde->proc_fops->read;
449 grant_file_ops.write = grant_pde->proc_fops->write;
451 grant_pde->proc_fops = &grant_file_ops;
453 grant_pde->read_proc = &grant_read;
454 grant_pde->write_proc = &grant_write;
455 #endif
457 printk("Grant table initialized\n");
458 return 0;
459 }
461 __initcall(gnttab_init);
463 /*
464 * Local variables:
465 * c-file-style: "linux"
466 * indent-tabs-mode: t
467 * c-indent-level: 8
468 * c-basic-offset: 8
469 * tab-width: 8
470 * End:
471 */