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] [IA64] Change vCPU initialization to avoi

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [IA64] Change vCPU initialization to avoid domVTi privregs memory leak
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 18 Jan 2007 21:10:59 -0800
Delivery-date: Thu, 18 Jan 2007 21:13:50 -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 awilliam@xxxxxxxxxxxx
# Date 1168969237 25200
# Node ID 7d8670a30445e50fad19a0885113376245727f65
# Parent  a2b2b2a011f1d406d49caba478020f3b2b173cb8
[IA64] Change vCPU initialization to avoid domVTi privregs memory leak

1) This patch moved some processing from vcpu_initialise() and
   added a new function vcpu_late_initialise().
   It executes the following initializations for VCPU of
   dom0/domU.
    - Allocate the VHPT
    - Allocate the privregs area and assign these pages into
      guest pseudo physical address space.
    - Set the tlbflush_timestamp.

   It is executed in the following sequence.

   dom0:
     start_kernel()
       ->domain_create()
       ->alloc_vcpu(VCPU0)
         ->alloc_vcpu_struct(VCPU0)
         ->vcpu_initialise(VCPU0)
       ->vcpu_late_initialise(VCPU0)

       ->construct_dom0
         ->alloc_vcpu(othe VCPUs)
           ->alloc_vcpu_struct(other VCPUs)
           ->vcpu_initialise(other VCPUs)

     ia64_hypercall(FW_HYPERCALL_IPI)
       ->fw_hypercall_ipi(XEN_SAL_BOOT_RENDEZ_VEC)
         ->arch_set_info_guest(other VCPUs)
           ->vcpu_late_initialise(other VCPUs)

   domU:
     do_domctl(XEN_DOMCTL_createdomain)
       ->domain_create()

     do_domctl(XEN_DOMCTL_max_vcpus)
       ->alloc_vcpu(all VCPUs)
         ->alloc_vcpu_struct(all VCPUs)
         ->vcpu_initialise(all VCPUs)

     do_domctl(XEN_DOMCTL_setvcpucontext)
       ->set_info_guest(VCPU0)
         ->arch_set_info_guest(VCPU0)
           ->vcpu_late_initialise(VCPU0)

     ia64_hypercall(FW_HYPERCALL_IPI)
       ->fw_hypercall_ipi(XEN_SAL_BOOT_RENDEZ_VEC)
         ->arch_set_info_guest(other VCPUs)
           ->vcpu_late_initialise(other VCPUs)

2) This patch modified the domain_set_shared_info_va().
   Currently, initialization of arch.privregs->interrupt_mask_addr
   of all VCPUs is executed in domain_set_shared_info_va().
   However, allocation of privregs area is late by modified of 1).
   Therefore, this patch modified initialization of
   arch.privregs->interrupt_mask_addr to the following sequence.

   dom0 and domU:
     ia64_hypercall(FW_HYPERCALL_SET_SHARED_INFO_VA)
       ->domain_set_shared_info_va()
         Initialize interrupt_mask_addr of VCPU0

     ia64_hypercall(FW_HYPERCALL_IPI)
       ->fw_hypercall_ipi(XEN_SAL_BOOT_RENDEZ_VEC)
         ->arch_set_info_guest(other VCPUs)
           ->vcpu_late_initialise(other VCPUs)
           Initialize interrupt_mask_addr of other VCPUs

Signed-off-by: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>
---
 xen/arch/ia64/xen/dom0_ops.c  |   10 ---
 xen/arch/ia64/xen/domain.c    |  128 +++++++++++++++++++++---------------------
 xen/arch/ia64/xen/xensetup.c  |    6 +
 xen/include/asm-ia64/domain.h |    1 
 4 files changed, 72 insertions(+), 73 deletions(-)

diff -r a2b2b2a011f1 -r 7d8670a30445 xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c      Mon Jan 15 15:15:26 2007 -0700
+++ b/xen/arch/ia64/xen/dom0_ops.c      Tue Jan 16 10:40:37 2007 -0700
@@ -103,16 +103,6 @@ long arch_do_domctl(xen_domctl_t *op, XE
                     ret = -EINVAL;
                     break;
                 }
-                if (!d->arch.is_vti) {
-                    struct vcpu *v;
-                    for_each_vcpu(d, v) {
-                        BUG_ON(v->arch.privregs == NULL);
-                        free_domheap_pages(virt_to_page(v->arch.privregs),
-                                      get_order_from_shift(XMAPPEDREGS_SHIFT));
-                        v->arch.privregs = NULL;
-                        relinquish_vcpu_resources(v);
-                    }
-                }
                 d->arch.is_vti = 1;
                 vmx_setup_platform(d);
             }
diff -r a2b2b2a011f1 -r 7d8670a30445 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Mon Jan 15 15:15:26 2007 -0700
+++ b/xen/arch/ia64/xen/domain.c        Tue Jan 16 10:40:37 2007 -0700
@@ -305,24 +305,14 @@ void hlt_timer_fn(void *data)
 
 void relinquish_vcpu_resources(struct vcpu *v)
 {
-    if (HAS_PERVCPU_VHPT(v->domain))
-        pervcpu_vhpt_free(v);
-    if (v->arch.privregs != NULL) {
-        // this might be called by arch_do_domctl() with 
XEN_DOMCTL_arch_setup()
-        // for domVTi.
-        if (!(atomic_read(&v->domain->refcnt) & DOMAIN_DESTROYED)) {
-            unsigned long i;
-            for (i = 0; i < XMAPPEDREGS_SIZE; i += PAGE_SIZE)
-                guest_physmap_remove_page(v->domain,
-                    IA64_XMAPPEDREGS_PADDR(v->vcpu_id) + i,
-                    virt_to_maddr(v->arch.privregs + i));
-        }
-
-        free_xenheap_pages(v->arch.privregs,
-                           get_order_from_shift(XMAPPEDREGS_SHIFT));
-        v->arch.privregs = NULL;
-    }
-    kill_timer(&v->arch.hlt_timer);
+       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)
@@ -361,36 +351,8 @@ int vcpu_initialise(struct vcpu *v)
 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) {
-               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);
-               v->arch.privregs = alloc_xenheap_pages(order);
-               BUG_ON(v->arch.privregs == NULL);
-               memset(v->arch.privregs, 0, 1 << XMAPPEDREGS_SHIFT);
-               for (i = 0; i < (1 << order); i++)
-                   share_xen_page_with_guest(virt_to_page(v->arch.privregs) +
-                                             i, d, XENSHARE_writable);
-               /*
-                * XXX IA64_XMAPPEDREGS_PADDR
-                * assign these pages into guest pseudo physical address
-                * space for dom0 to map this page by gmfn.
-                * this is necessary for domain save, restore and dump-core.
-                */
-               for (i = 0; i < XMAPPEDREGS_SIZE; i += PAGE_SIZE)
-                   assign_domain_page(d, IA64_XMAPPEDREGS_PADDR(v->vcpu_id) + 
i,
-                                      virt_to_maddr(v->arch.privregs + i));
-
-               tlbflush_update_time(&v->arch.tlbflush_timestamp,
-                                    tlbflush_current_time());
-           }
-
            v->arch.metaphysical_rr0 = d->arch.metaphysical_rr0;
            v->arch.metaphysical_rr4 = d->arch.metaphysical_rr4;
            v->arch.metaphysical_saved_rr0 = d->arch.metaphysical_rr0;
@@ -416,6 +378,41 @@ int vcpu_initialise(struct vcpu *v)
        if (!VMX_DOMAIN(v))
                init_timer(&v->arch.hlt_timer, hlt_timer_fn, v,
                           first_cpu(cpu_online_map));
+
+       return 0;
+}
+
+int vcpu_late_initialise(struct vcpu *v)
+{
+       struct domain *d = v->domain;
+       int rc, order, i;
+
+       if (HAS_PERVCPU_VHPT(d)) {
+               rc = pervcpu_vhpt_alloc(v);
+               if (rc != 0)
+                       return rc;
+       }
+
+       /* Create privregs page. */
+       order = get_order_from_shift(XMAPPEDREGS_SHIFT);
+       v->arch.privregs = alloc_xenheap_pages(order);
+       BUG_ON(v->arch.privregs == NULL);
+       memset(v->arch.privregs, 0, 1 << XMAPPEDREGS_SHIFT);
+       for (i = 0; i < (1 << order); i++)
+               share_xen_page_with_guest(virt_to_page(v->arch.privregs) + i,
+                                         d, XENSHARE_writable);
+       /*
+        * XXX IA64_XMAPPEDREGS_PADDR
+        * assign these pages into guest pseudo physical address
+        * space for dom0 to map this page by gmfn.
+        * this is necessary for domain save, restore and dump-core.
+        */
+       for (i = 0; i < XMAPPEDREGS_SIZE; i += PAGE_SIZE)
+               assign_domain_page(d, IA64_XMAPPEDREGS_PADDR(v->vcpu_id) + i,
+                                  virt_to_maddr(v->arch.privregs + i));
+
+       tlbflush_update_time(&v->arch.tlbflush_timestamp,
+                            tlbflush_current_time());
 
        return 0;
 }
@@ -553,6 +550,7 @@ int arch_set_info_guest(struct vcpu *v, 
 {
        struct pt_regs *regs = vcpu_regs (v);
        struct domain *d = v->domain;
+       int rc;
        
        *regs = c.nat->user_regs;
        
@@ -582,16 +580,25 @@ int arch_set_info_guest(struct vcpu *v, 
                v->arch.event_callback_ip = er->event_callback_ip;
                v->arch.dcr = er->dcr;
                v->arch.iva = er->iva;
-       }
-       
-       if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
-               return 0;
-       if (d->arch.is_vti)
-               vmx_final_setup_guest(v);
-       
-       /* This overrides some registers.  */
-       vcpu_init_regs(v);
-  
+       }
+
+       if (test_bit(_VCPUF_initialised, &v->vcpu_flags))
+               return 0;
+
+       if (d->arch.is_vti)
+               vmx_final_setup_guest(v);
+       else {
+               rc = vcpu_late_initialise(v);
+               if (rc != 0)
+                       return rc;
+               VCPU(v, interrupt_mask_addr) = 
+                       (unsigned char *) d->arch.shared_info_va +
+                       INT_ENABLE_OFFSET(v);
+       }
+
+       /* This overrides some registers. */
+       vcpu_init_regs(v);
+
        /* Don't redo final setup */
        set_bit(_VCPUF_initialised, &v->vcpu_flags);
        return 0;
@@ -683,7 +690,6 @@ domain_set_shared_info_va (unsigned long
 {
        struct vcpu *v = current;
        struct domain *d = v->domain;
-       struct vcpu *v1;
 
        /* Check virtual address:
           must belong to region 7,
@@ -699,10 +705,8 @@ domain_set_shared_info_va (unsigned long
        printk ("Domain set shared_info_va to 0x%016lx\n", va);
        d->arch.shared_info_va = va;
 
-       for_each_vcpu (d, v1) {
-               VCPU(v1, interrupt_mask_addr) = 
-                       (unsigned char *)va + INT_ENABLE_OFFSET(v1);
-       }
+       VCPU(v, interrupt_mask_addr) = (unsigned char *)va +
+                                      INT_ENABLE_OFFSET(v);
 
        __ia64_per_cpu_var(current_psr_ic_addr) = (int *)(va + XSI_PSR_IC_OFS);
 
@@ -1106,7 +1110,7 @@ int construct_dom0(struct domain *d,
        printk ("Dom0 max_vcpus=%d\n", dom0_max_vcpus);
        for ( i = 1; i < dom0_max_vcpus; i++ )
            if (alloc_vcpu(d, i, i) == NULL)
-               printk ("Cannot allocate dom0 vcpu %d\n", i);
+               panic("Cannot allocate dom0 vcpu %d\n", i);
 
        /* Copy the OS image. */
        loaddomainelfimage(d,image_start);
diff -r a2b2b2a011f1 -r 7d8670a30445 xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c      Mon Jan 15 15:15:26 2007 -0700
+++ b/xen/arch/ia64/xen/xensetup.c      Tue Jan 16 10:40:37 2007 -0700
@@ -249,6 +249,7 @@ void start_kernel(void)
     unsigned long dom0_initrd_start, dom0_initrd_size;
     unsigned long md_end, relo_start, relo_end, relo_size = 0;
     struct domain *idle_domain;
+    struct vcpu *dom0_vcpu0;
     efi_memory_desc_t *kern_md, *last_md, *md;
 #ifdef CONFIG_SMP
     int i;
@@ -503,8 +504,11 @@ printk("num_online_cpus=%d, max_cpus=%d\
 
     /* Create initial domain 0. */
     dom0 = domain_create(0, 0);
-    if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) )
+    if (dom0 == NULL)
         panic("Error creating domain 0\n");
+    dom0_vcpu0 = alloc_vcpu(dom0, 0, 0);
+    if (dom0_vcpu0 == NULL || vcpu_late_initialise(dom0_vcpu0) != 0)
+        panic("Cannot allocate dom0 vcpu 0\n");
 
     dom0->is_privileged = 1;
 
diff -r a2b2b2a011f1 -r 7d8670a30445 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h     Mon Jan 15 15:15:26 2007 -0700
+++ b/xen/include/asm-ia64/domain.h     Tue Jan 16 10:40:37 2007 -0700
@@ -21,6 +21,7 @@ extern void domain_relinquish_resources(
 extern void domain_relinquish_resources(struct domain *);
 struct vcpu;
 extern void relinquish_vcpu_resources(struct vcpu *v);
+extern int vcpu_late_initialise(struct vcpu *v);
 
 /* given a current domain metaphysical address, return the physical address */
 extern unsigned long translate_domain_mpaddr(unsigned long mpaddr,

_______________________________________________
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] [IA64] Change vCPU initialization to avoid domVTi privregs memory leak, Xen patchbot-unstable <=