Add a KVM-only named CPU model for Neoverse V2 (TRM 102375, r0p0),
inheriting from arm-v9.0-a-v1. The property list is the subset of the
TRM that KVM can virtualize for a non-nested guest.

EL2, EL3, and SEL2 are left unimplemented. AMU, MPAM, SPE, TRF, and
similar features are omitted because KVM does not virtualize them. SoC
crypto opt-ins
are left unimplemented. PMU stays disabled for named models.

Some fields that a non-EL2 guest does not use (VH, EVT, S2FWB, E2H0) are
still pinned to the TRM value because KVM does not allow userspace to
lower them.

Final ID register state requested from KVM for "neoverse-v2-v1":
[  0] AIDR_EL1                 = 0x0000000000000000
[  1] CLIDR_EL1                = 0x0000000000000000
[  2] CTR_EL0                  = 0x000000009444c004
[  3] DCZID_EL0                = 0x0000000000000004
[  4] GMID_EL1                 = 0x0000000000000000
[  5] ID_AA64AFR0_EL1          = 0x0000000000000000
[  6] ID_AA64AFR1_EL1          = 0x0000000000000000
[  7] ID_AA64DFR0_EL1          = 0x000000f010305009
[  8] ID_AA64DFR1_EL1          = 0x0000000000000000
[  9] ID_AA64DFR2_EL1          = 0x0000000000000000
[ 10] ID_AA64FPFR0_EL1         = 0x0000000000000000
[ 11] ID_AA64ISAR0_EL1         = 0x0221100010210000
[ 12] ID_AA64ISAR1_EL1         = 0x0011111101211052
[ 13] ID_AA64ISAR2_EL1         = 0x0000000000000000
[ 14] ID_AA64ISAR3_EL1         = 0x0000000000000000
[ 15] ID_AA64MMFR0_EL1         = 0x0000011100101125
[ 16] ID_AA64MMFR1_EL1         = 0x0000000010312122
[ 17] ID_AA64MMFR2_EL1         = 0x1221011110001011
[ 18] ID_AA64MMFR3_EL1         = 0x0000000000000000
[ 19] ID_AA64MMFR4_EL1         = 0x0000000000000000
[ 20] ID_AA64PFR0_EL1          = 0x1101000120110011
[ 21] ID_AA64PFR1_EL1          = 0x0000000000000021
[ 22] ID_AA64PFR2_EL1          = 0x0000000000000000
[ 23] ID_AA64SMFR0_EL1         = 0x0000000000000000
[ 24] ID_AA64ZFR0_EL1          = 0x0000100000110001
[ 25] ID_AFR0_EL1              = 0x0000000000000000
[ 26] ID_DFR0_EL1              = 0x0000000000000000
[ 27] ID_DFR1_EL1              = 0x0000000000000000
[ 28] ID_ISAR0_EL1             = 0x0000000000000000
[ 29] ID_ISAR1_EL1             = 0x0000000000000000
[ 30] ID_ISAR2_EL1             = 0x0000000000000000
[ 31] ID_ISAR3_EL1             = 0x0000000000000000
[ 32] ID_ISAR4_EL1             = 0x0000000000000000
[ 33] ID_ISAR5_EL1             = 0x0000000000000000
[ 34] ID_ISAR6_EL1             = 0x0000000000000000
[ 35] ID_MMFR0_EL1             = 0x0000000000000000
[ 36] ID_MMFR1_EL1             = 0x0000000000000000
[ 37] ID_MMFR2_EL1             = 0x0000000000000000
[ 38] ID_MMFR3_EL1             = 0x0000000000000000
[ 39] ID_MMFR4_EL1             = 0x0000000000000000
[ 40] ID_MMFR5_EL1             = 0x0000000000000000
[ 41] ID_PFR0_EL1              = 0x0000000000000000
[ 42] ID_PFR1_EL1              = 0x0000000000000000
[ 43] ID_PFR2_EL1              = 0x0000000000000000
[ 44] MIDR_EL1                 = 0x00000000410fd4f0
[ 45] MPIDR_EL1                = 0x0000000080000000
[ 46] MVFR0_EL1                = 0x0000000000000000
[ 47] MVFR1_EL1                = 0x0000000000000000
[ 48] MVFR2_EL1                = 0x0000000000000000
[ 49] REVIDR_EL1               = 0x0000000000000000
[ 50] SMIDR_EL1                = 0x0000000000000000

