215
224
struct kvm_sregs sregs;
217
kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
218
sregs.tr.selector = 0xdb + (env->cpu_index << 8);
219
kvm_set_sregs(kvm_context, env->cpu_index, &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);
221
232
kvm_enable_vapic(kvm_context, env->cpu_index,
222
233
vapic_phys + (env->cpu_index << 7));
238
251
static void patch_instruction(CPUState *env, uint64_t rip)
254
struct vapic_patches *vp;
256
vp = smp_cpus == 1 ? &vapic_bios.up : &vapic_bios.mp;
242
257
b1 = read_byte_virt(env, rip);
243
258
b2 = read_byte_virt(env, rip + 1);
245
260
case 0x89: /* mov r32 to r/m32 */
246
261
write_byte_virt(env, rip, 0x50 + modrm_reg(b2)); /* push reg */
247
patch_call(env, rip + 1, vapic_bios.set_tpr);
262
patch_call(env, rip + 1, vp->set_tpr);
249
264
case 0x8b: /* mov r/m32 to r32 */
250
265
write_byte_virt(env, rip, 0x90);
251
patch_call(env, rip + 1, vapic_bios.get_tpr[modrm_reg(b2)]);
266
patch_call(env, rip + 1, vp->get_tpr[modrm_reg(b2)]);
253
268
case 0xa1: /* mov abs to eax */
254
patch_call(env, rip, vapic_bios.get_tpr[0]);
269
patch_call(env, rip, vp->get_tpr[0]);
256
271
case 0xa3: /* mov eax to abs */
257
patch_call(env, rip, vapic_bios.set_tpr_eax);
272
patch_call(env, rip, vp->set_tpr_eax);
259
274
case 0xc7: /* mov imm32, r/m32 (c7/0) */
260
275
write_byte_virt(env, rip, 0x68); /* push imm32 */
262
277
write_byte_virt(env, rip + 2, read_byte_virt(env, rip+7));
263
278
write_byte_virt(env, rip + 3, read_byte_virt(env, rip+8));
264
279
write_byte_virt(env, rip + 4, read_byte_virt(env, rip+9));
265
patch_call(env, rip + 5, vapic_bios.set_tpr);
280
patch_call(env, rip + 5, vp->set_tpr);
268
283
printf("funny insn %02x %02x\n", b1, b2);
280
295
patch_instruction(env, rip);
283
void kvm_tpr_opt_setup(CPUState *env)
298
void kvm_tpr_vcpu_start(CPUState *env)
285
300
if (smp_cpus > 1)
287
302
kvm_enable_tpr_access_reporting(kvm_context, env->cpu_index);
307
static void tpr_save(QEMUFile *f, void *s)
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)
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);
336
CPUState *env = first_cpu->next_cpu;
338
for (env = first_cpu; env != NULL; env = env->next_cpu)
345
void kvm_tpr_opt_setup(CPUState *env)
347
register_savevm("kvm-tpr-opt", 0, 1, tpr_save, tpr_load, NULL);