Commit 867583b3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull kvm fixes from Paolo Bonzini:
"RISC-V:

   - Fix a race condition in updating external interrupt for
     trap-n-emulated IMSIC swfile

   - Fix print_reg defaults in get-reg-list selftest

  ARM:

   - Ensure a vCPU's redistributor is unregistered from the MMIO bus if
     vCPU creation fails

   - Fix building KVM selftests for arm64 from the top-level Makefile

  x86:

   - Fix breakage for SEV-ES guests that use XSAVES

  Selftests:

   - Fix bad use of strcat(), by not using strcat() at all"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: SEV: Do not intercept accesses to MSR_IA32_XSS for SEV-ES guests
  KVM: selftests: Fix dynamic generation of configuration names
  RISCV: KVM: update external interrupt atomically for IMSIC swfile
  KVM: riscv: selftests: Fix get-reg-list print_reg defaults
  KVM: selftests: Ensure sysreg-defs.h is generated at the expected path
  KVM: Convert comment into an assertion in kvm_io_bus_register_dev()
  KVM: arm64: vgic: Ensure that slots_lock is held in vgic_register_all_redist_iodevs()
  KVM: arm64: vgic: Force vcpu vgic teardown on vcpu destroy
  KVM: arm64: vgic: Add a non-locking primitive for kvm_vgic_vcpu_destroy()
  KVM: arm64: vgic: Simplify kvm_vgic_destroy()
parents c0f65a7c ef5b2837
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -410,7 +410,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
	kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
	kvm_timer_vcpu_terminate(vcpu);
	kvm_pmu_vcpu_destroy(vcpu);

	kvm_vgic_vcpu_destroy(vcpu);
	kvm_arm_vcpu_destroy(vcpu);
}

+29 −18
Original line number Diff line number Diff line
@@ -368,7 +368,7 @@ static void kvm_vgic_dist_destroy(struct kvm *kvm)
		vgic_v4_teardown(kvm);
}

void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
static void __kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
{
	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;

@@ -379,29 +379,39 @@ void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
	vgic_flush_pending_lpis(vcpu);

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

static void __kvm_vgic_destroy(struct kvm *kvm)
void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
{
	struct kvm *kvm = vcpu->kvm;

	mutex_lock(&kvm->slots_lock);
	__kvm_vgic_vcpu_destroy(vcpu);
	mutex_unlock(&kvm->slots_lock);
}

void kvm_vgic_destroy(struct kvm *kvm)
{
	struct kvm_vcpu *vcpu;
	unsigned long i;

	lockdep_assert_held(&kvm->arch.config_lock);
	mutex_lock(&kvm->slots_lock);

	vgic_debug_destroy(kvm);

	kvm_for_each_vcpu(i, vcpu, kvm)
		kvm_vgic_vcpu_destroy(vcpu);
		__kvm_vgic_vcpu_destroy(vcpu);

	mutex_lock(&kvm->arch.config_lock);

	kvm_vgic_dist_destroy(kvm);
}

void kvm_vgic_destroy(struct kvm *kvm)
{
	mutex_lock(&kvm->arch.config_lock);
	__kvm_vgic_destroy(kvm);
	mutex_unlock(&kvm->arch.config_lock);
	mutex_unlock(&kvm->slots_lock);
}

/**
@@ -469,25 +479,26 @@ int kvm_vgic_map_resources(struct kvm *kvm)
		type = VGIC_V3;
	}

	if (ret) {
		__kvm_vgic_destroy(kvm);
	if (ret)
		goto out;
	}

	dist->ready = true;
	dist_base = dist->vgic_dist_base;
	mutex_unlock(&kvm->arch.config_lock);

	ret = vgic_register_dist_iodev(kvm, dist_base, type);
	if (ret) {
	if (ret)
		kvm_err("Unable to register VGIC dist MMIO regions\n");
		kvm_vgic_destroy(kvm);
	}
	mutex_unlock(&kvm->slots_lock);
	return ret;

	goto out_slots;
out:
	mutex_unlock(&kvm->arch.config_lock);
out_slots:
	mutex_unlock(&kvm->slots_lock);

	if (ret)
		kvm_vgic_destroy(kvm);

	return ret;
}

+3 −1
Original line number Diff line number Diff line
@@ -820,7 +820,7 @@ int vgic_register_redist_iodev(struct kvm_vcpu *vcpu)
	return ret;
}

static void vgic_unregister_redist_iodev(struct kvm_vcpu *vcpu)
void vgic_unregister_redist_iodev(struct kvm_vcpu *vcpu)
{
	struct vgic_io_device *rd_dev = &vcpu->arch.vgic_cpu.rd_iodev;

@@ -833,6 +833,8 @@ static int vgic_register_all_redist_iodevs(struct kvm *kvm)
	unsigned long c;
	int ret = 0;

	lockdep_assert_held(&kvm->slots_lock);

	kvm_for_each_vcpu(c, vcpu, kvm) {
		ret = vgic_register_redist_iodev(vcpu);
		if (ret)
+1 −0
Original line number Diff line number Diff line
@@ -241,6 +241,7 @@ int vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq);
int vgic_v3_save_pending_tables(struct kvm *kvm);
int vgic_v3_set_redist_base(struct kvm *kvm, u32 index, u64 addr, u32 count);
int vgic_register_redist_iodev(struct kvm_vcpu *vcpu);
void vgic_unregister_redist_iodev(struct kvm_vcpu *vcpu);
bool vgic_v3_check_base(struct kvm *kvm);

void vgic_v3_load(struct kvm_vcpu *vcpu);
+13 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ struct imsic {
	/* IMSIC SW-file */
	struct imsic_mrif *swfile;
	phys_addr_t swfile_pa;
	spinlock_t swfile_extirq_lock;
};

#define imsic_vs_csr_read(__c)			\
@@ -613,12 +614,23 @@ static void imsic_swfile_extirq_update(struct kvm_vcpu *vcpu)
{
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
	struct imsic_mrif *mrif = imsic->swfile;
	unsigned long flags;

	/*
	 * The critical section is necessary during external interrupt
	 * updates to avoid the risk of losing interrupts due to potential
	 * interruptions between reading topei and updating pending status.
	 */

	spin_lock_irqsave(&imsic->swfile_extirq_lock, flags);

	if (imsic_mrif_atomic_read(mrif, &mrif->eidelivery) &&
	    imsic_mrif_topei(mrif, imsic->nr_eix, imsic->nr_msis))
		kvm_riscv_vcpu_set_interrupt(vcpu, IRQ_VS_EXT);
	else
		kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT);

	spin_unlock_irqrestore(&imsic->swfile_extirq_lock, flags);
}

static void imsic_swfile_read(struct kvm_vcpu *vcpu, bool clear,
@@ -1039,6 +1051,7 @@ int kvm_riscv_vcpu_aia_imsic_init(struct kvm_vcpu *vcpu)
	}
	imsic->swfile = page_to_virt(swfile_page);
	imsic->swfile_pa = page_to_phys(swfile_page);
	spin_lock_init(&imsic->swfile_extirq_lock);

	/* Setup IO device */
	kvm_iodevice_init(&imsic->iodev, &imsic_iodoev_ops);
Loading