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.
6 From: "David S. Miller" <davem@davemloft.net>
9 [ Upstream commit b429ae4d5b565a71dfffd759dfcd4f6c093ced94 ]
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.
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.
18 Use an absolute jmpl to fix this problem.
20 Signed-off-by: David S. Miller <davem@davemloft.net>
21 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
23 arch/sparc/mm/ultra.S | 65 +++++++++++++++++++++++++++++++++++++++-----------
24 1 file changed, 51 insertions(+), 14 deletions(-)
26 --- a/arch/sparc/mm/ultra.S
27 +++ b/arch/sparc/mm/ultra.S
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
37 @@ -81,7 +81,7 @@ __flush_tlb_page: /* 22 insns */
40 .globl __flush_tlb_pending
41 -__flush_tlb_pending: /* 26 insns */
42 +__flush_tlb_pending: /* 27 insns */
43 /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
46 @@ -113,7 +113,7 @@ __flush_tlb_pending: /* 26 insns */
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 */
55 @@ -131,6 +131,9 @@ __flush_tlb_kernel_range: /* 16 insns */
63 __spitfire_flush_tlb_mm_slow:
65 @@ -309,19 +312,28 @@ __hypervisor_tlb_tl0_error:
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
77 - brnz,pn %o0, __hypervisor_tlb_tl0_error
79 mov HV_FAST_MMU_DEMAP_CTX, %o1
82 +1: sethi %hi(__hypervisor_tlb_tl0_error), %o5
83 + jmpl %o5 + %lo(__hypervisor_tlb_tl0_error), %g0
92 -__hypervisor_flush_tlb_page: /* 11 insns */
93 +__hypervisor_flush_tlb_page: /* 22 insns */
94 /* %o0 = context, %o1 = vaddr */
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
103 mov HV_MMU_UNMAP_ADDR_TRAP, %o1
106 +1: sethi %hi(__hypervisor_tlb_tl0_error), %o2
107 + jmpl %o2 + %lo(__hypervisor_tlb_tl0_error), %g0
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
126 mov HV_MMU_UNMAP_ADDR_TRAP, %o1
131 +1: sethi %hi(__hypervisor_tlb_tl0_error), %o2
132 + jmpl %o2 + %lo(__hypervisor_tlb_tl0_error), %g0
143 -__hypervisor_flush_tlb_kernel_range: /* 16 insns */
144 +__hypervisor_flush_tlb_kernel_range: /* 19 insns */
145 /* %o0=start, %o1=end */
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
154 mov HV_MMU_UNMAP_ADDR_TRAP, %o1
159 +3: sethi %hi(__hypervisor_tlb_tl0_error), %o2
160 + jmpl %o2 + %lo(__hypervisor_tlb_tl0_error), %g0
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
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
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
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
196 #ifdef DCACHE_ALIASING_POSSIBLE
197 sethi %hi(__flush_dcache_page), %o0