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
kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry * e,struct kvm * kvm,int irq_source_id,int level,bool line_status)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 */
kvm_set_msi(struct kvm_kernel_irq_routing_entry * e,struct kvm * kvm,int irq_source_id,int level,bool line_status)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 */
kvm_set_routing_entry(struct kvm * kvm,struct kvm_kernel_irq_routing_entry * e,const struct kvm_irq_routing_entry * ue)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
kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry * e,struct kvm * kvm,int irq_source_id,int level,bool line_status)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
kvm_arch_intc_initialized(struct kvm * kvm)86 bool kvm_arch_intc_initialized(struct kvm *kvm)
87 {
88 return kvm_arch_irqchip_in_kernel(kvm);
89 }
90