| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 1 | #include <linux/linkage.h> | 
|  | 2 | #include <linux/errno.h> | 
| H. Peter Anvin | 79c5dca | 2009-08-31 13:59:53 -0700 | [diff] [blame] | 3 | #include <asm/dwarf2.h> | 
| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 4 | #include <asm/asm.h> | 
|  | 5 | #include <asm/msr.h> | 
|  | 6 |  | 
|  | 7 | #ifdef CONFIG_X86_64 | 
|  | 8 | /* | 
|  | 9 | * int native_{rdmsr,wrmsr}_safe_regs(u32 gprs[8]); | 
|  | 10 | * | 
|  | 11 | * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi] | 
|  | 12 | * | 
|  | 13 | */ | 
| H. Peter Anvin | f6909f3 | 2009-09-01 13:31:52 -0700 | [diff] [blame] | 14 | .macro op_safe_regs op | 
| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 15 | ENTRY(native_\op\()_safe_regs) | 
| H. Peter Anvin | 79c5dca | 2009-08-31 13:59:53 -0700 | [diff] [blame] | 16 | CFI_STARTPROC | 
|  | 17 | pushq_cfi %rbx | 
|  | 18 | pushq_cfi %rbp | 
|  | 19 | movq	%rdi, %r10	/* Save pointer */ | 
|  | 20 | xorl	%r11d, %r11d	/* Return value */ | 
| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 21 | 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 Anvin | 79c5dca | 2009-08-31 13:59:53 -0700 | [diff] [blame] | 28 | CFI_REMEMBER_STATE | 
| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 29 | 1:	\op | 
| H. Peter Anvin | 79c5dca | 2009-08-31 13:59:53 -0700 | [diff] [blame] | 30 | 2:	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 Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 40 | ret | 
|  | 41 | 3: | 
| H. Peter Anvin | 79c5dca | 2009-08-31 13:59:53 -0700 | [diff] [blame] | 42 | CFI_RESTORE_STATE | 
|  | 43 | movl    $-EIO, %r11d | 
| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 44 | jmp     2b | 
| H. Peter Anvin | 79c5dca | 2009-08-31 13:59:53 -0700 | [diff] [blame] | 45 |  | 
|  | 46 | _ASM_EXTABLE(1b, 3b) | 
|  | 47 | CFI_ENDPROC | 
| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 48 | ENDPROC(native_\op\()_safe_regs) | 
|  | 49 | .endm | 
|  | 50 |  | 
|  | 51 | #else /* X86_32 */ | 
|  | 52 |  | 
| Ingo Molnar | 8adf65c | 2009-09-03 21:26:34 +0200 | [diff] [blame] | 53 | .macro op_safe_regs op | 
| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 54 | ENTRY(native_\op\()_safe_regs) | 
| H. Peter Anvin | 79c5dca | 2009-08-31 13:59:53 -0700 | [diff] [blame] | 55 | 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 Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 62 | 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 Anvin | 79c5dca | 2009-08-31 13:59:53 -0700 | [diff] [blame] | 69 | CFI_REMEMBER_STATE | 
| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 70 | 1:	\op | 
| H. Peter Anvin | 79c5dca | 2009-08-31 13:59:53 -0700 | [diff] [blame] | 71 | 2:	pushl_cfi %eax | 
| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 72 | movl    4(%esp), %eax | 
| H. Peter Anvin | 79c5dca | 2009-08-31 13:59:53 -0700 | [diff] [blame] | 73 | popl_cfi (%eax) | 
| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 74 | addl    $4, %esp | 
| H. Peter Anvin | 79c5dca | 2009-08-31 13:59:53 -0700 | [diff] [blame] | 75 | CFI_ADJUST_CFA_OFFSET -4 | 
| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 76 | 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 Anvin | 79c5dca | 2009-08-31 13:59:53 -0700 | [diff] [blame] | 82 | popl_cfi %eax | 
|  | 83 | popl_cfi %edi | 
|  | 84 | popl_cfi %esi | 
|  | 85 | popl_cfi %ebp | 
|  | 86 | popl_cfi %ebx | 
| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 87 | ret | 
|  | 88 | 3: | 
| H. Peter Anvin | 79c5dca | 2009-08-31 13:59:53 -0700 | [diff] [blame] | 89 | CFI_RESTORE_STATE | 
| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 90 | movl    $-EIO, 4(%esp) | 
|  | 91 | jmp     2b | 
| H. Peter Anvin | 79c5dca | 2009-08-31 13:59:53 -0700 | [diff] [blame] | 92 |  | 
|  | 93 | _ASM_EXTABLE(1b, 3b) | 
|  | 94 | CFI_ENDPROC | 
| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 95 | ENDPROC(native_\op\()_safe_regs) | 
|  | 96 | .endm | 
|  | 97 |  | 
|  | 98 | #endif | 
|  | 99 |  | 
|  | 100 | op_safe_regs rdmsr | 
|  | 101 | op_safe_regs wrmsr | 
|  | 102 |  |