All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model
@ 2026-05-19 13:27 Eric Auger
  2026-05-19 13:27 ` [PATCH v5 01/18] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py Eric Auger
                   ` (18 more replies)
  0 siblings, 19 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, 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. 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-v5

History:
--------

v4 -> v5:
- generate target/arm/cpu-idregs.h.inc that look similar to
  the format used in [RFC PATCH v1 02/13] target/arm:
  named_cpu_model: Add ID Register Fields without the
  description of the value values nor safe policy/value.
  I guess valid values could be generated from the Registers.json
  file too. Safe policy/values cannot.
  I reused one patch from the above series.
  Let's see how both series can progress/coexist without any
  anticipated bias.
- Addressed all comments from Shameer on v4
- Addressed 2 comments from v4 that were missed including the
  issue of IDreg visibility affected by some other settings.
  Unfortunately I was not able to test it.
- Further look at overrides between low level id reg field
  properties versus legacy CPU options. I have the feeling they
  can coexist as long as we document the hierarchy between them:
  host kvm default -> ID reg field props -> legacy CPU options
- Noticed more writable fields that are RES0/RAZ
- Improved commit messages in general

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"}


Cornelia Huck (3):
  target/arm/kvm: Introduce kvm_get_writable_id_regs
  arm-qmp-cmds: introspection for ID register props
  arm/cpu-features: document ID reg properties

Eric Auger (14):
  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-idregs.h.inc: generate with script
  target/arm/cpu64: Retrieve writable ID reg map in
    aarch64_host_initfn()
  arm/kvm: Initialize all writable ID registers from host
  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: Ignore some writable bits that shouldn't be
  target/arm/cpu: Expose writable ID reg field properties on the kvm
    host vcpu model

Shaju Abraham (1):
  target/arm/cpu_idregs: generate tables for Arm64 ID registers and
    fields

 docs/system/arm/cpu-features.rst              | 106 ++-
 scripts/aarch64_sysreg_helpers.py             | 109 ++++
 .../update-aarch64-cpu-sysreg-properties.py   | 168 +++++
 scripts/update-aarch64-cpu-sysregs-header.py  |  51 ++
 target/arm/arm-qmp-cmds.c                     |  19 +
 target/arm/cpu-idregs.c                       |  50 ++
 target/arm/cpu-idregs.h                       |  33 +
 target/arm/cpu-idregs.h.inc                   | 617 ++++++++++++++++++
 target/arm/cpu-sysregs.h.inc                  |  57 +-
 target/arm/cpu.h                              |   3 +
 target/arm/cpu64.c                            |  14 +
 target/arm/kvm-stub.c                         |   5 +
 target/arm/kvm.c                              | 320 ++++++++-
 target/arm/kvm_arm.h                          |  12 +
 target/arm/meson.build                        |   1 +
 target/arm/trace-events                       |   6 +
 16 files changed, 1539 insertions(+), 32 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.c
 create mode 100644 target/arm/cpu-idregs.h
 create mode 100644 target/arm/cpu-idregs.h.inc

-- 
2.53.0


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

* [PATCH v5 01/18] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-19 13:27 ` [PATCH v5 02/18] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order Eric Auger
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, 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] 74+ messages in thread

* [PATCH v5 02/18] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
  2026-05-19 13:27 ` [PATCH v5 01/18] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-06-01 14:07   ` Shameer Kolothum Thodi
  2026-05-19 13:27 ` [PATCH v5 03/18] target/arm/cpu-sysregs.h.inc: Update with automatic generation Eric Auger
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, sebott, skolothumtho, philmd
  Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar

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>

---

v4 -> v5:
- remove spurious CCSIDR definition
---
 target/arm/cpu-sysregs.h.inc | 42 ++++++++++++++++++------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc
index 3d1ed40f04..a044596135 100644
--- a/target/arm/cpu-sysregs.h.inc
+++ b/target/arm/cpu-sysregs.h.inc
@@ -1,12 +1,11 @@
 /* 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(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 +14,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] 74+ messages in thread

* [PATCH v5 03/18] target/arm/cpu-sysregs.h.inc: Update with automatic generation
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
  2026-05-19 13:27 ` [PATCH v5 01/18] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py Eric Auger
  2026-05-19 13:27 ` [PATCH v5 02/18] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-06-01 14:09   ` Shameer Kolothum Thodi
  2026-05-19 13:27 ` [PATCH v5 04/18] arm/cpu: Add infra to handle generated ID register definitions Eric Auger
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, 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>
---
 target/arm/cpu-sysregs.h.inc | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc
index a044596135..2188cd7be0 100644
--- a/target/arm/cpu-sysregs.h.inc
+++ b/target/arm/cpu-sysregs.h.inc
@@ -1,14 +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)
@@ -38,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] 74+ messages in thread

* [PATCH v5 04/18] arm/cpu: Add infra to handle generated ID register definitions
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (2 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 03/18] target/arm/cpu-sysregs.h.inc: Update with automatic generation Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-21 13:23   ` Sebastian Ott
  2026-06-01 14:28   ` Shameer Kolothum Thodi
  2026-05-19 13:27 ` [PATCH v5 05/18] scripts: Introduce scripts/aarch64_sysreg_helpers module Eric Auger
                   ` (14 subsequent siblings)
  18 siblings, 2 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, 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.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>

---

v4 -> v5
- ifdef TARGET_ARM_CPU_IDREGS_H
- s/g_list_append/g_list_prepend
- void arm64_sysreg_add_field()
---
 target/arm/cpu-idregs.h | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 target/arm/cpu-idregs.h

diff --git a/target/arm/cpu-idregs.h b/target/arm/cpu-idregs.h
new file mode 100644
index 0000000000..664e2d6ddd
--- /dev/null
+++ b/target/arm/cpu-idregs.h
@@ -0,0 +1,33 @@
+/*
+ * handle ID registers and their fields
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef TARGET_ARM_CPU_IDREGS_H
+#define 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 shift; /* lsb of the field in the register */
+    int length; /* highest bit number */
+} ARM64SysRegField;
+
+typedef struct ARM64SysReg {
+    const char *name;   /* name of the sysreg, for instance CTR_EL0 */
+    ARMIDRegisterIdx index; /* register index, e.g. CTR_EL0_IDX */
+    struct ARM64SysRegField *fields;
+    uint32_t fields_count;
+} ARM64SysReg;
+
+/*
+ * List of exposed ID regs (automatically populated from AARCHMRS Registers.json)
+ */
+extern ARM64SysReg arm64_id_regs[NUM_ID_IDX];
+
+#endif
-- 
2.53.0


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

* [PATCH v5 05/18] scripts: Introduce scripts/aarch64_sysreg_helpers module
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (3 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 04/18] arm/cpu: Add infra to handle generated ID register definitions Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-19 13:27 ` [PATCH v5 06/18] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py Eric Auger
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, 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] 74+ messages in thread

* [PATCH v5 06/18] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (4 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 05/18] scripts: Introduce scripts/aarch64_sysreg_helpers module Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-27 14:35   ` Khushit Shah
  2026-05-19 13:27 ` [PATCH v5 07/18] target/arm/cpu-idregs.h.inc: generate with script Eric Auger
                   ` (12 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, 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-idregs.h.inc 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   | 168 ++++++++++++++++++
 1 file changed, 168 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..3571e228ee
--- /dev/null
+++ b/scripts/update-aarch64-cpu-sysreg-properties.py
@@ -0,0 +1,168 @@
+#!/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
+
+    # 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))
+
+    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"    IDREG_START({reg_name})\n"
+
+        unique_fields = {}
+        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'))
+                    width = r.get('width')
+                    msb = lsb + int(width) - 1
+
+                    # 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, 'width': width}
+
+        # 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"    IDREG_FIELD({reg_name}, "
+                    f"{name}, {bits['lsb']}, {bits['width']})\n")
+            final_output += line
+        final_output += f"    IDREG_END({reg_name})\n"
+        final_output += "\n"
+
+    os.makedirs("target/arm", exist_ok=True)
+    with open("target/arm/cpu-idregs.h.inc", 'w') as f:
+        f.write("/* AUTOMATICALLY GENERATED, DO NOT MODIFY */\n\n")
+        f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
+        f.write("/* IDREG_START(REG) */\n")
+        f.write("/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */\n")
+        f.write("/* ... */\n")
+        f.write("/* IDREG_END(REG) */\n\n")
+        f.write(final_output)
+
+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-idregs.h.inc")
-- 
2.53.0


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

