// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2015, 2016 ARM Ltd.
 */

#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kvm.h>
#include <linux/kvm_host.h>
#include <linux/list_sort.h>
#include <linux/nospec.h>

#include <asm/kvm_hyp.h>

#include "vgic.h"

#define CREATE_TRACE_POINTS
#include "trace.h"

struct vgic_global kvm_vgic_global_state __ro_after_init = {
	.gicv3_cpuif = STATIC_KEY_FALSE_INIT,
};

/*
 * Locking order is always:
 * kvm->lock (mutex)
 *   its->cmd_lock (mutex)
 *     its->its_lock (mutex)
 *       vgic_cpu->ap_list_lock		must be taken with IRQs disabled
 *         kvm->lpi_list_lock		must be taken with IRQs disabled
 *           vgic_irq->irq_lock		must be taken with IRQs disabled
 *
 * As the ap_list_lock might be taken from the timer interrupt handler,
 * we have to disable IRQs before taking this lock and everything lower
 * than it.
 *
 * 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
 * have to drop the lower ranking lock first and re-aquire it after having
 * taken the upper one.
 *
 * When taking more than one ap_list_lock at the same time, always take the
 * lowest numbered VCPU's ap_list_lock first, so:
 *   vcpuX->vcpu_id < vcpuY->vcpu_id:
 *     raw_spin_lock(vcpuX->arch.vgic_cpu.ap_list_lock);
 *     raw_spin_lock(vcpuY->arch.vgic_cpu.ap_list_lock);
 *
 * Since the VGIC must support injecting virtual interrupts from ISRs, we have
 * to use the raw_spin_lock_irqsave/raw_spin_unlock_irqrestore versions of outer
 * spinlocks for any lock that may be taken while injecting an interrupt.
 */

/*
 * Iterate over the VM's list of mapped LPIs to find the one with a
 * matching interrupt ID and return a reference to the IRQ structure.
 */
static struct vgic_irq *vgic_get_lpi(struct kvm *kvm, u32 intid)
{
	struct vgic_dist *dist = &kvm->arch.vgic;
	struct vgic_irq *irq = NULL;
	unsigned long flags;

	raw_spin_lock_irqsave(&dist->lpi_list_lock, flags);

	list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) {
		if (irq->intid != intid)
			continue;

		/*
		 * This increases the refcount, the caller is expected to
		 * call vgic_put_irq() later once it's finished with the IRQ.
		 */
		vgic_get_irq_kref(irq);
		goto out_unlock;
	}
	irq = NULL;

out_unlock:
	raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);

	return irq;
}

/*
 * This looks up the virtual interrupt ID to get the corresponding
 * struct vgic_irq. It also increases the refcount, so any caller is expected
 * to call vgic_put_irq() once it's finished with this IRQ.
 */
struct vgic_irq *vgic_get_irq(struct kvm *kvm, struct kvm_vcpu *vcpu,
			      u32 intid)
{
	/* SGIs and PPIs */
	if (intid <= VGIC_MAX_PRIVATE) {
		intid = array_index_nospec(intid, VGIC_MAX_PRIVATE + 1);
		return &vcpu->arch.vgic_cpu.private_irqs[intid];
	}

	/* SPIs */
	if (intid < (kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) {
		intid = array_index_nospec(intid, kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS);
		return &kvm->arch.vgic.spis[intid - VGIC_NR_PRIVATE_IRQS];
	}

	/* LPIs */
	if (intid >= VGIC_MIN_LPI)
		return vgic_get_lpi(kvm, intid);

	return NULL;
}

/*
 * We can't do anything in here, because we lack the kvm pointer to
 * lock and remove the item from the lpi_list. So we keep this function
 * empty and use the return value of kref_put() to trigger the freeing.
 */
static void vgic_irq_release(struct kref *ref)
{
}

/*
 * Drop the refcount on the LPI. Must be called with lpi_list_lock held.
 */
void __vgic_put_lpi_locked(struct kvm *kvm, struct vgic_irq *irq)
{
	struct vgic_dist *dist = &kvm->arch.vgic;

	if (!kref_put(&irq->refcount, vgic_irq_release))
		return;

	list_del(&irq->lpi_list);
	dist->lpi_list_count--;

	kfree(irq);
}

void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq)
{
	struct vgic_dist *dist = &kvm->arch.vgic;
	unsigned long flags;

	if (irq->intid < VGIC_MIN_LPI)
		return;

	raw_spin_lock_irqsave(&dist->lpi_list_lock, flags);
	__vgic_put_lpi_locked(kvm, irq);
	raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
}

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,
				      IRQCHIP_STATE_PENDING,
				      pending));
}

bool vgic_get_phys_line_level(struct vgic_irq *irq)
{
	bool line_level;

	BUG_ON(!irq->hw);

	if (irq->ops && irq->ops->get_input_level)
		return irq->ops->get_input_level(irq->intid);

	WARN_ON(irq_get_irqchip_state(irq->host_irq,
				      IRQCHIP_STATE_PENDING,
				      &line_level));
	return line_level;
}

/* Set/Clear the physical active state */
void vgic_irq_set_phys_active(struct vgic_irq *irq, bool active)
{

	BUG_ON(!irq->hw);
	WARN_ON(irq_set_irqchip_state(irq->host_irq,
				      IRQCHIP_STATE_ACTIVE,
				      active));
}

/**
 * kvm_vgic_target_oracle - compute the target vcpu for an irq
 *
 * @irq:	The irq to route. Must be already locked.
 *
 * Based on the current state of the interrupt (enabled, pending,
 * active, vcpu and target_vcpu), compute the next vcpu this should be
 * given to. Return NULL if this shouldn't be injected at all.
 *
 * Requires the IRQ lock to be held.
 */
static struct kvm_vcpu *vgic_target_oracle(struct vgic_irq *irq)
{
	lockdep_assert_held(&irq->irq_lock);

	/* If the interrupt is active, it must stay on the current vcpu */
	if (irq->active)
		return irq->vcpu ? : irq->target_vcpu;

	/*
	 * If the IRQ is not active but enabled and pending, we should direct
	 * it to its configured target VCPU.
	 * If the distributor is disabled, pending interrupts shouldn't be
	 * forwarded.
	 */
	if (irq->enabled && irq_is_pending(irq)) {
		if (unlikely(irq->target_vcpu &&
			     !irq->target_vcpu->kvm->arch.vgic.enabled))
			return NULL;

		return irq->target_vcpu;
	}

	/* If neither active nor pending and enabled, then this IRQ should not
	 * be queued to any VCPU.
	 */
	return NULL;
}

/*
 * The order of items in the ap_lists defines how we'll pack things in LRs as
 * well, the first items in the list being the first things populated in the
 * LRs.
 *
 * A hard rule is that active interrupts can never be pushed out of the LRs
 * (and therefore take priority) since we cannot reliably trap on deactivation
 * of IRQs and therefore they have to be present in the LRs.
 *
 * Otherwise things should be sorted by the priority field and the GIC
 * hardware support will take care of preemption of priority groups etc.
 *
 * Return negative if "a" sorts before "b", 0 to preserve order, and positive
 * to sort "b" before "a".
 */
static int vgic_irq_cmp(void *priv, const struct list_head *a,
			const struct list_head *b)
{
	struct vgic_irq *irqa = container_of(a, struct vgic_irq, ap_list);
	struct vgic_irq *irqb = container_of(b, struct vgic_irq, ap_list);
	bool penda, pendb;
	int ret;

	/*
	 * list_sort may call this function with the same element when
	 * the list is fairly long.
	 */
	if (unlikely(irqa == irqb))
		return 0;

	raw_spin_lock(&irqa->irq_lock);
	raw_spin_lock_nested(&irqb->irq_lock, SINGLE_DEPTH_NESTING);

	if (irqa->active || irqb->active) {
		ret = (int)irqb->active - (int)irqa->active;
		goto out;
	}

	penda = irqa->enabled && irq_is_pending(irqa);
	pendb = irqb->enabled && irq_is_pending(irqb);

	if (!penda || !pendb) {
		ret = (int)pendb - (int)penda;
		goto out;
	}

	/* Both pending and enabled, sort by priority */
	ret = irqa->priority - irqb->priority;
out:
	raw_spin_unlock(&irqb->irq_lock);
	raw_spin_unlock(&irqa->irq_lock);
	return ret;
}

