jmp HYPERCALL_iret
ENDFUNC(entry_SYSCALL)
+
+ENTRY(entry_SYSENTER)
+ push $0
+ push $0x200
+
+ push %es
+ push %ds
+
+ SAVE_ALL
+
+ mov $__KERN_DS, %eax /* Restore data segments. */
+ mov %eax, %ds
+ mov %eax, %es
+
+ push %esp /* struct cpu_regs * */
+ call do_sysenter
+ add $4, %esp
+
+ RESTORE_ALL
+
+ pop %ds
+ pop %es
+
+ add $8, %esp /* Pop error_code/entry_vector. */
+
+ jmp HYPERCALL_iret
+ENDFUNC(entry_SYSENTER)
#endif
/*
jmp HYPERCALL_iret
ENDFUNC(entry_SYSCALL)
+
+ENTRY(entry_SYSENTER)
+ env_ADJUST_FRAME
+
+ push $0
+ movl $0x200, 4(%rsp)
+
+ SAVE_ALL
+
+ mov %rsp, %rdi /* struct cpu_regs * */
+ call do_sysenter
+
+ RESTORE_ALL
+
+ movq $0, (%rsp) /* Clobber error_code/entry_vector */
+ jmp HYPERCALL_iret
+
+ENDFUNC(entry_SYSENTER)
#endif /* CONFIG_PV */
/*
*/
void do_syscall(struct cpu_regs *regs);
+/**
+ * May be implemented by a guest to handle SYSENTER invocations.
+ */
+void do_sysenter(struct cpu_regs *regs);
+
/**
* May be implemented by a guest to handle Event Channel upcalls.
*/
void entry_ret_to_kernel(void);
void entry_SYSCALL(void);
+void entry_SYSENTER(void);
void entry_EVTCHN(void);
struct xen_trap_info pv_default_trap_info[] =
.flags = CALLBACKF_mask_events,
.address = INIT_XEN_CALLBACK(__KERN_CS, _u(entry_SYSCALL)),
},
+ {
+ .type = CALLBACKTYPE_sysenter,
+ .flags = CALLBACKF_mask_events,
+ .address = INIT_XEN_CALLBACK(__KERN_CS, _u(entry_SYSENTER)),
+ },
};
for ( unsigned int i = 0; i < ARRAY_SIZE(cb); ++i )
panic("Unhandled syscall\n");
}
+void __weak do_sysenter(struct cpu_regs *regs)
+{
+ panic("Unhandled sysenter\n");
+}
+
void __weak do_evtchn(struct cpu_regs *regs)
{
panic("Unhandled evtchn upcall\n");