[PATCH v1 20/26] KVM: arm64: Share ID reg handling

From: Steffen Eiden

Date: Fri May 29 2026 - 13:03:50 EST


Move ID register definitions from arch/arm64/include to a shared
location (include/kvm/arm64) to enable reuse by e.g. s390 for KVM/arm64
on s390 support.

Signed-off-by: Steffen Eiden <seiden@xxxxxxxxxxxxx>
---
arch/arm64/include/asm/kvm_host.h | 41 ------------------------------
include/kvm/arm64/kvm_host.h | 42 +++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+), 41 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 5734e93cad57..a5fca468cc4a 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1385,47 +1385,6 @@ static inline void kvm_hyp_reserve(void) { }
void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu);
bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);

-struct kvm_vm_id_regs {
- /*
- * Emulated CPU ID registers per VM
- * (Op0, Op1, CRn, CRm, Op2) of the ID registers to be saved in it
- * is (3, 0, 0, crm, op2), where 1<=crm<8, 0<=op2<8.
- *
- * These emulated idregs are VM-wide, but accessed from the context of a vCPU.
- * Atomic access to multiple idregs are guarded by kvm_arch.config_lock.
- */
-#define IDREG_IDX(id) (((sys_reg_CRm(id) - 1) << 3) | sys_reg_Op2(id))
-#define KVM_ARM_ID_REG_NUM (IDREG_IDX(sys_reg(3, 0, 0, 7, 7)) + 1)
- u64 normal[KVM_ARM_ID_REG_NUM];
-
- u64 midr_el1;
- u64 revidr_el1;
- u64 aidr_el1;
- u64 ctr_el0;
-};
-
-static inline u64 *__vm_id_reg(struct kvm_vm_id_regs *id_regs, u32 reg)
-{
- switch (reg) {
- case sys_reg(3, 0, 0, 1, 0) ... sys_reg(3, 0, 0, 7, 7):
- return &id_regs->normal[IDREG_IDX(reg)];
- case SYS_CTR_EL0:
- return &id_regs->ctr_el0;
- case SYS_MIDR_EL1:
- return &id_regs->midr_el1;
- case SYS_REVIDR_EL1:
- return &id_regs->revidr_el1;
- case SYS_AIDR_EL1:
- return &id_regs->aidr_el1;
- default:
- WARN_ON_ONCE(1);
- return NULL;
- }
-}
-
-#define kvm_read_vm_id_reg(kvm, reg) \
- ({ u64 __val = *__vm_id_reg(&(kvm)->arch.id_regs, reg); __val; })
-
void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);

static inline bool kvm_arch_has_irq_bypass(void)
diff --git a/include/kvm/arm64/kvm_host.h b/include/kvm/arm64/kvm_host.h
index 8bf399508757..379942225d5f 100644
--- a/include/kvm/arm64/kvm_host.h
+++ b/include/kvm/arm64/kvm_host.h
@@ -4,6 +4,7 @@
#define __KVM_ARM64_KVM_HOST_H

#include <linux/types.h>
+#include <asm/sysreg-defs.h>

#define KVM_VCPU_MAX_FEATURES 9

@@ -21,6 +22,47 @@
#define KVM_REQ_MAP_L1_VNCR_EL2 KVM_ARCH_REQ(10)
#define KVM_REQ_VGIC_PROCESS_UPDATE KVM_ARCH_REQ(11)

+struct kvm_vm_id_regs {
+ /*
+ * Emulated CPU ID registers per VM
+ * (Op0, Op1, CRn, CRm, Op2) of the ID registers to be saved in it
+ * is (3, 0, 0, crm, op2), where 1<=crm<8, 0<=op2<8.
+ *
+ * These emulated idregs are VM-wide, but accessed from the context of a vCPU.
+ * Atomic access to multiple idregs are guarded by kvm_arch.config_lock.
+ */
+#define IDREG_IDX(id) (((sys_reg_CRm(id) - 1) << 3) | sys_reg_Op2(id))
+#define KVM_ARM_ID_REG_NUM (IDREG_IDX(sys_reg(3, 0, 0, 7, 7)) + 1)
+ u64 normal[KVM_ARM_ID_REG_NUM];
+
+ u64 midr_el1;
+ u64 revidr_el1;
+ u64 aidr_el1;
+ u64 ctr_el0;
+};
+
+static inline u64 *__vm_id_reg(struct kvm_vm_id_regs *id_regs, u32 reg)
+{
+ switch (reg) {
+ case sys_reg(3, 0, 0, 1, 0) ... sys_reg(3, 0, 0, 7, 7):
+ return &id_regs->normal[IDREG_IDX(reg)];
+ case SYS_CTR_EL0:
+ return &id_regs->ctr_el0;
+ case SYS_MIDR_EL1:
+ return &id_regs->midr_el1;
+ case SYS_REVIDR_EL1:
+ return &id_regs->revidr_el1;
+ case SYS_AIDR_EL1:
+ return &id_regs->aidr_el1;
+ default:
+ WARN_ON_ONCE(1);
+ return NULL;
+ }
+}
+
+#define kvm_read_vm_id_reg(kvm, reg) \
+ ({ u64 __val = *__vm_id_reg(&(kvm)->arch.id_regs, reg); __val; })
+
struct vcpu_reset_state {
unsigned long pc;
unsigned long r0;
--
2.53.0