direct-io.hg

changeset 12251:8eb8c0085604

[HVM] Replace relinquish_resources() destructor hook with
separate vcpu and domain destructors that are called at the
point the domain is finally destroyed.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Mon Nov 06 16:36:51 2006 +0000 (2006-11-06)
parents a910bf123e58
children 32e4952c0638
files xen/arch/x86/domain.c xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/svm/vmcb.c xen/arch/x86/hvm/vlapic.c xen/arch/x86/hvm/vmx/vmcs.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/hvm.h xen/include/asm-x86/hvm/io.h xen/include/asm-x86/hvm/vlapic.h
line diff
     1.1 --- a/xen/arch/x86/domain.c	Mon Nov 06 15:46:28 2006 +0000
     1.2 +++ b/xen/arch/x86/domain.c	Mon Nov 06 16:36:51 2006 +0000
     1.3 @@ -235,7 +235,7 @@ int arch_domain_create(struct domain *d)
     1.4              virt_to_page(d->shared_info), d, XENSHARE_writable);
     1.5      }
     1.6  
     1.7 -    return hvm_domain_initialise(d);
     1.8 +    return is_hvm_domain(d) ? hvm_domain_initialise(d) : 0;
     1.9  
    1.10   fail:
    1.11      free_xenheap_page(d->shared_info);
    1.12 @@ -249,6 +249,15 @@ int arch_domain_create(struct domain *d)
    1.13  
    1.14  void arch_domain_destroy(struct domain *d)
    1.15  {
    1.16 +    struct vcpu *v;
    1.17 +
    1.18 +    if ( is_hvm_domain(d) )
    1.19 +    {
    1.20 +        for_each_vcpu ( d, v )
    1.21 +            hvm_vcpu_destroy(v);
    1.22 +        hvm_domain_destroy(d);
    1.23 +    }
    1.24 +
    1.25      shadow_final_teardown(d);
    1.26  
    1.27      free_xenheap_pages(
    1.28 @@ -974,9 +983,6 @@ void domain_relinquish_resources(struct 
    1.29  #endif
    1.30      }
    1.31  
    1.32 -    if ( is_hvm_domain(d) )
    1.33 -        hvm_relinquish_guest_resources(d);
    1.34 -
    1.35      /* Tear down shadow mode stuff. */
    1.36      shadow_teardown(d);
    1.37  
     2.1 --- a/xen/arch/x86/hvm/hvm.c	Mon Nov 06 15:46:28 2006 +0000
     2.2 +++ b/xen/arch/x86/hvm/hvm.c	Mon Nov 06 16:36:51 2006 +0000
     2.3 @@ -110,19 +110,11 @@ void hvm_do_resume(struct vcpu *v)
     2.4      }
     2.5  }
     2.6  
     2.7 -void hvm_release_assist_channel(struct vcpu *v)
     2.8 -{
     2.9 -    free_xen_event_channel(v, v->arch.hvm_vcpu.xen_port);
    2.10 -}
    2.11 -
    2.12  int hvm_domain_initialise(struct domain *d)
    2.13  {
    2.14      struct hvm_domain *platform = &d->arch.hvm_domain;
    2.15      int rc;
    2.16  
    2.17 -    if ( !is_hvm_domain(d) )
    2.18 -        return 0;
    2.19 -
    2.20      if ( !hvm_enabled )
    2.21      {
    2.22          gdprintk(XENLOG_WARNING, "Attempt to create a HVM guest "
    2.23 @@ -146,6 +138,20 @@ int hvm_domain_initialise(struct domain 
    2.24      return 0;
    2.25  }
    2.26  
    2.27 +void hvm_domain_destroy(struct domain *d)
    2.28 +{
    2.29 +    kill_timer(&d->arch.hvm_domain.pl_time.periodic_tm.timer);
    2.30 +    rtc_deinit(d);
    2.31 +    pmtimer_deinit(d);
    2.32 +
    2.33 +    if ( d->arch.hvm_domain.shared_page_va )
    2.34 +        unmap_domain_page_global(
    2.35 +            (void *)d->arch.hvm_domain.shared_page_va);
    2.36 +
    2.37 +    if ( d->arch.hvm_domain.buffered_io_va )
    2.38 +        unmap_domain_page_global((void *)d->arch.hvm_domain.buffered_io_va);
    2.39 +}
    2.40 +
    2.41  int hvm_vcpu_initialise(struct vcpu *v)
    2.42  {
    2.43      struct hvm_domain *platform;
    2.44 @@ -154,12 +160,20 @@ int hvm_vcpu_initialise(struct vcpu *v)
    2.45      if ( (rc = hvm_funcs.vcpu_initialise(v)) != 0 )
    2.46          return rc;
    2.47  
    2.48 +    if ( (rc = vlapic_init(v)) != 0 )
    2.49 +    {
    2.50 +        hvm_funcs.vcpu_destroy(v);
    2.51 +        return rc;
    2.52 +    }
    2.53 +
    2.54      /* Create ioreq event channel. */
    2.55      v->arch.hvm_vcpu.xen_port = alloc_unbound_xen_event_channel(v, 0);
    2.56      if ( get_sp(v->domain) && get_vio(v->domain, v->vcpu_id) )
    2.57          get_vio(v->domain, v->vcpu_id)->vp_eport =
    2.58              v->arch.hvm_vcpu.xen_port;
    2.59  
    2.60 +    init_timer(&v->arch.hvm_vcpu.hlt_timer, hlt_timer_fn, v, v->processor);
    2.61 +
    2.62      if ( v->vcpu_id != 0 )
    2.63          return 0;
    2.64  
    2.65 @@ -178,6 +192,16 @@ int hvm_vcpu_initialise(struct vcpu *v)
    2.66      return 0;
    2.67  }
    2.68  
    2.69 +void hvm_vcpu_destroy(struct vcpu *v)
    2.70 +{
    2.71 +    kill_timer(&v->arch.hvm_vcpu.hlt_timer);
    2.72 +    vlapic_destroy(v);
    2.73 +    hvm_funcs.vcpu_destroy(v);
    2.74 +
    2.75 +    /* Event channel is already freed by evtchn_destroy(). */
    2.76 +    /*free_xen_event_channel(v, v->arch.hvm_vcpu.xen_port);*/
    2.77 +}
    2.78 +
    2.79  void pic_irq_request(void *data, int level)
    2.80  {
    2.81      int *interrupt_request = data;
     3.1 --- a/xen/arch/x86/hvm/svm/svm.c	Mon Nov 06 15:46:28 2006 +0000
     3.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Mon Nov 06 16:36:51 2006 +0000
     3.3 @@ -61,7 +61,6 @@ extern void svm_dump_inst(unsigned long 
     3.4  extern int svm_dbg_on;
     3.5  void svm_dump_regs(const char *from, struct cpu_user_regs *regs);
     3.6  
     3.7 -static void svm_relinquish_guest_resources(struct domain *d);
     3.8  static int svm_do_vmmcall_reset_to_realmode(struct vcpu *v,
     3.9                                              struct cpu_user_regs *regs);
    3.10  
    3.11 @@ -777,6 +776,11 @@ static int svm_vcpu_initialise(struct vc
    3.12      return 0;
    3.13  }
    3.14  
    3.15 +static void svm_vcpu_destroy(struct vcpu *v)
    3.16 +{
    3.17 +    destroy_vmcb(&v->arch.hvm_svm);
    3.18 +}
    3.19 +
    3.20  int start_svm(void)
    3.21  {
    3.22      u32 eax, ecx, edx;
    3.23 @@ -825,7 +829,7 @@ int start_svm(void)
    3.24      hvm_funcs.disable = stop_svm;
    3.25  
    3.26      hvm_funcs.vcpu_initialise = svm_vcpu_initialise;
    3.27 -    hvm_funcs.relinquish_guest_resources = svm_relinquish_guest_resources;
    3.28 +    hvm_funcs.vcpu_destroy    = svm_vcpu_destroy;
    3.29  
    3.30      hvm_funcs.store_cpu_guest_regs = svm_store_cpu_guest_regs;
    3.31      hvm_funcs.load_cpu_guest_regs = svm_load_cpu_guest_regs;
    3.32 @@ -851,40 +855,6 @@ int start_svm(void)
    3.33  }
    3.34  
    3.35  
    3.36 -static void svm_relinquish_guest_resources(struct domain *d)
    3.37 -{
    3.38 -    struct vcpu *v;
    3.39 -
    3.40 -    for_each_vcpu ( d, v )
    3.41 -    {
    3.42 -        if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
    3.43 -            continue;
    3.44 -
    3.45 -        destroy_vmcb(&v->arch.hvm_svm);
    3.46 -        kill_timer(&v->arch.hvm_vcpu.hlt_timer);
    3.47 -        if ( VLAPIC(v) != NULL )
    3.48 -        {
    3.49 -            kill_timer(&VLAPIC(v)->vlapic_timer);
    3.50 -            unmap_domain_page_global(VLAPIC(v)->regs);
    3.51 -            free_domheap_page(VLAPIC(v)->regs_page);
    3.52 -            xfree(VLAPIC(v));
    3.53 -        }
    3.54 -        hvm_release_assist_channel(v);
    3.55 -    }
    3.56 -
    3.57 -    kill_timer(&d->arch.hvm_domain.pl_time.periodic_tm.timer);
    3.58 -    rtc_deinit(d);
    3.59 -    pmtimer_deinit(d);
    3.60 -
    3.61 -    if ( d->arch.hvm_domain.shared_page_va )
    3.62 -        unmap_domain_page_global(
    3.63 -            (void *)d->arch.hvm_domain.shared_page_va);
    3.64 -
    3.65 -    if ( d->arch.hvm_domain.buffered_io_va )
    3.66 -        unmap_domain_page_global((void *)d->arch.hvm_domain.buffered_io_va);
    3.67 -}
    3.68 -
    3.69 -
    3.70  static void svm_migrate_timers(struct vcpu *v)
    3.71  {
    3.72      struct periodic_time *pt = 
     4.1 --- a/xen/arch/x86/hvm/svm/vmcb.c	Mon Nov 06 15:46:28 2006 +0000
     4.2 +++ b/xen/arch/x86/hvm/svm/vmcb.c	Mon Nov 06 16:36:51 2006 +0000
     4.3 @@ -351,9 +351,6 @@ void svm_do_launch(struct vcpu *v)
     4.4      if ( !asidpool_assign_next( vmcb, 0, core, core ))
     4.5          BUG();
     4.6  
     4.7 -    vlapic_init(v);
     4.8 -    init_timer(&v->arch.hvm_vcpu.hlt_timer, hlt_timer_fn, v, v->processor);
     4.9 -
    4.10      vmcb->ldtr.sel = 0;
    4.11      vmcb->ldtr.base = 0;
    4.12      vmcb->ldtr.limit = 0;
     5.1 --- a/xen/arch/x86/hvm/vlapic.c	Mon Nov 06 15:46:28 2006 +0000
     5.2 +++ b/xen/arch/x86/hvm/vlapic.c	Mon Nov 06 16:36:51 2006 +0000
     5.3 @@ -1016,7 +1016,7 @@ static int vlapic_reset(struct vlapic *v
     5.4  
     5.5  int vlapic_init(struct vcpu *v)
     5.6  {
     5.7 -    struct vlapic *vlapic = NULL;
     5.8 +    struct vlapic *vlapic;
     5.9  
    5.10      HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_init %d", v->vcpu_id);
    5.11  
    5.12 @@ -1047,3 +1047,18 @@ int vlapic_init(struct vcpu *v)
    5.13  
    5.14      return 0;
    5.15  }
    5.16 +
    5.17 +void vlapic_destroy(struct vcpu *v)
    5.18 +{
    5.19 +    struct vlapic *vlapic = VLAPIC(v);
    5.20 +    
    5.21 +    if ( vlapic == NULL )
    5.22 +        return;
    5.23 +
    5.24 +    VLAPIC(v) = NULL;
    5.25 +
    5.26 +    kill_timer(&vlapic->vlapic_timer);
    5.27 +    unmap_domain_page_global(vlapic->regs);
    5.28 +    free_domheap_page(vlapic->regs_page);
    5.29 +    xfree(vlapic);
    5.30 +}
     6.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Mon Nov 06 15:46:28 2006 +0000
     6.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Mon Nov 06 16:36:51 2006 +0000
     6.3 @@ -193,11 +193,7 @@ void vmx_vmcs_enter(struct vcpu *v)
     6.4  {
     6.5      /*
     6.6       * NB. We must *always* run an HVM VCPU on its own VMCS, except for
     6.7 -     * vmx_vmcs_enter/exit critical regions. This leads to some TODOs:
     6.8 -     *  1. VMPTRLD as soon as we context-switch to a HVM VCPU.
     6.9 -     *  2. VMCS destruction needs to happen later (from domain_destroy()).
    6.10 -     * We can relax this a bit if a paused VCPU always commits its
    6.11 -     * architectural state to a software structure.
    6.12 +     * vmx_vmcs_enter/exit critical regions.
    6.13       */
    6.14      if ( v == current )
    6.15          return;
    6.16 @@ -416,11 +412,6 @@ static int construct_vmcs(struct vcpu *v
    6.17          cr4 & ~(X86_CR4_PGE | X86_CR4_VMXE | X86_CR4_PAE);
    6.18      error |= __vmwrite(CR4_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr4);
    6.19  
    6.20 -    /* XXX Move this out. */
    6.21 -    init_timer(&v->arch.hvm_vcpu.hlt_timer, hlt_timer_fn, v, v->processor);
    6.22 -    if ( vlapic_init(v) != 0 )
    6.23 -        return -1;
    6.24 -
    6.25  #ifdef __x86_64__ 
    6.26      /* VLAPIC TPR optimisation. */
    6.27      v->arch.hvm_vcpu.u.vmx.exec_control |= CPU_BASED_TPR_SHADOW;
     7.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Mon Nov 06 15:46:28 2006 +0000
     7.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Mon Nov 06 16:36:51 2006 +0000
     7.3 @@ -74,36 +74,9 @@ static int vmx_vcpu_initialise(struct vc
     7.4      return 0;
     7.5  }
     7.6  
     7.7 -static void vmx_relinquish_guest_resources(struct domain *d)
     7.8 +static void vmx_vcpu_destroy(struct vcpu *v)
     7.9  {
    7.10 -    struct vcpu *v;
    7.11 -
    7.12 -    for_each_vcpu ( d, v )
    7.13 -    {
    7.14 -        vmx_destroy_vmcs(v);
    7.15 -        if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
    7.16 -            continue;
    7.17 -        kill_timer(&v->arch.hvm_vcpu.hlt_timer);
    7.18 -        if ( VLAPIC(v) != NULL )
    7.19 -        {
    7.20 -            kill_timer(&VLAPIC(v)->vlapic_timer);
    7.21 -            unmap_domain_page_global(VLAPIC(v)->regs);
    7.22 -            free_domheap_page(VLAPIC(v)->regs_page);
    7.23 -            xfree(VLAPIC(v));
    7.24 -        }
    7.25 -        hvm_release_assist_channel(v);
    7.26 -    }
    7.27 -
    7.28 -    kill_timer(&d->arch.hvm_domain.pl_time.periodic_tm.timer);
    7.29 -    rtc_deinit(d);
    7.30 -    pmtimer_deinit(d);
    7.31 -
    7.32 -    if ( d->arch.hvm_domain.shared_page_va )
    7.33 -        unmap_domain_page_global(
    7.34 -            (void *)d->arch.hvm_domain.shared_page_va);
    7.35 -
    7.36 -    if ( d->arch.hvm_domain.buffered_io_va )
    7.37 -        unmap_domain_page_global((void *)d->arch.hvm_domain.buffered_io_va);
    7.38 +    vmx_destroy_vmcs(v);
    7.39  }
    7.40  
    7.41  #ifdef __x86_64__
    7.42 @@ -674,7 +647,7 @@ static void vmx_setup_hvm_funcs(void)
    7.43      hvm_funcs.disable = stop_vmx;
    7.44  
    7.45      hvm_funcs.vcpu_initialise = vmx_vcpu_initialise;
    7.46 -    hvm_funcs.relinquish_guest_resources = vmx_relinquish_guest_resources;
    7.47 +    hvm_funcs.vcpu_destroy    = vmx_vcpu_destroy;
    7.48  
    7.49      hvm_funcs.store_cpu_guest_regs = vmx_store_cpu_guest_regs;
    7.50      hvm_funcs.load_cpu_guest_regs = vmx_load_cpu_guest_regs;
     8.1 --- a/xen/include/asm-x86/hvm/hvm.h	Mon Nov 06 15:46:28 2006 +0000
     8.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Mon Nov 06 16:36:51 2006 +0000
     8.3 @@ -33,10 +33,10 @@ struct hvm_function_table {
     8.4      void (*disable)(void);
     8.5  
     8.6      /*
     8.7 -     * Initialize/relinguish HVM guest resources
     8.8 +     * Initialise/destroy HVM VCPU resources
     8.9       */
    8.10      int  (*vcpu_initialise)(struct vcpu *v);
    8.11 -    void (*relinquish_guest_resources)(struct domain *d);
    8.12 +    void (*vcpu_destroy)(struct vcpu *v);
    8.13  
    8.14      /*
    8.15       * Store and load guest state:
    8.16 @@ -92,13 +92,10 @@ hvm_disable(void)
    8.17  }
    8.18  
    8.19  int hvm_domain_initialise(struct domain *d);
    8.20 -int hvm_vcpu_initialise(struct vcpu *v);
    8.21 +void hvm_domain_destroy(struct domain *d);
    8.22  
    8.23 -static inline void
    8.24 -hvm_relinquish_guest_resources(struct domain *d)
    8.25 -{
    8.26 -    hvm_funcs.relinquish_guest_resources(d);
    8.27 -}
    8.28 +int hvm_vcpu_initialise(struct vcpu *v);
    8.29 +void hvm_vcpu_destroy(struct vcpu *v);
    8.30  
    8.31  static inline void
    8.32  hvm_store_cpu_guest_regs(
     9.1 --- a/xen/include/asm-x86/hvm/io.h	Mon Nov 06 15:46:28 2006 +0000
     9.2 +++ b/xen/include/asm-x86/hvm/io.h	Mon Nov 06 16:36:51 2006 +0000
     9.3 @@ -151,7 +151,6 @@ extern void pic_irq_request(void *data, 
     9.4  extern void hvm_pic_assist(struct vcpu *v);
     9.5  extern int cpu_get_interrupt(struct vcpu *v, int *type);
     9.6  extern int cpu_has_pending_irq(struct vcpu *v);
     9.7 -extern void hvm_release_assist_channel(struct vcpu *v);
     9.8  
     9.9  // XXX - think about this, maybe use bit 30 of the mfn to signify an MMIO frame.
    9.10  #define mmio_space(gpa) (!VALID_MFN(get_mfn_from_gpfn((gpa) >> PAGE_SHIFT)))
    10.1 --- a/xen/include/asm-x86/hvm/vlapic.h	Mon Nov 06 15:46:28 2006 +0000
    10.2 +++ b/xen/include/asm-x86/hvm/vlapic.h	Mon Nov 06 16:36:51 2006 +0000
    10.3 @@ -77,7 +77,8 @@ int vlapic_find_highest_irr(struct vlapi
    10.4  
    10.5  int cpu_get_apic_interrupt(struct vcpu *v, int *mode);
    10.6  
    10.7 -int vlapic_init(struct vcpu *vc);
    10.8 +int  vlapic_init(struct vcpu *v);
    10.9 +void vlapic_destroy(struct vcpu *v);
   10.10  
   10.11  void vlapic_msr_set(struct vlapic *vlapic, uint64_t value);
   10.12