0d71e75f73
26369-libxl-devid.patch - fate##313584: pass bios information to XEN HVM guest 26554-hvm-firmware-passthrough.patch 26555-hvm-firmware-passthrough.patch 26556-hvm-firmware-passthrough.patch - Upstream patches from Jan 26516-ACPI-parse-table-retval.patch (Replaces CVE-2013-0153-xsa36.patch) 26517-AMD-IOMMU-clear-irtes.patch (Replaces CVE-2013-0153-xsa36.patch) 26518-AMD-IOMMU-disable-if-SATA-combined-mode.patch (Replaces CVE-2013-0153-xsa36.patch) 26519-AMD-IOMMU-perdev-intremap-default.patch (Replaces CVE-2013-0153-xsa36.patch) 26526-pvdrv-no-devinit.patch 26529-gcc48-build-fix.patch 26531-AMD-IOMMU-IVHD-special-missing.patch (Replaces CVE-2013-0153-xsa36.patch) 26532-AMD-IOMMU-phantom-MSI.patch 26536-xenoprof-div-by-0.patch 26576-x86-APICV-migration.patch 26577-x86-APICV-x2APIC.patch 26578-AMD-IOMMU-replace-BUG_ON.patch - bnc#797014 - no way to control live migrations 26547-tools-xc_fix_logic_error_in_stdiostream_progress.patch 26548-tools-xc_handle_tty_output_differently_in_stdiostream_progress.patch 26549-tools-xc_turn_XCFLAGS_*_into_shifts.patch 26550-tools-xc_restore_logging_in_xc_save.patch 26551-tools-xc_log_pid_in_xc_save-xc_restore_output.patch - PVonHVM: __devinit was removed in linux-3.8 OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=229
128 lines
5.0 KiB
Diff
128 lines
5.0 KiB
Diff
References: CVE-2013-0153 XSA-36 bnc#800275
|
|
|
|
# HG changeset patch
|
|
# User Jan Beulich <jbeulich@suse.com>
|
|
# Date 1360831252 -3600
|
|
# Node ID e68f14b9e73925e9d404e517ba510f73fe472e4e
|
|
# Parent c43be17eec0602015fc6461d1f13c992ba330c20
|
|
AMD IOMMU: also spot missing IO-APIC entries in IVRS table
|
|
|
|
Apart from dealing duplicate conflicting entries, we also have to
|
|
handle firmware omitting IO-APIC entries in IVRS altogether. Not doing
|
|
so has resulted in c/s 26517:601139e2b0db to crash such systems during
|
|
boot (whereas with the change here the IOMMU gets disabled just as is
|
|
being done in the other cases, i.e. unless global tables are being
|
|
used).
|
|
|
|
Debugging this issue has also pointed out that the debug log output is
|
|
pretty ugly to look at - consolidate the output, and add one extra
|
|
item for the IVHD special entries, so that future issues are easier
|
|
to analyze.
|
|
|
|
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
|
Tested-by: Sander Eikelenboom <linux@eikelenboom.it>
|
|
Acked-by: Ian Campbell <ian.campbell@citrix.com>
|
|
|
|
--- a/xen/drivers/passthrough/amd/iommu_acpi.c
|
|
+++ b/xen/drivers/passthrough/amd/iommu_acpi.c
|
|
@@ -352,9 +352,8 @@ static int __init parse_ivmd_block(const
|
|
base = start_addr & PAGE_MASK;
|
|
limit = (start_addr + mem_length - 1) & PAGE_MASK;
|
|
|
|
- AMD_IOMMU_DEBUG("IVMD Block: Type 0x%x\n",ivmd_block->header.type);
|
|
- AMD_IOMMU_DEBUG(" Start_Addr_Phys 0x%lx\n", start_addr);
|
|
- AMD_IOMMU_DEBUG(" Mem_Length 0x%lx\n", mem_length);
|
|
+ AMD_IOMMU_DEBUG("IVMD Block: type %#x phys %#lx len %#lx\n",
|
|
+ ivmd_block->header.type, start_addr, mem_length);
|
|
|
|
if ( ivmd_block->header.flags & ACPI_IVMD_EXCLUSION_RANGE )
|
|
iw = ir = IOMMU_CONTROL_ENABLED;
|
|
@@ -549,8 +548,8 @@ static u16 __init parse_ivhd_device_alia
|
|
return 0;
|
|
}
|
|
|
|
- AMD_IOMMU_DEBUG(" Dev_Id Range: 0x%x -> 0x%x\n", first_bdf, last_bdf);
|
|
- AMD_IOMMU_DEBUG(" Dev_Id Alias: 0x%x\n", alias_id);
|
|
+ AMD_IOMMU_DEBUG(" Dev_Id Range: %#x -> %#x alias %#x\n",
|
|
+ first_bdf, last_bdf, alias_id);
|
|
|
|
for ( bdf = first_bdf; bdf <= last_bdf; bdf++ )
|
|
add_ivrs_mapping_entry(bdf, alias_id, range->alias.header.data_setting,
|
|
@@ -652,6 +651,9 @@ static u16 __init parse_ivhd_device_spec
|
|
return 0;
|
|
}
|
|
|
|
+ AMD_IOMMU_DEBUG("IVHD Special: %04x:%02x:%02x.%u variety %#x handle %#x\n",
|
|
+ seg, PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf),
|
|
+ special->variety, special->handle);
|
|
add_ivrs_mapping_entry(bdf, bdf, special->header.data_setting, iommu);
|
|
|
|
if ( special->variety != ACPI_IVHD_IOAPIC )
|
|
@@ -737,10 +739,9 @@ static int __init parse_ivhd_block(const
|
|
{
|
|
ivhd_device = (const void *)((const u8 *)ivhd_block + block_length);
|
|
|
|
- AMD_IOMMU_DEBUG( "IVHD Device Entry:\n");
|
|
- AMD_IOMMU_DEBUG( " Type 0x%x\n", ivhd_device->header.type);
|
|
- AMD_IOMMU_DEBUG( " Dev_Id 0x%x\n", ivhd_device->header.id);
|
|
- AMD_IOMMU_DEBUG( " Flags 0x%x\n", ivhd_device->header.data_setting);
|
|
+ AMD_IOMMU_DEBUG("IVHD Device Entry: type %#x id %#x flags %#x\n",
|
|
+ ivhd_device->header.type, ivhd_device->header.id,
|
|
+ ivhd_device->header.data_setting);
|
|
|
|
switch ( ivhd_device->header.type )
|
|
{
|
|
@@ -869,6 +870,7 @@ static int __init parse_ivrs_table(struc
|
|
{
|
|
const struct acpi_ivrs_header *ivrs_block;
|
|
unsigned long length;
|
|
+ unsigned int apic;
|
|
int error = 0;
|
|
|
|
BUG_ON(!table);
|
|
@@ -882,11 +884,9 @@ static int __init parse_ivrs_table(struc
|
|
{
|
|
ivrs_block = (struct acpi_ivrs_header *)((u8 *)table + length);
|
|
|
|
- AMD_IOMMU_DEBUG("IVRS Block:\n");
|
|
- AMD_IOMMU_DEBUG(" Type 0x%x\n", ivrs_block->type);
|
|
- AMD_IOMMU_DEBUG(" Flags 0x%x\n", ivrs_block->flags);
|
|
- AMD_IOMMU_DEBUG(" Length 0x%x\n", ivrs_block->length);
|
|
- AMD_IOMMU_DEBUG(" Dev_Id 0x%x\n", ivrs_block->device_id);
|
|
+ AMD_IOMMU_DEBUG("IVRS Block: type %#x flags %#x len %#x id %#x\n",
|
|
+ ivrs_block->type, ivrs_block->flags,
|
|
+ ivrs_block->length, ivrs_block->device_id);
|
|
|
|
if ( table->length < (length + ivrs_block->length) )
|
|
{
|
|
@@ -901,6 +901,29 @@ static int __init parse_ivrs_table(struc
|
|
length += ivrs_block->length;
|
|
}
|
|
|
|
+ /* Each IO-APIC must have been mentioned in the table. */
|
|
+ for ( apic = 0; !error && apic < nr_ioapics; ++apic )
|
|
+ {
|
|
+ if ( !nr_ioapic_entries[apic] ||
|
|
+ ioapic_sbdf[IO_APIC_ID(apic)].pin_setup )
|
|
+ continue;
|
|
+
|
|
+ printk(XENLOG_ERR "IVHD Error: no information for IO-APIC %#x\n",
|
|
+ IO_APIC_ID(apic));
|
|
+ if ( amd_iommu_perdev_intremap )
|
|
+ error = -ENXIO;
|
|
+ else
|
|
+ {
|
|
+ ioapic_sbdf[IO_APIC_ID(apic)].pin_setup = xzalloc_array(
|
|
+ unsigned long, BITS_TO_LONGS(nr_ioapic_entries[apic]));
|
|
+ if ( !ioapic_sbdf[IO_APIC_ID(apic)].pin_setup )
|
|
+ {
|
|
+ printk(XENLOG_ERR "IVHD Error: Out of memory\n");
|
|
+ error = -ENOMEM;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
return error;
|
|
}
|
|
|