* [PATCH RFCv2 01/20] kvm: kvm_get_writable_id_regs
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
@ 2024-12-06 11:21 ` Cornelia Huck
2024-12-12 13:59 ` Richard Henderson
2024-12-06 11:21 ` [PATCH RFCv2 02/20] arm/cpu: Add sysreg definitions in cpu-sysregs.h Cornelia Huck
` (22 subsequent siblings)
23 siblings, 1 reply; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:21 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
Add an helper to retrieve the writable id reg bitmask. The
status of the query is stored in the CPU struct so that an
an error, if any, can be reported on vcpu realize().
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
target/arm/cpu.h | 19 +++++++++++++++++++
target/arm/kvm.c | 32 ++++++++++++++++++++++++++++++++
target/arm/kvm_arm.h | 7 +++++++
3 files changed, 58 insertions(+)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index d86e641280d4..e359152a4dbc 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -828,6 +828,19 @@ typedef struct {
uint32_t map, init, supported;
} ARMVQMap;
+typedef enum ARMIdRegsState {
+ WRITABLE_ID_REGS_UNKNOWN,
+ WRITABLE_ID_REGS_NOT_DISCOVERABLE,
+ WRITABLE_ID_REGS_FAILED,
+ WRITABLE_ID_REGS_AVAIL,
+} ARMIdRegsState;
+
+#define NR_ID_REGS (3 * 8 * 8)
+
+typedef struct IdRegMap {
+ uint64_t regs[NR_ID_REGS];
+} IdRegMap;
+
/**
* ARMCPU:
* @env: #CPUARMState
@@ -969,6 +982,12 @@ struct ArchCPU {
*/
bool host_cpu_probe_failed;
+ /*
+ * state of writable id regs query used to report an error, if any,
+ * on KVM custom vcpu model realize
+ */
+ ARMIdRegsState writable_id_regs;
+
/* QOM property to indicate we should use the back-compat CNTFRQ default */
bool backcompat_cntfrq;
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 7b6812c0de2e..8577d6f520ba 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -49,6 +49,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
static bool cap_has_mp_state;
static bool cap_has_inject_serror_esr;
static bool cap_has_inject_ext_dabt;
+static int cap_writable_id_regs;
/**
* ARMHostCPUFeatures: information about the host CPU (identified
@@ -495,6 +496,37 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
env->features = arm_host_cpu_features.features;
}
+int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap)
+{
+ struct reg_mask_range range = {
+ .range = 0, /* up to now only a single range is supported */
+ .addr = (uint64_t)idregmap,
+ };
+ int ret;
+
+ if (!kvm_enabled()) {
+ cpu->writable_id_regs = WRITABLE_ID_REGS_NOT_DISCOVERABLE;
+ return -ENOSYS;
+ }
+
+ cap_writable_id_regs =
+ kvm_check_extension(kvm_state, KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES);
+
+ if (!cap_writable_id_regs ||
+ !(cap_writable_id_regs & (1 << KVM_ARM_FEATURE_ID_RANGE))) {
+ cpu->writable_id_regs = WRITABLE_ID_REGS_NOT_DISCOVERABLE;
+ return -ENOSYS;
+ }
+
+ ret = kvm_vm_ioctl(kvm_state, KVM_ARM_GET_REG_WRITABLE_MASKS, &range);
+ if (ret) {
+ cpu->writable_id_regs = WRITABLE_ID_REGS_FAILED;
+ return ret;
+ }
+ cpu->writable_id_regs = WRITABLE_ID_REGS_AVAIL;
+ return ret;
+}
+
static bool kvm_no_adjvtime_get(Object *obj, Error **errp)
{
return !ARM_CPU(obj)->kvm_adjvtime;
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 2e6b49bf1376..426816ad3a74 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -221,6 +221,8 @@ int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level);
void kvm_arm_enable_mte(Object *cpuobj, Error **errp);
+int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap);
+
#else
/*
@@ -247,6 +249,11 @@ static inline bool kvm_arm_mte_supported(void)
return false;
}
+static inline int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap)
+{
+ return -ENOSYS;
+}
+
/*
* These functions should never actually be called without KVM support.
*/
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* Re: [PATCH RFCv2 01/20] kvm: kvm_get_writable_id_regs
2024-12-06 11:21 ` [PATCH RFCv2 01/20] kvm: kvm_get_writable_id_regs Cornelia Huck
@ 2024-12-12 13:59 ` Richard Henderson
2024-12-12 14:12 ` Eric Auger
0 siblings, 1 reply; 56+ messages in thread
From: Richard Henderson @ 2024-12-12 13:59 UTC (permalink / raw)
To: Cornelia Huck, eric.auger.pro, eric.auger, qemu-devel, qemu-arm,
kvmarm
On 12/6/24 05:21, Cornelia Huck wrote:
> +#define NR_ID_REGS (3 * 8 * 8)
> +
> +typedef struct IdRegMap {
> + uint64_t regs[NR_ID_REGS];
> +} IdRegMap;
> +
Where does the NR_ID_REGS come from? In particular the * 3?
IIRC, all of the id registers are in op0=3, op1=0, crn=0, crm={0-7}, op2={0-7}.
Whatever the actual answer, some comments would be good.
r~
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH RFCv2 01/20] kvm: kvm_get_writable_id_regs
2024-12-12 13:59 ` Richard Henderson
@ 2024-12-12 14:12 ` Eric Auger
2024-12-13 15:43 ` Cornelia Huck
0 siblings, 1 reply; 56+ messages in thread
From: Eric Auger @ 2024-12-12 14:12 UTC (permalink / raw)
To: Richard Henderson, Cornelia Huck, eric.auger.pro, qemu-devel,
qemu-arm, kvmarm
Hi Richard,
On 12/12/24 14:59, Richard Henderson wrote:
> On 12/6/24 05:21, Cornelia Huck wrote:
>> +#define NR_ID_REGS (3 * 8 * 8)
>> +
>> +typedef struct IdRegMap {
>> + uint64_t regs[NR_ID_REGS];
>> +} IdRegMap;
>> +
>
> Where does the NR_ID_REGS come from? In particular the * 3?
> IIRC, all of the id registers are in op0=3, op1=0, crn=0, crm={0-7},
> op2={0-7}.
According to the KVM API and code,
"The Feature ID space is defined as the AArch64 System register space
with +op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}."
hence that choice
See:
https://lore.kernel.org/all/20230919175017.538312-3-jingzhangos@google.com/
Definitively we can add a comment
Thanks
Eric
>
> Whatever the actual answer, some comments would be good.
>
>
> r~
>
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH RFCv2 01/20] kvm: kvm_get_writable_id_regs
2024-12-12 14:12 ` Eric Auger
@ 2024-12-13 15:43 ` Cornelia Huck
0 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-13 15:43 UTC (permalink / raw)
To: eric.auger, Richard Henderson, eric.auger.pro, qemu-devel,
qemu-arm, kvmarm
On Thu, Dec 12 2024, Eric Auger <eric.auger@redhat.com> wrote:
> Hi Richard,
>
> On 12/12/24 14:59, Richard Henderson wrote:
>> On 12/6/24 05:21, Cornelia Huck wrote:
>>> +#define NR_ID_REGS (3 * 8 * 8)
>>> +
>>> +typedef struct IdRegMap {
>>> + uint64_t regs[NR_ID_REGS];
>>> +} IdRegMap;
>>> +
>>
>> Where does the NR_ID_REGS come from? In particular the * 3?
>> IIRC, all of the id registers are in op0=3, op1=0, crn=0, crm={0-7},
>> op2={0-7}.
>
> According to the KVM API and code,
>
> "The Feature ID space is defined as the AArch64 System register space
> with +op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}."
>
>
> hence that choice
>
> See:
> https://lore.kernel.org/all/20230919175017.538312-3-jingzhangos@google.com/
>
> Definitively we can add a comment
I've added
/*
* ID registers in op0==3, op1=={0,1,3}, crn=0, crm=={0-7}, op2=={0-7},
* as used by the KVM_ARM_GET_REG_WRITABLE_MASKS ioctl call.
*/
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH RFCv2 02/20] arm/cpu: Add sysreg definitions in cpu-sysregs.h
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
2024-12-06 11:21 ` [PATCH RFCv2 01/20] kvm: kvm_get_writable_id_regs Cornelia Huck
@ 2024-12-06 11:21 ` Cornelia Huck
2024-12-12 14:37 ` Richard Henderson
2024-12-06 11:21 ` [PATCH RFCv2 03/20] arm/cpu: Store aa64isar0 into the idregs arrays Cornelia Huck
` (21 subsequent siblings)
23 siblings, 1 reply; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:21 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
This new header contains macros that define aarch64 registers.
In a subsequent patch, this will be replaced by a more exhaustive
version that will be generated from linux arch/arm64/tools/sysreg
file. Those macros are sufficient to migrate the storage of those
ID regs from named fields in isar struct to an array cell.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
target/arm/cpu-sysregs.h | 42 +++++++++++++++++++++++++++++++
target/arm/cpu.h | 54 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 96 insertions(+)
create mode 100644 target/arm/cpu-sysregs.h
diff --git a/target/arm/cpu-sysregs.h b/target/arm/cpu-sysregs.h
new file mode 100644
index 000000000000..f4b63a3af77b
--- /dev/null
+++ b/target/arm/cpu-sysregs.h
@@ -0,0 +1,42 @@
+#ifndef ARM_CPU_SYSREGS_H
+#define ARM_CPU_SYSREGS_H
+
+/* to be generated */
+
+#define SYS_ID_AA64PFR0_EL1 sys_reg(3, 0, 0, 4, 0)
+#define SYS_ID_AA64PFR1_EL1 sys_reg(3, 0, 0, 4, 1)
+#define SYS_ID_AA64SMFR0_EL1 sys_reg(3, 0, 0, 4, 5)
+#define SYS_ID_AA64DFR0_EL1 sys_reg(3, 0, 0, 5, 0)
+#define SYS_ID_AA64DFR1_EL1 sys_reg(3, 0, 0, 5, 1)
+#define SYS_ID_AA64ISAR0_EL1 sys_reg(3, 0, 0, 6, 0)
+#define SYS_ID_AA64ISAR1_EL1 sys_reg(3, 0, 0, 6, 1)
+#define SYS_ID_AA64ISAR2_EL1 sys_reg(3, 0, 0, 6, 2)
+#define SYS_ID_AA64MMFR0_EL1 sys_reg(3, 0, 0, 7, 0)
+#define SYS_ID_AA64MMFR1_EL1 sys_reg(3, 0, 0, 7, 1)
+#define SYS_ID_AA64MMFR2_EL1 sys_reg(3, 0, 0, 7, 2)
+#define SYS_ID_AA64MMFR3_EL1 sys_reg(3, 0, 0, 7, 3)
+
+#define SYS_ID_PFR0_EL1 sys_reg(3, 0, 0, 1, 0)
+#define SYS_ID_PFR1_EL1 sys_reg(3, 0, 0, 1, 1)
+#define SYS_ID_DFR0_EL1 sys_reg(3, 0, 0, 1, 2)
+#define SYS_ID_MMFR0_EL1 sys_reg(3, 0, 0, 1, 4)
+#define SYS_ID_MMFR1_EL1 sys_reg(3, 0, 0, 1, 5)
+#define SYS_ID_MMFR2_EL1 sys_reg(3, 0, 0, 1, 6)
+#define SYS_ID_MMFR3_EL1 sys_reg(3, 0, 0, 1, 7)
+#define SYS_ID_ISAR0_EL1 sys_reg(3, 0, 0, 2, 0)
+#define SYS_ID_ISAR1_EL1 sys_reg(3, 0, 0, 2, 1)
+#define SYS_ID_ISAR2_EL1 sys_reg(3, 0, 0, 2, 2)
+#define SYS_ID_ISAR3_EL1 sys_reg(3, 0, 0, 2, 3)
+#define SYS_ID_ISAR4_EL1 sys_reg(3, 0, 0, 2, 4)
+#define SYS_ID_ISAR5_EL1 sys_reg(3, 0, 0, 2, 5)
+#define SYS_ID_MMFR4_EL1 sys_reg(3, 0, 0, 2, 6)
+#define SYS_ID_ISAR6_EL1 sys_reg(3, 0, 0, 2, 7)
+#define SYS_MVFR0_EL1 sys_reg(3, 0, 0, 3, 0)
+#define SYS_MVFR1_EL1 sys_reg(3, 0, 0, 3, 1)
+#define SYS_MVFR2_EL1 sys_reg(3, 0, 0, 3, 2)
+#define SYS_ID_PFR2_EL1 sys_reg(3, 0, 0, 3, 4)
+#define SYS_ID_DFR1_EL1 sys_reg(3, 0, 0, 3, 5)
+#define SYS_ID_MMFR5_EL1 sys_reg(3, 0, 0, 3, 6)
+#define SYS_ID_AA64ZFR0_EL1 sys_reg(3, 0, 0, 4, 4)
+
+#endif
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e359152a4dbc..9e0403c9810a 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -144,6 +144,14 @@ typedef struct ARMGenericTimer {
uint64_t ctl; /* Timer Control register */
} ARMGenericTimer;
+typedef struct ARMSysReg {
+ int op0;
+ int op1;
+ int crn;
+ int crm;
+ int op2;
+} ARMSysReg;
+
/* Define a maximum sized vector register.
* For 32-bit, this is a 128-bit NEON/AdvSIMD register.
* For 64-bit, this is a 2048-bit SVE register.
@@ -841,6 +849,51 @@ typedef struct IdRegMap {
uint64_t regs[NR_ID_REGS];
} IdRegMap;
+#define ARM_FEATURE_ID_RANGE_IDX(op0, op1, crn, crm, op2) \
+ ({ \
+ __u64 __op1 = (op1) & 3; \
+ __op1 -= (__op1 == 3); \
+ (__op1 << 6 | ((crm) & 7) << 3 | (op2)); \
+ })
+
+static inline uint64_t _get_idreg(const IdRegMap *map, ARMSysReg sr)
+{
+ int index = ARM_FEATURE_ID_RANGE_IDX(sr.op0, sr.op1, sr.crn, sr.crm, sr.op2);
+
+ return map->regs[index];
+}
+
+static inline void _set_idreg(IdRegMap *map, ARMSysReg sr, uint64_t value)
+{
+ int index = ARM_FEATURE_ID_RANGE_IDX(sr.op0, sr.op1, sr.crn, sr.crm, sr.op2);
+
+ map->regs[index] = value;
+}
+
+/* REG is ID_XXX */
+#define FIELD_DP64_IDREG(MAP, REG, FIELD, VALUE) \
+{ \
+uint64_t regval = _get_idreg(MAP, SYS_ ## REG ## _EL1); \
+regval = FIELD_DP64(regval, REG, FIELD, VALUE); \
+_set_idreg(MAP, SYS_ ## REG ## _EL1, regval); \
+}
+
+#define FIELD_EX64_IDREG(MAP, REG, FIELD) \
+FIELD_EX64(_get_idreg(MAP, SYS_ ## REG ## _EL1), REG, FIELD) \
+
+#define SET_IDREG(MAP, REG, VALUE) \
+_set_idreg(MAP, SYS_ ## REG ## _EL1, VALUE)
+
+#define GET_IDREG(MAP, REG) \
+_get_idreg(MAP, SYS_ ## REG ## _EL1)
+
+static inline ARMSysReg sys_reg(int op0, int op1, int crn, int crm, int op2)
+{
+ ARMSysReg sr = {op0, op1, crn, crm, op2};
+
+ return sr;
+}
+
/**
* ARMCPU:
* @env: #CPUARMState
@@ -1052,6 +1105,7 @@ struct ArchCPU {
uint64_t id_aa64zfr0;
uint64_t id_aa64smfr0;
uint64_t reset_pmcr_el0;
+ IdRegMap idregs;
} isar;
uint64_t midr;
uint32_t revidr;
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* Re: [PATCH RFCv2 02/20] arm/cpu: Add sysreg definitions in cpu-sysregs.h
2024-12-06 11:21 ` [PATCH RFCv2 02/20] arm/cpu: Add sysreg definitions in cpu-sysregs.h Cornelia Huck
@ 2024-12-12 14:37 ` Richard Henderson
2024-12-12 17:46 ` Eric Auger
0 siblings, 1 reply; 56+ messages in thread
From: Richard Henderson @ 2024-12-12 14:37 UTC (permalink / raw)
To: Cornelia Huck, eric.auger.pro, eric.auger, qemu-devel, qemu-arm,
kvmarm, peter.maydell, alex.bennee, maz, oliver.upton, sebott,
shameerali.kolothum.thodi, armbru, berrange, abologna, jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini
On 12/6/24 05:21, Cornelia Huck wrote:
> +#define SYS_ID_AA64PFR0_EL1 sys_reg(3, 0, 0, 4, 0)
...
> +typedef struct ARMSysReg {
> + int op0;
> + int op1;
> + int crn;
> + int crm;
> + int op2;
> +} ARMSysReg;
...
> +static inline ARMSysReg sys_reg(int op0, int op1, int crn, int crm, int op2)
> +{
> + ARMSysReg sr = {op0, op1, crn, crm, op2};
> +
> + return sr;
> +}
Not a fan. Why take 20 bytes to represent these?
Our existing ENCODE_CP_REG and ENCODE_AA64_CP_REG macros seem much better, even if the
argument ordering doesn't match the column ordering in Table D22-2.
> @@ -841,6 +849,51 @@ typedef struct IdRegMap {
> uint64_t regs[NR_ID_REGS];
> } IdRegMap;
>
> +#define ARM_FEATURE_ID_RANGE_IDX(op0, op1, crn, crm, op2) \
> + ({ \
> + __u64 __op1 = (op1) & 3; \
> + __op1 -= (__op1 == 3); \
> + (__op1 << 6 | ((crm) & 7) << 3 | (op2)); \
> + })
Ah, well, this answers my question re patch 1.
It seems a shame to use 128 slots to represent all 9 id registers in the op1={1,3} space.
Do we really need anything beyond the defined registers, or even the defined registers for
which qemu knows how to do anything?
I'm certainly happy to replace ARMISARegisters fields with an array, but more like
enum ARMIDRegisterIdx {
ID_AA64ISAR0_IDX,
etc
ordering arbitrary, either machine or macro generated,
but every register has a symbolic index.
NUM_ID_IDX,
};
enum ARMSysregs {
SYS_ID_AA64PFR0_EL1 = ENCODE_AA64_CP_REG(...),
etc
};
const uint32_t id_register_sysreg[NUM_ID_IDX] = {
[ID_AA64ISAR0_IDX] = SYS_ID_AA64PFR0_EL1,
etc
};
struct ARMISARegisters {
uint64_t id[NUM_ID_IDX];
};
This seems trivial to automate, and wastes no space.
r~
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH RFCv2 02/20] arm/cpu: Add sysreg definitions in cpu-sysregs.h
2024-12-12 14:37 ` Richard Henderson
@ 2024-12-12 17:46 ` Eric Auger
2024-12-12 18:12 ` Richard Henderson
0 siblings, 1 reply; 56+ messages in thread
From: Eric Auger @ 2024-12-12 17:46 UTC (permalink / raw)
To: Richard Henderson, Cornelia Huck, eric.auger.pro, qemu-devel,
qemu-arm, kvmarm, peter.maydell, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini
Hi Richard,
On 12/12/24 15:37, Richard Henderson wrote:
> On 12/6/24 05:21, Cornelia Huck wrote:
>> +#define SYS_ID_AA64PFR0_EL1 sys_reg(3,
>> 0, 0, 4, 0)
> ...
>> +typedef struct ARMSysReg {
>> + int op0;
>> + int op1;
>> + int crn;
>> + int crm;
>> + int op2;
>> +} ARMSysReg;
> ...
>> +static inline ARMSysReg sys_reg(int op0, int op1, int crn, int crm,
>> int op2)
>> +{
>> + ARMSysReg sr = {op0, op1, crn, crm, op2};
>> +
>> + return sr;
>> +}
>
> Not a fan. Why take 20 bytes to represent these?
sure we can optimize it
>
> Our existing ENCODE_CP_REG and ENCODE_AA64_CP_REG macros seem much
> better, even if the argument ordering doesn't match the column
> ordering in Table D22-2.
>
>> @@ -841,6 +849,51 @@ typedef struct IdRegMap {
>> uint64_t regs[NR_ID_REGS];
>> } IdRegMap;
>> +#define ARM_FEATURE_ID_RANGE_IDX(op0, op1, crn, crm,
>> op2) \
>> +
>> ({ \
>> + __u64 __op1 = (op1) &
>> 3; \
>> + __op1 -= (__op1 ==
>> 3); \
>> + (__op1 << 6 | ((crm) & 7) << 3 |
>> (op2)); \
>> + })
>
> Ah, well, this answers my question re patch 1.
>
> It seems a shame to use 128 slots to represent all 9 id registers in
> the op1={1,3} space.
wouldn't it make sense to use a hashtable then as we don't have
consecutive indexes?
>
> Do we really need anything beyond the defined registers, or even the
> defined registers for which qemu knows how to do anything?
what do you mean by "defined registers". The end goal is to be able to
tune any id reg that the kernel allows to write. So I guess we shall
encompass more regs than qemu currently handles.
Wrt op1={1,3}, tbh I initially sticked to the KVM API. Now looking at
D22-2, effectively we have very few ID regs there. If we were to use a
hashtable we may be more flexible in picking up the indexes that are
relevant for us.
>
> I'm certainly happy to replace ARMISARegisters fields with an array,
> but more like
>
> enum ARMIDRegisterIdx {
> ID_AA64ISAR0_IDX,
> etc
> ordering arbitrary, either machine or macro generated,
> but every register has a symbolic index.
> NUM_ID_IDX,
> };
>
> enum ARMSysregs {
> SYS_ID_AA64PFR0_EL1 = ENCODE_AA64_CP_REG(...),
> etc
> };
>
> const uint32_t id_register_sysreg[NUM_ID_IDX] = {
> [ID_AA64ISAR0_IDX] = SYS_ID_AA64PFR0_EL1,
> etc
> };
>
> struct ARMISARegisters {
> uint64_t id[NUM_ID_IDX];
> };
>
> This seems trivial to automate, and wastes no space.
Sure we will study such rework. As long as the key (ID_AA64ISAR0_IDX)
can be matched against the index used by the KVM API we should be fine.
Thanks
Eric
>
>
> r~
>
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH RFCv2 02/20] arm/cpu: Add sysreg definitions in cpu-sysregs.h
2024-12-12 17:46 ` Eric Auger
@ 2024-12-12 18:12 ` Richard Henderson
2024-12-13 16:16 ` Cornelia Huck
0 siblings, 1 reply; 56+ messages in thread
From: Richard Henderson @ 2024-12-12 18:12 UTC (permalink / raw)
To: eric.auger, Cornelia Huck, eric.auger.pro, qemu-devel, qemu-arm,
kvmarm, peter.maydell, alex.bennee, maz, oliver.upton, sebott,
shameerali.kolothum.thodi, armbru, berrange, abologna, jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini
On 12/12/24 11:46, Eric Auger wrote:
>> Do we really need anything beyond the defined registers, or even the
>> defined registers for which qemu knows how to do anything?
> what do you mean by "defined registers". The end goal is to be able to
> tune any id reg that the kernel allows to write. So I guess we shall
> encompass more regs than qemu currently handles.
Defined registers as in "have an architected definition".
E.g. there's no need to set any fields in (op0=0 op1=0 crn=0, crm=0, op2=1), because that
isn't a defined system register. It's in id register space sure, and almost certainly
RAZ, but there's no call to either set it or represent it within qemu.
Because you're working to a a symbolic command-line interface, with FEAT_FOO, ID_REG.FIELD
names, qemu will (be extended to) handle every register named.
> Wrt op1={1,3}, tbh I initially sticked to the KVM API. Now looking at
> D22-2, effectively we have very few ID regs there. If we were to use a
> hashtable we may be more flexible in picking up the indexes that are
> relevant for us.
Yes. And I'm suggesting the "hashtable" be defined by compile-time constants.
>> const uint32_t id_register_sysreg[NUM_ID_IDX] = {
>> [ID_AA64ISAR0_IDX] = SYS_ID_AA64PFR0_EL1,
>> etc
>> };
>>
>> struct ARMISARegisters {
>> uint64_t id[NUM_ID_IDX];
>> };
>>
>> This seems trivial to automate, and wastes no space.
>
> Sure we will study such rework. As long as the key (ID_AA64ISAR0_IDX)
> can be matched against the index used by the KVM API we should be fine.
I haven't looked to see what KVM_ARM_GET_REG_WRITABLE_MASKS really returns, but I see no
reason that it should not be trivial to map back and forth between the spaces.
r~
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH RFCv2 02/20] arm/cpu: Add sysreg definitions in cpu-sysregs.h
2024-12-12 18:12 ` Richard Henderson
@ 2024-12-13 16:16 ` Cornelia Huck
0 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-13 16:16 UTC (permalink / raw)
To: Richard Henderson, eric.auger, eric.auger.pro, qemu-devel,
qemu-arm, kvmarm, peter.maydell, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini
On Thu, Dec 12 2024, Richard Henderson <richard.henderson@linaro.org> wrote:
> On 12/12/24 11:46, Eric Auger wrote:
>>> Do we really need anything beyond the defined registers, or even the
>>> defined registers for which qemu knows how to do anything?
>> what do you mean by "defined registers". The end goal is to be able to
>> tune any id reg that the kernel allows to write. So I guess we shall
>> encompass more regs than qemu currently handles.
>
> Defined registers as in "have an architected definition".
>
> E.g. there's no need to set any fields in (op0=0 op1=0 crn=0, crm=0, op2=1), because that
> isn't a defined system register. It's in id register space sure, and almost certainly
> RAZ, but there's no call to either set it or represent it within qemu.
>
> Because you're working to a a symbolic command-line interface, with FEAT_FOO, ID_REG.FIELD
> names, qemu will (be extended to) handle every register named.
Going from the definitions, we have the potential to generate props for
anything that has been named (do we have named registers/fields that are not
architected?) Exposed on the command line are only those register fields
that are actually writable with the current KVM interface (see patch 18.)
I'm still not quite sure how to continue with FEAT_FOO, but I guess
we're still going to need the ID_REG.FIELD names in any case to handle
differences like DIC in CTR_EL0 mentioned elsewhere in this thread.
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH RFCv2 03/20] arm/cpu: Store aa64isar0 into the idregs arrays
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
2024-12-06 11:21 ` [PATCH RFCv2 01/20] kvm: kvm_get_writable_id_regs Cornelia Huck
2024-12-06 11:21 ` [PATCH RFCv2 02/20] arm/cpu: Add sysreg definitions in cpu-sysregs.h Cornelia Huck
@ 2024-12-06 11:21 ` Cornelia Huck
2024-12-06 11:21 ` [PATCH RFCv2 04/20] arm/cpu: Store aa64isar1/2 into the idregs array Cornelia Huck
` (20 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:21 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
target/arm/cpu-features.h | 57 ++++++++++++++++++++-------------------
target/arm/cpu.c | 14 ++++------
target/arm/cpu.h | 2 --
target/arm/cpu64.c | 8 +++---
target/arm/helper.c | 6 +++--
target/arm/kvm.c | 20 +++++++++++---
target/arm/tcg/cpu64.c | 44 ++++++++++++++++++------------
7 files changed, 86 insertions(+), 65 deletions(-)
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index e806f138b8f1..f92372bdd8d2 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -22,6 +22,7 @@
#include "hw/registerfields.h"
#include "qemu/host-utils.h"
+#include "cpu-sysregs.h"
/*
* Naming convention for isar_feature functions:
@@ -376,92 +377,92 @@ static inline bool isar_feature_aa32_doublelock(const ARMISARegisters *id)
*/
static inline bool isar_feature_aa64_aes(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, AES) != 0;
}
static inline bool isar_feature_aa64_pmull(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) > 1;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, AES) > 1;
}
static inline bool isar_feature_aa64_sha1(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA1) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, SHA1) != 0;
}
static inline bool isar_feature_aa64_sha256(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, SHA2) != 0;
}
static inline bool isar_feature_aa64_sha512(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) > 1;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, SHA2) > 1;
}
static inline bool isar_feature_aa64_crc32(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, CRC32) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, CRC32) != 0;
}
static inline bool isar_feature_aa64_atomics(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, ATOMIC) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, ATOMIC) != 0;
}
static inline bool isar_feature_aa64_rdm(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RDM) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, RDM) != 0;
}
static inline bool isar_feature_aa64_sha3(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA3) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, SHA3) != 0;
}
static inline bool isar_feature_aa64_sm3(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM3) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, SM3) != 0;
}
static inline bool isar_feature_aa64_sm4(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM4) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, SM4) != 0;
}
static inline bool isar_feature_aa64_dp(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, DP) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, DP) != 0;
}
static inline bool isar_feature_aa64_fhm(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, FHM) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, FHM) != 0;
}
static inline bool isar_feature_aa64_condm_4(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, TS) != 0;
}
static inline bool isar_feature_aa64_condm_5(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) >= 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, TS) >= 2;
}
static inline bool isar_feature_aa64_rndr(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RNDR) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, RNDR) != 0;
}
static inline bool isar_feature_aa64_tlbirange(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) == 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, TLB) == 2;
}
static inline bool isar_feature_aa64_tlbios(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR0, TLB) != 0;
}
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
@@ -912,52 +913,52 @@ static inline bool isar_feature_aa64_doublelock(const ARMISARegisters *id)
static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SVEVER) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ZFR0, SVEVER) != 0;
}
static inline bool isar_feature_aa64_sve2_aes(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, AES) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ZFR0, AES) != 0;
}
static inline bool isar_feature_aa64_sve2_pmull128(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, AES) >= 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ZFR0, AES) >= 2;
}
static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BITPERM) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ZFR0, BITPERM) != 0;
}
static inline bool isar_feature_aa64_sve_bf16(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BFLOAT16) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ZFR0, BFLOAT16) != 0;
}
static inline bool isar_feature_aa64_sve2_sha3(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SHA3) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ZFR0, SHA3) != 0;
}
static inline bool isar_feature_aa64_sve2_sm4(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SM4) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ZFR0, SM4) != 0;
}
static inline bool isar_feature_aa64_sve_i8mm(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, I8MM) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ZFR0, I8MM) != 0;
}
static inline bool isar_feature_aa64_sve_f32mm(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F32MM) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ZFR0, F32MM) != 0;
}
static inline bool isar_feature_aa64_sve_f64mm(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F64MM) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ZFR0, F64MM) != 0;
}
static inline bool isar_feature_aa64_sme_f64f64(const ARMISARegisters *id)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 6938161b9541..4f06dd516d1b 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1976,6 +1976,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
ARMCPU *cpu = ARM_CPU(dev);
+ IdRegMap *idregs = &cpu->isar.idregs;
ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev);
CPUARMState *env = &cpu->env;
Error *local_err = NULL;
@@ -2177,7 +2178,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
unset_feature(env, ARM_FEATURE_NEON);
- t = cpu->isar.id_aa64isar0;
+ t = GET_IDREG(idregs, ID_AA64ISAR0);
t = FIELD_DP64(t, ID_AA64ISAR0, AES, 0);
t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 0);
t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 0);
@@ -2185,7 +2186,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 0);
t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 0);
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 0);
- cpu->isar.id_aa64isar0 = t;
+ SET_IDREG(idregs, ID_AA64ISAR0, t);
t = cpu->isar.id_aa64isar1;
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 0);
@@ -2227,16 +2228,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
}
if (!cpu->has_neon && !cpu->has_vfp) {
- uint64_t t;
uint32_t u;
- t = cpu->isar.id_aa64isar0;
- t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 0);
- cpu->isar.id_aa64isar0 = t;
+ FIELD_DP64_IDREG(idregs, ID_AA64ISAR0, FHM, 0);
- t = cpu->isar.id_aa64isar1;
- t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 0);
- cpu->isar.id_aa64isar1 = t;
+ FIELD_DP64_IDREG(idregs, ID_AA64ISAR1, FRINTTS, 0);
u = cpu->isar.mvfr0;
u = FIELD_DP32(u, MVFR0, SIMDREG, 0);
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 9e0403c9810a..180cc77370ef 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1091,7 +1091,6 @@ struct ArchCPU {
uint32_t dbgdidr;
uint32_t dbgdevid;
uint32_t dbgdevid1;
- uint64_t id_aa64isar0;
uint64_t id_aa64isar1;
uint64_t id_aa64isar2;
uint64_t id_aa64pfr0;
@@ -1102,7 +1101,6 @@ struct ArchCPU {
uint64_t id_aa64mmfr3;
uint64_t id_aa64dfr0;
uint64_t id_aa64dfr1;
- uint64_t id_aa64zfr0;
uint64_t id_aa64smfr0;
uint64_t reset_pmcr_el0;
IdRegMap idregs;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 458d1cee0120..4f411acbcb97 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -114,7 +114,7 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
* SVE is disabled and so are all vector lengths. Good.
* Disable all SVE extensions as well.
*/
- cpu->isar.id_aa64zfr0 = 0;
+ SET_IDREG(&cpu->isar.idregs, ID_AA64ZFR0, 0);
return;
}
@@ -599,6 +599,7 @@ void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp)
static void aarch64_a57_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,cortex-a57";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -636,7 +637,7 @@ static void aarch64_a57_initfn(Object *obj)
cpu->isar.id_isar6 = 0;
cpu->isar.id_aa64pfr0 = 0x00002222;
cpu->isar.id_aa64dfr0 = 0x10305106;
- cpu->isar.id_aa64isar0 = 0x00011120;
+ SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
cpu->isar.id_aa64mmfr0 = 0x00001124;
cpu->isar.dbgdidr = 0x3516d000;
cpu->isar.dbgdevid = 0x01110f13;
@@ -660,6 +661,7 @@ static void aarch64_a57_initfn(Object *obj)
static void aarch64_a53_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,cortex-a53";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -697,7 +699,7 @@ static void aarch64_a53_initfn(Object *obj)
cpu->isar.id_isar6 = 0;
cpu->isar.id_aa64pfr0 = 0x00002222;
cpu->isar.id_aa64dfr0 = 0x10305106;
- cpu->isar.id_aa64isar0 = 0x00011120;
+ SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
cpu->isar.dbgdidr = 0x3516d000;
cpu->isar.dbgdevid = 0x00110f13;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index f38eb054c06b..c90a489bd0c4 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8720,6 +8720,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
{
/* Register all the coprocessor registers based on feature bits */
CPUARMState *env = &cpu->env;
+ IdRegMap *idregs = &cpu->isar.idregs;
+
if (arm_feature(env, ARM_FEATURE_M)) {
/* M profile has no coprocessor registers */
return;
@@ -8911,7 +8913,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64zfr0 },
+ .resetvalue = GET_IDREG(idregs, ID_AA64ZFR0)},
{ .name = "ID_AA64SMFR0_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
@@ -8971,7 +8973,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64isar0 },
+ .resetvalue = GET_IDREG(idregs, ID_AA64ISAR0)},
{ .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 8577d6f520ba..bf2b2b136377 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -26,6 +26,7 @@
#include "sysemu/kvm_int.h"
#include "kvm_arm.h"
#include "cpu.h"
+#include "cpu-sysregs.h"
#include "trace.h"
#include "internals.h"
#include "hw/pci/pci.h"
@@ -247,6 +248,18 @@ static bool kvm_arm_pauth_supported(void)
kvm_check_extension(kvm_state, KVM_CAP_ARM_PTRAUTH_GENERIC));
}
+/* read a 64b sysreg value and store it in the idregs */
+static int get_host_cpu_reg64(int fd, ARMHostCPUFeatures *ahcf, ARMSysReg sr)
+{
+ int index = KVM_ARM_FEATURE_ID_RANGE_IDX(sr.op0, sr.op1, sr.crn, sr.crm, sr.op2);
+ uint64_t *reg = &ahcf->isar.idregs.regs[index];
+ int ret;
+
+ ret = read_sys_reg64(fd, reg,
+ ARM64_SYS_REG(sr.op0, sr.op1, sr.crn, sr.crm, sr.op2));
+ return ret;
+}
+
static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
{
/* Identify the feature bits corresponding to the host CPU, and
@@ -307,6 +320,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
ahcf->target = init.target;
ahcf->dtb_compatible = "arm,arm-v8";
+ int fd = fdarray[2];
err = read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr0,
ARM64_SYS_REG(3, 0, 0, 4, 0));
@@ -338,8 +352,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
ARM64_SYS_REG(3, 0, 0, 5, 0));
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr1,
ARM64_SYS_REG(3, 0, 0, 5, 1));
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar0,
- ARM64_SYS_REG(3, 0, 0, 6, 0));
+ err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64ISAR0_EL1);
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1,
ARM64_SYS_REG(3, 0, 0, 6, 1));
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar2,
@@ -448,8 +461,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
* enabled SVE support, which resulted in an error rather than RAZ.
* So only read the register if we set KVM_ARM_VCPU_SVE above.
*/
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64zfr0,
- ARM64_SYS_REG(3, 0, 0, 4, 4));
+ err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64ZFR0_EL1);
}
}
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 2963d7510f3d..6012ce6fda7a 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -32,6 +32,7 @@
static void aarch64_a35_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,cortex-a35";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -66,7 +67,7 @@ static void aarch64_a35_initfn(Object *obj)
cpu->isar.id_aa64pfr1 = 0;
cpu->isar.id_aa64dfr0 = 0x10305106;
cpu->isar.id_aa64dfr1 = 0;
- cpu->isar.id_aa64isar0 = 0x00011120;
+ SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
cpu->isar.id_aa64isar1 = 0;
cpu->isar.id_aa64mmfr0 = 0x00101122;
cpu->isar.id_aa64mmfr1 = 0;
@@ -204,6 +205,7 @@ static Property arm_cpu_lpa2_property =
static void aarch64_a55_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,cortex-a55";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -221,7 +223,7 @@ static void aarch64_a55_initfn(Object *obj)
cpu->ctr = 0x84448004; /* L1Ip = VIPT */
cpu->dcz_blocksize = 4; /* 64 bytes */
cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
- cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
+ SET_IDREG(idregs, ID_AA64ISAR0, 0x0000100010211120ull);
cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
@@ -276,6 +278,7 @@ static void aarch64_a55_initfn(Object *obj)
static void aarch64_a72_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,cortex-a72";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -311,7 +314,7 @@ static void aarch64_a72_initfn(Object *obj)
cpu->isar.id_isar5 = 0x00011121;
cpu->isar.id_aa64pfr0 = 0x00002222;
cpu->isar.id_aa64dfr0 = 0x10305106;
- cpu->isar.id_aa64isar0 = 0x00011120;
+ SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
cpu->isar.id_aa64mmfr0 = 0x00001124;
cpu->isar.dbgdidr = 0x3516d000;
cpu->isar.dbgdevid = 0x01110f13;
@@ -335,6 +338,7 @@ static void aarch64_a72_initfn(Object *obj)
static void aarch64_a76_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,cortex-a76";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -352,7 +356,7 @@ static void aarch64_a76_initfn(Object *obj)
cpu->ctr = 0x8444C004;
cpu->dcz_blocksize = 4;
cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
- cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
+ SET_IDREG(idregs, ID_AA64ISAR0, 0x0000100010211120ull);
cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
@@ -408,6 +412,7 @@ static void aarch64_a76_initfn(Object *obj)
static void aarch64_a64fx_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,a64fx";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -431,9 +436,9 @@ static void aarch64_a64fx_initfn(Object *obj)
cpu->isar.id_aa64mmfr0 = 0x0000000000001122;
cpu->isar.id_aa64mmfr1 = 0x0000000011212100;
cpu->isar.id_aa64mmfr2 = 0x0000000000001011;
- cpu->isar.id_aa64isar0 = 0x0000000010211120;
+ SET_IDREG(idregs, ID_AA64ISAR0, 0x0000000010211120);
cpu->isar.id_aa64isar1 = 0x0000000000010001;
- cpu->isar.id_aa64zfr0 = 0x0000000000000000;
+ SET_IDREG(idregs, ID_AA64ZFR0, 0x0000000000000000);
cpu->clidr = 0x0000000080000023;
/* 64KB L1 dcache */
cpu->ccsidr[0] = make_ccsidr(CCSIDR_FORMAT_LEGACY, 4, 256, 64 * KiB, 7);
@@ -581,6 +586,7 @@ static void define_neoverse_v1_cp_reginfo(ARMCPU *cpu)
static void aarch64_neoverse_n1_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,neoverse-n1";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -598,7 +604,7 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
cpu->ctr = 0x8444c004;
cpu->dcz_blocksize = 4;
cpu->isar.id_aa64dfr0 = 0x0000000110305408ull;
- cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
+ SET_IDREG(idregs, ID_AA64ISAR0, 0x0000100010211120ull);
cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
@@ -656,6 +662,7 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
static void aarch64_neoverse_v1_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,neoverse-v1";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -676,7 +683,7 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
cpu->id_aa64afr1 = 0x00000000;
cpu->isar.id_aa64dfr0 = 0x000001f210305519ull;
cpu->isar.id_aa64dfr1 = 0x00000000;
- cpu->isar.id_aa64isar0 = 0x1011111110212120ull; /* with FEAT_RNG */
+ SET_IDREG(idregs, ID_AA64ISAR0, 0x1011111110212120ull); /* with FEAT_RNG */
cpu->isar.id_aa64isar1 = 0x0011100001211032ull;
cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
@@ -735,7 +742,7 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043;
/* From 3.7.5 ID_AA64ZFR0_EL1 */
- cpu->isar.id_aa64zfr0 = 0x0000100000100000;
+ SET_IDREG(idregs, ID_AA64ZFR0, 0x0000100000100000);
cpu->sve_vq.supported = (1 << 0) /* 128bit */
| (1 << 1); /* 256bit */
@@ -882,6 +889,7 @@ static const ARMCPRegInfo cortex_a710_cp_reginfo[] = {
static void aarch64_a710_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,cortex-a710";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -919,12 +927,12 @@ static void aarch64_a710_initfn(Object *obj)
cpu->isar.id_pfr2 = 0x00000011;
cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */
cpu->isar.id_aa64pfr1 = 0x0000000000000221ull;
- cpu->isar.id_aa64zfr0 = 0x0000110100110021ull; /* with Crypto */
+ SET_IDREG(idregs, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */
cpu->isar.id_aa64dfr0 = 0x000011f010305619ull;
cpu->isar.id_aa64dfr1 = 0;
cpu->id_aa64afr0 = 0;
cpu->id_aa64afr1 = 0;
- cpu->isar.id_aa64isar0 = 0x0221111110212120ull; /* with Crypto */
+ SET_IDREG(idregs, ID_AA64ISAR0, 0x0221111110212120ull); /* with Crypto */
cpu->isar.id_aa64isar1 = 0x0010111101211052ull;
cpu->isar.id_aa64mmfr0 = 0x0000022200101122ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
@@ -983,6 +991,7 @@ static const ARMCPRegInfo neoverse_n2_cp_reginfo[] = {
static void aarch64_neoverse_n2_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,neoverse-n2";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -1020,12 +1029,12 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
cpu->isar.id_pfr2 = 0x00000011;
cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */
cpu->isar.id_aa64pfr1 = 0x0000000000000221ull;
- cpu->isar.id_aa64zfr0 = 0x0000110100110021ull; /* with Crypto */
+ SET_IDREG(idregs, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */
cpu->isar.id_aa64dfr0 = 0x000011f210305619ull;
cpu->isar.id_aa64dfr1 = 0;
cpu->id_aa64afr0 = 0;
cpu->id_aa64afr1 = 0;
- cpu->isar.id_aa64isar0 = 0x1221111110212120ull; /* with Crypto and FEAT_RNG */
+ SET_IDREG(idregs, ID_AA64ISAR0, 0x1221111110212120ull); /* with Crypto and FEAT_RNG */
cpu->isar.id_aa64isar1 = 0x0011111101211052ull;
cpu->isar.id_aa64mmfr0 = 0x0000022200101125ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
@@ -1083,6 +1092,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
void aarch64_max_tcg_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
uint64_t t;
uint32_t u;
@@ -1133,7 +1143,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, CTR_EL0, DIC, 1);
cpu->ctr = t;
- t = cpu->isar.id_aa64isar0;
+ t = GET_IDREG(idregs, ID_AA64ISAR0);
t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */
t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */
t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* FEAT_SHA512 */
@@ -1148,7 +1158,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* FEAT_FlagM2 */
t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2); /* FEAT_TLBIRANGE */
t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1); /* FEAT_RNG */
- cpu->isar.id_aa64isar0 = t;
+ SET_IDREG(idregs, ID_AA64ISAR0, t);
t = cpu->isar.id_aa64isar1;
t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); /* FEAT_DPB2 */
@@ -1241,7 +1251,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64MMFR3, SPEC_FPACC, 1); /* FEAT_FPACC_SPEC */
cpu->isar.id_aa64mmfr3 = t;
- t = cpu->isar.id_aa64zfr0;
+ t = GET_IDREG(idregs, ID_AA64ZFR0);
t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);
t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* FEAT_SVE_PMULL128 */
t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1); /* FEAT_SVE_BitPerm */
@@ -1251,7 +1261,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1); /* FEAT_I8MM */
t = FIELD_DP64(t, ID_AA64ZFR0, F32MM, 1); /* FEAT_F32MM */
t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1); /* FEAT_F64MM */
- cpu->isar.id_aa64zfr0 = t;
+ SET_IDREG(idregs, ID_AA64ZFR0, t);
t = cpu->isar.id_aa64dfr0;
t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 10); /* FEAT_Debugv8p8 */
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 04/20] arm/cpu: Store aa64isar1/2 into the idregs array
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (2 preceding siblings ...)
2024-12-06 11:21 ` [PATCH RFCv2 03/20] arm/cpu: Store aa64isar0 into the idregs arrays Cornelia Huck
@ 2024-12-06 11:21 ` Cornelia Huck
2024-12-06 11:21 ` [PATCH RFCv2 05/20] arm/cpu: Store aa64drf0/1 " Cornelia Huck
` (19 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:21 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
target/arm/cpu-features.h | 40 +++++++++++++++++++--------------------
target/arm/cpu.c | 8 +++-----
target/arm/cpu.h | 2 --
target/arm/cpu64.c | 9 +++++----
target/arm/helper.c | 4 ++--
target/arm/kvm.c | 6 ++----
target/arm/tcg/cpu64.c | 24 +++++++++++------------
7 files changed, 44 insertions(+), 49 deletions(-)
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index f92372bdd8d2..357be7d0c3b3 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -467,12 +467,12 @@ static inline bool isar_feature_aa64_tlbios(const ARMISARegisters *id)
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR1, JSCVT) != 0;
}
static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR1, FCMA) != 0;
}
/*
@@ -496,9 +496,9 @@ isar_feature_pauth_feature(const ARMISARegisters *id)
* Architecturally, only one of {APA,API,APA3} may be active (non-zero)
* and the other two must be zero. Thus we may avoid conditionals.
*/
- return (FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) |
- FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, API) |
- FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, APA3));
+ return (FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR1, APA) |
+ FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR1, API) |
+ FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR2, APA3));
}
static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
@@ -516,7 +516,7 @@ static inline bool isar_feature_aa64_pauth_qarma5(const ARMISARegisters *id)
* Return true if pauth is enabled with the architected QARMA5 algorithm.
* QEMU will always enable or disable both APA and GPA.
*/
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR1, APA) != 0;
}
static inline bool isar_feature_aa64_pauth_qarma3(const ARMISARegisters *id)
@@ -525,72 +525,72 @@ static inline bool isar_feature_aa64_pauth_qarma3(const ARMISARegisters *id)
* Return true if pauth is enabled with the architected QARMA3 algorithm.
* QEMU will always enable or disable both APA3 and GPA3.
*/
- return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, APA3) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR2, APA3) != 0;
}
static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR1, SB) != 0;
}
static inline bool isar_feature_aa64_predinv(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SPECRES) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR1, SPECRES) != 0;
}
static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR1, FRINTTS) != 0;
}
static inline bool isar_feature_aa64_dcpop(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR1, DPB) != 0;
}
static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR1, DPB) >= 2;
}
static inline bool isar_feature_aa64_bf16(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, BF16) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR1, BF16) != 0;
}
static inline bool isar_feature_aa64_ebf16(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, BF16) > 1;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR1, BF16) > 1;
}
static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR1, LRCPC) != 0;
}
static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) >= 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR1, LRCPC) >= 2;
}
static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, I8MM) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR1, I8MM) != 0;
}
static inline bool isar_feature_aa64_wfxt(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, WFXT) >= 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR2, WFXT) >= 2;
}
static inline bool isar_feature_aa64_hbc(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, BC) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR2, BC) != 0;
}
static inline bool isar_feature_aa64_mops(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, MOPS);
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64ISAR2, MOPS);
}
static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 4f06dd516d1b..de13b50cae58 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2133,9 +2133,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
uint64_t t;
uint32_t u;
- t = cpu->isar.id_aa64isar1;
- t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 0);
- cpu->isar.id_aa64isar1 = t;
+ FIELD_DP64_IDREG(idregs, ID_AA64ISAR1, JSCVT, 0);
t = cpu->isar.id_aa64pfr0;
t = FIELD_DP64(t, ID_AA64PFR0, FP, 0xf);
@@ -2188,11 +2186,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 0);
SET_IDREG(idregs, ID_AA64ISAR0, t);
- t = cpu->isar.id_aa64isar1;
+ t = GET_IDREG(idregs, ID_AA64ISAR1);
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 0);
t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 0);
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 0);
- cpu->isar.id_aa64isar1 = t;
+ SET_IDREG(idregs, ID_AA64ISAR1, t);
t = cpu->isar.id_aa64pfr0;
t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 0xf);
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 180cc77370ef..c671b5058a96 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1091,8 +1091,6 @@ struct ArchCPU {
uint32_t dbgdidr;
uint32_t dbgdevid;
uint32_t dbgdevid1;
- uint64_t id_aa64isar1;
- uint64_t id_aa64isar2;
uint64_t id_aa64pfr0;
uint64_t id_aa64pfr1;
uint64_t id_aa64mmfr0;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 4f411acbcb97..c5f2ce6f5f8f 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -480,6 +480,7 @@ void aarch64_add_sme_properties(Object *obj)
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
{
ARMPauthFeature features = cpu_isar_feature(pauth_feature, cpu);
+ IdRegMap *idregs = &cpu->isar.idregs;
uint64_t isar1, isar2;
/*
@@ -490,13 +491,13 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
*
* Begin by disabling all fields.
*/
- isar1 = cpu->isar.id_aa64isar1;
+ isar1 = GET_IDREG(idregs, ID_AA64ISAR1);
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, APA, 0);
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPA, 0);
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, API, 0);
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPI, 0);
- isar2 = cpu->isar.id_aa64isar2;
+ isar2 = GET_IDREG(idregs, ID_AA64ISAR2);
isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, APA3, 0);
isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, GPA3, 0);
@@ -543,8 +544,8 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
}
}
- cpu->isar.id_aa64isar1 = isar1;
- cpu->isar.id_aa64isar2 = isar2;
+ SET_IDREG(idregs, ID_AA64ISAR1, isar1);
+ SET_IDREG(idregs, ID_AA64ISAR2, isar2);
}
static Property arm_cpu_pauth_property =
diff --git a/target/arm/helper.c b/target/arm/helper.c
index c90a489bd0c4..09d635f8bf24 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8978,12 +8978,12 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64isar1 },
+ .resetvalue = GET_IDREG(idregs, ID_AA64ISAR1)},
{ .name = "ID_AA64ISAR2_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64isar2 },
+ .resetvalue = GET_IDREG(idregs, ID_AA64ISAR2)},
{ .name = "ID_AA64ISAR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST,
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index bf2b2b136377..35161659b040 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -353,10 +353,8 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr1,
ARM64_SYS_REG(3, 0, 0, 5, 1));
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64ISAR0_EL1);
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1,
- ARM64_SYS_REG(3, 0, 0, 6, 1));
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar2,
- ARM64_SYS_REG(3, 0, 0, 6, 2));
+ err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64ISAR1_EL1);
+ err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64ISAR2_EL1);
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr0,
ARM64_SYS_REG(3, 0, 0, 7, 0));
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1,
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 6012ce6fda7a..8e48ddc06f16 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -68,7 +68,7 @@ static void aarch64_a35_initfn(Object *obj)
cpu->isar.id_aa64dfr0 = 0x10305106;
cpu->isar.id_aa64dfr1 = 0;
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
- cpu->isar.id_aa64isar1 = 0;
+ SET_IDREG(idregs, ID_AA64ISAR1, 0);
cpu->isar.id_aa64mmfr0 = 0x00101122;
cpu->isar.id_aa64mmfr1 = 0;
cpu->clidr = 0x0a200023;
@@ -224,7 +224,7 @@ static void aarch64_a55_initfn(Object *obj)
cpu->dcz_blocksize = 4; /* 64 bytes */
cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
SET_IDREG(idregs, ID_AA64ISAR0, 0x0000100010211120ull);
- cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
+ SET_IDREG(idregs, ID_AA64ISAR1, 0x0000000000100001ull);
cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
@@ -357,7 +357,7 @@ static void aarch64_a76_initfn(Object *obj)
cpu->dcz_blocksize = 4;
cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
SET_IDREG(idregs, ID_AA64ISAR0, 0x0000100010211120ull);
- cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
+ SET_IDREG(idregs, ID_AA64ISAR1, 0x0000000000100001ull);
cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
@@ -437,7 +437,7 @@ static void aarch64_a64fx_initfn(Object *obj)
cpu->isar.id_aa64mmfr1 = 0x0000000011212100;
cpu->isar.id_aa64mmfr2 = 0x0000000000001011;
SET_IDREG(idregs, ID_AA64ISAR0, 0x0000000010211120);
- cpu->isar.id_aa64isar1 = 0x0000000000010001;
+ SET_IDREG(idregs, ID_AA64ISAR1, 0x0000000000010001);
SET_IDREG(idregs, ID_AA64ZFR0, 0x0000000000000000);
cpu->clidr = 0x0000000080000023;
/* 64KB L1 dcache */
@@ -605,7 +605,7 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
cpu->dcz_blocksize = 4;
cpu->isar.id_aa64dfr0 = 0x0000000110305408ull;
SET_IDREG(idregs, ID_AA64ISAR0, 0x0000100010211120ull);
- cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
+ SET_IDREG(idregs, ID_AA64ISAR1, 0x0000000000100001ull);
cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
@@ -684,7 +684,7 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
cpu->isar.id_aa64dfr0 = 0x000001f210305519ull;
cpu->isar.id_aa64dfr1 = 0x00000000;
SET_IDREG(idregs, ID_AA64ISAR0, 0x1011111110212120ull); /* with FEAT_RNG */
- cpu->isar.id_aa64isar1 = 0x0011100001211032ull;
+ SET_IDREG(idregs, ID_AA64ISAR1, 0x0011000001211032ull);
cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
cpu->isar.id_aa64mmfr2 = 0x0220011102101011ull;
@@ -933,7 +933,7 @@ static void aarch64_a710_initfn(Object *obj)
cpu->id_aa64afr0 = 0;
cpu->id_aa64afr1 = 0;
SET_IDREG(idregs, ID_AA64ISAR0, 0x0221111110212120ull); /* with Crypto */
- cpu->isar.id_aa64isar1 = 0x0010111101211052ull;
+ SET_IDREG(idregs, ID_AA64ISAR1, 0x0010111101211052ull);
cpu->isar.id_aa64mmfr0 = 0x0000022200101122ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
cpu->isar.id_aa64mmfr2 = 0x1221011110101011ull;
@@ -1035,7 +1035,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
cpu->id_aa64afr0 = 0;
cpu->id_aa64afr1 = 0;
SET_IDREG(idregs, ID_AA64ISAR0, 0x1221111110212120ull); /* with Crypto and FEAT_RNG */
- cpu->isar.id_aa64isar1 = 0x0011111101211052ull;
+ SET_IDREG(idregs, ID_AA64ISAR1, 0x0011111101211052ull);
cpu->isar.id_aa64mmfr0 = 0x0000022200101125ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
cpu->isar.id_aa64mmfr2 = 0x1221011112101011ull;
@@ -1160,7 +1160,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1); /* FEAT_RNG */
SET_IDREG(idregs, ID_AA64ISAR0, t);
- t = cpu->isar.id_aa64isar1;
+ t = GET_IDREG(idregs, ID_AA64ISAR1);
t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); /* FEAT_DPB2 */
t = FIELD_DP64(t, ID_AA64ISAR1, APA, PauthFeat_FPACCOMBINED);
t = FIELD_DP64(t, ID_AA64ISAR1, API, 1);
@@ -1173,13 +1173,13 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 2); /* FEAT_BF16, FEAT_EBF16 */
t = FIELD_DP64(t, ID_AA64ISAR1, DGH, 1); /* FEAT_DGH */
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); /* FEAT_I8MM */
- cpu->isar.id_aa64isar1 = t;
+ SET_IDREG(idregs, ID_AA64ISAR1, t);
- t = cpu->isar.id_aa64isar2;
+ t = GET_IDREG(idregs, ID_AA64ISAR2);
t = FIELD_DP64(t, ID_AA64ISAR2, MOPS, 1); /* FEAT_MOPS */
t = FIELD_DP64(t, ID_AA64ISAR2, BC, 1); /* FEAT_HBC */
t = FIELD_DP64(t, ID_AA64ISAR2, WFXT, 2); /* FEAT_WFxT */
- cpu->isar.id_aa64isar2 = t;
+ SET_IDREG(idregs, ID_AA64ISAR2, t);
t = cpu->isar.id_aa64pfr0;
t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); /* FEAT_FP16 */
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 05/20] arm/cpu: Store aa64drf0/1 into the idregs array
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (3 preceding siblings ...)
2024-12-06 11:21 ` [PATCH RFCv2 04/20] arm/cpu: Store aa64isar1/2 into the idregs array Cornelia Huck
@ 2024-12-06 11:21 ` Cornelia Huck
2024-12-06 11:21 ` [PATCH RFCv2 06/20] arm/cpu: Store aa64mmfr0-3 " Cornelia Huck
` (18 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:21 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
target/arm/cpu-features.h | 40 ++++++++++++++++-----------------
target/arm/cpu.c | 29 ++++++++----------------
target/arm/cpu.h | 5 +++--
target/arm/cpu64.c | 14 ++++--------
target/arm/helper.c | 6 ++---
target/arm/kvm.c | 24 +++++++++-----------
target/arm/tcg/cpu64.c | 47 ++++++++++++++++++---------------------
7 files changed, 71 insertions(+), 94 deletions(-)
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index 357be7d0c3b3..406452ef9fba 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -596,68 +596,68 @@ static inline bool isar_feature_aa64_mops(const ARMISARegisters *id)
static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id)
{
/* We always set the AdvSIMD and FP fields identically. */
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) != 0xf;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR0, FP) != 0xf;
}
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
{
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR0, FP) == 1;
}
static inline bool isar_feature_aa64_aa32(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL0) >= 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR0, EL0) >= 2;
}
static inline bool isar_feature_aa64_aa32_el1(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL1) >= 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR0, EL1) >= 2;
}
static inline bool isar_feature_aa64_aa32_el2(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL2) >= 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR0, EL2) >= 2;
}
static inline bool isar_feature_aa64_ras(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RAS) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR0, RAS) != 0;
}
static inline bool isar_feature_aa64_doublefault(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RAS) >= 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR0, RAS) >= 2;
}
static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR0, SVE) != 0;
}
static inline bool isar_feature_aa64_sel2(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SEL2) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR0, SEL2) != 0;
}
static inline bool isar_feature_aa64_rme(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RME) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR0, RME) != 0;
}
static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR0, DIT) != 0;
}
static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id)
{
- int key = FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, CSV2);
+ int key = FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR0, CSV2);
if (key >= 2) {
return true; /* FEAT_CSV2_2 */
}
if (key == 1) {
- key = FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, CSV2_FRAC);
+ key = FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR1, CSV2_FRAC);
return key >= 2; /* FEAT_CSV2_1p2 */
}
return false;
@@ -665,37 +665,37 @@ static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id)
static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR1, SSBS) != 0;
}
static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR1, BT) != 0;
}
static inline bool isar_feature_aa64_mte_insn_reg(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR1, MTE) != 0;
}
static inline bool isar_feature_aa64_mte(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) >= 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR1, MTE) >= 2;
}
static inline bool isar_feature_aa64_mte3(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) >= 3;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR1, MTE) >= 3;
}
static inline bool isar_feature_aa64_sme(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SME) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR1, SME) != 0;
}
static inline bool isar_feature_aa64_nmi(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, NMI) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64PFR1, NMI) != 0;
}
static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index de13b50cae58..bcbb8b8733aa 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2130,14 +2130,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
}
if (!cpu->has_vfp) {
- uint64_t t;
uint32_t u;
FIELD_DP64_IDREG(idregs, ID_AA64ISAR1, JSCVT, 0);
- t = cpu->isar.id_aa64pfr0;
- t = FIELD_DP64(t, ID_AA64PFR0, FP, 0xf);
- cpu->isar.id_aa64pfr0 = t;
+ FIELD_DP64_IDREG(idregs, ID_AA64PFR0, FP, 0xf);
u = cpu->isar.id_isar6;
u = FIELD_DP32(u, ID_ISAR6, JSCVT, 0);
@@ -2192,9 +2189,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 0);
SET_IDREG(idregs, ID_AA64ISAR1, t);
- t = cpu->isar.id_aa64pfr0;
- t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 0xf);
- cpu->isar.id_aa64pfr0 = t;
+ FIELD_DP64_IDREG(idregs, ID_AA64PFR0, ADVSIMD, 0xf);
u = cpu->isar.id_isar5;
u = FIELD_DP32(u, ID_ISAR5, AES, 0);
@@ -2336,12 +2331,10 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
*/
cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1, ID_PFR1, SECURITY, 0);
cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPSDBG, 0);
- cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
- ID_AA64PFR0, EL3, 0);
+ FIELD_DP64_IDREG(idregs, ID_AA64PFR0, EL3, 0);
/* Disable the realm management extension, which requires EL3. */
- cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
- ID_AA64PFR0, RME, 0);
+ FIELD_DP64_IDREG(idregs, ID_AA64PFR0, RME, 0);
}
if (!cpu->has_el2) {
@@ -2376,8 +2369,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* Disable the hypervisor feature bits in the processor feature
* registers if we don't have EL2.
*/
- cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
- ID_AA64PFR0, EL2, 0);
+ FIELD_DP64_IDREG(idregs, ID_AA64PFR0, EL2, 0);
cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1,
ID_PFR1, VIRTUALIZATION, 0);
}
@@ -2398,8 +2390,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* This matches Cortex-A710 BROADCASTMTE input being LOW.
*/
if (tcg_enabled() && cpu->tag_memory == NULL) {
- cpu->isar.id_aa64pfr1 =
- FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 1);
+ FIELD_DP64_IDREG(idregs, ID_AA64PFR1, MTE, 1);
}
/*
@@ -2407,7 +2398,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* enabled on the guest (i.e mte=off), clear guest's MTE bits."
*/
if (kvm_enabled() && !cpu->kvm_mte) {
- FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 0);
+ FIELD_DP64_IDREG(idregs, ID_AA64PFR1, MTE, 0);
}
#endif
}
@@ -2446,13 +2437,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
cpu->isar.id_dfr0 =
FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, MMAPTRC, 0);
/* FEAT_AMU (Activity Monitors Extension) */
- cpu->isar.id_aa64pfr0 =
- FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, AMU, 0);
+ FIELD_DP64_IDREG(idregs, ID_AA64PFR0, AMU, 0);
cpu->isar.id_pfr0 =
FIELD_DP32(cpu->isar.id_pfr0, ID_PFR0, AMU, 0);
/* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */
- cpu->isar.id_aa64pfr0 =
- FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, MPAM, 0);
+ FIELD_DP64_IDREG(idregs, ID_AA64PFR0, MPAM, 0);
}
/* MPU can be configured out of a PMSA CPU either by setting has-mpu
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index c671b5058a96..8c841988c5ad 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -881,6 +881,9 @@ _set_idreg(MAP, SYS_ ## REG ## _EL1, regval); \
#define FIELD_EX64_IDREG(MAP, REG, FIELD) \
FIELD_EX64(_get_idreg(MAP, SYS_ ## REG ## _EL1), REG, FIELD) \
+#define FIELD_EX32_IDREG(MAP, REG, FIELD) \
+FIELD_EX32(_get_idreg(MAP, SYS_ ## REG ## _EL1), REG, FIELD) \
+
#define SET_IDREG(MAP, REG, VALUE) \
_set_idreg(MAP, SYS_ ## REG ## _EL1, VALUE)
@@ -1091,8 +1094,6 @@ struct ArchCPU {
uint32_t dbgdidr;
uint32_t dbgdevid;
uint32_t dbgdevid1;
- uint64_t id_aa64pfr0;
- uint64_t id_aa64pfr1;
uint64_t id_aa64mmfr0;
uint64_t id_aa64mmfr1;
uint64_t id_aa64mmfr2;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index c5f2ce6f5f8f..48b4a08a4a7b 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -288,16 +288,13 @@ static bool cpu_arm_get_sve(Object *obj, Error **errp)
static void cpu_arm_set_sve(Object *obj, bool value, Error **errp)
{
ARMCPU *cpu = ARM_CPU(obj);
- uint64_t t;
if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
error_setg(errp, "'sve' feature not supported by KVM on this host");
return;
}
- t = cpu->isar.id_aa64pfr0;
- t = FIELD_DP64(t, ID_AA64PFR0, SVE, value);
- cpu->isar.id_aa64pfr0 = t;
+ FIELD_DP64_IDREG(&cpu->isar.idregs, ID_AA64PFR0, SVE, value);
}
void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp)
@@ -348,11 +345,8 @@ static bool cpu_arm_get_sme(Object *obj, Error **errp)
static void cpu_arm_set_sme(Object *obj, bool value, Error **errp)
{
ARMCPU *cpu = ARM_CPU(obj);
- uint64_t t;
- t = cpu->isar.id_aa64pfr1;
- t = FIELD_DP64(t, ID_AA64PFR1, SME, value);
- cpu->isar.id_aa64pfr1 = t;
+ FIELD_DP64_IDREG(&cpu->isar.idregs, ID_AA64PFR1, SME, value);
}
static bool cpu_arm_get_sme_fa64(Object *obj, Error **errp)
@@ -636,7 +630,7 @@ static void aarch64_a57_initfn(Object *obj)
cpu->isar.id_isar4 = 0x00011142;
cpu->isar.id_isar5 = 0x00011121;
cpu->isar.id_isar6 = 0;
- cpu->isar.id_aa64pfr0 = 0x00002222;
+ SET_IDREG(idregs, ID_AA64PFR0, 0x00002222);
cpu->isar.id_aa64dfr0 = 0x10305106;
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
cpu->isar.id_aa64mmfr0 = 0x00001124;
@@ -698,7 +692,7 @@ static void aarch64_a53_initfn(Object *obj)
cpu->isar.id_isar4 = 0x00011142;
cpu->isar.id_isar5 = 0x00011121;
cpu->isar.id_isar6 = 0;
- cpu->isar.id_aa64pfr0 = 0x00002222;
+ SET_IDREG(idregs, ID_AA64PFR0, 0x00002222);
cpu->isar.id_aa64dfr0 = 0x10305106;
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 09d635f8bf24..be9cc22a3ffc 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7706,7 +7706,7 @@ static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri)
static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
ARMCPU *cpu = env_archcpu(env);
- uint64_t pfr0 = cpu->isar.id_aa64pfr0;
+ uint64_t pfr0 = GET_IDREG(&cpu->isar.idregs, ID_AA64PFR0);
if (env->gicv3state) {
pfr0 |= 1 << 24;
@@ -8886,7 +8886,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.access = PL1_R,
#ifdef CONFIG_USER_ONLY
.type = ARM_CP_CONST,
- .resetvalue = cpu->isar.id_aa64pfr0
+ .resetvalue = GET_IDREG(idregs, ID_AA64PFR0)
#else
.type = ARM_CP_NO_RAW,
.accessfn = access_aa64_tid3,
@@ -8898,7 +8898,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64pfr1},
+ .resetvalue = GET_IDREG(idregs, ID_AA64PFR1)},
{ .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 35161659b040..a7d0aac63ae9 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -322,8 +322,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
ahcf->dtb_compatible = "arm,arm-v8";
int fd = fdarray[2];
- err = read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr0,
- ARM64_SYS_REG(3, 0, 0, 4, 0));
+ err = get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64PFR0_EL1);
if (unlikely(err < 0)) {
/*
* Before v4.15, the kernel only exposed a limited number of system
@@ -341,11 +340,10 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
* ??? Either of these sounds like too much effort just
* to work around running a modern host kernel.
*/
- ahcf->isar.id_aa64pfr0 = 0x00000011; /* EL1&0, AArch64 only */
+ SET_IDREG(&ahcf->isar.idregs, ID_AA64PFR0, 0x00000011); /* EL1&0, AArch64 only */
err = 0;
} else {
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr1,
- ARM64_SYS_REG(3, 0, 0, 4, 1));
+ err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64PFR1_EL1);
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64smfr0,
ARM64_SYS_REG(3, 0, 0, 4, 5));
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr0,
@@ -371,10 +369,8 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
* than skipping the reads and leaving 0, as we must avoid
* considering the values in every case.
*/
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr0,
- ARM64_SYS_REG(3, 0, 0, 1, 0));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr1,
- ARM64_SYS_REG(3, 0, 0, 1, 1));
+ err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64PFR0_EL1);
+ err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64PFR1_EL1);
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
ARM64_SYS_REG(3, 0, 0, 1, 2));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
@@ -425,14 +421,14 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
* arch/arm64/kvm/sys_regs.c:trap_dbgidr() does.
* We only do this if the CPU supports AArch32 at EL1.
*/
- if (FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL1) >= 2) {
- int wrps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, WRPS);
- int brps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, BRPS);
+ if (FIELD_EX32_IDREG(&ahcf->isar.idregs, ID_AA64PFR0, EL1) >= 2) {
+ int wrps = FIELD_EX64_IDREG(&ahcf->isar.idregs, ID_AA64DFR0, WRPS);
+ int brps = FIELD_EX64_IDREG(&ahcf->isar.idregs, ID_AA64DFR0, BRPS);
int ctx_cmps =
- FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS);
+ FIELD_EX64_IDREG(&ahcf->isar.idregs, ID_AA64DFR0, CTX_CMPS);
int version = 6; /* ARMv8 debug architecture */
bool has_el3 =
- !!FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL3);
+ !!FIELD_EX32_IDREG(&ahcf->isar.idregs, ID_AA64PFR0, EL3);
uint32_t dbgdidr = 0;
dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, WRPS, wrps);
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 8e48ddc06f16..827ac0200211 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -63,8 +63,8 @@ static void aarch64_a35_initfn(Object *obj)
cpu->isar.id_isar3 = 0x01112131;
cpu->isar.id_isar4 = 0x00011142;
cpu->isar.id_isar5 = 0x00011121;
- cpu->isar.id_aa64pfr0 = 0x00002222;
- cpu->isar.id_aa64pfr1 = 0;
+ SET_IDREG(idregs, ID_AA64PFR0, 0x00002222);
+ SET_IDREG(idregs, ID_AA64PFR1, 0);
cpu->isar.id_aa64dfr0 = 0x10305106;
cpu->isar.id_aa64dfr1 = 0;
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
@@ -158,11 +158,8 @@ static bool cpu_arm_get_rme(Object *obj, Error **errp)
static void cpu_arm_set_rme(Object *obj, bool value, Error **errp)
{
ARMCPU *cpu = ARM_CPU(obj);
- uint64_t t;
- t = cpu->isar.id_aa64pfr0;
- t = FIELD_DP64(t, ID_AA64PFR0, RME, value);
- cpu->isar.id_aa64pfr0 = t;
+ FIELD_DP64_IDREG(&cpu->isar.idregs, ID_AA64PFR0, RME, value);
}
static void cpu_max_set_l0gptsz(Object *obj, Visitor *v, const char *name,
@@ -228,8 +225,8 @@ static void aarch64_a55_initfn(Object *obj)
cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
- cpu->isar.id_aa64pfr0 = 0x0000000010112222ull;
- cpu->isar.id_aa64pfr1 = 0x0000000000000010ull;
+ SET_IDREG(idregs, ID_AA64PFR0, 0x0000000010112222ull);
+ SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000010ull);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_dfr0 = 0x04010088;
cpu->isar.id_isar0 = 0x02101110;
@@ -312,7 +309,7 @@ static void aarch64_a72_initfn(Object *obj)
cpu->isar.id_isar3 = 0x01112131;
cpu->isar.id_isar4 = 0x00011142;
cpu->isar.id_isar5 = 0x00011121;
- cpu->isar.id_aa64pfr0 = 0x00002222;
+ SET_IDREG(idregs, ID_AA64PFR0, 0x00002222);
cpu->isar.id_aa64dfr0 = 0x10305106;
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
cpu->isar.id_aa64mmfr0 = 0x00001124;
@@ -361,8 +358,8 @@ static void aarch64_a76_initfn(Object *obj)
cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
- cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; /* GIC filled in later */
- cpu->isar.id_aa64pfr1 = 0x0000000000000010ull;
+ SET_IDREG(idregs, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */
+ SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000010ull);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_dfr0 = 0x04010088;
cpu->isar.id_isar0 = 0x02101110;
@@ -427,8 +424,8 @@ static void aarch64_a64fx_initfn(Object *obj)
cpu->revidr = 0x00000000;
cpu->ctr = 0x86668006;
cpu->reset_sctlr = 0x30000180;
- cpu->isar.id_aa64pfr0 = 0x0000000101111111; /* No RAS Extensions */
- cpu->isar.id_aa64pfr1 = 0x0000000000000000;
+ SET_IDREG(idregs, ID_AA64PFR0, 0x0000000101111111); /* No RAS Extensions */
+ SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000000);
cpu->isar.id_aa64dfr0 = 0x0000000010305408;
cpu->isar.id_aa64dfr1 = 0x0000000000000000;
cpu->id_aa64afr0 = 0x0000000000000000;
@@ -609,8 +606,8 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
- cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; /* GIC filled in later */
- cpu->isar.id_aa64pfr1 = 0x0000000000000020ull;
+ SET_IDREG(idregs, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */
+ SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000020ull);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_dfr0 = 0x04010088;
cpu->isar.id_isar0 = 0x02101110;
@@ -688,8 +685,8 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
cpu->isar.id_aa64mmfr2 = 0x0220011102101011ull;
- cpu->isar.id_aa64pfr0 = 0x1101110120111112ull; /* GIC filled in later */
- cpu->isar.id_aa64pfr1 = 0x0000000000000020ull;
+ SET_IDREG(idregs, ID_AA64PFR0, 0x1101110120111112ull); /* GIC filled in later */
+ SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000020ull);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_dfr0 = 0x15011099;
cpu->isar.id_isar0 = 0x02101110;
@@ -925,8 +922,8 @@ static void aarch64_a710_initfn(Object *obj)
cpu->isar.mvfr1 = 0x13211111;
cpu->isar.mvfr2 = 0x00000043;
cpu->isar.id_pfr2 = 0x00000011;
- cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */
- cpu->isar.id_aa64pfr1 = 0x0000000000000221ull;
+ SET_IDREG(idregs, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */
+ SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000221ull);
SET_IDREG(idregs, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */
cpu->isar.id_aa64dfr0 = 0x000011f010305619ull;
cpu->isar.id_aa64dfr1 = 0;
@@ -1027,8 +1024,8 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
cpu->isar.mvfr1 = 0x13211111;
cpu->isar.mvfr2 = 0x00000043;
cpu->isar.id_pfr2 = 0x00000011;
- cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */
- cpu->isar.id_aa64pfr1 = 0x0000000000000221ull;
+ SET_IDREG(idregs, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */
+ SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000221ull);
SET_IDREG(idregs, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */
cpu->isar.id_aa64dfr0 = 0x000011f210305619ull;
cpu->isar.id_aa64dfr1 = 0;
@@ -1181,7 +1178,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64ISAR2, WFXT, 2); /* FEAT_WFxT */
SET_IDREG(idregs, ID_AA64ISAR2, t);
- t = cpu->isar.id_aa64pfr0;
+ t = GET_IDREG(idregs, ID_AA64PFR0);
t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); /* FEAT_FP16 */
t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); /* FEAT_FP16 */
t = FIELD_DP64(t, ID_AA64PFR0, RAS, 2); /* FEAT_RASv1p1 + FEAT_DoubleFault */
@@ -1190,9 +1187,9 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 3); /* FEAT_CSV2_3 */
t = FIELD_DP64(t, ID_AA64PFR0, CSV3, 1); /* FEAT_CSV3 */
- cpu->isar.id_aa64pfr0 = t;
+ SET_IDREG(idregs, ID_AA64PFR0, t);
- t = cpu->isar.id_aa64pfr1;
+ t = GET_IDREG(idregs, ID_AA64PFR1);
t = FIELD_DP64(t, ID_AA64PFR1, BT, 1); /* FEAT_BTI */
t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2); /* FEAT_SSBS2 */
/*
@@ -1205,7 +1202,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64PFR1, SME, 1); /* FEAT_SME */
t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_3 */
t = FIELD_DP64(t, ID_AA64PFR1, NMI, 1); /* FEAT_NMI */
- cpu->isar.id_aa64pfr1 = t;
+ SET_IDREG(idregs, ID_AA64PFR1, t);
t = cpu->isar.id_aa64mmfr0;
t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 06/20] arm/cpu: Store aa64mmfr0-3 into the idregs array
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (4 preceding siblings ...)
2024-12-06 11:21 ` [PATCH RFCv2 05/20] arm/cpu: Store aa64drf0/1 " Cornelia Huck
@ 2024-12-06 11:21 ` Cornelia Huck
2024-12-06 11:22 ` [PATCH RFCv2 07/20] arm/cpu: Store aa64drf0/1 " Cornelia Huck
` (17 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:21 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
target/arm/cpu-features.h | 72 +++++++++++++++++++--------------------
target/arm/cpu.h | 7 ++--
target/arm/cpu64.c | 8 ++---
target/arm/helper.c | 8 ++---
target/arm/kvm.c | 12 +++----
target/arm/ptw.c | 6 ++--
target/arm/tcg/cpu64.c | 64 +++++++++++++++++-----------------
7 files changed, 85 insertions(+), 92 deletions(-)
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index 406452ef9fba..531f38da6569 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -700,187 +700,187 @@ static inline bool isar_feature_aa64_nmi(const ARMISARegisters *id)
static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
{
- return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1;
+ return FIELD_SEX64_IDREG(&id->idregs, ID_AA64MMFR0, TGRAN4) >= 1;
}
static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id)
{
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
+ unsigned t = FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR0, TGRAN4_2);
return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id));
}
static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR0, TGRAN16) >= 2;
}
static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
{
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
+ unsigned t = FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR0, TGRAN16_2);
return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
}
static inline bool isar_feature_aa64_tgran4(const ARMISARegisters *id)
{
- return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 0;
+ return FIELD_SEX64_IDREG(&id->idregs, ID_AA64MMFR0, TGRAN4) >= 0;
}
static inline bool isar_feature_aa64_tgran16(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 1;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR0, TGRAN16) >= 1;
}
static inline bool isar_feature_aa64_tgran64(const ARMISARegisters *id)
{
- return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64) >= 0;
+ return FIELD_SEX64_IDREG(&id->idregs, ID_AA64MMFR0, TGRAN64) >= 0;
}
static inline bool isar_feature_aa64_tgran4_2(const ARMISARegisters *id)
{
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
+ unsigned t = FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR0, TGRAN4_2);
return t >= 2 || (t == 0 && isar_feature_aa64_tgran4(id));
}
static inline bool isar_feature_aa64_tgran16_2(const ARMISARegisters *id)
{
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
+ unsigned t = FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR0, TGRAN16_2);
return t >= 2 || (t == 0 && isar_feature_aa64_tgran16(id));
}
static inline bool isar_feature_aa64_tgran64_2(const ARMISARegisters *id)
{
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64_2);
+ unsigned t = FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR0, TGRAN64_2);
return t >= 2 || (t == 0 && isar_feature_aa64_tgran64(id));
}
static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR0, FGT) != 0;
}
static inline bool isar_feature_aa64_ecv_traps(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR0, ECV) > 0;
}
static inline bool isar_feature_aa64_ecv(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 1;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR0, ECV) > 1;
}
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR1, VH) != 0;
}
static inline bool isar_feature_aa64_lor(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR1, LO) != 0;
}
static inline bool isar_feature_aa64_pan(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR1, PAN) != 0;
}
static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR1, PAN) >= 2;
}
static inline bool isar_feature_aa64_pan3(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 3;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR1, PAN) >= 3;
}
static inline bool isar_feature_aa64_hcx(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HCX) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR1, HCX) != 0;
}
static inline bool isar_feature_aa64_tidcp1(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, TIDCP1) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR1, TIDCP1) != 0;
}
static inline bool isar_feature_aa64_cmow(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, CMOW) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR1, CMOW) != 0;
}
static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR1, HAFDBS) != 0;
}
static inline bool isar_feature_aa64_hdbs(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) >= 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR1, HAFDBS) >= 2;
}
static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR1, XNX) != 0;
}
static inline bool isar_feature_aa64_uao(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, UAO) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR2, UAO) != 0;
}
static inline bool isar_feature_aa64_st(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, ST) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR2, ST) != 0;
}
static inline bool isar_feature_aa64_lse2(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, AT) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR2, AT) != 0;
}
static inline bool isar_feature_aa64_fwb(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, FWB) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR2, FWB) != 0;
}
static inline bool isar_feature_aa64_ids(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, IDS) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR2, IDS) != 0;
}
static inline bool isar_feature_aa64_half_evt(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, EVT) >= 1;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR2, EVT) >= 1;
}
static inline bool isar_feature_aa64_evt(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, EVT) >= 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR2, EVT) >= 2;
}
static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR2, CCIDX) != 0;
}
static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR2, VARANGE) != 0;
}
static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR2, E0PD) != 0;
}
static inline bool isar_feature_aa64_nv(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, NV) != 0;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR2, NV) != 0;
}
static inline bool isar_feature_aa64_nv2(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, NV) >= 2;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64MMFR2, NV) >= 2;
}
static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 8c841988c5ad..f36139ba79db 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -881,6 +881,9 @@ _set_idreg(MAP, SYS_ ## REG ## _EL1, regval); \
#define FIELD_EX64_IDREG(MAP, REG, FIELD) \
FIELD_EX64(_get_idreg(MAP, SYS_ ## REG ## _EL1), REG, FIELD) \
+#define FIELD_SEX64_IDREG(MAP, REG, FIELD) \
+FIELD_SEX64(_get_idreg(MAP, SYS_ ## REG ## _EL1), REG, FIELD) \
+
#define FIELD_EX32_IDREG(MAP, REG, FIELD) \
FIELD_EX32(_get_idreg(MAP, SYS_ ## REG ## _EL1), REG, FIELD) \
@@ -1094,10 +1097,6 @@ struct ArchCPU {
uint32_t dbgdidr;
uint32_t dbgdevid;
uint32_t dbgdevid1;
- uint64_t id_aa64mmfr0;
- uint64_t id_aa64mmfr1;
- uint64_t id_aa64mmfr2;
- uint64_t id_aa64mmfr3;
uint64_t id_aa64dfr0;
uint64_t id_aa64dfr1;
uint64_t id_aa64smfr0;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 48b4a08a4a7b..fb1c50ee9007 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -583,12 +583,12 @@ void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp)
return;
}
- t = cpu->isar.id_aa64mmfr0;
+ t = GET_IDREG(&cpu->isar.idregs, ID_AA64MMFR0);
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 2); /* 16k pages w/ LPA2 */
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4, 1); /* 4k pages w/ LPA2 */
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 3); /* 16k stage2 w/ LPA2 */
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 3); /* 4k stage2 w/ LPA2 */
- cpu->isar.id_aa64mmfr0 = t;
+ SET_IDREG(&cpu->isar.idregs, ID_AA64MMFR0, t);
}
static void aarch64_a57_initfn(Object *obj)
@@ -633,7 +633,7 @@ static void aarch64_a57_initfn(Object *obj)
SET_IDREG(idregs, ID_AA64PFR0, 0x00002222);
cpu->isar.id_aa64dfr0 = 0x10305106;
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
- cpu->isar.id_aa64mmfr0 = 0x00001124;
+ SET_IDREG(idregs, ID_AA64MMFR0, 0x00001124);
cpu->isar.dbgdidr = 0x3516d000;
cpu->isar.dbgdevid = 0x01110f13;
cpu->isar.dbgdevid1 = 0x2;
@@ -695,7 +695,7 @@ static void aarch64_a53_initfn(Object *obj)
SET_IDREG(idregs, ID_AA64PFR0, 0x00002222);
cpu->isar.id_aa64dfr0 = 0x10305106;
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
- cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
+ SET_IDREG(idregs, ID_AA64MMFR0, 0x00001122); /* 40 bit physical addr */
cpu->isar.dbgdidr = 0x3516d000;
cpu->isar.dbgdevid = 0x00110f13;
cpu->isar.dbgdevid1 = 0x1;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index be9cc22a3ffc..1ee415c276a8 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -9013,22 +9013,22 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64mmfr0 },
+ .resetvalue = GET_IDREG(idregs, ID_AA64MMFR0)},
{ .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64mmfr1 },
+ .resetvalue = GET_IDREG(idregs, ID_AA64MMFR1) },
{ .name = "ID_AA64MMFR2_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64mmfr2 },
+ .resetvalue = GET_IDREG(idregs, ID_AA64MMFR2) },
{ .name = "ID_AA64MMFR3_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64mmfr3 },
+ .resetvalue = GET_IDREG(idregs, ID_AA64MMFR3) },
{ .name = "ID_AA64MMFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST,
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index a7d0aac63ae9..c073758ad6c3 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -353,14 +353,10 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64ISAR0_EL1);
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64ISAR1_EL1);
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64ISAR2_EL1);
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr0,
- ARM64_SYS_REG(3, 0, 0, 7, 0));
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1,
- ARM64_SYS_REG(3, 0, 0, 7, 1));
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr2,
- ARM64_SYS_REG(3, 0, 0, 7, 2));
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr3,
- ARM64_SYS_REG(3, 0, 0, 7, 3));
+ err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64MMFR0_EL1);
+ err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64MMFR1_EL1);
+ err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64MMFR2_EL1);
+ err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64MMFR3_EL1);
/*
* Note that if AArch32 support is not present in the host,
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index 64bb6878a48a..f5d294cfb75c 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -123,7 +123,7 @@ unsigned int arm_pamax(ARMCPU *cpu)
{
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
unsigned int parange =
- FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
+ FIELD_EX64_IDREG(&cpu->isar.idregs, ID_AA64MMFR0, PARANGE);
/*
* id_aa64mmfr0 is a read-only register so values outside of the
@@ -333,7 +333,7 @@ static bool granule_protection_check(CPUARMState *env, uint64_t paddress,
* physical address size is invalid.
*/
pps = FIELD_EX64(gpccr, GPCCR, PPS);
- if (pps > FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE)) {
+ if (pps > FIELD_EX64_IDREG(&cpu->isar.idregs, ID_AA64MMFR0, PARANGE)) {
goto fault_walk;
}
pps = pamax_map[pps];
@@ -1735,7 +1735,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
* ID_AA64MMFR0 is a read-only register so values outside of the
* supported mappings can be considered an implementation error.
*/
- ps = FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
+ ps = FIELD_EX64_IDREG(&cpu->isar.idregs, ID_AA64MMFR0, PARANGE);
ps = MIN(ps, param.ps);
assert(ps < ARRAY_SIZE(pamax_map));
outputsize = pamax_map[ps];
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 827ac0200211..53ee612b8657 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -69,8 +69,8 @@ static void aarch64_a35_initfn(Object *obj)
cpu->isar.id_aa64dfr1 = 0;
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
SET_IDREG(idregs, ID_AA64ISAR1, 0);
- cpu->isar.id_aa64mmfr0 = 0x00101122;
- cpu->isar.id_aa64mmfr1 = 0;
+ SET_IDREG(idregs, ID_AA64MMFR0, 0x00101122);
+ SET_IDREG(idregs, ID_AA64MMFR1, 0);
cpu->clidr = 0x0a200023;
cpu->dcz_blocksize = 4;
@@ -222,9 +222,9 @@ static void aarch64_a55_initfn(Object *obj)
cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
SET_IDREG(idregs, ID_AA64ISAR0, 0x0000100010211120ull);
SET_IDREG(idregs, ID_AA64ISAR1, 0x0000000000100001ull);
- cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
- cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
- cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
+ SET_IDREG(idregs, ID_AA64MMFR0, 0x0000000000101122ull);
+ SET_IDREG(idregs, ID_AA64MMFR1, 0x0000000010212122ull);
+ SET_IDREG(idregs, ID_AA64MMFR2, 0x0000000000001011ull);
SET_IDREG(idregs, ID_AA64PFR0, 0x0000000010112222ull);
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000010ull);
cpu->id_afr0 = 0x00000000;
@@ -312,7 +312,7 @@ static void aarch64_a72_initfn(Object *obj)
SET_IDREG(idregs, ID_AA64PFR0, 0x00002222);
cpu->isar.id_aa64dfr0 = 0x10305106;
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
- cpu->isar.id_aa64mmfr0 = 0x00001124;
+ SET_IDREG(idregs, ID_AA64MMFR0, 0x00001124);
cpu->isar.dbgdidr = 0x3516d000;
cpu->isar.dbgdevid = 0x01110f13;
cpu->isar.dbgdevid1 = 0x2;
@@ -355,9 +355,9 @@ static void aarch64_a76_initfn(Object *obj)
cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
SET_IDREG(idregs, ID_AA64ISAR0, 0x0000100010211120ull);
SET_IDREG(idregs, ID_AA64ISAR1, 0x0000000000100001ull);
- cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
- cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
- cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
+ SET_IDREG(idregs, ID_AA64MMFR0, 0x0000000000101122ull);
+ SET_IDREG(idregs, ID_AA64MMFR1, 0x0000000010212122ull);
+ SET_IDREG(idregs, ID_AA64MMFR2, 0x0000000000001011ull);
SET_IDREG(idregs, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000010ull);
cpu->id_afr0 = 0x00000000;
@@ -430,9 +430,9 @@ static void aarch64_a64fx_initfn(Object *obj)
cpu->isar.id_aa64dfr1 = 0x0000000000000000;
cpu->id_aa64afr0 = 0x0000000000000000;
cpu->id_aa64afr1 = 0x0000000000000000;
- cpu->isar.id_aa64mmfr0 = 0x0000000000001122;
- cpu->isar.id_aa64mmfr1 = 0x0000000011212100;
- cpu->isar.id_aa64mmfr2 = 0x0000000000001011;
+ SET_IDREG(idregs, ID_AA64MMFR0, 0x0000000000001122);
+ SET_IDREG(idregs, ID_AA64MMFR1, 0x0000000011212100);
+ SET_IDREG(idregs, ID_AA64MMFR2, 0x0000000000001011);
SET_IDREG(idregs, ID_AA64ISAR0, 0x0000000010211120);
SET_IDREG(idregs, ID_AA64ISAR1, 0x0000000000010001);
SET_IDREG(idregs, ID_AA64ZFR0, 0x0000000000000000);
@@ -603,9 +603,9 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
cpu->isar.id_aa64dfr0 = 0x0000000110305408ull;
SET_IDREG(idregs, ID_AA64ISAR0, 0x0000100010211120ull);
SET_IDREG(idregs, ID_AA64ISAR1, 0x0000000000100001ull);
- cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
- cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
- cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
+ SET_IDREG(idregs, ID_AA64MMFR0, 0x0000000000101125ull);
+ SET_IDREG(idregs, ID_AA64MMFR1, 0x0000000010212122ull);
+ SET_IDREG(idregs, ID_AA64MMFR2, 0x0000000000001011ull);
SET_IDREG(idregs, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000020ull);
cpu->id_afr0 = 0x00000000;
@@ -682,9 +682,9 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
cpu->isar.id_aa64dfr1 = 0x00000000;
SET_IDREG(idregs, ID_AA64ISAR0, 0x1011111110212120ull); /* with FEAT_RNG */
SET_IDREG(idregs, ID_AA64ISAR1, 0x0011000001211032ull);
- cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
- cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
- cpu->isar.id_aa64mmfr2 = 0x0220011102101011ull;
+ SET_IDREG(idregs, ID_AA64MMFR0, 0x0000000000101125ull);
+ SET_IDREG(idregs, ID_AA64MMFR1, 0x0000000010212122ull),
+ SET_IDREG(idregs, ID_AA64MMFR2, 0x0220011102101011ull),
SET_IDREG(idregs, ID_AA64PFR0, 0x1101110120111112ull); /* GIC filled in later */
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000020ull);
cpu->id_afr0 = 0x00000000;
@@ -931,9 +931,9 @@ static void aarch64_a710_initfn(Object *obj)
cpu->id_aa64afr1 = 0;
SET_IDREG(idregs, ID_AA64ISAR0, 0x0221111110212120ull); /* with Crypto */
SET_IDREG(idregs, ID_AA64ISAR1, 0x0010111101211052ull);
- cpu->isar.id_aa64mmfr0 = 0x0000022200101122ull;
- cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
- cpu->isar.id_aa64mmfr2 = 0x1221011110101011ull;
+ SET_IDREG(idregs, ID_AA64MMFR0, 0x0000022200101122ull);
+ SET_IDREG(idregs, ID_AA64MMFR1, 0x0000000010212122ull);
+ SET_IDREG(idregs, ID_AA64MMFR2, 0x1221011110101011ull);
cpu->clidr = 0x0000001482000023ull;
cpu->gm_blocksize = 4;
cpu->ctr = 0x000000049444c004ull;
@@ -1033,9 +1033,9 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
cpu->id_aa64afr1 = 0;
SET_IDREG(idregs, ID_AA64ISAR0, 0x1221111110212120ull); /* with Crypto and FEAT_RNG */
SET_IDREG(idregs, ID_AA64ISAR1, 0x0011111101211052ull);
- cpu->isar.id_aa64mmfr0 = 0x0000022200101125ull;
- cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
- cpu->isar.id_aa64mmfr2 = 0x1221011112101011ull;
+ SET_IDREG(idregs, ID_AA64MMFR0, 0x0000022200101125ull);
+ SET_IDREG(idregs, ID_AA64MMFR1, 0x0000000010212122ull);
+ SET_IDREG(idregs, ID_AA64MMFR2, 0x1221011112101011ull);
cpu->clidr = 0x0000001482000023ull;
cpu->gm_blocksize = 4;
cpu->ctr = 0x00000004b444c004ull;
@@ -1204,7 +1204,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64PFR1, NMI, 1); /* FEAT_NMI */
SET_IDREG(idregs, ID_AA64PFR1, t);
- t = cpu->isar.id_aa64mmfr0;
+ t = GET_IDREG(idregs, ID_AA64MMFR0);
t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 1); /* 16k pages supported */
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 2); /* 16k stage2 supported */
@@ -1212,9 +1212,9 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */
t = FIELD_DP64(t, ID_AA64MMFR0, FGT, 1); /* FEAT_FGT */
t = FIELD_DP64(t, ID_AA64MMFR0, ECV, 2); /* FEAT_ECV */
- cpu->isar.id_aa64mmfr0 = t;
+ SET_IDREG(idregs, ID_AA64MMFR0, t);
- t = cpu->isar.id_aa64mmfr1;
+ t = GET_IDREG(idregs, ID_AA64MMFR1);
t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 2); /* FEAT_HAFDBS */
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */
@@ -1226,9 +1226,9 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64MMFR1, HCX, 1); /* FEAT_HCX */
t = FIELD_DP64(t, ID_AA64MMFR1, TIDCP1, 1); /* FEAT_TIDCP1 */
t = FIELD_DP64(t, ID_AA64MMFR1, CMOW, 1); /* FEAT_CMOW */
- cpu->isar.id_aa64mmfr1 = t;
+ SET_IDREG(idregs, ID_AA64MMFR1, t);
- t = cpu->isar.id_aa64mmfr2;
+ t = GET_IDREG(idregs, ID_AA64MMFR2);
t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* FEAT_TTCNP */
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); /* FEAT_UAO */
t = FIELD_DP64(t, ID_AA64MMFR2, IESB, 1); /* FEAT_IESB */
@@ -1242,11 +1242,9 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */
t = FIELD_DP64(t, ID_AA64MMFR2, EVT, 2); /* FEAT_EVT */
t = FIELD_DP64(t, ID_AA64MMFR2, E0PD, 1); /* FEAT_E0PD */
- cpu->isar.id_aa64mmfr2 = t;
+ SET_IDREG(idregs, ID_AA64MMFR2, t);
- t = cpu->isar.id_aa64mmfr3;
- t = FIELD_DP64(t, ID_AA64MMFR3, SPEC_FPACC, 1); /* FEAT_FPACC_SPEC */
- cpu->isar.id_aa64mmfr3 = t;
+ FIELD_DP64_IDREG(idregs, ID_AA64MMFR3, SPEC_FPACC, 1); /* FEAT_FPACC_SPEC */
t = GET_IDREG(idregs, ID_AA64ZFR0);
t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 07/20] arm/cpu: Store aa64drf0/1 into the idregs array
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (5 preceding siblings ...)
2024-12-06 11:21 ` [PATCH RFCv2 06/20] arm/cpu: Store aa64mmfr0-3 " Cornelia Huck
@ 2024-12-06 11:22 ` Cornelia Huck
2024-12-06 11:22 ` [PATCH RFCv2 08/20] arm/cpu: Store aa64smfr0 " Cornelia Huck
` (16 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:22 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
target/arm/cpu-features.h | 16 ++++++++--------
target/arm/cpu.c | 15 +++++----------
target/arm/cpu.h | 2 --
target/arm/cpu64.c | 4 ++--
target/arm/helper.c | 4 ++--
target/arm/internals.h | 6 +++---
target/arm/kvm.c | 6 ++----
target/arm/tcg/cpu64.c | 33 +++++++++++++++++----------------
8 files changed, 39 insertions(+), 47 deletions(-)
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index 531f38da6569..5e3c83f0cc61 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -885,30 +885,30 @@ static inline bool isar_feature_aa64_nv2(const ARMISARegisters *id)
static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
- FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64DFR0, PMUVER) >= 4 &&
+ FIELD_EX64_IDREG(&id->idregs, ID_AA64DFR0, PMUVER) != 0xf;
}
static inline bool isar_feature_aa64_pmuv3p4(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
- FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64DFR0, PMUVER) >= 5 &&
+ FIELD_EX64_IDREG(&id->idregs, ID_AA64DFR0, PMUVER) != 0xf;
}
static inline bool isar_feature_aa64_pmuv3p5(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 6 &&
- FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64DFR0, PMUVER) >= 6 &&
+ FIELD_EX64_IDREG(&id->idregs, ID_AA64DFR0, PMUVER) != 0xf;
}
static inline bool isar_feature_aa64_debugv8p2(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, DEBUGVER) >= 8;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64DFR0, DEBUGVER) >= 8;
}
static inline bool isar_feature_aa64_doublelock(const ARMISARegisters *id)
{
- return FIELD_SEX64(id->id_aa64dfr0, ID_AA64DFR0, DOUBLELOCK) >= 0;
+ return FIELD_SEX64_IDREG(&id->idregs, ID_AA64DFR0, DOUBLELOCK) >= 0;
}
static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index bcbb8b8733aa..f5fc53ac530a 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2357,8 +2357,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
cpu);
#endif
} else {
- cpu->isar.id_aa64dfr0 =
- FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
+ FIELD_DP64_IDREG(idregs, ID_AA64DFR0, PMUVER, 0);
cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
cpu->pmceid0 = 0;
cpu->pmceid1 = 0;
@@ -2418,19 +2417,15 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* try to access the non-existent system registers for them.
*/
/* FEAT_SPE (Statistical Profiling Extension) */
- cpu->isar.id_aa64dfr0 =
- FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMSVER, 0);
+ FIELD_DP64_IDREG(idregs, ID_AA64DFR0, PMSVER, 0);
/* FEAT_TRBE (Trace Buffer Extension) */
- cpu->isar.id_aa64dfr0 =
- FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEBUFFER, 0);
+ FIELD_DP64_IDREG(idregs, ID_AA64DFR0, TRACEBUFFER, 0);
/* FEAT_TRF (Self-hosted Trace Extension) */
- cpu->isar.id_aa64dfr0 =
- FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEFILT, 0);
+ FIELD_DP64_IDREG(idregs, ID_AA64DFR0, TRACEFILT, 0);
cpu->isar.id_dfr0 =
FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, TRACEFILT, 0);
/* Trace Macrocell system register access */
- cpu->isar.id_aa64dfr0 =
- FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEVER, 0);
+ FIELD_DP64_IDREG(idregs, ID_AA64DFR0, TRACEVER, 0);
cpu->isar.id_dfr0 =
FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPTRC, 0);
/* Memory mapped trace */
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index f36139ba79db..f3d694b8e2c8 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1097,8 +1097,6 @@ struct ArchCPU {
uint32_t dbgdidr;
uint32_t dbgdevid;
uint32_t dbgdevid1;
- uint64_t id_aa64dfr0;
- uint64_t id_aa64dfr1;
uint64_t id_aa64smfr0;
uint64_t reset_pmcr_el0;
IdRegMap idregs;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index fb1c50ee9007..3a1c441fbf80 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -631,7 +631,7 @@ static void aarch64_a57_initfn(Object *obj)
cpu->isar.id_isar5 = 0x00011121;
cpu->isar.id_isar6 = 0;
SET_IDREG(idregs, ID_AA64PFR0, 0x00002222);
- cpu->isar.id_aa64dfr0 = 0x10305106;
+ SET_IDREG(idregs, ID_AA64DFR0, 0x10305106);
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
SET_IDREG(idregs, ID_AA64MMFR0, 0x00001124);
cpu->isar.dbgdidr = 0x3516d000;
@@ -693,7 +693,7 @@ static void aarch64_a53_initfn(Object *obj)
cpu->isar.id_isar5 = 0x00011121;
cpu->isar.id_isar6 = 0;
SET_IDREG(idregs, ID_AA64PFR0, 0x00002222);
- cpu->isar.id_aa64dfr0 = 0x10305106;
+ SET_IDREG(idregs, ID_AA64DFR0, 0x10305106);
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
SET_IDREG(idregs, ID_AA64MMFR0, 0x00001122); /* 40 bit physical addr */
cpu->isar.dbgdidr = 0x3516d000;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 1ee415c276a8..6626695b1adf 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8933,12 +8933,12 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64dfr0 },
+ .resetvalue = GET_IDREG(idregs, ID_AA64DFR0) },
{ .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64dfr1 },
+ .resetvalue = GET_IDREG(idregs, ID_AA64DFR1) },
{ .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
diff --git a/target/arm/internals.h b/target/arm/internals.h
index e37f459af350..6de6a002edd9 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1033,7 +1033,7 @@ static inline bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
static inline int arm_num_brps(ARMCPU *cpu)
{
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
- return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1;
+ return FIELD_EX64_IDREG(&cpu->isar.idregs, ID_AA64DFR0, BRPS) + 1;
} else {
return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, BRPS) + 1;
}
@@ -1047,7 +1047,7 @@ static inline int arm_num_brps(ARMCPU *cpu)
static inline int arm_num_wrps(ARMCPU *cpu)
{
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
- return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1;
+ return FIELD_EX64_IDREG(&cpu->isar.idregs, ID_AA64DFR0, WRPS) + 1;
} else {
return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, WRPS) + 1;
}
@@ -1061,7 +1061,7 @@ static inline int arm_num_wrps(ARMCPU *cpu)
static inline int arm_num_ctx_cmps(ARMCPU *cpu)
{
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
- return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) + 1;
+ return FIELD_EX64_IDREG(&cpu->isar.idregs, ID_AA64DFR0, CTX_CMPS) + 1;
} else {
return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, CTX_CMPS) + 1;
}
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index c073758ad6c3..bfe5347e1cc9 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -346,10 +346,8 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64PFR1_EL1);
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64smfr0,
ARM64_SYS_REG(3, 0, 0, 4, 5));
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr0,
- ARM64_SYS_REG(3, 0, 0, 5, 0));
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr1,
- ARM64_SYS_REG(3, 0, 0, 5, 1));
+ err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64DFR0_EL1);
+ err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64DFR1_EL1);
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64ISAR0_EL1);
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64ISAR1_EL1);
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64ISAR2_EL1);
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 53ee612b8657..72209bd4dfc1 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -65,8 +65,8 @@ static void aarch64_a35_initfn(Object *obj)
cpu->isar.id_isar5 = 0x00011121;
SET_IDREG(idregs, ID_AA64PFR0, 0x00002222);
SET_IDREG(idregs, ID_AA64PFR1, 0);
- cpu->isar.id_aa64dfr0 = 0x10305106;
- cpu->isar.id_aa64dfr1 = 0;
+ SET_IDREG(idregs, ID_AA64DFR0, 0x10305106);
+ SET_IDREG(idregs, ID_AA64DFR1, 0);
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
SET_IDREG(idregs, ID_AA64ISAR1, 0);
SET_IDREG(idregs, ID_AA64MMFR0, 0x00101122);
@@ -219,7 +219,7 @@ static void aarch64_a55_initfn(Object *obj)
cpu->clidr = 0x82000023;
cpu->ctr = 0x84448004; /* L1Ip = VIPT */
cpu->dcz_blocksize = 4; /* 64 bytes */
- cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
+ SET_IDREG(idregs, ID_AA64DFR0, 0x0000000010305408ull);
SET_IDREG(idregs, ID_AA64ISAR0, 0x0000100010211120ull);
SET_IDREG(idregs, ID_AA64ISAR1, 0x0000000000100001ull);
SET_IDREG(idregs, ID_AA64MMFR0, 0x0000000000101122ull);
@@ -310,7 +310,7 @@ static void aarch64_a72_initfn(Object *obj)
cpu->isar.id_isar4 = 0x00011142;
cpu->isar.id_isar5 = 0x00011121;
SET_IDREG(idregs, ID_AA64PFR0, 0x00002222);
- cpu->isar.id_aa64dfr0 = 0x10305106;
+ SET_IDREG(idregs, ID_AA64DFR0, 0x10305106);
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
SET_IDREG(idregs, ID_AA64MMFR0, 0x00001124);
cpu->isar.dbgdidr = 0x3516d000;
@@ -352,7 +352,7 @@ static void aarch64_a76_initfn(Object *obj)
cpu->clidr = 0x82000023;
cpu->ctr = 0x8444C004;
cpu->dcz_blocksize = 4;
- cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
+ SET_IDREG(idregs, ID_AA64DFR0, 0x0000000010305408ull),
SET_IDREG(idregs, ID_AA64ISAR0, 0x0000100010211120ull);
SET_IDREG(idregs, ID_AA64ISAR1, 0x0000000000100001ull);
SET_IDREG(idregs, ID_AA64MMFR0, 0x0000000000101122ull);
@@ -426,8 +426,8 @@ static void aarch64_a64fx_initfn(Object *obj)
cpu->reset_sctlr = 0x30000180;
SET_IDREG(idregs, ID_AA64PFR0, 0x0000000101111111); /* No RAS Extensions */
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000000);
- cpu->isar.id_aa64dfr0 = 0x0000000010305408;
- cpu->isar.id_aa64dfr1 = 0x0000000000000000;
+ SET_IDREG(idregs, ID_AA64DFR0, 0x0000000010305408),
+ SET_IDREG(idregs, ID_AA64DFR1, 0x0000000000000000),
cpu->id_aa64afr0 = 0x0000000000000000;
cpu->id_aa64afr1 = 0x0000000000000000;
SET_IDREG(idregs, ID_AA64MMFR0, 0x0000000000001122);
@@ -600,7 +600,7 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
cpu->clidr = 0x82000023;
cpu->ctr = 0x8444c004;
cpu->dcz_blocksize = 4;
- cpu->isar.id_aa64dfr0 = 0x0000000110305408ull;
+ SET_IDREG(idregs, ID_AA64DFR0, 0x0000000110305408ull);
SET_IDREG(idregs, ID_AA64ISAR0, 0x0000100010211120ull);
SET_IDREG(idregs, ID_AA64ISAR1, 0x0000000000100001ull);
SET_IDREG(idregs, ID_AA64MMFR0, 0x0000000000101125ull);
@@ -678,8 +678,8 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
cpu->dcz_blocksize = 4;
cpu->id_aa64afr0 = 0x00000000;
cpu->id_aa64afr1 = 0x00000000;
- cpu->isar.id_aa64dfr0 = 0x000001f210305519ull;
- cpu->isar.id_aa64dfr1 = 0x00000000;
+ SET_IDREG(idregs, ID_AA64DFR0, 0x000001f210305519ull),
+ SET_IDREG(idregs, ID_AA64DFR1, 0x00000000),
SET_IDREG(idregs, ID_AA64ISAR0, 0x1011111110212120ull); /* with FEAT_RNG */
SET_IDREG(idregs, ID_AA64ISAR1, 0x0011000001211032ull);
SET_IDREG(idregs, ID_AA64MMFR0, 0x0000000000101125ull);
@@ -925,8 +925,9 @@ static void aarch64_a710_initfn(Object *obj)
SET_IDREG(idregs, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000221ull);
SET_IDREG(idregs, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */
- cpu->isar.id_aa64dfr0 = 0x000011f010305619ull;
- cpu->isar.id_aa64dfr1 = 0;
+ SET_IDREG(idregs, ID_AA64DFR0, 0x000011f010305619ull);
+ SET_IDREG(idregs, ID_AA64DFR0, 0x000011f010305619ull);
+ SET_IDREG(idregs, ID_AA64DFR1, 0);
cpu->id_aa64afr0 = 0;
cpu->id_aa64afr1 = 0;
SET_IDREG(idregs, ID_AA64ISAR0, 0x0221111110212120ull); /* with Crypto */
@@ -1027,8 +1028,8 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
SET_IDREG(idregs, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000221ull);
SET_IDREG(idregs, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */
- cpu->isar.id_aa64dfr0 = 0x000011f210305619ull;
- cpu->isar.id_aa64dfr1 = 0;
+ SET_IDREG(idregs, ID_AA64DFR0, 0x000011f210305619ull);
+ SET_IDREG(idregs, ID_AA64DFR1, 0);
cpu->id_aa64afr0 = 0;
cpu->id_aa64afr1 = 0;
SET_IDREG(idregs, ID_AA64ISAR0, 0x1221111110212120ull); /* with Crypto and FEAT_RNG */
@@ -1258,11 +1259,11 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1); /* FEAT_F64MM */
SET_IDREG(idregs, ID_AA64ZFR0, t);
- t = cpu->isar.id_aa64dfr0;
+ t = GET_IDREG(idregs, ID_AA64DFR0);
t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 10); /* FEAT_Debugv8p8 */
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 6); /* FEAT_PMUv3p5 */
t = FIELD_DP64(t, ID_AA64DFR0, HPMN0, 1); /* FEAT_HPMN0 */
- cpu->isar.id_aa64dfr0 = t;
+ SET_IDREG(idregs, ID_AA64DFR0, t);
t = cpu->isar.id_aa64smfr0;
t = FIELD_DP64(t, ID_AA64SMFR0, F32F32, 1); /* FEAT_SME */
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 08/20] arm/cpu: Store aa64smfr0 into the idregs array
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (6 preceding siblings ...)
2024-12-06 11:22 ` [PATCH RFCv2 07/20] arm/cpu: Store aa64drf0/1 " Cornelia Huck
@ 2024-12-06 11:22 ` Cornelia Huck
2024-12-06 11:22 ` [PATCH RFCv2 09/20] arm/cpu: Store id_isar0-7 " Cornelia Huck
` (15 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:22 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
target/arm/cpu-features.h | 6 +++---
target/arm/cpu.h | 1 -
target/arm/cpu64.c | 7 ++-----
target/arm/helper.c | 2 +-
target/arm/kvm.c | 3 +--
target/arm/tcg/cpu64.c | 4 ++--
6 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index 5e3c83f0cc61..5b463aee373c 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -963,17 +963,17 @@ static inline bool isar_feature_aa64_sve_f64mm(const ARMISARegisters *id)
static inline bool isar_feature_aa64_sme_f64f64(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, F64F64);
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64SMFR0, F64F64);
}
static inline bool isar_feature_aa64_sme_i16i64(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, I16I64) == 0xf;
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64SMFR0, I16I64) == 0xf;
}
static inline bool isar_feature_aa64_sme_fa64(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, FA64);
+ return FIELD_EX64_IDREG(&id->idregs, ID_AA64SMFR0, FA64);
}
/*
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index f3d694b8e2c8..612035e7c9fc 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1097,7 +1097,6 @@ struct ArchCPU {
uint32_t dbgdidr;
uint32_t dbgdevid;
uint32_t dbgdevid1;
- uint64_t id_aa64smfr0;
uint64_t reset_pmcr_el0;
IdRegMap idregs;
} isar;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 3a1c441fbf80..07240469b6f7 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -306,7 +306,7 @@ void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp)
if (vq_map == 0) {
if (!cpu_isar_feature(aa64_sme, cpu)) {
- cpu->isar.id_aa64smfr0 = 0;
+ SET_IDREG(&cpu->isar.idregs, ID_AA64SMFR0, 0);
return;
}
@@ -359,11 +359,8 @@ static bool cpu_arm_get_sme_fa64(Object *obj, Error **errp)
static void cpu_arm_set_sme_fa64(Object *obj, bool value, Error **errp)
{
ARMCPU *cpu = ARM_CPU(obj);
- uint64_t t;
- t = cpu->isar.id_aa64smfr0;
- t = FIELD_DP64(t, ID_AA64SMFR0, FA64, value);
- cpu->isar.id_aa64smfr0 = t;
+ FIELD_DP64_IDREG(&cpu->isar.idregs, ID_AA64SMFR0, FA64, value);
}
#ifdef CONFIG_USER_ONLY
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 6626695b1adf..46d18a640cec 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8918,7 +8918,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64smfr0 },
+ .resetvalue = GET_IDREG(idregs, ID_AA64SMFR0)},
{ .name = "ID_AA64PFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index bfe5347e1cc9..82b8c39732ed 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -344,8 +344,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
err = 0;
} else {
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64PFR1_EL1);
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64smfr0,
- ARM64_SYS_REG(3, 0, 0, 4, 5));
+ err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64SMFR0_EL1);
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64DFR0_EL1);
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64DFR1_EL1);
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64ISAR0_EL1);
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 72209bd4dfc1..e228a545db2c 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -1265,7 +1265,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64DFR0, HPMN0, 1); /* FEAT_HPMN0 */
SET_IDREG(idregs, ID_AA64DFR0, t);
- t = cpu->isar.id_aa64smfr0;
+ t = GET_IDREG(idregs, ID_AA64SMFR0);
t = FIELD_DP64(t, ID_AA64SMFR0, F32F32, 1); /* FEAT_SME */
t = FIELD_DP64(t, ID_AA64SMFR0, B16F32, 1); /* FEAT_SME */
t = FIELD_DP64(t, ID_AA64SMFR0, F16F32, 1); /* FEAT_SME */
@@ -1273,7 +1273,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64SMFR0, F64F64, 1); /* FEAT_SME_F64F64 */
t = FIELD_DP64(t, ID_AA64SMFR0, I16I64, 0xf); /* FEAT_SME_I16I64 */
t = FIELD_DP64(t, ID_AA64SMFR0, FA64, 1); /* FEAT_SME_FA64 */
- cpu->isar.id_aa64smfr0 = t;
+ SET_IDREG(idregs, ID_AA64SMFR0, t);
/* Replicate the same data to the 32-bit id registers. */
aa32_max_features(cpu);
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 09/20] arm/cpu: Store id_isar0-7 into the idregs array
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (7 preceding siblings ...)
2024-12-06 11:22 ` [PATCH RFCv2 08/20] arm/cpu: Store aa64smfr0 " Cornelia Huck
@ 2024-12-06 11:22 ` Cornelia Huck
2024-12-06 11:22 ` [PATCH RFCv2 10/20] arm/cpu: Store id_mfr0/1 " Cornelia Huck
` (14 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:22 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
hw/intc/armv7m_nvic.c | 12 ++--
target/arm/cpu-features.h | 36 +++++-----
target/arm/cpu.c | 24 +++----
target/arm/cpu.h | 14 ++--
target/arm/cpu64.c | 28 ++++----
target/arm/helper.c | 14 ++--
target/arm/kvm.c | 34 +++++----
target/arm/tcg/cpu-v7m.c | 90 +++++++++++++-----------
target/arm/tcg/cpu32.c | 143 ++++++++++++++++++++------------------
target/arm/tcg/cpu64.c | 108 ++++++++++++++--------------
10 files changed, 262 insertions(+), 241 deletions(-)
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 98f3cf59bcaa..a8e1f9a56ae7 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1303,32 +1303,32 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_isar0;
+ return GET_IDREG(&cpu->isar.idregs, ID_ISAR0);
case 0xd64: /* ISAR1. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_isar1;
+ return GET_IDREG(&cpu->isar.idregs, ID_ISAR1);
case 0xd68: /* ISAR2. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_isar2;
+ return GET_IDREG(&cpu->isar.idregs, ID_ISAR2);
case 0xd6c: /* ISAR3. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_isar3;
+ return GET_IDREG(&cpu->isar.idregs, ID_ISAR3);
case 0xd70: /* ISAR4. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_isar4;
+ return GET_IDREG(&cpu->isar.idregs, ID_ISAR4);
case 0xd74: /* ISAR5. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_isar5;
+ return GET_IDREG(&cpu->isar.idregs, ID_ISAR5);
case 0xd78: /* CLIDR */
return cpu->clidr;
case 0xd7c: /* CTR */
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index 5b463aee373c..1028d1c64c98 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -45,93 +45,93 @@
*/
static inline bool isar_feature_aa32_thumb_div(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR0, DIVIDE) != 0;
}
static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR0, DIVIDE) > 1;
}
static inline bool isar_feature_aa32_lob(const ARMISARegisters *id)
{
/* (M-profile) low-overhead loops and branch future */
- return FIELD_EX32(id->id_isar0, ID_ISAR0, CMPBRANCH) >= 3;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR0, CMPBRANCH) >= 3;
}
static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR1, JAZELLE) != 0;
}
static inline bool isar_feature_aa32_aes(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR5, AES) != 0;
}
static inline bool isar_feature_aa32_pmull(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) > 1;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR5, AES) > 1;
}
static inline bool isar_feature_aa32_sha1(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA1) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR5, SHA1) != 0;
}
static inline bool isar_feature_aa32_sha2(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA2) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR5, SHA2) != 0;
}
static inline bool isar_feature_aa32_crc32(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar5, ID_ISAR5, CRC32) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR5, CRC32) != 0;
}
static inline bool isar_feature_aa32_rdm(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar5, ID_ISAR5, RDM) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR5, RDM) != 0;
}
static inline bool isar_feature_aa32_vcma(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar5, ID_ISAR5, VCMA) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR5, VCMA) != 0;
}
static inline bool isar_feature_aa32_jscvt(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar6, ID_ISAR6, JSCVT) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR6, JSCVT) != 0;
}
static inline bool isar_feature_aa32_dp(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR6, DP) != 0;
}
static inline bool isar_feature_aa32_fhm(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar6, ID_ISAR6, FHM) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR6, FHM) != 0;
}
static inline bool isar_feature_aa32_sb(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar6, ID_ISAR6, SB) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR6, SB) != 0;
}
static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR6, SPECRES) != 0;
}
static inline bool isar_feature_aa32_bf16(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar6, ID_ISAR6, BF16) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR6, BF16) != 0;
}
static inline bool isar_feature_aa32_i8mm(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_isar6, ID_ISAR6, I8MM) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_ISAR6, I8MM) != 0;
}
static inline bool isar_feature_aa32_ras(const ARMISARegisters *id)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index f5fc53ac530a..1f03aca54765 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2136,10 +2136,10 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
FIELD_DP64_IDREG(idregs, ID_AA64PFR0, FP, 0xf);
- u = cpu->isar.id_isar6;
+ u = GET_IDREG(idregs, ID_ISAR6);
u = FIELD_DP32(u, ID_ISAR6, JSCVT, 0);
u = FIELD_DP32(u, ID_ISAR6, BF16, 0);
- cpu->isar.id_isar6 = u;
+ SET_IDREG(idregs, ID_ISAR6, u);
u = cpu->isar.mvfr0;
u = FIELD_DP32(u, MVFR0, FPSP, 0);
@@ -2191,20 +2191,20 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
FIELD_DP64_IDREG(idregs, ID_AA64PFR0, ADVSIMD, 0xf);
- u = cpu->isar.id_isar5;
+ u = GET_IDREG(idregs, ID_ISAR5);
u = FIELD_DP32(u, ID_ISAR5, AES, 0);
u = FIELD_DP32(u, ID_ISAR5, SHA1, 0);
u = FIELD_DP32(u, ID_ISAR5, SHA2, 0);
u = FIELD_DP32(u, ID_ISAR5, RDM, 0);
u = FIELD_DP32(u, ID_ISAR5, VCMA, 0);
- cpu->isar.id_isar5 = u;
+ SET_IDREG(idregs, ID_ISAR5, u);
- u = cpu->isar.id_isar6;
+ u = GET_IDREG(idregs, ID_ISAR6);
u = FIELD_DP32(u, ID_ISAR6, DP, 0);
u = FIELD_DP32(u, ID_ISAR6, FHM, 0);
u = FIELD_DP32(u, ID_ISAR6, BF16, 0);
u = FIELD_DP32(u, ID_ISAR6, I8MM, 0);
- cpu->isar.id_isar6 = u;
+ SET_IDREG(idregs, ID_ISAR6, u);
if (!arm_feature(env, ARM_FEATURE_M)) {
u = cpu->isar.mvfr1;
@@ -2242,19 +2242,17 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
unset_feature(env, ARM_FEATURE_THUMB_DSP);
- u = cpu->isar.id_isar1;
- u = FIELD_DP32(u, ID_ISAR1, EXTEND, 1);
- cpu->isar.id_isar1 = u;
+ FIELD_DP32_IDREG(idregs, ID_ISAR1, EXTEND, 1);
- u = cpu->isar.id_isar2;
+ u = GET_IDREG(idregs, ID_ISAR2);
u = FIELD_DP32(u, ID_ISAR2, MULTU, 1);
u = FIELD_DP32(u, ID_ISAR2, MULTS, 1);
- cpu->isar.id_isar2 = u;
+ SET_IDREG(idregs, ID_ISAR2, u);
- u = cpu->isar.id_isar3;
+ u = GET_IDREG(idregs, ID_ISAR3);
u = FIELD_DP32(u, ID_ISAR3, SIMD, 1);
u = FIELD_DP32(u, ID_ISAR3, SATURATE, 0);
- cpu->isar.id_isar3 = u;
+ SET_IDREG(idregs, ID_ISAR3, u);
}
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 612035e7c9fc..bd12cdad415e 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -878,6 +878,13 @@ regval = FIELD_DP64(regval, REG, FIELD, VALUE); \
_set_idreg(MAP, SYS_ ## REG ## _EL1, regval); \
}
+#define FIELD_DP32_IDREG(MAP, REG, FIELD, VALUE) \
+{ \
+uint64_t regval = _get_idreg(MAP, SYS_ ## REG ## _EL1); \
+regval = FIELD_DP32(regval, REG, FIELD, VALUE); \
+_set_idreg(MAP, SYS_ ## REG ## _EL1, regval); \
+}
+
#define FIELD_EX64_IDREG(MAP, REG, FIELD) \
FIELD_EX64(_get_idreg(MAP, SYS_ ## REG ## _EL1), REG, FIELD) \
@@ -1073,13 +1080,6 @@ struct ArchCPU {
* field by reading the value from the KVM vCPU.
*/
struct ARMISARegisters {
- uint32_t id_isar0;
- uint32_t id_isar1;
- uint32_t id_isar2;
- uint32_t id_isar3;
- uint32_t id_isar4;
- uint32_t id_isar5;
- uint32_t id_isar6;
uint32_t id_mmfr0;
uint32_t id_mmfr1;
uint32_t id_mmfr2;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 07240469b6f7..eaf4235b2252 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -620,13 +620,13 @@ static void aarch64_a57_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x40000000;
cpu->isar.id_mmfr2 = 0x01260000;
cpu->isar.id_mmfr3 = 0x02102211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00011142;
- cpu->isar.id_isar5 = 0x00011121;
- cpu->isar.id_isar6 = 0;
+ SET_IDREG(idregs, ID_ISAR0, 0x02101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232042);
+ SET_IDREG(idregs, ID_ISAR3, 0x01112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x00011142);
+ SET_IDREG(idregs, ID_ISAR5, 0x00011121);
+ SET_IDREG(idregs, ID_ISAR6, 0);
SET_IDREG(idregs, ID_AA64PFR0, 0x00002222);
SET_IDREG(idregs, ID_AA64DFR0, 0x10305106);
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
@@ -682,13 +682,13 @@ static void aarch64_a53_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x40000000;
cpu->isar.id_mmfr2 = 0x01260000;
cpu->isar.id_mmfr3 = 0x02102211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00011142;
- cpu->isar.id_isar5 = 0x00011121;
- cpu->isar.id_isar6 = 0;
+ SET_IDREG(idregs, ID_ISAR0, 0x02101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232042);
+ SET_IDREG(idregs, ID_ISAR3, 0x01112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x00011142);
+ SET_IDREG(idregs, ID_ISAR5, 0x00011121);
+ SET_IDREG(idregs, ID_ISAR6, 0);
SET_IDREG(idregs, ID_AA64PFR0, 0x00002222);
SET_IDREG(idregs, ID_AA64DFR0, 0x10305106);
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 46d18a640cec..5891cdb1681e 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8796,32 +8796,32 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_isar0 },
+ .resetvalue = GET_IDREG(idregs, ID_ISAR0)},
{ .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_isar1 },
+ .resetvalue = GET_IDREG(idregs, ID_ISAR1)},
{ .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_isar2 },
+ .resetvalue = GET_IDREG(idregs, ID_ISAR2)},
{ .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_isar3 },
+ .resetvalue = GET_IDREG(idregs, ID_ISAR3) },
{ .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_isar4 },
+ .resetvalue = GET_IDREG(idregs, ID_ISAR4) },
{ .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_isar5 },
+ .resetvalue = GET_IDREG(idregs, ID_ISAR5) },
{ .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
@@ -8831,7 +8831,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_isar6 },
+ .resetvalue = GET_IDREG(idregs, ID_ISAR6) },
};
define_arm_cp_regs(cpu, v6_idregs);
define_arm_cp_regs(cpu, v6_cp_reginfo);
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 82b8c39732ed..0a9a27c046f4 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -248,6 +248,18 @@ static bool kvm_arm_pauth_supported(void)
kvm_check_extension(kvm_state, KVM_CAP_ARM_PTRAUTH_GENERIC));
}
+/* read a 32b sysreg value and store it in the idregs */
+static int get_host_cpu_reg32(int fd, ARMHostCPUFeatures *ahcf, ARMSysReg sr)
+{
+ int index = KVM_ARM_FEATURE_ID_RANGE_IDX(sr.op0, sr.op1, sr.crn, sr.crm, sr.op2);
+ uint64_t *reg = &ahcf->isar.idregs.regs[index];
+ int ret;
+
+ ret = read_sys_reg32(fd, (uint32_t *)reg,
+ ARM64_SYS_REG(sr.op0, sr.op1, sr.crn, sr.crm, sr.op2));
+ return ret;
+}
+
/* read a 64b sysreg value and store it in the idregs */
static int get_host_cpu_reg64(int fd, ARMHostCPUFeatures *ahcf, ARMSysReg sr)
{
@@ -260,6 +272,7 @@ static int get_host_cpu_reg64(int fd, ARMHostCPUFeatures *ahcf, ARMSysReg sr)
return ret;
}
+
static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
{
/* Identify the feature bits corresponding to the host CPU, and
@@ -374,22 +387,15 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
ARM64_SYS_REG(3, 0, 0, 1, 6));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr3,
ARM64_SYS_REG(3, 0, 0, 1, 7));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0,
- ARM64_SYS_REG(3, 0, 0, 2, 0));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar1,
- ARM64_SYS_REG(3, 0, 0, 2, 1));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar2,
- ARM64_SYS_REG(3, 0, 0, 2, 2));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar3,
- ARM64_SYS_REG(3, 0, 0, 2, 3));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar4,
- ARM64_SYS_REG(3, 0, 0, 2, 4));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar5,
- ARM64_SYS_REG(3, 0, 0, 2, 5));
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_ISAR0_EL1);
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_ISAR1_EL1);
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_ISAR2_EL1);
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_ISAR3_EL1);
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_ISAR4_EL1);
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_ISAR5_EL1);
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_ISAR6_EL1);
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr4,
ARM64_SYS_REG(3, 0, 0, 2, 6));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6,
- ARM64_SYS_REG(3, 0, 0, 2, 7));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0,
ARM64_SYS_REG(3, 0, 0, 3, 0));
diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
index 58e54578d67d..ea7d0237f442 100644
--- a/target/arm/tcg/cpu-v7m.c
+++ b/target/arm/tcg/cpu-v7m.c
@@ -46,6 +46,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
static void cortex_m0_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
set_feature(&cpu->env, ARM_FEATURE_V6);
set_feature(&cpu->env, ARM_FEATURE_M);
@@ -67,18 +68,19 @@ static void cortex_m0_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x00000000;
cpu->isar.id_mmfr3 = 0x00000000;
- cpu->isar.id_isar0 = 0x01141110;
- cpu->isar.id_isar1 = 0x02111000;
- cpu->isar.id_isar2 = 0x21112231;
- cpu->isar.id_isar3 = 0x01111110;
- cpu->isar.id_isar4 = 0x01310102;
- cpu->isar.id_isar5 = 0x00000000;
- cpu->isar.id_isar6 = 0x00000000;
+ SET_IDREG(idregs, ID_ISAR0, 0x01141110);
+ SET_IDREG(idregs, ID_ISAR1, 0x02111000);
+ SET_IDREG(idregs, ID_ISAR2, 0x21112231);
+ SET_IDREG(idregs, ID_ISAR3, 0x01111110);
+ SET_IDREG(idregs, ID_ISAR4, 0x01310102);
+ SET_IDREG(idregs, ID_ISAR5, 0x00000000);
+ SET_IDREG(idregs, ID_ISAR6, 0x00000000);
}
static void cortex_m3_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M);
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
@@ -92,18 +94,19 @@ static void cortex_m3_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x00000000;
cpu->isar.id_mmfr3 = 0x00000000;
- cpu->isar.id_isar0 = 0x01141110;
- cpu->isar.id_isar1 = 0x02111000;
- cpu->isar.id_isar2 = 0x21112231;
- cpu->isar.id_isar3 = 0x01111110;
- cpu->isar.id_isar4 = 0x01310102;
- cpu->isar.id_isar5 = 0x00000000;
- cpu->isar.id_isar6 = 0x00000000;
+ SET_IDREG(idregs, ID_ISAR0, 0x01141110);
+ SET_IDREG(idregs, ID_ISAR1, 0x02111000);
+ SET_IDREG(idregs, ID_ISAR2, 0x21112231);
+ SET_IDREG(idregs, ID_ISAR3, 0x01111110);
+ SET_IDREG(idregs, ID_ISAR4, 0x01310102);
+ SET_IDREG(idregs, ID_ISAR5, 0x00000000);
+ SET_IDREG(idregs, ID_ISAR6, 0x00000000);
}
static void cortex_m4_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M);
@@ -122,18 +125,19 @@ static void cortex_m4_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x00000000;
cpu->isar.id_mmfr3 = 0x00000000;
- cpu->isar.id_isar0 = 0x01141110;
- cpu->isar.id_isar1 = 0x02111000;
- cpu->isar.id_isar2 = 0x21112231;
- cpu->isar.id_isar3 = 0x01111110;
- cpu->isar.id_isar4 = 0x01310102;
- cpu->isar.id_isar5 = 0x00000000;
- cpu->isar.id_isar6 = 0x00000000;
+ SET_IDREG(idregs, ID_ISAR0, 0x01141110);
+ SET_IDREG(idregs, ID_ISAR1, 0x02111000);
+ SET_IDREG(idregs, ID_ISAR2, 0x21112231);
+ SET_IDREG(idregs, ID_ISAR3, 0x01111110);
+ SET_IDREG(idregs, ID_ISAR4, 0x01310102);
+ SET_IDREG(idregs, ID_ISAR5, 0x00000000);
+ SET_IDREG(idregs, ID_ISAR6, 0x00000000);
}
static void cortex_m7_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M);
@@ -152,18 +156,19 @@ static void cortex_m7_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x01000000;
cpu->isar.id_mmfr3 = 0x00000000;
- cpu->isar.id_isar0 = 0x01101110;
- cpu->isar.id_isar1 = 0x02112000;
- cpu->isar.id_isar2 = 0x20232231;
- cpu->isar.id_isar3 = 0x01111131;
- cpu->isar.id_isar4 = 0x01310132;
- cpu->isar.id_isar5 = 0x00000000;
- cpu->isar.id_isar6 = 0x00000000;
+ SET_IDREG(idregs, ID_ISAR0, 0x01101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x02112000);
+ SET_IDREG(idregs, ID_ISAR2, 0x20232231);
+ SET_IDREG(idregs, ID_ISAR3, 0x01111131);
+ SET_IDREG(idregs, ID_ISAR4, 0x01310132);
+ SET_IDREG(idregs, ID_ISAR5, 0x00000000);
+ SET_IDREG(idregs, ID_ISAR6, 0x00000000);
}
static void cortex_m33_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_M);
@@ -184,13 +189,13 @@ static void cortex_m33_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x01000000;
cpu->isar.id_mmfr3 = 0x00000000;
- cpu->isar.id_isar0 = 0x01101110;
- cpu->isar.id_isar1 = 0x02212000;
- cpu->isar.id_isar2 = 0x20232232;
- cpu->isar.id_isar3 = 0x01111131;
- cpu->isar.id_isar4 = 0x01310132;
- cpu->isar.id_isar5 = 0x00000000;
- cpu->isar.id_isar6 = 0x00000000;
+ SET_IDREG(idregs, ID_ISAR0, 0x01101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x02212000);
+ SET_IDREG(idregs, ID_ISAR2, 0x20232232);
+ SET_IDREG(idregs, ID_ISAR3, 0x01111131);
+ SET_IDREG(idregs, ID_ISAR4, 0x01310132);
+ SET_IDREG(idregs, ID_ISAR5, 0x00000000);
+ SET_IDREG(idregs, ID_ISAR6, 0x00000000);
cpu->clidr = 0x00000000;
cpu->ctr = 0x8000c000;
}
@@ -198,6 +203,7 @@ static void cortex_m33_initfn(Object *obj)
static void cortex_m55_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_V8_1M);
@@ -221,13 +227,13 @@ static void cortex_m55_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x01000000;
cpu->isar.id_mmfr3 = 0x00000011;
- cpu->isar.id_isar0 = 0x01103110;
- cpu->isar.id_isar1 = 0x02212000;
- cpu->isar.id_isar2 = 0x20232232;
- cpu->isar.id_isar3 = 0x01111131;
- cpu->isar.id_isar4 = 0x01310132;
- cpu->isar.id_isar5 = 0x00000000;
- cpu->isar.id_isar6 = 0x00000000;
+ SET_IDREG(idregs, ID_ISAR0, 0x01103110);
+ SET_IDREG(idregs, ID_ISAR1, 0x02212000);
+ SET_IDREG(idregs, ID_ISAR2, 0x20232232);
+ SET_IDREG(idregs, ID_ISAR3, 0x01111131);
+ SET_IDREG(idregs, ID_ISAR4, 0x01310132);
+ SET_IDREG(idregs, ID_ISAR5, 0x00000000);
+ SET_IDREG(idregs, ID_ISAR6, 0x00000000);
cpu->clidr = 0x00000000; /* caches not implemented */
cpu->ctr = 0x8303c003;
}
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
index 2ad218252553..3bb1b6276881 100644
--- a/target/arm/tcg/cpu32.c
+++ b/target/arm/tcg/cpu32.c
@@ -25,16 +25,16 @@ void aa32_max_features(ARMCPU *cpu)
uint32_t t;
/* Add additional features supported by QEMU */
- t = cpu->isar.id_isar5;
+ t = GET_IDREG(&cpu->isar.idregs, ID_ISAR5);
t = FIELD_DP32(t, ID_ISAR5, AES, 2); /* FEAT_PMULL */
t = FIELD_DP32(t, ID_ISAR5, SHA1, 1); /* FEAT_SHA1 */
t = FIELD_DP32(t, ID_ISAR5, SHA2, 1); /* FEAT_SHA256 */
t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
t = FIELD_DP32(t, ID_ISAR5, RDM, 1); /* FEAT_RDM */
t = FIELD_DP32(t, ID_ISAR5, VCMA, 1); /* FEAT_FCMA */
- cpu->isar.id_isar5 = t;
+ SET_IDREG(&cpu->isar.idregs, ID_ISAR5, t);
- t = cpu->isar.id_isar6;
+ t = GET_IDREG(&cpu->isar.idregs, ID_ISAR6);
t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1); /* FEAT_JSCVT */
t = FIELD_DP32(t, ID_ISAR6, DP, 1); /* Feat_DotProd */
t = FIELD_DP32(t, ID_ISAR6, FHM, 1); /* FEAT_FHM */
@@ -42,7 +42,7 @@ void aa32_max_features(ARMCPU *cpu)
t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1); /* FEAT_SPECRES */
t = FIELD_DP32(t, ID_ISAR6, BF16, 1); /* FEAT_AA32BF16 */
t = FIELD_DP32(t, ID_ISAR6, I8MM, 1); /* FEAT_AA32I8MM */
- cpu->isar.id_isar6 = t;
+ SET_IDREG(&cpu->isar.idregs, ID_ISAR6, t);
t = cpu->isar.mvfr1;
t = FIELD_DP32(t, MVFR1, FPHP, 3); /* FEAT_FP16 */
@@ -140,7 +140,7 @@ static void arm926_initfn(Object *obj)
* ARMv5 does not have the ID_ISAR registers, but we can still
* set the field to indicate Jazelle support within QEMU.
*/
- cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
+ FIELD_DP32_IDREG(&cpu->isar.idregs, ID_ISAR1, JAZELLE, 1);
/*
* Similarly, we need to set MVFR0 fields to enable vfp and short vector
* support even though ARMv5 doesn't have this register.
@@ -182,7 +182,7 @@ static void arm1026_initfn(Object *obj)
* ARMv5 does not have the ID_ISAR registers, but we can still
* set the field to indicate Jazelle support within QEMU.
*/
- cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
+ FIELD_DP32_IDREG(&cpu->isar.idregs, ID_ISAR1, JAZELLE, 1);
/*
* Similarly, we need to set MVFR0 fields to enable vfp and short vector
* support even though ARMv5 doesn't have this register.
@@ -206,6 +206,7 @@ static void arm1026_initfn(Object *obj)
static void arm1136_r2_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
/*
* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an
* older core than plain "arm1136". In particular this does not
@@ -233,17 +234,18 @@ static void arm1136_r2_initfn(Object *obj)
cpu->isar.id_mmfr0 = 0x01130003;
cpu->isar.id_mmfr1 = 0x10030302;
cpu->isar.id_mmfr2 = 0x01222110;
- cpu->isar.id_isar0 = 0x00140011;
- cpu->isar.id_isar1 = 0x12002111;
- cpu->isar.id_isar2 = 0x11231111;
- cpu->isar.id_isar3 = 0x01102131;
- cpu->isar.id_isar4 = 0x141;
+ SET_IDREG(idregs, ID_ISAR0, 0x00140011);
+ SET_IDREG(idregs, ID_ISAR1, 0x12002111);
+ SET_IDREG(idregs, ID_ISAR2, 0x11231111);
+ SET_IDREG(idregs, ID_ISAR3, 0x01102131);
+ SET_IDREG(idregs, ID_ISAR4, 0x141);
cpu->reset_auxcr = 7;
}
static void arm1136_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,arm1136";
set_feature(&cpu->env, ARM_FEATURE_V6K);
@@ -264,17 +266,18 @@ static void arm1136_initfn(Object *obj)
cpu->isar.id_mmfr0 = 0x01130003;
cpu->isar.id_mmfr1 = 0x10030302;
cpu->isar.id_mmfr2 = 0x01222110;
- cpu->isar.id_isar0 = 0x00140011;
- cpu->isar.id_isar1 = 0x12002111;
- cpu->isar.id_isar2 = 0x11231111;
- cpu->isar.id_isar3 = 0x01102131;
- cpu->isar.id_isar4 = 0x141;
+ SET_IDREG(idregs, ID_ISAR0, 0x00140011);
+ SET_IDREG(idregs, ID_ISAR1, 0x12002111);
+ SET_IDREG(idregs, ID_ISAR2, 0x11231111);
+ SET_IDREG(idregs, ID_ISAR3, 0x01102131);
+ SET_IDREG(idregs, ID_ISAR4, 0x141);
cpu->reset_auxcr = 7;
}
static void arm1176_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,arm1176";
set_feature(&cpu->env, ARM_FEATURE_V6K);
@@ -296,17 +299,18 @@ static void arm1176_initfn(Object *obj)
cpu->isar.id_mmfr0 = 0x01130003;
cpu->isar.id_mmfr1 = 0x10030302;
cpu->isar.id_mmfr2 = 0x01222100;
- cpu->isar.id_isar0 = 0x0140011;
- cpu->isar.id_isar1 = 0x12002111;
- cpu->isar.id_isar2 = 0x11231121;
- cpu->isar.id_isar3 = 0x01102131;
- cpu->isar.id_isar4 = 0x01141;
+ SET_IDREG(idregs, ID_ISAR0, 0x0140011);
+ SET_IDREG(idregs, ID_ISAR1, 0x12002111);
+ SET_IDREG(idregs, ID_ISAR2, 0x11231121);
+ SET_IDREG(idregs, ID_ISAR3, 0x01102131);
+ SET_IDREG(idregs, ID_ISAR4, 0x01141);
cpu->reset_auxcr = 7;
}
static void arm11mpcore_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,arm11mpcore";
set_feature(&cpu->env, ARM_FEATURE_V6K);
@@ -325,11 +329,11 @@ static void arm11mpcore_initfn(Object *obj)
cpu->isar.id_mmfr0 = 0x01100103;
cpu->isar.id_mmfr1 = 0x10020302;
cpu->isar.id_mmfr2 = 0x01222000;
- cpu->isar.id_isar0 = 0x00100011;
- cpu->isar.id_isar1 = 0x12002111;
- cpu->isar.id_isar2 = 0x11221011;
- cpu->isar.id_isar3 = 0x01102131;
- cpu->isar.id_isar4 = 0x141;
+ SET_IDREG(idregs, ID_ISAR0, 0x00100011);
+ SET_IDREG(idregs, ID_ISAR1, 0x12002111);
+ SET_IDREG(idregs, ID_ISAR2, 0x11221011);
+ SET_IDREG(idregs, ID_ISAR3, 0x01102131);
+ SET_IDREG(idregs, ID_ISAR4, 0x141);
cpu->reset_auxcr = 1;
}
@@ -343,6 +347,7 @@ static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
static void cortex_a8_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,cortex-a8";
set_feature(&cpu->env, ARM_FEATURE_V7);
@@ -365,11 +370,11 @@ static void cortex_a8_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x20000000;
cpu->isar.id_mmfr2 = 0x01202000;
cpu->isar.id_mmfr3 = 0x11;
- cpu->isar.id_isar0 = 0x00101111;
- cpu->isar.id_isar1 = 0x12112111;
- cpu->isar.id_isar2 = 0x21232031;
- cpu->isar.id_isar3 = 0x11112131;
- cpu->isar.id_isar4 = 0x00111142;
+ SET_IDREG(idregs, ID_ISAR0, 0x00101111);
+ SET_IDREG(idregs, ID_ISAR1, 0x12112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232031);
+ SET_IDREG(idregs, ID_ISAR3, 0x11112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x00111142);
cpu->isar.dbgdidr = 0x15141000;
cpu->clidr = (1 << 27) | (2 << 24) | 3;
cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
@@ -412,6 +417,7 @@ static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
static void cortex_a9_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,cortex-a9";
set_feature(&cpu->env, ARM_FEATURE_V7);
@@ -440,11 +446,11 @@ static void cortex_a9_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x20000000;
cpu->isar.id_mmfr2 = 0x01230000;
cpu->isar.id_mmfr3 = 0x00002111;
- cpu->isar.id_isar0 = 0x00101111;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232041;
- cpu->isar.id_isar3 = 0x11112131;
- cpu->isar.id_isar4 = 0x00111142;
+ SET_IDREG(idregs, ID_ISAR0, 0x00101111);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232041);
+ SET_IDREG(idregs, ID_ISAR3, 0x11112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x00111142);
cpu->isar.dbgdidr = 0x35141000;
cpu->clidr = (1 << 27) | (1 << 24) | 3;
cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */
@@ -479,6 +485,7 @@ static const ARMCPRegInfo cortexa15_cp_reginfo[] = {
static void cortex_a7_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,cortex-a7";
set_feature(&cpu->env, ARM_FEATURE_V7VE);
@@ -509,11 +516,11 @@ static void cortex_a7_initfn(Object *obj)
* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
* table 4-41 gives 0x02101110, which includes the arm div insns.
*/
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232041;
- cpu->isar.id_isar3 = 0x11112131;
- cpu->isar.id_isar4 = 0x10011142;
+ SET_IDREG(idregs, ID_ISAR0, 0x02101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232041);
+ SET_IDREG(idregs, ID_ISAR3, 0x11112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x10011142);
cpu->isar.dbgdidr = 0x3515f005;
cpu->isar.dbgdevid = 0x01110f13;
cpu->isar.dbgdevid1 = 0x1;
@@ -528,6 +535,7 @@ static void cortex_a7_initfn(Object *obj)
static void cortex_a15_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
cpu->dtb_compatible = "arm,cortex-a15";
set_feature(&cpu->env, ARM_FEATURE_V7VE);
@@ -556,11 +564,11 @@ static void cortex_a15_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x20000000;
cpu->isar.id_mmfr2 = 0x01240000;
cpu->isar.id_mmfr3 = 0x02102211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232041;
- cpu->isar.id_isar3 = 0x11112131;
- cpu->isar.id_isar4 = 0x10011142;
+ SET_IDREG(idregs, ID_ISAR0, 0x02101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232041);
+ SET_IDREG(idregs, ID_ISAR3, 0x11112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x10011142);
cpu->isar.dbgdidr = 0x3515f021;
cpu->isar.dbgdevid = 0x01110f13;
cpu->isar.dbgdevid1 = 0x0;
@@ -585,6 +593,7 @@ static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
static void cortex_r5_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_V7MP);
@@ -599,13 +608,13 @@ static void cortex_r5_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x01200000;
cpu->isar.id_mmfr3 = 0x0211;
- cpu->isar.id_isar0 = 0x02101111;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232141;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x0010142;
- cpu->isar.id_isar5 = 0x0;
- cpu->isar.id_isar6 = 0x0;
+ SET_IDREG(idregs, ID_ISAR0, 0x02101111);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232141);
+ SET_IDREG(idregs, ID_ISAR3, 0x01112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x0010142);
+ SET_IDREG(idregs, ID_ISAR5, 0x21232141);
+ SET_IDREG(idregs, ID_ISAR6, 0x0);
cpu->mp_is_up = true;
cpu->pmsav7_dregion = 16;
cpu->isar.reset_pmcr_el0 = 0x41151800;
@@ -720,6 +729,7 @@ static const ARMCPRegInfo cortex_r52_cp_reginfo[] = {
static void cortex_r52_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_EL2);
@@ -746,12 +756,12 @@ static void cortex_r52_initfn(Object *obj)
cpu->isar.id_mmfr2 = 0x01200000;
cpu->isar.id_mmfr3 = 0xf0102211;
cpu->isar.id_mmfr4 = 0x00000010;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232142;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00010142;
- cpu->isar.id_isar5 = 0x00010001;
+ SET_IDREG(idregs, ID_ISAR0, 0x02101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232142);
+ SET_IDREG(idregs, ID_ISAR3, 0x01112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x00010142);
+ SET_IDREG(idregs, ID_ISAR5, 0x00010001);
cpu->isar.dbgdidr = 0x77168000;
cpu->clidr = (1 << 27) | (1 << 24) | 0x3;
cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
@@ -949,6 +959,7 @@ static void pxa270c5_initfn(Object *obj)
static void arm_max_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
/* aarch64_a57_initfn, advertising none of the aarch64 features */
cpu->dtb_compatible = "arm,cortex-a57";
@@ -976,13 +987,13 @@ static void arm_max_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x40000000;
cpu->isar.id_mmfr2 = 0x01260000;
cpu->isar.id_mmfr3 = 0x02102211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00011142;
- cpu->isar.id_isar5 = 0x00011121;
- cpu->isar.id_isar6 = 0;
+ SET_IDREG(idregs, ID_ISAR0, 0x02101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232042);
+ SET_IDREG(idregs, ID_ISAR3, 0x01112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x00011142);
+ SET_IDREG(idregs, ID_ISAR5, 0x00011121);
+ SET_IDREG(idregs, ID_ISAR6, 0);
cpu->isar.reset_pmcr_el0 = 0x41013000;
cpu->clidr = 0x0a200023;
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index e228a545db2c..9bca36093006 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -57,12 +57,12 @@ static void aarch64_a35_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x40000000;
cpu->isar.id_mmfr2 = 0x01260000;
cpu->isar.id_mmfr3 = 0x02102211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00011142;
- cpu->isar.id_isar5 = 0x00011121;
+ SET_IDREG(idregs, ID_ISAR0, 0x02101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232042);
+ SET_IDREG(idregs, ID_ISAR3, 0x01112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x00011142);
+ SET_IDREG(idregs, ID_ISAR5, 0x00011121);
SET_IDREG(idregs, ID_AA64PFR0, 0x00002222);
SET_IDREG(idregs, ID_AA64PFR1, 0);
SET_IDREG(idregs, ID_AA64DFR0, 0x10305106);
@@ -229,13 +229,13 @@ static void aarch64_a55_initfn(Object *obj)
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000010ull);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_dfr0 = 0x04010088;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00011142;
- cpu->isar.id_isar5 = 0x01011121;
- cpu->isar.id_isar6 = 0x00000010;
+ SET_IDREG(idregs, ID_ISAR0, 0x02101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232042);
+ SET_IDREG(idregs, ID_ISAR3, 0x01112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x00011142);
+ SET_IDREG(idregs, ID_ISAR5, 0x01011121);
+ SET_IDREG(idregs, ID_ISAR6, 0x00000010);
cpu->isar.id_mmfr0 = 0x10201105;
cpu->isar.id_mmfr1 = 0x40000000;
cpu->isar.id_mmfr2 = 0x01260000;
@@ -303,12 +303,12 @@ static void aarch64_a72_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x40000000;
cpu->isar.id_mmfr2 = 0x01260000;
cpu->isar.id_mmfr3 = 0x02102211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00011142;
- cpu->isar.id_isar5 = 0x00011121;
+ SET_IDREG(idregs, ID_ISAR0, 0x02101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232042);
+ SET_IDREG(idregs, ID_ISAR3, 0x01112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x00011142);
+ SET_IDREG(idregs, ID_ISAR5, 0x00011121);
SET_IDREG(idregs, ID_AA64PFR0, 0x00002222);
SET_IDREG(idregs, ID_AA64DFR0, 0x10305106);
SET_IDREG(idregs, ID_AA64ISAR0, 0x00011120);
@@ -362,13 +362,13 @@ static void aarch64_a76_initfn(Object *obj)
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000010ull);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_dfr0 = 0x04010088;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00010142;
- cpu->isar.id_isar5 = 0x01011121;
- cpu->isar.id_isar6 = 0x00000010;
+ SET_IDREG(idregs, ID_ISAR0, 0x02101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232042);
+ SET_IDREG(idregs, ID_ISAR3, 0x01112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x00010142);
+ SET_IDREG(idregs, ID_ISAR5, 0x01011121);
+ SET_IDREG(idregs, ID_ISAR6, 0x00000010);
cpu->isar.id_mmfr0 = 0x10201105;
cpu->isar.id_mmfr1 = 0x40000000;
cpu->isar.id_mmfr2 = 0x01260000;
@@ -610,13 +610,13 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000020ull);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_dfr0 = 0x04010088;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00010142;
- cpu->isar.id_isar5 = 0x01011121;
- cpu->isar.id_isar6 = 0x00000010;
+ SET_IDREG(idregs, ID_ISAR0, 0x02101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232042);
+ SET_IDREG(idregs, ID_ISAR3, 0x01112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x00010142);
+ SET_IDREG(idregs, ID_ISAR5, 0x01011121);
+ SET_IDREG(idregs, ID_ISAR6, 0x00000010);
cpu->isar.id_mmfr0 = 0x10201105;
cpu->isar.id_mmfr1 = 0x40000000;
cpu->isar.id_mmfr2 = 0x01260000;
@@ -689,13 +689,13 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000020ull);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_dfr0 = 0x15011099;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00010142;
- cpu->isar.id_isar5 = 0x11011121;
- cpu->isar.id_isar6 = 0x01100111;
+ SET_IDREG(idregs, ID_ISAR0, 0x02101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232042);
+ SET_IDREG(idregs, ID_ISAR3, 0x01112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x00010142);
+ SET_IDREG(idregs, ID_ISAR5, 0x11011121);
+ SET_IDREG(idregs, ID_ISAR6, 0x01100111);
cpu->isar.id_mmfr0 = 0x10201105;
cpu->isar.id_mmfr1 = 0x40000000;
cpu->isar.id_mmfr2 = 0x01260000;
@@ -910,14 +910,14 @@ static void aarch64_a710_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x40000000;
cpu->isar.id_mmfr2 = 0x01260000;
cpu->isar.id_mmfr3 = 0x02122211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00010142;
- cpu->isar.id_isar5 = 0x11011121; /* with Crypto */
+ SET_IDREG(idregs, ID_ISAR0, 0x02101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232042);
+ SET_IDREG(idregs, ID_ISAR3, 0x01112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x00010142);
+ SET_IDREG(idregs, ID_ISAR5, 0x11011121); /* with Crypto */
cpu->isar.id_mmfr4 = 0x21021110;
- cpu->isar.id_isar6 = 0x01111111;
+ SET_IDREG(idregs, ID_ISAR6, 0x01111111);
cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x13211111;
cpu->isar.mvfr2 = 0x00000043;
@@ -1013,14 +1013,14 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
cpu->isar.id_mmfr1 = 0x40000000;
cpu->isar.id_mmfr2 = 0x01260000;
cpu->isar.id_mmfr3 = 0x02122211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00010142;
- cpu->isar.id_isar5 = 0x11011121; /* with Crypto */
+ SET_IDREG(idregs, ID_ISAR0, 0x02101110);
+ SET_IDREG(idregs, ID_ISAR1, 0x13112111);
+ SET_IDREG(idregs, ID_ISAR2, 0x21232042);
+ SET_IDREG(idregs, ID_ISAR3, 0x01112131);
+ SET_IDREG(idregs, ID_ISAR4, 0x00010142);
+ SET_IDREG(idregs, ID_ISAR5, 0x11011121); /* with Crypto */
cpu->isar.id_mmfr4 = 0x01021110;
- cpu->isar.id_isar6 = 0x01111111;
+ SET_IDREG(idregs, ID_ISAR6, 0x01111111);
cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x13211111;
cpu->isar.mvfr2 = 0x00000043;
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 10/20] arm/cpu: Store id_mfr0/1 into the idregs array
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (8 preceding siblings ...)
2024-12-06 11:22 ` [PATCH RFCv2 09/20] arm/cpu: Store id_isar0-7 " Cornelia Huck
@ 2024-12-06 11:22 ` Cornelia Huck
2024-12-06 11:22 ` [PATCH RFCv2 11/20] arm/cpu: Store id_dfr0/1 " Cornelia Huck
` (13 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:22 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
hw/intc/armv7m_nvic.c | 5 ++--
target/arm/cpu-features.h | 10 +++----
target/arm/cpu.c | 8 ++---
target/arm/cpu.h | 3 --
target/arm/cpu64.c | 8 ++---
target/arm/helper.c | 8 ++---
target/arm/kvm.c | 3 +-
target/arm/tcg/cpu-v7m.c | 24 +++++++--------
target/arm/tcg/cpu32.c | 61 ++++++++++++++++++++-------------------
target/arm/tcg/cpu64.c | 44 ++++++++++++++--------------
10 files changed, 85 insertions(+), 89 deletions(-)
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index a8e1f9a56ae7..ac2c4fe4db5c 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -988,6 +988,7 @@ static void nvic_nmi_trigger(void *opaque, int n, int level)
static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
{
ARMCPU *cpu = s->cpu;
+ IdRegMap *idregs = &cpu->isar.idregs;
uint32_t val;
switch (offset) {
@@ -1263,12 +1264,12 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_pfr0;
+ return GET_IDREG(idregs, ID_PFR0);
case 0xd44: /* PFR1. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_pfr1;
+ return GET_IDREG(idregs, ID_PFR1);
case 0xd48: /* DFR0. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index 1028d1c64c98..c49fe8547cc9 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -136,12 +136,12 @@ static inline bool isar_feature_aa32_i8mm(const ARMISARegisters *id)
static inline bool isar_feature_aa32_ras(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_pfr0, ID_PFR0, RAS) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_PFR0, RAS) != 0;
}
static inline bool isar_feature_aa32_mprofile(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_pfr1, ID_PFR1, MPROGMOD) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_PFR1, MPROGMOD) != 0;
}
static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id)
@@ -150,7 +150,7 @@ static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id)
* Return true if M-profile state handling insns
* (VSCCLRM, CLRM, FPCTX access insns) are implemented
*/
- return FIELD_EX32(id->id_pfr1, ID_PFR1, SECURITY) >= 3;
+ return FIELD_EX32_IDREG(&id->idregs, ID_PFR1, SECURITY) >= 3;
}
static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
@@ -349,12 +349,12 @@ static inline bool isar_feature_aa32_evt(const ARMISARegisters *id)
static inline bool isar_feature_aa32_dit(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_pfr0, ID_PFR0, DIT) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_PFR0, DIT) != 0;
}
static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_PFR2, SSBS) != 0;
}
static inline bool isar_feature_aa32_debugv7p1(const ARMISARegisters *id)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 1f03aca54765..8d0a5d7c46da 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2327,7 +2327,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* Disable the security extension feature bits in the processor
* feature registers as well.
*/
- cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1, ID_PFR1, SECURITY, 0);
+ FIELD_DP32_IDREG(idregs, ID_PFR1, SECURITY, 0);
cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPSDBG, 0);
FIELD_DP64_IDREG(idregs, ID_AA64PFR0, EL3, 0);
@@ -2367,8 +2367,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* registers if we don't have EL2.
*/
FIELD_DP64_IDREG(idregs, ID_AA64PFR0, EL2, 0);
- cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1,
- ID_PFR1, VIRTUALIZATION, 0);
+ FIELD_DP32_IDREG(idregs, ID_PFR1, VIRTUALIZATION, 0);
}
if (cpu_isar_feature(aa64_mte, cpu)) {
@@ -2431,8 +2430,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, MMAPTRC, 0);
/* FEAT_AMU (Activity Monitors Extension) */
FIELD_DP64_IDREG(idregs, ID_AA64PFR0, AMU, 0);
- cpu->isar.id_pfr0 =
- FIELD_DP32(cpu->isar.id_pfr0, ID_PFR0, AMU, 0);
+ FIELD_DP32_IDREG(idregs, ID_PFR0, AMU, 0);
/* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */
FIELD_DP64_IDREG(idregs, ID_AA64PFR0, MPAM, 0);
}
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index bd12cdad415e..38b85035c366 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1086,9 +1086,6 @@ struct ArchCPU {
uint32_t id_mmfr3;
uint32_t id_mmfr4;
uint32_t id_mmfr5;
- uint32_t id_pfr0;
- uint32_t id_pfr1;
- uint32_t id_pfr2;
uint32_t mvfr0;
uint32_t mvfr1;
uint32_t mvfr2;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index eaf4235b2252..a25b30157965 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -612,8 +612,8 @@ static void aarch64_a57_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50838;
- cpu->isar.id_pfr0 = 0x00000131;
- cpu->isar.id_pfr1 = 0x00011011;
+ SET_IDREG(idregs, ID_PFR0, 0x00000131);
+ SET_IDREG(idregs, ID_PFR1, 0x00011011);
cpu->isar.id_dfr0 = 0x03010066;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10101105;
@@ -674,8 +674,8 @@ static void aarch64_a53_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x84448004; /* L1Ip = VIPT */
cpu->reset_sctlr = 0x00c50838;
- cpu->isar.id_pfr0 = 0x00000131;
- cpu->isar.id_pfr1 = 0x00011011;
+ SET_IDREG(idregs, ID_PFR0, 0x00000131);
+ SET_IDREG(idregs, ID_PFR1, 0x00011011);
cpu->isar.id_dfr0 = 0x03010066;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10101105;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 5891cdb1681e..ade5355c71ee 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7695,7 +7695,7 @@ static void define_pmu_regs(ARMCPU *cpu)
static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
ARMCPU *cpu = env_archcpu(env);
- uint64_t pfr1 = cpu->isar.id_pfr1;
+ uint64_t pfr1 = GET_IDREG(&cpu->isar.idregs, ID_PFR1);
if (env->gicv3state) {
pfr1 |= 1 << 28;
@@ -8743,7 +8743,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_pfr0 },
+ .resetvalue = GET_IDREG(idregs, ID_PFR0)},
/*
* ID_PFR1 is not a plain ARM_CP_CONST because we don't know
* the value of the GIC field until after we define these regs.
@@ -8754,7 +8754,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.accessfn = access_aa32_tid3,
#ifdef CONFIG_USER_ONLY
.type = ARM_CP_CONST,
- .resetvalue = cpu->isar.id_pfr1,
+ .resetvalue = GET_IDREG(idregs, ID_PFR0),
#else
.type = ARM_CP_NO_RAW,
.accessfn = access_aa32_tid3,
@@ -9100,7 +9100,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_pfr2 },
+ .resetvalue = GET_IDREG(idregs, ID_PFR2)},
{ .name = "ID_DFR1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 0a9a27c046f4..287f5ee849a4 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -403,8 +403,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
ARM64_SYS_REG(3, 0, 0, 3, 1));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr2,
ARM64_SYS_REG(3, 0, 0, 3, 2));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr2,
- ARM64_SYS_REG(3, 0, 0, 3, 4));
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_PFR2_EL1);
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr1,
ARM64_SYS_REG(3, 0, 0, 3, 5));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr5,
diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
index ea7d0237f442..e9a02bada8d1 100644
--- a/target/arm/tcg/cpu-v7m.c
+++ b/target/arm/tcg/cpu-v7m.c
@@ -60,8 +60,8 @@ static void cortex_m0_initfn(Object *obj)
* by looking at ID register fields. We use the same values as
* for the M3.
*/
- cpu->isar.id_pfr0 = 0x00000030;
- cpu->isar.id_pfr1 = 0x00000200;
+ SET_IDREG(idregs, ID_PFR0, 0x00000030);
+ SET_IDREG(idregs, ID_PFR1, 0x00000200);
cpu->isar.id_dfr0 = 0x00100000;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00000030;
@@ -86,8 +86,8 @@ static void cortex_m3_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
cpu->midr = 0x410fc231;
cpu->pmsav7_dregion = 8;
- cpu->isar.id_pfr0 = 0x00000030;
- cpu->isar.id_pfr1 = 0x00000200;
+ SET_IDREG(idregs, ID_PFR0, 0x00000030);
+ SET_IDREG(idregs, ID_PFR1, 0x00000200);
cpu->isar.id_dfr0 = 0x00100000;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00000030;
@@ -117,8 +117,8 @@ static void cortex_m4_initfn(Object *obj)
cpu->isar.mvfr0 = 0x10110021;
cpu->isar.mvfr1 = 0x11000011;
cpu->isar.mvfr2 = 0x00000000;
- cpu->isar.id_pfr0 = 0x00000030;
- cpu->isar.id_pfr1 = 0x00000200;
+ SET_IDREG(idregs, ID_PFR0, 0x00000030);
+ SET_IDREG(idregs, ID_PFR1, 0x00000200);
cpu->isar.id_dfr0 = 0x00100000;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00000030;
@@ -148,8 +148,8 @@ static void cortex_m7_initfn(Object *obj)
cpu->isar.mvfr0 = 0x10110221;
cpu->isar.mvfr1 = 0x12000011;
cpu->isar.mvfr2 = 0x00000040;
- cpu->isar.id_pfr0 = 0x00000030;
- cpu->isar.id_pfr1 = 0x00000200;
+ SET_IDREG(idregs, ID_PFR0, 0x00000030);
+ SET_IDREG(idregs, ID_PFR1, 0x00000200);
cpu->isar.id_dfr0 = 0x00100000;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00100030;
@@ -181,8 +181,8 @@ static void cortex_m33_initfn(Object *obj)
cpu->isar.mvfr0 = 0x10110021;
cpu->isar.mvfr1 = 0x11000011;
cpu->isar.mvfr2 = 0x00000040;
- cpu->isar.id_pfr0 = 0x00000030;
- cpu->isar.id_pfr1 = 0x00000210;
+ SET_IDREG(idregs, ID_PFR0, 0x00000030);
+ SET_IDREG(idregs, ID_PFR1, 0x00000210);
cpu->isar.id_dfr0 = 0x00200000;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00101F40;
@@ -219,8 +219,8 @@ static void cortex_m55_initfn(Object *obj)
cpu->isar.mvfr0 = 0x10110221;
cpu->isar.mvfr1 = 0x12100211;
cpu->isar.mvfr2 = 0x00000040;
- cpu->isar.id_pfr0 = 0x20000030;
- cpu->isar.id_pfr1 = 0x00000230;
+ SET_IDREG(idregs, ID_PFR0, 0x20000030);
+ SET_IDREG(idregs, ID_PFR1, 0x00000230);
cpu->isar.id_dfr0 = 0x10200000;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00111040;
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
index 3bb1b6276881..9ac76c61109d 100644
--- a/target/arm/tcg/cpu32.c
+++ b/target/arm/tcg/cpu32.c
@@ -23,18 +23,19 @@
void aa32_max_features(ARMCPU *cpu)
{
uint32_t t;
+ IdRegMap *idregs = &cpu->isar.idregs;
/* Add additional features supported by QEMU */
- t = GET_IDREG(&cpu->isar.idregs, ID_ISAR5);
+ t = GET_IDREG(idregs, ID_ISAR5);
t = FIELD_DP32(t, ID_ISAR5, AES, 2); /* FEAT_PMULL */
t = FIELD_DP32(t, ID_ISAR5, SHA1, 1); /* FEAT_SHA1 */
t = FIELD_DP32(t, ID_ISAR5, SHA2, 1); /* FEAT_SHA256 */
t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
t = FIELD_DP32(t, ID_ISAR5, RDM, 1); /* FEAT_RDM */
t = FIELD_DP32(t, ID_ISAR5, VCMA, 1); /* FEAT_FCMA */
- SET_IDREG(&cpu->isar.idregs, ID_ISAR5, t);
+ SET_IDREG(idregs, ID_ISAR5, t);
- t = GET_IDREG(&cpu->isar.idregs, ID_ISAR6);
+ t = GET_IDREG(idregs, ID_ISAR6);
t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1); /* FEAT_JSCVT */
t = FIELD_DP32(t, ID_ISAR6, DP, 1); /* Feat_DotProd */
t = FIELD_DP32(t, ID_ISAR6, FHM, 1); /* FEAT_FHM */
@@ -42,7 +43,7 @@ void aa32_max_features(ARMCPU *cpu)
t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1); /* FEAT_SPECRES */
t = FIELD_DP32(t, ID_ISAR6, BF16, 1); /* FEAT_AA32BF16 */
t = FIELD_DP32(t, ID_ISAR6, I8MM, 1); /* FEAT_AA32I8MM */
- SET_IDREG(&cpu->isar.idregs, ID_ISAR6, t);
+ SET_IDREG(idregs, ID_ISAR6, t);
t = cpu->isar.mvfr1;
t = FIELD_DP32(t, MVFR1, FPHP, 3); /* FEAT_FP16 */
@@ -70,16 +71,16 @@ void aa32_max_features(ARMCPU *cpu)
t = FIELD_DP32(t, ID_MMFR5, ETS, 2); /* FEAT_ETS2 */
cpu->isar.id_mmfr5 = t;
- t = cpu->isar.id_pfr0;
+ t = GET_IDREG(idregs, ID_PFR0);
t = FIELD_DP32(t, ID_PFR0, CSV2, 2); /* FEAT_CSV2 */
t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */
t = FIELD_DP32(t, ID_PFR0, RAS, 1); /* FEAT_RAS */
- cpu->isar.id_pfr0 = t;
+ SET_IDREG(idregs, ID_PFR0, t);
- t = cpu->isar.id_pfr2;
+ t = GET_IDREG(idregs, ID_PFR2);
t = FIELD_DP32(t, ID_PFR2, CSV3, 1); /* FEAT_CSV3 */
t = FIELD_DP32(t, ID_PFR2, SSBS, 1); /* FEAT_SSBS */
- cpu->isar.id_pfr2 = t;
+ SET_IDREG(idregs, ID_PFR2, t);
t = cpu->isar.id_dfr0;
t = FIELD_DP32(t, ID_DFR0, COPDBG, 10); /* FEAT_Debugv8p8 */
@@ -227,8 +228,8 @@ static void arm1136_r2_initfn(Object *obj)
cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
- cpu->isar.id_pfr0 = 0x111;
- cpu->isar.id_pfr1 = 0x1;
+ SET_IDREG(idregs, ID_PFR0, 0x111);
+ SET_IDREG(idregs, ID_PFR1, 0x1);
cpu->isar.id_dfr0 = 0x2;
cpu->id_afr0 = 0x3;
cpu->isar.id_mmfr0 = 0x01130003;
@@ -259,8 +260,8 @@ static void arm1136_initfn(Object *obj)
cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
- cpu->isar.id_pfr0 = 0x111;
- cpu->isar.id_pfr1 = 0x1;
+ SET_IDREG(idregs, ID_PFR0, 0x111);
+ SET_IDREG(idregs, ID_PFR1, 0x1);
cpu->isar.id_dfr0 = 0x2;
cpu->id_afr0 = 0x3;
cpu->isar.id_mmfr0 = 0x01130003;
@@ -292,8 +293,8 @@ static void arm1176_initfn(Object *obj)
cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
- cpu->isar.id_pfr0 = 0x111;
- cpu->isar.id_pfr1 = 0x11;
+ SET_IDREG(idregs, ID_PFR0, 0x111);
+ SET_IDREG(idregs, ID_PFR1, 0x11);
cpu->isar.id_dfr0 = 0x33;
cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x01130003;
@@ -322,8 +323,8 @@ static void arm11mpcore_initfn(Object *obj)
cpu->isar.mvfr0 = 0x11111111;
cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
- cpu->isar.id_pfr0 = 0x111;
- cpu->isar.id_pfr1 = 0x1;
+ SET_IDREG(idregs, ID_PFR0, 0x111);
+ SET_IDREG(idregs, ID_PFR1, 0x1);
cpu->isar.id_dfr0 = 0;
cpu->id_afr0 = 0x2;
cpu->isar.id_mmfr0 = 0x01100103;
@@ -362,8 +363,8 @@ static void cortex_a8_initfn(Object *obj)
cpu->isar.mvfr1 = 0x00011111;
cpu->ctr = 0x82048004;
cpu->reset_sctlr = 0x00c50078;
- cpu->isar.id_pfr0 = 0x1031;
- cpu->isar.id_pfr1 = 0x11;
+ SET_IDREG(idregs, ID_PFR0, 0x1031);
+ SET_IDREG(idregs, ID_PFR1, 0x11);
cpu->isar.id_dfr0 = 0x400;
cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x31100003;
@@ -438,8 +439,8 @@ static void cortex_a9_initfn(Object *obj)
cpu->isar.mvfr1 = 0x01111111;
cpu->ctr = 0x80038003;
cpu->reset_sctlr = 0x00c50078;
- cpu->isar.id_pfr0 = 0x1031;
- cpu->isar.id_pfr1 = 0x11;
+ SET_IDREG(idregs, ID_PFR0, 0x1031);
+ SET_IDREG(idregs, ID_PFR1, 0x11);
cpu->isar.id_dfr0 = 0x000;
cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x00100103;
@@ -504,8 +505,8 @@ static void cortex_a7_initfn(Object *obj)
cpu->isar.mvfr1 = 0x11111111;
cpu->ctr = 0x84448003;
cpu->reset_sctlr = 0x00c50078;
- cpu->isar.id_pfr0 = 0x00001131;
- cpu->isar.id_pfr1 = 0x00011011;
+ SET_IDREG(idregs, ID_PFR0, 0x00001131);
+ SET_IDREG(idregs, ID_PFR1, 0x00011011);
cpu->isar.id_dfr0 = 0x02010555;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10101105;
@@ -556,8 +557,8 @@ static void cortex_a15_initfn(Object *obj)
cpu->isar.mvfr1 = 0x11111111;
cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50078;
- cpu->isar.id_pfr0 = 0x00001131;
- cpu->isar.id_pfr1 = 0x00011011;
+ SET_IDREG(idregs, ID_PFR0, 0x00001131);
+ SET_IDREG(idregs, ID_PFR1, 0x00011011);
cpu->isar.id_dfr0 = 0x02010555;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10201105;
@@ -600,8 +601,8 @@ static void cortex_r5_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_PMSA);
set_feature(&cpu->env, ARM_FEATURE_PMU);
cpu->midr = 0x411fc153; /* r1p3 */
- cpu->isar.id_pfr0 = 0x0131;
- cpu->isar.id_pfr1 = 0x001;
+ SET_IDREG(idregs, ID_PFR0, 0x0131);
+ SET_IDREG(idregs, ID_PFR1, 0x001);
cpu->isar.id_dfr0 = 0x010400;
cpu->id_afr0 = 0x0;
cpu->isar.id_mmfr0 = 0x0210030;
@@ -747,8 +748,8 @@ static void cortex_r52_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x8144c004;
cpu->reset_sctlr = 0x30c50838;
- cpu->isar.id_pfr0 = 0x00000131;
- cpu->isar.id_pfr1 = 0x10111001;
+ SET_IDREG(idregs, ID_PFR0, 0x00000131);
+ SET_IDREG(idregs, ID_PFR1, 0x10111001);
cpu->isar.id_dfr0 = 0x03010006;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00211040;
@@ -979,8 +980,8 @@ static void arm_max_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50838;
- cpu->isar.id_pfr0 = 0x00000131;
- cpu->isar.id_pfr1 = 0x00011011;
+ SET_IDREG(idregs, ID_PFR0, 0x00000131);
+ SET_IDREG(idregs, ID_PFR1, 0x00011011);
cpu->isar.id_dfr0 = 0x03010066;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10101105;
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 9bca36093006..42662878b2df 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -49,8 +49,8 @@ static void aarch64_a35_initfn(Object *obj)
cpu->midr = 0x411fd040;
cpu->revidr = 0;
cpu->ctr = 0x84448004;
- cpu->isar.id_pfr0 = 0x00000131;
- cpu->isar.id_pfr1 = 0x00011011;
+ SET_IDREG(idregs, ID_PFR0, 0x00000131);
+ SET_IDREG(idregs, ID_PFR1, 0x00011011);
cpu->isar.id_dfr0 = 0x03010066;
cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x10201105;
@@ -241,9 +241,9 @@ static void aarch64_a55_initfn(Object *obj)
cpu->isar.id_mmfr2 = 0x01260000;
cpu->isar.id_mmfr3 = 0x02122211;
cpu->isar.id_mmfr4 = 0x00021110;
- cpu->isar.id_pfr0 = 0x10010131;
- cpu->isar.id_pfr1 = 0x00011011;
- cpu->isar.id_pfr2 = 0x00000011;
+ SET_IDREG(idregs, ID_PFR0, 0x10010131);
+ SET_IDREG(idregs, ID_PFR1, 0x00011011);
+ SET_IDREG(idregs, ID_PFR2, 0x00000011);
cpu->midr = 0x412FD050; /* r2p0 */
cpu->revidr = 0;
@@ -295,8 +295,8 @@ static void aarch64_a72_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50838;
- cpu->isar.id_pfr0 = 0x00000131;
- cpu->isar.id_pfr1 = 0x00011011;
+ SET_IDREG(idregs, ID_PFR0, 0x00000131);
+ SET_IDREG(idregs, ID_PFR1, 0x00011011);
cpu->isar.id_dfr0 = 0x03010066;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10201105;
@@ -374,9 +374,9 @@ static void aarch64_a76_initfn(Object *obj)
cpu->isar.id_mmfr2 = 0x01260000;
cpu->isar.id_mmfr3 = 0x02122211;
cpu->isar.id_mmfr4 = 0x00021110;
- cpu->isar.id_pfr0 = 0x10010131;
- cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
- cpu->isar.id_pfr2 = 0x00000011;
+ SET_IDREG(idregs, ID_PFR0, 0x10010131);
+ SET_IDREG(idregs, ID_PFR1, 0x00010000); /* GIC filled in later */
+ SET_IDREG(idregs, ID_PFR2, 0x00000011);
cpu->midr = 0x414fd0b1; /* r4p1 */
cpu->revidr = 0;
@@ -622,9 +622,9 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
cpu->isar.id_mmfr2 = 0x01260000;
cpu->isar.id_mmfr3 = 0x02122211;
cpu->isar.id_mmfr4 = 0x00021110;
- cpu->isar.id_pfr0 = 0x10010131;
- cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
- cpu->isar.id_pfr2 = 0x00000011;
+ SET_IDREG(idregs, ID_PFR0, 0x10010131);
+ SET_IDREG(idregs, ID_PFR1, 0x00010000); /* GIC filled in later */
+ SET_IDREG(idregs, ID_PFR2, 0x00000011);
cpu->midr = 0x414fd0c1; /* r4p1 */
cpu->revidr = 0;
@@ -701,9 +701,9 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
cpu->isar.id_mmfr2 = 0x01260000;
cpu->isar.id_mmfr3 = 0x02122211;
cpu->isar.id_mmfr4 = 0x01021110;
- cpu->isar.id_pfr0 = 0x21110131;
- cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
- cpu->isar.id_pfr2 = 0x00000011;
+ SET_IDREG(idregs, ID_PFR0, 0x21110131);
+ SET_IDREG(idregs, ID_PFR1, 0x00010000); /* GIC filled in later */
+ SET_IDREG(idregs, ID_PFR2, 0x00000011);
cpu->midr = 0x411FD402; /* r1p2 */
cpu->revidr = 0;
@@ -902,8 +902,8 @@ static void aarch64_a710_initfn(Object *obj)
/* Ordered by Section B.4: AArch64 registers */
cpu->midr = 0x412FD471; /* r2p1 */
cpu->revidr = 0;
- cpu->isar.id_pfr0 = 0x21110131;
- cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
+ SET_IDREG(idregs, ID_PFR0, 0x21110131);
+ SET_IDREG(idregs, ID_PFR1, 0x00010000); /* GIC filled in later */
cpu->isar.id_dfr0 = 0x16011099;
cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x10201105;
@@ -921,7 +921,7 @@ static void aarch64_a710_initfn(Object *obj)
cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x13211111;
cpu->isar.mvfr2 = 0x00000043;
- cpu->isar.id_pfr2 = 0x00000011;
+ SET_IDREG(idregs, ID_PFR2, 0x00000011);
SET_IDREG(idregs, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000221ull);
SET_IDREG(idregs, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */
@@ -1005,8 +1005,8 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
/* Ordered by Section B.5: AArch64 ID registers */
cpu->midr = 0x410FD493; /* r0p3 */
cpu->revidr = 0;
- cpu->isar.id_pfr0 = 0x21110131;
- cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
+ SET_IDREG(idregs, ID_PFR0, 0x21110131);
+ SET_IDREG(idregs, ID_PFR1, 0x00010000); /* GIC filled in later */
cpu->isar.id_dfr0 = 0x16011099;
cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x10201105;
@@ -1024,7 +1024,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x13211111;
cpu->isar.mvfr2 = 0x00000043;
- cpu->isar.id_pfr2 = 0x00000011;
+ SET_IDREG(idregs, ID_PFR2, 0x00000011);
SET_IDREG(idregs, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000221ull);
SET_IDREG(idregs, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 11/20] arm/cpu: Store id_dfr0/1 into the idregs array
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (9 preceding siblings ...)
2024-12-06 11:22 ` [PATCH RFCv2 10/20] arm/cpu: Store id_mfr0/1 " Cornelia Huck
@ 2024-12-06 11:22 ` Cornelia Huck
2024-12-06 11:22 ` [PATCH RFCv2 12/20] arm/cpu: Store id_mmfr0-5 " Cornelia Huck
` (12 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:22 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
hw/intc/armv7m_nvic.c | 2 +-
target/arm/cpu-features.h | 16 ++++++++--------
target/arm/cpu.c | 13 +++++--------
target/arm/cpu.h | 2 --
target/arm/cpu64.c | 4 ++--
target/arm/helper.c | 4 ++--
target/arm/kvm.c | 6 ++----
target/arm/tcg/cpu-v7m.c | 12 ++++++------
target/arm/tcg/cpu32.c | 30 ++++++++++++++----------------
target/arm/tcg/cpu64.c | 16 ++++++++--------
10 files changed, 48 insertions(+), 57 deletions(-)
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index ac2c4fe4db5c..5cf8cd9321d7 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1274,7 +1274,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_dfr0;
+ return GET_IDREG(idregs, ID_DFR0);
case 0xd4c: /* AFR0. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index c49fe8547cc9..e056498fc065 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -299,22 +299,22 @@ static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id)
static inline bool isar_feature_aa32_pmuv3p1(const ARMISARegisters *id)
{
/* 0xf means "non-standard IMPDEF PMU" */
- return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
- FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
+ return FIELD_EX32_IDREG(&id->idregs, ID_DFR0, PERFMON) >= 4 &&
+ FIELD_EX32_IDREG(&id->idregs, ID_DFR0, PERFMON) != 0xf;
}
static inline bool isar_feature_aa32_pmuv3p4(const ARMISARegisters *id)
{
/* 0xf means "non-standard IMPDEF PMU" */
- return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 5 &&
- FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
+ return FIELD_EX32_IDREG(&id->idregs, ID_DFR0, PERFMON) >= 5 &&
+ FIELD_EX32_IDREG(&id->idregs, ID_DFR0, PERFMON) != 0xf;
}
static inline bool isar_feature_aa32_pmuv3p5(const ARMISARegisters *id)
{
/* 0xf means "non-standard IMPDEF PMU" */
- return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 6 &&
- FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
+ return FIELD_EX32_IDREG(&id->idregs, ID_DFR0, PERFMON) >= 6 &&
+ FIELD_EX32_IDREG(&id->idregs, ID_DFR0, PERFMON) != 0xf;
}
static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id)
@@ -359,12 +359,12 @@ static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
static inline bool isar_feature_aa32_debugv7p1(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 5;
+ return FIELD_EX32_IDREG(&id->idregs, ID_DFR0, COPDBG) >= 5;
}
static inline bool isar_feature_aa32_debugv8p2(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 8;
+ return FIELD_EX32_IDREG(&id->idregs, ID_DFR0, COPDBG) >= 8;
}
static inline bool isar_feature_aa32_doublelock(const ARMISARegisters *id)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 8d0a5d7c46da..fee822eaf416 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2328,7 +2328,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* feature registers as well.
*/
FIELD_DP32_IDREG(idregs, ID_PFR1, SECURITY, 0);
- cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPSDBG, 0);
+ FIELD_DP32_IDREG(idregs, ID_DFR0, COPSDBG, 0);
FIELD_DP64_IDREG(idregs, ID_AA64PFR0, EL3, 0);
/* Disable the realm management extension, which requires EL3. */
@@ -2356,7 +2356,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
#endif
} else {
FIELD_DP64_IDREG(idregs, ID_AA64DFR0, PMUVER, 0);
- cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
+ FIELD_DP32_IDREG(idregs, ID_DFR0, PERFMON, 0);
cpu->pmceid0 = 0;
cpu->pmceid1 = 0;
}
@@ -2419,15 +2419,12 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
FIELD_DP64_IDREG(idregs, ID_AA64DFR0, TRACEBUFFER, 0);
/* FEAT_TRF (Self-hosted Trace Extension) */
FIELD_DP64_IDREG(idregs, ID_AA64DFR0, TRACEFILT, 0);
- cpu->isar.id_dfr0 =
- FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, TRACEFILT, 0);
+ FIELD_DP32_IDREG(idregs, ID_DFR0, TRACEFILT, 0);
/* Trace Macrocell system register access */
FIELD_DP64_IDREG(idregs, ID_AA64DFR0, TRACEVER, 0);
- cpu->isar.id_dfr0 =
- FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPTRC, 0);
+ FIELD_DP32_IDREG(idregs, ID_DFR0, COPTRC, 0);
/* Memory mapped trace */
- cpu->isar.id_dfr0 =
- FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, MMAPTRC, 0);
+ FIELD_DP32_IDREG(idregs, ID_DFR0, MMAPTRC, 0);
/* FEAT_AMU (Activity Monitors Extension) */
FIELD_DP64_IDREG(idregs, ID_AA64PFR0, AMU, 0);
FIELD_DP32_IDREG(idregs, ID_PFR0, AMU, 0);
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 38b85035c366..df1506ab74fe 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1089,8 +1089,6 @@ struct ArchCPU {
uint32_t mvfr0;
uint32_t mvfr1;
uint32_t mvfr2;
- uint32_t id_dfr0;
- uint32_t id_dfr1;
uint32_t dbgdidr;
uint32_t dbgdevid;
uint32_t dbgdevid1;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index a25b30157965..fb3845c8cceb 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -614,7 +614,7 @@ static void aarch64_a57_initfn(Object *obj)
cpu->reset_sctlr = 0x00c50838;
SET_IDREG(idregs, ID_PFR0, 0x00000131);
SET_IDREG(idregs, ID_PFR1, 0x00011011);
- cpu->isar.id_dfr0 = 0x03010066;
+ SET_IDREG(idregs, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10101105;
cpu->isar.id_mmfr1 = 0x40000000;
@@ -676,7 +676,7 @@ static void aarch64_a53_initfn(Object *obj)
cpu->reset_sctlr = 0x00c50838;
SET_IDREG(idregs, ID_PFR0, 0x00000131);
SET_IDREG(idregs, ID_PFR1, 0x00011011);
- cpu->isar.id_dfr0 = 0x03010066;
+ SET_IDREG(idregs, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10101105;
cpu->isar.id_mmfr1 = 0x40000000;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index ade5355c71ee..90db2baff200 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8766,7 +8766,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_dfr0 },
+ .resetvalue = GET_IDREG(idregs, ID_DFR0)},
{ .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST,
@@ -9105,7 +9105,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_dfr1 },
+ .resetvalue = GET_IDREG(idregs, ID_DFR1)},
{ .name = "ID_MMFR5", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 287f5ee849a4..88fa08e390d5 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -377,8 +377,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
*/
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64PFR0_EL1);
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64PFR1_EL1);
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
- ARM64_SYS_REG(3, 0, 0, 1, 2));
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_DFR0_EL1);
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
ARM64_SYS_REG(3, 0, 0, 1, 4));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1,
@@ -404,8 +403,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr2,
ARM64_SYS_REG(3, 0, 0, 3, 2));
err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_PFR2_EL1);
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr1,
- ARM64_SYS_REG(3, 0, 0, 3, 5));
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_DFR1_EL1);
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr5,
ARM64_SYS_REG(3, 0, 0, 3, 6));
diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
index e9a02bada8d1..a7034ce5b66c 100644
--- a/target/arm/tcg/cpu-v7m.c
+++ b/target/arm/tcg/cpu-v7m.c
@@ -62,7 +62,7 @@ static void cortex_m0_initfn(Object *obj)
*/
SET_IDREG(idregs, ID_PFR0, 0x00000030);
SET_IDREG(idregs, ID_PFR1, 0x00000200);
- cpu->isar.id_dfr0 = 0x00100000;
+ SET_IDREG(idregs, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00000030;
cpu->isar.id_mmfr1 = 0x00000000;
@@ -88,7 +88,7 @@ static void cortex_m3_initfn(Object *obj)
cpu->pmsav7_dregion = 8;
SET_IDREG(idregs, ID_PFR0, 0x00000030);
SET_IDREG(idregs, ID_PFR1, 0x00000200);
- cpu->isar.id_dfr0 = 0x00100000;
+ SET_IDREG(idregs, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00000030;
cpu->isar.id_mmfr1 = 0x00000000;
@@ -119,7 +119,7 @@ static void cortex_m4_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000000;
SET_IDREG(idregs, ID_PFR0, 0x00000030);
SET_IDREG(idregs, ID_PFR1, 0x00000200);
- cpu->isar.id_dfr0 = 0x00100000;
+ SET_IDREG(idregs, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00000030;
cpu->isar.id_mmfr1 = 0x00000000;
@@ -150,7 +150,7 @@ static void cortex_m7_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000040;
SET_IDREG(idregs, ID_PFR0, 0x00000030);
SET_IDREG(idregs, ID_PFR1, 0x00000200);
- cpu->isar.id_dfr0 = 0x00100000;
+ SET_IDREG(idregs, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00100030;
cpu->isar.id_mmfr1 = 0x00000000;
@@ -183,7 +183,7 @@ static void cortex_m33_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000040;
SET_IDREG(idregs, ID_PFR0, 0x00000030);
SET_IDREG(idregs, ID_PFR1, 0x00000210);
- cpu->isar.id_dfr0 = 0x00200000;
+ SET_IDREG(idregs, ID_DFR0, 0x00200000);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00101F40;
cpu->isar.id_mmfr1 = 0x00000000;
@@ -221,7 +221,7 @@ static void cortex_m55_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000040;
SET_IDREG(idregs, ID_PFR0, 0x20000030);
SET_IDREG(idregs, ID_PFR1, 0x00000230);
- cpu->isar.id_dfr0 = 0x10200000;
+ SET_IDREG(idregs, ID_DFR0, 0x10200000);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00111040;
cpu->isar.id_mmfr1 = 0x00000000;
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
index 9ac76c61109d..3036c39d00f1 100644
--- a/target/arm/tcg/cpu32.c
+++ b/target/arm/tcg/cpu32.c
@@ -82,11 +82,11 @@ void aa32_max_features(ARMCPU *cpu)
t = FIELD_DP32(t, ID_PFR2, SSBS, 1); /* FEAT_SSBS */
SET_IDREG(idregs, ID_PFR2, t);
- t = cpu->isar.id_dfr0;
+ t = GET_IDREG(idregs, ID_DFR0);
t = FIELD_DP32(t, ID_DFR0, COPDBG, 10); /* FEAT_Debugv8p8 */
t = FIELD_DP32(t, ID_DFR0, COPSDBG, 10); /* FEAT_Debugv8p8 */
t = FIELD_DP32(t, ID_DFR0, PERFMON, 6); /* FEAT_PMUv3p5 */
- cpu->isar.id_dfr0 = t;
+ SET_IDREG(idregs, ID_DFR0, t);
/* Debug ID registers. */
@@ -116,9 +116,7 @@ void aa32_max_features(ARMCPU *cpu)
t = FIELD_DP32(t, DBGDEVID1, PCSROFFSET, 2);
cpu->isar.dbgdevid1 = t;
- t = cpu->isar.id_dfr1;
- t = FIELD_DP32(t, ID_DFR1, HPMN0, 1); /* FEAT_HPMN0 */
- cpu->isar.id_dfr1 = t;
+ FIELD_DP32_IDREG(idregs, ID_DFR1, HPMN0, 1); /* FEAT_HPMN0 */
}
/* CPU models. These are not needed for the AArch64 linux-user build. */
@@ -230,7 +228,7 @@ static void arm1136_r2_initfn(Object *obj)
cpu->reset_sctlr = 0x00050078;
SET_IDREG(idregs, ID_PFR0, 0x111);
SET_IDREG(idregs, ID_PFR1, 0x1);
- cpu->isar.id_dfr0 = 0x2;
+ SET_IDREG(idregs, ID_DFR0, 0x2);
cpu->id_afr0 = 0x3;
cpu->isar.id_mmfr0 = 0x01130003;
cpu->isar.id_mmfr1 = 0x10030302;
@@ -262,7 +260,7 @@ static void arm1136_initfn(Object *obj)
cpu->reset_sctlr = 0x00050078;
SET_IDREG(idregs, ID_PFR0, 0x111);
SET_IDREG(idregs, ID_PFR1, 0x1);
- cpu->isar.id_dfr0 = 0x2;
+ SET_IDREG(idregs, ID_DFR0, 0x2);
cpu->id_afr0 = 0x3;
cpu->isar.id_mmfr0 = 0x01130003;
cpu->isar.id_mmfr1 = 0x10030302;
@@ -295,7 +293,7 @@ static void arm1176_initfn(Object *obj)
cpu->reset_sctlr = 0x00050078;
SET_IDREG(idregs, ID_PFR0, 0x111);
SET_IDREG(idregs, ID_PFR1, 0x11);
- cpu->isar.id_dfr0 = 0x33;
+ SET_IDREG(idregs, ID_DFR0, 0x33);
cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x01130003;
cpu->isar.id_mmfr1 = 0x10030302;
@@ -325,7 +323,7 @@ static void arm11mpcore_initfn(Object *obj)
cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
SET_IDREG(idregs, ID_PFR0, 0x111);
SET_IDREG(idregs, ID_PFR1, 0x1);
- cpu->isar.id_dfr0 = 0;
+ SET_IDREG(idregs, ID_DFR0, 0);
cpu->id_afr0 = 0x2;
cpu->isar.id_mmfr0 = 0x01100103;
cpu->isar.id_mmfr1 = 0x10020302;
@@ -365,7 +363,7 @@ static void cortex_a8_initfn(Object *obj)
cpu->reset_sctlr = 0x00c50078;
SET_IDREG(idregs, ID_PFR0, 0x1031);
SET_IDREG(idregs, ID_PFR1, 0x11);
- cpu->isar.id_dfr0 = 0x400;
+ SET_IDREG(idregs, ID_DFR0, 0x400);
cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x31100003;
cpu->isar.id_mmfr1 = 0x20000000;
@@ -441,7 +439,7 @@ static void cortex_a9_initfn(Object *obj)
cpu->reset_sctlr = 0x00c50078;
SET_IDREG(idregs, ID_PFR0, 0x1031);
SET_IDREG(idregs, ID_PFR1, 0x11);
- cpu->isar.id_dfr0 = 0x000;
+ SET_IDREG(idregs, ID_DFR0, 0x000);
cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x00100103;
cpu->isar.id_mmfr1 = 0x20000000;
@@ -507,7 +505,7 @@ static void cortex_a7_initfn(Object *obj)
cpu->reset_sctlr = 0x00c50078;
SET_IDREG(idregs, ID_PFR0, 0x00001131);
SET_IDREG(idregs, ID_PFR1, 0x00011011);
- cpu->isar.id_dfr0 = 0x02010555;
+ SET_IDREG(idregs, ID_DFR0, 0x02010555);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10101105;
cpu->isar.id_mmfr1 = 0x40000000;
@@ -559,7 +557,7 @@ static void cortex_a15_initfn(Object *obj)
cpu->reset_sctlr = 0x00c50078;
SET_IDREG(idregs, ID_PFR0, 0x00001131);
SET_IDREG(idregs, ID_PFR1, 0x00011011);
- cpu->isar.id_dfr0 = 0x02010555;
+ SET_IDREG(idregs, ID_DFR0, 0x02010555);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10201105;
cpu->isar.id_mmfr1 = 0x20000000;
@@ -603,7 +601,7 @@ static void cortex_r5_initfn(Object *obj)
cpu->midr = 0x411fc153; /* r1p3 */
SET_IDREG(idregs, ID_PFR0, 0x0131);
SET_IDREG(idregs, ID_PFR1, 0x001);
- cpu->isar.id_dfr0 = 0x010400;
+ SET_IDREG(idregs, ID_DFR0, 0x010400);
cpu->id_afr0 = 0x0;
cpu->isar.id_mmfr0 = 0x0210030;
cpu->isar.id_mmfr1 = 0x00000000;
@@ -750,7 +748,7 @@ static void cortex_r52_initfn(Object *obj)
cpu->reset_sctlr = 0x30c50838;
SET_IDREG(idregs, ID_PFR0, 0x00000131);
SET_IDREG(idregs, ID_PFR1, 0x10111001);
- cpu->isar.id_dfr0 = 0x03010006;
+ SET_IDREG(idregs, ID_DFR0, 0x03010006);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00211040;
cpu->isar.id_mmfr1 = 0x40000000;
@@ -982,7 +980,7 @@ static void arm_max_initfn(Object *obj)
cpu->reset_sctlr = 0x00c50838;
SET_IDREG(idregs, ID_PFR0, 0x00000131);
SET_IDREG(idregs, ID_PFR1, 0x00011011);
- cpu->isar.id_dfr0 = 0x03010066;
+ SET_IDREG(idregs, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10101105;
cpu->isar.id_mmfr1 = 0x40000000;
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 42662878b2df..ead0b5600024 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -51,7 +51,7 @@ static void aarch64_a35_initfn(Object *obj)
cpu->ctr = 0x84448004;
SET_IDREG(idregs, ID_PFR0, 0x00000131);
SET_IDREG(idregs, ID_PFR1, 0x00011011);
- cpu->isar.id_dfr0 = 0x03010066;
+ SET_IDREG(idregs, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x10201105;
cpu->isar.id_mmfr1 = 0x40000000;
@@ -228,7 +228,7 @@ static void aarch64_a55_initfn(Object *obj)
SET_IDREG(idregs, ID_AA64PFR0, 0x0000000010112222ull);
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000010ull);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_dfr0 = 0x04010088;
+ SET_IDREG(idregs, ID_DFR0, 0x04010088);
SET_IDREG(idregs, ID_ISAR0, 0x02101110);
SET_IDREG(idregs, ID_ISAR1, 0x13112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232042);
@@ -297,7 +297,7 @@ static void aarch64_a72_initfn(Object *obj)
cpu->reset_sctlr = 0x00c50838;
SET_IDREG(idregs, ID_PFR0, 0x00000131);
SET_IDREG(idregs, ID_PFR1, 0x00011011);
- cpu->isar.id_dfr0 = 0x03010066;
+ SET_IDREG(idregs, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10201105;
cpu->isar.id_mmfr1 = 0x40000000;
@@ -361,7 +361,7 @@ static void aarch64_a76_initfn(Object *obj)
SET_IDREG(idregs, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000010ull);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_dfr0 = 0x04010088;
+ SET_IDREG(idregs, ID_DFR0, 0x04010088);
SET_IDREG(idregs, ID_ISAR0, 0x02101110);
SET_IDREG(idregs, ID_ISAR1, 0x13112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232042);
@@ -609,7 +609,7 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
SET_IDREG(idregs, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000020ull);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_dfr0 = 0x04010088;
+ SET_IDREG(idregs, ID_DFR0, 0x04010088);
SET_IDREG(idregs, ID_ISAR0, 0x02101110);
SET_IDREG(idregs, ID_ISAR1, 0x13112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232042);
@@ -688,7 +688,7 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
SET_IDREG(idregs, ID_AA64PFR0, 0x1101110120111112ull); /* GIC filled in later */
SET_IDREG(idregs, ID_AA64PFR1, 0x0000000000000020ull);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_dfr0 = 0x15011099;
+ SET_IDREG(idregs, ID_DFR0, 0x15011099);
SET_IDREG(idregs, ID_ISAR0, 0x02101110);
SET_IDREG(idregs, ID_ISAR1, 0x13112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232042);
@@ -904,7 +904,7 @@ static void aarch64_a710_initfn(Object *obj)
cpu->revidr = 0;
SET_IDREG(idregs, ID_PFR0, 0x21110131);
SET_IDREG(idregs, ID_PFR1, 0x00010000); /* GIC filled in later */
- cpu->isar.id_dfr0 = 0x16011099;
+ SET_IDREG(idregs, ID_DFR0, 0x16011099);
cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x10201105;
cpu->isar.id_mmfr1 = 0x40000000;
@@ -1007,7 +1007,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
cpu->revidr = 0;
SET_IDREG(idregs, ID_PFR0, 0x21110131);
SET_IDREG(idregs, ID_PFR1, 0x00010000); /* GIC filled in later */
- cpu->isar.id_dfr0 = 0x16011099;
+ SET_IDREG(idregs, ID_DFR0, 0x16011099);
cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x10201105;
cpu->isar.id_mmfr1 = 0x40000000;
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 12/20] arm/cpu: Store id_mmfr0-5 into the idregs array
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (10 preceding siblings ...)
2024-12-06 11:22 ` [PATCH RFCv2 11/20] arm/cpu: Store id_dfr0/1 " Cornelia Huck
@ 2024-12-06 11:22 ` Cornelia Huck
2024-12-06 11:22 ` [PATCH RFCv2 13/20] arm/cpu: Add infra to handle generated ID register definitions Cornelia Huck
` (11 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:22 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
hw/intc/armv7m_nvic.c | 8 ++--
target/arm/cpu-features.h | 18 ++++----
target/arm/cpu.h | 6 ---
target/arm/cpu64.c | 16 +++----
target/arm/helper.c | 12 ++---
target/arm/kvm.c | 18 +++-----
target/arm/tcg/cpu-v7m.c | 48 ++++++++++----------
target/arm/tcg/cpu32.c | 94 +++++++++++++++++++--------------------
target/arm/tcg/cpu64.c | 76 +++++++++++++++----------------
9 files changed, 140 insertions(+), 156 deletions(-)
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 5cf8cd9321d7..71b19fd4e70a 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1284,22 +1284,22 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_mmfr0;
+ return GET_IDREG(idregs, ID_MMFR0);
case 0xd54: /* MMFR1. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_mmfr1;
+ return GET_IDREG(idregs, ID_MMFR1);
case 0xd58: /* MMFR2. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_mmfr2;
+ return GET_IDREG(idregs, ID_MMFR2);
case 0xd5c: /* MMFR3. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_mmfr3;
+ return GET_IDREG(idregs, ID_MMFR3);
case 0xd60: /* ISAR0. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index e056498fc065..aa5ddfca5efd 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -283,17 +283,17 @@ static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
static inline bool isar_feature_aa32_pxn(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_mmfr0, ID_MMFR0, VMSA) >= 4;
+ return FIELD_EX32_IDREG(&id->idregs, ID_MMFR0, VMSA) >= 4;
}
static inline bool isar_feature_aa32_pan(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_MMFR3, PAN) != 0;
}
static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) >= 2;
+ return FIELD_EX32_IDREG(&id->idregs, ID_MMFR3, PAN) >= 2;
}
static inline bool isar_feature_aa32_pmuv3p1(const ARMISARegisters *id)
@@ -319,32 +319,32 @@ static inline bool isar_feature_aa32_pmuv3p5(const ARMISARegisters *id)
static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, HPDS) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_MMFR4, HPDS) != 0;
}
static inline bool isar_feature_aa32_ac2(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, AC2) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_MMFR4, AC2) != 0;
}
static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_MMFR4, CCIDX) != 0;
}
static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
+ return FIELD_EX32_IDREG(&id->idregs, ID_MMFR4, XNX) != 0;
}
static inline bool isar_feature_aa32_half_evt(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, EVT) >= 1;
+ return FIELD_EX32_IDREG(&id->idregs, ID_MMFR4, EVT) >= 1;
}
static inline bool isar_feature_aa32_evt(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, EVT) >= 2;
+ return FIELD_EX32_IDREG(&id->idregs, ID_MMFR4, EVT) >= 2;
}
static inline bool isar_feature_aa32_dit(const ARMISARegisters *id)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index df1506ab74fe..c803d191e84d 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1080,12 +1080,6 @@ struct ArchCPU {
* field by reading the value from the KVM vCPU.
*/
struct ARMISARegisters {
- uint32_t id_mmfr0;
- uint32_t id_mmfr1;
- uint32_t id_mmfr2;
- uint32_t id_mmfr3;
- uint32_t id_mmfr4;
- uint32_t id_mmfr5;
uint32_t mvfr0;
uint32_t mvfr1;
uint32_t mvfr2;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index fb3845c8cceb..efc930ff8367 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -616,10 +616,10 @@ static void aarch64_a57_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x00011011);
SET_IDREG(idregs, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x10101105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02102211;
+ SET_IDREG(idregs, ID_MMFR0, 0x10101105);
+ SET_IDREG(idregs, ID_MMFR1, 0x40000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01260000);
+ SET_IDREG(idregs, ID_MMFR3, 0x02102211);
SET_IDREG(idregs, ID_ISAR0, 0x02101110);
SET_IDREG(idregs, ID_ISAR1, 0x13112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232042);
@@ -678,10 +678,10 @@ static void aarch64_a53_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x00011011);
SET_IDREG(idregs, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x10101105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02102211;
+ SET_IDREG(idregs, ID_MMFR0, 0x10101105);
+ SET_IDREG(idregs, ID_MMFR1, 0x40000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01260000);
+ SET_IDREG(idregs, ID_MMFR3, 0x02102211);
SET_IDREG(idregs, ID_ISAR0, 0x02101110);
SET_IDREG(idregs, ID_ISAR1, 0x13112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232042);
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 90db2baff200..ed9fcdc0dbdf 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8776,22 +8776,22 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_mmfr0 },
+ .resetvalue = GET_IDREG(idregs, ID_MMFR0)},
{ .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_mmfr1 },
+ .resetvalue = GET_IDREG(idregs, ID_MMFR1)},
{ .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_mmfr2 },
+ .resetvalue = GET_IDREG(idregs, ID_MMFR2)},
{ .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_mmfr3 },
+ .resetvalue = GET_IDREG(idregs, ID_MMFR3)},
{ .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
@@ -8826,7 +8826,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_mmfr4 },
+ .resetvalue = GET_IDREG(idregs, ID_MMFR4)},
{ .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST,
@@ -9110,7 +9110,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_mmfr5 },
+ .resetvalue = GET_IDREG(idregs, ID_MMFR5)},
{ .name = "RES_0_C0_C3_7", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST,
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 88fa08e390d5..f11d512388b8 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -378,14 +378,10 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64PFR0_EL1);
err |= get_host_cpu_reg64(fd, ahcf, SYS_ID_AA64PFR1_EL1);
err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_DFR0_EL1);
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
- ARM64_SYS_REG(3, 0, 0, 1, 4));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1,
- ARM64_SYS_REG(3, 0, 0, 1, 5));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr2,
- ARM64_SYS_REG(3, 0, 0, 1, 6));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr3,
- ARM64_SYS_REG(3, 0, 0, 1, 7));
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_MMFR0_EL1);
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_MMFR1_EL1);
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_MMFR2_EL1);
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_MMFR3_EL1);
err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_ISAR0_EL1);
err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_ISAR1_EL1);
err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_ISAR2_EL1);
@@ -393,8 +389,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_ISAR4_EL1);
err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_ISAR5_EL1);
err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_ISAR6_EL1);
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr4,
- ARM64_SYS_REG(3, 0, 0, 2, 6));
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_MMFR4_EL1);
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0,
ARM64_SYS_REG(3, 0, 0, 3, 0));
@@ -404,8 +399,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
ARM64_SYS_REG(3, 0, 0, 3, 2));
err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_PFR2_EL1);
err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_DFR1_EL1);
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr5,
- ARM64_SYS_REG(3, 0, 0, 3, 6));
+ err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_MMFR5_EL1);
/*
* DBGDIDR is a bit complicated because the kernel doesn't
diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
index a7034ce5b66c..758560f1e896 100644
--- a/target/arm/tcg/cpu-v7m.c
+++ b/target/arm/tcg/cpu-v7m.c
@@ -64,10 +64,10 @@ static void cortex_m0_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x00000200);
SET_IDREG(idregs, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x00000030;
- cpu->isar.id_mmfr1 = 0x00000000;
- cpu->isar.id_mmfr2 = 0x00000000;
- cpu->isar.id_mmfr3 = 0x00000000;
+ SET_IDREG(idregs, ID_MMFR0, 0x00000030);
+ SET_IDREG(idregs, ID_MMFR1, 0x00000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x00000000);
+ SET_IDREG(idregs, ID_MMFR3, 0x00000000);
SET_IDREG(idregs, ID_ISAR0, 0x01141110);
SET_IDREG(idregs, ID_ISAR1, 0x02111000);
SET_IDREG(idregs, ID_ISAR2, 0x21112231);
@@ -90,10 +90,10 @@ static void cortex_m3_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x00000200);
SET_IDREG(idregs, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x00000030;
- cpu->isar.id_mmfr1 = 0x00000000;
- cpu->isar.id_mmfr2 = 0x00000000;
- cpu->isar.id_mmfr3 = 0x00000000;
+ SET_IDREG(idregs, ID_MMFR0, 0x00000030);
+ SET_IDREG(idregs, ID_MMFR1, 0x00000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x00000000);
+ SET_IDREG(idregs, ID_MMFR3, 0x00000000);
SET_IDREG(idregs, ID_ISAR0, 0x01141110);
SET_IDREG(idregs, ID_ISAR1, 0x02111000);
SET_IDREG(idregs, ID_ISAR2, 0x21112231);
@@ -121,10 +121,10 @@ static void cortex_m4_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x00000200);
SET_IDREG(idregs, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x00000030;
- cpu->isar.id_mmfr1 = 0x00000000;
- cpu->isar.id_mmfr2 = 0x00000000;
- cpu->isar.id_mmfr3 = 0x00000000;
+ SET_IDREG(idregs, ID_MMFR0, 0x00000030);
+ SET_IDREG(idregs, ID_MMFR1, 0x00000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x00000000);
+ SET_IDREG(idregs, ID_MMFR3, 0x00000000);
SET_IDREG(idregs, ID_ISAR0, 0x01141110);
SET_IDREG(idregs, ID_ISAR1, 0x02111000);
SET_IDREG(idregs, ID_ISAR2, 0x21112231);
@@ -152,10 +152,10 @@ static void cortex_m7_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x00000200);
SET_IDREG(idregs, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x00100030;
- cpu->isar.id_mmfr1 = 0x00000000;
- cpu->isar.id_mmfr2 = 0x01000000;
- cpu->isar.id_mmfr3 = 0x00000000;
+ SET_IDREG(idregs, ID_MMFR0, 0x00100030);
+ SET_IDREG(idregs, ID_MMFR1, 0x00000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01000000);
+ SET_IDREG(idregs, ID_MMFR3, 0x00000000);
SET_IDREG(idregs, ID_ISAR0, 0x01101110);
SET_IDREG(idregs, ID_ISAR1, 0x02112000);
SET_IDREG(idregs, ID_ISAR2, 0x20232231);
@@ -185,10 +185,10 @@ static void cortex_m33_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x00000210);
SET_IDREG(idregs, ID_DFR0, 0x00200000);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x00101F40;
- cpu->isar.id_mmfr1 = 0x00000000;
- cpu->isar.id_mmfr2 = 0x01000000;
- cpu->isar.id_mmfr3 = 0x00000000;
+ SET_IDREG(idregs, ID_MMFR0, 0x00101F40);
+ SET_IDREG(idregs, ID_MMFR1, 0x00000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01000000);
+ SET_IDREG(idregs, ID_MMFR3, 0x00000000);
SET_IDREG(idregs, ID_ISAR0, 0x01101110);
SET_IDREG(idregs, ID_ISAR1, 0x02212000);
SET_IDREG(idregs, ID_ISAR2, 0x20232232);
@@ -223,10 +223,10 @@ static void cortex_m55_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x00000230);
SET_IDREG(idregs, ID_DFR0, 0x10200000);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x00111040;
- cpu->isar.id_mmfr1 = 0x00000000;
- cpu->isar.id_mmfr2 = 0x01000000;
- cpu->isar.id_mmfr3 = 0x00000011;
+ SET_IDREG(idregs, ID_MMFR0, 0x00111040);
+ SET_IDREG(idregs, ID_MMFR1, 0x00000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01000000);
+ SET_IDREG(idregs, ID_MMFR3, 0x00000011);
SET_IDREG(idregs, ID_ISAR0, 0x01103110);
SET_IDREG(idregs, ID_ISAR1, 0x02212000);
SET_IDREG(idregs, ID_ISAR2, 0x20232232);
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
index 3036c39d00f1..7606bd263fca 100644
--- a/target/arm/tcg/cpu32.c
+++ b/target/arm/tcg/cpu32.c
@@ -55,21 +55,17 @@ void aa32_max_features(ARMCPU *cpu)
t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
cpu->isar.mvfr2 = t;
- t = cpu->isar.id_mmfr3;
- t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* FEAT_PAN2 */
- cpu->isar.id_mmfr3 = t;
+ FIELD_DP32_IDREG(idregs, ID_MMFR3, PAN, 2); /* FEAT_PAN2 */
- t = cpu->isar.id_mmfr4;
+ t = GET_IDREG(idregs, ID_MMFR4);
t = FIELD_DP32(t, ID_MMFR4, HPDS, 2); /* FEAT_HPDS2 */
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* FEAT_TTCNP */
t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* FEAT_XNX */
t = FIELD_DP32(t, ID_MMFR4, EVT, 2); /* FEAT_EVT */
- cpu->isar.id_mmfr4 = t;
+ SET_IDREG(idregs, ID_MMFR4, t);
- t = cpu->isar.id_mmfr5;
- t = FIELD_DP32(t, ID_MMFR5, ETS, 2); /* FEAT_ETS2 */
- cpu->isar.id_mmfr5 = t;
+ FIELD_DP32_IDREG(idregs, ID_MMFR5, ETS, 2); /* FEAT_ETS2 */
t = GET_IDREG(idregs, ID_PFR0);
t = FIELD_DP32(t, ID_PFR0, CSV2, 2); /* FEAT_CSV2 */
@@ -230,9 +226,9 @@ static void arm1136_r2_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x1);
SET_IDREG(idregs, ID_DFR0, 0x2);
cpu->id_afr0 = 0x3;
- cpu->isar.id_mmfr0 = 0x01130003;
- cpu->isar.id_mmfr1 = 0x10030302;
- cpu->isar.id_mmfr2 = 0x01222110;
+ SET_IDREG(idregs, ID_MMFR0, 0x01130003);
+ SET_IDREG(idregs, ID_MMFR1, 0x10030302);
+ SET_IDREG(idregs, ID_MMFR2, 0x01222110);
SET_IDREG(idregs, ID_ISAR0, 0x00140011);
SET_IDREG(idregs, ID_ISAR1, 0x12002111);
SET_IDREG(idregs, ID_ISAR2, 0x11231111);
@@ -262,9 +258,9 @@ static void arm1136_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x1);
SET_IDREG(idregs, ID_DFR0, 0x2);
cpu->id_afr0 = 0x3;
- cpu->isar.id_mmfr0 = 0x01130003;
- cpu->isar.id_mmfr1 = 0x10030302;
- cpu->isar.id_mmfr2 = 0x01222110;
+ SET_IDREG(idregs, ID_MMFR0, 0x01130003);
+ SET_IDREG(idregs, ID_MMFR1, 0x10030302);
+ SET_IDREG(idregs, ID_MMFR2, 0x01222110);
SET_IDREG(idregs, ID_ISAR0, 0x00140011);
SET_IDREG(idregs, ID_ISAR1, 0x12002111);
SET_IDREG(idregs, ID_ISAR2, 0x11231111);
@@ -295,9 +291,9 @@ static void arm1176_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x11);
SET_IDREG(idregs, ID_DFR0, 0x33);
cpu->id_afr0 = 0;
- cpu->isar.id_mmfr0 = 0x01130003;
- cpu->isar.id_mmfr1 = 0x10030302;
- cpu->isar.id_mmfr2 = 0x01222100;
+ SET_IDREG(idregs, ID_MMFR0, 0x01130003);
+ SET_IDREG(idregs, ID_MMFR1, 0x10030302);
+ SET_IDREG(idregs, ID_MMFR2, 0x01222100);
SET_IDREG(idregs, ID_ISAR0, 0x0140011);
SET_IDREG(idregs, ID_ISAR1, 0x12002111);
SET_IDREG(idregs, ID_ISAR2, 0x11231121);
@@ -325,9 +321,9 @@ static void arm11mpcore_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x1);
SET_IDREG(idregs, ID_DFR0, 0);
cpu->id_afr0 = 0x2;
- cpu->isar.id_mmfr0 = 0x01100103;
- cpu->isar.id_mmfr1 = 0x10020302;
- cpu->isar.id_mmfr2 = 0x01222000;
+ SET_IDREG(idregs, ID_MMFR0, 0x01100103);
+ SET_IDREG(idregs, ID_MMFR1, 0x10020302);
+ SET_IDREG(idregs, ID_MMFR2, 0x01222000);
SET_IDREG(idregs, ID_ISAR0, 0x00100011);
SET_IDREG(idregs, ID_ISAR1, 0x12002111);
SET_IDREG(idregs, ID_ISAR2, 0x11221011);
@@ -365,10 +361,10 @@ static void cortex_a8_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x11);
SET_IDREG(idregs, ID_DFR0, 0x400);
cpu->id_afr0 = 0;
- cpu->isar.id_mmfr0 = 0x31100003;
- cpu->isar.id_mmfr1 = 0x20000000;
- cpu->isar.id_mmfr2 = 0x01202000;
- cpu->isar.id_mmfr3 = 0x11;
+ SET_IDREG(idregs, ID_MMFR0, 0x31100003);
+ SET_IDREG(idregs, ID_MMFR1, 0x20000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01202000);
+ SET_IDREG(idregs, ID_MMFR3, 0x11);
SET_IDREG(idregs, ID_ISAR0, 0x00101111);
SET_IDREG(idregs, ID_ISAR1, 0x12112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232031);
@@ -441,10 +437,10 @@ static void cortex_a9_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x11);
SET_IDREG(idregs, ID_DFR0, 0x000);
cpu->id_afr0 = 0;
- cpu->isar.id_mmfr0 = 0x00100103;
- cpu->isar.id_mmfr1 = 0x20000000;
- cpu->isar.id_mmfr2 = 0x01230000;
- cpu->isar.id_mmfr3 = 0x00002111;
+ SET_IDREG(idregs, ID_MMFR0, 0x00100103);
+ SET_IDREG(idregs, ID_MMFR1, 0x20000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01230000);
+ SET_IDREG(idregs, ID_MMFR3, 0x00002111);
SET_IDREG(idregs, ID_ISAR0, 0x00101111);
SET_IDREG(idregs, ID_ISAR1, 0x13112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232041);
@@ -507,10 +503,10 @@ static void cortex_a7_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x00011011);
SET_IDREG(idregs, ID_DFR0, 0x02010555);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x10101105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01240000;
- cpu->isar.id_mmfr3 = 0x02102211;
+ SET_IDREG(idregs, ID_MMFR0, 0x10101105);
+ SET_IDREG(idregs, ID_MMFR1, 0x40000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01240000);
+ SET_IDREG(idregs, ID_MMFR3, 0x02102211);
/*
* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
* table 4-41 gives 0x02101110, which includes the arm div insns.
@@ -559,10 +555,10 @@ static void cortex_a15_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x00011011);
SET_IDREG(idregs, ID_DFR0, 0x02010555);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x20000000;
- cpu->isar.id_mmfr2 = 0x01240000;
- cpu->isar.id_mmfr3 = 0x02102211;
+ SET_IDREG(idregs, ID_MMFR0, 0x10201105);
+ SET_IDREG(idregs, ID_MMFR1, 0x20000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01240000);
+ SET_IDREG(idregs, ID_MMFR3, 0x02102211);
SET_IDREG(idregs, ID_ISAR0, 0x02101110);
SET_IDREG(idregs, ID_ISAR1, 0x13112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232041);
@@ -603,10 +599,10 @@ static void cortex_r5_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x001);
SET_IDREG(idregs, ID_DFR0, 0x010400);
cpu->id_afr0 = 0x0;
- cpu->isar.id_mmfr0 = 0x0210030;
- cpu->isar.id_mmfr1 = 0x00000000;
- cpu->isar.id_mmfr2 = 0x01200000;
- cpu->isar.id_mmfr3 = 0x0211;
+ SET_IDREG(idregs, ID_MMFR0, 0x0210030);
+ SET_IDREG(idregs, ID_MMFR1, 0x00000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01200000);
+ SET_IDREG(idregs, ID_MMFR3, 0x0211);
SET_IDREG(idregs, ID_ISAR0, 0x02101111);
SET_IDREG(idregs, ID_ISAR1, 0x13112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232141);
@@ -750,11 +746,11 @@ static void cortex_r52_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x10111001);
SET_IDREG(idregs, ID_DFR0, 0x03010006);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x00211040;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01200000;
- cpu->isar.id_mmfr3 = 0xf0102211;
- cpu->isar.id_mmfr4 = 0x00000010;
+ SET_IDREG(idregs, ID_MMFR0, 0x00211040);
+ SET_IDREG(idregs, ID_MMFR1, 0x40000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01200000);
+ SET_IDREG(idregs, ID_MMFR3, 0xf0102211);
+ SET_IDREG(idregs, ID_MMFR4, 0x00000010);
SET_IDREG(idregs, ID_ISAR0, 0x02101110);
SET_IDREG(idregs, ID_ISAR1, 0x13112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232142);
@@ -982,10 +978,10 @@ static void arm_max_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x00011011);
SET_IDREG(idregs, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x10101105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02102211;
+ ET_IDREG(idregs, ID_MMFR0, 0x10101105);
+ ET_IDREG(idregs, ID_MMFR1, 0x40000000);
+ ET_IDREG(idregs, ID_MMFR2, 0x01260000);
+ ET_IDREG(idregs, ID_MMFR3, 0x02102211);
SET_IDREG(idregs, ID_ISAR0, 0x02101110);
SET_IDREG(idregs, ID_ISAR1, 0x13112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232042);
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index ead0b5600024..df1a958494a2 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -53,10 +53,10 @@ static void aarch64_a35_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x00011011);
SET_IDREG(idregs, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0;
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02102211;
+ SET_IDREG(idregs, ID_MMFR0, 0x10201105);
+ SET_IDREG(idregs, ID_MMFR1, 0x40000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01260000);
+ SET_IDREG(idregs, ID_MMFR3, 0x02102211);
SET_IDREG(idregs, ID_ISAR0, 0x02101110);
SET_IDREG(idregs, ID_ISAR1, 0x13112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232042);
@@ -236,11 +236,11 @@ static void aarch64_a55_initfn(Object *obj)
SET_IDREG(idregs, ID_ISAR4, 0x00011142);
SET_IDREG(idregs, ID_ISAR5, 0x01011121);
SET_IDREG(idregs, ID_ISAR6, 0x00000010);
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02122211;
- cpu->isar.id_mmfr4 = 0x00021110;
+ SET_IDREG(idregs, ID_MMFR0, 0x10201105);
+ SET_IDREG(idregs, ID_MMFR1, 0x40000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01260000);
+ SET_IDREG(idregs, ID_MMFR3, 0x02122211);
+ SET_IDREG(idregs, ID_MMFR4, 0x00021110);
SET_IDREG(idregs, ID_PFR0, 0x10010131);
SET_IDREG(idregs, ID_PFR1, 0x00011011);
SET_IDREG(idregs, ID_PFR2, 0x00000011);
@@ -299,10 +299,10 @@ static void aarch64_a72_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x00011011);
SET_IDREG(idregs, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02102211;
+ SET_IDREG(idregs, ID_MMFR0, 0x10201105);
+ SET_IDREG(idregs, ID_MMFR1, 0x40000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01260000);
+ SET_IDREG(idregs, ID_MMFR3, 0x02102211);
SET_IDREG(idregs, ID_ISAR0, 0x02101110);
SET_IDREG(idregs, ID_ISAR1, 0x13112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232042);
@@ -369,11 +369,11 @@ static void aarch64_a76_initfn(Object *obj)
SET_IDREG(idregs, ID_ISAR4, 0x00010142);
SET_IDREG(idregs, ID_ISAR5, 0x01011121);
SET_IDREG(idregs, ID_ISAR6, 0x00000010);
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02122211;
- cpu->isar.id_mmfr4 = 0x00021110;
+ SET_IDREG(idregs, ID_MMFR0, 0x10201105);
+ SET_IDREG(idregs, ID_MMFR1, 0x40000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01260000);
+ SET_IDREG(idregs, ID_MMFR3, 0x02122211);
+ SET_IDREG(idregs, ID_MMFR4, 0x00021110);
SET_IDREG(idregs, ID_PFR0, 0x10010131);
SET_IDREG(idregs, ID_PFR1, 0x00010000); /* GIC filled in later */
SET_IDREG(idregs, ID_PFR2, 0x00000011);
@@ -617,11 +617,11 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
SET_IDREG(idregs, ID_ISAR4, 0x00010142);
SET_IDREG(idregs, ID_ISAR5, 0x01011121);
SET_IDREG(idregs, ID_ISAR6, 0x00000010);
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02122211;
- cpu->isar.id_mmfr4 = 0x00021110;
+ SET_IDREG(idregs, ID_MMFR0, 0x10201105);
+ SET_IDREG(idregs, ID_MMFR1, 0x40000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01260000);
+ SET_IDREG(idregs, ID_MMFR3, 0x02122211);
+ SET_IDREG(idregs, ID_MMFR4, 0x00021110);
SET_IDREG(idregs, ID_PFR0, 0x10010131);
SET_IDREG(idregs, ID_PFR1, 0x00010000); /* GIC filled in later */
SET_IDREG(idregs, ID_PFR2, 0x00000011);
@@ -696,11 +696,11 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
SET_IDREG(idregs, ID_ISAR4, 0x00010142);
SET_IDREG(idregs, ID_ISAR5, 0x11011121);
SET_IDREG(idregs, ID_ISAR6, 0x01100111);
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02122211;
- cpu->isar.id_mmfr4 = 0x01021110;
+ SET_IDREG(idregs, ID_MMFR0, 0x10201105);
+ SET_IDREG(idregs, ID_MMFR1, 0x40000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01260000);
+ SET_IDREG(idregs, ID_MMFR3, 0x02122211);
+ SET_IDREG(idregs, ID_MMFR4, 0x01021110);
SET_IDREG(idregs, ID_PFR0, 0x21110131);
SET_IDREG(idregs, ID_PFR1, 0x00010000); /* GIC filled in later */
SET_IDREG(idregs, ID_PFR2, 0x00000011);
@@ -906,17 +906,17 @@ static void aarch64_a710_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x00010000); /* GIC filled in later */
SET_IDREG(idregs, ID_DFR0, 0x16011099);
cpu->id_afr0 = 0;
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02122211;
+ SET_IDREG(idregs, ID_MMFR0, 0x10201105);
+ SET_IDREG(idregs, ID_MMFR1, 0x40000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01260000);
+ SET_IDREG(idregs, ID_MMFR3, 0x02122211);
SET_IDREG(idregs, ID_ISAR0, 0x02101110);
SET_IDREG(idregs, ID_ISAR1, 0x13112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232042);
SET_IDREG(idregs, ID_ISAR3, 0x01112131);
SET_IDREG(idregs, ID_ISAR4, 0x00010142);
SET_IDREG(idregs, ID_ISAR5, 0x11011121); /* with Crypto */
- cpu->isar.id_mmfr4 = 0x21021110;
+ SET_IDREG(idregs, ID_MMFR4, 0x21021110);
SET_IDREG(idregs, ID_ISAR6, 0x01111111);
cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x13211111;
@@ -1009,17 +1009,17 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
SET_IDREG(idregs, ID_PFR1, 0x00010000); /* GIC filled in later */
SET_IDREG(idregs, ID_DFR0, 0x16011099);
cpu->id_afr0 = 0;
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02122211;
+ SET_IDREG(idregs, ID_MMFR0, 0x10201105);
+ SET_IDREG(idregs, ID_MMFR1, 0x40000000);
+ SET_IDREG(idregs, ID_MMFR2, 0x01260000);
+ SET_IDREG(idregs, ID_MMFR3, 0x02122211);
SET_IDREG(idregs, ID_ISAR0, 0x02101110);
SET_IDREG(idregs, ID_ISAR1, 0x13112111);
SET_IDREG(idregs, ID_ISAR2, 0x21232042);
SET_IDREG(idregs, ID_ISAR3, 0x01112131);
SET_IDREG(idregs, ID_ISAR4, 0x00010142);
SET_IDREG(idregs, ID_ISAR5, 0x11011121); /* with Crypto */
- cpu->isar.id_mmfr4 = 0x01021110;
+ SET_IDREG(idregs, ID_MMFR4, 0x01021110);
SET_IDREG(idregs, ID_ISAR6, 0x01111111);
cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x13211111;
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 13/20] arm/cpu: Add infra to handle generated ID register definitions
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (11 preceding siblings ...)
2024-12-06 11:22 ` [PATCH RFCv2 12/20] arm/cpu: Store id_mmfr0-5 " Cornelia Huck
@ 2024-12-06 11:22 ` Cornelia Huck
2024-12-06 11:22 ` [PATCH RFCv2 14/20] arm/cpu: Add sysreg generation scripts Cornelia Huck
` (10 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:22 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
The known ID regs are described in a new initialization function
dubbed initialize_cpu_sysreg_properties(). That code will be
automatically generated from linux arch/arm64/tools/sysreg. For the
time being let's just describe a single id reg, CTR_EL0. In this
description we only care about non RES/RAZ fields, ie. named fields.
The registers are populated in a 3x8x8 array 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>
---
target/arm/cpu-custom.h | 58 ++++++++++++++++++++++++++++++
target/arm/cpu-sysreg-properties.c | 41 +++++++++++++++++++++
target/arm/cpu64.c | 2 ++
target/arm/meson.build | 1 +
4 files changed, 102 insertions(+)
create mode 100644 target/arm/cpu-custom.h
create mode 100644 target/arm/cpu-sysreg-properties.c
diff --git a/target/arm/cpu-custom.h b/target/arm/cpu-custom.h
new file mode 100644
index 000000000000..1952095bf7b8
--- /dev/null
+++ b/target/arm/cpu-custom.h
@@ -0,0 +1,58 @@
+#ifndef ARM_CPU_CUSTOM_H
+#define ARM_CPU_CUSTOM_H
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "cpu.h"
+#include "cpu-sysregs.h"
+
+typedef struct ARM64SysRegField {
+ const char *name; /* name of the field, for instance CTR_EL0_IDC */
+ int index;
+ int lower;
+ int upper;
+} ARM64SysRegField;
+
+typedef struct ARM64SysReg {
+ const char *name; /* name of the sysreg, for instance CTR_EL0 */
+ ARMSysReg *sysreg;
+ int index;
+ GList *fields; /* list of named fields, excluding RES* */
+} ARM64SysReg;
+
+void initialize_cpu_sysreg_properties(void);
+
+/*
+ * List of exposed ID regs (automatically populated from linux
+ * arch/arm64/tools/sysreg)
+ */
+extern ARM64SysReg arm64_id_regs[NR_ID_REGS];
+
+/* Allocate a new field and insert it at the head of the @reg list */
+static inline GList *arm64_sysreg_add_field(ARM64SysReg *reg, const char *name,
+ uint8_t min, uint8_t max) {
+
+ ARM64SysRegField *field = g_new0(ARM64SysRegField, 1);
+
+ field->name = name;
+ field->lower = min;
+ field->upper = max;
+ field->index = reg->index;
+
+ reg->fields = g_list_append(reg->fields, field);
+ return reg->fields;
+}
+
+static inline ARM64SysReg *
+arm64_sysreg_get(int op0, int op1, int crn, int crm, int op2)
+{
+ uint64_t index = ARM_FEATURE_ID_RANGE_IDX(op0, op1, crn, crm, op2);
+ ARM64SysReg *reg = &arm64_id_regs[index];
+
+ reg->index = index;
+ reg->sysreg = g_new(ARMSysReg, 1);
+ *reg->sysreg = sys_reg(op0, op1, crn, crm, op2);
+ return reg;
+}
+
+#endif
diff --git a/target/arm/cpu-sysreg-properties.c b/target/arm/cpu-sysreg-properties.c
new file mode 100644
index 000000000000..7e6b9f526d32
--- /dev/null
+++ b/target/arm/cpu-sysreg-properties.c
@@ -0,0 +1,41 @@
+/*
+ * QEMU ARM CPU SYSREG PROPERTIES
+ * to be generated from linux sysreg
+ *
+ * Copyright (c) Red Hat, Inc. 2024
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
+ */
+
+#include "cpu-custom.h"
+
+ARM64SysReg arm64_id_regs[NR_ID_REGS];
+
+void initialize_cpu_sysreg_properties(void)
+{
+ memset(arm64_id_regs, 0, sizeof(ARM64SysReg) * NR_ID_REGS);
+ /* CTR_EL0 */
+ ARM64SysReg *CTR_EL0 = arm64_sysreg_get(3, 3, 0, 0, 1);
+ CTR_EL0->name = "CTR_EL0";
+ arm64_sysreg_add_field(CTR_EL0, "TMinline", 32, 37);
+ arm64_sysreg_add_field(CTR_EL0, "DIC", 29, 29);
+ arm64_sysreg_add_field(CTR_EL0, "IDC", 28, 28);
+ arm64_sysreg_add_field(CTR_EL0, "CWG", 24, 27);
+ arm64_sysreg_add_field(CTR_EL0, "ERG", 20, 23);
+ arm64_sysreg_add_field(CTR_EL0, "DMinLine", 16, 19);
+ arm64_sysreg_add_field(CTR_EL0, "L1Ip", 14, 15);
+ arm64_sysreg_add_field(CTR_EL0, "IminLine", 0, 3);
+}
+
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index efc930ff8367..29558cda8186 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -35,6 +35,7 @@
#include "internals.h"
#include "cpu-features.h"
#include "cpregs.h"
+#include "cpu-custom.h"
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
{
@@ -851,6 +852,7 @@ static void aarch64_cpu_register_types(void)
{
size_t i;
+ initialize_cpu_sysreg_properties();
type_register_static(&aarch64_cpu_type_info);
for (i = 0; i < ARRAY_SIZE(aarch64_cpus); ++i) {
diff --git a/target/arm/meson.build b/target/arm/meson.build
index 2e10464dbb6b..9c7a04ee1b26 100644
--- a/target/arm/meson.build
+++ b/target/arm/meson.build
@@ -14,6 +14,7 @@ arm_ss.add(when: 'CONFIG_HVF', if_true: files('hyp_gdbstub.c'))
arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
'cpu64.c',
'gdbstub64.c',
+ 'cpu-sysreg-properties.c',
))
arm_system_ss = ss.source_set()
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 14/20] arm/cpu: Add sysreg generation scripts
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (12 preceding siblings ...)
2024-12-06 11:22 ` [PATCH RFCv2 13/20] arm/cpu: Add infra to handle generated ID register definitions Cornelia Huck
@ 2024-12-06 11:22 ` Cornelia Huck
2024-12-06 11:22 ` [PATCH RFCv2 15/20] arm/cpu: Add generated files Cornelia Huck
` (9 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:22 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
Introduce scripts that automate the generation of system register
definitions from a given linux source tree arch/arm64/tools/sysreg.
Invocation of
./update-aarch64-sysreg-code.sh $PATH_TO_LINUX_SOURCE_TREE
in scripts directory do generate 2 qemu files:
- target/arm/cpu-sysreg-properties.c
- target/arm/cpu-sysregs.h
cpu-sysregs.h creates defined for all system registers.
However cpu-sysreg-properties.c only cares about feature ID registers.
update-aarch64-sysreg-code.sh calls two awk scripts.
gen-cpu-sysreg-properties.awk is inherited from kernel
arch/arm64/tools/gen-sysreg.awk. All credits to Mark Rutland
the original author of this script.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
scripts/gen-cpu-sysreg-properties.awk | 325 ++++++++++++++++++++++++++
| 47 ++++
scripts/update-aarch64-sysreg-code.sh | 27 +++
3 files changed, 399 insertions(+)
create mode 100755 scripts/gen-cpu-sysreg-properties.awk
create mode 100755 scripts/gen-cpu-sysregs-header.awk
create mode 100755 scripts/update-aarch64-sysreg-code.sh
diff --git a/scripts/gen-cpu-sysreg-properties.awk b/scripts/gen-cpu-sysreg-properties.awk
new file mode 100755
index 000000000000..b0ed55e05999
--- /dev/null
+++ b/scripts/gen-cpu-sysreg-properties.awk
@@ -0,0 +1,325 @@
+#!/bin/awk -f
+# SPDX-License-Identifier: GPL-2.0
+# gen-sysreg.awk: arm64 sysreg header generator
+#
+# Usage: awk -f gen-custom-sysreg.awk $LINUX_PATH/arch/arm64/tools/sysreg
+
+function block_current() {
+ return __current_block[__current_block_depth];
+}
+
+# Log an error and terminate
+function fatal(msg) {
+ print "Error at " NR ": " msg > "/dev/stderr"
+
+ printf "Current block nesting:"
+
+ for (i = 0; i <= __current_block_depth; i++) {
+ printf " " __current_block[i]
+ }
+ printf "\n"
+
+ exit 1
+}
+
+# Enter a new block, setting the active block to @block
+function block_push(block) {
+ __current_block[++__current_block_depth] = block
+}
+
+# Exit a block, setting the active block to the parent block
+function block_pop() {
+ if (__current_block_depth == 0)
+ fatal("error: block_pop() in root block")
+
+ __current_block_depth--;
+}
+
+# Sanity check the number of records for a field makes sense. If not, produce
+# an error and terminate.
+function expect_fields(nf) {
+ if (NF != nf)
+ fatal(NF " fields found where " nf " expected")
+}
+
+# Print a CPP macro definition, padded with spaces so that the macro bodies
+# line up in a column
+function define(name, val) {
+ printf "%-56s%s\n", "#define " name, val
+}
+
+# Print standard BITMASK/SHIFT/WIDTH CPP definitions for a field
+function define_field(reg, field, msb, lsb, idreg) {
+ if (idreg)
+ print " arm64_sysreg_add_field("reg", \""field"\", "lsb", "msb");"
+}
+
+# Print a field _SIGNED definition for a field
+function define_field_sign(reg, field, sign, idreg) {
+ if (idreg)
+ print " arm64_sysreg_add_field("reg", \""field"\", "lsb", "msb");"
+}
+
+# Parse a "<msb>[:<lsb>]" string into the global variables @msb and @lsb
+function parse_bitdef(reg, field, bitdef, _bits)
+{
+ if (bitdef ~ /^[0-9]+$/) {
+ msb = bitdef
+ lsb = bitdef
+ } else if (split(bitdef, _bits, ":") == 2) {
+ msb = _bits[1]
+ lsb = _bits[2]
+ } else {
+ fatal("invalid bit-range definition '" bitdef "'")
+ }
+
+
+ if (msb != next_bit)
+ fatal(reg "." field " starts at " msb " not " next_bit)
+ if (63 < msb || msb < 0)
+ fatal(reg "." field " invalid high bit in '" bitdef "'")
+ if (63 < lsb || lsb < 0)
+ fatal(reg "." field " invalid low bit in '" bitdef "'")
+ if (msb < lsb)
+ fatal(reg "." field " invalid bit-range '" bitdef "'")
+ if (low > high)
+ fatal(reg "." field " has invalid range " high "-" low)
+
+ next_bit = lsb - 1
+}
+
+BEGIN {
+ print "#include \"cpu-custom.h\""
+ print ""
+ print "ARM64SysReg arm64_id_regs[NR_ID_REGS];"
+ print ""
+ print "void initialize_cpu_sysreg_properties(void)"
+ print "{"
+ print " memset(arm64_id_regs, 0, sizeof(ARM64SysReg) * NR_ID_REGS);"
+ print ""
+
+ __current_block_depth = 0
+ __current_block[__current_block_depth] = "Root"
+}
+
+END {
+ if (__current_block_depth != 0)
+ fatal("Missing terminator for " block_current() " block")
+
+ print "}"
+}
+
+# skip blank lines and comment lines
+/^$/ { next }
+/^[\t ]*#/ { next }
+
+/^SysregFields/ && block_current() == "Root" {
+ block_push("SysregFields")
+
+ expect_fields(2)
+
+ reg = $2
+
+ res0 = "UL(0)"
+ res1 = "UL(0)"
+ unkn = "UL(0)"
+
+ next_bit = 63
+
+ next
+}
+
+/^EndSysregFields/ && block_current() == "SysregFields" {
+ if (next_bit > 0)
+ fatal("Unspecified bits in " reg)
+
+ reg = null
+ res0 = null
+ res1 = null
+ unkn = null
+
+ block_pop()
+ next
+}
+
+/^Sysreg/ && block_current() == "Root" {
+ block_push("Sysreg")
+
+ expect_fields(7)
+
+ reg = $2
+ op0 = $3
+ op1 = $4
+ crn = $5
+ crm = $6
+ op2 = $7
+
+ res0 = "UL(0)"
+ res1 = "UL(0)"
+ unkn = "UL(0)"
+
+ if (op0 == 3 && (op1>=0 && op1<=3) && crn==0 && (crm>=0 && crm<=7) && (op2>=0 && op2<=7)) {
+ idreg = 1
+ } else {
+ idreg = 0
+ }
+
+ if (idreg == 1) {
+ print " /* "reg" */"
+ print " ARM64SysReg *"reg" = arm64_sysreg_get("op0", "op1", "crn", "crm", "op2");"
+ print " "reg"->name = \""reg"\";"
+ }
+
+ next_bit = 63
+
+ next
+}
+
+/^EndSysreg/ && block_current() == "Sysreg" {
+ if (next_bit > 0)
+ fatal("Unspecified bits in " reg)
+
+ reg = null
+ op0 = null
+ op1 = null
+ crn = null
+ crm = null
+ op2 = null
+ res0 = null
+ res1 = null
+ unkn = null
+
+ if (idreg==1)
+ print ""
+ block_pop()
+ next
+}
+
+# Currently this is effectivey a comment, in future we may want to emit
+# defines for the fields.
+/^Fields/ && block_current() == "Sysreg" {
+ expect_fields(2)
+
+ if (next_bit != 63)
+ fatal("Some fields already defined for " reg)
+
+ print "/* For " reg " fields see " $2 " */"
+ print ""
+
+ next_bit = 0
+ res0 = null
+ res1 = null
+ unkn = null
+
+ next
+}
+
+
+/^Res0/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+ expect_fields(2)
+ parse_bitdef(reg, "RES0", $2)
+ field = "RES0_" msb "_" lsb
+
+ res0 = res0 " | GENMASK_ULL(" msb ", " lsb ")"
+
+ next
+}
+
+/^Res1/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+ expect_fields(2)
+ parse_bitdef(reg, "RES1", $2)
+ field = "RES1_" msb "_" lsb
+
+ res1 = res1 " | GENMASK_ULL(" msb ", " lsb ")"
+
+ next
+}
+
+/^Unkn/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+ expect_fields(2)
+ parse_bitdef(reg, "UNKN", $2)
+ field = "UNKN_" msb "_" lsb
+
+ unkn = unkn " | GENMASK_ULL(" msb ", " lsb ")"
+
+ next
+}
+
+/^Field/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+ expect_fields(3)
+ field = $3
+ parse_bitdef(reg, field, $2)
+
+
+ define_field(reg, field, msb, lsb, idreg)
+
+ next
+}
+
+/^Raz/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+ expect_fields(2)
+ parse_bitdef(reg, field, $2)
+
+ next
+}
+
+/^SignedEnum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+ block_push("Enum")
+
+ expect_fields(3)
+ field = $3
+ parse_bitdef(reg, field, $2)
+
+ define_field(reg, field, msb, lsb, idreg)
+ define_field_sign(reg, field, "true", idreg)
+
+ next
+}
+
+/^UnsignedEnum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+ block_push("Enum")
+
+ expect_fields(3)
+ field = $3
+ parse_bitdef(reg, field, $2)
+
+ define_field(reg, field, msb, lsb, idreg)
+ #define_field_sign(reg, field, "false", idreg)
+
+ next
+}
+
+/^Enum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") {
+ block_push("Enum")
+
+ expect_fields(3)
+ field = $3
+ parse_bitdef(reg, field, $2)
+
+ define_field(reg, field, msb, lsb, idreg)
+
+ next
+}
+
+/^EndEnum/ && block_current() == "Enum" {
+
+ field = null
+ msb = null
+ lsb = null
+
+ block_pop()
+ next
+}
+
+/0b[01]+/ && block_current() == "Enum" {
+ expect_fields(2)
+ val = $1
+ name = $2
+
+ next
+}
+
+# Any lines not handled by previous rules are unexpected
+{
+ fatal("unhandled statement")
+}
--git a/scripts/gen-cpu-sysregs-header.awk b/scripts/gen-cpu-sysregs-header.awk
new file mode 100755
index 000000000000..cdad686a53bc
--- /dev/null
+++ b/scripts/gen-cpu-sysregs-header.awk
@@ -0,0 +1,47 @@
+#!/bin/awk -f
+# SPDX-License-Identifier: GPL-2.0
+# gen-sysreg.awk: arm64 sysreg header generator
+#
+# Usage: awk -f gen-custom-sysreg.awk $LINUX_PATH/arch/arm64/tools/sysreg
+
+# Sanity check the number of records for a field makes sense. If not, produce
+# an error and terminate.
+
+# Print a CPP macro definition, padded with spaces so that the macro bodies
+# line up in a column
+function define(name, val) {
+ printf "%-56s%s\n", "#define " name, val
+}
+
+BEGIN {
+ print "#ifndef ARM_CPU_SYSREGS_H"
+ print "#define ARM_CPU_SYSREGS_H"
+ print ""
+ print "/* Generated file - do not edit */"
+ print ""
+} END {
+ print ""
+ print "#endif /* ARM_CPU_SYSREGS_H */"
+}
+
+# skip blank lines and comment lines
+/^$/ { next }
+/^[\t ]*#/ { next }
+
+/^Sysreg\t/ || /^Sysreg /{
+
+ reg = $2
+ op0 = $3
+ op1 = $4
+ crn = $5
+ crm = $6
+ op2 = $7
+
+ define("SYS_" reg, "sys_reg(" op0 ", " op1 ", " crn ", " crm ", " op2 ")")
+ next
+}
+
+{
+ /* skip all other lines */
+ next
+}
diff --git a/scripts/update-aarch64-sysreg-code.sh b/scripts/update-aarch64-sysreg-code.sh
new file mode 100755
index 000000000000..e1fe40308ba1
--- /dev/null
+++ b/scripts/update-aarch64-sysreg-code.sh
@@ -0,0 +1,27 @@
+#!/bin/sh -e
+#
+# Update target/arm/cpu-sysreg-properties.c and target/arm/cpu-sysregs.h
+# from a linux source tree (arch/arm64/tools/sysreg)
+#
+# Copyright Red Hat, Inc. 2024
+#
+# Authors:
+# Eric Auger <eric.auger@redhat.com>
+#
+
+linux="$1"
+output="$PWD"
+
+if [ -z "$linux" ] || ! [ -d "$linux" ]; then
+ cat << EOF
+usage: update-aarch64-sysreg-code.sh LINUX_PATH
+
+LINUX_PATH Linux kernel directory to obtain the headers from
+EOF
+ exit 1
+fi
+
+awk -f gen-cpu-sysregs-header.awk \
+ $linux/arch/arm64/tools/sysreg > ../target/arm/cpu-sysregs.h
+awk -f gen-cpu-sysreg-properties.awk \
+ $linux/arch/arm64/tools/sysreg > ../target/arm/cpu-sysreg-properties.c
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 15/20] arm/cpu: Add generated files
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (13 preceding siblings ...)
2024-12-06 11:22 ` [PATCH RFCv2 14/20] arm/cpu: Add sysreg generation scripts Cornelia Huck
@ 2024-12-06 11:22 ` Cornelia Huck
2024-12-06 11:22 ` [PATCH RFCv2 16/20] arm/kvm: Allow reading all the writable ID registers Cornelia Huck
` (8 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:22 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
target/arm/cpu-sysreg-properties.c | 689 ++++++++++++++++++++++++++++-
target/arm/cpu-sysregs.h | 142 +++++-
2 files changed, 791 insertions(+), 40 deletions(-)
diff --git a/target/arm/cpu-sysreg-properties.c b/target/arm/cpu-sysreg-properties.c
index 7e6b9f526d32..4a3106cc4850 100644
--- a/target/arm/cpu-sysreg-properties.c
+++ b/target/arm/cpu-sysreg-properties.c
@@ -1,24 +1,3 @@
-/*
- * QEMU ARM CPU SYSREG PROPERTIES
- * to be generated from linux sysreg
- *
- * Copyright (c) Red Hat, Inc. 2024
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see
- * <http://www.gnu.org/licenses/gpl-2.0.html>
- */
-
#include "cpu-custom.h"
ARM64SysReg arm64_id_regs[NR_ID_REGS];
@@ -26,16 +5,678 @@ ARM64SysReg arm64_id_regs[NR_ID_REGS];
void initialize_cpu_sysreg_properties(void)
{
memset(arm64_id_regs, 0, sizeof(ARM64SysReg) * NR_ID_REGS);
+
+ /* ID_PFR0_EL1 */
+ ARM64SysReg *ID_PFR0_EL1 = arm64_sysreg_get(3, 0, 0, 1, 0);
+ ID_PFR0_EL1->name = "ID_PFR0_EL1";
+ arm64_sysreg_add_field(ID_PFR0_EL1, "RAS", 28, 31);
+ arm64_sysreg_add_field(ID_PFR0_EL1, "DIT", 24, 27);
+ arm64_sysreg_add_field(ID_PFR0_EL1, "AMU", 20, 23);
+ arm64_sysreg_add_field(ID_PFR0_EL1, "CSV2", 16, 19);
+ arm64_sysreg_add_field(ID_PFR0_EL1, "State3", 12, 15);
+ arm64_sysreg_add_field(ID_PFR0_EL1, "State2", 8, 11);
+ arm64_sysreg_add_field(ID_PFR0_EL1, "State1", 4, 7);
+ arm64_sysreg_add_field(ID_PFR0_EL1, "State0", 0, 3);
+
+ /* ID_PFR1_EL1 */
+ ARM64SysReg *ID_PFR1_EL1 = arm64_sysreg_get(3, 0, 0, 1, 1);
+ ID_PFR1_EL1->name = "ID_PFR1_EL1";
+ arm64_sysreg_add_field(ID_PFR1_EL1, "GIC", 28, 31);
+ arm64_sysreg_add_field(ID_PFR1_EL1, "Virt_frac", 24, 27);
+ arm64_sysreg_add_field(ID_PFR1_EL1, "Sec_frac", 20, 23);
+ arm64_sysreg_add_field(ID_PFR1_EL1, "GenTimer", 16, 19);
+ arm64_sysreg_add_field(ID_PFR1_EL1, "Virtualization", 12, 15);
+ arm64_sysreg_add_field(ID_PFR1_EL1, "MProgMod", 8, 11);
+ arm64_sysreg_add_field(ID_PFR1_EL1, "Security", 4, 7);
+ arm64_sysreg_add_field(ID_PFR1_EL1, "ProgMod", 0, 3);
+
+ /* ID_DFR0_EL1 */
+ ARM64SysReg *ID_DFR0_EL1 = arm64_sysreg_get(3, 0, 0, 1, 2);
+ ID_DFR0_EL1->name = "ID_DFR0_EL1";
+ arm64_sysreg_add_field(ID_DFR0_EL1, "TraceFilt", 28, 31);
+ arm64_sysreg_add_field(ID_DFR0_EL1, "PerfMon", 24, 27);
+ arm64_sysreg_add_field(ID_DFR0_EL1, "MProfDbg", 20, 23);
+ arm64_sysreg_add_field(ID_DFR0_EL1, "MMapTrc", 16, 19);
+ arm64_sysreg_add_field(ID_DFR0_EL1, "CopTrc", 12, 15);
+ arm64_sysreg_add_field(ID_DFR0_EL1, "MMapDbg", 8, 11);
+ arm64_sysreg_add_field(ID_DFR0_EL1, "CopSDbg", 4, 7);
+ arm64_sysreg_add_field(ID_DFR0_EL1, "CopDbg", 0, 3);
+
+ /* ID_AFR0_EL1 */
+ ARM64SysReg *ID_AFR0_EL1 = arm64_sysreg_get(3, 0, 0, 1, 3);
+ ID_AFR0_EL1->name = "ID_AFR0_EL1";
+ arm64_sysreg_add_field(ID_AFR0_EL1, "IMPDEF3", 12, 15);
+ arm64_sysreg_add_field(ID_AFR0_EL1, "IMPDEF2", 8, 11);
+ arm64_sysreg_add_field(ID_AFR0_EL1, "IMPDEF1", 4, 7);
+ arm64_sysreg_add_field(ID_AFR0_EL1, "IMPDEF0", 0, 3);
+
+ /* ID_MMFR0_EL1 */
+ ARM64SysReg *ID_MMFR0_EL1 = arm64_sysreg_get(3, 0, 0, 1, 4);
+ ID_MMFR0_EL1->name = "ID_MMFR0_EL1";
+ arm64_sysreg_add_field(ID_MMFR0_EL1, "InnerShr", 28, 31);
+ arm64_sysreg_add_field(ID_MMFR0_EL1, "FCSE", 24, 27);
+ arm64_sysreg_add_field(ID_MMFR0_EL1, "AuxReg", 20, 23);
+ arm64_sysreg_add_field(ID_MMFR0_EL1, "TCM", 16, 19);
+ arm64_sysreg_add_field(ID_MMFR0_EL1, "ShareLvl", 12, 15);
+ arm64_sysreg_add_field(ID_MMFR0_EL1, "OuterShr", 8, 11);
+ arm64_sysreg_add_field(ID_MMFR0_EL1, "PMSA", 4, 7);
+ arm64_sysreg_add_field(ID_MMFR0_EL1, "VMSA", 0, 3);
+
+ /* ID_MMFR1_EL1 */
+ ARM64SysReg *ID_MMFR1_EL1 = arm64_sysreg_get(3, 0, 0, 1, 5);
+ ID_MMFR1_EL1->name = "ID_MMFR1_EL1";
+ arm64_sysreg_add_field(ID_MMFR1_EL1, "BPred", 28, 31);
+ arm64_sysreg_add_field(ID_MMFR1_EL1, "L1TstCln", 24, 27);
+ arm64_sysreg_add_field(ID_MMFR1_EL1, "L1Uni", 20, 23);
+ arm64_sysreg_add_field(ID_MMFR1_EL1, "L1Hvd", 16, 19);
+ arm64_sysreg_add_field(ID_MMFR1_EL1, "L1UniSW", 12, 15);
+ arm64_sysreg_add_field(ID_MMFR1_EL1, "L1HvdSW", 8, 11);
+ arm64_sysreg_add_field(ID_MMFR1_EL1, "L1UniVA", 4, 7);
+ arm64_sysreg_add_field(ID_MMFR1_EL1, "L1HvdVA", 0, 3);
+
+ /* ID_MMFR2_EL1 */
+ ARM64SysReg *ID_MMFR2_EL1 = arm64_sysreg_get(3, 0, 0, 1, 6);
+ ID_MMFR2_EL1->name = "ID_MMFR2_EL1";
+ arm64_sysreg_add_field(ID_MMFR2_EL1, "HWAccFlg", 28, 31);
+ arm64_sysreg_add_field(ID_MMFR2_EL1, "WFIStall", 24, 27);
+ arm64_sysreg_add_field(ID_MMFR2_EL1, "MemBarr", 20, 23);
+ arm64_sysreg_add_field(ID_MMFR2_EL1, "UniTLB", 16, 19);
+ arm64_sysreg_add_field(ID_MMFR2_EL1, "HvdTLB", 12, 15);
+ arm64_sysreg_add_field(ID_MMFR2_EL1, "L1HvdRng", 8, 11);
+ arm64_sysreg_add_field(ID_MMFR2_EL1, "L1HvdBG", 4, 7);
+ arm64_sysreg_add_field(ID_MMFR2_EL1, "L1HvdFG", 0, 3);
+
+ /* ID_MMFR3_EL1 */
+ ARM64SysReg *ID_MMFR3_EL1 = arm64_sysreg_get(3, 0, 0, 1, 7);
+ ID_MMFR3_EL1->name = "ID_MMFR3_EL1";
+ arm64_sysreg_add_field(ID_MMFR3_EL1, "Supersec", 28, 31);
+ arm64_sysreg_add_field(ID_MMFR3_EL1, "CMemSz", 24, 27);
+ arm64_sysreg_add_field(ID_MMFR3_EL1, "CohWalk", 20, 23);
+ arm64_sysreg_add_field(ID_MMFR3_EL1, "PAN", 16, 19);
+ arm64_sysreg_add_field(ID_MMFR3_EL1, "MaintBcst", 12, 15);
+ arm64_sysreg_add_field(ID_MMFR3_EL1, "BPMaint", 8, 11);
+ arm64_sysreg_add_field(ID_MMFR3_EL1, "CMaintSW", 4, 7);
+ arm64_sysreg_add_field(ID_MMFR3_EL1, "CMaintVA", 0, 3);
+
+ /* ID_ISAR0_EL1 */
+ ARM64SysReg *ID_ISAR0_EL1 = arm64_sysreg_get(3, 0, 0, 2, 0);
+ ID_ISAR0_EL1->name = "ID_ISAR0_EL1";
+ arm64_sysreg_add_field(ID_ISAR0_EL1, "Divide", 24, 27);
+ arm64_sysreg_add_field(ID_ISAR0_EL1, "Debug", 20, 23);
+ arm64_sysreg_add_field(ID_ISAR0_EL1, "Coproc", 16, 19);
+ arm64_sysreg_add_field(ID_ISAR0_EL1, "CmpBranch", 12, 15);
+ arm64_sysreg_add_field(ID_ISAR0_EL1, "BitField", 8, 11);
+ arm64_sysreg_add_field(ID_ISAR0_EL1, "BitCount", 4, 7);
+ arm64_sysreg_add_field(ID_ISAR0_EL1, "Swap", 0, 3);
+
+ /* ID_ISAR1_EL1 */
+ ARM64SysReg *ID_ISAR1_EL1 = arm64_sysreg_get(3, 0, 0, 2, 1);
+ ID_ISAR1_EL1->name = "ID_ISAR1_EL1";
+ arm64_sysreg_add_field(ID_ISAR1_EL1, "Jazelle", 28, 31);
+ arm64_sysreg_add_field(ID_ISAR1_EL1, "Interwork", 24, 27);
+ arm64_sysreg_add_field(ID_ISAR1_EL1, "Immediate", 20, 23);
+ arm64_sysreg_add_field(ID_ISAR1_EL1, "IfThen", 16, 19);
+ arm64_sysreg_add_field(ID_ISAR1_EL1, "Extend", 12, 15);
+ arm64_sysreg_add_field(ID_ISAR1_EL1, "Except_AR", 8, 11);
+ arm64_sysreg_add_field(ID_ISAR1_EL1, "Except", 4, 7);
+ arm64_sysreg_add_field(ID_ISAR1_EL1, "Endian", 0, 3);
+
+ /* ID_ISAR2_EL1 */
+ ARM64SysReg *ID_ISAR2_EL1 = arm64_sysreg_get(3, 0, 0, 2, 2);
+ ID_ISAR2_EL1->name = "ID_ISAR2_EL1";
+ arm64_sysreg_add_field(ID_ISAR2_EL1, "Reversal", 28, 31);
+ arm64_sysreg_add_field(ID_ISAR2_EL1, "PSR_AR", 24, 27);
+ arm64_sysreg_add_field(ID_ISAR2_EL1, "MultU", 20, 23);
+ arm64_sysreg_add_field(ID_ISAR2_EL1, "MultS", 16, 19);
+ arm64_sysreg_add_field(ID_ISAR2_EL1, "Mult", 12, 15);
+ arm64_sysreg_add_field(ID_ISAR2_EL1, "MultiAccessInt", 8, 11);
+ arm64_sysreg_add_field(ID_ISAR2_EL1, "MemHint", 4, 7);
+ arm64_sysreg_add_field(ID_ISAR2_EL1, "LoadStore", 0, 3);
+
+ /* ID_ISAR3_EL1 */
+ ARM64SysReg *ID_ISAR3_EL1 = arm64_sysreg_get(3, 0, 0, 2, 3);
+ ID_ISAR3_EL1->name = "ID_ISAR3_EL1";
+ arm64_sysreg_add_field(ID_ISAR3_EL1, "T32EE", 28, 31);
+ arm64_sysreg_add_field(ID_ISAR3_EL1, "TrueNOP", 24, 27);
+ arm64_sysreg_add_field(ID_ISAR3_EL1, "T32Copy", 20, 23);
+ arm64_sysreg_add_field(ID_ISAR3_EL1, "TabBranch", 16, 19);
+ arm64_sysreg_add_field(ID_ISAR3_EL1, "SynchPrim", 12, 15);
+ arm64_sysreg_add_field(ID_ISAR3_EL1, "SVC", 8, 11);
+ arm64_sysreg_add_field(ID_ISAR3_EL1, "SIMD", 4, 7);
+ arm64_sysreg_add_field(ID_ISAR3_EL1, "Saturate", 0, 3);
+
+ /* ID_ISAR4_EL1 */
+ ARM64SysReg *ID_ISAR4_EL1 = arm64_sysreg_get(3, 0, 0, 2, 4);
+ ID_ISAR4_EL1->name = "ID_ISAR4_EL1";
+ arm64_sysreg_add_field(ID_ISAR4_EL1, "SWP_frac", 28, 31);
+ arm64_sysreg_add_field(ID_ISAR4_EL1, "PSR_M", 24, 27);
+ arm64_sysreg_add_field(ID_ISAR4_EL1, "SynchPrim_frac", 20, 23);
+ arm64_sysreg_add_field(ID_ISAR4_EL1, "Barrier", 16, 19);
+ arm64_sysreg_add_field(ID_ISAR4_EL1, "SMC", 12, 15);
+ arm64_sysreg_add_field(ID_ISAR4_EL1, "Writeback", 8, 11);
+ arm64_sysreg_add_field(ID_ISAR4_EL1, "WithShifts", 4, 7);
+ arm64_sysreg_add_field(ID_ISAR4_EL1, "Unpriv", 0, 3);
+
+ /* ID_ISAR5_EL1 */
+ ARM64SysReg *ID_ISAR5_EL1 = arm64_sysreg_get(3, 0, 0, 2, 5);
+ ID_ISAR5_EL1->name = "ID_ISAR5_EL1";
+ arm64_sysreg_add_field(ID_ISAR5_EL1, "VCMA", 28, 31);
+ arm64_sysreg_add_field(ID_ISAR5_EL1, "RDM", 24, 27);
+ arm64_sysreg_add_field(ID_ISAR5_EL1, "CRC32", 16, 19);
+ arm64_sysreg_add_field(ID_ISAR5_EL1, "SHA2", 12, 15);
+ arm64_sysreg_add_field(ID_ISAR5_EL1, "SHA1", 8, 11);
+ arm64_sysreg_add_field(ID_ISAR5_EL1, "AES", 4, 7);
+ arm64_sysreg_add_field(ID_ISAR5_EL1, "SEVL", 0, 3);
+
+ /* ID_ISAR6_EL1 */
+ ARM64SysReg *ID_ISAR6_EL1 = arm64_sysreg_get(3, 0, 0, 2, 7);
+ ID_ISAR6_EL1->name = "ID_ISAR6_EL1";
+ arm64_sysreg_add_field(ID_ISAR6_EL1, "I8MM", 24, 27);
+ arm64_sysreg_add_field(ID_ISAR6_EL1, "BF16", 20, 23);
+ arm64_sysreg_add_field(ID_ISAR6_EL1, "SPECRES", 16, 19);
+ arm64_sysreg_add_field(ID_ISAR6_EL1, "SB", 12, 15);
+ arm64_sysreg_add_field(ID_ISAR6_EL1, "FHM", 8, 11);
+ arm64_sysreg_add_field(ID_ISAR6_EL1, "DP", 4, 7);
+ arm64_sysreg_add_field(ID_ISAR6_EL1, "JSCVT", 0, 3);
+
+ /* ID_MMFR4_EL1 */
+ ARM64SysReg *ID_MMFR4_EL1 = arm64_sysreg_get(3, 0, 0, 2, 6);
+ ID_MMFR4_EL1->name = "ID_MMFR4_EL1";
+ arm64_sysreg_add_field(ID_MMFR4_EL1, "EVT", 28, 31);
+ arm64_sysreg_add_field(ID_MMFR4_EL1, "CCIDX", 24, 27);
+ arm64_sysreg_add_field(ID_MMFR4_EL1, "LSM", 20, 23);
+ arm64_sysreg_add_field(ID_MMFR4_EL1, "HPDS", 16, 19);
+ arm64_sysreg_add_field(ID_MMFR4_EL1, "CnP", 12, 15);
+ arm64_sysreg_add_field(ID_MMFR4_EL1, "XNX", 8, 11);
+ arm64_sysreg_add_field(ID_MMFR4_EL1, "AC2", 4, 7);
+ arm64_sysreg_add_field(ID_MMFR4_EL1, "SpecSEI", 0, 3);
+
+ /* MVFR0_EL1 */
+ ARM64SysReg *MVFR0_EL1 = arm64_sysreg_get(3, 0, 0, 3, 0);
+ MVFR0_EL1->name = "MVFR0_EL1";
+ arm64_sysreg_add_field(MVFR0_EL1, "FPRound", 28, 31);
+ arm64_sysreg_add_field(MVFR0_EL1, "FPShVec", 24, 27);
+ arm64_sysreg_add_field(MVFR0_EL1, "FPSqrt", 20, 23);
+ arm64_sysreg_add_field(MVFR0_EL1, "FPDivide", 16, 19);
+ arm64_sysreg_add_field(MVFR0_EL1, "FPTrap", 12, 15);
+ arm64_sysreg_add_field(MVFR0_EL1, "FPDP", 8, 11);
+ arm64_sysreg_add_field(MVFR0_EL1, "FPSP", 4, 7);
+ arm64_sysreg_add_field(MVFR0_EL1, "SIMDReg", 0, 3);
+
+ /* MVFR1_EL1 */
+ ARM64SysReg *MVFR1_EL1 = arm64_sysreg_get(3, 0, 0, 3, 1);
+ MVFR1_EL1->name = "MVFR1_EL1";
+ arm64_sysreg_add_field(MVFR1_EL1, "SIMDFMAC", 28, 31);
+ arm64_sysreg_add_field(MVFR1_EL1, "FPHP", 24, 27);
+ arm64_sysreg_add_field(MVFR1_EL1, "SIMDHP", 20, 23);
+ arm64_sysreg_add_field(MVFR1_EL1, "SIMDSP", 16, 19);
+ arm64_sysreg_add_field(MVFR1_EL1, "SIMDInt", 12, 15);
+ arm64_sysreg_add_field(MVFR1_EL1, "SIMDLS", 8, 11);
+ arm64_sysreg_add_field(MVFR1_EL1, "FPDNaN", 4, 7);
+ arm64_sysreg_add_field(MVFR1_EL1, "FPFtZ", 0, 3);
+
+ /* MVFR2_EL1 */
+ ARM64SysReg *MVFR2_EL1 = arm64_sysreg_get(3, 0, 0, 3, 2);
+ MVFR2_EL1->name = "MVFR2_EL1";
+ arm64_sysreg_add_field(MVFR2_EL1, "FPMisc", 4, 7);
+ arm64_sysreg_add_field(MVFR2_EL1, "SIMDMisc", 0, 3);
+
+ /* ID_PFR2_EL1 */
+ ARM64SysReg *ID_PFR2_EL1 = arm64_sysreg_get(3, 0, 0, 3, 4);
+ ID_PFR2_EL1->name = "ID_PFR2_EL1";
+ arm64_sysreg_add_field(ID_PFR2_EL1, "RAS_frac", 8, 11);
+ arm64_sysreg_add_field(ID_PFR2_EL1, "SSBS", 4, 7);
+ arm64_sysreg_add_field(ID_PFR2_EL1, "CSV3", 0, 3);
+
+ /* ID_DFR1_EL1 */
+ ARM64SysReg *ID_DFR1_EL1 = arm64_sysreg_get(3, 0, 0, 3, 5);
+ ID_DFR1_EL1->name = "ID_DFR1_EL1";
+ arm64_sysreg_add_field(ID_DFR1_EL1, "HPMN0", 4, 7);
+ arm64_sysreg_add_field(ID_DFR1_EL1, "MTPMU", 0, 3);
+
+ /* ID_MMFR5_EL1 */
+ ARM64SysReg *ID_MMFR5_EL1 = arm64_sysreg_get(3, 0, 0, 3, 6);
+ ID_MMFR5_EL1->name = "ID_MMFR5_EL1";
+ arm64_sysreg_add_field(ID_MMFR5_EL1, "nTLBPA", 4, 7);
+ arm64_sysreg_add_field(ID_MMFR5_EL1, "ETS", 0, 3);
+
+ /* ID_AA64PFR0_EL1 */
+ ARM64SysReg *ID_AA64PFR0_EL1 = arm64_sysreg_get(3, 0, 0, 4, 0);
+ ID_AA64PFR0_EL1->name = "ID_AA64PFR0_EL1";
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "CSV3", 60, 63);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "CSV2", 56, 59);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "RME", 52, 55);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "DIT", 48, 51);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "AMU", 44, 47);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "MPAM", 40, 43);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "SEL2", 36, 39);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "SVE", 32, 35);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "RAS", 28, 31);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "GIC", 24, 27);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "AdvSIMD", 20, 23);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "AdvSIMD", 20, 23);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "FP", 16, 19);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "FP", 16, 19);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "EL3", 12, 15);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "EL2", 8, 11);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "EL1", 4, 7);
+ arm64_sysreg_add_field(ID_AA64PFR0_EL1, "EL0", 0, 3);
+
+ /* ID_AA64PFR1_EL1 */
+ ARM64SysReg *ID_AA64PFR1_EL1 = arm64_sysreg_get(3, 0, 0, 4, 1);
+ ID_AA64PFR1_EL1->name = "ID_AA64PFR1_EL1";
+ arm64_sysreg_add_field(ID_AA64PFR1_EL1, "PFAR", 60, 63);
+ arm64_sysreg_add_field(ID_AA64PFR1_EL1, "DF2", 56, 59);
+ arm64_sysreg_add_field(ID_AA64PFR1_EL1, "MTEX", 52, 55);
+ arm64_sysreg_add_field(ID_AA64PFR1_EL1, "THE", 48, 51);
+ arm64_sysreg_add_field(ID_AA64PFR1_EL1, "GCS", 44, 47);
+ arm64_sysreg_add_field(ID_AA64PFR1_EL1, "MTE_frac", 40, 43);
+ arm64_sysreg_add_field(ID_AA64PFR1_EL1, "NMI", 36, 39);
+ arm64_sysreg_add_field(ID_AA64PFR1_EL1, "CSV2_frac", 32, 35);
+ arm64_sysreg_add_field(ID_AA64PFR1_EL1, "RNDR_trap", 28, 31);
+ arm64_sysreg_add_field(ID_AA64PFR1_EL1, "SME", 24, 27);
+ arm64_sysreg_add_field(ID_AA64PFR1_EL1, "MPAM_frac", 16, 19);
+ arm64_sysreg_add_field(ID_AA64PFR1_EL1, "RAS_frac", 12, 15);
+ arm64_sysreg_add_field(ID_AA64PFR1_EL1, "MTE", 8, 11);
+ arm64_sysreg_add_field(ID_AA64PFR1_EL1, "SSBS", 4, 7);
+ arm64_sysreg_add_field(ID_AA64PFR1_EL1, "BT", 0, 3);
+
+ /* ID_AA64PFR2_EL1 */
+ ARM64SysReg *ID_AA64PFR2_EL1 = arm64_sysreg_get(3, 0, 0, 4, 2);
+ ID_AA64PFR2_EL1->name = "ID_AA64PFR2_EL1";
+ arm64_sysreg_add_field(ID_AA64PFR2_EL1, "FPMR", 32, 35);
+ arm64_sysreg_add_field(ID_AA64PFR2_EL1, "MTEFAR", 8, 11);
+ arm64_sysreg_add_field(ID_AA64PFR2_EL1, "MTESTOREONLY", 4, 7);
+ arm64_sysreg_add_field(ID_AA64PFR2_EL1, "MTEPERM", 0, 3);
+
+ /* ID_AA64ZFR0_EL1 */
+ ARM64SysReg *ID_AA64ZFR0_EL1 = arm64_sysreg_get(3, 0, 0, 4, 4);
+ ID_AA64ZFR0_EL1->name = "ID_AA64ZFR0_EL1";
+ arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "F64MM", 56, 59);
+ arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "F32MM", 52, 55);
+ arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "I8MM", 44, 47);
+ arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "SM4", 40, 43);
+ arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "SHA3", 32, 35);
+ arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "B16B16", 24, 27);
+ arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "BF16", 20, 23);
+ arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "BitPerm", 16, 19);
+ arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "AES", 4, 7);
+ arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "SVEver", 0, 3);
+
+ /* ID_AA64SMFR0_EL1 */
+ ARM64SysReg *ID_AA64SMFR0_EL1 = arm64_sysreg_get(3, 0, 0, 4, 5);
+ ID_AA64SMFR0_EL1->name = "ID_AA64SMFR0_EL1";
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "FA64", 63, 63);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "LUTv2", 60, 60);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SMEver", 56, 59);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "I16I64", 52, 55);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F64F64", 48, 48);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "I16I32", 44, 47);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "B16B16", 43, 43);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F16F16", 42, 42);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F8F16", 41, 41);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F8F32", 40, 40);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "I8I32", 36, 39);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F16F32", 35, 35);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "B16F32", 34, 34);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "BI32I32", 33, 33);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F32F32", 32, 32);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SF8FMA", 30, 30);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SF8DP4", 29, 29);
+ arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SF8DP2", 28, 28);
+
+ /* ID_AA64FPFR0_EL1 */
+ ARM64SysReg *ID_AA64FPFR0_EL1 = arm64_sysreg_get(3, 0, 0, 4, 7);
+ ID_AA64FPFR0_EL1->name = "ID_AA64FPFR0_EL1";
+ arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8CVT", 31, 31);
+ arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8FMA", 30, 30);
+ arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8DP4", 29, 29);
+ arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8DP2", 28, 28);
+ arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8E4M3", 1, 1);
+ arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8E5M2", 0, 0);
+
+ /* ID_AA64DFR0_EL1 */
+ ARM64SysReg *ID_AA64DFR0_EL1 = arm64_sysreg_get(3, 0, 0, 5, 0);
+ ID_AA64DFR0_EL1->name = "ID_AA64DFR0_EL1";
+ arm64_sysreg_add_field(ID_AA64DFR0_EL1, "HPMN0", 60, 63);
+ arm64_sysreg_add_field(ID_AA64DFR0_EL1, "ExtTrcBuff", 56, 59);
+ arm64_sysreg_add_field(ID_AA64DFR0_EL1, "BRBE", 52, 55);
+ arm64_sysreg_add_field(ID_AA64DFR0_EL1, "MTPMU", 48, 51);
+ arm64_sysreg_add_field(ID_AA64DFR0_EL1, "TraceBuffer", 44, 47);
+ arm64_sysreg_add_field(ID_AA64DFR0_EL1, "TraceFilt", 40, 43);
+ arm64_sysreg_add_field(ID_AA64DFR0_EL1, "DoubleLock", 36, 39);
+ arm64_sysreg_add_field(ID_AA64DFR0_EL1, "PMSVer", 32, 35);
+ arm64_sysreg_add_field(ID_AA64DFR0_EL1, "CTX_CMPs", 28, 31);
+ arm64_sysreg_add_field(ID_AA64DFR0_EL1, "WRPs", 20, 23);
+ arm64_sysreg_add_field(ID_AA64DFR0_EL1, "BRPs", 12, 15);
+ arm64_sysreg_add_field(ID_AA64DFR0_EL1, "PMUVer", 8, 11);
+ arm64_sysreg_add_field(ID_AA64DFR0_EL1, "TraceVer", 4, 7);
+ arm64_sysreg_add_field(ID_AA64DFR0_EL1, "DebugVer", 0, 3);
+
+ /* ID_AA64DFR1_EL1 */
+ ARM64SysReg *ID_AA64DFR1_EL1 = arm64_sysreg_get(3, 0, 0, 5, 1);
+ ID_AA64DFR1_EL1->name = "ID_AA64DFR1_EL1";
+ arm64_sysreg_add_field(ID_AA64DFR1_EL1, "ABL_CMPs", 56, 63);
+ arm64_sysreg_add_field(ID_AA64DFR1_EL1, "DPFZS", 52, 55);
+ arm64_sysreg_add_field(ID_AA64DFR1_EL1, "EBEP", 48, 51);
+ arm64_sysreg_add_field(ID_AA64DFR1_EL1, "ITE", 44, 47);
+ arm64_sysreg_add_field(ID_AA64DFR1_EL1, "ABLE", 40, 43);
+ arm64_sysreg_add_field(ID_AA64DFR1_EL1, "PMICNTR", 36, 39);
+ arm64_sysreg_add_field(ID_AA64DFR1_EL1, "SPMU", 32, 35);
+ arm64_sysreg_add_field(ID_AA64DFR1_EL1, "CTX_CMPs", 24, 31);
+ arm64_sysreg_add_field(ID_AA64DFR1_EL1, "WRPs", 16, 23);
+ arm64_sysreg_add_field(ID_AA64DFR1_EL1, "BRPs", 8, 15);
+ arm64_sysreg_add_field(ID_AA64DFR1_EL1, "SYSPMUID", 0, 7);
+
+ /* ID_AA64AFR0_EL1 */
+ ARM64SysReg *ID_AA64AFR0_EL1 = arm64_sysreg_get(3, 0, 0, 5, 4);
+ ID_AA64AFR0_EL1->name = "ID_AA64AFR0_EL1";
+ arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF7", 28, 31);
+ arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF6", 24, 27);
+ arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF5", 20, 23);
+ arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF4", 16, 19);
+ arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF3", 12, 15);
+ arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF2", 8, 11);
+ arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF1", 4, 7);
+ arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF0", 0, 3);
+
+ /* ID_AA64AFR1_EL1 */
+ ARM64SysReg *ID_AA64AFR1_EL1 = arm64_sysreg_get(3, 0, 0, 5, 5);
+ ID_AA64AFR1_EL1->name = "ID_AA64AFR1_EL1";
+
+ /* ID_AA64ISAR0_EL1 */
+ ARM64SysReg *ID_AA64ISAR0_EL1 = arm64_sysreg_get(3, 0, 0, 6, 0);
+ ID_AA64ISAR0_EL1->name = "ID_AA64ISAR0_EL1";
+ arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "RNDR", 60, 63);
+ arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "TLB", 56, 59);
+ arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "TS", 52, 55);
+ arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "FHM", 48, 51);
+ arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "DP", 44, 47);
+ arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "SM4", 40, 43);
+ arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "SM3", 36, 39);
+ arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "SHA3", 32, 35);
+ arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "RDM", 28, 31);
+ arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "TME", 24, 27);
+ arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "ATOMIC", 20, 23);
+ arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "CRC32", 16, 19);
+ arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "SHA2", 12, 15);
+ arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "SHA1", 8, 11);
+ arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "AES", 4, 7);
+
+ /* ID_AA64ISAR1_EL1 */
+ ARM64SysReg *ID_AA64ISAR1_EL1 = arm64_sysreg_get(3, 0, 0, 6, 1);
+ ID_AA64ISAR1_EL1->name = "ID_AA64ISAR1_EL1";
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "LS64", 60, 63);
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "XS", 56, 59);
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "I8MM", 52, 55);
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "DGH", 48, 51);
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "BF16", 44, 47);
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "SPECRES", 40, 43);
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "SB", 36, 39);
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "FRINTTS", 32, 35);
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "GPI", 28, 31);
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "GPA", 24, 27);
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "LRCPC", 20, 23);
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "FCMA", 16, 19);
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "JSCVT", 12, 15);
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "API", 8, 11);
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "APA", 4, 7);
+ arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "DPB", 0, 3);
+
+ /* ID_AA64ISAR2_EL1 */
+ ARM64SysReg *ID_AA64ISAR2_EL1 = arm64_sysreg_get(3, 0, 0, 6, 2);
+ ID_AA64ISAR2_EL1->name = "ID_AA64ISAR2_EL1";
+ arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "ATS1A", 60, 63);
+ arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "LUT", 56, 59);
+ arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "CSSC", 52, 55);
+ arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "RPRFM", 48, 51);
+ arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "PRFMSLC", 40, 43);
+ arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "SYSINSTR_128", 36, 39);
+ arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "SYSREG_128", 32, 35);
+ arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "CLRBHB", 28, 31);
+ arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "PAC_frac", 24, 27);
+ arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "BC", 20, 23);
+ arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "MOPS", 16, 19);
+ arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "APA3", 12, 15);
+ arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "GPA3", 8, 11);
+ arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "RPRES", 4, 7);
+ arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "WFxT", 0, 3);
+
+ /* ID_AA64ISAR3_EL1 */
+ ARM64SysReg *ID_AA64ISAR3_EL1 = arm64_sysreg_get(3, 0, 0, 6, 3);
+ ID_AA64ISAR3_EL1->name = "ID_AA64ISAR3_EL1";
+ arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "PACM", 12, 15);
+ arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "TLBIW", 8, 11);
+ arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "FAMINMAX", 4, 7);
+ arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "CPA", 0, 3);
+
+ /* ID_AA64MMFR0_EL1 */
+ ARM64SysReg *ID_AA64MMFR0_EL1 = arm64_sysreg_get(3, 0, 0, 7, 0);
+ ID_AA64MMFR0_EL1->name = "ID_AA64MMFR0_EL1";
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "ECV", 60, 63);
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "FGT", 56, 59);
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "EXS", 44, 47);
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN4_2", 40, 43);
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN64_2", 36, 39);
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN16_2", 32, 35);
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN4", 28, 31);
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN4", 28, 31);
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN64", 24, 27);
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN64", 24, 27);
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN16", 20, 23);
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "BIGENDEL0", 16, 19);
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "SNSMEM", 12, 15);
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "BIGEND", 8, 11);
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "ASIDBITS", 4, 7);
+ arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "PARANGE", 0, 3);
+
+ /* ID_AA64MMFR1_EL1 */
+ ARM64SysReg *ID_AA64MMFR1_EL1 = arm64_sysreg_get(3, 0, 0, 7, 1);
+ ID_AA64MMFR1_EL1->name = "ID_AA64MMFR1_EL1";
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "ECBHB", 60, 63);
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "CMOW", 56, 59);
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "TIDCP1", 52, 55);
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "nTLBPA", 48, 51);
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "AFP", 44, 47);
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "HCX", 40, 43);
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "ETS", 36, 39);
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "TWED", 32, 35);
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "XNX", 28, 31);
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "SpecSEI", 24, 27);
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "PAN", 20, 23);
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "LO", 16, 19);
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "HPDS", 12, 15);
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "VH", 8, 11);
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "VMIDBits", 4, 7);
+ arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "HAFDBS", 0, 3);
+
+ /* ID_AA64MMFR2_EL1 */
+ ARM64SysReg *ID_AA64MMFR2_EL1 = arm64_sysreg_get(3, 0, 0, 7, 2);
+ ID_AA64MMFR2_EL1->name = "ID_AA64MMFR2_EL1";
+ arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "E0PD", 60, 63);
+ arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "EVT", 56, 59);
+ arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "BBM", 52, 55);
+ arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "TTL", 48, 51);
+ arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "FWB", 40, 43);
+ arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "IDS", 36, 39);
+ arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "AT", 32, 35);
+ arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "ST", 28, 31);
+ arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "NV", 24, 27);
+ arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "CCIDX", 20, 23);
+ arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "VARange", 16, 19);
+ arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "IESB", 12, 15);
+ arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "LSM", 8, 11);
+ arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "UAO", 4, 7);
+ arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "CnP", 0, 3);
+
+ /* ID_AA64MMFR3_EL1 */
+ ARM64SysReg *ID_AA64MMFR3_EL1 = arm64_sysreg_get(3, 0, 0, 7, 3);
+ ID_AA64MMFR3_EL1->name = "ID_AA64MMFR3_EL1";
+ arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "Spec_FPACC", 60, 63);
+ arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "ADERR", 56, 59);
+ arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "SDERR", 52, 55);
+ arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "ANERR", 44, 47);
+ arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "SNERR", 40, 43);
+ arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "D128_2", 36, 39);
+ arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "D128", 32, 35);
+ arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "MEC", 28, 31);
+ arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "AIE", 24, 27);
+ arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "S2POE", 20, 23);
+ arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "S1POE", 16, 19);
+ arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "S2PIE", 12, 15);
+ arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "S1PIE", 8, 11);
+ arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "SCTLRX", 4, 7);
+ arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "TCRX", 0, 3);
+
+ /* ID_AA64MMFR4_EL1 */
+ ARM64SysReg *ID_AA64MMFR4_EL1 = arm64_sysreg_get(3, 0, 0, 7, 4);
+ ID_AA64MMFR4_EL1->name = "ID_AA64MMFR4_EL1";
+ arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "E3DSE", 36, 39);
+ arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "E2H0", 24, 27);
+ arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "E2H0", 24, 27);
+ arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "NV_frac", 20, 23);
+ arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "FGWTE3", 16, 19);
+ arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "HACDBS", 12, 15);
+ arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "ASID2", 8, 11);
+ arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "EIESB", 4, 7);
+ arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "EIESB", 4, 7);
+
+/* For CPACR_EL1 fields see CPACR_ELx */
+
+/* For ZCR_EL1 fields see ZCR_ELx */
+
+/* For SMCR_EL1 fields see SMCR_ELx */
+
+/* For GCSCR_EL1 fields see GCSCR_ELx */
+
+/* For GCSPR_EL1 fields see GCSPR_ELx */
+
+/* For CONTEXTIDR_EL1 fields see CONTEXTIDR_ELx */
+
+ /* CCSIDR_EL1 */
+ ARM64SysReg *CCSIDR_EL1 = arm64_sysreg_get(3, 1, 0, 0, 0);
+ CCSIDR_EL1->name = "CCSIDR_EL1";
+ arm64_sysreg_add_field(CCSIDR_EL1, "NumSets", 13, 27);
+ arm64_sysreg_add_field(CCSIDR_EL1, "Associativity", 3, 12);
+ arm64_sysreg_add_field(CCSIDR_EL1, "LineSize", 0, 2);
+
+ /* CLIDR_EL1 */
+ ARM64SysReg *CLIDR_EL1 = arm64_sysreg_get(3, 1, 0, 0, 1);
+ CLIDR_EL1->name = "CLIDR_EL1";
+ arm64_sysreg_add_field(CLIDR_EL1, "Ttypen", 33, 46);
+ arm64_sysreg_add_field(CLIDR_EL1, "ICB", 30, 32);
+ arm64_sysreg_add_field(CLIDR_EL1, "LoUU", 27, 29);
+ arm64_sysreg_add_field(CLIDR_EL1, "LoC", 24, 26);
+ arm64_sysreg_add_field(CLIDR_EL1, "LoUIS", 21, 23);
+ arm64_sysreg_add_field(CLIDR_EL1, "Ctype7", 18, 20);
+ arm64_sysreg_add_field(CLIDR_EL1, "Ctype6", 15, 17);
+ arm64_sysreg_add_field(CLIDR_EL1, "Ctype5", 12, 14);
+ arm64_sysreg_add_field(CLIDR_EL1, "Ctype4", 9, 11);
+ arm64_sysreg_add_field(CLIDR_EL1, "Ctype3", 6, 8);
+ arm64_sysreg_add_field(CLIDR_EL1, "Ctype2", 3, 5);
+ arm64_sysreg_add_field(CLIDR_EL1, "Ctype1", 0, 2);
+
+ /* CCSIDR2_EL1 */
+ ARM64SysReg *CCSIDR2_EL1 = arm64_sysreg_get(3, 1, 0, 0, 2);
+ CCSIDR2_EL1->name = "CCSIDR2_EL1";
+ arm64_sysreg_add_field(CCSIDR2_EL1, "NumSets", 0, 23);
+
+ /* GMID_EL1 */
+ ARM64SysReg *GMID_EL1 = arm64_sysreg_get(3, 1, 0, 0, 4);
+ GMID_EL1->name = "GMID_EL1";
+ arm64_sysreg_add_field(GMID_EL1, "BS", 0, 3);
+
+ /* SMIDR_EL1 */
+ ARM64SysReg *SMIDR_EL1 = arm64_sysreg_get(3, 1, 0, 0, 6);
+ SMIDR_EL1->name = "SMIDR_EL1";
+ arm64_sysreg_add_field(SMIDR_EL1, "IMPLEMENTER", 24, 31);
+ arm64_sysreg_add_field(SMIDR_EL1, "REVISION", 16, 23);
+ arm64_sysreg_add_field(SMIDR_EL1, "SMPS", 15, 15);
+ arm64_sysreg_add_field(SMIDR_EL1, "AFFINITY", 0, 11);
+
+ /* CSSELR_EL1 */
+ ARM64SysReg *CSSELR_EL1 = arm64_sysreg_get(3, 2, 0, 0, 0);
+ CSSELR_EL1->name = "CSSELR_EL1";
+ arm64_sysreg_add_field(CSSELR_EL1, "TnD", 4, 4);
+ arm64_sysreg_add_field(CSSELR_EL1, "Level", 1, 3);
+ arm64_sysreg_add_field(CSSELR_EL1, "InD", 0, 0);
+
/* CTR_EL0 */
ARM64SysReg *CTR_EL0 = arm64_sysreg_get(3, 3, 0, 0, 1);
CTR_EL0->name = "CTR_EL0";
- arm64_sysreg_add_field(CTR_EL0, "TMinline", 32, 37);
+ arm64_sysreg_add_field(CTR_EL0, "TminLine", 32, 37);
arm64_sysreg_add_field(CTR_EL0, "DIC", 29, 29);
arm64_sysreg_add_field(CTR_EL0, "IDC", 28, 28);
arm64_sysreg_add_field(CTR_EL0, "CWG", 24, 27);
arm64_sysreg_add_field(CTR_EL0, "ERG", 20, 23);
- arm64_sysreg_add_field(CTR_EL0, "DMinLine", 16, 19);
+ arm64_sysreg_add_field(CTR_EL0, "DminLine", 16, 19);
arm64_sysreg_add_field(CTR_EL0, "L1Ip", 14, 15);
arm64_sysreg_add_field(CTR_EL0, "IminLine", 0, 3);
-}
+ /* DCZID_EL0 */
+ ARM64SysReg *DCZID_EL0 = arm64_sysreg_get(3, 3, 0, 0, 7);
+ DCZID_EL0->name = "DCZID_EL0";
+ arm64_sysreg_add_field(DCZID_EL0, "DZP", 4, 4);
+ arm64_sysreg_add_field(DCZID_EL0, "BS", 0, 3);
+
+/* For GCSPR_EL0 fields see GCSPR_ELx */
+
+/* For HFGRTR_EL2 fields see HFGxTR_EL2 */
+
+/* For HFGWTR_EL2 fields see HFGxTR_EL2 */
+
+/* For ZCR_EL2 fields see ZCR_ELx */
+
+/* For SMCR_EL2 fields see SMCR_ELx */
+
+/* For GCSCR_EL2 fields see GCSCR_ELx */
+
+/* For GCSPR_EL2 fields see GCSPR_ELx */
+
+/* For CONTEXTIDR_EL2 fields see CONTEXTIDR_ELx */
+
+/* For CPACR_EL12 fields see CPACR_ELx */
+
+/* For ZCR_EL12 fields see ZCR_ELx */
+
+/* For SMCR_EL12 fields see SMCR_ELx */
+
+/* For GCSCR_EL12 fields see GCSCR_ELx */
+
+/* For GCSPR_EL12 fields see GCSPR_ELx */
+
+/* For CONTEXTIDR_EL12 fields see CONTEXTIDR_ELx */
+
+/* For TTBR0_EL1 fields see TTBRx_EL1 */
+
+/* For TTBR1_EL1 fields see TTBRx_EL1 */
+
+/* For TCR2_EL1 fields see TCR2_EL1x */
+
+/* For TCR2_EL12 fields see TCR2_EL1x */
+
+/* For MAIR2_EL1 fields see MAIR2_ELx */
+
+/* For MAIR2_EL2 fields see MAIR2_ELx */
+
+/* For PIRE0_EL1 fields see PIRx_ELx */
+
+/* For PIRE0_EL12 fields see PIRx_ELx */
+
+/* For PIR_EL1 fields see PIRx_ELx */
+
+/* For PIR_EL12 fields see PIRx_ELx */
+
+/* For PIR_EL2 fields see PIRx_ELx */
+
+/* For POR_EL0 fields see PIRx_ELx */
+
+/* For POR_EL1 fields see PIRx_ELx */
+
+/* For POR_EL12 fields see PIRx_ELx */
+
+/* For S2POR_EL1 fields see PIRx_ELx */
+
+/* For S2PIR_EL2 fields see PIRx_ELx */
+
+}
diff --git a/target/arm/cpu-sysregs.h b/target/arm/cpu-sysregs.h
index f4b63a3af77b..8c4cd0f2b414 100644
--- a/target/arm/cpu-sysregs.h
+++ b/target/arm/cpu-sysregs.h
@@ -1,24 +1,18 @@
#ifndef ARM_CPU_SYSREGS_H
#define ARM_CPU_SYSREGS_H
-/* to be generated */
-
-#define SYS_ID_AA64PFR0_EL1 sys_reg(3, 0, 0, 4, 0)
-#define SYS_ID_AA64PFR1_EL1 sys_reg(3, 0, 0, 4, 1)
-#define SYS_ID_AA64SMFR0_EL1 sys_reg(3, 0, 0, 4, 5)
-#define SYS_ID_AA64DFR0_EL1 sys_reg(3, 0, 0, 5, 0)
-#define SYS_ID_AA64DFR1_EL1 sys_reg(3, 0, 0, 5, 1)
-#define SYS_ID_AA64ISAR0_EL1 sys_reg(3, 0, 0, 6, 0)
-#define SYS_ID_AA64ISAR1_EL1 sys_reg(3, 0, 0, 6, 1)
-#define SYS_ID_AA64ISAR2_EL1 sys_reg(3, 0, 0, 6, 2)
-#define SYS_ID_AA64MMFR0_EL1 sys_reg(3, 0, 0, 7, 0)
-#define SYS_ID_AA64MMFR1_EL1 sys_reg(3, 0, 0, 7, 1)
-#define SYS_ID_AA64MMFR2_EL1 sys_reg(3, 0, 0, 7, 2)
-#define SYS_ID_AA64MMFR3_EL1 sys_reg(3, 0, 0, 7, 3)
+/* Generated file - do not edit */
+#define SYS_OSDTRRX_EL1 sys_reg(2, 0, 0, 0, 2)
+#define SYS_MDCCINT_EL1 sys_reg(2, 0, 0, 2, 0)
+#define SYS_MDSCR_EL1 sys_reg(2, 0, 0, 2, 2)
+#define SYS_OSDTRTX_EL1 sys_reg(2, 0, 0, 3, 2)
+#define SYS_OSECCR_EL1 sys_reg(2, 0, 0, 6, 2)
+#define SYS_OSLAR_EL1 sys_reg(2, 0, 1, 0, 4)
#define SYS_ID_PFR0_EL1 sys_reg(3, 0, 0, 1, 0)
#define SYS_ID_PFR1_EL1 sys_reg(3, 0, 0, 1, 1)
#define SYS_ID_DFR0_EL1 sys_reg(3, 0, 0, 1, 2)
+#define SYS_ID_AFR0_EL1 sys_reg(3, 0, 0, 1, 3)
#define SYS_ID_MMFR0_EL1 sys_reg(3, 0, 0, 1, 4)
#define SYS_ID_MMFR1_EL1 sys_reg(3, 0, 0, 1, 5)
#define SYS_ID_MMFR2_EL1 sys_reg(3, 0, 0, 1, 6)
@@ -29,14 +23,130 @@
#define SYS_ID_ISAR3_EL1 sys_reg(3, 0, 0, 2, 3)
#define SYS_ID_ISAR4_EL1 sys_reg(3, 0, 0, 2, 4)
#define SYS_ID_ISAR5_EL1 sys_reg(3, 0, 0, 2, 5)
-#define SYS_ID_MMFR4_EL1 sys_reg(3, 0, 0, 2, 6)
#define SYS_ID_ISAR6_EL1 sys_reg(3, 0, 0, 2, 7)
+#define SYS_ID_MMFR4_EL1 sys_reg(3, 0, 0, 2, 6)
#define SYS_MVFR0_EL1 sys_reg(3, 0, 0, 3, 0)
#define SYS_MVFR1_EL1 sys_reg(3, 0, 0, 3, 1)
#define SYS_MVFR2_EL1 sys_reg(3, 0, 0, 3, 2)
#define SYS_ID_PFR2_EL1 sys_reg(3, 0, 0, 3, 4)
#define SYS_ID_DFR1_EL1 sys_reg(3, 0, 0, 3, 5)
#define SYS_ID_MMFR5_EL1 sys_reg(3, 0, 0, 3, 6)
+#define SYS_ID_AA64PFR0_EL1 sys_reg(3, 0, 0, 4, 0)
+#define SYS_ID_AA64PFR1_EL1 sys_reg(3, 0, 0, 4, 1)
+#define SYS_ID_AA64PFR2_EL1 sys_reg(3, 0, 0, 4, 2)
#define SYS_ID_AA64ZFR0_EL1 sys_reg(3, 0, 0, 4, 4)
+#define SYS_ID_AA64SMFR0_EL1 sys_reg(3, 0, 0, 4, 5)
+#define SYS_ID_AA64FPFR0_EL1 sys_reg(3, 0, 0, 4, 7)
+#define SYS_ID_AA64DFR0_EL1 sys_reg(3, 0, 0, 5, 0)
+#define SYS_ID_AA64DFR1_EL1 sys_reg(3, 0, 0, 5, 1)
+#define SYS_ID_AA64AFR0_EL1 sys_reg(3, 0, 0, 5, 4)
+#define SYS_ID_AA64AFR1_EL1 sys_reg(3, 0, 0, 5, 5)
+#define SYS_ID_AA64ISAR0_EL1 sys_reg(3, 0, 0, 6, 0)
+#define SYS_ID_AA64ISAR1_EL1 sys_reg(3, 0, 0, 6, 1)
+#define SYS_ID_AA64ISAR2_EL1 sys_reg(3, 0, 0, 6, 2)
+#define SYS_ID_AA64ISAR3_EL1 sys_reg(3, 0, 0, 6, 3)
+#define SYS_ID_AA64MMFR0_EL1 sys_reg(3, 0, 0, 7, 0)
+#define SYS_ID_AA64MMFR1_EL1 sys_reg(3, 0, 0, 7, 1)
+#define SYS_ID_AA64MMFR2_EL1 sys_reg(3, 0, 0, 7, 2)
+#define SYS_ID_AA64MMFR3_EL1 sys_reg(3, 0, 0, 7, 3)
+#define SYS_ID_AA64MMFR4_EL1 sys_reg(3, 0, 0, 7, 4)
+#define SYS_SCTLR_EL1 sys_reg(3, 0, 1, 0, 0)
+#define SYS_CPACR_EL1 sys_reg(3, 0, 1, 0, 2)
+#define SYS_SMPRI_EL1 sys_reg(3, 0, 1, 2, 4)
+#define SYS_ZCR_EL1 sys_reg(3, 0, 1, 2, 0)
+#define SYS_SMCR_EL1 sys_reg(3, 0, 1, 2, 6)
+#define SYS_GCSCR_EL1 sys_reg(3, 0, 2, 5, 0)
+#define SYS_GCSPR_EL1 sys_reg(3, 0, 2, 5, 1)
+#define SYS_GCSCRE0_EL1 sys_reg(3, 0, 2, 5, 2)
+#define SYS_ALLINT sys_reg(3, 0, 4, 3, 0)
+#define SYS_FAR_EL1 sys_reg(3, 0, 6, 0, 0)
+#define SYS_PMICNTR_EL0 sys_reg(3, 3, 9, 4, 0)
+#define SYS_PMICFILTR_EL0 sys_reg(3, 3, 9, 6, 0)
+#define SYS_PMSCR_EL1 sys_reg(3, 0, 9, 9, 0)
+#define SYS_PMSNEVFR_EL1 sys_reg(3, 0, 9, 9, 1)
+#define SYS_PMSICR_EL1 sys_reg(3, 0, 9, 9, 2)
+#define SYS_PMSIRR_EL1 sys_reg(3, 0, 9, 9, 3)
+#define SYS_PMSFCR_EL1 sys_reg(3, 0, 9, 9, 4)
+#define SYS_PMSEVFR_EL1 sys_reg(3, 0, 9, 9, 5)
+#define SYS_PMSLATFR_EL1 sys_reg(3, 0, 9, 9, 6)
+#define SYS_PMSIDR_EL1 sys_reg(3, 0, 9, 9, 7)
+#define SYS_PMBLIMITR_EL1 sys_reg(3, 0, 9, 10, 0)
+#define SYS_PMBPTR_EL1 sys_reg(3, 0, 9, 10, 1)
+#define SYS_PMBSR_EL1 sys_reg(3, 0, 9, 10, 3)
+#define SYS_PMBIDR_EL1 sys_reg(3, 0, 9, 10, 7)
+#define SYS_PMSELR_EL0 sys_reg(3, 3, 9, 12, 5)
+#define SYS_CONTEXTIDR_EL1 sys_reg(3, 0, 13, 0, 1)
+#define SYS_RCWSMASK_EL1 sys_reg(3, 0, 13, 0, 3)
+#define SYS_TPIDR_EL1 sys_reg(3, 0, 13, 0, 4)
+#define SYS_RCWMASK_EL1 sys_reg(3, 0, 13, 0, 6)
+#define SYS_SCXTNUM_EL1 sys_reg(3, 0, 13, 0, 7)
+#define SYS_CCSIDR_EL1 sys_reg(3, 1, 0, 0, 0)
+#define SYS_CLIDR_EL1 sys_reg(3, 1, 0, 0, 1)
+#define SYS_CCSIDR2_EL1 sys_reg(3, 1, 0, 0, 2)
+#define SYS_GMID_EL1 sys_reg(3, 1, 0, 0, 4)
+#define SYS_SMIDR_EL1 sys_reg(3, 1, 0, 0, 6)
+#define SYS_CSSELR_EL1 sys_reg(3, 2, 0, 0, 0)
+#define SYS_CTR_EL0 sys_reg(3, 3, 0, 0, 1)
+#define SYS_DCZID_EL0 sys_reg(3, 3, 0, 0, 7)
+#define SYS_GCSPR_EL0 sys_reg(3, 3, 2, 5, 1)
+#define SYS_SVCR sys_reg(3, 3, 4, 2, 2)
+#define SYS_FPMR sys_reg(3, 3, 4, 4, 2)
+#define SYS_HFGRTR_EL2 sys_reg(3, 4, 1, 1, 4)
+#define SYS_HFGWTR_EL2 sys_reg(3, 4, 1, 1, 5)
+#define SYS_HFGITR_EL2 sys_reg(3, 4, 1, 1, 6)
+#define SYS_HDFGRTR_EL2 sys_reg(3, 4, 3, 1, 4)
+#define SYS_HDFGWTR_EL2 sys_reg(3, 4, 3, 1, 5)
+#define SYS_HAFGRTR_EL2 sys_reg(3, 4, 3, 1, 6)
+#define SYS_ZCR_EL2 sys_reg(3, 4, 1, 2, 0)
+#define SYS_HCRX_EL2 sys_reg(3, 4, 1, 2, 2)
+#define SYS_SMPRIMAP_EL2 sys_reg(3, 4, 1, 2, 5)
+#define SYS_SMCR_EL2 sys_reg(3, 4, 1, 2, 6)
+#define SYS_GCSCR_EL2 sys_reg(3, 4, 2, 5, 0)
+#define SYS_GCSPR_EL2 sys_reg(3, 4, 2, 5, 1)
+#define SYS_DACR32_EL2 sys_reg(3, 4, 3, 0, 0)
+#define SYS_FAR_EL2 sys_reg(3, 4, 6, 0, 0)
+#define SYS_PMSCR_EL2 sys_reg(3, 4, 9, 9, 0)
+#define SYS_CONTEXTIDR_EL2 sys_reg(3, 4, 13, 0, 1)
+#define SYS_CNTPOFF_EL2 sys_reg(3, 4, 14, 0, 6)
+#define SYS_CPACR_EL12 sys_reg(3, 5, 1, 0, 2)
+#define SYS_ZCR_EL12 sys_reg(3, 5, 1, 2, 0)
+#define SYS_SMCR_EL12 sys_reg(3, 5, 1, 2, 6)
+#define SYS_GCSCR_EL12 sys_reg(3, 5, 2, 5, 0)
+#define SYS_GCSPR_EL12 sys_reg(3, 5, 2, 5, 1)
+#define SYS_FAR_EL12 sys_reg(3, 5, 6, 0, 0)
+#define SYS_CONTEXTIDR_EL12 sys_reg(3, 5, 13, 0, 1)
+#define SYS_TTBR0_EL1 sys_reg(3, 0, 2, 0, 0)
+#define SYS_TTBR1_EL1 sys_reg(3, 0, 2, 0, 1)
+#define SYS_TCR2_EL1 sys_reg(3, 0, 2, 0, 3)
+#define SYS_TCR2_EL12 sys_reg(3, 5, 2, 0, 3)
+#define SYS_TCR2_EL2 sys_reg(3, 4, 2, 0, 3)
+#define SYS_MAIR2_EL1 sys_reg(3, 0, 10, 2, 1)
+#define SYS_MAIR2_EL2 sys_reg(3, 4, 10, 1, 1)
+#define SYS_AMAIR2_EL1 sys_reg(3, 0, 10, 3, 1)
+#define SYS_AMAIR2_EL2 sys_reg(3, 4, 10, 3, 1)
+#define SYS_PIRE0_EL1 sys_reg(3, 0, 10, 2, 2)
+#define SYS_PIRE0_EL12 sys_reg(3, 5, 10, 2, 2)
+#define SYS_PIR_EL1 sys_reg(3, 0, 10, 2, 3)
+#define SYS_PIR_EL12 sys_reg(3, 5, 10, 2, 3)
+#define SYS_PIR_EL2 sys_reg(3, 4, 10, 2, 3)
+#define SYS_POR_EL0 sys_reg(3, 3, 10, 2, 4)
+#define SYS_POR_EL1 sys_reg(3, 0, 10, 2, 4)
+#define SYS_POR_EL12 sys_reg(3, 5, 10, 2, 4)
+#define SYS_S2POR_EL1 sys_reg(3, 0, 10, 2, 5)
+#define SYS_S2PIR_EL2 sys_reg(3, 4, 10, 2, 5)
+#define SYS_LORSA_EL1 sys_reg(3, 0, 10, 4, 0)
+#define SYS_LOREA_EL1 sys_reg(3, 0, 10, 4, 1)
+#define SYS_LORN_EL1 sys_reg(3, 0, 10, 4, 2)
+#define SYS_LORC_EL1 sys_reg(3, 0, 10, 4, 3)
+#define SYS_LORID_EL1 sys_reg(3, 0, 10, 4, 7)
+#define SYS_ISR_EL1 sys_reg(3, 0, 12, 1, 0)
+#define SYS_ICC_NMIAR1_EL1 sys_reg(3, 0, 12, 9, 5)
+#define SYS_TRBLIMITR_EL1 sys_reg(3, 0, 9, 11, 0)
+#define SYS_TRBPTR_EL1 sys_reg(3, 0, 9, 11, 1)
+#define SYS_TRBBASER_EL1 sys_reg(3, 0, 9, 11, 2)
+#define SYS_TRBSR_EL1 sys_reg(3, 0, 9, 11, 3)
+#define SYS_TRBMAR_EL1 sys_reg(3, 0, 9, 11, 4)
+#define SYS_TRBTRG_EL1 sys_reg(3, 0, 9, 11, 6)
+#define SYS_TRBIDR_EL1 sys_reg(3, 0, 9, 11, 7)
-#endif
+#endif /* ARM_CPU_SYSREGS_H */
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 16/20] arm/kvm: Allow reading all the writable ID registers
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (14 preceding siblings ...)
2024-12-06 11:22 ` [PATCH RFCv2 15/20] arm/cpu: Add generated files Cornelia Huck
@ 2024-12-06 11:22 ` Cornelia Huck
2024-12-06 11:22 ` [PATCH RFCv2 17/20] arm/kvm: write back modified ID regs to KVM Cornelia Huck
` (7 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:22 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
At the moment kvm_arm_get_host_cpu_features() reads a subset of the
ID regs. As we want to introduce properties for all writable ID reg
fields, we want more genericity and read more default host register
values.
Introduce a new get_host_cpu_idregs() helper and add a new exhaustive
boolean parameter to kvm_arm_get_host_cpu_features() and
kvm_arm_set_cpu_features_from_host() to select the right behavior.
The host cpu model will keep the legacy behavior unless the writable
id register interface is available.
A writable_map IdRegMap is introduced in the CPU object. A subsequent
patch will populate it.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
target/arm/cpu.h | 3 +++
target/arm/cpu64.c | 4 ++--
target/arm/kvm.c | 53 ++++++++++++++++++++++++++++++++++++++---
target/arm/kvm_arm.h | 9 +++++--
target/arm/trace-events | 1 +
5 files changed, 63 insertions(+), 7 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index c803d191e84d..1ae482aac6a7 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1054,6 +1054,9 @@ struct ArchCPU {
*/
ARMIdRegsState writable_id_regs;
+ /* ID reg writable bitmask (KVM only) */
+ IdRegMap *writable_map;
+
/* QOM property to indicate we should use the back-compat CNTFRQ default */
bool backcompat_cntfrq;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 29558cda8186..e23df993e00e 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -717,14 +717,14 @@ static void aarch64_host_initfn(Object *obj)
{
#if defined(CONFIG_KVM)
ARMCPU *cpu = ARM_CPU(obj);
- kvm_arm_set_cpu_features_from_host(cpu);
+ kvm_arm_set_cpu_features_from_host(cpu, false);
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
aarch64_add_sve_properties(obj);
aarch64_add_pauth_properties(obj);
}
#elif defined(CONFIG_HVF)
ARMCPU *cpu = ARM_CPU(obj);
- hvf_arm_set_cpu_features_from_host(cpu);
+ hvf_arm_set_cpu_features_from_host(cpu, false);
aarch64_add_pauth_properties(obj);
#else
g_assert_not_reached();
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index f11d512388b8..4bb8094e846f 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -41,6 +41,7 @@
#include "hw/acpi/ghes.h"
#include "target/arm/gtimer.h"
#include "migration/blocker.h"
+#include "cpu-custom.h"
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_INFO(DEVICE_CTRL),
@@ -272,8 +273,49 @@ static int get_host_cpu_reg64(int fd, ARMHostCPUFeatures *ahcf, ARMSysReg sr)
return ret;
}
+/*
+ * 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 aslo readable!
+ */
+static int get_host_cpu_idregs(ARMCPU *cpu, int fd, ARMHostCPUFeatures *ahcf)
+{
+ int err = 0;
+ int i;
+
+ for (i = 0; i < NR_ID_REGS; i++) {
+ ARM64SysReg *sysregdesc = &arm64_id_regs[i];
+ ARMSysReg *sysreg = sysregdesc->sysreg;
+ uint64_t writable_mask = cpu->writable_map->regs[i];
+ uint64_t *reg;
+ int ret;
+
+ if (!sysreg || !writable_mask) {
+ continue;
+ }
+
+ reg = &ahcf->isar.idregs.regs[i];
+ ret = read_sys_reg64(fd, reg,
+ ARM64_SYS_REG(sysreg->op0, sysreg->op1,
+ sysreg->crn, sysreg->crm,
+ sysreg->op2));
+ trace_get_host_cpu_idregs(sysregdesc->name, *reg);
+ if (ret) {
+ error_report("%s error reading value of host %s register (%m)",
+ __func__, sysregdesc->name);
-static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
+ err = ret;
+ }
+ }
+ return err;
+}
+
+static bool
+kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf,
+ bool exhaustive)
{
/* Identify the feature bits corresponding to the host CPU, and
* fill out the ARMHostCPUClass fields accordingly. To do this
@@ -401,6 +443,11 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_DFR1_EL1);
err |= get_host_cpu_reg32(fd, ahcf, SYS_ID_MMFR5_EL1);
+ /* Make sure writable ID reg values are read */
+ if (exhaustive) {
+ err |= get_host_cpu_idregs(cpu, fd, ahcf);
+ }
+
/*
* DBGDIDR is a bit complicated because the kernel doesn't
* provide an accessor for it in 64-bit mode, which is what this
@@ -470,13 +517,13 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
return true;
}
-void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
+void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, bool exhaustive)
{
CPUARMState *env = &cpu->env;
if (!arm_host_cpu_features.dtb_compatible) {
if (!kvm_enabled() ||
- !kvm_arm_get_host_cpu_features(&arm_host_cpu_features)) {
+ !kvm_arm_get_host_cpu_features(cpu, &arm_host_cpu_features, exhaustive)) {
/* We can't report this error yet, so flag that we need to
* in arm_cpu_realizefn().
*/
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 426816ad3a74..035eedf82ff1 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -141,8 +141,12 @@ uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu);
*
* Set up the ARMCPU struct fields up to match the information probed
* from the host CPU.
+ *
+ * @cpu: cpu object
+ * @exhaustive: if true, all the feature ID regs are queried instead of
+ * a subset
*/
-void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
+void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, bool exhaustive);
/**
* kvm_arm_add_vcpu_properties:
@@ -257,7 +261,8 @@ static inline int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap)
/*
* These functions should never actually be called without KVM support.
*/
-static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
+static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu,
+ bool exhaustive)
{
g_assert_not_reached();
}
diff --git a/target/arm/trace-events b/target/arm/trace-events
index 4438dce7becc..0df3bfafffcc 100644
--- a/target/arm/trace-events
+++ b/target/arm/trace-events
@@ -13,3 +13,4 @@ arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
# kvm.c
kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
+get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu gost value for %s is 0x%"PRIx64
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 17/20] arm/kvm: write back modified ID regs to KVM
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (15 preceding siblings ...)
2024-12-06 11:22 ` [PATCH RFCv2 16/20] arm/kvm: Allow reading all the writable ID registers Cornelia Huck
@ 2024-12-06 11:22 ` Cornelia Huck
2024-12-06 11:22 ` [PATCH RFCv2 18/20] arm/cpu: more customization for the kvm host cpu model Cornelia Huck
` (6 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:22 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
We want to give a chance to override the value of host ID regs.
In a previous patch we made sure all their values could be fetched
through kvm_get_one_reg() calls before their modification. After
their potential modification we need to make sure we write back
the values through kvm_set_one_reg() calls.
Make sure the cpreg_list is modified with updated values and
transfer those values back to kvm.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
target/arm/kvm.c | 36 +++++++++++++++++++++++++++++++++++-
target/arm/trace-events | 1 +
2 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 4bb8094e846f..3b2f98041484 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -1061,6 +1061,31 @@ void kvm_arm_cpu_post_load(ARMCPU *cpu)
}
}
+static void kvm_arm_writable_idregs_to_cpreg_list(ARMCPU *cpu)
+{
+ for (int i = 0; i < NR_ID_REGS; i++) {
+ uint64_t writable_mask = cpu->writable_map->regs[i];
+ uint64_t *cpreg;
+
+ if (writable_mask) {
+ uint64_t regidx;
+ uint64_t previous, new;
+ ARM64SysReg *sysregdesc = &arm64_id_regs[i];
+ ARMSysReg *sr = sysregdesc->sysreg;
+
+ regidx = ARM64_SYS_REG(sr->op0, sr->op1, sr->crn, sr->crm, sr->op2);
+ cpreg = kvm_arm_get_cpreg_ptr(cpu, regidx);
+ previous = *cpreg;
+ new = cpu->isar.idregs.regs[i];
+ 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;
@@ -2028,7 +2053,16 @@ int kvm_arch_init_vcpu(CPUState *cs)
}
cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
- return kvm_arm_init_cpreg_list(cpu);
+ ret = kvm_arm_init_cpreg_list(cpu);
+ if (ret) {
+ return ret;
+ }
+ /* overwrite writable ID regs with their updated property values */
+ kvm_arm_writable_idregs_to_cpreg_list(cpu);
+
+ write_list_to_kvmstate(cpu, 3);
+
+ return 0;
}
int kvm_arch_destroy_vcpu(CPUState *cs)
diff --git a/target/arm/trace-events b/target/arm/trace-events
index 0df3bfafffcc..668acf94ab60 100644
--- a/target/arm/trace-events
+++ b/target/arm/trace-events
@@ -14,3 +14,4 @@ arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
# kvm.c
kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu gost value for %s is 0x%"PRIx64
+kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint64_t new) "%s overwrite default 0x%"PRIx64" with 0x%"PRIx64
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 18/20] arm/cpu: more customization for the kvm host cpu model
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (16 preceding siblings ...)
2024-12-06 11:22 ` [PATCH RFCv2 17/20] arm/kvm: write back modified ID regs to KVM Cornelia Huck
@ 2024-12-06 11:22 ` Cornelia Huck
2024-12-06 11:22 ` [PATCH RFCv2 19/20] arm-qmp-cmds: introspection for ID register props Cornelia Huck
` (5 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:22 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
From: Eric Auger <eric.auger@redhat.com>
If the interface for writable ID registers is available, expose uint64
SYSREG properties for writable ID reg fields exposed by the host
kernel. Properties are named SYSREG_<REG>_<FIELD> with REG and FIELD
being those used in linux arch/arm64/tools/sysreg. This done by
matching the writable fields retrieved from the host kernel against the
generated description of sysregs.
An example of invocation is:
-cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0
which sets DP field of ID_AA64ISAR0_EL1 to 0.
[CH: add properties to the host model instead of introducing a new
"custom" model]
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
Interaction with the existing cpu properties is still a bit unclear --
at the moment, the different configurations can overwrite each other.
---
target/arm/cpu.c | 12 ++++
target/arm/cpu64.c | 150 +++++++++++++++++++++++++++++++++++++++-
target/arm/trace-events | 6 ++
3 files changed, 167 insertions(+), 1 deletion(-)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index fee822eaf416..c20550cccbd2 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1999,6 +1999,18 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
return;
}
+ /*
+ * If we failed to retrieve the set of writable ID registers for the "host"
+ * CPU model, report it here. No error if the interface for discovering
+ * writable ID registers is not available.
+ * In case we did get the set of writable ID registers, set the features to
+ * the configured values here and perform some sanity checks.
+ */
+ if (cpu->writable_id_regs == WRITABLE_ID_REGS_FAILED) {
+ error_setg(errp, "Failed to discover writable id registers");
+ return;
+ }
+
if (!cpu->gt_cntfrq_hz) {
/*
* 0 means "the board didn't set a value, use the default". (We also
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index e23df993e00e..7c75779d1eb1 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -20,6 +20,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
+#include "qemu/error-report.h"
#include "cpu.h"
#include "cpregs.h"
#include "qemu/module.h"
@@ -36,6 +37,7 @@
#include "cpu-features.h"
#include "cpregs.h"
#include "cpu-custom.h"
+#include "trace.h"
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
{
@@ -713,15 +715,161 @@ static void aarch64_a53_initfn(Object *obj)
define_cortex_a72_a57_a53_cp_reginfo(cpu);
}
+#ifdef CONFIG_KVM
+
+static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
+{
+ GList *l;
+
+ for (l = reg->fields; l; l = l->next) {
+ ARM64SysRegField *field = (ARM64SysRegField *)l->data;
+
+ if (i >= field->lower && i <= field->upper) {
+ return field;
+ }
+ }
+ return NULL;
+}
+
+static void set_sysreg_prop(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ ARM64SysRegField *field = (ARM64SysRegField *)opaque;
+ ARMCPU *cpu = ARM_CPU(obj);
+ IdRegMap *idregs = &cpu->isar.idregs;
+ uint64_t old, value, mask;
+ int lower = field->lower;
+ int upper = field->upper;
+ int length = upper - lower + 1;
+ int index = field->index;
+
+ if (!visit_type_uint64(v, name, &value, errp)) {
+ return;
+ }
+
+ if (length < 64 && value > ((1 << length) - 1)) {
+ error_setg(errp,
+ "idreg %s set value (0x%lx) exceeds length of field (%d)!",
+ name, value, length);
+ return;
+ }
+
+ mask = MAKE_64BIT_MASK(lower, length);
+ value = value << lower;
+ old = idregs->regs[index];
+ idregs->regs[index] = old & ~mask;
+ idregs->regs[index] |= value;
+ trace_set_sysreg_prop(name, old, mask, value, idregs->regs[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);
+ IdRegMap *idregs = &cpu->isar.idregs;
+ int index = field->index;
+
+ error_report("%s %s", __func__, name);
+ visit_type_uint64(v, name, &idregs->regs[index], errp);
+ trace_get_sysreg_prop(name, idregs->regs[index]);
+}
+
+/*
+ * decode_idreg_writemap: Generate props for writable fields
+ *
+ * @obj: CPU object
+ * @index: index of the sysreg
+ * @map: writable map for the sysreg
+ * @reg: description of the sysreg
+ */
+static int
+decode_idreg_writemap(Object *obj, int index, uint64_t map, ARM64SysReg *reg)
+{
+ int i = ctz64(map);
+ int nb_sysreg_props = 0;
+
+ while (map) {
+ ARM64SysRegField *field = get_field(i, reg);
+ int lower, upper;
+ uint64_t mask;
+ char *prop_name;
+
+ if (!field) {
+ /* the field cannot be matched to any know id named field */
+ warn_report("%s bit %d of %s is writable but cannot be matched",
+ __func__, i, reg->name);
+ warn_report("%s is cpu-sysreg-properties.c up to date?", __func__);
+ map = map & ~BIT_ULL(i);
+ i = ctz64(map);
+ continue;
+ }
+ lower = field->lower;
+ upper = field->upper;
+ prop_name = g_strdup_printf("SYSREG_%s_%s", reg->name, field->name);
+ trace_decode_idreg_writemap(field->name, lower, upper, prop_name);
+ object_property_add(obj, prop_name, "uint64",
+ get_sysreg_prop, set_sysreg_prop, NULL, field);
+ nb_sysreg_props++;
+
+ mask = MAKE_64BIT_MASK(lower, upper - lower + 1);
+ map = map & ~mask;
+ i = ctz64(map);
+ }
+ trace_nb_sysreg_props(reg->name, nb_sysreg_props);
+ return 0;
+}
+
+/* analyze the writable mask and generate properties for writable fields */
+static int expose_idreg_properties(Object *obj, IdRegMap *map,
+ ARM64SysReg *regs)
+{
+ int i;
+
+ for (i = 0; i < NR_ID_REGS; i++) {
+ uint64_t mask = map->regs[i];
+
+ if (mask) {
+ /* reg @i has some writable fields, decode them */
+ decode_idreg_writemap(obj, i, mask, ®s[i]);
+ }
+ }
+ return 0;
+}
+
+#endif
+
static void aarch64_host_initfn(Object *obj)
{
#if defined(CONFIG_KVM)
ARMCPU *cpu = ARM_CPU(obj);
- kvm_arm_set_cpu_features_from_host(cpu, false);
+ bool expose_id_regs = true;
+ int ret;
+
+ cpu->writable_map = g_malloc(sizeof(IdRegMap));
+
+ /* discover via KVM_ARM_GET_REG_WRITABLE_MASKS */
+ ret = kvm_arm_get_writable_id_regs(cpu, cpu->writable_map);
+ if (ret == -ENOSYS) {
+ /* legacy: continue without writable id regs */
+ expose_id_regs = false;
+ } else if (ret) {
+ /* function will have marked an error */
+ return;
+ }
+
+ kvm_arm_set_cpu_features_from_host(cpu, expose_id_regs);
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
aarch64_add_sve_properties(obj);
aarch64_add_pauth_properties(obj);
}
+ if (expose_id_regs) {
+ /* generate SYSREG properties according to writable masks */
+ expose_idreg_properties(obj, cpu->writable_map, arm64_id_regs);
+ }
+
#elif defined(CONFIG_HVF)
ARMCPU *cpu = ARM_CPU(obj);
hvf_arm_set_cpu_features_from_host(cpu, false);
diff --git a/target/arm/trace-events b/target/arm/trace-events
index 668acf94ab60..1b4bd5ab1498 100644
--- a/target/arm/trace-events
+++ b/target/arm/trace-events
@@ -15,3 +15,9 @@ 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 gost 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
+
+# cpu64.c
+decode_idreg_writemap(const char* name, int lower, int upper, char *prop_name) "%s [%d:%d] is writable (prop %s)"
+get_sysreg_prop(const char *name, uint64_t value) "%s 0x%"PRIx64
+set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_value, uint64_t new) "%s old reg value=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new reg value=0x%"PRIx64
+nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 19/20] arm-qmp-cmds: introspection for ID register props
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (17 preceding siblings ...)
2024-12-06 11:22 ` [PATCH RFCv2 18/20] arm/cpu: more customization for the kvm host cpu model Cornelia Huck
@ 2024-12-06 11:22 ` Cornelia Huck
2024-12-06 11:22 ` [PATCH RFCv2 20/20] arm/cpu-features: document ID reg properties Cornelia Huck
` (4 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:22 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
Implement the capability to query available ID register values by
adding SYSREG_* options and values to the cpu model expansion for the
host model, if available.
Excerpt:
(QEMU) query-cpu-model-expansion type=full model={"name":"host"}
{"return": {"model": {"name": "host", "props":
{"SYSREG_ID_AA64PFR0_EL1_EL3": 1224979098931106066,
"SYSREG_ID_AA64ISAR2_EL1_CLRBHB": 0,
../..
So this allows the upper stack to detect available writable ID
regs and the "host passthrough model" values.
[CH: moved SYSREG_* values to host model]
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
TODO: Add the moment there is no way to test changing a given
ID reg field value. ie:
(QEMU) query-cpu-model-expansion type=full model={"name":"host", "prop":{"SYSREG_ID_AA64ISAR0_EL1_DP":0x13}}
---
target/arm/arm-qmp-cmds.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
index 3cc8cc738bb0..44d7bf4c80ce 100644
--- a/target/arm/arm-qmp-cmds.c
+++ b/target/arm/arm-qmp-cmds.c
@@ -21,6 +21,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/error-report.h"
#include "hw/boards.h"
#include "kvm_arm.h"
#include "qapi/error.h"
@@ -209,6 +210,24 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
}
}
+ /* If writable ID regs are supported, add them as well */
+ if (ARM_CPU(obj)->writable_id_regs == WRITABLE_ID_REGS_AVAIL) {
+ ObjectProperty *prop;
+ ObjectPropertyIterator iter;
+
+ object_property_iter_init(&iter, obj);
+
+ while ((prop = object_property_iter_next(&iter))) {
+ QObject *value;
+
+ if (!g_str_has_prefix(prop->name, "SYSREG_")) {
+ continue;
+ }
+ value = object_property_get_qobject(obj, prop->name, &error_abort);
+ qdict_put_obj(qdict_out, prop->name, value);
+ }
+ }
+
if (!qdict_size(qdict_out)) {
qobject_unref(qdict_out);
} else {
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH RFCv2 20/20] arm/cpu-features: document ID reg properties
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (18 preceding siblings ...)
2024-12-06 11:22 ` [PATCH RFCv2 19/20] arm-qmp-cmds: introspection for ID register props Cornelia Huck
@ 2024-12-06 11:22 ` Cornelia Huck
2024-12-12 7:41 ` [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (3 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-06 11:22 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini, Cornelia Huck
Add some documentation for how individual ID registers can be
configured with the host cpu model.
[CH: adapt to removal of the 'custom' model]
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
docs/system/arm/cpu-features.rst | 47 ++++++++++++++++++++++++++------
1 file changed, 39 insertions(+), 8 deletions(-)
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
index a5fb929243c5..abee557d7b6e 100644
--- a/docs/system/arm/cpu-features.rst
+++ b/docs/system/arm/cpu-features.rst
@@ -2,7 +2,10 @@ Arm CPU Features
================
CPU features are optional features that a CPU of supporting type may
-choose to implement or not. In QEMU, optional CPU features have
+choose to implement or not. QEMU provides two different mechanisms
+to configure those features:
+
+1. For most CPU models, optional CPU features may have
corresponding boolean CPU proprieties that, when enabled, indicate
that the feature is implemented, and, conversely, when disabled,
indicate that it is not implemented. An example of an Arm CPU feature
@@ -29,6 +32,16 @@ supports the feature. While ``aarch64`` currently only works with KVM,
it could work with TCG. CPU features that are specific to KVM are
prefixed with "kvm-" and are described in "KVM VCPU Features".
+2. Additionally, the ``host`` CPU model on KVM allows to configure optional
+CPU features via the corresponding ID registers. The host kernel allows
+to write a subset of ID register fields. The host model exposes
+properties for each write ID register fields. Those options are named
+SYSREG_<IDREG>_<FIELD>. IDREG and FIELD names are those used in the
+ARM ARM Reference Manual. They can also be found in the linux
+arch/arm64/tool/sysreg file which is used to automatically generate the
+description for those registers and fields. This currently only has been
+implemented for KVM.
+
CPU Feature Probing
===================
@@ -106,6 +119,10 @@ As expected they are now all ``false``.
Only the ``pmu`` CPU feature is available.
+Probing for the ``custom`` CPU model is working differently. CPU model
+expansion will return the list of available SYSREG properties (matching
+writable ID register fields)
+
A note about CPU feature dependencies
-------------------------------------
@@ -124,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 to the guest, and the host kernel
+supports it, the ``host`` model can be instructed to disable individual
+ID register values. This is especially useful for migration purposes.
+However, this interface will not allow configuring an arbitrary set of
+features; the ID registers must describe a subset of the host's features,
+and all differences to the host's configuration must actually be supported
+by the kernel to be deconfigured.
Enabling KVM also affects the ``query-cpu-model-expansion`` QMP command. The
affect is not only limited to specific features, as pointed out in example
@@ -167,6 +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
=================
--
2.47.0
^ permalink raw reply related [flat|nested] 56+ messages in thread* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (19 preceding siblings ...)
2024-12-06 11:22 ` [PATCH RFCv2 20/20] arm/cpu-features: document ID reg properties Cornelia Huck
@ 2024-12-12 7:41 ` Eric Auger
2024-12-12 8:12 ` Eric Auger
` (2 subsequent siblings)
23 siblings, 0 replies; 56+ messages in thread
From: Eric Auger @ 2024-12-12 7:41 UTC (permalink / raw)
To: Cornelia Huck, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini
Hi Peter, Richard,
On 12/6/24 12:21, Cornelia Huck wrote:
> A respin/update on the aarch64 KVM cpu models. Also available at
> gitlab.com/cohuck/qemu arm-cpu-model-rfcv2
>
> Find Eric's original cover letter below, so that I do not need to
> repeat myself on the aspects that have not changed since RFCv1 :)
>
> Changes from RFCv1:
>
> Rebased on more recent QEMU (some adaptions in the register conversions
> of the first few patches.)
>
> Based on feedback, I have removed the "custom" cpu model; instead, I
> have added the new SYSREG_<REG>_<FIELD> properties to the "host" model.
> This works well if you want to tweak anything that does not correspond
> to the existing properties for the host model; however, if you e.g.
> wanted to tweak sve, you have two ways to do so -- we'd probably either
> want to check for conflicts, or just declare precedence. The kvm-specific
> props remain unchanged, as they are orthogonal to this configuration.
>
> The cpu model expansion for the "host" model now dumps the new SYSREG_
> properties in addition to the existing host model properties; this is a
> bit ugly, but I don't see a good way on how to split this up.
>
> Some more adaptions due to the removal of the "custom" model.
>
> Things *not* changed from RFCv1:
>
> SYSREG_ property naming (can be tweaked easily, once we are clear on what
> the interface should look like.)
>
> Sysreg generation scripts, and the generated files (I have not updated
> anything there.) I think generating the various definitions makes sense,
> as long as we double-check the generated files on each update (which would
> be something to trigger manually anyway.)
>
> What I would like us to reach some kind of consensus on:
>
> How to continue with the patches moving the ID registers from the isar
> struct into the idregs array. These are a bit of churn to drag along;
> if they make sense, maybe they can be picked independently of this series?
What is your opinion on that? Patches 2 -12 are dedicated to the move of
isar struct's individual idreg fields to an array. To me , this
anonymous storage looks more generic, scalable and adapted to the way we
retrieve information from KVM. Do you think this is an acceptable
reshuffle of the code and can we envision to push those changes in a
separate prerequisite series that would avoid us to rebase everytime
until we get a solution for named vcpu models?
Thanks
Eric
>
> Whether it make sense to continue with the approach of tweaking values in
> the ID registers in general. If we want to be able to migrate between cpus
> that do not differ wildly, we'll encounter differences that cannot be
> expressed via FEAT_xxx -- e.g. when comparing various AmpereAltra Max systems,
> they only differ in parts of CTR_EL0 -- which is not a feature register, but
> a writable register.
>
> Please take a look, and looking forward to your feedback :)
>
> ***********************************************************************
>
> Title: Introduce a customizable aarch64 KVM host model
>
> This RFC series introduces a KVM host "custom" model.
>
> 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 custom model uses this capability and allows to tune the host
> passthrough model by overriding some of the host passthrough ID regs.
>
> The end goal is to get more flexibility when migrating guests
> between different machines. We would like the upper software layer
> to be able detect how tunable the vpcu is on both source and destination
> and accordingly define a customized KVM host model that can fit
> both ends. With the legacy host passthrough model, this migration
> use case would fail.
>
> QEMU queries the host kernel to get the list of writable ID reg
> fields and expose all the writable fields as uint64 properties. Those
> are named "SYSREG_<REG>_<FIELD>". REG and FIELD names are those
> described in ARM ARM Reference manual and linux arch/arm64/tools/sysreg.
> Some awk scriptsintroduced in the series help parsing the sysreg file and
> generate some code. those scripts are used in a similar way as
> scripts/update-linux-headers.sh. In case the ABI gets broken, it is
> still possible to manually edit the generated code. However it is
> globally expected the REG and FIELD names are stable.
>
> The list of SYSREG_ID properties can be retrieved through the qmp
> monitor using query-cpu-model-expansion [2].
>
> The first part of the series mostly consists in migrating id reg
> storage from named fields in ARMISARegisters to anonymous index
> ordered storage in an IdRegMap struct array. The goal is to have
> a generic way to store all id registers, also compatible with the
> way we retrieve their writable capability at kernel level through
> the KVM_ARM_GET_REG_WRITABLE_MASKS ioctl. Having named fields
> prevented us from getting this scalability/genericity. Although the
> change is invasive it is quite straightforward and should be easy
> to be reviewed.
>
> Then the bulk of the job is to retrieve the writable ID fields and
> match them against a "human readable" description of those fields.
> We use awk scripts, derived from kernel arch/arm64/tools/gen-sysreg.awk
> (so all the credit to Mark Rutland) that populates a data structure
> which describes all the ID regs in sysreg and their fields. We match
> writable ID reg fields with those latter and dynamically create a
> uint64 property.
>
> Then we need to extend the list of id regs read from the host
> so that we get a chance to let their value overriden and write them
> back into KVM .
>
> This expectation is that this custom KVM host model can prepare for
> the advent of named models. Introducing named models with reduced
> and explicitly defined features is the next step.
>
> Obviously this series is not able to cope with non writable ID regs.
> For instance the problematic of MIDR/REVIDR setting is not handled
> at the moment.
>
>
> TESTS:
> - with few IDREG fields that can be easily examined from guest
> userspace:
> -cpu custom,SYSREG_ID_AA64ISAR0_EL1_DP=0x0,SYSREG_ID_AA64ISAR1_EL1_DPB=0x0
> - migration between custom models
> - TCG A57 non regressions. Light testing for TCG though. Deep
> review may detect some mistakes when migrating between named fields
> and IDRegMap storage
> - light testing of introspection. Testing a given writable ID field
> value with query-cpu-model-expansion is not supported yet.
>
> TODO/QUESTIONS:
> - Some idreg named fields are not yet migrated to an array storage.
> some of them are not in isar struct either. Maybe we could have
> handled TCG and KVM separately and it may turn out that this
> conversion is unneeded. So as it is quite cumbersome I prefered
> to keep it for a later stage.
> - the custom model does not come with legacy host properties
> such as SVE, MTE, expecially those that induce some KVM
> settings. This needs to be fixed.
> - The custom model and its exposed properties depend on the host
> capabilities. More and more IDREG become writable meaning that
> the custom model gains more properties over the time and it is
> host linux dependent. At the moment there is no versioning in
> place. By default the custom model is a host passthrough model
> (besides the legacy functions). So if the end-user tries to set
> a field that is not writable from a kernel pov, it will fail.
> Nevertheless a versionned custom model could constrain the props
> exposed, independently on the host linux capabilities.
> - the QEMU layer does not take care of IDREG field value consistency.
> The kernel neither. I imagine this could be the role of the upper
> layer to implement a vcpu profile that makes sure settings are
> consistent. Here we come to "named" models. What should they look
> like on ARM?
> - Implementation details:
> - it seems there are a lot of duplications in
> the code. ID regs are described in different manners, with different
> data structs, for TCG, now for KVM.
> - The IdRegMap->regs is sparsely populated. Maybe a better data
> struct could be used, although this is the one chosen for the kernel
> uapi.
>
> References:
>
> [1] [PATCH v12 00/11] Support writable CPU ID registers from userspace
> https://lore.kernel.org/all/20230609190054.1542113-1-oliver.upton@linux.dev/
>
> [2]
> qemu-system-aarch64 -qmp unix:/home/augere/TEST/QEMU/qmp-sock,server,nowait -M virt --enable-kvm -cpu custom
> scripts/qmp/qmp-shell /home/augere/TEST/QEMU/qmp-sock
> Welcome to the QMP low-level shell!
> Connected to QEMU 9.0.50
> (QEMU) query-cpu-model-expansion type=full model={"name":"custom"}
>
> [3]
> KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES
> KVM_ARM_GET_REG_WRITABLE_MASKS
> Documentation/virt/kvm/api.rst
>
> [4] linux "sysreg" file
> linux/arch/arm64/tools/sysreg and gen-sysreg.awk
> ./tools/include/generated/asm/sysreg-defs.h
>
>
> Cornelia Huck (3):
> kvm: kvm_get_writable_id_regs
> arm-qmp-cmds: introspection for ID register props
> arm/cpu-features: document ID reg properties
>
> Eric Auger (17):
> arm/cpu: Add sysreg definitions in cpu-sysregs.h
> arm/cpu: Store aa64isar0 into the idregs arrays
> arm/cpu: Store aa64isar1/2 into the idregs array
> arm/cpu: Store aa64drf0/1 into the idregs array
> arm/cpu: Store aa64mmfr0-3 into the idregs array
> arm/cpu: Store aa64drf0/1 into the idregs array
> arm/cpu: Store aa64smfr0 into the idregs array
> arm/cpu: Store id_isar0-7 into the idregs array
> arm/cpu: Store id_mfr0/1 into the idregs array
> arm/cpu: Store id_dfr0/1 into the idregs array
> arm/cpu: Store id_mmfr0-5 into the idregs array
> arm/cpu: Add infra to handle generated ID register definitions
> arm/cpu: Add sysreg generation scripts
> arm/cpu: Add generated files
> arm/kvm: Allow reading all the writable ID registers
> arm/kvm: write back modified ID regs to KVM
> arm/cpu: more customization for the kvm host cpu model
>
> docs/system/arm/cpu-features.rst | 47 +-
> hw/intc/armv7m_nvic.c | 27 +-
> scripts/gen-cpu-sysreg-properties.awk | 325 ++++++++++++
> scripts/gen-cpu-sysregs-header.awk | 47 ++
> scripts/update-aarch64-sysreg-code.sh | 27 +
> target/arm/arm-qmp-cmds.c | 19 +
> target/arm/cpu-custom.h | 58 +++
> target/arm/cpu-features.h | 311 ++++++------
> target/arm/cpu-sysreg-properties.c | 682 ++++++++++++++++++++++++++
> target/arm/cpu-sysregs.h | 152 ++++++
> target/arm/cpu.c | 123 ++---
> target/arm/cpu.h | 120 +++--
> target/arm/cpu64.c | 260 +++++++---
> target/arm/helper.c | 68 +--
> target/arm/internals.h | 6 +-
> target/arm/kvm.c | 253 +++++++---
> target/arm/kvm_arm.h | 16 +-
> target/arm/meson.build | 1 +
> target/arm/ptw.c | 6 +-
> target/arm/tcg/cpu-v7m.c | 174 +++----
> target/arm/tcg/cpu32.c | 320 ++++++------
> target/arm/tcg/cpu64.c | 460 ++++++++---------
> target/arm/trace-events | 8 +
> 23 files changed, 2594 insertions(+), 916 deletions(-)
> create mode 100755 scripts/gen-cpu-sysreg-properties.awk
> create mode 100755 scripts/gen-cpu-sysregs-header.awk
> create mode 100755 scripts/update-aarch64-sysreg-code.sh
> create mode 100644 target/arm/cpu-custom.h
> create mode 100644 target/arm/cpu-sysreg-properties.c
> create mode 100644 target/arm/cpu-sysregs.h
>
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (20 preceding siblings ...)
2024-12-12 7:41 ` [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
@ 2024-12-12 8:12 ` Eric Auger
2024-12-12 8:42 ` Eric Auger
` (2 more replies)
2024-12-12 13:13 ` Sebastian Ott
2024-12-17 15:21 ` Marc Zyngier
23 siblings, 3 replies; 56+ messages in thread
From: Eric Auger @ 2024-12-12 8:12 UTC (permalink / raw)
To: Cornelia Huck, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini
Connie,
On 12/6/24 12:21, Cornelia Huck wrote:
> A respin/update on the aarch64 KVM cpu models. Also available at
> gitlab.com/cohuck/qemu arm-cpu-model-rfcv2
>
> Find Eric's original cover letter below, so that I do not need to
> repeat myself on the aspects that have not changed since RFCv1 :)
>
> Changes from RFCv1:
>
> Rebased on more recent QEMU (some adaptions in the register conversions
> of the first few patches.)
>
> Based on feedback, I have removed the "custom" cpu model; instead, I
> have added the new SYSREG_<REG>_<FIELD> properties to the "host" model.
> This works well if you want to tweak anything that does not correspond
> to the existing properties for the host model; however, if you e.g.
> wanted to tweak sve, you have two ways to do so -- we'd probably either
> want to check for conflicts, or just declare precedence. The kvm-specific
> props remain unchanged, as they are orthogonal to this configuration.
>
> The cpu model expansion for the "host" model now dumps the new SYSREG_
> properties in addition to the existing host model properties; this is a
> bit ugly, but I don't see a good way on how to split this up.
>
> Some more adaptions due to the removal of the "custom" model.
>
> Things *not* changed from RFCv1:
>
> SYSREG_ property naming (can be tweaked easily, once we are clear on what
> the interface should look like.)
>
> Sysreg generation scripts, and the generated files (I have not updated
> anything there.) I think generating the various definitions makes sense,
> as long as we double-check the generated files on each update (which would
> be something to trigger manually anyway.)
>
> What I would like us to reach some kind of consensus on:
>
> How to continue with the patches moving the ID registers from the isar
> struct into the idregs array. These are a bit of churn to drag along;
> if they make sense, maybe they can be picked independently of this series?
>
> Whether it make sense to continue with the approach of tweaking values in
> the ID registers in general. If we want to be able to migrate between cpus
> that do not differ wildly, we'll encounter differences that cannot be
> expressed via FEAT_xxx -- e.g. when comparing various AmpereAltra Max systems,
> they only differ in parts of CTR_EL0 -- which is not a feature register, but
> a writable register.
In v1 most of the commenters said they would prefer to see FEAT props
instead of IDREG field props. I think we shall try to go in this
direction anyway. As you pointed out there will be some cases where FEAT
won't be enough (CTR_EL0 is a good example). So I tend to think the end
solution will be a mix of FEAT and ID reg field props.
Personally I would smoothly migrate what we can from ID reg field props
to FEAT props (maybe using prop aliases?), starting from the easiest 1-1
mappings and then adressing the FEAT that are more complex but are
explictly needed to enable the use cases we are interested in, at RedHat:
migration within Ampere AltraMax family, migration within NVidia Grace
family, migration within AmpereOne family and migration between Graviton3/4.
We have no info about other's use cases. If some of you want to see some
other live migration combinations addressed, please raise your voice.
Some CSPs may have their own LM solution/requirements but they don't use
qemu. So I think we shall concentrate on those use cases.
You did the exercise to identify most prevalent patterns for FEAT to
IDREG fields mappings. I think we should now encode this conversion
table for those which are needed in above use cases.
From a named model point of view, since I do not see much traction
upstream besides Red Hat use cases, targetting ARM spec revision
baselines may be overkill. Personally I would try to focus on above
models: AltraMax, AmpereOne, Grace, ... Or maybe the ARM cores they may
be derived from. According to the discussion we had with Marc in [1] it
seems it does not make sense to target migration between very
heterogeneous machines and Dan said we would prefer to avoid adding
plenty of feat add-ons to a named models. So I would rather be as close
as possible to a specific family definition.
Thanks
Eric
[1]
https://lore.kernel.org/all/c879fda9-db5a-4743-805d-03c0acba8060@redhat.com/#r
>
> Please take a look, and looking forward to your feedback :)
>
> ***********************************************************************
>
> Title: Introduce a customizable aarch64 KVM host model
>
> This RFC series introduces a KVM host "custom" model.
>
> 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 custom model uses this capability and allows to tune the host
> passthrough model by overriding some of the host passthrough ID regs.
>
> The end goal is to get more flexibility when migrating guests
> between different machines. We would like the upper software layer
> to be able detect how tunable the vpcu is on both source and destination
> and accordingly define a customized KVM host model that can fit
> both ends. With the legacy host passthrough model, this migration
> use case would fail.
>
> QEMU queries the host kernel to get the list of writable ID reg
> fields and expose all the writable fields as uint64 properties. Those
> are named "SYSREG_<REG>_<FIELD>". REG and FIELD names are those
> described in ARM ARM Reference manual and linux arch/arm64/tools/sysreg.
> Some awk scriptsintroduced in the series help parsing the sysreg file and
> generate some code. those scripts are used in a similar way as
> scripts/update-linux-headers.sh. In case the ABI gets broken, it is
> still possible to manually edit the generated code. However it is
> globally expected the REG and FIELD names are stable.
>
> The list of SYSREG_ID properties can be retrieved through the qmp
> monitor using query-cpu-model-expansion [2].
>
> The first part of the series mostly consists in migrating id reg
> storage from named fields in ARMISARegisters to anonymous index
> ordered storage in an IdRegMap struct array. The goal is to have
> a generic way to store all id registers, also compatible with the
> way we retrieve their writable capability at kernel level through
> the KVM_ARM_GET_REG_WRITABLE_MASKS ioctl. Having named fields
> prevented us from getting this scalability/genericity. Although the
> change is invasive it is quite straightforward and should be easy
> to be reviewed.
>
> Then the bulk of the job is to retrieve the writable ID fields and
> match them against a "human readable" description of those fields.
> We use awk scripts, derived from kernel arch/arm64/tools/gen-sysreg.awk
> (so all the credit to Mark Rutland) that populates a data structure
> which describes all the ID regs in sysreg and their fields. We match
> writable ID reg fields with those latter and dynamically create a
> uint64 property.
>
> Then we need to extend the list of id regs read from the host
> so that we get a chance to let their value overriden and write them
> back into KVM .
>
> This expectation is that this custom KVM host model can prepare for
> the advent of named models. Introducing named models with reduced
> and explicitly defined features is the next step.
>
> Obviously this series is not able to cope with non writable ID regs.
> For instance the problematic of MIDR/REVIDR setting is not handled
> at the moment.
>
>
> TESTS:
> - with few IDREG fields that can be easily examined from guest
> userspace:
> -cpu custom,SYSREG_ID_AA64ISAR0_EL1_DP=0x0,SYSREG_ID_AA64ISAR1_EL1_DPB=0x0
> - migration between custom models
> - TCG A57 non regressions. Light testing for TCG though. Deep
> review may detect some mistakes when migrating between named fields
> and IDRegMap storage
> - light testing of introspection. Testing a given writable ID field
> value with query-cpu-model-expansion is not supported yet.
>
> TODO/QUESTIONS:
> - Some idreg named fields are not yet migrated to an array storage.
> some of them are not in isar struct either. Maybe we could have
> handled TCG and KVM separately and it may turn out that this
> conversion is unneeded. So as it is quite cumbersome I prefered
> to keep it for a later stage.
> - the custom model does not come with legacy host properties
> such as SVE, MTE, expecially those that induce some KVM
> settings. This needs to be fixed.
> - The custom model and its exposed properties depend on the host
> capabilities. More and more IDREG become writable meaning that
> the custom model gains more properties over the time and it is
> host linux dependent. At the moment there is no versioning in
> place. By default the custom model is a host passthrough model
> (besides the legacy functions). So if the end-user tries to set
> a field that is not writable from a kernel pov, it will fail.
> Nevertheless a versionned custom model could constrain the props
> exposed, independently on the host linux capabilities.
> - the QEMU layer does not take care of IDREG field value consistency.
> The kernel neither. I imagine this could be the role of the upper
> layer to implement a vcpu profile that makes sure settings are
> consistent. Here we come to "named" models. What should they look
> like on ARM?
> - Implementation details:
> - it seems there are a lot of duplications in
> the code. ID regs are described in different manners, with different
> data structs, for TCG, now for KVM.
> - The IdRegMap->regs is sparsely populated. Maybe a better data
> struct could be used, although this is the one chosen for the kernel
> uapi.
>
> References:
>
> [1] [PATCH v12 00/11] Support writable CPU ID registers from userspace
> https://lore.kernel.org/all/20230609190054.1542113-1-oliver.upton@linux.dev/
>
> [2]
> qemu-system-aarch64 -qmp unix:/home/augere/TEST/QEMU/qmp-sock,server,nowait -M virt --enable-kvm -cpu custom
> scripts/qmp/qmp-shell /home/augere/TEST/QEMU/qmp-sock
> Welcome to the QMP low-level shell!
> Connected to QEMU 9.0.50
> (QEMU) query-cpu-model-expansion type=full model={"name":"custom"}
>
> [3]
> KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES
> KVM_ARM_GET_REG_WRITABLE_MASKS
> Documentation/virt/kvm/api.rst
>
> [4] linux "sysreg" file
> linux/arch/arm64/tools/sysreg and gen-sysreg.awk
> ./tools/include/generated/asm/sysreg-defs.h
>
>
> Cornelia Huck (3):
> kvm: kvm_get_writable_id_regs
> arm-qmp-cmds: introspection for ID register props
> arm/cpu-features: document ID reg properties
>
> Eric Auger (17):
> arm/cpu: Add sysreg definitions in cpu-sysregs.h
> arm/cpu: Store aa64isar0 into the idregs arrays
> arm/cpu: Store aa64isar1/2 into the idregs array
> arm/cpu: Store aa64drf0/1 into the idregs array
> arm/cpu: Store aa64mmfr0-3 into the idregs array
> arm/cpu: Store aa64drf0/1 into the idregs array
> arm/cpu: Store aa64smfr0 into the idregs array
> arm/cpu: Store id_isar0-7 into the idregs array
> arm/cpu: Store id_mfr0/1 into the idregs array
> arm/cpu: Store id_dfr0/1 into the idregs array
> arm/cpu: Store id_mmfr0-5 into the idregs array
> arm/cpu: Add infra to handle generated ID register definitions
> arm/cpu: Add sysreg generation scripts
> arm/cpu: Add generated files
> arm/kvm: Allow reading all the writable ID registers
> arm/kvm: write back modified ID regs to KVM
> arm/cpu: more customization for the kvm host cpu model
>
> docs/system/arm/cpu-features.rst | 47 +-
> hw/intc/armv7m_nvic.c | 27 +-
> scripts/gen-cpu-sysreg-properties.awk | 325 ++++++++++++
> scripts/gen-cpu-sysregs-header.awk | 47 ++
> scripts/update-aarch64-sysreg-code.sh | 27 +
> target/arm/arm-qmp-cmds.c | 19 +
> target/arm/cpu-custom.h | 58 +++
> target/arm/cpu-features.h | 311 ++++++------
> target/arm/cpu-sysreg-properties.c | 682 ++++++++++++++++++++++++++
> target/arm/cpu-sysregs.h | 152 ++++++
> target/arm/cpu.c | 123 ++---
> target/arm/cpu.h | 120 +++--
> target/arm/cpu64.c | 260 +++++++---
> target/arm/helper.c | 68 +--
> target/arm/internals.h | 6 +-
> target/arm/kvm.c | 253 +++++++---
> target/arm/kvm_arm.h | 16 +-
> target/arm/meson.build | 1 +
> target/arm/ptw.c | 6 +-
> target/arm/tcg/cpu-v7m.c | 174 +++----
> target/arm/tcg/cpu32.c | 320 ++++++------
> target/arm/tcg/cpu64.c | 460 ++++++++---------
> target/arm/trace-events | 8 +
> 23 files changed, 2594 insertions(+), 916 deletions(-)
> create mode 100755 scripts/gen-cpu-sysreg-properties.awk
> create mode 100755 scripts/gen-cpu-sysregs-header.awk
> create mode 100755 scripts/update-aarch64-sysreg-code.sh
> create mode 100644 target/arm/cpu-custom.h
> create mode 100644 target/arm/cpu-sysreg-properties.c
> create mode 100644 target/arm/cpu-sysregs.h
>
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-12 8:12 ` Eric Auger
@ 2024-12-12 8:42 ` Eric Auger
2024-12-12 13:09 ` Shameerali Kolothum Thodi via
2024-12-12 9:10 ` Daniel P. Berrangé
2024-12-16 16:42 ` Cornelia Huck
2 siblings, 1 reply; 56+ messages in thread
From: Eric Auger @ 2024-12-12 8:42 UTC (permalink / raw)
To: eric.auger, Cornelia Huck, eric.auger.pro, qemu-devel, qemu-arm,
kvmarm, peter.maydell, richard.henderson, alex.bennee, maz,
oliver.upton, sebott, shameerali.kolothum.thodi, armbru, berrange,
abologna, jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini
Shameer,
On 12/12/24 09:12, Eric Auger wrote:
> Connie,
>
> On 12/6/24 12:21, Cornelia Huck wrote:
>> A respin/update on the aarch64 KVM cpu models. Also available at
>> gitlab.com/cohuck/qemu arm-cpu-model-rfcv2
>>
>> Find Eric's original cover letter below, so that I do not need to
>> repeat myself on the aspects that have not changed since RFCv1 :)
>>
>> Changes from RFCv1:
>>
>> Rebased on more recent QEMU (some adaptions in the register conversions
>> of the first few patches.)
>>
>> Based on feedback, I have removed the "custom" cpu model; instead, I
>> have added the new SYSREG_<REG>_<FIELD> properties to the "host" model.
>> This works well if you want to tweak anything that does not correspond
>> to the existing properties for the host model; however, if you e.g.
>> wanted to tweak sve, you have two ways to do so -- we'd probably either
>> want to check for conflicts, or just declare precedence. The kvm-specific
>> props remain unchanged, as they are orthogonal to this configuration.
>>
>> The cpu model expansion for the "host" model now dumps the new SYSREG_
>> properties in addition to the existing host model properties; this is a
>> bit ugly, but I don't see a good way on how to split this up.
>>
>> Some more adaptions due to the removal of the "custom" model.
>>
>> Things *not* changed from RFCv1:
>>
>> SYSREG_ property naming (can be tweaked easily, once we are clear on what
>> the interface should look like.)
>>
>> Sysreg generation scripts, and the generated files (I have not updated
>> anything there.) I think generating the various definitions makes sense,
>> as long as we double-check the generated files on each update (which would
>> be something to trigger manually anyway.)
>>
>> What I would like us to reach some kind of consensus on:
>>
>> How to continue with the patches moving the ID registers from the isar
>> struct into the idregs array. These are a bit of churn to drag along;
>> if they make sense, maybe they can be picked independently of this series?
>>
>> Whether it make sense to continue with the approach of tweaking values in
>> the ID registers in general. If we want to be able to migrate between cpus
>> that do not differ wildly, we'll encounter differences that cannot be
>> expressed via FEAT_xxx -- e.g. when comparing various AmpereAltra Max systems,
>> they only differ in parts of CTR_EL0 -- which is not a feature register, but
>> a writable register.
> In v1 most of the commenters said they would prefer to see FEAT props
> instead of IDREG field props. I think we shall try to go in this
> direction anyway. As you pointed out there will be some cases where FEAT
> won't be enough (CTR_EL0 is a good example). So I tend to think the end
> solution will be a mix of FEAT and ID reg field props.
>
> Personally I would smoothly migrate what we can from ID reg field props
> to FEAT props (maybe using prop aliases?), starting from the easiest 1-1
> mappings and then adressing the FEAT that are more complex but are
> explictly needed to enable the use cases we are interested in, at RedHat:
> migration within Ampere AltraMax family, migration within NVidia Grace
> family, migration within AmpereOne family and migration between Graviton3/4.
>
> We have no info about other's use cases. If some of you want to see some
> other live migration combinations addressed, please raise your voice.
In relation to [1] you seem to be also interested in the migration
between heterogeneous systems with qemu.
Do you think targeting migration within a cpu family is enough for your
use cases. How different are the source and destination host on your
cases. Do you thing feat props are relevant in your case or would you
need lower granularity at idreg field levelto pass the migration?
[1] [PATCH v3 0/3] KVM: arm64: Errata management for VM Live migration
https://lore.kernel.org/all/20241209115311.40496-1-shameerali.kolothum.thodi@huawei.com/
Thank you in advance
Eric
> Some CSPs may have their own LM solution/requirements but they don't use
> qemu. So I think we shall concentrate on those use cases.
>
> You did the exercise to identify most prevalent patterns for FEAT to
> IDREG fields mappings. I think we should now encode this conversion
> table for those which are needed in above use cases.
>
> From a named model point of view, since I do not see much traction
> upstream besides Red Hat use cases, targetting ARM spec revision
> baselines may be overkill. Personally I would try to focus on above
> models: AltraMax, AmpereOne, Grace, ... Or maybe the ARM cores they may
> be derived from. According to the discussion we had with Marc in [1] it
> seems it does not make sense to target migration between very
> heterogeneous machines and Dan said we would prefer to avoid adding
> plenty of feat add-ons to a named models. So I would rather be as close
> as possible to a specific family definition.
>
> Thanks
>
> Eric
>
> [1]
> https://lore.kernel.org/all/c879fda9-db5a-4743-805d-03c0acba8060@redhat.com/#r
>
>>
>> Please take a look, and looking forward to your feedback :)
>>
>> ***********************************************************************
>>
>> Title: Introduce a customizable aarch64 KVM host model
>>
>> This RFC series introduces a KVM host "custom" model.
>>
>> 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 custom model uses this capability and allows to tune the host
>> passthrough model by overriding some of the host passthrough ID regs.
>>
>> The end goal is to get more flexibility when migrating guests
>> between different machines. We would like the upper software layer
>> to be able detect how tunable the vpcu is on both source and destination
>> and accordingly define a customized KVM host model that can fit
>> both ends. With the legacy host passthrough model, this migration
>> use case would fail.
>>
>> QEMU queries the host kernel to get the list of writable ID reg
>> fields and expose all the writable fields as uint64 properties. Those
>> are named "SYSREG_<REG>_<FIELD>". REG and FIELD names are those
>> described in ARM ARM Reference manual and linux arch/arm64/tools/sysreg.
>> Some awk scriptsintroduced in the series help parsing the sysreg file and
>> generate some code. those scripts are used in a similar way as
>> scripts/update-linux-headers.sh. In case the ABI gets broken, it is
>> still possible to manually edit the generated code. However it is
>> globally expected the REG and FIELD names are stable.
>>
>> The list of SYSREG_ID properties can be retrieved through the qmp
>> monitor using query-cpu-model-expansion [2].
>>
>> The first part of the series mostly consists in migrating id reg
>> storage from named fields in ARMISARegisters to anonymous index
>> ordered storage in an IdRegMap struct array. The goal is to have
>> a generic way to store all id registers, also compatible with the
>> way we retrieve their writable capability at kernel level through
>> the KVM_ARM_GET_REG_WRITABLE_MASKS ioctl. Having named fields
>> prevented us from getting this scalability/genericity. Although the
>> change is invasive it is quite straightforward and should be easy
>> to be reviewed.
>>
>> Then the bulk of the job is to retrieve the writable ID fields and
>> match them against a "human readable" description of those fields.
>> We use awk scripts, derived from kernel arch/arm64/tools/gen-sysreg.awk
>> (so all the credit to Mark Rutland) that populates a data structure
>> which describes all the ID regs in sysreg and their fields. We match
>> writable ID reg fields with those latter and dynamically create a
>> uint64 property.
>>
>> Then we need to extend the list of id regs read from the host
>> so that we get a chance to let their value overriden and write them
>> back into KVM .
>>
>> This expectation is that this custom KVM host model can prepare for
>> the advent of named models. Introducing named models with reduced
>> and explicitly defined features is the next step.
>>
>> Obviously this series is not able to cope with non writable ID regs.
>> For instance the problematic of MIDR/REVIDR setting is not handled
>> at the moment.
>>
>>
>> TESTS:
>> - with few IDREG fields that can be easily examined from guest
>> userspace:
>> -cpu custom,SYSREG_ID_AA64ISAR0_EL1_DP=0x0,SYSREG_ID_AA64ISAR1_EL1_DPB=0x0
>> - migration between custom models
>> - TCG A57 non regressions. Light testing for TCG though. Deep
>> review may detect some mistakes when migrating between named fields
>> and IDRegMap storage
>> - light testing of introspection. Testing a given writable ID field
>> value with query-cpu-model-expansion is not supported yet.
>>
>> TODO/QUESTIONS:
>> - Some idreg named fields are not yet migrated to an array storage.
>> some of them are not in isar struct either. Maybe we could have
>> handled TCG and KVM separately and it may turn out that this
>> conversion is unneeded. So as it is quite cumbersome I prefered
>> to keep it for a later stage.
>> - the custom model does not come with legacy host properties
>> such as SVE, MTE, expecially those that induce some KVM
>> settings. This needs to be fixed.
>> - The custom model and its exposed properties depend on the host
>> capabilities. More and more IDREG become writable meaning that
>> the custom model gains more properties over the time and it is
>> host linux dependent. At the moment there is no versioning in
>> place. By default the custom model is a host passthrough model
>> (besides the legacy functions). So if the end-user tries to set
>> a field that is not writable from a kernel pov, it will fail.
>> Nevertheless a versionned custom model could constrain the props
>> exposed, independently on the host linux capabilities.
>> - the QEMU layer does not take care of IDREG field value consistency.
>> The kernel neither. I imagine this could be the role of the upper
>> layer to implement a vcpu profile that makes sure settings are
>> consistent. Here we come to "named" models. What should they look
>> like on ARM?
>> - Implementation details:
>> - it seems there are a lot of duplications in
>> the code. ID regs are described in different manners, with different
>> data structs, for TCG, now for KVM.
>> - The IdRegMap->regs is sparsely populated. Maybe a better data
>> struct could be used, although this is the one chosen for the kernel
>> uapi.
>>
>> References:
>>
>> [1] [PATCH v12 00/11] Support writable CPU ID registers from userspace
>> https://lore.kernel.org/all/20230609190054.1542113-1-oliver.upton@linux.dev/
>>
>> [2]
>> qemu-system-aarch64 -qmp unix:/home/augere/TEST/QEMU/qmp-sock,server,nowait -M virt --enable-kvm -cpu custom
>> scripts/qmp/qmp-shell /home/augere/TEST/QEMU/qmp-sock
>> Welcome to the QMP low-level shell!
>> Connected to QEMU 9.0.50
>> (QEMU) query-cpu-model-expansion type=full model={"name":"custom"}
>>
>> [3]
>> KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES
>> KVM_ARM_GET_REG_WRITABLE_MASKS
>> Documentation/virt/kvm/api.rst
>>
>> [4] linux "sysreg" file
>> linux/arch/arm64/tools/sysreg and gen-sysreg.awk
>> ./tools/include/generated/asm/sysreg-defs.h
>>
>>
>> Cornelia Huck (3):
>> kvm: kvm_get_writable_id_regs
>> arm-qmp-cmds: introspection for ID register props
>> arm/cpu-features: document ID reg properties
>>
>> Eric Auger (17):
>> arm/cpu: Add sysreg definitions in cpu-sysregs.h
>> arm/cpu: Store aa64isar0 into the idregs arrays
>> arm/cpu: Store aa64isar1/2 into the idregs array
>> arm/cpu: Store aa64drf0/1 into the idregs array
>> arm/cpu: Store aa64mmfr0-3 into the idregs array
>> arm/cpu: Store aa64drf0/1 into the idregs array
>> arm/cpu: Store aa64smfr0 into the idregs array
>> arm/cpu: Store id_isar0-7 into the idregs array
>> arm/cpu: Store id_mfr0/1 into the idregs array
>> arm/cpu: Store id_dfr0/1 into the idregs array
>> arm/cpu: Store id_mmfr0-5 into the idregs array
>> arm/cpu: Add infra to handle generated ID register definitions
>> arm/cpu: Add sysreg generation scripts
>> arm/cpu: Add generated files
>> arm/kvm: Allow reading all the writable ID registers
>> arm/kvm: write back modified ID regs to KVM
>> arm/cpu: more customization for the kvm host cpu model
>>
>> docs/system/arm/cpu-features.rst | 47 +-
>> hw/intc/armv7m_nvic.c | 27 +-
>> scripts/gen-cpu-sysreg-properties.awk | 325 ++++++++++++
>> scripts/gen-cpu-sysregs-header.awk | 47 ++
>> scripts/update-aarch64-sysreg-code.sh | 27 +
>> target/arm/arm-qmp-cmds.c | 19 +
>> target/arm/cpu-custom.h | 58 +++
>> target/arm/cpu-features.h | 311 ++++++------
>> target/arm/cpu-sysreg-properties.c | 682 ++++++++++++++++++++++++++
>> target/arm/cpu-sysregs.h | 152 ++++++
>> target/arm/cpu.c | 123 ++---
>> target/arm/cpu.h | 120 +++--
>> target/arm/cpu64.c | 260 +++++++---
>> target/arm/helper.c | 68 +--
>> target/arm/internals.h | 6 +-
>> target/arm/kvm.c | 253 +++++++---
>> target/arm/kvm_arm.h | 16 +-
>> target/arm/meson.build | 1 +
>> target/arm/ptw.c | 6 +-
>> target/arm/tcg/cpu-v7m.c | 174 +++----
>> target/arm/tcg/cpu32.c | 320 ++++++------
>> target/arm/tcg/cpu64.c | 460 ++++++++---------
>> target/arm/trace-events | 8 +
>> 23 files changed, 2594 insertions(+), 916 deletions(-)
>> create mode 100755 scripts/gen-cpu-sysreg-properties.awk
>> create mode 100755 scripts/gen-cpu-sysregs-header.awk
>> create mode 100755 scripts/update-aarch64-sysreg-code.sh
>> create mode 100644 target/arm/cpu-custom.h
>> create mode 100644 target/arm/cpu-sysreg-properties.c
>> create mode 100644 target/arm/cpu-sysregs.h
>>
>
^ permalink raw reply [flat|nested] 56+ messages in thread* RE: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-12 8:42 ` Eric Auger
@ 2024-12-12 13:09 ` Shameerali Kolothum Thodi via
0 siblings, 0 replies; 56+ messages in thread
From: Shameerali Kolothum Thodi @ 2024-12-12 13:09 UTC (permalink / raw)
To: Eric Auger, eric.auger@redhat.com, Cornelia Huck,
eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, richard.henderson@linaro.org,
alex.bennee@linaro.org, maz@kernel.org, oliver.upton@linux.dev,
sebott@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Cc: shahuang@redhat.com, mark.rutland@arm.com, philmd@linaro.org,
pbonzini@redhat.com, Wangzhou (B), Linuxarm
Hi Eric,
> -----Original Message-----
> From: Eric Auger <eauger@redhat.com>
> Sent: Thursday, December 12, 2024 8:42 AM
> To: eric.auger@redhat.com; Cornelia Huck <cohuck@redhat.com>;
> eric.auger.pro@gmail.com; qemu-devel@nongnu.org; qemu-
> arm@nongnu.org; kvmarm@lists.linux.dev; peter.maydell@linaro.org;
> richard.henderson@linaro.org; alex.bennee@linaro.org; maz@kernel.org;
> oliver.upton@linux.dev; sebott@redhat.com; Shameerali Kolothum Thodi
> <shameerali.kolothum.thodi@huawei.com>; armbru@redhat.com;
> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
> Cc: shahuang@redhat.com; mark.rutland@arm.com; philmd@linaro.org;
> pbonzini@redhat.com
> Subject: Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable
> aarch64 KVM host model
>
> Shameer,
>
> On 12/12/24 09:12, Eric Auger wrote:
> > Connie,
> >
> > On 12/6/24 12:21, Cornelia Huck wrote:
> >> A respin/update on the aarch64 KVM cpu models. Also available at
> >> gitlab.com/cohuck/qemu arm-cpu-model-rfcv2
> >>
> >> Find Eric's original cover letter below, so that I do not need to
> >> repeat myself on the aspects that have not changed since RFCv1 :)
> >>
> >> Changes from RFCv1:
> >>
> >> Rebased on more recent QEMU (some adaptions in the register
> conversions
> >> of the first few patches.)
> >>
> >> Based on feedback, I have removed the "custom" cpu model; instead, I
> >> have added the new SYSREG_<REG>_<FIELD> properties to the "host"
> model.
> >> This works well if you want to tweak anything that does not correspond
> >> to the existing properties for the host model; however, if you e.g.
> >> wanted to tweak sve, you have two ways to do so -- we'd probably either
> >> want to check for conflicts, or just declare precedence. The kvm-specific
> >> props remain unchanged, as they are orthogonal to this configuration.
> >>
> >> The cpu model expansion for the "host" model now dumps the new
> SYSREG_
> >> properties in addition to the existing host model properties; this is a
> >> bit ugly, but I don't see a good way on how to split this up.
> >>
> >> Some more adaptions due to the removal of the "custom" model.
> >>
> >> Things *not* changed from RFCv1:
> >>
> >> SYSREG_ property naming (can be tweaked easily, once we are clear on
> what
> >> the interface should look like.)
> >>
> >> Sysreg generation scripts, and the generated files (I have not updated
> >> anything there.) I think generating the various definitions makes sense,
> >> as long as we double-check the generated files on each update (which
> would
> >> be something to trigger manually anyway.)
> >>
> >> What I would like us to reach some kind of consensus on:
> >>
> >> How to continue with the patches moving the ID registers from the isar
> >> struct into the idregs array. These are a bit of churn to drag along;
> >> if they make sense, maybe they can be picked independently of this
> series?
> >>
> >> Whether it make sense to continue with the approach of tweaking
> values in
> >> the ID registers in general. If we want to be able to migrate between
> cpus
> >> that do not differ wildly, we'll encounter differences that cannot be
> >> expressed via FEAT_xxx -- e.g. when comparing various AmpereAltra Max
> systems,
> >> they only differ in parts of CTR_EL0 -- which is not a feature register, but
> >> a writable register.
> > In v1 most of the commenters said they would prefer to see FEAT props
> > instead of IDREG field props. I think we shall try to go in this
> > direction anyway. As you pointed out there will be some cases where
> FEAT
> > won't be enough (CTR_EL0 is a good example). So I tend to think the end
> > solution will be a mix of FEAT and ID reg field props.
> >
> > Personally I would smoothly migrate what we can from ID reg field props
> > to FEAT props (maybe using prop aliases?), starting from the easiest 1-1
> > mappings and then adressing the FEAT that are more complex but are
> > explictly needed to enable the use cases we are interested in, at RedHat:
> > migration within Ampere AltraMax family, migration within NVidia Grace
> > family, migration within AmpereOne family and migration between
> Graviton3/4.
> >
> > We have no info about other's use cases. If some of you want to see some
> > other live migration combinations addressed, please raise your voice.
> In relation to [1] you seem to be also interested in the migration
> between heterogeneous systems with qemu.
Yes. That is correct.
> Do you think targeting migration within a cpu family is enough for your
> use cases. How different are the source and destination host on your
> cases. Do you thing feat props are relevant in your case or would you
> need lower granularity at idreg field levelto pass the migration?
I think, from the current requirement we have for migration, the source and
destination mostly can be handled by FEAT_XXX. But like Ampere, we do need
to manage the CTR_EL0 differences[1].
Also we do have differences in GIC support as well(AA64PFR0_EL1.GIC) which
I am not sure how to manage with FEAT_XXX.
And we are checking with our Product team whether we need to support migration
from an old CPU type in which case we have to do a bit more analysis.
Thanks,
Shameer
1. https://lore.kernel.org/kvmarm/20241022073943.35764-1-shameerali.kolothum.thodi@huawei.com/
^ permalink raw reply [flat|nested] 56+ messages in thread
* RE: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
@ 2024-12-12 13:09 ` Shameerali Kolothum Thodi via
0 siblings, 0 replies; 56+ messages in thread
From: Shameerali Kolothum Thodi via @ 2024-12-12 13:09 UTC (permalink / raw)
To: Eric Auger, eric.auger@redhat.com, Cornelia Huck,
eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, richard.henderson@linaro.org,
alex.bennee@linaro.org, maz@kernel.org, oliver.upton@linux.dev,
sebott@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Cc: shahuang@redhat.com, mark.rutland@arm.com, philmd@linaro.org,
pbonzini@redhat.com, Wangzhou (B), Linuxarm
Hi Eric,
> -----Original Message-----
> From: Eric Auger <eauger@redhat.com>
> Sent: Thursday, December 12, 2024 8:42 AM
> To: eric.auger@redhat.com; Cornelia Huck <cohuck@redhat.com>;
> eric.auger.pro@gmail.com; qemu-devel@nongnu.org; qemu-
> arm@nongnu.org; kvmarm@lists.linux.dev; peter.maydell@linaro.org;
> richard.henderson@linaro.org; alex.bennee@linaro.org; maz@kernel.org;
> oliver.upton@linux.dev; sebott@redhat.com; Shameerali Kolothum Thodi
> <shameerali.kolothum.thodi@huawei.com>; armbru@redhat.com;
> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
> Cc: shahuang@redhat.com; mark.rutland@arm.com; philmd@linaro.org;
> pbonzini@redhat.com
> Subject: Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable
> aarch64 KVM host model
>
> Shameer,
>
> On 12/12/24 09:12, Eric Auger wrote:
> > Connie,
> >
> > On 12/6/24 12:21, Cornelia Huck wrote:
> >> A respin/update on the aarch64 KVM cpu models. Also available at
> >> gitlab.com/cohuck/qemu arm-cpu-model-rfcv2
> >>
> >> Find Eric's original cover letter below, so that I do not need to
> >> repeat myself on the aspects that have not changed since RFCv1 :)
> >>
> >> Changes from RFCv1:
> >>
> >> Rebased on more recent QEMU (some adaptions in the register
> conversions
> >> of the first few patches.)
> >>
> >> Based on feedback, I have removed the "custom" cpu model; instead, I
> >> have added the new SYSREG_<REG>_<FIELD> properties to the "host"
> model.
> >> This works well if you want to tweak anything that does not correspond
> >> to the existing properties for the host model; however, if you e.g.
> >> wanted to tweak sve, you have two ways to do so -- we'd probably either
> >> want to check for conflicts, or just declare precedence. The kvm-specific
> >> props remain unchanged, as they are orthogonal to this configuration.
> >>
> >> The cpu model expansion for the "host" model now dumps the new
> SYSREG_
> >> properties in addition to the existing host model properties; this is a
> >> bit ugly, but I don't see a good way on how to split this up.
> >>
> >> Some more adaptions due to the removal of the "custom" model.
> >>
> >> Things *not* changed from RFCv1:
> >>
> >> SYSREG_ property naming (can be tweaked easily, once we are clear on
> what
> >> the interface should look like.)
> >>
> >> Sysreg generation scripts, and the generated files (I have not updated
> >> anything there.) I think generating the various definitions makes sense,
> >> as long as we double-check the generated files on each update (which
> would
> >> be something to trigger manually anyway.)
> >>
> >> What I would like us to reach some kind of consensus on:
> >>
> >> How to continue with the patches moving the ID registers from the isar
> >> struct into the idregs array. These are a bit of churn to drag along;
> >> if they make sense, maybe they can be picked independently of this
> series?
> >>
> >> Whether it make sense to continue with the approach of tweaking
> values in
> >> the ID registers in general. If we want to be able to migrate between
> cpus
> >> that do not differ wildly, we'll encounter differences that cannot be
> >> expressed via FEAT_xxx -- e.g. when comparing various AmpereAltra Max
> systems,
> >> they only differ in parts of CTR_EL0 -- which is not a feature register, but
> >> a writable register.
> > In v1 most of the commenters said they would prefer to see FEAT props
> > instead of IDREG field props. I think we shall try to go in this
> > direction anyway. As you pointed out there will be some cases where
> FEAT
> > won't be enough (CTR_EL0 is a good example). So I tend to think the end
> > solution will be a mix of FEAT and ID reg field props.
> >
> > Personally I would smoothly migrate what we can from ID reg field props
> > to FEAT props (maybe using prop aliases?), starting from the easiest 1-1
> > mappings and then adressing the FEAT that are more complex but are
> > explictly needed to enable the use cases we are interested in, at RedHat:
> > migration within Ampere AltraMax family, migration within NVidia Grace
> > family, migration within AmpereOne family and migration between
> Graviton3/4.
> >
> > We have no info about other's use cases. If some of you want to see some
> > other live migration combinations addressed, please raise your voice.
> In relation to [1] you seem to be also interested in the migration
> between heterogeneous systems with qemu.
Yes. That is correct.
> Do you think targeting migration within a cpu family is enough for your
> use cases. How different are the source and destination host on your
> cases. Do you thing feat props are relevant in your case or would you
> need lower granularity at idreg field levelto pass the migration?
I think, from the current requirement we have for migration, the source and
destination mostly can be handled by FEAT_XXX. But like Ampere, we do need
to manage the CTR_EL0 differences[1].
Also we do have differences in GIC support as well(AA64PFR0_EL1.GIC) which
I am not sure how to manage with FEAT_XXX.
And we are checking with our Product team whether we need to support migration
from an old CPU type in which case we have to do a bit more analysis.
Thanks,
Shameer
1. https://lore.kernel.org/kvmarm/20241022073943.35764-1-shameerali.kolothum.thodi@huawei.com/
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-12 13:09 ` Shameerali Kolothum Thodi via
(?)
@ 2024-12-12 13:29 ` Eric Auger
-1 siblings, 0 replies; 56+ messages in thread
From: Eric Auger @ 2024-12-12 13:29 UTC (permalink / raw)
To: Shameerali Kolothum Thodi, eric.auger@redhat.com, Cornelia Huck,
eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, richard.henderson@linaro.org,
alex.bennee@linaro.org, maz@kernel.org, oliver.upton@linux.dev,
sebott@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Cc: shahuang@redhat.com, mark.rutland@arm.com, philmd@linaro.org,
pbonzini@redhat.com, Wangzhou (B), Linuxarm
Hi Shameer,
On 12/12/24 14:09, Shameerali Kolothum Thodi wrote:
> Hi Eric,
>
>> -----Original Message-----
>> From: Eric Auger <eauger@redhat.com>
>> Sent: Thursday, December 12, 2024 8:42 AM
>> To: eric.auger@redhat.com; Cornelia Huck <cohuck@redhat.com>;
>> eric.auger.pro@gmail.com; qemu-devel@nongnu.org; qemu-
>> arm@nongnu.org; kvmarm@lists.linux.dev; peter.maydell@linaro.org;
>> richard.henderson@linaro.org; alex.bennee@linaro.org; maz@kernel.org;
>> oliver.upton@linux.dev; sebott@redhat.com; Shameerali Kolothum Thodi
>> <shameerali.kolothum.thodi@huawei.com>; armbru@redhat.com;
>> berrange@redhat.com; abologna@redhat.com; jdenemar@redhat.com
>> Cc: shahuang@redhat.com; mark.rutland@arm.com; philmd@linaro.org;
>> pbonzini@redhat.com
>> Subject: Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable
>> aarch64 KVM host model
>>
>> Shameer,
>>
>> On 12/12/24 09:12, Eric Auger wrote:
>>> Connie,
>>>
>>> On 12/6/24 12:21, Cornelia Huck wrote:
>>>> A respin/update on the aarch64 KVM cpu models. Also available at
>>>> gitlab.com/cohuck/qemu arm-cpu-model-rfcv2
>>>>
>>>> Find Eric's original cover letter below, so that I do not need to
>>>> repeat myself on the aspects that have not changed since RFCv1 :)
>>>>
>>>> Changes from RFCv1:
>>>>
>>>> Rebased on more recent QEMU (some adaptions in the register
>> conversions
>>>> of the first few patches.)
>>>>
>>>> Based on feedback, I have removed the "custom" cpu model; instead, I
>>>> have added the new SYSREG_<REG>_<FIELD> properties to the "host"
>> model.
>>>> This works well if you want to tweak anything that does not correspond
>>>> to the existing properties for the host model; however, if you e.g.
>>>> wanted to tweak sve, you have two ways to do so -- we'd probably either
>>>> want to check for conflicts, or just declare precedence. The kvm-specific
>>>> props remain unchanged, as they are orthogonal to this configuration.
>>>>
>>>> The cpu model expansion for the "host" model now dumps the new
>> SYSREG_
>>>> properties in addition to the existing host model properties; this is a
>>>> bit ugly, but I don't see a good way on how to split this up.
>>>>
>>>> Some more adaptions due to the removal of the "custom" model.
>>>>
>>>> Things *not* changed from RFCv1:
>>>>
>>>> SYSREG_ property naming (can be tweaked easily, once we are clear on
>> what
>>>> the interface should look like.)
>>>>
>>>> Sysreg generation scripts, and the generated files (I have not updated
>>>> anything there.) I think generating the various definitions makes sense,
>>>> as long as we double-check the generated files on each update (which
>> would
>>>> be something to trigger manually anyway.)
>>>>
>>>> What I would like us to reach some kind of consensus on:
>>>>
>>>> How to continue with the patches moving the ID registers from the isar
>>>> struct into the idregs array. These are a bit of churn to drag along;
>>>> if they make sense, maybe they can be picked independently of this
>> series?
>>>>
>>>> Whether it make sense to continue with the approach of tweaking
>> values in
>>>> the ID registers in general. If we want to be able to migrate between
>> cpus
>>>> that do not differ wildly, we'll encounter differences that cannot be
>>>> expressed via FEAT_xxx -- e.g. when comparing various AmpereAltra Max
>> systems,
>>>> they only differ in parts of CTR_EL0 -- which is not a feature register, but
>>>> a writable register.
>>> In v1 most of the commenters said they would prefer to see FEAT props
>>> instead of IDREG field props. I think we shall try to go in this
>>> direction anyway. As you pointed out there will be some cases where
>> FEAT
>>> won't be enough (CTR_EL0 is a good example). So I tend to think the end
>>> solution will be a mix of FEAT and ID reg field props.
>>>
>>> Personally I would smoothly migrate what we can from ID reg field props
>>> to FEAT props (maybe using prop aliases?), starting from the easiest 1-1
>>> mappings and then adressing the FEAT that are more complex but are
>>> explictly needed to enable the use cases we are interested in, at RedHat:
>>> migration within Ampere AltraMax family, migration within NVidia Grace
>>> family, migration within AmpereOne family and migration between
>> Graviton3/4.
>>>
>>> We have no info about other's use cases. If some of you want to see some
>>> other live migration combinations addressed, please raise your voice.
>> In relation to [1] you seem to be also interested in the migration
>> between heterogeneous systems with qemu.
>
> Yes. That is correct.
>
>> Do you think targeting migration within a cpu family is enough for your
>> use cases. How different are the source and destination host on your
>> cases. Do you thing feat props are relevant in your case or would you
>> need lower granularity at idreg field levelto pass the migration?
>
> I think, from the current requirement we have for migration, the source and
> destination mostly can be handled by FEAT_XXX. But like Ampere, we do need
> to manage the CTR_EL0 differences[1].
OK
>
> Also we do have differences in GIC support as well(AA64PFR0_EL1.GIC) which
> I am not sure how to manage with FEAT_XXX.
interesting. We need to further look at this one.
>
> And we are checking with our Product team whether we need to support migration
> from an old CPU type in which case we have to do a bit more analysis.
Sure, please come back to us whenever you get more insights. It will
help us define the scope of this upstream work
Thanks!
Eric
>
> Thanks,
> Shameer
>
> 1. https://lore.kernel.org/kvmarm/20241022073943.35764-1-shameerali.kolothum.thodi@huawei.com/
>
>
>
>
>
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-12 8:12 ` Eric Auger
2024-12-12 8:42 ` Eric Auger
@ 2024-12-12 9:10 ` Daniel P. Berrangé
2024-12-12 9:36 ` Cornelia Huck
2024-12-16 16:42 ` Cornelia Huck
2 siblings, 1 reply; 56+ messages in thread
From: Daniel P. Berrangé @ 2024-12-12 9:10 UTC (permalink / raw)
To: Eric Auger
Cc: Cornelia Huck, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, abologna, jdenemar,
shahuang, mark.rutland, philmd, pbonzini
On Thu, Dec 12, 2024 at 09:12:33AM +0100, Eric Auger wrote:
> Connie,
>
> On 12/6/24 12:21, Cornelia Huck wrote:
> > A respin/update on the aarch64 KVM cpu models. Also available at
> > gitlab.com/cohuck/qemu arm-cpu-model-rfcv2
snip
> From a named model point of view, since I do not see much traction
> upstream besides Red Hat use cases, targetting ARM spec revision
> baselines may be overkill. Personally I would try to focus on above
> models: AltraMax, AmpereOne, Grace, ... Or maybe the ARM cores they may
> be derived from.
If we target modelling of vendor named CPU models, then beware that
we're opening the door to an very large set (potentially unbounded)
of named CPU models over time. If we target ARM spec baselines then
the set of named CPU models is fairly modest and grows slowly.
Including ARM spec baselines will probably reduce the demand for
adding vendor specific named models, though I expect we'll still
end up wanting some, or possibly even many.
Having some common baseline models is likely useful for mgmt
applications in other ways though.
Consider you mgmt app wants to set a CPU model that's common across
heterogeneous hardware. They don't neccessarily want/need to be
able to live migrate between heterogeneous CPUs, but for simplicity
of configuration desire to set a single named CPU across all guests,
irrespective of what host hey are launched on. The ARM spec baseline
named models would give you that config simplicity.
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-12 9:10 ` Daniel P. Berrangé
@ 2024-12-12 9:36 ` Cornelia Huck
2024-12-12 10:04 ` Eric Auger
0 siblings, 1 reply; 56+ messages in thread
From: Cornelia Huck @ 2024-12-12 9:36 UTC (permalink / raw)
To: Daniel P. Berrangé, Eric Auger
Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
richard.henderson, alex.bennee, maz, oliver.upton, sebott,
shameerali.kolothum.thodi, armbru, abologna, jdenemar, shahuang,
mark.rutland, philmd, pbonzini
On Thu, Dec 12 2024, Daniel P. Berrangé <berrange@redhat.com> wrote:
> On Thu, Dec 12, 2024 at 09:12:33AM +0100, Eric Auger wrote:
>> Connie,
>>
>> On 12/6/24 12:21, Cornelia Huck wrote:
>> > A respin/update on the aarch64 KVM cpu models. Also available at
>> > gitlab.com/cohuck/qemu arm-cpu-model-rfcv2
>
> snip
>
>> From a named model point of view, since I do not see much traction
>> upstream besides Red Hat use cases, targetting ARM spec revision
>> baselines may be overkill. Personally I would try to focus on above
>> models: AltraMax, AmpereOne, Grace, ... Or maybe the ARM cores they may
>> be derived from.
>
> If we target modelling of vendor named CPU models, then beware that
> we're opening the door to an very large set (potentially unbounded)
> of named CPU models over time. If we target ARM spec baselines then
> the set of named CPU models is fairly modest and grows slowly.
>
> Including ARM spec baselines will probably reduce the demand for
> adding vendor specific named models, though I expect we'll still
> end up wanting some, or possibly even many.
>
> Having some common baseline models is likely useful for mgmt
> applications in other ways though.
>
> Consider you mgmt app wants to set a CPU model that's common across
> heterogeneous hardware. They don't neccessarily want/need to be
> able to live migrate between heterogeneous CPUs, but for simplicity
> of configuration desire to set a single named CPU across all guests,
> irrespective of what host hey are launched on. The ARM spec baseline
> named models would give you that config simplicity.
If we use architecture extensions (i.e. Armv8.x/9.x) as baseline, I'm
seeing some drawbacks:
- a lot of work before we can address some specific use cases
- old models can get new optional features
- a specific cpu might have a huge set of optional features on top of
the baseline model
Using a reference core such as Neoverse-V2 probably makes more sense
(easier to get started, less feature diff?) It would still make a good
starting point for a simple config.
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-12 9:36 ` Cornelia Huck
@ 2024-12-12 10:04 ` Eric Auger
2024-12-12 14:46 ` Cornelia Huck
2024-12-19 11:35 ` Kashyap Chamarthy
0 siblings, 2 replies; 56+ messages in thread
From: Eric Auger @ 2024-12-12 10:04 UTC (permalink / raw)
To: Cornelia Huck, Daniel P. Berrangé
Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
richard.henderson, alex.bennee, maz, oliver.upton, sebott,
shameerali.kolothum.thodi, armbru, abologna, jdenemar, shahuang,
mark.rutland, philmd, pbonzini
On 12/12/24 10:36, Cornelia Huck wrote:
> On Thu, Dec 12 2024, Daniel P. Berrangé <berrange@redhat.com> wrote:
>
>> On Thu, Dec 12, 2024 at 09:12:33AM +0100, Eric Auger wrote:
>>> Connie,
>>>
>>> On 12/6/24 12:21, Cornelia Huck wrote:
>>>> A respin/update on the aarch64 KVM cpu models. Also available at
>>>> gitlab.com/cohuck/qemu arm-cpu-model-rfcv2
>> snip
>>
>>> From a named model point of view, since I do not see much traction
>>> upstream besides Red Hat use cases, targetting ARM spec revision
>>> baselines may be overkill. Personally I would try to focus on above
>>> models: AltraMax, AmpereOne, Grace, ... Or maybe the ARM cores they may
>>> be derived from.
>> If we target modelling of vendor named CPU models, then beware that
>> we're opening the door to an very large set (potentially unbounded)
>> of named CPU models over time. If we target ARM spec baselines then
>> the set of named CPU models is fairly modest and grows slowly.
>>
>> Including ARM spec baselines will probably reduce the demand for
>> adding vendor specific named models, though I expect we'll still
>> end up wanting some, or possibly even many.
>>
>> Having some common baseline models is likely useful for mgmt
>> applications in other ways though.
>>
>> Consider you mgmt app wants to set a CPU model that's common across
>> heterogeneous hardware. They don't neccessarily want/need to be
>> able to live migrate between heterogeneous CPUs, but for simplicity
>> of configuration desire to set a single named CPU across all guests,
>> irrespective of what host hey are launched on. The ARM spec baseline
>> named models would give you that config simplicity.
> If we use architecture extensions (i.e. Armv8.x/9.x) as baseline, I'm
> seeing some drawbacks:
> - a lot of work before we can address some specific use cases
> - old models can get new optional features
> - a specific cpu might have a huge set of optional features on top of
> the baseline model
>
> Using a reference core such as Neoverse-V2 probably makes more sense
> (easier to get started, less feature diff?) It would still make a good
> starting point for a simple config.
>
Actually from a dev point of view I am not sure it changes much to have
either ARM spec rev baseline or CPU ref core named model.
One remark is that if you look at
https://developer.arm.com/documentation/109697/2024_09?lang=en
you will see there are quite a lot of spec revisions and quite a few of
them are actually meaningful in the light of currently avaiable and
relevant HW we want to address. What I would like to avoid is to be
obliged to look at all of them in a generic manner while we just want to
address few cpu ref models.
Also starting from the ARM spec rev baseline the end-user may need to
add more feature opt-ins to be close to a specific cpu model. So I
foresee extra complexity for the end-user.
But again I from a dev pov it shouldn't change much and we should end up
with a proto that illustrates the working model
Eric
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-12 10:04 ` Eric Auger
@ 2024-12-12 14:46 ` Cornelia Huck
2024-12-19 11:35 ` Kashyap Chamarthy
1 sibling, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-12 14:46 UTC (permalink / raw)
To: eric.auger, Daniel P. Berrangé
Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
richard.henderson, alex.bennee, maz, oliver.upton, sebott,
shameerali.kolothum.thodi, armbru, abologna, jdenemar, shahuang,
mark.rutland, philmd, pbonzini
On Thu, Dec 12 2024, Eric Auger <eric.auger@redhat.com> wrote:
> On 12/12/24 10:36, Cornelia Huck wrote:
>> On Thu, Dec 12 2024, Daniel P. Berrangé <berrange@redhat.com> wrote:
>>
>>> On Thu, Dec 12, 2024 at 09:12:33AM +0100, Eric Auger wrote:
>>>> Connie,
>>>>
>>>> On 12/6/24 12:21, Cornelia Huck wrote:
>>>>> A respin/update on the aarch64 KVM cpu models. Also available at
>>>>> gitlab.com/cohuck/qemu arm-cpu-model-rfcv2
>>> snip
>>>
>>>> From a named model point of view, since I do not see much traction
>>>> upstream besides Red Hat use cases, targetting ARM spec revision
>>>> baselines may be overkill. Personally I would try to focus on above
>>>> models: AltraMax, AmpereOne, Grace, ... Or maybe the ARM cores they may
>>>> be derived from.
>>> If we target modelling of vendor named CPU models, then beware that
>>> we're opening the door to an very large set (potentially unbounded)
>>> of named CPU models over time. If we target ARM spec baselines then
>>> the set of named CPU models is fairly modest and grows slowly.
>>>
>>> Including ARM spec baselines will probably reduce the demand for
>>> adding vendor specific named models, though I expect we'll still
>>> end up wanting some, or possibly even many.
>>>
>>> Having some common baseline models is likely useful for mgmt
>>> applications in other ways though.
>>>
>>> Consider you mgmt app wants to set a CPU model that's common across
>>> heterogeneous hardware. They don't neccessarily want/need to be
>>> able to live migrate between heterogeneous CPUs, but for simplicity
>>> of configuration desire to set a single named CPU across all guests,
>>> irrespective of what host hey are launched on. The ARM spec baseline
>>> named models would give you that config simplicity.
>> If we use architecture extensions (i.e. Armv8.x/9.x) as baseline, I'm
>> seeing some drawbacks:
>> - a lot of work before we can address some specific use cases
>> - old models can get new optional features
>> - a specific cpu might have a huge set of optional features on top of
>> the baseline model
>>
>> Using a reference core such as Neoverse-V2 probably makes more sense
>> (easier to get started, less feature diff?) It would still make a good
>> starting point for a simple config.
>>
> Actually from a dev point of view I am not sure it changes much to have
> either ARM spec rev baseline or CPU ref core named model.
>
> One remark is that if you look at
> https://developer.arm.com/documentation/109697/2024_09?lang=en
> you will see there are quite a lot of spec revisions and quite a few of
> them are actually meaningful in the light of currently avaiable and
> relevant HW we want to address. What I would like to avoid is to be
> obliged to look at all of them in a generic manner while we just want to
> address few cpu ref models.
Yes, exactly.
>
> Also starting from the ARM spec rev baseline the end-user may need to
> add more feature opt-ins to be close to a specific cpu model. So I
> foresee extra complexity for the end-user.
For ref cores, it's easier to pick the ones that actually matter for a
specific use case, for arch exts I don't think we can avoid implementing
those we don't really care about. And yes, from the sample of cpus I've
looked at they seem to be much closer to a ref core than to an arch ext.
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-12 10:04 ` Eric Auger
2024-12-12 14:46 ` Cornelia Huck
@ 2024-12-19 11:35 ` Kashyap Chamarthy
2024-12-19 12:26 ` Marc Zyngier
1 sibling, 1 reply; 56+ messages in thread
From: Kashyap Chamarthy @ 2024-12-19 11:35 UTC (permalink / raw)
To: Eric Auger
Cc: Cornelia Huck, Daniel P. Berrangé, eric.auger.pro,
qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson,
alex.bennee, maz, oliver.upton, sebott, shameerali.kolothum.thodi,
armbru, abologna, jdenemar, shahuang, mark.rutland, philmd,
pbonzini
On Thu, Dec 12, 2024 at 11:04:30AM +0100, Eric Auger wrote:
Hi Eric,
> On 12/12/24 10:36, Cornelia Huck wrote:
> > On Thu, Dec 12 2024, Daniel P. Berrangé <berrange@redhat.com> wrote:
[...]
> >> Consider you mgmt app wants to set a CPU model that's common across
> >> heterogeneous hardware. They don't neccessarily want/need to be
> >> able to live migrate between heterogeneous CPUs, but for simplicity
> >> of configuration desire to set a single named CPU across all guests,
> >> irrespective of what host hey are launched on. The ARM spec baseline
> >> named models would give you that config simplicity.
> > If we use architecture extensions (i.e. Armv8.x/9.x) as baseline, I'm
> > seeing some drawbacks:
> > - a lot of work before we can address some specific use cases
> > - old models can get new optional features
> > - a specific cpu might have a huge set of optional features on top of
> > the baseline model
> >
> > Using a reference core such as Neoverse-V2 probably makes more sense
> > (easier to get started, less feature diff?) It would still make a good
> > starting point for a simple config.
> >
> Actually from a dev point of view I am not sure it changes much to have
> either ARM spec rev baseline or CPU ref core named model.
>
> One remark is that if you look at
> https://developer.arm.com/documentation/109697/2024_09?lang=en
> you will see there are quite a lot of spec revisions and quite a few of
> them are actually meaningful in the light of currently avaiable and
> relevant HW we want to address. What I would like to avoid is to be
> obliged to look at all of them in a generic manner while we just want to
> address few cpu ref models.
>
> Also starting from the ARM spec rev baseline the end-user may need to
> add more feature opt-ins to be close to a specific cpu model. So I
> foresee extra complexity for the end-user.
(Assuming I'm parsing your last para right; correct me if not.)
Isn't a user wanting to add extra CPU flags (on top of a baseline) a
"normal behaviour" and not "extra complexity"? Besides coming close to
a specific CPU model, there's the additional important use-case of CPU
flags that provide security mitigation.
Consider this:
Say, there's a serious security issue in a released ARM CPU. As part of
the fix, two new CPU flags need to be exposed to the guest OS, call them
"secflag1" and "secflag2". Here, the user is configuring a baseline
model + two extra CPU flags, not to get close to some other CPU model
but to mitigate itself against a serious security flaw.
An example that comes to mind is the infamous "speculative store bypass"
(SSB) vulnerability and how QEMU addressed it[1][2] in x86. I'm sure,
as you know, it also affects ARM[3].
[1] https://lists.gnu.org/archive/html/qemu-devel/2018-05/msg04796.html
— i386: define the 'ssbd' CPUID feature bit (CVE-2018-3639)
[2] https://lists.gnu.org/archive/html/qemu-devel/2018-05/msg04797.html
— i386: Define the Virt SSBD MSR and handling of it (CVE-2018-3639)
[3] https://developer.arm.com/documentation/ddi0601/2024-06/AArch64-Registers/SSBS--Speculative-Store-Bypass-Safe
--
/kashyap
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-19 11:35 ` Kashyap Chamarthy
@ 2024-12-19 12:26 ` Marc Zyngier
2024-12-19 12:38 ` Daniel P. Berrangé
2024-12-19 15:07 ` Kashyap Chamarthy
0 siblings, 2 replies; 56+ messages in thread
From: Marc Zyngier @ 2024-12-19 12:26 UTC (permalink / raw)
To: Kashyap Chamarthy
Cc: Eric Auger, Cornelia Huck, Daniel "P. Berrangé",
eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
richard.henderson, alex.bennee, oliver.upton, sebott,
shameerali.kolothum.thodi, armbru, abologna, jdenemar, shahuang,
mark.rutland, philmd, pbonzini
On Thu, 19 Dec 2024 11:35:16 +0000,
Kashyap Chamarthy <kchamart@redhat.com> wrote:
>
> On Thu, Dec 12, 2024 at 11:04:30AM +0100, Eric Auger wrote:
>
> Hi Eric,
>
> > On 12/12/24 10:36, Cornelia Huck wrote:
> > > On Thu, Dec 12 2024, Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> [...]
>
> > >> Consider you mgmt app wants to set a CPU model that's common across
> > >> heterogeneous hardware. They don't neccessarily want/need to be
> > >> able to live migrate between heterogeneous CPUs, but for simplicity
> > >> of configuration desire to set a single named CPU across all guests,
> > >> irrespective of what host hey are launched on. The ARM spec baseline
> > >> named models would give you that config simplicity.
> > > If we use architecture extensions (i.e. Armv8.x/9.x) as baseline, I'm
> > > seeing some drawbacks:
> > > - a lot of work before we can address some specific use cases
> > > - old models can get new optional features
> > > - a specific cpu might have a huge set of optional features on top of
> > > the baseline model
> > >
> > > Using a reference core such as Neoverse-V2 probably makes more sense
> > > (easier to get started, less feature diff?) It would still make a good
> > > starting point for a simple config.
> > >
> > Actually from a dev point of view I am not sure it changes much to have
> > either ARM spec rev baseline or CPU ref core named model.
> >
> > One remark is that if you look at
> > https://developer.arm.com/documentation/109697/2024_09?lang=en
> > you will see there are quite a lot of spec revisions and quite a few of
> > them are actually meaningful in the light of currently avaiable and
> > relevant HW we want to address. What I would like to avoid is to be
> > obliged to look at all of them in a generic manner while we just want to
> > address few cpu ref models.
> >
> > Also starting from the ARM spec rev baseline the end-user may need to
> > add more feature opt-ins to be close to a specific cpu model. So I
> > foresee extra complexity for the end-user.
>
> (Assuming I'm parsing your last para right; correct me if not.)
>
> Isn't a user wanting to add extra CPU flags (on top of a baseline) a
> "normal behaviour" and not "extra complexity"? Besides coming close to
> a specific CPU model, there's the additional important use-case of CPU
> flags that provide security mitigation.
>
> Consider this:
>
> Say, there's a serious security issue in a released ARM CPU. As part of
> the fix, two new CPU flags need to be exposed to the guest OS, call them
> "secflag1" and "secflag2". Here, the user is configuring a baseline
> model + two extra CPU flags, not to get close to some other CPU model
> but to mitigate itself against a serious security flaw.
If there's such a security issue, that the hypervisor's job to do so,
not userspace. See what KVM does for CSV3, for example (and all the
rest of the side-channel stuff).
You can't rely on userspace for security, that'd be completely
ludicrous.
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-19 12:26 ` Marc Zyngier
@ 2024-12-19 12:38 ` Daniel P. Berrangé
2024-12-19 13:01 ` Marc Zyngier
2024-12-19 15:07 ` Kashyap Chamarthy
1 sibling, 1 reply; 56+ messages in thread
From: Daniel P. Berrangé @ 2024-12-19 12:38 UTC (permalink / raw)
To: Marc Zyngier
Cc: Kashyap Chamarthy, Eric Auger, Cornelia Huck, eric.auger.pro,
qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson,
alex.bennee, oliver.upton, sebott, shameerali.kolothum.thodi,
armbru, abologna, jdenemar, shahuang, mark.rutland, philmd,
pbonzini
On Thu, Dec 19, 2024 at 12:26:29PM +0000, Marc Zyngier wrote:
> On Thu, 19 Dec 2024 11:35:16 +0000,
> Kashyap Chamarthy <kchamart@redhat.com> wrote:
> >
> > On Thu, Dec 12, 2024 at 11:04:30AM +0100, Eric Auger wrote:
> >
> > Hi Eric,
> >
> > > On 12/12/24 10:36, Cornelia Huck wrote:
> > > > On Thu, Dec 12 2024, Daniel P. Berrangé <berrange@redhat.com> wrote:
> >
> > [...]
> >
> > > >> Consider you mgmt app wants to set a CPU model that's common across
> > > >> heterogeneous hardware. They don't neccessarily want/need to be
> > > >> able to live migrate between heterogeneous CPUs, but for simplicity
> > > >> of configuration desire to set a single named CPU across all guests,
> > > >> irrespective of what host hey are launched on. The ARM spec baseline
> > > >> named models would give you that config simplicity.
> > > > If we use architecture extensions (i.e. Armv8.x/9.x) as baseline, I'm
> > > > seeing some drawbacks:
> > > > - a lot of work before we can address some specific use cases
> > > > - old models can get new optional features
> > > > - a specific cpu might have a huge set of optional features on top of
> > > > the baseline model
> > > >
> > > > Using a reference core such as Neoverse-V2 probably makes more sense
> > > > (easier to get started, less feature diff?) It would still make a good
> > > > starting point for a simple config.
> > > >
> > > Actually from a dev point of view I am not sure it changes much to have
> > > either ARM spec rev baseline or CPU ref core named model.
> > >
> > > One remark is that if you look at
> > > https://developer.arm.com/documentation/109697/2024_09?lang=en
> > > you will see there are quite a lot of spec revisions and quite a few of
> > > them are actually meaningful in the light of currently avaiable and
> > > relevant HW we want to address. What I would like to avoid is to be
> > > obliged to look at all of them in a generic manner while we just want to
> > > address few cpu ref models.
> > >
> > > Also starting from the ARM spec rev baseline the end-user may need to
> > > add more feature opt-ins to be close to a specific cpu model. So I
> > > foresee extra complexity for the end-user.
> >
> > (Assuming I'm parsing your last para right; correct me if not.)
> >
> > Isn't a user wanting to add extra CPU flags (on top of a baseline) a
> > "normal behaviour" and not "extra complexity"? Besides coming close to
> > a specific CPU model, there's the additional important use-case of CPU
> > flags that provide security mitigation.
> >
> > Consider this:
> >
> > Say, there's a serious security issue in a released ARM CPU. As part of
> > the fix, two new CPU flags need to be exposed to the guest OS, call them
> > "secflag1" and "secflag2". Here, the user is configuring a baseline
> > model + two extra CPU flags, not to get close to some other CPU model
> > but to mitigate itself against a serious security flaw.
>
> If there's such a security issue, that the hypervisor's job to do so,
> not userspace. See what KVM does for CSV3, for example (and all the
> rest of the side-channel stuff).
>
> You can't rely on userspace for security, that'd be completely
> ludicrous.
Actually that's a normal situation QEMU has to deal with.
QEMU needs to be able to expose a deterministic fixed ABI to the guest
VM, and that includes control over what CPU features are exposed to
it. In most cases, the hypervisor cannot arbitrary force enable new
guest features without agreement from QEMU.
If a guest happens to be using '-cpu host', then when a new CPU flag
arrives as part of a security fix, there is at least no CPU config
change required. QEMU may or may not need changes, in order that
the behaviour associated with the new CPU flag is correctly handled.
If the guest is using a named CPU model, as well as modifying QEMU
to know about the new flag, the host admin needs to explicitly
decide whether & when to expose the new CPU flag for each guest VM
on the host.
Until the new CPU flag is exposed to the guest, while the host itself
may be able to remain protected to the new security issue, the guest
OS is likely remain vulnerable, or have degraded operation in some way.
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-19 12:38 ` Daniel P. Berrangé
@ 2024-12-19 13:01 ` Marc Zyngier
0 siblings, 0 replies; 56+ messages in thread
From: Marc Zyngier @ 2024-12-19 13:01 UTC (permalink / raw)
To: Daniel "P. Berrangé"
Cc: Kashyap Chamarthy, Eric Auger, Cornelia Huck, eric.auger.pro,
qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson,
alex.bennee, oliver.upton, sebott, shameerali.kolothum.thodi,
armbru, abologna, jdenemar, shahuang, mark.rutland, philmd,
pbonzini
On Thu, 19 Dec 2024 12:38:50 +0000,
Daniel "P. Berrangé" <berrange@redhat.com> wrote:
>
> On Thu, Dec 19, 2024 at 12:26:29PM +0000, Marc Zyngier wrote:
> > On Thu, 19 Dec 2024 11:35:16 +0000,
> > Kashyap Chamarthy <kchamart@redhat.com> wrote:
> > >
> > > On Thu, Dec 12, 2024 at 11:04:30AM +0100, Eric Auger wrote:
> > >
> > > Hi Eric,
> > >
> > > > On 12/12/24 10:36, Cornelia Huck wrote:
> > > > > On Thu, Dec 12 2024, Daniel P. Berrangé <berrange@redhat.com> wrote:
> > >
> > > [...]
> > >
> > > > >> Consider you mgmt app wants to set a CPU model that's common across
> > > > >> heterogeneous hardware. They don't neccessarily want/need to be
> > > > >> able to live migrate between heterogeneous CPUs, but for simplicity
> > > > >> of configuration desire to set a single named CPU across all guests,
> > > > >> irrespective of what host hey are launched on. The ARM spec baseline
> > > > >> named models would give you that config simplicity.
> > > > > If we use architecture extensions (i.e. Armv8.x/9.x) as baseline, I'm
> > > > > seeing some drawbacks:
> > > > > - a lot of work before we can address some specific use cases
> > > > > - old models can get new optional features
> > > > > - a specific cpu might have a huge set of optional features on top of
> > > > > the baseline model
> > > > >
> > > > > Using a reference core such as Neoverse-V2 probably makes more sense
> > > > > (easier to get started, less feature diff?) It would still make a good
> > > > > starting point for a simple config.
> > > > >
> > > > Actually from a dev point of view I am not sure it changes much to have
> > > > either ARM spec rev baseline or CPU ref core named model.
> > > >
> > > > One remark is that if you look at
> > > > https://developer.arm.com/documentation/109697/2024_09?lang=en
> > > > you will see there are quite a lot of spec revisions and quite a few of
> > > > them are actually meaningful in the light of currently avaiable and
> > > > relevant HW we want to address. What I would like to avoid is to be
> > > > obliged to look at all of them in a generic manner while we just want to
> > > > address few cpu ref models.
> > > >
> > > > Also starting from the ARM spec rev baseline the end-user may need to
> > > > add more feature opt-ins to be close to a specific cpu model. So I
> > > > foresee extra complexity for the end-user.
> > >
> > > (Assuming I'm parsing your last para right; correct me if not.)
> > >
> > > Isn't a user wanting to add extra CPU flags (on top of a baseline) a
> > > "normal behaviour" and not "extra complexity"? Besides coming close to
> > > a specific CPU model, there's the additional important use-case of CPU
> > > flags that provide security mitigation.
> > >
> > > Consider this:
> > >
> > > Say, there's a serious security issue in a released ARM CPU. As part of
> > > the fix, two new CPU flags need to be exposed to the guest OS, call them
> > > "secflag1" and "secflag2". Here, the user is configuring a baseline
> > > model + two extra CPU flags, not to get close to some other CPU model
> > > but to mitigate itself against a serious security flaw.
> >
> > If there's such a security issue, that the hypervisor's job to do so,
> > not userspace. See what KVM does for CSV3, for example (and all the
> > rest of the side-channel stuff).
> >
> > You can't rely on userspace for security, that'd be completely
> > ludicrous.
>
> Actually that's a normal situation QEMU has to deal with.
>
> QEMU needs to be able to expose a deterministic fixed ABI to the guest
> VM, and that includes control over what CPU features are exposed to
> it. In most cases, the hypervisor cannot arbitrary force enable new
> guest features without agreement from QEMU.
Which ABI? The only ABI that matters is what is defined by the
architecture. When it comes to CPU features, new features are exposed
by default. If QEMU wants to turn it off, it can in most (but not all)
cases. But that's the extent of the "agreement" we have with
userspace, QEMU or otherwise.
If a feature is deemed broken or unsafe, KVM will turn it at least
hide it from the guest without userspace's intervention, and if
possible actively turn it off.
> If a guest happens to be using '-cpu host', then when a new CPU flag
> arrives as part of a security fix, there is at least no CPU config
> change required. QEMU may or may not need changes, in order that
> the behaviour associated with the new CPU flag is correctly handled.
How is that "flag" visible from the guest? The only way to expose
properties is through the ID registers, and you can't invent your own,
nor expose something that is not already handled by the host.
> If the guest is using a named CPU model, as well as modifying QEMU
> to know about the new flag, the host admin needs to explicitly
> decide whether & when to expose the new CPU flag for each guest VM
> on the host.
>
> Until the new CPU flag is exposed to the guest, while the host itself
> may be able to remain protected to the new security issue, the guest
> OS is likely remain vulnerable, or have degraded operation in some way.
I think that's the point where we talk past each other. There is no
"flag" that can be exposed to a guest as part of the architecture. We
have a set of architectural features, and in 99% of the cases, we can
only expose to the guest a feature that both exists on the host and
that the hypervisor understands.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-19 12:26 ` Marc Zyngier
2024-12-19 12:38 ` Daniel P. Berrangé
@ 2024-12-19 15:07 ` Kashyap Chamarthy
2024-12-19 15:41 ` Marc Zyngier
1 sibling, 1 reply; 56+ messages in thread
From: Kashyap Chamarthy @ 2024-12-19 15:07 UTC (permalink / raw)
To: Marc Zyngier
Cc: Eric Auger, Cornelia Huck, Daniel "P. Berrangé",
eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
richard.henderson, alex.bennee, oliver.upton, sebott,
shameerali.kolothum.thodi, armbru, abologna, jdenemar, shahuang,
mark.rutland, philmd, pbonzini
On Thu, Dec 19, 2024 at 12:26:29PM +0000, Marc Zyngier wrote:
> On Thu, 19 Dec 2024 11:35:16 +0000,
> Kashyap Chamarthy <kchamart@redhat.com> wrote:
[...]
> > Consider this:
> >
> > Say, there's a serious security issue in a released ARM CPU. As part of
> > the fix, two new CPU flags need to be exposed to the guest OS, call them
> > "secflag1" and "secflag2". Here, the user is configuring a baseline
> > model + two extra CPU flags, not to get close to some other CPU model
> > but to mitigate itself against a serious security flaw.
>
> If there's such a security issue, that the hypervisor's job to do so,
> not userspace.
I don't disagree. Probably that has always been the case on ARM. I
asked the above based on how QEMU on x86 handles it today.
> See what KVM does for CSV3, for example (and all the
> rest of the side-channel stuff).
Noted. From a quick look in the kernel tree, I assume you're referring
to these commits[1].
> You can't rely on userspace for security, that'd be completely
> ludicrous.
As Dan Berrangé points out, it's the bog-standard way QEMU deals with
some of the CPU-related issues on x86 today. See this "important CPU
flags"[2] section in the QEMU docs.
Mind you, I'm _not_ saying this is how ARM should do it. I don't know
enough about ARM to make such remarks.
* * *
To reply to your other question on this thread[3] about "which ABI?" I
think Dan is talking about the *guest* ABI: the virtual "chipset" that
is exposed to a guest (e.g. PCI(e) topology, ACPI tables, CPU model,
etc). As I understand it, this "guest ABI" should remain predictable,
regardless of:
- whether you're updating KVM, QEMU, or the underlying physical
hardware itself; or
- if the guest is migrated, live or offline
(As you might know, QEMU's "machine types" concept allows to create a
stable guest ABI.)
[1] "CVE3"-related commits:
- 471470bc7052 (arm64: errata: Add Cortex-A520 speculative
unprivileged load workaround, 2023-09-21)
- 4f1df628d4ec (KVM: arm64: Advertise ID_AA64PFR0_EL1.CSV3=1 if the
CPUs are Meltdown-safe, 2020-11-26)
[2] https://www.qemu.org/docs/master/system/i386/cpu.html#important-cpu-features-for-intel-x86-hosts
- "Important CPU features for Intel x86 hosts"
[3] https://lists.nongnu.org/archive/html/qemu-arm/2024-12/msg01224.html
--
/kashyap
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-19 15:07 ` Kashyap Chamarthy
@ 2024-12-19 15:41 ` Marc Zyngier
2024-12-19 17:51 ` Daniel P. Berrangé
2024-12-20 11:52 ` Kashyap Chamarthy
0 siblings, 2 replies; 56+ messages in thread
From: Marc Zyngier @ 2024-12-19 15:41 UTC (permalink / raw)
To: Kashyap Chamarthy
Cc: Eric Auger, Cornelia Huck, Daniel "P. Berrangé",
eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
richard.henderson, alex.bennee, oliver.upton, sebott,
shameerali.kolothum.thodi, armbru, abologna, jdenemar, shahuang,
mark.rutland, philmd, pbonzini
On Thu, 19 Dec 2024 15:07:25 +0000,
Kashyap Chamarthy <kchamart@redhat.com> wrote:
>
> On Thu, Dec 19, 2024 at 12:26:29PM +0000, Marc Zyngier wrote:
> > On Thu, 19 Dec 2024 11:35:16 +0000,
> > Kashyap Chamarthy <kchamart@redhat.com> wrote:
>
> [...]
>
> > > Consider this:
> > >
> > > Say, there's a serious security issue in a released ARM CPU. As part of
> > > the fix, two new CPU flags need to be exposed to the guest OS, call them
> > > "secflag1" and "secflag2". Here, the user is configuring a baseline
> > > model + two extra CPU flags, not to get close to some other CPU model
> > > but to mitigate itself against a serious security flaw.
> >
> > If there's such a security issue, that the hypervisor's job to do so,
> > not userspace.
>
> I don't disagree. Probably that has always been the case on ARM. I
> asked the above based on how QEMU on x86 handles it today.
>
> > See what KVM does for CSV3, for example (and all the
> > rest of the side-channel stuff).
>
> Noted. From a quick look in the kernel tree, I assume you're referring
> to these commits[1].
>
> > You can't rely on userspace for security, that'd be completely
> > ludicrous.
>
> As Dan Berrangé points out, it's the bog-standard way QEMU deals with
> some of the CPU-related issues on x86 today. See this "important CPU
> flags"[2] section in the QEMU docs.
I had a look, and we do things quite differently. For example, the
spec-ctrl equivalent in implemented in FW and in KVM, and is exposed
by default if the HW is vulnerable. Userspace could hide that the
mitigation is there, but that's the extent of the configurability.
>
> Mind you, I'm _not_ saying this is how ARM should do it. I don't know
> enough about ARM to make such remarks.
>
> * * *
>
> To reply to your other question on this thread[3] about "which ABI?" I
> think Dan is talking about the *guest* ABI: the virtual "chipset" that
> is exposed to a guest (e.g. PCI(e) topology, ACPI tables, CPU model,
> etc). As I understand it, this "guest ABI" should remain predictable,
> regardless of:
>
> - whether you're updating KVM, QEMU, or the underlying physical
> hardware itself; or
> - if the guest is migrated, live or offline
>
> (As you might know, QEMU's "machine types" concept allows to create a
> stable guest ABI.)
All of this is under control of QEMU, *except* for the "maximum" of
the architectural features exposed to the guest. All you can do is
*downgrade* from there, and only to a limited extent.
That, in turn has a direct impact on what you call the "CPU model",
which for the ARM architecture really doesn't exist. All we have is a
bag of discrete features, with intricate dependencies between them.
Even ignoring virtualisation: you can readily find two machines using
the same CPUs (let's say Neoverse-N1), integrated by the same vendor
(let's say, Ampere), in SoCs that bear the same name (Altra), and
realise that they have a different feature set. Fun, isn't it?
That's why I don't see CPU models as a viable thing in terms of ABI.
They are an approximation of what you could have, but the ABI is
elsewhere.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-19 15:41 ` Marc Zyngier
@ 2024-12-19 17:51 ` Daniel P. Berrangé
2024-12-20 16:04 ` Cornelia Huck
2024-12-21 13:02 ` Marc Zyngier
2024-12-20 11:52 ` Kashyap Chamarthy
1 sibling, 2 replies; 56+ messages in thread
From: Daniel P. Berrangé @ 2024-12-19 17:51 UTC (permalink / raw)
To: Marc Zyngier
Cc: Kashyap Chamarthy, Eric Auger, Cornelia Huck, eric.auger.pro,
qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson,
alex.bennee, oliver.upton, sebott, shameerali.kolothum.thodi,
armbru, abologna, jdenemar, shahuang, mark.rutland, philmd,
pbonzini
On Thu, Dec 19, 2024 at 03:41:56PM +0000, Marc Zyngier wrote:
> On Thu, 19 Dec 2024 15:07:25 +0000,
> Kashyap Chamarthy <kchamart@redhat.com> wrote:
> >
> > On Thu, Dec 19, 2024 at 12:26:29PM +0000, Marc Zyngier wrote:
> > > On Thu, 19 Dec 2024 11:35:16 +0000,
> > > Kashyap Chamarthy <kchamart@redhat.com> wrote:
> >
> > [...]
> >
> > > > Consider this:
> > > >
> > > > Say, there's a serious security issue in a released ARM CPU. As part of
> > > > the fix, two new CPU flags need to be exposed to the guest OS, call them
> > > > "secflag1" and "secflag2". Here, the user is configuring a baseline
> > > > model + two extra CPU flags, not to get close to some other CPU model
> > > > but to mitigate itself against a serious security flaw.
> > >
> > > If there's such a security issue, that the hypervisor's job to do so,
> > > not userspace.
> >
> > I don't disagree. Probably that has always been the case on ARM. I
> > asked the above based on how QEMU on x86 handles it today.
> >
> > > See what KVM does for CSV3, for example (and all the
> > > rest of the side-channel stuff).
> >
> > Noted. From a quick look in the kernel tree, I assume you're referring
> > to these commits[1].
> >
> > > You can't rely on userspace for security, that'd be completely
> > > ludicrous.
> >
> > As Dan Berrangé points out, it's the bog-standard way QEMU deals with
> > some of the CPU-related issues on x86 today. See this "important CPU
> > flags"[2] section in the QEMU docs.
>
> I had a look, and we do things quite differently. For example, the
> spec-ctrl equivalent in implemented in FW and in KVM, and is exposed
> by default if the HW is vulnerable. Userspace could hide that the
> mitigation is there, but that's the extent of the configurability.
Whether it is enabled by default or disabled by default isn't a
totally fatal problem. If QEMU can toggle it to the opposite value,
we have the same level of configurability in both cases.
It does, however, have implications for QEMU as if KVM gained support
for exposing the new feature by default and QEMU didn't know about
it, then the guest ABI would have changed without QEMU realizing it.
IOW, it would imply a requirement for timely QEMU updates to match
the kernel, which is something we wouldn't need in x86 world where
the feature is disabled by default. Disable by default is a more
stable approach from QEMU's POV.
> > Mind you, I'm _not_ saying this is how ARM should do it. I don't know
> > enough about ARM to make such remarks.
> >
> > * * *
> >
> > To reply to your other question on this thread[3] about "which ABI?" I
> > think Dan is talking about the *guest* ABI: the virtual "chipset" that
> > is exposed to a guest (e.g. PCI(e) topology, ACPI tables, CPU model,
> > etc). As I understand it, this "guest ABI" should remain predictable,
> > regardless of:
> >
> > - whether you're updating KVM, QEMU, or the underlying physical
> > hardware itself; or
> > - if the guest is migrated, live or offline
> >
> > (As you might know, QEMU's "machine types" concept allows to create a
> > stable guest ABI.)
>
> All of this is under control of QEMU, *except* for the "maximum" of
> the architectural features exposed to the guest. All you can do is
> *downgrade* from there, and only to a limited extent.
>
> That, in turn has a direct impact on what you call the "CPU model",
> which for the ARM architecture really doesn't exist. All we have is a
> bag of discrete features, with intricate dependencies between them.
>
> Even ignoring virtualisation: you can readily find two machines using
> the same CPUs (let's say Neoverse-N1), integrated by the same vendor
> (let's say, Ampere), in SoCs that bear the same name (Altra), and
> realise that they have a different feature set. Fun, isn't it?
"Fun" is probably not the word I'd pick :-)
> That's why I don't see CPU models as a viable thing in terms of ABI.
> They are an approximation of what you could have, but the ABI is
> elsewhere.
Right, this makes life quite challenging for QEMU. The premise of named
CPU models (as opposed to -host), is to facilitate the migration of VMs
between heterogenous hardware platforms. That assumes it is possible to
downgrade the CPU on both src + dst, to the common baseline you desire.
If we were to define a named CPU model, for that to be usable, QEMU
would have to be able to query the "maxmimum" architectural features,
and validate that the delta between the host maximum, and the named
CPU model is possible to downgrade. Is arm providing sufficient info
to let QEMU do that ?
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-19 17:51 ` Daniel P. Berrangé
@ 2024-12-20 16:04 ` Cornelia Huck
2024-12-21 13:02 ` Marc Zyngier
1 sibling, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-20 16:04 UTC (permalink / raw)
To: Daniel P. Berrangé, Marc Zyngier
Cc: Kashyap Chamarthy, Eric Auger, eric.auger.pro, qemu-devel,
qemu-arm, kvmarm, peter.maydell, richard.henderson, alex.bennee,
oliver.upton, sebott, shameerali.kolothum.thodi, armbru, abologna,
jdenemar, shahuang, mark.rutland, philmd, pbonzini
On Thu, Dec 19 2024, Daniel P. Berrangé <berrange@redhat.com> wrote:
> On Thu, Dec 19, 2024 at 03:41:56PM +0000, Marc Zyngier wrote:
>> On Thu, 19 Dec 2024 15:07:25 +0000,
>> Kashyap Chamarthy <kchamart@redhat.com> wrote:
>> >
>> > On Thu, Dec 19, 2024 at 12:26:29PM +0000, Marc Zyngier wrote:
>> > > On Thu, 19 Dec 2024 11:35:16 +0000,
>> > > Kashyap Chamarthy <kchamart@redhat.com> wrote:
>> >
>> > [...]
>> >
>> > > > Consider this:
>> > > >
>> > > > Say, there's a serious security issue in a released ARM CPU. As part of
>> > > > the fix, two new CPU flags need to be exposed to the guest OS, call them
>> > > > "secflag1" and "secflag2". Here, the user is configuring a baseline
>> > > > model + two extra CPU flags, not to get close to some other CPU model
>> > > > but to mitigate itself against a serious security flaw.
>> > >
>> > > If there's such a security issue, that the hypervisor's job to do so,
>> > > not userspace.
>> >
>> > I don't disagree. Probably that has always been the case on ARM. I
>> > asked the above based on how QEMU on x86 handles it today.
>> >
>> > > See what KVM does for CSV3, for example (and all the
>> > > rest of the side-channel stuff).
>> >
>> > Noted. From a quick look in the kernel tree, I assume you're referring
>> > to these commits[1].
>> >
>> > > You can't rely on userspace for security, that'd be completely
>> > > ludicrous.
>> >
>> > As Dan Berrangé points out, it's the bog-standard way QEMU deals with
>> > some of the CPU-related issues on x86 today. See this "important CPU
>> > flags"[2] section in the QEMU docs.
>>
>> I had a look, and we do things quite differently. For example, the
>> spec-ctrl equivalent in implemented in FW and in KVM, and is exposed
>> by default if the HW is vulnerable. Userspace could hide that the
>> mitigation is there, but that's the extent of the configurability.
>
> Whether it is enabled by default or disabled by default isn't a
> totally fatal problem. If QEMU can toggle it to the opposite value,
> we have the same level of configurability in both cases.
I don't think "hiding" is the same thing as "disabling"? The underlying
behaviour will still have changed, the main question is whether that is
a problem.
>
> It does, however, have implications for QEMU as if KVM gained support
> for exposing the new feature by default and QEMU didn't know about
> it, then the guest ABI would have changed without QEMU realizing it.
>
> IOW, it would imply a requirement for timely QEMU updates to match
> the kernel, which is something we wouldn't need in x86 world where
> the feature is disabled by default. Disable by default is a more
> stable approach from QEMU's POV.
It implies that QEMU (or generally the VMM) needs to actively disable
everything it does not know about (i.e. setting everything in any
writable id reg to zero if it has no idea what it is about) to provide a
stable guest interface across different kernels. Just tweaking some
known values is only sufficient for a stable interface across two
systems with the same kernel.
(...)
>> That's why I don't see CPU models as a viable thing in terms of ABI.
>> They are an approximation of what you could have, but the ABI is
>> elsewhere.
>
> Right, this makes life quite challenging for QEMU. The premise of named
> CPU models (as opposed to -host), is to facilitate the migration of VMs
> between heterogenous hardware platforms. That assumes it is possible to
> downgrade the CPU on both src + dst, to the common baseline you desire.
>
> If we were to define a named CPU model, for that to be usable, QEMU
> would have to be able to query the "maxmimum" architectural features,
> and validate that the delta between the host maximum, and the named
> CPU model is possible to downgrade. Is arm providing sufficient info
> to let QEMU do that ?
Not sure if I understand what you mean, but "give me the contents of all
id registers, and which registers are writable" should probably do the
trick?
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-19 17:51 ` Daniel P. Berrangé
2024-12-20 16:04 ` Cornelia Huck
@ 2024-12-21 13:02 ` Marc Zyngier
1 sibling, 0 replies; 56+ messages in thread
From: Marc Zyngier @ 2024-12-21 13:02 UTC (permalink / raw)
To: Daniel "P. Berrangé"
Cc: Kashyap Chamarthy, Eric Auger, Cornelia Huck, eric.auger.pro,
qemu-devel, qemu-arm, kvmarm, peter.maydell, richard.henderson,
alex.bennee, oliver.upton, sebott, shameerali.kolothum.thodi,
armbru, abologna, jdenemar, shahuang, mark.rutland, philmd,
pbonzini
On Thu, 19 Dec 2024 17:51:44 +0000,
Daniel "P. Berrangé" <berrange@redhat.com> wrote:
>
> On Thu, Dec 19, 2024 at 03:41:56PM +0000, Marc Zyngier wrote:
> > On Thu, 19 Dec 2024 15:07:25 +0000,
> > Kashyap Chamarthy <kchamart@redhat.com> wrote:
> > >
> > > On Thu, Dec 19, 2024 at 12:26:29PM +0000, Marc Zyngier wrote:
> > > > On Thu, 19 Dec 2024 11:35:16 +0000,
> > > > Kashyap Chamarthy <kchamart@redhat.com> wrote:
> > >
> > > [...]
> > >
> > > > > Consider this:
> > > > >
> > > > > Say, there's a serious security issue in a released ARM CPU. As part of
> > > > > the fix, two new CPU flags need to be exposed to the guest OS, call them
> > > > > "secflag1" and "secflag2". Here, the user is configuring a baseline
> > > > > model + two extra CPU flags, not to get close to some other CPU model
> > > > > but to mitigate itself against a serious security flaw.
> > > >
> > > > If there's such a security issue, that the hypervisor's job to do so,
> > > > not userspace.
> > >
> > > I don't disagree. Probably that has always been the case on ARM. I
> > > asked the above based on how QEMU on x86 handles it today.
> > >
> > > > See what KVM does for CSV3, for example (and all the
> > > > rest of the side-channel stuff).
> > >
> > > Noted. From a quick look in the kernel tree, I assume you're referring
> > > to these commits[1].
> > >
> > > > You can't rely on userspace for security, that'd be completely
> > > > ludicrous.
> > >
> > > As Dan Berrangé points out, it's the bog-standard way QEMU deals with
> > > some of the CPU-related issues on x86 today. See this "important CPU
> > > flags"[2] section in the QEMU docs.
> >
> > I had a look, and we do things quite differently. For example, the
> > spec-ctrl equivalent in implemented in FW and in KVM, and is exposed
> > by default if the HW is vulnerable. Userspace could hide that the
> > mitigation is there, but that's the extent of the configurability.
>
> Whether it is enabled by default or disabled by default isn't a
> totally fatal problem. If QEMU can toggle it to the opposite value,
> we have the same level of configurability in both cases.
>
> It does, however, have implications for QEMU as if KVM gained support
> for exposing the new feature by default and QEMU didn't know about
> it, then the guest ABI would have changed without QEMU realizing it.
No. It just imposes that QEMU implements its part of the architecture,
which is that any ID reg it doesn't know about and that is advertised
as writable gets written back to 0, which is (in general, but with a
couple of exceptions) the value indicating that a feature is not
implemented.
The ID register space is architected, and has been unchanged for the
past 13 years.
> IOW, it would imply a requirement for timely QEMU updates to match
> the kernel, which is something we wouldn't need in x86 world where
> the feature is disabled by default. Disable by default is a more
> stable approach from QEMU's POV.
Given the above, I don't see where the burden is. And that ship has
sailed since the beginning of KVM/arm, really. It is also worth
realising that for a very long time, it wasn't really possible to
"disable" new features. Even today, disabling a feature really means
emulating its absence.
>
> > > Mind you, I'm _not_ saying this is how ARM should do it. I don't know
> > > enough about ARM to make such remarks.
> > >
> > > * * *
> > >
> > > To reply to your other question on this thread[3] about "which ABI?" I
> > > think Dan is talking about the *guest* ABI: the virtual "chipset" that
> > > is exposed to a guest (e.g. PCI(e) topology, ACPI tables, CPU model,
> > > etc). As I understand it, this "guest ABI" should remain predictable,
> > > regardless of:
> > >
> > > - whether you're updating KVM, QEMU, or the underlying physical
> > > hardware itself; or
> > > - if the guest is migrated, live or offline
> > >
> > > (As you might know, QEMU's "machine types" concept allows to create a
> > > stable guest ABI.)
> >
> > All of this is under control of QEMU, *except* for the "maximum" of
> > the architectural features exposed to the guest. All you can do is
> > *downgrade* from there, and only to a limited extent.
> >
> > That, in turn has a direct impact on what you call the "CPU model",
> > which for the ARM architecture really doesn't exist. All we have is a
> > bag of discrete features, with intricate dependencies between them.
> >
> > Even ignoring virtualisation: you can readily find two machines using
> > the same CPUs (let's say Neoverse-N1), integrated by the same vendor
> > (let's say, Ampere), in SoCs that bear the same name (Altra), and
> > realise that they have a different feature set. Fun, isn't it?
>
> "Fun" is probably not the word I'd pick :-)
Of course not. "Braindead" is the word I wanted to write, but sarcasm
took over... ;-)
>
> > That's why I don't see CPU models as a viable thing in terms of ABI.
> > They are an approximation of what you could have, but the ABI is
> > elsewhere.
>
> Right, this makes life quite challenging for QEMU. The premise of named
> CPU models (as opposed to -host), is to facilitate the migration of VMs
> between heterogenous hardware platforms. That assumes it is possible to
> downgrade the CPU on both src + dst, to the common baseline you desire.
>
> If we were to define a named CPU model, for that to be usable, QEMU
> would have to be able to query the "maxmimum" architectural features,
> and validate that the delta between the host maximum, and the named
> CPU model is possible to downgrade. Is arm providing sufficient info
> to let QEMU do that ?
I think so. On creating a brand new VM, you get the maximum allowed on
the HW, and the subset of features you can downgrade. The intersection
of these two sets and your model's will tell you whether you can
actually instantiate this model on this host. You can also decide that
it is OK to let a extra features advertised, such as extra page sizes
or 32bit support, which the hypervisor can hide, but not disable.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-19 15:41 ` Marc Zyngier
2024-12-19 17:51 ` Daniel P. Berrangé
@ 2024-12-20 11:52 ` Kashyap Chamarthy
2024-12-20 16:17 ` Cornelia Huck
2024-12-21 14:45 ` Marc Zyngier
1 sibling, 2 replies; 56+ messages in thread
From: Kashyap Chamarthy @ 2024-12-20 11:52 UTC (permalink / raw)
To: Marc Zyngier
Cc: Eric Auger, Cornelia Huck, Daniel "P. Berrangé",
eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
richard.henderson, alex.bennee, oliver.upton, sebott,
shameerali.kolothum.thodi, armbru, abologna, jdenemar, shahuang,
mark.rutland, philmd, pbonzini
On Thu, Dec 19, 2024 at 03:41:56PM +0000, Marc Zyngier wrote:
> On Thu, 19 Dec 2024 15:07:25 +0000,
> Kashyap Chamarthy <kchamart@redhat.com> wrote:
> >
> > On Thu, Dec 19, 2024 at 12:26:29PM +0000, Marc Zyngier wrote:
> > > On Thu, 19 Dec 2024 11:35:16 +0000,
> > > Kashyap Chamarthy <kchamart@redhat.com> wrote:
[...]
> > > You can't rely on userspace for security, that'd be completely
> > > ludicrous.
> >
> > As Dan Berrangé points out, it's the bog-standard way QEMU deals with
> > some of the CPU-related issues on x86 today. See this "important CPU
> > flags"[2] section in the QEMU docs.
>
> I had a look, and we do things quite differently. For example, the
> spec-ctrl equivalent in implemented in FW and in KVM, and is exposed
> by default if the HW is vulnerable. Userspace could hide that the
> mitigation is there, but that's the extent of the configurability.
Noted. As Dan says, as long as QEMU can toggle the feature on/off, then
that might be sufficient in the context of migratability.
[...]
> > To reply to your other question on this thread[3] about "which ABI?" I
> > think Dan is talking about the *guest* ABI: the virtual "chipset" that
> > is exposed to a guest (e.g. PCI(e) topology, ACPI tables, CPU model,
> > etc). As I understand it, this "guest ABI" should remain predictable,
> > regardless of:
> >
> > - whether you're updating KVM, QEMU, or the underlying physical
> > hardware itself; or
> > - if the guest is migrated, live or offline
> >
> > (As you might know, QEMU's "machine types" concept allows to create a
> > stable guest ABI.)
>
> All of this is under control of QEMU, *except* for the "maximum" of
> the architectural features exposed to the guest. All you can do is
> *downgrade* from there, and only to a limited extent.
>
> That, in turn has a direct impact on what you call the "CPU model",
> which for the ARM architecture really doesn't exist. All we have is a
> bag of discrete features, with intricate dependencies between them.
I see; thanks for this explanation. Your last sentence above is the
shortest summary of the CPU features situation on ARM I've ever read so
far.
So, I infer this from what you're saying (do correct if it's wrong):
• Currently it is impractical (not feasible?) to pull together a
minimal-and-usable set of CPU features + their dependencies on ARM
to come up with a "CPU model" that can work across a reasonable set
of hardware.
• If the above is true, then the ability to toggle CPU features on and
off might become even more important for QEMU — if it wants to be
able to support live migration across mixed set of hardware on ARM.
NB: by "mixed set of hardware", I mean hardware that is *close
enough* (e.g. among the "Ampere Altra Family" - BTW, this "family"
seems to be only 2 systems far). Not arbitrarily mixed. I did read
your response in this thread about "who in their right mind" would
want to migrate from Nvidia "Grace" to "AmpereOne".
https://lore.kernel.org/linux-arm-kernel/86y10ytpo6.wl-maz@kernel.org/
— KVM: arm64: Make the exposed feature bits in AA64DFR0_EL1
writable from userspace
> Even ignoring virtualisation: you can readily find two machines using
> the same CPUs (let's say Neoverse-N1), integrated by the same vendor
> (let's say, Ampere), in SoCs that bear the same name (Altra), and
> realise that they have a different feature set. Fun, isn't it?
Yikes! I would use a different word, that starts with "m" and ends with
"s" (the resulting word rhymes with the latter) ;-)
* * *
Related tangent on CPU feature discoverability on ARM:
Speaking of "Neoverse-N1", looking at a system that I have access to,
the `lscpu` output does not say anything about who the integrator is; it
only says:
...
Vendor ID: ARM
Model name: Neoverse-N1
...
I realize, `lscpu` displays only whatever the kernel knows. Nothing in
`dmidecode` either.
Also, it looks like there's no equivalent of a "CPUID" instruction (I
realize it is x86-specific) on ARM. Although, I came across a Google
Git repo that seems to implement a bespoke, "aarch64_cpuid". From a
what I see, it seems to fetch the "Main ID Register" (MIDR_EL1) - I
don't know enough about it to understand its implications:
https://github.com/google/cpu_features/blob/main/src/impl_aarch64_cpuid.c
> That's why I don't see CPU models as a viable thing in terms of ABI.
> They are an approximation of what you could have, but the ABI is
> elsewhere.
Hmm, this is "significant new information" for me. If CPU models can't
be part of the guest ABI on ARM, then the whole "migratability across
heterogenous hardware" on QEMU requires deeper thinking.
Thanks for this discussion.
--
/kashyap
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-20 11:52 ` Kashyap Chamarthy
@ 2024-12-20 16:17 ` Cornelia Huck
2024-12-21 14:45 ` Marc Zyngier
1 sibling, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-20 16:17 UTC (permalink / raw)
To: Kashyap Chamarthy, Marc Zyngier
Cc: Eric Auger, Daniel P. Berrangé, eric.auger.pro, qemu-devel,
qemu-arm, kvmarm, peter.maydell, richard.henderson, alex.bennee,
oliver.upton, sebott, shameerali.kolothum.thodi, armbru, abologna,
jdenemar, shahuang, mark.rutland, philmd, pbonzini
On Fri, Dec 20 2024, Kashyap Chamarthy <kchamart@redhat.com> wrote:
> Related tangent on CPU feature discoverability on ARM:
>
> Speaking of "Neoverse-N1", looking at a system that I have access to,
> the `lscpu` output does not say anything about who the integrator is; it
> only says:
>
> ...
> Vendor ID: ARM
> Model name: Neoverse-N1
> ...
>
> I realize, `lscpu` displays only whatever the kernel knows. Nothing in
> `dmidecode` either.
>
> Also, it looks like there's no equivalent of a "CPUID" instruction (I
> realize it is x86-specific) on ARM. Although, I came across a Google
> Git repo that seems to implement a bespoke, "aarch64_cpuid". From a
> what I see, it seems to fetch the "Main ID Register" (MIDR_EL1) - I
> don't know enough about it to understand its implications:
>
> https://github.com/google/cpu_features/blob/main/src/impl_aarch64_cpuid.c
My guess is that this is mostly for "we have code that looks for a cpuid
like on x86, let's provide some code on arm that gives something that is
at least somewhat useful."
For "CPU feature discoverability", I don't think that there's any way
other than looking at the actual id registers. It would be nice if you
could at least know that "there are some <unspecified> differences in
features" by comparing MIDR/REVIDR/AIDR, but that's not the case IIRC?
[Anyway, I'm off for the year :)]
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-20 11:52 ` Kashyap Chamarthy
2024-12-20 16:17 ` Cornelia Huck
@ 2024-12-21 14:45 ` Marc Zyngier
1 sibling, 0 replies; 56+ messages in thread
From: Marc Zyngier @ 2024-12-21 14:45 UTC (permalink / raw)
To: Kashyap Chamarthy
Cc: Eric Auger, Cornelia Huck, Daniel "P. Berrangé",
eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
richard.henderson, alex.bennee, oliver.upton, sebott,
shameerali.kolothum.thodi, armbru, abologna, jdenemar, shahuang,
mark.rutland, philmd, pbonzini
On Fri, 20 Dec 2024 11:52:51 +0000,
Kashyap Chamarthy <kchamart@redhat.com> wrote:
>
> On Thu, Dec 19, 2024 at 03:41:56PM +0000, Marc Zyngier wrote:
> > On Thu, 19 Dec 2024 15:07:25 +0000,
> > Kashyap Chamarthy <kchamart@redhat.com> wrote:
> > >
> > > On Thu, Dec 19, 2024 at 12:26:29PM +0000, Marc Zyngier wrote:
> > > > On Thu, 19 Dec 2024 11:35:16 +0000,
> > > > Kashyap Chamarthy <kchamart@redhat.com> wrote:
>
> [...]
>
> > > > You can't rely on userspace for security, that'd be completely
> > > > ludicrous.
> > >
> > > As Dan Berrangé points out, it's the bog-standard way QEMU deals with
> > > some of the CPU-related issues on x86 today. See this "important CPU
> > > flags"[2] section in the QEMU docs.
> >
> > I had a look, and we do things quite differently. For example, the
> > spec-ctrl equivalent in implemented in FW and in KVM, and is exposed
> > by default if the HW is vulnerable. Userspace could hide that the
> > mitigation is there, but that's the extent of the configurability.
>
> Noted. As Dan says, as long as QEMU can toggle the feature on/off, then
> that might be sufficient in the context of migratability.
>
> [...]
>
> > > To reply to your other question on this thread[3] about "which ABI?" I
> > > think Dan is talking about the *guest* ABI: the virtual "chipset" that
> > > is exposed to a guest (e.g. PCI(e) topology, ACPI tables, CPU model,
> > > etc). As I understand it, this "guest ABI" should remain predictable,
> > > regardless of:
> > >
> > > - whether you're updating KVM, QEMU, or the underlying physical
> > > hardware itself; or
> > > - if the guest is migrated, live or offline
> > >
> > > (As you might know, QEMU's "machine types" concept allows to create a
> > > stable guest ABI.)
> >
> > All of this is under control of QEMU, *except* for the "maximum" of
> > the architectural features exposed to the guest. All you can do is
> > *downgrade* from there, and only to a limited extent.
> >
> > That, in turn has a direct impact on what you call the "CPU model",
> > which for the ARM architecture really doesn't exist. All we have is a
> > bag of discrete features, with intricate dependencies between them.
>
> I see; thanks for this explanation. Your last sentence above is the
> shortest summary of the CPU features situation on ARM I've ever read so
> far.
>
> So, I infer this from what you're saying (do correct if it's wrong):
>
> • Currently it is impractical (not feasible?) to pull together a
> minimal-and-usable set of CPU features + their dependencies on ARM
> to come up with a "CPU model" that can work across a reasonable set
> of hardware.
It isn't quite that. It *is* technically possible, and KVM does give
you the tools you need for that. In practice, the diversity of the
ecosystem is so huge that you can only rely on some very basic stuff
unless the implementations are already very close. And that "small
details" such as the timer frequency are strictly identical.
>
> • If the above is true, then the ability to toggle CPU features on and
> off might become even more important for QEMU — if it wants to be
> able to support live migration across mixed set of hardware on ARM.
Turning CPU features off is not always possible. Hiding them is
generally possible, with a number of exceptions. We try our best to
provide both, but it's... complicated.
[...]
> Related tangent on CPU feature discoverability on ARM:
>
> Speaking of "Neoverse-N1", looking at a system that I have access to,
> the `lscpu` output does not say anything about who the integrator is; it
> only says:
>
> ...
> Vendor ID: ARM
> Model name: Neoverse-N1
> ...
>
> I realize, `lscpu` displays only whatever the kernel knows. Nothing in
> `dmidecode` either.
The kernel does not know anything about the "Neoverse-N1" string. It
can match some MIDR_EL1 values for errata workaround purposes, but
doesn't gives two hoots about a human readable string.
Every other year, we get asked to add a full database of strings in
the kernel. The answer is a simple, polite, and final "no way". This
serves no purpose at all. lscpu does have that database, and that's
the right place to do it.
When it comes to integration, the firmware can optionally report some
information, which is the EL3 version of a commercial break (see the
SOC_ID stuff). This isn't wildly deployed, thankfully.
> Also, it looks like there's no equivalent of a "CPUID" instruction (I
> realize it is x86-specific) on ARM. Although, I came across a Google
> Git repo that seems to implement a bespoke, "aarch64_cpuid". From a
> what I see, it seems to fetch the "Main ID Register" (MIDR_EL1) - I
> don't know enough about it to understand its implications:
>
> https://github.com/google/cpu_features/blob/main/src/impl_aarch64_cpuid.c
MIDR_EL1 doesn't give you much, and you cannot assume anything about
the the feature set from it. Linux already allows you to inspect the
ID registers from userspace (by trapping, emulating, and sanitising
the result). That's the only reliable source of information.
>
> > That's why I don't see CPU models as a viable thing in terms of ABI.
> > They are an approximation of what you could have, but the ABI is
> > elsewhere.
>
> Hmm, this is "significant new information" for me. If CPU models can't
> be part of the guest ABI on ARM, then the whole "migratability across
> heterogenous hardware" on QEMU requires deeper thinking.
As I said all along, the only source of truth is the set of ID
registers. Nothing else. You can build a "model" on top of that, but
not the other way around.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-12 8:12 ` Eric Auger
2024-12-12 8:42 ` Eric Auger
2024-12-12 9:10 ` Daniel P. Berrangé
@ 2024-12-16 16:42 ` Cornelia Huck
2024-12-16 16:58 ` Cornelia Huck
2 siblings, 1 reply; 56+ messages in thread
From: Cornelia Huck @ 2024-12-16 16:42 UTC (permalink / raw)
To: eric.auger, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini
On Thu, Dec 12 2024, Eric Auger <eric.auger@redhat.com> wrote:
> Connie,
>
> On 12/6/24 12:21, Cornelia Huck wrote:
>> Whether it make sense to continue with the approach of tweaking values in
>> the ID registers in general. If we want to be able to migrate between cpus
>> that do not differ wildly, we'll encounter differences that cannot be
>> expressed via FEAT_xxx -- e.g. when comparing various AmpereAltra Max systems,
>> they only differ in parts of CTR_EL0 -- which is not a feature register, but
>> a writable register.
> In v1 most of the commenters said they would prefer to see FEAT props
> instead of IDREG field props. I think we shall try to go in this
> direction anyway. As you pointed out there will be some cases where FEAT
> won't be enough (CTR_EL0 is a good example). So I tend to think the end
> solution will be a mix of FEAT and ID reg field props.
Some analysis of FEAT_xxx mappings:
https://lore.kernel.org/qemu-devel/87ikstn8sc.fsf@redhat.com/
(actually, ~190 of FEAT_xxx map to a single value in a single register,
so mappings are easy other than the sheer amount of them)
We probably should simply not support FEAT_xxx that are solely defined
via dependencies.
Some more real-world examples from some cpu pairings I had looked at:
https://lore.kernel.org/qemu-devel/87ldx2krdp.fsf@redhat.com/
(but also see Peter's follow-up, the endianness field is actually
covered by a feature)
The values-in-registers-not-covered-by-features we are currently aware
of are:
- number of breakpoints
- PARange values
- GIC
- some fields in CTR_EL0
(see also
https://lore.kernel.org/qemu-devel/4fb49b5b02bb417399ee871b2c85bb35@huawei.com/
for the latter two)
Also, MIDR/REVIDR handling.
Given that we'll need a mix if we support FEAT_xxx, should we mandate
the FEAT_xxx syntax if there is a mapping and allow direct specification
of register fields only if there is none, or allow them as alternatives
(with proper priority handling, or alias handling?)
>
> Personally I would smoothly migrate what we can from ID reg field props
> to FEAT props (maybe using prop aliases?), starting from the easiest 1-1
> mappings and then adressing the FEAT that are more complex but are
> explictly needed to enable the use cases we are interested in, at RedHat:
> migration within Ampere AltraMax family, migration within NVidia Grace
> family, migration within AmpereOne family and migration between Graviton3/4.
For these, we'll already need the mix (my examples above all came from
these use cases.)
(Of course, the existing legacy props need to be expressed as well. I
guess they should map to registers directly.)
>
> We have no info about other's use cases. If some of you want to see some
> other live migration combinations addressed, please raise your voice.
> Some CSPs may have their own LM solution/requirements but they don't use
> qemu. So I think we shall concentrate on those use cases.
>
> You did the exercise to identify most prevalent patterns for FEAT to
> IDREG fields mappings. I think we should now encode this conversion
> table for those which are needed in above use cases.
I'd focus on the actually needed features first, as otherwise it's
really overwhelming.
>
> From a named model point of view, since I do not see much traction
> upstream besides Red Hat use cases, targetting ARM spec revision
> baselines may be overkill. Personally I would try to focus on above
> models: AltraMax, AmpereOne, Grace, ... Or maybe the ARM cores they may
> be derived from. According to the discussion we had with Marc in [1] it
> seems it does not make sense to target migration between very
> heterogeneous machines and Dan said we would prefer to avoid adding
> plenty of feat add-ons to a named models. So I would rather be as close
> as possible to a specific family definition.
Using e.g. Neoverse-V2 as a base currently looks most attractive to
me -- going with Armv<x>.<y> would probably give a larger diff (although
the diff for Graviton3/4 is pretty large anyway.)
>
> Thanks
>
> Eric
>
> [1]
> https://lore.kernel.org/all/c879fda9-db5a-4743-805d-03c0acba8060@redhat.com/#r
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-16 16:42 ` Cornelia Huck
@ 2024-12-16 16:58 ` Cornelia Huck
0 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-16 16:58 UTC (permalink / raw)
To: eric.auger, eric.auger.pro, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar
Cc: shahuang, mark.rutland, philmd, pbonzini
On Mon, Dec 16 2024, Cornelia Huck <cohuck@redhat.com> wrote:
> On Thu, Dec 12 2024, Eric Auger <eric.auger@redhat.com> wrote:
>
>> Connie,
>>
>> On 12/6/24 12:21, Cornelia Huck wrote:
>>> Whether it make sense to continue with the approach of tweaking values in
>>> the ID registers in general. If we want to be able to migrate between cpus
>>> that do not differ wildly, we'll encounter differences that cannot be
>>> expressed via FEAT_xxx -- e.g. when comparing various AmpereAltra Max systems,
>>> they only differ in parts of CTR_EL0 -- which is not a feature register, but
>>> a writable register.
>> In v1 most of the commenters said they would prefer to see FEAT props
>> instead of IDREG field props. I think we shall try to go in this
>> direction anyway. As you pointed out there will be some cases where FEAT
>> won't be enough (CTR_EL0 is a good example). So I tend to think the end
>> solution will be a mix of FEAT and ID reg field props.
>
> Some analysis of FEAT_xxx mappings:
> https://lore.kernel.org/qemu-devel/87ikstn8sc.fsf@redhat.com/
>
> (actually, ~190 of FEAT_xxx map to a single value in a single register,
> so mappings are easy other than the sheer amount of them)
>
> We probably should simply not support FEAT_xxx that are solely defined
> via dependencies.
>
> Some more real-world examples from some cpu pairings I had looked at:
> https://lore.kernel.org/qemu-devel/87ldx2krdp.fsf@redhat.com/
> (but also see Peter's follow-up, the endianness field is actually
> covered by a feature)
>
> The values-in-registers-not-covered-by-features we are currently aware
> of are:
> - number of breakpoints
> - PARange values
> - GIC
> - some fields in CTR_EL0
> (see also
> https://lore.kernel.org/qemu-devel/4fb49b5b02bb417399ee871b2c85bb35@huawei.com/
> for the latter two)
And the differences in GIC might be actually due to a GICv3 not being
configured, together with running a recent kernel, which will zero the
field. So we might actually already be able to handle it for most cases.
>
> Also, MIDR/REVIDR handling.
>
> Given that we'll need a mix if we support FEAT_xxx, should we mandate
> the FEAT_xxx syntax if there is a mapping and allow direct specification
> of register fields only if there is none, or allow them as alternatives
> (with proper priority handling, or alias handling?)
>
>>
>> Personally I would smoothly migrate what we can from ID reg field props
>> to FEAT props (maybe using prop aliases?), starting from the easiest 1-1
>> mappings and then adressing the FEAT that are more complex but are
>> explictly needed to enable the use cases we are interested in, at RedHat:
>> migration within Ampere AltraMax family, migration within NVidia Grace
>> family, migration within AmpereOne family and migration between Graviton3/4.
>
> For these, we'll already need the mix (my examples above all came from
> these use cases.)
>
> (Of course, the existing legacy props need to be expressed as well. I
> guess they should map to registers directly.)
>
>>
>> We have no info about other's use cases. If some of you want to see some
>> other live migration combinations addressed, please raise your voice.
>> Some CSPs may have their own LM solution/requirements but they don't use
>> qemu. So I think we shall concentrate on those use cases.
>>
>> You did the exercise to identify most prevalent patterns for FEAT to
>> IDREG fields mappings. I think we should now encode this conversion
>> table for those which are needed in above use cases.
>
> I'd focus on the actually needed features first, as otherwise it's
> really overwhelming.
>
>>
>> From a named model point of view, since I do not see much traction
>> upstream besides Red Hat use cases, targetting ARM spec revision
>> baselines may be overkill. Personally I would try to focus on above
>> models: AltraMax, AmpereOne, Grace, ... Or maybe the ARM cores they may
>> be derived from. According to the discussion we had with Marc in [1] it
>> seems it does not make sense to target migration between very
>> heterogeneous machines and Dan said we would prefer to avoid adding
>> plenty of feat add-ons to a named models. So I would rather be as close
>> as possible to a specific family definition.
>
> Using e.g. Neoverse-V2 as a base currently looks most attractive to
> me -- going with Armv<x>.<y> would probably give a larger diff (although
> the diff for Graviton3/4 is pretty large anyway.)
>
>>
>> Thanks
>>
>> Eric
>>
>> [1]
>> https://lore.kernel.org/all/c879fda9-db5a-4743-805d-03c0acba8060@redhat.com/#r
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (21 preceding siblings ...)
2024-12-12 8:12 ` Eric Auger
@ 2024-12-12 13:13 ` Sebastian Ott
2024-12-12 14:46 ` Cornelia Huck
2024-12-17 15:21 ` Marc Zyngier
23 siblings, 1 reply; 56+ messages in thread
From: Sebastian Ott @ 2024-12-12 13:13 UTC (permalink / raw)
To: Cornelia Huck
Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
shameerali.kolothum.thodi, armbru, berrange, abologna, jdenemar,
shahuang, mark.rutland, philmd, pbonzini
On Fri, 6 Dec 2024, Cornelia Huck wrote:
> A respin/update on the aarch64 KVM cpu models. Also available at
> gitlab.com/cohuck/qemu arm-cpu-model-rfcv2
>
> Find Eric's original cover letter below, so that I do not need to
> repeat myself on the aspects that have not changed since RFCv1 :)
>
> Changes from RFCv1:
>
> Rebased on more recent QEMU (some adaptions in the register conversions
> of the first few patches.)
>
> Based on feedback, I have removed the "custom" cpu model; instead, I
> have added the new SYSREG_<REG>_<FIELD> properties to the "host" model.
> This works well if you want to tweak anything that does not correspond
> to the existing properties for the host model; however, if you e.g.
> wanted to tweak sve, you have two ways to do so -- we'd probably either
> want to check for conflicts, or just declare precedence. The kvm-specific
> props remain unchanged, as they are orthogonal to this configuration.
>
> The cpu model expansion for the "host" model now dumps the new SYSREG_
> properties in addition to the existing host model properties; this is a
> bit ugly, but I don't see a good way on how to split this up.
>
I gave this a spin today and successfully migrated a VM between 2 similar
machines that only differ in the DIC bit of the cache type register using:
-cpu host,SYSREG_CTR_EL0_DIC=0
This allows me to get rid of my horrid qemu hacks to achieve the same.
Thanks,
Sebastian
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-12 13:13 ` Sebastian Ott
@ 2024-12-12 14:46 ` Cornelia Huck
0 siblings, 0 replies; 56+ messages in thread
From: Cornelia Huck @ 2024-12-12 14:46 UTC (permalink / raw)
To: Sebastian Ott
Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, maz, oliver.upton,
shameerali.kolothum.thodi, armbru, berrange, abologna, jdenemar,
shahuang, mark.rutland, philmd, pbonzini
On Thu, Dec 12 2024, Sebastian Ott <sebott@redhat.com> wrote:
> On Fri, 6 Dec 2024, Cornelia Huck wrote:
>> A respin/update on the aarch64 KVM cpu models. Also available at
>> gitlab.com/cohuck/qemu arm-cpu-model-rfcv2
>>
>> Find Eric's original cover letter below, so that I do not need to
>> repeat myself on the aspects that have not changed since RFCv1 :)
>>
>> Changes from RFCv1:
>>
>> Rebased on more recent QEMU (some adaptions in the register conversions
>> of the first few patches.)
>>
>> Based on feedback, I have removed the "custom" cpu model; instead, I
>> have added the new SYSREG_<REG>_<FIELD> properties to the "host" model.
>> This works well if you want to tweak anything that does not correspond
>> to the existing properties for the host model; however, if you e.g.
>> wanted to tweak sve, you have two ways to do so -- we'd probably either
>> want to check for conflicts, or just declare precedence. The kvm-specific
>> props remain unchanged, as they are orthogonal to this configuration.
>>
>> The cpu model expansion for the "host" model now dumps the new SYSREG_
>> properties in addition to the existing host model properties; this is a
>> bit ugly, but I don't see a good way on how to split this up.
>>
>
> I gave this a spin today and successfully migrated a VM between 2 similar
> machines that only differ in the DIC bit of the cache type register using:
>
> -cpu host,SYSREG_CTR_EL0_DIC=0
>
> This allows me to get rid of my horrid qemu hacks to achieve the same.
Great, thanks for testing!
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-06 11:21 [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model Cornelia Huck
` (22 preceding siblings ...)
2024-12-12 13:13 ` Sebastian Ott
@ 2024-12-17 15:21 ` Marc Zyngier
2024-12-17 18:05 ` Eric Auger
23 siblings, 1 reply; 56+ messages in thread
From: Marc Zyngier @ 2024-12-17 15:21 UTC (permalink / raw)
To: Cornelia Huck
Cc: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, richard.henderson, alex.bennee, oliver.upton,
sebott, shameerali.kolothum.thodi, armbru, berrange, abologna,
jdenemar, shahuang, mark.rutland, philmd, pbonzini
On Fri, 06 Dec 2024 11:21:53 +0000,
Cornelia Huck <cohuck@redhat.com> wrote:
>
> A respin/update on the aarch64 KVM cpu models. Also available at
> gitlab.com/cohuck/qemu arm-cpu-model-rfcv2
>
> Find Eric's original cover letter below, so that I do not need to
> repeat myself on the aspects that have not changed since RFCv1 :)
Does anyone have a branch containing both this series and Eric's KVM
NV support series?
Asking for a friend...
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH RFCv2 00/20] kvm/arm: Introduce a customizable aarch64 KVM host model
2024-12-17 15:21 ` Marc Zyngier
@ 2024-12-17 18:05 ` Eric Auger
0 siblings, 0 replies; 56+ messages in thread
From: Eric Auger @ 2024-12-17 18:05 UTC (permalink / raw)
To: Marc Zyngier, Cornelia Huck
Cc: eric.auger.pro, qemu-devel, qemu-arm, kvmarm, peter.maydell,
richard.henderson, alex.bennee, oliver.upton, sebott,
shameerali.kolothum.thodi, armbru, berrange, abologna, jdenemar,
shahuang, mark.rutland, philmd, pbonzini
Hi Marc,
On 12/17/24 16:21, Marc Zyngier wrote:
> On Fri, 06 Dec 2024 11:21:53 +0000,
> Cornelia Huck <cohuck@redhat.com> wrote:
>> A respin/update on the aarch64 KVM cpu models. Also available at
>> gitlab.com/cohuck/qemu arm-cpu-model-rfcv2
>>
>> Find Eric's original cover letter below, so that I do not need to
>> repeat myself on the aspects that have not changed since RFCv1 :)
> Does anyone have a branch containing both this series and Eric's KVM
> NV support series?
>
> Asking for a friend...
I have just assembled
https://github.com/eauger/qemu.git
v9.0-nv-rfcv4-vcpu-model-v2
Totally untested atm
Eric
>
> M.
>
^ permalink raw reply [flat|nested] 56+ messages in thread