@@ -1187,6 +1187,8 @@ int xc_cputopoinfo(xc_interface *xch, unsigned *max_cpus,
xc_cputopo_t *cputopo);
int xc_microcode_update(xc_interface *xch, const void *buf, size_t len);
int xc_get_cpu_version(xc_interface *xch, struct xenpf_pcpu_version *cpu_ver);
+int xc_get_ucode_revision(xc_interface *xch,
+ struct xenpf_ucode_revision *ucode_rev);
int xc_numainfo(xc_interface *xch, unsigned *max_nodes,
xc_meminfo_t *meminfo, uint32_t *distance);
int xc_pcitopoinfo(xc_interface *xch, unsigned num_devs,
@@ -243,6 +243,24 @@ int xc_get_cpu_version(xc_interface *xch, struct xenpf_pcpu_version *cpu_ver)
return 0;
}
+int xc_get_ucode_revision(xc_interface *xch,
+ struct xenpf_ucode_revision *ucode_rev)
+{
+ int ret;
+ struct xen_platform_op op = {
+ .cmd = XENPF_get_ucode_revision,
+ .u.ucode_revision.cpu = ucode_rev->cpu,
+ };
+
+ ret = do_platform_op(xch, &op);
+ if ( ret != 0 )
+ return ret;
+
+ *ucode_rev = op.u.ucode_revision;
+
+ return 0;
+}
+
int xc_cputopoinfo(xc_interface *xch, unsigned *max_cpus,
xc_cputopo_t *cputopo)
{
@@ -640,6 +640,35 @@ ret_t do_platform_op(
}
break;
+ case XENPF_get_ucode_revision:
+ {
+ struct xenpf_ucode_revision *rev = &op->u.ucode_revision;
+
+ if ( !get_cpu_maps() )
+ {
+ ret = -EBUSY;
+ break;
+ }
+
+ /* TODO: make it possible to know ucode revisions for parked CPUs */
+ if ( (rev->cpu >= nr_cpu_ids) || !cpu_online(rev->cpu) )
+ ret = -ENOENT;
+ else
+ {
+ const struct cpu_signature *sig = &per_cpu(cpu_sig, rev->cpu);
+
+ rev->signature = sig->sig;
+ rev->pf = sig->pf;
+ rev->revision = sig->rev;
+ }
+
+ put_cpu_maps();
+
+ if ( __copy_field_to_guest(u_xenpf_op, op, u.ucode_revision) )
+ ret = -EFAULT;
+ }
+ break;
+
case XENPF_cpu_online:
{
int cpu = op->u.cpu_ol.cpuid;
@@ -28,6 +28,10 @@ CHECK_pf_pcpuinfo;
CHECK_pf_pcpu_version;
#undef xen_pf_pcpu_version
+#define xen_pf_ucode_revision xenpf_ucode_revision
+CHECK_pf_ucode_revision;
+#undef xen_pf_pucode_revision
+
#define xen_pf_enter_acpi_sleep xenpf_enter_acpi_sleep
CHECK_pf_enter_acpi_sleep;
#undef xen_pf_enter_acpi_sleep
@@ -614,6 +614,16 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_symdata_t);
typedef struct dom0_vga_console_info xenpf_dom0_console_t;
DEFINE_XEN_GUEST_HANDLE(xenpf_dom0_console_t);
+#define XENPF_get_ucode_revision 65
+struct xenpf_ucode_revision {
+ uint32_t cpu; /* IN: CPU number to get the revision from. */
+ uint32_t signature; /* OUT: CPU signature (CPUID.1.EAX). */
+ uint32_t pf; /* OUT: Platform Flags (Intel only) */
+ uint32_t revision; /* OUT: Microcode Revision. */
+};
+typedef struct xenpf_ucode_revision xenpf_ucode_revision_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_ucode_revision_t);
+
/*
* ` enum neg_errnoval
* ` HYPERVISOR_platform_op(const struct xen_platform_op*);
@@ -645,6 +655,7 @@ struct xen_platform_op {
xenpf_resource_op_t resource_op;
xenpf_symdata_t symdata;
xenpf_dom0_console_t dom0_console;
+ xenpf_ucode_revision_t ucode_revision;
uint8_t pad[128];
} u;
};
@@ -157,6 +157,7 @@
? xenpf_pcpuinfo platform.h
? xenpf_pcpu_version platform.h
? xenpf_resource_entry platform.h
+? xenpf_ucode_revision platform.h
? pmu_data pmu.h
? pmu_params pmu.h
! sched_poll sched.h