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

KVM: arm64: kire: irq routing entry cached the relevant cache data

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: 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 013f5894
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -9,6 +9,29 @@
#include <kvm/arm_vgic.h>
#include "vgic.h"

#ifdef CONFIG_VIRT_PLAT_DEV
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;
}
#endif

/**
 * vgic_irqfd_set_irq: inject the IRQ corresponding to the
 * irqchip routing entry
+1 −0
Original line number Diff line number Diff line
@@ -465,6 +465,7 @@ 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

#endif /* __KVM_ARM_VGIC_H */
+16 −0
Original line number Diff line number Diff line
@@ -631,6 +631,13 @@ struct kvm_xen_evtchn {
	u32 priority;
};

#ifdef CONFIG_VIRT_PLAT_DEV
struct kire_data {
	bool    valid;
	void    *data;
};
#endif

struct kvm_kernel_irq_routing_entry {
	u32 gsi;
	u32 type;
@@ -654,6 +661,10 @@ struct kvm_kernel_irq_routing_entry {
		struct kvm_xen_evtchn xen_evtchn;
	};
	struct hlist_node link;

#ifdef CONFIG_VIRT_PLAT_DEV
	struct kire_data cache;
#endif
};

#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
@@ -1640,6 +1651,11 @@ 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);

#ifdef CONFIG_VIRT_PLAT_DEV
void kire_arch_cached_data_update(struct kvm *kvm,
				  struct kvm_kernel_irq_routing_entry *e);
#endif

/*
 * Returns a pointer to the memslot if it contains gfn.
 * Otherwise returns NULL.
+11 −0
Original line number Diff line number Diff line
@@ -38,6 +38,14 @@ kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args)
	return true;
}

#ifdef CONFIG_VIRT_PLAT_DEV
void __weak
kire_arch_cached_data_update(struct kvm *kvm,
			     struct kvm_kernel_irq_routing_entry *e)
{
}
#endif

static void
irqfd_inject(struct work_struct *work)
{
@@ -270,6 +278,9 @@ static void irqfd_update(struct kvm *kvm, struct kvm_kernel_irqfd *irqfd)
	else
		irqfd->irq_entry.type = 0;

#ifdef CONFIG_VIRT_PLAT_DEV
	kire_arch_cached_data_update(kvm, &irqfd->irq_entry);
#endif
	write_seqcount_end(&irqfd->irq_entry_sc);
}