From 30f1b43aaefc3f7ed7f07cd8707bffbcc146e4da Mon Sep 17 00:00:00 2001
From: "Michael S. Tsirkin" <mst@redhat.com>
Date: Sun, 23 Sep 2012 14:31:55 -0300
Subject: [RHEL6 qemu-kvm PATCH 4/5] kvm: get/set PV EOI MSR

RH-Author: Michael S. Tsirkin <mst@redhat.com>
Message-id: <301897dd24b05fe5fe19687333ba31eaa2e5fd1f.1348408802.git.mst@redhat.com>
Patchwork-id: 42290
O-Subject: [PATCHv2 RHEL6.4 2/3] kvm: get/set PV EOI MSR
Bugzilla: 835101
RH-Acked-by: Xiao Wang <jasowang@redhat.com>
RH-Acked-by: Gleb Natapov <gleb@redhat.com>
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>

Support get/set of new PV EOI MSR, for migration.
Also, add a subsection to migrate the msr.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit bc9a839d569d4d8532c5c097bf1f4583226e3aa0)
---
 qemu-kvm-x86.c        | 13 +++++++++++++
 target-i386/cpu.h     |  1 +
 target-i386/machine.c | 23 ++++++++++++++++++++++-
 3 files changed, 36 insertions(+), 1 deletion(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 qemu-kvm-x86.c        | 13 +++++++++++++
 target-i386/cpu.h     |  1 +
 target-i386/machine.c | 23 ++++++++++++++++++++++-
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index 59d32f1..6a3e1b5 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -33,6 +33,8 @@ static int kvm_has_vm_hsave_pa;
 
 static int lm_capable_kernel;
 
+static bool has_msr_pv_eoi_en;
+
 int kvm_set_tss_addr(kvm_context_t kvm, unsigned long addr)
 {
 #ifdef KVM_CAP_SET_TSS_ADDR
@@ -852,6 +854,9 @@ static int get_msr_entry(struct kvm_msr_entry *entry, CPUState *env)
         case MSR_KVM_WALL_CLOCK:
             env->wall_clock_msr = entry->data;
             break;
+        case MSR_KVM_PV_EOI_EN:
+            env->pv_eoi_en_msr = entry->data;
+            break;
 #ifdef KVM_CAP_MCE
         case MSR_MCG_STATUS:
             env->mcg_status = entry->data;
@@ -1075,6 +1080,9 @@ void kvm_arch_load_regs(CPUState *env)
 #endif
     set_msr_entry(&msrs[n++], MSR_KVM_SYSTEM_TIME,  env->system_time_msr);
     set_msr_entry(&msrs[n++], MSR_KVM_WALL_CLOCK,  env->wall_clock_msr);
+    if (has_msr_pv_eoi_en) {
+        set_msr_entry(&msrs[n++], MSR_KVM_PV_EOI_EN, env->pv_eoi_en_msr);
+    }
 
 #ifdef KVM_CAP_MCE
     if (env->mcg_cap) {
@@ -1310,6 +1318,9 @@ void kvm_arch_save_regs(CPUState *env)
 #endif
     msrs[n++].index = MSR_KVM_SYSTEM_TIME;
     msrs[n++].index = MSR_KVM_WALL_CLOCK;
+    if (has_msr_pv_eoi_en) {
+        msrs[n++].index = MSR_KVM_PV_EOI_EN;
+    }
 
 #ifdef KVM_CAP_MCE
     if (env->mcg_cap) {
@@ -1420,6 +1431,8 @@ int kvm_arch_init_vcpu(CPUState *cenv)
 
     copy = *cenv;
 
+    has_msr_pv_eoi_en = pv_ent->eax & (1 << KVM_FEATURE_PV_EOI);
+
     copy.regs[R_EAX] = 0;
     qemu_kvm_cpuid_on_env(&copy);
     limit = copy.regs[R_EAX];
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 91e1961..0eeaa0c 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -670,6 +670,7 @@ typedef struct CPUX86State {
 #endif
     uint64_t system_time_msr;
     uint64_t wall_clock_msr;
+    uint64_t pv_eoi_en_msr;
 
     uint64_t tsc;
 
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 07076b7..2e1eeb5 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -419,6 +419,24 @@ static const VMStateDescription vmstate_xsave ={
     }
 };
 
+static bool pv_eoi_msr_needed(void *opaque)
+{
+    CPUState *cpu = opaque;
+
+    return cpu->pv_eoi_en_msr != 0;
+}
+
+static const VMStateDescription vmstate_pv_eoi_msr = {
+    .name = "cpu/async_pv_eoi_msr",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT64(pv_eoi_en_msr, CPUX86State),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_cpu = {
     .name = "cpu",
     .version_id = CPU_SAVE_VERSION,
@@ -520,7 +538,7 @@ static const VMStateDescription vmstate_cpu = {
         /* The above list is not sorted /wrt version numbers, watch out! */
     },
     /*
-       Put the XSAVE state in a sub-section to allow compatibility with
+       Put the XSAVE/PV_EOI state in sub-sections to allow compatibility with
 	older save files.
      */
     .subsections = (VMStateSubsection []) {
@@ -528,6 +546,9 @@ static const VMStateDescription vmstate_cpu = {
 	    .vmsd = &vmstate_xsave,
 	    .needed = vmstate_xsave_needed,
 	}, {
+            .vmsd = &vmstate_pv_eoi_msr,
+            .needed = pv_eoi_msr_needed,
+        }, {
 	    /* empty */
 	}
     }
-- 
1.7.11.4

