From owner-dev-commits-src-main@freebsd.org Thu Jul 29 14:49:14 2021 Return-Path: Delivered-To: dev-commits-src-main@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 98622675477; Thu, 29 Jul 2021 14:49:14 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4GbD220zclz4md3; Thu, 29 Jul 2021 14:49:14 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id EFDA313C2F; Thu, 29 Jul 2021 14:49:13 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 16TEnDN3055977; Thu, 29 Jul 2021 14:49:13 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 16TEnD5U055976; Thu, 29 Jul 2021 14:49:13 GMT (envelope-from git) Date: Thu, 29 Jul 2021 14:49:13 GMT Message-Id: <202107291449.16TEnD5U055976@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: 4b136ef259ce - main - amd64: Set GS.base before calling init_secondary() on APs MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 4b136ef259cefedc9b6404afc09138aeb8acbd91 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-main@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for the main branch of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Jul 2021 14:49:14 -0000 The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=4b136ef259cefedc9b6404afc09138aeb8acbd91 commit 4b136ef259cefedc9b6404afc09138aeb8acbd91 Author: Mark Johnston AuthorDate: 2021-07-29 14:22:37 +0000 Commit: Mark Johnston CommitDate: 2021-07-29 14:22:37 +0000 amd64: Set GS.base before calling init_secondary() on APs KMSAN instrumentation requires thread-local storage to track initialization state for function parameters and return values. This buffer is accessed as part of each function prologue. It is provided by the KMSAN runtime, which looks up a pointer in the current thread's structure. When KMSAN is configured, init_secondary() is instrumented, but this means that GS.base must be initialized first, otherwise the runtime cannot safely access curthread. Work around this by loading GS.base before calling init_secondary(), so that the runtime can at least check curthread == NULL and return a pointer to some dummy storage. Note that init_secondary() still must reload GS.base after calling lgdt(), which loads a selector into %gs, which in turn clears the base register. Reviewed by: kib MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D31336 --- sys/amd64/amd64/mp_machdep.c | 8 ++++---- sys/amd64/amd64/mpboot.S | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 86a5d78c8a8e..343589ae4c6a 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -103,6 +103,7 @@ static char *doublefault_stack; static char *mce_stack; static char *nmi_stack; static char *dbg_stack; +void *bootpcpu; extern u_int mptramp_la57; extern u_int mptramp_nx; @@ -197,10 +198,8 @@ init_secondary(void) /* Update microcode before doing anything else. */ ucode_load_ap(cpu); - /* Get per-cpu data and save */ - pc = &__pcpu[cpu]; - - /* prime data page for it to use */ + /* Initialize the PCPU area. */ + pc = bootpcpu; pcpu_init(pc, cpu, sizeof(struct pcpu)); dpcpu_init(dpcpu, cpu); pc->pc_apic_id = cpu_apic_ids[cpu]; @@ -431,6 +430,7 @@ start_all_aps(void) dpcpu = (void *)kmem_malloc_domainset(DOMAINSET_PREF(domain), DPCPU_SIZE, M_WAITOK | M_ZERO); + bootpcpu = &__pcpu[cpu]; bootSTK = (char *)bootstacks[cpu] + kstack_pages * PAGE_SIZE - 8; bootAP = cpu; diff --git a/sys/amd64/amd64/mpboot.S b/sys/amd64/amd64/mpboot.S index b6c599a2aff3..1b5657d3bef8 100644 --- a/sys/amd64/amd64/mpboot.S +++ b/sys/amd64/amd64/mpboot.S @@ -260,4 +260,21 @@ bootMP_size: .p2align 4,0 entry_64: movq bootSTK, %rsp + + /* + * Initialize the segment register used for the PCPU area. The PCPU + * area will be initialized by init_secondary(), but it should be + * accessible before that to support sanitizer instrumentation which + * accesses per-CPU variables. + * + * Note that GS.base is loaded again in init_secondary(). This is not + * redundant: lgdt() loads a selector into %gs and this has the side + * effect of clearing GS.base. + */ + movl $MSR_GSBASE, %ecx + movq bootpcpu, %rax + movq %rax, %rdx + shrq $32, %rdx + wrmsr + jmp init_secondary