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