|
|
1.1 root 1: /*
2: * KVM in-kernel IOPIC support
3: *
4: * Copyright (c) 2011 Siemens AG
5: *
6: * Authors:
7: * Jan Kiszka <[email protected]>
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 "hw/pc.h"
14: #include "hw/ioapic_internal.h"
15: #include "hw/apic_internal.h"
16: #include "kvm.h"
17:
18: typedef struct KVMIOAPICState KVMIOAPICState;
19:
20: struct KVMIOAPICState {
21: IOAPICCommonState ioapic;
22: uint32_t kvm_gsi_base;
23: };
24:
25: static void kvm_ioapic_get(IOAPICCommonState *s)
26: {
27: struct kvm_irqchip chip;
28: struct kvm_ioapic_state *kioapic;
29: int ret, i;
30:
31: chip.chip_id = KVM_IRQCHIP_IOAPIC;
32: ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, &chip);
33: if (ret < 0) {
34: fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret));
35: abort();
36: }
37:
38: kioapic = &chip.chip.ioapic;
39:
40: s->id = kioapic->id;
41: s->ioregsel = kioapic->ioregsel;
42: s->irr = kioapic->irr;
43: for (i = 0; i < IOAPIC_NUM_PINS; i++) {
44: s->ioredtbl[i] = kioapic->redirtbl[i].bits;
45: }
46: }
47:
48: static void kvm_ioapic_put(IOAPICCommonState *s)
49: {
50: struct kvm_irqchip chip;
51: struct kvm_ioapic_state *kioapic;
52: int ret, i;
53:
54: chip.chip_id = KVM_IRQCHIP_IOAPIC;
55: kioapic = &chip.chip.ioapic;
56:
57: kioapic->id = s->id;
58: kioapic->ioregsel = s->ioregsel;
59: kioapic->base_address = s->busdev.mmio[0].addr;
60: kioapic->irr = s->irr;
61: for (i = 0; i < IOAPIC_NUM_PINS; i++) {
62: kioapic->redirtbl[i].bits = s->ioredtbl[i];
63: }
64:
65: ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, &chip);
66: if (ret < 0) {
67: fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret));
68: abort();
69: }
70: }
71:
72: static void kvm_ioapic_reset(DeviceState *dev)
73: {
74: IOAPICCommonState *s = DO_UPCAST(IOAPICCommonState, busdev.qdev, dev);
75:
76: ioapic_reset_common(dev);
77: kvm_ioapic_put(s);
78: }
79:
80: static void kvm_ioapic_set_irq(void *opaque, int irq, int level)
81: {
82: KVMIOAPICState *s = opaque;
83: int delivered;
84:
85: delivered = kvm_irqchip_set_irq(kvm_state, s->kvm_gsi_base + irq, level);
86: apic_report_irq_delivered(delivered);
87: }
88:
89: static void kvm_ioapic_init(IOAPICCommonState *s, int instance_no)
90: {
91: memory_region_init_reservation(&s->io_memory, "kvm-ioapic", 0x1000);
92:
93: qdev_init_gpio_in(&s->busdev.qdev, kvm_ioapic_set_irq, IOAPIC_NUM_PINS);
94: }
95:
96: static Property kvm_ioapic_properties[] = {
97: DEFINE_PROP_UINT32("gsi_base", KVMIOAPICState, kvm_gsi_base, 0),
98: DEFINE_PROP_END_OF_LIST()
99: };
100:
101: static void kvm_ioapic_class_init(ObjectClass *klass, void *data)
102: {
103: IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
104: DeviceClass *dc = DEVICE_CLASS(klass);
105:
106: k->init = kvm_ioapic_init;
107: k->pre_save = kvm_ioapic_get;
108: k->post_load = kvm_ioapic_put;
109: dc->reset = kvm_ioapic_reset;
110: dc->props = kvm_ioapic_properties;
111: }
112:
113: static TypeInfo kvm_ioapic_info = {
114: .name = "kvm-ioapic",
115: .parent = TYPE_IOAPIC_COMMON,
116: .instance_size = sizeof(KVMIOAPICState),
117: .class_init = kvm_ioapic_class_init,
118: };
119:
120: static void kvm_ioapic_register_types(void)
121: {
122: type_register_static(&kvm_ioapic_info);
123: }
124:
125: type_init(kvm_ioapic_register_types)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.