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-Url: https://git.stricted.de/?a=commitdiff_plain;h=1fe3f29e4a908461be16a9388e73837157cc7942;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.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 6df2029405a3,6df2029405a3,d0cce90b0855,0bb31cb8c73b..c24b4224d439 --- 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 ade185a46b1d,36a9c017540e,ade185a46b1d,410e8e2700c5..1e630d1b7ad9 --- 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);