Merge branches 'x86/fpu', 'x86/mm' and 'x86/asm' into x86/pkeys
authorIngo Molnar <mingo@kernel.org>
Tue, 16 Feb 2016 08:37:37 +0000 (09:37 +0100)
committerIngo Molnar <mingo@kernel.org>
Tue, 16 Feb 2016 08:37:37 +0000 (09:37 +0100)
Provide a stable basis for the pkeys patches, which touches various
x86 details.

Signed-off-by: Ingo Molnar <mingo@kernel.org>
13 files changed:
1  2  3  4 
Documentation/kernel-parameters.txt
arch/x86/include/asm/fpu/internal.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/tlbflush.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/head_32.S
arch/x86/kernel/traps.c
arch/x86/mm/setup_nx.c
fs/btrfs/disk-io.c
include/linux/mm.h
include/linux/mm_types.h
mm/memory.c
mm/mmap.c

Simple merge
Simple merge
Simple merge
@@@@@ -5,8 -5,8 -5,56 -5,9 +5,57 @@@@@
    #include <linux/sched.h>
    
    #include <asm/processor.h>
+++ #include <asm/cpufeature.h>
    #include <asm/special_insns.h>
    
++ +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 <asm/paravirt.h>
    #else
Simple merge
Simple merge
@@@@@ -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);
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc mm/memory.c
Simple merge
diff --cc mm/mmap.c
Simple merge