Merge branch 'upstream-merge' into next
[qemu-dev-zwu.git] / qemu-kvm-x86.c
blob2a01ccc885f8f4caa8bf13293863917c949d0dda
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 #ifdef KVM_CAP_PIT
29 int r;
31 if (kvm_pit) {
32 r = kvm_vm_ioctl(s, KVM_CREATE_PIT);
33 if (r < 0) {
34 fprintf(stderr, "Create kernel PIC irqchip failed\n");
35 return r;
37 if (!kvm_pit_reinject) {
38 r = kvm_reinject_control(s, 0);
39 if (r < 0) {
40 fprintf(stderr,
41 "failure to disable in-kernel PIT reinjection\n");
42 return r;
46 #endif
47 return 0;
50 #ifdef KVM_EXIT_TPR_ACCESS
52 int kvm_handle_tpr_access(CPUState *env)
54 struct kvm_run *run = env->kvm_run;
55 kvm_tpr_access_report(env,
56 run->tpr_access.rip,
57 run->tpr_access.is_write);
58 return 1;
62 int kvm_enable_vapic(CPUState *env, uint64_t vapic)
64 struct kvm_vapic_addr va = {
65 .vapic_addr = vapic,
68 return kvm_vcpu_ioctl(env, KVM_SET_VAPIC_ADDR, &va);
71 #endif
73 #ifdef KVM_CAP_IRQCHIP
75 int kvm_get_lapic(CPUState *env, struct kvm_lapic_state *s)
77 int r = 0;
79 if (!kvm_irqchip_in_kernel()) {
80 return r;
83 r = kvm_vcpu_ioctl(env, KVM_GET_LAPIC, s);
84 if (r < 0) {
85 fprintf(stderr, "KVM_GET_LAPIC failed\n");
87 return r;
90 int kvm_set_lapic(CPUState *env, struct kvm_lapic_state *s)
92 int r = 0;
94 if (!kvm_irqchip_in_kernel()) {
95 return 0;
98 r = kvm_vcpu_ioctl(env, KVM_SET_LAPIC, s);
100 if (r < 0) {
101 fprintf(stderr, "KVM_SET_LAPIC failed\n");
103 return r;
106 #endif
108 #ifdef KVM_CAP_PIT
110 int kvm_get_pit(KVMState *s, struct kvm_pit_state *pit_state)
112 if (!kvm_pit_in_kernel()) {
113 return 0;
115 return kvm_vm_ioctl(s, KVM_GET_PIT, pit_state);
118 int kvm_set_pit(KVMState *s, struct kvm_pit_state *pit_state)
120 if (!kvm_pit_in_kernel()) {
121 return 0;
123 return kvm_vm_ioctl(s, KVM_SET_PIT, pit_state);
126 #ifdef KVM_CAP_PIT_STATE2
127 int kvm_get_pit2(KVMState *s, struct kvm_pit_state2 *ps2)
129 if (!kvm_pit_in_kernel()) {
130 return 0;
132 return kvm_vm_ioctl(s, KVM_GET_PIT2, ps2);
135 int kvm_set_pit2(KVMState *s, struct kvm_pit_state2 *ps2)
137 if (!kvm_pit_in_kernel()) {
138 return 0;
140 return kvm_vm_ioctl(s, KVM_SET_PIT2, ps2);
143 #endif
144 #endif
146 #ifdef KVM_CAP_VAPIC
147 static int kvm_enable_tpr_access_reporting(CPUState *env)
149 int r;
150 struct kvm_tpr_access_ctl tac = { .enabled = 1 };
152 r = kvm_ioctl(env->kvm_state, KVM_CHECK_EXTENSION, KVM_CAP_VAPIC);
153 if (r <= 0) {
154 return -ENOSYS;
156 return kvm_vcpu_ioctl(env, KVM_TPR_ACCESS_REPORTING, &tac);
158 #endif
160 static int _kvm_arch_init_vcpu(CPUState *env)
162 kvm_arch_reset_vcpu(env);
164 #ifdef KVM_EXIT_TPR_ACCESS
165 kvm_enable_tpr_access_reporting(env);
166 #endif
168 return kvm_update_ioport_access(env);
171 #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
172 int kvm_arch_set_ioport_access(unsigned long start, unsigned long size,
173 bool enable)
175 if (ioperm(start, size, enable) < 0) {
176 return -errno;
178 return 0;
180 #endif
183 * Setup x86 specific IRQ routing
185 int kvm_arch_init_irq_routing(void)
187 int i, r;
189 if (kvm_has_gsi_routing()) {
190 kvm_clear_gsi_routes();
191 for (i = 0; i < 8; ++i) {
192 if (i == 2) {
193 continue;
195 r = kvm_add_irq_route(i, KVM_IRQCHIP_PIC_MASTER, i);
196 if (r < 0) {
197 return r;
200 for (i = 8; i < 16; ++i) {
201 r = kvm_add_irq_route(i, KVM_IRQCHIP_PIC_SLAVE, i - 8);
202 if (r < 0) {
203 return r;
206 for (i = 0; i < 24; ++i) {
207 if (i == 0) {
208 r = kvm_add_irq_route(i, KVM_IRQCHIP_IOAPIC, 2);
209 } else if (i != 2) {
210 r = kvm_add_irq_route(i, KVM_IRQCHIP_IOAPIC, i);
212 if (r < 0) {
213 return r;
216 kvm_commit_irq_routes();
218 if (!kvm_has_pit_state2()) {
219 no_hpet = 1;
221 } else {
222 /* If kernel can't do irq routing, interrupt source
223 * override 0->2 can not be set up as required by HPET.
224 * so we have to disable it.
226 no_hpet = 1;
229 return 0;