diff options
Diffstat (limited to 'xen/drivers')
-rw-r--r-- | xen/drivers/passthrough/amd/iommu_intr.c | 27 |
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) |