qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: qemu-arm@nongnu.org
Subject: [PATCH v2 12/37] target/arm: Put 128-bit sysregs into a separate list
Date: Tue, 14 Oct 2025 13:06:53 -0700	[thread overview]
Message-ID: <20251014200718.422022-13-richard.henderson@linaro.org> (raw)
In-Reply-To: <20251014200718.422022-1-richard.henderson@linaro.org>

Duplicate the cpreg_{indexes,values,array_len} array as
cpreg128_{indexes,values,array_len}.  Similarly for
cpreg_vmstate_{indexes,values,array_len}.

Split the values between the two arrays during
write_cpustate_to_list, write_list_to_cpustate,
count_cpreg, and add_cpreg_to_list.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu.h    |  19 +++++--
 target/arm/helper.c | 125 +++++++++++++++++++++++++++++++++++---------
 2 files changed, 116 insertions(+), 28 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e21612b898..a030539488 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -918,25 +918,36 @@ struct ArchCPU {
 
     /* Coprocessor information */
     GHashTable *cp_regs;
-    /* For marshalling (mostly coprocessor) register state between the
+    /*
+     * For marshalling (mostly coprocessor) register state between the
      * kernel and QEMU (for KVM) and between two QEMUs (for migration),
      * we use these arrays.
      */
-    /* List of register indexes managed via these arrays; (full KVM style
-     * 64 bit indexes, not CPRegInfo 32 bit indexes)
+    /*
+     * List of register indexes managed via these arrays (full KVM style
+     * 64 bit indexes, not CPRegInfo 32 bit indexes).  The registers are
+     * segregated by size, with 64-bit registers in cpreg_indexes and
+     * 128-bit registers in cpreg128_indexes.
      */
     uint64_t *cpreg_indexes;
+    uint64_t *cpreg128_indexes;
     /* Values of the registers (cpreg_indexes[i]'s value is cpreg_values[i]) */
     uint64_t *cpreg_values;
+    Int128 *cpreg128_values;
     /* Length of the indexes, values, reset_values arrays */
     int32_t cpreg_array_len;
-    /* These are used only for migration: incoming data arrives in
+    int32_t cpreg128_array_len;
+    /*
+     * These are used only for migration: incoming data arrives in
      * these fields and is sanity checked in post_load before copying
      * to the working data structures above.
      */
     uint64_t *cpreg_vmstate_indexes;
+    uint64_t *cpreg128_vmstate_indexes;
     uint64_t *cpreg_vmstate_values;
+    Int128 *cpreg128_vmstate_values;
     int32_t cpreg_vmstate_array_len;
+    int32_t cpreg128_vmstate_array_len;
 
     DynamicGDBFeatureInfo dyn_sysreg_feature;
     DynamicGDBFeatureInfo dyn_svereg_feature;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index d9d8ae56e8..d3a425e259 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -217,10 +217,11 @@ static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
 bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
 {
     /* Write the coprocessor state from cpu->env to the (index,value) list. */
-    int i;
+    int i, n;
     bool ok = true;
 
-    for (i = 0; i < cpu->cpreg_array_len; i++) {
+    n = cpu->cpreg_array_len;
+    for (i = 0; i < n; i++) {
         uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
         const ARMCPRegInfo *ri;
         uint64_t newval;
@@ -230,6 +231,10 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
             ok = false;
             continue;
         }
+        if (ri->type & ARM_CP_128BIT) {
+            ok = false;
+            continue;
+        }
         if (ri->type & ARM_CP_NO_RAW) {
             continue;
         }
@@ -257,35 +262,77 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
         }
         cpu->cpreg_values[i] = newval;
     }
-    return ok;
-}
 
