ia64/xen-unstable

changeset 17506:2ebb7f79e3bb

vt-d: Clean up and fix dom0 initialisation.
Based on a patch by Weidong Han <weidong.han@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Apr 22 19:07:48 2008 +0100 (2008-04-22)
parents 5355726f01b6
children 4f9284a5d3ab
files xen/drivers/passthrough/vtd/iommu.c
line diff
     1.1 --- a/xen/drivers/passthrough/vtd/iommu.c	Tue Apr 22 14:40:34 2008 +0100
     1.2 +++ b/xen/drivers/passthrough/vtd/iommu.c	Tue Apr 22 19:07:48 2008 +0100
     1.3 @@ -41,6 +41,9 @@ static spinlock_t domid_bitmap_lock;    
     1.4  static int domid_bitmap_size;           /* domain id bitmap size in bits */
     1.5  static unsigned long *domid_bitmap;     /* iommu domain id bitmap */
     1.6  
     1.7 +static void setup_dom0_devices(struct domain *d);
     1.8 +static void setup_dom0_rmrr(struct domain *d);
     1.9 +
    1.10  #define DID_FIELD_WIDTH 16
    1.11  #define DID_HIGH_OFFSET 8
    1.12  static void context_set_domain_id(struct context_entry *context,
    1.13 @@ -1033,7 +1036,6 @@ static int iommu_alloc(struct acpi_drhd_
    1.14      spin_lock_init(&iommu->lock);
    1.15      spin_lock_init(&iommu->register_lock);
    1.16  
    1.17 -
    1.18      drhd->iommu = iommu;
    1.19      return 0;
    1.20  }
    1.21 @@ -1068,15 +1070,17 @@ static void iommu_free(struct acpi_drhd_
    1.22          agaw = 64;                              \
    1.23      agaw; })
    1.24  
    1.25 -static int intel_iommu_domain_init(struct domain *domain)
    1.26 +static int intel_iommu_domain_init(struct domain *d)
    1.27  {
    1.28 -    struct hvm_iommu *hd = domain_hvm_iommu(domain);
    1.29 +    struct hvm_iommu *hd = domain_hvm_iommu(d);
    1.30      struct iommu *iommu = NULL;
    1.31      int guest_width = DEFAULT_DOMAIN_ADDRESS_WIDTH;
    1.32 -    int adjust_width, agaw;
    1.33 +    int i, adjust_width, agaw;
    1.34      unsigned long sagaw;
    1.35      struct acpi_drhd_unit *drhd;
    1.36  
    1.37 +    INIT_LIST_HEAD(&hd->pdev_list);
    1.38 +
    1.39      drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
    1.40      iommu = drhd->iommu;
    1.41  
    1.42 @@ -1096,6 +1100,26 @@ static int intel_iommu_domain_init(struc
    1.43              return -ENODEV;
    1.44      }
    1.45      hd->agaw = agaw;
    1.46 +
    1.47 +    if ( d->domain_id == 0 )
    1.48 +    {
    1.49 +        /* Set up 1:1 page table for dom0. */
    1.50 +        for ( i = 0; i < max_page; i++ )
    1.51 +            iommu_map_page(d, i, i);
    1.52 +
    1.53 +        setup_dom0_devices(d);
    1.54 +        setup_dom0_rmrr(d);
    1.55 +
    1.56 +        iommu_flush_all();
    1.57 +
    1.58 +        for_each_drhd_unit ( drhd )
    1.59 +        {
    1.60 +            iommu = drhd->iommu;
    1.61 +            if ( iommu_enable_translation(iommu) )
    1.62 +                return -EIO;
    1.63 +        }
    1.64 +    }
    1.65 +
    1.66      return 0;
    1.67  }
    1.68  
    1.69 @@ -1696,37 +1720,15 @@ static int iommu_prepare_rmrr_dev(
    1.70      return ret;
    1.71  }
    1.72  
    1.73 -void __init setup_dom0_devices(void)
    1.74 +static void setup_dom0_devices(struct domain *d)
    1.75  {
    1.76 -    struct hvm_iommu *hd  = domain_hvm_iommu(dom0);
    1.77 +    struct hvm_iommu *hd;
    1.78      struct acpi_drhd_unit *drhd;
    1.79      struct pci_dev *pdev;
    1.80      int bus, dev, func, ret;
    1.81      u32 l;
    1.82  
    1.83 -#ifdef DEBUG_VTD_CONTEXT_ENTRY
    1.84 -    for ( bus = 0; bus < 256; bus++ )
    1.85 -    {
    1.86 -        for ( dev = 0; dev < 32; dev++ )
    1.87 -        { 
    1.88 -            for ( func = 0; func < 8; func++ )
    1.89 -            {
    1.90 -                struct context_entry *context;
    1.91 -                struct pci_dev device;
    1.92 -
    1.93 -                device.bus = bus; 
    1.94 -                device.devfn = PCI_DEVFN(dev, func); 
    1.95 -                drhd = acpi_find_matched_drhd_unit(&device);
    1.96 -                context = device_to_context_entry(drhd->iommu,
    1.97 -                                                  bus, PCI_DEVFN(dev, func));
    1.98 -                if ( (context->lo != 0) || (context->hi != 0) )
    1.99 -                    dprintk(XENLOG_INFO VTDPREFIX,
   1.100 -                            "setup_dom0_devices-%x:%x:%x- context not 0\n",
   1.101 -                            bus, dev, func);
   1.102 -            }
   1.103 -        }    
   1.104 -    }        
   1.105 -#endif
   1.106 +    hd = domain_hvm_iommu(d);
   1.107  
   1.108      for ( bus = 0; bus < 256; bus++ )
   1.109      {
   1.110 @@ -1745,7 +1747,7 @@ void __init setup_dom0_devices(void)
   1.111                  list_add_tail(&pdev->list, &hd->pdev_list);
   1.112  
   1.113                  drhd = acpi_find_matched_drhd_unit(pdev);
   1.114 -                ret = domain_context_mapping(dom0, drhd->iommu, pdev);
   1.115 +                ret = domain_context_mapping(d, drhd->iommu, pdev);
   1.116                  if ( ret != 0 )
   1.117                      gdprintk(XENLOG_ERR VTDPREFIX,
   1.118                               "domain_context_mapping failed\n");
   1.119 @@ -1753,7 +1755,7 @@ void __init setup_dom0_devices(void)
   1.120          }
   1.121      }
   1.122  
   1.123 -    for_each_pdev ( dom0, pdev )
   1.124 +    for_each_pdev ( d, pdev )
   1.125          dprintk(XENLOG_INFO VTDPREFIX,
   1.126                  "setup_dom0_devices: bdf = %x:%x:%x\n",
   1.127                  pdev->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
   1.128 @@ -1803,13 +1805,6 @@ static int init_vtd_hw(void)
   1.129          flush->context = flush_context_reg;
   1.130          flush->iotlb = flush_iotlb_reg;
   1.131      }
   1.132 -    return 0;
   1.133 -}
   1.134 -
   1.135 -static int init_vtd2_hw(void)
   1.136 -{
   1.137 -    struct acpi_drhd_unit *drhd;
   1.138 -    struct iommu *iommu;
   1.139  
   1.140      for_each_drhd_unit ( drhd )
   1.141      {
   1.142 @@ -1826,31 +1821,18 @@ static int init_vtd2_hw(void)
   1.143              dprintk(XENLOG_ERR VTDPREFIX,
   1.144                      "Interrupt Remapping hardware not found\n");
   1.145      }
   1.146 +
   1.147      return 0;
   1.148  }
   1.149  
   1.150 -static int enable_vtd_translation(void)
   1.151 -{
   1.152 -    struct acpi_drhd_unit *drhd;
   1.153 -    struct iommu *iommu;
   1.154 -
   1.155 -    for_each_drhd_unit ( drhd )
   1.156 -    {
   1.157 -        iommu = drhd->iommu;
   1.158 -        if ( iommu_enable_translation(iommu) )
   1.159 -            return -EIO;
   1.160 -    }
   1.161 -    return 0;
   1.162 -}
   1.163 -
   1.164 -static void setup_dom0_rmrr(void)
   1.165 +static void setup_dom0_rmrr(struct domain *d)
   1.166  {
   1.167      struct acpi_rmrr_unit *rmrr;
   1.168      struct pci_dev *pdev;
   1.169      int ret;
   1.170  
   1.171      for_each_rmrr_device ( rmrr, pdev )
   1.172 -        ret = iommu_prepare_rmrr_dev(dom0, rmrr, pdev);
   1.173 +        ret = iommu_prepare_rmrr_dev(d, rmrr, pdev);
   1.174          if ( ret )
   1.175              gdprintk(XENLOG_ERR VTDPREFIX,
   1.176                       "IOMMU: mapping reserved region failed\n");
   1.177 @@ -1859,17 +1841,13 @@ static void setup_dom0_rmrr(void)
   1.178  
   1.179  int intel_vtd_setup(void)
   1.180  {
   1.181 -    struct hvm_iommu *hd  = domain_hvm_iommu(dom0);
   1.182      struct acpi_drhd_unit *drhd;
   1.183      struct iommu *iommu;
   1.184 -    unsigned long i;
   1.185  
   1.186      if ( !vtd_enabled )
   1.187          return -ENODEV;
   1.188  
   1.189      spin_lock_init(&domid_bitmap_lock);
   1.190 -    INIT_LIST_HEAD(&hd->pdev_list);
   1.191 -
   1.192      clflush_size = get_clflush_size();
   1.193  
   1.194      for_each_drhd_unit ( drhd )
   1.195 @@ -1889,16 +1867,7 @@ int intel_vtd_setup(void)
   1.196      memset(domid_bitmap, 0, domid_bitmap_size / 8);
   1.197      set_bit(0, domid_bitmap);
   1.198  
   1.199 -    /* Set up 1:1 page table for dom0. */
   1.200 -    for ( i = 0; i < max_page; i++ )
   1.201 -        iommu_map_page(dom0, i, i);
   1.202 -
   1.203      init_vtd_hw();
   1.204 -    setup_dom0_devices();
   1.205 -    setup_dom0_rmrr();
   1.206 -    iommu_flush_all();
   1.207 -    enable_vtd_translation();
   1.208 -    init_vtd2_hw();
   1.209  
   1.210      return 0;
   1.211