aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xen/arch/x86/hvm/svm/intr.c2
-rw-r--r--xen/arch/x86/hvm/vmx/intr.c2
-rw-r--r--xen/drivers/passthrough/amd/pci_amd_iommu.c107
-rw-r--r--xen/drivers/passthrough/iommu.c20
-rw-r--r--xen/drivers/passthrough/vtd/dmar.c21
-rw-r--r--xen/drivers/passthrough/vtd/iommu.c11
-rw-r--r--xen/drivers/passthrough/vtd/utils.c2
-rw-r--r--xen/include/asm-x86/amd-iommu.h1
-rw-r--r--xen/include/asm-x86/hvm/svm/amd-iommu-proto.h5
-rw-r--r--xen/include/xen/iommu.h3
10 files changed, 76 insertions, 98 deletions
diff --git a/xen/arch/x86/hvm/svm/intr.c b/xen/arch/x86/hvm/svm/intr.c
index 17a9c3bc7b..4b3dcd33ad 100644
--- a/xen/arch/x86/hvm/svm/intr.c
+++ b/xen/arch/x86/hvm/svm/intr.c
@@ -102,7 +102,7 @@ static void svm_dirq_assist(struct vcpu *v)
struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
struct dev_intx_gsi_link *digl;
- if ( !amd_iommu_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
+ if ( !iommu_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
return;
for ( irq = find_first_bit(hvm_irq_dpci->dirq_mask, NR_IRQS);
diff --git a/xen/arch/x86/hvm/vmx/intr.c b/xen/arch/x86/hvm/vmx/intr.c
index a212310d75..dc47430a63 100644
--- a/xen/arch/x86/hvm/vmx/intr.c
+++ b/xen/arch/x86/hvm/vmx/intr.c
@@ -111,7 +111,7 @@ static void vmx_dirq_assist(struct vcpu *v)
struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
struct dev_intx_gsi_link *digl;
- if ( !vtd_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
+ if ( !iommu_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
return;
for ( irq = find_first_bit(hvm_irq_dpci->dirq_mask, NR_IRQS);
diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/passthrough/amd/pci_amd_iommu.c
index 08d46e37e7..ab2b86e20d 100644
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -30,16 +30,10 @@ struct list_head amd_iommu_head;
long amd_iommu_poll_comp_wait = COMPLETION_WAIT_DEFAULT_POLLING_COUNT;
static long amd_iommu_cmd_buffer_entries = IOMMU_CMD_BUFFER_DEFAULT_ENTRIES;
static long amd_iommu_event_log_entries = IOMMU_EVENT_LOG_DEFAULT_ENTRIES;
-int nr_amd_iommus = 0;
+int nr_amd_iommus;
-unsigned short ivrs_bdf_entries = 0;
-struct ivrs_mappings *ivrs_mappings = NULL;
-
-/* will set if amd-iommu HW is found */
-int amd_iommu_enabled = 0;
-
-static int enable_amd_iommu = 0;
-boolean_param("enable_amd_iov", enable_amd_iommu);
+unsigned short ivrs_bdf_entries;
+struct ivrs_mappings *ivrs_mappings;
static void deallocate_domain_page_tables(struct hvm_iommu *hd)
{
@@ -78,24 +72,6 @@ static void __init deallocate_iommu_resources(struct amd_iommu *iommu)
deallocate_iommu_table_struct(&iommu->event_log);
}
-static void __init detect_cleanup(void)
-{
- struct amd_iommu *iommu, *next;
-
- list_for_each_entry_safe ( iommu, next, &amd_iommu_head, list )
- {
- list_del(&iommu->list);
- deallocate_iommu_resources(iommu);
- xfree(iommu);
- }
-
- if ( ivrs_mappings )
- {
- xfree(ivrs_mappings);
- ivrs_mappings = NULL;
- }
-}
-
static int __init allocate_iommu_table_struct(struct table_struct *table,
const char *name)
{
@@ -246,8 +222,6 @@ static int __init amd_iommu_init(void)
nr_amd_iommus++;
}
- amd_iommu_enabled = 1;
-
return 0;
error_out:
@@ -277,7 +251,7 @@ struct amd_iommu *find_iommu_for_device(int bus, int devfn)
return NULL;
}
-void amd_iommu_setup_domain_device(
+static void amd_iommu_setup_domain_device(
struct domain *domain, struct amd_iommu *iommu, int bdf)
{
void *dte;
@@ -316,7 +290,7 @@ void amd_iommu_setup_domain_device(
}
}
-void __init amd_iommu_setup_dom0_devices(void)
+static void __init amd_iommu_setup_dom0_devices(void)
{
struct hvm_iommu *hd = domain_hvm_iommu(dom0);
struct amd_iommu *iommu;
@@ -358,13 +332,7 @@ int amd_iov_detect(void)
{
unsigned long i;
int last_bus;
- struct amd_iommu *iommu;
-
- if ( !enable_amd_iommu )
- {
- printk("AMD_IOV: Disabled.\n");
- return 0;
- }
+ struct amd_iommu *iommu, *next;
INIT_LIST_HEAD(&amd_iommu_head);
@@ -377,29 +345,26 @@ int amd_iov_detect(void)
if ( !iommu_found() )
{
printk("AMD_IOV: IOMMU not found!\n");
- return 0;
+ goto error_out;
}
- else
+
+ /* allocate 'ivrs mappings' table */
+ /* note: the table has entries to accomodate all IOMMUs */
+ last_bus = 0;
+ for_each_amd_iommu ( iommu )
+ if ( iommu->last_downstream_bus > last_bus )
+ last_bus = iommu->last_downstream_bus;
+
+ ivrs_bdf_entries = (last_bus + 1) *
+ IOMMU_DEV_TABLE_ENTRIES_PER_BUS;
+ ivrs_mappings = xmalloc_array( struct ivrs_mappings, ivrs_bdf_entries);
+ if ( ivrs_mappings == NULL )
{
- /* allocate 'ivrs mappings' table */
- /* note: the table has entries to accomodate all IOMMUs */
- last_bus = 0;
- for_each_amd_iommu ( iommu )
- if ( iommu->last_downstream_bus > last_bus )
- last_bus = iommu->last_downstream_bus;
-
- ivrs_bdf_entries = (last_bus + 1) *
- IOMMU_DEV_TABLE_ENTRIES_PER_BUS;
- ivrs_mappings = xmalloc_array( struct ivrs_mappings, ivrs_bdf_entries);
-
- if ( !ivrs_mappings )
- {
- amd_iov_error("Error allocating IVRS DevMappings table\n");
- goto error_out;
- }
- memset(ivrs_mappings, 0,
- ivrs_bdf_entries * sizeof(struct ivrs_mappings));
+ amd_iov_error("Error allocating IVRS DevMappings table\n");
+ goto error_out;
}
+ memset(ivrs_mappings, 0,
+ ivrs_bdf_entries * sizeof(struct ivrs_mappings));
if ( amd_iommu_init() != 0 )
{
@@ -418,9 +383,20 @@ int amd_iov_detect(void)
return 0;
error_out:
- detect_cleanup();
- return -ENODEV;
+ list_for_each_entry_safe ( iommu, next, &amd_iommu_head, list )
+ {
+ list_del(&iommu->list);
+ deallocate_iommu_resources(iommu);
+ xfree(iommu);
+ }
+
+ if ( ivrs_mappings )
+ {
+ xfree(ivrs_mappings);
+ ivrs_mappings = NULL;
+ }
+ return -ENODEV;
}
static int allocate_domain_resources(struct hvm_iommu *hd)
@@ -464,7 +440,7 @@ static int get_paging_mode(unsigned long entries)
return level;
}
-int amd_iommu_domain_init(struct domain *domain)
+static int amd_iommu_domain_init(struct domain *domain)
{
struct hvm_iommu *hd = domain_hvm_iommu(domain);
@@ -561,7 +537,7 @@ static int reassign_device( struct domain *source, struct domain *target,
return 0;
}
-int amd_iommu_assign_device(struct domain *d, u8 bus, u8 devfn)
+static int amd_iommu_assign_device(struct domain *d, u8 bus, u8 devfn)
{
int bdf = (bus << 8) | devfn;
int req_id = ivrs_mappings[bdf].dte_requestor_id;
@@ -647,16 +623,13 @@ static void deallocate_iommu_page_tables(struct domain *d)
hd ->root_table = NULL;
}
-void amd_iommu_domain_destroy(struct domain *d)
+static void amd_iommu_domain_destroy(struct domain *d)
{
- if ( !amd_iommu_enabled )
- return;
-
deallocate_iommu_page_tables(d);
release_domain_devices(d);
}
-void amd_iommu_return_device(
+static void amd_iommu_return_device(
struct domain *s, struct domain *t, u8 bus, u8 devfn)
{
pdev_flr(bus, devfn);
diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index 51a6e20b44..9fbd41a584 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -21,6 +21,9 @@ extern struct iommu_ops amd_iommu_ops;
int intel_vtd_setup(void);
int amd_iov_detect(void);
+int iommu_enabled = 1;
+boolean_param("iommu", iommu_enabled);
+
int iommu_domain_init(struct domain *domain)
{
struct hvm_iommu *hd = domain_hvm_iommu(domain);
@@ -139,13 +142,24 @@ void deassign_device(struct domain *d, u8 bus, u8 devfn)
int iommu_setup(void)
{
+ int rc = -ENODEV;
+
+ if ( !iommu_enabled )
+ goto out;
+
switch ( boot_cpu_data.x86_vendor )
{
case X86_VENDOR_INTEL:
- return intel_vtd_setup();
+ rc = intel_vtd_setup();
+ break;
case X86_VENDOR_AMD:
- return amd_iov_detect();
+ rc = amd_iov_detect();
+ break;
}
- return 0;
+ iommu_enabled = (rc == 0);
+
+ out:
+ printk("I/O virtualisation %sabled\n", iommu_enabled ? "en" : "dis");
+ return rc;
}
diff --git a/xen/drivers/passthrough/vtd/dmar.c b/xen/drivers/passthrough/vtd/dmar.c
index 9498914044..6ba260b37e 100644
--- a/xen/drivers/passthrough/vtd/dmar.c
+++ b/xen/drivers/passthrough/vtd/dmar.c
@@ -30,8 +30,7 @@
#include "dmar.h"
#include "../pci_regs.h"
-int vtd_enabled;
-boolean_param("vtd", vtd_enabled);
+int vtd_enabled = 1;
#undef PREFIX
#define PREFIX VTDPREFIX "ACPI DMAR:"
@@ -604,22 +603,24 @@ int acpi_dmar_init(void)
{
int rc;
- if ( !vtd_enabled )
- return -ENODEV;
+ rc = -ENODEV;
+ if ( !iommu_enabled )
+ goto fail;
if ( (rc = vtd_hw_check()) != 0 )
- return rc;
+ goto fail;
acpi_table_parse(ACPI_DMAR, acpi_parse_dmar);
+ rc = -ENODEV;
if ( list_empty(&acpi_drhd_units) )
- {
- dprintk(XENLOG_ERR VTDPREFIX, "No DMAR devices found\n");
- vtd_enabled = 0;
- return -ENODEV;
- }
+ goto fail;
printk("Intel VT-d has been enabled\n");
return 0;
+
+ fail:
+ vtd_enabled = 0;
+ return -ENODEV;
}
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index d7498e4d35..9396959dc1 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -1111,7 +1111,7 @@ static void free_iommu(struct iommu *iommu)
agaw = 64; \
agaw; })
-int intel_iommu_domain_init(struct domain *domain)
+static int intel_iommu_domain_init(struct domain *domain)
{
struct hvm_iommu *hd = domain_hvm_iommu(domain);
struct iommu *iommu = NULL;
@@ -1120,9 +1120,6 @@ int intel_iommu_domain_init(struct domain *domain)
unsigned long sagaw;
struct acpi_drhd_unit *drhd;
- if ( !vtd_enabled || list_empty(&acpi_drhd_units) )
- return 0;
-
for_each_drhd_unit ( drhd )
iommu = drhd->iommu ? : iommu_alloc(drhd);
@@ -1911,7 +1908,7 @@ int intel_vtd_setup(void)
unsigned long i;
if ( !vtd_enabled )
- return 0;
+ return -ENODEV;
spin_lock_init(&domid_bitmap_lock);
INIT_LIST_HEAD(&hd->pdev_list);
@@ -1946,13 +1943,13 @@ int intel_vtd_setup(void)
return 0;
error:
- printk("iommu_setup() failed\n");
for_each_drhd_unit ( drhd )
{
iommu = drhd->iommu;
free_iommu(iommu);
}
- return -EIO;
+ vtd_enabled = 0;
+ return -ENOMEM;
}
/*
diff --git a/xen/drivers/passthrough/vtd/utils.c b/xen/drivers/passthrough/vtd/utils.c
index 3c33a2c300..47c6b7b83c 100644
--- a/xen/drivers/passthrough/vtd/utils.c
+++ b/xen/drivers/passthrough/vtd/utils.c
@@ -60,10 +60,10 @@ int vtd_hw_check(void)
dprintk(XENLOG_WARNING VTDPREFIX,
"*** vendor = %x device = %x revision = %x\n",
vendor, device, revision);
- vtd_enabled = 0;
return -ENODEV;
}
}
+
return 0;
}
diff --git a/xen/include/asm-x86/amd-iommu.h b/xen/include/asm-x86/amd-iommu.h
index f896088f8d..8acfb55189 100644
--- a/xen/include/asm-x86/amd-iommu.h
+++ b/xen/include/asm-x86/amd-iommu.h
@@ -28,7 +28,6 @@
#define iommu_found() (!list_empty(&amd_iommu_head))
-extern int amd_iommu_enabled;
extern struct list_head amd_iommu_head;
extern int __init amd_iov_detect(void);
diff --git a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
index 646ab7047e..0886776cea 100644
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
@@ -84,11 +84,6 @@ void invalidate_dev_table_entry(struct amd_iommu *iommu,
int send_iommu_command(struct amd_iommu *iommu, u32 cmd[]);
void flush_command_buffer(struct amd_iommu *iommu);
-/* iommu domain funtions */
-int amd_iommu_domain_init(struct domain *domain);
-void amd_iommu_setup_domain_device(struct domain *domain,
- struct amd_iommu *iommu, int bdf);
-
/* find iommu for bdf */
struct amd_iommu *find_iommu_for_device(int bus, int devfn);
diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
index bde167694e..7ad55190fa 100644
--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
@@ -27,9 +27,8 @@
#include <public/domctl.h>
extern int vtd_enabled;
-extern int amd_iommu_enabled;
+extern int iommu_enabled;
-#define iommu_enabled ( amd_iommu_enabled || vtd_enabled )
#define domain_hvm_iommu(d) (&d->arch.hvm_domain.hvm_iommu)
#define domain_vmx_iommu(d) (&d->arch.hvm_domain.hvm_iommu.vmx_iommu)