-bool write_list_to_cpustate(ARMCPU *cpu)
-{
-    int i;
-    bool ok = true;
+    n = cpu->cpreg128_array_len;
+    if (n == 0) {
+        return ok;
+    }
+    assert(!kvm_sync);
 
-    for (i = 0; i < cpu->cpreg_array_len; i++) {
-        uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
-        uint64_t v = cpu->cpreg_values[i];
-        const ARMCPRegInfo *ri;
+    for (i = 0; i < n; i++) {
+        uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg128_indexes[i]);
+        const ARMCPRegInfo *ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
 
-        ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
         if (!ri) {
             ok = false;
             continue;
         }
+        if (!(ri->type & ARM_CP_128BIT)) {
+            ok = false;
+            continue;
+        }
         if (ri->type & ARM_CP_NO_RAW) {
             continue;
         }
-        /*
-         * Write value and confirm it reads back as written
-         * (to catch read-only registers and partially read-only
-         * registers where the incoming migration value doesn't match)
-         */
-        write_raw_cp_reg(&cpu->env, ri, v);
-        if (read_raw_cp_reg(&cpu->env, ri) != v) {
+
+        cpu->cpreg128_values[i] = read_raw_cp_reg128(&cpu->env, ri);
+    }
+    return ok;
+}
+
+bool write_list_to_cpustate(ARMCPU *cpu)
+{
+    int i, n;
+    bool ok = true;
+
+    n = cpu->cpreg_array_len;
+    for (i = 0; i < n; i++) {
+        uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
+        const ARMCPRegInfo *ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
+
+        if (!ri) {
             ok = false;
+        } else if (ri->type & ARM_CP_128BIT) {
+            ok = false;
+        } else if (!(ri->type & ARM_CP_NO_RAW)) {
+            /*
+             * Write value and confirm it reads back as written
+             * (to catch read-only registers and partially read-only
+             * registers where the incoming migration value doesn't match)
+             */
+            uint64_t v = cpu->cpreg_values[i];
+            write_raw_cp_reg(&cpu->env, ri, v);
+            if (read_raw_cp_reg(&cpu->env, ri) != v) {
+                ok = false;
+            }
+        }
+    }
+
+    n = cpu->cpreg128_array_len;
+    for (i = 0; i < n; i++) {
+        uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg128_indexes[i]);
+        const ARMCPRegInfo *ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
+
+        if (!ri) {
+            ok = false;
+        } else if (!(ri->type & ARM_CP_128BIT)) {
+            ok = false;
+        } else if (!(ri->type & ARM_CP_NO_RAW)) {
+            Int128 v = cpu->cpreg128_values[i];
+            write_raw_cp_reg128(&cpu->env, ri, v);
+            if (int128_ne(read_raw_cp_reg128(&cpu->env, ri), v)) {
+                ok = false;
+            }
         }
     }
     return ok;
@@ -298,9 +345,14 @@ static void add_cpreg_to_list(gpointer key, gpointer value, gpointer opaque)
     const ARMCPRegInfo *ri = value;
 
     if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_ALIAS))) {
-        cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx);
+        uint64_t idx = cpreg_to_kvm_id(regidx);
+
         /* The value array need not be initialized at this point */
-        cpu->cpreg_array_len++;
+        if (ri->type & ARM_CP_128BIT) {
+            cpu->cpreg128_indexes[cpu->cpreg128_array_len++] = idx;
+        } else {
+            cpu->cpreg_indexes[cpu->cpreg_array_len++] = idx;
+        }
     }
 }
 
@@ -310,7 +362,11 @@ static void count_cpreg(gpointer key, gpointer value, gpointer opaque)
     const ARMCPRegInfo *ri = value;
 
     if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_ALIAS))) {
-        cpu->cpreg_array_len++;
+        if (ri->type & ARM_CP_128BIT) {
+            cpu->cpreg128_array_len++;
+        } else {
+            cpu->cpreg_array_len++;
+        }
     }
 }
 
@@ -320,9 +376,10 @@ void init_cpreg_list(ARMCPU *cpu)
      * Initialise the cpreg_tuples[] array based on the cp_regs hash.
      * Note that we require cpreg_tuples[] to be sorted by key ID.
      */
-    int arraylen;
+    int arraylen, array128len;
 
     cpu->cpreg_array_len = 0;
+    cpu->cpreg128_array_len = 0;
     g_hash_table_foreach(cpu->cp_regs, count_cpreg, cpu);
 
     arraylen = cpu->cpreg_array_len;
@@ -340,13 +397,33 @@ void init_cpreg_list(ARMCPU *cpu)
     cpu->cpreg_vmstate_array_len = arraylen;
     cpu->cpreg_array_len = 0;
 
+    array128len = cpu->cpreg128_array_len;
+    if (array128len) {
+        cpu->cpreg128_indexes = g_new(uint64_t, array128len);
+        cpu->cpreg128_values = g_new(Int128, array128len);
+        cpu->cpreg128_vmstate_indexes = g_new(uint64_t, array128len);
+        cpu->cpreg128_vmstate_values = g_new(Int128, array128len);
+    } else {
+        cpu->cpreg128_indexes = NULL;
+        cpu->cpreg128_values = NULL;
+        cpu->cpreg128_vmstate_indexes = NULL;
+        cpu->cpreg128_vmstate_values = NULL;
+    }
+    cpu->cpreg128_vmstate_array_len = array128len;
+    cpu->cpreg128_array_len = 0;
+
     g_hash_table_foreach(cpu->cp_regs, add_cpreg_to_list, cpu);
 
     assert(cpu->cpreg_array_len == arraylen);
+    assert(cpu->cpreg128_array_len == array128len);
 
     if (arraylen) {
         qsort(cpu->cpreg_indexes, arraylen, sizeof(uint64_t), compare_u64);
     }
+    if (array128len) {
+        qsort(cpu->cpreg128_indexes, array128len,
+              sizeof(uint64_t), compare_u64);
+    }
 }
 
 bool arm_pan_enabled(CPUARMState *env)