/* Must be called with the ap_list_lock held */
static void vgic_sort_ap_list(struct kvm_vcpu *vcpu)
{
	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;

	lockdep_assert_held(&vgic_cpu->ap_list_lock);

	list_sort(NULL, &vgic_cpu->ap_list_head, vgic_irq_cmp);
}

/*
 * Only valid injection if changing level for level-triggered IRQs or for a
 * rising edge, and in-kernel connected IRQ lines can only be controlled by
 * their owner.
 */
static bool vgic_validate_injection(struct vgic_irq *irq, bool level, void *owner)
{
	if (irq->owner != owner)
		return false;

	switch (irq->config) {
	case VGIC_CONFIG_LEVEL:
		return irq->line_level != level;
	case VGIC_CONFIG_EDGE:
		return level;
	}

	return false;
}

/*
 * Check whether an IRQ needs to (and can) be queued to a VCPU's ap list.
 * Do the queuing if necessary, taking the right locks in the right order.
 * Returns true when the IRQ was queued, false otherwise.
 *
 * Needs to be entered with the IRQ lock already held, but will return
 * with all locks dropped.
 */
bool vgic_queue_irq_unlock(struct kvm *kvm, struct vgic_irq *irq,
			   unsigned long flags)
{
	struct kvm_vcpu *vcpu;

	lockdep_assert_held(&irq->irq_lock);

retry:
	vcpu = vgic_target_oracle(irq);
	if (irq->vcpu || !vcpu) {
		/*
		 * If this IRQ is already on a VCPU's ap_list, then it
		 * cannot be moved or modified and there is no more work for
		 * us to do.
		 *
		 * Otherwise, if the irq is not pending and enabled, it does
		 * not need to be inserted into an ap_list and there is also
		 * no more work for us to do.
		 */
		raw_spin_unlock_irqrestore(&irq->irq_lock, flags);

		/*
		 * We have to kick the VCPU here, because we could be
		 * queueing an edge-triggered interrupt for which we
		 * get no EOI maintenance interrupt. In that case,
		 * while the IRQ is already on the VCPU's AP list, the
		 * VCPU could have EOI'ed the original interrupt and
		 * won't see this one until it exits for some other
		 * reason.
		 */
		if (vcpu) {
			kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu);
			kvm_vcpu_kick(vcpu);
		}
		return false;
	}

	/*
	 * We must unlock the irq lock to take the ap_list_lock where
	 * we are going to insert this new pending interrupt.
	 */
	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);

	/* someone can do stuff here, which we re-check below */

	raw_spin_lock_irqsave(&vcpu->arch.vgic_cpu.ap_list_lock, flags);
	raw_spin_lock(&irq->irq_lock);

	/*
	 * Did something change behind our backs?
	 *
	 * There are two cases:
	 * 1) The irq lost its pending state or was disabled behind our
	 *    backs and/or it was queued to another VCPU's ap_list.
	 * 2) Someone changed the affinity on this irq behind our
	 *    backs and we are now holding the wrong ap_list_lock.
	 *
	 * In both cases, drop the locks and retry.
	 */

	if (unlikely(irq->vcpu || vcpu != vgic_target_oracle(irq))) {
		raw_spin_unlock(&irq->irq_lock);
		raw_spin_unlock_irqrestore(&vcpu->arch.vgic_cpu.ap_list_lock,
					   flags);

		raw_spin_lock_irqsave(&irq->irq_lock, flags);
		goto retry;
	}

	/*
	 * Grab a reference to the irq to reflect the fact that it is
	 * now in the ap_list.
	 */
	vgic_get_irq_kref(irq);
	list_add_tail(&irq->ap_list, &vcpu->arch.vgic_cpu.ap_list_head);
	irq->vcpu = vcpu;

	raw_spin_unlock(&irq->irq_lock);
	raw_spin_unlock_irqrestore(&vcpu->arch.vgic_cpu.ap_list_lock, flags);

	kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu);
	kvm_vcpu_kick(vcpu);

	return true;
}

