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>
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  }