ia64/xen-unstable

changeset 2389:67172d807d37

bitkeeper revision 1.1159.65.1 (4133a979YYvSU8Cjqbo3qyIcdTx6pw)

Grant-issuing side of Linux grant-table code. The grant-receiving side
is still to be implemented.
author kaf24@freefall.cl.cam.ac.uk
date Mon Aug 30 22:26:01 2004 +0000 (2004-08-30)
parents bcc898397e06
children b0b5ac0ee900
files linux-2.4.27-xen-sparse/include/asm-xen/fixmap.h linux-2.6.8.1-xen-sparse/arch/xen/kernel/gnttab.c linux-2.6.8.1-xen-sparse/include/asm-xen/asm-i386/fixmap.h linux-2.6.8.1-xen-sparse/include/asm-xen/hypervisor.h
line diff
     1.1 --- a/linux-2.4.27-xen-sparse/include/asm-xen/fixmap.h	Sat Aug 28 15:59:24 2004 +0000
     1.2 +++ b/linux-2.4.27-xen-sparse/include/asm-xen/fixmap.h	Mon Aug 30 22:26:01 2004 +0000
     1.3 @@ -52,7 +52,7 @@ enum fixed_addresses {
     1.4  	FIX_NETRING2_BASE,
     1.5  	FIX_NETRING3_BASE,
     1.6          FIX_SHARED_INFO,
     1.7 -
     1.8 +	FIX_GNTTAB,
     1.9  #ifdef CONFIG_VGA_CONSOLE
    1.10  #define NR_FIX_BTMAPS   32  /* 128KB For the Dom0 VGA Console A0000-C0000 */
    1.11  #else
     2.1 --- a/linux-2.6.8.1-xen-sparse/arch/xen/kernel/gnttab.c	Sat Aug 28 15:59:24 2004 +0000
     2.2 +++ b/linux-2.6.8.1-xen-sparse/arch/xen/kernel/gnttab.c	Mon Aug 30 22:26:01 2004 +0000
     2.3 @@ -11,17 +11,112 @@
     2.4  
     2.5  #include <linux/config.h>
     2.6  #include <linux/module.h>
     2.7 +#include <linux/sched.h>
     2.8 +#include <asm/pgtable.h>
     2.9 +#include <asm/fixmap.h>
    2.10  #include <asm-xen/gnttab.h>
    2.11  
    2.12 +#ifndef set_fixmap_ma
    2.13 +#define set_fixmap_ma set_fixmap
    2.14 +#endif
    2.15 +
    2.16 +#if 1
    2.17 +#define ASSERT(_p) \
    2.18 +    if ( !(_p) ) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \
    2.19 +    #_p , __LINE__, __FILE__); *(int*)0=0; }
    2.20 +#else
    2.21 +#define ASSERT(_p) ((void)0)
    2.22 +#endif
    2.23 +
    2.24  EXPORT_SYMBOL(gnttab_grant_foreign_access);
    2.25  EXPORT_SYMBOL(gnttab_end_foreign_access);
    2.26  EXPORT_SYMBOL(gnttab_grant_foreign_transfer);
    2.27  EXPORT_SYMBOL(gnttab_end_foreign_transfer);
    2.28  
    2.29 +struct gntent_auxinfo {
    2.30 +    u16         write_pin, read_pin; /* reference counts */
    2.31 +    u16         inuse;
    2.32 +    grant_ref_t next;                /* hash chain       */
    2.33 +};
    2.34 +
    2.35 +#define NR_GRANT_REFS 512
    2.36 +
    2.37 +static struct gntent_auxinfo auxtab[NR_GRANT_REFS];
    2.38 +static grant_ref_t gnttab_free_head;
    2.39 +static spinlock_t gnttab_lock;
    2.40 +
    2.41 +#define HASH_INVALID (0xFFFFU)
    2.42 +#define GNTTAB_HASH_SZ 512
    2.43 +#define GNTTAB_HASH(_f) ((_f) & (GNTTAB_HASH_SZ-1))
    2.44 +static grant_ref_t gnttab_hash[GNTTAB_HASH_SZ];
    2.45 +
    2.46 +static grant_entry_t *shared;
    2.47 +
    2.48 +/*
    2.49 + * Lock-free grant-entry allocator
    2.50 + */
    2.51 +
    2.52 +static inline grant_ref_t
    2.53 +get_free_entry(
    2.54 +    void)
    2.55 +{
    2.56 +    grant_ref_t fh, nfh = gnttab_free_head;
    2.57 +    do { fh = nfh; }
    2.58 +    while ( unlikely((nfh = cmpxchg(&gnttab_free_head, fh,
    2.59 +                                    auxtab[fh].next)) != fh) );
    2.60 +    return fh;
    2.61 +}
    2.62 +
    2.63 +static inline void
    2.64 +put_free_entry(
    2.65 +    grant_ref_t ref)
    2.66 +{
    2.67 +    grant_ref_t fh, nfh = gnttab_free_head;
    2.68 +    do { auxtab[ref].next = fh = nfh; wmb(); }
    2.69 +    while ( unlikely((nfh = cmpxchg(&gnttab_free_head, fh, ref)) != fh) );
    2.70 +}
    2.71 +
    2.72 +/*
    2.73 + * Public interface functions
    2.74 + */
    2.75 +
    2.76  grant_ref_t
    2.77  gnttab_grant_foreign_access(
    2.78      domid_t domid, unsigned long frame, int readonly)
    2.79  {
    2.80 +    unsigned long flags;
    2.81 +    grant_ref_t   ref;
    2.82 +
    2.83 +    spin_lock_irqsave(&gnttab_lock, flags);
    2.84 +
    2.85 +    for ( ref  = gnttab_hash[GNTTAB_HASH(frame)];
    2.86 +          ref != HASH_INVALID;
    2.87 +          ref  = auxtab[ref].next )
    2.88 +    {
    2.89 +        if ( auxtab[ref].inuse && (shared[ref].frame == frame) )
    2.90 +        {
    2.91 +            if ( readonly )
    2.92 +                auxtab[ref].read_pin++;
    2.93 +            else if ( auxtab[ref].write_pin++ == 0 )
    2.94 +                clear_bit(_GTF_readonly, (unsigned long *)&shared[ref].flags);
    2.95 +            goto done;
    2.96 +        }
    2.97 +    }
    2.98 +
    2.99 +    ref = get_free_entry();
   2.100 +    auxtab[ref].inuse     = 1;
   2.101 +    auxtab[ref].read_pin  = !!readonly;
   2.102 +    auxtab[ref].write_pin =  !readonly;
   2.103 +    auxtab[ref].next = gnttab_hash[GNTTAB_HASH(frame)];
   2.104 +    gnttab_hash[GNTTAB_HASH(frame)] = ref;
   2.105 +
   2.106 +    shared[ref].frame = frame;
   2.107 +    shared[ref].domid = domid;
   2.108 +    wmb();
   2.109 +    shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
   2.110 +
   2.111 + done:
   2.112 +    spin_unlock_irqrestore(&gnttab_lock, flags);
   2.113      return 0;
   2.114  }
   2.115  
   2.116 @@ -29,18 +124,111 @@ void
   2.117  gnttab_end_foreign_access(
   2.118      grant_ref_t ref, int readonly)
   2.119  {
   2.120 +    unsigned long flags, frame = shared[ref].frame;
   2.121 +    grant_ref_t  *pref;
   2.122 +    u16           sflags, nsflags;
   2.123 +
   2.124 +    spin_lock_irqsave(&gnttab_lock, flags);
   2.125 +
   2.126 +    if ( readonly )
   2.127 +    {
   2.128 +        if ( (auxtab[ref].read_pin-- == 0) && (auxtab[ref].write_pin == 0) )
   2.129 +            goto delete;
   2.130 +    }
   2.131 +    else if ( auxtab[ref].write_pin-- == 0 )
   2.132 +    {
   2.133 +        if ( auxtab[ref].read_pin == 0 )
   2.134 +            goto delete;
   2.135 +        nsflags = shared[ref].flags;
   2.136 +        do {
   2.137 +            if ( (sflags = nsflags) & GTF_writing )
   2.138 +                printk(KERN_ALERT "WARNING: g.e. still in use for writing!\n");
   2.139 +        }
   2.140 +        while ( (nsflags = cmpxchg(&shared[ref].flags, sflags, 
   2.141 +                                   sflags | GTF_readonly)) != sflags );
   2.142 +    }
   2.143 +
   2.144 +    goto out;
   2.145 +
   2.146 + delete:
   2.147 +    nsflags = shared[ref].flags;
   2.148 +    do {
   2.149 +        if ( (sflags = nsflags) & (GTF_reading|GTF_writing) )
   2.150 +            printk(KERN_ALERT "WARNING: g.e. still in use!\n");
   2.151 +    }
   2.152 +    while ( (nsflags = cmpxchg(&shared[ref].flags, sflags, 0)) != sflags );
   2.153 +
   2.154 +    pref = &gnttab_hash[GNTTAB_HASH(frame)];
   2.155 +    while ( *pref != ref )
   2.156 +        pref = &auxtab[*pref].next;
   2.157 +    *pref = auxtab[ref].next;
   2.158 +
   2.159 +    auxtab[ref].inuse = 0;
   2.160 +    put_free_entry(ref);
   2.161 +
   2.162 + out:
   2.163 +    spin_unlock_irqrestore(&gnttab_lock, flags);
   2.164  }
   2.165  
   2.166  grant_ref_t
   2.167  gnttab_grant_foreign_transfer(
   2.168      domid_t domid)
   2.169  {
   2.170 -    return 0;
   2.171 +    grant_ref_t ref = get_free_entry();
   2.172 +
   2.173 +    shared[ref].frame = 0;
   2.174 +    shared[ref].domid = domid;
   2.175 +    wmb();
   2.176 +    shared[ref].flags = GTF_accept_transfer;
   2.177 +
   2.178 +    return ref;
   2.179  }
   2.180  
   2.181  unsigned long
   2.182  gnttab_end_foreign_transfer(
   2.183      grant_ref_t ref)
   2.184  {
   2.185 -    return 0;
   2.186 +    unsigned long frame = 0;
   2.187 +    u16           flags;
   2.188 +
   2.189 +    flags = shared[ref].flags;
   2.190 +    ASSERT(flags == (GTF_accept_transfer | GTF_transfer_committed));
   2.191 +
   2.192 +    /*
   2.193 +     * If a transfer is committed then wait for the frame address to appear.
   2.194 +     * Otherwise invalidate the grant entry against future use.
   2.195 +     */
   2.196 +    if ( likely(flags != GTF_accept_transfer) ||
   2.197 +         (cmpxchg(&shared[ref].flags, flags, 0) != GTF_accept_transfer) )
   2.198 +        while ( unlikely((frame = shared[ref].frame) == 0) )
   2.199 +            cpu_relax();
   2.200 +
   2.201 +    put_free_entry(ref);
   2.202 +
   2.203 +    return frame;
   2.204  }
   2.205 +
   2.206 +void __init gnttab_init(void)
   2.207 +{
   2.208 +    int               i;
   2.209 +    gnttab_op_t       gntop;
   2.210 +    unsigned long     frame;
   2.211 +
   2.212 +    spin_lock_init(&gnttab_lock);
   2.213 +
   2.214 +    for ( i = 0; i < GNTTAB_HASH_SZ; i++ )
   2.215 +    {
   2.216 +        gnttab_hash[i] = HASH_INVALID;
   2.217 +        auxtab[i].next = i+1;
   2.218 +    }
   2.219 +
   2.220 +    gntop.cmd = GNTTABOP_setup_table;
   2.221 +    gntop.u.setup_table.dom        = DOMID_SELF;
   2.222 +    gntop.u.setup_table.nr_frames  = 1;
   2.223 +    gntop.u.setup_table.frame_list = &frame;
   2.224 +    if ( HYPERVISOR_grant_table_op(&gntop) != 0 )
   2.225 +        BUG();
   2.226 +
   2.227 +    set_fixmap_ma(FIX_GNTTAB, frame << PAGE_SHIFT);
   2.228 +    shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB);
   2.229 +}
     3.1 --- a/linux-2.6.8.1-xen-sparse/include/asm-xen/asm-i386/fixmap.h	Sat Aug 28 15:59:24 2004 +0000
     3.2 +++ b/linux-2.6.8.1-xen-sparse/include/asm-xen/asm-i386/fixmap.h	Mon Aug 30 22:26:01 2004 +0000
     3.3 @@ -75,6 +75,7 @@ enum fixed_addresses {
     3.4  	FIX_PCIE_MCFG,
     3.5  #endif
     3.6  	FIX_SHARED_INFO,
     3.7 +	FIX_GNTTAB,
     3.8  #ifdef CONFIG_XEN_PRIVILEGED_GUEST
     3.9  #define NR_FIX_ISAMAPS	256
    3.10  	FIX_ISAMAP_END,
     4.1 --- a/linux-2.6.8.1-xen-sparse/include/asm-xen/hypervisor.h	Sat Aug 28 15:59:24 2004 +0000
     4.2 +++ b/linux-2.6.8.1-xen-sparse/include/asm-xen/hypervisor.h	Mon Aug 30 22:26:01 2004 +0000
     4.3 @@ -466,6 +466,17 @@ static inline int HYPERVISOR_physdev_op(
     4.4      return ret;
     4.5  }
     4.6  
     4.7 +static inline int HYPERVISOR_grant_table_op(void *gnttab_op)
     4.8 +{
     4.9 +    int ret;
    4.10 +    __asm__ __volatile__ (
    4.11 +        TRAP_INSTR
    4.12 +        : "=a" (ret) : "0" (__HYPERVISOR_grant_table_op),
    4.13 +        "b" (gnttab_op) : "memory" );
    4.14 +
    4.15 +    return ret;
    4.16 +}
    4.17 +
    4.18  static inline int HYPERVISOR_update_va_mapping_otherdomain(
    4.19      unsigned long page_nr, pte_t new_val, unsigned long flags, domid_t domid)
    4.20  {