1#include <linux/linkage.h> 2#include <linux/errno.h> 3#include <asm/asm.h> 4#include <asm/msr.h> 5 6#ifdef CONFIG_X86_64 7/* 8 * int {rdmsr,wrmsr}_safe_regs(u32 gprs[8]); 9 * 10 * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi] 11 * 12 */ 13.macro op_safe_regs op 14ENTRY(\op\()_safe_regs) 15 pushq %rbx 16 pushq %r12 17 movq %rdi, %r10 /* Save pointer */ 18 xorl %r11d, %r11d /* Return value */ 19 movl (%rdi), %eax 20 movl 4(%rdi), %ecx 21 movl 8(%rdi), %edx 22 movl 12(%rdi), %ebx 23 movl 20(%rdi), %r12d 24 movl 24(%rdi), %esi 25 movl 28(%rdi), %edi 261: \op 272: movl %eax, (%r10) 28 movl %r11d, %eax /* Return value */ 29 movl %ecx, 4(%r10) 30 movl %edx, 8(%r10) 31 movl %ebx, 12(%r10) 32 movl %r12d, 20(%r10) 33 movl %esi, 24(%r10) 34 movl %edi, 28(%r10) 35 popq %r12 36 popq %rbx 37 ret 383: 39 movl $-EIO, %r11d 40 jmp 2b 41 42 _ASM_EXTABLE(1b, 3b) 43ENDPROC(\op\()_safe_regs) 44.endm 45 46#else /* X86_32 */ 47 48.macro op_safe_regs op 49ENTRY(\op\()_safe_regs) 50 pushl %ebx 51 pushl %ebp 52 pushl %esi 53 pushl %edi 54 pushl $0 /* Return value */ 55 pushl %eax 56 movl 4(%eax), %ecx 57 movl 8(%eax), %edx 58 movl 12(%eax), %ebx 59 movl 20(%eax), %ebp 60 movl 24(%eax), %esi 61 movl 28(%eax), %edi 62 movl (%eax), %eax 631: \op 642: pushl %eax 65 movl 4(%esp), %eax 66 popl (%eax) 67 addl $4, %esp 68 movl %ecx, 4(%eax) 69 movl %edx, 8(%eax) 70 movl %ebx, 12(%eax) 71 movl %ebp, 20(%eax) 72 movl %esi, 24(%eax) 73 movl %edi, 28(%eax) 74 popl %eax 75 popl %edi 76 popl %esi 77 popl %ebp 78 popl %ebx 79 ret 803: 81 movl $-EIO, 4(%esp) 82 jmp 2b 83 84 _ASM_EXTABLE(1b, 3b) 85ENDPROC(\op\()_safe_regs) 86.endm 87 88#endif 89 90op_safe_regs rdmsr 91op_safe_regs wrmsr 92 93