Commit e880b16e authored by Marc Zyngier's avatar Marc Zyngier
Browse files

Merge branch kvm-arm64/pkvm-fixed-features-6.14 into kvmarm-master/next



* kvm-arm64/pkvm-fixed-features-6.14: (24 commits)
  : .
  : Complete rework of the pKVM handling of features, catching up
  : with the rest of the code deals with it these days.
  : Patches courtesy of Fuad Tabba. From the cover letter:
  :
  : "This patch series uses the vm's feature id registers to track the
  : supported features, a framework similar to nested virt to set the
  : trap values, and removes the need to store cptr_el2 per vcpu in
  : favor of setting its value when traps are activated, as VHE mode
  : does."
  :
  : This branch drags the arm64/for-next/cpufeature branch to solve
  : ugly conflicts in -next.
  : .
  KVM: arm64: Fix FEAT_MTE in pKVM
  KVM: arm64: Use kvm_vcpu_has_feature() directly for struct kvm
  KVM: arm64: Convert the SVE guest vcpu flag to a vm flag
  KVM: arm64: Remove PtrAuth guest vcpu flag
  KVM: arm64: Fix the value of the CPTR_EL2 RES1 bitmask for nVHE
  KVM: arm64: Refactor kvm_reset_cptr_el2()
  KVM: arm64: Calculate cptr_el2 traps on activating traps
  KVM: arm64: Remove redundant setting of HCR_EL2 trap bit
  KVM: arm64: Remove fixed_config.h header
  KVM: arm64: Rework specifying restricted features for protected VMs
  KVM: arm64: Set protected VM traps based on its view of feature registers
  KVM: arm64: Fix RAS trapping in pKVM for protected VMs
  KVM: arm64: Initialize feature id registers for protected VMs
  KVM: arm64: Use KVM extension checks for allowed protected VM capabilities
  KVM: arm64: Remove KVM_ARM_VCPU_POWER_OFF from protected VMs allowed features in pKVM
  KVM: arm64: Move checking protected vcpu features to a separate function
  KVM: arm64: Group setting traps for protected VMs by control register
  KVM: arm64: Consolidate allowed and restricted VM feature checks
  arm64/sysreg: Get rid of CPACR_ELx SysregFields
  arm64/sysreg: Convert *_EL12 accessors to Mapping
  ...

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>

# Conflicts:
#	arch/arm64/kvm/fpsimd.c
#	arch/arm64/kvm/hyp/nvhe/pkvm.c
parents d0670128 4e26de25
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@ cpucap_is_possible(const unsigned int cap)
		return IS_ENABLED(CONFIG_ARM64_POE);
	case ARM64_HAS_GCS:
		return IS_ENABLED(CONFIG_ARM64_GCS);
	case ARM64_HAFT:
		return IS_ENABLED(CONFIG_ARM64_HAFT);
	case ARM64_UNMAP_KERNEL_AT_EL0:
		return IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0);
	case ARM64_WORKAROUND_843419:
+1 −2
Original line number Diff line number Diff line
@@ -852,8 +852,7 @@ static inline bool system_supports_gcs(void)

static inline bool system_supports_haft(void)
{
	return IS_ENABLED(CONFIG_ARM64_HAFT) &&
		cpus_have_final_cap(ARM64_HAFT);
	return cpus_have_final_cap(ARM64_HAFT);
}

static __always_inline bool system_supports_mpam(void)
+3 −3
Original line number Diff line number Diff line
@@ -154,7 +154,7 @@
/* Coprocessor traps */
.macro __init_el2_cptr
	__check_hvhe .LnVHE_\@, x1
	mov	x0, #CPACR_ELx_FPEN
	mov	x0, #CPACR_EL1_FPEN
	msr	cpacr_el1, x0
	b	.Lskip_set_cptr_\@
.LnVHE_\@:
@@ -332,7 +332,7 @@

	// (h)VHE case
	mrs	x0, cpacr_el1			// Disable SVE traps
	orr	x0, x0, #CPACR_ELx_ZEN
	orr	x0, x0, #CPACR_EL1_ZEN
	msr	cpacr_el1, x0
	b	.Lskip_set_cptr_\@

