[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] misc/xenmicrocode: Upload /lib/firmware/<some blob> to the hypervisor



From: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>

There are several ways that a Xen system can update the
CPU microcode on a pvops kernel [0] now, the preferred way
is through the early microcode update mechanism. At run
time folks should use this new xenmicrocode tool and use
the same CPU microcode file as present on /lib/firmware.

Some distributions may use the historic sysfs rescan interface,
users of that mechanism should be aware that the interface will
not be available when using Xen and as such should first check
the presence of the interface before usage, as an alternative
this xenmicrocode tool can be used on priviledged domains.

Folks wishing to update CPU microcode at run time should be
aware that not all CPU microcode can be updated on a system
and should take care to ensure that only known-to-work and
supported CPU microcode updates are used [0].

[0] http://wiki.xenproject.org/wiki/XenParavirtOps/microcode_update

Cc: Borislav Petkov <bp@xxxxxxx>
Cc: Takashi Iwai <tiwai@xxxxxxx>
Cc: Olaf Hering <ohering@xxxxxxx>
Cc: Jan Beulich <JBeulich@xxxxxxxx>
Cc: Jason Douglas <jdouglas@xxxxxxxx>
Cc: Juergen Gross <jgross@xxxxxxxx>
Cc: Michal Marek <mmarek@xxxxxxx>
Cc: Henrique de Moraes Holschuh <hmh@xxxxxxxxxx>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
Signed-off-by: Luis R. Rodriguez <mcgrof@xxxxxxxx>
---
 tools/libxc/xc_misc.c     | 19 +++++++++++
 tools/libxc/xenctrl.h     |  2 ++
 tools/misc/Makefile       |  7 ++--
 tools/misc/xenmicrocode.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 107 insertions(+), 2 deletions(-)
 create mode 100644 tools/misc/xenmicrocode.c

diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
index e253a58..3ef2664 100644
--- a/tools/libxc/xc_misc.c
+++ b/tools/libxc/xc_misc.c
@@ -250,6 +250,25 @@ int xc_mca_op(xc_interface *xch, struct xen_mc *mc)
     xc_hypercall_bounce_post(xch, mc);
     return ret;
 }
+int xc_platform_op(xc_interface *xch, struct xen_platform_op *op)
+{
+    int ret = 0;
+    DECLARE_HYPERCALL;
+    DECLARE_HYPERCALL_BOUNCE(op, sizeof(*op), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
+
+    if ( xc_hypercall_bounce_pre(xch, op) )
+    {
+        PERROR("Could not bounce xen_platform_op memory buffer");
+        return -1;
+    }
+    op->interface_version = XENPF_INTERFACE_VERSION;
+
+    hypercall.op = __HYPERVISOR_platform_op;
+    hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(op);
+    ret = do_xen_hypercall(xch, &hypercall);
+    xc_hypercall_bounce_post(xch, op);
+    return ret;
+}
 #endif
 
 int xc_perfc_reset(xc_interface *xch)
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index 514b241..5085e50 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -54,6 +54,7 @@
 #include <xen/foreign/x86_32.h>
 #include <xen/foreign/x86_64.h>
 #include <xen/arch-x86/xen-mca.h>
+#include <xen/platform.h>
 #endif
 
 #define XC_PAGE_SHIFT           12
@@ -2131,6 +2132,7 @@ int xc_cpuid_apply_policy(xc_interface *xch,
 void xc_cpuid_to_str(const unsigned int *regs,
                      char **strs); /* some strs[] may be NULL if ENOMEM */
 int xc_mca_op(xc_interface *xch, struct xen_mc *mc);
+int xc_platform_op(xc_interface *xch, struct xen_platform_op *platform_op);
 #endif
 
 struct xc_px_val {
diff --git a/tools/misc/Makefile b/tools/misc/Makefile
index 69b1817..bb838d0 100644
--- a/tools/misc/Makefile
+++ b/tools/misc/Makefile
@@ -10,7 +10,7 @@ CFLAGS += $(CFLAGS_libxenstore)
 HDRS     = $(wildcard *.h)
 
 TARGETS-y := xenperf xenpm xen-tmem-list-parse gtraceview gtracestat 
xenlockprof xenwatchdogd xencov
-TARGETS-$(CONFIG_X86) += xen-detect xen-hvmctx xen-hvmcrash xen-lowmemd 
xen-mfndump
+TARGETS-$(CONFIG_X86) += xen-detect xen-hvmctx xen-hvmcrash xen-lowmemd 
xen-mfndump xenmicrocode
 TARGETS-$(CONFIG_MIGRATE) += xen-hptool
 TARGETS := $(TARGETS-y)
 
@@ -22,7 +22,7 @@ INSTALL_BIN := $(INSTALL_BIN-y)
 
 INSTALL_SBIN-y := xen-bugtool xen-python-path xenperf xenpm 
xen-tmem-list-parse gtraceview \
        gtracestat xenlockprof xenwatchdogd xen-ringwatch xencov
-INSTALL_SBIN-$(CONFIG_X86) += xen-hvmctx xen-hvmcrash xen-lowmemd xen-mfndump
+INSTALL_SBIN-$(CONFIG_X86) += xen-hvmctx xen-hvmcrash xen-lowmemd xen-mfndump 
xenmicrocode
 INSTALL_SBIN-$(CONFIG_MIGRATE) += xen-hptool
 INSTALL_SBIN := $(INSTALL_SBIN-y)
 
@@ -66,6 +66,9 @@ xenperf: xenperf.o
 xenpm: xenpm.o
        $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
 
+xenmicrocode: xenmicrocode.o
+       $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
+
 gtracestat: gtracestat.o
        $(CC) $(LDFLAGS) -o $@ $< $(APPEND_LDFLAGS)
 
diff --git a/tools/misc/xenmicrocode.c b/tools/misc/xenmicrocode.c
new file mode 100644
index 0000000..5c58a1b
--- /dev/null
+++ b/tools/misc/xenmicrocode.c
@@ -0,0 +1,81 @@
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <string.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <xenctrl.h>
+
+int main(int argc, char *argv[])
+{
+    int fd = 0;
+    unsigned char *fbuf;
+    int len;
+    xc_interface *xc_handle;
+    char *filename;
+    struct stat buf;
+    DECLARE_HYPERCALL_BUFFER(struct xenpf_microcode_update, uc);
+    struct xen_platform_op op;
+
+    filename = argv[1];
+    fd = open(filename, O_RDONLY);
+
+    if (fd <= 0)
+    {
+        printf("Could not open; err: %d(%s)\n", errno, strerror(errno));
+        return errno;
+    }
+
+    if (stat(filename, &buf) != 0)
+    {
+        printf("Could not open; err: %d(%s)\n", errno, strerror(errno));
+        return errno;
+    }
+
+    printf("%s: %ld\n", filename, buf.st_size);
+
+    len = buf.st_size;
+    fbuf = mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0);
+
+    if ((xc_handle = xc_interface_open(0,0,0)) == 0)
+    {
+        fprintf(stderr, "Error opening xc interface: %d (%s)\n",
+                errno, strerror(errno));
+        return 1;
+    }
+
+    if (fbuf == MAP_FAILED)
+    {
+        printf("Could not map: error: %d(%s)\n", errno,
+               strerror(errno));
+        return errno;
+    }
+
+    uc = xc_hypercall_buffer_alloc(xc_handle, uc, len);
+    memcpy(uc, fbuf, len);
+
+    set_xen_guest_handle(op.u.microcode.data, uc);
+    op.cmd = XENPF_microcode_update;
+    op.interface_version = XENPF_INTERFACE_VERSION;
+    op.u.microcode.length = len;
+    xc_platform_op(xc_handle, &op);
+
+    xc_hypercall_buffer_free(xc_handle, uc);
+    xc_interface_close(xc_handle);
+
+    if (munmap(fbuf, len))
+    {
+        printf("Could not unmap: %d(%s)\n", errno, strerror(errno));
+        return errno;
+    }
+
+    close(fd);
+
+    return 0;
+}
-- 
2.1.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.