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

Commit 8fa3adb8 authored by Julien Thierry's avatar Julien Thierry Committed by Christoffer Dall
Browse files

KVM: arm/arm64: vgic: Make vgic_irq->irq_lock a raw_spinlock



vgic_irq->irq_lock must always be taken with interrupts disabled as
it is used in interrupt context.

For configurations such as PREEMPT_RT_FULL, this means that it should
be a raw_spinlock since RT spinlocks are interruptible.

Signed-off-by: default avatarJulien Thierry <julien.thierry@arm.com>
Acked-by: default avatarChristoffer Dall <christoffer.dall@arm.com>
Acked-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Signed-off-by: default avatarChristoffer Dall <christoffer.dall@arm.com>
parent 49a57857
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -100,7 +100,7 @@ enum vgic_irq_config {
};

struct vgic_irq {
	spinlock_t irq_lock;		/* Protects the content of the struct */
	raw_spinlock_t irq_lock;	/* Protects the content of the struct */
	struct list_head lpi_list;	/* Used to link all LPIs together */
	struct list_head ap_list;

+2 −2
Original line number Diff line number Diff line
@@ -251,9 +251,9 @@ static int vgic_debug_show(struct seq_file *s, void *v)
		return 0;
	}

	spin_lock_irqsave(&irq->irq_lock, flags);
	raw_spin_lock_irqsave(&irq->irq_lock, flags);
	print_irq_state(s, irq, vcpu);
	spin_unlock_irqrestore(&irq->irq_lock, flags);
	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);

	vgic_put_irq(kvm, irq);
	return 0;
+2 −2
Original line number Diff line number Diff line
@@ -171,7 +171,7 @@ static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis)

		irq->intid = i + VGIC_NR_PRIVATE_IRQS;
		INIT_LIST_HEAD(&irq->ap_list);
		spin_lock_init(&irq->irq_lock);
		raw_spin_lock_init(&irq->irq_lock);
		irq->vcpu = NULL;
		irq->target_vcpu = vcpu0;
		kref_init(&irq->refcount);
@@ -216,7 +216,7 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
		struct vgic_irq *irq = &vgic_cpu->private_irqs[i];

		INIT_LIST_HEAD(&irq->ap_list);
		spin_lock_init(&irq->irq_lock);
		raw_spin_lock_init(&irq->irq_lock);
		irq->intid = i;
		irq->vcpu = NULL;
		irq->target_vcpu = vcpu;
+7 −7
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid,

	INIT_LIST_HEAD(&irq->lpi_list);
	INIT_LIST_HEAD(&irq->ap_list);
	spin_lock_init(&irq->irq_lock);
	raw_spin_lock_init(&irq->irq_lock);

	irq->config = VGIC_CONFIG_EDGE;
	kref_init(&irq->refcount);
@@ -287,7 +287,7 @@ static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
	if (ret)
		return ret;

	spin_lock_irqsave(&irq->irq_lock, flags);
	raw_spin_lock_irqsave(&irq->irq_lock, flags);

	if (!filter_vcpu || filter_vcpu == irq->target_vcpu) {
		irq->priority = LPI_PROP_PRIORITY(prop);
@@ -299,7 +299,7 @@ static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
		}
	}

	spin_unlock_irqrestore(&irq->irq_lock, flags);
	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);

	if (irq->hw)
		return its_prop_update_vlpi(irq->host_irq, prop, needs_inv);
@@ -352,9 +352,9 @@ static int update_affinity(struct vgic_irq *irq, struct kvm_vcpu *vcpu)
	int ret = 0;
	unsigned long flags;

	spin_lock_irqsave(&irq->irq_lock, flags);
	raw_spin_lock_irqsave(&irq->irq_lock, flags);
	irq->target_vcpu = vcpu;
	spin_unlock_irqrestore(&irq->irq_lock, flags);
	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);

	if (irq->hw) {
		struct its_vlpi_map map;
@@ -455,7 +455,7 @@ static int its_sync_lpi_pending_table(struct kvm_vcpu *vcpu)
		}

		irq = vgic_get_irq(vcpu->kvm, NULL, intids[i]);
		spin_lock_irqsave(&irq->irq_lock, flags);
		raw_spin_lock_irqsave(&irq->irq_lock, flags);
		irq->pending_latch = pendmask & (1U << bit_nr);
		vgic_queue_irq_unlock(vcpu->kvm, irq, flags);
		vgic_put_irq(vcpu->kvm, irq);
@@ -612,7 +612,7 @@ static int vgic_its_trigger_msi(struct kvm *kvm, struct vgic_its *its,
		return irq_set_irqchip_state(irq->host_irq,
					     IRQCHIP_STATE_PENDING, true);

	spin_lock_irqsave(&irq->irq_lock, flags);
	raw_spin_lock_irqsave(&irq->irq_lock, flags);
	irq->pending_latch = true;
	vgic_queue_irq_unlock(kvm, irq, flags);

+7 −7
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ static void vgic_mmio_write_sgir(struct kvm_vcpu *source_vcpu,

		irq = vgic_get_irq(source_vcpu->kvm, vcpu, intid);

		spin_lock_irqsave(&irq->irq_lock, flags);
		raw_spin_lock_irqsave(&irq->irq_lock, flags);
		irq->pending_latch = true;
		irq->source |= 1U << source_vcpu->vcpu_id;

@@ -191,13 +191,13 @@ static void vgic_mmio_write_target(struct kvm_vcpu *vcpu,
		struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, NULL, intid + i);
		int target;

		spin_lock_irqsave(&irq->irq_lock, flags);
		raw_spin_lock_irqsave(&irq->irq_lock, flags);

		irq->targets = (val >> (i * 8)) & cpu_mask;
		target = irq->targets ? __ffs(irq->targets) : 0;
		irq->target_vcpu = kvm_get_vcpu(vcpu->kvm, target);

		spin_unlock_irqrestore(&irq->irq_lock, flags);
		raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
		vgic_put_irq(vcpu->kvm, irq);
	}
}
@@ -230,13 +230,13 @@ static void vgic_mmio_write_sgipendc(struct kvm_vcpu *vcpu,
	for (i = 0; i < len; i++) {
		struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);

		spin_lock_irqsave(&irq->irq_lock, flags);
		raw_spin_lock_irqsave(&irq->irq_lock, flags);

		irq->source &= ~((val >> (i * 8)) & 0xff);
		if (!irq->source)
			irq->pending_latch = false;

		spin_unlock_irqrestore(&irq->irq_lock, flags);
		raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
		vgic_put_irq(vcpu->kvm, irq);
	}
}
@@ -252,7 +252,7 @@ static void vgic_mmio_write_sgipends(struct kvm_vcpu *vcpu,
	for (i = 0; i < len; i++) {
		struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);

		spin_lock_irqsave(&irq->irq_lock, flags);
		raw_spin_lock_irqsave(&irq->irq_lock, flags);

		irq->source |= (val >> (i * 8)) & 0xff;

@@ -260,7 +260,7 @@ static void vgic_mmio_write_sgipends(struct kvm_vcpu *vcpu,
			irq->pending_latch = true;
			vgic_queue_irq_unlock(vcpu->kvm, irq, flags);
		} else {
			spin_unlock_irqrestore(&irq->irq_lock, flags);
			raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
		}
		vgic_put_irq(vcpu->kvm, irq);
	}
Loading