commit 124cb1f15cdf0a60a7ef824d91bec97877957c26 Author: CentOS Sources Date: Fri Aug 2 11:43:37 2019 -0400 import microcode_ctl-20180807a-2.20190514a.2.el8_0 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9746acd --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/microcode-20190514a.tar.gz diff --git a/.microcode_ctl.metadata b/.microcode_ctl.metadata new file mode 100644 index 0000000..d49f21d --- /dev/null +++ b/.microcode_ctl.metadata @@ -0,0 +1 @@ +252f56e1e1e6dc491813cb649c5c83fe1ff1c122 SOURCES/microcode-20190514a.tar.gz diff --git a/SOURCES/01-microcode.conf b/SOURCES/01-microcode.conf new file mode 100644 index 0000000..52511c0 --- /dev/null +++ b/SOURCES/01-microcode.conf @@ -0,0 +1 @@ +early_microcode="yes" diff --git a/SOURCES/06-4f-01_config b/SOURCES/06-4f-01_config new file mode 100644 index 0000000..f589fbf --- /dev/null +++ b/SOURCES/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/SOURCES/06-4f-01_readme b/SOURCES/06-4f-01_readme new file mode 100644 index 0000000..740ad18 --- /dev/null +++ b/SOURCES/06-4f-01_readme @@ -0,0 +1,76 @@ +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": + + 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: + + touch /etc/microcode_ctl/ucode_with_caveats/force-early-intel-06-4f-01 + dracut -f --regenerate-all + +If you want 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/SOURCES/99-microcode-override.conf b/SOURCES/99-microcode-override.conf new file mode 100644 index 0000000..c898801 --- /dev/null +++ b/SOURCES/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/SOURCES/README.caveats b/SOURCES/README.caveats new file mode 100644 index 0000000..6f98122 --- /dev/null +++ b/SOURCES/README.caveats @@ -0,0 +1,452 @@ +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. + + +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 overridden. (See sections "check_caveats script" +and "reload_microcode script" for details). + +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. + +Affected microcode: all. + +Mitigation: early microcode loading is disabled for all CPU models. + +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 + + +Additional information +====================== +Red Hat provides updated microcode, developed by our 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 +microarchitectural side-channel attacks 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 diff --git a/SOURCES/check_caveats b/SOURCES/check_caveats new file mode 100755 index 0000000..93c7406 --- /dev/null +++ b/SOURCES/check_caveats @@ -0,0 +1,483 @@ +#! /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 [-e] [-k TARGET_KVER] [-c CONFIG] [-m] [-v]' + echo + 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 +} + +# 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" +} + +#check_kver "$@" +#get_model_name + +match_model=0 +configs= +kver=$(/bin/uname -r) +verbose=0 +early_check=0 + +ret=0 + +while getopts "ek:c:mv" opt; do + case "${opt}" in + 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= + + 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 + break + ;; + 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 + find "$MC_CAVEATS_DATA_DIR/$cfg" \ + -path "$MC_CAVEATS_DATA_DIR/$cfg/$p" -print0 \ + | grep -zFxq "$cpu_mc_path" \ + || continue + + cfg_mc_present=1 + 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 + + ok_cfgs="$ok_cfgs $cfg" + ok_paths="$ok_paths $cfg_path" +done + +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/SOURCES/dracut_99microcode_ctl-fw_dir_override_module_init.sh b/SOURCES/dracut_99microcode_ctl-fw_dir_override_module_init.sh new file mode 100755 index 0000000..c14fcb9 --- /dev/null +++ b/SOURCES/dracut_99microcode_ctl-fw_dir_override_module_init.sh @@ -0,0 +1,163 @@ +#!/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}\"" + } + + while read -d "/" -r i; do + dinfo " microcode_ctl: processing data directory " \ + "\"$DATA_DIR/$i\"..." + + if ! cc_out=$($check_caveats -e -k "$kernel" -c "$i" $verbose_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 + } + + 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 + + if [ 0 -eq "$do_skip_host_only" ]; then + local hostonly_passed=0 + local ucode + local uvendor + local ucode_dir="" + + ucode=$(get_ucode_file) + uvendor=$(get_cpu_vendor) + + case "$uvendor" in + Intel) + ucode_dir="intel-ucode" + ;; + AMD) + ucode_dir="amd-ucode" + ;; + *) + dinfo " microcode_ctl: unknown CPU" \ + "vendor: \"$uvendor\", bailing out of" \ + "Host-Only check" + continue + ;; + esac + + # $path is a list of globs, so it needs special care + for p in $(printf "%s" "$path"); do + find "$DATA_DIR/$i" -path "$DATA_DIR/$i/$p" \ + -print0 \ + | grep -zFxq \ + "$DATA_DIR/$i/$ucode_dir/$ucode" \ + || continue + + dinfo " microcode_ctl: $i: Host-Only" \ + "mode is enabled and" \ + "\"$ucode_dir/$ucode\" matches \"$p\"" + + hostonly_passed=1 + break + done + + [ 1 -eq "$hostonly_passed" ] || { + dinfo " microcode_ctl: $i: Host-Only mode" \ + "is enabled and ucode name does not" \ + "match the expected one, skipping" \ + "caveat (\"$ucode\" not in \"$path\")" + continue + } + fi + + dinfo " microcode_ctl: $i: caveats check for kernel" \ + "version \"$kernel\" passed, adding" \ + "\"$DATA_DIR/$i\" to fw_dir variable" + fw_dir="$DATA_DIR/$i $fw_dir" + + # 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. + done <<-EOF + $(find "$DATA_DIR" -maxdepth 1 -mindepth 1 -type d -printf "%f/" \ + | sort -r) + EOF + + dinfo " microcode_ctl: final fw_dir: \"${fw_dir}\"" +} + diff --git a/SOURCES/gen_provides.sh b/SOURCES/gen_provides.sh new file mode 100755 index 0000000..0ecf7aa --- /dev/null +++ b/SOURCES/gen_provides.sh @@ -0,0 +1,114 @@ +#! /bin/bash -efux + +# 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 + + while :; do + [ "$skip" -lt "$file_sz" ] || break + + # Microcode header format description: + # https://gitlab.com/iucode-tool/iucode-tool/blob/master/intel_microcode.c + IFS=' ' read hdrver rev \ + date_y date_d date_m \ + cpuid cksum ldrver \ + pf_mask datasz totalsz <<- EOF + $(dd if="$f" bs=1 skip="$skip" count=36 status=none \ + | hexdump -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"') + 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. + + skip=$((skip + totalsz)) + + #[ -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/SOURCES/intel_config b/SOURCES/intel_config new file mode 100644 index 0000000..d37878d --- /dev/null +++ b/SOURCES/intel_config @@ -0,0 +1,8 @@ +path intel-ucode/* +vendor_id 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/SOURCES/intel_readme b/SOURCES/intel_readme new file mode 100644 index 0000000..ed352e5 --- /dev/null +++ b/SOURCES/intel_readme @@ -0,0 +1,54 @@ +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-intel + /usr/libexec/microcode_ctl/update_ucode + 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-intel + dracut -f --kver 3.10.0-862.9.1 + +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 "": + + modir -p/lib/firmware/3.10.0-862.9.1/ + 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 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/SOURCES/microcode.service b/SOURCES/microcode.service new file mode 100644 index 0000000..a96138f --- /dev/null +++ b/SOURCES/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/SOURCES/reload_microcode b/SOURCES/reload_microcode new file mode 100644 index 0000000..5d4d1b1 --- /dev/null +++ b/SOURCES/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/SOURCES/update_ucode b/SOURCES/update_ucode new file mode 100644 index 0000000..0d5038e --- /dev/null +++ b/SOURCES/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 diff --git a/SPECS/microcode_ctl.spec b/SPECS/microcode_ctl.spec new file mode 100644 index 0000000..01ee903 --- /dev/null +++ b/SPECS/microcode_ctl.spec @@ -0,0 +1,587 @@ +%define intel_ucode_version 20190514a +%define intel_ucode_file_id 28727 +%global debug_package %{nil} + +%define caveat_dir %{_datarootdir}/microcode_ctl/ucode_with_caveats +%define microcode_ctl_libexec %{_libexecdir}/microcode_ctl + +%define update_ucode %{microcode_ctl_libexec}/update_ucode +%define check_caveats %{microcode_ctl_libexec}/check_caveats +%define reload_microcode %{microcode_ctl_libexec}/reload_microcode + +%define dracutlibdir %{_prefix}/lib/dracut + +Summary: CPU microcode updates for Intel x86 processors +Name: microcode_ctl +Version: 20180807a +Release: 2.%{intel_ucode_version}.2%{?dist} +Epoch: 4 +License: CC0 and Redistributable, no modification permitted +URL: https://downloadcenter.intel.com/download/%{intel_ucode_file_id}/Linux-Processor-Microcode-Data-File +Source0: https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/archive/microcode-%{intel_ucode_version}.tar.gz + + +# systemd unit +Source10: microcode.service + +# dracut-related stuff +Source20: 01-microcode.conf +Source21: 99-microcode-override.conf +Source22: dracut_99microcode_ctl-fw_dir_override_module_init.sh + +# libexec +Source30: update_ucode +Source31: check_caveats +Source32: reload_microcode + +# docs +Source41: README.caveats + +## Caveats +# BDW EP/EX +Source100: 06-4f-01_readme +Source101: 06-4f-01_config + +# Unsafe early MC update inside VM: +# https://bugzilla.redhat.com/show_bug.cgi?id=1596627 +Source110: intel_readme +Source111: intel_config + +Source200: gen_provides.sh + +ExclusiveArch: %{ix86} x86_64 +BuildRequires: systemd-units +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +Requires(posttrans): kernel + +%global _use_internal_dependency_generator 0 +%define __find_provides "%{SOURCE200}" + +%description +This package provides microcode update files for Intel x86 and x86_64 CPUs. + +The microcode update is volatile and needs to be uploaded on each system +boot i.e. it isn't stored on a CPU permanently; reboot and it reverts +back to the old microcode. + +Package name "microcode_ctl" is historical, as the binary with the same name +is no longer used for microcode upload and, as a result, no longer provided. + +%prep +%setup -n "Intel-Linux-Processor-Microcode-Data-Files-microcode-%{intel_ucode_version}" + +%build +: + +%install +install -m 755 -d \ + "%{buildroot}/%{_datarootdir}/microcode_ctl/intel-ucode" \ + "%{buildroot}/%{caveat_dir}/" \ + "%{buildroot}/etc/microcode_ctl/ucode_with_caveats/" + +# systemd unit +install -m 755 -d "%{buildroot}/%{_unitdir}" +install -m 644 "%{SOURCE10}" -t "%{buildroot}/%{_unitdir}/" + +# dracut +%define dracut_mod_dir "%{buildroot}/%{dracutlibdir}/modules.d/99microcode_ctl-fw_dir_override" +install -m 755 -d \ + "%{dracut_mod_dir}" \ + "%{buildroot}/%{dracutlibdir}/dracut.conf.d/" +install -m 644 "%{SOURCE20}" "%{SOURCE21}" \ + -t "%{buildroot}/%{dracutlibdir}/dracut.conf.d/" +install -m 755 "%{SOURCE22}" "%{dracut_mod_dir}/module-setup.sh" + +# Internal helper scripts +install -m 755 -d "%{buildroot}/%{microcode_ctl_libexec}" +install "%{SOURCE30}" "%{SOURCE31}" "%{SOURCE32}" \ + -m 755 -t "%{buildroot}/%{microcode_ctl_libexec}" + + +## Documentation +install -m 755 -d "%{buildroot}/%{_pkgdocdir}/caveats" + +install "%{SOURCE41}" \ + -m 644 -t "%{buildroot}/%{_pkgdocdir}/" + +# Provide Intel microcode license, as it requires so +install -m 644 license \ + "%{buildroot}/%{_pkgdocdir}/LICENSE.intel-ucode" +install -m 644 releasenote \ + "%{buildroot}/%{_pkgdocdir}/RELEASE_NOTES.intel-ucode" + +# caveats +install -m 644 "%{SOURCE100}" "%{SOURCE110}" \ + -t "%{buildroot}/%{_pkgdocdir}/caveats/" + + +## Caveat data + +# BDW caveat +%define bdw_inst_dir %{buildroot}/%{caveat_dir}/intel-06-4f-01/ +install -m 755 -d "%{bdw_inst_dir}/intel-ucode" +install -m 644 intel-ucode-with-caveats/* -t "%{bdw_inst_dir}/intel-ucode/" +install -m 644 "%{SOURCE100}" "%{bdw_inst_dir}/readme" +install -m 644 "%{SOURCE101}" "%{bdw_inst_dir}/config" + +# Early update caveat +%define intel_inst_dir %{buildroot}/%{caveat_dir}/intel/ +install -m 755 -d "%{intel_inst_dir}/intel-ucode" +install -m 644 intel-ucode/* -t "%{intel_inst_dir}/intel-ucode/" +install -m 644 "%{SOURCE110}" "%{intel_inst_dir}/readme" +install -m 644 "%{SOURCE111}" "%{intel_inst_dir}/config" + + +## Cleanup +#rm -f intel-ucode-with-caveats/06-4f-01 +#rmdir intel-ucode-with-caveats +#rm -rf intel-ucode + + +%post +%systemd_post microcode.service +%{update_ucode} +%{reload_microcode} + +exit 0 + +%posttrans +# We only want to regenerate the initramfs for a fully booted +# system; if this package happened to e.g. be pulled in as a build +# dependency, it is pointless at best to regenerate the initramfs, +# and also does not work with rpm-ostree: +# https://bugzilla.redhat.com/show_bug.cgi?id=1199582 +# +# Also check that the running kernel is actually installed: +# https://bugzilla.redhat.com/show_bug.cgi?id=1591664 +# We use the presence of symvers file as an indicator, the check similar +# to what weak-modules script does. +# +# Now that /boot/symvers-KVER.gz population is now relies on some shell scripts +# that are triggered by other shell scripts (kernel-install, which is a part +# of systemd) that called by RPM scripts, and systemd is not inclined to fix +# https://bugzilla.redhat.com/show_bug.cgi?id=1609698 +# https://bugzilla.redhat.com/show_bug.cgi?id=1609696 +# So, we check for symvers file inside /lib/modules. +if [ -d /run/systemd/system -a -e "/lib/modules/$(uname -r)/symvers.gz" ]; then + dracut -f +fi + +%global rpm_state_dir %{_localstatedir}/lib/rpm-state + + +%preun +%systemd_preun microcode.service + +# Storing ucode list before uninstall +ls /usr/share/microcode_ctl/intel-ucode | + sort > "%{rpm_state_dir}/microcode_ctl_un_intel-ucode" +ls /usr/share/microcode_ctl/ucode_with_caveats | + sort > "%{rpm_state_dir}/microcode_ctl_un_ucode_caveats" +%{update_ucode} --action list --skip-common | + sort > "%{rpm_state_dir}/microcode_ctl_un_file_list" + +%postun +%systemd_postun microcode.service + +ls /usr/share/microcode_ctl/intel-ucode 2> /dev/null | + sort > "%{rpm_state_dir}/microcode_ctl_un_intel-ucode_after" +comm -23 \ + "%{rpm_state_dir}/microcode_ctl_un_intel-ucode" \ + "%{rpm_state_dir}/microcode_ctl_un_intel-ucode_after" \ + > "%{rpm_state_dir}/microcode_ctl_un_intel-ucode_diff" + +if [ -e "%{update_ucode}" ]; then + ls /usr/share/microcode_ctl/ucode_with_caveats 2> /dev/null | + sort > "%{rpm_state_dir}/microcode_ctl_un_ucode_caveats_after" + + comm -23 \ + "%{rpm_state_dir}/microcode_ctl_un_ucode_caveats" \ + "%{rpm_state_dir}/microcode_ctl_un_ucode_caveats_after" \ + > "%{rpm_state_dir}/microcode_ctl_un_ucode_caveats_diff" + + %{update_ucode} --action remove --cleanup \ + "%{rpm_state_dir}/microcode_ctl_un_intel-ucode_diff" \ + "%{rpm_state_dir}/microcode_ctl_un_ucode_caveats_diff" || : + + rm -f "%{rpm_state_dir}/microcode_ctl_un_ucode_caveats_after" + rm -f "%{rpm_state_dir}/microcode_ctl_un_ucode_caveats_diff" +else + while read -r f; do + [ -L "/lib/firmware/intel-ucode/$f" ] || continue + rm -f "/lib/firmware/intel-ucode/$f" + done < "%{rpm_state_dir}/microcode_ctl_un_intel-ucode_diff" + + rmdir "/lib/firmware/intel-ucode" 2>/dev/null || : + + # We presume that if we don't have update_ucode script, we can remove + # all the caveats-related files. + while read -r f; do + if [ -L "$f" ] || [ "${f%%readme-*}" != "$f" ]; then + rm -f "$f" + rmdir -p $(dirname "$f") 2>/dev/null || : + fi + done < "%{rpm_state_dir}/microcode_ctl_un_file_list" +fi + +rm -f "%{rpm_state_dir}/microcode_ctl_un_intel-ucode" +rm -f "%{rpm_state_dir}/microcode_ctl_un_intel-ucode_after" +rm -f "%{rpm_state_dir}/microcode_ctl_un_intel-ucode_diff" + +rm -f "%{rpm_state_dir}/microcode_ctl_un_ucode_caveats" + +rm -f "%{rpm_state_dir}/microcode_ctl_un_file_list" + +exit 0 + + +%triggerin -- kernel-core +%{update_ucode} + +%triggerpostun -- kernel-core +%{update_ucode} + + +%clean +rm -rf %{buildroot} + + +%files +%ghost %attr(0755, root, root) /lib/firmware/intel-ucode +%{microcode_ctl_libexec} +/usr/share/microcode_ctl +/etc/microcode_ctl +%{dracutlibdir}/modules.d/* +%config(noreplace) %{dracutlibdir}/dracut.conf.d/* +%{_unitdir}/microcode.service +%doc %{_pkgdocdir} + + +%changelog +* Sun Jun 02 2019 Eugene Syromiatnikov - 4:20180807a-2.20190514a.2 +- Remove disclaimer, as it is not as important now to justify kmsg/log + pollution; its contents are partially adopted in README.caveats. + +* Mon May 20 2019 Eugene Syromiatnikov - 4:20180807a-2.20190514a.1 +- Intel CPU microcode update to 20190514a (#1715334). + +* Fri May 10 2019 Eugene Syromiatnikov - 4:20180807a-2.20190507.1 +- Intel CPU microcode update to 20190507 (#1704339). + +* Fri May 10 2019 Eugene Syromiatnikov 4:20180807a-2.20190312.1 +- Intel CPU microcode update to 20190312 (#1704339). +- Add "Provides:" tags generation. + +* Tue Nov 06 2018 Eugene Syromiatnikov 4:20180807a-2 +- Do not exit with error in %postin if disclaimer printing returned an error + (#1647083). + +* Wed Oct 17 2018 Eugene Syromiatnikov 4:20180807a-1 +- Use the tar ball distributed by Intel directly, sync up with RHEL 7.6. + +* Fri Aug 24 2018 Eugene Syromiatnikov 3:2.1-27 +- Bump epoch in order to ensure upgrade from RHEL 7 (#1622131). + +* Mon Aug 13 2018 Anton Arapov 2:2.1-26 +- Update to upstream 2.1-19. 20180807 + +* Fri Jul 13 2018 Fedora Release Engineering - 2:2.1-25 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Mon Jul 09 2018 Anton Arapov 2:2.1-24 +- Update to upstream 2.1-18. 20180703 + +* Wed May 16 2018 Anton Arapov 2:2.1-23 +- Update to upstream 2.1-17. 20180425 + +* Thu Mar 15 2018 Anton Arapov 2:2.1-22 +- Update to upstream 2.1-16. 20180312 + +* Thu Feb 08 2018 Fedora Release Engineering - 2:2.1-21 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Tue Jan 09 2018 Anton Arapov 2:2.1-20 +- Update to upstream 2.1-15. 20180108 + +* Tue Nov 21 2017 Anton Arapov 2:2.1-19 +- Update to upstream 2.1-14. 20171117 + +* Thu Aug 03 2017 Fedora Release Engineering - 2:2.1-18 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 2:2.1-17 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Wed Jul 12 2017 Anton Arapov 2:2.1-16 +- Update to upstream 2.1-13. 20170707 + +* Tue May 23 2017 Anton Arapov 2:2.1-15 +- Update to upstream 2.1-12. 20170511 + +* Fri Feb 10 2017 Fedora Release Engineering - 2:2.1-14.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Fri Dec 02 2016 Anton Arapov 2.1-13.1 +- Update to upstream 2.1-11. 20161104 + +* Thu Jul 21 2016 Anton Arapov 2.1-13 +- Update to upstream 2.1-10. 20160714 +- Fixes rhbz#1353103 + +* Fri Jun 24 2016 Anton Arapov 2.1-12 +- Update to upstream 2.1-9. 20160607 + +* Thu Feb 04 2016 Fedora Release Engineering - 2:2.1-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Tue Jan 12 2016 Anton Arapov 2.1-10 +- Update to upstream 2.1-8. 20151106 + +* Wed Jun 17 2015 Fedora Release Engineering - 2:2.1-9.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Tue Feb 03 2015 Anton Arapov 2.1-8.1 +- Update to upstream 2.1-7. 20150121 + +* Sun Sep 21 2014 Anton Arapov 2.1-8 +- Update to upstream 2.1-6. 20140913 + +* Sun Aug 17 2014 Fedora Release Engineering - 2:2.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Tue Jul 08 2014 Anton Arapov 2.1-6 +- Update to upstream 2.1-5. 20140624 + +* Sat Jun 07 2014 Fedora Release Engineering - 2:2.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Thu May 01 2014 Anton Arapov 2.1-4 +- Update to upstream 2.1-4. + +* Fri Jan 24 2014 Anton Arapov 2.1-3 +- Update to upstream 2.1-3. + +* Mon Sep 09 2013 Anton Arapov 2.1-2 +- Update to upstream 2.1-2. + +* Wed Aug 14 2013 Anton Arapov 2.1-1 +- Update to upstream 2.1-1. + +* Sat Jul 27 2013 Anton Arapov 2.1-0 +- Update to upstream 2.1. AMD microcode has been removed, find it in linux-firmware. + +* Wed Apr 03 2013 Anton Arapov 2.0-3.1 +- Update to upstream 2.0-3 + +* Thu Feb 14 2013 Fedora Release Engineering - 2:2.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Wed Oct 17 2012 Anton Arapov 2.0-2 +- Update to upstream 2.0-2 + +* Tue Oct 02 2012 Anton Arapov 2.0-1 +- Update to upstream 2.0-1 + +* Mon Aug 06 2012 Anton Arapov 2.0 +- Update to upstream 2.0 + +* Wed Jul 25 2012 Anton Arapov 1.18-1 +- Update to upstream 1.18 + +* Fri Jul 20 2012 Fedora Release Engineering - 1:1.17-26 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Thu Jun 07 2012 Anton Arapov 1.17-25 +- Update to microcode-20120606.dat + +* Tue Feb 07 2012 Anton Arapov 1.17-24 +- Update to amd-ucode-2012-01-17.tar + +* Fri Jan 13 2012 Fedora Release Engineering - 1:1.17-22 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Thu Dec 22 2011 Anton Arapov 1.17-21 +- Fix a segfault that may be triggered by very long parameter [#768803] + +* Tue Dec 13 2011 Anton Arapov 1.17-20 +- Update to microcode-20111110.dat + +* Tue Sep 27 2011 Anton Arapov 1.17-19 +- Update to microcode-20110915.dat + +* Thu Aug 04 2011 Anton Arapov 1.17-18 +- Ship splitted microcode for Intel CPUs [#690930] +- Include tool for splitting microcode for Intl CPUs (Kay Sievers ) + +* Thu Jun 30 2011 Anton Arapov 1.17-17 +- Fix udev rules (Dave Jones ) [#690930] + +* Thu May 12 2011 Anton Arapov 1.17-14 +- Update to microcode-20110428.dat + +* Thu Mar 24 2011 Anton Arapov 1.17-13 +- fix memory leak. + +* Mon Mar 07 2011 Anton Arapov 1.17-12 +- Update to amd-ucode-2011-01-11.tar + +* Tue Feb 08 2011 Fedora Release Engineering - 1:1.17-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Wed Jan 19 2011 Anton Arapov 1.17-10 +- manpage fix (John Bradshaw ) [#670879] + +* Wed Jan 05 2011 Anton Arapov 1.17-9 +- Update to microcode-20101123.dat + +* Mon Nov 01 2010 Anton Arapov 1.17-8 +- Update to microcode-20100914.dat + +* Wed Sep 29 2010 jkeating - 1:1.17-7 +- Rebuilt for gcc bug 634757 + +* Wed Sep 15 2010 Anton Arapov 1.17-6 +- Update to microcode-20100826.dat + +* Tue Sep 07 2010 Toshio Kuratomi 1.17-5 +- Fix license tag: bz#450491 + +* Fri Aug 27 2010 Dave Jones 1.17-4 +- Update to microcode-20100826.dat + +* Tue Mar 23 2010 Anton Arapov 1.17-3 +- Fix the udev rules (Harald Hoyer ) + +* Mon Mar 22 2010 Anton Arapov 1.17-2 +- Make microcode_ctl event driven (Bill Nottingham ) [#479898] + +* Thu Feb 11 2010 Dave Jones 1.17-1.58 +- Update to microcode-20100209.dat + +* Fri Dec 04 2009 Kyle McMartin 1.17-1.57 +- Fix duplicate message pointed out by Edward Sheldrake. + +* Wed Dec 02 2009 Kyle McMartin 1.17-1.56 +- Add AMD x86/x86-64 microcode. (Dated: 2009-10-09) + Doesn't need microcode_ctl modifications as it's loaded by + request_firmware() like any other sensible driver. +- Eventually, this AMD firmware can probably live inside + kernel-firmware once it is split out. + +* Wed Sep 30 2009 Dave Jones +- Update to microcode-20090927.dat + +* Fri Sep 11 2009 Dave Jones +- Remove some unnecessary code from the init script. + +* Sat Jul 25 2009 Fedora Release Engineering - 1:1.17-1.52.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Thu Jun 25 2009 Dave Jones +- Shorten sleep time during init. + This really needs to be replaced with proper udev hooks, but this is + a quick interim fix. + +* Wed Jun 03 2009 Kyle McMartin 1:1.17-1.50 +- Change ExclusiveArch to i586 instead of i386. Resolves rhbz#497711. + +* Wed May 13 2009 Dave Jones +- update to microcode 20090330 + +* Wed Feb 25 2009 Fedora Release Engineering - 1:1.17-1.46.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Fri Sep 12 2008 Dave Jones +- update to microcode 20080910 + +* Tue Apr 01 2008 Jarod Wilson +- Update to microcode 20080401 + +* Sat Mar 29 2008 Dave Jones +- Update to microcode 20080220 +- Fix rpmlint warnings in specfile. + +* Mon Mar 17 2008 Dave Jones +- specfile cleanups. + +* Fri Feb 22 2008 Jarod Wilson +- Use /lib/firmware instead of /etc/firmware + +* Wed Feb 13 2008 Jarod Wilson +- Fix permissions on microcode.dat + +* Thu Feb 07 2008 Jarod Wilson +- Spec cleanup and macro standardization. +- Update license +- Update microcode data file to 20080131 revision. + +* Mon Jul 2 2007 Dave Jones +- Update to upstream 1.17 + +* Thu Oct 12 2006 Jon Masters +- BZ209455 fixes. + +* Mon Jul 17 2006 Jesse Keating +- rebuild + +* Fri Jun 16 2006 Bill Nottingham +- remove kudzu requirement +- add prereq for coreutils, awk, grep + +* Thu Feb 09 2006 Dave Jones +- rebuild. + +* Fri Jan 27 2006 Dave Jones +- Update to upstream 1.13 + +* Fri Dec 16 2005 Jesse Keating +- rebuilt for new gcj + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Mon Nov 14 2005 Dave Jones +- initscript tweaks. + +* Tue Sep 13 2005 Dave Jones +- Update to upstream 1.12 + +* Wed Aug 17 2005 Dave Jones +- Check for device node *after* loading the module. (#157672) + +* Tue Mar 1 2005 Dave Jones +- Rebuild for gcc4 + +* Thu Feb 17 2005 Dave Jones +- s/Serial/Epoch/ + +* Tue Jan 25 2005 Dave Jones +- Drop the node creation/deletion change from previous release. + It'll cause grief with selinux, and was a hack to get around + a udev shortcoming that should be fixed properly. + +* Fri Jan 21 2005 Dave Jones +- Create/remove the /dev/cpu/microcode dev node as needed. +- Use correct path again for the microcode.dat. +- Remove some no longer needed tests in the init script. + +* Fri Jan 14 2005 Dave Jones +- Only enable microcode_ctl service if the CPU is capable. +- Prevent microcode_ctl getting restarted multiple times on initlevel change (#141581) +- Make restart/reload work properly +- Do nothing if not started by root. + +* Wed Jan 12 2005 Dave Jones +- Adjust dev node location. (#144963) + +* Tue Jan 11 2005 Dave Jones +- Load/Remove microcode module in initscript. + +* Mon Jan 10 2005 Dave Jones +- Update to upstream 1.11 release. + +* Sat Dec 18 2004 Dave Jones +- Initial packaging, based upon kernel-utils. +