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