From owner-svn-src-all@freebsd.org Thu Oct 5 13:13:01 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 243E3E387D2; Thu, 5 Oct 2017 13:13:01 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::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 F230A7107E; Thu, 5 Oct 2017 13:13:00 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v95DCxqi061350; Thu, 5 Oct 2017 13:12:59 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v95DCxVm061349; Thu, 5 Oct 2017 13:12:59 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201710051312.v95DCxVm061349@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Thu, 5 Oct 2017 13:12:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r324315 - head/sys/amd64/amd64 X-SVN-Group: head X-SVN-Commit-Author: kib X-SVN-Commit-Paths: head/sys/amd64/amd64 X-SVN-Commit-Revision: 324315 X-SVN-Commit-Repository: base 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.23 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: Thu, 05 Oct 2017 13:13:01 -0000 Author: kib Date: Thu Oct 5 13:12:59 2017 New Revision: 324315 URL: https://svnweb.freebsd.org/changeset/base/324315 Log: Ensure that after sucessfull i386_set_ldt() call, other threads can use LDT segments immediately. If the i386_set_ldt() call created a first LDT descriptor (and consequently created the LDT) for our address space, LDTR is currently loaded only on the CPU executing the syscall. Other CPUs executing threads sharing the address space, would only load LDTR after context switch. Uncomment set_user_ldt_rv() and call it on all CPUs. Remove critical section inside set_user_ldt(), it is not needed in the context of call from smp_rendezvous(). Set md_ldt after md_ldt_sd is initialized using the same code sequence as in user_ldt_free(). Do the whole initialization in a critical section, to not race with the context switching while we set LDT. Discussed with: bde Sponsored by: The FreeBSD Foundation MFC after: 1 week Modified: head/sys/amd64/amd64/sys_machdep.c Modified: head/sys/amd64/amd64/sys_machdep.c ============================================================================== --- head/sys/amd64/amd64/sys_machdep.c Thu Oct 5 13:01:18 2017 (r324314) +++ head/sys/amd64/amd64/sys_machdep.c Thu Oct 5 13:12:59 2017 (r324315) @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -80,11 +81,6 @@ max_ldt_segment_init(void *arg __unused) } SYSINIT(maxldt, SI_SUB_VM_CONF, SI_ORDER_ANY, max_ldt_segment_init, NULL); -#ifdef notyet -#ifdef SMP -static void set_user_ldt_rv(struct vmspace *vmsp); -#endif -#endif static void user_ldt_derefl(struct proc_ldt *pldt); #ifndef _SYS_SYSPROTO_H_ @@ -430,14 +426,10 @@ static void set_user_ldt(struct mdproc *mdp) { - critical_enter(); *PCPU_GET(ldt) = mdp->md_ldt_sd; lldt(GSEL(GUSERLDT_SEL, SEL_KPL)); - critical_exit(); } -#ifdef notyet -#ifdef SMP static void set_user_ldt_rv(struct vmspace *vmsp) { @@ -449,8 +441,6 @@ set_user_ldt_rv(struct vmspace *vmsp) set_user_ldt(&td->td_proc->p_md); } -#endif -#endif struct proc_ldt * user_ldt_alloc(struct proc *p, int force) @@ -492,11 +482,13 @@ user_ldt_alloc(struct proc *p, int force) sizeof(struct user_segment_descriptor)); user_ldt_derefl(pldt); } + critical_enter(); ssdtosyssd(&sldt, &p->p_md.md_ldt_sd); - atomic_store_rel_ptr((volatile uintptr_t *)&mdp->md_ldt, - (uintptr_t)new_ldt); - if (p == curproc) - set_user_ldt(mdp); + atomic_thread_fence_rel(); + mdp->md_ldt = new_ldt; + critical_exit(); + smp_rendezvous(NULL, (void (*)(void *))set_user_ldt_rv, NULL, + p->p_vmspace); return (mdp->md_ldt); }