Plan 9 from Bell Labs’s /usr/web/sources/contrib/cinap_lenrek/segdescpatch/kernel.diff

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/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

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.