* [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model
@ 2026-05-03 7:33 Eric Auger
2026-05-03 7:33 ` [PATCH v4 01/17] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py Eric Auger
` (17 more replies)
0 siblings, 18 replies; 39+ messages in thread
From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, cohuck, sebott, skolothumtho,
philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
This series enhances the current host KVM model with capability to
set writable ID reg fields.
Since v6.7 kernel, KVM/arm allows the userspace to overwrite the values
of a subset of ID regs. The list of writable fields continues to grow.
The feature ID range is defined as the AArch64 System register space
with op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}.
The end goal is to get more flexibility when migrating guests
between different host hardware.
QEMU retrieves the writable ID fields from KVM UAPI [1] and
match them against a generated description of ID regs and their
named fields that stem from AARCHMRS Registers.json file.
Current description is based on latest 2026-03 edition.
The content of the generated files was compared against kernel
linux/arch/arm64/tools/sysreg file [3] . It is not straightforward
to have unit tests for python scripts as there are many cases for
field extraction.
For each writable named field a uint64 property is created
following the "SYSREG_<REG>_<FIELD>" naming convention. REG and
FIELD names are those described in ARM ARM Reference manual.
The list of SYSREG_ID properties can be retrieved through the qmp
monitor using query-cpu-model-expansion [2].
Connie & Eric
This series can be found at:
https://github.com/eauger/qemu/tree/arm-cpu-model-v4
References:
[1]
KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES
KVM_ARM_GET_REG_WRITABLE_MASKS
Documentation/virt/kvm/api.rst
[2]
qemu-system-aarch64 -qmp unix:/home/augere/TEST/QEMU/qmp-sock,server,nowait -M virt --enable-kvm -cpu custom
sudo build/run qmp-shell /home/augere/TEST/QEMU/qmp-sock
Welcome to the QMP low-level shell!
Connected to QEMU 11.0.50
(QEMU) query-cpu-model-expansion type=full model={"name":"host"}
[3]
linux/arch/arm64/tools/sysreg and gen-sysreg.awk
./tools/include/generated/asm/sysreg-defs.h
Cornelia Huck (4):
target/arm/kvm: Introduce 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 (13):
scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py
target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order
target/arm/cpu-sysregs.h.inc: Update with automatic generation
arm/cpu: Add infra to handle generated ID register definitions
scripts: Introduce scripts/aarch64_sysreg_helpers module
scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py
target/arm/cpu-sysreg-properties.c: Generate code with new script
arm/kvm: Allow reading all the writable ID registers
arm/kvm: write back modified ID regs to KVM
target/arm/kvm: Introduce kvm_arm_expose_idreg_properties
target/arm/kvm: Special case REVIDR_EL1 and AIDR_EL1
target/arm/kvm: Special case ID_AA64ISAR0_EL1 RES0 [24, 27] bits
arm/cpu: Expose writable ID reg field properties on the kvm host vcpu
model
docs/system/arm/cpu-features.rst | 104 ++-
scripts/aarch64_sysreg_helpers.py | 109 +++
.../update-aarch64-cpu-sysreg-properties.py | 169 +++++
scripts/update-aarch64-cpu-sysregs-header.py | 51 ++
target/arm/arm-qmp-cmds.c | 19 +
target/arm/cpu-idregs.h | 59 ++
target/arm/cpu-sysreg-properties.c | 673 ++++++++++++++++++
target/arm/cpu-sysregs.h.inc | 57 +-
target/arm/cpu.c | 12 +
target/arm/cpu.h | 36 +
target/arm/cpu64.c | 26 +-
target/arm/kvm-stub.c | 3 +-
target/arm/kvm.c | 313 +++++++-
target/arm/kvm_arm.h | 19 +-
target/arm/meson.build | 3 +-
target/arm/trace-events | 6 +
16 files changed, 1622 insertions(+), 37 deletions(-)
create mode 100644 scripts/aarch64_sysreg_helpers.py
create mode 100644 scripts/update-aarch64-cpu-sysreg-properties.py
create mode 100755 scripts/update-aarch64-cpu-sysregs-header.py
create mode 100644 target/arm/cpu-idregs.h
create mode 100644 target/arm/cpu-sysreg-properties.c
--
2.53.0
^ permalink raw reply [flat|nested] 39+ messages in thread* [PATCH v4 01/17] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-03 7:33 ` [PATCH v4 02/17] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order Eric Auger ` (16 subsequent siblings) 17 siblings, 0 replies; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar Introduce a script that takes as input the Registers.json file delivered in the AARCHMRS Features Model downloadable from the Arm Developer A-Profile Architecture Exploration Tools page: https://developer.arm.com/Architectures/A-Profile%20Architecture#Downloads and outputs the list of ID regs in target/arm/cpu-sysregs.h.inc under the form of DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>). We only care about IDregs with opcodes satisfying: op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7] Signed-off-by: Eric Auger <eric.auger@redhat.com> [CH: note correct op1 range, don't skip CCSIDR] Signed-off-by: Cornelia Huck <cohuck@redhat.com> Message-ID: <20251208163751.611186-2-eric.auger@redhat.com> --- scripts/update-aarch64-cpu-sysregs-header.py | 134 +++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100755 scripts/update-aarch64-cpu-sysregs-header.py diff --git a/scripts/update-aarch64-cpu-sysregs-header.py b/scripts/update-aarch64-cpu-sysregs-header.py new file mode 100755 index 0000000000..8c337147dd --- /dev/null +++ b/scripts/update-aarch64-cpu-sysregs-header.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 + +# This script takes as input the Registers.json file delivered in +# the AARCHMRS Features Model downloadable from the Arm Developer +# A-Profile Architecture Exploration Tools page: +# https://developer.arm.com/Architectures/A-Profile%20Architecture#Downloads +# and outputs the list of ID regs in target/arm/cpu-sysregs.h.inc +# under the form of DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>) +# +# Copyright (C) 2026 Red Hat, Inc. +# +# Authors: Eric Auger <eric.auger@redhat.com> +# +# SPDX-License-Identifier: GPL-2.0-or-later + + +import json +import os +import sys + +# Some regs have op code values like 000x, 001x. Anyway we don't need +# them. Besides some regs are undesired in the generated file such as +# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we +# are interested in and are tricky to decode as their system accessor +# refer to MPIDR_EL1/MIDR_EL1 respectively + +skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \ + 'VMPIDR_EL2', 'VPIDR_EL2'] + +# returns the int value of a given @opcode for a reg @encoding +def get_opcode(encoding, opcode): + fvalue = encoding.get(opcode) + if fvalue: + value = fvalue.get('value') + if isinstance(value, str): + value = value.strip("'") + value = int(value, 2) + return value + return -1 + +def extract_idregs_from_registers_json(filename): + """ + Load a Registers.json file and extract all ID registers, decode their + opcode and dump the information in target/arm/cpu-sysregs.h.inc + + Args: + filename (str): The path to the Registers.json + returns: + idregs: list of ID regs and their encoding + """ + if not os.path.exists(filename): + print(f"Error: {filename} could not be found!") + return {} + + try: + with open(filename, 'r') as f: + register_data = json.load(f) + + except json.JSONDecodeError: + print(f"Could not decode json from '{filename}'!") + return {} + except Exception as e: + print(f"Unexpected error while reading {filename}: {e}") + return {} + + registers = [r for r in register_data if isinstance(r, dict) and \ + r.get('_type') == 'Register'] + + idregs = {} + + for register in registers: + reg_name = register.get('name') + + is_skipped = any(term in (reg_name or "").upper() for term in skiplist) + + if reg_name and not is_skipped: + accessors = register.get('accessors', []) + + for accessor in accessors: + type = accessor.get('_type') + if type in ['Accessors.SystemAccessor']: + encoding_list = accessor.get('encoding') + + if isinstance(encoding_list, list) and encoding_list and \ + isinstance(encoding_list[0], dict): + encoding_wrapper = encoding_list[0] + encoding_source = encoding_wrapper.get('encodings', \ + encoding_wrapper) + + if isinstance(encoding_source, dict): + op0 = get_opcode(encoding_source, 'op0') + op1 = get_opcode(encoding_source, 'op1') + op2 = get_opcode(encoding_source, 'op2') + crn = get_opcode(encoding_source, 'CRn') + crm = get_opcode(encoding_source, 'CRm') + encoding_str=f"{op0} {op1} {crn} {crm} {op2}" + + # ID regs are assumed within this scope + if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \ + crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7): + idregs[reg_name] = encoding_str + + return idregs + +if __name__ == "__main__": + # Single arg expected: the path to the Registers.json file + if len(sys.argv) < 2: + print("Usage: python scripts/update-aarch64-cpu-sysregs-header.py " + "<path_to_registers_json>") + sys.exit(1) + else: + json_file_path = sys.argv[1] + + extracted_registers = extract_idregs_from_registers_json(json_file_path) + + if extracted_registers: + output_list = extracted_registers.items() + + # Sort by register name + sorted_output = sorted(output_list, key=lambda item: item[0]) + + # format lines as DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>) + final_output = "" + for reg_name, encoding in sorted_output: + reformatted_encoding = encoding.replace(" ", ", ") + final_output += f"DEF({reg_name}, {reformatted_encoding})\n" + + with open("target/arm/cpu-sysregs.h.inc", 'w') as f: + f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n") + f.write("/* This file is autogenerated by ") + f.write("scripts/update-aarch64-cpu-sysregs-header.py */\n") + f.write("/* DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>) */\n\n") + f.write(final_output) + print("updated target/arm/cpu-sysregs.h.inc") -- 2.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* [PATCH v4 02/17] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger 2026-05-03 7:33 ` [PATCH v4 01/17] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-06 16:10 ` Shameer Kolothum Thodi 2026-05-03 7:33 ` [PATCH v4 03/17] target/arm/cpu-sysregs.h.inc: Update with automatic generation Eric Auger ` (15 subsequent siblings) 17 siblings, 1 reply; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order Sort by register name alphabetical order. This will allow to easily diff with the future content, automatically generated. No functional change intended. Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> Message-ID: <20251208163751.611186-3-eric.auger@redhat.com> --- target/arm/cpu-sysregs.h.inc | 43 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc index 3d1ed40f04..d61f0d0a19 100644 --- a/target/arm/cpu-sysregs.h.inc +++ b/target/arm/cpu-sysregs.h.inc @@ -1,12 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -DEF(ID_AA64PFR0_EL1, 3, 0, 0, 4, 0) -DEF(ID_AA64PFR1_EL1, 3, 0, 0, 4, 1) -DEF(ID_AA64PFR2_EL1, 3, 0, 0, 4, 2) -DEF(ID_AA64SMFR0_EL1, 3, 0, 0, 4, 5) -DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0) -DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1) +DEF(CCSIDR_EL1, 3, 1, 0, 0, 0) +DEF(CLIDR_EL1, 3, 1, 0, 0, 1) +DEF(CTR_EL0, 3, 3, 0, 0, 1) +DEF(DCZID_EL0, 3, 3, 0, 0, 7) DEF(ID_AA64AFR0_EL1, 3, 0, 0, 5, 4) DEF(ID_AA64AFR1_EL1, 3, 0, 0, 5, 5) +DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0) +DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1) DEF(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0) DEF(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1) DEF(ID_AA64ISAR2_EL1, 3, 0, 0, 6, 2) @@ -15,29 +15,30 @@ DEF(ID_AA64MMFR1_EL1, 3, 0, 0, 7, 1) DEF(ID_AA64MMFR2_EL1, 3, 0, 0, 7, 2) DEF(ID_AA64MMFR3_EL1, 3, 0, 0, 7, 3) DEF(ID_AA64MMFR4_EL1, 3, 0, 0, 7, 4) -DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0) -DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1) -DEF(ID_DFR0_EL1, 3, 0, 0, 1, 2) +DEF(ID_AA64PFR0_EL1, 3, 0, 0, 4, 0) +DEF(ID_AA64PFR1_EL1, 3, 0, 0, 4, 1) +DEF(ID_AA64PFR2_EL1, 3, 0, 0, 4, 2) +DEF(ID_AA64SMFR0_EL1, 3, 0, 0, 4, 5) +DEF(ID_AA64ZFR0_EL1, 3, 0, 0, 4, 4) DEF(ID_AFR0_EL1, 3, 0, 0, 1, 3) -DEF(ID_MMFR0_EL1, 3, 0, 0, 1, 4) -DEF(ID_MMFR1_EL1, 3, 0, 0, 1, 5) -DEF(ID_MMFR2_EL1, 3, 0, 0, 1, 6) -DEF(ID_MMFR3_EL1, 3, 0, 0, 1, 7) +DEF(ID_DFR0_EL1, 3, 0, 0, 1, 2) +DEF(ID_DFR1_EL1, 3, 0, 0, 3, 5) DEF(ID_ISAR0_EL1, 3, 0, 0, 2, 0) DEF(ID_ISAR1_EL1, 3, 0, 0, 2, 1) DEF(ID_ISAR2_EL1, 3, 0, 0, 2, 2) DEF(ID_ISAR3_EL1, 3, 0, 0, 2, 3) DEF(ID_ISAR4_EL1, 3, 0, 0, 2, 4) DEF(ID_ISAR5_EL1, 3, 0, 0, 2, 5) -DEF(ID_MMFR4_EL1, 3, 0, 0, 2, 6) DEF(ID_ISAR6_EL1, 3, 0, 0, 2, 7) +DEF(ID_MMFR0_EL1, 3, 0, 0, 1, 4) +DEF(ID_MMFR1_EL1, 3, 0, 0, 1, 5) +DEF(ID_MMFR2_EL1, 3, 0, 0, 1, 6) +DEF(ID_MMFR3_EL1, 3, 0, 0, 1, 7) +DEF(ID_MMFR4_EL1, 3, 0, 0, 2, 6) +DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6) +DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0) +DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1) +DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4) DEF(MVFR0_EL1, 3, 0, 0, 3, 0) DEF(MVFR1_EL1, 3, 0, 0, 3, 1) DEF(MVFR2_EL1, 3, 0, 0, 3, 2) -DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4) -DEF(ID_DFR1_EL1, 3, 0, 0, 3, 5) -DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6) -DEF(CLIDR_EL1, 3, 1, 0, 0, 1) -DEF(ID_AA64ZFR0_EL1, 3, 0, 0, 4, 4) -DEF(CTR_EL0, 3, 3, 0, 0, 1) -DEF(DCZID_EL0, 3, 3, 0, 0, 7) -- 2.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* RE: [PATCH v4 02/17] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order 2026-05-03 7:33 ` [PATCH v4 02/17] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order Eric Auger @ 2026-05-06 16:10 ` Shameer Kolothum Thodi 2026-05-12 6:24 ` Eric Auger 0 siblings, 1 reply; 39+ messages in thread From: Shameer Kolothum Thodi @ 2026-05-06 16:10 UTC (permalink / raw) To: Eric Auger, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com > -----Original Message----- > From: Eric Auger <eric.auger@redhat.com> > Sent: 03 May 2026 08:33 > 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; > cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi > <skolothumtho@nvidia.com>; philmd@linaro.org > Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; > armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; > jdenemar@redhat.com > Subject: [PATCH v4 02/17] target/arm/cpu-sysregs.h.inc: Sort by name > alphabetical order > > External email: Use caution opening links or attachments > > > target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order > > Sort by register name alphabetical order. This will allow to > easily diff with the future content, automatically generated. > > No functional change intended. > > Signed-off-by: Eric Auger <eric.auger@redhat.com> > Signed-off-by: Cornelia Huck <cohuck@redhat.com> > Message-ID: <20251208163751.611186-3-eric.auger@redhat.com> > --- > target/arm/cpu-sysregs.h.inc | 43 ++++++++++++++++++------------------ > 1 file changed, 22 insertions(+), 21 deletions(-) Took a while to figure out the extra addition 😊 +DEF(CCSIDR_EL1, 3, 1, 0, 0, 0) May be worth mentioning in commit log. Thanks, Shameer > > diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc > index 3d1ed40f04..d61f0d0a19 100644 > --- a/target/arm/cpu-sysregs.h.inc > +++ b/target/arm/cpu-sysregs.h.inc > @@ -1,12 +1,12 @@ > /* SPDX-License-Identifier: GPL-2.0-or-later */ > -DEF(ID_AA64PFR0_EL1, 3, 0, 0, 4, 0) > -DEF(ID_AA64PFR1_EL1, 3, 0, 0, 4, 1) > -DEF(ID_AA64PFR2_EL1, 3, 0, 0, 4, 2) > -DEF(ID_AA64SMFR0_EL1, 3, 0, 0, 4, 5) > -DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0) > -DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1) > +DEF(CCSIDR_EL1, 3, 1, 0, 0, 0) > +DEF(CLIDR_EL1, 3, 1, 0, 0, 1) > +DEF(CTR_EL0, 3, 3, 0, 0, 1) > +DEF(DCZID_EL0, 3, 3, 0, 0, 7) > DEF(ID_AA64AFR0_EL1, 3, 0, 0, 5, 4) > DEF(ID_AA64AFR1_EL1, 3, 0, 0, 5, 5) > +DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0) > +DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1) > DEF(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0) > DEF(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1) > DEF(ID_AA64ISAR2_EL1, 3, 0, 0, 6, 2) > @@ -15,29 +15,30 @@ DEF(ID_AA64MMFR1_EL1, 3, 0, 0, 7, 1) > DEF(ID_AA64MMFR2_EL1, 3, 0, 0, 7, 2) > DEF(ID_AA64MMFR3_EL1, 3, 0, 0, 7, 3) > DEF(ID_AA64MMFR4_EL1, 3, 0, 0, 7, 4) > -DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0) > -DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1) > -DEF(ID_DFR0_EL1, 3, 0, 0, 1, 2) > +DEF(ID_AA64PFR0_EL1, 3, 0, 0, 4, 0) > +DEF(ID_AA64PFR1_EL1, 3, 0, 0, 4, 1) > +DEF(ID_AA64PFR2_EL1, 3, 0, 0, 4, 2) > +DEF(ID_AA64SMFR0_EL1, 3, 0, 0, 4, 5) > +DEF(ID_AA64ZFR0_EL1, 3, 0, 0, 4, 4) > DEF(ID_AFR0_EL1, 3, 0, 0, 1, 3) > -DEF(ID_MMFR0_EL1, 3, 0, 0, 1, 4) > -DEF(ID_MMFR1_EL1, 3, 0, 0, 1, 5) > -DEF(ID_MMFR2_EL1, 3, 0, 0, 1, 6) > -DEF(ID_MMFR3_EL1, 3, 0, 0, 1, 7) > +DEF(ID_DFR0_EL1, 3, 0, 0, 1, 2) > +DEF(ID_DFR1_EL1, 3, 0, 0, 3, 5) > DEF(ID_ISAR0_EL1, 3, 0, 0, 2, 0) > DEF(ID_ISAR1_EL1, 3, 0, 0, 2, 1) > DEF(ID_ISAR2_EL1, 3, 0, 0, 2, 2) > DEF(ID_ISAR3_EL1, 3, 0, 0, 2, 3) > DEF(ID_ISAR4_EL1, 3, 0, 0, 2, 4) > DEF(ID_ISAR5_EL1, 3, 0, 0, 2, 5) > -DEF(ID_MMFR4_EL1, 3, 0, 0, 2, 6) > DEF(ID_ISAR6_EL1, 3, 0, 0, 2, 7) > +DEF(ID_MMFR0_EL1, 3, 0, 0, 1, 4) > +DEF(ID_MMFR1_EL1, 3, 0, 0, 1, 5) > +DEF(ID_MMFR2_EL1, 3, 0, 0, 1, 6) > +DEF(ID_MMFR3_EL1, 3, 0, 0, 1, 7) > +DEF(ID_MMFR4_EL1, 3, 0, 0, 2, 6) > +DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6) > +DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0) > +DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1) > +DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4) > DEF(MVFR0_EL1, 3, 0, 0, 3, 0) > DEF(MVFR1_EL1, 3, 0, 0, 3, 1) > DEF(MVFR2_EL1, 3, 0, 0, 3, 2) > -DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4) > -DEF(ID_DFR1_EL1, 3, 0, 0, 3, 5) > -DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6) > -DEF(CLIDR_EL1, 3, 1, 0, 0, 1) > -DEF(ID_AA64ZFR0_EL1, 3, 0, 0, 4, 4) > -DEF(CTR_EL0, 3, 3, 0, 0, 1) > -DEF(DCZID_EL0, 3, 3, 0, 0, 7) > -- > 2.53.0 ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v4 02/17] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order 2026-05-06 16:10 ` Shameer Kolothum Thodi @ 2026-05-12 6:24 ` Eric Auger 0 siblings, 0 replies; 39+ messages in thread From: Eric Auger @ 2026-05-12 6:24 UTC (permalink / raw) To: Shameer Kolothum Thodi, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com Hi Shameer, On 5/6/26 6:10 PM, Shameer Kolothum Thodi wrote: > >> -----Original Message----- >> From: Eric Auger <eric.auger@redhat.com> >> Sent: 03 May 2026 08:33 >> 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; >> cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi >> <skolothumtho@nvidia.com>; philmd@linaro.org >> Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; >> armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; >> jdenemar@redhat.com >> Subject: [PATCH v4 02/17] target/arm/cpu-sysregs.h.inc: Sort by name >> alphabetical order >> >> External email: Use caution opening links or attachments >> >> >> target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order >> >> Sort by register name alphabetical order. This will allow to >> easily diff with the future content, automatically generated. >> >> No functional change intended. >> >> Signed-off-by: Eric Auger <eric.auger@redhat.com> >> Signed-off-by: Cornelia Huck <cohuck@redhat.com> >> Message-ID: <20251208163751.611186-3-eric.auger@redhat.com> >> --- >> target/arm/cpu-sysregs.h.inc | 43 ++++++++++++++++++------------------ >> 1 file changed, 22 insertions(+), 21 deletions(-) > Took a while to figure out the extra addition 😊 > +DEF(CCSIDR_EL1, 3, 1, 0, 0, 0) Hum I missed this spurious addition during the rebase. I will remove it as the goal was just to sort the file without adding anything. Next patch is supposed to add some new stuff. Thanks! Eric > > May be worth mentioning in commit log. > > Thanks, > Shameer > >> diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc >> index 3d1ed40f04..d61f0d0a19 100644 >> --- a/target/arm/cpu-sysregs.h.inc >> +++ b/target/arm/cpu-sysregs.h.inc >> @@ -1,12 +1,12 @@ >> /* SPDX-License-Identifier: GPL-2.0-or-later */ >> -DEF(ID_AA64PFR0_EL1, 3, 0, 0, 4, 0) >> -DEF(ID_AA64PFR1_EL1, 3, 0, 0, 4, 1) >> -DEF(ID_AA64PFR2_EL1, 3, 0, 0, 4, 2) >> -DEF(ID_AA64SMFR0_EL1, 3, 0, 0, 4, 5) >> -DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0) >> -DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1) >> +DEF(CCSIDR_EL1, 3, 1, 0, 0, 0) >> +DEF(CLIDR_EL1, 3, 1, 0, 0, 1) >> +DEF(CTR_EL0, 3, 3, 0, 0, 1) >> +DEF(DCZID_EL0, 3, 3, 0, 0, 7) >> DEF(ID_AA64AFR0_EL1, 3, 0, 0, 5, 4) >> DEF(ID_AA64AFR1_EL1, 3, 0, 0, 5, 5) >> +DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0) >> +DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1) >> DEF(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0) >> DEF(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1) >> DEF(ID_AA64ISAR2_EL1, 3, 0, 0, 6, 2) >> @@ -15,29 +15,30 @@ DEF(ID_AA64MMFR1_EL1, 3, 0, 0, 7, 1) >> DEF(ID_AA64MMFR2_EL1, 3, 0, 0, 7, 2) >> DEF(ID_AA64MMFR3_EL1, 3, 0, 0, 7, 3) >> DEF(ID_AA64MMFR4_EL1, 3, 0, 0, 7, 4) >> -DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0) >> -DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1) >> -DEF(ID_DFR0_EL1, 3, 0, 0, 1, 2) >> +DEF(ID_AA64PFR0_EL1, 3, 0, 0, 4, 0) >> +DEF(ID_AA64PFR1_EL1, 3, 0, 0, 4, 1) >> +DEF(ID_AA64PFR2_EL1, 3, 0, 0, 4, 2) >> +DEF(ID_AA64SMFR0_EL1, 3, 0, 0, 4, 5) >> +DEF(ID_AA64ZFR0_EL1, 3, 0, 0, 4, 4) >> DEF(ID_AFR0_EL1, 3, 0, 0, 1, 3) >> -DEF(ID_MMFR0_EL1, 3, 0, 0, 1, 4) >> -DEF(ID_MMFR1_EL1, 3, 0, 0, 1, 5) >> -DEF(ID_MMFR2_EL1, 3, 0, 0, 1, 6) >> -DEF(ID_MMFR3_EL1, 3, 0, 0, 1, 7) >> +DEF(ID_DFR0_EL1, 3, 0, 0, 1, 2) >> +DEF(ID_DFR1_EL1, 3, 0, 0, 3, 5) >> DEF(ID_ISAR0_EL1, 3, 0, 0, 2, 0) >> DEF(ID_ISAR1_EL1, 3, 0, 0, 2, 1) >> DEF(ID_ISAR2_EL1, 3, 0, 0, 2, 2) >> DEF(ID_ISAR3_EL1, 3, 0, 0, 2, 3) >> DEF(ID_ISAR4_EL1, 3, 0, 0, 2, 4) >> DEF(ID_ISAR5_EL1, 3, 0, 0, 2, 5) >> -DEF(ID_MMFR4_EL1, 3, 0, 0, 2, 6) >> DEF(ID_ISAR6_EL1, 3, 0, 0, 2, 7) >> +DEF(ID_MMFR0_EL1, 3, 0, 0, 1, 4) >> +DEF(ID_MMFR1_EL1, 3, 0, 0, 1, 5) >> +DEF(ID_MMFR2_EL1, 3, 0, 0, 1, 6) >> +DEF(ID_MMFR3_EL1, 3, 0, 0, 1, 7) >> +DEF(ID_MMFR4_EL1, 3, 0, 0, 2, 6) >> +DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6) >> +DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0) >> +DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1) >> +DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4) >> DEF(MVFR0_EL1, 3, 0, 0, 3, 0) >> DEF(MVFR1_EL1, 3, 0, 0, 3, 1) >> DEF(MVFR2_EL1, 3, 0, 0, 3, 2) >> -DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4) >> -DEF(ID_DFR1_EL1, 3, 0, 0, 3, 5) >> -DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6) >> -DEF(CLIDR_EL1, 3, 1, 0, 0, 1) >> -DEF(ID_AA64ZFR0_EL1, 3, 0, 0, 4, 4) >> -DEF(CTR_EL0, 3, 3, 0, 0, 1) >> -DEF(DCZID_EL0, 3, 3, 0, 0, 7) >> -- >> 2.53.0 ^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v4 03/17] target/arm/cpu-sysregs.h.inc: Update with automatic generation 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger 2026-05-03 7:33 ` [PATCH v4 01/17] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py Eric Auger 2026-05-03 7:33 ` [PATCH v4 02/17] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-07 8:45 ` Shameer Kolothum Thodi 2026-05-03 7:33 ` [PATCH v4 04/17] arm/cpu: Add infra to handle generated ID register definitions Eric Auger ` (14 subsequent siblings) 17 siblings, 1 reply; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar Generated definitions with scripts/update-aarch64-cpu-sysregs-header.py based on "AARCHMRS containing the JSON files for Arm A-profile architecture (2026-03)" Registers.json file. Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> Message-ID: <20251208163751.611186-4-eric.auger@redhat.com> --- target/arm/cpu-sysregs.h.inc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc index d61f0d0a19..2188cd7be0 100644 --- a/target/arm/cpu-sysregs.h.inc +++ b/target/arm/cpu-sysregs.h.inc @@ -1,15 +1,25 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* This file is autogenerated by scripts/update-aarch64-cpu-sysregs-header.py */ +/* DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>) */ + +DEF(AIDR_EL1, 3, 1, 0, 0, 7) +DEF(CCSIDR2_EL1, 3, 1, 0, 0, 2) DEF(CCSIDR_EL1, 3, 1, 0, 0, 0) DEF(CLIDR_EL1, 3, 1, 0, 0, 1) DEF(CTR_EL0, 3, 3, 0, 0, 1) DEF(DCZID_EL0, 3, 3, 0, 0, 7) +DEF(GMID_EL1, 3, 1, 0, 0, 4) DEF(ID_AA64AFR0_EL1, 3, 0, 0, 5, 4) DEF(ID_AA64AFR1_EL1, 3, 0, 0, 5, 5) DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0) DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1) +DEF(ID_AA64DFR2_EL1, 3, 0, 0, 5, 2) +DEF(ID_AA64FPFR0_EL1, 3, 0, 0, 4, 7) DEF(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0) DEF(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1) DEF(ID_AA64ISAR2_EL1, 3, 0, 0, 6, 2) +DEF(ID_AA64ISAR3_EL1, 3, 0, 0, 6, 3) DEF(ID_AA64MMFR0_EL1, 3, 0, 0, 7, 0) DEF(ID_AA64MMFR1_EL1, 3, 0, 0, 7, 1) DEF(ID_AA64MMFR2_EL1, 3, 0, 0, 7, 2) @@ -39,6 +49,10 @@ DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6) DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0) DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1) DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4) +DEF(MIDR_EL1, 3, 0, 0, 0, 0) +DEF(MPIDR_EL1, 3, 0, 0, 0, 5) DEF(MVFR0_EL1, 3, 0, 0, 3, 0) DEF(MVFR1_EL1, 3, 0, 0, 3, 1) DEF(MVFR2_EL1, 3, 0, 0, 3, 2) +DEF(REVIDR_EL1, 3, 0, 0, 0, 6) +DEF(SMIDR_EL1, 3, 1, 0, 0, 6) -- 2.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* RE: [PATCH v4 03/17] target/arm/cpu-sysregs.h.inc: Update with automatic generation 2026-05-03 7:33 ` [PATCH v4 03/17] target/arm/cpu-sysregs.h.inc: Update with automatic generation Eric Auger @ 2026-05-07 8:45 ` Shameer Kolothum Thodi 2026-05-12 6:38 ` Eric Auger 0 siblings, 1 reply; 39+ messages in thread From: Shameer Kolothum Thodi @ 2026-05-07 8:45 UTC (permalink / raw) To: Eric Auger, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com > -----Original Message----- > From: Eric Auger <eric.auger@redhat.com> > Sent: 03 May 2026 08:33 > 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; > cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi > <skolothumtho@nvidia.com>; philmd@linaro.org > Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; > armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; > jdenemar@redhat.com > Subject: [PATCH v4 03/17] target/arm/cpu-sysregs.h.inc: Update with > automatic generation > > External email: Use caution opening links or attachments > > > Generated definitions with scripts/update-aarch64-cpu-sysregs-header.py > based on "AARCHMRS containing the JSON files for Arm A-profile > architecture (2026-03)" Registers.json file. > > Signed-off-by: Eric Auger <eric.auger@redhat.com> > Signed-off-by: Cornelia Huck <cohuck@redhat.com> > Message-ID: <20251208163751.611186-4-eric.auger@redhat.com> > --- > target/arm/cpu-sysregs.h.inc | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > > diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc > index d61f0d0a19..2188cd7be0 100644 > --- a/target/arm/cpu-sysregs.h.inc > +++ b/target/arm/cpu-sysregs.h.inc > @@ -1,15 +1,25 @@ > /* SPDX-License-Identifier: GPL-2.0-or-later */ > + > +/* This file is autogenerated by scripts/update-aarch64-cpu-sysregs- > header.py */ > +/* DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>) */ > + > +DEF(AIDR_EL1, 3, 1, 0, 0, 7) > +DEF(CCSIDR2_EL1, 3, 1, 0, 0, 2) > DEF(CCSIDR_EL1, 3, 1, 0, 0, 0) > DEF(CLIDR_EL1, 3, 1, 0, 0, 1) > DEF(CTR_EL0, 3, 3, 0, 0, 1) > DEF(DCZID_EL0, 3, 3, 0, 0, 7) > +DEF(GMID_EL1, 3, 1, 0, 0, 4) > DEF(ID_AA64AFR0_EL1, 3, 0, 0, 5, 4) > DEF(ID_AA64AFR1_EL1, 3, 0, 0, 5, 5) > DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0) > DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1) > +DEF(ID_AA64DFR2_EL1, 3, 0, 0, 5, 2) > +DEF(ID_AA64FPFR0_EL1, 3, 0, 0, 4, 7) > DEF(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0) > DEF(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1) > DEF(ID_AA64ISAR2_EL1, 3, 0, 0, 6, 2) > +DEF(ID_AA64ISAR3_EL1, 3, 0, 0, 6, 3) > DEF(ID_AA64MMFR0_EL1, 3, 0, 0, 7, 0) > DEF(ID_AA64MMFR1_EL1, 3, 0, 0, 7, 1) > DEF(ID_AA64MMFR2_EL1, 3, 0, 0, 7, 2) > @@ -39,6 +49,10 @@ DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6) > DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0) > DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1) > DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4) > +DEF(MIDR_EL1, 3, 0, 0, 0, 0) > +DEF(MPIDR_EL1, 3, 0, 0, 0, 5) Do we need MPIDR_EL1 as well? Is this considered as a feature ID register and is writable? I don't think so. Thanks, Shameer > DEF(MVFR0_EL1, 3, 0, 0, 3, 0) > DEF(MVFR1_EL1, 3, 0, 0, 3, 1) > DEF(MVFR2_EL1, 3, 0, 0, 3, 2) > +DEF(REVIDR_EL1, 3, 0, 0, 0, 6) > +DEF(SMIDR_EL1, 3, 1, 0, 0, 6) > -- > 2.53.0 ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v4 03/17] target/arm/cpu-sysregs.h.inc: Update with automatic generation 2026-05-07 8:45 ` Shameer Kolothum Thodi @ 2026-05-12 6:38 ` Eric Auger 2026-05-12 9:41 ` Shameer Kolothum Thodi 0 siblings, 1 reply; 39+ messages in thread From: Eric Auger @ 2026-05-12 6:38 UTC (permalink / raw) To: Shameer Kolothum Thodi, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com Hi Shameer, On 5/7/26 10:45 AM, Shameer Kolothum Thodi wrote: > >> -----Original Message----- >> From: Eric Auger <eric.auger@redhat.com> >> Sent: 03 May 2026 08:33 >> 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; >> cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi >> <skolothumtho@nvidia.com>; philmd@linaro.org >> Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; >> armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; >> jdenemar@redhat.com >> Subject: [PATCH v4 03/17] target/arm/cpu-sysregs.h.inc: Update with >> automatic generation >> >> External email: Use caution opening links or attachments >> >> >> Generated definitions with scripts/update-aarch64-cpu-sysregs-header.py >> based on "AARCHMRS containing the JSON files for Arm A-profile >> architecture (2026-03)" Registers.json file. >> >> Signed-off-by: Eric Auger <eric.auger@redhat.com> >> Signed-off-by: Cornelia Huck <cohuck@redhat.com> >> Message-ID: <20251208163751.611186-4-eric.auger@redhat.com> >> --- >> target/arm/cpu-sysregs.h.inc | 14 ++++++++++++++ >> 1 file changed, 14 insertions(+) >> >> diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc >> index d61f0d0a19..2188cd7be0 100644 >> --- a/target/arm/cpu-sysregs.h.inc >> +++ b/target/arm/cpu-sysregs.h.inc >> @@ -1,15 +1,25 @@ >> /* SPDX-License-Identifier: GPL-2.0-or-later */ >> + >> +/* This file is autogenerated by scripts/update-aarch64-cpu-sysregs- >> header.py */ >> +/* DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>) */ >> + >> +DEF(AIDR_EL1, 3, 1, 0, 0, 7) >> +DEF(CCSIDR2_EL1, 3, 1, 0, 0, 2) >> DEF(CCSIDR_EL1, 3, 1, 0, 0, 0) >> DEF(CLIDR_EL1, 3, 1, 0, 0, 1) >> DEF(CTR_EL0, 3, 3, 0, 0, 1) >> DEF(DCZID_EL0, 3, 3, 0, 0, 7) >> +DEF(GMID_EL1, 3, 1, 0, 0, 4) >> DEF(ID_AA64AFR0_EL1, 3, 0, 0, 5, 4) >> DEF(ID_AA64AFR1_EL1, 3, 0, 0, 5, 5) >> DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0) >> DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1) >> +DEF(ID_AA64DFR2_EL1, 3, 0, 0, 5, 2) >> +DEF(ID_AA64FPFR0_EL1, 3, 0, 0, 4, 7) >> DEF(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0) >> DEF(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1) >> DEF(ID_AA64ISAR2_EL1, 3, 0, 0, 6, 2) >> +DEF(ID_AA64ISAR3_EL1, 3, 0, 0, 6, 3) >> DEF(ID_AA64MMFR0_EL1, 3, 0, 0, 7, 0) >> DEF(ID_AA64MMFR1_EL1, 3, 0, 0, 7, 1) >> DEF(ID_AA64MMFR2_EL1, 3, 0, 0, 7, 2) >> @@ -39,6 +49,10 @@ DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6) >> DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0) >> DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1) >> DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4) >> +DEF(MIDR_EL1, 3, 0, 0, 0, 0) >> +DEF(MPIDR_EL1, 3, 0, 0, 0, 5) > Do we need MPIDR_EL1 as well? Is this considered as a feature ID > register and is writable? I don't think so. MPIDR_EL1 is part of the ID regs range defined in the kernel doc op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7] That's why the python script extracts it. Effectively it is not writable yet. I can exclude it from the automatic generation but do we really need to? Any specific reason? Thanks Eric > Thanks, > Shameer > >> DEF(MVFR0_EL1, 3, 0, 0, 3, 0) >> DEF(MVFR1_EL1, 3, 0, 0, 3, 1) >> DEF(MVFR2_EL1, 3, 0, 0, 3, 2) >> +DEF(REVIDR_EL1, 3, 0, 0, 0, 6) >> +DEF(SMIDR_EL1, 3, 1, 0, 0, 6) >> -- >> 2.53.0 ^ permalink raw reply [flat|nested] 39+ messages in thread
* RE: [PATCH v4 03/17] target/arm/cpu-sysregs.h.inc: Update with automatic generation 2026-05-12 6:38 ` Eric Auger @ 2026-05-12 9:41 ` Shameer Kolothum Thodi 2026-05-12 14:11 ` Eric Auger 0 siblings, 1 reply; 39+ messages in thread From: Shameer Kolothum Thodi @ 2026-05-12 9:41 UTC (permalink / raw) To: eric.auger@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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com > -----Original Message----- > From: Eric Auger <eric.auger@redhat.com> > Sent: 12 May 2026 07:39 > To: Shameer Kolothum Thodi <skolothumtho@nvidia.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; cohuck@redhat.com; sebott@redhat.com; > philmd@linaro.org > Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; > armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; > jdenemar@redhat.com > Subject: Re: [PATCH v4 03/17] target/arm/cpu-sysregs.h.inc: Update with > automatic generation > [...] > >> +DEF(MPIDR_EL1, 3, 0, 0, 0, 5) > > Do we need MPIDR_EL1 as well? Is this considered as a feature ID > > register and is writable? I don't think so. > MPIDR_EL1 is part of the ID regs range defined in the kernel doc > > op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7] > > That's why the python script extracts it. Effectively it is not writable yet. > > I can exclude it from the automatic generation but do we really need to? Any > specific reason? No specific reason. The only thing is it's not really a feature ID register but a topology register and is not writable now. I leave that to you. Thanks, Shameer ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v4 03/17] target/arm/cpu-sysregs.h.inc: Update with automatic generation 2026-05-12 9:41 ` Shameer Kolothum Thodi @ 2026-05-12 14:11 ` Eric Auger 0 siblings, 0 replies; 39+ messages in thread From: Eric Auger @ 2026-05-12 14:11 UTC (permalink / raw) To: Shameer Kolothum Thodi, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com Hi Shameer, On 5/12/26 11:41 AM, Shameer Kolothum Thodi wrote: > >> -----Original Message----- >> From: Eric Auger <eric.auger@redhat.com> >> Sent: 12 May 2026 07:39 >> To: Shameer Kolothum Thodi <skolothumtho@nvidia.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; cohuck@redhat.com; sebott@redhat.com; >> philmd@linaro.org >> Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; >> armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; >> jdenemar@redhat.com >> Subject: Re: [PATCH v4 03/17] target/arm/cpu-sysregs.h.inc: Update with >> automatic generation >> > [...] > >>>> +DEF(MPIDR_EL1, 3, 0, 0, 0, 5) >>> Do we need MPIDR_EL1 as well? Is this considered as a feature ID >>> register and is writable? I don't think so. >> MPIDR_EL1 is part of the ID regs range defined in the kernel doc >> >> op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7] >> >> That's why the python script extracts it. Effectively it is not writable yet. >> >> I can exclude it from the automatic generation but do we really need to? Any >> specific reason? > No specific reason. The only thing is it's not really a feature ID register but > a topology register and is not writable now. I leave that to you. noted. I leave it as is for now and we will decide upon further reviews. Thanks Eric > > Thanks, > Shameer > ^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v4 04/17] arm/cpu: Add infra to handle generated ID register definitions 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger ` (2 preceding siblings ...) 2026-05-03 7:33 ` [PATCH v4 03/17] target/arm/cpu-sysregs.h.inc: Update with automatic generation Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-07 8:58 ` Shameer Kolothum Thodi 2026-05-03 7:33 ` [PATCH v4 05/17] scripts: Introduce scripts/aarch64_sysreg_helpers module Eric Auger ` (13 subsequent siblings) 17 siblings, 1 reply; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar The known ID regs are populated in a new initialization function named initialize_cpu_sysreg_properties(). That code will be automatically generated from AARCHMRS Registers.json. 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-idregs.h | 59 ++++++++++++++++++++++++++++++ target/arm/cpu-sysreg-properties.c | 30 +++++++++++++++ target/arm/cpu64.c | 3 ++ target/arm/meson.build | 3 +- 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 target/arm/cpu-idregs.h create mode 100644 target/arm/cpu-sysreg-properties.c diff --git a/target/arm/cpu-idregs.h b/target/arm/cpu-idregs.h new file mode 100644 index 0000000000..4a9034594d --- /dev/null +++ b/target/arm/cpu-idregs.h @@ -0,0 +1,59 @@ +/* + * 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 */ + ARMIDRegisterIdx index; /* parent register, e.g. CTR_EL0_IDX */ + int lower; /* lowest bit number of the field in the register */ + int upper; /* highest bit number */ +} ARM64SysRegField; + +typedef struct ARM64SysReg { + const char *name; /* name of the sysreg, for instance CTR_EL0 */ + ARMSysRegs sysreg; + ARMIDRegisterIdx index; /* register index, e.g. CTR_EL0_IDX */ + GList *fields; /* list of named fields, excluding RES* */ +} ARM64SysReg; + +void initialize_cpu_sysreg_properties(void); + +/* + * List of exposed ID regs (automatically populated from AARCHMRS Registers.json) + */ +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 0000000000..5cc06c8f24 --- /dev/null +++ b/target/arm/cpu-sysreg-properties.c @@ -0,0 +1,30 @@ +/* + * QEMU ARM CPU SYSREG PROPERTIES + * will be automatically generated + * + * Copyright (c) Red Hat, Inc. 2026 + * + */ + + /* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "cpu-idregs.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 a93ad2da5a..b940842d9e 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -37,6 +37,7 @@ #include "hw/core/qdev-properties.h" #include "internals.h" #include "cpu-features.h" +#include "cpu-idregs.h" /* convert between <register>_IDX and SYS_<register> */ #define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \ @@ -906,6 +907,8 @@ static void aarch64_cpu_register_types(void) { size_t i; + initialize_cpu_sysreg_properties(); + for (i = 0; i < ARRAY_SIZE(aarch64_cpus); ++i) { arm_cpu_register(&aarch64_cpus[i]); } diff --git a/target/arm/meson.build b/target/arm/meson.build index 192ac7c31e..e2f740e48f 100644 --- a/target/arm/meson.build +++ b/target/arm/meson.build @@ -9,7 +9,8 @@ arm_user_ss.add(files('gdbstub.c')) arm_ss.add(when: 'TARGET_AARCH64', if_true: files( 'cpu64.c', - 'gdbstub64.c' + 'gdbstub64.c', + 'cpu-sysreg-properties.c', )) arm_common_ss.add(files( -- 2.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* RE: [PATCH v4 04/17] arm/cpu: Add infra to handle generated ID register definitions 2026-05-03 7:33 ` [PATCH v4 04/17] arm/cpu: Add infra to handle generated ID register definitions Eric Auger @ 2026-05-07 8:58 ` Shameer Kolothum Thodi 2026-05-12 14:52 ` Eric Auger 0 siblings, 1 reply; 39+ messages in thread From: Shameer Kolothum Thodi @ 2026-05-07 8:58 UTC (permalink / raw) To: Eric Auger, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com > -----Original Message----- > From: Eric Auger <eric.auger@redhat.com> > Sent: 03 May 2026 08:33 > 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; > cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi > <skolothumtho@nvidia.com>; philmd@linaro.org > Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; > armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; > jdenemar@redhat.com > Subject: [PATCH v4 04/17] arm/cpu: Add infra to handle generated ID register > definitions > > External email: Use caution opening links or attachments > > > The known ID regs are populated in a new initialization function > named initialize_cpu_sysreg_properties(). That code will be > automatically generated from AARCHMRS Registers.json. 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-idregs.h | 59 ++++++++++++++++++++++++++++++ > target/arm/cpu-sysreg-properties.c | 30 +++++++++++++++ > target/arm/cpu64.c | 3 ++ > target/arm/meson.build | 3 +- > 4 files changed, 94 insertions(+), 1 deletion(-) > create mode 100644 target/arm/cpu-idregs.h > create mode 100644 target/arm/cpu-sysreg-properties.c > > diff --git a/target/arm/cpu-idregs.h b/target/arm/cpu-idregs.h > new file mode 100644 > index 0000000000..4a9034594d > --- /dev/null > +++ b/target/arm/cpu-idregs.h > @@ -0,0 +1,59 @@ > +/* > + * handle ID registers and their fields > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > +#ifndef ARM_CPU_CUSTOM_H > +#define ARM_CPU_CUSTOM_H ARM_CPU_IDREGS_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 */ > + ARMIDRegisterIdx index; /* parent register, e.g. CTR_EL0_IDX */ > + int lower; /* lowest bit number of the field in the register */ > + int upper; /* highest bit number */ > +} ARM64SysRegField; > + > +typedef struct ARM64SysReg { > + const char *name; /* name of the sysreg, for instance CTR_EL0 */ > + ARMSysRegs sysreg; > + ARMIDRegisterIdx index; /* register index, e.g. CTR_EL0_IDX */ > + GList *fields; /* list of named fields, excluding RES* */ > +} ARM64SysReg; > + > +void initialize_cpu_sysreg_properties(void); > + > +/* > + * List of exposed ID regs (automatically populated from AARCHMRS > Registers.json) > + */ > +extern ARM64SysReg arm64_id_regs[NUM_ID_IDX]; > + > +/* Allocate a new field and insert it at the head of the @reg list */ It says insert at the head... > +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); But this is adding to the tail, right? > + return reg->fields; Don't think the return is used anywhere. Thanks, Shameer > +} > + > +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 0000000000..5cc06c8f24 > --- /dev/null > +++ b/target/arm/cpu-sysreg-properties.c > @@ -0,0 +1,30 @@ > +/* > + * QEMU ARM CPU SYSREG PROPERTIES > + * will be automatically generated > + * > + * Copyright (c) Red Hat, Inc. 2026 > + * > + */ > + > + /* SPDX-License-Identifier: GPL-2.0-or-later */ > + > +#include "cpu-idregs.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 a93ad2da5a..b940842d9e 100644 > --- a/target/arm/cpu64.c > +++ b/target/arm/cpu64.c > @@ -37,6 +37,7 @@ > #include "hw/core/qdev-properties.h" > #include "internals.h" > #include "cpu-features.h" > +#include "cpu-idregs.h" > > /* convert between <register>_IDX and SYS_<register> */ > #define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \ > @@ -906,6 +907,8 @@ static void aarch64_cpu_register_types(void) > { > size_t i; > > + initialize_cpu_sysreg_properties(); > + > for (i = 0; i < ARRAY_SIZE(aarch64_cpus); ++i) { > arm_cpu_register(&aarch64_cpus[i]); > } > diff --git a/target/arm/meson.build b/target/arm/meson.build > index 192ac7c31e..e2f740e48f 100644 > --- a/target/arm/meson.build > +++ b/target/arm/meson.build > @@ -9,7 +9,8 @@ arm_user_ss.add(files('gdbstub.c')) > > arm_ss.add(when: 'TARGET_AARCH64', if_true: files( > 'cpu64.c', > - 'gdbstub64.c' > + 'gdbstub64.c', > + 'cpu-sysreg-properties.c', > )) > > arm_common_ss.add(files( > -- > 2.53.0 ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v4 04/17] arm/cpu: Add infra to handle generated ID register definitions 2026-05-07 8:58 ` Shameer Kolothum Thodi @ 2026-05-12 14:52 ` Eric Auger 0 siblings, 0 replies; 39+ messages in thread From: Eric Auger @ 2026-05-12 14:52 UTC (permalink / raw) To: Shameer Kolothum Thodi, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com On 5/7/26 10:58 AM, Shameer Kolothum Thodi wrote: > >> -----Original Message----- >> From: Eric Auger <eric.auger@redhat.com> >> Sent: 03 May 2026 08:33 >> 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; >> cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi >> <skolothumtho@nvidia.com>; philmd@linaro.org >> Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; >> armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; >> jdenemar@redhat.com >> Subject: [PATCH v4 04/17] arm/cpu: Add infra to handle generated ID register >> definitions >> >> External email: Use caution opening links or attachments >> >> >> The known ID regs are populated in a new initialization function >> named initialize_cpu_sysreg_properties(). That code will be >> automatically generated from AARCHMRS Registers.json. 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-idregs.h | 59 ++++++++++++++++++++++++++++++ >> target/arm/cpu-sysreg-properties.c | 30 +++++++++++++++ >> target/arm/cpu64.c | 3 ++ >> target/arm/meson.build | 3 +- >> 4 files changed, 94 insertions(+), 1 deletion(-) >> create mode 100644 target/arm/cpu-idregs.h >> create mode 100644 target/arm/cpu-sysreg-properties.c >> >> diff --git a/target/arm/cpu-idregs.h b/target/arm/cpu-idregs.h >> new file mode 100644 >> index 0000000000..4a9034594d >> --- /dev/null >> +++ b/target/arm/cpu-idregs.h >> @@ -0,0 +1,59 @@ >> +/* >> + * handle ID registers and their fields >> + * >> + * SPDX-License-Identifier: GPL-2.0-or-later >> + */ >> +#ifndef ARM_CPU_CUSTOM_H >> +#define ARM_CPU_CUSTOM_H > ARM_CPU_IDREGS_H ? indeed: TARGET_ARM_CPU_IDREGS__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 */ >> + ARMIDRegisterIdx index; /* parent register, e.g. CTR_EL0_IDX */ >> + int lower; /* lowest bit number of the field in the register */ >> + int upper; /* highest bit number */ >> +} ARM64SysRegField; >> + >> +typedef struct ARM64SysReg { >> + const char *name; /* name of the sysreg, for instance CTR_EL0 */ >> + ARMSysRegs sysreg; >> + ARMIDRegisterIdx index; /* register index, e.g. CTR_EL0_IDX */ >> + GList *fields; /* list of named fields, excluding RES* */ >> +} ARM64SysReg; >> + >> +void initialize_cpu_sysreg_properties(void); >> + >> +/* >> + * List of exposed ID regs (automatically populated from AARCHMRS >> Registers.json) >> + */ >> +extern ARM64SysReg arm64_id_regs[NUM_ID_IDX]; >> + >> +/* Allocate a new field and insert it at the head of the @reg list */ > It says insert at the head... > >> +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); > But this is adding to the tail, right? indeed use prepend instead > >> + return reg->fields; > Don't think the return is used anywhere. now becoming static inline void arm64_sysreg_add_field() Thanks Eric > > Thanks, > Shameer > >> +} >> + >> +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 0000000000..5cc06c8f24 >> --- /dev/null >> +++ b/target/arm/cpu-sysreg-properties.c >> @@ -0,0 +1,30 @@ >> +/* >> + * QEMU ARM CPU SYSREG PROPERTIES >> + * will be automatically generated >> + * >> + * Copyright (c) Red Hat, Inc. 2026 >> + * >> + */ >> + >> + /* SPDX-License-Identifier: GPL-2.0-or-later */ >> + >> +#include "cpu-idregs.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 a93ad2da5a..b940842d9e 100644 >> --- a/target/arm/cpu64.c >> +++ b/target/arm/cpu64.c >> @@ -37,6 +37,7 @@ >> #include "hw/core/qdev-properties.h" >> #include "internals.h" >> #include "cpu-features.h" >> +#include "cpu-idregs.h" >> >> /* convert between <register>_IDX and SYS_<register> */ >> #define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \ >> @@ -906,6 +907,8 @@ static void aarch64_cpu_register_types(void) >> { >> size_t i; >> >> + initialize_cpu_sysreg_properties(); >> + >> for (i = 0; i < ARRAY_SIZE(aarch64_cpus); ++i) { >> arm_cpu_register(&aarch64_cpus[i]); >> } >> diff --git a/target/arm/meson.build b/target/arm/meson.build >> index 192ac7c31e..e2f740e48f 100644 >> --- a/target/arm/meson.build >> +++ b/target/arm/meson.build >> @@ -9,7 +9,8 @@ arm_user_ss.add(files('gdbstub.c')) >> >> arm_ss.add(when: 'TARGET_AARCH64', if_true: files( >> 'cpu64.c', >> - 'gdbstub64.c' >> + 'gdbstub64.c', >> + 'cpu-sysreg-properties.c', >> )) >> >> arm_common_ss.add(files( >> -- >> 2.53.0 ^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v4 05/17] scripts: Introduce scripts/aarch64_sysreg_helpers module 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger ` (3 preceding siblings ...) 2026-05-03 7:33 ` [PATCH v4 04/17] arm/cpu: Add infra to handle generated ID register definitions Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-03 7:33 ` [PATCH v4 06/17] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py Eric Auger ` (12 subsequent siblings) 17 siblings, 0 replies; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar We plan to reuse get_opcode() and extract_idregs_from_registers_json() functions in another script. So let's move them into a module No functional change intended. Signed-off-by: Eric Auger <eric.auger@redhat.com> --- scripts/aarch64_sysreg_helpers.py | 109 +++++++++++++++++++ scripts/update-aarch64-cpu-sysregs-header.py | 85 +-------------- 2 files changed, 110 insertions(+), 84 deletions(-) create mode 100644 scripts/aarch64_sysreg_helpers.py diff --git a/scripts/aarch64_sysreg_helpers.py b/scripts/aarch64_sysreg_helpers.py new file mode 100644 index 0000000000..dd5ec4bafa --- /dev/null +++ b/scripts/aarch64_sysreg_helpers.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 + +# Helpers used in aarch64 sysreg definition generation +# +# Copyright (C) 2026 Red Hat, Inc. +# +# Authors: Eric Auger <eric.auger@redhat.com> +# +# SPDX-License-Identifier: GPL-2.0-or-later + + +import json +import os + +# Some regs have op code values like 000x, 001x. Anyway we don't need +# them. Besides some regs are undesired in the generated file such as +# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we +# are interested in and are tricky to decode as their system accessor +# refer to MPIDR_EL1/MIDR_EL1 respectively + +skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \ + 'VMPIDR_EL2', 'VPIDR_EL2'] + +# returns the int value of a given @opcode for a reg @encoding +def get_opcode(encoding, opcode): + fvalue = encoding.get(opcode) + if fvalue: + value = fvalue.get('value') + if isinstance(value, str): + value = value.strip("'") + value = int(value, 2) + return value + return -1 + +def extract_idregs_from_registers_json(filename): + """ + Load a Registers.json file and extract all ID registers, decode their + opcode and dump the information in target/arm/cpu-sysregs.h.inc + + Args: + filename (str): The path to the Registers.json + returns: + idregs: list of ID regs and their encoding + """ + if not os.path.exists(filename): + print(f"Error: {filename} could not be found!") + return {} + + try: + with open(filename, 'r') as f: + register_data = json.load(f) + + except json.JSONDecodeError: + print(f"Could not decode json from '{filename}'!") + return {} + except Exception as e: + print(f"Unexpected error while reading {filename}: {e}") + return {} + + registers = [r for r in register_data if isinstance(r, dict) and \ + r.get('_type') == 'Register'] + + idregs = {} + + # Some regs have op code values like 000x, 001x. Anyway we don't need + # them. Besides some regs are undesired in the generated file such as + # VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we + # are interested in and are tricky to decode as their system accessor + # refer to MPIDR_EL1/MIDR_EL1 respectively + + skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \ + 'VMPIDR_EL2', 'VPIDR_EL2'] + + for register in registers: + reg_name = register.get('name') + + is_skipped = any(term in (reg_name or "").upper() for term in skiplist) + + if reg_name and not is_skipped: + accessors = register.get('accessors', []) + + for accessor in accessors: + type = accessor.get('_type') + if type in ['Accessors.SystemAccessor']: + encoding_list = accessor.get('encoding') + + if isinstance(encoding_list, list) and encoding_list and \ + isinstance(encoding_list[0], dict): + encoding_wrapper = encoding_list[0] + encoding_source = encoding_wrapper.get('encodings', \ + encoding_wrapper) + + if isinstance(encoding_source, dict): + op0 = get_opcode(encoding_source, 'op0') + op1 = get_opcode(encoding_source, 'op1') + op2 = get_opcode(encoding_source, 'op2') + crn = get_opcode(encoding_source, 'CRn') + crm = get_opcode(encoding_source, 'CRm') + encoding_str=f"{op0} {op1} {crn} {crm} {op2}" + + # ID regs are assumed within this scope + if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \ + crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7): + idregs[reg_name] = encoding_str + + return idregs + + + diff --git a/scripts/update-aarch64-cpu-sysregs-header.py b/scripts/update-aarch64-cpu-sysregs-header.py index 8c337147dd..43107264e9 100755 --- a/scripts/update-aarch64-cpu-sysregs-header.py +++ b/scripts/update-aarch64-cpu-sysregs-header.py @@ -17,90 +17,7 @@ import json import os import sys - -# Some regs have op code values like 000x, 001x. Anyway we don't need -# them. Besides some regs are undesired in the generated file such as -# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we -# are interested in and are tricky to decode as their system accessor -# refer to MPIDR_EL1/MIDR_EL1 respectively - -skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \ - 'VMPIDR_EL2', 'VPIDR_EL2'] - -# returns the int value of a given @opcode for a reg @encoding -def get_opcode(encoding, opcode): - fvalue = encoding.get(opcode) - if fvalue: - value = fvalue.get('value') - if isinstance(value, str): - value = value.strip("'") - value = int(value, 2) - return value - return -1 - -def extract_idregs_from_registers_json(filename): - """ - Load a Registers.json file and extract all ID registers, decode their - opcode and dump the information in target/arm/cpu-sysregs.h.inc - - Args: - filename (str): The path to the Registers.json - returns: - idregs: list of ID regs and their encoding - """ - if not os.path.exists(filename): - print(f"Error: {filename} could not be found!") - return {} - - try: - with open(filename, 'r') as f: - register_data = json.load(f) - - except json.JSONDecodeError: - print(f"Could not decode json from '{filename}'!") - return {} - except Exception as e: - print(f"Unexpected error while reading {filename}: {e}") - return {} - - registers = [r for r in register_data if isinstance(r, dict) and \ - r.get('_type') == 'Register'] - - idregs = {} - - for register in registers: - reg_name = register.get('name') - - is_skipped = any(term in (reg_name or "").upper() for term in skiplist) - - if reg_name and not is_skipped: - accessors = register.get('accessors', []) - - for accessor in accessors: - type = accessor.get('_type') - if type in ['Accessors.SystemAccessor']: - encoding_list = accessor.get('encoding') - - if isinstance(encoding_list, list) and encoding_list and \ - isinstance(encoding_list[0], dict): - encoding_wrapper = encoding_list[0] - encoding_source = encoding_wrapper.get('encodings', \ - encoding_wrapper) - - if isinstance(encoding_source, dict): - op0 = get_opcode(encoding_source, 'op0') - op1 = get_opcode(encoding_source, 'op1') - op2 = get_opcode(encoding_source, 'op2') - crn = get_opcode(encoding_source, 'CRn') - crm = get_opcode(encoding_source, 'CRm') - encoding_str=f"{op0} {op1} {crn} {crm} {op2}" - - # ID regs are assumed within this scope - if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \ - crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7): - idregs[reg_name] = encoding_str - - return idregs +from aarch64_sysreg_helpers import extract_idregs_from_registers_json if __name__ == "__main__": # Single arg expected: the path to the Registers.json file -- 2.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* [PATCH v4 06/17] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger ` (4 preceding siblings ...) 2026-05-03 7:33 ` [PATCH v4 05/17] scripts: Introduce scripts/aarch64_sysreg_helpers module Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-03 7:33 ` [PATCH v4 07/17] target/arm/cpu-sysreg-properties.c: Generate code with new script Eric Auger ` (11 subsequent siblings) 17 siblings, 0 replies; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar Introduce a script that takes as input the Registers.json file delivered in the AARCHMRS Features Model downloadable from the Arm Developer A-Profile Architecture Exploration Tools page: https://developer.arm.com/Architectures/A-Profile%20Architecture#Downloads and automates the generation of system register properties definitions. generates target/arm/cpu-sysreg-properties.c containing definitions for feature ID registers. We only care about IDregs with opcodes satisfying: op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7] Signed-off-by: Eric Auger <eric.auger@redhat.com> --- .../update-aarch64-cpu-sysreg-properties.py | 171 ++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 scripts/update-aarch64-cpu-sysreg-properties.py diff --git a/scripts/update-aarch64-cpu-sysreg-properties.py b/scripts/update-aarch64-cpu-sysreg-properties.py new file mode 100644 index 0000000000..603faa2c80 --- /dev/null +++ b/scripts/update-aarch64-cpu-sysreg-properties.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python3 + +# This script takes as input the Registers.json file delivered in +# the AARCHMRS Features Model downloadable from the Arm Developer +# A-Profile Architecture Exploration Tools page: +# https://developer.arm.com/Architectures/A-Profile%20Architecture#Downloads +# and outputs target/arm/cpu-sysreg-properties.c content. +# There, initialize_cpu_sysreg_properties() populates arm64_id_regs array +# with the name of each ID register and definition of all its fields +# including their name and min/max bit under the form of the below pattern: +# +# /* 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); +# +# Copyright (C) 2026 Red Hat, Inc. +# +# Authors: Eric Auger <eric.auger@redhat.com> +# +# SPDX-License-Identifier: GPL-2.0-or-later + + +import json +import os +import sys +from aarch64_sysreg_helpers import extract_idregs_from_registers_json + +def collect_fields(item, bit_offset=0): + """ + Recursively finds all field-like objects, handling Fields.Array, + Fields.ArrayField, and ConditionalField structures. + Applies bit_offset from containers to child fields. + """ + fields = [] + if not isinstance(item, dict): + return fields + + _type = item.get('_type', '') + + # Array types (for example CLIDR_EL1 Ctype<n>, Ttype<n>) + if _type == 'Fields.Array': + name_template = item.get('name') or item.get('label', '') + index_info = item.get('indexes', [{}])[0] + start_idx = index_info.get('start', 0) + count = index_info.get('width', 0) + + full_range = item.get('rangeset', [{}])[0] + bit_start = full_range.get('start', 0) + bit_offset + elem_width = full_range.get('width', 0) // count if count else 0 + + for i in range(count): + idx = start_idx + i + # Correctly handle indexed names like Ctype1, Ctype2 + field_name = name_template.replace('<n>', str(idx)) + fields.append({ + 'name': field_name, + 'rangeset': [{ + 'start': bit_start + (i * elem_width), + 'width': elem_width + }], + '_type': 'Fields.Field' + }) + return fields + + # ConditionalFields + elif _type == 'Fields.ConditionalField': + inner_offset = bit_offset + if item.get('rangeset'): + # Parent container defines the absolute start bit + inner_offset = item['rangeset'][0].get('start', bit_offset) + + for entry in item.get('fields', []): + inner = entry.get('field') + if inner: + fields.extend(collect_fields(inner, inner_offset)) + return fields + + # Normal Field Types + leaf_types = ['Fields.Field', 'Fields.ConstantField', + 'Fields.EnumeratedField', 'Fields.Bitfield'] + if _type in leaf_types: + field_copy = item.copy() + if field_copy.get('rangeset'): + new_ranges = [] + for r in field_copy['rangeset']: + nr = r.copy() + # Apply the cumulative offset to the field's start bit + nr['start'] = r.get('start', 0) + bit_offset + new_ranges.append(nr) + field_copy['rangeset'] = new_ranges + fields.append(field_copy) + return fields + + # Go down the hierarchy for other cases + for key in ['fields', 'values', 'fieldsets']: + for nested in item.get(key, []): + fields.extend(collect_fields(nested, bit_offset)) + + return fields + + +def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path): + with open(raw_json_path, 'r') as f: + register_data = json.load(f) + + regs = {r.get('name'): r for r in register_data if r.get('_type') == 'Register'} + + final_output = "" + + for reg_name in id_reg_names: + register = regs.get(reg_name) + if not register: + continue + + final_output += f" /* {reg_name} */\n" + final_output += (f" ARM64SysReg *{reg_name} = " + f"arm64_sysreg_get({reg_name}_IDX);\n") + final_output += f" {reg_name}->name = \"{reg_name}\";\n" + + # Collect all fields + field_entries = [] + for fieldset in register.get('fieldsets', []): + candidates = collect_fields(fieldset) + for val in candidates: + name = (val.get('name') or val.get('label', '')).strip() + if not name or "RESERVED" in name.upper(): + continue + for r in val.get('rangeset', []): + lsb = int(r.get('start')) + msb = lsb + int(r.get('width')) - 1 + field_entries.append({'name': name, 'lsb': lsb, 'msb': msb}) + + # Sort fields by lsb (decreasing order) + field_entries.sort(key=lambda x: x['lsb'], reverse=True) + + seen_fields = set() + for entry in field_entries: + f_id = f"{entry['name']}_{entry['lsb']}_{entry['msb']}" + if f_id in seen_fields: + continue + seen_fields.add(f_id) + + line = (f" arm64_sysreg_add_field({reg_name}, " + f"\"{entry['name']}\", {entry['lsb']}, {entry['msb']});\n") + final_output += line + final_output += "\n" + + os.makedirs("target/arm", exist_ok=True) + with open("target/arm/cpu-sysreg-properties.c", 'w') as f: + f.write("/* AUTOMATICALLY GENERATED, DO NOT MODIFY */\n\n") + f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n\n") + f.write("#include \"cpu-idregs.h\"\n\n") + f.write("ARM64SysReg arm64_id_regs[NUM_ID_IDX];\n\n") + f.write("void initialize_cpu_sysreg_properties(void)\n{\n") + f.write(final_output) + f.write("}\n") + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Usage: python scripts/update-aarch64-cpu-sysreg-properties.py " + "<path_to_registers_json>") + else: + json_path = sys.argv[1] + + id_regs_dict = extract_idregs_from_registers_json(json_path) + sorted_names = sorted(id_regs_dict.keys()) + + if sorted_names: + generate_sysreg_properties_from_registers_json(sorted_names, json_path) + print("Generated target/arm/cpu-sysreg-properties.c") -- 2.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* [PATCH v4 07/17] target/arm/cpu-sysreg-properties.c: Generate code with new script 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger ` (5 preceding siblings ...) 2026-05-03 7:33 ` [PATCH v4 06/17] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-03 7:33 ` [PATCH v4 08/17] target/arm/kvm: Introduce kvm_get_writable_id_regs Eric Auger ` (10 subsequent siblings) 17 siblings, 0 replies; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar Generate the code with scripts/update-aarch64-cpu-sysreg-properties.py based on AARCHMRS_OPENSOURCE_A_profile_FAT-2026-03 Registers.json Signed-off-by: Eric Auger <eric.auger@redhat.com> --- .../update-aarch64-cpu-sysreg-properties.py | 24 +- target/arm/cpu-sysreg-properties.c | 663 +++++++++++++++++- 2 files changed, 664 insertions(+), 23 deletions(-) diff --git a/scripts/update-aarch64-cpu-sysreg-properties.py b/scripts/update-aarch64-cpu-sysreg-properties.py index 603faa2c80..b13700e73d 100644 --- a/scripts/update-aarch64-cpu-sysreg-properties.py +++ b/scripts/update-aarch64-cpu-sysreg-properties.py @@ -92,7 +92,7 @@ def collect_fields(item, bit_offset=0): fields.append(field_copy) return fields - # Go down the hierarchy for other cases + # Traverse the hierarchy for other cases for key in ['fields', 'values', 'fieldsets']: for nested in item.get(key, []): fields.extend(collect_fields(nested, bit_offset)) @@ -118,8 +118,7 @@ def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path): f"arm64_sysreg_get({reg_name}_IDX);\n") final_output += f" {reg_name}->name = \"{reg_name}\";\n" - # Collect all fields - field_entries = [] + unique_fields = {} for fieldset in register.get('fieldsets', []): candidates = collect_fields(fieldset) for val in candidates: @@ -129,20 +128,19 @@ def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path): for r in val.get('rangeset', []): lsb = int(r.get('start')) msb = lsb + int(r.get('width')) - 1 - field_entries.append({'name': name, 'lsb': lsb, 'msb': msb}) - # Sort fields by lsb (decreasing order) - field_entries.sort(key=lambda x: x['lsb'], reverse=True) + # Only keep the fields with the highest MSB + # needed fir CCSIDR_EL1 + if name not in unique_fields or msb > unique_fields[name]['msb']: + unique_fields[name] = {'lsb': lsb, 'msb': msb} - seen_fields = set() - for entry in field_entries: - f_id = f"{entry['name']}_{entry['lsb']}_{entry['msb']}" - if f_id in seen_fields: - continue - seen_fields.add(f_id) + # Sort decreasing lsbs + sorted_fields = sorted(unique_fields.items(), + key=lambda x: x[1]['lsb'], reverse=True) + for name, bits in sorted_fields: line = (f" arm64_sysreg_add_field({reg_name}, " - f"\"{entry['name']}\", {entry['lsb']}, {entry['msb']});\n") + f"\"{name}\", {bits['lsb']}, {bits['msb']});\n") final_output += line final_output += "\n" diff --git a/target/arm/cpu-sysreg-properties.c b/target/arm/cpu-sysreg-properties.c index 5cc06c8f24..4fd348557a 100644 --- a/target/arm/cpu-sysreg-properties.c +++ b/target/arm/cpu-sysreg-properties.c @@ -1,12 +1,7 @@ -/* - * QEMU ARM CPU SYSREG PROPERTIES - * will be automatically generated - * - * Copyright (c) Red Hat, Inc. 2026 - * - */ +/* AUTOMATICALLY GENERATED, DO NOT MODIFY */ + +/* SPDX-License-Identifier: GPL-2.0-or-later */ - /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "cpu-idregs.h" @@ -14,7 +9,44 @@ ARM64SysReg arm64_id_regs[NUM_ID_IDX]; void initialize_cpu_sysreg_properties(void) { - memset(arm64_id_regs, 0, sizeof(ARM64SysReg) * NUM_ID_IDX); + /* AIDR_EL1 */ + ARM64SysReg *AIDR_EL1 = arm64_sysreg_get(AIDR_EL1_IDX); + AIDR_EL1->name = "AIDR_EL1"; + + /* 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); + + /* CCSIDR_EL1 */ + ARM64SysReg *CCSIDR_EL1 = arm64_sysreg_get(CCSIDR_EL1_IDX); + CCSIDR_EL1->name = "CCSIDR_EL1"; + arm64_sysreg_add_field(CCSIDR_EL1, "NumSets", 32, 55); + arm64_sysreg_add_field(CCSIDR_EL1, "Associativity", 3, 23); + 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, "Ttype7", 45, 46); + arm64_sysreg_add_field(CLIDR_EL1, "Ttype6", 43, 44); + arm64_sysreg_add_field(CLIDR_EL1, "Ttype5", 41, 42); + arm64_sysreg_add_field(CLIDR_EL1, "Ttype4", 39, 40); + arm64_sysreg_add_field(CLIDR_EL1, "Ttype3", 37, 38); + arm64_sysreg_add_field(CLIDR_EL1, "Ttype2", 35, 36); + arm64_sysreg_add_field(CLIDR_EL1, "Ttype1", 33, 34); + 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); + /* CTR_EL0 */ ARM64SysReg *CTR_EL0 = arm64_sysreg_get(CTR_EL0_IDX); CTR_EL0->name = "CTR_EL0"; @@ -26,5 +58,616 @@ 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, "TBS", 5, 8); + arm64_sysreg_add_field(DCZID_EL0, "DZP", 4, 4); + arm64_sysreg_add_field(DCZID_EL0, "BS", 0, 3); + + /* 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); + + /* ID_AA64AFR0_EL1 */ + ARM64SysReg *ID_AA64AFR0_EL1 = arm64_sysreg_get(ID_AA64AFR0_EL1_IDX); + ID_AA64AFR0_EL1->name = "ID_AA64AFR0_EL1"; + + /* ID_AA64AFR1_EL1 */ + ARM64SysReg *ID_AA64AFR1_EL1 = arm64_sysreg_get(ID_AA64AFR1_EL1_IDX); + ID_AA64AFR1_EL1->name = "ID_AA64AFR1_EL1"; + + /* 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, "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, "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_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, "F16MM2", 15, 15); + arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8E4M3", 1, 1); + arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8E5M2", 0, 0); + + /* 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, "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, "LSCP", 44, 47); + arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "LSCSHINT", 40, 43); + arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "MTETC", 36, 39); + arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "PAC_frac2", 32, 35); + 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, "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, "MTEFGT", 60, 63); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "SCRX", 56, 59); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "TEV", 52, 55); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "TPS", 48, 51); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "SRMASK", 44, 47); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "TLBID", 40, 43); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "E3DSE", 36, 39); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "EAESR", 32, 35); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "RMEGDI", 28, 31); + 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, "PoPS", 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, "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, "VMTETCL", 44, 47); + arm64_sysreg_add_field(ID_AA64PFR2_EL1, "VMTETC", 40, 43); + arm64_sysreg_add_field(ID_AA64PFR2_EL1, "VMTE", 36, 39); + arm64_sysreg_add_field(ID_AA64PFR2_EL1, "FPMR", 32, 35); + arm64_sysreg_add_field(ID_AA64PFR2_EL1, "MPAM2", 28, 31); + arm64_sysreg_add_field(ID_AA64PFR2_EL1, "FGDT", 24, 27); + arm64_sysreg_add_field(ID_AA64PFR2_EL1, "MTEEIRG", 20, 23); + arm64_sysreg_add_field(ID_AA64PFR2_EL1, "UINJ", 16, 19); + arm64_sysreg_add_field(ID_AA64PFR2_EL1, "GCIE", 12, 15); + 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_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, "LUT6", 61, 61); + 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_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_AFR0_EL1 */ + ARM64SysReg *ID_AFR0_EL1 = arm64_sysreg_get(ID_AFR0_EL1_IDX); + ID_AFR0_EL1->name = "ID_AFR0_EL1"; + + /* 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_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_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, "CLRBHB", 28, 31); + 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_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_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); + + /* 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_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_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); + + /* 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); + + /* MPIDR_EL1 */ + ARM64SysReg *MPIDR_EL1 = arm64_sysreg_get(MPIDR_EL1_IDX); + MPIDR_EL1->name = "MPIDR_EL1"; + arm64_sysreg_add_field(MPIDR_EL1, "Aff3", 32, 39); + arm64_sysreg_add_field(MPIDR_EL1, "U", 30, 30); + arm64_sysreg_add_field(MPIDR_EL1, "MT", 24, 24); + arm64_sysreg_add_field(MPIDR_EL1, "Aff2", 16, 23); + arm64_sysreg_add_field(MPIDR_EL1, "Aff1", 8, 15); + arm64_sysreg_add_field(MPIDR_EL1, "Aff0", 0, 7); + + /* 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); + + /* REVIDR_EL1 */ + ARM64SysReg *REVIDR_EL1 = arm64_sysreg_get(REVIDR_EL1_IDX); + REVIDR_EL1->name = "REVIDR_EL1"; + + /* SMIDR_EL1 */ + ARM64SysReg *SMIDR_EL1 = arm64_sysreg_get(SMIDR_EL1_IDX); + SMIDR_EL1->name = "SMIDR_EL1"; + arm64_sysreg_add_field(SMIDR_EL1, "NSMC", 56, 59); + arm64_sysreg_add_field(SMIDR_EL1, "HIP", 52, 55); + arm64_sysreg_add_field(SMIDR_EL1, "Affinity2", 32, 51); + 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, "SH", 13, 14); + arm64_sysreg_add_field(SMIDR_EL1, "Affinity", 0, 11); + +} -- 2.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* [PATCH v4 08/17] target/arm/kvm: Introduce kvm_get_writable_id_regs 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger ` (6 preceding siblings ...) 2026-05-03 7:33 ` [PATCH v4 07/17] target/arm/cpu-sysreg-properties.c: Generate code with new script Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-07 10:07 ` Shameer Kolothum Thodi 2026-05-03 7:33 ` [PATCH v4 09/17] arm/cpu: accessors for writable id registers Eric Auger ` (9 subsequent siblings) 17 siblings, 1 reply; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar From: Cornelia Huck <cohuck@redhat.com> 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 | 3 +++ 3 files changed, 61 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index be14a47c35..2aa22360d2 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -866,6 +866,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_REG_MASKS (3 * 8 * 8) + +typedef struct IdRegMap { + uint64_t regs[NR_ID_REG_MASKS]; /* writable masks for registers */ +} IdRegMap; + /* REG is ID_XXX */ #define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE) \ ({ \ @@ -1054,6 +1074,12 @@ struct ArchCPU { */ bool host_cpu_probe_failed; + /* + * state of writable id regs query used to report an error, if any, + * on vcpu model realize + */ + ARMIdRegsState writable_id_regs_status; + /* 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 d4a68874b8..f06a60804d 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -51,6 +51,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 @@ -499,6 +500,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_status = 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_status = 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_status = WRITABLE_ID_REGS_FAILED; + return ret; + } + cpu->writable_id_regs_status = 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 e7c40fb003..b22a56fc17 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -240,4 +240,7 @@ void arm_gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3); */ char *kvm_print_register_name(uint64_t regidx); +typedef struct IdRegMap IdRegMap; +int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap); + #endif -- 2.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* RE: [PATCH v4 08/17] target/arm/kvm: Introduce kvm_get_writable_id_regs 2026-05-03 7:33 ` [PATCH v4 08/17] target/arm/kvm: Introduce kvm_get_writable_id_regs Eric Auger @ 2026-05-07 10:07 ` Shameer Kolothum Thodi 2026-05-12 15:12 ` Eric Auger 0 siblings, 1 reply; 39+ messages in thread From: Shameer Kolothum Thodi @ 2026-05-07 10:07 UTC (permalink / raw) To: Eric Auger, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com > -----Original Message----- > From: Eric Auger <eric.auger@redhat.com> > Sent: 03 May 2026 08:33 > 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; > cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi > <skolothumtho@nvidia.com>; philmd@linaro.org > Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; > armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; > jdenemar@redhat.com > Subject: [PATCH v4 08/17] target/arm/kvm: Introduce > kvm_get_writable_id_regs > > External email: Use caution opening links or attachments > > > From: Cornelia Huck <cohuck@redhat.com> > > 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 | 3 +++ > 3 files changed, 61 insertions(+) > > diff --git a/target/arm/cpu.h b/target/arm/cpu.h > index be14a47c35..2aa22360d2 100644 > --- a/target/arm/cpu.h > +++ b/target/arm/cpu.h > @@ -866,6 +866,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_REG_MASKS (3 * 8 * 8) Probably can re-use KVM_ARM_FEATURE_ID_RANGE_SIZE here. Looks like used for the same purpose in: tools/testing/selftests/kvm/arm64/set_id_regs.c Thanks, Shameer > + > +typedef struct IdRegMap { > + uint64_t regs[NR_ID_REG_MASKS]; /* writable masks for registers */ > +} IdRegMap; > + > /* REG is ID_XXX */ > #define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE) \ > ({ \ > @@ -1054,6 +1074,12 @@ struct ArchCPU { > */ > bool host_cpu_probe_failed; > > + /* > + * state of writable id regs query used to report an error, if any, > + * on vcpu model realize > + */ > + ARMIdRegsState writable_id_regs_status; > + > /* 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 d4a68874b8..f06a60804d 100644 > --- a/target/arm/kvm.c > +++ b/target/arm/kvm.c > @@ -51,6 +51,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 > @@ -499,6 +500,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_status = > 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_status = > 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_status = WRITABLE_ID_REGS_FAILED; > + return ret; > + } > + cpu->writable_id_regs_status = 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 e7c40fb003..b22a56fc17 100644 > --- a/target/arm/kvm_arm.h > +++ b/target/arm/kvm_arm.h > @@ -240,4 +240,7 @@ void arm_gic_cap_kvm_probe(GICCapability *v2, > GICCapability *v3); > */ > char *kvm_print_register_name(uint64_t regidx); > > +typedef struct IdRegMap IdRegMap; > +int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap); > + > #endif > -- > 2.53.0 ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v4 08/17] target/arm/kvm: Introduce kvm_get_writable_id_regs 2026-05-07 10:07 ` Shameer Kolothum Thodi @ 2026-05-12 15:12 ` Eric Auger 0 siblings, 0 replies; 39+ messages in thread From: Eric Auger @ 2026-05-12 15:12 UTC (permalink / raw) To: Shameer Kolothum Thodi, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com On 5/7/26 12:07 PM, Shameer Kolothum Thodi wrote: > >> -----Original Message----- >> From: Eric Auger <eric.auger@redhat.com> >> Sent: 03 May 2026 08:33 >> 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; >> cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi >> <skolothumtho@nvidia.com>; philmd@linaro.org >> Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; >> armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; >> jdenemar@redhat.com >> Subject: [PATCH v4 08/17] target/arm/kvm: Introduce >> kvm_get_writable_id_regs >> >> External email: Use caution opening links or attachments >> >> >> From: Cornelia Huck <cohuck@redhat.com> >> >> 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 | 3 +++ >> 3 files changed, 61 insertions(+) >> >> diff --git a/target/arm/cpu.h b/target/arm/cpu.h >> index be14a47c35..2aa22360d2 100644 >> --- a/target/arm/cpu.h >> +++ b/target/arm/cpu.h >> @@ -866,6 +866,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_REG_MASKS (3 * 8 * 8) > Probably can re-use KVM_ARM_FEATURE_ID_RANGE_SIZE here. > Looks like used for the same purpose in: > tools/testing/selftests/kvm/arm64/set_id_regs.c removed. The writable_map array is now dynamically allocated in kvm_arch_init_vcpu() Thanks Eric > > Thanks, > Shameer >> + >> +typedef struct IdRegMap { >> + uint64_t regs[NR_ID_REG_MASKS]; /* writable masks for registers */ >> +} IdRegMap; >> + >> /* REG is ID_XXX */ >> #define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE) \ >> ({ \ >> @@ -1054,6 +1074,12 @@ struct ArchCPU { >> */ >> bool host_cpu_probe_failed; >> >> + /* >> + * state of writable id regs query used to report an error, if any, >> + * on vcpu model realize >> + */ >> + ARMIdRegsState writable_id_regs_status; >> + >> /* 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 d4a68874b8..f06a60804d 100644 >> --- a/target/arm/kvm.c >> +++ b/target/arm/kvm.c >> @@ -51,6 +51,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 >> @@ -499,6 +500,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_status = >> 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_status = >> 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_status = WRITABLE_ID_REGS_FAILED; >> + return ret; >> + } >> + cpu->writable_id_regs_status = 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 e7c40fb003..b22a56fc17 100644 >> --- a/target/arm/kvm_arm.h >> +++ b/target/arm/kvm_arm.h >> @@ -240,4 +240,7 @@ void arm_gic_cap_kvm_probe(GICCapability *v2, >> GICCapability *v3); >> */ >> char *kvm_print_register_name(uint64_t regidx); >> >> +typedef struct IdRegMap IdRegMap; >> +int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap); >> + >> #endif >> -- >> 2.53.0 ^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v4 09/17] arm/cpu: accessors for writable id registers 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger ` (7 preceding siblings ...) 2026-05-03 7:33 ` [PATCH v4 08/17] target/arm/kvm: Introduce kvm_get_writable_id_regs Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-07 10:32 ` Shameer Kolothum Thodi 2026-05-03 7:33 ` [PATCH v4 10/17] arm/kvm: Allow reading all the writable ID registers Eric Auger ` (8 subsequent siblings) 17 siblings, 1 reply; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar From: Cornelia Huck <cohuck@redhat.com> Introduce ARM_FEATURE_ID_RANGE_IDX macro that converts opcodes into the index used to access the 3 * 8 * 8 feature id array. KVM_ARM_GET_REG_WRITABLE_MASKS populates writable masks with that indexing. Signed-off-by: Cornelia Huck <cohuck@redhat.com> Signed-off-by: Eric Auger <eric.auger@redhat.com> --- target/arm/cpu.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 2aa22360d2..0ac0fd13cf 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -886,6 +886,13 @@ typedef struct IdRegMap { uint64_t regs[NR_ID_REG_MASKS]; /* writable masks for registers */ } 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) \ ({ \ -- 2.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* RE: [PATCH v4 09/17] arm/cpu: accessors for writable id registers 2026-05-03 7:33 ` [PATCH v4 09/17] arm/cpu: accessors for writable id registers Eric Auger @ 2026-05-07 10:32 ` Shameer Kolothum Thodi 2026-05-12 15:33 ` Eric Auger 0 siblings, 1 reply; 39+ messages in thread From: Shameer Kolothum Thodi @ 2026-05-07 10:32 UTC (permalink / raw) To: Eric Auger, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com > -----Original Message----- > From: Eric Auger <eric.auger@redhat.com> > Sent: 03 May 2026 08:33 > 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; > cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi > <skolothumtho@nvidia.com>; philmd@linaro.org > Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; > armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; > jdenemar@redhat.com > Subject: [PATCH v4 09/17] arm/cpu: accessors for writable id registers > > External email: Use caution opening links or attachments > > > From: Cornelia Huck <cohuck@redhat.com> > > Introduce ARM_FEATURE_ID_RANGE_IDX macro that converts opcodes > into the index used to access the 3 * 8 * 8 feature id array. > > KVM_ARM_GET_REG_WRITABLE_MASKS populates writable masks with > that indexing. > > Signed-off-by: Cornelia Huck <cohuck@redhat.com> > Signed-off-by: Eric Auger <eric.auger@redhat.com> > --- > target/arm/cpu.h | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/target/arm/cpu.h b/target/arm/cpu.h > index 2aa22360d2..0ac0fd13cf 100644 > --- a/target/arm/cpu.h > +++ b/target/arm/cpu.h > @@ -886,6 +886,13 @@ typedef struct IdRegMap { > uint64_t regs[NR_ID_REG_MASKS]; /* writable masks for registers */ > } 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)); \ > + }) > + It looks like this macro is not used anywhere and in next patch it uses KVM_ARM_FEATURE_ID_RANGE_IDX instead. Please check. Thanks, Shameer > /* REG is ID_XXX */ > #define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE) \ > ({ \ > -- > 2.53.0 ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v4 09/17] arm/cpu: accessors for writable id registers 2026-05-07 10:32 ` Shameer Kolothum Thodi @ 2026-05-12 15:33 ` Eric Auger 0 siblings, 0 replies; 39+ messages in thread From: Eric Auger @ 2026-05-12 15:33 UTC (permalink / raw) To: Shameer Kolothum Thodi, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com On 5/7/26 12:32 PM, Shameer Kolothum Thodi wrote: > >> -----Original Message----- >> From: Eric Auger <eric.auger@redhat.com> >> Sent: 03 May 2026 08:33 >> 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; >> cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi >> <skolothumtho@nvidia.com>; philmd@linaro.org >> Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; >> armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; >> jdenemar@redhat.com >> Subject: [PATCH v4 09/17] arm/cpu: accessors for writable id registers >> >> External email: Use caution opening links or attachments >> >> >> From: Cornelia Huck <cohuck@redhat.com> >> >> Introduce ARM_FEATURE_ID_RANGE_IDX macro that converts opcodes >> into the index used to access the 3 * 8 * 8 feature id array. >> >> KVM_ARM_GET_REG_WRITABLE_MASKS populates writable masks with >> that indexing. >> >> Signed-off-by: Cornelia Huck <cohuck@redhat.com> >> Signed-off-by: Eric Auger <eric.auger@redhat.com> >> --- >> target/arm/cpu.h | 7 +++++++ >> 1 file changed, 7 insertions(+) >> >> diff --git a/target/arm/cpu.h b/target/arm/cpu.h >> index 2aa22360d2..0ac0fd13cf 100644 >> --- a/target/arm/cpu.h >> +++ b/target/arm/cpu.h >> @@ -886,6 +886,13 @@ typedef struct IdRegMap { >> uint64_t regs[NR_ID_REG_MASKS]; /* writable masks for registers */ >> } 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)); \ >> + }) >> + > It looks like this macro is not used anywhere and in next patch it > uses KVM_ARM_FEATURE_ID_RANGE_IDX instead. Thanks for pointing this out. Removed that patch Eric > > Please check. > > Thanks, > Shameer > > >> /* REG is ID_XXX */ >> #define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE) \ >> ({ \ >> -- >> 2.53.0 ^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v4 10/17] arm/kvm: Allow reading all the writable ID registers 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger ` (8 preceding siblings ...) 2026-05-03 7:33 ` [PATCH v4 09/17] arm/cpu: accessors for writable id registers Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-07 11:50 ` Shameer Kolothum Thodi 2026-05-03 7:33 ` [PATCH v4 11/17] arm/kvm: write back modified ID regs to KVM Eric Auger ` (7 subsequent siblings) 17 siblings, 1 reply; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar 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.h | 3 ++ target/arm/cpu64.c | 2 +- target/arm/kvm-stub.c | 3 +- target/arm/kvm.c | 77 +++++++++++++++++++++++++++++++++++++++-- target/arm/kvm_arm.h | 6 +++- target/arm/trace-events | 1 + 6 files changed, 86 insertions(+), 6 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 0ac0fd13cf..87fb0047eb 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1087,6 +1087,9 @@ struct ArchCPU { */ ARMIdRegsState writable_id_regs_status; + /* 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 b940842d9e..1b3d3fb245 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -862,7 +862,7 @@ static void aarch64_host_initfn(Object *obj) #if defined(CONFIG_KVM) kvm_arm_set_cpreg_mig_tolerances(cpu); - kvm_arm_set_cpu_features_from_host(cpu); + kvm_arm_set_cpu_features_from_host(cpu, false); aarch64_add_sve_properties(obj); #elif defined(CONFIG_HVF) hvf_arm_set_cpu_features_from_host(cpu); diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c index 88cbe8d85c..94478c5690 100644 --- a/target/arm/kvm-stub.c +++ b/target/arm/kvm-stub.c @@ -45,7 +45,8 @@ bool kvm_arm_el2_supported(void) /* * These functions should never actually be called without KVM support. */ -void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu) +void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, + bool get_all_writable_id_regs) { g_assert_not_reached(); } diff --git a/target/arm/kvm.c b/target/arm/kvm.c index f06a60804d..1a9b91bf8a 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -42,6 +42,7 @@ #include "hw/acpi/ghes.h" #include "target/arm/gtimer.h" #include "migration/blocker.h" +#include "cpu-idregs.h" const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_INFO(DEVICE_CTRL), @@ -274,7 +275,63 @@ static uint32_t kvm_arm_sve_get_vls(int fd) return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ); } -static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) +static int idregs_idx_to_kvm_feature_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_feature_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 get_all_writable_id_regs) { /* Identify the feature bits corresponding to the host CPU, and * fill out the ARMHostCPUClass fields accordingly. To do this @@ -401,6 +458,18 @@ 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 (get_all_writable_id_regs) { + err |= get_host_cpu_idregs(cpu, fd, ahcf); + } + + /* + * temporarily override the CLIDR_EL1 value since host value does + * not seem to be supported. Getting "Unified type is not implemented + * at level n" error in fdt_add_cpu_nodes() + */ + SET_IDREG(&ahcf->isar, CLIDR, 0x0); + /* * DBGDIDR is a bit complicated because the kernel doesn't * provide an accessor for it in 64-bit mode, which is what this @@ -477,13 +546,15 @@ 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 get_all_writable_id_regs) { 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, + get_all_writable_id_regs)) { /* 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 b22a56fc17..91a7d5cc4b 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -127,11 +127,15 @@ void kvm_arm_destroy_scratch_host_vcpu(int *fdarray); /** * kvm_arm_set_cpu_features_from_host: * @cpu: ARMCPU to set the features for + * @get_all_writable_id_regs: if true, get the contents of all writable ID + * registers as well * * Set up the ARMCPU struct fields up to match the information probed * from the host CPU. + * */ -void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu); +void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, + bool get_all_writable_id_regs); /** * kvm_arm_add_vcpu_properties: diff --git a/target/arm/trace-events b/target/arm/trace-events index 8502fb3265..8c7faf57c7 100644 --- a/target/arm/trace-events +++ b/target/arm/trace-events @@ -13,6 +13,7 @@ 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 # cpu.c arm_cpu_reset(uint64_t mp_aff) "cpu %" PRIu64 -- 2.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* RE: [PATCH v4 10/17] arm/kvm: Allow reading all the writable ID registers 2026-05-03 7:33 ` [PATCH v4 10/17] arm/kvm: Allow reading all the writable ID registers Eric Auger @ 2026-05-07 11:50 ` Shameer Kolothum Thodi 0 siblings, 0 replies; 39+ messages in thread From: Shameer Kolothum Thodi @ 2026-05-07 11:50 UTC (permalink / raw) To: Eric Auger, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com > -----Original Message----- > From: Eric Auger <eric.auger@redhat.com> > Sent: 03 May 2026 08:34 > 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; > cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi > <skolothumtho@nvidia.com>; philmd@linaro.org > Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; > armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; > jdenemar@redhat.com > Subject: [PATCH v4 10/17] arm/kvm: Allow reading all the writable ID registers > > External email: Use caution opening links or attachments > > > 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.h | 3 ++ > target/arm/cpu64.c | 2 +- > target/arm/kvm-stub.c | 3 +- > target/arm/kvm.c | 77 +++++++++++++++++++++++++++++++++++++++-- > target/arm/kvm_arm.h | 6 +++- > target/arm/trace-events | 1 + > 6 files changed, 86 insertions(+), 6 deletions(-) > > diff --git a/target/arm/cpu.h b/target/arm/cpu.h > index 0ac0fd13cf..87fb0047eb 100644 > --- a/target/arm/cpu.h > +++ b/target/arm/cpu.h > @@ -1087,6 +1087,9 @@ struct ArchCPU { > */ > ARMIdRegsState writable_id_regs_status; > > + /* 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 b940842d9e..1b3d3fb245 100644 > --- a/target/arm/cpu64.c > +++ b/target/arm/cpu64.c > @@ -862,7 +862,7 @@ static void aarch64_host_initfn(Object *obj) > > #if defined(CONFIG_KVM) > kvm_arm_set_cpreg_mig_tolerances(cpu); > - kvm_arm_set_cpu_features_from_host(cpu); > + kvm_arm_set_cpu_features_from_host(cpu, false); > aarch64_add_sve_properties(obj); > #elif defined(CONFIG_HVF) > hvf_arm_set_cpu_features_from_host(cpu); > diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c > index 88cbe8d85c..94478c5690 100644 > --- a/target/arm/kvm-stub.c > +++ b/target/arm/kvm-stub.c > @@ -45,7 +45,8 @@ bool kvm_arm_el2_supported(void) > /* > * These functions should never actually be called without KVM support. > */ > -void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu) > +void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, > + bool get_all_writable_id_regs) > { > g_assert_not_reached(); > } > diff --git a/target/arm/kvm.c b/target/arm/kvm.c > index f06a60804d..1a9b91bf8a 100644 > --- a/target/arm/kvm.c > +++ b/target/arm/kvm.c > @@ -42,6 +42,7 @@ > #include "hw/acpi/ghes.h" > #include "target/arm/gtimer.h" > #include "migration/blocker.h" > +#include "cpu-idregs.h" > > const KVMCapabilityInfo kvm_arch_required_capabilities[] = { > KVM_CAP_INFO(DEVICE_CTRL), > @@ -274,7 +275,63 @@ static uint32_t kvm_arm_sve_get_vls(int fd) > return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ); > } > > -static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) > +static int idregs_idx_to_kvm_feature_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_feature_idx(i)]; Nit: I can see writable_map is always populated by the time it reaches here, but may be good to have: g_assert(cpu->writable_map); Thanks, Shameer > + 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 get_all_writable_id_regs) > { > /* Identify the feature bits corresponding to the host CPU, and > * fill out the ARMHostCPUClass fields accordingly. To do this > @@ -401,6 +458,18 @@ 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 (get_all_writable_id_regs) { > + err |= get_host_cpu_idregs(cpu, fd, ahcf); > + } > + > + /* > + * temporarily override the CLIDR_EL1 value since host value does > + * not seem to be supported. Getting "Unified type is not implemented > + * at level n" error in fdt_add_cpu_nodes() > + */ > + SET_IDREG(&ahcf->isar, CLIDR, 0x0); > + > /* > * DBGDIDR is a bit complicated because the kernel doesn't > * provide an accessor for it in 64-bit mode, which is what this > @@ -477,13 +546,15 @@ 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 get_all_writable_id_regs) > { > 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, > + get_all_writable_id_regs)) { > /* 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 b22a56fc17..91a7d5cc4b 100644 > --- a/target/arm/kvm_arm.h > +++ b/target/arm/kvm_arm.h > @@ -127,11 +127,15 @@ void kvm_arm_destroy_scratch_host_vcpu(int > *fdarray); > /** > * kvm_arm_set_cpu_features_from_host: > * @cpu: ARMCPU to set the features for > + * @get_all_writable_id_regs: if true, get the contents of all writable ID > + * registers as well > * > * Set up the ARMCPU struct fields up to match the information probed > * from the host CPU. > + * > */ > -void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu); > +void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, > + bool get_all_writable_id_regs); > > /** > * kvm_arm_add_vcpu_properties: > diff --git a/target/arm/trace-events b/target/arm/trace-events > index 8502fb3265..8c7faf57c7 100644 > --- a/target/arm/trace-events > +++ b/target/arm/trace-events > @@ -13,6 +13,7 @@ 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 > > # cpu.c > arm_cpu_reset(uint64_t mp_aff) "cpu %" PRIu64 > -- > 2.53.0 ^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v4 11/17] arm/kvm: write back modified ID regs to KVM 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger ` (9 preceding siblings ...) 2026-05-03 7:33 ` [PATCH v4 10/17] arm/kvm: Allow reading all the writable ID registers Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-07 18:53 ` Shameer Kolothum Thodi 2026-05-08 13:03 ` Shameer Kolothum Thodi 2026-05-03 7:33 ` [PATCH v4 12/17] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties Eric Auger ` (6 subsequent siblings) 17 siblings, 2 replies; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar 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 | 59 ++++++++++++++++++++++++++++++++++++++++- target/arm/trace-events | 1 + 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 1a9b91bf8a..ca9a7d9439 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -275,6 +275,21 @@ static uint32_t kvm_arm_sve_get_vls(int fd) return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ); } +static int kvm_feature_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); +} + static int idregs_idx_to_kvm_feature_idx(ARMIDRegisterIdx idx) { ARMSysRegs sysreg = id_register_sysreg[idx]; @@ -1197,6 +1212,39 @@ bool kvm_arm_cpu_post_load(ARMCPU *cpu) return true; } +static void kvm_arm_writable_idregs_to_cpreg_list(ARMCPU *cpu) +{ + if (!cpu->writable_map) { + return; + } + for (int i = 0; i < NR_ID_REG_MASKS; i++) { + uint64_t writable_mask = cpu->writable_map->regs[i]; + uint64_t *cpreg; + + if (writable_mask) { + uint64_t previous, new; + int idx = kvm_feature_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; @@ -2148,7 +2196,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, KVM_PUT_FULL_STATE); + + return 0; } int kvm_arch_destroy_vcpu(CPUState *cs) diff --git a/target/arm/trace-events b/target/arm/trace-events index 8c7faf57c7..c25d2a1191 100644 --- a/target/arm/trace-events +++ b/target/arm/trace-events @@ -14,6 +14,7 @@ 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 # cpu.c arm_cpu_reset(uint64_t mp_aff) "cpu %" PRIu64 -- 2.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* RE: [PATCH v4 11/17] arm/kvm: write back modified ID regs to KVM 2026-05-03 7:33 ` [PATCH v4 11/17] arm/kvm: write back modified ID regs to KVM Eric Auger @ 2026-05-07 18:53 ` Shameer Kolothum Thodi 2026-05-08 13:03 ` Shameer Kolothum Thodi 1 sibling, 0 replies; 39+ messages in thread From: Shameer Kolothum Thodi @ 2026-05-07 18:53 UTC (permalink / raw) To: Eric Auger, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com > -----Original Message----- > From: Eric Auger <eric.auger@redhat.com> > Sent: 03 May 2026 08:34 > 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; > cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi > <skolothumtho@nvidia.com>; philmd@linaro.org > Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; > armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; > jdenemar@redhat.com > Subject: [PATCH v4 11/17] arm/kvm: write back modified ID regs to KVM > > External email: Use caution opening links or attachments > > > 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 | 59 ++++++++++++++++++++++++++++++++++++++++- > target/arm/trace-events | 1 + > 2 files changed, 59 insertions(+), 1 deletion(-) > > diff --git a/target/arm/kvm.c b/target/arm/kvm.c > index 1a9b91bf8a..ca9a7d9439 100644 > --- a/target/arm/kvm.c > +++ b/target/arm/kvm.c > @@ -275,6 +275,21 @@ static uint32_t kvm_arm_sve_get_vls(int fd) > return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ); > } > > +static int kvm_feature_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); > +} > + > static int idregs_idx_to_kvm_feature_idx(ARMIDRegisterIdx idx) > { > ARMSysRegs sysreg = id_register_sysreg[idx]; > @@ -1197,6 +1212,39 @@ bool kvm_arm_cpu_post_load(ARMCPU *cpu) > return true; > } > > +static void kvm_arm_writable_idregs_to_cpreg_list(ARMCPU *cpu) > +{ > + if (!cpu->writable_map) { > + return; > + } > + for (int i = 0; i < NR_ID_REG_MASKS; i++) { > + uint64_t writable_mask = cpu->writable_map->regs[i]; > + uint64_t *cpreg; > + > + if (writable_mask) { > + uint64_t previous, new; > + int idx = kvm_feature_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; > @@ -2148,7 +2196,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, KVM_PUT_FULL_STATE); kvm_arm_writable_idregs_to_cpreg_list() does nothing if writable_map is NULL. But we unconditionally call write_list_to_kvmstate() . No harm, but still, I think better, return a bool indicating any updates and call write_list_to_kvmstate() accordingly. Also, please check return value of write_list_to_kvmstate() Thanks, Shameer > + > + return 0; > } > > int kvm_arch_destroy_vcpu(CPUState *cs) > diff --git a/target/arm/trace-events b/target/arm/trace-events > index 8c7faf57c7..c25d2a1191 100644 > --- a/target/arm/trace-events > +++ b/target/arm/trace-events > @@ -14,6 +14,7 @@ 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 > > # cpu.c > arm_cpu_reset(uint64_t mp_aff) "cpu %" PRIu64 > -- > 2.53.0 ^ permalink raw reply [flat|nested] 39+ messages in thread
* RE: [PATCH v4 11/17] arm/kvm: write back modified ID regs to KVM 2026-05-03 7:33 ` [PATCH v4 11/17] arm/kvm: write back modified ID regs to KVM Eric Auger 2026-05-07 18:53 ` Shameer Kolothum Thodi @ 2026-05-08 13:03 ` Shameer Kolothum Thodi 1 sibling, 0 replies; 39+ messages in thread From: Shameer Kolothum Thodi @ 2026-05-08 13:03 UTC (permalink / raw) To: Eric Auger, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com Hi Eric, > -----Original Message----- > From: Eric Auger <eric.auger@redhat.com> > Sent: 03 May 2026 08:34 > 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; > cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi > <skolothumtho@nvidia.com>; philmd@linaro.org > Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; > armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; > jdenemar@redhat.com > Subject: [PATCH v4 11/17] arm/kvm: write back modified ID regs to KVM > > External email: Use caution opening links or attachments > > > 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 | 59 > ++++++++++++++++++++++++++++++++++++++++- > target/arm/trace-events | 1 + > 2 files changed, 59 insertions(+), 1 deletion(-) > > diff --git a/target/arm/kvm.c b/target/arm/kvm.c > index 1a9b91bf8a..ca9a7d9439 100644 > --- a/target/arm/kvm.c > +++ b/target/arm/kvm.c > @@ -275,6 +275,21 @@ static uint32_t kvm_arm_sve_get_vls(int fd) > return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ); > } > > +static int kvm_feature_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); > +} > + > static int idregs_idx_to_kvm_feature_idx(ARMIDRegisterIdx idx) > { > ARMSysRegs sysreg = id_register_sysreg[idx]; > @@ -1197,6 +1212,39 @@ bool kvm_arm_cpu_post_load(ARMCPU *cpu) > return true; > } > > +static void kvm_arm_writable_idregs_to_cpreg_list(ARMCPU *cpu) > +{ > + if (!cpu->writable_map) { > + return; > + } > + for (int i = 0; i < NR_ID_REG_MASKS; i++) { > + uint64_t writable_mask = cpu->writable_map->regs[i]; > + uint64_t *cpreg; > + > + if (writable_mask) { > + uint64_t previous, new; > + int idx = kvm_feature_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; > @@ -2148,7 +2196,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, KVM_PUT_FULL_STATE); KVM may hide registers based on ID register fields when features are disabled. Updating writable ID registers after KVM_GET_REG_LIST can result in a mismatched register list and failures when setting registers. This was reported on v3: https://lore.kernel.org/qemu-devel/ae3f4d26-7a1a-418c-b303-2ed1d9ced4ba@huawei.com/ Is this fixed someway in this series? I am not sure. I have faced the same issue on NV platforms as well. Thanks, Shameer ^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v4 12/17] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger ` (10 preceding siblings ...) 2026-05-03 7:33 ` [PATCH v4 11/17] arm/kvm: write back modified ID regs to KVM Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-07 19:10 ` Shameer Kolothum Thodi 2026-05-03 7:33 ` [PATCH v4 13/17] target/arm/kvm: Special case REVIDR_EL1 and AIDR_EL1 Eric Auger ` (5 subsequent siblings) 17 siblings, 1 reply; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar This helper decode the ID reg writable mask, matches it against ID reg fields defined in target/arm/cpu-sysreg-properties.c and for each writable named field, generates a uint64 property. Signed-off-by: Eric Auger <eric.auger@redhat.com> --- target/arm/kvm.c | 134 ++++++++++++++++++++++++++++++++++++++++ target/arm/kvm_arm.h | 10 +++ target/arm/trace-events | 4 ++ 3 files changed, 148 insertions(+) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index ca9a7d9439..d9bf1ec039 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -344,6 +344,140 @@ 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) { + warn_report("%s bit %d of %s is writable but no named field " + "in target/arm/cpu-sysreg-properties.c", + __func__, i, reg->name); + warn_report("%s is target/arm/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_REG_MASKS; i++) { + uint64_t mask = map->regs[i]; + + if (mask) { + /* reg @i has some writable fields, decode them */ + idx = kvm_feature_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, ®s[idx]); + } + } + } +} + static bool kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf, bool get_all_writable_id_regs) diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 91a7d5cc4b..a3034f264b 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -146,6 +146,16 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, */ 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 c25d2a1191..d72ad6b671 100644 --- a/target/arm/trace-events +++ b/target/arm/trace-events @@ -15,6 +15,10 @@ 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" # cpu.c arm_cpu_reset(uint64_t mp_aff) "cpu %" PRIu64 -- 2.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* RE: [PATCH v4 12/17] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties 2026-05-03 7:33 ` [PATCH v4 12/17] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties Eric Auger @ 2026-05-07 19:10 ` Shameer Kolothum Thodi 0 siblings, 0 replies; 39+ messages in thread From: Shameer Kolothum Thodi @ 2026-05-07 19:10 UTC (permalink / raw) To: Eric Auger, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com > -----Original Message----- > From: Eric Auger <eric.auger@redhat.com> > Sent: 03 May 2026 08:34 > 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; > cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi > <skolothumtho@nvidia.com>; philmd@linaro.org > Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; > armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; > jdenemar@redhat.com > Subject: [PATCH v4 12/17] target/arm/kvm: Introduce > kvm_arm_expose_idreg_properties > > External email: Use caution opening links or attachments > > > This helper decode the ID reg writable mask, matches it against > ID reg fields defined in target/arm/cpu-sysreg-properties.c and > for each writable named field, generates a uint64 property. > > Signed-off-by: Eric Auger <eric.auger@redhat.com> > --- > target/arm/kvm.c | 134 > ++++++++++++++++++++++++++++++++++++++++ > target/arm/kvm_arm.h | 10 +++ > target/arm/trace-events | 4 ++ > 3 files changed, 148 insertions(+) > > diff --git a/target/arm/kvm.c b/target/arm/kvm.c > index ca9a7d9439..d9bf1ec039 100644 > --- a/target/arm/kvm.c > +++ b/target/arm/kvm.c > @@ -344,6 +344,140 @@ 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) { > + warn_report("%s bit %d of %s is writable but no named field " > + "in target/arm/cpu-sysreg-properties.c", > + __func__, i, reg->name); > + warn_report("%s is target/arm/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++; g_free(prop_name) ? Or may be use g_autofree. > + > + 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; I think better we check writable_map before proceeding. Thanks, Shameer > + Object *obj = OBJECT(cpu); > + > + for (i = 0; i < NR_ID_REG_MASKS; i++) { > + uint64_t mask = map->regs[i]; > + > + if (mask) { > + /* reg @i has some writable fields, decode them */ > + idx = kvm_feature_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, ®s[idx]); > + } > + } > + } > +} > + > static bool > kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures > *ahcf, > bool get_all_writable_id_regs) > diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h > index 91a7d5cc4b..a3034f264b 100644 > --- a/target/arm/kvm_arm.h > +++ b/target/arm/kvm_arm.h > @@ -146,6 +146,16 @@ void > kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, > */ > 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 c25d2a1191..d72ad6b671 100644 > --- a/target/arm/trace-events > +++ b/target/arm/trace-events > @@ -15,6 +15,10 @@ 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" > > # cpu.c > arm_cpu_reset(uint64_t mp_aff) "cpu %" PRIu64 > -- > 2.53.0 ^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v4 13/17] target/arm/kvm: Special case REVIDR_EL1 and AIDR_EL1 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger ` (11 preceding siblings ...) 2026-05-03 7:33 ` [PATCH v4 12/17] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-03 7:33 ` [PATCH v4 14/17] target/arm/kvm: Special case ID_AA64ISAR0_EL1 RES0 [24, 27] bits Eric Auger ` (4 subsequent siblings) 17 siblings, 0 replies; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar Special case REVIDR_EL1 and AIDR_EL1 which are writable but does not expose named fields. They will need to be handled separately Signed-off-by: Eric Auger <eric.auger@redhat.com> --- target/arm/kvm.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index d9bf1ec039..f3aecef35c 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -472,7 +472,15 @@ void kvm_arm_expose_idreg_properties(ARMCPU *cpu, ARM64SysReg *regs) warn_report("%s: reg %d writable, but not in list of idregs?", __func__, i); } else { - decode_idreg_writemap(obj, i, mask, ®s[idx]); + /* + * special case REVIDR_EL1 and AIDR_EL1 which are writable but + * does not expose named fields. They will need to be handled + * separately + */ + if (strcmp(regs[idx].name, "REVIDR_EL1") && + strcmp(regs[idx].name, "AIDR_EL1")) { + decode_idreg_writemap(obj, i, mask, ®s[idx]); + } } } } -- 2.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* [PATCH v4 14/17] target/arm/kvm: Special case ID_AA64ISAR0_EL1 RES0 [24, 27] bits 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger ` (12 preceding siblings ...) 2026-05-03 7:33 ` [PATCH v4 13/17] target/arm/kvm: Special case REVIDR_EL1 and AIDR_EL1 Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-03 7:33 ` [PATCH v4 15/17] arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model Eric Auger ` (3 subsequent siblings) 17 siblings, 0 replies; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar RES0 [24, 27] bits seem to be reported as writable by the kernel. This corresponds to former TME field that was turned to RES0 after FEAT_TME removal from the architecture. See kernel commit d65bf6e317e7b ("KVM: arm64: Remove all traces of FEAT_TME") for additional info. However the kernel still exposes it at writable. Until this gets fixed, Let's ignore those bits. Signed-off-by: Eric Auger <eric.auger@redhat.com> --- target/arm/kvm.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index f3aecef35c..18373b0936 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -430,10 +430,13 @@ decode_idreg_writemap(Object *obj, int index, uint64_t map, ARM64SysReg *reg) char *prop_name; if (!field) { - warn_report("%s bit %d of %s is writable but no named field " - "in target/arm/cpu-sysreg-properties.c", - __func__, i, reg->name); - warn_report("%s is target/arm/cpu-sysreg-properties.c up to date?", __func__); + if (strcmp(reg->name, "ID_AA64ISAR0_EL1") || i < 24 || i > 27) { + warn_report("%s bit %d of %s is writable but no named field " + "in target/arm/cpu-sysreg-properties.c", + __func__, i, reg->name); + warn_report("%s is target/arm/cpu-sysreg-properties.c up to date?", + __func__); + } map = map & ~BIT_ULL(i); i = ctz64(map); continue; -- 2.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* [PATCH v4 15/17] arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger ` (13 preceding siblings ...) 2026-05-03 7:33 ` [PATCH v4 14/17] target/arm/kvm: Special case ID_AA64ISAR0_EL1 RES0 [24, 27] bits Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-07 19:22 ` Shameer Kolothum Thodi 2026-05-03 7:33 ` [PATCH v4 16/17] arm-qmp-cmds: introspection for ID register props Eric Auger ` (2 subsequent siblings) 17 siblings, 1 reply; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar If the host supports KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES and KVM_ARM_GET_REG_WRITABLE_MASKS ioctl successfully retrieved the mask of writable fields for all ID regs, expose uint64 SYSREG properties for all the writable ID reg fields exposed by the host kernel which can be matched in target/arm/cpu-sysreg-properties.c. Properties are named SYSREG_<REG>_<FIELD> with REG and FIELD being those used in linux arch/arm64/tools/sysreg or in the AARCHMRS Registers.json. This is achieved by matching the writable fields retrieved from the host kernel against the generated description of ID regs and their fields in target/arm/cpu-sysreg-properties.c. 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> --- target/arm/cpu.c | 12 ++++++++++++ target/arm/cpu64.c | 23 ++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 10feb639c4..10ce4eb0cb 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1824,6 +1824,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_status == 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 1b3d3fb245..d66cb00a21 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -852,6 +852,8 @@ static void kvm_arm_set_cpreg_mig_tolerances(ARMCPU *cpu) static void aarch64_host_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + bool expose_id_regs = true; + int ret; #if defined(CONFIG_NITRO) if (nitro_enabled()) { @@ -862,8 +864,27 @@ static void aarch64_host_initfn(Object *obj) #if defined(CONFIG_KVM) kvm_arm_set_cpreg_mig_tolerances(cpu); - kvm_arm_set_cpu_features_from_host(cpu, false); + + 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); aarch64_add_sve_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) hvf_arm_set_cpu_features_from_host(cpu); #elif defined(CONFIG_WHPX) -- 2.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* RE: [PATCH v4 15/17] arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model 2026-05-03 7:33 ` [PATCH v4 15/17] arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model Eric Auger @ 2026-05-07 19:22 ` Shameer Kolothum Thodi 0 siblings, 0 replies; 39+ messages in thread From: Shameer Kolothum Thodi @ 2026-05-07 19:22 UTC (permalink / raw) To: Eric Auger, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com > -----Original Message----- > From: Eric Auger <eric.auger@redhat.com> > Sent: 03 May 2026 08:34 > 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; > cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi > <skolothumtho@nvidia.com>; philmd@linaro.org > Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; > armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; > jdenemar@redhat.com > Subject: [PATCH v4 15/17] arm/cpu: Expose writable ID reg field properties on > the kvm host vcpu model > > External email: Use caution opening links or attachments > > > If the host supports KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES and > KVM_ARM_GET_REG_WRITABLE_MASKS ioctl successfully retrieved the mask > of writable fields for all ID regs, expose uint64 SYSREG properties > for all the writable ID reg fields exposed by the host kernel which > can be matched in target/arm/cpu-sysreg-properties.c. > > Properties are named SYSREG_<REG>_<FIELD> with REG and FIELD > being those used in linux arch/arm64/tools/sysreg or in the AARCHMRS > Registers.json. > > This is achieved by matching the writable fields retrieved from the > host kernel against the generated description of ID regs and their > fields in target/arm/cpu-sysreg-properties.c. > > 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> > --- > target/arm/cpu.c | 12 ++++++++++++ > target/arm/cpu64.c | 23 ++++++++++++++++++++++- > 2 files changed, 34 insertions(+), 1 deletion(-) > > diff --git a/target/arm/cpu.c b/target/arm/cpu.c > index 10feb639c4..10ce4eb0cb 100644 > --- a/target/arm/cpu.c > +++ b/target/arm/cpu.c > @@ -1824,6 +1824,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_status == 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 1b3d3fb245..d66cb00a21 100644 > --- a/target/arm/cpu64.c > +++ b/target/arm/cpu64.c > @@ -852,6 +852,8 @@ static void > kvm_arm_set_cpreg_mig_tolerances(ARMCPU *cpu) > static void aarch64_host_initfn(Object *obj) > { > ARMCPU *cpu = ARM_CPU(obj); > + bool expose_id_regs = true; > + int ret; The above will be unused for non KVM builds. > > #if defined(CONFIG_NITRO) > if (nitro_enabled()) { > @@ -862,8 +864,27 @@ static void aarch64_host_initfn(Object *obj) > > #if defined(CONFIG_KVM) > kvm_arm_set_cpreg_mig_tolerances(cpu); > - kvm_arm_set_cpu_features_from_host(cpu, false); > + > + cpu->writable_map = g_malloc(sizeof(IdRegMap)); Does kernel clear the buffer before setting writable mask? > + /* 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; > + } Should free and NULL writable_map for both error paths above. Thanks, Shameer > + > + kvm_arm_set_cpu_features_from_host(cpu, expose_id_regs); > aarch64_add_sve_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) > hvf_arm_set_cpu_features_from_host(cpu); > #elif defined(CONFIG_WHPX) > -- > 2.53.0 ^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v4 16/17] arm-qmp-cmds: introspection for ID register props 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger ` (14 preceding siblings ...) 2026-05-03 7:33 ` [PATCH v4 15/17] arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-03 7:33 ` [PATCH v4 17/17] arm/cpu-features: document ID reg properties Eric Auger 2026-05-15 8:31 ` [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Peter Maydell 17 siblings, 0 replies; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar From: Cornelia Huck <cohuck@redhat.com> 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 83ec95c290..ea8c541a00 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 "qemu/target-info.h" #include "hw/core/boards.h" #include "kvm_arm.h" @@ -190,6 +191,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_status == 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.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* [PATCH v4 17/17] arm/cpu-features: document ID reg properties 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger ` (15 preceding siblings ...) 2026-05-03 7:33 ` [PATCH v4 16/17] arm-qmp-cmds: introspection for ID register props Eric Auger @ 2026-05-03 7:33 ` Eric Auger 2026-05-07 19:44 ` Shameer Kolothum Thodi 2026-05-15 8:31 ` [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Peter Maydell 17 siblings, 1 reply; 39+ messages in thread From: Eric Auger @ 2026-05-03 7:33 UTC (permalink / raw) To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson, cohuck, sebott, skolothumtho, philmd Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar From: Cornelia Huck <cohuck@redhat.com> 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 10b0eff27e..22f671b15d 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 @@ -31,6 +34,16 @@ running guests in AArch32. CPU features that are inherently 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 =================== @@ -126,13 +139,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 @@ -169,6 +189,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 ================= @@ -495,3 +522,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.53.0 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* RE: [PATCH v4 17/17] arm/cpu-features: document ID reg properties 2026-05-03 7:33 ` [PATCH v4 17/17] arm/cpu-features: document ID reg properties Eric Auger @ 2026-05-07 19:44 ` Shameer Kolothum Thodi 0 siblings, 0 replies; 39+ messages in thread From: Shameer Kolothum Thodi @ 2026-05-07 19:44 UTC (permalink / raw) To: Eric Auger, 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, cohuck@redhat.com, sebott@redhat.com, philmd@linaro.org Cc: maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com, abologna@redhat.com, jdenemar@redhat.com > -----Original Message----- > From: Eric Auger <eric.auger@redhat.com> > Sent: 03 May 2026 08:34 > 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; > cohuck@redhat.com; sebott@redhat.com; Shameer Kolothum Thodi > <skolothumtho@nvidia.com>; philmd@linaro.org > Cc: maz@kernel.org; oliver.upton@linux.dev; pbonzini@redhat.com; > armbru@redhat.com; berrange@redhat.com; abologna@redhat.com; > jdenemar@redhat.com > Subject: [PATCH v4 17/17] arm/cpu-features: document ID reg properties > > External email: Use caution opening links or attachments > > > From: Cornelia Huck <cohuck@redhat.com> > > 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 10b0eff27e..22f671b15d 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 > @@ -31,6 +34,16 @@ running guests in AArch32. > CPU features that are inherently 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 arch/arm64/tools/sysreg Anyway, I think this needs update as the scripts now uses Registers.json from AARCHMRS, right? > +description for those registers and fields. This currently only has been > +implemented for KVM. > + > CPU Feature Probing > =================== > > @@ -126,13 +139,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 s/hidden to the guest/hidden from the guest/ > +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 > @@ -169,6 +189,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 > ================= > > @@ -495,3 +522,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 s/incompatibities/incompatibilities/ Thanks, Shameer > +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.53.0 ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger ` (16 preceding siblings ...) 2026-05-03 7:33 ` [PATCH v4 17/17] arm/cpu-features: document ID reg properties Eric Auger @ 2026-05-15 8:31 ` Peter Maydell 2026-05-15 9:04 ` Marc Zyngier 17 siblings, 1 reply; 39+ messages in thread From: Peter Maydell @ 2026-05-15 8:31 UTC (permalink / raw) To: Eric Auger Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, richard.henderson, cohuck, sebott, skolothumtho, philmd, maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar On Sun, 3 May 2026 at 08:35, Eric Auger <eric.auger@redhat.com> wrote: > > This series enhances the current host KVM model with capability to > set writable ID reg fields. > > Since v6.7 kernel, KVM/arm allows the userspace to overwrite the values > of a subset of ID regs. The list of writable fields continues to grow. > The feature ID range is defined as the AArch64 System register space > with op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}. > > The end goal is to get more flexibility when migrating guests > between different host hardware. > > QEMU retrieves the writable ID fields from KVM UAPI [1] and > match them against a generated description of ID regs and their > named fields that stem from AARCHMRS Registers.json file. > Current description is based on latest 2026-03 edition. > The content of the generated files was compared against kernel > linux/arch/arm64/tools/sysreg file [3] . It is not straightforward > to have unit tests for python scripts as there are many cases for > field extraction. > > For each writable named field a uint64 property is created > following the "SYSREG_<REG>_<FIELD>" naming convention. REG and > FIELD names are those described in ARM ARM Reference manual. So if the user asks to set ID registers to an architecturally invalid combination (e.g. one that reports FEAT_X but not FEAT_Y even though FEAT_X is supposed to imply FEAT_Y, or one where one ID register says we have FEAT_X but a different ID register says we don't have FEAT_X), what happens ? Do we catch and reject that? Does the kernel reject that? Or do we just report to the guest what the user asked for, and if they asked for something broken they can keep both pieces ? thanks -- PMM ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model 2026-05-15 8:31 ` [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Peter Maydell @ 2026-05-15 9:04 ` Marc Zyngier 2026-05-15 16:41 ` Eric Auger 0 siblings, 1 reply; 39+ messages in thread From: Marc Zyngier @ 2026-05-15 9:04 UTC (permalink / raw) To: Peter Maydell Cc: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, kvmarm, richard.henderson, cohuck, sebott, skolothumtho, philmd, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar On Fri, 15 May 2026 09:31:19 +0100, Peter Maydell <peter.maydell@linaro.org> wrote: > > So if the user asks to set ID registers to an architecturally > invalid combination (e.g. one that reports FEAT_X but not > FEAT_Y even though FEAT_X is supposed to imply FEAT_Y, or > one where one ID register says we have FEAT_X but a different > ID register says we don't have FEAT_X), what happens ? > Do we catch and reject that? Does the kernel reject that? > Or do we just report to the guest what the user asked for, > and if they asked for something broken they can keep both > pieces ? I fully expect the latter. Neither the kernel nor QEMU can enforce this short of encoding all the various dependencies, which have the horrible habit of changing over time. The only thing we can realistically reason about is a single idreg at a time. Thanks, M. -- Jazz isn't dead. It just smells funny. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model 2026-05-15 9:04 ` Marc Zyngier @ 2026-05-15 16:41 ` Eric Auger 0 siblings, 0 replies; 39+ messages in thread From: Eric Auger @ 2026-05-15 16:41 UTC (permalink / raw) To: Marc Zyngier, Peter Maydell Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, richard.henderson, cohuck, sebott, skolothumtho, philmd, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar Hi Peter, Marc, On 5/15/26 11:04 AM, Marc Zyngier wrote: > On Fri, 15 May 2026 09:31:19 +0100, > Peter Maydell <peter.maydell@linaro.org> wrote: >> So if the user asks to set ID registers to an architecturally >> invalid combination (e.g. one that reports FEAT_X but not >> FEAT_Y even though FEAT_X is supposed to imply FEAT_Y, or >> one where one ID register says we have FEAT_X but a different >> ID register says we don't have FEAT_X), what happens ? >> Do we catch and reject that? Does the kernel reject that? >> Or do we just report to the guest what the user asked for, >> and if they asked for something broken they can keep both >> pieces ? > I fully expect the latter. Neither the kernel nor QEMU can enforce > this short of encoding all the various dependencies, which have the > horrible habit of changing over time. The only thing we can > realistically reason about is a single idreg at a time. Effectively at the moment the series does not implement any consistency check at qemu level (neither on the individual value nor any cross check with other ID reg field values). For individual setting we fully rely on KVM check. Thanks Eric > > Thanks, > > M. > ^ permalink raw reply [flat|nested] 39+ messages in thread
end of thread, other threads:[~2026-05-15 16:41 UTC | newest] Thread overview: 39+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-05-03 7:33 [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger 2026-05-03 7:33 ` [PATCH v4 01/17] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py Eric Auger 2026-05-03 7:33 ` [PATCH v4 02/17] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order Eric Auger 2026-05-06 16:10 ` Shameer Kolothum Thodi 2026-05-12 6:24 ` Eric Auger 2026-05-03 7:33 ` [PATCH v4 03/17] target/arm/cpu-sysregs.h.inc: Update with automatic generation Eric Auger 2026-05-07 8:45 ` Shameer Kolothum Thodi 2026-05-12 6:38 ` Eric Auger 2026-05-12 9:41 ` Shameer Kolothum Thodi 2026-05-12 14:11 ` Eric Auger 2026-05-03 7:33 ` [PATCH v4 04/17] arm/cpu: Add infra to handle generated ID register definitions Eric Auger 2026-05-07 8:58 ` Shameer Kolothum Thodi 2026-05-12 14:52 ` Eric Auger 2026-05-03 7:33 ` [PATCH v4 05/17] scripts: Introduce scripts/aarch64_sysreg_helpers module Eric Auger 2026-05-03 7:33 ` [PATCH v4 06/17] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py Eric Auger 2026-05-03 7:33 ` [PATCH v4 07/17] target/arm/cpu-sysreg-properties.c: Generate code with new script Eric Auger 2026-05-03 7:33 ` [PATCH v4 08/17] target/arm/kvm: Introduce kvm_get_writable_id_regs Eric Auger 2026-05-07 10:07 ` Shameer Kolothum Thodi 2026-05-12 15:12 ` Eric Auger 2026-05-03 7:33 ` [PATCH v4 09/17] arm/cpu: accessors for writable id registers Eric Auger 2026-05-07 10:32 ` Shameer Kolothum Thodi 2026-05-12 15:33 ` Eric Auger 2026-05-03 7:33 ` [PATCH v4 10/17] arm/kvm: Allow reading all the writable ID registers Eric Auger 2026-05-07 11:50 ` Shameer Kolothum Thodi 2026-05-03 7:33 ` [PATCH v4 11/17] arm/kvm: write back modified ID regs to KVM Eric Auger 2026-05-07 18:53 ` Shameer Kolothum Thodi 2026-05-08 13:03 ` Shameer Kolothum Thodi 2026-05-03 7:33 ` [PATCH v4 12/17] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties Eric Auger 2026-05-07 19:10 ` Shameer Kolothum Thodi 2026-05-03 7:33 ` [PATCH v4 13/17] target/arm/kvm: Special case REVIDR_EL1 and AIDR_EL1 Eric Auger 2026-05-03 7:33 ` [PATCH v4 14/17] target/arm/kvm: Special case ID_AA64ISAR0_EL1 RES0 [24, 27] bits Eric Auger 2026-05-03 7:33 ` [PATCH v4 15/17] arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model Eric Auger 2026-05-07 19:22 ` Shameer Kolothum Thodi 2026-05-03 7:33 ` [PATCH v4 16/17] arm-qmp-cmds: introspection for ID register props Eric Auger 2026-05-03 7:33 ` [PATCH v4 17/17] arm/cpu-features: document ID reg properties Eric Auger 2026-05-07 19:44 ` Shameer Kolothum Thodi 2026-05-15 8:31 ` [PATCH v4 00/17] kvm/arm: Introduce a customizable aarch64 KVM host model Peter Maydell 2026-05-15 9:04 ` Marc Zyngier 2026-05-15 16:41 ` Eric Auger
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.