WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Clean up grant-table code and replace uses of get_user

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Clean up grant-table code and replace uses of get_user
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 15 Feb 2006 16:26:08 +0000
Delivery-date: Wed, 15 Feb 2006 16:39:25 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 1346a69694be920551771d94b1f9382bf885a0a9
# Parent  765b0657264d6c9e4843c30875154e1269a55d4e
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@xxxxxxxxxxxxx>

diff -r 765b0657264d -r 1346a69694be xen/common/grant_table.c
--- a/xen/common/grant_table.c  Wed Feb 15 14:13:10 2006
+++ b/xen/common/grant_table.c  Wed Feb 15 14:20:32 2006
@@ -66,17 +66,13 @@
  * addr is _either_ a host virtual address, or the address of the pte to
  * update, as indicated by the GNTMAP_contains_pte flag.
  */
-static int
+static void
 __gnttab_map_grant_ref(
-    gnttab_map_grant_ref_t *uop)
-{
-    domid_t        dom;
-    grant_ref_t    ref;
+    struct gnttab_map_grant_ref *op)
+{
     struct domain *ld, *rd;
     struct vcpu   *led;
-    u32            dev_hst_ro_flags;
     int            handle;
-    u64            addr;
     unsigned long  frame = 0;
     int            rc = GNTST_okay;
     active_grant_entry_t *act;
@@ -99,39 +95,28 @@
     led = current;
     ld = led->domain;
 
-    /* Bitwise-OR avoids short-circuiting which screws control flow. */
-    if ( unlikely(__get_user(dom, &uop->dom) |
-                  __get_user(ref, &uop->ref) |
-                  __get_user(addr, &uop->host_addr) |
-                  __get_user(dev_hst_ro_flags, &uop->flags)) )
-    {
-        DPRINTK("Fault while reading gnttab_map_grant_ref_t.\n");
-        return -EFAULT; /* don't set status */
-    }
-
-    if ( unlikely(ref >= NR_GRANT_ENTRIES) ||
-         unlikely((dev_hst_ro_flags &
-                   (GNTMAP_device_map|GNTMAP_host_map)) == 0) )
-    {
-        DPRINTK("Bad ref (%d) or flags (%x).\n", ref, dev_hst_ro_flags);
-        (void)__put_user(GNTST_bad_gntref, &uop->status);
-        return GNTST_bad_gntref;
-    }
-
-    if ( acm_pre_grant_map_ref(dom) )
-    {
-        (void)__put_user(GNTST_permission_denied, &uop->status);
-        return GNTST_permission_denied;
-    }
-
-    if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
+    if ( unlikely(op->ref >= NR_GRANT_ENTRIES) ||
+         unlikely((op->flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0) )
+    {
+        DPRINTK("Bad ref (%d) or flags (%x).\n", op->ref, op->flags);
+        op->status = GNTST_bad_gntref;
+        return;
+    }
+
+    if ( acm_pre_grant_map_ref(op->dom) )
+    {
+        op->status = GNTST_permission_denied;
+        return;
+    }
+
+    if ( unlikely((rd = find_domain_by_id(op->dom)) == NULL) ||
          unlikely(ld == rd) )
     {
         if ( rd != NULL )
             put_domain(rd);
-        DPRINTK("Could not find domain %d\n", dom);
-        (void)__put_user(GNTST_bad_domain, &uop->status);
-        return GNTST_bad_domain;
+        DPRINTK("Could not find domain %d\n", op->dom);
+        op->status = GNTST_bad_domain;
+        return;
     }
 
     /* Get a maptrack handle. */
@@ -145,8 +130,8 @@
         {
             put_domain(rd);
             DPRINTK("Maptrack table is at maximum size.\n");
-            (void)__put_user(GNTST_no_device_space, &uop->status);
-            return GNTST_no_device_space;
+            op->status = GNTST_no_device_space;
+            return;
         }
 
         /* Grow the maptrack table. */
@@ -155,8 +140,8 @@
         {
             put_domain(rd);
             DPRINTK("No more map handles available.\n");
-            (void)__put_user(GNTST_no_device_space, &uop->status);
-            return GNTST_no_device_space;
+            op->status = GNTST_no_device_space;
+            return;
         }
 
         memcpy(new_mt, lgt->maptrack, PAGE_SIZE << lgt->maptrack_order);
@@ -172,13 +157,13 @@
         handle = get_maptrack_handle(ld->grant_table);
     }
 
-    act = &rd->grant_table->active[ref];
-    sha = &rd->grant_table->shared[ref];
+    act = &rd->grant_table->active[op->ref];
+    sha = &rd->grant_table->shared[op->ref];
 
     spin_lock(&rd->grant_table->lock);
 
     if ( !act->pin ||
-         (!(dev_hst_ro_flags & GNTMAP_readonly) &&
+         (!(op->flags & GNTMAP_readonly) &&
           !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask))) )
     {
         sflags = sha->flags;
@@ -205,7 +190,7 @@
             prev_scombo = scombo = ((u32)sdom << 16) | (u32)sflags;
 
             new_scombo = scombo | GTF_reading;
-            if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
+            if ( !(op->flags & GNTMAP_readonly) )
             {
                 new_scombo |= GTF_writing;
                 if ( unlikely(sflags & GTF_readonly) )
@@ -244,68 +229,68 @@
         PIN_FAIL(unlock_out, ENOSPC,
                  "Risk of counter overflow %08x\n", act->pin);
 
-    if ( dev_hst_ro_flags & GNTMAP_device_map )
-        act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
+    if ( op->flags & GNTMAP_device_map )
+        act->pin += (op->flags & GNTMAP_readonly) ?
             GNTPIN_devr_inc : GNTPIN_devw_inc;
-    if ( dev_hst_ro_flags & GNTMAP_host_map )
-        act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
+    if ( op->flags & GNTMAP_host_map )
+        act->pin += (op->flags & GNTMAP_readonly) ?
             GNTPIN_hstr_inc : GNTPIN_hstw_inc;
 
     spin_unlock(&rd->grant_table->lock);
 
     frame = act->frame;
     if ( unlikely(!mfn_valid(frame)) ||
-         unlikely(!((dev_hst_ro_flags & GNTMAP_readonly) ?
+         unlikely(!((op->flags & GNTMAP_readonly) ?
                     get_page(mfn_to_page(frame), rd) :
                     get_page_and_type(mfn_to_page(frame), rd,
                                       PGT_writable_page))) )
         PIN_FAIL(undo_out, GNTST_general_error,
                  "Could not pin the granted frame (%lx)!\n", frame);
 
-    if ( dev_hst_ro_flags & GNTMAP_host_map )
-    {
-        rc = create_grant_host_mapping(addr, frame, dev_hst_ro_flags);
+    if ( op->flags & GNTMAP_host_map )
+    {
+        rc = create_grant_host_mapping(op->host_addr, frame, op->flags);
         if ( rc != GNTST_okay )
         {
-            if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
+            if ( !(op->flags & GNTMAP_readonly) )
                 put_page_type(mfn_to_page(frame));
             put_page(mfn_to_page(frame));
             goto undo_out;
         }
 
-        if ( dev_hst_ro_flags & GNTMAP_device_map )
+        if ( op->flags & GNTMAP_device_map )
         {
             (void)get_page(mfn_to_page(frame), rd);
-            if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
+            if ( !(op->flags & GNTMAP_readonly) )
                 get_page_type(mfn_to_page(frame), PGT_writable_page);
         }
     }
 
-    TRACE_1D(TRC_MEM_PAGE_GRANT_MAP, dom);
-
-    ld->grant_table->maptrack[handle].domid         = dom;
+    TRACE_1D(TRC_MEM_PAGE_GRANT_MAP, op->dom);
+
+    ld->grant_table->maptrack[handle].domid         = op->dom;
     ld->grant_table->maptrack[handle].ref_and_flags =
-        (ref << MAPTRACK_REF_SHIFT) |
-        (dev_hst_ro_flags & MAPTRACK_GNTMAP_MASK);
-
-    (void)__put_user((u64)frame << PAGE_SHIFT, &uop->dev_bus_addr);
-    (void)__put_user(handle, &uop->handle);
-    (void)__put_user(GNTST_okay, &uop->status);
+        (op->ref << MAPTRACK_REF_SHIFT) |
+        (op->flags & MAPTRACK_GNTMAP_MASK);
+
+    op->dev_bus_addr = (u64)frame << PAGE_SHIFT;
+    op->handle       = handle;
+    op->status       = GNTST_okay;
 
     put_domain(rd);
-    return rc;
+    return;
 
  undo_out:
     spin_lock(&rd->grant_table->lock);
 
-    if ( dev_hst_ro_flags & GNTMAP_device_map )
-        act->pin -= (dev_hst_ro_flags & GNTMAP_readonly) ?
+    if ( op->flags & GNTMAP_device_map )
+        act->pin -= (op->flags & GNTMAP_readonly) ?
             GNTPIN_devr_inc : GNTPIN_devw_inc;
-    if ( dev_hst_ro_flags & GNTMAP_host_map )
-        act->pin -= (dev_hst_ro_flags & GNTMAP_readonly) ?
+    if ( op->flags & GNTMAP_host_map )
+        act->pin -= (op->flags & GNTMAP_readonly) ?
             GNTPIN_hstr_inc : GNTPIN_hstw_inc;
 
-    if ( !(dev_hst_ro_flags & GNTMAP_readonly) &&
+    if ( !(op->flags & GNTMAP_readonly) &&
          !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
         clear_bit(_GTF_writing, &sha->flags);
 
@@ -314,61 +299,56 @@
 
  unlock_out:
     spin_unlock(&rd->grant_table->lock);
-    (void)__put_user(rc, &uop->status);
+    op->status = rc;
     put_maptrack_handle(ld->grant_table, handle);
     put_domain(rd);
-    return rc;
 }
 
 static long
 gnttab_map_grant_ref(
-    gnttab_map_grant_ref_t *uop, unsigned int count)
+    struct gnttab_map_grant_ref *uop, unsigned int count)
 {
     int i;
+    struct gnttab_map_grant_ref op;
 
     for ( i = 0; i < count; i++ )
-        (void)__gnttab_map_grant_ref(&uop[i]);
+    {
+        if ( unlikely(__copy_from_user(&op, &uop[i], sizeof(op))) )
+            return -EFAULT;
+        __gnttab_map_grant_ref(&op);
+        if ( unlikely(__copy_to_user(&uop[i], &op, sizeof(op))) )
+            return -EFAULT;
+    }
 
     return 0;
 }
 
-static int
+static void
 __gnttab_unmap_grant_ref(
-    gnttab_unmap_grant_ref_t *uop)
+    struct gnttab_unmap_grant_ref *op)
 {
     domid_t          dom;
     grant_ref_t      ref;
-    grant_handle_t   handle;
     struct domain   *ld, *rd;
     active_grant_entry_t *act;
     grant_entry_t   *sha;
     grant_mapping_t *map;
     u16              flags;
     s16              rc = 0;
-    u64              addr, dev_bus_addr;
     unsigned long    frame;
 
     ld = current->domain;
 
-    /* Bitwise-OR avoids short-circuiting which screws control flow. */
-    if ( unlikely(__get_user(addr, &uop->host_addr) |
-                  __get_user(dev_bus_addr, &uop->dev_bus_addr) |
-                  __get_user(handle, &uop->handle)) )
-    {
-        DPRINTK("Fault while reading gnttab_unmap_grant_ref_t.\n");
-        return -EFAULT; /* don't set status */
-    }
-
-    frame = (unsigned long)(dev_bus_addr >> PAGE_SHIFT);
-
-    map = &ld->grant_table->maptrack[handle];
-
-    if ( unlikely(handle >= ld->grant_table->maptrack_limit) ||
+    frame = (unsigned long)(op->dev_bus_addr >> PAGE_SHIFT);
+
+    map = &ld->grant_table->maptrack[op->handle];
+
+    if ( unlikely(op->handle >= ld->grant_table->maptrack_limit) ||
          unlikely(!(map->ref_and_flags & MAPTRACK_GNTMAP_MASK)) )
     {
-        DPRINTK("Bad handle (%d).\n", handle);
-        (void)__put_user(GNTST_bad_handle, &uop->status);
-        return GNTST_bad_handle;
+        DPRINTK("Bad handle (%d).\n", op->handle);
+        op->status = GNTST_bad_handle;
+        return;
     }
 
     dom   = map->domid;
@@ -381,8 +361,8 @@
         if ( rd != NULL )
             put_domain(rd);
         DPRINTK("Could not find domain %d\n", dom);
-        (void)__put_user(GNTST_bad_domain, &uop->status);
-        return GNTST_bad_domain;
+        op->status = GNTST_bad_domain;
+        return;
     }
 
     TRACE_1D(TRC_MEM_PAGE_GRANT_UNMAP, dom);
@@ -418,9 +398,10 @@
         }
     }
 
-    if ( (addr != 0) && (flags & GNTMAP_host_map) )
-    {
-        if ( (rc = destroy_grant_host_mapping(addr, frame, flags)) < 0 )
+    if ( (op->host_addr != 0) && (flags & GNTMAP_host_map) )
+    {
+        if ( (rc = destroy_grant_host_mapping(op->host_addr,
+                                              frame, flags)) < 0 )
             goto unmap_out;
 
         ASSERT(act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask));
@@ -440,7 +421,7 @@
     if ( (map->ref_and_flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0 )
     {
         map->ref_and_flags = 0;
-        put_maptrack_handle(ld->grant_table, handle);
+        put_maptrack_handle(ld->grant_table, op->handle);
     }
 
     /* If just unmapped a writable mapping, mark as dirtied */
@@ -455,34 +436,44 @@
         clear_bit(_GTF_reading, &sha->flags);
 
  unmap_out:
-    (void)__put_user(rc, &uop->status);
+    op->status = rc;
     spin_unlock(&rd->grant_table->lock);
     put_domain(rd);
-    return rc;
 }
 
 static long
 gnttab_unmap_grant_ref(
-    gnttab_unmap_grant_ref_t *uop, unsigned int count)
+    struct gnttab_unmap_grant_ref *uop, unsigned int count)
 {
     int i;
+    struct gnttab_unmap_grant_ref op;
 
     for ( i = 0; i < count; i++ )
-        (void)__gnttab_unmap_grant_ref(&uop[i]);
+    {
+        if ( unlikely(__copy_from_user(&op, &uop[i], sizeof(op))) )
+            goto fault;
+        __gnttab_unmap_grant_ref(&op);
+        if ( unlikely(__copy_to_user(&uop[i], &op, sizeof(op))) )
+            goto fault;
+    }
 
     flush_tlb_mask(current->domain->domain_dirty_cpumask);
-
     return 0;
+
+fault:
+    flush_tlb_mask(current->domain->domain_dirty_cpumask);
+    return -EFAULT;    
 }
 
 static long 
 gnttab_setup_table(
-    gnttab_setup_table_t *uop, unsigned int count)
-{
-    gnttab_setup_table_t  op;
-    struct domain        *d;
-    int                   i;
-    unsigned long         gmfn;
+    struct gnttab_setup_table *uop, unsigned int count)
+{
+    struct gnttab_setup_table op;
+    struct domain *d;
+    int            i;
+    unsigned long  gmfn;
+    domid_t        dom;
 
     if ( count != 1 )
         return -EINVAL;
@@ -497,122 +488,45 @@
     {
         DPRINTK("Xen only supports up to %d grant-table frames per domain.\n",
                 NR_GRANT_FRAMES);
-        (void)put_user(GNTST_general_error, &uop->status);
-        return 0;
-    }
-
-    if ( op.dom == DOMID_SELF )
-    {
-        op.dom = current->domain->domain_id;
+        op.status = GNTST_general_error;
+        goto out;
+    }
+
+    dom = op.dom;
+    if ( dom == DOMID_SELF )
+    {
+        dom = current->domain->domain_id;
     }
     else if ( unlikely(!IS_PRIV(current->domain)) )
     {
-        (void)put_user(GNTST_permission_denied, &uop->status);
-        return 0;
-    }
-
-    if ( unlikely((d = find_domain_by_id(op.dom)) == NULL) )
-    {
-        DPRINTK("Bad domid %d.\n", op.dom);
-        (void)put_user(GNTST_bad_domain, &uop->status);
-        return 0;
+        op.status = GNTST_permission_denied;
+        goto out;
+    }
+
+    if ( unlikely((d = find_domain_by_id(dom)) == NULL) )
+    {
+        DPRINTK("Bad domid %d.\n", dom);
+        op.status = GNTST_bad_domain;
+        goto out;
     }
 
     if ( op.nr_frames <= NR_GRANT_FRAMES )
     {
         ASSERT(d->grant_table != NULL);
-        (void)put_user(GNTST_okay, &uop->status);
+        op.status = GNTST_okay;
         for ( i = 0; i < op.nr_frames; i++ )
         {
             gmfn = gnttab_shared_gmfn(d, d->grant_table, i);
-            (void)put_user(gmfn, &op.frame_list[i]);
+            (void)copy_to_user(&op.frame_list[i], &gmfn, sizeof(gmfn));
         }
     }
 
     put_domain(d);
-    return 0;
-}
-
-static int
-gnttab_dump_table(
-    gnttab_dump_table_t *uop)
-{
-    grant_table_t        *gt;
-    gnttab_dump_table_t   op;
-    struct domain        *d;
-    u32                   shared_mfn;
-    active_grant_entry_t *act;
-    grant_entry_t         sha_copy;
-    grant_mapping_t      *maptrack;
-    int                   i;
-
-    if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
-    if ( unlikely(copy_from_user(&op, uop, sizeof(op)) != 0) )
-    {
-        DPRINTK("Fault while reading gnttab_dump_table_t.\n");
+
+ out:
+    if ( unlikely(copy_to_user(uop, &op, sizeof(op))) )
         return -EFAULT;
-    }
-
-    if ( op.dom == DOMID_SELF )
-        op.dom = current->domain->domain_id;
-
-    if ( unlikely((d = find_domain_by_id(op.dom)) == NULL) )
-    {
-        DPRINTK("Bad domid %d.\n", op.dom);
-        (void)put_user(GNTST_bad_domain, &uop->status);
-        return 0;
-    }
-
-    ASSERT(d->grant_table != NULL);
-    gt = d->grant_table;
-    (void)put_user(GNTST_okay, &uop->status);
-
-    shared_mfn = virt_to_maddr(d->grant_table->shared);
-
-    DPRINTK("Grant table for dom (%hu) MFN (%x)\n",
-            op.dom, shared_mfn);
-
-    ASSERT(d->grant_table->active != NULL);
-    ASSERT(d->grant_table->shared != NULL);
-    ASSERT(d->grant_table->maptrack != NULL);
-
-    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
-    {
-        sha_copy = gt->shared[i];
-        if ( sha_copy.flags )
-            DPRINTK("Grant: dom (%hu) SHARED (%d) flags:(%hx) "
-                    "dom:(%hu) frame:(%x)\n",
-                    op.dom, i, sha_copy.flags, sha_copy.domid, sha_copy.frame);
-    }
-
-    spin_lock(&gt->lock);
-
-    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
-    {
-        act = &gt->active[i];
-        if ( act->pin )
-            DPRINTK("Grant: dom (%hu) ACTIVE (%d) pin:(%x) "
-                    "dom:(%hu) frame:(%lx)\n",
-                    op.dom, i, act->pin, act->domid, act->frame);
-    }
-
-    for ( i = 0; i < gt->maptrack_limit; i++ )
-    {
-        maptrack = &gt->maptrack[i];
-        if ( maptrack->ref_and_flags & MAPTRACK_GNTMAP_MASK )
-            DPRINTK("Grant: dom (%hu) MAP (%d) ref:(%hu) flags:(%x) "
-                    "dom:(%hu)\n",
-                    op.dom, i,
-                    maptrack->ref_and_flags >> MAPTRACK_REF_SHIFT,
-                    maptrack->ref_and_flags & MAPTRACK_GNTMAP_MASK,
-                    maptrack->domid);
-    }
-
-    spin_unlock(&gt->lock);
-
-    put_domain(d);
+
     return 0;
 }
 
@@ -694,14 +608,14 @@
 
 static long
 gnttab_transfer(
-    gnttab_transfer_t *uop, unsigned int count)
+    struct gnttab_transfer *uop, unsigned int count)
 {
     struct domain *d = current->domain;
     struct domain *e;
     struct page_info *page;
     int i;
     grant_entry_t *sha;
-    gnttab_transfer_t gop;
+    struct gnttab_transfer gop;
     unsigned long mfn;
 
     for ( i = 0; i < count; i++ )
@@ -710,8 +624,7 @@
         if ( unlikely(__copy_from_user(&gop, &uop[i], sizeof(gop))) )
         {
             DPRINTK("gnttab_transfer: error reading req %d/%d\n", i, count);
-            (void)__put_user(GNTST_bad_page, &uop[i].status);
-            return -EFAULT; /* This is *very* fatal. */
+            return -EFAULT;
         }
 
         /* Check the passed page frame for basic validity. */
@@ -719,8 +632,8 @@
         { 
             DPRINTK("gnttab_transfer: out-of-range %lx\n",
                     (unsigned long)gop.mfn);
-            (void)__put_user(GNTST_bad_page, &uop[i].status);
-            continue;
+            gop.status = GNTST_bad_page;
+            goto copyback;
         }
 
         mfn = gmfn_to_mfn(d, gop.mfn);
@@ -729,24 +642,24 @@
         { 
             DPRINTK("gnttab_transfer: xen frame %lx\n",
                     (unsigned long)gop.mfn);
-            (void)__put_user(GNTST_bad_page, &uop[i].status);
-            continue;
+            gop.status = GNTST_bad_page;
+            goto copyback;
         }
 
         if ( steal_page_for_grant_transfer(d, page) < 0 )
         {
-            (void)__put_user(GNTST_bad_page, &uop[i].status);
-            continue;
+            gop.status = GNTST_bad_page;
+            goto copyback;
         }
 
         /* Find the target domain. */
         if ( unlikely((e = find_domain_by_id(gop.domid)) == NULL) )
         {
             DPRINTK("gnttab_transfer: can't find domain %d\n", gop.domid);
-            (void)__put_user(GNTST_bad_domain, &uop[i].status);
             page->count_info &= ~(PGC_count_mask|PGC_allocated);
             free_domheap_page(page);
-            continue;
+            gop.status = GNTST_bad_domain;
+            goto copyback;
         }
 
         spin_lock(&e->page_alloc_lock);
@@ -767,10 +680,10 @@
                         e->tot_pages, e->max_pages, gop.ref, e->domain_flags);
             spin_unlock(&e->page_alloc_lock);
             put_domain(e);
-            (void)__put_user(GNTST_general_error, &uop[i].status);
             page->count_info &= ~(PGC_count_mask|PGC_allocated);
             free_domheap_page(page);
-            continue;
+            gop.status = GNTST_general_error;
+            goto copyback;
         }
 
         /* Okay, add the page to 'e'. */
@@ -792,7 +705,14 @@
 
         put_domain(e);
 
-        (void)__put_user(GNTST_okay, &uop[i].status);
+        gop.status = GNTST_okay;
+
+    copyback:
+        if ( unlikely(__copy_from_user(&uop[i], &gop, sizeof(gop))) )
+        {
+            DPRINTK("gnttab_transfer: error writing resp %d/%d\n", i, count);
+            return -EFAULT;
+        }
     }
 
     return 0;
@@ -831,9 +751,6 @@
     case GNTTABOP_setup_table:
         rc = gnttab_setup_table((gnttab_setup_table_t *)uop, count);
         break;
-    case GNTTABOP_dump_table:
-        rc = gnttab_dump_table((gnttab_dump_table_t *)uop);
-        break;
     case GNTTABOP_transfer:
         if (unlikely(!array_access_ok(
             uop, count, sizeof(gnttab_transfer_t))))
diff -r 765b0657264d -r 1346a69694be xen/common/memory.c
--- a/xen/common/memory.c       Wed Feb 15 14:13:10 2006
+++ b/xen/common/memory.c       Wed Feb 15 14:20:32 2006
@@ -30,7 +30,7 @@
     int           *preempted)
 {
     struct page_info *page;
-    unsigned long    i;
+    unsigned long     i, mfn;
 
     if ( (extent_list != NULL) &&
          !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) )
@@ -58,9 +58,12 @@
         }
 
         /* Inform the domain of the new page's machine address. */ 
-        if ( (extent_list != NULL) &&
-             (__put_user(page_to_mfn(page), &extent_list[i]) != 0) )
-            return i;
+        if ( extent_list != NULL )
+        {
+            mfn = page_to_mfn(page);
+            if ( unlikely(__copy_to_user(&extent_list[i], &mfn, sizeof(mfn))) )
+                return i;
+        }
     }
 
     return nr_extents;
