mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	KEYS: Extend TIF_NOTIFY_RESUME to (almost) all architectures [try #6]
Implement TIF_NOTIFY_RESUME for most of those architectures in which isn't yet available, and, whilst we're at it, have it call the appropriate tracehook. After this patch, blackfin, m68k* and xtensa still lack support and need alteration of assembly code to make it work. Resume notification can then be used (by a later patch) to install a new session keyring on the parent of a process. Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Russell King <rmk+kernel@arm.linux.org.uk> cc: linux-arch@vger.kernel.org Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
		
							parent
							
								
									7b1b916459
								
							
						
					
					
						commit
						d0420c83f3
					
				
					 18 changed files with 64 additions and 6 deletions
				
			
		| 
						 | 
				
			
			@ -75,6 +75,7 @@ register struct thread_info *__current_thread_info __asm__("$8");
 | 
			
		|||
#define TIF_UAC_SIGBUS		7
 | 
			
		||||
#define TIF_MEMDIE		8
 | 
			
		||||
#define TIF_RESTORE_SIGMASK	9	/* restore signal mask in do_signal */
 | 
			
		||||
#define TIF_NOTIFY_RESUME	10	/* callback before returning to user */
 | 
			
		||||
#define TIF_FREEZE		16	/* is freezing for suspend */
 | 
			
		||||
 | 
			
		||||
#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 | 
			
		||||
| 
						 | 
				
			
			@ -82,10 +83,12 @@ register struct thread_info *__current_thread_info __asm__("$8");
 | 
			
		|||
#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 | 
			
		||||
#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 | 
			
		||||
#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 | 
			
		||||
#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 | 
			
		||||
#define _TIF_FREEZE		(1<<TIF_FREEZE)
 | 
			
		||||
 | 
			
		||||
/* Work to do on interrupt/exception return.  */
 | 
			
		||||
#define _TIF_WORK_MASK		(_TIF_SIGPENDING | _TIF_NEED_RESCHED)
 | 
			
		||||
#define _TIF_WORK_MASK		(_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
 | 
			
		||||
				 _TIF_NOTIFY_RESUME)
 | 
			
		||||
 | 
			
		||||
/* Work to do on any return to userspace.  */
 | 
			
		||||
#define _TIF_ALLWORK_MASK	(_TIF_WORK_MASK		\
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -683,4 +683,9 @@ do_notify_resume(struct pt_regs *regs, struct switch_stack *sw,
 | 
			
		|||
{
 | 
			
		||||
	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
 | 
			
		||||
		do_signal(regs, sw, r0, r19);
 | 
			
		||||
 | 
			
		||||
	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
 | 
			
		||||
		clear_thread_flag(TIF_NOTIFY_RESUME);
 | 
			
		||||
		tracehook_notify_resume(regs);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -130,11 +130,13 @@ extern void vfp_sync_state(struct thread_info *thread);
 | 
			
		|||
 *  TIF_SYSCALL_TRACE	- syscall trace active
 | 
			
		||||
 *  TIF_SIGPENDING	- signal pending
 | 
			
		||||
 *  TIF_NEED_RESCHED	- rescheduling necessary
 | 
			
		||||
 *  TIF_NOTIFY_RESUME	- callback before returning to user
 | 
			
		||||
 *  TIF_USEDFPU		- FPU was used by this task this quantum (SMP)
 | 
			
		||||
 *  TIF_POLLING_NRFLAG	- true if poll_idle() is polling TIF_NEED_RESCHED
 | 
			
		||||
 */
 | 
			
		||||
#define TIF_SIGPENDING		0
 | 
			
		||||
#define TIF_NEED_RESCHED	1
 | 
			
		||||
#define TIF_NOTIFY_RESUME	2	/* callback before returning to user */
 | 
			
		||||
#define TIF_SYSCALL_TRACE	8
 | 
			
		||||
#define TIF_POLLING_NRFLAG	16
 | 
			
		||||
#define TIF_USING_IWMMXT	17
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +145,7 @@ extern void vfp_sync_state(struct thread_info *thread);
 | 
			
		|||
 | 
			
		||||
#define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 | 
			
		||||
#define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
 | 
			
		||||
#define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 | 
			
		||||
#define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 | 
			
		||||
#define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 | 
			
		||||
#define _TIF_USING_IWMMXT	(1 << TIF_USING_IWMMXT)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,7 +51,7 @@ fast_work_pending:
 | 
			
		|||
work_pending:
 | 
			
		||||
	tst	r1, #_TIF_NEED_RESCHED
 | 
			
		||||
	bne	work_resched
 | 
			
		||||
	tst	r1, #_TIF_SIGPENDING
 | 
			
		||||
	tst	r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME
 | 
			
		||||
	beq	no_work_pending
 | 
			
		||||
	mov	r0, sp				@ 'regs'
 | 
			
		||||
	mov	r2, why				@ 'syscall'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -707,4 +707,9 @@ do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall)
 | 
			
		|||
{
 | 
			
		||||
	if (thread_flags & _TIF_SIGPENDING)
 | 
			
		||||
		do_signal(¤t->blocked, regs, syscall);
 | 
			
		||||
 | 
			
		||||
	if (thread_flags & _TIF_NOTIFY_RESUME) {
 | 
			
		||||
		clear_thread_flag(TIF_NOTIFY_RESUME);
 | 
			
		||||
		tracehook_notify_resume(regs);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -84,6 +84,7 @@ static inline struct thread_info *current_thread_info(void)
 | 
			
		|||
#define TIF_MEMDIE		6
 | 
			
		||||
#define TIF_RESTORE_SIGMASK	7	/* restore signal mask in do_signal */
 | 
			
		||||
#define TIF_CPU_GOING_TO_SLEEP	8	/* CPU is entering sleep 0 mode */
 | 
			
		||||
#define TIF_NOTIFY_RESUME	9	/* callback before returning to user */
 | 
			
		||||
#define TIF_FREEZE		29
 | 
			
		||||
#define TIF_DEBUG		30	/* debugging enabled */
 | 
			
		||||
#define TIF_USERSPACE		31      /* true if FS sets userspace */
 | 
			
		||||
| 
						 | 
				
			
			@ -96,6 +97,7 @@ static inline struct thread_info *current_thread_info(void)
 | 
			
		|||
#define _TIF_MEMDIE		(1 << TIF_MEMDIE)
 | 
			
		||||
#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
 | 
			
		||||
#define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP)
 | 
			
		||||
#define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 | 
			
		||||
#define _TIF_FREEZE		(1 << TIF_FREEZE)
 | 
			
		||||
 | 
			
		||||
/* Note: The masks below must never span more than 16 bits! */
 | 
			
		||||
| 
						 | 
				
			
			@ -103,13 +105,15 @@ static inline struct thread_info *current_thread_info(void)
 | 
			
		|||
/* work to do on interrupt/exception return */
 | 
			
		||||
#define _TIF_WORK_MASK				\
 | 
			
		||||
	((1 << TIF_SIGPENDING)			\
 | 
			
		||||
	 | _TIF_NOTIFY_RESUME			\
 | 
			
		||||
	 | (1 << TIF_NEED_RESCHED)		\
 | 
			
		||||
	 | (1 << TIF_POLLING_NRFLAG)		\
 | 
			
		||||
	 | (1 << TIF_BREAKPOINT)		\
 | 
			
		||||
	 | (1 << TIF_RESTORE_SIGMASK))
 | 
			
		||||
 | 
			
		||||
/* work to do on any return to userspace */
 | 
			
		||||
#define _TIF_ALLWORK_MASK	(_TIF_WORK_MASK | (1 << TIF_SYSCALL_TRACE))
 | 
			
		||||
#define _TIF_ALLWORK_MASK	(_TIF_WORK_MASK | (1 << TIF_SYSCALL_TRACE) | \
 | 
			
		||||
				 _TIF_NOTIFY_RESUME)
 | 
			
		||||
/* work to do on return from debug mode */
 | 
			
		||||
#define _TIF_DBGWORK_MASK	(_TIF_WORK_MASK & ~(1 << TIF_BREAKPOINT))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -281,7 +281,7 @@ syscall_exit_work:
 | 
			
		|||
	ld.w	r1, r0[TI_flags]
 | 
			
		||||
	rjmp	1b
 | 
			
		||||
 | 
			
		||||
2:	mov	r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK
 | 
			
		||||
2:	mov	r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NOTIFY_RESUME
 | 
			
		||||
	tst	r1, r2
 | 
			
		||||
	breq	3f
 | 
			
		||||
	unmask_interrupts
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -322,4 +322,9 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti)
 | 
			
		|||
 | 
			
		||||
	if (ti->flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
 | 
			
		||||
		do_signal(regs, ¤t->blocked, syscall);
 | 
			
		||||
 | 
			
		||||
	if (ti->flags & _TIF_NOTIFY_RESUME) {
 | 
			
		||||
		clear_thread_flag(TIF_NOTIFY_RESUME);
 | 
			
		||||
		tracehook_notify_resume(regs);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,4 +36,9 @@ void do_notify_resume(int canrestart, struct pt_regs *regs,
 | 
			
		|||
	/* deal with pending signal delivery */
 | 
			
		||||
	if (thread_info_flags & _TIF_SIGPENDING)
 | 
			
		||||
		do_signal(canrestart,regs);
 | 
			
		||||
 | 
			
		||||
	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
 | 
			
		||||
		clear_thread_flag(TIF_NOTIFY_RESUME);
 | 
			
		||||
		tracehook_notify_resume(regs);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -89,6 +89,7 @@ static inline struct thread_info *current_thread_info(void)
 | 
			
		|||
					   TIF_NEED_RESCHED */
 | 
			
		||||
#define TIF_MEMDIE		4
 | 
			
		||||
#define TIF_RESTORE_SIGMASK	5	/* restore signal mask in do_signal() */
 | 
			
		||||
#define TIF_NOTIFY_RESUME	6	/* callback before returning to user */
 | 
			
		||||
#define TIF_FREEZE		16	/* is freezing for suspend */
 | 
			
		||||
 | 
			
		||||
/* as above, but as bit values */
 | 
			
		||||
| 
						 | 
				
			
			@ -97,6 +98,7 @@ static inline struct thread_info *current_thread_info(void)
 | 
			
		|||
#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 | 
			
		||||
#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 | 
			
		||||
#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 | 
			
		||||
#define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 | 
			
		||||
#define _TIF_FREEZE		(1<<TIF_FREEZE)
 | 
			
		||||
 | 
			
		||||
#define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -552,4 +552,9 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
 | 
			
		|||
{
 | 
			
		||||
	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
 | 
			
		||||
		do_signal(regs, NULL);
 | 
			
		||||
 | 
			
		||||
	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
 | 
			
		||||
		clear_thread_flag(TIF_NOTIFY_RESUME);
 | 
			
		||||
		tracehook_notify_resume(regs);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,6 +149,7 @@ static inline unsigned int get_thread_fault_code(void)
 | 
			
		|||
#define TIF_NEED_RESCHED	2	/* rescheduling necessary */
 | 
			
		||||
#define TIF_SINGLESTEP		3	/* restore singlestep on return to user mode */
 | 
			
		||||
#define TIF_IRET		4	/* return with iret */
 | 
			
		||||
#define TIF_NOTIFY_RESUME	5	/* callback before returning to user */
 | 
			
		||||
#define TIF_RESTORE_SIGMASK	8	/* restore signal mask in do_signal() */
 | 
			
		||||
#define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
 | 
			
		||||
#define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 | 
			
		||||
| 
						 | 
				
			
			@ -160,6 +161,7 @@ static inline unsigned int get_thread_fault_code(void)
 | 
			
		|||
#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 | 
			
		||||
#define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
 | 
			
		||||
#define _TIF_IRET		(1<<TIF_IRET)
 | 
			
		||||
#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 | 
			
		||||
#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 | 
			
		||||
#define _TIF_USEDFPU		(1<<TIF_USEDFPU)
 | 
			
		||||
#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -408,5 +408,10 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
 | 
			
		|||
	if (thread_info_flags & _TIF_SIGPENDING)
 | 
			
		||||
		do_signal(regs,oldset);
 | 
			
		||||
 | 
			
		||||
	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
 | 
			
		||||
		clear_thread_flag(TIF_NOTIFY_RESUME);
 | 
			
		||||
		tracehook_notify_resume(regs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	clear_thread_flag(TIF_IRET);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,6 +115,7 @@ register struct thread_info *__current_thread_info __asm__("$28");
 | 
			
		|||
#define TIF_NEED_RESCHED	2	/* rescheduling necessary */
 | 
			
		||||
#define TIF_SYSCALL_AUDIT	3	/* syscall auditing active */
 | 
			
		||||
#define TIF_SECCOMP		4	/* secure computing */
 | 
			
		||||
#define TIF_NOTIFY_RESUME	5	/* callback before returning to user */
 | 
			
		||||
#define TIF_RESTORE_SIGMASK	9	/* restore signal mask in do_signal() */
 | 
			
		||||
#define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
 | 
			
		||||
#define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 | 
			
		||||
| 
						 | 
				
			
			@ -139,6 +140,7 @@ register struct thread_info *__current_thread_info __asm__("$28");
 | 
			
		|||
#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 | 
			
		||||
#define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
 | 
			
		||||
#define _TIF_SECCOMP		(1<<TIF_SECCOMP)
 | 
			
		||||
#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 | 
			
		||||
#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 | 
			
		||||
#define _TIF_USEDFPU		(1<<TIF_USEDFPU)
 | 
			
		||||
#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -700,4 +700,9 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
 | 
			
		|||
	/* deal with pending signal delivery */
 | 
			
		||||
	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
 | 
			
		||||
		do_signal(regs);
 | 
			
		||||
 | 
			
		||||
	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
 | 
			
		||||
		clear_thread_flag(TIF_NOTIFY_RESUME);
 | 
			
		||||
		tracehook_notify_resume(regs);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,6 +59,7 @@ struct thread_info {
 | 
			
		|||
#define TIF_MEMDIE		5
 | 
			
		||||
#define TIF_RESTORE_SIGMASK	6	/* restore saved signal mask */
 | 
			
		||||
#define TIF_FREEZE		7	/* is freezing for suspend */
 | 
			
		||||
#define TIF_NOTIFY_RESUME	8	/* callback before returning to user */
 | 
			
		||||
 | 
			
		||||
#define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 | 
			
		||||
#define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 | 
			
		||||
| 
						 | 
				
			
			@ -67,8 +68,9 @@ struct thread_info {
 | 
			
		|||
#define _TIF_32BIT		(1 << TIF_32BIT)
 | 
			
		||||
#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
 | 
			
		||||
#define _TIF_FREEZE		(1 << TIF_FREEZE)
 | 
			
		||||
#define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 | 
			
		||||
 | 
			
		||||
#define _TIF_USER_WORK_MASK     (_TIF_SIGPENDING | \
 | 
			
		||||
#define _TIF_USER_WORK_MASK     (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \
 | 
			
		||||
                                 _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK)
 | 
			
		||||
 | 
			
		||||
#endif /* __KERNEL__ */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -948,7 +948,7 @@ intr_check_sig:
 | 
			
		|||
	/* As above */
 | 
			
		||||
	mfctl   %cr30,%r1
 | 
			
		||||
	LDREG	TI_FLAGS(%r1),%r19
 | 
			
		||||
	ldi	(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %r20
 | 
			
		||||
	ldi	(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NOTIFY_RESUME), %r20
 | 
			
		||||
	and,COND(<>)	%r19, %r20, %r0
 | 
			
		||||
	b,n	intr_restore	/* skip past if we've nothing to do */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -645,4 +645,9 @@ void do_notify_resume(struct pt_regs *regs, long in_syscall)
 | 
			
		|||
	if (test_thread_flag(TIF_SIGPENDING) ||
 | 
			
		||||
	    test_thread_flag(TIF_RESTORE_SIGMASK))
 | 
			
		||||
		do_signal(regs, in_syscall);
 | 
			
		||||
 | 
			
		||||
	if (test_thread_flag(TIF_NOTIFY_RESUME)) {
 | 
			
		||||
		clear_thread_flag(TIF_NOTIFY_RESUME);
 | 
			
		||||
		tracehook_notify_resume(regs);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue