4a5ee0f11d
5537a4d8-libxl-use-DEBUG-log-level-instead-of-INFO.patch - Upstream patches from Jan 55dc78e9-x86-amd_ucode-skip-updates-for-final-levels.patch 55dc7937-x86-IO-APIC-don-t-create-pIRQ-mapping-from-masked-RTE.patch 55df2f76-IOMMU-skip-domains-without-page-tables-when-dumping.patch 55e43fd8-x86-NUMA-fix-setup_node.patch 55e43ff8-x86-NUMA-don-t-account-hotplug-regions.patch 55e593f1-x86-NUMA-make-init_node_heap-respect-Xen-heap-limit.patch 54c2553c-grant-table-use-uint16_t-consistently-for-offset-and-length.patch 54ca33bc-grant-table-refactor-grant-copy-to-reduce-duplicate-code.patch 54ca340e-grant-table-defer-releasing-pages-acquired-in-a-grant-copy.patch - bsc#944463 - VUL-0: CVE-2015-5239: qemu-kvm: Integer overflow in vnc_client_read() and protocol_client_msg() CVE-2015-5239-qemuu-limit-client_cut_text-msg-payload-size.patch CVE-2015-5239-qemut-limit-client_cut_text-msg-payload-size.patch - bsc#944697 - VUL-1: CVE-2015-6815: qemu: net: e1000: infinite loop issue CVE-2015-6815-qemuu-e1000-fix-infinite-loop.patch CVE-2015-6815-qemut-e1000-fix-infinite-loop.patch OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=375
97 lines
3.3 KiB
Diff
97 lines
3.3 KiB
Diff
# Commit 22c5675877c8209adcfdb6bceddb561320374529
|
|
# Date 2015-08-25 16:17:13 +0200
|
|
# Author Aravind Gopalakrishnan <aravind.gopalakrishnan@amd.com>
|
|
# Committer Jan Beulich <jbeulich@suse.com>
|
|
x86, amd_ucode: skip microcode updates for final levels
|
|
|
|
Some of older[Fam10h] systems require that certain number of
|
|
applied microcode patch levels should not be overwritten by
|
|
the microcode loader. Otherwise, system hangs are known to occur.
|
|
|
|
The 'final_levels' of patch ids have been obtained empirically.
|
|
Refer bug https://bugzilla.suse.com/show_bug.cgi?id=913996
|
|
for details of the issue.
|
|
|
|
The short version is that people have predominantly noticed
|
|
system hang issues when trying to update microcode levels
|
|
beyond the patch IDs below.
|
|
[0x01000098, 0x0100009f, 0x010000af]
|
|
|
|
From internal discussions, we gathered that OS/hypervisor
|
|
cannot reliably perform microcode updates beyond these levels
|
|
due to hardware issues. Therefore, we need to abort microcode
|
|
update process if we hit any of these levels.
|
|
|
|
In this patch, we check for those microcode versions and abort
|
|
if the current core has one of those final patch levels applied
|
|
by the BIOS
|
|
|
|
A linux version of the patch has already made it into tip-
|
|
http://marc.info/?l=linux-kernel&m=143703405627170
|
|
|
|
Signed-off-by: Aravind Gopalakrishnan <aravind.gopalakrishnan@amd.com>
|
|
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
|
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
|
|
|
|
--- a/xen/arch/x86/microcode_amd.c
|
|
+++ b/xen/arch/x86/microcode_amd.c
|
|
@@ -347,6 +347,43 @@ static int container_fast_forward(const
|
|
return 0;
|
|
}
|
|
|
|
+/*
|
|
+ * The 'final_levels' of patch ids have been obtained empirically.
|
|
+ * Refer bug https://bugzilla.suse.com/show_bug.cgi?id=913996
|
|
+ * for details of the issue. The short version is that people
|
|
+ * using certain Fam10h systems noticed system hang issues when
|
|
+ * trying to update microcode levels beyond the patch IDs below.
|
|
+ * From internal discussions, we gathered that OS/hypervisor
|
|
+ * cannot reliably perform microcode updates beyond these levels
|
|
+ * due to hardware issues. Therefore, we need to abort microcode
|
|
+ * update process if we hit any of these levels.
|
|
+ */
|
|
+static const unsigned int final_levels[] = {
|
|
+ 0x01000098,
|
|
+ 0x0100009f,
|
|
+ 0x010000af
|
|
+};
|
|
+
|
|
+static bool_t check_final_patch_levels(unsigned int cpu)
|
|
+{
|
|
+ /*
|
|
+ * Check the current patch levels on the cpu. If they are equal to
|
|
+ * any of the 'final_levels', then we should not update the microcode
|
|
+ * patch on the cpu as system will hang otherwise.
|
|
+ */
|
|
+ struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
|
|
+ unsigned int i;
|
|
+
|
|
+ if ( boot_cpu_data.x86 != 0x10 )
|
|
+ return 0;
|
|
+
|
|
+ for ( i = 0; i < ARRAY_SIZE(final_levels); i++ )
|
|
+ if ( uci->cpu_sig.rev == final_levels[i] )
|
|
+ return 1;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int cpu_request_microcode(int cpu, const void *buf, size_t bufsize)
|
|
{
|
|
struct microcode_amd *mc_amd, *mc_old;
|
|
@@ -369,6 +406,14 @@ static int cpu_request_microcode(int cpu
|
|
goto out;
|
|
}
|
|
|
|
+ if ( check_final_patch_levels(cpu) )
|
|
+ {
|
|
+ printk(XENLOG_INFO
|
|
+ "microcode: Cannot update microcode patch on the cpu as we hit a final level\n");
|
|
+ error = -EPERM;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
mc_amd = xmalloc(struct microcode_amd);
|
|
if ( !mc_amd )
|
|
{
|