lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Date:   Mon, 26 Nov 2018 03:01:51 +0800
From:   kbuild test robot <lkp@...el.com>
To:     Thomas Gleixner <tglx@...utronix.de>
Cc:     kbuild-all@...org, linux-kernel@...r.kernel.org, tipbuild@...or.com
Subject: [tip:WIP.x86/pti 23/30] arch/x86/mm/tlb.c:192:51: error:
 'LAST_USR_MM_IBPB' undeclared; did you mean 'LAST_USER_MM_IBPB'?

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git WIP.x86/pti
head:   05bdddd3be604144c2f2dc65fcb6e53961834d11
commit: 03b772b5933ba040f9e805f7f82554e64d6344d8 [23/30] x86/speculation: Prepare for conditional IBPB in switch_mm()
config: i386-randconfig-x002-201847 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        git checkout 03b772b5933ba040f9e805f7f82554e64d6344d8
        # save the attached .config to linux build tree
        make ARCH=i386 

All error/warnings (new ones prefixed by >>):

   arch/x86/mm/tlb.c: In function 'mm_mangle_tif_spec_ib':
>> arch/x86/mm/tlb.c:192:51: error: 'LAST_USR_MM_IBPB' undeclared (first use in this function); did you mean 'LAST_USER_MM_IBPB'?
     unsigned long ibpb = (next_tif >> TIF_SPEC_IB) & LAST_USR_MM_IBPB;
                                                      ^~~~~~~~~~~~~~~~
                                                      LAST_USER_MM_IBPB
   arch/x86/mm/tlb.c:192:51: note: each undeclared identifier is reported only once for each function it appears in
   In file included from include/linux/init.h:5:0,
                    from arch/x86/mm/tlb.c:1:
   arch/x86/mm/tlb.c: In function 'cond_ibpb':
   arch/x86/mm/tlb.c:243:51: error: 'LAST_USR_MM_IBPB' undeclared (first use in this function); did you mean 'LAST_USER_MM_IBPB'?
      if (next_mm != prev_mm && (next_mm | prev_mm) & LAST_USR_MM_IBPB)
                                                      ^
   include/linux/compiler.h:58:30: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                 ^~~~
>> arch/x86/mm/tlb.c:243:3: note: in expansion of macro 'if'
      if (next_mm != prev_mm && (next_mm | prev_mm) & LAST_USR_MM_IBPB)
      ^~
   In file included from arch/x86/include/asm/preempt.h:6:0,
                    from include/linux/preempt.h:81,
                    from include/linux/spinlock.h:51,
                    from include/linux/mmzone.h:8,
                    from include/linux/gfp.h:6,
                    from include/linux/mm.h:10,
                    from arch/x86/mm/tlb.c:3:
   arch/x86/mm/tlb.c: In function 'initialize_tlbstate_and_flush':
   arch/x86/mm/tlb.c:491:49: error: 'LAST_USR_MM_IBPB' undeclared (first use in this function); did you mean 'LAST_USER_MM_IBPB'?
     this_cpu_write(cpu_tlbstate.last_user_mm_ibpb, LAST_USR_MM_IBPB);
                                                    ^
   arch/x86/include/asm/percpu.h:95:16: note: in definition of macro 'percpu_to_op'
      pto_tmp__ = (val);   \
                   ^~~
   include/linux/percpu-defs.h:377:11: note: in expansion of macro 'this_cpu_write_1'
      case 1: stem##1(variable, __VA_ARGS__);break;  \
              ^~~~
   include/linux/percpu-defs.h:508:34: note: in expansion of macro '__pcpu_size_call'
    #define this_cpu_write(pcp, val) __pcpu_size_call(this_cpu_write_, pcp, val)
                                     ^~~~~~~~~~~~~~~~
>> arch/x86/mm/tlb.c:491:2: note: in expansion of macro 'this_cpu_write'
     this_cpu_write(cpu_tlbstate.last_user_mm_ibpb, LAST_USR_MM_IBPB);
     ^~~~~~~~~~~~~~

