ia64/xen-unstable

changeset 4693:2f776687450f

bitkeeper revision 1.1389.2.2 (42714ca83Gv7CX98R4gC0TU3w-pX1Q)

Merge xen-2.0-testing "sync w/ unstable" changes.
author cl349@firebug.cl.cam.ac.uk
date Thu Apr 28 20:50:48 2005 +0000 (2005-04-28)
parents c9edf0896f07
children f23e5c9c3f1b
files .rootkeys linux-2.6.11-xen-sparse/arch/xen/kernel/gnttab.c linux-2.6.11-xen-sparse/include/asm-xen/gnttab.h
line diff
     1.1 --- a/.rootkeys	Thu Apr 28 20:47:24 2005 +0000
     1.2 +++ b/.rootkeys	Thu Apr 28 20:50:48 2005 +0000
     1.3 @@ -259,6 +259,7 @@ 40f56239bvOjuuuViZ0XMlNiREFC0A linux-2.6
     1.4  41ab6fa06JdF7jxUsuDcjN3UhuIAxg linux-2.6.11-xen-sparse/arch/xen/kernel/devmem.c
     1.5  40f56238xFQe9T7M_U_FItM-bZIpLw linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c
     1.6  4110f478aeQWllIN7J4kouAHiAqrPw linux-2.6.11-xen-sparse/arch/xen/kernel/fixup.c
     1.7 +412dfae9eA3_6e6bCGUtg1mj8b56fQ linux-2.6.11-xen-sparse/arch/xen/kernel/gnttab.c
     1.8  40f562392LBhwmOxVPsYdkYXMxI_ZQ linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c
     1.9  414c113396tK1HTVeUalm3u-1DF16g linux-2.6.11-xen-sparse/arch/xen/kernel/skbuff.c
    1.10  418f90e4lGdeJK9rmbOB1kN-IKSjsQ linux-2.6.11-xen-sparse/arch/xen/kernel/smp.c
    1.11 @@ -406,6 +407,7 @@ 41af4017PDMuSmMWtSRU5UC9Vylw5g linux-2.6
    1.12  40f5623bYNP7tHE2zX6YQxp9Zq2utQ linux-2.6.11-xen-sparse/include/asm-xen/ctrl_if.h
    1.13  40f5623b3Eqs8pAc5WpPX8_jTzV2qw linux-2.6.11-xen-sparse/include/asm-xen/evtchn.h
    1.14  419b4e9367PjTEvdjwavWN12BeBBXg linux-2.6.11-xen-sparse/include/asm-xen/foreign_page.h
    1.15 +412dfaeazclyNDM0cpnp60Yo4xulpQ linux-2.6.11-xen-sparse/include/asm-xen/gnttab.h
    1.16  40f5623aGPlsm0u1LTO-NVZ6AGzNRQ linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h
    1.17  3f108af1ylCIm82H052FVTfXACBHrw linux-2.6.11-xen-sparse/include/asm-xen/linux-public/privcmd.h
    1.18  3fa8e3f0kBLeE4To2vpdi3cpJbIkbQ linux-2.6.11-xen-sparse/include/asm-xen/linux-public/suspend.h
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/gnttab.c	Thu Apr 28 20:50:48 2005 +0000
     2.3 @@ -0,0 +1,391 @@
     2.4 +/******************************************************************************
     2.5 + * gnttab.c
     2.6 + * 
     2.7 + * Two sets of functionality:
     2.8 + * 1. Granting foreign access to our memory reservation.
     2.9 + * 2. Accessing others' memory reservations via grant references.
    2.10 + * (i.e., mechanisms for both sender and recipient of grant references)
    2.11 + * 
    2.12 + * Copyright (c) 2005, Christopher Clark
    2.13 + * Copyright (c) 2004, K A Fraser
    2.14 + */
    2.15 +
    2.16 +#include <linux/config.h>
    2.17 +#include <linux/module.h>
    2.18 +#include <linux/sched.h>
    2.19 +#include <asm/pgtable.h>
    2.20 +#include <asm/fixmap.h>
    2.21 +#include <asm/uaccess.h>
    2.22 +#include <asm-xen/xen_proc.h>
    2.23 +#include <asm-xen/linux-public/privcmd.h>
    2.24 +#include <asm-xen/gnttab.h>
    2.25 +
    2.26 +#ifndef set_fixmap_ma
    2.27 +#define set_fixmap_ma set_fixmap
    2.28 +#endif
    2.29 +
    2.30 +#if 1
    2.31 +#define ASSERT(_p) \
    2.32 +    if ( !(_p) ) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \
    2.33 +    #_p , __LINE__, __FILE__); *(int*)0=0; }
    2.34 +#else
    2.35 +#define ASSERT(_p) ((void)0)
    2.36 +#endif
    2.37 +
    2.38 +#define WPRINTK(fmt, args...) \
    2.39 +    printk(KERN_WARNING "xen_grant: " fmt, ##args)
    2.40 +
    2.41 +
    2.42 +EXPORT_SYMBOL(gnttab_grant_foreign_access);
    2.43 +EXPORT_SYMBOL(gnttab_end_foreign_access);
    2.44 +EXPORT_SYMBOL(gnttab_query_foreign_access);
    2.45 +EXPORT_SYMBOL(gnttab_grant_foreign_transfer);
    2.46 +EXPORT_SYMBOL(gnttab_end_foreign_transfer);
    2.47 +EXPORT_SYMBOL(gnttab_alloc_grant_references);
    2.48 +EXPORT_SYMBOL(gnttab_free_grant_references);
    2.49 +EXPORT_SYMBOL(gnttab_claim_grant_reference);
    2.50 +EXPORT_SYMBOL(gnttab_release_grant_reference);
    2.51 +EXPORT_SYMBOL(gnttab_grant_foreign_access_ref);
    2.52 +EXPORT_SYMBOL(gnttab_grant_foreign_transfer_ref);
    2.53 +
    2.54 +static grant_ref_t gnttab_free_list[NR_GRANT_ENTRIES];
    2.55 +static grant_ref_t gnttab_free_head;
    2.56 +
    2.57 +static grant_entry_t *shared;
    2.58 +
    2.59 +/*
    2.60 + * Lock-free grant-entry allocator
    2.61 + */
    2.62 +
    2.63 +static inline int
    2.64 +get_free_entry(
    2.65 +    void)
    2.66 +{
    2.67 +    grant_ref_t fh, nfh = gnttab_free_head;
    2.68 +    do { if ( unlikely((fh = nfh) == NR_GRANT_ENTRIES) ) return -1; }
    2.69 +    while ( unlikely((nfh = cmpxchg(&gnttab_free_head, fh,
    2.70 +                                    gnttab_free_list[fh])) != fh) );
    2.71 +    return fh;
    2.72 +}
    2.73 +
    2.74 +static inline void
    2.75 +put_free_entry(
    2.76 +    grant_ref_t ref)
    2.77 +{
    2.78 +    grant_ref_t fh, nfh = gnttab_free_head;
    2.79 +    do { gnttab_free_list[ref] = fh = nfh; wmb(); }
    2.80 +    while ( unlikely((nfh = cmpxchg(&gnttab_free_head, fh, ref)) != fh) );
    2.81 +}
    2.82 +
    2.83 +/*
    2.84 + * Public grant-issuing interface functions
    2.85 + */
    2.86 +
    2.87 +int
    2.88 +gnttab_grant_foreign_access(
    2.89 +    domid_t domid, unsigned long frame, int readonly)
    2.90 +{
    2.91 +    int ref;
    2.92 +    
    2.93 +    if ( unlikely((ref = get_free_entry()) == -1) )
    2.94 +        return -ENOSPC;
    2.95 +
    2.96 +    shared[ref].frame = frame;
    2.97 +    shared[ref].domid = domid;
    2.98 +    wmb();
    2.99 +    shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
   2.100 +
   2.101 +    return ref;
   2.102 +}
   2.103 +
   2.104 +void
   2.105 +gnttab_grant_foreign_access_ref(
   2.106 +    grant_ref_t ref, domid_t domid, unsigned long frame, int readonly)
   2.107 +{
   2.108 +    shared[ref].frame = frame;
   2.109 +    shared[ref].domid = domid;
   2.110 +    wmb();
   2.111 +    shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
   2.112 +}
   2.113 +
   2.114 +
   2.115 +int
   2.116 +gnttab_query_foreign_access( grant_ref_t ref )
   2.117 +{
   2.118 +    u16 nflags;
   2.119 +
   2.120 +    nflags = shared[ref].flags;
   2.121 +
   2.122 +    return ( nflags & (GTF_reading|GTF_writing) );
   2.123 +}
   2.124 +
   2.125 +void
   2.126 +gnttab_end_foreign_access( grant_ref_t ref, int readonly )
   2.127 +{
   2.128 +    u16 flags, nflags;
   2.129 +
   2.130 +    nflags = shared[ref].flags;
   2.131 +    do {
   2.132 +        if ( (flags = nflags) & (GTF_reading|GTF_writing) )
   2.133 +            printk(KERN_ALERT "WARNING: g.e. still in use!\n");
   2.134 +    }
   2.135 +    while ( (nflags = cmpxchg(&shared[ref].flags, flags, 0)) != flags );
   2.136 +
   2.137 +    put_free_entry(ref);
   2.138 +}
   2.139 +
   2.140 +int
   2.141 +gnttab_grant_foreign_transfer(
   2.142 +    domid_t domid, unsigned long pfn )
   2.143 +{
   2.144 +    int ref;
   2.145 +
   2.146 +    if ( unlikely((ref = get_free_entry()) == -1) )
   2.147 +        return -ENOSPC;
   2.148 +
   2.149 +    shared[ref].frame = pfn;
   2.150 +    shared[ref].domid = domid;
   2.151 +    wmb();
   2.152 +    shared[ref].flags = GTF_accept_transfer;
   2.153 +
   2.154 +    return ref;
   2.155 +}
   2.156 +
   2.157 +void
   2.158 +gnttab_grant_foreign_transfer_ref(
   2.159 +    grant_ref_t ref, domid_t domid, unsigned long pfn )
   2.160 +{
   2.161 +    shared[ref].frame = pfn;
   2.162 +    shared[ref].domid = domid;
   2.163 +    wmb();
   2.164 +    shared[ref].flags = GTF_accept_transfer;
   2.165 +}
   2.166 +
   2.167 +unsigned long
   2.168 +gnttab_end_foreign_transfer(
   2.169 +    grant_ref_t ref)
   2.170 +{
   2.171 +    unsigned long frame = 0;
   2.172 +    u16           flags;
   2.173 +
   2.174 +    flags = shared[ref].flags;
   2.175 +    ASSERT(flags == (GTF_accept_transfer | GTF_transfer_committed));
   2.176 +
   2.177 +    /*
   2.178 +     * If a transfer is committed then wait for the frame address to appear.
   2.179 +     * Otherwise invalidate the grant entry against future use.
   2.180 +     */
   2.181 +    if ( likely(flags != GTF_accept_transfer) ||
   2.182 +         (cmpxchg(&shared[ref].flags, flags, 0) != GTF_accept_transfer) )
   2.183 +        while ( unlikely((frame = shared[ref].frame) == 0) )
   2.184 +            cpu_relax();
   2.185 +
   2.186 +    put_free_entry(ref);
   2.187 +
   2.188 +    return frame;
   2.189 +}
   2.190 +
   2.191 +void
   2.192 +gnttab_free_grant_references( u16 count, grant_ref_t head )
   2.193 +{
   2.194 +    /* TODO: O(N)...? */
   2.195 +    grant_ref_t to_die = 0, next = head;
   2.196 +    int i;
   2.197 +
   2.198 +    for ( i = 0; i < count; i++ )
   2.199 +        to_die = next;
   2.200 +        next = gnttab_free_list[next];
   2.201 +        put_free_entry( to_die );
   2.202 +}
   2.203 +
   2.204 +int
   2.205 +gnttab_alloc_grant_references( u16 count,
   2.206 +                               grant_ref_t *head,
   2.207 +                               grant_ref_t *terminal )
   2.208 +{
   2.209 +    int i;
   2.210 +    grant_ref_t h = gnttab_free_head;
   2.211 +
   2.212 +    for ( i = 0; i < count; i++ )
   2.213 +        if ( unlikely(get_free_entry() == -1) )
   2.214 +            goto not_enough_refs;
   2.215 +
   2.216 +    *head = h;
   2.217 +    *terminal = gnttab_free_head;
   2.218 +
   2.219 +    return 0;
   2.220 +
   2.221 +not_enough_refs:
   2.222 +    gnttab_free_head = h;
   2.223 +    return -ENOSPC;
   2.224 +}
   2.225 +
   2.226 +int
   2.227 +gnttab_claim_grant_reference( grant_ref_t *private_head,
   2.228 +                              grant_ref_t  terminal )
   2.229 +{
   2.230 +    grant_ref_t g;
   2.231 +    if ( unlikely((g = *private_head) == terminal) )
   2.232 +        return -ENOSPC;
   2.233 +    *private_head = gnttab_free_list[g];
   2.234 +    return g;
   2.235 +}
   2.236 +
   2.237 +void
   2.238 +gnttab_release_grant_reference( grant_ref_t *private_head,
   2.239 +                                grant_ref_t  release )
   2.240 +{
   2.241 +    gnttab_free_list[release] = *private_head;
   2.242 +    *private_head = release;
   2.243 +}
   2.244 +
   2.245 +/*
   2.246 + * ProcFS operations
   2.247 + */
   2.248 +
   2.249 +#ifdef CONFIG_PROC_FS
   2.250 +
   2.251 +static struct proc_dir_entry *grant_pde;
   2.252 +
   2.253 +static int grant_ioctl(struct inode *inode, struct file *file,
   2.254 +                       unsigned int cmd, unsigned long data)
   2.255 +{
   2.256 +    int                     ret;
   2.257 +    privcmd_hypercall_t     hypercall;
   2.258 +
   2.259 +    /* XXX Need safety checks here if using for anything other
   2.260 +     *     than debugging */
   2.261 +    return -ENOSYS;
   2.262 +
   2.263 +    if ( cmd != IOCTL_PRIVCMD_HYPERCALL )
   2.264 +        return -ENOSYS;
   2.265 +
   2.266 +    if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
   2.267 +        return -EFAULT;
   2.268 +
   2.269 +    if ( hypercall.op != __HYPERVISOR_grant_table_op )
   2.270 +        return -ENOSYS;
   2.271 +
   2.272 +    /* hypercall-invoking asm taken from privcmd.c */
   2.273 +    __asm__ __volatile__ (
   2.274 +        "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; "
   2.275 +        "movl  4(%%eax),%%ebx ;"
   2.276 +        "movl  8(%%eax),%%ecx ;"
   2.277 +        "movl 12(%%eax),%%edx ;"
   2.278 +        "movl 16(%%eax),%%esi ;"
   2.279 +        "movl 20(%%eax),%%edi ;"
   2.280 +        "movl   (%%eax),%%eax ;"
   2.281 +        TRAP_INSTR "; "
   2.282 +        "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
   2.283 +        : "=a" (ret) : "0" (&hypercall) : "memory" );
   2.284 +
   2.285 +    return ret;
   2.286 +}
   2.287 +
   2.288 +static struct file_operations grant_file_ops = {
   2.289 +    ioctl:  grant_ioctl,
   2.290 +};
   2.291 +
   2.292 +static int grant_read(char *page, char **start, off_t off,
   2.293 +                      int count, int *eof, void *data)
   2.294 +{
   2.295 +    int             len;
   2.296 +    unsigned int    i;
   2.297 +    grant_entry_t  *gt;
   2.298 +
   2.299 +    gt = (grant_entry_t *)shared;
   2.300 +    len = 0;
   2.301 +
   2.302 +    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
   2.303 +        /* TODO: safety catch here until this can handle >PAGE_SIZE output */
   2.304 +        if (len > (PAGE_SIZE - 200))
   2.305 +        {
   2.306 +            len += sprintf( page + len, "Truncated.\n");
   2.307 +            break;
   2.308 +        }
   2.309 +
   2.310 +        if ( gt[i].flags )
   2.311 +            len += sprintf( page + len,
   2.312 +                    "Grant: ref (0x%x) flags (0x%hx) dom (0x%hx) frame (0x%x)\n", 
   2.313 +                    i,
   2.314 +                    gt[i].flags,
   2.315 +                    gt[i].domid,
   2.316 +                    gt[i].frame );
   2.317 +
   2.318 +    *eof = 1;
   2.319 +    return len;
   2.320 +}
   2.321 +
   2.322 +static int grant_write(struct file *file, const char __user *buffer,
   2.323 +                       unsigned long count, void *data)
   2.324 +{
   2.325 +    /* TODO: implement this */
   2.326 +    return -ENOSYS;
   2.327 +}
   2.328 +
   2.329 +#endif /* CONFIG_PROC_FS */
   2.330 +
   2.331 +int gnttab_resume(void)
   2.332 +{
   2.333 +    gnttab_setup_table_t setup;
   2.334 +    unsigned long        frames[NR_GRANT_FRAMES];
   2.335 +    int                  i;
   2.336 +
   2.337 +    setup.dom        = DOMID_SELF;
   2.338 +    setup.nr_frames  = NR_GRANT_FRAMES;
   2.339 +    setup.frame_list = frames;
   2.340 +
   2.341 +    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1) != 0);
   2.342 +    BUG_ON(setup.status != 0);
   2.343 +
   2.344 +    for ( i = 0; i < NR_GRANT_FRAMES; i++ )
   2.345 +        set_fixmap_ma(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT);
   2.346 +
   2.347 +    return 0;
   2.348 +}
   2.349 +
   2.350 +int gnttab_suspend(void)
   2.351 +{
   2.352 +    int i;
   2.353 +
   2.354 +    for ( i = 0; i < NR_GRANT_FRAMES; i++ )
   2.355 +	clear_fixmap(FIX_GNTTAB_END - i);
   2.356 +
   2.357 +    return 0;
   2.358 +}
   2.359 +
   2.360 +static int __init gnttab_init(void)
   2.361 +{
   2.362 +    int i;
   2.363 +
   2.364 +    BUG_ON(gnttab_resume());
   2.365 +
   2.366 +    shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB_END);
   2.367 +
   2.368 +    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
   2.369 +        gnttab_free_list[i] = i + 1;
   2.370 +    
   2.371 +#ifdef CONFIG_PROC_FS
   2.372 +    /*
   2.373 +     *  /proc/xen/grant : used by libxc to access grant tables
   2.374 +     */
   2.375 +    if ( (grant_pde = create_xen_proc_entry("grant", 0600)) == NULL )
   2.376 +    {
   2.377 +        WPRINTK("Unable to create grant xen proc entry\n");
   2.378 +        return -1;
   2.379 +    }
   2.380 +
   2.381 +    grant_file_ops.read   = grant_pde->proc_fops->read;
   2.382 +    grant_file_ops.write  = grant_pde->proc_fops->write;
   2.383 +
   2.384 +    grant_pde->proc_fops  = &grant_file_ops;
   2.385 +
   2.386 +    grant_pde->read_proc  = &grant_read;
   2.387 +    grant_pde->write_proc = &grant_write;
   2.388 +#endif
   2.389 +
   2.390 +    printk("Grant table initialized\n");
   2.391 +    return 0;
   2.392 +}
   2.393 +
   2.394 +__initcall(gnttab_init);
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/gnttab.h	Thu Apr 28 20:50:48 2005 +0000
     3.3 @@ -0,0 +1,72 @@
     3.4 +/******************************************************************************
     3.5 + * gnttab.h
     3.6 + * 
     3.7 + * Two sets of functionality:
     3.8 + * 1. Granting foreign access to our memory reservation.
     3.9 + * 2. Accessing others' memory reservations via grant references.
    3.10 + * (i.e., mechanisms for both sender and recipient of grant references)
    3.11 + * 
    3.12 + * Copyright (c) 2004, K A Fraser
    3.13 + * Copyright (c) 2005, Christopher Clark
    3.14 + */
    3.15 +
    3.16 +#ifndef __ASM_GNTTAB_H__
    3.17 +#define __ASM_GNTTAB_H__
    3.18 +
    3.19 +#include <linux/config.h>
    3.20 +#include <asm-xen/hypervisor.h>
    3.21 +#include <asm-xen/xen-public/grant_table.h>
    3.22 +
    3.23 +/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
    3.24 +#define NR_GRANT_FRAMES 4
    3.25 +#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
    3.26 +
    3.27 +int
    3.28 +gnttab_grant_foreign_access(
    3.29 +    domid_t domid, unsigned long frame, int readonly);
    3.30 +
    3.31 +void
    3.32 +gnttab_end_foreign_access(
    3.33 +    grant_ref_t ref, int readonly);
    3.34 +
    3.35 +int
    3.36 +gnttab_grant_foreign_transfer(
    3.37 +    domid_t domid, unsigned long pfn);
    3.38 +
    3.39 +unsigned long
    3.40 +gnttab_end_foreign_transfer(
    3.41 +    grant_ref_t ref);
    3.42 +
    3.43 +int
    3.44 +gnttab_query_foreign_access( 
    3.45 +    grant_ref_t ref );
    3.46 +
    3.47 +/*
    3.48 + * operations on reserved batches of grant references
    3.49 + */
    3.50 +int
    3.51 +gnttab_alloc_grant_references(
    3.52 +    u16 count, grant_ref_t *pprivate_head, grant_ref_t *private_terminal );
    3.53 +
    3.54 +void
    3.55 +gnttab_free_grant_references(
    3.56 +    u16 count, grant_ref_t private_head );
    3.57 +
    3.58 +int
    3.59 +gnttab_claim_grant_reference( grant_ref_t *pprivate_head, grant_ref_t terminal
    3.60 +);
    3.61 +
    3.62 +void
    3.63 +gnttab_release_grant_reference(
    3.64 +    grant_ref_t *private_head, grant_ref_t release );
    3.65 +
    3.66 +void
    3.67 +gnttab_grant_foreign_access_ref(
    3.68 +    grant_ref_t ref, domid_t domid, unsigned long frame, int readonly);
    3.69 +
    3.70 +void
    3.71 +gnttab_grant_foreign_transfer_ref(
    3.72 +    grant_ref_t, domid_t domid, unsigned long pfn);
    3.73 +
    3.74 +
    3.75 +#endif /* __ASM_GNTTAB_H__ */