Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'x86/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Peter Anvin.

This includes the resume-time FPU corruption fix from the chromeos guys,
marked for stable.

* 'x86/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86, fpu: Avoid FPU lazy restore after suspend
x86-32: Unbreak booting on some 486 clones
x86, kvm: Remove incorrect redundant assembly constraint

+22 -10
+9 -6
arch/x86/include/asm/fpu-internal.h
··· 399 399 typedef struct { int preload; } fpu_switch_t; 400 400 401 401 /* 402 - * FIXME! We could do a totally lazy restore, but we need to 403 - * add a per-cpu "this was the task that last touched the FPU 404 - * on this CPU" variable, and the task needs to have a "I last 405 - * touched the FPU on this CPU" and check them. 402 + * Must be run with preemption disabled: this clears the fpu_owner_task, 403 + * on this CPU. 406 404 * 407 - * We don't do that yet, so "fpu_lazy_restore()" always returns 408 - * false, but some day.. 405 + * This will disable any lazy FPU state restore of the current FPU state, 406 + * but if the current thread owns the FPU, it will still be saved by. 409 407 */ 408 + static inline void __cpu_disable_lazy_restore(unsigned int cpu) 409 + { 410 + per_cpu(fpu_owner_task, cpu) = NULL; 411 + } 412 + 410 413 static inline int fpu_lazy_restore(struct task_struct *new, unsigned int cpu) 411 414 { 412 415 return new == this_cpu_read_stable(fpu_owner_task) &&
+7 -2
arch/x86/kernel/head_32.S
··· 292 292 * be using the global pages. 293 293 * 294 294 * NOTE! If we are on a 486 we may have no cr4 at all! 295 - * Specifically, cr4 exists if and only if CPUID exists, 296 - * which in turn exists if and only if EFLAGS.ID exists. 295 + * Specifically, cr4 exists if and only if CPUID exists 296 + * and has flags other than the FPU flag set. 297 297 */ 298 298 movl $X86_EFLAGS_ID,%ecx 299 299 pushl %ecx ··· 307 307 xorl %edx,%eax 308 308 testl %ecx,%eax 309 309 jz 6f # No ID flag = no CPUID = no CR4 310 + 311 + movl $1,%eax 312 + cpuid 313 + andl $~1,%edx # Ignore CPUID.FPU 314 + jz 6f # No flags or only CPUID.FPU = no CR4 310 315 311 316 movl pa(mmu_cr4_features),%eax 312 317 movl %eax,%cr4
+5
arch/x86/kernel/smpboot.c
··· 68 68 #include <asm/mwait.h> 69 69 #include <asm/apic.h> 70 70 #include <asm/io_apic.h> 71 + #include <asm/i387.h> 72 + #include <asm/fpu-internal.h> 71 73 #include <asm/setup.h> 72 74 #include <asm/uv/uv.h> 73 75 #include <linux/mc146818rtc.h> ··· 819 817 mtrr_save_state(); 820 818 821 819 per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; 820 + 821 + /* the FPU context is blank, nobody can own it */ 822 + __cpu_disable_lazy_restore(cpu); 822 823 823 824 err = do_boot_cpu(apicid, cpu, tidle); 824 825 if (err) {
+1 -2
arch/x86/kvm/emulate.c
··· 426 426 _ASM_EXTABLE(1b, 3b) \ 427 427 : "=m" ((ctxt)->eflags), "=&r" (_tmp), \ 428 428 "+a" (*rax), "+d" (*rdx), "+qm"(_ex) \ 429 - : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val), \ 430 - "a" (*rax), "d" (*rdx)); \ 429 + : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val)); \ 431 430 } while (0) 432 431 433 432 /* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */