diff options
Diffstat (limited to 'usr/src/uts/intel/ml')
-rw-r--r-- | usr/src/uts/intel/ml/modstubs.s | 10 | ||||
-rw-r--r-- | usr/src/uts/intel/ml/swtch.s | 38 |
2 files changed, 44 insertions, 4 deletions
diff --git a/usr/src/uts/intel/ml/modstubs.s b/usr/src/uts/intel/ml/modstubs.s index bac97ef672..0994573bd7 100644 --- a/usr/src/uts/intel/ml/modstubs.s +++ b/usr/src/uts/intel/ml/modstubs.s @@ -46,7 +46,7 @@ * NOTE: Use NO_UNLOAD_STUBs if the module is NOT unloadable once it is * loaded. */ -#define MAXNARG 10 +#define MAXNARG 12 /* * WARNING: there is no check for forgetting to write END_MODULE, @@ -181,7 +181,7 @@ fcnname/**/_info: \ pushq %rcx pushq %r8 pushq %r9 - /* (next 4 args, if any, are already on the stack above %rbp) */ + /* (next 6 args, if any, are already on the stack above %rbp) */ movq %r15, %rdi call mod_hold_stub /* mod_hold_stub(mod_stub_info *) */ cmpl $-1, %eax /* error? */ @@ -192,7 +192,7 @@ fcnname/**/_info: \ jmp .L2 .L1: /* - * copy MAXNARG == 10 incoming arguments + * copy MAXNARG == 12 incoming arguments */ popq %r9 popq %r8 @@ -216,9 +216,11 @@ fcnname/**/_info: \ pushq (%rsp, %r11, 8) 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 */ + addq $0x30, %rsp /* pop off last 6 args */ pushq %rax /* save any return values */ pushq %rdx movq %r15, %rdi diff --git a/usr/src/uts/intel/ml/swtch.s b/usr/src/uts/intel/ml/swtch.s index c6c606b11e..55aaf4e122 100644 --- a/usr/src/uts/intel/ml/swtch.s +++ b/usr/src/uts/intel/ml/swtch.s @@ -507,3 +507,41 @@ resume_from_intr_return: call thread_exit /* destroy thread if it returns. */ /*NOTREACHED*/ SET_SIZE(thread_start) + + ENTRY(thread_splitstack_run) + pushq %rbp /* push base pointer */ + movq %rsp, %rbp /* construct frame */ + movq %rdi, %rsp /* set stack pinter */ + movq %rdx, %rdi /* load arg */ + INDIRECT_CALL_REG(rsi) /* call specified function */ + leave /* pop base pointer */ + ret + SET_SIZE(thread_splitstack_run) + + /* + * Once we're back on our own stack, we need to be sure to set the + * value of rsp0 in the TSS back to our original stack: if we gave + * up the CPU at all while on our split stack, the rsp0 will point + * to that stack from resume (above); if were to try to return to + * userland in that state, we will die absolutely horribly (namely, + * trying to iretq back to registers in a bunch of freed segkp). We + * are expecting this to be called after T_STACK has been restored, + * but before we return. It's okay if we are preempted in this code: + * when the new CPU picks us up, they will automatically set rsp0 + * correctly, which is all we're trying to do here. + */ + ENTRY(thread_splitstack_cleanup) + LOADCPU(%r8) + movq CPU_TSS(%r8), %r9 + cmpq $1, kpti_enable + jne 1f + leaq CPU_KPTI_TR_RSP(%r8), %rax + jmp 2f +1: + movq CPU_THREAD(%r8), %r10 + movq T_STACK(%r10), %rax + addq $REGSIZE+MINFRAME, %rax +2: + movq %rax, TSS_RSP0(%r9) + ret + SET_SIZE(thread_splitstack_cleanup) |