Currently it's impossible to get CPU's microcode revision after late loading without looking into Xen logs which is not always convenient.
Leverage xenhypfs to expose struct cpu_signature in a new cpuinfo dir. The tree structure is: / cpuinfo/ cpu-signature microcode-revision processor-flags The most useful bit is cpu microcode revision which will get updated after late ucode loading. Signed-off-by: Sergey Dyasli <sergey.dya...@citrix.com> --- xen/arch/x86/cpu/common.c | 58 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index 5ad347534a..aa864fdbab 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -1005,3 +1005,61 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id table[]) } return NULL; } + +#ifdef CONFIG_HYPFS +#include <xen/hypfs.h> +#include <xen/guest_access.h> +#include <asm/microcode.h> + +static unsigned int cpu_signature; +static unsigned int processor_flags; +static unsigned int ucode_revision; + +int cf_check hypfs_read_cpusig( + const struct hypfs_entry *entry, XEN_GUEST_HANDLE_PARAM(void) uaddr) +{ + const struct hypfs_entry_leaf *l; + unsigned int size = entry->funcs->getsize(entry); + const struct cpu_signature *sig = &per_cpu(cpu_sig, + cpumask_first(&cpu_online_map)); + + l = container_of(entry, const struct hypfs_entry_leaf, e); + + cpu_signature = sig->sig; + processor_flags = sig->pf; + ucode_revision = sig->rev; + + return copy_to_guest(uaddr, l->u.content, size) ? -EFAULT : 0; +} + +const struct hypfs_funcs ucode_rev_funcs = { + .enter = hypfs_node_enter, + .exit = hypfs_node_exit, + .read = hypfs_read_cpusig, + .write = hypfs_write_deny, + .getsize = hypfs_getsize, + .findentry = hypfs_leaf_findentry, +}; + +static HYPFS_DIR_INIT(cpuinfo, "cpuinfo"); +static HYPFS_FIXEDSIZE_INIT(signature, XEN_HYPFS_TYPE_UINT, "cpu-signature", + cpu_signature, &ucode_rev_funcs, 0); +static HYPFS_FIXEDSIZE_INIT(pf, XEN_HYPFS_TYPE_UINT, "processor-flags", + processor_flags, &ucode_rev_funcs, 0); +static HYPFS_FIXEDSIZE_INIT(revision, XEN_HYPFS_TYPE_UINT, "microcode-revision", + ucode_revision, &ucode_rev_funcs, 0); + +static int __init cf_check cpuinfo_init(void) +{ + hypfs_add_dir(&hypfs_root, &cpuinfo, true); + hypfs_add_leaf(&cpuinfo, &signature, true); + + if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ) + hypfs_add_leaf(&cpuinfo, &pf, true); + + hypfs_add_leaf(&cpuinfo, &revision, true); + + return 0; +} +__initcall(cpuinfo_init); +#endif /* CONFIG_HYPFS */ -- 2.17.1