From 22cc94bb97f4c9ae3fcd3d3c751db935c8c594a2 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 4 Jan 2008 11:54:37 -0200 Subject: [PATCH] xen-64: xen_iret() use iretq directly if returning to kernel-space Optimization pulled from upstream Xen. Signed-off-by: Eduardo Habkost --- arch/x86/xen/xen-asm.S | 5 ++++ arch/x86/xen/xen-asm_64.S | 49 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 0 deletions(-) diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S index 1c3c0ac..c7356c0 100644 --- a/arch/x86/xen/xen-asm.S +++ b/arch/x86/xen/xen-asm.S @@ -21,6 +21,11 @@ #include #include +#include + +#include +#include + #define RELOC(x, v) .globl x##_reloc; x##_reloc=v #define ENDPATCH(x) .globl x##_end; x##_end=. diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S index 8f28a91..85c235c 100644 --- a/arch/x86/xen/xen-asm_64.S +++ b/arch/x86/xen/xen-asm_64.S @@ -7,7 +7,56 @@ ENTRY(xen_iret_direct) /*FIXME: implement me! */ ud2a +//FIXME: move to calling.h? +#define IRETOFFSET RIP + ENTRY(xen_iret) + /* Are we returning to kernel space? */ + testb $3,CS-IRETOFFSET(%rsp) + jnz xen_iret_slow + +#if 0 + /*FIXME: handle NMI callbacks */ + testl $NMI_MASK,EFLAGS-IRETOFFSET(%rsp) + jnz xen_iret_slow +#endif + + /* If we are going to restore interrupts, we need to + * return through the hypervisor, too. + * + * We may set evtchn_upcall_mask ourselves, but things get complicated + * because we would need to avoid a stack overflow if we get + * interrupts between upcall_mask being cleared and iret being + * executed. + */ + testl $X86_EFLAGS_IF,EFLAGS-IRETOFFSET(%rsp) + jnz xen_iret_slow + + + + /* Returning to kernel (RING0). + * Use direct iret to kernel space after correcting CS and SS + */ + + cmpb $0,(xen_features+XENFEAT_supervisor_mode_kernel)(%rip) + /* supervisor_mode_kernel -> no need to correct CS and SS */ + jne xen_iretq + + /* Direct iret to kernel space. Correct CS and SS. */ + orl $3,CS-IRETOFFSET(%rsp) + orl $3,SS-IRETOFFSET(%rsp) +xen_iretq: + iretq + +xen_iret_slow: + /* Slow iret via hypervisor */ + +#if 0 + /*FIXME: handle NMI callbacks */ + andl $~NMI_MASK, 2*8(%rsp) +#endif + + /* Xen has an additional value in the stack for iret */ /*FIXME: the VGCF_in_syscall flag need to be handled here */ pushq $0 jmp hypercall_page + (__HYPERVISOR_iret * 32) -- 1.5.4.1