Print this page
OS-7125 Need mitigation of L1TF (CVE-2018-3646)
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/i86pc/io/apix/apix_intr.c
          +++ new/usr/src/uts/i86pc/io/apix/apix_intr.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright 2018 Western Digital Corporation.  All rights reserved.
       25 + * Copyright 2018 Joyent, Inc.
  25   26   */
  26   27  
  27   28  #include <sys/cpuvar.h>
  28   29  #include <sys/cpu_event.h>
  29   30  #include <sys/param.h>
  30   31  #include <sys/cmn_err.h>
  31   32  #include <sys/t_lock.h>
  32   33  #include <sys/kmem.h>
  33   34  #include <sys/machlock.h>
  34   35  #include <sys/systm.h>
↓ open down ↓ 26 lines elided ↑ open up ↑
  61   62  #include <sys/pci_intr_lib.h>
  62   63  #include <sys/spl.h>
  63   64  #include <sys/clock.h>
  64   65  #include <sys/dditypes.h>
  65   66  #include <sys/sunddi.h>
  66   67  #include <sys/x_call.h>
  67   68  #include <sys/reboot.h>
  68   69  #include <vm/hat_i86.h>
  69   70  #include <sys/stack.h>
  70   71  #include <sys/apix.h>
       72 +#include <sys/ht.h>
  71   73  
  72   74  static void apix_post_hardint(int);
  73   75  
  74   76  /*
  75   77   * Insert an vector into the tail of the interrupt pending list
  76   78   */
  77   79  static __inline__ void
  78   80  apix_insert_pending_av(apix_impl_t *apixp, struct autovec *avp, int ipl)
  79   81  {
  80   82          struct autovec **head = apixp->x_intr_head;
↓ open down ↓ 192 lines elided ↑ open up ↑
 273  275           * Set the new thread as the current one.
 274  276           * Set interrupted thread's T_SP because if it is the idle thread,
 275  277           * resume() may use that stack between threads.
 276  278           */
 277  279  
 278  280          ASSERT(SA((uintptr_t)stackptr) == (uintptr_t)stackptr);
 279  281          t->t_sp = (uintptr_t)stackptr;
 280  282  
 281  283          it->t_intr = t;
 282  284          cpu->cpu_thread = it;
      285 +        ht_begin_intr(pil);
 283  286  
 284  287          /*
 285  288           * Set bit for this pil in CPU's interrupt active bitmask.
 286  289           */
 287  290          ASSERT((cpu->cpu_intr_actv & (1 << pil)) == 0);
 288  291          cpu->cpu_intr_actv |= (1 << pil);
 289  292  
 290  293          /*
 291  294           * Initialize thread priority level from intr_pri
 292  295           */
↓ open down ↓ 50 lines elided ↑ open up ↑
 343  346                  cpu->cpu_intr_thread = it;
 344  347                  (void) splhigh();
 345  348                  sti();
 346  349                  swtch();
 347  350                  /*NOTREACHED*/
 348  351                  panic("dosoftint_epilog: swtch returned");
 349  352          }
 350  353          it->t_link = cpu->cpu_intr_thread;
 351  354          cpu->cpu_intr_thread = it;
 352  355          it->t_state = TS_FREE;
      356 +        ht_end_intr();
 353  357          cpu->cpu_thread = t;
      358 +
 354  359          if (t->t_flag & T_INTR_THREAD)
 355  360                  t->t_intr_start = now;
 356  361          basespl = cpu->cpu_base_spl;
 357  362          pil = MAX(oldpil, basespl);
 358  363          mcpu->mcpu_pri = pil;
 359  364  }
 360  365  
 361  366  /*
 362  367   * Dispatch a soft interrupt
 363  368   */
↓ open down ↓ 95 lines elided ↑ open up ↑
 459  464                   * is non-zero.
 460  465                   */
 461  466                  if ((t->t_flag & T_INTR_THREAD) != 0 && t->t_intr_start != 0) {
 462  467                          intrtime = now - t->t_intr_start;
 463  468                          mcpu->intrstat[t->t_pil][0] += intrtime;
 464  469                          cpu->cpu_intracct[cpu->cpu_mstate] += intrtime;
 465  470                          t->t_intr_start = 0;
 466  471                  }
 467  472          }
 468  473  
      474 +        ht_begin_intr(pil);
      475 +
 469  476          /* store starting timestamp in CPu structure for this IPL */
 470  477          mcpu->pil_high_start[pil - (LOCK_LEVEL + 1)] = now;
 471  478  
 472  479          if (pil == 15) {
 473  480                  /*
 474  481                   * To support reentrant level 15 interrupts, we maintain a
 475  482                   * recursion count in the top half of cpu_intr_actv.  Only
 476  483                   * when this count hits zero do we clear the PIL 15 bit from
 477  484                   * the lower half of cpu_intr_actv.
 478  485                   */
↓ open down ↓ 70 lines elided ↑ open up ↑
 549  556                   * Check to see if there is a low-level interrupt active.
 550  557                   * If so, place a starting timestamp in the thread
 551  558                   * structure.
 552  559                   */
 553  560                  kthread_t *t = cpu->cpu_thread;
 554  561  
 555  562                  if (t->t_flag & T_INTR_THREAD)
 556  563                          t->t_intr_start = now;
 557  564          }
 558  565  
      566 +        ht_end_intr();
      567 +
 559  568          mcpu->mcpu_pri = oldpil;
 560  569          if (pil < CBE_HIGH_PIL)
 561  570                  (void) (*setlvlx)(oldpil, 0);
 562  571  
 563  572          return (mask);
 564  573  }
 565  574  
 566  575  /*
 567  576   * Dispatch a hilevel interrupt (one above LOCK_LEVEL)
 568  577   */
↓ open down ↓ 92 lines elided ↑ open up ↑
 661  670          it->t_lwp = t->t_lwp;
 662  671  
 663  672          /*
 664  673           * (threads on the interrupt thread free list could have state
 665  674           * preset to TS_ONPROC, but it helps in debugging if
 666  675           * they're TS_FREE.)
 667  676           */
 668  677          it->t_state = TS_ONPROC;
 669  678  
 670  679          cpu->cpu_thread = it;
      680 +        ht_begin_intr(pil);
 671  681  
 672  682          /*
 673  683           * Initialize thread priority level from intr_pri
 674  684           */
 675  685          it->t_pil = (uchar_t)pil;
 676  686          it->t_pri = (pri_t)pil + intr_pri;
 677  687          it->t_intr_start = now;
 678  688  
 679  689          return (it->t_stk);
 680  690  }
↓ open down ↓ 68 lines elided ↑ open up ↑
 749  759                  panic("dosoftint_epilog: swtch returned");
 750  760          }
 751  761  
 752  762          /*
 753  763           * Return interrupt thread to the pool
 754  764           */
 755  765          it->t_link = cpu->cpu_intr_thread;
 756  766          cpu->cpu_intr_thread = it;
 757  767          it->t_state = TS_FREE;
 758  768  
      769 +        ht_end_intr();
 759  770          cpu->cpu_thread = t;
      771 +
 760  772          if (t->t_flag & T_INTR_THREAD)
 761  773                  t->t_intr_start = now;
 762  774          basespl = cpu->cpu_base_spl;
 763  775          mcpu->mcpu_pri = MAX(oldpil, basespl);
 764  776          (*setlvlx)(mcpu->mcpu_pri, 0);
 765  777  }
 766  778  
 767  779  
 768  780  static void
 769  781  apix_dispatch_pending_hardint(uint_t oldpil, uint_t arg2)
↓ open down ↓ 229 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX