summaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
authorZou Nan hai <nanhai.zou@intel.com>2006-07-26 07:26:51 +0800
committerTony Luck <tony.luck@intel.com>2006-08-02 16:12:08 -0700
commitacb15c85de57d81d773b6e4184b7cb143ce83eba (patch)
tree3f8363f32e3a0bad1a7bce90915651e9d95b4711 /arch/ia64
parentc7c17423b9ea3c5559cfb480a00844f1df9eed06 (diff)
downloadlinux-acb15c85de57d81d773b6e4184b7cb143ce83eba.tar.gz
linux-acb15c85de57d81d773b6e4184b7cb143ce83eba.tar.bz2
linux-acb15c85de57d81d773b6e4184b7cb143ce83eba.zip
[IA64] Do not assume output registers be reservered.
We found an issue in pal.S. According to the software runtime SPEC, The caller's output registers do not need to be preserved for caller. The callee may reuse input registers for any other purpose within the procedure. in ia64_pal_call_phys_stacked, input registers are copied to output registers before call into ia64_switch_mode_phys, then used to call into PAL. This assumes output registers are preserved in ia64_switch_mode_phys, which may not be true. In this particular case, ia64_switch_mode_phys alloc a null frame , and mask off psr.i. If an interrupt comes at this small window, or an MCA comes inside the procedure, output registers maybe changed, then the pal call may got some staled input registers. This patch moves the copies from input to output after ia64_switch_mode_phys to follow the software runtime convention. It also removed some unused labels in ia64_pal_call_phys_stacked. Signed-off-by: Zou Nan hai <nanhai.zou@intel.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/kernel/pal.S18
1 files changed, 9 insertions, 9 deletions
diff --git a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S
index 5018c7f2e7a8..ebaf1e685f5e 100644
--- a/arch/ia64/kernel/pal.S
+++ b/arch/ia64/kernel/pal.S
@@ -217,12 +217,7 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
.body
;;
ld8 loc2 = [loc2] // loc2 <- entry point
- mov out0 = in0 // first argument
- mov out1 = in1 // copy arg2
- mov out2 = in2 // copy arg3
- mov out3 = in3 // copy arg3
- ;;
- mov loc3 = psr // save psr
+ mov loc3 = psr // save psr
;;
mov loc4=ar.rsc // save RSE configuration
dep.z loc2=loc2,0,61 // convert pal entry point to physical
@@ -236,18 +231,23 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
;;
andcm r16=loc3,r16 // removes bits to clear from psr
br.call.sptk.many rp=ia64_switch_mode_phys
-.ret6:
+
+ mov out0 = in0 // first argument
+ mov out1 = in1 // copy arg2
+ mov out2 = in2 // copy arg3
+ mov out3 = in3 // copy arg3
mov loc5 = r19
mov loc6 = r20
+
br.call.sptk.many rp=b7 // now make the call
-.ret7:
+
mov ar.rsc=0 // put RSE in enforced lazy, LE mode
mov r16=loc3 // r16= original psr
mov r19=loc5
mov r20=loc6
br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
-.ret8: mov psr.l = loc3 // restore init PSR
+ mov psr.l = loc3 // restore init PSR
mov ar.pfs = loc1
mov rp = loc0
;;