Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a6cd3ba authored by Radim Krčmář's avatar Radim Krčmář
Browse files
KVM/ARM Fixes for v4.6-rc4

Addresses:
 - Wrong indentation in the PMU code from the merge window
 - A long-time bug occuring with running ntpd on the host, candidate for stable
 - Properly handle (and warn about) the unsupported configuration of running on
   systems with less than 40 bits of PA space
 - More fixes to the PM and hotplug notifier stuff from the merge window
parents 3d8e15dd 06a71a24
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -1112,10 +1112,17 @@ static void __init hyp_cpu_pm_init(void)
{
	cpu_pm_register_notifier(&hyp_init_cpu_pm_nb);
}
static void __init hyp_cpu_pm_exit(void)
{
	cpu_pm_unregister_notifier(&hyp_init_cpu_pm_nb);
}
#else
static inline void hyp_cpu_pm_init(void)
{
}
static inline void hyp_cpu_pm_exit(void)
{
}
#endif

static void teardown_common_resources(void)
@@ -1141,9 +1148,7 @@ static int init_subsystems(void)
	/*
	 * Register CPU Hotplug notifier
	 */
	cpu_notifier_register_begin();
	err = __register_cpu_notifier(&hyp_init_cpu_nb);
	cpu_notifier_register_done();
	err = register_cpu_notifier(&hyp_init_cpu_nb);
	if (err) {
		kvm_err("Cannot register KVM init CPU notifier (%d)\n", err);
		return err;
@@ -1193,6 +1198,8 @@ static void teardown_hyp_mode(void)
	free_hyp_pgds();
	for_each_possible_cpu(cpu)
		free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
	unregister_cpu_notifier(&hyp_init_cpu_nb);
	hyp_cpu_pm_exit();
}

static int init_vhe_mode(void)
+2 −4
Original line number Diff line number Diff line
@@ -151,8 +151,7 @@
 */
#define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_64K | VTCR_EL2_SH0_INNER | \
				 VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \
				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B | \
				 VTCR_EL2_RES1)
				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_RES1)
#define VTTBR_X		(38 - VTCR_EL2_T0SZ_40B)
#else
/*
@@ -163,8 +162,7 @@
 */
#define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_4K | VTCR_EL2_SH0_INNER | \
				 VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \
				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B | \
				 VTCR_EL2_RES1)
				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_RES1)
#define VTTBR_X		(37 - VTCR_EL2_T0SZ_40B)
#endif

+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ extern void __vgic_v3_init_lrs(void);

extern u32 __kvm_get_mdcr_el2(void);

extern void __init_stage2_translation(void);
extern u32 __init_stage2_translation(void);

#endif

+4 −3
Original line number Diff line number Diff line
@@ -369,11 +369,12 @@ int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
			       struct kvm_device_attr *attr);

/* #define kvm_call_hyp(f, ...) __kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__) */

static inline void __cpu_init_stage2(void)
{
	kvm_call_hyp(__init_stage2_translation);
	u32 parange = kvm_call_hyp(__init_stage2_translation);

	WARN_ONCE(parange < 40,
		  "PARange is %d bits, unsupported configuration!", parange);
}

#endif /* __ARM64_KVM_HOST_H__ */
+37 −2
Original line number Diff line number Diff line
@@ -20,9 +20,10 @@
#include <asm/kvm_asm.h>
#include <asm/kvm_hyp.h>

void __hyp_text __init_stage2_translation(void)
u32 __hyp_text __init_stage2_translation(void)
{
	u64 val = VTCR_EL2_FLAGS;
	u64 parange;
	u64 tmp;

	/*
@@ -30,7 +31,39 @@ void __hyp_text __init_stage2_translation(void)
	 * bits in VTCR_EL2. Amusingly, the PARange is 4 bits, while
	 * PS is only 3. Fortunately, bit 19 is RES0 in VTCR_EL2...
	 */
	val |= (read_sysreg(id_aa64mmfr0_el1) & 7) << 16;
	parange = read_sysreg(id_aa64mmfr0_el1) & 7;
	val |= parange << 16;

	/* Compute the actual PARange... */
	switch (parange) {
	case 0:
		parange = 32;
		break;
	case 1:
		parange = 36;
		break;
	case 2:
		parange = 40;
		break;
	case 3:
		parange = 42;
		break;
	case 4:
		parange = 44;
		break;
	case 5:
	default:
		parange = 48;
		break;
	}

	/*
	 * ... and clamp it to 40 bits, unless we have some braindead
	 * HW that implements less than that. In all cases, we'll
	 * return that value for the rest of the kernel to decide what
	 * to do.
	 */
	val |= 64 - (parange > 40 ? 40 : parange);

	/*
	 * Read the VMIDBits bits from ID_AA64MMFR1_EL1 and set the VS
@@ -42,4 +75,6 @@ void __hyp_text __init_stage2_translation(void)
			VTCR_EL2_VS_8BIT;

	write_sysreg(val, vtcr_el2);

	return parange;
}
Loading