root / hw / kvm / ioapic.c @ edc92115
History | View | Annotate | Download (3.1 kB)
1 | a39c1d47 | Jan Kiszka | /*
|
---|---|---|---|
2 | a39c1d47 | Jan Kiszka | * KVM in-kernel IOPIC support
|
3 | a39c1d47 | Jan Kiszka | *
|
4 | a39c1d47 | Jan Kiszka | * Copyright (c) 2011 Siemens AG
|
5 | a39c1d47 | Jan Kiszka | *
|
6 | a39c1d47 | Jan Kiszka | * Authors:
|
7 | a39c1d47 | Jan Kiszka | * Jan Kiszka <jan.kiszka@siemens.com>
|
8 | a39c1d47 | Jan Kiszka | *
|
9 | a39c1d47 | Jan Kiszka | * This work is licensed under the terms of the GNU GPL version 2.
|
10 | a39c1d47 | Jan Kiszka | * See the COPYING file in the top-level directory.
|
11 | a39c1d47 | Jan Kiszka | */
|
12 | a39c1d47 | Jan Kiszka | |
13 | a39c1d47 | Jan Kiszka | #include "hw/pc.h" |
14 | a39c1d47 | Jan Kiszka | #include "hw/ioapic_internal.h" |
15 | a39c1d47 | Jan Kiszka | #include "hw/apic_internal.h" |
16 | a39c1d47 | Jan Kiszka | #include "kvm.h" |
17 | a39c1d47 | Jan Kiszka | |
18 | a39c1d47 | Jan Kiszka | typedef struct KVMIOAPICState KVMIOAPICState; |
19 | a39c1d47 | Jan Kiszka | |
20 | a39c1d47 | Jan Kiszka | struct KVMIOAPICState {
|
21 | a39c1d47 | Jan Kiszka | IOAPICCommonState ioapic; |
22 | a39c1d47 | Jan Kiszka | uint32_t kvm_gsi_base; |
23 | a39c1d47 | Jan Kiszka | }; |
24 | a39c1d47 | Jan Kiszka | |
25 | a39c1d47 | Jan Kiszka | static void kvm_ioapic_get(IOAPICCommonState *s) |
26 | a39c1d47 | Jan Kiszka | { |
27 | a39c1d47 | Jan Kiszka | struct kvm_irqchip chip;
|
28 | a39c1d47 | Jan Kiszka | struct kvm_ioapic_state *kioapic;
|
29 | a39c1d47 | Jan Kiszka | int ret, i;
|
30 | a39c1d47 | Jan Kiszka | |
31 | a39c1d47 | Jan Kiszka | chip.chip_id = KVM_IRQCHIP_IOAPIC; |
32 | a39c1d47 | Jan Kiszka | ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, &chip); |
33 | a39c1d47 | Jan Kiszka | if (ret < 0) { |
34 | a39c1d47 | Jan Kiszka | fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret));
|
35 | a39c1d47 | Jan Kiszka | abort(); |
36 | a39c1d47 | Jan Kiszka | } |
37 | a39c1d47 | Jan Kiszka | |
38 | a39c1d47 | Jan Kiszka | kioapic = &chip.chip.ioapic; |
39 | a39c1d47 | Jan Kiszka | |
40 | a39c1d47 | Jan Kiszka | s->id = kioapic->id; |
41 | a39c1d47 | Jan Kiszka | s->ioregsel = kioapic->ioregsel; |
42 | a39c1d47 | Jan Kiszka | s->irr = kioapic->irr; |
43 | a39c1d47 | Jan Kiszka | for (i = 0; i < IOAPIC_NUM_PINS; i++) { |
44 | a39c1d47 | Jan Kiszka | s->ioredtbl[i] = kioapic->redirtbl[i].bits; |
45 | a39c1d47 | Jan Kiszka | } |
46 | a39c1d47 | Jan Kiszka | } |
47 | a39c1d47 | Jan Kiszka | |
48 | a39c1d47 | Jan Kiszka | static void kvm_ioapic_put(IOAPICCommonState *s) |
49 | a39c1d47 | Jan Kiszka | { |
50 | a39c1d47 | Jan Kiszka | struct kvm_irqchip chip;
|
51 | a39c1d47 | Jan Kiszka | struct kvm_ioapic_state *kioapic;
|
52 | a39c1d47 | Jan Kiszka | int ret, i;
|
53 | a39c1d47 | Jan Kiszka | |
54 | a39c1d47 | Jan Kiszka | chip.chip_id = KVM_IRQCHIP_IOAPIC; |
55 | a39c1d47 | Jan Kiszka | kioapic = &chip.chip.ioapic; |
56 | a39c1d47 | Jan Kiszka | |
57 | a39c1d47 | Jan Kiszka | kioapic->id = s->id; |
58 | a39c1d47 | Jan Kiszka | kioapic->ioregsel = s->ioregsel; |
59 | a39c1d47 | Jan Kiszka | kioapic->base_address = s->busdev.mmio[0].addr;
|
60 | a39c1d47 | Jan Kiszka | kioapic->irr = s->irr; |
61 | a39c1d47 | Jan Kiszka | for (i = 0; i < IOAPIC_NUM_PINS; i++) { |
62 | a39c1d47 | Jan Kiszka | kioapic->redirtbl[i].bits = s->ioredtbl[i]; |
63 | a39c1d47 | Jan Kiszka | } |
64 | a39c1d47 | Jan Kiszka | |
65 | a39c1d47 | Jan Kiszka | ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, &chip); |
66 | a39c1d47 | Jan Kiszka | if (ret < 0) { |
67 | a39c1d47 | Jan Kiszka | fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret));
|
68 | a39c1d47 | Jan Kiszka | abort(); |
69 | a39c1d47 | Jan Kiszka | } |
70 | a39c1d47 | Jan Kiszka | } |
71 | a39c1d47 | Jan Kiszka | |
72 | a39c1d47 | Jan Kiszka | static void kvm_ioapic_reset(DeviceState *dev) |
73 | a39c1d47 | Jan Kiszka | { |
74 | a39c1d47 | Jan Kiszka | IOAPICCommonState *s = DO_UPCAST(IOAPICCommonState, busdev.qdev, dev); |
75 | a39c1d47 | Jan Kiszka | |
76 | a39c1d47 | Jan Kiszka | ioapic_reset_common(dev); |
77 | a39c1d47 | Jan Kiszka | kvm_ioapic_put(s); |
78 | a39c1d47 | Jan Kiszka | } |
79 | a39c1d47 | Jan Kiszka | |
80 | a39c1d47 | Jan Kiszka | static void kvm_ioapic_set_irq(void *opaque, int irq, int level) |
81 | a39c1d47 | Jan Kiszka | { |
82 | a39c1d47 | Jan Kiszka | KVMIOAPICState *s = opaque; |
83 | a39c1d47 | Jan Kiszka | int delivered;
|
84 | a39c1d47 | Jan Kiszka | |
85 | a39c1d47 | Jan Kiszka | delivered = kvm_irqchip_set_irq(kvm_state, s->kvm_gsi_base + irq, level); |
86 | a39c1d47 | Jan Kiszka | apic_report_irq_delivered(delivered); |
87 | a39c1d47 | Jan Kiszka | } |
88 | a39c1d47 | Jan Kiszka | |
89 | a39c1d47 | Jan Kiszka | static void kvm_ioapic_init(IOAPICCommonState *s, int instance_no) |
90 | a39c1d47 | Jan Kiszka | { |
91 | a39c1d47 | Jan Kiszka | memory_region_init_reservation(&s->io_memory, "kvm-ioapic", 0x1000); |
92 | a39c1d47 | Jan Kiszka | |
93 | a39c1d47 | Jan Kiszka | qdev_init_gpio_in(&s->busdev.qdev, kvm_ioapic_set_irq, IOAPIC_NUM_PINS); |
94 | a39c1d47 | Jan Kiszka | } |
95 | a39c1d47 | Jan Kiszka | |
96 | 39bffca2 | Anthony Liguori | static Property kvm_ioapic_properties[] = {
|
97 | 39bffca2 | Anthony Liguori | DEFINE_PROP_UINT32("gsi_base", KVMIOAPICState, kvm_gsi_base, 0), |
98 | 39bffca2 | Anthony Liguori | DEFINE_PROP_END_OF_LIST() |
99 | 39bffca2 | Anthony Liguori | }; |
100 | 39bffca2 | Anthony Liguori | |
101 | 999e12bb | Anthony Liguori | static void kvm_ioapic_class_init(ObjectClass *klass, void *data) |
102 | 999e12bb | Anthony Liguori | { |
103 | 999e12bb | Anthony Liguori | IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass); |
104 | 39bffca2 | Anthony Liguori | DeviceClass *dc = DEVICE_CLASS(klass); |
105 | 999e12bb | Anthony Liguori | |
106 | 999e12bb | Anthony Liguori | k->init = kvm_ioapic_init; |
107 | 999e12bb | Anthony Liguori | k->pre_save = kvm_ioapic_get; |
108 | 999e12bb | Anthony Liguori | k->post_load = kvm_ioapic_put; |
109 | 39bffca2 | Anthony Liguori | dc->reset = kvm_ioapic_reset; |
110 | 39bffca2 | Anthony Liguori | dc->props = kvm_ioapic_properties; |
111 | 999e12bb | Anthony Liguori | } |
112 | 999e12bb | Anthony Liguori | |
113 | 39bffca2 | Anthony Liguori | static TypeInfo kvm_ioapic_info = {
|
114 | 999e12bb | Anthony Liguori | .name = "kvm-ioapic",
|
115 | 39bffca2 | Anthony Liguori | .parent = TYPE_IOAPIC_COMMON, |
116 | 39bffca2 | Anthony Liguori | .instance_size = sizeof(KVMIOAPICState),
|
117 | 999e12bb | Anthony Liguori | .class_init = kvm_ioapic_class_init, |
118 | a39c1d47 | Jan Kiszka | }; |
119 | a39c1d47 | Jan Kiszka | |
120 | 83f7d43a | Andreas Färber | static void kvm_ioapic_register_types(void) |
121 | a39c1d47 | Jan Kiszka | { |
122 | 39bffca2 | Anthony Liguori | type_register_static(&kvm_ioapic_info); |
123 | a39c1d47 | Jan Kiszka | } |
124 | a39c1d47 | Jan Kiszka | |
125 | 83f7d43a | Andreas Färber | type_init(kvm_ioapic_register_types) |