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.
10 #include "config-host.h"
22 static uint64_t map_addr(CPUState
*env
, target_ulong virt
, unsigned *perms
)
24 uint64_t mask
= ((1ull << 48) - 1) & ~4095ull;
28 if (env
->cr
[4] & 0x20) {
30 p
= ldq_phys(p
+ 8 * (virt
>> 30));
34 p
= ldq_phys(p
+ 8 * ((virt
>> 21) & 511));
39 p
+= ((virt
>> 12) & 511) << 12;
42 p
= ldq_phys(p
+ 8 * ((virt
>> 12) & 511));
49 p
= ldl_phys(p
+ 4 * ((virt
>> 22) & 1023));
54 p
+= ((virt
>> 12) & 1023) << 12;
57 p
= ldl_phys(p
+ 4 * ((virt
>> 12) & 1023));
66 return p
+ (virt
& 4095);
69 static uint8_t read_byte_virt(CPUState
*env
, target_ulong virt
)
71 return ldub_phys(map_addr(env
, virt
, NULL
));
74 static void write_byte_virt(CPUState
*env
, target_ulong virt
, uint8_t b
)
76 cpu_physical_memory_write_rom(map_addr(env
, virt
, NULL
), &b
, 1);
88 struct vapic_patches
{
92 uint32_t get_tpr_stack
;
93 } __attribute__((packed
)) up
, mp
;
94 } __attribute__((packed
));
96 static struct vapic_bios vapic_bios
;
98 static uint32_t real_tpr
;
99 static uint32_t bios_addr
;
100 static uint32_t vapic_phys
;
101 static uint32_t bios_enabled
;
102 static uint32_t vbios_desc_phys
;
103 static uint32_t vapic_bios_addr
;
105 static void update_vbios_real_tpr(void)
107 cpu_physical_memory_rw(vbios_desc_phys
, (void *)&vapic_bios
, sizeof vapic_bios
, 0);
108 vapic_bios
.real_tpr
= real_tpr
;
109 vapic_bios
.vcpu_shift
= 7;
110 cpu_physical_memory_write_rom(vbios_desc_phys
, (void *)&vapic_bios
, sizeof vapic_bios
);
113 static unsigned modrm_reg(uint8_t modrm
)
115 return (modrm
>> 3) & 7;
118 static int is_abs_modrm(uint8_t modrm
)
120 return (modrm
& 0xc7) == 0x05;
123 static int instruction_is_ok(CPUState
*env
, uint64_t rip
, int is_write
)
126 unsigned addr_offset
;
130 if ((rip
& 0xf0000000) != 0x80000000 && (rip
& 0xf0000000) != 0xe0000000)
132 if (env
->regs
[R_ESP
] == 0)
134 b1
= read_byte_virt(env
, rip
);
135 b2
= read_byte_virt(env
, rip
+ 1);
137 case 0xc7: /* mov imm32, r/m32 (c7/0) */
138 if (modrm_reg(b2
) != 0)
141 case 0x89: /* mov r32 to r/m32 */
142 case 0x8b: /* mov r/m32 to r32 */
143 if (!is_abs_modrm(b2
))
147 case 0xa1: /* mov abs to eax */
148 case 0xa3: /* mov eax to abs */
151 case 0xff: /* push r/m32 */
152 if (modrm_reg(b2
) != 6 || !is_abs_modrm(b2
))
158 p
= rip
+ addr_offset
;
159 addr
= read_byte_virt(env
, p
++);
160 addr
|= read_byte_virt(env
, p
++) << 8;
161 addr
|= read_byte_virt(env
, p
++) << 16;
162 addr
|= read_byte_virt(env
, p
++) << 24;
163 if ((addr
& 0xfff) != 0x80)
166 update_vbios_real_tpr();
170 static int bios_is_mapped(CPUState
*env
, uint64_t rip
)
176 uint32_t offset
, fixup
, start
= vapic_bios_addr
? : 0xe0000;
182 probe
= (rip
& 0xf0000000) + start
;
183 phys
= map_addr(env
, probe
, &perms
);
187 for (i
= 0; i
< 64; ++i
) {
188 cpu_physical_memory_read(phys
, (void *)&vapic_bios
, sizeof(vapic_bios
));
189 if (memcmp(vapic_bios
.signature
, "kvm aPiC", 8) == 0)
196 if (bios_addr
== vapic_bios
.virt_base
)
198 vbios_desc_phys
= phys
;
199 for (i
= vapic_bios
.fixup_start
; i
< vapic_bios
.fixup_end
; i
+= 4) {
200 offset
= ldl_phys(phys
+ i
- vapic_bios
.virt_base
);
201 fixup
= phys
+ offset
;
202 patch
= ldl_phys(fixup
) + bios_addr
- vapic_bios
.virt_base
;
203 cpu_physical_memory_write_rom(fixup
, (uint8_t *)&patch
, 4);
205 vapic_phys
= vapic_bios
.vapic
- vapic_bios
.virt_base
+ phys
;
209 static int get_pcr_cpu(CPUState
*env
)
213 cpu_synchronize_state(env
);
215 if (cpu_memory_rw_debug(env
, env
->segs
[R_FS
].base
+ 0x51, &b
, 1, 0) < 0)
221 int kvm_tpr_enable_vapic(CPUState
*env
)
223 static uint8_t one
= 1;
224 int pcr_cpu
= get_pcr_cpu(env
);
229 kvm_enable_vapic(env
, vapic_phys
+ (pcr_cpu
<< 7));
230 cpu_physical_memory_write_rom(vapic_phys
+ (pcr_cpu
<< 7) + 4, &one
, 1);
231 env
->kvm_vcpu_update_vapic
= 0;
236 static void patch_call(CPUState
*env
, uint64_t rip
, uint32_t target
)
240 offset
= target
- vapic_bios
.virt_base
+ bios_addr
- rip
- 5;
241 write_byte_virt(env
, rip
, 0xe8); /* call near */
242 write_byte_virt(env
, rip
+ 1, offset
);
243 write_byte_virt(env
, rip
+ 2, offset
>> 8);
244 write_byte_virt(env
, rip
+ 3, offset
>> 16);
245 write_byte_virt(env
, rip
+ 4, offset
>> 24);
248 static void patch_instruction(CPUState
*env
, uint64_t rip
)
251 struct vapic_patches
*vp
;
253 vp
= smp_cpus
== 1 ? &vapic_bios
.up
: &vapic_bios
.mp
;
254 b1
= read_byte_virt(env
, rip
);
255 b2
= read_byte_virt(env
, rip
+ 1);
257 case 0x89: /* mov r32 to r/m32 */
258 write_byte_virt(env
, rip
, 0x50 + modrm_reg(b2
)); /* push reg */
259 patch_call(env
, rip
+ 1, vp
->set_tpr
);
261 case 0x8b: /* mov r/m32 to r32 */
262 write_byte_virt(env
, rip
, 0x90);
263 patch_call(env
, rip
+ 1, vp
->get_tpr
[modrm_reg(b2
)]);
265 case 0xa1: /* mov abs to eax */
266 patch_call(env
, rip
, vp
->get_tpr
[0]);
268 case 0xa3: /* mov eax to abs */
269 patch_call(env
, rip
, vp
->set_tpr_eax
);
271 case 0xc7: /* mov imm32, r/m32 (c7/0) */
272 write_byte_virt(env
, rip
, 0x68); /* push imm32 */
273 write_byte_virt(env
, rip
+ 1, read_byte_virt(env
, rip
+6));
274 write_byte_virt(env
, rip
+ 2, read_byte_virt(env
, rip
+7));
275 write_byte_virt(env
, rip
+ 3, read_byte_virt(env
, rip
+8));
276 write_byte_virt(env
, rip
+ 4, read_byte_virt(env
, rip
+9));
277 patch_call(env
, rip
+ 5, vp
->set_tpr
);
279 case 0xff: /* push r/m32 */
280 printf("patching push\n");
281 write_byte_virt(env
, rip
, 0x50); /* push eax */
282 patch_call(env
, rip
+ 1, vp
->get_tpr_stack
);
285 printf("funny insn %02x %02x\n", b1
, b2
);
289 void kvm_tpr_access_report(CPUState
*env
, uint64_t rip
, int is_write
)
291 cpu_synchronize_state(env
);
292 if (!instruction_is_ok(env
, rip
, is_write
))
294 if (!bios_is_mapped(env
, rip
))
296 if (!kvm_tpr_enable_vapic(env
))
298 patch_instruction(env
, rip
);
301 static void tpr_save(QEMUFile
*f
, void *s
)
305 for (i
= 0; i
< (sizeof vapic_bios
) / 4; ++i
)
306 qemu_put_be32s(f
, &((uint32_t *)&vapic_bios
)[i
]);
307 qemu_put_be32s(f
, &bios_enabled
);
308 qemu_put_be32s(f
, &real_tpr
);
309 qemu_put_be32s(f
, &bios_addr
);
310 qemu_put_be32s(f
, &vapic_phys
);
311 qemu_put_be32s(f
, &vbios_desc_phys
);
314 static int tpr_load(QEMUFile
*f
, void *s
, int version_id
)
321 for (i
= 0; i
< (sizeof vapic_bios
) / 4; ++i
)
322 qemu_get_be32s(f
, &((uint32_t *)&vapic_bios
)[i
]);
323 qemu_get_be32s(f
, &bios_enabled
);
324 qemu_get_be32s(f
, &real_tpr
);
325 qemu_get_be32s(f
, &bios_addr
);
326 qemu_get_be32s(f
, &vapic_phys
);
327 qemu_get_be32s(f
, &vbios_desc_phys
);
330 CPUState
*env
= first_cpu
->next_cpu
;
332 for (env
= first_cpu
; env
!= NULL
; env
= env
->next_cpu
)
333 env
->kvm_vcpu_update_vapic
= 1;
339 static void vtpr_ioport_write16(void *opaque
, uint32_t addr
, uint32_t val
)
341 CPUState
*env
= cpu_single_env
;
343 cpu_synchronize_state(env
);
345 vapic_bios_addr
= ((env
->segs
[R_CS
].base
+ env
->eip
) & ~(512 - 1)) + val
;
349 static void vtpr_ioport_write(void *opaque
, uint32_t addr
, uint32_t val
)
351 CPUState
*env
= cpu_single_env
;
354 cpu_synchronize_state(env
);
357 write_byte_virt(env
, rip
, 0x66);
358 write_byte_virt(env
, rip
+ 1, 0x90);
361 if (!bios_is_mapped(env
, rip
))
362 printf("bios not mapped?\n");
363 for (addr
= 0xfffff000u
; addr
>= 0x80000000u
; addr
-= 4096)
364 if (map_addr(env
, addr
, NULL
) == 0xfee00000u
) {
365 real_tpr
= addr
+ 0x80;
369 update_vbios_real_tpr();
370 kvm_tpr_enable_vapic(env
);
373 static void kvm_tpr_opt_setup(void)
375 register_savevm(NULL
, "kvm-tpr-opt", 0, 1, tpr_save
, tpr_load
, NULL
);
376 register_ioport_write(0x7e, 1, 1, vtpr_ioport_write
, NULL
);
377 register_ioport_write(0x7e, 2, 2, vtpr_ioport_write16
, NULL
);
380 device_init(kvm_tpr_opt_setup
);