Enable the in-kernel C2 emulation after the _CST notification has been triggered.
Emulate in userspace for -no-kvm-irqchip case. Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]> Index: kvm-userspace.tip/qemu/hw/acpi.c =================================================================== --- kvm-userspace.tip.orig/qemu/hw/acpi.c +++ kvm-userspace.tip/qemu/hw/acpi.c @@ -124,6 +124,7 @@ static void pm_tmr_timer(void *opaque) * Fake C2 emulation, so the OS will consider the TSC unreliable * and fallback to C1 after the latency is updated to a high value * in acpi-dsdt.dsl. + * We still emulate C2 halt in case the OS ignores the _CST notification. */ static void qemu_system_cpu_power_notify(void); static uint32_t pm_ioport_readb(void *opaque, uint32_t addr) @@ -131,7 +132,12 @@ static uint32_t pm_ioport_readb(void *op addr &= 0x3f; switch (addr) { case 0x14: /* P_LVL2 */ - qemu_system_cpu_power_notify(); + if (!cst_notified) + qemu_system_cpu_power_notify(); + cst_notified = 1; + } else { + qemu_kvm_handle_plvl2_read(); + } } #ifdef DEBUG printf("pm_ioport_readb addr=%x\n", addr); @@ -791,10 +797,12 @@ void qemu_system_cpu_hot_add(int cpu, in static void qemu_system_cpu_power_notify(void) { - power_gpe.disable = 1; + if (kvm_irqchip_in_kernel(kvm_context)) { + power_gpe.disable = 1; - qemu_set_irq(pm_state->irq, 1); - qemu_set_irq(pm_state->irq, 0); + qemu_set_irq(pm_state->irq, 1); + qemu_set_irq(pm_state->irq, 0); + } } #endif Index: kvm-userspace.tip/qemu/qemu-kvm-x86.c =================================================================== --- kvm-userspace.tip.orig/qemu/qemu-kvm-x86.c +++ kvm-userspace.tip/qemu/qemu-kvm-x86.c @@ -287,6 +287,21 @@ void kvm_load_mpstate(CPUState *env) #endif } +uint32_t qemu_kvm_handle_plvl2_read(void) +{ + CPUState *env = cpu_single_env; + uint32_t ret; + + if (kvm_irqchip_in_kernel(kvm_context)) { + kvm_enable_acpi_c2(kvm_context); + ret = 0; + } else { + kvm_arch_halt(NULL, env->cpu_index); + ret = 1; + } + return ret; +} + void kvm_arch_save_regs(CPUState *env) { struct kvm_regs regs; Index: kvm-userspace.tip/qemu/qemu-kvm.h =================================================================== --- kvm-userspace.tip.orig/qemu/qemu-kvm.h +++ kvm-userspace.tip/qemu/qemu-kvm.h @@ -88,6 +88,9 @@ void qemu_kvm_system_reset_request(void) int handle_powerpc_dcr_read(int vcpu, uint32_t dcrn, uint32_t *data); int handle_powerpc_dcr_write(int vcpu,uint32_t dcrn, uint32_t data); #endif +#if defined(TARGET_I386) || defined(TARGET_X86_64) || defined (TARGET_IA64) +uint32_t qemu_kvm_handle_plvl2_read(void); +#endif #if !defined(SYS_signalfd) struct signalfd_siginfo { Index: kvm-userspace.tip/qemu/qemu-kvm.c =================================================================== --- kvm-userspace.tip.orig/qemu/qemu-kvm.c +++ kvm-userspace.tip/qemu/qemu-kvm.c @@ -619,6 +619,12 @@ static int kvm_debug(void *opaque, int v static int kvm_inb(void *opaque, uint16_t addr, uint8_t *data) { *data = cpu_inb(0, addr); + /* + * reads from the ACPI LVL2 port are similar to HLT emulation, + * so make current thread go sleep in main_loop(). + */ + if (addr == 0xb014 && *data) + return 1; return 0; } -- -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html