ia64/xen-unstable
changeset 13536:0bf0672528cf
[XEN] Support VCPU reset via DOMCTL_setvcpucontext.
Signed-off-by: Andrei Petrov <andrei.petrov@xensource.com>
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__ */