@@ -40,6 +40,8 @@
#include <asm/processor.h>
#include <asm/setup.h>
+#include <public/platform.h>
+
#include "private.h"
/*
@@ -570,6 +572,7 @@ static int cf_check do_microcode_update(void *patch)
}
struct ucode_buf {
+ unsigned int flags;
unsigned int len;
char buffer[];
};
@@ -708,13 +711,14 @@ static long cf_check microcode_update_helper(void *data)
return ret;
}
-int microcode_update(XEN_GUEST_HANDLE(const_void) buf, unsigned long len)
+int microcode_update(XEN_GUEST_HANDLE(const_void) buf,
+ unsigned long len, unsigned int flags)
{
int ret;
struct ucode_buf *buffer;
- if ( len != (uint32_t)len )
- return -E2BIG;
+ if ( flags & ~XENPF_UCODE_FORCE )
+ return -EINVAL;
if ( !ucode_ops.apply_microcode )
return -EINVAL;
@@ -730,6 +734,7 @@ int microcode_update(XEN_GUEST_HANDLE(const_void) buf, unsigned long len)
return -EFAULT;
}
buffer->len = len;
+ buffer->flags = flags;
/*
* Always queue microcode_update_helper() on CPU0. Most of the logic
@@ -22,7 +22,8 @@ struct cpu_signature {
DECLARE_PER_CPU(struct cpu_signature, cpu_sig);
void microcode_set_module(unsigned int idx);
-int microcode_update(XEN_GUEST_HANDLE(const_void) buf, unsigned long len);
+int microcode_update(XEN_GUEST_HANDLE(const_void) buf,
+ unsigned long len, unsigned int flags);
int early_microcode_init(unsigned long *module_map,
const struct multiboot_info *mbi);
int microcode_init_cache(unsigned long *module_map,
@@ -311,7 +311,18 @@ ret_t do_platform_op(
guest_from_compat_handle(data, op->u.microcode.data);
- ret = microcode_update(data, op->u.microcode.length);
+ ret = microcode_update(data, op->u.microcode.length, 0);
+ break;
+ }
+
+ case XENPF_microcode_update2:
+ {
+ XEN_GUEST_HANDLE(const_void) data;
+
+ guest_from_compat_handle(data, op->u.microcode2.data);
+
+ ret = microcode_update(data, op->u.microcode2.length,
+ op->u.microcode2.flags);
break;
}
@@ -624,6 +624,19 @@ struct xenpf_ucode_revision {
typedef struct xenpf_ucode_revision xenpf_ucode_revision_t;
DEFINE_XEN_GUEST_HANDLE(xenpf_ucode_revision_t);
+/* Hypercall to microcode_update with flags */
+#define XENPF_microcode_update2 66
+struct xenpf_microcode_update2 {
+ /* IN variables. */
+ uint32_t flags; /* Flags to be passed with ucode. */
+/* Force to skip microcode version check */
+#define XENPF_UCODE_FORCE 1
+ uint32_t length; /* Length of microcode data. */
+ XEN_GUEST_HANDLE(const_void) data;/* Pointer to microcode data */
+};
+typedef struct xenpf_microcode_update2 xenpf_microcode_update2_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_microcode_update2_t);
+
/*
* ` enum neg_errnoval
* ` HYPERVISOR_platform_op(const struct xen_platform_op*);
@@ -656,6 +669,7 @@ struct xen_platform_op {
xenpf_symdata_t symdata;
xenpf_dom0_console_t dom0_console;
xenpf_ucode_revision_t ucode_revision;
+ xenpf_microcode_update2_t microcode2;
uint8_t pad[128];
} u;
};