[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Grant tables for FreeBSD.



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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.