powerpc64: Use medium code model in asm files for TOC references
Summary: With a sufficiently large TOC, it's possible to index out of range, as the immediate load instructions only permit 16-bit indices, allowing up to 64kB range (signed) from the base pointer. Allow +/- 2GB range, with the medium code model TOC accesses in asm. Patch originally by Brandon Bergren. The issue appears to impact ELFv2 more than ELFv1. Reviewed by: luporl Differential Revision: https://reviews.freebsd.org/D19708
This commit is contained in:
parent
080518d810
commit
0499e9c619
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=345676
@ -345,7 +345,8 @@ CNAME(rstcodeend):
|
||||
cpu_reset_handler:
|
||||
GET_TOCBASE(%r2)
|
||||
|
||||
ld %r1,TOC_REF(tmpstk)(%r2) /* get new SP */
|
||||
addis %r1,%r2,TOC_REF(tmpstk)@ha
|
||||
ld %r1,TOC_REF(tmpstk)@l(%r1) /* get new SP */
|
||||
addi %r1,%r1,(TMPSTKSZ-48)
|
||||
|
||||
bl CNAME(cpudep_ap_early_bootstrap) /* Set PCPU */
|
||||
@ -380,7 +381,8 @@ cpu_wakeup_handler:
|
||||
GET_TOCBASE(%r2)
|
||||
|
||||
/* Check for false wake up due to badly SRR1 set (eg. by OPAL) */
|
||||
ld %r3,TOC_REF(can_wakeup)(%r2)
|
||||
addis %r3,%r2,TOC_REF(can_wakeup)@ha
|
||||
ld %r3,TOC_REF(can_wakeup)@l(%r3)
|
||||
ld %r3,0(%r3)
|
||||
cmpdi %r3,0
|
||||
beq cpu_reset_handler
|
||||
@ -897,7 +899,8 @@ dbtrap:
|
||||
mtsprg3 %r1
|
||||
|
||||
GET_TOCBASE(%r1) /* get new SP */
|
||||
ld %r1,TOC_REF(trapstk)(%r1)
|
||||
addis %r1,%r1,TOC_REF(trapstk)@ha
|
||||
ld %r1,TOC_REF(trapstk)@l(%r1)
|
||||
addi %r1,%r1,(TRAPSTKSZ-48)
|
||||
|
||||
FRAME_SETUP(PC_DBSAVE)
|
||||
|
@ -303,7 +303,8 @@ done_mapping:
|
||||
subf %r31,%r31,%r2 /* Subtract from real TOC base to get base */
|
||||
|
||||
/* Set up the stack pointer */
|
||||
ld %r1,TOC_REF(tmpstack)(%r2)
|
||||
addis %r1,%r2,TOC_REF(tmpstack)@ha
|
||||
ld %r1,TOC_REF(tmpstack)@l(%r1)
|
||||
addi %r1,%r1,TMPSTACKSZ-96
|
||||
add %r1,%r1,%r31
|
||||
bl 1f
|
||||
@ -552,7 +553,8 @@ bp_kernload:
|
||||
mtspr SPR_SPRG8, %r2
|
||||
|
||||
/* Set up the stack pointer */
|
||||
ld %r1,TOC_REF(tmpstack)(%r2)
|
||||
addis %r1,%r2,TOC_REF(tmpstack)@ha
|
||||
ld %r1,TOC_REF(tmpstack)@l(%r1)
|
||||
addi %r1,%r1,TMPSTACKSZ-96
|
||||
#else
|
||||
/*
|
||||
|
@ -101,11 +101,13 @@ ASENTRY_NOPROF(ofwcall)
|
||||
mfmsr %r6
|
||||
|
||||
/* read client interface handler */
|
||||
ld %r4,TOC_REF(openfirmware_entry)(%r2)
|
||||
addis %r4,%r2,TOC_REF(openfirmware_entry)@ha
|
||||
ld %r4,TOC_REF(openfirmware_entry)@l(%r4)
|
||||
ld %r4,0(%r4)
|
||||
|
||||
/* Get OF stack pointer */
|
||||
ld %r7,TOC_REF(ofwstk)(%r2)
|
||||
addis %r7,%r2,TOC_REF(ofwstk)@ha
|
||||
ld %r7,TOC_REF(ofwstk)@l(%r7)
|
||||
addi %r7,%r7,OFWSTKSZ-40
|
||||
|
||||
/*
|
||||
@ -113,7 +115,8 @@ ASENTRY_NOPROF(ofwcall)
|
||||
* exceptions, which is important for the next few steps.
|
||||
*/
|
||||
|
||||
ld %r5,TOC_REF(ofmsr)(%r2)
|
||||
addis %r5,%r2,TOC_REF(ofmsr)@ha
|
||||
ld %r5,TOC_REF(ofmsr)@l(%r5)
|
||||
ld %r5,0(%r5)
|
||||
mtmsrd %r5
|
||||
isync
|
||||
@ -233,16 +236,19 @@ ASENTRY_NOPROF(rtascall)
|
||||
mfmsr %r6
|
||||
|
||||
/* Read RTAS entry and reg save area pointers */
|
||||
ld %r5,TOC_REF(rtas_entry)(%r2)
|
||||
addis %r5,%r2,TOC_REF(rtas_entry)@ha
|
||||
ld %r5,TOC_REF(rtas_entry)@l(%r5)
|
||||
ld %r5,0(%r5)
|
||||
ld %r8,TOC_REF(rtas_regsave)(%r2)
|
||||
addis %r8,%r2,TOC_REF(rtas_regsave)@ha
|
||||
ld %r8,TOC_REF(rtas_regsave)@l(%r8)
|
||||
|
||||
/*
|
||||
* Set the MSR to the RTAS value. This has the side effect of disabling
|
||||
* exceptions, which is important for the next few steps.
|
||||
*/
|
||||
|
||||
ld %r7,TOC_REF(rtasmsr)(%r2)
|
||||
addis %r7,%r2,TOC_REF(rtasmsr)@ha
|
||||
ld %r7,TOC_REF(rtasmsr)@l(%r7)
|
||||
ld %r7,0(%r7)
|
||||
mtmsrd %r7
|
||||
isync
|
||||
|
@ -53,7 +53,8 @@ ASENTRY(opal_call)
|
||||
|
||||
/* Load OPAL entry information */
|
||||
mr %r0,%r3
|
||||
ld %r3,TOC_REF(opal_entrypoint)(%r2)
|
||||
addis %r3,%r2,TOC_REF(opal_entrypoint)@ha
|
||||
ld %r3,TOC_REF(opal_entrypoint)@l(%r3)
|
||||
ld %r3,0(%r3)
|
||||
mtctr %r3
|
||||
|
||||
@ -62,9 +63,11 @@ ASENTRY(opal_call)
|
||||
mfmsr %r31
|
||||
|
||||
/* Load last bits from the TOC */
|
||||
ld %r3,TOC_REF(opal_msr)(%r2)
|
||||
addis %r3,%r2,TOC_REF(opal_msr)@ha
|
||||
ld %r3,TOC_REF(opal_msr)@l(%r3)
|
||||
ld %r3,0(%r3)
|
||||
ld %r2,TOC_REF(opal_data)(%r2)
|
||||
addis %r2,%r2,TOC_REF(opal_data)@ha
|
||||
ld %r2,TOC_REF(opal_data)@l(%r2)
|
||||
ld %r2,0(%r2)
|
||||
|
||||
mtmsrd %r3
|
||||
|
@ -159,7 +159,8 @@ ENTRY(cpu_switch)
|
||||
cpu_switchin:
|
||||
#if defined(SMP) && defined(SCHED_ULE)
|
||||
/* Wait for the new thread to become unblocked */
|
||||
ld %r6,TOC_REF(blocked_lock)(%r2)
|
||||
addis %r6,%r2,TOC_REF(blocked_lock)@ha
|
||||
ld %r6,TOC_REF(blocked_lock)@l(%r6)
|
||||
blocked_loop:
|
||||
ld %r7,TD_LOCK(%r13)
|
||||
cmpd %r6,%r7
|
||||
|
Loading…
Reference in New Issue
Block a user