diff --git a/23153-x86-amd-clear-DramModEn.patch b/23153-x86-amd-clear-DramModEn.patch deleted file mode 100644 index 0051c07..0000000 --- a/23153-x86-amd-clear-DramModEn.patch +++ /dev/null @@ -1,57 +0,0 @@ -# HG changeset patch -# User Wei Huang -# Date 1302076891 -3600 -# Node ID 8fb61c9ebe499b576687907d164da07802414925 -# Parent 97763efc41f9b664cf6f7db653c9c3f51e50b358 -x86, amd, MTRR: correct DramModEn bit of SYS_CFG MSR - -Some buggy BIOS might set SYS_CFG DramModEn bit to 1, which can cause -unexpected behavior on AMD platforms. This patch clears DramModEn bit -if it is 1. - -Signed-off-by: Wei Huang - ---- a/xen/arch/x86/cpu/amd.c -+++ b/xen/arch/x86/cpu/amd.c -@@ -318,6 +318,32 @@ static void check_disable_c1e(unsigned i - on_each_cpu(disable_c1e, NULL, 1); - } - -+/* -+ * BIOS is expected to clear MtrrFixDramModEn bit. According to AMD BKDG : -+ * "The MtrrFixDramModEn bit should be set to 1 during BIOS initalization of -+ * the fixed MTRRs, then cleared to 0 for operation." -+ */ -+static void check_syscfg_dram_mod_en(void) -+{ -+ uint64_t syscfg; -+ static bool_t printed = 0; -+ -+ if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && -+ (boot_cpu_data.x86 >= 0x0f))) -+ return; -+ -+ rdmsrl(MSR_K8_SYSCFG, syscfg); -+ if (!(syscfg & K8_MTRRFIXRANGE_DRAM_MODIFY)) -+ return; -+ -+ if (!test_and_set_bool(printed)) -+ printk(KERN_ERR "MTRR: SYSCFG[MtrrFixDramModEn] not " -+ "cleared by BIOS, clearing this bit\n"); -+ -+ syscfg &= ~K8_MTRRFIXRANGE_DRAM_MODIFY; -+ wrmsrl(MSR_K8_SYSCFG, syscfg); -+} -+ - static void __devinit init_amd(struct cpuinfo_x86 *c) - { - u32 l, h; -@@ -587,6 +613,8 @@ static void __devinit init_amd(struct cp - disable_c1_ramping(); - - set_cpuidmask(c); -+ -+ check_syscfg_dram_mod_en(); - } - - static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) diff --git a/23154-x86-amd-iorr-no-rdwr.patch b/23154-x86-amd-iorr-no-rdwr.patch deleted file mode 100644 index 6f42f83..0000000 --- a/23154-x86-amd-iorr-no-rdwr.patch +++ /dev/null @@ -1,51 +0,0 @@ -# HG changeset patch -# User Wei Huang -# Date 1302076933 -3600 -# Node ID 42fa70e0761bbb0596618ca5323664f31a2faa76 -# Parent 8fb61c9ebe499b576687907d164da07802414925 -x86, amd, MTRR: remove k8_enable_fixed_iorrs() - -AMD64 defines two special bits (bit 3 and 4) RdMem and WrMem in fixed -MTRR type. Their values are supposed to be 0 after BIOS hands the -control to OS according to AMD BKDG. Unless OS specificially turn them -on, they are kept 0 all the time. As a result, k8_enable_fixed_iorrs() -is unnecessary and removed from upstream kernel (see -https://patchwork.kernel.org/patch/11425/). This patch does the same -thing. - -Signed-off-by: Wei Huang - ---- a/xen/arch/x86/cpu/mtrr/generic.c -+++ b/xen/arch/x86/cpu/mtrr/generic.c -@@ -116,20 +116,6 @@ void mtrr_wrmsr(unsigned int msr, uint64 - } - - /** -- * Enable and allow read/write of extended fixed-range MTRR bits on K8 CPUs -- * see AMD publication no. 24593, chapter 3.2.1 for more information -- */ --static inline void k8_enable_fixed_iorrs(void) --{ -- uint64_t msr_content; -- -- rdmsrl(MSR_K8_SYSCFG, msr_content); -- mtrr_wrmsr(MSR_K8_SYSCFG, msr_content -- | K8_MTRRFIXRANGE_DRAM_ENABLE -- | K8_MTRRFIXRANGE_DRAM_MODIFY); --} -- --/** - * Checks and updates an fixed-range MTRR if it differs from the value it - * should have. If K8 extenstions are wanted, update the K8 SYSCFG MSR also. - * see AMD publication no. 24593, chapter 7.8.1, page 233 for more information -@@ -145,10 +131,6 @@ static void set_fixed_range(int msr, int - val = ((uint64_t)msrwords[1] << 32) | msrwords[0]; - - if (msr_content != val) { -- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && -- boot_cpu_data.x86 == 15 && -- ((msrwords[0] | msrwords[1]) & K8_MTRR_RDMEM_WRMEM_MASK)) -- k8_enable_fixed_iorrs(); - mtrr_wrmsr(msr, val); - *changed = TRUE; - } diff --git a/23200-amd-iommu-intremap-sync.patch b/23200-amd-iommu-intremap-sync.patch deleted file mode 100644 index 972adcc..0000000 --- a/23200-amd-iommu-intremap-sync.patch +++ /dev/null @@ -1,179 +0,0 @@ -References: bnc#680824 - -# HG changeset patch -# User Wei Wang -# Date 1302611179 -3600 -# Node ID 995a0c01a076e9c4fb124c090bc146a10d76bc7b -# Parent dbd98ab2f87facba8117bb881fa2ea5dfdb92960 -AMD IOMMU: Fix an interrupt remapping issue - -Some device could generate bogus interrupts if an IO-APIC RTE and an -iommu interrupt remapping entry are not consistent during 2 adjacent -64bits IO-APIC RTE updates. For example, if the 2nd operation updates -destination bits in RTE for SATA device and unmask it, in some case, -SATA device will assert ioapic pin to generate interrupt immediately -using new destination but iommu could still translate it into the old -destination, then dom0 would be confused. To fix that, we sync up -interrupt remapping entry with IO-APIC IRE on every 32 bits operation -and forward IOAPIC RTE updates after interrupt. - -Signed-off-by: Wei Wang -Acked-by: Jan Beulich - ---- a/xen/drivers/passthrough/amd/iommu_intr.c -+++ b/xen/drivers/passthrough/amd/iommu_intr.c -@@ -117,8 +117,7 @@ void invalidate_interrupt_table(struct a - static void update_intremap_entry_from_ioapic( - int bdf, - struct amd_iommu *iommu, -- struct IO_APIC_route_entry *ioapic_rte, -- unsigned int rte_upper, unsigned int value) -+ struct IO_APIC_route_entry *ioapic_rte) - { - unsigned long flags; - u32* entry; -@@ -130,28 +129,26 @@ static void update_intremap_entry_from_i - - req_id = get_intremap_requestor_id(bdf); - lock = get_intremap_lock(req_id); -- /* only remap interrupt vector when lower 32 bits in ioapic ire changed */ -- if ( likely(!rte_upper) ) -- { -- delivery_mode = rte->delivery_mode; -- vector = rte->vector; -- dest_mode = rte->dest_mode; -- dest = rte->dest.logical.logical_dest; - -- spin_lock_irqsave(lock, flags); -- offset = get_intremap_offset(vector, delivery_mode); -- entry = (u32*)get_intremap_entry(req_id, offset); -+ delivery_mode = rte->delivery_mode; -+ vector = rte->vector; -+ dest_mode = rte->dest_mode; -+ dest = rte->dest.logical.logical_dest; - -- update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest); -- spin_unlock_irqrestore(lock, flags); -+ spin_lock_irqsave(lock, flags); - -- if ( iommu->enabled ) -- { -- spin_lock_irqsave(&iommu->lock, flags); -- invalidate_interrupt_table(iommu, req_id); -- flush_command_buffer(iommu); -- spin_unlock_irqrestore(&iommu->lock, flags); -- } -+ offset = get_intremap_offset(vector, delivery_mode); -+ entry = (u32*)get_intremap_entry(req_id, offset); -+ update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest); -+ -+ spin_unlock_irqrestore(lock, flags); -+ -+ if ( iommu->enabled ) -+ { -+ spin_lock_irqsave(&iommu->lock, flags); -+ invalidate_interrupt_table(iommu, req_id); -+ flush_command_buffer(iommu); -+ spin_unlock_irqrestore(&iommu->lock, flags); - } - } - -@@ -199,7 +196,8 @@ int __init amd_iommu_setup_ioapic_remapp - spin_lock_irqsave(lock, flags); - offset = get_intremap_offset(vector, delivery_mode); - entry = (u32*)get_intremap_entry(req_id, offset); -- update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest); -+ update_intremap_entry(entry, vector, -+ delivery_mode, dest_mode, dest); - spin_unlock_irqrestore(lock, flags); - - if ( iommu->enabled ) -@@ -217,16 +215,17 @@ int __init amd_iommu_setup_ioapic_remapp - void amd_iommu_ioapic_update_ire( - unsigned int apic, unsigned int reg, unsigned int value) - { -- struct IO_APIC_route_entry ioapic_rte = { 0 }; -- unsigned int rte_upper = (reg & 1) ? 1 : 0; -+ 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; - int saved_mask, bdf; - struct amd_iommu *iommu; - -- *IO_APIC_BASE(apic) = reg; -- *(IO_APIC_BASE(apic)+4) = value; -- - if ( !iommu_intremap ) -+ { -+ __io_apic_write(apic, reg, value); - return; -+ } - - /* get device id of ioapic devices */ - bdf = ioapic_bdf[IO_APIC_ID(apic)]; -@@ -235,30 +234,49 @@ void amd_iommu_ioapic_update_ire( - { - AMD_IOMMU_DEBUG("Fail to find iommu for ioapic device id = 0x%x\n", - bdf); -+ __io_apic_write(apic, reg, value); - return; - } -- if ( rte_upper ) -- return; - -- /* read both lower and upper 32-bits of rte entry */ -- *IO_APIC_BASE(apic) = reg; -- *(((u32 *)&ioapic_rte) + 0) = *(IO_APIC_BASE(apic)+4); -- *IO_APIC_BASE(apic) = reg + 1; -- *(((u32 *)&ioapic_rte) + 1) = *(IO_APIC_BASE(apic)+4); -+ /* save io-apic rte lower 32 bits */ -+ *((u32 *)&old_rte) = __io_apic_read(apic, rte_lo); -+ saved_mask = old_rte.mask; -+ -+ if ( reg == rte_lo ) -+ { -+ *((u32 *)&new_rte) = value; -+ /* read upper 32 bits from io-apic rte */ -+ *(((u32 *)&new_rte) + 1) = __io_apic_read(apic, reg + 1); -+ } -+ else -+ { -+ *((u32 *)&new_rte) = *((u32 *)&old_rte); -+ *(((u32 *)&new_rte) + 1) = value; -+ } - - /* mask the interrupt while we change the intremap table */ -- saved_mask = ioapic_rte.mask; -- ioapic_rte.mask = 1; -- *IO_APIC_BASE(apic) = reg; -- *(IO_APIC_BASE(apic)+4) = *(((int *)&ioapic_rte)+0); -- ioapic_rte.mask = saved_mask; -+ if ( !saved_mask ) -+ { -+ old_rte.mask = 1; -+ __io_apic_write(apic, rte_lo, *((u32 *)&old_rte)); -+ } - -- update_intremap_entry_from_ioapic( -- bdf, iommu, &ioapic_rte, rte_upper, value); -+ /* Update interrupt remapping entry */ -+ update_intremap_entry_from_ioapic(bdf, iommu, &new_rte); -+ -+ /* Forward write access to IO-APIC RTE */ -+ __io_apic_write(apic, reg, value); -+ -+ /* For lower bits access, return directly to avoid double writes */ -+ if ( reg == rte_lo ) -+ return; - - /* unmask the interrupt after we have updated the intremap table */ -- *IO_APIC_BASE(apic) = reg; -- *(IO_APIC_BASE(apic)+4) = *(((u32 *)&ioapic_rte)+0); -+ if ( !saved_mask ) -+ { -+ old_rte.mask = saved_mask; -+ __io_apic_write(apic, rte_lo, *((u32 *)&old_rte)); -+ } - } - - static void update_intremap_entry_from_msi_msg( diff --git a/23228-x86-conditional-write_tsc.patch b/23228-x86-conditional-write_tsc.patch deleted file mode 100644 index ab3b82f..0000000 --- a/23228-x86-conditional-write_tsc.patch +++ /dev/null @@ -1,220 +0,0 @@ -References: bnc#623680 - -# HG changeset patch -# User Keir Fraser -# Date 1302853928 -3600 -# Node ID 1329d99b4f161b7617a667f601077cc92559f248 -# Parent b5165fb66b56d9438d77b475eaa9db67318d1ea1 -x86: don't write_tsc() non-zero values on CPUs updating only the lower 32 bits - -This means suppressing the uses in time_calibration_tsc_rendezvous(), -cstate_restore_tsc(), and synchronize_tsc_slave(), and fixes a boot -hang of Linux Dom0 when loading processor.ko on such systems that -have support for C states above C1. - -Signed-off-by: Jan Beulich -Signed-off-by: Keir Fraser - ---- a/xen/arch/x86/acpi/cpu_idle.c -+++ b/xen/arch/x86/acpi/cpu_idle.c -@@ -1099,3 +1099,7 @@ void cpuidle_disable_deep_cstate(void) - hpet_disable_legacy_broadcast(); - } - -+bool_t cpuidle_using_deep_cstate(void) -+{ -+ return xen_cpuidle && max_cstate > (local_apic_timer_c2_ok ? 2 : 1); -+} ---- a/xen/arch/x86/hpet.c -+++ b/xen/arch/x86/hpet.c -@@ -634,6 +634,9 @@ void hpet_disable_legacy_broadcast(void) - u32 cfg; - unsigned long flags; - -+ if ( !legacy_hpet_event.shift ) -+ return; -+ - spin_lock_irqsave(&legacy_hpet_event.lock, flags); - - legacy_hpet_event.flags |= HPET_EVT_DISABLE; ---- a/xen/arch/x86/smpboot.c -+++ b/xen/arch/x86/smpboot.c -@@ -41,6 +41,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -134,6 +135,12 @@ static void smp_store_cpu_info(int id) - ; - } - -+/* -+ * TSC's upper 32 bits can't be written in earlier CPUs (before -+ * Prescott), there is no way to resync one AP against BP. -+ */ -+bool_t disable_tsc_sync; -+ - static atomic_t tsc_count; - static uint64_t tsc_value; - static cpumask_t tsc_sync_cpu_mask; -@@ -142,6 +149,9 @@ static void synchronize_tsc_master(unsig - { - unsigned int i; - -+ if ( disable_tsc_sync ) -+ return; -+ - if ( boot_cpu_has(X86_FEATURE_TSC_RELIABLE) && - !cpu_isset(slave, tsc_sync_cpu_mask) ) - return; -@@ -163,6 +173,9 @@ static void synchronize_tsc_slave(unsign - { - unsigned int i; - -+ if ( disable_tsc_sync ) -+ return; -+ - if ( boot_cpu_has(X86_FEATURE_TSC_RELIABLE) && - !cpu_isset(slave, tsc_sync_cpu_mask) ) - return; ---- a/xen/arch/x86/time.c -+++ b/xen/arch/x86/time.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -682,6 +683,8 @@ void cstate_restore_tsc(void) - if ( boot_cpu_has(X86_FEATURE_NONSTOP_TSC) ) - return; - -+ ASSERT(boot_cpu_has(X86_FEATURE_TSC_RELIABLE)); -+ - write_tsc(stime2tsc(read_platform_stime())); - } - -@@ -1384,6 +1387,66 @@ void init_percpu_time(void) - } - } - -+/* -+ * On certain older Intel CPUs writing the TSC MSR clears the upper 32 bits. -+ * Obviously we must not use write_tsc() on such CPUs. -+ * -+ * Additionally, AMD specifies that being able to write the TSC MSR is not an -+ * architectural feature (but, other than their manual says, also cannot be -+ * determined from CPUID bits). -+ */ -+static void __init tsc_check_writability(void) -+{ -+ const char *what = NULL; -+ uint64_t tsc; -+ -+ /* -+ * If all CPUs are reported as synchronised and in sync, we never write -+ * the TSCs (except unavoidably, when a CPU is physically hot-plugged). -+ * Hence testing for writability is pointless and even harmful. -+ */ -+ if ( boot_cpu_has(X86_FEATURE_TSC_RELIABLE) ) -+ return; -+ -+ rdtscll(tsc); -+ if ( wrmsr_safe(MSR_IA32_TSC, 0) == 0 ) -+ { -+ uint64_t tmp, tmp2; -+ rdtscll(tmp2); -+ write_tsc(tsc | (1ULL << 32)); -+ rdtscll(tmp); -+ if ( ABS((s64)tmp - (s64)tmp2) < (1LL << 31) ) -+ what = "only partially"; -+ } -+ else -+ { -+ what = "not"; -+ } -+ -+ /* Nothing to do if the TSC is fully writable. */ -+ if ( !what ) -+ { -+ /* -+ * Paranoia - write back original TSC value. However, APs get synced -+ * with BSP as they are brought up, so this doesn't much matter. -+ */ -+ write_tsc(tsc); -+ return; -+ } -+ -+ printk(XENLOG_WARNING "TSC %s writable\n", what); -+ -+ /* time_calibration_tsc_rendezvous() must not be used */ -+ setup_clear_cpu_cap(X86_FEATURE_CONSTANT_TSC); -+ -+ /* cstate_restore_tsc() must not be used (or do nothing) */ -+ if ( !boot_cpu_has(X86_FEATURE_NONSTOP_TSC) ) -+ cpuidle_disable_deep_cstate(); -+ -+ /* synchronize_tsc_slave() must do nothing */ -+ disable_tsc_sync = 1; -+} -+ - /* Late init function (after all CPUs are booted). */ - int __init init_xen_time(void) - { -@@ -1400,6 +1463,8 @@ int __init init_xen_time(void) - setup_clear_cpu_cap(X86_FEATURE_TSC_RELIABLE); - } - -+ tsc_check_writability(); -+ - /* If we have constant-rate TSCs then scale factor can be shared. */ - if ( boot_cpu_has(X86_FEATURE_CONSTANT_TSC) ) - { -@@ -1451,7 +1516,7 @@ static int disable_pit_irq(void) - * XXX dom0 may rely on RTC interrupt delivery, so only enable - * hpet_broadcast if FSB mode available or if force_hpet_broadcast. - */ -- if ( xen_cpuidle && !boot_cpu_has(X86_FEATURE_ARAT) ) -+ if ( cpuidle_using_deep_cstate() && !boot_cpu_has(X86_FEATURE_ARAT) ) - { - hpet_broadcast_init(); - if ( !hpet_broadcast_is_available() ) ---- a/xen/include/asm-x86/setup.h -+++ b/xen/include/asm-x86/setup.h -@@ -4,7 +4,6 @@ - #include - - extern bool_t early_boot; --extern s8 xen_cpuidle; - extern unsigned long xenheap_initial_phys_start; - - void init_done(void); ---- a/xen/include/asm-x86/time.h -+++ b/xen/include/asm-x86/time.h -@@ -24,6 +24,8 @@ - - typedef u64 cycles_t; - -+extern bool_t disable_tsc_sync; -+ - static inline cycles_t get_cycles(void) - { - cycles_t c; ---- a/xen/include/xen/cpuidle.h -+++ b/xen/include/xen/cpuidle.h -@@ -85,7 +85,10 @@ struct cpuidle_governor - void (*reflect) (struct acpi_processor_power *dev); - }; - -+extern s8 xen_cpuidle; - extern struct cpuidle_governor *cpuidle_current_governor; -+ -+bool_t cpuidle_using_deep_cstate(void); - void cpuidle_disable_deep_cstate(void); - - extern void cpuidle_wakeup_mwait(cpumask_t *mask); diff --git a/cve-2011-1583-4.1.patch b/cve-2011-1583-4.1.patch deleted file mode 100644 index 1d2c4a3..0000000 --- a/cve-2011-1583-4.1.patch +++ /dev/null @@ -1,217 +0,0 @@ -diff -r dbf2ddf652dc tools/libxc/xc_dom_bzimageloader.c ---- a/tools/libxc/xc_dom_bzimageloader.c Thu Apr 07 15:26:58 2011 +0100 -+++ b/tools/libxc/xc_dom_bzimageloader.c Thu Apr 21 12:05:57 2011 +0100 -@@ -82,8 +82,29 @@ static int xc_try_bzip2_decode( - for ( ; ; ) - { - ret = BZ2_bzDecompress(&stream); -- if ( (stream.avail_out == 0) || (ret != BZ_OK) ) -+ if ( ret == BZ_STREAM_END ) - { -+ DOMPRINTF("BZIP2: Saw data stream end"); -+ retval = 0; -+ break; -+ } -+ if ( ret != BZ_OK ) -+ { -+ DOMPRINTF("BZIP2: error %d", ret); -+ free(out_buf); -+ goto bzip2_cleanup; -+ } -+ -+ if ( stream.avail_out == 0 ) -+ { -+ /* Protect against output buffer overflow */ -+ if ( outsize > INT_MAX / 2 ) -+ { -+ DOMPRINTF("BZIP2: output buffer overflow"); -+ free(out_buf); -+ goto bzip2_cleanup; -+ } -+ - tmp_buf = realloc(out_buf, outsize * 2); - if ( tmp_buf == NULL ) - { -@@ -97,16 +118,18 @@ static int xc_try_bzip2_decode( - stream.avail_out = (outsize * 2) - outsize; - outsize *= 2; - } -- -- if ( ret != BZ_OK ) -+ else if ( stream.avail_in == 0 ) - { -- if ( ret == BZ_STREAM_END ) -- { -- DOMPRINTF("BZIP2: Saw data stream end"); -- retval = 0; -- break; -- } -- DOMPRINTF("BZIP2: error"); -+ /* -+ * If there is output buffer available then this indicates -+ * that BZ2_bzDecompress would like more input data to be -+ * provided. However our complete input buffer is in -+ * memory and provided upfront so if avail_in is zero this -+ * actually indicates a truncated input. -+ */ -+ DOMPRINTF("BZIP2: not enough input"); -+ free(out_buf); -+ goto bzip2_cleanup; - } - } - -@@ -180,31 +203,14 @@ static int xc_try_lzma_decode( - for ( ; ; ) - { - ret = lzma_code(&stream, action); -- if ( (stream.avail_out == 0) || (ret != LZMA_OK) ) -+ if ( ret == LZMA_STREAM_END ) - { -- tmp_buf = realloc(out_buf, outsize * 2); -- if ( tmp_buf == NULL ) -- { -- DOMPRINTF("LZMA: Failed to realloc memory"); -- free(out_buf); -- goto lzma_cleanup; -- } -- out_buf = tmp_buf; -- -- stream.next_out = out_buf + outsize; -- stream.avail_out = (outsize * 2) - outsize; -- outsize *= 2; -+ DOMPRINTF("LZMA: Saw data stream end"); -+ retval = 0; -+ break; - } -- - if ( ret != LZMA_OK ) - { -- if ( ret == LZMA_STREAM_END ) -- { -- DOMPRINTF("LZMA: Saw data stream end"); -- retval = 0; -- break; -- } -- - switch ( ret ) - { - case LZMA_MEM_ERROR: -@@ -238,7 +244,32 @@ static int xc_try_lzma_decode( - } - DOMPRINTF("%s: LZMA decompression error %s", - __FUNCTION__, msg); -- break; -+ free(out_buf); -+ goto lzma_cleanup; -+ } -+ -+ if ( stream.avail_out == 0 ) -+ { -+ /* Protect against output buffer overflow */ -+ if ( outsize > INT_MAX / 2 ) -+ { -+ DOMPRINTF("LZMA: output buffer overflow"); -+ free(out_buf); -+ goto lzma_cleanup; -+ } -+ -+ tmp_buf = realloc(out_buf, outsize * 2); -+ if ( tmp_buf == NULL ) -+ { -+ DOMPRINTF("LZMA: Failed to realloc memory"); -+ free(out_buf); -+ goto lzma_cleanup; -+ } -+ out_buf = tmp_buf; -+ -+ stream.next_out = out_buf + outsize; -+ stream.avail_out = (outsize * 2) - outsize; -+ outsize *= 2; - } - } - -@@ -489,18 +520,18 @@ struct setup_header { - - extern struct xc_dom_loader elf_loader; - --static unsigned int payload_offset(struct setup_header *hdr) -+static int check_magic(struct xc_dom_image *dom, const void *magic, size_t len) - { -- unsigned int off; -+ if (len > dom->kernel_size) -+ return 0; - -- off = (hdr->setup_sects + 1) * 512; -- off += hdr->payload_offset; -- return off; -+ return (memcmp(dom->kernel_blob, magic, len) == 0); - } - - static int xc_dom_probe_bzimage_kernel(struct xc_dom_image *dom) - { - struct setup_header *hdr; -+ uint64_t payload_offset, payload_length; - int ret; - - if ( dom->kernel_blob == NULL ) -@@ -533,10 +564,30 @@ static int xc_dom_probe_bzimage_kernel(s - return -EINVAL; - } - -- dom->kernel_blob = dom->kernel_blob + payload_offset(hdr); -- dom->kernel_size = hdr->payload_length; - -- if ( memcmp(dom->kernel_blob, "\037\213", 2) == 0 ) -+ /* upcast to 64 bits to avoid overflow */ -+ /* setup_sects is u8 and so cannot overflow */ -+ payload_offset = (hdr->setup_sects + 1) * 512; -+ payload_offset += hdr->payload_offset; -+ payload_length = hdr->payload_length; -+ -+ if ( payload_offset >= dom->kernel_size ) -+ { -+ xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: payload offset overflow", -+ __FUNCTION__); -+ return -EINVAL; -+ } -+ if ( (payload_offset + payload_length) > dom->kernel_size ) -+ { -+ xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: payload length overflow", -+ __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ dom->kernel_blob = dom->kernel_blob + payload_offset; -+ dom->kernel_size = payload_length; -+ -+ if ( check_magic(dom, "\037\213", 2) ) - { - ret = xc_dom_try_gunzip(dom, &dom->kernel_blob, &dom->kernel_size); - if ( ret == -1 ) -@@ -546,7 +597,7 @@ static int xc_dom_probe_bzimage_kernel(s - return -EINVAL; - } - } -- else if ( memcmp(dom->kernel_blob, "\102\132\150", 3) == 0 ) -+ else if ( check_magic(dom, "\102\132\150", 3) ) - { - ret = xc_try_bzip2_decode(dom, &dom->kernel_blob, &dom->kernel_size); - if ( ret < 0 ) -@@ -557,7 +608,7 @@ static int xc_dom_probe_bzimage_kernel(s - return -EINVAL; - } - } -- else if ( memcmp(dom->kernel_blob, "\135\000", 2) == 0 ) -+ else if ( check_magic(dom, "\135\000", 2) ) - { - ret = xc_try_lzma_decode(dom, &dom->kernel_blob, &dom->kernel_size); - if ( ret < 0 ) -@@ -568,7 +619,7 @@ static int xc_dom_probe_bzimage_kernel(s - return -EINVAL; - } - } -- else if ( memcmp(dom->kernel_blob, "\x89LZO", 5) == 0 ) -+ else if ( check_magic(dom, "\x89LZO", 5) ) - { - ret = xc_try_lzo1x_decode(dom, &dom->kernel_blob, &dom->kernel_size); - if ( ret < 0 )