ia64/xen-unstable

changeset 13536:0bf0672528cf

[XEN] Support VCPU reset via DOMCTL_setvcpucontext.
Signed-off-by: Andrei Petrov <andrei.petrov@xensource.com>
author kfraser@localhost.localdomain
date Fri Jan 19 17:55:29 2007 +0000 (2007-01-19)
parents 62e2e515febe
children d4ed1deee42d
files tools/libxc/xc_domain.c xen/arch/x86/domain.c xen/common/domain.c xen/include/xen/compat.h xen/include/xen/domain.h
line diff
     1.1 --- a/tools/libxc/xc_domain.c	Fri Jan 19 17:20:57 2007 +0000
     1.2 +++ b/tools/libxc/xc_domain.c	Fri Jan 19 17:55:29 2007 +0000
     1.3 @@ -602,12 +602,13 @@ int xc_vcpu_setcontext(int xc_handle,
     1.4      domctl.u.vcpucontext.vcpu = vcpu;
     1.5      set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);
     1.6  
     1.7 -    if ( (rc = lock_pages(ctxt, sizeof(*ctxt))) != 0 )
     1.8 +    if ( (ctxt != NULL) && ((rc = lock_pages(ctxt, sizeof(*ctxt))) != 0) )
     1.9          return rc;
    1.10  
    1.11      rc = do_domctl(xc_handle, &domctl);
    1.12  
    1.13 -    unlock_pages(ctxt, sizeof(*ctxt));
    1.14 +    if ( ctxt != NULL )
    1.15 +        unlock_pages(ctxt, sizeof(*ctxt));
    1.16  
    1.17      return rc;
    1.18  
     2.1 --- a/xen/arch/x86/domain.c	Fri Jan 19 17:20:57 2007 +0000
     2.2 +++ b/xen/arch/x86/domain.c	Fri Jan 19 17:55:29 2007 +0000
     2.3 @@ -50,6 +50,8 @@ DEFINE_PER_CPU(struct vcpu *, curr_vcpu)
     2.4  static void paravirt_ctxt_switch_from(struct vcpu *v);
     2.5  static void paravirt_ctxt_switch_to(struct vcpu *v);
     2.6  
     2.7 +static void vcpu_destroy_pagetables(struct vcpu *v);
     2.8 +
     2.9  static void continue_idle_domain(struct vcpu *v)
    2.10  {
    2.11      reset_stack_and_jump(idle_loop);
    2.12 @@ -658,6 +660,13 @@ int arch_set_info_guest(
    2.13  #undef c
    2.14  }
    2.15  
    2.16 +int arch_vcpu_reset(struct vcpu *v)
    2.17 +{
    2.18 +    destroy_gdt(v);
    2.19 +    vcpu_destroy_pagetables(v);
    2.20 +    return 0;
    2.21 +}
    2.22 +
    2.23  long
    2.24  arch_do_vcpu_op(
    2.25      int cmd, struct vcpu *v, XEN_GUEST_HANDLE(void) arg)
    2.26 @@ -1380,63 +1389,73 @@ static void relinquish_memory(struct dom
    2.27      spin_unlock_recursive(&d->page_alloc_lock);
    2.28  }
    2.29  
    2.30 -void domain_relinquish_resources(struct domain *d)
    2.31 +static void vcpu_destroy_pagetables(struct vcpu *v)
    2.32  {
    2.33 -    struct vcpu *v;
    2.34 +    struct domain *d = v->domain;
    2.35      unsigned long pfn;
    2.36  
    2.37 -    BUG_ON(!cpus_empty(d->domain_dirty_cpumask));
    2.38 -
    2.39 -    /* Drop the in-use references to page-table bases. */
    2.40 -    for_each_vcpu ( d, v )
    2.41 +#ifdef CONFIG_COMPAT
    2.42 +    if ( IS_COMPAT(d) )
    2.43      {
    2.44 -        /* Drop ref to guest_table (from new_guest_cr3(), svm/vmx cr3 handling,
    2.45 -         * or sh_update_paging_modes()) */
    2.46 -#ifdef CONFIG_COMPAT
    2.47 -        if ( IS_COMPAT(d) )
    2.48 -        {
    2.49 -            if ( is_hvm_vcpu(v) )
    2.50 -                pfn = pagetable_get_pfn(v->arch.guest_table);
    2.51 -            else
    2.52 -                pfn = l4e_get_pfn(*(l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table)));
    2.53 +        if ( is_hvm_vcpu(v) )
    2.54 +            pfn = pagetable_get_pfn(v->arch.guest_table);
    2.55 +        else
    2.56 +            pfn = l4e_get_pfn(*(l4_pgentry_t *)
    2.57 +                              __va(pagetable_get_paddr(v->arch.guest_table)));
    2.58  
    2.59 -            if ( pfn != 0 )
    2.60 -            {
    2.61 -                if ( shadow_mode_refcounts(d) )
    2.62 -                    put_page(mfn_to_page(pfn));
    2.63 -                else
    2.64 -                    put_page_and_type(mfn_to_page(pfn));
    2.65 -            }
    2.66 -            continue;
    2.67 -        }
    2.68 -#endif
    2.69 -        pfn = pagetable_get_pfn(v->arch.guest_table);
    2.70          if ( pfn != 0 )
    2.71          {
    2.72              if ( shadow_mode_refcounts(d) )
    2.73                  put_page(mfn_to_page(pfn));
    2.74              else
    2.75                  put_page_and_type(mfn_to_page(pfn));
    2.76 +        }
    2.77 +
    2.78 +        v->arch.guest_table = pagetable_null();
    2.79 +        v->arch.cr3 = 0;
    2.80 +        return;
    2.81 +    }
    2.82 +#endif
    2.83 +
    2.84 +    pfn = pagetable_get_pfn(v->arch.guest_table);
    2.85 +    if ( pfn != 0 )
    2.86 +    {
    2.87 +        if ( shadow_mode_refcounts(d) )
    2.88 +            put_page(mfn_to_page(pfn));
    2.89 +        else
    2.90 +            put_page_and_type(mfn_to_page(pfn));
    2.91  #ifdef __x86_64__
    2.92 -            if ( pfn == pagetable_get_pfn(v->arch.guest_table_user) )
    2.93 -                v->arch.guest_table_user = pagetable_null();
    2.94 +        if ( pfn == pagetable_get_pfn(v->arch.guest_table_user) )
    2.95 +            v->arch.guest_table_user = pagetable_null();
    2.96  #endif
    2.97 -            v->arch.guest_table = pagetable_null();
    2.98 -        }
    2.99 +        v->arch.guest_table = pagetable_null();
   2.100 +    }
   2.101  
   2.102  #ifdef __x86_64__
   2.103 -        /* Drop ref to guest_table_user (from MMUEXT_NEW_USER_BASEPTR) */
   2.104 -        pfn = pagetable_get_pfn(v->arch.guest_table_user);
   2.105 -        if ( pfn != 0 )
   2.106 -        {
   2.107 -            if ( shadow_mode_refcounts(d) )
   2.108 -                put_page(mfn_to_page(pfn));
   2.109 -            else
   2.110 -                put_page_and_type(mfn_to_page(pfn));
   2.111 -            v->arch.guest_table_user = pagetable_null();
   2.112 -        }
   2.113 +    /* Drop ref to guest_table_user (from MMUEXT_NEW_USER_BASEPTR) */
   2.114 +    pfn = pagetable_get_pfn(v->arch.guest_table_user);
   2.115 +    if ( pfn != 0 )
   2.116 +    {
   2.117 +        if ( shadow_mode_refcounts(d) )
   2.118 +            put_page(mfn_to_page(pfn));
   2.119 +        else
   2.120 +            put_page_and_type(mfn_to_page(pfn));
   2.121 +        v->arch.guest_table_user = pagetable_null();
   2.122 +    }
   2.123  #endif
   2.124 -    }
   2.125 +
   2.126 +    v->arch.cr3 = 0;
   2.127 +}
   2.128 +
   2.129 +void domain_relinquish_resources(struct domain *d)
   2.130 +{
   2.131 +    struct vcpu *v;
   2.132 +
   2.133 +    BUG_ON(!cpus_empty(d->domain_dirty_cpumask));
   2.134 +
   2.135 +    /* Drop the in-use references to page-table bases. */
   2.136 +    for_each_vcpu ( d, v )
   2.137 +        vcpu_destroy_pagetables(v);
   2.138  
   2.139      /* Tear down shadow mode stuff. */
   2.140      shadow_teardown(d);
     3.1 --- a/xen/common/domain.c	Fri Jan 19 17:20:57 2007 +0000
     3.2 +++ b/xen/common/domain.c	Fri Jan 19 17:55:29 2007 +0000
     3.3 @@ -5,6 +5,7 @@
     3.4   */
     3.5  
     3.6  #include <xen/config.h>
     3.7 +#include <xen/compat.h>
     3.8  #include <xen/init.h>
     3.9  #include <xen/lib.h>
    3.10  #include <xen/errno.h>
    3.11 @@ -467,7 +468,12 @@ int set_info_guest(struct domain *d,
    3.12  
    3.13      if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) )
    3.14          return -EINVAL;
    3.15 -    
    3.16 +
    3.17 +    if ( IS_COMPAT(v->domain)
    3.18 +         ? compat_handle_is_null(vcpucontext.cmp->ctxt)
    3.19 +         : guest_handle_is_null(vcpucontext.nat->ctxt) )
    3.20 +        return vcpu_reset(v);
    3.21 +
    3.22  #ifdef CONFIG_COMPAT
    3.23      BUILD_BUG_ON(sizeof(struct vcpu_guest_context)
    3.24                   < sizeof(struct compat_vcpu_guest_context));
    3.25 @@ -521,6 +527,36 @@ int boot_vcpu(struct domain *d, int vcpu
    3.26      return arch_set_info_guest(v, ctxt);
    3.27  }
    3.28  
    3.29 +int vcpu_reset(struct vcpu *v)
    3.30 +{
    3.31 +    struct domain *d = v->domain;
    3.32 +    int rc;
    3.33 +
    3.34 +    domain_pause(d);
    3.35 +    LOCK_BIGLOCK(d);
    3.36 +
    3.37 +    rc = arch_vcpu_reset(v);
    3.38 +    if ( rc != 0 )
    3.39 +        goto out;
    3.40 +
    3.41 +    set_bit(_VCPUF_down, &v->vcpu_flags);
    3.42 +
    3.43 +    clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
    3.44 +    clear_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags);
    3.45 +    clear_bit(_VCPUF_blocked, &v->vcpu_flags);
    3.46 +    clear_bit(_VCPUF_initialised, &v->vcpu_flags);
    3.47 +    clear_bit(_VCPUF_nmi_pending, &v->vcpu_flags);
    3.48 +    clear_bit(_VCPUF_nmi_masked, &v->vcpu_flags);
    3.49 +    clear_bit(_VCPUF_polling, &v->vcpu_flags);
    3.50 +
    3.51 + out:
    3.52 +    UNLOCK_BIGLOCK(v->domain);
    3.53 +    domain_unpause(d);
    3.54 +
    3.55 +    return rc;
    3.56 +}
    3.57 +
    3.58 +
    3.59  long do_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg)
    3.60  {
    3.61      struct domain *d = current->domain;
     4.1 --- a/xen/include/xen/compat.h	Fri Jan 19 17:20:57 2007 +0000
     4.2 +++ b/xen/include/xen/compat.h	Fri Jan 19 17:55:29 2007 +0000
     4.3 @@ -173,6 +173,8 @@ int switch_native(struct domain *);
     4.4  
     4.5  #else
     4.6  
     4.7 +#define compat_handle_is_null(hnd) 0
     4.8 +
     4.9  #define BITS_PER_GUEST_LONG(d) BITS_PER_LONG
    4.10  
    4.11  #endif
     5.1 --- a/xen/include/xen/domain.h	Fri Jan 19 17:20:57 2007 +0000
     5.2 +++ b/xen/include/xen/domain.h	Fri Jan 19 17:55:29 2007 +0000
     5.3 @@ -12,6 +12,7 @@ struct vcpu *alloc_vcpu(
     5.4  int boot_vcpu(
     5.5      struct domain *d, int vcpuid, vcpu_guest_context_u ctxt);
     5.6  struct vcpu *alloc_idle_vcpu(unsigned int cpu_id);
     5.7 +int vcpu_reset(struct vcpu *v);
     5.8  
     5.9  struct domain *alloc_domain(domid_t domid);
    5.10  void free_domain(struct domain *d);
    5.11 @@ -56,4 +57,6 @@ void arch_dump_vcpu_info(struct vcpu *v)
    5.12  
    5.13  void arch_dump_domain_info(struct domain *d);
    5.14  
    5.15 +int arch_vcpu_reset(struct vcpu *v);
    5.16 +
    5.17  #endif /* __XEN_DOMAIN_H__ */