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

TOMOYO Linux Cross Reference
Linux/arch/x86/entry/entry_64_compat.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/x86/entry/entry_64_compat.S (Version linux-6.12-rc7) and /arch/i386/entry/entry_64_compat.S (Version linux-5.15.171)


  1 /* SPDX-License-Identifier: GPL-2.0 */            
  2 /*                                                
  3  * Compatibility mode system call entry point     
  4  *                                                
  5  * Copyright 2000-2002 Andi Kleen, SuSE Labs.     
  6  */                                               
  7 #include <asm/asm-offsets.h>                      
  8 #include <asm/current.h>                          
  9 #include <asm/errno.h>                            
 10 #include <asm/thread_info.h>                      
 11 #include <asm/segment.h>                          
 12 #include <asm/irqflags.h>                         
 13 #include <asm/asm.h>                              
 14 #include <asm/smap.h>                             
 15 #include <asm/nospec-branch.h>                    
 16 #include <linux/linkage.h>                        
 17 #include <linux/err.h>                            
 18                                                   
 19 #include "calling.h"                              
 20                                                   
 21         .section .entry.text, "ax"                
 22                                                   
 23 /*                                                
 24  * 32-bit SYSENTER entry.                         
 25  *                                                
 26  * 32-bit system calls through the vDSO's __ke    
 27  * on 64-bit kernels running on Intel CPUs.       
 28  *                                                
 29  * The SYSENTER instruction, in principle, sho    
 30  * vDSO.  In practice, a small number of Andro    
 31  * with a copy of Bionic that inlined a SYSENT    
 32  * never happened in any of Google's Bionic ve    
 33  * in a narrow range of Intel-provided version    
 34  *                                                
 35  * SYSENTER loads SS, RSP, CS, and RIP from pr    
 36  * IF and VM in RFLAGS are cleared (IOW: inter    
 37  * SYSENTER does not save anything on the stac    
 38  * and does not save old RIP (!!!), RSP, or RF    
 39  *                                                
 40  * Arguments:                                     
 41  * eax  system call number                        
 42  * ebx  arg1                                      
 43  * ecx  arg2                                      
 44  * edx  arg3                                      
 45  * esi  arg4                                      
 46  * edi  arg5                                      
 47  * ebp  user stack                                
 48  * 0(%ebp) arg6                                   
 49  */                                               
 50 SYM_CODE_START(entry_SYSENTER_compat)             
 51         UNWIND_HINT_ENTRY                         
 52         ENDBR                                     
 53         /* Interrupts are off on entry. */        
 54         swapgs                                    
 55                                                   
 56         pushq   %rax                              
 57         SWITCH_TO_KERNEL_CR3 scratch_reg=%rax     
 58         popq    %rax                              
 59                                                   
 60         movq    PER_CPU_VAR(pcpu_hot + X86_top    
 61                                                   
 62         /* Construct struct pt_regs on stack *    
 63         pushq   $__USER_DS              /* pt_    
 64         pushq   $0                      /* pt_    
 65                                                   
 66         /*                                        
 67          * Push flags.  This is nasty.  First,    
 68          * off, but we need pt_regs->flags to     
 69          * was set in usermode, it's still set    
 70          * through this code.  do_SYSENTER_32(    
 71          */                                       
 72         pushfq                          /* pt_    
 73         pushq   $__USER32_CS            /* pt_    
 74         pushq   $0                      /* pt_    
 75 SYM_INNER_LABEL(entry_SYSENTER_compat_after_hw    
 76                                                   
 77         /*                                        
 78          * User tracing code (ptrace or signal    
 79          * the saved RAX contains a 32-bit num    
 80          * syscall.  Just in case the high bit    
 81          * the syscall number.  (This could al    
 82          * with no ill effects.)                  
 83          */                                       
 84         movl    %eax, %eax                        
 85                                                   
 86         pushq   %rax                    /* pt_    
 87         PUSH_AND_CLEAR_REGS rax=$-ENOSYS          
 88         UNWIND_HINT_REGS                          
 89                                                   
 90         cld                                       
 91                                                   
 92         /*                                        
 93          * SYSENTER doesn't filter flags, so w    
 94          * ourselves.  To save a few cycles, w    
 95          * either was set instead of doing an     
 96          * This needs to happen before enablin    
 97          * we don't get preempted with NT set.    
 98          *                                        
 99          * If TF is set, we will single-step a    
100          * will ignore all the traps.  (Yes, t    
101          * single-stepping in general.  This a    
102          * a more complicated code to handle t    
103          * forces us to single-step through th    
104          *                                        
105          * NB.: .Lsysenter_fix_flags is a labe    
106          * out-of-line as an optimization: NT     
107          * majority of the cases and instead o    
108          * we're keeping that code behind a br    
109          * not-taken and therefore its instruc    
110          */                                       
111         testl   $X86_EFLAGS_NT|X86_EFLAGS_AC|X    
112         jnz     .Lsysenter_fix_flags              
113 .Lsysenter_flags_fixed:                           
114                                                   
115         /*                                        
116          * CPU bugs mitigations mechanisms can    
117          * should be invoked after making sure    
118          * single-step is ignored only for ins    
119          * entry_SYSENTER_compat function.        
120          */                                       
121         IBRS_ENTER                                
122         UNTRAIN_RET                               
123         CLEAR_BRANCH_HISTORY                      
124                                                   
125         movq    %rsp, %rdi                        
126         call    do_SYSENTER_32                    
127         jmp     sysret32_from_system_call         
128                                                   
129 .Lsysenter_fix_flags:                             
130         pushq   $X86_EFLAGS_FIXED                 
131         popfq                                     
132         jmp     .Lsysenter_flags_fixed            
133 SYM_INNER_LABEL(__end_entry_SYSENTER_compat, S    
134 SYM_CODE_END(entry_SYSENTER_compat)               
135                                                   
136 /*                                                
137  * 32-bit SYSCALL entry.                          
138  *                                                
139  * 32-bit system calls through the vDSO's __ke    
140  * on 64-bit kernels running on AMD CPUs.         
141  *                                                
142  * The SYSCALL instruction, in principle, shou    
143  * vDSO.  In practice, it appears that this re    
144  * As evidence:                                   
145  *                                                
146  *  - The calling convention for SYSCALL has c    
147  *    anyone noticing.                            
148  *                                                
149  *  - Prior to the in-kernel X86_BUG_SYSRET_SS    
150  *    user task that did SYSCALL without immed    
151  *    would randomly crash.                       
152  *                                                
153  *  - Most programmers do not directly target     
154  *    SYSCALL instruction does not exist on In    
155  *    CPUs, Linux disables the SYSCALL instruc    
156  *    because the SYSCALL instruction in legac    
157  *    opposed to compat mode) is sufficiently     
158  *    essentially unusable.                       
159  *                                                
160  * 32-bit SYSCALL saves RIP to RCX, clears RFL    
161  * RFLAGS to R11, then loads new SS, CS, and R    
162  * programmed MSRs.  RFLAGS gets masked by a v    
163  * (so CLD and CLAC are not needed).  SYSCALL     
164  * the stack and does not change RSP.             
165  *                                                
166  * Note: RFLAGS saving+masking-with-MSR happen    
167  * (in legacy 32-bit mode, IF, RF and VM bits     
168  * Don't get confused: RFLAGS saving+masking d    
169  * (EFER.LMA=1), NOT on bitness of userspace w    
170  * or target CS descriptor's L bit (SYSCALL do    
171  *                                                
172  * Arguments:                                     
173  * eax  system call number                        
174  * ecx  return address                            
175  * ebx  arg1                                      
176  * ebp  arg2    (note: not saved in the stack     
177  * edx  arg3                                      
178  * esi  arg4                                      
179  * edi  arg5                                      
180  * esp  user stack                                
181  * 0(%esp) arg6                                   
182  */                                               
183 SYM_CODE_START(entry_SYSCALL_compat)              
184         UNWIND_HINT_ENTRY                         
185         ENDBR                                     
186         /* Interrupts are off on entry. */        
187         swapgs                                    
188                                                   
189         /* Stash user ESP */                      
190         movl    %esp, %r8d                        
191                                                   
192         /* Use %rsp as scratch reg. User ESP i    
193         SWITCH_TO_KERNEL_CR3 scratch_reg=%rsp     
194                                                   
195         /* Switch to the kernel stack */          
196         movq    PER_CPU_VAR(pcpu_hot + X86_top    
197                                                   
198 SYM_INNER_LABEL(entry_SYSCALL_compat_safe_stac    
199         ANNOTATE_NOENDBR                          
200                                                   
201         /* Construct struct pt_regs on stack *    
202         pushq   $__USER_DS              /* pt_    
203         pushq   %r8                     /* pt_    
204         pushq   %r11                    /* pt_    
205         pushq   $__USER32_CS            /* pt_    
206         pushq   %rcx                    /* pt_    
207 SYM_INNER_LABEL(entry_SYSCALL_compat_after_hwf    
208         movl    %eax, %eax              /* dis    
209         pushq   %rax                    /* pt_    
210         PUSH_AND_CLEAR_REGS rcx=%rbp rax=$-ENO    
211         UNWIND_HINT_REGS                          
212                                                   
213         IBRS_ENTER                                
214         UNTRAIN_RET                               
215         CLEAR_BRANCH_HISTORY                      
216                                                   
217         movq    %rsp, %rdi                        
218         call    do_fast_syscall_32                
219                                                   
220 sysret32_from_system_call:                        
221         /* XEN PV guests always use IRET path     
222         ALTERNATIVE "testb %al, %al; jz swapgs    
223                     "jmp swapgs_restore_regs_a    
224                                                   
225         /*                                        
226          * Opportunistic SYSRET                   
227          *                                        
228          * We are not going to return to users    
229          * stack. So let's erase the thread st    
230          */                                       
231         STACKLEAK_ERASE                           
232                                                   
233         IBRS_EXIT                                 
234                                                   
235         movq    RBX(%rsp), %rbx         /* pt_    
236         movq    RBP(%rsp), %rbp         /* pt_    
237         movq    EFLAGS(%rsp), %r11      /* pt_    
238         movq    RIP(%rsp), %rcx         /* pt_    
239         addq    $RAX, %rsp              /* Ski    
240         popq    %rax                    /* pt_    
241         popq    %rdx                    /* Ski    
242         popq    %rdx                    /* pt_    
243         popq    %rsi                    /* pt_    
244         popq    %rdi                    /* pt_    
245                                                   
246         /*                                        
247          * USERGS_SYSRET32 does:                  
248          *  GSBASE = user's GS base               
249          *  EIP = ECX                             
250          *  RFLAGS = R11                          
251          *  CS = __USER32_CS                      
252          *  SS = __USER_DS                        
253          *                                        
254          * ECX will not match pt_regs->cx, but    
255          * trampoline that will fix up RCX, so    
256          *                                        
257          * R12-R15 are callee-saved, so they c    
258          * when the system call started, which    
259          * code.  We zero R8-R10 to avoid info    
260          */                                       
261         movq    RSP-ORIG_RAX(%rsp), %rsp          
262 SYM_INNER_LABEL(entry_SYSRETL_compat_unsafe_st    
263         ANNOTATE_NOENDBR                          
264                                                   
265         /*                                        
266          * The original userspace %rsp (RSP-OR    
267          * on the process stack which is not m    
268          * not readable after we SWITCH_TO_USE    
269          * switch until after after the last r    
270          * stack.                                 
271          *                                        
272          * %r8/%r9 are zeroed before the sysre    
273          */                                       
274         SWITCH_TO_USER_CR3_NOSTACK scratch_reg    
275                                                   
276         xorl    %r8d, %r8d                        
277         xorl    %r9d, %r9d                        
278         xorl    %r10d, %r10d                      
279         swapgs                                    
280         CLEAR_CPU_BUFFERS                         
281         sysretl                                   
282 SYM_INNER_LABEL(entry_SYSRETL_compat_end, SYM_    
283         ANNOTATE_NOENDBR                          
284         int3                                      
285 SYM_CODE_END(entry_SYSCALL_compat)                
286                                                   
287 /*                                                
288  * int 0x80 is used by 32 bit mode as a system    
289  * point to C routines, however since this is     
290  * history needs to be scrubbed to protect aga    
291  * scrubbing needs to take place in assembly c    
292  * routines.                                      
293  */                                               
294 SYM_CODE_START(int80_emulation)                   
295         ANNOTATE_NOENDBR                          
296         UNWIND_HINT_FUNC                          
297         CLEAR_BRANCH_HISTORY                      
298         jmp do_int80_emulation                    
299 SYM_CODE_END(int80_emulation)                     
                                                      

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