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