ia64/xen-unstable

changeset 4100:bd0c28f54450

bitkeeper revision 1.1236.26.1 (4231b4a20dnya9Kf1nGoYAKIhIcGJw)

Grant tables map operation working.
author cwc22@centipede.cl.cam.ac.uk
date Fri Mar 11 15:09:22 2005 +0000 (2005-03-11)
parents afa2f6b47e70
children 00c3e9ce38eb
files xen/arch/x86/domain.c xen/arch/x86/mm.c xen/common/grant_table.c xen/include/asm-x86/mm.h xen/include/xen/grant_table.h
line diff
     1.1 --- a/xen/arch/x86/domain.c	Thu Mar 10 16:10:02 2005 +0000
     1.2 +++ b/xen/arch/x86/domain.c	Fri Mar 11 15:09:22 2005 +0000
     1.3 @@ -970,6 +970,10 @@ 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 device mappings of other domains */
     1.8 +    gnttab_release_dev_mappings( d->grant_table );
     1.9 +
    1.10 +
    1.11      /* Exit shadow mode before deconstructing final guest page table. */
    1.12      shadow_mode_disable(d);
    1.13  
     2.1 --- a/xen/arch/x86/mm.c	Thu Mar 10 16:10:02 2005 +0000
     2.2 +++ b/xen/arch/x86/mm.c	Fri Mar 11 15:09:22 2005 +0000
     2.3 @@ -1976,13 +1976,6 @@ int update_grant_va_mapping(unsigned lon
     2.4       * . check PTE being installed isn't DISALLOWED
     2.5       */
     2.6  
     2.7 -    /* Return value:
     2.8 -     * -ve : error
     2.9 -     * 0   : done
    2.10 -     * GNTUPDVA_prev_ro : done & prior mapping was ro to same frame
    2.11 -     * GNTUPDVA_prev_rw : done & prior mapping was rw to same frame
    2.12 -     */
    2.13 -
    2.14      int             rc = 0;
    2.15      l1_pgentry_t   *pl1e;
    2.16      unsigned long   _ol1e;
    2.17 @@ -1998,18 +1991,7 @@ int update_grant_va_mapping(unsigned lon
    2.18          l1_pgentry_t ol1e = mk_l1_pgentry(_ol1e);
    2.19  
    2.20          if ( update_l1e(pl1e, ol1e, mk_l1_pgentry(_nl1e)) )
    2.21 -        {
    2.22 -            /* overwrote different mfn?  */
    2.23 -            if (((_ol1e ^ _nl1e) & (PADDR_MASK & PAGE_MASK)) != 0)
    2.24 -                put_page_from_l1e(ol1e, d);
    2.25 -
    2.26 -            else if (_ol1e & _PAGE_PRESENT)
    2.27 -                rc = ((_ol1e & _PAGE_RW) ? GNTUPDVA_prev_rw
    2.28 -                                         : GNTUPDVA_prev_ro );
    2.29 -                /* use return code to avoid nasty grant table
    2.30 -                 * slow path in put_page_from_l1e -- caller
    2.31 -                 * must handle grant ref count instead. */
    2.32 -        }
    2.33 +            put_page_from_l1e(ol1e, d);
    2.34          else
    2.35              rc = -EINVAL;
    2.36      }
     3.1 --- a/xen/common/grant_table.c	Thu Mar 10 16:10:02 2005 +0000
     3.2 +++ b/xen/common/grant_table.c	Fri Mar 11 15:09:22 2005 +0000
     3.3 @@ -227,6 +227,8 @@ static int
     3.4          if ( (act->pin & 0x80808080U) != 0 )
     3.5              PIN_FAIL(ENOSPC, "Risk of counter overflow %08x\n", act->pin);
     3.6  
     3.7 +        frame = act->frame;
     3.8 +
     3.9          if ( !(flags & GNTMAP_readonly) && 
    3.10               !((sflags = sha->flags) & GTF_writing) )
    3.11          {
    3.12 @@ -256,8 +258,6 @@ static int
    3.13                  sflags = prev_sflags;
    3.14              }
    3.15  
    3.16 -            frame = act->frame;
    3.17 -
    3.18              if ( unlikely(!get_page_type(&frame_table[frame],
    3.19                                           PGT_writable_page)) )
    3.20              {
    3.21 @@ -275,14 +275,9 @@ static int
    3.22                  GNTPIN_hstr_inc : GNTPIN_hstw_inc;
    3.23      }
    3.24  
    3.25 -    ld->grant_table->maptrack[handle].domid         = dom;
    3.26 -    ld->grant_table->maptrack[handle].ref_and_flags =
    3.27 -        (ref << MAPTRACK_REF_SHIFT) | (flags & MAPTRACK_GNTMAP_MASK);
    3.28 -
    3.29      /* At this point:
    3.30       * act->pin updated to reflect mapping
    3.31       * sha->flags updated to indicate to granting domain mapping done
    3.32 -     * maptrack points to correct remote domain data
    3.33       * frame contains the mfn
    3.34       */
    3.35  
    3.36 @@ -290,12 +285,22 @@ static int
    3.37      {
    3.38          /* Write update into the pagetable
    3.39           */
    3.40 -        if ( 0 > (rc = update_grant_va_mapping( host_virt_addr,
    3.41 +
    3.42 +        /* cwc22: TODO: check locking... */
    3.43 +
    3.44 +        spin_unlock(&rd->grant_table->lock);
    3.45 +
    3.46 +        rc = update_grant_va_mapping( host_virt_addr,
    3.47                                  (frame << PAGE_SHIFT) | _PAGE_PRESENT  |
    3.48                                                          _PAGE_ACCESSED |
    3.49                                                          _PAGE_DIRTY    |
    3.50                         ((flags & GNTMAP_readonly) ? 0 : _PAGE_RW),
    3.51 -                       ld, led )) )
    3.52 +                       ld, led );
    3.53 +        DPRINTK("update_grant_va_mapping : rc %d\n", rc);
    3.54 +
    3.55 +        spin_lock(&rd->grant_table->lock);
    3.56 +
    3.57 +        if ( 0 > rc )
    3.58          {
    3.59              /* Abort. */
    3.60              act->pin -= (flags & GNTMAP_readonly) ?
    3.61 @@ -306,37 +311,20 @@ static int
    3.62              else
    3.63              {
    3.64                  act->pin -= GNTPIN_hstw_inc;
    3.65 -                if ( (act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)) == 0 )
    3.66 +                if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 )
    3.67                  {
    3.68                      put_page_type(&frame_table[frame]);
    3.69                      clear_bit(_GTF_writing, &sha->flags);
    3.70                  }
    3.71 -
    3.72 -                if ( act->pin == 0 )
    3.73 -                {
    3.74 -                    put_page(&frame_table[frame]);
    3.75 -                    clear_bit(_GTF_reading, &sha->flags);
    3.76 -                }
    3.77 +            }
    3.78 +            if ( act->pin == 0 )
    3.79 +            {
    3.80 +                put_page(&frame_table[frame]);
    3.81 +                clear_bit(_GTF_reading, &sha->flags);
    3.82              }
    3.83              goto fail;
    3.84          }
    3.85  
    3.86 -        /* Check to see if update overwrote a mapping of the same mfn
    3.87 -         * - if so, must handle ref count here
    3.88 -         */
    3.89 -        if ( rc == GNTUPDVA_prev_ro )
    3.90 -            act->pin -= GNTPIN_hstr_inc;
    3.91 -
    3.92 -        if ( rc == GNTUPDVA_prev_rw ) 
    3.93 -        {
    3.94 -            act->pin -= GNTPIN_hstw_inc;
    3.95 -
    3.96 -            if ( (act->pin & (GNTPIN_hstw_mask | GNTPIN_devw_mask)) == 0 )
    3.97 -            {
    3.98 -                put_page_type(&frame_table[frame]);
    3.99 -                clear_bit(_GTF_writing, &sha->flags);
   3.100 -            }
   3.101 -        }
   3.102          rc = 0;
   3.103          *va = host_virt_addr;
   3.104  
   3.105 @@ -345,6 +333,12 @@ static int
   3.106           */
   3.107      }
   3.108  
   3.109 +    /* Only make the maptrack live _after_ writing the pte, in case
   3.110 +     * we overwrite the same frame number, causing a maptrack walk to find it */
   3.111 +    ld->grant_table->maptrack[handle].domid         = dom;
   3.112 +    ld->grant_table->maptrack[handle].ref_and_flags =
   3.113 +        (ref << MAPTRACK_REF_SHIFT) | (flags & MAPTRACK_GNTMAP_MASK);
   3.114 +
   3.115      /* Unchecked and unconditional writes to user uop. */
   3.116      if ( flags & GNTMAP_device_map )
   3.117          (void)__put_user(frame,  &uop->dev_bus_addr);
   3.118 @@ -437,6 +431,8 @@ static int
   3.119      act = &rd->grant_table->active[ref];
   3.120      sha = &rd->grant_table->shared[ref];
   3.121  
   3.122 +    // cwc22: TODO: put_maptrack_handle
   3.123 +
   3.124      spin_lock(&rd->grant_table->lock);
   3.125  
   3.126      if ( frame != 0 )
   3.127 @@ -643,9 +639,9 @@ gnttab_dump_table(gnttab_dump_table_t *u
   3.128          if ( act->pin || act->domid || act->frame ||
   3.129               sha_copy.flags || sha_copy.domid || sha_copy.frame )
   3.130          {
   3.131 -            DPRINTK("Grant: dom (%hu) ACTIVE (%d) pin:(%x) dom:(%hu) frame:(%u)\n",
   3.132 +            DPRINTK("Grant: dom (%hu) ACTIVE (%d) pin:(%x) dom:(%hu) frame:(%lx)\n",
   3.133                      op.dom, i, act->pin, act->domid, act->frame);
   3.134 -            DPRINTK("Grant: dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu) frame:(%u)\n",
   3.135 +            DPRINTK("Grant: dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu) frame:(%lx)\n",
   3.136                      op.dom, i, sha_copy.flags, sha_copy.domid, sha_copy.frame);
   3.137  
   3.138          }
   3.139 @@ -729,6 +725,11 @@ gnttab_check_unmap(
   3.140       * also traverse this.
   3.141       */
   3.142  
   3.143 +    /* Note: if the same frame is mapped multiple times, and then one of
   3.144 +     *       the ptes is overwritten, which maptrack handle gets invalidated?
   3.145 +     * Advice: don't do it.
   3.146 +     */
   3.147 +
   3.148      unsigned int handle, ref, refcount;
   3.149      grant_table_t        *lgt, *rgt;
   3.150      active_grant_entry_t *act;
   3.151 @@ -741,8 +742,6 @@ gnttab_check_unmap(
   3.152      if ( lgt->map_count == 0 )
   3.153          return 0;
   3.154  
   3.155 -    rgt = rd->grant_table;
   3.156 -
   3.157  #ifdef GRANT_DEBUG
   3.158      if ( ld->id != 0 ) {
   3.159          DPRINTK("Foreign unref rd(%d) ld(%d) frm(%x) flgs(%x).\n",
   3.160 @@ -750,6 +749,14 @@ gnttab_check_unmap(
   3.161      }
   3.162  #endif
   3.163  
   3.164 +    if ( get_domain(rd) == 0 )
   3.165 +    {
   3.166 +        DPRINTK("gnttab_check_unmap: couldn't get_domain rd(%d)\n", rd->id);
   3.167 +        return 0;
   3.168 +    }
   3.169 +
   3.170 +    rgt = rd->grant_table;
   3.171 +
   3.172      for ( handle = 0; handle < NR_MAPTRACK_ENTRIES; handle++ )
   3.173      {
   3.174          map = &lgt->maptrack[handle];
   3.175 @@ -792,7 +799,7 @@ gnttab_check_unmap(
   3.176                  act->pin -= GNTPIN_hstw_inc;
   3.177  
   3.178                  /* any more granted writable mappings? */
   3.179 -                if ( (act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)) == 0 )
   3.180 +                if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 )
   3.181                  {
   3.182                      put_page_type(&frame_table[frame]);
   3.183                      clear_bit(_GTF_writing, &rgt->shared[ref].flags);
   3.184 @@ -815,6 +822,7 @@ gnttab_check_unmap(
   3.185              break;
   3.186          }
   3.187      }
   3.188 +    put_domain(rd);
   3.189  
   3.190      return found;
   3.191  }
   3.192 @@ -957,6 +965,79 @@ grant_table_create(
   3.193  }
   3.194  
   3.195  void
   3.196 +gnttab_release_dev_mappings(grant_table_t *gt)
   3.197 +{
   3.198 +    grant_mapping_t        *map;
   3.199 +    domid_t                 dom;
   3.200 +    grant_ref_t             ref;
   3.201 +    u16                     handle;
   3.202 +    struct domain          *ld, *rd;
   3.203 +    unsigned long           frame;
   3.204 +    active_grant_entry_t   *act;
   3.205 +    grant_entry_t          *sha;
   3.206 +
   3.207 +    ld = current->domain;
   3.208 +
   3.209 +    for ( handle = 0; handle < NR_MAPTRACK_ENTRIES; handle++ )
   3.210 +    {
   3.211 +        map = &gt->maptrack[handle];
   3.212 +
   3.213 +        if ( map->ref_and_flags & GNTMAP_device_map )
   3.214 +        {
   3.215 +            dom = map->domid;
   3.216 +            ref = map->ref_and_flags >> MAPTRACK_REF_SHIFT;
   3.217 +
   3.218 +            DPRINTK("Grant release (%hu) ref:(%hu) flags:(%x) dom:(%hu)\n",
   3.219 +                    handle, ref,
   3.220 +                    map->ref_and_flags & MAPTRACK_GNTMAP_MASK, dom);
   3.221 +
   3.222 +            if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
   3.223 +                 unlikely(ld == rd) )
   3.224 +            {
   3.225 +                if ( rd != NULL )
   3.226 +                    put_domain(rd);
   3.227 +
   3.228 +                printk(KERN_WARNING "Grant release: Could not find domain %d\n", dom);
   3.229 +                continue;
   3.230 +            }
   3.231 +
   3.232 +            act = &rd->grant_table->active[ref];
   3.233 +            sha = &rd->grant_table->shared[ref];
   3.234 +
   3.235 +            spin_lock(&rd->grant_table->lock);
   3.236 +
   3.237 +            if ( act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask) )
   3.238 +            {
   3.239 +                frame = act->frame;
   3.240 +
   3.241 +                if ( ( (act->pin & GNTPIN_hstw_mask) == 0 ) &&
   3.242 +                     ( (act->pin & GNTPIN_devw_mask) >  0 ) )
   3.243 +                {
   3.244 +                    clear_bit(_GTF_writing, &sha->flags);
   3.245 +                    put_page_type(&frame_table[frame]);
   3.246 +                }
   3.247 +
   3.248 +                act->pin &= ~(GNTPIN_devw_mask | GNTPIN_devr_mask);
   3.249 +
   3.250 +                if ( act->pin == 0 )
   3.251 +                {
   3.252 +                    clear_bit(_GTF_reading, &sha->flags);
   3.253 +                    map->ref_and_flags = 0;
   3.254 +                    put_page(&frame_table[frame]);
   3.255 +                }
   3.256 +                else
   3.257 +                    map->ref_and_flags &= ~GNTMAP_device_map;
   3.258 +            }
   3.259 +
   3.260 +            spin_unlock(&rd->grant_table->lock);
   3.261 +
   3.262 +            put_domain(rd);
   3.263 +        }
   3.264 +    }
   3.265 +}
   3.266 +
   3.267 +
   3.268 +void
   3.269  grant_table_destroy(
   3.270      struct domain *d)
   3.271  {
     4.1 --- a/xen/include/asm-x86/mm.h	Thu Mar 10 16:10:02 2005 +0000
     4.2 +++ b/xen/include/asm-x86/mm.h	Fri Mar 11 15:09:22 2005 +0000
     4.3 @@ -343,7 +343,4 @@ int update_grant_va_mapping(unsigned lon
     4.4                              unsigned long val,
     4.5                              struct domain *d,
     4.6                              struct exec_domain *ed);
     4.7 -#define GNTUPDVA_prev_ro 1
     4.8 -#define GNTUPDVA_prev_rw 2
     4.9 -
    4.10  #endif /* __ASM_X86_MM_H__ */
     5.1 --- a/xen/include/xen/grant_table.h	Thu Mar 10 16:10:02 2005 +0000
     5.2 +++ b/xen/include/xen/grant_table.h	Fri Mar 11 15:09:22 2005 +0000
     5.3 @@ -106,4 +106,8 @@ void
     5.4  gnttab_notify_transfer(
     5.5      struct domain *rd, grant_ref_t ref, unsigned long frame);
     5.6  
     5.7 +/* Pre-domain destruction release of granted device mappings of other domains.*/
     5.8 +void
     5.9 +gnttab_release_dev_mappings(grant_table_t *gt);
    5.10 +
    5.11  #endif /* __XEN_GRANT_H__ */