* [PATCH kvmtool v2 0/7] x86 compilation fixes and arm64 PMU improvements
@ 2026-06-18 15:49 Alexandru Elisei
2026-06-18 15:49 ` [PATCH kvmtool v2 1/7] x86: Define bioscall only in 32-bit mode Alexandru Elisei
` (6 more replies)
0 siblings, 7 replies; 9+ messages in thread
From: Alexandru Elisei @ 2026-06-18 15:49 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
v1 here [1].
v1 was sent to fix this compilation error:
disk/core.c: In function ‘disk_img_name_parser’:
disk/core.c:27:21: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
27 | sep = strstr(arg, ":");
| ^
fixed in patches #2 and #3.
Working on v2 found another one:
x86/include/kvm/bios.h:91:43: error: ‘regparm’ attribute ignored [-Werror=attributes]
91 | extern bioscall void int10_handler(struct biosregs *regs);
| ^~~~~~~~
which is fixed in patch #1.
The remaining of the patches are there to improve PMU initialisation and
error reporting.
Tested on arm64, with and without hugetlbfs, with and without a PMU. Also
tested on arm64 using scsi-virtio (got it working in v2, I couldn't get
scsi-virtio working for v1, most likely user error).
Tested on x86_64 by booting a VM. Don't have an x86_32 machine to do the
same, but I did cross-compile for x86_32.
Changes in v2:
- Patch #1 ("x86: Define bioscall only in 32-bit mode") is new. The bug
that it fixes was probably triggered when I updated the gcc compiler.
- pmu__init() is now called from gic__init_gic() (Will).
- die_perror() prints the original errno is vsnprintf() fails (Will).
[1] https://lore.kernel.org/kvm/20260323150221.49256-1-alexandru.elisei@arm.com/
Alexandru Elisei (7):
x86: Define bioscall only in 32-bit mode
virtio: Do not modify const strings in virtio_9p_rootdir_parser()
disk/core: Do not modify const strings in disk_img_name_parser()
arm64: Initialise the PMU after the GIC
util: Set exit status to errno in die_perror()
util: Allow die_perror() to take a variable list of argument
arm64: Improve KVM_ARM_VCPU_PMU_V3_CTRL diagnostics
arm64/gic.c | 9 +++++-
arm64/include/asm/pmu.h | 3 ++
arm64/pmu.c | 59 ++++++++++++++++++++++++++++------------
disk/core.c | 44 ++++++++++++++++++++----------
include/kvm/disk-image.h | 6 ++--
include/kvm/util.h | 2 +-
util/util.c | 21 ++++++++++++--
virtio/9p.c | 21 +++++++++-----
x86/include/kvm/bios.h | 4 +++
9 files changed, 123 insertions(+), 46 deletions(-)
base-commit: 6c2de8d9531c7e9aad7ac6701e848bedb3f1d3a4
--
2.54.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH kvmtool v2 1/7] x86: Define bioscall only in 32-bit mode
2026-06-18 15:49 [PATCH kvmtool v2 0/7] x86 compilation fixes and arm64 PMU improvements Alexandru Elisei
@ 2026-06-18 15:49 ` Alexandru Elisei
2026-06-18 15:49 ` [PATCH kvmtool v2 2/7] virtio: Do not modify const strings in virtio_9p_rootdir_parser() Alexandru Elisei
` (5 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Alexandru Elisei @ 2026-06-18 15:49 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
The gcc online docs define the behaviour of the regparm attribute for
x86-32 targets [1], and there's no mention of the behaviour for the 64-bit
version of the architecure.
gcc version 16.1 throws this error when compiling for x86-64:
x86/include/kvm/bios.h:91:43: error: ‘regparm’ attribute ignored [-Werror=attributes]
91 | extern bioscall void int10_handler(struct biosregs *regs);
| ^~~~~~~~
but there's no such error with gcc version 14.2.
This patch author assumes that somewhere between gcc 14.2 and 16.1 the
compiler behaviour was modified to treat the regparm attribute on x86_64
as unused. Fix the compilation error by using it only for the 32-bit
version of the x86 architecture.
[1] https://gcc.gnu.org/onlinedocs/gcc-16.1.0/gcc/x86-Attributes.html#index-regparm_002c-x86
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
x86/include/kvm/bios.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/x86/include/kvm/bios.h b/x86/include/kvm/bios.h
index 6f4338d50717..76beb2e0a46b 100644
--- a/x86/include/kvm/bios.h
+++ b/x86/include/kvm/bios.h
@@ -62,11 +62,15 @@
#define MB_BIOS_SS 0xfff7
#define MB_BIOS_SP 0x40
+#ifdef CONFIG_X86_32
/*
* When interfere with assembler code we need to be sure how
* arguments are passed in real mode.
*/
#define bioscall __attribute__((regparm(3)))
+#else
+#define bioscall
+#endif
#ifndef __ASSEMBLER__
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH kvmtool v2 2/7] virtio: Do not modify const strings in virtio_9p_rootdir_parser()
2026-06-18 15:49 [PATCH kvmtool v2 0/7] x86 compilation fixes and arm64 PMU improvements Alexandru Elisei
2026-06-18 15:49 ` [PATCH kvmtool v2 1/7] x86: Define bioscall only in 32-bit mode Alexandru Elisei
@ 2026-06-18 15:49 ` Alexandru Elisei
2026-06-18 15:49 ` [PATCH kvmtool v2 3/7] disk/core: Do not modify const strings in disk_img_name_parser() Alexandru Elisei
` (4 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Alexandru Elisei @ 2026-06-18 15:49 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
Even though @arg is of type const char *, virtio_9p_rootdir_parser()
modifies it it if a tag name is specified, leading to the following
compilation error on an x86_64 machine with gcc 15.2.1:
virtio/9p.c:1503:18: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
1503 | tag_name = strstr(arg, ",");
Fix it by copying @arg to a local string, which can then be modified
in-place.
Also use die_perror() if realpath() fails, to provide more information to
the user.
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
virtio/9p.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/virtio/9p.c b/virtio/9p.c
index e6f669c49895..cf3e547d3173 100644
--- a/virtio/9p.c
+++ b/virtio/9p.c
@@ -1491,25 +1491,32 @@ struct virtio_ops p9_dev_virtio_ops = {
int virtio_9p_rootdir_parser(const struct option *opt, const char *arg, int unset)
{
- char *tag_name;
- char tmp[PATH_MAX];
struct kvm *kvm = opt->ptr;
+ char *tag_name, *copy;
+ char path[PATH_MAX];
+ copy = strdup(arg);
+ if (!copy)
+ die_perror("strdup");
/*
* 9p dir can be of the form dirname,tag_name or
* just dirname. In the later case we use the
* default tag name
*/
- tag_name = strstr(arg, ",");
+ tag_name = strstr(copy, ",");
if (tag_name) {
*tag_name = '\0';
tag_name++;
}
- if (realpath(arg, tmp)) {
- if (virtio_9p__register(kvm, tmp, tag_name) < 0)
+ if (realpath(copy, path)) {
+ if (virtio_9p__register(kvm, path, tag_name) < 0)
die("Unable to initialize virtio 9p");
- } else
- die("Failed resolving 9p path");
+ } else {
+ die_perror("Failed resolving 9p path");
+ }
+
+ free(copy);
+
return 0;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH kvmtool v2 3/7] disk/core: Do not modify const strings in disk_img_name_parser()
2026-06-18 15:49 [PATCH kvmtool v2 0/7] x86 compilation fixes and arm64 PMU improvements Alexandru Elisei
2026-06-18 15:49 ` [PATCH kvmtool v2 1/7] x86: Define bioscall only in 32-bit mode Alexandru Elisei
2026-06-18 15:49 ` [PATCH kvmtool v2 2/7] virtio: Do not modify const strings in virtio_9p_rootdir_parser() Alexandru Elisei
@ 2026-06-18 15:49 ` Alexandru Elisei
2026-06-18 15:49 ` [PATCH kvmtool v2 4/7] arm64: Initialise the PMU after the GIC Alexandru Elisei
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Alexandru Elisei @ 2026-06-18 15:49 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
@arg is const char *, but disk_img_name_parser() modifies it, which leads
to a compilation error on x86 with gcc 15.2.1:
disk/core.c:27:21: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
27 | sep = strstr(arg, ":");
Make a copy of @arg and modify it instead, and be very careful to free it
when no longer needed.
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
disk/core.c | 44 +++++++++++++++++++++++++++-------------
include/kvm/disk-image.h | 6 +++---
2 files changed, 33 insertions(+), 17 deletions(-)
diff --git a/disk/core.c b/disk/core.c
index 91db277f7846..b232eece9e73 100644
--- a/disk/core.c
+++ b/disk/core.c
@@ -13,35 +13,42 @@ static int disk_image__close(struct disk_image *disk);
int disk_img_name_parser(const struct option *opt, const char *arg, int unset)
{
- const char *cur;
- char *sep;
+ struct disk_image_params *params;
struct kvm *kvm = opt->ptr;
+ char *cur, *sep;
if (kvm->nr_disks >= MAX_DISK_IMAGES)
die("Currently only 4 images are supported");
- kvm->cfg.disk_image[kvm->nr_disks].filename = arg;
- cur = arg;
+ params = &kvm->cfg.disk_image[kvm->nr_disks];
if (strncmp(arg, "scsi:", 5) == 0) {
- sep = strstr(arg, ":");
- kvm->cfg.disk_image[kvm->nr_disks].wwpn = sep + 1;
+ params->wwpn = strdup(strstr(arg, ":") + 1);
+ if (!params->wwpn)
+ die_perror("strdup");
/* Old invocation had two parameters. Ignore the second one. */
- sep = strstr(sep + 1, ":");
+ sep = strstr(params->wwpn, ":");
if (sep) {
*sep = 0;
cur = sep + 1;
+ } else {
+ cur = params->wwpn;
}
+ } else {
+ params->filename = strdup(arg);
+ if (!params->filename)
+ die_perror("strdup");
+ cur = params->filename;
}
do {
sep = strstr(cur, ",");
if (sep) {
if (strncmp(sep + 1, "ro", 2) == 0)
- kvm->cfg.disk_image[kvm->nr_disks].readonly = true;
+ params->readonly = true;
else if (strncmp(sep + 1, "direct", 6) == 0)
- kvm->cfg.disk_image[kvm->nr_disks].direct = true;
+ params->direct = true;
*sep = 0;
cur = sep + 1;
}
@@ -145,8 +152,7 @@ static struct disk_image *disk_image__open(const char *filename, bool readonly,
static struct disk_image **disk_image__open_all(struct kvm *kvm)
{
struct disk_image **disks;
- const char *filename;
- const char *wwpn;
+ char *filename, *wwpn;
bool readonly;
bool direct;
void *err;
@@ -189,18 +195,27 @@ static struct disk_image **disk_image__open_all(struct kvm *kvm)
goto error;
}
disks[i]->debug_iodelay = kvm->cfg.debug_iodelay;
+
+ free(params[i].filename);
+ params[i].filename = NULL;
}
return disks;
error:
for (i = 0; i < count; i++) {
- if (IS_ERR_OR_NULL(disks[i]))
+ free(params[i].filename);
+
+ if (IS_ERR_OR_NULL(disks[i])) {
+ free(params[i].wwpn);
continue;
+ }
- if (disks[i]->wwpn)
+ if (disks[i]->wwpn) {
+ free(disks[i]->wwpn);
free(disks[i]);
- else
+ } else {
disk_image__close(disks[i]);
+ }
}
free(disks);
return err;
@@ -236,6 +251,7 @@ static int disk_image__close(struct disk_image *disk)
if (disk->fd && close(disk->fd) < 0)
pr_warning("close() failed");
+ free(disk->wwpn);
free(disk);
return 0;
diff --git a/include/kvm/disk-image.h b/include/kvm/disk-image.h
index bf602b582a3b..cbe91b07af0b 100644
--- a/include/kvm/disk-image.h
+++ b/include/kvm/disk-image.h
@@ -47,9 +47,9 @@ struct disk_image_operations {
};
struct disk_image_params {
- const char *filename;
+ char *filename;
/* wwpn == World Wide Port Number */
- const char *wwpn;
+ char *wwpn;
bool readonly;
bool direct;
};
@@ -69,7 +69,7 @@ struct disk_image {
pthread_t thread;
u64 aio_inflight;
#endif /* CONFIG_HAS_AIO */
- const char *wwpn;
+ char *wwpn;
int debug_iodelay;
};
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH kvmtool v2 4/7] arm64: Initialise the PMU after the GIC
2026-06-18 15:49 [PATCH kvmtool v2 0/7] x86 compilation fixes and arm64 PMU improvements Alexandru Elisei
` (2 preceding siblings ...)
2026-06-18 15:49 ` [PATCH kvmtool v2 3/7] disk/core: Do not modify const strings in disk_img_name_parser() Alexandru Elisei
@ 2026-06-18 15:49 ` Alexandru Elisei
2026-06-18 15:49 ` [PATCH kvmtool v2 5/7] util: Set exit status to errno in die_perror() Alexandru Elisei
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Alexandru Elisei @ 2026-06-18 15:49 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
PMU initialisation is done in:
setup_fdt()
vcpu->generate_fdt_nodes()
pmu__generate_fdt_nodes()
The PMU ioctl KVM_ARM_VCPU_PMU_V3_INIT requires that the GIC has been
initialised, which is done in gic__init_gic().
gic__init_gic() and setup_fdt() are part of the same initialisation list.
The relative order on the list depends on the order of compilation: gic.c
is compiled after fdt.c and this places gic__init_gic() first on the
initialisation list.
If the compilation order changes and gic.c is compiled *before* fdt.c,
gic__init_gic() will be executed *after* setup_fdt() and PMU initialisation
will fail with an error message:
PMU KVM_SET_DEVICE_ATTR: No such device
This is fragile and hard to debug. Improve the situation by having
gic__init_gic() explicitely initialize the PMU.
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
arm64/gic.c | 9 ++++++++-
arm64/include/asm/pmu.h | 3 +++
arm64/pmu.c | 28 ++++++++++++++++++----------
3 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/arm64/gic.c b/arm64/gic.c
index b0be9e5766df..1e4009625595 100644
--- a/arm64/gic.c
+++ b/arm64/gic.c
@@ -9,6 +9,8 @@
#include <linux/kvm.h>
#include <linux/sizes.h>
+#include <asm/pmu.h>
+
#define IRQCHIP_GIC 0
#define GIC_MAINT_IRQ 9
@@ -355,7 +357,12 @@ static int gic__init_gic(struct kvm *kvm)
vgic_is_init = true;
- return irq__setup_irqfd_lines(kvm);
+ ret = irq__setup_irqfd_lines(kvm);
+ if (ret)
+ return ret;
+
+ /* The PMU requires that the GIC has been initialized. */
+ return pmu__init(kvm);
}
late_init(gic__init_gic)
diff --git a/arm64/include/asm/pmu.h b/arm64/include/asm/pmu.h
index 38e3154b11b7..74566943f355 100644
--- a/arm64/include/asm/pmu.h
+++ b/arm64/include/asm/pmu.h
@@ -3,6 +3,9 @@
#define KVM_ARM_PMUv3_PPI 23
+struct kvm;
+
void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm);
+int pmu__init(struct kvm *kvm);
#endif /* __ARM_PMU_H__ */
diff --git a/arm64/pmu.c b/arm64/pmu.c
index 5f31d6b6f346..92cacd62479e 100644
--- a/arm64/pmu.c
+++ b/arm64/pmu.c
@@ -193,21 +193,32 @@ static int find_pmu(struct kvm *kvm)
void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm)
{
const char compatible[] = "arm,armv8-pmuv3";
- int irq = KVM_ARM_PMUv3_PPI;
- struct kvm_cpu *vcpu;
- int pmu_id = -ENXIO;
- int i;
-
u32 cpu_mask = gic__get_fdt_irq_cpumask(kvm);
u32 irq_prop[] = {
cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
- cpu_to_fdt32(irq - 16),
+ cpu_to_fdt32(KVM_ARM_PMUv3_PPI - 16),
cpu_to_fdt32(cpu_mask | IRQ_TYPE_LEVEL_HIGH),
};
if (!kvm->cfg.arch.has_pmuv3)
return;
+ _FDT(fdt_begin_node(fdt, "pmu"));
+ _FDT(fdt_property(fdt, "compatible", compatible, sizeof(compatible)));
+ _FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
+ _FDT(fdt_end_node(fdt));
+}
+
+int pmu__init(struct kvm *kvm)
+{
+ int irq = KVM_ARM_PMUv3_PPI;
+ struct kvm_cpu *vcpu;
+ int pmu_id = -ENXIO;
+ int i;
+
+ if (!kvm->cfg.arch.has_pmuv3)
+ return 0;
+
if (pmu_has_attr(kvm->cpus[0], KVM_ARM_VCPU_PMU_V3_SET_PMU)) {
pmu_id = find_pmu(kvm);
if (pmu_id < 0) {
@@ -228,8 +239,5 @@ void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm)
set_pmu_attr(vcpu, NULL, KVM_ARM_VCPU_PMU_V3_INIT);
}
- _FDT(fdt_begin_node(fdt, "pmu"));
- _FDT(fdt_property(fdt, "compatible", compatible, sizeof(compatible)));
- _FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
- _FDT(fdt_end_node(fdt));
+ return 0;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH kvmtool v2 5/7] util: Set exit status to errno in die_perror()
2026-06-18 15:49 [PATCH kvmtool v2 0/7] x86 compilation fixes and arm64 PMU improvements Alexandru Elisei
` (3 preceding siblings ...)
2026-06-18 15:49 ` [PATCH kvmtool v2 4/7] arm64: Initialise the PMU after the GIC Alexandru Elisei
@ 2026-06-18 15:49 ` Alexandru Elisei
2026-06-18 15:50 ` [PATCH kvmtool v2 6/7] util: Allow die_perror() to take a variable list of argument Alexandru Elisei
2026-06-18 15:50 ` [PATCH kvmtool v2 7/7] arm64: Improve KVM_ARM_VCPU_PMU_V3_CTRL diagnostics Alexandru Elisei
6 siblings, 0 replies; 9+ messages in thread
From: Alexandru Elisei @ 2026-06-18 15:49 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
Exit with a return code equal to errno in die_perror() to make it easier
for the user to get the error code directly.
As per man 3 perror, errno is undefined after a successful library call, so
save it when entering die_perror().
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
util/util.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/util/util.c b/util/util.c
index bab4bb394111..fc732200f2dc 100644
--- a/util/util.c
+++ b/util/util.c
@@ -100,8 +100,10 @@ void __pr_debug(const char *debug, ...)
void die_perror(const char *s)
{
+ int e = errno;
+
perror(s);
- exit(1);
+ exit(e);
}
void *mmap_hugetlbfs(struct kvm *kvm, const char *htlbfs_path, u64 size)
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH kvmtool v2 6/7] util: Allow die_perror() to take a variable list of argument
2026-06-18 15:49 [PATCH kvmtool v2 0/7] x86 compilation fixes and arm64 PMU improvements Alexandru Elisei
` (4 preceding siblings ...)
2026-06-18 15:49 ` [PATCH kvmtool v2 5/7] util: Set exit status to errno in die_perror() Alexandru Elisei
@ 2026-06-18 15:50 ` Alexandru Elisei
2026-06-18 15:50 ` [PATCH kvmtool v2 7/7] arm64: Improve KVM_ARM_VCPU_PMU_V3_CTRL diagnostics Alexandru Elisei
6 siblings, 0 replies; 9+ messages in thread
From: Alexandru Elisei @ 2026-06-18 15:50 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
Make die_perror() more similar to die() by allowing the user to specify
a format string and arguments.
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
include/kvm/util.h | 2 +-
util/util.c | 17 +++++++++++++++--
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/include/kvm/util.h b/include/kvm/util.h
index ac8515f8c46b..a6dba1147d68 100644
--- a/include/kvm/util.h
+++ b/include/kvm/util.h
@@ -41,7 +41,7 @@
#define MAP_ANON_NORESERVE (MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE)
extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
-extern void die_perror(const char *s) NORETURN;
+extern void die_perror(const char *fmt, ...) NORETURN __attribute__((format (printf, 1, 2)));
extern void pr_err(const char *err, ...) __attribute__((format (printf, 1, 2)));
extern void pr_warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
extern void pr_info(const char *err, ...) __attribute__((format (printf, 1, 2)));
diff --git a/util/util.c b/util/util.c
index fc732200f2dc..6f41e2c1b008 100644
--- a/util/util.c
+++ b/util/util.c
@@ -1,6 +1,7 @@
/*
* Taken from perf which in turn take it from GIT
*/
+#include <stdio.h>
#include "kvm/util.h"
@@ -98,11 +99,23 @@ void __pr_debug(const char *debug, ...)
va_end(params);
}
-void die_perror(const char *s)
+void die_perror(const char *fmt, ...)
{
+ char buf[1024];
+ va_list params;
int e = errno;
+ int ret;
+
+ va_start(params, fmt);
+ ret = vsnprintf(buf, sizeof(buf), fmt, params);
+ if (ret < 0) {
+ perror("vsnprintf");
+ buf[0] = '\0';
+ }
+ va_end(params);
- perror(s);
+ errno = e;
+ perror(buf);
exit(e);
}
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH kvmtool v2 7/7] arm64: Improve KVM_ARM_VCPU_PMU_V3_CTRL diagnostics
2026-06-18 15:49 [PATCH kvmtool v2 0/7] x86 compilation fixes and arm64 PMU improvements Alexandru Elisei
` (5 preceding siblings ...)
2026-06-18 15:50 ` [PATCH kvmtool v2 6/7] util: Allow die_perror() to take a variable list of argument Alexandru Elisei
@ 2026-06-18 15:50 ` Alexandru Elisei
2026-06-18 19:06 ` Oliver Upton
6 siblings, 1 reply; 9+ messages in thread
From: Alexandru Elisei @ 2026-06-18 15:50 UTC (permalink / raw)
To: will, julien.thierry.kdev, maz, oupton, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
kvmtool issues several ioctls when configuring the PMU, and each of them
can fail for different reasons. Be more specific about the ioctl that
failed when that happens.
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
arm64/pmu.c | 31 ++++++++++++++++++++++++-------
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/arm64/pmu.c b/arm64/pmu.c
index 92cacd62479e..78c15f153fad 100644
--- a/arm64/pmu.c
+++ b/arm64/pmu.c
@@ -12,6 +12,24 @@
#include "asm/pmu.h"
+static const char *pmu_attr_names[] = {
+ [KVM_ARM_VCPU_PMU_V3_IRQ] = "KVM_ARM_VCPU_PMU_V3_IRQ",
+ [KVM_ARM_VCPU_PMU_V3_INIT] = "KVM_ARM_VCPU_PMU_V3_INIT",
+ [KVM_ARM_VCPU_PMU_V3_FILTER] = "KVM_ARM_VCPU_PMU_V3_FILTER",
+ [KVM_ARM_VCPU_PMU_V3_SET_PMU] = "KVM_ARM_VCPU_PMU_V3_SET_PMU",
+ [KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS] = "KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTER",
+};
+
+static const char *pmu_get_attr_name(u64 attr)
+{
+ switch (attr) {
+ case KVM_ARM_VCPU_PMU_V3_IRQ ... KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS:
+ return pmu_attr_names[attr];
+ default:
+ return "UNKNOWN";
+ }
+}
+
static bool pmu_has_attr(struct kvm_cpu *vcpu, u64 attr)
{
struct kvm_device_attr pmu_attr = {
@@ -32,13 +50,12 @@ static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr)
};
int ret;
- if (pmu_has_attr(vcpu, attr)) {
- ret = ioctl(vcpu->vcpu_fd, KVM_SET_DEVICE_ATTR, &pmu_attr);
- if (ret)
- die_perror("PMU KVM_SET_DEVICE_ATTR");
- } else {
- die_perror("PMU KVM_HAS_DEVICE_ATTR");
- }
+ if (!pmu_has_attr(vcpu, attr))
+ die_perror("KVM_HAS_DEVICE_ATTR(%s)", pmu_get_attr_name(attr));
+
+ ret = ioctl(vcpu->vcpu_fd, KVM_SET_DEVICE_ATTR, &pmu_attr);
+ if (ret)
+ die_perror("KVM_SET_DEVICE_ATTR(%s)", pmu_get_attr_name(attr));
}
#define SYS_EVENT_SOURCE "/sys/bus/event_source/devices/"
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH kvmtool v2 7/7] arm64: Improve KVM_ARM_VCPU_PMU_V3_CTRL diagnostics
2026-06-18 15:50 ` [PATCH kvmtool v2 7/7] arm64: Improve KVM_ARM_VCPU_PMU_V3_CTRL diagnostics Alexandru Elisei
@ 2026-06-18 19:06 ` Oliver Upton
0 siblings, 0 replies; 9+ messages in thread
From: Oliver Upton @ 2026-06-18 19:06 UTC (permalink / raw)
To: Alexandru Elisei
Cc: will, julien.thierry.kdev, maz, jean-philippe.brucker,
andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
On Thu, Jun 18, 2026 at 04:50:01PM +0100, Alexandru Elisei wrote:
> kvmtool issues several ioctls when configuring the PMU, and each of them
> can fail for different reasons. Be more specific about the ioctl that
> failed when that happens.
>
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> ---
> arm64/pmu.c | 31 ++++++++++++++++++++++++-------
> 1 file changed, 24 insertions(+), 7 deletions(-)
>
> diff --git a/arm64/pmu.c b/arm64/pmu.c
> index 92cacd62479e..78c15f153fad 100644
> --- a/arm64/pmu.c
> +++ b/arm64/pmu.c
> @@ -12,6 +12,24 @@
>
> #include "asm/pmu.h"
>
> +static const char *pmu_attr_names[] = {
> + [KVM_ARM_VCPU_PMU_V3_IRQ] = "KVM_ARM_VCPU_PMU_V3_IRQ",
> + [KVM_ARM_VCPU_PMU_V3_INIT] = "KVM_ARM_VCPU_PMU_V3_INIT",
> + [KVM_ARM_VCPU_PMU_V3_FILTER] = "KVM_ARM_VCPU_PMU_V3_FILTER",
> + [KVM_ARM_VCPU_PMU_V3_SET_PMU] = "KVM_ARM_VCPU_PMU_V3_SET_PMU",
> + [KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS] = "KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTER",
> +};
> +
> +static const char *pmu_get_attr_name(u64 attr)
> +{
> + switch (attr) {
> + case KVM_ARM_VCPU_PMU_V3_IRQ ... KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS:
> + return pmu_attr_names[attr];
> + default:
> + return "UNKNOWN";
> + }
> +}
> +
> static bool pmu_has_attr(struct kvm_cpu *vcpu, u64 attr)
> {
> struct kvm_device_attr pmu_attr = {
> @@ -32,13 +50,12 @@ static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr)
> };
> int ret;
>
> - if (pmu_has_attr(vcpu, attr)) {
> - ret = ioctl(vcpu->vcpu_fd, KVM_SET_DEVICE_ATTR, &pmu_attr);
> - if (ret)
> - die_perror("PMU KVM_SET_DEVICE_ATTR");
> - } else {
> - die_perror("PMU KVM_HAS_DEVICE_ATTR");
> - }
> + if (!pmu_has_attr(vcpu, attr))
> + die_perror("KVM_HAS_DEVICE_ATTR(%s)", pmu_get_attr_name(attr));
> +
> + ret = ioctl(vcpu->vcpu_fd, KVM_SET_DEVICE_ATTR, &pmu_attr);
> + if (ret)
> + die_perror("KVM_SET_DEVICE_ATTR(%s)", pmu_get_attr_name(attr));
> }
The whole if (ret) die_perror(...) thing is a bit repetetive IMO. A
treewide cleanup replacing this with macros would be nice, then you could
stringize the ioctl under the hood.
diff --git a/arm64/pmu.c b/arm64/pmu.c
index 5f31d6b..0d9f3df 100644
--- a/arm64/pmu.c
+++ b/arm64/pmu.c
@@ -23,23 +23,19 @@ static bool pmu_has_attr(struct kvm_cpu *vcpu, u64 attr)
return ret == 0;
}
-static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr)
-{
- struct kvm_device_attr pmu_attr = {
- .group = KVM_ARM_VCPU_PMU_V3_CTRL,
- .addr = (u64)addr,
- .attr = attr,
- };
- int ret;
-
- if (pmu_has_attr(vcpu, attr)) {
- ret = ioctl(vcpu->vcpu_fd, KVM_SET_DEVICE_ATTR, &pmu_attr);
- if (ret)
- die_perror("PMU KVM_SET_DEVICE_ATTR");
- } else {
- die_perror("PMU KVM_HAS_DEVICE_ATTR");
- }
-}
+#define kvm_set_device_attr(fd, _group, _attr, _addr) \
+do { \
+ struct kvm_device_attr __attr = { \
+ .group = (_group), \
+ .attr = (_attr), \
+ .addr = (u64)(_addr), \
+ }; \
+ int r; \
+ \
+ r = ioctl((fd), KVM_SET_DEVICE_ATTR, &__attr); \
+ if (r) \
+ die_perror("KVM_SET_DEVICE_ATTR(group:"#_group", attr:"#_attr")"); \
+} while (0)
#define SYS_EVENT_SOURCE "/sys/bus/event_source/devices/"
/*
@@ -218,14 +214,18 @@ void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm)
for (i = 0; i < kvm->nrcpus; i++) {
vcpu = kvm->cpus[i];
- set_pmu_attr(vcpu, &irq, KVM_ARM_VCPU_PMU_V3_IRQ);
+ kvm_set_device_attr(vcpu->vcpu_fd, KVM_ARM_VCPU_PMU_V3_CTRL,
+ KVM_ARM_VCPU_PMU_V3_IRQ, &irq);
/*
* PMU IDs 0-5 are reserved; a positive value means a PMU was
* found.
*/
if (pmu_id > 0)
- set_pmu_attr(vcpu, &pmu_id, KVM_ARM_VCPU_PMU_V3_SET_PMU);
- set_pmu_attr(vcpu, NULL, KVM_ARM_VCPU_PMU_V3_INIT);
+ kvm_set_device_attr(vcpu->vcpu_fd, KVM_ARM_VCPU_PMU_V3_CTRL,
+ KVM_ARM_VCPU_PMU_V3_SET_PMU, &pmu_id);
+
+ kvm_set_device_attr(vcpu->vcpu_fd, KVM_ARM_VCPU_PMU_V3_CTRL,
+ KVM_ARM_VCPU_PMU_V3_INIT, NULL);
}
_FDT(fdt_begin_node(fdt, "pmu"));
^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-06-18 19:06 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-18 15:49 [PATCH kvmtool v2 0/7] x86 compilation fixes and arm64 PMU improvements Alexandru Elisei
2026-06-18 15:49 ` [PATCH kvmtool v2 1/7] x86: Define bioscall only in 32-bit mode Alexandru Elisei
2026-06-18 15:49 ` [PATCH kvmtool v2 2/7] virtio: Do not modify const strings in virtio_9p_rootdir_parser() Alexandru Elisei
2026-06-18 15:49 ` [PATCH kvmtool v2 3/7] disk/core: Do not modify const strings in disk_img_name_parser() Alexandru Elisei
2026-06-18 15:49 ` [PATCH kvmtool v2 4/7] arm64: Initialise the PMU after the GIC Alexandru Elisei
2026-06-18 15:49 ` [PATCH kvmtool v2 5/7] util: Set exit status to errno in die_perror() Alexandru Elisei
2026-06-18 15:50 ` [PATCH kvmtool v2 6/7] util: Allow die_perror() to take a variable list of argument Alexandru Elisei
2026-06-18 15:50 ` [PATCH kvmtool v2 7/7] arm64: Improve KVM_ARM_VCPU_PMU_V3_CTRL diagnostics Alexandru Elisei
2026-06-18 19:06 ` Oliver Upton
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.