From 23ae50ba25109d228bb70e2cdb334dc0611bd1d0 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 3 Jul 2013 16:16:36 -0400 Subject: [PATCH] misc/xenmicrocode: Upload /lib/firmware/ to the hypervisor. Signed-off-by: Konrad Rzeszutek Wilk --- tools/libxc/xc_misc.c | 19 ++++++++++++ tools/libxc/xenctrl.h | 2 + tools/misc/Makefile | 7 +++- tools/misc/xenmicrocode.c | 70 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 96 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 3c5d64a..2f3487d 100644 --- a/tools/libxc/xc_misc.c +++ b/tools/libxc/xc_misc.c @@ -211,6 +211,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 b7741ca..42a2828 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -53,6 +53,7 @@ #include #include #include +#include #endif #ifdef __ia64__ @@ -1780,6 +1781,7 @@ int xc_cpuid_apply_policy(xc_interface *xch, void xc_cpuid_to_str(const unsigned int *regs, char **strs); 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 22e60fd..b578f6c 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 -TARGETS-$(CONFIG_X86) += xen-detect xen-hvmctx xen-hvmcrash xen-lowmemd +TARGETS-$(CONFIG_X86) += xen-detect xen-hvmctx xen-hvmcrash xen-lowmemd xenmicrocode TARGETS-$(CONFIG_MIGRATE) += xen-hptool TARGETS := $(TARGETS-y) @@ -23,7 +23,7 @@ INSTALL_BIN-$(CONFIG_X86) += xen-detect INSTALL_BIN := $(INSTALL_BIN-y) INSTALL_SBIN-y := xm xen-bugtool xen-python-path xend xenperf xsview xenpm xen-tmem-list-parse gtraceview gtracestat xenlockprof xenwatchdogd xen-ringwatch -INSTALL_SBIN-$(CONFIG_X86) += xen-hvmctx xen-hvmcrash xen-lowmemd +INSTALL_SBIN-$(CONFIG_X86) += xen-hvmctx xen-hvmcrash xen-lowmemd xenmicrocode INSTALL_SBIN-$(CONFIG_MIGRATE) += xen-hptool INSTALL_SBIN := $(INSTALL_SBIN-y) @@ -67,6 +67,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..80bb743 --- /dev/null +++ b/tools/misc/xenmicrocode.c @@ -0,0 +1,70 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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; +} -- 1.7.3.4