* [PATCH v5 07/18] target/arm/cpu-idregs.h.inc: generate with script
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (5 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 06/18] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-19 13:27 ` [PATCH v5 08/18] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields Eric Auger
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, sebott, skolothumtho, philmd
  Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar

Generate ID reg definitions with the scripts/update-aarch64-cpu-sysreg-properties.py
based on AARCHMRS_OPENSOURCE_A_profile_FAT-2026-03 Registers.json

Each register and fields are described with this pattern:

IDREG_START(REG)
IDREG_FIELD(REG, FIELD, SHIFT, LENGTH)
...
IDREG_END(REG)

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Suggested-by: Khushit Shah <khushit.shah@nutanix.com>
Suggested-by: Shaju Abraham <shaju.abraham@nutanix.com>
---
 target/arm/cpu-idregs.h.inc | 617 ++++++++++++++++++++++++++++++++++++
 1 file changed, 617 insertions(+)
 create mode 100644 target/arm/cpu-idregs.h.inc

diff --git a/target/arm/cpu-idregs.h.inc b/target/arm/cpu-idregs.h.inc
new file mode 100644
index 0000000000..7832c52ef7
--- /dev/null
+++ b/target/arm/cpu-idregs.h.inc
@@ -0,0 +1,617 @@
+/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/* IDREG_START(REG) */
+/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */
+/* ... */
+/* IDREG_END(REG) */
+
+    IDREG_START(AIDR_EL1)
+    IDREG_END(AIDR_EL1)
+
+    IDREG_START(CCSIDR2_EL1)
+    IDREG_FIELD(CCSIDR2_EL1, NumSets, 0, 24)
+    IDREG_END(CCSIDR2_EL1)
+
+    IDREG_START(CCSIDR_EL1)
+    IDREG_FIELD(CCSIDR_EL1, NumSets, 32, 24)
+    IDREG_FIELD(CCSIDR_EL1, Associativity, 3, 21)
+    IDREG_FIELD(CCSIDR_EL1, LineSize, 0, 3)
+    IDREG_END(CCSIDR_EL1)
+
+    IDREG_START(CLIDR_EL1)
+    IDREG_FIELD(CLIDR_EL1, Ttype7, 45, 2)
+    IDREG_FIELD(CLIDR_EL1, Ttype6, 43, 2)
+    IDREG_FIELD(CLIDR_EL1, Ttype5, 41, 2)
+    IDREG_FIELD(CLIDR_EL1, Ttype4, 39, 2)
+    IDREG_FIELD(CLIDR_EL1, Ttype3, 37, 2)
+    IDREG_FIELD(CLIDR_EL1, Ttype2, 35, 2)
+    IDREG_FIELD(CLIDR_EL1, Ttype1, 33, 2)
+    IDREG_FIELD(CLIDR_EL1, ICB, 30, 3)
+    IDREG_FIELD(CLIDR_EL1, LoUU, 27, 3)
+    IDREG_FIELD(CLIDR_EL1, LoC, 24, 3)
+    IDREG_FIELD(CLIDR_EL1, LoUIS, 21, 3)
+    IDREG_FIELD(CLIDR_EL1, Ctype7, 18, 3)
+    IDREG_FIELD(CLIDR_EL1, Ctype6, 15, 3)
+    IDREG_FIELD(CLIDR_EL1, Ctype5, 12, 3)
+    IDREG_FIELD(CLIDR_EL1, Ctype4, 9, 3)
+    IDREG_FIELD(CLIDR_EL1, Ctype3, 6, 3)
+    IDREG_FIELD(CLIDR_EL1, Ctype2, 3, 3)
+    IDREG_FIELD(CLIDR_EL1, Ctype1, 0, 3)
+    IDREG_END(CLIDR_EL1)
+
+    IDREG_START(CTR_EL0)
+    IDREG_FIELD(CTR_EL0, TminLine, 32, 6)
+    IDREG_FIELD(CTR_EL0, DIC, 29, 1)
+    IDREG_FIELD(CTR_EL0, IDC, 28, 1)
+    IDREG_FIELD(CTR_EL0, CWG, 24, 4)
+    IDREG_FIELD(CTR_EL0, ERG, 20, 4)
+    IDREG_FIELD(CTR_EL0, DminLine, 16, 4)
+    IDREG_FIELD(CTR_EL0, L1Ip, 14, 2)
+    IDREG_FIELD(CTR_EL0, IminLine, 0, 4)
+    IDREG_END(CTR_EL0)
+
+    IDREG_START(DCZID_EL0)
+    IDREG_FIELD(DCZID_EL0, TBS, 5, 4)
+    IDREG_FIELD(DCZID_EL0, DZP, 4, 1)
+    IDREG_FIELD(DCZID_EL0, BS, 0, 4)
+    IDREG_END(DCZID_EL0)
+
+    IDREG_START(GMID_EL1)
+    IDREG_FIELD(GMID_EL1, BS, 0, 4)
+    IDREG_END(GMID_EL1)
+
+    IDREG_START(ID_AA64AFR0_EL1)
+    IDREG_END(ID_AA64AFR0_EL1)
+
+    IDREG_START(ID_AA64AFR1_EL1)
+    IDREG_END(ID_AA64AFR1_EL1)
+
+    IDREG_START(ID_AA64DFR0_EL1)
+    IDREG_FIELD(ID_AA64DFR0_EL1, HPMN0, 60, 4)
+    IDREG_FIELD(ID_AA64DFR0_EL1, ExtTrcBuff, 56, 4)
+    IDREG_FIELD(ID_AA64DFR0_EL1, BRBE, 52, 4)
+    IDREG_FIELD(ID_AA64DFR0_EL1, MTPMU, 48, 4)
+    IDREG_FIELD(ID_AA64DFR0_EL1, TraceBuffer, 44, 4)
+    IDREG_FIELD(ID_AA64DFR0_EL1, TraceFilt, 40, 4)
+    IDREG_FIELD(ID_AA64DFR0_EL1, DoubleLock, 36, 4)
+    IDREG_FIELD(ID_AA64DFR0_EL1, PMSVer, 32, 4)
+    IDREG_FIELD(ID_AA64DFR0_EL1, CTX_CMPs, 28, 4)
+    IDREG_FIELD(ID_AA64DFR0_EL1, WRPs, 20, 4)
+    IDREG_FIELD(ID_AA64DFR0_EL1, PMSS, 16, 4)
+    IDREG_FIELD(ID_AA64DFR0_EL1, BRPs, 12, 4)
+    IDREG_FIELD(ID_AA64DFR0_EL1, PMUVer, 8, 4)
+    IDREG_FIELD(ID_AA64DFR0_EL1, TraceVer, 4, 4)
+    IDREG_FIELD(ID_AA64DFR0_EL1, DebugVer, 0, 4)
+    IDREG_END(ID_AA64DFR0_EL1)
+
+    IDREG_START(ID_AA64DFR1_EL1)
+    IDREG_FIELD(ID_AA64DFR1_EL1, ABL_CMPs, 56, 8)
+    IDREG_FIELD(ID_AA64DFR1_EL1, DPFZS, 52, 4)
+    IDREG_FIELD(ID_AA64DFR1_EL1, EBEP, 48, 4)
+    IDREG_FIELD(ID_AA64DFR1_EL1, ITE, 44, 4)
+    IDREG_FIELD(ID_AA64DFR1_EL1, ABLE, 40, 4)
+    IDREG_FIELD(ID_AA64DFR1_EL1, PMICNTR, 36, 4)
+    IDREG_FIELD(ID_AA64DFR1_EL1, SPMU, 32, 4)
+    IDREG_FIELD(ID_AA64DFR1_EL1, CTX_CMPs, 24, 8)
+    IDREG_FIELD(ID_AA64DFR1_EL1, WRPs, 16, 8)
+    IDREG_FIELD(ID_AA64DFR1_EL1, BRPs, 8, 8)
+    IDREG_FIELD(ID_AA64DFR1_EL1, SYSPMUID, 0, 8)
+    IDREG_END(ID_AA64DFR1_EL1)
+
+    IDREG_START(ID_AA64DFR2_EL1)
+    IDREG_FIELD(ID_AA64DFR2_EL1, TRBE_EXC, 24, 4)
+    IDREG_FIELD(ID_AA64DFR2_EL1, SPE_nVM, 20, 4)
+    IDREG_FIELD(ID_AA64DFR2_EL1, SPE_EXC, 16, 4)
+    IDREG_FIELD(ID_AA64DFR2_EL1, BWE, 4, 4)
+    IDREG_FIELD(ID_AA64DFR2_EL1, STEP, 0, 4)
+    IDREG_END(ID_AA64DFR2_EL1)
+
+    IDREG_START(ID_AA64FPFR0_EL1)
+    IDREG_FIELD(ID_AA64FPFR0_EL1, F8CVT, 31, 1)
+    IDREG_FIELD(ID_AA64FPFR0_EL1, F8FMA, 30, 1)
+    IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP4, 29, 1)
+    IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP2, 28, 1)
+    IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM8, 27, 1)
+    IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM4, 26, 1)
+    IDREG_FIELD(ID_AA64FPFR0_EL1, F16MM2, 15, 1)
+    IDREG_FIELD(ID_AA64FPFR0_EL1, F8E4M3, 1, 1)
+    IDREG_FIELD(ID_AA64FPFR0_EL1, F8E5M2, 0, 1)
+    IDREG_END(ID_AA64FPFR0_EL1)
+
+    IDREG_START(ID_AA64ISAR0_EL1)
+    IDREG_FIELD(ID_AA64ISAR0_EL1, RNDR, 60, 4)
+    IDREG_FIELD(ID_AA64ISAR0_EL1, TLB, 56, 4)
+    IDREG_FIELD(ID_AA64ISAR0_EL1, TS, 52, 4)
+    IDREG_FIELD(ID_AA64ISAR0_EL1, FHM, 48, 4)
+    IDREG_FIELD(ID_AA64ISAR0_EL1, DP, 44, 4)
+    IDREG_FIELD(ID_AA64ISAR0_EL1, SM4, 40, 4)
+    IDREG_FIELD(ID_AA64ISAR0_EL1, SM3, 36, 4)
+    IDREG_FIELD(ID_AA64ISAR0_EL1, SHA3, 32, 4)
+    IDREG_FIELD(ID_AA64ISAR0_EL1, RDM, 28, 4)
+    IDREG_FIELD(ID_AA64ISAR0_EL1, Atomic, 20, 4)
+    IDREG_FIELD(ID_AA64ISAR0_EL1, CRC32, 16, 4)
+    IDREG_FIELD(ID_AA64ISAR0_EL1, SHA2, 12, 4)
+    IDREG_FIELD(ID_AA64ISAR0_EL1, SHA1, 8, 4)
+    IDREG_FIELD(ID_AA64ISAR0_EL1, AES, 4, 4)
+    IDREG_END(ID_AA64ISAR0_EL1)
+
+    IDREG_START(ID_AA64ISAR1_EL1)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, LS64, 60, 4)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, XS, 56, 4)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, I8MM, 52, 4)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, DGH, 48, 4)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, BF16, 44, 4)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, SPECRES, 40, 4)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, SB, 36, 4)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, FRINTTS, 32, 4)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, GPI, 28, 4)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, GPA, 24, 4)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, LRCPC, 20, 4)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, FCMA, 16, 4)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, JSCVT, 12, 4)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, API, 8, 4)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, APA, 4, 4)
+    IDREG_FIELD(ID_AA64ISAR1_EL1, DPB, 0, 4)
+    IDREG_END(ID_AA64ISAR1_EL1)
+
+    IDREG_START(ID_AA64ISAR2_EL1)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, ATS1A, 60, 4)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, LUT, 56, 4)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, CSSC, 52, 4)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, RPRFM, 48, 4)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, PCDPHINT, 44, 4)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, PRFMSLC, 40, 4)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, SYSINSTR_128, 36, 4)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, SYSREG_128, 32, 4)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, CLRBHB, 28, 4)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, PAC_frac, 24, 4)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, BC, 20, 4)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, MOPS, 16, 4)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, APA3, 12, 4)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, GPA3, 8, 4)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, RPRES, 4, 4)
+    IDREG_FIELD(ID_AA64ISAR2_EL1, WFxT, 0, 4)
+    IDREG_END(ID_AA64ISAR2_EL1)
+
+    IDREG_START(ID_AA64ISAR3_EL1)
+    IDREG_FIELD(ID_AA64ISAR3_EL1, LSCP, 44, 4)
+    IDREG_FIELD(ID_AA64ISAR3_EL1, LSCSHINT, 40, 4)
+    IDREG_FIELD(ID_AA64ISAR3_EL1, MTETC, 36, 4)
+    IDREG_FIELD(ID_AA64ISAR3_EL1, PAC_frac2, 32, 4)
+    IDREG_FIELD(ID_AA64ISAR3_EL1, FPRCVT, 28, 4)
+    IDREG_FIELD(ID_AA64ISAR3_EL1, LSUI, 24, 4)
+    IDREG_FIELD(ID_AA64ISAR3_EL1, OCCMO, 20, 4)
+    IDREG_FIELD(ID_AA64ISAR3_EL1, LSFE, 16, 4)
+    IDREG_FIELD(ID_AA64ISAR3_EL1, PACM, 12, 4)
+    IDREG_FIELD(ID_AA64ISAR3_EL1, TLBIW, 8, 4)
+    IDREG_FIELD(ID_AA64ISAR3_EL1, FAMINMAX, 4, 4)
+    IDREG_FIELD(ID_AA64ISAR3_EL1, CPA, 0, 4)
+    IDREG_END(ID_AA64ISAR3_EL1)
+
+    IDREG_START(ID_AA64MMFR0_EL1)
+    IDREG_FIELD(ID_AA64MMFR0_EL1, ECV, 60, 4)
+    IDREG_FIELD(ID_AA64MMFR0_EL1, FGT, 56, 4)
+    IDREG_FIELD(ID_AA64MMFR0_EL1, ExS, 44, 4)
+    IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4_2, 40, 4)
+    IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64_2, 36, 4)
+    IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16_2, 32, 4)
+    IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4, 28, 4)
+    IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64, 24, 4)
+    IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16, 20, 4)
+    IDREG_FIELD(ID_AA64MMFR0_EL1, BigEndEL0, 16, 4)
+    IDREG_FIELD(ID_AA64MMFR0_EL1, SNSMem, 12, 4)
+    IDREG_FIELD(ID_AA64MMFR0_EL1, BigEnd, 8, 4)
+    IDREG_FIELD(ID_AA64MMFR0_EL1, ASIDBits, 4, 4)
+    IDREG_FIELD(ID_AA64MMFR0_EL1, PARange, 0, 4)
+    IDREG_END(ID_AA64MMFR0_EL1)
+
+    IDREG_START(ID_AA64MMFR1_EL1)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, ECBHB, 60, 4)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, CMOW, 56, 4)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, TIDCP1, 52, 4)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, nTLBPA, 48, 4)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, AFP, 44, 4)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, HCX, 40, 4)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, ETS, 36, 4)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, TWED, 32, 4)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, XNX, 28, 4)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, SpecSEI, 24, 4)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, PAN, 20, 4)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, LO, 16, 4)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, HPDS, 12, 4)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, VH, 8, 4)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, VMIDBits, 4, 4)
+    IDREG_FIELD(ID_AA64MMFR1_EL1, HAFDBS, 0, 4)
+    IDREG_END(ID_AA64MMFR1_EL1)
+
+    IDREG_START(ID_AA64MMFR2_EL1)
+    IDREG_FIELD(ID_AA64MMFR2_EL1, E0PD, 60, 4)
+    IDREG_FIELD(ID_AA64MMFR2_EL1, EVT, 56, 4)
+    IDREG_FIELD(ID_AA64MMFR2_EL1, BBM, 52, 4)
+    IDREG_FIELD(ID_AA64MMFR2_EL1, TTL, 48, 4)
+    IDREG_FIELD(ID_AA64MMFR2_EL1, FWB, 40, 4)
+    IDREG_FIELD(ID_AA64MMFR2_EL1, IDS, 36, 4)
+    IDREG_FIELD(ID_AA64MMFR2_EL1, AT, 32, 4)
+    IDREG_FIELD(ID_AA64MMFR2_EL1, ST, 28, 4)
+    IDREG_FIELD(ID_AA64MMFR2_EL1, NV, 24, 4)
+    IDREG_FIELD(ID_AA64MMFR2_EL1, CCIDX, 20, 4)
+    IDREG_FIELD(ID_AA64MMFR2_EL1, VARange, 16, 4)
+    IDREG_FIELD(ID_AA64MMFR2_EL1, IESB, 12, 4)
+    IDREG_FIELD(ID_AA64MMFR2_EL1, LSM, 8, 4)
+    IDREG_FIELD(ID_AA64MMFR2_EL1, UAO, 4, 4)
+    IDREG_FIELD(ID_AA64MMFR2_EL1, CnP, 0, 4)
+    IDREG_END(ID_AA64MMFR2_EL1)
+
+    IDREG_START(ID_AA64MMFR3_EL1)
+    IDREG_FIELD(ID_AA64MMFR3_EL1, Spec_FPACC, 60, 4)
+    IDREG_FIELD(ID_AA64MMFR3_EL1, ADERR, 56, 4)
+    IDREG_FIELD(ID_AA64MMFR3_EL1, SDERR, 52, 4)
+    IDREG_FIELD(ID_AA64MMFR3_EL1, ANERR, 44, 4)
+    IDREG_FIELD(ID_AA64MMFR3_EL1, SNERR, 40, 4)
+    IDREG_FIELD(ID_AA64MMFR3_EL1, D128_2, 36, 4)
+    IDREG_FIELD(ID_AA64MMFR3_EL1, D128, 32, 4)
+    IDREG_FIELD(ID_AA64MMFR3_EL1, MEC, 28, 4)
+    IDREG_FIELD(ID_AA64MMFR3_EL1, AIE, 24, 4)
+    IDREG_FIELD(ID_AA64MMFR3_EL1, S2POE, 20, 4)
+    IDREG_FIELD(ID_AA64MMFR3_EL1, S1POE, 16, 4)
+    IDREG_FIELD(ID_AA64MMFR3_EL1, S2PIE, 12, 4)
+    IDREG_FIELD(ID_AA64MMFR3_EL1, S1PIE, 8, 4)
+    IDREG_FIELD(ID_AA64MMFR3_EL1, SCTLRX, 4, 4)
+    IDREG_FIELD(ID_AA64MMFR3_EL1, TCRX, 0, 4)
+    IDREG_END(ID_AA64MMFR3_EL1)
+
+    IDREG_START(ID_AA64MMFR4_EL1)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, MTEFGT, 60, 4)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, SCRX, 56, 4)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, TEV, 52, 4)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, TPS, 48, 4)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, SRMASK, 44, 4)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, TLBID, 40, 4)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, E3DSE, 36, 4)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, EAESR, 32, 4)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, RMEGDI, 28, 4)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, E2H0, 24, 4)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, NV_frac, 20, 4)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, FGWTE3, 16, 4)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, HACDBS, 12, 4)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, ASID2, 8, 4)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, EIESB, 4, 4)
+    IDREG_FIELD(ID_AA64MMFR4_EL1, PoPS, 0, 4)
+    IDREG_END(ID_AA64MMFR4_EL1)
+
+    IDREG_START(ID_AA64PFR0_EL1)
+    IDREG_FIELD(ID_AA64PFR0_EL1, CSV3, 60, 4)
+    IDREG_FIELD(ID_AA64PFR0_EL1, CSV2, 56, 4)
+    IDREG_FIELD(ID_AA64PFR0_EL1, RME, 52, 4)
+    IDREG_FIELD(ID_AA64PFR0_EL1, DIT, 48, 4)
+    IDREG_FIELD(ID_AA64PFR0_EL1, AMU, 44, 4)
+    IDREG_FIELD(ID_AA64PFR0_EL1, MPAM, 40, 4)
+    IDREG_FIELD(ID_AA64PFR0_EL1, SEL2, 36, 4)
+    IDREG_FIELD(ID_AA64PFR0_EL1, SVE, 32, 4)
+    IDREG_FIELD(ID_AA64PFR0_EL1, RAS, 28, 4)
+    IDREG_FIELD(ID_AA64PFR0_EL1, GIC, 24, 4)
+    IDREG_FIELD(ID_AA64PFR0_EL1, AdvSIMD, 20, 4)
+    IDREG_FIELD(ID_AA64PFR0_EL1, FP, 16, 4)
+    IDREG_FIELD(ID_AA64PFR0_EL1, EL3, 12, 4)
+    IDREG_FIELD(ID_AA64PFR0_EL1, EL2, 8, 4)
+    IDREG_FIELD(ID_AA64PFR0_EL1, EL1, 4, 4)
+    IDREG_FIELD(ID_AA64PFR0_EL1, EL0, 0, 4)
+    IDREG_END(ID_AA64PFR0_EL1)
+
+    IDREG_START(ID_AA64PFR1_EL1)
+    IDREG_FIELD(ID_AA64PFR1_EL1, PFAR, 60, 4)
+    IDREG_FIELD(ID_AA64PFR1_EL1, DF2, 56, 4)
+    IDREG_FIELD(ID_AA64PFR1_EL1, MTEX, 52, 4)
+    IDREG_FIELD(ID_AA64PFR1_EL1, THE, 48, 4)
+    IDREG_FIELD(ID_AA64PFR1_EL1, GCS, 44, 4)
+    IDREG_FIELD(ID_AA64PFR1_EL1, MTE_frac, 40, 4)
+    IDREG_FIELD(ID_AA64PFR1_EL1, NMI, 36, 4)
+    IDREG_FIELD(ID_AA64PFR1_EL1, CSV2_frac, 32, 4)
+    IDREG_FIELD(ID_AA64PFR1_EL1, RNDR_trap, 28, 4)
+    IDREG_FIELD(ID_AA64PFR1_EL1, SME, 24, 4)
+    IDREG_FIELD(ID_AA64PFR1_EL1, MPAM_frac, 16, 4)
+    IDREG_FIELD(ID_AA64PFR1_EL1, RAS_frac, 12, 4)
+    IDREG_FIELD(ID_AA64PFR1_EL1, MTE, 8, 4)
+    IDREG_FIELD(ID_AA64PFR1_EL1, SSBS, 4, 4)
+    IDREG_FIELD(ID_AA64PFR1_EL1, BT, 0, 4)
+    IDREG_END(ID_AA64PFR1_EL1)
+
+    IDREG_START(ID_AA64PFR2_EL1)
+    IDREG_FIELD(ID_AA64PFR2_EL1, VMTETCL, 44, 4)
+    IDREG_FIELD(ID_AA64PFR2_EL1, VMTETC, 40, 4)
+    IDREG_FIELD(ID_AA64PFR2_EL1, VMTE, 36, 4)
+    IDREG_FIELD(ID_AA64PFR2_EL1, FPMR, 32, 4)
+    IDREG_FIELD(ID_AA64PFR2_EL1, MPAM2, 28, 4)
+    IDREG_FIELD(ID_AA64PFR2_EL1, FGDT, 24, 4)
+    IDREG_FIELD(ID_AA64PFR2_EL1, MTEEIRG, 20, 4)
+    IDREG_FIELD(ID_AA64PFR2_EL1, UINJ, 16, 4)
+    IDREG_FIELD(ID_AA64PFR2_EL1, GCIE, 12, 4)
+    IDREG_FIELD(ID_AA64PFR2_EL1, MTEFAR, 8, 4)
+    IDREG_FIELD(ID_AA64PFR2_EL1, MTESTOREONLY, 4, 4)
+    IDREG_FIELD(ID_AA64PFR2_EL1, MTEPERM, 0, 4)
+    IDREG_END(ID_AA64PFR2_EL1)
+
+    IDREG_START(ID_AA64SMFR0_EL1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, FA64, 63, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, LUT6, 61, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, LUTv2, 60, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, SMEver, 56, 4)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, I16I64, 52, 4)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, F64F64, 48, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, I16I32, 44, 4)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, B16B16, 43, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, F16F16, 42, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, F8F16, 41, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, F8F32, 40, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, I8I32, 36, 4)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, F16F32, 35, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, B16F32, 34, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, BI32I32, 33, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, F32F32, 32, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, SF8FMA, 30, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP4, 29, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP2, 28, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, SBitPerm, 25, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, AES, 24, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, SFEXPA, 23, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, STMOP, 16, 1)
+    IDREG_FIELD(ID_AA64SMFR0_EL1, SMOP4, 0, 1)
+    IDREG_END(ID_AA64SMFR0_EL1)
+
+    IDREG_START(ID_AA64ZFR0_EL1)
+    IDREG_FIELD(ID_AA64ZFR0_EL1, F64MM, 56, 4)
+    IDREG_FIELD(ID_AA64ZFR0_EL1, F32MM, 52, 4)
+    IDREG_FIELD(ID_AA64ZFR0_EL1, F16MM, 48, 4)
+    IDREG_FIELD(ID_AA64ZFR0_EL1, I8MM, 44, 4)
+    IDREG_FIELD(ID_AA64ZFR0_EL1, SM4, 40, 4)
+    IDREG_FIELD(ID_AA64ZFR0_EL1, SHA3, 32, 4)
+    IDREG_FIELD(ID_AA64ZFR0_EL1, B16B16, 24, 4)
+    IDREG_FIELD(ID_AA64ZFR0_EL1, BF16, 20, 4)
+    IDREG_FIELD(ID_AA64ZFR0_EL1, BitPerm, 16, 4)
+    IDREG_FIELD(ID_AA64ZFR0_EL1, EltPerm, 12, 4)
+    IDREG_FIELD(ID_AA64ZFR0_EL1, AES, 4, 4)
+    IDREG_FIELD(ID_AA64ZFR0_EL1, SVEver, 0, 4)
+    IDREG_END(ID_AA64ZFR0_EL1)
+
+    IDREG_START(ID_AFR0_EL1)
+    IDREG_END(ID_AFR0_EL1)
+
+    IDREG_START(ID_DFR0_EL1)
+    IDREG_FIELD(ID_DFR0_EL1, TraceFilt, 28, 4)
+    IDREG_FIELD(ID_DFR0_EL1, PerfMon, 24, 4)
+    IDREG_FIELD(ID_DFR0_EL1, MProfDbg, 20, 4)
+    IDREG_FIELD(ID_DFR0_EL1, MMapTrc, 16, 4)
+    IDREG_FIELD(ID_DFR0_EL1, CopTrc, 12, 4)
+    IDREG_FIELD(ID_DFR0_EL1, MMapDbg, 8, 4)
+    IDREG_FIELD(ID_DFR0_EL1, CopSDbg, 4, 4)
+    IDREG_FIELD(ID_DFR0_EL1, CopDbg, 0, 4)
+    IDREG_END(ID_DFR0_EL1)
+
+    IDREG_START(ID_DFR1_EL1)
+    IDREG_FIELD(ID_DFR1_EL1, HPMN0, 4, 4)
+    IDREG_FIELD(ID_DFR1_EL1, MTPMU, 0, 4)
+    IDREG_END(ID_DFR1_EL1)
+
+    IDREG_START(ID_ISAR0_EL1)
+    IDREG_FIELD(ID_ISAR0_EL1, Divide, 24, 4)
+    IDREG_FIELD(ID_ISAR0_EL1, Debug, 20, 4)
+    IDREG_FIELD(ID_ISAR0_EL1, Coproc, 16, 4)
+    IDREG_FIELD(ID_ISAR0_EL1, CmpBranch, 12, 4)
+    IDREG_FIELD(ID_ISAR0_EL1, BitField, 8, 4)
+    IDREG_FIELD(ID_ISAR0_EL1, BitCount, 4, 4)
+    IDREG_FIELD(ID_ISAR0_EL1, Swap, 0, 4)
+    IDREG_END(ID_ISAR0_EL1)
+
+    IDREG_START(ID_ISAR1_EL1)
+    IDREG_FIELD(ID_ISAR1_EL1, Jazelle, 28, 4)
+    IDREG_FIELD(ID_ISAR1_EL1, Interwork, 24, 4)
+    IDREG_FIELD(ID_ISAR1_EL1, Immediate, 20, 4)
+    IDREG_FIELD(ID_ISAR1_EL1, IfThen, 16, 4)
+    IDREG_FIELD(ID_ISAR1_EL1, Extend, 12, 4)
+    IDREG_FIELD(ID_ISAR1_EL1, Except_AR, 8, 4)
+    IDREG_FIELD(ID_ISAR1_EL1, Except, 4, 4)
+    IDREG_FIELD(ID_ISAR1_EL1, Endian, 0, 4)
+    IDREG_END(ID_ISAR1_EL1)
+
+    IDREG_START(ID_ISAR2_EL1)
+    IDREG_FIELD(ID_ISAR2_EL1, Reversal, 28, 4)
+    IDREG_FIELD(ID_ISAR2_EL1, PSR_AR, 24, 4)
+    IDREG_FIELD(ID_ISAR2_EL1, MultU, 20, 4)
+    IDREG_FIELD(ID_ISAR2_EL1, MultS, 16, 4)
+    IDREG_FIELD(ID_ISAR2_EL1, Mult, 12, 4)
+    IDREG_FIELD(ID_ISAR2_EL1, MultiAccessInt, 8, 4)
+    IDREG_FIELD(ID_ISAR2_EL1, MemHint, 4, 4)
+    IDREG_FIELD(ID_ISAR2_EL1, LoadStore, 0, 4)
+    IDREG_END(ID_ISAR2_EL1)
+
+    IDREG_START(ID_ISAR3_EL1)
+    IDREG_FIELD(ID_ISAR3_EL1, T32EE, 28, 4)
+    IDREG_FIELD(ID_ISAR3_EL1, TrueNOP, 24, 4)
+    IDREG_FIELD(ID_ISAR3_EL1, T32Copy, 20, 4)
+    IDREG_FIELD(ID_ISAR3_EL1, TabBranch, 16, 4)
+    IDREG_FIELD(ID_ISAR3_EL1, SynchPrim, 12, 4)
+    IDREG_FIELD(ID_ISAR3_EL1, SVC, 8, 4)
+    IDREG_FIELD(ID_ISAR3_EL1, SIMD, 4, 4)
+    IDREG_FIELD(ID_ISAR3_EL1, Saturate, 0, 4)
+    IDREG_END(ID_ISAR3_EL1)
+
+    IDREG_START(ID_ISAR4_EL1)
+    IDREG_FIELD(ID_ISAR4_EL1, SWP_frac, 28, 4)
+    IDREG_FIELD(ID_ISAR4_EL1, PSR_M, 24, 4)
+    IDREG_FIELD(ID_ISAR4_EL1, SynchPrim_frac, 20, 4)
+    IDREG_FIELD(ID_ISAR4_EL1, Barrier, 16, 4)
+    IDREG_FIELD(ID_ISAR4_EL1, SMC, 12, 4)
+    IDREG_FIELD(ID_ISAR4_EL1, Writeback, 8, 4)
+    IDREG_FIELD(ID_ISAR4_EL1, WithShifts, 4, 4)
+    IDREG_FIELD(ID_ISAR4_EL1, Unpriv, 0, 4)
+    IDREG_END(ID_ISAR4_EL1)
+
+    IDREG_START(ID_ISAR5_EL1)
+    IDREG_FIELD(ID_ISAR5_EL1, VCMA, 28, 4)
+    IDREG_FIELD(ID_ISAR5_EL1, RDM, 24, 4)
+    IDREG_FIELD(ID_ISAR5_EL1, CRC32, 16, 4)
+    IDREG_FIELD(ID_ISAR5_EL1, SHA2, 12, 4)
+    IDREG_FIELD(ID_ISAR5_EL1, SHA1, 8, 4)
+    IDREG_FIELD(ID_ISAR5_EL1, AES, 4, 4)
+    IDREG_FIELD(ID_ISAR5_EL1, SEVL, 0, 4)
+    IDREG_END(ID_ISAR5_EL1)
+
+    IDREG_START(ID_ISAR6_EL1)
+    IDREG_FIELD(ID_ISAR6_EL1, CLRBHB, 28, 4)
+    IDREG_FIELD(ID_ISAR6_EL1, I8MM, 24, 4)
+    IDREG_FIELD(ID_ISAR6_EL1, BF16, 20, 4)
+    IDREG_FIELD(ID_ISAR6_EL1, SPECRES, 16, 4)
+    IDREG_FIELD(ID_ISAR6_EL1, SB, 12, 4)
+    IDREG_FIELD(ID_ISAR6_EL1, FHM, 8, 4)
+    IDREG_FIELD(ID_ISAR6_EL1, DP, 4, 4)
+    IDREG_FIELD(ID_ISAR6_EL1, JSCVT, 0, 4)
+    IDREG_END(ID_ISAR6_EL1)
+
+    IDREG_START(ID_MMFR0_EL1)
+    IDREG_FIELD(ID_MMFR0_EL1, InnerShr, 28, 4)
+    IDREG_FIELD(ID_MMFR0_EL1, FCSE, 24, 4)
+    IDREG_FIELD(ID_MMFR0_EL1, AuxReg, 20, 4)
+    IDREG_FIELD(ID_MMFR0_EL1, TCM, 16, 4)
+    IDREG_FIELD(ID_MMFR0_EL1, ShareLvl, 12, 4)
+    IDREG_FIELD(ID_MMFR0_EL1, OuterShr, 8, 4)
+    IDREG_FIELD(ID_MMFR0_EL1, PMSA, 4, 4)
+    IDREG_FIELD(ID_MMFR0_EL1, VMSA, 0, 4)
+    IDREG_END(ID_MMFR0_EL1)
+
+    IDREG_START(ID_MMFR1_EL1)
+    IDREG_FIELD(ID_MMFR1_EL1, BPred, 28, 4)
+    IDREG_FIELD(ID_MMFR1_EL1, L1TstCln, 24, 4)
+    IDREG_FIELD(ID_MMFR1_EL1, L1Uni, 20, 4)
+    IDREG_FIELD(ID_MMFR1_EL1, L1Hvd, 16, 4)
+    IDREG_FIELD(ID_MMFR1_EL1, L1UniSW, 12, 4)
+    IDREG_FIELD(ID_MMFR1_EL1, L1HvdSW, 8, 4)
+    IDREG_FIELD(ID_MMFR1_EL1, L1UniVA, 4, 4)
+    IDREG_FIELD(ID_MMFR1_EL1, L1HvdVA, 0, 4)
+    IDREG_END(ID_MMFR1_EL1)
+
+    IDREG_START(ID_MMFR2_EL1)
+    IDREG_FIELD(ID_MMFR2_EL1, HWAccFlg, 28, 4)
+    IDREG_FIELD(ID_MMFR2_EL1, WFIStall, 24, 4)
+    IDREG_FIELD(ID_MMFR2_EL1, MemBarr, 20, 4)
+    IDREG_FIELD(ID_MMFR2_EL1, UniTLB, 16, 4)
+    IDREG_FIELD(ID_MMFR2_EL1, HvdTLB, 12, 4)
+    IDREG_FIELD(ID_MMFR2_EL1, L1HvdRng, 8, 4)
+    IDREG_FIELD(ID_MMFR2_EL1, L1HvdBG, 4, 4)
+    IDREG_FIELD(ID_MMFR2_EL1, L1HvdFG, 0, 4)
+    IDREG_END(ID_MMFR2_EL1)
+
+    IDREG_START(ID_MMFR3_EL1)
+    IDREG_FIELD(ID_MMFR3_EL1, Supersec, 28, 4)
+    IDREG_FIELD(ID_MMFR3_EL1, CMemSz, 24, 4)
+    IDREG_FIELD(ID_MMFR3_EL1, CohWalk, 20, 4)
+    IDREG_FIELD(ID_MMFR3_EL1, PAN, 16, 4)
+    IDREG_FIELD(ID_MMFR3_EL1, MaintBcst, 12, 4)
+    IDREG_FIELD(ID_MMFR3_EL1, BPMaint, 8, 4)
+    IDREG_FIELD(ID_MMFR3_EL1, CMaintSW, 4, 4)
+    IDREG_FIELD(ID_MMFR3_EL1, CMaintVA, 0, 4)
+    IDREG_END(ID_MMFR3_EL1)
+
+    IDREG_START(ID_MMFR4_EL1)
+    IDREG_FIELD(ID_MMFR4_EL1, EVT, 28, 4)
+    IDREG_FIELD(ID_MMFR4_EL1, CCIDX, 24, 4)
+    IDREG_FIELD(ID_MMFR4_EL1, LSM, 20, 4)
+    IDREG_FIELD(ID_MMFR4_EL1, HPDS, 16, 4)
+    IDREG_FIELD(ID_MMFR4_EL1, CnP, 12, 4)
+    IDREG_FIELD(ID_MMFR4_EL1, XNX, 8, 4)
+    IDREG_FIELD(ID_MMFR4_EL1, AC2, 4, 4)
+    IDREG_FIELD(ID_MMFR4_EL1, SpecSEI, 0, 4)
+    IDREG_END(ID_MMFR4_EL1)
+
+    IDREG_START(ID_MMFR5_EL1)
+    IDREG_FIELD(ID_MMFR5_EL1, nTLBPA, 4, 4)
+    IDREG_FIELD(ID_MMFR5_EL1, ETS, 0, 4)
+    IDREG_END(ID_MMFR5_EL1)
+
+    IDREG_START(ID_PFR0_EL1)
+    IDREG_FIELD(ID_PFR0_EL1, RAS, 28, 4)
+    IDREG_FIELD(ID_PFR0_EL1, DIT, 24, 4)
+    IDREG_FIELD(ID_PFR0_EL1, AMU, 20, 4)
+    IDREG_FIELD(ID_PFR0_EL1, CSV2, 16, 4)
+    IDREG_FIELD(ID_PFR0_EL1, State3, 12, 4)
+    IDREG_FIELD(ID_PFR0_EL1, State2, 8, 4)
+    IDREG_FIELD(ID_PFR0_EL1, State1, 4, 4)
+    IDREG_FIELD(ID_PFR0_EL1, State0, 0, 4)
+    IDREG_END(ID_PFR0_EL1)
+
+    IDREG_START(ID_PFR1_EL1)
+    IDREG_FIELD(ID_PFR1_EL1, GIC, 28, 4)
+    IDREG_FIELD(ID_PFR1_EL1, Virt_frac, 24, 4)
+    IDREG_FIELD(ID_PFR1_EL1, Sec_frac, 20, 4)
+    IDREG_FIELD(ID_PFR1_EL1, GenTimer, 16, 4)
+    IDREG_FIELD(ID_PFR1_EL1, Virtualization, 12, 4)
+    IDREG_FIELD(ID_PFR1_EL1, MProgMod, 8, 4)
+    IDREG_FIELD(ID_PFR1_EL1, Security, 4, 4)
+    IDREG_FIELD(ID_PFR1_EL1, ProgMod, 0, 4)
+    IDREG_END(ID_PFR1_EL1)
+
+    IDREG_START(ID_PFR2_EL1)
+    IDREG_FIELD(ID_PFR2_EL1, RAS_frac, 8, 4)
+    IDREG_FIELD(ID_PFR2_EL1, SSBS, 4, 4)
+    IDREG_FIELD(ID_PFR2_EL1, CSV3, 0, 4)
+    IDREG_END(ID_PFR2_EL1)
+
+    IDREG_START(MIDR_EL1)
+    IDREG_FIELD(MIDR_EL1, Implementer, 24, 8)
+    IDREG_FIELD(MIDR_EL1, Variant, 20, 4)
+    IDREG_FIELD(MIDR_EL1, Architecture, 16, 4)
+    IDREG_FIELD(MIDR_EL1, PartNum, 4, 12)
+    IDREG_FIELD(MIDR_EL1, Revision, 0, 4)
+    IDREG_END(MIDR_EL1)
+
+    IDREG_START(MPIDR_EL1)
+    IDREG_FIELD(MPIDR_EL1, Aff3, 32, 8)
+    IDREG_FIELD(MPIDR_EL1, U, 30, 1)
+    IDREG_FIELD(MPIDR_EL1, MT, 24, 1)
+    IDREG_FIELD(MPIDR_EL1, Aff2, 16, 8)
+    IDREG_FIELD(MPIDR_EL1, Aff1, 8, 8)
+    IDREG_FIELD(MPIDR_EL1, Aff0, 0, 8)
+    IDREG_END(MPIDR_EL1)
+
+    IDREG_START(MVFR0_EL1)
+    IDREG_FIELD(MVFR0_EL1, FPRound, 28, 4)
+    IDREG_FIELD(MVFR0_EL1, FPShVec, 24, 4)
+    IDREG_FIELD(MVFR0_EL1, FPSqrt, 20, 4)
+    IDREG_FIELD(MVFR0_EL1, FPDivide, 16, 4)
+    IDREG_FIELD(MVFR0_EL1, FPTrap, 12, 4)
+    IDREG_FIELD(MVFR0_EL1, FPDP, 8, 4)
+    IDREG_FIELD(MVFR0_EL1, FPSP, 4, 4)
+    IDREG_FIELD(MVFR0_EL1, SIMDReg, 0, 4)
+    IDREG_END(MVFR0_EL1)
+
+    IDREG_START(MVFR1_EL1)
+    IDREG_FIELD(MVFR1_EL1, SIMDFMAC, 28, 4)
+    IDREG_FIELD(MVFR1_EL1, FPHP, 24, 4)
+    IDREG_FIELD(MVFR1_EL1, SIMDHP, 20, 4)
+    IDREG_FIELD(MVFR1_EL1, SIMDSP, 16, 4)
+    IDREG_FIELD(MVFR1_EL1, SIMDInt, 12, 4)
+    IDREG_FIELD(MVFR1_EL1, SIMDLS, 8, 4)
+    IDREG_FIELD(MVFR1_EL1, FPDNaN, 4, 4)
+    IDREG_FIELD(MVFR1_EL1, FPFtZ, 0, 4)
+    IDREG_END(MVFR1_EL1)
+
+    IDREG_START(MVFR2_EL1)
+    IDREG_FIELD(MVFR2_EL1, FPMisc, 4, 4)
+    IDREG_FIELD(MVFR2_EL1, SIMDMisc, 0, 4)
+    IDREG_END(MVFR2_EL1)
+
+    IDREG_START(REVIDR_EL1)
+    IDREG_END(REVIDR_EL1)
+
+    IDREG_START(SMIDR_EL1)
+    IDREG_FIELD(SMIDR_EL1, NSMC, 56, 4)
+    IDREG_FIELD(SMIDR_EL1, HIP, 52, 4)
+    IDREG_FIELD(SMIDR_EL1, Affinity2, 32, 20)
+    IDREG_FIELD(SMIDR_EL1, Implementer, 24, 8)
+    IDREG_FIELD(SMIDR_EL1, Revision, 16, 8)
+    IDREG_FIELD(SMIDR_EL1, SMPS, 15, 1)
+    IDREG_FIELD(SMIDR_EL1, SH, 13, 2)
+    IDREG_FIELD(SMIDR_EL1, Affinity, 0, 12)
+    IDREG_END(SMIDR_EL1)
+
-- 
2.53.0


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

* [PATCH v5 08/18] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (6 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 07/18] target/arm/cpu-idregs.h.inc: generate with script Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-21 13:27   ` Sebastian Ott
  2026-05-27 14:52   ` Khushit Shah
  2026-05-19 13:27 ` [PATCH v5 09/18] target/arm/kvm: Introduce kvm_get_writable_id_regs Eric Auger
                   ` (10 subsequent siblings)
  18 siblings, 2 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, sebott, skolothumtho, philmd
  Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar

From: Shaju Abraham <shaju.abraham@nutanix.com>

Include cpu-idregs.h.inc multiple times with different definitions for the
X-macros. This will generate tables for all Arm64 ID registers and their
fields. Additionally, initialize the tables with all architecturally defined
values. These tables will be consumed by the property layer in future
patches.

Co-authored-by: Khushit Shah <khushit.shah@nutanix.com>
Signed-off-by: Shaju Abraham <shaju.abraham@nutanix.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 target/arm/cpu-idregs.c | 50 +++++++++++++++++++++++++++++++++++++++++
 target/arm/meson.build  |  1 +
 2 files changed, 51 insertions(+)
 create mode 100644 target/arm/cpu-idregs.c

diff --git a/target/arm/cpu-idregs.c b/target/arm/cpu-idregs.c
new file mode 100644
index 0000000000..f79b22680c
--- /dev/null
+++ b/target/arm/cpu-idregs.c
@@ -0,0 +1,50 @@
+/*
+ *   ARM ID register field table.
+ *
+ *   Builds the per-id-register field descriptor arrays and the global
+ *   arm_idregs[] table.
+ *
+ *  SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "cpu-idregs.h"
+
+#define IDREG_START(reg) \
+    static ARM64SysRegField reg##_fields[] = {
+
+#define IDREG_END(reg) \
+    };
+
+#define IDREG_FIELD(reg, field, _shift, _length) \
+    { \
+        .name = #field, \
+        .index = reg##_IDX, \
+        .shift = (_shift), \
+        .length = (_length), \
+    },
+#include "cpu-idregs.h.inc"
+#undef IDREG_START
+#undef IDREG_END
+#undef IDREG_FIELD
+
+/* generate an array of top level ID registers */
+#define IDREG_END(reg)
+#define IDREG_FIELD(reg, field, shift, length)
+
+#define IDREG_START(reg) \
+    [reg##_IDX] = { \
+        .name = #reg, \
+        .index = reg##_IDX, \
+        .fields = reg##_fields, \
+        .fields_count = ARRAY_SIZE(reg##_fields), \
+    },
+
+ARM64SysReg arm64_id_regs[NUM_ID_IDX] = {
+#include "cpu-idregs.h.inc"
+};
+#undef IDREG_START
+#undef IDREG_END
+#undef IDREG_FIELD
diff --git a/target/arm/meson.build b/target/arm/meson.build
index 4723f9f170..64d1ec63ab 100644
--- a/target/arm/meson.build
+++ b/target/arm/meson.build
@@ -19,6 +19,7 @@ arm_common_ss.add(files(
 
 arm_common_system_ss.add(files(
   'arm-qmp-cmds.c',
+  'cpu-idregs.c',
 ))
 arm_system_ss.add(when: 'CONFIG_KVM', if_true: files('hyp_gdbstub.c', 'kvm.c'))
 arm_system_ss.add(when: 'CONFIG_HVF', if_true: files('hyp_gdbstub.c'))
-- 
2.53.0


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

* [PATCH v5 09/18] target/arm/kvm: Introduce kvm_get_writable_id_regs
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (7 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 08/18] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-21 13:43   ` Sebastian Ott
  2026-06-01 15:26   ` Shameer Kolothum Thodi
  2026-05-19 13:27 ` [PATCH v5 10/18] target/arm/cpu64: Retrieve writable ID reg map in aarch64_host_initfn() Eric Auger
                   ` (9 subsequent siblings)
  18 siblings, 2 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, 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.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>

---

v4 -> v5:
- get rid of IdRegMap datatype
- do not store the status of the query in cpu anymore, just
  return the error in case the retrieval failed
- add implementation in kvm-stub.c
---
 target/arm/kvm-stub.c |  5 +++++
 target/arm/kvm.c      | 21 +++++++++++++++++++++
 target/arm/kvm_arm.h  |  2 ++
 3 files changed, 28 insertions(+)

diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c
index 88cbe8d85c..cd88eb741a 100644
--- a/target/arm/kvm-stub.c
+++ b/target/arm/kvm-stub.c
@@ -119,3 +119,8 @@ char *kvm_print_register_name(uint64_t regidx)
 {
     g_assert_not_reached();
 }
+
+int kvm_arm_get_writable_id_regs(uint64_t *idregmap)
+{
+    g_assert_not_reached();
+}
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 7d194ea112..4adfd20050 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -505,6 +505,27 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
     env->features = arm_host_cpu_features.features;
 }
 
+int kvm_arm_get_writable_id_regs(uint64_t *idregmap)
+{
+    int cap_writable_id_regs;
+    struct reg_mask_range range = {
+        .range = 0, /* up to now only a single range is supported */
+        .addr = (uint64_t)idregmap,
+    };
+    int ret;
+
+    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))) {
+        return -ENOSYS;
+    }
+
+    ret = kvm_vm_ioctl(kvm_state, KVM_ARM_GET_REG_WRITABLE_MASKS, &range);
+    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..c1c2e7ec37 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -240,4 +240,6 @@ void arm_gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3);
  */
 char *kvm_print_register_name(uint64_t regidx);
 
+int kvm_arm_get_writable_id_regs(uint64_t *idregmap);
+
 #endif
-- 
2.53.0


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

* [PATCH v5 10/18] target/arm/cpu64: Retrieve writable ID reg map in aarch64_host_initfn()
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (8 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 09/18] target/arm/kvm: Introduce kvm_get_writable_id_regs Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-21 13:47   ` Sebastian Ott
  2026-05-27 14:54   ` Khushit Shah
  2026-05-19 13:27 ` [PATCH v5 11/18] arm/kvm: Initialize all writable ID registers from host Eric Auger
                   ` (8 subsequent siblings)
  18 siblings, 2 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, sebott, skolothumtho, philmd
  Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar

Store the writable_map array in the CPU state and populate it
in aarch64_host_initfn(). In case the retrieval fails we simply
free and null the pointer: this will indicate that the writable_map
is not usable in subsequent patches.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 target/arm/cpu.h   | 3 +++
 target/arm/cpu64.c | 9 +++++++++
 2 files changed, 12 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index a0a1d7fbe3..3558460333 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1073,6 +1073,9 @@ struct ArchCPU {
     /* KVM steal time */
     OnOffAuto kvm_steal_time;
 
+    /* ID reg writable bitmask */
+    uint64_t *writable_map;
+
     /* Uniprocessor system with MP extensions */
     bool mp_is_up;
 
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index a93ad2da5a..f2edbfc437 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -851,6 +851,7 @@ static void kvm_arm_set_cpreg_mig_tolerances(ARMCPU *cpu)
 static void aarch64_host_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+    int ret;
 
 #if defined(CONFIG_NITRO)
     if (nitro_enabled()) {
@@ -861,6 +862,14 @@ static void aarch64_host_initfn(Object *obj)
 
 #if defined(CONFIG_KVM)
     kvm_arm_set_cpreg_mig_tolerances(cpu);
+
+    cpu->writable_map = g_new(uint64_t, KVM_ARM_FEATURE_ID_RANGE_SIZE);
+
+    ret = kvm_arm_get_writable_id_regs(cpu->writable_map);
+    if (ret) {
+        g_free(cpu->writable_map);
+        cpu->writable_map = NULL;
+    }
     kvm_arm_set_cpu_features_from_host(cpu);
     aarch64_add_sve_properties(obj);
 #elif defined(CONFIG_HVF)
-- 
2.53.0


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

* [PATCH v5 11/18] arm/kvm: Initialize all writable ID registers from host
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (9 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 10/18] target/arm/cpu64: Retrieve writable ID reg map in aarch64_host_initfn() Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-21 14:22   ` Sebastian Ott
  2026-05-27 15:02   ` Khushit Shah
  2026-05-19 13:27 ` [PATCH v5 12/18] arm/kvm: write back modified ID regs to KVM Eric Auger
                   ` (7 subsequent siblings)
  18 siblings, 2 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, sebott, skolothumtho, philmd
  Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar

We want to allow overwriting writable fields of some ID registers.
However currently some of them are never touched, neither read nor
w. Examples are CLIDR_EL1, CTR_EL0, REVIDR_EL1, MIDR_EL1.

We want to initialize them from the host value, allow overwrite
and write back for kvm afterwards. This patch implements the
initialization.

Introduce a new get_host_cpu_idregs() helper that gets the host
values for all writable ID regs and store them in isar.idregs[].

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>

---
---
 target/arm/kvm.c        | 72 +++++++++++++++++++++++++++++++++++++++--
 target/arm/trace-events |  1 +
 2 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 4adfd20050..92219ee62e 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),
@@ -273,7 +274,62 @@ static uint32_t kvm_arm_sve_get_vls(int fd)
     return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ);
 }
 
-static void 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 = id_register_sysreg[i];
+        uint64_t writable_mask =
+             cpu->writable_map[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 void
+kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf)
 {
     /* Identify the feature bits corresponding to the host CPU, and
      * fill out the ARMHostCPUClass fields accordingly. To do this
@@ -359,6 +415,18 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
         SET_IDREG(&ahcf->isar, ID_AA64PFR0, 0x00000011); /* EL1&0, AArch64 only */
         err = 0;
     } else {
+        /* Make sure all writable ID reg values are initialized */
+        if (cpu->writable_map) {
+            err |= get_host_cpu_idregs(cpu, fd, ahcf);
+        }
+
+        /*
+         * temporarily override the CLIDR_EL1 value since some host values
+         * trigger "Unified type is not implemented at level n" error in
+         * fdt_add_cpu_nodes()
+         */
+        SET_IDREG(&ahcf->isar, CLIDR, 0x0);
+
         err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR1_EL1_IDX);
         err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR2_EL1_IDX);
         err |= get_host_cpu_reg(fd, ahcf, ID_AA64SMFR0_EL1_IDX);
@@ -485,7 +553,7 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
     CPUARMState *env = &cpu->env;
 
     if (!arm_host_cpu_features.dtb_compatible) {
-        kvm_arm_get_host_cpu_features(&arm_host_cpu_features);
+        kvm_arm_get_host_cpu_features(cpu, &arm_host_cpu_features);
     }
 
     cpu->kvm_target = arm_host_cpu_features.target;
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] 74+ messages in thread

* [PATCH v5 12/18] arm/kvm: write back modified ID regs to KVM
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (10 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 11/18] arm/kvm: Initialize all writable ID registers from host Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-27 14:42   ` Khushit Shah
  2026-05-19 13:27 ` [PATCH v5 13/18] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties Eric Auger
                   ` (6 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, sebott, skolothumtho, philmd
  Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar

In case some ID reg values were overriden after their
initialization in kvm_arm_get_host_cpu_features() we need to
copy the new value stored in isar.idregs array back to the
cpreg_list and then sync the cpreg_list to KVM.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>

---

v4 -> v5:
- only call kvm_arm_writable_idregs_to_cpreg_list and
  write_list_to_kvmstate if writable_map is allocated
- reinitialize the cpreg list after sync (Jinqian)
---
 target/arm/kvm.c        | 69 ++++++++++++++++++++++++++++++++++++++++-
 target/arm/trace-events |  1 +
 2 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 92219ee62e..30c5175c68 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -274,6 +274,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];
