aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
authorMatthew Chapman <matthewc@hp.com>2005-06-21 19:19:20 -0400
committerTony Luck <tony.luck@intel.com>2005-06-21 19:19:20 -0400
commit4ea78729b8dbfc400fe165a57b90a394a7275a54 (patch)
treecc8d7def737ca5a4189481466d1e4164eef98313 /arch/ia64
parent7b404b3459db1326bbdc7085edb1f58b98da5826 (diff)
[IA64] ptrace and restore_sigcontext() allow ar.rsc.pl==0
This patch fixes handling of accesses to ar.rsc via ptrace & restore_sigcontext [With Thanks to Chris Wright for noticing the restore_sigcontext path] Signed-off-by: Matthew Chapman <matthewc@hp.com> Acked-by: David Mosberger <davidm@hpl.hp.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/kernel/ptrace.c15
-rw-r--r--arch/ia64/kernel/signal.c5
2 files changed, 13 insertions, 7 deletions
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 575a8f657b31..6d57aebad485 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -945,6 +945,13 @@ access_uarea (struct task_struct *child, unsigned long addr,
945 *data = (pt->cr_ipsr & IPSR_MASK); 945 *data = (pt->cr_ipsr & IPSR_MASK);
946 return 0; 946 return 0;
947 947
948 case PT_AR_RSC:
949 if (write_access)
950 pt->ar_rsc = *data | (3 << 2); /* force PL3 */
951 else
952 *data = pt->ar_rsc;
953 return 0;
954
948 case PT_AR_RNAT: 955 case PT_AR_RNAT:
949 urbs_end = ia64_get_user_rbs_end(child, pt, NULL); 956 urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
950 rnat_addr = (long) ia64_rse_rnat_addr((long *) 957 rnat_addr = (long) ia64_rse_rnat_addr((long *)
@@ -996,9 +1003,6 @@ access_uarea (struct task_struct *child, unsigned long addr,
996 case PT_AR_BSPSTORE: 1003 case PT_AR_BSPSTORE:
997 ptr = pt_reg_addr(pt, ar_bspstore); 1004 ptr = pt_reg_addr(pt, ar_bspstore);
998 break; 1005 break;
999 case PT_AR_RSC:
1000 ptr = pt_reg_addr(pt, ar_rsc);
1001 break;
1002 case PT_AR_UNAT: 1006 case PT_AR_UNAT:
1003 ptr = pt_reg_addr(pt, ar_unat); 1007 ptr = pt_reg_addr(pt, ar_unat);
1004 break; 1008 break;
@@ -1234,7 +1238,7 @@ ptrace_getregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
1234static long 1238static long
1235ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr) 1239ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
1236{ 1240{
1237 unsigned long psr, ec, lc, rnat, bsp, cfm, nat_bits, val = 0; 1241 unsigned long psr, rsc, ec, lc, rnat, bsp, cfm, nat_bits, val = 0;
1238 struct unw_frame_info info; 1242 struct unw_frame_info info;
1239 struct switch_stack *sw; 1243 struct switch_stack *sw;
1240 struct ia64_fpreg fpval; 1244 struct ia64_fpreg fpval;
@@ -1267,7 +1271,7 @@ ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
1267 /* app regs */ 1271 /* app regs */
1268 1272
1269 retval |= __get_user(pt->ar_pfs, &ppr->ar[PT_AUR_PFS]); 1273 retval |= __get_user(pt->ar_pfs, &ppr->ar[PT_AUR_PFS]);
1270 retval |= __get_user(pt->ar_rsc, &ppr->ar[PT_AUR_RSC]); 1274 retval |= __get_user(rsc, &ppr->ar[PT_AUR_RSC]);
1271 retval |= __get_user(pt->ar_bspstore, &ppr->ar[PT_AUR_BSPSTORE]); 1275 retval |= __get_user(pt->ar_bspstore, &ppr->ar[PT_AUR_BSPSTORE]);
1272 retval |= __get_user(pt->ar_unat, &ppr->ar[PT_AUR_UNAT]); 1276 retval |= __get_user(pt->ar_unat, &ppr->ar[PT_AUR_UNAT]);
1273 retval |= __get_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]); 1277 retval |= __get_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]);
@@ -1365,6 +1369,7 @@ ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
1365 retval |= __get_user(nat_bits, &ppr->nat); 1369 retval |= __get_user(nat_bits, &ppr->nat);
1366 1370
1367 retval |= access_uarea(child, PT_CR_IPSR, &psr, 1); 1371 retval |= access_uarea(child, PT_CR_IPSR, &psr, 1);
1372 retval |= access_uarea(child, PT_AR_RSC, &rsc, 1);
1368 retval |= access_uarea(child, PT_AR_EC, &ec, 1); 1373 retval |= access_uarea(child, PT_AR_EC, &ec, 1);
1369 retval |= access_uarea(child, PT_AR_LC, &lc, 1); 1374 retval |= access_uarea(child, PT_AR_LC, &lc, 1);
1370 retval |= access_uarea(child, PT_AR_RNAT, &rnat, 1); 1375 retval |= access_uarea(child, PT_AR_RNAT, &rnat, 1);
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 499b7e5317cf..edd9f07860b2 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -94,7 +94,7 @@ sys_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, long arg2,
94static long 94static long
95restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr) 95restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
96{ 96{
97 unsigned long ip, flags, nat, um, cfm; 97 unsigned long ip, flags, nat, um, cfm, rsc;
98 long err; 98 long err;
99 99
100 /* Always make any pending restarted system calls return -EINTR */ 100 /* Always make any pending restarted system calls return -EINTR */
@@ -106,7 +106,7 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
106 err |= __get_user(ip, &sc->sc_ip); /* instruction pointer */ 106 err |= __get_user(ip, &sc->sc_ip); /* instruction pointer */
107 err |= __get_user(cfm, &sc->sc_cfm); 107 err |= __get_user(cfm, &sc->sc_cfm);
108 err |= __get_user(um, &sc->sc_um); /* user mask */ 108 err |= __get_user(um, &sc->sc_um); /* user mask */
109 err |= __get_user(scr->pt.ar_rsc, &sc->sc_ar_rsc); 109 err |= __get_user(rsc, &sc->sc_ar_rsc);
110 err |= __get_user(scr->pt.ar_unat, &sc->sc_ar_unat); 110 err |= __get_user(scr->pt.ar_unat, &sc->sc_ar_unat);
111 err |= __get_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr); 111 err |= __get_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr);
112 err |= __get_user(scr->pt.ar_pfs, &sc->sc_ar_pfs); 112 err |= __get_user(scr->pt.ar_pfs, &sc->sc_ar_pfs);
@@ -119,6 +119,7 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
119 err |= __copy_from_user(&scr->pt.r15, &sc->sc_gr[15], 8); /* r15 */ 119 err |= __copy_from_user(&scr->pt.r15, &sc->sc_gr[15], 8); /* r15 */
120 120
121 scr->pt.cr_ifs = cfm | (1UL << 63); 121 scr->pt.cr_ifs = cfm | (1UL << 63);
122 scr->pt.ar_rsc = rsc | (3 << 2); /* force PL3 */
122 123
123 /* establish new instruction pointer: */ 124 /* establish new instruction pointer: */
124 scr->pt.cr_iip = ip & ~0x3UL; 125 scr->pt.cr_iip = ip & ~0x3UL;