1/* SPDX-License-Identifier: GPL-2.0 */ 2#include <linux/linkage.h> 3#include <linux/errno.h> 4#include <linux/cfi_types.h> 5#include <asm/asm.h> 6#include <asm/msr.h> 7 8#ifdef CONFIG_X86_64 9/* 10 * int {rdmsr,wrmsr}_safe_regs(u32 gprs[8]); 11 * 12 * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi] 13 * 14 */ 15.macro op_safe_regs op 16SYM_TYPED_FUNC_START(\op\()_safe_regs) 17 pushq %rbx 18 pushq %r12 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), %r12d 26 movl 24(%rdi), %esi 27 movl 28(%rdi), %edi 281: \op 292: movl %eax, (%r10) 30 movl %r11d, %eax /* Return value */ 31 movl %ecx, 4(%r10) 32 movl %edx, 8(%r10) 33 movl %ebx, 12(%r10) 34 movl %r12d, 20(%r10) 35 movl %esi, 24(%r10) 36 movl %edi, 28(%r10) 37 popq %r12 38 popq %rbx 39 RET 403: 41 movl $-EIO, %r11d 42 jmp 2b 43 44 _ASM_EXTABLE(1b, 3b) 45SYM_FUNC_END(\op\()_safe_regs) 46.endm 47 48#else /* X86_32 */ 49 50.macro op_safe_regs op 51SYM_FUNC_START(\op\()_safe_regs) 52 pushl %ebx 53 pushl %ebp 54 pushl %esi 55 pushl %edi 56 pushl $0 /* Return value */ 57 pushl %eax 58 movl 4(%eax), %ecx 59 movl 8(%eax), %edx 60 movl 12(%eax), %ebx 61 movl 20(%eax), %ebp 62 movl 24(%eax), %esi 63 movl 28(%eax), %edi 64 movl (%eax), %eax 651: \op 662: pushl %eax 67 movl 4(%esp), %eax 68 popl (%eax) 69 addl $4, %esp 70 movl %ecx, 4(%eax) 71 movl %edx, 8(%eax) 72 movl %ebx, 12(%eax) 73 movl %ebp, 20(%eax) 74 movl %esi, 24(%eax) 75 movl %edi, 28(%eax) 76 popl %eax 77 popl %edi 78 popl %esi 79 popl %ebp 80 popl %ebx 81 RET 823: 83 movl $-EIO, 4(%esp) 84 jmp 2b 85 86 _ASM_EXTABLE(1b, 3b) 87SYM_FUNC_END(\op\()_safe_regs) 88.endm 89 90#endif 91 92op_safe_regs rdmsr 93op_safe_regs wrmsr 94 95