KVM uses a page mapped by userspace as a buffer for PIO. Save/restore it. Signed-off-by: Marcelo Tosatti <mtosatti@xxxxxxxxxx> Index: qemu-kvm/target-i386/cpu.h =================================================================== --- qemu-kvm.orig/target-i386/cpu.h +++ qemu-kvm/target-i386/cpu.h @@ -716,6 +716,7 @@ typedef struct CPUX86State { uint32_t cpuid_kvm_features; KVMPIOState kvm_pio; + uint8_t kvm_pio_page[4096]; /* in order to simplify APIC support, we leave this pointer to the user */ Index: qemu-kvm/target-i386/machine.c =================================================================== --- qemu-kvm.orig/target-i386/machine.c +++ qemu-kvm/target-i386/machine.c @@ -350,6 +350,8 @@ static void cpu_pre_save(void *opaque) int i; cpu_synchronize_state(env); + if (kvm_enabled()) + kvm_get_pio_page(env); /* FPU */ env->fpus_vmstate = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; @@ -378,6 +380,9 @@ static int cpu_post_load(void *opaque, i CPUState *env = opaque; int i; + if (kvm_enabled()) + kvm_put_pio_page(env); + /* XXX: restore FPU round state */ env->fpstt = (env->fpus_vmstate >> 11) & 7; env->fpus = env->fpus_vmstate & ~0x3800; @@ -494,6 +499,7 @@ static const VMStateDescription vmstate_ VMSTATE_UINT64_V(wall_clock_msr, CPUState, 11), VMSTATE_KVM_PIO(kvm_pio, CPUState, 11), + VMSTATE_UINT8_ARRAY_V(kvm_pio_page, CPUState, TARGET_PAGE_SIZE, 11), VMSTATE_END_OF_LIST() /* The above list is not sorted /wrt version numbers, watch out! */ Index: qemu-kvm/kvm.h =================================================================== --- qemu-kvm.orig/kvm.h +++ qemu-kvm/kvm.h @@ -132,6 +132,9 @@ uint32_t kvm_arch_get_supported_cpuid(CP int reg); void kvm_cpu_synchronize_state(CPUState *env); +void kvm_put_pio_page(CPUState *env); +void kvm_get_pio_page(CPUState *env); + /* generic hooks - to be moved/refactored once there are more users */ static inline void cpu_synchronize_state(CPUState *env) Index: qemu-kvm/target-i386/kvm.c =================================================================== --- qemu-kvm.orig/target-i386/kvm.c +++ qemu-kvm/target-i386/kvm.c @@ -889,6 +889,39 @@ static int kvm_get_pio(CPUState *env) return 0; } +static int kvm_pio_page_offset(CPUState *env) +{ + int ret = 0; + +#ifdef KVM_CAP_PIO + ret = kvm_check_extension(env->kvm_state, KVM_CAP_PIO); +#endif + + return ret; +} + +void kvm_put_pio_page(CPUState *env) +{ + uint8_t *pio_page; + int pio_page_off = kvm_pio_page_offset(env); + + if (pio_page_off) { + pio_page = (uint8_t *)env->kvm_run + (pio_page_off * TARGET_PAGE_SIZE); + memcpy(pio_page, env->kvm_pio_page, TARGET_PAGE_SIZE); + } +} + +void kvm_get_pio_page(CPUState *env) +{ + uint8_t *pio_page; + int pio_page_off = kvm_pio_page_offset(env); + + if (pio_page_off) { + pio_page = (uint8_t *)env->kvm_run + (pio_page_off * TARGET_PAGE_SIZE); + memcpy(env->kvm_pio_page, pio_page, TARGET_PAGE_SIZE); + } +} + int kvm_arch_put_registers(CPUState *env) { int ret; -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html