@@ -93,6 +96,9 @@
             goto out;
         }
 
+        if ( unlikely(__copy_from_user(&gpfn, &extent_list[i], sizeof(gpfn))) )
+            goto out;
+
         if ( unlikely((page = alloc_domheap_pages(
             d, extent_order, flags)) == NULL) )
         {
@@ -104,9 +110,6 @@
 
         mfn = page_to_mfn(page);
 
-        if ( unlikely(__get_user(gpfn, &extent_list[i]) != 0) )
-            goto out;
-
         if ( unlikely(shadow_mode_translate(d)) )
         {
             for ( j = 0; j < (1 << extent_order); j++ )
@@ -118,7 +121,7 @@
                 set_gpfn_from_mfn(mfn + j, gpfn + j);
 
             /* Inform the domain of the new page's machine address. */ 
-            if ( __put_user(mfn, &extent_list[i]) != 0 )
+            if ( unlikely(__copy_to_user(&extent_list[i], &mfn, sizeof(mfn))) )
                 goto out;
         }
     }
@@ -150,7 +153,7 @@
             return i;
         }
 
-        if ( unlikely(__get_user(gmfn, &extent_list[i]) != 0) )
+        if ( unlikely(__copy_from_user(&gmfn, &extent_list[i], sizeof(gmfn))) )
             return i;
 
         for ( j = 0; j < (1 << extent_order); j++ )
