]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.8.10/sparc64-fix-illegal-relative-branches-in-hypervisor-patched-tlb-code.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.8.10 / sparc64-fix-illegal-relative-branches-in-hypervisor-patched-tlb-code.patch
CommitLineData
3d2efbd9
GKH
1From foo@baz Sat Nov 19 09:52:59 CET 2016
2From: "David S. Miller" <davem@davemloft.net>
3Date: Tue, 25 Oct 2016 16:23:26 -0700
4Subject: sparc64: Fix illegal relative branches in hypervisor patched TLB code.
5
6From: "David S. Miller" <davem@davemloft.net>
7
8
9[ Upstream commit b429ae4d5b565a71dfffd759dfcd4f6c093ced94 ]
10
11When we copy code over to patch another piece of code, we can only use
12PC-relative branches that target code within that piece of code.
13
14Such PC-relative branches cannot be made to external symbols because
15the patch moves the location of the code and thus modifies the
16relative address of external symbols.
17
18Use an absolute jmpl to fix this problem.
19
20Signed-off-by: David S. Miller <davem@davemloft.net>
21Signed-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