/**
 * kvm_vgic_inject_irq - Inject an IRQ from a device to the vgic
 * @kvm:     The VM structure pointer
 * @cpuid:   The CPU for PPIs
 * @intid:   The INTID to inject a new state to.
 * @level:   Edge-triggered:  true:  to trigger the interrupt
 *			      false: to ignore the call
 *	     Level-sensitive  true:  raise the input signal
 *			      false: lower the input signal
 * @owner:   The opaque pointer to the owner of the IRQ being raised to verify
 *           that the caller is allowed to inject this IRQ.  Userspace
 *           injections will have owner == NULL.
 *
 * The VGIC is not concerned with devices being active-LOW or active-HIGH for
 * level-sensitive interrupts.  You can think of the level parameter as 1
 * being HIGH and 0 being LOW and all devices being active-HIGH.
 */
int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid,
			bool level, void *owner)
{
	struct kvm_vcpu *vcpu;
	struct vgic_irq *irq;
	unsigned long flags;
	int ret;

	trace_vgic_update_irq_pending(cpuid, intid, level);

	ret = vgic_lazy_init(kvm);
	if (ret)
		return ret;

	vcpu = kvm_get_vcpu(kvm, cpuid);
	if (!vcpu && intid < VGIC_NR_PRIVATE_IRQS)
		return -EINVAL;

	irq = vgic_get_irq(kvm, vcpu, intid);
	if (!irq)
		return -EINVAL;

	raw_spin_lock_irqsave(&irq->irq_lock, flags);

	if (!vgic_validate_injection(irq, level, owner)) {
		/* Nothing to see here, move along... */
		raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
		vgic_put_irq(kvm, irq);
		return 0;
	}

	if (irq->config == VGIC_CONFIG_LEVEL)
		irq->line_level = level;
	else
		irq->pending_latch = true;

	vgic_queue_irq_unlock(kvm, irq, flags);
	vgic_put_irq(kvm, irq);

	return 0;
}

/* @irq->irq_lock must be held */
static int kvm_vgic_map_irq(struct kvm_vcpu *vcpu, struct vgic_irq *irq,
			    unsigned int host_irq,
			    struct irq_ops *ops)
{
	struct irq_desc *desc;
	struct irq_data *data;

	/*
	 * Find the physical IRQ number corresponding to @host_irq
	 */
	desc = irq_to_desc(host_irq);
	if (!desc) {
		kvm_err("%s: no interrupt descriptor\n", __func__);
		return -EINVAL;
	}
	data = irq_desc_get_irq_data(desc);
	while (data->parent_data)
		data = data->parent_data;

	irq->hw = true;
	irq->host_irq = host_irq;
	irq->hwintid = data->hwirq;
	irq->ops = ops;
	return 0;
}

/* @irq->irq_lock must be held */
static inline void kvm_vgic_unmap_irq(struct vgic_irq *irq)
{
	irq->hw = false;
	irq->hwintid = 0;
	irq->ops = NULL;
}

int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq,
			  u32 vintid, struct irq_ops *ops)
{
	struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid);
	unsigned long flags;
	int ret;

	BUG_ON(!irq);

	raw_spin_lock_irqsave(&irq->irq_lock, flags);
	ret = kvm_vgic_map_irq(vcpu, irq, host_irq, ops);
	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
	vgic_put_irq(vcpu->kvm, irq);

	return ret;
}

/**
 * kvm_vgic_reset_mapped_irq - Reset a mapped IRQ
 * @vcpu: The VCPU pointer
 * @vintid: The INTID of the interrupt
 *
 * Reset the active and pending states of a mapped interrupt.  Kernel
 * subsystems injecting mapped interrupts should reset their interrupt lines
 * when we are doing a reset of the VM.
 */
