Commit 81fbef16 authored by Oliver Upton's avatar Oliver Upton
Browse files

KVM: arm64: Wire up SCTLR2_ELx sysreg descriptors



Set up the sysreg descriptors for SCTLR2_ELx, along with the associated
storage and VNCR mapping.

Reviewed-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20250708172532.1699409-12-oliver.upton@linux.dev


Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
parent 0ead48ac
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -523,6 +523,7 @@ enum vcpu_sysreg {
	/* Anything from this can be RES0/RES1 sanitised */
	MARKER(__SANITISED_REG_START__),
	TCR2_EL2,	/* Extended Translation Control Register (EL2) */
	SCTLR2_EL2,	/* System Control Register 2 (EL2) */
	MDCR_EL2,	/* Monitor Debug Configuration Register (EL2) */
	CNTHCTL_EL2,	/* Counter-timer Hypervisor Control register */

@@ -537,6 +538,7 @@ enum vcpu_sysreg {
	VNCR(TTBR1_EL1),/* Translation Table Base Register 1 */
	VNCR(TCR_EL1),	/* Translation Control Register */
	VNCR(TCR2_EL1),	/* Extended Translation Control Register */
	VNCR(SCTLR2_EL1), /* System Control Register 2 */
	VNCR(ESR_EL1),	/* Exception Syndrome Register */
	VNCR(AFSR0_EL1),/* Auxiliary Fault Status Register 0 */
	VNCR(AFSR1_EL1),/* Auxiliary Fault Status Register 1 */
@@ -1204,6 +1206,7 @@ static inline bool __vcpu_read_sys_reg_from_cpu(int reg, u64 *val)
	case IFSR32_EL2:	*val = read_sysreg_s(SYS_IFSR32_EL2);	break;
	case DBGVCR32_EL2:	*val = read_sysreg_s(SYS_DBGVCR32_EL2);	break;
	case ZCR_EL1:		*val = read_sysreg_s(SYS_ZCR_EL12);	break;
	case SCTLR2_EL1:	*val = read_sysreg_s(SYS_SCTLR2_EL12);	break;
	default:		return false;
	}

@@ -1254,6 +1257,7 @@ static inline bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg)
	case IFSR32_EL2:	write_sysreg_s(val, SYS_IFSR32_EL2);	break;
	case DBGVCR32_EL2:	write_sysreg_s(val, SYS_DBGVCR32_EL2);	break;
	case ZCR_EL1:		write_sysreg_s(val, SYS_ZCR_EL12);	break;
	case SCTLR2_EL1:	write_sysreg_s(val, SYS_SCTLR2_EL12);	break;
	default:		return false;
	}

@@ -1685,6 +1689,9 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
#define kvm_has_ras(k)					\
	(kvm_has_feat((k), ID_AA64PFR0_EL1, RAS, IMP))

#define kvm_has_sctlr2(k)				\
	(kvm_has_feat((k), ID_AA64MMFR3_EL1, SCTLRX, IMP))

static inline bool kvm_arch_has_irq_bypass(void)
{
	return true;
+1 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@
#define VNCR_SP_EL1             0x240
#define VNCR_VBAR_EL1           0x250
#define VNCR_TCR2_EL1		0x270
#define VNCR_SCTLR2_EL1		0x278
#define VNCR_PIRE0_EL1		0x290
#define VNCR_PIR_EL1		0x2A0
#define VNCR_POR_EL1		0x2A8
+20 −0
Original line number Diff line number Diff line
@@ -144,6 +144,7 @@ static bool get_el2_to_el1_mapping(unsigned int reg,
		MAPPED_EL2_SYSREG(SPSR_EL2,    SPSR_EL1,    NULL	     );
		MAPPED_EL2_SYSREG(ZCR_EL2,     ZCR_EL1,     NULL	     );
		MAPPED_EL2_SYSREG(CONTEXTIDR_EL2, CONTEXTIDR_EL1, NULL	     );
		MAPPED_EL2_SYSREG(SCTLR2_EL2,  SCTLR2_EL1,  NULL	     );
	default:
		return false;
	}
@@ -2483,6 +2484,21 @@ static unsigned int vncr_el2_visibility(const struct kvm_vcpu *vcpu,
	return REG_HIDDEN;
}

static unsigned int sctlr2_visibility(const struct kvm_vcpu *vcpu,
				      const struct sys_reg_desc *rd)
{
	if (kvm_has_sctlr2(vcpu->kvm))
		return 0;

	return REG_HIDDEN;
}

static unsigned int sctlr2_el2_visibility(const struct kvm_vcpu *vcpu,
					  const struct sys_reg_desc *rd)
{
	return __el2_visibility(vcpu, rd, sctlr2_visibility);
}

static bool access_zcr_el2(struct kvm_vcpu *vcpu,
			   struct sys_reg_params *p,
			   const struct sys_reg_desc *r)
@@ -2955,6 +2971,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
	{ SYS_DESC(SYS_SCTLR_EL1), access_vm_reg, reset_val, SCTLR_EL1, 0x00C50078 },
	{ SYS_DESC(SYS_ACTLR_EL1), access_actlr, reset_actlr, ACTLR_EL1 },
	{ SYS_DESC(SYS_CPACR_EL1), NULL, reset_val, CPACR_EL1, 0 },
	{ SYS_DESC(SYS_SCTLR2_EL1), access_vm_reg, reset_val, SCTLR2_EL1, 0,
	  .visibility = sctlr2_visibility },

	MTE_REG(RGSR_EL1),
	MTE_REG(GCR_EL1),
@@ -3302,6 +3320,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
	EL2_REG_VNCR(VMPIDR_EL2, reset_unknown, 0),
	EL2_REG(SCTLR_EL2, access_rw, reset_val, SCTLR_EL2_RES1),
	EL2_REG(ACTLR_EL2, access_rw, reset_val, 0),
	EL2_REG_FILTERED(SCTLR2_EL2, access_vm_reg, reset_val, 0,
			 sctlr2_el2_visibility),
	EL2_REG_VNCR(HCR_EL2, reset_hcr, 0),
	EL2_REG(MDCR_EL2, access_mdcr, reset_mdcr, 0),
	EL2_REG(CPTR_EL2, access_rw, reset_val, CPTR_NVHE_EL2_RES1),