[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] tools/xen-ucode: print information about currently loaded ucode


  • To: Sergey Dyasli <sergey.dyasli@xxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Mon, 16 Jan 2023 16:21:12 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=IxkvyELeO30gwo1hNMwGZ9VENPcTdBnlwf4A6MgvRns=; b=hWHPauMVJohbd9Jl+o77o4/3lLGTv3hbHDqTMv7+rnJspOq1fP22Dx2bS3KAB5iyMWcrO9eI2nnsfsfM6JwZ9hKgZFHMHwIS93sgc2vIJfGLSL/x3Qo9swLHc8RjUAwqZctM77CGPRsrPJZD8EIaw5wq3TEi3OTD4jFZ9eKhhI14fgZLuhZr31aM1jKFhErKHVgaFWNxRfTxJcq4udFqs3xRxm8nAPhSzuMISshdSR12LDMHJJpQDGPGV80X2o+7gZjCthS1l5fentmvtu0Vru6Fe/oqwO9v5N4hx5JL49UvPtBYC4wk1AkZocQFA9LxHJrFKXWlyVMg8jVUhOkmQA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=IgdYxScOm/IVRxxwqB9ddNzeE7jMkWe2UdxBw0k769iX1Hde3SDuIY2jd5MI//8OqE6rIa34di89SuwDfPT372kkoBe6Gv+uMYnyRTQ4PMis2bzy6qD2ERmyAK4Vc7bjZ+Z+wQdj308ismBBzTYOEt0sRwKgKNTYHew9T/88n7/DOk22HtwPDFciBvsAi2XjD1GBZPinDmJLSkEAB2LQZ05YNwnrMHnHm/qDXVIochCZqQIVfS3NTEC6/ZxVkK7nf0v7uXwzSUlN6oBnvPLuHVu6hUxzHrrvonaCOkbxtEvR8+WNk6OPiEqC0pWPsRgyfu8mFvYnLl3Gnl7WT2lYlQ==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com;
  • Cc: Wei Liu <wl@xxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>, Juergen Gross <jgross@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, George Dunlap <george.dunlap@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Mon, 16 Jan 2023 15:21:47 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 13.01.2023 12:56, Sergey Dyasli wrote:
> Currently it's impossible to get CPU's microcode revision after late
> loading without looking into Xen logs which is not always convenient.
> Add an option to xen-ucode tool to print the currently loaded ucode
> version and also print it during usage info.
> 
> Add a new platform op in order to get the required data from Xen.
> Print CPU signature and processor flags as well.
> 
> Example output:
>     Intel:
>     Current CPU signature is: 06-55-04 (raw 0x50654)
>     Current CPU microcode revision is: 0x2006e05
>     Current CPU processor flags are: 0x1
> 
>     AMD:
>     Current CPU signature is: fam19h (raw 0xa00f11)

So quite a bit less precise information than on Intel in the non-raw
part. Is there a reason for this?

> --- a/tools/libs/ctrl/xc_misc.c
> +++ b/tools/libs/ctrl/xc_misc.c
> @@ -226,6 +226,11 @@ int xc_microcode_update(xc_interface *xch, const void 
> *buf, size_t len)
>      return ret;
>  }
>  
> +int xc_platform_op(xc_interface *xch, struct xen_platform_op *op)
> +{
> +    return do_platform_op(xch, op);
> +}

Wouldn't it make sense to simply rename do_platform_op()?

> --- a/tools/misc/xen-ucode.c
> +++ b/tools/misc/xen-ucode.c
> @@ -12,6 +12,67 @@
>  #include <fcntl.h>
>  #include <xenctrl.h>
>  
> +static const char *intel_id = "GenuineIntel";
> +static const char *amd_id   = "AuthenticAMD";

Do these need to be (non-const) pointers, rather than const char[]?

> +void show_curr_cpu(FILE *f)
> +{
> +    int ret;
> +    xc_interface *xch;
> +    struct xen_platform_op op_cpu = {0}, op_ucode = {0};

Instead of the dummy initializers, can't you make ...

> +    struct xenpf_pcpu_version *cpu_ver = &op_cpu.u.pcpu_version;
> +    struct xenpf_ucode_version *ucode_ver = &op_ucode.u.ucode_version;
> +    bool intel = false, amd = false;
> +
> +    xch = xc_interface_open(0, 0, 0);
> +    if ( xch == NULL )
> +        return;
> +
> +    op_cpu.cmd = XENPF_get_cpu_version;
> +    op_cpu.interface_version = XENPF_INTERFACE_VERSION;
> +    op_cpu.u.pcpu_version.xen_cpuid = 0;

... this and ...

> +    ret = xc_platform_op(xch, &op_cpu);
> +    if ( ret )
> +        return;
> +
> +    op_ucode.cmd = XENPF_get_ucode_version;
> +    op_ucode.interface_version = XENPF_INTERFACE_VERSION;
> +    op_ucode.u.pcpu_version.xen_cpuid = 0;

... this the initializers?

> @@ -20,11 +81,18 @@ int main(int argc, char *argv[])
>      struct stat st;
>      xc_interface *xch;
>  
> +    if ( argc >= 2 && !strcmp(argv[1], "show-cpu-info") )
> +    {
> +        show_curr_cpu(stdout);
> +        return 0;
> +    }
> +
>      if ( argc < 2 )
>      {
>          fprintf(stderr,
>                  "xen-ucode: Xen microcode updating tool\n"
>                  "Usage: %s <microcode blob>\n", argv[0]);
> +        show_curr_cpu(stderr);
>          exit(2);
>      }

Personally I'd find it mode logical if this remained first and you
inserted your new fragment right afterwards. That way you also don't
need to check argc twice.

> --- a/xen/arch/x86/platform_hypercall.c
> +++ b/xen/arch/x86/platform_hypercall.c
> @@ -640,6 +640,38 @@ ret_t do_platform_op(
>      }
>      break;
>  
> +    case XENPF_get_ucode_version:
> +    {
> +        struct xenpf_ucode_version *ver = &op->u.ucode_version;
> +
> +        if ( !get_cpu_maps() )
> +        {
> +            ret = -EBUSY;
> +            break;
> +        }
> +
> +        if ( (ver->xen_cpuid >= nr_cpu_ids) || !cpu_online(ver->xen_cpuid) )
> +        {
> +            ver->cpu_signature = 0;
> +            ver->pf = 0;
> +            ver->ucode_revision = 0;

Better return -ENOENT in this case?

> +        }
> +        else
> +        {
> +            const struct cpu_signature *sig = &per_cpu(cpu_sig, 
> ver->xen_cpuid);
> +
> +            ver->cpu_signature = sig->sig;
> +            ver->pf = sig->pf;
> +            ver->ucode_revision = sig->rev;

Here you read what is actually present, which ...

> --- a/xen/include/public/platform.h
> +++ b/xen/include/public/platform.h
> @@ -610,6 +610,19 @@ 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_version 65
> +struct xenpf_ucode_version {
> +    uint32_t xen_cpuid;       /* IN:  CPU number to get the revision from.  
> */
> +                              /*      Return data should be equal among all 
> */
> +                              /*      the CPUs.                             
> */

... doesn't necessarily match the promise here. Perhaps weaken the
"should", or clarify what the conditionsare for this to be the case?
Also your addition to xen-ucode builds on this, which can easily
end up misleading when it's not really the case.

> --- a/xen/include/xlat.lst
> +++ b/xen/include/xlat.lst
> @@ -157,6 +157,7 @@
>  ?    xenpf_pcpuinfo                  platform.h
>  ?    xenpf_pcpu_version              platform.h
>  ?    xenpf_resource_entry            platform.h
> +?    xenpf_ucode_version             platform.h

You also want to invoke the resulting macro, so that the intended checking
actually occurs.

Jan



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.