# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1154082524 -32400 # Node ID a8eddc3f1f82a90047834b063cdeb21cf31eef8f # Parent 2d73714911c2103958e3bc82957a78cacf4d8bfe privregs clean up. memory leak occures when VT-i domain is created. When domain is created, xend sets max vcpu before domain setup. So alloc_vcpu_struct() think the domain is normal domU, not domVTI. And next xend set the domain as domVTI. so the memory is allocated for domU won't be freed. PATCHNAME: dom_vti_memory_leak Signed-off-by: Isaku Yamahata diff -r 2d73714911c2 -r a8eddc3f1f82 xen/arch/ia64/xen/dom0_ops.c --- a/xen/arch/ia64/xen/dom0_ops.c Thu Jul 27 10:43:34 2006 -0600 +++ b/xen/arch/ia64/xen/dom0_ops.c Fri Jul 28 19:28:44 2006 +0900 @@ -245,6 +245,14 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_ 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)); + relinquish_vcpu_resources(v); + } + } d->arch.is_vti = 1; vmx_setup_platform(d); } diff -r 2d73714911c2 -r a8eddc3f1f82 xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Thu Jul 27 10:43:34 2006 -0600 +++ b/xen/arch/ia64/xen/domain.c Fri Jul 28 19:28:44 2006 +0900 @@ -261,13 +261,19 @@ struct vcpu *alloc_vcpu_struct(struct do if (!is_idle_domain(d)) { if (!d->arch.is_vti) { - /* Create privregs page only if not VTi. */ - v->arch.privregs = - alloc_xenheap_pages(get_order(sizeof(mapped_regs_t))); - BUG_ON(v->arch.privregs == NULL); - memset(v->arch.privregs, 0, PAGE_SIZE); - share_xen_page_with_guest(virt_to_page(v->arch.privregs), - d, XENSHARE_writable); + int order; + int i; + + /* Create privregs page only if not VTi. */ + order = get_order_from_shift(XMAPPEDREGS_SHIFT); + BUG_ON(get_order(sizeof(mapped_regs_t)) != + 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 << order) * PAGE_SIZE); + for (i = 0; i < (1 << order); i++) + share_xen_page_with_guest(virt_to_page(v->arch.privregs) + i, + d, XENSHARE_writable); } v->arch.metaphysical_rr0 = d->arch.metaphysical_rr0; @@ -295,15 +301,21 @@ struct vcpu *alloc_vcpu_struct(struct do return v; } +void relinquish_vcpu_resources(struct vcpu *v) +{ + if (v->arch.privregs != NULL) { + free_xenheap_pages(v->arch.privregs, + get_order_from_shift(XMAPPEDREGS_SHIFT)); + v->arch.privregs = NULL; + } +} + void free_vcpu_struct(struct vcpu *v) { if (VMX_DOMAIN(v)) vmx_relinquish_vcpu_resources(v); - else { - if (v->arch.privregs != NULL) - free_xenheap_pages(v->arch.privregs, - get_order_from_shift(XMAPPEDREGS_SHIFT)); - } + else + relinquish_vcpu_resources(v); free_xenheap_pages(v, KERNEL_STACK_SIZE_ORDER); } diff -r 2d73714911c2 -r a8eddc3f1f82 xen/include/asm-ia64/domain.h --- a/xen/include/asm-ia64/domain.h Thu Jul 27 10:43:34 2006 -0600 +++ b/xen/include/asm-ia64/domain.h Fri Jul 28 19:28:44 2006 +0900 @@ -37,6 +37,8 @@ p2m_entry_retry(struct p2m_entry* entry) } extern void domain_relinquish_resources(struct domain *); +struct vcpu; +extern void relinquish_vcpu_resources(struct vcpu *v); /* given a current domain metaphysical address, return the physical address */ extern unsigned long translate_domain_mpaddr(unsigned long mpaddr,