/n/sources/plan9/sys/src/9/pc/fns.h:83,88 - pc/fns.h:83,89
void kbdinit(void);
#define kmapinval()
void lgdt(ushort[3]);
+ void lldt(ulong);
void lidt(ushort[3]);
void links(void);
void ltr(ulong);
/n/sources/plan9/sys/src/9/pc/fns.h:142,147 - pc/fns.h:143,149
void procrestore(Proc*);
void procsave(Proc*);
void procsetup(Proc*);
+ void procfork(Proc*);
void putcr0(ulong);
void putcr3(ulong);
void putcr4(ulong);
/n/sources/plan9/sys/src/9/pc/fns.h:166,172 - pc/fns.h:168,174
ulong upaalloc(int, int);
void upafree(ulong, int);
void upareserve(ulong, int);
- #define userureg(ur) (((ur)->cs & 0xFFFF) == UESEL)
+ #define userureg(ur) (((ur)->cs & 3) == 3)
void vectortable(void);
void* vmap(ulong, int);
int vmapsync(ulong);
/n/sources/plan9/sys/src/9/pc/dat.h:108,113 - pc/dat.h:108,119
int nuart; /* number of uart devices */
};
+ struct Segdesc
+ {
+ ulong d0;
+ ulong d1;
+ };
+
/*
* MMU stuff in proc
*/
/n/sources/plan9/sys/src/9/pc/dat.h:120,125 - pc/dat.h:126,136
Page* kmaptable; /* page table used by kmap */
uint lastkmap; /* last entry used by kmap */
int nkmap; /* number of current kmaps */
+
+ Segdesc *ldt; /* local descriptor table */
+ int nldt; /* number of ldt descriptors allocated */
+
+ Segdesc gdt[NPROCSEG]; /* per process descriptors */
};
/*
/n/sources/plan9/sys/src/9/pc/dat.h:162,173 - pc/dat.h:173,178
ulong ldt; /* selector for task's LDT */
ulong iomap; /* I/O map base address + T-bit */
} Tss;
-
- struct Segdesc
- {
- ulong d0;
- ulong d1;
- };
struct Mach
{
/n/sources/plan9/sys/src/9/pc/mem.h:84,91 - pc/mem.h:84,93
#define APMCSEG16 7 /* APM 16-bit code segment */
#define APMDSEG 8 /* APM data segment */
#define KESEG16 9 /* kernel executable 16-bit */
- #define NGDT 10 /* number of GDT entries required */
- /* #define APM40SEG 8 /* APM segment 0x40 */
+ #define LDTSEG 10 /* local descriptor table */
+ #define PROCSEG0 11 /* per process descriptor0 */
+ #define NPROCSEG 3 /* number of per process descriptors */
+ #define NGDT 14 /* number of GDT entries required */
#define SELGDT (0<<2) /* selector is in gdt */
#define SELLDT (1<<2) /* selector is in ldt */
/n/sources/plan9/sys/src/9/pc/mem.h:102,107 - pc/mem.h:104,110
#define APMCSEL16 SELECTOR(APMCSEG16, SELGDT, 0)
#define APMDSEL SELECTOR(APMDSEG, SELGDT, 0)
/* #define APM40SEL SELECTOR(APM40SEG, SELGDT, 0) */
+ #define LDTSEL SELECTOR(LDTSEG, SELGDT, 0)
/*
* fields in segment descriptors
/n/sources/plan9/sys/src/9/pc/mem.h:108,117 - pc/mem.h:111,121
*/
#define SEGDATA (0x10<<8) /* data/stack segment */
#define SEGEXEC (0x18<<8) /* executable segment */
- #define SEGTSS (0x9<<8) /* TSS segment */
+ #define SEGTSS (0x09<<8) /* TSS segment */
#define SEGCG (0x0C<<8) /* call gate */
#define SEGIG (0x0E<<8) /* interrupt gate */
#define SEGTG (0x0F<<8) /* trap gate */
+ #define SEGLDT (0x02<<8) /* local descriptor table */
#define SEGTYPE (0x1F<<8)
#define SEGP (1<<15) /* segment present */
/n/sources/plan9/sys/src/9/pc/io.h:10,15 - pc/io.h:10,17
VectorCNA = 7, /* coprocessor not available */
Vector2F = 8, /* double fault */
VectorCSO = 9, /* coprocessor segment overrun */
+ VectorSNP = 11, /* segment not present */
+ VectorGPF = 13, /* general protection fault */
VectorPF = 14, /* page fault */
Vector15 = 15, /* reserved */
VectorCERR = 16, /* coprocessor error */
/n/sources/plan9/sys/src/9/pc/trap.c:326,332 - pc/trap.c:326,332
}
m->perf.intrts = perfticks();
- user = (ureg->cs & 0xFFFF) == UESEL;
+ user = userureg(ureg);
if(user){
up->dbgreg = ureg;
cycles(&up->kentry);
/n/sources/plan9/sys/src/9/pc/trap.c:335,340 - pc/trap.c:335,341
clockintr = 0;
vno = ureg->trap;
+
if(ctl = vctl[vno]){
if(ctl->isintr){
m->intr++;
/n/sources/plan9/sys/src/9/pc/trap.c:424,429 - pc/trap.c:425,480
while(m->machno != 0)
;
}
+
+ /*
+ * general protection fault in kernel mode
+ * can be caused by loading invalid segments
+ * when returning to userspace. as the user
+ * can change the descriptors now we take
+ * it here to prevent the damage to the
+ * kernel. -cinap
+ */
+ if(vno == VectorGPF || vno == VectorSNP){
+ ulong *sp;
+ uchar *pc;
+
+ /* l.s */
+ extern void load_fs(ulong);
+ extern void load_gs(ulong);
+
+ /*
+ * CS, SS, DS and ES are initialized by strayintr
+ * in l.s. initialize the others too so we dont trap
+ * again when restoring the old context.
+ */
+ load_fs(NULLSEL);
+ load_gs(NULLSEL);
+
+ pc = (uchar*)ureg->pc;
+ sp = (ulong*)&ureg->sp;
+
+ /*
+ * we test for the instructions used by forkret()
+ * to load the segments. this needs to be changed
+ * if forkret changes!
+ */
+
+ /* POP */
+ if((pc[0] == 0x0f && (pc[1] == 0xa9 /*GS*/ ||
+ pc[1] == 0xa1 /*FS*/)) || (pc[0] == 0x07) /*ES*/ ||
+ (pc[0] == 0x1f) /*DS*/){
+ sp[0] = NULLSEL;
+ return;
+ }
+
+ /* IRET */
+ if(pc[0] == 0xcf){
+ sp[1] = UESEL; /*CS*/
+ sp[4] = UDSEL; /*SS*/
+ return;
+ }
+ }
+
dumpregs(ureg);
if(!user){
ureg->sp = (ulong)&ureg->sp;
/n/sources/plan9/sys/src/9/pc/trap.c:461,467 - pc/trap.c:512,522
iprint("cpu%d: registers for kernel\n", m->machno);
iprint("FLAGS=%luX TRAP=%luX ECODE=%luX PC=%luX",
ureg->flags, ureg->trap, ureg->ecode, ureg->pc);
- iprint(" SS=%4.4luX USP=%luX\n", ureg->ss & 0xFFFF, ureg->usp);
+ if(userureg(ureg)){
+ iprint(" SS=%4.4luX USP=%luX\n", ureg->ss & 0xFFFF, ureg->usp);
+ } else {
+ iprint(" SP=%luX\n", (ulong)&ureg->sp);
+ }
iprint(" AX %8.8luX BX %8.8luX CX %8.8luX DX %8.8luX\n",
ureg->ax, ureg->bx, ureg->cx, ureg->dx);
iprint(" SI %8.8luX DI %8.8luX BP %8.8luX\n",
/n/sources/plan9/sys/src/9/pc/trap.c:496,501 - pc/trap.c:551,557
}
}
iprint("\n ur %#p up %#p\n", ureg, up);
+ iprint("\n");
}
/n/sources/plan9/sys/src/9/pc/trap.c:619,625 - pc/trap.c:675,681
addr = getcr2();
read = !(ureg->ecode & 2);
- user = (ureg->cs & 0xFFFF) == UESEL;
+ user = userureg(ureg);
if(!user){
if(vmapsync(addr))
return;
/n/sources/plan9/sys/src/9/pc/trap.c:665,671 - pc/trap.c:721,727
int i, s;
ulong scallnr;
- if((ureg->cs & 0xFFFF) != UESEL)
+ if(!userureg(ureg))
panic("syscall: cs 0x%4.4luX", ureg->cs);
cycles(&up->kentry);
/n/sources/plan9/sys/src/9/pc/trap.c:828,833 - pc/trap.c:884,893
*(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */
ureg->usp = sp;
ureg->pc = (ulong)up->notify;
+
+ ureg->cs = UESEL;
+ ureg->ss = ureg->ds = ureg->es = UDSEL;
+
up->notified = 1;
up->nnote--;
memmove(&up->lastnote, &up->note[0], sizeof(Note));
/n/sources/plan9/sys/src/9/pc/trap.c:867,889 - pc/trap.c:927,936
pexit("Suicide", 0);
}
- /*
- * Check the segment selectors are all valid, otherwise
- * a fault will be taken on attempting to return to the
- * user process.
- * Take care with the comparisons as different processor
- * generations push segment descriptors in different ways.
- */
- if((nureg->cs & 0xFFFF) != UESEL || (nureg->ss & 0xFFFF) != UDSEL
- || (nureg->ds & 0xFFFF) != UDSEL || (nureg->es & 0xFFFF) != UDSEL
- || (nureg->fs & 0xFFFF) != UDSEL || (nureg->gs & 0xFFFF) != UDSEL){
- pprint("bad segment selector in noted\n");
- qunlock(&up->debug);
- pexit("Suicide", 0);
- }
-
/* don't let user change system flags */
nureg->flags = (ureg->flags & ~0xCD5) | (nureg->flags & 0xCD5);
+ nureg->cs |= 3;
+ nureg->ss |= 3;
memmove(ureg, nureg, sizeof(Ureg));
/n/sources/plan9/sys/src/9/pc/trap.c:946,951 - pc/trap.c:993,1003
ureg = up->dbgreg;
ureg->usp = (ulong)sp;
ureg->pc = entry;
+
+ ureg->cs = UESEL;
+ ureg->ss = ureg->ds = ureg->es = UDSEL;
+ ureg->fs = ureg->gs = NULLSEL;
+
return USTKTOP-sizeof(Tos); /* address of kernel/user shared data */
}
/n/sources/plan9/sys/src/9/pc/trap.c:967,989 - pc/trap.c:1019,1034
void
setregisters(Ureg* ureg, char* pureg, char* uva, int n)
{
- ulong cs, ds, es, flags, fs, gs, ss;
+ ulong flags;
- ss = ureg->ss;
flags = ureg->flags;
- cs = ureg->cs;
- ds = ureg->ds;
- es = ureg->es;
- fs = ureg->fs;
- gs = ureg->gs;
+
memmove(pureg, uva, n);
- ureg->gs = gs;
- ureg->fs = fs;
- ureg->es = es;
- ureg->ds = ds;
- ureg->cs = cs;
- ureg->flags = (ureg->flags & 0x00FF) | (flags & 0xFF00);
- ureg->ss = ss;
+
+ /* don't allow chaning system flags */
+ ureg->flags = (ureg->flags & 0xCD5) | (flags & ~0xCD5);
+ ureg->cs |= 3;
+ ureg->ss |= 3;
}
static void
/n/sources/plan9/sys/src/9/pc/trap.c:1024,1029 - pc/trap.c:1069,1075
cureg = (Ureg*)(p->sched.sp+2*BY2WD);
memmove(cureg, ureg, sizeof(Ureg));
+
/* return value of syscall in child */
cureg->ax = 0;
/n/sources/plan9/sys/src/9/pc/mmu.c:294,299 - pc/mmu.c:294,301
mmuswitch(Proc* proc)
{
ulong *pdb;
+ ulong x;
+ int n;
if(proc->newtlb){
mmuptefree(proc);
/n/sources/plan9/sys/src/9/pc/mmu.c:307,312 - pc/mmu.c:309,323
taskswitch(proc->mmupdb->pa, (ulong)(proc->kstack+KSTACK));
}else
taskswitch(PADDR(m->pdb), (ulong)(proc->kstack+KSTACK));
+
+ memmove(&m->gdt[PROCSEG0], proc->gdt, sizeof(proc->gdt));
+ if((x = (ulong)proc->ldt) && (n = proc->nldt) > 0){
+ m->gdt[LDTSEG].d0 = (x<<16)|((n * sizeof(Segdesc)) - 1);
+ m->gdt[LDTSEG].d1 = (x&0xFF000000)|((x>>16)&0xFF)|SEGLDT|SEGPL(0)|SEGP;
+ lldt(LDTSEL);
+ } else {
+ lldt(NULLSEL);
+ }
}
/*
/n/sources/plan9/sys/src/9/pc/mmu.c:362,367 - pc/mmu.c:373,384
if(--page->ref)
panic("mmurelease: page->ref %d", page->ref);
pagechainhead(page);
+ }
+ if(proc->ldt){
+ lldt(NULLSEL);
+ free(proc->ldt);
+ proc->ldt = nil;
+ proc->nldt = 0;
}
if(proc->mmufree && palloc.r.p)
wakeup(&palloc.r);
/n/sources/plan9/sys/src/9/pc/l.s:601,606 - pc/l.s:601,611
MOVL (AX), GDTR
RET
+ TEXT lldt(SB), $0 /* LDTR - local descriptor table */
+ MOVL sel+0(FP), AX
+ BYTE $0x0F; BYTE $0x00; BYTE $0xD0 /* LLDT AX */
+ RET
+
TEXT lidt(SB), $0 /* IDTR - interrupt descriptor table */
MOVL idtptr+0(FP), AX
MOVL (AX), IDTR
/n/sources/plan9/sys/src/9/pc/l.s:989,994 - pc/l.s:994,1009
_nothingready:
STI
HLT
+ RET
+
+ TEXT load_fs(SB), $0
+ MOVW fs+0(FP), AX
+ MOVW AX, FS
+ RET
+
+ TEXT load_gs(SB), $0
+ MOVW gs+0(FP), AX
+ MOVW AX, GS
RET
/*
/tmp/diff100000066833:0 - pc/segdesc.c:1,272
+ #include "u.h"
+ #include "../port/lib.h"
+ #include "mem.h"
+ #include "dat.h"
+ #include "fns.h"
+ #include "../port/error.h"
+
+ /*
+ * flags:
+ * P = present
+ * A = accessed (for code/data)
+ * E = expand down (for data)
+ * W = writable (for data)
+ * R = readable (for code)
+ * C = conforming (for code)
+ * G = limit granularity in pages (for code/data)
+ * D = 32 bit operand size (for code)
+ * B = 32 bit stack pointer (for data)
+ * Y = busy (for tss and tss16)
+ * U = available for use by system software
+ */
+
+ static struct {
+ char *name;
+ char *flags;
+ } descrtypes[] = {
+ "data", "--------AWE01--P----U.BG--------",
+ "code", "--------ARC11--P----U.DG--------",
+ "tss16", "--------1Y000--P----U..G--------",
+ "ldt", "--------01000--P----U..G--------",
+ "callg16", "--------00100--P----U..G--------",
+ "taskg", "--------10100--P----U..G--------",
+ "intrg16", "--------01100--P----U..G--------",
+ "trapg16", "--------11100--P----U..G--------",
+ "tss", "--------1Y010--P----U..G--------",
+ "callg", "--------00110--P----U..G--------",
+ "intrg", "--------01110--P----U..G--------",
+ "trapg", "--------11110--P----U..G--------",
+ };
+
+ /*
+ * format:
+ * idx[4] type[8] flags[8] dpl[1] base[8] limit[5]\n
+ */
+
+ enum
+ {
+ RECLEN = 4+1 + 8+1 + 8+1 + 1+1 + 8+1 + 5+1,
+ };
+
+ static long
+ descwrite(Proc *proc, int local, void *v, long n, vlong)
+ {
+ int i, j, t;
+ char buf[RECLEN+1];
+ char c, *p, *s, *e, *f[6];
+ Segdesc d;
+
+ int dpl;
+ ulong base;
+ ulong limit;
+
+ s = (char*)v;
+ e = s + n;
+
+ if(waserror()){
+ if(proc == up)
+ flushmmu();
+ nexterror();
+ }
+
+ while(s < e){
+ for(p = s; p < e && *p != '\n'; p++);
+ ;
+ if((p - s) > RECLEN)
+ error(Ebadarg);
+ memmove(buf, s, p - s);
+ buf[p-s] = 0;
+ s = p+1;
+
+ if(getfields(buf, f, nelem(f), 1, " ") != nelem(f))
+ error(Ebadarg);
+
+ i = strtoul(f[0], nil, 16);
+
+ for(t=0; t<nelem(descrtypes); t++)
+ if(strcmp(descrtypes[t].name, f[1]) == 0)
+ break;
+ if(t == nelem(descrtypes))
+ error(Ebadarg);
+
+ dpl = atoi(f[3]);
+ base = strtoul(f[4], nil, 16);
+ limit = strtoul(f[5], nil, 16);
+
+ d.d0 = ((base & 0xFFFF)<<16) | (limit & 0xFFFF);
+ d.d1 = (base & 0xFF000000) | (limit & 0xF0000) | ((dpl & 3)<<13) | ((base & 0xFF0000)>>16);
+
+ for(j=0; c = descrtypes[t].flags[j]; j++){
+ switch(c){
+ default:
+ if(strchr(f[2], c) == nil){
+ case '0':
+ case '.':
+ d.d1 &= ~(1<<j);
+ break;
+ } else {
+ case '1':
+ d.d1 |= (1<<j);
+ break;
+ }
+ case '-':
+ continue;
+ }
+ }
+
+ /* dont allow system segments */
+ if((d.d1 & SEGP) && ((dpl != 3) || !(d.d1 & (1<<12))))
+ error(Eperm);
+
+ if(local){
+ Segdesc *new, *old;
+ int c;
+
+ if(i < 0 || i >= 8192)
+ error(Ebadarg);
+ if(i >= (c = ((old = proc->ldt) ? proc->nldt : 0))){
+ if((new = malloc(sizeof(Segdesc) * (i+1))) == nil)
+ error(Enomem);
+ if(c > 0)
+ memmove(new, old, sizeof(Segdesc) * c);
+ memset(new + c, 0, sizeof(Segdesc) * ((i+1) - c));
+ proc->ldt = new;
+ proc->nldt = i+1;
+ free(old);
+ }
+ proc->ldt[i] = d;
+ } else {
+ if(i < PROCSEG0 || i >= PROCSEG0 + NPROCSEG)
+ error(Ebadarg);
+ proc->gdt[i - PROCSEG0] = d;
+ }
+ }
+ poperror();
+
+ if(proc == up)
+ flushmmu();
+
+ return n;
+ }
+
+ static long
+ descread(Proc *proc, int local, void *v, long n, vlong o)
+ {
+ int i, j, k, t;
+ char *s;
+
+ int dpl;
+ ulong base;
+ ulong limit;
+
+ s = v;
+ for(i = 0;;i++){
+ Segdesc d;
+
+ if(local){
+ if(proc->ldt == nil || i >= proc->nldt)
+ break;
+ d = proc->ldt[i];
+ } else {
+ if(i < PROCSEG0)
+ i = PROCSEG0;
+ if(i >= PROCSEG0 + NPROCSEG)
+ break;
+ d = proc->gdt[i - PROCSEG0];
+ }
+
+ if(o >= RECLEN){
+ o -= RECLEN;
+ continue;
+ }
+
+ if(s + RECLEN+1 >= (char*)v + n)
+ break;
+
+ for(t=0; t<nelem(descrtypes); t++){
+ for(j=0; descrtypes[t].flags[j]; j++){
+ if(descrtypes[t].flags[j]=='0' && (d.d1 & (1<<j)) != 0)
+ break;
+ if(descrtypes[t].flags[j]=='1' && (d.d1 & (1<<j)) == 0)
+ break;
+ }
+ if(descrtypes[t].flags[j] == 0)
+ break;
+ }
+ if(t == nelem(descrtypes))
+ t = 0;
+
+ s += sprint(s, "%.4lux ", (ulong)i);
+ s += sprint(s, "%-8s ", descrtypes[t].name);
+
+ k = 0;
+ for(j=0; descrtypes[t].flags[j]; j++){
+ switch(descrtypes[t].flags[j]){
+ case '-':
+ case '.':
+ case '0':
+ case '1':
+ continue;
+ }
+ if(d.d1 & (1 << j))
+ s[k++] = descrtypes[t].flags[j];
+ }
+ if(k == 0)
+ s[k++] = '-';
+ while(k < 9)
+ s[k++] = ' ';
+ s += k;
+
+ dpl = (d.d1 & 0x6000)>>13;
+ base = ((d.d0 & 0xFFFF0000)>>16) | ((d.d1 & 0xFF)<<16) | (d.d1 & 0xFF000000);
+ limit = (d.d1 & 0xF0000) | (d.d0 & 0xFFFF);
+
+ s += sprint(s, "%.1d ", dpl);
+ s += sprint(s, "%.8lux ", base);
+ s += sprint(s, "%.5lux\n", limit);
+ }
+
+ return s-(char*)v;
+ }
+
+ static long
+ gdtread(Chan*, void *v, long n, vlong o)
+ {
+ return descread(up, 0, v, n, o);
+ }
+
+ static long
+ gdtwrite(Chan*, void *v, long n, vlong o)
+ {
+ return descwrite(up, 0, v, n, o);
+ }
+
+ static long
+ ldtread(Chan*, void *v, long n, vlong o)
+ {
+ return descread(up, 1, v, n, o);
+ }
+
+ static long
+ ldtwrite(Chan*, void *v, long n, vlong o)
+ {
+ return descwrite(up, 1, v, n, o);
+ }
+
+ /*
+ * devproc hook
+ * extern long (*psegdescread)(Proc*, int, void*, long, vlong);
+ * extern long (*psegdescwrite)(Proc*, int, void*, long, vlong);
+ */
+
+ void
+ segdesclink(void)
+ {
+ /*
+ * devproc hook
+ * psegdescread = descread;
+ * psegdescwrite = descwrite;
+ */
+ addarchfile("gdt", 0666, gdtread, gdtwrite);
+ addarchfile("ldt", 0666, ldtread, ldtwrite);
+ }
/n/sources/plan9/sys/src/9/pc/main.c:440,453 - pc/main.c:440,446
+ conf.nswap
+ conf.nswppo*sizeof(Page);
mainmem->maxsize = kpages;
- if(!cpuserver){
- /*
- * give terminals lots of image memory, too; the dynamic
- * allocation will balance the load properly, hopefully.
- * be careful with 32-bit overflow.
- */
- imagmem->maxsize = kpages;
- }
+ imagmem->maxsize = kpages;
}
static char* mathmsg[] =
/n/sources/plan9/sys/src/9/pc/main.c:575,588 - pc/main.c:568,582
trapenable(VectorCSO, mathover, 0, "mathover");
}
- /*
- * set up floating point for a new process
- */
void
procsetup(Proc*p)
{
p->fpstate = FPinit;
fpoff();
+
+ memset(p->gdt, 0, sizeof(p->gdt));
+ p->ldt = nil;
+ p->nldt = 0;
}
void
/n/sources/plan9/sys/src/9/pc/main.c:592,597 - pc/main.c:586,592
if(p->kp)
return;
+
cycles(&t);
p->pcycles -= t;
}
/n/sources/plan9/sys/src/9/pc/main.c:637,642 - pc/main.c:632,651
mmuflushtlb(PADDR(m->pdb));
}
+ void
+ procfork(Proc *p)
+ {
+ /* inherit user descriptors */
+ memmove(p->gdt, up->gdt, sizeof(p->gdt));
+
+ /* copy local descriptor table */
+ if(up->ldt != nil && up->nldt > 0){
+ p->ldt = malloc(sizeof(Segdesc) * up->nldt);
+ memmove(p->ldt, up->ldt, sizeof(Segdesc) * up->nldt);
+ p->nldt = up->nldt;
+ }
+ }
+
static void
shutdown(int ispanic)
{
/n/sources/plan9/sys/src/9/pc/main.c:648,660 - pc/main.c:657,662
else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
active.ispanic = 0;
once = active.machs & (1<<m->machno);
- /*
- * setting exiting will make hzclock() on each processor call exit(0),
- * which calls shutdown(0) and arch->reset(), which on mp systems is
- * mpshutdown, from which there is no return: the processor is idled
- * or initiates a reboot. clearing our bit in machs avoids calling
- * exit(0) from hzclock() on this processor.
- */
active.machs &= ~(1<<m->machno);
active.exiting = 1;
unlock(&active);
/n/sources/plan9/sys/src/9/pc/main.c:661,668 - pc/main.c:663,668
if(once)
iprint("cpu%d: exiting\n", m->machno);
-
- /* wait for any other processors to shutdown */
spllo();
for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
delay(TK2MS(2));
/n/sources/plan9/sys/src/9/pc/main.c:670,683 - pc/main.c:670,683
break;
}
+ if(getconf("*debug"))
+ delay(5*60*1000);
+
if(active.ispanic){
if(!cpuserver)
for(;;)
halt();
- if(getconf("*debug"))
- delay(5*60*1000);
- else
- delay(10000);
+ delay(10000);
}else
delay(1000);
}
/n/sources/plan9/sys/src/9/pc/main.c:690,715 - pc/main.c:690,700
writeconf();
- /*
- * the boot processor is cpu0. execute this function on it
- * so that the new kernel has the same cpu0. this only matters
- * because the hardware has a notion of which processor was the
- * boot processor and we look at it at start up.
- */
- if (m->machno != 0) {
- procwired(up, 0);
- sched();
- }
-
shutdown(0);
/*
* should be the only processor running now
*/
- if (m->machno != 0)
- print("on cpu%d (not 0)!\n", m->machno);
- if (active.machs)
- print("still have active ap processors!\n");
print("shutting down...\n");
delay(200);
/n/sources/plan9/sys/src/9/pc/main.c:721,727 - pc/main.c:706,711
/* shutdown devices */
chandevshutdown();
- arch->introff();
/*
* Modify the machine page table to directly map the low 4MB of memory
/n/sources/plan9/sys/src/9/ppc/main.c:297,302 - ppc/main.c:297,308
p->pcycles -= t;
}
+ void
+ procfork(Proc *)
+ {
+ }
+
+
/*
* Save the mach dependent part of the process state.
*/
/n/sources/plan9/sys/src/9/ppc/fns.h:77,82 - ppc/fns.h:77,83
void pcicfgw8(Pcidev*, int, int);
void procsave(Proc*);
void procsetup(Proc*);
+ void procfork(Proc*);
void putdcmp(ulong);
void putdec(ulong);
void puthash1(ulong);
/n/sources/plan9/sys/src/9/alphapc/main.c:295,300 - alphapc/main.c:295,306
}
void
+ procfork(Proc *)
+ {
+ }
+
+
+ void
setupboot(int halt)
{
int n = 0; // cpu id of primary cpu, not just m->machno
/n/sources/plan9/sys/src/9/alphapc/fns.h:88,93 - alphapc/fns.h:88,94
#define procrestore(p)
void procsave(Proc*);
void procsetup(Proc*);
+ void procfork(Proc*);
void restfpregs(FPsave*);
uvlong rpcc(uvlong*);
void screeninit(void);
/n/sources/plan9/sys/src/9/bitsy/main.c:252,257 - bitsy/main.c:252,263
USED(p);
}
+ void
+ procfork(Proc *)
+ {
+ }
+
+
/* place holder */
/*
* dummy since rdb is not included
/n/sources/plan9/sys/src/9/bitsy/fns.h:85,90 - bitsy/fns.h:85,91
#define procrestore(p)
void procsave(Proc*);
void procsetup(Proc*);
+ void procfork(Proc*);
void putdac(ulong);
void putttb(ulong);
void putpid(ulong);
/n/sources/plan9/sys/src/9/mtx/main.c:274,279 - mtx/main.c:274,285
}
void
+ procfork(Proc *)
+ {
+ }
+
+
+ void
confinit(void)
{
char *p;
/n/sources/plan9/sys/src/9/mtx/fns.h:86,91 - mtx/fns.h:86,92
#define procrestore(p)
void procsave(Proc*);
void procsetup(Proc*);
+ void procfork(Proc*);
void putdec(ulong);
void puthid0(ulong);
void puthid1(ulong);
/n/sources/plan9/sys/src/9/port/sysproc.c:187,192 - port/sysproc.c:187,195
kstrdup(&p->text, up->text);
kstrdup(&p->user, up->user);
+
+ procfork(p);
+
/*
* since the bss/data segments are now shareable,
* any mmu info about this process is now stale
|