ia64/xen-unstable

changeset 2322:4950b4d2cf62

bitkeeper revision 1.1159.48.1 (4126259181cq4hyB3cquYrgpQokAIQ)

Framework for grant-table implementation in Xen.
author kaf24@scramble.cl.cam.ac.uk
date Fri Aug 20 16:23:45 2004 +0000 (2004-08-20)
parents 959e38e07474
children 274473cddeee
files .rootkeys xen/arch/x86/domain.c xen/common/domain.c xen/common/grant_table.c xen/common/kernel.c xen/common/page_alloc.c xen/include/asm-x86/mm.h xen/include/xen/grant_table.h xen/include/xen/sched.h
line diff
     1.1 --- a/.rootkeys	Fri Aug 20 14:02:42 2004 +0000
     1.2 +++ b/.rootkeys	Fri Aug 20 16:23:45 2004 +0000
     1.3 @@ -571,6 +571,7 @@ 3e6377e4i0c9GtKN65e99OtRbw3AZw xen/commo
     1.4  3ddb79bdYO5D8Av12NHqPeSviav7cg xen/common/domain.c
     1.5  40f2b4a27xPOh3R6zD4M_aabz-TDyg xen/common/elf.c
     1.6  3fba5b96H0khoxNiKbjdi0inpXV-Pw xen/common/event_channel.c
     1.7 +41262590gGIOn-1pvF5KpUu8Wb6_JA xen/common/grant_table.c
     1.8  3ddb79bd9drcFPVxd4w2GPOIjLlXpA xen/common/kernel.c
     1.9  3e4cd9d8LAAghUY0hNIK72uc2ch_Nw xen/common/keyhandler.c
    1.10  3ddb79bduhSEZI8xa7IbGQCpap5y2A xen/common/lib.c
    1.11 @@ -719,6 +720,7 @@ 3ddb79c05DdHQ0UxX_jKsXdR4QlMCA xen/inclu
    1.12  3ddb79c2O729EttZTYu1c8LcsUO_GQ xen/include/xen/elf.h
    1.13  3ddb79c0HIghfBF8zFUdmXhOU8i6hA xen/include/xen/errno.h
    1.14  3ddb79c1W0lQca8gRV7sN6j3iY4Luw xen/include/xen/event.h
    1.15 +41262590CyJy4vd42dnqzsn8-eeGvw xen/include/xen/grant_table.h
    1.16  3ddb79c0GurNF9tDWqQbAwJFH8ugfA xen/include/xen/init.h
    1.17  3ddb79c1nzaWu8NoF4xCCMSFJR4MlA xen/include/xen/ioport.h
    1.18  3ddb79c2qAxCOABlkKtD8Txohe-qEw xen/include/xen/irq.h
     2.1 --- a/xen/arch/x86/domain.c	Fri Aug 20 14:02:42 2004 +0000
     2.2 +++ b/xen/arch/x86/domain.c	Fri Aug 20 16:23:45 2004 +0000
     2.3 @@ -472,13 +472,19 @@ void domain_relinquish_memory(struct dom
     2.4       */
     2.5      destroy_gdt(d);
     2.6  
     2.7 -    /* Relinquish Xen-heap pages. Currently this can only be 'shared_info'. */
     2.8 -    page = virt_to_page(d->shared_info);
     2.9 -    if ( test_and_clear_bit(_PGC_allocated, &page->u.inuse.count_info) )
    2.10 -        put_page(page);
    2.11 +    /* Use a recursive lock, as we may enter 'free_domheap_page'. */
    2.12 +    spin_lock_recursive(&d->page_alloc_lock);
    2.13 +
    2.14 +    /* Relinquish Xen-heap pages. */
    2.15 +    list_for_each_safe ( ent, tmp, &d->xenpage_list )
    2.16 +    {
    2.17 +        page = list_entry(ent, struct pfn_info, list);
    2.18 +
    2.19 +        if ( test_and_clear_bit(_PGC_allocated, &page->u.inuse.count_info) )
    2.20 +            put_page(page);
    2.21 +    }
    2.22  
    2.23      /* Relinquish all pages on the domain's allocation list. */
    2.24 -    spin_lock_recursive(&d->page_alloc_lock); /* may enter free_domheap_page */
    2.25      list_for_each_safe ( ent, tmp, &d->page_list )
    2.26      {
    2.27          page = list_entry(ent, struct pfn_info, list);
    2.28 @@ -507,6 +513,7 @@ void domain_relinquish_memory(struct dom
    2.29          }
    2.30          while ( unlikely(y != x) );
    2.31      }
    2.32 +
    2.33      spin_unlock_recursive(&d->page_alloc_lock);
    2.34  }
    2.35  
     3.1 --- a/xen/common/domain.c	Fri Aug 20 14:02:42 2004 +0000
     3.2 +++ b/xen/common/domain.c	Fri Aug 20 16:23:45 2004 +0000
     3.3 @@ -45,7 +45,7 @@ struct domain *do_createdomain(domid_t d
     3.4  
     3.5      spin_lock_init(&d->page_alloc_lock);
     3.6      INIT_LIST_HEAD(&d->page_list);
     3.7 -    d->max_pages = d->tot_pages = 0;
     3.8 +    INIT_LIST_HEAD(&d->xenpage_list);
     3.9  
    3.10      /* Per-domain PCI-device list. */
    3.11      spin_lock_init(&d->pcidev_lock);
    3.12 @@ -53,12 +53,13 @@ struct domain *do_createdomain(domid_t d
    3.13  
    3.14      if ( d->domain != IDLE_DOMAIN_ID )
    3.15      {
    3.16 -        if ( init_event_channels(d) != 0 )
    3.17 +        if ( (init_event_channels(d) != 0) || (grant_table_create(d) != 0) )
    3.18          {
    3.19 +            destroy_event_channels(d);
    3.20              free_domain_struct(d);
    3.21              return NULL;
    3.22          }
    3.23 -        
    3.24 +
    3.25          /* We use a large intermediate to avoid overflow in sprintf. */
    3.26          sprintf(buf, "Domain-%u", dom_id);
    3.27          strncpy(d->name, buf, MAX_DOMAIN_NAME);
    3.28 @@ -256,6 +257,7 @@ void domain_destruct(struct domain *d)
    3.29      write_unlock_irqrestore(&tasklist_lock, flags);
    3.30  
    3.31      destroy_event_channels(d);
    3.32 +    grant_table_destroy(d);
    3.33  
    3.34      free_perdomain_pt(d);
    3.35      free_xenheap_page((unsigned long)d->shared_info);
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xen/common/grant_table.c	Fri Aug 20 16:23:45 2004 +0000
     4.3 @@ -0,0 +1,134 @@
     4.4 +/******************************************************************************
     4.5 + * common/grant_table.c
     4.6 + * 
     4.7 + * Mechanism for granting foreign access to page frames, and receiving
     4.8 + * page-ownership transfers.
     4.9 + * 
    4.10 + * Copyright (c) 2004 K A Fraser
    4.11 + * 
    4.12 + * This program is free software; you can redistribute it and/or modify
    4.13 + * it under the terms of the GNU General Public License as published by
    4.14 + * the Free Software Foundation; either version 2 of the License, or
    4.15 + * (at your option) any later version.
    4.16 + * 
    4.17 + * This program is distributed in the hope that it will be useful,
    4.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.20 + * GNU General Public License for more details.
    4.21 + * 
    4.22 + * You should have received a copy of the GNU General Public License
    4.23 + * along with this program; if not, write to the Free Software
    4.24 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    4.25 + */
    4.26 +
    4.27 +#define __GRANT_TABLE_IMPLEMENTATION__
    4.28 +typedef struct grant_table grant_table_t;
    4.29 +
    4.30 +#include <xen/config.h>
    4.31 +#include <xen/sched.h>
    4.32 +#include <hypervisor-ifs/grant_table.h>
    4.33 +
    4.34 +/* Active grant entry - used for shadowing GTF_permit_access grants. */
    4.35 +typedef struct {
    4.36 +    u32           counts; /* Reference count information.   */
    4.37 +    u16           next;   /* Mapping hash chain.            */
    4.38 +    domid_t       domid;  /* Domain being granted access.   */
    4.39 +    unsigned long frame;  /* Frame being granted.           */
    4.40 +} active_grant_entry_t;
    4.41 +
    4.42 +/* Bitfields in active_grant_entry_t:counts. */
    4.43 + /* Grant is pinned by 'domid' for read mappings and I/O. */
    4.44 +#define _GNTCNT_read_pinned  (0)
    4.45 +#define GNTCNT_read_pinned   (1<<_GNTCNT_read_pinned)
    4.46 + /* Grant is pinned by 'domid' for write mappings and I/O. */
    4.47 +#define _GNTCNT_write_pinned (1)
    4.48 +#define GNTCNT_write_pinned  (1<<_GNTCNT_write_pinned)
    4.49 + /* Grant is pinned in IOMMU (read-only unless GNTCNT_write_pinned). */
    4.50 +#define _GNTCNT_io_pinned    (2)
    4.51 +#define GNTCNT_io_pinned     (1<<_GNTCNT_io_pinned)
    4.52 + /* Grant is mappable (read-only unless GNTCNT_write_pinned). */
    4.53 +#define _GNTCNT_mappable     (3)
    4.54 +#define GNTCNT_mappable      (1<<_GNTCNT_mappable)
    4.55 + /* Count of writable page mappings. (!GNTCNT_write_pinned => count==0). */
    4.56 +#define GNTCNT_wmap_shift    (4)
    4.57 +#define GNTCNT_wmap_mask     (0x3FFFU << GNTCNT_wmap_shift)
    4.58 + /* Count of read-only page mappings. */
    4.59 +#define GNTCNT_rmap_shift    (18)
    4.60 +#define GNTCNT_rmap_mask     (0x3FFFU << GNTCNT_rmap_shift)
    4.61 +
    4.62 +#define MAPHASH_SZ       (256)
    4.63 +#define MAPHASH(_k)      ((_k) & (MAPHASH_SZ-1))
    4.64 +#define MAPHASH_INVALID  (0xFFFFU)
    4.65 +
    4.66 +#define NR_GRANT_ENTRIES     (PAGE_SIZE / sizeof(grant_entry_t))
    4.67 +
    4.68 +/* Per-domain grant information. */
    4.69 +struct grant_table {
    4.70 +    /* Shared grant table (see include/hypervisor-ifs/grant_table.h). */
    4.71 +    grant_entry_t        *shared;
    4.72 +    /* Active grant table. */
    4.73 +    active_grant_entry_t *active;
    4.74 +    /* Lock protecting updates to maphash and shared grant table. */
    4.75 +    spinlock_t            lock;
    4.76 +    /* Hash table: frame -> active grant entry. */
    4.77 +    u16                   maphash[MAPHASH_SZ];
    4.78 +};
    4.79 +
    4.80 +int grant_table_create(struct domain *d)
    4.81 +{
    4.82 +    grant_table_t *t;
    4.83 +    int            i;
    4.84 +
    4.85 +    if ( (t = xmalloc(sizeof(grant_table_t))) == NULL )
    4.86 +        goto no_mem;
    4.87 +
    4.88 +    /* Simple stuff. */
    4.89 +    t->shared = NULL;
    4.90 +    t->active = NULL;
    4.91 +    spin_lock_init(&t->lock);
    4.92 +    for ( i = 0; i < MAPHASH_SZ; i++ )
    4.93 +        t->maphash[i] = MAPHASH_INVALID;
    4.94 +
    4.95 +    /* Active grant-table page. */
    4.96 +    if ( (t->active = xmalloc(sizeof(active_grant_entry_t) * 
    4.97 +                              NR_GRANT_ENTRIES)) == NULL )
    4.98 +        goto no_mem;
    4.99 +
   4.100 +    /* Set up shared grant-table page. */
   4.101 +    if ( (t->shared = (void *)alloc_xenheap_page()) == NULL )
   4.102 +        goto no_mem;
   4.103 +    memset(t->shared, 0, PAGE_SIZE);
   4.104 +    SHARE_PFN_WITH_DOMAIN(virt_to_page(t->shared), d);
   4.105 +
   4.106 +    /* Okay, install the structure. */
   4.107 +    d->grant_table = t;
   4.108 +    return 0;
   4.109 +
   4.110 + no_mem:
   4.111 +    if ( t != NULL )
   4.112 +    {
   4.113 +        if ( t->active != NULL )
   4.114 +            xfree(t->active);
   4.115 +        xfree(t);
   4.116 +    }
   4.117 +    return -ENOMEM;
   4.118 +}
   4.119 +
   4.120 +void grant_table_destroy(struct domain *d)
   4.121 +{
   4.122 +    grant_table_t *t;
   4.123 +
   4.124 +    if ( (t = d->grant_table) != NULL )
   4.125 +    {
   4.126 +        /* Free memory relating to this grant table. */
   4.127 +        d->grant_table = NULL;
   4.128 +        free_xenheap_page((unsigned long)t->shared);
   4.129 +        xfree(t->active);
   4.130 +        xfree(t);
   4.131 +    }
   4.132 +}
   4.133 +
   4.134 +void grant_table_init(void)
   4.135 +{
   4.136 +    /* Nothing. */
   4.137 +}
     5.1 --- a/xen/common/kernel.c	Fri Aug 20 14:02:42 2004 +0000
     5.2 +++ b/xen/common/kernel.c	Fri Aug 20 16:23:45 2004 +0000
     5.3 @@ -304,6 +304,8 @@ void cmain(multiboot_info_t *mbi)
     5.4  
     5.5      start_of_day();
     5.6  
     5.7 +    grant_table_init();
     5.8 +
     5.9      /* Create initial domain 0. */
    5.10      new_dom = do_createdomain(0, 0);
    5.11      if ( new_dom == NULL )
     6.1 --- a/xen/common/page_alloc.c	Fri Aug 20 14:02:42 2004 +0000
     6.2 +++ b/xen/common/page_alloc.c	Fri Aug 20 16:23:45 2004 +0000
     6.3 @@ -418,6 +418,8 @@ void free_domheap_pages(struct pfn_info 
     6.4      if ( unlikely(IS_XEN_HEAP_FRAME(pg)) )
     6.5      {
     6.6          spin_lock_recursive(&d->page_alloc_lock);
     6.7 +        for ( i = 0; i < (1 << order); i++ )
     6.8 +            list_del(&pg[i].list);
     6.9          d->xenheap_pages -= 1 << order;
    6.10          drop_dom_ref = (d->xenheap_pages == 0);
    6.11          spin_unlock_recursive(&d->page_alloc_lock);
     7.1 --- a/xen/include/asm-x86/mm.h	Fri Aug 20 14:02:42 2004 +0000
     7.2 +++ b/xen/include/asm-x86/mm.h	Fri Aug 20 16:23:45 2004 +0000
     7.3 @@ -109,6 +109,7 @@ struct pfn_info
     7.4          (_pfn)->u.inuse.count_info = PGC_allocated | 1;                     \
     7.5          if ( unlikely((_dom)->xenheap_pages++ == 0) )                       \
     7.6              get_knownalive_domain(_dom);                                    \
     7.7 +        list_add_tail(&(_pfn)->list, &(_dom)->xenpage_list);                \
     7.8          spin_unlock(&(_dom)->page_alloc_lock);                              \
     7.9      } while ( 0 )
    7.10  
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/xen/include/xen/grant_table.h	Fri Aug 20 16:23:45 2004 +0000
     8.3 @@ -0,0 +1,38 @@
     8.4 +/******************************************************************************
     8.5 + * include/xen/grant_table.h
     8.6 + * 
     8.7 + * Mechanism for granting foreign access to page frames, and receiving
     8.8 + * page-ownership transfers.
     8.9 + * 
    8.10 + * Copyright (c) 2004 K A Fraser
    8.11 + * 
    8.12 + * This program is free software; you can redistribute it and/or modify
    8.13 + * it under the terms of the GNU General Public License as published by
    8.14 + * the Free Software Foundation; either version 2 of the License, or
    8.15 + * (at your option) any later version.
    8.16 + * 
    8.17 + * This program is distributed in the hope that it will be useful,
    8.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.20 + * GNU General Public License for more details.
    8.21 + * 
    8.22 + * You should have received a copy of the GNU General Public License
    8.23 + * along with this program; if not, write to the Free Software
    8.24 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    8.25 + */
    8.26 +
    8.27 +#ifndef __XEN_GRANT_H__
    8.28 +#define __XEN_GRANT_H__
    8.29 +
    8.30 +#ifndef __GRANT_TABLE_IMPLEMENTATION__
    8.31 +typedef void grant_table_t;
    8.32 +#endif
    8.33 +
    8.34 +/* Start-of-day system initialisation. */
    8.35 +void grant_table_init(void);
    8.36 +
    8.37 +/* Create/destroy per-domain grant table context. */
    8.38 +int  grant_table_create(struct domain *d);
    8.39 +void grant_table_destroy(struct domain *d);
    8.40 +
    8.41 +#endif /* __XEN_GRANT_H__ */
     9.1 --- a/xen/include/xen/sched.h	Fri Aug 20 14:02:42 2004 +0000
     9.2 +++ b/xen/include/xen/sched.h	Fri Aug 20 16:23:45 2004 +0000
     9.3 @@ -4,16 +4,13 @@
     9.4  #include <xen/config.h>
     9.5  #include <xen/types.h>
     9.6  #include <xen/spinlock.h>
     9.7 -#ifdef LINUX_2_6
     9.8 -#include <linux/thread_info.h>
     9.9 -#endif
    9.10  #include <asm/ptrace.h>
    9.11  #include <xen/smp.h>
    9.12  #include <asm/page.h>
    9.13  #include <asm/processor.h>
    9.14  #include <hypervisor-ifs/hypervisor-if.h>
    9.15  #include <hypervisor-ifs/dom0_ops.h>
    9.16 -
    9.17 +#include <xen/grant_table.h>
    9.18  #include <xen/list.h>
    9.19  #include <xen/time.h>
    9.20  #include <xen/ac_timer.h>
    9.21 @@ -95,6 +92,7 @@ struct domain
    9.22  
    9.23      spinlock_t       page_alloc_lock; /* protects all the following fields  */
    9.24      struct list_head page_list;       /* linked list, of size tot_pages     */
    9.25 +    struct list_head xenpage_list;    /* linked list, of size xenheap_pages */
    9.26      unsigned int     tot_pages;       /* number of pages currently possesed */
    9.27      unsigned int     max_pages;       /* maximum value for tot_pages        */
    9.28      unsigned int     xenheap_pages;   /* # pages allocated from Xen heap    */
    9.29 @@ -121,6 +119,8 @@ struct domain
    9.30      unsigned int     max_event_channel;
    9.31      spinlock_t       event_channel_lock;
    9.32  
    9.33 +    grant_table_t *grant_table;
    9.34 +
    9.35      /*
    9.36       * Interrupt to event-channel mappings. Updates should be protected by the 
    9.37       * domain's event-channel spinlock. Read accesses can also synchronise on