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