kernel: do all fp state fork from procfork() (like pc kernel)

this simplifies the arm ports and keeps all the stuff in one place
instead of spreading it thru notify(), trap() and syscall() functions
and prevents useless fp state copying for kernel procs.

also make sure to save fp in notify while still splhi().
This commit is contained in:
cinap_lenrek 2013-05-30 23:26:21 +02:00
parent 9652f5bec5
commit d94ffb4808
15 changed files with 45 additions and 157 deletions

View file

@ -523,16 +523,16 @@ notify(Ureg *ur)
if(up->nnote == 0)
return 0;
spllo();
qlock(&up->debug);
up->notepending = 0;
if(up->fpstate == FPactive){
savefpregs(&up->fpsave);
up->fpstate = FPinactive;
}
up->fpstate |= FPillegal;
spllo();
qlock(&up->debug);
up->notepending = 0;
n = &up->note[0];
if(strncmp(n->msg, "sys:", 4) == 0) {
l = strlen(n->msg);
@ -712,12 +712,6 @@ syscall(Ureg *aur)
scallnr = ur->r0;
up->scallnr = ur->r0;
if(scallnr == RFORK && up->fpstate == FPactive){
savefpregs(&up->fpsave);
up->fpstate = FPinactive;
//print("SR=%lux+", up->fpsave.fpstatus);
}
spllo();
sp = ur->sp;

View file

@ -82,9 +82,8 @@ extern void fpunoted(void);
extern void fpunotify(Ureg*);
extern void fpuprocrestore(Proc*);
extern void fpuprocsave(Proc*);
extern void fpuprocfork(Proc*);
extern void fpusysprocsetup(Proc*);
extern void fpusysrfork(Ureg*);
extern void fpusysrforkchild(Proc*, Ureg*, Proc*);
extern int fpuemu(Ureg*);
/*
* Things called from port.

View file

@ -239,33 +239,6 @@ fpunoted(void)
up->fpstate &= ~FPillegal;
}
/*
* Called early in the non-interruptible path of
* sysrfork() via the machine-dependent syscall() routine.
* Save the state so that it can be easily copied
* to the child process later.
*/
void
fpusysrfork(Ureg*)
{
if(up->fpstate == FPactive){
fpsave(&up->fpsave);
up->fpstate = FPinactive;
}
}
/*
* Called later in sysrfork() via the machine-dependent
* sysrforkchild() routine.
* Copy the parent FPU state to the child.
*/
void
fpusysrforkchild(Proc *p, Ureg *, Proc *up)
{
/* don't penalize the child, it hasn't done FP in a note handler. */
p->fpstate = up->fpstate & ~FPillegal;
}
/* should only be called if p->fpstate == FPactive */
void
fpsave(FPsave *fps)
@ -332,6 +305,28 @@ fpuprocrestore(Proc *)
{
}
/*
* The current process has been forked,
* save and copy neccesary state to child.
*/
void
fpuprocfork(Proc *p)
{
int s;
s = splhi();
switch(up->fpstate & ~FPillegal){
case FPactive:
fpsave(&up->fpsave);
up->fpstate = FPinactive;
/* no break */
case FPinactive:
p->fpsave = up->fpsave;
p->fpstate = FPinactive;
}
splx(s);
}
/*
* Disable the FPU.
* Called from sysexec() via sysprocsetup() to

View file

@ -99,8 +99,6 @@ extern void fpunotify(Ureg*);
extern void fpuprocrestore(Proc*);
extern void fpuprocsave(Proc*);
extern void fpusysprocsetup(Proc*);
extern void fpusysrfork(Ureg*);
extern void fpusysrforkchild(Proc*, Ureg *, Proc*);
extern int fpuemu(Ureg*);
/*

View file

@ -41,27 +41,6 @@ fpunoted(void)
*/
}
void
fpusysrfork(Ureg*)
{
/*
* Called early in the non-interruptible path of
* sysrfork() via the machine-dependent syscall() routine.
* Save the state so that it can be easily copied
* to the child process later.
*/
}
void
fpusysrforkchild(Proc*, Ureg*, Proc*)
{
/*
* Called later in sysrfork() via the machine-dependent
* sysrforkchild() routine.
* Copy the parent FPU state to the child.
*/
}
void
fpuprocsave(Proc*)
{

View file

@ -201,8 +201,6 @@ syscall(Ureg* ureg)
scallnr = ureg->r0;
up->scallnr = scallnr;
if(scallnr == RFORK)
fpusysrfork(ureg);
spllo();
sp = ureg->sp;
@ -332,6 +330,4 @@ forkchild(Proc *p, Ureg *ureg)
/* Things from bottom of syscall which were never executed */
p->psstate = 0;
p->insyscall = 0;
fpusysrforkchild(p, cureg, up);
}

View file

