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:
parent
42f5ddc2f4
commit
8b77ed77bd
@ -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
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user