Commit e19d5331 authored by Marc Zyngier's avatar Marc Zyngier Committed by Oliver Upton
Browse files

KVM: arm64: nv: Add trap description for CPTR_EL2



Add trap description for CPTR_EL2.{TCPAC,TAM,E0POE,TTA}.

TTA is a bit annoying as it changes location depending on E2H.
This forces us to add yet another "complex" trap condition.

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20240620164653.1130714-14-oliver.upton@linux.dev


Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
parent 0edc60fd
Loading
Loading
Loading
Loading
+91 −0
Original line number Diff line number Diff line
@@ -79,6 +79,10 @@ enum cgt_group_id {
	CGT_MDCR_E2TB,
	CGT_MDCR_TDCC,

	CGT_CPACR_E0POE,
	CGT_CPTR_TAM,
	CGT_CPTR_TCPAC,

	/*
	 * Anything after this point is a combination of coarse trap
	 * controls, which must all be evaluated to decide what to do.
@@ -106,6 +110,8 @@ enum cgt_group_id {
	CGT_CNTHCTL_EL1PCTEN = __COMPLEX_CONDITIONS__,
	CGT_CNTHCTL_EL1PTEN,

	CGT_CPTR_TTA,

	/* Must be last */
	__NR_CGT_GROUP_IDS__
};
@@ -345,6 +351,24 @@ static const struct trap_bits coarse_trap_bits[] = {
		.mask		= MDCR_EL2_TDCC,
		.behaviour	= BEHAVE_FORWARD_ANY,
	},
	[CGT_CPACR_E0POE] = {
		.index		= CPTR_EL2,
		.value		= CPACR_ELx_E0POE,
		.mask		= CPACR_ELx_E0POE,
		.behaviour	= BEHAVE_FORWARD_ANY,
	},
	[CGT_CPTR_TAM] = {
		.index		= CPTR_EL2,
		.value		= CPTR_EL2_TAM,
		.mask		= CPTR_EL2_TAM,
		.behaviour	= BEHAVE_FORWARD_ANY,
	},
	[CGT_CPTR_TCPAC] = {
		.index		= CPTR_EL2,
		.value		= CPTR_EL2_TCPAC,
		.mask		= CPTR_EL2_TCPAC,
		.behaviour	= BEHAVE_FORWARD_ANY,
	},
};

#define MCB(id, ...)						\
@@ -410,12 +434,26 @@ static enum trap_behaviour check_cnthctl_el1pten(struct kvm_vcpu *vcpu)
	return BEHAVE_FORWARD_ANY;
}

static enum trap_behaviour check_cptr_tta(struct kvm_vcpu *vcpu)
{
	u64 val = __vcpu_sys_reg(vcpu, CPTR_EL2);

	if (!vcpu_el2_e2h_is_set(vcpu))
		val = translate_cptr_el2_to_cpacr_el1(val);

	if (val & CPACR_ELx_TTA)
		return BEHAVE_FORWARD_ANY;

	return BEHAVE_HANDLE_LOCALLY;
}

#define CCC(id, fn)				\
	[id - __COMPLEX_CONDITIONS__] = fn

static const complex_condition_check ccc[] = {
	CCC(CGT_CNTHCTL_EL1PCTEN, check_cnthctl_el1pcten),
	CCC(CGT_CNTHCTL_EL1PTEN, check_cnthctl_el1pten),
	CCC(CGT_CPTR_TTA, check_cptr_tta),
};

/*
@@ -1000,6 +1038,59 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
	SR_TRAP(SYS_TRBPTR_EL1, 	CGT_MDCR_E2TB),
	SR_TRAP(SYS_TRBSR_EL1, 		CGT_MDCR_E2TB),
	SR_TRAP(SYS_TRBTRG_EL1,		CGT_MDCR_E2TB),
	SR_TRAP(SYS_CPACR_EL1,		CGT_CPTR_TCPAC),
	SR_TRAP(SYS_AMUSERENR_EL0,	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMCFGR_EL0,		CGT_CPTR_TAM),
	SR_TRAP(SYS_AMCGCR_EL0,		CGT_CPTR_TAM),
	SR_TRAP(SYS_AMCNTENCLR0_EL0,	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMCNTENCLR1_EL0,	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMCNTENSET0_EL0,	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMCNTENSET1_EL0,	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMCR_EL0,		CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR0_EL0(0),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR0_EL0(1),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR0_EL0(2),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR0_EL0(3),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(0),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(1),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(2),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(3),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(4),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(5),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(6),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(7),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(8),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(9),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(10),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(11),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(12),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(13),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(14),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVCNTR1_EL0(15),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER0_EL0(0),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER0_EL0(1),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER0_EL0(2),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER0_EL0(3),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(0),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(1),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(2),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(3),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(4),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(5),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(6),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(7),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(8),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(9),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(10),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(11),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(12),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(13),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(14),	CGT_CPTR_TAM),
	SR_TRAP(SYS_AMEVTYPER1_EL0(15),	CGT_CPTR_TAM),
	SR_TRAP(SYS_POR_EL0,		CGT_CPACR_E0POE),
	/* op0=2, op1=1, and CRn<0b1000 */
	SR_RANGE_TRAP(sys_reg(2, 1, 0, 0, 0),
		      sys_reg(2, 1, 7, 15, 7), CGT_CPTR_TTA),
	SR_TRAP(SYS_CNTP_TVAL_EL0,	CGT_CNTHCTL_EL1PTEN),
	SR_TRAP(SYS_CNTP_CVAL_EL0,	CGT_CNTHCTL_EL1PTEN),
	SR_TRAP(SYS_CNTP_CTL_EL0,	CGT_CNTHCTL_EL1PTEN),