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.
10 #include "config-host.h"
19 #include <sys/utsname.h>
20 #include <linux/kvm_para.h>
21 #include <sys/ioctl.h>
26 static int kvm_create_pit(KVMState
*s
)
31 r
= kvm_vm_ioctl(s
, KVM_CREATE_PIT
);
33 fprintf(stderr
, "Create kernel PIC irqchip failed\n");
36 if (!kvm_pit_reinject
) {
37 r
= kvm_reinject_control(s
, 0);
40 "failure to disable in-kernel PIT reinjection\n");
48 int kvm_handle_tpr_access(CPUState
*env
)
50 struct kvm_run
*run
= env
->kvm_run
;
51 kvm_tpr_access_report(env
,
53 run
->tpr_access
.is_write
);
58 int kvm_enable_vapic(CPUState
*env
, uint64_t vapic
)
60 struct kvm_vapic_addr va
= {
64 return kvm_vcpu_ioctl(env
, KVM_SET_VAPIC_ADDR
, &va
);
67 int kvm_get_lapic(CPUState
*env
, struct kvm_lapic_state
*s
)
71 if (!kvm_irqchip_in_kernel()) {
75 r
= kvm_vcpu_ioctl(env
, KVM_GET_LAPIC
, s
);
77 fprintf(stderr
, "KVM_GET_LAPIC failed\n");
82 int kvm_set_lapic(CPUState
*env
, struct kvm_lapic_state
*s
)
86 if (!kvm_irqchip_in_kernel()) {
90 r
= kvm_vcpu_ioctl(env
, KVM_SET_LAPIC
, s
);
93 fprintf(stderr
, "KVM_SET_LAPIC failed\n");
98 int kvm_get_pit(KVMState
*s
, struct kvm_pit_state
*pit_state
)
100 if (!kvm_pit_in_kernel()) {
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()) {
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()) {
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()) {
127 return kvm_vm_ioctl(s
, KVM_SET_PIT2
, ps2
);
130 static int kvm_enable_tpr_access_reporting(CPUState
*env
)
133 struct kvm_tpr_access_ctl tac
= { .enabled
= 1 };
135 r
= kvm_ioctl(env
->kvm_state
, KVM_CHECK_EXTENSION
, KVM_CAP_VAPIC
);
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
,
155 if (ioperm(start
, size
, enable
) < 0) {
163 * Setup x86 specific IRQ routing
165 int kvm_arch_init_irq_routing(void)
169 if (kvm_has_gsi_routing()) {
170 kvm_clear_gsi_routes();
171 for (i
= 0; i
< 8; ++i
) {
175 r
= kvm_add_irq_route(i
, KVM_IRQCHIP_PIC_MASTER
, i
);
180 for (i
= 8; i
< 16; ++i
) {
181 r
= kvm_add_irq_route(i
, KVM_IRQCHIP_PIC_SLAVE
, i
- 8);
186 for (i
= 0; i
< 24; ++i
) {
188 r
= kvm_add_irq_route(i
, KVM_IRQCHIP_IOAPIC
, 2);
190 r
= kvm_add_irq_route(i
, KVM_IRQCHIP_IOAPIC
, i
);
196 kvm_commit_irq_routes();
198 if (!kvm_has_pit_state2()) {
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.