xref: /OK3568_Linux_fs/kernel/arch/x86/lib/msr-reg.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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