ia64/xen-unstable

changeset 8859:1346a69694be

Clean up grant-table code and replace uses of get_user
and put_user in common code. This is an attempt to narrow
the uaccess API before it gets replaced.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Feb 15 15:20:32 2006 +0100 (2006-02-15)
parents 765b0657264d
children 1ca3d63e7008
files xen/common/grant_table.c xen/common/memory.c xen/common/multicall.c xen/drivers/char/console.c xen/include/public/grant_table.h
line diff
     1.1 --- a/xen/common/grant_table.c	Wed Feb 15 14:13:10 2006 +0000
     1.2 +++ b/xen/common/grant_table.c	Wed Feb 15 15:20:32 2006 +0100
     1.3 @@ -66,17 +66,13 @@ put_maptrack_handle(
     1.4   * addr is _either_ a host virtual address, or the address of the pte to
     1.5   * update, as indicated by the GNTMAP_contains_pte flag.
     1.6   */
     1.7 -static int
     1.8 +static void
     1.9  __gnttab_map_grant_ref(
    1.10 -    gnttab_map_grant_ref_t *uop)
    1.11 +    struct gnttab_map_grant_ref *op)
    1.12  {
    1.13 -    domid_t        dom;
    1.14 -    grant_ref_t    ref;
    1.15      struct domain *ld, *rd;
    1.16      struct vcpu   *led;
    1.17 -    u32            dev_hst_ro_flags;
    1.18      int            handle;
    1.19 -    u64            addr;
    1.20      unsigned long  frame = 0;
    1.21      int            rc = GNTST_okay;
    1.22      active_grant_entry_t *act;
    1.23 @@ -99,39 +95,28 @@ static int
    1.24      led = current;
    1.25      ld = led->domain;
    1.26  
    1.27 -    /* Bitwise-OR avoids short-circuiting which screws control flow. */
    1.28 -    if ( unlikely(__get_user(dom, &uop->dom) |
    1.29 -                  __get_user(ref, &uop->ref) |
    1.30 -                  __get_user(addr, &uop->host_addr) |
    1.31 -                  __get_user(dev_hst_ro_flags, &uop->flags)) )
    1.32 +    if ( unlikely(op->ref >= NR_GRANT_ENTRIES) ||
    1.33 +         unlikely((op->flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0) )
    1.34      {
    1.35 -        DPRINTK("Fault while reading gnttab_map_grant_ref_t.\n");
    1.36 -        return -EFAULT; /* don't set status */
    1.37 +        DPRINTK("Bad ref (%d) or flags (%x).\n", op->ref, op->flags);
    1.38 +        op->status = GNTST_bad_gntref;
    1.39 +        return;
    1.40      }
    1.41  
    1.42 -    if ( unlikely(ref >= NR_GRANT_ENTRIES) ||
    1.43 -         unlikely((dev_hst_ro_flags &
    1.44 -                   (GNTMAP_device_map|GNTMAP_host_map)) == 0) )
    1.45 +    if ( acm_pre_grant_map_ref(op->dom) )
    1.46      {
    1.47 -        DPRINTK("Bad ref (%d) or flags (%x).\n", ref, dev_hst_ro_flags);
    1.48 -        (void)__put_user(GNTST_bad_gntref, &uop->status);
    1.49 -        return GNTST_bad_gntref;
    1.50 +        op->status = GNTST_permission_denied;
    1.51 +        return;
    1.52      }
    1.53  
    1.54 -    if ( acm_pre_grant_map_ref(dom) )
    1.55 -    {
    1.56 -        (void)__put_user(GNTST_permission_denied, &uop->status);
    1.57 -        return GNTST_permission_denied;
    1.58 -    }
    1.59 -
    1.60 -    if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
    1.61 +    if ( unlikely((rd = find_domain_by_id(op->dom)) == NULL) ||
    1.62           unlikely(ld == rd) )
    1.63      {
    1.64          if ( rd != NULL )
    1.65              put_domain(rd);
    1.66 -        DPRINTK("Could not find domain %d\n", dom);
    1.67 -        (void)__put_user(GNTST_bad_domain, &uop->status);
    1.68 -        return GNTST_bad_domain;
    1.69 +        DPRINTK("Could not find domain %d\n", op->dom);
    1.70 +        op->status = GNTST_bad_domain;
    1.71 +        return;
    1.72      }
    1.73  
    1.74      /* Get a maptrack handle. */
    1.75 @@ -145,8 +130,8 @@ static int
    1.76          {
    1.77              put_domain(rd);
    1.78              DPRINTK("Maptrack table is at maximum size.\n");
    1.79 -            (void)__put_user(GNTST_no_device_space, &uop->status);
    1.80 -            return GNTST_no_device_space;
    1.81 +            op->status = GNTST_no_device_space;
    1.82 +            return;
    1.83          }
    1.84  
    1.85          /* Grow the maptrack table. */
    1.86 @@ -155,8 +140,8 @@ static int
    1.87          {
    1.88              put_domain(rd);
    1.89              DPRINTK("No more map handles available.\n");
    1.90 -            (void)__put_user(GNTST_no_device_space, &uop->status);
    1.91 -            return GNTST_no_device_space;
    1.92 +            op->status = GNTST_no_device_space;
    1.93 +            return;
    1.94          }
    1.95  
    1.96          memcpy(new_mt, lgt->maptrack, PAGE_SIZE << lgt->maptrack_order);
    1.97 @@ -172,13 +157,13 @@ static int
    1.98          handle = get_maptrack_handle(ld->grant_table);
    1.99      }
   1.100  
   1.101 -    act = &rd->grant_table->active[ref];
   1.102 -    sha = &rd->grant_table->shared[ref];
   1.103 +    act = &rd->grant_table->active[op->ref];
   1.104 +    sha = &rd->grant_table->shared[op->ref];
   1.105  
   1.106      spin_lock(&rd->grant_table->lock);
   1.107  
   1.108      if ( !act->pin ||
   1.109 -         (!(dev_hst_ro_flags & GNTMAP_readonly) &&
   1.110 +         (!(op->flags & GNTMAP_readonly) &&
   1.111            !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask))) )
   1.112      {
   1.113          sflags = sha->flags;
   1.114 @@ -205,7 +190,7 @@ static int
   1.115              prev_scombo = scombo = ((u32)sdom << 16) | (u32)sflags;
   1.116  
   1.117              new_scombo = scombo | GTF_reading;
   1.118 -            if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
   1.119 +            if ( !(op->flags & GNTMAP_readonly) )
   1.120              {
   1.121                  new_scombo |= GTF_writing;
   1.122                  if ( unlikely(sflags & GTF_readonly) )
   1.123 @@ -244,68 +229,68 @@ static int
   1.124          PIN_FAIL(unlock_out, ENOSPC,
   1.125                   "Risk of counter overflow %08x\n", act->pin);
   1.126  
   1.127 -    if ( dev_hst_ro_flags & GNTMAP_device_map )
   1.128 -        act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
   1.129 +    if ( op->flags & GNTMAP_device_map )
   1.130 +        act->pin += (op->flags & GNTMAP_readonly) ?
   1.131              GNTPIN_devr_inc : GNTPIN_devw_inc;
   1.132 -    if ( dev_hst_ro_flags & GNTMAP_host_map )
   1.133 -        act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
   1.134 +    if ( op->flags & GNTMAP_host_map )
   1.135 +        act->pin += (op->flags & GNTMAP_readonly) ?
   1.136              GNTPIN_hstr_inc : GNTPIN_hstw_inc;
   1.137  
   1.138      spin_unlock(&rd->grant_table->lock);
   1.139  
   1.140      frame = act->frame;
   1.141      if ( unlikely(!mfn_valid(frame)) ||
   1.142 -         unlikely(!((dev_hst_ro_flags & GNTMAP_readonly) ?
   1.143 +         unlikely(!((op->flags & GNTMAP_readonly) ?
   1.144                      get_page(mfn_to_page(frame), rd) :
   1.145                      get_page_and_type(mfn_to_page(frame), rd,
   1.146                                        PGT_writable_page))) )
   1.147          PIN_FAIL(undo_out, GNTST_general_error,
   1.148                   "Could not pin the granted frame (%lx)!\n", frame);
   1.149  
   1.150 -    if ( dev_hst_ro_flags & GNTMAP_host_map )
   1.151 +    if ( op->flags & GNTMAP_host_map )
   1.152      {
   1.153 -        rc = create_grant_host_mapping(addr, frame, dev_hst_ro_flags);
   1.154 +        rc = create_grant_host_mapping(op->host_addr, frame, op->flags);
   1.155          if ( rc != GNTST_okay )
   1.156          {
   1.157 -            if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
   1.158 +            if ( !(op->flags & GNTMAP_readonly) )
   1.159                  put_page_type(mfn_to_page(frame));
   1.160              put_page(mfn_to_page(frame));
   1.161              goto undo_out;
   1.162          }
   1.163  
   1.164 -        if ( dev_hst_ro_flags & GNTMAP_device_map )
   1.165 +        if ( op->flags & GNTMAP_device_map )
   1.166          {
   1.167              (void)get_page(mfn_to_page(frame), rd);
   1.168 -            if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
   1.169 +            if ( !(op->flags & GNTMAP_readonly) )
   1.170                  get_page_type(mfn_to_page(frame), PGT_writable_page);
   1.171          }
   1.172      }
   1.173  
   1.174 -    TRACE_1D(TRC_MEM_PAGE_GRANT_MAP, dom);
   1.175 +    TRACE_1D(TRC_MEM_PAGE_GRANT_MAP, op->dom);
   1.176  
   1.177 -    ld->grant_table->maptrack[handle].domid         = dom;
   1.178 +    ld->grant_table->maptrack[handle].domid         = op->dom;
   1.179      ld->grant_table->maptrack[handle].ref_and_flags =
   1.180 -        (ref << MAPTRACK_REF_SHIFT) |
   1.181 -        (dev_hst_ro_flags & MAPTRACK_GNTMAP_MASK);
   1.182 +        (op->ref << MAPTRACK_REF_SHIFT) |
   1.183 +        (op->flags & MAPTRACK_GNTMAP_MASK);
   1.184  
   1.185 -    (void)__put_user((u64)frame << PAGE_SHIFT, &uop->dev_bus_addr);
   1.186 -    (void)__put_user(handle, &uop->handle);
   1.187 -    (void)__put_user(GNTST_okay, &uop->status);
   1.188 +    op->dev_bus_addr = (u64)frame << PAGE_SHIFT;
   1.189 +    op->handle       = handle;
   1.190 +    op->status       = GNTST_okay;
   1.191  
   1.192      put_domain(rd);
   1.193 -    return rc;
   1.194 +    return;
   1.195  
   1.196   undo_out:
   1.197      spin_lock(&rd->grant_table->lock);
   1.198  
   1.199 -    if ( dev_hst_ro_flags & GNTMAP_device_map )
   1.200 -        act->pin -= (dev_hst_ro_flags & GNTMAP_readonly) ?
   1.201 +    if ( op->flags & GNTMAP_device_map )
   1.202 +        act->pin -= (op->flags & GNTMAP_readonly) ?
   1.203              GNTPIN_devr_inc : GNTPIN_devw_inc;
   1.204 -    if ( dev_hst_ro_flags & GNTMAP_host_map )
   1.205 -        act->pin -= (dev_hst_ro_flags & GNTMAP_readonly) ?
   1.206 +    if ( op->flags & GNTMAP_host_map )
   1.207 +        act->pin -= (op->flags & GNTMAP_readonly) ?
   1.208              GNTPIN_hstr_inc : GNTPIN_hstw_inc;
   1.209  
   1.210 -    if ( !(dev_hst_ro_flags & GNTMAP_readonly) &&
   1.211 +    if ( !(op->flags & GNTMAP_readonly) &&
   1.212           !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
   1.213          clear_bit(_GTF_writing, &sha->flags);
   1.214  
   1.215 @@ -314,61 +299,56 @@ static int
   1.216  
   1.217   unlock_out:
   1.218      spin_unlock(&rd->grant_table->lock);
   1.219 -    (void)__put_user(rc, &uop->status);
   1.220 +    op->status = rc;
   1.221      put_maptrack_handle(ld->grant_table, handle);
   1.222      put_domain(rd);
   1.223 -    return rc;
   1.224  }
   1.225  
   1.226  static long
   1.227  gnttab_map_grant_ref(
   1.228 -    gnttab_map_grant_ref_t *uop, unsigned int count)
   1.229 +    struct gnttab_map_grant_ref *uop, unsigned int count)
   1.230  {
   1.231      int i;
   1.232 +    struct gnttab_map_grant_ref op;
   1.233  
   1.234      for ( i = 0; i < count; i++ )
   1.235 -        (void)__gnttab_map_grant_ref(&uop[i]);
   1.236 +    {
   1.237 +        if ( unlikely(__copy_from_user(&op, &uop[i], sizeof(op))) )
   1.238 +            return -EFAULT;
   1.239 +        __gnttab_map_grant_ref(&op);
   1.240 +        if ( unlikely(__copy_to_user(&uop[i], &op, sizeof(op))) )
   1.241 +            return -EFAULT;
   1.242 +    }
   1.243  
   1.244      return 0;
   1.245  }
   1.246  
   1.247 -static int
   1.248 +static void
   1.249  __gnttab_unmap_grant_ref(
   1.250 -    gnttab_unmap_grant_ref_t *uop)
   1.251 +    struct gnttab_unmap_grant_ref *op)
   1.252  {
   1.253      domid_t          dom;
   1.254      grant_ref_t      ref;
   1.255 -    grant_handle_t   handle;
   1.256      struct domain   *ld, *rd;
   1.257      active_grant_entry_t *act;
   1.258      grant_entry_t   *sha;
   1.259      grant_mapping_t *map;
   1.260      u16              flags;
   1.261      s16              rc = 0;
   1.262 -    u64              addr, dev_bus_addr;
   1.263      unsigned long    frame;
   1.264  
   1.265      ld = current->domain;
   1.266  
   1.267 -    /* Bitwise-OR avoids short-circuiting which screws control flow. */
   1.268 -    if ( unlikely(__get_user(addr, &uop->host_addr) |
   1.269 -                  __get_user(dev_bus_addr, &uop->dev_bus_addr) |
   1.270 -                  __get_user(handle, &uop->handle)) )
   1.271 -    {
   1.272 -        DPRINTK("Fault while reading gnttab_unmap_grant_ref_t.\n");
   1.273 -        return -EFAULT; /* don't set status */
   1.274 -    }
   1.275 +    frame = (unsigned long)(op->dev_bus_addr >> PAGE_SHIFT);
   1.276  
   1.277 -    frame = (unsigned long)(dev_bus_addr >> PAGE_SHIFT);
   1.278 +    map = &ld->grant_table->maptrack[op->handle];
   1.279  
   1.280 -    map = &ld->grant_table->maptrack[handle];
   1.281 -
   1.282 -    if ( unlikely(handle >= ld->grant_table->maptrack_limit) ||
   1.283 +    if ( unlikely(op->handle >= ld->grant_table->maptrack_limit) ||
   1.284           unlikely(!(map->ref_and_flags & MAPTRACK_GNTMAP_MASK)) )
   1.285      {
   1.286 -        DPRINTK("Bad handle (%d).\n", handle);
   1.287 -        (void)__put_user(GNTST_bad_handle, &uop->status);
   1.288 -        return GNTST_bad_handle;
   1.289 +        DPRINTK("Bad handle (%d).\n", op->handle);
   1.290 +        op->status = GNTST_bad_handle;
   1.291 +        return;
   1.292      }
   1.293  
   1.294      dom   = map->domid;
   1.295 @@ -381,8 +361,8 @@ static int
   1.296          if ( rd != NULL )
   1.297              put_domain(rd);
   1.298          DPRINTK("Could not find domain %d\n", dom);
   1.299 -        (void)__put_user(GNTST_bad_domain, &uop->status);
   1.300 -        return GNTST_bad_domain;
   1.301 +        op->status = GNTST_bad_domain;
   1.302 +        return;
   1.303      }
   1.304  
   1.305      TRACE_1D(TRC_MEM_PAGE_GRANT_UNMAP, dom);
   1.306 @@ -418,9 +398,10 @@ static int
   1.307          }
   1.308      }
   1.309  
   1.310 -    if ( (addr != 0) && (flags & GNTMAP_host_map) )
   1.311 +    if ( (op->host_addr != 0) && (flags & GNTMAP_host_map) )
   1.312      {
   1.313 -        if ( (rc = destroy_grant_host_mapping(addr, frame, flags)) < 0 )
   1.314 +        if ( (rc = destroy_grant_host_mapping(op->host_addr,
   1.315 +                                              frame, flags)) < 0 )
   1.316              goto unmap_out;
   1.317  
   1.318          ASSERT(act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask));
   1.319 @@ -440,7 +421,7 @@ static int
   1.320      if ( (map->ref_and_flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0 )
   1.321      {
   1.322          map->ref_and_flags = 0;
   1.323 -        put_maptrack_handle(ld->grant_table, handle);
   1.324 +        put_maptrack_handle(ld->grant_table, op->handle);
   1.325      }
   1.326  
   1.327      /* If just unmapped a writable mapping, mark as dirtied */
   1.328 @@ -455,34 +436,44 @@ static int
   1.329          clear_bit(_GTF_reading, &sha->flags);
   1.330  
   1.331   unmap_out:
   1.332 -    (void)__put_user(rc, &uop->status);
   1.333 +    op->status = rc;
   1.334      spin_unlock(&rd->grant_table->lock);
   1.335      put_domain(rd);
   1.336 -    return rc;
   1.337  }
   1.338  
   1.339  static long
   1.340  gnttab_unmap_grant_ref(
   1.341 -    gnttab_unmap_grant_ref_t *uop, unsigned int count)
   1.342 +    struct gnttab_unmap_grant_ref *uop, unsigned int count)
   1.343  {
   1.344      int i;
   1.345 +    struct gnttab_unmap_grant_ref op;
   1.346  
   1.347      for ( i = 0; i < count; i++ )
   1.348 -        (void)__gnttab_unmap_grant_ref(&uop[i]);
   1.349 +    {
   1.350 +        if ( unlikely(__copy_from_user(&op, &uop[i], sizeof(op))) )
   1.351 +            goto fault;
   1.352 +        __gnttab_unmap_grant_ref(&op);
   1.353 +        if ( unlikely(__copy_to_user(&uop[i], &op, sizeof(op))) )
   1.354 +            goto fault;
   1.355 +    }
   1.356  
   1.357      flush_tlb_mask(current->domain->domain_dirty_cpumask);
   1.358 +    return 0;
   1.359  
   1.360 -    return 0;
   1.361 +fault:
   1.362 +    flush_tlb_mask(current->domain->domain_dirty_cpumask);
   1.363 +    return -EFAULT;    
   1.364  }
   1.365  
   1.366  static long 
   1.367  gnttab_setup_table(
   1.368 -    gnttab_setup_table_t *uop, unsigned int count)
   1.369 +    struct gnttab_setup_table *uop, unsigned int count)
   1.370  {
   1.371 -    gnttab_setup_table_t  op;
   1.372 -    struct domain        *d;
   1.373 -    int                   i;
   1.374 -    unsigned long         gmfn;
   1.375 +    struct gnttab_setup_table op;
   1.376 +    struct domain *d;
   1.377 +    int            i;
   1.378 +    unsigned long  gmfn;
   1.379 +    domid_t        dom;
   1.380  
   1.381      if ( count != 1 )
   1.382          return -EINVAL;
   1.383 @@ -497,122 +488,45 @@ gnttab_setup_table(
   1.384      {
   1.385          DPRINTK("Xen only supports up to %d grant-table frames per domain.\n",
   1.386                  NR_GRANT_FRAMES);
   1.387 -        (void)put_user(GNTST_general_error, &uop->status);
   1.388 -        return 0;
   1.389 +        op.status = GNTST_general_error;
   1.390 +        goto out;
   1.391      }
   1.392  
   1.393 -    if ( op.dom == DOMID_SELF )
   1.394 +    dom = op.dom;
   1.395 +    if ( dom == DOMID_SELF )
   1.396      {
   1.397 -        op.dom = current->domain->domain_id;
   1.398 +        dom = current->domain->domain_id;
   1.399      }
   1.400      else if ( unlikely(!IS_PRIV(current->domain)) )
   1.401      {
   1.402 -        (void)put_user(GNTST_permission_denied, &uop->status);
   1.403 -        return 0;
   1.404 +        op.status = GNTST_permission_denied;
   1.405 +        goto out;
   1.406      }
   1.407  
   1.408 -    if ( unlikely((d = find_domain_by_id(op.dom)) == NULL) )
   1.409 +    if ( unlikely((d = find_domain_by_id(dom)) == NULL) )
   1.410      {
   1.411 -        DPRINTK("Bad domid %d.\n", op.dom);
   1.412 -        (void)put_user(GNTST_bad_domain, &uop->status);
   1.413 -        return 0;
   1.414 +        DPRINTK("Bad domid %d.\n", dom);
   1.415 +        op.status = GNTST_bad_domain;
   1.416 +        goto out;
   1.417      }
   1.418  
   1.419      if ( op.nr_frames <= NR_GRANT_FRAMES )
   1.420      {
   1.421          ASSERT(d->grant_table != NULL);
   1.422 -        (void)put_user(GNTST_okay, &uop->status);
   1.423 +        op.status = GNTST_okay;
   1.424          for ( i = 0; i < op.nr_frames; i++ )
   1.425          {
   1.426              gmfn = gnttab_shared_gmfn(d, d->grant_table, i);
   1.427 -            (void)put_user(gmfn, &op.frame_list[i]);
   1.428 +            (void)copy_to_user(&op.frame_list[i], &gmfn, sizeof(gmfn));
   1.429          }
   1.430      }
   1.431  
   1.432      put_domain(d);
   1.433 -    return 0;
   1.434 -}
   1.435 -
   1.436 -static int
   1.437 -gnttab_dump_table(
   1.438 -    gnttab_dump_table_t *uop)
   1.439 -{
   1.440 -    grant_table_t        *gt;
   1.441 -    gnttab_dump_table_t   op;
   1.442 -    struct domain        *d;
   1.443 -    u32                   shared_mfn;
   1.444 -    active_grant_entry_t *act;
   1.445 -    grant_entry_t         sha_copy;
   1.446 -    grant_mapping_t      *maptrack;
   1.447 -    int                   i;
   1.448 -
   1.449 -    if ( !IS_PRIV(current->domain) )
   1.450 -        return -EPERM;
   1.451 -
   1.452 -    if ( unlikely(copy_from_user(&op, uop, sizeof(op)) != 0) )
   1.453 -    {
   1.454 -        DPRINTK("Fault while reading gnttab_dump_table_t.\n");
   1.455 -        return -EFAULT;
   1.456 -    }
   1.457 -
   1.458 -    if ( op.dom == DOMID_SELF )
   1.459 -        op.dom = current->domain->domain_id;
   1.460 -
   1.461 -    if ( unlikely((d = find_domain_by_id(op.dom)) == NULL) )
   1.462 -    {
   1.463 -        DPRINTK("Bad domid %d.\n", op.dom);
   1.464 -        (void)put_user(GNTST_bad_domain, &uop->status);
   1.465 -        return 0;
   1.466 -    }
   1.467 -
   1.468 -    ASSERT(d->grant_table != NULL);
   1.469 -    gt = d->grant_table;
   1.470 -    (void)put_user(GNTST_okay, &uop->status);
   1.471 -
   1.472 -    shared_mfn = virt_to_maddr(d->grant_table->shared);
   1.473  
   1.474 -    DPRINTK("Grant table for dom (%hu) MFN (%x)\n",
   1.475 -            op.dom, shared_mfn);
   1.476 -
   1.477 -    ASSERT(d->grant_table->active != NULL);
   1.478 -    ASSERT(d->grant_table->shared != NULL);
   1.479 -    ASSERT(d->grant_table->maptrack != NULL);
   1.480 -
   1.481 -    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
   1.482 -    {
   1.483 -        sha_copy = gt->shared[i];
   1.484 -        if ( sha_copy.flags )
   1.485 -            DPRINTK("Grant: dom (%hu) SHARED (%d) flags:(%hx) "
   1.486 -                    "dom:(%hu) frame:(%x)\n",
   1.487 -                    op.dom, i, sha_copy.flags, sha_copy.domid, sha_copy.frame);
   1.488 -    }
   1.489 -
   1.490 -    spin_lock(&gt->lock);
   1.491 + out:
   1.492 +    if ( unlikely(copy_to_user(uop, &op, sizeof(op))) )
   1.493 +        return -EFAULT;
   1.494  
   1.495 -    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
   1.496 -    {
   1.497 -        act = &gt->active[i];
   1.498 -        if ( act->pin )
   1.499 -            DPRINTK("Grant: dom (%hu) ACTIVE (%d) pin:(%x) "
   1.500 -                    "dom:(%hu) frame:(%lx)\n",
   1.501 -                    op.dom, i, act->pin, act->domid, act->frame);
   1.502 -    }
   1.503 -
   1.504 -    for ( i = 0; i < gt->maptrack_limit; i++ )
   1.505 -    {
   1.506 -        maptrack = &gt->maptrack[i];
   1.507 -        if ( maptrack->ref_and_flags & MAPTRACK_GNTMAP_MASK )
   1.508 -            DPRINTK("Grant: dom (%hu) MAP (%d) ref:(%hu) flags:(%x) "
   1.509 -                    "dom:(%hu)\n",
   1.510 -                    op.dom, i,
   1.511 -                    maptrack->ref_and_flags >> MAPTRACK_REF_SHIFT,
   1.512 -                    maptrack->ref_and_flags & MAPTRACK_GNTMAP_MASK,
   1.513 -                    maptrack->domid);
   1.514 -    }
   1.515 -
   1.516 -    spin_unlock(&gt->lock);
   1.517 -
   1.518 -    put_domain(d);
   1.519      return 0;
   1.520  }
   1.521  
   1.522 @@ -694,14 +608,14 @@ gnttab_prepare_for_transfer(
   1.523  
   1.524  static long
   1.525  gnttab_transfer(
   1.526 -    gnttab_transfer_t *uop, unsigned int count)
   1.527 +    struct gnttab_transfer *uop, unsigned int count)
   1.528  {
   1.529      struct domain *d = current->domain;
   1.530      struct domain *e;
   1.531      struct page_info *page;
   1.532      int i;
   1.533      grant_entry_t *sha;
   1.534 -    gnttab_transfer_t gop;
   1.535 +    struct gnttab_transfer gop;
   1.536      unsigned long mfn;
   1.537  
   1.538      for ( i = 0; i < count; i++ )
   1.539 @@ -710,8 +624,7 @@ gnttab_transfer(
   1.540          if ( unlikely(__copy_from_user(&gop, &uop[i], sizeof(gop))) )
   1.541          {
   1.542              DPRINTK("gnttab_transfer: error reading req %d/%d\n", i, count);
   1.543 -            (void)__put_user(GNTST_bad_page, &uop[i].status);
   1.544 -            return -EFAULT; /* This is *very* fatal. */
   1.545 +            return -EFAULT;
   1.546          }
   1.547  
   1.548          /* Check the passed page frame for basic validity. */
   1.549 @@ -719,8 +632,8 @@ gnttab_transfer(
   1.550          { 
   1.551              DPRINTK("gnttab_transfer: out-of-range %lx\n",
   1.552                      (unsigned long)gop.mfn);
   1.553 -            (void)__put_user(GNTST_bad_page, &uop[i].status);
   1.554 -            continue;
   1.555 +            gop.status = GNTST_bad_page;
   1.556 +            goto copyback;
   1.557          }
   1.558  
   1.559          mfn = gmfn_to_mfn(d, gop.mfn);
   1.560 @@ -729,24 +642,24 @@ gnttab_transfer(
   1.561          { 
   1.562              DPRINTK("gnttab_transfer: xen frame %lx\n",
   1.563                      (unsigned long)gop.mfn);
   1.564 -            (void)__put_user(GNTST_bad_page, &uop[i].status);
   1.565 -            continue;
   1.566 +            gop.status = GNTST_bad_page;
   1.567 +            goto copyback;
   1.568          }
   1.569  
   1.570          if ( steal_page_for_grant_transfer(d, page) < 0 )
   1.571          {
   1.572 -            (void)__put_user(GNTST_bad_page, &uop[i].status);
   1.573 -            continue;
   1.574 +            gop.status = GNTST_bad_page;
   1.575 +            goto copyback;
   1.576          }
   1.577  
   1.578          /* Find the target domain. */
   1.579          if ( unlikely((e = find_domain_by_id(gop.domid)) == NULL) )
   1.580          {
   1.581              DPRINTK("gnttab_transfer: can't find domain %d\n", gop.domid);
   1.582 -            (void)__put_user(GNTST_bad_domain, &uop[i].status);
   1.583              page->count_info &= ~(PGC_count_mask|PGC_allocated);
   1.584              free_domheap_page(page);
   1.585 -            continue;
   1.586 +            gop.status = GNTST_bad_domain;
   1.587 +            goto copyback;
   1.588          }
   1.589  
   1.590          spin_lock(&e->page_alloc_lock);
   1.591 @@ -767,10 +680,10 @@ gnttab_transfer(
   1.592                          e->tot_pages, e->max_pages, gop.ref, e->domain_flags);
   1.593              spin_unlock(&e->page_alloc_lock);
   1.594              put_domain(e);
   1.595 -            (void)__put_user(GNTST_general_error, &uop[i].status);
   1.596              page->count_info &= ~(PGC_count_mask|PGC_allocated);
   1.597              free_domheap_page(page);
   1.598 -            continue;
   1.599 +            gop.status = GNTST_general_error;
   1.600 +            goto copyback;
   1.601          }
   1.602  
   1.603          /* Okay, add the page to 'e'. */
   1.604 @@ -792,7 +705,14 @@ gnttab_transfer(
   1.605  
   1.606          put_domain(e);
   1.607  
   1.608 -        (void)__put_user(GNTST_okay, &uop[i].status);
   1.609 +        gop.status = GNTST_okay;
   1.610 +
   1.611 +    copyback:
   1.612 +        if ( unlikely(__copy_from_user(&uop[i], &gop, sizeof(gop))) )
   1.613 +        {
   1.614 +            DPRINTK("gnttab_transfer: error writing resp %d/%d\n", i, count);
   1.615 +            return -EFAULT;
   1.616 +        }
   1.617      }
   1.618  
   1.619      return 0;
   1.620 @@ -831,9 +751,6 @@ do_grant_table_op(
   1.621      case GNTTABOP_setup_table:
   1.622          rc = gnttab_setup_table((gnttab_setup_table_t *)uop, count);
   1.623          break;
   1.624 -    case GNTTABOP_dump_table:
   1.625 -        rc = gnttab_dump_table((gnttab_dump_table_t *)uop);
   1.626 -        break;
   1.627      case GNTTABOP_transfer:
   1.628          if (unlikely(!array_access_ok(
   1.629              uop, count, sizeof(gnttab_transfer_t))))
     2.1 --- a/xen/common/memory.c	Wed Feb 15 14:13:10 2006 +0000
     2.2 +++ b/xen/common/memory.c	Wed Feb 15 15:20:32 2006 +0100
     2.3 @@ -30,7 +30,7 @@ increase_reservation(
     2.4      int           *preempted)
     2.5  {
     2.6      struct page_info *page;
     2.7 -    unsigned long    i;
     2.8 +    unsigned long     i, mfn;
     2.9  
    2.10      if ( (extent_list != NULL) &&
    2.11           !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) )
    2.12 @@ -58,9 +58,12 @@ increase_reservation(
    2.13          }
    2.14  
    2.15          /* Inform the domain of the new page's machine address. */ 
    2.16 -        if ( (extent_list != NULL) &&
    2.17 -             (__put_user(page_to_mfn(page), &extent_list[i]) != 0) )
    2.18 -            return i;
    2.19 +        if ( extent_list != NULL )
    2.20 +        {
    2.21 +            mfn = page_to_mfn(page);
    2.22 +            if ( unlikely(__copy_to_user(&extent_list[i], &mfn, sizeof(mfn))) )
    2.23 +                return i;
    2.24 +        }
    2.25      }
    2.26  
    2.27      return nr_extents;
    2.28 @@ -93,6 +96,9 @@ populate_physmap(
    2.29              goto out;
    2.30          }
    2.31  
    2.32 +        if ( unlikely(__copy_from_user(&gpfn, &extent_list[i], sizeof(gpfn))) )
    2.33 +            goto out;
    2.34 +
    2.35          if ( unlikely((page = alloc_domheap_pages(
    2.36              d, extent_order, flags)) == NULL) )
    2.37          {
    2.38 @@ -104,9 +110,6 @@ populate_physmap(
    2.39  
    2.40          mfn = page_to_mfn(page);
    2.41  
    2.42 -        if ( unlikely(__get_user(gpfn, &extent_list[i]) != 0) )
    2.43 -            goto out;
    2.44 -
    2.45          if ( unlikely(shadow_mode_translate(d)) )
    2.46          {
    2.47              for ( j = 0; j < (1 << extent_order); j++ )
    2.48 @@ -118,7 +121,7 @@ populate_physmap(
    2.49                  set_gpfn_from_mfn(mfn + j, gpfn + j);
    2.50  
    2.51              /* Inform the domain of the new page's machine address. */ 
    2.52 -            if ( __put_user(mfn, &extent_list[i]) != 0 )
    2.53 +            if ( unlikely(__copy_to_user(&extent_list[i], &mfn, sizeof(mfn))) )
    2.54                  goto out;
    2.55          }
    2.56      }
    2.57 @@ -150,7 +153,7 @@ decrease_reservation(
    2.58              return i;
    2.59          }
    2.60  
    2.61 -        if ( unlikely(__get_user(gmfn, &extent_list[i]) != 0) )
    2.62 +        if ( unlikely(__copy_from_user(&gmfn, &extent_list[i], sizeof(gmfn))) )
    2.63              return i;
    2.64  
    2.65          for ( j = 0; j < (1 << extent_order); j++ )
    2.66 @@ -282,7 +285,7 @@ long do_memory_op(int cmd, void *arg)
    2.67  
    2.68      case XENMEM_current_reservation:
    2.69      case XENMEM_maximum_reservation:
    2.70 -        if ( get_user(domid, (domid_t *)arg) )
    2.71 +        if ( copy_from_user(&domid, (domid_t *)arg, sizeof(domid)) )
    2.72              return -EFAULT;
    2.73  
    2.74          if ( likely((domid = (unsigned long)arg) == DOMID_SELF) )
     3.1 --- a/xen/common/multicall.c	Wed Feb 15 14:13:10 2006 +0000
     3.2 +++ b/xen/common/multicall.c	Wed Feb 15 15:20:32 2006 +0100
     3.3 @@ -57,7 +57,9 @@ long do_multicall(struct multicall_entry
     3.4          }
     3.5  #endif
     3.6  
     3.7 -        if ( unlikely(__put_user(mcs->call.result, &call_list[i].result)) )
     3.8 +        if ( unlikely(__copy_to_user(&call_list[i].result,
     3.9 +                                     &mcs->call.result,
    3.10 +                                     sizeof(mcs->call.result))) )
    3.11          {
    3.12              DPRINTK("Error writing result back to multicall block.\n");
    3.13              goto fault;
     4.1 --- a/xen/drivers/char/console.c	Wed Feb 15 14:13:10 2006 +0000
     4.2 +++ b/xen/drivers/char/console.c	Wed Feb 15 15:20:32 2006 +0100
     4.3 @@ -224,14 +224,26 @@ static void putchar_console_ring(int c)
     4.4  long read_console_ring(char **pstr, u32 *pcount, int clear)
     4.5  {
     4.6      char *str = *pstr;
     4.7 -    u32 count = *pcount;
     4.8 -    unsigned int p, q;
     4.9 +    unsigned int idx, len, max, sofar, c;
    4.10      unsigned long flags;
    4.11  
    4.12 -    /* Start of buffer may get overwritten during copy. So copy backwards. */
    4.13 -    for ( p = conringp, q = count; (p > conringc) && (q > 0); p--, q-- )
    4.14 -        if ( put_user(conring[CONRING_IDX_MASK(p-1)], (char *)str+q-1) )
    4.15 +    max   = *pcount;
    4.16 +    sofar = 0;
    4.17 +
    4.18 +    c = conringc;
    4.19 +    while ( c != conringp )
    4.20 +    {
    4.21 +        idx = CONRING_IDX_MASK(c);
    4.22 +        len = conringp - c;
    4.23 +        if ( (idx + len) > CONRING_SIZE )
    4.24 +            len = CONRING_SIZE - idx;
    4.25 +        if ( (sofar + len) > max )
    4.26 +            len = max - sofar;
    4.27 +        if ( copy_to_user(str + sofar, &conring[idx], len) )
    4.28              return -EFAULT;
    4.29 +        sofar += len;
    4.30 +        c += len;
    4.31 +    }
    4.32  
    4.33      if ( clear )
    4.34      {
    4.35 @@ -240,8 +252,7 @@ long read_console_ring(char **pstr, u32 
    4.36          spin_unlock_irqrestore(&console_lock, flags);
    4.37      }
    4.38  
    4.39 -    *pstr   = str + q;
    4.40 -    *pcount = count - q;
    4.41 +    *pcount = sofar;
    4.42      return 0;
    4.43  }
    4.44  
    4.45 @@ -347,6 +358,7 @@ long guest_console_write(char *buffer, i
    4.46  long do_console_io(int cmd, int count, char *buffer)
    4.47  {
    4.48      long rc;
    4.49 +    unsigned int idx, len;
    4.50  
    4.51  #ifndef VERBOSE
    4.52      /* Only domain 0 may access the emergency console. */
    4.53 @@ -363,14 +375,19 @@ long do_console_io(int cmd, int count, c
    4.54          rc = 0;
    4.55          while ( (serial_rx_cons != serial_rx_prod) && (rc < count) )
    4.56          {
    4.57 -            if ( put_user(serial_rx_ring[SERIAL_RX_MASK(serial_rx_cons)],
    4.58 -                          &buffer[rc]) )
    4.59 +            idx = SERIAL_RX_MASK(serial_rx_cons);
    4.60 +            len = serial_rx_prod - serial_rx_cons;
    4.61 +            if ( (idx + len) > SERIAL_RX_SIZE )
    4.62 +                len = SERIAL_RX_SIZE - idx;
    4.63 +            if ( (rc + len) > count )
    4.64 +                len = count - rc;
    4.65 +            if ( copy_to_user(&buffer[rc], &serial_rx_ring[idx], len) )
    4.66              {
    4.67                  rc = -EFAULT;
    4.68                  break;
    4.69              }
    4.70 -            rc++;
    4.71 -            serial_rx_cons++;
    4.72 +            rc += len;
    4.73 +            serial_rx_cons += len;
    4.74          }
    4.75          break;
    4.76      default:
     5.1 --- a/xen/include/public/grant_table.h	Wed Feb 15 14:13:10 2006 +0000
     5.2 +++ b/xen/include/public/grant_table.h	Wed Feb 15 15:20:32 2006 +0100
     5.3 @@ -229,7 +229,7 @@ typedef struct gnttab_dump_table {
     5.4   * to the calling domain *unless* the error is GNTST_bad_page.
     5.5   */
     5.6  #define GNTTABOP_transfer                4
     5.7 -typedef struct {
     5.8 +typedef struct gnttab_transfer {
     5.9      /* IN parameters. */
    5.10      unsigned long mfn;
    5.11      domid_t       domid;