Commit acb15c85 authored by Zou Nan hai's avatar Zou Nan hai Committed by Tony Luck

[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: default avatarZou Nan hai <nanhai.zou@intel.com>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent c7c17423
...@@ -217,12 +217,7 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked) ...@@ -217,12 +217,7 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
.body .body
;; ;;
ld8 loc2 = [loc2] // loc2 <- entry point ld8 loc2 = [loc2] // loc2 <- entry point
mov out0 = in0 // first argument mov loc3 = psr // save psr
mov out1 = in1 // copy arg2
mov out2 = in2 // copy arg3
mov out3 = in3 // copy arg3
;;
mov loc3 = psr // save psr
;; ;;
mov loc4=ar.rsc // save RSE configuration mov loc4=ar.rsc // save RSE configuration
dep.z loc2=loc2,0,61 // convert pal entry point to physical dep.z loc2=loc2,0,61 // convert pal entry point to physical
...@@ -236,18 +231,23 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked) ...@@ -236,18 +231,23 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
;; ;;
andcm r16=loc3,r16 // removes bits to clear from psr andcm r16=loc3,r16 // removes bits to clear from psr
br.call.sptk.many rp=ia64_switch_mode_phys 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 loc5 = r19
mov loc6 = r20 mov loc6 = r20
br.call.sptk.many rp=b7 // now make the call br.call.sptk.many rp=b7 // now make the call
.ret7:
mov ar.rsc=0 // put RSE in enforced lazy, LE mode mov ar.rsc=0 // put RSE in enforced lazy, LE mode
mov r16=loc3 // r16= original psr mov r16=loc3 // r16= original psr
mov r19=loc5 mov r19=loc5
mov r20=loc6 mov r20=loc6
br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode 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 ar.pfs = loc1
mov rp = loc0 mov rp = loc0
;; ;;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment