Commit 4563243e authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull kvm fixes from Paolo Bonzini:
 "ARM64:

   - Fix pKVM error path on init, making sure we do not change critical
     system registers as we're about to fail

   - Make sure that the host's vector length is at capped by a value
     common to all CPUs

   - Fix kvm_has_feat*() handling of "negative" features, as the current
     code is pretty broken

   - Promote Joey to the status of official reviewer, while James steps
     down -- hopefully only temporarly

  x86:

   - Fix compilation with KVM_INTEL=KVM_AMD=n

   - Fix disabling KVM_X86_QUIRK_SLOT_ZAP_ALL when shadow MMU is in use

  Selftests:

   - Fix compilation on non-x86 architectures"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  x86/reboot: emergency callbacks are now registered by common KVM code
  KVM: x86: leave kvm.ko out of the build if no vendor module is requested
  KVM: x86/mmu: fix KVM_X86_QUIRK_SLOT_ZAP_ALL for shadow MMU
  KVM: arm64: Fix kvm_has_feat*() handling of negative features
  KVM: selftests: Fix build on architectures other than x86_64
  KVM: arm64: Another reviewer reshuffle
  KVM: arm64: Constrain the host to the maximum shared SVE VL with pKVM
  KVM: arm64: Fix __pkvm_init_vcpu cptr_el2 error path
parents b3ce5c30 c8d430db
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -12463,7 +12463,7 @@ F: virt/kvm/*
KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64)
M:	Marc Zyngier <maz@kernel.org>
M:	Oliver Upton <oliver.upton@linux.dev>
R:	James Morse <james.morse@arm.com>
R:	Joey Gouly <joey.gouly@arm.com>
R:	Suzuki K Poulose <suzuki.poulose@arm.com>
R:	Zenghui Yu <yuzenghui@huawei.com>
L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+13 −12
Original line number Diff line number Diff line
@@ -1441,11 +1441,6 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
		sign_extend64(__val, id##_##fld##_WIDTH - 1);		\
	})

#define expand_field_sign(id, fld, val)					\
	(id##_##fld##_SIGNED ?						\
	 __expand_field_sign_signed(id, fld, val) :			\
	 __expand_field_sign_unsigned(id, fld, val))

#define get_idreg_field_unsigned(kvm, id, fld)				\
	({								\
		u64 __val = kvm_read_vm_id_reg((kvm), SYS_##id);	\
@@ -1461,20 +1456,26 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
#define get_idreg_field_enum(kvm, id, fld)				\
	get_idreg_field_unsigned(kvm, id, fld)

#define get_idreg_field(kvm, id, fld)					\
#define kvm_cmp_feat_signed(kvm, id, fld, op, limit)			\
	(get_idreg_field_signed((kvm), id, fld) op __expand_field_sign_signed(id, fld, limit))

#define kvm_cmp_feat_unsigned(kvm, id, fld, op, limit)			\
	(get_idreg_field_unsigned((kvm), id, fld) op __expand_field_sign_unsigned(id, fld, limit))

#define kvm_cmp_feat(kvm, id, fld, op, limit)				\
	(id##_##fld##_SIGNED ?						\
	 get_idreg_field_signed(kvm, id, fld) :				\
	 get_idreg_field_unsigned(kvm, id, fld))
	 kvm_cmp_feat_signed(kvm, id, fld, op, limit) :			\
	 kvm_cmp_feat_unsigned(kvm, id, fld, op, limit))

#define kvm_has_feat(kvm, id, fld, limit)				\
	(get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, limit))
	kvm_cmp_feat(kvm, id, fld, >=, limit)

#define kvm_has_feat_enum(kvm, id, fld, val)				\
	(get_idreg_field_unsigned((kvm), id, fld) == __expand_field_sign_unsigned(id, fld, val))
	kvm_cmp_feat_unsigned(kvm, id, fld, ==, val)

#define kvm_has_feat_range(kvm, id, fld, min, max)			\
	(get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, min) && \
	 get_idreg_field((kvm), id, fld) <= expand_field_sign(id, fld, max))
	(kvm_cmp_feat(kvm, id, fld, >=, min) &&				\
	kvm_cmp_feat(kvm, id, fld, <=, max))

/* Check for a given level of PAuth support */
#define kvm_has_pauth(k, l)						\
+1 −1
Original line number Diff line number Diff line
@@ -338,7 +338,7 @@ static inline void __hyp_sve_save_host(void)
	struct cpu_sve_state *sve_state = *host_data_ptr(sve_state);

	sve_state->zcr_el1 = read_sysreg_el1(SYS_ZCR);
	write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2);
	write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2);
	__sve_save_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl),
			 &sve_state->fpsr,
			 true);
+7 −5
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ static void __hyp_sve_save_guest(struct kvm_vcpu *vcpu)
	 */
	sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2);
	__sve_save_state(vcpu_sve_pffr(vcpu), &vcpu->arch.ctxt.fp_regs.fpsr, true);
	write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2);
	write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2);
}

static void __hyp_sve_restore_host(void)
@@ -45,10 +45,11 @@ static void __hyp_sve_restore_host(void)
	 * the host. The layout of the data when saving the sve state depends
	 * on the VL, so use a consistent (i.e., the maximum) host VL.
	 *
	 * Setting ZCR_EL2 to ZCR_ELx_LEN_MASK sets the effective length
	 * supported by the system (or limited at EL3).
	 * Note that this constrains the PE to the maximum shared VL
	 * that was discovered, if we wish to use larger VLs this will
	 * need to be revisited.
	 */
	write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2);
	write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2);
	__sve_restore_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl),
			    &sve_state->fpsr,
			    true);
@@ -488,7 +489,8 @@ void handle_trap(struct kvm_cpu_context *host_ctxt)
	case ESR_ELx_EC_SVE:
		cpacr_clear_set(0, CPACR_ELx_ZEN);
		isb();
		sve_cond_update_zcr_vq(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2);
		sve_cond_update_zcr_vq(sve_vq_from_vl(kvm_host_sve_max_vl) - 1,
				       SYS_ZCR_EL2);
		break;
	case ESR_ELx_EC_IABT_LOW:
	case ESR_ELx_EC_DABT_LOW:
+4 −2
Original line number Diff line number Diff line
@@ -574,12 +574,14 @@ int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu,
unlock:
	hyp_spin_unlock(&vm_table_lock);

	if (ret)
	if (ret) {
		unmap_donated_memory(hyp_vcpu, sizeof(*hyp_vcpu));
		return ret;
	}

	hyp_vcpu->vcpu.arch.cptr_el2 = kvm_get_reset_cptr_el2(&hyp_vcpu->vcpu);

	return ret;
	return 0;
}

static void
Loading