qemu-kvm: Fix GSI handling with in-kernel irqchip
[qemu-kvm.git] / qemu-kvm-x86.c
bloba7981b17795f0c02c37dd04b73512e280247d159
1 /*
2 * qemu/kvm integration, x86 specific code
4 * Copyright (C) 2006-2008 Qumranet Technologies
6 * Licensed under the terms of the GNU GPL version 2 or higher.
7 */
9 #include "config.h"
10 #include "config-host.h"
12 #include <string.h>
13 #include "hw/hw.h"
14 #include "gdbstub.h"
15 #include <sys/io.h>
17 #include "qemu-kvm.h"
18 #include <pthread.h>
19 #include <sys/utsname.h>
20 #include <linux/kvm_para.h>
21 #include <sys/ioctl.h>
23 #include "kvm.h"
24 #include "hw/apic.h"
26 static int kvm_create_pit(KVMState *s)
28 int r;
30 if (kvm_pit) {
31 r = kvm_vm_ioctl(s, KVM_CREATE_PIT);
32 if (r < 0) {
33 fprintf(stderr, "Create kernel PIC irqchip failed\n");
34 return r;
36 if (!kvm_pit_reinject) {
37 r = kvm_reinject_control(s, 0);
38 if (r < 0) {
39 fprintf(stderr,
40 "failure to disable in-kernel PIT reinjection\n");
41 return r;
45 return 0;
48 int kvm_handle_tpr_access(CPUState *env)
50 struct kvm_run *run = env->kvm_run;
51 kvm_tpr_access_report(env,
52 run->tpr_access.rip,
53 run->tpr_access.is_write);
54 return 1;
58 int kvm_enable_vapic(CPUState *env, uint64_t vapic)
60 struct kvm_vapic_addr va = {
61 .vapic_addr = vapic,
64 return kvm_vcpu_ioctl(env, KVM_SET_VAPIC_ADDR, &va);
67 int kvm_get_lapic(CPUState *env, struct kvm_lapic_state *s)
69 int r = 0;
71 if (!kvm_irqchip_in_kernel()) {
72 return r;
75 r = kvm_vcpu_ioctl(env, KVM_GET_LAPIC, s);
76 if (r < 0) {
77 fprintf(stderr, "KVM_GET_LAPIC failed\n");
79 return r;
82 int kvm_set_lapic(CPUState *env, struct kvm_lapic_state *s)
84 int r = 0;
86 if (!kvm_irqchip_in_kernel()) {
87 return 0;
90 r = kvm_vcpu_ioctl(env, KVM_SET_LAPIC, s);
92 if (r < 0) {
93 fprintf(stderr, "KVM_SET_LAPIC failed\n");
95 return r;
98 int kvm_get_pit(KVMState *s, struct kvm_pit_state *pit_state)
100 if (!kvm_pit_in_kernel()) {
101 return 0;
103 return kvm_vm_ioctl(s, KVM_GET_PIT, pit_state);
106 int kvm_set_pit(KVMState *s, struct kvm_pit_state *pit_state)
108 if (!kvm_pit_in_kernel()) {
109 return 0;
111 return kvm_vm_ioctl(s, KVM_SET_PIT, pit_state);
114 int kvm_get_pit2(KVMState *s, struct kvm_pit_state2 *ps2)
116 if (!kvm_pit_in_kernel()) {
117 return 0;
119 return kvm_vm_ioctl(s, KVM_GET_PIT2, ps2);
122 int kvm_set_pit2(KVMState *s, struct kvm_pit_state2 *ps2)
124 if (!kvm_pit_in_kernel()) {
125 return 0;
127 return kvm_vm_ioctl(s, KVM_SET_PIT2, ps2);
130 static int kvm_enable_tpr_access_reporting(CPUState *env)
132 int r;
133 struct kvm_tpr_access_ctl tac = { .enabled = 1 };
135 r = kvm_ioctl(env->kvm_state, KVM_CHECK_EXTENSION, KVM_CAP_VAPIC);
136 if (r <= 0) {
137 return -ENOSYS;
139 return kvm_vcpu_ioctl(env, KVM_TPR_ACCESS_REPORTING, &tac);
142 static int _kvm_arch_init_vcpu(CPUState *env)
144 kvm_arch_reset_vcpu(env);
146 kvm_enable_tpr_access_reporting(env);
148 return kvm_update_ioport_access(env);
151 #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
152 int kvm_arch_set_ioport_access(unsigned long start, unsigned long size,
153 bool enable)
155 if (ioperm(start, size, enable) < 0) {
156 return -errno;
158 return 0;
160 #endif
163 * Setup x86 specific IRQ routing
165 int kvm_arch_init_irq_routing(void)
167 int i, r;
169 if (kvm_has_gsi_routing()) {
170 kvm_clear_gsi_routes();
171 for (i = 0; i < 8; ++i) {
172 if (i == 2) {
173 continue;
175 r = kvm_add_irq_route(i, KVM_IRQCHIP_PIC_MASTER, i);
176 if (r < 0) {
177 return r;
180 for (i = 8; i < 16; ++i) {
181 r = kvm_add_irq_route(i, KVM_IRQCHIP_PIC_SLAVE, i - 8);
182 if (r < 0) {
183 return r;
186 for (i = 0; i < 24; ++i) {
187 if (i == 0) {
188 r = kvm_add_irq_route(i, KVM_IRQCHIP_IOAPIC, 2);
189 } else if (i != 2) {
190 r = kvm_add_irq_route(i, KVM_IRQCHIP_IOAPIC, i);
192 if (r < 0) {
193 return r;
196 kvm_commit_irq_routes();
198 if (!kvm_has_pit_state2()) {
199 no_hpet = 1;
201 } else {
202 /* If kernel can't do irq routing, interrupt source
203 * override 0->2 can not be set up as required by HPET.
204 * so we have to disable it.
206 no_hpet = 1;
209 return 0;