aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>2013-09-30 14:00:44 +0200
committerJan Beulich <jbeulich@suse.com>2013-09-30 14:00:44 +0200
commit0a6b415d5212af68249ddf41a20dfc3998c8d670 (patch)
tree8a7a3622abf816ce766078936b4ef021c3cf4844
parent93be8285a79c6cbbf66c8681fec1d1bfb71d84cc (diff)
downloadxen-0a6b415d5212af68249ddf41a20dfc3998c8d670.tar.gz
xen-0a6b415d5212af68249ddf41a20dfc3998c8d670.tar.bz2
xen-0a6b415d5212af68249ddf41a20dfc3998c8d670.zip
x86/AMD-Vi: Fix IVRS HPET special->handle override
The current logic does not handle the case when HPET special->handle is invalid in IVRS. On such system, the following message is shown: (XEN) AMD-Vi: Failed to setup HPET MSI remapping: Wrong HPET This patch will allow the ivrs_hpet[<handle>]=<sbdf> to override the IVRS. Also, it removes struct hpet_sbdf.iommu since it is not used anywhere in the code. Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
-rw-r--r--xen/drivers/passthrough/amd/iommu_acpi.c28
-rw-r--r--xen/drivers/passthrough/amd/iommu_intr.c12
-rw-r--r--xen/include/asm-x86/hvm/svm/amd-iommu-proto.h7
3 files changed, 32 insertions, 15 deletions
diff --git a/xen/drivers/passthrough/amd/iommu_acpi.c b/xen/drivers/passthrough/amd/iommu_acpi.c
index c3b9631c14..fca203707d 100644
--- a/xen/drivers/passthrough/amd/iommu_acpi.c
+++ b/xen/drivers/passthrough/amd/iommu_acpi.c
@@ -674,7 +674,7 @@ static void __init parse_ivrs_hpet(char *str)
hpet_sbdf.id = id;
hpet_sbdf.bdf = PCI_BDF(bus, dev, func);
hpet_sbdf.seg = seg;
- hpet_sbdf.cmdline = 1;
+ hpet_sbdf.init = HPET_CMDL;
}
custom_param("ivrs_hpet[", parse_ivrs_hpet);
@@ -789,20 +789,28 @@ static u16 __init parse_ivhd_device_special(
}
break;
case ACPI_IVHD_HPET:
- /* set device id of hpet */
- if ( hpet_sbdf.iommu ||
- (hpet_sbdf.cmdline && hpet_sbdf.id != special->handle) )
+ switch (hpet_sbdf.init)
{
- printk(XENLOG_WARNING "Only one IVHD HPET entry is supported\n");
+ case HPET_IVHD:
+ printk(XENLOG_WARNING "Only one IVHD HPET entry is supported.\n");
break;
- }
- hpet_sbdf.id = special->handle;
- if ( !hpet_sbdf.cmdline )
- {
+ case HPET_CMDL:
+ AMD_IOMMU_DEBUG("IVHD: Command line override present for HPET %#x "
+ "(IVRS: %#x devID %04x:%02x:%02x.%u)\n",
+ hpet_sbdf.id, special->handle, seg, PCI_BUS(bdf),
+ PCI_SLOT(bdf), PCI_FUNC(bdf));
+ break;
+ case HPET_NONE:
+ /* set device id of hpet */
+ hpet_sbdf.id = special->handle;
hpet_sbdf.bdf = bdf;
hpet_sbdf.seg = seg;
+ hpet_sbdf.init = HPET_IVHD;
+ break;
+ default:
+ ASSERT(0);
+ break;
}
- hpet_sbdf.iommu = iommu;
break;
default:
printk(XENLOG_ERR "Unrecognized IVHD special variety %#x\n",
diff --git a/xen/drivers/passthrough/amd/iommu_intr.c b/xen/drivers/passthrough/amd/iommu_intr.c
index 213f4d7bab..c1b76fb9d0 100644
--- a/xen/drivers/passthrough/amd/iommu_intr.c
+++ b/xen/drivers/passthrough/amd/iommu_intr.c
@@ -598,10 +598,16 @@ int __init amd_setup_hpet_msi(struct msi_desc *msi_desc)
unsigned long flags;
int rc = 0;
- if ( msi_desc->hpet_id != hpet_sbdf.id || !hpet_sbdf.iommu )
+ if ( hpet_sbdf.init == HPET_NONE )
{
- AMD_IOMMU_DEBUG("Failed to setup HPET MSI remapping: %s\n",
- hpet_sbdf.iommu ? "Wrong HPET" : "No IOMMU");
+ AMD_IOMMU_DEBUG("Failed to setup HPET MSI remapping."
+ " Missing IVRS HPET info.\n");
+ return -ENODEV;
+ }
+ if ( msi_desc->hpet_id != hpet_sbdf.id )
+ {
+ AMD_IOMMU_DEBUG("Failed to setup HPET MSI remapping."
+ " Wrong HPET.\n");
return -ENODEV;
}
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 3e6961d5c0..b5abc8ffe4 100644
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
@@ -108,8 +108,11 @@ extern struct ioapic_sbdf {
extern struct hpet_sbdf {
u16 bdf, seg, id;
- bool_t cmdline;
- struct amd_iommu *iommu;
+ enum {
+ HPET_NONE,
+ HPET_CMDL,
+ HPET_IVHD,
+ } init;
} hpet_sbdf;
extern void *shared_intremap_table;