svn commit: r206459 - in head/sys/amd64: amd64 include
Konstantin Belousov
kib at FreeBSD.org
Sat Apr 10 18:38:12 UTC 2010
Author: kib
Date: Sat Apr 10 18:38:11 2010
New Revision: 206459
URL: http://svn.freebsd.org/changeset/base/206459
Log:
Handle a case when non-canonical address is loaded into the fsbase or
gsbase MSR.
MFC after: 3 days
Modified:
head/sys/amd64/amd64/exception.S
head/sys/amd64/amd64/trap.c
head/sys/amd64/include/md_var.h
Modified: head/sys/amd64/amd64/exception.S
==============================================================================
--- head/sys/amd64/amd64/exception.S Sat Apr 10 14:28:58 2010 (r206458)
+++ head/sys/amd64/amd64/exception.S Sat Apr 10 18:38:11 2010 (r206459)
@@ -668,7 +668,8 @@ ld_fs: movw %ax,%fs
movl $MSR_FSBASE,%ecx
movl PCB_FSBASE(%r8),%eax
movl PCB_FSBASE+4(%r8),%edx
- wrmsr
+ .globl ld_fsbase
+ld_fsbase: wrmsr
1:
/* Restore %gs and gsbase */
movw TF_GS(%rsp),%si
@@ -685,7 +686,8 @@ ld_gs: movw %si,%gs
movl $MSR_KGSBASE,%ecx
movl PCB_GSBASE(%r8),%eax
movl PCB_GSBASE+4(%r8),%edx
- wrmsr
+ .globl ld_gsbase
+ld_gsbase: wrmsr
1: .globl ld_es
ld_es: movw TF_ES(%rsp),%es
.globl ld_ds
@@ -798,6 +800,30 @@ gs_load_fault:
call trap
movw $KUG32SEL,TF_GS(%rsp)
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
ENTRY(end_exceptions)
#endif
Modified: head/sys/amd64/amd64/trap.c
==============================================================================
--- head/sys/amd64/amd64/trap.c Sat Apr 10 14:28:58 2010 (r206458)
+++ head/sys/amd64/amd64/trap.c Sat Apr 10 18:38:11 2010 (r206459)
@@ -566,6 +566,14 @@ trap(struct trapframe *frame)
frame->tf_gs = _ugssel;
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) {
frame->tf_rip =
(long)PCPU_GET(curpcb)->pcb_onfault;
Modified: head/sys/amd64/include/md_var.h
==============================================================================
--- head/sys/amd64/include/md_var.h Sat Apr 10 14:28:58 2010 (r206458)
+++ head/sys/amd64/include/md_var.h Sat Apr 10 18:38:11 2010 (r206459)
@@ -83,10 +83,14 @@ void ld_ds(void) __asm(__STRING(ld_ds));
void ld_es(void) __asm(__STRING(ld_es));
void ld_fs(void) __asm(__STRING(ld_fs));
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 es_load_fault(void) __asm(__STRING(es_load_fault));
void fs_load_fault(void) __asm(__STRING(fs_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_drop_page(vm_paddr_t);
void initializecpu(void);
More information about the svn-src-all
mailing list