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

Commit b33c8732 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvm-arm-fixes-for-v4.14' of...

Merge tag 'kvm-arm-fixes-for-v4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into kvm-master

KVM/ARM Fixes for v4.14

 - Fixes a number of issues with saving/restoring the ITS
 - Fixes a bug in KVM/ARM when branch profiling is enabled in Hyp mode
 - Fixes an emulation bug for 32-bit guests when injecting aborts
  - Fixes a failure to check if a kmalloc succeeds in the ITS emulation
parents 4191db26 c2385eaa
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -227,7 +227,7 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
	u32 return_offset = (is_thumb) ? 2 : 4;

	kvm_update_psr(vcpu, UND_MODE);
	*vcpu_reg(vcpu, 14) = *vcpu_pc(vcpu) - return_offset;
	*vcpu_reg(vcpu, 14) = *vcpu_pc(vcpu) + return_offset;

	/* Branch to exception vector */
	*vcpu_pc(vcpu) = exc_vector_base(vcpu) + vect_offset;
@@ -239,10 +239,8 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
 */
static void inject_abt(struct kvm_vcpu *vcpu, bool is_pabt, unsigned long addr)
{
	unsigned long cpsr = *vcpu_cpsr(vcpu);
	bool is_thumb = (cpsr & PSR_T_BIT);
	u32 vect_offset;
	u32 return_offset = (is_thumb) ? 4 : 0;
	u32 return_offset = (is_pabt) ? 4 : 8;
	bool is_lpae;

	kvm_update_psr(vcpu, ABT_MODE);
+1 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
# Makefile for Kernel-based Virtual Machine module, HYP part
#

ccflags-y += -fno-stack-protector
ccflags-y += -fno-stack-protector -DDISABLE_BRANCH_PROFILING

KVM=../../../../virt/kvm

+1 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
# Makefile for Kernel-based Virtual Machine module, HYP part
#

ccflags-y += -fno-stack-protector
ccflags-y += -fno-stack-protector -DDISABLE_BRANCH_PROFILING

KVM=../../../../virt/kvm

+15 −1
Original line number Diff line number Diff line
@@ -33,12 +33,26 @@
#define LOWER_EL_AArch64_VECTOR		0x400
#define LOWER_EL_AArch32_VECTOR		0x600

/*
 * Table taken from ARMv8 ARM DDI0487B-B, table G1-10.
 */
static const u8 return_offsets[8][2] = {
	[0] = { 0, 0 },		/* Reset, unused */
	[1] = { 4, 2 },		/* Undefined */
	[2] = { 0, 0 },		/* SVC, unused */
	[3] = { 4, 4 },		/* Prefetch abort */
	[4] = { 8, 8 },		/* Data abort */
	[5] = { 0, 0 },		/* HVC, unused */
	[6] = { 4, 4 },		/* IRQ, unused */
	[7] = { 4, 4 },		/* FIQ, unused */
};

static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)
{
	unsigned long cpsr;
	unsigned long new_spsr_value = *vcpu_cpsr(vcpu);
	bool is_thumb = (new_spsr_value & COMPAT_PSR_T_BIT);
	u32 return_offset = (is_thumb) ? 4 : 0;
	u32 return_offset = return_offsets[vect_offset >> 2][is_thumb];
	u32 sctlr = vcpu_cp15(vcpu, c1_SCTLR);

	cpsr = mode | COMPAT_PSR_I_BIT;
+14 −17
Original line number Diff line number Diff line
@@ -1326,21 +1326,12 @@ static void teardown_hyp_mode(void)
{
	int cpu;

	if (is_kernel_in_hyp_mode())
		return;

	free_hyp_pgds();
	for_each_possible_cpu(cpu)
		free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
	hyp_cpu_pm_exit();
}

static int init_vhe_mode(void)
{
	kvm_info("VHE mode initialized successfully\n");
	return 0;
}

/**
 * Inits Hyp-mode on all online CPUs
 */
@@ -1421,8 +1412,6 @@ static int init_hyp_mode(void)
		}
	}

	kvm_info("Hyp mode initialized successfully\n");

	return 0;

out_err:
@@ -1456,6 +1445,7 @@ int kvm_arch_init(void *opaque)
{
	int err;
	int ret, cpu;
	bool in_hyp_mode;

	if (!is_hyp_mode_available()) {
		kvm_err("HYP mode not available\n");
@@ -1474,20 +1464,27 @@ int kvm_arch_init(void *opaque)
	if (err)
		return err;

	if (is_kernel_in_hyp_mode())
		err = init_vhe_mode();
	else
	in_hyp_mode = is_kernel_in_hyp_mode();

	if (!in_hyp_mode) {
		err = init_hyp_mode();
		if (err)
			goto out_err;
	}

	err = init_subsystems();
	if (err)
		goto out_hyp;

	if (in_hyp_mode)
		kvm_info("VHE mode initialized successfully\n");
	else
		kvm_info("Hyp mode initialized successfully\n");

	return 0;

out_hyp:
	if (!in_hyp_mode)
		teardown_hyp_mode();
out_err:
	teardown_common_resources();
Loading