qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model
@ 2025-04-14 16:38 Cornelia Huck
  2025-04-14 16:38 ` [PATCH v3 01/10] arm/cpu: Add infra to handle generated ID register definitions Cornelia Huck
                   ` (11 more replies)
  0 siblings, 12 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-04-14 16:38 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck

[This is on top of v5 of the ID register storage rework:
https://lore.kernel.org/qemu-devel/20250409144304.912325-1-cohuck@redhat.com/T/#t]

It's been a while, but here's finally a respin of the series to make ID
registers configurable directly via the command line.

Major changes from v2 include:
- split out the rework of ID register storage (see above) and rebased on top
  of that
- hopefully improved the documentation
- fixed some bugs along the way (including output of the cpu model expansion
  command, and compilation with HVF on)

Decided against zeroing unknown registers; it's mostly a "dammed if you do,
dammed if you don't" situation as one case or the other will not quite work
as desired, even disregarding fields like AA64PFR1_EL1.MTE_frac where 0
might indicate things we do not support. You'll need to be careful when
doing kernel updates and be explicit with configuring fields.

The current cpu properties stay as they are; we can work on converting them
to compatibility props once we have support for configuring the ID register
fields on the command line for the other accelerators (this is still KVM only.)

The FEAT_xxx features only support a subset of what we need to configure in
real life; for example, different AltraMax machines differ in CTR_EL0, which
is not covered by any FEAT_. It might make sense to provide them as syntactic
sugar on top.

We still have to deal with MIDR/REVIDR/AIDR differences by exploiting
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit?id=d300b0168ea8fd5022a1413bd37ab63f4e5a7d4d
(in a different series.)

I have not ignored the issue of named models on Arm, I just wanted to get the
base infrastructure into place first :)

Real world example (migration Graviton 3 -> 4, thx to Sebastian):

-cpu host,pauth=off,SYSREG_ID_AA64PFR0_EL1_SEL2=0,SYSREG_ID_AA64PFR0_EL1_EL0=1,
 SYSREG_ID_AA64ISAR0_EL1_TLB=0,SYSREG_ID_AA64ISAR0_EL1_TS=0,
 SYSREG_ID_AA64ISAR0_EL1_SM4=0,SYSREG_ID_AA64ISAR0_EL1_SM3=0,
 SYSREG_ID_AA64ISAR1_EL1_SPECRES=0,SYSREG_ID_AA64ISAR1_EL1_SB=0,
 SYSREG_ID_AA64ISAR1_EL1_FRINTTS=0,SYSREG_ID_AA64MMFR0_EL1_TGRAN4_2=1,
 SYSREG_ID_AA64MMFR0_EL1_TGRAN16_2=1,SYSREG_ID_AA64MMFR0_EL1_TGRAN64_2=1

(not including handling MIDR differences, which is out of scope for this series)

Code also available at
https://gitlab.com/cohuck/qemu/-/tree/arm-cpu-model-rfcv3?ref_type=heads


Cornelia Huck (5):
  arm/cpu: Add generated sysreg properties
  kvm: kvm_get_writable_id_regs
  arm/cpu: accessors for writable id registers
  arm-qmp-cmds: introspection for ID register props
  arm/cpu-features: document ID reg properties

Eric Auger (5):
  arm/cpu: Add infra to handle generated ID register definitions
  arm/cpu: Add sysreg properties generation
  arm/kvm: Allow reading all the writable ID registers
  arm/kvm: write back modified ID regs to KVM
  arm/cpu: more customization for the kvm host cpu model

 docs/system/arm/cpu-features.rst      | 104 +++-
 scripts/gen-cpu-sysreg-properties.awk | 325 ++++++++++++
 scripts/update-aarch64-sysreg-code.sh |   5 +-
 target/arm/arm-qmp-cmds.c             |  19 +
 target/arm/cpu-custom.h               |  60 +++
 target/arm/cpu-sysreg-properties.c    | 713 ++++++++++++++++++++++++++
 target/arm/cpu-sysregs.h              |   2 +
 target/arm/cpu.c                      |  12 +
 target/arm/cpu.h                      |  47 ++
 target/arm/cpu64.c                    |  24 +-
 target/arm/kvm.c                      | 289 ++++++++++-
 target/arm/kvm_arm.h                  |  26 +-
 target/arm/meson.build                |   1 +
 target/arm/trace-events               |   6 +
 14 files changed, 1617 insertions(+), 16 deletions(-)
 create mode 100755 scripts/gen-cpu-sysreg-properties.awk
 create mode 100644 target/arm/cpu-custom.h
 create mode 100644 target/arm/cpu-sysreg-properties.c

-- 
2.49.0



^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v3 01/10] arm/cpu: Add infra to handle generated ID register definitions
  2025-04-14 16:38 [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
@ 2025-04-14 16:38 ` Cornelia Huck
  2025-05-13 13:52   ` Eric Auger
  2025-04-14 16:38 ` [PATCH v3 02/10] arm/cpu: Add sysreg properties generation Cornelia Huck
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 58+ messages in thread
From: Cornelia Huck @ 2025-04-14 16:38 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck

From: Eric Auger <eric.auger@redhat.com>

The known ID regs are described in a new initialization function
dubbed initialize_cpu_sysreg_properties(). That code will be
automatically generated from linux arch/arm64/tools/sysreg. For the
time being let's just describe a single id reg, CTR_EL0. In this
description we only care about non RES/RAZ fields, ie. named fields.

The registers are populated in an array indexed by ARMIDRegisterIdx
and their fields are added in a sorted list.

[CH: adapted to reworked register storage]
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
 target/arm/cpu-custom.h            | 60 ++++++++++++++++++++++++++++++
 target/arm/cpu-sysreg-properties.c | 41 ++++++++++++++++++++
 target/arm/cpu64.c                 |  2 +
 target/arm/meson.build             |  1 +
 4 files changed, 104 insertions(+)
 create mode 100644 target/arm/cpu-custom.h
 create mode 100644 target/arm/cpu-sysreg-properties.c

diff --git a/target/arm/cpu-custom.h b/target/arm/cpu-custom.h
new file mode 100644
index 000000000000..615347376e56
--- /dev/null
+++ b/target/arm/cpu-custom.h
@@ -0,0 +1,60 @@
+/*
+ * handle ID registers and their fields
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef ARM_CPU_CUSTOM_H
+#define ARM_CPU_CUSTOM_H
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "cpu.h"
+#include "cpu-sysregs.h"
+
+typedef struct ARM64SysRegField {
+    const char *name; /* name of the field, for instance CTR_EL0_IDC */
+    int index;
+    int lower;
+    int upper;
+} ARM64SysRegField;
+
+typedef struct ARM64SysReg {
+    const char *name;   /* name of the sysreg, for instance CTR_EL0 */
+    ARMSysRegs sysreg;
+    int index;
+    GList *fields; /* list of named fields, excluding RES* */
+} ARM64SysReg;
+
+void initialize_cpu_sysreg_properties(void);
+
+/*
+ * List of exposed ID regs (automatically populated from linux
+ * arch/arm64/tools/sysreg)
+ */
+extern ARM64SysReg arm64_id_regs[NUM_ID_IDX];
+
+/* Allocate a new field and insert it at the head of the @reg list */
+static inline GList *arm64_sysreg_add_field(ARM64SysReg *reg, const char *name,
+                                     uint8_t min, uint8_t max) {
+
+     ARM64SysRegField *field = g_new0(ARM64SysRegField, 1);
+
+     field->name = name;
+     field->lower = min;
+     field->upper = max;
+     field->index = reg->index;
+
+     reg->fields = g_list_append(reg->fields, field);
+     return reg->fields;
+}
+
+static inline ARM64SysReg *arm64_sysreg_get(ARMIDRegisterIdx index)
+{
+        ARM64SysReg *reg = &arm64_id_regs[index];
+
+        reg->index = index;
+        reg->sysreg = id_register_sysreg[index];
+        return reg;
+}
+
+#endif
diff --git a/target/arm/cpu-sysreg-properties.c b/target/arm/cpu-sysreg-properties.c
new file mode 100644
index 000000000000..8b7ef5badfb9
--- /dev/null
+++ b/target/arm/cpu-sysreg-properties.c
@@ -0,0 +1,41 @@
+/*
+ * QEMU ARM CPU SYSREG PROPERTIES
+ * to be generated from linux sysreg
+ *
+ * Copyright (c) Red Hat, Inc. 2024
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
+ */
+
+#include "cpu-custom.h"
+
+ARM64SysReg arm64_id_regs[NUM_ID_IDX];
+
+void initialize_cpu_sysreg_properties(void)
+{
+    memset(arm64_id_regs, 0, sizeof(ARM64SysReg) * NUM_ID_IDX);
+    /* CTR_EL0 */
+    ARM64SysReg *CTR_EL0 = arm64_sysreg_get(CTR_EL0_IDX);
+    CTR_EL0->name = "CTR_EL0";
+    arm64_sysreg_add_field(CTR_EL0, "TminLine", 32, 37);
+    arm64_sysreg_add_field(CTR_EL0, "DIC", 29, 29);
+    arm64_sysreg_add_field(CTR_EL0, "IDC", 28, 28);
+    arm64_sysreg_add_field(CTR_EL0, "CWG", 24, 27);
+    arm64_sysreg_add_field(CTR_EL0, "ERG", 20, 23);
+    arm64_sysreg_add_field(CTR_EL0, "DminLine", 16, 19);
+    arm64_sysreg_add_field(CTR_EL0, "L1Ip", 14, 15);
+    arm64_sysreg_add_field(CTR_EL0, "IminLine", 0, 3);
+}
+
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 9769401a8585..839442745ea4 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -35,6 +35,7 @@
 #include "internals.h"
 #include "cpu-features.h"
 #include "cpregs.h"
+#include "cpu-custom.h"
 
 /* convert between <register>_IDX and SYS_<register> */
 #define DEF(NAME, OP0, OP1, CRN, CRM, OP2)      \
@@ -891,6 +892,7 @@ static void aarch64_cpu_register_types(void)
 {
     size_t i;
 
+    initialize_cpu_sysreg_properties();
     type_register_static(&aarch64_cpu_type_info);
 
     for (i = 0; i < ARRAY_SIZE(aarch64_cpus); ++i) {
diff --git a/target/arm/meson.build b/target/arm/meson.build
index 3065081d241d..1c97c1ef7580 100644
--- a/target/arm/meson.build
+++ b/target/arm/meson.build
@@ -14,6 +14,7 @@ arm_ss.add(when: 'CONFIG_HVF', if_true: files('hyp_gdbstub.c'))
 arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
   'cpu64.c',
   'gdbstub64.c',
+  'cpu-sysreg-properties.c',
 ))
 
 arm_system_ss = ss.source_set()
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 02/10] arm/cpu: Add sysreg properties generation
  2025-04-14 16:38 [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
  2025-04-14 16:38 ` [PATCH v3 01/10] arm/cpu: Add infra to handle generated ID register definitions Cornelia Huck
@ 2025-04-14 16:38 ` Cornelia Huck
  2025-04-15  7:09   ` Philippe Mathieu-Daudé
  2025-05-13 15:23   ` Daniel P. Berrangé
  2025-04-14 16:38 ` [PATCH v3 03/10] arm/cpu: Add generated sysreg properties Cornelia Huck
                   ` (9 subsequent siblings)
  11 siblings, 2 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-04-14 16:38 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck

From: Eric Auger <eric.auger@redhat.com>

Introduce a script that automates the generation of system register
properties definitions from a given linux source tree
arch/arm64/tools/sysreg.

Invocation of
./update-aarch64-sysreg-code.sh $PATH_TO_LINUX_SOURCE_TREE
in scripts directory additionally generates
target/arm/cpu-sysreg-properties.c containing definitions for
feature ID registers.

update-aarch64-sysreg-code.sh additionally calls
gen-cpu-sysreg-properties.awk which is inherited from kernel
arch/arm64/tools/gen-sysreg.awk. All credits to Mark Rutland
the original author of this script.

[CH: split off from original patch adding both sysreg definitions
 and properties]
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
 scripts/gen-cpu-sysreg-properties.awk | 325 ++++++++++++++++++++++++++
 scripts/update-aarch64-sysreg-code.sh |   5 +-
 2 files changed, 329 insertions(+), 1 deletion(-)
 create mode 100755 scripts/gen-cpu-sysreg-properties.awk

diff --git a/scripts/gen-cpu-sysreg-properties.awk b/scripts/gen-cpu-sysreg-properties.awk
new file mode 100755
index 000000000000..76c37938b168
--- /dev/null
+++ b/scripts/gen-cpu-sysreg-properties.awk
@@ -0,0 +1,325 @@
+#!/bin/awk -f
+# SPDX-License-Identifier: GPL-2.0
+# gen-cpu-sysreg-properties.awk: arm64 sysreg header generator
+#
+# Usage: awk -f gen-cpu-sysreg-properties.awk $LINUX_PATH/arch/arm64/tools/sysreg
+
+function block_current() {
+	return __current_block[__current_block_depth];
+}
+
+# Log an error and terminate
+function fatal(msg) {
+	print "Error at " NR ": " msg > "/dev/stderr"
+
+	printf "Current block nesting:"
+
+	for (i = 0; i <= __current_block_depth; i++) {
+		printf " " __current_block[i]
+	}
+	printf "\n"
+
+	exit 1
+}
+
+# Enter a new block, setting the active block to @block
+function block_push(block) {
+	__current_block[++__current_block_depth] = block
+}
+
+# Exit a block, setting the active block to the parent block
+function block_pop() {
+	if (__current_block_depth == 0)
+		fatal("error: block_pop() in root block")
+
+	__current_block_depth--;
+}
+
+# Sanity check the number of records for a field makes sense. If not, produce
+# an error and terminate.
+function expect_fields(nf) {
+	if (NF != nf)
+		fatal(NF " fields found where " nf " expected")
+}
+
+# Print a CPP macro definition, padded with spaces so that the macro bodies
+# line up in a column
+function define(name, val) {
+	printf "%-56s%s\n", "#define " name, val
+}
+
+# Print standard BITMASK/SHIFT/WIDTH CPP definitions for a field
+function define_field(reg, field, msb, lsb, idreg) {
+	if (idreg)
+            print "    arm64_sysreg_add_field("reg", \""field"\", "lsb", "msb");"
+}
+
+# Print a field _SIGNED definition for a field
+function define_field_sign(reg, field, sign, idreg) {
+	if (idreg)
+            print "    arm64_sysreg_add_field("reg", \""field"\", "lsb", "msb");"
+}
+
+# Parse a "<msb>[:<lsb>]" string into the global variables @msb and @lsb
+function parse_bitdef(reg, field, bitdef, _bits)
+{
+	if (bitdef ~ /^[0-9]+$/) {
+		msb = bitdef
+		lsb = bitdef
+	} else if (split(bitdef, _bits, ":") == 2) {
+		msb = _bits[1]
+		lsb = _bits[2]
+	} else {
+		fatal("invalid bit-range definition '" bitdef "'")
+	}
+
+
+	if (msb != next_bit)
+		fatal(reg "." field " starts at " msb " not " next_bit)
+	if (63 < msb || msb < 0)
+		fatal(reg "." field " invalid high bit in '" bitdef "'")
+	if (63 < lsb || lsb < 0)
+		fatal(reg "." field " invalid low bit in '" bitdef "'")
+	if (msb < lsb)
+		fatal(reg "." field " invalid bit-range '" bitdef "'")
+	if (low > high)
+		fatal(reg "." field " has invalid range " high "-" low)
+
+	next_bit = lsb - 1
+}
+
+BEGIN {
+	print "#include \"cpu-custom.h\""
+	print ""
+	print "ARM64SysReg arm64_id_regs[NUM_ID_IDX];"
+	print ""
+	print "void initialize_cpu_sysreg_properties(void)"
+	print "{"
+        print "    memset(arm64_id_regs, 0, sizeof(ARM64SysReg) * NUM_ID_IDX);"
+        print ""
+
+	__current_block_depth = 0
+	__current_block[__current_block_depth] = "Root"
+}
+
+END {
+	if (__current_block_depth != 0)
+		fatal("Missing terminator for " block_current() " block")
+
+	print "}"
+}
+
+# skip blank lines and comment lines
+/^$/ { next }
+/^[\t ]*#/ { next }
+
+/^SysregFields/ && block_current() == "Root" {
+	block_push("SysregFields")
+
+	expect_fields(2)
+
+	reg = $2
+
+	res0 = "UL(0)"
+	res1 = "UL(0)"
+	unkn = "UL(0)"
+
+	next_bit = 63
+
+	next
+}
+
+/^EndSysregFields/ && block_current() == "SysregFields" {
+	if (next_bit > 0)
+		fatal("Unspecified bits in " reg)
+
+	reg = null
+	res0 = null
+	res1 = null
+	unkn = null
+
+	block_pop()
+	next
+}
+
+/^Sysreg/ && block_current() == "Root" {
+	block_push("Sysreg")
+
+	expect_fields(7)
+
+	reg = $2
+	op0 = $3
+	op1 = $4
+	crn = $5
+	crm = $6
+	op2 = $7
+
+	res0 = "UL(0)"
+	res1 = "UL(0)"
+	unkn = "UL(0)"
+
+	if (op0 == 3 && (op1>=0 && op1<=3) && crn==0 && (crm>=0 && crm<=7) && (op2>=0 && op2<=7)) {
+	    idreg = 1
+        } else {
+	    idreg = 0
+	}
+
+	if (idreg == 1) {
+	   print "    /* "reg" */"
+	   print "    ARM64SysReg *"reg" = arm64_sysreg_get("reg"_IDX);"
+	   print "    "reg"->name = \""reg"\";"
+	}
+
+	next_bit = 63
+
+	next
+}
+
+/^EndSysreg/ && block_current() == "Sysreg" {
+	if (next_bit > 0)
+		fatal("Unspecified bits in " reg)
+
+	reg = null
+	op0 = null
+	op1 = null
+	crn = null
+	crm = null
+	op2 = null
+	res0 = null
+	res1 = null
+	unkn = null
+
+	if (idreg==1)
+	    print ""
+	block_pop()
+	next
+}
+
+# Currently this is effectivey a comment, in future we may want to emit
+# defines for the fields.
+(/^Fields/ || /^Mapping/) && block_current() == "Sysreg" {
+	expect_fields(2)
+
+	if (next_bit != 63)
+		fatal("Some fields already defined for " reg)
+
+	print "/* For " reg " fields see " $2 " */"
+	print ""
+
+        next_bit = 0
+	res0 = null
+	res1 = null
+	unkn = null
+
+	next
+}
+
+
+/^Res0/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+	expect_fields(2)
+	parse_bitdef(reg, "RES0", $2)
+	field = "RES0_" msb "_" lsb
+
+	res0 = res0 " | GENMASK_ULL(" msb ", " lsb ")"
+
+	next
+}
+
+/^Res1/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+	expect_fields(2)
+	parse_bitdef(reg, "RES1", $2)
+	field = "RES1_" msb "_" lsb
+
+	res1 = res1 " | GENMASK_ULL(" msb ", " lsb ")"
+
+	next
+}
+
+/^Unkn/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+	expect_fields(2)
+	parse_bitdef(reg, "UNKN", $2)
+	field = "UNKN_" msb "_" lsb
+
+	unkn = unkn " | GENMASK_ULL(" msb ", " lsb ")"
+
+	next
+}
+
+/^Field/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+	expect_fields(3)
+	field = $3
+	parse_bitdef(reg, field, $2)
+
+
+	define_field(reg, field, msb, lsb, idreg)
+
+	next
+}
+
+/^Raz/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+	expect_fields(2)
+	parse_bitdef(reg, field, $2)
+
+	next
+}
+
+/^SignedEnum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+	block_push("Enum")
+
+	expect_fields(3)
+	field = $3
+	parse_bitdef(reg, field, $2)
+
+	define_field(reg, field, msb, lsb, idreg)
+	define_field_sign(reg, field, "true", idreg)
+
+	next
+}
+
+/^UnsignedEnum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+	block_push("Enum")
+
+	expect_fields(3)
+	field = $3
+	parse_bitdef(reg, field, $2)
+
+	define_field(reg, field, msb, lsb, idreg)
+	#define_field_sign(reg, field, "false", idreg)
+
+	next
+}
+
+/^Enum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+	block_push("Enum")
+
+	expect_fields(3)
+	field = $3
+	parse_bitdef(reg, field, $2)
+
+	define_field(reg, field, msb, lsb, idreg)
+
+	next
+}
+
+/^EndEnum/ && block_current() == "Enum" {
+
+	field = null
+	msb = null
+	lsb = null
+
+	block_pop()
+	next
+}
+
+/0b[01]+/ && block_current() == "Enum" {
+	expect_fields(2)
+	val = $1
+	name = $2
+
+	next
+}
+
+# Any lines not handled by previous rules are unexpected
+{
+	fatal("unhandled statement")
+}
diff --git a/scripts/update-aarch64-sysreg-code.sh b/scripts/update-aarch64-sysreg-code.sh
index 721f41a9a516..a11637091815 100755
--- a/scripts/update-aarch64-sysreg-code.sh
+++ b/scripts/update-aarch64-sysreg-code.sh
@@ -1,6 +1,6 @@
 #!/bin/sh -e
 #
-# Update target/arm/cpu-sysregs.h
+# Update target/arm/cpu-sysreg-properties.c and target/arm/cpu-sysregs.h
 # from a linux source tree (arch/arm64/tools/sysreg)
 #
 # Copyright Red Hat, Inc. 2024
@@ -23,3 +23,6 @@ fi
 
 awk -f gen-cpu-sysregs-header.awk \
     $linux/arch/arm64/tools/sysreg > ../target/arm/cpu-sysregs.h.inc
+
+awk -f gen-cpu-sysreg-properties.awk \
+       $linux/arch/arm64/tools/sysreg > ../target/arm/cpu-sysreg-properties.c
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 03/10] arm/cpu: Add generated sysreg properties
  2025-04-14 16:38 [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
  2025-04-14 16:38 ` [PATCH v3 01/10] arm/cpu: Add infra to handle generated ID register definitions Cornelia Huck
  2025-04-14 16:38 ` [PATCH v3 02/10] arm/cpu: Add sysreg properties generation Cornelia Huck
@ 2025-04-14 16:38 ` Cornelia Huck
  2025-04-14 16:38 ` [PATCH v3 04/10] kvm: kvm_get_writable_id_regs Cornelia Huck
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-04-14 16:38 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck

Generated against Linux 6.14-rc1.

Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
 target/arm/cpu-sysreg-properties.c | 716 ++++++++++++++++++++++++++++-
 1 file changed, 694 insertions(+), 22 deletions(-)

diff --git a/target/arm/cpu-sysreg-properties.c b/target/arm/cpu-sysreg-properties.c
index 8b7ef5badfb9..05eb40487313 100644
--- a/target/arm/cpu-sysreg-properties.c
+++ b/target/arm/cpu-sysreg-properties.c
@@ -1,24 +1,3 @@
-/*
- * QEMU ARM CPU SYSREG PROPERTIES
- * to be generated from linux sysreg
- *
- * Copyright (c) Red Hat, Inc. 2024
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see
- * <http://www.gnu.org/licenses/gpl-2.0.html>
- */
-
 #include "cpu-custom.h"
 
 ARM64SysReg arm64_id_regs[NUM_ID_IDX];
@@ -26,6 +5,627 @@ ARM64SysReg arm64_id_regs[NUM_ID_IDX];
 void initialize_cpu_sysreg_properties(void)
 {
     memset(arm64_id_regs, 0, sizeof(ARM64SysReg) * NUM_ID_IDX);
+
+    /* ID_PFR0_EL1 */
+    ARM64SysReg *ID_PFR0_EL1 = arm64_sysreg_get(ID_PFR0_EL1_IDX);
+    ID_PFR0_EL1->name = "ID_PFR0_EL1";
+    arm64_sysreg_add_field(ID_PFR0_EL1, "RAS", 28, 31);
+    arm64_sysreg_add_field(ID_PFR0_EL1, "DIT", 24, 27);
+    arm64_sysreg_add_field(ID_PFR0_EL1, "AMU", 20, 23);
+    arm64_sysreg_add_field(ID_PFR0_EL1, "CSV2", 16, 19);
+    arm64_sysreg_add_field(ID_PFR0_EL1, "State3", 12, 15);
+    arm64_sysreg_add_field(ID_PFR0_EL1, "State2", 8, 11);
+    arm64_sysreg_add_field(ID_PFR0_EL1, "State1", 4, 7);
+    arm64_sysreg_add_field(ID_PFR0_EL1, "State0", 0, 3);
+
+    /* ID_PFR1_EL1 */
+    ARM64SysReg *ID_PFR1_EL1 = arm64_sysreg_get(ID_PFR1_EL1_IDX);
+    ID_PFR1_EL1->name = "ID_PFR1_EL1";
+    arm64_sysreg_add_field(ID_PFR1_EL1, "GIC", 28, 31);
+    arm64_sysreg_add_field(ID_PFR1_EL1, "Virt_frac", 24, 27);
+    arm64_sysreg_add_field(ID_PFR1_EL1, "Sec_frac", 20, 23);
+    arm64_sysreg_add_field(ID_PFR1_EL1, "GenTimer", 16, 19);
+    arm64_sysreg_add_field(ID_PFR1_EL1, "Virtualization", 12, 15);
+    arm64_sysreg_add_field(ID_PFR1_EL1, "MProgMod", 8, 11);
+    arm64_sysreg_add_field(ID_PFR1_EL1, "Security", 4, 7);
+    arm64_sysreg_add_field(ID_PFR1_EL1, "ProgMod", 0, 3);
+
+    /* ID_DFR0_EL1 */
+    ARM64SysReg *ID_DFR0_EL1 = arm64_sysreg_get(ID_DFR0_EL1_IDX);
+    ID_DFR0_EL1->name = "ID_DFR0_EL1";
+    arm64_sysreg_add_field(ID_DFR0_EL1, "TraceFilt", 28, 31);
+    arm64_sysreg_add_field(ID_DFR0_EL1, "PerfMon", 24, 27);
+    arm64_sysreg_add_field(ID_DFR0_EL1, "MProfDbg", 20, 23);
+    arm64_sysreg_add_field(ID_DFR0_EL1, "MMapTrc", 16, 19);
+    arm64_sysreg_add_field(ID_DFR0_EL1, "CopTrc", 12, 15);
+    arm64_sysreg_add_field(ID_DFR0_EL1, "MMapDbg", 8, 11);
+    arm64_sysreg_add_field(ID_DFR0_EL1, "CopSDbg", 4, 7);
+    arm64_sysreg_add_field(ID_DFR0_EL1, "CopDbg", 0, 3);
+
+    /* ID_AFR0_EL1 */
+    ARM64SysReg *ID_AFR0_EL1 = arm64_sysreg_get(ID_AFR0_EL1_IDX);
+    ID_AFR0_EL1->name = "ID_AFR0_EL1";
+    arm64_sysreg_add_field(ID_AFR0_EL1, "IMPDEF3", 12, 15);
+    arm64_sysreg_add_field(ID_AFR0_EL1, "IMPDEF2", 8, 11);
+    arm64_sysreg_add_field(ID_AFR0_EL1, "IMPDEF1", 4, 7);
+    arm64_sysreg_add_field(ID_AFR0_EL1, "IMPDEF0", 0, 3);
+
+    /* ID_MMFR0_EL1 */
+    ARM64SysReg *ID_MMFR0_EL1 = arm64_sysreg_get(ID_MMFR0_EL1_IDX);
+    ID_MMFR0_EL1->name = "ID_MMFR0_EL1";
+    arm64_sysreg_add_field(ID_MMFR0_EL1, "InnerShr", 28, 31);
+    arm64_sysreg_add_field(ID_MMFR0_EL1, "FCSE", 24, 27);
+    arm64_sysreg_add_field(ID_MMFR0_EL1, "AuxReg", 20, 23);
+    arm64_sysreg_add_field(ID_MMFR0_EL1, "TCM", 16, 19);
+    arm64_sysreg_add_field(ID_MMFR0_EL1, "ShareLvl", 12, 15);
+    arm64_sysreg_add_field(ID_MMFR0_EL1, "OuterShr", 8, 11);
+    arm64_sysreg_add_field(ID_MMFR0_EL1, "PMSA", 4, 7);
+    arm64_sysreg_add_field(ID_MMFR0_EL1, "VMSA", 0, 3);
+
+    /* ID_MMFR1_EL1 */
+    ARM64SysReg *ID_MMFR1_EL1 = arm64_sysreg_get(ID_MMFR1_EL1_IDX);
+    ID_MMFR1_EL1->name = "ID_MMFR1_EL1";
+    arm64_sysreg_add_field(ID_MMFR1_EL1, "BPred", 28, 31);
+    arm64_sysreg_add_field(ID_MMFR1_EL1, "L1TstCln", 24, 27);
+    arm64_sysreg_add_field(ID_MMFR1_EL1, "L1Uni", 20, 23);
+    arm64_sysreg_add_field(ID_MMFR1_EL1, "L1Hvd", 16, 19);
+    arm64_sysreg_add_field(ID_MMFR1_EL1, "L1UniSW", 12, 15);
+    arm64_sysreg_add_field(ID_MMFR1_EL1, "L1HvdSW", 8, 11);
+    arm64_sysreg_add_field(ID_MMFR1_EL1, "L1UniVA", 4, 7);
+    arm64_sysreg_add_field(ID_MMFR1_EL1, "L1HvdVA", 0, 3);
+
+    /* ID_MMFR2_EL1 */
+    ARM64SysReg *ID_MMFR2_EL1 = arm64_sysreg_get(ID_MMFR2_EL1_IDX);
+    ID_MMFR2_EL1->name = "ID_MMFR2_EL1";
+    arm64_sysreg_add_field(ID_MMFR2_EL1, "HWAccFlg", 28, 31);
+    arm64_sysreg_add_field(ID_MMFR2_EL1, "WFIStall", 24, 27);
+    arm64_sysreg_add_field(ID_MMFR2_EL1, "MemBarr", 20, 23);
+    arm64_sysreg_add_field(ID_MMFR2_EL1, "UniTLB", 16, 19);
+    arm64_sysreg_add_field(ID_MMFR2_EL1, "HvdTLB", 12, 15);
+    arm64_sysreg_add_field(ID_MMFR2_EL1, "L1HvdRng", 8, 11);
+    arm64_sysreg_add_field(ID_MMFR2_EL1, "L1HvdBG", 4, 7);
+    arm64_sysreg_add_field(ID_MMFR2_EL1, "L1HvdFG", 0, 3);
+
+    /* ID_MMFR3_EL1 */
+    ARM64SysReg *ID_MMFR3_EL1 = arm64_sysreg_get(ID_MMFR3_EL1_IDX);
+    ID_MMFR3_EL1->name = "ID_MMFR3_EL1";
+    arm64_sysreg_add_field(ID_MMFR3_EL1, "Supersec", 28, 31);
+    arm64_sysreg_add_field(ID_MMFR3_EL1, "CMemSz", 24, 27);
+    arm64_sysreg_add_field(ID_MMFR3_EL1, "CohWalk", 20, 23);
+    arm64_sysreg_add_field(ID_MMFR3_EL1, "PAN", 16, 19);
+    arm64_sysreg_add_field(ID_MMFR3_EL1, "MaintBcst", 12, 15);
+    arm64_sysreg_add_field(ID_MMFR3_EL1, "BPMaint", 8, 11);
+    arm64_sysreg_add_field(ID_MMFR3_EL1, "CMaintSW", 4, 7);
+    arm64_sysreg_add_field(ID_MMFR3_EL1, "CMaintVA", 0, 3);
+
+    /* ID_ISAR0_EL1 */
+    ARM64SysReg *ID_ISAR0_EL1 = arm64_sysreg_get(ID_ISAR0_EL1_IDX);
+    ID_ISAR0_EL1->name = "ID_ISAR0_EL1";
+    arm64_sysreg_add_field(ID_ISAR0_EL1, "Divide", 24, 27);
+    arm64_sysreg_add_field(ID_ISAR0_EL1, "Debug", 20, 23);
+    arm64_sysreg_add_field(ID_ISAR0_EL1, "Coproc", 16, 19);
+    arm64_sysreg_add_field(ID_ISAR0_EL1, "CmpBranch", 12, 15);
+    arm64_sysreg_add_field(ID_ISAR0_EL1, "BitField", 8, 11);
+    arm64_sysreg_add_field(ID_ISAR0_EL1, "BitCount", 4, 7);
+    arm64_sysreg_add_field(ID_ISAR0_EL1, "Swap", 0, 3);
+
+    /* ID_ISAR1_EL1 */
+    ARM64SysReg *ID_ISAR1_EL1 = arm64_sysreg_get(ID_ISAR1_EL1_IDX);
+    ID_ISAR1_EL1->name = "ID_ISAR1_EL1";
+    arm64_sysreg_add_field(ID_ISAR1_EL1, "Jazelle", 28, 31);
+    arm64_sysreg_add_field(ID_ISAR1_EL1, "Interwork", 24, 27);
+    arm64_sysreg_add_field(ID_ISAR1_EL1, "Immediate", 20, 23);
+    arm64_sysreg_add_field(ID_ISAR1_EL1, "IfThen", 16, 19);
+    arm64_sysreg_add_field(ID_ISAR1_EL1, "Extend", 12, 15);
+    arm64_sysreg_add_field(ID_ISAR1_EL1, "Except_AR", 8, 11);
+    arm64_sysreg_add_field(ID_ISAR1_EL1, "Except", 4, 7);
+    arm64_sysreg_add_field(ID_ISAR1_EL1, "Endian", 0, 3);
+
+    /* ID_ISAR2_EL1 */
+    ARM64SysReg *ID_ISAR2_EL1 = arm64_sysreg_get(ID_ISAR2_EL1_IDX);
+    ID_ISAR2_EL1->name = "ID_ISAR2_EL1";
+    arm64_sysreg_add_field(ID_ISAR2_EL1, "Reversal", 28, 31);
+    arm64_sysreg_add_field(ID_ISAR2_EL1, "PSR_AR", 24, 27);
+    arm64_sysreg_add_field(ID_ISAR2_EL1, "MultU", 20, 23);
+    arm64_sysreg_add_field(ID_ISAR2_EL1, "MultS", 16, 19);
+    arm64_sysreg_add_field(ID_ISAR2_EL1, "Mult", 12, 15);
+    arm64_sysreg_add_field(ID_ISAR2_EL1, "MultiAccessInt", 8, 11);
+    arm64_sysreg_add_field(ID_ISAR2_EL1, "MemHint", 4, 7);
+    arm64_sysreg_add_field(ID_ISAR2_EL1, "LoadStore", 0, 3);
+
+    /* ID_ISAR3_EL1 */
+    ARM64SysReg *ID_ISAR3_EL1 = arm64_sysreg_get(ID_ISAR3_EL1_IDX);
+    ID_ISAR3_EL1->name = "ID_ISAR3_EL1";
+    arm64_sysreg_add_field(ID_ISAR3_EL1, "T32EE", 28, 31);
+    arm64_sysreg_add_field(ID_ISAR3_EL1, "TrueNOP", 24, 27);
+    arm64_sysreg_add_field(ID_ISAR3_EL1, "T32Copy", 20, 23);
+    arm64_sysreg_add_field(ID_ISAR3_EL1, "TabBranch", 16, 19);
+    arm64_sysreg_add_field(ID_ISAR3_EL1, "SynchPrim", 12, 15);
+    arm64_sysreg_add_field(ID_ISAR3_EL1, "SVC", 8, 11);
+    arm64_sysreg_add_field(ID_ISAR3_EL1, "SIMD", 4, 7);
+    arm64_sysreg_add_field(ID_ISAR3_EL1, "Saturate", 0, 3);
+
+    /* ID_ISAR4_EL1 */
+    ARM64SysReg *ID_ISAR4_EL1 = arm64_sysreg_get(ID_ISAR4_EL1_IDX);
+    ID_ISAR4_EL1->name = "ID_ISAR4_EL1";
+    arm64_sysreg_add_field(ID_ISAR4_EL1, "SWP_frac", 28, 31);
+    arm64_sysreg_add_field(ID_ISAR4_EL1, "PSR_M", 24, 27);
+    arm64_sysreg_add_field(ID_ISAR4_EL1, "SynchPrim_frac", 20, 23);
+    arm64_sysreg_add_field(ID_ISAR4_EL1, "Barrier", 16, 19);
+    arm64_sysreg_add_field(ID_ISAR4_EL1, "SMC", 12, 15);
+    arm64_sysreg_add_field(ID_ISAR4_EL1, "Writeback", 8, 11);
+    arm64_sysreg_add_field(ID_ISAR4_EL1, "WithShifts", 4, 7);
+    arm64_sysreg_add_field(ID_ISAR4_EL1, "Unpriv", 0, 3);
+
+    /* ID_ISAR5_EL1 */
+    ARM64SysReg *ID_ISAR5_EL1 = arm64_sysreg_get(ID_ISAR5_EL1_IDX);
+    ID_ISAR5_EL1->name = "ID_ISAR5_EL1";
+    arm64_sysreg_add_field(ID_ISAR5_EL1, "VCMA", 28, 31);
+    arm64_sysreg_add_field(ID_ISAR5_EL1, "RDM", 24, 27);
+    arm64_sysreg_add_field(ID_ISAR5_EL1, "CRC32", 16, 19);
+    arm64_sysreg_add_field(ID_ISAR5_EL1, "SHA2", 12, 15);
+    arm64_sysreg_add_field(ID_ISAR5_EL1, "SHA1", 8, 11);
+    arm64_sysreg_add_field(ID_ISAR5_EL1, "AES", 4, 7);
+    arm64_sysreg_add_field(ID_ISAR5_EL1, "SEVL", 0, 3);
+
+    /* ID_ISAR6_EL1 */
+    ARM64SysReg *ID_ISAR6_EL1 = arm64_sysreg_get(ID_ISAR6_EL1_IDX);
+    ID_ISAR6_EL1->name = "ID_ISAR6_EL1";
+    arm64_sysreg_add_field(ID_ISAR6_EL1, "I8MM", 24, 27);
+    arm64_sysreg_add_field(ID_ISAR6_EL1, "BF16", 20, 23);
+    arm64_sysreg_add_field(ID_ISAR6_EL1, "SPECRES", 16, 19);
+    arm64_sysreg_add_field(ID_ISAR6_EL1, "SB", 12, 15);
+    arm64_sysreg_add_field(ID_ISAR6_EL1, "FHM", 8, 11);
+    arm64_sysreg_add_field(ID_ISAR6_EL1, "DP", 4, 7);
+    arm64_sysreg_add_field(ID_ISAR6_EL1, "JSCVT", 0, 3);
+
+    /* ID_MMFR4_EL1 */
+    ARM64SysReg *ID_MMFR4_EL1 = arm64_sysreg_get(ID_MMFR4_EL1_IDX);
+    ID_MMFR4_EL1->name = "ID_MMFR4_EL1";
+    arm64_sysreg_add_field(ID_MMFR4_EL1, "EVT", 28, 31);
+    arm64_sysreg_add_field(ID_MMFR4_EL1, "CCIDX", 24, 27);
+    arm64_sysreg_add_field(ID_MMFR4_EL1, "LSM", 20, 23);
+    arm64_sysreg_add_field(ID_MMFR4_EL1, "HPDS", 16, 19);
+    arm64_sysreg_add_field(ID_MMFR4_EL1, "CnP", 12, 15);
+    arm64_sysreg_add_field(ID_MMFR4_EL1, "XNX", 8, 11);
+    arm64_sysreg_add_field(ID_MMFR4_EL1, "AC2", 4, 7);
+    arm64_sysreg_add_field(ID_MMFR4_EL1, "SpecSEI", 0, 3);
+
+    /* MVFR0_EL1 */
+    ARM64SysReg *MVFR0_EL1 = arm64_sysreg_get(MVFR0_EL1_IDX);
+    MVFR0_EL1->name = "MVFR0_EL1";
+    arm64_sysreg_add_field(MVFR0_EL1, "FPRound", 28, 31);
+    arm64_sysreg_add_field(MVFR0_EL1, "FPShVec", 24, 27);
+    arm64_sysreg_add_field(MVFR0_EL1, "FPSqrt", 20, 23);
+    arm64_sysreg_add_field(MVFR0_EL1, "FPDivide", 16, 19);
+    arm64_sysreg_add_field(MVFR0_EL1, "FPTrap", 12, 15);
+    arm64_sysreg_add_field(MVFR0_EL1, "FPDP", 8, 11);
+    arm64_sysreg_add_field(MVFR0_EL1, "FPSP", 4, 7);
+    arm64_sysreg_add_field(MVFR0_EL1, "SIMDReg", 0, 3);
+
+    /* MVFR1_EL1 */
+    ARM64SysReg *MVFR1_EL1 = arm64_sysreg_get(MVFR1_EL1_IDX);
+    MVFR1_EL1->name = "MVFR1_EL1";
+    arm64_sysreg_add_field(MVFR1_EL1, "SIMDFMAC", 28, 31);
+    arm64_sysreg_add_field(MVFR1_EL1, "FPHP", 24, 27);
+    arm64_sysreg_add_field(MVFR1_EL1, "SIMDHP", 20, 23);
+    arm64_sysreg_add_field(MVFR1_EL1, "SIMDSP", 16, 19);
+    arm64_sysreg_add_field(MVFR1_EL1, "SIMDInt", 12, 15);
+    arm64_sysreg_add_field(MVFR1_EL1, "SIMDLS", 8, 11);
+    arm64_sysreg_add_field(MVFR1_EL1, "FPDNaN", 4, 7);
+    arm64_sysreg_add_field(MVFR1_EL1, "FPFtZ", 0, 3);
+
+    /* MVFR2_EL1 */
+    ARM64SysReg *MVFR2_EL1 = arm64_sysreg_get(MVFR2_EL1_IDX);
+    MVFR2_EL1->name = "MVFR2_EL1";
+    arm64_sysreg_add_field(MVFR2_EL1, "FPMisc", 4, 7);
+    arm64_sysreg_add_field(MVFR2_EL1, "SIMDMisc", 0, 3);
+
+    /* ID_PFR2_EL1 */
+    ARM64SysReg *ID_PFR2_EL1 = arm64_sysreg_get(ID_PFR2_EL1_IDX);
+    ID_PFR2_EL1->name = "ID_PFR2_EL1";
+    arm64_sysreg_add_field(ID_PFR2_EL1, "RAS_frac", 8, 11);
+    arm64_sysreg_add_field(ID_PFR2_EL1, "SSBS", 4, 7);
+    arm64_sysreg_add_field(ID_PFR2_EL1, "CSV3", 0, 3);
+
+    /* ID_DFR1_EL1 */
+    ARM64SysReg *ID_DFR1_EL1 = arm64_sysreg_get(ID_DFR1_EL1_IDX);
+    ID_DFR1_EL1->name = "ID_DFR1_EL1";
+    arm64_sysreg_add_field(ID_DFR1_EL1, "HPMN0", 4, 7);
+    arm64_sysreg_add_field(ID_DFR1_EL1, "MTPMU", 0, 3);
+
+    /* ID_MMFR5_EL1 */
+    ARM64SysReg *ID_MMFR5_EL1 = arm64_sysreg_get(ID_MMFR5_EL1_IDX);
+    ID_MMFR5_EL1->name = "ID_MMFR5_EL1";
+    arm64_sysreg_add_field(ID_MMFR5_EL1, "nTLBPA", 4, 7);
+    arm64_sysreg_add_field(ID_MMFR5_EL1, "ETS", 0, 3);
+
+    /* ID_AA64PFR0_EL1 */
+    ARM64SysReg *ID_AA64PFR0_EL1 = arm64_sysreg_get(ID_AA64PFR0_EL1_IDX);
+    ID_AA64PFR0_EL1->name = "ID_AA64PFR0_EL1";
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "CSV3", 60, 63);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "CSV2", 56, 59);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "RME", 52, 55);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "DIT", 48, 51);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "AMU", 44, 47);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "MPAM", 40, 43);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "SEL2", 36, 39);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "SVE", 32, 35);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "RAS", 28, 31);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "GIC", 24, 27);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "AdvSIMD", 20, 23);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "AdvSIMD", 20, 23);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "FP", 16, 19);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "FP", 16, 19);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "EL3", 12, 15);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "EL2", 8, 11);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "EL1", 4, 7);
+    arm64_sysreg_add_field(ID_AA64PFR0_EL1, "EL0", 0, 3);
+
+    /* ID_AA64PFR1_EL1 */
+    ARM64SysReg *ID_AA64PFR1_EL1 = arm64_sysreg_get(ID_AA64PFR1_EL1_IDX);
+    ID_AA64PFR1_EL1->name = "ID_AA64PFR1_EL1";
+    arm64_sysreg_add_field(ID_AA64PFR1_EL1, "PFAR", 60, 63);
+    arm64_sysreg_add_field(ID_AA64PFR1_EL1, "DF2", 56, 59);
+    arm64_sysreg_add_field(ID_AA64PFR1_EL1, "MTEX", 52, 55);
+    arm64_sysreg_add_field(ID_AA64PFR1_EL1, "THE", 48, 51);
+    arm64_sysreg_add_field(ID_AA64PFR1_EL1, "GCS", 44, 47);
+    arm64_sysreg_add_field(ID_AA64PFR1_EL1, "MTE_frac", 40, 43);
+    arm64_sysreg_add_field(ID_AA64PFR1_EL1, "NMI", 36, 39);
+    arm64_sysreg_add_field(ID_AA64PFR1_EL1, "CSV2_frac", 32, 35);
+    arm64_sysreg_add_field(ID_AA64PFR1_EL1, "RNDR_trap", 28, 31);
+    arm64_sysreg_add_field(ID_AA64PFR1_EL1, "SME", 24, 27);
+    arm64_sysreg_add_field(ID_AA64PFR1_EL1, "MPAM_frac", 16, 19);
+    arm64_sysreg_add_field(ID_AA64PFR1_EL1, "RAS_frac", 12, 15);
+    arm64_sysreg_add_field(ID_AA64PFR1_EL1, "MTE", 8, 11);
+    arm64_sysreg_add_field(ID_AA64PFR1_EL1, "SSBS", 4, 7);
+    arm64_sysreg_add_field(ID_AA64PFR1_EL1, "BT", 0, 3);
+
+    /* ID_AA64PFR2_EL1 */
+    ARM64SysReg *ID_AA64PFR2_EL1 = arm64_sysreg_get(ID_AA64PFR2_EL1_IDX);
+    ID_AA64PFR2_EL1->name = "ID_AA64PFR2_EL1";
+    arm64_sysreg_add_field(ID_AA64PFR2_EL1, "FPMR", 32, 35);
+    arm64_sysreg_add_field(ID_AA64PFR2_EL1, "UINJ", 16, 19);
+    arm64_sysreg_add_field(ID_AA64PFR2_EL1, "MTEFAR", 8, 11);
+    arm64_sysreg_add_field(ID_AA64PFR2_EL1, "MTESTOREONLY", 4, 7);
+    arm64_sysreg_add_field(ID_AA64PFR2_EL1, "MTEPERM", 0, 3);
+
+    /* ID_AA64ZFR0_EL1 */
+    ARM64SysReg *ID_AA64ZFR0_EL1 = arm64_sysreg_get(ID_AA64ZFR0_EL1_IDX);
+    ID_AA64ZFR0_EL1->name = "ID_AA64ZFR0_EL1";
+    arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "F64MM", 56, 59);
+    arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "F32MM", 52, 55);
+    arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "F16MM", 48, 51);
+    arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "I8MM", 44, 47);
+    arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "SM4", 40, 43);
+    arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "SHA3", 32, 35);
+    arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "B16B16", 24, 27);
+    arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "BF16", 20, 23);
+    arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "BitPerm", 16, 19);
+    arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "EltPerm", 12, 15);
+    arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "AES", 4, 7);
+    arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "SVEver", 0, 3);
+
+    /* ID_AA64SMFR0_EL1 */
+    ARM64SysReg *ID_AA64SMFR0_EL1 = arm64_sysreg_get(ID_AA64SMFR0_EL1_IDX);
+    ID_AA64SMFR0_EL1->name = "ID_AA64SMFR0_EL1";
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "FA64", 63, 63);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "LUTv2", 60, 60);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SMEver", 56, 59);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "I16I64", 52, 55);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F64F64", 48, 48);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "I16I32", 44, 47);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "B16B16", 43, 43);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F16F16", 42, 42);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F8F16", 41, 41);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F8F32", 40, 40);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "I8I32", 36, 39);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F16F32", 35, 35);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "B16F32", 34, 34);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "BI32I32", 33, 33);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F32F32", 32, 32);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SF8FMA", 30, 30);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SF8DP4", 29, 29);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SF8DP2", 28, 28);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SBitPerm", 25, 25);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "AES", 24, 24);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SFEXPA", 23, 23);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "STMOP", 16, 16);
+    arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SMOP4", 0, 0);
+
+    /* ID_AA64FPFR0_EL1 */
+    ARM64SysReg *ID_AA64FPFR0_EL1 = arm64_sysreg_get(ID_AA64FPFR0_EL1_IDX);
+    ID_AA64FPFR0_EL1->name = "ID_AA64FPFR0_EL1";
+    arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8CVT", 31, 31);
+    arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8FMA", 30, 30);
+    arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8DP4", 29, 29);
+    arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8DP2", 28, 28);
+    arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8MM8", 27, 27);
+    arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8MM4", 26, 26);
+    arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8E4M3", 1, 1);
+    arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8E5M2", 0, 0);
+
+    /* ID_AA64DFR0_EL1 */
+    ARM64SysReg *ID_AA64DFR0_EL1 = arm64_sysreg_get(ID_AA64DFR0_EL1_IDX);
+    ID_AA64DFR0_EL1->name = "ID_AA64DFR0_EL1";
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "HPMN0", 60, 63);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "ExtTrcBuff", 56, 59);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "BRBE", 52, 55);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "MTPMU", 48, 51);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "MTPMU", 48, 51);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "TraceBuffer", 44, 47);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "TraceFilt", 40, 43);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "DoubleLock", 36, 39);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "PMSVer", 32, 35);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "CTX_CMPs", 28, 31);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "SEBEP", 24, 27);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "WRPs", 20, 23);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "PMSS", 16, 19);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "BRPs", 12, 15);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "PMUVer", 8, 11);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "TraceVer", 4, 7);
+    arm64_sysreg_add_field(ID_AA64DFR0_EL1, "DebugVer", 0, 3);
+
+    /* ID_AA64DFR1_EL1 */
+    ARM64SysReg *ID_AA64DFR1_EL1 = arm64_sysreg_get(ID_AA64DFR1_EL1_IDX);
+    ID_AA64DFR1_EL1->name = "ID_AA64DFR1_EL1";
+    arm64_sysreg_add_field(ID_AA64DFR1_EL1, "ABL_CMPs", 56, 63);
+    arm64_sysreg_add_field(ID_AA64DFR1_EL1, "DPFZS", 52, 55);
+    arm64_sysreg_add_field(ID_AA64DFR1_EL1, "EBEP", 48, 51);
+    arm64_sysreg_add_field(ID_AA64DFR1_EL1, "ITE", 44, 47);
+    arm64_sysreg_add_field(ID_AA64DFR1_EL1, "ABLE", 40, 43);
+    arm64_sysreg_add_field(ID_AA64DFR1_EL1, "PMICNTR", 36, 39);
+    arm64_sysreg_add_field(ID_AA64DFR1_EL1, "SPMU", 32, 35);
+    arm64_sysreg_add_field(ID_AA64DFR1_EL1, "CTX_CMPs", 24, 31);
+    arm64_sysreg_add_field(ID_AA64DFR1_EL1, "WRPs", 16, 23);
+    arm64_sysreg_add_field(ID_AA64DFR1_EL1, "BRPs", 8, 15);
+    arm64_sysreg_add_field(ID_AA64DFR1_EL1, "SYSPMUID", 0, 7);
+
+    /* ID_AA64DFR2_EL1 */
+    ARM64SysReg *ID_AA64DFR2_EL1 = arm64_sysreg_get(ID_AA64DFR2_EL1_IDX);
+    ID_AA64DFR2_EL1->name = "ID_AA64DFR2_EL1";
+    arm64_sysreg_add_field(ID_AA64DFR2_EL1, "TRBE_EXC", 24, 27);
+    arm64_sysreg_add_field(ID_AA64DFR2_EL1, "SPE_nVM", 20, 23);
+    arm64_sysreg_add_field(ID_AA64DFR2_EL1, "SPE_EXC", 16, 19);
+    arm64_sysreg_add_field(ID_AA64DFR2_EL1, "BWE", 4, 7);
+    arm64_sysreg_add_field(ID_AA64DFR2_EL1, "STEP", 0, 3);
+
+    /* ID_AA64AFR0_EL1 */
+    ARM64SysReg *ID_AA64AFR0_EL1 = arm64_sysreg_get(ID_AA64AFR0_EL1_IDX);
+    ID_AA64AFR0_EL1->name = "ID_AA64AFR0_EL1";
+    arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF7", 28, 31);
+    arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF6", 24, 27);
+    arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF5", 20, 23);
+    arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF4", 16, 19);
+    arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF3", 12, 15);
+    arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF2", 8, 11);
+    arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF1", 4, 7);
+    arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF0", 0, 3);
+
+    /* ID_AA64AFR1_EL1 */
+    ARM64SysReg *ID_AA64AFR1_EL1 = arm64_sysreg_get(ID_AA64AFR1_EL1_IDX);
+    ID_AA64AFR1_EL1->name = "ID_AA64AFR1_EL1";
+
+    /* ID_AA64ISAR0_EL1 */
+    ARM64SysReg *ID_AA64ISAR0_EL1 = arm64_sysreg_get(ID_AA64ISAR0_EL1_IDX);
+    ID_AA64ISAR0_EL1->name = "ID_AA64ISAR0_EL1";
+    arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "RNDR", 60, 63);
+    arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "TLB", 56, 59);
+    arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "TS", 52, 55);
+    arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "FHM", 48, 51);
+    arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "DP", 44, 47);
+    arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "SM4", 40, 43);
+    arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "SM3", 36, 39);
+    arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "SHA3", 32, 35);
+    arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "RDM", 28, 31);
+    arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "TME", 24, 27);
+    arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "ATOMIC", 20, 23);
+    arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "CRC32", 16, 19);
+    arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "SHA2", 12, 15);
+    arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "SHA1", 8, 11);
+    arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "AES", 4, 7);
+
+    /* ID_AA64ISAR1_EL1 */
+    ARM64SysReg *ID_AA64ISAR1_EL1 = arm64_sysreg_get(ID_AA64ISAR1_EL1_IDX);
+    ID_AA64ISAR1_EL1->name = "ID_AA64ISAR1_EL1";
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "LS64", 60, 63);
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "XS", 56, 59);
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "I8MM", 52, 55);
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "DGH", 48, 51);
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "BF16", 44, 47);
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "SPECRES", 40, 43);
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "SB", 36, 39);
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "FRINTTS", 32, 35);
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "GPI", 28, 31);
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "GPA", 24, 27);
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "LRCPC", 20, 23);
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "FCMA", 16, 19);
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "JSCVT", 12, 15);
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "API", 8, 11);
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "APA", 4, 7);
+    arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "DPB", 0, 3);
+
+    /* ID_AA64ISAR2_EL1 */
+    ARM64SysReg *ID_AA64ISAR2_EL1 = arm64_sysreg_get(ID_AA64ISAR2_EL1_IDX);
+    ID_AA64ISAR2_EL1->name = "ID_AA64ISAR2_EL1";
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "ATS1A", 60, 63);
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "LUT", 56, 59);
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "CSSC", 52, 55);
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "RPRFM", 48, 51);
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "PCDPHINT", 44, 47);
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "PRFMSLC", 40, 43);
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "SYSINSTR_128", 36, 39);
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "SYSREG_128", 32, 35);
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "CLRBHB", 28, 31);
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "PAC_frac", 24, 27);
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "BC", 20, 23);
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "MOPS", 16, 19);
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "APA3", 12, 15);
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "GPA3", 8, 11);
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "RPRES", 4, 7);
+    arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "WFxT", 0, 3);
+
+    /* ID_AA64ISAR3_EL1 */
+    ARM64SysReg *ID_AA64ISAR3_EL1 = arm64_sysreg_get(ID_AA64ISAR3_EL1_IDX);
+    ID_AA64ISAR3_EL1->name = "ID_AA64ISAR3_EL1";
+    arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "FPRCVT", 28, 31);
+    arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "LSUI", 24, 27);
+    arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "OCCMO", 20, 23);
+    arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "LSFE", 16, 19);
+    arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "PACM", 12, 15);
+    arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "TLBIW", 8, 11);
+    arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "FAMINMAX", 4, 7);
+    arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "CPA", 0, 3);
+
+    /* ID_AA64MMFR0_EL1 */
+    ARM64SysReg *ID_AA64MMFR0_EL1 = arm64_sysreg_get(ID_AA64MMFR0_EL1_IDX);
+    ID_AA64MMFR0_EL1->name = "ID_AA64MMFR0_EL1";
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "ECV", 60, 63);
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "FGT", 56, 59);
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "EXS", 44, 47);
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN4_2", 40, 43);
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN64_2", 36, 39);
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN16_2", 32, 35);
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN4", 28, 31);
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN4", 28, 31);
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN64", 24, 27);
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN64", 24, 27);
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN16", 20, 23);
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "BIGENDEL0", 16, 19);
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "SNSMEM", 12, 15);
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "BIGEND", 8, 11);
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "ASIDBITS", 4, 7);
+    arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "PARANGE", 0, 3);
+
+    /* ID_AA64MMFR1_EL1 */
+    ARM64SysReg *ID_AA64MMFR1_EL1 = arm64_sysreg_get(ID_AA64MMFR1_EL1_IDX);
+    ID_AA64MMFR1_EL1->name = "ID_AA64MMFR1_EL1";
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "ECBHB", 60, 63);
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "CMOW", 56, 59);
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "TIDCP1", 52, 55);
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "nTLBPA", 48, 51);
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "AFP", 44, 47);
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "HCX", 40, 43);
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "ETS", 36, 39);
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "TWED", 32, 35);
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "XNX", 28, 31);
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "SpecSEI", 24, 27);
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "PAN", 20, 23);
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "LO", 16, 19);
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "HPDS", 12, 15);
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "VH", 8, 11);
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "VMIDBits", 4, 7);
+    arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "HAFDBS", 0, 3);
+
+    /* ID_AA64MMFR2_EL1 */
+    ARM64SysReg *ID_AA64MMFR2_EL1 = arm64_sysreg_get(ID_AA64MMFR2_EL1_IDX);
+    ID_AA64MMFR2_EL1->name = "ID_AA64MMFR2_EL1";
+    arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "E0PD", 60, 63);
+    arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "EVT", 56, 59);
+    arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "BBM", 52, 55);
+    arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "TTL", 48, 51);
+    arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "FWB", 40, 43);
+    arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "IDS", 36, 39);
+    arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "AT", 32, 35);
+    arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "ST", 28, 31);
+    arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "NV", 24, 27);
+    arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "CCIDX", 20, 23);
+    arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "VARange", 16, 19);
+    arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "IESB", 12, 15);
+    arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "LSM", 8, 11);
+    arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "UAO", 4, 7);
+    arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "CnP", 0, 3);
+
+    /* ID_AA64MMFR3_EL1 */
+    ARM64SysReg *ID_AA64MMFR3_EL1 = arm64_sysreg_get(ID_AA64MMFR3_EL1_IDX);
+    ID_AA64MMFR3_EL1->name = "ID_AA64MMFR3_EL1";
+    arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "Spec_FPACC", 60, 63);
+    arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "ADERR", 56, 59);
+    arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "SDERR", 52, 55);
+    arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "ANERR", 44, 47);
+    arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "SNERR", 40, 43);
+    arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "D128_2", 36, 39);
+    arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "D128", 32, 35);
+    arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "MEC", 28, 31);
+    arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "AIE", 24, 27);
+    arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "S2POE", 20, 23);
+    arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "S1POE", 16, 19);
+    arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "S2PIE", 12, 15);
+    arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "S1PIE", 8, 11);
+    arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "SCTLRX", 4, 7);
+    arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "TCRX", 0, 3);
+
+    /* ID_AA64MMFR4_EL1 */
+    ARM64SysReg *ID_AA64MMFR4_EL1 = arm64_sysreg_get(ID_AA64MMFR4_EL1_IDX);
+    ID_AA64MMFR4_EL1->name = "ID_AA64MMFR4_EL1";
+    arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "E3DSE", 36, 39);
+    arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "E2H0", 24, 27);
+    arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "E2H0", 24, 27);
+    arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "NV_frac", 20, 23);
+    arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "FGWTE3", 16, 19);
+    arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "HACDBS", 12, 15);
+    arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "ASID2", 8, 11);
+    arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "EIESB", 4, 7);
+    arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "EIESB", 4, 7);
+
+/* For ZCR_EL1 fields see ZCR_ELx */
+
+/* For SMCR_EL1 fields see SMCR_ELx */
+
+/* For GCSCR_EL1 fields see GCSCR_ELx */
+
+/* For GCSPR_EL1 fields see GCSPR_ELx */
+
+/* For CONTEXTIDR_EL1 fields see CONTEXTIDR_ELx */
+
+    /* CCSIDR_EL1 */
+    ARM64SysReg *CCSIDR_EL1 = arm64_sysreg_get(CCSIDR_EL1_IDX);
+    CCSIDR_EL1->name = "CCSIDR_EL1";
+    arm64_sysreg_add_field(CCSIDR_EL1, "NumSets", 13, 27);
+    arm64_sysreg_add_field(CCSIDR_EL1, "Associativity", 3, 12);
+    arm64_sysreg_add_field(CCSIDR_EL1, "LineSize", 0, 2);
+
+    /* CLIDR_EL1 */
+    ARM64SysReg *CLIDR_EL1 = arm64_sysreg_get(CLIDR_EL1_IDX);
+    CLIDR_EL1->name = "CLIDR_EL1";
+    arm64_sysreg_add_field(CLIDR_EL1, "Ttypen", 33, 46);
+    arm64_sysreg_add_field(CLIDR_EL1, "ICB", 30, 32);
+    arm64_sysreg_add_field(CLIDR_EL1, "LoUU", 27, 29);
+    arm64_sysreg_add_field(CLIDR_EL1, "LoC", 24, 26);
+    arm64_sysreg_add_field(CLIDR_EL1, "LoUIS", 21, 23);
+    arm64_sysreg_add_field(CLIDR_EL1, "Ctype7", 18, 20);
+    arm64_sysreg_add_field(CLIDR_EL1, "Ctype6", 15, 17);
+    arm64_sysreg_add_field(CLIDR_EL1, "Ctype5", 12, 14);
+    arm64_sysreg_add_field(CLIDR_EL1, "Ctype4", 9, 11);
+    arm64_sysreg_add_field(CLIDR_EL1, "Ctype3", 6, 8);
+    arm64_sysreg_add_field(CLIDR_EL1, "Ctype2", 3, 5);
+    arm64_sysreg_add_field(CLIDR_EL1, "Ctype1", 0, 2);
+
+    /* CCSIDR2_EL1 */
+    ARM64SysReg *CCSIDR2_EL1 = arm64_sysreg_get(CCSIDR2_EL1_IDX);
+    CCSIDR2_EL1->name = "CCSIDR2_EL1";
+    arm64_sysreg_add_field(CCSIDR2_EL1, "NumSets", 0, 23);
+
+    /* GMID_EL1 */
+    ARM64SysReg *GMID_EL1 = arm64_sysreg_get(GMID_EL1_IDX);
+    GMID_EL1->name = "GMID_EL1";
+    arm64_sysreg_add_field(GMID_EL1, "BS", 0, 3);
+
+    /* SMIDR_EL1 */
+    ARM64SysReg *SMIDR_EL1 = arm64_sysreg_get(SMIDR_EL1_IDX);
+    SMIDR_EL1->name = "SMIDR_EL1";
+    arm64_sysreg_add_field(SMIDR_EL1, "IMPLEMENTER", 24, 31);
+    arm64_sysreg_add_field(SMIDR_EL1, "REVISION", 16, 23);
+    arm64_sysreg_add_field(SMIDR_EL1, "SMPS", 15, 15);
+    arm64_sysreg_add_field(SMIDR_EL1, "AFFINITY", 0, 11);
+
+    /* CSSELR_EL1 */
+    ARM64SysReg *CSSELR_EL1 = arm64_sysreg_get(CSSELR_EL1_IDX);
+    CSSELR_EL1->name = "CSSELR_EL1";
+    arm64_sysreg_add_field(CSSELR_EL1, "TnD", 4, 4);
+    arm64_sysreg_add_field(CSSELR_EL1, "Level", 1, 3);
+    arm64_sysreg_add_field(CSSELR_EL1, "InD", 0, 0);
+
     /* CTR_EL0 */
     ARM64SysReg *CTR_EL0 = arm64_sysreg_get(CTR_EL0_IDX);
     CTR_EL0->name = "CTR_EL0";
@@ -37,5 +637,77 @@ void initialize_cpu_sysreg_properties(void)
     arm64_sysreg_add_field(CTR_EL0, "DminLine", 16, 19);
     arm64_sysreg_add_field(CTR_EL0, "L1Ip", 14, 15);
     arm64_sysreg_add_field(CTR_EL0, "IminLine", 0, 3);
-}
 
+    /* DCZID_EL0 */
+    ARM64SysReg *DCZID_EL0 = arm64_sysreg_get(DCZID_EL0_IDX);
+    DCZID_EL0->name = "DCZID_EL0";
+    arm64_sysreg_add_field(DCZID_EL0, "DZP", 4, 4);
+    arm64_sysreg_add_field(DCZID_EL0, "BS", 0, 3);
+
+/* For GCSPR_EL0 fields see GCSPR_ELx */
+
+/* For HFGRTR_EL2 fields see HFGxTR_EL2 */
+
+/* For HFGWTR_EL2 fields see HFGxTR_EL2 */
+
+/* For ZCR_EL2 fields see ZCR_ELx */
+
+/* For SMCR_EL2 fields see SMCR_ELx */
+
+/* For GCSCR_EL2 fields see GCSCR_ELx */
+
+/* For GCSPR_EL2 fields see GCSPR_ELx */
+
+/* For CONTEXTIDR_EL2 fields see CONTEXTIDR_ELx */
+
+/* For CPACR_EL12 fields see CPACR_EL1 */
+
+/* For ZCR_EL12 fields see ZCR_EL1 */
+
+/* For TRFCR_EL12 fields see TRFCR_EL1 */
+
+/* For SMCR_EL12 fields see SMCR_EL1 */
+
+/* For GCSCR_EL12 fields see GCSCR_EL1 */
+
+/* For GCSPR_EL12 fields see GCSPR_EL1 */
+
+/* For MPAM1_EL12 fields see MPAM1_ELx */
+
+/* For CONTEXTIDR_EL12 fields see CONTEXTIDR_EL1 */
+
+/* For TTBR0_EL1 fields see TTBRx_EL1 */
+
+/* For TTBR1_EL1 fields see TTBRx_EL1 */
+
+/* For TCR2_EL12 fields see TCR2_EL1 */
+
+/* For MAIR2_EL1 fields see MAIR2_ELx */
+
+/* For MAIR2_EL2 fields see MAIR2_ELx */
+
+/* For PIRE0_EL1 fields see PIRx_ELx */
+
+/* For PIRE0_EL12 fields see PIRE0_EL1 */
+
+/* For PIRE0_EL2 fields see PIRx_ELx */
+
+/* For PIR_EL1 fields see PIRx_ELx */
+
+/* For PIR_EL12 fields see PIR_EL1 */
+
+/* For PIR_EL2 fields see PIRx_ELx */
+
+/* For POR_EL0 fields see PIRx_ELx */
+
+/* For POR_EL1 fields see PIRx_ELx */
+
+/* For POR_EL2 fields see PIRx_ELx */
+
+/* For POR_EL12 fields see POR_EL1 */
+
+/* For S2POR_EL1 fields see PIRx_ELx */
+
+/* For S2PIR_EL2 fields see PIRx_ELx */
+
+}
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 04/10] kvm: kvm_get_writable_id_regs
  2025-04-14 16:38 [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
                   ` (2 preceding siblings ...)
  2025-04-14 16:38 ` [PATCH v3 03/10] arm/cpu: Add generated sysreg properties Cornelia Huck
@ 2025-04-14 16:38 ` Cornelia Huck
  2025-05-13 14:20   ` Eric Auger
  2025-04-14 16:38 ` [PATCH v3 05/10] arm/cpu: accessors for writable id registers Cornelia Huck
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 58+ messages in thread
From: Cornelia Huck @ 2025-04-14 16:38 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck

Add an helper to retrieve the writable id reg bitmask. The
status of the query is stored in the CPU struct so that an
an error, if any, can be reported on vcpu realize().

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
 target/arm/cpu.h     | 26 ++++++++++++++++++++++++++
 target/arm/kvm.c     | 32 ++++++++++++++++++++++++++++++++
 target/arm/kvm_arm.h |  7 +++++++
 3 files changed, 65 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index d27134f4a025..bbee7ff2414a 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -856,6 +856,26 @@ typedef struct {
     uint32_t map, init, supported;
 } ARMVQMap;
 
+typedef enum ARMIdRegsState {
+    WRITABLE_ID_REGS_UNKNOWN,
+    WRITABLE_ID_REGS_NOT_DISCOVERABLE,
+    WRITABLE_ID_REGS_FAILED,
+    WRITABLE_ID_REGS_AVAIL,
+} ARMIdRegsState;
+
+/*
+ * The following structures are for the purpose of mapping the output of
+ * KVM_ARM_GET_REG_WRITABLE_MASKS that also may cover id registers we do
+ * not support in QEMU
+ * ID registers in op0==3, op1=={0,1,3}, crn=0, crm=={0-7}, op2=={0-7},
+ * as used by the KVM_ARM_GET_REG_WRITABLE_MASKS ioctl call.
+ */
+#define NR_ID_REGS (3 * 8 * 8)
+
+typedef struct IdRegMap {
+    uint64_t regs[NR_ID_REGS];
+} IdRegMap;
+
 /* REG is ID_XXX */
 #define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE)                       \
     ({                                                                  \
@@ -1044,6 +1064,12 @@ struct ArchCPU {
      */
     bool host_cpu_probe_failed;
 
+    /*
+     * state of writable id regs query used to report an error, if any,
+     * on KVM custom vcpu model realize
+     */
+    ARMIdRegsState writable_id_regs;
+
     /* QOM property to indicate we should use the back-compat CNTFRQ default */
     bool backcompat_cntfrq;
 
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 8491f42a18d2..6e3cd06e9bc5 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -50,6 +50,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
 static bool cap_has_mp_state;
 static bool cap_has_inject_serror_esr;
 static bool cap_has_inject_ext_dabt;
+static int cap_writable_id_regs;
 
 /**
  * ARMHostCPUFeatures: information about the host CPU (identified
@@ -488,6 +489,37 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
     env->features = arm_host_cpu_features.features;
 }
 
+int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap)
+{
+    struct reg_mask_range range = {
+        .range = 0, /* up to now only a single range is supported */
+        .addr = (uint64_t)idregmap,
+    };
+    int ret;
+
+    if (!kvm_enabled()) {
+        cpu->writable_id_regs = WRITABLE_ID_REGS_NOT_DISCOVERABLE;
+        return -ENOSYS;
+    }
+
+    cap_writable_id_regs =
+        kvm_check_extension(kvm_state, KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES);
+
+    if (!cap_writable_id_regs ||
+        !(cap_writable_id_regs & (1 << KVM_ARM_FEATURE_ID_RANGE))) {
+        cpu->writable_id_regs = WRITABLE_ID_REGS_NOT_DISCOVERABLE;
+        return -ENOSYS;
+    }
+
+    ret = kvm_vm_ioctl(kvm_state, KVM_ARM_GET_REG_WRITABLE_MASKS, &range);
+    if (ret) {
+        cpu->writable_id_regs = WRITABLE_ID_REGS_FAILED;
+        return ret;
+     }
+    cpu->writable_id_regs = WRITABLE_ID_REGS_AVAIL;
+    return ret;
+}
+
 static bool kvm_no_adjvtime_get(Object *obj, Error **errp)
 {
     return !ARM_CPU(obj)->kvm_adjvtime;
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 05c3de8cd46e..8d1f20ca8d89 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -221,6 +221,8 @@ int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level);
 
 void kvm_arm_enable_mte(Object *cpuobj, Error **errp);
 
+int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap);
+
 #else
 
 /*
@@ -247,6 +249,11 @@ static inline bool kvm_arm_mte_supported(void)
     return false;
 }
 
+static inline int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap)
+{
+    return -ENOSYS;
+}
+
 /*
  * These functions should never actually be called without KVM support.
  */
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 05/10] arm/cpu: accessors for writable id registers
  2025-04-14 16:38 [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
                   ` (3 preceding siblings ...)
  2025-04-14 16:38 ` [PATCH v3 04/10] kvm: kvm_get_writable_id_regs Cornelia Huck
@ 2025-04-14 16:38 ` Cornelia Huck
  2025-04-29 16:27   ` Sebastian Ott
  2025-04-14 16:38 ` [PATCH v3 06/10] arm/kvm: Allow reading all the writable ID registers Cornelia Huck
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 58+ messages in thread
From: Cornelia Huck @ 2025-04-14 16:38 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck

Also add conversion between the different indices.

Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
 target/arm/cpu.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index bbee7ff2414a..775a8aebc5d3 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -876,6 +876,13 @@ typedef struct IdRegMap {
     uint64_t regs[NR_ID_REGS];
 } IdRegMap;
 
+#define ARM_FEATURE_ID_RANGE_IDX(op0, op1, crn, crm, op2)               \
+        ({                                                              \
+                __u64 __op1 = (op1) & 3;                                \
+                __op1 -= (__op1 == 3);                                  \
+                (__op1 << 6 | ((crm) & 7) << 3 | (op2));                \
+        })
+
 /* REG is ID_XXX */
 #define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE)                       \
     ({                                                                  \
@@ -923,6 +930,17 @@ typedef struct IdRegMap {
         i_->idregs[REG ## _EL1_IDX];                                    \
     })
 
+#define GET_IDREG_WRITABLE(MAP, REG)                                  \
+    ({                                                                \
+    const IdRegMap *m_ = (MAP);                                       \
+    int index = ARM_FEATURE_ID_RANGE_IDX((sysreg >> 14) & 0x0000c000, \
+                                         (sysreg >> 11) & 0x00003800, \
+                                         (sysreg >> 7) & 0x00000780,  \
+                                         (sysreg >> 3) & 0x00000078,  \
+                                         sysreg & 0x00000007);        \
+    m_->regs[index];                                                  \
+    })
+
 /**
  * ARMCPU:
  * @env: #CPUARMState
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 06/10] arm/kvm: Allow reading all the writable ID registers
  2025-04-14 16:38 [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
                   ` (4 preceding siblings ...)
  2025-04-14 16:38 ` [PATCH v3 05/10] arm/cpu: accessors for writable id registers Cornelia Huck
@ 2025-04-14 16:38 ` Cornelia Huck
  2025-05-13 14:31   ` Eric Auger
  2025-05-23  8:27   ` Shameerali Kolothum Thodi via
  2025-04-14 16:38 ` [PATCH v3 07/10] arm/kvm: write back modified ID regs to KVM Cornelia Huck
                   ` (5 subsequent siblings)
  11 siblings, 2 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-04-14 16:38 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck

From: Eric Auger <eric.auger@redhat.com>

At the moment kvm_arm_get_host_cpu_features() reads a subset of the
ID regs. As we want to introduce properties for all writable ID reg
fields, we want more genericity and read more default host register
values.

Introduce a new get_host_cpu_idregs() helper and add a new exhaustive
boolean parameter to kvm_arm_get_host_cpu_features() and
kvm_arm_set_cpu_features_from_host() to select the right behavior.
The host cpu model will keep the legacy behavior unless the writable
id register interface is available.

A writable_map IdRegMap is introduced in the CPU object. A subsequent
patch will populate it.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
 target/arm/cpu-sysregs.h |  2 ++
 target/arm/cpu.h         |  3 ++
 target/arm/cpu64.c       |  2 +-
 target/arm/kvm.c         | 78 ++++++++++++++++++++++++++++++++++++++--
 target/arm/kvm_arm.h     |  9 +++--
 target/arm/trace-events  |  1 +
 6 files changed, 89 insertions(+), 6 deletions(-)

diff --git a/target/arm/cpu-sysregs.h b/target/arm/cpu-sysregs.h
index e89a1105904c..367fab51f19e 100644
--- a/target/arm/cpu-sysregs.h
+++ b/target/arm/cpu-sysregs.h
@@ -41,6 +41,8 @@ int get_sysreg_idx(ARMSysRegs sysreg);
 
 #ifdef CONFIG_KVM
 uint64_t idregs_sysreg_to_kvm_reg(ARMSysRegs sysreg);
+int kvm_idx_to_idregs_idx(int kidx);
+int idregs_idx_to_kvm_idx(ARMIDRegisterIdx idx);
 #endif
 
 #endif /* ARM_CPU_SYSREGS_H */
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 775a8aebc5d3..8717c5e7695b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1088,6 +1088,9 @@ struct ArchCPU {
      */
     ARMIdRegsState writable_id_regs;
 
+    /* ID reg writable bitmask (KVM only) */
+    IdRegMap *writable_map;
+
     /* QOM property to indicate we should use the back-compat CNTFRQ default */
     bool backcompat_cntfrq;
 
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 839442745ea4..60a709502697 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -757,7 +757,7 @@ static void aarch64_host_initfn(Object *obj)
 {
 #if defined(CONFIG_KVM)
     ARMCPU *cpu = ARM_CPU(obj);
-    kvm_arm_set_cpu_features_from_host(cpu);
+    kvm_arm_set_cpu_features_from_host(cpu, false);
     if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
         aarch64_add_sve_properties(obj);
         aarch64_add_pauth_properties(obj);
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 6e3cd06e9bc5..b07d5f16db50 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -41,6 +41,7 @@
 #include "hw/acpi/ghes.h"
 #include "target/arm/gtimer.h"
 #include "migration/blocker.h"
+#include "cpu-custom.h"
 
 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
     KVM_CAP_INFO(DEVICE_CTRL),
@@ -270,7 +271,73 @@ static int get_host_cpu_reg(int fd, ARMHostCPUFeatures *ahcf, ARMIDRegisterIdx i
     return ret;
 }
 
-static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
+int kvm_idx_to_idregs_idx(int kidx)
+{
+    int op1, crm, op2;
+    ARMSysRegs sysreg;
+
+    op1 = kidx / 64;
+    if (op1 == 2) {
+        op1 = 3;
+    }
+    crm = (kidx % 64) / 8;
+    op2 = kidx % 8;
+    sysreg = ENCODE_ID_REG(3, op1, 0, crm, op2);
+    return get_sysreg_idx(sysreg);
+}
+
+int idregs_idx_to_kvm_idx(ARMIDRegisterIdx idx)
+{
+    ARMSysRegs sysreg = id_register_sysreg[idx];
+
+    return KVM_ARM_FEATURE_ID_RANGE_IDX((sysreg & CP_REG_ARM64_SYSREG_OP0_MASK) >> CP_REG_ARM64_SYSREG_OP0_SHIFT,
+                                        (sysreg & CP_REG_ARM64_SYSREG_OP1_MASK) >> CP_REG_ARM64_SYSREG_OP1_SHIFT,
+                                        (sysreg & CP_REG_ARM64_SYSREG_CRN_MASK) >> CP_REG_ARM64_SYSREG_CRN_SHIFT,
+                                        (sysreg & CP_REG_ARM64_SYSREG_CRM_MASK) >> CP_REG_ARM64_SYSREG_CRM_SHIFT,
+                                        (sysreg & CP_REG_ARM64_SYSREG_OP2_MASK) >> CP_REG_ARM64_SYSREG_OP2_SHIFT);
+}
+
+
+/*
+ * get_host_cpu_idregs: Read all the writable ID reg host values
+ *
+ * Need to be called once the writable mask has been populated
+ * Note we may want to read all the known id regs but some of them are not
+ * writable and return an error, hence the choice of reading only those which
+ * are writable. Those are also readable!
+ */
+static int get_host_cpu_idregs(ARMCPU *cpu, int fd, ARMHostCPUFeatures *ahcf)
+{
+    int err = 0;
+    int i;
+
+    for (i = 0; i < NUM_ID_IDX; i++) {
+        ARM64SysReg *sysregdesc = &arm64_id_regs[i];
+        ARMSysRegs sysreg = sysregdesc->sysreg;
+        uint64_t writable_mask = cpu->writable_map->regs[idregs_idx_to_kvm_idx(i)];
+        uint64_t *reg;
+        int ret;
+
+        if (!writable_mask) {
+            continue;
+        }
+
+        reg = &ahcf->isar.idregs[i];
+        ret = read_sys_reg64(fd, reg, idregs_sysreg_to_kvm_reg(sysreg));
+        trace_get_host_cpu_idregs(sysregdesc->name, *reg);
+        if (ret) {
+            error_report("%s error reading value of host %s register (%m)",
+                         __func__, sysregdesc->name);
+
+            err = ret;
+        }
+    }
+    return err;
+}
+
+static bool
+kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf,
+                              bool exhaustive)
 {
     /* Identify the feature bits corresponding to the host CPU, and
      * fill out the ARMHostCPUClass fields accordingly. To do this
@@ -398,6 +465,11 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
         err |= get_host_cpu_reg(fd, ahcf, ID_DFR1_EL1_IDX);
         err |= get_host_cpu_reg(fd, ahcf, ID_MMFR5_EL1_IDX);
 
+        /* Make sure writable ID reg values are read */
+        if (exhaustive) {
+            err |= get_host_cpu_idregs(cpu, fd, ahcf);
+        }
+
         /*
          * DBGDIDR is a bit complicated because the kernel doesn't
          * provide an accessor for it in 64-bit mode, which is what this
@@ -467,13 +539,13 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
     return true;
 }
 
-void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
+void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, bool exhaustive)
 {
     CPUARMState *env = &cpu->env;
 
     if (!arm_host_cpu_features.dtb_compatible) {
         if (!kvm_enabled() ||
-            !kvm_arm_get_host_cpu_features(&arm_host_cpu_features)) {
+            !kvm_arm_get_host_cpu_features(cpu, &arm_host_cpu_features, exhaustive)) {
             /* We can't report this error yet, so flag that we need to
              * in arm_cpu_realizefn().
              */
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 8d1f20ca8d89..90ba4f7d8987 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -141,8 +141,12 @@ uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu);
  *
  * Set up the ARMCPU struct fields up to match the information probed
  * from the host CPU.
+ *
+ * @cpu: cpu object
+ * @exhaustive: if true, all the feature ID regs are queried instead of
+ *              a subset
  */
-void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
+void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, bool exhaustive);
 
 /**
  * kvm_arm_add_vcpu_properties:
@@ -257,7 +261,8 @@ static inline int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap)
 /*
  * These functions should never actually be called without KVM support.
  */
-static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
+static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu,
+                                                      bool exhaustive)
 {
     g_assert_not_reached();
 }
diff --git a/target/arm/trace-events b/target/arm/trace-events
index 4438dce7becc..17e52c0705f2 100644
--- a/target/arm/trace-events
+++ b/target/arm/trace-events
@@ -13,3 +13,4 @@ arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
 
 # kvm.c
 kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
+get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host value for %s is 0x%"PRIx64
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 07/10] arm/kvm: write back modified ID regs to KVM
  2025-04-14 16:38 [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
                   ` (5 preceding siblings ...)
  2025-04-14 16:38 ` [PATCH v3 06/10] arm/kvm: Allow reading all the writable ID registers Cornelia Huck
@ 2025-04-14 16:38 ` Cornelia Huck
  2025-04-15  7:03   ` Philippe Mathieu-Daudé
                     ` (2 more replies)
  2025-04-14 16:38 ` [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model Cornelia Huck
                   ` (4 subsequent siblings)
  11 siblings, 3 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-04-14 16:38 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck

From: Eric Auger <eric.auger@redhat.com>

We want to give a chance to override the value of host ID regs.
In a previous patch we made sure all their values could be fetched
through kvm_get_one_reg() calls before their modification. After
their potential modification we need to make sure we write back
the values through kvm_set_one_reg() calls.

Make sure the cpreg_list is modified with updated values and
transfer those values back to kvm.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
 target/arm/kvm.c        | 44 ++++++++++++++++++++++++++++++++++++++++-
 target/arm/trace-events |  1 +
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index b07d5f16db50..9e4cca1705c8 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -1083,6 +1083,39 @@ void kvm_arm_cpu_post_load(ARMCPU *cpu)
     }
 }
 
+static void kvm_arm_writable_idregs_to_cpreg_list(ARMCPU *cpu)
+{
+    if (!cpu->writable_map) {
+        return;
+    }
+    for (int i = 0; i < NR_ID_REGS; i++) {
+        uint64_t writable_mask = cpu->writable_map->regs[i];
+        uint64_t *cpreg;
+
+        if (writable_mask) {
+            uint64_t previous, new;
+            int idx = kvm_idx_to_idregs_idx(i);
+            ARM64SysReg *sysregdesc;
+            uint32_t sysreg;
+
+            if (idx == -1) {
+                /* sysreg writable, but we don't know it */
+                continue;
+            }
+            sysregdesc = &arm64_id_regs[idx];
+            sysreg = sysregdesc->sysreg;
+            cpreg = kvm_arm_get_cpreg_ptr(cpu, idregs_sysreg_to_kvm_reg(sysreg));
+            previous = *cpreg;
+            new = cpu->isar.idregs[idx];
+            if (previous != new) {
+                *cpreg = new;
+                trace_kvm_arm_writable_idregs_to_cpreg_list(sysregdesc->name,
+                                                            previous, new);
+            }
+        }
+    }
+}
+
 void kvm_arm_reset_vcpu(ARMCPU *cpu)
 {
     int ret;
@@ -2050,7 +2083,16 @@ int kvm_arch_init_vcpu(CPUState *cs)
     }
     cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
 
-    return kvm_arm_init_cpreg_list(cpu);
+    ret = kvm_arm_init_cpreg_list(cpu);
+    if (ret) {
+        return ret;
+    }
+    /* overwrite writable ID regs with their updated property values */
+    kvm_arm_writable_idregs_to_cpreg_list(cpu);
+
+    write_list_to_kvmstate(cpu, 3);
+
+    return 0;
 }
 
 int kvm_arch_destroy_vcpu(CPUState *cs)
diff --git a/target/arm/trace-events b/target/arm/trace-events
index 17e52c0705f2..955149ee1ac4 100644
--- a/target/arm/trace-events
+++ b/target/arm/trace-events
@@ -14,3 +14,4 @@ arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
 # kvm.c
 kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
 get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host value for %s is 0x%"PRIx64
+kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint64_t new) "%s overwrite default 0x%"PRIx64" with 0x%"PRIx64
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model
  2025-04-14 16:38 [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
                   ` (6 preceding siblings ...)
  2025-04-14 16:38 ` [PATCH v3 07/10] arm/kvm: write back modified ID regs to KVM Cornelia Huck
@ 2025-04-14 16:38 ` Cornelia Huck
  2025-05-13 14:47   ` Eric Auger
                     ` (2 more replies)
  2025-04-14 16:38 ` [PATCH v3 09/10] arm-qmp-cmds: introspection for ID register props Cornelia Huck
                   ` (3 subsequent siblings)
  11 siblings, 3 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-04-14 16:38 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck

From: Eric Auger <eric.auger@redhat.com>

If the interface for writable ID registers is available, expose uint64
SYSREG properties for writable ID reg fields exposed by the host
kernel. Properties are named  SYSREG_<REG>_<FIELD> with REG and FIELD
being those used  in linux arch/arm64/tools/sysreg. This done by
matching the writable fields retrieved from the host kernel against the
generated description of sysregs.

An example of invocation is:
-cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0
which sets DP field of ID_AA64ISAR0_EL1 to 0.

[CH: add properties to the host model instead of introducing a new
"custom" model]
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>

---

Interaction with the existing cpu properties is still a bit unclear --
at the moment, the different configurations can overwrite each other.
---
 target/arm/cpu.c        |  12 ++++
 target/arm/cpu64.c      |  22 ++++++-
 target/arm/kvm.c        | 135 ++++++++++++++++++++++++++++++++++++++++
 target/arm/kvm_arm.h    |  10 +++
 target/arm/trace-events |   4 ++
 5 files changed, 182 insertions(+), 1 deletion(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index a3de5ee2b19c..c03f38ad5cfe 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1991,6 +1991,18 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
         return;
     }
 
+    /*
+     * If we failed to retrieve the set of writable ID registers for the "host"
+     * CPU model, report it here. No error if the interface for discovering
+     * writable ID registers is not available.
+     * In case we did get the set of writable ID registers, set the features to
+     * the configured values here and perform some sanity checks.
+     */
+    if (cpu->writable_id_regs == WRITABLE_ID_REGS_FAILED) {
+        error_setg(errp, "Failed to discover writable id registers");
+        return;
+    }
+
     if (!cpu->gt_cntfrq_hz) {
         /*
          * 0 means "the board didn't set a value, use the default". (We also
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 60a709502697..c595dbb532c1 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -757,11 +757,31 @@ static void aarch64_host_initfn(Object *obj)
 {
 #if defined(CONFIG_KVM)
     ARMCPU *cpu = ARM_CPU(obj);
-    kvm_arm_set_cpu_features_from_host(cpu, false);
+    bool expose_id_regs = true;
+    int ret;
+
+    cpu->writable_map = g_malloc(sizeof(IdRegMap));
+
+    /* discover via KVM_ARM_GET_REG_WRITABLE_MASKS */
+    ret = kvm_arm_get_writable_id_regs(cpu, cpu->writable_map);
+    if (ret == -ENOSYS) {
+        /* legacy: continue without writable id regs */
+        expose_id_regs = false;
+    } else if (ret) {
+        /* function will have marked an error */
+        return;
+    }
+
+    kvm_arm_set_cpu_features_from_host(cpu, expose_id_regs);
     if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
         aarch64_add_sve_properties(obj);
         aarch64_add_pauth_properties(obj);
     }
+    if (expose_id_regs) {
+        /* generate SYSREG properties according to writable masks */
+        kvm_arm_expose_idreg_properties(cpu, arm64_id_regs);
+    }
+
 #elif defined(CONFIG_HVF)
     ARMCPU *cpu = ARM_CPU(obj);
     hvf_arm_set_cpu_features_from_host(cpu);
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 9e4cca1705c8..63e27906cc42 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -335,6 +335,141 @@ static int get_host_cpu_idregs(ARMCPU *cpu, int fd, ARMHostCPUFeatures *ahcf)
     return err;
 }
 
+static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
+{
+    GList *l;
+
+    for (l = reg->fields; l; l = l->next) {
+        ARM64SysRegField *field = (ARM64SysRegField *)l->data;
+
+        if (i >= field->lower && i <= field->upper) {
+            return field;
+        }
+    }
+    return NULL;
+}
+
+static void set_sysreg_prop(Object *obj, Visitor *v,
+                            const char *name, void *opaque,
+                            Error **errp)
+{
+    ARM64SysRegField *field = (ARM64SysRegField *)opaque;
+    ARMCPU *cpu = ARM_CPU(obj);
+    uint64_t *idregs = cpu->isar.idregs;
+    uint64_t old, value, mask;
+    int lower = field->lower;
+    int upper = field->upper;
+    int length = upper - lower + 1;
+    int index = field->index;
+
+    if (!visit_type_uint64(v, name, &value, errp)) {
+        return;
+    }
+
+    if (length < 64 && value > ((1 << length) - 1)) {
+        error_setg(errp,
+                   "idreg %s set value (0x%lx) exceeds length of field (%d)!",
+                   name, value, length);
+        return;
+    }
+
+    mask = MAKE_64BIT_MASK(lower, length);
+    value = value << lower;
+    old = idregs[index];
+    idregs[index] = old & ~mask;
+    idregs[index] |= value;
+    trace_set_sysreg_prop(name, old, mask, value, idregs[index]);
+}
+
+static void get_sysreg_prop(Object *obj, Visitor *v,
+                            const char *name, void *opaque,
+                            Error **errp)
+{
+    ARM64SysRegField *field = (ARM64SysRegField *)opaque;
+    ARMCPU *cpu = ARM_CPU(obj);
+    uint64_t *idregs = cpu->isar.idregs;
+    uint64_t value, mask;
+    int lower = field->lower;
+    int upper = field->upper;
+    int length = upper - lower + 1;
+    int index = field->index;
+
+    mask = MAKE_64BIT_MASK(lower, length);
+    value = (idregs[index] & mask) >> lower;
+    visit_type_uint64(v, name, &value, errp);
+    trace_get_sysreg_prop(name, value);
+}
+
+/*
+ * decode_idreg_writemap: Generate props for writable fields
+ *
+ * @obj: CPU object
+ * @index: index of the sysreg
+ * @map: writable map for the sysreg
+ * @reg: description of the sysreg
+ */
+static int
+decode_idreg_writemap(Object *obj, int index, uint64_t map, ARM64SysReg *reg)
+{
+    int i = ctz64(map);
+    int nb_sysreg_props = 0;
+
+    while (map) {
+
+        ARM64SysRegField *field = get_field(i, reg);
+        int lower, upper;
+        uint64_t mask;
+        char *prop_name;
+
+        if (!field) {
+            /* the field cannot be matched to any know id named field */
+            warn_report("%s bit %d of %s is writable but cannot be matched",
+                        __func__, i, reg->name);
+            warn_report("%s is cpu-sysreg-properties.c up to date?", __func__);
+            map =  map & ~BIT_ULL(i);
+            i = ctz64(map);
+            continue;
+        }
+        lower = field->lower;
+        upper = field->upper;
+        prop_name = g_strdup_printf("SYSREG_%s_%s", reg->name, field->name);
+        trace_decode_idreg_writemap(field->name, lower, upper, prop_name);
+        object_property_add(obj, prop_name, "uint64",
+                            get_sysreg_prop, set_sysreg_prop, NULL, field);
+        nb_sysreg_props++;
+
+        mask = MAKE_64BIT_MASK(lower, upper - lower + 1);
+        map = map & ~mask;
+        i = ctz64(map);
+    }
+    trace_nb_sysreg_props(reg->name, nb_sysreg_props);
+    return 0;
+}
+
+/* analyze the writable mask and generate properties for writable fields */
+void kvm_arm_expose_idreg_properties(ARMCPU *cpu, ARM64SysReg *regs)
+{
+    int i, idx;
+    IdRegMap *map = cpu->writable_map;
+    Object *obj = OBJECT(cpu);
+
+    for (i = 0; i < NR_ID_REGS; i++) {
+        uint64_t mask = map->regs[i];
+
+        if (mask) {
+            /* reg @i has some writable fields, decode them */
+            idx = kvm_idx_to_idregs_idx(i);
+            if (idx < 0) {
+                /* no matching reg? */
+                warn_report("%s: reg %d writable, but not in list of idregs?",
+                            __func__, i);
+            } else {
+                decode_idreg_writemap(obj, i, mask, &regs[idx]);
+            }
+        }
+    }
+}
+
 static bool
 kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf,
                               bool exhaustive)
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 90ba4f7d8987..ba5de45f868c 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -157,6 +157,16 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, bool exhaustive);
  */
 void kvm_arm_add_vcpu_properties(ARMCPU *cpu);
 
+typedef struct ARM64SysReg ARM64SysReg;
+/**
+ * kvm_arm_expose_idreg_properties:
+ * @cpu: The CPU object to generate the properties for
+ * @reg: registers from the host
+ *
+ * analyze the writable mask and generate properties for writable fields
+ */
+void kvm_arm_expose_idreg_properties(ARMCPU *cpu, ARM64SysReg *regs);
+
 /**
  * kvm_arm_steal_time_finalize:
  * @cpu: ARMCPU for which to finalize kvm-steal-time
diff --git a/target/arm/trace-events b/target/arm/trace-events
index 955149ee1ac4..8d2a234d5272 100644
--- a/target/arm/trace-events
+++ b/target/arm/trace-events
@@ -15,3 +15,7 @@ arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
 kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
 get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host value for %s is 0x%"PRIx64
 kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint64_t new) "%s overwrite default 0x%"PRIx64" with 0x%"PRIx64
+decode_idreg_writemap(const char* name, int lower, int upper, char *prop_name) "%s [%d:%d] is writable (prop %s)"
+get_sysreg_prop(const char *name, uint64_t value) "%s 0x%"PRIx64
+set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_value, uint64_t new) "%s old reg value=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new reg value=0x%"PRIx64
+nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 09/10] arm-qmp-cmds: introspection for ID register props
  2025-04-14 16:38 [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
                   ` (7 preceding siblings ...)
  2025-04-14 16:38 ` [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model Cornelia Huck
@ 2025-04-14 16:38 ` Cornelia Huck
  2025-05-13 14:50   ` Eric Auger
  2025-04-14 16:38 ` [PATCH v3 10/10] arm/cpu-features: document ID reg properties Cornelia Huck
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 58+ messages in thread
From: Cornelia Huck @ 2025-04-14 16:38 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck

Implement the capability to query available ID register values by
adding SYSREG_* options and values to the cpu model expansion for the
host model, if available.

Excerpt:
(QEMU) query-cpu-model-expansion type=full model={"name":"host"}
{"return": {"model": {"name": "host", "props":
{"SYSREG_ID_AA64PFR0_EL1_EL3": 1224979098931106066,
"SYSREG_ID_AA64ISAR2_EL1_CLRBHB": 0,
../..

So this allows the upper stack to detect available writable ID
regs and the "host passthrough model" values.

[CH: moved SYSREG_* values to host model]
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>

---

TODO: Add the moment there is no way to test changing a given
ID reg field value. ie:

(QEMU) query-cpu-model-expansion type=full model={"name":"host", "prop":{"SYSREG_ID_AA64ISAR0_EL1_DP":0x13}}
---
 target/arm/arm-qmp-cmds.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
index 883c0a0e8cce..5f48c7d835e1 100644
--- a/target/arm/arm-qmp-cmds.c
+++ b/target/arm/arm-qmp-cmds.c
@@ -21,6 +21,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/error-report.h"
 #include "hw/boards.h"
 #include "kvm_arm.h"
 #include "qapi/error.h"
@@ -209,6 +210,24 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
         }
     }
 
+    /* If writable ID regs are supported, add them as well */
+    if (ARM_CPU(obj)->writable_id_regs == WRITABLE_ID_REGS_AVAIL) {
+        ObjectProperty *prop;
+        ObjectPropertyIterator iter;
+
+        object_property_iter_init(&iter, obj);
+
+        while ((prop = object_property_iter_next(&iter))) {
+            QObject *value;
+
+            if (!g_str_has_prefix(prop->name, "SYSREG_")) {
+                continue;
+            }
+            value = object_property_get_qobject(obj, prop->name, &error_abort);
+            qdict_put_obj(qdict_out, prop->name, value);
+        }
+    }
+
     if (!qdict_size(qdict_out)) {
         qobject_unref(qdict_out);
     } else {
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v3 10/10] arm/cpu-features: document ID reg properties
  2025-04-14 16:38 [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
                   ` (8 preceding siblings ...)
  2025-04-14 16:38 ` [PATCH v3 09/10] arm-qmp-cmds: introspection for ID register props Cornelia Huck
@ 2025-04-14 16:38 ` Cornelia Huck
  2025-05-13 15:09   ` Eric Auger
  2025-05-13 16:23   ` Daniel P. Berrangé
  2025-05-13 15:29 ` [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
  2025-05-23 13:23 ` Shameerali Kolothum Thodi via
  11 siblings, 2 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-04-14 16:38 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck

Add some documentation for how individual ID registers can be
configured with the host cpu model.

[CH: adapt to removal of the 'custom' model, added some more
 explanations about using the ID register props]
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
 docs/system/arm/cpu-features.rst | 104 ++++++++++++++++++++++++++++---
 1 file changed, 96 insertions(+), 8 deletions(-)

diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
index 37d5dfd15b34..22faefd76edd 100644
--- a/docs/system/arm/cpu-features.rst
+++ b/docs/system/arm/cpu-features.rst
@@ -2,7 +2,10 @@ Arm CPU Features
 ================
 
 CPU features are optional features that a CPU of supporting type may
-choose to implement or not.  In QEMU, optional CPU features have
+choose to implement or not.  QEMU provides two different mechanisms
+to configure those features:
+
+1. For most CPU models, optional CPU features may have
 corresponding boolean CPU proprieties that, when enabled, indicate
 that the feature is implemented, and, conversely, when disabled,
 indicate that it is not implemented. An example of an Arm CPU feature
@@ -29,6 +32,16 @@ supports the feature.  While ``aarch64`` currently only works with KVM,
 it could work with TCG.  CPU features that are specific to KVM are
 prefixed with "kvm-" and are described in "KVM VCPU Features".
 
+2. Additionally, the ``host`` CPU model on KVM allows to configure optional
+CPU features via the corresponding ID registers. The host kernel allows
+to write a subset of ID register fields. The host model exposes
+properties for each writable ID register field. Those options are named
+SYSREG_<IDREG>_<FIELD>. IDREG and FIELD names are those used in the
+ARM ARM Reference Manual. They can also be found in the Linux
+arch/arm64/tool/sysreg file which is used to automatically generate the
+description for those registers and fields. This currently only has been
+implemented for KVM.
+
 CPU Feature Probing
 ===================
 
@@ -124,13 +137,20 @@ A note about CPU models and KVM
 
 Named CPU models generally do not work with KVM.  There are a few cases
 that do work, e.g. using the named CPU model ``cortex-a57`` with KVM on a
-seattle host, but mostly if KVM is enabled the ``host`` CPU type must be
-used.  This means the guest is provided all the same CPU features as the
-host CPU type has.  And, for this reason, the ``host`` CPU type should
-enable all CPU features that the host has by default.  Indeed it's even
-a bit strange to allow disabling CPU features that the host has when using
-the ``host`` CPU type, but in the absence of CPU models it's the best we can
-do if we want to launch guests without all the host's CPU features enabled.
+seattle host, but mostly if KVM is enabled, the ``host`` CPU model must be
+used.
+
+Using the ``host`` type means the guest is provided all the same CPU
+features as the host CPU type has.  And, for this reason, the ``host``
+CPU type should enable all CPU features that the host has by default.
+
+In case some features need to be hidden to the guest, and the host kernel
+supports it, the ``host`` model can be instructed to disable individual
+ID register values. This is especially useful for migration purposes.
+However, this interface will not allow configuring an arbitrary set of
+features; the ID registers must describe a subset of the host's features,
+and all differences to the host's configuration must actually be supported
+by the kernel to be deconfigured.
 
 Enabling KVM also affects the ``query-cpu-model-expansion`` QMP command.  The
 affect is not only limited to specific features, as pointed out in example
@@ -167,6 +187,13 @@ disabling many SVE vector lengths would be quite verbose, the ``sve<N>`` CPU
 properties have special semantics (see "SVE CPU Property Parsing
 Semantics").
 
+Additionally, if supported by KVM on the host kernel, the ``host`` CPU model
+may be configured via individual ID register field properties, for example::
+
+  $ qemu-system-aarch64 -M virt -cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0
+
+This forces ID_AA64ISAR0_EL1 DP field to 0.
+
 KVM VCPU Features
 =================
 
@@ -466,3 +493,64 @@ Legal values for ``S`` are 30, 34, 36, and 39; the default is 30.
 
 As with ``x-rme``, the ``x-l0gptsz`` property may be renamed or
 removed in some future QEMU release.
+
+Configuring CPU features via ID register fields
+===============================================
+
+Note that this is currently only supported under KVM, and with the
+``host`` CPU model.
+
+Querying available ID register fields
+-------------------------------------
+
+QEMU will create properties for all ID register fields that are
+reported as being writable by the kernel, and that are known to the
+QEMU instance. Therefore, the same QEMU binary may expose different
+properties when run under a different kernel.
+
+To find out all available writable ID register fields, use the
+``query-cpu-model-expansion`` QMP command::
+
+  (QEMU) query-cpu-model-expansion type=full model={"name":"host"}
+  {"return": {
+   "model": {"name": "host", "props": {
+   "SYSREG_ID_AA64PFR0_EL1_EL3": 1, "SYSREG_ID_AA64ISAR2_EL1_CLRBHB": 0,
+   "SYSREG_CTR_EL0_L1Ip": 3, "SYSREG_CTR_EL0_DminLine": 4,
+   "SYSREG_ID_AA64MMFR0_EL1_BIGEND": 1, "SYSREG_ID_AA64MMFR1_EL1_ECBHB": 0,
+   "SYSREG_ID_AA64MMFR2_EL1_CnP": 1, "SYSREG_ID_DFR0_EL1_PerfMon": 4,
+   "SYSREG_ID_AA64PFR0_EL1_DIT": 0, "SYSREG_ID_AA64MMFR1_EL1_HAFDBS": 2,
+   "SYSREG_ID_AA64ISAR0_EL1_FHM": 0, "SYSREG_ID_AA64ISAR2_EL1_CSSC": 0,
+   "SYSREG_ID_AA64ISAR0_EL1_DP": 1, (...)
+   }}}}
+
+If a certain field in an ID register does not show up in this list, it
+is not writable with the specific host kernel.
+
+A note on compatibility
+-----------------------
+
+A common use case for providing a defined set of ID register values is
+to be able to present a fixed set of features to a guest, often referred
+to as "stable guest ABI". This may take the form of ironing out differences
+between two similar CPUs with the intention of being able to migrate
+between machines with those CPUs, or providing the same CPU across Linux
+kernel updates on the host.
+
+Over the course of time, the Linux kernel is changing the set of ID register
+fields that are writable by userspace. Newly introduced writable ID
+registers should be initialized to 0 to ensure compatibility. However, ID
+registers that have already been introduced that undergo a change as to
+which fields are writable may introduce incompatibities that need to be
+addressed on a case-by-case basis for the systems that you wish to migrate
+inbetween.
+
+A note on Arm CPU features (FEAT_xxx)
+-------------------------------------
+
+Configuring CPUs is done on a feature level on other architectures, and this
+would imply configuring FEAT_xxx values on Arm. However, differences between
+CPUs may not map to FEAT_xxx, but to differences in other registers in the
+ID register range; for example, differences in the cache architecture exposed
+via ``CTR_EL0``. We therefore cannot rely on configuration via FEAT_xxx. A
+feature-based interface more similar to other architectures may be implemented
+on top of the ID register interface in the future.
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 07/10] arm/kvm: write back modified ID regs to KVM
  2025-04-14 16:38 ` [PATCH v3 07/10] arm/kvm: write back modified ID regs to KVM Cornelia Huck
@ 2025-04-15  7:03   ` Philippe Mathieu-Daudé
  2025-04-15  9:54     ` Cornelia Huck
  2025-05-13 14:33   ` Eric Auger
  2025-07-02  4:01   ` Jinqian Yang via
  2 siblings, 1 reply; 58+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-04-15  7:03 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro, eric.auger, qemu-devel, qemu-arm,
	kvmarm, peter.maydell, richard.henderson, alex.bennee, maz,
	oliver.upton, sebott, shameerali.kolothum.thodi, armbru, berrange,
	abologna, jdenemar
  Cc: agraf, shahuang, mark.rutland, pbonzini

On 14/4/25 18:38, Cornelia Huck wrote:
> From: Eric Auger <eric.auger@redhat.com>
> 
> We want to give a chance to override the value of host ID regs.
> In a previous patch we made sure all their values could be fetched
> through kvm_get_one_reg() calls before their modification. After
> their potential modification we need to make sure we write back
> the values through kvm_set_one_reg() calls.
> 
> Make sure the cpreg_list is modified with updated values and
> transfer those values back to kvm.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
>   target/arm/kvm.c        | 44 ++++++++++++++++++++++++++++++++++++++++-
>   target/arm/trace-events |  1 +
>   2 files changed, 44 insertions(+), 1 deletion(-)


>   void kvm_arm_reset_vcpu(ARMCPU *cpu)
>   {
>       int ret;
> @@ -2050,7 +2083,16 @@ int kvm_arch_init_vcpu(CPUState *cs)
>       }
>       cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
>   
> -    return kvm_arm_init_cpreg_list(cpu);
> +    ret = kvm_arm_init_cpreg_list(cpu);
> +    if (ret) {
> +        return ret;
> +    }
> +    /* overwrite writable ID regs with their updated property values */
> +    kvm_arm_writable_idregs_to_cpreg_list(cpu);
> +
> +    write_list_to_kvmstate(cpu, 3);

s/3/KVM_PUT_FULL_STATE/?

> +
> +    return 0;
>   }



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 02/10] arm/cpu: Add sysreg properties generation
  2025-04-14 16:38 ` [PATCH v3 02/10] arm/cpu: Add sysreg properties generation Cornelia Huck
@ 2025-04-15  7:09   ` Philippe Mathieu-Daudé
  2025-04-15  7:20     ` Philippe Mathieu-Daudé
  2025-05-19 14:49     ` Cornelia Huck
  2025-05-13 15:23   ` Daniel P. Berrangé
  1 sibling, 2 replies; 58+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-04-15  7:09 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro, eric.auger, qemu-devel, qemu-arm,
	kvmarm, peter.maydell, richard.henderson, alex.bennee, maz,
	oliver.upton, sebott, shameerali.kolothum.thodi, armbru, berrange,
	abologna, jdenemar
  Cc: agraf, shahuang, mark.rutland, pbonzini

On 14/4/25 18:38, Cornelia Huck wrote:
> From: Eric Auger <eric.auger@redhat.com>
> 
> Introduce a script that automates the generation of system register
> properties definitions from a given linux source tree
> arch/arm64/tools/sysreg.
> 
> Invocation of
> ./update-aarch64-sysreg-code.sh $PATH_TO_LINUX_SOURCE_TREE
> in scripts directory additionally generates
> target/arm/cpu-sysreg-properties.c containing definitions for
> feature ID registers.
> 
> update-aarch64-sysreg-code.sh additionally calls
> gen-cpu-sysreg-properties.awk which is inherited from kernel
> arch/arm64/tools/gen-sysreg.awk. All credits to Mark Rutland
> the original author of this script.
> 
> [CH: split off from original patch adding both sysreg definitions
>   and properties]
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
>   scripts/gen-cpu-sysreg-properties.awk | 325 ++++++++++++++++++++++++++
>   scripts/update-aarch64-sysreg-code.sh |   5 +-
>   2 files changed, 329 insertions(+), 1 deletion(-)
>   create mode 100755 scripts/gen-cpu-sysreg-properties.awk
> 
> diff --git a/scripts/gen-cpu-sysreg-properties.awk b/scripts/gen-cpu-sysreg-properties.awk
> new file mode 100755
> index 000000000000..76c37938b168
> --- /dev/null
> +++ b/scripts/gen-cpu-sysreg-properties.awk
> @@ -0,0 +1,325 @@
> +#!/bin/awk -f
> +# SPDX-License-Identifier: GPL-2.0
> +# gen-cpu-sysreg-properties.awk: arm64 sysreg header generator
> +#
> +# Usage: awk -f gen-cpu-sysreg-properties.awk $LINUX_PATH/arch/arm64/tools/sysreg


> +BEGIN {

         print "/* AUTOMATICALLY GENERATED, DO NOT MODIFY */\n"

Should we keep copyright?

> +	print "#include \"cpu-custom.h\""
> +	print ""
> +	print "ARM64SysReg arm64_id_regs[NUM_ID_IDX];"
> +	print ""
> +	print "void initialize_cpu_sysreg_properties(void)"
> +	print "{"
> +        print "    memset(arm64_id_regs, 0, sizeof(ARM64SysReg) * NUM_ID_IDX);"
> +        print ""
> +
> +	__current_block_depth = 0
> +	__current_block[__current_block_depth] = "Root"
> +}


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 02/10] arm/cpu: Add sysreg properties generation
  2025-04-15  7:09   ` Philippe Mathieu-Daudé
@ 2025-04-15  7:20     ` Philippe Mathieu-Daudé
  2025-05-19 14:49     ` Cornelia Huck
  1 sibling, 0 replies; 58+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-04-15  7:20 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro, eric.auger, qemu-devel, qemu-arm,
	kvmarm, peter.maydell, richard.henderson, alex.bennee, maz,
	oliver.upton, sebott, shameerali.kolothum.thodi, armbru, berrange,
	abologna, jdenemar
  Cc: agraf, shahuang, mark.rutland, pbonzini

On 15/4/25 09:09, Philippe Mathieu-Daudé wrote:
> On 14/4/25 18:38, Cornelia Huck wrote:
>> From: Eric Auger <eric.auger@redhat.com>
>>
>> Introduce a script that automates the generation of system register
>> properties definitions from a given linux source tree
>> arch/arm64/tools/sysreg.
>>
>> Invocation of
>> ./update-aarch64-sysreg-code.sh $PATH_TO_LINUX_SOURCE_TREE
>> in scripts directory additionally generates
>> target/arm/cpu-sysreg-properties.c containing definitions for
>> feature ID registers.
>>
>> update-aarch64-sysreg-code.sh additionally calls
>> gen-cpu-sysreg-properties.awk which is inherited from kernel
>> arch/arm64/tools/gen-sysreg.awk. All credits to Mark Rutland
>> the original author of this script.
>>
>> [CH: split off from original patch adding both sysreg definitions
>>   and properties]
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>> ---
>>   scripts/gen-cpu-sysreg-properties.awk | 325 ++++++++++++++++++++++++++
>>   scripts/update-aarch64-sysreg-code.sh |   5 +-
>>   2 files changed, 329 insertions(+), 1 deletion(-)
>>   create mode 100755 scripts/gen-cpu-sysreg-properties.awk
>>
>> diff --git a/scripts/gen-cpu-sysreg-properties.awk b/scripts/gen-cpu- 
>> sysreg-properties.awk
>> new file mode 100755
>> index 000000000000..76c37938b168
>> --- /dev/null
>> +++ b/scripts/gen-cpu-sysreg-properties.awk
>> @@ -0,0 +1,325 @@
>> +#!/bin/awk -f
>> +# SPDX-License-Identifier: GPL-2.0
>> +# gen-cpu-sysreg-properties.awk: arm64 sysreg header generator
>> +#
>> +# Usage: awk -f gen-cpu-sysreg-properties.awk $LINUX_PATH/arch/arm64/ 
>> tools/sysreg
> 
> 
>> +BEGIN {
> 
>          print "/* AUTOMATICALLY GENERATED, DO NOT MODIFY */\n"
> 
> Should we keep copyright?

(if so, preferably as SPDX tag)

> 
>> +    print "#include \"cpu-custom.h\""
>> +    print ""
>> +    print "ARM64SysReg arm64_id_regs[NUM_ID_IDX];"
>> +    print ""
>> +    print "void initialize_cpu_sysreg_properties(void)"
>> +    print "{"
>> +        print "    memset(arm64_id_regs, 0, sizeof(ARM64SysReg) * 
>> NUM_ID_IDX);"
>> +        print ""
>> +
>> +    __current_block_depth = 0
>> +    __current_block[__current_block_depth] = "Root"
>> +}



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 07/10] arm/kvm: write back modified ID regs to KVM
  2025-04-15  7:03   ` Philippe Mathieu-Daudé
@ 2025-04-15  9:54     ` Cornelia Huck
  0 siblings, 0 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-04-15  9:54 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, eric.auger.pro, eric.auger,
	qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson,
	alex.bennee, maz, oliver.upton, sebott, shameerali.kolothum.thodi,
	armbru, berrange, abologna, jdenemar
  Cc: agraf, shahuang, mark.rutland, pbonzini

On Tue, Apr 15 2025, Philippe Mathieu-Daudé <philmd@linaro.org> wrote:

> On 14/4/25 18:38, Cornelia Huck wrote:
>> From: Eric Auger <eric.auger@redhat.com>
>> 
>> We want to give a chance to override the value of host ID regs.
>> In a previous patch we made sure all their values could be fetched
>> through kvm_get_one_reg() calls before their modification. After
>> their potential modification we need to make sure we write back
>> the values through kvm_set_one_reg() calls.
>> 
>> Make sure the cpreg_list is modified with updated values and
>> transfer those values back to kvm.
>> 
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>> ---
>>   target/arm/kvm.c        | 44 ++++++++++++++++++++++++++++++++++++++++-
>>   target/arm/trace-events |  1 +
>>   2 files changed, 44 insertions(+), 1 deletion(-)
>
>
>>   void kvm_arm_reset_vcpu(ARMCPU *cpu)
>>   {
>>       int ret;
>> @@ -2050,7 +2083,16 @@ int kvm_arch_init_vcpu(CPUState *cs)
>>       }
>>       cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
>>   
>> -    return kvm_arm_init_cpreg_list(cpu);
>> +    ret = kvm_arm_init_cpreg_list(cpu);
>> +    if (ret) {
>> +        return ret;
>> +    }
>> +    /* overwrite writable ID regs with their updated property values */
>> +    kvm_arm_writable_idregs_to_cpreg_list(cpu);
>> +
>> +    write_list_to_kvmstate(cpu, 3);
>
> s/3/KVM_PUT_FULL_STATE/?

Indeed, that's more obvious. Thanks!



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 05/10] arm/cpu: accessors for writable id registers
  2025-04-14 16:38 ` [PATCH v3 05/10] arm/cpu: accessors for writable id registers Cornelia Huck
@ 2025-04-29 16:27   ` Sebastian Ott
  2025-04-30 13:48     ` Cornelia Huck
  0 siblings, 1 reply; 58+ messages in thread
From: Sebastian Ott @ 2025-04-29 16:27 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	shameerali.kolothum.thodi, armbru, berrange, abologna, jdenemar,
	agraf, shahuang, mark.rutland, philmd, pbonzini

On Mon, 14 Apr 2025, Cornelia Huck wrote:
> Also add conversion between the different indices.
>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
> target/arm/cpu.h | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index bbee7ff2414a..775a8aebc5d3 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -876,6 +876,13 @@ typedef struct IdRegMap {
>     uint64_t regs[NR_ID_REGS];
> } IdRegMap;
>
> +#define ARM_FEATURE_ID_RANGE_IDX(op0, op1, crn, crm, op2)               \
> +        ({                                                              \
> +                __u64 __op1 = (op1) & 3;                                \
> +                __op1 -= (__op1 == 3);                                  \
> +                (__op1 << 6 | ((crm) & 7) << 3 | (op2));                \
> +        })
> +
> /* REG is ID_XXX */
> #define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE)                       \
>     ({                                                                  \
> @@ -923,6 +930,17 @@ typedef struct IdRegMap {
>         i_->idregs[REG ## _EL1_IDX];                                    \
>     })
>
> +#define GET_IDREG_WRITABLE(MAP, REG)                                  \
> +    ({                                                                \
> +    const IdRegMap *m_ = (MAP);                                       \
> +    int index = ARM_FEATURE_ID_RANGE_IDX((sysreg >> 14) & 0x0000c000, \
> +                                         (sysreg >> 11) & 0x00003800, \
> +                                         (sysreg >> 7) & 0x00000780,  \
> +                                         (sysreg >> 3) & 0x00000078,  \
> +                                         sysreg & 0x00000007);        \
> +    m_->regs[index];                                                  \
> +    })
> +

s/sysreg/REG/

Also GET_IDREG_WRITABLE doesn't seem to be used in this series.

Sebastian



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 05/10] arm/cpu: accessors for writable id registers
  2025-04-29 16:27   ` Sebastian Ott
@ 2025-04-30 13:48     ` Cornelia Huck
  0 siblings, 0 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-04-30 13:48 UTC (permalink / raw)
  To: Sebastian Ott
  Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	shameerali.kolothum.thodi, armbru, berrange, abologna, jdenemar,
	agraf, shahuang, mark.rutland, philmd, pbonzini

On Tue, Apr 29 2025, Sebastian Ott <sebott@redhat.com> wrote:

> On Mon, 14 Apr 2025, Cornelia Huck wrote:
>> Also add conversion between the different indices.
>>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>> ---
>> target/arm/cpu.h | 18 ++++++++++++++++++
>> 1 file changed, 18 insertions(+)
>>
>> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
>> index bbee7ff2414a..775a8aebc5d3 100644
>> --- a/target/arm/cpu.h
>> +++ b/target/arm/cpu.h
>> @@ -876,6 +876,13 @@ typedef struct IdRegMap {
>>     uint64_t regs[NR_ID_REGS];
>> } IdRegMap;
>>
>> +#define ARM_FEATURE_ID_RANGE_IDX(op0, op1, crn, crm, op2)               \
>> +        ({                                                              \
>> +                __u64 __op1 = (op1) & 3;                                \
>> +                __op1 -= (__op1 == 3);                                  \
>> +                (__op1 << 6 | ((crm) & 7) << 3 | (op2));                \
>> +        })
>> +
>> /* REG is ID_XXX */
>> #define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE)                       \
>>     ({                                                                  \
>> @@ -923,6 +930,17 @@ typedef struct IdRegMap {
>>         i_->idregs[REG ## _EL1_IDX];                                    \
>>     })
>>
>> +#define GET_IDREG_WRITABLE(MAP, REG)                                  \
>> +    ({                                                                \
>> +    const IdRegMap *m_ = (MAP);                                       \
>> +    int index = ARM_FEATURE_ID_RANGE_IDX((sysreg >> 14) & 0x0000c000, \
>> +                                         (sysreg >> 11) & 0x00003800, \
>> +                                         (sysreg >> 7) & 0x00000780,  \
>> +                                         (sysreg >> 3) & 0x00000078,  \
>> +                                         sysreg & 0x00000007);        \
>> +    m_->regs[index];                                                  \
>> +    })
>> +
>
> s/sysreg/REG/
>
> Also GET_IDREG_WRITABLE doesn't seem to be used in this series.

Hm, and it wouldn't have worked if we did use it... probably an artifact
left over from earlier refactorings, I think we can get rid of it.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 01/10] arm/cpu: Add infra to handle generated ID register definitions
  2025-04-14 16:38 ` [PATCH v3 01/10] arm/cpu: Add infra to handle generated ID register definitions Cornelia Huck
@ 2025-05-13 13:52   ` Eric Auger
  2025-05-13 14:05     ` Cornelia Huck
  0 siblings, 1 reply; 58+ messages in thread
From: Eric Auger @ 2025-05-13 13:52 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini

Hi Connie,

On 4/14/25 6:38 PM, Cornelia Huck wrote:
> From: Eric Auger <eric.auger@redhat.com>
>
> The known ID regs are described in a new initialization function
> dubbed initialize_cpu_sysreg_properties(). That code will be
> automatically generated from linux arch/arm64/tools/sysreg. For the
> time being let's just describe a single id reg, CTR_EL0. In this
> description we only care about non RES/RAZ fields, ie. named fields.
>
> The registers are populated in an array indexed by ARMIDRegisterIdx
> and their fields are added in a sorted list.
>
> [CH: adapted to reworked register storage]
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
>  target/arm/cpu-custom.h            | 60 ++++++++++++++++++++++++++++++
>  target/arm/cpu-sysreg-properties.c | 41 ++++++++++++++++++++
>  target/arm/cpu64.c                 |  2 +
>  target/arm/meson.build             |  1 +
>  4 files changed, 104 insertions(+)
>  create mode 100644 target/arm/cpu-custom.h
do we still want reference to the "custom" terminology, following
initial comments?
>  create mode 100644 target/arm/cpu-sysreg-properties.c
>
> diff --git a/target/arm/cpu-custom.h b/target/arm/cpu-custom.h
> new file mode 100644
> index 000000000000..615347376e56
> --- /dev/null
> +++ b/target/arm/cpu-custom.h
> @@ -0,0 +1,60 @@
> +/*
> + * handle ID registers and their fields
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +#ifndef ARM_CPU_CUSTOM_H
> +#define ARM_CPU_CUSTOM_H
> +
> +#include "qemu/osdep.h"
> +#include "qemu/error-report.h"
> +#include "cpu.h"
> +#include "cpu-sysregs.h"
> +
> +typedef struct ARM64SysRegField {
> +    const char *name; /* name of the field, for instance CTR_EL0_IDC */
> +    int index;
worth to add a comment saying this is the ARMIDRegisterIdx of the parent
sysreg.
> +    int lower;
> +    int upper;
> +} ARM64SysRegField;
> +
> +typedef struct ARM64SysReg {
> +    const char *name;   /* name of the sysreg, for instance CTR_EL0 */
> +    ARMSysRegs sysreg;
> +    int index;
now that we have different kinds of indexing, may be worth adding a
comment to explain which one is being used.
I guess here it is ARMIDRegisterIdx. So you could even change the data type.
> +    GList *fields; /* list of named fields, excluding RES* */
> +} ARM64SysReg;
> +
> +void initialize_cpu_sysreg_properties(void);
> +
> +/*
> + * List of exposed ID regs (automatically populated from linux
> + * arch/arm64/tools/sysreg)
> + */
> +extern ARM64SysReg arm64_id_regs[NUM_ID_IDX];
> +
> +/* Allocate a new field and insert it at the head of the @reg list */
> +static inline GList *arm64_sysreg_add_field(ARM64SysReg *reg, const char *name,
> +                                     uint8_t min, uint8_t max) {
> +
> +     ARM64SysRegField *field = g_new0(ARM64SysRegField, 1);
> +
> +     field->name = name;
> +     field->lower = min;
> +     field->upper = max;
> +     field->index = reg->index;
> +
> +     reg->fields = g_list_append(reg->fields, field);
> +     return reg->fields;
> +}
> +
> +static inline ARM64SysReg *arm64_sysreg_get(ARMIDRegisterIdx index)
> +{
> +        ARM64SysReg *reg = &arm64_id_regs[index];
> +
> +        reg->index = index;
> +        reg->sysreg = id_register_sysreg[index];
> +        return reg;
> +}
> +
> +#endif
> diff --git a/target/arm/cpu-sysreg-properties.c b/target/arm/cpu-sysreg-properties.c
> new file mode 100644
> index 000000000000..8b7ef5badfb9
> --- /dev/null
> +++ b/target/arm/cpu-sysreg-properties.c
> @@ -0,0 +1,41 @@
> +/*
> + * QEMU ARM CPU SYSREG PROPERTIES
> + * to be generated from linux sysreg
> + *
> + * Copyright (c) Red Hat, Inc. 2024
maybe increment the year now ;-)
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, see
> + * <http://www.gnu.org/licenses/gpl-2.0.html>
> + */
> +
> +#include "cpu-custom.h"
> +
> +ARM64SysReg arm64_id_regs[NUM_ID_IDX];
> +
> +void initialize_cpu_sysreg_properties(void)
> +{
> +    memset(arm64_id_regs, 0, sizeof(ARM64SysReg) * NUM_ID_IDX);
> +    /* CTR_EL0 */
> +    ARM64SysReg *CTR_EL0 = arm64_sysreg_get(CTR_EL0_IDX);
> +    CTR_EL0->name = "CTR_EL0";
> +    arm64_sysreg_add_field(CTR_EL0, "TminLine", 32, 37);
> +    arm64_sysreg_add_field(CTR_EL0, "DIC", 29, 29);
> +    arm64_sysreg_add_field(CTR_EL0, "IDC", 28, 28);
> +    arm64_sysreg_add_field(CTR_EL0, "CWG", 24, 27);
> +    arm64_sysreg_add_field(CTR_EL0, "ERG", 20, 23);
> +    arm64_sysreg_add_field(CTR_EL0, "DminLine", 16, 19);
> +    arm64_sysreg_add_field(CTR_EL0, "L1Ip", 14, 15);
> +    arm64_sysreg_add_field(CTR_EL0, "IminLine", 0, 3);
> +}
> +
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index 9769401a8585..839442745ea4 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -35,6 +35,7 @@
>  #include "internals.h"
>  #include "cpu-features.h"
>  #include "cpregs.h"
> +#include "cpu-custom.h"
>  
>  /* convert between <register>_IDX and SYS_<register> */
>  #define DEF(NAME, OP0, OP1, CRN, CRM, OP2)      \
> @@ -891,6 +892,7 @@ static void aarch64_cpu_register_types(void)
>  {
>      size_t i;
>  
> +    initialize_cpu_sysreg_properties();
>      type_register_static(&aarch64_cpu_type_info);
>  
>      for (i = 0; i < ARRAY_SIZE(aarch64_cpus); ++i) {
> diff --git a/target/arm/meson.build b/target/arm/meson.build
> index 3065081d241d..1c97c1ef7580 100644
> --- a/target/arm/meson.build
> +++ b/target/arm/meson.build
> @@ -14,6 +14,7 @@ arm_ss.add(when: 'CONFIG_HVF', if_true: files('hyp_gdbstub.c'))
>  arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
>    'cpu64.c',
>    'gdbstub64.c',
> +  'cpu-sysreg-properties.c',
>  ))
>  
>  arm_system_ss = ss.source_set()



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 01/10] arm/cpu: Add infra to handle generated ID register definitions
  2025-05-13 13:52   ` Eric Auger
@ 2025-05-13 14:05     ` Cornelia Huck
  2025-05-13 15:12       ` Eric Auger
  0 siblings, 1 reply; 58+ messages in thread
From: Cornelia Huck @ 2025-05-13 14:05 UTC (permalink / raw)
  To: eric.auger, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini

On Tue, May 13 2025, Eric Auger <eric.auger@redhat.com> wrote:

> Hi Connie,
>
> On 4/14/25 6:38 PM, Cornelia Huck wrote:
>> From: Eric Auger <eric.auger@redhat.com>
>>
>> The known ID regs are described in a new initialization function
>> dubbed initialize_cpu_sysreg_properties(). That code will be
>> automatically generated from linux arch/arm64/tools/sysreg. For the
>> time being let's just describe a single id reg, CTR_EL0. In this
>> description we only care about non RES/RAZ fields, ie. named fields.
>>
>> The registers are populated in an array indexed by ARMIDRegisterIdx
>> and their fields are added in a sorted list.
>>
>> [CH: adapted to reworked register storage]
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>> ---
>>  target/arm/cpu-custom.h            | 60 ++++++++++++++++++++++++++++++
>>  target/arm/cpu-sysreg-properties.c | 41 ++++++++++++++++++++
>>  target/arm/cpu64.c                 |  2 +
>>  target/arm/meson.build             |  1 +
>>  4 files changed, 104 insertions(+)
>>  create mode 100644 target/arm/cpu-custom.h
> do we still want reference to the "custom" terminology, following
> initial comments?

Hm, maybe 'cpu-idregs.h'?

>>  create mode 100644 target/arm/cpu-sysreg-properties.c
>>
>> diff --git a/target/arm/cpu-custom.h b/target/arm/cpu-custom.h
>> new file mode 100644
>> index 000000000000..615347376e56
>> --- /dev/null
>> +++ b/target/arm/cpu-custom.h
>> @@ -0,0 +1,60 @@
>> +/*
>> + * handle ID registers and their fields
>> + *
>> + * SPDX-License-Identifier: GPL-2.0-or-later
>> + */
>> +#ifndef ARM_CPU_CUSTOM_H
>> +#define ARM_CPU_CUSTOM_H
>> +
>> +#include "qemu/osdep.h"
>> +#include "qemu/error-report.h"
>> +#include "cpu.h"
>> +#include "cpu-sysregs.h"
>> +
>> +typedef struct ARM64SysRegField {
>> +    const char *name; /* name of the field, for instance CTR_EL0_IDC */
>> +    int index;
> worth to add a comment saying this is the ARMIDRegisterIdx of the parent
> sysreg.

ok

>> +    int lower;
>> +    int upper;
>> +} ARM64SysRegField;
>> +
>> +typedef struct ARM64SysReg {
>> +    const char *name;   /* name of the sysreg, for instance CTR_EL0 */
>> +    ARMSysRegs sysreg;
>> +    int index;
> now that we have different kinds of indexing, may be worth adding a
> comment to explain which one is being used.
> I guess here it is ARMIDRegisterIdx. So you could even change the data type.

Yeah, comments are good, I'll add some.

>> +    GList *fields; /* list of named fields, excluding RES* */
>> +} ARM64SysReg;
>> +
>> +void initialize_cpu_sysreg_properties(void);
>> +
>> +/*
>> + * List of exposed ID regs (automatically populated from linux
>> + * arch/arm64/tools/sysreg)
>> + */
>> +extern ARM64SysReg arm64_id_regs[NUM_ID_IDX];
>> +
>> +/* Allocate a new field and insert it at the head of the @reg list */
>> +static inline GList *arm64_sysreg_add_field(ARM64SysReg *reg, const char *name,
>> +                                     uint8_t min, uint8_t max) {
>> +
>> +     ARM64SysRegField *field = g_new0(ARM64SysRegField, 1);
>> +
>> +     field->name = name;
>> +     field->lower = min;
>> +     field->upper = max;
>> +     field->index = reg->index;
>> +
>> +     reg->fields = g_list_append(reg->fields, field);
>> +     return reg->fields;
>> +}
>> +
>> +static inline ARM64SysReg *arm64_sysreg_get(ARMIDRegisterIdx index)
>> +{
>> +        ARM64SysReg *reg = &arm64_id_regs[index];
>> +
>> +        reg->index = index;
>> +        reg->sysreg = id_register_sysreg[index];
>> +        return reg;
>> +}
>> +
>> +#endif
>> diff --git a/target/arm/cpu-sysreg-properties.c b/target/arm/cpu-sysreg-properties.c
>> new file mode 100644
>> index 000000000000..8b7ef5badfb9
>> --- /dev/null
>> +++ b/target/arm/cpu-sysreg-properties.c
>> @@ -0,0 +1,41 @@
>> +/*
>> + * QEMU ARM CPU SYSREG PROPERTIES
>> + * to be generated from linux sysreg
>> + *
>> + * Copyright (c) Red Hat, Inc. 2024
> maybe increment the year now ;-)

Wait, it is 2025 already? :)



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 04/10] kvm: kvm_get_writable_id_regs
  2025-04-14 16:38 ` [PATCH v3 04/10] kvm: kvm_get_writable_id_regs Cornelia Huck
@ 2025-05-13 14:20   ` Eric Auger
  2025-05-13 14:42     ` Cornelia Huck
  0 siblings, 1 reply; 58+ messages in thread
From: Eric Auger @ 2025-05-13 14:20 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini

Hi Connie,

On 4/14/25 6:38 PM, Cornelia Huck wrote:
> Add an helper to retrieve the writable id reg bitmask. The
> status of the query is stored in the CPU struct so that an
> an error, if any, can be reported on vcpu realize().
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
>  target/arm/cpu.h     | 26 ++++++++++++++++++++++++++
>  target/arm/kvm.c     | 32 ++++++++++++++++++++++++++++++++
>  target/arm/kvm_arm.h |  7 +++++++
>  3 files changed, 65 insertions(+)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index d27134f4a025..bbee7ff2414a 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -856,6 +856,26 @@ typedef struct {
>      uint32_t map, init, supported;
>  } ARMVQMap;
>  
> +typedef enum ARMIdRegsState {
> +    WRITABLE_ID_REGS_UNKNOWN,
> +    WRITABLE_ID_REGS_NOT_DISCOVERABLE,
> +    WRITABLE_ID_REGS_FAILED,
> +    WRITABLE_ID_REGS_AVAIL,
> +} ARMIdRegsState;
> +
> +/*
> + * The following structures are for the purpose of mapping the output of
> + * KVM_ARM_GET_REG_WRITABLE_MASKS that also may cover id registers we do
> + * not support in QEMU
> + * ID registers in op0==3, op1=={0,1,3}, crn=0, crm=={0-7}, op2=={0-7},
> + * as used by the KVM_ARM_GET_REG_WRITABLE_MASKS ioctl call.
> + */
> +#define NR_ID_REGS (3 * 8 * 8)
We may rename this define to better associate to the KVM API. I tend to
mix it with NUM_ID_IDX now ;-)
maybe something like KVM_NR_EXPOSED_ID_REGS
> +
> +typedef struct IdRegMap {
> +    uint64_t regs[NR_ID_REGS];
> +} IdRegMap;
I would add a comment saying this is the mask array, just to prevent the
reading from thinking it is the actual reg content.
> +
>  /* REG is ID_XXX */
>  #define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE)                       \
>      ({                                                                  \
> @@ -1044,6 +1064,12 @@ struct ArchCPU {
>       */
>      bool host_cpu_probe_failed;
>  
> +    /*
> +     * state of writable id regs query used to report an error, if any,
> +     * on KVM custom vcpu model realize
> +     */
> +    ARMIdRegsState writable_id_regs;
maybe rename into writable_id_reg_status that would better reflect what
it is.
> +
>      /* QOM property to indicate we should use the back-compat CNTFRQ default */
>      bool backcompat_cntfrq;
>  
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index 8491f42a18d2..6e3cd06e9bc5 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -50,6 +50,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
>  static bool cap_has_mp_state;
>  static bool cap_has_inject_serror_esr;
>  static bool cap_has_inject_ext_dabt;
> +static int cap_writable_id_regs;
>  
>  /**
>   * ARMHostCPUFeatures: information about the host CPU (identified
> @@ -488,6 +489,37 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
>      env->features = arm_host_cpu_features.features;
>  }
>  
> +int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap)
> +{
> +    struct reg_mask_range range = {
> +        .range = 0, /* up to now only a single range is supported */
> +        .addr = (uint64_t)idregmap,
> +    };
> +    int ret;
> +
> +    if (!kvm_enabled()) {
> +        cpu->writable_id_regs = WRITABLE_ID_REGS_NOT_DISCOVERABLE;
> +        return -ENOSYS;
> +    }
> +
> +    cap_writable_id_regs =
> +        kvm_check_extension(kvm_state, KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES);
> +
> +    if (!cap_writable_id_regs ||
> +        !(cap_writable_id_regs & (1 << KVM_ARM_FEATURE_ID_RANGE))) {
> +        cpu->writable_id_regs = WRITABLE_ID_REGS_NOT_DISCOVERABLE;
> +        return -ENOSYS;
> +    }
> +
> +    ret = kvm_vm_ioctl(kvm_state, KVM_ARM_GET_REG_WRITABLE_MASKS, &range);
> +    if (ret) {
> +        cpu->writable_id_regs = WRITABLE_ID_REGS_FAILED;
> +        return ret;
> +     }
> +    cpu->writable_id_regs = WRITABLE_ID_REGS_AVAIL;
> +    return ret;
> +}
> +
>  static bool kvm_no_adjvtime_get(Object *obj, Error **errp)
>  {
>      return !ARM_CPU(obj)->kvm_adjvtime;
> diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
> index 05c3de8cd46e..8d1f20ca8d89 100644
> --- a/target/arm/kvm_arm.h
> +++ b/target/arm/kvm_arm.h
> @@ -221,6 +221,8 @@ int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level);
>  
>  void kvm_arm_enable_mte(Object *cpuobj, Error **errp);
>  
> +int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap);
> +
>  #else
>  
>  /*
> @@ -247,6 +249,11 @@ static inline bool kvm_arm_mte_supported(void)
>      return false;
>  }
>  
> +static inline int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap)
> +{
> +    return -ENOSYS;
> +}
> +
>  /*
>   * These functions should never actually be called without KVM support.
>   */
Cheers

Eric



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 06/10] arm/kvm: Allow reading all the writable ID registers
  2025-04-14 16:38 ` [PATCH v3 06/10] arm/kvm: Allow reading all the writable ID registers Cornelia Huck
@ 2025-05-13 14:31   ` Eric Auger
  2025-05-16 14:17     ` Cornelia Huck
  2025-05-20 14:05     ` Cornelia Huck
  2025-05-23  8:27   ` Shameerali Kolothum Thodi via
  1 sibling, 2 replies; 58+ messages in thread
From: Eric Auger @ 2025-05-13 14:31 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini



On 4/14/25 6:38 PM, Cornelia Huck wrote:
> From: Eric Auger <eric.auger@redhat.com>
>
> At the moment kvm_arm_get_host_cpu_features() reads a subset of the
> ID regs. As we want to introduce properties for all writable ID reg
> fields, we want more genericity and read more default host register
> values.
>
> Introduce a new get_host_cpu_idregs() helper and add a new exhaustive
> boolean parameter to kvm_arm_get_host_cpu_features() and
> kvm_arm_set_cpu_features_from_host() to select the right behavior.
> The host cpu model will keep the legacy behavior unless the writable
> id register interface is available.
>
> A writable_map IdRegMap is introduced in the CPU object. A subsequent
> patch will populate it.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
>  target/arm/cpu-sysregs.h |  2 ++
>  target/arm/cpu.h         |  3 ++
>  target/arm/cpu64.c       |  2 +-
>  target/arm/kvm.c         | 78 ++++++++++++++++++++++++++++++++++++++--
>  target/arm/kvm_arm.h     |  9 +++--
>  target/arm/trace-events  |  1 +
>  6 files changed, 89 insertions(+), 6 deletions(-)
>
> diff --git a/target/arm/cpu-sysregs.h b/target/arm/cpu-sysregs.h
> index e89a1105904c..367fab51f19e 100644
> --- a/target/arm/cpu-sysregs.h
> +++ b/target/arm/cpu-sysregs.h
> @@ -41,6 +41,8 @@ int get_sysreg_idx(ARMSysRegs sysreg);
>  
>  #ifdef CONFIG_KVM
>  uint64_t idregs_sysreg_to_kvm_reg(ARMSysRegs sysreg);
> +int kvm_idx_to_idregs_idx(int kidx);
> +int idregs_idx_to_kvm_idx(ARMIDRegisterIdx idx);
>  #endif
>  
>  #endif /* ARM_CPU_SYSREGS_H */
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 775a8aebc5d3..8717c5e7695b 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -1088,6 +1088,9 @@ struct ArchCPU {
>       */
>      ARMIdRegsState writable_id_regs;
>  
> +    /* ID reg writable bitmask (KVM only) */
> +    IdRegMap *writable_map;
as it is KVM only we may put it in ifdef CONFIG_KVM block above
> +
>      /* QOM property to indicate we should use the back-compat CNTFRQ default */
>      bool backcompat_cntfrq;
>  
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index 839442745ea4..60a709502697 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -757,7 +757,7 @@ static void aarch64_host_initfn(Object *obj)
>  {
>  #if defined(CONFIG_KVM)
>      ARMCPU *cpu = ARM_CPU(obj);
> -    kvm_arm_set_cpu_features_from_host(cpu);
> +    kvm_arm_set_cpu_features_from_host(cpu, false);
>      if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
>          aarch64_add_sve_properties(obj);
>          aarch64_add_pauth_properties(obj);
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index 6e3cd06e9bc5..b07d5f16db50 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -41,6 +41,7 @@
>  #include "hw/acpi/ghes.h"
>  #include "target/arm/gtimer.h"
>  #include "migration/blocker.h"
> +#include "cpu-custom.h"
>  
>  const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
>      KVM_CAP_INFO(DEVICE_CTRL),
> @@ -270,7 +271,73 @@ static int get_host_cpu_reg(int fd, ARMHostCPUFeatures *ahcf, ARMIDRegisterIdx i
>      return ret;
>  }
>  
> -static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
> +int kvm_idx_to_idregs_idx(int kidx)
> +{
> +    int op1, crm, op2;
> +    ARMSysRegs sysreg;
> +
> +    op1 = kidx / 64;
> +    if (op1 == 2) {
> +        op1 = 3;
> +    }
> +    crm = (kidx % 64) / 8;
> +    op2 = kidx % 8;
> +    sysreg = ENCODE_ID_REG(3, op1, 0, crm, op2);
> +    return get_sysreg_idx(sysreg);
> +}
> +
> +int idregs_idx_to_kvm_idx(ARMIDRegisterIdx idx)
> +{
> +    ARMSysRegs sysreg = id_register_sysreg[idx];
> +
> +    return KVM_ARM_FEATURE_ID_RANGE_IDX((sysreg & CP_REG_ARM64_SYSREG_OP0_MASK) >> CP_REG_ARM64_SYSREG_OP0_SHIFT,
> +                                        (sysreg & CP_REG_ARM64_SYSREG_OP1_MASK) >> CP_REG_ARM64_SYSREG_OP1_SHIFT,
> +                                        (sysreg & CP_REG_ARM64_SYSREG_CRN_MASK) >> CP_REG_ARM64_SYSREG_CRN_SHIFT,
> +                                        (sysreg & CP_REG_ARM64_SYSREG_CRM_MASK) >> CP_REG_ARM64_SYSREG_CRM_SHIFT,
> +                                        (sysreg & CP_REG_ARM64_SYSREG_OP2_MASK) >> CP_REG_ARM64_SYSREG_OP2_SHIFT);
> +}
> +
> +
> +/*
> + * get_host_cpu_idregs: Read all the writable ID reg host values
> + *
> + * Need to be called once the writable mask has been populated
> + * Note we may want to read all the known id regs but some of them are not
> + * writable and return an error, hence the choice of reading only those which
> + * are writable. Those are also readable!
> + */
> +static int get_host_cpu_idregs(ARMCPU *cpu, int fd, ARMHostCPUFeatures *ahcf)
> +{
> +    int err = 0;
> +    int i;
> +
> +    for (i = 0; i < NUM_ID_IDX; i++) {
> +        ARM64SysReg *sysregdesc = &arm64_id_regs[i];
> +        ARMSysRegs sysreg = sysregdesc->sysreg;
> +        uint64_t writable_mask = cpu->writable_map->regs[idregs_idx_to_kvm_idx(i)];
> +        uint64_t *reg;
> +        int ret;
> +
> +        if (!writable_mask) {
> +            continue;
> +        }
> +
> +        reg = &ahcf->isar.idregs[i];
> +        ret = read_sys_reg64(fd, reg, idregs_sysreg_to_kvm_reg(sysreg));
> +        trace_get_host_cpu_idregs(sysregdesc->name, *reg);
> +        if (ret) {
> +            error_report("%s error reading value of host %s register (%m)",
> +                         __func__, sysregdesc->name);
> +
> +            err = ret;
> +        }
> +    }
> +    return err;
> +}
> +
> +static bool
> +kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf,
> +                              bool exhaustive)
maybe the exhaustive term shall be replaced by handle_writable_id_regs
which tells more explicitly what it does
>  {
>      /* Identify the feature bits corresponding to the host CPU, and
>       * fill out the ARMHostCPUClass fields accordingly. To do this
> @@ -398,6 +465,11 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>          err |= get_host_cpu_reg(fd, ahcf, ID_DFR1_EL1_IDX);
>          err |= get_host_cpu_reg(fd, ahcf, ID_MMFR5_EL1_IDX);
>  
> +        /* Make sure writable ID reg values are read */
> +        if (exhaustive) {
> +            err |= get_host_cpu_idregs(cpu, fd, ahcf);
> +        }
> +
>          /*
>           * DBGDIDR is a bit complicated because the kernel doesn't
>           * provide an accessor for it in 64-bit mode, which is what this
> @@ -467,13 +539,13 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>      return true;
>  }
>  
> -void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
> +void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, bool exhaustive)
>  {
>      CPUARMState *env = &cpu->env;
>  
>      if (!arm_host_cpu_features.dtb_compatible) {
>          if (!kvm_enabled() ||
> -            !kvm_arm_get_host_cpu_features(&arm_host_cpu_features)) {
> +            !kvm_arm_get_host_cpu_features(cpu, &arm_host_cpu_features, exhaustive)) {
>              /* We can't report this error yet, so flag that we need to
>               * in arm_cpu_realizefn().
>               */
> diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
> index 8d1f20ca8d89..90ba4f7d8987 100644
> --- a/target/arm/kvm_arm.h
> +++ b/target/arm/kvm_arm.h
> @@ -141,8 +141,12 @@ uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu);
>   *
>   * Set up the ARMCPU struct fields up to match the information probed
>   * from the host CPU.
> + *
> + * @cpu: cpu object
> + * @exhaustive: if true, all the feature ID regs are queried instead of
s/queried/handled
> + *              a subset
>   */
> -void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
> +void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, bool exhaustive);
>  
>  /**
>   * kvm_arm_add_vcpu_properties:
> @@ -257,7 +261,8 @@ static inline int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap)
>  /*
>   * These functions should never actually be called without KVM support.
>   */
> -static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
> +static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu,
> +                                                      bool exhaustive)
>  {
>      g_assert_not_reached();
>  }
> diff --git a/target/arm/trace-events b/target/arm/trace-events
> index 4438dce7becc..17e52c0705f2 100644
> --- a/target/arm/trace-events
> +++ b/target/arm/trace-events
> @@ -13,3 +13,4 @@ arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
>  
>  # kvm.c
>  kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
> +get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host value for %s is 0x%"PRIx64

Eric



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 07/10] arm/kvm: write back modified ID regs to KVM
  2025-04-14 16:38 ` [PATCH v3 07/10] arm/kvm: write back modified ID regs to KVM Cornelia Huck
  2025-04-15  7:03   ` Philippe Mathieu-Daudé
@ 2025-05-13 14:33   ` Eric Auger
  2025-07-02  4:01   ` Jinqian Yang via
  2 siblings, 0 replies; 58+ messages in thread
From: Eric Auger @ 2025-05-13 14:33 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini



On 4/14/25 6:38 PM, Cornelia Huck wrote:
> From: Eric Auger <eric.auger@redhat.com>
>
> We want to give a chance to override the value of host ID regs.
> In a previous patch we made sure all their values could be fetched
> through kvm_get_one_reg() calls before their modification. After
> their potential modification we need to make sure we write back
nit: write their value back?

Eric
> the values through kvm_set_one_reg() calls.
>
> Make sure the cpreg_list is modified with updated values and
> transfer those values back to kvm.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
>  target/arm/kvm.c        | 44 ++++++++++++++++++++++++++++++++++++++++-
>  target/arm/trace-events |  1 +
>  2 files changed, 44 insertions(+), 1 deletion(-)
>
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index b07d5f16db50..9e4cca1705c8 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -1083,6 +1083,39 @@ void kvm_arm_cpu_post_load(ARMCPU *cpu)
>      }
>  }
>  
> +static void kvm_arm_writable_idregs_to_cpreg_list(ARMCPU *cpu)
> +{
> +    if (!cpu->writable_map) {
> +        return;
> +    }
> +    for (int i = 0; i < NR_ID_REGS; i++) {
> +        uint64_t writable_mask = cpu->writable_map->regs[i];
> +        uint64_t *cpreg;
> +
> +        if (writable_mask) {
> +            uint64_t previous, new;
> +            int idx = kvm_idx_to_idregs_idx(i);
> +            ARM64SysReg *sysregdesc;
> +            uint32_t sysreg;
> +
> +            if (idx == -1) {
> +                /* sysreg writable, but we don't know it */
> +                continue;
> +            }
> +            sysregdesc = &arm64_id_regs[idx];
> +            sysreg = sysregdesc->sysreg;
> +            cpreg = kvm_arm_get_cpreg_ptr(cpu, idregs_sysreg_to_kvm_reg(sysreg));
> +            previous = *cpreg;
> +            new = cpu->isar.idregs[idx];
> +            if (previous != new) {
> +                *cpreg = new;
> +                trace_kvm_arm_writable_idregs_to_cpreg_list(sysregdesc->name,
> +                                                            previous, new);
> +            }
> +        }
> +    }
> +}
> +
>  void kvm_arm_reset_vcpu(ARMCPU *cpu)
>  {
>      int ret;
> @@ -2050,7 +2083,16 @@ int kvm_arch_init_vcpu(CPUState *cs)
>      }
>      cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
>  
> -    return kvm_arm_init_cpreg_list(cpu);
> +    ret = kvm_arm_init_cpreg_list(cpu);
> +    if (ret) {
> +        return ret;
> +    }
> +    /* overwrite writable ID regs with their updated property values */
> +    kvm_arm_writable_idregs_to_cpreg_list(cpu);
> +
> +    write_list_to_kvmstate(cpu, 3);
> +
> +    return 0;
>  }
>  
>  int kvm_arch_destroy_vcpu(CPUState *cs)
> diff --git a/target/arm/trace-events b/target/arm/trace-events
> index 17e52c0705f2..955149ee1ac4 100644
> --- a/target/arm/trace-events
> +++ b/target/arm/trace-events
> @@ -14,3 +14,4 @@ arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
>  # kvm.c
>  kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
>  get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host value for %s is 0x%"PRIx64
> +kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint64_t new) "%s overwrite default 0x%"PRIx64" with 0x%"PRIx64



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 04/10] kvm: kvm_get_writable_id_regs
  2025-05-13 14:20   ` Eric Auger
@ 2025-05-13 14:42     ` Cornelia Huck
  2025-05-13 15:16       ` Eric Auger
  0 siblings, 1 reply; 58+ messages in thread
From: Cornelia Huck @ 2025-05-13 14:42 UTC (permalink / raw)
  To: eric.auger, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini

On Tue, May 13 2025, Eric Auger <eric.auger@redhat.com> wrote:

> Hi Connie,
>
> On 4/14/25 6:38 PM, Cornelia Huck wrote:
>> Add an helper to retrieve the writable id reg bitmask. The
>> status of the query is stored in the CPU struct so that an
>> an error, if any, can be reported on vcpu realize().
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>> ---
>>  target/arm/cpu.h     | 26 ++++++++++++++++++++++++++
>>  target/arm/kvm.c     | 32 ++++++++++++++++++++++++++++++++
>>  target/arm/kvm_arm.h |  7 +++++++
>>  3 files changed, 65 insertions(+)
>>
>> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
>> index d27134f4a025..bbee7ff2414a 100644
>> --- a/target/arm/cpu.h
>> +++ b/target/arm/cpu.h
>> @@ -856,6 +856,26 @@ typedef struct {
>>      uint32_t map, init, supported;
>>  } ARMVQMap;
>>  
>> +typedef enum ARMIdRegsState {
>> +    WRITABLE_ID_REGS_UNKNOWN,
>> +    WRITABLE_ID_REGS_NOT_DISCOVERABLE,
>> +    WRITABLE_ID_REGS_FAILED,
>> +    WRITABLE_ID_REGS_AVAIL,
>> +} ARMIdRegsState;
>> +
>> +/*
>> + * The following structures are for the purpose of mapping the output of
>> + * KVM_ARM_GET_REG_WRITABLE_MASKS that also may cover id registers we do
>> + * not support in QEMU
>> + * ID registers in op0==3, op1=={0,1,3}, crn=0, crm=={0-7}, op2=={0-7},
>> + * as used by the KVM_ARM_GET_REG_WRITABLE_MASKS ioctl call.
>> + */
>> +#define NR_ID_REGS (3 * 8 * 8)
> We may rename this define to better associate to the KVM API. I tend to
> mix it with NUM_ID_IDX now ;-)
> maybe something like KVM_NR_EXPOSED_ID_REGS

The kernel calls it KVM_FEATURE_ID_RANGE_SIZE, but I'd like to avoid
adding 'KVM' in the name, as it is basically a range of registers and
nothing really KVM specific... maybe ID_REG_RANGE_SIZE?

>> +
>> +typedef struct IdRegMap {
>> +    uint64_t regs[NR_ID_REGS];
>> +} IdRegMap;
> I would add a comment saying this is the mask array, just to prevent the
> reading from thinking it is the actual reg content.

"More comments" seems to be a theme :) I'll go ahead and add them where
it makes sense.

>> +
>>  /* REG is ID_XXX */
>>  #define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE)                       \
>>      ({                                                                  \
>> @@ -1044,6 +1064,12 @@ struct ArchCPU {
>>       */
>>      bool host_cpu_probe_failed;
>>  
>> +    /*
>> +     * state of writable id regs query used to report an error, if any,
>> +     * on KVM custom vcpu model realize
>> +     */
>> +    ARMIdRegsState writable_id_regs;
> maybe rename into writable_id_reg_status that would better reflect what
> it is.

Indeed.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model
  2025-04-14 16:38 ` [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model Cornelia Huck
@ 2025-05-13 14:47   ` Eric Auger
  2025-05-13 15:56   ` Daniel P. Berrangé
  2025-05-13 15:59   ` Daniel P. Berrangé
  2 siblings, 0 replies; 58+ messages in thread
From: Eric Auger @ 2025-05-13 14:47 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini

Hi Connie,

On 4/14/25 6:38 PM, Cornelia Huck wrote:
> From: Eric Auger <eric.auger@redhat.com>
>
> If the interface for writable ID registers is available, expose uint64
> SYSREG properties for writable ID reg fields exposed by the host
> kernel. Properties are named  SYSREG_<REG>_<FIELD> with REG and FIELD
I remember we had a comment in the early RFC that suggested to remove
the "SYSREG_" prefix. I introduced to ease the qmp introspection if I
remember correctly. Could we manage without it?
> being those used  in linux arch/arm64/tools/sysreg. This done by
s/used in/used in
> matching the writable fields retrieved from the host kernel against the
> generated description of sysregs.
>
> An example of invocation is:
> -cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0
> which sets DP field of ID_AA64ISAR0_EL1 to 0.
>
> [CH: add properties to the host model instead of introducing a new
> "custom" model]
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>
> ---
>
> Interaction with the existing cpu properties is still a bit unclear --
> at the moment, the different configurations can overwrite each other.
> ---
>  target/arm/cpu.c        |  12 ++++
>  target/arm/cpu64.c      |  22 ++++++-
>  target/arm/kvm.c        | 135 ++++++++++++++++++++++++++++++++++++++++
>  target/arm/kvm_arm.h    |  10 +++
>  target/arm/trace-events |   4 ++
>  5 files changed, 182 insertions(+), 1 deletion(-)
>
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index a3de5ee2b19c..c03f38ad5cfe 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -1991,6 +1991,18 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
>          return;
>      }
>  
> +    /*
> +     * If we failed to retrieve the set of writable ID registers for the "host"
> +     * CPU model, report it here. No error if the interface for discovering
> +     * writable ID registers is not available.
> +     * In case we did get the set of writable ID registers, set the features to
> +     * the configured values here and perform some sanity checks.
> +     */
> +    if (cpu->writable_id_regs == WRITABLE_ID_REGS_FAILED) {
> +        error_setg(errp, "Failed to discover writable id registers");
> +        return;
> +    }
> +
>      if (!cpu->gt_cntfrq_hz) {
>          /*
>           * 0 means "the board didn't set a value, use the default". (We also
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index 60a709502697..c595dbb532c1 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -757,11 +757,31 @@ static void aarch64_host_initfn(Object *obj)
>  {
>  #if defined(CONFIG_KVM)
>      ARMCPU *cpu = ARM_CPU(obj);
> -    kvm_arm_set_cpu_features_from_host(cpu, false);
> +    bool expose_id_regs = true;
> +    int ret;
> +
> +    cpu->writable_map = g_malloc(sizeof(IdRegMap));
> +
> +    /* discover via KVM_ARM_GET_REG_WRITABLE_MASKS */
> +    ret = kvm_arm_get_writable_id_regs(cpu, cpu->writable_map);
> +    if (ret == -ENOSYS) {
> +        /* legacy: continue without writable id regs */
> +        expose_id_regs = false;
> +    } else if (ret) {
> +        /* function will have marked an error */
> +        return;
> +    }
> +
> +    kvm_arm_set_cpu_features_from_host(cpu, expose_id_regs);
>      if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
>          aarch64_add_sve_properties(obj);
>          aarch64_add_pauth_properties(obj);
>      }
> +    if (expose_id_regs) {
> +        /* generate SYSREG properties according to writable masks */
> +        kvm_arm_expose_idreg_properties(cpu, arm64_id_regs);
> +    }
> +
>  #elif defined(CONFIG_HVF)
>      ARMCPU *cpu = ARM_CPU(obj);
>      hvf_arm_set_cpu_features_from_host(cpu);
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index 9e4cca1705c8..63e27906cc42 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -335,6 +335,141 @@ static int get_host_cpu_idregs(ARMCPU *cpu, int fd, ARMHostCPUFeatures *ahcf)
>      return err;
>  }
>  
> +static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
> +{
> +    GList *l;
> +
> +    for (l = reg->fields; l; l = l->next) {
> +        ARM64SysRegField *field = (ARM64SysRegField *)l->data;
> +
> +        if (i >= field->lower && i <= field->upper) {
> +            return field;
> +        }
> +    }
> +    return NULL;
> +}
> +
> +static void set_sysreg_prop(Object *obj, Visitor *v,
> +                            const char *name, void *opaque,
> +                            Error **errp)
> +{
> +    ARM64SysRegField *field = (ARM64SysRegField *)opaque;
> +    ARMCPU *cpu = ARM_CPU(obj);
> +    uint64_t *idregs = cpu->isar.idregs;
> +    uint64_t old, value, mask;
> +    int lower = field->lower;
> +    int upper = field->upper;
> +    int length = upper - lower + 1;
> +    int index = field->index;
> +
> +    if (!visit_type_uint64(v, name, &value, errp)) {
> +        return;
> +    }
> +
> +    if (length < 64 && value > ((1 << length) - 1)) {
> +        error_setg(errp,
> +                   "idreg %s set value (0x%lx) exceeds length of field (%d)!",
> +                   name, value, length);
> +        return;
> +    }
> +
> +    mask = MAKE_64BIT_MASK(lower, length);
> +    value = value << lower;
> +    old = idregs[index];
> +    idregs[index] = old & ~mask;
> +    idregs[index] |= value;
> +    trace_set_sysreg_prop(name, old, mask, value, idregs[index]);
> +}
> +
> +static void get_sysreg_prop(Object *obj, Visitor *v,
> +                            const char *name, void *opaque,
> +                            Error **errp)
> +{
> +    ARM64SysRegField *field = (ARM64SysRegField *)opaque;
> +    ARMCPU *cpu = ARM_CPU(obj);
> +    uint64_t *idregs = cpu->isar.idregs;
> +    uint64_t value, mask;
> +    int lower = field->lower;
> +    int upper = field->upper;
> +    int length = upper - lower + 1;
> +    int index = field->index;
> +
> +    mask = MAKE_64BIT_MASK(lower, length);
> +    value = (idregs[index] & mask) >> lower;
> +    visit_type_uint64(v, name, &value, errp);
> +    trace_get_sysreg_prop(name, value);
> +}
> +
> +/*
> + * decode_idreg_writemap: Generate props for writable fields
> + *
> + * @obj: CPU object
> + * @index: index of the sysreg
> + * @map: writable map for the sysreg
> + * @reg: description of the sysreg
> + */
> +static int
> +decode_idreg_writemap(Object *obj, int index, uint64_t map, ARM64SysReg *reg)
> +{
> +    int i = ctz64(map);
> +    int nb_sysreg_props = 0;
> +
> +    while (map) {
> +
spurious empty line
> +        ARM64SysRegField *field = get_field(i, reg);
> +        int lower, upper;
> +        uint64_t mask;
> +        char *prop_name;
> +
> +        if (!field) {
> +            /* the field cannot be matched to any know id named field */
> +            warn_report("%s bit %d of %s is writable but cannot be matched",
> +                        __func__, i, reg->name);
> +            warn_report("%s is cpu-sysreg-properties.c up to date?", __func__);
> +            map =  map & ~BIT_ULL(i);
> +            i = ctz64(map);
> +            continue;
> +        }
> +        lower = field->lower;
> +        upper = field->upper;
> +        prop_name = g_strdup_printf("SYSREG_%s_%s", reg->name, field->name);
> +        trace_decode_idreg_writemap(field->name, lower, upper, prop_name);
> +        object_property_add(obj, prop_name, "uint64",
> +                            get_sysreg_prop, set_sysreg_prop, NULL, field);
> +        nb_sysreg_props++;
> +
> +        mask = MAKE_64BIT_MASK(lower, upper - lower + 1);
> +        map = map & ~mask;
> +        i = ctz64(map);
> +    }
> +    trace_nb_sysreg_props(reg->name, nb_sysreg_props);
> +    return 0;
> +}
> +
> +/* analyze the writable mask and generate properties for writable fields */
> +void kvm_arm_expose_idreg_properties(ARMCPU *cpu, ARM64SysReg *regs)
> +{
> +    int i, idx;
> +    IdRegMap *map = cpu->writable_map;
> +    Object *obj = OBJECT(cpu);
> +
> +    for (i = 0; i < NR_ID_REGS; i++) {
> +        uint64_t mask = map->regs[i];
> +
> +        if (mask) {
> +            /* reg @i has some writable fields, decode them */
> +            idx = kvm_idx_to_idregs_idx(i);
> +            if (idx < 0) {
can it happen? I understand it asserts?
> +                /* no matching reg? */
> +                warn_report("%s: reg %d writable, but not in list of idregs?",
> +                            __func__, i);
> +            } else {
> +                decode_idreg_writemap(obj, i, mask, &regs[idx]);
> +            }
> +        }
> +    }
> +}
> +
>  static bool
>  kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf,
>                                bool exhaustive)
> diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
> index 90ba4f7d8987..ba5de45f868c 100644
> --- a/target/arm/kvm_arm.h
> +++ b/target/arm/kvm_arm.h
> @@ -157,6 +157,16 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, bool exhaustive);
>   */
>  void kvm_arm_add_vcpu_properties(ARMCPU *cpu);
>  
> +typedef struct ARM64SysReg ARM64SysReg;
> +/**
> + * kvm_arm_expose_idreg_properties:
> + * @cpu: The CPU object to generate the properties for
> + * @reg: registers from the host
> + *
> + * analyze the writable mask and generate properties for writable fields
> + */
> +void kvm_arm_expose_idreg_properties(ARMCPU *cpu, ARM64SysReg *regs);
> +
>  /**
>   * kvm_arm_steal_time_finalize:
>   * @cpu: ARMCPU for which to finalize kvm-steal-time
> diff --git a/target/arm/trace-events b/target/arm/trace-events
> index 955149ee1ac4..8d2a234d5272 100644
> --- a/target/arm/trace-events
> +++ b/target/arm/trace-events
> @@ -15,3 +15,7 @@ arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
>  kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
>  get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host value for %s is 0x%"PRIx64
>  kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint64_t new) "%s overwrite default 0x%"PRIx64" with 0x%"PRIx64
> +decode_idreg_writemap(const char* name, int lower, int upper, char *prop_name) "%s [%d:%d] is writable (prop %s)"
> +get_sysreg_prop(const char *name, uint64_t value) "%s 0x%"PRIx64
> +set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_value, uint64_t new) "%s old reg value=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new reg value=0x%"PRIx64
> +nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
Eric



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 09/10] arm-qmp-cmds: introspection for ID register props
  2025-04-14 16:38 ` [PATCH v3 09/10] arm-qmp-cmds: introspection for ID register props Cornelia Huck
@ 2025-05-13 14:50   ` Eric Auger
  0 siblings, 0 replies; 58+ messages in thread
From: Eric Auger @ 2025-05-13 14:50 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini



On 4/14/25 6:38 PM, Cornelia Huck wrote:
> Implement the capability to query available ID register values by
> adding SYSREG_* options and values to the cpu model expansion for the
> host model, if available.
>
> Excerpt:
> (QEMU) query-cpu-model-expansion type=full model={"name":"host"}
> {"return": {"model": {"name": "host", "props":
> {"SYSREG_ID_AA64PFR0_EL1_EL3": 1224979098931106066,
> "SYSREG_ID_AA64ISAR2_EL1_CLRBHB": 0,
> ../..
>
> So this allows the upper stack to detect available writable ID
> regs and the "host passthrough model" values.
>
> [CH: moved SYSREG_* values to host model]
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>
> ---
>
> TODO: Add the moment there is no way to test changing a given
> ID reg field value. ie:
>
> (QEMU) query-cpu-model-expansion type=full model={"name":"host", "prop":{"SYSREG_ID_AA64ISAR0_EL1_DP":0x13}}
Isn't it a mandated feature for layered products to be able to try a
given combination. Do you think this would be achievable?

Eric
> ---
>  target/arm/arm-qmp-cmds.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
>
> diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
> index 883c0a0e8cce..5f48c7d835e1 100644
> --- a/target/arm/arm-qmp-cmds.c
> +++ b/target/arm/arm-qmp-cmds.c
> @@ -21,6 +21,7 @@
>   */
>  
>  #include "qemu/osdep.h"
> +#include "qemu/error-report.h"
>  #include "hw/boards.h"
>  #include "kvm_arm.h"
>  #include "qapi/error.h"
> @@ -209,6 +210,24 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
>          }
>      }
>  
> +    /* If writable ID regs are supported, add them as well */
> +    if (ARM_CPU(obj)->writable_id_regs == WRITABLE_ID_REGS_AVAIL) {
> +        ObjectProperty *prop;
> +        ObjectPropertyIterator iter;
> +
> +        object_property_iter_init(&iter, obj);
> +
> +        while ((prop = object_property_iter_next(&iter))) {
> +            QObject *value;
> +
> +            if (!g_str_has_prefix(prop->name, "SYSREG_")) {
> +                continue;
> +            }
> +            value = object_property_get_qobject(obj, prop->name, &error_abort);
> +            qdict_put_obj(qdict_out, prop->name, value);
> +        }
> +    }
> +
>      if (!qdict_size(qdict_out)) {
>          qobject_unref(qdict_out);
>      } else {



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 10/10] arm/cpu-features: document ID reg properties
  2025-04-14 16:38 ` [PATCH v3 10/10] arm/cpu-features: document ID reg properties Cornelia Huck
@ 2025-05-13 15:09   ` Eric Auger
  2025-05-13 16:23   ` Daniel P. Berrangé
  1 sibling, 0 replies; 58+ messages in thread
From: Eric Auger @ 2025-05-13 15:09 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini

Hi Connie,
On 4/14/25 6:38 PM, Cornelia Huck wrote:
> Add some documentation for how individual ID registers can be
> configured with the host cpu model.
>
> [CH: adapt to removal of the 'custom' model, added some more
>  explanations about using the ID register props]
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
>  docs/system/arm/cpu-features.rst | 104 ++++++++++++++++++++++++++++---
>  1 file changed, 96 insertions(+), 8 deletions(-)
>
> diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
> index 37d5dfd15b34..22faefd76edd 100644
> --- a/docs/system/arm/cpu-features.rst
> +++ b/docs/system/arm/cpu-features.rst
> @@ -2,7 +2,10 @@ Arm CPU Features
>  ================
>  
>  CPU features are optional features that a CPU of supporting type may
> -choose to implement or not.  In QEMU, optional CPU features have
> +choose to implement or not.  QEMU provides two different mechanisms
> +to configure those features:
> +
> +1. For most CPU models, optional CPU features may have
>  corresponding boolean CPU proprieties that, when enabled, indicate
>  that the feature is implemented, and, conversely, when disabled,
>  indicate that it is not implemented. An example of an Arm CPU feature
> @@ -29,6 +32,16 @@ supports the feature.  While ``aarch64`` currently only works with KVM,
>  it could work with TCG.  CPU features that are specific to KVM are
>  prefixed with "kvm-" and are described in "KVM VCPU Features".
>  
> +2. Additionally, the ``host`` CPU model on KVM allows to configure optional
> +CPU features via the corresponding ID registers. The host kernel allows
> +to write a subset of ID register fields. The host model exposes
> +properties for each writable ID register field. Those options are named
> +SYSREG_<IDREG>_<FIELD>. IDREG and FIELD names are those used in the
> +ARM ARM Reference Manual. They can also be found in the Linux
> +arch/arm64/tool/sysreg file which is used to automatically generate the
> +description for those registers and fields. This currently only has been
> +implemented for KVM.
> +
>  CPU Feature Probing
>  ===================
>  
> @@ -124,13 +137,20 @@ A note about CPU models and KVM
>  
>  Named CPU models generally do not work with KVM.  There are a few cases
>  that do work, e.g. using the named CPU model ``cortex-a57`` with KVM on a
> -seattle host, but mostly if KVM is enabled the ``host`` CPU type must be
> -used.  This means the guest is provided all the same CPU features as the
> -host CPU type has.  And, for this reason, the ``host`` CPU type should
> -enable all CPU features that the host has by default.  Indeed it's even
> -a bit strange to allow disabling CPU features that the host has when using
> -the ``host`` CPU type, but in the absence of CPU models it's the best we can
> -do if we want to launch guests without all the host's CPU features enabled.
> +seattle host, but mostly if KVM is enabled, the ``host`` CPU model must be
> +used.
> +
> +Using the ``host`` type means the guest is provided all the same CPU
> +features as the host CPU type has.  And, for this reason, the ``host``
> +CPU type should enable all CPU features that the host has by default.
> +
> +In case some features need to be hidden to the guest, and the host kernel
> +supports it, the ``host`` model can be instructed to disable individual
> +ID register values. This is especially useful for migration purposes.
> +However, this interface will not allow configuring an arbitrary set of
> +features; the ID registers must describe a subset of the host's features,
> +and all differences to the host's configuration must actually be supported
> +by the kernel to be deconfigured.
>  
>  Enabling KVM also affects the ``query-cpu-model-expansion`` QMP command.  The
>  affect is not only limited to specific features, as pointed out in example
> @@ -167,6 +187,13 @@ disabling many SVE vector lengths would be quite verbose, the ``sve<N>`` CPU
>  properties have special semantics (see "SVE CPU Property Parsing
>  Semantics").
>  
> +Additionally, if supported by KVM on the host kernel, the ``host`` CPU model
> +may be configured via individual ID register field properties, for example::
> +
> +  $ qemu-system-aarch64 -M virt -cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0
> +
> +This forces ID_AA64ISAR0_EL1 DP field to 0.
> +
>  KVM VCPU Features
>  =================
>  
> @@ -466,3 +493,64 @@ Legal values for ``S`` are 30, 34, 36, and 39; the default is 30.
>  
>  As with ``x-rme``, the ``x-l0gptsz`` property may be renamed or
>  removed in some future QEMU release.
> +
> +Configuring CPU features via ID register fields
> +===============================================
> +
> +Note that this is currently only supported under KVM, and with the
> +``host`` CPU model.
> +
> +Querying available ID register fields
> +-------------------------------------
> +
> +QEMU will create properties for all ID register fields that are
> +reported as being writable by the kernel, and that are known to the
> +QEMU instance. Therefore, the same QEMU binary may expose different
> +properties when run under a different kernel.
> +
> +To find out all available writable ID register fields, use the
> +``query-cpu-model-expansion`` QMP command::
> +
> +  (QEMU) query-cpu-model-expansion type=full model={"name":"host"}
> +  {"return": {
> +   "model": {"name": "host", "props": {
> +   "SYSREG_ID_AA64PFR0_EL1_EL3": 1, "SYSREG_ID_AA64ISAR2_EL1_CLRBHB": 0,
> +   "SYSREG_CTR_EL0_L1Ip": 3, "SYSREG_CTR_EL0_DminLine": 4,
> +   "SYSREG_ID_AA64MMFR0_EL1_BIGEND": 1, "SYSREG_ID_AA64MMFR1_EL1_ECBHB": 0,
> +   "SYSREG_ID_AA64MMFR2_EL1_CnP": 1, "SYSREG_ID_DFR0_EL1_PerfMon": 4,
> +   "SYSREG_ID_AA64PFR0_EL1_DIT": 0, "SYSREG_ID_AA64MMFR1_EL1_HAFDBS": 2,
> +   "SYSREG_ID_AA64ISAR0_EL1_FHM": 0, "SYSREG_ID_AA64ISAR2_EL1_CSSC": 0,
> +   "SYSREG_ID_AA64ISAR0_EL1_DP": 1, (...)
> +   }}}}
> +
> +If a certain field in an ID register does not show up in this list, it
> +is not writable with the specific host kernel.
> +
> +A note on compatibility
> +-----------------------
> +
> +A common use case for providing a defined set of ID register values is
> +to be able to present a fixed set of features to a guest, often referred
> +to as "stable guest ABI". This may take the form of ironing out differences
> +between two similar CPUs with the intention of being able to migrate
> +between machines with those CPUs, or providing the same CPU across Linux
> +kernel updates on the host.
> +
> +Over the course of time, the Linux kernel is changing the set of ID register
> +fields that are writable by userspace. Newly introduced writable ID
> +registers should be initialized to 0 to ensure compatibility. However, ID
why 0? shouldn't they just be ommitted from the explicit command line?
> +registers that have already been introduced that undergo a change as to
> +which fields are writable may introduce incompatibities that need to be
Aren't incompatibilities due to changed default values only. The fact a
new writable field gets exposed does not change the default value in
general. If it was not exposed before, the end user couldn't change its
value, no?

Thanks

Eric
> +addressed on a case-by-case basis for the systems that you wish to migrate
> +inbetween.
> +
> +A note on Arm CPU features (FEAT_xxx)
> +-------------------------------------
> +
> +Configuring CPUs is done on a feature level on other architectures, and this
> +would imply configuring FEAT_xxx values on Arm. However, differences between
> +CPUs may not map to FEAT_xxx, but to differences in other registers in the
> +ID register range; for example, differences in the cache architecture exposed
> +via ``CTR_EL0``. We therefore cannot rely on configuration via FEAT_xxx. A
> +feature-based interface more similar to other architectures may be implemented
> +on top of the ID register interface in the future.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 01/10] arm/cpu: Add infra to handle generated ID register definitions
  2025-05-13 14:05     ` Cornelia Huck
@ 2025-05-13 15:12       ` Eric Auger
  0 siblings, 0 replies; 58+ messages in thread
From: Eric Auger @ 2025-05-13 15:12 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini



On 5/13/25 4:05 PM, Cornelia Huck wrote:
> On Tue, May 13 2025, Eric Auger <eric.auger@redhat.com> wrote:
>
>> Hi Connie,
>>
>> On 4/14/25 6:38 PM, Cornelia Huck wrote:
>>> From: Eric Auger <eric.auger@redhat.com>
>>>
>>> The known ID regs are described in a new initialization function
>>> dubbed initialize_cpu_sysreg_properties(). That code will be
>>> automatically generated from linux arch/arm64/tools/sysreg. For the
>>> time being let's just describe a single id reg, CTR_EL0. In this
>>> description we only care about non RES/RAZ fields, ie. named fields.
>>>
>>> The registers are populated in an array indexed by ARMIDRegisterIdx
>>> and their fields are added in a sorted list.
>>>
>>> [CH: adapted to reworked register storage]
>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>>> ---
>>>  target/arm/cpu-custom.h            | 60 ++++++++++++++++++++++++++++++
>>>  target/arm/cpu-sysreg-properties.c | 41 ++++++++++++++++++++
>>>  target/arm/cpu64.c                 |  2 +
>>>  target/arm/meson.build             |  1 +
>>>  4 files changed, 104 insertions(+)
>>>  create mode 100644 target/arm/cpu-custom.h
>> do we still want reference to the "custom" terminology, following
>> initial comments?
> Hm, maybe 'cpu-idregs.h'?
OK for me

Eric
>
>>>  create mode 100644 target/arm/cpu-sysreg-properties.c
>>>
>>> diff --git a/target/arm/cpu-custom.h b/target/arm/cpu-custom.h
>>> new file mode 100644
>>> index 000000000000..615347376e56
>>> --- /dev/null
>>> +++ b/target/arm/cpu-custom.h
>>> @@ -0,0 +1,60 @@
>>> +/*
>>> + * handle ID registers and their fields
>>> + *
>>> + * SPDX-License-Identifier: GPL-2.0-or-later
>>> + */
>>> +#ifndef ARM_CPU_CUSTOM_H
>>> +#define ARM_CPU_CUSTOM_H
>>> +
>>> +#include "qemu/osdep.h"
>>> +#include "qemu/error-report.h"
>>> +#include "cpu.h"
>>> +#include "cpu-sysregs.h"
>>> +
>>> +typedef struct ARM64SysRegField {
>>> +    const char *name; /* name of the field, for instance CTR_EL0_IDC */
>>> +    int index;
>> worth to add a comment saying this is the ARMIDRegisterIdx of the parent
>> sysreg.
> ok
>
>>> +    int lower;
>>> +    int upper;
>>> +} ARM64SysRegField;
>>> +
>>> +typedef struct ARM64SysReg {
>>> +    const char *name;   /* name of the sysreg, for instance CTR_EL0 */
>>> +    ARMSysRegs sysreg;
>>> +    int index;
>> now that we have different kinds of indexing, may be worth adding a
>> comment to explain which one is being used.
>> I guess here it is ARMIDRegisterIdx. So you could even change the data type.
> Yeah, comments are good, I'll add some.
>
>>> +    GList *fields; /* list of named fields, excluding RES* */
>>> +} ARM64SysReg;
>>> +
>>> +void initialize_cpu_sysreg_properties(void);
>>> +
>>> +/*
>>> + * List of exposed ID regs (automatically populated from linux
>>> + * arch/arm64/tools/sysreg)
>>> + */
>>> +extern ARM64SysReg arm64_id_regs[NUM_ID_IDX];
>>> +
>>> +/* Allocate a new field and insert it at the head of the @reg list */
>>> +static inline GList *arm64_sysreg_add_field(ARM64SysReg *reg, const char *name,
>>> +                                     uint8_t min, uint8_t max) {
>>> +
>>> +     ARM64SysRegField *field = g_new0(ARM64SysRegField, 1);
>>> +
>>> +     field->name = name;
>>> +     field->lower = min;
>>> +     field->upper = max;
>>> +     field->index = reg->index;
>>> +
>>> +     reg->fields = g_list_append(reg->fields, field);
>>> +     return reg->fields;
>>> +}
>>> +
>>> +static inline ARM64SysReg *arm64_sysreg_get(ARMIDRegisterIdx index)
>>> +{
>>> +        ARM64SysReg *reg = &arm64_id_regs[index];
>>> +
>>> +        reg->index = index;
>>> +        reg->sysreg = id_register_sysreg[index];
>>> +        return reg;
>>> +}
>>> +
>>> +#endif
>>> diff --git a/target/arm/cpu-sysreg-properties.c b/target/arm/cpu-sysreg-properties.c
>>> new file mode 100644
>>> index 000000000000..8b7ef5badfb9
>>> --- /dev/null
>>> +++ b/target/arm/cpu-sysreg-properties.c
>>> @@ -0,0 +1,41 @@
>>> +/*
>>> + * QEMU ARM CPU SYSREG PROPERTIES
>>> + * to be generated from linux sysreg
>>> + *
>>> + * Copyright (c) Red Hat, Inc. 2024
>> maybe increment the year now ;-)
> Wait, it is 2025 already? :)
>



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 04/10] kvm: kvm_get_writable_id_regs
  2025-05-13 14:42     ` Cornelia Huck
@ 2025-05-13 15:16       ` Eric Auger
  0 siblings, 0 replies; 58+ messages in thread
From: Eric Auger @ 2025-05-13 15:16 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini



On 5/13/25 4:42 PM, Cornelia Huck wrote:
> On Tue, May 13 2025, Eric Auger <eric.auger@redhat.com> wrote:
>
>> Hi Connie,
>>
>> On 4/14/25 6:38 PM, Cornelia Huck wrote:
>>> Add an helper to retrieve the writable id reg bitmask. The
>>> status of the query is stored in the CPU struct so that an
>>> an error, if any, can be reported on vcpu realize().
>>>
>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>>> ---
>>>  target/arm/cpu.h     | 26 ++++++++++++++++++++++++++
>>>  target/arm/kvm.c     | 32 ++++++++++++++++++++++++++++++++
>>>  target/arm/kvm_arm.h |  7 +++++++
>>>  3 files changed, 65 insertions(+)
>>>
>>> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
>>> index d27134f4a025..bbee7ff2414a 100644
>>> --- a/target/arm/cpu.h
>>> +++ b/target/arm/cpu.h
>>> @@ -856,6 +856,26 @@ typedef struct {
>>>      uint32_t map, init, supported;
>>>  } ARMVQMap;
>>>  
>>> +typedef enum ARMIdRegsState {
>>> +    WRITABLE_ID_REGS_UNKNOWN,
>>> +    WRITABLE_ID_REGS_NOT_DISCOVERABLE,
>>> +    WRITABLE_ID_REGS_FAILED,
>>> +    WRITABLE_ID_REGS_AVAIL,
>>> +} ARMIdRegsState;
>>> +
>>> +/*
>>> + * The following structures are for the purpose of mapping the output of
>>> + * KVM_ARM_GET_REG_WRITABLE_MASKS that also may cover id registers we do
>>> + * not support in QEMU
>>> + * ID registers in op0==3, op1=={0,1,3}, crn=0, crm=={0-7}, op2=={0-7},
>>> + * as used by the KVM_ARM_GET_REG_WRITABLE_MASKS ioctl call.
>>> + */
>>> +#define NR_ID_REGS (3 * 8 * 8)
>> We may rename this define to better associate to the KVM API. I tend to
>> mix it with NUM_ID_IDX now ;-)
>> maybe something like KVM_NR_EXPOSED_ID_REGS
> The kernel calls it KVM_FEATURE_ID_RANGE_SIZE, but I'd like to avoid
> adding 'KVM' in the name, as it is basically a range of registers and
> nothing really KVM specific... maybe ID_REG_RANGE_SIZE?
what about NR_ID_REG_MASKS
because it is masks actually.
>
>>> +
>>> +typedef struct IdRegMap {
>>> +    uint64_t regs[NR_ID_REGS];
>>> +} IdRegMap;
>> I would add a comment saying this is the mask array, just to prevent the
>> reading from thinking it is the actual reg content.
> "More comments" seems to be a theme :) I'll go ahead and add them where
> it makes sense.
yeah. I am sorry. previously we had a single indexing and on top of that
we have several kinds of definitions for id regs and writable masks.
Even for me who contributed to that mess it can be difficult to parse so
I imagine it can be painful to read for other readers too ;-)

Eric
>
>>> +
>>>  /* REG is ID_XXX */
>>>  #define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE)                       \
>>>      ({                                                                  \
>>> @@ -1044,6 +1064,12 @@ struct ArchCPU {
>>>       */
>>>      bool host_cpu_probe_failed;
>>>  
>>> +    /*
>>> +     * state of writable id regs query used to report an error, if any,
>>> +     * on KVM custom vcpu model realize
>>> +     */
>>> +    ARMIdRegsState writable_id_regs;
>> maybe rename into writable_id_reg_status that would better reflect what
>> it is.
> Indeed.
>



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 02/10] arm/cpu: Add sysreg properties generation
  2025-04-14 16:38 ` [PATCH v3 02/10] arm/cpu: Add sysreg properties generation Cornelia Huck
  2025-04-15  7:09   ` Philippe Mathieu-Daudé
@ 2025-05-13 15:23   ` Daniel P. Berrangé
  2025-05-14 15:25     ` Cornelia Huck
  1 sibling, 1 reply; 58+ messages in thread
From: Daniel P. Berrangé @ 2025-05-13 15:23 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, abologna, jdenemar,
	agraf, shahuang, mark.rutland, philmd, pbonzini

On Mon, Apr 14, 2025 at 06:38:41PM +0200, Cornelia Huck wrote:
> From: Eric Auger <eric.auger@redhat.com>
> 
> Introduce a script that automates the generation of system register
> properties definitions from a given linux source tree
> arch/arm64/tools/sysreg.
> 
> Invocation of
> ./update-aarch64-sysreg-code.sh $PATH_TO_LINUX_SOURCE_TREE
> in scripts directory additionally generates
> target/arm/cpu-sysreg-properties.c containing definitions for
> feature ID registers.
> 
> update-aarch64-sysreg-code.sh additionally calls
> gen-cpu-sysreg-properties.awk which is inherited from kernel
> arch/arm64/tools/gen-sysreg.awk. All credits to Mark Rutland
> the original author of this script.
> 
> [CH: split off from original patch adding both sysreg definitions
>  and properties]
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
>  scripts/gen-cpu-sysreg-properties.awk | 325 ++++++++++++++++++++++++++
>  scripts/update-aarch64-sysreg-code.sh |   5 +-
>  2 files changed, 329 insertions(+), 1 deletion(-)
>  create mode 100755 scripts/gen-cpu-sysreg-properties.awk
> 
> diff --git a/scripts/gen-cpu-sysreg-properties.awk b/scripts/gen-cpu-sysreg-properties.awk
> new file mode 100755
> index 000000000000..76c37938b168
> --- /dev/null
> +++ b/scripts/gen-cpu-sysreg-properties.awk
> @@ -0,0 +1,325 @@
> +#!/bin/awk -f
> +# SPDX-License-Identifier: GPL-2.0

GPL-2.0 is a deprecated SPDX identifier. checkpatch.pl ought to
have complained about this, requiring GPL-2.0-or-later as the
preference, with GPL-2.0-only requiring justification in the
commit.

> +# gen-cpu-sysreg-properties.awk: arm64 sysreg header generator
> +#
> +# Usage: awk -f gen-cpu-sysreg-properties.awk $LINUX_PATH/arch/arm64/tools/sysreg

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model
  2025-04-14 16:38 [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
                   ` (9 preceding siblings ...)
  2025-04-14 16:38 ` [PATCH v3 10/10] arm/cpu-features: document ID reg properties Cornelia Huck
@ 2025-05-13 15:29 ` Eric Auger
  2025-05-14 13:47   ` Shameerali Kolothum Thodi via
  2025-05-23 13:23 ` Shameerali Kolothum Thodi via
  11 siblings, 1 reply; 58+ messages in thread
From: Eric Auger @ 2025-05-13 15:29 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini

Hi,

On 4/14/25 6:38 PM, Cornelia Huck wrote:
> [This is on top of v5 of the ID register storage rework:
> https://lore.kernel.org/qemu-devel/20250409144304.912325-1-cohuck@redhat.com/T/#t]
>
> It's been a while, but here's finally a respin of the series to make ID
> registers configurable directly via the command line.
>
> Major changes from v2 include:
> - split out the rework of ID register storage (see above) and rebased on top
>   of that
> - hopefully improved the documentation
> - fixed some bugs along the way (including output of the cpu model expansion
>   command, and compilation with HVF on)
>
> Decided against zeroing unknown registers; it's mostly a "dammed if you do,
> dammed if you don't" situation as one case or the other will not quite work
> as desired, even disregarding fields like AA64PFR1_EL1.MTE_frac where 0
> might indicate things we do not support. You'll need to be careful when
> doing kernel updates and be explicit with configuring fields.
This is not totally clear to me. Is it possible to come with examples
and also derive some guidelines to avoid pitfalls? I guess this kind of
aknowledgement can be scary.
>
> The current cpu properties stay as they are; we can work on converting them
> to compatibility props once we have support for configuring the ID register
> fields on the command line for the other accelerators (this is still KVM only.)

At least what can we do to make sure they are not inconsistent and work
well together. Looks like a must have before being non RFC.
>
> The FEAT_xxx features only support a subset of what we need to configure in
> real life; for example, different AltraMax machines differ in CTR_EL0, which
> is not covered by any FEAT_. It might make sense to provide them as syntactic
> sugar on top.

I agree that anyway we will need an ID reg field granularity for some
real life cases. On top of that we shall try to build higher level props
matching to features as requested by an overwhelming majority in earlier
comments.
>
> We still have to deal with MIDR/REVIDR/AIDR differences by exploiting
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit?id=d300b0168ea8fd5022a1413bd37ab63f4e5a7d4d
> (in a different series.)
Shameer, do you plan to contribute the qemu integration of this feature
you developped on kernel side; or do you allow us to integrate it in
this series?

Thanks

Eric
>
> I have not ignored the issue of named models on Arm, I just wanted to get the
> base infrastructure into place first :)
>
> Real world example (migration Graviton 3 -> 4, thx to Sebastian):
>
> -cpu host,pauth=off,SYSREG_ID_AA64PFR0_EL1_SEL2=0,SYSREG_ID_AA64PFR0_EL1_EL0=1,
>  SYSREG_ID_AA64ISAR0_EL1_TLB=0,SYSREG_ID_AA64ISAR0_EL1_TS=0,
>  SYSREG_ID_AA64ISAR0_EL1_SM4=0,SYSREG_ID_AA64ISAR0_EL1_SM3=0,
>  SYSREG_ID_AA64ISAR1_EL1_SPECRES=0,SYSREG_ID_AA64ISAR1_EL1_SB=0,
>  SYSREG_ID_AA64ISAR1_EL1_FRINTTS=0,SYSREG_ID_AA64MMFR0_EL1_TGRAN4_2=1,
>  SYSREG_ID_AA64MMFR0_EL1_TGRAN16_2=1,SYSREG_ID_AA64MMFR0_EL1_TGRAN64_2=1
>
> (not including handling MIDR differences, which is out of scope for this series)
>
> Code also available at
> https://gitlab.com/cohuck/qemu/-/tree/arm-cpu-model-rfcv3?ref_type=heads
>
>
> Cornelia Huck (5):
>   arm/cpu: Add generated sysreg properties
>   kvm: kvm_get_writable_id_regs
>   arm/cpu: accessors for writable id registers
>   arm-qmp-cmds: introspection for ID register props
>   arm/cpu-features: document ID reg properties
>
> Eric Auger (5):
>   arm/cpu: Add infra to handle generated ID register definitions
>   arm/cpu: Add sysreg properties generation
>   arm/kvm: Allow reading all the writable ID registers
>   arm/kvm: write back modified ID regs to KVM
>   arm/cpu: more customization for the kvm host cpu model
>
>  docs/system/arm/cpu-features.rst      | 104 +++-
>  scripts/gen-cpu-sysreg-properties.awk | 325 ++++++++++++
>  scripts/update-aarch64-sysreg-code.sh |   5 +-
>  target/arm/arm-qmp-cmds.c             |  19 +
>  target/arm/cpu-custom.h               |  60 +++
>  target/arm/cpu-sysreg-properties.c    | 713 ++++++++++++++++++++++++++
>  target/arm/cpu-sysregs.h              |   2 +
>  target/arm/cpu.c                      |  12 +
>  target/arm/cpu.h                      |  47 ++
>  target/arm/cpu64.c                    |  24 +-
>  target/arm/kvm.c                      | 289 ++++++++++-
>  target/arm/kvm_arm.h                  |  26 +-
>  target/arm/meson.build                |   1 +
>  target/arm/trace-events               |   6 +
>  14 files changed, 1617 insertions(+), 16 deletions(-)
>  create mode 100755 scripts/gen-cpu-sysreg-properties.awk
>  create mode 100644 target/arm/cpu-custom.h
>  create mode 100644 target/arm/cpu-sysreg-properties.c
>



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model
  2025-04-14 16:38 ` [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model Cornelia Huck
  2025-05-13 14:47   ` Eric Auger
@ 2025-05-13 15:56   ` Daniel P. Berrangé
  2025-05-16 14:42     ` Cornelia Huck
  2025-05-13 15:59   ` Daniel P. Berrangé
  2 siblings, 1 reply; 58+ messages in thread
From: Daniel P. Berrangé @ 2025-05-13 15:56 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, abologna, jdenemar,
	agraf, shahuang, mark.rutland, philmd, pbonzini

On Mon, Apr 14, 2025 at 06:38:47PM +0200, Cornelia Huck wrote:
> From: Eric Auger <eric.auger@redhat.com>
> 
> If the interface for writable ID registers is available, expose uint64
> SYSREG properties for writable ID reg fields exposed by the host
> kernel. Properties are named  SYSREG_<REG>_<FIELD> with REG and FIELD
> being those used  in linux arch/arm64/tools/sysreg. This done by
> matching the writable fields retrieved from the host kernel against the
> generated description of sysregs.
> 
> An example of invocation is:
> -cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0
> which sets DP field of ID_AA64ISAR0_EL1 to 0.

Functionally this works, but stylewise it is rather too verbose
IMHO. I understand this aims to mtch the arm feature names, but
we can at least drop the SYSREG_ prefix here which IMHO doesn't
add much value. The <REG> component only has a small number of
possible prefixes, so it seems pretty unlikely we would get a
name clash between these and some other QOM property.

Also could we stick with lowercase, rather than uppercase. I
appreciate the spec uses uppercase, but that doesn't concern
itself with end user usage. If we just plain transform everything
to lowercase, there's still a clear mapping to the spec that
people will understand [1].

This example uses '-cpu host', but does this also work
with '-cpu max'  ?

Conceptually '-cpu max' is supposed to be functionally identical
to '-cpu host' when KVM is enabled. Obviously you'd ned to
exclude it from '-cpu max' with TCG or other non-KVM accels.


> +/*
> + * decode_idreg_writemap: Generate props for writable fields
> + *
> + * @obj: CPU object
> + * @index: index of the sysreg
> + * @map: writable map for the sysreg
> + * @reg: description of the sysreg
> + */
> +static int
> +decode_idreg_writemap(Object *obj, int index, uint64_t map, ARM64SysReg *reg)
> +{
> +    int i = ctz64(map);
> +    int nb_sysreg_props = 0;
> +
> +    while (map) {
> +
> +        ARM64SysRegField *field = get_field(i, reg);
> +        int lower, upper;
> +        uint64_t mask;
> +        char *prop_name;
> +
> +        if (!field) {
> +            /* the field cannot be matched to any know id named field */
> +            warn_report("%s bit %d of %s is writable but cannot be matched",
> +                        __func__, i, reg->name);
> +            warn_report("%s is cpu-sysreg-properties.c up to date?", __func__);

What scenario triggers this warning ? Is this in relation to QEMU
auto-detecting host CPU features, as opposed to user -cpu input ?

> +            map =  map & ~BIT_ULL(i);
> +            i = ctz64(map);
> +            continue;
> +        }
> +        lower = field->lower;
> +        upper = field->upper;
> +        prop_name = g_strdup_printf("SYSREG_%s_%s", reg->name, field->name);
> +        trace_decode_idreg_writemap(field->name, lower, upper, prop_name);
> +        object_property_add(obj, prop_name, "uint64",
> +                            get_sysreg_prop, set_sysreg_prop, NULL, field);
> +        nb_sysreg_props++;
> +
> +        mask = MAKE_64BIT_MASK(lower, upper - lower + 1);
> +        map = map & ~mask;
> +        i = ctz64(map);
> +    }
> +    trace_nb_sysreg_props(reg->name, nb_sysreg_props);
> +    return 0;
> +}
> +
> +/* analyze the writable mask and generate properties for writable fields */
> +void kvm_arm_expose_idreg_properties(ARMCPU *cpu, ARM64SysReg *regs)
> +{
> +    int i, idx;
> +    IdRegMap *map = cpu->writable_map;
> +    Object *obj = OBJECT(cpu);
> +
> +    for (i = 0; i < NR_ID_REGS; i++) {
> +        uint64_t mask = map->regs[i];
> +
> +        if (mask) {
> +            /* reg @i has some writable fields, decode them */
> +            idx = kvm_idx_to_idregs_idx(i);
> +            if (idx < 0) {
> +                /* no matching reg? */
> +                warn_report("%s: reg %d writable, but not in list of idregs?",
> +                            __func__, i);
> +            } else {
> +                decode_idreg_writemap(obj, i, mask, &regs[idx]);
> +            }
> +        }
> +    }
> +}
> +

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model
  2025-04-14 16:38 ` [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model Cornelia Huck
  2025-05-13 14:47   ` Eric Auger
  2025-05-13 15:56   ` Daniel P. Berrangé
@ 2025-05-13 15:59   ` Daniel P. Berrangé
  2025-05-14 15:36     ` Cornelia Huck
  2 siblings, 1 reply; 58+ messages in thread
From: Daniel P. Berrangé @ 2025-05-13 15:59 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, abologna, jdenemar,
	agraf, shahuang, mark.rutland, philmd, pbonzini

On Mon, Apr 14, 2025 at 06:38:47PM +0200, Cornelia Huck wrote:
> From: Eric Auger <eric.auger@redhat.com>
> 
> If the interface for writable ID registers is available, expose uint64
> SYSREG properties for writable ID reg fields exposed by the host
> kernel. Properties are named  SYSREG_<REG>_<FIELD> with REG and FIELD
> being those used  in linux arch/arm64/tools/sysreg. This done by
> matching the writable fields retrieved from the host kernel against the
> generated description of sysregs.
> 
> An example of invocation is:
> -cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0
> which sets DP field of ID_AA64ISAR0_EL1 to 0.

For the value you are illustrating 0x0 - is this implying that
all the flags take an arbitrary integer hex value ?

This would be different from x86, where CPU feature flags are
a boolean on/off state.

> [CH: add properties to the host model instead of introducing a new
> "custom" model]
> Signed-off-by: Eric Auger <eric.auger@redhat.com>

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 10/10] arm/cpu-features: document ID reg properties
  2025-04-14 16:38 ` [PATCH v3 10/10] arm/cpu-features: document ID reg properties Cornelia Huck
  2025-05-13 15:09   ` Eric Auger
@ 2025-05-13 16:23   ` Daniel P. Berrangé
  1 sibling, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2025-05-13 16:23 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, abologna, jdenemar,
	agraf, shahuang, mark.rutland, philmd, pbonzini

On Mon, Apr 14, 2025 at 06:38:49PM +0200, Cornelia Huck wrote:
> Add some documentation for how individual ID registers can be
> configured with the host cpu model.
> 
> [CH: adapt to removal of the 'custom' model, added some more
>  explanations about using the ID register props]
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
>  docs/system/arm/cpu-features.rst | 104 ++++++++++++++++++++++++++++---
>  1 file changed, 96 insertions(+), 8 deletions(-)
> 
> diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
> index 37d5dfd15b34..22faefd76edd 100644
> --- a/docs/system/arm/cpu-features.rst
> +++ b/docs/system/arm/cpu-features.rst
> @@ -2,7 +2,10 @@ Arm CPU Features
>  ================
>  
>  CPU features are optional features that a CPU of supporting type may
> -choose to implement or not.  In QEMU, optional CPU features have
> +choose to implement or not.  QEMU provides two different mechanisms
> +to configure those features:
> +
> +1. For most CPU models, optional CPU features may have
>  corresponding boolean CPU proprieties that, when enabled, indicate
>  that the feature is implemented, and, conversely, when disabled,
>  indicate that it is not implemented. An example of an Arm CPU feature
> @@ -29,6 +32,16 @@ supports the feature.  While ``aarch64`` currently only works with KVM,
>  it could work with TCG.  CPU features that are specific to KVM are
>  prefixed with "kvm-" and are described in "KVM VCPU Features".
>  
> +2. Additionally, the ``host`` CPU model on KVM allows to configure optional
> +CPU features via the corresponding ID registers. The host kernel allows
> +to write a subset of ID register fields. The host model exposes
> +properties for each writable ID register field. Those options are named
> +SYSREG_<IDREG>_<FIELD>. IDREG and FIELD names are those used in the
> +ARM ARM Reference Manual. They can also be found in the Linux
> +arch/arm64/tool/sysreg file which is used to automatically generate the
> +description for those registers and fields. This currently only has been
> +implemented for KVM.

Whereever they are referencing 'host', the docs should also
mention 'max' CPU which should be a drop-in functional
equivalent.

> +
>  CPU Feature Probing
>  ===================
>  
> @@ -124,13 +137,20 @@ A note about CPU models and KVM
>  
>  Named CPU models generally do not work with KVM.  There are a few cases
>  that do work, e.g. using the named CPU model ``cortex-a57`` with KVM on a
> -seattle host, but mostly if KVM is enabled the ``host`` CPU type must be
> -used.  This means the guest is provided all the same CPU features as the
> -host CPU type has.  And, for this reason, the ``host`` CPU type should
> -enable all CPU features that the host has by default.  Indeed it's even
> -a bit strange to allow disabling CPU features that the host has when using
> -the ``host`` CPU type, but in the absence of CPU models it's the best we can
> -do if we want to launch guests without all the host's CPU features enabled.
> +seattle host, but mostly if KVM is enabled, the ``host`` CPU model must be
> +used.
> +
> +Using the ``host`` type means the guest is provided all the same CPU
> +features as the host CPU type has.  And, for this reason, the ``host``
> +CPU type should enable all CPU features that the host has by default.
> +
> +In case some features need to be hidden to the guest, and the host kernel
> +supports it, the ``host`` model can be instructed to disable individual
> +ID register values. This is especially useful for migration purposes.
> +However, this interface will not allow configuring an arbitrary set of
> +features; the ID registers must describe a subset of the host's features,
> +and all differences to the host's configuration must actually be supported
> +by the kernel to be deconfigured.
>  
>  Enabling KVM also affects the ``query-cpu-model-expansion`` QMP command.  The
>  affect is not only limited to specific features, as pointed out in example
> @@ -167,6 +187,13 @@ disabling many SVE vector lengths would be quite verbose, the ``sve<N>`` CPU
>  properties have special semantics (see "SVE CPU Property Parsing
>  Semantics").
>  
> +Additionally, if supported by KVM on the host kernel, the ``host`` CPU model
> +may be configured via individual ID register field properties, for example::
> +
> +  $ qemu-system-aarch64 -M virt -cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0
> +
> +This forces ID_AA64ISAR0_EL1 DP field to 0.
> +
>  KVM VCPU Features
>  =================
>  
> @@ -466,3 +493,64 @@ Legal values for ``S`` are 30, 34, 36, and 39; the default is 30.
>  
>  As with ``x-rme``, the ``x-l0gptsz`` property may be renamed or
>  removed in some future QEMU release.
> +
> +Configuring CPU features via ID register fields
> +===============================================
> +
> +Note that this is currently only supported under KVM, and with the
> +``host`` CPU model.
> +
> +Querying available ID register fields
> +-------------------------------------
> +
> +QEMU will create properties for all ID register fields that are
> +reported as being writable by the kernel, and that are known to the
> +QEMU instance. Therefore, the same QEMU binary may expose different
> +properties when run under a different kernel.
> +
> +To find out all available writable ID register fields, use the
> +``query-cpu-model-expansion`` QMP command::
> +
> +  (QEMU) query-cpu-model-expansion type=full model={"name":"host"}
> +  {"return": {
> +   "model": {"name": "host", "props": {
> +   "SYSREG_ID_AA64PFR0_EL1_EL3": 1, "SYSREG_ID_AA64ISAR2_EL1_CLRBHB": 0,
> +   "SYSREG_CTR_EL0_L1Ip": 3, "SYSREG_CTR_EL0_DminLine": 4,
> +   "SYSREG_ID_AA64MMFR0_EL1_BIGEND": 1, "SYSREG_ID_AA64MMFR1_EL1_ECBHB": 0,
> +   "SYSREG_ID_AA64MMFR2_EL1_CnP": 1, "SYSREG_ID_DFR0_EL1_PerfMon": 4,
> +   "SYSREG_ID_AA64PFR0_EL1_DIT": 0, "SYSREG_ID_AA64MMFR1_EL1_HAFDBS": 2,
> +   "SYSREG_ID_AA64ISAR0_EL1_FHM": 0, "SYSREG_ID_AA64ISAR2_EL1_CSSC": 0,
> +   "SYSREG_ID_AA64ISAR0_EL1_DP": 1, (...)
> +   }}}}
> +
> +If a certain field in an ID register does not show up in this list, it
> +is not writable with the specific host kernel.

On x86,   "-cpu help" will list all feature names too. It makes the
output pretty huge, so not sure if we want to mirror that on arm ?
It is at least more useful to humans though, compared to QMP.


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model
  2025-05-13 15:29 ` [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
@ 2025-05-14 13:47   ` Shameerali Kolothum Thodi via
  2025-05-14 14:47     ` Eric Auger
  0 siblings, 1 reply; 58+ messages in thread
From: Shameerali Kolothum Thodi via @ 2025-05-14 13:47 UTC (permalink / raw)
  To: eric.auger@redhat.com, Cornelia Huck, eric.auger.pro@gmail.com,
	qemu-devel@nongnu.org, qemu-arm@nongnu.org,
	kvmarm@lists.linux.dev, peter.maydell@linaro.org,
	richard.henderson@linaro.org, alex.bennee@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, sebott@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com
  Cc: agraf@csgraf.de, shahuang@redhat.com, mark.rutland@arm.com,
	philmd@linaro.org, pbonzini@redhat.com



> -----Original Message-----
> From: Eric Auger <eric.auger@redhat.com>
> Sent: Tuesday, May 13, 2025 4:30 PM
> To: Cornelia Huck <cohuck@redhat.com>; eric.auger.pro@gmail.com; qemu-
> devel@nongnu.org; qemu-arm@nongnu.org; kvmarm@lists.linux.dev;
> peter.maydell@linaro.org; richard.henderson@linaro.org;
> alex.bennee@linaro.org; maz@kernel.org; oliver.upton@linux.dev;
> sebott@redhat.com; Shameerali Kolothum Thodi
> <shameerali.kolothum.thodi@huawei.com>; armbru@redhat.com;
> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
> Cc: agraf@csgraf.de; shahuang@redhat.com; mark.rutland@arm.com;
> philmd@linaro.org; pbonzini@redhat.com
> Subject: Re: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64
> KVM host model

[...]

> > We still have to deal with MIDR/REVIDR/AIDR differences by exploiting
> >
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit?i
> d=d300b0168ea8fd5022a1413bd37ab63f4e5a7d4d
> > (in a different series.)
> Shameer, do you plan to contribute the qemu integration of this feature
> you developped on kernel side; or do you allow us to integrate it in
> this series?

Yes, it's on my ToDo list. I'll first go through this series and then work on
adding the above support on top of it.

Thanks,
Shameer


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model
  2025-05-14 13:47   ` Shameerali Kolothum Thodi via
@ 2025-05-14 14:47     ` Eric Auger
  0 siblings, 0 replies; 58+ messages in thread
From: Eric Auger @ 2025-05-14 14:47 UTC (permalink / raw)
  To: Shameerali Kolothum Thodi, Cornelia Huck,
	eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, richard.henderson@linaro.org,
	alex.bennee@linaro.org, maz@kernel.org, oliver.upton@linux.dev,
	sebott@redhat.com, armbru@redhat.com, berrange@redhat.com,
	abologna@redhat.com, jdenemar@redhat.com
  Cc: agraf@csgraf.de, shahuang@redhat.com, mark.rutland@arm.com,
	philmd@linaro.org, pbonzini@redhat.com



On 5/14/25 3:47 PM, Shameerali Kolothum Thodi wrote:
>
>> -----Original Message-----
>> From: Eric Auger <eric.auger@redhat.com>
>> Sent: Tuesday, May 13, 2025 4:30 PM
>> To: Cornelia Huck <cohuck@redhat.com>; eric.auger.pro@gmail.com; qemu-
>> devel@nongnu.org; qemu-arm@nongnu.org; kvmarm@lists.linux.dev;
>> peter.maydell@linaro.org; richard.henderson@linaro.org;
>> alex.bennee@linaro.org; maz@kernel.org; oliver.upton@linux.dev;
>> sebott@redhat.com; Shameerali Kolothum Thodi
>> <shameerali.kolothum.thodi@huawei.com>; armbru@redhat.com;
>> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
>> Cc: agraf@csgraf.de; shahuang@redhat.com; mark.rutland@arm.com;
>> philmd@linaro.org; pbonzini@redhat.com
>> Subject: Re: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64
>> KVM host model
> [...]
>
>>> We still have to deal with MIDR/REVIDR/AIDR differences by exploiting
>>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit?i
>> d=d300b0168ea8fd5022a1413bd37ab63f4e5a7d4d
>>> (in a different series.)
>> Shameer, do you plan to contribute the qemu integration of this feature
>> you developped on kernel side; or do you allow us to integrate it in
>> this series?
> Yes, it's on my ToDo list. I'll first go through this series and then work on
> adding the above support on top of it.

OK. Thank you for your reply!

Cheers

Eric
>
> Thanks,
> Shameer
>



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 02/10] arm/cpu: Add sysreg properties generation
  2025-05-13 15:23   ` Daniel P. Berrangé
@ 2025-05-14 15:25     ` Cornelia Huck
  2025-05-14 15:29       ` Daniel P. Berrangé
  0 siblings, 1 reply; 58+ messages in thread
From: Cornelia Huck @ 2025-05-14 15:25 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, abologna, jdenemar,
	agraf, shahuang, mark.rutland, philmd, pbonzini

On Tue, May 13 2025, Daniel P. Berrangé <berrange@redhat.com> wrote:

> On Mon, Apr 14, 2025 at 06:38:41PM +0200, Cornelia Huck wrote:
>> From: Eric Auger <eric.auger@redhat.com>
>> 
>> Introduce a script that automates the generation of system register
>> properties definitions from a given linux source tree
>> arch/arm64/tools/sysreg.
>> 
>> Invocation of
>> ./update-aarch64-sysreg-code.sh $PATH_TO_LINUX_SOURCE_TREE
>> in scripts directory additionally generates
>> target/arm/cpu-sysreg-properties.c containing definitions for
>> feature ID registers.
>> 
>> update-aarch64-sysreg-code.sh additionally calls
>> gen-cpu-sysreg-properties.awk which is inherited from kernel
>> arch/arm64/tools/gen-sysreg.awk. All credits to Mark Rutland
>> the original author of this script.
>> 
>> [CH: split off from original patch adding both sysreg definitions
>>  and properties]
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>> ---
>>  scripts/gen-cpu-sysreg-properties.awk | 325 ++++++++++++++++++++++++++
>>  scripts/update-aarch64-sysreg-code.sh |   5 +-
>>  2 files changed, 329 insertions(+), 1 deletion(-)
>>  create mode 100755 scripts/gen-cpu-sysreg-properties.awk
>> 
>> diff --git a/scripts/gen-cpu-sysreg-properties.awk b/scripts/gen-cpu-sysreg-properties.awk
>> new file mode 100755
>> index 000000000000..76c37938b168
>> --- /dev/null
>> +++ b/scripts/gen-cpu-sysreg-properties.awk
>> @@ -0,0 +1,325 @@
>> +#!/bin/awk -f
>> +# SPDX-License-Identifier: GPL-2.0
>
> GPL-2.0 is a deprecated SPDX identifier. checkpatch.pl ought to
> have complained about this, requiring GPL-2.0-or-later as the
> preference, with GPL-2.0-only requiring justification in the
> commit.

GPL-2.0 is inherited from the Linux script mentioned; not sure if
GPL-2.0-only would be the correct fit here?



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 02/10] arm/cpu: Add sysreg properties generation
  2025-05-14 15:25     ` Cornelia Huck
@ 2025-05-14 15:29       ` Daniel P. Berrangé
  0 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2025-05-14 15:29 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, abologna, jdenemar,
	agraf, shahuang, mark.rutland, philmd, pbonzini

On Wed, May 14, 2025 at 05:25:59PM +0200, Cornelia Huck wrote:
> On Tue, May 13 2025, Daniel P. Berrangé <berrange@redhat.com> wrote:
> 
> > On Mon, Apr 14, 2025 at 06:38:41PM +0200, Cornelia Huck wrote:
> >> From: Eric Auger <eric.auger@redhat.com>
> >> 
> >> Introduce a script that automates the generation of system register
> >> properties definitions from a given linux source tree
> >> arch/arm64/tools/sysreg.
> >> 
> >> Invocation of
> >> ./update-aarch64-sysreg-code.sh $PATH_TO_LINUX_SOURCE_TREE
> >> in scripts directory additionally generates
> >> target/arm/cpu-sysreg-properties.c containing definitions for
> >> feature ID registers.
> >> 
> >> update-aarch64-sysreg-code.sh additionally calls
> >> gen-cpu-sysreg-properties.awk which is inherited from kernel
> >> arch/arm64/tools/gen-sysreg.awk. All credits to Mark Rutland
> >> the original author of this script.
> >> 
> >> [CH: split off from original patch adding both sysreg definitions
> >>  and properties]
> >> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> >> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> >> ---
> >>  scripts/gen-cpu-sysreg-properties.awk | 325 ++++++++++++++++++++++++++
> >>  scripts/update-aarch64-sysreg-code.sh |   5 +-
> >>  2 files changed, 329 insertions(+), 1 deletion(-)
> >>  create mode 100755 scripts/gen-cpu-sysreg-properties.awk
> >> 
> >> diff --git a/scripts/gen-cpu-sysreg-properties.awk b/scripts/gen-cpu-sysreg-properties.awk
> >> new file mode 100755
> >> index 000000000000..76c37938b168
> >> --- /dev/null
> >> +++ b/scripts/gen-cpu-sysreg-properties.awk
> >> @@ -0,0 +1,325 @@
> >> +#!/bin/awk -f
> >> +# SPDX-License-Identifier: GPL-2.0
> >
> > GPL-2.0 is a deprecated SPDX identifier. checkpatch.pl ought to
> > have complained about this, requiring GPL-2.0-or-later as the
> > preference, with GPL-2.0-only requiring justification in the
> > commit.
> 
> GPL-2.0 is inherited from the Linux script mentioned; not sure if
> GPL-2.0-only would be the correct fit here?

Yes, according to the table of deprecated terms at the bottom of

https://spdx.org/licenses/

GPL-2.0-only would indeed be the correct replacement.

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model
  2025-05-13 15:59   ` Daniel P. Berrangé
@ 2025-05-14 15:36     ` Cornelia Huck
  2025-05-14 18:22       ` Daniel P. Berrangé
  0 siblings, 1 reply; 58+ messages in thread
From: Cornelia Huck @ 2025-05-14 15:36 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, abologna, jdenemar,
	agraf, shahuang, mark.rutland, philmd, pbonzini

On Tue, May 13 2025, Daniel P. Berrangé <berrange@redhat.com> wrote:

> On Mon, Apr 14, 2025 at 06:38:47PM +0200, Cornelia Huck wrote:
>> From: Eric Auger <eric.auger@redhat.com>
>> 
>> If the interface for writable ID registers is available, expose uint64
>> SYSREG properties for writable ID reg fields exposed by the host
>> kernel. Properties are named  SYSREG_<REG>_<FIELD> with REG and FIELD
>> being those used  in linux arch/arm64/tools/sysreg. This done by
>> matching the writable fields retrieved from the host kernel against the
>> generated description of sysregs.
>> 
>> An example of invocation is:
>> -cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0
>> which sets DP field of ID_AA64ISAR0_EL1 to 0.
>
> For the value you are illustrating 0x0 - is this implying that
> all the flags take an arbitrary integer hex value ?
>
> This would be different from x86, where CPU feature flags are
> a boolean on/off state.

Most of the fields are 4 bits, the allowed values vary (there are also
some fields that are single bits, or wider.) The FEAT_xxx values (which
can be expressed via ID register fields, or a combination thereof) are
mostly boolean, but there are also some of them that can take values.

We could cook up pseudo-features that are always on/off, but I don't
like that approach: they would be QEMU only, whereas the ID register
fields and FEAT_xxx features are all defined in the Arm documentation.

An additional difference from x86 would be that FEAT_xxx featues are not
neccessarily configurable (only if the host kernel supports changing the
ID register field(s) backing the feature.)



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model
  2025-05-14 15:36     ` Cornelia Huck
@ 2025-05-14 18:22       ` Daniel P. Berrangé
  2025-05-16 14:51         ` Cornelia Huck
  0 siblings, 1 reply; 58+ messages in thread
From: Daniel P. Berrangé @ 2025-05-14 18:22 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, abologna, jdenemar,
	agraf, shahuang, mark.rutland, philmd, pbonzini

On Wed, May 14, 2025 at 05:36:58PM +0200, Cornelia Huck wrote:
> On Tue, May 13 2025, Daniel P. Berrangé <berrange@redhat.com> wrote:
> 
> > On Mon, Apr 14, 2025 at 06:38:47PM +0200, Cornelia Huck wrote:
> >> From: Eric Auger <eric.auger@redhat.com>
> >> 
> >> If the interface for writable ID registers is available, expose uint64
> >> SYSREG properties for writable ID reg fields exposed by the host
> >> kernel. Properties are named  SYSREG_<REG>_<FIELD> with REG and FIELD
> >> being those used  in linux arch/arm64/tools/sysreg. This done by
> >> matching the writable fields retrieved from the host kernel against the
> >> generated description of sysregs.
> >> 
> >> An example of invocation is:
> >> -cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0
> >> which sets DP field of ID_AA64ISAR0_EL1 to 0.
> >
> > For the value you are illustrating 0x0 - is this implying that
> > all the flags take an arbitrary integer hex value ?
> >
> > This would be different from x86, where CPU feature flags are
> > a boolean on/off state.
> 
> Most of the fields are 4 bits, the allowed values vary (there are also
> some fields that are single bits, or wider.) The FEAT_xxx values (which
> can be expressed via ID register fields, or a combination thereof) are
> mostly boolean, but there are also some of them that can take values.
> 
> We could cook up pseudo-features that are always on/off, but I don't
> like that approach: they would be QEMU only, whereas the ID register
> fields and FEAT_xxx features are all defined in the Arm documentation.

Fortunately from a libvirt POV we can likely expand our config
to cope with hex values for arm features without too much
trouble.

> 
> An additional difference from x86 would be that FEAT_xxx featues are not
> neccessarily configurable (only if the host kernel supports changing the
> ID register field(s) backing the feature.)

Is the kernel able to tell us which ones are configurable and which
are not ? If so, it'd be helpful to expose this info in QAPI some
place.

> 

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 06/10] arm/kvm: Allow reading all the writable ID registers
  2025-05-13 14:31   ` Eric Auger
@ 2025-05-16 14:17     ` Cornelia Huck
  2025-05-20 14:05     ` Cornelia Huck
  1 sibling, 0 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-05-16 14:17 UTC (permalink / raw)
  To: eric.auger, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini

On Tue, May 13 2025, Eric Auger <eric.auger@redhat.com> wrote:

> On 4/14/25 6:38 PM, Cornelia Huck wrote:
>> From: Eric Auger <eric.auger@redhat.com>
(...)

>> +static bool
>> +kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf,
>> +                              bool exhaustive)
> maybe the exhaustive term shall be replaced by handle_writable_id_regs
> which tells more explicitly what it does

Maybe get_all_writable_id_regs?

>>  {
>>      /* Identify the feature bits corresponding to the host CPU, and
>>       * fill out the ARMHostCPUClass fields accordingly. To do this

(...)

>> diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
>> index 8d1f20ca8d89..90ba4f7d8987 100644
>> --- a/target/arm/kvm_arm.h
>> +++ b/target/arm/kvm_arm.h
>> @@ -141,8 +141,12 @@ uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu);
>>   *
>>   * Set up the ARMCPU struct fields up to match the information probed
>>   * from the host CPU.
>> + *
>> + * @cpu: cpu object
>> + * @exhaustive: if true, all the feature ID regs are queried instead of
> s/queried/handled
>> + *              a subset

And make this "if true, additionally get the contents of all writable ID
registers as well"?

>>   */
>> -void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
>> +void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, bool exhaustive);



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model
  2025-05-13 15:56   ` Daniel P. Berrangé
@ 2025-05-16 14:42     ` Cornelia Huck
  0 siblings, 0 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-05-16 14:42 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, abologna, jdenemar,
	agraf, shahuang, mark.rutland, philmd, pbonzini

On Tue, May 13 2025, Daniel P. Berrangé <berrange@redhat.com> wrote:

> On Mon, Apr 14, 2025 at 06:38:47PM +0200, Cornelia Huck wrote:
>> From: Eric Auger <eric.auger@redhat.com>
>> 
>> If the interface for writable ID registers is available, expose uint64
>> SYSREG properties for writable ID reg fields exposed by the host
>> kernel. Properties are named  SYSREG_<REG>_<FIELD> with REG and FIELD
>> being those used  in linux arch/arm64/tools/sysreg. This done by
>> matching the writable fields retrieved from the host kernel against the
>> generated description of sysregs.
>> 
>> An example of invocation is:
>> -cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0
>> which sets DP field of ID_AA64ISAR0_EL1 to 0.
>
> Functionally this works, but stylewise it is rather too verbose
> IMHO. I understand this aims to mtch the arm feature names, but
> we can at least drop the SYSREG_ prefix here which IMHO doesn't
> add much value. The <REG> component only has a small number of
> possible prefixes, so it seems pretty unlikely we would get a
> name clash between these and some other QOM property.

The main reason for the SYSREG_ prefix was to make implementation of the
query interface easier; I'll see if we can implement it differently. (We
might want to think about how we handle it differently anyway.)

>
> Also could we stick with lowercase, rather than uppercase. I
> appreciate the spec uses uppercase, but that doesn't concern
> itself with end user usage. If we just plain transform everything
> to lowercase, there's still a clear mapping to the spec that
> people will understand [1].

Did you forget to include [1]? :)

I agree that a lowercase conversion wouldn't make things too hard to
find in the docuementation.

>
> This example uses '-cpu host', but does this also work
> with '-cpu max'  ?
>
> Conceptually '-cpu max' is supposed to be functionally identical
> to '-cpu host' when KVM is enabled. Obviously you'd ned to
> exclude it from '-cpu max' with TCG or other non-KVM accels.

For KVM, this works with -cpu max as well, as it falls through to -cpu
host implicitly. aarch64_host_initfn() is basically split into KVM and
HVF parts, so HVF will already do the right thing (i.e. not support it),
as will tcg (which uses a separate init function.)

>
>
>> +/*
>> + * decode_idreg_writemap: Generate props for writable fields
>> + *
>> + * @obj: CPU object
>> + * @index: index of the sysreg
>> + * @map: writable map for the sysreg
>> + * @reg: description of the sysreg
>> + */
>> +static int
>> +decode_idreg_writemap(Object *obj, int index, uint64_t map, ARM64SysReg *reg)
>> +{
>> +    int i = ctz64(map);
>> +    int nb_sysreg_props = 0;
>> +
>> +    while (map) {
>> +
>> +        ARM64SysRegField *field = get_field(i, reg);
>> +        int lower, upper;
>> +        uint64_t mask;
>> +        char *prop_name;
>> +
>> +        if (!field) {
>> +            /* the field cannot be matched to any know id named field */
>> +            warn_report("%s bit %d of %s is writable but cannot be matched",
>> +                        __func__, i, reg->name);
>> +            warn_report("%s is cpu-sysreg-properties.c up to date?", __func__);
>
> What scenario triggers this warning ? Is this in relation to QEMU
> auto-detecting host CPU features, as opposed to user -cpu input ?

The kernel making something writable, but we haven't updated
cpu-sysreg-properties.c via the script. As I'd expect regs/fields to be
added to sysreg much earlier than KVM making them writable, we'll
probably not see much of this warning in practice (only if you run a
really old QEMU version with a cutting-edge kernel.) This has mostly
triggered for me when I had messed up something while writing the code
:)

This is not user-input triggered, so maybe we should log it differently,
as the user can't really fix this themself?



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model
  2025-05-14 18:22       ` Daniel P. Berrangé
@ 2025-05-16 14:51         ` Cornelia Huck
  2025-05-16 14:57           ` Daniel P. Berrangé
  0 siblings, 1 reply; 58+ messages in thread
From: Cornelia Huck @ 2025-05-16 14:51 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, abologna, jdenemar,
	agraf, shahuang, mark.rutland, philmd, pbonzini

On Wed, May 14 2025, Daniel P. Berrangé <berrange@redhat.com> wrote:

> On Wed, May 14, 2025 at 05:36:58PM +0200, Cornelia Huck wrote:
>> On Tue, May 13 2025, Daniel P. Berrangé <berrange@redhat.com> wrote:
>> 
>> > On Mon, Apr 14, 2025 at 06:38:47PM +0200, Cornelia Huck wrote:
>> >> From: Eric Auger <eric.auger@redhat.com>
>> >> 
>> >> If the interface for writable ID registers is available, expose uint64
>> >> SYSREG properties for writable ID reg fields exposed by the host
>> >> kernel. Properties are named  SYSREG_<REG>_<FIELD> with REG and FIELD
>> >> being those used  in linux arch/arm64/tools/sysreg. This done by
>> >> matching the writable fields retrieved from the host kernel against the
>> >> generated description of sysregs.
>> >> 
>> >> An example of invocation is:
>> >> -cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0
>> >> which sets DP field of ID_AA64ISAR0_EL1 to 0.
>> >
>> > For the value you are illustrating 0x0 - is this implying that
>> > all the flags take an arbitrary integer hex value ?
>> >
>> > This would be different from x86, where CPU feature flags are
>> > a boolean on/off state.
>> 
>> Most of the fields are 4 bits, the allowed values vary (there are also
>> some fields that are single bits, or wider.) The FEAT_xxx values (which
>> can be expressed via ID register fields, or a combination thereof) are
>> mostly boolean, but there are also some of them that can take values.
>> 
>> We could cook up pseudo-features that are always on/off, but I don't
>> like that approach: they would be QEMU only, whereas the ID register
>> fields and FEAT_xxx features are all defined in the Arm documentation.
>
> Fortunately from a libvirt POV we can likely expand our config
> to cope with hex values for arm features without too much
> trouble.
>
>> 
>> An additional difference from x86 would be that FEAT_xxx featues are not
>> neccessarily configurable (only if the host kernel supports changing the
>> ID register field(s) backing the feature.)
>
> Is the kernel able to tell us which ones are configurable and which
> are not ? If so, it'd be helpful to expose this info in QAPI some
> place.

The kernel can tell us which ID register fields are writable (we won't
generate properties if we don't.) For FEAT_xxx, this depends on how
we'll end up handling them (maybe we should only expose them if all ID
register bits backing them are actually writable.)

What worries me a bit is that QEMU exposing a certain set of FEAT_xxx
values could be interpreted as "those features are present, any other
features aren't", while it is only the list of configurable features.

Another issue: If libvirt is trying to baseline two cpus, it might end
up creating a model that looks sane on paper, but migrations will fail
because there are differences in non-writable bits. It would be much
better if libvirt could detect beforehand that there was no common
determinator. Not yet sure how to handle this.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model
  2025-05-16 14:51         ` Cornelia Huck
@ 2025-05-16 14:57           ` Daniel P. Berrangé
  2025-05-16 15:13             ` Cornelia Huck
  0 siblings, 1 reply; 58+ messages in thread
From: Daniel P. Berrangé @ 2025-05-16 14:57 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, abologna, jdenemar,
	agraf, shahuang, mark.rutland, philmd, pbonzini

On Fri, May 16, 2025 at 04:51:34PM +0200, Cornelia Huck wrote:
> On Wed, May 14 2025, Daniel P. Berrangé <berrange@redhat.com> wrote:
> 
> > On Wed, May 14, 2025 at 05:36:58PM +0200, Cornelia Huck wrote:
> >> On Tue, May 13 2025, Daniel P. Berrangé <berrange@redhat.com> wrote:
> >> 
> >> > On Mon, Apr 14, 2025 at 06:38:47PM +0200, Cornelia Huck wrote:
> >> >> From: Eric Auger <eric.auger@redhat.com>
> >> >> 
> >> >> If the interface for writable ID registers is available, expose uint64
> >> >> SYSREG properties for writable ID reg fields exposed by the host
> >> >> kernel. Properties are named  SYSREG_<REG>_<FIELD> with REG and FIELD
> >> >> being those used  in linux arch/arm64/tools/sysreg. This done by
> >> >> matching the writable fields retrieved from the host kernel against the
> >> >> generated description of sysregs.
> >> >> 
> >> >> An example of invocation is:
> >> >> -cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0
> >> >> which sets DP field of ID_AA64ISAR0_EL1 to 0.
> >> >
> >> > For the value you are illustrating 0x0 - is this implying that
> >> > all the flags take an arbitrary integer hex value ?
> >> >
> >> > This would be different from x86, where CPU feature flags are
> >> > a boolean on/off state.
> >> 
> >> Most of the fields are 4 bits, the allowed values vary (there are also
> >> some fields that are single bits, or wider.) The FEAT_xxx values (which
> >> can be expressed via ID register fields, or a combination thereof) are
> >> mostly boolean, but there are also some of them that can take values.
> >> 
> >> We could cook up pseudo-features that are always on/off, but I don't
> >> like that approach: they would be QEMU only, whereas the ID register
> >> fields and FEAT_xxx features are all defined in the Arm documentation.
> >
> > Fortunately from a libvirt POV we can likely expand our config
> > to cope with hex values for arm features without too much
> > trouble.
> >
> >> 
> >> An additional difference from x86 would be that FEAT_xxx featues are not
> >> neccessarily configurable (only if the host kernel supports changing the
> >> ID register field(s) backing the feature.)
> >
> > Is the kernel able to tell us which ones are configurable and which
> > are not ? If so, it'd be helpful to expose this info in QAPI some
> > place.
> 
> The kernel can tell us which ID register fields are writable (we won't
> generate properties if we don't.) For FEAT_xxx, this depends on how
> we'll end up handling them (maybe we should only expose them if all ID
> register bits backing them are actually writable.)
> 
> What worries me a bit is that QEMU exposing a certain set of FEAT_xxx
> values could be interpreted as "those features are present, any other
> features aren't", while it is only the list of configurable features.
> 
> Another issue: If libvirt is trying to baseline two cpus, it might end
> up creating a model that looks sane on paper, but migrations will fail
> because there are differences in non-writable bits. It would be much
> better if libvirt could detect beforehand that there was no common
> determinator. Not yet sure how to handle this.

For "host" model that's probably not the end of the world. Apps have
already given up strong guarantee of migration compat by using 'host'
CPU and so in that context libvirt's feature comparison can assume
the underlying silicon is a match and just compare features.


In that sense the ability to list features and baseline two cpus
lets you guarantee that whatever CPU you boot the guest on, will
have at least those requested features. That's useful, even if it
does not give you a strong migration compat guarantee.

Doing better would require info on non-writable features, and
possibly even that might not be sufficient to guarantee compat

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model
  2025-05-16 14:57           ` Daniel P. Berrangé
@ 2025-05-16 15:13             ` Cornelia Huck
  0 siblings, 0 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-05-16 15:13 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, abologna, jdenemar,
	agraf, shahuang, mark.rutland, philmd, pbonzini

On Fri, May 16 2025, Daniel P. Berrangé <berrange@redhat.com> wrote:

> On Fri, May 16, 2025 at 04:51:34PM +0200, Cornelia Huck wrote:
>> On Wed, May 14 2025, Daniel P. Berrangé <berrange@redhat.com> wrote:
>> 
>> > On Wed, May 14, 2025 at 05:36:58PM +0200, Cornelia Huck wrote:
>> >> On Tue, May 13 2025, Daniel P. Berrangé <berrange@redhat.com> wrote:
>> >> 
>> >> > On Mon, Apr 14, 2025 at 06:38:47PM +0200, Cornelia Huck wrote:
>> >> >> From: Eric Auger <eric.auger@redhat.com>
>> >> >> 
>> >> >> If the interface for writable ID registers is available, expose uint64
>> >> >> SYSREG properties for writable ID reg fields exposed by the host
>> >> >> kernel. Properties are named  SYSREG_<REG>_<FIELD> with REG and FIELD
>> >> >> being those used  in linux arch/arm64/tools/sysreg. This done by
>> >> >> matching the writable fields retrieved from the host kernel against the
>> >> >> generated description of sysregs.
>> >> >> 
>> >> >> An example of invocation is:
>> >> >> -cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0
>> >> >> which sets DP field of ID_AA64ISAR0_EL1 to 0.
>> >> >
>> >> > For the value you are illustrating 0x0 - is this implying that
>> >> > all the flags take an arbitrary integer hex value ?
>> >> >
>> >> > This would be different from x86, where CPU feature flags are
>> >> > a boolean on/off state.
>> >> 
>> >> Most of the fields are 4 bits, the allowed values vary (there are also
>> >> some fields that are single bits, or wider.) The FEAT_xxx values (which
>> >> can be expressed via ID register fields, or a combination thereof) are
>> >> mostly boolean, but there are also some of them that can take values.
>> >> 
>> >> We could cook up pseudo-features that are always on/off, but I don't
>> >> like that approach: they would be QEMU only, whereas the ID register
>> >> fields and FEAT_xxx features are all defined in the Arm documentation.
>> >
>> > Fortunately from a libvirt POV we can likely expand our config
>> > to cope with hex values for arm features without too much
>> > trouble.
>> >
>> >> 
>> >> An additional difference from x86 would be that FEAT_xxx featues are not
>> >> neccessarily configurable (only if the host kernel supports changing the
>> >> ID register field(s) backing the feature.)
>> >
>> > Is the kernel able to tell us which ones are configurable and which
>> > are not ? If so, it'd be helpful to expose this info in QAPI some
>> > place.
>> 
>> The kernel can tell us which ID register fields are writable (we won't
>> generate properties if we don't.) For FEAT_xxx, this depends on how
>> we'll end up handling them (maybe we should only expose them if all ID
>> register bits backing them are actually writable.)
>> 
>> What worries me a bit is that QEMU exposing a certain set of FEAT_xxx
>> values could be interpreted as "those features are present, any other
>> features aren't", while it is only the list of configurable features.
>> 
>> Another issue: If libvirt is trying to baseline two cpus, it might end
>> up creating a model that looks sane on paper, but migrations will fail
>> because there are differences in non-writable bits. It would be much
>> better if libvirt could detect beforehand that there was no common
>> determinator. Not yet sure how to handle this.
>
> For "host" model that's probably not the end of the world. Apps have
> already given up strong guarantee of migration compat by using 'host'
> CPU and so in that context libvirt's feature comparison can assume
> the underlying silicon is a match and just compare features.
>
>
> In that sense the ability to list features and baseline two cpus
> lets you guarantee that whatever CPU you boot the guest on, will
> have at least those requested features. That's useful, even if it
> does not give you a strong migration compat guarantee.
>
> Doing better would require info on non-writable features, and
> possibly even that might not be sufficient to guarantee compat

We'd probably want to use named models rather than 'host' for better
generic handling, but that's a whole different can of worms that I'd
prefer to keep closed right now.

OTOH, 'host' with some features tweaked is already useful if you want to
migrate across machines in a heterogeneous environment with known
players (i.e. you know that the various machines only differ in features
that you can actually configure.)



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 02/10] arm/cpu: Add sysreg properties generation
  2025-04-15  7:09   ` Philippe Mathieu-Daudé
  2025-04-15  7:20     ` Philippe Mathieu-Daudé
@ 2025-05-19 14:49     ` Cornelia Huck
  1 sibling, 0 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-05-19 14:49 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, eric.auger.pro, eric.auger,
	qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson,
	alex.bennee, maz, oliver.upton, sebott, shameerali.kolothum.thodi,
	armbru, berrange, abologna, jdenemar
  Cc: agraf, shahuang, mark.rutland, pbonzini

On Tue, Apr 15 2025, Philippe Mathieu-Daudé <philmd@linaro.org> wrote:

> On 14/4/25 18:38, Cornelia Huck wrote:
>> From: Eric Auger <eric.auger@redhat.com>
>> 
>> Introduce a script that automates the generation of system register
>> properties definitions from a given linux source tree
>> arch/arm64/tools/sysreg.
>> 
>> Invocation of
>> ./update-aarch64-sysreg-code.sh $PATH_TO_LINUX_SOURCE_TREE
>> in scripts directory additionally generates
>> target/arm/cpu-sysreg-properties.c containing definitions for
>> feature ID registers.
>> 
>> update-aarch64-sysreg-code.sh additionally calls
>> gen-cpu-sysreg-properties.awk which is inherited from kernel
>> arch/arm64/tools/gen-sysreg.awk. All credits to Mark Rutland
>> the original author of this script.
>> 
>> [CH: split off from original patch adding both sysreg definitions
>>   and properties]
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>> ---
>>   scripts/gen-cpu-sysreg-properties.awk | 325 ++++++++++++++++++++++++++
>>   scripts/update-aarch64-sysreg-code.sh |   5 +-
>>   2 files changed, 329 insertions(+), 1 deletion(-)
>>   create mode 100755 scripts/gen-cpu-sysreg-properties.awk
>> 
>> diff --git a/scripts/gen-cpu-sysreg-properties.awk b/scripts/gen-cpu-sysreg-properties.awk
>> new file mode 100755
>> index 000000000000..76c37938b168
>> --- /dev/null
>> +++ b/scripts/gen-cpu-sysreg-properties.awk
>> @@ -0,0 +1,325 @@
>> +#!/bin/awk -f
>> +# SPDX-License-Identifier: GPL-2.0
>> +# gen-cpu-sysreg-properties.awk: arm64 sysreg header generator
>> +#
>> +# Usage: awk -f gen-cpu-sysreg-properties.awk $LINUX_PATH/arch/arm64/tools/sysreg
>
>
>> +BEGIN {
>
>          print "/* AUTOMATICALLY GENERATED, DO NOT MODIFY */\n"

Makes sense.

>
> Should we keep copyright?

GPL-2.0-or-later, I guess?

>
>> +	print "#include \"cpu-custom.h\""
>> +	print ""
>> +	print "ARM64SysReg arm64_id_regs[NUM_ID_IDX];"
>> +	print ""
>> +	print "void initialize_cpu_sysreg_properties(void)"
>> +	print "{"
>> +        print "    memset(arm64_id_regs, 0, sizeof(ARM64SysReg) * NUM_ID_IDX);"
>> +        print ""
>> +
>> +	__current_block_depth = 0
>> +	__current_block[__current_block_depth] = "Root"
>> +}



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 06/10] arm/kvm: Allow reading all the writable ID registers
  2025-05-13 14:31   ` Eric Auger
  2025-05-16 14:17     ` Cornelia Huck
@ 2025-05-20 14:05     ` Cornelia Huck
  1 sibling, 0 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-05-20 14:05 UTC (permalink / raw)
  To: eric.auger, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
	sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
	jdenemar
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini

On Tue, May 13 2025, Eric Auger <eric.auger@redhat.com> wrote:

> On 4/14/25 6:38 PM, Cornelia Huck wrote:
>> From: Eric Auger <eric.auger@redhat.com>
>>
>> At the moment kvm_arm_get_host_cpu_features() reads a subset of the
>> ID regs. As we want to introduce properties for all writable ID reg
>> fields, we want more genericity and read more default host register
>> values.
>>
>> Introduce a new get_host_cpu_idregs() helper and add a new exhaustive
>> boolean parameter to kvm_arm_get_host_cpu_features() and
>> kvm_arm_set_cpu_features_from_host() to select the right behavior.
>> The host cpu model will keep the legacy behavior unless the writable
>> id register interface is available.
>>
>> A writable_map IdRegMap is introduced in the CPU object. A subsequent
>> patch will populate it.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>> ---
>>  target/arm/cpu-sysregs.h |  2 ++
>>  target/arm/cpu.h         |  3 ++
>>  target/arm/cpu64.c       |  2 +-
>>  target/arm/kvm.c         | 78 ++++++++++++++++++++++++++++++++++++++--
>>  target/arm/kvm_arm.h     |  9 +++--
>>  target/arm/trace-events  |  1 +
>>  6 files changed, 89 insertions(+), 6 deletions(-)
>>

(...)

>> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
>> index 775a8aebc5d3..8717c5e7695b 100644
>> --- a/target/arm/cpu.h
>> +++ b/target/arm/cpu.h
>> @@ -1088,6 +1088,9 @@ struct ArchCPU {
>>       */
>>      ARMIdRegsState writable_id_regs;
>>  
>> +    /* ID reg writable bitmask (KVM only) */
>> +    IdRegMap *writable_map;
> as it is KVM only we may put it in ifdef CONFIG_KVM block above

Forgot to reply here; the CONFIG_KVM block is gone with a725f3710231
("target/arm/cpu: always define kvm related registers")



^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v3 06/10] arm/kvm: Allow reading all the writable ID registers
  2025-04-14 16:38 ` [PATCH v3 06/10] arm/kvm: Allow reading all the writable ID registers Cornelia Huck
  2025-05-13 14:31   ` Eric Auger
@ 2025-05-23  8:27   ` Shameerali Kolothum Thodi via
  2025-05-26 12:37     ` Cornelia Huck
  1 sibling, 1 reply; 58+ messages in thread
From: Shameerali Kolothum Thodi via @ 2025-05-23  8:27 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro@gmail.com, eric.auger@redhat.com,
	qemu-devel@nongnu.org, qemu-arm@nongnu.org,
	kvmarm@lists.linux.dev, peter.maydell@linaro.org,
	richard.henderson@linaro.org, alex.bennee@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, sebott@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com
  Cc: agraf@csgraf.de, shahuang@redhat.com, mark.rutland@arm.com,
	philmd@linaro.org, pbonzini@redhat.com



> -----Original Message-----
> From: Cornelia Huck <cohuck@redhat.com>
> Sent: Monday, April 14, 2025 5:39 PM
> To: eric.auger.pro@gmail.com; eric.auger@redhat.com; qemu-
> devel@nongnu.org; qemu-arm@nongnu.org; kvmarm@lists.linux.dev;
> peter.maydell@linaro.org; richard.henderson@linaro.org;
> alex.bennee@linaro.org; maz@kernel.org; oliver.upton@linux.dev;
> sebott@redhat.com; Shameerali Kolothum Thodi
> <shameerali.kolothum.thodi@huawei.com>; armbru@redhat.com;
> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
> Cc: agraf@csgraf.de; shahuang@redhat.com; mark.rutland@arm.com;
> philmd@linaro.org; pbonzini@redhat.com; Cornelia Huck
> <cohuck@redhat.com>
> Subject: [PATCH v3 06/10] arm/kvm: Allow reading all the writable ID
> registers
> 
> From: Eric Auger <eric.auger@redhat.com>
> 
> At the moment kvm_arm_get_host_cpu_features() reads a subset of the
> ID regs. As we want to introduce properties for all writable ID reg
> fields, we want more genericity and read more default host register
> values.
> 
> Introduce a new get_host_cpu_idregs() helper and add a new exhaustive
> boolean parameter to kvm_arm_get_host_cpu_features() and
> kvm_arm_set_cpu_features_from_host() to select the right behavior.
> The host cpu model will keep the legacy behavior unless the writable
> id register interface is available.
> 
> A writable_map IdRegMap is introduced in the CPU object. A subsequent
> patch will populate it.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
>  target/arm/cpu-sysregs.h |  2 ++
>  target/arm/cpu.h         |  3 ++
>  target/arm/cpu64.c       |  2 +-
>  target/arm/kvm.c         | 78 ++++++++++++++++++++++++++++++++++++++--
>  target/arm/kvm_arm.h     |  9 +++--
>  target/arm/trace-events  |  1 +
>  6 files changed, 89 insertions(+), 6 deletions(-)
> 
> diff --git a/target/arm/cpu-sysregs.h b/target/arm/cpu-sysregs.h
> index e89a1105904c..367fab51f19e 100644
> --- a/target/arm/cpu-sysregs.h
> +++ b/target/arm/cpu-sysregs.h
> @@ -41,6 +41,8 @@ int get_sysreg_idx(ARMSysRegs sysreg);
> 
>  #ifdef CONFIG_KVM
>  uint64_t idregs_sysreg_to_kvm_reg(ARMSysRegs sysreg);
> +int kvm_idx_to_idregs_idx(int kidx);
> +int idregs_idx_to_kvm_idx(ARMIDRegisterIdx idx);
>  #endif
> 
>  #endif /* ARM_CPU_SYSREGS_H */
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 775a8aebc5d3..8717c5e7695b 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -1088,6 +1088,9 @@ struct ArchCPU {
>       */
>      ARMIdRegsState writable_id_regs;
> 
> +    /* ID reg writable bitmask (KVM only) */
> +    IdRegMap *writable_map;
> +
>      /* QOM property to indicate we should use the back-compat CNTFRQ
> default */
>      bool backcompat_cntfrq;
> 
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index 839442745ea4..60a709502697 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -757,7 +757,7 @@ static void aarch64_host_initfn(Object *obj)
>  {
>  #if defined(CONFIG_KVM)
>      ARMCPU *cpu = ARM_CPU(obj);
> -    kvm_arm_set_cpu_features_from_host(cpu);
> +    kvm_arm_set_cpu_features_from_host(cpu, false);
>      if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
>          aarch64_add_sve_properties(obj);
>          aarch64_add_pauth_properties(obj);
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index 6e3cd06e9bc5..b07d5f16db50 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -41,6 +41,7 @@
>  #include "hw/acpi/ghes.h"
>  #include "target/arm/gtimer.h"
>  #include "migration/blocker.h"
> +#include "cpu-custom.h"
> 
>  const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
>      KVM_CAP_INFO(DEVICE_CTRL),
> @@ -270,7 +271,73 @@ static int get_host_cpu_reg(int fd,
> ARMHostCPUFeatures *ahcf, ARMIDRegisterIdx i
>      return ret;
>  }
> 
> -static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
> +int kvm_idx_to_idregs_idx(int kidx)
> +{
> +    int op1, crm, op2;
> +    ARMSysRegs sysreg;
> +
> +    op1 = kidx / 64;
> +    if (op1 == 2) {
> +        op1 = 3;
> +    }
> +    crm = (kidx % 64) / 8;
> +    op2 = kidx % 8;
> +    sysreg = ENCODE_ID_REG(3, op1, 0, crm, op2);
> +    return get_sysreg_idx(sysreg);
> +}
> +
> +int idregs_idx_to_kvm_idx(ARMIDRegisterIdx idx)
> +{
> +    ARMSysRegs sysreg = id_register_sysreg[idx];
> +
> +    return KVM_ARM_FEATURE_ID_RANGE_IDX((sysreg &
> CP_REG_ARM64_SYSREG_OP0_MASK) >>
> CP_REG_ARM64_SYSREG_OP0_SHIFT,
> +                                        (sysreg & CP_REG_ARM64_SYSREG_OP1_MASK) >>
> CP_REG_ARM64_SYSREG_OP1_SHIFT,
> +                                        (sysreg & CP_REG_ARM64_SYSREG_CRN_MASK) >>
> CP_REG_ARM64_SYSREG_CRN_SHIFT,
> +                                        (sysreg & CP_REG_ARM64_SYSREG_CRM_MASK) >>
> CP_REG_ARM64_SYSREG_CRM_SHIFT,
> +                                        (sysreg & CP_REG_ARM64_SYSREG_OP2_MASK) >>
> CP_REG_ARM64_SYSREG_OP2_SHIFT);
> +}
> +
> +
> +/*
> + * get_host_cpu_idregs: Read all the writable ID reg host values
> + *
> + * Need to be called once the writable mask has been populated
> + * Note we may want to read all the known id regs but some of them are
> not
> + * writable and return an error, hence the choice of reading only those
> which
> + * are writable. Those are also readable!
> + */
> +static int get_host_cpu_idregs(ARMCPU *cpu, int fd, ARMHostCPUFeatures
> *ahcf)
> +{
> +    int err = 0;
> +    int i;
> +
> +    for (i = 0; i < NUM_ID_IDX; i++) {
> +        ARM64SysReg *sysregdesc = &arm64_id_regs[i];
> +        ARMSysRegs sysreg = sysregdesc->sysreg;
> +        uint64_t writable_mask = cpu->writable_map-
> >regs[idregs_idx_to_kvm_idx(i)];
> +        uint64_t *reg;
> +        int ret;
> +
> +        if (!writable_mask) {
> +            continue;
> +        }
> +
> +        reg = &ahcf->isar.idregs[i];
> +        ret = read_sys_reg64(fd, reg, idregs_sysreg_to_kvm_reg(sysreg));

I think we can use get_host_cpu_reg() here.

> +        trace_get_host_cpu_idregs(sysregdesc->name, *reg);
> +        if (ret) {
> +            error_report("%s error reading value of host %s register (%m)",
> +                         __func__, sysregdesc->name);
> +
> +            err = ret;
> +        }
> +    }
> +    return err;
> +}
> +
> +static bool
> +kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures
> *ahcf,
> +                              bool exhaustive)
>  {
>      /* Identify the feature bits corresponding to the host CPU, and
>       * fill out the ARMHostCPUClass fields accordingly. To do this
> @@ -398,6 +465,11 @@ static bool
> kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>          err |= get_host_cpu_reg(fd, ahcf, ID_DFR1_EL1_IDX);
>          err |= get_host_cpu_reg(fd, ahcf, ID_MMFR5_EL1_IDX);
> 
> +        /* Make sure writable ID reg values are read */
> +        if (exhaustive) {
> +            err |= get_host_cpu_idregs(cpu, fd, ahcf);
> +        }


Also if we do this a bit above can we avoid reading the ID registers twice
if "exhaustive=true" ?

Thanks,
Shameer

> +
>          /*
>           * DBGDIDR is a bit complicated because the kernel doesn't
>           * provide an accessor for it in 64-bit mode, which is what this
> @@ -467,13 +539,13 @@ static bool
> kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>      return true;
>  }
> 
> -void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
> +void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, bool
> exhaustive)
>  {
>      CPUARMState *env = &cpu->env;
> 
>      if (!arm_host_cpu_features.dtb_compatible) {
>          if (!kvm_enabled() ||
> -            !kvm_arm_get_host_cpu_features(&arm_host_cpu_features)) {
> +            !kvm_arm_get_host_cpu_features(cpu, &arm_host_cpu_features,
> exhaustive)) {
>              /* We can't report this error yet, so flag that we need to
>               * in arm_cpu_realizefn().
>               */
> diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
> index 8d1f20ca8d89..90ba4f7d8987 100644
> --- a/target/arm/kvm_arm.h
> +++ b/target/arm/kvm_arm.h
> @@ -141,8 +141,12 @@ uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu);
>   *
>   * Set up the ARMCPU struct fields up to match the information probed
>   * from the host CPU.
> + *
> + * @cpu: cpu object
> + * @exhaustive: if true, all the feature ID regs are queried instead of
> + *              a subset
>   */
> -void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
> +void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, bool
> exhaustive);
> 
>  /**
>   * kvm_arm_add_vcpu_properties:
> @@ -257,7 +261,8 @@ static inline int
> kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap)
>  /*
>   * These functions should never actually be called without KVM support.
>   */
> -static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
> +static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu,
> +                                                      bool exhaustive)
>  {
>      g_assert_not_reached();
>  }
> diff --git a/target/arm/trace-events b/target/arm/trace-events
> index 4438dce7becc..17e52c0705f2 100644
> --- a/target/arm/trace-events
> +++ b/target/arm/trace-events
> @@ -13,3 +13,4 @@ arm_gt_update_irq(int timer, int irqstate)
> "gt_update_irq: timer %d irqstate %d"
> 
>  # kvm.c
>  kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova =
> 0x%"PRIx64" is translated into 0x%"PRIx64
> +get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host
> value for %s is 0x%"PRIx64
> --
> 2.49.0
> 



^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model
  2025-04-14 16:38 [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
                   ` (10 preceding siblings ...)
  2025-05-13 15:29 ` [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
@ 2025-05-23 13:23 ` Shameerali Kolothum Thodi via
  2025-05-26 12:44   ` Cornelia Huck
  11 siblings, 1 reply; 58+ messages in thread
From: Shameerali Kolothum Thodi via @ 2025-05-23 13:23 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro@gmail.com, eric.auger@redhat.com,
	qemu-devel@nongnu.org, qemu-arm@nongnu.org,
	kvmarm@lists.linux.dev, peter.maydell@linaro.org,
	richard.henderson@linaro.org, alex.bennee@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, sebott@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com
  Cc: agraf@csgraf.de, shahuang@redhat.com, mark.rutland@arm.com,
	philmd@linaro.org, pbonzini@redhat.com

Hi,

> -----Original Message-----
> From: Cornelia Huck <cohuck@redhat.com>
> Sent: Monday, April 14, 2025 5:39 PM
> To: eric.auger.pro@gmail.com; eric.auger@redhat.com; qemu-
> devel@nongnu.org; qemu-arm@nongnu.org; kvmarm@lists.linux.dev;
> peter.maydell@linaro.org; richard.henderson@linaro.org;
> alex.bennee@linaro.org; maz@kernel.org; oliver.upton@linux.dev;
> sebott@redhat.com; Shameerali Kolothum Thodi
> <shameerali.kolothum.thodi@huawei.com>; armbru@redhat.com;
> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
> Cc: agraf@csgraf.de; shahuang@redhat.com; mark.rutland@arm.com;
> philmd@linaro.org; pbonzini@redhat.com; Cornelia Huck
> <cohuck@redhat.com>
> Subject: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM
> host model

[..]

)
> 
> Code also available at
> https://gitlab.com/cohuck/qemu/-/tree/arm-cpu-model-
> rfcv3?ref_type=heads

I had a spin with the above branch, but Qemu boot fails,

ERROR:../target/arm/cpu64.c:57:get_sysreg_idx: code should not be reached
Bail out! ERROR:../target/arm/cpu64.c:57:get_sysreg_idx: code should not be reached

From a quick debug, it looks like the below path results in an invalid ID idx.

kvm_arm_expose_idreg_properties()
 kvm_idx_to_idregs_idx(0)
  get_sysreg_idx(0xc000)  --> id_register seems to start at 0xc008

Haven't debugged further.

I am running against a 6.15-rc1 kernel after updating the Qemu branch by,
./update-aarch64-sysreg-code.sh  path_to_6.15-rc1

Not sure I am  missing anything. Please check and let me know.

Thanks,
Shameer

 


^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v3 06/10] arm/kvm: Allow reading all the writable ID registers
  2025-05-23  8:27   ` Shameerali Kolothum Thodi via
@ 2025-05-26 12:37     ` Cornelia Huck
  0 siblings, 0 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-05-26 12:37 UTC (permalink / raw)
  To: Shameerali Kolothum Thodi, eric.auger.pro@gmail.com,
	eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org,
	kvmarm@lists.linux.dev, peter.maydell@linaro.org,
	richard.henderson@linaro.org, alex.bennee@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, sebott@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com
  Cc: agraf@csgraf.de, shahuang@redhat.com, mark.rutland@arm.com,
	philmd@linaro.org, pbonzini@redhat.com

On Fri, May 23 2025, Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com> wrote:

>> -----Original Message-----
>> From: Cornelia Huck <cohuck@redhat.com>
>> Sent: Monday, April 14, 2025 5:39 PM
>> To: eric.auger.pro@gmail.com; eric.auger@redhat.com; qemu-
>> devel@nongnu.org; qemu-arm@nongnu.org; kvmarm@lists.linux.dev;
>> peter.maydell@linaro.org; richard.henderson@linaro.org;
>> alex.bennee@linaro.org; maz@kernel.org; oliver.upton@linux.dev;
>> sebott@redhat.com; Shameerali Kolothum Thodi
>> <shameerali.kolothum.thodi@huawei.com>; armbru@redhat.com;
>> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
>> Cc: agraf@csgraf.de; shahuang@redhat.com; mark.rutland@arm.com;
>> philmd@linaro.org; pbonzini@redhat.com; Cornelia Huck
>> <cohuck@redhat.com>
>> Subject: [PATCH v3 06/10] arm/kvm: Allow reading all the writable ID
>> registers
>> 
>> From: Eric Auger <eric.auger@redhat.com>
>> 
>> At the moment kvm_arm_get_host_cpu_features() reads a subset of the
>> ID regs. As we want to introduce properties for all writable ID reg
>> fields, we want more genericity and read more default host register
>> values.
>> 
>> Introduce a new get_host_cpu_idregs() helper and add a new exhaustive
>> boolean parameter to kvm_arm_get_host_cpu_features() and
>> kvm_arm_set_cpu_features_from_host() to select the right behavior.
>> The host cpu model will keep the legacy behavior unless the writable
>> id register interface is available.
>> 
>> A writable_map IdRegMap is introduced in the CPU object. A subsequent
>> patch will populate it.
>> 
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>> ---
>>  target/arm/cpu-sysregs.h |  2 ++
>>  target/arm/cpu.h         |  3 ++
>>  target/arm/cpu64.c       |  2 +-
>>  target/arm/kvm.c         | 78 ++++++++++++++++++++++++++++++++++++++--
>>  target/arm/kvm_arm.h     |  9 +++--
>>  target/arm/trace-events  |  1 +
>>  6 files changed, 89 insertions(+), 6 deletions(-)

(...)

>> +/*
>> + * get_host_cpu_idregs: Read all the writable ID reg host values
>> + *
>> + * Need to be called once the writable mask has been populated
>> + * Note we may want to read all the known id regs but some of them are
>> not
>> + * writable and return an error, hence the choice of reading only those
>> which
>> + * are writable. Those are also readable!
>> + */
>> +static int get_host_cpu_idregs(ARMCPU *cpu, int fd, ARMHostCPUFeatures
>> *ahcf)
>> +{
>> +    int err = 0;
>> +    int i;
>> +
>> +    for (i = 0; i < NUM_ID_IDX; i++) {
>> +        ARM64SysReg *sysregdesc = &arm64_id_regs[i];
>> +        ARMSysRegs sysreg = sysregdesc->sysreg;
>> +        uint64_t writable_mask = cpu->writable_map-
>> >regs[idregs_idx_to_kvm_idx(i)];
>> +        uint64_t *reg;
>> +        int ret;
>> +
>> +        if (!writable_mask) {
>> +            continue;
>> +        }
>> +
>> +        reg = &ahcf->isar.idregs[i];
>> +        ret = read_sys_reg64(fd, reg, idregs_sysreg_to_kvm_reg(sysreg));
>
> I think we can use get_host_cpu_reg() here.

We'd need to rejiggle the tracing a bit, though.

Looking at this, maybe we have too many cross-indexing variants, I'll
check and see if we can simplify that a bit.

>
>> +        trace_get_host_cpu_idregs(sysregdesc->name, *reg);
>> +        if (ret) {
>> +            error_report("%s error reading value of host %s register (%m)",
>> +                         __func__, sysregdesc->name);
>> +
>> +            err = ret;
>> +        }
>> +    }
>> +    return err;
>> +}
>> +
>> +static bool
>> +kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures
>> *ahcf,
>> +                              bool exhaustive)
>>  {
>>      /* Identify the feature bits corresponding to the host CPU, and
>>       * fill out the ARMHostCPUClass fields accordingly. To do this
>> @@ -398,6 +465,11 @@ static bool
>> kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>>          err |= get_host_cpu_reg(fd, ahcf, ID_DFR1_EL1_IDX);
>>          err |= get_host_cpu_reg(fd, ahcf, ID_MMFR5_EL1_IDX);
>> 
>> +        /* Make sure writable ID reg values are read */
>> +        if (exhaustive) {
>> +            err |= get_host_cpu_idregs(cpu, fd, ahcf);
>> +        }
>
>
> Also if we do this a bit above can we avoid reading the ID registers twice
> if "exhaustive=true" ?

It's probably not performance critical as we just do this once, but
let's try that anyway.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model
  2025-05-23 13:23 ` Shameerali Kolothum Thodi via
@ 2025-05-26 12:44   ` Cornelia Huck
  2025-05-27 10:06     ` Cornelia Huck
  0 siblings, 1 reply; 58+ messages in thread
From: Cornelia Huck @ 2025-05-26 12:44 UTC (permalink / raw)
  To: Shameerali Kolothum Thodi, eric.auger.pro@gmail.com,
	eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org,
	kvmarm@lists.linux.dev, peter.maydell@linaro.org,
	richard.henderson@linaro.org, alex.bennee@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, sebott@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com
  Cc: agraf@csgraf.de, shahuang@redhat.com, mark.rutland@arm.com,
	philmd@linaro.org, pbonzini@redhat.com

On Fri, May 23 2025, Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com> wrote:

> Hi,
>
>> -----Original Message-----
>> From: Cornelia Huck <cohuck@redhat.com>
>> Sent: Monday, April 14, 2025 5:39 PM
>> To: eric.auger.pro@gmail.com; eric.auger@redhat.com; qemu-
>> devel@nongnu.org; qemu-arm@nongnu.org; kvmarm@lists.linux.dev;
>> peter.maydell@linaro.org; richard.henderson@linaro.org;
>> alex.bennee@linaro.org; maz@kernel.org; oliver.upton@linux.dev;
>> sebott@redhat.com; Shameerali Kolothum Thodi
>> <shameerali.kolothum.thodi@huawei.com>; armbru@redhat.com;
>> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
>> Cc: agraf@csgraf.de; shahuang@redhat.com; mark.rutland@arm.com;
>> philmd@linaro.org; pbonzini@redhat.com; Cornelia Huck
>> <cohuck@redhat.com>
>> Subject: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM
>> host model
>
> [..]
>
> )
>> 
>> Code also available at
>> https://gitlab.com/cohuck/qemu/-/tree/arm-cpu-model-
>> rfcv3?ref_type=heads
>
> I had a spin with the above branch, but Qemu boot fails,
>
> ERROR:../target/arm/cpu64.c:57:get_sysreg_idx: code should not be reached
> Bail out! ERROR:../target/arm/cpu64.c:57:get_sysreg_idx: code should not be reached
>
> From a quick debug, it looks like the below path results in an invalid ID idx.
>
> kvm_arm_expose_idreg_properties()
>  kvm_idx_to_idregs_idx(0)
>   get_sysreg_idx(0xc000)  --> id_register seems to start at 0xc008
>
> Haven't debugged further.
>
> I am running against a 6.15-rc1 kernel after updating the Qemu branch by,
> ./update-aarch64-sysreg-code.sh  path_to_6.15-rc1
>
> Not sure I am  missing anything. Please check and let me know.

Thanks for trying this out; I'll try to re-create this here.
(I think I've messed up those conversion functions often enough...)



^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model
  2025-05-26 12:44   ` Cornelia Huck
@ 2025-05-27 10:06     ` Cornelia Huck
  2025-06-03 15:14       ` Cornelia Huck
  0 siblings, 1 reply; 58+ messages in thread
From: Cornelia Huck @ 2025-05-27 10:06 UTC (permalink / raw)
  To: Shameerali Kolothum Thodi, eric.auger.pro@gmail.com,
	eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org,
	kvmarm@lists.linux.dev, peter.maydell@linaro.org,
	richard.henderson@linaro.org, alex.bennee@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, sebott@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com
  Cc: agraf@csgraf.de, shahuang@redhat.com, mark.rutland@arm.com,
	philmd@linaro.org, pbonzini@redhat.com

On Mon, May 26 2025, Cornelia Huck <cohuck@redhat.com> wrote:

> On Fri, May 23 2025, Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com> wrote:
>
>> Hi,
>>
>>> -----Original Message-----
>>> From: Cornelia Huck <cohuck@redhat.com>
>>> Sent: Monday, April 14, 2025 5:39 PM
>>> To: eric.auger.pro@gmail.com; eric.auger@redhat.com; qemu-
>>> devel@nongnu.org; qemu-arm@nongnu.org; kvmarm@lists.linux.dev;
>>> peter.maydell@linaro.org; richard.henderson@linaro.org;
>>> alex.bennee@linaro.org; maz@kernel.org; oliver.upton@linux.dev;
>>> sebott@redhat.com; Shameerali Kolothum Thodi
>>> <shameerali.kolothum.thodi@huawei.com>; armbru@redhat.com;
>>> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
>>> Cc: agraf@csgraf.de; shahuang@redhat.com; mark.rutland@arm.com;
>>> philmd@linaro.org; pbonzini@redhat.com; Cornelia Huck
>>> <cohuck@redhat.com>
>>> Subject: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM
>>> host model
>>
>> [..]
>>
>> )
>>> 
>>> Code also available at
>>> https://gitlab.com/cohuck/qemu/-/tree/arm-cpu-model-
>>> rfcv3?ref_type=heads
>>
>> I had a spin with the above branch, but Qemu boot fails,
>>
>> ERROR:../target/arm/cpu64.c:57:get_sysreg_idx: code should not be reached
>> Bail out! ERROR:../target/arm/cpu64.c:57:get_sysreg_idx: code should not be reached
>>
>> From a quick debug, it looks like the below path results in an invalid ID idx.
>>
>> kvm_arm_expose_idreg_properties()
>>  kvm_idx_to_idregs_idx(0)
>>   get_sysreg_idx(0xc000)  --> id_register seems to start at 0xc008
>>
>> Haven't debugged further.
>>
>> I am running against a 6.15-rc1 kernel after updating the Qemu branch by,
>> ./update-aarch64-sysreg-code.sh  path_to_6.15-rc1
>>
>> Not sure I am  missing anything. Please check and let me know.
>
> Thanks for trying this out; I'll try to re-create this here.
> (I think I've messed up those conversion functions often enough...)

The conversion functions are not at fault here, but we're missing
registers. If we have MIDR and friends writable, they show up in the
masks returned by the kernel, but they are not present in the kernel's
sysreg file where we generate our definitions from, and
kvm_idx_to_idregs_idx() asserts instead of returning an error, which is
kind of suboptimal...

So I see two possible ways to fix this:
- add MIDR and friends to the kernel's sysreg file
- add MIDR and friends in QEMU's cpu-sysregs.h.inc file, and only append
  generated definitions there

First option means one more round trip, second options has more
potential for messing things up if we keep stuff local to QEMU.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model
  2025-05-27 10:06     ` Cornelia Huck
@ 2025-06-03 15:14       ` Cornelia Huck
  2025-06-04 10:58         ` Shameerali Kolothum Thodi via
  0 siblings, 1 reply; 58+ messages in thread
From: Cornelia Huck @ 2025-06-03 15:14 UTC (permalink / raw)
  To: Shameerali Kolothum Thodi, eric.auger.pro@gmail.com,
	eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org,
	kvmarm@lists.linux.dev, peter.maydell@linaro.org,
	richard.henderson@linaro.org, alex.bennee@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, sebott@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com
  Cc: agraf@csgraf.de, shahuang@redhat.com, mark.rutland@arm.com,
	philmd@linaro.org, pbonzini@redhat.com

On Tue, May 27 2025, Cornelia Huck <cohuck@redhat.com> wrote:

> On Mon, May 26 2025, Cornelia Huck <cohuck@redhat.com> wrote:
>
>> On Fri, May 23 2025, Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com> wrote:
>>
>>> Hi,
>>>
>>>> -----Original Message-----
>>>> From: Cornelia Huck <cohuck@redhat.com>
>>>> Sent: Monday, April 14, 2025 5:39 PM
>>>> To: eric.auger.pro@gmail.com; eric.auger@redhat.com; qemu-
>>>> devel@nongnu.org; qemu-arm@nongnu.org; kvmarm@lists.linux.dev;
>>>> peter.maydell@linaro.org; richard.henderson@linaro.org;
>>>> alex.bennee@linaro.org; maz@kernel.org; oliver.upton@linux.dev;
>>>> sebott@redhat.com; Shameerali Kolothum Thodi
>>>> <shameerali.kolothum.thodi@huawei.com>; armbru@redhat.com;
>>>> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
>>>> Cc: agraf@csgraf.de; shahuang@redhat.com; mark.rutland@arm.com;
>>>> philmd@linaro.org; pbonzini@redhat.com; Cornelia Huck
>>>> <cohuck@redhat.com>
>>>> Subject: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM
>>>> host model
>>>
>>> [..]
>>>
>>> )
>>>> 
>>>> Code also available at
>>>> https://gitlab.com/cohuck/qemu/-/tree/arm-cpu-model-
>>>> rfcv3?ref_type=heads
>>>
>>> I had a spin with the above branch, but Qemu boot fails,
>>>
>>> ERROR:../target/arm/cpu64.c:57:get_sysreg_idx: code should not be reached
>>> Bail out! ERROR:../target/arm/cpu64.c:57:get_sysreg_idx: code should not be reached
>>>
>>> From a quick debug, it looks like the below path results in an invalid ID idx.
>>>
>>> kvm_arm_expose_idreg_properties()
>>>  kvm_idx_to_idregs_idx(0)
>>>   get_sysreg_idx(0xc000)  --> id_register seems to start at 0xc008
>>>
>>> Haven't debugged further.
>>>
>>> I am running against a 6.15-rc1 kernel after updating the Qemu branch by,
>>> ./update-aarch64-sysreg-code.sh  path_to_6.15-rc1
>>>
>>> Not sure I am  missing anything. Please check and let me know.
>>
>> Thanks for trying this out; I'll try to re-create this here.
>> (I think I've messed up those conversion functions often enough...)
>
> The conversion functions are not at fault here, but we're missing
> registers. If we have MIDR and friends writable, they show up in the
> masks returned by the kernel, but they are not present in the kernel's
> sysreg file where we generate our definitions from, and
> kvm_idx_to_idregs_idx() asserts instead of returning an error, which is
> kind of suboptimal...
>
> So I see two possible ways to fix this:
> - add MIDR and friends to the kernel's sysreg file
> - add MIDR and friends in QEMU's cpu-sysregs.h.inc file, and only append
>   generated definitions there
>
> First option means one more round trip, second options has more
> potential for messing things up if we keep stuff local to QEMU.

With the patch below, things work for me with a 6.15+ kernel. It's a bit
messy, though, and raises questions (how do we want to handle those regs
across accelerators, for example, or how we can make sure that the code
is more robust when registers are added.)

My biggest question, however, is how this interacts with the framework
to provide lists of MIDR/REVIDR/AIDR for errata management. The hack
below adds properties to configure those regs, I guess we'd want to
suppress adding the props in order to avoid conflicts.

WDYT?

diff --git a/scripts/gen-cpu-sysreg-properties.awk b/scripts/gen-cpu-sysreg-properties.awk
index 6740e814f733..7afd9afd2650 100755
--- a/scripts/gen-cpu-sysreg-properties.awk
+++ b/scripts/gen-cpu-sysreg-properties.awk
@@ -109,6 +109,27 @@ END {
 	if (__current_block_depth != 0)
 		fatal("Missing terminator for " block_current() " block")
 
+	# Manually add MIDR/REVIDR/AIDR
+	print ""
+	print "    /* MIDR_EL1 */"
+	print "    ARM64SysReg *MIDR_EL1 = arm64_sysreg_get(MIDR_EL1_IDX);"
+	print "    MIDR_EL1->name = \"MIDR_EL1\";"
+	print "    arm64_sysreg_add_field(MIDR_EL1, \"Implementer\", 24, 31);"
+	print "    arm64_sysreg_add_field(MIDR_EL1, \"Variant\", 20, 23);"
+	print "    arm64_sysreg_add_field(MIDR_EL1, \"Architecture\", 16, 19);"
+	print "    arm64_sysreg_add_field(MIDR_EL1, \"PartNum\", 4, 15);"
+	print "    arm64_sysreg_add_field(MIDR_EL1, \"Revision\", 0, 3);"
+	print ""
+	print "    /* REVIDR_EL1 */"
+	print "    ARM64SysReg *REVIDR_EL1 = arm64_sysreg_get(REVIDR_EL1_IDX);"
+	print "    REVIDR_EL1->name = \"REVIDR_EL1\";"
+	print "    arm64_sysreg_add_field(REVIDR_EL1, \"IMPDEF\", 0, 63);"
+	print ""
+	print "    /* AIDR_EL1 */"
+	print "    ARM64SysReg *AIDR_EL1 = arm64_sysreg_get(AIDR_EL1_IDX);"
+	print "    AIDR_EL1->name = \"AIDR_EL1\";"
+	print "    arm64_sysreg_add_field(AIDR_EL1, \"IMPDEF\", 0, 63);"
+	print ""
 	print "}"
 }
 
diff --git a/scripts/gen-cpu-sysregs-header.awk b/scripts/gen-cpu-sysregs-header.awk
index 452e51035d52..2eb561b693dc 100755
--- a/scripts/gen-cpu-sysregs-header.awk
+++ b/scripts/gen-cpu-sysregs-header.awk
@@ -7,7 +7,10 @@
 BEGIN {
     print ""
 } END {
-    print ""
+    /* add MIDR, REVIDR, and AIDR */
+    print "DEF(MIDR_EL1, 3, 0, 0, 0, 0)"
+    print "DEF(REVIDR_EL1, 3, 0, 0, 0, 6)"
+    print "DEF(AIDR_EL1, 3, 1, 0, 0, 7)"
 }
 
 # skip blank lines and comment lines
diff --git a/target/arm/cpu-sysreg-properties.c b/target/arm/cpu-sysreg-properties.c
index 29c4c8ada115..bc1ae5e1a224 100644
--- a/target/arm/cpu-sysreg-properties.c
+++ b/target/arm/cpu-sysreg-properties.c
@@ -715,4 +715,24 @@ void initialize_cpu_sysreg_properties(void)
 
 /* For S2PIR_EL2 fields see PIRx_ELx */
 
+
+    /* MIDR_EL1 */
+    ARM64SysReg *MIDR_EL1 = arm64_sysreg_get(MIDR_EL1_IDX);
+    MIDR_EL1->name = "MIDR_EL1";
+    arm64_sysreg_add_field(MIDR_EL1, "Implementer", 24, 31);
+    arm64_sysreg_add_field(MIDR_EL1, "Variant", 20, 23);
+    arm64_sysreg_add_field(MIDR_EL1, "Architecture", 16, 19);
+    arm64_sysreg_add_field(MIDR_EL1, "PartNum", 4, 15);
+    arm64_sysreg_add_field(MIDR_EL1, "Revision", 0, 3);
+
+    /* REVIDR_EL1 */
+    ARM64SysReg *REVIDR_EL1 = arm64_sysreg_get(REVIDR_EL1_IDX);
+    REVIDR_EL1->name = "REVIDR_EL1";
+    arm64_sysreg_add_field(REVIDR_EL1, "IMPDEF", 0, 63);
+
+    /* AIDR_EL1 */
+    ARM64SysReg *AIDR_EL1 = arm64_sysreg_get(AIDR_EL1_IDX);
+    AIDR_EL1->name = "AIDR_EL1";
+    arm64_sysreg_add_field(AIDR_EL1, "IMPDEF", 0, 63);
+
 }
diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc
index 02aae133eb67..8f0927ce0422 100644
--- a/target/arm/cpu-sysregs.h.inc
+++ b/target/arm/cpu-sysregs.h.inc
@@ -49,4 +49,6 @@ DEF(SMIDR_EL1, 3, 1, 0, 0, 6)
 DEF(CSSELR_EL1, 3, 2, 0, 0, 0)
 DEF(CTR_EL0, 3, 3, 0, 0, 1)
 DEF(DCZID_EL0, 3, 3, 0, 0, 7)
-
+DEF(MIDR_EL1, 3, 0, 0, 0, 0)
+DEF(REVIDR_EL1, 3, 0, 0, 0, 6)
+DEF(AIDR_EL1, 3, 1, 0, 0, 7)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 95bb728a77f1..7454f329157c 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -54,7 +54,7 @@ int get_sysreg_idx(ARMSysRegs sysreg)
     switch (sysreg) {
 #include "cpu-sysregs.h.inc"
     }
-    g_assert_not_reached();
+    return -1;
 }
 
 #undef DEF



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* RE: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model
  2025-06-03 15:14       ` Cornelia Huck
@ 2025-06-04 10:58         ` Shameerali Kolothum Thodi via
  2025-06-04 12:35           ` Cornelia Huck
  0 siblings, 1 reply; 58+ messages in thread
From: Shameerali Kolothum Thodi via @ 2025-06-04 10:58 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro@gmail.com, eric.auger@redhat.com,
	qemu-devel@nongnu.org, qemu-arm@nongnu.org,
	kvmarm@lists.linux.dev, peter.maydell@linaro.org,
	richard.henderson@linaro.org, alex.bennee@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, sebott@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com
  Cc: agraf@csgraf.de, shahuang@redhat.com, mark.rutland@arm.com,
	philmd@linaro.org, pbonzini@redhat.com



> -----Original Message-----
> From: Cornelia Huck <cohuck@redhat.com>
> Sent: Tuesday, June 3, 2025 4:15 PM
> To: Shameerali Kolothum Thodi
> <shameerali.kolothum.thodi@huawei.com>; eric.auger.pro@gmail.com;
> eric.auger@redhat.com; qemu-devel@nongnu.org; qemu-arm@nongnu.org;
> kvmarm@lists.linux.dev; peter.maydell@linaro.org;
> richard.henderson@linaro.org; alex.bennee@linaro.org; maz@kernel.org;
> oliver.upton@linux.dev; sebott@redhat.com; armbru@redhat.com;
> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
> Cc: agraf@csgraf.de; shahuang@redhat.com; mark.rutland@arm.com;
> philmd@linaro.org; pbonzini@redhat.com
> Subject: RE: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64
> KVM host model
> 
> On Tue, May 27 2025, Cornelia Huck <cohuck@redhat.com> wrote:
> 
> > On Mon, May 26 2025, Cornelia Huck <cohuck@redhat.com> wrote:
> >
> >> On Fri, May 23 2025, Shameerali Kolothum Thodi
> <shameerali.kolothum.thodi@huawei.com> wrote:
> >>
> >>> Hi,
> >>>
> >>>> -----Original Message-----
> >>>> From: Cornelia Huck <cohuck@redhat.com>
> >>>> Sent: Monday, April 14, 2025 5:39 PM
> >>>> To: eric.auger.pro@gmail.com; eric.auger@redhat.com; qemu-
> >>>> devel@nongnu.org; qemu-arm@nongnu.org; kvmarm@lists.linux.dev;
> >>>> peter.maydell@linaro.org; richard.henderson@linaro.org;
> >>>> alex.bennee@linaro.org; maz@kernel.org; oliver.upton@linux.dev;
> >>>> sebott@redhat.com; Shameerali Kolothum Thodi
> >>>> <shameerali.kolothum.thodi@huawei.com>; armbru@redhat.com;
> >>>> berrange@redhat.com; abologna@redhat.com;
> jdenemar@redhat.com
> >>>> Cc: agraf@csgraf.de; shahuang@redhat.com; mark.rutland@arm.com;
> >>>> philmd@linaro.org; pbonzini@redhat.com; Cornelia Huck
> >>>> <cohuck@redhat.com>
> >>>> Subject: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64
> >>>> KVM host model
> >>>
> >>> [..]
> >>>
> >>> )
> >>>>
> >>>> Code also available at
> >>>> https://gitlab.com/cohuck/qemu/-/tree/arm-cpu-model-
> >>>> rfcv3?ref_type=heads
> >>>
> >>> I had a spin with the above branch, but Qemu boot fails,
> >>>
> >>> ERROR:../target/arm/cpu64.c:57:get_sysreg_idx: code should not be
> >>> reached Bail out! ERROR:../target/arm/cpu64.c:57:get_sysreg_idx:
> >>> code should not be reached
> >>>
> >>> From a quick debug, it looks like the below path results in an invalid ID
> idx.
> >>>
> >>> kvm_arm_expose_idreg_properties()
> >>>  kvm_idx_to_idregs_idx(0)
> >>>   get_sysreg_idx(0xc000)  --> id_register seems to start at 0xc008
> >>>
> >>> Haven't debugged further.
> >>>
> >>> I am running against a 6.15-rc1 kernel after updating the Qemu
> >>> branch by, ./update-aarch64-sysreg-code.sh  path_to_6.15-rc1
> >>>
> >>> Not sure I am  missing anything. Please check and let me know.
> >>
> >> Thanks for trying this out; I'll try to re-create this here.
> >> (I think I've messed up those conversion functions often enough...)
> >
> > The conversion functions are not at fault here, but we're missing
> > registers. If we have MIDR and friends writable, they show up in the
> > masks returned by the kernel, but they are not present in the kernel's
> > sysreg file where we generate our definitions from, and
> > kvm_idx_to_idregs_idx() asserts instead of returning an error, which
> > is kind of suboptimal...
> >
> > So I see two possible ways to fix this:
> > - add MIDR and friends to the kernel's sysreg file
> > - add MIDR and friends in QEMU's cpu-sysregs.h.inc file, and only append
> >   generated definitions there
> >
> > First option means one more round trip, second options has more
> > potential for messing things up if we keep stuff local to QEMU.
> 
> With the patch below, things work for me with a 6.15+ kernel. It's a bit

Yes works for me too now. Thanks.

> messy, though, and raises questions (how do we want to handle those regs
> across accelerators, for example, or how we can make sure that the code is
> more robust when registers are added.)
> 
> My biggest question, however, is how this interacts with the framework to
> provide lists of MIDR/REVIDR/AIDR for errata management. The hack below
> adds properties to configure those regs, I guess we'd want to suppress
> adding the props in order to avoid conflicts.

Not sure how this impacts the errata management though. My initial take on
this was, user will provide a list of target CPU ids through command line and
that will be used to set the target CPUs for errata management(if kernel
supports it).

Eg:
-machine virt,.., x-target-impl-cpus=0xMIDR1:0xREVIDR1-0xMIDR2:REVIDR2

And these will be stored in,

#define MAX_TARGET_IMPL_CPUS    4
typedef struct TargetImplCpu {
     uint32_t midr;
     uint32_t revidr;
} TargetImplCpu;


Please see the initial (a hack for testing kernel) implementation here,
https://github.com/hisilicon/qemu/commit/a393c1180274c73d34f32eaab66764a874a9ad31

Please let me know if there is a better/preferred way of obtaining this
target CPU list from user.

Thanks,
Shameer



^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model
  2025-06-04 10:58         ` Shameerali Kolothum Thodi via
@ 2025-06-04 12:35           ` Cornelia Huck
  2025-06-04 13:45             ` Shameerali Kolothum Thodi via
  0 siblings, 1 reply; 58+ messages in thread
From: Cornelia Huck @ 2025-06-04 12:35 UTC (permalink / raw)
  To: Shameerali Kolothum Thodi, eric.auger.pro@gmail.com,
	eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org,
	kvmarm@lists.linux.dev, peter.maydell@linaro.org,
	richard.henderson@linaro.org, alex.bennee@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, sebott@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com
  Cc: agraf@csgraf.de, shahuang@redhat.com, mark.rutland@arm.com,
	philmd@linaro.org, pbonzini@redhat.com

On Wed, Jun 04 2025, Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com> wrote:

>> -----Original Message-----
>> From: Cornelia Huck <cohuck@redhat.com>
>> Sent: Tuesday, June 3, 2025 4:15 PM
>> To: Shameerali Kolothum Thodi
>> <shameerali.kolothum.thodi@huawei.com>; eric.auger.pro@gmail.com;
>> eric.auger@redhat.com; qemu-devel@nongnu.org; qemu-arm@nongnu.org;
>> kvmarm@lists.linux.dev; peter.maydell@linaro.org;
>> richard.henderson@linaro.org; alex.bennee@linaro.org; maz@kernel.org;
>> oliver.upton@linux.dev; sebott@redhat.com; armbru@redhat.com;
>> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
>> Cc: agraf@csgraf.de; shahuang@redhat.com; mark.rutland@arm.com;
>> philmd@linaro.org; pbonzini@redhat.com
>> Subject: RE: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64
>> KVM host model
>> 
>> On Tue, May 27 2025, Cornelia Huck <cohuck@redhat.com> wrote:
>> > The conversion functions are not at fault here, but we're missing
>> > registers. If we have MIDR and friends writable, they show up in the
>> > masks returned by the kernel, but they are not present in the kernel's
>> > sysreg file where we generate our definitions from, and
>> > kvm_idx_to_idregs_idx() asserts instead of returning an error, which
>> > is kind of suboptimal...
>> >
>> > So I see two possible ways to fix this:
>> > - add MIDR and friends to the kernel's sysreg file
>> > - add MIDR and friends in QEMU's cpu-sysregs.h.inc file, and only append
>> >   generated definitions there
>> >
>> > First option means one more round trip, second options has more
>> > potential for messing things up if we keep stuff local to QEMU.
>> 
>> With the patch below, things work for me with a 6.15+ kernel. It's a bit
>
> Yes works for me too now. Thanks.

Thanks for checking.

>
>> messy, though, and raises questions (how do we want to handle those regs
>> across accelerators, for example, or how we can make sure that the code is
>> more robust when registers are added.)
>> 
>> My biggest question, however, is how this interacts with the framework to
>> provide lists of MIDR/REVIDR/AIDR for errata management. The hack below
>> adds properties to configure those regs, I guess we'd want to suppress
>> adding the props in order to avoid conflicts.
>
> Not sure how this impacts the errata management though. My initial take on
> this was, user will provide a list of target CPU ids through command line and
> that will be used to set the target CPUs for errata management(if kernel
> supports it).
>
> Eg:
> -machine virt,.., x-target-impl-cpus=0xMIDR1:0xREVIDR1-0xMIDR2:REVIDR2

I'm a bit confused by the range, I'd rather expect a list of tuples,
e.g. <midr>:<revidr>,<midr>:<revidr>, ...

>
> And these will be stored in,
>
> #define MAX_TARGET_IMPL_CPUS    4
> typedef struct TargetImplCpu {
>      uint32_t midr;
>      uint32_t revidr;

Isn't revidr a 64 bit value?

> } TargetImplCpu;
>
>
> Please see the initial (a hack for testing kernel) implementation here,
> https://github.com/hisilicon/qemu/commit/a393c1180274c73d34f32eaab66764a874a9ad31
>
> Please let me know if there is a better/preferred way of obtaining this
> target CPU list from user.

I'm mostly wondering about conflicting values between "we make MIDR et
al. writable, so we have a value different from what the host sees" and
"we provide a list of possible values to the guest, so it can prepare
for running on those hosts". Do we want to be able to provide a common
set to the guest, and then enlighten it with the list of systems that it
actually *might* run on? A benefit would be that it could always observe
the same (configured) register entries, regardless where it runs (needs
more plumbing in QEMU, I think.) We'd also need to be clear about what
we'd require (i.e. do we expect that both the real host values and the
configured values are present in the list?)

Not sure if the machine level is the right place to configure this, or
if it needs to go to the cpu options. While it is a machine-wide
configuration, it also means that we configure some cpu features in two
different places (even if they serve a different purpose.)

We could also choose to not expose properties for MIDR and friends at
all, even if they are writable.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model
  2025-06-04 12:35           ` Cornelia Huck
@ 2025-06-04 13:45             ` Shameerali Kolothum Thodi via
  2025-06-05 16:31               ` Cornelia Huck
  0 siblings, 1 reply; 58+ messages in thread
From: Shameerali Kolothum Thodi via @ 2025-06-04 13:45 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro@gmail.com, eric.auger@redhat.com,
	qemu-devel@nongnu.org, qemu-arm@nongnu.org,
	kvmarm@lists.linux.dev, peter.maydell@linaro.org,
	richard.henderson@linaro.org, alex.bennee@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, sebott@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com
  Cc: agraf@csgraf.de, shahuang@redhat.com, mark.rutland@arm.com,
	philmd@linaro.org, pbonzini@redhat.com



> -----Original Message-----
> From: Cornelia Huck <cohuck@redhat.com>
> Sent: Wednesday, June 4, 2025 1:36 PM
> To: Shameerali Kolothum Thodi
> <shameerali.kolothum.thodi@huawei.com>; eric.auger.pro@gmail.com;
> eric.auger@redhat.com; qemu-devel@nongnu.org; qemu-arm@nongnu.org;
> kvmarm@lists.linux.dev; peter.maydell@linaro.org;
> richard.henderson@linaro.org; alex.bennee@linaro.org; maz@kernel.org;
> oliver.upton@linux.dev; sebott@redhat.com; armbru@redhat.com;
> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
> Cc: agraf@csgraf.de; shahuang@redhat.com; mark.rutland@arm.com;
> philmd@linaro.org; pbonzini@redhat.com
> Subject: RE: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64
> KVM host model
> 
> On Wed, Jun 04 2025, Shameerali Kolothum Thodi
> <shameerali.kolothum.thodi@huawei.com> wrote:
> 
> >> -----Original Message-----
> >> From: Cornelia Huck <cohuck@redhat.com>
> >> Sent: Tuesday, June 3, 2025 4:15 PM
> >> To: Shameerali Kolothum Thodi
> >> <shameerali.kolothum.thodi@huawei.com>; eric.auger.pro@gmail.com;
> >> eric.auger@redhat.com; qemu-devel@nongnu.org; qemu-
> arm@nongnu.org;
> >> kvmarm@lists.linux.dev; peter.maydell@linaro.org;
> >> richard.henderson@linaro.org; alex.bennee@linaro.org;
> maz@kernel.org;
> >> oliver.upton@linux.dev; sebott@redhat.com; armbru@redhat.com;
> >> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
> >> Cc: agraf@csgraf.de; shahuang@redhat.com; mark.rutland@arm.com;
> >> philmd@linaro.org; pbonzini@redhat.com
> >> Subject: RE: [PATCH v3 00/10] kvm/arm: Introduce a customizable
> aarch64
> >> KVM host model
> >>
> >> On Tue, May 27 2025, Cornelia Huck <cohuck@redhat.com> wrote:
> >> > The conversion functions are not at fault here, but we're missing
> >> > registers. If we have MIDR and friends writable, they show up in the
> >> > masks returned by the kernel, but they are not present in the kernel's
> >> > sysreg file where we generate our definitions from, and
> >> > kvm_idx_to_idregs_idx() asserts instead of returning an error, which
> >> > is kind of suboptimal...
> >> >
> >> > So I see two possible ways to fix this:
> >> > - add MIDR and friends to the kernel's sysreg file
> >> > - add MIDR and friends in QEMU's cpu-sysregs.h.inc file, and only
> append
> >> >   generated definitions there
> >> >
> >> > First option means one more round trip, second options has more
> >> > potential for messing things up if we keep stuff local to QEMU.
> >>
> >> With the patch below, things work for me with a 6.15+ kernel. It's a bit
> >
> > Yes works for me too now. Thanks.
> 
> Thanks for checking.
> 
> >
> >> messy, though, and raises questions (how do we want to handle those
> regs
> >> across accelerators, for example, or how we can make sure that the code
> is
> >> more robust when registers are added.)
> >>
> >> My biggest question, however, is how this interacts with the framework
> to
> >> provide lists of MIDR/REVIDR/AIDR for errata management. The hack
> below
> >> adds properties to configure those regs, I guess we'd want to suppress
> >> adding the props in order to avoid conflicts.
> >
> > Not sure how this impacts the errata management though. My initial take
> on
> > this was, user will provide a list of target CPU ids through command line
> and
> > that will be used to set the target CPUs for errata management(if kernel
> > supports it).
> >
> > Eg:
> > -machine virt,.., x-target-impl-cpus=0xMIDR1:0xREVIDR1-0xMIDR2:REVIDR2
> 
> I'm a bit confused by the range, I'd rather expect a list of tuples,
> e.g. <midr>:<revidr>,<midr>:<revidr>, ...

Hmm..is the concern here is the format or the number of entries?

> 
> >
> > And these will be stored in,
> >
> > #define MAX_TARGET_IMPL_CPUS    4
> > typedef struct TargetImplCpu {
> >      uint32_t midr;
> >      uint32_t revidr;
> 
> Isn't revidr a 64 bit value?

Yes. In fact they both are, though MIDR only uses 32 bits now. Will change.

> 
> > } TargetImplCpu;
> >
> >
> > Please see the initial (a hack for testing kernel) implementation here,
> >
> https://github.com/hisilicon/qemu/commit/a393c1180274c73d34f32eaab66
> 764a874a9ad31
> >
> > Please let me know if there is a better/preferred way of obtaining this
> > target CPU list from user.
> 
> I'm mostly wondering about conflicting values between "we make MIDR et
> al. writable, so we have a value different from what the host sees" and
> "we provide a list of possible values to the guest, so it can prepare
> for running on those hosts". Do we want to be able to provide a common
> set to the guest, and then enlighten it with the list of systems that it
> actually *might* run on? A benefit would be that it could always observe
> the same (configured) register entries, regardless where it runs (needs
> more plumbing in QEMU, I think.) We'd also need to be clear about what
> we'd require (i.e. do we expect that both the real host values and the
> configured values are present in the list?)

The expectation from kernel is that when target errata CPUs are specified,
it includes the current host CPU Ids as well. We could check to see the list includes
the host one. But I am not sure how we can validate the complete list provided
by user though. I think,  the onus of deciding which platforms this Guest VM is
going to run during its life time and specifying that correctly is with the user.

> 
> Not sure if the machine level is the right place to configure this, or
> if it needs to go to the cpu options. While it is a machine-wide
> configuration, it also means that we configure some cpu features in two
> different places (even if they serve a different purpose.)

I exploited MachineState for ease of hacking 😊. But not sure this belongs to CPU
either as it is very specific to KVM is enabled, supported kernel etc.
 
> We could also choose to not expose properties for MIDR and friends at
> all, even if they are writable.
>

Does that mean Qemu figures out all the supported target Ids based on the 
Host CPU  Ids?

Thanks,
Shameer
 


^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model
  2025-06-04 13:45             ` Shameerali Kolothum Thodi via
@ 2025-06-05 16:31               ` Cornelia Huck
  0 siblings, 0 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-06-05 16:31 UTC (permalink / raw)
  To: Shameerali Kolothum Thodi, eric.auger.pro@gmail.com,
	eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org,
	kvmarm@lists.linux.dev, peter.maydell@linaro.org,
	richard.henderson@linaro.org, alex.bennee@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, sebott@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com
  Cc: agraf@csgraf.de, shahuang@redhat.com, mark.rutland@arm.com,
	philmd@linaro.org, pbonzini@redhat.com

On Wed, Jun 04 2025, Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com> wrote:

>> -----Original Message-----
>> From: Cornelia Huck <cohuck@redhat.com>
>> Sent: Wednesday, June 4, 2025 1:36 PM
>> To: Shameerali Kolothum Thodi
>> <shameerali.kolothum.thodi@huawei.com>; eric.auger.pro@gmail.com;
>> eric.auger@redhat.com; qemu-devel@nongnu.org; qemu-arm@nongnu.org;
>> kvmarm@lists.linux.dev; peter.maydell@linaro.org;
>> richard.henderson@linaro.org; alex.bennee@linaro.org; maz@kernel.org;
>> oliver.upton@linux.dev; sebott@redhat.com; armbru@redhat.com;
>> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
>> Cc: agraf@csgraf.de; shahuang@redhat.com; mark.rutland@arm.com;
>> philmd@linaro.org; pbonzini@redhat.com
>> Subject: RE: [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64
>> KVM host model
>> 
>> On Wed, Jun 04 2025, Shameerali Kolothum Thodi
>> <shameerali.kolothum.thodi@huawei.com> wrote:
>> 
>> >> -----Original Message-----
>> >> From: Cornelia Huck <cohuck@redhat.com>
>> >> Sent: Tuesday, June 3, 2025 4:15 PM
>> >> To: Shameerali Kolothum Thodi
>> >> <shameerali.kolothum.thodi@huawei.com>; eric.auger.pro@gmail.com;
>> >> eric.auger@redhat.com; qemu-devel@nongnu.org; qemu-
>> arm@nongnu.org;
>> >> kvmarm@lists.linux.dev; peter.maydell@linaro.org;
>> >> richard.henderson@linaro.org; alex.bennee@linaro.org;
>> maz@kernel.org;
>> >> oliver.upton@linux.dev; sebott@redhat.com; armbru@redhat.com;
>> >> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
>> >> Cc: agraf@csgraf.de; shahuang@redhat.com; mark.rutland@arm.com;
>> >> philmd@linaro.org; pbonzini@redhat.com
>> >> Subject: RE: [PATCH v3 00/10] kvm/arm: Introduce a customizable
>> aarch64
>> >> KVM host model
>> >>
>> >> On Tue, May 27 2025, Cornelia Huck <cohuck@redhat.com> wrote:
>> >> > The conversion functions are not at fault here, but we're missing
>> >> > registers. If we have MIDR and friends writable, they show up in the
>> >> > masks returned by the kernel, but they are not present in the kernel's
>> >> > sysreg file where we generate our definitions from, and
>> >> > kvm_idx_to_idregs_idx() asserts instead of returning an error, which
>> >> > is kind of suboptimal...
>> >> >
>> >> > So I see two possible ways to fix this:
>> >> > - add MIDR and friends to the kernel's sysreg file
>> >> > - add MIDR and friends in QEMU's cpu-sysregs.h.inc file, and only
>> append
>> >> >   generated definitions there
>> >> >
>> >> > First option means one more round trip, second options has more
>> >> > potential for messing things up if we keep stuff local to QEMU.
>> >>
>> >> With the patch below, things work for me with a 6.15+ kernel. It's a bit
>> >
>> > Yes works for me too now. Thanks.
>> 
>> Thanks for checking.
>> 
>> >
>> >> messy, though, and raises questions (how do we want to handle those
>> regs
>> >> across accelerators, for example, or how we can make sure that the code
>> is
>> >> more robust when registers are added.)
>> >>
>> >> My biggest question, however, is how this interacts with the framework
>> to
>> >> provide lists of MIDR/REVIDR/AIDR for errata management. The hack
>> below
>> >> adds properties to configure those regs, I guess we'd want to suppress
>> >> adding the props in order to avoid conflicts.
>> >
>> > Not sure how this impacts the errata management though. My initial take
>> on
>> > this was, user will provide a list of target CPU ids through command line
>> and
>> > that will be used to set the target CPUs for errata management(if kernel
>> > supports it).
>> >
>> > Eg:
>> > -machine virt,.., x-target-impl-cpus=0xMIDR1:0xREVIDR1-0xMIDR2:REVIDR2
>> 
>> I'm a bit confused by the range, I'd rather expect a list of tuples,
>> e.g. <midr>:<revidr>,<midr>:<revidr>, ...
>
> Hmm..is the concern here is the format or the number of entries?

Format of the command line; number of entries is something we can change
later.

>
>> 
>> >
>> > And these will be stored in,
>> >
>> > #define MAX_TARGET_IMPL_CPUS    4
>> > typedef struct TargetImplCpu {
>> >      uint32_t midr;
>> >      uint32_t revidr;
>> 
>> Isn't revidr a 64 bit value?
>
> Yes. In fact they both are, though MIDR only uses 32 bits now. Will change.

It probably should also have aidr, just to be safe. (Even if triplets on
the command line will be a bit ugly.)

>
>> 
>> > } TargetImplCpu;
>> >
>> >
>> > Please see the initial (a hack for testing kernel) implementation here,
>> >
>> https://github.com/hisilicon/qemu/commit/a393c1180274c73d34f32eaab66
>> 764a874a9ad31
>> >
>> > Please let me know if there is a better/preferred way of obtaining this
>> > target CPU list from user.
>> 
>> I'm mostly wondering about conflicting values between "we make MIDR et
>> al. writable, so we have a value different from what the host sees" and
>> "we provide a list of possible values to the guest, so it can prepare
>> for running on those hosts". Do we want to be able to provide a common
>> set to the guest, and then enlighten it with the list of systems that it
>> actually *might* run on? A benefit would be that it could always observe
>> the same (configured) register entries, regardless where it runs (needs
>> more plumbing in QEMU, I think.) We'd also need to be clear about what
>> we'd require (i.e. do we expect that both the real host values and the
>> configured values are present in the list?)
>
> The expectation from kernel is that when target errata CPUs are specified,
> it includes the current host CPU Ids as well. We could check to see the list includes
> the host one. But I am not sure how we can validate the complete list provided
> by user though. I think,  the onus of deciding which platforms this Guest VM is
> going to run during its life time and specifying that correctly is with the user.

My question was more along the line of "if the user configures MIDR to
something different from the actual host values, do they need to include
that modified value in the list of target cpus as well?" If we disallow
changing MIDR, we'd naturally sidestep that issue.

>
>> 
>> Not sure if the machine level is the right place to configure this, or
>> if it needs to go to the cpu options. While it is a machine-wide
>> configuration, it also means that we configure some cpu features in two
>> different places (even if they serve a different purpose.)
>
> I exploited MachineState for ease of hacking 😊. But not sure this belongs to CPU
> either as it is very specific to KVM is enabled, supported kernel etc.

That's an interesting question :) I think we can keep it with the
machine state for now until we figure out more details -- it's more
important to actually test it out with real life scenarios.

>  
>> We could also choose to not expose properties for MIDR and friends at
>> all, even if they are writable.
>>
>
> Does that mean Qemu figures out all the supported target Ids based on the 
> Host CPU  Ids?

I think the target ids always need to be figured out and provided by the
user (as only they can possibly have an idea on where that guest might
end up running.) The question is more whether we should give the user
the means to directly configure the regs for a certain instance.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 07/10] arm/kvm: write back modified ID regs to KVM
  2025-04-14 16:38 ` [PATCH v3 07/10] arm/kvm: write back modified ID regs to KVM Cornelia Huck
  2025-04-15  7:03   ` Philippe Mathieu-Daudé
  2025-05-13 14:33   ` Eric Auger
@ 2025-07-02  4:01   ` Jinqian Yang via
  2025-07-02  8:46     ` Cornelia Huck
  2 siblings, 1 reply; 58+ messages in thread
From: Jinqian Yang via @ 2025-07-02  4:01 UTC (permalink / raw)
  To: Cornelia Huck, eric.auger.pro, eric.auger, qemu-devel, qemu-arm,
	kvmarm, peter.maydell, richard.henderson, alex.bennee, maz,
	oliver.upton, sebott, shameerali.kolothum.thodi, armbru, berrange,
	abologna, jdenemar, Zhou Wang, liuyonglong
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini


On 2025/4/15 0:38, Cornelia Huck wrote:
> From: Eric Auger <eric.auger@redhat.com>
>
> We want to give a chance to override the value of host ID regs.
> In a previous patch we made sure all their values could be fetched
> through kvm_get_one_reg() calls before their modification. After
> their potential modification we need to make sure we write back
> the values through kvm_set_one_reg() calls.
>
> Make sure the cpreg_list is modified with updated values and
> transfer those values back to kvm.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
>   target/arm/kvm.c        | 44 ++++++++++++++++++++++++++++++++++++++++-
>   target/arm/trace-events |  1 +
>   2 files changed, 44 insertions(+), 1 deletion(-)
>
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index b07d5f16db50..9e4cca1705c8 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -1083,6 +1083,39 @@ void kvm_arm_cpu_post_load(ARMCPU *cpu)
>       }
>   }
>   
> +static void kvm_arm_writable_idregs_to_cpreg_list(ARMCPU *cpu)
> +{
> +    if (!cpu->writable_map) {
> +        return;
> +    }
> +    for (int i = 0; i < NR_ID_REGS; i++) {
> +        uint64_t writable_mask = cpu->writable_map->regs[i];
> +        uint64_t *cpreg;
> +
> +        if (writable_mask) {
> +            uint64_t previous, new;
> +            int idx = kvm_idx_to_idregs_idx(i);
> +            ARM64SysReg *sysregdesc;
> +            uint32_t sysreg;
> +
> +            if (idx == -1) {
> +                /* sysreg writable, but we don't know it */
> +                continue;
> +            }
> +            sysregdesc = &arm64_id_regs[idx];
> +            sysreg = sysregdesc->sysreg;
> +            cpreg = kvm_arm_get_cpreg_ptr(cpu, idregs_sysreg_to_kvm_reg(sysreg));
> +            previous = *cpreg;
> +            new = cpu->isar.idregs[idx];
> +            if (previous != new) {
> +                *cpreg = new;
> +                trace_kvm_arm_writable_idregs_to_cpreg_list(sysregdesc->name,
> +                                                            previous, new);
> +            }
> +        }
> +    }
> +}
> +
>   void kvm_arm_reset_vcpu(ARMCPU *cpu)
>   {
>       int ret;
> @@ -2050,7 +2083,16 @@ int kvm_arch_init_vcpu(CPUState *cs)
>       }
>       cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
>   
> -    return kvm_arm_init_cpreg_list(cpu);
> +    ret = kvm_arm_init_cpreg_list(cpu);
> +    if (ret) {
> +        return ret;
> +    }
> +    /* overwrite writable ID regs with their updated property values */
> +    kvm_arm_writable_idregs_to_cpreg_list(cpu);
> +
> +    write_list_to_kvmstate(cpu, 3);
> +
> +    return 0;
>   }

Hi,

When I was testing this series, I found a problem. On the host, 
SYSREG_ID_AA64MMFR3_EL1_TCRX=0x1,
I configured it to 0x0 in qemu, and qemu cannot start.
The ID_AA64MMFR3_EL1 TCRX field controls whether the TCR2_EL1 and 
TCR2_EL2 registers are used.
In the kernel, when TCRX is 0, TCR2_EL1 is invisible to the guest, and 
when it is 1, it is visible. When we
configure this field segment to 0, the configuration is not yet written 
to KVM, but the cpreg list is initialized,
adding TCR2_EL1 to the cpreg list. Therefore, after writing the 
QEMU-configured registers to KVM, the
cpreg list needs to be updated again.

@@ -2227,7 +2229,7 @@ int kvm_arch_init_vcpu(CPUState *cs)

      write_list_to_kvmstate(cpu, 3);

-    return 0;
+    return kvm_arm_init_cpreg_list(cpu);
  }

The above modification can solve the problem, but it may not be the best 
way.

Thanks,
Jinqian


>   
>   int kvm_arch_destroy_vcpu(CPUState *cs)
> diff --git a/target/arm/trace-events b/target/arm/trace-events
> index 17e52c0705f2..955149ee1ac4 100644
> --- a/target/arm/trace-events
> +++ b/target/arm/trace-events
> @@ -14,3 +14,4 @@ arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
>   # kvm.c
>   kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
>   get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host value for %s is 0x%"PRIx64
> +kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint64_t new) "%s overwrite default 0x%"PRIx64" with 0x%"PRIx64


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v3 07/10] arm/kvm: write back modified ID regs to KVM
  2025-07-02  4:01   ` Jinqian Yang via
@ 2025-07-02  8:46     ` Cornelia Huck
  0 siblings, 0 replies; 58+ messages in thread
From: Cornelia Huck @ 2025-07-02  8:46 UTC (permalink / raw)
  To: Jinqian Yang, eric.auger.pro, eric.auger, qemu-devel, qemu-arm,
	kvmarm, peter.maydell, richard.henderson, alex.bennee, maz,
	oliver.upton, sebott, shameerali.kolothum.thodi, armbru, berrange,
	abologna, jdenemar, Zhou Wang, liuyonglong
  Cc: agraf, shahuang, mark.rutland, philmd, pbonzini

On Wed, Jul 02 2025, Jinqian Yang <yangjinqian1@huawei.com> wrote:

> On 2025/4/15 0:38, Cornelia Huck wrote:
>> From: Eric Auger <eric.auger@redhat.com>
>>
>> We want to give a chance to override the value of host ID regs.
>> In a previous patch we made sure all their values could be fetched
>> through kvm_get_one_reg() calls before their modification. After
>> their potential modification we need to make sure we write back
>> the values through kvm_set_one_reg() calls.
>>
>> Make sure the cpreg_list is modified with updated values and
>> transfer those values back to kvm.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>> ---
>>   target/arm/kvm.c        | 44 ++++++++++++++++++++++++++++++++++++++++-
>>   target/arm/trace-events |  1 +
>>   2 files changed, 44 insertions(+), 1 deletion(-)
>>
>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>> index b07d5f16db50..9e4cca1705c8 100644
>> --- a/target/arm/kvm.c
>> +++ b/target/arm/kvm.c
>> @@ -1083,6 +1083,39 @@ void kvm_arm_cpu_post_load(ARMCPU *cpu)
>>       }
>>   }
>>   
>> +static void kvm_arm_writable_idregs_to_cpreg_list(ARMCPU *cpu)
>> +{
>> +    if (!cpu->writable_map) {
>> +        return;
>> +    }
>> +    for (int i = 0; i < NR_ID_REGS; i++) {
>> +        uint64_t writable_mask = cpu->writable_map->regs[i];
>> +        uint64_t *cpreg;
>> +
>> +        if (writable_mask) {
>> +            uint64_t previous, new;
>> +            int idx = kvm_idx_to_idregs_idx(i);
>> +            ARM64SysReg *sysregdesc;
>> +            uint32_t sysreg;
>> +
>> +            if (idx == -1) {
>> +                /* sysreg writable, but we don't know it */
>> +                continue;
>> +            }
>> +            sysregdesc = &arm64_id_regs[idx];
>> +            sysreg = sysregdesc->sysreg;
>> +            cpreg = kvm_arm_get_cpreg_ptr(cpu, idregs_sysreg_to_kvm_reg(sysreg));
>> +            previous = *cpreg;
>> +            new = cpu->isar.idregs[idx];
>> +            if (previous != new) {
>> +                *cpreg = new;
>> +                trace_kvm_arm_writable_idregs_to_cpreg_list(sysregdesc->name,
>> +                                                            previous, new);
>> +            }
>> +        }
>> +    }
>> +}
>> +
>>   void kvm_arm_reset_vcpu(ARMCPU *cpu)
>>   {
>>       int ret;
>> @@ -2050,7 +2083,16 @@ int kvm_arch_init_vcpu(CPUState *cs)
>>       }
>>       cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
>>   
>> -    return kvm_arm_init_cpreg_list(cpu);
>> +    ret = kvm_arm_init_cpreg_list(cpu);
>> +    if (ret) {
>> +        return ret;
>> +    }
>> +    /* overwrite writable ID regs with their updated property values */
>> +    kvm_arm_writable_idregs_to_cpreg_list(cpu);
>> +
>> +    write_list_to_kvmstate(cpu, 3);
>> +
>> +    return 0;
>>   }
>
> Hi,
>
> When I was testing this series, I found a problem. On the host, 
> SYSREG_ID_AA64MMFR3_EL1_TCRX=0x1,
> I configured it to 0x0 in qemu, and qemu cannot start.
> The ID_AA64MMFR3_EL1 TCRX field controls whether the TCR2_EL1 and 
> TCR2_EL2 registers are used.
> In the kernel, when TCRX is 0, TCR2_EL1 is invisible to the guest, and 
> when it is 1, it is visible. When we
> configure this field segment to 0, the configuration is not yet written 
> to KVM, but the cpreg list is initialized,
> adding TCR2_EL1 to the cpreg list. Therefore, after writing the 
> QEMU-configured registers to KVM, the
> cpreg list needs to be updated again.
>
> @@ -2227,7 +2229,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
>
>       write_list_to_kvmstate(cpu, 3);
>
> -    return 0;
> +    return kvm_arm_init_cpreg_list(cpu);
>   }
>
> The above modification can solve the problem, but it may not be the best 
> way.

Thanks for testing. Indeed, if we write something that changes the
visibility of registers, we need to do an update. Probably needs some
thinking (e.g. what happens if a register disappears, but the user set
some fields?)



^ permalink raw reply	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2025-07-02  8:47 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-14 16:38 [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
2025-04-14 16:38 ` [PATCH v3 01/10] arm/cpu: Add infra to handle generated ID register definitions Cornelia Huck
2025-05-13 13:52   ` Eric Auger
2025-05-13 14:05     ` Cornelia Huck
2025-05-13 15:12       ` Eric Auger
2025-04-14 16:38 ` [PATCH v3 02/10] arm/cpu: Add sysreg properties generation Cornelia Huck
2025-04-15  7:09   ` Philippe Mathieu-Daudé
2025-04-15  7:20     ` Philippe Mathieu-Daudé
2025-05-19 14:49     ` Cornelia Huck
2025-05-13 15:23   ` Daniel P. Berrangé
2025-05-14 15:25     ` Cornelia Huck
2025-05-14 15:29       ` Daniel P. Berrangé
2025-04-14 16:38 ` [PATCH v3 03/10] arm/cpu: Add generated sysreg properties Cornelia Huck
2025-04-14 16:38 ` [PATCH v3 04/10] kvm: kvm_get_writable_id_regs Cornelia Huck
2025-05-13 14:20   ` Eric Auger
2025-05-13 14:42     ` Cornelia Huck
2025-05-13 15:16       ` Eric Auger
2025-04-14 16:38 ` [PATCH v3 05/10] arm/cpu: accessors for writable id registers Cornelia Huck
2025-04-29 16:27   ` Sebastian Ott
2025-04-30 13:48     ` Cornelia Huck
2025-04-14 16:38 ` [PATCH v3 06/10] arm/kvm: Allow reading all the writable ID registers Cornelia Huck
2025-05-13 14:31   ` Eric Auger
2025-05-16 14:17     ` Cornelia Huck
2025-05-20 14:05     ` Cornelia Huck
2025-05-23  8:27   ` Shameerali Kolothum Thodi via
2025-05-26 12:37     ` Cornelia Huck
2025-04-14 16:38 ` [PATCH v3 07/10] arm/kvm: write back modified ID regs to KVM Cornelia Huck
2025-04-15  7:03   ` Philippe Mathieu-Daudé
2025-04-15  9:54     ` Cornelia Huck
2025-05-13 14:33   ` Eric Auger
2025-07-02  4:01   ` Jinqian Yang via
2025-07-02  8:46     ` Cornelia Huck
2025-04-14 16:38 ` [PATCH v3 08/10] arm/cpu: more customization for the kvm host cpu model Cornelia Huck
2025-05-13 14:47   ` Eric Auger
2025-05-13 15:56   ` Daniel P. Berrangé
2025-05-16 14:42     ` Cornelia Huck
2025-05-13 15:59   ` Daniel P. Berrangé
2025-05-14 15:36     ` Cornelia Huck
2025-05-14 18:22       ` Daniel P. Berrangé
2025-05-16 14:51         ` Cornelia Huck
2025-05-16 14:57           ` Daniel P. Berrangé
2025-05-16 15:13             ` Cornelia Huck
2025-04-14 16:38 ` [PATCH v3 09/10] arm-qmp-cmds: introspection for ID register props Cornelia Huck
2025-05-13 14:50   ` Eric Auger
2025-04-14 16:38 ` [PATCH v3 10/10] arm/cpu-features: document ID reg properties Cornelia Huck
2025-05-13 15:09   ` Eric Auger
2025-05-13 16:23   ` Daniel P. Berrangé
2025-05-13 15:29 ` [PATCH v3 00/10] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
2025-05-14 13:47   ` Shameerali Kolothum Thodi via
2025-05-14 14:47     ` Eric Auger
2025-05-23 13:23 ` Shameerali Kolothum Thodi via
2025-05-26 12:44   ` Cornelia Huck
2025-05-27 10:06     ` Cornelia Huck
2025-06-03 15:14       ` Cornelia Huck
2025-06-04 10:58         ` Shameerali Kolothum Thodi via
2025-06-04 12:35           ` Cornelia Huck
2025-06-04 13:45             ` Shameerali Kolothum Thodi via
2025-06-05 16:31               ` Cornelia Huck

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).