diff options
Diffstat (limited to 'arch/x86_64/lib/copy_page.S')
-rw-r--r-- | arch/x86_64/lib/copy_page.S | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/arch/x86_64/lib/copy_page.S b/arch/x86_64/lib/copy_page.S index 8fa19d96a7ee..0ebb03b60e79 100644 --- a/arch/x86_64/lib/copy_page.S +++ b/arch/x86_64/lib/copy_page.S | |||
@@ -1,17 +1,33 @@ | |||
1 | /* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */ | 1 | /* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */ |
2 | 2 | ||
3 | #include <linux/config.h> | ||
4 | #include <linux/linkage.h> | ||
5 | #include <asm/dwarf2.h> | ||
6 | |||
7 | ALIGN | ||
8 | copy_page_c: | ||
9 | CFI_STARTPROC | ||
10 | movl $4096/8,%ecx | ||
11 | rep movsq | ||
12 | ret | ||
13 | CFI_ENDPROC | ||
14 | ENDPROC(copy_page_c) | ||
15 | |||
3 | /* Don't use streaming store because it's better when the target | 16 | /* Don't use streaming store because it's better when the target |
4 | ends up in cache. */ | 17 | ends up in cache. */ |
5 | 18 | ||
6 | /* Could vary the prefetch distance based on SMP/UP */ | 19 | /* Could vary the prefetch distance based on SMP/UP */ |
7 | 20 | ||
8 | .globl copy_page | 21 | ENTRY(copy_page) |
9 | .p2align 4 | 22 | CFI_STARTPROC |
10 | copy_page: | ||
11 | subq $3*8,%rsp | 23 | subq $3*8,%rsp |
24 | CFI_ADJUST_CFA_OFFSET 3*8 | ||
12 | movq %rbx,(%rsp) | 25 | movq %rbx,(%rsp) |
26 | CFI_REL_OFFSET rbx, 0 | ||
13 | movq %r12,1*8(%rsp) | 27 | movq %r12,1*8(%rsp) |
28 | CFI_REL_OFFSET r12, 1*8 | ||
14 | movq %r13,2*8(%rsp) | 29 | movq %r13,2*8(%rsp) |
30 | CFI_REL_OFFSET r13, 2*8 | ||
15 | 31 | ||
16 | movl $(4096/64)-5,%ecx | 32 | movl $(4096/64)-5,%ecx |
17 | .p2align 4 | 33 | .p2align 4 |
@@ -72,30 +88,33 @@ copy_page: | |||
72 | jnz .Loop2 | 88 | jnz .Loop2 |
73 | 89 | ||
74 | movq (%rsp),%rbx | 90 | movq (%rsp),%rbx |
91 | CFI_RESTORE rbx | ||
75 | movq 1*8(%rsp),%r12 | 92 | movq 1*8(%rsp),%r12 |
93 | CFI_RESTORE r12 | ||
76 | movq 2*8(%rsp),%r13 | 94 | movq 2*8(%rsp),%r13 |
95 | CFI_RESTORE r13 | ||
77 | addq $3*8,%rsp | 96 | addq $3*8,%rsp |
97 | CFI_ADJUST_CFA_OFFSET -3*8 | ||
78 | ret | 98 | ret |
99 | .Lcopy_page_end: | ||
100 | CFI_ENDPROC | ||
101 | ENDPROC(copy_page) | ||
79 | 102 | ||
80 | /* Some CPUs run faster using the string copy instructions. | 103 | /* Some CPUs run faster using the string copy instructions. |
81 | It is also a lot simpler. Use this when possible */ | 104 | It is also a lot simpler. Use this when possible */ |
82 | 105 | ||
83 | #include <asm/cpufeature.h> | 106 | #include <asm/cpufeature.h> |
84 | 107 | ||
108 | .section .altinstr_replacement,"ax" | ||
109 | 1: .byte 0xeb /* jmp <disp8> */ | ||
110 | .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */ | ||
111 | 2: | ||
112 | .previous | ||
85 | .section .altinstructions,"a" | 113 | .section .altinstructions,"a" |
86 | .align 8 | 114 | .align 8 |
87 | .quad copy_page | 115 | .quad copy_page |
88 | .quad copy_page_c | 116 | .quad 1b |
89 | .byte X86_FEATURE_REP_GOOD | 117 | .byte X86_FEATURE_REP_GOOD |
90 | .byte copy_page_c_end-copy_page_c | 118 | .byte .Lcopy_page_end - copy_page |
91 | .byte copy_page_c_end-copy_page_c | 119 | .byte 2b - 1b |
92 | .previous | ||
93 | |||
94 | .section .altinstr_replacement,"ax" | ||
95 | copy_page_c: | ||
96 | movl $4096/8,%ecx | ||
97 | rep | ||
98 | movsq | ||
99 | ret | ||
100 | copy_page_c_end: | ||
101 | .previous | 120 | .previous |