Commit 6fb75733 authored by Marc Zyngier's avatar Marc Zyngier
Browse files

KVM: arm64: nv: Add userspace and guest handling of VNCR_EL2



Plug VNCR_EL2 in the vcpu_sysreg enum, define its RES0/RES1 bits,
and make it accessible to userspace when the VM is configured to
support FEAT_NV2.

Reviewed-by: default avatarOliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20250514103501.2225951-9-maz@kernel.org


Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent ea8d3cf4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -562,6 +562,8 @@ enum vcpu_sysreg {
	VNCR(HDFGWTR_EL2),
	VNCR(HAFGRTR_EL2),

	VNCR(VNCR_EL2),

	VNCR(CNTVOFF_EL2),
	VNCR(CNTV_CVAL_EL0),
	VNCR(CNTV_CTL_EL0),
+3 −0
Original line number Diff line number Diff line
@@ -1400,6 +1400,9 @@ int kvm_init_nv_sysregs(struct kvm_vcpu *vcpu)
	res0 |= ICH_HCR_EL2_DVIM | ICH_HCR_EL2_vSGIEOICount;
	set_sysreg_masks(kvm, ICH_HCR_EL2, res0, res1);

	/* VNCR_EL2 */
	set_sysreg_masks(kvm, VNCR_EL2, VNCR_EL2_RES0, VNCR_EL2_RES1);

out:
	for (enum vcpu_sysreg sr = __SANITISED_REG_START__; sr < NR_SYS_REGS; sr++)
		(void)__vcpu_sys_reg(vcpu, sr);
+15 −9
Original line number Diff line number Diff line
@@ -2281,15 +2281,6 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu,
			"trap of EL2 register redirected to EL1");
}

#define EL2_REG(name, acc, rst, v) {		\
	SYS_DESC(SYS_##name),			\
	.access = acc,				\
	.reset = rst,				\
	.reg = name,				\
	.visibility = el2_visibility,		\
	.val = v,				\
}

#define EL2_REG_FILTERED(name, acc, rst, v, filter) {	\
	SYS_DESC(SYS_##name),			\
	.access = acc,				\
@@ -2299,6 +2290,9 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu,
	.val = v,				\
}

#define EL2_REG(name, acc, rst, v)			\
	EL2_REG_FILTERED(name, acc, rst, v, el2_visibility)

#define EL2_REG_VNCR(name, rst, v)	EL2_REG(name, bad_vncr_trap, rst, v)
#define EL2_REG_REDIR(name, rst, v)	EL2_REG(name, bad_redir_trap, rst, v)

@@ -2446,6 +2440,16 @@ static unsigned int sve_el2_visibility(const struct kvm_vcpu *vcpu,
	return __el2_visibility(vcpu, rd, sve_visibility);
}

static unsigned int vncr_el2_visibility(const struct kvm_vcpu *vcpu,
					const struct sys_reg_desc *rd)
{
	if (el2_visibility(vcpu, rd) == 0 &&
	    kvm_has_feat(vcpu->kvm, ID_AA64MMFR4_EL1, NV_frac, NV2_ONLY))
		return 0;

	return REG_HIDDEN;
}

static bool access_zcr_el2(struct kvm_vcpu *vcpu,
			   struct sys_reg_params *p,
			   const struct sys_reg_desc *r)
@@ -3263,6 +3267,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
			 tcr2_el2_visibility),
	EL2_REG_VNCR(VTTBR_EL2, reset_val, 0),
	EL2_REG_VNCR(VTCR_EL2, reset_val, 0),
	EL2_REG_FILTERED(VNCR_EL2, bad_vncr_trap, reset_val, 0,
			 vncr_el2_visibility),

	{ SYS_DESC(SYS_DACR32_EL2), undef_access, reset_unknown, DACR32_EL2 },
	EL2_REG_VNCR(HDFGRTR_EL2, reset_val, 0),