xref: /linux/arch/loongarch/kvm/irqfd.c (revision 7f4f3b14e8079ecde096bd734af10e30d40c27b7)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2024 Loongson Technology Corporation Limited
4  */
5 
6 #include <linux/kvm_host.h>
7 #include <trace/events/kvm.h>
8 #include <asm/kvm_pch_pic.h>
9 
10 static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
11 		struct kvm *kvm, int irq_source_id, int level, bool line_status)
12 {
13 	/* PCH-PIC pin (0 ~ 64) <---> GSI (0 ~ 64) */
14 	pch_pic_set_irq(kvm->arch.pch_pic, e->irqchip.pin, level);
15 
16 	return 0;
17 }
18 
19 /*
20  * kvm_set_msi: inject the MSI corresponding to the
21  * MSI routing entry
22  *
23  * This is the entry point for irqfd MSI injection
24  * and userspace MSI injection.
25  */
26 int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
27 		struct kvm *kvm, int irq_source_id, int level, bool line_status)
28 {
29 	if (!level)
30 		return -1;
31 
32 	pch_msi_set_irq(kvm, e->msi.data, level);
33 
34 	return 0;
35 }
36 
37 /*
38  * kvm_set_routing_entry: populate a kvm routing entry
39  * from a user routing entry
40  *
41  * @kvm: the VM this entry is applied to
42  * @e: kvm kernel routing entry handle
43  * @ue: user api routing entry handle
44  * return 0 on success, -EINVAL on errors.
45  */
46 int kvm_set_routing_entry(struct kvm *kvm,
47 			struct kvm_kernel_irq_routing_entry *e,
48 			const struct kvm_irq_routing_entry *ue)
49 {
50 	switch (ue->type) {
51 	case KVM_IRQ_ROUTING_IRQCHIP:
52 		e->set = kvm_set_pic_irq;
53 		e->irqchip.irqchip = ue->u.irqchip.irqchip;
54 		e->irqchip.pin = ue->u.irqchip.pin;
55 
56 		if (e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS)
57 			return -EINVAL;
58 
59 		return 0;
60 	case KVM_IRQ_ROUTING_MSI:
61 		e->set = kvm_set_msi;
62 		e->msi.address_lo = ue->u.msi.address_lo;
63 		e->msi.address_hi = ue->u.msi.address_hi;
64 		e->msi.data = ue->u.msi.data;
65 		return 0;
66 	default:
67 		return -EINVAL;
68 	}
69 }
70 
71 int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
72 		struct kvm *kvm, int irq_source_id, int level, bool line_status)
73 {
74 	switch (e->type) {
75 	case KVM_IRQ_ROUTING_IRQCHIP:
76 		pch_pic_set_irq(kvm->arch.pch_pic, e->irqchip.pin, level);
77 		return 0;
78 	case KVM_IRQ_ROUTING_MSI:
79 		pch_msi_set_irq(kvm, e->msi.data, level);
80 		return 0;
81 	default:
82 		return -EWOULDBLOCK;
83 	}
84 }
85 
86 bool kvm_arch_intc_initialized(struct kvm *kvm)
87 {
88 	return kvm_arch_irqchip_in_kernel(kvm);
89 }
90