diff --git a/.gitignore b/.gitignore
index 73b7846..c4fca8e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
 SOURCES/06-2d-07
 SOURCES/06-55-04
-SOURCES/microcode-20191115.tar.gz
+SOURCES/microcode-20200602.tar.gz
diff --git a/.microcode_ctl.metadata b/.microcode_ctl.metadata
index 49611a4..5e26097 100644
--- a/.microcode_ctl.metadata
+++ b/.microcode_ctl.metadata
@@ -1,3 +1,3 @@
 bcf2173cd3dd499c37defbc2533703cfa6ec2430 SOURCES/06-2d-07
 2e405644a145de0f55517b6a9de118eec8ec1e5a SOURCES/06-55-04
-774636f4d440623b0ee6a2dad65260e81208074d SOURCES/microcode-20191115.tar.gz
+ea699fd62ba3625062cae60d4a657fa11822b372 SOURCES/microcode-20200602.tar.gz
diff --git a/SOURCES/06-2d-07_readme b/SOURCES/06-2d-07_readme
index 60c20d4..2a9f5ec 100644
--- a/SOURCES/06-2d-07_readme
+++ b/SOURCES/06-2d-07_readme
@@ -1,17 +1,21 @@
 Intel Sandy Bridge-E/EN/EP CPU models (SNB-EP, family 6, model 45, stepping 7)
 have issues with MDS-related microcode update that may lead to a system hang
-after a microcode update. In order to address this, microcode update
+after a microcode update[1][2].  In order to address this, microcode update
 to the MDS-related revision 0x718 has been disabled, and the previously
 published microcode revision 0x714 is used by default for the OS-driven
 microcode update.
 
+[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
+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"):
diff --git a/SOURCES/06-4f-01_disclaimer b/SOURCES/06-4f-01_disclaimer
index d5bc60d..c978958 100644
--- a/SOURCES/06-4f-01_disclaimer
+++ b/SOURCES/06-4f-01_disclaimer
@@ -1,4 +1,4 @@
-microcode update for Intel Broadwell-EP/EX (BDX-ML B/M/R0; family 6, model 79,
+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/SOURCES/06-55-04_config b/SOURCES/06-55-04_config
index 6ba6d76..df081c9 100644
--- a/SOURCES/06-55-04_config
+++ b/SOURCES/06-55-04_config
@@ -1,3 +1,10 @@
 model GenuineIntel 06-55-04
 path intel-ucode/06-55-04
-disable early late
+# 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.
+pci_config_val mode=success-all device=0x1e function=3 vid=0x8086 did=0x2083 offset=0x84 size=4 mask=0x38 val=0x38,0x18,0x8
diff --git a/SOURCES/06-55-04_disclaimer b/SOURCES/06-55-04_disclaimer
index 238d233..afeb511 100644
--- a/SOURCES/06-55-04_disclaimer
+++ b/SOURCES/06-55-04_disclaimer
@@ -1,6 +1,5 @@
-Microcode revision 0x2000065 for Intel Skylake-SP/X/W (family 6, model 85,
-stepping 4; CPUID 0x50654) CPUs that has been included into microcode-20191112
-release is disabled as it may cause system instability and the previous revision
-0x2000064 is used instead.
+Microcode revisions 0x2000065 and higher for Intel Skylake-X/W (family 6,
+model 85, stepping 4; CPUID 0x50654) are disabled as they may cause system
+hangs on reboot and the previous revision 0x2000064 is 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/SOURCES/06-55-04_readme b/SOURCES/06-55-04_readme
index 41fb757..fbfeeba 100644
--- a/SOURCES/06-55-04_readme
+++ b/SOURCES/06-55-04_readme
@@ -1,10 +1,13 @@
-Intel Skulake Scalable Platform CPU models (SKL-SP/W/X, family 6, model 85,
-stepping 4) have reports of system hangs when revision 0x2000065 of microcode,
-that is included since microcode-20191112 update, is applied.  In order
-to address this, microcode update to this revision has been disabled,
+Intel Skulake Scalable Platform CPU models that belong to Workstation and HEDT
+(Basin Falls) segment (SKL-W/X, family 6, model 85, stepping 4) have reports
+of system hangs on reboot when revision 0x2000065 of microcode, that is included
+since microcode-20191112 update, is applied[1].  In order to address this,
+microcode update to this revision has been disabled by default on these systems,
 and the previously published microcode revision 0x2000064 is used by default
 for the OS-driven microcode update.
 
+[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
diff --git a/SOURCES/README.caveats b/SOURCES/README.caveats
index 4ead5e5..65a3fca 100644
--- a/SOURCES/README.caveats
+++ b/SOURCES/README.caveats
@@ -160,6 +160,49 @@ separated by white space.  Currently, the following options are supported:
    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.
+   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.
+
 
 
 check_caveats script
@@ -439,13 +482,16 @@ Minimum versions of the kernel package that contain the fix:
 Intel Sandy Bridge-E/EN/EP caveat
 ---------------------------------
 MDS-related microcode revision 0x718 for Intel Sandy Bridge-E/EN/EP
-(SNB-EP, family 6, model 45, stepping 7) may lead to system instability.
+(SNB-EP, family 6, model 45, stepping 7) may lead to system instability[1][2].
 In order to address this, this microcode update is not used and the previous
 microcode revision is provided instead by default; the microcode file, 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. (See
 the sections "check_caveats script" and "reload_microcode script" for details.)
 
+[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.
@@ -455,14 +501,17 @@ Mitigation: previously published microcode revision 0x714 is used by default.
 
 Intel Skylake-SP/W/X caveat
 ---------------------------
-Microcode revision 0x2000065 for Intel Skylake Scalable Platform (SKL-SP/W/X,
-family 6, model 85, stepping 4) may lead to system instability.
-In order to address this, this microcode update is not used and the previous
-microcode revision is provided instead by default; the microcode file, 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.
-(See the sections "check_caveats script" and "reload_microcode script"
-for details.)
+Microcode revisions 0x2000065 and later for some CPU models that belong to
+Intel Skylake Scalable Platform (SKL-W/X, family 6, model 85, stepping 4,
+Workstation/HEDT segments) may lead to hangs during reboot[1].  In order
+to address this, by default these microcode updates are not used
+and the previous microcode revision is provided instead; the microcode file,
+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. (See the sections "check_caveats script" and "reload_microcode
+script" for details.)
+
+[1] https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/issues/21
 
 Caveat name: intel-06-55-04
 
diff --git a/SOURCES/check_caveats b/SOURCES/check_caveats
index 462d541..f43fb4a 100755
--- a/SOURCES/check_caveats
+++ b/SOURCES/check_caveats
@@ -132,6 +132,132 @@ check_kver()
 	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-spearated, 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
+	)
+}
+
 # Provides model in format "VENDOR_ID FAMILY-MODEL-STEPPING"
 #
 # We check only the first processor as we don't expect non-symmetrical setups
@@ -182,7 +308,7 @@ fail()
 	fail_paths="$fail_paths $cfg_path"
 
 	[ 0 -eq "$print_disclaimers" ] || [ ! -e "${dir}/disclaimer" ] \
-		|| cat "${dir}/disclaimer"
+		|| /bin/cat "${dir}/disclaimer"
 }
 
 #check_kver "$@"
@@ -225,7 +351,7 @@ while getopts "dek:c:mv" opt; do
 	esac
 done
 
-: ${configs:=$(find "${MC_CAVEATS_DATA_DIR}" -maxdepth 1 -mindepth 1 -type d -printf "%f\n")}
+: "${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)
@@ -273,6 +399,7 @@ for cfg in $(echo "${configs}"); do
 	cfg_blacklist=
 	cfg_mc_min_ver_late=
 	cfg_disable=
+	cfg_pci=
 
 	while read -r key value; do
 		case "$key" in
@@ -299,7 +426,17 @@ for cfg in $(echo "${configs}"); do
 			;;
 		blacklist)
 			cfg_blacklist=1
-			break
+			;;
+		pci_config_val)
+			cfg_pci="$cfg_pci
+				$value"
+			;;
+		'#'*|'')
+			continue
+			;;
+		*)
+			debug "Unknown key '$key' (value '$value') in config" \
+			      "'$cfg'"
 			;;
 		esac
 	done < "${dir}/config"
@@ -388,12 +525,14 @@ for cfg in $(echo "${configs}"); do
 		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" \
+			{ /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" ] || {
@@ -478,6 +617,28 @@ for cfg in $(echo "${configs}"); do
 		}
 	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
+
 	ok_cfgs="$ok_cfgs $cfg"
 	ok_paths="$ok_paths $cfg_path"
 done
diff --git a/SOURCES/dracut_99microcode_ctl-fw_dir_override_module_init.sh b/SOURCES/dracut_99microcode_ctl-fw_dir_override_module_init.sh
index 9839d36..854e278 100755
--- a/SOURCES/dracut_99microcode_ctl-fw_dir_override_module_init.sh
+++ b/SOURCES/dracut_99microcode_ctl-fw_dir_override_module_init.sh
@@ -48,29 +48,6 @@ install() {
 		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
 
@@ -92,57 +69,33 @@ install() {
 			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
-				# "true" is due to sporadic SIGPIPE from find
-				# when "grep -q" exits early.
-				{ find "$DATA_DIR/$i" -path "$DATA_DIR/$i/$p" \
-					-print0; true; } \
-				    | 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
+		match_model_opt=""
+		[ 1 = "$do_skip_host_only" ] || match_model_opt="-m"
 
-			[ 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
-			}
+		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"
diff --git a/SOURCES/gen_provides.sh b/SOURCES/gen_provides.sh
index c0c6b1d..5e2a2a4 100755
--- a/SOURCES/gen_provides.sh
+++ b/SOURCES/gen_provides.sh
@@ -21,31 +21,75 @@ for f in $(grep -E '/intel-ucode.*/[0-9a-f][0-9a-f]-[0-9a-f][0-9a-f]-[0-9a-f][0-
 	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
 
-		# 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))
+		# 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
 
diff --git a/SOURCES/intel_config b/SOURCES/intel_config
index d37878d..1f47b87 100644
--- a/SOURCES/intel_config
+++ b/SOURCES/intel_config
@@ -1,5 +1,5 @@
 path intel-ucode/*
-vendor_id GenuineIntel
+vendor GenuineIntel
 kernel_early 4.10.0
 kernel_early 3.10.0-930
 kernel_early 3.10.0-862.14.1
diff --git a/SPECS/microcode_ctl.spec b/SPECS/microcode_ctl.spec
index 66933e1..bf02db2 100644
--- a/SPECS/microcode_ctl.spec
+++ b/SPECS/microcode_ctl.spec
@@ -1,5 +1,4 @@
-%define intel_ucode_version 20191115
-%define intel_ucode_file_id 28727
+%define intel_ucode_version 20200602
 %global debug_package %{nil}
 
 %define caveat_dir %{_datarootdir}/microcode_ctl/ucode_with_caveats
@@ -13,11 +12,11 @@
 
 Summary:        CPU microcode updates for Intel x86 processors
 Name:           microcode_ctl
-Version:        %{intel_ucode_version}
-Release:        4%{?dist}
+Version:        20191115
+Release:        4.%{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
+URL:            https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files
 Source0:        https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/archive/microcode-%{intel_ucode_version}.tar.gz
 
 # (Pre-MDS) revision 0x714 of 06-2d-07 microcode
@@ -77,10 +76,13 @@ Source200:      gen_provides.sh
 
 ExclusiveArch:  %{ix86} x86_64
 BuildRequires:  systemd-units
-Requires(post): systemd
-Requires(preun): systemd
-Requires(postun): systemd
-Requires(posttrans): dracut
+# hexdump is used in gen_provides.sh
+BuildRequires:  coreutils util-linux
+Requires:       coreutils
+Requires(post): systemd coreutils
+Requires(preun): systemd coreutils
+Requires(postun): systemd coreutils
+Requires(posttrans): dracut coreutils
 
 %global _use_internal_dependency_generator 0
 %define __find_provides "%{SOURCE200}"
@@ -211,21 +213,121 @@ exit 0
 # 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
+# https://bugzilla.redhat.com/show_bug.cgi?id=1530400
+[ -d /run/systemd/system ] || exit 0
+
+# We can't simply update all initramfs images, since "dracut --regenerate-all"
+# generates initramfs even for removed kernels and if dracut generates botched
+# initramfs image, that results in unbootable system, even with older kernels
+# that can't be used as a fallback:
+# https://bugzilla.redhat.com/show_bug.cgi?id=1420180
+# https://access.redhat.com/support/cases/#/case/01779274
+# https://access.redhat.com/support/cases/#/case/01814106
 #
-# 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.
+# ...and we can't simply limit ourselves to updating only the currently
+# running kernel, as this doesn't work well with cases where kernel
+# is installed before the updated microcode, or in the same transaction.
+# And we can't rely on late update either, due to issues like this:
+# https://bugzilla.redhat.com/show_bug.cgi?id=1710445
 #
-# 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
+# ...and there are also issues with setups with increased "installonly_limit"
+# in /etc/yum.conf, which could lead to unacceptably long package installation
+# times.
+#
+# So, in the end, we try to grab no more than 2 most recently installed kernels
+# that are installed after the currently running one (with the currently running
+# kernel that makes up to 3 in total, the default "installonly_limit" value)
+# as a kernel package selection heuristic that tries to accomodate both the need
+# to put the latest microcode in freshly installed kernels and also addresses
+# existing concerns.
+#
+# For RPM selection, kernel flavours (like "debug" or "kdump" or "zfcp",
+# with only the former being relevant to x86 architecture) are a part or RPM
+# name; it's also a part of uname, with different separator used in RHEL 6/7
+# and RHEL 8.  RT kernel, however, is special, as "rt" is another part
+# of RPM name and it has its own versioning scheme both in NVR and uname.
+# And there's the kernel package split in RHEL 8, so one should look for *-core
+# and not the main package.
+pkgs="kernel-core kernel-debug-core kernel-rt-core kernel-rt-debug-core"
+qf='%%{NAME} %%{VERSION}-%%{RELEASE}.%%{ARCH} %%{installtime}\n'
+: "${MICROCODE_RPM_KVER_LIMIT=2}"
+
+rpm -qa --qf "${qf}" ${pkgs} | sort -r -n -k'3,3' | {
+	kver_cnt=0
+	processed=""
+	skipped=""
+	skip=0
+
+	while read -r pkgname vra install_ts; do
+		flavour=''
+
+		# For x86, only "debug" flavour exists in RHEL 8
+		[ "x${pkgname%*-debug-core}" = "x${pkgname}" ] \
+			|| flavour='+debug'
+
+		kver_cnt="$((kver_cnt + 1))"
+		kver_uname="${vra}${flavour}"
+
+		# Also check that the 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.
+		#
+		# XXX: Not sure if this check is still needed, since we now
+		# iterate over the rpm output.
+		[ -e "/lib/modules/${kver_uname}/symvers.gz" ] || continue
+		# Check that modules.dep for the kernel is present as well,
+		# otherwise dracut complains with "/lib/modules/.../modules.dep
+		# is missing. Did you run depmod?".
+		[ -e "/lib/modules/${kver_uname}/modules.dep" ] || continue
+
+		# We update the kernels with the same uname as the running kernel
+		# regardless of the selected limit
+		if [ "x$(uname -r)" = "x${kver_uname}" \
+		     -o \( "${kver_cnt}" -le "${MICROCODE_RPM_KVER_LIMIT}" \
+		           -a "${skip}" = 0 \) ]
+		then
+			dracut -f --kver "${kver_uname}"
+
+			processed="${processed} ${pkgname}-${vra}"
+		else
+			skipped="${skipped} ${pkgname}-${vra}"
+		fi
+
+		# The packages are processed until a package with the same uname
+		# as the running kernel is hit (since they are sorted
+		# in the descending installation time stamp older).
+		[ "x$(uname -r)" != "x${kver_uname}" ] || skip=1
+	done
+
+	if [ -n "${skipped}" ]; then
+		skip_msg="After installation of a new version of microcode_ctl package,
+initramfs hasn't been re-generated for all the installed kernel packages.
+The following kernel packages have been skipped:${skipped}.
+Please re-generate initramfs manually for these kernel packages with the
+\"dracut -f --kver KERNEL_VERSION\" command in order to get the latest
+Intel CPU microcode included into early initramfs image for it, if needed."
+
+		if [ -e /usr/bin/logger ]; then
+			echo "${skip_msg}" |
+				/usr/bin/logger -p syslog.notice -t microcode_ctl
+		fi
+
+		if [ -e /dev/kmsg ]; then
+			echo "${skip_msg}" > /dev/kmsg
+		fi
+	fi
+}
+
+exit 0
 
 %global rpm_state_dir %{_localstatedir}/lib/rpm-state
 
@@ -318,6 +420,68 @@ rm -rf %{buildroot}
 
 
 %changelog
+* Thu Jun 04 2020 Eugene Syromiatnikov <esyr@redhat.com> - 4:20191115-4.20200602.2
+- Avoid temporary file creation, used for here-documents in check_caveats.
+
+* Wed Jun 03 2020 Eugene Syromiatnikov <esyr@redhat.com> - 4:20191115-4.20200602.1
+- Update Intel CPU microcode to microcode-20200602 release, addresses
+  CVE-2020-0543, CVE-2020-0548, CVE-2020-0549 (#1827183):
+  - Update of 06-2d-06/0x6d (SNB-E/EN/EP C1/M0) microcode from revision 0x61f
+    up to 0x621;
+  - Update of 06-2d-07/0x6d (SNB-E/EN/EP C2/M1) microcode from revision 0x718
+    up to 0x71a;
+  - Update of 06-3c-03/0x32 (HSW C0) microcode from revision 0x27 up to 0x28;
+  - Update of 06-3d-04/0xc0 (BDW-U/Y E0/F0) microcode from revision 0x2e
+    up to 0x2f;
+  - Update of 06-45-01/0x72 (HSW-U C0/D0) microcode from revision 0x25
+    up to 0x26;
+  - Update of 06-46-01/0x32 (HSW-H C0) microcode from revision 0x1b up to 0x1c;
+  - Update of 06-47-01/0x22 (BDW-H/Xeon E3 E0/G0) microcode from revision 0x21
+    up to 0x22;
+  - Update of 06-4e-03/0xc0 (SKL-U/Y D0) microcode from revision 0xd6
+    up to 0xdc;
+  - Update of 06-55-03/0x97 (SKX-SP B1) microcode from revision 0x1000151
+    up to 0x1000157;
+  - Update of 06-55-04/0xb7 (SKX-SP H0/M0/U0, SKX-D M1) microcode
+    (in intel-06-55-04/intel-ucode/06-55-04) from revision 0x2000065
+    up to 0x2006906;
+  - Update of 06-55-06/0xbf (CLX-SP B0) microcode from revision 0x400002c
+    up to 0x4002f01;
+  - Update of 06-55-07/0xbf (CLX-SP B1) microcode from revision 0x500002c
+    up to 0x5002f01;
+  - Update of 06-5e-03/0x36 (SKL-H/S R0/N0) microcode from revision 0xd6
+    up to 0xdc;
+  - Update of 06-7e-05/0x80 (ICL-U/Y D1) microcode from revision 0x46
+    up to 0x78;
+  - Update of 06-8e-09/0x10 (AML-Y22 H0) microcode from revision 0xca
+    up to 0xd6;
+  - Update of 06-8e-09/0xc0 (KBL-U/Y H0) microcode from revision 0xca
+    up to 0xd6;
+  - Update of 06-8e-0a/0xc0 (CFL-U43e D0) microcode from revision 0xca
+    up to 0xd6;
+  - Update of 06-8e-0b/0xd0 (WHL-U W0) microcode from revision 0xca
+    up to 0xd6;
+  - Update of 06-8e-0c/0x94 (AML-Y42 V0, CML-Y42 V0, WHL-U V0) microcode
+    from revision 0xca up to 0xd6;
+  - Update of 06-9e-09/0x2a (KBL-G/H/S/X/Xeon E3 B0) microcode from revision
+    0xca up to 0xd6;
+  - Update of 06-9e-0a/0x22 (CFL-H/S/Xeon E3 U0) microcode from revision 0xca
+    up to 0xd6;
+  - Update of 06-9e-0b/0x02 (CFL-S B0) microcode from revision 0xca up to 0xd6;
+  - Update of 06-9e-0c/0x22 (CFL-H/S P0) microcode from revision 0xca
+    up to 0xd6;
+  - Update of 06-9e-0d/0x22 (CFL-H R0) microcode from revision 0xca up to 0xd6.
+- Change the URL to point to the GitHub repository since the microcode download
+  section at Intel Download Center does not exist anymore.
+
+* Wed Jun 03 2020 Eugene Syromiatnikov <esyr@redhat.com> - 4:20191115-4.20191115.6
+- Narrow down SKL-SP/W/X blacklist to exclude Server/FPGA/Fabric segment
+  models.
+
+* Wed Jun 03 2020 Eugene Syromiatnikov <esyr@redhat.com> - 4:20191115-4.20191115.5
+- Re-generate initramfs not only for the currently running kernel,
+  but for several recently installed kernels as well.
+
 * Mon Dec 09 2019 Eugene Syromiatnikov <esyr@redhat.com> - 4:20191115-4
 - Avoid find being SIGPIPE'd on early "grep -q" exit in the dracut script
   (#1781365).