aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei Wang <wei.wang2@amd.com>2011-11-11 12:03:21 +0100
committerWei Wang <wei.wang2@amd.com>2011-11-11 12:03:21 +0100
commit756273ab103c20be805fcbea1c3dbee6aed73e71 (patch)
treee9e7f9bd65f38a16c2375fe91d249b2e646da614
parentce56a70bd78a43e59266d884c1398c1ede2f3b89 (diff)
downloadxen-756273ab103c20be805fcbea1c3dbee6aed73e71.tar.gz
xen-756273ab103c20be805fcbea1c3dbee6aed73e71.tar.bz2
xen-756273ab103c20be805fcbea1c3dbee6aed73e71.zip
amd iommu: Cleanup iommu pci capabilites detection
* Define new structure to represent capability block. * Remove unnecessary read for unused information. * Add sanity check into get_iommu_capabilities. * iommu capability offset is 16 bit not 8 bit, fix that. Signed-off-by: Wei Wang <wei.wang2@amd.com> Committed-by: Jan Beulich <jbeulich@suse.com>
-rw-r--r--xen/drivers/passthrough/amd/iommu_detect.c43
-rw-r--r--xen/include/asm-x86/amd-iommu.h14
-rw-r--r--xen/include/asm-x86/hvm/svm/amd-iommu-defs.h2
3 files changed, 32 insertions, 27 deletions
diff --git a/xen/drivers/passthrough/amd/iommu_detect.c b/xen/drivers/passthrough/amd/iommu_detect.c
index 5113f67544..9ead31d4e6 100644
--- a/xen/drivers/passthrough/amd/iommu_detect.c
+++ b/xen/drivers/passthrough/amd/iommu_detect.c
@@ -48,25 +48,16 @@ static int __init get_iommu_msi_capabilities(
}
static int __init get_iommu_capabilities(
- u16 seg, u8 bus, u8 dev, u8 func, u8 cap_ptr, struct amd_iommu *iommu)
+ u16 seg, u8 bus, u8 dev, u8 func, u16 cap_ptr, struct amd_iommu *iommu)
{
- u32 cap_header, cap_range, misc_info;
+ u8 type;
- cap_header = pci_conf_read32(seg, bus, dev, func, cap_ptr);
- iommu->revision = get_field_from_reg_u32(
- cap_header, PCI_CAP_REV_MASK, PCI_CAP_REV_SHIFT);
- iommu->pte_not_present_cached = get_field_from_reg_u32(
- cap_header, PCI_CAP_NP_CACHE_MASK, PCI_CAP_NP_CACHE_SHIFT);
+ iommu->cap.header = pci_conf_read32(seg, bus, dev, func, cap_ptr);
+ type = get_field_from_reg_u32(iommu->cap.header, PCI_CAP_TYPE_MASK,
+ PCI_CAP_TYPE_SHIFT);
- cap_range = pci_conf_read32(seg, bus, dev, func,
- cap_ptr + PCI_CAP_RANGE_OFFSET);
- iommu->unit_id = get_field_from_reg_u32(
- cap_range, PCI_CAP_UNIT_ID_MASK, PCI_CAP_UNIT_ID_SHIFT);
-
- misc_info = pci_conf_read32(seg, bus, dev, func,
- cap_ptr + PCI_MISC_INFO_OFFSET);
- iommu->msi_number = get_field_from_reg_u32(
- misc_info, PCI_CAP_MSI_NUMBER_MASK, PCI_CAP_MSI_NUMBER_SHIFT);
+ if ( type != PCI_CAP_TYPE_IOMMU )
+ return -ENODEV;
return 0;
}
@@ -76,6 +67,7 @@ int __init amd_iommu_detect_one_acpi(void *ivhd)
struct amd_iommu *iommu;
u8 bus, dev, func;
struct acpi_ivhd_block_header *ivhd_block;
+ int rt = 0;
ivhd_block = (struct acpi_ivhd_block_header *)ivhd;
@@ -125,12 +117,19 @@ int __init amd_iommu_detect_one_acpi(void *ivhd)
iommu->ht_tunnel_enable = get_field_from_byte(ivhd_block->header.flags,
AMD_IOMMU_ACPI_HT_TUN_ENB_MASK,
AMD_IOMMU_ACPI_HT_TUN_ENB_SHIFT);
- bus = iommu->bdf >> 8;
- dev = PCI_SLOT(iommu->bdf & 0xFF);
- func = PCI_FUNC(iommu->bdf & 0xFF);
- get_iommu_capabilities(iommu->seg, bus, dev, func,
- iommu->cap_offset, iommu);
- get_iommu_msi_capabilities(iommu->seg, bus, dev, func, iommu);
+
+ bus = PCI_BUS(iommu->bdf);
+ dev = PCI_SLOT(iommu->bdf);
+ func = PCI_FUNC(iommu->bdf);
+
+ rt = get_iommu_capabilities(iommu->seg, bus, dev, func,
+ iommu->cap_offset, iommu);
+ if ( rt )
+ return -ENODEV;
+
+ rt = get_iommu_msi_capabilities(iommu->seg, bus, dev, func, iommu);
+ if ( rt )
+ return -ENODEV;
list_add_tail(&iommu->list, &amd_iommu_head);
diff --git a/xen/include/asm-x86/amd-iommu.h b/xen/include/asm-x86/amd-iommu.h
index 5dc97c6766..df36fe25ac 100644
--- a/xen/include/asm-x86/amd-iommu.h
+++ b/xen/include/asm-x86/amd-iommu.h
@@ -36,16 +36,22 @@ struct table_struct {
unsigned long alloc_size;
};
+typedef struct iommu_cap {
+ uint32_t header; /* offset 00h */
+ uint32_t base_low; /* offset 04h */
+ uint32_t base_hi; /* offset 08h */
+ uint32_t range; /* offset 0Ch */
+ uint32_t misc; /* offset 10h */
+} iommu_cap_t;
+
struct amd_iommu {
struct list_head list;
spinlock_t lock; /* protect iommu */
u16 seg;
u16 bdf;
- u8 cap_offset;
- u8 revision;
- u8 unit_id;
- u8 msi_number;
+ u16 cap_offset;
+ iommu_cap_t cap;
u8 pte_not_present_cached;
u8 ht_tunnel_support;
diff --git a/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h b/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h
index a37e32d8c1..dfcf4d77b9 100644
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h
@@ -74,7 +74,7 @@
#define PCI_CAP_UNIT_ID_MASK 0x0000001F
#define PCI_CAP_UNIT_ID_SHIFT 0
-#define PCI_MISC_INFO_OFFSET 0x10
+#define PCI_CAP_MISC_INFO_OFFSET 0x10
#define PCI_CAP_MSI_NUMBER_MASK 0x0000001F
#define PCI_CAP_MSI_NUMBER_SHIFT 0