aboutsummaryrefslogtreecommitdiffstats
path: root/xen/drivers
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2013-08-28 10:11:19 +0200
committerJan Beulich <jbeulich@suse.com>2013-08-28 10:11:19 +0200
commitdcbff3aeac6020cdf1f5bd0f0eb0d329fc55d939 (patch)
tree0374ffbfeac5fcde01677769f4cc272d9cb41a26 /xen/drivers
parent460dea6c817eada4f7d43097b1e71e975a7ba52b (diff)
downloadxen-dcbff3aeac6020cdf1f5bd0f0eb0d329fc55d939.tar.gz
xen-dcbff3aeac6020cdf1f5bd0f0eb0d329fc55d939.tar.bz2
xen-dcbff3aeac6020cdf1f5bd0f0eb0d329fc55d939.zip
AMD IOMMU: also allocate IRTEs for HPET MSI
Omitting this was a blatant oversight of mine in commit 2ca9fbd7 ("AMD IOMMU: allocate IRTE entries instead of using a static mapping"). This also changes a bogus inequality check into a sensible one, even though it is already known that this will make HPET MSI unusable on certain systems (having respective broken firmware). This, however, seems better than failing on systems with consistent ACPI tables. Reported-by: Sander Eikelenboom <linux@eikelenboom.it> Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Diffstat (limited to 'xen/drivers')
-rw-r--r--xen/drivers/passthrough/amd/iommu_intr.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/xen/drivers/passthrough/amd/iommu_intr.c b/xen/drivers/passthrough/amd/iommu_intr.c
index bae0be76bd..831f92a732 100644
--- a/xen/drivers/passthrough/amd/iommu_intr.c
+++ b/xen/drivers/passthrough/amd/iommu_intr.c
@@ -595,14 +595,31 @@ void* __init amd_iommu_alloc_intremap_table(unsigned long **inuse_map)
int __init amd_setup_hpet_msi(struct msi_desc *msi_desc)
{
- if ( (!msi_desc->hpet_id != hpet_sbdf.id) ||
- (hpet_sbdf.iommu == NULL) )
+ spinlock_t *lock;
+ unsigned long flags;
+ int rc = 0;
+
+ if ( msi_desc->hpet_id != hpet_sbdf.id || !hpet_sbdf.iommu )
{
- AMD_IOMMU_DEBUG("Fail to setup HPET MSI remapping\n");
- return 1;
+ AMD_IOMMU_DEBUG("Failed to setup HPET MSI remapping: %s\n",
+ hpet_sbdf.iommu ? "Wrong HPET" : "No IOMMU");
+ return -ENODEV;
}
- return 0;
+ lock = get_intremap_lock(hpet_sbdf.seg, hpet_sbdf.bdf);
+ spin_lock_irqsave(lock, flags);
+
+ msi_desc->remap_index = alloc_intremap_entry(hpet_sbdf.seg,
+ hpet_sbdf.bdf, 1);
+ if ( msi_desc->remap_index >= INTREMAP_ENTRIES )
+ {
+ msi_desc->remap_index = -1;
+ rc = -ENXIO;
+ }
+
+ spin_unlock_irqrestore(lock, flags);
+
+ return rc;
}
static void dump_intremap_table(const u32 *table)