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

KVM: arm64: sdev: Support virq bypass by INT/VSYNC command

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


CVE: NA

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

We already have the set_irqchip_state() callback which will issue
INT/VSYNC commands on the physical side when the handled IRQ is
forwarded to vcpu.  It was intended to be used to handle the guest
INT command targeting a VLPI.

Let's reuse this hack to set the virtio-pci function's VLPI pending,
instead of directly writing message data into GITS_TRANSLATER, which
should only be treated as the Message Address of PCI devices.

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 b5100c97
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -119,6 +119,21 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
	return vgic_its_inject_msi(kvm, &msi);
}

static int kvm_arch_set_irq_bypass(struct kvm_kernel_irq_routing_entry *e,
				  struct kvm *kvm)
{
	struct kire_data *cache = &e->cache;

	/*
	 * FIXME: is there any race against the irqfd_update(),
	 * where the cache data will be updated?
	 */
	if (!cache->valid)
		return -EWOULDBLOCK;

	return shadow_dev_virq_bypass_inject(kvm, e);
}

/**
 * kvm_arch_set_irq_inatomic: fast-path for irqfd injection
 */
@@ -136,6 +151,9 @@ int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
		if (!vgic_has_its(kvm))
			break;

		if (!kvm_arch_set_irq_bypass(e, kvm))
			return 0;

		kvm_populate_msi(e, &msi);
		return vgic_its_inject_cached_translation(kvm, &msi);
	}
+2 −0
Original line number Diff line number Diff line
@@ -474,4 +474,6 @@ void kvm_shadow_dev_delete(struct kvm *kvm, u32 devid);
void kvm_shadow_dev_delete_all(struct kvm *kvm);
struct shadow_dev *kvm_shadow_dev_get(struct kvm *kvm, struct kvm_msi *msi);

int shadow_dev_virq_bypass_inject(struct kvm *kvm,
				  struct kvm_kernel_irq_routing_entry *e);
#endif /* __KVM_ARM_VGIC_H */