Commit a8a8dcbd authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull arm64 kvm fixes from Catalin Marinas:

 - Don't drop references on LPIs that weren't visited by the vgic-debug
   iterator

 - Cure lock ordering issue when unregistering vgic redistributors

 - Fix for misaligned stage-2 mappings when VMs are backed by hugetlb
   pages

 - Treat SGI registers as UNDEFINED if a VM hasn't been configured for
   GICv3

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  KVM: arm64: Make ICC_*SGI*_EL1 undef in the absence of a vGICv3
  KVM: arm64: Ensure canonical IPA is hugepage-aligned when handling fault
  KVM: arm64: vgic: Don't hold config_lock while unregistering redistributors
  KVM: arm64: vgic-debug: Don't put unmarked LPIs
parents 60f0560f 75c8f387
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -1540,8 +1540,15 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
		vma_pagesize = min(vma_pagesize, (long)max_map_size);
	}

	if (vma_pagesize == PMD_SIZE || vma_pagesize == PUD_SIZE)
	/*
	 * Both the canonical IPA and fault IPA must be hugepage-aligned to
	 * ensure we find the right PFN and lay down the mapping in the right
	 * place.
	 */
	if (vma_pagesize == PMD_SIZE || vma_pagesize == PUD_SIZE) {
		fault_ipa &= ~(vma_pagesize - 1);
		ipa &= ~(vma_pagesize - 1);
	}

	gfn = ipa >> PAGE_SHIFT;
	mte_allowed = kvm_vma_mte_allowed(vma);
+6 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include <trace/events/kvm.h>

#include "sys_regs.h"
#include "vgic/vgic.h"

#include "trace.h"

@@ -435,6 +436,11 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
{
	bool g1;

	if (!kvm_has_gicv3(vcpu->kvm)) {
		kvm_inject_undefined(vcpu);
		return false;
	}

	if (!p->is_write)
		return read_from_write_only(vcpu, p, r);

+1 −1
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ static void iter_unmark_lpis(struct kvm *kvm)
	struct vgic_irq *irq;
	unsigned long intid;

	xa_for_each(&dist->lpi_xa, intid, irq) {
	xa_for_each_marked(&dist->lpi_xa, intid, irq, LPI_XA_MARK_DEBUG_ITER) {
		xa_clear_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER);
		vgic_put_irq(kvm, irq);
	}
+6 −3
Original line number Diff line number Diff line
@@ -417,11 +417,9 @@ static void __kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
	kfree(vgic_cpu->private_irqs);
	vgic_cpu->private_irqs = NULL;

	if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
		vgic_unregister_redist_iodev(vcpu);
	if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
		vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF;
}
}

void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
{
@@ -448,6 +446,11 @@ void kvm_vgic_destroy(struct kvm *kvm)
	kvm_vgic_dist_destroy(kvm);

	mutex_unlock(&kvm->arch.config_lock);

	if (kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
		kvm_for_each_vcpu(i, vcpu, kvm)
			vgic_unregister_redist_iodev(vcpu);

	mutex_unlock(&kvm->slots_lock);
}

+5 −0
Original line number Diff line number Diff line
@@ -36,6 +36,11 @@ struct vgic_global kvm_vgic_global_state __ro_after_init = {
 * we have to disable IRQs before taking this lock and everything lower
 * than it.
 *
 * The config_lock has additional ordering requirements:
 * kvm->slots_lock
 *   kvm->srcu
 *     kvm->arch.config_lock
 *
 * If you need to take multiple locks, always take the upper lock first,
 * then the lower ones, e.g. first take the its_lock, then the irq_lock.
 * If you are already holding a lock and need to take a higher one, you
Loading