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

TOMOYO Linux Cross Reference
Linux/arch/hexagon/kernel/vm_entry.S

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.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/hexagon/kernel/vm_entry.S (Architecture mips) and /arch/sparc/kernel/vm_entry.S (Architecture sparc)


  1 /* SPDX-License-Identifier: GPL-2.0-only */       
  2 /*                                                
  3  * Event entry/exit for Hexagon                   
  4  *                                                
  5  * Copyright (c) 2010-2013, The Linux Foundati    
  6  */                                               
  7                                                   
  8 #include <asm/asm-offsets.h>  /*  assembly-saf    
  9 #include <asm/mem-layout.h>   /*  sigh, except    
 10 #include <asm/hexagon_vm.h>                       
 11 #include <asm/thread_info.h>                      
 12                                                   
 13 /*                                                
 14  * Entry into guest-mode Linux under Hexagon V    
 15  * Stack pointer points to event record - buil    
 16  * set up a plausible C stack frame, and dispa    
 17  * On return, do vmrte virtual instruction wit    
 18  *                                                
 19  * VM Spec 0.5 uses a trap to fetch HVM record    
 20  */                                               
 21                                                   
 22 /*                                                
 23  * Save full register state, while setting up     
 24  * pointer derived from kernel stack pointer i    
 25  * register, putting prior thread_info.regs po    
 26  * register (R24, which had better not ever be    
 27  * and updating thread_info.regs to point to c    
 28  * so as to support nested events in kernel mo    
 29  *                                                
 30  * As this is common code, we set the pt_regs     
 31  * to -1 for all events.  It will be replaced     
 32  * number in the case where we decode a system    
 33  */                                               
 34                                                   
 35 #if CONFIG_HEXAGON_ARCH_VERSION < 4               
 36 #define save_pt_regs()\                           
 37  memd(R0 + #_PT_R3130) = R31:30; \                
 38  { memw(R0 + #_PT_R2928) = R28; \                 
 39    R31 = memw(R0 + #_PT_ER_VMPSP); }\             
 40  { memw(R0 + #(_PT_R2928 + 4)) = R31; \           
 41    R31 = ugp; } \                                 
 42  { memd(R0 + #_PT_R2726) = R27:26; \              
 43    R30 = gp ; } \                                 
 44  memd(R0 + #_PT_R2524) = R25:24; \                
 45  memd(R0 + #_PT_R2322) = R23:22; \                
 46  memd(R0 + #_PT_R2120) = R21:20; \                
 47  memd(R0 + #_PT_R1918) = R19:18; \                
 48  memd(R0 + #_PT_R1716) = R17:16; \                
 49  memd(R0 + #_PT_R1514) = R15:14; \                
 50  memd(R0 + #_PT_R1312) = R13:12; \                
 51  { memd(R0 + #_PT_R1110) = R11:10; \              
 52    R15 = lc0; } \                                 
 53  { memd(R0 + #_PT_R0908) = R9:8; \                
 54    R14 = sa0; } \                                 
 55  { memd(R0 + #_PT_R0706) = R7:6; \                
 56    R13 = lc1; } \                                 
 57  { memd(R0 + #_PT_R0504) = R5:4; \                
 58    R12 = sa1; } \                                 
 59  { memd(R0 + #_PT_GPUGP) = R31:30; \              
 60    R11 = m1; \                                    
 61    R2.H = #HI(_THREAD_SIZE); } \                  
 62  { memd(R0 + #_PT_LC0SA0) = R15:14; \             
 63    R10 = m0; \                                    
 64    R2.L = #LO(_THREAD_SIZE); } \                  
 65  { memd(R0 + #_PT_LC1SA1) = R13:12; \             
 66    R15 = p3:0; \                                  
 67    R2 = neg(R2); } \                              
 68  { memd(R0 + #_PT_M1M0) = R11:10; \               
 69    R14  = usr; \                                  
 70    R2 = and(R0,R2); } \                           
 71  { memd(R0 + #_PT_PREDSUSR) =  R15:14; \          
 72    THREADINFO_REG = R2; } \                       
 73  { r24 = memw(THREADINFO_REG + #_THREAD_INFO_P    
 74    memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS    
 75    R2 = #-1; } \                                  
 76  { memw(R0 + #_PT_SYSCALL_NR) = R2; \             
 77    R30 = #0; }                                    
 78 #else                                             
 79 /* V4+ */                                         
 80 /* the # ## # syntax inserts a literal ## */      
 81 #define save_pt_regs()\                           
 82         { memd(R0 + #_PT_R3130) = R31:30; \       
 83                 R30 = memw(R0 + #_PT_ER_VMPSP)    
 84         { memw(R0 + #_PT_R2928) = R28; \          
 85                 memw(R0 + #(_PT_R2928 + 4)) =     
 86         { R31:30 = C11:10; \                      
 87                 memd(R0 + #_PT_R2726) = R27:26    
 88                 memd(R0 + #_PT_R2524) = R25:24    
 89         { memd(R0 + #_PT_R2322) = R23:22; \       
 90                 memd(R0 + #_PT_R2120) = R21:20    
 91         { memd(R0 + #_PT_R1918) = R19:18; \       
 92                 memd(R0 + #_PT_R1716) = R17:16    
 93         { memd(R0 + #_PT_R1514) = R15:14; \       
 94                 memd(R0 + #_PT_R1312) = R13:12    
 95                 R17:16 = C13:12; }\               
 96         { memd(R0 + #_PT_R1110) = R11:10; \       
 97                 memd(R0 + #_PT_R0908) = R9:8;     
 98           R15:14 = C1:0; } \                      
 99         { memd(R0 + #_PT_R0706) = R7:6; \         
100                 memd(R0 + #_PT_R0504) = R5:4;     
101     R13:12 = C3:2; } \                            
102         { memd(R0 + #_PT_GPUGP) = R31:30; \       
103                 memd(R0 + #_PT_LC0SA0) = R15:1    
104           R11:10 = C7:6; }\                       
105         {       THREADINFO_REG = and(R0, # ##     
106                 memd(R0 + #_PT_LC1SA1) = R13:1    
107           R15 = p3:0; }\                          
108         { memd(R0 + #_PT_M1M0) = R11:10; \        
109                 memw(R0 + #_PT_PREDSUSR + 4) =    
110         { r24 = memw(THREADINFO_REG + #_THREAD    
111           memw(THREADINFO_REG + #_THREAD_INFO_    
112           R2 = #-1; } \                           
113         { memw(R0 + #_PT_SYSCALL_NR) = R2; \      
114                 memd(R0 + #_PT_CS1CS0) = R17:1    
115           R30 = #0; }                             
116 #endif                                            
117                                                   
118 /*                                                
119  * Restore registers and thread_info.regs stat    
120  * is assumed to still be sane, and R24 to hav    
121  * preserved. Don't restore R29 (SP) until lat    
122  */                                               
123                                                   
124 #if CONFIG_HEXAGON_ARCH_VERSION < 4               
125 #define restore_pt_regs() \                       
126         { memw(THREADINFO_REG + #_THREAD_INFO_    
127           R15:14 = memd(R0 + #_PT_PREDSUSR); }    
128         { R11:10 = memd(R0 + #_PT_M1M0); \        
129           p3:0 = R15; } \                         
130         { R13:12 = memd(R0 + #_PT_LC1SA1); \      
131           usr = R14; } \                          
132         { R15:14 = memd(R0 + #_PT_LC0SA0); \      
133           m1 = R11; } \                           
134         { R3:2 = memd(R0 + #_PT_R0302); \         
135           m0 = R10; } \                           
136         { R5:4 = memd(R0 + #_PT_R0504); \         
137           lc1 = R13; } \                          
138         { R7:6 = memd(R0 + #_PT_R0706); \         
139           sa1 = R12; } \                          
140         { R9:8 = memd(R0 + #_PT_R0908); \         
141           lc0 = R15; } \                          
142         { R11:10 = memd(R0 + #_PT_R1110); \       
143           sa0 = R14; } \                          
144         { R13:12 = memd(R0 + #_PT_R1312); \       
145           R15:14 = memd(R0 + #_PT_R1514); } \     
146         { R17:16 = memd(R0 + #_PT_R1716); \       
147           R19:18 = memd(R0 + #_PT_R1918); } \     
148         { R21:20 = memd(R0 + #_PT_R2120); \       
149           R23:22 = memd(R0 + #_PT_R2322); } \     
150         { R25:24 = memd(R0 + #_PT_R2524); \       
151           R27:26 = memd(R0 + #_PT_R2726); } \     
152         R31:30 = memd(R0 + #_PT_GPUGP); \         
153         { R28 = memw(R0 + #_PT_R2928); \          
154           ugp = R31; } \                          
155         { R31:30 = memd(R0 + #_PT_R3130); \       
156           gp = R30; }                             
157 #else                                             
158 /* V4+ */                                         
159 #define restore_pt_regs() \                       
160         { memw(THREADINFO_REG + #_THREAD_INFO_    
161           R15:14 = memd(R0 + #_PT_PREDSUSR); }    
162         { R11:10 = memd(R0 + #_PT_M1M0); \        
163                 R13:12 = memd(R0 + #_PT_LC1SA1    
164                 p3:0 = R15; } \                   
165         { R15:14 = memd(R0 + #_PT_LC0SA0); \      
166                 R3:2 = memd(R0 + #_PT_R0302);     
167                 usr = R14; } \                    
168         { R5:4 = memd(R0 + #_PT_R0504); \         
169                 R7:6 = memd(R0 + #_PT_R0706);     
170                 C7:6 = R11:10; }\                 
171         { R9:8 = memd(R0 + #_PT_R0908); \         
172                 R11:10 = memd(R0 + #_PT_R1110)    
173     C3:2 = R13:12; }\                             
174         { R13:12 = memd(R0 + #_PT_R1312); \       
175           R15:14 = memd(R0 + #_PT_R1514); \       
176                 C1:0 = R15:14; }\                 
177         { R17:16 = memd(R0 + #_PT_R1716); \       
178           R19:18 = memd(R0 + #_PT_R1918); } \     
179         { R21:20 = memd(R0 + #_PT_R2120); \       
180           R23:22 = memd(R0 + #_PT_R2322); } \     
181         { R25:24 = memd(R0 + #_PT_R2524); \       
182           R27:26 = memd(R0 + #_PT_R2726); } \     
183         R31:30 = memd(R0 + #_PT_CS1CS0); \        
184         { C13:12 = R31:30; \                      
185                 R31:30 = memd(R0 + #_PT_GPUGP)    
186                 R28 = memw(R0 + #_PT_R2928); }    
187         { C11:10 = R31:30; \                      
188                 R31:30 = memd(R0 + #_PT_R3130)    
189 #endif                                            
190                                                   
191         /*                                        
192          * Clears off enough space for the res    
193          * of pt_regs in HVM mode.  Save R0/R1    
194          * R0 is the address of pt_regs and is    
195          */                                       
196                                                   
197 /*                                                
198  * Since the HVM isn't automagically pushing t    
199  * we'll subract the entire size out and then     
200  * Need to save off R0, R1, R2, R3 immediately    
201  */                                               
202                                                   
203 #if CONFIG_HEXAGON_ARCH_VERSION < 4               
204 #define vm_event_entry(CHandler) \                
205         { \                                       
206                 R29 = add(R29, #-(_PT_REGS_SIZ    
207                 memd(R29 + #(_PT_R0100 + -_PT_    
208         } \                                       
209         { \                                       
210                 memd(R29 +#_PT_R0302) = R3:2;     
211         } \                                       
212         trap1(#HVM_TRAP1_VMGETREGS); \            
213         { \                                       
214                 memd(R29 + #_PT_ER_VMEL) = R1:    
215                 R0 = R29; \                       
216                 R1.L = #LO(CHandler); \           
217         } \                                       
218         { \                                       
219                 memd(R29 + #_PT_ER_VMPSP) = R3    
220                 R1.H = #HI(CHandler); \           
221                 jump event_dispatch; \            
222         }                                         
223 #else                                             
224 /* V4+ */                                         
225 /* turn on I$ prefetch early */                   
226 /* the # ## # syntax inserts a literal ## */      
227 #define vm_event_entry(CHandler) \                
228         { \                                       
229                 R29 = add(R29, #-(_PT_REGS_SIZ    
230                 memd(R29 + #(_PT_R0100 + -_PT_    
231                 memd(R29 + #(_PT_R0302 + -_PT_    
232                 R0 = usr; \                       
233         } \                                       
234         { \                                       
235                 memw(R29 + #_PT_PREDSUSR) = R0    
236                 R0 = setbit(R0, #16); \           
237         } \                                       
238         usr = R0; \                               
239         R1:0 = G1:0; \                            
240         { \                                       
241                 memd(R29 + #_PT_ER_VMEL) = R1:    
242                 R1 = # ## #(CHandler); \          
243                 R3:2 = G3:2; \                    
244         } \                                       
245         { \                                       
246                 R0 = R29; \                       
247                 memd(R29 + #_PT_ER_VMPSP) = R3    
248                 jump event_dispatch; \            
249         }                                         
250 #endif                                            
251                                                   
252 .text                                             
253         /*                                        
254          * Do bulk save/restore in one place.     
255          * Adds a jump to dispatch latency, bu    
256          * saves hundreds of bytes.               
257          */                                       
258                                                   
259 event_dispatch:                                   
260         save_pt_regs()                            
261         callr   r1                                
262                                                   
263         /*                                        
264          * Coming back from the C-world, our t    
265          * should be in the designated registe    
266          *                                        
267          * If we were in kernel mode, we don't    
268          * or signals if CONFIG_PREEMPTION is     
269          * to jump to a need_resched kind of b    
270          * BTW, CONFIG_PREEMPTION is not suppo    
271          */                                       
272                                                   
273 #ifdef CONFIG_PREEMPTION                          
274         R0 = #VM_INT_DISABLE                      
275         trap1(#HVM_TRAP1_VMSETIE)                 
276 #endif                                            
277                                                   
278         /*  "Nested control path" -- if the pr    
279         {                                         
280                 R0 = memw(R29 + #_PT_ER_VMEST)    
281                 R26.L = #LO(do_work_pending);     
282         }                                         
283         {                                         
284                 P0 = tstbit(R0, #HVM_VMEST_UM_    
285                 if (!P0.new) jump:nt restore_a    
286                 R26.H = #HI(do_work_pending);     
287                 R0 = #VM_INT_DISABLE;             
288         }                                         
289                                                   
290         /*                                        
291          * Check also the return from fork/sys    
292          * user mode                              
293          *                                        
294          * R26 needs to have do_work_pending,     
295          */                                       
296                                                   
297 check_work_pending:                               
298         /*  Disable interrupts while checking     
299         trap1(#HVM_TRAP1_VMSETIE)                 
300         {                                         
301                 R0 = R29;  /*  regs should sti    
302                 R1 = memw(THREADINFO_REG + #_T    
303                 callr R26;                        
304         }                                         
305                                                   
306         {                                         
307                 P0 = cmp.eq(R0, #0); if (!P0.n    
308                 R0 = #VM_INT_DISABLE;             
309         }                                         
310                                                   
311 restore_all:                                      
312         /*                                        
313          * Disable interrupts, if they weren't    
314          * R0 gets preloaded with #VM_INT_DISA    
315          */                                       
316         trap1(#HVM_TRAP1_VMSETIE)                 
317                                                   
318         /*  do the setregs here for VM 0.5  */    
319         /*  R29 here should already be pointin    
320         {                                         
321                 R1:0 = memd(R29 + #_PT_ER_VMEL    
322                 R3:2 = memd(R29 + #_PT_ER_VMPS    
323         }                                         
324 #if CONFIG_HEXAGON_ARCH_VERSION < 4               
325         trap1(#HVM_TRAP1_VMSETREGS);              
326 #else                                             
327         G1:0 = R1:0;                              
328         G3:2 = R3:2;                              
329 #endif                                            
330                                                   
331         R0 = R29                                  
332         restore_pt_regs()                         
333         {                                         
334                 R1:0 = memd(R29 + #_PT_R0100);    
335                 R29 = add(R29, #_PT_REGS_SIZE)    
336         }                                         
337         trap1(#HVM_TRAP1_VMRTE)                   
338         /* Notreached */                          
339                                                   
340                                                   
341         .globl _K_enter_genex                     
342 _K_enter_genex:                                   
343         vm_event_entry(do_genex)                  
344                                                   
345         .globl _K_enter_interrupt                 
346 _K_enter_interrupt:                               
347         vm_event_entry(arch_do_IRQ)               
348                                                   
349         .globl _K_enter_trap0                     
350 _K_enter_trap0:                                   
351         vm_event_entry(do_trap0)                  
352                                                   
353         .globl _K_enter_machcheck                 
354 _K_enter_machcheck:                               
355         vm_event_entry(do_machcheck)              
356                                                   
357         .globl _K_enter_debug                     
358 _K_enter_debug:                                   
359         vm_event_entry(do_debug_exception)        
360                                                   
361         .globl ret_from_fork                      
362 ret_from_fork:                                    
363         {                                         
364                 call schedule_tail                
365                 R26.H = #HI(do_work_pending);     
366         }                                         
367         {                                         
368                 P0 = cmp.eq(R24, #0);             
369                 R26.L = #LO(do_work_pending);     
370                 R0 = #VM_INT_DISABLE;             
371         }                                         
372         if (P0) jump check_work_pending           
373         {                                         
374                 R0 = R25;                         
375                 callr R24                         
376         }                                         
377         {                                         
378                 jump check_work_pending           
379                 R0 = #VM_INT_DISABLE;             
380         }                                         
                                                      

~ [ 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