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

Commit 6245242d authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvmarm-fixes-for-5.1-2' of...

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

KVM/ARM fixes for 5.1, take #2:

- Don't try to emulate timers on userspace access
- Fix unaligned huge mappings, again
- Properly reset a vcpu that fails to reset(!)
- Properly retire pending LPIs on reset
- Fix computation of emulated CNTP_TVAL
parents eba3afde 6bc21000
Loading
Loading
Loading
Loading
+10 −7
Original line number Diff line number Diff line
@@ -507,6 +507,14 @@ static void kvm_timer_vcpu_load_nogic(struct kvm_vcpu *vcpu)
{
	struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);

	/*
	 * Update the timer output so that it is likely to match the
	 * state we're about to restore. If the timer expires between
	 * this point and the register restoration, we'll take the
	 * interrupt anyway.
	 */
	kvm_timer_update_irq(vcpu, kvm_timer_should_fire(vtimer), vtimer);

	/*
	 * When using a userspace irqchip with the architected timers and a
	 * host interrupt controller that doesn't support an active state, we
@@ -730,7 +738,6 @@ static void kvm_timer_init_interrupt(void *info)
int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value)
{
	struct arch_timer_context *timer;
	bool level;

	switch (regid) {
	case KVM_REG_ARM_TIMER_CTL:
@@ -758,10 +765,6 @@ int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value)
		return -1;
	}

	level = kvm_timer_should_fire(timer);
	kvm_timer_update_irq(vcpu, level, timer);
	timer_emulate(timer);

	return 0;
}

@@ -812,7 +815,7 @@ static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,

	switch (treg) {
	case TIMER_REG_TVAL:
		val = kvm_phys_timer_read() - timer->cntvoff - timer->cnt_cval;
		val = timer->cnt_cval - kvm_phys_timer_read() + timer->cntvoff;
		break;

	case TIMER_REG_CTL:
@@ -858,7 +861,7 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
{
	switch (treg) {
	case TIMER_REG_TVAL:
		timer->cnt_cval = val - kvm_phys_timer_read() - timer->cntvoff;
		timer->cnt_cval = kvm_phys_timer_read() - timer->cntvoff + val;
		break;

	case TIMER_REG_CTL:
+8 −3
Original line number Diff line number Diff line
@@ -934,7 +934,7 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level,
static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
			       const struct kvm_vcpu_init *init)
{
	unsigned int i;
	unsigned int i, ret;
	int phys_target = kvm_target_cpu();

	if (init->target != phys_target)
@@ -969,9 +969,14 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
	vcpu->arch.target = phys_target;

	/* Now we know what it is, we can reset it. */
	return kvm_reset_vcpu(vcpu);
	ret = kvm_reset_vcpu(vcpu);
	if (ret) {
		vcpu->arch.target = -1;
		bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
	}

	return ret;
}

static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
					 struct kvm_vcpu_init *init)
+5 −1
Original line number Diff line number Diff line
@@ -1781,8 +1781,12 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
		 * Only PMD_SIZE transparent hugepages(THP) are
		 * currently supported. This code will need to be
		 * updated to support other THP sizes.
		 *
		 * Make sure the host VA and the guest IPA are sufficiently
		 * aligned and that the block is contained within the memslot.
		 */
		if (transparent_hugepage_adjust(&pfn, &fault_ipa))
		if (fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE) &&
		    transparent_hugepage_adjust(&pfn, &fault_ipa))
			vma_pagesize = PMD_SIZE;
	}

+3 −0
Original line number Diff line number Diff line
@@ -200,6 +200,9 @@ static void vgic_mmio_write_v3r_ctlr(struct kvm_vcpu *vcpu,

	vgic_cpu->lpis_enabled = val & GICR_CTLR_ENABLE_LPIS;

	if (was_enabled && !vgic_cpu->lpis_enabled)
		vgic_flush_pending_lpis(vcpu);

	if (!was_enabled && vgic_cpu->lpis_enabled)
		vgic_enable_lpis(vcpu);
}
+21 −0
Original line number Diff line number Diff line
@@ -151,6 +151,27 @@ void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq)
	kfree(irq);
}

void vgic_flush_pending_lpis(struct kvm_vcpu *vcpu)
{
	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
	struct vgic_irq *irq, *tmp;
	unsigned long flags;

	raw_spin_lock_irqsave(&vgic_cpu->ap_list_lock, flags);

	list_for_each_entry_safe(irq, tmp, &vgic_cpu->ap_list_head, ap_list) {
		if (irq->intid >= VGIC_MIN_LPI) {
			raw_spin_lock(&irq->irq_lock);
			list_del(&irq->ap_list);
			irq->vcpu = NULL;
			raw_spin_unlock(&irq->irq_lock);
			vgic_put_irq(vcpu->kvm, irq);
		}
	}

	raw_spin_unlock_irqrestore(&vgic_cpu->ap_list_lock, flags);
}

void vgic_irq_set_phys_pending(struct vgic_irq *irq, bool pending)
{
	WARN_ON(irq_set_irqchip_state(irq->host_irq,
Loading