Print this page
10924 Need mitigation of L1TF (CVE-2018-3646)
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Peter Tribble <peter.tribble@gmail.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/i86pc/os/intr.c
          +++ new/usr/src/uts/i86pc/os/intr.c
↓ open down ↓ 458 lines elided ↑ open up ↑
 459  459  #include <sys/kstat.h>
 460  460  #include <sys/smp_impldefs.h>
 461  461  #include <sys/pool_pset.h>
 462  462  #include <sys/zone.h>
 463  463  #include <sys/bitmap.h>
 464  464  #include <sys/archsystm.h>
 465  465  #include <sys/machsystm.h>
 466  466  #include <sys/ontrap.h>
 467  467  #include <sys/x86_archext.h>
 468  468  #include <sys/promif.h>
      469 +#include <sys/ht.h>
 469  470  #include <vm/hat_i86.h>
 470  471  #if defined(__xpv)
 471  472  #include <sys/hypervisor.h>
 472  473  #endif
 473  474  
 474      -#if defined(__amd64) && !defined(__xpv)
 475      -/* If this fails, then the padding numbers in machcpuvar.h are wrong. */
 476      -CTASSERT((offsetof(cpu_t, cpu_m) + offsetof(struct machcpu, mcpu_pad)) <
 477      -    MMU_PAGESIZE);
 478      -CTASSERT((offsetof(cpu_t, cpu_m) + offsetof(struct machcpu, mcpu_kpti)) >=
 479      -    MMU_PAGESIZE);
 480      -CTASSERT((offsetof(cpu_t, cpu_m) + offsetof(struct machcpu, mcpu_kpti_dbg)) <
 481      -    2 * MMU_PAGESIZE);
 482      -CTASSERT((offsetof(cpu_t, cpu_m) + offsetof(struct machcpu, mcpu_pad2)) <
 483      -    2 * MMU_PAGESIZE);
      475 +/* If these fail, then the padding numbers in machcpuvar.h are wrong. */
      476 +#if !defined(__xpv)
      477 +#define MCOFF(member)   \
      478 +        (offsetof(cpu_t, cpu_m) + offsetof(struct machcpu, member))
      479 +CTASSERT(MCOFF(mcpu_pad) == MACHCPU_SIZE);
      480 +CTASSERT(MCOFF(mcpu_pad2) == MMU_PAGESIZE);
      481 +CTASSERT((MCOFF(mcpu_kpti) & 0xF) == 0);
 484  482  CTASSERT(((sizeof (struct kpti_frame)) & 0xF) == 0);
 485      -CTASSERT(((offsetof(cpu_t, cpu_m) +
 486      -    offsetof(struct machcpu, mcpu_kpti_dbg)) & 0xF) == 0);
 487  483  CTASSERT((offsetof(struct kpti_frame, kf_tr_rsp) & 0xF) == 0);
      484 +CTASSERT(MCOFF(mcpu_pad3) < 2 * MMU_PAGESIZE);
 488  485  #endif
 489  486  
 490  487  #if defined(__xpv) && defined(DEBUG)
 491  488  
 492  489  /*
 493  490   * This panic message is intended as an aid to interrupt debugging.
 494  491   *
 495  492   * The associated assertion tests the condition of enabling
 496  493   * events when events are already enabled.  The implication
 497  494   * being that whatever code the programmer thought was
↓ open down ↓ 95 lines elided ↑ open up ↑
 593  590                   * is non-zero.
 594  591                   */
 595  592                  if ((t->t_flag & T_INTR_THREAD) != 0 && t->t_intr_start != 0) {
 596  593                          intrtime = now - t->t_intr_start;
 597  594                          mcpu->intrstat[t->t_pil][0] += intrtime;
 598  595                          cpu->cpu_intracct[cpu->cpu_mstate] += intrtime;
 599  596                          t->t_intr_start = 0;
 600  597                  }
 601  598          }
 602  599  
      600 +        ht_begin_intr(pil);
      601 +
 603  602          /*
 604  603           * Store starting timestamp in CPU structure for this PIL.
 605  604           */
 606  605          mcpu->pil_high_start[pil - (LOCK_LEVEL + 1)] = now;
 607  606  
 608  607          ASSERT((cpu->cpu_intr_actv & (1 << pil)) == 0);
 609  608  
 610  609          if (pil == 15) {
 611  610                  /*
 612  611                   * To support reentrant level 15 interrupts, we maintain a
↓ open down ↓ 84 lines elided ↑ open up ↑
 697  696                   * Check to see if there is a low-level interrupt active.
 698  697                   * If so, place a starting timestamp in the thread
 699  698                   * structure.
 700  699                   */
 701  700                  kthread_t *t = cpu->cpu_thread;
 702  701  
 703  702                  if (t->t_flag & T_INTR_THREAD)
 704  703                          t->t_intr_start = now;
 705  704          }
 706  705  
      706 +        ht_end_intr();
      707 +
 707  708          mcpu->mcpu_pri = oldpil;
 708  709          (void) (*setlvlx)(oldpil, vecnum);
 709  710  
 710  711          return (cpu->cpu_intr_actv & CPU_INTR_ACTV_HIGH_LEVEL_MASK);
 711  712  }
 712  713  
 713  714  /*
 714  715   * Set up the cpu, thread and interrupt thread structures for
 715  716   * executing an interrupt thread.  The new stack pointer of the
 716  717   * interrupt thread (which *must* be switched to) is returned.
↓ open down ↓ 42 lines elided ↑ open up ↑
 759  760          it->t_lwp = t->t_lwp;
 760  761  
 761  762          /*
 762  763           * (threads on the interrupt thread free list could have state
 763  764           * preset to TS_ONPROC, but it helps in debugging if
 764  765           * they're TS_FREE.)
 765  766           */
 766  767          it->t_state = TS_ONPROC;
 767  768  
 768  769          cpu->cpu_thread = it;           /* new curthread on this cpu */
      770 +        ht_begin_intr(pil);
      771 +
 769  772          it->t_pil = (uchar_t)pil;
 770  773          it->t_pri = intr_pri + (pri_t)pil;
 771  774          it->t_intr_start = now;
 772  775  
 773  776          return (it->t_stk);
 774  777  }
 775  778  
 776  779  
 777  780  #ifdef DEBUG
 778  781  int intr_thread_cnt;
