Commit 699116c4 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvmarm-fixes-5.10-1' of...

Merge tag 'kvmarm-fixes-5.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD

KVM/arm64 fixes for 5.10, take #1

- Force PTE mapping on device pages provided via VFIO
- Fix detection of cacheable mapping at S2
- Fallback to PMD/PTE mappings for composite huge pages
- Fix accounting of Stage-2 PGD allocation
- Fix AArch32 handling of some of the debug registers
- Simplify host HYP entry
- Fix stray pointer conversion on nVHE TLB invalidation
- Fix initialization of the nVHE code
- Simplify handling of capabilities exposed to HYP
- Nuke VCPUs caught using a forbidden AArch32 EL0
parents 5a169bf0 22f55384
Loading
Loading
Loading
Loading
+31 −9
Original line number Diff line number Diff line
@@ -375,6 +375,23 @@ cpucap_multi_entry_cap_matches(const struct arm64_cpu_capabilities *entry,
	return false;
}

static __always_inline bool is_vhe_hyp_code(void)
{
	/* Only defined for code run in VHE hyp context */
	return __is_defined(__KVM_VHE_HYPERVISOR__);
}

static __always_inline bool is_nvhe_hyp_code(void)
{
	/* Only defined for code run in NVHE hyp context */
	return __is_defined(__KVM_NVHE_HYPERVISOR__);
}

static __always_inline bool is_hyp_code(void)
{
	return is_vhe_hyp_code() || is_nvhe_hyp_code();
}

extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS];
extern struct static_key_false arm64_const_caps_ready;
@@ -428,35 +445,40 @@ static __always_inline bool __cpus_have_const_cap(int num)
}

/*
 * Test for a capability, possibly with a runtime check.
 * Test for a capability without a runtime check.
 *
 * Before capabilities are finalized, this behaves as cpus_have_cap().
 * Before capabilities are finalized, this will BUG().
 * After capabilities are finalized, this is patched to avoid a runtime check.
 *
 * @num must be a compile-time constant.
 */
static __always_inline bool cpus_have_const_cap(int num)
static __always_inline bool cpus_have_final_cap(int num)
{
	if (system_capabilities_finalized())
		return __cpus_have_const_cap(num);
	else
		return cpus_have_cap(num);
		BUG();
}

/*
 * Test for a capability without a runtime check.
 * Test for a capability, possibly with a runtime check for non-hyp code.
 *
 * Before capabilities are finalized, this will BUG().
 * For hyp code, this behaves the same as cpus_have_final_cap().
 *
 * For non-hyp code:
 * Before capabilities are finalized, this behaves as cpus_have_cap().
 * After capabilities are finalized, this is patched to avoid a runtime check.
 *
 * @num must be a compile-time constant.
 */
static __always_inline bool cpus_have_final_cap(int num)
static __always_inline bool cpus_have_const_cap(int num)
{
	if (system_capabilities_finalized())
	if (is_hyp_code())
		return cpus_have_final_cap(num);
	else if (system_capabilities_finalized())
		return __cpus_have_const_cap(num);
	else
		BUG();
		return cpus_have_cap(num);
}

static inline void cpus_set_cap(unsigned int num)
+1 −0
Original line number Diff line number Diff line
@@ -239,6 +239,7 @@ enum vcpu_sysreg {
#define cp14_DBGWCR0	(DBGWCR0_EL1 * 2)
#define cp14_DBGWVR0	(DBGWVR0_EL1 * 2)
#define cp14_DBGDCCINT	(MDCCINT_EL1 * 2)
#define cp14_DBGVCR	(DBGVCR32_EL2 * 2)

#define NR_COPRO_REGS	(NR_SYS_REGS * 2)

+4 −5
Original line number Diff line number Diff line
@@ -86,13 +86,12 @@ static inline bool is_kernel_in_hyp_mode(void)
static __always_inline bool has_vhe(void)
{
	/*
	 * The following macros are defined for code specic to VHE/nVHE.
	 * If has_vhe() is inlined into those compilation units, it can
	 * be determined statically. Otherwise fall back to caps.
	 * Code only run in VHE/NVHE hyp context can assume VHE is present or
	 * absent. Otherwise fall back to caps.
	 */
	if (__is_defined(__KVM_VHE_HYPERVISOR__))
	if (is_vhe_hyp_code())
		return true;
	else if (__is_defined(__KVM_NVHE_HYPERVISOR__))
	else if (is_nvhe_hyp_code())
		return false;
	else
		return cpus_have_final_cap(ARM64_HAS_VIRT_HOST_EXTN);
+0 −1
Original line number Diff line number Diff line
@@ -87,7 +87,6 @@ KVM_NVHE_ALIAS(__icache_flags);
/* Kernel symbols needed for cpus_have_final/const_caps checks. */
KVM_NVHE_ALIAS(arm64_const_caps_ready);
KVM_NVHE_ALIAS(cpu_hwcap_keys);
KVM_NVHE_ALIAS(cpu_hwcaps);

/* Static keys which are set if a vGIC trap should be handled in hyp. */
KVM_NVHE_ALIAS(vgic_v2_cpuif_trap);
+19 −0
Original line number Diff line number Diff line
@@ -808,6 +808,25 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)

		preempt_enable();

		/*
		 * The ARMv8 architecture doesn't give the hypervisor
		 * a mechanism to prevent a guest from dropping to AArch32 EL0
		 * if implemented by the CPU. If we spot the guest in such
		 * state and that we decided it wasn't supposed to do so (like
		 * with the asymmetric AArch32 case), return to userspace with
		 * a fatal error.
		 */
		if (!system_supports_32bit_el0() && vcpu_mode_is_32bit(vcpu)) {
			/*
			 * As we have caught the guest red-handed, decide that
			 * it isn't fit for purpose anymore by making the vcpu
			 * invalid. The VMM can try and fix it by issuing  a
			 * KVM_ARM_VCPU_INIT if it really wants to.
			 */
			vcpu->arch.target = -1;
			ret = ARM_EXCEPTION_IL;
		}

		ret = handle_exit(vcpu, ret);
	}

Loading