提交 233d2d46 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

use the IST mechanism to avoid NMI-syscall/sysret race conditions

上级 c0c238fb
...@@ -286,6 +286,7 @@ void initpg(void); ...@@ -286,6 +286,7 @@ void initpg(void);
void initmp(void); void initmp(void);
void initlapic(void); void initlapic(void);
void inittls(void); void inittls(void);
void initnmi(void);
void inittrap(void); void inittrap(void);
void initseg(void); void initseg(void);
void initkalloc(u64 mbaddr); void initkalloc(u64 mbaddr);
......
...@@ -95,7 +95,7 @@ struct intdesc ...@@ -95,7 +95,7 @@ struct intdesc
{ {
u16 rip0; u16 rip0;
u16 cs; u16 cs;
u8 reserved0; u8 ist;
u8 bits; u8 bits;
u16 rip1; u16 rip1;
u32 rip2; u32 rip2;
......
...@@ -18,6 +18,7 @@ mpboot(void) ...@@ -18,6 +18,7 @@ mpboot(void)
inittls(); inittls();
initlapic(); initlapic();
initsamp(); initsamp();
initnmi();
bstate = 1; bstate = 1;
scheduler(); // start running processes scheduler(); // start running processes
} }
...@@ -94,6 +95,7 @@ cmain(u64 mbmagic, u64 mbaddr) ...@@ -94,6 +95,7 @@ cmain(u64 mbmagic, u64 mbaddr)
cprintf("ncpu %d %lu MHz\n", ncpu, cpuhz / 1000000); cprintf("ncpu %d %lu MHz\n", ncpu, cpuhz / 1000000);
inituser(); // first user process inituser(); // first user process
initnmi();
bootothers(); // start other processors bootothers(); // start other processors
kpml4.e[0] = 0; // don't need 1 GB identity mapping anymore kpml4.e[0] = 0; // don't need 1 GB identity mapping anymore
lcr3(rcr3()); lcr3(rcr3());
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "proc.hh" #include "proc.hh"
#include "kmtrace.hh" #include "kmtrace.hh"
#include "bits.hh" #include "bits.hh"
#include "kalloc.hh"
struct intdesc idt[256] __attribute__((aligned(16))); struct intdesc idt[256] __attribute__((aligned(16)));
...@@ -205,6 +206,16 @@ inittrap(void) ...@@ -205,6 +206,16 @@ inittrap(void)
} }
void void
initnmi(void)
{
void *nmistackbase = ksalloc(slab_stack);
mycpu()->ts.ist[1] = (u64) nmistackbase + KSTACKSIZE;
if (mycpu()->id == 0)
idt[T_NMI].ist = 1;
}
void
initseg(void) initseg(void)
{ {
volatile struct desctr dtr; volatile struct desctr dtr;
......
...@@ -11,12 +11,12 @@ ...@@ -11,12 +11,12 @@
#define MAXNAME 16 // max string names #define MAXNAME 16 // max string names
#define NEPOCH 4 #define NEPOCH 4
#define CACHELINE 64 // cache line size #define CACHELINE 64 // cache line size
#define CPUKSTACKS (NPROC + NCPU) #define CPUKSTACKS (NPROC + NCPU*2)
#define QUANTUM 10 // scheduling time quantum and tick length (in msec) #define QUANTUM 10 // scheduling time quantum and tick length (in msec)
#define CILKSHIFT 4 // 2^WORKSHIFT work queue slots #define CILKSHIFT 4 // 2^WORKSHIFT work queue slots
#define VICTIMAGE 1000000 // cycles a proc executes before an eligible victim #define VICTIMAGE 1000000 // cycles a proc executes before an eligible victim
#define VERBOSE 0 // print kernel diagnostics #define VERBOSE 0 // print kernel diagnostics
#define SPINLOCK_DEBUG 1 // Debug spin locks #define SPINLOCK_DEBUG 1 // Debug spin locks
#define RCU_TYPE_DEBUG 1 #define RCU_TYPE_DEBUG 1
#define LOCKSTAT 1 #define LOCKSTAT 1
#define VERIFYFREE 0 // Unreliable, e.g. vma's vmnode pointer gets reused #define VERIFYFREE 0 // Unreliable, e.g. vma's vmnode pointer gets reused
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论