Regenerate bios for vtpr using windows pcr
[qemu-kvm/fedora.git] / kvm-tpr-opt.c
blob6677741d88812acc9b995d458803c53f9fd2dd9e
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 "hw/isa.h"
16 #include "sysemu.h"
17 #include "qemu-kvm.h"
18 #include "cpu.h"
20 #include <stdio.h>
22 extern kvm_context_t kvm_context;
24 static uint64_t map_addr(struct kvm_sregs *sregs, target_ulong virt, unsigned *perms)
26 uint64_t mask = ((1ull << 48) - 1) & ~4095ull;
27 uint64_t p, pp = 7;
29 p = sregs->cr3;
30 if (sregs->cr4 & 0x20) {
31 p &= ~31ull;
32 p = ldq_phys(p + 8 * (virt >> 30));
33 if (!(p & 1))
34 return -1ull;
35 p &= mask;
36 p = ldq_phys(p + 8 * ((virt >> 21) & 511));
37 if (!(p & 1))
38 return -1ull;
39 pp &= p;
40 if (p & 128) {
41 p += ((virt >> 12) & 511) << 12;
42 } else {
43 p &= mask;
44 p = ldq_phys(p + 8 * ((virt >> 12) & 511));
45 if (!(p & 1))
46 return -1ull;
47 pp &= p;
49 } else {
50 p &= mask;
51 p = ldl_phys(p + 4 * ((virt >> 22) & 1023));
52 if (!(p & 1))
53 return -1ull;
54 pp &= p;
55 if (p & 128) {
56 p += ((virt >> 12) & 1023) << 12;
57 } else {
58 p &= mask;
59 p = ldl_phys(p + 4 * ((virt >> 12) & 1023));
60 pp &= p;
61 if (!(p & 1))
62 return -1ull;
65 if (perms)
66 *perms = pp >> 1;
67 p &= mask;
68 return p + (virt & 4095);
71 static uint8_t read_byte_virt(CPUState *env, target_ulong virt)
73 struct kvm_sregs sregs;
75 kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
76 return ldub_phys(map_addr(&sregs, virt, NULL));
79 static void write_byte_virt(CPUState *env, target_ulong virt, uint8_t b)
81 struct kvm_sregs sregs;
83 kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
84 stb_phys(map_addr(&sregs, virt, NULL), b);
87 static __u64 kvm_rsp_read(CPUState *env)
89 struct kvm_regs regs;
91 kvm_get_regs(kvm_context, env->cpu_index, &regs);
92 return regs.rsp;
95 struct vapic_bios {
96 char signature[8];
97 uint32_t virt_base;
98 uint32_t fixup_start;
99 uint32_t fixup_end;
100 uint32_t vapic;
101 uint32_t vapic_size;
102 uint32_t vcpu_shift;
103 uint32_t real_tpr;
104 struct vapic_patches {
105 uint32_t set_tpr;
106 uint32_t set_tpr_eax;
107 uint32_t get_tpr[8];
108 uint32_t get_tpr_stack;
109 } __attribute__((packed)) up, mp;
110 } __attribute__((packed));
112 static struct vapic_bios vapic_bios;
114 static uint32_t real_tpr;
115 static uint32_t bios_addr;
116 static uint32_t vapic_phys;
117 static int bios_enabled;
118 static uint32_t vbios_desc_phys;
120 void update_vbios_real_tpr()
122 cpu_physical_memory_rw(vbios_desc_phys, (void *)&vapic_bios, sizeof vapic_bios, 0);
123 vapic_bios.real_tpr = real_tpr;
124 vapic_bios.vcpu_shift = 7;
125 cpu_physical_memory_rw(vbios_desc_phys, (void *)&vapic_bios, sizeof vapic_bios, 1);
128 static unsigned modrm_reg(uint8_t modrm)
130 return (modrm >> 3) & 7;
133 static int is_abs_modrm(uint8_t modrm)
135 return (modrm & 0xc7) == 0x05;
138 static int instruction_is_ok(CPUState *env, uint64_t rip, int is_write)
140 uint8_t b1, b2;
141 unsigned addr_offset;
142 uint32_t addr;
143 uint64_t p;
145 if ((rip & 0xf0000000) != 0x80000000 && (rip & 0xf0000000) != 0xe0000000)
146 return 0;
147 if (kvm_rsp_read(env) == 0)
148 return 0;
149 b1 = read_byte_virt(env, rip);
150 b2 = read_byte_virt(env, rip + 1);
151 switch (b1) {
152 case 0xc7: /* mov imm32, r/m32 (c7/0) */
153 if (modrm_reg(b2) != 0)
154 return 0;
155 /* fall through */
156 case 0x89: /* mov r32 to r/m32 */
157 case 0x8b: /* mov r/m32 to r32 */
158 if (!is_abs_modrm(b2))
159 return 0;
160 addr_offset = 2;
161 break;
162 case 0xa1: /* mov abs to eax */
163 case 0xa3: /* mov eax to abs */
164 addr_offset = 1;
165 break;
166 case 0xff: /* push r/m32 */
167 if (modrm_reg(b2) != 6 || !is_abs_modrm(b2))
168 return 0;
169 addr_offset = 2;
170 default:
171 return 0;
173 p = rip + addr_offset;
174 addr = read_byte_virt(env, p++);
175 addr |= read_byte_virt(env, p++) << 8;
176 addr |= read_byte_virt(env, p++) << 16;
177 addr |= read_byte_virt(env, p++) << 24;
178 if ((addr & 0xfff) != 0x80)
179 return 0;
180 real_tpr = addr;
181 update_vbios_real_tpr();
182 return 1;
185 static int bios_is_mapped(CPUState *env, uint64_t rip)
187 uint32_t probe;
188 uint64_t phys;
189 struct kvm_sregs sregs;
190 unsigned perms;
191 uint32_t i;
192 uint32_t offset, fixup;
194 if (bios_enabled)
195 return 1;
197 kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
199 probe = (rip & 0xf0000000) + 0xe0000;
200 phys = map_addr(&sregs, probe, &perms);
201 if (phys != 0xe0000)
202 return 0;
203 bios_addr = probe;
204 for (i = 0; i < 64; ++i) {
205 cpu_physical_memory_read(phys, (void *)&vapic_bios, sizeof(vapic_bios));
206 if (memcmp(vapic_bios.signature, "kvm aPiC", 8) == 0)
207 break;
208 phys += 1024;
209 bios_addr += 1024;
211 if (i == 64)
212 return 0;
213 if (bios_addr == vapic_bios.virt_base)
214 return 1;
215 vbios_desc_phys = phys;
216 for (i = vapic_bios.fixup_start; i < vapic_bios.fixup_end; i += 4) {
217 offset = ldl_phys(phys + i - vapic_bios.virt_base);
218 fixup = phys + offset;
219 stl_phys(fixup, ldl_phys(fixup) + bios_addr - vapic_bios.virt_base);
221 vapic_phys = vapic_bios.vapic - vapic_bios.virt_base + phys;
222 return 1;
225 static int enable_vapic(CPUState *env)
227 struct kvm_sregs sregs;
229 if (smp_cpus > 1) {/* uniprocessor doesn't need cpu id */
230 kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
231 sregs.tr.selector = 0xdb + (env->cpu_index << 8);
232 kvm_set_sregs(kvm_context, env->cpu_index, &sregs);
235 kvm_enable_vapic(kvm_context, env->cpu_index,
236 vapic_phys + (env->cpu_index << 7));
237 bios_enabled = 1;
239 return 1;
242 static void patch_call(CPUState *env, uint64_t rip, uint32_t target)
244 uint32_t offset;
246 offset = target - vapic_bios.virt_base + bios_addr - rip - 5;
247 write_byte_virt(env, rip, 0xe8); /* call near */
248 write_byte_virt(env, rip + 1, offset);
249 write_byte_virt(env, rip + 2, offset >> 8);
250 write_byte_virt(env, rip + 3, offset >> 16);
251 write_byte_virt(env, rip + 4, offset >> 24);
254 static void patch_instruction(CPUState *env, uint64_t rip)
256 uint8_t b1, b2;
257 struct vapic_patches *vp;
259 vp = smp_cpus == 1 ? &vapic_bios.up : &vapic_bios.mp;
260 b1 = read_byte_virt(env, rip);
261 b2 = read_byte_virt(env, rip + 1);
262 switch (b1) {
263 case 0x89: /* mov r32 to r/m32 */
264 write_byte_virt(env, rip, 0x50 + modrm_reg(b2)); /* push reg */
265 patch_call(env, rip + 1, vp->set_tpr);
266 break;
267 case 0x8b: /* mov r/m32 to r32 */
268 write_byte_virt(env, rip, 0x90);
269 patch_call(env, rip + 1, vp->get_tpr[modrm_reg(b2)]);
270 break;
271 case 0xa1: /* mov abs to eax */
272 patch_call(env, rip, vp->get_tpr[0]);
273 break;
274 case 0xa3: /* mov eax to abs */
275 patch_call(env, rip, vp->set_tpr_eax);
276 break;
277 case 0xc7: /* mov imm32, r/m32 (c7/0) */
278 write_byte_virt(env, rip, 0x68); /* push imm32 */
279 write_byte_virt(env, rip + 1, read_byte_virt(env, rip+6));
280 write_byte_virt(env, rip + 2, read_byte_virt(env, rip+7));
281 write_byte_virt(env, rip + 3, read_byte_virt(env, rip+8));
282 write_byte_virt(env, rip + 4, read_byte_virt(env, rip+9));
283 patch_call(env, rip + 5, vp->set_tpr);
284 break;
285 case 0xff: /* push r/m32 */
286 printf("patching push\n");
287 write_byte_virt(env, rip, 0x50); /* push eax */
288 patch_call(env, rip + 1, vp->get_tpr_stack);
289 break;
290 default:
291 printf("funny insn %02x %02x\n", b1, b2);
295 void kvm_tpr_access_report(CPUState *env, uint64_t rip, int is_write)
297 if (!instruction_is_ok(env, rip, is_write))
298 return;
299 if (!bios_is_mapped(env, rip))
300 return;
301 if (!enable_vapic(env))
302 return;
303 patch_instruction(env, rip);
306 void kvm_tpr_vcpu_start(CPUState *env)
308 kvm_enable_tpr_access_reporting(kvm_context, env->cpu_index);
309 if (bios_enabled)
310 enable_vapic(env);
313 static void tpr_save(QEMUFile *f, void *s)
315 int i;
317 for (i = 0; i < (sizeof vapic_bios) / 4; ++i)
318 qemu_put_be32s(f, &((uint32_t *)&vapic_bios)[i]);
319 qemu_put_be32s(f, &bios_enabled);
320 qemu_put_be32s(f, &real_tpr);
321 qemu_put_be32s(f, &bios_addr);
322 qemu_put_be32s(f, &vapic_phys);
323 qemu_put_be32s(f, &vbios_desc_phys);
326 static int tpr_load(QEMUFile *f, void *s, int version_id)
328 int i;
330 if (version_id != 1)
331 return -EINVAL;
333 for (i = 0; i < (sizeof vapic_bios) / 4; ++i)
334 qemu_get_be32s(f, &((uint32_t *)&vapic_bios)[i]);
335 qemu_get_be32s(f, &bios_enabled);
336 qemu_get_be32s(f, &real_tpr);
337 qemu_get_be32s(f, &bios_addr);
338 qemu_get_be32s(f, &vapic_phys);
339 qemu_get_be32s(f, &vbios_desc_phys);
341 if (bios_enabled) {
342 CPUState *env = first_cpu->next_cpu;
344 for (env = first_cpu; env != NULL; env = env->next_cpu)
345 enable_vapic(env);
348 return 0;
351 static void vtpr_ioport_write(void *opaque, uint32_t addr, uint32_t val)
353 CPUState *env = cpu_single_env;
354 struct kvm_regs regs;
355 struct kvm_sregs sregs;
356 uint32_t rip;
358 kvm_get_regs(kvm_context, env->cpu_index, &regs);
359 rip = regs.rip - 2;
360 write_byte_virt(env, rip, 0x66);
361 write_byte_virt(env, rip + 1, 0x90);
362 if (bios_enabled)
363 return;
364 if (!bios_is_mapped(env, rip))
365 printf("bios not mapped?\n");
366 kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
367 for (addr = 0xfffff000u; addr >= 0x80000000u; addr -= 4096)
368 if (map_addr(&sregs, addr, NULL) == 0xfee00000u) {
369 real_tpr = addr + 0x80;
370 break;
372 bios_enabled = 1;
373 update_vbios_real_tpr();
374 enable_vapic(env);
377 void kvm_tpr_opt_setup(CPUState *env)
379 register_savevm("kvm-tpr-opt", 0, 1, tpr_save, tpr_load, NULL);
380 register_ioport_write(0x7e, 1, 1, vtpr_ioport_write, NULL);