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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 David Howells
				David Howells