-- 
2.43.0



  parent reply	other threads:[~2025-10-14 20:20 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-14 20:06 [PATCH v2 00/37] target/arm: Implement FEAT_SYSREG128 Richard Henderson
2025-10-14 20:06 ` [PATCH v2 01/37] target/arm: Implement isar tests for FEAT_SYSREG128, FEAT_SYSINSTR128 Richard Henderson
2025-10-17 12:34   ` Peter Maydell
2025-10-14 20:06 ` [PATCH v2 02/37] target/arm: Define CP_REG_SIZE_U128 Richard Henderson
2025-10-17 12:37   ` Peter Maydell
2025-10-14 20:06 ` [PATCH v2 03/37] target/arm: Update ARMCPRegInfo for 128-bit sysregs Richard Henderson
2025-10-17 12:56   ` Peter Maydell
2025-10-14 20:06 ` [PATCH v2 04/37] target/arm: Asserts for ARM_CP_128BIT in define_one_arm_cp_reg Richard Henderson
2025-10-17 12:59   ` Peter Maydell
2025-10-17 15:01     ` Richard Henderson
2025-10-14 20:06 ` [PATCH v2 05/37] target/arm: Split add_cpreg_to_hashtable_aa64 Richard Henderson
2025-10-17 13:05   ` Peter Maydell
2025-10-14 20:06 ` [PATCH v2 06/37] target/arm: Add raw_read128, raw_write128 Richard Henderson
2025-10-17 13:07   ` Peter Maydell
2025-10-14 20:06 ` [PATCH v2 07/37] target/arm: Add read_raw_cp_reg128, write_raw_cp_reg128 Richard Henderson
2025-10-17 13:11   ` Peter Maydell
2025-10-17 15:04     ` Richard Henderson
2025-10-20 13:23   ` Peter Maydell
2025-10-14 20:06 ` [PATCH v2 08/37] target/arm: Use cpreg_field_type in arm_gen_one_feature_sysreg Richard Henderson
2025-10-17 13:14   ` Peter Maydell
2025-10-14 20:06 ` [PATCH v2 09/37] target/arm: Merge arm_gen_one_feature_sysreg into the single caller Richard Henderson
2025-10-17 13:16   ` Peter Maydell
2025-10-14 20:06 ` [PATCH v2 10/37] target/arm: Handle MO_128 in arm_gdb_get_sysreg Richard Henderson
2025-10-17 13:18   ` Peter Maydell
2025-10-14 20:06 ` [PATCH v2 11/37] target/arm: Handle ARM_CP_128BIT in cpu reset Richard Henderson
2025-10-17 13:34   ` Peter Maydell
2025-10-14 20:06 ` Richard Henderson [this message]
2025-10-20 12:34   ` [PATCH v2 12/37] target/arm: Put 128-bit sysregs into a separate list Peter Maydell
2025-10-14 20:06 ` [PATCH v2 13/37] target/arm/kvm: Assert no 128-bit sysregs in kvm_arm_init_cpreg_list Richard Henderson
2025-10-20 12:34   ` Peter Maydell
2025-10-14 20:06 ` [PATCH v2 14/37] target/arm/hvf: Assert no 128-bit sysregs in hvf_arch_init_vcpu Richard Henderson
2025-10-20 12:35   ` Peter Maydell
2025-10-14 20:06 ` [PATCH v2 15/37] migration: Add vmstate_info_int128 Richard Henderson
2025-10-20 12:41   ` Peter Maydell
2025-10-14 20:06 ` [PATCH v2 16/37] target/arm: Migrate cpreg128 registers Richard Henderson
2025-10-20 12:44   ` Peter Maydell
2025-10-14 20:06 ` [PATCH v2 17/37] target/arm: Add syn_aa64_sysreg128trap Richard Henderson
2025-10-20 12:45   ` Peter Maydell
2025-10-14 20:06 ` [PATCH v2 18/37] target/arm: Introduce helper_{get,set}_cp_reg128 Richard Henderson
2025-10-20 12:49   ` [PATCH v2 18/37] target/arm: Introduce helper_{get, set}_cp_reg128 Peter Maydell
2025-10-14 20:07 ` [PATCH v2 19/37] target/arm: Implement MRRS, MSRR, SYSP Richard Henderson
2025-10-20 13:15   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 20/37] target/arm: Consolidate definitions of PAR Richard Henderson
2025-10-20 13:31   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 21/37] target/arm: Extend PAR_EL1 to 128-bit Richard Henderson
2025-10-17 12:49   ` Peter Maydell
2025-10-17 19:03     ` Richard Henderson
2025-10-14 20:07 ` [PATCH v2 22/37] target/arm: Consolidate definitions of TTBR[01] Richard Henderson
2025-10-20 14:00   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 23/37] target/arm: Split out flush_if_asid_change Richard Henderson
2025-10-20 14:02   ` Peter Maydell
2025-10-20 14:12   ` Philippe Mathieu-Daudé
2025-10-14 20:07 ` [PATCH v2 24/37] target/arm: Use flush_if_asid_change in vmsa_ttbr_write Richard Henderson
2025-10-20 14:08   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 25/37] target/arm: Extend TTBR system registers to 128-bit Richard Henderson
2025-10-20 14:14   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 26/37] target/arm: Implement TLBIP IPAS2E1, IPAS2LE1 Richard Henderson
2025-10-20 14:34   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 27/37] target/arm: Implement TLBIP IPAS2E1IS, IPAS2LE1IS Richard Henderson
2025-10-20 14:35   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 28/37] target/arm: Implement TLBIP RVAE1, RVAAE1, RVALE1, RVAALE1 Richard Henderson
2025-10-20 14:48   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 29/37] target/arm: Implement TLBIP RIPAS1E1, RIPAS1LE1, RIPAS2E1IS, RIPAS2LE1IS Richard Henderson
2025-10-20 14:49   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 30/37] target/arm: Implement TLBIP RVA{L}E2{IS,OS} Richard Henderson
2025-10-20 14:50   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 31/37] target/arm: Implement TLBIP RVA{L}E3{IS,OS} Richard Henderson
2025-10-20 14:50   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 32/37] target/arm: Implement TLBIP VA{L}E1{IS,OS} Richard Henderson
2025-10-20 14:52   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 33/37] target/arm: Implement TLBIP VAE2, VALE2 Richard Henderson
2025-10-20 14:52   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 34/37] target/arm: Implement TLBIP VAE3, VALE3 Richard Henderson
2025-10-20 14:52   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 35/37] target/arm: Implement TLBIP VA{L}E2{IS,OS} Richard Henderson
2025-10-20 14:53   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 36/37] target/arm: Implement TLBIP VA{L}E3{IS,OS} Richard Henderson
2025-10-20 14:53   ` Peter Maydell
2025-10-14 20:07 ` [PATCH v2 37/37] NOTFORMERGE: Enable FEAT_SYSREG128, FEAT_SYSINSTR128 for cpu max Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251014200718.422022-13-richard.henderson@linaro.org \
    --to=richard.henderson@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).