ia64/xen-unstable

changeset 8430:9b108cf447e5

Merge with xen-ia64-unstable.hg.
author kaf24@firebug.cl.cam.ac.uk
date Wed Dec 21 19:52:00 2005 +0100 (2005-12-21)
parents 5a790011259e a4de51a2629f
children 8b322047c80f
files
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c	Wed Dec 21 11:56:19 2005 -0600
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c	Wed Dec 21 19:52:00 2005 +0100
     1.3 @@ -27,6 +27,12 @@
     1.4   * IN THE SOFTWARE.
     1.5   */
     1.6  
     1.7 +#include <asm-xen/evtchn.h>
     1.8 +#include <asm-xen/gnttab.h>
     1.9 +#include <asm-xen/xenbus.h>
    1.10 +
    1.11 +/* xenbus_probe.c */
    1.12 +extern char *kasprintf(const char *fmt, ...);
    1.13  
    1.14  #if 0
    1.15  #define DPRINTK(fmt, args...) \
    1.16 @@ -36,11 +42,6 @@
    1.17  #endif
    1.18  
    1.19  
    1.20 -#include <asm-xen/evtchn.h>
    1.21 -#include <asm-xen/gnttab.h>
    1.22 -#include <asm-xen/xenbus.h>
    1.23 -
    1.24 -
    1.25  int xenbus_watch_path(struct xenbus_device *dev, const char *path,
    1.26  		      struct xenbus_watch *watch, 
    1.27  		      void (*callback)(struct xenbus_watch *,
    1.28 @@ -70,16 +71,11 @@ int xenbus_watch_path2(struct xenbus_dev
    1.29  					const char **, unsigned int))
    1.30  {
    1.31  	int err;
    1.32 -	char *state =
    1.33 -		kmalloc(strlen(path) + 1 + strlen(path2) + 1, GFP_KERNEL);
    1.34 +	char *state = kasprintf("%s/%s", path, path2);
    1.35  	if (!state) {
    1.36  		xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch");
    1.37  		return -ENOMEM;
    1.38  	}
    1.39 -	strcpy(state, path);
    1.40 -	strcat(state, "/");
    1.41 -	strcat(state, path2);
    1.42 -
    1.43  	err = xenbus_watch_path(dev, state, watch, callback);
    1.44  
    1.45  	if (err) {
    1.46 @@ -126,16 +122,7 @@ EXPORT_SYMBOL(xenbus_switch_state);
    1.47   */
    1.48  static char *error_path(struct xenbus_device *dev)
    1.49  {
    1.50 -	char *path_buffer = kmalloc(strlen("error/") + strlen(dev->nodename) +
    1.51 -				    1, GFP_KERNEL);
    1.52 -	if (path_buffer == NULL) {
    1.53 -		return NULL;
    1.54 -	}
    1.55 -
    1.56 -	strcpy(path_buffer, "error/");
    1.57 -	strcpy(path_buffer + strlen("error/"), dev->nodename);
    1.58 -
    1.59 -	return path_buffer;
    1.60 +	return kasprintf("error/%s", dev->nodename);
    1.61  }
    1.62  
    1.63  
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Wed Dec 21 11:56:19 2005 -0600
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Wed Dec 21 19:52:00 2005 +0100
     2.3 @@ -505,7 +505,7 @@ static void xenbus_dev_release(struct de
     2.4  }
     2.5  
     2.6  /* Simplified asprintf. */
     2.7 -static char *kasprintf(const char *fmt, ...)
     2.8 +char *kasprintf(const char *fmt, ...)
     2.9  {
    2.10  	va_list ap;
    2.11  	unsigned int len;
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Wed Dec 21 11:56:19 2005 -0600
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Wed Dec 21 19:52:00 2005 +0100
     3.3 @@ -41,6 +41,9 @@
     3.4  #include <asm-xen/xenbus.h>
     3.5  #include "xenbus_comms.h"
     3.6  
     3.7 +/* xenbus_probe.c */
     3.8 +extern char *kasprintf(const char *fmt, ...);
     3.9 +
    3.10  #define streq(a, b) (strcmp((a), (b)) == 0)
    3.11  
    3.12  struct xs_stored_msg {
    3.13 @@ -276,18 +279,11 @@ static char *join(const char *dir, const
    3.14  {
    3.15  	char *buffer;
    3.16  
    3.17 -	buffer = kmalloc(strlen(dir) + strlen("/") + strlen(name) + 1,
    3.18 -			 GFP_KERNEL);
    3.19 -	if (buffer == NULL)
    3.20 -		return ERR_PTR(-ENOMEM);
    3.21 -
    3.22 -	strcpy(buffer, dir);
    3.23 -	if (!streq(name, "")) {
    3.24 -		strcat(buffer, "/");
    3.25 -		strcat(buffer, name);
    3.26 -	}
    3.27 -
    3.28 -	return buffer;
    3.29 +	if (strlen(name) == 0)
    3.30 +		buffer = kasprintf("%s", dir);
    3.31 +	else
    3.32 +		buffer = kasprintf("%s/%s", dir, name);
    3.33 +	return (!buffer) ? ERR_PTR(-ENOMEM) : buffer;
    3.34  }
    3.35  
    3.36  static char **split(char *strings, unsigned int len, unsigned int *num)
     4.1 --- a/xen/arch/x86/domain.c	Wed Dec 21 11:56:19 2005 -0600
     4.2 +++ b/xen/arch/x86/domain.c	Wed Dec 21 19:52:00 2005 +0100
     4.3 @@ -957,8 +957,6 @@ void domain_relinquish_resources(struct 
     4.4  
     4.5      ptwr_destroy(d);
     4.6  
     4.7 -    gnttab_release_mappings(d);
     4.8 -
     4.9      /* Drop the in-use references to page-table bases. */
    4.10      for_each_vcpu ( d, v )
    4.11      {
     5.1 --- a/xen/arch/x86/mm.c	Wed Dec 21 11:56:19 2005 -0600
     5.2 +++ b/xen/arch/x86/mm.c	Wed Dec 21 19:52:00 2005 +0100
     5.3 @@ -1930,105 +1930,6 @@ int do_mmuext_op(
     5.4              }
     5.5              break;
     5.6          }
     5.7 -
     5.8 -        case MMUEXT_REASSIGN_PAGE:
     5.9 -            if ( unlikely(!IS_PRIV(d)) )
    5.10 -            {
    5.11 -                MEM_LOG("Dom %u has no reassignment priv", d->domain_id);
    5.12 -                okay = 0;
    5.13 -                break;
    5.14 -            }
    5.15 -            
    5.16 -            e = percpu_info[cpu].foreign;
    5.17 -            if ( unlikely(e == NULL) )
    5.18 -            {
    5.19 -                MEM_LOG("No FOREIGNDOM to reassign mfn %lx to", mfn);
    5.20 -                okay = 0;
    5.21 -                break;
    5.22 -            }
    5.23 -            
    5.24 -            /*
    5.25 -             * Grab both page_list locks, in order. This prevents the page from
    5.26 -             * disappearing elsewhere while we modify the owner, and we'll need
    5.27 -             * both locks if we're successful so that we can change lists.
    5.28 -             */
    5.29 -            if ( d < e )
    5.30 -            {
    5.31 -                spin_lock(&d->page_alloc_lock);
    5.32 -                spin_lock(&e->page_alloc_lock);
    5.33 -            }
    5.34 -            else
    5.35 -            {
    5.36 -                spin_lock(&e->page_alloc_lock);
    5.37 -                spin_lock(&d->page_alloc_lock);
    5.38 -            }
    5.39 -            
    5.40 -            /*
    5.41 -             * Check that 'e' will accept the page and has reservation
    5.42 -             * headroom. Also, a domain mustn't have PGC_allocated pages when
    5.43 -             * it is dying. 
    5.44 -             */
    5.45 -            ASSERT(e->tot_pages <= e->max_pages);
    5.46 -            if ( unlikely(test_bit(_DOMF_dying, &e->domain_flags)) ||
    5.47 -                 unlikely(e->tot_pages == e->max_pages) ||
    5.48 -                 unlikely(IS_XEN_HEAP_FRAME(page)) )
    5.49 -            {
    5.50 -                MEM_LOG("Transferee has no reservation headroom (%d,%d), or "
    5.51 -                        "page is in Xen heap (%lx), or dom is dying (%ld).",
    5.52 -                        e->tot_pages, e->max_pages, mfn, e->domain_flags);
    5.53 -                okay = 0;
    5.54 -                goto reassign_fail;
    5.55 -            }
    5.56 -
    5.57 -            /*
    5.58 -             * The tricky bit: atomically change owner while there is just one
    5.59 -             * benign reference to the page (PGC_allocated). If that reference
    5.60 -             * disappears then the deallocation routine will safely spin.
    5.61 -             */
    5.62 -            _d  = pickle_domptr(d);
    5.63 -            _nd = page->u.inuse._domain;
    5.64 -            y   = page->count_info;
    5.65 -            do {
    5.66 -                x = y;
    5.67 -                if ( unlikely((x & (PGC_count_mask|PGC_allocated)) != 
    5.68 -                              (1|PGC_allocated)) ||
    5.69 -                     unlikely(_nd != _d) )
    5.70 -                {
    5.71 -                    MEM_LOG("Bad page values %lx: ed=%p(%u), sd=%p,"
    5.72 -                            " caf=%08x, taf=%" PRtype_info,
    5.73 -                            page_to_pfn(page), d, d->domain_id,
    5.74 -                            unpickle_domptr(_nd), x, page->u.inuse.type_info);
    5.75 -                    okay = 0;
    5.76 -                    goto reassign_fail;
    5.77 -                }
    5.78 -                __asm__ __volatile__(
    5.79 -                    LOCK_PREFIX "cmpxchg8b %3"
    5.80 -                    : "=d" (_nd), "=a" (y), "=c" (e),
    5.81 -                    "=m" (*(volatile u64 *)(&page->count_info))
    5.82 -                    : "0" (_d), "1" (x), "c" (e), "b" (x) );
    5.83 -            } 
    5.84 -            while ( unlikely(_nd != _d) || unlikely(y != x) );
    5.85 -            
    5.86 -            /*
    5.87 -             * Unlink from 'd'. We transferred at least one reference to 'e',
    5.88 -             * so noone else is spinning to try to delete this page from 'd'.
    5.89 -             */
    5.90 -            d->tot_pages--;
    5.91 -            list_del(&page->list);
    5.92 -            
    5.93 -            /*
    5.94 -             * Add the page to 'e'. Someone may already have removed the last
    5.95 -             * reference and want to remove the page from 'e'. However, we have
    5.96 -             * the lock so they'll spin waiting for us.
    5.97 -             */
    5.98 -            if ( unlikely(e->tot_pages++ == 0) )
    5.99 -                get_knownalive_domain(e);
   5.100 -            list_add_tail(&page->list, &e->page_list);
   5.101 -            
   5.102 -        reassign_fail:        
   5.103 -            spin_unlock(&d->page_alloc_lock);
   5.104 -            spin_unlock(&e->page_alloc_lock);
   5.105 -            break;
   5.106              
   5.107          default:
   5.108              MEM_LOG("Invalid extended pt command 0x%x", op.cmd);
     6.1 --- a/xen/arch/x86/setup.c	Wed Dec 21 11:56:19 2005 -0600
     6.2 +++ b/xen/arch/x86/setup.c	Wed Dec 21 19:52:00 2005 +0100
     6.3 @@ -488,8 +488,6 @@ void __init __start_xen(multiboot_info_t
     6.4  
     6.5      start_of_day();
     6.6  
     6.7 -    grant_table_init();
     6.8 -
     6.9      shadow_mode_init();
    6.10  
    6.11      /* initialize access control security module */
     7.1 --- a/xen/common/domain.c	Wed Dec 21 11:56:19 2005 -0600
     7.2 +++ b/xen/common/domain.c	Wed Dec 21 19:52:00 2005 +0100
     7.3 @@ -118,6 +118,7 @@ void domain_kill(struct domain *d)
     7.4          for_each_vcpu(d, v)
     7.5              sched_rem_domain(v);
     7.6          domain_relinquish_resources(d);
     7.7 +        gnttab_release_mappings(d);
     7.8          put_domain(d);
     7.9  
    7.10          send_guest_virq(dom0->vcpu[0], VIRQ_DOM_EXC);
     8.1 --- a/xen/common/grant_table.c	Wed Dec 21 11:56:19 2005 -0600
     8.2 +++ b/xen/common/grant_table.c	Wed Dec 21 19:52:00 2005 +0100
     8.3 @@ -177,17 +177,19 @@ static int
     8.4  
     8.5      spin_lock(&rd->grant_table->lock);
     8.6  
     8.7 -    if ( act->pin == 0 )
     8.8 +    if ( !act->pin ||
     8.9 +         (!(dev_hst_ro_flags & GNTMAP_readonly) &&
    8.10 +          !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask))) )
    8.11      {
    8.12 -        /* CASE 1: Activating a previously inactive entry. */
    8.13 -
    8.14          sflags = sha->flags;
    8.15          sdom   = sha->domid;
    8.16  
    8.17 -        /* This loop attempts to set the access (reading/writing) flags
    8.18 +        /*
    8.19 +         * This loop attempts to set the access (reading/writing) flags
    8.20           * in the grant table entry.  It tries a cmpxchg on the field
    8.21           * up to five times, and then fails under the assumption that 
    8.22 -         * the guest is misbehaving. */
    8.23 +         * the guest is misbehaving.
    8.24 +         */
    8.25          for ( ; ; )
    8.26          {
    8.27              u32 scombo, prev_scombo, new_scombo;
    8.28 @@ -196,7 +198,7 @@ static int
    8.29                   unlikely(sdom != led->domain->domain_id) )
    8.30                  PIN_FAIL(unlock_out, GNTST_general_error,
    8.31                           "Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
    8.32 -                        sflags, sdom, led->domain->domain_id);
    8.33 +                         sflags, sdom, led->domain->domain_id);
    8.34  
    8.35              /* Merge two 16-bit values into a 32-bit combined update. */
    8.36              /* NB. Endianness! */
    8.37 @@ -232,132 +234,50 @@ static int
    8.38              sdom   = (u16)(prev_scombo >> 16);
    8.39          }
    8.40  
    8.41 -        /* rmb(); */ /* not on x86 */
    8.42 -
    8.43 -        frame = __gpfn_to_mfn(rd, sha->frame);
    8.44 -
    8.45 -        if ( unlikely(!pfn_valid(frame)) ||
    8.46 -             unlikely(!((dev_hst_ro_flags & GNTMAP_readonly) ?
    8.47 -                        get_page(pfn_to_page(frame), rd) :
    8.48 -                        get_page_and_type(pfn_to_page(frame), rd,
    8.49 -                                          PGT_writable_page))) )
    8.50 -        {
    8.51 -            clear_bit(_GTF_writing, &sha->flags);
    8.52 -            clear_bit(_GTF_reading, &sha->flags);
    8.53 -            PIN_FAIL(unlock_out, GNTST_general_error,
    8.54 -                     "Could not pin the granted frame (%lx)!\n", frame);
    8.55 -        }
    8.56 -
    8.57 -        if ( dev_hst_ro_flags & GNTMAP_device_map )
    8.58 -            act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
    8.59 -                GNTPIN_devr_inc : GNTPIN_devw_inc;
    8.60 -        if ( dev_hst_ro_flags & GNTMAP_host_map )
    8.61 -            act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
    8.62 -                GNTPIN_hstr_inc : GNTPIN_hstw_inc;
    8.63 -        act->domid = sdom;
    8.64 -        act->frame = frame;
    8.65 -    }
    8.66 -    else 
    8.67 -    {
    8.68 -        /* CASE 2: Active modications to an already active entry. */
    8.69 -
    8.70 -        /*
    8.71 -         * A cheesy check for possible pin-count overflow.
    8.72 -         * A more accurate check cannot be done with a single comparison.
    8.73 -         */
    8.74 -        if ( (act->pin & 0x80808080U) != 0 )
    8.75 -            PIN_FAIL(unlock_out, ENOSPC,
    8.76 -                     "Risk of counter overflow %08x\n", act->pin);
    8.77 -
    8.78 -        sflags = sha->flags;
    8.79 -        frame  = act->frame;
    8.80 -
    8.81 -        if ( !(dev_hst_ro_flags & GNTMAP_readonly) &&
    8.82 -             !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
    8.83 +        if ( !act->pin )
    8.84          {
    8.85 -            for ( ; ; )
    8.86 -            {
    8.87 -                u16 prev_sflags;
    8.88 -                
    8.89 -                if ( unlikely(sflags & GTF_readonly) )
    8.90 -                    PIN_FAIL(unlock_out, GNTST_general_error,
    8.91 -                             "Attempt to write-pin a r/o grant entry.\n");
    8.92 -
    8.93 -                prev_sflags = sflags;
    8.94 -
    8.95 -                /* NB. prev_sflags is updated in place to seen value. */
    8.96 -                if ( unlikely(cmpxchg_user(&sha->flags, prev_sflags, 
    8.97 -                                           prev_sflags | GTF_writing)) )
    8.98 -                    PIN_FAIL(unlock_out, GNTST_general_error,
    8.99 -                         "Fault while modifying shared flags.\n");
   8.100 -
   8.101 -                if ( likely(prev_sflags == sflags) )
   8.102 -                    break;
   8.103 -
   8.104 -                if ( retries++ == 4 )
   8.105 -                    PIN_FAIL(unlock_out, GNTST_general_error,
   8.106 -                             "Shared grant entry is unstable.\n");
   8.107 +            act->domid = sdom;
   8.108 +            act->frame = __gpfn_to_mfn(rd, sha->frame);
   8.109 +        }
   8.110 +    }
   8.111 +    else if ( (act->pin & 0x80808080U) != 0 )
   8.112 +        PIN_FAIL(unlock_out, ENOSPC,
   8.113 +                 "Risk of counter overflow %08x\n", act->pin);
   8.114  
   8.115 -                sflags = prev_sflags;
   8.116 -            }
   8.117 -
   8.118 -            if ( unlikely(!get_page_type(pfn_to_page(frame),
   8.119 -                                         PGT_writable_page)) )
   8.120 -            {
   8.121 -                clear_bit(_GTF_writing, &sha->flags);
   8.122 -                PIN_FAIL(unlock_out, GNTST_general_error,
   8.123 -                         "Attempt to write-pin a unwritable page.\n");
   8.124 -            }
   8.125 -        }
   8.126 -
   8.127 -        if ( dev_hst_ro_flags & GNTMAP_device_map )
   8.128 -            act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ? 
   8.129 -                GNTPIN_devr_inc : GNTPIN_devw_inc;
   8.130 -
   8.131 -        if ( dev_hst_ro_flags & GNTMAP_host_map )
   8.132 -            act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
   8.133 -                GNTPIN_hstr_inc : GNTPIN_hstw_inc;
   8.134 -    }
   8.135 -
   8.136 -    /*
   8.137 -     * At this point:
   8.138 -     * act->pin updated to reference count mappings.
   8.139 -     * sha->flags updated to indicate to granting domain mapping done.
   8.140 -     * frame contains the mfn.
   8.141 -     */
   8.142 +    if ( dev_hst_ro_flags & GNTMAP_device_map )
   8.143 +        act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
   8.144 +            GNTPIN_devr_inc : GNTPIN_devw_inc;
   8.145 +    if ( dev_hst_ro_flags & GNTMAP_host_map )
   8.146 +        act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
   8.147 +            GNTPIN_hstr_inc : GNTPIN_hstw_inc;
   8.148  
   8.149      spin_unlock(&rd->grant_table->lock);
   8.150  
   8.151 +    frame = act->frame;
   8.152 +    if ( unlikely(!pfn_valid(frame)) ||
   8.153 +         unlikely(!((dev_hst_ro_flags & GNTMAP_readonly) ?
   8.154 +                    get_page(pfn_to_page(frame), rd) :
   8.155 +                    get_page_and_type(pfn_to_page(frame), rd,
   8.156 +                                      PGT_writable_page))) )
   8.157 +        PIN_FAIL(undo_out, GNTST_general_error,
   8.158 +                 "Could not pin the granted frame (%lx)!\n", frame);
   8.159 +
   8.160      if ( dev_hst_ro_flags & GNTMAP_host_map )
   8.161      {
   8.162          rc = create_grant_host_mapping(addr, frame, dev_hst_ro_flags);
   8.163 -        if ( rc < 0 )
   8.164 +        if ( rc != GNTST_okay )
   8.165          {
   8.166 -            /* Failure: undo and abort. */
   8.167 -
   8.168 -            spin_lock(&rd->grant_table->lock);
   8.169 +            if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
   8.170 +                put_page_type(pfn_to_page(frame));
   8.171 +            put_page(pfn_to_page(frame));
   8.172 +            goto undo_out;
   8.173 +        }
   8.174  
   8.175 -            if ( dev_hst_ro_flags & GNTMAP_readonly )
   8.176 -            {
   8.177 -                act->pin -= GNTPIN_hstr_inc;
   8.178 -            }
   8.179 -            else
   8.180 -            {
   8.181 -                act->pin -= GNTPIN_hstw_inc;
   8.182 -                if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 )
   8.183 -                {
   8.184 -                    clear_bit(_GTF_writing, &sha->flags);
   8.185 -                    put_page_type(pfn_to_page(frame));
   8.186 -                }
   8.187 -            }
   8.188 -
   8.189 -            if ( act->pin == 0 )
   8.190 -            {
   8.191 -                clear_bit(_GTF_reading, &sha->flags);
   8.192 -                put_page(pfn_to_page(frame));
   8.193 -            }
   8.194 -
   8.195 -            spin_unlock(&rd->grant_table->lock);
   8.196 +        if ( dev_hst_ro_flags & GNTMAP_device_map )
   8.197 +        {
   8.198 +            (void)get_page(pfn_to_page(frame), rd);
   8.199 +            if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
   8.200 +                get_page_type(pfn_to_page(frame), PGT_writable_page);
   8.201          }
   8.202      }
   8.203  
   8.204 @@ -375,6 +295,24 @@ static int
   8.205      put_domain(rd);
   8.206      return rc;
   8.207  
   8.208 + undo_out:
   8.209 +    spin_lock(&rd->grant_table->lock);
   8.210 +
   8.211 +    if ( dev_hst_ro_flags & GNTMAP_device_map )
   8.212 +        act->pin -= (dev_hst_ro_flags & GNTMAP_readonly) ?
   8.213 +            GNTPIN_devr_inc : GNTPIN_devw_inc;
   8.214 +    if ( dev_hst_ro_flags & GNTMAP_host_map )
   8.215 +        act->pin -= (dev_hst_ro_flags & GNTMAP_readonly) ?
   8.216 +            GNTPIN_hstr_inc : GNTPIN_hstw_inc;
   8.217 +
   8.218 +    if ( !(dev_hst_ro_flags & GNTMAP_readonly) &&
   8.219 +         !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
   8.220 +        clear_bit(_GTF_writing, &sha->flags);
   8.221 +
   8.222 +    if ( !act->pin )
   8.223 +        clear_bit(_GTF_reading, &sha->flags);
   8.224 +
   8.225 +    spin_unlock(&rd->grant_table->lock);
   8.226  
   8.227   unlock_out:
   8.228      spin_unlock(&rd->grant_table->lock);
   8.229 @@ -465,27 +403,42 @@ static int
   8.230              PIN_FAIL(unmap_out, GNTST_general_error,
   8.231                       "Bad frame number doesn't match gntref.\n");
   8.232          if ( flags & GNTMAP_device_map )
   8.233 -            act->pin -= (flags & GNTMAP_readonly) ? GNTPIN_devr_inc
   8.234 -                                                  : GNTPIN_devw_inc;
   8.235 -
   8.236 -        map->ref_and_flags &= ~GNTMAP_device_map;
   8.237 -        (void)__put_user(0, &uop->dev_bus_addr);
   8.238 +        {
   8.239 +            ASSERT(act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask));
   8.240 +            map->ref_and_flags &= ~GNTMAP_device_map;
   8.241 +            if ( flags & GNTMAP_readonly )
   8.242 +            {
   8.243 +                act->pin -= GNTPIN_devr_inc;
   8.244 +                put_page(pfn_to_page(frame));
   8.245 +            }
   8.246 +            else
   8.247 +            {
   8.248 +                act->pin -= GNTPIN_devw_inc;
   8.249 +                put_page_and_type(pfn_to_page(frame));
   8.250 +            }
   8.251 +        }
   8.252      }
   8.253  
   8.254 -    if ( (addr != 0) &&
   8.255 -         (flags & GNTMAP_host_map) &&
   8.256 -         ((act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)) > 0))
   8.257 +    if ( (addr != 0) && (flags & GNTMAP_host_map) )
   8.258      {
   8.259          if ( (rc = destroy_grant_host_mapping(addr, frame, flags)) < 0 )
   8.260              goto unmap_out;
   8.261  
   8.262 +        ASSERT(act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask));
   8.263          map->ref_and_flags &= ~GNTMAP_host_map;
   8.264 -
   8.265 -        act->pin -= (flags & GNTMAP_readonly) ? GNTPIN_hstr_inc
   8.266 -                                              : GNTPIN_hstw_inc;
   8.267 +        if ( flags & GNTMAP_readonly )
   8.268 +        {
   8.269 +            act->pin -= GNTPIN_hstr_inc;
   8.270 +            put_page(pfn_to_page(frame));
   8.271 +        }
   8.272 +        else
   8.273 +        {
   8.274 +            act->pin -= GNTPIN_hstw_inc;
   8.275 +            put_page_and_type(pfn_to_page(frame));
   8.276 +        }
   8.277      }
   8.278  
   8.279 -    if ( (map->ref_and_flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0)
   8.280 +    if ( (map->ref_and_flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0 )
   8.281      {
   8.282          map->ref_and_flags = 0;
   8.283          put_maptrack_handle(ld->grant_table, handle);
   8.284 @@ -495,20 +448,12 @@ static int
   8.285      if ( !(flags & GNTMAP_readonly) )
   8.286           gnttab_log_dirty(rd, frame);
   8.287  
   8.288 -    /* If the last writable mapping has been removed, put_page_type */
   8.289      if ( ((act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0) &&
   8.290           !(flags & GNTMAP_readonly) )
   8.291 -    {
   8.292          clear_bit(_GTF_writing, &sha->flags);
   8.293 -        put_page_type(pfn_to_page(frame));
   8.294 -    }
   8.295  
   8.296      if ( act->pin == 0 )
   8.297 -    {
   8.298 -        act->frame = 0xdeadbeef;
   8.299          clear_bit(_GTF_reading, &sha->flags);
   8.300 -        put_page(pfn_to_page(frame));
   8.301 -    }
   8.302  
   8.303   unmap_out:
   8.304      (void)__put_user(rc, &uop->status);
   8.305 @@ -669,6 +614,91 @@ gnttab_dump_table(
   8.306      return 0;
   8.307  }
   8.308  
   8.309 +/*
   8.310 + * Check that the given grant reference (rd,ref) allows 'ld' to transfer
   8.311 + * ownership of a page frame. If so, lock down the grant entry.
   8.312 + */
   8.313 +static int 
   8.314 +gnttab_prepare_for_transfer(
   8.315 +    struct domain *rd, struct domain *ld, grant_ref_t ref)
   8.316 +{
   8.317 +    grant_table_t *rgt;
   8.318 +    grant_entry_t *sha;
   8.319 +    domid_t        sdom;
   8.320 +    u16            sflags;
   8.321 +    u32            scombo, prev_scombo;
   8.322 +    int            retries = 0;
   8.323 +    unsigned long  target_pfn;
   8.324 +
   8.325 +    if ( unlikely((rgt = rd->grant_table) == NULL) ||
   8.326 +         unlikely(ref >= NR_GRANT_ENTRIES) )
   8.327 +    {
   8.328 +        DPRINTK("Dom %d has no g.t., or ref is bad (%d).\n",
   8.329 +                rd->domain_id, ref);
   8.330 +        return 0;
   8.331 +    }
   8.332 +
   8.333 +    spin_lock(&rgt->lock);
   8.334 +
   8.335 +    sha = &rgt->shared[ref];
   8.336 +    
   8.337 +    sflags = sha->flags;
   8.338 +    sdom   = sha->domid;
   8.339 +
   8.340 +    for ( ; ; )
   8.341 +    {
   8.342 +        target_pfn = sha->frame;
   8.343 +
   8.344 +        if ( unlikely(target_pfn >= max_page ) )
   8.345 +        {
   8.346 +            DPRINTK("Bad pfn (%lx)\n", target_pfn);
   8.347 +            goto fail;
   8.348 +        }
   8.349 +
   8.350 +        if ( unlikely(sflags != GTF_accept_transfer) ||
   8.351 +             unlikely(sdom != ld->domain_id) )
   8.352 +        {
   8.353 +            DPRINTK("Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
   8.354 +                    sflags, sdom, ld->domain_id);
   8.355 +            goto fail;
   8.356 +        }
   8.357 +
   8.358 +        /* Merge two 16-bit values into a 32-bit combined update. */
   8.359 +        /* NB. Endianness! */
   8.360 +        prev_scombo = scombo = ((u32)sdom << 16) | (u32)sflags;
   8.361 +
   8.362 +        /* NB. prev_scombo is updated in place to seen value. */
   8.363 +        if ( unlikely(cmpxchg_user((u32 *)&sha->flags, prev_scombo, 
   8.364 +                                   prev_scombo | GTF_transfer_committed)) )
   8.365 +        {
   8.366 +            DPRINTK("Fault while modifying shared flags and domid.\n");
   8.367 +            goto fail;
   8.368 +        }
   8.369 +
   8.370 +        /* Did the combined update work (did we see what we expected?). */
   8.371 +        if ( likely(prev_scombo == scombo) )
   8.372 +            break;
   8.373 +
   8.374 +        if ( retries++ == 4 )
   8.375 +        {
   8.376 +            DPRINTK("Shared grant entry is unstable.\n");
   8.377 +            goto fail;
   8.378 +        }
   8.379 +
   8.380 +        /* Didn't see what we expected. Split out the seen flags & dom. */
   8.381 +        /* NB. Endianness! */
   8.382 +        sflags = (u16)prev_scombo;
   8.383 +        sdom   = (u16)(prev_scombo >> 16);
   8.384 +    }
   8.385 +
   8.386 +    spin_unlock(&rgt->lock);
   8.387 +    return 1;
   8.388 +
   8.389 + fail:
   8.390 +    spin_unlock(&rgt->lock);
   8.391 +    return 0;
   8.392 +}
   8.393 +
   8.394  static long
   8.395  gnttab_transfer(
   8.396      gnttab_transfer_t *uop, unsigned int count)
   8.397 @@ -818,87 +848,6 @@ do_grant_table_op(
   8.398  }
   8.399  
   8.400  int 
   8.401 -gnttab_prepare_for_transfer(
   8.402 -    struct domain *rd, struct domain *ld, grant_ref_t ref)
   8.403 -{
   8.404 -    grant_table_t *rgt;
   8.405 -    grant_entry_t *sha;
   8.406 -    domid_t        sdom;
   8.407 -    u16            sflags;
   8.408 -    u32            scombo, prev_scombo;
   8.409 -    int            retries = 0;
   8.410 -    unsigned long  target_pfn;
   8.411 -
   8.412 -    if ( unlikely((rgt = rd->grant_table) == NULL) ||
   8.413 -         unlikely(ref >= NR_GRANT_ENTRIES) )
   8.414 -    {
   8.415 -        DPRINTK("Dom %d has no g.t., or ref is bad (%d).\n",
   8.416 -                rd->domain_id, ref);
   8.417 -        return 0;
   8.418 -    }
   8.419 -
   8.420 -    spin_lock(&rgt->lock);
   8.421 -
   8.422 -    sha = &rgt->shared[ref];
   8.423 -    
   8.424 -    sflags = sha->flags;
   8.425 -    sdom   = sha->domid;
   8.426 -
   8.427 -    for ( ; ; )
   8.428 -    {
   8.429 -        target_pfn = sha->frame;
   8.430 -
   8.431 -        if ( unlikely(target_pfn >= max_page ) )
   8.432 -        {
   8.433 -            DPRINTK("Bad pfn (%lx)\n", target_pfn);
   8.434 -            goto fail;
   8.435 -        }
   8.436 -
   8.437 -        if ( unlikely(sflags != GTF_accept_transfer) ||
   8.438 -             unlikely(sdom != ld->domain_id) )
   8.439 -        {
   8.440 -            DPRINTK("Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
   8.441 -                    sflags, sdom, ld->domain_id);
   8.442 -            goto fail;
   8.443 -        }
   8.444 -
   8.445 -        /* Merge two 16-bit values into a 32-bit combined update. */
   8.446 -        /* NB. Endianness! */
   8.447 -        prev_scombo = scombo = ((u32)sdom << 16) | (u32)sflags;
   8.448 -
   8.449 -        /* NB. prev_scombo is updated in place to seen value. */
   8.450 -        if ( unlikely(cmpxchg_user((u32 *)&sha->flags, prev_scombo, 
   8.451 -                                   prev_scombo | GTF_transfer_committed)) )
   8.452 -        {
   8.453 -            DPRINTK("Fault while modifying shared flags and domid.\n");
   8.454 -            goto fail;
   8.455 -        }
   8.456 -
   8.457 -        /* Did the combined update work (did we see what we expected?). */
   8.458 -        if ( likely(prev_scombo == scombo) )
   8.459 -            break;
   8.460 -
   8.461 -        if ( retries++ == 4 )
   8.462 -        {
   8.463 -            DPRINTK("Shared grant entry is unstable.\n");
   8.464 -            goto fail;
   8.465 -        }
   8.466 -
   8.467 -        /* Didn't see what we expected. Split out the seen flags & dom. */
   8.468 -        /* NB. Endianness! */
   8.469 -        sflags = (u16)prev_scombo;
   8.470 -        sdom   = (u16)(prev_scombo >> 16);
   8.471 -    }
   8.472 -
   8.473 -    spin_unlock(&rgt->lock);
   8.474 -    return 1;
   8.475 -
   8.476 - fail:
   8.477 -    spin_unlock(&rgt->lock);
   8.478 -    return 0;
   8.479 -}
   8.480 -
   8.481 -int 
   8.482  grant_table_create(
   8.483      struct domain *d)
   8.484  {
   8.485 @@ -989,42 +938,42 @@ gnttab_release_mappings(
   8.486          {
   8.487              if ( map->ref_and_flags & GNTMAP_device_map )
   8.488              {
   8.489 -                BUG_ON((act->pin & GNTPIN_devr_mask) == 0);
   8.490 +                BUG_ON(!(act->pin & GNTPIN_devr_mask));
   8.491                  act->pin -= GNTPIN_devr_inc;
   8.492 +                put_page(pfn_to_page(act->frame));
   8.493              }
   8.494  
   8.495              if ( map->ref_and_flags & GNTMAP_host_map )
   8.496              {
   8.497 -                BUG_ON((act->pin & GNTPIN_hstr_mask) == 0);
   8.498 +                BUG_ON(!(act->pin & GNTPIN_hstr_mask));
   8.499                  act->pin -= GNTPIN_hstr_inc;
   8.500 +                /* Done implicitly when page tables are destroyed. */
   8.501 +                /* put_page(pfn_to_page(act->frame)); */
   8.502              }
   8.503          }
   8.504          else
   8.505          {
   8.506              if ( map->ref_and_flags & GNTMAP_device_map )
   8.507              {
   8.508 -                BUG_ON((act->pin & GNTPIN_devw_mask) == 0);
   8.509 +                BUG_ON(!(act->pin & GNTPIN_devw_mask));
   8.510                  act->pin -= GNTPIN_devw_inc;
   8.511 +                put_page_and_type(pfn_to_page(act->frame));
   8.512              }
   8.513  
   8.514              if ( map->ref_and_flags & GNTMAP_host_map )
   8.515              {
   8.516 -                BUG_ON((act->pin & GNTPIN_hstw_mask) == 0);
   8.517 +                BUG_ON(!(act->pin & GNTPIN_hstw_mask));
   8.518                  act->pin -= GNTPIN_hstw_inc;
   8.519 +                /* Done implicitly when page tables are destroyed. */
   8.520 +                /* put_page_and_type(pfn_to_page(act->frame)); */
   8.521              }
   8.522  
   8.523              if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
   8.524 -            {
   8.525                  clear_bit(_GTF_writing, &sha->flags);
   8.526 -                put_page_type(pfn_to_page(act->frame));
   8.527 -            }
   8.528          }
   8.529  
   8.530          if ( act->pin == 0 )
   8.531 -        {
   8.532              clear_bit(_GTF_reading, &sha->flags);
   8.533 -            put_page(pfn_to_page(act->frame));
   8.534 -        }
   8.535  
   8.536          spin_unlock(&rd->grant_table->lock);
   8.537  
   8.538 @@ -1039,24 +988,17 @@ void
   8.539  grant_table_destroy(
   8.540      struct domain *d)
   8.541  {
   8.542 -    grant_table_t *t;
   8.543 +    grant_table_t *t = d->grant_table;
   8.544  
   8.545 -    if ( (t = d->grant_table) != NULL )
   8.546 -    {
   8.547 -        /* Free memory relating to this grant table. */
   8.548 -        d->grant_table = NULL;
   8.549 -        free_xenheap_pages(t->shared, ORDER_GRANT_FRAMES);
   8.550 -        free_xenheap_page(t->maptrack);
   8.551 -        xfree(t->active);
   8.552 -        xfree(t);
   8.553 -    }
   8.554 -}
   8.555 +    if ( t == NULL )
   8.556 +        return;
   8.557 +    
   8.558 +    free_xenheap_pages(t->shared, ORDER_GRANT_FRAMES);
   8.559 +    free_xenheap_page(t->maptrack);
   8.560 +    xfree(t->active);
   8.561 +    xfree(t);
   8.562  
   8.563 -void
   8.564 -grant_table_init(
   8.565 -    void)
   8.566 -{
   8.567 -    /* Nothing. */
   8.568 +    d->grant_table = NULL;
   8.569  }
   8.570  
   8.571  /*
     9.1 --- a/xen/include/public/xen.h	Wed Dec 21 11:56:19 2005 -0600
     9.2 +++ b/xen/include/public/xen.h	Wed Dec 21 19:52:00 2005 +0100
     9.3 @@ -145,10 +145,6 @@
     9.4   * cmd: MMUEXT_SET_LDT
     9.5   * linear_addr: Linear address of LDT base (NB. must be page-aligned).
     9.6   * nr_ents: Number of entries in LDT.
     9.7 - * 
     9.8 - * cmd: MMUEXT_REASSIGN_PAGE
     9.9 - * mfn: Machine frame number to be reassigned to the FD.
    9.10 - *      (NB. page must currently belong to the calling domain).
    9.11   */
    9.12  #define MMUEXT_PIN_L1_TABLE      0
    9.13  #define MMUEXT_PIN_L2_TABLE      1
    9.14 @@ -164,14 +160,13 @@
    9.15  #define MMUEXT_INVLPG_ALL       11
    9.16  #define MMUEXT_FLUSH_CACHE      12
    9.17  #define MMUEXT_SET_LDT          13
    9.18 -#define MMUEXT_REASSIGN_PAGE    14
    9.19  #define MMUEXT_NEW_USER_BASEPTR 15
    9.20  
    9.21  #ifndef __ASSEMBLY__
    9.22  struct mmuext_op {
    9.23      unsigned int cmd;
    9.24      union {
    9.25 -        /* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR, REASSIGN_PAGE */
    9.26 +        /* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR */
    9.27          unsigned long mfn;
    9.28          /* INVLPG_LOCAL, INVLPG_ALL, SET_LDT */
    9.29          unsigned long linear_addr;
    10.1 --- a/xen/include/xen/grant_table.h	Wed Dec 21 11:56:19 2005 -0600
    10.2 +++ b/xen/include/xen/grant_table.h	Wed Dec 21 19:52:00 2005 +0100
    10.3 @@ -84,24 +84,12 @@ typedef struct {
    10.4      spinlock_t            lock;
    10.5  } grant_table_t;
    10.6  
    10.7 -/* Start-of-day system initialisation. */
    10.8 -void grant_table_init(
    10.9 -    void);
   10.10 -
   10.11  /* Create/destroy per-domain grant table context. */
   10.12  int grant_table_create(
   10.13      struct domain *d);
   10.14  void grant_table_destroy(
   10.15      struct domain *d);
   10.16  
   10.17 -/*
   10.18 - * Check that the given grant reference (rd,ref) allows 'ld' to transfer
   10.19 - * ownership of a page frame. If so, lock down the grant entry.
   10.20 - */
   10.21 -int 
   10.22 -gnttab_prepare_for_transfer(
   10.23 -    struct domain *rd, struct domain *ld, grant_ref_t ref);
   10.24 -
   10.25  /* Domain death release of granted mappings of other domains' memory. */
   10.26  void
   10.27  gnttab_release_mappings(