@@ -1189,6 +1204,40 @@ bool kvm_arm_cpu_post_load(ARMCPU *cpu)
     return true;
 }
 
+/*
+ * Copy writable ID regs from isar.idregs[] to cpreg_list
+ * in case their value differs from the original init cpreg value
+ */
+static void kvm_arm_writable_idregs_to_cpreg_list(ARMCPU *cpu)
+{
+    for (int i = 0; i < KVM_ARM_FEATURE_ID_RANGE_SIZE; i++) {
+        uint64_t writable_mask = cpu->writable_map[i];
+
+        if (writable_mask) {
+            int idx = kvm_feature_idx_to_idregs_idx(i);
+            ARM64SysReg *sysregdesc;
+            uint64_t previous, new;
+            uint64_t *cpreg;
+            uint32_t sysreg;
+
+            if (idx == -1) {
+                /* sysreg writable, but we don't know it */
+                continue;
+            }
+            sysregdesc = &arm64_id_regs[idx];
+            sysreg = id_register_sysreg[idx];
+            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;
@@ -2140,7 +2189,25 @@ 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 */
+    if (cpu->writable_map) {
+        kvm_arm_writable_idregs_to_cpreg_list(cpu);
+        ret = write_list_to_kvmstate(cpu, KVM_PUT_FULL_STATE);
+        if (!ret) {
+            return -1;
+        }
+        /*
+         * modified values may have changed the visibility of some regs,
+         * reinitialize the cpreg_list accordingly
+         */
+         ret = kvm_arm_init_cpreg_list(cpu);
+    }
+
+    return ret;
 }
 
 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] 74+ messages in thread

* [PATCH v5 13/18] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (11 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 12/18] arm/kvm: write back modified ID regs to KVM Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-26 14:42   ` Sebastian Ott
  2026-05-27 15:08   ` Khushit Shah
  2026-05-19 13:27 ` [PATCH v5 14/18] target/arm/kvm: Special case REVIDR_EL1 and AIDR_EL1 Eric Auger
                   ` (5 subsequent siblings)
  18 siblings, 2 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, 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-idregs.h.inc and
for each writable named field, generates a uint64 property.

Signed-off-by: Eric Auger <eric.auger@redhat.com>

---

v4 -> v5:
- free prop_name
- check cpu->writable_map as a preamble in kvm_arm_expose_idreg_properties
---
 target/arm/kvm.c        | 135 ++++++++++++++++++++++++++++++++++++++++
 target/arm/kvm_arm.h    |  10 +++
 target/arm/trace-events |   4 ++
 3 files changed, 149 insertions(+)

diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 30c5175c68..960052e67e 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -343,6 +343,141 @@ static int get_host_cpu_idregs(ARMCPU *cpu, int fd, ARMHostCPUFeatures *ahcf)
     return err;
 }
 
+static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
+{
+    for (int f = 0; f < reg->fields_count; f++) {
+        struct ARM64SysRegField *field = &reg->fields[f];
+        int upper = field->shift + field->length - 1;
+
+        if (i >= field->shift && i <= 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->shift;
+    int length = field->length;
+    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->shift;
+    int length = field->length;
+    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;
+        char *prop_name;
+        uint64_t mask;
+
+        if (!field) {
+            warn_report("%s bit %d of %s is writable but no named field "
+                        "in target/arm/cpu-idregs.h.inc",
+                        __func__, i, reg->name);
+            warn_report("%s is target/arm/cpu-idregs.h.inc?", __func__);
+            map =  map & ~BIT_ULL(i);
+            i = ctz64(map);
+            continue;
+        }
+        lower = field->shift;
+        upper = field->shift + field->length - 1;
+        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);
+        g_free(prop_name);
+        nb_sysreg_props++;
+
+        mask = MAKE_64BIT_MASK(lower, field->length);
+        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;
+    Object *obj = OBJECT(cpu);
+
+    if (!cpu->writable_map) {
+        return;
+    }
+
+    for (i = 0; i < KVM_ARM_FEATURE_ID_RANGE_SIZE; i++) {
+        uint64_t mask = cpu->writable_map[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, &regs[idx]);
+            }
+        }
+    }
+}
+
 static void
 kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf)
 {
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index c1c2e7ec37..8446a9cbf0 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -142,6 +142,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] 74+ messages in thread

* [PATCH v5 14/18] target/arm/kvm: Special case REVIDR_EL1 and AIDR_EL1
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (12 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 13/18] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-26 15:08   ` Sebastian Ott
  2026-05-19 13:27 ` [PATCH v5 15/18] target/arm/kvm: Ignore some writable bits that shouldn't be Eric Auger
                   ` (4 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, 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 960052e67e..6373a66bbd 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, &regs[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, &regs[idx]);
+                }
             }
         }
     }
-- 
2.53.0


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

* [PATCH v5 15/18] target/arm/kvm: Ignore some writable bits that shouldn't be
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (13 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 14/18] target/arm/kvm: Special case REVIDR_EL1 and AIDR_EL1 Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-27 14:46   ` Khushit Shah
  2026-05-19 13:27 ` [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model Eric Auger
                   ` (3 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, sebott, skolothumtho, philmd
  Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar

KVM currently reports some bits as writable whereas they are
RES0 or RAZ. This is detected because the code attempts to
match those bits against a named field and this later does not
exist in target/arm/cpu-idregs.h.inc.

Let's silence warnings until those bits get fixed in the kernel.

This was observed with v7.1-rc4 kernel.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 target/arm/kvm.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 6373a66bbd..1688cc2106 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -405,6 +405,19 @@ static void get_sysreg_prop(Object *obj, Visitor *v,
     trace_get_sysreg_prop(name, value);
 }
 
+static bool ignore_unnamed_writable_field(ARM64SysReg *reg, int i)
+{
+    if ((!strcmp(reg->name, "ID_ISAR0_EL1") && i >= 28 && i <= 31) || /* RES0 */
+        (!strcmp(reg->name, "ID_ISAR5_EL1") && i >= 20 && i <= 23) || /* RES0 */
+        (!strcmp(reg->name, "MVFR2_EL1") && i >= 8 && i <= 31) || /* RES0 */
+        (!strcmp(reg->name, "ID_PFR2_EL1") && i >= 12 && i <= 31) || /* RES0 */
+        (!strcmp(reg->name, "ID_MMFR5_EL1") && i >= 8 && i <= 31) || /* RES0 */
+        (!strcmp(reg->name, "ID_AA64FPFR0_EL1") && i >= 2 && i <= 7)) { /* RAZ */
+        return true;
+    }
+    return false;
+}
+
 /*
  * decode_idreg_writemap: Generate props for writable fields
  *
@@ -426,10 +439,12 @@ decode_idreg_writemap(Object *obj, int index, uint64_t map, ARM64SysReg *reg)
         uint64_t mask;
 
         if (!field) {
-            warn_report("%s bit %d of %s is writable but no named field "
-                        "in target/arm/cpu-idregs.h.inc",
-                        __func__, i, reg->name);
-            warn_report("%s is target/arm/cpu-idregs.h.inc?", __func__);
+            if (!ignore_unnamed_writable_field(reg, i)) {
+                warn_report("%s bit %d of %s is writable but no named field "
+                            "in target/arm/cpu-idregs.h.inc",
+                            __func__, i, reg->name);
+                warn_report("%s is target/arm/cpu-idregs.h.inc?", __func__);
+            }
             map =  map & ~BIT_ULL(i);
             i = ctz64(map);
             continue;
-- 
2.53.0


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

* [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (14 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 15/18] target/arm/kvm: Ignore some writable bits that shouldn't be Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-26 14:51   ` Sebastian Ott
  2026-05-27 15:16   ` Khushit Shah
  2026-05-19 13:27 ` [PATCH v5 17/18] arm-qmp-cmds: introspection for ID register props Eric Auger
                   ` (2 subsequent siblings)
  18 siblings, 2 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, 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-idregs.h.inc.

Properties are named  SYSREG_<REG>_<FIELD> with REG and FIELD
being those used ARCHMRS Registers.json.

When such properties are set, they override the default field value
retrieved from the host and reinjected into KVM. Then the actual value
being applied at KVM depends on the register, ie. it can be sanitized.
In case the field value is rejected by KVM, the vpcu init fails.

Anyway there is a first attempt to write back this value into KVM.

Then legacy CPU options (virtualization, secure, ...) can still
override the previous value. So low level IDREG field properties
apply before the legacy ones.

An example of invocation is:
-cpu host,SYSREG_ID_AA64MMFR0_EL1_ECV=0x0
which sets ECV field of ID_AA64MMFR0_EL1 to 0 (enhanced counter
virtualization).

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>

---
v4 -> v5:
- get rid of ret local variable, dynamically allocate and free writable_map
  here
---
 target/arm/cpu64.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index f2edbfc437..e0e1ff6cfb 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)      \
@@ -851,7 +852,6 @@ static void kvm_arm_set_cpreg_mig_tolerances(ARMCPU *cpu)
 static void aarch64_host_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
-    int ret;
 
 #if defined(CONFIG_NITRO)
     if (nitro_enabled()) {
@@ -865,13 +865,18 @@ static void aarch64_host_initfn(Object *obj)
 
     cpu->writable_map = g_new(uint64_t, KVM_ARM_FEATURE_ID_RANGE_SIZE);
 
-    ret = kvm_arm_get_writable_id_regs(cpu->writable_map);
-    if (ret) {
+    if (kvm_arm_get_writable_id_regs(cpu->writable_map)) {
         g_free(cpu->writable_map);
         cpu->writable_map = NULL;
     }
     kvm_arm_set_cpu_features_from_host(cpu);
     aarch64_add_sve_properties(obj);
+
+    if (cpu->writable_map) {
+        /* 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] 74+ messages in thread

* [PATCH v5 17/18] arm-qmp-cmds: introspection for ID register props
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (15 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-27  6:29   ` Sebastian Ott
  2026-05-27 15:17   ` Khushit Shah
  2026-05-19 13:27 ` [PATCH v5 18/18] arm/cpu-features: document ID reg properties Eric Auger
  2026-06-04  6:08 ` [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Jinqian Yang
  18 siblings, 2 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, 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..e6c717a872 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_map) {
+        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] 74+ messages in thread

* [PATCH v5 18/18] arm/cpu-features: document ID reg properties
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (16 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 17/18] arm-qmp-cmds: introspection for ID register props Eric Auger
@ 2026-05-19 13:27 ` Eric Auger
  2026-05-27  6:37   ` Sebastian Ott
  2026-06-04  6:08 ` [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Jinqian Yang
  18 siblings, 1 reply; 74+ messages in thread
From: Eric Auger @ 2026-05-19 13:27 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, 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.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
 docs/system/arm/cpu-features.rst | 106 ++++++++++++++++++++++++++++---
 1 file changed, 98 insertions(+), 8 deletions(-)

diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
index 10b0eff27e..6203757781 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,18 @@ 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. Their availability depend on the host capability
+to let the userspace write those fields. Values set with those properties
+override the initial values retrieved from the host. They are written back
+to KVM and the eventual value applied by KVM depends on whether the value
+is sanitized or not by the host kernel. Then those field values are likely
+to be overriden again by legacy CPU options which apply at the end.
+
 CPU Feature Probing
 ===================
 
@@ -126,13 +141,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 from 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 +191,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 +524,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 incompatibilities 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] 74+ messages in thread

* Re: [PATCH v5 04/18] arm/cpu: Add infra to handle generated ID register definitions
  2026-05-19 13:27 ` [PATCH v5 04/18] arm/cpu: Add infra to handle generated ID register definitions Eric Auger
@ 2026-05-21 13:23   ` Sebastian Ott
  2026-06-01 14:28   ` Shameer Kolothum Thodi
  1 sibling, 0 replies; 74+ messages in thread
From: Sebastian Ott @ 2026-05-21 13:23 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
	shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, skolothumtho, philmd, maz, oliver.upton,
	pbonzini, armbru, berrange, abologna, jdenemar

On Tue, 19 May 2026, Eric Auger wrote:
> 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.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>

Reviewed-by: Sebastian Ott <sebott@redhat.com>


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

* Re: [PATCH v5 08/18] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields
  2026-05-19 13:27 ` [PATCH v5 08/18] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields Eric Auger
@ 2026-05-21 13:27   ` Sebastian Ott
  2026-05-27 14:52   ` Khushit Shah
  1 sibling, 0 replies; 74+ messages in thread
From: Sebastian Ott @ 2026-05-21 13:27 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
	shaju.abraham, khushit.shah, yangjinqian1, Cornelia Huck,
	richard.henderson, skolothumtho, philmd, maz, oliver.upton,
	pbonzini, armbru, berrange, abologna, jdenemar

On Tue, 19 May 2026, Eric Auger wrote:
> From: Shaju Abraham <shaju.abraham@nutanix.com>
>
> Include cpu-idregs.h.inc multiple times with different definitions for the
> X-macros. This will generate tables for all Arm64 ID registers and their
> fields. Additionally, initialize the tables with all architecturally defined
> values. These tables will be consumed by the property layer in future
> patches.
>
> Co-authored-by: Khushit Shah <khushit.shah@nutanix.com>
> Signed-off-by: Shaju Abraham <shaju.abraham@nutanix.com>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
> target/arm/cpu-idregs.c | 50 +++++++++++++++++++++++++++++++++++++++++
> target/arm/meson.build  |  1 +
> 2 files changed, 51 insertions(+)
> create mode 100644 target/arm/cpu-idregs.c
>
> diff --git a/target/arm/cpu-idregs.c b/target/arm/cpu-idregs.c
> new file mode 100644
> index 0000000000..f79b22680c
> --- /dev/null
> +++ b/target/arm/cpu-idregs.c
> @@ -0,0 +1,50 @@
> +/*
> + *   ARM ID register field table.
> + *
> + *   Builds the per-id-register field descriptor arrays and the global
> + *   arm_idregs[] table.

arm64_id_regs[]

Reviewed-by: Sebastian Ott <sebott@redhat.com>



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

* Re: [PATCH v5 09/18] target/arm/kvm: Introduce kvm_get_writable_id_regs
  2026-05-19 13:27 ` [PATCH v5 09/18] target/arm/kvm: Introduce kvm_get_writable_id_regs Eric Auger
@ 2026-05-21 13:43   ` Sebastian Ott
  2026-06-01 15:26   ` Shameer Kolothum Thodi
  1 sibling, 0 replies; 74+ messages in thread
From: Sebastian Ott @ 2026-05-21 13:43 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
	shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, skolothumtho, philmd, maz, oliver.upton,
	pbonzini, armbru, berrange, abologna, jdenemar

On Tue, 19 May 2026, Eric Auger wrote:
> From: Cornelia Huck <cohuck@redhat.com>
>
> Add an helper to retrieve the writable id reg bitmask.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>
[...]
> +int kvm_arm_get_writable_id_regs(uint64_t *idregmap)
> +{
> +    int cap_writable_id_regs;
> +    struct reg_mask_range range = {
> +        .range = 0, /* up to now only a single range is supported */

.range = KVM_ARM_FEATURE_ID_RANGE,
.reserved = {0},

Reviewed-by: Sebastian Ott <sebott@redhat.com>


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

* Re: [PATCH v5 10/18] target/arm/cpu64: Retrieve writable ID reg map in aarch64_host_initfn()
  2026-05-19 13:27 ` [PATCH v5 10/18] target/arm/cpu64: Retrieve writable ID reg map in aarch64_host_initfn() Eric Auger
@ 2026-05-21 13:47   ` Sebastian Ott
  2026-05-27 14:54   ` Khushit Shah
  1 sibling, 0 replies; 74+ messages in thread
From: Sebastian Ott @ 2026-05-21 13:47 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
	shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, skolothumtho, philmd, maz, oliver.upton,
	pbonzini, armbru, berrange, abologna, jdenemar

On Tue, 19 May 2026, Eric Auger wrote:

> Store the writable_map array in the CPU state and populate it
> in aarch64_host_initfn(). In case the retrieval fails we simply
> free and null the pointer: this will indicate that the writable_map
> is not usable in subsequent patches.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>

Reviewed-by: Sebastian Ott <sebott@redhat.com>


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

* Re: [PATCH v5 11/18] arm/kvm: Initialize all writable ID registers from host
  2026-05-19 13:27 ` [PATCH v5 11/18] arm/kvm: Initialize all writable ID registers from host Eric Auger
@ 2026-05-21 14:22   ` Sebastian Ott
  2026-05-27 15:02   ` Khushit Shah
  1 sibling, 0 replies; 74+ messages in thread
From: Sebastian Ott @ 2026-05-21 14:22 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
	shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, skolothumtho, philmd, maz, oliver.upton,
	pbonzini, armbru, berrange, abologna, jdenemar

On Tue, 19 May 2026, Eric Auger wrote:
> We want to allow overwriting writable fields of some ID registers.
> However currently some of them are never touched, neither read nor
> w. Examples are CLIDR_EL1, CTR_EL0, REVIDR_EL1, MIDR_EL1.
>
> We want to initialize them from the host value, allow overwrite
> and write back for kvm afterwards. This patch implements the
> initialization.
>
> Introduce a new get_host_cpu_idregs() helper that gets the host
> values for all writable ID regs and store them in isar.idregs[].
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>

Reviewed-by: Sebastian Ott <sebott@redhat.com>


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

* Re: [PATCH v5 13/18] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties
  2026-05-19 13:27 ` [PATCH v5 13/18] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties Eric Auger
@ 2026-05-26 14:42   ` Sebastian Ott
  2026-05-27 15:08   ` Khushit Shah
  1 sibling, 0 replies; 74+ messages in thread
From: Sebastian Ott @ 2026-05-26 14:42 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
	shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, skolothumtho, philmd, maz, oliver.upton,
	pbonzini, armbru, berrange, abologna, jdenemar

On Tue, 19 May 2026, Eric Auger wrote:
> This helper decode the ID reg writable mask, matches it against
> ID reg fields defined in target/arm/cpu-idregs.h.inc and
> for each writable named field, generates a uint64 property.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
[...]
> +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;
> +        char *prop_name;
> +        uint64_t mask;
> +
> +        if (!field) {
> +            warn_report("%s bit %d of %s is writable but no named field "
> +                        "in target/arm/cpu-idregs.h.inc",
> +                        __func__, i, reg->name);
> +            warn_report("%s is target/arm/cpu-idregs.h.inc?", __func__);
 							^
 							up-to-date?

Reviewed-by: Sebastian Ott <sebott@redhat.com>



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

* Re: [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model
  2026-05-19 13:27 ` [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model Eric Auger
@ 2026-05-26 14:51   ` Sebastian Ott
  2026-05-27 15:16   ` Khushit Shah
  1 sibling, 0 replies; 74+ messages in thread
From: Sebastian Ott @ 2026-05-26 14:51 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
	shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, skolothumtho, philmd, maz, oliver.upton,
	pbonzini, armbru, berrange, abologna, jdenemar

On Tue, 19 May 2026, Eric Auger wrote:
> 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-idregs.h.inc.
>
> Properties are named  SYSREG_<REG>_<FIELD> with REG and FIELD
> being those used ARCHMRS Registers.json.
>
> When such properties are set, they override the default field value
> retrieved from the host and reinjected into KVM. Then the actual value
> being applied at KVM depends on the register, ie. it can be sanitized.
> In case the field value is rejected by KVM, the vpcu init fails.
>
> Anyway there is a first attempt to write back this value into KVM.
>
> Then legacy CPU options (virtualization, secure, ...) can still
> override the previous value. So low level IDREG field properties
> apply before the legacy ones.
>
> An example of invocation is:
> -cpu host,SYSREG_ID_AA64MMFR0_EL1_ECV=0x0
> which sets ECV field of ID_AA64MMFR0_EL1 to 0 (enhanced counter
> virtualization).
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>

Reviewed-by: Sebastian Ott <sebott@redhat.com>


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

* Re: [PATCH v5 14/18] target/arm/kvm: Special case REVIDR_EL1 and AIDR_EL1
  2026-05-19 13:27 ` [PATCH v5 14/18] target/arm/kvm: Special case REVIDR_EL1 and AIDR_EL1 Eric Auger
@ 2026-05-26 15:08   ` Sebastian Ott
  0 siblings, 0 replies; 74+ messages in thread
From: Sebastian Ott @ 2026-05-26 15:08 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
	shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, skolothumtho, philmd, maz, oliver.upton,
	pbonzini, armbru, berrange, abologna, jdenemar

On Tue, 19 May 2026, Eric Auger wrote:
> 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 960052e67e..6373a66bbd 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, &regs[idx]);
> +                /*
> +                 * special case REVIDR_EL1 and AIDR_EL1 which are writable but
> +                 * does not expose named fields. They will need to be handled
> +                 * separately
> +                 */

"Special case REVIDR_EL1 and AIDR_EL1 which are writable but
do not expose named fields. They will need to be handled
separately."

Reviewed-by: Sebastian Ott <sebott@redhat.com>


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

* Re: [PATCH v5 17/18] arm-qmp-cmds: introspection for ID register props
  2026-05-19 13:27 ` [PATCH v5 17/18] arm-qmp-cmds: introspection for ID register props Eric Auger
@ 2026-05-27  6:29   ` Sebastian Ott
  2026-05-27 15:17   ` Khushit Shah
  1 sibling, 0 replies; 74+ messages in thread
From: Sebastian Ott @ 2026-05-27  6:29 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
	shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, skolothumtho, philmd, maz, oliver.upton,
	pbonzini, armbru, berrange, abologna, jdenemar

On Tue, 19 May 2026, Eric Auger wrote:
> 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,
 				 ^
This looks wrong - more like the full reg value and not just EL3..

> "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>
>

Reviewed-by: Sebastian Ott <sebott@redhat.com>


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

* Re: [PATCH v5 18/18] arm/cpu-features: document ID reg properties
  2026-05-19 13:27 ` [PATCH v5 18/18] arm/cpu-features: document ID reg properties Eric Auger
@ 2026-05-27  6:37   ` Sebastian Ott
  0 siblings, 0 replies; 74+ messages in thread
From: Sebastian Ott @ 2026-05-27  6:37 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
	shaju.abraham, khushit.shah, yangjinqian1, cohuck,
	richard.henderson, skolothumtho, philmd, maz, oliver.upton,
	pbonzini, armbru, berrange, abologna, jdenemar

On Tue, 19 May 2026, Eric Auger wrote:
> From: Cornelia Huck <cohuck@redhat.com>
>
> Add some documentation for how individual ID registers can be
> configured with the host cpu model.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
> docs/system/arm/cpu-features.rst | 106 ++++++++++++++++++++++++++++---
> 1 file changed, 98 insertions(+), 8 deletions(-)
>
> diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
> index 10b0eff27e..6203757781 100644
> --- a/docs/system/arm/cpu-features.rst
[...]
> +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. Their availability depend on the host capability

^
ARM ARM

Reviewed-by: Sebastian Ott <sebott@redhat.com>



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

* Re: [PATCH v5 06/18] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py
  2026-05-19 13:27 ` [PATCH v5 06/18] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py Eric Auger
@ 2026-05-27 14:35   ` Khushit Shah
  2026-05-27 15:11     ` Eric Auger
  0 siblings, 1 reply; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 14:35 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> !-------------------------------------------------------------------|
>  CAUTION: External Email
> 
> |-------------------------------------------------------------------!
> 
> 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://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=lifWLuAPiWiPtZHA1AnNwE36XKErpJppnuqSRce8eEXbd2seIXgOyghkIcv1h_tk&s=HRujmTCQGTPR11d90Orv_1iwKOLX_k3RFbkK_mx7A1s&e= 
> and automates the generation of system register properties definitions.
> 
> generates target/arm/cpu-idregs.h.inc 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   | 168 ++++++++++++++++++
> 1 file changed, 168 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..3571e228ee
> --- /dev/null
> +++ b/scripts/update-aarch64-cpu-sysreg-properties.py
> @@ -0,0 +1,168 @@
> +#!/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://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=lifWLuAPiWiPtZHA1AnNwE36XKErpJppnuqSRce8eEXbd2seIXgOyghkIcv1h_tk&s=HRujmTCQGTPR11d90Orv_1iwKOLX_k3RFbkK_mx7A1s&e= 
> +# 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
> +
> +    # 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))
> +
> +    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"    IDREG_START({reg_name})\n"
> +
> +        unique_fields = {}
> +        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'))
> +                    width = r.get('width')
> +                    msb = lsb + int(width) - 1
> +
> +                    # 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, 'width': width}
> +
> +        # 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"    IDREG_FIELD({reg_name}, "
> +                    f"{name}, {bits['lsb']}, {bits['width']})\n")
> +            final_output += line
> +        final_output += f"    IDREG_END({reg_name})\n"
> +        final_output += "\n"
> +
> +    os.makedirs("target/arm", exist_ok=True)
> +    with open("target/arm/cpu-idregs.h.inc", 'w') as f:
> +        f.write("/* AUTOMATICALLY GENERATED, DO NOT MODIFY */\n\n")
> +        f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
> +        f.write("/* IDREG_START(REG) */\n")
> +        f.write("/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */\n")
> +        f.write("/* ... */\n")
> +        f.write("/* IDREG_END(REG) */\n\n")
> +        f.write(final_output)
> +
> +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-idregs.h.inc")
> -- 
> 2.53.0
> 