↓ open down ↓ 70 lines elided ↑ open up ↑
 849  852           */
 850  853          it->t_link = cpu->cpu_intr_thread;
 851  854          cpu->cpu_intr_thread = it;
 852  855          it->t_state = TS_FREE;
 853  856  
 854  857          basespl = cpu->cpu_base_spl;
 855  858          pil = MAX(oldpil, basespl);
 856  859          mcpu->mcpu_pri = pil;
 857  860          (*setlvlx)(pil, vec);
 858  861          t->t_intr_start = now;
      862 +        ht_end_intr();
 859  863          cpu->cpu_thread = t;
 860  864  }
 861  865  
 862  866  /*
 863  867   * intr_get_time() is a resource for interrupt handlers to determine how
 864  868   * much time has been spent handling the current interrupt. Such a function
 865  869   * is needed because higher level interrupts can arrive during the
 866  870   * processing of an interrupt.  intr_get_time() only returns time spent in the
 867  871   * current interrupt handler.
 868  872   *
↓ open down ↓ 167 lines elided ↑ open up ↑
1036 1040           * Set the new thread as the current one.
1037 1041           * Set interrupted thread's T_SP because if it is the idle thread,
1038 1042           * resume() may use that stack between threads.
1039 1043           */
1040 1044  
1041 1045          ASSERT(SA((uintptr_t)stackptr) == (uintptr_t)stackptr);
1042 1046          t->t_sp = (uintptr_t)stackptr;
1043 1047  
1044 1048          it->t_intr = t;
1045 1049          cpu->cpu_thread = it;
     1050 +        ht_begin_intr(pil);
1046 1051  
1047 1052          /*
1048 1053           * Set bit for this pil in CPU's interrupt active bitmask.
1049 1054           */
1050 1055          ASSERT((cpu->cpu_intr_actv & (1 << pil)) == 0);
1051 1056          cpu->cpu_intr_actv |= (1 << pil);
1052 1057  
1053 1058          /*
1054 1059           * Initialize thread priority level from intr_pri
1055 1060           */
↓ open down ↓ 40 lines elided ↑ open up ↑
1096 1101                  cpu->cpu_intr_thread = it;
1097 1102                  (void) splhigh();
1098 1103                  sti();
1099 1104                  swtch();
1100 1105                  /*NOTREACHED*/
1101 1106                  panic("dosoftint_epilog: swtch returned");
1102 1107          }
1103 1108          it->t_link = cpu->cpu_intr_thread;
1104 1109          cpu->cpu_intr_thread = it;
1105 1110          it->t_state = TS_FREE;
     1111 +        ht_end_intr();
1106 1112          cpu->cpu_thread = t;
     1113 +
1107 1114          if (t->t_flag & T_INTR_THREAD)
1108 1115                  t->t_intr_start = now;
1109 1116          basespl = cpu->cpu_base_spl;
1110 1117          pil = MAX(oldpil, basespl);
1111 1118          mcpu->mcpu_pri = pil;
1112 1119          (*setspl)(pil);
1113 1120  }
1114 1121  
1115 1122  
1116 1123  /*
↓ open down ↓ 561 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX