Add an option to xen-ucode tool to print the currently loaded ucode
version and also print it during usage info.  Print CPU signature and
processor flags as well.  The raw data comes from cpuinfo directory in
xenhypfs and from XENPF_get_cpu_version platform op.

Example output:
    Intel:
    Current CPU signature is: 06-55-04 (raw 0x50654)
    Current CPU microcode revision is: 0x2006e05
    Current CPU processor flags are: 0x1

    AMD:
    Current CPU signature is: fam19h (raw 0xa00f11)
    Current CPU microcode revision is: 0xa0011a8

Signed-off-by: Sergey Dyasli <sergey.dya...@citrix.com>
---
 tools/misc/Makefile    |  2 +-
 tools/misc/xen-ucode.c | 97 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/tools/misc/Makefile b/tools/misc/Makefile
index 1c6e1d6a04..e345ac76db 100644
--- a/tools/misc/Makefile
+++ b/tools/misc/Makefile
@@ -136,6 +136,6 @@ xencov: xencov.o
        $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
 
 xen-ucode: xen-ucode.o
-       $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
+       $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(LDLIBS_libxenhypfs) 
$(APPEND_LDFLAGS)
 
 -include $(DEPS_INCLUDE)
diff --git a/tools/misc/xen-ucode.c b/tools/misc/xen-ucode.c
index ad32face2b..7e657689f4 100644
--- a/tools/misc/xen-ucode.c
+++ b/tools/misc/xen-ucode.c
@@ -11,6 +11,96 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <xenctrl.h>
+#include <xenhypfs.h>
+
+static const char intel_id[] = "GenuineIntel";
+static const char   amd_id[] = "AuthenticAMD";
+
+static const char sig_path[] = "/cpuinfo/cpu-signature";
+static const char rev_path[] = "/cpuinfo/microcode-revision";
+static const char  pf_path[] = "/cpuinfo/processor-flags";
+
+static int hypfs_read_uint(struct xenhypfs_handle *hdl, const char *path,
+                           unsigned int *var)
+{
+    char *result;
+    result = xenhypfs_read(hdl, path);
+    if ( !result )
+        return -1;
+
+    errno = 0;
+    *var = strtol(result, NULL, 10);
+    if ( errno )
+        return -1;
+
+    return 0;
+}
+
+static void show_curr_cpu(FILE *f)
+{
+    int ret;
+    struct xenhypfs_handle *hdl;
+    xc_interface *xch;
+    struct xenpf_pcpu_version cpu_ver = {0};
+    bool intel = false, amd = false;
+    unsigned int cpu_signature, pf, ucode_revision;
+
+    hdl = xenhypfs_open(NULL, 0);
+    if ( !hdl )
+        return;
+
+    xch = xc_interface_open(0, 0, 0);
+    if ( xch == NULL )
+        return;
+
+    ret = xc_get_cpu_version(xch, &cpu_ver);
+    if ( ret )
+        return;
+
+    if ( memcmp(cpu_ver.vendor_id, intel_id,
+                sizeof(cpu_ver.vendor_id)) == 0 )
+        intel = true;
+    else if ( memcmp(cpu_ver.vendor_id, amd_id,
+                     sizeof(cpu_ver.vendor_id)) == 0 )
+        amd = true;
+
+    if ( hypfs_read_uint(hdl, sig_path, &cpu_signature) != 0 )
+        return;
+
+    if ( hypfs_read_uint(hdl, rev_path, &ucode_revision) != 0 )
+        return;
+
+    if ( intel && hypfs_read_uint(hdl, pf_path,  &pf) != 0 )
+        return;
+
+    /*
+     * Print signature in a form that allows to quickly identify which ucode
+     * blob to load, e.g.:
+     *
+     *      Intel:   /lib/firmware/intel-ucode/06-55-04
+     *      AMD:     /lib/firmware/amd-ucode/microcode_amd_fam19h.bin
+     */
+    if ( intel )
+    {
+        fprintf(f, "Current CPU signature is: %02x-%02x-%02x (raw %#x)\n",
+                   cpu_ver.family, cpu_ver.model, cpu_ver.stepping,
+                   cpu_signature);
+    }
+    else if ( amd )
+    {
+        fprintf(f, "Current CPU signature is: fam%xh (raw %#x)\n",
+                   cpu_ver.family, cpu_signature);
+    }
+
+    if ( intel || amd )
+        fprintf(f, "Current CPU microcode revision is: %#x\n", ucode_revision);
+
+    if ( intel )
+        fprintf(f, "Current CPU processor flags are: %#x\n", pf);
+
+    xc_interface_close(xch);
+    xenhypfs_close(hdl);
+}
 
 int main(int argc, char *argv[])
 {
@@ -25,9 +115,16 @@ int main(int argc, char *argv[])
         fprintf(stderr,
                 "xen-ucode: Xen microcode updating tool\n"
                 "Usage: %s <microcode blob>\n", argv[0]);
+        show_curr_cpu(stderr);
         exit(2);
     }
 
+    if ( !strcmp(argv[1], "show-cpu-info") )
+    {
+        show_curr_cpu(stdout);
+        return 0;
+    }
+
     filename = argv[1];
     fd = open(filename, O_RDONLY);
     if ( fd < 0 )
-- 
2.17.1


Reply via email to