@@ -1237,6 +1237,22 @@ enum compat_regset {
1237
1237
REGSET_COMPAT_VFP ,
1238
1238
};
1239
1239
1240
+ static inline compat_ulong_t compat_get_user_reg (struct task_struct * task , int idx )
1241
+ {
1242
+ struct pt_regs * regs = task_pt_regs (task );
1243
+
1244
+ switch (idx ) {
1245
+ case 15 :
1246
+ return regs -> pc ;
1247
+ case 16 :
1248
+ return pstate_to_compat_psr (regs -> pstate );
1249
+ case 17 :
1250
+ return regs -> orig_x0 ;
1251
+ default :
1252
+ return regs -> regs [idx ];
1253
+ }
1254
+ }
1255
+
1240
1256
static int compat_gpr_get (struct task_struct * target ,
1241
1257
const struct user_regset * regset ,
1242
1258
unsigned int pos , unsigned int count ,
@@ -1255,23 +1271,7 @@ static int compat_gpr_get(struct task_struct *target,
1255
1271
return - EIO ;
1256
1272
1257
1273
for (i = 0 ; i < num_regs ; ++ i ) {
1258
- unsigned int idx = start + i ;
1259
- compat_ulong_t reg ;
1260
-
1261
- switch (idx ) {
1262
- case 15 :
1263
- reg = task_pt_regs (target )-> pc ;
1264
- break ;
1265
- case 16 :
1266
- reg = task_pt_regs (target )-> pstate ;
1267
- reg = pstate_to_compat_psr (reg );
1268
- break ;
1269
- case 17 :
1270
- reg = task_pt_regs (target )-> orig_x0 ;
1271
- break ;
1272
- default :
1273
- reg = task_pt_regs (target )-> regs [idx ];
1274
- }
1274
+ compat_ulong_t reg = compat_get_user_reg (target , start + i );
1275
1275
1276
1276
if (kbuf ) {
1277
1277
memcpy (kbuf , & reg , sizeof (reg ));
@@ -1541,9 +1541,7 @@ static int compat_ptrace_read_user(struct task_struct *tsk, compat_ulong_t off,
1541
1541
else if (off == COMPAT_PT_TEXT_END_ADDR )
1542
1542
tmp = tsk -> mm -> end_code ;
1543
1543
else if (off < sizeof (compat_elf_gregset_t ))
1544
- return copy_regset_to_user (tsk , & user_aarch32_view ,
1545
- REGSET_COMPAT_GPR , off ,
1546
- sizeof (compat_ulong_t ), ret );
1544
+ tmp = compat_get_user_reg (tsk , off >> 2 );
1547
1545
else if (off >= COMPAT_USER_SZ )
1548
1546
return - EIO ;
1549
1547
else
@@ -1555,23 +1553,34 @@ static int compat_ptrace_read_user(struct task_struct *tsk, compat_ulong_t off,
1555
1553
static int compat_ptrace_write_user (struct task_struct * tsk , compat_ulong_t off ,
1556
1554
compat_ulong_t val )
1557
1555
{
1558
- int ret ;
1559
- mm_segment_t old_fs = get_fs () ;
1556
+ struct pt_regs newregs = * task_pt_regs ( tsk ) ;
1557
+ unsigned int idx = off / 4 ;
1560
1558
1561
1559
if (off & 3 || off >= COMPAT_USER_SZ )
1562
1560
return - EIO ;
1563
1561
1564
1562
if (off >= sizeof (compat_elf_gregset_t ))
1565
1563
return 0 ;
1566
1564
1567
- set_fs (KERNEL_DS );
1568
- ret = copy_regset_from_user (tsk , & user_aarch32_view ,
1569
- REGSET_COMPAT_GPR , off ,
1570
- sizeof (compat_ulong_t ),
1571
- & val );
1572
- set_fs (old_fs );
1565
+ switch (idx ) {
1566
+ case 15 :
1567
+ newregs .pc = val ;
1568
+ break ;
1569
+ case 16 :
1570
+ newregs .pstate = compat_psr_to_pstate (val );
1571
+ break ;
1572
+ case 17 :
1573
+ newregs .orig_x0 = val ;
1574
+ break ;
1575
+ default :
1576
+ newregs .regs [idx ] = val ;
1577
+ }
1578
+
1579
+ if (!valid_user_regs (& newregs .user_regs , tsk ))
1580
+ return - EINVAL ;
1573
1581
1574
- return ret ;
1582
+ * task_pt_regs (tsk ) = newregs ;
1583
+ return 0 ;
1575
1584
}
1576
1585
1577
1586
#ifdef CONFIG_HAVE_HW_BREAKPOINT
0 commit comments