Commit c3680403 authored by wanghaibin's avatar wanghaibin Committed by Dongxu Sun
Browse files

KVM: arm64: vgic: Add helper for vtimer vppi info register

virt inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8K89F


CVE: NA

------------------------------------------------------------------

Introudce vtimer_info in vgic_cpu, holds the vtimer vppi info
for irqbypass extension.

Signed-off-by: default avatarwanghaibin <wanghaibin.wang@huawei.com>
Signed-off-by: default avatarZenghui Yu <yuzenghui@huawei.com>
Signed-off-by: default avatarKunkun Jiang <jiangkunkun@huawei.com>
Signed-off-by: default avatarDongxu Sun <sundongxu3@huawei.com>
parent 82eac475
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -222,6 +222,9 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
			/* PPIs */
			irq->config = VGIC_CONFIG_LEVEL;
		}

		/* Needed? */
		irq->vtimer_info = NULL;
	}

	if (!irqchip_in_kernel(vcpu->kvm))
+26 −0
Original line number Diff line number Diff line
@@ -573,6 +573,32 @@ int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid)
	return 0;
}

int kvm_vgic_config_vtimer_irqbypass(struct kvm_vcpu *vcpu, u32 vintid,
				bool (*get_as)(struct kvm_vcpu *, int),
				void (*set_as)(struct kvm_vcpu *, int, bool))
{
	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
	struct vtimer_info *vtimer = &vgic_cpu->vtimer;
	struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid);
	unsigned long flags;

	if (WARN_ON_ONCE(!irq || !kvm_vgic_vtimer_irqbypass_support()))
		return -EINVAL;

	vgic_cpu->vtimer_irqbypass = true;

	vtimer->intid = vintid;
	vtimer->get_active_stat = get_as;
	vtimer->set_active_stat = set_as;

	raw_spin_lock_irqsave(&irq->irq_lock, flags);
	irq->vtimer_info = vtimer;
	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
 *
+17 −0
Original line number Diff line number Diff line
@@ -33,6 +33,14 @@
#define irq_is_spi(irq) ((irq) >= VGIC_NR_PRIVATE_IRQS && \
			 (irq) <= VGIC_MAX_SPI)

/* Information about HiSilicon implementation of vtimer (GICv4.1-based) */
struct vtimer_info {
	u32 intid;

	bool (*get_active_stat)(struct kvm_vcpu *vcpu, int vintid);
	void (*set_active_stat)(struct kvm_vcpu *vcpu, int vintid, bool active);
};

/*The number of lpi translation cache lists*/
#define LPI_TRANS_CACHES_NUM 8

@@ -148,6 +156,8 @@ struct vgic_irq {

	void *owner;			/* Opaque pointer to reserve an interrupt
					   for in-kernel devices. */

	struct vtimer_info *vtimer_info;	/* vtimer interrupt only */
};

struct vgic_register_region;
@@ -321,6 +331,10 @@ struct vgic_cpu {

	struct vgic_irq private_irqs[VGIC_NR_PRIVATE_IRQS];

	/* Indicate whether the vtimer irqbypass mode is used */
	bool vtimer_irqbypass;
	struct vtimer_info vtimer;

	raw_spinlock_t ap_list_lock;	/* Protects the ap_list */

	/*
@@ -427,5 +441,8 @@ int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int irq,
int vgic_v4_load(struct kvm_vcpu *vcpu);
void vgic_v4_commit(struct kvm_vcpu *vcpu);
int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db);
int kvm_vgic_config_vtimer_irqbypass(struct kvm_vcpu *vcpu, u32 vintid,
		bool (*get_as)(struct kvm_vcpu *, int),
		void (*set_as)(struct kvm_vcpu *, int, bool));

#endif /* __KVM_ARM_VGIC_H */