@@ -282,7 +285,7 @@
 
     case XENMEM_current_reservation:
     case XENMEM_maximum_reservation:
-        if ( get_user(domid, (domid_t *)arg) )
+        if ( copy_from_user(&domid, (domid_t *)arg, sizeof(domid)) )
             return -EFAULT;
 
         if ( likely((domid = (unsigned long)arg) == DOMID_SELF) )
diff -r 765b0657264d -r 1346a69694be xen/common/multicall.c
--- a/xen/common/multicall.c    Wed Feb 15 14:13:10 2006
+++ b/xen/common/multicall.c    Wed Feb 15 14:20:32 2006
@@ -57,7 +57,9 @@
         }
 #endif
 
-        if ( unlikely(__put_user(mcs->call.result, &call_list[i].result)) )
+        if ( unlikely(__copy_to_user(&call_list[i].result,
+                                     &mcs->call.result,
+                                     sizeof(mcs->call.result))) )
         {
             DPRINTK("Error writing result back to multicall block.\n");
             goto fault;
diff -r 765b0657264d -r 1346a69694be xen/drivers/char/console.c
--- a/xen/drivers/char/console.c        Wed Feb 15 14:13:10 2006
+++ b/xen/drivers/char/console.c        Wed Feb 15 14:20:32 2006
@@ -224,14 +224,26 @@
 long read_console_ring(char **pstr, u32 *pcount, int clear)
 {
     char *str = *pstr;
-    u32 count = *pcount;
-    unsigned int p, q;
+    unsigned int idx, len, max, sofar, c;
     unsigned long flags;
 
-    /* Start of buffer may get overwritten during copy. So copy backwards. */
-    for ( p = conringp, q = count; (p > conringc) && (q > 0); p--, q-- )
-        if ( put_user(conring[CONRING_IDX_MASK(p-1)], (char *)str+q-1) )
+    max   = *pcount;
+    sofar = 0;
+
+    c = conringc;
+    while ( c != conringp )
+    {
+        idx = CONRING_IDX_MASK(c);
+        len = conringp - c;
+        if ( (idx + len) > CONRING_SIZE )
+            len = CONRING_SIZE - idx;
+        if ( (sofar + len) > max )
+            len = max - sofar;
+        if ( copy_to_user(str + sofar, &conring[idx], len) )
             return -EFAULT;
+        sofar += len;
+        c += len;
+    }
 
     if ( clear )
     {
@@ -240,8 +252,7 @@
         spin_unlock_irqrestore(&console_lock, flags);
     }
 
-    *pstr   = str + q;
-    *pcount = count - q;
+    *pcount = sofar;
     return 0;
 }
 
@@ -347,6 +358,7 @@
 long do_console_io(int cmd, int count, char *buffer)
 {
     long rc;
+    unsigned int idx, len;
 
 #ifndef VERBOSE
     /* Only domain 0 may access the emergency console. */
@@ -363,14 +375,19 @@
         rc = 0;
         while ( (serial_rx_cons != serial_rx_prod) && (rc < count) )
         {
-            if ( put_user(serial_rx_ring[SERIAL_RX_MASK(serial_rx_cons)],
-                          &buffer[rc]) )
+            idx = SERIAL_RX_MASK(serial_rx_cons);
+            len = serial_rx_prod - serial_rx_cons;
+            if ( (idx + len) > SERIAL_RX_SIZE )
+                len = SERIAL_RX_SIZE - idx;
+            if ( (rc + len) > count )
+                len = count - rc;
+            if ( copy_to_user(&buffer[rc], &serial_rx_ring[idx], len) )
             {
                 rc = -EFAULT;
                 break;
             }
-            rc++;
-            serial_rx_cons++;
+            rc += len;
+            serial_rx_cons += len;
         }
         break;
     default:
diff -r 765b0657264d -r 1346a69694be xen/include/public/grant_table.h
--- a/xen/include/public/grant_table.h  Wed Feb 15 14:13:10 2006
+++ b/xen/include/public/grant_table.h  Wed Feb 15 14:20:32 2006
@@ -229,7 +229,7 @@
  * to the calling domain *unless* the error is GNTST_bad_page.
  */
 #define GNTTABOP_transfer                4
-typedef struct {
+typedef struct gnttab_transfer {
     /* IN parameters. */
     unsigned long mfn;
     domid_t       domid;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Clean up grant-table code and replace uses of get_user, Xen patchbot -unstable <=