xen/55dc78e9-x86-amd_ucode-skip-updates-for-final-levels.patch
Charles Arnold 4a5ee0f11d - bsc#945164 - Xl destroy show error with kernel of SLES 12 sp1
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
2015-09-16 16:29:39 +00:00

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 )
{