[patch 3/3] uqmaster: save/restore PIO page

Marcelo Tosatti
2010-01-28T19:06:49Z

[-- Attachment #1: kvm-save-pio-page --]
[-- Type: text/plain, Size: 3217 bytes --]

KVM uses a page mapped by userspace as a buffer for PIO.

Save/restore it.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

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;