Hello community,

here is the log from the commit of package iucode-tool for openSUSE:Factory 
checked in at 2018-02-02 22:23:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/iucode-tool (Old)
 and      /work/SRC/openSUSE:Factory/.iucode-tool.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "iucode-tool"

Fri Feb  2 22:23:17 2018 rev:6 rq:572024 version:2.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/iucode-tool/iucode-tool.changes  2017-10-27 
14:00:22.314960804 +0200
+++ /work/SRC/openSUSE:Factory/.iucode-tool.new/iucode-tool.changes     
2018-02-02 22:23:33.810286659 +0100
@@ -1,0 +2,19 @@
+Fri Feb  2 13:30:19 UTC 2018 - mplus...@suse.com
+
+- Update to version 2.3:
+  * Ready for release: v2.3
+  * update copyright dates to 2018
+  * iucode_tool(8): document changes to ucode filtering
+  * iucode_tool: support selecting by ucode revision
+  * iucode_tool: add function to parse signed 32-bit integers
+  * iucode_tool: optimize detection of base10 numeric names
+  * iucode_tool: better handle offline/non-continuous topology
+  * iucode_tool(8): document changes to --scan-system
+  * iucode_tool: select scan-system strategy change at runtime
+  * gitignore: rearrange, and ignore backup and vim swap files
+  * iucode_tool: move scan_system_processor() one layer down
+  * iucode_tool: do not scan-system while parsing
+  * iucode_tool: add two command-line parser helpers
+  * intel_microcode.h: document intel_ucode_status_t sources
+
+-------------------------------------------------------------------

Old:
----
  iucode-tool-2.2.tar.xz

New:
----
  iucode-tool-2.3.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ iucode-tool.spec ++++++
--- /var/tmp/diff_new_pack.fTM8KJ/_old  2018-02-02 22:23:34.802240354 +0100
+++ /var/tmp/diff_new_pack.fTM8KJ/_new  2018-02-02 22:23:34.806240168 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package iucode-tool
 #
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,12 +17,12 @@
 
 
 Name:           iucode-tool
-Version:        2.2
+Version:        2.3
 Release:        0
 Summary:        A program to manipulate Intel microcode update collections
 License:        GPL-2.0
 Group:          System/Boot
-Url:            https://gitlab.com/iucode-tool/iucode-tool
+URL:            https://gitlab.com/iucode-tool/iucode-tool
 Source:         %{name}-%{version}.tar.xz
 BuildRequires:  autoconf
 BuildRequires:  automake

++++++ _service ++++++
--- /var/tmp/diff_new_pack.fTM8KJ/_old  2018-02-02 22:23:34.834238861 +0100
+++ /var/tmp/diff_new_pack.fTM8KJ/_new  2018-02-02 22:23:34.834238861 +0100
@@ -4,8 +4,8 @@
     <param name="scm">git</param>
     <param name="changesgenerate">enable</param>
     <param name="filename">iucode-tool</param>
-    <param name="revision">refs/tags/v2.2</param>
-    <param name="version">2.2</param>
+    <param name="revision">refs/tags/v2.3</param>
+    <param name="version">2.3</param>
   </service>
   <service mode="disabled" name="recompress">
     <param name="file">*.tar</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.fTM8KJ/_old  2018-02-02 22:23:34.854237928 +0100
+++ /var/tmp/diff_new_pack.fTM8KJ/_new  2018-02-02 22:23:34.854237928 +0100
@@ -1,4 +1,4 @@
 <servicedata>
 <service name="tar_scm">
             <param 
name="url">https://gitlab.com/iucode-tool/iucode-tool.git</param>
-          <param 
name="changesrevision">3d05f5b913703893795fe04338285444b8e7ebe1</param></service></servicedata>
\ No newline at end of file
+          <param 
name="changesrevision">327f21f412183ef8f29e8b0c3c8c44d841c63fc9</param></service></servicedata>
\ No newline at end of file

++++++ iucode-tool-2.2.tar.xz -> iucode-tool-2.3.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iucode-tool-2.2/ChangeLog 
new/iucode-tool-2.3/ChangeLog
--- old/iucode-tool-2.2/ChangeLog       2017-08-28 16:40:04.000000000 +0200
+++ new/iucode-tool-2.3/ChangeLog       2018-01-28 16:00:44.000000000 +0100
@@ -1,3 +1,45 @@
+2018-01-28, iucode_tool v2.3
+
+  * iucode_tool(8): document changes to ucode filtering
+  * iucode_tool: support selecting by ucode revision
+    Add a third (and optional) parameter to microcode selection filters, to
+    select microcodes by revision.  The revision can be prefixed by the
+    operators eq: (equal to), lt: (less than), or gt: (greater than).
+    The revision numbering is signed, but in order to be more user friendly,
+    since we display revisions as unsigned values in hex, we accept the
+    range -INT32_MAX to +UINT32_MAX, and convert it to int32_t.
+  * iucode_tool: add function to parse signed 32-bit integers
+    Add parse_s32e(), based on parse_u32().  It will be used to parse
+    microcode revisions in the command line, so it has an extension
+    that accepts something like 0xfffffffe as an alias for -2.
+  * iucode_tool: optimize detection of base10 numeric names
+  * iucode_tool: better handle offline/non-continuous topology
+  * iucode_tool(8): document changes to --scan-system
+  * iucode_tool: select scan-system strategy change at runtime
+    Instead of selecting the scan-system strategy at compile time, enhance the
+    long-version of the --scan-system option to take an optional argument, and
+    select the strategy.  Available strategies are: 0 (auto), 1 (fast), and 2
+    (exact).  Fast uses just the cpuid instruction and activates all steppings.
+    Exact will query all processors using the kernel cpuid driver.  Auto (the
+    default) is currently the same as fast.  The short option -S is equivalent
+    to --scan-system=auto.  This way, we don't break backwards command line
+    behavior, and something like "iucode_tool -Sl" will still work.  In
+    --scan-system=exact mode, when a /dev/cpu/#/cpuid scan fails, it will use
+    the result from the cpuid instruction and also add every other stepping for
+    any signatures found before the failure.
+  * gitignore: rearrange, and ignore backup and vim swap files
+  * iucode_tool: move scan_system_processor() one layer down
+  * iucode_tool: do not scan-system while parsing
+    Instead of processing -s and -S/--scan-system while parsing, queue all
+    filters so that we can call scan_system_processors() later.  This was the
+    only complex operation that was being carried out while parsing the command
+    line.  This change ensures that global options such as -q and -v, that are
+    not supposed to be sensitive to their position in the command line, will
+    work as expected.
+  * iucode_tool: add two command-line parser helpers
+  * intel_microcode.h: document intel_ucode_status_t sources
+  * update copyright dates to 2018
+
 2017-08-28, iucode_tool v2.2
 
   * README: update for mixed dat and bin Intel releases
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iucode-tool-2.2/NEWS new/iucode-tool-2.3/NEWS
--- old/iucode-tool-2.2/NEWS    2017-08-28 16:40:04.000000000 +0200
+++ new/iucode-tool-2.3/NEWS    2018-01-28 16:00:44.000000000 +0100
@@ -1,3 +1,12 @@
+v2.3:
+  * Processor signature scan strategies can now be selected at
+    runtime, using a new optional argument of the --scan-system
+    option.  It is possible to disable the "exact" scan strategy
+    (which uses the kernel cpuid device) at build time to reduce the
+    impact on executable size.
+  * Microcode updates for a specific signature can now be optionally
+    selected based on their revision, not just processor flags mask.
+
 v2.2:
   * build infrastructure changes: autoconf 2.69 or later, and
     automake 1.13 or later are now required.  The configure script
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iucode-tool-2.2/README new/iucode-tool-2.3/README
--- old/iucode-tool-2.2/README  2017-08-28 16:40:04.000000000 +0200
+++ new/iucode-tool-2.3/README  2018-01-28 16:00:44.000000000 +0100
@@ -2,8 +2,8 @@
 
        iucode_tool - IntelĀ® 64 and IA-32 processor microcode tool
 
-                             Version 2.2
-                          August 28th, 2017
+                             Version 2.3
+                         January 28th,  2018
 
                     https://gitlab.com/iucode-tool
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iucode-tool-2.2/configure.ac 
new/iucode-tool-2.3/configure.ac
--- old/iucode-tool-2.2/configure.ac    2017-08-28 16:40:04.000000000 +0200
+++ new/iucode-tool-2.3/configure.ac    2018-01-28 16:00:44.000000000 +0100
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf 2.69+ to produce a configure script.
 dnl
-dnl Copyright (c) 2010-2017 Henrique de Moraes Holschuh
+dnl Copyright (c) 2010-2018 Henrique de Moraes Holschuh
 dnl
 dnl This program is free software; you can redistribute it and/or modify
 dnl it under the terms of the GNU General Public License as published by
@@ -17,11 +17,11 @@
 dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 AC_PREREQ([2.69])
-AC_INIT([iucode_tool], [2.2],
+AC_INIT([iucode_tool], [2.3],
         [https://gitlab.com/iucode-tool/iucode-tool/issues],
         [iucode-tool],
         [https://gitlab.com/iucode-tool/iucode-tool/wikis/home])
-AC_COPYRIGHT([Copyright (c) 2010-2017 Henrique de Moraes Holschuh])
+AC_COPYRIGHT([Copyright (c) 2010-2018 Henrique de Moraes Holschuh])
 
 AC_CONFIG_SRCDIR([iucode_tool.c])
 AC_CANONICAL_HOST
@@ -128,23 +128,32 @@
     [Path to the kernel microcode firmware directory])
 AC_SUBST(MICROCODE_DIR_DEFAULT)
 
+AC_ARG_WITH([cpuid-device-parent],
+    [AS_HELP_STRING([--with-cpuid-device-parent=PATH],
+          [per-cpu devices parent directory (/dev/cpu)])],
+    [AS_IF([test "x$withval" = "x" || test "x$withval" = "xno"],
+               [AC_ERROR([use --disable-cpuid-device instead of 
--without-cpuid-device-parent])],
+          [CPUID_DEVICE_PARENT="$withval"])],
+    [CPUID_DEVICE_PARENT="/dev/cpu"])
+AC_DEFINE_UNQUOTED(CPUID_DEVICE_PARENT, "$CPUID_DEVICE_PARENT",
+    [path to the per-cpu tree of cpuid devices])
+AC_SUBST(CPUID_DEVICE_PARENT)
 AC_ARG_WITH([cpuid-device-base],
     [AS_HELP_STRING([--with-cpuid-device-base=PATH_FORMAT],
-          [per-cpu cpuid device path (/dev/cpu/%u/cpuid)])],
+          [per-cpu cpuid device format string, relative to CPUID_DEVICE_PARENT 
(%s/cpuid)])],
     [AS_IF([test "x$withval" = "x" || test "x$withval" = "xno"],
                [AC_ERROR([use --disable-cpuid-device instead of 
--without-cpuid-device-base])],
           [CPUID_DEVICE_BASE="$withval"])],
-    [CPUID_DEVICE_BASE="/dev/cpu/%u/cpuid"])
+    [CPUID_DEVICE_BASE="%s/cpuid"])
 AC_DEFINE_UNQUOTED(CPUID_DEVICE_BASE, "$CPUID_DEVICE_BASE",
-    [fprintf base string to the per-cpu cpuid device])
+    [snprintf format string for the per-cpu cpuid device path, relative to 
CPUID_DEVICE_NAME])
 AC_SUBST(CPUID_DEVICE_BASE)
 
 AC_ARG_ENABLE([cpuid-device],
-    [AS_HELP_STRING([--enable-cpuid-device],
-       [use Linux cpuid device and check all cores])],
-    [AS_IF([test "x$enableval" != "xno"],
-               [AC_DEFINE(USE_CPUID_DEVICE, [], [Scan every core using Linux 
cpuid device])])
-    ])
+    [AS_HELP_STRING([--disable-cpuid-device],
+       [disable support for the Linux cpuid device (cripples 
--scan-system=exact)])])
+AS_IF([test "x${enable_cpuid_device}" != "xno"],
+    [AC_DEFINE(USE_CPUID_DEVICE, [], [Support scanning every core using Linux 
cpuid device])])
 
 AC_ARG_ENABLE([valgrind-build],
     [AS_HELP_STRING([--enable-valgrind-build],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iucode-tool-2.2/intel_microcode.c 
new/iucode-tool-2.3/intel_microcode.c
--- old/iucode-tool-2.2/intel_microcode.c       2017-08-28 16:40:04.000000000 
+0200
+++ new/iucode-tool-2.3/intel_microcode.c       2018-01-28 16:00:44.000000000 
+0100
@@ -3,7 +3,7 @@
  *
  *  Copyright (c) 2000-2006 Tigran Aivazian <tig...@aivazian.fsnet.co.uk>
  *                2006      Shaohua Li <shaohua...@intel.com>
- *                2010-2017 Henrique de Moraes Holschuh <h...@hmh.eng.br>
+ *                2010-2018 Henrique de Moraes Holschuh <h...@hmh.eng.br>
  *
  *  Based on Linux kernel Intel Microcode driver v2.6.36-rc3 (1.14)
  *  Based on Linux microcode.ctl version 1.17
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iucode-tool-2.2/intel_microcode.h 
new/iucode-tool-2.3/intel_microcode.h
--- old/iucode-tool-2.2/intel_microcode.h       2017-08-28 16:40:04.000000000 
+0200
+++ new/iucode-tool-2.3/intel_microcode.h       2018-01-28 16:00:44.000000000 
+0100
@@ -3,7 +3,7 @@
  *
  *  Copyright (c) 2000-2006 Tigran Aivazian <tig...@aivazian.fsnet.co.uk>
  *                2006      Shaohua Li <shaohua...@intel.com>
- *                2010-2017 Henrique de Moraes Holschuh <h...@hmh.eng.br>
+ *                2010-2018 Henrique de Moraes Holschuh <h...@hmh.eng.br>
  *
  *  Based on Linux kernel Intel Microcode driver v2.6.36-rc3 (1.14)
  *  Based on Linux microcode.ctl version 1.17
@@ -35,12 +35,14 @@
        INTEL_UCODE_BAD_PARAMETERS,
        INTEL_UCODE_INVALID_DATA,
        INTEL_UCODE_UNKNOWN_FORMAT,
-       INTEL_UCODE_COUNTEROVERFLOW,
+       /* only returned by intel_ucode_check_microcode() */
        INTEL_UCODE_BAD_EXTENDED_TABLE,
        INTEL_UCODE_BAD_EXTENDED_TABLE_CHECKSUM,
        INTEL_UCODE_BAD_EXTENDED_SIG_CHECKSUM,
        INTEL_UCODE_BAD_CHECKSUM,
+       /* only returned by the foreach functions */
        INTEL_UCODE_CALLBACK_ERROR,
+       INTEL_UCODE_COUNTEROVERFLOW,
 } intel_ucode_status_t;
 
 struct intel_ucode_metadata {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iucode-tool-2.2/iucode_tool.8.in 
new/iucode-tool-2.3/iucode_tool.8.in
--- old/iucode-tool-2.2/iucode_tool.8.in        2017-08-28 16:40:04.000000000 
+0200
+++ new/iucode-tool-2.3/iucode_tool.8.in        2018-01-28 16:00:44.000000000 
+0100
@@ -1,5 +1,5 @@
 .\"                              hey, Emacs:   -*- nroff -*-
-.\" Copyright (c) 2010-2017 Henrique de Moraes Holschuh <h...@hmh.eng.br>
+.\" Copyright (c) 2010-2018 Henrique de Moraes Holschuh <h...@hmh.eng.br>
 .\"
 .\" iucode_tool is free software; you can redistribute it and/or modify
 .\" it under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
 .\" along with this program; see the file COPYING.  If not, write to
 .\" the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 .\"
-.TH IUCODE_TOOL 8 "2016-11-10" "IUCODE_TOOL @VERSION@" "iucode_tool manual"
+.TH IUCODE_TOOL 8 "2018-01-28" "IUCODE_TOOL @VERSION@" "iucode_tool manual"
 .\" Please update the above date whenever this man page is modified.
 .\"
 .\" Some roff macros, for reference:
@@ -179,11 +179,20 @@
 
 
 .TP
-.BI "\-s ! | [!]" signature "[," pf_mask "]"
-Select microcodes by the specified \fIsignature\fP and \fIprocessor flags
-mask\fP (\fIpf_mask\fP).  If the \fIprocessor flags mask\fP is specified, it 
will
-select only microcodes that are suitable for at least one of the processor flag
-combinations present in the mask.
+.BI "\-s ! | [!]" signature "[,[" pf_mask "][,[" lt: "|" eq: "|" gt: "]" 
revision "]]"
+Select microcodes by the specified \fIsignature\fP, \fIprocessor flags mask\fP
+(\fIpf_mask\fP), and \fIrevision\fP.
+
+If the \fIprocessor flags mask\fP is specified, it will select only microcodes
+that are suitable for at least one of the processor flag combinations present
+in the mask.
+
+If the \fIrevision\fP is specified, optionally prefixed by one of the
+\(lq\fIeq:\fP\(rq, \(lq\fIlt:\fP\(rq or \(lq\fIgt:\fP\(rq operators, it will
+select only microcodes that have that same \fIrevision\fP (if no operator, or
+if the \(lq\fIeq:\fP\(rq operator is used), or microcodes that have a
+\fIrevision\fP that is less than (\(lq\fIlt:\fP\(rq operator), or greater than
+(\(lq\fIgt:\fP\(rq operator), the one specified.
 
 Specify more than once to select more microcodes.  This option can be combined
 with the \fI\-\-scan\-system\fP option to select more microcodes.  If
@@ -201,7 +210,7 @@
 the non\-negated form of \fI\-s\fP, or using \fI\-\-scan\-system\fP).
 
 .TP
-.BR "\-S" ", " "\-\-scan\-system"
+.BR "\-S" ", " "\-\-scan\-system" "[=\fImode\fP]"
 Select microcodes by scanning online processors on this system for their
 signatures.
 
@@ -210,10 +219,26 @@
 \fI\-\-scan\-system\fP can also be deselected by a later \fI\-s\ !signature\fP
 option.
 
-Should the signature scan fail, the program will print a warning to the user
-and continue as if \fI\-\-scan\-system\fP had not been specified.  This is a
-fail-safe condition when \fBiucode_tool\fP is used to install microcode updates
-for the next boot.
+The optional \fImode\fP argument (accepted only by the long version of the
+option) selects the strategy used to scan processors:
+.RS
+.IP "\fB0\fP or \fBauto\fP"
+Currently the same as \fBfast\fP, but this might change in future versions if
+Intel ever deploys multi-signature systems that go beyond mixed-stepping.  This
+is the default mode of operation, for backwards compatibility
+with previous versions of \fBiucode_tool\fP.
+.IP "\fB1\fP or \fBfast\fP"
+Uses the cpuid instruction to detect the signature of the processor
+\fBiucode_tool\fP is running on, and selects all steppings for that processor's
+type, family and model.  Supports mixed-stepping systems.
+.IP "\fB2\fP or \fBexact\fP"
+Uses kernel drivers to scan the signature of every online processor directly.
+This mode supports multi-signature systems.  This scan mode will be slow on
+large systems with many processors, and likely requires special permissions
+(such as running as the root user).  Should the scan fail for any reason, as
+a fail-safe measure, it will issue an warning and consider all possible
+steppings for every signature it did manage to scan successfully.
+.RE
 
 .TP
 \fB\-\-date\-before\fR=\fIYYYY\-MM\-DD\fR and 
\fB\-\-date\-after\fR=\fIYYYY\-MM\-DD\fR
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iucode-tool-2.2/iucode_tool.c 
new/iucode-tool-2.3/iucode_tool.c
--- old/iucode-tool-2.2/iucode_tool.c   2017-08-28 16:40:04.000000000 +0200
+++ new/iucode-tool-2.3/iucode_tool.c   2018-01-28 16:00:44.000000000 +0100
@@ -1,7 +1,7 @@
 /*
  * iucode_tool - Manipulates Intel(R) IA32/x86_64 processor microcode bundles
  *
- * Copyright (c) 2010-2017 Henrique de Moraes Holschuh <h...@hmh.eng.br>
+ * Copyright (c) 2010-2018 Henrique de Moraes Holschuh <h...@hmh.eng.br>
  *               2000 Simon Trimmer, Tigran Aivazian
  *
  * Some code copied from microcode.ctl v1.17.
@@ -177,12 +177,33 @@
 static struct microcode_iterator_data microcode_iterator_data;
 
 /* Filter masks */
+#define IUCODE_FILTERMASK_SCANCPUS 0xffffffffU
+
+enum iuc_rev_match_mode {
+       IUCODE_REVFLT_ANY = 0,  /* Ignore revision on match */
+       IUCODE_REVFLT_EQ,       /* Revision must be = filter's rev */
+       IUCODE_REVFLT_LT,       /* Revision must be < filter's rev */
+       IUCODE_REVFLT_GT,       /* Revision must be > filter's rev */
+
+       IUCODE_REVFLT_SIZE      /* EOL */
+};
+static const char * const iuc_rev_match_mode_s[IUCODE_REVFLT_SIZE] = {
+       [IUCODE_REVFLT_ANY] = NULL,
+       [IUCODE_REVFLT_EQ] = "eq:",
+       [IUCODE_REVFLT_LT] = "lt:",
+       [IUCODE_REVFLT_GT] = "gt:",
+}; /* keep this in sync with enum iuc_rev_match_mode !! */
+
 struct microcode_filter_entry {
        struct microcode_filter_entry *next;
        uint32_t cpuid;         /* exact match */
        uint32_t pfm;           /* common bits set match */
-       int invert;
+       int32_t  rev;
+       enum iuc_rev_match_mode rev_match;
+       int      invert;
 };
+static struct microcode_filter_entry *uc_filter_queue = NULL;
+static struct microcode_filter_entry *uc_filter_queue_tail = NULL;
 static struct microcode_filter_entry *uc_filter_list = NULL;
 static int filter_list_allow = 1;
 
@@ -247,6 +268,31 @@
        return 0;
 }
 
+static int parse_s32e(const char *nptr, char **endptr, int base,
+                     int32_t * const res)
+{
+       long int l;
+
+       assert(nptr);
+       assert(endptr);
+       assert(res);
+
+       errno = 0;
+       l = strtol(nptr, endptr, base);
+       if (errno || nptr == *endptr)
+               return errno ? errno : EINVAL;
+       if (l > UINT32_MAX || l < INT32_MIN)
+               return ERANGE;
+
+       /*
+        * Accept UINT32_MAX >= x > INT32_MAX, as if it were
+        * the binary representation of int32_t read as uint32_t
+        */
+       *res = (int32_t)(l & UINT32_MAX);
+
+       return 0;
+}
+
 static int is_valid_fd(const int fd)
 {
        return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
@@ -1898,7 +1944,6 @@
        return !!((d > datefilter_min) && (d < datefilter_max));
 }
 
-static void free_filter_list(struct microcode_filter_entry *f) 
__attribute__((unused));
 static void free_filter_list(struct microcode_filter_entry *f)
 {
        static struct microcode_filter_entry *p;
@@ -1910,9 +1955,15 @@
        }
 }
 
-static void xx_merge_filter(struct microcode_filter_entry * const f,
-                        const uint32_t pf_mask, const int invert)
-{
+static int xx_merge_filter(struct microcode_filter_entry * const f,
+                        const uint32_t pf_mask, const int32_t rev,
+                        const enum iuc_rev_match_mode rev_match,
+                        const int invert)
+{
+       /* FIXME: we could do better, sometimes it is possible to merge */
+       if (f->rev_match != rev_match || f->rev != rev)
+               return 0; /* can't merge */
+
        if (f->invert == invert) {
                f->pfm |= pf_mask;
        } else if (!(f->invert)) {
@@ -1921,15 +1972,21 @@
                f->invert = 0;
                f->pfm = pf_mask;
        }
+
+       return 1; /* merged */
 }
 
-static int add_filter_to_list(uint32_t cpuid, uint32_t pf_mask, int invert,
-                               struct microcode_filter_entry ** const base)
+static int add_filter_to_list(uint32_t cpuid, uint32_t pf_mask, int32_t rev,
+                             enum iuc_rev_match_mode rev_match, int invert,
+                             struct microcode_filter_entry ** const base)
 {
        struct microcode_filter_entry **pnext, *n;
 
        assert(base);
 
+       if (!cpuid || cpuid == IUCODE_FILTERMASK_SCANCPUS)
+               return EINVAL;
+
        if (!pf_mask)
                pf_mask = PFMASK_MATCH_ANY;
 
@@ -1940,13 +1997,16 @@
 
        if (*pnext && (*pnext)->cpuid == cpuid) {
                if (((pf_mask & (*pnext)->pfm) == pf_mask) &&
-                    ((*pnext)->invert == invert)) {
+                   (*pnext)->rev_match == rev_match &&
+                   (*pnext)->rev == rev &&
+                   (*pnext)->invert == invert) {
                        /* found equivalent, report it */
                        return EEXIST;
                }
 
-               xx_merge_filter(*pnext, pf_mask, invert);
-               return 0;
+               /* merge when possible */
+               if (xx_merge_filter(*pnext, pf_mask, rev, rev_match, invert))
+                       return 0;
        }
 
        /* insert before */
@@ -1955,6 +2015,8 @@
                return ENOMEM;
        n->cpuid = cpuid;
        n->pfm = pf_mask;
+       n->rev = rev;
+       n->rev_match = rev_match;
        n->invert = invert;
        n->next = *pnext;
        *pnext = n;
@@ -1982,34 +2044,51 @@
                while (*pp && (*pp)->cpuid < e->cpuid)
                        pp = &((*pp)->next);
 
-               if (*pp && (*pp)->cpuid == e->cpuid) {
-                       xx_merge_filter(*pp, e->pfm, e->invert);
-               } else {
+               if (!*pp || (*pp)->cpuid != e->cpuid ||
+                   !xx_merge_filter(*pp, e->pfm, e->rev, e->rev_match, 
e->invert)) {
                        /* insert before */
                        e->next = *pp;
                        *pp = e;
                        e = NULL;
                }
-               if (e)
-                       free(e);
+               free(e);
+       }
+}
+
+static int xx_compare_rev(const int32_t rev,
+                         const struct microcode_filter_entry *f)
+{
+       const enum iuc_rev_match_mode op = f->rev_match;
+
+       if ((op == IUCODE_REVFLT_ANY) ||
+           (op == IUCODE_REVFLT_EQ && rev == f->rev) ||
+           (op == IUCODE_REVFLT_LT && rev < f->rev)  ||
+           (op == IUCODE_REVFLT_GT && rev > f->rev)) {
+               return !(f->invert);
        }
+
+       return -1;
 }
 
 /* returns non-zero if selected */
 static int is_selected(const uint32_t cpuid,
                       const uint32_t pf_mask,
+                      const int32_t rev,
                       const struct microcode_filter_entry *f)
 {
+       int state = -1;
+
        while (f && f->cpuid < cpuid)
                f = f->next;
-       while (f && f->cpuid == cpuid) {
+       while (f && f->cpuid == cpuid && state < 0) {
                if ((pf_mask & f->pfm) != 0 ||
-                   f->pfm == PFMASK_MATCH_ANY)
-                       return !(f->invert);
+                   f->pfm == PFMASK_MATCH_ANY) {
+                       state = xx_compare_rev(rev, f);
+               }
                f = f->next;
        }
 
-       return filter_list_allow;
+       return (state >= 0)? state : filter_list_allow;
 }
 
 /* Microcode extended signature deduplication */
@@ -2230,7 +2309,7 @@
                        INTEL_UCLE_HASXST;
                extsig_tables_in_use = 1;
        }
-       if (is_selected(cpuid, pf_mask, uc_filter_list))
+       if (is_selected(cpuid, pf_mask, m.revision, uc_filter_list))
                uce_flags |= (is_in_date_range(&m)) ?
                                INTEL_UCLE_SELECT : INTEL_UCLE_SELID;
 
@@ -2640,7 +2719,7 @@
                 * Get main processor signature from cpuid(1) EAX
                 * and add it as a filter.
                 */
-               switch (add_filter_to_list(sig, 0, 0, ucfp)) {
+               switch (add_filter_to_list(sig, 0, 0, IUCODE_REVFLT_ANY, 0, 
ucfp)) {
                case ENOMEM:
                        print_err("out of memory");
                        return ENOMEM;
@@ -2656,8 +2735,22 @@
 }
 
 #ifdef USE_CPUID_DEVICE
-static int check_cpuid_devs(__attribute__((unused)) const uint32_t sig,
-                           struct microcode_filter_entry ** const ucfp)
+static int is_base10_number(const char *s)
+{
+       if (!s || !*s)
+               return 0;
+
+       while(*s) {
+               if (*s < '0' || *s > '9')
+                       return 0;
+               s++;
+       }
+
+       return 1;
+}
+
+/* requires a kernel driver, and *really* hurts on very large systems */
+static int xx_check_cpuid_devs(struct microcode_filter_entry ** const ucfp)
 {
        uint32_t cpuid_buf[8];  /* two cpuid levels */
        char cpuid_device[PATH_MAX];
@@ -2665,27 +2758,57 @@
        int rc = 0;
        unsigned int i = 0;
        unsigned int ncpu = 0;
+       struct dirent *d;
+
+       DIR *cpudir = opendir(CPUID_DEVICE_PARENT);
+       if (!cpudir) {
+               int en = errno;
+               print_err("%s: could not open directory: %s", 
CPUID_DEVICE_PARENT, strerror(en));
+               return -1;
+       }
 
        while (1) {
+               errno = 0;
+               d = readdir(cpudir);
+               if (!d) {
+                       int err = errno;
+                       if (unlikely(err)) {
+                               print_err("%s: cannot walk directory: %s",
+                                         CPUID_DEVICE_PARENT, strerror(err));
+                               rc = -1; /* note that we skipped processors due 
to unexpected errors */
+                       }
+                       break; /* finish/abort walk */
+               }
+
+               /* Linux procfs supports d_type */
+               if (d->d_type != DT_DIR)
+                       continue; /* next dentry */
+
+               /* must be [0-9]+, no trailling weirdness */
+               if (!is_base10_number(d->d_name))
+                       continue; /* next dentry */
+
                snprintf(cpuid_device, sizeof(cpuid_device),
-                        CPUID_DEVICE_BASE, i);
-               cpuid_fd = open(cpuid_device, O_RDONLY);
+                        CPUID_DEVICE_BASE, d->d_name);
+
+               errno = EINTR;
+               cpuid_fd = -1;
+               while (cpuid_fd == -1 && errno == EINTR)
+                       cpuid_fd = openat(dirfd(cpudir), cpuid_device, O_RDONLY 
| O_CLOEXEC);
                if (cpuid_fd == -1) {
                        int en = errno;
 
-                       print_msg(4, "%s: returned error status on open(): %s",
-                                 cpuid_device, strerror(en));
+                       print_msg(4, "%s/%s: returned error status on open(): 
%s",
+                                 CPUID_DEVICE_PARENT, cpuid_device, 
strerror(en));
 
-                       if (en == EINTR)
-                               continue; /* try again */
                        if (en == ENOENT)
                                break;    /* cpuid device inode not found */
                        if (en == ENXIO || en == EIO) {
                                /* Linux cpuid driver: ENXIO: offline; EIO: no 
cpuid support */
                                print_msg(2, "processor %u is offline or has no 
cpuid support", i);
                        } else {
-                               print_msg(2, "%s: cannot open cpuid device 
node: %s",
-                                       cpuid_device, strerror(en));
+                               print_msg(2, "%s/%s: cannot open cpuid device 
node: %s",
+                                       CPUID_DEVICE_PARENT, cpuid_device, 
strerror(en));
                                rc = -1; /* note that we skipped processors due 
to unexpected errors */
                        }
 
@@ -2694,13 +2817,14 @@
                        continue;
                }
 
-               print_msg(3, "trying to get CPUID information from %s",
-                         cpuid_device);
+               print_msg(3, "trying to get CPUID information from %s/%s",
+                         CPUID_DEVICE_PARENT, cpuid_device);
                if (read(cpuid_fd, &cpuid_buf, sizeof(cpuid_buf)) == -1) {
-                       print_err("%s: access to CPUID(0) and CPUID(1) failed: 
%s",
-                                 cpuid_device, strerror(errno));
+                       print_err("%s/%s: access to CPUID(0) and CPUID(1) 
failed: %s",
+                                 CPUID_DEVICE_PARENT, cpuid_device, 
strerror(errno));
                        /* this is in the should not happen list, so abort */
                        close(cpuid_fd);
+                       closedir(cpudir);
                        return 1;
                }
 
@@ -2716,6 +2840,8 @@
                i++;
        };
 
+       closedir(cpudir);
+
        if (i == 0 && ncpu == 0) {
                print_err("cpuid kernel driver unavailable");
                return -1;
@@ -2732,16 +2858,22 @@
        return rc;
 }
 #else
+static int xx_check_cpuid_devs(__attribute__((unused)) struct 
microcode_filter_entry ** const ucfp)
+{
+       print_msg(1, "support for exact system scan disabled at compile time");
+       return -1;
+}
+#endif /* USE_CPUID_DEVICE */
 
-/* this hurts a lot less on very big systems... */
-static int check_cpuid_devs(uint32_t sig, struct microcode_filter_entry ** 
const ucfp)
+
+/* xx_add_all_steppings(cpuid) hurts a lot less on very big systems... */
+static int xx_add_all_steppings(uint32_t sig, struct microcode_filter_entry ** 
const ucfp)
 {
        unsigned int i;
 
-       print_msg(2, "assuming all processors have the same type, family and 
model");
        sig |= 0xf;
        for (i = 0; i < 0x10; i++) {
-               if (add_filter_to_list(sig, 0, 0, ucfp) == ENOMEM) {
+               if (add_filter_to_list(sig, 0, 0, IUCODE_REVFLT_ANY, 0, ucfp) 
== ENOMEM) {
                        print_err("out of memory");
                        return ENOMEM;
                }
@@ -2749,14 +2881,46 @@
        }
        return 0;
 }
-#endif
 
-static int scan_system_processors(void)
+/* Handle mixed-signature systems, even if Intel still hasn't admited that
+ * they will exist in the SDM, the writing is already out in the wall */
+static int xx_add_all_steppings_for_every_sig(uint32_t sig, struct 
microcode_filter_entry ** const ucfp)
+{
+       struct microcode_filter_entry *fl = NULL;
+       struct microcode_filter_entry *p;
+       int rc;
+
+       /* failsafe of the failsafe: add running processor sig */
+       rc = xx_add_all_steppings(sig, &fl);
+
+       /* creating a new list is just plain safer in the long run */
+       p = *ucfp;
+       while (p && !rc) {
+               /* handle mixed sig systems, unlikely as that might be */
+               if (p->cpuid != sig)
+                       rc = xx_add_all_steppings(p->cpuid, &fl);
+               p = p->next;
+       }
+
+       if (!rc) {
+               free_filter_list(*ucfp);
+               *ucfp = fl;
+       } else {
+               free_filter_list(fl);
+       }
+
+       return rc;
+}
+
+static int scan_system_processors(unsigned int strategy,
+                                 struct microcode_filter_entry ** const 
filter_list)
 {
        uint32_t id0, id1, id2, id3, sig, idx;
        struct microcode_filter_entry *uc_cpu = NULL;
        int rc = 0;
 
+       assert(filter_list);
+
        print_msg(3, "trying to get CPUID information directly");
        if (!(__get_cpuid(0, &id0, &id1, &id2, &id3) &&
              __get_cpuid(1, &sig, &idx, &idx, &idx))) {
@@ -2775,7 +2939,15 @@
 
        switch (xx_scan_handle_sig(id1, id2, id3, sig, &uc_cpu)) {
        case 0:
-               rc = check_cpuid_devs(sig, &uc_cpu);
+               if (strategy == 2) {
+                       if (xx_check_cpuid_devs(&uc_cpu)) {
+                               print_warn("exact cpuid signature scan failed, 
switching to failsafe strategy");
+                               rc = xx_add_all_steppings_for_every_sig(sig, 
&uc_cpu);
+                       }
+               } else {
+                       print_msg(2, "assuming all processors have the same 
type, family and model");
+                       rc = xx_add_all_steppings(sig, &uc_cpu);
+               }
                break;
        case ENXIO:
                print_msg(1, "running on a non-Intel processor");
@@ -2792,18 +2964,81 @@
 
        if (uc_cpu) {
                /* tie linked lists */
-               add_filter_list_to_list(&uc_filter_list, uc_cpu);
+               add_filter_list_to_list(filter_list, uc_cpu);
                uc_cpu = NULL;
        }
 
        return (rc > 0) ? rc : 0;
 }
 
+static int cmdline_queue_ucode_filter(uint32_t cpuid, uint32_t pf_mask,
+                                     int32_t rev, enum iuc_rev_match_mode 
rev_match,
+                                     int invert)
+{
+       struct microcode_filter_entry *n;
+
+       n = malloc(sizeof(struct microcode_filter_entry));
+       if (!n)
+               return ENOMEM;
+       n->cpuid = cpuid;
+       n->pfm = pf_mask;
+       n->rev = rev;
+       n->rev_match = rev_match;
+       n->invert = invert;
+       n->next = NULL;
+
+       if (uc_filter_queue_tail) {
+               uc_filter_queue_tail->next = n;
+       } else {
+               uc_filter_queue = n;
+       }
+
+       uc_filter_queue_tail = n;
+
+       return 0;
+}
+
+static int process_ucode_filter_queue(void)
+{
+       struct microcode_filter_entry *p = uc_filter_queue;
+       int rc = 0;
+
+       while(p && !rc) {
+               if (p->cpuid != IUCODE_FILTERMASK_SCANCPUS) {
+                       rc = add_filter_to_list(p->cpuid, p->pfm, p->rev, 
p->rev_match, p->invert, &uc_filter_list);
+                       if (rc == EEXIST)
+                               rc = 0;
+               } else {
+                       rc = scan_system_processors(p->pfm, &uc_filter_list);
+               }
+
+               p = p->next;
+       }
+
+       uc_filter_queue_tail = NULL;
+       free_filter_list(uc_filter_queue);
+       uc_filter_queue = NULL;
+
+       switch(rc) {
+       case 0:
+               return 0;
+
+       case ENOMEM:
+               print_err("Cannot add filter entry: out of memory");
+               break;
+       case EINVAL:
+               print_err("Internal error while processing filter list");
+               break;
+       }
+
+       return 1;
+}
+
 /* Command line processing */
 
 static const char program_version[] =
        PROGNAME " " VERSION "\n"
-       "Copyright (c) 2010-2017 by Henrique de Moraes Holschuh\n\n"
+       "Copyright (c) 2010-2018 by Henrique de Moraes Holschuh\n\n"
 
        "Based on code from the Linux microcode_intel driver and from\n"
        "the microcode.ctl package, copyright (c) 2000 by Simon Trimmer\n"
@@ -2851,6 +3086,7 @@
        IUCODE_ARGP_DATEAFTER,
        IUCODE_ARGP_DATEFSTRICT,
        IUCODE_ARGP_DATEFLOOSE,
+       IUCODE_ARGP_SCANSYSTEMOPT,
        IUCODE_ARGP_EIRFS,
        IUCODE_ARGP_MINSIZE_EIRFS,
        IUCODE_ARGP_DFLSIZE_EIRFS,
@@ -2870,19 +3106,29 @@
           "selected by filename suffix)",
          10 },
 
-       { NULL, 's', "! | [!]signature[,pf_mask]", 0,
-          "Select microcodes by the specified signature and processor "
-          "flags mask (pf_mask).  Specify more than once to select/unselect "
-          "more microcodes.  Prefix with ! to unselect microcodes.  "
+       { NULL, 's', "! | [!]signature[,[pf_mask][,[lt:|eq:|gt:]revision]]", 0,
+          "Select microcodes by the specified signature, processor "
+          "flags mask (pf_mask), and revision.  Optionally, prefix revision "
+          "with eq: (equal -- implied there is no prefix), lt: (less than) "
+          "or gt: (greater than).  "
+          "Specify more than once to select/unselect more microcodes.  "
+          "Prefix with ! to unselect microcodes.  "
           "Use -s ! to disable the default behavior of selecting all "
           "microcodes when no -s or -S filter is specified",
          20 },
-       { "scan-system", 'S', NULL, 0,
+       { NULL, 'S', NULL, 0,
+          "Same as --scan-system=auto",
+         21 },
+       { "scan-system", IUCODE_ARGP_SCANSYSTEMOPT, "mode", OPTION_ARG_OPTIONAL,
           "Select microcodes based on the running system processor(s).  "
           "Can be combined with the -s option, and can be used only once.  "
           "Microcodes selected by --scan-system can be unselected by a "
-          "later -s !<signature> option",
-         20 },
+          "later -s !<signature> option.  The optional mode argument "
+          "selects the strategy: 0 or auto (default); 1 or fast (good for "
+          "most systems, including mixed-stepping); and 2 or exact (slow, "
+          "supports multi-signature systems, requires the cpuid kernel "
+          "driver and might require root access)",
+         22 },
 
        { "downgrade", IUCODE_ARGP_DOWNGRADE, NULL, 0,
           "Instead of discarding microcodes based on revision level, "
@@ -2976,6 +3222,8 @@
 };
 static const char cmdline_nonarg_doc[] = "[[-t<type>] filename] ...";
 
+static const char * const cmdline_scan_system_tbl[] = { "auto", "fast", 
"exact", NULL };
+
 static int new_filename(const char * const fn,
                        const intel_ucode_file_type_t ftype)
 {
@@ -3022,15 +3270,17 @@
        input_files = NULL;
 }
 
-/* -s ! | [!]cpuid[,pf_mask] */
-static int add_ucode_filter(const char *arg)
+/* -s ! | [!]cpuid[,[pf_mask][,[<revmatch_operator>]rev]] */
+static int cmdline_parse_ucode_filter(const char *arg)
 {
        char *p;
        uint32_t acpuid, amask;
-       int invert;
+       int32_t arev;
+       int invert, arev_match;
 
        amask = 0;
        invert = 0;
+       arev = 0;
 
        while (isspace(*arg))
                arg++;
@@ -3051,28 +3301,65 @@
                }
        }
 
+       /* cpuid, mandatory */
        if (!*arg || parse_u32(arg, &p, 0, &acpuid))
                return EINVAL;
        while (isspace(*p))
                p++;
 
+       /* pf_mask, optional */
        if (*p == ',') {
                p++;
+               if (*p != ',') {
+                       arg = p;
+                       if (!*arg || parse_u32(arg, &p, 0, &amask))
+                               return EINVAL;
+               } /* else amask = MATCH_ANY */
+               while (isspace(*p))
+                       p++;
+       } else if (*p) {
+               return EINVAL;
+       }
+
+       /* rev, optional */
+       if (*p == ',') {
+               p++;
+               while (isspace(*p))
+                       p++;
+               if (!*p)
+                       return EINVAL;
+
+               /* revison match operator, optional */
+               int i = 0;
+               while (i < IUCODE_REVFLT_SIZE &&
+                      (!iuc_rev_match_mode_s[i] ||
+                       strncasecmp(p, iuc_rev_match_mode_s[i],
+                                   strlen(iuc_rev_match_mode_s[i]))))
+                       i++;
+               if (i < IUCODE_REVFLT_SIZE) {
+                       arev_match = i;
+                       p += strlen(iuc_rev_match_mode_s[i]);
+               } else {
+                       arev_match = IUCODE_REVFLT_EQ;
+               }
+
+               /* revision */
                arg = p;
-               if (!*arg || parse_u32(arg, &p, 0, &amask))
+               if (!*arg || parse_s32e(arg, &p, 0, &arev))
                        return EINVAL;
                while (isspace(*p))
                        p++;
-               if (*p)
-                       return EINVAL;
-       } else if (*p) {
+       } else {
+               arev_match = IUCODE_REVFLT_ANY;
+       }
+       if (*p) {
                return EINVAL;
        }
 
        if (!invert)
                filter_list_allow = 0;
 
-       return add_filter_to_list(acpuid, amask, invert, &uc_filter_list);
+       return cmdline_queue_ucode_filter(acpuid, amask, arev, arev_match, 
invert);
 }
 
 /* YYYY-MM-DD */
@@ -3114,6 +3401,55 @@
        return 0;
 }
 
+static int cmdline_get_int(const char *arg, int pmin, int pmax, int *d)
+{
+       char *p;
+       long int l;
+
+       if (!arg)
+               return 0;
+
+       errno = 0;
+       l = strtol(arg, &p, 10);
+       if (errno || p == arg)
+               return errno ? errno : EINVAL;
+       if (l > INT32_MAX || l < INT32_MIN)
+               return ERANGE;
+       if (l < pmin || l > pmax)
+               return EINVAL;
+
+       while (isspace(*p))
+               p++;
+       if (*p)
+               return EINVAL;
+
+       if (d)
+               *d = (int) l;
+
+       return 0;
+}
+
+/* note: does not tolerate trailing blanks */
+static int cmdline_get_enumstr(const char *arg, const char * const table[],
+                              int *d)
+{
+       int r = 0;
+
+       if (!arg || !table)
+               return 0;
+
+       while (table[r]) {
+               if (!strcasecmp(arg, table[r])) {
+                       if (d)
+                               *d = r;
+                       return 0;
+               }
+               r++;
+       }
+
+       return ENOENT;
+}
+
 static error_t cmdline_do_parse_arg(int key, char *arg,
                                    struct argp_state *state)
 {
@@ -3237,29 +3573,61 @@
                break;
 
        case 's':
-               rc = add_ucode_filter(arg);
+               rc = cmdline_parse_ucode_filter(arg);
                switch (rc) {
                case 0:
-               case EEXIST:
                        break; /* success */
                case EINVAL:
                        argp_error(state, "invalid filter: '%s'", arg);
                        break; /* not reached */
                default:
                        argp_failure(state, EXIT_SWFAILURE, rc,
-                                    "could not add filter '%s'", arg);
+                                    "could not queue filter '%s'", arg);
                }
                command_line_actions |= IUCODE_F_UCSELECT;
                break;
+
        case 'S':
+               /*
+                * -S and --scan-system cannot be handled the same way
+                * because -S cannot be made OPTION_ARG_OPTIONAL: it would
+                * break command-line backwards compatibility when people
+                * specify several short options together and -S is not the
+                * last option in the chain
+                */
+               if (command_line_actions & IUCODE_DO_SELPROC)
+                       argp_error(state,
+                                  "--scan-system option can be specified only 
once");
+               /*
+                * note: the pfm field of the queue filter item is used to
+                * encode the scan-system strategy.
+                */
+               rc = cmdline_queue_ucode_filter(IUCODE_FILTERMASK_SCANCPUS, 0, 
0, 0, 0);
+               if (rc)
+                       argp_failure(state, EXIT_SWFAILURE, rc,
+                                    "could not queue --scan-system action");
+               command_line_actions |= IUCODE_DO_SELPROC | IUCODE_F_UCSELECT;
+               break;
+       case IUCODE_ARGP_SCANSYSTEMOPT:
                if (command_line_actions & IUCODE_DO_SELPROC)
                        argp_error(state,
                                   "--scan-system option can be specified only 
once");
 
-               if (scan_system_processors()) {
-                       argp_failure(state, EXIT_SWFAILURE, 0,
-                               "fatal failure while scanning for system 
processors");
-               }
+               int scan_system_strategy = 0;
+               if (cmdline_get_int(arg, 0, 2, &scan_system_strategy) &&
+                   cmdline_get_enumstr(arg, cmdline_scan_system_tbl, 
&scan_system_strategy))
+                       argp_error(state, "invalid --scan-system mode: '%s'", 
arg);
+
+               /*
+                * note: the pfm field of the queue filter item is used to
+                * encode the scan-system strategy.
+                */
+               rc = cmdline_queue_ucode_filter(IUCODE_FILTERMASK_SCANCPUS,
+                                               (uint32_t)scan_system_strategy,
+                                               0, 0, 0);
+               if (rc)
+                       argp_failure(state, EXIT_SWFAILURE, rc,
+                                    "could not queue --scan-system action");
                command_line_actions |= IUCODE_DO_SELPROC | IUCODE_F_UCSELECT;
                break;
 
@@ -3335,6 +3703,11 @@
                goto do_nothing;
        }
 
+       if (process_ucode_filter_queue()) {
+               rc = EXIT_SWFAILURE;
+               goto err_exit;
+       }
+
        if (command_line_actions & IUCODE_DO_LOADFILE) {
                struct filename_list *fn = input_files;
                while (fn && next_bundle_id) {


Reply via email to