svn commit: r249709 - projects/amd64_xen_pv/sys/amd64/xen
Cherry G. Mathew
cherry at FreeBSD.org
Sat Apr 20 18:52:07 UTC 2013
Author: cherry
Date: Sat Apr 20 18:52:06 2013
New Revision: 249709
URL: http://svnweb.freebsd.org/changeset/base/249709
Log:
Intercept syscall instruction from userland via hypervisor callback.
Reroute to FreeBSD system call routines.
Enable fpu (Unrelated)
Approved by: gibbs(implicit)
Modified:
projects/amd64_xen_pv/sys/amd64/xen/exception.S
projects/amd64_xen_pv/sys/amd64/xen/machdep.c
Modified: projects/amd64_xen_pv/sys/amd64/xen/exception.S
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/xen/exception.S Sat Apr 20 18:45:28 2013 (r249708)
+++ projects/amd64_xen_pv/sys/amd64/xen/exception.S Sat Apr 20 18:52:06 2013 (r249709)
@@ -41,6 +41,7 @@
#include "assym.s"
#define T_EVENT T_RESERVED /* XXX: */
+#define VGCF_IN_SYSCALL 256 /* See: xen/interface/arch-x86/xen-x86_64.h */
/*
* We're guaranteed that sizeof(struct vcpu_info) == 64 bytes.
@@ -213,6 +214,24 @@
pushq $0 ; \
jmp hypercall_page + (__HYPERVISOR_iret * 32)
+#define CALLSYSCALL \
+ cld ;\
+ movq PCPU(CURTHREAD),%rdi ;\
+ movq %rsp, TD_FRAME(%rdi) ;\
+ movl TF_RFLAGS(%rsp),%esi ;\
+ andl $PSL_T,%esi ;\
+ call amd64_syscall
+
+#define SYSRET \
+ /* XXX: watchout for:
+ * http: //cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-0744
+ * Explained here:
+ * http://blog.xen.org/index.php/2012/06/13/the-intel-sysret-privilege-escalation/
+ * Also see comments in trap.c
+ */
+ pushq $VGCF_IN_SYSCALL ;\
+ jmp hypercall_page + (__HYPERVISOR_iret * 32)
+
NON_GPROF_ENTRY(restore_segment_regs)
.globl ld_es
.globl ld_ds
@@ -537,3 +556,16 @@ ENTRY(failsafe_callback)
movq msgfailsafe, %rdi ;
call panic ; /* panic("..."); */
msgfailsafe: .asciz "Failsafe upcall triggered\n"
+
+IDTVEC(syscall_callback)
+ TRAP_FRAME_ENTER_NOERR ;
+ TRAP_PROLOGUE(T_USER) ;
+ SAVE_SEGMENT_REGS ;
+ SAVE_GENERAL_REGS ;
+ DO_STI_MAYBE ;
+ CALLSYSCALL ;
+ DO_AST_MAYBE ;
+ RESTORE_GENERAL_REGS ; /* XXX: optimise for SYSRET */
+ RESTORE_SEGMENT_REGS ;
+ TRAP_FRAME_EXIT_NOERR ;
+ INTR_EXIT ; /* XXX: SYSRET is more optimal */
Modified: projects/amd64_xen_pv/sys/amd64/xen/machdep.c
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/xen/machdep.c Sat Apr 20 18:45:28 2013 (r249708)
+++ projects/amd64_xen_pv/sys/amd64/xen/machdep.c Sat Apr 20 18:52:06 2013 (r249709)
@@ -131,9 +131,10 @@ __aligned(PAGE_SIZE); /* vcpu0 global de
struct mtx icu_lock;
struct mtx dt_lock; /* lock for GDT and LDT */ /* XXX : please review its use */
-/* Event callback prototypes */
+/* callback prototypes */
void Xhypervisor_callback(void);
void failsafe_callback(void);
+void Xsyscall_callback(void);
vm_paddr_t initxen(struct start_info *);
@@ -290,21 +291,24 @@ init_exception_table(void)
static void init_event_callbacks(void)
{
- struct callback_register event = {
- .type = CALLBACKTYPE_event,
- .address = (unsigned long)Xhypervisor_callback
- };
+ struct callback_register cbr;
- struct callback_register failsafe = {
- .type = CALLBACKTYPE_failsafe,
- .address = (unsigned long)failsafe_callback
- };
+ cbr.type = CALLBACKTYPE_event;
+ cbr.address = (unsigned long)Xhypervisor_callback;
+ PANIC_IF(HYPERVISOR_callback_op(CALLBACKOP_register, &cbr));
+
+
+ cbr.type = CALLBACKTYPE_failsafe;
+ cbr.address = (unsigned long)failsafe_callback;
- PANIC_IF(HYPERVISOR_callback_op(CALLBACKOP_register, &event));
+ PANIC_IF(HYPERVISOR_callback_op(CALLBACKOP_register, &cbr));
- PANIC_IF(HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe));
+ cbr.type = CALLBACKTYPE_syscall;
+ cbr.address = (unsigned long)Xsyscall_callback;
- /* XXX: syscall */
+ PANIC_IF(HYPERVISOR_callback_op(CALLBACKOP_register, &cbr));
+
+ /* XXX: syscall32, sysenter */
}
#define XEN_CPUID_LEAF_HYPERCALL XEN_CPUID_LEAF(3 - 1)
@@ -540,7 +544,14 @@ initxen(struct start_info *si)
bzero(msgbufp, msgbufsize);
msgbufinit(msgbufp, msgbufsize);
- //fpuinit(); XXX: TODO
+
+ /* Enable write permissions for code patching */
+ static vm_offset_t xsave_cpage;
+ xsave_cpage = (vm_offset_t) ctx_switch_xsave & ~PAGE_MASK;
+ PT_SET_MA(xsave_cpage, phystomach(VTOP(xsave_cpage)) | PG_V | PG_U | PG_RW);
+ fpuinit();
+ PT_SET_MA(xsave_cpage, phystomach(VTOP(xsave_cpage)) | PG_V | PG_U);
+
/*
* Set up thread0 pcb after fpuinit calculated pcb + fpu save
More information about the svn-src-projects
mailing list