WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [XEN] Re-jig VCPU initialisation -- VMX i

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [XEN] Re-jig VCPU initialisation -- VMX init requires generic VCPU
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 06 Nov 2006 16:50:35 +0000
Delivery-date: Mon, 06 Nov 2006 08:53:45 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID e793dad2114d678b9ce8ebd36145f205943bf1cb
# Parent  31985f348d2e388d973500816899fde97c4dbeda
[XEN] Re-jig VCPU initialisation -- VMX init requires generic VCPU
fields to already be allocated. This has led to a general cleanup of
domain and vcpu initialisation and destruction.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/ia64/xen/domain.c  |  103 ++++++++++++++-------------
 xen/arch/powerpc/domain.c   |   23 +++---
 xen/arch/x86/domain.c       |   44 ++++++-----
 xen/arch/x86/hvm/vmx/vmcs.c |  163 ++++++++++++--------------------------------
 xen/arch/x86/hvm/vmx/vmx.c  |   12 ---
 xen/common/domain.c         |   30 +++++---
 xen/common/sched_credit.c   |   81 ++++++++++-----------
 xen/common/sched_sedf.c     |   35 +++++----
 xen/common/schedule.c       |   21 +++--
 xen/include/xen/domain.h    |   14 +++
 xen/include/xen/sched-if.h  |    5 +
 xen/include/xen/sched.h     |    4 -
 12 files changed, 253 insertions(+), 282 deletions(-)

diff -r 31985f348d2e -r e793dad2114d xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Mon Nov 06 09:46:13 2006 +0000
+++ b/xen/arch/ia64/xen/domain.c        Mon Nov 06 11:03:04 2006 +0000
@@ -275,40 +275,61 @@ void hlt_timer_fn(void *data)
        vcpu_unblock(v);
 }
 
-struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
+void relinquish_vcpu_resources(struct vcpu *v)
+{
+    if (HAS_PERVCPU_VHPT(v->domain))
+        pervcpu_vhpt_free(v);
+    if (v->arch.privregs != NULL) {
+        free_xenheap_pages(v->arch.privregs,
+                           get_order_from_shift(XMAPPEDREGS_SHIFT));
+        v->arch.privregs = NULL;
+    }
+    kill_timer(&v->arch.hlt_timer);
+}
+
+struct vcpu *alloc_vcpu_struct(void)
 {
        struct vcpu *v;
        struct thread_info *ti;
-
-       /* Still keep idle vcpu0 static allocated at compilation, due
-        * to some code from Linux still requires it in early phase.
+       static int first_allocation = 1;
+
+       if (first_allocation) {
+               first_allocation = 0;
+               /* Still keep idle vcpu0 static allocated at compilation, due
+                * to some code from Linux still requires it in early phase.
+                */
+               return idle_vcpu[0];
+       }
+
+       if ((v = alloc_xenheap_pages(KERNEL_STACK_SIZE_ORDER)) == NULL)
+               return NULL;
+       memset(v, 0, sizeof(*v)); 
+
+       ti = alloc_thread_info(v);
+       /* Clear thread_info to clear some important fields, like
+        * preempt_count
         */
-       if (is_idle_domain(d) && !vcpu_id)
-           v = idle_vcpu[0];
-       else {
-           if ((v = alloc_xenheap_pages(KERNEL_STACK_SIZE_ORDER)) == NULL)
-               return NULL;
-           memset(v, 0, sizeof(*v)); 
-
-           ti = alloc_thread_info(v);
-           /* Clear thread_info to clear some important fields, like
-            * preempt_count
-            */
-           memset(ti, 0, sizeof(struct thread_info));
-           init_switch_stack(v);
-       }
+       memset(ti, 0, sizeof(struct thread_info));
+       init_switch_stack(v);
+
+       return v;
+}
+
+void free_vcpu_struct(struct vcpu *v)
+{
+       free_xenheap_pages(v, KERNEL_STACK_SIZE_ORDER);
+}
+
+int vcpu_initialise(struct vcpu *v)
+{
+       struct domain *d = v->domain;
+       int rc, order, i;
 
        if (!is_idle_domain(d)) {
            if (!d->arch.is_vti) {
-               int order;
-               int i;
-               // vti domain has its own vhpt policy.
-               if (HAS_PERVCPU_VHPT(d)) {
-                       if (pervcpu_vhpt_alloc(v) < 0) {
-                               free_xenheap_pages(v, KERNEL_STACK_SIZE_ORDER);
-                               return NULL;
-                       }
-               }
+               if (HAS_PERVCPU_VHPT(d))
+                       if ((rc = pervcpu_vhpt_alloc(v)) != 0)
+                               return rc;
 
                /* Create privregs page only if not VTi. */
                order = get_order_from_shift(XMAPPEDREGS_SHIFT);
@@ -344,34 +365,20 @@ struct vcpu *alloc_vcpu_struct(struct do
            v->arch.breakimm = d->arch.breakimm;
            v->arch.last_processor = INVALID_PROCESSOR;
        }
-       if (!VMX_DOMAIN(v)){
+
+       if (!VMX_DOMAIN(v))
                init_timer(&v->arch.hlt_timer, hlt_timer_fn, v,
                           first_cpu(cpu_online_map));
-       }
-
-       return v;
-}
-
-void relinquish_vcpu_resources(struct vcpu *v)
-{
-    if (HAS_PERVCPU_VHPT(v->domain))
-        pervcpu_vhpt_free(v);
-    if (v->arch.privregs != NULL) {
-        free_xenheap_pages(v->arch.privregs,
-                           get_order_from_shift(XMAPPEDREGS_SHIFT));
-        v->arch.privregs = NULL;
-    }
-    kill_timer(&v->arch.hlt_timer);
-}
-
-void free_vcpu_struct(struct vcpu *v)
+
+       return 0;
+}
+
+void vcpu_destroy(struct vcpu *v)
 {
        if (v->domain->arch.is_vti)
                vmx_relinquish_vcpu_resources(v);
        else
                relinquish_vcpu_resources(v);
-
-       free_xenheap_pages(v, KERNEL_STACK_SIZE_ORDER);
 }
 
 static void init_switch_stack(struct vcpu *v)
diff -r 31985f348d2e -r e793dad2114d xen/arch/powerpc/domain.c
--- a/xen/arch/powerpc/domain.c Mon Nov 06 09:46:13 2006 +0000
+++ b/xen/arch/powerpc/domain.c Mon Nov 06 11:03:04 2006 +0000
@@ -109,25 +109,26 @@ void machine_restart(char * __unused)
     while(1);
 }
 
-struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
+struct vcpu *alloc_vcpu_struct(void)
 {
     struct vcpu *v;
-
-    if ( (v = xmalloc(struct vcpu)) == NULL )
-        return NULL;
-
-    memset(v, 0, sizeof(*v));
-    v->vcpu_id = vcpu_id;
-
+    if ( (v = xmalloc(struct vcpu)) != NULL )
+        memset(v, 0, sizeof(*v));
     return v;
 }
 
 void free_vcpu_struct(struct vcpu *v)
 {
-    BUG_ON(v->next_in_list != NULL);
-    if ( v->vcpu_id != 0 )
-        v->domain->vcpu[v->vcpu_id - 1]->next_in_list = NULL;
     xfree(v);
+}
+
+int vcpu_initialise(struct vcpu *v)
+{
+    return 0;
+}
+
+void vcpu_destroy(struct vcpu *v)
+{
 }
 
 int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_t *c)
diff -r 31985f348d2e -r e793dad2114d xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Mon Nov 06 09:46:13 2006 +0000
+++ b/xen/arch/x86/domain.c     Mon Nov 06 11:03:04 2006 +0000
@@ -114,27 +114,30 @@ void dump_pageframe_info(struct domain *
     }
 }
 
-struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
+struct vcpu *alloc_vcpu_struct(void)
 {
     struct vcpu *v;
-
-    if ( (v = xmalloc(struct vcpu)) == NULL )
-        return NULL;
-
-    memset(v, 0, sizeof(*v));
-
-    v->vcpu_id = vcpu_id;
-    v->domain  = d;
+    if ( (v = xmalloc(struct vcpu)) != NULL )
+        memset(v, 0, sizeof(*v));
+    return v;
+}
+
+void free_vcpu_struct(struct vcpu *v)
+{
+    xfree(v);
+}
+
+int vcpu_initialise(struct vcpu *v)
+{
+    struct domain *d = v->domain;
+    int rc;
 
     v->arch.flags = TF_kernel_mode;
 
     if ( is_hvm_domain(d) )
     {
-        if ( hvm_vcpu_initialise(v) != 0 )
-        {
-            xfree(v);
-            return NULL;
-        }
+        if ( (rc = hvm_vcpu_initialise(v)) != 0 )
+            return rc;
     }
     else
     {
@@ -150,16 +153,15 @@ struct vcpu *alloc_vcpu_struct(struct do
     }
 
     v->arch.perdomain_ptes =
-        d->arch.mm_perdomain_pt + (vcpu_id << GDT_LDT_VCPU_SHIFT);
+        d->arch.mm_perdomain_pt + (v->vcpu_id << GDT_LDT_VCPU_SHIFT);
 
     pae_l3_cache_init(&v->arch.pae_l3_cache);
 
-    return v;
-}
-
-void free_vcpu_struct(struct vcpu *v)
-{
-    xfree(v);
+    return 0;
+}
+
+void vcpu_destroy(struct vcpu *v)
+{
 }
 
 int arch_domain_create(struct domain *d)
diff -r 31985f348d2e -r e793dad2114d xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Mon Nov 06 09:46:13 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Mon Nov 06 11:03:04 2006 +0000
@@ -193,11 +193,9 @@ void vmx_vmcs_enter(struct vcpu *v)
 {
     /*
      * NB. We must *always* run an HVM VCPU on its own VMCS, except for
-     * vmx_vmcs_enter/exit critical regions. This leads to some XXX TODOs XXX:
-     *  1. Move construct_vmcs() much earlier, to domain creation or
-     *     context initialisation.
-     *  2. VMPTRLD as soon as we context-switch to a HVM VCPU.
-     *  3. VMCS destruction needs to happen later (from domain_destroy()).
+     * vmx_vmcs_enter/exit critical regions. This leads to some TODOs:
+     *  1. VMPTRLD as soon as we context-switch to a HVM VCPU.
+     *  2. VMCS destruction needs to happen later (from domain_destroy()).
      * We can relax this a bit if a paused VCPU always commits its
      * architectural state to a software structure.
      */
@@ -233,17 +231,6 @@ void vmx_free_host_vmcs(struct vmcs_stru
 void vmx_free_host_vmcs(struct vmcs_struct *vmcs)
 {
     vmx_free_vmcs(vmcs);
-}
-
-static inline int construct_vmcs_controls(struct arch_vmx_struct *arch_vmx)
-{
-    int error = 0;
-
-    error |= __vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control);
-    error |= __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control);
-    error |= __vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control);
-
-    return error;
 }
 
 #define GUEST_LAUNCH_DS         0x08
@@ -366,17 +353,40 @@ static void vmx_do_launch(struct vcpu *v
     v->arch.schedule_tail = arch_vmx_do_resume;
 }
 
-/*
- * Initially set the same environement as host.
- */
-static inline int construct_init_vmcs_guest(cpu_user_regs_t *regs)
+static int construct_vmcs(struct vcpu *v, cpu_user_regs_t *regs)
 {
     int error = 0;
+    unsigned long tmp, eflags;
     union vmcs_arbytes arbytes;
-    unsigned long dr7;
-    unsigned long eflags;
-
-    /* MSR */
+
+    /* VMCS controls. */
+    error |= __vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control);
+    error |= __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control);
+    error |= __vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control);
+
+    /* Host data selectors. */
+    error |= __vmwrite(HOST_SS_SELECTOR, __HYPERVISOR_DS);
+    error |= __vmwrite(HOST_DS_SELECTOR, __HYPERVISOR_DS);
+    error |= __vmwrite(HOST_ES_SELECTOR, __HYPERVISOR_DS);
+#if defined(__i386__)
+    error |= __vmwrite(HOST_FS_SELECTOR, __HYPERVISOR_DS);
+    error |= __vmwrite(HOST_GS_SELECTOR, __HYPERVISOR_DS);
+    error |= __vmwrite(HOST_FS_BASE, 0);
+    error |= __vmwrite(HOST_GS_BASE, 0);
+#elif defined(__x86_64__)
+    rdmsrl(MSR_FS_BASE, tmp); error |= __vmwrite(HOST_FS_BASE, tmp);
+    rdmsrl(MSR_GS_BASE, tmp); error |= __vmwrite(HOST_GS_BASE, tmp);
+#endif
+
+    /* Host control registers. */
+    error |= __vmwrite(HOST_CR0, read_cr0());
+    error |= __vmwrite(HOST_CR4, read_cr4());
+
+    /* Host CS:RIP. */
+    error |= __vmwrite(HOST_CS_SELECTOR, __HYPERVISOR_CS);
+    error |= __vmwrite(HOST_RIP, (unsigned long)vmx_asm_vmexit_handler);
+
+    /* MSR intercepts. */
     error |= __vmwrite(VM_EXIT_MSR_LOAD_ADDR, 0);
     error |= __vmwrite(VM_EXIT_MSR_STORE_ADDR, 0);
     error |= __vmwrite(VM_EXIT_MSR_STORE_COUNT, 0);
@@ -395,7 +405,7 @@ static inline int construct_init_vmcs_gu
 
     error |= __vmwrite(GUEST_ACTIVITY_STATE, 0);
 
-    /* Guest Selectors */
+    /* Guest selectors. */
     error |= __vmwrite(GUEST_ES_SELECTOR, GUEST_LAUNCH_DS);
     error |= __vmwrite(GUEST_SS_SELECTOR, GUEST_LAUNCH_DS);
     error |= __vmwrite(GUEST_DS_SELECTOR, GUEST_LAUNCH_DS);
