1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2018 Joyent, Inc.
  14  */
  15 
  16 #include <sys/types.h>
  17 #include <sys/sysi86.h>
  18 #include <sys/segments.h>
  19 #include <sys/segment.h>
  20 #include <unistd.h>
  21 #include <string.h>
  22 #include <errno.h>
  23 #include <pthread.h>
  24 #include <err.h>
  25 
  26 char foo[4096];
  27 
  28 static void *
  29 donothing(void *nothing)
  30 {
  31         sleep(5);
  32         return (NULL);
  33 }
  34 
  35 int
  36 main(void)
  37 {
  38         pthread_t tid;
  39 
  40         /*
  41          * This first is similar to what sbcl does in some variants.  Note the
  42          * SDT_MEMRW (not SDT_MEMRWA) so we check that the kernel is forcing the
  43          * 'accessed' bit too.
  44          */
  45         int sel = SEL_LDT(7);
  46 
  47         struct ssd ssd = { sel, (unsigned long)&foo, 4096,
  48             SDT_MEMRW | (SEL_UPL << 5) | (1 << 7), 0x4 };
  49 
  50         if (sysi86(SI86DSCR, &ssd) < 0)
  51                 err(-1, "failed to setup segment");
  52 
  53         __asm__ __volatile__("mov %0, %%fs" : : "r" (sel));
  54 
  55         ssd.acc1 = 0;
  56 
  57         if (sysi86(SI86DSCR, &ssd) == 0)
  58                 errx(-1, "removed in-use segment?");
  59 
  60         __asm__ __volatile__("mov %0, %%fs" : : "r" (0));
  61 
  62         if (sysi86(SI86DSCR, &ssd) < 0)
  63                 err(-1, "failed to remove segment");
  64 
  65         for (int i = 0; i < MAXNLDT; i++) {
  66                 ssd.sel = SEL_LDT(i);
  67                 (void) sysi86(SI86DSCR, &ssd);
  68         }
  69 
  70         for (int i = 0; i < 10; i++)
  71                 pthread_create(&tid, NULL, donothing, NULL);
  72 
  73         if (forkall() == 0) {
  74                 sleep(2);
  75                 _exit(0);
  76         }
  77 
  78         sleep(6);
  79         return (0);
  80 }