1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- #include <linux/linkage.h>
- #include <linux/errno.h>
- #include <asm/asm.h>
- #include <asm/msr.h>
- #ifdef CONFIG_X86_64
- /*
- * int {rdmsr,wrmsr}_safe_regs(u32 gprs[8]);
- *
- * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi]
- *
- */
- .macro op_safe_regs op
- ENTRY(\op\()_safe_regs)
- pushq %rbx
- pushq %rbp
- movq %rdi, %r10 /* Save pointer */
- xorl %r11d, %r11d /* Return value */
- movl (%rdi), %eax
- movl 4(%rdi), %ecx
- movl 8(%rdi), %edx
- movl 12(%rdi), %ebx
- movl 20(%rdi), %ebp
- movl 24(%rdi), %esi
- movl 28(%rdi), %edi
- 1: \op
- 2: movl %eax, (%r10)
- movl %r11d, %eax /* Return value */
- movl %ecx, 4(%r10)
- movl %edx, 8(%r10)
- movl %ebx, 12(%r10)
- movl %ebp, 20(%r10)
- movl %esi, 24(%r10)
- movl %edi, 28(%r10)
- popq %rbp
- popq %rbx
- ret
- 3:
- movl $-EIO, %r11d
- jmp 2b
- _ASM_EXTABLE(1b, 3b)
- ENDPROC(\op\()_safe_regs)
- .endm
- #else /* X86_32 */
- .macro op_safe_regs op
- ENTRY(\op\()_safe_regs)
- pushl %ebx
- pushl %ebp
- pushl %esi
- pushl %edi
- pushl $0 /* Return value */
- pushl %eax
- movl 4(%eax), %ecx
- movl 8(%eax), %edx
- movl 12(%eax), %ebx
- movl 20(%eax), %ebp
- movl 24(%eax), %esi
- movl 28(%eax), %edi
- movl (%eax), %eax
- 1: \op
- 2: pushl %eax
- movl 4(%esp), %eax
- popl (%eax)
- addl $4, %esp
- movl %ecx, 4(%eax)
- movl %edx, 8(%eax)
- movl %ebx, 12(%eax)
- movl %ebp, 20(%eax)
- movl %esi, 24(%eax)
- movl %edi, 28(%eax)
- popl %eax
- popl %edi
- popl %esi
- popl %ebp
- popl %ebx
- ret
- 3:
- movl $-EIO, 4(%esp)
- jmp 2b
- _ASM_EXTABLE(1b, 3b)
- ENDPROC(\op\()_safe_regs)
- .endm
- #endif
- op_safe_regs rdmsr
- op_safe_regs wrmsr
|