@ -134,6 +134,8 @@ procfork(Proc* p)
{
p->kentry = up->kentry;
p->pcycles = -p->kentry;
fpuprocfork(p);
}
/*

View file

@ -114,8 +114,7 @@ extern void fpunotify(Ureg*);
extern void fpuprocrestore(Proc*);
extern void fpuprocsave(Proc*);
extern void fpusysprocsetup(Proc*);
extern void fpusysrfork(Ureg*);
extern void fpusysrforkchild(Proc*, Ureg*, Proc*);
extern void fpuprocfork(Proc*);
extern int fpuemu(Ureg*);
/*

View file

@ -41,27 +41,6 @@ fpunoted(void)
*/
}
void
fpusysrfork(Ureg*)
{
/*
* Called early in the non-interruptible path of
* sysrfork() via the machine-dependent syscall() routine.
* Save the state so that it can be easily copied
* to the child process later.
*/
}
void
fpusysrforkchild(Proc*, Ureg *, Proc*)
{
/*
* Called later in sysrfork() via the machine-dependent
* sysrforkchild() routine.
* Copy the parent FPU state to the child.
*/
}
void
fpuprocsave(Proc*)
{
@ -85,6 +64,15 @@ fpuprocrestore(Proc*)
*/
}
void
fpuprocfork(Proc*)
{
/*
* The current process has been forked, save and copy neccesary
* state to child. Nothing to do here, child proc starts with FPinit.
*/
}
void
fpusysprocsetup(Proc*)
{

View file

@ -205,8 +205,6 @@ syscall(Ureg* ureg)
scallnr = ureg->r0;
up->scallnr = scallnr;
if(scallnr == RFORK)
fpusysrfork(ureg);
spllo();
sp = ureg->sp;
@ -328,6 +326,4 @@ forkchild(Proc *p, Ureg *ureg)
/* Things from bottom of syscall which were never executed */
p->psstate = 0;
p->insyscall = 0;
fpusysrforkchild(p, cureg, up);
}

View file

@ -633,10 +633,6 @@ syscall(Ureg* ureg)
scallnr = ureg->r3;
up->scallnr = ureg->r3;
if(scallnr == RFORK && up->fpstate == FPactive){
fpsave(&up->fpsave);
up->fpstate = FPinactive;
}
spllo();
sp = ureg->usp;
@ -714,6 +710,12 @@ notify(Ureg* ur)
if(up->nnote == 0)
return 0;
if(up->fpstate == FPactive){
fpsave(&up->fpsave);
up->fpstate = FPinactive;
}
up->fpstate |= FPillegal;
s = spllo();
qlock(&up->debug);
up->notepending = 0;
@ -743,12 +745,6 @@ notify(Ureg* ur)
pexit(n->msg, n->flag!=NDebug);
}
if(up->fpstate == FPactive){
fpsave(&up->fpsave);
up->fpstate = FPinactive;
}
up->fpstate |= FPillegal;
sp = ur->usp & ~(BY2V-1);
sp -= sizeof(Ureg);

View file

@ -172,8 +172,6 @@ extern void fpunotify(Ureg*);
extern void fpuprocrestore(Proc*);
extern void fpuprocsave(Proc*);
extern void fpusysprocsetup(Proc*);
extern void fpusysrfork(Ureg*);
extern void fpusysrforkchild(Proc*, Ureg*, Proc*);
extern int fpuemu(Ureg*);
/*

View file

@ -41,27 +41,6 @@ fpunoted(void)
*/
}
void
fpusysrfork(Ureg*)
{
/*
* Called early in the non-interruptible path of
* sysrfork() via the machine-dependent syscall() routine.
* Save the state so that it can be easily copied
* to the child process later.
*/
}
void
fpusysrforkchild(Proc*, Ureg *, Proc*)
{
/*
* Called later in sysrfork() via the machine-dependent
* sysrforkchild() routine.
* Copy the parent FPU state to the child.
*/
}
void
fpuprocsave(Proc*)
{

View file

@ -209,8 +209,6 @@ syscall(Ureg* ureg)
scallnr = ureg->r0;
up->scallnr = scallnr;
if(scallnr == RFORK)
fpusysrfork(ureg);
spllo();
sp = ureg->sp;
@ -361,6 +359,4 @@ forkchild(Proc *p, Ureg *ureg)
/* Things from bottom of syscall which were never executed */
p->psstate = 0;
p->insyscall = 0;
fpusysrforkchild(p, cureg, up);
}

View file

@ -239,33 +239,6 @@ fpunoted(void)
up->fpstate &= ~FPillegal;
}
/*
* Called early in the non-interruptible path of
* sysrfork() via the machine-dependent syscall() routine.
* Save the state so that it can be easily copied
* to the child process later.
*/
void
fpusysrfork(Ureg*)
{
if(up->fpstate == FPactive){
fpsave(&up->fpsave);
up->fpstate = FPinactive;
}
}
/*
* Called later in sysrfork() via the machine-dependent
* sysrforkchild() routine.
* Copy the parent FPU state to the child.
*/
void
fpusysrforkchild(Proc *p, Ureg *, Proc *up)
{
/* don't penalize the child, it hasn't done FP in a note handler. */
p->fpstate = up->fpstate & ~FPillegal;
}
/* should only be called if p->fpstate == FPactive */
void
fpsave(FPsave *fps)