vim +192 arch/x86/mm/tlb.c

   > 1	#include <linux/init.h>
     2	
     3	#include <linux/mm.h>
     4	#include <linux/spinlock.h>
     5	#include <linux/smp.h>
     6	#include <linux/interrupt.h>
     7	#include <linux/export.h>
     8	#include <linux/cpu.h>
     9	#include <linux/debugfs.h>
    10	
    11	#include <asm/tlbflush.h>
    12	#include <asm/mmu_context.h>
    13	#include <asm/nospec-branch.h>
    14	#include <asm/cache.h>
    15	#include <asm/apic.h>
    16	#include <asm/uv/uv.h>
    17	
    18	/*
    19	 *	TLB flushing, formerly SMP-only
    20	 *		c/o Linus Torvalds.
    21	 *
    22	 *	These mean you can really definitely utterly forget about
    23	 *	writing to user space from interrupts. (Its not allowed anyway).
    24	 *
    25	 *	Optimizations Manfred Spraul <manfred@...orfullife.com>
    26	 *
    27	 *	More scalable flush, from Andi Kleen
    28	 *
    29	 *	Implement flush IPI by CALL_FUNCTION_VECTOR, Alex Shi
    30	 */
    31	
    32	/*
    33	 * Use bit 0 to mangle the TIF_SPEC_IB state into the mm pointer which is
    34	 * stored in cpu_tlb_state.last_user_mm_ibpb.
    35	 */
    36	#define LAST_USER_MM_IBPB	0x1UL
    37	
    38	/*
    39	 * We get here when we do something requiring a TLB invalidation
    40	 * but could not go invalidate all of the contexts.  We do the
    41	 * necessary invalidation by clearing out the 'ctx_id' which
    42	 * forces a TLB flush when the context is loaded.
    43	 */
    44	static void clear_asid_other(void)
    45	{
    46		u16 asid;
    47	
    48		/*
    49		 * This is only expected to be set if we have disabled
    50		 * kernel _PAGE_GLOBAL pages.
    51		 */
    52		if (!static_cpu_has(X86_FEATURE_PTI)) {
    53			WARN_ON_ONCE(1);
    54			return;
    55		}
    56	
    57		for (asid = 0; asid < TLB_NR_DYN_ASIDS; asid++) {
    58			/* Do not need to flush the current asid */
    59			if (asid == this_cpu_read(cpu_tlbstate.loaded_mm_asid))
    60				continue;
    61			/*
    62			 * Make sure the next time we go to switch to
    63			 * this asid, we do a flush:
    64			 */
    65			this_cpu_write(cpu_tlbstate.ctxs[asid].ctx_id, 0);
    66		}
    67		this_cpu_write(cpu_tlbstate.invalidate_other, false);
    68	}
    69	
    70	atomic64_t last_mm_ctx_id = ATOMIC64_INIT(1);
    71	
    72	
    73	static void choose_new_asid(struct mm_struct *next, u64 next_tlb_gen,
    74				    u16 *new_asid, bool *need_flush)
    75	{
    76		u16 asid;
    77	
    78		if (!static_cpu_has(X86_FEATURE_PCID)) {
    79			*new_asid = 0;
    80			*need_flush = true;
    81			return;
    82		}
    83	
    84		if (this_cpu_read(cpu_tlbstate.invalidate_other))
    85			clear_asid_other();
    86	
    87		for (asid = 0; asid < TLB_NR_DYN_ASIDS; asid++) {
    88			if (this_cpu_read(cpu_tlbstate.ctxs[asid].ctx_id) !=
    89			    next->context.ctx_id)
    90				continue;
    91	
    92			*new_asid = asid;
    93			*need_flush = (this_cpu_read(cpu_tlbstate.ctxs[asid].tlb_gen) <
    94				       next_tlb_gen);
    95			return;
    96		}
    97	
    98		/*
    99		 * We don't currently own an ASID slot on this CPU.
   100		 * Allocate a slot.
   101		 */
   102		*new_asid = this_cpu_add_return(cpu_tlbstate.next_asid, 1) - 1;
   103		if (*new_asid >= TLB_NR_DYN_ASIDS) {
   104			*new_asid = 0;
   105			this_cpu_write(cpu_tlbstate.next_asid, 1);
   106		}
   107		*need_flush = true;
   108	}
   109	
   110	static void load_new_mm_cr3(pgd_t *pgdir, u16 new_asid, bool need_flush)
   111	{
   112		unsigned long new_mm_cr3;
   113	
   114		if (need_flush) {
   115			invalidate_user_asid(new_asid);
   116			new_mm_cr3 = build_cr3(pgdir, new_asid);
   117		} else {
   118			new_mm_cr3 = build_cr3_noflush(pgdir, new_asid);
   119		}
   120	
   121		/*
   122		 * Caution: many callers of this function expect
   123		 * that load_cr3() is serializing and orders TLB
   124		 * fills with respect to the mm_cpumask writes.
   125		 */
   126		write_cr3(new_mm_cr3);
   127	}
   128	
   129	void leave_mm(int cpu)
   130	{
   131		struct mm_struct *loaded_mm = this_cpu_read(cpu_tlbstate.loaded_mm);
   132	
   133		/*
   134		 * It's plausible that we're in lazy TLB mode while our mm is init_mm.
   135		 * If so, our callers still expect us to flush the TLB, but there
   136		 * aren't any user TLB entries in init_mm to worry about.
   137		 *
   138		 * This needs to happen before any other sanity checks due to
   139		 * intel_idle's shenanigans.
   140		 */
   141		if (loaded_mm == &init_mm)
   142			return;
   143	
   144		/* Warn if we're not lazy. */
   145		WARN_ON(!this_cpu_read(cpu_tlbstate.is_lazy));
   146	
   147		switch_mm(NULL, &init_mm, NULL);
   148	}
   149	EXPORT_SYMBOL_GPL(leave_mm);
   150	
   151	void switch_mm(struct mm_struct *prev, struct mm_struct *next,
   152		       struct task_struct *tsk)
   153	{
   154		unsigned long flags;
   155	
   156		local_irq_save(flags);
   157		switch_mm_irqs_off(prev, next, tsk);
   158		local_irq_restore(flags);
   159	}
   160	
   161	static void sync_current_stack_to_mm(struct mm_struct *mm)
   162	{
   163		unsigned long sp = current_stack_pointer;
   164		pgd_t *pgd = pgd_offset(mm, sp);
   165	
   166		if (pgtable_l5_enabled()) {
   167			if (unlikely(pgd_none(*pgd))) {
   168				pgd_t *pgd_ref = pgd_offset_k(sp);
   169	
   170				set_pgd(pgd, *pgd_ref);
   171			}
   172		} else {
   173			/*
   174			 * "pgd" is faked.  The top level entries are "p4d"s, so sync
   175			 * the p4d.  This compiles to approximately the same code as
   176			 * the 5-level case.
   177			 */
   178			p4d_t *p4d = p4d_offset(pgd, sp);
   179	
   180			if (unlikely(p4d_none(*p4d))) {
   181				pgd_t *pgd_ref = pgd_offset_k(sp);
   182				p4d_t *p4d_ref = p4d_offset(pgd_ref, sp);
   183	
   184				set_p4d(p4d, *p4d_ref);
   185			}
   186		}
   187	}
   188	
   189	static inline unsigned long mm_mangle_tif_spec_ib(struct task_struct *next)
   190	{
   191		unsigned long next_tif = task_thread_info(next)->flags;
 > 192		unsigned long ibpb = (next_tif >> TIF_SPEC_IB) & LAST_USR_MM_IBPB;
   193	
   194		return (unsigned long)next->mm | ibpb;
   195	}
   196	
   197	static void cond_ibpb(struct task_struct *next)
   198	{
   199		if (!next || !next->mm)
   200			return;
   201	
   202		if (static_branch_likely(&switch_mm_cond_ibpb)) {
   203			unsigned long prev_mm, next_mm;
   204	
   205			/*
   206			 * This is a bit more complex than the always mode because
   207			 * it has to handle two cases:
   208			 *
   209			 * 1) Switch from a user space task (potential attacker)
   210			 *    which has TIF_SPEC_IB set to a user space task
   211			 *    (potential victim) which has TIF_SPEC_IB not set.
   212			 *
   213			 * 2) Switch from a user space task (potential attacker)
   214			 *    which has TIF_SPEC_IB not set to a user space task
   215			 *    (potential victim) which has TIF_SPEC_IB set.
   216			 *
   217			 * This could be done by unconditionally issuing IBPB when
   218			 * a task which has TIF_SPEC_IB set is either scheduled in
   219			 * or out. Though that results in two flushes when:
   220			 *
   221			 * - the same user space task is scheduled out and later
   222			 *   scheduled in again and only a kernel thread ran in
   223			 *   between.
   224			 *
   225			 * - a user space task belonging to the same process is
   226			 *   scheduled in after a kernel thread ran in between
   227			 *
   228			 * - a user space task belonging to the same process is
   229			 *   scheduled in immediately.
   230			 *
   231			 * Optimize this with reasonably small overhead for the
   232			 * above cases. Mangle the TIF_SPEC_IB bit into the mm
   233			 * pointer of the incoming task which is stored in
   234			 * cpu_tlbstate.last_user_mm_ibpb for comparison.
   235			 */
   236			next_mm = mm_mangle_tif_spec_ib(next);
   237			prev_mm = this_cpu_read(cpu_tlbstate.last_user_mm_ibpb);
   238	
   239			/*
   240			 * Issue IBPB only if the mm's are different and one or
   241			 * both have the IBPB bit set.
   242			 */
 > 243			if (next_mm != prev_mm && (next_mm | prev_mm) & LAST_USR_MM_IBPB)
   244				indirect_branch_prediction_barrier();
   245	
   246			this_cpu_write(cpu_tlbstate.last_user_mm_ibpb, next_mm);
   247		}
   248	
   249		if (static_branch_unlikely(&switch_mm_always_ibpb)) {
   250			/*
   251			 * Only flush when switching to a user space task with a
   252			 * different context than the user space task which ran
   253			 * last on this CPU.
   254			 */
   255			if (this_cpu_read(cpu_tlbstate.last_user_mm) != next->mm) {
   256				indirect_branch_prediction_barrier();
   257				this_cpu_write(cpu_tlbstate.last_user_mm, next->mm);
   258			}
   259		}
   260	}
   261	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

Download attachment ".config.gz" of type "application/gzip" (29034 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