Blame SOURCES/kvm-target-i386-sanitize-x86-MSR_PAT-loaded-from-another.patch

4a2fec
From 7705b73dcfd0a9391bb93b9e26695ecb6dc51139 Mon Sep 17 00:00:00 2001
4a2fec
From: Wei Huang <wei@redhat.com>
4a2fec
Date: Wed, 17 Jan 2018 22:13:23 +0100
4a2fec
Subject: [PATCH 05/21] target-i386: sanitize x86 MSR_PAT loaded from another
4a2fec
 source
4a2fec
4a2fec
RH-Author: Wei Huang <wei@redhat.com>
4a2fec
Message-id: <20180117221323.1008-1-wei@redhat.com>
4a2fec
Patchwork-id: 78659
4a2fec
O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 1/1] target-i386: sanitize x86 MSR_PAT loaded from another source
4a2fec
Bugzilla: 1529461
4a2fec
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
4a2fec
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
4a2fec
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
4a2fec
4a2fec
The RHEL 7 downstream commit a94f33258 honors guest VM's writes of MSR_PAT
4a2fec
for SVM machines. But this cause a problem when an x86 VM is migrated from
4a2fec
an old host, such as RHEL 6.9. This is because older system doesn't save
4a2fec
the guest's PAT field during migration; Instead 0x0 is saved and migrated.
4a2fec
At the destination, it will use 0x0 as guest PAT because of a94f33258.
4a2fec
This causes the guest VM's performance to drop significatly.
4a2fec
4a2fec
This patch solves the problem by sanitizing the PAT field. If it is zero,
4a2fec
we use the default MSR_PAT value (0x0007040600070406ULL) to prevent
4a2fec
performance drop. This solution should work with different types of
4a2fec
(old or new) VM sources.
4a2fec
4a2fec
Signed-off-by: Wei Huang <wei@redhat.com>
4a2fec
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
4a2fec
---
4a2fec
 target/i386/cpu.c     | 2 +-
4a2fec
 target/i386/cpu.h     | 1 +
4a2fec
 target/i386/machine.c | 3 +++
4a2fec
 3 files changed, 5 insertions(+), 1 deletion(-)
4a2fec
4a2fec
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
4a2fec
index da5a266..81d0b75 100644
4a2fec
--- a/target/i386/cpu.c
4a2fec
+++ b/target/i386/cpu.c
4a2fec
@@ -3678,7 +3678,7 @@ static void x86_cpu_reset(CPUState *s)
4a2fec
     /* All units are in INIT state.  */
4a2fec
     env->xstate_bv = 0;
4a2fec
 
4a2fec
-    env->pat = 0x0007040600070406ULL;
4a2fec
+    env->pat = MSR_PAT_DEFAULT;
4a2fec
     env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
4a2fec
 
4a2fec
     memset(env->dr, 0, sizeof(env->dr));
4a2fec
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
4a2fec
index eb77e85..e04579d 100644
4a2fec
--- a/target/i386/cpu.h
4a2fec
+++ b/target/i386/cpu.h
4a2fec
@@ -385,6 +385,7 @@
4a2fec
 #define MSR_MTRRfix4K_F8000             0x26f
4a2fec
 
4a2fec
 #define MSR_PAT                         0x277
4a2fec
+#define MSR_PAT_DEFAULT                 0x0007040600070406ULL
4a2fec
 
4a2fec
 #define MSR_MTRRdefType                 0x2ff
4a2fec
 
4a2fec
diff --git a/target/i386/machine.c b/target/i386/machine.c
4a2fec
index 0212270..9f6ba9a 100644
4a2fec
--- a/target/i386/machine.c
4a2fec
+++ b/target/i386/machine.c
4a2fec
@@ -274,6 +274,9 @@ static int cpu_post_load(void *opaque, int version_id)
4a2fec
     env->hflags &= ~HF_CPL_MASK;
4a2fec
     env->hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
4a2fec
 
4a2fec
+    if (!(env->pat))
4a2fec
+        env->pat = MSR_PAT_DEFAULT;
4a2fec
+
4a2fec
     env->fpstt = (env->fpus_vmstate >> 11) & 7;
4a2fec
     env->fpus = env->fpus_vmstate & ~0x3800;
4a2fec
     env->fptag_vmstate ^= 0xff;
4a2fec
-- 
4a2fec
1.8.3.1
4a2fec