@@ -403,7 +413,7 @@ static inline int construct_init_vmcs_gu
     error |= __vmwrite(GUEST_GS_SELECTOR, GUEST_LAUNCH_DS);
     error |= __vmwrite(GUEST_CS_SELECTOR, GUEST_LAUNCH_CS);
 
-    /* Guest segment bases */
+    /* Guest segment bases. */
     error |= __vmwrite(GUEST_ES_BASE, 0);
     error |= __vmwrite(GUEST_SS_BASE, 0);
     error |= __vmwrite(GUEST_DS_BASE, 0);
@@ -411,7 +421,7 @@ static inline int construct_init_vmcs_gu
     error |= __vmwrite(GUEST_GS_BASE, 0);
     error |= __vmwrite(GUEST_CS_BASE, 0);
 
-    /* Guest segment Limits */
+    /* Guest segment limits. */
     error |= __vmwrite(GUEST_ES_LIMIT, GUEST_SEGMENT_LIMIT);
     error |= __vmwrite(GUEST_SS_LIMIT, GUEST_SEGMENT_LIMIT);
     error |= __vmwrite(GUEST_DS_LIMIT, GUEST_SEGMENT_LIMIT);
@@ -419,7 +429,7 @@ static inline int construct_init_vmcs_gu
     error |= __vmwrite(GUEST_GS_LIMIT, GUEST_SEGMENT_LIMIT);
     error |= __vmwrite(GUEST_CS_LIMIT, GUEST_SEGMENT_LIMIT);
 
-    /* Guest segment AR bytes */
+    /* Guest segment AR bytes. */
     arbytes.bytes = 0;
     arbytes.fields.seg_type = 0x3;          /* type = 3 */
     arbytes.fields.s = 1;                   /* code or data, i.e. not system */
@@ -428,131 +438,54 @@ static inline int construct_init_vmcs_gu
     arbytes.fields.default_ops_size = 1;    /* 32-bit */
     arbytes.fields.g = 1;
     arbytes.fields.null_bit = 0;            /* not null */
-
     error |= __vmwrite(GUEST_ES_AR_BYTES, arbytes.bytes);
     error |= __vmwrite(GUEST_SS_AR_BYTES, arbytes.bytes);
     error |= __vmwrite(GUEST_DS_AR_BYTES, arbytes.bytes);
     error |= __vmwrite(GUEST_FS_AR_BYTES, arbytes.bytes);
     error |= __vmwrite(GUEST_GS_AR_BYTES, arbytes.bytes);
-
     arbytes.fields.seg_type = 0xb;          /* type = 0xb */
     error |= __vmwrite(GUEST_CS_AR_BYTES, arbytes.bytes);
 
-    /* Guest GDT */
+    /* Guest GDT. */
     error |= __vmwrite(GUEST_GDTR_BASE, 0);
     error |= __vmwrite(GUEST_GDTR_LIMIT, 0);
 
-    /* Guest IDT */
+    /* Guest IDT. */
     error |= __vmwrite(GUEST_IDTR_BASE, 0);
     error |= __vmwrite(GUEST_IDTR_LIMIT, 0);
 
-    /* Guest LDT & TSS */
+    /* Guest LDT and TSS. */
     arbytes.fields.s = 0;                   /* not code or data segement */
     arbytes.fields.seg_type = 0x2;          /* LTD */
     arbytes.fields.default_ops_size = 0;    /* 16-bit */
     arbytes.fields.g = 0;
     error |= __vmwrite(GUEST_LDTR_AR_BYTES, arbytes.bytes);
-
     arbytes.fields.seg_type = 0xb;          /* 32-bit TSS (busy) */
     error |= __vmwrite(GUEST_TR_AR_BYTES, arbytes.bytes);
-    /* CR3 is set in vmx_final_setup_guest */
 
     error |= __vmwrite(GUEST_RSP, 0);
     error |= __vmwrite(GUEST_RIP, regs->eip);
 
-    /* Guest EFLAGS */
+    /* Guest EFLAGS. */
     eflags = regs->eflags & ~HVM_EFLAGS_RESERVED_0; /* clear 0s */
     eflags |= HVM_EFLAGS_RESERVED_1; /* set 1s */
     error |= __vmwrite(GUEST_RFLAGS, eflags);
 
     error |= __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
-    __asm__ __volatile__ ("mov %%dr7, %0\n" : "=r" (dr7));
-    error |= __vmwrite(GUEST_DR7, dr7);
+    __asm__ __volatile__ ("mov %%dr7, %0\n" : "=r" (tmp));
+    error |= __vmwrite(GUEST_DR7, tmp);
     error |= __vmwrite(VMCS_LINK_POINTER, ~0UL);
 #if defined(__i386__)
     error |= __vmwrite(VMCS_LINK_POINTER_HIGH, ~0UL);
 #endif
 
