[PATCH 1/4] stubs for xsavec support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



These are needed for KVM changes in 3.18.

Recent kernels added a separate feature word for XSAVE features, and KVM's
CPUID code is relying on the new definition.  Except for cpu_has_xsaves,
it's never accessing the feature itself: wrap cpu_has_xsaves with
kvm_cpu_has_xsaves, and then there is no problem with out-of-bounds
accesses.

Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
 external-module-compat-comm.h |  4 ++++
 external-module-compat.c      | 11 +++++++++++
 sync                          | 14 ++++++++++++--
 x86/external-module-compat.h  | 37 +++++++++++++++++++++++++++++++++++++
 4 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/external-module-compat-comm.h b/external-module-compat-comm.h
index c20b1ed..1717ba3 100644
--- a/external-module-compat-comm.h
+++ b/external-module-compat-comm.h
@@ -1424,3 +1424,7 @@ extern u64 kvm_get_boot_base_ns(struct timekeeper *tk);
 
 #undef is_zero_pfn
 #define is_zero_pfn(pfn) ((pfn) == page_to_pfn(ZERO_PAGE(0)))
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0)
+void *get_xsave_addr(struct xsave_struct *xsave, int feature);
+#endif
diff --git a/external-module-compat.c b/external-module-compat.c
index 38717b6..068ab44 100644
--- a/external-module-compat.c
+++ b/external-module-compat.c
@@ -362,3 +362,14 @@ u64 kvm_get_boot_base_ns(struct timekeeper *tk)
 }
 #endif
 #endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0)
+void *get_xsave_addr(struct xsave_struct *xsave, int feature)
+{
+	int index = fls64(feature) - 1;
+	u32 size, offset, ecx, edx;
+
+	cpuid_count(0xd, index, &size, &offset, &ecx, &edx);
+	return (u8 *)xsave + offset;
+}
+#endif
diff --git a/sync b/sync
index fff85f3..3086b70 100755
--- a/sync
+++ b/sync
@@ -44,8 +44,8 @@ def hack_content(fname, data):
         'set_desc_base set_desc_limit pvclock_vcpu_time_info tboot_enabled '
         'i387_fxsave_struct native_write_msr_safe xsave_struct '
         'fpu_alloc fpu_free fpu_restore_checking fpu_save_init fpu_finit '
-        'load_gdt store_gdt xstate_size cpu_has_xsave __get_user_pages_fast '
-        'set_64bit siginfo_t use_mm '
+        'load_gdt store_gdt xstate_size cpu_has_xsave cpu_has_xsaves '
+        '__get_user_pages_fast set_64bit siginfo_t use_mm '
         'unuse_mm request_threaded_irq init_fpu __this_cpu_read '
         '__this_cpu_write sigset_from_compat '
         'sched_info_on x86_pmu_capability perf_get_x86_pmu_capability '
@@ -299,6 +299,16 @@ def hack_content(fname, data):
         if line == '#endif' and finish_endif:
             w('#endif')
             finish_endif = False
+        if match(r'xcomp_bv'):
+            w('#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)')
+            w(line)
+            w('#else')
+            # Will be under if (cpu_has_xsaves), which is always 0.  Just
+            # replace with something that compiles, the C statement might
+            # span more than one line.
+            w('WARN(1, "this should never happen"),')
+            w(sub(r'xcomp_bv', 'xstate_bv', line))
+            line = '#endif'
         if match(r'tkr\.'):
             w('#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)')
             w(line)
diff --git a/x86/external-module-compat.h b/x86/external-module-compat.h
index dec53b6..87cf76a 100644
--- a/x86/external-module-compat.h
+++ b/x86/external-module-compat.h
@@ -428,6 +428,23 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
 #define X86_FEATURE_MPX		(9*32+14) /* Memory Protection Extension */
 #endif
 
+#if X86_FEATURE_XSAVEOPT < 10 * 32
+#undef X86_FEATURE_XSAVEOPT
+#endif
+#define X86_FEATURE_XSAVEOPT	(10*32+0) /* XSAVEOPT instruction */
+
+#ifndef X86_FEATURE_XSAVEC
+#define X86_FEATURE_XSAVEC	(10*32+1) /* XSAVEC instruction */
+#endif
+
+#ifndef X86_FEATURE_XGETBV1
+#define X86_FEATURE_XGETBV1	(10*32+2) /* "XCR1" register */
+#endif
+
+#ifndef X86_FEATURE_XSAVES
+#define X86_FEATURE_XSAVES	(10*32+3) /* XSAVES instruction */
+#endif
+
 #ifndef MSR_AMD64_PATCH_LOADER
 #define MSR_AMD64_PATCH_LOADER         0xc0010020
 #endif
@@ -586,6 +603,10 @@ static inline void preempt_notifier_sys_exit(void) {}
 #define cpu_has_xsave boot_cpu_has(X86_FEATURE_XSAVE)
 #endif
 
+#ifndef cpu_has_xsaves
+#define cpu_has_xsaves boot_cpu_has(X86_FEATURE_XSAVES)
+#endif
+
 /* EFER_LMA and EFER_LME are missing in pre 2.6.24 i386 kernels */
 #ifndef EFER_LME
 #define _EFER_LME           8  /* Long mode enable */
@@ -1141,6 +1162,16 @@ static inline int kvm_init_fpu(struct task_struct *tsk)
 #define XSTATE_EAGER	(XSTATE_BNDREGS | XSTATE_BNDCSR)
 #endif
 
+#ifndef XSTATE_OPMASK
+#define XSTATE_OPMASK           0x20
+#define XSTATE_ZMM_Hi256        0x40
+#define XSTATE_Hi16_ZMM         0x80
+#endif
+
+#ifndef XSTATE_AVX512
+#define XSTATE_AVX512   (XSTATE_OPMASK | XSTATE_ZMM_Hi256 | XSTATE_Hi16_ZMM)
+#endif
+
 #ifndef XSTATE_EXTEND_MASK
 #define XSTATE_EXTEND_MASK	(~(XSTATE_FPSSE | (1ULL << 63)))
 #endif
@@ -1496,6 +1527,12 @@ static inline int __register_hotcpu_notifier(struct notifier_block *nb)
 }
 #endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0)
+#define kvm_cpu_has_xsaves	0
+#else /* >= 3.17 */
+#define kvm_cpu_has_xsaves	cpu_has_xsaves
+#endif /* >= 3.17 */
+
 #ifndef MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS
 #define MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS (1ULL << 29)
 #endif
-- 
1.8.3.1


--
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



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux