diff --git a/SPECS/01-microcode.conf b/SPECS/01-microcode.conf new file mode 100644 index 0000000..52511c0 --- /dev/null +++ b/SPECS/01-microcode.conf @@ -0,0 +1 @@ +early_microcode="yes" diff --git a/SPECS/06-2d-07 b/SPECS/06-2d-07 new file mode 100644 index 0000000..0da2b9e Binary files /dev/null and b/SPECS/06-2d-07 differ diff --git a/SPECS/06-2d-07_config b/SPECS/06-2d-07_config new file mode 100644 index 0000000..979455d --- /dev/null +++ b/SPECS/06-2d-07_config @@ -0,0 +1,13 @@ +model GenuineIntel 06-2d-07 +path intel-ucode/06-2d-07 +## The "kernel_early" statements are carried over from the intel caveat config +## in order to avoid enabling this newer microcode on these problematic kernels; +## see the caveat description in /usr/share/doc/microcode_ctl/caveats/intel_readme +## (That also means that this caveat has to be enforced separately on these +## kernels.) +kernel_early 4.10.0 +kernel_early 3.10.0-930 +kernel_early 3.10.0-862.14.1 +kernel_early 3.10.0-693.38.1 +kernel_early 3.10.0-514.57.1 +kernel_early 3.10.0-327.73.1 diff --git a/SPECS/06-2d-07_disclaimer b/SPECS/06-2d-07_disclaimer new file mode 100644 index 0000000..ae71a34 --- /dev/null +++ b/SPECS/06-2d-07_disclaimer @@ -0,0 +1,4 @@ +MDS-related microcode update for Intel Sandy Bridge-EP (family 6, model 45, +stepping 7; CPUID 0x206d7) CPUs is disabled. +Please refer to /usr/share/doc/microcode_ctl/caveats/06-2d-07_readme +and /usr/share/doc/microcode_ctl/README.caveats for details. diff --git a/SPECS/06-2d-07_readme b/SPECS/06-2d-07_readme new file mode 100644 index 0000000..e5e575b --- /dev/null +++ b/SPECS/06-2d-07_readme @@ -0,0 +1,58 @@ +Intel Sandy Bridge-E/EN/EP CPU models (SNB-EP, family 6, model 45, stepping 7) +had issues with MDS-related microcode update that may lead to a system hang +after a microcode update[1][2]. In order to address this, microcode update +to the MDS-related revision 0x718 had been disabled, and the previously +published microcode revision 0x714 is used by default for the OS-driven +microcode update. The revision 0x71a of the microcode is intended to fix +the aforementioned issue, hence it is enabled by default (but can be disabled +explicitly; see below). + +[1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/15 +[2] https://access.redhat.com/solutions/4593951 + +For the reference, SHA1 checksums of 06-2d-07 microcode files containing +microcode revisions in question are listed below: + * 06-2d-07, revision 0x714: bcf2173cd3dd499c37defbc2533703cfa6ec2430 + * 06-2d-07, revision 0x718: 837cfebbfc09b911151dfd179082ad99cf87e85d + * 06-2d-07, revision 0x71a: 4512c8149e63e5ed15f45005d7fb5be0041f66f6 + +Please contact your system vendor for a BIOS/firmware update that contains +the latest microcode version. For the information regarding microcode versions +required for mitigating specific side-channel cache attacks, please refer +to the following knowledge base articles: + * CVE-2017-5715 ("Spectre"): + https://access.redhat.com/articles/3436091 + * CVE-2018-3639 ("Speculative Store Bypass"): + https://access.redhat.com/articles/3540901 + * CVE-2018-3620, CVE-2018-3646 ("L1 Terminal Fault Attack"): + https://access.redhat.com/articles/3562741 + * CVE-2018-12130, CVE-2018-12126, CVE-2018-12127, and CVE-2019-11091 + ("Microarchitectural Data Sampling"): + https://access.redhat.com/articles/4138151 + +The information regarding disabling microcode update is provided below. + +To disable usage of the newer microcode revision for a specific kernel +version, please create file "disallow-intel-06-2d-07" inside +/lib/firmware/ directory, run +"/usr/libexec/microcode_ctl/update_ucode" to add it to firmware directory +where microcode will be available for late microcode update, and run +"dracut -f --kver ", so initramfs for this kernel version +is regenerated and the microcode can be loaded early, for example: + + touch /lib/firmware/3.10.0-862.9.1/disallow-intel-06-2d-07 + /usr/libexec/microcode_ctl/update_ucode + dracut -f --kver 3.10.0-862.9.1 + +To avoid addition of the newer microcode revision for all kernels, please create +file "/etc/microcode_ctl/ucode_with_caveats/disallow-intel-06-2d-07", run +"/usr/libexec/microcode_ctl/update_ucode" for late microcode updates, +and "dracut -f --regenerate-all" for early microcode updates: + + mkdir -p /etc/microcode_ctl/ucode_with_caveats + touch /etc/microcode_ctl/ucode_with_caveats/disallow-intel-06-2d-07 + /usr/libexec/microcode_ctl/update_ucode + dracut -f --regenerate-all + +Please refer to /usr/share/doc/microcode_ctl/README.caveats for additional +information. diff --git a/SPECS/06-4e-03 b/SPECS/06-4e-03 new file mode 100644 index 0000000..1fabcf8 Binary files /dev/null and b/SPECS/06-4e-03 differ diff --git a/SPECS/06-4e-03_config b/SPECS/06-4e-03_config new file mode 100644 index 0000000..bee51b2 --- /dev/null +++ b/SPECS/06-4e-03_config @@ -0,0 +1,3 @@ +model GenuineIntel 06-4e-03 +path intel-ucode/06-4e-03 +disable early late diff --git a/SPECS/06-4e-03_disclaimer b/SPECS/06-4e-03_disclaimer new file mode 100644 index 0000000..ec27ef7 --- /dev/null +++ b/SPECS/06-4e-03_disclaimer @@ -0,0 +1,5 @@ +Microcode revisions 0xda and higher for Intel Skylake-U/Y (family 6, +model 78, stepping 3; CPUID 0x406e3) are disabled as they may cause system +instability; the previously published revision 0xd6 is used instead. +Please refer to /usr/share/doc/microcode_ctl/caveats/06-4e-03_readme +and /usr/share/doc/microcode_ctl/README.caveats for details. diff --git a/SPECS/06-4e-03_readme b/SPECS/06-4e-03_readme new file mode 100644 index 0000000..e221544 --- /dev/null +++ b/SPECS/06-4e-03_readme @@ -0,0 +1,68 @@ +Some Intel Skylake CPU models (SKL-U/Y, family 6, model 78, stepping 3) +have reports of system hangs when revision 0xdc of microcode, that is included +since microcode-20200609 update to address CVE-2020-0543, CVE-2020-0548, +and CVE-2020-0549, is applied[1]. In order to address this, microcode update +to the newer revision has been disabled by default on these systems, +and the previously published microcode revision 0xd6 is used by default +for the OS-driven microcode update. + +[1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/31 + +For the reference, SHA1 checksums of 06-55-04 microcode files containing +microcode revisions in question are listed below: + * 06-4e-03, revision 0xd6: 06432a25053c823b0e2a6b8e84e2e2023ee3d43e + * 06-4e-03, revision 0xdc: cd1733458d187486999337ff8b51eeaa0cfbca6c + +Please contact your system vendor for a BIOS/firmware update that contains +the latest microcode version. For the information regarding microcode versions +required for mitigating specific side-channel cache attacks, please refer +to the following knowledge base articles: + * CVE-2017-5715 ("Spectre"): + https://access.redhat.com/articles/3436091 + * CVE-2018-3639 ("Speculative Store Bypass"): + https://access.redhat.com/articles/3540901 + * CVE-2018-3620, CVE-2018-3646 ("L1 Terminal Fault Attack"): + https://access.redhat.com/articles/3562741 + * CVE-2018-12130, CVE-2018-12126, CVE-2018-12127, and CVE-2019-11091 + ("Microarchitectural Data Sampling"): + https://access.redhat.com/articles/4138151 + * CVE-2019-0117 (Intel SGX Information Leak), + CVE-2019-0123 (Intel SGX Privilege Escalation), + CVE-2019-11135 (TSX Asynchronous Abort), + CVE-2019-11139 (Voltage Setting Modulation): + https://access.redhat.com/solutions/2019-microcode-nov + * CVE-2020-0543 (Special Register Buffer Data Sampling), + CVE-2020-0548 (Vector Register Data Sampling), + CVE-2020-0549 (L1D Cache Eviction Sampling): + https://access.redhat.com/solutions/5142751 + +The information regarding enforcing microcode update is provided below. + +To enforce usage of the latest 06-4e-03 microcode revision for a specific kernel +version, please create a file "force-intel-06-4e-03" inside +/lib/firmware/ directory, run +"/usr/libexec/microcode_ctl/update_ucode" to add it to firmware directory +where microcode will be available for late microcode update, and run +"dracut -f --kver ", so initramfs for this kernel version +is regenerated and the microcode can be loaded early, for example: + + touch /lib/firmware/3.10.0-862.9.1/force-intel-06-4e-03 + /usr/libexec/microcode_ctl/update_ucode + dracut -f --kver 3.10.0-862.9.1 + +After that, it is possible to perform a late microcode update by executing +"/usr/libexec/microcode_ctl/reload_microcode" or by writing value "1" to +"/sys/devices/system/cpu/microcode/reload" directly. + +To enforce addition of this microcode for all kernels, please create file +"/etc/microcode_ctl/ucode_with_caveats/force-intel-06-4e-03", run +"/usr/libexec/microcode_ctl/update_ucode" for enabling late microcode updates, +and "dracut -f --regenerate-all" for enabling early microcode updates: + + mkdir -p /etc/microcode_ctl/ucode_with_caveats + touch /etc/microcode_ctl/ucode_with_caveats/force-intel-06-4e-03 + /usr/libexec/microcode_ctl/update_ucode + dracut -f --regenerate-all + +Please refer to /usr/share/doc/microcode_ctl/README.caveats for additional +information. diff --git a/SPECS/06-4f-01_config b/SPECS/06-4f-01_config new file mode 100644 index 0000000..f589fbf --- /dev/null +++ b/SPECS/06-4f-01_config @@ -0,0 +1,21 @@ +model GenuineIntel 06-4f-01 +path intel-ucode/06-4f-01 +kernel 4.17.0 +kernel 3.10.0-894 +kernel 3.10.0-862.6.1 +kernel 3.10.0-693.35.1 +kernel 3.10.0-514.52.1 +kernel 3.10.0-327.70.1 +kernel 2.6.32-754.1.1 +kernel 2.6.32-573.58.1 +kernel 2.6.32-504.71.1 +kernel 2.6.32-431.90.1 +kernel 2.6.32-358.90.1 +kernel_early 4.10.0 +kernel_early 3.10.0-930 +kernel_early 3.10.0-862.14.1 +kernel_early 3.10.0-693.38.1 +kernel_early 3.10.0-514.57.1 +kernel_early 3.10.0-327.73.1 +mc_min_ver_late 0xb000019 +disable early late diff --git a/SPECS/06-4f-01_disclaimer b/SPECS/06-4f-01_disclaimer new file mode 100644 index 0000000..c978958 --- /dev/null +++ b/SPECS/06-4f-01_disclaimer @@ -0,0 +1,4 @@ +Microcode update for Intel Broadwell-EP/EX (BDX-ML B/M/R0; family 6, model 79, +stepping 1; CPUID 0x406f1) CPUs is disabled as it may cause system instability. +Please refer to /usr/share/doc/microcode_ctl/caveats/06-4f-01_readme +and /usr/share/doc/microcode_ctl/README.caveats for details. diff --git a/SPECS/06-4f-01_readme b/SPECS/06-4f-01_readme new file mode 100644 index 0000000..962c7a6 --- /dev/null +++ b/SPECS/06-4f-01_readme @@ -0,0 +1,78 @@ +Intel Broadwell-EP/EX (BDX-ML B/M/R0, family 6, model 79, stepping 1) has issues +with microcode update that may lead to a system hang; while some changes +to the Linux kernel have been made in an attempt to address these issues, +they were not eliminated, so a possibility of unstable system behaviour +after a microcode update performed on a running system is still present even +on a kernels that contain aforementioned changes. As a result, microcode update +for this CPU model has been disabled by default. + +For the reference, kernel versions for the respective RHEL minor versions +that contain the aforementioned changes, are listed below: + * Upstream/RHEL 8: kernel-4.17.0 or newer; + * RHEL 7.6 onwards: kernel-3.10.0-894 or newer; + * RHEL 7.5.z: kernel-3.10.0-862.6.1 or newer; + * RHEL 7.4.z: kernel-3.10.0-693.35.1 or newer; + * RHEL 7.3.z: kernel-3.10.0-514.52.1 or newer; + * RHEL 7.2.z: kernel-3.10.0-327.70.1 or newer. + +Please contact you system vendor for a BIOS/firmware update that contains +the latest microcode version. For the information regarding microcode versions +required for mitigating specific side-channel cache attacks, please refer +to the following knowledge base articles: + * CVE-2017-5715 ("Spectre"): + https://access.redhat.com/articles/3436091 + * CVE-2018-3639 ("Speculative Store Bypass"): + https://access.redhat.com/articles/3540901 + * CVE-2018-3620, CVE-2018-3646 ("L1 Terminal Fault Attack"): + https://access.redhat.com/articles/3562741 + * CVE-2018-12130, CVE-2018-12126, CVE-2018-12127, and CVE-2019-11091 + ("Microarchitectural Data Sampling"): + https://access.redhat.com/articles/4138151 + +The information regarding enforcing microcode load is provided below. + +For enforcing addition of this microcode to the firmware directory +for a specific kernel, where it is available for a late microcode update, +please create a file "force-late-intel-06-4f-01" inside +/lib/firmware/ directory and run +"/usr/libexec/microcode_ctl/update_ucode": + + touch /lib/firmware/3.10.0-862.9.1/force-late-intel-06-4f-01 + /usr/libexec/microcode_ctl/update_ucode + +After that, it is possible to perform a late microcode update by executing +"/usr/libexec/microcode_ctl/reload_microcode" or by writing value "1" to +"/sys/devices/system/cpu/microcode/reload" directly. + +For enforcing addition of this microcode to firmware directories for all +kernels, please create a file +"/etc/microcode_ctl/ucode_with_caveats/force-late-intel-06-4f-01" +and run "/usr/libexec/microcode_ctl/update_ucode": + + mkdir -p /etc/microcode_ctl/ucode_with_caveats + touch /etc/microcode_ctl/ucode_with_caveats/force-late-intel-06-4f-01 + /usr/libexec/microcode_ctl/update_ucode + +For enforcing early load of this microcode for a specific kernel, please +create a file "force-early-intel-06-4f-01" inside +"/lib/firmware/" directory and run +"dracut -f --kver ": + + touch /lib/firmware/3.10.0-862.9.1/force-early-intel-06-4f-01 + dracut -f --kver 3.10.0-862.9.1 + +For enforcing early load of this microcode for all kernels, please +create a file "/etc/microcode_ctl/ucode_with_caveats/force-early-intel-06-4f-01" +and run dracut -f --regenerate-all: + + mkdir -p /etc/microcode_ctl/ucode_with_caveats + touch /etc/microcode_ctl/ucode_with_caveats/force-early-intel-06-4f-01 + dracut -f --regenerate-all + +If you want to avoid removal of the microcode file during cleanup performed by +/usr/libexec/microcode_ctl/update_ucode, please remove the corresponding readme +file (/lib/firmware//readme-intel-06-4f-01). + + +Please refer to /usr/share/doc/microcode_ctl/README.caveats for additional +information. diff --git a/SPECS/06-55-04 b/SPECS/06-55-04 new file mode 100644 index 0000000..754d081 Binary files /dev/null and b/SPECS/06-55-04 differ diff --git a/SPECS/06-55-04_config b/SPECS/06-55-04_config new file mode 100644 index 0000000..373c8ac --- /dev/null +++ b/SPECS/06-55-04_config @@ -0,0 +1,22 @@ +model GenuineIntel 06-55-04 +path intel-ucode/06-55-04 +## Bug https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/21 +## affects only SKX-W/X (Workstation and HEDT segments); product segment +## can be determined by checking bits 5..3 of the CAPID0 field in PCU registers +## device (see https://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/xeon-scalable-spec-update.pdf#page=13 +## for Server/FPGA/Fabric segments description; for SKX-W/X no public +## documentation seems to be available). Specific device/function numbers +## are provided for speeding up the search only, VID:DID is the real selector. +## Commented out since revision 0x2006906 seems to fix the issue. +#pci_config_val mode=success-all device=0x1e function=3 vid=0x8086 did=0x2083 offset=0x84 size=4 mask=0x38 val=0x38,0x18,0x8 +## The "kernel_early" statements are carried over from the intel caveat config +## in order to avoid enabling this newer microcode on these problematic kernels; +## see the caveat description in /usr/share/doc/microcode_ctl/caveats/intel_readme +## (That also means that this caveat has to be enforced separately on these +## kernels.) +kernel_early 4.10.0 +kernel_early 3.10.0-930 +kernel_early 3.10.0-862.14.1 +kernel_early 3.10.0-693.38.1 +kernel_early 3.10.0-514.57.1 +kernel_early 3.10.0-327.73.1 diff --git a/SPECS/06-55-04_disclaimer b/SPECS/06-55-04_disclaimer new file mode 100644 index 0000000..66d71bd --- /dev/null +++ b/SPECS/06-55-04_disclaimer @@ -0,0 +1,5 @@ +Microcode revisions 0x2000065 and higher for Intel Skylake-X/W (family 6, +model 85, stepping 4; CPUID 0x50654) were disabled as they could cause system +hangs on reboot, so the previous revision 0x2000064 was used instead. +Please refer to /usr/share/doc/microcode_ctl/caveats/06-55-04_readme +and /usr/share/doc/microcode_ctl/README.caveats for details. diff --git a/SPECS/06-55-04_readme b/SPECS/06-55-04_readme new file mode 100644 index 0000000..097e07b --- /dev/null +++ b/SPECS/06-55-04_readme @@ -0,0 +1,69 @@ +Intel Skylake Scalable Platform CPU models that belong to Workstation and HEDT +(Basin Falls) segment (SKL-W/X, family 6, model 85, stepping 4) had reports +of system hangs on reboot when revision 0x2000065 of microcode, that was included +from microcode-20191112 update up to microcode-20200520 update, was applied[1]. +In order to address this, microcode update to the newer revision had been +disabled by default on these systems, and the previously published microcode +revision 0x2000064 is used by default for the OS-driven microcode update. + +Since revision 0x2006906 (included with the microcode-20200609 release) +it is reported that the issue is no longer present, so the newer microcode +revision is enabled by default now (but can be disabled explicitly; see below). + +[1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/21 + +For the reference, SHA1 checksums of 06-55-04 microcode files containing +microcode revisions in question are listed below: + * 06-55-04, revision 0x2000064: 2e405644a145de0f55517b6a9de118eec8ec1e5a + * 06-55-04, revision 0x2000065: f27f12b9d53f492c297afd856cdbc596786fad23 + * 06-55-04, revision 0x2006906: 5f18f985f6d5ad369b5f6549b7f3ee55acaef967 + +Please contact your system vendor for a BIOS/firmware update that contains +the latest microcode version. For the information regarding microcode versions +required for mitigating specific side-channel cache attacks, please refer +to the following knowledge base articles: + * CVE-2017-5715 ("Spectre"): + https://access.redhat.com/articles/3436091 + * CVE-2018-3639 ("Speculative Store Bypass"): + https://access.redhat.com/articles/3540901 + * CVE-2018-3620, CVE-2018-3646 ("L1 Terminal Fault Attack"): + https://access.redhat.com/articles/3562741 + * CVE-2018-12130, CVE-2018-12126, CVE-2018-12127, and CVE-2019-11091 + ("Microarchitectural Data Sampling"): + https://access.redhat.com/articles/4138151 + * CVE-2019-0117 (Intel SGX Information Leak), + CVE-2019-0123 (Intel SGX Privilege Escalation), + CVE-2019-11135 (TSX Asynchronous Abort), + CVE-2019-11139 (Voltage Setting Modulation): + https://access.redhat.com/solutions/2019-microcode-nov + * CVE-2020-0543 (Special Register Buffer Data Sampling), + CVE-2020-0548 (Vector Register Data Sampling), + CVE-2020-0549 (L1D Cache Eviction Sampling): + https://access.redhat.com/solutions/5142751 + +The information regarding disabling microcode update is provided below. + +To disable usage of the newer microcode revision for a specific kernel +version, please create a file "disallow-intel-06-55-04" inside +/lib/firmware/ directory, run +"/usr/libexec/microcode_ctl/update_ucode" to update firmware directory +used for late microcode updates, and run "dracut -f --kver " +so initramfs for this kernel version is regenerated, for example: + + touch /lib/firmware/3.10.0-862.9.1/disallow-intel-06-55-04 + /usr/libexec/microcode_ctl/update_ucode + dracut -f --kver 3.10.0-862.9.1 + +To disable usage of the newer microcode revision for all kernels, please create +file "/etc/microcode_ctl/ucode_with_caveats/disallow-intel-06-55-04", run +"/usr/libexec/microcode_ctl/update_ucode" to update firmware directories +used for late microcode updates, and run "dracut -f --regenerate-all" +so initramfs images get regenerated, for example: + + mkdir -p /etc/microcode_ctl/ucode_with_caveats + touch /etc/microcode_ctl/ucode_with_caveats/disallow-intel-06-55-04 + /usr/libexec/microcode_ctl/update_ucode + dracut -f --regenerate-all + +Please refer to /usr/share/doc/microcode_ctl/README.caveats for additional +information. diff --git a/SPECS/06-5e-03 b/SPECS/06-5e-03 new file mode 100644 index 0000000..a3119d5 Binary files /dev/null and b/SPECS/06-5e-03 differ diff --git a/SPECS/06-5e-03_config b/SPECS/06-5e-03_config new file mode 100644 index 0000000..7482d36 --- /dev/null +++ b/SPECS/06-5e-03_config @@ -0,0 +1,3 @@ +model GenuineIntel 06-5e-03 +path intel-ucode/06-5e-03 +disable early late diff --git a/SPECS/06-5e-03_disclaimer b/SPECS/06-5e-03_disclaimer new file mode 100644 index 0000000..7e3bb16 --- /dev/null +++ b/SPECS/06-5e-03_disclaimer @@ -0,0 +1,5 @@ +Microcode revisions 0xda and higher for Intel Skylake-H/S/Xeon E3 v5 (family 6, +model 94, stepping 3; CPUID 0x506e3) are disabled as they may cause system +instability; the previously published revision 0xd6 is used instead. +Please refer to /usr/share/doc/microcode_ctl/caveats/06-5e-03_readme +and /usr/share/doc/microcode_ctl/README.caveats for details. diff --git a/SPECS/06-5e-03_readme b/SPECS/06-5e-03_readme new file mode 100644 index 0000000..b739bf2 --- /dev/null +++ b/SPECS/06-5e-03_readme @@ -0,0 +1,68 @@ +Some Intel Skylake CPU models (SKL-H/S/Xeon E3 v5, family 6, model 94, +stepping 3) have reports of possible system hangs when revision 0xdc +of microcode, that is included in microcode-20200609 update to address +CVE-2020-0543, CVE-2020-0548, and CVE-2020-0549, is applied[1]. In order +to address this, microcode update to the newer revision has been disabled +by default on these systems, and the previously published microcode revision +0xd6 is used by default for the OS-driven microcode update. + +[1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/31#issuecomment-644885826 + +For the reference, SHA1 checksums of 06-55-04 microcode files containing +microcode revisions in question are listed below: + * 06-5e-03, revision 0xd6: 86c60ee7d5d0d7115a4962c1c61ceecb0fd3a95a + * 06-5e-03, revision 0xdc: 5e1020a10678cfc60980131c3d3a2cfd462b4dd7 + +Please contact your system vendor for a BIOS/firmware update that contains +the latest microcode version. For the information regarding microcode versions +required for mitigating specific side-channel cache attacks, please refer +to the following knowledge base articles: + * CVE-2017-5715 ("Spectre"): + https://access.redhat.com/articles/3436091 + * CVE-2018-3639 ("Speculative Store Bypass"): + https://access.redhat.com/articles/3540901 + * CVE-2018-3620, CVE-2018-3646 ("L1 Terminal Fault Attack"): + https://access.redhat.com/articles/3562741 + * CVE-2018-12130, CVE-2018-12126, CVE-2018-12127, and CVE-2019-11091 + ("Microarchitectural Data Sampling"): + https://access.redhat.com/articles/4138151 + * CVE-2019-0117 (Intel SGX Information Leak), + CVE-2019-0123 (Intel SGX Privilege Escalation), + CVE-2019-11135 (TSX Asynchronous Abort), + CVE-2019-11139 (Voltage Setting Modulation): + https://access.redhat.com/solutions/2019-microcode-nov + * CVE-2020-0543 (Special Register Buffer Data Sampling), + CVE-2020-0548 (Vector Register Data Sampling), + CVE-2020-0549 (L1D Cache Eviction Sampling): + https://access.redhat.com/solutions/5142751 + +The information regarding enforcing microcode update is provided below. + +To enforce usage of the latest 06-5e-03 microcode revision for a specific kernel +version, please create a file "force-intel-06-5e-03" inside +/lib/firmware/ directory, run +"/usr/libexec/microcode_ctl/update_ucode" to add it to firmware directory +where microcode will be available for late microcode update, and run +"dracut -f --kver ", so initramfs for this kernel version +is regenerated and the microcode can be loaded early, for example: + + touch /lib/firmware/3.10.0-862.9.1/force-intel-06-5e-03 + /usr/libexec/microcode_ctl/update_ucode + dracut -f --kver 3.10.0-862.9.1 + +After that, it is possible to perform a late microcode update by executing +"/usr/libexec/microcode_ctl/reload_microcode" or by writing value "1" to +"/sys/devices/system/cpu/microcode/reload" directly. + +To enforce addition of this microcode for all kernels, please create file +"/etc/microcode_ctl/ucode_with_caveats/force-intel-06-5e-03", run +"/usr/libexec/microcode_ctl/update_ucode" for enabling late microcode updates, +and "dracut -f --regenerate-all" for enabling early microcode updates: + + mkdir -p /etc/microcode_ctl/ucode_with_caveats + touch /etc/microcode_ctl/ucode_with_caveats/force-intel-06-5e-03 + /usr/libexec/microcode_ctl/update_ucode + dracut -f --regenerate-all + +Please refer to /usr/share/doc/microcode_ctl/README.caveats for additional +information. diff --git a/SPECS/06-8e-9e-0x-0xca_config b/SPECS/06-8e-9e-0x-0xca_config new file mode 100644 index 0000000..2dbca4a --- /dev/null +++ b/SPECS/06-8e-9e-0x-0xca_config @@ -0,0 +1,4 @@ +path intel-ucode/* +vendor GenuineIntel +dmi mode=fail-equal key=bios_vendor val="Dell Inc." +disable early late diff --git a/SPECS/06-8e-9e-0x-0xca_disclaimer b/SPECS/06-8e-9e-0x-0xca_disclaimer new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/SPECS/06-8e-9e-0x-0xca_disclaimer diff --git a/SPECS/06-8e-9e-0x-0xca_readme b/SPECS/06-8e-9e-0x-0xca_readme new file mode 100644 index 0000000..aba1bc7 --- /dev/null +++ b/SPECS/06-8e-9e-0x-0xca_readme @@ -0,0 +1,123 @@ +Some Dell systems that use some models of Intel CPUs are susceptible to hangs +and system instability during or after microcode update to revision 0xc6/0xca +(included as part of microcode-20191113/microcode-20191115 update that addressed +CVE-2019-0117, CVE-2019-0123, CVE-2019-11135, and CVE-2019-11139) +and/or revision 0xd6 (included as part of microcode-20200609 update +that addressed CVE-2020-0543, CVE-2020-0548, and CVE-2020-0549) +[1][2][3][4][5][6]. In order to address this, microcode update to the newer +revision has been disabled by default on these systems, and the previously +published microcode revisions 0xae/0xb4/0xb8 are used by default +for the OS-driven microcode update. + +[1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/23 +[2] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/24 +[3] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/33 +[4] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/34 +[5] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/35 +[6] https://bugzilla.redhat.com/show_bug.cgi?id=1846097 + +This caveat contains revision 0xca of 06-[89]e-0x microcode publicly released +by Intel; for the latest revision of the microcode files, please refer to caveat +06-8e-9e-0x-dell. + +For the reference, microarchitectures of the affected CPU models: + * Amber Lake-Y + * Kaby Lake-G/H/S/U/Y/Xeon E3 + * Coffee Lake-H/S/U/Xeon E + * Comet Lake-U 4+2 + * Whiskey Lake-U + +Family names of the affected CPU models: + * 7th Generation Intel® Core™ Processor Family + * 8th Generation Intel® Core™ Processor Family + * 9th Generation Intel® Core™ Processor Family + * 10th Generation Intel® Core™ Processor Family (selected models) + * Intel® Celeron® Processor G Series + * Intel® Celeron® Processor 5000 Series + * Intel® Core™ X-series Processors (i7-7740X, i5-7640X only) + * Intel® Pentium® Gold Processor Series + * Intel® Pentium® Processor Series (selected models) + * Intel® Xeon® Processor E Family + * Intel® Xeon® Processor E3 v6 Family + +SHA1 checksums of the microcode files containing microcode revisions +in question: + * 06-8e-09, revision 0xb4: e253c95c29c3eef6576db851dfa069d82a91256f + * 06-8e-0a, revision 0xb4: 45bcba494be07df9eeccff9627578095a97fba4d + * 06-8e-0b, revision 0xb8: 3e54bf91d642ad81ff07fe274d0cfb5d10d09c43 + * 06-8e-0c, revision 0xb8: bf635c87177d6dc4e067ec11e1caeb19d3c325f0 + * 06-9e-09, revision 0xb4: 42f68eec4ddb79dd6be0c95c4ce60e514e4504b1 + * 06-9e-0a, revision 0xb4: 37c7cb394dd36610b57943578343723da67d50f0 + * 06-9e-0b, revision 0xb4: b5399109d0a5ce8f5fb623ff942da0322b438b95 + * 06-9e-0c, revision 0xae: 131bce89e4d210de8322ffbc6bd787f1af66a7df + * 06-9e-0d, revision 0xb8: 22511b007d1df55558d115abb13a1c23ea398317 + + * 06-8e-09, revision 0xca: 9afa1bae40995207afef13247f114be042d88083 + * 06-8e-0a, revision 0xca: 1d90291cc25e17dc6c36c764cf8c06b41fed4c16 + * 06-8e-0b, revision 0xca: 3fb1246a6594eff5e2c2076c63c600d734f10777 + * 06-8e-0c, revision 0xca: e871540671f59b4fa5d0d454798f09a4d412aace + * 06-9e-09, revision 0xca: b5eed11108ab7ac1e675fe75d0e7454a400ddd35 + * 06-9e-0a, revision 0xca: e472304aaa2f3815a32822cb111ab3f43bf3dfe4 + * 06-9e-0b, revision 0xca: 78f47c5162da680878ed057dc7c853f9737c524b + * 06-9e-0c, revision 0xca: f23848a009928796a153cb9e8f44522136969408 + * 06-9e-0d, revision 0xca: c7a3d469469ee828ba9faf91b67af881fceec3b7 + + * 06-8e-09, revision 0xd6: 2272c621768437d20e602207752201e0966e5a8c + * 06-8e-0a, revision 0xd6: 0b145afb88e028e612f04c2a86385e7d7c3fefc4 + * 06-8e-0b, revision 0xd6: c3831b05da83be54f3acc451a1bce90f75e2e9e5 + * 06-8e-0c, revision 0xd6: 4b8938a93e23f4b5a2d9de40b87f6afcfdc27c05 + * 06-9e-09, revision 0xd6: 4bacba8c598508e7dd4e87e179586abe7a1a987f + * 06-9e-0a, revision 0xd6: 4c236afeef9f80ff3a286698fe7cef72926722f0 + * 06-9e-0b, revision 0xd6: 2f9ab9b2ba29559ce177632281d7290a24fed2ef + * 06-9e-0c, revision 0xd6: 4b9059e519bcab6085b6c103f5d99e509fe0b2bb + * 06-9e-0d, revision 0xd6: 3a3b7edfd8126bb34b761b46a32102a622047899 + +Please contact your system vendor for a BIOS/firmware update that contains +the latest microcode version. For the information regarding microcode versions +required for mitigating specific side-channel cache attacks, please refer +to the following knowledge base articles: + * CVE-2017-5715 ("Spectre"): + https://access.redhat.com/articles/3436091 + * CVE-2018-3639 ("Speculative Store Bypass"): + https://access.redhat.com/articles/3540901 + * CVE-2018-3620, CVE-2018-3646 ("L1 Terminal Fault Attack"): + https://access.redhat.com/articles/3562741 + * CVE-2018-12130, CVE-2018-12126, CVE-2018-12127, and CVE-2019-11091 + ("Microarchitectural Data Sampling"): + https://access.redhat.com/articles/4138151 + * CVE-2019-0117 (Intel SGX Information Leak), + CVE-2019-0123 (Intel SGX Privilege Escalation), + CVE-2019-11135 (TSX Asynchronous Abort), + CVE-2019-11139 (Voltage Setting Modulation): + https://access.redhat.com/solutions/2019-microcode-nov + * CVE-2020-0543 (Special Register Buffer Data Sampling), + CVE-2020-0548 (Vector Register Data Sampling), + CVE-2020-0549 (L1D Cache Eviction Sampling): + https://access.redhat.com/solutions/5142751 + +The information regarding disabling microcode update is provided below. + +To disable usage of the newer microcode revision for a specific kernel +version, please create a file "disallow-intel-06-8e-9e-0x-0xca" inside +/lib/firmware/ directory, run +"/usr/libexec/microcode_ctl/update_ucode" to update firmware directory +used for late microcode updates, and run "dracut -f --kver " +so initramfs for this kernel version is regenerated, for example: + + touch /lib/firmware/3.10.0-862.9.1/disallow-intel-06-8e-9e-0x-0xca + /usr/libexec/microcode_ctl/update_ucode + dracut -f --kver 3.10.0-862.9.1 + +To disable usage of the newer microcode revision for all kernels, please create +file "/etc/microcode_ctl/ucode_with_caveats/disallow-intel-06-8e-9e-0x-0xca", +run "/usr/libexec/microcode_ctl/update_ucode" to update firmware directories +used for late microcode updates, and run "dracut -f --regenerate-all" +so initramfs images get regenerated, for example: + + mkdir -p /etc/microcode_ctl/ucode_with_caveats + touch /etc/microcode_ctl/ucode_with_caveats/disallow-intel-06-8e-9e-0xca + /usr/libexec/microcode_ctl/update_ucode + dracut -f --regenerate-all + +Please refer to /usr/share/doc/microcode_ctl/README.caveats for additional +information. diff --git a/SPECS/06-8e-9e-0x-dell_config b/SPECS/06-8e-9e-0x-dell_config new file mode 100644 index 0000000..bc1fe2b --- /dev/null +++ b/SPECS/06-8e-9e-0x-dell_config @@ -0,0 +1,17 @@ +path intel-ucode/* +vendor GenuineIntel +## It is deemed that blacklisting all 06-[89]e-0x models on all hardware +## in cases where no model filter is used is too broad, hence +## no-model-mode=success. +dmi mode=fail-equal no-model-mode=success key=bios_vendor val="Dell Inc." +## The "kernel_early" statements are carried over from the intel caveat config +## in order to avoid enabling this newer microcode on these problematic kernels; +## see the caveat description in /usr/share/doc/microcode_ctl/caveats/intel_readme +## (That also means that this caveat has to be enforced separately on these +## kernels.) +kernel_early 4.10.0 +kernel_early 3.10.0-930 +kernel_early 3.10.0-862.14.1 +kernel_early 3.10.0-693.38.1 +kernel_early 3.10.0-514.57.1 +kernel_early 3.10.0-327.73.1 diff --git a/SPECS/06-8e-9e-0x-dell_disclaimer b/SPECS/06-8e-9e-0x-dell_disclaimer new file mode 100644 index 0000000..224a822 --- /dev/null +++ b/SPECS/06-8e-9e-0x-dell_disclaimer @@ -0,0 +1,7 @@ +Some Dell systems that use some models of Intel CPUs are susceptible to hangs +and system instability during or after microcode update to newer revisions. +In order to address this, microcode update to these newer revision +has been disabled by default on these systems, and the previously published +microcode revisions are used by default for the OS-driven microcode update. +Please refer to /usr/share/doc/microcode_ctl/caveats/06-8e-9e-0x-dell_readme +and /usr/share/doc/microcode_ctl/README.caveats for details. diff --git a/SPECS/06-8e-9e-0x-dell_readme b/SPECS/06-8e-9e-0x-dell_readme new file mode 100644 index 0000000..0c13193 --- /dev/null +++ b/SPECS/06-8e-9e-0x-dell_readme @@ -0,0 +1,123 @@ +Some Dell systems that use some models of Intel CPUs are susceptible to hangs +and system instability during or after microcode update to revision 0xc6/0xca +(included as part of microcode-20191113/microcode-20191115 update that addressed +CVE-2019-0117, CVE-2019-0123, CVE-2019-11135, and CVE-2019-11139) +and/or revision 0xd6 (included as part of microcode-20200609 update +that addressed CVE-2020-0543, CVE-2020-0548, and CVE-2020-0549) +[1][2][3][4][5][6]. In order to address this, microcode update to the newer +revision has been disabled by default on these systems, and the previously +published microcode revisions 0xae/0xb4/0xb8 are used by default +for the OS-driven microcode update. + +[1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/23 +[2] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/24 +[3] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/33 +[4] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/34 +[5] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/35 +[6] https://bugzilla.redhat.com/show_bug.cgi?id=1846097 + +This caveat contains latest microcode revisions publicly released by Intel; +for the revision 0xca of the microcode files, please refer to caveat +06-8e-9e-0x-0xca. + +For the reference, microarchitectures of the affected CPU models: + * Amber Lake-Y + * Kaby Lake-G/H/S/U/X/Y/Xeon E3 + * Coffee Lake-H/S/U/Xeon E + * Comet Lake-U 4+2 + * Whiskey Lake-U + +Family names of the affected CPU models: + * 7th Generation Intel® Core™ Processor Family + * 8th Generation Intel® Core™ Processor Family + * 9th Generation Intel® Core™ Processor Family + * 10th Generation Intel® Core™ Processor Family (selected models) + * Intel® Celeron® Processor G Series + * Intel® Celeron® Processor 5000 Series + * Intel® Core™ X-series Processors (i7-7740X, i5-7640X only) + * Intel® Pentium® Gold Processor Series + * Intel® Pentium® Processor Series (selected models) + * Intel® Xeon® Processor E Family + * Intel® Xeon® Processor E3 v6 Family + +SHA1 checksums of the microcode files containing microcode revisions +in question: + * 06-8e-09, revision 0xb4: e253c95c29c3eef6576db851dfa069d82a91256f + * 06-8e-0a, revision 0xb4: 45bcba494be07df9eeccff9627578095a97fba4d + * 06-8e-0b, revision 0xb8: 3e54bf91d642ad81ff07fe274d0cfb5d10d09c43 + * 06-8e-0c, revision 0xb8: bf635c87177d6dc4e067ec11e1caeb19d3c325f0 + * 06-9e-09, revision 0xb4: 42f68eec4ddb79dd6be0c95c4ce60e514e4504b1 + * 06-9e-0a, revision 0xb4: 37c7cb394dd36610b57943578343723da67d50f0 + * 06-9e-0b, revision 0xb4: b5399109d0a5ce8f5fb623ff942da0322b438b95 + * 06-9e-0c, revision 0xae: 131bce89e4d210de8322ffbc6bd787f1af66a7df + * 06-9e-0d, revision 0xb8: 22511b007d1df55558d115abb13a1c23ea398317 + + * 06-8e-09, revision 0xca: 9afa1bae40995207afef13247f114be042d88083 + * 06-8e-0a, revision 0xca: 1d90291cc25e17dc6c36c764cf8c06b41fed4c16 + * 06-8e-0b, revision 0xca: 3fb1246a6594eff5e2c2076c63c600d734f10777 + * 06-8e-0c, revision 0xca: e871540671f59b4fa5d0d454798f09a4d412aace + * 06-9e-09, revision 0xca: b5eed11108ab7ac1e675fe75d0e7454a400ddd35 + * 06-9e-0a, revision 0xca: e472304aaa2f3815a32822cb111ab3f43bf3dfe4 + * 06-9e-0b, revision 0xca: 78f47c5162da680878ed057dc7c853f9737c524b + * 06-9e-0c, revision 0xca: f23848a009928796a153cb9e8f44522136969408 + * 06-9e-0d, revision 0xca: c7a3d469469ee828ba9faf91b67af881fceec3b7 + + * 06-8e-09, revision 0xd6: 2272c621768437d20e602207752201e0966e5a8c + * 06-8e-0a, revision 0xd6: 0b145afb88e028e612f04c2a86385e7d7c3fefc4 + * 06-8e-0b, revision 0xd6: c3831b05da83be54f3acc451a1bce90f75e2e9e5 + * 06-8e-0c, revision 0xd6: 4b8938a93e23f4b5a2d9de40b87f6afcfdc27c05 + * 06-9e-09, revision 0xd6: 4bacba8c598508e7dd4e87e179586abe7a1a987f + * 06-9e-0a, revision 0xd6: 4c236afeef9f80ff3a286698fe7cef72926722f0 + * 06-9e-0b, revision 0xd6: 2f9ab9b2ba29559ce177632281d7290a24fed2ef + * 06-9e-0c, revision 0xd6: 4b9059e519bcab6085b6c103f5d99e509fe0b2bb + * 06-9e-0d, revision 0xd6: 3a3b7edfd8126bb34b761b46a32102a622047899 + +Please contact your system vendor for a BIOS/firmware update that contains +the latest microcode version. For the information regarding microcode versions +required for mitigating specific side-channel cache attacks, please refer +to the following knowledge base articles: + * CVE-2017-5715 ("Spectre"): + https://access.redhat.com/articles/3436091 + * CVE-2018-3639 ("Speculative Store Bypass"): + https://access.redhat.com/articles/3540901 + * CVE-2018-3620, CVE-2018-3646 ("L1 Terminal Fault Attack"): + https://access.redhat.com/articles/3562741 + * CVE-2018-12130, CVE-2018-12126, CVE-2018-12127, and CVE-2019-11091 + ("Microarchitectural Data Sampling"): + https://access.redhat.com/articles/4138151 + * CVE-2019-0117 (Intel SGX Information Leak), + CVE-2019-0123 (Intel SGX Privilege Escalation), + CVE-2019-11135 (TSX Asynchronous Abort), + CVE-2019-11139 (Voltage Setting Modulation): + https://access.redhat.com/solutions/2019-microcode-nov + * CVE-2020-0543 (Special Register Buffer Data Sampling), + CVE-2020-0548 (Vector Register Data Sampling), + CVE-2020-0549 (L1D Cache Eviction Sampling): + https://access.redhat.com/solutions/5142751 + +The information regarding disabling microcode update is provided below. + +To disable usage of the newer microcode revision for a specific kernel +version, please create a file "disallow-intel-06-8e-9e-0x-dell" inside +/lib/firmware/ directory, run +"/usr/libexec/microcode_ctl/update_ucode" to update firmware directory +used for late microcode updates, and run "dracut -f --kver " +so initramfs for this kernel version is regenerated, for example: + + touch /lib/firmware/3.10.0-862.9.1/disallow-intel-06-8e-9e-0x-dell + /usr/libexec/microcode_ctl/update_ucode + dracut -f --kver 3.10.0-862.9.1 + +To disable usage of the newer microcode revision for all kernels, please create +file "/etc/microcode_ctl/ucode_with_caveats/disallow-intel-06-8e-9e-0x-dell", +run "/usr/libexec/microcode_ctl/update_ucode" to update firmware directories +used for late microcode updates, and run "dracut -f --regenerate-all" +so initramfs images get regenerated, for example: + + mkdir -p /etc/microcode_ctl/ucode_with_caveats + touch /etc/microcode_ctl/ucode_with_caveats/disallow-intel-06-8e-9e-dell + /usr/libexec/microcode_ctl/update_ucode + dracut -f --regenerate-all + +Please refer to /usr/share/doc/microcode_ctl/README.caveats for additional +information. diff --git a/SPECS/99-microcode-override.conf b/SPECS/99-microcode-override.conf new file mode 100644 index 0000000..c898801 --- /dev/null +++ b/SPECS/99-microcode-override.conf @@ -0,0 +1,7 @@ +## Uncomment the following line in order to disable +## microcode_ctl module that is used for $fw_dir variable overriding. +## +## Please refer to /usr/share/doc/microcode_ctl/README.caveats +## for additional information. +## +#omit_dracutmodules+=' microcode_ctl-fw_dir_override ' diff --git a/SPECS/README.caveats b/SPECS/README.caveats new file mode 100644 index 0000000..2220a09 --- /dev/null +++ b/SPECS/README.caveats @@ -0,0 +1,660 @@ +The microcode_ctl package contains microcode files (vendor-provided binary data +and/or code in proprietary format that affects behaviour of a device) for Intel +CPUs that may be loaded into the CPU during boot. + +The microcode_ctl package contains provisions for some issues related +to microcode loading. While those provisions are expected to suit most users, +several knobs are available in order to provide ability to override the default +behaviour. + + +General behaviour +================= +In RHEL 8 (as well as RHEL 7 before it), there are currently two main handlers +for CPU microcode update: + * Early microcode update. It uses GenuineIntel.bin or AuthenticAMD.bin file + placed at the beginning of an initramfs image + (/boot/initramfs-KERNEL_VERSION.img, where "KERNEL_VERSION" is a kernel + version in the same format as provided by "uname -r") as a source + of microcode data, and is performed very early during the boot process + (if the relevant microcode file is available in the aforementioned file). + * On-demand (late) microcode update. It can be triggered by writing "1" to + /sys/devices/system/cpu/microcode/reload file (provided my the "microcode" + module). It relies on request_firmware infrastructure, which searches (and + loads, if found) microcode from a file present in one of the following + directories (in the search order): + /lib/firmware/updates/KERNEL_VERSION/ + /lib/firmware/updates/ + /lib/firmware/KERNEL_VERSION/ + /lib/firmware/ + (there is also an additional directory that can be configured via the + "fw_path_para" module option of the "firmware_class" module; as this module + is built-in in RHEL kernel, a boot parameter "firmware_class.fw_path_para" + should be used for that purpose; this is out of the document's scope, however) + +The firmware for Intel CPUs is searched in "intel-ucode" subdirectory, and for +AMD CPUs, a file under "amd-ucode" is searched. + +For Intel CPUs, the name of the specific microcode file the kernel tries to load +has the format "FF-MM-SS", where "FF" is the family number, "MM" is the model +number, and "SS" is the stepping. All those numbers are zero-filled to two digits +and are written in hexadecimal (letters are in the lower case). For AMD CPUs, +the file name has the format "microcode_amd_famFFh.bin", where "FF" is the +family number, written in hexadecimal, letters are in the lower case, not +zero-filled. + +The early microcode is placed into initramfs image by the "dracut" script, which +scans the aforementioned subdirectories of the configured list of firmware +directories (by default, the list consists of two directories in RHEL 8, +"/lib/firmware/updates" and "/lib/firmware"). + +In RHEL 8, AMD CPU microcode is shipped as a part of the linux-firmware package, +and Intel microcode is shipped as a part of the microcode_ctl package. + +The microcode_ctl package currently includes the following: + * Intel CPU microcode files, placed in /usr/share/microcode_ctl/intel-ucode + directory (currently there are none); + * A dracut module, /usr/lib/dracut/modules.d/99microcode_ctl-fw_dir_override, + that controls which additional firmware directories will be added to dracut's + default configuration; + * A dracut configuration file, /usr/lib/dracut/dracut.conf.d/01-microcode.conf, + that enables inclusion of early microcode to the generated initramfs + in dracut; + * A dracut configuration file, + /usr/lib/dracut/dracut.conf.d/99-microcode-override.conf, that provides a way + to quickly disable 99microcode_ctl-fw_dir-override dracut module; + * A systemd service file, microcode.service, that triggers microcode reload + late during boot; + * A set of directories in /usr/share/microcode_ctl/ucode_with_caveats, each + of which contains configuration and related data for various caveats related + to microcode: + * readme - description of caveat and related information, + * config - caveat configuration file, with syntax as described in "Caveat + configuration" section below, + * intel-ucode - directory containing microcode files related to the caveat; + * A set of support scripts, placed in /usr/libexec/microcode_ctl: + * "check_caveats" is an utility script that performs checks of the target + kernel (and running CPU) in accordance with caveat configuration files + in ucode_with_caveats directory and reports whether it passes them or not, + * "reload_microcode" is a script that is called by microcode.service and + triggers microcode reloading (by writing "1" to + /sys/devices/system/cpu/microcode/reload) if the running kernel passes + check_caveats checks, + * "update_ucode" is a script that populates symlinks to microcode files + in /lib/firmware, so it can be picked up by relevant kernels for the late + microcode loading. + +Also, microcode_ctl RPM includes triggers that run update_ucode script on every +installation or removal of a kernel RPM in order to provide microcode files +for newly installed kernels and cleanup symlinks for the uninstalled ones. + + +Caveat configuration +-------------------- +There is a directory for each caveat under +/usr/share/microcode_ctl/ucode_with_caveats, containing the following files: + * "config", a configuration file for the caveat; + * "readme", that contains description of the caveat; + * set of related associated microcode files. + +"config" file is a set of lines each containing option name and its value, +separated by white space. Currently, the following options are supported: + * "model" option, which has format "VENDOR_ID FF-MM-SS", that specifies + to which CPU model the caveat is applicable (check_caveats ignores caveats + with non-matching models if "-m" option is passed to it). Can be set + in the configuration file only once (the last provided value is used). + * "vendor" option specifies CPUs of which vendor (as provided + in the /proc/cpuinfo file) the caveat is applicable to (check_caveats + ignores caveats with non-matching models when it is invoked with "-m" + option). Can be set in the configuration file only once. + * "path" is a glob pattern that specifies set of microcode files associated + with the caveat as a relative path to the caveat directory. This option + is used for populating files in /lib/firmware by update_ucode script and + for matching microcode file when dracut is run in host-only mode + (as in that case it uses only the first directory in firmware directory list + to look for the microcode file applicable to the host CPU). Can be set + in the configuration file multiple times. + * "kernel" is a minimal kernel version that supports proper handling + of the related microcode files during late microcode load. It may be + provided in one of the following formats that affect the way it is compared + to the running kernel version: + * A.B.C (where A, B, and C are decimal numbers), "upstream version". In this + case, simple version comparison against the respective part of the running + kernel version is used, and the running kernel version should be greater + or equal than the version provided in the configuration option in order + for comparison to succeed (that is, the first part, major version number, + of the running kernel version should be greater than the value provided + in the configuration option, or those should be equal and the second part, + minor version number, should be greater than the minor version number + of the kernel version provided in the configuration option, or the first + two parts should be equal and the third part, patch level, should + be greater or equal the patch level of the version in the configuration + option). + * A.B.C-Y (where A, B, C, and Y are decimal numbers), "Y-stream version". + In this case, A.B.C part should be equal, and Y part of the running kernel + version should be greater or equal than the Y part of the configuration + option version in order to satisfy the comparison requirement. + * A.B.C-Y.Z1.Z2 (where A, B, C, Y, Z1, and Z2 are decimal numbers), + "Z-stream version". In this case, A.B.C-Y part should be equal and Z1.Z2 + part of the running kernel should be greater or equal than the respective + part of the configuration option version (when compared as a version) + for comparison to succeed. + Kernel version check passed if at least one comparison of the running kernel + version against a kernel version provided in a configuration option + succeeded. The "kernel" configuration option can be provided + in the configuration file multiple times. + * "kernel_early" is a minimal kernel version that supports proper handling + of the related microcode during early microcode load. The format of the + option and its semantics is similar to the "kernel" configuration options. + This option can be provided multiple times as well. + * "mc_min_ver_late" is the minimal version of the currently loaded microcode + on the CPU (as reported in /proc/cpuinfo) that supports late microcode + update. Microcode update will be attempted only if the currently loaded + microcode version is greater or equal the microcode version provided + in the configuration option. Can be set in the configuration file only once. + * "disable" is a way to disable a specific caveat from inside its + configuration. Argument for the argument is a list of stages ("early", + "late") for which the caveat should be disable. The configuration option + can be provided multiple times in a configuration file. + * "blacklist" is a marker for a start of list of blacklisted model names, + one model name per line. The model name of the running CPU (as reported + in /proc/cpuinfo) is compared against the names in the provided list, and, + if there is a match, caveat check fails. + * "pci_config_val" performs check for specific values in selected parts + of configuration space of specified PCI devices. If "-m" option + is not specified, then the actual check is skipped, and the check returns + result in accordance with the provided "mode" option (se below). Check + arguments are a white-space-separated list of "key=value" pairs. + The following keys are supported: + * "domain" - PCI domain number, or "*" (an asterisk) for any domain. + Default is "*". + * "bus" - PCI bus number, or "*" (an asterisk) for any bus. Default is "*". + * "device" - PCI device number, or "*" (an asterisk) for any device. + Default is "*". + * "function" - PCI function number, or "*" (an asterisk) for any function. + Default is "*". + * "vid" - PCI vendor ID, or empty string for any vendor ID. Default + is empty string. + * "did" - PCI device ID, or empty string for any device ID. Default + is empty string. + * "offset" - offset in device's configuration space where the value resides. + Default is 0. + * "size" - field size. Possible values are 1, 2, 4, or 8. Default is 4. + * "mask" - mask applied to the values during the check. Default is 0. + * "val" - comma-separated list of matching values. Default is 0. + * "mode" - check mode, the way matches are interpreted: + * "success-any" - check succeeds if there was at least one match, + otherwise it fails. + * "success-all" - check succeeds if there was at least one device checked + and all the checked devices have matches, otherwise the check fails. + * "fail-any" - check fails if there was at least one match, otherwise + it succeeds. + * "fail-all" - check fails if there was at least one device checked + and all the checked devices have matches, otherwise the check succeeds. + Default is "success-any". + An example of a check: + pci_config_val mode=success-all device=30 function=3 vid=0x8086 did=0x2083 offset=0x84 size=4 mask=0x38 val=0x38,0x18,0x8 + It interprets 4 bytes at offset 0x84 of special files "config" under + directories that match glob pattern "/sys/bus/pci/devices/*:*:1e.3" + as an unsigned integer value, applies mask 0x38 (thus selecting bit 5..3 + of it) and checks whether it is one of the values 0x38, 0x18, or 0x8 (0b111, + 0b011, or 0b001 in bits 5..3, respectively); if there are such files, + and all the checked values in every checked file has matched at least one + of the aforementioned value, then the check is successful, otherwise + it fails (in accordance with "mode=success-all" semantics). This check fails + if "-m" option is not specified. + * "dmi" performs checks for specific values available in DMI sysfs files + (present under /sys/devices/virtual/dmi/id/). The check fails if file + is not readable. If "-m" option is specified, then the actual check + is skipped, and the check returns value in accordance with "no-model-mode" + parameter value (see below). Check arguments are a white-space-separated + list of "key=value" pairs. The following keys are supported: + * "key" - DMI file to check. Value can be one of the following: bios_date, + bios_vendor, bios_version, board_asset_tag, board_name, board_serial, + board_vendor, board_version, chassis_asset_tag, chassis_serial, + chassis_type, chassis_vendor, chassis_version, product_family, + product_name, product_serial, product_uuid, product_version, sys_vendor. + Default is empty string. + * "val" - a string to match DMI data against. Can be enclosed in single + or double quotes. Default is empty string. + * "mode" - check mode, the way matches are interpreted: + * "success-equal" - returns 0 if the value present in the file + with the name supplied via the "key" parameter file under + /sys/devices/virtual/dmi/id/ is equal to the value supplied as a value + of "val" parameter, otherwise 1. + * "success-equal" - returns 1 if the value present in the file + with the name supplied via the "key" parameter file under + /sys/devices/virtual/dmi/id/ is equal to the value supplied as a value + of "val" parameter, otherwise 0. + Default is "success-any". + * "no-model-mode" - return value if model filter ("-m" option) + is not enabled: + * "success" - return 0. + * "fail" - return 1. + Default is "success". + An example of a check: + dmi mode=fail-equal no-model-mode=success key=bios_vendor val="Dell Inc." + It checks file /sys/devices/virtual/dmi/id/bios_vendor and fails if its + content is "Dell Inc." (without quotes). It succeeds if "-m" option + is not enabled. + + +check_caveats script +-------------------- +"check_caveats" is an utility script (called by update_ucode, reload_microcode, +dracut module) that performs checks of the target kernel (and running CPU) +in accordance with caveat configuration files in directory +"/usr/share/microcode_ctl/ucode_with_caveats", and returns information, whether +the system passes the checks, or not. + +Usage: + check_caveats [-e] [-k TARGET_KVER] [-c CONFIG]* [-m] [-v]' + +Options: + -e - check for early microcode load possibility (instead of late microcode + load). "kernel_early" caveat configuration options are used for checking + instead of "kernel", and "mc_min_ver_late" is not checked. + -k - target kernel version to check against, $(uname -r) is used otherwise. + -c - caveat(s) to check, all caveat configurations found inside + $MC_CAVEATS_DATA_DIR are checked otherwise. + -m - ignore caveats that do not apply to the current CPU model. + -v - verbose output. + +Environment: + MC_CAVEATS_DATA_DIR - directory that contains caveats configurations, + "/usr/share/microcode_ctl/ucode_with_caveats" + by default. + FW_DIR - directory containing firmware files (per-kernel configuration + overrides are checked there), "/lib/firmware" by default. + CFG_DIR - directory containing global caveats overrides, + "/etc/microcode_ctl/ucode_with_caveats" by default. + +Output: + Script returns information about caveats check results. Output has a format + of "KEY VALUE1 VALUE2 ..." with KEY defining the semantics of the VALUEs. + Currently, the following data is issued: + - "cfgs" - list of caveats that have been processed (and not skipped + due to missing "config", "readme", or a disallow-* override described + below); + - "skip_cfgs" - list of caveats that have been skipped (due to missing + config/readme file, or because of overrides); + - "paths" - list of glob patterns matching files associated with caveats + that have been processed; + - "ok_cfgs" - list of caveat configurations that have all the checks passed + (or have enforced by one of force-* overrides described below); + - "ok_paths" - list of glob patterns associated with caveat files from + the "ok_cfgs" list; + - "fail_cfgs" - list of caveats that have one of the checks failed. + - "fail_paths" - list of glob patterns associated with caveats from the + "fail_cfgs" list. + +Return value: + - 0 in case caveats check has passed, 1 otherwise. + - In "-d" mode, 0 is always returned. + +Overrides: + +When check_caveats perform its checks, it also checks for presence of files +in specific places, and, if they exist, check_caveats skips a caveat or ignores +its checks; that mechanism allows overriding the information provided +in configuration on local systems and affect the behaviour of the microcode +update process. + +Current list of overrides (where $FW_DIR and $CFG_DIR are the environment +options described earlier; $kver - the currently processed kernel version, +$s is the requested stage ("early" or "late"), $cfg is the caveat directory +name): + $FW_DIR/$kver/disallow-$s-$cfg - skip a caveat for the requested stage for + a specific kernel version.. + $FW_DIR/$kver/force-$s-$cfg - apply a specific caveat file for a specific + kernel version for the requested stage without + performing any checks. + $FW_DIR/$kver/disallow-$cfg - skip a caveat for any stage for a specific + kernel version. + $FW_DIR/$kver/force-$cfg - apply a specific caveat for any stage + for a specific kernel version without checks. + $FW_DIR/$kver/disallow-$s - skip all caveats for a specific stage + for a specific kernel version. + $CFG_DIR/disallow-$s-$cfg - skip a caveat for a specific stage for all + kernel versions. + $FW_DIR/$kver/force-$s - apply all caveats for a specific stage + for a specific kernel version without checks. + $CFG_DIR/force-$s-$cfg - apply a specific caveat for a specific stage for + all kernel versions without checks. + $FW_DIR/$kver/disallow - skip all caveats for all stages for a specific + kernel version. + $CFG_DIR/disallow-$cfg - skip a caveat for all stages for all kernel + versions. + $FW_DIR/$kver/force - apply all caveats for all stages for a specific kernel + version without checks. + $CFG_DIR/force-$cfg - apply a caveat for all stages for all kernel versions + without checks. + $CFG_DIR/disallow-$s - skip all caveat for all kernel versions + for a specific stage. + $CFG_DIR/force-$s - apply all caveats for all kernel versions for specific + stage without checks. + $CFG_DIR/disallow - skip all caveats for all stages for all kernel versions + (disable everything). + $CFG_DIR/force - force all caveats for all stages for all kernel versions + (enable everything). + +The "apply" action above means creating symlinks in /lib/firmware by +update_ucode in case of the "late" stage and adding caveat directory to the list +of firmware directories by dracut plugin in case of the "early" stage. + +The files are checked for existence until the first match, so more specific +overrides can override more broad ones. + +Also, a caveat is ignored if it lacks either config or readme file. + + +update_ucode script +------------------- +"update_ucode" populates symlinks to microcode files in accordance with caveats +configuration. It enables late microcode loading that is invoked by triggering +/sys/devices/system/cpu/microcode/reload file. Since caveats depend +on the kernel version, symlinks are populated inside +"/lib/firmware/KERNEL_VERSION" directory for each installed kernel. +As a consequence, this script is triggered upon each kernel package installation +and removal. + +The script has two parts: common and kernel-version-specific. + +During the common part, files are populated from +/usr/share/microcode_ctl/intel-ucode in /lib/firmware/intel-ucode. There are +several possibilities to affect the process: + * Presence of "/etc/microcode_ctl/intel-ucode-disallow" file leads to skipping + the common part of the script. + * The same for "/lib/firmware/intel-ucode-disallow". + +During the kernel-version-specific part, each caveat is checked against every +kernel version, and those combinations, for which caveat check succeeds, +gets the symlinks to the associated microcode files populated. + * Absence of "/lib/firmware/KERNEL_VERSION/readme-CAVEAT" prevents update_ucode + from removing symlinks related to the caveat for specific kernel version. + * Since the check is being done by check_caveats, all the overrides that + described there also stay. + +Usage: + update_ucode [--action {add|remove|refresh|list}] [--kernel KERNELVER]* + [--verbose] [--dry-run] [--cleanup intel_ucode caveats_ucode] + [--skip-common] [--skip-kernel-specific] + +Options: + --action - action to perform. Currently, the following actions are supported: + * "add" - create new symlinks. + * "remove" - remove old symlinks that are no longer needed. + * "refresh" - re-populate symlinks. + * "list" - list files under control of update_ucode. + By default, "refresh" action is executed. + --kernel - kernel version to process. By default, list of kernel versions + is formed based on contents of /lib/firmware and /lib/modules + directories. + --verbose - verbose output. + --dry-run - do not call commands, just print the invocation lines. + --cleanup - cleanup mode. Used by post-uninstall script during package + upgrades. Removes excess files in accordance to the contents + of the files provided in the arguments to the option. + --skip-common - do not process /lib/firmware directory. + --skip-kernel-specific - do not process /lib/firmware/KERNEL_VERSION + directories. + +Return value: + 0 on success, 1 on error. + + +reload_microcode script +----------------------- +"reload_microcode" is a script that is called by microcode.service and +triggers late microcode reloading (by writing "1" to +/sys/devices/system/cpu/microcode/reload) if the following check are passed: + * the microcode update performed not in a virtualised environment; + * running kernel passes "check_caveats" checks that applicable to the current + CPU model. + +For a virtualised environment check, the script searches the "/proc/cpuinfo" +file for presence of the "hypervisor" flag among CPU features (it corresponds +to a CPUID feature bit set by hypervisors in order to inform that the kernel +operates inside a virtual machine). This check can be overridden and skipped +by creation of a file "/etc/microcode_ctl/ignore-hypervisor-flag". + +The script has no options and always returns 0. + + +99microcode_ctl-fw_dir_override dracut module +--------------------------------------------- +This dracut module injects directories with microcode files for caveats +that pass "early" check_caveats check (with "-e" flag). In addition +to "check_caveats" overrides, the following abilities to control module's +behaviour are present: + * Presence of one of the following files: + - /etc/microcode_ctl/ucode_with_caveats/skip-host-only-check + - /etc/microcode_ctl/ucode_with_caveats/skip-host-only-check-$cfg + - /lib/firmware/$kver/skip-host-only-check + - /lib/firmware/$kver/skip-host-only-check-$cfg + (where "$kver" is the kernel version in question and "$cfg" is the caveat + directory name) allows skipping matching of microcode file name when dracut's + Host-Only mode is enabled. + +When caveats_check succeeds, caveats directory (not its possibly populated +version for late microcode update: "/lib/firmware/KERNEL_VERSION"; +it is done so in order +to have ability to configure list of caveats enabled for early and late +microcode update, independently) is added to dracut's list of firmware search +directories. + +The module can be disabled by running dracut with +"-o microcode_ctl-fw_dir_override" (for one-time exclusion), or it can +be disabled permanently by uncommenting string +"omit_dracutmodules+=' microcode_ctl-fw_dir_override '" in +/usr/lib/dracut/dracut.conf.d/99-microcode-override.conf configuration file. + +See dracut(8), section "Omitting dracut Modules", and dracut.conf(5), variable +"omit_dracutmodules" for additional information. + + +Caveats +======= + +Intel Broadwell-EP/EX ("BDX-ML B/M/R0") caveat +---------------------------------------------- +Microcode update process on Intel Broadwell-EP/EX CPUs (BDX-ML B/M/R0, +family 6, model 79, stepping 1) has issues that lead to system instability. +A series of changes for the Linux kernel has been developed in order to work +around those issues; however, as it turned out, some systems have issues even +when a microcode update performed on a kernel that contains those changes. +As a result, microcode update for this CPU model is disabled by default; +the microcode file, however, is still shipped as a part of microcode_ctl +package and can be used for performing a microcode update if it is enforced +via the aforementioned overrides. (See the sections "check_caveats script" +and "reload_microcode script" for details.) + +Caveat name: intel-06-4f-01 + +Affected microcode: intel-ucode/06-4f-01. + +Mitigation: microcode loading is disabled for the affected CPU model. + +Minimum versions of the kernel package that contain the aforementioned patch +series: + - Upstream/RHEL 8: 4.17.0 + - RHEL 7.6 onwards: 3.10.0-894 + - RHEL 7.5: 3.10.0-862.6.1 + - RHEL 7.4: 3.10.0-693.35.1 + - RHEL 7.3: 3.10.0-514.52.1 + - RHEL 7.2: 3.10.0-327.70.1 + - RHEL 6.10: 2.6.32-754.1.1 + - RHEL 6.7: 2.6.32-573.58.1 + - RHEL 6.6: 2.6.32-504.71.1 + - RHEL 6.5: 2.6.32-431.90.1 + - RHEL 6.4: 2.6.32-358.90.1 + + +Early microcode load inside a virtual machine +--------------------------------------------- +RHEL 8 kernel supports performing microcode update during early boot stage +from a cpio archive placed at the beginning of the initramfs image. However, +when an early microcode update is attempted inside some virtualised +environments, that may result in unexpected system behaviour. + +Caveat name: intel + +Affected microcode: all. + +Mitigation: early microcode loading is disabled for all CPU models on kernels +without the fix. + +Minimum versions of the kernel package that contain the fix: + - Upstream/RHEL 8: 4.10.0 + - RHEL 7.6 onwards: 3.10.0-930 + - RHEL 7.5: 3.10.0-862.14.1 + - RHEL 7.4: 3.10.0-693.38.1 + - RHEL 7.3: 3.10.0-514.57.1 + - RHEL 7.2: 3.10.0-327.73.1 + + +Intel Sandy Bridge-E/EN/EP caveat +--------------------------------- +Microcode revision 0x718 for Intel Sandy Bridge-E/EN/EP (SNB-EP, family 6, +model 45, stepping 7), that was released to address MDS vulnerability, +and was available from microcode-20190618 up to microcode-20190508 release) +could lead to system instability[1][2]. In order to address this, +this microcode update was not used and the previous microcode revision +was provided instead by default; the microcode file, however, was still shipped +as part of microcode_ctl package and could be used for performing a microcode +update if it is enforced via the aforementioned overrides. With the release +of 0x71a revision of the microcode (as art of microcode-20200520 release) +that aims at fixing the aforementioned stability issue, the latest microcode +revision is again used by default; it is still provided via the caveat +mechanism, hovewer, in order to enable ability to disable it in case such +a need arises. (See the sections "check_caveats script" and "reload_microcode +script" for details regarding caveats mechanism operation.) + +[1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/15 +[2] https://access.redhat.com/solutions/4593951 + +Caveat name: intel-06-2d-07 + +Affected microcode: intel-ucode/06-2d-07. + +Mitigation: None; the latest revision of the microcode file is used by default; +previously published microcode revision 0x714 is still available as a fallback +as part of "intel" caveat. + + +Intel Skylake-SP/W/X caveat +--------------------------- +Microcode revision 0x2000065 (that was provided with microcode releases +microcode-20191112 up to microcode-20200520) for some CPU models that belong +to Intel Skylake Scalable Platform (SKL-W/X, family 6, model 85, stepping 4, +Workstation/HEDT segments) could lead to hangs during reboot[1]. In order +to address this, by default this microcode update was disabled by default and +and the previous 0x2000064 microcode revision was used instead; the microcode +file with, however, is still shipped as part of microcode_ctl package and can +be used for performing a microcode update if it is enforced +via the aforementioned overrides. With the availability of 0x2006906 revision +of the microcode (in the microcode-20200609 release) that fixes +the aforementioned issue, the latest microcode revision is again used +by default; it is still provided via caveat mechanism, hovewer, in order +to enable ability to disable it in case such a need arises. (See the sections +"check_caveats script" and "reload_microcode script" for details regarding +caveats mechanism operation.) + +[1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/21 + +Caveat name: intel-06-55-04 + +Affected microcode: intel-ucode/06-55-04. + +Mitigation: None; the latest revision of the microcode file is used by default; +previously published microcode revision 0x2000064 is still available +as a fallback as part of "intel" caveat. + + +Intel Skylake-U/Y/H/S/Xeon E3 v5 caveats +---------------------------------------- +Some Intel Skylake CPU models (SKL-U/Y, family 6, model 78, stepping 3; +and SKL-H/S/Xeon E3 v5, family 6, model 94, stepping 3) have reports of system +hangs when revision 0xdc of microcode, that is included in microcode-20200609 +update to address CVE-2020-0543, CVE-2020-0548, and CVE-2020-0549, +is applied[1][2]. In order to address this, microcode update to the newer +revision has been disabled by default on these systems, and the previously +published microcode revision 0xd6 is used instead; the newer microcode files, +however, are still shipped as part of microcode_ctl package and can be used +for performing a microcode update if they are enforced via the aforementioned +overrides. (See the sections "check_caveats script" and "reload_microcode +script" for details.) + +[1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/31 +[2] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/31#issuecomment-644885826 + +Caveat names: intel-06-4e-03, intel-06-5e-03 + +Affected microcode: intel-ucode/06-4e-03, intel-ucode/06-5e-03. + +Mitigation: previously published microcode revision 0xd6 is used by default. + + +Dell caveats +------------ +Some Dell systems that use some models of Intel CPUs are susceptible to hangs +and system instability during or after microcode update to revision 0xc6/0xca +(included as part of microcode-20191113/microcode-20191115 update that addressed +CVE-2019-0117, CVE-2019-0123, CVE-2019-11135, and CVE-2019-11139) +and/or revision 0xd6 (included as part of microcode-20200609 update +that addressed CVE-2020-0543, CVE-2020-0548, and CVE-2020-0549) +[1][2][3][4][5][6]. In order to address this, microcode update to the newer +revision has been disabled by default on these systems, and the previously +published microcode revisions 0xae/0xb4/0xb8 are used by default +for the OS-driven microcode update. + +[1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/23 +[2] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/24 +[3] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/33 +[4] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/34 +[5] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/35 +[6] https://bugzilla.redhat.com/show_bug.cgi?id=1846097 + +Caveat names: intel-06-8e-9e-0x-dell, intel-06-8e-9e-0x-0xca + +Affected microcode: intel-ucode/06-8e-09, intel-ucode/06-8e-0a, + intel-ucode/06-8e-0b, intel-ucode/06-8e-0c, + intel-ucode/06-9e-09, intel-ucode/06-9e-0a, + intel-ucode/06-9e-0b, intel-ucode/06-9e-0c, + intel-ucode/06-9e-0d. + +Mitigation: previously published microcode revision 0xac/0xb4/0xb8 is used + by default if /sys/devices/virtual/dmi/id/bios_vendor reports + "Dell Inc."; otherwise, the latest microcode revision is used. + Caveat with revision 0xca of microcode files is provided + as a convenience for the cases where it was working well before. + + + +Additional information +====================== +Red Hat provides updated microcode, developed by its microprocessor partners, +as a customer convenience. Please contact your hardware vendor to determine +whether more recent BIOS/firmware updates are recommended because additional +improvements may be available. + +Information regarding microcode revisions required for mitigating specific +Intel CPU vulnerabilities is available in the following knowledge base articles: + * CVE-2017-5715 ("Spectre"): + https://access.redhat.com/articles/3436091 + * CVE-2018-3639 ("Speculative Store Bypass"): + https://access.redhat.com/articles/3540901 + * CVE-2018-3620, CVE-2018-3646 ("L1 Terminal Fault Attack"): + https://access.redhat.com/articles/3562741 + * CVE-2018-12130, CVE-2018-12126, CVE-2018-12127, and CVE-2019-11091 + ("Microarchitectural Data Sampling"): + https://access.redhat.com/articles/4138151 + * CVE-2019-0117 (Intel SGX Information Leak), + CVE-2019-0123 (Intel SGX Privilege Escalation), + CVE-2019-11135 (TSX Asynchronous Abort), + CVE-2019-11139 (Voltage Setting Modulation): + https://access.redhat.com/solutions/2019-microcode-nov + * CVE-2020-0543 (Special Register Buffer Data Sampling), + CVE-2020-0548 (Vector Register Data Sampling), + CVE-2020-0549 (L1D Cache Eviction Sampling): + https://access.redhat.com/solutions/5142751 diff --git a/SPECS/check_caveats b/SPECS/check_caveats new file mode 100755 index 0000000..ab02a02 --- /dev/null +++ b/SPECS/check_caveats @@ -0,0 +1,782 @@ +#! /bin/bash -eu + +# Script for checking various microcode caveats +# +# +# SPDX-License-Identifier: CC0-1.0 + +: ${MC_CAVEATS_DATA_DIR=/usr/share/microcode_ctl/ucode_with_caveats} +: ${FW_DIR=/lib/firmware} +: ${CFG_DIR=/etc/microcode_ctl/ucode_with_caveats} + +usage() { + echo 'Usage: check_caveats [-d] [-e] [-k TARGET_KVER] [-c CONFIG]' + echo ' [-m] [-v]' + echo + echo ' -d - enables disclaimer printing mode' + echo ' -e - check for early microcode load possibility (instead of' + echo ' late microcode load)' + echo ' -k - target version to check against, $(uname -r) is used' + echo ' otherwise' + echo ' -c - caveat config(s) to check, all configs are checked' + echo ' otherwise' + echo ' -m - check that caveats actually apply to the current model' + echo ' -v - verbose output' + echo + echo 'Environment:' + echo ' MC_CAVEATS_DATA_DIR - directory that contains caveats' + echo ' configuration data' +} + +debug() { [ 0 = "$verbose" ] || echo "$*" >&2; } + +# A simplified RPM version comparison that takes into account knowledge about +# Y- and Z-streams (so it compares versions inside Y-stram or Z-stream if +# the version against which comparison is performed has appropriate versioning +# scheme). +# +# $1 - kernel version to check +# $* - list of kernel versions to check against +check_kver() +{ + local t_major= t_minor= t_patch= t_y= t_z1= t_z2= t_rest= + local m_major= m_minor= m_patch= m_y= m_z1= m_z2= m_rest= + local cmp_type= + + # IFS=.- read -r t_major t_minor t_patch t_y t_z1 t_z2 t_rest <<<"$1" + # "cannot create temp file for here-document: Read-only file system" + # that's why we can't have nice things. + t_major=${1%%.*} + t_rest=${1#${t_major}} + t_rest=${t_rest#.} + t_minor=${t_rest%%.*} + t_rest=${t_rest#${t_minor}} + t_rest=${t_rest#.} + t_patch=${t_rest%%-*} + t_rest=${t_rest#${t_patch}} + t_rest=${t_rest#-} + t_y=${t_rest%%.*} + t_rest=${t_rest#${t_y}} + t_rest=${t_rest#.} + t_z1=${t_rest%%.*} + t_rest=${t_rest#${t_z1}} + t_rest=${t_rest#.} + t_z2=${t_rest%%.*} + + # minor/major/patch/y should be numeric + [ -n "${t_major##*[!0-9]*}" ] || return 1 + [ -n "${t_minor##*[!0-9]*}" ] || return 1 + [ -n "${t_patch##*[!0-9]*}" ] || return 1 + [ -n "${t_y##*[!0-9]*}" ] || return 1 + # reset z1/z2 to zero if non-numeric + [ -n "${t_z1##*[!0-9]*}" ] || t_z1=0 + [ -n "${t_z2##*[!0-9]*}" ] || t_z2=0 + + while [ 1 -lt "$#" ]; do + cmp_type=upstream + + shift + m_major=${1%%.*} + m_rest=${1#${m_major}} + m_rest=${m_rest#.} + m_minor=${m_rest%%.*} + m_rest=${m_rest#${m_minor}} + m_rest=${m_rest#.} + m_patch=${m_rest%%-*} + m_rest=${m_rest#${m_patch}} + m_rest=${m_rest#-} + m_y=${m_rest%%.*} + m_rest=${m_rest#${m_y}} + m_rest=${m_rest#.} + m_z1=${m_rest%%.*} + m_rest=${m_rest#${m_z1}} + m_rest=${m_rest#.} + m_z2=${m_rest%%.*} + + # minor/major/patch should be numeric + [ -n "${m_major##*[!0-9]*}" ] || continue + [ -n "${m_minor##*[!0-9]*}" ] || continue + [ -n "${m_patch##*[!0-9]*}" ] || continue + # reset z1/z2 to zero if non-numeric + [ -n "${m_y##*[!0-9]*}" ] && cmp_type=y || m_y=0 + [ -n "${m_z1##*[!0-9]*}" ] && cmp_type=z || m_z1=0 + [ -n "${m_z2##*[!0-9]*}" ] && cmp_type=z || m_z2=0 + + # Comparing versions + case "$cmp_type" in + upstream) + [ "$t_major" -ge "$m_major" ] || continue + [ "$t_minor" -ge "$m_minor" ] || continue + [ "$t_patch" -ge "$m_patch" ] || continue + return 0 + ;; + y) + [ "$t_major" -eq "$m_major" ] || continue + [ "$t_minor" -eq "$m_minor" ] || continue + [ "$t_patch" -eq "$m_patch" ] || continue + [ "$t_y" -ge "$m_y" ] || continue + return 0 + ;; + z) + [ "$t_major" -eq "$m_major" ] || continue + [ "$t_minor" -eq "$m_minor" ] || continue + [ "$t_patch" -eq "$m_patch" ] || continue + [ "$t_y" -eq "$m_y" ] || continue + [ "$t_z1" -ge "$m_z1" ] || continue + [ "$t_z2" -ge "$m_z2" ] || continue + return 0 + ;; + esac + done + + return 1 +} + +# It is needed for SKX[1] for which different product segments +# are differentiated by a value in the CAPID0 field of PCU registers +# device[2]. +# [1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/21 +# [2] https://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/xeon-scalable-spec-update.pdf#page=13 +# +# $1 - params in config file, space-separated, in key=value form: +# domain=* - PCI domain, '*' or number +# bus=* - PCI bus, '*' or number +# device=* - PCI device, '*' or number +# function=* - PCI function, '*' or number +# vid= - PCI vendor ID, empty or number +# did= - PCI device ID, empty or number +# offset=0 - offset in configuration space +# size=4 - field size +# mask=0 - mask applied to the data read +# val=0 - comma-separated list of possible values +# mode=success-any [ success-ail, fail-any, fail-all ] - matching mode: +# success-any: Returns 0 if there was at least one match, otherwise 1. +# success-all: Returns 0 if there was at least one device checked and all +# the checked devices have matches, otherwise 1. +# fail-any: Returns 1 if there was at least one match, otherwise 0. +# fail-all: Returns 1 if there was at least one device checked and all +# the checked devices have matches, otherwise 0. +# $2 - whether model filter is engaged (if it is not '1', just return the result +# based on "mode" value that assumes that there were 0 checks/0 matches). +check_pci_config_val() +{ + local domain='*' bus='*' device='*' func='*' vid= did= + local offset=0 size=4 mask=0 val=0 mode=success-any + local checked=0 matched=0 path='' + local dev_path dev_vid dev_did dev_val + local opts="${1:-}" + local match_model="${2:0}" + + set -- $1 + while [ "$#" -gt 0 ]; do + [ "x${1#domain=}" = "x${1}" ] || domain="${1#domain=}" + [ "x${1#bus=}" = "x${1}" ] || bus="${1#bus=}" + [ "x${1#device=}" = "x${1}" ] || device="${1#device=}" + [ "x${1#function=}" = "x${1}" ] || func="${1#function=}" + [ "x${1#vid=}" = "x${1}" ] || vid="${1#vid=}" + [ "x${1#did=}" = "x${1}" ] || did="${1#did=}" + [ "x${1#offset=}" = "x${1}" ] || offset="${1#offset=}" + [ "x${1#size=}" = "x${1}" ] || size="${1#size=}" + [ "x${1#mask=}" = "x${1}" ] || mask="${1#mask=}" + [ "x${1#val=}" = "x${1}" ] || val="${1#val=}" + [ "x${1#mode=}" = "x${1}" ] || mode="${1#mode=}" + + shift + done + + path="$domain" + if [ "x$bus" = 'x*' ]; then + path="$path:$bus"; + else + path=$(printf '%s:%02x' "$path" "$bus") + fi + if [ "x$device" = 'x*' ]; then + path="$path:$device"; + else + path=$(printf '%s:%02x' "$path" "$device") + fi + if [ "x$func" = 'x*' ]; then + path="$path.$func"; + else + path=$(printf '%s.%01x' "$path" "$func") + fi + + # Normalise VID, DID + [ -n "$vid" ] || vid="$(printf '0x%04x' "$vid")" + [ -n "$did" ] || did="$(printf '0x%04x' "$did")" + + ( [ 1 != "$match_model" ] \ + || /usr/bin/find /sys/bus/pci/devices/ -maxdepth 1 -name "$path" \ + || : ) | ( + while read -r dev_path; do + # Filter VID, DID + if [ -n "$vid" ]; then + dev_vid=$(/bin/cat "$dev_path/vendor") + [ "x$vid" = "x$dev_vid" ] || continue + fi + if [ -n "$did" ]; then + dev_did=$(/bin/cat "$dev_path/device") + [ "x$did" = "x$dev_did" ] || continue + fi + + checked="$((checked + 1))" + + dev_val="$(/usr/bin/od -j "$offset" -N "$size" -A n \ + -t "u$size" "$dev_path/config")" + + val_rest="${val}" + while :; do + cur_val="${val_rest%%,*}" + if [ "$((dev_val & mask))" = "$((cur_val & mask))" ] + then + matched="$((matched + 1))" + break + fi + [ "x${val_rest}" != "x${val_rest#*,}" ] || break + val_rest="${val_rest#*,}" + done + + case "$mode" in + success-any) [ "$matched" -eq 0 ] || { echo 0; exit; } ;; + success-all) [ "$matched" -eq "$checked" ] || { echo 1; exit; } ;; + fail-any) [ "$matched" -eq 0 ] || { echo 1; exit; } ;; + fail-all) [ "$matched" -eq "$checked" ] || { echo 0; exit; } ;; + *) echo 2; exit;; + esac + done + + debug "PCI config value check ($opts): checked $checked," \ + "matched $matched (model check is set to $match_model)" + + case "$mode" in + success-any) if [ "$matched" -eq 0 ]; then echo 1; else echo 0; fi ;; + success-all) if [ "$matched" -gt 0 -a "$matched" -eq "$checked" ]; then echo 0; else echo 1; fi ;; + fail-any) if [ "$matched" -eq 0 ]; then echo 0; else echo 1; fi ;; + fail-all) if [ "$matched" -gt 0 -a "$matched" -eq "$checked" ]; then echo 1; else echo 0; fi ;; + *) echo 2; exit;; + esac + ) +} + +# It is needed for filtering by BIOS vendor name that is available in DMI data +# +# $1 - params in config file, space-separated, in key=value form: +# key= - DMI value to check. Can be one of the following: bios_date, +# bios_vendor, bios_version, board_asset_tag, board_name, board_serial, +# board_vendor, board_version, chassis_asset_tag, chassis_serial, +# chassis_type, chassis_vendor, chassis_version, product_family, +# product_name, product_serial, product_uuid, product_version, +# sys_vendor. +# val= - a string to match DMI data against. Can be enclosed in single +# or double quotes. +# mode=success-equal [ success-equal, fail-equal ] - matching mode: +# success-equal: Returns 0 if the value present in the corresponding file +# under /sys/devices/virtual/dmi/id/ is equal +# to the value supplied as a value of "val" parameter, +# otherwise 1. +# fail-equal: Returns 1 if the value present in the corresponding file +# under /sys/devices/virtual/dmi/id/ is equal +# to the value supplied as a value of "val" parameter, +# otherwise 0. +# no-model-mode=success [ success, fail ] - return value if model filter +# is not enabled: +# success: Return 0. +# fail: Return 1. +# $2 - whether model filter is engaged (if it is not '1', just return the result +# based on "mode" value that assumes that the check has failed). +check_dmi_val() +{ + local key= val= mode='success-equal' nm_mode='success' + local opts="${1:-}" opt= opt_= + local match_model="${2:0}" + + local valid_keys=" bios_date bios_vendor bios_version board_asset_tag board_name board_serial board_vendor board_version chassis_asset_tag chassis_serial chassis_type chassis_vendor chassis_version product_family product_name product_serial product_uuid product_version sys_vendor " + local success=1 + + while [ -n "$opts" ]; do + opt="${opts%%[ ]*}" + [ -n "${opt}" ] || { opts="${opts#[ ]}"; continue; } + + [ "x${opt#key=}" = "x${opt}" ] || key="${opt#key=}" + [ "x${opt#mode=}" = "x${opt}" ] || mode="${opt#mode=}" + [ "x${opt#no-model-mode=}" = "x${opt}" ] || \ + nm_mode="${opt#no-model-mode=}" + + # Handle possible quoting + [ "x${opt#val=}" = "x${opt}" ] || { + case "${opt#val=}" in + [']*) opt_="${opts#val=\'}"; val="${opt_%%\'*}"; opt="val=\'${val}\'" ;; + ["]*) opt_="${opts#val=\"}"; val="${opt_%%\"*}"; opt="val=\"${val}\"" ;; + *) val="${opt#val=}" ;; + esac + } + + opts="${opts#"${opt}"}" + continue + done + + # Check key for validity + [ "x${valid_keys#* ${key} *}" != "x${valid_keys}" ] || { + debug "Invalid \"key\" parameter value: \"${key}\"" + echo 2 + exit + } + + [ 1 = "$match_model" ] || { + case "$nm_mode" in + success) echo 0 ;; + fail) echo 1 ;; + *) + debug "Invalid no-model-mode value: \"${nm_mode}\"" + echo 2 + ;; + esac + + exit + } + + [ -r "/sys/devices/virtual/dmi/id/${key}" ] || { + debug "Can't access /sys/devices/virtual/dmi/id/${key}" + echo 3 + exit + } + + file_val="$(cat "/sys/devices/virtual/dmi/id/${key}")" + + [ "x${val}" = "x${file_val}" ] || success=0 + + case "$mode" in + success-equal) echo "$((1 - $success))" ;; + fail-equal) echo "${success}" ;; + *) debug "Invalid mode value: \"${nm_mode}\""; echo 2 ;; + esac +} + +# Provides model in format "VENDOR_ID FAMILY-MODEL-STEPPING" +# +# We check only the first processor as we don't expect non-symmetrical setups +# with CPUs with caveats +get_model_string() +{ + /usr/bin/printf "%s %02x-%02x-%02x" \ + $(/bin/sed -rn '1,/^$/{ + s/^vendor_id[[:space:]]*: (.*)$/\1/p; + s/^cpu family[[:space:]]*: (.*)$/\1/p; + s/^model[[:space:]]*: (.*)$/\1/p; + s/^stepping[[:space:]]*: (.*)$/\1/p; + }' /proc/cpuinfo) +} + +get_model_name() +{ + /bin/sed -rn '1,/^$/s/^model name[[:space:]]*: (.*)$/\1/p' /proc/cpuinfo +} + +get_vendor_id() +{ + /bin/sed -rn '1,/^$/s/^vendor_id[[:space:]]*: (.*)$/\1/p' /proc/cpuinfo +} + +get_mc_path() +{ + case "$1" in + GenuineIntel) + echo "intel-ucode/$2" + ;; + AuthenticAMD) + echo "amd-ucode/$2" + ;; + esac +} + +get_mc_ver() +{ + /bin/sed -rn '1,/^$/s/^microcode[[:space:]]*: (.*)$/\1/p' /proc/cpuinfo +} + +fail() +{ + ret=1 + + fail_cfgs="$fail_cfgs $cfg" + fail_paths="$fail_paths $cfg_path" + + [ 0 -eq "$print_disclaimers" ] || [ ! -e "${dir}/disclaimer" ] \ + || /bin/cat "${dir}/disclaimer" +} + +#check_kver "$@" +#get_model_name + +match_model=0 +configs= +kver=$(/bin/uname -r) +verbose=0 +early_check=0 +print_disclaimers=0 + +ret=0 + +while getopts "dek:c:mv" opt; do + case "${opt}" in + d) + print_disclaimers=1 + early_check=2 + ;; + e) + early_check=1 + ;; + k) + kver="$OPTARG" + ;; + c) + configs="$configs $OPTARG" + ;; + m) + match_model=1 + ;; + v) + verbose=1 + ;; + *) + usage + exit 1; + ;; + esac +done + +: "${configs:=$(find "${MC_CAVEATS_DATA_DIR}" -maxdepth 1 -mindepth 1 -type d -printf "%f\n")}" + +cpu_model=$(get_model_string) +cpu_model_name=$(get_model_name) +cpu_vendor=$(get_vendor_id) + +ret_paths="" +ok_paths="" +fail_paths="" + +ret_cfgs="" +ok_cfgs="" +fail_cfgs="" + +skip_cfgs="" + +if [ 1 -eq "$early_check" ]; then + stage="early" +else + stage="late" +fi + + +for cfg in $(echo "${configs}"); do + dir="$MC_CAVEATS_DATA_DIR/$cfg" + + # We add cfg to the skip list first and then, if we do not skip it, + # we remove the configuration from the list. + skip_cfgs="$skip_cfgs $cfg" + + [ -r "${dir}/readme" ] || { + debug "File 'readme' in ${dir} is not found, skipping" + continue + } + + [ -r "${dir}/config" ] || { + debug "File 'config' in ${dir} is not found, skipping" + continue + } + + cfg_model= + cfg_vendor= + cfg_path= + cfg_kvers= + cfg_kvers_early= + cfg_blacklist= + cfg_mc_min_ver_late= + cfg_disable= + cfg_pci= + cfg_dmi= + + while read -r key value; do + case "$key" in + model) + cfg_model="$value" + ;; + vendor) + cfg_vendor="$value" + ;; + path) + cfg_path="$cfg_path $value" + ;; + kernel) + cfg_kvers="$cfg_kvers $value" + ;; + kernel_early) + cfg_kvers_early="$cfg_kvers_early $value" + ;; + mc_min_ver_late) + cfg_mc_min_ver_late="$value" + ;; + disable) + cfg_disable="$cfg_disable $value " + ;; + blacklist) + cfg_blacklist=1 + # "blacklist" is special: it stops entity parsing, + # and the rest of file is a list of blacklisted model + # names. + break + ;; + pci_config_val) + cfg_pci="$cfg_pci + $value" + ;; + dmi) + cfg_dmi="$cfg_dmi + $value" + ;; + '#'*|'') + continue + ;; + *) + debug "Unknown key '$key' (value '$value') in config" \ + "'$cfg'" + ;; + esac + done < "${dir}/config" + + [ -z "${cfg_blacklist}" ] || \ + cfg_blacklist=$(/bin/sed -n '/^blacklist$/,$p' "${dir}/config" | + /usr/bin/tail -n +2) + + debug "${cfg}: model '$cfg_model', path '$cfg_path', kvers '$cfg_kvers'" + debug "${cfg}: blacklist '$cfg_blacklist'" + + # Check for override files in the following order: + # - disallow early/late specific caveat for specific kernel + # - force early/late specific caveat for specific kernel + # - disallow specific caveat for specific kernel + # - force specific caveat for specific kernel + # + # - disallow early/late specific caveat for any kernel + # - disallow early/late any caveat for specific kernel + # - force early/late specific caveat for any kernel + # - force early/late any caveat for specific kernel + # - disallow specific caveat for any kernel + # - disallow any caveat for specific kernel + # - force specific caveat for any kernel + # - force any caveat for specific kernel + # + # - disallow early/late everything + # - force early/late everyhting + # - disallow everything + # - force everyhting + ignore_cfg=0 + force_cfg=0 + override_file="" + overrides=" + 0:$FW_DIR/$kver/disallow-$stage-$cfg + 1:$FW_DIR/$kver/force-$stage-$cfg + 0:$FW_DIR/$kver/disallow-$cfg + 1:$FW_DIR/$kver/force-$cfg + 0:$FW_DIR/$kver/disallow-$stage + 0:$CFG_DIR/disallow-$stage-$cfg + 1:$FW_DIR/$kver/force-$stage + 1:$CFG_DIR/force-$stage-$cfg + 0:$FW_DIR/$kver/disallow + 0:$CFG_DIR/disallow-$cfg + 1:$FW_DIR/$kver/force + 1:$CFG_DIR/force-$cfg + 0:$CFG_DIR/disallow-$stage + 1:$CFG_DIR/force-$stage + 0:$CFG_DIR/disallow + 1:$CFG_DIR/force" + for o in $(echo "$overrides"); do + o_force=${o%%:*} + override_file=${o#$o_force:} + + [ -e "$override_file" ] || continue + + if [ 0 -eq "$o_force" ]; then + ignore_cfg=1 + else + force_cfg=1 + fi + + break + done + + [ 0 -eq "$ignore_cfg" ] || { + debug "Configuration \"$cfg\" is ignored due to presence of" \ + "\"$override_file\"." + continue + } + + # Check model if model filter is enabled + if [ 1 -eq "$match_model" -a -n "$cfg_model" ]; then + [ "x$cpu_model" = "x$cfg_model" ] || { + debug "Current CPU model '$cpu_model' doesn't" \ + "match configuration CPU model '$cfg_model'," \ + "skipping" + continue + } + fi + + # Check paths if model filter is enabled + if [ 1 -eq "$match_model" -a -n "$cfg_path" ]; then + cpu_mc_path="$MC_CAVEATS_DATA_DIR/$cfg/$(get_mc_path \ + "$cpu_vendor" "${cpu_model#* }")" + cfg_mc_present=0 + + for p in $(printf "%s" "$cfg_path"); do + { /usr/bin/find "$MC_CAVEATS_DATA_DIR/$cfg" \ + -path "$MC_CAVEATS_DATA_DIR/$cfg/$p" -print0; + /bin/true; } \ + | /bin/grep -zFxq "$cpu_mc_path" \ + || continue + + cfg_mc_present=1 + break + done + + [ 1 = "$cfg_mc_present" ] || { + debug "No matching microcode files in '$cfg_path'" \ + "for CPU model '$cpu_model', skipping" + continue + } + fi + + # Check vendor if model filter is enabled + if [ 1 -eq "$match_model" -a -n "$cfg_vendor" ]; then + [ "x$cpu_vendor" = "x$cfg_vendor" ] || { + debug "Current CPU vendor '$cpu_vendor' doesn't" \ + "match configuration CPU vendor '$cfg_vendor'," \ + "skipping" + continue + } + fi + + # Check configuration files + + ret_cfgs="$ret_cfgs $cfg" + ret_paths="$ret_paths $cfg_path" + skip_cfgs="${skip_cfgs% $cfg}" + + [ 0 -eq "$force_cfg" ] || { + debug "Checks for configuration \"$cfg\" are ignored due to" \ + "presence of \"$override_file\"." + + ok_cfgs="$ok_cfgs $cfg" + ok_paths="$ok_paths $cfg_path" + + continue + } + + [ "x${cfg_disable%%* $stage *}" = "x$cfg_disable" ] || { + debug "${cfg}: caveat is disabled in configuration" + fail + continue + } + + # Check late load kernel version + if [ 1 -ne "$early_check" -a -n "$cfg_kvers" ]; then + check_kver "$kver" $cfg_kvers || { + debug "${cfg}: late load kernel version check for" \ + " '$kver' against '$cfg_kvers' failed" + fail + continue + } + fi + + # Check early load kernel version + if [ 0 -ne "$early_check" -a -n "$cfg_kvers_early" ]; then + check_kver "$kver" $cfg_kvers_early || { + debug "${cfg}: early load kernel version check for" \ + "'$kver' against '$cfg_kvers_early' failed" + fail + continue + } + fi + + # Check model blacklist + if [ -n "$cfg_blacklist" ]; then + echo "$cfg_blacklist" | /bin/grep -vqFx "${cpu_model_name}" || { + debug "${cfg}: model '${cpu_model_name}' is blacklisted" + fail + continue + } + fi + + # Check current microcode version for the late update + if [ -n "$cfg_mc_min_ver_late" -a 1 -ne "$early_check" -a \ + "x$cpu_model" = "x$cfg_model" ]; then + cpu_mc_ver="$(get_mc_ver)" + + [ 1 -eq $((cpu_mc_ver >= cfg_mc_min_ver_late)) ] || { + debug "${cfg}: CPU microcode version $cpu_mc_ver" \ + "failed check (should be at least" \ + "${cfg_mc_min_ver_late})" + fail + continue + } + fi + + # Check PCI devices if model filter is enabled + # Note that the model filter check is done inside check_pci_config_val + # based on the 'mode=' parameter. + if [ -n "$cfg_pci" ]; then + pci_line="$(printf "%s\n" "$cfg_pci" | while read -r pci_line; do + [ -n "$pci_line" ] || continue + pci_res=$(check_pci_config_val "$pci_line" \ + "$match_model") + [ 0 != "$pci_res" ] || continue + echo "$pci_res $pci_line" + break + done + echo "0 ")" + + [ -z "${pci_line#* }" ] || { + debug "PCI configuration word check '${pci_line#* }'" \ + "failed (with return code ${pci_line%% *})" + fail + continue + } + fi + + # Check DMI data if model filter is enabled + # Note that the model filter check is done inside check_pci_config_val + # based on the 'mode=' parameter. + if [ -n "$cfg_dmi" ]; then + dmi_line="$(printf "%s\n" "$cfg_dmi" | while read -r dmi_line + do + [ -n "$dmi_line" ] || continue + dmi_res=$(check_dmi_val "$dmi_line" \ + "$match_model") + [ 0 != "$dmi_res" ] || continue + echo "$dmi_res $dmi_line" + break + done + echo "0 ")" + + [ -z "${dmi_line#* }" ] || { + debug "DMI data check '${dmi_line#* }'" \ + "failed (with return code ${dmi_line%% *})" + fail + continue + } + fi + + ok_cfgs="$ok_cfgs $cfg" + ok_paths="$ok_paths $cfg_path" +done + +[ 0 -eq "$print_disclaimers" ] || exit 0 + +echo "cfgs$ret_cfgs" +echo "skip_cfgs$skip_cfgs" +echo "paths$ret_paths" +echo "ok_cfgs$ok_cfgs" +echo "ok_paths$ok_paths" +echo "fail_cfgs$fail_cfgs" +echo "fail_paths$fail_paths" + +exit $ret diff --git a/SPECS/dracut_99microcode_ctl-fw_dir_override_module_init.sh b/SPECS/dracut_99microcode_ctl-fw_dir_override_module_init.sh new file mode 100755 index 0000000..854e278 --- /dev/null +++ b/SPECS/dracut_99microcode_ctl-fw_dir_override_module_init.sh @@ -0,0 +1,132 @@ +#!/bin/bash + +# Hack in additional firmware directories for supported caveats. +# +# SPDX-License-Identifier: CC0-1.0 + +check() { + return 0 +} + +install() { + local FW_DIR=/lib/firmware + local DATA_DIR=/usr/share/microcode_ctl/ucode_with_caveats + local CFG_DIR="/etc/microcode_ctl/ucode_with_caveats" + local check_caveats=/usr/libexec/microcode_ctl/check_caveats + + local verbose_opt + local cc_out + local path + local ignored + local do_skip_host_only + local p + + verbose_opt= + [ 4 -gt "$stdloglvl" ] || verbose_opt="-v" + + # HACK: we override external fw_dir variable in order to get + # an additional ucode based on the kernel version. + dinfo " microcode_ctl module: mangling fw_dir" + + [ -z "$fw_dir_l" ] || { + dinfo " microcode_ctl: avoid touching fw_dir as" \ + "it has been changed (fw_dir_l is '$fw_dir_l')" + + return 0 + } + + # Reset fw_dir to avoid inclusion of kernel-version-specific directories + # populated with microcode for the late load + [ "x$fw_dir" != \ + "x/lib/firmware/updates /lib/firmware /lib/firmware/$kernel" ] || { + fw_dir="/lib/firmware/updates /lib/firmware" + dinfo " microcode_ctl: reset fw_dir to \"${fw_dir}\"" + } + + fw_dir_add="" + while read -d $'\n' -r i; do + dinfo " microcode_ctl: processing data directory " \ + "\"$DATA_DIR/$i\"..." + + if [ "x" != "x$hostonly" ]; then + do_skip_host_only=0 + + local sho_overrides=" + $CFG_DIR/skip-host-only-check + $CFG_DIR/skip-host-only-check-$i + $FW_DIR/$kernel/skip-host-only-check + $FW_DIR/$kernel/skip-host-only-check-$i" + + for p in $(echo "$sho_overrides"); do + [ -e "$p" ] || continue + + do_skip_host_only=1 + dinfo " microcode_ctl: $i; skipping" \ + "Host-Only check, since \"$p\" exists." + break + done + else + do_skip_host_only=1 + fi + + match_model_opt="" + [ 1 = "$do_skip_host_only" ] || match_model_opt="-m" + + if ! cc_out=$($check_caveats -e -k "$kernel" -c "$i" \ + $verbose_opt $match_model_opt) + then + dinfo " microcode_ctl: kernel version \"$kernel\"" \ + "failed early load check for \"$i\", skipping" + continue + fi + + path=$(printf "%s" "$cc_out" | sed -n 's/^paths //p') + [ -n "$path" ] || { + ignored=$(printf "%s" "$cc_out" | \ + sed -n 's/^skip_cfgs //p') + + if [ -n "$ignored" ]; then + dinfo " microcode_ctl: configuration" \ + "\"$i\" is ignored" + else + dinfo " microcode_ctl: no microcode paths" \ + "are associated with \"$i\", skipping" + fi + + continue + } + + dinfo " microcode_ctl: $i: caveats check for kernel" \ + "version \"$kernel\" passed, adding" \ + "\"$DATA_DIR/$i\" to fw_dir variable" + + if [ 0 -eq "$do_skip_host_only" ]; then + fw_dir_add="$DATA_DIR/$i " + else + fw_dir_add="$DATA_DIR/$i $fw_dir_add" + fi + # The list of directories is reverse-sorted in order to preserve the + # "last wins" policy in case of presence of multiple microcode + # revisions. + # + # In case of hostonly == 0, all microcode revisions will be included, + # but since the microcode search is done with the "first wins" policy + # by the (early) microcode loading code, the correct microcode revision + # still has to be picked. + # + # Note that dracut without patch [1] puts only the last directory + # in the early cpio; we try to address this by putting only the last + # matching caveat in the search path, but that workaround works only + # for host-only mode; non-host-only mode early cpio generation is still + # broken without that patch. + # + # [1] https://github.com/dracutdevs/dracut/commit/c44d2252bb4b + done <<-EOF + $(find "$DATA_DIR" -maxdepth 1 -mindepth 1 -type d -printf "%f\n" \ + | LC_ALL=C sort) + EOF + + fw_dir="${fw_dir_add}${fw_dir}" + dinfo " microcode_ctl: final fw_dir: \"${fw_dir}\"" +} + diff --git a/SPECS/gen_provides.sh b/SPECS/gen_provides.sh new file mode 100755 index 0000000..5e2a2a4 --- /dev/null +++ b/SPECS/gen_provides.sh @@ -0,0 +1,158 @@ +#! /bin/bash -efu + +# Generator of RPM "Provides:" tags for Intel microcode files. +# +# SPDX-License-Identifier: CC0-1.0 + +IFS=$'\n' +UPDATED="intel-beta" +CODENAMES="codenames" + +if [ "$#" -ge 1 ]; then + CODENAMES="$1" + shift +fi + +# Match only FF-MM-SS ucode files under intel-ucode/intel-ucode-with-caveats +# directories. +for f in $(grep -E '/intel-ucode.*/[0-9a-f][0-9a-f]-[0-9a-f][0-9a-f]-[0-9a-f][0-9a-f]$'); do + ucode=$(basename "$f") + ucode_caveat="$(basename "$(dirname "$(dirname "$f")")")" + ucode_fname="$ucode_caveat/$ucode" + file_sz="$(stat -c "%s" "$f")" + skip=0 + ext_hdr=0 + ext_sig_cnt=0 + ext_sig_pos=0 + next_skip=0 + + # Microcode header format description: + # https://gitlab.com/iucode-tool/iucode-tool/blob/master/intel_microcode.c + while :; do + [ "$skip" -lt "$file_sz" ] || break + + # Do we parse ext_sig table or another microcode header? + if [ 0 != "$next_skip" ]; then + # Check whether we should abort ext_sig table parsing + [ \( "${skip}" -lt "${next_skip}" \) -a \ + \( "${ext_sig_pos}" -lt "${ext_sig_cnt}" \) ] || { + skip="${next_skip}" + next_skip=0 + continue + } + + # ext_sig, 12 bytes in size + IFS=' ' read cpuid pf_mask <<- EOF + $(hexdump -s "$skip" -n 8 \ + -e '"" 1/4 "%08x " 1/4 "%u" "\n"' "$f") + EOF + + skip="$((skip + 12))" + ext_sig_pos="$((ext_sig_pos + 1))" + else + # Microcode header, 48 bytes, last 3 fields reserved + IFS=' ' read hdrver rev \ + date_y date_d date_m \ + cpuid cksum ldrver \ + pf_mask datasz totalsz <<- EOF + $(hexdump -s "$skip" -n 36 \ + -e '"" 1/4 "%u " 1/4 "%#x " \ + 1/2 "%04x " 1/1 "%02x " 1/1 "%02x " \ + 1/4 "%08x " 1/4 "%x " 1/4 "%#x " \ + 1/4 "%u " 1/4 "%u " 1/4 "%u" "\n"' "$f") + EOF + + [ 0 != "$datasz" ] || datasz=2000 + [ 0 != "$totalsz" ] || totalsz=2048 + + # TODO: add some sanity/safety checks here. As of now, + # there's a (pretty fragile) assumption that all + # the matched files are valid Intel microcode + # files in the expected format. + + # ext_sig table is after the microcode payload, + # check for its presence + if [ 48 -lt "$((totalsz - datasz))" ]; then + next_skip="$((skip + totalsz))" + skip="$((skip + datasz + 48))" + ext_sig_pos=0 + + # ext_sig table header, 20 bytes in size, + # last 3 fields are reserved. + IFS=' ' read ext_sig_cnt <<- EOF + $(hexdump -s "$skip" -n 4 \ + -e '"" 1/4 "%u" "\n"' "$f") + EOF + + skip="$((skip + 20))" + else + skip="$((skip + totalsz))" + next_skip=0 + fi + fi + + #[ -n "$rev" ] || continue + + # Basic "Provides:" tag. Everything else is bells and whistles. + # It's possible that microcode files for different platform_id's + # and the same CPUID have the same version, that's why "sort -u" + # in the end. + printf "firmware(intel-ucode/%s) = %s\n" "$ucode" "$rev" + + # Generate extended "Provides:" tags with additional + # information, which allow more precise matching. + printf "iucode_date(fname:%s;cpuid:%s;pf_mask:0x%x) = %s.%s.%s\n" \ + "$ucode_fname" "$cpuid" "$pf_mask" "$date_y" "$date_m" "$date_d" + printf "iucode_rev(fname:%s;cpuid:%s;pf_mask:0x%x) = %s\n" \ + "$ucode_fname" "$cpuid" "$pf_mask" "$rev" + + # Generate tags for each possible platform_id + _pf=1 + _pf_mask="$pf_mask" + while [ 0 -lt "$_pf_mask" ]; do + [ 1 -ne "$((_pf_mask % 2))" ] || \ + # We try to provide a more specific firmware() + # dependency here. It has incorrect file name, + # but allows constructing a required RPM + # capability name by (directly) using + # the contents of /proc/cpuinfo and + # /sys/devices/system/cpu/cpu*/microcode/processor_flags + # (except for a Deschutes CPU with sig 0x1632) + printf "iucode_rev(fname:%s;platform_id:0x%x) = %s\n" \ + "$ucode_fname" "$_pf" "$rev" + + _pf_mask=$((_pf_mask / 2)) + _pf=$((_pf * 2)) + done + + # Generate tags with codename information, in case + # it is available + cpuid_up="$(echo "$cpuid" | tr 'a-z' 'A-Z')" + if [ -e "$CODENAMES" ]; then + grep ' '"$cpuid_up"' ' "$CODENAMES" \ + | while IFS=$'\t' read segm int_fname codename stepping candidate_pf rest; do + codename=$(echo "$codename" | tr ' (),' '_[];') + candidate_pf=$(printf "%u" "0x${candidate_pf}") + [ \( 0 -ne "$pf_mask" \) -a \ + \( "$candidate_pf" -ne "$((candidate_pf & pf_mask))" \) ] || { \ + printf "iucode_rev(fname:%s;cpuid:%s;pf_mask:0x%x;segment:\"%s\";codename:\"%s\";stepping:\"%s\";pf_model:0x%x) = %s\n" \ + "$ucode_fname" "$cpuid" "$pf_mask" \ + "$segm" "$codename" "$stepping" "$candidate_pf" \ + "$rev"; + printf "iucode_date(fname:%s;cpuid:%s;pf_mask:0x%x;segment:\"%s\";codename:\"%s\";stepping:\"%s\";pf_model:0x%x) = %s.%s.%s\n" \ + "$ucode_fname" "$cpuid" "$pf_mask" \ + "$segm" "$codename" "$stepping" "$candidate_pf" \ + "$date_y" "$date_m" "$date_d"; + } + done + fi + + # Kludge squared: generate additional "Provides:" tags + # for the files in the overrides tarball (that a placed + # in a separate caveat with a specific name) + [ "x${ucode_caveat}" != "x${UPDATED}" ] || { + printf "firmware_updated(intel-ucode/%s) = %s\n" \ + "$ucode" "$rev"; + } + done +done | sort -u diff --git a/SPECS/intel_config b/SPECS/intel_config new file mode 100644 index 0000000..1f47b87 --- /dev/null +++ b/SPECS/intel_config @@ -0,0 +1,8 @@ +path intel-ucode/* +vendor GenuineIntel +kernel_early 4.10.0 +kernel_early 3.10.0-930 +kernel_early 3.10.0-862.14.1 +kernel_early 3.10.0-693.38.1 +kernel_early 3.10.0-514.57.1 +kernel_early 3.10.0-327.73.1 diff --git a/SPECS/intel_disclaimer b/SPECS/intel_disclaimer new file mode 100644 index 0000000..c4669ba --- /dev/null +++ b/SPECS/intel_disclaimer @@ -0,0 +1,10 @@ +This kernel doesn't handle early microcode load properly (it tries to load +microcode even in virtualised environment, which may lead to a panic on some +hypervisors), thus the microcode files have not been added to the initramfs +image. Please update your kernel to one of the following: + RHEL 7.5: kernel-3.10.0-862.14.1 or newer; + RHEL 7.4: kernel-3.10.0-693.38.1 or newer; + RHEL 7.3: kernel-3.10.0-514.57.1 or newer; + RHEL 7.2: kernel-3.10.0-327.73.1 or newer. +Please refer to /usr/share/doc/microcode_ctl/caveats/intel_readme +and /usr/share/doc/microcode_ctl/README.caveats for details. diff --git a/SPECS/intel_readme b/SPECS/intel_readme new file mode 100644 index 0000000..de9213d --- /dev/null +++ b/SPECS/intel_readme @@ -0,0 +1,53 @@ +Older RHEL 7 kernels try to early load microcode even inside virtual +machine, which may lead to panic on some hypervisors. In order to circumvent +that, microcode is installed into a kernel-version-specific directory (which +is not scanned by the dracut script, that constructs early microcode binary +in initramfs, by default), and path to microcode files provided only in case +initramfs is generated for the kernel version that properly handles early +microcode inside a virtual machine (i.e. do not attempts yo load it). +The versions of the kernel package that properly handle early microcode load +inside a virtual machine are as follows: + * RHEL 7.6 onwards: kernel-3.10.0-930 or newer; + * RHEL 7.5: kernel-3.10.0-862.14.1 or newer; + * RHEL 7.4: kernel-3.10.0-693.38.1 or newer; + * RHEL 7.3: kernel-3.10.0-514.57.1 or newer; + * RHEL 7.2: kernel-3.10.0-327.73.1 or newer. +RHEL 8 kernels are not affected. + +If you want to avoid early load of microcode for a specific kernel, please +create "disallow-early-intel" file inside /lib/firmware/ +directory and run dracut -f --kver "": + + touch /lib/firmware/3.10.0-862.9.1/disallow-early-intel + dracut -f --kver 3.10.0-862.9.1 + +If you want to avoid early load of microcode for all kernels, please create +"disallow-early-intel" file inside the "/etc/microcode_ctl/ucode_with_caveats" +directory and run dracut -f --regenerate-all: + + mkdir -p /etc/microcode_ctl/ucode_with_caveats + touch /etc/microcode_ctl/ucode_with_caveats/disallow-early-intel + dracut -f --regenerate-all + +If you want to enforce early load of microcode for a specific kernel, please +create "force-early-intel" file inside /lib/firmware/ directory +and run dracut -f --kver "": + + touch /lib/firmware/3.10.0-862.9.1/force-early-intel + dracut -f --kver 3.10.0-862.9.1 + +If you want to enforce early load of microcode for all kernels, please create +"force-early-intel" file inside /etc/microcode_ctl/ucode_with_caveats +directory and run dracut -f --kver "": + + mkdir -p /etc/microcode_ctl/ucode_with_caveats + touch /etc/microcode_ctl/ucode_with_caveats/force-early-intel + dracut -f --regenerate-all + +In order to override the late load behaviour, the "early" part of file names +should be replaced with "late" (and there is no need to call dracut +in that case). + + +Please refer to /usr/share/doc/microcode_ctl/README.caveats for additional +information. diff --git a/SPECS/microcode.service b/SPECS/microcode.service new file mode 100644 index 0000000..a96138f --- /dev/null +++ b/SPECS/microcode.service @@ -0,0 +1,12 @@ +[Unit] +Description=Load CPU microcode update +After=basic.target +ConditionVirtualization=false +ConditionPathExists=/sys/devices/system/cpu/microcode/reload + +[Service] +Type=oneshot +RemainAfterExit=no +ExecStart=/usr/libexec/microcode_ctl/reload_microcode +[Install] +WantedBy=basic.target diff --git a/SPECS/reload_microcode b/SPECS/reload_microcode new file mode 100644 index 0000000..5d4d1b1 --- /dev/null +++ b/SPECS/reload_microcode @@ -0,0 +1,22 @@ +#! /bin/bash -efu + +# Trigger microcode reload with additional check for BDW-EP that can have +# microcode reloaded only in case kernel has specific patches. +# +# SPDX-License-Identifier: CC0-1.0 + +CHECK_CAVEATS=/usr/libexec/microcode_ctl/check_caveats +IGNORE_HYPERVISOR="/etc/microcode_ctl/ignore-hypervisor-flag" + +[ -e "$IGNORE_HYPERVISOR" ] || { + if grep -q '^flags[[:space:]]*:.* hypervisor\( .*\)\?$' /proc/cpuinfo + then + exit 0 + fi +} + +"$CHECK_CAVEATS" -m > /dev/null || exit 0 + +echo 2>/dev/null 1 > /sys/devices/system/cpu/microcode/reload || : + +exit 0 diff --git a/SPECS/update_ucode b/SPECS/update_ucode new file mode 100644 index 0000000..0d5038e --- /dev/null +++ b/SPECS/update_ucode @@ -0,0 +1,290 @@ +#! /bin/bash -eu + +# Maintain kernel-version-specific symlinks in /lib/firmware based on +# configuration present in /usr/share/microcode_ctl/ucode_with_caveats. +# +# SPDX-License-Identifier: CC0-1.0 + +usage() +{ + echo "Usage: update_ucode [--action {add|remove|refresh|list}]" \ + "[--kernel KERNELVER]* [--verbose] [--dry-run]" \ + "[--cleanup intel_ucode caveats_ucode]" \ + "[--skip-common] [--skip-kernel-specific]" >&2 +} + +debug() { [ 0 = "$verbose" ] || echo "$*" >&2; } + +MC_DIR=/usr/share/microcode_ctl +INTEL_UCODE_DIR=intel-ucode +DATA_DIR=/usr/share/microcode_ctl/ucode_with_caveats +FW_DIR=/lib/firmware +check_caveats=/usr/libexec/microcode_ctl/check_caveats + +action=refresh +kernel= +verbose=0 +verbose_opt= +dry_run=0 +remove_cleanup=0 +cleanup_intel= +cleanup_caveats= +skip_common=0 +skip_caveats=0 + +while [ 1 -le "$#" ]; do + case "$1" in + -C|--skip-common) + skip_common=1 + ;; + -K|--skip-kernel-specific) + skip_caveats=1 + ;; + -a|--action) + shift + action="$1" + ;; + -k|--kernel) + shift + kernel="$kernel $1" + ;; + -v|--verbose) + verbose=1 + verbose_opt="-v" + ;; + -n|--dry-run) + dry_run=1 + ;; + -c|--cleanup) + remove_cleanup=1 + shift + cleanup_intel="$1" + shift + cleanup_caveats="$1" + ;; + *) + echo "Unknown argument \"$1\"" >&2 + usage + exit 1 + esac + shift +done + +cmd= +[ 0 -eq "$dry_run" ] || cmd=echo + +case "$action" in +add|remove|refresh|list) + # Scan all directories in FW_DIR and all existing kernels + if [ -z "$kernel" ]; then + debug "No kernel versions provided, scanning..." + + kvers=$(find /lib/modules/ -name '[2-9].*' -print) + for k_dir in $kvers; do + k="${k_dir#/lib/modules/}" + [ ! -e "${k_dir}/symvers.gz" ] || { + debug " Adding $k (from /lib/modules)" + kernel="$kernel $k" + } + done + + kvers=$(find /lib/firmware/ -name '[2-9].*' -print) + for k_dir in $kvers; do + k="${k_dir#/lib/firmware/}" + [ ! -d "$k_dir" ] || { + debug " Adding $k (from /lib/firmware)" + kernel="$kernel $k" + } + done + + kernel=$(printf "%s" "$kernel" | xargs -n 1 | sort -u) + fi + ;; +*) + echo "Unknown action \"$action\"" >&2 + usage + exit 1 + ;; +esac + +# Generic part: managing intel ucode +debug "Running action \"$action\" on common Intel microcode directory" +while :; do + [ 0 -eq "$skip_common" ] || break + + [ ! -e "/etc/microcode_ctl/intel-ucode-disallow" ] || { + debug " Skipping \"$i\":" \ + "\"/etc/microcode_ctl/intel-ucode-disallow\"" \ + "present" + break + } + [ ! -e "$FW_DIR/intel-ucode-disallow" ] || { + debug " Found \"$FW_DIR/intel-ucode-disallow\"," \ + "skipping" + break + } + + # Removing old files + case "$action" in + refresh|remove|list) + debug " Removing old files from ${FW_DIR}/${INTEL_UCODE_DIR}" + if [ 0 = "$remove_cleanup" ]; then + find "${MC_DIR}/${INTEL_UCODE_DIR}" \ + -maxdepth 1 -mindepth 1 \ + -type f -printf '%f\n' + else + cat "$cleanup_intel" + fi | while read -r fname; do + name="${FW_DIR}/${INTEL_UCODE_DIR}/${fname}" + + # Needed in case we downgrade to a version where + # no symlinks in /lib/firmware were used + if [ 1 = "$remove_cleanup" ]; then + [ -L "$name" ] || continue + fi + + [ "xlist" != "x$action" ] || { + echo "$name" + continue + } + + $cmd rm -f $verbose_opt "$name" + done + [ "xlist" = "x$action" ] || { + $cmd rmdir -p $verbose_opt \ + "${FW_DIR}/${INTEL_UCODE_DIR}" 2>/dev/null \ + || true + } + ;; + esac + + # Adding new ones + case "$action" in + add|refresh) + debug " Creating symlinks in ${FW_DIR}/${INTEL_UCODE_DIR}" + $cmd mkdir -p $verbose_opt "${FW_DIR}/${INTEL_UCODE_DIR}" + $cmd find "${MC_DIR}/${INTEL_UCODE_DIR}" -maxdepth 1 -mindepth 1 \ + -type f -exec bash -c 'ln -fs '"$verbose_opt"' '\''{}'\'' \ + "'"${FW_DIR}/${INTEL_UCODE_DIR}/"'$(basename '\''{}'\'')"' \; + ;; + esac + + break +done + +debug "Running action \"$action\" on kernels $kernel" + +if [ 0 = "$remove_cleanup" ]; then + ls "$DATA_DIR" +else + cat "$cleanup_caveats" +fi | while read -r i; do + [ 0 -eq "$skip_caveats" ] || break + + debug "Processing data directory \"$i\"..." + + for k in $(echo "$kernel"); do + debug " Processing kernel version \"$k\"" + { + out=$($check_caveats -k "$k" -c "$i" $verbose_opt) + ret="$?" + } || : + paths=$(printf "%s" "$out" | sed -n 's/^paths //p') + ignore=$(printf "%s" "$out" | sed -n 's/^skip_cfgs //p') + + [ -z "$ignore" ] || { + debug " Configuration is ignored, skipping" + continue + } + + case "$action" in + remove|refresh|list) + [ "xlist" = "x$action" ] || \ + debug " Removing \"$paths\" (part of $action)..." + + for p in $(printf "%s" "$paths"); do + find "$DATA_DIR/$i" -path "$DATA_DIR/$i/$p" \ + -printf "%P\n" + done | while read -r path; do + [ -e "$FW_DIR/$k/readme-$i" ] || { + debug " \"$FW_DIR/$k/readme-$i\"" \ + "is not found, skipping" \ + "\"$paths\" removal" + + break + } + + if [ "xlist" = "x$action" ]; then + echo "$FW_DIR/$k/$path" + else + debug " Removing \"$FW_DIR/$k/$path\"" + $cmd rm -f $verbose_opt "$FW_DIR/$k/$path" + $cmd rmdir -p $verbose_opt \ + "$FW_DIR/$k/$(dirname $path)" 2>/dev/null \ + || true + fi + done + + if [ -e "$FW_DIR/$k/readme-$i" ]; then + if [ "xlist" = "x$action" ]; then + echo "$FW_DIR/$k/readme-$i" + else + $cmd rm -f $verbose_opt \ + "$FW_DIR/$k/readme-$i" + $cmd rmdir -p $verbose_opt \ + "$FW_DIR/$k" 2>/dev/null || true + fi + fi + ;; + esac + + [ 0 -eq "$ret" ] || { + debug " Checking for caveats failed" \ + "(kernel version \"$k\"), skipping" + continue + } + + [ -n "$paths" ] || { + debug " List of paths to add is empty, skipping" + continue + } + + case "$action" in + add|refresh) + debug " Adding $paths (part of $action)..." + + [ -e "/lib/modules/$k/symvers.gz" ] || { + debug " \"/lib/modules/$k/symvers.gz\"" \ + "does not exist, skipping" + continue + } + + for p in $(printf "%s" "$paths"); do + find "$DATA_DIR/$i" -path "$DATA_DIR/$i/$p" \ + -printf "%P\n" + done | while read -r path; do + [ ! -e "$FW_DIR/$k/$path" ] || { + debug " $FW_DIR/$k/$path already" \ + "exists, skipping" + continue + } + + debug " Adding \"$FW_DIR/$k/$path\"" + $cmd mkdir -p $verbose_opt \ + "$(dirname "$FW_DIR/$k/$path")" + $cmd ln -fs $verbose_opt "$DATA_DIR/$i/$path" \ + "$FW_DIR/$k/$path" + done + + if [ -e "$FW_DIR/$k/readme-$i" ]; then + debug " $FW_DIR/$k/readme-$i already" \ + "exists, skipping creation" + else + $cmd cp $verbose_opt "$DATA_DIR/$i/readme" \ + "$FW_DIR/$k/readme-$i" + fi + ;; + remove) + esac + done +done