ia64/xen-unstable

annotate extras/mini-os/gnttab.c @ 18811:390ef36eb596

Remove Xen-private definitions from kexec public header.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Nov 19 13:13:39 2008 +0000 (2008-11-19)
parents a1c98534418b
children
rev   line source
kfraser@10657 1 /*
kfraser@10657 2 ****************************************************************************
kfraser@10657 3 * (C) 2006 - Cambridge University
kfraser@10657 4 ****************************************************************************
kfraser@10657 5 *
kfraser@10657 6 * File: gnttab.c
kfraser@10657 7 * Author: Steven Smith (sos22@cam.ac.uk)
kfraser@10657 8 * Changes: Grzegorz Milos (gm281@cam.ac.uk)
kfraser@10657 9 *
kfraser@10657 10 * Date: July 2006
kfraser@10657 11 *
kfraser@10657 12 * Environment: Xen Minimal OS
kfraser@10657 13 * Description: Simple grant tables implementation. About as stupid as it's
kfraser@10657 14 * possible to be and still work.
kfraser@10657 15 *
kfraser@10657 16 ****************************************************************************
kfraser@10657 17 */
kfraser@10657 18 #include <os.h>
kfraser@10657 19 #include <mm.h>
kfraser@10657 20 #include <gnttab.h>
keir@16488 21 #include <semaphore.h>
kfraser@10657 22
kfraser@10657 23 #define NR_RESERVED_ENTRIES 8
kfraser@10657 24
kfraser@13857 25 /* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
kfraser@13857 26 #ifdef __ia64__
kfraser@13857 27 #define NR_GRANT_FRAMES 1
kfraser@13857 28 #else
kfraser@10657 29 #define NR_GRANT_FRAMES 4
kfraser@13857 30 #endif
kfraser@10657 31 #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
kfraser@10657 32
kfraser@10657 33 static grant_entry_t *gnttab_table;
kfraser@10657 34 static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
keir@17323 35 #ifdef GNT_DEBUG
keir@17323 36 static char inuse[NR_GRANT_ENTRIES];
keir@17323 37 #endif
keir@17879 38 static __DECLARE_SEMAPHORE_GENERIC(gnttab_sem, 0);
kfraser@13414 39
kfraser@13414 40 static void
kfraser@13414 41 put_free_entry(grant_ref_t ref)
kfraser@13414 42 {
keir@16488 43 unsigned long flags;
keir@16488 44 local_irq_save(flags);
keir@17323 45 #ifdef GNT_DEBUG
keir@17323 46 BUG_ON(!inuse[ref]);
keir@17323 47 inuse[ref] = 0;
keir@17323 48 #endif
kfraser@13414 49 gnttab_list[ref] = gnttab_list[0];
kfraser@13414 50 gnttab_list[0] = ref;
keir@16488 51 local_irq_restore(flags);
keir@16488 52 up(&gnttab_sem);
kfraser@13414 53 }
kfraser@10657 54
kfraser@10657 55 static grant_ref_t
kfraser@13414 56 get_free_entry(void)
kfraser@10657 57 {
keir@16488 58 unsigned int ref;
keir@16488 59 unsigned long flags;
keir@16488 60 down(&gnttab_sem);
keir@16488 61 local_irq_save(flags);
keir@16488 62 ref = gnttab_list[0];
keir@17879 63 BUG_ON(ref < NR_RESERVED_ENTRIES || ref >= NR_GRANT_ENTRIES);
kfraser@13414 64 gnttab_list[0] = gnttab_list[ref];
keir@17323 65 #ifdef GNT_DEBUG
keir@17323 66 BUG_ON(inuse[ref]);
keir@17323 67 inuse[ref] = 1;
keir@17323 68 #endif
keir@16488 69 local_irq_restore(flags);
kfraser@10657 70 return ref;
kfraser@10657 71 }
kfraser@10657 72
kfraser@10657 73 grant_ref_t
kfraser@10657 74 gnttab_grant_access(domid_t domid, unsigned long frame, int readonly)
kfraser@10657 75 {
kfraser@10657 76 grant_ref_t ref;
kfraser@10657 77
kfraser@13414 78 ref = get_free_entry();
kfraser@10657 79 gnttab_table[ref].frame = frame;
kfraser@10657 80 gnttab_table[ref].domid = domid;
kfraser@10657 81 wmb();
kfraser@10657 82 readonly *= GTF_readonly;
kfraser@10657 83 gnttab_table[ref].flags = GTF_permit_access | readonly;
kfraser@10657 84
kfraser@10657 85 return ref;
kfraser@10657 86 }
kfraser@10657 87
kfraser@10657 88 grant_ref_t
kfraser@10657 89 gnttab_grant_transfer(domid_t domid, unsigned long pfn)
kfraser@10657 90 {
kfraser@10657 91 grant_ref_t ref;
kfraser@10657 92
kfraser@13414 93 ref = get_free_entry();
kfraser@10657 94 gnttab_table[ref].frame = pfn;
kfraser@10657 95 gnttab_table[ref].domid = domid;
kfraser@10657 96 wmb();
kfraser@10657 97 gnttab_table[ref].flags = GTF_accept_transfer;
kfraser@10657 98
kfraser@10657 99 return ref;
kfraser@10657 100 }
kfraser@10657 101
kfraser@10657 102 int
kfraser@10657 103 gnttab_end_access(grant_ref_t ref)
kfraser@10657 104 {
kfraser@10657 105 u16 flags, nflags;
kfraser@10657 106
keir@17323 107 BUG_ON(ref >= NR_GRANT_ENTRIES || ref < NR_RESERVED_ENTRIES);
keir@17323 108
kfraser@10657 109 nflags = gnttab_table[ref].flags;
kfraser@10657 110 do {
kfraser@10657 111 if ((flags = nflags) & (GTF_reading|GTF_writing)) {
keir@17323 112 printk("WARNING: g.e. still in use! (%x)\n", flags);
kfraser@10657 113 return 0;
kfraser@10657 114 }
kfraser@10657 115 } while ((nflags = synch_cmpxchg(&gnttab_table[ref].flags, flags, 0)) !=
kfraser@10657 116 flags);
kfraser@10657 117
kfraser@10657 118 put_free_entry(ref);
kfraser@10657 119 return 1;
kfraser@10657 120 }
kfraser@10657 121
kfraser@10657 122 unsigned long
kfraser@10657 123 gnttab_end_transfer(grant_ref_t ref)
kfraser@10657 124 {
kfraser@10657 125 unsigned long frame;
kfraser@10657 126 u16 flags;
kfraser@10657 127
keir@17323 128 BUG_ON(ref >= NR_GRANT_ENTRIES || ref < NR_RESERVED_ENTRIES);
keir@17323 129
kfraser@10657 130 while (!((flags = gnttab_table[ref].flags) & GTF_transfer_committed)) {
kfraser@10657 131 if (synch_cmpxchg(&gnttab_table[ref].flags, flags, 0) == flags) {
kfraser@10657 132 printk("Release unused transfer grant.\n");
kfraser@10657 133 put_free_entry(ref);
kfraser@10657 134 return 0;
kfraser@10657 135 }
kfraser@10657 136 }
kfraser@10657 137
kfraser@10657 138 /* If a transfer is in progress then wait until it is completed. */
kfraser@10657 139 while (!(flags & GTF_transfer_completed)) {
kfraser@10657 140 flags = gnttab_table[ref].flags;
kfraser@10657 141 }
kfraser@10657 142
kfraser@10657 143 /* Read the frame number /after/ reading completion status. */
kfraser@10657 144 rmb();
kfraser@10657 145 frame = gnttab_table[ref].frame;
kfraser@10657 146
kfraser@10657 147 put_free_entry(ref);
kfraser@10657 148
kfraser@10657 149 return frame;
kfraser@10657 150 }
kfraser@10657 151
kfraser@10657 152 grant_ref_t
kfraser@10657 153 gnttab_alloc_and_grant(void **map)
kfraser@10657 154 {
kfraser@10657 155 unsigned long mfn;
kfraser@10657 156 grant_ref_t gref;
kfraser@10657 157
kfraser@10657 158 *map = (void *)alloc_page();
kfraser@10657 159 mfn = virt_to_mfn(*map);
kfraser@10657 160 gref = gnttab_grant_access(0, mfn, 0);
kfraser@10657 161 return gref;
kfraser@10657 162 }
kfraser@10657 163
kfraser@14427 164 static const char * const gnttabop_error_msgs[] = GNTTABOP_error_msgs;
sos22@10852 165
sos22@10852 166 const char *
sos22@10852 167 gnttabop_error(int16_t status)
sos22@10852 168 {
sos22@10852 169 status = -status;
sos22@10852 170 if (status < 0 || status >= ARRAY_SIZE(gnttabop_error_msgs))
sos22@10852 171 return "bad status";
sos22@10852 172 else
sos22@10852 173 return gnttabop_error_msgs[status];
sos22@10852 174 }
sos22@10852 175
kfraser@10657 176 void
kfraser@10657 177 init_gnttab(void)
kfraser@10657 178 {
kfraser@10657 179 struct gnttab_setup_table setup;
kfraser@10657 180 unsigned long frames[NR_GRANT_FRAMES];
kfraser@10657 181 int i;
kfraser@10657 182
keir@17323 183 #ifdef GNT_DEBUG
keir@17323 184 memset(inuse, 1, sizeof(inuse));
keir@17323 185 #endif
kfraser@10657 186 for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
kfraser@13414 187 put_free_entry(i);
kfraser@10657 188
kfraser@10657 189 setup.dom = DOMID_SELF;
kfraser@10657 190 setup.nr_frames = NR_GRANT_FRAMES;
kfraser@10657 191 set_xen_guest_handle(setup.frame_list, frames);
kfraser@10657 192
kfraser@10657 193 HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
kfraser@10657 194 gnttab_table = map_frames(frames, NR_GRANT_FRAMES);
kfraser@10657 195 printk("gnttab_table mapped at %p.\n", gnttab_table);
kfraser@10657 196 }
keir@17812 197
keir@17812 198 void
keir@17812 199 fini_gnttab(void)
keir@17812 200 {
keir@17812 201 struct gnttab_setup_table setup;
keir@17812 202
keir@17812 203 setup.dom = DOMID_SELF;
keir@17812 204 setup.nr_frames = 0;
keir@17812 205
keir@17812 206 HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
keir@17812 207 }