49da9ad
From 0fdb006a5af7f391a6de4ce810aba4af46c427e4 Mon Sep 17 00:00:00 2001
49da9ad
From: Andy Lutomirski <luto@amacapital.net>
49da9ad
Date: Fri, 5 Dec 2014 19:03:28 -0800
49da9ad
Subject: [PATCH] x86, kvm: Clear paravirt_enabled on KVM guests for espfix32's
49da9ad
 benefit
49da9ad
49da9ad
paravirt_enabled has the following effects:
49da9ad
49da9ad
 - Disables the F00F bug workaround warning.  There is no F00F bug
49da9ad
   workaround any more because Linux's standard IDT handling already
49da9ad
   works around the F00F bug, but the warning still exists.  This
49da9ad
   is only cosmetic, and, in any event, there is no such thing as
49da9ad
   KVM on a CPU with the F00F bug.
49da9ad
49da9ad
 - Disables 32-bit APM BIOS detection.  On a KVM paravirt system,
49da9ad
   there should be no APM BIOS anyway.
49da9ad
49da9ad
 - Disables tboot.  I think that the tboot code should check the
49da9ad
   CPUID hypervisor bit directly if it matters.
49da9ad
49da9ad
 - paravirt_enabled disables espfix32.  espfix32 should *not* be
49da9ad
   disabled under KVM paravirt.
49da9ad
49da9ad
The last point is the purpose of this patch.  It fixes a leak of the
49da9ad
high 16 bits of the kernel stack address on 32-bit KVM paravirt
49da9ad
guests.
49da9ad
49da9ad
While I'm at it, this removes pv_info setup from kvmclock.  That
49da9ad
code seems to serve no purpose.
49da9ad
49da9ad
Cc: stable@vger.kernel.org
49da9ad
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
49da9ad
---
49da9ad
 arch/x86/kernel/kvm.c      | 9 ++++++++-
49da9ad
 arch/x86/kernel/kvmclock.c | 2 --
49da9ad
 2 files changed, 8 insertions(+), 3 deletions(-)
49da9ad
49da9ad
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
49da9ad
index 3dd8e2c4d74a..07de51f66deb 100644
49da9ad
--- a/arch/x86/kernel/kvm.c
49da9ad
+++ b/arch/x86/kernel/kvm.c
49da9ad
@@ -282,7 +282,14 @@ NOKPROBE_SYMBOL(do_async_page_fault);
49da9ad
 static void __init paravirt_ops_setup(void)
49da9ad
 {
49da9ad
 	pv_info.name = "KVM";
49da9ad
-	pv_info.paravirt_enabled = 1;
49da9ad
+
49da9ad
+	/*
49da9ad
+	 * KVM isn't paravirt in the sense of paravirt_enabled.  A KVM
49da9ad
+	 * guest kernel works like a bare metal kernel with additional
49da9ad
+	 * features, and paravirt_enabled is about features that are
49da9ad
+	 * missing.
49da9ad
+	 */
49da9ad
+	pv_info.paravirt_enabled = 0;
49da9ad
 
49da9ad
 	if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY))
49da9ad
 		pv_cpu_ops.io_delay = kvm_io_delay;
49da9ad
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
49da9ad
index d9156ceecdff..d4d9a8ad7893 100644
49da9ad
--- a/arch/x86/kernel/kvmclock.c
49da9ad
+++ b/arch/x86/kernel/kvmclock.c
49da9ad
@@ -263,8 +263,6 @@ void __init kvmclock_init(void)
49da9ad
 #endif
49da9ad
 	kvm_get_preset_lpj();
49da9ad
 	clocksource_register_hz(&kvm_clock, NSEC_PER_SEC);
49da9ad
-	pv_info.paravirt_enabled = 1;
49da9ad
-	pv_info.name = "KVM";
49da9ad
 
49da9ad
 	if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE_STABLE_BIT))
49da9ad
 		pvclock_set_flags(PVCLOCK_TSC_STABLE_BIT);
49da9ad
-- 
49da9ad
2.1.0
49da9ad