diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2014-10-17 20:08:47 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2014-10-17 20:08:58 +0000 |
commit | d541160f82299ea525edd5dd4c62ddd225c9c7fe (patch) | |
tree | 4db76c67de663ead7a216dedc14f0fe921ab48d9 | |
parent | c59757c47d4a1eb2cf2dd3b414b3cc5980868b1c (diff) | |
download | illumos-joyent-d541160f82299ea525edd5dd4c62ddd225c9c7fe.tar.gz |
OS-3433 lxbrand 64bit can take a signal with incorrect %fsbase
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/amd64/lx_handler.s | 17 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/amd64/offsets.in | 2 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/clone.c | 4 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/lx_brand.c | 9 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/lx_thunk_server.c | 7 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/signal.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/os/lx_brand.c | 193 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/os/lx_misc.c | 28 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/sys/lx_brand.h | 4 | ||||
-rw-r--r-- | usr/src/uts/intel/brand/lx/lx_brand_asm.s | 12 | ||||
-rw-r--r-- | usr/src/uts/intel/genassym/offsets.in | 2 |
11 files changed, 215 insertions, 65 deletions
diff --git a/usr/src/lib/brand/lx/lx_brand/amd64/lx_handler.s b/usr/src/lib/brand/lx/lx_brand/amd64/lx_handler.s index 7cf509da13..45625a83f2 100644 --- a/usr/src/lib/brand/lx/lx_brand/amd64/lx_handler.s +++ b/usr/src/lib/brand/lx/lx_brand/amd64/lx_handler.s @@ -171,8 +171,8 @@ lx_sigreturn_tolibc(uintptr_t sp) movq %rbp, LXR_RSP(%rsp) addq $144, LXR_RSP(%rsp) /* 128 byte red zone + 2 pointers */ - movq $0, LXR_GS(%rsp) - movw %gs, LXR_GS(%rsp) + movq $0, LXR_FS(%rsp) + movw %fs, LXR_FS(%rsp) movq %rdi, LXR_RDI(%rsp) movq %rsi, LXR_RSI(%rsp) movq %rbx, LXR_RBX(%rsp) @@ -232,7 +232,7 @@ lx_sigreturn_tolibc(uintptr_t sp) movq LXR_R13(%rsp), %r13 movq LXR_R14(%rsp), %r14 movq LXR_R15(%rsp), %r15 - movw LXR_GS(%rsp), %gs + /* XXX movw LXR_FS(%rsp), %fs */ /* addq $SIZEOF_LX_REGS_T, %rsp not needed due to next instr. */ @@ -343,6 +343,17 @@ lx_sigreturn_tolibc(uintptr_t sp) jmp *%r9 /* jmp to the Linux signal handler */ SET_SIZE(lx_sigdeliver) + ENTRY_NP(lx_fsbchk) + movq %fs:0, %rax + ret + SET_SIZE(lx_fsbchk) + + ENTRY_NP(lx_fschk) + xorq %rax, %rax + mov %fs, %rax + ret + SET_SIZE(lx_fsbchk) + /* * The libc routine that calls user signal handlers ends with a * setcontext, so we would never return here even if we used a call diff --git a/usr/src/lib/brand/lx/lx_brand/amd64/offsets.in b/usr/src/lib/brand/lx/lx_brand/amd64/offsets.in index 06712dbde9..b774986e24 100644 --- a/usr/src/lib/brand/lx/lx_brand/amd64/offsets.in +++ b/usr/src/lib/brand/lx/lx_brand/amd64/offsets.in @@ -14,7 +14,7 @@ #include <sys/lx_brand.h> lx_regs_t SIZEOF_LX_REGS_T - lxr_gs + lxr_fs lxr_rdi lxr_rsi lxr_rbp diff --git a/usr/src/lib/brand/lx/lx_brand/common/clone.c b/usr/src/lib/brand/lx/lx_brand/common/clone.c index fa205567a6..40415cd0e1 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/clone.c +++ b/usr/src/lib/brand/lx/lx_brand/common/clone.c @@ -108,7 +108,9 @@ struct clone_state { void *c_ptidp; struct lx_desc *c_ldtinfo; /* thread-specific segment */ void *c_ctidp; +#if defined(_ILP32) uintptr_t c_gs; /* Linux's %gs */ +#endif sigset_t c_sigmask; /* signal mask */ lx_affmask_t c_affmask; /* CPU affinity mask */ volatile int *c_clone_res; /* pid/error returned to cloner */ @@ -538,7 +540,9 @@ lx_clone(uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4, cs->c_ldtinfo = ldtinfo; cs->c_ctidp = ctidp; cs->c_clone_res = &clone_res; +#if defined(_ILP32) cs->c_gs = rp->lxr_gs; +#endif if (lx_sched_getaffinity(0, sizeof (cs->c_affmask), (uintptr_t)&cs->c_affmask) == -1) diff --git a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c index ffee3c9234..4300c3f9ee 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c +++ b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c @@ -229,6 +229,10 @@ static struct lx_sysent sysents[LX_NSYSCALLS + 1]; static uintptr_t stack_bottom; +#if defined(_LP64) +long lx_fsb; +long lx_fs; +#endif int lx_install = 0; /* install mode enabled if non-zero */ boolean_t lx_is_rpm = B_FALSE; int lx_rpm_delay = 1; @@ -500,6 +504,11 @@ lx_emulate(lx_regs_t *rp) #if defined(_LP64) syscall_num = rp->lxr_rax; + extern long lx_fsbchk(); + extern long lx_fschk(); + lx_fsb = lx_fsbchk(); + lx_fs = lx_fschk(); + (void) syscall(SYS_brand, B_TRUSS_POINT, lx_fsb, lx_fs, syscall_num); #else syscall_num = rp->lxr_eax; #endif diff --git a/usr/src/lib/brand/lx/lx_brand/common/lx_thunk_server.c b/usr/src/lib/brand/lx/lx_brand/common/lx_thunk_server.c index f85b19bfac..02bfe48e01 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/lx_thunk_server.c +++ b/usr/src/lib/brand/lx/lx_brand/common/lx_thunk_server.c @@ -379,14 +379,15 @@ lx_call(lx_handle_sym_t lx_ch, uintptr_t p1, uintptr_t p2, rp = lx_syscall_regs(); - lx_debug("lx_call: calling to Linux code at 0x%p", lx_ch); +#if defined(_ILP32) lx_debug("lx_call: loading Linux gs, rp = 0x%p, gs = 0x%p", rp, rp->lxr_gs); - -#if defined(_ILP32) lx_swap_gs(rp->lxr_gs, &cur_gs); #endif + + lx_debug("lx_call: calling to Linux code at 0x%p", lx_ch); ret = lx_funcp(p1, p2, p3, p4, p5, p6, p7, p8); + #if defined(_ILP32) lx_swap_gs(cur_gs, &rp->lxr_gs); #endif diff --git a/usr/src/lib/brand/lx/lx_brand/common/signal.c b/usr/src/lib/brand/lx/lx_brand/common/signal.c index 042b9e0227..e59bc26c9e 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/signal.c +++ b/usr/src/lib/brand/lx/lx_brand/common/signal.c @@ -1240,7 +1240,7 @@ lx_setcontext(const ucontext_t *ucp) extern int lx_traceflag; /* - * See we don't return via lx_emulate, issue a trace msg here if + * Since we don't return via lx_emulate, issue a trace msg here if * necessary. We know this is only called in the 64-bit rt_sigreturn * code path to the syscall number is 15. */ diff --git a/usr/src/uts/common/brand/lx/os/lx_brand.c b/usr/src/uts/common/brand/lx/os/lx_brand.c index 9713a89ea5..1581d5c3b3 100644 --- a/usr/src/uts/common/brand/lx/os/lx_brand.c +++ b/usr/src/uts/common/brand/lx/os/lx_brand.c @@ -526,39 +526,86 @@ lx_brand_systrace_disable(void) static void lx_psig_to_proc(proc_t *p, kthread_t *t, int sig) { - lx_lwp_data_t *lwpd = ttolxlwp(t); #if defined(__amd64) + lx_lwp_data_t *lwpd = ttolxlwp(t); klwp_t *lwp = ttolwp(t); + pcb_t *pcb; model_t datamodel; datamodel = lwp_getdatamodel(lwp); - if (datamodel == DATAMODEL_NATIVE) { - pcb_t *pcb = &lwp->lwp_pcb; + if (datamodel != DATAMODEL_NATIVE) + return; + + pcb = &lwp->lwp_pcb; - DTRACE_PROBE2(brand__lx__psig, - uintptr_t, rdmsr(MSR_AMD_FSBASE), - uintptr_t, lwpd->br_libc_syscall); +#ifdef DEBUG + /* + * Debug check to see if we have the correct fsbase. + */ + ulong_t curr_base = rdmsr(MSR_AMD_FSBASE); + + if (curr_base != 0) { + if (lwpd->br_ntv_syscall == 0 && lwpd->br_lx_fsbase != 0) { + /* should have Linux fsbase */ + if (lwpd->br_lx_fsbase != curr_base) { + DTRACE_PROBE2(brand__lx__psig__lx__fsb, + uintptr_t, lwpd->br_lx_fsbase, + uintptr_t, curr_base); + } - /* We "push" the current syscall mode flag on the "stack". */ - ASSERT(lwpd->br_libc_syscall == 0 || - lwpd->br_libc_syscall == 1); - lwpd->br_scms = (lwpd->br_scms << 1) | lwpd->br_libc_syscall; + if (lwpd->br_lx_fsbase != pcb->pcb_fsbase) { + DTRACE_PROBE2(brand__lx__psig__lx__pcb, + uintptr_t, lwpd->br_lx_fsbase, + uintptr_t, pcb->pcb_fsbase); + } - /* - * Make sure we have the native fsbase loaded. Also update pcb - * so that if we service an interrupt we will restore the - * correct fsbase in update_sregs(). Because of the amd64 guard - * and datamodel check, this obviously will only happen for the - * 64-bit user-land. - */ - if (lwpd->br_ntv_fsbase != 0) { - pcb->pcb_fsbase = lwpd->br_ntv_fsbase; - wrmsr(MSR_AMD_FSBASE, lwpd->br_ntv_fsbase); + } + + if (lwpd->br_ntv_syscall == 1 && lwpd->br_ntv_fsbase != 0) { + /* should have Illumos fsbase */ + if (lwpd->br_ntv_fsbase != curr_base) { + DTRACE_PROBE2(brand__lx__psig__ntv__fsb, + uintptr_t, lwpd->br_ntv_fsbase, + uintptr_t, curr_base); + } + + if (lwpd->br_ntv_fsbase != pcb->pcb_fsbase) { + DTRACE_PROBE2(brand__lx__psig__ntv__pcb, + uintptr_t, lwpd->br_ntv_fsbase, + uintptr_t, pcb->pcb_fsbase); + } } } #endif - lwpd->br_libc_syscall = 1; + /* We "push" the current syscall mode flag on the "stack". */ + ASSERT(lwpd->br_ntv_syscall == 0 || lwpd->br_ntv_syscall == 1); + lwpd->br_scms = (lwpd->br_scms << 1) | lwpd->br_ntv_syscall; + + if (lwpd->br_ntv_syscall == 0 && lwpd->br_ntv_fsbase != 0) { + /* + * We were executing in Linux code but now that we're handling + * a signal we have to make sure we have the native fsbase + * loaded. Also update pcb so that if we service an interrupt + * we will restore the correct fsbase in update_sregs(). + * Because of the amd64 guard and datamodel check, this + * obviously will only happen for the 64-bit user-land. + * + * There is a non-obvious side-effect here. Since the fsbase + * will now be the native value, when we bounce out to + * user-land the ucontext will capture the native value, even + * though we need to restore the Linux value when we return + * from the signal. This is handled by the B_SIGNAL_RETURN + * code in lx_brandsys(). + */ + pcb->pcb_fsbase = lwpd->br_ntv_fsbase; + wrmsr(MSR_AMD_FSBASE, lwpd->br_ntv_fsbase); + + /* Ensure that we go out via update_sregs */ + pcb->pcb_rupdate = 1; + } + lwpd->br_ntv_syscall = 1; +#endif } void @@ -611,6 +658,9 @@ lx_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2, int error; lx_brand_registration_t reg; lx_lwp_data_t *lwpd; +#if defined(__amd64) && defined(DEBUG) + ulong_t curr_base; +#endif /* * There is one operation that is suppored for non-branded @@ -685,7 +735,7 @@ lx_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2, * handling. */ lwpd = ttolxlwp(t); - lwpd->br_libc_syscall = 1; + lwpd->br_ntv_syscall = 1; lwpd->br_scms = 1; #endif @@ -753,10 +803,17 @@ lx_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2, /* * The B_TRUSS_POINT subcommand is used so that we can make a no-op * syscall for debugging purposes (dtracing) from within the user-level - * emulation. + * emulation. Enhanced in the lx brand to allow probing of fsbase. */ case B_TRUSS_POINT: + DTRACE_PROBE1(brand__lx__rd__fsbase, + uintptr_t, rdmsr(MSR_AMD_FSBASE)); +#if defined(__amd64) + lwpd = ttolxlwp(curthread); + *rval = lwpd->br_ntv_fsbase; +#else *rval = 0; +#endif return (0); case B_LPID_TO_SPAIR: @@ -922,8 +979,25 @@ lx_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2, } case B_CLR_NTV_SYSC_FLAG: +#if defined(__amd64) lwpd = ttolxlwp(curthread); - lwpd->br_libc_syscall = 0; + lwpd->br_ntv_syscall = 0; + +#ifdef DEBUG + /* + * Debug check to see if we have the native fsbase. We should + * since this syscall came from native code. + */ + curr_base = rdmsr(MSR_AMD_FSBASE); + + if (curr_base != 0 && lwpd->br_ntv_fsbase != 0 && + lwpd->br_ntv_fsbase != curr_base) { + DTRACE_PROBE2(brand__lx__clr__ntv__fsb, + uintptr_t, lwpd->br_ntv_fsbase, + uintptr_t, curr_base); + } +#endif + /* * If Linux fsbase has been set, restore it. The user-level * code only ever calls this in the 64-bit library. @@ -933,13 +1007,15 @@ lx_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2, * in the pcb so that if we service an interrupt we will restore * the correct fsbase in update_sregs(). */ -#if defined(__amd64) if (lwpd->br_lx_fsbase != 0) { klwp_t *lwp = ttolwp(t); pcb_t *pcb = &lwp->lwp_pcb; pcb->pcb_fsbase = lwpd->br_lx_fsbase; wrmsr(MSR_AMD_FSBASE, lwpd->br_lx_fsbase); + + /* Ensure that we go out via update_sregs */ + pcb->pcb_rupdate = 1; } #endif return (0); @@ -957,7 +1033,7 @@ lx_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2, */ lwpd = ttolxlwp(curthread); - lwpd->br_libc_syscall = lwpd->br_scms & 0x1; + lwpd->br_ntv_syscall = lwpd->br_scms & 0x1; /* "pop" this value from the "stack" */ lwpd->br_scms >>= 1; @@ -966,33 +1042,60 @@ lx_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2, * Debug check to see if we have the native fsbase. We should * since this syscall came from native code. */ - if (lwpd->br_ntv_fsbase != 0) { + curr_base = rdmsr(MSR_AMD_FSBASE); + + if (curr_base != 0 && lwpd->br_ntv_fsbase != 0) { klwp_t *lwp = ttolwp(t); pcb_t *pcb = &lwp->lwp_pcb; - if (lwpd->br_ntv_fsbase != rdmsr(MSR_AMD_FSBASE)) - cmn_err(CE_WARN, "Incorrect msr native fsbase " - "0x%lx 0x%lx", lwpd->br_ntv_fsbase, - rdmsr(MSR_AMD_FSBASE)); - if (lwpd->br_ntv_fsbase != pcb->pcb_fsbase) - cmn_err(CE_WARN, "Incorrect pcb native fsbase " - "0x%lx 0x%lx", lwpd->br_ntv_fsbase, - pcb->pcb_fsbase); + if (lwpd->br_ntv_fsbase != curr_base) { + DTRACE_PROBE2(brand__lx__sigret__ntv__fsb, + uintptr_t, lwpd->br_ntv_fsbase, + uintptr_t, curr_base); + } + if (lwpd->br_ntv_fsbase != pcb->pcb_fsbase) { + DTRACE_PROBE2(brand__lx__sigret__ntv__pcb, + uintptr_t, lwpd->br_ntv_fsbase, + uintptr_t, pcb->pcb_fsbase); + } } #endif /* - * If setting the mode to lx, make sure we load the lx fsbase. + * If setting the mode to lx, make sure we fix up the context + * so that we load the lx fsbase when we return to the Linux + * code. For the native case, the context already has the + * correct native fsbase so we don't need to do anything here. + * Note that setgregs updates the pcb and in update_sregs we + * wrmsr the correct fsbase when we return to user-level. + * getsetcontext -> restorecontext -> setgregs */ - if (lwpd->br_libc_syscall == 0) { - /* if Linux fsbase has been initialized, restore it */ - if (lwpd->br_lx_fsbase != 0) { - klwp_t *lwp = ttolwp(t); - pcb_t *pcb = &lwp->lwp_pcb; - - pcb->pcb_fsbase = lwpd->br_lx_fsbase; - wrmsr(MSR_AMD_FSBASE, lwpd->br_lx_fsbase); - } + if (lwpd->br_ntv_syscall == 0 && lwpd->br_lx_fsbase != 0 && + arg1 != NULL) { + /* + * Linux fsbase has been initialized, restore it. + * We have to copyin to modify since the user-level + * emulation doesn't have a copy of the lx fsbase or + * know that we are returning to Linux code. + */ + ucontext_t uc; + klwp_t *lwp = ttolwp(t); + pcb_t *pcb = &lwp->lwp_pcb; + + if (copyin((void *)arg1, &uc, sizeof (ucontext_t) - + sizeof (uc.uc_filler) - + sizeof (uc.uc_mcontext.fpregs))) + return (set_errno(EFAULT)); + + uc.uc_mcontext.gregs[REG_FSBASE] = lwpd->br_lx_fsbase; + + if (copyout(&uc, (void *)arg1, sizeof (ucontext_t) - + sizeof (uc.uc_filler) - + sizeof (uc.uc_mcontext.fpregs))) + return (set_errno(EFAULT)); + + /* Ensure that we go out via update_sregs */ + pcb->pcb_rupdate = 1; } #endif /* amd64 */ return (getsetcontext(SETCONTEXT, (void *)arg1)); diff --git a/usr/src/uts/common/brand/lx/os/lx_misc.c b/usr/src/uts/common/brand/lx/os/lx_misc.c index 58ba0b0ff8..66421722d6 100644 --- a/usr/src/uts/common/brand/lx/os/lx_misc.c +++ b/usr/src/uts/common/brand/lx/os/lx_misc.c @@ -41,6 +41,8 @@ #include <sys/cmn_err.h> #include <sys/siginfo.h> #include <sys/contract/process_impl.h> +#include <sys/x86_archext.h> +#include <sys/sdt.h> #include <lx_signum.h> #include <lx_syscall.h> #include <sys/proc.h> @@ -239,7 +241,7 @@ lx_initlwp(klwp_t *lwp) lwpd->br_clear_ctidp = NULL; lwpd->br_set_ctidp = NULL; lwpd->br_signal = 0; - lwpd->br_libc_syscall = 1; + lwpd->br_ntv_syscall = 1; lwpd->br_scms = 1; /* @@ -264,6 +266,30 @@ lx_initlwp(klwp_t *lwp) /* The child inherits the 2 fsbase values from the parent */ lwpd->br_lx_fsbase = plwpd->br_lx_fsbase; lwpd->br_ntv_fsbase = plwpd->br_ntv_fsbase; + +#if defined(__amd64) + pcb_t *pcb = &lwp->lwp_pcb; + DTRACE_PROBE2(brand__lx__initlwp, + uintptr_t, pcb->pcb_fsbase, + uintptr_t, rdmsr(MSR_AMD_FSBASE)); +#ifdef DEBUG + ulong_t curr_base = rdmsr(MSR_AMD_FSBASE); + + if (curr_base != 0 && lwpd->br_ntv_fsbase != 0 && + lwpd->br_ntv_fsbase != curr_base) { + DTRACE_PROBE2(brand__lx__initlwp__ntv__fsb, + uintptr_t, lwpd->br_lx_fsbase, + uintptr_t, curr_base); + } + + if (pcb->pcb_fsbase != 0 && lwpd->br_ntv_fsbase != 0 && + lwpd->br_ntv_fsbase != pcb->pcb_fsbase) { + DTRACE_PROBE2(brand__lx__initlwp__ntv__pcb, + uintptr_t, lwpd->br_ntv_fsbase, + uintptr_t, pcb->pcb_fsbase); + } +#endif +#endif } else { /* * Oddball case: the parent thread isn't a Linux process. diff --git a/usr/src/uts/common/brand/lx/sys/lx_brand.h b/usr/src/uts/common/brand/lx/sys/lx_brand.h index 7a05deae7a..9b61a9c0e0 100644 --- a/usr/src/uts/common/brand/lx/sys/lx_brand.h +++ b/usr/src/uts/common/brand/lx/sys/lx_brand.h @@ -159,7 +159,7 @@ typedef struct lx_brand_registration32 { #ifdef __amd64 typedef struct lx_regs { - long lxr_gs; + long lxr_fs; long lxr_rdi; long lxr_rsi; long lxr_rbp; @@ -271,7 +271,7 @@ typedef ulong_t lx_affmask_t[LX_AFF_ULONGS]; * lx-specific data in the klwp_t */ typedef struct lx_lwp_data { - uint_t br_libc_syscall; /* 1 = syscall from native libc */ + uint_t br_ntv_syscall; /* 1 = syscall from native libc */ uint_t br_lwp_flags; /* misc. flags */ klwp_t *br_lwp; /* back pointer to container lwp */ int br_signal; /* signal to send to parent when */ diff --git a/usr/src/uts/intel/brand/lx/lx_brand_asm.s b/usr/src/uts/intel/brand/lx/lx_brand_asm.s index 897f3891fc..568d462c2c 100644 --- a/usr/src/uts/intel/brand/lx/lx_brand_asm.s +++ b/usr/src/uts/intel/brand/lx/lx_brand_asm.s @@ -147,14 +147,14 @@ ENTRY(lx_brand_syscall_callback) /* check for native vs. Linux syscall */ GET_V(SP_REG, 0, V_LWP, %r15); /* get lwp pointer */ movq LWP_BRAND(%r15), %r15 /* grab lx lwp data pointer */ - movl BR_LIBC_SYSCALL(%r15), %r15d /* grab syscall src flag */ + movl BR_NTV_SYSCALL(%r15), %r15d /* grab syscall src flag */ cmp $1, %r15 /* check for native syscall */ je 2f /* is native, stay in kernel */ /* Linux syscall - subsequent emul. syscalls will use native mode */ GET_V(SP_REG, 0, V_LWP, %r15); /* get lwp pointer */ movq LWP_BRAND(%r15), %r15 /* grab lx lwp data pointer */ - movl $1, BR_LIBC_SYSCALL(%r15) /* set native syscall flag */ + movl $1, BR_NTV_SYSCALL(%r15) /* set native syscall flag */ /* check if we have to restore native fsbase */ GET_V(SP_REG, 0, V_LWP, %r15); /* get lwp pointer */ @@ -186,7 +186,7 @@ ENTRY(lx_brand_syscall_callback) movq BR_LX_FSBASE(%r15), %r15 /* grab Linux fsbase */ subq $24, %rsp /* make room for 3 regs */ - movq %rax, 0x0(%rsp) /* save regs used by wrmsr */ + movq %rax, 0x0(%rsp) /* save regs used by rdmsr */ movq %rcx, 0x8(%rsp) movq %rdx, 0x10(%rsp) @@ -199,11 +199,7 @@ ENTRY(lx_brand_syscall_callback) cmp %rax, %r15 /* check if is lx fsbase */ je 4f /* match, ok */ - movq %rsp, %rdx /* use rdx as temp sp */ - addq $24, %rdx /* fix it back up */ - GET_V(%rdx, 0, V_LWP, %r15); /* get lwp pointer */ - movq LWP_BRAND(%r15), %r15 /* grab lx lwp data pointer */ - movq %rax, BR_LX_FSBASE(%r15) /* save bad Linux fsbase */ + movq %rax, %rdi /* pass bad fsbase as arg0 */ movq $155, %rax /* fail! use pivot_root */ jmp 5f diff --git a/usr/src/uts/intel/genassym/offsets.in b/usr/src/uts/intel/genassym/offsets.in index 8b2ccb3411..59763c1b4b 100644 --- a/usr/src/uts/intel/genassym/offsets.in +++ b/usr/src/uts/intel/genassym/offsets.in @@ -44,6 +44,6 @@ lx_zone_data lxzd_max_syscall lx_lwp_data - br_libc_syscall + br_ntv_syscall br_lx_fsbase br_ntv_fsbase |