Hi Eric,

Can we also have the arch-defined values in here? It is already available in Registers.json easily, would be great if we can validate at-least the user
set values are architecturally valid.

Warm Regards,
Khushit


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

* Re: [PATCH v5 12/18] arm/kvm: write back modified ID regs to KVM
  2026-05-19 13:27 ` [PATCH v5 12/18] arm/kvm: write back modified ID regs to KVM Eric Auger
@ 2026-05-27 14:42   ` Khushit Shah
  2026-05-27 15:28     ` Khushit Shah
  2026-05-28 17:35     ` Eric Auger
  0 siblings, 2 replies; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 14:42 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> !-------------------------------------------------------------------|
>  CAUTION: External Email
> 
> |-------------------------------------------------------------------!
> 
> In case some ID reg values were overriden after their
> initialization in kvm_arm_get_host_cpu_features() we need to
> copy the new value stored in isar.idregs array back to the
> cpreg_list and then sync the cpreg_list to KVM.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> 
> ---
> 
> v4 -> v5:
> - only call kvm_arm_writable_idregs_to_cpreg_list and
>  write_list_to_kvmstate if writable_map is allocated
> - reinitialize the cpreg list after sync (Jinqian)
> ---
> target/arm/kvm.c        | 69 ++++++++++++++++++++++++++++++++++++++++-
> target/arm/trace-events |  1 +
> 2 files changed, 69 insertions(+), 1 deletion(-)
> 
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index 92219ee62e..30c5175c68 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -274,6 +274,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];
> @@ -1189,6 +1204,40 @@ bool kvm_arm_cpu_post_load(ARMCPU *cpu)
>     return true;
> }
> 
> +/*
> + * Copy writable ID regs from isar.idregs[] to cpreg_list
> + * in case their value differs from the original init cpreg value
> + */
> +static void kvm_arm_writable_idregs_to_cpreg_list(ARMCPU *cpu)
> +{
> +    for (int i = 0; i < KVM_ARM_FEATURE_ID_RANGE_SIZE; i++) {
> +        uint64_t writable_mask = cpu->writable_map[i];
> +
> +        if (writable_mask) {
> +            int idx = kvm_feature_idx_to_idregs_idx(i);
> +            ARM64SysReg *sysregdesc;
> +            uint64_t previous, new;
> +            uint64_t *cpreg;
> +            uint32_t sysreg;
> +
> +            if (idx == -1) {
> +                /* sysreg writable, but we don't know it */
> +                continue;
> +            }
> +            sysregdesc = &arm64_id_regs[idx];
> +            sysreg = id_register_sysreg[idx];
> +            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;
> @@ -2140,7 +2189,25 @@ 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 */
> +    if (cpu->writable_map) {
> +        kvm_arm_writable_idregs_to_cpreg_list(cpu);
> +        ret = write_list_to_kvmstate(cpu, KVM_PUT_FULL_STATE);
> +        if (!ret) {
> +            return -1;
> +        }
> +        /*
> +         * modified values may have changed the visibility of some regs,
> +         * reinitialize the cpreg_list accordingly
> +         */
> +         ret = kvm_arm_init_cpreg_list(cpu);
> +    }
> +
> +    return ret;
> }
> 
> 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
> 

Hi Eric, 

We can not safely rely on ahcf on all configurations. This will not work for a host kernel that is booted with nested virtualisation support but qemu started without virtualisation  (i.e. -machine virt (no virtualisation=on)).
 This happens because scratch vCPU always enables EL2 support if supported
by the host kernel. Why limits alot of ID register fields (see limit_nv_id_reg() in
kernel). Then the actual vCPU is initialised with ahcf->isar.idregs[] (with EL2 support). When trying to write back this will result in error.

Will attach how we solved this is separate mail/reply.

Warm Regards,
Khushit. 

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

* Re: [PATCH v5 15/18] target/arm/kvm: Ignore some writable bits that shouldn't be
  2026-05-19 13:27 ` [PATCH v5 15/18] target/arm/kvm: Ignore some writable bits that shouldn't be Eric Auger
@ 2026-05-27 14:46   ` Khushit Shah
  2026-05-27 15:45     ` Eric Auger
  0 siblings, 1 reply; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 14:46 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> 
> KVM currently reports some bits as writable whereas they are
> RES0 or RAZ. This is detected because the code attempts to
> match those bits against a named field and this later does not
> exist in target/arm/cpu-idregs.h.inc.
> 
> Let's silence warnings until those bits get fixed in the kernel.
> 
> This was observed with v7.1-rc4 kernel.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
> target/arm/kvm.c | 23 +++++++++++++++++++----
> 1 file changed, 19 insertions(+), 4 deletions(-)
> 
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index 6373a66bbd..1688cc2106 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -405,6 +405,19 @@ static void get_sysreg_prop(Object *obj, Visitor *v,
>     trace_get_sysreg_prop(name, value);
> }
> 
> +static bool ignore_unnamed_writable_field(ARM64SysReg *reg, int i)
> +{
> +    if ((!strcmp(reg->name, "ID_ISAR0_EL1") && i >= 28 && i <= 31) || /* RES0 */
> +        (!strcmp(reg->name, "ID_ISAR5_EL1") && i >= 20 && i <= 23) || /* RES0 */
> +        (!strcmp(reg->name, "MVFR2_EL1") && i >= 8 && i <= 31) || /* RES0 */
> +        (!strcmp(reg->name, "ID_PFR2_EL1") && i >= 12 && i <= 31) || /* RES0 */
> +        (!strcmp(reg->name, "ID_MMFR5_EL1") && i >= 8 && i <= 31) || /* RES0 */
> +        (!strcmp(reg->name, "ID_AA64FPFR0_EL1") && i >= 2 && i <= 7)) { /* RAZ */
> +        return true;
> +    }
> +    return false;
> +}
> +
> /*
>  * decode_idreg_writemap: Generate props for writable fields
>  *
> @@ -426,10 +439,12 @@ decode_idreg_writemap(Object *obj, int index, uint64_t map, ARM64SysReg *reg)
>         uint64_t mask;
> 
>         if (!field) {
> -            warn_report("%s bit %d of %s is writable but no named field "
> -                        "in target/arm/cpu-idregs.h.inc",
> -                        __func__, i, reg->name);
> -            warn_report("%s is target/arm/cpu-idregs.h.inc?", __func__);
> +            if (!ignore_unnamed_writable_field(reg, i)) {
> +                warn_report("%s bit %d of %s is writable but no named field "
> +                            "in target/arm/cpu-idregs.h.inc",
> +                            __func__, i, reg->name);
> +                warn_report("%s is target/arm/cpu-idregs.h.inc?", __func__);
> +            }
>             map =  map & ~BIT_ULL(i);
>             i = ctz64(map);
>             continue;
> — 

This is why I feel the generated cpu-idregs.h.inc should also have information of
RES0/1 fields as in our RFC. These fields will obviously have only one architecturally
valid value, hence we will never allow user to write something else.

Warm Regards,
Khushit

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

* Re: [PATCH v5 08/18] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields
  2026-05-19 13:27 ` [PATCH v5 08/18] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields Eric Auger
  2026-05-21 13:27   ` Sebastian Ott
@ 2026-05-27 14:52   ` Khushit Shah
  2026-05-27 15:14     ` Eric Auger
  1 sibling, 1 reply; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 14:52 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> !-------------------------------------------------------------------|
>  CAUTION: External Email
> 
> |-------------------------------------------------------------------!
> 
> From: Shaju Abraham <shaju.abraham@nutanix.com>
> 
> Include cpu-idregs.h.inc multiple times with different definitions for the
> X-macros. This will generate tables for all Arm64 ID registers and their
> fields. Additionally, initialize the tables with all architecturally defined
> values. These tables will be consumed by the property layer in future
> patches.
> 
> Co-authored-by: Khushit Shah <khushit.shah@nutanix.com>
> Signed-off-by: Shaju Abraham <shaju.abraham@nutanix.com>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
> target/arm/cpu-idregs.c | 50 +++++++++++++++++++++++++++++++++++++++++
> target/arm/meson.build  |  1 +
> 2 files changed, 51 insertions(+)
> create mode 100644 target/arm/cpu-idregs.c
> 
> diff --git a/target/arm/cpu-idregs.c b/target/arm/cpu-idregs.c
> new file mode 100644
> index 0000000000..f79b22680c
> --- /dev/null
> +++ b/target/arm/cpu-idregs.c
> @@ -0,0 +1,50 @@
> +/*
> + *   ARM ID register field table.
> + *
> + *   Builds the per-id-register field descriptor arrays and the global
> + *   arm_idregs[] table.
> + *
> + *  SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +#include "qemu/osdep.h"
> +#include "qemu/error-report.h"
> +#include "qapi/error.h"
> +#include "cpu.h"
> +#include "cpu-idregs.h"
> +
> +#define IDREG_START(reg) \
> +    static ARM64SysRegField reg##_fields[] = {
> +
> +#define IDREG_END(reg) \
> +    };
> +
> +#define IDREG_FIELD(reg, field, _shift, _length) \
> +    { \
> +        .name = #field, \
> +        .index = reg##_IDX, \
> +        .shift = (_shift), \
> +        .length = (_length), \
> +    },
> +#include "cpu-idregs.h.inc"
> +#undef IDREG_START
> +#undef IDREG_END
> +#undef IDREG_FIELD
> +
> +/* generate an array of top level ID registers */
> +#define IDREG_END(reg)
> +#define IDREG_FIELD(reg, field, shift, length)
> +
> +#define IDREG_START(reg) \
> +    [reg##_IDX] = { \
> +        .name = #reg, \
> +        .index = reg##_IDX, \
> +        .fields = reg##_fields, \
> +        .fields_count = ARRAY_SIZE(reg##_fields), \
> +    },
> +
> +ARM64SysReg arm64_id_regs[NUM_ID_IDX] = {
> +#include "cpu-idregs.h.inc"
> +};
> +#undef IDREG_START
> +#undef IDREG_END
> +#undef IDREG_FIELD
> diff --git a/target/arm/meson.build b/target/arm/meson.build
> index 4723f9f170..64d1ec63ab 100644
> --- a/target/arm/meson.build
> +++ b/target/arm/meson.build
> @@ -19,6 +19,7 @@ arm_common_ss.add(files(
> 
> arm_common_system_ss.add(files(
>   'arm-qmp-cmds.c',
> +  'cpu-idregs.c',
> ))
> arm_system_ss.add(when: 'CONFIG_KVM', if_true: files('hyp_gdbstub.c', 'kvm.c'))
> arm_system_ss.add(when: 'CONFIG_HVF', if_true: files('hyp_gdbstub.c'))
> -- 
> 2.53.0
> 

We can also store writable_masks here. writable_mask exposed by KVM is
static. It does not change in any configuration hence can be fetched once 
during scratch vCPU creation

Warm Regards,
Khushit

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

* Re: [PATCH v5 10/18] target/arm/cpu64: Retrieve writable ID reg map in aarch64_host_initfn()
  2026-05-19 13:27 ` [PATCH v5 10/18] target/arm/cpu64: Retrieve writable ID reg map in aarch64_host_initfn() Eric Auger
  2026-05-21 13:47   ` Sebastian Ott
@ 2026-05-27 14:54   ` Khushit Shah
  2026-05-27 15:17     ` Eric Auger
  1 sibling, 1 reply; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 14:54 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> +
> +    cpu->writable_map = g_new(uint64_t, KVM_ARM_FEATURE_ID_RANGE_SIZE);
> +
> +    ret = kvm_arm_get_writable_id_regs(cpu->writable_map);
> +    if (ret) {
> +        g_free(cpu->writable_map);
> +        cpu->writable_map = NULL;
> +    }

I feel it should not be in ARMCPU state. The is a KVM property, which does not
change for a given kernel version.

Warm Regards,
Khushit

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

* Re: [PATCH v5 11/18] arm/kvm: Initialize all writable ID registers from host
  2026-05-19 13:27 ` [PATCH v5 11/18] arm/kvm: Initialize all writable ID registers from host Eric Auger
  2026-05-21 14:22   ` Sebastian Ott
@ 2026-05-27 15:02   ` Khushit Shah
  2026-05-27 15:25     ` Eric Auger
  2026-05-27 15:30     ` Eric Auger
  1 sibling, 2 replies; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 15:02 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> !-------------------------------------------------------------------|
>  CAUTION: External Email
> 
> |-------------------------------------------------------------------!
> 
> We want to allow overwriting writable fields of some ID registers.
> However currently some of them are never touched, neither read nor
> w. Examples are CLIDR_EL1, CTR_EL0, REVIDR_EL1, MIDR_EL1.
> 
> We want to initialize them from the host value, allow overwrite
> and write back for kvm afterwards. This patch implements the
> initialization.
> 
> Introduce a new get_host_cpu_idregs() helper that gets the host
> values for all writable ID regs and store them in isar.idregs[].
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> 
> ---
> ---
> target/arm/kvm.c        | 72 +++++++++++++++++++++++++++++++++++++++--
> target/arm/trace-events |  1 +
> 2 files changed, 71 insertions(+), 2 deletions(-)
> 
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index 4adfd20050..92219ee62e 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),
> @@ -273,7 +274,62 @@ static uint32_t kvm_arm_sve_get_vls(int fd)
>     return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ);
> }
> 
> -static void 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 = id_register_sysreg[i];
> +        uint64_t writable_mask =
> +             cpu->writable_map[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 void
> +kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf)
> {
>     /* Identify the feature bits corresponding to the host CPU, and
>      * fill out the ARMHostCPUClass fields accordingly. To do this
> @@ -359,6 +415,18 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>         SET_IDREG(&ahcf->isar, ID_AA64PFR0, 0x00000011); /* EL1&0, AArch64 only */
>         err = 0;
>     } else {
> +        /* Make sure all writable ID reg values are initialized */
> +        if (cpu->writable_map) {
> +            err |= get_host_cpu_idregs(cpu, fd, ahcf);
> +        }

Again, I do not like writable_map being in ARMCPU.

Why should kvm_arm_get_host_cpu_features care if writable
map is populated or not?

> +        /*
> +         * temporarily override the CLIDR_EL1 value since some host values
> +         * trigger "Unified type is not implemented at level n" error in
> +         * fdt_add_cpu_nodes()
> +         */
> +        SET_IDREG(&ahcf->isar, CLIDR, 0x0);
> +

This is because by default KVM exposes a 1 level unified, 1 way 1 set simple
cache, to efficiently handle set/way based cache operations.

TBH this is slightly ugly. Should make the virt machine code to not expose
cache fdt nodes if using KVM.

For our v2 (WIP), we have handled this by a new property ‘expose-cache’ for
named cpu models which is used to set CLIDR and CCSIDR banks based
on values provided by the model and only creating fdt nodes if those
values are provided.

>         err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR1_EL1_IDX);
>         err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR2_EL1_IDX);
>         err |= get_host_cpu_reg(fd, ahcf, ID_AA64SMFR0_EL1_IDX);
> @@ -485,7 +553,7 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
>     CPUARMState *env = &cpu->env;
> 
>     if (!arm_host_cpu_features.dtb_compatible) {
> -        kvm_arm_get_host_cpu_features(&arm_host_cpu_features);
> +        kvm_arm_get_host_cpu_features(cpu, &arm_host_cpu_features);
>     }
> 
>     cpu->kvm_target = arm_host_cpu_features.target;
> 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
> 


Warm Regards,
Khushit


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

* Re: [PATCH v5 13/18] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties
  2026-05-19 13:27 ` [PATCH v5 13/18] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties Eric Auger
  2026-05-26 14:42   ` Sebastian Ott
@ 2026-05-27 15:08   ` Khushit Shah
  2026-05-27 15:32     ` Eric Auger
  1 sibling, 1 reply; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 15:08 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> !-------------------------------------------------------------------|
>  CAUTION: External Email
> 
> |-------------------------------------------------------------------!
> 
> This helper decode the ID reg writable mask, matches it against
> ID reg fields defined in target/arm/cpu-idregs.h.inc and
> for each writable named field, generates a uint64 property.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> 
> ---
> 
> v4 -> v5:
> - free prop_name
> - check cpu->writable_map as a preamble in kvm_arm_expose_idreg_properties
> ---
> target/arm/kvm.c        | 135 ++++++++++++++++++++++++++++++++++++++++
> target/arm/kvm_arm.h    |  10 +++
> target/arm/trace-events |   4 ++
> 3 files changed, 149 insertions(+)
> 
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index 30c5175c68..960052e67e 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -343,6 +343,141 @@ static int get_host_cpu_idregs(ARMCPU *cpu, int fd, ARMHostCPUFeatures *ahcf)
>     return err;
> }
> 
> +static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
> +{
> +    for (int f = 0; f < reg->fields_count; f++) {
> +        struct ARM64SysRegField *field = &reg->fields[f];
> +        int upper = field->shift + field->length - 1;
> +
> +        if (i >= field->shift && i <= 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->shift;
> +    int length = field->length;
> +    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->shift;
> +    int length = field->length;
> +    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;
> +        char *prop_name;
> +        uint64_t mask;
> +
> +        if (!field) {
> +            warn_report("%s bit %d of %s is writable but no named field "
> +                        "in target/arm/cpu-idregs.h.inc",
> +                        __func__, i, reg->name);
> +            warn_report("%s is target/arm/cpu-idregs.h.inc?", __func__);
> +            map =  map & ~BIT_ULL(i);
> +            i = ctz64(map);
> +            continue;
> +        }
> +        lower = field->shift;
> +        upper = field->shift + field->length - 1;
> +        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);
> +        g_free(prop_name);
> +        nb_sysreg_props++;
> +
> +        mask = MAKE_64BIT_MASK(lower, field->length);
> +        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;
> +    Object *obj = OBJECT(cpu);
> +
> +    if (!cpu->writable_map) {
> +        return;
> +    }
> +
> +    for (i = 0; i < KVM_ARM_FEATURE_ID_RANGE_SIZE; i++) {
> +        uint64_t mask = cpu->writable_map[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, &regs[idx]);
> +            }
> +        }
> +    }
> +}
> +
> static void
> kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf)
> {
> diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
> index c1c2e7ec37..8446a9cbf0 100644
> --- a/target/arm/kvm_arm.h
> +++ b/target/arm/kvm_arm.h
> @@ -142,6 +142,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
> 

Why only expose the writable fields? I assume any management layer would also
atleast like to know the values of non-writable fields. If they just know about 
writable fields. How will they know if a migration is safe between two nodes?

I understand we cannot write to non-writable fields but that does not mean we
cannot expose the host values for those fields.

Warm Regards,
Khushit

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

* Re: [PATCH v5 06/18] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py
  2026-05-27 14:35   ` Khushit Shah
@ 2026-05-27 15:11     ` Eric Auger
  0 siblings, 0 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-27 15:11 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com

Hi Khushit,

On 5/27/26 4:35 PM, Khushit Shah wrote:
>
>> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>>  CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> 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://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=lifWLuAPiWiPtZHA1AnNwE36XKErpJppnuqSRce8eEXbd2seIXgOyghkIcv1h_tk&s=HRujmTCQGTPR11d90Orv_1iwKOLX_k3RFbkK_mx7A1s&e= 
>> and automates the generation of system register properties definitions.
>>
>> generates target/arm/cpu-idregs.h.inc 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   | 168 ++++++++++++++++++
>> 1 file changed, 168 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..3571e228ee
>> --- /dev/null
>> +++ b/scripts/update-aarch64-cpu-sysreg-properties.py
>> @@ -0,0 +1,168 @@
>> +#!/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://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=lifWLuAPiWiPtZHA1AnNwE36XKErpJppnuqSRce8eEXbd2seIXgOyghkIcv1h_tk&s=HRujmTCQGTPR11d90Orv_1iwKOLX_k3RFbkK_mx7A1s&e= 
>> +# 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
>> +
>> +    # 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))
>> +
>> +    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"    IDREG_START({reg_name})\n"
>> +
>> +        unique_fields = {}
>> +        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'))
>> +                    width = r.get('width')
>> +                    msb = lsb + int(width) - 1
>> +
>> +                    # 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, 'width': width}
>> +
>> +        # 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"    IDREG_FIELD({reg_name}, "
>> +                    f"{name}, {bits['lsb']}, {bits['width']})\n")
>> +            final_output += line
>> +        final_output += f"    IDREG_END({reg_name})\n"
>> +        final_output += "\n"
>> +
>> +    os.makedirs("target/arm", exist_ok=True)
>> +    with open("target/arm/cpu-idregs.h.inc", 'w') as f:
>> +        f.write("/* AUTOMATICALLY GENERATED, DO NOT MODIFY */\n\n")
>> +        f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
>> +        f.write("/* IDREG_START(REG) */\n")
>> +        f.write("/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */\n")
>> +        f.write("/* ... */\n")
>> +        f.write("/* IDREG_END(REG) */\n\n")
>> +        f.write(final_output)
>> +
>> +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-idregs.h.inc")
>> -- 
>> 2.53.0
>>
> Hi Eric,
>
> Can we also have the arch-defined values in here? It is already available in Registers.json easily, would be great if we can validate at-least the user
> set values are architecturally valid.

Yes valid values should be easily extractable

Thanks

Eric
>
> Warm Regards,
> Khushit
>


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

* Re: [PATCH v5 08/18] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields
  2026-05-27 14:52   ` Khushit Shah
@ 2026-05-27 15:14     ` Eric Auger
  0 siblings, 0 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-27 15:14 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



