1919struct patch_insn {
2020 void * addr ;
2121 u32 * insns ;
22- int ninsns ;
22+ size_t len ;
2323 atomic_t cpu_count ;
2424};
2525
@@ -54,7 +54,7 @@ static __always_inline void *patch_map(void *addr, const unsigned int fixmap)
5454 BUG_ON (!page );
5555
5656 return (void * )set_fixmap_offset (fixmap , page_to_phys (page ) +
57- ( uintaddr & ~ PAGE_MASK ));
57+ offset_in_page ( addr ));
5858}
5959
6060static void patch_unmap (int fixmap )
@@ -65,8 +65,8 @@ NOKPROBE_SYMBOL(patch_unmap);
6565
6666static int __patch_insn_set (void * addr , u8 c , size_t len )
6767{
68+ bool across_pages = (offset_in_page (addr ) + len ) > PAGE_SIZE ;
6869 void * waddr = addr ;
69- bool across_pages = (((uintptr_t )addr & ~PAGE_MASK ) + len ) > PAGE_SIZE ;
7070
7171 /*
7272 * Only two pages can be mapped at a time for writing.
@@ -102,8 +102,8 @@ NOKPROBE_SYMBOL(__patch_insn_set);
102102
103103static int __patch_insn_write (void * addr , const void * insn , size_t len )
104104{
105+ bool across_pages = (offset_in_page (addr ) + len ) > PAGE_SIZE ;
105106 void * waddr = addr ;
106- bool across_pages = (((uintptr_t ) addr & ~PAGE_MASK ) + len ) > PAGE_SIZE ;
107107 int ret ;
108108
109109 /*
@@ -163,69 +163,70 @@ NOKPROBE_SYMBOL(__patch_insn_write);
163163
164164static int patch_insn_set (void * addr , u8 c , size_t len )
165165{
166- size_t patched = 0 ;
167166 size_t size ;
168- int ret = 0 ;
167+ int ret ;
169168
170169 /*
171170 * __patch_insn_set() can only work on 2 pages at a time so call it in a
172171 * loop with len <= 2 * PAGE_SIZE.
173172 */
174- while (patched < len && !ret ) {
175- size = min_t (size_t , PAGE_SIZE * 2 - offset_in_page (addr + patched ), len - patched );
176- ret = __patch_insn_set (addr + patched , c , size );
177-
178- patched += size ;
173+ while (len ) {
174+ size = min (len , PAGE_SIZE * 2 - offset_in_page (addr ));
175+ ret = __patch_insn_set (addr , c , size );
176+ if (ret )
177+ return ret ;
178+
179+ addr += size ;
180+ len -= size ;
179181 }
180182
181- return ret ;
183+ return 0 ;
182184}
183185NOKPROBE_SYMBOL (patch_insn_set );
184186
185187int patch_text_set_nosync (void * addr , u8 c , size_t len )
186188{
187- u32 * tp = addr ;
188189 int ret ;
189190
190- ret = patch_insn_set (tp , c , len );
191-
191+ ret = patch_insn_set (addr , c , len );
192192 if (!ret )
193- flush_icache_range ((uintptr_t )tp , (uintptr_t )tp + len );
193+ flush_icache_range ((uintptr_t )addr , (uintptr_t )addr + len );
194194
195195 return ret ;
196196}
197197NOKPROBE_SYMBOL (patch_text_set_nosync );
198198
199199int patch_insn_write (void * addr , const void * insn , size_t len )
200200{
201- size_t patched = 0 ;
202201 size_t size ;
203- int ret = 0 ;
202+ int ret ;
204203
205204 /*
206205 * Copy the instructions to the destination address, two pages at a time
207206 * because __patch_insn_write() can only handle len <= 2 * PAGE_SIZE.
208207 */
209- while (patched < len && !ret ) {
210- size = min_t (size_t , PAGE_SIZE * 2 - offset_in_page (addr + patched ), len - patched );
211- ret = __patch_insn_write (addr + patched , insn + patched , size );
212-
213- patched += size ;
208+ while (len ) {
209+ size = min (len , PAGE_SIZE * 2 - offset_in_page (addr ));
210+ ret = __patch_insn_write (addr , insn , size );
211+ if (ret )
212+ return ret ;
213+
214+ addr += size ;
215+ insn += size ;
216+ len -= size ;
214217 }
215218
216- return ret ;
219+ return 0 ;
217220}
218221NOKPROBE_SYMBOL (patch_insn_write );
219222
220223int patch_text_nosync (void * addr , const void * insns , size_t len )
221224{
222- u32 * tp = addr ;
223225 int ret ;
224226
225- ret = patch_insn_write (tp , insns , len );
226-
227+ ret = patch_insn_write (addr , insns , len );
227228 if (!ret )
228- flush_icache_range ((uintptr_t ) tp , (uintptr_t ) tp + len );
229+ flush_icache_range ((uintptr_t )addr , (uintptr_t )addr + len );
229230
230231 return ret ;
231232}
@@ -234,14 +235,10 @@ NOKPROBE_SYMBOL(patch_text_nosync);
234235static int patch_text_cb (void * data )
235236{
236237 struct patch_insn * patch = data ;
237- unsigned long len ;
238- int i , ret = 0 ;
238+ int ret = 0 ;
239239
240240 if (atomic_inc_return (& patch -> cpu_count ) == num_online_cpus ()) {
241- for (i = 0 ; ret == 0 && i < patch -> ninsns ; i ++ ) {
242- len = GET_INSN_LENGTH (patch -> insns [i ]);
243- ret = patch_insn_write (patch -> addr + i * len , & patch -> insns [i ], len );
244- }
241+ ret = patch_insn_write (patch -> addr , patch -> insns , patch -> len );
245242 /*
246243 * Make sure the patching store is effective *before* we
247244 * increment the counter which releases all waiting CPUs
@@ -261,13 +258,13 @@ static int patch_text_cb(void *data)
261258}
262259NOKPROBE_SYMBOL (patch_text_cb );
263260
264- int patch_text (void * addr , u32 * insns , int ninsns )
261+ int patch_text (void * addr , u32 * insns , size_t len )
265262{
266263 int ret ;
267264 struct patch_insn patch = {
268265 .addr = addr ,
269266 .insns = insns ,
270- .ninsns = ninsns ,
267+ .len = len ,
271268 .cpu_count = ATOMIC_INIT (0 ),
272269 };
273270
0 commit comments