In EFI calling convention, %xmm0 - %xmm5 are specified as the scratch registers (UEFI Specification 2.1, 2.3.4.2). To conforms to EFI specification, this patch save/restore %xmm0 - %xmm5 registers before/after invoking EFI runtime service. At the same time, the stack is aligned in 16 bytes, and TS in CR0 in clear/restore to make it possible to use SSE2 in EFI runtime service.
This patch is based on 2.6.24-rc4-mm1. And it has been tested on Intel platforms with 64-bit UEFI 2.0 firmware. Signed-off-by: Huang Ying <[EMAIL PROTECTED]> --- arch/x86/kernel/efi_stub_64.S | 71 +++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 15 deletions(-) --- a/arch/x86/kernel/efi_stub_64.S +++ b/arch/x86/kernel/efi_stub_64.S @@ -8,61 +8,102 @@ #include <linux/linkage.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_call0) - subq $40, %rsp + SAVE_XMM + subq $32, %rsp call *%rdi - addq $40, %rsp + addq $32, %rsp + RESTORE_XMM ret ENTRY(efi_call1) - subq $40, %rsp + SAVE_XMM + subq $32, %rsp mov %rsi, %rcx call *%rdi - addq $40, %rsp + addq $32, %rsp + RESTORE_XMM ret ENTRY(efi_call2) - subq $40, %rsp + SAVE_XMM + subq $32, %rsp mov %rsi, %rcx call *%rdi - addq $40, %rsp + addq $32, %rsp + RESTORE_XMM ret ENTRY(efi_call3) - subq $40, %rsp + SAVE_XMM + subq $32, %rsp mov %rcx, %r8 mov %rsi, %rcx call *%rdi - addq $40, %rsp + addq $32, %rsp + RESTORE_XMM ret ENTRY(efi_call4) - subq $40, %rsp + SAVE_XMM + subq $32, %rsp mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx call *%rdi - addq $40, %rsp + addq $32, %rsp + RESTORE_XMM ret ENTRY(efi_call5) - subq $40, %rsp + SAVE_XMM + subq $48, %rsp mov %r9, 32(%rsp) mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx call *%rdi - addq $40, %rsp + addq $48, %rsp + RESTORE_XMM ret ENTRY(efi_call6) - subq $56, %rsp - mov 56+8(%rsp), %rax + SAVE_XMM + mov (%rsp), %rax + mov 8(%rax), %rax + subq $48, %rsp mov %r9, 32(%rsp) mov %rax, 40(%rsp) mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx call *%rdi - addq $56, %rsp + addq $48, %rsp + RESTORE_XMM ret -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/