On 5/27/26 4:52 PM, Khushit Shah wrote:
>
>> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>>  CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> From: Shaju Abraham <shaju.abraham@nutanix.com>
>>
>> Include cpu-idregs.h.inc multiple times with different definitions for the
>> X-macros. This will generate tables for all Arm64 ID registers and their
>> fields. Additionally, initialize the tables with all architecturally defined
>> values. These tables will be consumed by the property layer in future
>> patches.
>>
>> Co-authored-by: Khushit Shah <khushit.shah@nutanix.com>
>> Signed-off-by: Shaju Abraham <shaju.abraham@nutanix.com>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> ---
>> target/arm/cpu-idregs.c | 50 +++++++++++++++++++++++++++++++++++++++++
>> target/arm/meson.build  |  1 +
>> 2 files changed, 51 insertions(+)
>> create mode 100644 target/arm/cpu-idregs.c
>>
>> diff --git a/target/arm/cpu-idregs.c b/target/arm/cpu-idregs.c
>> new file mode 100644
>> index 0000000000..f79b22680c
>> --- /dev/null
>> +++ b/target/arm/cpu-idregs.c
>> @@ -0,0 +1,50 @@
>> +/*
>> + *   ARM ID register field table.
>> + *
>> + *   Builds the per-id-register field descriptor arrays and the global
>> + *   arm_idregs[] table.
>> + *
>> + *  SPDX-License-Identifier: GPL-2.0-or-later
>> + */
>> +#include "qemu/osdep.h"
>> +#include "qemu/error-report.h"
>> +#include "qapi/error.h"
>> +#include "cpu.h"
>> +#include "cpu-idregs.h"
>> +
>> +#define IDREG_START(reg) \
>> +    static ARM64SysRegField reg##_fields[] = {
>> +
>> +#define IDREG_END(reg) \
>> +    };
>> +
>> +#define IDREG_FIELD(reg, field, _shift, _length) \
>> +    { \
>> +        .name = #field, \
>> +        .index = reg##_IDX, \
>> +        .shift = (_shift), \
>> +        .length = (_length), \
>> +    },
>> +#include "cpu-idregs.h.inc"
>> +#undef IDREG_START
>> +#undef IDREG_END
>> +#undef IDREG_FIELD
>> +
>> +/* generate an array of top level ID registers */
>> +#define IDREG_END(reg)
>> +#define IDREG_FIELD(reg, field, shift, length)
>> +
>> +#define IDREG_START(reg) \
>> +    [reg##_IDX] = { \
>> +        .name = #reg, \
>> +        .index = reg##_IDX, \
>> +        .fields = reg##_fields, \
>> +        .fields_count = ARRAY_SIZE(reg##_fields), \
>> +    },
>> +
>> +ARM64SysReg arm64_id_regs[NUM_ID_IDX] = {
>> +#include "cpu-idregs.h.inc"
>> +};
>> +#undef IDREG_START
>> +#undef IDREG_END
>> +#undef IDREG_FIELD
>> diff --git a/target/arm/meson.build b/target/arm/meson.build
>> index 4723f9f170..64d1ec63ab 100644
>> --- a/target/arm/meson.build
>> +++ b/target/arm/meson.build
>> @@ -19,6 +19,7 @@ arm_common_ss.add(files(
>>
>> arm_common_system_ss.add(files(
>>   'arm-qmp-cmds.c',
>> +  'cpu-idregs.c',
>> ))
>> arm_system_ss.add(when: 'CONFIG_KVM', if_true: files('hyp_gdbstub.c', 'kvm.c'))
>> arm_system_ss.add(when: 'CONFIG_HVF', if_true: files('hyp_gdbstub.c'))
>> -- 
>> 2.53.0
>>
> We can also store writable_masks here. writable_mask exposed by KVM is
> static. It does not change in any configuration hence can be fetched once 
> during scratch vCPU creation

I agree. Nevertheless when using the KVM API we need an array to store
the bitmasks anyway. That's why I initially saved it in the CPU state.
We can copy the bitmask to each id reg struct though

Eric
>
> Warm Regards,
> Khushit



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

* Re: [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model
  2026-05-19 13:27 ` [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model Eric Auger
  2026-05-26 14:51   ` Sebastian Ott
@ 2026-05-27 15:16   ` Khushit Shah
  2026-05-27 15:51     ` Eric Auger
  1 sibling, 1 reply; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 15:16 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> !-------------------------------------------------------------------|
>  CAUTION: External Email
> 
> |-------------------------------------------------------------------!
> 
> 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-idregs.h.inc.
> 
> Properties are named  SYSREG_<REG>_<FIELD> with REG and FIELD
> being those used ARCHMRS Registers.json.
> 
> When such properties are set, they override the default field value
> retrieved from the host and reinjected into KVM. Then the actual value
> being applied at KVM depends on the register, ie. it can be sanitized.
> In case the field value is rejected by KVM, the vpcu init fails.
> 
> Anyway there is a first attempt to write back this value into KVM.
> 
> Then legacy CPU options (virtualization, secure, ...) can still
> override the previous value. So low level IDREG field properties
> apply before the legacy ones.

No code to handle this right now right? Anyway I just think parse the
props in order they are specified in command line. 

qmp cpu-model-expansion is a weird case, it defines an order in which
props are processed.

> An example of invocation is:
> -cpu host,SYSREG_ID_AA64MMFR0_EL1_ECV=0x0
> which sets ECV field of ID_AA64MMFR0_EL1 to 0 (enhanced counter
> virtualization).

> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> 
> ---
> v4 -> v5:
> - get rid of ret local variable, dynamically allocate and free writable_map
>  here
> ---
> target/arm/cpu64.c | 11 ++++++++---
> 1 file changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index f2edbfc437..e0e1ff6cfb 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)      \
> @@ -851,7 +852,6 @@ static void kvm_arm_set_cpreg_mig_tolerances(ARMCPU *cpu)
> static void aarch64_host_initfn(Object *obj)
> {
>     ARMCPU *cpu = ARM_CPU(obj);
> -    int ret;
> 
> #if defined(CONFIG_NITRO)
>     if (nitro_enabled()) {
> @@ -865,13 +865,18 @@ static void aarch64_host_initfn(Object *obj)
> 
>     cpu->writable_map = g_new(uint64_t, KVM_ARM_FEATURE_ID_RANGE_SIZE);
> 
> -    ret = kvm_arm_get_writable_id_regs(cpu->writable_map);
> -    if (ret) {
> +    if (kvm_arm_get_writable_id_regs(cpu->writable_map)) {
>         g_free(cpu->writable_map);
>         cpu->writable_map = NULL;
>     }
>     kvm_arm_set_cpu_features_from_host(cpu);
>     aarch64_add_sve_properties(obj);
> +
> +    if (cpu->writable_map) {
> +        /* 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
> 

Warm Regards,
Khushit


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

* Re: [PATCH v5 17/18] arm-qmp-cmds: introspection for ID register props
  2026-05-19 13:27 ` [PATCH v5 17/18] arm-qmp-cmds: introspection for ID register props Eric Auger
  2026-05-27  6:29   ` Sebastian Ott
@ 2026-05-27 15:17   ` Khushit Shah
  2026-05-27 15:55     ` Eric Auger
  1 sibling, 1 reply; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 15:17 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> !-------------------------------------------------------------------|
>  CAUTION: External Email
> 
> |-------------------------------------------------------------------!
> 
> 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..e6c717a872 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_map) {
> +        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
> 


Why also not add support to set these properties? Like the function does for
legacy properties?

Warm Regards,
Khushit


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

* Re: [PATCH v5 10/18] target/arm/cpu64: Retrieve writable ID reg map in aarch64_host_initfn()
  2026-05-27 14:54   ` Khushit Shah
@ 2026-05-27 15:17     ` Eric Auger
  0 siblings, 0 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-27 15:17 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



On 5/27/26 4:54 PM, Khushit Shah wrote:
>
>> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> +
>> +    cpu->writable_map = g_new(uint64_t, KVM_ARM_FEATURE_ID_RANGE_SIZE);
>> +
>> +    ret = kvm_arm_get_writable_id_regs(cpu->writable_map);
>> +    if (ret) {
>> +        g_free(cpu->writable_map);
>> +        cpu->writable_map = NULL;
>> +    }
> I feel it should not be in ARMCPU state. The is a KVM property, which does not
> change for a given kernel version.

in cpu.h struct ArchCPU there are other KVM specific flags
See    /* KVM CPU state */

I agree we can eventually copy the result in ID reg structs but I am not
sure what is the best

Thanks

Eric
>
> Warm Regards,
> Khushit


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

* Re: [PATCH v5 11/18] arm/kvm: Initialize all writable ID registers from host
  2026-05-27 15:02   ` Khushit Shah
@ 2026-05-27 15:25     ` Eric Auger
  2026-05-27 15:30     ` Eric Auger
  1 sibling, 0 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-27 15:25 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



On 5/27/26 5:02 PM, Khushit Shah wrote:
>
>> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>>  CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> We want to allow overwriting writable fields of some ID registers.
>> However currently some of them are never touched, neither read nor
>> w. Examples are CLIDR_EL1, CTR_EL0, REVIDR_EL1, MIDR_EL1.
>>
>> We want to initialize them from the host value, allow overwrite
>> and write back for kvm afterwards. This patch implements the
>> initialization.
>>
>> Introduce a new get_host_cpu_idregs() helper that gets the host
>> values for all writable ID regs and store them in isar.idregs[].
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>>
>> ---
>> ---
>> target/arm/kvm.c        | 72 +++++++++++++++++++++++++++++++++++++++--
>> target/arm/trace-events |  1 +
>> 2 files changed, 71 insertions(+), 2 deletions(-)
>>
>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>> index 4adfd20050..92219ee62e 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),
>> @@ -273,7 +274,62 @@ static uint32_t kvm_arm_sve_get_vls(int fd)
>>     return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ);
>> }
>>
>> -static void 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 = id_register_sysreg[i];
>> +        uint64_t writable_mask =
>> +             cpu->writable_map[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 void
>> +kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf)
>> {
>>     /* Identify the feature bits corresponding to the host CPU, and
>>      * fill out the ARMHostCPUClass fields accordingly. To do this
>> @@ -359,6 +415,18 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>>         SET_IDREG(&ahcf->isar, ID_AA64PFR0, 0x00000011); /* EL1&0, AArch64 only */
>>         err = 0;
>>     } else {
>> +        /* Make sure all writable ID reg values are initialized */
>> +        if (cpu->writable_map) {
>> +            err |= get_host_cpu_idregs(cpu, fd, ahcf);
>> +        }
> Again, I do not like writable_map being in ARMCPU.
>
> Why should kvm_arm_get_host_cpu_features care if writable
> map is populated or not?
the cpu->writable_map check can be moved to get_host_cpu_idregs or we
use the copied bitmask in the idreg struct

Thanks

Eric
>
>> +        /*
>> +         * temporarily override the CLIDR_EL1 value since some host values
>> +         * trigger "Unified type is not implemented at level n" error in
>> +         * fdt_add_cpu_nodes()
>> +         */
>> +        SET_IDREG(&ahcf->isar, CLIDR, 0x0);
>> +
> This is because by default KVM exposes a 1 level unified, 1 way 1 set simple
> cache, to efficiently handle set/way based cache operations.
>
> TBH this is slightly ugly. Should make the virt machine code to not expose
> cache fdt nodes if using KVM.
>
> For our v2 (WIP), we have handled this by a new property ‘expose-cache’ for
> named cpu models which is used to set CLIDR and CCSIDR banks based
> on values provided by the model and only creating fdt nodes if those
> values are provided.
>
>>         err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR1_EL1_IDX);
>>         err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR2_EL1_IDX);
>>         err |= get_host_cpu_reg(fd, ahcf, ID_AA64SMFR0_EL1_IDX);
>> @@ -485,7 +553,7 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
>>     CPUARMState *env = &cpu->env;
>>
>>     if (!arm_host_cpu_features.dtb_compatible) {
>> -        kvm_arm_get_host_cpu_features(&arm_host_cpu_features);
>> +        kvm_arm_get_host_cpu_features(cpu, &arm_host_cpu_features);
>>     }
>>
>>     cpu->kvm_target = arm_host_cpu_features.target;
>> 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
>>
>
> Warm Regards,
> Khushit
>


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

* Re: [PATCH v5 12/18] arm/kvm: write back modified ID regs to KVM
  2026-05-27 14:42   ` Khushit Shah
@ 2026-05-27 15:28     ` Khushit Shah
  2026-05-27 15:33       ` Khushit Shah
  2026-05-28 17:35     ` Eric Auger
  1 sibling, 1 reply; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 15:28 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com

From 92b813355251d61ab7941a8df500ab35c0a34193 Mon Sep 17 00:00:00 2001
From: Khushit Shah <khushit.shah@nutanix.com>
Date: Mon, 25 May 2026 17:51:54 +0530
Subject: [PATCH] target/arm/kvm: cache host ID register views with and
 without EL2

kvm_arm_get_host_cpu_features() probes the host by spinning up a
scratch vCPU and reading its ID registers. When the host kernel
advertises nested virtualization, the scratch was always created with
KVM_ARM_VCPU_HAS_EL2, which makes the kernel run limit_nv_id_reg() on
that vCPU and force several ID register fields (e.g.
ID_AA64MMFR4_EL1.NV_frac, parts of ID_AA64DFR0_EL1, etc.) to values
that match KVM's nested-virt emulation rather than the raw host
capability.

Split the cache into two slots indexed by with_el2 (lazily populated)
and plumb the selector through kvm_arm_set_cpu_features_from_host()
and kvm_arm_get_host_isar(). Callers pick the view that matches their
intent.

Signed-off-by: Khushit Shah <khushit.shah@nutanix.com>
---
Patch 1, part of RFC v2 for named models for arm.
will not cleanly apply but for the gist of the solution.
---
 target/arm/arm-cpu-models.c |  5 +++--
 target/arm/arm-qmp-cmds.c   |  4 ++--
 target/arm/cpu64.c          |  2 +-
 target/arm/kvm-stub.c       |  7 ++++++-
 target/arm/kvm.c            | 37 +++++++++++++++++++++----------------
 target/arm/kvm_arm.h        |  5 +++--
 6 files changed, 36 insertions(+), 24 deletions(-)

diff --git a/target/arm/arm-cpu-models.c b/target/arm/arm-cpu-models.c
index 9265bb776a..31765be55b 100644
--- a/target/arm/arm-cpu-models.c
+++ b/target/arm/arm-cpu-models.c
@@ -549,7 +549,8 @@ static void arm_named_cpu_initfn(Object *obj)
         return;
     }
 
-    kvm_arm_set_cpu_features_from_host(cpu);
+    /* For now let's not support nested virt for named models */
+    kvm_arm_set_cpu_features_from_host(cpu, false);
     if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
         return;
     }
@@ -592,7 +593,7 @@ void arm_cpu_class_check_missing_features(ARMCPUClass *acc, strList **blockers)
         }
     }
 
-    arm_idregs_get_blockers(cpu, kvm_arm_get_host_isar(), blockers);
+    arm_idregs_get_blockers(cpu, kvm_arm_get_host_isar(false), blockers);
 out:
     object_unref(obj);
 }
diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
index 84341a2105..453442ab93 100644
--- a/target/arm/arm-qmp-cmds.c
+++ b/target/arm/arm-qmp-cmds.c
@@ -82,7 +82,7 @@ CpuPropSupportedValues *qmp_query_cpu_props_supported_values(Error **errp)
         QList *sv = qlist_new();
 
         arm_prop_append_supported_values(pdesc,
-                                         kvm_arm_get_host_isar(), sv);
+                                         kvm_arm_get_host_isar(false), sv);
         qdict_put_obj(props, pdesc->name, QOBJECT(sv));
     }
 
@@ -119,7 +119,7 @@ CpuPropInfoList *qmp_query_arm_cpu_named_model_prop_info(Error **errp)
 
         sv = qlist_new();
         arm_prop_append_supported_values(pdesc,
-                                         kvm_arm_get_host_isar(), sv);
+                                         kvm_arm_get_host_isar(false), sv);
 
         prop_info->supported_values = QOBJECT(sv);
         prop_info->composite = NULL;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 109cead3c8..16b4d87dc1 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -875,7 +875,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, true);
     aarch64_add_sve_properties(obj);
     arm_add_cpu_props(obj);
 #elif defined(CONFIG_HVF)
diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c
index 88cbe8d85c..98f41818ba 100644
--- a/target/arm/kvm-stub.c
+++ b/target/arm/kvm-stub.c
@@ -45,7 +45,7 @@ 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 with_el2)
 {
     g_assert_not_reached();
 }
@@ -119,3 +119,8 @@ char *kvm_print_register_name(uint64_t regidx)
 {
     g_assert_not_reached();
 }
+
+const ARMISARegisters *kvm_arm_get_host_isar(bool with_el2)
+{
+    return NULL;
+}
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 9f8368712f..c26ed485a3 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -65,7 +65,7 @@ typedef struct ARMHostCPUFeatures {
     const char *dtb_compatible;
 } ARMHostCPUFeatures;
 
-static ARMHostCPUFeatures arm_host_cpu_features;
+static ARMHostCPUFeatures arm_host_cpu_features[2];
 
 #define DEF(NAME, OP0, OP1, CRN, CRM, OP2) [NAME##_IDX] = #NAME,
 const char * const sysreg_names[NUM_ID_IDX] = {
@@ -349,7 +349,7 @@ static uint32_t kvm_arm_sve_get_vls(int fd)
     return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ);
 }
 
-static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
+static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf, bool with_el2)
 {
     /* Identify the feature bits corresponding to the host CPU, and
      * fill out the ARMHostCPUClass fields accordingly. To do this
@@ -389,7 +389,7 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
      * Ask for EL2 if supported.
      */
     el2_supported = kvm_arm_el2_supported();
-    if (el2_supported) {
+    if (el2_supported && with_el2) {
         init.features[0] |= 1 << KVM_ARM_VCPU_HAS_EL2;
     }
 
@@ -528,7 +528,7 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
             err |= get_host_cpu_reg(fd, ahcf, ID_AA64ZFR0_EL1_IDX);
 
             /* Read the set of supported vector lengths. */
-            arm_host_cpu_features.sve_vq_supported = kvm_arm_sve_get_vls(fd);
+            ahcf->sve_vq_supported = kvm_arm_sve_get_vls(fd);
         }
     }
     /*
@@ -586,15 +586,15 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
     ahcf->features = features;
 }
 
-void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
+void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, bool with_el2)
 {
     CPUARMState *env = &cpu->env;
 
-    if (!arm_host_cpu_features.dtb_compatible) {
-        kvm_arm_get_host_cpu_features(&arm_host_cpu_features);
+    if (!arm_host_cpu_features[with_el2].dtb_compatible) {
+        kvm_arm_get_host_cpu_features(&arm_host_cpu_features[with_el2], with_el2);
     }
 
-    cpu->kvm_target = arm_host_cpu_features.target;
+    cpu->kvm_target = arm_host_cpu_features[with_el2].target;
 
     if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {
         /*
@@ -605,15 +605,18 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
         return;
     }
 
-    cpu->dtb_compatible = arm_host_cpu_features.dtb_compatible;
-    cpu->isar = arm_host_cpu_features.isar;
-    cpu->sve_vq.supported = arm_host_cpu_features.sve_vq_supported;
-    env->features = arm_host_cpu_features.features;
+    cpu->dtb_compatible = arm_host_cpu_features[with_el2].dtb_compatible;
+    cpu->isar = arm_host_cpu_features[with_el2].isar;
+    cpu->sve_vq.supported = arm_host_cpu_features[with_el2].sve_vq_supported;
+    env->features = arm_host_cpu_features[with_el2].features;
 }
 
-const ARMISARegisters *kvm_arm_get_host_isar(void)
+const ARMISARegisters *kvm_arm_get_host_isar(bool with_el2)
 {
-    return &arm_host_cpu_features.isar;
+    if (!arm_host_cpu_features[with_el2].dtb_compatible) {
+        kvm_arm_get_host_cpu_features(&arm_host_cpu_features[with_el2], with_el2);
+    }
+    return &arm_host_cpu_features[with_el2].isar;
 }
 
 static bool kvm_no_adjvtime_get(Object *obj, Error **errp)
@@ -2331,9 +2334,11 @@ int kvm_arch_init_vcpu(CPUState *cs)
                 "  host=0x%016" PRIx64 "\n",
                 _i, sysreg_names[_i] ? sysreg_names[_i] : "(null)",
                 cpu->isar.idregs[_i],
-                arm_host_cpu_features.isar.idregs[_i]);
+                arm_host_cpu_features[cpu->has_el2].isar.idregs[_i]);
     }
-    if (!arm_idregs_validate_safe_rule(cpu, &arm_host_cpu_features.isar, &err)) {
+
+    /* validate the cpu->isar.idregs[] against the ahcf->isar.idregs[], select ahcf based on the cpu->has_el2 */
+    if (!arm_idregs_validate_safe_rule(cpu, &arm_host_cpu_features[cpu->has_el2].isar, &err)) {
         error_report_err(err);
         return -EINVAL;
     }
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 750dbe1ef4..538f87e69e 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -129,11 +129,12 @@ void kvm_arm_destroy_scratch_host_vcpu(int *fdarray);
 /**
  * kvm_arm_set_cpu_features_from_host:
  * @cpu: ARMCPU to set the features for
+ * @with_el2: probe the host with the EL2-enabled scratch vCPU view
  *
  * 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 with_el2);
 
 /**
  * kvm_arm_add_vcpu_properties:
@@ -231,7 +232,7 @@ void kvm_arm_enable_mte(Object *cpuobj, Error **errp);
 
 void arm_cpu_kvm_set_irq(void *arm_cpu, int irq, int level);
 
-const ARMISARegisters *kvm_arm_get_host_isar(void);
+const ARMISARegisters *kvm_arm_get_host_isar(bool with_el2);
 
 void arm_gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3);
 
-- 
2.52.0



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

* Re: [PATCH v5 11/18] arm/kvm: Initialize all writable ID registers from host
  2026-05-27 15:02   ` Khushit Shah
  2026-05-27 15:25     ` Eric Auger
@ 2026-05-27 15:30     ` Eric Auger
  1 sibling, 0 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-27 15:30 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



On 5/27/26 5:02 PM, Khushit Shah wrote:
>
>> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>>  CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> We want to allow overwriting writable fields of some ID registers.
>> However currently some of them are never touched, neither read nor
>> w. Examples are CLIDR_EL1, CTR_EL0, REVIDR_EL1, MIDR_EL1.
>>
>> We want to initialize them from the host value, allow overwrite
>> and write back for kvm afterwards. This patch implements the
>> initialization.
>>
>> Introduce a new get_host_cpu_idregs() helper that gets the host
>> values for all writable ID regs and store them in isar.idregs[].
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>>
>> ---
>> ---
>> target/arm/kvm.c        | 72 +++++++++++++++++++++++++++++++++++++++--
>> target/arm/trace-events |  1 +
>> 2 files changed, 71 insertions(+), 2 deletions(-)
>>
>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>> index 4adfd20050..92219ee62e 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),
>> @@ -273,7 +274,62 @@ static uint32_t kvm_arm_sve_get_vls(int fd)
>>     return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ);
>> }
>>
>> -static void 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 = id_register_sysreg[i];
>> +        uint64_t writable_mask =
>> +             cpu->writable_map[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 void
>> +kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf)
>> {
>>     /* Identify the feature bits corresponding to the host CPU, and
>>      * fill out the ARMHostCPUClass fields accordingly. To do this
>> @@ -359,6 +415,18 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>>         SET_IDREG(&ahcf->isar, ID_AA64PFR0, 0x00000011); /* EL1&0, AArch64 only */
>>         err = 0;
>>     } else {
>> +        /* Make sure all writable ID reg values are initialized */
>> +        if (cpu->writable_map) {
>> +            err |= get_host_cpu_idregs(cpu, fd, ahcf);
>> +        }
> Again, I do not like writable_map being in ARMCPU.
>
> Why should kvm_arm_get_host_cpu_features care if writable
> map is populated or not?
>
>> +        /*
>> +         * temporarily override the CLIDR_EL1 value since some host values
>> +         * trigger "Unified type is not implemented at level n" error in
>> +         * fdt_add_cpu_nodes()
>> +         */
>> +        SET_IDREG(&ahcf->isar, CLIDR, 0x0);
>> +
> This is because by default KVM exposes a 1 level unified, 1 way 1 set simple
> cache, to efficiently handle set/way based cache operations.

I sent a separate question to the contributor in
https://lore.kernel.org/all/0fc08e52-d62c-4c40-9221-9f4e659c2aa5@redhat.com/.
You can also reply in the separate thread

This looks we need a separate fix for that, no?

Thanks

Eric
>
> TBH this is slightly ugly. Should make the virt machine code to not expose
> cache fdt nodes if using KVM.
>
> For our v2 (WIP), we have handled this by a new property ‘expose-cache’ for
> named cpu models which is used to set CLIDR and CCSIDR banks based
> on values provided by the model and only creating fdt nodes if those
> values are provided.
>
>>         err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR1_EL1_IDX);
>>         err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR2_EL1_IDX);
>>         err |= get_host_cpu_reg(fd, ahcf, ID_AA64SMFR0_EL1_IDX);
>> @@ -485,7 +553,7 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
>>     CPUARMState *env = &cpu->env;
>>
>>     if (!arm_host_cpu_features.dtb_compatible) {
>> -        kvm_arm_get_host_cpu_features(&arm_host_cpu_features);
>> +        kvm_arm_get_host_cpu_features(cpu, &arm_host_cpu_features);
>>     }
>>
>>     cpu->kvm_target = arm_host_cpu_features.target;
>> 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
>>
>
> Warm Regards,
> Khushit
>


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

* Re: [PATCH v5 13/18] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties
  2026-05-27 15:08   ` Khushit Shah
@ 2026-05-27 15:32     ` Eric Auger
  2026-05-27 15:44       ` Khushit Shah
  0 siblings, 1 reply; 74+ messages in thread
From: Eric Auger @ 2026-05-27 15:32 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com

Hi,

On 5/27/26 5:08 PM, Khushit Shah wrote:
>
>> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>>  CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> This helper decode the ID reg writable mask, matches it against
>> ID reg fields defined in target/arm/cpu-idregs.h.inc and
>> for each writable named field, generates a uint64 property.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>
>> ---
>>
>> v4 -> v5:
>> - free prop_name
>> - check cpu->writable_map as a preamble in kvm_arm_expose_idreg_properties
>> ---
>> target/arm/kvm.c        | 135 ++++++++++++++++++++++++++++++++++++++++
>> target/arm/kvm_arm.h    |  10 +++
>> target/arm/trace-events |   4 ++
>> 3 files changed, 149 insertions(+)
>>
>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>> index 30c5175c68..960052e67e 100644
>> --- a/target/arm/kvm.c
>> +++ b/target/arm/kvm.c
>> @@ -343,6 +343,141 @@ static int get_host_cpu_idregs(ARMCPU *cpu, int fd, ARMHostCPUFeatures *ahcf)
>>     return err;
>> }
>>
>> +static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
>> +{
>> +    for (int f = 0; f < reg->fields_count; f++) {
>> +        struct ARM64SysRegField *field = &reg->fields[f];
>> +        int upper = field->shift + field->length - 1;
>> +
>> +        if (i >= field->shift && i <= 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->shift;
>> +    int length = field->length;
>> +    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->shift;
>> +    int length = field->length;
>> +    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;
>> +        char *prop_name;
>> +        uint64_t mask;
>> +
>> +        if (!field) {
>> +            warn_report("%s bit %d of %s is writable but no named field "
>> +                        "in target/arm/cpu-idregs.h.inc",
>> +                        __func__, i, reg->name);
>> +            warn_report("%s is target/arm/cpu-idregs.h.inc?", __func__);
>> +            map =  map & ~BIT_ULL(i);
>> +            i = ctz64(map);
>> +            continue;
>> +        }
>> +        lower = field->shift;
>> +        upper = field->shift + field->length - 1;
>> +        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);
>> +        g_free(prop_name);
>> +        nb_sysreg_props++;
>> +
>> +        mask = MAKE_64BIT_MASK(lower, field->length);
>> +        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;
>> +    Object *obj = OBJECT(cpu);
>> +
>> +    if (!cpu->writable_map) {
>> +        return;
>> +    }
>> +
>> +    for (i = 0; i < KVM_ARM_FEATURE_ID_RANGE_SIZE; i++) {
>> +        uint64_t mask = cpu->writable_map[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, &regs[idx]);
>> +            }
>> +        }
>> +    }
>> +}
>> +
>> static void
>> kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf)
>> {
>> diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
>> index c1c2e7ec37..8446a9cbf0 100644
>> --- a/target/arm/kvm_arm.h
>> +++ b/target/arm/kvm_arm.h
>> @@ -142,6 +142,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
>>
> Why only expose the writable fields? I assume any management layer would also
> atleast like to know the values of non-writable fields. If they just know about 
> writable fields. How will they know if a migration is safe between two nodes?
>
> I understand we cannot write to non-writable fields but that does not mean we
> cannot expose the host values for those fields.
I replied separately to this on your series thread. I am inclined to do
so but this raises another problematic for the layered products to know
which mismatch can be fixed

Thanks

Eric
>
> Warm Regards,
> Khushit



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

* Re: [PATCH v5 12/18] arm/kvm: write back modified ID regs to KVM
  2026-05-27 15:28     ` Khushit Shah
@ 2026-05-27 15:33       ` Khushit Shah
  0 siblings, 0 replies; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 15:33 UTC (permalink / raw)
  To: Eric Auger
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com

From 842f2adb6e4c64d285863f582d5c91862126e1fe Mon Sep 17 00:00:00 2001
From: Khushit Shah <khushit.shah@nutanix.com>
Date: Mon, 25 May 2026 17:52:40 +0530
Subject: [PATCH] target/arm/kvm: rebase -cpu host idregs to the EL2-off
 host view

When the host kernel supports nested virtualization, the scratch vCPU
used to seed cpu->isar for -cpu host is created with
KVM_ARM_VCPU_HAS_EL2. limit_nv_id_reg() then forces several ID
register fields on that scratch (e.g. ID_AA64MMFR4_EL1.NV_frac, parts
of ID_AA64DFR0_EL1) to values that match KVM's nested-virt emulation
rather than the raw host capability.

If the actual -cpu host vCPU is later created without EL2 (for example
under -machine virt,virtualization=off) limit_nv_id_reg() does not run on
it. cpu->isar still intialized on top of the scratch vCPU with EL2. This is
obivously wrong and leads to error while writeback.

To solve this rebase the idregs fields of cpu->isar.idregs[]
on top of the scratch vCPU isar without EL2. If the field
in cpu->isar.idregs[] is unchanged, it get's set to the
scratch vCPU's field value without EL2.

Named models are unaffected: their cpu->isar is rebuilt by
arm_idregs_reset_to_defaults() which resets the idregs view.

Signed-off-by: Khushit Shah <khushit.shah@nutanix.com>
---
And then this.

There is also another way to do this, We can track which properties
are set by user/model and then try to enforce those on top of the new_isar.
This is more concrete than rebasing but did not get into that complexity
for v2. I think this is good enough for now.
---
 target/arm/kvm.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index c26ed485a3..26d20799b4 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -2207,6 +2207,52 @@ bool kvm_arm_mte_supported(void)
     return kvm_check_extension(kvm_state, KVM_CAP_ARM_MTE);
 }
 
+/*
+ * Rebase cpu->isar.idregs[] on top of new_isar->isar.
+ *
+ * For fields in cpu->isar.idregs[] that are same as initial_isar->isar, update the
+ * field with the new_isar->isar values.
+ *
+ * cpu->isar.idregs[] is initialized with initial_isar->isar, CPU props
+ * changes fields values on top of that.
+ *
+ * But, initial_isar->isar always enables all the features that are supported
+ * by host, -cpu host might not enable the same (for example, virtualization/has_el2)
+ * So the idregs[] view for the actual -cpu host vCPU differs from initial_isar->isar
+ * This function rebases cpu->isar.idregs[] on top of new_isar->isar.
+ */
+static void kvm_arm_rebase_host_idregs(ARMCPU *cpu,
+                                       const ARMISARegisters *new_isar,
+                                       const ARMISARegisters *initial_isar)
+{
+    for (int i = 0; i < NUM_ID_IDX; i++) {
+        ArmIdReg *idreg = &arm_idregs[i];
+
+        for (int j = 0; j < idreg->fields_count; j++) {
+            ArmIdRegField *field = &idreg->fields[j];
+            uint64_t idreg_val;
+            uint64_t initial_val;
+            uint64_t new_val;
+
+            arm_idreg_field_read(&cpu->isar, field->idx, &idreg_val);
+            arm_idreg_field_read(initial_isar, field->idx, &initial_val);
+            arm_idreg_field_read(new_isar, field->idx, &new_val);
+
+            if (idreg_val == initial_val && new_val != idreg_val) {
+                /* The cpu->isar.idregs[]'s field val is same as
+                 * ahcf->isar.idregs[]'s field val, which was used to
+                 * initialise it.
+                 * Hence, override it with the cpregs[] value.
+                 */
+                arm_idreg_field_write(cpu, field->idx, new_val, &error_abort);
+                
+                warn_report("KVM ID %s.%s value changed from 0x%016" PRIx64 " to 0x%016" PRIx64,
+                            idreg->name,field->name, idreg_val, new_val);
+            }
+        }
+    }
+}
+
 QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
 
 static int kvm_arm_sve_set_vls(ARMCPU *cpu)
@@ -2337,6 +2383,15 @@ int kvm_arch_init_vcpu(CPUState *cs)
                 arm_host_cpu_features[cpu->has_el2].isar.idregs[_i]);
     }
 
+    /* For -cpu host/max, rebase the idregs[] on top of new_isar->isar */
+    if ((object_dynamic_cast(OBJECT(cpu), TYPE_ARM_HOST_CPU)
+        || object_dynamic_cast(OBJECT(cpu), TYPE_ARM_MAX_CPU))
+        && !cpu->has_el2 
+        && kvm_arm_el2_supported()) {
+        /* scratch vCPU is created with EL2-enabled for -cpu host */
+        kvm_arm_rebase_host_idregs(cpu, kvm_arm_get_host_isar(false), kvm_arm_get_host_isar(true));
+    }
+
     /* validate the cpu->isar.idregs[] against the ahcf->isar.idregs[], select ahcf based on the cpu->has_el2 */
     if (!arm_idregs_validate_safe_rule(cpu, &arm_host_cpu_features[cpu->has_el2].isar, &err)) {
         error_report_err(err);
-- 
2.52.0



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

* Re: [PATCH v5 13/18] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties
  2026-05-27 15:32     ` Eric Auger
@ 2026-05-27 15:44       ` Khushit Shah
  2026-05-27 16:19         ` Eric Auger
  0 siblings, 1 reply; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 15:44 UTC (permalink / raw)
  To: eric.auger@redhat.com
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 27 May 2026, at 9:02 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> I replied separately to this on your series thread. I am inclined to do
> so but this raises another problematic for the layered products to know
> which mismatch can be fixed
> 
> Thanks
> 
> Eric
> 


Hence the safe-value tags :), sneak peek to v2 of RFC, with safe-value tags.
For each prop we can say:
        ...
        {
            "name": "feat_RDM",
            "supported-values": [
                "off",
                "on"
            ],
            "type": "string"
        },
        {
            "name": "feat_ATOMIC",
            "supported-values": [
                "off",
                "on"
            ],
            "type": "string"
        },
        {
            "name": "feat_CRC32",
            "supported-values": [
                "off",
                "on"
            ],
            "type": "string"
        },
        {
            "name": "feat_SHA2",
            "supported-values": [
                "off",
                "sha256",
                "sha512"
            ],
            "type": "string"
        },
        {
            "name": "feat_SHA1",
            "supported-values": [
                "off",
                "on"
            ],
            "type": "string"
        },
        {
            "name": "feat_AES",
            "supported-values": [
                "off",
                "aes",
                "pmull"
            ],
            "type": "string"
        }
        {
            "name": "feat_NV",
            "supported-values": [
                "0.0"
            ],
            "type": "string"
        },
        {
            "name": "feat_RAS",
            "supported-values": [
                "0.0",
                "1.0",
                "1.1_base"
            ],
            "type": "string"
        },
        {
            "name": "feat_MPAM",
            "supported-values": [
                "0.0"
            ],
            "type": "string"
        },
        {
            "name": "feat_CSV2",
            "supported-values": [
                "0.0",
                "1.0"
            ],
            "type": "string"
        },
        …


	I am inclined to do so but this raises another problematic for the 	layered products to know which mismatch can be fixed
	
I am tempted to make the same argument for writable fields: how will the
layered products know which values are safe (or effectively can be set?)?

I know right now we don’t agree on keeping safe-value tags or default values.
But, I hope the above inclines you towards keeping those :) 

Warm Regards,
Khushit

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

* Re: [PATCH v5 15/18] target/arm/kvm: Ignore some writable bits that shouldn't be
  2026-05-27 14:46   ` Khushit Shah
@ 2026-05-27 15:45     ` Eric Auger
  2026-05-27 15:54       ` Khushit Shah
  0 siblings, 1 reply; 74+ messages in thread
From: Eric Auger @ 2026-05-27 15:45 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



On 5/27/26 4:46 PM, Khushit Shah wrote:
>
>> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>>
>> KVM currently reports some bits as writable whereas they are
>> RES0 or RAZ. This is detected because the code attempts to
>> match those bits against a named field and this later does not
>> exist in target/arm/cpu-idregs.h.inc.
>>
>> Let's silence warnings until those bits get fixed in the kernel.
>>
>> This was observed with v7.1-rc4 kernel.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> ---
>> target/arm/kvm.c | 23 +++++++++++++++++++----
>> 1 file changed, 19 insertions(+), 4 deletions(-)
>>
>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>> index 6373a66bbd..1688cc2106 100644
>> --- a/target/arm/kvm.c
>> +++ b/target/arm/kvm.c
>> @@ -405,6 +405,19 @@ static void get_sysreg_prop(Object *obj, Visitor *v,
>>     trace_get_sysreg_prop(name, value);
>> }
>>
>> +static bool ignore_unnamed_writable_field(ARM64SysReg *reg, int i)
>> +{
>> +    if ((!strcmp(reg->name, "ID_ISAR0_EL1") && i >= 28 && i <= 31) || /* RES0 */
>> +        (!strcmp(reg->name, "ID_ISAR5_EL1") && i >= 20 && i <= 23) || /* RES0 */
>> +        (!strcmp(reg->name, "MVFR2_EL1") && i >= 8 && i <= 31) || /* RES0 */
>> +        (!strcmp(reg->name, "ID_PFR2_EL1") && i >= 12 && i <= 31) || /* RES0 */
>> +        (!strcmp(reg->name, "ID_MMFR5_EL1") && i >= 8 && i <= 31) || /* RES0 */
>> +        (!strcmp(reg->name, "ID_AA64FPFR0_EL1") && i >= 2 && i <= 7)) { /* RAZ */
>> +        return true;
>> +    }
>> +    return false;
>> +}
>> +
>> /*
>>  * decode_idreg_writemap: Generate props for writable fields
>>  *
>> @@ -426,10 +439,12 @@ decode_idreg_writemap(Object *obj, int index, uint64_t map, ARM64SysReg *reg)
>>         uint64_t mask;
>>
>>         if (!field) {
>> -            warn_report("%s bit %d of %s is writable but no named field "
>> -                        "in target/arm/cpu-idregs.h.inc",
>> -                        __func__, i, reg->name);
>> -            warn_report("%s is target/arm/cpu-idregs.h.inc?", __func__);
>> +            if (!ignore_unnamed_writable_field(reg, i)) {
>> +                warn_report("%s bit %d of %s is writable but no named field "
>> +                            "in target/arm/cpu-idregs.h.inc",
>> +                            __func__, i, reg->name);
>> +                warn_report("%s is target/arm/cpu-idregs.h.inc?", __func__);
>> +            }
>>             map =  map & ~BIT_ULL(i);
>>             i = ctz64(map);
>>             continue;
>> — 
> This is why I feel the generated cpu-idregs.h.inc should also have information of
> RES0/1 fields as in our RFC. These fields will obviously have only one architecturally
> valid value, hence we will never allow user to write something else.
The good thing is it allowed to detect that kind of kernel inconsistency ;-)

RES fields are not defined either in target/arm/cpu-features.h and since
they are not meant to be touched, it was not that obvious to add them.

What would it change anyway, if we detect we have a writable field
matching a RESx field, I guess we would continue raising a warning, no?

Thanks

Eric

 
>
> Warm Regards,
> Khushit


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

* Re: [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model
  2026-05-27 15:16   ` Khushit Shah
@ 2026-05-27 15:51     ` Eric Auger
  2026-05-27 15:56       ` Khushit Shah
  0 siblings, 1 reply; 74+ messages in thread
From: Eric Auger @ 2026-05-27 15:51 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



On 5/27/26 5:16 PM, Khushit Shah wrote:
>
>> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>>  CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> 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-idregs.h.inc.
>>
>> Properties are named  SYSREG_<REG>_<FIELD> with REG and FIELD
>> being those used ARCHMRS Registers.json.
>>
>> When such properties are set, they override the default field value
>> retrieved from the host and reinjected into KVM. Then the actual value
>> being applied at KVM depends on the register, ie. it can be sanitized.
>> In case the field value is rejected by KVM, the vpcu init fails.
>>
>> Anyway there is a first attempt to write back this value into KVM.
>>
>> Then legacy CPU options (virtualization, secure, ...) can still
>> override the previous value. So low level IDREG field properties
>> apply before the legacy ones.
> No code to handle this right now right? Anyway I just think parse the
> props in order they are specified in command line. 
Actually I think it works that way already because we first override the
values with ID reg field prop values and then apply the legacy composite
props
>
> qmp cpu-model-expansion is a weird case, it defines an order in which
> props are processed.
Yeah that's effectively something that needs to be further tested

Thanks

Eric
>
>> An example of invocation is:
>> -cpu host,SYSREG_ID_AA64MMFR0_EL1_ECV=0x0
>> which sets ECV field of ID_AA64MMFR0_EL1 to 0 (enhanced counter
>> virtualization).
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>>
>> ---
>> v4 -> v5:
>> - get rid of ret local variable, dynamically allocate and free writable_map
>>  here
>> ---
>> target/arm/cpu64.c | 11 ++++++++---
>> 1 file changed, 8 insertions(+), 3 deletions(-)
>>
>> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
>> index f2edbfc437..e0e1ff6cfb 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)      \
>> @@ -851,7 +852,6 @@ static void kvm_arm_set_cpreg_mig_tolerances(ARMCPU *cpu)
>> static void aarch64_host_initfn(Object *obj)
>> {
>>     ARMCPU *cpu = ARM_CPU(obj);
>> -    int ret;
>>
>> #if defined(CONFIG_NITRO)
>>     if (nitro_enabled()) {
>> @@ -865,13 +865,18 @@ static void aarch64_host_initfn(Object *obj)
>>
>>     cpu->writable_map = g_new(uint64_t, KVM_ARM_FEATURE_ID_RANGE_SIZE);
>>
>> -    ret = kvm_arm_get_writable_id_regs(cpu->writable_map);
>> -    if (ret) {
>> +    if (kvm_arm_get_writable_id_regs(cpu->writable_map)) {
>>         g_free(cpu->writable_map);
>>         cpu->writable_map = NULL;
>>     }
>>     kvm_arm_set_cpu_features_from_host(cpu);
>>     aarch64_add_sve_properties(obj);
>> +
>> +    if (cpu->writable_map) {
>> +        /* 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
>>
> Warm Regards,
> Khushit
>


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

* Re: [PATCH v5 15/18] target/arm/kvm: Ignore some writable bits that shouldn't be
  2026-05-27 15:45     ` Eric Auger
@ 2026-05-27 15:54       ` Khushit Shah
  2026-05-27 16:01         ` Eric Auger
  0 siblings, 1 reply; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 15:54 UTC (permalink / raw)
  To: eric.auger@redhat.com
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 27 May 2026, at 9:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> What would it change anyway, if we detect we have a writable field
> matching a RESx field, I guess we would continue raising a warning, no?

At-least for named models we want values for each bit in 
ID register.

Warm Regards,
Khushit

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

* Re: [PATCH v5 17/18] arm-qmp-cmds: introspection for ID register props
  2026-05-27 15:17   ` Khushit Shah
@ 2026-05-27 15:55     ` Eric Auger
  0 siblings, 0 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-27 15:55 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com

Hi Khushit,

On 5/27/26 5:17 PM, Khushit Shah wrote:
>
>> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>>  CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> 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..e6c717a872 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_map) {
>> +        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
>>
>
> Why also not add support to set these properties? Like the function does for
> legacy properties?

Tbh I have not tested it yet in write mode. One problem we may encounter
is setting one ID reg value may change the value of others or at least
their visibility. So if my understanding is correct we should set each
if reg one at a time and each time read the whole set before applying
the next value. But I may be wrong

Thanks

Eric
>
> Warm Regards,
> Khushit
>


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

* Re: [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model
  2026-05-27 15:51     ` Eric Auger
@ 2026-05-27 15:56       ` Khushit Shah
  2026-05-27 16:04         ` Eric Auger
  0 siblings, 1 reply; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 15:56 UTC (permalink / raw)
  To: eric.auger@redhat.com
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 27 May 2026, at 9:21 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> Actually I think it works that way already because we first override the
> values with ID reg field prop values and then apply the legacy composite
> props
> 


So you are saying, if I do, 
	-cpu host,sve=on,SYSREG_ID_AA64PFR0_SVE=0
QEMU will still show sve capabilities to the guest?

Warm regards,
Khushit

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

* Re: [PATCH v5 15/18] target/arm/kvm: Ignore some writable bits that shouldn't be
  2026-05-27 15:54       ` Khushit Shah
@ 2026-05-27 16:01         ` Eric Auger
  2026-05-27 16:16           ` Khushit Shah
  0 siblings, 1 reply; 74+ messages in thread
From: Eric Auger @ 2026-05-27 16:01 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



On 5/27/26 5:54 PM, Khushit Shah wrote:
>
>> On 27 May 2026, at 9:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> What would it change anyway, if we detect we have a writable field
>> matching a RESx field, I guess we would continue raising a warning, no?
> At-least for named models we want values for each bit in 
> ID register.
but if a field is RESx why don't you want to overwrite it? Are there
cases where a field is RESx depending on a condition?

Thanks

Eric
>
> Warm Regards,
> Khushit


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

* Re: [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model
  2026-05-27 15:56       ` Khushit Shah
@ 2026-05-27 16:04         ` Eric Auger
  2026-05-27 16:11           ` Khushit Shah
  0 siblings, 1 reply; 74+ messages in thread
From: Eric Auger @ 2026-05-27 16:04 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



On 5/27/26 5:56 PM, Khushit Shah wrote:
> So you are saying, if I do, 
> 	-cpu host,sve=on,SYSREG_ID_AA64PFR0_SVE=0
> QEMU will still show sve capabilities to the guest?
Yes that's what I expect. Require more extensive testing though. That
could be way to handle coexistence of different levels of granulaity.
Lowest level applies first, overriden by legacy compositive options. I
guess if you plan to introduce other layers of compositive props you
will most probably handle this situation too.

Thanks

Eric



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

* Re: [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model
  2026-05-27 16:04         ` Eric Auger
@ 2026-05-27 16:11           ` Khushit Shah
  2026-05-27 17:20             ` Eric Auger
  2026-05-28 15:14             ` Eric Auger
  0 siblings, 2 replies; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 16:11 UTC (permalink / raw)
  To: eric.auger@redhat.com
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 27 May 2026, at 9:34 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> On 5/27/26 5:56 PM, Khushit Shah wrote:
>> So you are saying, if I do, 
>> -cpu host,sve=on,SYSREG_ID_AA64PFR0_SVE=0
>> QEMU will still show sve capabilities to the guest?
> Yes that's what I expect. Require more extensive testing though. That
> could be way to handle coexistence of different levels of granulaity.
> Lowest level applies first, overriden by legacy compositive options. I
> guess if you plan to introduce other layers of compositive props you
> will most probably handle this situation too.
> 

I am sure this at-least does not work with sve, 
because arm_cpu_sve_finalize() just takes looks at the PFR0.SVE field and If value is 0 sve is 'off' otherwise 'on’.

What you describe might work for legacy props backed by prop_* boolean variables in ARMCPU like pauth (backed by cpu->prop_pauth).

I have not tested this. I maybe wrong if some prop ordering magic happens at machine level.

My plan is to just parse properties in order they arrive in cmdline :)

Warm Regards,
Khushit

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

* Re: [PATCH v5 15/18] target/arm/kvm: Ignore some writable bits that shouldn't be
  2026-05-27 16:01         ` Eric Auger
@ 2026-05-27 16:16           ` Khushit Shah
  2026-05-27 16:30             ` Eric Auger
  0 siblings, 1 reply; 74+ messages in thread
From: Khushit Shah @ 2026-05-27 16:16 UTC (permalink / raw)
  To: eric.auger@redhat.com
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 27 May 2026, at 9:31 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> but if a field is RESx why don't you want to overwrite it? Are there
> cases where a field is RESx depending on a condition?
> 
> Thanks
> 
> Eric
> 

There are cases where fields are RESx based on conditions.
but too complex to get into those (CCSIDR for e.g.). 

What I meant is when we want to realize a model, 
1. If we don’t account for RESx fields how will we know which fields Res0 or Res1.
2. In future what if RESx field becomes a defined field? Instead of maintaining:
> 
> 
> +    if ((!strcmp(reg->name, "ID_ISAR0_EL1") && i >= 28 && i <= 31) || /* RES0 */
> +        (!strcmp(reg->name, "ID_ISAR5_EL1") && i >= 20 && i <= 23) || /* RES0 */
> +        (!strcmp(reg->name, "MVFR2_EL1") && i >= 8 && i <= 31) || /* RES0 */
> +        (!strcmp(reg->name, "ID_PFR2_EL1") && i >= 12 && i <= 31) || /* RES0 */
> +        (!strcmp(reg->name, "ID_MMFR5_EL1") && i >= 8 && i <= 31) || /* RES0 */
> +        (!strcmp(reg->name, "ID_AA64FPFR0_EL1") && i >= 2 && i <= 7)) { /* RAZ */
> +        return true;
> +    }

We can just maintain one cpu-idregs.h.inc and have RESx in that.

Warm Regards,
Khushit

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

* Re: [PATCH v5 13/18] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties
  2026-05-27 15:44       ` Khushit Shah
@ 2026-05-27 16:19         ` Eric Auger
  2026-05-28  5:07           ` Khushit Shah
  0 siblings, 1 reply; 74+ messages in thread
From: Eric Auger @ 2026-05-27 16:19 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



On 5/27/26 5:44 PM, Khushit Shah wrote:
>
>> On 27 May 2026, at 9:02 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> I replied separately to this on your series thread. I am inclined to do
>> so but this raises another problematic for the layered products to know
>> which mismatch can be fixed
>>
>> Thanks
>>
>> Eric
>>
>
> Hence the safe-value tags :), sneak peek to v2 of RFC, with safe-value tags.
> For each prop we can say:
>         ...
>         {
>             "name": "feat_RDM",
>             "supported-values": [
>                 "off",
>                 "on"
>             ],
>             "type": "string"
>         },
>         {
>             "name": "feat_ATOMIC",
>             "supported-values": [
>                 "off",
>                 "on"
>             ],
>             "type": "string"
>         },
>         {
>             "name": "feat_CRC32",
>             "supported-values": [
>                 "off",
>                 "on"
>             ],
>             "type": "string"
>         },
>         {
>             "name": "feat_SHA2",
>             "supported-values": [
>                 "off",
>                 "sha256",
>                 "sha512"
>             ],
>             "type": "string"
>         },
>         {
>             "name": "feat_SHA1",
>             "supported-values": [
>                 "off",
>                 "on"
>             ],
>             "type": "string"
>         },
>         {
>             "name": "feat_AES",
>             "supported-values": [
>                 "off",
>                 "aes",
>                 "pmull"
>             ],
>             "type": "string"
>         }
>         {
>             "name": "feat_NV",
>             "supported-values": [
>                 "0.0"
>             ],
>             "type": "string"
>         },
>         {
>             "name": "feat_RAS",
>             "supported-values": [
>                 "0.0",
>                 "1.0",
>                 "1.1_base"
>             ],
>             "type": "string"
>         },
>         {
>             "name": "feat_MPAM",
>             "supported-values": [
>                 "0.0"
>             ],
>             "type": "string"
>         },
>         {
>             "name": "feat_CSV2",
>             "supported-values": [
>                 "0.0",
>                 "1.0"
>             ],
>             "type": "string"
>         },
I am not sure what the above represents
>         …
>
>
> 	I am inclined to do so but this raises another problematic for the 	layered products to know which mismatch can be fixed
> 	
> I am tempted to make the same argument for writable fields: how will the
> layered products know which values are safe (or effectively can be set?)?
>
> I know right now we don’t agree on keeping safe-value tags or default values.
> But, I hope the above inclines you towards keeping those :) 

OK I think I now understand what you plan to do with safe_rule (which,
as far as I understand is not currently implemented in your v1). With a
"tool" like 

query-cpu-model-expansion you would be able to retrieve the host value. If it does not match your named model default value, you can use the safe_rule to see if it could be applied, without relying on any scratch vcpu instantiation. This makes sense in the context of providing ways for layered products to see which vcpu model can be used, assuming there is no other way like scratch vcpu instantiation.

Is that a correct understanding?

I think this implies that we need to return more information though query-cpu-model-expansion than what we currently do (at least in [1] we only return the value). We would need to return whether the prop value can apply on this host (its default value is same as host value or OK with regards to host value and safe rule and the ID reg field is writable). This most probably means we need to enhance the prop value to contain more fields.

Thoughts?

Eric



>
> Warm Regards,
> Khushit


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

* Re: [PATCH v5 15/18] target/arm/kvm: Ignore some writable bits that shouldn't be
  2026-05-27 16:16           ` Khushit Shah
@ 2026-05-27 16:30             ` Eric Auger
  0 siblings, 0 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-27 16:30 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



On 5/27/26 6:16 PM, Khushit Shah wrote:
>
>> On 27 May 2026, at 9:31 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> but if a field is RESx why don't you want to overwrite it? Are there
>> cases where a field is RESx depending on a condition?
>>
>> Thanks
>>
>> Eric
>>
> There are cases where fields are RESx based on conditions.
> but too complex to get into those (CCSIDR for e.g.). 
>
> What I meant is when we want to realize a model, 
> 1. If we don’t account for RESx fields how will we know which fields Res0 or Res1.
why would you care. Those fields are not exposed through props so host
has the good value, Res0 or 1, no?
> 2. In future what if RESx field becomes a defined field? Instead of maintaining:
>>
>> +    if ((!strcmp(reg->name, "ID_ISAR0_EL1") && i >= 28 && i <= 31) || /* RES0 */
>> +        (!strcmp(reg->name, "ID_ISAR5_EL1") && i >= 20 && i <= 23) || /* RES0 */
>> +        (!strcmp(reg->name, "MVFR2_EL1") && i >= 8 && i <= 31) || /* RES0 */
>> +        (!strcmp(reg->name, "ID_PFR2_EL1") && i >= 12 && i <= 31) || /* RES0 */
>> +        (!strcmp(reg->name, "ID_MMFR5_EL1") && i >= 8 && i <= 31) || /* RES0 */
>> +        (!strcmp(reg->name, "ID_AA64FPFR0_EL1") && i >= 2 && i <= 7)) { /* RAZ */
>> +        return true;
>> +    }
but you still have to care with old kernels which expose those fields as
writable. If the value becomes non RESx, you won't have any mismatch
anymore so I think you're just fine. Effectively either we keep this
patch for we just turn the warnings into trace points

Eric
> We can just maintain one cpu-idregs.h.inc and have RESx in that.
>
> Warm Regards,
> Khushit


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

* Re: [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model
  2026-05-27 16:11           ` Khushit Shah
@ 2026-05-27 17:20             ` Eric Auger
  2026-05-28  5:29               ` Khushit Shah
  2026-05-28 15:14             ` Eric Auger
  1 sibling, 1 reply; 74+ messages in thread
From: Eric Auger @ 2026-05-27 17:20 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



On 5/27/26 6:11 PM, Khushit Shah wrote:
>
>> On 27 May 2026, at 9:34 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> On 5/27/26 5:56 PM, Khushit Shah wrote:
>>> So you are saying, if I do, 
>>> -cpu host,sve=on,SYSREG_ID_AA64PFR0_SVE=0
>>> QEMU will still show sve capabilities to the guest?
>> Yes that's what I expect. Require more extensive testing though. That
>> could be way to handle coexistence of different levels of granulaity.
>> Lowest level applies first, overriden by legacy compositive options. I
>> guess if you plan to introduce other layers of compositive props you
>> will most probably handle this situation too.
>>
> I am sure this at-least does not work with sve, 
> because arm_cpu_sve_finalize() just takes looks at the PFR0.SVE field and If value is 0 sve is 'off' otherwise 'on’.
My reasoning was:

arm_cpu_post_init
---> kvm_arm_add_vcpu_properties
    ---> set_sysreg_prop set the new value in cpu->isar.idregs
arm_cpu_finalize_features
---> arm_cpu_sve_finalize
---> arm_cpu_sme_finalize
---> arm_cpu_pauth_finalize
../..
those fonctions do some subsequent isar accesses

So I think in general id reg field settings are applied before composite
legacy options

Thanks

Eric





>
> What you describe might work for legacy props backed by prop_* boolean variables in ARMCPU like pauth (backed by cpu->prop_pauth).
>
> I have not tested this. I maybe wrong if some prop ordering magic happens at machine level.
>
> My plan is to just parse properties in order they arrive in cmdline :)
>
> Warm Regards,
> Khushit


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

* Re: [PATCH v5 13/18] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties
  2026-05-27 16:19         ` Eric Auger
@ 2026-05-28  5:07           ` Khushit Shah
  2026-05-28 15:22             ` Eric Auger
  0 siblings, 1 reply; 74+ messages in thread
From: Khushit Shah @ 2026-05-28  5:07 UTC (permalink / raw)
  To: eric.auger@redhat.com
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 27 May 2026, at 9:49 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> !-------------------------------------------------------------------|
>  CAUTION: External Email
> 
> |-------------------------------------------------------------------!
> 
> 
> 
> On 5/27/26 5:44 PM, Khushit Shah wrote:
>> 
>>> On 27 May 2026, at 9:02 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>> 
>>> I replied separately to this on your series thread. I am inclined to do
>>> so but this raises another problematic for the layered products to know
>>> which mismatch can be fixed
>>> 
>>> Thanks
>>> 
>>> Eric
>>> 
>> 
>> Hence the safe-value tags :), sneak peek to v2 of RFC, with safe-value tags.
>> For each prop we can say:
>>        ...
>>        {
>>            "name": "feat_RDM",
>>            "supported-values": [
>>                "off",
>>                "on"
>>            ],
>>            "type": "string"
>>        },
>>        {
>>            "name": "feat_ATOMIC",
>>            "supported-values": [
>>                "off",
>>                "on"
>>            ],
>>            "type": "string"
>>        },
>>        {
>>            "name": "feat_CRC32",
>>            "supported-values": [
>>                "off",
>>                "on"
>>            ],
>>            "type": "string"
>>        },
>>        {
>>            "name": "feat_SHA2",
>>            "supported-values": [
>>                "off",
>>                "sha256",
>>                "sha512"
>>            ],
>>            "type": "string"
>>        },
>>        {
>>            "name": "feat_SHA1",
>>            "supported-values": [
>>                "off",
>>                "on"
>>            ],
>>            "type": "string"
>>        },
>>        {
>>            "name": "feat_AES",
>>            "supported-values": [
>>                "off",
>>                "aes",
>>                "pmull"
>>            ],
>>            "type": "string"
>>        }
>>        {
>>            "name": "feat_NV",
>>            "supported-values": [
>>                "0.0"
>>            ],
>>            "type": "string"
>>        },
>>        {
>>            "name": "feat_RAS",
>>            "supported-values": [
>>                "0.0",
>>                "1.0",
>>                "1.1_base"
>>            ],
>>            "type": "string"
>>        },
>>        {
>>            "name": "feat_MPAM",
>>            "supported-values": [
>>                "0.0"
>>            ],
>>            "type": "string"
>>        },
>>        {
>>            "name": "feat_CSV2",
>>            "supported-values": [
>>                "0.0",
>>                "1.0"
>>            ],
>>            "type": "string"
>>        },
> I am not sure what the above represents

This is truncated output of similar qmp command as cpu-model-expansion, which returns for each prop what
values can be set. For example MPAM is not writable by KVM, hence only one supported value “0.0”,
CSV2 on the host is only “1.0” (architecturally, 2.0 is also valid), hence only “0.0” and “1.0” in the supported values.

>>        …
>> 
>> 
>> I am inclined to do so but this raises another problematic for the layered products to know which mismatch can be fixed
>> 
>> I am tempted to make the same argument for writable fields: how will the
>> layered products know which values are safe (or effectively can be set?)?
>> 
>> I know right now we don’t agree on keeping safe-value tags or default values.
>> But, I hope the above inclines you towards keeping those :)
> 
> OK I think I now understand what you plan to do with safe_rule (which,
> as far as I understand is not currently implemented in your v1). With a
> "tool" like 

Yes not implemented in v1.

> 
> query-cpu-model-expansion you would be able to retrieve the host value. If it does not match your named model default value, you can use the safe_rule to see if it could be applied, without relying on any scratch vcpu instantiation. This makes sense in the context of providing ways for layered products to see which vcpu model can be used, assuming there is no other way like scratch vcpu instantiation.
> 
> Is that a correct understanding?

Yes!!! 

> I think this implies that we need to return more information though query-cpu-model-expansion than what we currently do (at least in [1] we only return the value). We would need to return whether the prop value can apply on this host (its default value is same as host value or OK with regards to host value and safe rule and the ID reg field is writable). This most probably means we need to enhance the prop value to contain more fields.

Sorry, did not fully understand this.

Warm Regards,
Khushit

> Thoughts?
> 
> Eric
> 
> 
> 
>> 
>> Warm Regards,
>> Khushit
> 


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

* Re: [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model
  2026-05-27 17:20             ` Eric Auger
@ 2026-05-28  5:29               ` Khushit Shah
  2026-05-28 17:31                 ` Eric Auger
  0 siblings, 1 reply; 74+ messages in thread
From: Khushit Shah @ 2026-05-28  5:29 UTC (permalink / raw)
  To: eric.auger@redhat.com
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



> On 27 May 2026, at 10:50 PM, Eric Auger <eric.auger@redhat.com> wrote:
> 
> My reasoning was:
> 
> arm_cpu_post_init
> ---> kvm_arm_add_vcpu_properties
>     ---> set_sysreg_prop set the new value in cpu->isar.idregs
> arm_cpu_finalize_features
> ---> arm_cpu_sve_finalize
> ---> arm_cpu_sme_finalize
> ---> arm_cpu_pauth_finalize
> ../..
> those fonctions do some subsequent isar accesses
> 
> So I think in general id reg field settings are applied before composite
> legacy options
> 
> Thanks
> 
> Eric



Nope, kvm_arm_add_vcpu_properties, just adds KVM specific properties.

Right now, set_sysreg_prop are called along with legacy props during

The call stack is:
machvirt_init
----> set cpu specific machine_props (has-el2, has-el3, mp-affinity)
----> dev_realize(cpu)
  ----> set cmd cpu props (prop set in order they appear in cmdline)


Warm Regards,
Khushit

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

* Re: [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model
  2026-05-27 16:11           ` Khushit Shah
  2026-05-27 17:20             ` Eric Auger
@ 2026-05-28 15:14             ` Eric Auger
  1 sibling, 0 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-28 15:14 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



On 5/27/26 6:11 PM, Khushit Shah wrote:
>
>> On 27 May 2026, at 9:34 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> On 5/27/26 5:56 PM, Khushit Shah wrote:
>>> So you are saying, if I do, 
>>> -cpu host,sve=on,SYSREG_ID_AA64PFR0_SVE=0
>>> QEMU will still show sve capabilities to the guest?
>> Yes that's what I expect. Require more extensive testing though. That
>> could be way to handle coexistence of different levels of granulaity.
>> Lowest level applies first, overriden by legacy compositive options. I
>> guess if you plan to introduce other layers of compositive props you
>> will most probably handle this situation too.
>>
> I am sure this at-least does not work with sve, 
> because arm_cpu_sve_finalize() just takes looks at the PFR0.SVE field and If value is 0 sve is 'off' otherwise 'on’.
ID_AA64PFR0_EL1 SVE field is not writable if I am not wrong. Only
ID_AA64ZFR0_EL1.SVEver is

        ID_FILTERED(ID_AA64PFR0_EL1, id_aa64pfr0_el1,
                    ~(ID_AA64PFR0_EL1_AMU |
                      ID_AA64PFR0_EL1_MPAM |
                      ID_AA64PFR0_EL1_SVE |
                      ID_AA64PFR0_EL1_AdvSIMD |
                      ID_AA64PFR0_EL1_FP)),

Eric

>
> What you describe might work for legacy props backed by prop_* boolean variables in ARMCPU like pauth (backed by cpu->prop_pauth).
>
> I have not tested this. I maybe wrong if some prop ordering magic happens at machine level.
>
> My plan is to just parse properties in order they arrive in cmdline :)
>
> Warm Regards,
> Khushit



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

* Re: [PATCH v5 13/18] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties
  2026-05-28  5:07           ` Khushit Shah
@ 2026-05-28 15:22             ` Eric Auger
  0 siblings, 0 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-28 15:22 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



On 5/28/26 7:07 AM, Khushit Shah wrote:
>
>> On 27 May 2026, at 9:49 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>>  CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>>
>>
>> On 5/27/26 5:44 PM, Khushit Shah wrote:
>>>> On 27 May 2026, at 9:02 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>>>
>>>> I replied separately to this on your series thread. I am inclined to do
>>>> so but this raises another problematic for the layered products to know
>>>> which mismatch can be fixed
>>>>
>>>> Thanks
>>>>
>>>> Eric
>>>>
>>> Hence the safe-value tags :), sneak peek to v2 of RFC, with safe-value tags.
>>> For each prop we can say:
>>>        ...
>>>        {
>>>            "name": "feat_RDM",
>>>            "supported-values": [
>>>                "off",
>>>                "on"
>>>            ],
>>>            "type": "string"
>>>        },
>>>        {
>>>            "name": "feat_ATOMIC",
>>>            "supported-values": [
>>>                "off",
>>>                "on"
>>>            ],
>>>            "type": "string"
>>>        },
>>>        {
>>>            "name": "feat_CRC32",
>>>            "supported-values": [
>>>                "off",
>>>                "on"
>>>            ],
>>>            "type": "string"
>>>        },
>>>        {
>>>            "name": "feat_SHA2",
>>>            "supported-values": [
>>>                "off",
>>>                "sha256",
>>>                "sha512"
>>>            ],
>>>            "type": "string"
>>>        },
>>>        {
>>>            "name": "feat_SHA1",
>>>            "supported-values": [
>>>                "off",
>>>                "on"
>>>            ],
>>>            "type": "string"
>>>        },
>>>        {
>>>            "name": "feat_AES",
>>>            "supported-values": [
>>>                "off",
>>>                "aes",
>>>                "pmull"
>>>            ],
>>>            "type": "string"
>>>        }
>>>        {
>>>            "name": "feat_NV",
>>>            "supported-values": [
>>>                "0.0"
>>>            ],
>>>            "type": "string"
>>>        },
>>>        {
>>>            "name": "feat_RAS",
>>>            "supported-values": [
>>>                "0.0",
>>>                "1.0",
>>>                "1.1_base"
>>>            ],
>>>            "type": "string"
>>>        },
>>>        {
>>>            "name": "feat_MPAM",
>>>            "supported-values": [
>>>                "0.0"
>>>            ],
>>>            "type": "string"
>>>        },
>>>        {
>>>            "name": "feat_CSV2",
>>>            "supported-values": [
>>>                "0.0",
>>>                "1.0"
>>>            ],
>>>            "type": "string"
>>>        },
>> I am not sure what the above represents
> This is truncated output of similar qmp command as cpu-model-expansion, which returns for each prop what
> values can be set. For example MPAM is not writable by KVM, hence only one supported value “0.0”,
> CSV2 on the host is only “1.0” (architecturally, 2.0 is also valid), hence only “0.0” and “1.0” in the supported values.
>
>>>        …
>>>
>>>
>>> I am inclined to do so but this raises another problematic for the layered products to know which mismatch can be fixed
>>>
>>> I am tempted to make the same argument for writable fields: how will the
>>> layered products know which values are safe (or effectively can be set?)?
>>>
>>> I know right now we don’t agree on keeping safe-value tags or default values.
>>> But, I hope the above inclines you towards keeping those :)
>> OK I think I now understand what you plan to do with safe_rule (which,
>> as far as I understand is not currently implemented in your v1). With a
>> "tool" like 
> Yes not implemented in v1.
>
>> query-cpu-model-expansion you would be able to retrieve the host value. If it does not match your named model default value, you can use the safe_rule to see if it could be applied, without relying on any scratch vcpu instantiation. This makes sense in the context of providing ways for layered products to see which vcpu model can be used, assuming there is no other way like scratch vcpu instantiation.
>>
>> Is that a correct understanding?
> Yes!!! 
>
>> I think this implies that we need to return more information though query-cpu-model-expansion than what we currently do (at least in [1] we only return the value). We would need to return whether the prop value can apply on this host (its default value is same as host value or OK with regards to host value and safe rule and the ID reg field is writable). This most probably means we need to enhance the prop value to contain more fields.

