From owner-svn-src-all@freebsd.org Wed Nov 20 11:12:20 2019 Return-Path: Delivered-To: svn-src-all@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 25CC01B3028; Wed, 20 Nov 2019 11:12:20 +0000 (UTC) (envelope-from kib@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) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47J0QW6pGbz4ff7; Wed, 20 Nov 2019 11:12:19 +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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id CCE1C21CE3; Wed, 20 Nov 2019 11:12:19 +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 xAKBCJCS091117; Wed, 20 Nov 2019 11:12:19 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xAKBCJQd091115; Wed, 20 Nov 2019 11:12:19 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201911201112.xAKBCJQd091115@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Wed, 20 Nov 2019 11:12:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r354889 - 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: 354889 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.29 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: Wed, 20 Nov 2019 11:12:20 -0000 Author: kib Date: Wed Nov 20 11:12:19 2019 New Revision: 354889 URL: https://svnweb.freebsd.org/changeset/base/354889 Log: amd64: in double fault handler, do not rely on sane gsbase value. Typical reasons for doublefault faults are either kernel stack overflow or bugs in the code that manipulates protection CPU state. The later code is the code which often has to set up gsbase for kernel. Switching to explicit load of GSBASE MSR in the fault handler makes it more probable to output a useful information. Now all IST handlers have nmi_pcpu structure on top of their stacks. It would be even more useful to save gsbase value at the moment of the fault. I did not this because I do not want to modify PCB layout now. Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Modified: head/sys/amd64/amd64/exception.S head/sys/amd64/amd64/machdep.c head/sys/amd64/amd64/mp_machdep.c Modified: head/sys/amd64/amd64/exception.S ============================================================================== --- head/sys/amd64/amd64/exception.S Wed Nov 20 10:27:43 2019 (r354888) +++ head/sys/amd64/amd64/exception.S Wed Nov 20 11:12:19 2019 (r354889) @@ -345,10 +345,11 @@ IDTVEC(dblfault) pushfq andq $~(PSL_D | PSL_AC),(%rsp) popfq - testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */ - jz 1f /* already running with kernel GS.base */ - swapgs -1: lfence + movq TF_SIZE(%rsp),%rdx + movl %edx,%eax + shrq $32,%rdx + movl $MSR_GSBASE,%ecx + wrmsr movq %cr3,%rax movq %rax,PCPU(SAVED_UCR3) movq PCPU(KCR3),%rax Modified: head/sys/amd64/amd64/machdep.c ============================================================================== --- head/sys/amd64/amd64/machdep.c Wed Nov 20 10:27:43 2019 (r354888) +++ head/sys/amd64/amd64/machdep.c Wed Nov 20 11:12:19 2019 (r354889) @@ -1575,7 +1575,9 @@ amd64_bsp_ist_init(struct pcpu *pc) tssp = &pc->pc_common_tss; /* doublefault stack space, runs on ist1 */ - tssp->tss_ist1 = (long)&dblfault_stack[sizeof(dblfault_stack)]; + np = ((struct nmi_pcpu *)&dblfault_stack[sizeof(dblfault_stack)]) - 1; + np->np_pcpu = (register_t)pc; + tssp->tss_ist1 = (long)np; /* * NMI stack, runs on ist2. The pcpu pointer is stored just Modified: head/sys/amd64/amd64/mp_machdep.c ============================================================================== --- head/sys/amd64/amd64/mp_machdep.c Wed Nov 20 10:27:43 2019 (r354888) +++ head/sys/amd64/amd64/mp_machdep.c Wed Nov 20 11:12:19 2019 (r354889) @@ -314,18 +314,24 @@ init_secondary(void) IOPERM_BITMAP_SIZE; pc->pc_common_tss.tss_rsp0 = 0; - pc->pc_common_tss.tss_ist1 = (long)&doublefault_stack[PAGE_SIZE]; + /* The doublefault stack runs on IST1. */ + np = ((struct nmi_pcpu *)&doublefault_stack[PAGE_SIZE]) - 1; + np->np_pcpu = (register_t)pc; + pc->pc_common_tss.tss_ist1 = (long)np; /* The NMI stack runs on IST2. */ np = ((struct nmi_pcpu *) &nmi_stack[PAGE_SIZE]) - 1; + np->np_pcpu = (register_t)pc; pc->pc_common_tss.tss_ist2 = (long)np; /* The MC# stack runs on IST3. */ np = ((struct nmi_pcpu *) &mce_stack[PAGE_SIZE]) - 1; + np->np_pcpu = (register_t)pc; pc->pc_common_tss.tss_ist3 = (long)np; /* The DB# stack runs on IST4. */ np = ((struct nmi_pcpu *) &dbg_stack[PAGE_SIZE]) - 1; + np->np_pcpu = (register_t)pc; pc->pc_common_tss.tss_ist4 = (long)np; /* Prepare private GDT */ @@ -340,18 +346,6 @@ init_secondary(void) ap_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; ap_gdt.rd_base = (u_long)gdt; lgdt(&ap_gdt); /* does magic intra-segment return */ - - /* Save the per-cpu pointer for use by the NMI handler. */ - np = ((struct nmi_pcpu *) &nmi_stack[PAGE_SIZE]) - 1; - np->np_pcpu = (register_t)pc; - - /* Save the per-cpu pointer for use by the MC# handler. */ - np = ((struct nmi_pcpu *) &mce_stack[PAGE_SIZE]) - 1; - np->np_pcpu = (register_t)pc; - - /* Save the per-cpu pointer for use by the DB# handler. */ - np = ((struct nmi_pcpu *) &dbg_stack[PAGE_SIZE]) - 1; - np->np_pcpu = (register_t)pc; wrmsr(MSR_FSBASE, 0); /* User value */ wrmsr(MSR_GSBASE, (u_int64_t)pc);