void kvm_vgic_reset_mapped_irq(struct kvm_vcpu *vcpu, u32 vintid)
{
	struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid);
	unsigned long flags;

	if (!irq->hw)
		goto out;

	raw_spin_lock_irqsave(&irq->irq_lock, flags);
	irq->active = false;
	irq->pending_latch = false;
	irq->line_level = false;
	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
out:
	vgic_put_irq(vcpu->kvm, irq);
}

int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid)
{
	struct vgic_irq *irq;
	unsigned long flags;

	if (!vgic_initialized(vcpu->kvm))
		return -EAGAIN;

	irq = vgic_get_irq(vcpu->kvm, vcpu, vintid);
	BUG_ON(!irq);

	raw_spin_lock_irqsave(&irq->irq_lock, flags);
	kvm_vgic_unmap_irq(irq);
	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
	vgic_put_irq(vcpu->kvm, irq);

	return 0;
}

/**
 * kvm_vgic_set_owner - Set the owner of an interrupt for a VM
 *
 * @vcpu:   Pointer to the VCPU (used for PPIs)
 * @intid:  The virtual INTID identifying the interrupt (PPI or SPI)
 * @owner:  Opaque pointer to the owner
 *
 * Returns 0 if intid is not already used by another in-kernel device and the
 * owner is set, otherwise returns an error code.
 */
int kvm_vgic_set_owner(struct kvm_vcpu *vcpu, unsigned int intid, void *owner)
{
	struct vgic_irq *irq;
	unsigned long flags;
	int ret = 0;

	if (!vgic_initialized(vcpu->kvm))
		return -EAGAIN;

	/* SGIs and LPIs cannot be wired up to any device */
	if (!irq_is_ppi(intid) && !vgic_valid_spi(vcpu->kvm, intid))
		return -EINVAL;

	irq = vgic_get_irq(vcpu->kvm, vcpu, intid);
	raw_spin_lock_irqsave(&irq->irq_lock, flags);
	if (irq->owner && irq->owner != owner)
		ret = -EEXIST;
	else
		irq->owner = owner;
	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);

	return ret;
}

/**
 * vgic_prune_ap_list - Remove non-relevant interrupts from the list
 *
 * @vcpu: The VCPU pointer
 *
 * Go over the list of "interesting" interrupts, and prune those that we
 * won't have to consider in the near future.
 */
static void vgic_prune_ap_list(struct kvm_vcpu *vcpu)
{
	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
	struct vgic_irq *irq, *tmp;

	DEBUG_SPINLOCK_BUG_ON(!irqs_disabled());

retry:
	raw_spin_lock(&vgic_cpu->ap_list_lock);

	list_for_each_entry_safe(irq, tmp, &vgic_cpu->ap_list_head, ap_list) {
		struct kvm_vcpu *target_vcpu, *vcpuA, *vcpuB;
		bool target_vcpu_needs_kick = false;

		raw_spin_lock(&irq->irq_lock);

		BUG_ON(vcpu != irq->vcpu);

		target_vcpu = vgic_target_oracle(irq);

		if (!target_vcpu) {
			/*
			 * We don't need to process this interrupt any
			 * further, move it off the list.
			 */
			list_del(&irq->ap_list);
			irq->vcpu = NULL;
			raw_spin_unlock(&irq->irq_lock);

			/*
			 * This vgic_put_irq call matches the
			 * vgic_get_irq_kref in vgic_queue_irq_unlock,
			 * where we added the LPI to the ap_list. As
			 * we remove the irq from the list, we drop
			 * also drop the refcount.
			 */
			vgic_put_irq(vcpu->kvm, irq);
			continue;
		}

		if (target_vcpu == vcpu) {
			/* We're on the right CPU */
			raw_spin_unlock(&irq->irq_lock);
			continue;
		}

		/* This interrupt looks like it has to be migrated. */

		raw_spin_unlock(&irq->irq_lock);
		raw_spin_unlock(&vgic_cpu->ap_list_lock);

		/*
		 * Ensure locking order by always locking the smallest
		 * ID first.
		 */
		if (vcpu->vcpu_id < target_vcpu->vcpu_id) {
			vcpuA = vcpu;
			vcpuB = target_vcpu;
		} else {
			vcpuA = target_vcpu;
			vcpuB = vcpu;
		}

		raw_spin_lock(&vcpuA->arch.vgic_cpu.ap_list_lock);
		raw_spin_lock_nested(&vcpuB->arch.vgic_cpu.ap_list_lock,
				      SINGLE_DEPTH_NESTING);
		raw_spin_lock(&irq->irq_lock);

		/*
		 * If the affinity has been preserved, move the
		 * interrupt around. Otherwise, it means things have
		 * changed while the interrupt was unlocked, and we
		 * need to replay this.
		 *
		 * In all cases, we cannot trust the list not to have
		 * changed, so we restart from the beginning.
		 */
		if (target_vcpu == vgic_target_oracle(irq)) {
			struct vgic_cpu *new_cpu = &target_vcpu->arch.vgic_cpu;

			list_del(&irq->ap_list);
			irq->vcpu = target_vcpu;
			list_add_tail(&irq->ap_list, &new_cpu->ap_list_head);
			target_vcpu_needs_kick = true;
		}

		raw_spin_unlock(&irq->irq_lock);
		raw_spin_unlock(&vcpuB->arch.vgic_cpu.ap_list_lock);
		raw_spin_unlock(&vcpuA->arch.vgic_cpu.ap_list_lock);

		if (target_vcpu_needs_kick) {
			kvm_make_request(KVM_REQ_IRQ_PENDING, target_vcpu);
			kvm_vcpu_kick(target_vcpu);
		}

		goto retry;
	}

	raw_spin_unlock(&vgic_cpu->ap_list_lock);
}

static inline void vgic_fold_lr_state(struct kvm_vcpu *vcpu)
{
	if (kvm_vgic_global_state.type == VGIC_V2)
		vgic_v2_fold_lr_state(vcpu);
	else
		vgic_v3_fold_lr_state(vcpu);
}

/* Requires the irq_lock to be held. */
static inline void vgic_populate_lr(struct kvm_vcpu *vcpu,
				    struct vgic_irq *irq, int lr)
{
	lockdep_assert_held(&irq->irq_lock);

	if (kvm_vgic_global_state.type == VGIC_V2)
		vgic_v2_populate_lr(vcpu, irq, lr);
	else
		vgic_v3_populate_lr(vcpu, irq, lr);
}

static inline void vgic_clear_lr(struct kvm_vcpu *vcpu, int lr)
{
	if (kvm_vgic_global_state.type == VGIC_V2)
		vgic_v2_clear_lr(vcpu, lr);
	else
		vgic_v3_clear_lr(vcpu, lr);
}

static inline void vgic_set_underflow(struct kvm_vcpu *vcpu)
{
	if (kvm_vgic_global_state.type == VGIC_V2)
		vgic_v2_set_underflow(vcpu);
	else
		vgic_v3_set_underflow(vcpu);
}

/* Requires the ap_list_lock to be held. */
static int compute_ap_list_depth(struct kvm_vcpu *vcpu,
				 bool *multi_sgi)
{
	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
	struct vgic_irq *irq;
	int count = 0;

	*multi_sgi = false;

	lockdep_assert_held(&vgic_cpu->ap_list_lock);

	list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) {
		int w;

		raw_spin_lock(&irq->irq_lock);
		/* GICv2 SGIs can count for more than one... */
		w = vgic_irq_get_lr_count(irq);
		raw_spin_unlock(&irq->irq_lock);

		count += w;
		*multi_sgi |= (w > 1);
	}
	return count;
}

/* Requires the VCPU's ap_list_lock to be held. */
static void vgic_flush_lr_state(struct kvm_vcpu *vcpu)
{
	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
	struct vgic_irq *irq;
	int count;
	bool multi_sgi;
	u8 prio = 0xff;
	int i = 0;

	lockdep_assert_held(&vgic_cpu->ap_list_lock);

	count = compute_ap_list_depth(vcpu, &multi_sgi);
	if (count > kvm_vgic_global_state.nr_lr || multi_sgi)
		vgic_sort_ap_list(vcpu);

	count = 0;

	list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) {
		raw_spin_lock(&irq->irq_lock);

		/*
		 * If we have multi-SGIs in the pipeline, we need to
		 * guarantee that they are all seen before any IRQ of
		 * lower priority. In that case, we need to filter out
		 * these interrupts by exiting early. This is easy as
		 * the AP list has been sorted already.
		 */
		if (multi_sgi && irq->priority > prio) {
			_raw_spin_unlock(&irq->irq_lock);
			break;
		}

		if (likely(vgic_target_oracle(irq) == vcpu)) {
			vgic_populate_lr(vcpu, irq, count++);

			if (irq->source)
				prio = irq->priority;
		}

		raw_spin_unlock(&irq->irq_lock);

		if (count == kvm_vgic_global_state.nr_lr) {
			if (!list_is_last(&irq->ap_list,
					  &vgic_cpu->ap_list_head))
				vgic_set_underflow(vcpu);
			break;
		}
	}

	/* Nuke remaining LRs */
	for (i = count ; i < kvm_vgic_global_state.nr_lr; i++)
		vgic_clear_lr(vcpu, i);

	if (!static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
		vcpu->arch.vgic_cpu.vgic_v2.used_lrs = count;
	else
		vcpu->arch.vgic_cpu.vgic_v3.used_lrs = count;
}

static inline bool can_access_vgic_from_kernel(void)
{
	/*
	 * GICv2 can always be accessed from the kernel because it is
	 * memory-mapped, and VHE systems can access GICv3 EL2 system
	 * registers.
	 */
	return !static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif) || has_vhe();
}

static inline void vgic_save_state(struct kvm_vcpu *vcpu)
{
	if (!static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
		vgic_v2_save_state(vcpu);
	else
		__vgic_v3_save_state(&vcpu->arch.vgic_cpu.vgic_v3);
}

/* Sync back the hardware VGIC state into our emulation after a guest's run. */
void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
{
	int used_lrs;

	/* An empty ap_list_head implies used_lrs == 0 */
	if (list_empty(&vcpu->arch.vgic_cpu.ap_list_head))
		return;

	if (can_access_vgic_from_kernel())
		vgic_save_state(vcpu);

	if (!static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
		used_lrs = vcpu->arch.vgic_cpu.vgic_v2.used_lrs;
	else
		used_lrs = vcpu->arch.vgic_cpu.vgic_v3.used_lrs;

	if (used_lrs)
		vgic_fold_lr_state(vcpu);
	vgic_prune_ap_list(vcpu);
}

static inline void vgic_restore_state(struct kvm_vcpu *vcpu)
{
	if (!static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
		vgic_v2_restore_state(vcpu);
	else
		__vgic_v3_restore_state(&vcpu->arch.vgic_cpu.vgic_v3);
}

/* Flush our emulation state into the GIC hardware before entering the guest. */
void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
{
	/*
	 * If there are no virtual interrupts active or pending for this
	 * VCPU, then there is no work to do and we can bail out without
	 * taking any lock.  There is a potential race with someone injecting
	 * interrupts to the VCPU, but it is a benign race as the VCPU will
	 * either observe the new interrupt before or after doing this check,
	 * and introducing additional synchronization mechanism doesn't change
	 * this.
	 *
	 * Note that we still need to go through the whole thing if anything
	 * can be directly injected (GICv4).
	 */
	if (list_empty(&vcpu->arch.vgic_cpu.ap_list_head) &&
	    !vgic_supports_direct_msis(vcpu->kvm))
		return;

	DEBUG_SPINLOCK_BUG_ON(!irqs_disabled());

	if (!list_empty(&vcpu->arch.vgic_cpu.ap_list_head)) {
		raw_spin_lock(&vcpu->arch.vgic_cpu.ap_list_lock);
		vgic_flush_lr_state(vcpu);
		raw_spin_unlock(&vcpu->arch.vgic_cpu.ap_list_lock);
	}

	if (can_access_vgic_from_kernel())
		vgic_restore_state(vcpu);

	if (vgic_supports_direct_msis(vcpu->kvm))
		vgic_v4_commit(vcpu);
}

void kvm_vgic_load(struct kvm_vcpu *vcpu)
{
	if (unlikely(!vgic_initialized(vcpu->kvm)))
		return;

	if (kvm_vgic_global_state.type == VGIC_V2)
		vgic_v2_load(vcpu);
	else
		vgic_v3_load(vcpu);
}

void kvm_vgic_put(struct kvm_vcpu *vcpu)
{
	if (unlikely(!vgic_initialized(vcpu->kvm)))
		return;

	if (kvm_vgic_global_state.type == VGIC_V2)
		vgic_v2_put(vcpu);
	else
		vgic_v3_put(vcpu);
}

void kvm_vgic_vmcr_sync(struct kvm_vcpu *vcpu)
{
	if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
		return;

	if (kvm_vgic_global_state.type == VGIC_V2)
		vgic_v2_vmcr_sync(vcpu);
	else
		vgic_v3_vmcr_sync(vcpu);
}

int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
{
	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
	struct vgic_irq *irq;
	bool pending = false;
	unsigned long flags;
	struct vgic_vmcr vmcr;

	if (!vcpu->kvm->arch.vgic.enabled)
		return false;

	if (vcpu->arch.vgic_cpu.vgic_v3.its_vpe.pending_last)
		return true;

	vgic_get_vmcr(vcpu, &vmcr);

	raw_spin_lock_irqsave(&vgic_cpu->ap_list_lock, flags);

	list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) {
		raw_spin_lock(&irq->irq_lock);
		pending = irq_is_pending(irq) && irq->enabled &&
			  !irq->active &&
			  irq->priority < vmcr.pmr;
		raw_spin_unlock(&irq->irq_lock);

		if (pending)
			break;
	}

	raw_spin_unlock_irqrestore(&vgic_cpu->ap_list_lock, flags);

	return pending;
}

void vgic_kick_vcpus(struct kvm *kvm)
{
	struct kvm_vcpu *vcpu;
	int c;

	/*
	 * We've injected an interrupt, time to find out who deserves
	 * a good kick...
	 */
	kvm_for_each_vcpu(c, vcpu, kvm) {
		if (kvm_vgic_vcpu_pending_irq(vcpu)) {
			kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu);
			kvm_vcpu_kick(vcpu);
		}
	}
}

bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid)
{
	struct vgic_irq *irq;
	bool map_is_active;
	unsigned long flags;

	if (!vgic_initialized(vcpu->kvm))
		return false;

	irq = vgic_get_irq(vcpu->kvm, vcpu, vintid);
	raw_spin_lock_irqsave(&irq->irq_lock, flags);
	map_is_active = irq->hw && irq->active;
	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
	vgic_put_irq(vcpu->kvm, irq);

	return map_is_active;
}

/*
 * Level-triggered mapped IRQs are special because we only observe rising
 * edges as input to the VGIC.
 *
 * If the guest never acked the interrupt we have to sample the physical
 * line and set the line level, because the device state could have changed
 * or we simply need to process the still pending interrupt later.
 *
 * We could also have entered the guest with the interrupt active+pending.
 * On the next exit, we need to re-evaluate the pending state, as it could
 * otherwise result in a spurious interrupt by injecting a now potentially
 * stale pending state.
 *
 * If this causes us to lower the level, we have to also clear the physical
 * active state, since we will otherwise never be told when the interrupt
 * becomes asserted again.
 *
 * Another case is when the interrupt requires a helping hand on
 * deactivation (no HW deactivation, for example).
 */
void vgic_irq_handle_resampling(struct vgic_irq *irq,
				bool lr_deactivated, bool lr_pending)
{
	if (vgic_irq_is_mapped_level(irq)) {
		bool resample = false;

		if (unlikely(vgic_irq_needs_resampling(irq))) {
			resample = !(irq->active || irq->pending_latch);
		} else if (lr_pending || (lr_deactivated && irq->line_level)) {
			irq->line_level = vgic_get_phys_line_level(irq);
			resample = !irq->line_level;
		}

		if (resample)
			vgic_irq_set_phys_active(irq, false);
	}
}
