SYSENTER/SYSCALL support

. add cpufeature detection of both
	. use it for both ipc and kernelcall traps, using a register
	  for call number
	. SYSENTER/SYSCALL does not save any context, therefore userland
	  has to save it
	. to accomodate multiple kernel entry/exit types, the entry
	  type is recorded in the process struct. hitherto all types
	  were interrupt (soft int, exception, hard int); now SYSENTER/SYSCALL
	  is new, with the difference that context is not fully restored
	  from proc struct when running the process again. this can't be
	  done as some information is missing.
	. complication: cases in which the kernel has to fully change
	  process context (i.e. sigreturn). in that case the exit type
	  is changed from SYSENTER/SYSEXIT to soft-int (i.e. iret) and
	  context is fully restored from the proc struct. this does mean
	  the PC and SP must change, as the sysenter/sysexit userland code
	  will otherwise try to restore its own context. this is true in the
	  sigreturn case.
	. override all usage by setting libc_ipc=1
This commit is contained in:
Ben Gras
2012-06-10 17:50:17 +00:00
parent 629829e69c
commit 2d72cbec41
38 changed files with 643 additions and 79 deletions

View File

@@ -47,10 +47,25 @@ void alignment_check(void);
void machine_check(void);
void simd_exception(void);
void restore_user_context_int(struct proc *);
void restore_user_context_sysenter(struct proc *);
void restore_user_context_syscall(struct proc *);
/* Software interrupt handlers, in numerical order. */
void trp(void);
void ipc_entry(void);
void kernel_call_entry(void);
void ipc_entry_softint_orig(void);
void ipc_entry_softint_um(void);
void ipc_entry_sysenter(void);
void ipc_entry_syscall_cpu0(void);
void ipc_entry_syscall_cpu1(void);
void ipc_entry_syscall_cpu2(void);
void ipc_entry_syscall_cpu3(void);
void ipc_entry_syscall_cpu4(void);
void ipc_entry_syscall_cpu5(void);
void ipc_entry_syscall_cpu6(void);
void ipc_entry_syscall_cpu7(void);
void kernel_call_entry_orig(void);
void kernel_call_entry_um(void);
void level0_call(void);
/* exception.c */
@@ -111,6 +126,30 @@ void x86_load_es(u32_t);
void x86_load_fs(u32_t);
void x86_load_gs(u32_t);
/* ipc functions in usermapped_ipc.S */
int usermapped_send_softint(endpoint_t dest, message *m_ptr);
int usermapped_receive_softint(endpoint_t src, message *m_ptr, int *status_ptr);
int usermapped_sendrec_softint(endpoint_t src_dest, message *m_ptr);
int usermapped_sendnb_softint(endpoint_t dest, message *m_ptr);
int usermapped_notify_softint(endpoint_t dest);
int usermapped_do_kernel_call_softint(message *m_ptr);
int usermapped_senda_softint(asynmsg_t *table, size_t count);
int usermapped_send_syscall(endpoint_t dest, message *m_ptr);
int usermapped_receive_syscall(endpoint_t src, message *m_ptr, int *status_ptr);
int usermapped_sendrec_syscall(endpoint_t src_dest, message *m_ptr);
int usermapped_sendnb_syscall(endpoint_t dest, message *m_ptr);
int usermapped_notify_syscall(endpoint_t dest);
int usermapped_do_kernel_call_syscall(message *m_ptr);
int usermapped_senda_syscall(asynmsg_t *table, size_t count);
int usermapped_send_sysenter(endpoint_t dest, message *m_ptr);
int usermapped_receive_sysenter(endpoint_t src, message *m_ptr, int *status_ptr);
int usermapped_sendrec_sysenter(endpoint_t src_dest, message *m_ptr);
int usermapped_sendnb_sysenter(endpoint_t dest, message *m_ptr);
int usermapped_notify_sysenter(endpoint_t dest);
int usermapped_do_kernel_call_sysenter(message *m_ptr);
int usermapped_senda_sysenter(asynmsg_t *table, size_t count);
void switch_k_stack(void * esp, void (* continuation)(void));

View File

@@ -150,4 +150,26 @@
#define PG_ALLOCATEME ((phys_bytes)-1)
/* MSRs */
#define INTEL_MSR_PERFMON_CRT0 0xc1
#define INTEL_MSR_SYSENTER_CS 0x174
#define INTEL_MSR_SYSENTER_ESP 0x175
#define INTEL_MSR_SYSENTER_EIP 0x176
#define INTEL_MSR_PERFMON_SEL0 0x186
#define INTEL_MSR_PERFMON_SEL0_ENABLE (1 << 22)
#define AMD_EFER_SCE (1L << 0) /* SYSCALL/SYSRET enabled */
#define AMD_MSR_EFER 0xC0000080 /* extended features msr */
#define AMD_MSR_STAR 0xC0000081 /* SYSCALL params msr */
/* trap styles recorded on kernel entry and exit */
#define KTS_NONE 1 /* invalid */
#define KTS_INT_HARD 2 /* exception / hard interrupt */
#define KTS_INT_ORIG 3 /* soft interrupt from libc */
#define KTS_INT_UM 4 /* soft interrupt from usermapped code */
#define KTS_FULLCONTEXT 5 /* must restore full context */
#define KTS_SYSENTER 6 /* SYSENTER instruction (usermapped) */
#define KTS_SYSCALL 7 /* SYSCALL instruction (usermapped) */
#endif /* _I386_ACONST_H */