Print this page
11787 Kernel needs to be built with retpolines
11788 Kernel needs to generally use RSB stuffing
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: John Levon <john.levon@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/i86pc/ml/syscall_asm_amd64.s
          +++ new/usr/src/uts/i86pc/ml/syscall_asm_amd64.s
↓ open down ↓ 191 lines elided ↑ open up ↑
 192  192          movq    T_LWP(%r15), %r15       /* load the lwp pointer         */ ;\
 193  193          pushq   %r15                    /* push the lwp pointer         */ ;\
 194  194          movq    LWP_PROCP(%r15), %r15   /* load the proc pointer        */ ;\
 195  195          movq    P_BRAND(%r15), %r15     /* load the brand pointer       */ ;\
 196  196          movq    B_MACHOPS(%r15), %r15   /* load the machops pointer     */ ;\
 197  197          movq    _CONST(_MUL(callback_id, CPTRSIZE))(%r15), %r15            ;\
 198  198          cmpq    $0, %r15                                                   ;\
 199  199          je      1f                                                         ;\
 200  200          movq    %r15, 16(%rsp)          /* save the callback pointer    */ ;\
 201  201          push_userland_ret               /* push the return address      */ ;\
 202      -        call    *24(%rsp)               /* call callback                */ ;\
      202 +        movq    24(%rsp), %r15          /* load callback pointer        */ ;\
      203 +        INDIRECT_CALL_REG(r15)          /* call callback                */ ;\
 203  204  1:      movq    %gs:CPU_RTMP_R15, %r15  /* restore %r15                 */ ;\
 204  205          movq    %gs:CPU_RTMP_RSP, %rsp  /* restore the stack pointer    */
 205  206  
 206  207  #define MSTATE_TRANSITION(from, to)             \
 207  208          movl    $from, %edi;                    \
 208  209          movl    $to, %esi;                      \
 209  210          call    syscall_mstate
 210  211  
 211  212  /*
 212  213   * Check to see if a simple (direct) return is possible i.e.
↓ open down ↓ 355 lines elided ↑ open up ↑
 568  569          movq    REGOFF_RDX(%rbp), %rdx
 569  570          movq    REGOFF_RCX(%rbp), %rcx
 570  571          movq    REGOFF_R8(%rbp), %r8
 571  572          movq    REGOFF_R9(%rbp), %r9
 572  573  
 573  574          cmpl    $NSYSCALL, %eax
 574  575          jae     _syscall_ill
 575  576          shll    $SYSENT_SIZE_SHIFT, %eax
 576  577          leaq    sysent(%rax), %rbx
 577  578  
 578      -        call    *SY_CALLC(%rbx)
      579 +        movq    SY_CALLC(%rbx), %rax
      580 +        INDIRECT_CALL_REG(rax)
 579  581  
 580  582          movq    %rax, %r12
 581  583          movq    %rdx, %r13
 582  584  
 583  585          /*
 584  586           * If the handler returns two ints, then we need to split the
 585  587           * 64-bit return value into two 32-bit values.
 586  588           */
 587  589          testw   $SE_32RVAL2, SY_FLAGS(%rbx)
 588  590          je      5f
↓ open down ↓ 55 lines elided ↑ open up ↑
 644  646          ASSERT_CR0TS_ZERO(%r11)
 645  647  
 646  648          /*
 647  649           * Unlike other cases, because we need to restore the user stack pointer
 648  650           * before exiting the kernel we must clear the microarch state before
 649  651           * getting here. This should be safe because it means that the only
 650  652           * values on the bus after this are based on the user's registers and
 651  653           * potentially the addresses where we stored them. Given the constraints
 652  654           * of sysret, that's how it has to be.
 653  655           */
 654      -        call    *x86_md_clear
      656 +        call    x86_md_clear
 655  657  
 656  658          /*
 657  659           * To get back to userland, we need the return %rip in %rcx and
 658  660           * the return %rfl in %r11d.  The sysretq instruction also arranges
 659  661           * to fix up %cs and %ss; everything else is our responsibility.
 660  662           */
 661  663          movq    REGOFF_RDI(%rsp), %rdi
 662  664          movq    REGOFF_RSI(%rsp), %rsi
 663  665          movq    REGOFF_RDX(%rsp), %rdx
 664  666          /* %rcx used to restore %rip value */
↓ open down ↓ 230 lines elided ↑ open up ↑
 895  897           */
 896  898  
 897  899          movq    %rax, %rbx
 898  900          movl    0(%rsp), %edi
 899  901          movl    8(%rsp), %esi
 900  902          movl    0x10(%rsp), %edx
 901  903          movl    0x18(%rsp), %ecx
 902  904          movl    0x20(%rsp), %r8d
 903  905          movl    0x28(%rsp), %r9d
 904  906  
 905      -        call    *SY_CALLC(%rbx)
      907 +        movq    SY_CALLC(%rbx), %rax
      908 +        INDIRECT_CALL_REG(rax)
 906  909  
 907  910          movq    %rbp, %rsp      /* pop the args */
 908  911  
 909  912          /*
 910  913           * amd64 syscall handlers -always- return a 64-bit value in %rax.
 911  914           * On the 32-bit kernel, they always return that value in %eax:%edx
 912  915           * as required by the 32-bit ABI.
 913  916           *
 914  917           * Simulate the same behaviour by unconditionally splitting the
 915  918           * return value in the same way.
↓ open down ↓ 26 lines elided ↑ open up ↑
 942  945          ASSERT_CR0TS_ZERO(%r11)
 943  946  
 944  947          /*
 945  948           * Unlike other cases, because we need to restore the user stack pointer
 946  949           * before exiting the kernel we must clear the microarch state before
 947  950           * getting here. This should be safe because it means that the only
 948  951           * values on the bus after this are based on the user's registers and
 949  952           * potentially the addresses where we stored them. Given the constraints
 950  953           * of sysret, that's how it has to be.
 951  954           */
 952      -        call    *x86_md_clear
      955 +        call    x86_md_clear
 953  956  
 954  957          /*
 955  958           * To get back to userland, we need to put the return %rip in %rcx and
 956  959           * the return %rfl in %r11d.  The sysret instruction also arranges
 957  960           * to fix up %cs and %ss; everything else is our responsibility.
 958  961           */
 959  962  
 960  963          movl    %r12d, %eax                     /* %eax: rval1 */
 961  964          movl    REGOFF_RBX(%rsp), %ebx
 962  965          /* %ecx used for return pointer */
↓ open down ↓ 219 lines elided ↑ open up ↑
1182 1185           * %rax contains the handler address.
1183 1186           */
1184 1187          movq    %rax, %rbx
1185 1188          movl    0(%rsp), %edi
1186 1189          movl    8(%rsp), %esi
1187 1190          movl    0x10(%rsp), %edx
1188 1191          movl    0x18(%rsp), %ecx
1189 1192          movl    0x20(%rsp), %r8d
1190 1193          movl    0x28(%rsp), %r9d
1191 1194  
1192      -        call    *SY_CALLC(%rbx)
     1195 +        movq    SY_CALLC(%rbx), %rax
     1196 +        INDIRECT_CALL_REG(rax)
1193 1197  
1194 1198          movq    %rbp, %rsp      /* pop the args */
1195 1199  
1196 1200          /*
1197 1201           * amd64 syscall handlers -always- return a 64-bit value in %rax.
1198 1202           * On the 32-bit kernel, the always return that value in %eax:%edx
1199 1203           * as required by the 32-bit ABI.
1200 1204           *
1201 1205           * Simulate the same behaviour by unconditionally splitting the
1202 1206           * return value in the same way.
↓ open down ↓ 47 lines elided ↑ open up ↑
1250 1254          movl    REGOFF_RBX(%rsp), %ebx
1251 1255          movl    REGOFF_RBP(%rsp), %ebp
1252 1256          movl    REGOFF_RSI(%rsp), %esi
1253 1257          movl    REGOFF_RDI(%rsp), %edi
1254 1258  
1255 1259          movl    REGOFF_RIP(%rsp), %edx  /* sysexit: %edx -> %eip */
1256 1260          pushq   REGOFF_RFL(%rsp)
1257 1261          popfq
1258 1262          movl    REGOFF_RSP(%rsp), %ecx  /* sysexit: %ecx -> %esp */
1259 1263          ALTENTRY(sys_sysenter_swapgs_sysexit)
1260      -        call    *x86_md_clear
     1264 +        call    x86_md_clear
1261 1265          jmp     tr_sysexit
1262 1266          SET_SIZE(sys_sysenter_swapgs_sysexit)
1263 1267          SET_SIZE(sys_sysenter)
1264 1268          SET_SIZE(_sys_sysenter_post_swapgs)
1265 1269          SET_SIZE(brand_sys_sysenter)
1266 1270  
1267 1271  #endif  /* __lint */
1268 1272  
1269 1273  /*
1270 1274   * This is the destination of the "int $T_SYSCALLINT" interrupt gate, used by
↓ open down ↓ 36 lines elided ↑ open up ↑
1307 1311          /*
1308 1312           * There should be no instructions between this label and SWAPGS/IRET
1309 1313           * or we could end up breaking branded zone support. See the usage of
1310 1314           * this label in lx_brand_int80_callback and sn1_brand_int91_callback
1311 1315           * for examples.
1312 1316           *
1313 1317           * We want to swapgs to maintain the invariant that all entries into
1314 1318           * tr_iret_user are done on the user gsbase.
1315 1319           */
1316 1320          ALTENTRY(sys_sysint_swapgs_iret)
1317      -        call    *x86_md_clear
     1321 +        call    x86_md_clear
1318 1322          SWAPGS
1319 1323          jmp     tr_iret_user
1320 1324          /*NOTREACHED*/
1321 1325          SET_SIZE(sys_sysint_swapgs_iret)
1322 1326          SET_SIZE(sys_syscall_int)
1323 1327          SET_SIZE(brand_sys_syscall_int)
1324 1328  
1325 1329  #endif  /* __lint */
1326 1330  
1327 1331  /*
↓ open down ↓ 93 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX