ChangeSet 1.1338, 2005/04/20 11:39:58+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx
Grant tables for FreeBSD.
Signed-off-by: Kip Macy <kmacy@xxxxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
conf/files.i386-xen | 11 -
i386-xen/i386-xen/gnttab.c | 367 ++++++++++++++++++++++++++++++++++++
i386-xen/i386-xen/machdep.c | 3
i386-xen/i386-xen/pmap.c | 22 +-
i386-xen/include/gnttab.h | 71 ++++++
i386-xen/include/hypervisor-ifs.h | 2
i386-xen/include/hypervisor.h | 116 ++++++++---
i386-xen/include/xenpmap.h | 25 +-
i386-xen/xen/blkfront/xb_blkfront.c | 96 ++++++++-
9 files changed, 655 insertions(+), 58 deletions(-)
diff -Nru a/freebsd-5.3-xen-sparse/conf/files.i386-xen
b/freebsd-5.3-xen-sparse/conf/files.i386-xen
--- a/freebsd-5.3-xen-sparse/conf/files.i386-xen 2005-04-20 07:03:47
-04:00
+++ b/freebsd-5.3-xen-sparse/conf/files.i386-xen 2005-04-20 07:03:47
-04:00
@@ -202,18 +202,19 @@
i386-xen/i386-xen/pmap.c standard
i386-xen/i386-xen/support.s standard
i386-xen/i386-xen/swtch.s standard
-i386-xen/i386-xen/sys_machdep.c standard
+i386-xen/i386-xen/sys_machdep.c standard
i386-xen/i386-xen/trap.c standard
i386/i386/tsc.c standard
-i386-xen/i386-xen/vm_machdep.c standard
+i386-xen/i386-xen/vm_machdep.c standard
i386-xen/i386-xen/clock.c standard
# xen specific arch-dep files
i386-xen/i386-xen/hypervisor.c standard
i386-xen/i386-xen/xen_machdep.c standard
-i386-xen/i386-xen/xen_bus.c standard
-i386-xen/i386-xen/evtchn.c standard
-i386-xen/i386-xen/ctrl_if.c standard
+i386-xen/i386-xen/xen_bus.c standard
+i386-xen/i386-xen/evtchn.c standard
+i386-xen/i386-xen/ctrl_if.c standard
+i386-xen/i386-xen/gnttab.c standard
i386/isa/asc.c count asc
diff -Nru a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/gnttab.c
b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/gnttab.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/gnttab.c 2005-04-20 07:03:47
-04:00
@@ -0,0 +1,367 @@
+/******************************************************************************
+ * gnttab.c
+ *
+ * Two sets of functionality:
+ * 1. Granting foreign access to our memory reservation.
+ * 2. Accessing others' memory reservations via grant references.
+ * (i.e., mechanisms for both sender and recipient of grant references)
+ *
+ * Copyright (c) 2005, Christopher Clark
+ * Copyright (c) 2004, K A Fraser
+ */
+
+#include "opt_pmap.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mman.h>
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+
+#include <machine/gnttab.h>
+#include <machine/pmap.h>
+
+#include <machine/hypervisor-ifs.h>
+
+#define cmpxchg(a, b, c) atomic_cmpset_int((volatile u_int *)(a),(b),(c))
+
+
+/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
+static inline void rep_nop(void)
+{
+ __asm__ __volatile__ ( "rep;nop" : : : "memory" );
+}
+#define cpu_relax() rep_nop()
+
+#if 1
+#define ASSERT(_p) \
+ if ( !(_p) ) { printk("Assertion '%s': line %d, file %s\n", \
+ #_p , __LINE__, __FILE__); *(int*)0=0; }
+#else
+#define ASSERT(_p) ((void)0)
+#endif
+
+#define WPRINTK(fmt, args...) \
+ printk("xen_grant: " fmt, ##args)
+
+static grant_ref_t gnttab_free_list[NR_GRANT_ENTRIES];
+static grant_ref_t gnttab_free_head;
+
+static grant_entry_t *shared;
+#if 0
+/* /proc/xen/grant */
+static struct proc_dir_entry *grant_pde;
+#endif
+
+/*
+ * Lock-free grant-entry allocator
+ */
+
+static inline int
+get_free_entry(void)
+{
+ grant_ref_t fh, nfh = gnttab_free_head;
+ do { if ( unlikely((fh = nfh) == NR_GRANT_ENTRIES) ) return -1; }
+ while ( unlikely((nfh = cmpxchg(&gnttab_free_head, fh,
+ gnttab_free_list[fh])) != fh) );
+ return fh;
+}
+
+static inline void
+put_free_entry(grant_ref_t ref)
+{
+ grant_ref_t fh, nfh = gnttab_free_head;
+ do { gnttab_free_list[ref] = fh = nfh; wmb(); }
+ while ( unlikely((nfh = cmpxchg(&gnttab_free_head, fh, ref)) != fh) );
+}
+
+/*
+ * Public grant-issuing interface functions
+ */
+
+int
+gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly)
+{
+ int ref;
+
+ if ( unlikely((ref = get_free_entry()) == -1) )
+ return -ENOSPC;
+
+ shared[ref].frame = frame;
+ shared[ref].domid = domid;
+ wmb();
+ shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
+
+ return ref;
+}
+
+void
+gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
+ unsigned long frame, int readonly)
+{
+ shared[ref].frame = frame;
+ shared[ref].domid = domid;
+ wmb();
+ shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
+}
+
+
+int
+gnttab_query_foreign_access(grant_ref_t ref)
+{
+ uint16_t nflags;
+
+ nflags = shared[ref].flags;
+
+ return (nflags & (GTF_reading|GTF_writing));
+}
+
+void
+gnttab_end_foreign_access(grant_ref_t ref, int readonly)
+{
+ uint16_t flags, nflags;
+
+ nflags = shared[ref].flags;
+ do {
+ if ( (flags = nflags) & (GTF_reading|GTF_writing) )
+ printk("WARNING: g.e. still in use!\n");
+ }
+ while ( (nflags = cmpxchg(&shared[ref].flags, flags, 0)) != flags );
+
+ put_free_entry(ref);
+}
+
+int
+gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn)
+{
+ int ref;
+
+ if ( unlikely((ref = get_free_entry()) == -1) )
+ return -ENOSPC;
+
+ shared[ref].frame = pfn;
+ shared[ref].domid = domid;
+ wmb();
+ shared[ref].flags = GTF_accept_transfer;
+
+ return ref;
+}
+
+void
+gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid,
+ unsigned long pfn)
+{
+ shared[ref].frame = pfn;
+ shared[ref].domid = domid;
+ wmb();
+ shared[ref].flags = GTF_accept_transfer;
+}
+
+unsigned long
+gnttab_end_foreign_transfer(grant_ref_t ref)
+{
+ unsigned long frame = 0;
+ uint16_t flags;
+
+ flags = shared[ref].flags;
+ ASSERT(flags == (GTF_accept_transfer | GTF_transfer_committed));
+
+ /*
+ * If a transfer is committed then wait for the frame address to appear.
+ * Otherwise invalidate the grant entry against future use.
+ */
+ if ( likely(flags != GTF_accept_transfer) ||
+ (cmpxchg(&shared[ref].flags, flags, 0) != GTF_accept_transfer) )
+ while ( unlikely((frame = shared[ref].frame) == 0) )
+ cpu_relax();
+
+ put_free_entry(ref);
+
+ return frame;
+}
+
+void
+gnttab_free_grant_references(uint16_t count, grant_ref_t head)
+{
+ /* TODO: O(N)...? */
+ grant_ref_t to_die = 0, next = head;
+ int i;
+
+ for ( i = 0; i < count; i++ )
+ to_die = next;
+ next = gnttab_free_list[next];
+ put_free_entry( to_die );
+}
+
+int
+gnttab_alloc_grant_references(uint16_t count, grant_ref_t *head,
+ grant_ref_t *terminal)
+{
+ int i;
+ grant_ref_t h = gnttab_free_head;
+
+ for ( i = 0; i < count; i++ )
+ if ( unlikely(get_free_entry() == -1) )
+ goto not_enough_refs;
+
+ *head = h;
+ *terminal = gnttab_free_head;
+
+ return 0;
+
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|