ia64/xen-unstable

changeset 4063:96b57b335681

bitkeeper revision 1.1236.22.1 (422fbf4aXvKwpBGHOzUdfvbs05k_oQ)

remove gnttab_release_all_mappings
fixes to refcounts and flags
author cwc22@centipede.cl.cam.ac.uk
date Thu Mar 10 03:30:18 2005 +0000 (2005-03-10)
parents 176d6d355157
children 3dafdc84f1a2
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	Wed Mar 09 16:45:29 2005 +0000
     1.2 +++ b/xen/arch/x86/domain.c	Thu Mar 10 03:30:18 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	Wed Mar 09 16:45:29 2005 +0000
     2.2 +++ b/xen/arch/x86/mm.c	Thu Mar 10 03:30:18 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	Wed Mar 09 16:45:29 2005 +0000
     3.2 +++ b/xen/common/grant_table.c	Thu Mar 10 03:30:18 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 @@ -353,8 +374,10 @@ gnttab_map_grant_ref(
    3.85  
    3.86      if ( flush == 1 )
    3.87          __flush_tlb_one(va);
    3.88 +
    3.89      else if ( flush )
    3.90          local_flush_tlb();
    3.91 +
    3.92      return 0;
    3.93  }
    3.94  
    3.95 @@ -425,9 +448,8 @@ static int
    3.96                  GNTPIN_devr_inc : GNTPIN_devw_inc;
    3.97      }
    3.98      else
    3.99 -    {
   3.100          frame = act->frame;
   3.101 -    }
   3.102 +
   3.103  
   3.104      if ( (virt != 0) &&
   3.105           (map->ref_and_flags & GNTMAP_host_map) &&
   3.106 @@ -456,12 +478,6 @@ static int
   3.107              goto fail;
   3.108          }
   3.109  
   3.110 -        /* This code _requires_ that the act->pin bits are updated
   3.111 -         * if a mapping is ever switched between RO and RW.
   3.112 -         */
   3.113 -        act->pin -= ( _ol1e & _PAGE_RW ) ? GNTPIN_hstw_inc
   3.114 -                                         : GNTPIN_hstr_inc;
   3.115 -
   3.116          /* Delete pagetable entry
   3.117           */
   3.118          if ( unlikely(__put_user(0, (unsigned long *)pl1e)))
   3.119 @@ -471,6 +487,10 @@ static int
   3.120              rc = -EINVAL;
   3.121              goto fail;
   3.122          }
   3.123 +
   3.124 +        act->pin -= (map->ref_and_flags & GNTMAP_readonly) ?
   3.125 +                        GNTPIN_hstr_inc : GNTPIN_hstw_inc;
   3.126 +
   3.127          rc = 0;
   3.128          *va = virt;
   3.129      }
   3.130 @@ -509,8 +529,10 @@ gnttab_unmap_grant_ref(
   3.131  
   3.132      if ( flush == 1 )
   3.133          __flush_tlb_one(va);
   3.134 +
   3.135      else if ( flush )
   3.136          local_flush_tlb();
   3.137 +
   3.138      return 0;
   3.139  }
   3.140  
   3.141 @@ -699,12 +721,94 @@ int
   3.142  gnttab_check_unmap(
   3.143      struct domain *rd, struct domain *ld, unsigned long frame, int readonly)
   3.144  {
   3.145 -    /* TODO: beat the caller around the head with a brick.
   3.146 -     *       have to walk the grant tables to find this thing.
   3.147 +    /* Called when put_page is invoked on a page belonging to a foreign domain.
   3.148 +     * Instead of decrementing the frame table ref count, locate the grant
   3.149 +     * table entry, if any, and if found, decrement that count.
   3.150 +     * Called a _lot_ at domain creation because pages mapped by priv domains
   3.151 +     * also traverse this.
   3.152       */
   3.153 -    /*DPRINTK("gnttab_check_unmap remote dom(%d) local dom(%d) frame (%x) flags(%x).\n",
   3.154 -            rd->id, ld->id, frame, readonly);*/
   3.155 -    return 0;
   3.156 +
   3.157 +    unsigned int handle, ref, refcount;
   3.158 +    grant_table_t        *lgt, *rgt;
   3.159 +    active_grant_entry_t *act;
   3.160 +    grant_mapping_t      *map;
   3.161 +    int found = 0;
   3.162 +
   3.163 +    lgt = ld->grant_table;
   3.164 +    rgt = rd->grant_table;
   3.165 +
   3.166 +    if ( ld->id != 0 ) {
   3.167 +        DPRINTK("Foreign unref rd(%d) ld(%d) frm(%x) flgs(%x).\n",
   3.168 +                rd->id, ld->id, frame, readonly);
   3.169 +    }
   3.170 +
   3.171 +    for ( handle = 0; handle < NR_MAPTRACK_ENTRIES; handle++ )
   3.172 +    {
   3.173 +        map = &lgt->maptrack[handle];
   3.174 +
   3.175 +
   3.176 +        /* cwc22: if multiple grants of the same frame are disallowed,
   3.177 +         * then the readonly check here can be changed to cause an early abort
   3.178 +         * if we've matched on frame, but not on write permission.
   3.179 +         */
   3.180 +        if ( ( map->ref_and_flags & MAPTRACK_GNTMAP_MASK ) &&
   3.181 +             ( readonly ? 1 : (!(map->ref_and_flags & GNTMAP_readonly))))
   3.182 +        {
   3.183 +            ref = (map->ref_and_flags >> MAPTRACK_REF_SHIFT);
   3.184 +            act = &rgt->active[ref];
   3.185 +
   3.186 +            spin_lock(&rgt->lock);
   3.187 +
   3.188 +            if ( act->frame != frame )
   3.189 +            {
   3.190 +                spin_unlock(&rgt->lock);
   3.191 +                continue;
   3.192 +            }
   3.193 +
   3.194 +            refcount = act->pin & ( readonly ? GNTPIN_hstr_mask
   3.195 +                                             : GNTPIN_hstw_mask );
   3.196 +            if ( refcount == 0 )
   3.197 +            {
   3.198 +                spin_unlock(&rgt->lock);
   3.199 +                continue;
   3.200 +            }
   3.201 +
   3.202 +            /* gotcha */
   3.203 +            DPRINTK("Grant unref rd(%d) ld(%d) frm(%x) flgs(%x).\n",
   3.204 +                    rd->id, ld->id, frame, readonly);
   3.205 +
   3.206 +            if ( readonly )
   3.207 +                act->pin -= GNTPIN_hstr_inc;
   3.208 +            else
   3.209 +            {
   3.210 +                act->pin -= GNTPIN_hstw_inc;
   3.211 +
   3.212 +                /* any more granted writable mappings? */
   3.213 +                if ( (act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)) == 0 )
   3.214 +                {
   3.215 +                    put_page_type(&frame_table[frame]);
   3.216 +                    clear_bit(_GTF_writing, &rgt->shared[ref].flags);
   3.217 +                }
   3.218 +            }
   3.219 +
   3.220 +            if ( act->pin == 0 )
   3.221 +            {
   3.222 +                put_page(&frame_table[frame]);
   3.223 +                clear_bit(_GTF_reading, &rgt->shared[ref].flags);
   3.224 +            }
   3.225 +            spin_unlock(&rgt->lock);
   3.226 +
   3.227 +            clear_bit(GNTMAP_host_map, &map->ref_and_flags);
   3.228 +
   3.229 +            if ( !(map->ref_and_flags & GNTMAP_device_map) )
   3.230 +                put_maptrack_handle(lgt, handle);
   3.231 +
   3.232 +            found = 1;
   3.233 +            break;
   3.234 +        }
   3.235 +    }
   3.236 +
   3.237 +    return found;
   3.238  }
   3.239  
   3.240  int 
   3.241 @@ -845,74 +949,6 @@ grant_table_create(
   3.242  }
   3.243  
   3.244  void
   3.245 -gnttab_release_all_mappings(grant_table_t *gt)
   3.246 -{
   3.247 -    grant_mapping_t        *map;
   3.248 -    domid_t                 dom;
   3.249 -    grant_ref_t             ref;
   3.250 -    u16                     handle;
   3.251 -    u32                     pincount;
   3.252 -    struct domain          *ld, *rd;
   3.253 -    unsigned long           frame;
   3.254 -    active_grant_entry_t   *act;
   3.255 -    grant_entry_t          *sha;
   3.256 -
   3.257 -    ld = current->domain;
   3.258 -
   3.259 -    for ( handle = 0; handle < NR_MAPTRACK_ENTRIES; handle++ )
   3.260 -    {
   3.261 -        map = &gt->maptrack[handle];
   3.262 -                                                                                        
   3.263 -        if ( map->ref_and_flags & MAPTRACK_GNTMAP_MASK )
   3.264 -        {
   3.265 -            dom = map->domid;
   3.266 -            ref = map->ref_and_flags >> MAPTRACK_REF_SHIFT;
   3.267 -
   3.268 -            DPRINTK("Grant release (%hu) ref:(%hu) flags:(%x) dom:(%hu)\n",
   3.269 -                    handle, ref,
   3.270 -                    map->ref_and_flags & MAPTRACK_GNTMAP_MASK, dom);
   3.271 -
   3.272 -            if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
   3.273 -                 unlikely(ld == rd) )
   3.274 -            {
   3.275 -                if ( rd != NULL )
   3.276 -                    put_domain(rd);
   3.277 -
   3.278 -                printk(KERN_WARNING "Grant release: Could not find domain %d\n", dom);
   3.279 -                continue;
   3.280 -            }
   3.281 -
   3.282 -            act = &rd->grant_table->active[ref];
   3.283 -            sha = &rd->grant_table->shared[ref];
   3.284 -
   3.285 -            spin_lock(&rd->grant_table->lock);
   3.286 -
   3.287 -            frame = act->frame;
   3.288 -
   3.289 -            pincount = ((act->pin & GNTPIN_hstw_mask) >> GNTPIN_hstw_shift) +
   3.290 -                       ((act->pin & GNTPIN_devw_mask) >> GNTPIN_devw_shift);
   3.291 -
   3.292 -            if ( pincount > 0 )
   3.293 -                put_page_type(&frame_table[frame]);
   3.294 -
   3.295 -            if (act->pin)
   3.296 -                put_page(&frame_table[frame]);
   3.297 -
   3.298 -            act->pin = 0;
   3.299 -
   3.300 -            clear_bit(_GTF_reading, &sha->flags);
   3.301 -            clear_bit(_GTF_writing, &sha->flags);
   3.302 -
   3.303 -            spin_unlock(&rd->grant_table->lock);
   3.304 -
   3.305 -            map->ref_and_flags = 0;
   3.306 -
   3.307 -            put_domain(rd);
   3.308 -        }
   3.309 -    }
   3.310 -}
   3.311 -
   3.312 -void
   3.313  grant_table_destroy(
   3.314      struct domain *d)
   3.315  {
   3.316 @@ -920,9 +956,6 @@ grant_table_destroy(
   3.317  
   3.318      if ( (t = d->grant_table) != NULL )
   3.319      {
   3.320 -        if ( t->maptrack != NULL )
   3.321 -            gnttab_release_all_mappings(t);
   3.322 -
   3.323          /* Free memory relating to this grant table. */
   3.324          d->grant_table = NULL;
   3.325          free_xenheap_page((unsigned long)t->shared);
     4.1 --- a/xen/include/xen/grant_table.h	Wed Mar 09 16:45:29 2005 +0000
     4.2 +++ b/xen/include/xen/grant_table.h	Thu Mar 10 03:30:18 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__ */