ia64/xen-unstable

changeset 17487:658f031557f6

iommu: Consolidate iommu enablement logic. Now there is only one
command-line parameter for disabling IOV/VTD: "iommu"/"no-iommu".

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Apr 21 10:33:40 2008 +0100 (2008-04-21)
parents e823b22c6017
children dac7703e8d93
files xen/arch/x86/hvm/svm/intr.c xen/arch/x86/hvm/vmx/intr.c xen/drivers/passthrough/amd/pci_amd_iommu.c xen/drivers/passthrough/iommu.c xen/drivers/passthrough/vtd/dmar.c xen/drivers/passthrough/vtd/iommu.c xen/drivers/passthrough/vtd/utils.c xen/include/asm-x86/amd-iommu.h xen/include/asm-x86/hvm/svm/amd-iommu-proto.h xen/include/xen/iommu.h
line diff
     1.1 --- a/xen/arch/x86/hvm/svm/intr.c	Mon Apr 21 10:01:46 2008 +0100
     1.2 +++ b/xen/arch/x86/hvm/svm/intr.c	Mon Apr 21 10:33:40 2008 +0100
     1.3 @@ -102,7 +102,7 @@ static void svm_dirq_assist(struct vcpu 
     1.4      struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
     1.5      struct dev_intx_gsi_link *digl;
     1.6  
     1.7 -    if ( !amd_iommu_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
     1.8 +    if ( !iommu_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
     1.9          return;
    1.10  
    1.11      for ( irq = find_first_bit(hvm_irq_dpci->dirq_mask, NR_IRQS);
     2.1 --- a/xen/arch/x86/hvm/vmx/intr.c	Mon Apr 21 10:01:46 2008 +0100
     2.2 +++ b/xen/arch/x86/hvm/vmx/intr.c	Mon Apr 21 10:33:40 2008 +0100
     2.3 @@ -111,7 +111,7 @@ static void vmx_dirq_assist(struct vcpu 
     2.4      struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
     2.5      struct dev_intx_gsi_link *digl;
     2.6  
     2.7 -    if ( !vtd_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
     2.8 +    if ( !iommu_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
     2.9          return;
    2.10  
    2.11      for ( irq = find_first_bit(hvm_irq_dpci->dirq_mask, NR_IRQS);
     3.1 --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c	Mon Apr 21 10:01:46 2008 +0100
     3.2 +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c	Mon Apr 21 10:33:40 2008 +0100
     3.3 @@ -30,16 +30,10 @@ struct list_head amd_iommu_head;
     3.4  long amd_iommu_poll_comp_wait = COMPLETION_WAIT_DEFAULT_POLLING_COUNT;
     3.5  static long amd_iommu_cmd_buffer_entries = IOMMU_CMD_BUFFER_DEFAULT_ENTRIES;
     3.6  static long amd_iommu_event_log_entries = IOMMU_EVENT_LOG_DEFAULT_ENTRIES;
     3.7 -int nr_amd_iommus = 0;
     3.8 -
     3.9 -unsigned short ivrs_bdf_entries = 0;
    3.10 -struct ivrs_mappings *ivrs_mappings = NULL;
    3.11 +int nr_amd_iommus;
    3.12  
    3.13 -/* will set if amd-iommu HW is found */
    3.14 -int amd_iommu_enabled = 0;
    3.15 -
    3.16 -static int enable_amd_iommu = 0;
    3.17 -boolean_param("enable_amd_iov", enable_amd_iommu);
    3.18 +unsigned short ivrs_bdf_entries;
    3.19 +struct ivrs_mappings *ivrs_mappings;
    3.20  
    3.21  static void deallocate_domain_page_tables(struct hvm_iommu *hd)
    3.22  {
    3.23 @@ -78,24 +72,6 @@ static void __init deallocate_iommu_reso
    3.24      deallocate_iommu_table_struct(&iommu->event_log);
    3.25  }
    3.26  
    3.27 -static void __init detect_cleanup(void)
    3.28 -{
    3.29 -    struct amd_iommu *iommu, *next;
    3.30 -
    3.31 -    list_for_each_entry_safe ( iommu, next, &amd_iommu_head, list )
    3.32 -    {
    3.33 -        list_del(&iommu->list);
    3.34 -        deallocate_iommu_resources(iommu);
    3.35 -        xfree(iommu);
    3.36 -    }
    3.37 -
    3.38 -    if ( ivrs_mappings )
    3.39 -    {
    3.40 -        xfree(ivrs_mappings);
    3.41 -        ivrs_mappings = NULL;
    3.42 -    }
    3.43 -}
    3.44 -
    3.45  static int __init allocate_iommu_table_struct(struct table_struct *table,
    3.46                                                const char *name)
    3.47  {
    3.48 @@ -246,8 +222,6 @@ static int __init amd_iommu_init(void)
    3.49          nr_amd_iommus++;
    3.50      }
    3.51  
    3.52 -    amd_iommu_enabled = 1;
    3.53 -
    3.54      return 0;
    3.55  
    3.56   error_out:
    3.57 @@ -277,7 +251,7 @@ struct amd_iommu *find_iommu_for_device(
    3.58      return NULL;
    3.59  }
    3.60  
    3.61 -void amd_iommu_setup_domain_device(
    3.62 +static void amd_iommu_setup_domain_device(
    3.63      struct domain *domain, struct amd_iommu *iommu, int bdf)
    3.64  {
    3.65      void *dte;
    3.66 @@ -316,7 +290,7 @@ void amd_iommu_setup_domain_device(
    3.67      }
    3.68  }
    3.69  
    3.70 -void __init amd_iommu_setup_dom0_devices(void)
    3.71 +static void __init amd_iommu_setup_dom0_devices(void)
    3.72  {
    3.73      struct hvm_iommu *hd = domain_hvm_iommu(dom0);
    3.74      struct amd_iommu *iommu;
    3.75 @@ -358,13 +332,7 @@ int amd_iov_detect(void)
    3.76  {
    3.77      unsigned long i;
    3.78      int last_bus;
    3.79 -    struct amd_iommu *iommu;
    3.80 -
    3.81 -    if ( !enable_amd_iommu )
    3.82 -    {
    3.83 -        printk("AMD_IOV: Disabled.\n");
    3.84 -        return 0;
    3.85 -    }
    3.86 +    struct amd_iommu *iommu, *next;
    3.87  
    3.88      INIT_LIST_HEAD(&amd_iommu_head);
    3.89  
    3.90 @@ -377,29 +345,26 @@ int amd_iov_detect(void)
    3.91      if ( !iommu_found() )
    3.92      {
    3.93          printk("AMD_IOV: IOMMU not found!\n");
    3.94 -        return 0;
    3.95 +        goto error_out;
    3.96      }
    3.97 -    else
    3.98 -    {
    3.99 -        /* allocate 'ivrs mappings' table */
   3.100 -        /* note: the table has entries to accomodate all IOMMUs */
   3.101 -        last_bus = 0;
   3.102 -        for_each_amd_iommu ( iommu )
   3.103 -            if ( iommu->last_downstream_bus > last_bus )
   3.104 -                last_bus = iommu->last_downstream_bus;
   3.105 +
   3.106 +    /* allocate 'ivrs mappings' table */
   3.107 +    /* note: the table has entries to accomodate all IOMMUs */
   3.108 +    last_bus = 0;
   3.109 +    for_each_amd_iommu ( iommu )
   3.110 +        if ( iommu->last_downstream_bus > last_bus )
   3.111 +            last_bus = iommu->last_downstream_bus;
   3.112  
   3.113 -        ivrs_bdf_entries = (last_bus + 1) *
   3.114 -            IOMMU_DEV_TABLE_ENTRIES_PER_BUS;
   3.115 -        ivrs_mappings = xmalloc_array( struct ivrs_mappings, ivrs_bdf_entries);
   3.116 -
   3.117 -        if ( !ivrs_mappings )
   3.118 -        {
   3.119 -            amd_iov_error("Error allocating IVRS DevMappings table\n");
   3.120 -            goto error_out;
   3.121 -        }
   3.122 -        memset(ivrs_mappings, 0,
   3.123 -               ivrs_bdf_entries * sizeof(struct ivrs_mappings));
   3.124 +    ivrs_bdf_entries = (last_bus + 1) *
   3.125 +        IOMMU_DEV_TABLE_ENTRIES_PER_BUS;
   3.126 +    ivrs_mappings = xmalloc_array( struct ivrs_mappings, ivrs_bdf_entries);
   3.127 +    if ( ivrs_mappings == NULL )
   3.128 +    {
   3.129 +        amd_iov_error("Error allocating IVRS DevMappings table\n");
   3.130 +        goto error_out;
   3.131      }
   3.132 +    memset(ivrs_mappings, 0,
   3.133 +           ivrs_bdf_entries * sizeof(struct ivrs_mappings));
   3.134  
   3.135      if ( amd_iommu_init() != 0 )
   3.136      {
   3.137 @@ -418,9 +383,20 @@ int amd_iov_detect(void)
   3.138      return 0;
   3.139  
   3.140   error_out:
   3.141 -    detect_cleanup();
   3.142 +    list_for_each_entry_safe ( iommu, next, &amd_iommu_head, list )
   3.143 +    {
   3.144 +        list_del(&iommu->list);
   3.145 +        deallocate_iommu_resources(iommu);
   3.146 +        xfree(iommu);
   3.147 +    }
   3.148 +
   3.149 +    if ( ivrs_mappings )
   3.150 +    {
   3.151 +        xfree(ivrs_mappings);
   3.152 +        ivrs_mappings = NULL;
   3.153 +    }
   3.154 +
   3.155      return -ENODEV;
   3.156 -
   3.157  }
   3.158  
   3.159  static int allocate_domain_resources(struct hvm_iommu *hd)
   3.160 @@ -464,7 +440,7 @@ static int get_paging_mode(unsigned long
   3.161      return level;
   3.162  }
   3.163  
   3.164 -int amd_iommu_domain_init(struct domain *domain)
   3.165 +static int amd_iommu_domain_init(struct domain *domain)
   3.166  {
   3.167      struct hvm_iommu *hd = domain_hvm_iommu(domain);
   3.168  
   3.169 @@ -561,7 +537,7 @@ static int reassign_device( struct domai
   3.170      return 0;
   3.171  }
   3.172  
   3.173 -int amd_iommu_assign_device(struct domain *d, u8 bus, u8 devfn)
   3.174 +static int amd_iommu_assign_device(struct domain *d, u8 bus, u8 devfn)
   3.175  {
   3.176      int bdf = (bus << 8) | devfn;
   3.177      int req_id = ivrs_mappings[bdf].dte_requestor_id;
   3.178 @@ -647,16 +623,13 @@ static void deallocate_iommu_page_tables
   3.179      hd ->root_table = NULL;
   3.180  }
   3.181  
   3.182 -void amd_iommu_domain_destroy(struct domain *d)
   3.183 +static void amd_iommu_domain_destroy(struct domain *d)
   3.184  {
   3.185 -    if ( !amd_iommu_enabled )
   3.186 -        return;
   3.187 -
   3.188      deallocate_iommu_page_tables(d);
   3.189      release_domain_devices(d);
   3.190  }
   3.191  
   3.192 -void amd_iommu_return_device(
   3.193 +static void amd_iommu_return_device(
   3.194      struct domain *s, struct domain *t, u8 bus, u8 devfn)
   3.195  {
   3.196      pdev_flr(bus, devfn);
     4.1 --- a/xen/drivers/passthrough/iommu.c	Mon Apr 21 10:01:46 2008 +0100
     4.2 +++ b/xen/drivers/passthrough/iommu.c	Mon Apr 21 10:33:40 2008 +0100
     4.3 @@ -21,6 +21,9 @@ extern struct iommu_ops amd_iommu_ops;
     4.4  int intel_vtd_setup(void);
     4.5  int amd_iov_detect(void);
     4.6  
     4.7 +int iommu_enabled = 1;
     4.8 +boolean_param("iommu", iommu_enabled);
     4.9 +
    4.10  int iommu_domain_init(struct domain *domain)
    4.11  {
    4.12      struct hvm_iommu *hd = domain_hvm_iommu(domain);
    4.13 @@ -139,13 +142,24 @@ void deassign_device(struct domain *d, u
    4.14  
    4.15  int iommu_setup(void)
    4.16  {
    4.17 +    int rc = -ENODEV;
    4.18 +
    4.19 +    if ( !iommu_enabled )
    4.20 +        goto out;
    4.21 +
    4.22      switch ( boot_cpu_data.x86_vendor )
    4.23      {
    4.24      case X86_VENDOR_INTEL:
    4.25 -        return intel_vtd_setup();
    4.26 +        rc = intel_vtd_setup();
    4.27 +        break;
    4.28      case X86_VENDOR_AMD:
    4.29 -        return amd_iov_detect();
    4.30 +        rc = amd_iov_detect();
    4.31 +        break;
    4.32      }
    4.33  
    4.34 -    return 0;
    4.35 +    iommu_enabled = (rc == 0);
    4.36 +
    4.37 + out:
    4.38 +    printk("I/O virtualisation %sabled\n", iommu_enabled ? "en" : "dis");
    4.39 +    return rc;
    4.40  }
     5.1 --- a/xen/drivers/passthrough/vtd/dmar.c	Mon Apr 21 10:01:46 2008 +0100
     5.2 +++ b/xen/drivers/passthrough/vtd/dmar.c	Mon Apr 21 10:33:40 2008 +0100
     5.3 @@ -30,8 +30,7 @@
     5.4  #include "dmar.h"
     5.5  #include "../pci_regs.h"
     5.6  
     5.7 -int vtd_enabled;
     5.8 -boolean_param("vtd", vtd_enabled);
     5.9 +int vtd_enabled = 1;
    5.10  
    5.11  #undef PREFIX
    5.12  #define PREFIX VTDPREFIX "ACPI DMAR:"
    5.13 @@ -604,22 +603,24 @@ int acpi_dmar_init(void)
    5.14  {
    5.15      int rc;
    5.16  
    5.17 -    if ( !vtd_enabled )
    5.18 -        return -ENODEV;
    5.19 +    rc = -ENODEV;
    5.20 +    if ( !iommu_enabled )
    5.21 +        goto fail;
    5.22  
    5.23      if ( (rc = vtd_hw_check()) != 0 )
    5.24 -        return rc;
    5.25 +        goto fail;
    5.26  
    5.27      acpi_table_parse(ACPI_DMAR, acpi_parse_dmar);
    5.28  
    5.29 +    rc = -ENODEV;
    5.30      if ( list_empty(&acpi_drhd_units) )
    5.31 -    {
    5.32 -        dprintk(XENLOG_ERR VTDPREFIX, "No DMAR devices found\n");
    5.33 -        vtd_enabled = 0;
    5.34 -        return -ENODEV;
    5.35 -    }
    5.36 +        goto fail;
    5.37  
    5.38      printk("Intel VT-d has been enabled\n");
    5.39  
    5.40      return 0;
    5.41 +
    5.42 + fail:
    5.43 +    vtd_enabled = 0;
    5.44 +    return -ENODEV;
    5.45  }
     6.1 --- a/xen/drivers/passthrough/vtd/iommu.c	Mon Apr 21 10:01:46 2008 +0100
     6.2 +++ b/xen/drivers/passthrough/vtd/iommu.c	Mon Apr 21 10:33:40 2008 +0100
     6.3 @@ -1111,7 +1111,7 @@ static void free_iommu(struct iommu *iom
     6.4          agaw = 64;                              \
     6.5      agaw; })
     6.6  
     6.7 -int intel_iommu_domain_init(struct domain *domain)
     6.8 +static int intel_iommu_domain_init(struct domain *domain)
     6.9  {
    6.10      struct hvm_iommu *hd = domain_hvm_iommu(domain);
    6.11      struct iommu *iommu = NULL;
    6.12 @@ -1120,9 +1120,6 @@ int intel_iommu_domain_init(struct domai
    6.13      unsigned long sagaw;
    6.14      struct acpi_drhd_unit *drhd;
    6.15  
    6.16 -    if ( !vtd_enabled || list_empty(&acpi_drhd_units) )
    6.17 -        return 0;
    6.18 -
    6.19      for_each_drhd_unit ( drhd )
    6.20          iommu = drhd->iommu ? : iommu_alloc(drhd);
    6.21  
    6.22 @@ -1911,7 +1908,7 @@ int intel_vtd_setup(void)
    6.23      unsigned long i;
    6.24  
    6.25      if ( !vtd_enabled )
    6.26 -        return 0;
    6.27 +        return -ENODEV;
    6.28  
    6.29      spin_lock_init(&domid_bitmap_lock);
    6.30      INIT_LIST_HEAD(&hd->pdev_list);
    6.31 @@ -1946,13 +1943,13 @@ int intel_vtd_setup(void)
    6.32      return 0;
    6.33  
    6.34   error:
    6.35 -    printk("iommu_setup() failed\n");
    6.36      for_each_drhd_unit ( drhd )
    6.37      {
    6.38          iommu = drhd->iommu;
    6.39          free_iommu(iommu);
    6.40      }
    6.41 -    return -EIO;
    6.42 +    vtd_enabled = 0;
    6.43 +    return -ENOMEM;
    6.44  }
    6.45  
    6.46  /*
     7.1 --- a/xen/drivers/passthrough/vtd/utils.c	Mon Apr 21 10:01:46 2008 +0100
     7.2 +++ b/xen/drivers/passthrough/vtd/utils.c	Mon Apr 21 10:33:40 2008 +0100
     7.3 @@ -60,10 +60,10 @@ int vtd_hw_check(void)
     7.4              dprintk(XENLOG_WARNING VTDPREFIX,
     7.5                      "***  vendor = %x device = %x revision = %x\n",
     7.6                      vendor, device, revision);
     7.7 -            vtd_enabled = 0;
     7.8              return -ENODEV;
     7.9          }
    7.10      }
    7.11 +
    7.12      return 0;
    7.13  }
    7.14  
     8.1 --- a/xen/include/asm-x86/amd-iommu.h	Mon Apr 21 10:01:46 2008 +0100
     8.2 +++ b/xen/include/asm-x86/amd-iommu.h	Mon Apr 21 10:33:40 2008 +0100
     8.3 @@ -28,7 +28,6 @@
     8.4  
     8.5  #define iommu_found()           (!list_empty(&amd_iommu_head))
     8.6  
     8.7 -extern int amd_iommu_enabled;
     8.8  extern struct list_head amd_iommu_head;
     8.9  
    8.10  extern int __init amd_iov_detect(void);
     9.1 --- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h	Mon Apr 21 10:01:46 2008 +0100
     9.2 +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h	Mon Apr 21 10:33:40 2008 +0100
     9.3 @@ -84,11 +84,6 @@ void invalidate_dev_table_entry(struct a
     9.4  int send_iommu_command(struct amd_iommu *iommu, u32 cmd[]);
     9.5  void flush_command_buffer(struct amd_iommu *iommu);
     9.6  
     9.7 -/* iommu domain funtions */
     9.8 -int amd_iommu_domain_init(struct domain *domain);
     9.9 -void amd_iommu_setup_domain_device(struct domain *domain,
    9.10 -    struct amd_iommu *iommu, int bdf);
    9.11 -
    9.12  /* find iommu for bdf */
    9.13  struct amd_iommu *find_iommu_for_device(int bus, int devfn);
    9.14  
    10.1 --- a/xen/include/xen/iommu.h	Mon Apr 21 10:01:46 2008 +0100
    10.2 +++ b/xen/include/xen/iommu.h	Mon Apr 21 10:33:40 2008 +0100
    10.3 @@ -27,9 +27,8 @@
    10.4  #include <public/domctl.h>
    10.5  
    10.6  extern int vtd_enabled;
    10.7 -extern int amd_iommu_enabled;
    10.8 +extern int iommu_enabled;
    10.9  
   10.10 -#define iommu_enabled ( amd_iommu_enabled || vtd_enabled )
   10.11  #define domain_hvm_iommu(d)     (&d->arch.hvm_domain.hvm_iommu)
   10.12  #define domain_vmx_iommu(d)     (&d->arch.hvm_domain.hvm_iommu.vmx_iommu)
   10.13