Signed-off-by: Khushit Shah <[email protected]>
---
 hw/arm/virt.c           |   1 +
 target/arm/cpu-models.c | 100 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 101 insertions(+)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 01381ab5e7..f5a8ea1145 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -4146,6 +4146,7 @@ static GPtrArray *virt_get_valid_cpu_types(const 
MachineState *ms)
     }
     if (kvm_enabled() && target_aarch64()) {
         g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME("arm-v9.0-a-v1")));
+        g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME("neoverse-v2-v1")));
     }
     if (target_aarch64()) {
         g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME("cortex-a53")));
diff --git a/target/arm/cpu-models.c b/target/arm/cpu-models.c
index 7394dd358e..2de67f353b 100644
--- a/target/arm/cpu-models.c
+++ b/target/arm/cpu-models.c
@@ -13,6 +13,9 @@
  * Assumptions:
  *     - All named CPU model properties are idempotent.
  *
+ * Current Hierarchy:
+ * arm-v9.0-a-v1
+ *   neoverse-v2-v1 (r0p0)
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
@@ -113,8 +116,105 @@ static const ArmModelPropValue arm_v9_0_a_v1_props[] = {
     MODEL_PROP_END,
 };
 
+/* Neoverse V2 CPU model (TRM 102375, r0p0), inherits from arm-v9.0-a-v1. */
+static const ArmModelPropValue neoverse_v2_v1_props[] = {
+    /* MIDR_EL1 */
+    MODEL_PROP("SYSREG_MIDR_EL1_Implementer", NUM, 0x41), /* ARM */
+    MODEL_PROP("SYSREG_MIDR_EL1_Variant", NUM, 0x0), /* r0p0*/
+    MODEL_PROP("SYSREG_MIDR_EL1_Architecture", NUM, 0xF),
+    MODEL_PROP("SYSREG_MIDR_EL1_Revision", NUM, 0x0), /* r0p0 */
+    MODEL_PROP("SYSREG_MIDR_EL1_PartNum", NUM, 0xD4F), /* Neoverse V2 */
+
+    /* ID_AA64PFR0_EL1 */
+    /* Neoverse V2 implements CSV2.2 but CSV2 is capped to 1.0 by KVM */
+    /* AMU and MPAM are not supported by KVM */
+    /* SEL2 is left not implemented for non-virtualized VM */
+    /* EL2 and EL3 are not implemented for non-virtualized VM */
+    MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_SVE", NUM, 1), /* FEAT_SVE */
+    MODEL_PROP("sve128", BOOL, true),
+    MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_RAS", NUM, 2), /* override; 
FEAT_RASv1p1 */
+
+    /* ID_AA64PFR1_EL1 */
+    MODEL_PROP("SYSREG_ID_AA64PFR1_EL1_SSBS", NUM, 2), /* FEAT_SSBS2 */
+
+    /* ID_AA64ZFR0_EL1 */
+    MODEL_PROP("SYSREG_ID_AA64ZFR0_EL1_I8MM", NUM, 1), /* FEAT_I8MM */
+    MODEL_PROP("SYSREG_ID_AA64ZFR0_EL1_BF16", NUM, 1), /* FEAT_BF16 */
+    MODEL_PROP("SYSREG_ID_AA64ZFR0_EL1_BitPerm", NUM, 1), /* FEAT_SVE_BitPerm 
*/
+    MODEL_PROP("SYSREG_ID_AA64ZFR0_EL1_SVEver", NUM, 1), /* FEAT_SVE2 */
+    /* Other ID_AA64ZFR0_EL1 fields are SoC opt-ins */
+
+    /* ID_AA64DFR0_EL1 */
+    /* KVM does not virtualize FEAT_TRBE, FEAT_TRF, or FEAT_SPE. */
+    MODEL_PROP("SYSREG_ID_AA64DFR0_EL1_CTX_CMPs", NUM, 1), /* 2 context-aware 
BPs */
+    MODEL_PROP("SYSREG_ID_AA64DFR0_EL1_WRPs", NUM, 3), /* 4 watchpoints */
+    MODEL_PROP("SYSREG_ID_AA64DFR0_EL1_BRPs", NUM, 5), /* 6 breakpoints */
+
+    /* ID_AA64ISAR0_EL1 */
+    /* Many fields are SoC opt-ins; no mandatory overrides from Armv9.0-a-v1 */
+
+    /* ID_AA64ISAR1_EL1 */
+    MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_I8MM", NUM, 1), /* FEAT_I8MM */
+    MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_DGH", NUM, 1), /* FEAT_DGH */
+    MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_BF16", NUM, 1), /* FEAT_BF16 */
+    /* FEAT_PAuth2, QARMA5 is implemented */
+    MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_GPA", NUM, 1),
+    MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_APA", NUM, 5),
+
+    /* ID_AA64MMFR0_EL1 */
+    /* Keep stage-2 translations unimplemented for non-virtualized guests */
+    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran64", NUM, 0), /* supported */
+    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran16", NUM, 1), /* supported */
+    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_SNSMem", NUM, 1), /* supported */
+    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_BigEnd", NUM, 1), /* supported */
+    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_ASIDBits", NUM, 2), /* 16 bits ASID */
+    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_PARange", NUM, 5), /* 48 bits PA Range 
*/
+
+    /* ID_AA64MMFR1_EL1 */
+    MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_XNX", NUM, 1), /* FEAT_XNX */
+    MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_PAN", NUM, 3), /* override; FEAT_PAN3 
*/
+    MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_VMIDBits", NUM, 2), /* 16 bits */
+    MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_HAFDBS", NUM, 2), /* FEAT_HAFDBS */
+    /*
+     * VHE is not needed for non-virtualized guests, but KVM does not
+     * support writing to it.
+     */
+    MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_VH", NUM, 1),
+    MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_HPDS", NUM, 2), /* override; FEAT_HPDS 
*/
+
+    /* ID_AA64MMFR2_EL1 */
+    /*
+     * FEAT_EVT, FEAT_S2FWB not needed for non-virtualized guests, but KVM
+     * does not support writing to them.
+     */
+    MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_EVT", NUM, 2),
+    MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_BBM", NUM, 2), /* FEAT_BBM2 */
+    MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_FWB", NUM, 1), /* FEAT_S2FWB */
+    MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_ST", NUM, 1), /* FEAT_TTST */
+    MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_IESB", NUM, 1), /* FEAT_IESB */
+    /* FEAT_CCIDX not virtualized by KVM */
+    /* FEAT_NV not presented for non-virtualized guests */
+
+    /* ID_AA64MMFR4_EL1 */
+    MODEL_PROP("SYSREG_ID_AA64MMFR4_EL1_E2H0", NUM, 0), /* override; FEAT_E2H0 
*/
+
+    /* CTR_EL0 */
+    MODEL_PROP("SYSREG_CTR_EL0_IDC", NUM, 1),
+    MODEL_PROP("SYSREG_CTR_EL0_CWG", NUM, 4), /* Cache-writeback granule */
+    MODEL_PROP("SYSREG_CTR_EL0_ERG", NUM, 4),
+    MODEL_PROP("SYSREG_CTR_EL0_DminLine", NUM, 4), /* 64 bytes */
+    MODEL_PROP("SYSREG_CTR_EL0_IminLine", NUM, 4), /* 64 bytes */
+    MODEL_PROP("SYSREG_CTR_EL0_L1Ip", NUM, 3), /* PIPT */
+
+    /* DCZID_EL0 */
+    MODEL_PROP("SYSREG_DCZID_EL0_BS", NUM, 4), /* 64 bytes */
+
+    MODEL_PROP_END
+};
+
 static const ArmNamedCpuModel arm_cpu_models[] = {
     {"arm-v9.0-a-v1", NULL, arm_v9_0_a_v1_props},
+    {"neoverse-v2-v1", "arm-v9.0-a-v1", neoverse_v2_v1_props},
     {NULL, NULL, NULL}
 };
 
-- 
2.52.0


Reply via email to