@@ -137,19 +137,18 @@ static int genregs32_set(struct task_struct *target,
137
137
if (ret || !count )
138
138
return ret ;
139
139
140
- if (pos < 32 * sizeof (u32 )) {
141
- if (regwindow32_get (target , regs , uregs ))
142
- return - EFAULT ;
143
- ret = user_regset_copyin (& pos , & count , & kbuf , & ubuf ,
144
- uregs ,
145
- 16 * sizeof (u32 ), 32 * sizeof (u32 ));
146
- if (ret )
147
- return ret ;
148
- if (regwindow32_set (target , regs , uregs ))
149
- return - EFAULT ;
150
- if (!count )
151
- return 0 ;
152
- }
140
+ if (regwindow32_get (target , regs , uregs ))
141
+ return - EFAULT ;
142
+ ret = user_regset_copyin (& pos , & count , & kbuf , & ubuf ,
143
+ uregs ,
144
+ 16 * sizeof (u32 ), 32 * sizeof (u32 ));
145
+ if (ret )
146
+ return ret ;
147
+ if (regwindow32_set (target , regs , uregs ))
148
+ return - EFAULT ;
149
+ if (!count )
150
+ return 0 ;
151
+
153
152
ret = user_regset_copyin (& pos , & count , & kbuf , & ubuf ,
154
153
& psr ,
155
154
32 * sizeof (u32 ), 33 * sizeof (u32 ));
@@ -241,13 +240,11 @@ static int fpregs32_set(struct task_struct *target,
241
240
user_regset_copyin_ignore (& pos , & count , & kbuf , & ubuf ,
242
241
32 * sizeof (u32 ),
243
242
33 * sizeof (u32 ));
244
- if (!ret && count > 0 ) {
243
+ if (!ret )
245
244
ret = user_regset_copyin (& pos , & count , & kbuf , & ubuf ,
246
245
& target -> thread .fsr ,
247
246
33 * sizeof (u32 ),
248
247
34 * sizeof (u32 ));
249
- }
250
-
251
248
if (!ret )
252
249
ret = user_regset_copyin_ignore (& pos , & count , & kbuf , & ubuf ,
253
250
34 * sizeof (u32 ), -1 );
@@ -313,6 +310,33 @@ static int getregs_get(struct task_struct *target,
313
310
4 * sizeof (u32 ), 19 * sizeof (u32 ));
314
311
}
315
312
313
+ static int setregs_set (struct task_struct * target ,
314
+ const struct user_regset * regset ,
315
+ unsigned int pos , unsigned int count ,
316
+ const void * kbuf , const void __user * ubuf )
317
+ {
318
+ struct pt_regs * regs = target -> thread .kregs ;
319
+ u32 v [4 ];
320
+ int ret ;
321
+
322
+ if (target == current )
323
+ flush_user_windows ();
324
+
325
+ ret = user_regset_copyin (& pos , & count , & kbuf , & ubuf ,
326
+ v ,
327
+ 0 , 4 * sizeof (u32 ));
328
+ if (ret )
329
+ return ret ;
330
+ regs -> psr = (regs -> psr & ~(PSR_ICC | PSR_SYSCALL )) |
331
+ (v [0 ] & (PSR_ICC | PSR_SYSCALL ));
332
+ regs -> pc = v [1 ];
333
+ regs -> npc = v [2 ];
334
+ regs -> y = v [3 ];
335
+ return user_regset_copyin (& pos , & count , & kbuf , & ubuf ,
336
+ regs -> u_regs + 1 ,
337
+ 4 * sizeof (u32 ) , 19 * sizeof (u32 ));
338
+ }
339
+
316
340
static int getfpregs_get (struct task_struct * target ,
317
341
const struct user_regset * regset ,
318
342
unsigned int pos , unsigned int count ,
@@ -340,12 +364,37 @@ static int getfpregs_get(struct task_struct *target,
340
364
33 * sizeof (u32 ), 68 * sizeof (u32 ));
341
365
}
342
366
367
+ static int setfpregs_set (struct task_struct * target ,
368
+ const struct user_regset * regset ,
369
+ unsigned int pos , unsigned int count ,
370
+ const void * kbuf , const void __user * ubuf )
371
+ {
372
+ unsigned long * fpregs = target -> thread .float_regs ;
373
+ int ret ;
374
+
375
+ #if 0
376
+ if (target == current )
377
+ save_and_clear_fpu ();
378
+ #endif
379
+ ret = user_regset_copyin (& pos , & count , & kbuf , & ubuf ,
380
+ fpregs ,
381
+ 0 , 32 * sizeof (u32 ));
382
+ if (ret )
383
+ return ret ;
384
+ return user_regset_copyin (& pos , & count , & kbuf , & ubuf ,
385
+ & target -> thread .fsr ,
386
+ 32 * sizeof (u32 ),
387
+ 33 * sizeof (u32 ));
388
+ }
389
+
343
390
static const struct user_regset ptrace32_regsets [] = {
344
391
[REGSET_GENERAL ] = {
345
- .n = 19 , .size = sizeof (u32 ), .get = getregs_get ,
392
+ .n = 19 , .size = sizeof (u32 ),
393
+ .get = getregs_get , .set = setregs_set ,
346
394
},
347
395
[REGSET_FP ] = {
348
- .n = 68 , .size = sizeof (u32 ), .get = getfpregs_get ,
396
+ .n = 68 , .size = sizeof (u32 ),
397
+ .get = getfpregs_get , .set = setfpregs_set ,
349
398
},
350
399
};
351
400
@@ -380,12 +429,10 @@ long arch_ptrace(struct task_struct *child, long request,
380
429
{
381
430
unsigned long addr2 = current -> thread .kregs -> u_regs [UREG_I4 ];
382
431
void __user * addr2p ;
383
- const struct user_regset_view * view ;
384
432
struct pt_regs __user * pregs ;
385
433
struct fps __user * fps ;
386
434
int ret ;
387
435
388
- view = task_user_regset_view (current );
389
436
addr2p = (void __user * ) addr2 ;
390
437
pregs = (struct pt_regs __user * ) addr ;
391
438
fps = (struct fps __user * ) addr ;
@@ -400,15 +447,10 @@ long arch_ptrace(struct task_struct *child, long request,
400
447
}
401
448
402
449
case PTRACE_SETREGS : {
403
- ret = copy_regset_from_user (child , view , REGSET_GENERAL ,
404
- 32 * sizeof (u32 ),
405
- 4 * sizeof (u32 ),
406
- & pregs -> psr );
407
- if (!ret )
408
- copy_regset_from_user (child , view , REGSET_GENERAL ,
409
- 1 * sizeof (u32 ),
410
- 15 * sizeof (u32 ),
411
- & pregs -> u_regs [0 ]);
450
+ ret = copy_regset_from_user (child , & ptrace32_view ,
451
+ REGSET_GENERAL , 0 ,
452
+ 19 * sizeof (u32 ),
453
+ pregs );
412
454
break ;
413
455
}
414
456
@@ -421,15 +463,10 @@ long arch_ptrace(struct task_struct *child, long request,
421
463
}
422
464
423
465
case PTRACE_SETFPREGS : {
424
- ret = copy_regset_from_user (child , view , REGSET_FP ,
425
- 0 * sizeof (u32 ),
426
- 32 * sizeof (u32 ),
427
- & fps -> regs [0 ]);
428
- if (!ret )
429
- ret = copy_regset_from_user (child , view , REGSET_FP ,
430
- 33 * sizeof (u32 ),
431
- 1 * sizeof (u32 ),
432
- & fps -> fsr );
466
+ ret = copy_regset_from_user (child , & ptrace32_view ,
467
+ REGSET_FP , 0 ,
468
+ 33 * sizeof (u32 ),
469
+ fps );
433
470
break ;
434
471
}
435
472
0 commit comments