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

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

Merge tag 'kvm-arm-for-4.3-rc2' of...

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

KVM/ARM changes for 4.3-rc2

- Fix timer interrupt injection after the rework
  that went in during the merge window
- Reset the timer to zero on reboot
- Make sure the TCR_EL2 RES1 bits are really set to 1
- Fix a PSCI affinity bug for non-existing vcpus
parents edb9272f 0c067292
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -126,7 +126,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)

static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
{
	int i;
	int i, matching_cpus = 0;
	unsigned long mpidr;
	unsigned long target_affinity;
	unsigned long target_affinity_mask;
@@ -151,12 +151,16 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
	 */
	kvm_for_each_vcpu(i, tmp, kvm) {
		mpidr = kvm_vcpu_get_mpidr_aff(tmp);
		if (((mpidr & target_affinity_mask) == target_affinity) &&
		    !tmp->arch.pause) {
		if ((mpidr & target_affinity_mask) == target_affinity) {
			matching_cpus++;
			if (!tmp->arch.pause)
				return PSCI_0_2_AFFINITY_LEVEL_ON;
		}
	}

	if (!matching_cpus)
		return PSCI_RET_INVALID_PARAMS;

	return PSCI_0_2_AFFINITY_LEVEL_OFF;
}

+7 −3
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@
			 SCTLR_EL2_SA | SCTLR_EL2_I)

/* TCR_EL2 Registers bits */
#define TCR_EL2_RES1	((1 << 31) | (1 << 23))
#define TCR_EL2_TBI	(1 << 20)
#define TCR_EL2_PS	(7 << 16)
#define TCR_EL2_PS_40B	(2 << 16)
@@ -106,9 +107,10 @@
#define TCR_EL2_MASK	(TCR_EL2_TG0 | TCR_EL2_SH0 | \
			 TCR_EL2_ORGN0 | TCR_EL2_IRGN0 | TCR_EL2_T0SZ)

#define TCR_EL2_FLAGS	(TCR_EL2_PS_40B)
#define TCR_EL2_FLAGS	(TCR_EL2_RES1 | TCR_EL2_PS_40B)

/* VTCR_EL2 Registers bits */
#define VTCR_EL2_RES1		(1 << 31)
#define VTCR_EL2_PS_MASK	(7 << 16)
#define VTCR_EL2_TG0_MASK	(1 << 14)
#define VTCR_EL2_TG0_4K		(0 << 14)
@@ -147,7 +149,8 @@
 */
#define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_64K | VTCR_EL2_SH0_INNER | \
				 VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \
				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B)
				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B | \
				 VTCR_EL2_RES1)
#define VTTBR_X		(38 - VTCR_EL2_T0SZ_40B)
#else
/*
@@ -158,7 +161,8 @@
 */
#define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_4K | VTCR_EL2_SH0_INNER | \
				 VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \
				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B)
				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B | \
				 VTCR_EL2_RES1)
#define VTTBR_X		(37 - VTCR_EL2_T0SZ_40B)
#endif

+8 −0
Original line number Diff line number Diff line
@@ -199,6 +199,14 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
	 */
	timer->irq = irq;

	/*
	 * The bits in CNTV_CTL are architecturally reset to UNKNOWN for ARMv8
	 * and to 0 for ARMv7.  We provide an implementation that always
	 * resets the timer to be disabled and unmasked and is compliant with
	 * the ARMv7 architecture.
	 */
	timer->cntv_ctl = 0;

	/*
	 * Tell the VGIC that the virtual interrupt is tied to a
	 * physical interrupt. We do that once per VCPU.
+26 −16
Original line number Diff line number Diff line
@@ -1144,26 +1144,11 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
		struct irq_phys_map *map;
		map = vgic_irq_map_search(vcpu, irq);

		/*
		 * If we have a mapping, and the virtual interrupt is
		 * being injected, then we must set the state to
		 * active in the physical world. Otherwise the
		 * physical interrupt will fire and the guest will
		 * exit before processing the virtual interrupt.
		 */
		if (map) {
			int ret;

			BUG_ON(!map->active);
			vlr.hwirq = map->phys_irq;
			vlr.state |= LR_HW;
			vlr.state &= ~LR_EOI_INT;

			ret = irq_set_irqchip_state(map->irq,
						    IRQCHIP_STATE_ACTIVE,
						    true);
			WARN_ON(ret);

			/*
			 * Make sure we're not going to sample this
			 * again, as a HW-backed interrupt cannot be
@@ -1255,7 +1240,7 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
	unsigned long *pa_percpu, *pa_shared;
	int i, vcpu_id;
	int i, vcpu_id, lr, ret;
	int overflow = 0;
	int nr_shared = vgic_nr_shared_irqs(dist);

@@ -1310,6 +1295,31 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
		 */
		clear_bit(vcpu_id, dist->irq_pending_on_cpu);
	}

	for (lr = 0; lr < vgic->nr_lr; lr++) {
		struct vgic_lr vlr;

		if (!test_bit(lr, vgic_cpu->lr_used))
			continue;

		vlr = vgic_get_lr(vcpu, lr);

		/*
		 * If we have a mapping, and the virtual interrupt is
		 * presented to the guest (as pending or active), then we must
		 * set the state to active in the physical world. See
		 * Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt.
		 */
		if (vlr.state & LR_HW) {
			struct irq_phys_map *map;
			map = vgic_irq_map_search(vcpu, vlr.irq);

			ret = irq_set_irqchip_state(map->irq,
						    IRQCHIP_STATE_ACTIVE,
						    true);
			WARN_ON(ret);
		}
	}
}

static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)