ia64/xen-unstable

changeset 4064:3dafdc84f1a2

bitkeeper revision 1.1236.1.72 (4230532fk6tk4epkQg0JEAHMpbqxuA)

resolving after pull
author cwc22@centipede.cl.cam.ac.uk
date Thu Mar 10 14:01:19 2005 +0000 (2005-03-10)
parents 254b6cc19f34 96b57b335681
children 68d9d54ac50f
files xen/arch/x86/domain.c xen/arch/x86/mm.c xen/common/grant_table.c xen/include/xen/grant_table.h
line diff
     1.1 --- a/xen/arch/x86/domain.c	Thu Mar 10 02:20:43 2005 +0000
     1.2 +++ b/xen/arch/x86/domain.c	Thu Mar 10 14:01:19 2005 +0000
     1.3 @@ -970,9 +970,6 @@ void domain_relinquish_memory(struct dom
     1.4      /* Ensure that noone is running over the dead domain's page tables. */
     1.5      synchronise_pagetables(~0UL);
     1.6  
     1.7 -    /* Release mappings of other domains */
     1.8 -    gnttab_release_all_mappings( d->grant_table );
     1.9 -
    1.10      /* Exit shadow mode before deconstructing final guest page table. */
    1.11      shadow_mode_disable(d);
    1.12  
     2.1 --- a/xen/arch/x86/mm.c	Thu Mar 10 02:20:43 2005 +0000
     2.2 +++ b/xen/arch/x86/mm.c	Thu Mar 10 14:01:19 2005 +0000
     2.3 @@ -2001,16 +2001,14 @@ int update_grant_va_mapping(unsigned lon
     2.4          {
     2.5              /* overwrote different mfn?  */
     2.6              if (((_ol1e ^ _nl1e) & (PADDR_MASK & PAGE_MASK)) != 0)
     2.7 -            {
     2.8 -                rc = 0;
     2.9                  put_page_from_l1e(ol1e, d);
    2.10 -            }
    2.11 -            else
    2.12 +
    2.13 +            else if (_ol1e & _PAGE_PRESENT)
    2.14                  rc = ((_ol1e & _PAGE_RW) ? GNTUPDVA_prev_rw
    2.15                                           : GNTUPDVA_prev_ro );
    2.16                  /* use return code to avoid nasty grant table
    2.17                   * slow path in put_page_from_l1e -- caller
    2.18 -                 * must handle ref count instead. */
    2.19 +                 * must handle grant ref count instead. */
    2.20          }
    2.21          else
    2.22              rc = -EINVAL;
     3.1 --- a/xen/common/grant_table.c	Thu Mar 10 02:20:43 2005 +0000
     3.2 +++ b/xen/common/grant_table.c	Thu Mar 10 14:01:19 2005 +0000
     3.3 @@ -242,7 +242,7 @@ static int
     3.4                  if ( unlikely(cmpxchg_user(&sha->flags, prev_sflags, 
     3.5                                             prev_sflags | GTF_writing)) )
     3.6                      PIN_FAIL(GNTST_general_error,
     3.7 -                             "Fault while modifying shared flags.\n");
     3.8 +                         "Fault while modifying shared flags.\n");
     3.9  
    3.10                  if ( likely(prev_sflags == sflags) )
    3.11                      break;
    3.12 @@ -277,6 +277,13 @@ static int
    3.13      ld->grant_table->maptrack[handle].ref_and_flags =
    3.14          (ref << MAPTRACK_REF_SHIFT) | (flags & MAPTRACK_GNTMAP_MASK);
    3.15  
    3.16 +    /* At this point:
    3.17 +     * act->pin updated to reflect mapping
    3.18 +     * sha->flags updated to indicate to granting domain mapping done
    3.19 +     * maptrack points to correct remote domain data
    3.20 +     * frame contains the mfn
    3.21 +     */
    3.22 +
    3.23      if ( (host_virt_addr != 0) && (flags & GNTMAP_host_map) )
    3.24      {
    3.25          /* Write update into the pagetable
    3.26 @@ -298,21 +305,35 @@ static int
    3.27              {
    3.28                  act->pin -= GNTPIN_hstw_inc;
    3.29                  if ( (act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)) == 0 )
    3.30 +                {
    3.31                      put_page_type(&frame_table[frame]);
    3.32 +                    clear_bit(_GTF_writing, &sha->flags);
    3.33 +                }
    3.34  
    3.35                  if ( act->pin == 0 )
    3.36 +                {
    3.37                      put_page(&frame_table[frame]);
    3.38 +                    clear_bit(_GTF_reading, &sha->flags);
    3.39 +                }
    3.40              }
    3.41              goto fail;
    3.42          }
    3.43  
    3.44 +        /* Check to see if update overwrote a mapping of the same mfn
    3.45 +         * - if so, must handle ref count here
    3.46 +         */
    3.47          if ( rc == GNTUPDVA_prev_ro )
    3.48              act->pin -= GNTPIN_hstr_inc;
    3.49  
    3.50          if ( rc == GNTUPDVA_prev_rw ) 
    3.51          {
    3.52              act->pin -= GNTPIN_hstw_inc;
    3.53 -            put_page_type(&frame_table[frame]);
    3.54 +
    3.55 +            if ( (act->pin & (GNTPIN_hstw_mask | GNTPIN_devw_mask)) == 0 )
    3.56 +            {
    3.57 +                put_page_type(&frame_table[frame]);
    3.58 +                clear_bit(_GTF_writing, &sha->flags);
    3.59 +            }
    3.60          }
    3.61          rc = 0;
    3.62          *va = host_virt_addr;
    3.63 @@ -322,10 +343,10 @@ static int
    3.64           */
    3.65      }
    3.66  
    3.67 +    /* Unchecked and unconditional writes to user uop. */
    3.68      if ( flags & GNTMAP_device_map )
    3.69          (void)__put_user(frame,  &uop->dev_bus_addr);
    3.70  
    3.71 -    /* Unchecked and unconditional. */
    3.72      (void)__put_user(handle, &uop->handle);
    3.73  
    3.74      spin_unlock(&rd->grant_table->lock);
    3.75 @@ -336,7 +357,7 @@ static int
    3.76      (void)__put_user(rc, &uop->handle);
    3.77      spin_unlock(&rd->grant_table->lock);
    3.78      put_domain(rd);
    3.79 -    put_maptrack_handle(ld->grant_table, handle); //cwc22: check this
    3.80 +    put_maptrack_handle(ld->grant_table, handle);
    3.81      return rc;
    3.82  }
    3.83  
    3.84 @@ -426,9 +447,8 @@ static int
    3.85                  GNTPIN_devr_inc : GNTPIN_devw_inc;
    3.86      }
    3.87      else
    3.88 -    {
    3.89          frame = act->frame;
    3.90 -    }
    3.91 +
    3.92  
    3.93      if ( (virt != 0) &&
    3.94           (map->ref_and_flags & GNTMAP_host_map) &&
    3.95 @@ -457,12 +477,6 @@ static int
    3.96              goto fail;
    3.97          }
    3.98  
    3.99 -        /* This code _requires_ that the act->pin bits are updated
   3.100 -         * if a mapping is ever switched between RO and RW.
   3.101 -         */
   3.102 -        act->pin -= ( _ol1e & _PAGE_RW ) ? GNTPIN_hstw_inc
   3.103 -                                         : GNTPIN_hstr_inc;
   3.104 -
   3.105          /* Delete pagetable entry
   3.106           */
   3.107          if ( unlikely(__put_user(0, (unsigned long *)pl1e)))
   3.108 @@ -472,6 +486,10 @@ static int
   3.109              rc = -EINVAL;
   3.110              goto fail;
   3.111          }
   3.112 +
   3.113 +        act->pin -= (map->ref_and_flags & GNTMAP_readonly) ?
   3.114 +                        GNTPIN_hstr_inc : GNTPIN_hstw_inc;
   3.115 +
   3.116          rc = 0;
   3.117          *va = virt;
   3.118      }
   3.119 @@ -510,8 +528,10 @@ gnttab_unmap_grant_ref(
   3.120  
   3.121      if ( flush == 1 )
   3.122          __flush_tlb_one(va);
   3.123 +
   3.124      else if ( flush )
   3.125          local_flush_tlb();
   3.126 +
   3.127      return 0;
   3.128  }
   3.129  
   3.130 @@ -700,12 +720,94 @@ int
   3.131  gnttab_check_unmap(
   3.132      struct domain *rd, struct domain *ld, unsigned long frame, int readonly)
   3.133  {
   3.134 -    /* TODO: beat the caller around the head with a brick.
   3.135 -     *       have to walk the grant tables to find this thing.
   3.136 +    /* Called when put_page is invoked on a page belonging to a foreign domain.
   3.137 +     * Instead of decrementing the frame table ref count, locate the grant
   3.138 +     * table entry, if any, and if found, decrement that count.
   3.139 +     * Called a _lot_ at domain creation because pages mapped by priv domains
   3.140 +     * also traverse this.
   3.141       */
   3.142 -    /*DPRINTK("gnttab_check_unmap remote dom(%d) local dom(%d) frame (%x) flags(%x).\n",
   3.143 -            rd->id, ld->id, frame, readonly);*/
   3.144 -    return 0;
   3.145 +
   3.146 +    unsigned int handle, ref, refcount;
   3.147 +    grant_table_t        *lgt, *rgt;
   3.148 +    active_grant_entry_t *act;
   3.149 +    grant_mapping_t      *map;
   3.150 +    int found = 0;
   3.151 +
   3.152 +    lgt = ld->grant_table;
   3.153 +    rgt = rd->grant_table;
   3.154 +
   3.155 +    if ( ld->id != 0 ) {
   3.156 +        DPRINTK("Foreign unref rd(%d) ld(%d) frm(%x) flgs(%x).\n",
   3.157 +                rd->id, ld->id, frame, readonly);
   3.158 +    }
   3.159 +
   3.160 +    for ( handle = 0; handle < NR_MAPTRACK_ENTRIES; handle++ )
   3.161 +    {
   3.162 +        map = &lgt->maptrack[handle];
   3.163 +
   3.164 +
   3.165 +        /* cwc22: if multiple grants of the same frame are disallowed,
   3.166 +         * then the readonly check here can be changed to cause an early abort
   3.167 +         * if we've matched on frame, but not on write permission.
   3.168 +         */
   3.169 +        if ( ( map->ref_and_flags & MAPTRACK_GNTMAP_MASK ) &&
   3.170 +             ( readonly ? 1 : (!(map->ref_and_flags & GNTMAP_readonly))))
   3.171 +        {
   3.172 +            ref = (map->ref_and_flags >> MAPTRACK_REF_SHIFT);
   3.173 +            act = &rgt->active[ref];
   3.174 +
   3.175 +            spin_lock(&rgt->lock);
   3.176 +
   3.177 +            if ( act->frame != frame )
   3.178 +            {
   3.179 +                spin_unlock(&rgt->lock);
   3.180 +                continue;
   3.181 +            }
   3.182 +
   3.183 +            refcount = act->pin & ( readonly ? GNTPIN_hstr_mask
   3.184 +                                             : GNTPIN_hstw_mask );
   3.185 +            if ( refcount == 0 )
   3.186 +            {
   3.187 +                spin_unlock(&rgt->lock);
   3.188 +                continue;
   3.189 +            }
   3.190 +
   3.191 +            /* gotcha */
   3.192 +            DPRINTK("Grant unref rd(%d) ld(%d) frm(%x) flgs(%x).\n",
   3.193 +                    rd->id, ld->id, frame, readonly);
   3.194 +
   3.195 +            if ( readonly )
   3.196 +                act->pin -= GNTPIN_hstr_inc;
   3.197 +            else
   3.198 +            {
   3.199 +                act->pin -= GNTPIN_hstw_inc;
   3.200 +
   3.201 +                /* any more granted writable mappings? */
   3.202 +                if ( (act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)) == 0 )
   3.203 +                {
   3.204 +                    put_page_type(&frame_table[frame]);
   3.205 +                    clear_bit(_GTF_writing, &rgt->shared[ref].flags);
   3.206 +                }
   3.207 +            }
   3.208 +
   3.209 +            if ( act->pin == 0 )
   3.210 +            {
   3.211 +                put_page(&frame_table[frame]);
   3.212 +                clear_bit(_GTF_reading, &rgt->shared[ref].flags);
   3.213 +            }
   3.214 +            spin_unlock(&rgt->lock);
   3.215 +
   3.216 +            clear_bit(GNTMAP_host_map, &map->ref_and_flags);
   3.217 +
   3.218 +            if ( !(map->ref_and_flags & GNTMAP_device_map) )
   3.219 +                put_maptrack_handle(lgt, handle);
   3.220 +
   3.221 +            found = 1;
   3.222 +            break;
   3.223 +        }
   3.224 +    }
   3.225 +
   3.226 +    return found;
   3.227  }
   3.228  
   3.229  int 
   3.230 @@ -846,74 +948,6 @@ grant_table_create(
   3.231  }
   3.232  
   3.233  void
   3.234 -gnttab_release_all_mappings(grant_table_t *gt)
   3.235 -{
   3.236 -    grant_mapping_t        *map;
   3.237 -    domid_t                 dom;
   3.238 -    grant_ref_t             ref;
   3.239 -    u16                     handle;
   3.240 -    u32                     pincount;
   3.241 -    struct domain          *ld, *rd;
   3.242 -    unsigned long           frame;
   3.243 -    active_grant_entry_t   *act;
   3.244 -    grant_entry_t          *sha;
   3.245 -
   3.246 -    ld = current->domain;
   3.247 -
   3.248 -    for ( handle = 0; handle < NR_MAPTRACK_ENTRIES; handle++ )
   3.249 -    {
   3.250 -        map = &gt->maptrack[handle];
   3.251 -                                                                                        
   3.252 -        if ( map->ref_and_flags & MAPTRACK_GNTMAP_MASK )
   3.253 -        {
   3.254 -            dom = map->domid;
   3.255 -            ref = map->ref_and_flags >> MAPTRACK_REF_SHIFT;
   3.256 -
   3.257 -            DPRINTK("Grant release (%hu) ref:(%hu) flags:(%x) dom:(%hu)\n",
   3.258 -                    handle, ref,
   3.259 -                    map->ref_and_flags & MAPTRACK_GNTMAP_MASK, dom);
   3.260 -
   3.261 -            if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
   3.262 -                 unlikely(ld == rd) )
   3.263 -            {
   3.264 -                if ( rd != NULL )
   3.265 -                    put_domain(rd);
   3.266 -
   3.267 -                printk(KERN_WARNING "Grant release: Could not find domain %d\n", dom);
   3.268 -                continue;
   3.269 -            }
   3.270 -
   3.271 -            act = &rd->grant_table->active[ref];
   3.272 -            sha = &rd->grant_table->shared[ref];
   3.273 -
   3.274 -            spin_lock(&rd->grant_table->lock);
   3.275 -
   3.276 -            frame = act->frame;
   3.277 -
   3.278 -            pincount = ((act->pin & GNTPIN_hstw_mask) >> GNTPIN_hstw_shift) +
   3.279 -                       ((act->pin & GNTPIN_devw_mask) >> GNTPIN_devw_shift);
   3.280 -
   3.281 -            if ( pincount > 0 )
   3.282 -                put_page_type(&frame_table[frame]);
   3.283 -
   3.284 -            if (act->pin)
   3.285 -                put_page(&frame_table[frame]);
   3.286 -
   3.287 -            act->pin = 0;
   3.288 -
   3.289 -            clear_bit(_GTF_reading, &sha->flags);
   3.290 -            clear_bit(_GTF_writing, &sha->flags);
   3.291 -
   3.292 -            spin_unlock(&rd->grant_table->lock);
   3.293 -
   3.294 -            map->ref_and_flags = 0;
   3.295 -
   3.296 -            put_domain(rd);
   3.297 -        }
   3.298 -    }
   3.299 -}
   3.300 -
   3.301 -void
   3.302  grant_table_destroy(
   3.303      struct domain *d)
   3.304  {
   3.305 @@ -921,9 +955,6 @@ grant_table_destroy(
   3.306  
   3.307      if ( (t = d->grant_table) != NULL )
   3.308      {
   3.309 -        if ( t->maptrack != NULL )
   3.310 -            gnttab_release_all_mappings(t);
   3.311 -
   3.312          /* Free memory relating to this grant table. */
   3.313          d->grant_table = NULL;
   3.314          free_xenheap_page((unsigned long)t->shared);
     4.1 --- a/xen/include/xen/grant_table.h	Thu Mar 10 02:20:43 2005 +0000
     4.2 +++ b/xen/include/xen/grant_table.h	Thu Mar 10 14:01:19 2005 +0000
     4.3 @@ -105,9 +105,4 @@ void
     4.4  gnttab_notify_transfer(
     4.5      struct domain *rd, grant_ref_t ref, unsigned long frame);
     4.6  
     4.7 -/* Pre-domain destruction release of all mappings of other domains */
     4.8 -void
     4.9 -gnttab_release_all_mappings(grant_table_t *gt);
    4.10 -
    4.11 -
    4.12  #endif /* __XEN_GRANT_H__ */