1#include <linux/linkage.h> 2#include <linux/errno.h> 3#include <asm/dwarf2.h> 4#include <asm/asm.h> 5#include <asm/msr.h> 6 7#ifdef CONFIG_X86_64 8/* 9 * int {rdmsr,wrmsr}_safe_regs(u32 gprs[8]); 10 * 11 * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi] 12 * 13 */ 14.macro op_safe_regs op 15ENTRY(\op\()_safe_regs) 16 CFI_STARTPROC 17 pushq_cfi_reg rbx 18 pushq_cfi_reg rbp 19 movq %rdi, %r10 /* Save pointer */ 20 xorl %r11d, %r11d /* Return value */ 21 movl (%rdi), %eax 22 movl 4(%rdi), %ecx 23 movl 8(%rdi), %edx 24 movl 12(%rdi), %ebx 25 movl 20(%rdi), %ebp 26 movl 24(%rdi), %esi 27 movl 28(%rdi), %edi 28 CFI_REMEMBER_STATE 291: \op 302: movl %eax, (%r10) 31 movl %r11d, %eax /* Return value */ 32 movl %ecx, 4(%r10) 33 movl %edx, 8(%r10) 34 movl %ebx, 12(%r10) 35 movl %ebp, 20(%r10) 36 movl %esi, 24(%r10) 37 movl %edi, 28(%r10) 38 popq_cfi_reg rbp 39 popq_cfi_reg rbx 40 ret 413: 42 CFI_RESTORE_STATE 43 movl $-EIO, %r11d 44 jmp 2b 45 46 _ASM_EXTABLE(1b, 3b) 47 CFI_ENDPROC 48ENDPROC(\op\()_safe_regs) 49.endm 50 51#else /* X86_32 */ 52 53.macro op_safe_regs op 54ENTRY(\op\()_safe_regs) 55 CFI_STARTPROC 56 pushl_cfi_reg ebx 57 pushl_cfi_reg ebp 58 pushl_cfi_reg esi 59 pushl_cfi_reg edi 60 pushl_cfi $0 /* Return value */ 61 pushl_cfi %eax 62 movl 4(%eax), %ecx 63 movl 8(%eax), %edx 64 movl 12(%eax), %ebx 65 movl 20(%eax), %ebp 66 movl 24(%eax), %esi 67 movl 28(%eax), %edi 68 movl (%eax), %eax 69 CFI_REMEMBER_STATE 701: \op 712: pushl_cfi %eax 72 movl 4(%esp), %eax 73 popl_cfi (%eax) 74 addl $4, %esp 75 CFI_ADJUST_CFA_OFFSET -4 76 movl %ecx, 4(%eax) 77 movl %edx, 8(%eax) 78 movl %ebx, 12(%eax) 79 movl %ebp, 20(%eax) 80 movl %esi, 24(%eax) 81 movl %edi, 28(%eax) 82 popl_cfi %eax 83 popl_cfi_reg edi 84 popl_cfi_reg esi 85 popl_cfi_reg ebp 86 popl_cfi_reg ebx 87 ret 883: 89 CFI_RESTORE_STATE 90 movl $-EIO, 4(%esp) 91 jmp 2b 92 93 _ASM_EXTABLE(1b, 3b) 94 CFI_ENDPROC 95ENDPROC(\op\()_safe_regs) 96.endm 97 98#endif 99 100op_safe_regs rdmsr 101op_safe_regs wrmsr 102 103