debuggers.hg

changeset 19969:09dbdf12c33d

Eliminate grant_table_op restriction

Eliminate the hard-coded, arbitrarily chosen limit of 512 grant table
ops a domain may submit at a time, and instead check for necessary
preemption after each individual element got processed, invoking the
hypercall continuation logic when necessary.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Jul 13 12:18:04 2009 +0100 (2009-07-13)
parents 0d4406bc5cb7
children c0cb307d927f
files xen/common/compat/grant_table.c xen/common/grant_table.c
line diff
     1.1 --- a/xen/common/compat/grant_table.c	Mon Jul 13 12:17:05 2009 +0100
     1.2 +++ b/xen/common/compat/grant_table.c	Mon Jul 13 12:18:04 2009 +0100
     1.3 @@ -35,7 +35,9 @@ int compat_grant_table_op(unsigned int c
     1.4  {
     1.5      int rc = 0;
     1.6      unsigned int i;
     1.7 +    XEN_GUEST_HANDLE(void) cnt_uop;
     1.8  
     1.9 +    set_xen_guest_handle(cnt_uop, NULL);
    1.10      switch ( cmd )
    1.11      {
    1.12  #define CASE(name) \
    1.13 @@ -79,7 +81,7 @@ int compat_grant_table_op(unsigned int c
    1.14          return do_grant_table_op(cmd, cmp_uop, count);
    1.15      }
    1.16  
    1.17 -    if ( count > 512 )
    1.18 +    if ( (int)count < 0 )
    1.19          rc = -EINVAL;
    1.20  
    1.21      for ( i = 0; i < count && rc == 0; )
    1.22 @@ -128,6 +130,7 @@ int compat_grant_table_op(unsigned int c
    1.23                      rc = gnttab_setup_table(guest_handle_cast(nat.uop, gnttab_setup_table_t), 1);
    1.24                  }
    1.25              }
    1.26 +            ASSERT(rc <= 0);
    1.27              if ( rc == 0 )
    1.28              {
    1.29  #define XLAT_gnttab_setup_table_HNDL_frame_list(_d_, _s_) \
    1.30 @@ -163,12 +166,19 @@ int compat_grant_table_op(unsigned int c
    1.31              }
    1.32              if ( rc == 0 )
    1.33                  rc = gnttab_transfer(guest_handle_cast(nat.uop, gnttab_transfer_t), n);
    1.34 -            if ( rc == 0 )
    1.35 +            if ( rc > 0 )
    1.36 +            {
    1.37 +                ASSERT(rc < n);
    1.38 +                i -= n - rc;
    1.39 +                n = rc;
    1.40 +            }
    1.41 +            if ( rc >= 0 )
    1.42              {
    1.43                  XEN_GUEST_HANDLE(gnttab_transfer_compat_t) xfer;
    1.44  
    1.45                  xfer = guest_handle_cast(cmp_uop, gnttab_transfer_compat_t);
    1.46                  guest_handle_add_offset(xfer, i);
    1.47 +                cnt_uop = guest_handle_cast(xfer, void);
    1.48                  while ( n-- )
    1.49                  {
    1.50                      guest_handle_add_offset(xfer, -1);
    1.51 @@ -201,12 +211,19 @@ int compat_grant_table_op(unsigned int c
    1.52              }
    1.53              if ( rc == 0 )
    1.54                  rc = gnttab_copy(guest_handle_cast(nat.uop, gnttab_copy_t), n);
    1.55 -            if ( rc == 0 )
    1.56 +            if ( rc > 0 )
    1.57 +            {
    1.58 +                ASSERT(rc < n);
    1.59 +                i -= n - rc;
    1.60 +                n = rc;
    1.61 +            }
    1.62 +            if ( rc >= 0 )
    1.63              {
    1.64                  XEN_GUEST_HANDLE(gnttab_copy_compat_t) copy;
    1.65  
    1.66                  copy = guest_handle_cast(cmp_uop, gnttab_copy_compat_t);
    1.67                  guest_handle_add_offset(copy, i);
    1.68 +                cnt_uop = guest_handle_cast(copy, void);
    1.69                  while ( n-- )
    1.70                  {
    1.71                      guest_handle_add_offset(copy, -1);
    1.72 @@ -222,6 +239,14 @@ int compat_grant_table_op(unsigned int c
    1.73          }
    1.74      }
    1.75  
    1.76 +    if ( rc > 0 )
    1.77 +    {
    1.78 +        ASSERT(i < count);
    1.79 +        ASSERT(!guest_handle_is_null(cnt_uop));
    1.80 +        rc = hypercall_create_continuation(__HYPERVISOR_grant_table_op,
    1.81 +                                           "ihi", cmd, cnt_uop, count - i);
    1.82 +    }
    1.83 +
    1.84      return rc;
    1.85  }
    1.86  
     2.1 --- a/xen/common/grant_table.c	Mon Jul 13 12:17:05 2009 +0100
     2.2 +++ b/xen/common/grant_table.c	Mon Jul 13 12:18:04 2009 +0100
     2.3 @@ -29,6 +29,7 @@
     2.4  #include <xen/lib.h>
     2.5  #include <xen/sched.h>
     2.6  #include <xen/mm.h>
     2.7 +#include <xen/event.h>
     2.8  #include <xen/trace.h>
     2.9  #include <xen/guest_access.h>
    2.10  #include <xen/domain_page.h>
    2.11 @@ -465,6 +466,8 @@ gnttab_map_grant_ref(
    2.12  
    2.13      for ( i = 0; i < count; i++ )
    2.14      {
    2.15 +        if (i && hypercall_preempt_check())
    2.16 +            return i;
    2.17          if ( unlikely(__copy_from_guest_offset(&op, uop, i, 1)) )
    2.18              return -EFAULT;
    2.19          __gnttab_map_grant_ref(&op);
    2.20 @@ -722,6 +725,9 @@ gnttab_unmap_grant_ref(
    2.21  
    2.22          count -= c;
    2.23          done += c;
    2.24 +
    2.25 +        if (count && hypercall_preempt_check())
    2.26 +            return done;
    2.27      }
    2.28       
    2.29      return 0;
    2.30 @@ -781,6 +787,9 @@ gnttab_unmap_and_replace(
    2.31  
    2.32          count -= c;
    2.33          done += c;
    2.34 +
    2.35 +        if (count && hypercall_preempt_check())
    2.36 +            return done;
    2.37      }
    2.38  
    2.39      return 0;
    2.40 @@ -1086,6 +1095,9 @@ gnttab_transfer(
    2.41  
    2.42      for ( i = 0; i < count; i++ )
    2.43      {
    2.44 +        if (i && hypercall_preempt_check())
    2.45 +            return i;
    2.46 +
    2.47          /* Read from caller address space. */
    2.48          if ( unlikely(__copy_from_guest_offset(&gop, uop, i, 1)) )
    2.49          {
    2.50 @@ -1478,6 +1490,8 @@ gnttab_copy(
    2.51  
    2.52      for ( i = 0; i < count; i++ )
    2.53      {
    2.54 +        if (i && hypercall_preempt_check())
    2.55 +            return i;
    2.56          if ( unlikely(__copy_from_guest_offset(&op, uop, i, 1)) )
    2.57              return -EFAULT;
    2.58          __gnttab_copy(&op);
    2.59 @@ -1494,7 +1508,7 @@ do_grant_table_op(
    2.60      long rc;
    2.61      struct domain *d = current->domain;
    2.62      
    2.63 -    if ( count > 512 )
    2.64 +    if ( (int)count < 0 )
    2.65          return -EINVAL;
    2.66      
    2.67      domain_lock(d);
    2.68 @@ -1509,6 +1523,11 @@ do_grant_table_op(
    2.69          if ( unlikely(!guest_handle_okay(map, count)) )
    2.70              goto out;
    2.71          rc = gnttab_map_grant_ref(map, count);
    2.72 +        if ( rc > 0 )
    2.73 +        {
    2.74 +            guest_handle_add_offset(map, rc);
    2.75 +            uop = guest_handle_cast(map, void);
    2.76 +        }
    2.77          break;
    2.78      }
    2.79      case GNTTABOP_unmap_grant_ref:
    2.80 @@ -1518,6 +1537,11 @@ do_grant_table_op(
    2.81          if ( unlikely(!guest_handle_okay(unmap, count)) )
    2.82              goto out;
    2.83          rc = gnttab_unmap_grant_ref(unmap, count);
    2.84 +        if ( rc > 0 )
    2.85 +        {
    2.86 +            guest_handle_add_offset(unmap, rc);
    2.87 +            uop = guest_handle_cast(unmap, void);
    2.88 +        }
    2.89          break;
    2.90      }
    2.91      case GNTTABOP_unmap_and_replace:
    2.92 @@ -1530,12 +1554,18 @@ do_grant_table_op(
    2.93          if ( unlikely(!replace_grant_supported()) )
    2.94              goto out;
    2.95          rc = gnttab_unmap_and_replace(unmap, count);
    2.96 +        if ( rc > 0 )
    2.97 +        {
    2.98 +            guest_handle_add_offset(unmap, rc);
    2.99 +            uop = guest_handle_cast(unmap, void);
   2.100 +        }
   2.101          break;
   2.102      }
   2.103      case GNTTABOP_setup_table:
   2.104      {
   2.105          rc = gnttab_setup_table(
   2.106              guest_handle_cast(uop, gnttab_setup_table_t), count);
   2.107 +        ASSERT(rc <= 0);
   2.108          break;
   2.109      }
   2.110      case GNTTABOP_transfer:
   2.111 @@ -1545,6 +1575,11 @@ do_grant_table_op(
   2.112          if ( unlikely(!guest_handle_okay(transfer, count)) )
   2.113              goto out;
   2.114          rc = gnttab_transfer(transfer, count);
   2.115 +        if ( rc > 0 )
   2.116 +        {
   2.117 +            guest_handle_add_offset(transfer, rc);
   2.118 +            uop = guest_handle_cast(transfer, void);
   2.119 +        }
   2.120          break;
   2.121      }
   2.122      case GNTTABOP_copy:
   2.123 @@ -1554,12 +1589,18 @@ do_grant_table_op(
   2.124          if ( unlikely(!guest_handle_okay(copy, count)) )
   2.125              goto out;
   2.126          rc = gnttab_copy(copy, count);
   2.127 +        if ( rc > 0 )
   2.128 +        {
   2.129 +            guest_handle_add_offset(copy, rc);
   2.130 +            uop = guest_handle_cast(copy, void);
   2.131 +        }
   2.132          break;
   2.133      }
   2.134      case GNTTABOP_query_size:
   2.135      {
   2.136          rc = gnttab_query_size(
   2.137              guest_handle_cast(uop, gnttab_query_size_t), count);
   2.138 +        ASSERT(rc <= 0);
   2.139          break;
   2.140      }
   2.141      default:
   2.142 @@ -1569,6 +1610,13 @@ do_grant_table_op(
   2.143      
   2.144    out:
   2.145      domain_unlock(d);
   2.146 +
   2.147 +    if ( rc > 0 )
   2.148 +    {
   2.149 +        ASSERT(rc < count);
   2.150 +        rc = hypercall_create_continuation(__HYPERVISOR_grant_table_op,
   2.151 +                                           "ihi", cmd, uop, count - rc);
   2.152 +    }
   2.153      
   2.154      return rc;
   2.155  }