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

KVM: arm64: GICv4.1: Enable vtimer vPPI irqbypass config

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


CVE: NA

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

Plumb the configuration of vtimer interrupts into the first VCPU run.

The restore of a guest will also benefit from it. By configering
vPPIs at first run, we can move the restored PPIs to the HW if
that's what the HW allows us to do.

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 9eb939d9
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -596,6 +596,10 @@ int vgic_v3_map_resources(struct kvm *kvm)

	if (kvm_vgic_global_state.has_gicv4_1)
		vgic_v4_configure_vsgis(kvm);

	if (kvm_vgic_vtimer_irqbypass_support())
		vgic_v4_configure_vtimer(kvm);

	dist->ready = true;

out:
+46 −0
Original line number Diff line number Diff line
@@ -203,6 +203,52 @@ void vgic_v4_configure_vsgis(struct kvm *kvm)
	kvm_arm_resume_guest(kvm);
}

static void vgic_v4_enable_vtimer(struct kvm_vcpu *vcpu)
{
	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
	struct vtimer_info *vtimer = &vgic_cpu->vtimer;
	struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
	struct vgic_irq *irq;
	struct irq_desc *desc;
	int ret;

	if (!vgic_cpu->vtimer_irqbypass)
		return;

	irq = vgic_get_irq(vcpu->kvm, vcpu, vtimer->intid);
	irq->host_irq = irq_find_mapping(vpe->sgi_domain, vtimer->intid);

	/* Transfer the full irq state to the vPE */
	vgic_v4_sync_sgi_config(vpe, irq);
	desc = irq_to_desc(irq->host_irq);
	ret = irq_domain_activate_irq(irq_desc_get_irq_data(desc),
				      false);
	if (!WARN_ON(ret)) {
		/* Transfer pending state */
		ret = irq_set_irqchip_state(irq->host_irq,
					    IRQCHIP_STATE_PENDING,
					    irq->pending_latch);
		WARN_ON(ret);
		irq->pending_latch = false;

		/* Transfer active state */
		vtimer->set_active_stat(vcpu, irq->intid, irq->active);
		irq->active = false;
	}

	vgic_put_irq(vcpu->kvm, irq);
}

/* Must be called with the kvm lock held */
void vgic_v4_configure_vtimer(struct kvm *kvm)
{
	struct kvm_vcpu *vcpu;
	int i;

	kvm_for_each_vcpu(i, vcpu, kvm)
		vgic_v4_enable_vtimer(vcpu);
}

/*
 * Must be called with GICv4.1 and the vPE unmapped, which
 * indicates the invalidation of any VPT caches associated
+1 −0
Original line number Diff line number Diff line
@@ -328,5 +328,6 @@ int vgic_v4_init(struct kvm *kvm);
void vgic_v4_teardown(struct kvm *kvm);
void vgic_v4_configure_vsgis(struct kvm *kvm);
void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val);
void vgic_v4_configure_vtimer(struct kvm *kvm);

#endif