I imagined we could return all the data
through query-cpu-model-expansion but it seems you plan to use another
qmp cmd. Let's see what it looks like in your v2

Thanks

Eric
> Sorry, did not fully understand this.
>
> Warm Regards,
> Khushit
>
>> Thoughts?
>>
>> Eric
>>
>>
>>
>>> Warm Regards,
>>> Khushit


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

* Re: [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model
  2026-05-28  5:29               ` Khushit Shah
@ 2026-05-28 17:31                 ` Eric Auger
  0 siblings, 0 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-28 17:31 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com

Hi Khushit,

On 5/28/26 7:29 AM, Khushit Shah wrote:
>
>> On 27 May 2026, at 10:50 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> My reasoning was:
>>
>> arm_cpu_post_init
>> ---> kvm_arm_add_vcpu_properties
>>     ---> set_sysreg_prop set the new value in cpu->isar.idregs
>> arm_cpu_finalize_features
>> ---> arm_cpu_sve_finalize
>> ---> arm_cpu_sme_finalize
>> ---> arm_cpu_pauth_finalize
>> ../..
>> those fonctions do some subsequent isar accesses
>>
>> So I think in general id reg field settings are applied before composite
>> legacy options
>>
>> Thanks
>>
>> Eric
>
>
> Nope, kvm_arm_add_vcpu_properties, just adds KVM specific properties.
right, wrong copy/paste. kvm_arm_add_vcpu_properties just registers the
props
>
> Right now, set_sysreg_prop are called along with legacy props during
Yes options are applied in order but the difference is ID reg field
props settings directly touch the isar array while others are stored in
some temporary field in either machine or cpu code and analyzed later,
for what I see in arm_cpu_realizefn(), either in
arm_cpu_finalize_features() or directly in the body. So isar access
related to compositive functions should be done after those related to
new SYSREG_REG_FIELD props. However I acknoledge the requires a case by
case check and testing.

Thanks

Eric


>
> The call stack is:
> machvirt_init
> ----> set cpu specific machine_props (has-el2, has-el3, mp-affinity)
> ----> dev_realize(cpu)
>   ----> set cmd cpu props (prop set in order they appear in cmdline)


>
>
> Warm Regards,
> Khushit


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

* Re: [PATCH v5 12/18] arm/kvm: write back modified ID regs to KVM
  2026-05-27 14:42   ` Khushit Shah
  2026-05-27 15:28     ` Khushit Shah
@ 2026-05-28 17:35     ` Eric Auger
  1 sibling, 0 replies; 74+ messages in thread
From: Eric Auger @ 2026-05-28 17:35 UTC (permalink / raw)
  To: Khushit Shah
  Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
	qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
	peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	sebott@redhat.com, skolothumtho@nvidia.com, philmd@linaro.org,
	maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
	armbru@redhat.com, berrange@redhat.com, abologna@redhat.com,
	jdenemar@redhat.com



On 5/27/26 4:42 PM, Khushit Shah wrote:
>
>> On 19 May 2026, at 6:57 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>>  CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> In case some ID reg values were overriden after their
>> initialization in kvm_arm_get_host_cpu_features() we need to
>> copy the new value stored in isar.idregs array back to the
>> cpreg_list and then sync the cpreg_list to KVM.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>>
>> ---
>>
>> v4 -> v5:
>> - only call kvm_arm_writable_idregs_to_cpreg_list and
>>  write_list_to_kvmstate if writable_map is allocated
>> - reinitialize the cpreg list after sync (Jinqian)
>> ---
>> target/arm/kvm.c        | 69 ++++++++++++++++++++++++++++++++++++++++-
>> target/arm/trace-events |  1 +
>> 2 files changed, 69 insertions(+), 1 deletion(-)
>>
>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>> index 92219ee62e..30c5175c68 100644
>> --- a/target/arm/kvm.c
>> +++ b/target/arm/kvm.c
>> @@ -274,6 +274,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];
>> @@ -1189,6 +1204,40 @@ bool kvm_arm_cpu_post_load(ARMCPU *cpu)
>>     return true;
>> }
>>
>> +/*
>> + * Copy writable ID regs from isar.idregs[] to cpreg_list
>> + * in case their value differs from the original init cpreg value
>> + */
>> +static void kvm_arm_writable_idregs_to_cpreg_list(ARMCPU *cpu)
>> +{
>> +    for (int i = 0; i < KVM_ARM_FEATURE_ID_RANGE_SIZE; i++) {
>> +        uint64_t writable_mask = cpu->writable_map[i];
>> +
>> +        if (writable_mask) {
>> +            int idx = kvm_feature_idx_to_idregs_idx(i);
>> +            ARM64SysReg *sysregdesc;
>> +            uint64_t previous, new;
>> +            uint64_t *cpreg;
>> +            uint32_t sysreg;
>> +
>> +            if (idx == -1) {
>> +                /* sysreg writable, but we don't know it */
>> +                continue;
>> +            }
>> +            sysregdesc = &arm64_id_regs[idx];
>> +            sysreg = id_register_sysreg[idx];
>> +            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;
>> @@ -2140,7 +2189,25 @@ 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 */
>> +    if (cpu->writable_map) {
>> +        kvm_arm_writable_idregs_to_cpreg_list(cpu);
>> +        ret = write_list_to_kvmstate(cpu, KVM_PUT_FULL_STATE);
>> +        if (!ret) {
>> +            return -1;
>> +        }
>> +        /*
>> +         * modified values may have changed the visibility of some regs,
>> +         * reinitialize the cpreg_list accordingly
>> +         */
>> +         ret = kvm_arm_init_cpreg_list(cpu);
>> +    }
>> +
>> +    return ret;
>> }
>>
>> 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
>>
> Hi Eric, 
>
> We can not safely rely on ahcf on all configurations. This will not work for a host kernel that is booted with nested virtualisation support but qemu started without virtualisation  (i.e. -machine virt (no virtualisation=on)).
>  This happens because scratch vCPU always enables EL2 support if supported
> by the host kernel. Why limits alot of ID register fields (see limit_nv_id_reg() in
> kernel). Then the actual vCPU is initialised with ahcf->isar.idregs[] (with EL2 support). When trying to write back this will result in error.

OK I see. Thank you for reporting the issue

Eric
>
> Will attach how we solved this is separate mail/reply.
>
> Warm Regards,
> Khushit. 


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

* RE: [PATCH v5 02/18] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order
  2026-05-19 13:27 ` [PATCH v5 02/18] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order Eric Auger
@ 2026-06-01 14:07   ` Shameer Kolothum Thodi
  0 siblings, 0 replies; 74+ messages in thread
From: Shameer Kolothum Thodi @ 2026-06-01 14: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, shaju.abraham@nutanix.com,
	khushit.shah@nutanix.com, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	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: 19 May 2026 14:27
> 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; shaju.abraham@nutanix.com;
> khushit.shah@nutanix.com; yangjinqian1@huawei.com;
> cohuck@redhat.com; richard.henderson@linaro.org; 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 v5 02/18] target/arm/cpu-sysregs.h.inc: Sort by name
> alphabetical order
> 
> External email: Use caution opening links or attachments
> 
> 
> 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>

Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>

Thanks,
Shameer

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

* RE: [PATCH v5 03/18] target/arm/cpu-sysregs.h.inc: Update with automatic generation
  2026-05-19 13:27 ` [PATCH v5 03/18] target/arm/cpu-sysregs.h.inc: Update with automatic generation Eric Auger
@ 2026-06-01 14:09   ` Shameer Kolothum Thodi
  0 siblings, 0 replies; 74+ messages in thread
From: Shameer Kolothum Thodi @ 2026-06-01 14:09 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, shaju.abraham@nutanix.com,
	khushit.shah@nutanix.com, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	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: 19 May 2026 14:27
> 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; shaju.abraham@nutanix.com;
> khushit.shah@nutanix.com; yangjinqian1@huawei.com;
> cohuck@redhat.com; richard.henderson@linaro.org; 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 v5 03/18] 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>

Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>

Thanks,
Shameer

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

* RE: [PATCH v5 04/18] arm/cpu: Add infra to handle generated ID register definitions
  2026-05-19 13:27 ` [PATCH v5 04/18] arm/cpu: Add infra to handle generated ID register definitions Eric Auger
  2026-05-21 13:23   ` Sebastian Ott
@ 2026-06-01 14:28   ` Shameer Kolothum Thodi
  2026-06-12  7:38     ` Eric Auger
  1 sibling, 1 reply; 74+ messages in thread
From: Shameer Kolothum Thodi @ 2026-06-01 14:28 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, shaju.abraham@nutanix.com,
	khushit.shah@nutanix.com, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	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: 19 May 2026 14:27
> 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; shaju.abraham@nutanix.com;
> khushit.shah@nutanix.com; yangjinqian1@huawei.com;
> cohuck@redhat.com; richard.henderson@linaro.org; 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 v5 04/18] 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.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> 
> ---
> 
> v4 -> v5
> - ifdef TARGET_ARM_CPU_IDREGS_H
> - s/g_list_append/g_list_prepend
> - void arm64_sysreg_add_field()

Looks like this patch is missing the above and file:
target/arm/cpu-sysreg-properties.c

Please check.

Thanks,
Shameer

> ---
>  target/arm/cpu-idregs.h | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
>  create mode 100644 target/arm/cpu-idregs.h
> 
> diff --git a/target/arm/cpu-idregs.h b/target/arm/cpu-idregs.h
> new file mode 100644
> index 0000000000..664e2d6ddd
> --- /dev/null
> +++ b/target/arm/cpu-idregs.h
> @@ -0,0 +1,33 @@
> +/*
> + * handle ID registers and their fields
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +#ifndef TARGET_ARM_CPU_IDREGS_H
> +#define 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 shift; /* lsb of the field in the register */
> +    int length; /* highest bit number */
> +} ARM64SysRegField;
> +
> +typedef struct ARM64SysReg {
> +    const char *name;   /* name of the sysreg, for instance CTR_EL0 */
> +    ARMIDRegisterIdx index; /* register index, e.g. CTR_EL0_IDX */
> +    struct ARM64SysRegField *fields;
> +    uint32_t fields_count;
> +} ARM64SysReg;
> +
> +/*
> + * List of exposed ID regs (automatically populated from AARCHMRS
> Registers.json)
> + */
> +extern ARM64SysReg arm64_id_regs[NUM_ID_IDX];
> +
> +#endif
> --
> 2.53.0


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

* RE: [PATCH v5 09/18] target/arm/kvm: Introduce kvm_get_writable_id_regs
  2026-05-19 13:27 ` [PATCH v5 09/18] target/arm/kvm: Introduce kvm_get_writable_id_regs Eric Auger
  2026-05-21 13:43   ` Sebastian Ott
@ 2026-06-01 15:26   ` Shameer Kolothum Thodi
  1 sibling, 0 replies; 74+ messages in thread
From: Shameer Kolothum Thodi @ 2026-06-01 15:26 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, shaju.abraham@nutanix.com,
	khushit.shah@nutanix.com, yangjinqian1@huawei.com,
	cohuck@redhat.com, richard.henderson@linaro.org,
	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: 19 May 2026 14:27
> 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; shaju.abraham@nutanix.com;
> khushit.shah@nutanix.com; yangjinqian1@huawei.com;
> cohuck@redhat.com; richard.henderson@linaro.org; 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 v5 09/18] 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.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
> 
> v4 -> v5:
> - get rid of IdRegMap datatype
> - do not store the status of the query in cpu anymore, just
>   return the error in case the retrieval failed
> - add implementation in kvm-stub.c
> ---
>  target/arm/kvm-stub.c |  5 +++++
>  target/arm/kvm.c      | 21 +++++++++++++++++++++
>  target/arm/kvm_arm.h  |  2 ++
>  3 files changed, 28 insertions(+)
> 
> diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c index
> 88cbe8d85c..cd88eb741a 100644
> --- a/target/arm/kvm-stub.c
> +++ b/target/arm/kvm-stub.c
> @@ -119,3 +119,8 @@ char *kvm_print_register_name(uint64_t regidx)  {
>      g_assert_not_reached();
>  }
> +
> +int kvm_arm_get_writable_id_regs(uint64_t *idregmap) {
> +    g_assert_not_reached();
> +}
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c index
> 7d194ea112..4adfd20050 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -505,6 +505,27 @@ void
> kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
>      env->features = arm_host_cpu_features.features;  }
> 
> +int kvm_arm_get_writable_id_regs(uint64_t *idregmap) {

Nit: Subject has kvm_get_writable_id_regs

> +    int cap_writable_id_regs;
> +    struct reg_mask_range range = {
> +        .range = 0, /* up to now only a single range is supported */
> +        .addr = (uint64_t)idregmap,
> +    };
> +    int ret;
> +
> +    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))) {
> +        return -ENOSYS;
> +    }
> +
> +    ret = kvm_vm_ioctl(kvm_state, KVM_ARM_GET_REG_WRITABLE_MASKS,
> &range);
> +    return ret;
Nit:
return kvm_vm_ioctl(kvm_state, KVM_ARM_GET_REG_WRITABLE_MASKS, &range);

