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

From: Steffen Eiden <[email-masked]>
Date: Fri, 29 May 2026 17:55:53 +0200

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 <[email-masked]>
---
 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