-    return error;
-}
-
-static inline int construct_vmcs_host(void)
-{
-    int error = 0;
-#ifdef __x86_64__
-    unsigned long fs_base;
-    unsigned long gs_base;
-#endif
-    unsigned long crn;
-
-    /* Host Selectors */
-    error |= __vmwrite(HOST_ES_SELECTOR, __HYPERVISOR_DS);
-    error |= __vmwrite(HOST_SS_SELECTOR, __HYPERVISOR_DS);
-    error |= __vmwrite(HOST_DS_SELECTOR, __HYPERVISOR_DS);
-#if defined(__i386__)
-    error |= __vmwrite(HOST_FS_SELECTOR, __HYPERVISOR_DS);
-    error |= __vmwrite(HOST_GS_SELECTOR, __HYPERVISOR_DS);
-    error |= __vmwrite(HOST_FS_BASE, 0);
-    error |= __vmwrite(HOST_GS_BASE, 0);
-
-#else
-    rdmsrl(MSR_FS_BASE, fs_base);
-    rdmsrl(MSR_GS_BASE, gs_base);
-    error |= __vmwrite(HOST_FS_BASE, fs_base);
-    error |= __vmwrite(HOST_GS_BASE, gs_base);
-
-#endif
-    error |= __vmwrite(HOST_CS_SELECTOR, __HYPERVISOR_CS);
-
-    __asm__ __volatile__ ("mov %%cr0,%0" : "=r" (crn) : );
-    error |= __vmwrite(HOST_CR0, crn); /* same CR0 */
-
-    /* CR3 is set in vmx_final_setup_hostos */
-    __asm__ __volatile__ ("mov %%cr4,%0" : "=r" (crn) : );
-    error |= __vmwrite(HOST_CR4, crn);
-
-    error |= __vmwrite(HOST_RIP, (unsigned long) vmx_asm_vmexit_handler);
-
-    return error;
-}
-
-/*
- * the working VMCS pointer has been set properly
- * just before entering this function.
- */
-static int construct_vmcs(struct vcpu *v,
-                          cpu_user_regs_t *regs)
-{
-    struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx;
-    int error;
-
-    if ( (error = construct_vmcs_controls(arch_vmx)) ) {
-        printk("construct_vmcs: construct_vmcs_controls failed.\n");
-        return error;
-    }
-
-    /* host selectors */
-    if ( (error = construct_vmcs_host()) ) {
-        printk("construct_vmcs: construct_vmcs_host failed.\n");
-        return error;
-    }
-
-    /* guest selectors */
-    if ( (error = construct_init_vmcs_guest(regs)) ) {
-        printk("construct_vmcs: construct_vmcs_guest failed.\n");
-        return error;
-    }
-
-    if ( (error = __vmwrite(EXCEPTION_BITMAP,
-                            MONITOR_DEFAULT_EXCEPTION_BITMAP)) ) {
-        printk("construct_vmcs: setting exception bitmap failed.\n");
-        return error;
-    }
+    error |= __vmwrite(EXCEPTION_BITMAP,
+                       MONITOR_DEFAULT_EXCEPTION_BITMAP);
 
     if ( regs->eflags & EF_TF )
-        error = __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
+        error |= __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
     else
-        error = __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
+        error |= __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
 
     return error;
 }
diff -r 31985f348d2e -r e793dad2114d xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Mon Nov 06 09:46:13 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Mon Nov 06 11:03:04 2006 +0000
@@ -566,8 +566,6 @@ static unsigned long vmx_get_ctrl_reg(st
     return 0;                   /* dummy */
 }
 
-
-
 /* Make sure that xen intercepts any FP accesses from current */
 static void vmx_stts(struct vcpu *v)
 {
@@ -591,19 +589,15 @@ static void vmx_stts(struct vcpu *v)
     }
 }
 
-
 static void vmx_set_tsc_offset(struct vcpu *v, u64 offset)
 {
-    /* VMX depends on operating on the current vcpu */
-    ASSERT(v == current);
-
+    vmx_vmcs_enter(v);
     __vmwrite(TSC_OFFSET, offset);
 #if defined (__i386__)
     __vmwrite(TSC_OFFSET_HIGH, offset >> 32);
 #endif
-}
-
-
+    vmx_vmcs_exit(v);
+}
 
 /* SMP VMX guest support */
 static void vmx_init_ap_context(struct vcpu_guest_context *ctxt,
diff -r 31985f348d2e -r e793dad2114d xen/common/domain.c
--- a/xen/common/domain.c       Mon Nov 06 09:46:13 2006 +0000
+++ b/xen/common/domain.c       Mon Nov 06 11:03:04 2006 +0000
@@ -64,12 +64,16 @@ void free_domain(struct domain *d)
     struct vcpu *v;
     int i;
 
+    for ( i = MAX_VIRT_CPUS-1; i >= 0; i-- )
+    {
+        if ( (v = d->vcpu[i]) == NULL )
+            continue;
+        vcpu_destroy(v);
+        sched_destroy_vcpu(v);
+        free_vcpu_struct(v);
+    }
+
     sched_destroy_domain(d);
-
-    for ( i = MAX_VIRT_CPUS-1; i >= 0; i-- )
-        if ( (v = d->vcpu[i]) != NULL )
-            free_vcpu_struct(v);
-
     xfree(d);
 }
 
@@ -80,7 +84,7 @@ struct vcpu *alloc_vcpu(
 
     BUG_ON(d->vcpu[vcpu_id] != NULL);
 
-    if ( (v = alloc_vcpu_struct(d, vcpu_id)) == NULL )
+    if ( (v = alloc_vcpu_struct()) == NULL )
         return NULL;
 
     v->domain = d;
@@ -94,8 +98,15 @@ struct vcpu *alloc_vcpu(
     if ( (vcpu_id != 0) && !is_idle_domain(d) )
         set_bit(_VCPUF_down, &v->vcpu_flags);
 
-    if ( sched_init_vcpu(v, cpu_id) < 0 )
-    {
+    if ( sched_init_vcpu(v, cpu_id) != 0 )
+    {
+        free_vcpu_struct(v);
+        return NULL;
+    }
+
+    if ( vcpu_initialise(v) != 0 )
+    {
+        sched_destroy_vcpu(v);
         free_vcpu_struct(v);
         return NULL;
     }
@@ -151,6 +162,9 @@ struct domain *domain_create(domid_t dom
     d->iomem_caps = rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_hex);
     d->irq_caps   = rangeset_new(d, "Interrupts", 0);
     if ( (d->iomem_caps == NULL) || (d->irq_caps == NULL) )
+        goto fail4;
+
+    if ( sched_init_domain(d) != 0 )
         goto fail4;
 
     if ( !is_idle_domain(d) )
diff -r 31985f348d2e -r e793dad2114d xen/common/sched_credit.c
--- a/xen/common/sched_credit.c Mon Nov 06 09:46:13 2006 +0000
+++ b/xen/common/sched_credit.c Mon Nov 06 11:03:04 2006 +0000
@@ -115,8 +115,10 @@
     _MACRO(steal_peer_idle)                 \
     _MACRO(steal_peer_running)              \
     _MACRO(steal_peer_pinned)               \
+    _MACRO(dom_init)                        \
+    _MACRO(dom_destroy)                     \
     _MACRO(vcpu_init)                       \
-    _MACRO(dom_destroy)
+    _MACRO(vcpu_destroy)
 
 #ifndef NDEBUG
 #define CSCHED_STATS_EXPAND_CHECKS(_MACRO)  \
@@ -454,43 +456,14 @@ csched_vcpu_init(struct vcpu *vc)
 csched_vcpu_init(struct vcpu *vc)
 {
     struct domain * const dom = vc->domain;
-    struct csched_dom *sdom;
+    struct csched_dom *sdom = CSCHED_DOM(dom);
     struct csched_vcpu *svc;
-    int16_t pri;
 
     CSCHED_STAT_CRANK(vcpu_init);
-
-    /* Allocate, if appropriate, per-domain info */
-    if ( is_idle_vcpu(vc) )
-    {
-        sdom = NULL;
-        pri = CSCHED_PRI_IDLE;
-    }
-    else if ( CSCHED_DOM(dom) )
-    {
-        sdom = CSCHED_DOM(dom);
-        pri = CSCHED_PRI_TS_UNDER;
-    }
-    else 
-    {
-        sdom = xmalloc(struct csched_dom);
-        if ( !sdom )
-            return -1;
-
-        /* Initialize credit and weight */
-        INIT_LIST_HEAD(&sdom->active_vcpu);
-        sdom->active_vcpu_count = 0;
-        INIT_LIST_HEAD(&sdom->active_sdom_elem);
-        sdom->dom = dom;
-        sdom->weight = CSCHED_DEFAULT_WEIGHT;
-        sdom->cap = 0U;
-        dom->sched_priv = sdom;
-        pri = CSCHED_PRI_TS_UNDER;
-    }
 
     /* Allocate per-VCPU info */
     svc = xmalloc(struct csched_vcpu);
-    if ( !svc )
+    if ( svc == NULL )
         return -1;
 
     INIT_LIST_HEAD(&svc->runq_elem);
@@ -498,7 +471,7 @@ csched_vcpu_init(struct vcpu *vc)
     svc->sdom = sdom;
     svc->vcpu = vc;
     atomic_set(&svc->credit, 0);
-    svc->pri = pri;
+    svc->pri = is_idle_domain(dom) ? CSCHED_PRI_IDLE : CSCHED_PRI_TS_UNDER;
     memset(&svc->stats, 0, sizeof(svc->stats));
     vc->sched_priv = svc;
 
@@ -521,11 +494,13 @@ csched_vcpu_init(struct vcpu *vc)
 }
 
 static void
-csched_vcpu_free(struct vcpu *vc)
+csched_vcpu_destroy(struct vcpu *vc)
 {
     struct csched_vcpu * const svc = CSCHED_VCPU(vc);
     struct csched_dom * const sdom = svc->sdom;
     unsigned long flags;
+
+    CSCHED_STAT_CRANK(vcpu_destroy);
 
     BUG_ON( sdom == NULL );
     BUG_ON( !list_empty(&svc->runq_elem) );
@@ -641,19 +616,38 @@ csched_dom_cntl(
     return 0;
 }
 
+static int
+csched_dom_init(struct domain *dom)
+{
+    struct csched_dom *sdom;
+
+    CSCHED_STAT_CRANK(dom_init);
+
+    if ( is_idle_domain(dom) )
+        return 0;
+
+    sdom = xmalloc(struct csched_dom);
+    if ( sdom == NULL )
+        return -ENOMEM;
+
+    /* Initialize credit and weight */
+    INIT_LIST_HEAD(&sdom->active_vcpu);
+    sdom->active_vcpu_count = 0;
+    INIT_LIST_HEAD(&sdom->active_sdom_elem);
+    sdom->dom = dom;
+    sdom->weight = CSCHED_DEFAULT_WEIGHT;
+    sdom->cap = 0U;
+    dom->sched_priv = sdom;
+
+    return 0;
+}
+
 static void
 csched_dom_destroy(struct domain *dom)
 {
     struct csched_dom * const sdom = CSCHED_DOM(dom);
-    int i;
 
     CSCHED_STAT_CRANK(dom_destroy);
-
-    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-    {
-        if ( dom->vcpu[i] )
-            csched_vcpu_free(dom->vcpu[i]);
-    }
 
     xfree(sdom);
 }
@@ -1226,8 +1220,11 @@ struct scheduler sched_credit_def = {
     .opt_name       = "credit",
     .sched_id       = XEN_SCHEDULER_CREDIT,
 
+    .init_domain    = csched_dom_init,
+    .destroy_domain = csched_dom_destroy,
+
     .init_vcpu      = csched_vcpu_init,
-    .destroy_domain = csched_dom_destroy,
+    .destroy_vcpu   = csched_vcpu_destroy,
 
     .sleep          = csched_vcpu_sleep,
     .wake           = csched_vcpu_wake,
diff -r 31985f348d2e -r e793dad2114d xen/common/sched_sedf.c
--- a/xen/common/sched_sedf.c   Mon Nov 06 09:46:13 2006 +0000
+++ b/xen/common/sched_sedf.c   Mon Nov 06 11:03:04 2006 +0000
@@ -333,14 +333,6 @@ static int sedf_init_vcpu(struct vcpu *v
 {
     struct sedf_vcpu_info *inf;
 
-    if ( v->domain->sched_priv == NULL )
-    {
-        v->domain->sched_priv = xmalloc(struct sedf_dom_info);
-        if ( v->domain->sched_priv == NULL )
-            return -1;
-        memset(v->domain->sched_priv, 0, sizeof(struct sedf_dom_info));
-    }
-
     if ( (v->sched_priv = xmalloc(struct sedf_vcpu_info)) == NULL )
         return -1;
     memset(v->sched_priv, 0, sizeof(struct sedf_vcpu_info));
@@ -398,15 +390,25 @@ static int sedf_init_vcpu(struct vcpu *v
     return 0;
 }
 
+static void sedf_destroy_vcpu(struct vcpu *v)
+{
+    xfree(v->sched_priv);
+}
+
+static int sedf_init_domain(struct domain *d)
+{
+    d->sched_priv = xmalloc(struct sedf_dom_info);
+    if ( d->sched_priv == NULL )
+        return -ENOMEM;
+
+    memset(d->sched_priv, 0, sizeof(struct sedf_dom_info));
+
+    return 0;
+}
+
 static void sedf_destroy_domain(struct domain *d)
 {
-    int i;
-
     xfree(d->sched_priv);
- 
-    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-        if ( d->vcpu[i] )
-            xfree(d->vcpu[i]->sched_priv);
 }
 
 /*
@@ -1427,8 +1429,11 @@ struct scheduler sched_sedf_def = {
     .opt_name = "sedf",
     .sched_id = XEN_SCHEDULER_SEDF,
     
+    .init_domain    = sedf_init_domain,
+    .destroy_domain = sedf_destroy_domain,
+
     .init_vcpu      = sedf_init_vcpu,
-    .destroy_domain = sedf_destroy_domain,
+    .destroy_vcpu   = sedf_destroy_vcpu,
 
     .do_schedule    = sedf_do_schedule,
     .dump_cpu_state = sedf_dump_cpu_state,
diff -r 31985f348d2e -r e793dad2114d xen/common/schedule.c
--- a/xen/common/schedule.c     Mon Nov 06 09:46:13 2006 +0000
+++ b/xen/common/schedule.c     Mon Nov 06 11:03:04 2006 +0000
@@ -132,17 +132,20 @@ int sched_init_vcpu(struct vcpu *v, unsi
     return SCHED_OP(init_vcpu, v);
 }
 
+void sched_destroy_vcpu(struct vcpu *v)
+{
+    kill_timer(&v->timer);
+    kill_timer(&v->poll_timer);
+    SCHED_OP(destroy_vcpu, v);
+}
+
+int sched_init_domain(struct domain *d)
+{
+    return SCHED_OP(init_domain, d);
+}
+
 void sched_destroy_domain(struct domain *d)
 {
-    struct vcpu *v;
-
-    for_each_vcpu ( d, v )
-    {
-        kill_timer(&v->timer);
-        kill_timer(&v->poll_timer);
-        TRACE_2D(TRC_SCHED_DOM_REM, v->domain->domain_id, v->vcpu_id);
-    }
-
     SCHED_OP(destroy_domain, d);
 }
 
diff -r 31985f348d2e -r e793dad2114d xen/include/xen/domain.h
--- a/xen/include/xen/domain.h  Mon Nov 06 09:46:13 2006 +0000
+++ b/xen/include/xen/domain.h  Mon Nov 06 11:03:04 2006 +0000
@@ -15,9 +15,19 @@ void free_domain(struct domain *d);
  * Arch-specifics.
  */
 
-struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id);
+/* Allocate/free a VCPU structure. */
+struct vcpu *alloc_vcpu_struct(void);
+void free_vcpu_struct(struct vcpu *v);
 
-void free_vcpu_struct(struct vcpu *v);
+/*
+ * Initialise/destroy arch-specific details of a VCPU.
+ *  - vcpu_initialise() is called after the basic generic fields of the
+ *    VCPU structure are initialised. Many operations can be applied to the
+ *    VCPU at this point (e.g., vcpu_pause()).
+ *  - vcpu_destroy() is called only if vcpu_initialise() previously succeeded.
+ */
+int  vcpu_initialise(struct vcpu *v);
+void vcpu_destroy(struct vcpu *v);
 
 int arch_domain_create(struct domain *d);
 
diff -r 31985f348d2e -r e793dad2114d xen/include/xen/sched-if.h
--- a/xen/include/xen/sched-if.h        Mon Nov 06 09:46:13 2006 +0000
+++ b/xen/include/xen/sched-if.h        Mon Nov 06 11:03:04 2006 +0000
@@ -63,8 +63,11 @@ struct scheduler {
     void         (*init)           (void);
     void         (*tick)           (unsigned int cpu);
 
+    int          (*init_domain)    (struct domain *);
+    void         (*destroy_domain) (struct domain *);
+
     int          (*init_vcpu)      (struct vcpu *);
-    void         (*destroy_domain) (struct domain *);
+    void         (*destroy_vcpu)   (struct vcpu *);
 
     void         (*sleep)          (struct vcpu *);
     void         (*wake)           (struct vcpu *);
diff -r 31985f348d2e -r e793dad2114d xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Mon Nov 06 09:46:13 2006 +0000
+++ b/xen/include/xen/sched.h   Mon Nov 06 11:03:04 2006 +0000
@@ -291,7 +291,9 @@ void scheduler_init(void);
 void scheduler_init(void);
 void schedulers_start(void);
 int  sched_init_vcpu(struct vcpu *v, unsigned int processor);
-void sched_destroy_domain(struct domain *);
+void sched_destroy_vcpu(struct vcpu *v);
+int  sched_init_domain(struct domain *d);
+void sched_destroy_domain(struct domain *d);
 long sched_adjust(struct domain *, struct xen_domctl_scheduler_op *);
 int  sched_id(void);
 void vcpu_wake(struct vcpu *d);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [XEN] Re-jig VCPU initialisation -- VMX init requires generic VCPU, Xen patchbot-unstable <=