X-Original-To: alpine-devel@lists.alpinelinux.org Delivered-To: alpine-devel@mail.alpinelinux.org Received: from SMTP.EU.CITRIX.COM (smtp.eu.citrix.com [46.33.159.39]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (No client certificate requested) by mail.alpinelinux.org (Postfix) with ESMTPS id E4A45DC0070 for ; Wed, 6 Feb 2013 09:04:12 +0000 (UTC) X-IronPort-AV: E=Sophos;i="4.84,614,1355097600"; d="scan'208";a="1187161" Received: from lonpmailmx01.citrite.net ([10.30.203.162]) by LONPIPO01.EU.CITRIX.COM with ESMTP/TLS/RC4-MD5; 06 Feb 2013 09:04:10 +0000 Received: from localhost.localdomain (10.30.249.242) by LONPMAILMX01.citrite.net (10.30.203.162) with Microsoft SMTP Server id 8.3.297.1; Wed, 6 Feb 2013 09:04:10 +0000 From: Roger Pau Monne To: CC: Roger Pau Monne Subject: [alpine-devel] [PATCH] xen: XSA-36 and XSA-38 Date: Wed, 6 Feb 2013 10:02:31 +0100 Message-ID: <1360141351-5319-1-git-send-email-roger.pau@citrix.com> X-Mailer: git-send-email 1.7.7.5 (Apple Git-26) X-Mailinglist: alpine-devel Precedence: list List-Id: Alpine Development List-Unsubscribe: List-Post: List-Help: List-Subscribe: MIME-Version: 1.0 Content-Type: text/plain --- main/xen/APKBUILD | 6 +- main/xen/xsa36-4.2.patch | 323 ++++++++++++++++++++++++++++++++++++++++++++++ main/xen/xsa38.patch | 73 +++++++++++ 3 files changed, 401 insertions(+), 1 deletions(-) create mode 100644 main/xen/xsa36-4.2.patch create mode 100644 main/xen/xsa38.patch diff --git a/main/xen/APKBUILD b/main/xen/APKBUILD index 5e07fab..51ff406 100644 --- a/main/xen/APKBUILD +++ b/main/xen/APKBUILD @@ -3,7 +3,7 @@ # Maintainer: William Pitcock pkgname=xen pkgver=4.2.1 -pkgrel=5 +pkgrel=6 pkgdesc="Xen hypervisor" url="http://www.xen.org/" arch="x86 x86_64" @@ -24,6 +24,8 @@ source="http://bits.xensource.com/oss-xen/release/$pkgver/$pkgname-$pkgver.tar.g xsa41c.patch xsa34-4.2.patch xsa35-4.2-with-xsa34.patch + xsa36-4.2.patch + xsa38.patch xenstored.initd xenstored.confd @@ -145,6 +147,8 @@ ed7d0399c6ca6aeee479da5d8f807fe0 xsa41b.patch 2f3dd7bdc59d104370066d6582725575 xsa41c.patch af10e1a3f757a184a1d79904a5ef8572 xsa34-4.2.patch 8270dbf929e26b5e95532d10a697e404 xsa35-4.2-with-xsa34.patch +87a54b2a1f1ea3d955017fe1fd8c0398 xsa36-4.2.patch +47589e06d077d71282ec1b87dd4d87a9 xsa38.patch 95d8af17bf844d41a015ff32aae51ba1 xenstored.initd b017ccdd5e1c27bbf1513e3569d4ff07 xenstored.confd ed262f15fb880badb53575539468646c xenconsoled.initd diff --git a/main/xen/xsa36-4.2.patch b/main/xen/xsa36-4.2.patch new file mode 100644 index 0000000..8477701 --- /dev/null +++ b/main/xen/xsa36-4.2.patch @@ -0,0 +1,323 @@ +ACPI: acpi_table_parse() should return handler's error code + +Currently, the error code returned by acpi_table_parse()'s handler +is ignored. This patch will propagate handler's return value to +acpi_table_parse()'s caller. + +AMD,IOMMU: Clean up old entries in remapping tables when creating new +interrupt mapping. + +When changing the affinity of an IRQ associated with a passed +through PCI device, clear previous mapping. + +In addition, because some BIOSes may incorrectly program IVRS +entries for IOAPIC try to check for entry's consistency. Specifically, +if conflicting entries are found disable IOMMU if per-device +remapping table is used. If entries refer to bogus IOAPIC IDs +disable IOMMU unconditionally + +AMD,IOMMU: Disable IOMMU if SATA Combined mode is on + +AMD's SP5100 chipset can be placed into SATA Combined mode +that may cause prevent dom0 from booting when IOMMU is +enabled and per-device interrupt remapping table is used. +While SP5100 erratum 28 requires BIOSes to disable this mode, +some may still use it. + +This patch checks whether this mode is on and, if per-device +table is in use, disables IOMMU. + +AMD,IOMMU: Make per-device interrupt remapping table default + +Using global interrupt remapping table may be insecure, as +described by XSA-36. This patch makes per-device mode default. + +This is XSA-36 / CVE-2013-0153. + +Signed-off-by: Jan Beulich +Signed-off-by: Boris Ostrovsky + +--- a/xen/arch/x86/irq.c ++++ b/xen/arch/x86/irq.c +@@ -1942,9 +1942,6 @@ int map_domain_pirq( + spin_lock_irqsave(&desc->lock, flags); + set_domain_irq_pirq(d, irq, info); + spin_unlock_irqrestore(&desc->lock, flags); +- +- if ( opt_irq_vector_map == OPT_IRQ_VECTOR_MAP_PERDEV ) +- printk(XENLOG_INFO "Per-device vector maps for GSIs not implemented yet.\n"); + } + + done: +--- a/xen/drivers/acpi/tables.c ++++ b/xen/drivers/acpi/tables.c +@@ -267,7 +267,7 @@ acpi_table_parse_madt(enum acpi_madt_typ + * @handler: handler to run + * + * Scan the ACPI System Descriptor Table (STD) for a table matching @id, +- * run @handler on it. Return 0 if table found, return on if not. ++ * run @handler on it. + */ + int __init acpi_table_parse(char *id, acpi_table_handler handler) + { +@@ -282,8 +282,7 @@ int __init acpi_table_parse(char *id, ac + acpi_get_table(id, 0, &table); + + if (table) { +- handler(table); +- return 0; ++ return handler(table); + } else + return 1; + } +--- a/xen/drivers/passthrough/amd/iommu_acpi.c ++++ b/xen/drivers/passthrough/amd/iommu_acpi.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -635,6 +636,7 @@ static u16 __init parse_ivhd_device_spec + u16 header_length, u16 block_length, struct amd_iommu *iommu) + { + u16 dev_length, bdf; ++ int apic; + + dev_length = sizeof(*special); + if ( header_length < (block_length + dev_length) ) +@@ -651,10 +653,59 @@ static u16 __init parse_ivhd_device_spec + } + + add_ivrs_mapping_entry(bdf, bdf, special->header.data_setting, iommu); +- /* set device id of ioapic */ +- ioapic_sbdf[special->handle].bdf = bdf; +- ioapic_sbdf[special->handle].seg = seg; +- return dev_length; ++ ++ if ( special->variety != ACPI_IVHD_IOAPIC ) ++ { ++ if ( special->variety != ACPI_IVHD_HPET ) ++ printk(XENLOG_ERR "Unrecognized IVHD special variety %#x\n", ++ special->variety); ++ return dev_length; ++ } ++ ++ /* ++ * Some BIOSes have IOAPIC broken entries so we check for IVRS ++ * consistency here --- whether entry's IOAPIC ID is valid and ++ * whether there are conflicting/duplicated entries. ++ */ ++ for ( apic = 0; apic < nr_ioapics; apic++ ) ++ { ++ if ( IO_APIC_ID(apic) != special->handle ) ++ continue; ++ ++ if ( ioapic_sbdf[special->handle].pin_setup ) ++ { ++ if ( ioapic_sbdf[special->handle].bdf == bdf && ++ ioapic_sbdf[special->handle].seg == seg ) ++ AMD_IOMMU_DEBUG("IVHD Warning: Duplicate IO-APIC %#x entries\n", ++ special->handle); ++ else ++ { ++ printk(XENLOG_ERR "IVHD Error: Conflicting IO-APIC %#x entries\n", ++ special->handle); ++ if ( amd_iommu_perdev_intremap ) ++ return 0; ++ } ++ } ++ else ++ { ++ /* set device id of ioapic */ ++ ioapic_sbdf[special->handle].bdf = bdf; ++ ioapic_sbdf[special->handle].seg = seg; ++ ++ ioapic_sbdf[special->handle].pin_setup = xzalloc_array( ++ unsigned long, BITS_TO_LONGS(nr_ioapic_entries[apic])); ++ if ( nr_ioapic_entries[apic] && ++ !ioapic_sbdf[IO_APIC_ID(apic)].pin_setup ) ++ { ++ printk(XENLOG_ERR "IVHD Error: Out of memory\n"); ++ return 0; ++ } ++ } ++ return dev_length; ++ } ++ ++ printk(XENLOG_ERR "IVHD Error: Invalid IO-APIC %#x\n", special->handle); ++ return 0; + } + + static int __init parse_ivhd_block(const struct acpi_ivrs_hardware *ivhd_block) +--- a/xen/drivers/passthrough/amd/iommu_init.c ++++ b/xen/drivers/passthrough/amd/iommu_init.c +@@ -1126,12 +1126,45 @@ static int __init amd_iommu_setup_device + return 0; + } + ++/* Check whether SP5100 SATA Combined mode is on */ ++static bool_t __init amd_sp5100_erratum28(void) ++{ ++ u32 bus, id; ++ u16 vendor_id, dev_id; ++ u8 byte; ++ ++ for (bus = 0; bus < 256; bus++) ++ { ++ id = pci_conf_read32(0, bus, 0x14, 0, PCI_VENDOR_ID); ++ ++ vendor_id = id & 0xffff; ++ dev_id = (id >> 16) & 0xffff; ++ ++ /* SP5100 SMBus module sets Combined mode on */ ++ if (vendor_id != 0x1002 || dev_id != 0x4385) ++ continue; ++ ++ byte = pci_conf_read8(0, bus, 0x14, 0, 0xad); ++ if ( (byte >> 3) & 1 ) ++ { ++ printk(XENLOG_WARNING "AMD-Vi: SP5100 erratum 28 detected, disabling IOMMU.\n" ++ "If possible, disable SATA Combined mode in BIOS or contact your vendor for BIOS update.\n"); ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ + int __init amd_iommu_init(void) + { + struct amd_iommu *iommu; + + BUG_ON( !iommu_found() ); + ++ if ( amd_iommu_perdev_intremap && amd_sp5100_erratum28() ) ++ goto error_out; ++ + ivrs_bdf_entries = amd_iommu_get_ivrs_dev_entries(); + + if ( !ivrs_bdf_entries ) +--- a/xen/drivers/passthrough/amd/iommu_intr.c ++++ b/xen/drivers/passthrough/amd/iommu_intr.c +@@ -99,12 +99,12 @@ static void update_intremap_entry(u32* e + static void update_intremap_entry_from_ioapic( + int bdf, + struct amd_iommu *iommu, +- struct IO_APIC_route_entry *ioapic_rte) ++ const struct IO_APIC_route_entry *rte, ++ const struct IO_APIC_route_entry *old_rte) + { + unsigned long flags; + u32* entry; + u8 delivery_mode, dest, vector, dest_mode; +- struct IO_APIC_route_entry *rte = ioapic_rte; + int req_id; + spinlock_t *lock; + int offset; +@@ -120,6 +120,14 @@ static void update_intremap_entry_from_i + spin_lock_irqsave(lock, flags); + + offset = get_intremap_offset(vector, delivery_mode); ++ if ( old_rte ) ++ { ++ int old_offset = get_intremap_offset(old_rte->vector, ++ old_rte->delivery_mode); ++ ++ if ( offset != old_offset ) ++ free_intremap_entry(iommu->seg, bdf, old_offset); ++ } + entry = (u32*)get_intremap_entry(iommu->seg, req_id, offset); + update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest); + +@@ -188,6 +196,7 @@ int __init amd_iommu_setup_ioapic_remapp + amd_iommu_flush_intremap(iommu, req_id); + spin_unlock_irqrestore(&iommu->lock, flags); + } ++ set_bit(pin, ioapic_sbdf[IO_APIC_ID(apic)].pin_setup); + } + } + return 0; +@@ -199,6 +208,7 @@ void amd_iommu_ioapic_update_ire( + struct IO_APIC_route_entry old_rte = { 0 }; + struct IO_APIC_route_entry new_rte = { 0 }; + unsigned int rte_lo = (reg & 1) ? reg - 1 : reg; ++ unsigned int pin = (reg - 0x10) / 2; + int saved_mask, seg, bdf; + struct amd_iommu *iommu; + +@@ -236,6 +246,14 @@ void amd_iommu_ioapic_update_ire( + *(((u32 *)&new_rte) + 1) = value; + } + ++ if ( new_rte.mask && ++ !test_bit(pin, ioapic_sbdf[IO_APIC_ID(apic)].pin_setup) ) ++ { ++ ASSERT(saved_mask); ++ __io_apic_write(apic, reg, value); ++ return; ++ } ++ + /* mask the interrupt while we change the intremap table */ + if ( !saved_mask ) + { +@@ -244,7 +262,11 @@ void amd_iommu_ioapic_update_ire( + } + + /* Update interrupt remapping entry */ +- update_intremap_entry_from_ioapic(bdf, iommu, &new_rte); ++ update_intremap_entry_from_ioapic( ++ bdf, iommu, &new_rte, ++ test_and_set_bit(pin, ++ ioapic_sbdf[IO_APIC_ID(apic)].pin_setup) ? &old_rte ++ : NULL); + + /* Forward write access to IO-APIC RTE */ + __io_apic_write(apic, reg, value); +@@ -354,6 +376,12 @@ void amd_iommu_msi_msg_update_ire( + return; + } + ++ if ( msi_desc->remap_index >= 0 ) ++ update_intremap_entry_from_msi_msg(iommu, pdev, msi_desc, NULL); ++ ++ if ( !msg ) ++ return; ++ + update_intremap_entry_from_msi_msg(iommu, pdev, msi_desc, msg); + } + +--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c ++++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c +@@ -205,6 +205,8 @@ int __init amd_iov_detect(void) + { + printk("AMD-Vi: Not overriding irq_vector_map setting\n"); + } ++ if ( !amd_iommu_perdev_intremap ) ++ printk(XENLOG_WARNING "AMD-Vi: Using global interrupt remap table is not recommended (see XSA-36)!\n"); + return scan_pci_devices(); + } + +--- a/xen/drivers/passthrough/iommu.c ++++ b/xen/drivers/passthrough/iommu.c +@@ -52,7 +52,7 @@ bool_t __read_mostly iommu_qinval = 1; + bool_t __read_mostly iommu_intremap = 1; + bool_t __read_mostly iommu_hap_pt_share = 1; + bool_t __read_mostly iommu_debug; +-bool_t __read_mostly amd_iommu_perdev_intremap; ++bool_t __read_mostly amd_iommu_perdev_intremap = 1; + + DEFINE_PER_CPU(bool_t, iommu_dont_flush_iotlb); + +--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h ++++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h +@@ -100,6 +100,7 @@ void amd_iommu_read_msi_from_ire( + + extern struct ioapic_sbdf { + u16 bdf, seg; ++ unsigned long *pin_setup; + } ioapic_sbdf[MAX_IO_APICS]; + extern void *shared_intremap_table; + diff --git a/main/xen/xsa38.patch b/main/xen/xsa38.patch new file mode 100644 index 0000000..f4a5dc0 --- /dev/null +++ b/main/xen/xsa38.patch @@ -0,0 +1,73 @@ +diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml +index 3558889..d4d1c7b 100644 +--- a/tools/ocaml/libs/xb/partial.ml ++++ b/tools/ocaml/libs/xb/partial.ml +@@ -27,8 +27,15 @@ external header_size: unit -> int = "stub_header_size" + external header_of_string_internal: string -> int * int * int * int + = "stub_header_of_string" + ++let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *) ++ + let of_string s = + let tid, rid, opint, dlen = header_of_string_internal s in ++ (* A packet which is bigger than xenstore_payload_max is illegal. ++ This will leave the guest connection is a bad state and will ++ be hard to recover from without restarting the connection ++ (ie rebooting the guest) *) ++ let dlen = min xenstore_payload_max dlen in + { + tid = tid; + rid = rid; +@@ -38,6 +45,7 @@ let of_string s = + } + + let append pkt s sz = ++ if pkt.len > 4096 then failwith "Buffer.add: cannot grow buffer"; + Buffer.add_string pkt.buf (String.sub s 0 sz) + + let to_complete pkt = +diff --git a/tools/ocaml/libs/xb/xs_ring_stubs.c b/tools/ocaml/libs/xb/xs_ring_stubs.c +index 00414c5..4888ac5 100644 +--- a/tools/ocaml/libs/xb/xs_ring_stubs.c ++++ b/tools/ocaml/libs/xb/xs_ring_stubs.c +@@ -39,21 +39,23 @@ static int xs_ring_read(struct mmap_interface *interface, + char *buffer, int len) + { + struct xenstore_domain_interface *intf = interface->addr; +- XENSTORE_RING_IDX cons, prod; ++ XENSTORE_RING_IDX cons, prod; /* offsets only */ + int to_read; + +- cons = intf->req_cons; +- prod = intf->req_prod; ++ cons = *(volatile uint32*)&intf->req_cons; ++ prod = *(volatile uint32*)&intf->req_prod; + xen_mb(); ++ cons = MASK_XENSTORE_IDX(cons); ++ prod = MASK_XENSTORE_IDX(prod); + if (prod == cons) + return 0; +- if (MASK_XENSTORE_IDX(prod) > MASK_XENSTORE_IDX(cons)) ++ if (prod > cons) + to_read = prod - cons; + else +- to_read = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons); ++ to_read = XENSTORE_RING_SIZE - cons; + if (to_read < len) + len = to_read; +- memcpy(buffer, intf->req + MASK_XENSTORE_IDX(cons), len); ++ memcpy(buffer, intf->req + cons, len); + xen_mb(); + intf->req_cons += len; + return len; +@@ -66,8 +68,8 @@ static int xs_ring_write(struct mmap_interface *interface, + XENSTORE_RING_IDX cons, prod; + int can_write; + +- cons = intf->rsp_cons; +- prod = intf->rsp_prod; ++ cons = *(volatile uint32*)&intf->rsp_cons; ++ prod = *(volatile uint32*)&intf->rsp_prod; + xen_mb(); + if ( (prod - cons) >= XENSTORE_RING_SIZE ) + return 0; -- 1.7.7.5 (Apple Git-26) --- Unsubscribe: alpine-devel+unsubscribe@lists.alpinelinux.org Help: alpine-devel+help@lists.alpinelinux.org ---