blob: f6d13eefad1063d5e525dbc0cfff1ccc12b34bc9 [file] [log] [blame]
Borislav Petkov132ec922009-08-31 09:50:09 +02001#include <linux/linkage.h>
2#include <linux/errno.h>
H. Peter Anvin79c5dca2009-08-31 13:59:53 -07003#include <asm/dwarf2.h>
Borislav Petkov132ec922009-08-31 09:50:09 +02004#include <asm/asm.h>
5#include <asm/msr.h>
6
7#ifdef CONFIG_X86_64
8/*
Andre Przywara1f975f72012-06-01 16:52:35 +02009 * int {rdmsr,wrmsr}_safe_regs(u32 gprs[8]);
Borislav Petkov132ec922009-08-31 09:50:09 +020010 *
11 * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi]
12 *
13 */
H. Peter Anvinf6909f32009-09-01 13:31:52 -070014.macro op_safe_regs op
Andre Przywara1f975f72012-06-01 16:52:35 +020015ENTRY(\op\()_safe_regs)
H. Peter Anvin79c5dca2009-08-31 13:59:53 -070016 CFI_STARTPROC
17 pushq_cfi %rbx
18 pushq_cfi %rbp
19 movq %rdi, %r10 /* Save pointer */
20 xorl %r11d, %r11d /* Return value */
Borislav Petkov132ec922009-08-31 09:50:09 +020021 movl (%rdi), %eax
22 movl 4(%rdi), %ecx
23 movl 8(%rdi), %edx
24 movl 12(%rdi), %ebx
25 movl 20(%rdi), %ebp
26 movl 24(%rdi), %esi
27 movl 28(%rdi), %edi
H. Peter Anvin79c5dca2009-08-31 13:59:53 -070028 CFI_REMEMBER_STATE
Borislav Petkov132ec922009-08-31 09:50:09 +0200291: \op
H. Peter Anvin79c5dca2009-08-31 13:59:53 -0700302: movl %eax, (%r10)
31 movl %r11d, %eax /* Return value */
32 movl %ecx, 4(%r10)
33 movl %edx, 8(%r10)
34 movl %ebx, 12(%r10)
35 movl %ebp, 20(%r10)
36 movl %esi, 24(%r10)
37 movl %edi, 28(%r10)
38 popq_cfi %rbp
39 popq_cfi %rbx
Borislav Petkov132ec922009-08-31 09:50:09 +020040 ret
413:
H. Peter Anvin79c5dca2009-08-31 13:59:53 -070042 CFI_RESTORE_STATE
43 movl $-EIO, %r11d
Borislav Petkov132ec922009-08-31 09:50:09 +020044 jmp 2b
H. Peter Anvin79c5dca2009-08-31 13:59:53 -070045
46 _ASM_EXTABLE(1b, 3b)
47 CFI_ENDPROC
Andre Przywara1f975f72012-06-01 16:52:35 +020048ENDPROC(\op\()_safe_regs)
Borislav Petkov132ec922009-08-31 09:50:09 +020049.endm
50
51#else /* X86_32 */
52
Ingo Molnar8adf65c2009-09-03 21:26:34 +020053.macro op_safe_regs op
Andre Przywara1f975f72012-06-01 16:52:35 +020054ENTRY(\op\()_safe_regs)
H. Peter Anvin79c5dca2009-08-31 13:59:53 -070055 CFI_STARTPROC
56 pushl_cfi %ebx
57 pushl_cfi %ebp
58 pushl_cfi %esi
59 pushl_cfi %edi
60 pushl_cfi $0 /* Return value */
61 pushl_cfi %eax
Borislav Petkov132ec922009-08-31 09:50:09 +020062 movl 4(%eax), %ecx
63 movl 8(%eax), %edx
64 movl 12(%eax), %ebx
65 movl 20(%eax), %ebp
66 movl 24(%eax), %esi
67 movl 28(%eax), %edi
68 movl (%eax), %eax
H. Peter Anvin79c5dca2009-08-31 13:59:53 -070069 CFI_REMEMBER_STATE
Borislav Petkov132ec922009-08-31 09:50:09 +0200701: \op
H. Peter Anvin79c5dca2009-08-31 13:59:53 -0700712: pushl_cfi %eax
Borislav Petkov132ec922009-08-31 09:50:09 +020072 movl 4(%esp), %eax
H. Peter Anvin79c5dca2009-08-31 13:59:53 -070073 popl_cfi (%eax)
Borislav Petkov132ec922009-08-31 09:50:09 +020074 addl $4, %esp
H. Peter Anvin79c5dca2009-08-31 13:59:53 -070075 CFI_ADJUST_CFA_OFFSET -4
Borislav Petkov132ec922009-08-31 09:50:09 +020076 movl %ecx, 4(%eax)
77 movl %edx, 8(%eax)
78 movl %ebx, 12(%eax)
79 movl %ebp, 20(%eax)
80 movl %esi, 24(%eax)
81 movl %edi, 28(%eax)
H. Peter Anvin79c5dca2009-08-31 13:59:53 -070082 popl_cfi %eax
83 popl_cfi %edi
84 popl_cfi %esi
85 popl_cfi %ebp
86 popl_cfi %ebx
Borislav Petkov132ec922009-08-31 09:50:09 +020087 ret
883:
H. Peter Anvin79c5dca2009-08-31 13:59:53 -070089 CFI_RESTORE_STATE
Borislav Petkov132ec922009-08-31 09:50:09 +020090 movl $-EIO, 4(%esp)
91 jmp 2b
H. Peter Anvin79c5dca2009-08-31 13:59:53 -070092
93 _ASM_EXTABLE(1b, 3b)
94 CFI_ENDPROC
Andre Przywara1f975f72012-06-01 16:52:35 +020095ENDPROC(\op\()_safe_regs)
Borislav Petkov132ec922009-08-31 09:50:09 +020096.endm
97
98#endif
99
100op_safe_regs rdmsr
101op_safe_regs wrmsr
102