]>
Commit | Line | Data |
---|---|---|
3d2efbd9 GKH |
1 | From foo@baz Sat Nov 19 09:52:59 CET 2016 |
2 | From: "David S. Miller" <davem@davemloft.net> | |
3 | Date: Tue, 25 Oct 2016 16:23:26 -0700 | |
4 | Subject: sparc64: Fix illegal relative branches in hypervisor patched TLB code. | |
5 | ||
6 | From: "David S. Miller" <davem@davemloft.net> | |
7 | ||
8 | ||
9 | [ Upstream commit b429ae4d5b565a71dfffd759dfcd4f6c093ced94 ] | |
10 | ||
11 | When we copy code over to patch another piece of code, we can only use | |
12 | PC-relative branches that target code within that piece of code. | |
13 | ||
14 | Such PC-relative branches cannot be made to external symbols because | |
15 | the patch moves the location of the code and thus modifies the | |
16 | relative address of external symbols. | |
17 | ||
18 | Use an absolute jmpl to fix this problem. | |
19 | ||
20 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
21 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
22 | --- | |
23 | arch/sparc/mm/ultra.S | 65 +++++++++++++++++++++++++++++++++++++++----------- | |
24 | 1 file changed, 51 insertions(+), 14 deletions(-) | |
25 | ||
26 | --- a/arch/sparc/mm/ultra.S | |
27 | +++ b/arch/sparc/mm/ultra.S | |
28 | @@ -30,7 +30,7 @@ | |
29 | .text | |
30 | .align 32 | |
31 | .globl __flush_tlb_mm | |
32 | -__flush_tlb_mm: /* 18 insns */ | |
33 | +__flush_tlb_mm: /* 19 insns */ | |
34 | /* %o0=(ctx & TAG_CONTEXT_BITS), %o1=SECONDARY_CONTEXT */ | |
35 | ldxa [%o1] ASI_DMMU, %g2 | |
36 | cmp %g2, %o0 | |
37 | @@ -81,7 +81,7 @@ __flush_tlb_page: /* 22 insns */ | |
38 | ||
39 | .align 32 | |
40 | .globl __flush_tlb_pending | |
41 | -__flush_tlb_pending: /* 26 insns */ | |
42 | +__flush_tlb_pending: /* 27 insns */ | |
43 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ | |
44 | rdpr %pstate, %g7 | |
45 | sllx %o1, 3, %o1 | |
46 | @@ -113,7 +113,7 @@ __flush_tlb_pending: /* 26 insns */ | |
47 | ||
48 | .align 32 | |
49 | .globl __flush_tlb_kernel_range | |
50 | -__flush_tlb_kernel_range: /* 16 insns */ | |
51 | +__flush_tlb_kernel_range: /* 19 insns */ | |
52 | /* %o0=start, %o1=end */ | |
53 | cmp %o0, %o1 | |
54 | be,pn %xcc, 2f | |
55 | @@ -131,6 +131,9 @@ __flush_tlb_kernel_range: /* 16 insns */ | |
56 | retl | |
57 | nop | |
58 | nop | |
59 | + nop | |
60 | + nop | |
61 | + nop | |
62 | ||
63 | __spitfire_flush_tlb_mm_slow: | |
64 | rdpr %pstate, %g1 | |
65 | @@ -309,19 +312,28 @@ __hypervisor_tlb_tl0_error: | |
66 | ret | |
67 | restore | |
68 | ||
69 | -__hypervisor_flush_tlb_mm: /* 10 insns */ | |
70 | +__hypervisor_flush_tlb_mm: /* 19 insns */ | |
71 | mov %o0, %o2 /* ARG2: mmu context */ | |
72 | mov 0, %o0 /* ARG0: CPU lists unimplemented */ | |
73 | mov 0, %o1 /* ARG1: CPU lists unimplemented */ | |
74 | mov HV_MMU_ALL, %o3 /* ARG3: flags */ | |
75 | mov HV_FAST_MMU_DEMAP_CTX, %o5 | |
76 | ta HV_FAST_TRAP | |
77 | - brnz,pn %o0, __hypervisor_tlb_tl0_error | |
78 | + brnz,pn %o0, 1f | |
79 | mov HV_FAST_MMU_DEMAP_CTX, %o1 | |
80 | retl | |
81 | nop | |
82 | +1: sethi %hi(__hypervisor_tlb_tl0_error), %o5 | |
83 | + jmpl %o5 + %lo(__hypervisor_tlb_tl0_error), %g0 | |
84 | + nop | |
85 | + nop | |
86 | + nop | |
87 | + nop | |
88 | + nop | |
89 | + nop | |
90 | + nop | |
91 | ||
92 | -__hypervisor_flush_tlb_page: /* 11 insns */ | |
93 | +__hypervisor_flush_tlb_page: /* 22 insns */ | |
94 | /* %o0 = context, %o1 = vaddr */ | |
95 | mov %o0, %g2 | |
96 | mov %o1, %o0 /* ARG0: vaddr + IMMU-bit */ | |
97 | @@ -330,10 +342,21 @@ __hypervisor_flush_tlb_page: /* 11 insns | |
98 | srlx %o0, PAGE_SHIFT, %o0 | |
99 | sllx %o0, PAGE_SHIFT, %o0 | |
100 | ta HV_MMU_UNMAP_ADDR_TRAP | |
101 | - brnz,pn %o0, __hypervisor_tlb_tl0_error | |
102 | + brnz,pn %o0, 1f | |
103 | mov HV_MMU_UNMAP_ADDR_TRAP, %o1 | |
104 | retl | |
105 | nop | |
106 | +1: sethi %hi(__hypervisor_tlb_tl0_error), %o2 | |
107 | + jmpl %o2 + %lo(__hypervisor_tlb_tl0_error), %g0 | |
108 | + nop | |
109 | + nop | |
110 | + nop | |
111 | + nop | |
112 | + nop | |
113 | + nop | |
114 | + nop | |
115 | + nop | |
116 | + nop | |
117 | ||
118 | __hypervisor_flush_tlb_pending: /* 16 insns */ | |
119 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ | |
120 | @@ -347,14 +370,25 @@ __hypervisor_flush_tlb_pending: /* 16 in | |
121 | srlx %o0, PAGE_SHIFT, %o0 | |
122 | sllx %o0, PAGE_SHIFT, %o0 | |
123 | ta HV_MMU_UNMAP_ADDR_TRAP | |
124 | - brnz,pn %o0, __hypervisor_tlb_tl0_error | |
125 | + brnz,pn %o0, 1f | |
126 | mov HV_MMU_UNMAP_ADDR_TRAP, %o1 | |
127 | brnz,pt %g1, 1b | |
128 | nop | |
129 | retl | |
130 | nop | |
131 | +1: sethi %hi(__hypervisor_tlb_tl0_error), %o2 | |
132 | + jmpl %o2 + %lo(__hypervisor_tlb_tl0_error), %g0 | |
133 | + nop | |
134 | + nop | |
135 | + nop | |
136 | + nop | |
137 | + nop | |
138 | + nop | |
139 | + nop | |
140 | + nop | |
141 | + nop | |
142 | ||
143 | -__hypervisor_flush_tlb_kernel_range: /* 16 insns */ | |
144 | +__hypervisor_flush_tlb_kernel_range: /* 19 insns */ | |
145 | /* %o0=start, %o1=end */ | |
146 | cmp %o0, %o1 | |
147 | be,pn %xcc, 2f | |
148 | @@ -366,12 +400,15 @@ __hypervisor_flush_tlb_kernel_range: /* | |
149 | mov 0, %o1 /* ARG1: mmu context */ | |
150 | mov HV_MMU_ALL, %o2 /* ARG2: flags */ | |
151 | ta HV_MMU_UNMAP_ADDR_TRAP | |
152 | - brnz,pn %o0, __hypervisor_tlb_tl0_error | |
153 | + brnz,pn %o0, 3f | |
154 | mov HV_MMU_UNMAP_ADDR_TRAP, %o1 | |
155 | brnz,pt %g2, 1b | |
156 | sub %g2, %g3, %g2 | |
157 | 2: retl | |
158 | nop | |
159 | +3: sethi %hi(__hypervisor_tlb_tl0_error), %o2 | |
160 | + jmpl %o2 + %lo(__hypervisor_tlb_tl0_error), %g0 | |
161 | + nop | |
162 | ||
163 | #ifdef DCACHE_ALIASING_POSSIBLE | |
164 | /* XXX Niagara and friends have an 8K cache, so no aliasing is | |
165 | @@ -819,28 +856,28 @@ hypervisor_patch_cachetlbops: | |
166 | sethi %hi(__hypervisor_flush_tlb_mm), %o1 | |
167 | or %o1, %lo(__hypervisor_flush_tlb_mm), %o1 | |
168 | call tlb_patch_one | |
169 | - mov 10, %o2 | |
170 | + mov 19, %o2 | |
171 | ||
172 | sethi %hi(__flush_tlb_page), %o0 | |
173 | or %o0, %lo(__flush_tlb_page), %o0 | |
174 | sethi %hi(__hypervisor_flush_tlb_page), %o1 | |
175 | or %o1, %lo(__hypervisor_flush_tlb_page), %o1 | |
176 | call tlb_patch_one | |
177 | - mov 11, %o2 | |
178 | + mov 22, %o2 | |
179 | ||
180 | sethi %hi(__flush_tlb_pending), %o0 | |
181 | or %o0, %lo(__flush_tlb_pending), %o0 | |
182 | sethi %hi(__hypervisor_flush_tlb_pending), %o1 | |
183 | or %o1, %lo(__hypervisor_flush_tlb_pending), %o1 | |
184 | call tlb_patch_one | |
185 | - mov 16, %o2 | |
186 | + mov 27, %o2 | |
187 | ||
188 | sethi %hi(__flush_tlb_kernel_range), %o0 | |
189 | or %o0, %lo(__flush_tlb_kernel_range), %o0 | |
190 | sethi %hi(__hypervisor_flush_tlb_kernel_range), %o1 | |
191 | or %o1, %lo(__hypervisor_flush_tlb_kernel_range), %o1 | |
192 | call tlb_patch_one | |
193 | - mov 16, %o2 | |
194 | + mov 19, %o2 | |
195 | ||
196 | #ifdef DCACHE_ALIASING_POSSIBLE | |
197 | sethi %hi(__flush_dcache_page), %o0 |