Besides:
Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>

Thanks,
Shameer


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

* Re: [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model
  2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
                   ` (17 preceding siblings ...)
  2026-05-19 13:27 ` [PATCH v5 18/18] arm/cpu-features: document ID reg properties Eric Auger
@ 2026-06-04  6:08 ` Jinqian Yang
  2026-06-04  6:32   ` Jinqian Yang
  18 siblings, 1 reply; 74+ messages in thread
From: Jinqian Yang @ 2026-06-04  6:08 UTC (permalink / raw)
  To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, cohuck,
	richard.henderson, sebott, skolothumtho, philmd
  Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar,
	linuxarm, liuyonglong, Zhou Wang



On 2026/5/19 21:27, Eric Auger 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. 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-v5
> 
> History:
> --------
> 
> v4 -> v5:
> - generate target/arm/cpu-idregs.h.inc that look similar to
>    the format used in [RFC PATCH v1 02/13] target/arm:
>    named_cpu_model: Add ID Register Fields without the
>    description of the value values nor safe policy/value.
>    I guess valid values could be generated from the Registers.json
>    file too. Safe policy/values cannot.
>    I reused one patch from the above series.
>    Let's see how both series can progress/coexist without any
>    anticipated bias.
> - Addressed all comments from Shameer on v4
> - Addressed 2 comments from v4 that were missed including the
>    issue of IDreg visibility affected by some other settings.
>    Unfortunately I was not able to test it.
> - Further look at overrides between low level id reg field
>    properties versus legacy CPU options. I have the feeling they
>    can coexist as long as we document the hierarchy between them:
>    host kvm default -> ID reg field props -> legacy CPU options
> - Noticed more writable fields that are RES0/RAZ
> - Improved commit messages in general
> 
> 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"}
> 
> 
> Cornelia Huck (3):
>    target/arm/kvm: Introduce kvm_get_writable_id_regs
>    arm-qmp-cmds: introspection for ID register props
>    arm/cpu-features: document ID reg properties
> 
> Eric Auger (14):
>    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-idregs.h.inc: generate with script
>    target/arm/cpu64: Retrieve writable ID reg map in
>      aarch64_host_initfn()
>    arm/kvm: Initialize all writable ID registers from host
>    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: Ignore some writable bits that shouldn't be
>    target/arm/cpu: Expose writable ID reg field properties on the kvm
>      host vcpu model
> 
> Shaju Abraham (1):
>    target/arm/cpu_idregs: generate tables for Arm64 ID registers and
>      fields
> 
>   docs/system/arm/cpu-features.rst              | 106 ++-
>   scripts/aarch64_sysreg_helpers.py             | 109 ++++
>   .../update-aarch64-cpu-sysreg-properties.py   | 168 +++++
>   scripts/update-aarch64-cpu-sysregs-header.py  |  51 ++
>   target/arm/arm-qmp-cmds.c                     |  19 +
>   target/arm/cpu-idregs.c                       |  50 ++
>   target/arm/cpu-idregs.h                       |  33 +
>   target/arm/cpu-idregs.h.inc                   | 617 ++++++++++++++++++
>   target/arm/cpu-sysregs.h.inc                  |  57 +-
>   target/arm/cpu.h                              |   3 +
>   target/arm/cpu64.c                            |  14 +
>   target/arm/kvm-stub.c                         |   5 +
>   target/arm/kvm.c                              | 320 ++++++++-
>   target/arm/kvm_arm.h                          |  12 +
>   target/arm/meson.build                        |   1 +
>   target/arm/trace-events                       |   6 +
>   16 files changed, 1539 insertions(+), 32 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.c
>   create mode 100644 target/arm/cpu-idregs.h
>   create mode 100644 target/arm/cpu-idregs.h.inc
> 

Thanks for the patch series. I tested it, and it works as expected.
After configuring the QEMU command, it was able to successfully migrate
on Hisilicon KunPeng HIP09 and HIP12 chips.

Tested-by: Jinqian Yang <yangjinqian1@huawei.com>

Thanks,
Shameer

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

* Re: [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model
  2026-06-04  6:08 ` [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Jinqian Yang
@ 2026-06-04  6:32   ` Jinqian Yang
  2026-06-04  8:31     ` Eric Auger
  0 siblings, 1 reply; 74+ messages in thread
From: Jinqian Yang @ 2026-06-04  6:32 UTC (permalink / raw)
  To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, cohuck,
	richard.henderson, sebott, skolothumtho, philmd
  Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar



On 2026/6/4 14:08, Jinqian Yang wrote:
> 
> 
> On 2026/5/19 21:27, Eric Auger 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. 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-v5
>>
>> History:
>> --------
>>
>> v4 -> v5:
>> - generate target/arm/cpu-idregs.h.inc that look similar to
>>    the format used in [RFC PATCH v1 02/13] target/arm:
>>    named_cpu_model: Add ID Register Fields without the
>>    description of the value values nor safe policy/value.
>>    I guess valid values could be generated from the Registers.json
>>    file too. Safe policy/values cannot.
>>    I reused one patch from the above series.
>>    Let's see how both series can progress/coexist without any
>>    anticipated bias.
>> - Addressed all comments from Shameer on v4
>> - Addressed 2 comments from v4 that were missed including the
>>    issue of IDreg visibility affected by some other settings.
>>    Unfortunately I was not able to test it.
>> - Further look at overrides between low level id reg field
>>    properties versus legacy CPU options. I have the feeling they
>>    can coexist as long as we document the hierarchy between them:
>>    host kvm default -> ID reg field props -> legacy CPU options
>> - Noticed more writable fields that are RES0/RAZ
>> - Improved commit messages in general
>>
>> 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"}
>>
>>
>> Cornelia Huck (3):
>>    target/arm/kvm: Introduce kvm_get_writable_id_regs
>>    arm-qmp-cmds: introspection for ID register props
>>    arm/cpu-features: document ID reg properties
>>
>> Eric Auger (14):
>>    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-idregs.h.inc: generate with script
>>    target/arm/cpu64: Retrieve writable ID reg map in
>>      aarch64_host_initfn()
>>    arm/kvm: Initialize all writable ID registers from host
>>    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: Ignore some writable bits that shouldn't be
>>    target/arm/cpu: Expose writable ID reg field properties on the kvm
>>      host vcpu model
>>
>> Shaju Abraham (1):
>>    target/arm/cpu_idregs: generate tables for Arm64 ID registers and
>>      fields
>>
>>   docs/system/arm/cpu-features.rst              | 106 ++-
>>   scripts/aarch64_sysreg_helpers.py             | 109 ++++
>>   .../update-aarch64-cpu-sysreg-properties.py   | 168 +++++
>>   scripts/update-aarch64-cpu-sysregs-header.py  |  51 ++
>>   target/arm/arm-qmp-cmds.c                     |  19 +
>>   target/arm/cpu-idregs.c                       |  50 ++
>>   target/arm/cpu-idregs.h                       |  33 +
>>   target/arm/cpu-idregs.h.inc                   | 617 ++++++++++++++++++
>>   target/arm/cpu-sysregs.h.inc                  |  57 +-
>>   target/arm/cpu.h                              |   3 +
>>   target/arm/cpu64.c                            |  14 +
>>   target/arm/kvm-stub.c                         |   5 +
>>   target/arm/kvm.c                              | 320 ++++++++-
>>   target/arm/kvm_arm.h                          |  12 +
>>   target/arm/meson.build                        |   1 +
>>   target/arm/trace-events                       |   6 +
>>   16 files changed, 1539 insertions(+), 32 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.c
>>   create mode 100644 target/arm/cpu-idregs.h
>>   create mode 100644 target/arm/cpu-idregs.h.inc
>>
> 
> Thanks for the patch series. I tested it, and it works as expected.
> After configuring the QEMU command, it was able to successfully migrate
> on Hisilicon KunPeng HIP09 and HIP12 chips.
> 
> Tested-by: Jinqian Yang <yangjinqian1@huawei.com>
> 
> Thanks,
> Shameer
> 

Sorry, I forgot to update the salutation name at the end.

Thanks,
Jinqian


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

* Re: [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model
  2026-06-04  6:32   ` Jinqian Yang
@ 2026-06-04  8:31     ` Eric Auger
  2026-06-04 12:00       ` Jinqian Yang
  0 siblings, 1 reply; 74+ messages in thread
From: Eric Auger @ 2026-06-04  8:31 UTC (permalink / raw)
  To: Jinqian Yang, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, cohuck,
	richard.henderson, sebott, skolothumtho, philmd
  Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar

Hi Jinqian,

On 6/4/26 8:32 AM, Jinqian Yang wrote:
>
>
> On 2026/6/4 14:08, Jinqian Yang wrote:
>>
>>
>> On 2026/5/19 21:27, Eric Auger 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. 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-v5
>>>
>>> History:
>>> --------
>>>
>>> v4 -> v5:
>>> - generate target/arm/cpu-idregs.h.inc that look similar to
>>>    the format used in [RFC PATCH v1 02/13] target/arm:
>>>    named_cpu_model: Add ID Register Fields without the
>>>    description of the value values nor safe policy/value.
>>>    I guess valid values could be generated from the Registers.json
>>>    file too. Safe policy/values cannot.
>>>    I reused one patch from the above series.
>>>    Let's see how both series can progress/coexist without any
>>>    anticipated bias.
>>> - Addressed all comments from Shameer on v4
>>> - Addressed 2 comments from v4 that were missed including the
>>>    issue of IDreg visibility affected by some other settings.
>>>    Unfortunately I was not able to test it.
>>> - Further look at overrides between low level id reg field
>>>    properties versus legacy CPU options. I have the feeling they
>>>    can coexist as long as we document the hierarchy between them:
>>>    host kvm default -> ID reg field props -> legacy CPU options
>>> - Noticed more writable fields that are RES0/RAZ
>>> - Improved commit messages in general
>>>
>>> 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"}
>>>
>>>
>>> Cornelia Huck (3):
>>>    target/arm/kvm: Introduce kvm_get_writable_id_regs
>>>    arm-qmp-cmds: introspection for ID register props
>>>    arm/cpu-features: document ID reg properties
>>>
>>> Eric Auger (14):
>>>    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-idregs.h.inc: generate with script
>>>    target/arm/cpu64: Retrieve writable ID reg map in
>>>      aarch64_host_initfn()
>>>    arm/kvm: Initialize all writable ID registers from host
>>>    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: Ignore some writable bits that shouldn't be
>>>    target/arm/cpu: Expose writable ID reg field properties on the kvm
>>>      host vcpu model
>>>
>>> Shaju Abraham (1):
>>>    target/arm/cpu_idregs: generate tables for Arm64 ID registers and
>>>      fields
>>>
>>>   docs/system/arm/cpu-features.rst              | 106 ++-
>>>   scripts/aarch64_sysreg_helpers.py             | 109 ++++
>>>   .../update-aarch64-cpu-sysreg-properties.py   | 168 +++++
>>>   scripts/update-aarch64-cpu-sysregs-header.py  |  51 ++
>>>   target/arm/arm-qmp-cmds.c                     |  19 +
>>>   target/arm/cpu-idregs.c                       |  50 ++
>>>   target/arm/cpu-idregs.h                       |  33 +
>>>   target/arm/cpu-idregs.h.inc                   | 617
>>> ++++++++++++++++++
>>>   target/arm/cpu-sysregs.h.inc                  |  57 +-
>>>   target/arm/cpu.h                              |   3 +
>>>   target/arm/cpu64.c                            |  14 +
>>>   target/arm/kvm-stub.c                         |   5 +
>>>   target/arm/kvm.c                              | 320 ++++++++-
>>>   target/arm/kvm_arm.h                          |  12 +
>>>   target/arm/meson.build                        |   1 +
>>>   target/arm/trace-events                       |   6 +
>>>   16 files changed, 1539 insertions(+), 32 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.c
>>>   create mode 100644 target/arm/cpu-idregs.h
>>>   create mode 100644 target/arm/cpu-idregs.h.inc
>>>
>>
>> Thanks for the patch series. I tested it, and it works as expected.
>> After configuring the QEMU command, it was able to successfully migrate
>> on Hisilicon KunPeng HIP09 and HIP12 chips.
>>
>> Tested-by: Jinqian Yang <yangjinqian1@huawei.com> 
Thank you very much Jinqian for the testing. If it does not contain
anything confidential, could you paster the cmd line (restricted to the
SUSREG_* props) you used to tune your host vcpu model. This would
provide another example of usage for reviewers/maintainers?

Thank you in advance

Best Regards

Eric
>>
>> Thanks,
>> Shameer
>>
>
> Sorry, I forgot to update the salutation name at the end.
>
> Thanks,
> Jinqian
>


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

* Re: [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model
  2026-06-04  8:31     ` Eric Auger
@ 2026-06-04 12:00       ` Jinqian Yang
  0 siblings, 0 replies; 74+ messages in thread
From: Jinqian Yang @ 2026-06-04 12:00 UTC (permalink / raw)
  To: eric.auger, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
	peter.maydell, shaju.abraham, khushit.shah, cohuck,
	richard.henderson, sebott, skolothumtho, philmd
  Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar



On 2026/6/4 16:31, Eric Auger wrote:
> Hi Jinqian,
> 
> On 6/4/26 8:32 AM, Jinqian Yang wrote:
>>
>>
>> On 2026/6/4 14:08, Jinqian Yang wrote:
>>>
>>>
>>> On 2026/5/19 21:27, Eric Auger 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. 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-v5
>>>>
>>>> History:
>>>> --------
>>>>
>>>> v4 -> v5:
>>>> - generate target/arm/cpu-idregs.h.inc that look similar to
>>>>     the format used in [RFC PATCH v1 02/13] target/arm:
>>>>     named_cpu_model: Add ID Register Fields without the
>>>>     description of the value values nor safe policy/value.
>>>>     I guess valid values could be generated from the Registers.json
>>>>     file too. Safe policy/values cannot.
>>>>     I reused one patch from the above series.
>>>>     Let's see how both series can progress/coexist without any
>>>>     anticipated bias.
>>>> - Addressed all comments from Shameer on v4
>>>> - Addressed 2 comments from v4 that were missed including the
>>>>     issue of IDreg visibility affected by some other settings.
>>>>     Unfortunately I was not able to test it.
>>>> - Further look at overrides between low level id reg field
>>>>     properties versus legacy CPU options. I have the feeling they
>>>>     can coexist as long as we document the hierarchy between them:
>>>>     host kvm default -> ID reg field props -> legacy CPU options
>>>> - Noticed more writable fields that are RES0/RAZ
>>>> - Improved commit messages in general
>>>>
>>>> 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"}
>>>>
>>>>
>>>> Cornelia Huck (3):
>>>>     target/arm/kvm: Introduce kvm_get_writable_id_regs
>>>>     arm-qmp-cmds: introspection for ID register props
>>>>     arm/cpu-features: document ID reg properties
>>>>
>>>> Eric Auger (14):
>>>>     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-idregs.h.inc: generate with script
>>>>     target/arm/cpu64: Retrieve writable ID reg map in
>>>>       aarch64_host_initfn()
>>>>     arm/kvm: Initialize all writable ID registers from host
>>>>     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: Ignore some writable bits that shouldn't be
>>>>     target/arm/cpu: Expose writable ID reg field properties on the kvm
>>>>       host vcpu model
>>>>
>>>> Shaju Abraham (1):
>>>>     target/arm/cpu_idregs: generate tables for Arm64 ID registers and
>>>>       fields
>>>>
>>>>    docs/system/arm/cpu-features.rst              | 106 ++-
>>>>    scripts/aarch64_sysreg_helpers.py             | 109 ++++
>>>>    .../update-aarch64-cpu-sysreg-properties.py   | 168 +++++
>>>>    scripts/update-aarch64-cpu-sysregs-header.py  |  51 ++
>>>>    target/arm/arm-qmp-cmds.c                     |  19 +
>>>>    target/arm/cpu-idregs.c                       |  50 ++
>>>>    target/arm/cpu-idregs.h                       |  33 +
>>>>    target/arm/cpu-idregs.h.inc                   | 617
>>>> ++++++++++++++++++
>>>>    target/arm/cpu-sysregs.h.inc                  |  57 +-
>>>>    target/arm/cpu.h                              |   3 +
>>>>    target/arm/cpu64.c                            |  14 +
>>>>    target/arm/kvm-stub.c                         |   5 +
>>>>    target/arm/kvm.c                              | 320 ++++++++-
>>>>    target/arm/kvm_arm.h                          |  12 +
>>>>    target/arm/meson.build                        |   1 +
>>>>    target/arm/trace-events                       |   6 +
>>>>    16 files changed, 1539 insertions(+), 32 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.c
>>>>    create mode 100644 target/arm/cpu-idregs.h
>>>>    create mode 100644 target/arm/cpu-idregs.h.inc
>>>>
>>>
>>> Thanks for the patch series. I tested it, and it works as expected.
>>> After configuring the QEMU command, it was able to successfully migrate
>>> on Hisilicon KunPeng HIP09 and HIP12 chips.
>>>
>>> Tested-by: Jinqian Yang <yangjinqian1@huawei.com>
> Thank you very much Jinqian for the testing. If it does not contain
> anything confidential, could you paster the cmd line (restricted to the
> SUSREG_* props) you used to tune your host vcpu model. This would
> provide another example of usage for reviewers/maintainers?
> 

Hi, Eric

Sure, here is the QEMU command line I used for testing the SYSREG_*
properties.

```
-cpu host,pauth=off,pmu=off,sve=off,\
SYSREG_ID_AA64PFR1_EL1_NMI=0x0,\
SYSREG_ID_AA64ISAR1_EL1_LS64=0x0,\
SYSREG_ID_AA64ISAR1_EL1_XS=0x0,\
SYSREG_ID_AA64ISAR1_EL1_LRCPC=0x2,\
SYSREG_ID_AA64ISAR2_EL1_RPRFM=0x0,\
SYSREG_ID_AA64ISAR2_EL1_CLRBHB=0x0,\
SYSREG_ID_AA64ISAR2_EL1_PAC_frac=0x0,\
SYSREG_ID_AA64ISAR2_EL1_BC=0x0,\
SYSREG_ID_AA64ISAR2_EL1_RPRES=0x0,\
SYSREG_ID_AA64ISAR2_EL1_WFxT=0x0,\
SYSREG_ID_AA64MMFR0_EL1_FGT=0x0,\
SYSREG_ID_AA64MMFR0_EL1_BigEnd=0x0,\
SYSREG_ID_AA64MMFR1_EL1_ECBHB=0x0,\
SYSREG_ID_AA64MMFR1_EL1_CMOW=0x0,\
SYSREG_ID_AA64MMFR1_EL1_TIDCP1=0x0,\
SYSREG_ID_AA64MMFR1_EL1_nTLBPA=0x0,\
SYSREG_ID_AA64MMFR1_EL1_AFP=0x0,\
SYSREG_ID_AA64MMFR1_EL1_HCX=0x0,\
SYSREG_ID_AA64MMFR1_EL1_ETS=0x0,\
SYSREG_ID_AA64MMFR1_EL1_PAN=0x2,\
SYSREG_ID_AA64MMFR1_EL1_HAFDBS=0x2,\
SYSREG_ID_AA64MMFR2_EL1_CnP=0x0,\
SYSREG_ID_AA64MMFR3_EL1_TCRX=0x0,\
SYSREG_ID_AA64DFR0_EL1_PMUVer=0x6,\
SYSREG_ID_AA64DFR0_EL1_DebugVer=0x9,\
SYSREG_ID_AA64DFR0_EL1_DoubleLock=0xf,\
SYSREG_ID_AA64ZFR0_EL1_F64MM=0x0,\
SYSREG_ID_AA64ZFR0_EL1_F32MM=0x0,\
SYSREG_ID_AA64ZFR0_EL1_SM4=0x0,\
SYSREG_ID_AA64ZFR0_EL1_SHA3=0x0,\
SYSREG_ID_AA64ZFR0_EL1_BitPerm=0x0,\
SYSREG_ID_AA64ZFR0_EL1_AES=0x0,\
SYSREG_ID_AA64ZFR0_EL1_SVEver=0x0,\
SYSREG_CTR_EL0_L1Ip=0x2 \
```

Best regards,
Jinqian

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

* Re: [PATCH v5 04/18] arm/cpu: Add infra to handle generated ID register definitions
  2026-06-01 14:28   ` Shameer Kolothum Thodi
@ 2026-06-12  7:38     ` Eric Auger
  0 siblings, 0 replies; 74+ messages in thread
From: Eric Auger @ 2026-06-12  7: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,
	shaju.abraham@nutanix.com, khushit.shah@nutanix.com,
	yangjinqian1@huawei.com, cohuck@redhat.com,
	richard.henderson@linaro.org, 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 6/1/26 4:28 PM, Shameer Kolothum Thodi wrote:
> Hi Eric,
>
>> -----Original Message-----
>> From: Eric Auger <eric.auger@redhat.com>
>> Sent: 19 May 2026 14:27
>> 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; shaju.abraham@nutanix.com;
>> khushit.shah@nutanix.com; yangjinqian1@huawei.com;
>> cohuck@redhat.com; richard.henderson@linaro.org; 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 v5 04/18] 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.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>>
>> ---
>>
>> v4 -> v5
>> - ifdef TARGET_ARM_CPU_IDREGS_H
>> - s/g_list_append/g_list_prepend
>> - void arm64_sysreg_add_field()

Effectively the whole commit desc is outdated now that I have migrated
to Khushit description of idregs and their fields. No need for list nor 

arm64_sysreg_add_field anymore.

Arrays are populated in [PATCH v5 08/18] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields
This is much nicer.

Thanks

Eric

> Looks like this patch is missing the above and file:
> target/arm/cpu-sysreg-properties.c
>
> Please check.
>
> Thanks,
> Shameer
>
>> ---
>>  target/arm/cpu-idregs.h | 33 +++++++++++++++++++++++++++++++++
>>  1 file changed, 33 insertions(+)
>>  create mode 100644 target/arm/cpu-idregs.h
>>
>> diff --git a/target/arm/cpu-idregs.h b/target/arm/cpu-idregs.h
>> new file mode 100644
>> index 0000000000..664e2d6ddd
>> --- /dev/null
>> +++ b/target/arm/cpu-idregs.h
>> @@ -0,0 +1,33 @@
>> +/*
>> + * handle ID registers and their fields
>> + *
>> + * SPDX-License-Identifier: GPL-2.0-or-later
>> + */
>> +#ifndef TARGET_ARM_CPU_IDREGS_H
>> +#define 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 shift; /* lsb of the field in the register */
>> +    int length; /* highest bit number */
>> +} ARM64SysRegField;
>> +
>> +typedef struct ARM64SysReg {
>> +    const char *name;   /* name of the sysreg, for instance CTR_EL0 */
>> +    ARMIDRegisterIdx index; /* register index, e.g. CTR_EL0_IDX */
>> +    struct ARM64SysRegField *fields;
>> +    uint32_t fields_count;
>> +} ARM64SysReg;
>> +
>> +/*
>> + * List of exposed ID regs (automatically populated from AARCHMRS
>> Registers.json)
>> + */
>> +extern ARM64SysReg arm64_id_regs[NUM_ID_IDX];
>> +
>> +#endif
>> --
>> 2.53.0


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

end of thread, other threads:[~2026-06-12  7:38 UTC | newest]

Thread overview: 74+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-19 13:27 [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
2026-05-19 13:27 ` [PATCH v5 01/18] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py Eric Auger
2026-05-19 13:27 ` [PATCH v5 02/18] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order Eric Auger
2026-06-01 14:07   ` Shameer Kolothum Thodi
2026-05-19 13:27 ` [PATCH v5 03/18] target/arm/cpu-sysregs.h.inc: Update with automatic generation Eric Auger
2026-06-01 14:09   ` Shameer Kolothum Thodi
2026-05-19 13:27 ` [PATCH v5 04/18] arm/cpu: Add infra to handle generated ID register definitions Eric Auger
2026-05-21 13:23   ` Sebastian Ott
2026-06-01 14:28   ` Shameer Kolothum Thodi
2026-06-12  7:38     ` Eric Auger
2026-05-19 13:27 ` [PATCH v5 05/18] scripts: Introduce scripts/aarch64_sysreg_helpers module Eric Auger
2026-05-19 13:27 ` [PATCH v5 06/18] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py Eric Auger
2026-05-27 14:35   ` Khushit Shah
2026-05-27 15:11     ` Eric Auger
2026-05-19 13:27 ` [PATCH v5 07/18] target/arm/cpu-idregs.h.inc: generate with script Eric Auger
2026-05-19 13:27 ` [PATCH v5 08/18] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields Eric Auger
2026-05-21 13:27   ` Sebastian Ott
2026-05-27 14:52   ` Khushit Shah
2026-05-27 15:14     ` Eric Auger
2026-05-19 13:27 ` [PATCH v5 09/18] target/arm/kvm: Introduce kvm_get_writable_id_regs Eric Auger
2026-05-21 13:43   ` Sebastian Ott
2026-06-01 15:26   ` Shameer Kolothum Thodi
2026-05-19 13:27 ` [PATCH v5 10/18] target/arm/cpu64: Retrieve writable ID reg map in aarch64_host_initfn() Eric Auger
2026-05-21 13:47   ` Sebastian Ott
2026-05-27 14:54   ` Khushit Shah
2026-05-27 15:17     ` Eric Auger
2026-05-19 13:27 ` [PATCH v5 11/18] arm/kvm: Initialize all writable ID registers from host Eric Auger
2026-05-21 14:22   ` Sebastian Ott
2026-05-27 15:02   ` Khushit Shah
2026-05-27 15:25     ` Eric Auger
2026-05-27 15:30     ` Eric Auger
2026-05-19 13:27 ` [PATCH v5 12/18] arm/kvm: write back modified ID regs to KVM Eric Auger
2026-05-27 14:42   ` Khushit Shah
2026-05-27 15:28     ` Khushit Shah
2026-05-27 15:33       ` Khushit Shah
2026-05-28 17:35     ` Eric Auger
2026-05-19 13:27 ` [PATCH v5 13/18] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties Eric Auger
2026-05-26 14:42   ` Sebastian Ott
2026-05-27 15:08   ` Khushit Shah
2026-05-27 15:32     ` Eric Auger
2026-05-27 15:44       ` Khushit Shah
2026-05-27 16:19         ` Eric Auger
2026-05-28  5:07           ` Khushit Shah
2026-05-28 15:22             ` Eric Auger
2026-05-19 13:27 ` [PATCH v5 14/18] target/arm/kvm: Special case REVIDR_EL1 and AIDR_EL1 Eric Auger
2026-05-26 15:08   ` Sebastian Ott
2026-05-19 13:27 ` [PATCH v5 15/18] target/arm/kvm: Ignore some writable bits that shouldn't be Eric Auger
2026-05-27 14:46   ` Khushit Shah
2026-05-27 15:45     ` Eric Auger
2026-05-27 15:54       ` Khushit Shah
2026-05-27 16:01         ` Eric Auger
2026-05-27 16:16           ` Khushit Shah
2026-05-27 16:30             ` Eric Auger
2026-05-19 13:27 ` [PATCH v5 16/18] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model Eric Auger
2026-05-26 14:51   ` Sebastian Ott
2026-05-27 15:16   ` Khushit Shah
2026-05-27 15:51     ` Eric Auger
2026-05-27 15:56       ` Khushit Shah
2026-05-27 16:04         ` Eric Auger
2026-05-27 16:11           ` Khushit Shah
2026-05-27 17:20             ` Eric Auger
2026-05-28  5:29               ` Khushit Shah
2026-05-28 17:31                 ` Eric Auger
2026-05-28 15:14             ` Eric Auger
2026-05-19 13:27 ` [PATCH v5 17/18] arm-qmp-cmds: introspection for ID register props Eric Auger
2026-05-27  6:29   ` Sebastian Ott
2026-05-27 15:17   ` Khushit Shah
2026-05-27 15:55     ` Eric Auger
2026-05-19 13:27 ` [PATCH v5 18/18] arm/cpu-features: document ID reg properties Eric Auger
2026-05-27  6:37   ` Sebastian Ott
2026-06-04  6:08 ` [PATCH v5 00/18] kvm/arm: Introduce a customizable aarch64 KVM host model Jinqian Yang
2026-06-04  6:32   ` Jinqian Yang
2026-06-04  8:31     ` Eric Auger
2026-06-04 12:00       ` Jinqian Yang

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.