summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2014-10-17 20:08:47 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2014-10-17 20:08:58 +0000
commitd541160f82299ea525edd5dd4c62ddd225c9c7fe (patch)
tree4db76c67de663ead7a216dedc14f0fe921ab48d9
parentc59757c47d4a1eb2cf2dd3b414b3cc5980868b1c (diff)
downloadillumos-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.s17
-rw-r--r--usr/src/lib/brand/lx/lx_brand/amd64/offsets.in2
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/clone.c4
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/lx_brand.c9
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/lx_thunk_server.c7
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/signal.c2
-rw-r--r--usr/src/uts/common/brand/lx/os/lx_brand.c193
-rw-r--r--usr/src/uts/common/brand/lx/os/lx_misc.c28
-rw-r--r--usr/src/uts/common/brand/lx/sys/lx_brand.h4
-rw-r--r--usr/src/uts/intel/brand/lx/lx_brand_asm.s12
-rw-r--r--usr/src/uts/intel/genassym/offsets.in2
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