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:
Justin Hibbits 2019-03-29 02:38:30 +00:00
parent 080518d810
commit 0499e9c619
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=345676
5 changed files with 30 additions and 15 deletions

View File

@ -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)

View File

@ -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
/*

View File

@ -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

View File

@ -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

View File

@ -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