Print this page
11859 need swapgs mitigation
Reviewed by: Robert Mustacchi <rm@fingolfin.org>
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@fingolfin.org>


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2018 Joyent, Inc.
  24  */
  25 
  26 /*      Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
  27 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T   */
  28 /*      All Rights Reserved   */
  29 
  30 #include <sys/types.h>
  31 #include <sys/param.h>
  32 #include <sys/sysmacros.h>
  33 #include <sys/signal.h>
  34 #include <sys/systm.h>
  35 #include <sys/user.h>
  36 #include <sys/mman.h>
  37 #include <sys/class.h>
  38 #include <sys/proc.h>
  39 #include <sys/procfs.h>
  40 #include <sys/buf.h>
  41 #include <sys/kmem.h>
  42 #include <sys/cred.h>
  43 #include <sys/archsystm.h>


 534                 }
 535 
 536                 rp->r_gs = pcb->pcb_gs;
 537                 ASSERT((cpu_t *)kgsbase == CPU);
 538 
 539 #else   /* __xpv */
 540 
 541                 /*
 542                  * A little more complicated running native.
 543                  */
 544                 kgsbase = (ulong_t)CPU;
 545                 __set_gs(pcb->pcb_gs);
 546 
 547                 /*
 548                  * If __set_gs fails it's because the new %gs is a bad %gs,
 549                  * we'll be taking a trap but with the original %gs and %gsbase
 550                  * undamaged (i.e. pointing at curcpu).
 551                  *
 552                  * We've just mucked up the kernel's gsbase.  Oops.  In
 553                  * particular we can't take any traps at all.  Make the newly
 554                  * computed gsbase be the hidden gs via __swapgs, and fix
 555                  * the kernel's gsbase back again. Later, when we return to
 556                  * userland we'll swapgs again restoring gsbase just loaded
 557                  * above.
 558                  */
 559                 __swapgs();

 560                 rp->r_gs = pcb->pcb_gs;
 561 
 562                 /*
 563                  * restore kernel's gsbase


 564                  */
 565                 wrmsr(MSR_AMD_GSBASE, kgsbase);
 566 
 567 #endif  /* __xpv */
 568 
 569                 /*
 570                  * Only override the descriptor base address if
 571                  * r_gs == LWPGS_SEL or if r_gs == NULL. A note on
 572                  * NULL descriptors -- 32-bit programs take faults
 573                  * if they deference NULL descriptors; however,
 574                  * when 64-bit programs load them into %fs or %gs,
 575                  * they DONT fault -- only the base address remains
 576                  * whatever it was from the last load.   Urk.
 577                  *
 578                  * XXX - note that lwp_setprivate now sets %fs/%gs to the
 579                  * null selector for 64 bit processes. Whereas before
 580                  * %fs/%gs were set to LWP(FS|GS)_SEL regardless of
 581                  * the process's data model. For now we check for both
 582                  * values so that the kernel can also support the older
 583                  * libc. This should be ripped out at some point in the




   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2019 Joyent, Inc.
  24  */
  25 
  26 /*      Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
  27 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T   */
  28 /*      All Rights Reserved   */
  29 
  30 #include <sys/types.h>
  31 #include <sys/param.h>
  32 #include <sys/sysmacros.h>
  33 #include <sys/signal.h>
  34 #include <sys/systm.h>
  35 #include <sys/user.h>
  36 #include <sys/mman.h>
  37 #include <sys/class.h>
  38 #include <sys/proc.h>
  39 #include <sys/procfs.h>
  40 #include <sys/buf.h>
  41 #include <sys/kmem.h>
  42 #include <sys/cred.h>
  43 #include <sys/archsystm.h>


 534                 }
 535 
 536                 rp->r_gs = pcb->pcb_gs;
 537                 ASSERT((cpu_t *)kgsbase == CPU);
 538 
 539 #else   /* __xpv */
 540 
 541                 /*
 542                  * A little more complicated running native.
 543                  */
 544                 kgsbase = (ulong_t)CPU;
 545                 __set_gs(pcb->pcb_gs);
 546 
 547                 /*
 548                  * If __set_gs fails it's because the new %gs is a bad %gs,
 549                  * we'll be taking a trap but with the original %gs and %gsbase
 550                  * undamaged (i.e. pointing at curcpu).
 551                  *
 552                  * We've just mucked up the kernel's gsbase.  Oops.  In
 553                  * particular we can't take any traps at all.  Make the newly
 554                  * computed gsbase be the hidden gs via swapgs, and fix
 555                  * the kernel's gsbase back again. Later, when we return to
 556                  * userland we'll swapgs again restoring gsbase just loaded
 557                  * above.
 558                  */
 559                 __asm__ __volatile__("mfence; swapgs");
 560 
 561                 rp->r_gs = pcb->pcb_gs;
 562 
 563                 /*
 564                  * Restore kernel's gsbase. Note that this also serializes any
 565                  * attempted speculation from loading the user-controlled
 566                  * %gsbase.
 567                  */
 568                 wrmsr(MSR_AMD_GSBASE, kgsbase);
 569 
 570 #endif  /* __xpv */
 571 
 572                 /*
 573                  * Only override the descriptor base address if
 574                  * r_gs == LWPGS_SEL or if r_gs == NULL. A note on
 575                  * NULL descriptors -- 32-bit programs take faults
 576                  * if they deference NULL descriptors; however,
 577                  * when 64-bit programs load them into %fs or %gs,
 578                  * they DONT fault -- only the base address remains
 579                  * whatever it was from the last load.   Urk.
 580                  *
 581                  * XXX - note that lwp_setprivate now sets %fs/%gs to the
 582                  * null selector for 64 bit processes. Whereas before
 583                  * %fs/%gs were set to LWP(FS|GS)_SEL regardless of
 584                  * the process's data model. For now we check for both
 585                  * values so that the kernel can also support the older
 586                  * libc. This should be ripped out at some point in the