static void vapic_write(void *opaque, hwaddr addr, uint64_t data, unsigned int size) { CPUState *cs = current_cpu; X86CPU *cpu = X86_CPU(cs); CPUX86State *env = &cpu->env; hwaddr rom_paddr; VAPICROMState *s = opaque; cpu_synchronize_state(cs); /* * The VAPIC supports two PIO-based hypercalls, both via port 0x7E. * o 16-bit write access: * Reports the option ROM initialization to the hypervisor. Written * value is the offset of the state structure in the ROM. * o 8-bit write access: * Reactivates the VAPIC after a guest hibernation, i.e. after the * option ROM content has been re-initialized by a guest power cycle. * o 32-bit write access: * Poll for pending IRQs, considering the current VAPIC state. */ switch (size) { case 2: if (s->state == VAPIC_INACTIVE) { rom_paddr = (env->segs[R_CS].base + env->eip) & ROM_BLOCK_MASK; s->rom_state_paddr = rom_paddr + data; s->state = VAPIC_STANDBY; } if (vapic_prepare(s) < 0) { s->state = VAPIC_INACTIVE; s->rom_state_paddr = 0; break; } break; case 1: if (kvm_enabled()) { /* * Disable triggering instruction in ROM by writing a NOP. * * We cannot do this in TCG mode as the reported IP is not * accurate. */ pause_all_vcpus(); patch_byte(cpu, env->eip - 2, 0x66); patch_byte(cpu, env->eip - 1, 0x90); resume_all_vcpus(); } if (s->state == VAPIC_ACTIVE) { break; } if (update_rom_mapping(s, env, env->eip) < 0) { break; } if (find_real_tpr_addr(s, env) < 0) { break; } vapic_enable(s, cpu); break; default: case 4: if (!kvm_irqchip_in_kernel()) { apic_poll_irq(cpu->apic_state); } break; } }