ref: c6c2e04d4a700fe3982a4a72e768c69d6ace08a6
parent: b429f72eaedff27b43c4ac951cea62f574e6fb23
author: cinap_lenrek <cinap_lenrek@localhost>
date: Tue Jul 12 11:46:22 EDT 2011
segdesc: add /dev/^(ldt gdt) support
--- a/sys/src/9/alphapc/fns.h
+++ b/sys/src/9/alphapc/fns.h
@@ -88,6 +88,7 @@
#define procrestore(p)
void procsave(Proc*);
void procsetup(Proc*);
+void procfork(Proc*);
void restfpregs(FPsave*);
uvlong rpcc(uvlong*);
void screeninit(void);
--- a/sys/src/9/alphapc/main.c
+++ b/sys/src/9/alphapc/main.c
@@ -272,6 +272,11 @@
}
void
+procfork(Proc *)
+{
+}
+
+void
procsave(Proc *p)
{
if(p->fpstate == FPactive){
--- a/sys/src/9/bitsy/fns.h
+++ b/sys/src/9/bitsy/fns.h
@@ -85,6 +85,7 @@
#define procrestore(p)
void procsave(Proc*);
void procsetup(Proc*);
+void procfork(Proc*);
void putdac(ulong);
void putttb(ulong);
void putpid(ulong);
--- a/sys/src/9/bitsy/main.c
+++ b/sys/src/9/bitsy/main.c
@@ -243,6 +243,11 @@
p->fpstate = FPinit;
}
+void
+procfork(Proc*)
+{
+}
+
/*
* Save the mach dependent part of the process state.
*/
--- a/sys/src/9/kw/arch.c
+++ b/sys/src/9/kw/arch.c
@@ -126,6 +126,11 @@
fpusysprocsetup(p);
}
+void
+procfork(Proc *)
+{
+}
+
/*
* Save the mach dependent part of the process state.
*/
--- a/sys/src/9/kw/fns.h
+++ b/sys/src/9/kw/fns.h
@@ -68,6 +68,7 @@
void procrestore(Proc *);
void procsave(Proc*);
void procsetup(Proc*);
+void procfork(Proc*);
extern void _reset(void);
extern void setr13(int, u32int*);
extern void syscallfmt(int syscallno, ulong pc, va_list list);
--- a/sys/src/9/mtx/fns.h
+++ b/sys/src/9/mtx/fns.h
@@ -85,6 +85,7 @@
#define procrestore(p)
void procsave(Proc*);
void procsetup(Proc*);
+void procfork(Proc*);
void putdec(ulong);
void puthid0(ulong);
void puthid1(ulong);
--- a/sys/src/9/mtx/main.c
+++ b/sys/src/9/mtx/main.c
@@ -259,6 +259,11 @@
p->fpstate = FPinit;
}
+void
+procfork(Proc *)
+{
+}
+
/*
* Save the mach dependent part of the process state.
*/
--- a/sys/src/9/omap/arch.c
+++ b/sys/src/9/omap/arch.c
@@ -126,6 +126,11 @@
fpusysprocsetup(p);
}
+void
+procfork(Proc*)
+{
+}
+
/*
* Save the mach dependent part of the process state.
*/
--- a/sys/src/9/omap/fns.h
+++ b/sys/src/9/omap/fns.h
@@ -70,6 +70,7 @@
extern void procrestore(Proc *);
extern void procsave(Proc*);
extern void procsetup(Proc*);
+extern void procfork(Proc*);
extern void _reset(void);
extern void screenclockson(void);
extern void screeninit(void);
--- a/sys/src/9/pc/dat.h
+++ b/sys/src/9/pc/dat.h
@@ -108,6 +108,12 @@
int nuart; /* number of uart devices */
};
+struct Segdesc
+{
+ ulong d0;
+ ulong d1;
+};
+
/*
* MMU stuff in proc
*/
@@ -120,6 +126,10 @@
Page* kmaptable; /* page table used by kmap */
uint lastkmap; /* last entry used by kmap */
int nkmap; /* number of current kmaps */
+
+ Segdesc gdt[NPROCSEG]; /* per process descriptors */
+ Segdesc *ldt; /* local descriptor table */
+ int nldt; /* number of ldt descriptors allocated */
};
/*
@@ -162,12 +172,6 @@
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
{
--- a/sys/src/9/pc/fns.h
+++ b/sys/src/9/pc/fns.h
@@ -87,6 +87,7 @@
void kbdinit(void);
#define kmapinval()
void lgdt(ushort[3]);
+void lldt(ulong);
void lidt(ushort[3]);
void links(void);
void ltr(ulong);
@@ -147,6 +148,7 @@
void procrestore(Proc*);
void procsave(Proc*);
void procsetup(Proc*);
+void procfork(Proc*);
void putcr0(ulong);
void putcr3(ulong);
void putcr4(ulong);
@@ -173,7 +175,6 @@
ulong upaalloc(int, int);
void upafree(ulong, int);
void upareserve(ulong, int);
-#define userureg(ur) (((ur)->cs & 0xFFFF) == UESEL)
void vectortable(void);
void* vmap(ulong, int);
int vmapsync(ulong);
@@ -182,6 +183,7 @@
void wrmsr(int, vlong);
int xchgw(ushort*, int);
+#define userureg(ur) (((ur)->cs & 3) == 3)
#define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
#define KADDR(a) kaddr(a)
#define PADDR(a) paddr((void*)(a))
--- a/sys/src/9/pc/io.h
+++ b/sys/src/9/pc/io.h
@@ -10,6 +10,8 @@
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 */
--- a/sys/src/9/pc/l.s
+++ b/sys/src/9/pc/l.s
@@ -243,6 +243,17 @@
HLT
JMP _idle
+
+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
+
/*
* Save registers.
*/
@@ -599,6 +610,11 @@
TEXT lgdt(SB), $0 /* GDTR - global descriptor table */
MOVL gdtptr+0(FP), AX
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 */
--- a/sys/src/9/pc/main.c
+++ b/sys/src/9/pc/main.c
@@ -225,8 +225,7 @@
kstrdup(&p->text, "*init*");
kstrdup(&p->user, eve);
- p->fpstate = FPinit;
- fpoff();
+ procsetup(p);
/*
* Kernel Stack
@@ -585,6 +584,24 @@
{
p->fpstate = FPinit;
fpoff();
+
+ memset(p->gdt, 0, sizeof(p->gdt));
+ p->ldt = nil;
+ p->nldt = 0;
+}
+
+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;
+ }
}
void
--- a/sys/src/9/pc/mem.h
+++ b/sys/src/9/pc/mem.h
@@ -92,8 +92,10 @@
#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 */
@@ -109,7 +111,7 @@
#define APMCSEL SELECTOR(APMCSEG, SELGDT, 0)
#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
@@ -120,6 +122,7 @@
#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 */
--- a/sys/src/9/pc/mmu.c
+++ b/sys/src/9/pc/mmu.c
@@ -294,6 +294,8 @@
mmuswitch(Proc* proc)
{
ulong *pdb;
+ ulong x;
+ int n;
if(proc->newtlb){
mmuptefree(proc);
@@ -307,6 +309,14 @@
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);
}
/*
@@ -366,6 +376,11 @@
if(proc->mmufree && palloc.r.p)
wakeup(&palloc.r);
proc->mmufree = 0;
+ if(proc->ldt){
+ free(proc->ldt);
+ proc->ldt = nil;
+ proc->nldt = 0;
+ }
}
/*
--- a/sys/src/9/pc/pccpuf
+++ b/sys/src/9/pc/pccpuf
@@ -35,6 +35,7 @@
usb
link
+ segdesc
realmode
devpccard
devi82365
--- a/sys/src/9/pc/pcf
+++ b/sys/src/9/pc/pcf
@@ -37,6 +37,7 @@
usb
link
+ segdesc
realmode
devpccard
devi82365
--- /dev/null
+++ b/sys/src/9/pc/segdesc.c
@@ -1,0 +1,261 @@
+#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);
+}
+
+void
+segdesclink(void)
+{
+ addarchfile("gdt", 0666, gdtread, gdtwrite);
+ addarchfile("ldt", 0666, ldtread, ldtwrite);
+}
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -326,7 +326,7 @@
}
m->perf.intrts = perfticks();
- user = (ureg->cs & 0xFFFF) == UESEL;
+ user = userureg(ureg);
if(user){
up->dbgreg = ureg;
cycles(&up->kentry);
@@ -424,6 +424,48 @@
while(m->machno != 0)
;
}
+
+ 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;
@@ -461,7 +503,10 @@
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",
@@ -619,7 +664,7 @@
addr = getcr2();
read = !(ureg->ecode & 2);
- user = (ureg->cs & 0xFFFF) == UESEL;
+ user = userureg(ureg);
if(!user){
if(vmapsync(addr))
return;
@@ -666,7 +711,7 @@
ulong scallnr;
vlong startns, stopns;
- if((ureg->cs & 0xFFFF) != UESEL)
+ if(!userureg(ureg))
panic("syscall: cs 0x%4.4luX", ureg->cs);
cycles(&up->kentry);
@@ -850,6 +895,8 @@
*(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));
@@ -889,23 +936,10 @@
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){
- qunlock(&up->debug);
- pprint("bad segment selector in noted\n");
- 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));
@@ -968,6 +1002,9 @@
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 */
}
@@ -989,23 +1026,13 @@
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;
+ ureg->flags = (ureg->flags & 0xCD5) | (flags & ~0xCD5);
+ ureg->cs |= 3;
+ ureg->ss |= 3;
}
static void
--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -187,6 +187,9 @@
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
@@ -472,11 +475,6 @@
poperror();
cclose(tc);
- /*
- * At this point, the mmu contains info about the old address
- * space and needs to be flushed
- */
- flushmmu();
qlock(&up->debug);
up->nnote = 0;
up->notify = 0;
@@ -484,9 +482,15 @@
up->privatemem = 0;
procsetup(up);
qunlock(&up->debug);
+
+ /*
+ * At this point, the mmu contains info about the old address
+ * space and needs to be flushed
+ */
+ flushmmu();
+
if(up->hang)
up->procctl = Proc_stopme;
-
return execregs(entry, ssize, nargs);
}
--- a/sys/src/9/ppc/fns.h
+++ b/sys/src/9/ppc/fns.h
@@ -77,6 +77,7 @@
void pcicfgw8(Pcidev*, int, int);
void procsave(Proc*);
void procsetup(Proc*);
+void procfork(Proc*);
void putdcmp(ulong);
void putdec(ulong);
void puthash1(ulong);
--- a/sys/src/9/ppc/main.c
+++ b/sys/src/9/ppc/main.c
@@ -287,6 +287,11 @@
}
void
+procfork(Proc *)
+{
+}
+
+void
procrestore(Proc *p)
{
uvlong t;