Commit 8aed168b authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvmarm-fixes-6.16-4' of...

Merge tag 'kvmarm-fixes-6.16-4' of https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD

KVM/arm64 fixes for 6.16, take #4

- Gracefully fail initialising pKVM if the interrupt controller isn't
  GICv3

- Also gracefully fail initialising pKVM if the carveout allocation
  fails

- Fix the computing of the minimum MMIO range required for the host on
  stage-2 fault

- Fix the generation of the GICv3 Maintenance Interrupt in nested mode
parents 25e8b1dd 0e02219f
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -2129,7 +2129,7 @@ static void cpu_hyp_init(void *discard)

static void cpu_hyp_uninit(void *discard)
{
	if (__this_cpu_read(kvm_hyp_initialized)) {
	if (!is_protected_kvm_enabled() && __this_cpu_read(kvm_hyp_initialized)) {
		cpu_hyp_reset();
		__this_cpu_write(kvm_hyp_initialized, 0);
	}
@@ -2345,8 +2345,13 @@ static void __init teardown_hyp_mode(void)

	free_hyp_pgds();
	for_each_possible_cpu(cpu) {
		if (per_cpu(kvm_hyp_initialized, cpu))
			continue;

		free_pages(per_cpu(kvm_arm_hyp_stack_base, cpu), NVHE_STACK_SHIFT - PAGE_SHIFT);
		free_pages(kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu], nvhe_percpu_order());

		if (!kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu])
			continue;

		if (free_sve) {
			struct cpu_sve_state *sve_state;
@@ -2354,6 +2359,9 @@ static void __init teardown_hyp_mode(void)
			sve_state = per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->sve_state;
			free_pages((unsigned long) sve_state, pkvm_host_sve_state_order());
		}

		free_pages(kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu], nvhe_percpu_order());

	}
}

+12 −8
Original line number Diff line number Diff line
@@ -479,6 +479,7 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
{
	struct kvm_mem_range cur;
	kvm_pte_t pte;
	u64 granule;
	s8 level;
	int ret;

@@ -496,20 +497,23 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
		return -EPERM;
	}

	do {
		u64 granule = kvm_granule_size(level);
	for (; level <= KVM_PGTABLE_LAST_LEVEL; level++) {
		if (!kvm_level_supports_block_mapping(level))
			continue;
		granule = kvm_granule_size(level);
		cur.start = ALIGN_DOWN(addr, granule);
		cur.end = cur.start + granule;
		level++;
	} while ((level <= KVM_PGTABLE_LAST_LEVEL) &&
			!(kvm_level_supports_block_mapping(level) &&
			  range_included(&cur, range)));

		if (!range_included(&cur, range))
			continue;
		*range = cur;

		return 0;
	}

	WARN_ON(1);

	return -EINVAL;
}

int host_stage2_idmap_locked(phys_addr_t addr, u64 size,
			     enum kvm_pgtable_prot prot)
{
+1 −3
Original line number Diff line number Diff line
@@ -401,9 +401,7 @@ void vgic_v3_nested_update_mi(struct kvm_vcpu *vcpu)
{
	bool level;

	level  = __vcpu_sys_reg(vcpu, ICH_HCR_EL2) & ICH_HCR_EL2_En;
	if (level)
		level &= vgic_v3_get_misr(vcpu);
	level = (__vcpu_sys_reg(vcpu, ICH_HCR_EL2) & ICH_HCR_EL2_En) && vgic_v3_get_misr(vcpu);
	kvm_vgic_inject_irq(vcpu->kvm, vcpu,
			    vcpu->kvm->arch.vgic.mi_intid, level, vcpu);
}