mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 08:44:41 +00:00 
			
		
		
		
	arm64: Snapshot thread flags
Some thread flags can be set remotely, and so even when IRQs are disabled, the flags can change under our feet. Generally this is unlikely to cause a problem in practice, but it is somewhat unsound, and KCSAN will legitimately warn that there is a data race. To avoid such issues, a snapshot of the flags has to be taken prior to using them. Some places already use READ_ONCE() for that, others do not. Convert them all to the new flag accessor helpers. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Will Deacon <will@kernel.org> Acked-by: Paul E. McKenney <paulmck@kernel.org> Cc: Catalin Marinas <catalin.marinas@arm.com> Link: https://lore.kernel.org/r/20211129130653.2037928-7-mark.rutland@arm.com
This commit is contained in:
		
							parent
							
								
									050e22bfc4
								
							
						
					
					
						commit
						342b380878
					
				
					 4 changed files with 6 additions and 6 deletions
				
			
		|  | @ -129,7 +129,7 @@ static __always_inline void prepare_exit_to_user_mode(struct pt_regs *regs) | |||
| 
 | ||||
| 	local_daif_mask(); | ||||
| 
 | ||||
| 	flags = READ_ONCE(current_thread_info()->flags); | ||||
| 	flags = read_thread_flags(); | ||||
| 	if (unlikely(flags & _TIF_WORK_MASK)) | ||||
| 		do_notify_resume(regs, flags); | ||||
| } | ||||
|  |  | |||
|  | @ -1839,7 +1839,7 @@ static void tracehook_report_syscall(struct pt_regs *regs, | |||
| 
 | ||||
| int syscall_trace_enter(struct pt_regs *regs) | ||||
| { | ||||
| 	unsigned long flags = READ_ONCE(current_thread_info()->flags); | ||||
| 	unsigned long flags = read_thread_flags(); | ||||
| 
 | ||||
| 	if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) { | ||||
| 		tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER); | ||||
|  | @ -1862,7 +1862,7 @@ int syscall_trace_enter(struct pt_regs *regs) | |||
| 
 | ||||
| void syscall_trace_exit(struct pt_regs *regs) | ||||
| { | ||||
| 	unsigned long flags = READ_ONCE(current_thread_info()->flags); | ||||
| 	unsigned long flags = read_thread_flags(); | ||||
| 
 | ||||
| 	audit_syscall_exit(regs); | ||||
| 
 | ||||
|  |  | |||
|  | @ -948,7 +948,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags) | |||
| 		} | ||||
| 
 | ||||
| 		local_daif_mask(); | ||||
| 		thread_flags = READ_ONCE(current_thread_info()->flags); | ||||
| 		thread_flags = read_thread_flags(); | ||||
| 	} while (thread_flags & _TIF_WORK_MASK); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -81,7 +81,7 @@ void syscall_trace_exit(struct pt_regs *regs); | |||
| static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, | ||||
| 			   const syscall_fn_t syscall_table[]) | ||||
| { | ||||
| 	unsigned long flags = current_thread_info()->flags; | ||||
| 	unsigned long flags = read_thread_flags(); | ||||
| 
 | ||||
| 	regs->orig_x0 = regs->regs[0]; | ||||
| 	regs->syscallno = scno; | ||||
|  | @ -148,7 +148,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, | |||
| 	 */ | ||||
| 	if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) { | ||||
| 		local_daif_mask(); | ||||
| 		flags = current_thread_info()->flags; | ||||
| 		flags = read_thread_flags(); | ||||
| 		if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) | ||||
| 			return; | ||||
| 		local_daif_restore(DAIF_PROCCTX); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Mark Rutland
						Mark Rutland