]> xenbits.xensource.com Git - people/aperard/xen-unstable.git/commitdiff
x86/platform: introduce XENPF_get_ucode_revision
authorSergey Dyasli <sergey.dyasli@citrix.com>
Mon, 17 Apr 2023 13:53:34 +0000 (14:53 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 3 May 2023 17:36:46 +0000 (18:36 +0100)
Currently it's hard to get CPU's microcode revision from Xen after late
loading without looking into Xen logs, which is not always convenient.

Add a new platform op in order to get the required data from Xen and
provide a wrapper for libxenctrl.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
tools/include/xenctrl.h
tools/libs/ctrl/xc_misc.c
xen/arch/x86/platform_hypercall.c
xen/arch/x86/x86_64/platform_hypercall.c
xen/include/public/platform.h
xen/include/xlat.lst

index a82d8bc73bb2f00f5fc170203de430a216caad3d..086314d28ae86037b6da62569938185e0361f414 100644 (file)
@@ -1216,6 +1216,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,
index 90d50faa4fc84cddc7a117ea79d75d416dbbdb10..4159294b2ed5691bea30675658e29d2c6c95ca5b 100644 (file)
@@ -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)
 {
index a2d9526355d08008d2d5696b1fb876c2f234de0a..9ff2da8fc32460101246ddd5ffe10abe21f989ba 100644 (file)
@@ -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;
index 5bf6b958d242bbb82b172ff0d53ffd117ac1ecbc..99440f40764f10010536586f9f619d7d76244166 100644 (file)
@@ -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
index 60caa5ce7e73ce80f16b3cb5fa3e63cf9f08308b..15777b54169039c151fcce0d7713a293e5f5295d 100644 (file)
@@ -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;
 };
index d601a8a984213dbca2fbecebfdfb8df89bbb748d..9c41948514bf5bebcbc404a462a74dcf9c45d0bc 100644 (file)
 ?      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