kvm: bios: use smp_cpus as lapic id
[qemu-kvm/fedora.git] / kvm-tpr-opt.c
blob241f729931d01330feecee898c03682da7a66bec
1 /*
2 * tpr optimization for qemu/kvm
4 * Copyright (C) 2007-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>
14 #include "hw/hw.h"
15 #include "sysemu.h"
16 #include "qemu-kvm.h"
17 #include "cpu.h"
19 #include <stdio.h>
21 extern kvm_context_t kvm_context;
23 static uint64_t map_addr(struct kvm_sregs *sregs, target_ulong virt, unsigned *perms)
25 uint64_t mask = ((1ull << 48) - 1) & ~4095ull;
26 uint64_t p, pp = 7;
28 p = sregs->cr3;
29 if (sregs->cr4 & 0x20) {
30 p &= ~31ull;
31 p = ldq_phys(p + 8 * (virt >> 30));
32 if (!(p & 1))
33 return -1ull;
34 p &= mask;
35 p = ldq_phys(p + 8 * ((virt >> 21) & 511));
36 if (!(p & 1))
37 return -1ull;
38 pp &= p;
39 if (p & 128) {
40 p += ((virt >> 12) & 511) << 12;
41 } else {
42 p &= mask;
43 p = ldq_phys(p + 8 * ((virt >> 12) & 511));
44 if (!(p & 1))
45 return -1ull;
46 pp &= p;
48 } else {
49 p &= mask;
50 p = ldl_phys(p + 4 * ((virt >> 22) & 1023));
51 if (!(p & 1))
52 return -1ull;
53 pp &= p;
54 if (p & 128) {
55 p += ((virt >> 12) & 1023) << 12;
56 } else {
57 p &= mask;
58 p = ldl_phys(p + 4 * ((virt >> 12) & 1023));
59 pp &= p;
60 if (!(p & 1))
61 return -1ull;
64 if (perms)
65 *perms = pp >> 1;
66 p &= mask;
67 return p + (virt & 4095);
70 static uint8_t read_byte_virt(CPUState *env, target_ulong virt)
72 struct kvm_sregs sregs;
74 kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
75 return ldub_phys(map_addr(&sregs, virt, NULL));
78 static void write_byte_virt(CPUState *env, target_ulong virt, uint8_t b)
80 struct kvm_sregs sregs;
82 kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
83 stb_phys(map_addr(&sregs, virt, NULL), b);
86 static uint32_t get_bios_map(CPUState *env, unsigned *perms)
88 uint32_t v;
89 struct kvm_sregs sregs;
91 kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
93 for (v = -4096u; v != 0; v -= 4096)
94 if (map_addr(&sregs, v, perms) == 0xe0000)
95 return v;
96 return -1u;
99 struct vapic_bios {
100 char signature[8];
101 uint32_t virt_base;
102 uint32_t fixup_start;
103 uint32_t fixup_end;
104 uint32_t vapic;
105 uint32_t vapic_size;
106 uint32_t vcpu_shift;
107 uint32_t real_tpr;
108 struct vapic_patches {
109 uint32_t set_tpr;
110 uint32_t set_tpr_eax;
111 uint32_t get_tpr[8];
112 } __attribute__((packed)) up, mp;
113 } __attribute__((packed));
115 static struct vapic_bios vapic_bios;
117 static uint32_t real_tpr;
118 static uint32_t bios_addr;
119 static uint32_t vapic_phys;
120 static int bios_enabled;
121 static uint32_t vbios_desc_phys;
123 void update_vbios_real_tpr()
125 cpu_physical_memory_rw(vbios_desc_phys, (void *)&vapic_bios, sizeof vapic_bios, 0);
126 vapic_bios.real_tpr = real_tpr;
127 vapic_bios.vcpu_shift = 7;
128 cpu_physical_memory_rw(vbios_desc_phys, (void *)&vapic_bios, sizeof vapic_bios, 1);
131 static unsigned modrm_reg(uint8_t modrm)
133 return (modrm >> 3) & 7;
136 static int is_abs_modrm(uint8_t modrm)
138 return (modrm & 0xc7) == 0x05;
141 static int instruction_is_ok(CPUState *env, uint64_t rip, int is_write)
143 uint8_t b1, b2;
144 unsigned addr_offset;
145 uint32_t addr;
146 uint64_t p;
148 if ((rip & 0xf0000000) != 0x80000000 && (rip & 0xf0000000) != 0xe0000000)
149 return 0;
150 b1 = read_byte_virt(env, rip);
151 b2 = read_byte_virt(env, rip + 1);
152 switch (b1) {
153 case 0xc7: /* mov imm32, r/m32 (c7/0) */
154 if (modrm_reg(b2) != 0)
155 return 0;
156 /* fall through */
157 case 0x89: /* mov r32 to r/m32 */
158 case 0x8b: /* mov r/m32 to r32 */
159 if (!is_abs_modrm(b2))
160 return 0;
161 addr_offset = 2;
162 break;
163 case 0xa1: /* mov abs to eax */
164 case 0xa3: /* mov eax to abs */
165 addr_offset = 1;
166 break;
167 default:
168 return 0;
170 p = rip + addr_offset;
171 addr = read_byte_virt(env, p++);
172 addr |= read_byte_virt(env, p++) << 8;
173 addr |= read_byte_virt(env, p++) << 16;
174 addr |= read_byte_virt(env, p++) << 24;
175 if ((addr & 0xfff) != 0x80)
176 return 0;
177 real_tpr = addr;
178 update_vbios_real_tpr();
179 return 1;
182 static int bios_is_mapped(CPUState *env, uint64_t rip)
184 uint32_t probe;
185 uint64_t phys;
186 struct kvm_sregs sregs;
187 unsigned perms;
188 uint32_t i;
189 uint32_t offset, fixup;
191 if (bios_enabled)
192 return 1;
194 kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
196 probe = (rip & 0xf0000000) + 0xe0000;
197 phys = map_addr(&sregs, probe, &perms);
198 if (phys != 0xe0000)
199 return 0;
200 bios_addr = probe;
201 for (i = 0; i < 64; ++i) {
202 cpu_physical_memory_read(phys, (void *)&vapic_bios, sizeof(vapic_bios));
203 if (memcmp(vapic_bios.signature, "kvm aPiC", 8) == 0)
204 break;
205 phys += 1024;
206 bios_addr += 1024;
208 if (i == 64)
209 return 0;
210 if (bios_addr == vapic_bios.virt_base)
211 return 1;
212 vbios_desc_phys = phys;
213 for (i = vapic_bios.fixup_start; i < vapic_bios.fixup_end; i += 4) {
214 offset = ldl_phys(phys + i - vapic_bios.virt_base);
215 fixup = phys + offset;
216 stl_phys(fixup, ldl_phys(fixup) + bios_addr - vapic_bios.virt_base);
218 vapic_phys = vapic_bios.vapic - vapic_bios.virt_base + phys;
219 return 1;
222 static int enable_vapic(CPUState *env)
224 struct kvm_sregs sregs;
226 if (smp_cpus > 1) {/* uniprocessor doesn't need cpu id */
227 kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
228 sregs.tr.selector = 0xdb + (env->cpu_index << 8);
229 kvm_set_sregs(kvm_context, env->cpu_index, &sregs);
232 kvm_enable_vapic(kvm_context, env->cpu_index,
233 vapic_phys + (env->cpu_index << 7));
234 bios_enabled = 1;
236 return 1;
239 static void patch_call(CPUState *env, uint64_t rip, uint32_t target)
241 uint32_t offset;
243 offset = target - vapic_bios.virt_base + bios_addr - rip - 5;
244 write_byte_virt(env, rip, 0xe8); /* call near */
245 write_byte_virt(env, rip + 1, offset);
246 write_byte_virt(env, rip + 2, offset >> 8);
247 write_byte_virt(env, rip + 3, offset >> 16);
248 write_byte_virt(env, rip + 4, offset >> 24);
251 static void patch_instruction(CPUState *env, uint64_t rip)
253 uint8_t b1, b2;
254 struct vapic_patches *vp;
256 vp = smp_cpus == 1 ? &vapic_bios.up : &vapic_bios.mp;
257 b1 = read_byte_virt(env, rip);
258 b2 = read_byte_virt(env, rip + 1);
259 switch (b1) {
260 case 0x89: /* mov r32 to r/m32 */
261 write_byte_virt(env, rip, 0x50 + modrm_reg(b2)); /* push reg */
262 patch_call(env, rip + 1, vp->set_tpr);
263 break;
264 case 0x8b: /* mov r/m32 to r32 */
265 write_byte_virt(env, rip, 0x90);
266 patch_call(env, rip + 1, vp->get_tpr[modrm_reg(b2)]);
267 break;
268 case 0xa1: /* mov abs to eax */
269 patch_call(env, rip, vp->get_tpr[0]);
270 break;
271 case 0xa3: /* mov eax to abs */
272 patch_call(env, rip, vp->set_tpr_eax);
273 break;
274 case 0xc7: /* mov imm32, r/m32 (c7/0) */
275 write_byte_virt(env, rip, 0x68); /* push imm32 */
276 write_byte_virt(env, rip + 1, read_byte_virt(env, rip+6));
277 write_byte_virt(env, rip + 2, read_byte_virt(env, rip+7));
278 write_byte_virt(env, rip + 3, read_byte_virt(env, rip+8));
279 write_byte_virt(env, rip + 4, read_byte_virt(env, rip+9));
280 patch_call(env, rip + 5, vp->set_tpr);
281 break;
282 default:
283 printf("funny insn %02x %02x\n", b1, b2);
287 void kvm_tpr_access_report(CPUState *env, uint64_t rip, int is_write)
289 if (!instruction_is_ok(env, rip, is_write))
290 return;
291 if (!bios_is_mapped(env, rip))
292 return;
293 if (!enable_vapic(env))
294 return;
295 patch_instruction(env, rip);
298 void kvm_tpr_vcpu_start(CPUState *env)
300 if (smp_cpus > 1)
301 return;
302 kvm_enable_tpr_access_reporting(kvm_context, env->cpu_index);
303 if (bios_enabled)
304 enable_vapic(env);
307 static void tpr_save(QEMUFile *f, void *s)
309 int i;
311 for (i = 0; i < (sizeof vapic_bios) / 4; ++i)
312 qemu_put_be32s(f, &((uint32_t *)&vapic_bios)[i]);
313 qemu_put_be32s(f, &bios_enabled);
314 qemu_put_be32s(f, &real_tpr);
315 qemu_put_be32s(f, &bios_addr);
316 qemu_put_be32s(f, &vapic_phys);
317 qemu_put_be32s(f, &vbios_desc_phys);
320 static int tpr_load(QEMUFile *f, void *s, int version_id)
322 int i;
324 if (version_id != 1)
325 return -EINVAL;
327 for (i = 0; i < (sizeof vapic_bios) / 4; ++i)
328 qemu_get_be32s(f, &((uint32_t *)&vapic_bios)[i]);
329 qemu_get_be32s(f, &bios_enabled);
330 qemu_get_be32s(f, &real_tpr);
331 qemu_get_be32s(f, &bios_addr);
332 qemu_get_be32s(f, &vapic_phys);
333 qemu_get_be32s(f, &vbios_desc_phys);
335 if (bios_enabled) {
336 CPUState *env = first_cpu->next_cpu;
338 for (env = first_cpu; env != NULL; env = env->next_cpu)
339 enable_vapic(env);
342 return 0;
345 void kvm_tpr_opt_setup(CPUState *env)
347 register_savevm("kvm-tpr-opt", 0, 1, tpr_save, tpr_load, NULL);