From: Ingo Molnar Date: Tue, 16 Feb 2016 08:37:37 +0000 (+0100) Subject: Merge branches 'x86/fpu', 'x86/mm' and 'x86/asm' into x86/pkeys X-Git-Tag: v4.6-rc1~68^2~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1fe3f29e4a908461be16a9388e73837157cc7942;p=thirdparty%2Fkernel%2Flinux.git Merge branches 'x86/fpu', 'x86/mm' and 'x86/asm' into x86/pkeys Provide a stable basis for the pkeys patches, which touches various x86 details. Signed-off-by: Ingo Molnar --- 1fe3f29e4a908461be16a9388e73837157cc7942 diff --cc arch/x86/include/asm/tlbflush.h index 6df2029405a3a,6df2029405a3a,d0cce90b08553,0bb31cb8c73b4..c24b4224d4392 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@@@@ -5,8 -5,8 -5,56 -5,9 +5,57 @@@@@ #include #include +++ #include #include ++ +static inline void __invpcid(unsigned long pcid, unsigned long addr, ++ + unsigned long type) ++ +{ ++ + struct { u64 d[2]; } desc = { { pcid, addr } }; ++ + ++ + /* ++ + * The memory clobber is because the whole point is to invalidate ++ + * stale TLB entries and, especially if we're flushing global ++ + * mappings, we don't want the compiler to reorder any subsequent ++ + * memory accesses before the TLB flush. ++ + * ++ + * The hex opcode is invpcid (%ecx), %eax in 32-bit mode and ++ + * invpcid (%rcx), %rax in long mode. ++ + */ ++ + asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01" ++ + : : "m" (desc), "a" (type), "c" (&desc) : "memory"); ++ +} ++ + ++ +#define INVPCID_TYPE_INDIV_ADDR 0 ++ +#define INVPCID_TYPE_SINGLE_CTXT 1 ++ +#define INVPCID_TYPE_ALL_INCL_GLOBAL 2 ++ +#define INVPCID_TYPE_ALL_NON_GLOBAL 3 ++ + ++ +/* Flush all mappings for a given pcid and addr, not including globals. */ ++ +static inline void invpcid_flush_one(unsigned long pcid, ++ + unsigned long addr) ++ +{ ++ + __invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR); ++ +} ++ + ++ +/* Flush all mappings for a given PCID, not including globals. */ ++ +static inline void invpcid_flush_single_context(unsigned long pcid) ++ +{ ++ + __invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT); ++ +} ++ + ++ +/* Flush all mappings, including globals, for all PCIDs. */ ++ +static inline void invpcid_flush_all(void) ++ +{ ++ + __invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL); ++ +} ++ + ++ +/* Flush all mappings for all PCIDs except globals. */ ++ +static inline void invpcid_flush_all_nonglobals(void) ++ +{ ++ + __invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL); ++ +} ++ + #ifdef CONFIG_PARAVIRT #include #else diff --cc arch/x86/kernel/traps.c index ade185a46b1da,36a9c017540e4,ade185a46b1da,410e8e2700c58..1e630d1b7ad9c --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@@@@ -750,13 -750,12 -750,13 -741,13 +741,12 @@@@@ dotraplinkage voi do_device_not_available(struct pt_regs *regs, long error_code) { RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); - -- BUG_ON(use_eager_fpu()); #ifdef CONFIG_MATH_EMULATION - -- if (read_cr0() & X86_CR0_EM) { + ++ if (!boot_cpu_has(X86_FEATURE_FPU) && (read_cr0() & X86_CR0_EM)) { struct math_emu_info info = { }; --- conditional_sti(regs); +++ cond_local_irq_enable(regs); info.regs = regs; math_emulate(&info);