ia64/xen-unstable
changeset 16325:55b24410ebfc
vt-d: Free memory of g2m_ioport_list.
This patch frees memory of g2m_ioport_list when remove g2m_ioport or
destroy iommu domain to avoid memory leak. In addtion, does some
cleanup on domctl.c.
Signed-off-by: Weidong Han <weidong.han@intel.com>
This patch frees memory of g2m_ioport_list when remove g2m_ioport or
destroy iommu domain to avoid memory leak. In addtion, does some
cleanup on domctl.c.
Signed-off-by: Weidong Han <weidong.han@intel.com>
author | Keir Fraser <keir@xensource.com> |
---|---|
date | Tue Nov 06 09:43:22 2007 +0000 (2007-11-06) |
parents | e2445c775efc |
children | 6c218ca2db7e |
files | xen/arch/x86/domctl.c xen/arch/x86/hvm/vmx/vtd/io.c |
line diff
1.1 --- a/xen/arch/x86/domctl.c Tue Nov 06 09:41:57 2007 +0000 1.2 +++ b/xen/arch/x86/domctl.c Tue Nov 06 09:43:22 2007 +0000 1.3 @@ -535,9 +535,10 @@ long arch_do_domctl( 1.4 if ( !vtd_enabled ) 1.5 break; 1.6 1.7 - if ( unlikely((d = get_domain_by_id(domctl->domain)) == NULL) ) { 1.8 + if ( unlikely((d = get_domain_by_id(domctl->domain)) == NULL) ) 1.9 + { 1.10 gdprintk(XENLOG_ERR, 1.11 - "XEN_DOMCTL_assign_device: get_domain_by_id() failed\n"); 1.12 + "XEN_DOMCTL_assign_device: get_domain_by_id() failed\n"); 1.13 break; 1.14 } 1.15 hd = domain_hvm_iommu(d); 1.16 @@ -548,7 +549,7 @@ long arch_do_domctl( 1.17 break; 1.18 1.19 ret = assign_device(d, bus, devfn); 1.20 - gdprintk(XENLOG_ERR, "XEN_DOMCTL_assign_device: bdf = %x:%x:%x\n", 1.21 + gdprintk(XENLOG_INFO, "XEN_DOMCTL_assign_device: bdf = %x:%x:%x\n", 1.22 bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); 1.23 put_domain(d); 1.24 } 1.25 @@ -569,7 +570,7 @@ long arch_do_domctl( 1.26 gdprintk(XENLOG_ERR, "pt_irq_create_bind failed!\n"); 1.27 rcu_unlock_domain(d); 1.28 } 1.29 - break; 1.30 + break; 1.31 1.32 case XEN_DOMCTL_memory_mapping: 1.33 { 1.34 @@ -587,25 +588,25 @@ long arch_do_domctl( 1.35 if ( unlikely((d = rcu_lock_domain_by_id(domctl->domain)) == NULL) ) 1.36 break; 1.37 1.38 - ret=0; 1.39 - if ( domctl->u.memory_mapping.add_mapping ) 1.40 + ret=0; 1.41 + if ( domctl->u.memory_mapping.add_mapping ) 1.42 { 1.43 gdprintk(XENLOG_INFO, 1.44 "memory_map:add: gfn=%lx mfn=%lx nr_mfns=%lx\n", 1.45 - gfn, mfn, nr_mfns); 1.46 - 1.47 + gfn, mfn, nr_mfns); 1.48 + 1.49 ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1); 1.50 for ( i = 0; i < nr_mfns; i++ ) 1.51 - set_mmio_p2m_entry(d, gfn+i, _mfn(mfn+i)); 1.52 + set_mmio_p2m_entry(d, gfn+i, _mfn(mfn+i)); 1.53 } 1.54 - else 1.55 + else 1.56 { 1.57 gdprintk(XENLOG_INFO, 1.58 "memory_map:remove: gfn=%lx mfn=%lx nr_mfns=%lx\n", 1.59 gfn, mfn, nr_mfns); 1.60 1.61 for ( i = 0; i < nr_mfns; i++ ) 1.62 - clear_mmio_p2m_entry(d, gfn+i); 1.63 + clear_mmio_p2m_entry(d, gfn+i); 1.64 ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1); 1.65 } 1.66 1.67 @@ -644,39 +645,42 @@ long arch_do_domctl( 1.68 gdprintk(XENLOG_INFO, 1.69 "ioport_map:add f_gport=%x f_mport=%x np=%x\n", 1.70 fgp, fmp, np); 1.71 - 1.72 + 1.73 list_for_each_entry(g2m_ioport, &hd->g2m_ioport_list, list) 1.74 - if (g2m_ioport->mport == fmp ) { 1.75 + if (g2m_ioport->mport == fmp ) 1.76 + { 1.77 g2m_ioport->gport = fgp; 1.78 - g2m_ioport->np = np; 1.79 + g2m_ioport->np = np; 1.80 found = 1; 1.81 break; 1.82 } 1.83 - if ( !found ) 1.84 - { 1.85 + if ( !found ) 1.86 + { 1.87 g2m_ioport = xmalloc(struct g2m_ioport); 1.88 g2m_ioport->gport = fgp; 1.89 g2m_ioport->mport = fmp; 1.90 g2m_ioport->np = np; 1.91 list_add_tail(&g2m_ioport->list, &hd->g2m_ioport_list); 1.92 - } 1.93 + } 1.94 ret = ioports_permit_access(d, fmp, fmp + np - 1); 1.95 - 1.96 } 1.97 - else { 1.98 + else 1.99 + { 1.100 gdprintk(XENLOG_INFO, 1.101 "ioport_map:remove f_gport=%x f_mport=%x np=%x\n", 1.102 fgp, fmp, np); 1.103 list_for_each_entry(g2m_ioport, &hd->g2m_ioport_list, list) 1.104 - if ( g2m_ioport->mport == fmp ) { 1.105 + if ( g2m_ioport->mport == fmp ) 1.106 + { 1.107 list_del(&g2m_ioport->list); 1.108 + xfree(g2m_ioport); 1.109 break; 1.110 } 1.111 ret = ioports_deny_access(d, fmp, fmp + np - 1); 1.112 } 1.113 rcu_unlock_domain(d); 1.114 } 1.115 - break; 1.116 + break; 1.117 1.118 case XEN_DOMCTL_pin_mem_cacheattr: 1.119 {
2.1 --- a/xen/arch/x86/hvm/vmx/vtd/io.c Tue Nov 06 09:41:57 2007 +0000 2.2 +++ b/xen/arch/x86/hvm/vmx/vtd/io.c Tue Nov 06 09:43:22 2007 +0000 2.3 @@ -164,6 +164,9 @@ void iommu_domain_destroy(struct domain 2.4 { 2.5 struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci; 2.6 uint32_t i; 2.7 + struct hvm_iommu *hd = domain_hvm_iommu(d); 2.8 + struct list_head *ioport_list, *tmp; 2.9 + struct g2m_ioport *ioport; 2.10 2.11 if ( !vtd_enabled ) 2.12 return; 2.13 @@ -180,5 +183,15 @@ void iommu_domain_destroy(struct domain 2.14 xfree(hvm_irq_dpci); 2.15 } 2.16 2.17 + if ( hd ) 2.18 + { 2.19 + list_for_each_safe ( ioport_list, tmp, &hd->g2m_ioport_list ) 2.20 + { 2.21 + ioport = list_entry(ioport_list, struct g2m_ioport, list); 2.22 + list_del(&ioport->list); 2.23 + xfree(ioport); 2.24 + } 2.25 + } 2.26 + 2.27 iommu_domain_teardown(d); 2.28 }