From owner-svn-src-all@FreeBSD.ORG Sat Jan 3 01:41:11 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 6FB30BF1; Sat, 3 Jan 2015 01:41:11 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5A1DD64088; Sat, 3 Jan 2015 01:41:11 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t031fBHJ085972; Sat, 3 Jan 2015 01:41:11 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t031fAnb085970; Sat, 3 Jan 2015 01:41:10 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201501030141.t031fAnb085970@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Sat, 3 Jan 2015 01:41:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r276601 - stable/10/sys/amd64/ia32 X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 03 Jan 2015 01:41:11 -0000 Author: kib Date: Sat Jan 3 01:41:10 2015 New Revision: 276601 URL: https://svnweb.freebsd.org/changeset/base/276601 Log: MFC r276322: Change the way the lcall $7,$0 is reflected to usermode. Instead of setting call gate, which must be 64 bit, put a code segment descriptor into ldt slot 0. Modified: stable/10/sys/amd64/ia32/ia32_sigtramp.S stable/10/sys/amd64/ia32/ia32_syscall.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/amd64/ia32/ia32_sigtramp.S ============================================================================== --- stable/10/sys/amd64/ia32/ia32_sigtramp.S Sat Jan 3 01:28:58 2015 (r276600) +++ stable/10/sys/amd64/ia32/ia32_sigtramp.S Sat Jan 3 01:41:10 2015 (r276601) @@ -86,34 +86,14 @@ ia32_osigcode: * executed, we would have a window where the ring 0 code is * executed with the wrong gsbase. * - * Instead, reflect the lcall $7,$0 back to ring 3 trampoline - * which sets up the frame for int $0x80. + * Instead, set LDT descriptor 0 as code segment, which reflects + * the lcall $7,$0 back to ring 3 trampoline. The trampoline sets up + * the frame for int $0x80. */ ALIGN_TEXT lcall_tramp: - .code64 - /* - * There, we are in 64bit mode and need to return to 32bit. - * First, convert call frame from 64 to 32 bit format. - */ - pushq %rax - movl 16(%rsp),%eax - movl %eax,20(%rsp) /* ret %cs */ - movl 8(%rsp),%eax - movl %eax,16(%rsp) /* ret %rip -> %eip */ - popq %rax - addq $8,%rsp - /* Now return to 32bit */ - pushq $0x33 /* _ucode32sel UPL */ - callq 1f -1: - addq $2f-1b,(%rsp) - lretq -2: - /* Back in 32bit mode */ - .code32 cmpl $SYS_vfork,%eax - je 4f + je 1f pushl %ebp movl %esp,%ebp pushl 0x24(%ebp) /* arg 6 */ @@ -122,21 +102,20 @@ lcall_tramp: pushl 0x18(%ebp) pushl 0x14(%ebp) pushl 0x10(%ebp) /* arg 1 */ - pushl 0xc(%ebp) /* gap */ + subl $4,%esp /* gap */ int $0x80 leavel -3: lretl -4: +1: /* * vfork handling is special and relies on the libc stub saving - * the return ip in %ecx. If vfork failed, then there is no - * child which can corrupt the frame created by call gate. + * the return ip in %ecx. Also, we assume that the call was done + * with ucode32 selector in %cs. */ int $0x80 - jb 3b - addl $8,%esp - jmpl *%ecx + movl $0x33,4(%esp) /* GUCODE32_SEL | SEL_UPL */ + movl %ecx,(%esp) + lretl #endif ALIGN_TEXT Modified: stable/10/sys/amd64/ia32/ia32_syscall.c ============================================================================== --- stable/10/sys/amd64/ia32/ia32_syscall.c Sat Jan 3 01:28:58 2015 (r276600) +++ stable/10/sys/amd64/ia32/ia32_syscall.c Sat Jan 3 01:41:10 2015 (r276601) @@ -223,39 +223,28 @@ int setup_lcall_gate(void) { struct i386_ldt_args uap; - struct user_segment_descriptor descs[2]; - struct gate_descriptor *ssd; + struct user_segment_descriptor desc; uint32_t lcall_addr; int error; bzero(&uap, sizeof(uap)); uap.start = 0; - uap.num = 2; - - /* - * This is the easiest way to cut the space for system - * descriptor in ldt. Manually adjust the descriptor type to - * the call gate later. - */ - bzero(&descs[0], sizeof(descs)); - descs[0].sd_type = SDT_SYSNULL; - descs[1].sd_type = SDT_SYSNULL; - error = amd64_set_ldt(curthread, &uap, descs); + uap.num = 1; + lcall_addr = curproc->p_sysent->sv_psstrings - sz_lcall_tramp; + bzero(&desc, sizeof(desc)); + desc.sd_type = SDT_MEMERA; + desc.sd_dpl = SEL_UPL; + desc.sd_p = 1; + desc.sd_def32 = 1; + desc.sd_gran = 1; + desc.sd_lolimit = 0xffff; + desc.sd_hilimit = 0xf; + desc.sd_lobase = lcall_addr; + desc.sd_hibase = lcall_addr >> 24; + error = amd64_set_ldt(curthread, &uap, &desc); if (error != 0) return (error); - lcall_addr = curproc->p_sysent->sv_psstrings - sz_lcall_tramp; - mtx_lock(&dt_lock); - ssd = (struct gate_descriptor *)(curproc->p_md.md_ldt->ldt_base); - bzero(ssd, sizeof(*ssd)); - ssd->gd_looffset = lcall_addr; - ssd->gd_hioffset = lcall_addr >> 16; - ssd->gd_selector = _ucodesel; - ssd->gd_type = SDT_SYSCGT; - ssd->gd_dpl = SEL_UPL; - ssd->gd_p = 1; - mtx_unlock(&dt_lock); - return (0); } #endif