[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241128222948.579920-4-darwi@linutronix.de>
Date: Thu, 28 Nov 2024 23:29:38 +0100
From: "Ahmed S. Darwish" <darwi@...utronix.de>
To: Borislav Petkov <bp@...en8.de>,
Dave Hansen <dave.hansen@...ux.intel.com>,
"H. Peter Anvin" <hpa@...or.com>
Cc: Thomas Gleixner <tglx@...utronix.de>,
John Ogness <john.ogness@...utronix.de>,
linux-kernel@...r.kernel.org,
x86@...nel.org,
x86-cpuid@...ts.linux.dev,
"Ahmed S. Darwish" <darwi@...utronix.de>
Subject: [PATCH v1 03/13] tools/x86/kcpuid: Fix error handling
Error handling in kcpuid is unreliable:
- on malloc() failures, the code prints an error then just goes on.
- Error messages are printed to standard output, and thus getting
mixed with cpuid flags listings.
Introduce pr_err() and pr_warn() to automatically direct error and
warning messages to standard error. Use such macros throughout the
code.
Introduce pr_err_exit(), which is like pr_err(), but with the addition
of process termination through exit(3). Use pr_err_exit() in case of
malloc() failures; further commits will utilize it further.
Fixes: c6b2f240bf8d ("tools/x86: Add a kcpuid tool to show raw CPU features")
Reported-by: Remington Brasga <rbrasga@....edu>
Closes: https://lkml.kernel.org/r/20240926223557.2048-1-rbrasga@uci.edu
Signed-off-by: Ahmed S. Darwish <darwi@...utronix.de>
---
tools/arch/x86/kcpuid/kcpuid.c | 54 +++++++++++++++++++++++++++-------
1 file changed, 43 insertions(+), 11 deletions(-)
diff --git a/tools/arch/x86/kcpuid/kcpuid.c b/tools/arch/x86/kcpuid/kcpuid.c
index 62a77509a5b5..1ec60c892206 100644
--- a/tools/arch/x86/kcpuid/kcpuid.c
+++ b/tools/arch/x86/kcpuid/kcpuid.c
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE
+#include <errno.h>
#include <getopt.h>
+#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -111,6 +113,36 @@ static inline bool has_subleafs(u32 f)
return false;
}
+/**
+ * pr_err - Print passed error message to stderr
+ */
+static void pr_err(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
+/**
+ * pr_warn - Print passed warning message to stderr
+ */
+#define pr_warn(...) pr_err(__VA_ARGS__)
+
+/**
+ * pr_err_exit - Print passed error message to stderr, then exit
+ *
+ * @ecode: One-byte exit code. errno can be passed here as
+ * the passed value is quickly cached.
+ */
+#define pr_err_exit(ecode, ...) do { \
+ int __ecode = (ecode); \
+ \
+ pr_err(__VA_ARGS__); \
+ exit(__ecode); \
+} while (0)
+
static void leaf_print_raw(struct subleaf *leaf)
{
if (has_subleafs(leaf->index)) {
@@ -145,14 +177,14 @@ static bool cpuid_store(struct cpuid_range *range, u32 f, int subleaf,
if (!func->leafs) {
func->leafs = malloc(sizeof(struct subleaf));
if (!func->leafs)
- perror("malloc func leaf");
+ pr_err_exit(errno, "malloc func leaf");
func->nr = 1;
} else {
s = func->nr;
func->leafs = realloc(func->leafs, (s + 1) * sizeof(*leaf));
if (!func->leafs)
- perror("realloc f->leafs");
+ pr_err_exit(errno, "realloc f->leafs");
func->nr++;
}
@@ -211,7 +243,7 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)
range = malloc(sizeof(struct cpuid_range));
if (!range)
- perror("malloc range");
+ pr_err_exit(errno, "malloc range");
if (input_eax & 0x80000000)
range->is_ext = true;
@@ -220,7 +252,7 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)
range->funcs = malloc(sizeof(struct cpuid_func) * idx_func);
if (!range->funcs)
- perror("malloc range->funcs");
+ pr_err_exit(errno, "malloc range->funcs");
range->nr = idx_func;
memset(range->funcs, 0, sizeof(struct cpuid_func) * idx_func);
@@ -395,8 +427,8 @@ static int parse_line(char *line)
return 0;
err_exit:
- printf("Warning: wrong line format:\n");
- printf("\tline[%d]: %s\n", flines, line);
+ pr_warn("Warning: wrong line format:\n"
+ "\tline[%d]: %s\n", flines, line);
return -1;
}
@@ -419,7 +451,7 @@ static void parse_text(void)
}
if (!file) {
- printf("Fail to open '%s'\n", filename);
+ pr_err("Fail to open '%s'\n", filename);
return;
}
@@ -530,7 +562,7 @@ static inline struct cpuid_func *index_to_func(u32 index)
func_idx = index & 0xffff;
if ((func_idx + 1) > (u32)range->nr) {
- printf("ERR: invalid input index (0x%x)\n", index);
+ pr_err("ERR: invalid input index (0x%x)\n", index);
return NULL;
}
return &range->funcs[func_idx];
@@ -562,7 +594,7 @@ static void show_info(void)
return;
}
- printf("ERR: invalid input subleaf (0x%x)\n", user_sub);
+ pr_err("ERR: invalid input subleaf (0x%x)\n", user_sub);
}
show_func(func);
@@ -593,7 +625,7 @@ static void setup_platform_cpuid(void)
static void usage(void)
{
- printf("kcpuid [-abdfhr] [-l leaf] [-s subleaf]\n"
+ pr_err("kcpuid [-abdfhr] [-l leaf] [-s subleaf]\n"
"\t-a|--all Show both bit flags and complex bit fields info\n"
"\t-b|--bitflags Show boolean flags only\n"
"\t-d|--detail Show details of the flag/fields (default)\n"
@@ -652,7 +684,7 @@ static int parse_options(int argc, char *argv[])
user_sub = strtoul(optarg, NULL, 0);
break;
default:
- printf("%s: Invalid option '%c'\n", argv[0], optopt);
+ pr_err("%s: Invalid option '%c'\n", argv[0], optopt);
return -1;
}
--
2.46.2
Powered by blists - more mailing lists