[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Merge xen-2.0-testing "sync w/ unstable" changes.
ChangeSet 1.1392.1.2, 2005/04/28 21:50:48+01:00, cl349@xxxxxxxxxxxxxxxxxxxx Merge xen-2.0-testing "sync w/ unstable" changes. arch/xen/kernel/gnttab.c | 391 +++++++++++++++++++++++++++++++++++++++++++++++ include/asm-xen/gnttab.h | 72 ++++++++ 2 files changed, 463 insertions(+) diff -Nru a/linux-2.6.11-xen-sparse/arch/xen/kernel/gnttab.c b/linux-2.6.11-xen-sparse/arch/xen/kernel/gnttab.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/gnttab.c 2005-04-28 18:03:45 -04:00 @@ -0,0 +1,391 @@ +/****************************************************************************** + * 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 <linux/config.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <asm/pgtable.h> +#include <asm/fixmap.h> +#include <asm/uaccess.h> +#include <asm-xen/xen_proc.h> +#include <asm-xen/linux-public/privcmd.h> +#include <asm-xen/gnttab.h> + +#ifndef set_fixmap_ma +#define set_fixmap_ma set_fixmap +#endif + +#if 1 +#define ASSERT(_p) \ + if ( !(_p) ) { printk(KERN_ALERT"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(KERN_WARNING "xen_grant: " fmt, ##args) + + +EXPORT_SYMBOL(gnttab_grant_foreign_access); +EXPORT_SYMBOL(gnttab_end_foreign_access); +EXPORT_SYMBOL(gnttab_query_foreign_access); +EXPORT_SYMBOL(gnttab_grant_foreign_transfer); +EXPORT_SYMBOL(gnttab_end_foreign_transfer); +EXPORT_SYMBOL(gnttab_alloc_grant_references); +EXPORT_SYMBOL(gnttab_free_grant_references); +EXPORT_SYMBOL(gnttab_claim_grant_reference); +EXPORT_SYMBOL(gnttab_release_grant_reference); +EXPORT_SYMBOL(gnttab_grant_foreign_access_ref); +EXPORT_SYMBOL(gnttab_grant_foreign_transfer_ref); + +static grant_ref_t gnttab_free_list[NR_GRANT_ENTRIES]; +static grant_ref_t gnttab_free_head; + +static grant_entry_t *shared; + +/* + * 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 ) +{ + u16 nflags; + + nflags = shared[ref].flags; + + return ( nflags & (GTF_reading|GTF_writing) ); +} + +void +gnttab_end_foreign_access( grant_ref_t ref, int readonly ) +{ + u16 flags, nflags; + + nflags = shared[ref].flags; + do { + if ( (flags = nflags) & (GTF_reading|GTF_writing) ) + printk(KERN_ALERT "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; + u16 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( u16 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( u16 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; + +not_enough_refs: + gnttab_free_head = h; + return -ENOSPC; +} + +int +gnttab_claim_grant_reference( grant_ref_t *private_head, + grant_ref_t terminal ) +{ + grant_ref_t g; + if ( unlikely((g = *private_head) == terminal) ) + return -ENOSPC; + *private_head = gnttab_free_list[g]; + return g; +} + +void +gnttab_release_grant_reference( grant_ref_t *private_head, + grant_ref_t release ) +{ + gnttab_free_list[release] = *private_head; + *private_head = release; +} + +/* + * ProcFS operations + */ + +#ifdef CONFIG_PROC_FS _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |