~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/kernel/uprobes.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/powerpc/kernel/uprobes.c (Version linux-6.12-rc7) and /arch/i386/kernel/uprobes.c (Version linux-5.17.15)


  1 // SPDX-License-Identifier: GPL-2.0-or-later        1 
  2 /*                                                
  3  * User-space Probes (UProbes) for powerpc        
  4  *                                                
  5  * Copyright IBM Corporation, 2007-2012           
  6  *                                                
  7  * Adapted from the x86 port by Ananth N Mavin    
  8  */                                               
  9 #include <linux/kernel.h>                         
 10 #include <linux/sched.h>                          
 11 #include <linux/ptrace.h>                         
 12 #include <linux/uprobes.h>                        
 13 #include <linux/uaccess.h>                        
 14 #include <linux/kdebug.h>                         
 15                                                   
 16 #include <asm/sstep.h>                            
 17 #include <asm/inst.h>                             
 18                                                   
 19 #define UPROBE_TRAP_NR  UINT_MAX                  
 20                                                   
 21 /**                                               
 22  * is_trap_insn - check if the instruction is     
 23  * @insn: instruction to be checked.              
 24  * Returns true if @insn is a trap variant.       
 25  */                                               
 26 bool is_trap_insn(uprobe_opcode_t *insn)          
 27 {                                                 
 28         return (is_trap(*insn));                  
 29 }                                                 
 30                                                   
 31 /**                                               
 32  * arch_uprobe_analyze_insn                       
 33  * @mm: the probed address space.                 
 34  * @arch_uprobe: the probepoint information.      
 35  * @addr: vaddr to probe.                         
 36  * Return 0 on success or a -ve number on erro    
 37  */                                               
 38 int arch_uprobe_analyze_insn(struct arch_uprob    
 39                 struct mm_struct *mm, unsigned    
 40 {                                                 
 41         if (addr & 0x03)                          
 42                 return -EINVAL;                   
 43                                                   
 44         if (cpu_has_feature(CPU_FTR_ARCH_31) &    
 45             ppc_inst_prefixed(ppc_inst_read(au    
 46             (addr & 0x3f) == 60) {                
 47                 pr_info_ratelimited("Cannot re    
 48                 return -EINVAL;                   
 49         }                                         
 50                                                   
 51         if (!can_single_step(ppc_inst_val(ppc_    
 52                 pr_info_ratelimited("Cannot re    
 53                 return -ENOTSUPP;                 
 54         }                                         
 55                                                   
 56         return 0;                                 
 57 }                                                 
 58                                                   
 59 /*                                                
 60  * arch_uprobe_pre_xol - prepare to execute ou    
 61  * @auprobe: the probepoint information.          
 62  * @regs: reflects the saved user state of cur    
 63  */                                               
 64 int arch_uprobe_pre_xol(struct arch_uprobe *au    
 65 {                                                 
 66         struct arch_uprobe_task *autask = &cur    
 67                                                   
 68         autask->saved_trap_nr = current->threa    
 69         current->thread.trap_nr = UPROBE_TRAP_    
 70         regs_set_return_ip(regs, current->utas    
 71                                                   
 72         user_enable_single_step(current);         
 73         return 0;                                 
 74 }                                                 
 75                                                   
 76 /**                                               
 77  * uprobe_get_swbp_addr - compute address of s    
 78  * @regs: Reflects the saved state of the task    
 79  * instruction.                                   
 80  * Return the address of the breakpoint instru    
 81  */                                               
 82 unsigned long uprobe_get_swbp_addr(struct pt_r    
 83 {                                                 
 84         return instruction_pointer(regs);         
 85 }                                                 
 86                                                   
 87 /*                                                
 88  * If xol insn itself traps and generates a si    
 89  * then detect the case where a singlestepped     
 90  * own address. It is assumed that anything li    
 91  * sets thread.trap_nr != UINT_MAX.               
 92  *                                                
 93  * arch_uprobe_pre_xol/arch_uprobe_post_xol sa    
 94  * arch_uprobe_xol_was_trapped() simply checks    
 95  * UPROBE_TRAP_NR == UINT_MAX set by arch_upro    
 96  */                                               
 97 bool arch_uprobe_xol_was_trapped(struct task_s    
 98 {                                                 
 99         if (t->thread.trap_nr != UPROBE_TRAP_N    
100                 return true;                      
101                                                   
102         return false;                             
103 }                                                 
104                                                   
105 /*                                                
106  * Called after single-stepping. To avoid the     
107  * occur when we temporarily put back the orig    
108  * single-step, we single-stepped a copy of th    
109  *                                                
110  * This function prepares to resume execution     
111  */                                               
112 int arch_uprobe_post_xol(struct arch_uprobe *a    
113 {                                                 
114         struct uprobe_task *utask = current->u    
115                                                   
116         WARN_ON_ONCE(current->thread.trap_nr !    
117                                                   
118         current->thread.trap_nr = utask->autas    
119                                                   
120         /*                                        
121          * On powerpc, except for loads and st    
122          * including ones that alter code flow    
123          * are emulated in the kernel. We get     
124          * support doesn't exist and have to f    
125          * to be executed.                        
126          */                                       
127         regs_set_return_ip(regs, (unsigned lon    
128                                                   
129         user_disable_single_step(current);        
130         return 0;                                 
131 }                                                 
132                                                   
133 /* callback routine for handling exceptions. *    
134 int arch_uprobe_exception_notify(struct notifi    
135                                 unsigned long     
136 {                                                 
137         struct die_args *args = data;             
138         struct pt_regs *regs = args->regs;        
139                                                   
140         /* regs == NULL is a kernel bug */        
141         if (WARN_ON(!regs))                       
142                 return NOTIFY_DONE;               
143                                                   
144         /* We are only interested in userspace    
145         if (!user_mode(regs))                     
146                 return NOTIFY_DONE;               
147                                                   
148         switch (val) {                            
149         case DIE_BPT:                             
150                 if (uprobe_pre_sstep_notifier(    
151                         return NOTIFY_STOP;       
152                 break;                            
153         case DIE_SSTEP:                           
154                 if (uprobe_post_sstep_notifier    
155                         return NOTIFY_STOP;       
156                 break;                            
157         default:                                  
158                 break;                            
159         }                                         
160         return NOTIFY_DONE;                       
161 }                                                 
162                                                   
163 /*                                                
164  * This function gets called when XOL instruct    
165  * the thread has a fatal signal, so reset the    
166  * probed address.                                
167  */                                               
168 void arch_uprobe_abort_xol(struct arch_uprobe     
169 {                                                 
170         struct uprobe_task *utask = current->u    
171                                                   
172         current->thread.trap_nr = utask->autas    
173         instruction_pointer_set(regs, utask->v    
174                                                   
175         user_disable_single_step(current);        
176 }                                                 
177                                                   
178 /*                                                
179  * See if the instruction can be emulated.        
180  * Returns true if instruction was emulated, f    
181  */                                               
182 bool arch_uprobe_skip_sstep(struct arch_uprobe    
183 {                                                 
184         int ret;                                  
185                                                   
186         /*                                        
187          * emulate_step() returns 1 if the ins    
188          * For all other cases, we need to sin    
189          */                                       
190         ret = emulate_step(regs, ppc_inst_read    
191         if (ret > 0)                              
192                 return true;                      
193                                                   
194         return false;                             
195 }                                                 
196                                                   
197 unsigned long                                     
198 arch_uretprobe_hijack_return_addr(unsigned lon    
199 {                                                 
200         unsigned long orig_ret_vaddr;             
201                                                   
202         orig_ret_vaddr = regs->link;              
203                                                   
204         /* Replace the return addr with trampo    
205         regs->link = trampoline_vaddr;            
206                                                   
207         return orig_ret_vaddr;                    
208 }                                                 
209                                                   
210 bool arch_uretprobe_is_alive(struct return_ins    
211                                 struct pt_regs    
212 {                                                 
213         if (ctx == RP_CHECK_CHAIN_CALL)           
214                 return regs->gpr[1] <= ret->st    
215         else                                      
216                 return regs->gpr[1] < ret->sta    
217 }                                                 
218                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php