[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [IA64] Change vCPU initialization to avoid domVTi privregs memory leak
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |