* [PATCH v5 0/4] x86/xen-ucode: Introduce --force option
@ 2024-07-12 13:07 Fouad Hilly
2024-07-12 13:07 ` [PATCH v5 1/4] x86/ucode: Introduce XENPF_microcode_update2 with flags parameter Fouad Hilly
` (3 more replies)
0 siblings, 4 replies; 13+ messages in thread
From: Fouad Hilly @ 2024-07-12 13:07 UTC (permalink / raw)
To: xen-devel
Cc: Fouad Hilly, Jan Beulich, Andrew Cooper, Roger Pau Monné,
Julien Grall, Stefano Stabellini, Anthony PERARD, Juergen Gross
Refactor and introduce --force option to xen-ucode, which skips microcode
version check when updating x86 CPU micocode. A new hypercall introduced
with flags field to facilitate the new option and allow for future flags
as needed.
This change is required to enable developers to load ucode that is the same version as the
one already loaded or downgrade for testing.
Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Fouad Hilly (4):
x86/ucode: Introduce XENPF_microcode_update2 with flags parameter
x86/ucode: refactor xen-ucode to utilize getopt
x86/ucode: Introduce --force option to xen-ucode
x86/ucode: Utilize ucode_force and remove opt_ucode_allow_same
docs/misc/xen-command-line.pandoc | 7 +-
tools/include/xenctrl.h | 3 +-
tools/libs/ctrl/xc_misc.c | 12 ++--
tools/misc/xen-ucode.c | 63 +++++++++++++---
xen/arch/x86/cpu/microcode/amd.c | 8 ++-
xen/arch/x86/cpu/microcode/core.c | 104 +++++++++++++++++----------
xen/arch/x86/cpu/microcode/intel.c | 9 ++-
xen/arch/x86/cpu/microcode/private.h | 5 +-
xen/arch/x86/include/asm/microcode.h | 3 +-
xen/arch/x86/platform_hypercall.c | 13 +++-
xen/include/public/platform.h | 14 ++++
11 files changed, 172 insertions(+), 69 deletions(-)
--
2.42.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v5 1/4] x86/ucode: Introduce XENPF_microcode_update2 with flags parameter
2024-07-12 13:07 [PATCH v5 0/4] x86/xen-ucode: Introduce --force option Fouad Hilly
@ 2024-07-12 13:07 ` Fouad Hilly
2024-07-12 13:07 ` [PATCH v5 2/4] x86/ucode: refactor xen-ucode to utilize getopt Fouad Hilly
` (2 subsequent siblings)
3 siblings, 0 replies; 13+ messages in thread
From: Fouad Hilly @ 2024-07-12 13:07 UTC (permalink / raw)
To: xen-devel
Cc: Fouad Hilly, Jan Beulich, Andrew Cooper, Roger Pau Monné,
Julien Grall, Stefano Stabellini
Refactor microcode_update() by adding flags field.
struct xenpf_microcode_update2 added with uint32_t flags field.
Introduce XENPF_microcode_update2 hypercall with flags field.
Signed-off-by: Fouad Hilly <fouad.hilly@cloud.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
[v5]
1- Update commit message to include the full name of XENPF_microcode_update2
[v4]
1- Commit message and description updated.
2- Changing the order of the patches.
[v3]
1- Updated Commit message description.
2- Revereted changes to a stable ABI and introduced a new struct.
3- ucode_force_flag updated from static to a local variable.
4- microcode_update() updated to reject unsupported flags yet.
[v2]
1- Update message description to highlight interface change.
2- Removed extra empty lines.
3- removed unnecessary define.
4- Corrected long lines.
5- Removed ternary operator.
6- Introduced static ucode_update_flags, which will be used later to determine local ucode_force_flag.
---
xen/arch/x86/cpu/microcode/core.c | 11 ++++++++---
xen/arch/x86/include/asm/microcode.h | 3 ++-
xen/arch/x86/platform_hypercall.c | 13 ++++++++++++-
xen/include/public/platform.h | 14 ++++++++++++++
4 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c
index e90055772acf..8a9e744489b9 100644
--- a/xen/arch/x86/cpu/microcode/core.c
+++ b/xen/arch/x86/cpu/microcode/core.c
@@ -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
diff --git a/xen/arch/x86/include/asm/microcode.h b/xen/arch/x86/include/asm/microcode.h
index 8f59b20b0289..57c08205d475 100644
--- a/xen/arch/x86/include/asm/microcode.h
+++ b/xen/arch/x86/include/asm/microcode.h
@@ -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,
diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c
index 95467b88ab64..7e3278109300 100644
--- a/xen/arch/x86/platform_hypercall.c
+++ b/xen/arch/x86/platform_hypercall.c
@@ -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;
}
diff --git a/xen/include/public/platform.h b/xen/include/public/platform.h
index 15777b541690..2725b8d1044f 100644
--- a/xen/include/public/platform.h
+++ b/xen/include/public/platform.h
@@ -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;
};
--
2.42.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v5 2/4] x86/ucode: refactor xen-ucode to utilize getopt
2024-07-12 13:07 [PATCH v5 0/4] x86/xen-ucode: Introduce --force option Fouad Hilly
2024-07-12 13:07 ` [PATCH v5 1/4] x86/ucode: Introduce XENPF_microcode_update2 with flags parameter Fouad Hilly
@ 2024-07-12 13:07 ` Fouad Hilly
2024-07-16 14:51 ` Jan Beulich
2024-07-24 16:55 ` Anthony PERARD
2024-07-12 13:07 ` [PATCH v5 3/4] x86/ucode: Introduce --force option to xen-ucode Fouad Hilly
2024-07-12 13:07 ` [PATCH v5 4/4] x86/ucode: Utilize ucode_force and remove opt_ucode_allow_same Fouad Hilly
3 siblings, 2 replies; 13+ messages in thread
From: Fouad Hilly @ 2024-07-12 13:07 UTC (permalink / raw)
To: xen-devel; +Cc: Fouad Hilly, Anthony PERARD
Use getopt_long() to handle command line arguments.
Introduce ext_err for common exit with errors.
Introducing usage() to handle usage\help messages in a common block.
show_curr_cpu is printed to stdout only.
Signed-off-by: Fouad Hilly <fouad.hilly@cloud.com>
---
[v5]
1- Update message description.
2- re-arrange static and automatic variables.
3- Fix indentations.
4- reverted the deletion of show-cpu-info for backwards compatibility.
[v4]
1- Merge three patches into one.
2- usage() to print messages to the correct stream.
3- Update commit message and description.
---
tools/misc/xen-ucode.c | 52 +++++++++++++++++++++++++++++++++++-------
1 file changed, 44 insertions(+), 8 deletions(-)
diff --git a/tools/misc/xen-ucode.c b/tools/misc/xen-ucode.c
index 390969db3d1c..8de82e5b8a10 100644
--- a/tools/misc/xen-ucode.c
+++ b/tools/misc/xen-ucode.c
@@ -11,6 +11,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <xenctrl.h>
+#include <getopt.h>
static xc_interface *xch;
@@ -71,12 +72,29 @@ static void show_curr_cpu(FILE *f)
}
}
+static void usage(FILE *stream, const char *name)
+{
+ fprintf(stream,
+ "%s: Xen microcode updating tool\n"
+ "options:\n"
+ " -h, --help display this help\n"
+ " -s, --show-cpu-info show CPU information\n"
+ "Usage: %s [microcode file] [options]\n", name, name);
+ show_curr_cpu(stream);
+}
+
int main(int argc, char *argv[])
{
+ static const struct option options[] = {
+ {"help", no_argument, NULL, 'h'},
+ {"show-cpu-info", no_argument, NULL, 's'},
+ {NULL, no_argument, NULL, 0}
+ };
int fd, ret;
char *filename, *buf;
size_t len;
struct stat st;
+ int opt;
xch = xc_interface_open(NULL, NULL, 0);
if ( xch == NULL )
@@ -86,22 +104,34 @@ int main(int argc, char *argv[])
exit(1);
}
- if ( argc < 2 )
+ while ( (opt = getopt_long(argc, argv, "hs", options, NULL)) != -1 )
{
- fprintf(stderr,
- "xen-ucode: Xen microcode updating tool\n"
- "Usage: %s [<microcode file> | show-cpu-info]\n", argv[0]);
- show_curr_cpu(stderr);
- exit(2);
+ switch (opt)
+ {
+ case 'h':
+ usage(stdout, argv[0]);
+ exit(EXIT_SUCCESS);
+
+ case 's':
+ show_curr_cpu(stdout);
+ exit(EXIT_SUCCESS);
+
+ default:
+ goto ext_err;
+ }
}
- if ( !strcmp(argv[1], "show-cpu-info") )
+ if ( optind == argc )
+ goto ext_err;
+
+ /* For backwards compatibility to the pre-getopt() cmdline handling */
+ if ( !strcmp(argv[optind], "show-cpu-info") )
{
show_curr_cpu(stdout);
return 0;
}
- filename = argv[1];
+ filename = argv[optind];
fd = open(filename, O_RDONLY);
if ( fd < 0 )
{
@@ -146,4 +176,10 @@ int main(int argc, char *argv[])
close(fd);
return 0;
+
+ ext_err:
+ fprintf(stderr,
+ "%s: unable to process command line arguments\n", argv[0]);
+ usage(stderr, argv[0]);
+ exit(EXIT_FAILURE);
}
--
2.42.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v5 3/4] x86/ucode: Introduce --force option to xen-ucode
2024-07-12 13:07 [PATCH v5 0/4] x86/xen-ucode: Introduce --force option Fouad Hilly
2024-07-12 13:07 ` [PATCH v5 1/4] x86/ucode: Introduce XENPF_microcode_update2 with flags parameter Fouad Hilly
2024-07-12 13:07 ` [PATCH v5 2/4] x86/ucode: refactor xen-ucode to utilize getopt Fouad Hilly
@ 2024-07-12 13:07 ` Fouad Hilly
2024-07-12 13:27 ` Jan Beulich
2024-07-12 13:07 ` [PATCH v5 4/4] x86/ucode: Utilize ucode_force and remove opt_ucode_allow_same Fouad Hilly
3 siblings, 1 reply; 13+ messages in thread
From: Fouad Hilly @ 2024-07-12 13:07 UTC (permalink / raw)
To: xen-devel; +Cc: Fouad Hilly, Anthony PERARD, Juergen Gross, Andrew Cooper
Introduce --force option to xen-ucode to force skipping microcode version check, which
allows the user to update x86 microcode even if both versions are the same or downgrade.
xc_microcode_update() refactored to accept flags and utilize xenpf_microcode_update2.
Signed-off-by: Fouad Hilly <fouad.hilly@cloud.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
[v5]
1- Update commit message.
2- Re-phrase --force option description.
[v4]
1- Add --force to xen-ucode options.
2- Update xc_microcode_update() to accept and handle flags.
---
tools/include/xenctrl.h | 3 ++-
tools/libs/ctrl/xc_misc.c | 12 +++++++-----
tools/misc/xen-ucode.c | 13 +++++++++++--
3 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h
index 9ceca0cffc2f..2c4608c09ab0 100644
--- a/tools/include/xenctrl.h
+++ b/tools/include/xenctrl.h
@@ -1171,7 +1171,8 @@ typedef uint32_t xc_node_to_node_dist_t;
int xc_physinfo(xc_interface *xch, xc_physinfo_t *info);
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_microcode_update(xc_interface *xch, const void *buf,
+ size_t len, unsigned int flags);
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);
diff --git a/tools/libs/ctrl/xc_misc.c b/tools/libs/ctrl/xc_misc.c
index 50282fd60dcc..6a60216bda03 100644
--- a/tools/libs/ctrl/xc_misc.c
+++ b/tools/libs/ctrl/xc_misc.c
@@ -203,11 +203,12 @@ int xc_physinfo(xc_interface *xch,
return 0;
}
-int xc_microcode_update(xc_interface *xch, const void *buf, size_t len)
+int xc_microcode_update(xc_interface *xch, const void *buf,
+ size_t len, unsigned int flags)
{
int ret;
struct xen_platform_op platform_op = {};
- DECLARE_HYPERCALL_BUFFER(struct xenpf_microcode_update, uc);
+ DECLARE_HYPERCALL_BUFFER(struct xenpf_microcode_update2, uc);
uc = xc_hypercall_buffer_alloc(xch, uc, len);
if ( uc == NULL )
@@ -215,9 +216,10 @@ int xc_microcode_update(xc_interface *xch, const void *buf, size_t len)
memcpy(uc, buf, len);
- platform_op.cmd = XENPF_microcode_update;
- platform_op.u.microcode.length = len;
- set_xen_guest_handle(platform_op.u.microcode.data, uc);
+ platform_op.cmd = XENPF_microcode_update2;
+ platform_op.u.microcode2.length = len;
+ platform_op.u.microcode2.flags = flags;
+ set_xen_guest_handle(platform_op.u.microcode2.data, uc);
ret = do_platform_op(xch, &platform_op);
diff --git a/tools/misc/xen-ucode.c b/tools/misc/xen-ucode.c
index 8de82e5b8a10..a0eb3f205341 100644
--- a/tools/misc/xen-ucode.c
+++ b/tools/misc/xen-ucode.c
@@ -13,6 +13,8 @@
#include <xenctrl.h>
#include <getopt.h>
+#include <xen/platform.h>
+
static xc_interface *xch;
static const char intel_id[] = "GenuineIntel";
@@ -79,6 +81,8 @@ static void usage(FILE *stream, const char *name)
"options:\n"
" -h, --help display this help\n"
" -s, --show-cpu-info show CPU information\n"
+ " -f, --force skip certain checks; do not use unless you"
+ "know exactly what you are doing\n"
"Usage: %s [microcode file] [options]\n", name, name);
show_curr_cpu(stream);
}
@@ -88,6 +92,7 @@ int main(int argc, char *argv[])
static const struct option options[] = {
{"help", no_argument, NULL, 'h'},
{"show-cpu-info", no_argument, NULL, 's'},
+ {"force", no_argument, NULL, 'f'},
{NULL, no_argument, NULL, 0}
};
int fd, ret;
@@ -95,6 +100,7 @@ int main(int argc, char *argv[])
size_t len;
struct stat st;
int opt;
+ uint32_t ucode_flags = 0;
xch = xc_interface_open(NULL, NULL, 0);
if ( xch == NULL )
@@ -104,7 +110,7 @@ int main(int argc, char *argv[])
exit(1);
}
- while ( (opt = getopt_long(argc, argv, "hs", options, NULL)) != -1 )
+ while ( (opt = getopt_long(argc, argv, "hsf", options, NULL)) != -1 )
{
switch (opt)
{
@@ -116,6 +122,9 @@ int main(int argc, char *argv[])
show_curr_cpu(stdout);
exit(EXIT_SUCCESS);
+ case 'f':
+ ucode_flags = XENPF_UCODE_FORCE;
+ break;
default:
goto ext_err;
}
@@ -156,7 +165,7 @@ int main(int argc, char *argv[])
}
errno = 0;
- ret = xc_microcode_update(xch, buf, len);
+ ret = xc_microcode_update(xch, buf, len, ucode_flags);
if ( ret == -1 && errno == EEXIST )
printf("Microcode already up to date\n");
else if ( ret )
--
2.42.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v5 4/4] x86/ucode: Utilize ucode_force and remove opt_ucode_allow_same
2024-07-12 13:07 [PATCH v5 0/4] x86/xen-ucode: Introduce --force option Fouad Hilly
` (2 preceding siblings ...)
2024-07-12 13:07 ` [PATCH v5 3/4] x86/ucode: Introduce --force option to xen-ucode Fouad Hilly
@ 2024-07-12 13:07 ` Fouad Hilly
2024-07-16 14:59 ` Jan Beulich
3 siblings, 1 reply; 13+ messages in thread
From: Fouad Hilly @ 2024-07-12 13:07 UTC (permalink / raw)
To: xen-devel
Cc: Fouad Hilly, Andrew Cooper, Jan Beulich, Julien Grall,
Stefano Stabellini, Roger Pau Monné
Pass xen-ucode flags to do low level checks on micorocde version and
utilize it to allow for microcode downgrade or reapply the same version of the
microcode.
ucode_force is required to be passed to a low level Intel and AMD for version
checks to be done.
While adding ucode_force, opt_ucode_allow_same was removed.
Remove opt_ucode_allow_same from documentation.
Signed-off-by: Fouad Hilly <fouad.hilly@cloud.com>
---
[v5]
1- Update commit message.
2- Introduce structs microcode_patch_with_flags and microcode_nmi_patch_with_flags.
3- pass flags to Intel and AMD low level through apply_microcode().
[4]
1- As opt_ucode_allow_same is not required anymore, it has been removed while introducing ucode_force.
2- Apply the changes for both AMD and Intel.
3- Remove the mention of opt_ucode_allow_same from documentation.
---
docs/misc/xen-command-line.pandoc | 7 +--
xen/arch/x86/cpu/microcode/amd.c | 8 ++-
xen/arch/x86/cpu/microcode/core.c | 93 +++++++++++++++++-----------
xen/arch/x86/cpu/microcode/intel.c | 9 ++-
xen/arch/x86/cpu/microcode/private.h | 5 +-
5 files changed, 73 insertions(+), 49 deletions(-)
diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
index 98a45211556b..2a8d47bbc664 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -2650,7 +2650,7 @@ performance.
Alternatively, selecting `tsx=1` will re-enable TSX at the users own risk.
### ucode
-> `= List of [ <integer> | scan=<bool>, nmi=<bool>, allow-same=<bool> ]`
+> `= List of [ <integer> | scan=<bool>, nmi=<bool> ]`
Applicability: x86
Default: `nmi`
@@ -2682,11 +2682,6 @@ precedence over `scan`.
stop_machine context. In NMI handler, even NMIs are blocked, which is
considered safer. The default value is `true`.
-'allow-same' alters the default acceptance policy for new microcode to permit
-trying to reload the same version. Many CPUs will actually reload microcode
-of the same version, and this allows for easy testing of the late microcode
-loading path.
-
### unrestricted_guest (Intel)
> `= <boolean>`
diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c
index f76a563c8b84..8ec19441cfcd 100644
--- a/xen/arch/x86/cpu/microcode/amd.c
+++ b/xen/arch/x86/cpu/microcode/amd.c
@@ -22,6 +22,8 @@
#include "private.h"
+#include "public/platform.h"
+
#define pr_debug(x...) ((void)0)
struct equiv_cpu_entry {
@@ -214,13 +216,15 @@ static enum microcode_match_result cf_check compare_patch(
return compare_header(new, old);
}
-static int cf_check apply_microcode(const struct microcode_patch *patch)
+static int cf_check apply_microcode(const struct microcode_patch *patch,
+ unsigned int flags)
{
int hw_err;
unsigned int cpu = smp_processor_id();
struct cpu_signature *sig = &per_cpu(cpu_sig, cpu);
uint32_t rev, old_rev = sig->rev;
enum microcode_match_result result = microcode_fits(patch);
+ bool ucode_force = flags == XENPF_UCODE_FORCE;
if ( result == MIS_UCODE )
return -EINVAL;
@@ -229,7 +233,7 @@ static int cf_check apply_microcode(const struct microcode_patch *patch)
* Allow application of the same revision to pick up SMT-specific changes
* even if the revision of the other SMT thread is already up-to-date.
*/
- if ( result == OLD_UCODE )
+ if ( !ucode_force && (result == SAME_UCODE || result == OLD_UCODE) )
return -EEXIST;
if ( check_final_patch_levels(sig) )
diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c
index 8a9e744489b9..2e3923152367 100644
--- a/xen/arch/x86/cpu/microcode/core.c
+++ b/xen/arch/x86/cpu/microcode/core.c
@@ -90,6 +90,16 @@ struct ucode_mod_blob {
size_t size;
};
+struct microcode_patch_with_flags {
+ unsigned int flags;
+ struct microcode_patch *patch;
+};
+
+struct microcode_nmi_patch_with_flags {
+ unsigned int flags;
+ const struct microcode_patch *patch;
+};
+
static struct ucode_mod_blob __initdata ucode_blob;
/*
* By default we will NOT parse the multiboot modules to see if there is
@@ -100,8 +110,6 @@ static bool __initdata ucode_scan;
/* By default, ucode loading is done in NMI handler */
static bool ucode_in_nmi = true;
-bool __read_mostly opt_ucode_allow_same;
-
/* Protected by microcode_mutex */
static struct microcode_patch *microcode_cache;
@@ -128,8 +136,6 @@ static int __init cf_check parse_ucode(const char *s)
if ( (val = parse_boolean("nmi", s, ss)) >= 0 )
ucode_in_nmi = val;
- else if ( (val = parse_boolean("allow-same", s, ss)) >= 0 )
- opt_ucode_allow_same = val;
else if ( !ucode_mod_forced ) /* Not forced by EFI */
{
if ( (val = parse_boolean("scan", s, ss)) >= 0 )
@@ -237,7 +243,11 @@ static DEFINE_PER_CPU(int, loading_err);
*/
static cpumask_t cpu_callin_map;
static atomic_t cpu_out, cpu_updated;
-static const struct microcode_patch *nmi_patch = ZERO_BLOCK_PTR;
+static struct microcode_nmi_patch_with_flags nmi_patch_with_flags =
+{
+ .flags = 0,
+ .patch = ZERO_BLOCK_PTR,
+};
/*
* Return a patch that covers current CPU. If there are multiple patches,
@@ -327,7 +337,8 @@ static bool cf_check wait_cpu_callout(unsigned int nr)
* If no patch is provided, the cached patch will be loaded. Microcode update
* during APs bringup and CPU resuming falls into this case.
*/
-static int microcode_update_cpu(const struct microcode_patch *patch)
+static int microcode_update_cpu(const struct microcode_patch *patch,
+ unsigned int flags)
{
int err;
@@ -335,10 +346,11 @@ static int microcode_update_cpu(const struct microcode_patch *patch)
spin_lock(µcode_mutex);
if ( patch )
- err = alternative_call(ucode_ops.apply_microcode, patch);
+ err = alternative_call(ucode_ops.apply_microcode, patch, flags);
else if ( microcode_cache )
{
- err = alternative_call(ucode_ops.apply_microcode, microcode_cache);
+ err = alternative_call(ucode_ops.apply_microcode, microcode_cache,
+ flags);
if ( err == -EIO )
{
microcode_free_patch(microcode_cache);
@@ -379,7 +391,8 @@ static int secondary_nmi_work(void)
return wait_for_state(LOADING_EXIT) ? 0 : -EBUSY;
}
-static int primary_thread_work(const struct microcode_patch *patch)
+static int primary_thread_work(const struct microcode_patch *patch,
+ unsigned int flags)
{
int ret;
@@ -388,7 +401,7 @@ static int primary_thread_work(const struct microcode_patch *patch)
if ( !wait_for_state(LOADING_ENTER) )
return -EBUSY;
- ret = alternative_call(ucode_ops.apply_microcode, patch);
+ ret = alternative_call(ucode_ops.apply_microcode, patch, flags);
if ( !ret )
atomic_inc(&cpu_updated);
atomic_inc(&cpu_out);
@@ -416,7 +429,8 @@ static int cf_check microcode_nmi_callback(
return 0;
if ( primary_cpu )
- ret = primary_thread_work(nmi_patch);
+ ret = primary_thread_work(nmi_patch_with_flags.patch,
+ nmi_patch_with_flags.flags);
else
ret = secondary_nmi_work();
this_cpu(loading_err) = ret;
@@ -446,7 +460,8 @@ static int secondary_thread_fn(void)
return this_cpu(loading_err);
}
-static int primary_thread_fn(const struct microcode_patch *patch)
+static int primary_thread_fn(const struct microcode_patch *patch,
+ unsigned int flags)
{
if ( !wait_for_state(LOADING_CALLIN) )
return -EBUSY;
@@ -466,10 +481,11 @@ static int primary_thread_fn(const struct microcode_patch *patch)
return this_cpu(loading_err);
}
- return primary_thread_work(patch);
+ return primary_thread_work(patch, flags);
}
-static int control_thread_fn(const struct microcode_patch *patch)
+static int control_thread_fn(const struct microcode_patch *patch,
+ unsigned int flags)
{
unsigned int cpu = smp_processor_id(), done;
unsigned long tick;
@@ -482,7 +498,8 @@ static int control_thread_fn(const struct microcode_patch *patch)
*/
watchdog_disable();
- nmi_patch = patch;
+ nmi_patch_with_flags.patch = patch;
+ nmi_patch_with_flags.flags = flags;
smp_wmb();
saved_nmi_callback = set_nmi_callback(microcode_nmi_callback);
@@ -498,7 +515,7 @@ static int control_thread_fn(const struct microcode_patch *patch)
goto out;
/* Control thread loads ucode first while others are in NMI handler. */
- ret = alternative_call(ucode_ops.apply_microcode, patch);
+ ret = alternative_call(ucode_ops.apply_microcode, patch, flags);
if ( !ret )
atomic_inc(&cpu_updated);
atomic_inc(&cpu_out);
@@ -544,17 +561,19 @@ static int control_thread_fn(const struct microcode_patch *patch)
set_nmi_callback(saved_nmi_callback);
smp_wmb();
- nmi_patch = ZERO_BLOCK_PTR;
+ nmi_patch_with_flags.patch = ZERO_BLOCK_PTR;
+ nmi_patch_with_flags.flags = 0;
watchdog_enable();
return ret;
}
-static int cf_check do_microcode_update(void *patch)
+static int cf_check do_microcode_update(void *_patch_with_flags)
{
unsigned int cpu = smp_processor_id();
int ret;
+ struct microcode_patch_with_flags * patch_with_flags = _patch_with_flags;
/*
* The control thread set state to coordinate ucode loading. Primary
@@ -562,9 +581,11 @@ static int cf_check do_microcode_update(void *patch)
* the completion of the ucode loading process.
*/
if ( cpu == cpumask_first(&cpu_online_map) )
- ret = control_thread_fn(patch);
+ ret = control_thread_fn(patch_with_flags->patch,
+ patch_with_flags->flags);
else if ( is_cpu_primary(cpu) )
- ret = primary_thread_fn(patch);
+ ret = primary_thread_fn(patch_with_flags->patch,
+ patch_with_flags->flags);
else
ret = secondary_thread_fn();
@@ -582,7 +603,8 @@ static long cf_check microcode_update_helper(void *data)
int ret;
struct ucode_buf *buffer = data;
unsigned int cpu, updated;
- struct microcode_patch *patch;
+ struct microcode_patch_with_flags patch_with_flags;
+ bool ucode_force = buffer->flags == XENPF_UCODE_FORCE;
/* cpu_online_map must not change during update */
if ( !get_cpu_maps() )
@@ -606,16 +628,17 @@ static long cf_check microcode_update_helper(void *data)
goto put;
}
- patch = parse_blob(buffer->buffer, buffer->len);
+ patch_with_flags.patch = parse_blob(buffer->buffer, buffer->len);
+ patch_with_flags.flags = buffer->flags;
xfree(buffer);
- if ( IS_ERR(patch) )
+ if ( IS_ERR(patch_with_flags.patch) )
{
- ret = PTR_ERR(patch);
+ ret = PTR_ERR(patch_with_flags.patch);
printk(XENLOG_WARNING "Parsing microcode blob error %d\n", ret);
goto put;
}
- if ( !patch )
+ if ( !patch_with_flags.patch )
{
printk(XENLOG_WARNING "microcode: couldn't find any matching ucode in "
"the provided blob!\n");
@@ -632,17 +655,17 @@ static long cf_check microcode_update_helper(void *data)
{
enum microcode_match_result result;
- result = alternative_call(ucode_ops.compare_patch, patch,
- microcode_cache);
+ result = alternative_call(ucode_ops.compare_patch,
+ patch_with_flags.patch, microcode_cache);
if ( result != NEW_UCODE &&
- !(opt_ucode_allow_same && result == SAME_UCODE) )
+ !(ucode_force && (result == OLD_UCODE || result == SAME_UCODE)) )
{
spin_unlock(µcode_mutex);
printk(XENLOG_WARNING
"microcode: couldn't find any newer%s revision in the provided blob!\n",
- opt_ucode_allow_same ? " (or the same)" : "");
- microcode_free_patch(patch);
+ ucode_force? " (or a valid)" : "");
+ microcode_free_patch(patch_with_flags.patch);
ret = -EEXIST;
goto put;
@@ -674,13 +697,13 @@ static long cf_check microcode_update_helper(void *data)
* this requirement can be relaxed in the future. Right now, this is
* conservative and good.
*/
- ret = stop_machine_run(do_microcode_update, patch, NR_CPUS);
+ ret = stop_machine_run(do_microcode_update, &patch_with_flags, NR_CPUS);
updated = atomic_read(&cpu_updated);
if ( updated > 0 )
{
spin_lock(µcode_mutex);
- microcode_update_cache(patch);
+ microcode_update_cache(patch_with_flags.patch);
spin_unlock(µcode_mutex);
/*
@@ -697,7 +720,7 @@ static long cf_check microcode_update_helper(void *data)
alternative_vcall(ctxt_switch_masking, current);
}
else
- microcode_free_patch(patch);
+ microcode_free_patch(patch_with_flags.patch);
if ( updated && updated != nr_cores )
printk(XENLOG_ERR "ERROR: Updating microcode succeeded on %u cores and failed\n"
@@ -775,7 +798,7 @@ int microcode_update_one(void)
if ( !ucode_ops.apply_microcode )
return -EOPNOTSUPP;
- return microcode_update_cpu(NULL);
+ return microcode_update_cpu(NULL, 0);
}
static int __init early_update_cache(const void *data, size_t len)
@@ -858,7 +881,7 @@ static int __init early_microcode_update_cpu(void)
if ( !patch )
return -ENOENT;
- return microcode_update_cpu(patch);
+ return microcode_update_cpu(patch, 0);
}
int __init early_microcode_init(unsigned long *module_map,
diff --git a/xen/arch/x86/cpu/microcode/intel.c b/xen/arch/x86/cpu/microcode/intel.c
index f505aa1b7888..cb6e906481a4 100644
--- a/xen/arch/x86/cpu/microcode/intel.c
+++ b/xen/arch/x86/cpu/microcode/intel.c
@@ -29,6 +29,8 @@
#include "private.h"
+#include "public/platform.h"
+
#define pr_debug(x...) ((void)0)
struct microcode_patch {
@@ -284,21 +286,22 @@ static enum microcode_match_result cf_check compare_patch(
return compare_revisions(old->rev, new->rev);
}
-static int cf_check apply_microcode(const struct microcode_patch *patch)
+static int cf_check apply_microcode(const struct microcode_patch *patch,
+ unsigned int flags)
{
uint64_t msr_content;
unsigned int cpu = smp_processor_id();
struct cpu_signature *sig = &this_cpu(cpu_sig);
uint32_t rev, old_rev = sig->rev;
enum microcode_match_result result;
+ bool ucode_force = flags == XENPF_UCODE_FORCE;
result = microcode_update_match(patch);
if ( result == MIS_UCODE )
return -EINVAL;
- if ( result == OLD_UCODE ||
- (result == SAME_UCODE && !opt_ucode_allow_same) )
+ if ( !ucode_force && (result == SAME_UCODE || result == OLD_UCODE) )
return -EEXIST;
wbinvd();
diff --git a/xen/arch/x86/cpu/microcode/private.h b/xen/arch/x86/cpu/microcode/private.h
index da556fe5060a..017889e1b58d 100644
--- a/xen/arch/x86/cpu/microcode/private.h
+++ b/xen/arch/x86/cpu/microcode/private.h
@@ -3,8 +3,6 @@
#include <asm/microcode.h>
-extern bool opt_ucode_allow_same;
-
enum microcode_match_result {
OLD_UCODE, /* signature matched, but revision id is older */
SAME_UCODE, /* signature matched, but revision id is the same */
@@ -50,7 +48,8 @@ struct microcode_ops {
* Attempt to load the provided patch into the CPU. Returns an error if
* anything didn't go as expected.
*/
- int (*apply_microcode)(const struct microcode_patch *patch);
+ int (*apply_microcode)(const struct microcode_patch *patch,
+ unsigned int flags);
/*
* Given two patches, are they both applicable to the current CPU, and is
--
2.42.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v5 3/4] x86/ucode: Introduce --force option to xen-ucode
2024-07-12 13:07 ` [PATCH v5 3/4] x86/ucode: Introduce --force option to xen-ucode Fouad Hilly
@ 2024-07-12 13:27 ` Jan Beulich
2024-07-23 9:39 ` Fouad Hilly
0 siblings, 1 reply; 13+ messages in thread
From: Jan Beulich @ 2024-07-12 13:27 UTC (permalink / raw)
To: Fouad Hilly; +Cc: Anthony PERARD, Juergen Gross, Andrew Cooper, xen-devel
On 12.07.2024 15:07, Fouad Hilly wrote:
> @@ -79,6 +81,8 @@ static void usage(FILE *stream, const char *name)
> "options:\n"
> " -h, --help display this help\n"
> " -s, --show-cpu-info show CPU information\n"
> + " -f, --force skip certain checks; do not use unless you"
> + "know exactly what you are doing\n"
Would this output line perhaps better be wrapped explicitly, to avoid
odd wrapping effects on terminals not wider than 80 chars? In any event
there's a blank missing at the present source wrapping point.
Jan
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/4] x86/ucode: refactor xen-ucode to utilize getopt
2024-07-12 13:07 ` [PATCH v5 2/4] x86/ucode: refactor xen-ucode to utilize getopt Fouad Hilly
@ 2024-07-16 14:51 ` Jan Beulich
2024-07-23 9:41 ` Fouad Hilly
2024-07-24 16:55 ` Anthony PERARD
1 sibling, 1 reply; 13+ messages in thread
From: Jan Beulich @ 2024-07-16 14:51 UTC (permalink / raw)
To: Fouad Hilly; +Cc: Anthony PERARD, xen-devel
On 12.07.2024 15:07, Fouad Hilly wrote:
> --- a/tools/misc/xen-ucode.c
> +++ b/tools/misc/xen-ucode.c
> @@ -11,6 +11,7 @@
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <xenctrl.h>
> +#include <getopt.h>
>
> static xc_interface *xch;
>
> @@ -71,12 +72,29 @@ static void show_curr_cpu(FILE *f)
> }
> }
>
> +static void usage(FILE *stream, const char *name)
> +{
> + fprintf(stream,
> + "%s: Xen microcode updating tool\n"
> + "options:\n"
> + " -h, --help display this help\n"
> + " -s, --show-cpu-info show CPU information\n"
> + "Usage: %s [microcode file] [options]\n", name, name);
Isn't it more like [microcode file | options] at this point? Even when
--force support is added, neither of the two options here go together
with a microcode file.
> @@ -86,22 +104,34 @@ int main(int argc, char *argv[])
> exit(1);
> }
>
> - if ( argc < 2 )
> + while ( (opt = getopt_long(argc, argv, "hs", options, NULL)) != -1 )
> {
> - fprintf(stderr,
> - "xen-ucode: Xen microcode updating tool\n"
> - "Usage: %s [<microcode file> | show-cpu-info]\n", argv[0]);
> - show_curr_cpu(stderr);
> - exit(2);
> + switch (opt)
Nit (style): Missing blanks inside the parentheses.
Jan
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 4/4] x86/ucode: Utilize ucode_force and remove opt_ucode_allow_same
2024-07-12 13:07 ` [PATCH v5 4/4] x86/ucode: Utilize ucode_force and remove opt_ucode_allow_same Fouad Hilly
@ 2024-07-16 14:59 ` Jan Beulich
2024-07-23 9:52 ` Fouad Hilly
0 siblings, 1 reply; 13+ messages in thread
From: Jan Beulich @ 2024-07-16 14:59 UTC (permalink / raw)
To: Fouad Hilly
Cc: Andrew Cooper, Julien Grall, Stefano Stabellini,
Roger Pau Monné, xen-devel
On 12.07.2024 15:07, Fouad Hilly wrote:
> --- a/xen/arch/x86/cpu/microcode/core.c
> +++ b/xen/arch/x86/cpu/microcode/core.c
> @@ -90,6 +90,16 @@ struct ucode_mod_blob {
> size_t size;
> };
>
> +struct microcode_patch_with_flags {
> + unsigned int flags;
> + struct microcode_patch *patch;
> +};
> +
> +struct microcode_nmi_patch_with_flags {
> + unsigned int flags;
> + const struct microcode_patch *patch;
> +};
Why two different structures? I have to admit that I can't spot where the
difference (const or not) would matter?
Also for an internal struct I don't think you need the microcode_ prefixes.
> @@ -284,21 +286,22 @@ static enum microcode_match_result cf_check compare_patch(
> return compare_revisions(old->rev, new->rev);
> }
>
> -static int cf_check apply_microcode(const struct microcode_patch *patch)
> +static int cf_check apply_microcode(const struct microcode_patch *patch,
> + unsigned int flags)
> {
> uint64_t msr_content;
> unsigned int cpu = smp_processor_id();
> struct cpu_signature *sig = &this_cpu(cpu_sig);
> uint32_t rev, old_rev = sig->rev;
> enum microcode_match_result result;
> + bool ucode_force = flags == XENPF_UCODE_FORCE;
Why == ? The term "flags" usually stands for there being multiple boolean
indicators in a single value. That would demand use of & here.
Jan
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 3/4] x86/ucode: Introduce --force option to xen-ucode
2024-07-12 13:27 ` Jan Beulich
@ 2024-07-23 9:39 ` Fouad Hilly
0 siblings, 0 replies; 13+ messages in thread
From: Fouad Hilly @ 2024-07-23 9:39 UTC (permalink / raw)
To: Jan Beulich; +Cc: Anthony PERARD, Juergen Gross, Andrew Cooper, xen-devel
On Fri, Jul 12, 2024 at 2:27 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 12.07.2024 15:07, Fouad Hilly wrote:
> > @@ -79,6 +81,8 @@ static void usage(FILE *stream, const char *name)
> > "options:\n"
> > " -h, --help display this help\n"
> > " -s, --show-cpu-info show CPU information\n"
> > + " -f, --force skip certain checks; do not use unless you"
> > + "know exactly what you are doing\n"
>
> Would this output line perhaps better be wrapped explicitly, to avoid
> odd wrapping effects on terminals not wider than 80 chars? In any event
> there's a blank missing at the present source wrapping point.
Sure, I will wrap it in v6
>
> Jan
Thanks,
Fouad
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/4] x86/ucode: refactor xen-ucode to utilize getopt
2024-07-16 14:51 ` Jan Beulich
@ 2024-07-23 9:41 ` Fouad Hilly
0 siblings, 0 replies; 13+ messages in thread
From: Fouad Hilly @ 2024-07-23 9:41 UTC (permalink / raw)
To: Jan Beulich; +Cc: Anthony PERARD, xen-devel
On Tue, Jul 16, 2024 at 3:51 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 12.07.2024 15:07, Fouad Hilly wrote:
> > --- a/tools/misc/xen-ucode.c
> > +++ b/tools/misc/xen-ucode.c
> > @@ -11,6 +11,7 @@
> > #include <sys/stat.h>
> > #include <fcntl.h>
> > #include <xenctrl.h>
> > +#include <getopt.h>
> >
> > static xc_interface *xch;
> >
> > @@ -71,12 +72,29 @@ static void show_curr_cpu(FILE *f)
> > }
> > }
> >
> > +static void usage(FILE *stream, const char *name)
> > +{
> > + fprintf(stream,
> > + "%s: Xen microcode updating tool\n"
> > + "options:\n"
> > + " -h, --help display this help\n"
> > + " -s, --show-cpu-info show CPU information\n"
> > + "Usage: %s [microcode file] [options]\n", name, name);
>
> Isn't it more like [microcode file | options] at this point? Even when
> --force support is added, neither of the two options here go together
> with a microcode file.
Yes, I will fix it in v6
>
> > @@ -86,22 +104,34 @@ int main(int argc, char *argv[])
> > exit(1);
> > }
> >
> > - if ( argc < 2 )
> > + while ( (opt = getopt_long(argc, argv, "hs", options, NULL)) != -1 )
> > {
> > - fprintf(stderr,
> > - "xen-ucode: Xen microcode updating tool\n"
> > - "Usage: %s [<microcode file> | show-cpu-info]\n", argv[0]);
> > - show_curr_cpu(stderr);
> > - exit(2);
> > + switch (opt)
>
> Nit (style): Missing blanks inside the parentheses.
Will be fixed in v6
>
> Jan
Thanks,
Fouad
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 4/4] x86/ucode: Utilize ucode_force and remove opt_ucode_allow_same
2024-07-16 14:59 ` Jan Beulich
@ 2024-07-23 9:52 ` Fouad Hilly
0 siblings, 0 replies; 13+ messages in thread
From: Fouad Hilly @ 2024-07-23 9:52 UTC (permalink / raw)
To: Jan Beulich
Cc: Andrew Cooper, Julien Grall, Stefano Stabellini,
Roger Pau Monné, xen-devel
[-- Attachment #1: Type: text/plain, Size: 1837 bytes --]
On Tue, Jul 16, 2024 at 3:59 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 12.07.2024 15:07, Fouad Hilly wrote:
> > --- a/xen/arch/x86/cpu/microcode/core.c
> > +++ b/xen/arch/x86/cpu/microcode/core.c
> > @@ -90,6 +90,16 @@ struct ucode_mod_blob {
> > size_t size;
> > };
> >
> > +struct microcode_patch_with_flags {
> > + unsigned int flags;
> > + struct microcode_patch *patch;
> > +};
> > +
> > +struct microcode_nmi_patch_with_flags {
> > + unsigned int flags;
> > + const struct microcode_patch *patch;
> > +};
>
> Why two different structures? I have to admit that I can't spot where the
> difference (const or not) would matter?
I will remove the struct with const and update:
static int control_thread_fn(*const struct microcode_patch *patch*,
unsigned int flags)
>
> Also for an internal struct I don't think you need the microcode_
prefixes.
I will remove microcode_prefixes.
>
> > @@ -284,21 +286,22 @@ static enum microcode_match_result cf_check
compare_patch(
> > return compare_revisions(old->rev, new->rev);
> > }
> >
> > -static int cf_check apply_microcode(const struct microcode_patch
*patch)
> > +static int cf_check apply_microcode(const struct microcode_patch
*patch,
> > + unsigned int flags)
> > {
> > uint64_t msr_content;
> > unsigned int cpu = smp_processor_id();
> > struct cpu_signature *sig = &this_cpu(cpu_sig);
> > uint32_t rev, old_rev = sig->rev;
> > enum microcode_match_result result;
> > + bool ucode_force = flags == XENPF_UCODE_FORCE;
>
> Why == ? The term "flags" usually stands for there being multiple boolean
> indicators in a single value. That would demand use of & here.
Will be fixed in v6
>
> Jan
Thanks,
Fouad
[-- Attachment #2: Type: text/html, Size: 2379 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/4] x86/ucode: refactor xen-ucode to utilize getopt
2024-07-12 13:07 ` [PATCH v5 2/4] x86/ucode: refactor xen-ucode to utilize getopt Fouad Hilly
2024-07-16 14:51 ` Jan Beulich
@ 2024-07-24 16:55 ` Anthony PERARD
2024-08-19 8:56 ` Fouad Hilly
1 sibling, 1 reply; 13+ messages in thread
From: Anthony PERARD @ 2024-07-24 16:55 UTC (permalink / raw)
To: Fouad Hilly; +Cc: xen-devel
On Fri, Jul 12, 2024 at 02:07:47PM +0100, Fouad Hilly wrote:
> diff --git a/tools/misc/xen-ucode.c b/tools/misc/xen-ucode.c
> index 390969db3d1c..8de82e5b8a10 100644
> --- a/tools/misc/xen-ucode.c
> +++ b/tools/misc/xen-ucode.c
> @@ -71,12 +72,29 @@ static void show_curr_cpu(FILE *f)
> }
> }
>
> +static void usage(FILE *stream, const char *name)
> +{
> + fprintf(stream,
> + "%s: Xen microcode updating tool\n"
> + "options:\n"
> + " -h, --help display this help\n"
> + " -s, --show-cpu-info show CPU information\n"
> + "Usage: %s [microcode file] [options]\n", name, name);
FYI, I disagree with Andy about the order of this message. First is
"Usage:" which explain where the option (dash-prefixed) can go, and
which are the mandatory arguments, sometime having all the single-letter
option in this line as well. Then there's an explanation of what the
options are. I've check `bash`, `cat`, `xl`, `gcc`.
I wonder which CLI program would print the minimum amount of information
on how to run the program as the last line of the help message.
> @@ -86,22 +104,34 @@ int main(int argc, char *argv[])
> exit(1);
> }
>
> - if ( argc < 2 )
> + while ( (opt = getopt_long(argc, argv, "hs", options, NULL)) != -1 )
> {
> - fprintf(stderr,
> - "xen-ucode: Xen microcode updating tool\n"
> - "Usage: %s [<microcode file> | show-cpu-info]\n", argv[0]);
> - show_curr_cpu(stderr);
> - exit(2);
> + switch (opt)
> + {
> + case 'h':
> + usage(stdout, argv[0]);
> + exit(EXIT_SUCCESS);
> +
> + case 's':
> + show_curr_cpu(stdout);
> + exit(EXIT_SUCCESS);
> +
> + default:
> + goto ext_err;
> + }
> }
>
> - if ( !strcmp(argv[1], "show-cpu-info") )
> + if ( optind == argc )
> + goto ext_err;
> +
> + /* For backwards compatibility to the pre-getopt() cmdline handling */
> + if ( !strcmp(argv[optind], "show-cpu-info") )
> {
> show_curr_cpu(stdout);
> return 0;
> }
>
> - filename = argv[1];
> + filename = argv[optind];
> fd = open(filename, O_RDONLY);
> if ( fd < 0 )
> {
> @@ -146,4 +176,10 @@ int main(int argc, char *argv[])
> close(fd);
>
> return 0;
> +
> + ext_err:
> + fprintf(stderr,
> + "%s: unable to process command line arguments\n", argv[0]);
A nice to have would be to have a better error message to point out
what's wrong with the arguments. For that you could print the error
message before "goto ext_err". One would be "unknown option" for the
first goto, and "missing microcode file" for the second goto, that is
instead of printing this more generic error message.
Cheers,
--
Anthony Perard | Vates XCP-ng Developer
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/4] x86/ucode: refactor xen-ucode to utilize getopt
2024-07-24 16:55 ` Anthony PERARD
@ 2024-08-19 8:56 ` Fouad Hilly
0 siblings, 0 replies; 13+ messages in thread
From: Fouad Hilly @ 2024-08-19 8:56 UTC (permalink / raw)
To: Anthony PERARD; +Cc: xen-devel
[-- Attachment #1: Type: text/plain, Size: 3863 bytes --]
On Wed, Jul 24, 2024 at 5:55 PM Anthony PERARD <anthony.perard@vates.tech>
wrote:
> On Fri, Jul 12, 2024 at 02:07:47PM +0100, Fouad Hilly wrote:
> > diff --git a/tools/misc/xen-ucode.c b/tools/misc/xen-ucode.c
> > index 390969db3d1c..8de82e5b8a10 100644
> > --- a/tools/misc/xen-ucode.c
> > +++ b/tools/misc/xen-ucode.c
> > @@ -71,12 +72,29 @@ static void show_curr_cpu(FILE *f)
> > }
> > }
> >
> > +static void usage(FILE *stream, const char *name)
> > +{
> > + fprintf(stream,
> > + "%s: Xen microcode updating tool\n"
> > + "options:\n"
> > + " -h, --help display this help\n"
> > + " -s, --show-cpu-info show CPU information\n"
> > + "Usage: %s [microcode file] [options]\n", name, name);
>
> FYI, I disagree with Andy about the order of this message. First is
> "Usage:" which explain where the option (dash-prefixed) can go, and
> which are the mandatory arguments, sometime having all the single-letter
> option in this line as well. Then there's an explanation of what the
> options are. I've check `bash`, `cat`, `xl`, `gcc`.
>
> I wonder which CLI program would print the minimum amount of information
> on how to run the program as the last line of the help message.
>
My Bad, I misinterpreted Andy's comment, will fix in v7:
static void usage(FILE *stream, const char *name)
{
fprintf(stream,
"%s: Xen microcode updating tool\n"
"Usage: %s [options | microcode-file]\n"
"options:\n"
" -h, --help display this help\n"
" -s, --show-cpu-info show CPU information\n",
name, name);
show_curr_cpu(stream);
}
>
> > @@ -86,22 +104,34 @@ int main(int argc, char *argv[])
> > exit(1);
> > }
> >
> > - if ( argc < 2 )
> > + while ( (opt = getopt_long(argc, argv, "hs", options, NULL)) != -1 )
> > {
> > - fprintf(stderr,
> > - "xen-ucode: Xen microcode updating tool\n"
> > - "Usage: %s [<microcode file> | show-cpu-info]\n",
> argv[0]);
> > - show_curr_cpu(stderr);
> > - exit(2);
> > + switch (opt)
> > + {
> > + case 'h':
> > + usage(stdout, argv[0]);
> > + exit(EXIT_SUCCESS);
> > +
> > + case 's':
> > + show_curr_cpu(stdout);
> > + exit(EXIT_SUCCESS);
> > +
> > + default:
> > + goto ext_err;
> > + }
> > }
> >
> > - if ( !strcmp(argv[1], "show-cpu-info") )
> > + if ( optind == argc )
> > + goto ext_err;
> > +
> > + /* For backwards compatibility to the pre-getopt() cmdline handling
> */
> > + if ( !strcmp(argv[optind], "show-cpu-info") )
> > {
> > show_curr_cpu(stdout);
> > return 0;
> > }
> >
> > - filename = argv[1];
> > + filename = argv[optind];
> > fd = open(filename, O_RDONLY);
> > if ( fd < 0 )
> > {
> > @@ -146,4 +176,10 @@ int main(int argc, char *argv[])
> > close(fd);
> >
> > return 0;
> > +
> > + ext_err:
> > + fprintf(stderr,
> > + "%s: unable to process command line arguments\n", argv[0]);
>
> A nice to have would be to have a better error message to point out
> what's wrong with the arguments. For that you could print the error
> message before "goto ext_err". One would be "unknown option" for the
> first goto, and "missing microcode file" for the second goto, that is
> instead of printing this more generic error message.
>
Sure, I will have specific error messages instead of generic one in v7
>
> Cheers,
>
> --
>
> Anthony Perard | Vates XCP-ng Developer
>
> XCP-ng & Xen Orchestra - Vates solutions
>
> web: https://vates.tech
Thanks,
Fouad
[-- Attachment #2: Type: text/html, Size: 7048 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2024-08-19 8:56 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-12 13:07 [PATCH v5 0/4] x86/xen-ucode: Introduce --force option Fouad Hilly
2024-07-12 13:07 ` [PATCH v5 1/4] x86/ucode: Introduce XENPF_microcode_update2 with flags parameter Fouad Hilly
2024-07-12 13:07 ` [PATCH v5 2/4] x86/ucode: refactor xen-ucode to utilize getopt Fouad Hilly
2024-07-16 14:51 ` Jan Beulich
2024-07-23 9:41 ` Fouad Hilly
2024-07-24 16:55 ` Anthony PERARD
2024-08-19 8:56 ` Fouad Hilly
2024-07-12 13:07 ` [PATCH v5 3/4] x86/ucode: Introduce --force option to xen-ucode Fouad Hilly
2024-07-12 13:27 ` Jan Beulich
2024-07-23 9:39 ` Fouad Hilly
2024-07-12 13:07 ` [PATCH v5 4/4] x86/ucode: Utilize ucode_force and remove opt_ucode_allow_same Fouad Hilly
2024-07-16 14:59 ` Jan Beulich
2024-07-23 9:52 ` Fouad Hilly
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.