Checkpoint some of what I was starting to tinker with for having some

different context support for 32 vs 64 bit processes.  This simply omits
the save/restore of the segment selector registers for non 32 bit
processes.  This avoids the rdmsr/rwmsr juggling when restoring %gs
clobbers the kernel msr that holds the gsbase.

However, I suspect it might be better to conditionally do this at
user<->kernel transition where we wouldn't need to do the juggling in the
first place.  Or have per-thread extended context save/restore hooks.
This commit is contained in:
peter 2004-05-16 22:43:57 +00:00
parent 42f5ddc2f4
commit 8b77ed77bd
3 changed files with 20 additions and 7 deletions

View File

@ -103,6 +103,17 @@ ENTRY(cpu_switch)
pushfq /* PSL */
popq PCB_RFLAGS(%r8)
testl $PCB_32BIT,PCB_FLAGS(%r8)
jz 1f /* no, skip over */
/* Save segment selector numbers */
movl %ds,PCB_DS(%r8)
movl %es,PCB_ES(%r8)
movl %fs,PCB_FS(%r8)
movl %gs,PCB_GS(%r8)
jmp 2f
1:
/* Save userland %fs */
movl $MSR_FSBASE,%ecx
rdmsr
@ -114,12 +125,7 @@ ENTRY(cpu_switch)
rdmsr
movl %eax,PCB_GSBASE(%r8)
movl %edx,PCB_GSBASE+4(%r8)
/* Save segment selector numbers */
movl %ds,PCB_DS(%r8)
movl %es,PCB_ES(%r8)
movl %fs,PCB_FS(%r8)
movl %gs,PCB_GS(%r8)
2:
/* Test if debug registers should be saved. */
testl $PCB_DBREGS,PCB_FLAGS(%r8)
@ -181,6 +187,9 @@ sw1:
*/
movq TD_PCB(%rsi),%r8
testl $PCB_32BIT,PCB_FLAGS(%r8)
jz 1f /* no, skip over */
/* Restore segment selector numbers */
movl PCB_DS(%r8),%ds
movl PCB_ES(%r8),%es
@ -191,6 +200,8 @@ sw1:
rdmsr
movl PCB_GS(%r8),%gs
wrmsr
jmp 2f
1:
/* Restore userland %fs */
movl $MSR_FSBASE,%ecx
@ -203,6 +214,7 @@ sw1:
movl PCB_GSBASE(%r8),%eax
movl PCB_GSBASE+4(%r8),%edx
wrmsr
2:
/* Update the TSS_RSP0 pointer for the next interrupt */
movq PCPU(TSSP), %rax
@ -248,7 +260,6 @@ sw1:
orq %rcx,%rax
movq %rax,%dr7
1:
ret
/*

View File

@ -138,6 +138,7 @@ ASSYM(PCB_DR3, offsetof(struct pcb, pcb_dr3));
ASSYM(PCB_DR6, offsetof(struct pcb, pcb_dr6));
ASSYM(PCB_DR7, offsetof(struct pcb, pcb_dr7));
ASSYM(PCB_DBREGS, PCB_DBREGS);
ASSYM(PCB_32BIT, PCB_32BIT);
ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
ASSYM(PCB_FULLCTX, PCB_FULLCTX);

View File

@ -71,6 +71,7 @@ struct pcb {
u_long pcb_flags;
#define PCB_DBREGS 0x02 /* process using debug registers */
#define PCB_FPUINITDONE 0x08 /* fpu state is initialized */
#define PCB_32BIT 0x40 /* process has 32 bit context (segs etc) */
#define PCB_FULLCTX 0x80 /* full context restore on sysret */
caddr_t pcb_onfault; /* copyin/out fault recovery */