From: wanghaibin wanghaibin.wang@huawei.com
virt inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8K8HP CVE: NA
--------------------------------
For each kernel irq routing entry, cached the relevant virtual shadow device, for IRQ bypass inject in future.
Signed-off-by: wanghaibin wanghaibin.wang@huawei.com Signed-off-by: Zenghui Yu yuzenghui@huawei.com Signed-off-by: Kunkun Jiang jiangkunkun@huawei.com Signed-off-by: Dongxu Sun sundongxu3@huawei.com --- arch/arm64/kvm/vgic/vgic-irqfd.c | 21 +++++++++++++++++++++ include/kvm/arm_vgic.h | 2 ++ include/linux/kvm_host.h | 9 +++++++++ virt/kvm/eventfd.c | 8 ++++++++ 4 files changed, 40 insertions(+)
diff --git a/arch/arm64/kvm/vgic/vgic-irqfd.c b/arch/arm64/kvm/vgic/vgic-irqfd.c index 79f8899b234c..989a2669db71 100644 --- a/arch/arm64/kvm/vgic/vgic-irqfd.c +++ b/arch/arm64/kvm/vgic/vgic-irqfd.c @@ -9,6 +9,27 @@ #include <kvm/arm_vgic.h> #include "vgic.h"
+static void kvm_populate_msi(struct kvm_kernel_irq_routing_entry *e, + struct kvm_msi *msi); + +void kire_arch_cached_data_update(struct kvm *kvm, + struct kvm_kernel_irq_routing_entry *e) +{ + struct vgic_dist *dist = &kvm->arch.vgic; + struct kire_data *cache = &e->cache; + struct shadow_dev *sdev; + struct kvm_msi msi; + + kvm_populate_msi(e, &msi); + + raw_spin_lock(&dist->sdev_list_lock); + sdev = kvm_shadow_dev_get(kvm, &msi); + raw_spin_unlock(&dist->sdev_list_lock); + + cache->valid = !!sdev; + cache->data = sdev; +} + /** * vgic_irqfd_set_irq: inject the IRQ corresponding to the * irqchip routing entry diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index a8717362d409..98f93583aa57 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -472,4 +472,6 @@ void kvm_shadow_dev_init(void); int kvm_shadow_dev_create(struct kvm *kvm, struct kvm_master_dev_info *mdi); 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); + #endif /* __KVM_ARM_VGIC_H */ diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 148bffa3a994..8963e46d64d2 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -402,6 +402,11 @@ struct kvm_hv_sint { u32 sint; };
+struct kire_data { + bool valid; + void *data; +}; + struct kvm_kernel_irq_routing_entry { u32 gsi; u32 type; @@ -424,6 +429,8 @@ struct kvm_kernel_irq_routing_entry { struct kvm_hv_sint hv_sint; }; struct hlist_node link; + + struct kire_data cache; };
#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING @@ -1121,6 +1128,8 @@ int kvm_request_irq_source_id(struct kvm *kvm); void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args);
+void kire_arch_cached_data_update(struct kvm *kvm, + struct kvm_kernel_irq_routing_entry *e); /* * search_memslots() and __gfn_to_memslot() are here because they are * used in non-modular code in arch/powerpc/kvm/book3s_hv_rm_mmu.c. diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index 518cd8dc390e..d6309fc89518 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c @@ -38,6 +38,12 @@ kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args) return true; }
+void __attribute__((weak)) +kire_arch_cached_data_update(struct kvm *kvm, + struct kvm_kernel_irq_routing_entry *e) +{ +} + static void irqfd_inject(struct work_struct *work) { @@ -256,6 +262,8 @@ static void irqfd_update(struct kvm *kvm, struct kvm_kernel_irqfd *irqfd) else irqfd->irq_entry.type = 0;
+ kire_arch_cached_data_update(kvm, &irqfd->irq_entry); + write_seqcount_end(&irqfd->irq_entry_sc); }