1 /* 2 * KVM in-kernel IOPIC support 3 * 4 * Copyright (c) 2011 Siemens AG 5 * 6 * Authors: 7 * Jan Kiszka <jan.kiszka@siemens.com> 8 * 9 * This work is licensed under the terms of the GNU GPL version 2. 10 * See the COPYING file in the top-level directory. 11 */ 12 13 #include "qemu/osdep.h" 14 #include "monitor/monitor.h" 15 #include "hw/i386/pc.h" 16 #include "hw/i386/ioapic_internal.h" 17 #include "hw/i386/apic_internal.h" 18 #include "sysemu/kvm.h" 19 20 /* PC Utility function */ 21 void kvm_pc_setup_irq_routing(bool pci_enabled) 22 { 23 KVMState *s = kvm_state; 24 int i; 25 26 if (kvm_check_extension(s, KVM_CAP_IRQ_ROUTING)) { 27 for (i = 0; i < 8; ++i) { 28 if (i == 2) { 29 continue; 30 } 31 kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_PIC_MASTER, i); 32 } 33 for (i = 8; i < 16; ++i) { 34 kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_PIC_SLAVE, i - 8); 35 } 36 if (pci_enabled) { 37 for (i = 0; i < 24; ++i) { 38 if (i == 0) { 39 kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_IOAPIC, 2); 40 } else if (i != 2) { 41 kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_IOAPIC, i); 42 } 43 } 44 } 45 kvm_irqchip_commit_routes(s); 46 } 47 } 48 49 void kvm_pc_gsi_handler(void *opaque, int n, int level) 50 { 51 GSIState *s = opaque; 52 53 if (n < ISA_NUM_IRQS) { 54 /* Kernel will forward to both PIC and IOAPIC */ 55 qemu_set_irq(s->i8259_irq[n], level); 56 } else { 57 qemu_set_irq(s->ioapic_irq[n], level); 58 } 59 } 60 61 typedef struct KVMIOAPICState KVMIOAPICState; 62 63 struct KVMIOAPICState { 64 IOAPICCommonState ioapic; 65 uint32_t kvm_gsi_base; 66 }; 67 68 static void kvm_ioapic_get(IOAPICCommonState *s) 69 { 70 struct kvm_irqchip chip; 71 struct kvm_ioapic_state *kioapic; 72 int ret, i; 73 74 chip.chip_id = KVM_IRQCHIP_IOAPIC; 75 ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, &chip); 76 if (ret < 0) { 77 fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); 78 abort(); 79 } 80 81 kioapic = &chip.chip.ioapic; 82 83 s->id = kioapic->id; 84 s->ioregsel = kioapic->ioregsel; 85 s->irr = kioapic->irr; 86 for (i = 0; i < IOAPIC_NUM_PINS; i++) { 87 s->ioredtbl[i] = kioapic->redirtbl[i].bits; 88 } 89 } 90 91 static void kvm_ioapic_put(IOAPICCommonState *s) 92 { 93 struct kvm_irqchip chip; 94 struct kvm_ioapic_state *kioapic; 95 int ret, i; 96 97 chip.chip_id = KVM_IRQCHIP_IOAPIC; 98 kioapic = &chip.chip.ioapic; 99 100 kioapic->id = s->id; 101 kioapic->ioregsel = s->ioregsel; 102 kioapic->base_address = s->busdev.mmio[0].addr; 103 kioapic->irr = s->irr; 104 for (i = 0; i < IOAPIC_NUM_PINS; i++) { 105 kioapic->redirtbl[i].bits = s->ioredtbl[i]; 106 } 107 108 ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, &chip); 109 if (ret < 0) { 110 fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); 111 abort(); 112 } 113 } 114 115 void kvm_ioapic_dump_state(Monitor *mon, const QDict *qdict) 116 { 117 IOAPICCommonState *s = IOAPIC_COMMON(object_resolve_path("ioapic", NULL)); 118 119 assert(s); 120 kvm_ioapic_get(s); 121 ioapic_print_redtbl(mon, s); 122 } 123 124 static void kvm_ioapic_reset(DeviceState *dev) 125 { 126 IOAPICCommonState *s = IOAPIC_COMMON(dev); 127 128 ioapic_reset_common(dev); 129 kvm_ioapic_put(s); 130 } 131 132 static void kvm_ioapic_set_irq(void *opaque, int irq, int level) 133 { 134 KVMIOAPICState *s = opaque; 135 int delivered; 136 137 delivered = kvm_set_irq(kvm_state, s->kvm_gsi_base + irq, level); 138 apic_report_irq_delivered(delivered); 139 } 140 141 static void kvm_ioapic_realize(DeviceState *dev, Error **errp) 142 { 143 IOAPICCommonState *s = IOAPIC_COMMON(dev); 144 145 memory_region_init_io(&s->io_memory, OBJECT(dev), NULL, NULL, "kvm-ioapic", 0x1000); 146 /* 147 * KVM ioapic only supports 0x11 now. This will only be used when 148 * we want to dump ioapic version. 149 */ 150 s->version = 0x11; 151 152 qdev_init_gpio_in(dev, kvm_ioapic_set_irq, IOAPIC_NUM_PINS); 153 } 154 155 static Property kvm_ioapic_properties[] = { 156 DEFINE_PROP_UINT32("gsi_base", KVMIOAPICState, kvm_gsi_base, 0), 157 DEFINE_PROP_END_OF_LIST() 158 }; 159 160 static void kvm_ioapic_class_init(ObjectClass *klass, void *data) 161 { 162 IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass); 163 DeviceClass *dc = DEVICE_CLASS(klass); 164 165 k->realize = kvm_ioapic_realize; 166 k->pre_save = kvm_ioapic_get; 167 k->post_load = kvm_ioapic_put; 168 dc->reset = kvm_ioapic_reset; 169 dc->props = kvm_ioapic_properties; 170 } 171 172 static const TypeInfo kvm_ioapic_info = { 173 .name = "kvm-ioapic", 174 .parent = TYPE_IOAPIC_COMMON, 175 .instance_size = sizeof(KVMIOAPICState), 176 .class_init = kvm_ioapic_class_init, 177 }; 178 179 static void kvm_ioapic_register_types(void) 180 { 181 type_register_static(&kvm_ioapic_info); 182 } 183 184 type_init(kvm_ioapic_register_types) 185