MFC r206459:

Handle a case when non-canonical address is loaded into the fsbase or
gsbase MSR.
This commit is contained in:
kib 2010-04-13 10:23:03 +00:00
parent 443081b977
commit 9b7228a41e
3 changed files with 40 additions and 2 deletions

View File

@ -668,7 +668,8 @@ ld_fs: movw %ax,%fs
movl $MSR_FSBASE,%ecx movl $MSR_FSBASE,%ecx
movl PCB_FSBASE(%r8),%eax movl PCB_FSBASE(%r8),%eax
movl PCB_FSBASE+4(%r8),%edx movl PCB_FSBASE+4(%r8),%edx
wrmsr .globl ld_fsbase
ld_fsbase: wrmsr
1: 1:
/* Restore %gs and gsbase */ /* Restore %gs and gsbase */
movw TF_GS(%rsp),%si movw TF_GS(%rsp),%si
@ -685,7 +686,8 @@ ld_gs: movw %si,%gs
movl $MSR_KGSBASE,%ecx movl $MSR_KGSBASE,%ecx
movl PCB_GSBASE(%r8),%eax movl PCB_GSBASE(%r8),%eax
movl PCB_GSBASE+4(%r8),%edx movl PCB_GSBASE+4(%r8),%edx
wrmsr .globl ld_gsbase
ld_gsbase: wrmsr
1: .globl ld_es 1: .globl ld_es
ld_es: movw TF_ES(%rsp),%es ld_es: movw TF_ES(%rsp),%es
.globl ld_ds .globl ld_ds
@ -798,6 +800,30 @@ gs_load_fault:
call trap call trap
movw $KUG32SEL,TF_GS(%rsp) movw $KUG32SEL,TF_GS(%rsp)
jmp doreti jmp doreti
ALIGN_TEXT
.globl fsbase_load_fault
fsbase_load_fault:
movl $T_PROTFLT,TF_TRAPNO(%rsp)
movq %rsp, %rdi
call trap
movq PCPU(CURTHREAD),%r8
movq TD_PCB(%r8),%r8
movq $0,PCB_FSBASE(%r8)
jmp doreti
ALIGN_TEXT
.globl gsbase_load_fault
gsbase_load_fault:
popfq
movl $T_PROTFLT,TF_TRAPNO(%rsp)
movq %rsp, %rdi
call trap
movq PCPU(CURTHREAD),%r8
movq TD_PCB(%r8),%r8
movq $0,PCB_GSBASE(%r8)
jmp doreti
#ifdef HWPMC_HOOKS #ifdef HWPMC_HOOKS
ENTRY(end_exceptions) ENTRY(end_exceptions)
#endif #endif

View File

@ -563,6 +563,14 @@ trap(struct trapframe *frame)
frame->tf_gs = _ugssel; frame->tf_gs = _ugssel;
goto out; goto out;
} }
if (frame->tf_rip == (long)ld_gsbase) {
frame->tf_rip = (long)gsbase_load_fault;
goto out;
}
if (frame->tf_rip == (long)ld_fsbase) {
frame->tf_rip = (long)fsbase_load_fault;
goto out;
}
if (PCPU_GET(curpcb)->pcb_onfault != NULL) { if (PCPU_GET(curpcb)->pcb_onfault != NULL) {
frame->tf_rip = frame->tf_rip =
(long)PCPU_GET(curpcb)->pcb_onfault; (long)PCPU_GET(curpcb)->pcb_onfault;

View File

@ -83,10 +83,14 @@ void ld_ds(void) __asm(__STRING(ld_ds));
void ld_es(void) __asm(__STRING(ld_es)); void ld_es(void) __asm(__STRING(ld_es));
void ld_fs(void) __asm(__STRING(ld_fs)); void ld_fs(void) __asm(__STRING(ld_fs));
void ld_gs(void) __asm(__STRING(ld_gs)); void ld_gs(void) __asm(__STRING(ld_gs));
void ld_fsbase(void) __asm(__STRING(ld_fsbase));
void ld_gsbase(void) __asm(__STRING(ld_gsbase));
void ds_load_fault(void) __asm(__STRING(ds_load_fault)); void ds_load_fault(void) __asm(__STRING(ds_load_fault));
void es_load_fault(void) __asm(__STRING(es_load_fault)); void es_load_fault(void) __asm(__STRING(es_load_fault));
void fs_load_fault(void) __asm(__STRING(fs_load_fault)); void fs_load_fault(void) __asm(__STRING(fs_load_fault));
void gs_load_fault(void) __asm(__STRING(gs_load_fault)); void gs_load_fault(void) __asm(__STRING(gs_load_fault));
void fsbase_load_fault(void) __asm(__STRING(fsbase_load_fault));
void gsbase_load_fault(void) __asm(__STRING(gsbase_load_fault));
void dump_add_page(vm_paddr_t); void dump_add_page(vm_paddr_t);
void dump_drop_page(vm_paddr_t); void dump_drop_page(vm_paddr_t);
void initializecpu(void); void initializecpu(void);