From: wanghaibin wanghaibin.wang@huawei.com
virt inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8UROS 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 | 1 + include/linux/kvm_host.h | 9 +++++++++ virt/kvm/eventfd.c | 8 ++++++++ 4 files changed, 39 insertions(+)
diff --git a/arch/arm64/kvm/vgic/vgic-irqfd.c b/arch/arm64/kvm/vgic/vgic-irqfd.c index 475059bacedf..39b86a60b957 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 7f5debfd45a6..fa02ab5ef144 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -495,5 +495,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 fb6c6109fdca..a5d156dabbf7 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -631,6 +631,11 @@ struct kvm_xen_evtchn { u32 priority; };
+struct kire_data { + bool valid; + void *data; +}; + struct kvm_kernel_irq_routing_entry { u32 gsi; u32 type; @@ -654,6 +659,8 @@ struct kvm_kernel_irq_routing_entry { struct kvm_xen_evtchn xen_evtchn; }; struct hlist_node link; + + struct kire_data cache; };
#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING @@ -1640,6 +1647,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); /* * Returns a pointer to the memslot if it contains gfn. * Otherwise returns NULL. diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index 89912a17f5d5..ae8407ecce9c 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) { @@ -270,6 +276,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); }