OpenCloudOS-Kernel/arch/x86/platform/efi/efi_stub_64.S

58 lines
1.1 KiB
ArmAsm
Raw Normal View History

/*
* Function calling ABI conversion from Linux to EFI for x86_64
*
* Copyright (C) 2007 Intel Corp
* Bibo Mao <bibo.mao@intel.com>
* Huang Ying <ying.huang@intel.com>
*/
#include <linux/linkage.h>
#include <asm/segment.h>
#include <asm/msr.h>
#include <asm/processor-flags.h>
#include <asm/page_types.h>
#define SAVE_XMM \
mov %rsp, %rax; \
subq $0x70, %rsp; \
and $~0xf, %rsp; \
mov %rax, (%rsp); \
mov %cr0, %rax; \
clts; \
mov %rax, 0x8(%rsp); \
movaps %xmm0, 0x60(%rsp); \
movaps %xmm1, 0x50(%rsp); \
movaps %xmm2, 0x40(%rsp); \
movaps %xmm3, 0x30(%rsp); \
movaps %xmm4, 0x20(%rsp); \
movaps %xmm5, 0x10(%rsp)
#define RESTORE_XMM \
movaps 0x60(%rsp), %xmm0; \
movaps 0x50(%rsp), %xmm1; \
movaps 0x40(%rsp), %xmm2; \
movaps 0x30(%rsp), %xmm3; \
movaps 0x20(%rsp), %xmm4; \
movaps 0x10(%rsp), %xmm5; \
mov 0x8(%rsp), %rsi; \
mov %rsi, %cr0; \
mov (%rsp), %rsp
ENTRY(efi_call)
x86/efi: Fix 7-parameter efi_call()s Alex Thorlton reported that the SGI/UV code crashes in the efi_call() code when invoked with 7 parameters, due to: mov (%rsp), %rax mov 8(%rax), %rax ... mov %rax, 40(%rsp) Offset 8 is only true if CONFIG_FRAME_POINTERS is disabled, with frame pointers enabled it should be 16. Furthermore, the SAVE_XMM code saves the old stack pointer, but that's just crazy. It saves the stack pointer *AFTER* we've done the: FRAME_BEGIN ... which will have *changed* the stack pointer, depending on whether stack frames are enabled or not. So when the code then does: mov (%rsp), %rax ... we now move that old stack pointer into %rax, but the offset off that stack pointer will depend on whether that FRAME_BEGIN saved off %rbp or not. So that whole 8-vs-16 offset confusion depends on the frame pointer! If frame pointers were enabled, it will be 16. If they weren't, it will be 8. The right fix is to just get rid of that silly conditional frame pointer thing, and always use frame pointers in this stub function. And then we don't need that (odd) load to get the old stack pointer into %rax - we can just use the frame pointer. Reported-by: Alex Thorlton <athorlton@sgi.com> Tested-by: Alex Thorlton <athorlton@sgi.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Matt Fleming <matt@codeblueprint.co.uk> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vince Weaver <vincent.weaver@maine.edu> Link: http://lkml.kernel.org/r/CA%2B55aFzBS2v%3DWnEH83cUDg7XkOremFqJ30BJwF40dCYjReBkUQ@mail.gmail.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
2016-05-17 04:05:45 +08:00
pushq %rbp
movq %rsp, %rbp
SAVE_XMM
x86/efi: Fix 7-parameter efi_call()s Alex Thorlton reported that the SGI/UV code crashes in the efi_call() code when invoked with 7 parameters, due to: mov (%rsp), %rax mov 8(%rax), %rax ... mov %rax, 40(%rsp) Offset 8 is only true if CONFIG_FRAME_POINTERS is disabled, with frame pointers enabled it should be 16. Furthermore, the SAVE_XMM code saves the old stack pointer, but that's just crazy. It saves the stack pointer *AFTER* we've done the: FRAME_BEGIN ... which will have *changed* the stack pointer, depending on whether stack frames are enabled or not. So when the code then does: mov (%rsp), %rax ... we now move that old stack pointer into %rax, but the offset off that stack pointer will depend on whether that FRAME_BEGIN saved off %rbp or not. So that whole 8-vs-16 offset confusion depends on the frame pointer! If frame pointers were enabled, it will be 16. If they weren't, it will be 8. The right fix is to just get rid of that silly conditional frame pointer thing, and always use frame pointers in this stub function. And then we don't need that (odd) load to get the old stack pointer into %rax - we can just use the frame pointer. Reported-by: Alex Thorlton <athorlton@sgi.com> Tested-by: Alex Thorlton <athorlton@sgi.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Matt Fleming <matt@codeblueprint.co.uk> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vince Weaver <vincent.weaver@maine.edu> Link: http://lkml.kernel.org/r/CA%2B55aFzBS2v%3DWnEH83cUDg7XkOremFqJ30BJwF40dCYjReBkUQ@mail.gmail.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
2016-05-17 04:05:45 +08:00
mov 16(%rbp), %rax
subq $48, %rsp
mov %r9, 32(%rsp)
mov %rax, 40(%rsp)
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $48, %rsp
RESTORE_XMM
x86/efi: Fix 7-parameter efi_call()s Alex Thorlton reported that the SGI/UV code crashes in the efi_call() code when invoked with 7 parameters, due to: mov (%rsp), %rax mov 8(%rax), %rax ... mov %rax, 40(%rsp) Offset 8 is only true if CONFIG_FRAME_POINTERS is disabled, with frame pointers enabled it should be 16. Furthermore, the SAVE_XMM code saves the old stack pointer, but that's just crazy. It saves the stack pointer *AFTER* we've done the: FRAME_BEGIN ... which will have *changed* the stack pointer, depending on whether stack frames are enabled or not. So when the code then does: mov (%rsp), %rax ... we now move that old stack pointer into %rax, but the offset off that stack pointer will depend on whether that FRAME_BEGIN saved off %rbp or not. So that whole 8-vs-16 offset confusion depends on the frame pointer! If frame pointers were enabled, it will be 16. If they weren't, it will be 8. The right fix is to just get rid of that silly conditional frame pointer thing, and always use frame pointers in this stub function. And then we don't need that (odd) load to get the old stack pointer into %rax - we can just use the frame pointer. Reported-by: Alex Thorlton <athorlton@sgi.com> Tested-by: Alex Thorlton <athorlton@sgi.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Matt Fleming <matt@codeblueprint.co.uk> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vince Weaver <vincent.weaver@maine.edu> Link: http://lkml.kernel.org/r/CA%2B55aFzBS2v%3DWnEH83cUDg7XkOremFqJ30BJwF40dCYjReBkUQ@mail.gmail.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
2016-05-17 04:05:45 +08:00
popq %rbp
ret
ENDPROC(efi_call)