# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1154584176 -32400 # Node ID 30f69cd84f487c0fe72faec3367ed114528bd2e8 # Parent 561df7d9cecc92d08bcc34ed45880062b06dc2e6 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 561df7d9cecc -r 30f69cd84f48 xen/arch/ia64/asm-offsets.c --- a/xen/arch/ia64/asm-offsets.c Wed Aug 02 15:09:56 2006 -0600 +++ b/xen/arch/ia64/asm-offsets.c Thu Aug 03 14:49:36 2006 +0900 @@ -32,6 +32,7 @@ void foo(void) DEFINE(IA64_CPU_SIZE, sizeof (struct cpuinfo_ia64)); DEFINE(UNW_FRAME_INFO_SIZE, sizeof (struct unw_frame_info)); DEFINE(SHARED_INFO_SIZE, sizeof (struct shared_info)); + DEFINE(MAPPED_REGS_T_SIZE, sizeof (mapped_regs_t)); BLANK(); DEFINE(IA64_MCA_CPU_INIT_STACK_OFFSET, offsetof (struct ia64_mca_cpu, init_stack)); diff -r 561df7d9cecc -r 30f69cd84f48 xen/arch/ia64/xen/dom0_ops.c --- a/xen/arch/ia64/xen/dom0_ops.c Wed Aug 02 15:09:56 2006 -0600 +++ b/xen/arch/ia64/xen/dom0_ops.c Thu Aug 03 14:49:36 2006 +0900 @@ -122,6 +122,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 561df7d9cecc -r 30f69cd84f48 xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Wed Aug 02 15:09:56 2006 -0600 +++ b/xen/arch/ia64/xen/domain.c Thu Aug 03 14:49:36 2006 +0900 @@ -261,13 +261,23 @@ 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. */ +// compile time BUG_ON(get_order(sizeof(mapped_regs_t)) != +// get_order_from_shift(XMAPPEDREGS_SHIFT)) +#if !(((1 << (XMAPPEDREGS_SHIFT - 1)) < MAPPED_REGS_T_SIZE) && \ + (MAPPED_REGS_T_SIZE < (1 << (XMAPPEDREGS_SHIFT + 1)))) +# error "XMAPPEDREGS_SHIFT doesn't match sizeof(mapped_regs_t)." +#endif + 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); } v->arch.metaphysical_rr0 = d->arch.metaphysical_rr0; @@ -295,15 +305,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 561df7d9cecc -r 30f69cd84f48 xen/include/asm-ia64/domain.h --- a/xen/include/asm-ia64/domain.h Wed Aug 02 15:09:56 2006 -0600 +++ b/xen/include/asm-ia64/domain.h Thu Aug 03 14:49:36 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,