ia64/xen-unstable

changeset 3149:aacdccdb52e5

bitkeeper revision 1.1159.187.17 (41a63c69lFw9w4Qh2aZDluR-6MdrkQ)

More hypercall preemption fixes. do_mmu_update() now correctly remembers the
foreigndom across preempt/resume.
author kaf24@scramble.cl.cam.ac.uk
date Thu Nov 25 20:11:21 2004 +0000 (2004-11-25)
parents 0d7e310db68e
children 49296e6964d4 1a221a308fe5
files xen/arch/x86/domain.c xen/arch/x86/memory.c xen/arch/x86/traps.c xen/common/dom_mem_ops.c xen/common/multicall.c xen/include/xen/sched.h
line diff
     1.1 --- a/xen/arch/x86/domain.c	Thu Nov 25 17:45:40 2004 +0000
     1.2 +++ b/xen/arch/x86/domain.c	Thu Nov 25 20:11:21 2004 +0000
     1.3 @@ -427,7 +427,8 @@ long do_iopl(domid_t domain, unsigned in
     1.4      return 0;
     1.5  }
     1.6  
     1.7 -void hypercall_create_continuation(unsigned int op, unsigned int nr_args, ...)
     1.8 +unsigned long hypercall_create_continuation(
     1.9 +    unsigned int op, unsigned int nr_args, ...)
    1.10  {
    1.11      struct mc_state *mcs = &mc_state[smp_processor_id()];
    1.12      execution_context_t *ec;
    1.13 @@ -455,6 +456,8 @@ void hypercall_create_continuation(unsig
    1.14      }
    1.15  
    1.16      va_end(args);
    1.17 +
    1.18 +    return op;
    1.19  }
    1.20  
    1.21  #endif
     2.1 --- a/xen/arch/x86/memory.c	Thu Nov 25 17:45:40 2004 +0000
     2.2 +++ b/xen/arch/x86/memory.c	Thu Nov 25 20:11:21 2004 +0000
     2.3 @@ -126,10 +126,9 @@ static int mod_l1_entry(l1_pgentry_t *, 
     2.4  static struct {
     2.5  #define DOP_FLUSH_TLB   (1<<0) /* Flush the TLB.                 */
     2.6  #define DOP_RELOAD_LDT  (1<<1) /* Reload the LDT shadow mapping. */
     2.7 -    unsigned long       deferred_ops;
     2.8 -    unsigned long       cr0;
     2.9 +    unsigned long  deferred_ops;
    2.10      /* If non-NULL, specifies a foreign subject domain for some operations. */
    2.11 -    struct domain      *foreign;
    2.12 +    struct domain *foreign;
    2.13  } __cacheline_aligned percpu_info[NR_CPUS];
    2.14  
    2.15  /*
    2.16 @@ -1283,18 +1282,22 @@ int do_mmu_update(
    2.17  /*
    2.18   * We steal the m.s.b. of the @count parameter to indicate whether this
    2.19   * invocation of do_mmu_update() is resuming a previously preempted call.
    2.20 + * We steal the next 15 bits to remember the current FOREIGNDOM.
    2.21   */
    2.22 -#define MMU_UPDATE_PREEMPTED  (~(~0U>>1))
    2.23 +#define MMU_UPDATE_PREEMPTED          (~(~0U>>1))
    2.24 +#define MMU_UPDATE_PREEMPT_FDOM_SHIFT ((sizeof(int)*8)-16)
    2.25 +#define MMU_UPDATE_PREEMPT_FDOM_MASK  (0x7FFFU<<MMU_UPDATE_PREEMPT_FDOM_SHIFT)
    2.26  
    2.27      mmu_update_t req;
    2.28      unsigned long va = 0, deferred_ops, pfn, prev_pfn = 0;
    2.29      struct pfn_info *page;
    2.30 -    int rc = 0, okay = 1, i, cpu = smp_processor_id();
    2.31 +    int rc = 0, okay = 1, i = 0, cpu = smp_processor_id();
    2.32      unsigned int cmd, done = 0;
    2.33      unsigned long prev_spfn = 0;
    2.34      l1_pgentry_t *prev_spl1e = 0;
    2.35      struct domain *d = current;
    2.36      u32 type_info;
    2.37 +    domid_t domid;
    2.38  
    2.39      perfc_incrc(calls_to_mmu_update); 
    2.40      perfc_addc(num_page_updates, count);
    2.41 @@ -1304,25 +1307,45 @@ int do_mmu_update(
    2.42      /*
    2.43       * If we are resuming after preemption, read how much work we have already
    2.44       * done. This allows us to set the @done output parameter correctly.
    2.45 +     * We also reset FOREIGNDOM here.
    2.46       */
    2.47 -    if ( unlikely(count & MMU_UPDATE_PREEMPTED) )
    2.48 +    if ( unlikely(count&(MMU_UPDATE_PREEMPTED|MMU_UPDATE_PREEMPT_FDOM_MASK)) )
    2.49      {
    2.50 +        if ( !(count & MMU_UPDATE_PREEMPTED) )
    2.51 +        {
    2.52 +            /* Count overflow into private FOREIGNDOM field. */
    2.53 +            MEM_LOG("do_mmu_update count is too large");
    2.54 +            rc = -EINVAL;
    2.55 +            goto out;
    2.56 +        }
    2.57          count &= ~MMU_UPDATE_PREEMPTED;
    2.58 +        domid = count >> MMU_UPDATE_PREEMPT_FDOM_SHIFT;
    2.59 +        count &= ~MMU_UPDATE_PREEMPT_FDOM_MASK;
    2.60          if ( unlikely(pdone != NULL) )
    2.61              (void)get_user(done, pdone);
    2.62 +        if ( (domid != current->id) &&
    2.63 +             !do_extended_command(0, MMUEXT_SET_FOREIGNDOM | (domid << 16)) )
    2.64 +        {
    2.65 +            rc = -EINVAL;
    2.66 +            goto out;
    2.67 +        }
    2.68      }
    2.69  
    2.70      if ( unlikely(!array_access_ok(VERIFY_READ, ureqs, count, sizeof(req))) )
    2.71 -        return -EFAULT;
    2.72 +    {
    2.73 +        rc = -EFAULT;
    2.74 +        goto out;
    2.75 +    }
    2.76  
    2.77      for ( i = 0; i < count; i++ )
    2.78      {
    2.79          if ( hypercall_preempt_check() )
    2.80          {
    2.81 -            hypercall_create_continuation(
    2.82 +            rc = hypercall_create_continuation(
    2.83                  __HYPERVISOR_mmu_update, 3, ureqs, 
    2.84 -                (count - i) | MMU_UPDATE_PREEMPTED, pdone);
    2.85 -            rc = __HYPERVISOR_mmu_update;
    2.86 +                (count - i) |
    2.87 +                (FOREIGNDOM->id << MMU_UPDATE_PREEMPT_FDOM_SHIFT) | 
    2.88 +                MMU_UPDATE_PREEMPTED, pdone);
    2.89              break;
    2.90          }
    2.91  
    2.92 @@ -1459,6 +1482,7 @@ int do_mmu_update(
    2.93          ureqs++;
    2.94      }
    2.95  
    2.96 + out:
    2.97      if ( prev_pfn != 0 )
    2.98          unmap_domain_mem((void *)va);
    2.99  
     3.1 --- a/xen/arch/x86/traps.c	Thu Nov 25 17:45:40 2004 +0000
     3.2 +++ b/xen/arch/x86/traps.c	Thu Nov 25 20:11:21 2004 +0000
     3.3 @@ -805,11 +805,8 @@ long do_set_trap_table(trap_info_t *trap
     3.4      for ( ; ; )
     3.5      {
     3.6          if ( hypercall_preempt_check() )
     3.7 -        {
     3.8 -            hypercall_create_continuation(
     3.9 +            return hypercall_create_continuation(
    3.10                  __HYPERVISOR_set_trap_table, 1, traps);
    3.11 -            return __HYPERVISOR_set_trap_table;
    3.12 -        }
    3.13  
    3.14          if ( copy_from_user(&cur, traps, sizeof(cur)) ) return -EFAULT;
    3.15  
     4.1 --- a/xen/common/dom_mem_ops.c	Thu Nov 25 17:45:40 2004 +0000
     4.2 +++ b/xen/common/dom_mem_ops.c	Thu Nov 25 20:11:21 2004 +0000
     4.3 @@ -23,14 +23,12 @@
     4.4  #define START_EXTENT_SHIFT 4 /* op[:4] == start_extent */
     4.5  
     4.6  #define PREEMPT_CHECK(_op)                          \
     4.7 -    if ( hypercall_preempt_check() ) {              \
     4.8 -        hypercall_create_continuation(              \
     4.9 +    if ( hypercall_preempt_check() )                \
    4.10 +        return hypercall_create_continuation(       \
    4.11              __HYPERVISOR_dom_mem_op, 5,             \
    4.12              (_op) | (i << START_EXTENT_SHIFT),      \
    4.13              extent_list, nr_extents, extent_order,  \
    4.14 -            (d == current) ? DOMID_SELF : d->id);   \
    4.15 -        return __HYPERVISOR_dom_mem_op;             \
    4.16 -    }
    4.17 +            (d == current) ? DOMID_SELF : d->id)
    4.18  
    4.19  static long
    4.20  alloc_dom_mem(struct domain *d, 
     5.1 --- a/xen/common/multicall.c	Thu Nov 25 17:45:40 2004 +0000
     5.2 +++ b/xen/common/multicall.c	Thu Nov 25 20:11:21 2004 +0000
     5.3 @@ -60,9 +60,8 @@ long do_multicall(multicall_entry_t *cal
     5.4              if ( i < nr_calls )
     5.5              {
     5.6                  mcs->flags = 0;
     5.7 -                hypercall_create_continuation(
     5.8 +                return hypercall_create_continuation(
     5.9                      __HYPERVISOR_multicall, 2, &call_list[i], nr_calls-i);
    5.10 -                return __HYPERVISOR_multicall;
    5.11              }
    5.12          }
    5.13      }
     6.1 --- a/xen/include/xen/sched.h	Thu Nov 25 17:45:40 2004 +0000
     6.2 +++ b/xen/include/xen/sched.h	Thu Nov 25 20:11:21 2004 +0000
     6.3 @@ -218,7 +218,8 @@ void continue_cpu_idle_loop(void);
     6.4  
     6.5  void continue_nonidle_task(void);
     6.6  
     6.7 -void hypercall_create_continuation(unsigned int op, unsigned int nr_args, ...);
     6.8 +unsigned long hypercall_create_continuation(
     6.9 +    unsigned int op, unsigned int nr_args, ...);
    6.10  #define hypercall_preempt_check() \
    6.11      (unlikely(softirq_pending(smp_processor_id())))
    6.12