diff options
author | mischief <mischief@offblast.org> | 2014-06-24 18:02:25 -0700 |
---|---|---|
committer | mischief <mischief@offblast.org> | 2014-06-24 18:02:25 -0700 |
commit | 5ba95fdb07ddc2c32111a1b2f57f17aa27fcbbf5 (patch) | |
tree | c1ec54cb9ecff85b0b820a26d26a10a32a118d0c /sys/src/9/xen/xengrant.c | |
parent | fa03455b5057675b18d1c87aef2d1071b2088de0 (diff) |
import xen 32 bit paravirtual kernel from /n/sources/xen.
Diffstat (limited to 'sys/src/9/xen/xengrant.c')
-rw-r--r-- | sys/src/9/xen/xengrant.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/sys/src/9/xen/xengrant.c b/sys/src/9/xen/xengrant.c new file mode 100644 index 000000000..d4e5500e6 --- /dev/null +++ b/sys/src/9/xen/xengrant.c @@ -0,0 +1,100 @@ +/* + * Sharing page frames with other domains + */ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" + +enum { + Nframes = 1, // XXX don't increase this without setting up extra mappings in xengrant_init() +}; + +static struct { + Lock; + ushort free; + ushort *refs; +} refalloc; + +static grant_entry_t *granttab; + +void +xengrantinit(void) +{ + gnttab_setup_table_t setup; + ulong frames[Nframes]; + int nrefs, i; + + setup.dom = DOMID_SELF; + setup.nr_frames = Nframes; + set_xen_guest_handle(setup.frame_list, frames); + if (HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1) != 0 || setup.status != 0) + panic("xen grant table setup"); + granttab = (grant_entry_t*)mmumapframe(XENGRANTTAB, frames[0]); + nrefs = Nframes * BY2PG / sizeof(grant_entry_t); + refalloc.refs = (ushort*)malloc(nrefs*sizeof(ushort)); + for (i = 0; i < nrefs; i++) + refalloc.refs[i] = i-1; + refalloc.free = nrefs-1; +} + +static int +allocref(void) +{ + int ref; + + ilock(&refalloc); + ref = refalloc.free; + if (ref > 0) + refalloc.free = refalloc.refs[ref]; + iunlock(&refalloc); + return ref; +} + +static void +freeref(int ref) +{ + ilock(&refalloc); + refalloc.refs[ref] = refalloc.free; + refalloc.free = ref; + iunlock(&refalloc); +} + +int +xengrant(domid_t domid, ulong frame, int flags) +{ + int ref; + grant_entry_t *gt; + + if ((ref = allocref()) < 0) + panic("out of xengrant refs"); + gt = &granttab[ref]; + gt->frame = frame; + gt->domid = domid; + coherence(); + gt->flags = flags; + return ref; +} + +int +xengrantend(int ref) +{ + grant_entry_t *gt; + int frame; + + gt = &granttab[ref]; + coherence(); + if (gt->flags>F_accept_transfer) { + if ((gt->flags>F_transfer_completed) == 0) + panic("xengrantend transfer in progress"); + } else { + if (gt->flags&(GTF_reading|GTF_writing)) + panic("xengrantend frame in use"); + } + coherence(); + frame = gt->frame; + gt->flags = GTF_invalid; + freeref(ref); + return frame; +} |