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>

*** 19,29 **** * CDDL HEADER END */ /* * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright (c) 2017, Joyent, Inc. All rights reserved. */ #include <sys/asm_linkage.h> #if defined(__lint) --- 19,29 ---- * CDDL HEADER END */ /* * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2019 Joyent, Inc. */ #include <sys/asm_linkage.h> #if defined(__lint)
*** 89,100 **** /* * This file contains the stubs routines for modules which can be autoloaded. */ - #if defined(__amd64) - /* * See the 'struct mod_modinfo' definition to see what this declaration * is trying to achieve here. */ #define MODULE(module,namespace) \ --- 89,98 ----
*** 128,138 **** leaq fcnname/**/_info(%rip), %rax; \ cmpl $0, MODS_FLAG(%rax); /* weak? */ \ je stubs_common_code; /* not weak */ \ testb $MODS_INSTALLED, MODS_FLAG(%rax); /* installed? */ \ jne stubs_common_code; /* yes, do the mod_hold */ \ ! jmp *MODS_RETFCN(%rax); /* no, jump to retfcn */ \ SET_SIZE(fcnname); \ .data; \ .align CPTRSIZE; \ .type fcnname/**/_info, @object; \ fcnname/**/_info: \ --- 126,137 ---- leaq fcnname/**/_info(%rip), %rax; \ cmpl $0, MODS_FLAG(%rax); /* weak? */ \ je stubs_common_code; /* not weak */ \ testb $MODS_INSTALLED, MODS_FLAG(%rax); /* installed? */ \ jne stubs_common_code; /* yes, do the mod_hold */ \ ! movq MODS_RETFCN(%rax), %rax; /* no, load retfcn */ \ ! INDIRECT_JMP_REG(rax); /* no, jump to retfcn */ \ SET_SIZE(fcnname); \ .data; \ .align CPTRSIZE; \ .type fcnname/**/_info, @object; \ fcnname/**/_info: \
*** 146,159 **** #define STUB_NO_UNLOADABLE(module, fcnname, install_fcn, retfcn, weak) \ ENTRY(fcnname); \ leaq fcnname/**/_info(%rip), %rax; \ testb $MODS_INSTALLED, MODS_FLAG(%rax); /* installed? */ \ je 5f; /* no */ \ ! jmp *(%rax); /* yes, jump to install_fcn */ \ 5: testb $MODS_WEAK, MODS_FLAG(%rax); /* weak? */ \ je stubs_common_code; /* no, do mod load */ \ ! jmp *MODS_RETFCN(%rax); /* yes, jump to retfcn */ \ SET_SIZE(fcnname); \ .data; \ .align CPTRSIZE; \ .type fcnname/**/_info, @object; \ fcnname/**/_info: \ --- 145,160 ---- #define STUB_NO_UNLOADABLE(module, fcnname, install_fcn, retfcn, weak) \ ENTRY(fcnname); \ leaq fcnname/**/_info(%rip), %rax; \ testb $MODS_INSTALLED, MODS_FLAG(%rax); /* installed? */ \ je 5f; /* no */ \ ! movq MODS_INSTFCN(%rax), %rax; /* yes, load install_fcn */ \ ! INDIRECT_JMP_REG(rax); /* yes, jump to install_fcn */ \ 5: testb $MODS_WEAK, MODS_FLAG(%rax); /* weak? */ \ je stubs_common_code; /* no, do mod load */ \ ! movq MODS_RETFCN(%rax), %rax; /* yes, load retfcn */ \ ! INDIRECT_JMP_REG(rax); /* yes, jump to retfcn */ \ SET_SIZE(fcnname); \ .data; \ .align CPTRSIZE; \ .type fcnname/**/_info, @object; \ fcnname/**/_info: \
*** 188,198 **** movq %r15, %rdi call mod_hold_stub /* mod_hold_stub(mod_stub_info *) */ cmpl $-1, %eax /* error? */ jne .L1 movq 0x18(%r15), %rax ! call *%rax addq $0x30, %rsp jmp .L2 .L1: /* * copy MAXNARG == 10 incoming arguments --- 189,199 ---- movq %r15, %rdi call mod_hold_stub /* mod_hold_stub(mod_stub_info *) */ cmpl $-1, %eax /* error? */ jne .L1 movq 0x18(%r15), %rax ! INDIRECT_CALL_REG(rax) addq $0x30, %rsp jmp .L2 .L1: /* * copy MAXNARG == 10 incoming arguments
*** 217,227 **** movl $MAXNARG - 6 + 3, %r11d pushq (%rsp, %r11, 8) pushq (%rsp, %r11, 8) pushq (%rsp, %r11, 8) pushq (%rsp, %r11, 8) ! call *(%r15) /* call the stub fn(arg, ..) */ addq $0x20, %rsp /* pop off last 4 args */ pushq %rax /* save any return values */ pushq %rdx movq %r15, %rdi call mod_release_stub /* release hold on module */ --- 218,229 ---- movl $MAXNARG - 6 + 3, %r11d pushq (%rsp, %r11, 8) pushq (%rsp, %r11, 8) pushq (%rsp, %r11, 8) pushq (%rsp, %r11, 8) ! movq (%r15), %rax ! INDIRECT_CALL_REG(rax) /* call the stub fn(arg, ..) */ addq $0x20, %rsp /* pop off last 4 args */ pushq %rax /* save any return values */ pushq %rdx movq %r15, %rdi call mod_release_stub /* release hold on module */
*** 231,368 **** popq %r15 leave ret SET_SIZE(stubs_common_code) - #elif defined(__i386) - - /* - * See the 'struct mod_modinfo' definition to see what this declaration - * is trying to achieve here. - */ - #define MODULE(module,namespace) \ - .data; \ - module/**/_modname: \ - .string "namespace/module"; \ - SET_SIZE(module/**/_modname); \ - .align CPTRSIZE; \ - .globl module/**/_modinfo; \ - .type module/**/_modinfo, @object; \ - module/**/_modinfo: \ - .long module/**/_modname; \ - .long 0 /* storage for modctl pointer */ - - /* then mod_stub_info structures follow until a mods_func_adr is 0 */ - - /* this puts a 0 where the next mods_func_adr would be */ - #define END_MODULE(module) \ - .data; \ - .align CPTRSIZE; \ - .long 0; \ - SET_SIZE(module/**/_modinfo) - - /* - * The data section in the stub_common macro is the - * mod_stub_info structure for the stub function - */ - - /* - * The flag MODS_INSTALLED is stored in the stub data and is used to - * indicate if a module is installed and initialized. This flag is used - * instead of the mod_stub_info->mods_modinfo->mod_installed flag - * to minimize the number of pointer de-references for each function - * call (and also to avoid possible TLB misses which could be induced - * by dereferencing these pointers.) - */ - - #define STUB_COMMON(module, fcnname, install_fcn, retfcn, weak) \ - ENTRY(fcnname); \ - leal fcnname/**/_info, %eax; \ - cmpl $0, MODS_FLAG(%eax); /* weak? */ \ - je stubs_common_code; /* not weak */ \ - testb $MODS_INSTALLED, MODS_FLAG(%eax); /* installed? */ \ - jne stubs_common_code; /* yes, do the mod_hold */ \ - jmp *MODS_RETFCN(%eax); /* no, just jump to retfcn */ \ - SET_SIZE(fcnname); \ - .data; \ - .align CPTRSIZE; \ - .type fcnname/**/_info, @object; \ - fcnname/**/_info: \ - .long install_fcn; \ - .long module/**/_modinfo; \ - .long fcnname; \ - .long retfcn; \ - .long weak; \ - SET_SIZE(fcnname/**/_info) - - #define STUB_NO_UNLOADABLE(module, fcnname, install_fcn, retfcn, weak) \ - ENTRY(fcnname); \ - leal fcnname/**/_info, %eax; \ - testb $MODS_INSTALLED, MODS_FLAG(%eax); /* installed? */ \ - je 5f; /* no */ \ - jmp *(%eax); /* yes, just jump to install_fcn */ \ - 5: testb $MODS_WEAK, MODS_FLAG(%eax); /* weak? */ \ - je stubs_common_code; /* no, do mod load */ \ - jmp *MODS_RETFCN(%eax); /* yes, just jump to retfcn */ \ - SET_SIZE(fcnname); \ - .data; \ - .align CPTRSIZE; \ - .type fcnname/**/_info, @object; \ - fcnname/**/_info: \ - .long install_fcn; /* 0 */ \ - .long module/**/_modinfo; /* 0x4 */ \ - .long fcnname; /* 0x8 */ \ - .long retfcn; /* 0xc */ \ - .long weak; /* 0x10 */ \ - SET_SIZE(fcnname/**/_info) - - /* - * We branch here with the fcnname_info pointer in %eax - */ - ENTRY_NP(stubs_common_code) - .globl mod_hold_stub - .globl mod_release_stub - pushl %esi - movl %eax, %esi / save the info pointer - pushl %eax - call mod_hold_stub / mod_hold_stub(mod_stub_info *) - popl %ecx - cmpl $-1, %eax / error? - jne .L1 - movl MODS_RETFCN(%esi), %eax - call *%eax - popl %esi / yes, return error (panic?) - ret - .L1: - movl $MAXNARG+1, %ecx - / copy incoming arguments - pushl (%esp, %ecx, 4) / push MAXNARG times - pushl (%esp, %ecx, 4) - pushl (%esp, %ecx, 4) - pushl (%esp, %ecx, 4) - pushl (%esp, %ecx, 4) - pushl (%esp, %ecx, 4) - pushl (%esp, %ecx, 4) - pushl (%esp, %ecx, 4) - pushl (%esp, %ecx, 4) - pushl (%esp, %ecx, 4) - call *(%esi) / call the stub function(arg1,arg2, ...) - add $_MUL(MAXNARG, 4), %esp / pop off MAXNARG arguments - pushl %eax / save any return values from the stub - pushl %edx - pushl %esi - call mod_release_stub / release hold on module - addl $4, %esp - popl %edx / restore return values - popl %eax - .L2: - popl %esi - ret - SET_SIZE(stubs_common_code) - - #endif /* __i386 */ - #define STUB(module, fcnname, retfcn) \ STUB_COMMON(module, fcnname, mod_hold_stub, retfcn, 0) /* * "weak stub", don't load on account of this call --- 233,242 ----
*** 1408,1421 **** */ #ifndef ELFEXEC_MODULE MODULE(elfexec,exec); STUB(elfexec, elfexec, nomod_einval); STUB(elfexec, mapexec_brand, nomod_einval); - #if defined(__amd64) STUB(elfexec, elf32exec, nomod_einval); STUB(elfexec, mapexec32_brand, nomod_einval); - #endif END_MODULE(elfexec); #endif /* * Stub(s) for APIX module. --- 1282,1293 ----
*** 1424,1434 **** MODULE(apix,mach); WSTUB(apix, apix_loaded, nomod_zero); END_MODULE(apix); #endif ! / this is just a marker for the area of text that contains stubs ENTRY_NP(stubs_end) nop #endif /* lint */ --- 1296,1308 ---- MODULE(apix,mach); WSTUB(apix, apix_loaded, nomod_zero); END_MODULE(apix); #endif ! /* ! * this is just a marker for the area of text that contains stubs ! */ ENTRY_NP(stubs_end) nop #endif /* lint */