@@ -274,103 +274,9 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
274274 }
275275}
276276
277- static inline int ok_for_user (struct pt_regs * regs , unsigned int insn ,
278- enum direction dir )
279- {
280- unsigned int reg ;
281- int size = ((insn >> 19 ) & 3 ) == 3 ? 8 : 4 ;
282-
283- if ((regs -> pc | regs -> npc ) & 3 )
284- return 0 ;
285-
286- /* Must access_ok() in all the necessary places. */
287- #define WINREG_ADDR (regnum ) \
288- ((void __user *)(((unsigned long *)regs->u_regs[UREG_FP])+(regnum)))
289-
290- reg = (insn >> 25 ) & 0x1f ;
291- if (reg >= 16 ) {
292- if (!access_ok (WINREG_ADDR (reg - 16 ), size ))
293- return - EFAULT ;
294- }
295- reg = (insn >> 14 ) & 0x1f ;
296- if (reg >= 16 ) {
297- if (!access_ok (WINREG_ADDR (reg - 16 ), size ))
298- return - EFAULT ;
299- }
300- if (!(insn & 0x2000 )) {
301- reg = (insn & 0x1f );
302- if (reg >= 16 ) {
303- if (!access_ok (WINREG_ADDR (reg - 16 ), size ))
304- return - EFAULT ;
305- }
306- }
307- #undef WINREG_ADDR
308- return 0 ;
309- }
310-
311- static void user_mna_trap_fault (struct pt_regs * regs , unsigned int insn )
277+ asmlinkage void user_unaligned_trap (struct pt_regs * regs , unsigned int insn )
312278{
313279 send_sig_fault (SIGBUS , BUS_ADRALN ,
314280 (void __user * )safe_compute_effective_address (regs , insn ),
315281 0 , current );
316282}
317-
318- asmlinkage void user_unaligned_trap (struct pt_regs * regs , unsigned int insn )
319- {
320- enum direction dir ;
321-
322- if (!(current -> thread .flags & SPARC_FLAG_UNALIGNED ) ||
323- (((insn >> 30 ) & 3 ) != 3 ))
324- goto kill_user ;
325- dir = decode_direction (insn );
326- if (!ok_for_user (regs , insn , dir )) {
327- goto kill_user ;
328- } else {
329- int err , size = decode_access_size (insn );
330- unsigned long addr ;
331-
332- if (floating_point_load_or_store_p (insn )) {
333- printk ("User FPU load/store unaligned unsupported.\n" );
334- goto kill_user ;
335- }
336-
337- addr = compute_effective_address (regs , insn );
338- perf_sw_event (PERF_COUNT_SW_ALIGNMENT_FAULTS , 1 , regs , addr );
339- switch (dir ) {
340- case load :
341- err = do_int_load (fetch_reg_addr (((insn >>25 )& 0x1f ),
342- regs ),
343- size , (unsigned long * ) addr ,
344- decode_signedness (insn ));
345- break ;
346-
347- case store :
348- err = do_int_store (((insn >>25 )& 0x1f ), size ,
349- (unsigned long * ) addr , regs );
350- break ;
351-
352- case both :
353- /*
354- * This was supported in 2.4. However, we question
355- * the value of SWAP instruction across word boundaries.
356- */
357- printk ("Unaligned SWAP unsupported.\n" );
358- err = - EFAULT ;
359- break ;
360-
361- default :
362- unaligned_panic ("Impossible user unaligned trap." );
363- goto out ;
364- }
365- if (err )
366- goto kill_user ;
367- else
368- advance (regs );
369- goto out ;
370- }
371-
372- kill_user :
373- user_mna_trap_fault (regs , insn );
374- out :
375- ;
376- }
0 commit comments