@@ -353,7 +353,7 @@

	// (h)VHE case
	mrs	x0, cpacr_el1			// Disable SME traps
	orr	x0, x0, #CPACR_ELx_SMEN
	orr	x0, x0, #CPACR_EL1_SMEN
	msr	cpacr_el1, x0
	b	.Lskip_set_cptr_sme_\@

+1 −3
Original line number Diff line number Diff line
@@ -300,7 +300,7 @@
#define CPTR_EL2_TSM	(1 << 12)
#define CPTR_EL2_TFP	(1 << CPTR_EL2_TFP_SHIFT)
#define CPTR_EL2_TZ	(1 << 8)
#define CPTR_NVHE_EL2_RES1	0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */
#define CPTR_NVHE_EL2_RES1	(BIT(13) | BIT(9) | GENMASK(7, 0))
#define CPTR_NVHE_EL2_RES0	(GENMASK(63, 32) |	\
				 GENMASK(29, 21) |	\
				 GENMASK(19, 14) |	\
@@ -391,8 +391,6 @@
	ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \
	ECN(BKPT32), ECN(VECTOR32), ECN(BRK64), ECN(ERET)

#define CPACR_EL1_TTA		(1 << 28)

#define kvm_mode_names				\
	{ PSR_MODE_EL0t,	"EL0t" },	\
	{ PSR_MODE_EL1t,	"EL1t" },	\
+32 −37
Original line number Diff line number Diff line
@@ -556,13 +556,13 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
	({								\
		u64 cptr = 0;						\
									\
		if ((set) & CPACR_ELx_FPEN)				\
		if ((set) & CPACR_EL1_FPEN)				\
			cptr |= CPTR_EL2_TFP;				\
		if ((set) & CPACR_ELx_ZEN)				\
		if ((set) & CPACR_EL1_ZEN)				\
			cptr |= CPTR_EL2_TZ;				\
		if ((set) & CPACR_ELx_SMEN)				\
		if ((set) & CPACR_EL1_SMEN)				\
			cptr |= CPTR_EL2_TSM;				\
		if ((clr) & CPACR_ELx_TTA)				\
		if ((clr) & CPACR_EL1_TTA)				\
			cptr |= CPTR_EL2_TTA;				\
		if ((clr) & CPTR_EL2_TAM)				\
			cptr |= CPTR_EL2_TAM;				\
@@ -576,13 +576,13 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
	({								\
		u64 cptr = 0;						\
									\
		if ((clr) & CPACR_ELx_FPEN)				\
		if ((clr) & CPACR_EL1_FPEN)				\
			cptr |= CPTR_EL2_TFP;				\
		if ((clr) & CPACR_ELx_ZEN)				\
		if ((clr) & CPACR_EL1_ZEN)				\
			cptr |= CPTR_EL2_TZ;				\
		if ((clr) & CPACR_ELx_SMEN)				\
		if ((clr) & CPACR_EL1_SMEN)				\
			cptr |= CPTR_EL2_TSM;				\
		if ((set) & CPACR_ELx_TTA)				\
		if ((set) & CPACR_EL1_TTA)				\
			cptr |= CPTR_EL2_TTA;				\
		if ((set) & CPTR_EL2_TAM)				\
			cptr |= CPTR_EL2_TAM;				\
@@ -595,13 +595,13 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
#define cpacr_clear_set(clr, set)					\
	do {								\
		BUILD_BUG_ON((set) & CPTR_VHE_EL2_RES0);		\
		BUILD_BUG_ON((clr) & CPACR_ELx_E0POE);			\
		__build_check_all_or_none((clr), CPACR_ELx_FPEN);	\
		__build_check_all_or_none((set), CPACR_ELx_FPEN);	\
		__build_check_all_or_none((clr), CPACR_ELx_ZEN);	\
		__build_check_all_or_none((set), CPACR_ELx_ZEN);	\
		__build_check_all_or_none((clr), CPACR_ELx_SMEN);	\
		__build_check_all_or_none((set), CPACR_ELx_SMEN);	\
		BUILD_BUG_ON((clr) & CPACR_EL1_E0POE);			\
		__build_check_all_or_none((clr), CPACR_EL1_FPEN);	\
		__build_check_all_or_none((set), CPACR_EL1_FPEN);	\
		__build_check_all_or_none((clr), CPACR_EL1_ZEN);	\
		__build_check_all_or_none((set), CPACR_EL1_ZEN);	\
		__build_check_all_or_none((clr), CPACR_EL1_SMEN);	\
		__build_check_all_or_none((set), CPACR_EL1_SMEN);	\
									\
		if (has_vhe() || has_hvhe())				\
			sysreg_clear_set(cpacr_el1, clr, set);		\
@@ -619,40 +619,40 @@ static __always_inline void kvm_write_cptr_el2(u64 val)
		write_sysreg(val, cptr_el2);
}

static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu)
/* Resets the value of cptr_el2 when returning to the host. */
static __always_inline void __kvm_reset_cptr_el2(struct kvm *kvm)
{
	u64 val;

	if (has_vhe()) {
		val = (CPACR_ELx_FPEN | CPACR_EL1_ZEN_EL1EN);
		val = (CPACR_EL1_FPEN | CPACR_EL1_ZEN_EL1EN);
		if (cpus_have_final_cap(ARM64_SME))
			val |= CPACR_EL1_SMEN_EL1EN;
	} else if (has_hvhe()) {
		val = CPACR_ELx_FPEN;
		val = CPACR_EL1_FPEN;

		if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
			val |= CPACR_ELx_ZEN;
		if (!kvm_has_sve(kvm) || !guest_owns_fp_regs())
			val |= CPACR_EL1_ZEN;
		if (cpus_have_final_cap(ARM64_SME))
			val |= CPACR_ELx_SMEN;
			val |= CPACR_EL1_SMEN;
	} else {
		val = CPTR_NVHE_EL2_RES1;

		if (vcpu_has_sve(vcpu) && guest_owns_fp_regs())
		if (kvm_has_sve(kvm) && guest_owns_fp_regs())
			val |= CPTR_EL2_TZ;
		if (cpus_have_final_cap(ARM64_SME))
			val &= ~CPTR_EL2_TSM;
	}

	return val;
		if (!cpus_have_final_cap(ARM64_SME))
			val |= CPTR_EL2_TSM;
	}

static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
{
	u64 val = kvm_get_reset_cptr_el2(vcpu);

	kvm_write_cptr_el2(val);
}

#ifdef __KVM_NVHE_HYPERVISOR__
#define kvm_reset_cptr_el2(v)	__kvm_reset_cptr_el2(kern_hyp_va((v)->kvm))
#else
#define kvm_reset_cptr_el2(v)	__kvm_reset_cptr_el2((v)->kvm)
#endif

/*
 * Returns a 'sanitised' view of CPTR_EL2, translating from nVHE to the VHE
 * format if E2H isn't set.
@@ -685,7 +685,7 @@ static inline bool ____cptr_xen_trap_enabled(const struct kvm_vcpu *vcpu,
#define __guest_hyp_cptr_xen_trap_enabled(vcpu, xen)				\
	(!vcpu_has_nv(vcpu) ? false :						\
	 ____cptr_xen_trap_enabled(vcpu,					\
				   SYS_FIELD_GET(CPACR_ELx, xen,		\
				   SYS_FIELD_GET(CPACR_EL1, xen,		\
						 vcpu_sanitised_cptr_el2(vcpu))))

static inline bool guest_hyp_fpsimd_traps_enabled(const struct kvm_vcpu *vcpu)
@@ -697,9 +697,4 @@ static inline bool guest_hyp_sve_traps_enabled(const struct kvm_vcpu *vcpu)
{
	return __guest_hyp_cptr_xen_trap_enabled(vcpu, ZEN);
}

static inline void kvm_vcpu_enable_ptrauth(struct kvm_vcpu *vcpu)
{
	vcpu_set_flag(vcpu, GUEST_HAS_PTRAUTH);
}
#endif /* __ARM64_KVM_EMULATE_H__ */
Loading